TEveGeoShape.cxx

Go to the documentation of this file.
00001 // @(#)root/eve:$Id: TEveGeoShape.cxx 37192 2010-12-02 15:54:26Z matevz $
00002 // Author: Matevz Tadel 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 "TEveGeoShape.h"
00013 #include "TEveTrans.h"
00014 #include "TEveManager.h"
00015 #include "TEvePolygonSetProjected.h"
00016 #include "TEveProjections.h"
00017 #include "TEveProjectionManager.h"
00018 
00019 #include "TEveGeoShapeExtract.h"
00020 #include "TEveGeoPolyShape.h"
00021 
00022 #include "TROOT.h"
00023 #include "TBuffer3D.h"
00024 #include "TBuffer3DTypes.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 "TGeoBoolNode.h"
00035 #include "TGeoManager.h"
00036 #include "TGeoMatrix.h"
00037 #include "TVirtualGeoPainter.h"
00038 
00039 namespace
00040 {
00041    TGeoManager* init_geo_mangeur()
00042    {
00043       // Create a phony geo manager that can be used for storing free
00044       // shapes. Otherwise shapes register themselves to current
00045       // geo-manager (or even create one).
00046 
00047       TGeoManager  *old    = gGeoManager;
00048       TGeoIdentity *old_id = gGeoIdentity;
00049       gGeoManager = 0;
00050       TGeoManager* mgr = new TGeoManager();
00051       mgr->SetNameTitle("TEveGeoShape::fgGeoMangeur",
00052                         "Static geo manager used for wrapped TGeoShapes.");
00053       gGeoIdentity = new TGeoIdentity("Identity");
00054       gGeoManager  = old;
00055       gGeoIdentity = old_id;
00056       return mgr;
00057    }
00058 }
00059 
00060 //==============================================================================
00061 //==============================================================================
00062 // TEveGeoShape
00063 //==============================================================================
00064 
00065 //______________________________________________________________________________
00066 //
00067 // Wrapper for TGeoShape with absolute positioning and color
00068 // attributes allowing display of extracted TGeoShape's (without an
00069 // active TGeoManager) and simplified geometries (needed for non-linear
00070 // projections).
00071 //
00072 // TGeoCompositeShapes and TGeoAssemblies are supported.
00073 //
00074 // If fNSegments data-member is < 2 (0 by default), the default number of
00075 // segments is used for tesselation and special GL objects are
00076 // instantiated for selected shapes (spheres, tubes). If fNSegments is > 2,
00077 // it gets forwarded to geo-manager and this tesselation detail is
00078 // used when creating the buffer passed to GL.
00079 
00080 ClassImp(TEveGeoShape);
00081 
00082 TGeoManager* TEveGeoShape::fgGeoMangeur = init_geo_mangeur();
00083 
00084 //______________________________________________________________________________
00085 TGeoManager* TEveGeoShape::GetGeoMangeur()
00086 {
00087    // Return static geo-manager that is used intenally to make shapes
00088    // lead a happy life.
00089    // Set gGeoManager to this object when creating TGeoShapes to be
00090    // passed into TEveGeoShapes.
00091 
00092    return fgGeoMangeur;
00093 }
00094 
00095 //______________________________________________________________________________
00096 TEveGeoShape::TEveGeoShape(const char* name, const char* title) :
00097    TEveShape       (name, title),
00098    fNSegments      (0),
00099    fShape          (0),
00100    fCompositeShape (0)
00101 {
00102    // Constructor.
00103 
00104    InitMainTrans();
00105 }
00106 
00107 //______________________________________________________________________________
00108 TEveGeoShape::~TEveGeoShape()
00109 {
00110    // Destructor.
00111 
00112    SetShape(0);
00113 }
00114 
00115 //______________________________________________________________________________
00116 TGeoShape* TEveGeoShape::MakePolyShape()
00117 {
00118    // Create derived TEveGeoShape form a TGeoCompositeShape.
00119 
00120    return TEveGeoPolyShape::Construct(fCompositeShape, fNSegments);
00121 }
00122 
00123 //______________________________________________________________________________
00124 void TEveGeoShape::SetNSegments(Int_t s)
00125 {
00126    // Set number of segments.
00127 
00128    if (s != fNSegments && fCompositeShape != 0)
00129    {
00130       delete fShape;
00131       fShape = MakePolyShape();
00132    }
00133    fNSegments = s;
00134 }
00135 
00136 //______________________________________________________________________________
00137 void TEveGeoShape::SetShape(TGeoShape* s)
00138 {
00139    // Set TGeoShape shown by this object.
00140    //
00141    // The shape is owned by TEveGeoShape but TGeoShape::fUniqueID is
00142    // used for reference counting so you can pass the same shape to
00143    // several TEveGeoShapes.
00144    //
00145    // If it if is taken from an existing TGeoManager, manually
00146    // increase the fUniqueID before passing it to TEveGeoShape.
00147 
00148    TEveGeoManagerHolder gmgr(fgGeoMangeur);
00149 
00150    if (fCompositeShape)
00151    {
00152       delete fShape;
00153       fShape = fCompositeShape;
00154    }
00155    if (fShape)
00156    {
00157       fShape->SetUniqueID(fShape->GetUniqueID() - 1);
00158       if (fShape->GetUniqueID() == 0)
00159       {
00160          delete fShape;
00161       }
00162    }
00163    fShape = s;
00164    if (fShape)
00165    {
00166       fShape->SetUniqueID(fShape->GetUniqueID() + 1);
00167       fCompositeShape = dynamic_cast<TGeoCompositeShape*>(fShape);
00168       if (fCompositeShape)
00169       {
00170          fShape = MakePolyShape();
00171       }
00172    }
00173 }
00174 
00175 /******************************************************************************/
00176 
00177 //______________________________________________________________________________
00178 void TEveGeoShape::ComputeBBox()
00179 {
00180    // Compute bounding-box.
00181 
00182    TGeoBBox *bb = dynamic_cast<TGeoBBox*>(fShape);
00183    if (bb)
00184    {
00185       BBoxInit();
00186       const Double_t *o = bb->GetOrigin();
00187       BBoxCheckPoint(o[0] - bb->GetDX(), o[0] - bb->GetDY(), o[0] - bb->GetDZ());
00188       BBoxCheckPoint(o[0] + bb->GetDX(), o[0] + bb->GetDY(), o[0] + bb->GetDZ());
00189    }
00190    else
00191    {
00192       BBoxZero();
00193    }
00194 }
00195 
00196 //______________________________________________________________________________
00197 void TEveGeoShape::Paint(Option_t* /*option*/)
00198 {
00199    // Paint object.
00200 
00201    static const TEveException eh("TEveGeoShape::Paint ");
00202 
00203    if (fShape == 0)
00204       return;
00205 
00206    TEveGeoManagerHolder gmgr(fgGeoMangeur, fNSegments);
00207 
00208    if (fCompositeShape)
00209    {
00210       Double_t halfLengths[3] = { fCompositeShape->GetDX(), fCompositeShape->GetDY(), fCompositeShape->GetDZ() };
00211 
00212       TBuffer3D buff(TBuffer3DTypes::kComposite);
00213       buff.fID           = this;
00214       buff.fColor        = GetMainColor();
00215       buff.fTransparency = GetMainTransparency();
00216       RefMainTrans().SetBuffer3D(buff);
00217       buff.fLocalFrame   = kTRUE; // Always enforce local frame (no geo manager).
00218       buff.SetAABoundingBox(fCompositeShape->GetOrigin(), halfLengths);
00219       buff.SetSectionsValid(TBuffer3D::kCore|TBuffer3D::kBoundingBox);
00220 
00221       Bool_t paintComponents = kTRUE;
00222 
00223       // Start a composite shape, identified by this buffer
00224       if (TBuffer3D::GetCSLevel() == 0)
00225          paintComponents = gPad->GetViewer3D()->OpenComposite(buff);
00226 
00227       TBuffer3D::IncCSLevel();
00228 
00229       // Paint the boolean node - will add more buffers to viewer
00230       TGeoHMatrix xxx;
00231       TGeoMatrix *gst = TGeoShape::GetTransform();
00232       TGeoShape::SetTransform(&xxx);
00233       if (paintComponents) fCompositeShape->GetBoolNode()->Paint("");
00234       TGeoShape::SetTransform(gst);
00235       // Close the composite shape
00236       if (TBuffer3D::DecCSLevel() == 0)
00237          gPad->GetViewer3D()->CloseComposite();
00238    }
00239    else
00240    {
00241       TBuffer3D& buff = (TBuffer3D&) fShape->GetBuffer3D
00242          (TBuffer3D::kCore, kFALSE);
00243 
00244       buff.fID           = this;
00245       buff.fColor        = GetMainColor();
00246       buff.fTransparency = GetMainTransparency();
00247       RefMainTrans().SetBuffer3D(buff);
00248       buff.fLocalFrame   = kTRUE; // Always enforce local frame (no geo manager).
00249 
00250       Int_t sections = TBuffer3D::kBoundingBox | TBuffer3D::kShapeSpecific;
00251       if (fNSegments > 2)
00252          sections |= TBuffer3D::kRawSizes | TBuffer3D::kRaw;
00253       fShape->GetBuffer3D(sections, kTRUE);
00254 
00255       Int_t reqSec = gPad->GetViewer3D()->AddObject(buff);
00256 
00257       if (reqSec != TBuffer3D::kNone) {
00258          // This shouldn't happen, but I suspect it does sometimes.
00259          if (reqSec & TBuffer3D::kCore)
00260             Warning(eh, "Core section required again for shape='%s'. This shouldn't happen.", GetName());
00261          fShape->GetBuffer3D(reqSec, kTRUE);
00262          reqSec = gPad->GetViewer3D()->AddObject(buff);
00263       }
00264 
00265       if (reqSec != TBuffer3D::kNone)
00266          Warning(eh, "Extra section required: reqSec=%d, shape=%s.", reqSec, GetName());
00267    }
00268 }
00269 
00270 //==============================================================================
00271 
00272 //______________________________________________________________________________
00273 void TEveGeoShape::Save(const char* file, const char* name)
00274 {
00275    // Save the shape tree as TEveGeoShapeExtract.
00276    // File is always recreated.
00277    // This function is obsolete, use SaveExtractInstead().
00278 
00279    Warning("Save()", "This function is deprecated, use SaveExtract() instead.");
00280    SaveExtract(file, name);
00281 }
00282 
00283 //______________________________________________________________________________
00284 void TEveGeoShape::SaveExtract(const char* file, const char* name)
00285 {
00286    // Save the shape tree as TEveGeoShapeExtract.
00287    // File is always recreated.
00288 
00289    TEveGeoShapeExtract* gse = DumpShapeTree(this, 0);
00290 
00291    TFile f(file, "RECREATE");
00292    gse->Write(name);
00293    f.Close();
00294 }
00295 
00296 //______________________________________________________________________________
00297 void TEveGeoShape::WriteExtract(const char* name)
00298 {
00299    // Write the shape tree as TEveGeoShapeExtract to current directory.
00300 
00301    TEveGeoShapeExtract* gse = DumpShapeTree(this, 0);
00302    gse->Write(name);
00303 }
00304 
00305 /******************************************************************************/
00306 
00307 //______________________________________________________________________________
00308 TEveGeoShapeExtract* TEveGeoShape::DumpShapeTree(TEveGeoShape* gsre,
00309                                                  TEveGeoShapeExtract* parent)
00310 {
00311    // Export this shape and its descendants into a geoshape-extract.
00312 
00313    TEveGeoShapeExtract* she = new TEveGeoShapeExtract(gsre->GetName(), gsre->GetTitle());
00314    she->SetTrans(gsre->RefMainTrans().Array());
00315    {
00316       Int_t   ci = gsre->GetFillColor();
00317       TColor *c  = gROOT->GetColor(ci);
00318       Float_t rgba[4] = { 1, 0, 0, 1 - gsre->GetMainTransparency()/100. };
00319       if (c)
00320       {
00321          rgba[0] = c->GetRed();
00322          rgba[1] = c->GetGreen();
00323          rgba[2] = c->GetBlue();
00324       }
00325       she->SetRGBA(rgba);
00326    }
00327    {
00328       Int_t   ci = gsre->GetLineColor();
00329       TColor *c  = gROOT->GetColor(ci);
00330       Float_t rgba[4] = { 1, 0, 0, 1 };
00331       if (c)
00332       {
00333          rgba[0] = c->GetRed();
00334          rgba[1] = c->GetGreen();
00335          rgba[2] = c->GetBlue();
00336       }
00337       she->SetRGBALine(rgba);
00338    }
00339    she->SetRnrSelf(gsre->GetRnrSelf());
00340    she->SetRnrElements(gsre->GetRnrChildren());
00341    she->SetRnrFrame(gsre->GetDrawFrame());
00342    she->SetMiniFrame(gsre->GetMiniFrame());
00343    she->SetShape(gsre->GetShape());
00344    if (gsre->HasChildren())
00345    {
00346       TList* ele = new TList();
00347       she->SetElements(ele);
00348       she->GetElements()->SetOwner(true);
00349       TEveElement::List_i i = gsre->BeginChildren();
00350       while (i != gsre->EndChildren()) {
00351          TEveGeoShape* l = dynamic_cast<TEveGeoShape*>(*i);
00352          DumpShapeTree(l, she);
00353          i++;
00354       }
00355    }
00356    if (parent)
00357       parent->GetElements()->Add(she);
00358 
00359    return she;
00360 }
00361 
00362 //______________________________________________________________________________
00363 TEveGeoShape* TEveGeoShape::ImportShapeExtract(TEveGeoShapeExtract* gse,
00364                                                TEveElement*         parent)
00365 {
00366    // Import a shape extract 'gse' under element 'parent'.
00367 
00368    TEveGeoManagerHolder gmgr(fgGeoMangeur);
00369    TEveManager::TRedrawDisabler redrawOff(gEve);
00370    TEveGeoShape* gsre = SubImportShapeExtract(gse, parent);
00371    gsre->ElementChanged();
00372    return gsre;
00373 }
00374 
00375 
00376 //______________________________________________________________________________
00377 TEveGeoShape* TEveGeoShape::SubImportShapeExtract(TEveGeoShapeExtract* gse,
00378                                                   TEveElement*         parent)
00379 {
00380    // Recursive version for importing a shape extract tree.
00381 
00382    TEveGeoShape* gsre = new TEveGeoShape(gse->GetName(), gse->GetTitle());
00383    gsre->RefMainTrans().SetFromArray(gse->GetTrans());
00384    const Float_t* rgba = gse->GetRGBA();
00385    gsre->SetMainColorRGB(rgba[0], rgba[1], rgba[2]);
00386    gsre->SetMainAlpha(rgba[3]);
00387    rgba = gse->GetRGBALine();
00388    gsre->SetLineColor(TColor::GetColor(rgba[0], rgba[1], rgba[2]));
00389    gsre->SetRnrSelf(gse->GetRnrSelf());
00390    gsre->SetRnrChildren(gse->GetRnrElements());
00391    gsre->SetDrawFrame(gse->GetRnrFrame());
00392    gsre->SetMiniFrame(gse->GetMiniFrame());
00393    gsre->SetShape(gse->GetShape());
00394 
00395    if (parent)
00396       parent->AddElement(gsre);
00397 
00398    if (gse->HasElements())
00399    {
00400       TIter next(gse->GetElements());
00401       TEveGeoShapeExtract* chld;
00402       while ((chld = (TEveGeoShapeExtract*) next()) != 0)
00403          SubImportShapeExtract(chld, gsre);
00404    }
00405 
00406    return gsre;
00407 }
00408 
00409 /******************************************************************************/
00410 
00411 //______________________________________________________________________________
00412 TClass* TEveGeoShape::ProjectedClass(const TEveProjection* p) const
00413 {
00414    // Return class for projected objects:
00415    //  - 2D projections: TEvePolygonSetProjected,
00416    //  - 3D projections: TEveGeoShapeProjected.
00417    // Virtual from TEveProjectable.
00418 
00419    if (p->Is2D())
00420       return TEvePolygonSetProjected::Class();
00421    else
00422       return TEveGeoShapeProjected::Class();
00423 }
00424 
00425 /******************************************************************************/
00426 
00427 //______________________________________________________________________________
00428 TBuffer3D* TEveGeoShape::MakeBuffer3D()
00429 {
00430    // Create a TBuffer3D suitable for presentation of the shape.
00431    // Transformation matrix is also applied.
00432 
00433    if (fShape == 0) return 0;
00434 
00435    if (dynamic_cast<TGeoShapeAssembly*>(fShape)) {
00436       // TGeoShapeAssembly makes a bad TBuffer3D.
00437       return 0;
00438    }
00439 
00440    TEveGeoManagerHolder gmgr(fgGeoMangeur, fNSegments);
00441 
00442    TBuffer3D* buff  = fShape->MakeBuffer3D();
00443    TEveTrans& mx    = RefMainTrans();
00444    if (mx.GetUseTrans())
00445    {
00446       Int_t n = buff->NbPnts();
00447       Double_t* pnts = buff->fPnts;
00448       for(Int_t k = 0; k < n; ++k)
00449       {
00450          mx.MultiplyIP(&pnts[3*k]);
00451       }
00452    }
00453    return buff;
00454 }
00455 
00456 
00457 //==============================================================================
00458 //==============================================================================
00459 // TEveGeoShapeProjected
00460 //==============================================================================
00461 
00462 //______________________________________________________________________________
00463 //
00464 // A 3D projected TEveGeoShape.
00465 
00466 ClassImp(TEveGeoShapeProjected);
00467 
00468 //______________________________________________________________________________
00469 TEveGeoShapeProjected::TEveGeoShapeProjected() :
00470    TEveShape("TEveGeoShapeProjected"),
00471    fBuff(0)
00472 {
00473    // Constructor.
00474 }
00475 
00476 //______________________________________________________________________________
00477 void TEveGeoShapeProjected::SetDepthLocal(Float_t /*d*/)
00478 {
00479    // This should never be called as this class is only used for 3D
00480    // projections.
00481    // The implementation is required as this metod is abstract.
00482    // Just emits a warning if called.
00483 
00484    Warning("SetDepthLocal", "This function only exists to fulfill an abstract interface.");
00485 }
00486 
00487 //______________________________________________________________________________
00488 void TEveGeoShapeProjected::SetProjection(TEveProjectionManager* mng,
00489                                           TEveProjectable* model)
00490 {
00491    // This is virtual method from base-class TEveProjected.
00492 
00493    TEveProjected::SetProjection(mng, model);
00494 
00495    TEveGeoShape* gre = dynamic_cast<TEveGeoShape*>(fProjectable);
00496    CopyVizParams(gre);
00497 }
00498 
00499 //______________________________________________________________________________
00500 void TEveGeoShapeProjected::UpdateProjection()
00501 {
00502    // This is virtual method from base-class TEveProjected.
00503 
00504    TEveGeoShape   *gre = dynamic_cast<TEveGeoShape*>(fProjectable);
00505    TEveProjection *prj = fManager->GetProjection();
00506 
00507    delete fBuff;
00508    fBuff = gre->MakeBuffer3D();
00509 
00510    if (fBuff)
00511    {
00512       fBuff->SetSectionsValid(TBuffer3D::kCore | TBuffer3D::kRawSizes | TBuffer3D::kRaw);
00513 
00514       Double_t *p = fBuff->fPnts;
00515       for (UInt_t i = 0; i < fBuff->NbPnts(); ++i, p+=3)
00516       {
00517          prj->ProjectPointdv(p, 0);
00518       }
00519    }
00520 
00521    ResetBBox();
00522 }
00523 
00524 //______________________________________________________________________________
00525 void TEveGeoShapeProjected::ComputeBBox()
00526 {
00527    // Override of virtual method from TAttBBox.
00528 
00529    if (fBuff && fBuff->NbPnts() > 0)
00530    {
00531       BBoxInit();
00532 
00533       Double_t *p = fBuff->fPnts;
00534       for (UInt_t i = 0; i < fBuff->NbPnts(); ++i, p+=3)
00535       {
00536          BBoxCheckPoint(p[0], p[1], p[2]);
00537       }
00538    }
00539    else
00540    {
00541       BBoxZero();
00542    }
00543 }

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