00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #include "TEvePolygonSetProjected.h"
00013 #include "TEveGeoShape.h"
00014 #include "TEveProjectionManager.h"
00015
00016 #include "TBuffer3D.h"
00017 #include "TBuffer3DTypes.h"
00018 #include "TVirtualPad.h"
00019 #include "TVirtualViewer3D.h"
00020
00021 namespace
00022 {
00023 struct Seg_t
00024 {
00025
00026 Int_t fV1;
00027 Int_t fV2;
00028
00029 Seg_t(Int_t i1=-1, Int_t i2=-1) : fV1(i1), fV2(i2) {}
00030 };
00031
00032 typedef std::list<Seg_t> LSeg_t;
00033 typedef std::list<Seg_t>::iterator LSegIt_t;
00034 }
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050 ClassImp(TEvePolygonSetProjected);
00051
00052
00053 TEvePolygonSetProjected::TEvePolygonSetProjected(const char* n, const char* t) :
00054 TEveShape(n, t),
00055 fBuff(0),
00056 fNPnts(0),
00057 fPnts(0)
00058 {
00059
00060 }
00061
00062
00063 TEvePolygonSetProjected::~TEvePolygonSetProjected()
00064 {
00065
00066
00067 fPols.clear();
00068 if (fPnts) delete [] fPnts;
00069 if (fBuff) delete fBuff;
00070 }
00071
00072
00073 void TEvePolygonSetProjected::ComputeBBox()
00074 {
00075
00076
00077 if (fNPnts > 0) {
00078 BBoxInit();
00079 for (Int_t pi = 0; pi < fNPnts; ++pi)
00080 BBoxCheckPoint(fPnts[pi].fX, fPnts[pi].fY, fPnts[pi].fZ);
00081 } else {
00082 BBoxZero();
00083 }
00084 }
00085
00086
00087
00088
00089
00090 void TEvePolygonSetProjected::SetProjection(TEveProjectionManager* mng,
00091 TEveProjectable* model)
00092 {
00093
00094
00095 TEveProjected::SetProjection(mng, model);
00096
00097 TEveGeoShape* gre = dynamic_cast<TEveGeoShape*>(model);
00098 fBuff = gre->MakeBuffer3D();
00099 CopyVizParams(gre);
00100 }
00101
00102
00103 void TEvePolygonSetProjected::SetDepthLocal(Float_t d)
00104 {
00105
00106
00107 SetDepthCommon(d, this, fBBox);
00108
00109 for (Int_t i = 0; i < fNPnts; ++i)
00110 fPnts[i].fZ = fDepth;
00111 }
00112
00113
00114 void TEvePolygonSetProjected::UpdateProjection()
00115 {
00116
00117
00118 if (fBuff == 0) return;
00119
00120
00121 fPols.clear();
00122 ProjectBuffer3D();
00123 }
00124
00125
00126 Bool_t TEvePolygonSetProjected::IsFirstIdxHead(Int_t s0, Int_t s1)
00127 {
00128
00129
00130 Int_t v0 = fBuff->fSegs[3*s0 + 1];
00131 Int_t v2 = fBuff->fSegs[3*s1 + 1];
00132 Int_t v3 = fBuff->fSegs[3*s1 + 2];
00133 return v0 != v2 && v0 != v3;
00134 }
00135
00136
00137 Int_t* TEvePolygonSetProjected::ProjectAndReducePoints()
00138 {
00139
00140
00141 TEveProjection* projection = fManager->GetProjection();
00142
00143 Int_t buffN = fBuff->NbPnts();
00144 TEveVector* pnts = new TEveVector[buffN];
00145 for (Int_t i = 0; i < buffN; ++i)
00146 {
00147 pnts[i].Set(fBuff->fPnts[3*i],fBuff->fPnts[3*i+1], fBuff->fPnts[3*i+2]);
00148 projection->ProjectPoint(pnts[i].fX, pnts[i].fY, pnts[i].fZ, 0,
00149 TEveProjection::kPP_Plane);
00150 }
00151
00152 if (fPnts) delete [] fPnts;
00153 fNPnts=0;
00154 Int_t *idxMap = new Int_t[buffN];
00155 Int_t *ra = new Int_t[buffN];
00156 for (UInt_t v = 0; v < (UInt_t)buffN; ++v)
00157 {
00158 idxMap[v] = -1;
00159 for (Int_t k = 0; k < fNPnts; ++k)
00160 {
00161 if (pnts[v].SquareDistance(pnts[ra[k]]) < TEveProjection::fgEpsSqr)
00162 {
00163 idxMap[v] = k;
00164 break;
00165 }
00166 }
00167
00168 if (idxMap[v] == -1)
00169 {
00170 idxMap[v] = fNPnts;
00171 ra[fNPnts] = v;
00172 ++fNPnts;
00173 }
00174 }
00175
00176
00177 fPnts = new TEveVector[fNPnts];
00178 for (Int_t idx = 0; idx < fNPnts; ++idx)
00179 {
00180 Int_t i = ra[idx];
00181 projection->ProjectPoint(pnts[i].fX, pnts[i].fY, pnts[i].fZ, fDepth,
00182 TEveProjection::kPP_Distort);
00183 fPnts[idx].Set(pnts[i]);
00184 }
00185 delete [] ra;
00186 delete [] pnts;
00187
00188
00189 return idxMap;
00190 }
00191
00192
00193 Float_t TEvePolygonSetProjected::AddPolygon(std::list<Int_t>& pp, vpPolygon_t& pols)
00194 {
00195
00196
00197
00198 if (pp.size() <= 2) return 0;
00199
00200 Float_t bbox[4] = { 1e6, -1e6, 1e6, -1e6 };
00201 for (std::list<Int_t>::iterator u = pp.begin(); u != pp.end(); ++u)
00202 {
00203 Int_t idx = *u;
00204 if (fPnts[idx].fX < bbox[0]) bbox[0] = fPnts[idx].fX;
00205 if (fPnts[idx].fX > bbox[1]) bbox[1] = fPnts[idx].fX;
00206
00207 if (fPnts[idx].fY < bbox[2]) bbox[2] = fPnts[idx].fY;
00208 if (fPnts[idx].fY > bbox[3]) bbox[3] = fPnts[idx].fY;
00209 }
00210 Float_t eps = 2*TEveProjection::fgEps;
00211 if ((bbox[1]-bbox[0]) < eps || (bbox[3]-bbox[2]) < eps) return 0;
00212
00213
00214 for (vpPolygon_i poi = pols.begin(); poi != pols.end(); ++poi)
00215 {
00216 Polygon_t& refP = *poi;
00217
00218 if ((Int_t) pp.size() != refP.fNPnts)
00219 continue;
00220
00221 Int_t start_idx = refP.FindPoint(pp.front());
00222 if (start_idx < 0)
00223 continue;
00224 if (++start_idx >= refP.fNPnts) start_idx = 0;
00225
00226
00227 {
00228 std::list<Int_t>::iterator u = ++pp.begin();
00229 Int_t pidx = start_idx;
00230 while (u != pp.end())
00231 {
00232 if ((*u) != refP.fPnts[pidx])
00233 break;
00234 ++u;
00235 if (++pidx >= refP.fNPnts) pidx = 0;
00236 }
00237 if (u == pp.end()) return 0;
00238 }
00239
00240 {
00241 std::list<Int_t>::iterator u = --pp.end();
00242 Int_t pidx = start_idx;
00243 while (u != pp.begin())
00244 {
00245 if ((*u) != refP.fPnts[pidx])
00246 break;
00247 --u;
00248 if (++pidx >= refP.fNPnts) pidx = 0;
00249 }
00250 if (u == pp.begin()) return 0;
00251 }
00252 }
00253
00254 Int_t *pv = new Int_t[pp.size()];
00255 Int_t count = 0;
00256 for (std::list<Int_t>::iterator u = pp.begin(); u != pp.end(); ++u)
00257 {
00258 pv[count] = *u;
00259 ++count;
00260 }
00261
00262 pols.push_back(Polygon_t());
00263 pols.back().fNPnts = pp.size();
00264 pols.back().fPnts = &pv[0];
00265
00266 return (bbox[1]-bbox[0]) * (bbox[3]-bbox[2]);
00267 }
00268
00269
00270 Float_t TEvePolygonSetProjected::MakePolygonsFromBP(Int_t* idxMap)
00271 {
00272
00273
00274 TEveProjection* projection = fManager->GetProjection();
00275 Int_t *bpols = fBuff->fPols;
00276 Float_t surf = 0;
00277 for (UInt_t pi = 0; pi < fBuff->NbPols(); ++pi)
00278 {
00279 std::list<Int_t> pp;
00280 UInt_t segN = bpols[1];
00281 Int_t *seg = &bpols[2];
00282
00283 Int_t tail, head;
00284 if (IsFirstIdxHead(seg[0], seg[1]))
00285 {
00286 head = idxMap[fBuff->fSegs[3*seg[0] + 1]];
00287 tail = idxMap[fBuff->fSegs[3*seg[0] + 2]];
00288 }
00289 else
00290 {
00291 head = idxMap[fBuff->fSegs[3*seg[0] + 2]];
00292 tail = idxMap[fBuff->fSegs[3*seg[0] + 1]];
00293 }
00294 pp.push_back(head);
00295
00296 LSeg_t segs;
00297 for (UInt_t s = 1; s < segN; ++s)
00298 segs.push_back(Seg_t(fBuff->fSegs[3*seg[s] + 1],fBuff->fSegs[3*seg[s] + 2]));
00299
00300 for (LSegIt_t it = segs.begin(); it != segs.end(); ++it)
00301 {
00302 Int_t mv1 = idxMap[(*it).fV1];
00303 Int_t mv2 = idxMap[(*it).fV2];
00304
00305 if ( ! projection->AcceptSegment(fPnts[mv1], fPnts[mv2], TEveProjection::fgEps))
00306 {
00307 pp.clear();
00308 break;
00309 }
00310 if (tail != pp.back()) pp.push_back(tail);
00311 tail = (mv1 == tail) ? mv2 : mv1;
00312 }
00313
00314 if ( ! pp.empty())
00315 {
00316
00317 if (pp.front() == pp.back()) pp.pop_front();
00318 surf += AddPolygon(pp, fPolsBP);
00319 }
00320 bpols += (segN+2);
00321 }
00322 return surf;
00323 }
00324
00325
00326 Float_t TEvePolygonSetProjected::MakePolygonsFromBS(Int_t* idxMap)
00327 {
00328
00329
00330
00331
00332 LSeg_t segs;
00333 LSegIt_t it;
00334 Float_t surf = 0;
00335 TEveProjection *projection = fManager->GetProjection();
00336 for (UInt_t s = 0; s < fBuff->NbSegs(); ++s)
00337 {
00338 Bool_t duplicate = kFALSE;
00339 Int_t vo1, vo2;
00340 Int_t vor1, vor2;
00341 vo1 = fBuff->fSegs[3*s + 1];
00342 vo2 = fBuff->fSegs[3*s + 2];
00343 vor1 = idxMap[vo1];
00344 vor2 = idxMap[vo2];
00345 if (vor1 == vor2) continue;
00346
00347 for (it = segs.begin(); it != segs.end(); ++it)
00348 {
00349 Int_t vv1 = (*it).fV1;
00350 Int_t vv2 = (*it).fV2;
00351 if((vv1 == vor1 && vv2 == vor2) || (vv1 == vor2 && vv2 == vor1))
00352 {
00353 duplicate = kTRUE;
00354 continue;
00355 }
00356 }
00357 if (duplicate == kFALSE && projection->AcceptSegment(fPnts[vor1], fPnts[vor2], TEveProjection::fgEps))
00358 segs.push_back(Seg_t(vor1, vor2));
00359 }
00360
00361 while ( ! segs.empty())
00362 {
00363 std::list<Int_t> pp;
00364 pp.push_back(segs.front().fV1);
00365 Int_t tail = segs.front().fV2;
00366 segs.pop_front();
00367 Bool_t match = kTRUE;
00368 while (match && ! segs.empty())
00369 {
00370 for (LSegIt_t k = segs.begin(); k != segs.end(); ++k)
00371 {
00372 Int_t cv1 = (*k).fV1;
00373 Int_t cv2 = (*k).fV2;
00374 if (cv1 == tail || cv2 == tail)
00375 {
00376 pp.push_back(tail);
00377 tail = (cv1 == tail) ? cv2 : cv1;
00378 segs.erase(k);
00379 match = kTRUE;
00380 break;
00381 }
00382 else
00383 {
00384 match = kFALSE;
00385 }
00386 }
00387 if (tail == pp.front())
00388 break;
00389 }
00390 surf += AddPolygon(pp, fPolsBS);
00391 }
00392 return surf;
00393 }
00394
00395
00396 void TEvePolygonSetProjected::ProjectBuffer3D()
00397 {
00398
00399
00400
00401 Int_t* idxMap = ProjectAndReducePoints();
00402
00403 TEveProjection::EGeoMode_e mode = fManager->GetProjection()->GetGeoMode();
00404 switch (mode)
00405 {
00406 case TEveProjection::kGM_Polygons :
00407 {
00408 MakePolygonsFromBP(idxMap);
00409 fPolsBP.swap(fPols);
00410 break;
00411 }
00412 case TEveProjection::kGM_Segments :
00413 {
00414 MakePolygonsFromBS(idxMap);
00415 fPolsBS.swap(fPols);
00416 break;
00417 }
00418 case TEveProjection::kGM_Unknown:
00419 {
00420
00421 Float_t surfBP = MakePolygonsFromBP(idxMap);
00422 Float_t surfBS = MakePolygonsFromBS(idxMap);
00423 if (surfBS < surfBP)
00424 {
00425 fPolsBP.swap(fPols);
00426 fPolsBS.clear();
00427 }
00428 else
00429 {
00430 fPolsBS.swap(fPols);
00431 fPolsBP.clear();
00432 }
00433 }
00434 default:
00435 break;
00436 }
00437
00438 delete [] idxMap;
00439 ResetBBox();
00440 }
00441
00442
00443 Float_t TEvePolygonSetProjected::PolygonSurfaceXY(const TEvePolygonSetProjected::Polygon_t& p) const
00444 {
00445
00446
00447 Float_t surf = 0;
00448 Int_t nPnts = p.fNPnts;
00449 for (Int_t i = 0; i < nPnts - 1; ++i)
00450 {
00451 Int_t a = p.fPnts[i];
00452 Int_t b = p.fPnts[i+1];
00453 surf += fPnts[a].fX * fPnts[b].fY - fPnts[a].fY * fPnts[b].fX;
00454 }
00455 return 0.5f * TMath::Abs(surf);
00456 }
00457
00458
00459 void TEvePolygonSetProjected::DumpPolys() const
00460 {
00461
00462
00463 printf("TEvePolygonSetProjected %d polygons\n", (Int_t)fPols.size());
00464 Int_t cnt = 0;
00465 for (vpPolygon_ci i = fPols.begin(); i!= fPols.end(); i++)
00466 {
00467 Int_t nPnts = (*i).fNPnts;
00468 printf("Points of polygon %d [Np = %d]:\n", ++cnt, nPnts);
00469 for (Int_t vi = 0; vi<nPnts; ++vi) {
00470 Int_t pi = (*i).fPnts[vi];
00471 printf(" (%f, %f, %f)", fPnts[pi].fX, fPnts[pi].fY, fPnts[pi].fZ);
00472 }
00473 printf(", surf=%f\n", PolygonSurfaceXY(*i));
00474 }
00475 }
00476
00477
00478 void TEvePolygonSetProjected::DumpBuffer3D()
00479 {
00480
00481
00482 Int_t* bpols = fBuff->fPols;
00483
00484 for (UInt_t pi = 0; pi< fBuff->NbPols(); ++pi)
00485 {
00486 UInt_t segN = bpols[1];
00487 printf("%d polygon of %d has %d segments \n", pi, fBuff->NbPols(), segN);
00488
00489 Int_t* seg = &bpols[2];
00490 for (UInt_t a=0; a<segN; ++a)
00491 {
00492 Int_t a1 = fBuff->fSegs[3*seg[a] + 1];
00493 Int_t a2 = fBuff->fSegs[3*seg[a] + 2];
00494 printf("(%d, %d) \n", a1, a2);
00495 printf("ORIG points :(%f, %f, %f) (%f, %f, %f)\n",
00496 fBuff->fPnts[3*a1],fBuff->fPnts[3*a1+1], fBuff->fPnts[3*a1+2],
00497 fBuff->fPnts[3*a2],fBuff->fPnts[3*a2+1], fBuff->fPnts[3*a2+2]);
00498 }
00499 printf("\n");
00500 bpols += (segN+2);
00501 }
00502 }