CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_5_3_14/src/Fireworks/Core/src/FWGeoTopNode.cc

Go to the documentation of this file.
00001 // -*- C++ -*-
00002 //
00003 // Package:     Core
00004 // Class  :     FWGeoTopNode
00005 // 
00006 // Implementation:
00007 //     [Notes on implementation]
00008 //
00009 // Original Author:  Matevz Tadel, Alja Mrak Tadel  
00010 //         Created:  Thu Jun 23 01:24:51 CEST 2011
00011 // $Id: FWGeoTopNode.cc,v 1.25 2012/05/08 02:32:50 amraktad Exp $
00012 //
00013 
00014 // system include files
00015 
00016 // user include files
00017 
00018 #include "TEveTrans.h"
00019 #include "TEveViewer.h"
00020 #include "TEveManager.h"
00021 #include "TEveUtil.h"
00022 
00023 
00024 #include "TROOT.h"
00025 #include "TBuffer3D.h"
00026 #include "TBuffer3DTypes.h"
00027 #include "TVirtualViewer3D.h"
00028 #include "TColor.h"
00029 #include "TGLScenePad.h"
00030 #include "TGLPhysicalShape.h"
00031 #include "TGLSelectRecord.h"
00032 #include "TGLViewer.h"
00033 #include "TGLWidget.h"
00034 
00035 #include "TGeoShape.h"
00036 #include "TGeoVolume.h"
00037 #include "TGeoNode.h"
00038 #include "TGeoShapeAssembly.h"
00039 #include "TGeoCompositeShape.h"
00040 #include "TGeoBoolNode.h"
00041 #include "TGeoManager.h"
00042 #include "TGeoMatrix.h"
00043 #include "TVirtualGeoPainter.h"
00044 
00045 #include "Fireworks/Core/interface/FWGeoTopNode.h"
00046 #include "Fireworks/Core/src/FWGeoTopNodeScene.h"
00047 #include "Fireworks/Core/src/FWPopupMenu.cc"
00048 #include "Fireworks/Core/interface/FWViewType.h"
00049 #include "Fireworks/Core/interface/fwLog.h"
00050 
00051 TGLViewer* FWGeoTopNode::s_pickedViewer = 0;
00052 TGLVector3 FWGeoTopNode::s_pickedCamera3DCenter;
00053 
00054 UInt_t FWGeoTopNode::phyID(int tableIdx) 
00055 {
00056 return UInt_t(tableIdx + 2);
00057 
00058 }
00059 
00060 int FWGeoTopNode::tableIdx(TGLPhysicalShape* ps) 
00061 {
00062    return ps->ID() - 2;
00063 }
00064 //______________________________________________________________________________
00065 void FWGeoTopNode::EraseFromSet(std::set<TGLPhysicalShape*>& sset, TGLPhysicalShape* id)
00066 {
00067    sset.erase(id);
00068    SetStateOf(id);
00069 }
00070 
00071 //______________________________________________________________________________
00072 void FWGeoTopNode::ClearSet(std::set<TGLPhysicalShape*>& sset)
00073 {
00074    while (!sset.empty())
00075    {
00076       TGLPhysicalShape *id = *sset.begin();
00077       sset.erase(id);
00078       SetStateOf(id);
00079    }
00080 }
00081 //______________________________________________________________________________
00082 void FWGeoTopNode::SetStateOf(TGLPhysicalShape* id)
00083 {
00084    FWGeometryTableManagerBase::NodeInfo& data =  tableManager()->refEntries().at(tableIdx(id));
00085 
00086    if (fSted.find(id) != fSted.end())
00087    {
00088       id->Select(1);
00089       data.setBit(FWGeometryTableManagerBase::kSelected);
00090    }
00091    else if (fHted.find(id) != fHted.end())
00092    {
00093       id->Select(3);
00094       data.setBit(FWGeometryTableManagerBase::kHighlighted);
00095    }
00096    else
00097    {
00098       id->Select(0);
00099       data.resetBit(FWGeometryTableManagerBase::kHighlighted);
00100       data.resetBit(FWGeometryTableManagerBase::kSelected);
00101    }
00102 
00103 }
00104 
00105 //______________________________________________________________________________
00106 void FWGeoTopNode::ProcessSelection(TGLSelectRecord& rec, std::set<TGLPhysicalShape*>& sset, TGLPhysicalShape* id)
00107 {
00108    // printf("FWGeoTopNode::ProcessSelection ===============================\n");
00109 
00110    m_scene->BeginUpdate();
00111 
00112    if (sset.empty())
00113    {
00114       if (id)
00115       {
00116          sset.insert(id);
00117          rec.SetSecSelResult(TGLSelectRecord::kEnteringSelection);
00118       }  
00119    }
00120    else
00121    {
00122       if (id)
00123       {
00124          if (rec.GetMultiple())
00125          {
00126             if (sset.find(id) == sset.end())
00127             {
00128                sset.insert(id);
00129                rec.SetSecSelResult(TGLSelectRecord::kModifyingInternalSelection);
00130             }
00131             else
00132             {
00133                EraseFromSet(sset, id);
00134                if (sset.empty())
00135                   rec.SetSecSelResult(TGLSelectRecord::kLeavingSelection);
00136                else
00137                   rec.SetSecSelResult(TGLSelectRecord::kModifyingInternalSelection);
00138             }
00139          }
00140          else
00141          {
00142             if (sset.size() != 1 || sset.find(id) == sset.end())
00143             {
00144                ClearSet(sset);
00145                sset.insert(id);
00146                rec.SetSecSelResult(TGLSelectRecord::kModifyingInternalSelection);
00147             }
00148          }
00149       }
00150       else
00151       {
00152          if (!rec.GetMultiple())
00153          {
00154             ClearSet(sset);
00155             rec.SetSecSelResult(TGLSelectRecord::kLeavingSelection);
00156          }
00157       }
00158    }
00159 
00160    if (id)
00161    {
00162       SetStateOf(id);
00163    }
00164 
00165    if (rec.GetSecSelResult() != TGLSelectRecord::kNone)
00166    {
00167       m_scene->EndUpdate(kTRUE, kFALSE, kTRUE);
00168       gEve->Redraw3D();
00169 
00170       tableManager()->dataChanged();
00171    }
00172    else
00173    {
00174       m_scene->EndUpdate(kFALSE, kFALSE, kFALSE);
00175    }
00176 }
00177 
00178 //______________________________________________________________________________
00179 bool FWGeoTopNode::selectPhysicalFromTable( int tableIndex)
00180 {
00181    //   printf("FWGeoTopNode::selectPhysicalFromTable 
00182 
00183    TGLPhysicalShape* ps = m_scene->FindPhysical(phyID(tableIndex));
00184    if (ps) {
00185       fSted.insert(ps);
00186       ps->Select(1);
00187       // printf("selectPhysicalFromTable found physical \n");
00188       return true;
00189    }
00190    else if ( tableManager()->refEntries().at(tableIndex).testBit(FWGeometryTableManagerBase::kVisNodeSelf));
00191    {
00192       fwLog(fwlog::kInfo) << "Selected entry not drawn in GL viewer. \n" ;
00193       return false;
00194    }
00195 }
00196 
00197 //______________________________________________________________________________
00198 void FWGeoTopNode::printSelected() 
00199 {
00200    for (std::set<TGLPhysicalShape*>::iterator it = fSted.begin(); it != fSted.end(); ++it)
00201    {
00202       printf("FWGeoTopNode::printSelected %s \n",  tableManager()->refEntries().at(tableIdx(*it)).name() );
00203    }
00204 }
00205 
00206 //______________________________________________________________________________
00207 
00208 int FWGeoTopNode::getFirstSelectedTableIndex() 
00209 {
00210    // Note: if object would be rendered, this would return fSted.begin().
00211 
00212    if (fSted.size() <= 1)
00213    {
00214       int cnt = 0;
00215       for (FWGeometryTableManagerBase::Entries_i i = tableManager()->refEntries().begin(); i != tableManager()->refEntries().end(); ++i, ++cnt)
00216       {
00217          if (i->testBit(FWGeometryTableManagerBase::kSelected)) return cnt; 
00218       }
00219    }
00220    return -1;
00221 }
00222 
00223 //______________________________________________________________________________
00224 void FWGeoTopNode::ComputeBBox()
00225 {
00226    // Fill bounding-box information. Virtual from TAttBBox.
00227 
00228    BBoxZero(1.0f);
00229 }
00230 
00231 //______________________________________________________________________________
00232 void FWGeoTopNode::setupBuffMtx(TBuffer3D& buff, const TGeoHMatrix& mat)
00233 {
00234    const Double_t *r = mat.GetRotationMatrix();
00235    const Double_t *t = mat.GetTranslation();
00236    const Double_t *s = mat.GetScale();
00237    Double_t       *m = buff.fLocalMaster;
00238    m[0]  = r[0]*s[0]; m[1]  = r[1]*s[1]; m[2]  = r[2]*s[2]; m[3]  = 0;
00239    m[4]  = r[3]*s[0]; m[5]  = r[4]*s[1]; m[6]  = r[5]*s[2]; m[7]  = 0;
00240    m[8]  = r[6]*s[0]; m[9]  = r[7]*s[1]; m[10] = r[8]*s[2]; m[11] = 0;
00241    m[12] = t[0];      m[13] = t[1];      m[15] = t[2];      m[15] = 1;
00242 
00243    buff.fLocalFrame = kTRUE;
00244 }
00245 
00246 // ______________________________________________________________________
00247 void FWGeoTopNode::paintShape( Int_t tableIndex, const TGeoHMatrix& nm, bool volumeColor, bool isParentNode)
00248 {
00249    static const TEveException eh("FWGeoTopNode::paintShape ");
00250  
00251   // printf("paint sahpe id %d\n", tableIndex );
00252 
00253    FWGeometryTableManagerBase::NodeInfo& data = tableManager()->refEntries().at(tableIndex);
00254    UChar_t transparency = wrapTransparency(data, isParentNode);
00255    // printf("trans %d \n", transparency );
00256    if (transparency >= 100) return;
00257    
00258    TGeoShape* shape = data.m_node->GetVolume()->GetShape();
00259    
00260    TGeoCompositeShape* compositeShape = dynamic_cast<TGeoCompositeShape*>(shape);
00261    if (compositeShape)
00262    {
00263       // m_scene->fNextCompositeID = phyID(tableIndex);
00264 
00265       Double_t halfLengths[3] = { compositeShape->GetDX(), compositeShape->GetDY(), compositeShape->GetDZ() };
00266 
00267       TBuffer3D buff(TBuffer3DTypes::kComposite);
00268       buff.fID           = data.m_node->GetVolume();
00269       buff.fColor        = volumeColor ? data.m_node->GetVolume()->GetLineColor() : data.m_color ;
00270       buff.fTransparency = transparency;// data.m_node->GetVolume()->GetTransparency(); 
00271 
00272       nm.GetHomogenousMatrix(buff.fLocalMaster);  
00273       buff.fLocalFrame   = kTRUE; // Always enforce local frame (no geo manager).
00274       buff.SetAABoundingBox(compositeShape->GetOrigin(), halfLengths);
00275       buff.SetSectionsValid(TBuffer3D::kCore|TBuffer3D::kBoundingBox);
00276 
00277       Bool_t paintComponents = kTRUE;
00278       // Start a composite shape, identified by this buffer
00279       if (TBuffer3D::GetCSLevel() == 0) {
00280          paintComponents = m_scene->OpenCompositeWithPhyID(phyID(tableIndex), buff);
00281       }
00282 
00283       TBuffer3D::IncCSLevel();
00284       
00285       // Paint the boolean node - will add more buffers to viewer
00286       TGeoHMatrix xxx;
00287       TGeoMatrix *gst = TGeoShape::GetTransform();
00288       TGeoShape::SetTransform(&xxx);
00289 
00290       if (paintComponents) compositeShape->GetBoolNode()->Paint("");
00291       TGeoShape::SetTransform(gst);
00292       // Close the composite shape
00293       if (TBuffer3D::DecCSLevel() == 0)
00294          gPad->GetViewer3D()->CloseComposite();
00295 
00296 
00297       //  m_scene->fNextCompositeID = 0;
00298    }
00299    else
00300    {
00301       TBuffer3D& buff = (TBuffer3D&) shape->GetBuffer3D (TBuffer3D::kCore, kFALSE);
00302       setupBuffMtx(buff, nm);
00303       buff.fID           = data.m_node->GetVolume();
00304       buff.fColor        = volumeColor ? data.m_node->GetVolume()->GetLineColor() : data.m_color ;
00305       buff.fTransparency = transparency;// data.m_node->GetVolume()->GetTransparency(); 
00306 
00307 
00308       nm.GetHomogenousMatrix(buff.fLocalMaster);
00309       buff.fLocalFrame   = kTRUE; // Always enforce local frame (no geo manager).
00310 
00311       Int_t sections = TBuffer3D::kBoundingBox | TBuffer3D::kShapeSpecific;
00312       shape->GetBuffer3D(sections, kTRUE);
00313 
00314       Int_t reqSec = gPad->GetViewer3D()->AddObject(phyID(tableIndex), buff);
00315 
00316       if (reqSec != TBuffer3D::kNone) {
00317          // This shouldn't happen, but I suspect it does sometimes.
00318          if (reqSec & TBuffer3D::kCore)
00319             Warning(eh, "Core section required again for shape='%s'. This shouldn't happen.", GetName());
00320          shape->GetBuffer3D(reqSec, kTRUE);
00321          reqSec = gPad->GetViewer3D()->AddObject(phyID(tableIndex), buff);
00322       }
00323 
00324       if (reqSec != TBuffer3D::kNone)  
00325          Warning(eh, "Extra section required: reqSec=%d, shape=%s.", reqSec, GetName());
00326    }
00327 }
00328 
00329 // ______________________________________________________________________
00330 void FWGeoTopNode::Paint(Option_t* opt)
00331 {
00332    static const TEveException eh("FWGeoTopNode::Paint ");
00333 
00334    TBuffer3D buff(TBuffer3DTypes::kGeneric);
00335 
00336    // Section kCore
00337    buff.fID           = this;
00338    buff.fColor        = GetMainColor();
00339    buff.fTransparency = GetMainTransparency();
00340    if (HasMainTrans())  RefMainTrans().SetBuffer3D(buff);
00341 
00342    buff.SetSectionsValid(TBuffer3D::kCore);
00343 
00344    Int_t reqSections = gPad->GetViewer3D()->AddObject(1, buff);
00345    if (reqSections != TBuffer3D::kNone)
00346    {
00347       Warning(eh, "IsA='%s'. Viewer3D requires more sections (%d). Only direct-rendering supported.",
00348               ClassName(), reqSections);
00349    }
00350 }
00351 
00352 // ______________________________________________________________________
00353 void FWGeoTopNode::UnSelected()
00354 {
00355    ClearSet(fSted);
00356    for (FWGeometryTableManagerBase::Entries_i i = tableManager()->refEntries().begin(); i != tableManager()->refEntries().end(); ++i)
00357       i->resetBit(FWGeometryTableManagerBase::kSelected);
00358 }
00359 
00360 // ______________________________________________________________________
00361 void FWGeoTopNode::UnHighlighted()
00362 {
00363    ClearSet(fHted);
00364    for (FWGeometryTableManagerBase::Entries_i i = tableManager()->refEntries().begin(); i != tableManager()->refEntries().end(); ++i)
00365       i->resetBit(FWGeometryTableManagerBase::kHighlighted);
00366 }   
00367 
00368 
00369 // ______________________________________________________________________
00370 FWPopupMenu* FWGeoTopNode::setPopupMenu(int iX, int iY, TGLViewer* v, bool overlap)
00371 {
00372    if (getFirstSelectedTableIndex() < 0)
00373    {
00374       if (fSted.empty()) fwLog(fwlog::kInfo) << "No menu -- no node/entry selected \n";
00375       return 0;
00376    }
00377    
00378    FWPopupMenu* nodePopup = new FWPopupMenu();
00379    
00380    nodePopup->AddEntry("Set As Top Node", kSetTopNode);
00381    nodePopup->AddEntry("Set As Top Node And Reset Camera", kSetTopNodeCam);
00382    nodePopup->AddSeparator();
00383    if (v) { 
00384        nodePopup->AddEntry("Rnr Off", kVisSelfOff);
00385    }
00386    nodePopup->AddEntry("Rnr Off For All Children", kVisChldOff);
00387    nodePopup->AddEntry("Rnr On For All Children", kVisChldOn);      
00388    nodePopup->AddSeparator();
00389    
00390    if (overlap)
00391       nodePopup->AddEntry("Print Overlap", kPrintOverlap);
00392    nodePopup->AddEntry("Print Path", kPrintPath);
00393    nodePopup->AddEntry("Print Shape", kPrintShape);
00394    nodePopup->AddEntry("Print Material", kPrintMaterial);   
00395    
00396    nodePopup->AddSeparator();
00397    if (v) {
00398       Window_t wdummy;
00399       Int_t x,y;
00400       gVirtualX->TranslateCoordinates(gClient->GetDefaultRoot()->GetId(), v->GetGLWidget()->GetId(), iX, iY, x, y, wdummy);   
00401       TGLVector3 pnt(x, y, 0.5*v->GetSelRec().GetMinZ());
00402       v->CurrentCamera().WindowToViewport(pnt);
00403       s_pickedCamera3DCenter = v->CurrentCamera().ViewportToWorld(pnt);
00404       // s_pickedCamera3DCenter.Dump();
00405       s_pickedViewer = v;
00406       
00407       nodePopup->AddEntry("Set Camera Center", kCamera);
00408    }
00409    
00410    nodePopup->PlaceMenu(iX, iY,true,true);
00411    return nodePopup;
00412 }
00413 
00414 
00415 UChar_t FWGeoTopNode::wrapTransparency(FWGeometryTableManagerBase::NodeInfo& data, bool isParentNode)
00416 {
00417    if (isParentNode)
00418    {
00419       return TMath::Max((Char_t)browser()->getMinParentTransparency(), data.m_transparency) * browser()->getParentTransparencyFactor();
00420    }
00421    else 
00422    {
00423       return TMath::Max((Char_t)browser()->getMinLeafTransparency(), data.m_transparency) * browser()->getLeafTransparencyFactor();
00424    }   
00425 }