1 #include "NLTPolygonSet.h"
3 #include "Reve/GeoNode.h"
4 #include "Reve/NLTProjector.h"
7 #include <TBuffer3DTypes.h>
8 #include <TVirtualPad.h>
9 #include <TVirtualViewer3D.h>
20 Seg(Int_t i1=-1, Int_t i2=-1):v1(i1), v2(i2){};
22 typedef std::list<Seg>::iterator It_t;
26 ClassImp(NLTPolygonSet)
28 /**************************************************************************/
29 NLTPolygonSet::NLTPolygonSet(const Text_t* n, const Text_t* t) :
30 RenderElementList(n, t),
44 SetMainColorPtr(&fFillColor);
47 /**************************************************************************/
49 NLTPolygonSet::~NLTPolygonSet()
54 void NLTPolygonSet::ClearPolygonSet()
56 // delete polygon vertex indices
58 for (vpPolygon_i i = fPols.begin(); i!= fPols.end(); i++)
60 p = (*i).fPnts; delete [] p;
64 // delete reduced points
65 delete [] fPnts; fPnts = 0; fNPnts = 0;
68 /**************************************************************************/
69 void NLTPolygonSet::SetProjection(NLTProjector* proj, NLTProjectable* model)
71 NLTProjected::SetProjection(proj, model);
72 GeoShapeRnrEl* gsre = dynamic_cast<GeoShapeRnrEl*>(model);
74 fBuff = gsre->MakeBuffer3D();
77 SetMainColor(gsre->GetColor());
78 SetLineColor((Color_t)TColor::GetColorBright(gsre->GetColor()));
79 SetMainTransparency(gsre->GetMainTransparency());
83 /**************************************************************************/
84 void NLTPolygonSet::UpdateProjection()
86 if(fBuff == 0) return;
88 // drop polygons, and projected/reduced points
93 //______________________________________________________________________________
94 Bool_t NLTPolygonSet::IsFirstIdxHead(Int_t s0, Int_t s1)
96 Int_t v0 = fBuff->fSegs[3*s0 + 1];
97 Int_t v2 = fBuff->fSegs[3*s1 + 1];
98 Int_t v3 = fBuff->fSegs[3*s1 + 2];
99 if(v0 != v2 && v0 != v3 )
105 //______________________________________________________________________________
106 void NLTPolygonSet::ProjectAndReducePoints()
108 NLTProjection* projection = fProjector->GetProjection();
110 Int_t N = fBuff->NbPnts();
111 Vector* pnts = new Vector[N];
112 for(Int_t i = 0; i<N; i++)
113 pnts[i].Set(fBuff->fPnts[3*i],fBuff->fPnts[3*i+1], fBuff->fPnts[3*i+2]);
114 projection->Project(pnts, N, kFALSE);
116 fIdxMap = new Int_t[N];
117 Int_t* ra = new Int_t[N]; // list of reduced vertices
119 for(UInt_t v = 0; v < (UInt_t)N; ++v)
122 for(Int_t k = 0; k < fNPnts; ++k)
124 if(pnts[v].SquareDistance(pnts[ra[k]]) < fEps*fEps)
130 // have not found a point inside epsilon, add new point in scaled array
137 // printf("(%f, %f) vertex map %d -> %d \n", pnts[v*2], pnts[v*2 + 1], v, fIdxMap[v]);
140 // create an array of scaled points
141 fPnts = new Vector[fNPnts];
142 for(Int_t i = 0; i < fNPnts; ++i)
143 fPnts[i].Set(pnts[ra[i]].x, pnts[ra[i]].y, fDepth);
146 // printf("reduced %d points of %d\n", fNPnts, N);
149 //______________________________________________________________________________
150 void NLTPolygonSet::AddPolygon(std::list<Int_t>& pp)
152 if(pp.size() <= 2) return;
155 Float_t bbox[] = { 1e6, -1e6, 1e6, -1e6, 1e6, -1e6 };
156 for (std::list<Int_t>::iterator u = pp.begin(); u!= pp.end(); u++)
159 if(fPnts[idx].x < bbox[0]) bbox[0] = fPnts[idx].x;
160 if(fPnts[idx].x > bbox[1]) bbox[1] = fPnts[idx].x;
162 if(fPnts[idx].y < bbox[2]) bbox[2] = fPnts[idx].y;
163 if(fPnts[idx].y > bbox[3]) bbox[3] = fPnts[idx].y;
165 if(fPnts[idx].z < bbox[4]) bbox[4] = fPnts[idx].z;
166 if(fPnts[idx].z > bbox[5]) bbox[5] = fPnts[idx].z;
167 // printf("bbox (%f, %f) (%f, %f)\n", bbox[1], bbox[0], bbox[3], bbox[2]);
169 if((bbox[1]-bbox[0])<fEps || (bbox[3]-bbox[2])<fEps) return;
172 for (std::list<NLTPolygon>::iterator poi = fPols.begin(); poi!= fPols.end(); poi++)
175 if (pp.size() != (UInt_t)P.fNPnts)
177 std::list<Int_t>::iterator u = pp.begin();
178 Int_t pidx = P.FindPoint(*u);
181 while (u != pp.end())
183 if ((*u) != P.fPnts[pidx])
186 if (++pidx >= P.fNPnts) pidx = 0;
188 if (u == pp.end()) return;
191 // printf("add %d NLTPolygon points %d \n", fPols.size(), pp.size());
192 Int_t* pv = new Int_t[pp.size()];
194 for( std::list<Int_t>::iterator u = pp.begin(); u!= pp.end(); u++){
198 fPols.push_back(NLTPolygon(pp.size(), pv));
201 //______________________________________________________________________________
202 void NLTPolygonSet::MakePolygonsFromBP()
204 // build polygons from sorted list of segments : buff->fPols
206 // printf("START NLTPolygonSet::MakePolygonsFromBP\n");
207 NLTProjection* projection = fProjector->GetProjection();
208 Int_t* bpols = fBuff->fPols;
209 for(UInt_t pi = 0; pi< fBuff->NbPols(); pi++)
211 std::list<Int_t> pp; // points in current polygon
212 UInt_t Nseg = bpols[1];
213 Int_t* seg = &bpols[2];
214 // start idx in the fist segment depends of second segment
216 Bool_t h = IsFirstIdxHead(seg[0], seg[1]);
218 head = fIdxMap[fBuff->fSegs[3*seg[0] + 1]];
219 tail = fIdxMap[fBuff->fSegs[3*seg[0] + 2]];
222 head = fIdxMap[fBuff->fSegs[3*seg[0] + 2]];
223 tail = fIdxMap[fBuff->fSegs[3*seg[0] + 1]];
226 // printf("start idx head %d, tail %d\n", head, tail);
228 for(UInt_t s = 1; s < Nseg; ++s)
229 segs.push_back(Seg(fBuff->fSegs[3*seg[s] + 1],fBuff->fSegs[3*seg[s] + 2]));
230 Bool_t accepted = kFALSE;
231 for(std::list<Seg>::iterator it = segs.begin(); it != segs.end(); it++ )
233 Int_t mv1 = fIdxMap[(*it).v1];
234 Int_t mv2 = fIdxMap[(*it).v2];
235 accepted = projection->AcceptSegment(fPnts[mv1], fPnts[mv2], fEps);
236 if(accepted == kFALSE)
241 if(tail != pp.back()) pp.push_back(tail);
242 tail = (mv1 == tail) ? mv2 :mv1;
244 // DirectDraw implementation: last and first vertices should not be equal
245 if(pp.empty() == kFALSE)
247 if(pp.front() == pp.back()) pp.pop_front();
252 }// MakePolygonsFromBP
254 //______________________________________________________________________________
255 void NLTPolygonSet::MakePolygonsFromBS()
257 // builds polygons from the set of buffer segments
259 // create your own list of segments according to reduced and projected points
261 std::list<Seg>::iterator it;
262 NLTProjection* projection = fProjector->GetProjection();
263 for(UInt_t s = 0; s < fBuff->NbSegs(); ++s)
265 Bool_t duplicate = kFALSE;
266 Int_t vo1, vo2; // idx from fBuff segment
267 Int_t vor1, vor2; // mapped idx
268 vo1 = fBuff->fSegs[3*s + 1];
269 vo2 = fBuff->fSegs[3*s + 2]; //... skip color info
272 if(vor1 == vor2) continue;
274 for(it = segs.begin(); it != segs.end(); it++ ){
275 Int_t vv1 = (*it).v1;
276 Int_t vv2 = (*it).v2;
277 if((vv1 == vor1 && vv2 == vor2 )||(vv1 == vor2 && vv2 == vor1 )){
282 if(duplicate == kFALSE && projection->AcceptSegment(fPnts[vor1], fPnts[vor2], fEps))
284 segs.push_back(Seg(vor1, vor2));
288 // build polygons from segment pool
289 while(segs.empty() == kFALSE)
291 // printf("Start building polygon %d from %d segments in POOL \n", pols.size(), segs.size());
292 std::list<Int_t> pp; // points in current polygon
293 pp.push_back(segs.front().v1);
294 Int_t tail = segs.front().v2;
296 Bool_t match = kTRUE;
297 while(match && segs.empty() == kFALSE)
299 // printf("second loop search tail %d \n",tail);
300 for(It_t k=segs.begin(); k!=segs.end(); ++k){
303 if( cv1 == tail || cv2 == tail){
304 // printf("found point %d in %d,%d \n", tail, cv1, cv2);
306 tail = (cv1 == tail)? cv2:cv1;
308 segs.erase(to_erase);
316 } // end for loop in the segment pool
317 if(tail == pp.front())
322 }//MakePolygonsFromBS
325 /**************************************************************************/
326 void NLTPolygonSet::ProjectBuffer3D()
329 ProjectAndReducePoints();
331 MakePolygonsFromBP();
333 MakePolygonsFromBS();
340 /**************************************************************************/
341 void NLTPolygonSet::ComputeBBox()
343 // if(fPols.size() == 0) {
348 for(Int_t pi = 0; pi<fNPnts; pi++)
349 BBoxCheckPoint(fPnts[pi].x, fPnts[pi].y, fPnts[pi].z );
350 AssertBBoxExtents(0.1);
353 /**************************************************************************/
354 void NLTPolygonSet::Paint(Option_t* )
356 if(fNPnts == 0) return;
357 TBuffer3D buffer(TBuffer3DTypes::kGeneric);
361 buffer.fColor = GetMainColor();
362 buffer.fTransparency = fTransparency;
363 buffer.fLocalFrame = false;
365 buffer.SetSectionsValid(TBuffer3D::kCore);
367 // We fill kCore on first pass and try with viewer
368 Int_t reqSections = gPad->GetViewer3D()->AddObject(buffer);
369 if (reqSections == TBuffer3D::kNone) {
374 /**************************************************************************/
375 void NLTPolygonSet::DumpPolys() const
377 printf("NLTPolygonSet %d polygons\n", fPols.size());
378 for (vpPolygon_ci i = fPols.begin(); i!= fPols.end(); i++)
380 Int_t N = (*i).fNPnts;
381 printf("polygon %d points :\n", N);
382 for(Int_t vi = 0; vi<N; vi++) {
383 Int_t pi = (*i).fPnts[vi];
384 printf("(%f, %f, %f)", fPnts[pi].x, fPnts[pi].y, fPnts[pi].z);
390 //______________________________________________________________________________
391 void NLTPolygonSet::DumpBuffer3D()
393 Int_t* bpols = fBuff->fPols;
395 for(UInt_t pi = 0; pi< fBuff->NbPols(); pi++)
397 UInt_t Nseg = bpols[1];
398 printf("%d polygon of %d has %d segments \n", pi,fBuff->NbPols(),Nseg);
400 Int_t* seg = &bpols[2];
401 for(UInt_t a=0; a<Nseg; a++)
403 Int_t a1 = fBuff->fSegs[3*seg[a]+ 1];
404 Int_t a2 = fBuff->fSegs[3*seg[a]+ 2];
405 printf("(%d, %d) \n", a1, a2);
406 printf("ORIG points :(%f, %f, %f) (%f, %f, %f)\n",
407 fBuff->fPnts[3*a1],fBuff->fPnts[3*a1+1], fBuff->fPnts[3*a1+2],
408 fBuff->fPnts[3*a2],fBuff->fPnts[3*a2+1], fBuff->fPnts[3*a2+2]);