1 #include "NLTProjector.h"
2 #include "RGTopFrame.h"
3 #include "NLTPolygonSet.h"
10 #include "TPointSet3D.h"
11 #include "TGeoManager.h"
12 #include "TGeoMatrix.h"
23 Seg(Int_t i1=-1, Int_t i2=-1):v1(i1), v2(i2){};
26 typedef std::list<Seg>::iterator It_t;
29 //______________________________________________________________________________
30 Vector* NLTProjection::Project(Vector* origPnts, Int_t Npnts, Bool_t copy)
35 pnts = (Vector* )malloc(Npnts*sizeof(Vector));
36 memcpy(pnts, origPnts, Npnts*sizeof(Vector));
45 //______________________________________________________________________________
46 Vector* RhoZ::Project(Vector* origPnts, Int_t Npnts, Bool_t copy)
48 Vector* pnts = NLTProjection::Project(origPnts, Npnts, copy);
50 for(Int_t i = 0; i<Npnts; i++)
53 NR =R/(1+R*fDistortion);
54 y = ( pnts[i].y > 0) ? NR : -NR;
56 pnts[i].Set(z/(1+TMath::Abs(z*fDistortion)), y, 0);
61 //______________________________________________________________________________
62 Bool_t RhoZ::AcceptSegment(Vector& v1, Vector& v2)
64 return (v1.y*v2.y < 0) ? kFALSE : kTRUE;
67 //______________________________________________________________________________
68 Vector* CircularFishEye::Project(Vector* origPnts, Int_t Npnts, Bool_t copy )
70 Vector* pnts = NLTProjection::Project(origPnts, Npnts, copy);
73 for(Int_t i = 0; i<Npnts; i++) {
76 NR = R/(1+R*fDistortion);
77 pnts[i].Set(NR*TMath::Cos(phi), NR*TMath::Sin(phi), 0);
83 /**************************************************************************/
84 /**************************************************************************/
85 //______________________________________________________________________
89 ClassImp(NLTProjector)
91 NLTProjector::NLTProjector():
92 TNamed("NLTProjector",""),
94 fEps(0.05),fIdxMap(0),
99 //______________________________________________________________________________
100 NLTProjector::~NLTProjector()
104 if(fProjection) delete fProjection;
107 //______________________________________________________________________________
108 void NLTProjector::CleanUp()
123 /**************************************************************************/
124 void NLTProjector::SetProjection(NLTProjection::Type_e type, Float_t distort)
126 static const Exc_t eH("NLTProjector::SetProjection ");
129 case NLTProjection::RhoZ:
131 fProjection = new RhoZ();
134 case NLTProjection::CFishEye:
136 fProjection = new CircularFishEye();
140 throw(eH + "projection type not valid.");
143 fProjection->fDistortion = distort;
146 //______________________________________________________________________________
147 void NLTProjector::DumpBuffer(TBuffer3D* buff)
149 Int_t* bpols = buff->fPols;
151 for(UInt_t pi = 0; pi< buff->NbPols(); pi++)
153 UInt_t Nseg = bpols[1];
154 printf("%d polygon of %d has %d segments \n", pi,buff->NbPols(),Nseg);
156 Int_t* seg = &bpols[2];
157 for(UInt_t a=0; a<Nseg; a++)
159 Int_t a1 = buff->fSegs[3*seg[a]+ 1];
160 Int_t a2 = buff->fSegs[3*seg[a]+ 2];
161 printf("(%d, %d) \n", a1, a2);
162 printf("ORIG points :(%f, %f, %f) (%f, %f, %f)\n",
163 buff->fPnts[3*a1],buff->fPnts[3*a1+1], buff->fPnts[3*a1+2],
164 buff->fPnts[3*a2],buff->fPnts[3*a2+1], buff->fPnts[3*a2+2]);
171 //______________________________________________________________________________
172 void NLTProjector::CheckPoint(Int_t idx, Float_t* bbox)
174 if(fRPnts[idx].x < bbox[0]) bbox[0] = fRPnts[idx].x;
175 if(fRPnts[idx].x > bbox[1]) bbox[1] = fRPnts[idx].x;
177 if(fRPnts[idx].y < bbox[2]) bbox[2] = fRPnts[idx].y;
178 if(fRPnts[idx].y > bbox[3]) bbox[3] = fRPnts[idx].y;
180 if(fRPnts[idx].z < bbox[4]) bbox[4] = fRPnts[idx].z;
181 if(fRPnts[idx].z > bbox[5]) bbox[5] = fRPnts[idx].z;
184 //______________________________________________________________________________
185 Bool_t NLTProjector::IsFirstIdxHead(Int_t s0, Int_t s1, TBuffer3D* buff)
187 Int_t v0 = buff->fSegs[3*s0 + 1];
188 Int_t v2 = buff->fSegs[3*s1 + 1];
189 Int_t v3 = buff->fSegs[3*s1 + 2];
190 if(v0 != v2 && v0 != v3 )
196 //______________________________________________________________________________
197 void NLTProjector::ReducePoints(Vector* pnts, Int_t N)
199 fIdxMap = new Int_t[N];
200 Int_t* ra = new Int_t[N]; // list of reduced vertices
203 for(UInt_t v = 0; v < (UInt_t)N; v++)
206 for(Int_t k = 0; k<fNRPnts; k++)
208 if(pnts[v].SquareDistance(pnts[ra[k]]) < fEps*fEps)
214 // have not find a point inside epsilon, add new point in scaled array
217 fIdxMap[v] = fNRPnts;
221 // printf("(%f, %f) vertex map %d -> %d \n", pnts[v*2], pnts[v*2 + 1], v, fIdxMap[v]);
224 // create an array of scaled points
225 fRPnts = new Vector[fNRPnts];
226 for(Int_t i = 0; i<fNRPnts; i++)
227 fRPnts[i].Set(pnts[ra[i]].x, pnts[ra[i]].y, pnts[ra[i]].z);
230 // printf("reduced %d points of %d\n", fNRPnts, N);
233 //______________________________________________________________________________
234 void NLTProjector::MakePolygonsFromBP(TBuffer3D* buff, std::list<NLTPolygon>& pols)
236 // printf("START NLTProjector::MakePolygonsFromBP\n");
237 Int_t* bpols = buff->fPols;
238 for(UInt_t pi = 0; pi< buff->NbPols(); pi++)
240 std::list<Int_t> pp; // points in current polygon
241 UInt_t Nseg = bpols[1];
242 Int_t* seg = &bpols[2];
244 // start idx in the fist segment depends of second segment
246 Bool_t h = IsFirstIdxHead(seg[0], seg[1], buff);
248 head = fIdxMap[buff->fSegs[3*seg[0] + 1]];
249 tail = fIdxMap[buff->fSegs[3*seg[0] + 2]];
252 head = fIdxMap[buff->fSegs[3*seg[0] + 2]];
253 tail = fIdxMap[buff->fSegs[3*seg[0] + 1]];
255 Float_t bbox[] = {0., 0., 0., 0., 0., 0.};
257 CheckPoint(head, bbox);
258 // printf("start idx head %d, tail %d\n", head, tail);
261 for(UInt_t s=1; s< Nseg; s++)
262 segs.push_back(Seg(buff->fSegs[3*seg[s] + 1],buff->fSegs[3*seg[s] + 2]));
263 Bool_t accepted = kFALSE;
264 for(std::list<Seg>::iterator it = segs.begin(); it != segs.end(); it++ )
266 Int_t mv1 = fIdxMap[(*it).v1];
267 Int_t mv2 = fIdxMap[(*it).v2];
268 accepted = fProjection->AcceptSegment(fRPnts[mv1], fRPnts[mv2]);
269 if(accepted == kFALSE)
274 if(tail != pp.back())
277 CheckPoint(tail, bbox);
279 tail = (mv1 == tail) ? mv2 :mv1;
282 // render class loops indices last and first should not be equal
283 if(accepted && pp.front() == pp.back())
287 if( pp.size()>2 && (bbox[1]-bbox[0])>fEps && (bbox[3]-bbox[2])>fEps)
289 Bool_t duplicate = kFALSE;
290 for (std::list<NLTPolygon>::iterator poi = pols.begin(); poi!= pols.end(); poi++)
293 if(pp.size() != (UInt_t)P.fNPnts)
296 for (std::list<Int_t>::iterator u = pp.begin(); u!= pp.end(); u++) {
297 if (*u == P.fPnts[*u]) matched++;
300 if (matched == P.fNPnts) {
306 if(duplicate == kFALSE)
308 Int_t* pv = new Int_t[pp.size()];
310 // printf("%d NLTPolygon points %d \n", pols.size(), pp.size());
311 // printf("bbox (%f, %f) (%f, %f)\n", bbox[1], bbox[0], bbox[3], bbox[2]);
312 for( std::list<Int_t>::iterator u = pp.begin(); u!= pp.end(); u++){
316 pols.push_back(NLTPolygon(pp.size(), pv));
318 } // end of NLTPolygon
321 }// MakePolygonsFromBP
323 //______________________________________________________________________________
324 void NLTProjector::MakePolygonsFromBS(TBuffer3D* buff, std::list<NLTPolygon>& pols)
326 // create your own list of segments according to reduced and projected points
328 std::list<Seg>::iterator it;
329 for(UInt_t s=0; s< buff->NbSegs(); s++)
331 Bool_t duplicate = kFALSE;
332 Int_t vo1, vo2; // idx from buff segment
333 Int_t vor1, vor2; // mapped idx
334 vo1 = buff->fSegs[3*s + 1];
335 vo2 = buff->fSegs[3*s + 2]; //... skip color info
338 if(vor1 == vor2) continue;
340 for(it = segs.begin(); it != segs.end(); it++ ){
341 Int_t vv1 = (*it).v1;
342 Int_t vv2 = (*it).v2;
343 if((vv1 == vor1 && vv2 == vor2 )||(vv1 == vor2 && vv2 == vor1 )){
348 if(duplicate == kFALSE && fProjection->AcceptSegment(fRPnts[vor1], fRPnts[vor2]))
350 segs.push_back(Seg(vor1, vor2));
354 while(segs.empty() == kFALSE)
356 // printf("Start building polygon %d from %d segments in POOL \n", pols.size(), segs.size());
357 std::list<Int_t> pp; // points in current polygon
358 pp.push_back(segs.front().v1);
359 Int_t tail = segs.front().v2;
361 Bool_t match = kTRUE;
362 while(match && segs.empty() == kFALSE)
364 // printf("second loop search tail %d \n",tail);
365 for(It_t k=segs.begin(); k!=segs.end(); ++k){
368 if( cv1 == tail || cv2 == tail){
369 // printf("found point %d in %d,%d \n", tail, cv1, cv2);
377 segs.erase(to_erase);
385 } // end for loop in the segment pool
386 if(tail == pp.front())
391 // printf("CLOSING polygon %d with %d points \n", pols.size(),pp.size());
392 Int_t* pv = new Int_t[pp.size()];
394 for( std::list<Int_t>::iterator u = pp.begin(); u!= pp.end(); u++){
398 pols.push_back(NLTPolygon(pp.size(), pv));
400 } // while segment pool empty
401 }//MakePolygonsFromBS
403 //______________________________________________________________________________
404 NLTPolygonSet* NLTProjector::ProjectGeoShape(TBuffer3D* buff, Int_t useBuffPols)
407 // rewrite from Double_t to Vector array
408 Vector* pnts = new Vector[buff->NbPnts()];
409 for(Int_t i = 0; i<(Int_t)buff->NbPnts(); i++)
410 pnts[i].Set(buff->fPnts[3*i],buff->fPnts[3*i+1], buff->fPnts[3*i+2]);
412 fProjection->Project(pnts, buff->NbPnts(), kFALSE);
413 ReducePoints(pnts, buff->NbPnts());
416 std::list<NLTPolygon> pols;
417 if(useBuffPols == -1)
419 MakePolygonsFromBP(buff, pols);
422 // printf("useBuffPols == -1 call MakePolygonsFromBS \n");
423 MakePolygonsFromBS(buff, pols);
428 MakePolygonsFromBP(buff, pols);
432 MakePolygonsFromBS(buff, pols);
435 NLTPolygonSet* ps = new NLTPolygonSet();
436 if(pols.empty() == kFALSE)
439 ps->SetPoints(fRPnts,fNRPnts);
441 NLTPolygon* nltp = new NLTPolygon[pols.size()];
443 for( std::list<NLTPolygon>::iterator pi = pols.begin(); pi!= pols.end(); pi++)
445 nltp[pc].fNPnts = (*pi).fNPnts;
446 nltp[pc].fPnts = (*pi).fPnts;
449 ps->SetPolygons(nltp, pols.size());
457 //______________________________________________________________________________
458 void NLTProjector::ProjectPointSet(PointSet* orig)
460 // keep original rewrite points into Vector array
461 Float_t* op = orig->GetP();
462 Vector* vp = new Vector[orig->GetN()];
463 for( Int_t k=0; k<orig->GetN(); k++)
464 vp[k].Set(op[3*k], op[3*k+1], op[3*k+2]);
465 Vector* pnts = fProjection->Project(vp, orig->GetN(), kFALSE);
466 ReducePoints(pnts, orig->GetN());
467 orig->Reset(fNRPnts);
468 for(Int_t i = 0; i< fNRPnts; i++){
469 orig->SetPoint(i, fRPnts[i].x, fRPnts[i].y, fRPnts[3].z);
475 //______________________________________________________________________________
476 void NLTProjector::ProjectTrackList(TrackList* orig_tl)
478 // fill a track list from original track list
479 Reve::RenderElement::List_i i = orig_tl->BeginChildren();
480 Int_t Nc = orig_tl->GetNChildren();
481 for(Int_t c=0; c<Nc; c++)
483 // printf("project track with %d points \n", orig->GetN());
484 Track* orig = dynamic_cast<Track*>(*i);
486 // keep original copy points to Vector array
487 Float_t* op = orig->GetP();
488 Vector* pnts = new Vector[orig->GetN()];
489 for( Int_t k=0; k<orig->GetN(); k++)
490 pnts[k].Set(op[3*k], op[3*k+1], op[3*k+2]);
492 for( Int_t k=0; k<orig->GetN()-1; k++)
494 if(fProjection->AcceptSegment(pnts[k], pnts[(k+1)]) == kFALSE){
495 //printf("split track at %d\n", k);
496 Vector* tp = fProjection->Project(&pnts[start], k-start, kFALSE);
497 ReducePoints(tp, k-start);
498 Track* nt = new Track();
500 nt->SetMainColor(orig->GetMainColor());
501 for(Int_t j = 0; j<fNRPnts; j++)
502 nt->SetPoint(j, fRPnts[j].x, fRPnts[j].y, fRPnts[j].z);
503 orig_tl->AddElement(nt);
508 if(start != orig->GetN()-1) {
509 // printf("finish last track %d %d\n", start,orig->GetN()-1);
510 Track* nt = new Track();
511 Vector* tp = fProjection->Project(&pnts[start], orig->GetN()-start, kFALSE);
512 ReducePoints(tp, orig->GetN()-start);
514 nt->SetMainColor(orig->GetMainColor());
515 for(Int_t j = 0; j<fNRPnts; j++)
516 nt->SetPoint(j, fRPnts[j].x, fRPnts[j].y, fRPnts[j].z);
517 orig_tl->AddElement(nt);
520 // destroy unprojected
524 // remove original tracks
525 for(Int_t c=0; c<Nc; c++)
527 i = orig_tl->BeginChildren();