00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #include "Riostream.h"
00013 #include <stdlib.h>
00014
00015 #include "TROOT.h"
00016 #include "TClass.h"
00017 #include "TVirtualPad.h"
00018 #include "TView.h"
00019 #include "TGeometry.h"
00020 #include "TRotMatrix.h"
00021 #include "TShape.h"
00022 #include "TVolume.h"
00023 #include "TBrowser.h"
00024 #include "X3DBuffer.h"
00025
00026 #include "TTablePadView3D.h"
00027 #include "TCanvas.h"
00028
00029 #include "TRotMatrix.h"
00030 #include "TVolumePosition.h"
00031 #include "TVirtualViewer3D.h"
00032 #include "TBuffer3D.h"
00033
00034
00035 const Int_t kSonsInvisible = BIT(17);
00036
00037 #if 0
00038 const Int_t kVectorSize = 3;
00039 const Int_t kMatrixSize = kVectorSize*kVectorSize;
00040
00041 static Double_t gTranslation[kMAXLEVELS][kVectorSize];
00042 static Double_t gRotMatrix[kMAXLEVELS][kMatrixSize];
00043 static Int_t gGeomLevel = 0;
00044
00045 TVolume *gNode;
00046 #endif
00047
00048 static TRotMatrix *gIdentity = 0;
00049
00050 ClassImp(TVolume)
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072 TVolume::TVolume()
00073 {
00074
00075
00076
00077 fShape = 0;
00078 fListOfShapes = 0;
00079 fVisibility = kBothVisible;
00080 if (!gGeometry) new TGeometry;
00081 }
00082
00083
00084 TVolume::TVolume(const char *name, const char *title, const char *shapename, Option_t *option)
00085 :TObjectSet(name),TAttLine(), TAttFill(),fShape(0),fListOfShapes(0)
00086 {
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096 #ifdef WIN32
00097
00098 Color_t lcolor = 16;
00099 SetLineColor(lcolor);
00100 #endif
00101 static Int_t counter = 0;
00102 counter++;
00103 SetTitle(title);
00104 if(!(counter%1000))cout<<"TVolume count="<<counter<<" name="<<name<<endl;
00105 if (!gGeometry) new TGeometry;
00106 Add(gGeometry->GetShape(shapename),kTRUE);
00107
00108 fOption = option;
00109 fVisibility = kBothVisible;
00110
00111 if(fShape) ImportShapeAttributes();
00112 }
00113
00114
00115
00116 TVolume::TVolume(const char *name, const char *title, TShape *shape, Option_t *option)
00117 :TObjectSet(name),TAttLine(),TAttFill(),fShape(0),fListOfShapes(0)
00118 {
00119
00120
00121
00122
00123
00124
00125
00126
00127 #ifdef WIN32
00128
00129 Color_t lcolor = 16;
00130 SetLineColor(lcolor);
00131 #endif
00132
00133 if (!gGeometry) new TGeometry;
00134 Add(shape,kTRUE);
00135 fOption = option;
00136 fVisibility = kBothVisible;
00137 SetTitle(title);
00138 if(shape) ImportShapeAttributes();
00139 }
00140
00141
00142 Int_t TVolume::MapStNode2GEANTVis(ENodeSEEN vis)
00143 {
00144
00145
00146
00147
00148
00149 const Int_t mapVis[4] = {1, -2, 0, -1 };
00150 return mapVis[vis];
00151 }
00152
00153
00154
00155 Int_t TVolume::MapGEANT2StNodeVis(Int_t vis)
00156 {
00157
00158 const Int_t mapVis[4] = {1, -2, 0, -1 };
00159 Int_t i;
00160
00161 for (i =0; i<3;i++) if (mapVis[i] == vis) return i;
00162 return kBothVisible;
00163 }
00164
00165
00166 TVolume::TVolume(TNode &rootNode):fShape(0),fListOfShapes(0)
00167 {
00168
00169
00170 SetName(rootNode.GetName());
00171 SetTitle(rootNode.GetTitle());
00172 fVisibility = ENodeSEEN(MapGEANT2StNodeVis(rootNode.GetVisibility()));
00173 fOption = rootNode.GetOption();
00174 Add(rootNode.GetShape(),kTRUE);
00175
00176 SetLineColor(rootNode.GetLineColor());
00177 SetLineStyle(rootNode.GetLineStyle());
00178 SetLineWidth(rootNode.GetLineWidth());
00179 SetFillColor(rootNode.GetFillColor());
00180 SetFillStyle(rootNode.GetFillStyle());
00181
00182 TList *nodes = rootNode.GetListOfNodes();
00183 if (nodes) {
00184 TIter next(nodes);
00185 TNode *node = 0;
00186 while ( (node = (TNode *) next()) ){
00187 TVolume *nextNode = new TVolume(*node);
00188 Add(nextNode,node->GetX(),node->GetY(),node->GetZ(),node->GetMatrix());
00189 }
00190 }
00191 }
00192
00193
00194 void TVolume::Add(TShape *shape, Bool_t IsMaster)
00195 {
00196
00197 if (!shape) return;
00198 if (!fListOfShapes) fListOfShapes = new TList;
00199 fListOfShapes->Add(shape);
00200 if (IsMaster) fShape = shape;
00201 }
00202
00203
00204 TNode *TVolume::CreateTNode(const TVolumePosition *position)
00205 {
00206
00207
00208 Double_t x=0;
00209 Double_t y=0;
00210 Double_t z=0;
00211 const TRotMatrix* matrix = 0;
00212 if (position) {
00213 x=position->GetX();
00214 y=position->GetY();
00215 z=position->GetZ();
00216 matrix = position->GetMatrix();
00217 }
00218
00219
00220 TNode *newNode = new TNode(GetName(),GetTitle(),GetShape(),x,y,z,(TRotMatrix* )matrix,GetOption());
00221 newNode->SetVisibility(MapStNode2GEANTVis(GetVisibility()));
00222
00223 newNode->SetLineColor(GetLineColor());
00224 newNode->SetLineStyle(GetLineStyle());
00225 newNode->SetLineWidth(GetLineWidth());
00226 newNode->SetFillColor(GetFillColor());
00227 newNode->SetFillStyle(GetFillStyle());
00228
00229 TList *positions = GetListOfPositions();
00230 if (positions) {
00231 TIter next(positions);
00232 TVolumePosition *pos = 0;
00233 while ( (pos = (TVolumePosition *) next()) ){
00234 TVolume *node = pos->GetNode();
00235 if (node) {
00236 newNode->cd();
00237 node->CreateTNode(pos);
00238 }
00239 }
00240 }
00241 newNode->ImportShapeAttributes();
00242 return newNode;
00243 }
00244
00245
00246 TVolume::~TVolume()
00247 {
00248
00249
00250
00251
00252
00253
00254 if (GetListOfPositions()) {
00255 GetListOfPositions()->Delete();
00256 SetPositionsList();
00257 }
00258 SafeDelete(fListOfShapes);
00259 }
00260
00261
00262 void TVolume::Add(TVolumePosition *position)
00263 {
00264
00265 if (!GetListOfPositions()) SetPositionsList(new TList);
00266 if ( GetListOfPositions()) GetListOfPositions()->Add(position);
00267 else Error("Add","Can not create list of positions for the current node <%s>:<%s>",GetName(),GetTitle());
00268 }
00269
00270
00271 TVolumePosition *TVolume::Add(TVolume *node, TVolumePosition *nodePosition)
00272 {
00273
00274 TVolumePosition *position = nodePosition;
00275 if (!node) return 0;
00276 if (!position) position = new TVolumePosition(node);
00277
00278 if (!(GetCollection() && GetCollection()->FindObject(node)) ) TDataSet::Add(node);
00279 Add(position);
00280 return position;
00281 }
00282
00283
00284 TVolumePosition *TVolume::Add(TVolume *volume, Double_t x, Double_t y, Double_t z,
00285 TRotMatrix *matrix, UInt_t id, Option_t *)
00286 {
00287
00288
00289
00290
00291
00292
00293 if (!volume) return 0;
00294 TRotMatrix *rotation = matrix;
00295 if(!rotation) rotation = GetIdentity();
00296 TVolumePosition *position = new TVolumePosition(volume,x,y,z,rotation);
00297 position->SetId(id);
00298 return Add(volume,position);
00299 }
00300
00301
00302 TVolumePosition *TVolume::Add(TVolume *volume, Double_t x, Double_t y, Double_t z,
00303 const char *matrixname, UInt_t id, Option_t *)
00304 {
00305
00306
00307
00308
00309
00310
00311 if (!volume) return 0;
00312 TRotMatrix *rotation = 0;
00313 if (matrixname && strlen(matrixname)) rotation = gGeometry->GetRotMatrix(matrixname);
00314 if (!rotation) rotation = GetIdentity();
00315 TVolumePosition *position = new TVolumePosition(volume,x,y,z,rotation);
00316 position->SetId(id);
00317 return Add(volume,position);
00318 }
00319
00320
00321 void TVolume::Browse(TBrowser *b)
00322 {
00323
00324 if (GetListOfPositions()){
00325 TVolumePosition *nodePosition = 0;
00326 TIter next(GetListOfPositions());
00327 Int_t posNumber = 0;
00328 while ( (nodePosition = (TVolumePosition *)next()) ) {
00329 posNumber = nodePosition->GetId();
00330 TString posName = "*";
00331 posName += nodePosition->GetNode()->GetTitle();
00332 char num[10];
00333 posName += ";";
00334 snprintf(num,10,"%d",posNumber);
00335 posName += num;
00336 b->Add(nodePosition,posName.Data());
00337 }
00338 }
00339 }
00340
00341 Int_t TVolume::DistancetoPrimitive(Int_t px, Int_t py)
00342 {
00343
00344 return DistancetoNodePrimitive(px,py);
00345 }
00346
00347
00348 Int_t TVolume::DistancetoNodePrimitive(Int_t px, Int_t py,TVolumePosition *pos)
00349 {
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360 const Int_t big = 9999;
00361 if ( GetVisibility() == kNoneVisible ) return big;
00362
00363 const Int_t inaxis = 7;
00364 const Int_t maxdist = 5;
00365
00366 Int_t puxmin = gPad->XtoAbsPixel(gPad->GetUxmin());
00367 Int_t puymin = gPad->YtoAbsPixel(gPad->GetUymin());
00368 Int_t puxmax = gPad->XtoAbsPixel(gPad->GetUxmax());
00369 Int_t puymax = gPad->YtoAbsPixel(gPad->GetUymax());
00370
00371
00372 if (px < puxmin - inaxis) return big;
00373 if (py > puymin + inaxis) return big;
00374 if (px > puxmax + inaxis) return big;
00375 if (py < puymax - inaxis) return big;
00376
00377 TView *view =gPad->GetView();
00378 if (!view) return big;
00379
00380 static TVolumePosition nullPosition;
00381 TVolumePosition *position = pos;
00382 if (!position) position = &nullPosition;
00383 if (pos) position->UpdatePosition();
00384 Int_t dist = big;
00385 if ( !(GetVisibility() & kThisUnvisible ) ) {
00386 TShape *shape = 0;
00387 TIter nextShape(fListOfShapes);
00388 while ((shape = (TShape *)nextShape())) {
00389
00390 if (shape->GetVisibility()) {
00391 Int_t dshape = shape->DistancetoPrimitive(px,py);
00392 if (dshape < maxdist) {
00393 gPad->SetSelected(this);
00394 return 0;
00395 }
00396 if (dshape < dist) dist = dshape;
00397 }
00398 }
00399 }
00400
00401 if ( (GetVisibility() & kSonUnvisible) ) return dist;
00402
00403
00404 TList *posList = GetListOfPositions();
00405 Int_t dnode = dist;
00406 if (posList && posList->GetSize()) {
00407 gGeometry->PushLevel();
00408 TVolumePosition *thisPosition;
00409 TObject *obj;
00410 TIter next(posList);
00411 while ((obj = next())) {
00412 thisPosition = (TVolumePosition*)obj;
00413 TVolume *node = thisPosition->GetNode();
00414 dnode = node->DistancetoNodePrimitive(px,py,thisPosition);
00415 if (dnode <= 0) break;
00416 if (dnode < dist) dist = dnode;
00417 if (gGeometry->GeomLevel() > 2) break;
00418 }
00419 gGeometry->PopLevel();
00420 }
00421
00422 if (gGeometry->GeomLevel()==0 && dnode > maxdist) {
00423 gPad->SetSelected(view);
00424 return 0;
00425 } else
00426 return dnode;
00427 }
00428
00429
00430 void TVolume::Draw(Option_t *option)
00431 {
00432
00433
00434
00435 TString opt = option;
00436 opt.ToLower();
00437
00438 if (!gPad) {
00439 gROOT->MakeDefCanvas();
00440 }
00441 if (!opt.Contains("same")) gPad->Clear();
00442
00443
00444
00445 Int_t iopt = atoi(option);
00446 TDataSet *parent = 0;
00447 char buffer[10];
00448 if (iopt < 0) {
00449
00450 snprintf(buffer,10,"%d",-iopt);
00451 option = buffer;
00452
00453 parent = this;
00454 do parent = parent->GetParent();
00455 while (parent && ++iopt);
00456 }
00457 if (parent) parent->AppendPad(option);
00458 else AppendPad(option);
00459 #if ROOT_VERSION_CODE >= ROOT_VERSION(4,03,05)
00460
00461
00462 TView *view = gPad->GetView();
00463 if (!view) {
00464 view = TView::CreateView(1,0,0);
00465
00466
00467 view->SetAutoRange(kTRUE);
00468 }
00469
00470
00471
00472 gPad->GetViewer3D();
00473 #else
00474 Paint(option);
00475 #endif
00476 }
00477
00478
00479
00480 void TVolume::DrawOnly(Option_t *option)
00481 {
00482
00483
00484
00485 SetVisibility(kThisUnvisible);
00486 Draw(option);
00487 }
00488
00489
00490
00491 void TVolume::ExecuteEvent(Int_t, Int_t, Int_t)
00492 {
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503 gPad->SetCursor(kHand);
00504 }
00505
00506
00507 TRotMatrix *TVolume::GetIdentity()
00508 {
00509
00510 Double_t *identityMatrix = 0;
00511 if (!gIdentity) {
00512 gIdentity = gGeometry->GetRotMatrix("Identity");
00513 if (!gIdentity) {
00514 gIdentity = new TRotMatrix();
00515 gIdentity->SetName("Identity");
00516 gIdentity->SetTitle("Identity matrix");
00517 gIdentity->SetMatrix((Double_t *)0);
00518 identityMatrix = gIdentity->GetMatrix();
00519 memset(identityMatrix,0,9*sizeof(Double_t));
00520 *identityMatrix = 1;
00521 identityMatrix += 4; *identityMatrix = 1;
00522 identityMatrix += 4; *identityMatrix = 1;
00523 gGeometry->GetListOfMatrices()->AddFirst(gIdentity);
00524 }
00525 }
00526 return gIdentity;
00527 }
00528
00529
00530 char *TVolume::GetObjectInfo(Int_t px, Int_t py) const
00531 {
00532
00533 if (!gPad) return 0;
00534 static char info[512];
00535 snprintf(info,512,"%s/%s",GetName(),GetTitle());
00536 Double_t x[3];
00537 ((TPad *)gPad)->AbsPixeltoXY(px,py,x[0],x[1]);
00538 x[2] = 0;
00539 TView *view =gPad->GetView();
00540 if (view) view->NDCtoWC(x, x);
00541
00542 TIter nextShape(fListOfShapes);
00543 TShape *shape = 0;
00544 while( (shape = (TShape *)nextShape()) ) {
00545 Int_t nchi = strlen(info);
00546 snprintf(&info[nchi],512-nchi," %6.2f/%6.2f: shape=%s/%s",x[0],x[1],shape->GetName(),shape->ClassName());
00547 }
00548 return info;
00549 }
00550
00551
00552 void TVolume::ImportShapeAttributes()
00553 {
00554
00555
00556
00557 if (fShape) {
00558 SetLineColor(fShape->GetLineColor());
00559 SetLineStyle(fShape->GetLineStyle());
00560 SetLineWidth(fShape->GetLineWidth());
00561 SetFillColor(fShape->GetFillColor());
00562 SetFillStyle(fShape->GetFillStyle());
00563 }
00564
00565 if (!GetCollection()) return;
00566 TVolume *volume;
00567 TIter next(GetCollection());
00568 while ( (volume = (TVolume *)next()) )
00569 volume->ImportShapeAttributes();
00570 }
00571
00572
00573 void TVolume::Paint(Option_t *opt)
00574 {
00575
00576 gGeometry->SetGeomLevel();
00577 gGeometry->UpdateTempMatrix();
00578 PaintNodePosition(opt);
00579 return;
00580 }
00581
00582
00583 void TVolume::PaintNodePosition(Option_t *option,TVolumePosition *pos)
00584 {
00585
00586
00587
00588
00589
00590
00591
00592
00593
00594 if ( GetVisibility() == kNoneVisible ) return;
00595
00596 static TVolumePosition nullPosition;
00597
00598
00599 Int_t level = gGeometry->GeomLevel();
00600
00601 if ((!(GetVisibility() & kThisUnvisible)) && option && option[0]=='r' && level > 3 ) return;
00602 Int_t iopt = 0;
00603 if (option) iopt = atoi(option);
00604 if ( (0 < iopt) && (iopt <= level) ) return;
00605
00606 TTablePadView3D *view3D = (TTablePadView3D*)gPad->GetView3D();
00607 TVirtualViewer3D * viewer3D = gPad->GetViewer3D();
00608
00609 TVolumePosition *position = pos;
00610 if (!position) position = &nullPosition;
00611
00612
00613
00614 position->UpdatePosition(option);
00615
00616 if ( viewer3D && !(GetVisibility() & kThisUnvisible)) PaintShape(option);
00617
00618 if (GetVisibility() & kSonUnvisible) return;
00619
00620
00621 TList *posList = GetListOfPositions();
00622 if (posList && posList->GetSize()) {
00623 gGeometry->PushLevel();
00624 TVolumePosition *thisPosition;
00625 TIter next(posList);
00626 while ((thisPosition = (TVolumePosition *)next())) {
00627 if (view3D) view3D->PushMatrix();
00628
00629 TVolume *volume = thisPosition->GetNode();
00630 if (volume) volume->PaintNodePosition(option,thisPosition);
00631
00632 if (view3D) view3D->PopMatrix();
00633 }
00634 gGeometry->PopLevel();
00635 }
00636 }
00637
00638
00639 void TVolume::PaintShape(Option_t *option)
00640 {
00641
00642
00643 Bool_t rangeView = option && option[0]=='r';
00644 if (!rangeView) {
00645 TAttLine::Modify();
00646 TAttFill::Modify();
00647 }
00648
00649 if ( (GetVisibility() & kThisUnvisible) ) return;
00650
00651 TIter nextShape(fListOfShapes);
00652 TShape *shape = 0;
00653 while( (shape = (TShape *)nextShape()) ) {
00654 if (!rangeView) {
00655 shape->SetLineColor(GetLineColor());
00656 shape->SetLineStyle(GetLineStyle());
00657 shape->SetLineWidth(GetLineWidth());
00658 shape->SetFillColor(GetFillColor());
00659 shape->SetFillStyle(GetFillStyle());
00660 TTablePadView3D *view3D = (TTablePadView3D*)gPad->GetView3D();
00661 gPad->GetViewer3D();
00662 if (view3D)
00663 view3D->SetLineAttr(GetLineColor(),GetLineWidth(),option);
00664 }
00665
00666 #if ROOT_VERSION_CODE >= ROOT_VERSION(4,03,05)
00667
00668 Bool_t viewerWantsSons = kTRUE;
00669 TVirtualViewer3D * viewer3D = gPad->GetViewer3D();
00670 if (viewer3D) {
00671
00672
00673
00674
00675
00676 const TBuffer3D & buffer =
00677 fShape->GetBuffer3D(TBuffer3D::kCore|TBuffer3D::kBoundingBox|TBuffer3D::kShapeSpecific);
00678
00679
00680
00681 const_cast<TBuffer3D &>(buffer).fID = this;
00682
00683 Int_t reqSections = viewer3D->AddObject(buffer, &viewerWantsSons);
00684 if (reqSections != TBuffer3D::kNone) {
00685 fShape->GetBuffer3D(reqSections);
00686 viewer3D->AddObject(buffer);
00687 }
00688 }
00689 #else
00690 shape->Paint(option);
00691 #endif
00692 }
00693 }
00694
00695
00696 void TVolume::DeletePosition(TVolumePosition *position)
00697 {
00698
00699
00700
00701 if (!position) return;
00702
00703 if (GetListOfPositions()) {
00704 TObjLink *lnk = GetListOfPositions()->FirstLink();
00705 while (lnk) {
00706 TVolumePosition *nextPosition = (TVolumePosition *)(lnk->GetObject());
00707 if (nextPosition && nextPosition == position) {
00708 TVolume *node = nextPosition->GetNode();
00709 GetListOfPositions()->Remove(lnk);
00710 delete nextPosition;
00711 Remove(node);
00712 break;
00713 }
00714 lnk = lnk->Next();
00715 }
00716 }
00717 }
00718
00719
00720 void TVolume::GetLocalRange(Float_t *min, Float_t *max)
00721 {
00722
00723
00724
00725
00726
00727
00728
00729
00730 TVirtualPad *savePad = gPad;
00731
00732 TCanvas dummyPad("--Dumm--","dum",1,1);
00733
00734 TView *view = TView::CreateView(1,0,0);
00735
00736 gGeometry->SetGeomLevel();
00737 gGeometry->UpdateTempMatrix();
00738 view->SetAutoRange(kTRUE);
00739 Paint("range");
00740 view->GetRange(&min[0],&max[0]);
00741 delete view;
00742
00743 if (savePad) savePad->cd();
00744 }
00745
00746
00747 void TVolume::SetVisibility(ENodeSEEN vis)
00748 {
00749
00750
00751
00752
00753
00754
00755
00756
00757 fVisibility = vis;
00758 }
00759
00760
00761 void TVolume::Sizeof3D() const
00762 {
00763
00764
00765
00766 if (!(GetVisibility() & kThisUnvisible) ) {
00767 TIter nextShape(fListOfShapes);
00768 TShape *shape = 0;
00769 while( (shape = (TShape *)nextShape()) ) {
00770 if (shape->GetVisibility()) shape->Sizeof3D();
00771 }
00772 }
00773
00774 if ( GetVisibility() & kSonUnvisible ) return;
00775
00776 if (!Nodes()) return;
00777 TVolume *node;
00778 TObject *obj;
00779 TIter next(Nodes());
00780 while ((obj = next())) {
00781 node = (TVolume*)obj;
00782 node->Sizeof3D();
00783 }
00784 }