29 Seg_t(Int_t i1=-1, Int_t i2=-1) : fV1(i1), fV2(i2) {}
32 typedef std::list<Seg_t> LSeg_t;
33 typedef std::list<Seg_t>::iterator LSegIt_t;
45 ClassImp(TEvePolygonSetProjected);
50 TEvePolygonSetProjected::TEvePolygonSetProjected(
const char* n,
const char* t) :
61 TEvePolygonSetProjected::~TEvePolygonSetProjected()
64 if (fPnts)
delete [] fPnts;
65 if (fBuff)
delete fBuff;
71 void TEvePolygonSetProjected::ComputeBBox()
75 for (Int_t pi = 0; pi < fNPnts; ++pi)
76 BBoxCheckPoint(fPnts[pi].fX, fPnts[pi].fY, fPnts[pi].fZ);
85 void TEvePolygonSetProjected::SetProjection(TEveProjectionManager* mng,
86 TEveProjectable* model)
88 TEveProjected::SetProjection(mng, model);
90 TEveGeoShape* gre =
dynamic_cast<TEveGeoShape*
>(model);
91 fBuff = gre->MakeBuffer3D();
98 void TEvePolygonSetProjected::SetDepthLocal(Float_t d)
100 SetDepthCommon(d,
this, fBBox);
102 for (Int_t i = 0; i < fNPnts; ++i)
103 fPnts[i].fZ = fDepth;
109 void TEvePolygonSetProjected::UpdateProjection()
111 if (fBuff == 0)
return;
121 Bool_t TEvePolygonSetProjected::IsFirstIdxHead(Int_t s0, Int_t s1)
123 Int_t v0 = fBuff->fSegs[3*s0 + 1];
124 Int_t v2 = fBuff->fSegs[3*s1 + 1];
125 Int_t v3 = fBuff->fSegs[3*s1 + 2];
126 return v0 != v2 && v0 != v3;
132 Int_t* TEvePolygonSetProjected::ProjectAndReducePoints()
134 TEveProjection* projection = fManager->GetProjection();
136 Int_t buffN = fBuff->NbPnts();
137 TEveVector* pnts =
new TEveVector[buffN];
138 for (Int_t i = 0; i < buffN; ++i)
140 pnts[i].Set(fBuff->fPnts[3*i],fBuff->fPnts[3*i+1], fBuff->fPnts[3*i+2]);
141 projection->ProjectPoint(pnts[i].fX, pnts[i].fY, pnts[i].fZ, 0,
142 TEveProjection::kPP_Plane);
145 if (fPnts)
delete [] fPnts;
147 Int_t *idxMap =
new Int_t[buffN];
148 Int_t *ra =
new Int_t[buffN];
149 for (UInt_t v = 0; v < (UInt_t)buffN; ++v)
152 for (Int_t k = 0; k < fNPnts; ++k)
154 if (pnts[v].SquareDistance(pnts[ra[k]]) < TEveProjection::fgEpsSqr)
170 fPnts =
new TEveVector[fNPnts];
171 for (Int_t idx = 0; idx < fNPnts; ++idx)
174 projection->ProjectPoint(pnts[i].fX, pnts[i].fY, pnts[i].fZ, fDepth,
175 TEveProjection::kPP_Distort);
176 fPnts[idx].Set(pnts[i]);
189 Float_t TEvePolygonSetProjected::AddPolygon(std::list<Int_t>& pp, vpPolygon_t& pols)
191 if (pp.size() <= 2)
return 0;
193 Float_t bbox[4] = { 1e6, -1e6, 1e6, -1e6 };
194 for (std::list<Int_t>::iterator u = pp.begin(); u != pp.end(); ++u)
197 if (fPnts[idx].fX < bbox[0]) bbox[0] = fPnts[idx].fX;
198 if (fPnts[idx].fX > bbox[1]) bbox[1] = fPnts[idx].fX;
200 if (fPnts[idx].fY < bbox[2]) bbox[2] = fPnts[idx].fY;
201 if (fPnts[idx].fY > bbox[3]) bbox[3] = fPnts[idx].fY;
203 Float_t eps = 2*TEveProjection::fgEps;
204 if ((bbox[1]-bbox[0]) < eps || (bbox[3]-bbox[2]) < eps)
return 0;
207 for (vpPolygon_i poi = pols.begin(); poi != pols.end(); ++poi)
209 Polygon_t& refP = *poi;
211 if ((Int_t) pp.size() != refP.fNPnts)
214 Int_t start_idx = refP.FindPoint(pp.front());
217 if (++start_idx >= refP.fNPnts) start_idx = 0;
221 std::list<Int_t>::iterator u = ++pp.begin();
222 Int_t pidx = start_idx;
223 while (u != pp.end())
225 if ((*u) != refP.fPnts[pidx])
228 if (++pidx >= refP.fNPnts) pidx = 0;
230 if (u == pp.end())
return 0;
234 std::list<Int_t>::iterator u = --pp.end();
235 Int_t pidx = start_idx;
236 while (u != pp.begin())
238 if ((*u) != refP.fPnts[pidx])
241 if (++pidx >= refP.fNPnts) pidx = 0;
243 if (u == pp.begin())
return 0;
247 Int_t *pv =
new Int_t[pp.size()];
249 for (std::list<Int_t>::iterator u = pp.begin(); u != pp.end(); ++u)
255 pols.push_back(Polygon_t());
256 pols.back().fNPnts = pp.size();
257 pols.back().fPnts = &pv[0];
259 return (bbox[1]-bbox[0]) * (bbox[3]-bbox[2]);
265 Float_t TEvePolygonSetProjected::MakePolygonsFromBP(Int_t* idxMap)
267 TEveProjection* projection = fManager->GetProjection();
268 Int_t *bpols = fBuff->fPols;
270 for (UInt_t pi = 0; pi < fBuff->NbPols(); ++pi)
273 UInt_t segN = bpols[1];
274 Int_t *seg = &bpols[2];
277 if (IsFirstIdxHead(seg[0], seg[1]))
279 head = idxMap[fBuff->fSegs[3*seg[0] + 1]];
280 tail = idxMap[fBuff->fSegs[3*seg[0] + 2]];
284 head = idxMap[fBuff->fSegs[3*seg[0] + 2]];
285 tail = idxMap[fBuff->fSegs[3*seg[0] + 1]];
290 for (UInt_t s = 1; s < segN; ++s)
291 segs.push_back(Seg_t(fBuff->fSegs[3*seg[s] + 1],fBuff->fSegs[3*seg[s] + 2]));
293 for (LSegIt_t it = segs.begin(); it != segs.end(); ++it)
295 Int_t mv1 = idxMap[(*it).fV1];
296 Int_t mv2 = idxMap[(*it).fV2];
298 if ( ! projection->AcceptSegment(fPnts[mv1], fPnts[mv2], TEveProjection::fgEps))
303 if (tail != pp.back()) pp.push_back(tail);
304 tail = (mv1 == tail) ? mv2 : mv1;
310 if (pp.front() == pp.back()) pp.pop_front();
311 surf += AddPolygon(pp, fPolsBP);
323 Float_t TEvePolygonSetProjected::MakePolygonsFromBS(Int_t* idxMap)
328 TEveProjection *projection = fManager->GetProjection();
329 for (UInt_t s = 0; s < fBuff->NbSegs(); ++s)
331 Bool_t duplicate = kFALSE;
334 vo1 = fBuff->fSegs[3*s + 1];
335 vo2 = fBuff->fSegs[3*s + 2];
338 if (vor1 == vor2)
continue;
340 for (it = segs.begin(); it != segs.end(); ++it)
342 Int_t vv1 = (*it).fV1;
343 Int_t vv2 = (*it).fV2;
344 if((vv1 == vor1 && vv2 == vor2) || (vv1 == vor2 && vv2 == vor1))
350 if (duplicate == kFALSE && projection->AcceptSegment(fPnts[vor1], fPnts[vor2], TEveProjection::fgEps))
351 segs.push_back(Seg_t(vor1, vor2));
354 while ( ! segs.empty())
357 pp.push_back(segs.front().fV1);
358 Int_t tail = segs.front().fV2;
360 Bool_t match = kTRUE;
361 while (match && ! segs.empty())
363 for (LSegIt_t k = segs.begin(); k != segs.end(); ++k)
365 Int_t cv1 = (*k).fV1;
366 Int_t cv2 = (*k).fV2;
367 if (cv1 == tail || cv2 == tail)
370 tail = (cv1 == tail) ? cv2 : cv1;
380 if (tail == pp.front())
383 surf += AddPolygon(pp, fPolsBS);
391 void TEvePolygonSetProjected::ProjectBuffer3D()
394 Int_t* idxMap = ProjectAndReducePoints();
396 TEveProjection::EGeoMode_e mode = fManager->GetProjection()->GetGeoMode();
399 case TEveProjection::kGM_Polygons :
401 MakePolygonsFromBP(idxMap);
405 case TEveProjection::kGM_Segments :
407 MakePolygonsFromBS(idxMap);
411 case TEveProjection::kGM_Unknown:
414 Float_t surfBP = MakePolygonsFromBP(idxMap);
415 Float_t surfBS = MakePolygonsFromBS(idxMap);
438 Float_t TEvePolygonSetProjected::PolygonSurfaceXY(
const TEvePolygonSetProjected::Polygon_t& p)
const
441 Int_t nPnts = p.fNPnts;
442 for (Int_t i = 0; i < nPnts - 1; ++i)
444 Int_t a = p.fPnts[i];
445 Int_t b = p.fPnts[i+1];
446 surf += fPnts[a].fX * fPnts[b].fY - fPnts[a].fY * fPnts[b].fX;
448 return 0.5f * TMath::Abs(surf);
454 void TEvePolygonSetProjected::DumpPolys()
const
456 printf(
"TEvePolygonSetProjected %d polygons\n", (Int_t)fPols.size());
458 for (vpPolygon_ci i = fPols.begin(); i!= fPols.end(); i++)
460 Int_t nPnts = (*i).fNPnts;
461 printf(
"Points of polygon %d [Np = %d]:\n", ++cnt, nPnts);
462 for (Int_t vi = 0; vi<nPnts; ++vi) {
463 Int_t pi = (*i).fPnts[vi];
464 printf(
" (%f, %f, %f)", fPnts[pi].fX, fPnts[pi].fY, fPnts[pi].fZ);
466 printf(
", surf=%f\n", PolygonSurfaceXY(*i));
473 void TEvePolygonSetProjected::DumpBuffer3D()
475 Int_t* bpols = fBuff->fPols;
477 for (UInt_t pi = 0; pi< fBuff->NbPols(); ++pi)
479 UInt_t segN = bpols[1];
480 printf(
"%d polygon of %d has %d segments \n", pi, fBuff->NbPols(), segN);
482 Int_t* seg = &bpols[2];
483 for (UInt_t a=0; a<segN; ++a)
485 Int_t a1 = fBuff->fSegs[3*seg[a] + 1];
486 Int_t a2 = fBuff->fSegs[3*seg[a] + 2];
487 printf(
"(%d, %d) \n", a1, a2);
488 printf(
"ORIG points :(%f, %f, %f) (%f, %f, %f)\n",
489 fBuff->fPnts[3*a1],fBuff->fPnts[3*a1+1], fBuff->fPnts[3*a1+2],
490 fBuff->fPnts[3*a2],fBuff->fPnts[3*a2+1], fBuff->fPnts[3*a2+2]);