Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
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
44
45////////////////////////////////////////////////////////////////////////////////
46/// Constructor.
47
49 TEveShape(n, t),
50 fBuff(nullptr),
51 fNPnts(0),
52 fPnts(nullptr)
53{
54}
55
56////////////////////////////////////////////////////////////////////////////////
57/// Destructor.
58
60{
61 fPols.clear();
62 if (fPnts) delete [] fPnts;
63 if (fBuff) delete fBuff;
64}
65
66////////////////////////////////////////////////////////////////////////////////
67/// Override of virtual method from TAttBBox.
68
70{
71 if (fNPnts > 0) {
72 BBoxInit();
73 for (Int_t pi = 0; pi < fNPnts; ++pi)
74 BBoxCheckPoint(fPnts[pi].fX, fPnts[pi].fY, fPnts[pi].fZ);
75 } else {
76 BBoxZero();
77 }
78}
79
80////////////////////////////////////////////////////////////////////////////////
81/// This is virtual method from base-class TEveProjected.
82
84 TEveProjectable* model)
85{
87
88 TEveGeoShape* gre = dynamic_cast<TEveGeoShape*>(model);
89 fBuff = gre->MakeBuffer3D();
91}
92
93////////////////////////////////////////////////////////////////////////////////
94/// Set depth (z-coordinate) of the projected points.
95
97{
98 SetDepthCommon(d, this, fBBox);
99
100 for (Int_t i = 0; i < fNPnts; ++i)
101 fPnts[i].fZ = fDepth;
102}
103
104////////////////////////////////////////////////////////////////////////////////
105/// This is virtual method from base-class TEveProjected.
106
108{
109 if (fBuff == nullptr) return;
110
111 // drop polygons and projected/reduced points
112 fPols.clear();
114}
115
116////////////////////////////////////////////////////////////////////////////////
117/// Compare the two segments and check if the first index of first segment is starting.
118
120{
121 Int_t v0 = fBuff->fSegs[3*s0 + 1];
122 Int_t v2 = fBuff->fSegs[3*s1 + 1];
123 Int_t v3 = fBuff->fSegs[3*s1 + 2];
124 return v0 != v2 && v0 != v3;
125}
126
127////////////////////////////////////////////////////////////////////////////////
128/// Project and reduce buffer points.
129
131{
133
134 Int_t buffN = fBuff->NbPnts();
136 for (Int_t i = 0; i < buffN; ++i)
137 {
138 pnts[i].Set(fBuff->fPnts[3*i],fBuff->fPnts[3*i+1], fBuff->fPnts[3*i+2]);
139 projection->ProjectPoint(pnts[i].fX, pnts[i].fY, pnts[i].fZ, 0,
141 }
142
143 if (fPnts) delete [] fPnts;
144 fNPnts=0;
145 Int_t *idxMap = new Int_t[buffN];
146 Int_t *ra = new Int_t[buffN]; // list of reduced vertices
147 for (UInt_t v = 0; v < (UInt_t)buffN; ++v)
148 {
149 idxMap[v] = -1;
150 for (Int_t k = 0; k < fNPnts; ++k)
151 {
152 if (pnts[v].SquareDistance(pnts[ra[k]]) < TEveProjection::fgEpsSqr)
153 {
154 idxMap[v] = k;
155 break;
156 }
157 }
158 // have not found a point inside epsilon, add new point in scaled array
159 if (idxMap[v] == -1)
160 {
161 idxMap[v] = fNPnts;
162 ra[fNPnts] = v;
163 ++fNPnts;
164 }
165 }
166
167 // write the array of scaled points
168 fPnts = new TEveVector[fNPnts];
169 for (Int_t idx = 0; idx < fNPnts; ++idx)
170 {
171 Int_t i = ra[idx];
172 projection->ProjectPoint(pnts[i].fX, pnts[i].fY, pnts[i].fZ, fDepth,
174 fPnts[idx].Set(pnts[i]);
175 }
176 delete [] ra;
177 delete [] pnts;
178 // printf("reduced %d points of %d\n", fNPnts, N);
179
180 return idxMap;
181}
182
183////////////////////////////////////////////////////////////////////////////////
184/// Check if polygon has dimensions above TEveProjection::fgEps and add it
185/// to a list if it is not a duplicate.
186
188{
189 if (pp.size() <= 2) return 0;
190
191 Float_t bbox[4] = { 1e6, -1e6, 1e6, -1e6 };
192 for (std::list<Int_t>::iterator u = pp.begin(); u != pp.end(); ++u)
193 {
194 Int_t idx = *u;
195 if (fPnts[idx].fX < bbox[0]) bbox[0] = fPnts[idx].fX;
196 if (fPnts[idx].fX > bbox[1]) bbox[1] = fPnts[idx].fX;
197
198 if (fPnts[idx].fY < bbox[2]) bbox[2] = fPnts[idx].fY;
199 if (fPnts[idx].fY > bbox[3]) bbox[3] = fPnts[idx].fY;
200 }
202 if ((bbox[1]-bbox[0]) < eps || (bbox[3]-bbox[2]) < eps) return 0;
203
204 // Duplication
205 for (vpPolygon_i poi = pols.begin(); poi != pols.end(); ++poi)
206 {
207 Polygon_t& refP = *poi;
208
209 if ((Int_t) pp.size() != refP.fNPnts)
210 continue;
211
212 Int_t start_idx = refP.FindPoint(pp.front());
213 if (start_idx < 0)
214 continue;
215 if (++start_idx >= refP.fNPnts) start_idx = 0;
216
217 // Same orientation duplicate
218 {
219 std::list<Int_t>::iterator u = ++pp.begin();
221 while (u != pp.end())
222 {
223 if ((*u) != refP.fPnts[pidx])
224 break;
225 ++u;
226 if (++pidx >= refP.fNPnts) pidx = 0;
227 }
228 if (u == pp.end()) return 0;
229 }
230 // Inverse orientation duplicate
231 {
232 std::list<Int_t>::iterator u = --pp.end();
234 while (u != pp.begin())
235 {
236 if ((*u) != refP.fPnts[pidx])
237 break;
238 --u;
239 if (++pidx >= refP.fNPnts) pidx = 0;
240 }
241 if (u == pp.begin()) return 0;
242 }
243 }
244
245 Int_t *pv = new Int_t[pp.size()];
246 Int_t count = 0;
247 for (std::list<Int_t>::iterator u = pp.begin(); u != pp.end(); ++u)
248 {
249 pv[count] = *u;
250 ++count;
251 }
252
253 pols.push_back(Polygon_t());
254 pols.back().fNPnts = pp.size();
255 pols.back().fPnts = &pv[0];
256
257 return (bbox[1]-bbox[0]) * (bbox[3]-bbox[2]);
258}
259
260////////////////////////////////////////////////////////////////////////////////
261/// Build polygons from list of buffer polygons.
262
264{
267 Float_t surf = 0; // surface of projected polygons
268 for (UInt_t pi = 0; pi < fBuff->NbPols(); ++pi)
269 {
270 std::list<Int_t> pp; // points in current polygon
271 UInt_t segN = bpols[1];
272 Int_t *seg = &bpols[2];
273 // start idx in the fist segment depends of second segment
274 Int_t tail, head;
275 if (IsFirstIdxHead(seg[0], seg[1]))
276 {
277 head = idxMap[fBuff->fSegs[3*seg[0] + 1]];
278 tail = idxMap[fBuff->fSegs[3*seg[0] + 2]];
279 }
280 else
281 {
282 head = idxMap[fBuff->fSegs[3*seg[0] + 2]];
283 tail = idxMap[fBuff->fSegs[3*seg[0] + 1]];
284 }
285 pp.push_back(head);
286 // printf("start idx head %d, tail %d\n", head, tail);
287 LSeg_t segs;
288 for (UInt_t s = 1; s < segN; ++s)
289 segs.push_back(Seg_t(fBuff->fSegs[3*seg[s] + 1],fBuff->fSegs[3*seg[s] + 2]));
290
291 for (LSegIt_t it = segs.begin(); it != segs.end(); ++it)
292 {
293 Int_t mv1 = idxMap[(*it).fV1];
294 Int_t mv2 = idxMap[(*it).fV2];
295
296 if ( ! projection->AcceptSegment(fPnts[mv1], fPnts[mv2], TEveProjection::fgEps))
297 {
298 pp.clear();
299 break;
300 }
301 if (tail != pp.back()) pp.push_back(tail);
302 tail = (mv1 == tail) ? mv2 : mv1;
303 }
304
305 if ( ! pp.empty())
306 {
307 // DirectDraw() implementation: last and first vertices should not be equal
308 if (pp.front() == pp.back()) pp.pop_front();
309 surf += AddPolygon(pp, fPolsBP);
310 }
311 bpols += (segN+2);
312 }
313 return surf;
314}
315
316////////////////////////////////////////////////////////////////////////////////
317/// Build polygons from the set of buffer segments.
318/// First creates a segment pool according to reduced and projected points
319/// and then build polygons from the pool.
320
322{
323 LSeg_t segs;
324 LSegIt_t it;
325 Float_t surf = 0; // surface of projected polygons
327 for (UInt_t s = 0; s < fBuff->NbSegs(); ++s)
328 {
330 Int_t vo1, vo2; // idx from fBuff segment
331 Int_t vor1, vor2; // mapped idx
332 vo1 = fBuff->fSegs[3*s + 1];
333 vo2 = fBuff->fSegs[3*s + 2]; //... skip color info
334 vor1 = idxMap[vo1];
335 vor2 = idxMap[vo2];
336 if (vor1 == vor2) continue;
337 // check duplicate
338 for (it = segs.begin(); it != segs.end(); ++it)
339 {
340 Int_t vv1 = (*it).fV1;
341 Int_t vv2 = (*it).fV2;
342 if((vv1 == vor1 && vv2 == vor2) || (vv1 == vor2 && vv2 == vor1))
343 {
345 continue;
346 }
347 }
348 if (duplicate == kFALSE && projection->AcceptSegment(fPnts[vor1], fPnts[vor2], TEveProjection::fgEps))
349 segs.push_back(Seg_t(vor1, vor2));
350 }
351
352 while ( ! segs.empty())
353 {
354 std::list<Int_t> pp; // points in current polygon
355 pp.push_back(segs.front().fV1);
356 Int_t tail = segs.front().fV2;
357 segs.pop_front();
358 Bool_t match = kTRUE;
359 while (match && ! segs.empty())
360 {
361 for (LSegIt_t k = segs.begin(); k != segs.end(); ++k)
362 {
363 Int_t cv1 = (*k).fV1;
364 Int_t cv2 = (*k).fV2;
365 if (cv1 == tail || cv2 == tail)
366 {
367 pp.push_back(tail);
368 tail = (cv1 == tail) ? cv2 : cv1;
369 segs.erase(k);
370 match = kTRUE;
371 break;
372 }
373 else
374 {
375 match = kFALSE;
376 }
377 } // end for loop in the segment pool
378 if (tail == pp.front())
379 break;
380 }
381 surf += AddPolygon(pp, fPolsBS);
382 }
383 return surf;
384}
385
386////////////////////////////////////////////////////////////////////////////////
387/// Project current buffer.
388
390{
391 // create map from original to projected and reduced point needed only for geometry
393
395 switch (mode)
396 {
398 {
400 fPolsBP.swap(fPols);
401 break;
402 }
404 {
406 fPolsBS.swap(fPols);
407 break;
408 }
410 {
411 // take projection with largest surface
414 if (surfBS < surfBP)
415 {
416 fPolsBP.swap(fPols);
417 fPolsBS.clear();
418 }
419 else
420 {
421 fPolsBS.swap(fPols);
422 fPolsBP.clear();
423 }
424 }
425 default:
426 break;
427 }
428
429 delete [] idxMap;
430 ResetBBox();
431}
432
433////////////////////////////////////////////////////////////////////////////////
434/// Calculate XY surface of a polygon.
435
437{
438 Float_t surf = 0;
439 Int_t nPnts = p.fNPnts;
440 for (Int_t i = 0; i < nPnts - 1; ++i)
441 {
442 Int_t a = p.fPnts[i];
443 Int_t b = p.fPnts[i+1];
444 surf += fPnts[a].fX * fPnts[b].fY - fPnts[a].fY * fPnts[b].fX;
445 }
446 return 0.5f * TMath::Abs(surf);
447}
448
449////////////////////////////////////////////////////////////////////////////////
450/// Dump information about built polygons.
451
453{
454 printf("TEvePolygonSetProjected %d polygons\n", (Int_t)fPols.size());
455 Int_t cnt = 0;
456 for (vpPolygon_ci i = fPols.begin(); i!= fPols.end(); i++)
457 {
458 Int_t nPnts = (*i).fNPnts;
459 printf("Points of polygon %d [Np = %d]:\n", ++cnt, nPnts);
460 for (Int_t vi = 0; vi<nPnts; ++vi) {
461 Int_t pi = (*i).fPnts[vi];
462 printf(" (%f, %f, %f)", fPnts[pi].fX, fPnts[pi].fY, fPnts[pi].fZ);
463 }
464 printf(", surf=%f\n", PolygonSurfaceXY(*i));
465 }
466}
467
468////////////////////////////////////////////////////////////////////////////////
469/// Dump information about currently projected buffer.
470
472{
474
475 for (UInt_t pi = 0; pi< fBuff->NbPols(); ++pi)
476 {
477 UInt_t segN = bpols[1];
478 printf("%d polygon of %d has %d segments \n", pi, fBuff->NbPols(), segN);
479
480 Int_t* seg = &bpols[2];
481 for (UInt_t a=0; a<segN; ++a)
482 {
483 Int_t a1 = fBuff->fSegs[3*seg[a] + 1];
484 Int_t a2 = fBuff->fSegs[3*seg[a] + 2];
485 printf("(%d, %d) \n", a1, a2);
486 printf("ORIG points :(%f, %f, %f) (%f, %f, %f)\n",
487 fBuff->fPnts[3*a1],fBuff->fPnts[3*a1+1], fBuff->fPnts[3*a1+2],
488 fBuff->fPnts[3*a2],fBuff->fPnts[3*a2+1], fBuff->fPnts[3*a2+2]);
489 }
490 printf("\n");
491 bpols += (segN+2);
492 }
493}
#define d(i)
Definition RSha256.hxx:102
#define b(i)
Definition RSha256.hxx:100
#define s0(x)
Definition RSha256.hxx:90
#define a(i)
Definition RSha256.hxx:99
#define s1(x)
Definition RSha256.hxx:91
int Int_t
Signed integer 4 bytes (int)
Definition RtypesCore.h:59
unsigned int UInt_t
Unsigned integer 4 bytes (unsigned int)
Definition RtypesCore.h:60
float Float_t
Float 4 bytes (float)
Definition RtypesCore.h:71
constexpr Bool_t kFALSE
Definition RtypesCore.h:108
constexpr Bool_t kTRUE
Definition RtypesCore.h:107
ROOT::Detail::TRangeCast< T, true > TRangeDynCast
TRangeDynCast is an adapter class that allows the typed iteration through a TCollection.
winID h TVirtualViewer3D TVirtualGLPainter p
Option_t Option_t TPoint TPoint const char mode
segment * segs
Definition X3DBuffer.c:23
const_iterator begin() const
const_iterator end() const
void BBoxCheckPoint(Float_t x, Float_t y, Float_t z)
Definition TAttBBox.h:69
void ResetBBox()
Definition TAttBBox.h:57
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:41
void BBoxInit(Float_t infinity=1e6)
Dynamic Float_t[6] X(min,max), Y(min,max), Z(min,max)
Definition TAttBBox.cxx:28
Float_t * fBBox
Definition TAttBBox.h:20
Int_t * fPols
Definition TBuffer3D.h:115
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:114
Double_t * fPnts
Definition TBuffer3D.h:113
Wrapper for TGeoShape with absolute positioning and color attributes allowing display of extracted TG...
void SetDepthLocal(Float_t d) override
Set depth (z-coordinate) of the projected points.
~TEvePolygonSetProjected() override
Destructor.
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
void UpdateProjection() override
This is virtual method from base-class TEveProjected.
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.
void SetProjection(TEveProjectionManager *mng, TEveProjectable *model) override
This is virtual method from base-class TEveProjected.
void ProjectBuffer3D()
Project current buffer.
void ComputeBBox() override
Override of virtual method from TAttBBox.
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.
static Float_t fgEpsSqr
static Float_t fgEps
EGeoMode_e GetGeoMode() const
Abstract base-class for 2D/3D shapes.
Definition TEveShape.h:26
void CopyVizParams(const TEveElement *el) override
Copy visualization parameters from element el.
Definition TEveShape.cxx:69
void Set(const Float_t *v)
Definition TEveVector.h:82
const Int_t n
Definition legend1.C:16
Short_t Abs(Short_t d)
Returns the absolute value of parameter Short_t d.
Definition TMathBase.h:124