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