Logo ROOT  
Reference Guide
TEvePolygonSetProjected.cxx
Go to the documentation of this file.
1// @(#)root/eve:$Id$
2// Authors: Matevz Tadel & Alja Mrak-Tadel: 2006, 2007
3
4/*************************************************************************
5 * Copyright (C) 1995-2007, Rene Brun and Fons Rademakers. *
6 * All rights reserved. *
7 * *
8 * For the licensing terms see $ROOTSYS/LICENSE. *
9 * For the list of contributors see $ROOTSYS/README/CREDITS. *
10 *************************************************************************/
11
13#include "TEveGeoShape.h"
15
16#include "TBuffer3D.h"
17#include "TBuffer3DTypes.h"
18#include "TVirtualViewer3D.h"
19
20namespace
21{
22 struct Seg_t
23 {
24 // Helper class for building 2D polygons from TBuffer3D.
25 Int_t fV1;
26 Int_t fV2;
27
28 Seg_t(Int_t i1=-1, Int_t i2=-1) : fV1(i1), fV2(i2) {}
29 };
30
31 typedef std::list<Seg_t> LSeg_t;
32 typedef std::list<Seg_t>::iterator LSegIt_t;
33}
34
35/** \class TEvePolygonSetProjected
36\ingroup TEve
37A set of projected polygons.
38Used for storage of projected geometrical shapes.
39
40Internal struct Polygon_t holds only indices into the master vertex
41array in TEvePolygonSetProjected.
42*/
43
45
46////////////////////////////////////////////////////////////////////////////////
47/// Constructor.
48
50 TEveShape(n, t),
51 fBuff(0),
52 fNPnts(0),
53 fPnts(0)
54{
55}
56
57////////////////////////////////////////////////////////////////////////////////
58/// Destructor.
59
61{
62 fPols.clear();
63 if (fPnts) delete [] fPnts;
64 if (fBuff) delete fBuff;
65}
66
67////////////////////////////////////////////////////////////////////////////////
68/// Override of virtual method from TAttBBox.
69
71{
72 if (fNPnts > 0) {
73 BBoxInit();
74 for (Int_t pi = 0; pi < fNPnts; ++pi)
75 BBoxCheckPoint(fPnts[pi].fX, fPnts[pi].fY, fPnts[pi].fZ);
76 } else {
77 BBoxZero();
78 }
79}
80
81////////////////////////////////////////////////////////////////////////////////
82/// This is virtual method from base-class TEveProjected.
83
85 TEveProjectable* model)
86{
88
89 TEveGeoShape* gre = dynamic_cast<TEveGeoShape*>(model);
90 fBuff = gre->MakeBuffer3D();
91 CopyVizParams(gre);
92}
93
94////////////////////////////////////////////////////////////////////////////////
95/// Set depth (z-coordinate) of the projected points.
96
98{
99 SetDepthCommon(d, this, fBBox);
100
101 for (Int_t i = 0; i < fNPnts; ++i)
102 fPnts[i].fZ = fDepth;
103}
104
105////////////////////////////////////////////////////////////////////////////////
106/// This is virtual method from base-class TEveProjected.
107
109{
110 if (fBuff == 0) return;
111
112 // drop polygons and projected/reduced points
113 fPols.clear();
115}
116
117////////////////////////////////////////////////////////////////////////////////
118/// Compare the two segments and check if the first index of first segment is starting.
119
121{
122 Int_t v0 = fBuff->fSegs[3*s0 + 1];
123 Int_t v2 = fBuff->fSegs[3*s1 + 1];
124 Int_t v3 = fBuff->fSegs[3*s1 + 2];
125 return v0 != v2 && v0 != v3;
126}
127
128////////////////////////////////////////////////////////////////////////////////
129/// Project and reduce buffer points.
130
132{
133 TEveProjection* projection = fManager->GetProjection();
134
135 Int_t buffN = fBuff->NbPnts();
136 TEveVector* pnts = new TEveVector[buffN];
137 for (Int_t i = 0; i < buffN; ++i)
138 {
139 pnts[i].Set(fBuff->fPnts[3*i],fBuff->fPnts[3*i+1], fBuff->fPnts[3*i+2]);
140 projection->ProjectPoint(pnts[i].fX, pnts[i].fY, pnts[i].fZ, 0,
142 }
143
144 if (fPnts) delete [] fPnts;
145 fNPnts=0;
146 Int_t *idxMap = new Int_t[buffN];
147 Int_t *ra = new Int_t[buffN]; // list of reduced vertices
148 for (UInt_t v = 0; v < (UInt_t)buffN; ++v)
149 {
150 idxMap[v] = -1;
151 for (Int_t k = 0; k < fNPnts; ++k)
152 {
153 if (pnts[v].SquareDistance(pnts[ra[k]]) < TEveProjection::fgEpsSqr)
154 {
155 idxMap[v] = k;
156 break;
157 }
158 }
159 // have not found a point inside epsilon, add new point in scaled array
160 if (idxMap[v] == -1)
161 {
162 idxMap[v] = fNPnts;
163 ra[fNPnts] = v;
164 ++fNPnts;
165 }
166 }
167
168 // write the array of scaled points
169 fPnts = new TEveVector[fNPnts];
170 for (Int_t idx = 0; idx < fNPnts; ++idx)
171 {
172 Int_t i = ra[idx];
173 projection->ProjectPoint(pnts[i].fX, pnts[i].fY, pnts[i].fZ, fDepth,
175 fPnts[idx].Set(pnts[i]);
176 }
177 delete [] ra;
178 delete [] pnts;
179 // printf("reduced %d points of %d\n", fNPnts, N);
180
181 return idxMap;
182}
183
184////////////////////////////////////////////////////////////////////////////////
185/// Check if polygon has dimensions above TEveProjection::fgEps and add it
186/// to a list if it is not a duplicate.
187
189{
190 if (pp.size() <= 2) return 0;
191
192 Float_t bbox[4] = { 1e6, -1e6, 1e6, -1e6 };
193 for (std::list<Int_t>::iterator u = pp.begin(); u != pp.end(); ++u)
194 {
195 Int_t idx = *u;
196 if (fPnts[idx].fX < bbox[0]) bbox[0] = fPnts[idx].fX;
197 if (fPnts[idx].fX > bbox[1]) bbox[1] = fPnts[idx].fX;
198
199 if (fPnts[idx].fY < bbox[2]) bbox[2] = fPnts[idx].fY;
200 if (fPnts[idx].fY > bbox[3]) bbox[3] = fPnts[idx].fY;
201 }
203 if ((bbox[1]-bbox[0]) < eps || (bbox[3]-bbox[2]) < eps) return 0;
204
205 // Duplication
206 for (vpPolygon_i poi = pols.begin(); poi != pols.end(); ++poi)
207 {
208 Polygon_t& refP = *poi;
209
210 if ((Int_t) pp.size() != refP.fNPnts)
211 continue;
212
213 Int_t start_idx = refP.FindPoint(pp.front());
214 if (start_idx < 0)
215 continue;
216 if (++start_idx >= refP.fNPnts) start_idx = 0;
217
218 // Same orientation duplicate
219 {
220 std::list<Int_t>::iterator u = ++pp.begin();
221 Int_t pidx = start_idx;
222 while (u != pp.end())
223 {
224 if ((*u) != refP.fPnts[pidx])
225 break;
226 ++u;
227 if (++pidx >= refP.fNPnts) pidx = 0;
228 }
229 if (u == pp.end()) return 0;
230 }
231 // Inverse orientation duplicate
232 {
233 std::list<Int_t>::iterator u = --pp.end();
234 Int_t pidx = start_idx;
235 while (u != pp.begin())
236 {
237 if ((*u) != refP.fPnts[pidx])
238 break;
239 --u;
240 if (++pidx >= refP.fNPnts) pidx = 0;
241 }
242 if (u == pp.begin()) return 0;
243 }
244 }
245
246 Int_t *pv = new Int_t[pp.size()];
247 Int_t count = 0;
248 for (std::list<Int_t>::iterator u = pp.begin(); u != pp.end(); ++u)
249 {
250 pv[count] = *u;
251 ++count;
252 }
253
254 pols.push_back(Polygon_t());
255 pols.back().fNPnts = pp.size();
256 pols.back().fPnts = &pv[0];
257
258 return (bbox[1]-bbox[0]) * (bbox[3]-bbox[2]);
259}
260
261////////////////////////////////////////////////////////////////////////////////
262/// Build polygons from list of buffer polygons.
263
265{
266 TEveProjection* projection = fManager->GetProjection();
267 Int_t *bpols = fBuff->fPols;
268 Float_t surf = 0; // surface of projected polygons
269 for (UInt_t pi = 0; pi < fBuff->NbPols(); ++pi)
270 {
271 std::list<Int_t> pp; // points in current polygon
272 UInt_t segN = bpols[1];
273 Int_t *seg = &bpols[2];
274 // start idx in the fist segment depends of second segment
275 Int_t tail, head;
276 if (IsFirstIdxHead(seg[0], seg[1]))
277 {
278 head = idxMap[fBuff->fSegs[3*seg[0] + 1]];
279 tail = idxMap[fBuff->fSegs[3*seg[0] + 2]];
280 }
281 else
282 {
283 head = idxMap[fBuff->fSegs[3*seg[0] + 2]];
284 tail = idxMap[fBuff->fSegs[3*seg[0] + 1]];
285 }
286 pp.push_back(head);
287 // printf("start idx head %d, tail %d\n", head, tail);
288 LSeg_t segs;
289 for (UInt_t s = 1; s < segN; ++s)
290 segs.push_back(Seg_t(fBuff->fSegs[3*seg[s] + 1],fBuff->fSegs[3*seg[s] + 2]));
291
292 for (LSegIt_t it = segs.begin(); it != segs.end(); ++it)
293 {
294 Int_t mv1 = idxMap[(*it).fV1];
295 Int_t mv2 = idxMap[(*it).fV2];
296
297 if ( ! projection->AcceptSegment(fPnts[mv1], fPnts[mv2], TEveProjection::fgEps))
298 {
299 pp.clear();
300 break;
301 }
302 if (tail != pp.back()) pp.push_back(tail);
303 tail = (mv1 == tail) ? mv2 : mv1;
304 }
305
306 if ( ! pp.empty())
307 {
308 // DirectDraw() implementation: last and first vertices should not be equal
309 if (pp.front() == pp.back()) pp.pop_front();
310 surf += AddPolygon(pp, fPolsBP);
311 }
312 bpols += (segN+2);
313 }
314 return surf;
315}
316
317////////////////////////////////////////////////////////////////////////////////
318/// Build polygons from the set of buffer segments.
319/// First creates a segment pool according to reduced and projected points
320/// and then build polygons from the pool.
321
323{
324 LSeg_t segs;
325 LSegIt_t it;
326 Float_t surf = 0; // surface of projected polygons
327 TEveProjection *projection = fManager->GetProjection();
328 for (UInt_t s = 0; s < fBuff->NbSegs(); ++s)
329 {
330 Bool_t duplicate = kFALSE;
331 Int_t vo1, vo2; // idx from fBuff segment
332 Int_t vor1, vor2; // mapped idx
333 vo1 = fBuff->fSegs[3*s + 1];
334 vo2 = fBuff->fSegs[3*s + 2]; //... skip color info
335 vor1 = idxMap[vo1];
336 vor2 = idxMap[vo2];
337 if (vor1 == vor2) continue;
338 // check duplicate
339 for (it = segs.begin(); it != segs.end(); ++it)
340 {
341 Int_t vv1 = (*it).fV1;
342 Int_t vv2 = (*it).fV2;
343 if((vv1 == vor1 && vv2 == vor2) || (vv1 == vor2 && vv2 == vor1))
344 {
345 duplicate = kTRUE;
346 continue;
347 }
348 }
349 if (duplicate == kFALSE && projection->AcceptSegment(fPnts[vor1], fPnts[vor2], TEveProjection::fgEps))
350 segs.push_back(Seg_t(vor1, vor2));
351 }
352
353 while ( ! segs.empty())
354 {
355 std::list<Int_t> pp; // points in current polygon
356 pp.push_back(segs.front().fV1);
357 Int_t tail = segs.front().fV2;
358 segs.pop_front();
359 Bool_t match = kTRUE;
360 while (match && ! segs.empty())
361 {
362 for (LSegIt_t k = segs.begin(); k != segs.end(); ++k)
363 {
364 Int_t cv1 = (*k).fV1;
365 Int_t cv2 = (*k).fV2;
366 if (cv1 == tail || cv2 == tail)
367 {
368 pp.push_back(tail);
369 tail = (cv1 == tail) ? cv2 : cv1;
370 segs.erase(k);
371 match = kTRUE;
372 break;
373 }
374 else
375 {
376 match = kFALSE;
377 }
378 } // end for loop in the segment pool
379 if (tail == pp.front())
380 break;
381 }
382 surf += AddPolygon(pp, fPolsBS);
383 }
384 return surf;
385}
386
387////////////////////////////////////////////////////////////////////////////////
388/// Project current buffer.
389
391{
392 // create map from original to projected and reduced point needed only for geometry
393 Int_t* idxMap = ProjectAndReducePoints();
394
396 switch (mode)
397 {
399 {
400 MakePolygonsFromBP(idxMap);
401 fPolsBP.swap(fPols);
402 break;
403 }
405 {
406 MakePolygonsFromBS(idxMap);
407 fPolsBS.swap(fPols);
408 break;
409 }
411 {
412 // take projection with largest surface
413 Float_t surfBP = MakePolygonsFromBP(idxMap);
414 Float_t surfBS = MakePolygonsFromBS(idxMap);
415 if (surfBS < surfBP)
416 {
417 fPolsBP.swap(fPols);
418 fPolsBS.clear();
419 }
420 else
421 {
422 fPolsBS.swap(fPols);
423 fPolsBP.clear();
424 }
425 }
426 default:
427 break;
428 }
429
430 delete [] idxMap;
431 ResetBBox();
432}
433
434////////////////////////////////////////////////////////////////////////////////
435/// Calculate XY surface of a polygon.
436
438{
439 Float_t surf = 0;
440 Int_t nPnts = p.fNPnts;
441 for (Int_t i = 0; i < nPnts - 1; ++i)
442 {
443 Int_t a = p.fPnts[i];
444 Int_t b = p.fPnts[i+1];
445 surf += fPnts[a].fX * fPnts[b].fY - fPnts[a].fY * fPnts[b].fX;
446 }
447 return 0.5f * TMath::Abs(surf);
448}
449
450////////////////////////////////////////////////////////////////////////////////
451/// Dump information about built polygons.
452
454{
455 printf("TEvePolygonSetProjected %d polygons\n", (Int_t)fPols.size());
456 Int_t cnt = 0;
457 for (vpPolygon_ci i = fPols.begin(); i!= fPols.end(); i++)
458 {
459 Int_t nPnts = (*i).fNPnts;
460 printf("Points of polygon %d [Np = %d]:\n", ++cnt, nPnts);
461 for (Int_t vi = 0; vi<nPnts; ++vi) {
462 Int_t pi = (*i).fPnts[vi];
463 printf(" (%f, %f, %f)", fPnts[pi].fX, fPnts[pi].fY, fPnts[pi].fZ);
464 }
465 printf(", surf=%f\n", PolygonSurfaceXY(*i));
466 }
467}
468
469////////////////////////////////////////////////////////////////////////////////
470/// Dump information about currently projected buffer.
471
473{
474 Int_t* bpols = fBuff->fPols;
475
476 for (UInt_t pi = 0; pi< fBuff->NbPols(); ++pi)
477 {
478 UInt_t segN = bpols[1];
479 printf("%d polygon of %d has %d segments \n", pi, fBuff->NbPols(), segN);
480
481 Int_t* seg = &bpols[2];
482 for (UInt_t a=0; a<segN; ++a)
483 {
484 Int_t a1 = fBuff->fSegs[3*seg[a] + 1];
485 Int_t a2 = fBuff->fSegs[3*seg[a] + 2];
486 printf("(%d, %d) \n", a1, a2);
487 printf("ORIG points :(%f, %f, %f) (%f, %f, %f)\n",
488 fBuff->fPnts[3*a1],fBuff->fPnts[3*a1+1], fBuff->fPnts[3*a1+2],
489 fBuff->fPnts[3*a2],fBuff->fPnts[3*a2+1], fBuff->fPnts[3*a2+2]);
490 }
491 printf("\n");
492 bpols += (segN+2);
493 }
494}
int Int_t
Definition: CPyCppyy.h:43
unsigned int UInt_t
Definition: CPyCppyy.h:44
#define d(i)
Definition: RSha256.hxx:102
#define b(i)
Definition: RSha256.hxx:100
#define s0(x)
Definition: RSha256.hxx:90
#define s1(x)
Definition: RSha256.hxx:91
const Bool_t kFALSE
Definition: RtypesCore.h:101
bool Bool_t
Definition: RtypesCore.h:63
float Float_t
Definition: RtypesCore.h:57
const Bool_t kTRUE
Definition: RtypesCore.h:100
#define ClassImp(name)
Definition: Rtypes.h:364
segment * segs
Definition: X3DBuffer.c:23
void BBoxCheckPoint(Float_t x, Float_t y, Float_t z)
Definition: TAttBBox.h:58
void ResetBBox()
Definition: TAttBBox.h:46
void BBoxZero(Float_t epsilon=0, Float_t x=0, Float_t y=0, Float_t z=0)
Create cube of volume (2*epsilon)^3 at (x,y,z).
Definition: TAttBBox.cxx:42
void BBoxInit(Float_t infinity=1e6)
Dynamic Float_t[6] X(min,max), Y(min,max), Z(min,max)
Definition: TAttBBox.cxx:29
Float_t * fBBox
Definition: TAttBBox.h:20
Int_t * fPols
Definition: TBuffer3D.h:114
UInt_t NbPols() const
Definition: TBuffer3D.h:82
UInt_t NbPnts() const
Definition: TBuffer3D.h:80
UInt_t NbSegs() const
Definition: TBuffer3D.h:81
Int_t * fSegs
Definition: TBuffer3D.h:113
Double_t * fPnts
Definition: TBuffer3D.h:112
Wrapper for TGeoShape with absolute positioning and color attributes allowing display of extracted TG...
Definition: TEveGeoShape.h:24
virtual TBuffer3D * MakeBuffer3D()
Create a TBuffer3D suitable for presentation of the shape.
A set of projected polygons.
virtual void ComputeBBox()
Override of virtual method from TAttBBox.
virtual void SetDepthLocal(Float_t d)
Set depth (z-coordinate) of the projected points.
void DumpBuffer3D()
Dump information about currently projected buffer.
vpPolygon_t::iterator vpPolygon_i
vpPolygon_t::const_iterator vpPolygon_ci
Int_t * ProjectAndReducePoints()
Project and reduce buffer points.
Float_t MakePolygonsFromBS(Int_t *idxMap)
Build polygons from the set of buffer segments.
std::list< Polygon_t > vpPolygon_t
Float_t MakePolygonsFromBP(Int_t *idxMap)
Build polygons from list of buffer polygons.
TEvePolygonSetProjected(const TEvePolygonSetProjected &)=delete
Float_t PolygonSurfaceXY(const Polygon_t &poly) const
Calculate XY surface of a polygon.
virtual void SetProjection(TEveProjectionManager *mng, TEveProjectable *model)
This is virtual method from base-class TEveProjected.
void ProjectBuffer3D()
Project current buffer.
virtual void UpdateProjection()
This is virtual method from base-class TEveProjected.
virtual ~TEvePolygonSetProjected()
Destructor.
Float_t AddPolygon(std::list< Int_t, std::allocator< Int_t > > &pp, std::list< Polygon_t, std::allocator< Polygon_t > > &p)
Check if polygon has dimensions above TEveProjection::fgEps and add it to a list if it is not a dupli...
virtual void DumpPolys() const
Dump information about built polygons.
Bool_t IsFirstIdxHead(Int_t s0, Int_t s1)
Compare the two segments and check if the first index of first segment is starting.
Abstract base-class for non-linear projectable objects.
TEveProjectionManager * fManager
virtual void SetProjection(TEveProjectionManager *mng, TEveProjectable *model)
Sets projection manager and reference in the projectable object.
void SetDepthCommon(Float_t d, TEveElement *el, Float_t *bbox)
Utility function to update the z-values of the bounding-box.
Manager class for steering of projections and managing projected objects.
TEveProjection * GetProjection()
Base-class for non-linear projections.
virtual void ProjectPoint(Float_t &x, Float_t &y, Float_t &z, Float_t d, EPProc_e p=kPP_Full)=0
static Float_t fgEpsSqr
static Float_t fgEps
EGeoMode_e GetGeoMode() const
virtual Bool_t AcceptSegment(TEveVector &, TEveVector &, Float_t) const
Abstract base-class for 2D/3D shapes.
Definition: TEveShape.h:26
virtual void CopyVizParams(const TEveElement *el)
Copy visualization parameters from element el.
Definition: TEveShape.cxx:70
void Set(const Float_t *v)
Definition: TEveVector.h:82
const Int_t n
Definition: legend1.C:16
static constexpr double s
static constexpr double pi
Short_t Abs(Short_t d)
Definition: TMathBase.h:120
const char * cnt
Definition: TXMLSetup.cxx:75
auto * a
Definition: textangle.C:12