24 using namespace ROOT::Experimental;
 
   25 namespace REX = ROOT::Experimental;
 
   35       Seg_t(Int_t i1=-1, Int_t i2=-1) : fV1(i1), fV2(i2) {}
 
   38    typedef std::list<Seg_t>           LSeg_t;
 
   53 REvePolygonSetProjected::REvePolygonSetProjected(
const std::string &n, 
const std::string &t) :
 
   63 REvePolygonSetProjected::~REvePolygonSetProjected()
 
   71 Int_t REvePolygonSetProjected::WriteCoreJson(nlohmann::json& j, Int_t rnr_offset)
 
   73    Int_t ret = REveElement::WriteCoreJson(j, rnr_offset);
 
   75    j[
"fNPnts"] = fPnts.size();
 
   88 void REvePolygonSetProjected::BuildRenderData()
 
   90    fRenderData = std::make_unique<REveRenderData>(
"makePolygonSetProjected", 3 * fPnts.size());
 
   92    Int_t n_pols = fPols.size();
 
   93    Int_t n_poly_info = 0;
 
   94    for (
auto &p : fPols) n_poly_info += 1 + p.NPoints();
 
   96    std::vector<Double_t> verts;
 
   97    verts.reserve(3 * fPnts.size());
 
   98    std::vector<Int_t>    polys;
 
   99    polys.reserve(n_poly_info);
 
  101    for (
auto &p : fPols)
 
  103       polys.emplace_back(p.NPoints());
 
  104       polys.insert(polys.end(), p.fPnts.begin(), p.fPnts.end());
 
  107    for (
unsigned i = 0; i < fPnts.size(); ++i)
 
  109       verts.push_back(fPnts[i].fX);
 
  110       verts.push_back(fPnts[i].fY);
 
  111       verts.push_back(fPnts[i].fZ);
 
  112       fRenderData->PushV(fPnts[i]);
 
  117       EveGlu::TriangleCollector tc;
 
  119       tc.ProcessData(verts, polys, n_pols);
 
  121       polys.swap(tc.RefPolyDesc());
 
  122       n_trings = tc.GetNTrianlges();
 
  126    Int_t n_idxbuff = 2 + 3 * n_trings + n_pols + n_poly_info;
 
  127    fRenderData->Reserve(0,0,n_idxbuff);
 
  129    assert(n_trings * 4 == (
int)polys.size());
 
  132    fRenderData->PushI(REveRenderData::GL_TRIANGLES);
 
  133    fRenderData->PushI(n_trings);
 
  134    for (
int i = 0; i < n_trings; ++i)
 
  136       fRenderData->PushI(&polys[i*4 + 1], 3);
 
  139    assert (fRenderData->SizeI() == 2 + 3 * n_trings);
 
  142    for (
auto &p : fPols)
 
  144       fRenderData->PushI(REveRenderData::GL_LINE_LOOP);
 
  145       fRenderData->PushI(p.NPoints());
 
  146       fRenderData->PushI(p.fPnts);
 
  149    assert (fRenderData->SizeI() == n_idxbuff);
 
  155 void REvePolygonSetProjected::ComputeBBox()
 
  157    if (fPnts.size() > 0) {
 
  159       for (
unsigned pi = 0; pi < fPnts.size(); ++pi)
 
  160          BBoxCheckPoint(fPnts[pi].fX, fPnts[pi].fY, fPnts[pi].fZ);
 
  169 void REvePolygonSetProjected::SetProjection(REveProjectionManager* mng,
 
  170                                             REveProjectable* model)
 
  172    REveProjected::SetProjection(mng, model);
 
  174    REveGeoShape* gre = 
dynamic_cast<REveGeoShape*
>(model);
 
  175    fBuff = gre->MakeBuffer3D();
 
  182 void REvePolygonSetProjected::SetDepthLocal(Float_t d)
 
  184    SetDepthCommon(d, 
this, fBBox);
 
  186    for (
unsigned i = 0; i < fPnts.size(); ++i)
 
  187       fPnts[i].fZ = fDepth;
 
  193 void REvePolygonSetProjected::UpdateProjection()
 
  205 Bool_t REvePolygonSetProjected::IsFirstIdxHead(Int_t s0, Int_t s1)
 
  207    Int_t v0 = fBuff->fSegs[3*s0 + 1];
 
  208    Int_t v2 = fBuff->fSegs[3*s1 + 1];
 
  209    Int_t v3 = fBuff->fSegs[3*s1 + 2];
 
  210    return v0 != v2 && v0 != v3;
 
  216 std::vector<Int_t> REvePolygonSetProjected::ProjectAndReducePoints()
 
  218    REveProjection* projection = fManager->GetProjection();
 
  220    Int_t buffN = fBuff->NbPnts();
 
  221    std::vector<REveVector> pnts; pnts.resize(buffN);
 
  222    for (Int_t i = 0; i < buffN; ++i)
 
  224       pnts[i].Set(fBuff->fPnts[3*i],fBuff->fPnts[3*i+1], fBuff->fPnts[3*i+2]);
 
  225       projection->ProjectPoint(pnts[i].fX, pnts[i].fY, pnts[i].fZ, 0,
 
  226                                REveProjection::kPP_Plane);
 
  230    std::vector<Int_t> idxMap;
 
  231    idxMap.resize(buffN);
 
  235    for (UInt_t v = 0; v < (UInt_t)buffN; ++v)
 
  238       for (Int_t k = 0; k < npoints; ++k)
 
  240          if (pnts[v].SquareDistance(pnts[ra[k]]) < REveProjection::fgEpsSqr)
 
  256    fPnts.resize(npoints);
 
  257    for (Int_t idx = 0; idx < npoints; ++idx)
 
  260       projection->ProjectPoint(pnts[i].fX, pnts[i].fY, pnts[i].fZ, fDepth,
 
  261                                REveProjection::kPP_Distort);
 
  262       fPnts[idx].Set(pnts[i]);
 
  273 Float_t REvePolygonSetProjected::AddPolygon(std::list<Int_t> &pp, vpPolygon_t &pols)
 
  275    if (pp.size() <= 2) 
return 0;
 
  277    Float_t bbox[4] = { 1e6, -1e6, 1e6, -1e6 };
 
  280       if (fPnts[idx].fX < bbox[0]) bbox[0] = fPnts[idx].fX;
 
  281       if (fPnts[idx].fX > bbox[1]) bbox[1] = fPnts[idx].fX;
 
  283       if (fPnts[idx].fY < bbox[2]) bbox[2] = fPnts[idx].fY;
 
  284       if (fPnts[idx].fY > bbox[3]) bbox[3] = fPnts[idx].fY;
 
  286    Float_t eps = 2*REveProjection::fgEps;
 
  287    if ((bbox[1]-bbox[0]) < eps || (bbox[3]-bbox[2]) < eps) 
return 0;
 
  290    for (
auto &&refP : pols)
 
  292       if ((Int_t) pp.size() != refP.NPoints())
 
  295       Int_t start_idx = refP.FindPoint(pp.front());
 
  298       if (++start_idx >= refP.NPoints()) start_idx = 0;
 
  302          auto u = ++pp.begin();
 
  303          Int_t pidx = start_idx;
 
  304          while (u != pp.end())
 
  306             if ((*u) != refP.fPnts[pidx])
 
  309             if (++pidx >= refP.NPoints()) pidx = 0;
 
  311          if (u == pp.end()) 
return 0;
 
  316          Int_t pidx = start_idx;
 
  317          while (u != pp.begin())
 
  319             if ((*u) != refP.fPnts[pidx])
 
  322             if (++pidx >= refP.NPoints()) pidx = 0;
 
  324          if (u == pp.begin()) 
return 0;
 
  328    std::vector<int> pv(pp.size(), 0);
 
  330    for (
auto &&u : pp) {
 
  334    pols.emplace_back(std::move(pv));
 
  336    return (bbox[1]-bbox[0]) * (bbox[3]-bbox[2]);
 
  342 Float_t REvePolygonSetProjected::MakePolygonsFromBP(std::vector<Int_t> &idxMap)
 
  344    REveProjection* projection = fManager->GetProjection();
 
  345    Int_t   *bpols = fBuff->fPols;
 
  347    for (UInt_t pi = 0; pi < fBuff->NbPols(); ++pi)
 
  350       UInt_t  segN =  bpols[1];
 
  351       Int_t  *seg  = &bpols[2];
 
  354       if (IsFirstIdxHead(seg[0], seg[1]))
 
  356          head = idxMap[fBuff->fSegs[3*seg[0] + 1]];
 
  357          tail = idxMap[fBuff->fSegs[3*seg[0] + 2]];
 
  361          head = idxMap[fBuff->fSegs[3*seg[0] + 2]];
 
  362          tail = idxMap[fBuff->fSegs[3*seg[0] + 1]];
 
  364       pp.emplace_back(head);
 
  367       for (UInt_t s = 1; s < segN; ++s)
 
  368          segs.emplace_back(fBuff->fSegs[3*seg[s] + 1],fBuff->fSegs[3*seg[s] + 2]);
 
  372          Int_t mv1 = idxMap[it.fV1];
 
  373          Int_t mv2 = idxMap[it.fV2];
 
  375          if ( ! projection->AcceptSegment(fPnts[mv1], fPnts[mv2], REveProjection::fgEps))
 
  380          if (tail != pp.back()) pp.push_back(tail);
 
  381          tail = (mv1 == tail) ? mv2 : mv1;
 
  387          if (pp.front() == pp.back()) pp.pop_front();
 
  388          surf += AddPolygon(pp, fPolsBP);
 
  400 Float_t REvePolygonSetProjected::MakePolygonsFromBS(std::vector<Int_t> &idxMap)
 
  404    REveProjection *projection = fManager->GetProjection();
 
  405    for (UInt_t s = 0; s < fBuff->NbSegs(); ++s)
 
  407       Bool_t duplicate = kFALSE;
 
  410       vo1 =  fBuff->fSegs[3*s + 1];
 
  411       vo2 =  fBuff->fSegs[3*s + 2]; 
 
  414       if (vor1 == vor2) 
continue;
 
  416       for (
auto &seg: segs)
 
  420          if((vv1 == vor1 && vv2 == vor2) || (vv1 == vor2 && vv2 == vor1))
 
  426       if (duplicate == kFALSE && projection->AcceptSegment(fPnts[vor1], fPnts[vor2], REveProjection::fgEps))
 
  427          segs.emplace_back(vor1, vor2);
 
  430    while (!segs.empty())
 
  433       pp.push_back(segs.front().fV1);
 
  434       Int_t tail = segs.front().fV2;
 
  436       Bool_t match = kTRUE;
 
  437       while (match && ! segs.empty())
 
  439          for (
auto k = segs.begin(); k != segs.end(); ++k)
 
  441             Int_t cv1 = (*k).fV1;
 
  442             Int_t cv2 = (*k).fV2;
 
  443             if (cv1 == tail || cv2 == tail)
 
  445                pp.emplace_back(tail);
 
  446                tail = (cv1 == tail) ? cv2 : cv1;
 
  456          if (tail == pp.front())
 
  459       surf += AddPolygon(pp, fPolsBS);
 
  467 void  REvePolygonSetProjected::ProjectBuffer3D()
 
  470    auto idxMap = ProjectAndReducePoints();
 
  472    REveProjection::EGeoMode_e mode = fManager->GetProjection()->GetGeoMode();
 
  474       case REveProjection::kGM_Polygons: {
 
  475          MakePolygonsFromBP(idxMap);
 
  479       case REveProjection::kGM_Segments: {
 
  480          MakePolygonsFromBS(idxMap);
 
  484       case REveProjection::kGM_Unknown: {
 
  486          Float_t surfBP = MakePolygonsFromBP(idxMap);
 
  487          Float_t surfBS = MakePolygonsFromBS(idxMap);
 
  488          if (surfBS < surfBP) {
 
  506 Float_t REvePolygonSetProjected::PolygonSurfaceXY(
const REvePolygonSetProjected::Polygon_t &p)
 const 
  509    Int_t nPnts = p.NPoints();
 
  510    for (Int_t i = 0; i < nPnts - 1; ++i)
 
  512       Int_t a = p.fPnts[i];
 
  513       Int_t b = p.fPnts[i+1];
 
  514       surf += fPnts[a].fX * fPnts[b].fY - fPnts[a].fY * fPnts[b].fX;
 
  516    return 0.5f * TMath::Abs(surf);
 
  522 void REvePolygonSetProjected::DumpPolys()
 const 
  524    printf(
"REvePolygonSetProjected %d polygons\n", (Int_t)fPols.size());
 
  526    for ( 
auto &pol : fPols)
 
  528       Int_t nPnts = pol.NPoints();
 
  529       printf(
"Points of polygon %d [Np = %d]:\n", ++cnt, nPnts);
 
  530       for (Int_t vi = 0; vi<nPnts; ++vi) {
 
  531          Int_t pi = pol.fPnts[vi];
 
  532          printf(
"  (%f, %f, %f)", fPnts[pi].fX, fPnts[pi].fY, fPnts[pi].fZ);
 
  534       printf(
", surf=%f\n", PolygonSurfaceXY(pol));
 
  541 void REvePolygonSetProjected::DumpBuffer3D()
 
  543    Int_t* bpols = fBuff->fPols;
 
  545    for (UInt_t pi = 0; pi< fBuff->NbPols(); ++pi)
 
  547       UInt_t segN = bpols[1];
 
  548       printf(
"%d polygon of %d has %d segments \n", pi, fBuff->NbPols(), segN);
 
  550       Int_t* seg =  &bpols[2];
 
  551       for (UInt_t a=0; a<segN; ++a)
 
  553          Int_t a1 = fBuff->fSegs[3*seg[a] + 1];
 
  554          Int_t a2 = fBuff->fSegs[3*seg[a] + 2];
 
  555          printf(
"(%d, %d) \n", a1, a2);
 
  556          printf(
"ORIG points :(%f, %f, %f)  (%f, %f, %f)\n",
 
  557                 fBuff->fPnts[3*a1],fBuff->fPnts[3*a1+1], fBuff->fPnts[3*a1+2],
 
  558                 fBuff->fPnts[3*a2],fBuff->fPnts[3*a2+1], fBuff->fPnts[3*a2+2]);