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