TVolumeView.cxx

Go to the documentation of this file.
00001 // @(#)root/table:$Id: TVolumeView.cxx 36216 2010-10-09 09:05:14Z brun $
00002 // Author: Valery Fine(fine@bnl.gov)   25/12/98
00003 
00004 /*************************************************************************
00005  * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers.               *
00006  * All rights reserved.                                                  *
00007  *                                                                       *
00008  * For the licensing terms see $ROOTSYS/LICENSE.                         *
00009  * For the list of contributors see $ROOTSYS/README/CREDITS.             *
00010  *************************************************************************/
00011 
00012 
00013 #include "Riostream.h"
00014 #include <assert.h>
00015 #include <stdlib.h>
00016 
00017 #include "TCanvas.h"
00018 #include "TPad.h"
00019 #include "TCernLib.h"
00020 #include "TBrowser.h"
00021 #include "TVolumeView.h"
00022 #include "TVolumeViewIter.h"
00023 #include "TVolumePosition.h"
00024 #include "TROOT.h"
00025 #include "TView.h"
00026 #include "TTablePadView3D.h"
00027 #include "TGeometry.h"
00028 #include "TVirtualPad.h"
00029 #include "TObjArray.h"
00030 #include "TVirtualViewer3D.h"
00031 #include "TBuffer3D.h"
00032 
00033 //////////////////////////////////////////////////////////////////////////
00034 //                                                                      //
00035 // TVolumeView                                                          //
00036 //                                                                      //
00037 // TVolumeView class is a special kind of TDataSet with one extra       //
00038 // pointer to wrap any TObject onto TDataSet object                     //
00039 //                                                                      //
00040 //  BE CAREFUL !!!                                                      //
00041 //  One has to use it carefully no control over that extra object       //
00042 //  is performed. This means: the object m_Obj data-member points to can//
00043 //  be destroyed with no this kbject notifying.                         //
00044 //  There is no tool /protection to check whether m_Obj is till alive.  //
00045 //  It is one's  code responsilitiy                                     //
00046 //                                                                      //
00047 //////////////////////////////////////////////////////////////////////////
00048 
00049 ClassImp(TVolumeView)
00050 
00051 //_____________________________________________________________________________
00052 TVolumeView::TVolumeView(TVolumeView *viewNode,TVolumePosition *nodePosition)
00053             : TObjectSet(viewNode->GetName(),(TObject *)nodePosition),fListOfShapes(0)
00054             //             ,fListOfAttributes(0)
00055 {
00056   //
00057   // This ctor creates a TVolumeView structure from the "marked" nodes
00058   // of the "viewNode" input structure
00059   // It re-calculates all positions according of the new topology
00060   // All new TVolume became UNMARKED though
00061   //
00062    if (!gGeometry) new TGeometry;
00063    if (viewNode) {
00064       SetTitle(viewNode->GetTitle());
00065       EDataSetPass mode = kContinue;
00066       TVolumeViewIter next(viewNode,0);
00067       TVolumeView *nextView = 0;
00068       while ( (nextView = (TVolumeView *)next(mode)) ){
00069          mode = kContinue;
00070          if (nextView->IsMarked()) {
00071             TVolumePosition *position =next[0];
00072             if (!position->GetNode()) {
00073                Error("TVolumeView ctor","%s %s ",GetName(),nextView->GetName());
00074             }
00075             Add(new TVolumeView(nextView,position));
00076             mode = kPrune;
00077          }
00078       }
00079    }
00080 }
00081 
00082 //_____________________________________________________________________________
00083 TVolumeView::TVolumeView(TVolumeView *viewNode,TVolumeView *topNode)
00084             : TObjectSet(viewNode->GetName(),(TObject *)0),fListOfShapes(0)
00085             //             ,fListOfAttributes(0)
00086 {
00087   //
00088   // This ctor creates a TVolumeView structure containing:
00089   //
00090   //   - viewNode on the top
00091   //   - skip ALL node from the original viewNode untill topNode found
00092   //   - include all "marked" node below "topNode" if any
00093   //     topNode is always included
00094   //
00095   // It re-calculates all positions according of the new topology
00096   //
00097    if (!gGeometry) new TGeometry;
00098    if (viewNode && topNode) {
00099       SetTitle(viewNode->GetTitle());
00100       // define the depth of the "top" Node
00101       EDataSetPass mode = kContinue;
00102       TVolumeViewIter next(viewNode,0);
00103       TVolumeView *nextView = 0;
00104       while ( (nextView = (TVolumeView *)next(mode)) ){
00105          mode = kContinue;
00106          // Skip till  "top Node" found
00107          if (topNode != nextView) continue;
00108          TVolumePosition *position = next[0];
00109          if (!position->GetNode()) {
00110             Error("TVolumeView ctor","%s %s ",GetName(),nextView->GetName());
00111          }
00112          Add(new TVolumeView(nextView,position));
00113          break;
00114       }
00115    }
00116 }
00117 
00118 //_____________________________________________________________________________
00119 TVolumeView::TVolumeView(TVolumeView *viewNode,const Char_t *nodeName1,const Char_t *nodeName2)
00120             : TObjectSet(viewNode->GetName(),(TObject *)0),fListOfShapes(0)
00121             //             ,fListOfAttributes(0)
00122 {
00123   //
00124   // This ctor creates a TVolumeView structure containing:
00125   //
00126   //   - viewNode on the top
00127   //   - skip ALL node from the original viewNode untill topNodeName found
00128   //   - include all "marked" node below "topNodename" if any
00129   //     topNodeName is always included
00130   //
00131   // It re-calculates all positions according of the new topology
00132   //
00133    const Char_t *foundName[2] = {nodeName1, nodeName2};
00134    Bool_t found = kFALSE;
00135    if (!gGeometry) new TGeometry;
00136    if (viewNode && nodeName1 && nodeName1[0]) {
00137       SetTitle(viewNode->GetTitle());
00138       // define the depth of the "top" Node
00139       EDataSetPass mode = kContinue;
00140       TVolumeViewIter next(viewNode,0);
00141       TVolumeView *nextView = 0;
00142       while ( (nextView = (TVolumeView *)next(mode)) ){
00143          mode = kContinue;
00144          // Skip till  "top Node" found
00145          Int_t i = 0;
00146          found = kFALSE;
00147          for (i=0;i<2;i++) {
00148             if (foundName[i]) {
00149                if (strcmp(nextView->GetName(),foundName[i])) continue;
00150                foundName[i] = 0;
00151                found = kTRUE;
00152                break;
00153             }
00154          }
00155          if (!found) continue;
00156          TVolumePosition *position = next[0];
00157          if (!position->GetNode()) {
00158             Error("TVolumeView ctor","%s %s ",GetName(),nextView->GetName());
00159          }
00160          Add(new TVolumeView(nextView,position));
00161          mode = kPrune;
00162       }
00163    }
00164 }
00165 
00166 //_____________________________________________________________________________
00167 TVolumeView::TVolumeView(TVolumeView *viewNode,const TVolumeView *node1,const TVolumeView *node2)
00168             : TObjectSet(viewNode->GetName(),(TObject *)0),fListOfShapes(0)
00169             //             ,fListOfAttributes(0)
00170 {
00171   //
00172   // This ctor creates a TVolumeView structure containing:
00173   //
00174   //   - viewNode on the top
00175   //   - skip ALL node from the original viewNode untill topNodeName found
00176   //   - include all "marked" node below "topNodename" if any
00177   //     topNodeName is always included
00178   //
00179   // It re-calculates all positions according of the new topology
00180   //
00181    const TVolumeView *foundView[2] = {node1, node2};
00182    const Int_t nViews = sizeof(foundView)/sizeof(const TVolumeView *);
00183    Bool_t found = kFALSE;
00184    if (!gGeometry) new TGeometry;
00185    if (viewNode) {
00186       SetTitle(viewNode->GetTitle());
00187       // define the depth of the "top" Node
00188       EDataSetPass mode = kContinue;
00189       TVolumeViewIter next(viewNode,0);
00190       TVolumeView *nextView = 0;
00191       while ( (nextView = (TVolumeView *)next(mode)) ){
00192          mode = kContinue;
00193          // Skip till  "top Node" found
00194          Int_t i = 0;
00195          found = kFALSE;
00196          for (i=0;i<nViews;i++) {
00197             if (foundView[i]) {
00198                if (nextView != foundView[i]) continue;
00199                foundView[i] = 0;
00200                found = kTRUE;
00201                break;
00202             }
00203          }
00204          if (!found) continue;
00205          TVolumePosition *position = next[0];
00206          if (!position->GetNode()) {
00207             Error("TVolumeView ctor","%s %s ",GetName(),nextView->GetName());
00208          }
00209          Add(new TVolumeView(nextView,position));
00210          mode = kPrune;
00211       }
00212    }
00213 }
00214 
00215 //_____________________________________________________________________________
00216 TVolumeView::TVolumeView(TVolume &pattern,Int_t maxDepLevel,
00217              const TVolumePosition *nodePosition,EDataSetPass iopt, TVolumeView *rootVolume)
00218             : TObjectSet(pattern.GetName(),(TObject *)nodePosition),fListOfShapes(0)
00219 {
00220   //
00221   // Creates TVolumeView (view) with a topology similar with TVolume *pattern
00222   //
00223   //  Parameters:
00224   //  -----------
00225   //  pattern        - the pattern dataset
00226   //  iopt = kStruct - clone only my structural links
00227   //         kAll    - clone all links
00228   //         kRefs   - clone only refs
00229   //         kMarked - clone marked (not implemented yet) only
00230   //
00231   //   All new-created sets become the structural ones anyway.
00232   //
00233   //  cout << "ctor for " << GetName() << " - " << GetTitle() << endl;
00234    if (!gGeometry) new TGeometry;
00235    if (!nodePosition) {
00236       // Create the trivial position if any
00237       nodePosition = new TVolumePosition(&pattern);
00238       SetObject((TObject*)nodePosition);
00239    }
00240    if (!rootVolume) {
00241       rootVolume   = this;
00242       nodePosition = 0;
00243    }
00244    SetTitle(pattern.GetTitle());
00245    if ( pattern.IsMarked() ) Mark();
00246    TVolumePosition *position = 0;
00247    const TList *list = pattern.GetListOfPositions();
00248    if (!list || maxDepLevel == 1 || maxDepLevel < 0) return;
00249 
00250    TIter nextPosition(list);
00251    Bool_t optSel    = (iopt == kStruct);
00252 //  Bool_t optAll    = (iopt == kAll);
00253    Bool_t optMarked = (iopt == kMarked);
00254 
00255    const TRotMatrix *thisMatrix = 0;
00256    Double_t thisTranslation[3] = {0,0,0};
00257    if (nodePosition ) {
00258       thisMatrix = nodePosition->GetMatrix();
00259       for (int i =0; i< 3; i++) thisTranslation[i]= nodePosition->GetX(i);
00260    }
00261    while ( (position = (TVolumePosition *)nextPosition()) ) {
00262       // define the the related TVolume
00263       TVolume *node     = position->GetNode();
00264       Double_t *positionMatrix = ((TRotMatrix *)position->GetMatrix())->GetMatrix();
00265       if (node) {
00266          UInt_t positionId = position->GetId();
00267          Double_t newTranslation[3] = {position->GetX(),position->GetY(),position->GetZ()};
00268          Double_t newMatrix[9];
00269          TRotMatrix currentMatrix;
00270 
00271          if (nodePosition) {
00272             if (positionMatrix) {
00273                TGeometry::UpdateTempMatrix(thisTranslation,thisMatrix?((TRotMatrix *)thisMatrix)->GetMatrix():0
00274                          ,position->GetX(),position->GetY(),position->GetZ(),positionMatrix
00275                          ,newTranslation,newMatrix);
00276                currentMatrix.SetMatrix(newMatrix);
00277             } else {
00278                TCL::vadd(thisTranslation, newTranslation,newTranslation,3);
00279                currentMatrix.SetMatrix(((TRotMatrix *)thisMatrix)->GetMatrix());
00280             }
00281          } else {
00282             if (positionMatrix)
00283                currentMatrix.SetMatrix(positionMatrix);
00284             else {
00285                TCL::ucopy(thisTranslation,newTranslation,3);
00286                currentMatrix.SetMatrix(TVolume::GetIdentity()->GetMatrix());
00287             }
00288          }
00289          TVolumePosition nextPos(node,newTranslation[0],newTranslation[1],
00290                                       newTranslation[2], &currentMatrix);
00291          nextPos.SetId(positionId);
00292          if (optMarked && !node->IsMarked()) {
00293             TVolumeView fakeView(*node,maxDepLevel,&nextPos,iopt,rootVolume);
00294             fakeView.DoOwner(kFALSE);
00295             continue;
00296          }
00297 
00298          if (optSel) {
00299             TDataSet *parent = node->GetParent();
00300             if ( parent && (parent != (TDataSet *)&pattern) ) continue;
00301          }
00302          TRotMatrix *newRotation = new TRotMatrix();
00303          newRotation->SetMatrix(currentMatrix.GetMatrix());
00304          TVolumePosition *nP = new TVolumePosition(node,newTranslation[0],newTranslation[1],
00305                                      newTranslation[2], newRotation);
00306          nP->SetId(positionId);
00307          rootVolume->Add(new TVolumeView(*node,maxDepLevel?maxDepLevel-1:0,nP,iopt));
00308       } else
00309          Error("TVolumeView ctor","Position with NO node attached has been supplied");
00310 
00311    }
00312 }
00313 //_____________________________________________________________________________
00314 TVolumeView::TVolumeView(TVolumeView &viewNode):
00315              TObjectSet(viewNode.GetName(),(TObject *)viewNode.GetPosition())
00316             ,TAtt3D()
00317             ,fListOfShapes(viewNode.GetListOfShapes())
00318 {
00319    //to be documented
00320    if (viewNode.IsOwner()) {
00321       viewNode.DoOwner(kFALSE); DoOwner();
00322    }
00323 }
00324 
00325 //_____________________________________________________________________________
00326 TVolumeView::TVolumeView(Double_t *translate, Double_t *rotate, UInt_t positionId, TVolume *topNode,
00327                          const Char_t *thisNodePath, const Char_t *matrixName, Int_t matrixType)
00328             // : fListOfAttributes(0)
00329 {
00330    // Special ctor to back TVolumeView::SavePrimitive() method
00331    if (!gGeometry) new TGeometry;
00332    fListOfShapes     = 0;
00333    TVolume *thisNode = 0;
00334    Double_t thisX  = translate[0];
00335    Double_t thisY  = translate[1];
00336    Double_t thisZ  = translate[2];
00337 
00338    // Find TVolume by path;
00339    if (topNode) {
00340       thisNode =  (TVolume *)topNode->Find(thisNodePath);
00341       if (!thisNode->InheritsFrom(TVolume::Class())) {
00342          Error("TVolumeView","wrong node <%s> on path: \"%s\"",thisNode->GetName(),thisNodePath);
00343          thisNode = 0;
00344       }
00345    }
00346 
00347    TRotMatrix *thisRotMatrix =  0;
00348    if (matrixName && strlen(matrixName)) thisRotMatrix = gGeometry->GetRotMatrix(matrixName);
00349    TVolumePosition *thisPosition = 0;
00350    if (thisRotMatrix)
00351       thisPosition = new TVolumePosition(thisNode,thisX, thisY, thisZ, matrixName);
00352    else if (matrixType==2)
00353       thisPosition = new TVolumePosition(thisNode,thisX, thisY, thisZ);
00354    else if (rotate) {
00355       const Char_t *title = "rotation";
00356       thisRotMatrix = new TRotMatrix((char *)matrixName,(char *)title,rotate);
00357       thisPosition  = new TVolumePosition(thisNode,thisX, thisY, thisZ, thisRotMatrix);
00358    } else
00359       Error("TVolumeView"," No rotation matrix is defined");
00360    if (thisPosition) thisPosition->SetId(positionId);
00361    SetObject(thisPosition);
00362    if (thisNode) {
00363       SetName(thisNode->GetName());
00364       SetTitle(thisNode->GetTitle());
00365    }
00366 }
00367 
00368 //_____________________________________________________________________________
00369 TVolumeView::TVolumeView(TVolume *thisNode,TVolumePosition *nodePosition)
00370             : TObjectSet(thisNode?thisNode->GetName():"",(TObject *)nodePosition),fListOfShapes(0)
00371 {
00372    //to be documented
00373    if (!gGeometry) new TGeometry;
00374    SafeDelete(fListOfShapes);
00375    if (thisNode)
00376       SetTitle(thisNode->GetTitle());
00377 }
00378 
00379 //______________________________________________________________________________
00380 TVolumeView::~TVolumeView()
00381 {
00382 // default dtor (empty for this class)
00383 }
00384 
00385 //_____________________________________________________________________________
00386 TVolume *TVolumeView::AddNode(TVolume *node)
00387 {
00388   // Add the TVolume in the Tnode data-structure refered
00389   // by this TVolumeView object
00390   // Return TVolume * the input TVolume * was attached to
00391 
00392    TVolume *closedNode = 0;
00393    TVolumePosition *pos ;
00394    if ( node && (pos = GetPosition() )  && (closedNode = pos->GetNode()) )
00395       closedNode->Add(node);
00396    return closedNode;
00397 }
00398 
00399 //______________________________________________________________________________
00400 void TVolumeView::Add(TShape *shape, Bool_t IsMaster)
00401 {
00402    //to be documented
00403    if (!shape) return;
00404    if (!fListOfShapes) fListOfShapes = new TList;
00405    if (IsMaster)
00406       fListOfShapes->AddFirst(shape);
00407    else
00408       fListOfShapes->Add(shape);
00409 }
00410 
00411 //_____________________________________________________________________________
00412 void TVolumeView::Browse(TBrowser *b)
00413 {
00414    //to be documented
00415    TObjectSet::Browse(b);
00416 //  TVolumePosition *pos = GetPosition();
00417 //  if (pos) pos->Browse(b);
00418 //    b->Add(pos);
00419 }
00420 
00421 //______________________________________________________________________________
00422 Int_t TVolumeView::DistancetoPrimitive(Int_t px, Int_t py)
00423 {
00424 //*-*-*-*-*-*-*-*-*Compute distance from point px,py to a TVolumeView*-*-*-*-*-*
00425 //*-*                  ===========================================
00426 //*-*  Compute the closest distance of approach from point px,py to the position of
00427 //*-*  this node.
00428 //*-*  The distance is computed in pixels units.
00429 //*-*
00430 //*-*  It is restricted by 2 levels of TVolumes
00431 //*-*
00432 //*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
00433 
00434    const Int_t big = 9999;
00435    const Int_t inaxis = 7;
00436    const Int_t maxdist = 5;
00437 
00438    Int_t dist = big;
00439 
00440    Int_t puxmin = gPad->XtoAbsPixel(gPad->GetUxmin());
00441    Int_t puymin = gPad->YtoAbsPixel(gPad->GetUymin());
00442    Int_t puxmax = gPad->XtoAbsPixel(gPad->GetUxmax());
00443    Int_t puymax = gPad->YtoAbsPixel(gPad->GetUymax());
00444 
00445 //*-*- return if point is not in the user area
00446    if (px < puxmin - inaxis) return big;
00447    if (py > puymin + inaxis) return big;
00448    if (px > puxmax + inaxis) return big;
00449    if (py < puymax - inaxis) return big;
00450 
00451    TView *view =gPad->GetView();
00452    if (!view) return big;
00453 
00454    TVolumePosition *position = GetPosition();
00455    TVolume *thisNode  = 0;
00456    TShape  *thisShape = 0;
00457    if (position) {
00458       thisNode = position->GetNode();
00459       position->UpdatePosition();
00460       if (thisNode) {
00461          thisShape    = thisNode->GetShape();
00462          if (!(thisNode->GetVisibility() & TVolume::kThisUnvisible) &&
00463             thisShape && thisShape->GetVisibility()) {
00464             dist = thisShape->DistancetoPrimitive(px,py);
00465             if (dist < maxdist) {
00466                gPad->SetSelected(this);
00467                return 0;
00468             }
00469          }
00470       }
00471    }
00472 
00473 //   if ( TestBit(kSonsInvisible) ) return dist;
00474 
00475 //*-*- Loop on all sons
00476    TSeqCollection *fNodes =  GetCollection();
00477    Int_t nsons = fNodes?fNodes->GetSize():0;
00478    Int_t dnode = dist;
00479    if (nsons) {
00480       gGeometry->PushLevel();
00481       TVolume *node;
00482       TIter  next(fNodes);
00483       while ((node  = (TVolume *)next())) {
00484          dnode = node->DistancetoPrimitive(px,py);
00485          if (dnode <= 0)  break;
00486          if (dnode < dist) dist = dnode;
00487          if (gGeometry->GeomLevel() > 2) break;
00488       }
00489       gGeometry->PopLevel();
00490    }
00491 
00492    if (gGeometry->GeomLevel()==0 && dnode > maxdist) {
00493       gPad->SetSelected(view);
00494       return 0;
00495    } else
00496       return dnode;
00497 }
00498 
00499 //______________________________________________________________________________
00500 void TVolumeView::Draw(Option_t *option)
00501 {
00502 //*-*-*-*-*-*-*-*-*-*-*-*Draw Referenced node with current parameters*-*-*-*
00503 //*-*                   =============================================
00504 
00505    TString opt = option;
00506    opt.ToLower();
00507 //*-*- Clear pad if option "same" not given
00508    if (!gPad) {
00509       gROOT->MakeDefCanvas();
00510    }
00511    if (!opt.Contains("same")) gPad->Clear();
00512 
00513 //*-*- Draw Referenced node
00514    gGeometry->SetGeomLevel();
00515    gGeometry->UpdateTempMatrix();
00516 
00517    // Check geometry level
00518 
00519    Int_t iopt = atoi(option);
00520    TDataSet *parent = 0;
00521    char buffer[10];
00522    if (iopt < 0) {
00523       snprintf(buffer,10,"%d",-iopt);
00524       option = buffer;
00525       // select parent to draw
00526       parent = this;
00527       do parent = parent->GetParent();
00528       while (parent && ++iopt);
00529    }
00530    if (parent) parent->AppendPad(option);
00531    else        AppendPad(option);
00532 
00533 #if ROOT_VERSION_CODE >= ROOT_VERSION(4,03,05)
00534    // the new (4.03/05) way to active 3D viewer
00535    // Create a 3-D view
00536    TView *view = gPad->GetView();
00537    if (!view) {
00538       view = TView::CreateView(1,0,0);
00539       // Set the view to perform a first autorange (frame) draw.
00540       // TViewer3DPad will revert view to normal painting after this
00541       view->SetAutoRange(kTRUE);
00542    }
00543 
00544    // Create a 3D viewer to draw us
00545    gPad->GetViewer3D(option);
00546 #else
00547     Paint(option);
00548 #endif
00549 }
00550 
00551 //_____________________________________________________________________________
00552 TVolume *TVolumeView::GetNode() const
00553 {
00554    //to be documented
00555    TVolumePosition *pos = GetPosition();
00556    if (pos)
00557       return pos->GetNode();
00558    return 0;
00559 }
00560 
00561 //_____________________________________________________________________________
00562 Int_t TVolumeView::GetGlobalRange(const TVolumeView *rootNode,Float_t *globalMin,Float_t *globalMax)
00563 {
00564    //
00565    // Calculate the position of the vertrex of the outlined cube in repect
00566    // of the given TVolumeView object
00567    //
00568    if (rootNode) {
00569       SetTitle(rootNode->GetTitle());
00570       EDataSetPass mode = kContinue;
00571       TVolumeViewIter next((TVolumeView *)rootNode,0);
00572       TVolumeView *nextView = 0;
00573       // Find itself.
00574       while ( (nextView = (TVolumeView *)next(mode)) && nextView != this ){}
00575       if (nextView == this) {
00576          TVolumePosition *position = next[0];
00577          if (!position->GetNode()) {
00578             Error("TVolumeView ctor","%s %s ",GetName(),nextView->GetName());
00579          }
00580          // Calculate the range of the outlined cube verteces.
00581          GetLocalRange(globalMin,globalMax);
00582          Float_t offSet[3] = {position->GetX(),position->GetY(),position->GetZ()};
00583          for (Int_t i=0;i<3;i++) {
00584             globalMin[i] += offSet[i];
00585             globalMax[i] += offSet[i];
00586          }
00587       }
00588       return next.GetDepth();
00589    }
00590    else return -1;
00591 }
00592 
00593 //______________________________________________________________________________
00594 void TVolumeView::GetLocalRange(Float_t *min, Float_t *max)
00595 {
00596   //  GetRange
00597   //
00598   //  Calculates the size of 3 box the node occupies.
00599   //  Return:
00600   //    two floating point arrays with the bound of box
00601   //     surroundind all shapes of this TModeView
00602   //
00603 
00604    TVirtualPad *savePad = gPad;
00605    //  Create a dummy TPad;
00606    TCanvas dummyPad("--Dumm--","dum",1,1);
00607    // Assing 3D TView
00608    TView *view = TView::CreateView(1,0,0);
00609 
00610    gGeometry->SetGeomLevel();
00611    gGeometry->UpdateTempMatrix();
00612    view->SetAutoRange(kTRUE);
00613    Paint("range");
00614    view->GetRange(&min[0],&max[0]);
00615    delete view;
00616    // restore "current pad"
00617    if (savePad) savePad->cd();
00618 }
00619 
00620 //______________________________________________________________________________
00621 char *TVolumeView::GetObjectInfo(Int_t px, Int_t py) const
00622 {
00623    //to be documented
00624    if (!gPad) return 0;
00625    static char info[512];
00626    Double_t x[3] = {0,0,0.5};
00627    ((TPad *)gPad)->AbsPixeltoXY(px,py,x[0],x[1]);
00628    TView *view =gPad->GetView();
00629    if (view) {
00630       Double_t min[3], max[3];
00631       view->GetRange(min,max);
00632       for (int i =0; i<3;i++) min[i] = (max[i]+min[i])/2;
00633       view->WCtoNDC(min,max);
00634       min[0] = x[0]; min[1] = x[1];
00635       min[2] = max[2];
00636       view->NDCtoWC(min, x);
00637    }
00638    TShape *shape = GetShape();
00639    if (shape)
00640       snprintf(info,512,"%6.2f/%6.2f/%6.2f: %s/%s, shape=%s/%s",x[0],x[1],x[2],GetName(),GetTitle(),shape->GetName(),shape->ClassName());
00641    else
00642       snprintf(info,512,"%6.2f/%6.2f/%6.2f: %s/%s",x[0],x[1],x[2],GetName(),GetTitle());
00643    return info;
00644 }
00645 
00646 //______________________________________________________________________________
00647 TVolumePosition  *TVolumeView::Local2Master(const Char_t *localName, const Char_t *masterName)
00648 {
00649    //to be documented
00650    TVolumeView *masterNode = this;
00651    TVolumePosition *position = 0;
00652    if (masterName && masterName[0]) masterNode = (TVolumeView *)Find(masterName);
00653    if (masterNode) {
00654       TVolumeViewIter transform(masterNode,0);
00655       if (transform(localName)) position = transform[0];
00656    }
00657    return position;
00658 }
00659 
00660 //______________________________________________________________________________
00661 TVolumePosition *TVolumeView::Local2Master(const TVolumeView *localNode,const TVolumeView *masterNode)
00662 {
00663    //to be documented
00664    TVolumePosition *position = 0;
00665    if (!masterNode) masterNode = this;
00666    if (masterNode && localNode) {
00667       TVolumeViewIter transform((TVolumeView *)masterNode,0);
00668       TVolumeView *nextNode = 0;
00669       while ((nextNode = (TVolumeView *)transform()) && nextNode != localNode) { }
00670       if (nextNode) position = transform[0];
00671    }
00672    return position;
00673 }
00674 
00675 //______________________________________________________________________________
00676 Float_t *TVolumeView::Local2Master(const Float_t *local, Float_t *master,
00677                                    const Char_t *localName, const Char_t *masterName, Int_t nVector)
00678 {
00679   //
00680   // calculate  transformation  master = (M-local->master )*local + (T-local->master )
00681   //  where
00682   //     M-local->master - rotation matrix 3 x 3 from the master node to the local node
00683   //     T-local->master - trasport vector 3 from the master node to the local node
00684   //
00685   // returns a "master" pointer if transformation has been found
00686   //        otherwise 0;
00687   //
00688    Float_t *trans = 0;
00689    TVolumePosition *position = 0;
00690    TVolumeView *masterNode = this;
00691    if (masterName && masterName[0]) masterNode = (TVolumeView *)Find(masterName);
00692    if (masterNode) {
00693       TVolumeViewIter transform(masterNode,0);
00694       if (transform(localName) && (position = (TVolumePosition *) transform.GetPosition()) )
00695          trans = position->Local2Master(local,master,nVector);
00696    }
00697    return trans;
00698 }
00699 
00700 //______________________________________________________________________________
00701 Float_t *TVolumeView::Local2Master(const Float_t *local, Float_t *master,
00702                                    const TVolumeView *localNode,
00703                                    const TVolumeView *masterNode, Int_t nVector)
00704 {
00705   //
00706   // calculate  transformation  master = (M-local->master )*local + (T-local->master )
00707   //  where
00708   //     M-local->master - rotation matrix 3 x 3 from the master node to the local node
00709   //     T-local->master - trasport vector 3 from the master node to the local node
00710   //
00711   // returns a "master" pointer if transformation has been found
00712   //        otherwise 0;
00713   //
00714    Float_t *trans = 0;
00715    TVolumePosition *position = 0;
00716    if (!masterNode) masterNode = this;
00717    if (masterNode && localNode) {
00718       TVolumeViewIter transform((TVolumeView *)masterNode,0);
00719       TVolumeView *nextNode = 0;
00720       while ((nextNode = (TVolumeView *)transform()) && nextNode != localNode) { }
00721       if (nextNode && (position = (TVolumePosition *) transform.GetPosition()) )
00722          trans = position->Local2Master(local,master,nVector);
00723    }
00724    return trans;
00725 }
00726 
00727 //______________________________________________________________________________
00728 void TVolumeView::Paint(Option_t *option)
00729 {
00730 //*-*-*-*-*-*-*-*-*-*-*-*Paint Referenced node with current parameters*-*-*-*
00731 //*-*                   ==============================================
00732 //*-*
00733 //*-*  vis = 1  (default) shape is drawn
00734 //*-*  vis = 0  shape is not drawn but its sons may be not drawn
00735 //*-*  vis = -1 shape is not drawn. Its sons are not drawn
00736 //*-*  vis = -2 shape is drawn. Its sons are not drawn
00737 //*-*
00738 //*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
00739 //
00740 // It draw the TVolumeView layers from the iFirst one (form the zero) till
00741 // iLast one reached.
00742 //
00743 // restrict the levels for "range" option
00744    Int_t level = gGeometry->GeomLevel();
00745    if (!option) return;
00746    if (option[0]=='r' && level > 3 ) return;
00747 
00748    Int_t iFirst =  atoi(option);
00749    Int_t iLast = 0;
00750    const char *delim = strpbrk( option,":-,");
00751    if (delim)  iLast = atoi(delim+1);
00752    if (iLast < iFirst) {
00753       iLast = iFirst-1;
00754       iFirst = 0;
00755    }
00756 
00757    if ( (0 < iLast) && (iLast < level) )  return;
00758 
00759    TTablePadView3D *view3D = (TTablePadView3D*)gPad->GetView3D();
00760 
00761    TVolume *thisNode  = 0;
00762    TVolumePosition *position = GetPosition();
00763 
00764    // UpdatePosition does change the current matrix and it MUST be called FIRST !!!
00765    if (position) {
00766       thisNode  = position->GetNode();
00767       position->UpdatePosition(option);
00768    }
00769 
00770    // if (option[0] !='r' ) printf(" Level %d first = %d  iLast %d \n",level, iFirst, iLast);
00771    if (level >= iFirst) {
00772       PaintShape(option);
00773       if (thisNode)  thisNode->PaintShape(option);
00774    }
00775 ////---   if ( thisNode->TestBit(kSonsInvisible) ) return;
00776 
00777 //*-*- Paint all sons
00778    TSeqCollection *nodes =  GetCollection();
00779    Int_t nsons = nodes?nodes->GetSize():0;
00780 
00781    if(!nsons) return;
00782 
00783    gGeometry->PushLevel();
00784    TVolumeView *node;
00785    TIter  next(nodes);
00786    while ((node = (TVolumeView *)next())) {
00787       if (view3D)  view3D->PushMatrix();
00788 
00789       node->Paint(option);
00790 
00791       if (view3D)  view3D->PopMatrix();
00792    }
00793    gGeometry->PopLevel();
00794 }
00795 
00796 //______________________________________________________________________________
00797 void TVolumeView::PaintShape(Option_t *option)
00798 {
00799    // Paint shape of the node
00800    // To be called from the TObject::Paint method only
00801    Bool_t rangeView = option && option[0]=='r';
00802 
00803    TIter nextShape(fListOfShapes);
00804    TShape *shape = 0;
00805    while( (shape = (TShape *)nextShape()) ) {
00806       if (!shape->GetVisibility())   continue;
00807       if (!rangeView) {
00808          TTablePadView3D *view3D = (TTablePadView3D*)gPad->GetView3D();
00809          if (view3D)
00810             view3D->SetLineAttr(shape->GetLineColor(),shape->GetLineWidth(),option);
00811       }
00812 #if ROOT_VERSION_CODE >= ROOT_VERSION(4,03,05)
00813       // It MUST be the TShape::PAint method:
00814       Bool_t viewerWantsSons = kTRUE;
00815       TVirtualViewer3D * viewer3D = gPad->GetViewer3D();
00816       if (viewer3D) {
00817          // We only provide master frame positions in these shapes
00818          // so don't ask viewer preference
00819 
00820          // Ask all shapes for kCore/kBoundingBox/kShapeSpecific
00821          // Not all will support the last two - which is fine
00822          const TBuffer3D & buffer =
00823             shape->GetBuffer3D(TBuffer3D::kCore|TBuffer3D::kBoundingBox|TBuffer3D::kShapeSpecific);
00824 
00825          // TShape sets buffer id based on TNode * gNode
00826          // As we not using TNode we need to override this
00827          const_cast<TBuffer3D &>(buffer).fID = this;
00828 
00829          Int_t reqSections = viewer3D->AddObject(buffer, &viewerWantsSons);
00830          if (reqSections != TBuffer3D::kNone) {
00831             shape->GetBuffer3D(reqSections);
00832             viewer3D->AddObject(buffer);
00833          }
00834       }
00835 #else
00836       shape->Paint(option);
00837 #endif
00838    }
00839 }
00840 
00841 //______________________________________________________________________________
00842 TString TVolumeView::PathP() const
00843 {
00844    // return the full path of this data set
00845    TString str;
00846    TVolumeView *parent = (TVolumeView *)GetParent();
00847    if (parent) {
00848       str = parent->PathP();
00849       str += "/";
00850    }
00851    str +=  GetName();
00852    UInt_t positionId = 0;
00853    TVolumePosition *p = GetPosition();
00854    if (p) {
00855       char buffer[10];
00856       positionId = p->GetId();
00857       snprintf(buffer,10,";%d",p->GetId());
00858       str +=  buffer;
00859    }
00860    return str;
00861 }
00862 
00863 //_______________________________________________________________________
00864 void TVolumeView::SavePrimitive(ostream &out, Option_t * /*= ""*/)
00865 {
00866    //to be documented
00867    const Char_t *sceleton[] = {
00868       "TVolumeView *CreateNodeView(TVolume *topNode) {"
00869      ,"  TString     thisNodePath   = "
00870      ,"  UInt_t      thisPositionId = "
00871      ,"  Double_t thisTranslate[3]  = "
00872      ," "
00873      ,"  TString        matrixName  = "
00874      ,"  Int_t          matrixType  = "
00875      ,"  Double_t     thisMatrix[]  = {  "
00876      ,"                                  "
00877      ,"                                  "
00878      ,"                               };"
00879      ,"  return = new TVolumeView(thisTranslate, thisMatrix, thisPositionId, topNode,"
00880      ,"                          thisNodePath.Data(),matrixName.Data(), matrixType);"
00881      ,"}"
00882    };
00883 //------------------- end of sceleton ---------------------
00884    Int_t sceletonSize = sizeof(sceleton)/sizeof(const Char_t*);
00885    TVolumePosition *thisPosition = GetPosition();
00886    TVolume *thisFullNode = GetNode();
00887    TString thisNodePath = thisFullNode ? thisFullNode->Path() : TString("");
00888    // Define position
00889    UInt_t thisPositionId = thisPosition ? thisPosition->GetId():0;
00890    Double_t thisX  = thisPosition ? thisPosition->GetX():0;
00891    Double_t thisY  = thisPosition ? thisPosition->GetY():0;
00892    Double_t thisZ  = thisPosition ? thisPosition->GetZ():0;
00893 
00894    const TRotMatrix *matrix = thisPosition ? thisPosition->GetMatrix():0;
00895    Int_t matrixType = 2;
00896    TString matrixName = " ";
00897    Double_t thisMatrix[] = { 0,0,0, 0,0,0, 0,0,0 };
00898    if (matrix) {
00899       matrixName = matrix->GetName();
00900       memcpy(thisMatrix,((TRotMatrix *)matrix)->GetMatrix(),9*sizeof(Double_t));
00901       matrixType = matrix->GetType();
00902    }
00903    Int_t im = 0;
00904    for (Int_t lineNumber =0; lineNumber < sceletonSize; lineNumber++) {
00905       out << sceleton[lineNumber];                             // cout << lineNumber << ". " << sceleton[lineNumber];
00906       switch (lineNumber) {
00907          case  1:  out  << "\"" << thisNodePath.Data() << "\";" ; // cout  << "\"" << thisNodePath.Data() << "\";" ;
00908             break;
00909          case  2:  out   << thisPositionId << ";" ; // cout  << "\"" << thisNodePath.Data() << "\";" ;
00910             break;
00911          case  3:  out << "{" << thisX << ", " << thisY << ", "<< thisZ << "};";  // cout << thisX << ";" ;
00912             break;
00913          case  5:  out << "\"" << matrixName << "\";" ;           // cout << "\"" << matrixName << "\";" ;
00914             break;
00915          case  6:  out <<  matrixType << ";" ;                    // cout <<  matrixType << ";" ;
00916             break;
00917          case  7:  out << thisMatrix[im++] << ", "; out << thisMatrix[im++] << ", "; out << thisMatrix[im++] << ", ";
00918             break;
00919          case  8:  out << thisMatrix[im++] << ", "; out << thisMatrix[im++] << ", "; out << thisMatrix[im++] << ", ";
00920             break;
00921          case  9:  out << thisMatrix[im++] << ", "; out << thisMatrix[im++] << ", "; out << thisMatrix[im++];
00922             break;
00923          default:
00924             break;
00925       };
00926 //   cout << " " << endl;
00927       out << " " << endl;
00928    }
00929 }
00930 
00931 //______________________________________________________________________________
00932 void  TVolumeView::SetLineAttributes()
00933 {
00934    //to be documented
00935    TVolume *thisNode = GetNode();
00936    if (thisNode) thisNode->SetLineAttributes();
00937 }
00938 
00939 //______________________________________________________________________________
00940 void TVolumeView::SetVisibility(Int_t vis)
00941 {
00942    //to be documented
00943    TVolume *node = GetNode();
00944    if (node) node->SetVisibility(TVolume::ENodeSEEN(vis));
00945 }
00946 
00947 //______________________________________________________________________________
00948 void TVolumeView::Sizeof3D() const
00949 {
00950 //*-*-*-*-*-*-*Return total size of this 3-D Node with its attributes*-*-*
00951 //*-*          ==========================================================
00952 
00953    if (GetListOfShapes()) {
00954       TIter nextShape(GetListOfShapes());
00955       TShape *shape = 0;
00956       while( (shape = (TShape *)nextShape()) ) {
00957          if (shape->GetVisibility())  shape->Sizeof3D();
00958       }
00959    }
00960 
00961    TVolume *thisNode  = GetNode();
00962    if (thisNode && !(thisNode->GetVisibility()&TVolume::kThisUnvisible) ) {
00963       TIter nextShape(thisNode->GetListOfShapes());
00964       TShape *shape = 0;
00965       while( (shape = (TShape *)nextShape()) ) {
00966          if (shape->GetVisibility())  shape->Sizeof3D();
00967       }
00968    }
00969 
00970 //   if ( TestBit(kSonsInvisible) ) return;
00971 
00972    TVolumeView *node;
00973    TDataSetIter next((TVolumeView *)this);
00974    while ((node = (TVolumeView *)next())) node->Sizeof3D();
00975 }

Generated on Tue Jul 5 14:45:10 2011 for ROOT_528-00b_version by  doxygen 1.5.1