]> git.uio.no Git - u/mrichter/AliRoot.git/blame - EVE/Reve/NLTProjector.cxx
Refix triangle/vertex accessors.
[u/mrichter/AliRoot.git] / EVE / Reve / NLTProjector.cxx
CommitLineData
debf9f47 1#include "NLTProjector.h"
2#include "RGTopFrame.h"
3#include "NLTPolygonSet.h"
4#include "PODs.h"
5#include "PointSet.h"
6#include "Track.h"
7
8#include "TBuffer3D.h"
9#include "TColor.h"
10#include "TPointSet3D.h"
11#include "TGeoManager.h"
12#include "TGeoMatrix.h"
13
14#include <list>
15
16using namespace Reve;
17
18namespace {
19 struct Seg {
20 Int_t v1;
21 Int_t v2;
22
23 Seg(Int_t i1=-1, Int_t i2=-1):v1(i1), v2(i2){};
24 };
25
26 typedef std::list<Seg>::iterator It_t;
27}
28
29//______________________________________________________________________________
30Vector* NLTProjection::Project(Vector* origPnts, Int_t Npnts, Bool_t copy)
31{
32 Vector* pnts = 0;
33 if(copy)
34 {
35 pnts = (Vector* )malloc(Npnts*sizeof(Vector));
36 memcpy(pnts, origPnts, Npnts*sizeof(Vector));
37 }
38 else
39 {
40 pnts = origPnts;
41 }
42 return pnts;
43}
44
45//______________________________________________________________________________
46Vector* RhoZ::Project(Vector* origPnts, Int_t Npnts, Bool_t copy)
47{
48 Vector* pnts = NLTProjection::Project(origPnts, Npnts, copy);
49 Float_t R, NR, y, z;
50 for(Int_t i = 0; i<Npnts; i++)
51 {
52 R = pnts[i].R();
53 NR =R/(1+R*fDistortion);
54 y = ( pnts[i].y > 0) ? NR : -NR;
55 z = pnts[i].z;
56 pnts[i].Set(z/(1+TMath::Abs(z*fDistortion)), y, 0);
57 }
58 return pnts;
59}
60
61//______________________________________________________________________________
62Bool_t RhoZ::AcceptSegment(Vector& v1, Vector& v2)
63{
64 return (v1.y*v2.y < 0) ? kFALSE : kTRUE;
65}
66
67//______________________________________________________________________________
68Vector* CircularFishEye::Project(Vector* origPnts, Int_t Npnts, Bool_t copy )
69{
70 Vector* pnts = NLTProjection::Project(origPnts, Npnts, copy);
71
72 Float_t R, NR, phi;
73 for(Int_t i = 0; i<Npnts; i++) {
74 R = pnts[i].R();
75 phi = pnts[i].Phi();
76 NR = R/(1+R*fDistortion);
77 pnts[i].Set(NR*TMath::Cos(phi), NR*TMath::Sin(phi), 0);
78 }
79
80 return pnts;
81}
82
83/**************************************************************************/
84/**************************************************************************/
85//______________________________________________________________________
86// NLTProjector
87//
88
89ClassImp(NLTProjector)
90
91NLTProjector::NLTProjector():
92 TNamed("NLTProjector",""),
93 fProjection(0),
94 fEps(0.05),fIdxMap(0),
95 fNRPnts(0), fRPnts(0)
96{
97}
98
99//______________________________________________________________________________
100NLTProjector::~NLTProjector()
101{
102 CleanUp();
103
104 if(fProjection) delete fProjection;
105}
106
107//______________________________________________________________________________
108void NLTProjector::CleanUp()
109{
110 if(fIdxMap)
111 {
112 delete [] fIdxMap;
113 fIdxMap = 0;
114 }
115 if(fRPnts)
116 {
117 delete [] fRPnts;
118 fNRPnts = 0;
119 fRPnts = 0;
120 }
121}
122
123/**************************************************************************/
124void NLTProjector::SetProjection(NLTProjection::Type_e type, Float_t distort)
125{
126 static const Exc_t eH("NLTProjector::SetProjection ");
127 switch (type)
128 {
129 case NLTProjection::RhoZ:
130 {
131 fProjection = new RhoZ();
132 break;
133 }
134 case NLTProjection::CFishEye:
135 {
136 fProjection = new CircularFishEye();
137 break;
138 }
139 default:
140 throw(eH + "projection type not valid.");
141 break;
142 }
143 fProjection->fDistortion = distort;
144}
145
146//______________________________________________________________________________
147void NLTProjector::DumpBuffer(TBuffer3D* buff)
148{
149 Int_t* bpols = buff->fPols;
150
151 for(UInt_t pi = 0; pi< buff->NbPols(); pi++)
152 {
153 UInt_t Nseg = bpols[1];
154 printf("%d polygon of %d has %d segments \n", pi,buff->NbPols(),Nseg);
155
156 Int_t* seg = &bpols[2];
157 for(UInt_t a=0; a<Nseg; a++)
158 {
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]);
165 }
166 printf("\n");
167 bpols += (Nseg+2);
168 }
169}
170
171//______________________________________________________________________________
172void NLTProjector::CheckPoint(Int_t idx, Float_t* bbox)
173{
174 if(fRPnts[idx].x < bbox[0]) bbox[0] = fRPnts[idx].x;
175 if(fRPnts[idx].x > bbox[1]) bbox[1] = fRPnts[idx].x;
176
177 if(fRPnts[idx].y < bbox[2]) bbox[2] = fRPnts[idx].y;
178 if(fRPnts[idx].y > bbox[3]) bbox[3] = fRPnts[idx].y;
179
180 if(fRPnts[idx].z < bbox[4]) bbox[4] = fRPnts[idx].z;
181 if(fRPnts[idx].z > bbox[5]) bbox[5] = fRPnts[idx].z;
182}
183
184//______________________________________________________________________________
185Bool_t NLTProjector::IsFirstIdxHead(Int_t s0, Int_t s1, TBuffer3D* buff)
186{
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 )
191 return kTRUE;
192 else
193 return kFALSE;
194}
195
196//______________________________________________________________________________
197void NLTProjector::ReducePoints(Vector* pnts, Int_t N)
198{
199 fIdxMap = new Int_t[N];
200 Int_t* ra = new Int_t[N]; // list of reduced vertices
201 fNRPnts = 0;
202
203 for(UInt_t v = 0; v < (UInt_t)N; v++)
204 {
205 fIdxMap[v] = -1;
206 for(Int_t k = 0; k<fNRPnts; k++)
207 {
208 if(pnts[v].SquareDistance(pnts[ra[k]]) < fEps*fEps)
209 {
210 fIdxMap[v] = k;
211 break;
212 }
213 }
214 // have not find a point inside epsilon, add new point in scaled array
215 if(fIdxMap[v] == -1)
216 {
217 fIdxMap[v] = fNRPnts;
218 ra[fNRPnts] = v;
219 fNRPnts++;
220 }
221 // printf("(%f, %f) vertex map %d -> %d \n", pnts[v*2], pnts[v*2 + 1], v, fIdxMap[v]);
222 }
223
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);
228
229 delete [] ra;
230 // printf("reduced %d points of %d\n", fNRPnts, N);
231}
232
233//______________________________________________________________________________
234void NLTProjector::MakePolygonsFromBP(TBuffer3D* buff, std::list<NLTPolygon>& pols)
235{
236 // printf("START NLTProjector::MakePolygonsFromBP\n");
237 Int_t* bpols = buff->fPols;
238 for(UInt_t pi = 0; pi< buff->NbPols(); pi++)
239 {
240 std::list<Int_t> pp; // points in current polygon
241 UInt_t Nseg = bpols[1];
242 Int_t* seg = &bpols[2];
243
244 // start idx in the fist segment depends of second segment
245 Int_t tail, head;
246 Bool_t h = IsFirstIdxHead(seg[0], seg[1], buff);
247 if(h) {
248 head = fIdxMap[buff->fSegs[3*seg[0] + 1]];
249 tail = fIdxMap[buff->fSegs[3*seg[0] + 2]];
250 }
251 else {
252 head = fIdxMap[buff->fSegs[3*seg[0] + 2]];
253 tail = fIdxMap[buff->fSegs[3*seg[0] + 1]];
254 }
255 Float_t bbox[] = {0., 0., 0., 0., 0., 0.};
256 pp.push_back(head);
257 CheckPoint(head, bbox);
258 // printf("start idx head %d, tail %d\n", head, tail);
259
260 std::list<Seg> segs;
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++ )
265 {
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)
270 {
271 pp.clear();
272 break;
273 }
274 if(tail != pp.back())
275 {
276 pp.push_back(tail);
277 CheckPoint(tail, bbox);
278 }
279 tail = (mv1 == tail) ? mv2 :mv1;
280 }
281
282 // render class loops indices last and first should not be equal
283 if(accepted && pp.front() == pp.back())
284 pp.pop_front();
285
286
287 if( pp.size()>2 && (bbox[1]-bbox[0])>fEps && (bbox[3]-bbox[2])>fEps)
288 {
289 Bool_t duplicate = kFALSE;
f36b73bd 290 for (std::list<NLTPolygon>::iterator poi = pols.begin(); poi!= pols.end(); poi++)
debf9f47 291 {
f36b73bd 292 NLTPolygon P = *poi;
debf9f47 293 if(pp.size() != (UInt_t)P.fNPnts)
294 continue;
295 Int_t matched = 0;
f36b73bd 296 for (std::list<Int_t>::iterator u = pp.begin(); u!= pp.end(); u++) {
297 if (*u == P.fPnts[*u]) matched++;
debf9f47 298 else continue;
299 }
f36b73bd 300 if (matched == P.fNPnts) {
debf9f47 301 duplicate = kTRUE;
302 break;
303 }
304 }
305
306 if(duplicate == kFALSE)
307 {
308 Int_t* pv = new Int_t[pp.size()];
309 Int_t count=0;
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++){
313 pv[count] = *u;
314 count++;
315 }
316 pols.push_back(NLTPolygon(pp.size(), pv));
317 }
318 } // end of NLTPolygon
319 bpols += (Nseg+2);
320 }
321}// MakePolygonsFromBP
322
323//______________________________________________________________________________
324void NLTProjector::MakePolygonsFromBS(TBuffer3D* buff, std::list<NLTPolygon>& pols)
325{
326 // create your own list of segments according to reduced and projected points
327 std::list<Seg> segs;
328 std::list<Seg>::iterator it;
329 for(UInt_t s=0; s< buff->NbSegs(); s++)
330 {
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
336 vor1 = fIdxMap[vo1];
337 vor2 = fIdxMap[vo2];
338 if(vor1 == vor2) continue;
339 // check duplicate
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 )){
344 duplicate = kTRUE;
345 continue;
346 }
347 }
348 if(duplicate == kFALSE && fProjection->AcceptSegment(fRPnts[vor1], fRPnts[vor2]))
349 {
350 segs.push_back(Seg(vor1, vor2));
351 }
352 }
353
354 while(segs.empty() == kFALSE)
355 {
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;
360 segs.pop_front();
361 Bool_t match = kTRUE;
362 while(match && segs.empty() == kFALSE)
363 {
364 // printf("second loop search tail %d \n",tail);
365 for(It_t k=segs.begin(); k!=segs.end(); ++k){
366 Int_t cv1 = (*k).v1;
367 Int_t cv2 = (*k).v2;
368 if( cv1 == tail || cv2 == tail){
369 // printf("found point %d in %d,%d \n", tail, cv1, cv2);
370 pp.push_back(tail);
371 if(cv1 == tail)
372 tail = cv2;
373 else
374 tail = cv1;
375
376 It_t to_erase = k--;
377 segs.erase(to_erase);
378 match = kTRUE;
379 break;
380 }
381 else
382 {
383 match = kFALSE;
384 }
385 } // end for loop in the segment pool
386 if(tail == pp.front())
387 break;
388 };
389
390 if(pp.size() > 2){
391 // printf("CLOSING polygon %d with %d points \n", pols.size(),pp.size());
392 Int_t* pv = new Int_t[pp.size()];
393 Int_t count=0;
394 for( std::list<Int_t>::iterator u = pp.begin(); u!= pp.end(); u++){
395 pv[count] = *u;
396 count++;
397 }
398 pols.push_back(NLTPolygon(pp.size(), pv));
399 }
400 } // while segment pool empty
401}//MakePolygonsFromBS
402
403 //______________________________________________________________________________
404NLTPolygonSet* NLTProjector::ProjectGeoShape(TBuffer3D* buff, Int_t useBuffPols)
405{
406 // DumpBuffer(buff);
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]);
411
412 fProjection->Project(pnts, buff->NbPnts(), kFALSE);
413 ReducePoints(pnts, buff->NbPnts());
414
415 // build polygons
416 std::list<NLTPolygon> pols;
417 if(useBuffPols == -1)
418 {
419 MakePolygonsFromBP(buff, pols);
420 if(pols.empty())
421 {
422 // printf("useBuffPols == -1 call MakePolygonsFromBS \n");
423 MakePolygonsFromBS(buff, pols);
424 }
425 }
426 if(useBuffPols == 1)
427 {
428 MakePolygonsFromBP(buff, pols);
429 }
430 if(useBuffPols == 0)
431 {
432 MakePolygonsFromBS(buff, pols);
433 }
434
435 NLTPolygonSet* ps = new NLTPolygonSet();
436 if(pols.empty() == kFALSE)
437 {
438 // points
439 ps->SetPoints(fRPnts,fNRPnts);
440 // polygons
441 NLTPolygon* nltp = new NLTPolygon[pols.size()];
442 Int_t pc = 0;
443 for( std::list<NLTPolygon>::iterator pi = pols.begin(); pi!= pols.end(); pi++)
444 {
445 nltp[pc].fNPnts = (*pi).fNPnts;
446 nltp[pc].fPnts = (*pi).fPnts;
447 pc++;
448 }
449 ps->SetPolygons(nltp, pols.size());
450 // ps->Dump();
451 }
452 fRPnts = 0;
453 CleanUp();
454 return ps;
455}
456
457//______________________________________________________________________________
458void NLTProjector::ProjectPointSet(PointSet* orig)
459{
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);
470 }
471
472 CleanUp();
473}
474
475//______________________________________________________________________________
476void NLTProjector::ProjectTrackList(TrackList* orig_tl)
477{
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++)
482 {
483 // printf("project track with %d points \n", orig->GetN());
484 Track* orig = dynamic_cast<Track*>(*i);
485 Int_t start = 0;
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]);
491
492 for( Int_t k=0; k<orig->GetN()-1; k++)
493 {
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();
499 nt->Reset(fNRPnts);
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);
504 CleanUp();
505 start = k+1;
506 }
507 }
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);
513 nt->Reset(fNRPnts);
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);
518 CleanUp();
519 }
520 // destroy unprojected
521 ++i;
522 } // end loop tracks
523
524 // remove original tracks
525 for(Int_t c=0; c<Nc; c++)
526 {
527 i = orig_tl->BeginChildren();
528 (*i)->Destroy();
529 }
530}