TEveGeoNode.cxx

Go to the documentation of this file.
00001 // @(#)root/eve:$Id: TEveGeoNode.cxx 36892 2010-11-24 10:24:35Z matevz $
00002 // Authors: Matevz Tadel & Alja Mrak-Tadel: 2006, 2007
00003 
00004 /*************************************************************************
00005  * Copyright (C) 1995-2007, 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 #include "TEveGeoNode.h"
00013 #include "TEveTrans.h"
00014 #include "TEveManager.h"
00015 #include "TEvePolygonSetProjected.h"
00016 
00017 #include "TEveGeoShapeExtract.h"
00018 #include "TEvePad.h"
00019 #include "TEveGeoPolyShape.h"
00020 #include "TGLScenePad.h"
00021 #include "TGLFaceSet.h"
00022 
00023 #include "TROOT.h"
00024 #include "TBuffer3D.h"
00025 #include "TVirtualViewer3D.h"
00026 #include "TColor.h"
00027 #include "TFile.h"
00028 
00029 #include "TGeoShape.h"
00030 #include "TGeoVolume.h"
00031 #include "TGeoNode.h"
00032 #include "TGeoShapeAssembly.h"
00033 #include "TGeoCompositeShape.h"
00034 #include "TGeoManager.h"
00035 #include "TGeoMatrix.h"
00036 #include "TVirtualGeoPainter.h"
00037 
00038 //==============================================================================
00039 //==============================================================================
00040 // TEveGeoNode
00041 //==============================================================================
00042 
00043 //______________________________________________________________________________
00044 //
00045 // Wrapper for TGeoNode that allows it to be shown in GUI and controlled as a TEveElement.
00046 
00047 ClassImp(TEveGeoNode);
00048 
00049 Int_t                 TEveGeoNode::fgCSGExportNSeg = 64;
00050 std::list<TGeoShape*> TEveGeoNode::fgTemporaryStore;
00051 
00052 //______________________________________________________________________________
00053 Int_t TEveGeoNode::GetCSGExportNSeg()
00054 {
00055    // Returns number of segments used for CSG export.
00056 
00057    return fgCSGExportNSeg;
00058 }
00059 
00060 //______________________________________________________________________________
00061 void TEveGeoNode::SetCSGExportNSeg(Int_t nseg)
00062 {
00063    // Sets number of segments used for CSG export.
00064 
00065    fgCSGExportNSeg = nseg;
00066 }
00067 
00068 //______________________________________________________________________________
00069 TEveGeoNode::TEveGeoNode(TGeoNode* node) :
00070    TEveElement(),
00071    TObject(),
00072    fNode(node)
00073 {
00074    // Constructor.
00075 
00076    // Hack!! Should use cint to retrieve TAttLine::fLineColor offset.
00077    char* l = (char*) dynamic_cast<TAttLine*>(node->GetVolume());
00078    SetMainColorPtr((Color_t*)(l + sizeof(void*)));
00079    SetMainTransparency(fNode->GetVolume()->GetTransparency());
00080 
00081    SetRnrSelfChildren(fNode->IsVisible(), fNode->IsVisDaughters());
00082 }
00083 
00084 //______________________________________________________________________________
00085 const char* TEveGeoNode::GetName()  const
00086 {
00087    // Return name, taken from geo-node. Used via TObject.
00088 
00089    return fNode->GetName();
00090 }
00091 
00092 //______________________________________________________________________________
00093 const char* TEveGeoNode::GetTitle() const
00094 {
00095    // Return title, taken from geo-node. Used via TObject.
00096 
00097    return fNode->GetTitle();
00098 }
00099 
00100 //______________________________________________________________________________
00101 const char* TEveGeoNode::GetElementName()  const
00102 {
00103    // Return name, taken from geo-node. Used via TEveElement.
00104 
00105    return fNode->GetName();
00106 }
00107 
00108 //______________________________________________________________________________
00109 const char* TEveGeoNode::GetElementTitle() const
00110 {
00111    // Return title, taken from geo-node. Used via TEveElement.
00112 
00113    return fNode->GetTitle();
00114 }
00115 
00116 /******************************************************************************/
00117 
00118 //______________________________________________________________________________
00119 void TEveGeoNode::ExpandIntoListTree(TGListTree* ltree,
00120                                      TGListTreeItem* parent)
00121 {
00122    // Checks if child-nodes have been imported ... imports them if not.
00123    // Then calls TEveElement::ExpandIntoListTree.
00124 
00125    if ( ! HasChildren() && fNode->GetVolume()->GetNdaughters() > 0)
00126    {
00127       TIter next(fNode->GetVolume()->GetNodes());
00128       TGeoNode* dnode;
00129       while ((dnode = (TGeoNode*) next()) != 0)
00130       {
00131          TEveGeoNode* node_re = new TEveGeoNode(dnode);
00132          AddElement(node_re);
00133       }
00134    }
00135    TEveElement::ExpandIntoListTree(ltree, parent);
00136 }
00137 
00138 //______________________________________________________________________________
00139 void TEveGeoNode::ExpandIntoListTrees()
00140 {
00141    // Expand children into all list-trees.
00142 
00143    for (sLTI_i i = fItems.begin(); i != fItems.end(); ++i)
00144    {
00145       ExpandIntoListTree(i->fTree, i->fItem);
00146    }
00147 }
00148 
00149 //______________________________________________________________________________
00150 void TEveGeoNode::ExpandIntoListTreesRecursively()
00151 {
00152    // Expand children into all list-trees recursively.
00153    // This is useful if one wants to export extracted shapes.
00154 
00155    ExpandIntoListTrees();
00156    for (List_i i=fChildren.begin(); i!=fChildren.end(); ++i)
00157    {
00158       TEveGeoNode *egn = dynamic_cast<TEveGeoNode*>(*i);
00159       if (egn)
00160          egn->ExpandIntoListTreesRecursively();
00161    }
00162 }
00163 
00164 /******************************************************************************/
00165 
00166 //______________________________________________________________________________
00167 void TEveGeoNode::AddStamp(UChar_t bits)
00168 {
00169    // Override from TEveElement.
00170    // Process visibility changes and forward them to fNode.
00171 
00172    TEveElement::AddStamp(bits);
00173    if (bits & kCBVisibility)
00174    {
00175       fNode->SetVisibility(fRnrSelf);
00176       fNode->VisibleDaughters(fRnrChildren);
00177    }
00178 }
00179 
00180 /******************************************************************************/
00181 
00182 //______________________________________________________________________________
00183 Bool_t TEveGeoNode::CanEditMainColor() const
00184 {
00185    // Can edit main-color -- not available for assemblies.
00186 
00187    return ! fNode->GetVolume()->IsAssembly();
00188 }
00189 
00190 //______________________________________________________________________________
00191 void TEveGeoNode::SetMainColor(Color_t color)
00192 {
00193    // Set color, propagate to volume's line color.
00194 
00195    TEveElement::SetMainColor(color);
00196    fNode->GetVolume()->SetLineColor(color);
00197 }
00198 
00199 //______________________________________________________________________________
00200 Bool_t TEveGeoNode::CanEditMainTransparency() const
00201 {
00202    // Can edit main transparency -- not available for assemblies.
00203 
00204    return ! fNode->GetVolume()->IsAssembly();
00205 }
00206 
00207 //______________________________________________________________________________
00208 Char_t TEveGeoNode::GetMainTransparency() const
00209 {
00210    // Get transparency -- it is taken from the geo node.
00211 
00212    return fNode->GetVolume()->GetTransparency();
00213 }
00214 
00215 //______________________________________________________________________________
00216 void TEveGeoNode::SetMainTransparency(Char_t t)
00217 {
00218    // Set transparency, propagate to volume's transparency.
00219 
00220    TEveElement::SetMainTransparency(t);
00221    fNode->GetVolume()->SetTransparency(t);
00222 }
00223 
00224 /******************************************************************************/
00225 
00226 //______________________________________________________________________________
00227 void TEveGeoNode::UpdateNode(TGeoNode* node)
00228 {
00229    // Updates all reve-browsers having the node in their contents.
00230    // All 3D-pads updated if any change found.
00231    //
00232    // Should (could?) be optimized with some assumptions about
00233    // volume/node structure (search for parent, know the same node can not
00234    // reoccur on lower level once found).
00235 
00236    static const TEveException eH("TEveGeoNode::UpdateNode ");
00237 
00238    // printf("%s node %s %p\n", eH.Data(), node->GetName(), node);
00239 
00240    if (fNode == node)
00241       StampColorSelection();
00242 
00243    for (List_i i=fChildren.begin(); i!=fChildren.end(); ++i) {
00244       ((TEveGeoNode*)(*i))->UpdateNode(node);
00245    }
00246 }
00247 
00248 //______________________________________________________________________________
00249 void TEveGeoNode::UpdateVolume(TGeoVolume* volume)
00250 {
00251    // Updates all reve-browsers having the volume in their contents.
00252    // All 3D-pads updated if any change found.
00253    //
00254    // Should (could?) be optimized with some assumptions about
00255    // volume/node structure (search for parent, know the same node can not
00256    // reoccur on lower level once found).
00257 
00258    static const TEveException eH("TEveGeoNode::UpdateVolume ");
00259 
00260    // printf("%s volume %s %p\n", eH.Data(), volume->GetName(), volume);
00261 
00262    if(fNode->GetVolume() == volume)
00263       StampColorSelection();
00264 
00265    for(List_i i=fChildren.begin(); i!=fChildren.end(); ++i) {
00266       ((TEveGeoNode*)(*i))->UpdateVolume(volume);
00267    }
00268 }
00269 
00270 /******************************************************************************/
00271 
00272 //______________________________________________________________________________
00273 void TEveGeoNode::Draw(Option_t* option)
00274 {
00275    // Draw the object.
00276 
00277    TString opt("SAME");
00278    opt += option;
00279    fNode->GetVolume()->Draw(opt);
00280 }
00281 
00282 /******************************************************************************/
00283 
00284 //______________________________________________________________________________
00285 void TEveGeoNode::Save(const char* file, const char* name, Bool_t leafs_only)
00286 {
00287    // Save TEveGeoShapeExtract tree starting at this node.
00288    // This function is obsolete, use SaveExtract() instead.
00289 
00290    Warning("Save()", "This function is deprecated, use SaveExtract() instead.");
00291    SaveExtract(file, name, leafs_only);
00292 }
00293 
00294 //______________________________________________________________________________
00295 void TEveGeoNode::SaveExtract(const char* file, const char* name, Bool_t leafs_only)
00296 {
00297    // Save the shape tree as TEveGeoShapeExtract.
00298    // File is always recreated.
00299 
00300    TEveGeoShapeExtract* gse = DumpShapeTree(this, 0, leafs_only);
00301 
00302    TFile f(file, "RECREATE");
00303    gse->Write(name);
00304    f.Close();
00305 
00306    for (std::list<TGeoShape*>::iterator i = fgTemporaryStore.begin(); i != fgTemporaryStore.end(); ++i)
00307       delete *i;
00308    fgTemporaryStore.clear();
00309 }
00310 
00311 //______________________________________________________________________________
00312 void TEveGeoNode::WriteExtract(const char* name, Bool_t leafs_only)
00313 {
00314    // Write the shape tree as TEveGeoShapeExtract to current directory.
00315 
00316    TEveGeoShapeExtract* gse = DumpShapeTree(this, 0, leafs_only);
00317    gse->Write(name);
00318 }
00319 
00320 /******************************************************************************/
00321 
00322 //______________________________________________________________________________
00323 TEveGeoShapeExtract* TEveGeoNode::DumpShapeTree(TEveGeoNode*         geon,
00324                                                 TEveGeoShapeExtract* parent,
00325                                                 Bool_t               leafs_only)
00326 {
00327    // Export the node hierarchy into tree of TEveGeoShapeExtract objects.
00328 
00329    static const TEveException eh("TEveGeoNode::DumpShapeTree ");
00330 
00331    TGeoNode*   tnode   = 0;
00332    TGeoVolume* tvolume = 0;
00333    TGeoShape*  tshape  = 0;
00334 
00335    tnode = geon->GetNode();
00336    if (tnode == 0)
00337    {
00338       Info(eh, "Null TGeoNode for TEveGeoNode '%s': assuming it's a holder and descending.", geon->GetName());
00339    }
00340    else
00341    {
00342       tvolume = tnode->GetVolume();
00343       if (tvolume == 0) {
00344          Warning(eh, "Null TGeoVolume for TEveGeoNode '%s'; skipping its sub-tree.\n", geon->GetName());
00345          return 0;
00346       }
00347       tshape  = tvolume->GetShape();
00348       if (tshape->IsComposite())
00349       {
00350          TEvePad pad;
00351          TEvePadHolder gpad(kFALSE, &pad);
00352          pad.GetListOfPrimitives()->Add(tshape);
00353          TGLScenePad scene_pad(&pad);
00354          pad.SetViewer3D(&scene_pad);
00355 
00356          {
00357             TEveGeoManagerHolder gmgr(tvolume->GetGeoManager(), fgCSGExportNSeg);
00358             gGeoManager->SetPaintVolume(tvolume);
00359 
00360             Bool_t had_null_transform = kFALSE;
00361             if (tshape->GetTransform() == 0) {
00362                had_null_transform = kTRUE;
00363                tshape->SetTransform(gGeoIdentity);
00364             }
00365 
00366             scene_pad.BeginScene();
00367             dynamic_cast<TGeoCompositeShape*>(tshape)->PaintComposite();
00368             scene_pad.EndScene();
00369 
00370             if (had_null_transform) {
00371                tshape->SetTransform(0);
00372             }
00373          }
00374 
00375          pad.SetViewer3D(0);
00376 
00377          TGLFaceSet* fs = dynamic_cast<TGLFaceSet*>(scene_pad.FindLogical(tvolume));
00378          if (!fs) {
00379             Warning(eh, "Failed extracting CSG tesselation TEveGeoNode '%s'; skipping its sub-tree.\n", geon->GetName());
00380             return 0;
00381          }
00382 
00383          TEveGeoPolyShape* egps = new TEveGeoPolyShape();
00384          egps->SetFromFaceSet(fs);
00385          tshape = egps;
00386          fgTemporaryStore.push_back(egps);
00387       }
00388    }
00389 
00390    // transformation
00391    TEveTrans trans;
00392    if (parent)
00393       trans.SetFromArray(parent->GetTrans());
00394    if (tnode)
00395    {
00396       TGeoMatrix     *gm = tnode->GetMatrix();
00397       const Double_t *rm = gm->GetRotationMatrix();
00398       const Double_t *tv = gm->GetTranslation();
00399       TEveTrans t;
00400       t(1,1) = rm[0]; t(1,2) = rm[1]; t(1,3) = rm[2];
00401       t(2,1) = rm[3]; t(2,2) = rm[4]; t(2,3) = rm[5];
00402       t(3,1) = rm[6]; t(3,2) = rm[7]; t(3,3) = rm[8];
00403       t(1,4) = tv[0]; t(2,4) = tv[1]; t(3,4) = tv[2];
00404       trans *= t;
00405    }
00406 
00407    TEveGeoShapeExtract* gse = new TEveGeoShapeExtract(geon->GetName(), geon->GetTitle());
00408    gse->SetTrans(trans.Array());
00409    Int_t  ci = 0;
00410    Char_t transp = 0;
00411    if (tvolume) {
00412       ci = tvolume->GetLineColor();
00413       transp = tvolume->GetTransparency();
00414    }
00415    TColor* c = gROOT->GetColor(ci);
00416    Float_t rgba[4] = {1, 0, 0, 1.0f - transp/100.0f};
00417    if (c) {
00418       rgba[0] = c->GetRed();
00419       rgba[1] = c->GetGreen();
00420       rgba[2] = c->GetBlue();
00421    }
00422    gse->SetRGBA(rgba);
00423    rgba[3] = 1;
00424    c = gROOT->GetColor(TColor::GetColorDark(ci));
00425    if (c) {
00426       rgba[0] = c->GetRed();
00427       rgba[1] = c->GetGreen();
00428       rgba[2] = c->GetBlue();
00429    }
00430    gse->SetRGBALine(rgba);
00431 
00432    // Keep default extract line color --> black.
00433    Bool_t rnr     = tnode ? tnode->IsVisible()      : geon->GetRnrSelf();
00434    Bool_t rnr_els = tnode ? tnode->IsVisDaughters() : geon->GetRnrChildren();
00435    if (tvolume) {
00436       rnr     = rnr     && tvolume->IsVisible();
00437       rnr_els = rnr_els && tvolume->IsVisDaughters();
00438    }
00439    gse->SetRnrSelf    (rnr);
00440    gse->SetRnrElements(rnr_els);
00441    gse->SetRnrFrame   (kTRUE);
00442    gse->SetMiniFrame  (kTRUE);
00443 
00444    gse->SetShape((leafs_only && geon->HasChildren()) ? 0 : tshape);
00445 
00446    if (geon->HasChildren())
00447    {
00448       TList* ele = new TList();
00449       gse->SetElements(ele);
00450       gse->GetElements()->SetOwner(true);
00451 
00452       TEveElement::List_i i = geon->BeginChildren();
00453       while (i != geon->EndChildren())
00454       {
00455          TEveGeoNode* l = dynamic_cast<TEveGeoNode*>(*i);
00456          DumpShapeTree(l, gse, leafs_only);
00457          ++i;
00458       }
00459    }
00460 
00461    if (parent)
00462       parent->GetElements()->Add(gse);
00463 
00464    return gse;
00465 }
00466 
00467 
00468 //==============================================================================
00469 //==============================================================================
00470 // TEveGeoTopNode
00471 //==============================================================================
00472 
00473 //______________________________________________________________________________
00474 //
00475 // A wrapper over a TGeoNode, possibly displaced with a global
00476 // trasformation stored in TEveElement.
00477 //
00478 // It holds a pointer to TGeoManager and controls for steering of
00479 // TGeoPainter, fVisOption, fVisLevel and fMaxVisNodes. They have the
00480 // same meaning as in TGeoManager/TGeoPainter.
00481 
00482 ClassImp(TEveGeoTopNode);
00483 
00484 //______________________________________________________________________________
00485 TEveGeoTopNode::TEveGeoTopNode(TGeoManager* manager, TGeoNode* node,
00486                                Int_t visopt, Int_t vislvl, Int_t maxvisnds) :
00487    TEveGeoNode  (node),
00488    fManager     (manager),
00489    fVisOption   (visopt),
00490    fVisLevel    (vislvl),
00491    fMaxVisNodes (maxvisnds)
00492 {
00493    // Constructor.
00494 
00495    InitMainTrans();
00496    fRnrSelf = kTRUE; // Override back from TEveGeoNode.
00497 }
00498 
00499 /******************************************************************************/
00500 
00501 //______________________________________________________________________________
00502 void TEveGeoTopNode::UseNodeTrans()
00503 {
00504    // Use transforamtion matrix from the TGeoNode.
00505    // Warning: this is local transformation of the node!
00506 
00507    RefMainTrans().SetFrom(*fNode->GetMatrix());
00508 }
00509 
00510 /******************************************************************************/
00511 
00512 //______________________________________________________________________________
00513 void TEveGeoTopNode::AddStamp(UChar_t bits)
00514 {
00515    // Revert from TEveGeoNode back to standard behaviour, that is,
00516    // do not pass visibility chanes to fNode as they are honoured
00517    // in Paint() method.
00518 
00519    TEveElement::AddStamp(bits);
00520 }
00521 
00522 /******************************************************************************/
00523 
00524 //______________________________________________________________________________
00525 void TEveGeoTopNode::Draw(Option_t* option)
00526 {
00527    // Draw the top-node.
00528 
00529    AppendPad(option);
00530 }
00531 
00532 //______________________________________________________________________________
00533 void TEveGeoTopNode::Paint(Option_t* option)
00534 {
00535    // Paint the enclosed TGeo hierarchy with visibility level and
00536    // option given in data-members.
00537    // Uses TGeoPainter internally.
00538 
00539    if (fRnrSelf)
00540    {
00541       TEveGeoManagerHolder geo_holder(fManager);
00542       TVirtualPad *pad = gPad;
00543       gPad = 0;
00544       TGeoVolume* top_volume = fManager->GetTopVolume();
00545       if (fVisLevel > 0)
00546          fManager->SetVisLevel(fVisLevel);
00547       else
00548          fManager->SetMaxVisNodes(fMaxVisNodes);
00549       TVirtualGeoPainter* vgp = fManager->GetGeomPainter();
00550       fManager->SetTopVolume(fNode->GetVolume());
00551       switch (fVisOption)
00552       {
00553          case 0:
00554             fNode->GetVolume()->SetVisContainers(kTRUE);
00555             fManager->SetTopVisible(kTRUE);
00556             break;
00557          case 1:
00558             fNode->GetVolume()->SetVisLeaves(kTRUE);
00559             fManager->SetTopVisible(kFALSE);
00560             break;
00561          case 2:
00562             fNode->GetVolume()->SetVisOnly(kTRUE);
00563             break;
00564       }
00565       gPad = pad;
00566       if(vgp != 0) {
00567          vgp->SetVisOption(fVisOption);
00568          TGeoHMatrix geomat;
00569          if (HasMainTrans()) RefMainTrans().SetGeoHMatrix(geomat);
00570          vgp->PaintNode(fNode, option, &geomat);
00571       }
00572       fManager->SetTopVolume(top_volume);
00573    }
00574 }
00575 
00576 /******************************************************************************/
00577 
00578 //______________________________________________________________________________
00579 void TEveGeoTopNode::VolumeVisChanged(TGeoVolume* volume)
00580 {
00581    // Callback for propagating volume visibility changes.
00582 
00583    static const TEveException eh("TEveGeoTopNode::VolumeVisChanged ");
00584    printf("%s volume %s %p\n", eh.Data(), volume->GetName(), (void*)volume);
00585    UpdateVolume(volume);
00586 }
00587 
00588 //______________________________________________________________________________
00589 void TEveGeoTopNode::VolumeColChanged(TGeoVolume* volume)
00590 {
00591    // Callback for propagating volume parameter changes.
00592 
00593    static const TEveException eh("TEveGeoTopNode::VolumeColChanged ");
00594    printf("%s volume %s %p\n", eh.Data(), volume->GetName(), (void*)volume);
00595    UpdateVolume(volume);
00596 }
00597 
00598 //______________________________________________________________________________
00599 void TEveGeoTopNode::NodeVisChanged(TGeoNode* node)
00600 {
00601    // Callback for propagating node visibility changes.
00602 
00603    static const TEveException eh("TEveGeoTopNode::NodeVisChanged ");
00604    printf("%s node %s %p\n", eh.Data(), node->GetName(), (void*)node);
00605    UpdateNode(node);
00606 }

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