CMS 3D CMS Logo

FWGeoTopNode.cc
Go to the documentation of this file.
1 // -*- C++ -*-
2 //
3 // Package: Core
4 // Class : FWGeoTopNode
5 //
6 // Implementation:
7 // [Notes on implementation]
8 //
9 // Original Author: Matevz Tadel, Alja Mrak Tadel
10 // Created: Thu Jun 23 01:24:51 CEST 2011
11 //
12 
13 // system include files
14 
15 // user include files
16 
17 #include "TEveTrans.h"
18 #include "TEveViewer.h"
19 #include "TEveManager.h"
20 #include "TEveUtil.h"
21 
22 #include "TROOT.h"
23 #include "TBuffer3D.h"
24 #include "TBuffer3DTypes.h"
25 #include "TVirtualViewer3D.h"
26 #include "TColor.h"
27 #include "TGLScenePad.h"
28 #include "TGLPhysicalShape.h"
29 #include "TGLSelectRecord.h"
30 #include "TGLViewer.h"
31 #include "TGLWidget.h"
32 
33 #include "TGeoShape.h"
34 #include "TGeoVolume.h"
35 #include "TGeoNode.h"
36 #include "TGeoShapeAssembly.h"
37 #include "TGeoCompositeShape.h"
38 #include "TGeoBoolNode.h"
39 #include "TGeoManager.h"
40 #include "TGeoMatrix.h"
41 #include "TVirtualGeoPainter.h"
42 #include "TVirtualX.h"
43 
49 
50 TGLViewer* FWGeoTopNode::s_pickedViewer = nullptr;
52 
53 UInt_t FWGeoTopNode::phyID(int tableIdx) { return UInt_t(tableIdx + 2); }
54 
55 int FWGeoTopNode::tableIdx(TGLPhysicalShape* ps) { return ps->ID() - 2; }
56 //______________________________________________________________________________
57 void FWGeoTopNode::EraseFromSet(std::set<TGLPhysicalShape*>& sset, TGLPhysicalShape* id) {
58  sset.erase(id);
59  SetStateOf(id);
60 }
61 
62 //______________________________________________________________________________
63 void FWGeoTopNode::ClearSet(std::set<TGLPhysicalShape*>& sset) {
64  while (!sset.empty()) {
65  TGLPhysicalShape* id = *sset.begin();
66  sset.erase(id);
67  SetStateOf(id);
68  }
69 }
70 //______________________________________________________________________________
71 void FWGeoTopNode::SetStateOf(TGLPhysicalShape* id) {
73 
74  if (fSted.find(id) != fSted.end()) {
75  id->Select(1);
77  } else if (fHted.find(id) != fHted.end()) {
78  id->Select(3);
80  } else {
81  id->Select(0);
84  }
85 }
86 
87 //______________________________________________________________________________
88 void FWGeoTopNode::ProcessSelection(TGLSelectRecord& rec, std::set<TGLPhysicalShape*>& sset, TGLPhysicalShape* id) {
89  // printf("FWGeoTopNode::ProcessSelection ===============================\n");
90 
91  m_scene->BeginUpdate();
92 
93  if (sset.empty()) {
94  if (id) {
95  sset.insert(id);
96  rec.SetSecSelResult(TGLSelectRecord::kEnteringSelection);
97  }
98  } else {
99  if (id) {
100  if (rec.GetMultiple()) {
101  if (sset.find(id) == sset.end()) {
102  sset.insert(id);
103  rec.SetSecSelResult(TGLSelectRecord::kModifyingInternalSelection);
104  } else {
105  EraseFromSet(sset, id);
106  if (sset.empty())
107  rec.SetSecSelResult(TGLSelectRecord::kLeavingSelection);
108  else
109  rec.SetSecSelResult(TGLSelectRecord::kModifyingInternalSelection);
110  }
111  } else {
112  if (sset.size() != 1 || sset.find(id) == sset.end()) {
113  ClearSet(sset);
114  sset.insert(id);
115  rec.SetSecSelResult(TGLSelectRecord::kModifyingInternalSelection);
116  }
117  }
118  } else {
119  if (!rec.GetMultiple()) {
120  ClearSet(sset);
121  rec.SetSecSelResult(TGLSelectRecord::kLeavingSelection);
122  }
123  }
124  }
125 
126  if (id) {
127  SetStateOf(id);
128  }
129 
130  if (rec.GetSecSelResult() != TGLSelectRecord::kNone) {
131  m_scene->EndUpdate(kTRUE, kFALSE, kTRUE);
132  gEve->Redraw3D();
133 
135  } else {
136  m_scene->EndUpdate(kFALSE, kFALSE, kFALSE);
137  }
138 }
139 
140 //______________________________________________________________________________
142  // printf("FWGeoTopNode::selectPhysicalFromTable
143 
144  TGLPhysicalShape* ps = m_scene->FindPhysical(phyID(tableIndex));
145  if (ps) {
146  fSted.insert(ps);
147  ps->Select(1);
148  // printf("selectPhysicalFromTable found physical \n");
149  return true;
150  } else if (tableManager()->refEntries().at(tableIndex).testBit(FWGeometryTableManagerBase::kVisNodeSelf))
151  fwLog(fwlog::kInfo) << "Selected entry not drawn in GL viewer. \n";
152  return false;
153 }
154 
155 //______________________________________________________________________________
157  for (std::set<TGLPhysicalShape*>::iterator it = fSted.begin(); it != fSted.end(); ++it) {
158  printf("FWGeoTopNode::printSelected %s \n", tableManager()->refEntries().at(tableIdx(*it)).name());
159  }
160 }
161 
162 //______________________________________________________________________________
163 
165  // Note: if object would be rendered, this would return fSted.begin().
166 
167  if (fSted.size() <= 1) {
168  int cnt = 0;
170  i != tableManager()->refEntries().end();
171  ++i, ++cnt) {
173  return cnt;
174  }
175  }
176  return -1;
177 }
178 
179 //______________________________________________________________________________
181  // Fill bounding-box information. Virtual from TAttBBox.
182 
183  BBoxZero(1.0f);
184 }
185 
186 //______________________________________________________________________________
187 void FWGeoTopNode::setupBuffMtx(TBuffer3D& buff, const TGeoHMatrix& mat) {
188  const Double_t* r = mat.GetRotationMatrix();
189  const Double_t* t = mat.GetTranslation();
190  const Double_t* s = mat.GetScale();
191  Double_t* m = buff.fLocalMaster;
192  m[0] = r[0] * s[0];
193  m[1] = r[1] * s[1];
194  m[2] = r[2] * s[2];
195  m[3] = 0;
196  m[4] = r[3] * s[0];
197  m[5] = r[4] * s[1];
198  m[6] = r[5] * s[2];
199  m[7] = 0;
200  m[8] = r[6] * s[0];
201  m[9] = r[7] * s[1];
202  m[10] = r[8] * s[2];
203  m[11] = 0;
204  m[12] = t[0];
205  m[13] = t[1];
206  m[15] = t[2];
207  m[15] = 1;
208 
209  buff.fLocalFrame = kTRUE;
210 }
211 
212 // ______________________________________________________________________
213 void FWGeoTopNode::paintShape(Int_t tableIndex, const TGeoHMatrix& nm, bool volumeColor, bool isParentNode) {
214  static const TEveException eh("FWGeoTopNode::paintShape ");
215 
216  // printf("paint sahpe id %d\n", tableIndex );
217 
219  UChar_t transparency = wrapTransparency(data, isParentNode);
220  // printf("trans %d \n", transparency );
221  if (transparency >= 100)
222  return;
223 
224  if (data.m_node->GetVolume()->IsAssembly())
225  return;
226  TGeoShape* shape = data.m_node->GetVolume()->GetShape();
227 
228  TGeoCompositeShape* compositeShape = dynamic_cast<TGeoCompositeShape*>(shape);
229  if (compositeShape) {
230  // m_scene->fNextCompositeID = phyID(tableIndex);
231 
232  Double_t halfLengths[3] = {compositeShape->GetDX(), compositeShape->GetDY(), compositeShape->GetDZ()};
233 
234  TBuffer3D buff(TBuffer3DTypes::kComposite);
235  buff.fID = data.m_node->GetVolume();
236  buff.fColor = volumeColor ? data.m_node->GetVolume()->GetLineColor() : data.m_color;
237  buff.fTransparency = transparency; // data.m_node->GetVolume()->GetTransparency();
238 
239  nm.GetHomogenousMatrix(buff.fLocalMaster);
240  buff.fLocalFrame = kTRUE; // Always enforce local frame (no geo manager).
241  buff.SetAABoundingBox(compositeShape->GetOrigin(), halfLengths);
242  buff.SetSectionsValid(TBuffer3D::kCore | TBuffer3D::kBoundingBox);
243 
244  Bool_t paintComponents = kTRUE;
245  // Start a composite shape, identified by this buffer
246  if (TBuffer3D::GetCSLevel() == 0) {
247  paintComponents = m_scene->OpenCompositeWithPhyID(phyID(tableIndex), buff);
248  }
249 
250  TBuffer3D::IncCSLevel();
251 
252  // Paint the boolean node - will add more buffers to viewer
253  TGeoHMatrix xxx;
254  TGeoMatrix* gst = TGeoShape::GetTransform();
255  TGeoShape::SetTransform(&xxx);
256 
257  if (paintComponents)
258  compositeShape->GetBoolNode()->Paint("");
259  TGeoShape::SetTransform(gst);
260  // Close the composite shape
261  if (TBuffer3D::DecCSLevel() == 0)
262  gPad->GetViewer3D()->CloseComposite();
263 
264  // m_scene->fNextCompositeID = 0;
265  } else {
266  TBuffer3D& buff = (TBuffer3D&)shape->GetBuffer3D(TBuffer3D::kCore, kFALSE);
267  setupBuffMtx(buff, nm);
268  buff.fID = data.m_node->GetVolume();
269  buff.fColor = volumeColor ? data.m_node->GetVolume()->GetLineColor() : data.m_color;
270  buff.fTransparency = transparency; // data.m_node->GetVolume()->GetTransparency();
271 
272  nm.GetHomogenousMatrix(buff.fLocalMaster);
273  buff.fLocalFrame = kTRUE; // Always enforce local frame (no geo manager).
274 
275  Int_t sections = TBuffer3D::kBoundingBox | TBuffer3D::kShapeSpecific;
276  shape->GetBuffer3D(sections, kTRUE);
277 
278  Int_t reqSec = gPad->GetViewer3D()->AddObject(phyID(tableIndex), buff);
279 
280  if (reqSec != TBuffer3D::kNone) {
281  // This shouldn't happen, but I suspect it does sometimes.
282  if (reqSec & TBuffer3D::kCore)
283  Warning(eh, "Core section required again for shape='%s'. This shouldn't happen.", GetName());
284  shape->GetBuffer3D(reqSec, kTRUE);
285  reqSec = gPad->GetViewer3D()->AddObject(phyID(tableIndex), buff);
286  }
287 
288  if (reqSec != TBuffer3D::kNone)
289  Warning(eh, "Extra section required: reqSec=%d, shape=%s.", reqSec, GetName());
290  }
291 }
292 
293 // ______________________________________________________________________
294 void FWGeoTopNode::Paint(Option_t* opt) {
295  static const TEveException eh("FWGeoTopNode::Paint ");
296 
297  TBuffer3D buff(TBuffer3DTypes::kGeneric);
298 
299  // Section kCore
300  buff.fID = this;
301  buff.fColor = GetMainColor();
302  buff.fTransparency = GetMainTransparency();
303  if (HasMainTrans())
304  RefMainTrans().SetBuffer3D(buff);
305 
306  buff.SetSectionsValid(TBuffer3D::kCore);
307 
308  Int_t reqSections = gPad->GetViewer3D()->AddObject(1, buff);
309  if (reqSections != TBuffer3D::kNone) {
310  Warning(eh,
311  "IsA='%s'. Viewer3D requires more sections (%d). Only direct-rendering supported.",
312  ClassName(),
313  reqSections);
314  }
315 }
316 
317 // ______________________________________________________________________
319  ClearSet(fSted);
320  for (FWGeometryTableManagerBase::Entries_i i = tableManager()->refEntries().begin();
321  i != tableManager()->refEntries().end();
322  ++i)
324 }
325 
326 // ______________________________________________________________________
328  ClearSet(fHted);
329  for (FWGeometryTableManagerBase::Entries_i i = tableManager()->refEntries().begin();
330  i != tableManager()->refEntries().end();
331  ++i)
333 }
334 
335 // ______________________________________________________________________
336 FWPopupMenu* FWGeoTopNode::setPopupMenu(int iX, int iY, TGLViewer* v, bool overlap) {
337  if (getFirstSelectedTableIndex() < 0) {
338  if (fSted.empty())
339  fwLog(fwlog::kInfo) << "No menu -- no node/entry selected \n";
340  return nullptr;
341  }
342 
343  FWPopupMenu* nodePopup = new FWPopupMenu();
344 
345  nodePopup->AddEntry("Set As Top Node", kSetTopNode);
346  nodePopup->AddEntry("Set As Top Node and Reset Camera", kSetTopNodeCam);
347  nodePopup->AddSeparator();
348  if (v) {
349  nodePopup->AddEntry("Rnr Off", kVisSelfOff);
350  }
351  nodePopup->AddEntry("Turn Render On For Children", kVisChldOn);
352  nodePopup->AddEntry("Turn Render Off For Children", kVisChldOff);
353  nodePopup->AddEntry("Apply Color To Children", kApplyChldCol);
354  nodePopup->AddEntry("Apply Color Recursively", kApplyChldColRec);
355  nodePopup->AddSeparator();
356 
357  if (overlap)
358  nodePopup->AddEntry("Print Overlap", kPrintOverlap);
359  nodePopup->AddEntry("Print Path", kPrintPath);
360  nodePopup->AddEntry("Print Shape", kPrintShape);
361  nodePopup->AddEntry("Print Material", kPrintMaterial);
362 
363  nodePopup->AddSeparator();
364  if (v) {
365  Window_t wdummy;
366  Int_t x, y;
367  gVirtualX->TranslateCoordinates(
368  gClient->GetDefaultRoot()->GetId(), v->GetGLWidget()->GetId(), iX, iY, x, y, wdummy);
369  TGLVector3 pnt(x, y, 0.5 * v->GetSelRec().GetMinZ());
370  v->CurrentCamera().WindowToViewport(pnt);
371  s_pickedCamera3DCenter = v->CurrentCamera().ViewportToWorld(pnt);
372  // s_pickedCamera3DCenter.Dump();
373  s_pickedViewer = v;
374 
375  nodePopup->AddEntry("Set Camera Center", kCamera);
376  }
377 
378  nodePopup->PlaceMenu(iX, iY, true, true);
379  return nodePopup;
380 }
381 
383  if (isParentNode) {
384  return TMath::Max((Char_t)browser()->getMinParentTransparency(), data.m_transparency) *
386  } else {
387  return TMath::Max((Char_t)browser()->getMinLeafTransparency(), data.m_transparency) *
389  }
390 }
std::set< TGLPhysicalShape * > fSted
Definition: FWGeoTopNode.h:72
virtual FWGeometryTableManagerBase * tableManager()
Definition: FWGeoTopNode.h:68
void ClearSet(std::set< TGLPhysicalShape *> &sset)
Definition: FWGeoTopNode.cc:63
bool OpenCompositeWithPhyID(UInt_t phyID, const TBuffer3D &buffer)
void printSelected()
void dataChanged()
Classes which inherit from FWTableManagerBase must call this when their underlying data changes...
int getFirstSelectedTableIndex()
void UnHighlighted() override
static const G4AffineTransform & GetTransform(const G4TouchableHistory *touchable, int depth)
FWGeoTopNodeGLScene * m_scene
Definition: FWGeoTopNode.h:66
void UnSelected() override
UChar_t wrapTransparency(FWGeometryTableManagerBase::NodeInfo &data, bool leafNode)
double f[11][100]
void EraseFromSet(std::set< TGLPhysicalShape *> &sset, TGLPhysicalShape *id)
Definition: FWGeoTopNode.cc:57
FWPopupMenu * setPopupMenu(int iX, int iY, TGLViewer *v, bool)
void ProcessSelection(TGLSelectRecord &rec, std::set< TGLPhysicalShape *> &sset, TGLPhysicalShape *id)
Definition: FWGeoTopNode.cc:88
#define fwLog(_level_)
Definition: fwLog.h:45
virtual FWGeometryTableViewBase * browser()
Definition: FWGeoTopNode.h:69
bool selectPhysicalFromTable(int)
static TGLViewer * s_pickedViewer
Definition: FWGeoTopNode.h:88
std::set< TGLPhysicalShape * > fHted
Definition: FWGeoTopNode.h:71
void paintShape(Int_t idx, const TGeoHMatrix &nm, bool volumeColor, bool parentNode)
char data[epos_bytes_allocation]
Definition: EPOS_Wrapper.h:80
void Paint(Option_t *option="") override
void SetStateOf(TGLPhysicalShape *id)
Definition: FWGeoTopNode.cc:71
static int tableIdx(TGLPhysicalShape *ps)
Definition: FWGeoTopNode.cc:55
void ComputeBBox() override
static TGLVector3 s_pickedCamera3DCenter
Definition: FWGeoTopNode.h:87
void setupBuffMtx(TBuffer3D &buff, const TGeoHMatrix &mat)
static UInt_t phyID(int tableIdx)
Definition: FWGeoTopNode.cc:53