00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #include "TROOT.h"
00017 #include "TClass.h"
00018 #include "TColor.h"
00019 #include "TPoint.h"
00020 #include "TView.h"
00021 #include "TAttLine.h"
00022 #include "TAttFill.h"
00023 #include "TPad.h"
00024 #include "TCanvas.h"
00025 #include "TH2F.h"
00026 #include "TF1.h"
00027 #include "TPluginManager.h"
00028 #include "TVirtualPadEditor.h"
00029 #include "TStopwatch.h"
00030
00031 #include "TPolyMarker3D.h"
00032 #include "TVirtualGL.h"
00033
00034 #include "TGeoAtt.h"
00035 #include "TGeoVolume.h"
00036 #include "TGeoNode.h"
00037 #include "TGeoManager.h"
00038 #include "TGeoTrack.h"
00039 #include "TGeoOverlap.h"
00040 #include "TGeoChecker.h"
00041 #include "TGeoPhysicalNode.h"
00042 #include "TGeoCompositeShape.h"
00043 #include "TGeoShapeAssembly.h"
00044 #include "TGeoPainter.h"
00045 #include "TMath.h"
00046
00047 #include "X3DBuffer.h"
00048
00049 #include "TBuffer3D.h"
00050 #include "TBuffer3DTypes.h"
00051 #include "TVirtualViewer3D.h"
00052
00053 ClassImp(TGeoPainter)
00054
00055
00056 TGeoPainter::TGeoPainter(TGeoManager *manager) : TVirtualGeoPainter(manager)
00057 {
00058
00059
00060 TVirtualGeoPainter::SetPainter(this);
00061 if (manager) fGeoManager = manager;
00062 else {
00063 Error("ctor", "No geometry loaded");
00064 return;
00065 }
00066 fNsegments = fGeoManager->GetNsegments();
00067 fNVisNodes = 0;
00068 fBombX = 1.3;
00069 fBombY = 1.3;
00070 fBombZ = 1.3;
00071 fBombR = 1.3;
00072 fVisLevel = fGeoManager->GetVisLevel();
00073 fVisOption = fGeoManager->GetVisOption();
00074 fExplodedView = fGeoManager->GetBombMode();
00075 fVisBranch = "";
00076 fVolInfo = "";
00077 fVisLock = kFALSE;
00078 fIsRaytracing = kFALSE;
00079 fTopVisible = kFALSE;
00080 fPaintingOverlaps = kFALSE;
00081 fPlugin = 0;
00082 fVisVolumes = new TObjArray();
00083 fOverlap = 0;
00084 fGlobal = new TGeoHMatrix();
00085 fBuffer = new TBuffer3D(TBuffer3DTypes::kGeneric,20,3*20,0,0,0,0);
00086 fClippingShape = 0;
00087 fLastVolume = 0;
00088 fTopVolume = 0;
00089 fIsPaintingShape = kFALSE;
00090 memset(&fCheckedBox[0], 0, 6*sizeof(Double_t));
00091
00092 fCheckedNode = fGeoManager->GetTopNode();
00093 fChecker = new TGeoChecker(fGeoManager);
00094 fIsEditable = kFALSE;
00095 DefineColors();
00096 }
00097
00098 TGeoPainter::~TGeoPainter()
00099 {
00100
00101
00102 if (fChecker) delete fChecker;
00103 delete fVisVolumes;
00104 delete fGlobal;
00105 delete fBuffer;
00106 if (fPlugin) delete fPlugin;
00107 }
00108
00109 void TGeoPainter::AddSize3D(Int_t numpoints, Int_t numsegs, Int_t numpolys)
00110 {
00111
00112 gSize3D.numPoints += numpoints;
00113 gSize3D.numSegs += numsegs;
00114 gSize3D.numPolys += numpolys;
00115 }
00116
00117 TVirtualGeoTrack *TGeoPainter::AddTrack(Int_t id, Int_t pdgcode, TObject *particle)
00118 {
00119
00120 return (TVirtualGeoTrack*)(new TGeoTrack(id,pdgcode,0,particle));
00121 }
00122
00123
00124 void TGeoPainter::AddTrackPoint(Double_t *point, Double_t *box, Bool_t reset)
00125 {
00126
00127 static Int_t npoints = 0;
00128 static Double_t xmin[3] = {0,0,0};
00129 static Double_t xmax[3] = {0,0,0};
00130 Int_t i;
00131 if (reset) {
00132 memset(box, 0, 6*sizeof(Double_t));
00133 memset(xmin, 0, 3*sizeof(Double_t));
00134 memset(xmax, 0, 3*sizeof(Double_t));
00135 npoints = 0;
00136 return;
00137 }
00138 if (npoints==0) {
00139 for (i=0; i<3; i++) xmin[i]=xmax[i]=0;
00140 npoints++;
00141 }
00142 npoints++;
00143 Double_t ninv = 1./Double_t(npoints);
00144 for (i=0; i<3; i++) {
00145 box[i] += ninv*(point[i]-box[i]);
00146 if (point[i]<xmin[i]) xmin[i]=point[i];
00147 if (point[i]>xmax[i]) xmax[i]=point[i];
00148 box[i+3] = 0.5*(xmax[i]-xmin[i]);
00149 }
00150 }
00151
00152
00153 void TGeoPainter::BombTranslation(const Double_t *tr, Double_t *bombtr)
00154 {
00155
00156 memcpy(bombtr, tr, 3*sizeof(Double_t));
00157 switch (fExplodedView) {
00158 case kGeoNoBomb:
00159 return;
00160 case kGeoBombXYZ:
00161 bombtr[0] *= fBombX;
00162 bombtr[1] *= fBombY;
00163 bombtr[2] *= fBombZ;
00164 return;
00165 case kGeoBombCyl:
00166 bombtr[0] *= fBombR;
00167 bombtr[1] *= fBombR;
00168 bombtr[2] *= fBombZ;
00169 return;
00170 case kGeoBombSph:
00171 bombtr[0] *= fBombR;
00172 bombtr[1] *= fBombR;
00173 bombtr[2] *= fBombR;
00174 return;
00175 default:
00176 return;
00177 }
00178 }
00179
00180
00181 void TGeoPainter::CheckBoundaryErrors(Int_t ntracks, Double_t radius)
00182 {
00183
00184
00185
00186 fChecker->CheckBoundaryErrors(ntracks, radius);
00187 }
00188
00189
00190 void TGeoPainter::CheckBoundaryReference(Int_t icheck)
00191 {
00192
00193
00194
00195 fChecker->CheckBoundaryReference(icheck);
00196 }
00197
00198
00199 void TGeoPainter::CheckGeometryFull(Bool_t checkoverlaps, Bool_t checkcrossings, Int_t ntracks, const Double_t *vertex)
00200 {
00201
00202 fChecker->CheckGeometryFull(checkoverlaps,checkcrossings,ntracks,vertex);
00203 }
00204
00205
00206 void TGeoPainter::CheckGeometry(Int_t nrays, Double_t startx, Double_t starty, Double_t startz) const
00207 {
00208
00209 fChecker->CheckGeometry(nrays, startx, starty, startz);
00210 }
00211
00212
00213 void TGeoPainter::CheckOverlaps(const TGeoVolume *vol, Double_t ovlp, Option_t *option) const
00214 {
00215
00216 fChecker->CheckOverlaps(vol, ovlp, option);
00217 }
00218
00219
00220 void TGeoPainter::CheckPoint(Double_t x, Double_t y, Double_t z, Option_t *option)
00221 {
00222
00223 fChecker->CheckPoint(x,y,z,option);
00224 }
00225
00226
00227 void TGeoPainter::ClearVisibleVolumes()
00228 {
00229
00230
00231
00232 if (!fVisVolumes) return;
00233 TIter next(fVisVolumes);
00234 TGeoVolume *vol;
00235 while ((vol = (TGeoVolume*)next())) {
00236 vol->ResetAttBit(TGeoAtt::kVisOnScreen);
00237 }
00238 fVisVolumes->Clear();
00239 }
00240
00241
00242
00243 void TGeoPainter::DefineColors() const
00244 {
00245
00246
00247 TColor::InitializeColors();
00248 TColor *color = gROOT->GetColor(1000);
00249 if (color) return;
00250 Int_t i,j;
00251 Float_t r,g,b,h,l,s;
00252
00253 for (i=1; i<8; i++) {
00254 color = (TColor*)gROOT->GetListOfColors()->At(i);
00255 if (!color) {
00256 Warning("DefineColors", "No colors defined");
00257 return;
00258 }
00259 color->GetHLS(h,l,s);
00260 for (j=0; j<100; j++) {
00261 l = 0.25+0.5*j/99.;
00262 TColor::HLS2RGB(h,l,s,r,g,b);
00263 new TColor(1000+(i-1)*100+j, r,g,b);
00264 }
00265 }
00266 }
00267
00268
00269 Int_t TGeoPainter::GetColor(Int_t base, Float_t light) const
00270 {
00271
00272 const Int_t kBCols[8] = {1,2,3,5,4,6,7,1};
00273 TColor *tcolor = gROOT->GetColor(base);
00274 if (!tcolor) tcolor = new TColor(base, 0.5,0.5,0.5);
00275 Float_t r,g,b;
00276 tcolor->GetRGB(r,g,b);
00277 Int_t code = 0;
00278 if (r>0.5) code += 1;
00279 if (g>0.5) code += 2;
00280 if (b>0.5) code += 4;
00281 Int_t color, j;
00282
00283 if (light<0.25) {
00284 j=0;
00285 } else {
00286 if (light>0.8) j=99;
00287 else j = Int_t(99*(light-0.25)/0.5);
00288 }
00289 color = 1000 + (kBCols[code]-1)*100+j;
00290 return color;
00291 }
00292
00293
00294 TGeoVolume *TGeoPainter::GetDrawnVolume() const
00295 {
00296
00297 if (!gPad) return 0;
00298 return fTopVolume;
00299 }
00300
00301
00302 Int_t TGeoPainter::DistanceToPrimitiveVol(TGeoVolume *volume, Int_t px, Int_t py)
00303 {
00304
00305 const Int_t big = 9999;
00306 const Int_t inaxis = 7;
00307 const Int_t maxdist = 5;
00308
00309 if (fTopVolume != volume) fTopVolume = volume;
00310 TView *view = gPad->GetView();
00311 if (!view) return big;
00312 TGeoBBox *box;
00313 fGlobal->Clear();
00314 TGeoShape::SetTransform(fGlobal);
00315
00316 Int_t puxmin = gPad->XtoAbsPixel(gPad->GetUxmin());
00317 Int_t puymin = gPad->YtoAbsPixel(gPad->GetUymin());
00318 Int_t puxmax = gPad->XtoAbsPixel(gPad->GetUxmax());
00319 Int_t puymax = gPad->YtoAbsPixel(gPad->GetUymax());
00320
00321 if (px < puxmin - inaxis) return big;
00322 if (py > puymin + inaxis) return big;
00323 if (px > puxmax + inaxis) return big;
00324 if (py < puymax - inaxis) return big;
00325
00326 fCheckedNode = fGeoManager->GetTopNode();
00327 gPad->SetSelected(view);
00328 Int_t dist = big;
00329
00330
00331 if (fPaintingOverlaps) {
00332 TGeoVolume *crt;
00333 crt = fOverlap->GetFirstVolume();
00334 *fGlobal = fOverlap->GetFirstMatrix();
00335 dist = crt->GetShape()->DistancetoPrimitive(px,py);
00336 if (dist<maxdist) {
00337 gPad->SetSelected(crt);
00338 box = (TGeoBBox*)crt->GetShape();
00339 fGlobal->LocalToMaster(box->GetOrigin(), &fCheckedBox[0]);
00340 fCheckedBox[3] = box->GetDX();
00341 fCheckedBox[4] = box->GetDY();
00342 fCheckedBox[5] = box->GetDZ();
00343 return 0;
00344 }
00345 crt = fOverlap->GetSecondVolume();
00346 *fGlobal = fOverlap->GetSecondMatrix();
00347 dist = crt->GetShape()->DistancetoPrimitive(px,py);
00348 if (dist<maxdist) {
00349 gPad->SetSelected(crt);
00350 box = (TGeoBBox*)crt->GetShape();
00351 fGlobal->LocalToMaster(box->GetOrigin(), &fCheckedBox[0]);
00352 fCheckedBox[3] = box->GetDX();
00353 fCheckedBox[4] = box->GetDY();
00354 fCheckedBox[5] = box->GetDZ();
00355 return 0;
00356 }
00357 return big;
00358 }
00359
00360 if ((puxmax+inaxis-px) < 40) {
00361 if ((py-puymax+inaxis) < 40) {
00362
00363 gPad->SetSelected(fGeoManager);
00364 fVolInfo = fGeoManager->GetName();
00365 box = (TGeoBBox*)volume->GetShape();
00366 memcpy(fCheckedBox, box->GetOrigin(), 3*sizeof(Double_t));
00367 fCheckedBox[3] = box->GetDX();
00368 fCheckedBox[4] = box->GetDY();
00369 fCheckedBox[5] = box->GetDZ();
00370 return 0;
00371 }
00372
00373 gPad->SetSelected(volume);
00374 fVolInfo = volume->GetName();
00375 box = (TGeoBBox*)volume->GetShape();
00376 memcpy(fCheckedBox, box->GetOrigin(), 3*sizeof(Double_t));
00377 fCheckedBox[3] = box->GetDX();
00378 fCheckedBox[4] = box->GetDY();
00379 fCheckedBox[5] = box->GetDZ();
00380 return 0;
00381 }
00382
00383 TGeoVolume *vol = volume;
00384 Bool_t vis = vol->IsVisible();
00385
00386
00387 if (volume->IsVisBranch()) {
00388 if (!fGeoManager->IsClosed()) return big;
00389 fGeoManager->PushPath();
00390 fGeoManager->cd(fVisBranch.Data());
00391 while (fGeoManager->GetLevel()) {
00392 vol = fGeoManager->GetCurrentVolume();
00393 *fGlobal = gGeoManager->GetCurrentMatrix();
00394 dist = vol->GetShape()->DistancetoPrimitive(px,py);
00395 if (dist<maxdist) {
00396 fVolInfo = fVisBranch;
00397 box = (TGeoBBox*)vol->GetShape();
00398 fGeoManager->LocalToMaster(box->GetOrigin(), &fCheckedBox[0]);
00399 fCheckedNode = gGeoManager->GetCurrentNode();
00400 if (fGeoManager->IsNodeSelectable()) gPad->SetSelected(fCheckedNode);
00401 else gPad->SetSelected(vol);
00402 fCheckedBox[3] = box->GetDX();
00403 fCheckedBox[4] = box->GetDY();
00404 fCheckedBox[5] = box->GetDZ();
00405 fGeoManager->PopPath();
00406 return 0;
00407 }
00408 fGeoManager->CdUp();
00409 }
00410 fGeoManager->PopPath();
00411 return dist;
00412 }
00413
00414
00415 if ((fTopVisible && vis) || !vol->GetNdaughters() || !vol->IsVisDaughters() || vol->IsVisOnly()) {
00416 dist = vol->GetShape()->DistancetoPrimitive(px,py);
00417 if (dist<maxdist) {
00418 fVolInfo = vol->GetName();
00419 gPad->SetSelected(vol);
00420 box = (TGeoBBox*)vol->GetShape();
00421 memcpy(fCheckedBox, box->GetOrigin(), 3*sizeof(Double_t));
00422 fCheckedBox[3] = box->GetDX();
00423 fCheckedBox[4] = box->GetDY();
00424 fCheckedBox[5] = box->GetDZ();
00425 return 0;
00426 }
00427 if (vol->IsVisOnly() || !vol->GetNdaughters() || !vol->IsVisDaughters())
00428 return dist;
00429 }
00430
00431
00432 TGeoIterator next(vol);
00433 next.SetTopName(TString::Format("%s_1",vol->GetName()));
00434 TGeoNode *daughter;
00435
00436 Int_t level, nd;
00437 Bool_t last;
00438
00439 while ((daughter=next())) {
00440 vol = daughter->GetVolume();
00441 level = next.GetLevel();
00442 nd = daughter->GetNdaughters();
00443 vis = daughter->IsVisible();
00444 if (volume->IsVisContainers()) {
00445 if (vis && level<=fVisLevel) {
00446 *fGlobal = next.GetCurrentMatrix();
00447 dist = vol->GetShape()->DistancetoPrimitive(px,py);
00448 if (dist<maxdist) {
00449 next.GetPath(fVolInfo);
00450 box = (TGeoBBox*)vol->GetShape();
00451 fGlobal->LocalToMaster(box->GetOrigin(), &fCheckedBox[0]);
00452 fCheckedNode = daughter;
00453 if (fGeoManager->IsNodeSelectable()) gPad->SetSelected(fCheckedNode);
00454 else gPad->SetSelected(vol);
00455 fCheckedBox[3] = box->GetDX();
00456 fCheckedBox[4] = box->GetDY();
00457 fCheckedBox[5] = box->GetDZ();
00458 fGeoManager->PopPath();
00459 return 0;
00460 }
00461 }
00462
00463 if (level==fVisLevel || !daughter->IsVisDaughters()) {
00464 next.Skip();
00465 continue;
00466 }
00467 } else if (volume->IsVisLeaves()) {
00468 last = ((nd==0) || (level==fVisLevel) || (!daughter->IsVisDaughters()))?kTRUE:kFALSE;
00469 if (vis && last) {
00470 *fGlobal = next.GetCurrentMatrix();
00471 dist = vol->GetShape()->DistancetoPrimitive(px,py);
00472 if (dist<maxdist) {
00473 next.GetPath(fVolInfo);
00474 box = (TGeoBBox*)vol->GetShape();
00475 fGlobal->LocalToMaster(box->GetOrigin(), &fCheckedBox[0]);
00476 fCheckedNode = daughter;
00477 if (fGeoManager->IsNodeSelectable()) gPad->SetSelected(fCheckedNode);
00478 else gPad->SetSelected(vol);
00479 fCheckedBox[3] = box->GetDX();
00480 fCheckedBox[4] = box->GetDY();
00481 fCheckedBox[5] = box->GetDZ();
00482 fGeoManager->PopPath();
00483 return 0;
00484 }
00485 }
00486
00487 if (last || !daughter->IsVisDaughters()) next.Skip();
00488 }
00489 }
00490 return dist;
00491 }
00492
00493
00494 void TGeoPainter::DefaultAngles()
00495 {
00496
00497 if (gPad) {
00498 Int_t irep;
00499 TView *view = gPad->GetView();
00500 if (!view) return;
00501 view->SetView(-206,126,75,irep);
00502 ModifiedPad();
00503 }
00504 }
00505
00506
00507 void TGeoPainter::DefaultColors()
00508 {
00509
00510 TIter next(fGeoManager->GetListOfVolumes());
00511 TGeoVolume *vol;
00512 while ((vol=(TGeoVolume*)next()))
00513 vol->SetLineColor(vol->GetMaterial()->GetDefaultColor());
00514 ModifiedPad();
00515 }
00516
00517
00518 Int_t TGeoPainter::CountNodes(TGeoVolume *volume, Int_t rlevel) const
00519 {
00520
00521 TGeoVolume *vol = volume;
00522 Int_t count = 0;
00523 Bool_t vis = vol->IsVisible();
00524
00525 if ((fTopVisible && vis) || !vol->GetNdaughters() || !vol->IsVisDaughters() || vol->IsVisOnly())
00526 count++;
00527
00528 if (volume->IsVisOnly()) return count;
00529
00530
00531 if (volume->IsVisBranch()) {
00532 fGeoManager->PushPath();
00533 fGeoManager->cd(fVisBranch.Data());
00534 count = fGeoManager->GetLevel() + 1;
00535 fGeoManager->PopPath();
00536 return count;
00537 }
00538
00539 TGeoIterator next(vol);
00540 TGeoNode *daughter;
00541 Int_t level, nd;
00542 Bool_t last;
00543
00544 while ((daughter=next())) {
00545
00546 level = next.GetLevel();
00547 nd = daughter->GetNdaughters();
00548 vis = daughter->IsVisible();
00549 if (volume->IsVisContainers()) {
00550 if (vis && level<=rlevel) count++;
00551
00552 if (level==rlevel || !daughter->IsVisDaughters()) {
00553 next.Skip();
00554 continue;
00555 }
00556 } else if (volume->IsVisLeaves()) {
00557 last = ((nd==0) || (level==rlevel) || (!daughter->IsVisDaughters()))?kTRUE:kFALSE;
00558 if (vis && last) count++;
00559
00560 if (last) next.Skip();
00561 }
00562 }
00563 return count;
00564 }
00565
00566
00567 Int_t TGeoPainter::CountVisibleNodes()
00568 {
00569
00570 Int_t maxnodes = fGeoManager->GetMaxVisNodes();
00571 Int_t vislevel = fGeoManager->GetVisLevel();
00572
00573 TGeoVolume *top = fTopVolume;
00574 if (maxnodes <= 0 && top) {
00575 fNVisNodes = CountNodes(top, vislevel);
00576 SetVisLevel(vislevel);
00577 return fNVisNodes;
00578 }
00579
00580
00581
00582 if (!top) {
00583 SetVisLevel(vislevel);
00584 return 0;
00585 }
00586 fNVisNodes = -1;
00587 Bool_t again = kFALSE;
00588 for (Int_t level = 1;level<20;level++) {
00589 vislevel = level;
00590 Int_t nnodes = CountNodes(top, level);
00591 if (top->IsVisOnly() || top->IsVisBranch()) {
00592 vislevel = fVisLevel;
00593 fNVisNodes = nnodes;
00594 break;
00595 }
00596 if (nnodes > maxnodes) {
00597 vislevel--;
00598 break;
00599 }
00600 if (nnodes == fNVisNodes) {
00601 if (again) break;
00602 again = kTRUE;
00603 }
00604 fNVisNodes = nnodes;
00605 }
00606 SetVisLevel(vislevel);
00607 return fNVisNodes;
00608 }
00609
00610
00611 void TGeoPainter::CheckEdit()
00612 {
00613
00614 if (fIsEditable) return;
00615 if (!TClass::GetClass("TGedEditor")) return;
00616 TPluginHandler *h;
00617 if ((h = gROOT->GetPluginManager()->FindHandler("TGeoManagerEditor"))) {
00618 if (h->LoadPlugin() == -1) return;
00619 h->ExecPlugin(0);
00620 }
00621 fIsEditable = kTRUE;
00622 }
00623
00624
00625 void TGeoPainter::EditGeometry(Option_t *option)
00626 {
00627
00628 if (!gPad) return;
00629 if (!fIsEditable) {
00630 if (!strlen(option)) gPad->GetCanvas()->GetCanvasImp()->ShowEditor();
00631 else TVirtualPadEditor::ShowEditor();
00632 CheckEdit();
00633 }
00634 gPad->SetSelected(fGeoManager);
00635 gPad->GetCanvas()->Selected(gPad,fGeoManager,kButton1Down);
00636 }
00637
00638
00639 void TGeoPainter::Draw(Option_t *option)
00640 {
00641
00642 DrawVolume(fGeoManager->GetTopVolume(), option);
00643 }
00644
00645
00646 void TGeoPainter::DrawBatemanSol(TGeoBatemanSol *sol, Option_t *option)
00647 {
00648
00649 Int_t ncoeff = sol->GetNcoeff();
00650 if (!ncoeff) return;
00651 Double_t tlo=0., thi=0.;
00652 Double_t cn=0., lambda=0.;
00653 Int_t i;
00654 sol->GetRange(tlo, thi);
00655 Bool_t autorange = (thi==0.)?kTRUE:kFALSE;
00656
00657
00658 if (autorange) tlo = 0.;
00659 sol->GetCoeff(0, cn, lambda);
00660 Double_t lambdamin = lambda;
00661 TString formula = "";
00662 for (i=0; i<ncoeff; i++) {
00663 sol->GetCoeff(i, cn, lambda);
00664 formula += TString::Format("%g*exp(-%g*x)",cn, lambda);
00665 if (i < ncoeff-1) formula += "+";
00666 if (lambda < lambdamin &&
00667 lambda > 0.) lambdamin = lambda;
00668 }
00669 if (autorange) thi = 10./lambdamin;
00670 formula += ";time[s]";
00671 formula += TString::Format(";Concentration_of_%s",sol->GetElement()->GetName());
00672
00673 TF1 *func = new TF1(TString::Format("conc%s",sol->GetElement()->GetName()), formula.Data(), tlo,thi);
00674 func->SetMinimum(1.e-3);
00675 func->SetMaximum(1.25*TMath::Max(sol->Concentration(tlo), sol->Concentration(thi)));
00676 func->SetLineColor(sol->GetLineColor());
00677 func->SetLineStyle(sol->GetLineStyle());
00678 func->SetLineWidth(sol->GetLineWidth());
00679 func->SetMarkerColor(sol->GetMarkerColor());
00680 func->SetMarkerStyle(sol->GetMarkerStyle());
00681 func->SetMarkerSize(sol->GetMarkerSize());
00682 func->Draw(option);
00683 }
00684
00685
00686 void TGeoPainter::DrawVolume(TGeoVolume *vol, Option_t *option)
00687 {
00688
00689 fTopVolume = vol;
00690 fLastVolume = 0;
00691 fIsPaintingShape = kFALSE;
00692
00693
00694 CountVisibleNodes();
00695 TString opt = option;
00696 opt.ToLower();
00697 fPaintingOverlaps = kFALSE;
00698 fOverlap = 0;
00699
00700 if (fVisLock) {
00701 ClearVisibleVolumes();
00702 fVisLock = kFALSE;
00703 }
00704 Bool_t has_pad = (gPad==0)?kFALSE:kTRUE;
00705
00706 if (!gPad) {
00707 gROOT->MakeDefCanvas();
00708 }
00709 if (!opt.Contains("same")) gPad->Clear();
00710
00711 fTopVolume->AppendPad(option);
00712
00713
00714 TView *view = gPad->GetView();
00715 if (!view) {
00716 view = TView::CreateView(11,0,0);
00717
00718
00719 view->SetAutoRange(kTRUE);
00720 if (has_pad) gPad->Update();
00721 }
00722 Paint("range");
00723 view->SetAutoRange(kFALSE);
00724
00725
00726
00727
00728 fLastVolume = fTopVolume;
00729
00730
00731 gPad->GetViewer3D(option);
00732 }
00733
00734
00735 void TGeoPainter::DrawShape(TGeoShape *shape, Option_t *option)
00736 {
00737
00738 TString opt = option;
00739 opt.ToLower();
00740 fPaintingOverlaps = kFALSE;
00741 fOverlap = 0;
00742 fIsPaintingShape = kTRUE;
00743
00744 Bool_t has_pad = (gPad==0)?kFALSE:kTRUE;
00745
00746 if (!gPad) {
00747 gROOT->MakeDefCanvas();
00748 }
00749 if (!opt.Contains("same")) gPad->Clear();
00750
00751 shape->AppendPad(option);
00752
00753
00754 TView *view = gPad->GetView();
00755 if (!view) {
00756 view = TView::CreateView(11,0,0);
00757
00758
00759 view->SetAutoRange(kTRUE);
00760 if (has_pad) gPad->Update();
00761 }
00762 PaintShape(shape,"range");
00763 view->SetAutoRange(kTRUE);
00764
00765 gPad->GetViewer3D(option);
00766 }
00767
00768
00769 void TGeoPainter::DrawOverlap(void *ovlp, Option_t *option)
00770 {
00771
00772 TString opt = option;
00773 fIsPaintingShape = kFALSE;
00774 TGeoOverlap *overlap = (TGeoOverlap*)ovlp;
00775 if (!overlap) return;
00776
00777 fPaintingOverlaps = kTRUE;
00778 fOverlap = overlap;
00779 opt.ToLower();
00780 if (fVisLock) {
00781 ClearVisibleVolumes();
00782 fVisLock = kFALSE;
00783 }
00784 Bool_t has_pad = (gPad==0)?kFALSE:kTRUE;
00785
00786 if (!gPad) {
00787 gROOT->MakeDefCanvas();
00788 }
00789 if (!opt.Contains("same")) gPad->Clear();
00790
00791 overlap->AppendPad(option);
00792
00793
00794
00795 gPad->GetViewer3D(option);
00796 TView *view = gPad->GetView();
00797 if (!view) {
00798 view = TView::CreateView(11,0,0);
00799
00800
00801 view->SetAutoRange(kTRUE);
00802 PaintOverlap(ovlp, "range");
00803 overlap->GetPolyMarker()->Draw("SAME");
00804 if (has_pad) gPad->Update();
00805 }
00806
00807
00808
00809
00810 fVisLock = kTRUE;
00811 }
00812
00813
00814
00815 void TGeoPainter::DrawOnly(Option_t *option)
00816 {
00817
00818 TString opt = option;
00819 opt.ToLower();
00820 if (fVisLock) {
00821 ClearVisibleVolumes();
00822 fVisLock = kFALSE;
00823 }
00824 fPaintingOverlaps = kFALSE;
00825 fIsPaintingShape = kFALSE;
00826 Bool_t has_pad = (gPad==0)?kFALSE:kTRUE;
00827
00828 if (!gPad) {
00829 gROOT->MakeDefCanvas();
00830 }
00831 if (!opt.Contains("same")) gPad->Clear();
00832
00833 fTopVolume = fGeoManager->GetCurrentVolume();
00834 fTopVolume->AppendPad(option);
00835
00836
00837 TView *view = gPad->GetView();
00838 if (!view) {
00839 view = TView::CreateView(11,0,0);
00840
00841
00842 view->SetAutoRange(kTRUE);
00843 fVisOption = kGeoVisOnly;
00844 if (has_pad) gPad->Update();
00845 }
00846
00847
00848
00849
00850 fVisLock = kTRUE;
00851 }
00852
00853
00854 void TGeoPainter::DrawCurrentPoint(Int_t color)
00855 {
00856
00857 if (!gPad) return;
00858 if (!gPad->GetView()) return;
00859 TPolyMarker3D *pm = new TPolyMarker3D();
00860 pm->SetMarkerColor(color);
00861 const Double_t *point = fGeoManager->GetCurrentPoint();
00862 pm->SetNextPoint(point[0], point[1], point[2]);
00863 pm->SetMarkerStyle(8);
00864 pm->SetMarkerSize(0.5);
00865 pm->Draw("SAME");
00866 }
00867
00868
00869 void TGeoPainter::DrawPanel()
00870 {
00871 }
00872
00873
00874 void TGeoPainter::DrawPath(const char *path)
00875 {
00876
00877 fVisOption=kGeoVisBranch;
00878 fVisBranch=path;
00879 fIsPaintingShape = kFALSE;
00880 fTopVolume = fGeoManager->GetTopVolume();
00881 fTopVolume->SetVisRaytrace(kFALSE);
00882 DrawVolume(fTopVolume,"");
00883 }
00884
00885
00886 void TGeoPainter::EstimateCameraMove(Double_t tmin, Double_t tmax, Double_t *start, Double_t *end)
00887 {
00888
00889 if (!gPad) return;
00890 TIter next(gPad->GetListOfPrimitives());
00891 TVirtualGeoTrack *track;
00892 TObject *obj;
00893 Int_t ntracks = 0;
00894 Double_t *point = 0;
00895 AddTrackPoint(point, start, kTRUE);
00896 while ((obj=next())) {
00897 if (strcmp(obj->ClassName(), "TGeoTrack")) continue;
00898 track = (TVirtualGeoTrack*)obj;
00899 ntracks++;
00900 track->PaintCollect(tmin, start);
00901 }
00902
00903 if (!ntracks) return;
00904 next.Reset();
00905 AddTrackPoint(point, end, kTRUE);
00906 while ((obj=next())) {
00907 if (strcmp(obj->ClassName(), "TGeoTrack")) continue;
00908 track = (TVirtualGeoTrack*)obj;
00909 if (!track) continue;
00910 track->PaintCollect(tmax, end);
00911 }
00912 }
00913
00914
00915 void TGeoPainter::ExecuteManagerEvent(TGeoManager * , Int_t event, Int_t , Int_t )
00916 {
00917
00918 if (!gPad) return;
00919 gPad->SetCursor(kPointer);
00920 switch (event) {
00921 case kButton1Down:
00922 if (!fIsEditable) CheckEdit();
00923 }
00924 }
00925
00926
00927 void TGeoPainter::ExecuteShapeEvent(TGeoShape * , Int_t event, Int_t , Int_t )
00928 {
00929
00930 if (!gPad) return;
00931 gPad->SetCursor(kHand);
00932 switch (event) {
00933 case kButton1Down:
00934 if (!fIsEditable) CheckEdit();
00935 }
00936 }
00937
00938
00939 void TGeoPainter::ExecuteVolumeEvent(TGeoVolume * , Int_t event, Int_t , Int_t )
00940 {
00941
00942 if (!gPad) return;
00943 if (!fIsEditable) CheckEdit();
00944
00945
00946
00947
00948 gPad->SetCursor(kHand);
00949
00950 switch (event) {
00951 case kMouseEnter:
00952
00953
00954 break;
00955
00956 case kMouseLeave:
00957
00958
00959 break;
00960
00961 case kButton1Down:
00962
00963
00964
00965
00966 break;
00967
00968 case kButton1Up:
00969
00970
00971
00972
00973 break;
00974
00975 case kButton1Double:
00976 gPad->SetCursor(kWatch);
00977 GrabFocus();
00978 break;
00979 }
00980 }
00981
00982
00983 const char *TGeoPainter::GetVolumeInfo(const TGeoVolume *volume, Int_t , Int_t ) const
00984 {
00985
00986 static TString info;
00987 info = "";
00988 if (!gPad) return info;
00989 if (fPaintingOverlaps) {
00990 if (!fOverlap) {
00991 info = "wrong overlapping flag";
00992 return info;
00993 }
00994 TString ovtype, name;
00995 if (fOverlap->IsExtrusion()) ovtype="EXTRUSION";
00996 else ovtype = "OVERLAP";
00997 if (volume==fOverlap->GetFirstVolume()) name=volume->GetName();
00998 else name=fOverlap->GetSecondVolume()->GetName();
00999 info = TString::Format("%s: %s of %g", name.Data(), ovtype.Data(), fOverlap->GetOverlap());
01000 return info;
01001 }
01002 else info = TString::Format("%s, shape=%s", fVolInfo.Data(), volume->GetShape()->ClassName());
01003 return info;
01004 }
01005
01006
01007 TGeoChecker *TGeoPainter::GetChecker()
01008 {
01009
01010 if (!fChecker) fChecker = new TGeoChecker(fGeoManager);
01011 return fChecker;
01012 }
01013
01014
01015 void TGeoPainter::GetViewAngles(Double_t &longitude, Double_t &latitude, Double_t &psi)
01016 {
01017
01018 if (!gPad) return;
01019 TView *view = gPad->GetView();
01020 if (!view) return;
01021 longitude = view->GetLongitude();
01022 latitude = view->GetLatitude();
01023 psi = view->GetPsi();
01024 }
01025
01026
01027 void TGeoPainter::GrabFocus(Int_t nfr, Double_t dlong, Double_t dlat, Double_t dpsi)
01028 {
01029
01030 if (!gPad) return;
01031 TView *view = gPad->GetView();
01032 if (!view) return;
01033 if (!fCheckedNode && !fPaintingOverlaps) {
01034 printf("Woops!!!\n");
01035 TGeoBBox *box = (TGeoBBox*)fGeoManager->GetTopVolume()->GetShape();
01036 memcpy(&fCheckedBox[0], box->GetOrigin(), 3*sizeof(Double_t));
01037 fCheckedBox[3] = box->GetDX();
01038 fCheckedBox[4] = box->GetDY();
01039 fCheckedBox[5] = box->GetDZ();
01040 }
01041 view->SetPerspective();
01042 Int_t nvols = fVisVolumes->GetEntriesFast();
01043 Int_t nframes = nfr;
01044 if (nfr==0) {
01045 nframes = 1;
01046 if (nvols<1500) nframes=10;
01047 if (nvols<1000) nframes=20;
01048 if (nvols<200) nframes = 50;
01049 if (nvols<100) nframes = 100;
01050 }
01051 view->MoveFocus(&fCheckedBox[0], fCheckedBox[3], fCheckedBox[4], fCheckedBox[5], nframes, dlong, dlat, dpsi);
01052 }
01053
01054
01055 TH2F *TGeoPainter::LegoPlot(Int_t ntheta, Double_t themin, Double_t themax,
01056 Int_t nphi, Double_t phimin, Double_t phimax,
01057 Double_t rmin, Double_t rmax, Option_t *option)
01058 {
01059
01060 return fChecker->LegoPlot(ntheta, themin, themax, nphi, phimin, phimax, rmin, rmax, option);
01061 }
01062
01063 void TGeoPainter::LocalToMasterVect(const Double_t *local, Double_t *master) const
01064 {
01065
01066 for (Int_t i=0; i<3; i++)
01067 master[i] = -local[0]*fMat[i]-local[1]*fMat[i+3]-local[2]*fMat[i+6];
01068 }
01069
01070
01071 void TGeoPainter::ModifiedPad(Bool_t update) const
01072 {
01073
01074 if (!gPad) return;
01075 if (update) {
01076 gPad->Update();
01077 return;
01078 }
01079 TView *view = gPad->GetView();
01080 if (!view) return;
01081 view->SetViewChanged();
01082 gPad->Modified();
01083 if (gROOT->FromPopUp()) gPad->Update();
01084 }
01085
01086
01087 void TGeoPainter::Paint(Option_t *option)
01088 {
01089
01090 if (!fGeoManager || !fTopVolume) return;
01091 Bool_t is_padviewer = kTRUE;
01092 if (gPad) is_padviewer = (!strcmp(gPad->GetViewer3D()->ClassName(),"TViewer3DPad"))?kTRUE:kFALSE;
01093
01094 fIsRaytracing = fTopVolume->IsRaytracing();
01095 if (fTopVolume->IsVisContainers()) fVisOption = kGeoVisDefault;
01096 else if (fTopVolume->IsVisLeaves()) fVisOption = kGeoVisLeaves;
01097 else if (fTopVolume->IsVisOnly()) fVisOption = kGeoVisOnly;
01098 else if (fTopVolume->IsVisBranch()) fVisOption = kGeoVisBranch;
01099
01100
01101 if (!fIsRaytracing || !is_padviewer) {
01102 if (fGeoManager->IsDrawingExtra()) {
01103
01104 fGeoManager->CdTop();
01105 TObjArray *nodeList = fGeoManager->GetListOfPhysicalNodes();
01106 Int_t nnodes = nodeList->GetEntriesFast();
01107 Int_t inode;
01108 TGeoPhysicalNode *node;
01109 for (inode=0; inode<nnodes; inode++) {
01110 node = (TGeoPhysicalNode*)nodeList->UncheckedAt(inode);
01111 PaintPhysicalNode(node, option);
01112 }
01113 } else {
01114 PaintVolume(fTopVolume,option);
01115 }
01116 fVisLock = kTRUE;
01117 }
01118
01119 if (fIsRaytracing && is_padviewer) Raytrace();
01120 }
01121
01122
01123 void TGeoPainter::PaintOverlap(void *ovlp, Option_t *option)
01124 {
01125
01126 if (!fGeoManager) return;
01127 TGeoOverlap *overlap = (TGeoOverlap *)ovlp;
01128 if (!overlap) return;
01129 Int_t color, transparency;
01130 if (fOverlap != overlap) fOverlap = overlap;
01131 TGeoShape::SetTransform(fGlobal);
01132 TGeoHMatrix *hmat = fGlobal;
01133 TGeoVolume *vol;
01134 TGeoVolume *vol1 = overlap->GetFirstVolume();
01135 TGeoVolume *vol2 = overlap->GetSecondVolume();
01136 TGeoHMatrix *matrix1 = overlap->GetFirstMatrix();
01137 TGeoHMatrix *matrix2 = overlap->GetSecondMatrix();
01138
01139 vol = vol1;
01140 *hmat = matrix1;
01141 fGeoManager->SetMatrixReflection(matrix1->IsReflection());
01142 if (!fVisLock) fVisVolumes->Add(vol);
01143 fGeoManager->SetPaintVolume(vol);
01144 color = vol->GetLineColor();
01145 transparency = vol->GetTransparency();
01146 vol->SetLineColor(kGreen);
01147 vol->SetTransparency(40);
01148 if (!strstr(option,"range")) ((TAttLine*)vol)->Modify();
01149 PaintShape(*(vol->GetShape()),option);
01150 vol->SetLineColor(color);
01151 vol->SetTransparency(transparency);
01152 vol = vol2;
01153 *hmat = matrix2;
01154 fGeoManager->SetMatrixReflection(matrix2->IsReflection());
01155 if (!fVisLock) fVisVolumes->Add(vol);
01156 fGeoManager->SetPaintVolume(vol);
01157 color = vol->GetLineColor();
01158 transparency = vol->GetTransparency();
01159 vol->SetLineColor(kBlue);
01160 vol->SetTransparency(40);
01161 if (!strstr(option,"range")) ((TAttLine*)vol)->Modify();
01162 PaintShape(*(vol->GetShape()),option);
01163 vol->SetLineColor(color);
01164 vol->SetTransparency(transparency);
01165 fGeoManager->SetMatrixReflection(kFALSE);
01166 fVisLock = kTRUE;
01167 }
01168
01169
01170 void TGeoPainter::PaintNode(TGeoNode *node, Option_t *option, TGeoMatrix* global)
01171 {
01172
01173 PaintVolume(node->GetVolume(), option, global);
01174 }
01175
01176
01177 void TGeoPainter::PaintVolume(TGeoVolume *top, Option_t *option, TGeoMatrix* global)
01178 {
01179
01180 if (fTopVolume != top) {
01181 ClearVisibleVolumes();
01182 fVisLock = kFALSE;
01183 }
01184 fTopVolume = top;
01185 if (!fVisLevel) return;
01186 TGeoVolume *vol = top;
01187 if(global)
01188 *fGlobal = *global;
01189 else
01190 fGlobal->Clear();
01191 TGeoShape::SetTransform(fGlobal);
01192 Bool_t drawDaughters = kTRUE;
01193 Bool_t vis = (top->IsVisible() && !top->IsAssembly());
01194
01195
01196 if (!strstr(option,"range")) ((TAttLine*)vol)->Modify();
01197
01198
01199 if (top->IsVisBranch()) {
01200 fGeoManager->PushPath();
01201 fGeoManager->cd(fVisBranch.Data());
01202 Int_t transparency;
01203 while (fGeoManager->GetLevel()) {
01204 vol = fGeoManager->GetCurrentVolume();
01205 if (!fVisLock) {
01206 fVisVolumes->Add(vol);
01207 vol->SetAttBit(TGeoAtt::kVisOnScreen);
01208 }
01209 fGeoManager->SetPaintVolume(vol);
01210 transparency = vol->GetTransparency();
01211 vol->SetTransparency(40);
01212 if (!strstr(option,"range")) ((TAttLine*)vol)->Modify();
01213 if (global) {
01214 *fGlobal = *global;
01215 *fGlobal *= *fGeoManager->GetCurrentMatrix();
01216 } else {
01217 *fGlobal = fGeoManager->GetCurrentMatrix();
01218 }
01219 fGeoManager->SetMatrixReflection(fGlobal->IsReflection());
01220 PaintShape(*(vol->GetShape()),option);
01221 vol->SetTransparency(transparency);
01222 fGeoManager->CdUp();
01223 }
01224 fVisLock = kTRUE;
01225 fGeoManager->PopPath();
01226 fGeoManager->SetMatrixReflection(kFALSE);
01227 return;
01228 }
01229
01230
01231 if ((fTopVisible && vis) || !top->GetNdaughters() || !top->IsVisDaughters() || top->IsVisOnly()) {
01232 fGeoManager->SetPaintVolume(vol);
01233 fGeoManager->SetMatrixReflection(fGlobal->IsReflection());
01234 drawDaughters = PaintShape(*(vol->GetShape()),option);
01235 if (!fVisLock && !vol->TestAttBit(TGeoAtt::kVisOnScreen)) {
01236 fVisVolumes->Add(vol);
01237 vol->SetAttBit(TGeoAtt::kVisOnScreen);
01238 }
01239 if (top->IsVisOnly() || !top->GetNdaughters() || !top->IsVisDaughters()) {
01240 fVisLock = kTRUE;
01241 return;
01242 }
01243 }
01244
01245
01246 TGeoIterator next(vol);
01247 if (fPlugin) next.SetUserPlugin(fPlugin);
01248 TGeoNode *daughter;
01249
01250 Int_t level, nd;
01251 Bool_t last;
01252 Int_t line_color=0, line_width=0, line_style=0;
01253 while ((daughter=next())) {
01254 vol = daughter->GetVolume();
01255 fGeoManager->SetPaintVolume(vol);
01256 level = next.GetLevel();
01257 nd = daughter->GetNdaughters();
01258 vis = daughter->IsVisible();
01259 drawDaughters = kTRUE;
01260 if (top->IsVisContainers()) {
01261 if (vis && level<=fVisLevel) {
01262 if (fPlugin) {
01263 line_color = vol->GetLineColor();
01264 line_width = vol->GetLineWidth();
01265 line_style = vol->GetLineStyle();
01266 fPlugin->ProcessNode();
01267 }
01268 if (!strstr(option,"range")) ((TAttLine*)vol)->Modify();
01269 if (global) {
01270 *fGlobal = *global;
01271 *fGlobal *= *next.GetCurrentMatrix();
01272 } else {
01273 *fGlobal = next.GetCurrentMatrix();
01274 }
01275 fGeoManager->SetMatrixReflection(fGlobal->IsReflection());
01276 drawDaughters = PaintShape(*(vol->GetShape()),option);
01277 if (fPlugin) {
01278 vol->SetLineColor(line_color);
01279 vol->SetLineWidth(line_width);
01280 vol->SetLineStyle(line_style);
01281 }
01282 if (!fVisLock && !daughter->IsOnScreen()) {
01283 fVisVolumes->Add(vol);
01284 vol->SetAttBit(TGeoAtt::kVisOnScreen);
01285 }
01286 }
01287
01288 if (!drawDaughters || level==fVisLevel || !daughter->IsVisDaughters()) {
01289 next.Skip();
01290 continue;
01291 }
01292 } else if (top->IsVisLeaves()) {
01293 last = ((nd==0) || (level==fVisLevel) || (!daughter->IsVisDaughters()))?kTRUE:kFALSE;
01294 if (vis && last) {
01295 if (fPlugin) {
01296 line_color = vol->GetLineColor();
01297 line_width = vol->GetLineWidth();
01298 line_style = vol->GetLineStyle();
01299 fPlugin->ProcessNode();
01300 }
01301 if (!strstr(option,"range")) ((TAttLine*)vol)->Modify();
01302 if (global) {
01303 *fGlobal = *global;
01304 *fGlobal *= *next.GetCurrentMatrix();
01305 } else {
01306 *fGlobal = next.GetCurrentMatrix();
01307 }
01308 fGeoManager->SetMatrixReflection(fGlobal->IsReflection());
01309 drawDaughters = PaintShape(*(vol->GetShape()),option);
01310 if (fPlugin) {
01311 vol->SetLineColor(line_color);
01312 vol->SetLineWidth(line_width);
01313 vol->SetLineStyle(line_style);
01314 }
01315 if (!fVisLock && !daughter->IsOnScreen()) {
01316 fVisVolumes->Add(vol);
01317 vol->SetAttBit(TGeoAtt::kVisOnScreen);
01318 }
01319 }
01320
01321 if (!drawDaughters || last || !daughter->IsVisDaughters()) next.Skip();
01322 }
01323 }
01324 if (fPlugin) fPlugin->SetIterator(0);
01325 fGeoManager->SetMatrixReflection(kFALSE);
01326 fVisLock = kTRUE;
01327 }
01328
01329
01330 Bool_t TGeoPainter::PaintShape(const TGeoShape & shape, Option_t * option ) const
01331 {
01332
01333 Bool_t addDaughters = kTRUE;
01334
01335 TVirtualViewer3D * viewer = gPad->GetViewer3D();
01336
01337 if (!viewer || shape.IsA()==TGeoShapeAssembly::Class()) {
01338 return addDaughters;
01339 }
01340
01341
01342
01343 if (!shape.IsComposite()) {
01344
01345 Bool_t localFrame = viewer->PreferLocalFrame();
01346
01347
01348 const TBuffer3D & buffer =
01349 shape.GetBuffer3D(TBuffer3D::kCore|TBuffer3D::kBoundingBox|TBuffer3D::kShapeSpecific, localFrame);
01350 Int_t reqSections = viewer->AddObject(buffer, &addDaughters);
01351
01352
01353
01354 if (reqSections != TBuffer3D::kNone) {
01355 shape.GetBuffer3D(reqSections, localFrame);
01356 viewer->AddObject(buffer, &addDaughters);
01357 }
01358 }
01359
01360
01361
01362
01363 else {
01364 const TGeoCompositeShape * composite = static_cast<const TGeoCompositeShape *>(&shape);
01365
01366
01367
01368
01369
01370 addDaughters = composite->PaintComposite(option);
01371 }
01372
01373 return addDaughters;
01374 }
01375
01376
01377 void TGeoPainter::PaintShape(TGeoShape *shape, Option_t *option)
01378 {
01379
01380 TGeoShape::SetTransform(fGlobal);
01381 fGlobal->Clear();
01382 fGeoManager->SetPaintVolume(0);
01383 PaintShape(*shape,option);
01384 }
01385
01386
01387 void TGeoPainter::PaintPhysicalNode(TGeoPhysicalNode *node, Option_t *option)
01388 {
01389
01390 if (!node->IsVisible()) return;
01391 Int_t level = node->GetLevel();
01392 Int_t i, col, wid, sty;
01393 TGeoShape *shape;
01394 TGeoShape::SetTransform(fGlobal);
01395 TGeoHMatrix *matrix = fGlobal;
01396 TGeoVolume *vcrt;
01397 if (!node->IsVisibleFull()) {
01398
01399 vcrt = node->GetVolume();
01400 if (!strstr(option,"range")) ((TAttLine*)vcrt)->Modify();
01401 shape = vcrt->GetShape();
01402 *matrix = node->GetMatrix();
01403 fGeoManager->SetMatrixReflection(matrix->IsReflection());
01404 fGeoManager->SetPaintVolume(vcrt);
01405 if (!node->IsVolAttributes() && !strstr(option,"range")) {
01406 col = vcrt->GetLineColor();
01407 wid = vcrt->GetLineWidth();
01408 sty = vcrt->GetLineStyle();
01409 vcrt->SetLineColor(node->GetLineColor());
01410 vcrt->SetLineWidth(node->GetLineWidth());
01411 vcrt->SetLineStyle(node->GetLineStyle());
01412 ((TAttLine*)vcrt)->Modify();
01413 PaintShape(*shape,option);
01414 vcrt->SetLineColor(col);
01415 vcrt->SetLineWidth(wid);
01416 vcrt->SetLineStyle(sty);
01417 } else {
01418 PaintShape(*shape,option);
01419 }
01420 } else {
01421
01422 for (i=1;i<=level; i++) {
01423 vcrt = node->GetVolume(i);
01424 if (!strstr(option,"range")) ((TAttLine*)vcrt)->Modify();
01425 shape = vcrt->GetShape();
01426 *matrix = node->GetMatrix(i);
01427 fGeoManager->SetMatrixReflection(matrix->IsReflection());
01428 fGeoManager->SetPaintVolume(vcrt);
01429 if (!node->IsVolAttributes() && !strstr(option,"range")) {
01430 col = vcrt->GetLineColor();
01431 wid = vcrt->GetLineWidth();
01432 sty = vcrt->GetLineStyle();
01433 vcrt->SetLineColor(node->GetLineColor());
01434 vcrt->SetLineWidth(node->GetLineWidth());
01435 vcrt->SetLineStyle(node->GetLineStyle());
01436 ((TAttLine*)vcrt)->Modify();
01437 PaintShape(*shape,option);
01438 vcrt->SetLineColor(col);
01439 vcrt->SetLineWidth(wid);
01440 vcrt->SetLineStyle(sty);
01441 } else {
01442 PaintShape(*shape,option);
01443 }
01444 }
01445 }
01446 fGeoManager->SetMatrixReflection(kFALSE);
01447 }
01448
01449
01450 void TGeoPainter::PrintOverlaps() const
01451 {
01452
01453 fChecker->PrintOverlaps();
01454 }
01455
01456
01457 void TGeoPainter::OpProgress(const char *opname, Long64_t current, Long64_t size, TStopwatch *watch, Bool_t last, Bool_t refresh)
01458 {
01459
01460 fChecker->OpProgress(opname,current,size,watch,last,refresh);
01461 }
01462
01463
01464 void TGeoPainter::RandomPoints(const TGeoVolume *vol, Int_t npoints, Option_t *option)
01465 {
01466
01467 fChecker->RandomPoints((TGeoVolume*)vol, npoints, option);
01468 }
01469
01470
01471 void TGeoPainter::RandomRays(Int_t nrays, Double_t startx, Double_t starty, Double_t startz)
01472 {
01473
01474 fChecker->RandomRays(nrays, startx, starty, startz);
01475 }
01476
01477
01478 void TGeoPainter::Raytrace(Option_t * )
01479 {
01480
01481 if (!gPad || gPad->IsBatch()) return;
01482 TView *view = gPad->GetView();
01483 if (!view) return;
01484 TGeoVolume *top = fGeoManager->GetTopVolume();
01485 if (top != fTopVolume) fGeoManager->SetTopVolume(fTopVolume);
01486 if (!view->IsPerspective()) view->SetPerspective();
01487 gVirtualX->SetMarkerSize(1);
01488 gVirtualX->SetMarkerStyle(1);
01489 Int_t i;
01490 Bool_t inclipst=kFALSE, inclip=kFALSE;
01491 Double_t krad = TMath::DegToRad();
01492 Double_t lat = view->GetLatitude();
01493 Double_t longit = view->GetLongitude();
01494 Double_t psi = view->GetPsi();
01495 Double_t c1 = TMath::Cos(psi*krad);
01496 Double_t s1 = TMath::Sin(psi*krad);
01497 Double_t c2 = TMath::Cos(lat*krad);
01498 Double_t s2 = TMath::Sin(lat*krad);
01499 Double_t s3 = TMath::Cos(longit*krad);
01500 Double_t c3 = -TMath::Sin(longit*krad);
01501 fMat[0] = c1*c3 - s1*c2*s3;
01502 fMat[1] = c1*s3 + s1*c2*c3;
01503 fMat[2] = s1*s2;
01504
01505 fMat[3] = -s1*c3 - c1*c2*s3;
01506 fMat[4] = -s1*s3 + c1*c2*c3;
01507 fMat[5] = c1*s2;
01508
01509 fMat[6] = s2*s3;
01510 fMat[7] = -s2*c3;
01511 fMat[8] = c2;
01512 Double_t u0, v0, du, dv;
01513 view->GetWindow(u0,v0,du,dv);
01514 Double_t dview = view->GetDview();
01515 Double_t dproj = view->GetDproj();
01516 Double_t local[3] = {0,0,1};
01517 Double_t dir[3], normal[3];
01518 LocalToMasterVect(local,dir);
01519 Double_t min[3], max[3];
01520 view->GetRange(min, max);
01521 Double_t cov[3];
01522 for (i=0; i<3; i++) cov[i] = 0.5*(min[i]+max[i]);
01523 Double_t cop[3];
01524 for (i=0; i<3; i++) cop[i] = cov[i] - dir[i]*dview;
01525 fGeoManager->InitTrack(cop, dir);
01526 Bool_t outside = fGeoManager->IsOutside();
01527 fGeoManager->DoBackupState();
01528 if (fClippingShape) inclipst = inclip = fClippingShape->Contains(cop);
01529 Int_t px, py;
01530 Double_t xloc, yloc, modloc;
01531 Int_t pxmin,pxmax, pymin,pymax;
01532 pxmin = gPad->UtoAbsPixel(0);
01533 pxmax = gPad->UtoAbsPixel(1);
01534 pymin = gPad->VtoAbsPixel(1);
01535 pymax = gPad->VtoAbsPixel(0);
01536 TGeoNode *next, *nextnode;
01537 Double_t step,steptot;
01538 Double_t *norm;
01539 const Double_t *point = fGeoManager->GetCurrentPoint();
01540 Double_t *ppoint = (Double_t*)point;
01541 Double_t tosource[3];
01542 Double_t calf;
01543 Double_t phi = 0*krad;
01544 tosource[0] = -dir[0]*TMath::Cos(phi)+dir[1]*TMath::Sin(phi);
01545 tosource[1] = -dir[0]*TMath::Sin(phi)-dir[1]*TMath::Cos(phi);
01546 tosource[2] = -dir[2];
01547
01548 Bool_t done;
01549
01550 Int_t base_color, color;
01551 Double_t light;
01552 Double_t stemin=0, stemax=TGeoShape::Big();
01553 TPoint *pxy = new TPoint[1];
01554 TGeoVolume *nextvol;
01555 Int_t up;
01556 Int_t ntotal = pxmax*pymax;
01557 Int_t nrays = 0;
01558 TStopwatch *timer = new TStopwatch();
01559 timer->Start();
01560 for (px=pxmin; px<pxmax; px++) {
01561 for (py=pymin; py<pymax; py++) {
01562 if ((nrays%100)==0) OpProgress("Raytracing",nrays,ntotal,timer,kFALSE);
01563 nrays++;
01564 base_color = 1;
01565 steptot = 0;
01566 inclip = inclipst;
01567 xloc = gPad->AbsPixeltoX(pxmin+pxmax-px);
01568 xloc = xloc*du-u0;
01569 yloc = gPad->AbsPixeltoY(pymin+pymax-py);
01570 yloc = yloc*dv-v0;
01571 modloc = TMath::Sqrt(xloc*xloc+yloc*yloc+dproj*dproj);
01572 local[0] = xloc/modloc;
01573 local[1] = yloc/modloc;
01574 local[2] = dproj/modloc;
01575 LocalToMasterVect(local,dir);
01576 fGeoManager->DoRestoreState();
01577 fGeoManager->SetOutside(outside);
01578 fGeoManager->SetCurrentPoint(cop);
01579 fGeoManager->SetCurrentDirection(dir);
01580
01581
01582 done = kFALSE;
01583 norm = 0;
01584
01585 if (fClippingShape) {
01586 if (inclip) {
01587 stemin = fClippingShape->DistFromInside(cop,dir,3);
01588 stemax = TGeoShape::Big();
01589 } else {
01590 stemax = fClippingShape->DistFromOutside(cop,dir,3);
01591 stemin = 0;
01592 }
01593 }
01594
01595 while (!done) {
01596 if (fClippingShape) {
01597 if (stemin>1E10) break;
01598 if (stemin>0) {
01599
01600 fGeoManager->SetStep(stemin);
01601 next = fGeoManager->Step();
01602 steptot = 0;
01603 stemin = 0;
01604 up = 0;
01605 while (next) {
01606
01607 nextvol = next->GetVolume();
01608 if (nextvol->TestAttBit(TGeoAtt::kVisOnScreen)) {
01609 done = kTRUE;
01610 base_color = nextvol->GetLineColor();
01611 fClippingShape->ComputeNormal(ppoint, dir, normal);
01612 norm = normal;
01613 break;
01614 }
01615 up++;
01616 next = fGeoManager->GetMother(up);
01617 }
01618 if (done) break;
01619 inclip = fClippingShape->Contains(ppoint);
01620 fGeoManager->SetStep(1E-3);
01621 while (inclip) {
01622 fGeoManager->Step();
01623 inclip = fClippingShape->Contains(ppoint);
01624 }
01625 stemax = fClippingShape->DistFromOutside(ppoint,dir,3);
01626 }
01627 }
01628 nextnode = fGeoManager->FindNextBoundaryAndStep();
01629 step = fGeoManager->GetStep();
01630 if (step>1E10) break;
01631 steptot += step;
01632 next = nextnode;
01633
01634 if (fClippingShape) {
01635 if (steptot>stemax) {
01636 steptot = 0;
01637 inclip = fClippingShape->Contains(ppoint);
01638 if (inclip) {
01639 stemin = fClippingShape->DistFromInside(ppoint,dir,3);
01640 stemax = TGeoShape::Big();
01641 continue;
01642 } else {
01643 stemin = 0;
01644 stemax = fClippingShape->DistFromOutside(ppoint,dir,3);
01645 }
01646 }
01647 }
01648
01649 if (!nextnode) continue;
01650 nextvol = nextnode->GetVolume();
01651 if (nextvol->TestAttBit(TGeoAtt::kVisOnScreen)) {
01652 done = kTRUE;
01653 base_color = nextvol->GetLineColor();
01654 next = nextnode;
01655 break;
01656 }
01657 }
01658 if (!done) continue;
01659
01660
01661 if (!norm) norm = fGeoManager->FindNormalFast();
01662 if (!norm) continue;
01663 calf = norm[0]*tosource[0]+norm[1]*tosource[1]+norm[2]*tosource[2];
01664 light = 0.25+0.5*TMath::Abs(calf);
01665 color = GetColor(base_color, light);
01666
01667 gVirtualX->SetMarkerColor(color);
01668 pxy[0].fX = px;
01669 pxy[0].fY = py;
01670 gVirtualX->DrawPolyMarker(1,pxy);
01671 }
01672 }
01673 delete [] pxy;
01674 timer->Stop();
01675 fChecker->OpProgress("Raytracing",nrays,ntotal,timer,kTRUE);
01676 delete timer;
01677 }
01678
01679
01680 TGeoNode *TGeoPainter::SamplePoints(Int_t npoints, Double_t &dist, Double_t epsil,
01681 const char* g3path)
01682 {
01683
01684
01685 return fChecker->SamplePoints(npoints, dist, epsil, g3path);
01686 }
01687
01688
01689 void TGeoPainter::SetBombFactors(Double_t bombx, Double_t bomby, Double_t bombz, Double_t bombr)
01690 {
01691
01692 fBombX = bombx;
01693 fBombY = bomby;
01694 fBombZ = bombz;
01695 fBombR = bombr;
01696 if (IsExplodedView()) ModifiedPad();
01697 }
01698
01699
01700 void TGeoPainter::SetExplodedView(Int_t ibomb)
01701 {
01702
01703 if ((ibomb<0) || (ibomb>3)) {
01704 Warning("SetExplodedView", "exploded view can be 0-3");
01705 return;
01706 }
01707 if ((Int_t)ibomb==fExplodedView) return;
01708 Bool_t change = (gPad==0)?kFALSE:kTRUE;
01709
01710 if (ibomb==kGeoNoBomb) {
01711 change &= ((fExplodedView==kGeoNoBomb)?kFALSE:kTRUE);
01712 }
01713 if (ibomb==kGeoBombXYZ) {
01714 change &= ((fExplodedView==kGeoBombXYZ)?kFALSE:kTRUE);
01715 }
01716 if (ibomb==kGeoBombCyl) {
01717 change &= ((fExplodedView==kGeoBombCyl)?kFALSE:kTRUE);
01718 }
01719 if (ibomb==kGeoBombSph) {
01720 change &= ((fExplodedView==kGeoBombSph)?kFALSE:kTRUE);
01721 }
01722 fExplodedView = ibomb;
01723 if (change) ModifiedPad();
01724 }
01725
01726
01727 void TGeoPainter::SetNsegments(Int_t nseg)
01728 {
01729
01730 if (nseg<3) {
01731 Warning("SetNsegments", "number of segments should be > 2");
01732 return;
01733 }
01734 if (fNsegments==nseg) return;
01735 fNsegments = nseg;
01736 ModifiedPad();
01737 }
01738
01739
01740 void TGeoPainter::SetNmeshPoints(Int_t npoints) {
01741
01742 fChecker->SetNmeshPoints(npoints);
01743 }
01744
01745
01746 void TGeoPainter::SetCheckedNode(TGeoNode *node) {
01747
01748
01749 fChecker->SetSelectedNode(node);
01750 }
01751
01752
01753 void TGeoPainter::SetVisLevel(Int_t level) {
01754
01755 if (level==fVisLevel && fLastVolume==fTopVolume) return;
01756 fVisLevel=level;
01757 if (!fTopVolume) return;
01758 if (fVisLock) {
01759 ClearVisibleVolumes();
01760 fVisLock = kFALSE;
01761 }
01762 if (!fLastVolume) {
01763
01764 return;
01765 }
01766 if (!gPad) return;
01767 if (gPad->GetView()) {
01768
01769 ModifiedPad();
01770 }
01771 }
01772
01773
01774 void TGeoPainter::SetTopVisible(Bool_t vis)
01775 {
01776
01777 if (fTopVisible==vis) return;
01778 fTopVisible = vis;
01779 ModifiedPad();
01780 }
01781
01782
01783 void TGeoPainter::SetVisOption(Int_t option) {
01784
01785
01786
01787
01788 if ((fVisOption<0) || (fVisOption>4)) {
01789 Warning("SetVisOption", "wrong visualization option");
01790 return;
01791 }
01792
01793 if (option == kGeoVisChanged) {
01794 if (fVisLock) {
01795 ClearVisibleVolumes();
01796 fVisLock = kFALSE;
01797 }
01798 ModifiedPad();
01799 return;
01800 }
01801
01802 if (fTopVolume) {
01803 TGeoAtt *att = (TGeoAtt*)fTopVolume;
01804 att->SetAttBit(TGeoAtt::kVisBranch,kFALSE);
01805 att->SetAttBit(TGeoAtt::kVisContainers,kFALSE);
01806 att->SetAttBit(TGeoAtt::kVisOnly,kFALSE);
01807 switch (option) {
01808 case kGeoVisDefault:
01809 att->SetAttBit(TGeoAtt::kVisContainers,kTRUE);
01810 break;
01811 case kGeoVisLeaves:
01812 break;
01813 case kGeoVisOnly:
01814 att->SetAttBit(TGeoAtt::kVisOnly,kTRUE);
01815 break;
01816 }
01817 }
01818
01819 if (fVisOption==option) return;
01820 fVisOption=option;
01821 if (fVisLock) {
01822 ClearVisibleVolumes();
01823 fVisLock = kFALSE;
01824 }
01825 ModifiedPad();
01826 }
01827
01828
01829 Int_t TGeoPainter::ShapeDistancetoPrimitive(const TGeoShape *shape, Int_t numpoints, Int_t px, Int_t py) const
01830 {
01831
01832 const Int_t inaxis = 7;
01833 const Int_t maxdist = 5;
01834 const Int_t big = 9999;
01835 Int_t dist = big;
01836 if (!gPad) return dist;
01837 TView *view = gPad->GetView();
01838 if (!(numpoints && view)) return dist;
01839 if (shape->IsA()==TGeoShapeAssembly::Class()) return dist;
01840
01841 if (fIsPaintingShape) {
01842 Int_t puxmin = gPad->XtoAbsPixel(gPad->GetUxmin());
01843 Int_t puymin = gPad->YtoAbsPixel(gPad->GetUymin());
01844 Int_t puxmax = gPad->XtoAbsPixel(gPad->GetUxmax());
01845 Int_t puymax = gPad->YtoAbsPixel(gPad->GetUymax());
01846
01847 if (px < puxmin - inaxis) return big;
01848 if (py > puymin + inaxis) return big;
01849 if (px > puxmax + inaxis) return big;
01850 if (py < puymax - inaxis) return big;
01851 if ((puxmax+inaxis-px) < 40) {
01852
01853 gPad->SetSelected(fGeoManager);
01854 return 0;
01855 }
01856 }
01857
01858 fBuffer->SetRawSizes(numpoints, 3*numpoints, 0, 0, 0, 0);
01859 Double_t *points = fBuffer->fPnts;
01860 shape->SetPoints(points);
01861 Double_t dpoint2, x1, y1, xndc[3];
01862 Double_t dmaster[3];
01863 Int_t j;
01864 for (Int_t i=0; i<numpoints; i++) {
01865 j = 3*i;
01866 TGeoShape::GetTransform()->LocalToMaster(&points[j], dmaster);
01867 points[j]=dmaster[0]; points[j+1]=dmaster[1]; points[j+2]=dmaster[2];
01868 view->WCtoNDC(&points[j], xndc);
01869 x1 = gPad->XtoAbsPixel(xndc[0]);
01870 y1 = gPad->YtoAbsPixel(xndc[1]);
01871 dpoint2 = (px-x1)*(px-x1) + (py-y1)*(py-y1);
01872 if (dpoint2 < dist) dist=(Int_t)dpoint2;
01873 }
01874 if (dist > 100) return dist;
01875 dist = Int_t(TMath::Sqrt(Double_t(dist)));
01876 if (dist<maxdist && fIsPaintingShape) gPad->SetSelected((TObject*)shape);
01877 return dist;
01878 }
01879
01880
01881 void TGeoPainter::Test(Int_t npoints, Option_t *option)
01882 {
01883
01884 fChecker->Test(npoints, option);
01885 }
01886
01887
01888 void TGeoPainter::TestOverlaps(const char* path)
01889 {
01890
01891 fChecker->TestOverlaps(path);
01892 }
01893
01894
01895 Bool_t TGeoPainter::TestVoxels(TGeoVolume *vol)
01896 {
01897
01898 return fChecker->TestVoxels(vol);
01899 }
01900
01901
01902 void TGeoPainter::UnbombTranslation(const Double_t *tr, Double_t *bombtr)
01903 {
01904
01905 memcpy(bombtr, tr, 3*sizeof(Double_t));
01906 switch (fExplodedView) {
01907 case kGeoNoBomb:
01908 return;
01909 case kGeoBombXYZ:
01910 bombtr[0] /= fBombX;
01911 bombtr[1] /= fBombY;
01912 bombtr[2] /= fBombZ;
01913 return;
01914 case kGeoBombCyl:
01915 bombtr[0] /= fBombR;
01916 bombtr[1] /= fBombR;
01917 bombtr[2] /= fBombZ;
01918 return;
01919 case kGeoBombSph:
01920 bombtr[0] /= fBombR;
01921 bombtr[1] /= fBombR;
01922 bombtr[2] /= fBombR;
01923 return;
01924 default:
01925 return;
01926 }
01927 }
01928
01929
01930 Double_t TGeoPainter::Weight(Double_t precision, Option_t *option)
01931 {
01932
01933 return fChecker->Weight(precision, option);
01934 }
01935
01936