Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:11:39

0001 // -*- C++ -*-
0002 //
0003 // Package:     Core
0004 // Class  :     FWGeoTopNode
0005 //
0006 // Implementation:
0007 //     [Notes on implementation]
0008 //
0009 // Original Author:  Matevz Tadel, Alja Mrak Tadel
0010 //         Created:  Thu Jun 23 01:24:51 CEST 2011
0011 //
0012 
0013 // system include files
0014 
0015 // user include files
0016 
0017 #include "TEveTrans.h"
0018 #include "TEveViewer.h"
0019 #include "TEveManager.h"
0020 #include "TEveUtil.h"
0021 
0022 #include "TROOT.h"
0023 #include "TBuffer3D.h"
0024 #include "TBuffer3DTypes.h"
0025 #include "TVirtualViewer3D.h"
0026 #include "TColor.h"
0027 #include "TGLScenePad.h"
0028 #include "TGLPhysicalShape.h"
0029 #include "TGLSelectRecord.h"
0030 #include "TGLViewer.h"
0031 #include "TGLWidget.h"
0032 
0033 #include "TGeoShape.h"
0034 #include "TGeoVolume.h"
0035 #include "TGeoNode.h"
0036 #include "TGeoShapeAssembly.h"
0037 #include "TGeoCompositeShape.h"
0038 #include "TGeoBoolNode.h"
0039 #include "TGeoManager.h"
0040 #include "TGeoMatrix.h"
0041 #include "TVirtualGeoPainter.h"
0042 #include "TVirtualX.h"
0043 
0044 #include "Fireworks/Core/interface/FWGeoTopNode.h"
0045 #include "Fireworks/Core/src/FWGeoTopNodeScene.h"
0046 #include "Fireworks/Core/src/FWPopupMenu.cc"
0047 #include "Fireworks/Core/interface/FWViewType.h"
0048 #include "Fireworks/Core/interface/fwLog.h"
0049 
0050 TGLViewer* FWGeoTopNode::s_pickedViewer = nullptr;
0051 TGLVector3 FWGeoTopNode::s_pickedCamera3DCenter;
0052 
0053 UInt_t FWGeoTopNode::phyID(int tableIdx) { return UInt_t(tableIdx + 2); }
0054 
0055 int FWGeoTopNode::tableIdx(TGLPhysicalShape* ps) { return ps->ID() - 2; }
0056 //______________________________________________________________________________
0057 void FWGeoTopNode::EraseFromSet(std::set<TGLPhysicalShape*>& sset, TGLPhysicalShape* id) {
0058   sset.erase(id);
0059   SetStateOf(id);
0060 }
0061 
0062 //______________________________________________________________________________
0063 void FWGeoTopNode::ClearSet(std::set<TGLPhysicalShape*>& sset) {
0064   while (!sset.empty()) {
0065     TGLPhysicalShape* id = *sset.begin();
0066     sset.erase(id);
0067     SetStateOf(id);
0068   }
0069 }
0070 //______________________________________________________________________________
0071 void FWGeoTopNode::SetStateOf(TGLPhysicalShape* id) {
0072   FWGeometryTableManagerBase::NodeInfo& data = tableManager()->refEntries().at(tableIdx(id));
0073 
0074   if (fSted.find(id) != fSted.end()) {
0075     id->Select(1);
0076     data.setBit(FWGeometryTableManagerBase::kSelected);
0077   } else if (fHted.find(id) != fHted.end()) {
0078     id->Select(3);
0079     data.setBit(FWGeometryTableManagerBase::kHighlighted);
0080   } else {
0081     id->Select(0);
0082     data.resetBit(FWGeometryTableManagerBase::kHighlighted);
0083     data.resetBit(FWGeometryTableManagerBase::kSelected);
0084   }
0085 }
0086 
0087 //______________________________________________________________________________
0088 void FWGeoTopNode::ProcessSelection(TGLSelectRecord& rec, std::set<TGLPhysicalShape*>& sset, TGLPhysicalShape* id) {
0089   // printf("FWGeoTopNode::ProcessSelection ===============================\n");
0090 
0091   m_scene->BeginUpdate();
0092 
0093   if (sset.empty()) {
0094     if (id) {
0095       sset.insert(id);
0096       rec.SetSecSelResult(TGLSelectRecord::kEnteringSelection);
0097     }
0098   } else {
0099     if (id) {
0100       if (rec.GetMultiple()) {
0101         if (sset.find(id) == sset.end()) {
0102           sset.insert(id);
0103           rec.SetSecSelResult(TGLSelectRecord::kModifyingInternalSelection);
0104         } else {
0105           EraseFromSet(sset, id);
0106           if (sset.empty())
0107             rec.SetSecSelResult(TGLSelectRecord::kLeavingSelection);
0108           else
0109             rec.SetSecSelResult(TGLSelectRecord::kModifyingInternalSelection);
0110         }
0111       } else {
0112         if (sset.size() != 1 || sset.find(id) == sset.end()) {
0113           ClearSet(sset);
0114           sset.insert(id);
0115           rec.SetSecSelResult(TGLSelectRecord::kModifyingInternalSelection);
0116         }
0117       }
0118     } else {
0119       if (!rec.GetMultiple()) {
0120         ClearSet(sset);
0121         rec.SetSecSelResult(TGLSelectRecord::kLeavingSelection);
0122       }
0123     }
0124   }
0125 
0126   if (id) {
0127     SetStateOf(id);
0128   }
0129 
0130   if (rec.GetSecSelResult() != TGLSelectRecord::kNone) {
0131     m_scene->EndUpdate(kTRUE, kFALSE, kTRUE);
0132     gEve->Redraw3D();
0133 
0134     tableManager()->dataChanged();
0135   } else {
0136     m_scene->EndUpdate(kFALSE, kFALSE, kFALSE);
0137   }
0138 }
0139 
0140 //______________________________________________________________________________
0141 bool FWGeoTopNode::selectPhysicalFromTable(int tableIndex) {
0142   //   printf("FWGeoTopNode::selectPhysicalFromTable
0143 
0144   TGLPhysicalShape* ps = m_scene->FindPhysical(phyID(tableIndex));
0145   if (ps) {
0146     fSted.insert(ps);
0147     ps->Select(1);
0148     // printf("selectPhysicalFromTable found physical \n");
0149     return true;
0150   } else if (tableManager()->refEntries().at(tableIndex).testBit(FWGeometryTableManagerBase::kVisNodeSelf))
0151     fwLog(fwlog::kInfo) << "Selected entry not drawn in GL viewer. \n";
0152   return false;
0153 }
0154 
0155 //______________________________________________________________________________
0156 void FWGeoTopNode::printSelected() {
0157   for (std::set<TGLPhysicalShape*>::iterator it = fSted.begin(); it != fSted.end(); ++it) {
0158     printf("FWGeoTopNode::printSelected %s \n", tableManager()->refEntries().at(tableIdx(*it)).name());
0159   }
0160 }
0161 
0162 //______________________________________________________________________________
0163 
0164 int FWGeoTopNode::getFirstSelectedTableIndex() {
0165   // Note: if object would be rendered, this would return fSted.begin().
0166 
0167   if (fSted.size() <= 1) {
0168     int cnt = 0;
0169     for (FWGeometryTableManagerBase::Entries_i i = tableManager()->refEntries().begin();
0170          i != tableManager()->refEntries().end();
0171          ++i, ++cnt) {
0172       if (i->testBit(FWGeometryTableManagerBase::kSelected))
0173         return cnt;
0174     }
0175   }
0176   return -1;
0177 }
0178 
0179 //______________________________________________________________________________
0180 void FWGeoTopNode::ComputeBBox() {
0181   // Fill bounding-box information. Virtual from TAttBBox.
0182 
0183   BBoxZero(1.0f);
0184 }
0185 
0186 //______________________________________________________________________________
0187 void FWGeoTopNode::setupBuffMtx(TBuffer3D& buff, const TGeoHMatrix& mat) {
0188   const Double_t* r = mat.GetRotationMatrix();
0189   const Double_t* t = mat.GetTranslation();
0190   const Double_t* s = mat.GetScale();
0191   Double_t* m = buff.fLocalMaster;
0192   m[0] = r[0] * s[0];
0193   m[1] = r[1] * s[1];
0194   m[2] = r[2] * s[2];
0195   m[3] = 0;
0196   m[4] = r[3] * s[0];
0197   m[5] = r[4] * s[1];
0198   m[6] = r[5] * s[2];
0199   m[7] = 0;
0200   m[8] = r[6] * s[0];
0201   m[9] = r[7] * s[1];
0202   m[10] = r[8] * s[2];
0203   m[11] = 0;
0204   m[12] = t[0];
0205   m[13] = t[1];
0206   m[15] = t[2];
0207   m[15] = 1;
0208 
0209   buff.fLocalFrame = kTRUE;
0210 }
0211 
0212 // ______________________________________________________________________
0213 void FWGeoTopNode::paintShape(Int_t tableIndex, const TGeoHMatrix& nm, bool volumeColor, bool isParentNode) {
0214   static const TEveException eh("FWGeoTopNode::paintShape ");
0215 
0216   // printf("paint sahpe id %d\n", tableIndex );
0217 
0218   FWGeometryTableManagerBase::NodeInfo& data = tableManager()->refEntries().at(tableIndex);
0219   UChar_t transparency = wrapTransparency(data, isParentNode);
0220   // printf("trans %d \n", transparency );
0221   if (transparency >= 100)
0222     return;
0223 
0224   if (data.m_node->GetVolume()->IsAssembly())
0225     return;
0226   TGeoShape* shape = data.m_node->GetVolume()->GetShape();
0227 
0228   TGeoCompositeShape* compositeShape = dynamic_cast<TGeoCompositeShape*>(shape);
0229   if (compositeShape) {
0230     // m_scene->fNextCompositeID = phyID(tableIndex);
0231 
0232     Double_t halfLengths[3] = {compositeShape->GetDX(), compositeShape->GetDY(), compositeShape->GetDZ()};
0233 
0234     TBuffer3D buff(TBuffer3DTypes::kComposite);
0235     buff.fID = data.m_node->GetVolume();
0236     buff.fColor = volumeColor ? data.m_node->GetVolume()->GetLineColor() : data.m_color;
0237     buff.fTransparency = transparency;  // data.m_node->GetVolume()->GetTransparency();
0238 
0239     nm.GetHomogenousMatrix(buff.fLocalMaster);
0240     buff.fLocalFrame = kTRUE;  // Always enforce local frame (no geo manager).
0241     buff.SetAABoundingBox(compositeShape->GetOrigin(), halfLengths);
0242     buff.SetSectionsValid(TBuffer3D::kCore | TBuffer3D::kBoundingBox);
0243 
0244     Bool_t paintComponents = kTRUE;
0245     // Start a composite shape, identified by this buffer
0246     if (TBuffer3D::GetCSLevel() == 0) {
0247       paintComponents = m_scene->OpenCompositeWithPhyID(phyID(tableIndex), buff);
0248     }
0249 
0250     TBuffer3D::IncCSLevel();
0251 
0252     // Paint the boolean node - will add more buffers to viewer
0253     TGeoHMatrix xxx;
0254     TGeoMatrix* gst = TGeoShape::GetTransform();
0255     TGeoShape::SetTransform(&xxx);
0256 
0257     if (paintComponents)
0258       compositeShape->GetBoolNode()->Paint("");
0259     TGeoShape::SetTransform(gst);
0260     // Close the composite shape
0261     if (TBuffer3D::DecCSLevel() == 0)
0262       gPad->GetViewer3D()->CloseComposite();
0263 
0264     //  m_scene->fNextCompositeID = 0;
0265   } else {
0266     TBuffer3D& buff = (TBuffer3D&)shape->GetBuffer3D(TBuffer3D::kCore, kFALSE);
0267     setupBuffMtx(buff, nm);
0268     buff.fID = data.m_node->GetVolume();
0269     buff.fColor = volumeColor ? data.m_node->GetVolume()->GetLineColor() : data.m_color;
0270     buff.fTransparency = transparency;  // data.m_node->GetVolume()->GetTransparency();
0271 
0272     nm.GetHomogenousMatrix(buff.fLocalMaster);
0273     buff.fLocalFrame = kTRUE;  // Always enforce local frame (no geo manager).
0274 
0275     Int_t sections = TBuffer3D::kBoundingBox | TBuffer3D::kShapeSpecific;
0276     shape->GetBuffer3D(sections, kTRUE);
0277 
0278     Int_t reqSec = gPad->GetViewer3D()->AddObject(phyID(tableIndex), buff);
0279 
0280     if (reqSec != TBuffer3D::kNone) {
0281       // This shouldn't happen, but I suspect it does sometimes.
0282       if (reqSec & TBuffer3D::kCore)
0283         Warning(eh, "Core section required again for shape='%s'. This shouldn't happen.", GetName());
0284       shape->GetBuffer3D(reqSec, kTRUE);
0285       reqSec = gPad->GetViewer3D()->AddObject(phyID(tableIndex), buff);
0286     }
0287 
0288     if (reqSec != TBuffer3D::kNone)
0289       Warning(eh, "Extra section required: reqSec=%d, shape=%s.", reqSec, GetName());
0290   }
0291 }
0292 
0293 // ______________________________________________________________________
0294 void FWGeoTopNode::Paint(Option_t* opt) {
0295   static const TEveException eh("FWGeoTopNode::Paint ");
0296 
0297   TBuffer3D buff(TBuffer3DTypes::kGeneric);
0298 
0299   // Section kCore
0300   buff.fID = this;
0301   buff.fColor = GetMainColor();
0302   buff.fTransparency = GetMainTransparency();
0303   if (HasMainTrans())
0304     RefMainTrans().SetBuffer3D(buff);
0305 
0306   buff.SetSectionsValid(TBuffer3D::kCore);
0307 
0308   Int_t reqSections = gPad->GetViewer3D()->AddObject(1, buff);
0309   if (reqSections != TBuffer3D::kNone) {
0310     Warning(eh,
0311             "IsA='%s'. Viewer3D requires more sections (%d). Only direct-rendering supported.",
0312             ClassName(),
0313             reqSections);
0314   }
0315 }
0316 
0317 // ______________________________________________________________________
0318 void FWGeoTopNode::UnSelected() {
0319   ClearSet(fSted);
0320   for (FWGeometryTableManagerBase::Entries_i i = tableManager()->refEntries().begin();
0321        i != tableManager()->refEntries().end();
0322        ++i)
0323     i->resetBit(FWGeometryTableManagerBase::kSelected);
0324 }
0325 
0326 // ______________________________________________________________________
0327 void FWGeoTopNode::UnHighlighted() {
0328   ClearSet(fHted);
0329   for (FWGeometryTableManagerBase::Entries_i i = tableManager()->refEntries().begin();
0330        i != tableManager()->refEntries().end();
0331        ++i)
0332     i->resetBit(FWGeometryTableManagerBase::kHighlighted);
0333 }
0334 
0335 // ______________________________________________________________________
0336 FWPopupMenu* FWGeoTopNode::setPopupMenu(int iX, int iY, TGLViewer* v, bool overlap) {
0337   if (getFirstSelectedTableIndex() < 0) {
0338     if (fSted.empty())
0339       fwLog(fwlog::kInfo) << "No menu -- no node/entry selected \n";
0340     return nullptr;
0341   }
0342 
0343   FWPopupMenu* nodePopup = new FWPopupMenu();
0344 
0345   nodePopup->AddEntry("Set As Top Node", kSetTopNode);
0346   nodePopup->AddEntry("Set As Top Node and Reset Camera", kSetTopNodeCam);
0347   nodePopup->AddSeparator();
0348   if (v) {
0349     nodePopup->AddEntry("Rnr Off", kVisSelfOff);
0350   }
0351   nodePopup->AddEntry("Turn Render On For Children", kVisChldOn);
0352   nodePopup->AddEntry("Turn Render Off For Children", kVisChldOff);
0353   nodePopup->AddEntry("Apply Color To Children", kApplyChldCol);
0354   nodePopup->AddEntry("Apply Color Recursively", kApplyChldColRec);
0355   nodePopup->AddSeparator();
0356 
0357   if (overlap)
0358     nodePopup->AddEntry("Print Overlap", kPrintOverlap);
0359   nodePopup->AddEntry("Print Path", kPrintPath);
0360   nodePopup->AddEntry("Print Shape", kPrintShape);
0361   nodePopup->AddEntry("Print Material", kPrintMaterial);
0362 
0363   nodePopup->AddSeparator();
0364   if (v) {
0365     Window_t wdummy;
0366     Int_t x, y;
0367     gVirtualX->TranslateCoordinates(
0368         gClient->GetDefaultRoot()->GetId(), v->GetGLWidget()->GetId(), iX, iY, x, y, wdummy);
0369     TGLVector3 pnt(x, y, 0.5 * v->GetSelRec().GetMinZ());
0370     v->CurrentCamera().WindowToViewport(pnt);
0371     s_pickedCamera3DCenter = v->CurrentCamera().ViewportToWorld(pnt);
0372     // s_pickedCamera3DCenter.Dump();
0373     s_pickedViewer = v;
0374 
0375     nodePopup->AddEntry("Set Camera Center", kCamera);
0376   }
0377 
0378   nodePopup->PlaceMenu(iX, iY, true, true);
0379   return nodePopup;
0380 }
0381 
0382 UChar_t FWGeoTopNode::wrapTransparency(FWGeometryTableManagerBase::NodeInfo& data, bool isParentNode) {
0383   if (isParentNode) {
0384     return TMath::Max((Char_t)browser()->getMinParentTransparency(), data.m_transparency) *
0385            browser()->getParentTransparencyFactor();
0386   } else {
0387     return TMath::Max((Char_t)browser()->getMinLeafTransparency(), data.m_transparency) *
0388            browser()->getLeafTransparencyFactor();
0389   }
0390 }