Logo ROOT   6.14/05
Reference Guide
TOCCToStep.cxx
Go to the documentation of this file.
1 // @(#)geom/geocad:$Id$
2 // Author: Cinzia Luzzi 5/5/2012
3 
4 /*************************************************************************
5  * Copyright (C) 1995-2012, Rene Brun and Fons Rademakers. *
6  * All rights reserved. *
7  * *
8  * For the licensing terms see $ROOTSYS/LICENSE. *
9  * For the list of contributors see $ROOTSYS/README/CREDITS. *
10  *************************************************************************/
11 
12 /** \class TOCCToStep
13 \ingroup Geometry_cad
14 
15 This class contains implementation of writing OpenCascade's
16 geometry shapes to the STEP file reproducing the original ROOT
17 geometry tree. The TRootStep Class takes a gGeoManager pointer and
18 gives back a STEP file.
19 The OCCShapeCreation(TGeoManager *m) method starting from
20 the top of the ROOT geometry tree translates each ROOT shape in the
21 OCC one. A fLabel is created for each OCC shape and the
22 correspondance between the the fLabel and the shape is saved
23 in a map. The OCCTreeCreation(TGeoManager *m) method starting from
24 the top of the ROOT geometry and using the fLabel-shape map
25 reproduce the ROOT tree that will be written to the STEP file using
26 the OCCWriteStep(const char * fname ) method.
27 
28 */
29 #include "TOCCToStep.h"
30 #include "TGeoToOCC.h"
31 
32 #include "TGeoVolume.h"
33 #include "TString.h"
34 #include "TClass.h"
35 #include "TGeoManager.h"
36 #include "TError.h"
37 
38 #include <Interface_Static.hxx>
39 #include <BRepBuilderAPI_Transform.hxx>
40 #include <TDataStd_Name.hxx>
41 #include <XCAFDoc_DocumentTool.hxx>
42 #include <Standard.hxx>
43 #include <stdlib.h>
44 #include <XCAFApp_Application.hxx>
45 
46 using namespace std;
47 
48 
49 ////////////////////////////////////////////////////////////////////////////////
50 
52 {
53  OCCDocCreation();
54 }
55 
56 ////////////////////////////////////////////////////////////////////////////////
57 
59 {
60  Handle (XCAFApp_Application)A = XCAFApp_Application::GetApplication();
61  if (!A.IsNull()) {
62  A->NewDocument ("MDTV-XCAF", fDoc);
63  }
64  else
65  ::Error("TOCCToStep::OCCDocCreation", "creating OCC application");
66 }
67 
68 ////////////////////////////////////////////////////////////////////////////////
69 /// Logical fTree creation.
70 
72 {
73  TDF_Label motherLabel;
74  TGeoVolume * currentVolume;
75  TGeoVolume * motherVol;
76  TGeoVolume * Top;
77  TString path;
78  Int_t num = 0;
79  Int_t level = 0;
80  TIter next(m->GetListOfVolumes());
81  fLabel = XCAFDoc_DocumentTool::ShapeTool(fDoc->Main())->NewShape();
82  fShape = fRootShape.OCC_SimpleShape(m->GetTopVolume()->GetShape());
83  XCAFDoc_DocumentTool::ShapeTool(fDoc->Main())->SetShape(fLabel, fShape);
84  TDataStd_Name::Set(fLabel, m->GetTopVolume()->GetName());
85  XCAFDoc_DocumentTool::ShapeTool(fDoc->Main())->UpdateAssembly(fDoc->Main());
86  Top = m->GetTopVolume();
87  fTree[Top] = fLabel;
88  while ((currentVolume = (TGeoVolume *)next())) {
89  if (GetLabelOfVolume(currentVolume).IsNull()) {
90  //num = currentVolume->GetNdaughters();
91  if ((GetLabelOfVolume(currentVolume).IsNull())) {
92  if (currentVolume->GetShape()->IsA()==TGeoCompositeShape::Class()) {
93  fShape = fRootShape.OCC_CompositeShape((TGeoCompositeShape*)currentVolume->GetShape(), TGeoIdentity());
94  } else {
95  fShape = fRootShape.OCC_SimpleShape(currentVolume->GetShape());
96  }
97  }
98  TGeoNode *current;
99  TGeoIterator nextNode(m->GetTopVolume());
100  while ((current = nextNode())) {
101  if ((current->GetVolume() == currentVolume) && (GetLabelOfVolume(current->GetVolume()).IsNull())) {
102  level = nextNode.GetLevel();
103  nextNode.GetPath(path);
104  if (level == 1)
105  motherVol = m->GetTopVolume();
106  else {
107  TGeoNode * mother = nextNode.GetNode(--level);
108  motherVol = mother->GetVolume();
109  }
110  motherLabel = GetLabelOfVolume(motherVol);
111  if (!motherLabel.IsNull()) {
112  fLabel = TDF_TagSource::NewChild(motherLabel);
113  break;
114  } else {
115  TGeoNode * grandMother = nextNode.GetNode(level);
116  motherVol = grandMother->GetVolume();
117  TopoDS_Shape Mothershape;
118  if (motherVol->GetShape()->IsA()==TGeoCompositeShape::Class()) {
119  Mothershape = fRootShape.OCC_CompositeShape((TGeoCompositeShape*)motherVol->GetShape(), TGeoIdentity());
120  } else {
121  Mothershape = fRootShape.OCC_SimpleShape(motherVol->GetShape());
122  }
123  motherLabel = TDF_TagSource::NewChild(GetLabelOfVolume(Top));
124  XCAFDoc_DocumentTool::ShapeTool(fDoc->Main())->SetShape(motherLabel, Mothershape);
125  TDataStd_Name::Set(motherLabel, motherVol->GetName());
126  XCAFDoc_DocumentTool::ShapeTool(fDoc->Main())->UpdateAssembly(fDoc->Main());
127  fTree[motherVol] = motherLabel;
128  fLabel = TDF_TagSource::NewChild(motherLabel);
129  break;
130  }
131  }
132  }
133  XCAFDoc_DocumentTool::ShapeTool(fDoc->Main())->SetShape(fLabel, fShape);
134  TDataStd_Name::Set(fLabel, currentVolume->GetName());
135  XCAFDoc_DocumentTool::ShapeTool(fDoc->Main())->UpdateAssembly(fDoc->Main());
136  fTree[currentVolume] = fLabel;
137  }
138  }
139  return fLabel;
140 }
141 
142 ////////////////////////////////////////////////////////////////////////////////
143 
144 void TOCCToStep::OCCWriteStep(const char *fname)
145 {
146  STEPControl_StepModelType mode = STEPControl_AsIs;
147  fWriter.SetNameMode(Standard_True);
148  if (!Interface_Static::SetIVal("write.step.assembly", 1)) { //assembly mode
149  Error("TOCCToStep::OCCWriteStep", "failed to set assembly mode for step data");
150  }
151  if (!fWriter.Transfer(fDoc, mode)) {
152  ::Error("TOCCToStep::OCCWriteStep", "error translating document");
153  }
154  fWriter.Write(fname);
155 }
156 
157 ////////////////////////////////////////////////////////////////////////////////
158 
160 {
161  TDF_Label null;
162  if (fTree.find(v) != fTree.end())
163  return fTree[v];
164  else
165  return null;
166 }
167 
168 ////////////////////////////////////////////////////////////////////////////////
169 
171 {
172  map <TGeoVolume *,TDF_Label>::iterator it;
173  for(it = fTree.begin(); it != fTree.end(); ++it)
174  if (it->second.IsEqual(fLabel))
175  return it->first;
176  return 0;
177 }
178 
179 ////////////////////////////////////////////////////////////////////////////////
180 
181 void TOCCToStep::AddChildLabel(TDF_Label mother, TDF_Label child, TopLoc_Location loc)
182 {
183  XCAFDoc_DocumentTool::ShapeTool(mother)->AddComponent(mother, child,loc);
184  XCAFDoc_DocumentTool::ShapeTool(mother)->UpdateAssembly(mother);
185 }
186 
187 ////////////////////////////////////////////////////////////////////////////////
188 
189 TopLoc_Location TOCCToStep::CalcLocation (TGeoHMatrix matrix)
190 {
191  gp_Trsf TR,TR1;
192  TopLoc_Location locA;
193  Double_t const *t=matrix.GetTranslation();
194  Double_t const *r=matrix.GetRotationMatrix();
195  TR1.SetTranslation(gp_Vec(t[0],t[1],t[2]));
196  TR.SetValues(r[0],r[1],r[2],0,
197  r[3],r[4],r[5],0,
198  r[6],r[7],r[8],0
199 #if OCC_VERSION_MAJOR == 6 && OCC_VERSION_MINOR < 8
200  ,0,1
201 #endif
202  );
203  TR1.Multiply(TR);
204  locA = TopLoc_Location (TR1);
205  return locA;
206 }
207 
208 ////////////////////////////////////////////////////////////////////////////////
209 
211 {
212  TGeoIterator nextNode(m->GetTopVolume());
213  TGeoNode *currentNode = 0;
214  TGeoNode *motherNode = 0;
215  //TGeoNode *gmotherNode = 0;
216  Int_t level;
217  TDF_Label labelMother;
218  TopLoc_Location loc;
219  Int_t nd;
220 
221  while ((currentNode = nextNode())) {
222  level = nextNode.GetLevel();
223  if( level > max_level ){
224  continue;
225  }
226  // This loop looks for nodes which are the end of line (ancestrally) then navigates
227  // back up the family tree. As it does so, the OCC tree is constructed.
228  // It is not clear why it must be done this way, but it could be an idiosyncracy
229  // in OCC (which I am not too familar with at the moment).
230  nd = currentNode->GetNdaughters();
231  if (!nd) {
232  for (int i = level; i > 0; i--) {
233  if (i == 1) {
234  motherNode = m->GetTopNode();
235  } else {
236  motherNode = nextNode.GetNode(--level);
237  }
238  labelMother = GetLabelOfVolume(motherNode->GetVolume());
239  Int_t ndMother = motherNode->GetNdaughters();
240  fLabel = GetLabelOfVolume(currentNode->GetVolume());
241  loc = CalcLocation((*(currentNode->GetMatrix())));
242  if ((XCAFDoc_DocumentTool::ShapeTool(fDoc->Main())->NbComponents(labelMother) < ndMother) && (!nd)) {
243  AddChildLabel(labelMother, fLabel, loc);
244  } else if ((XCAFDoc_DocumentTool::ShapeTool(fDoc->Main())->NbComponents(fLabel) == nd) &&
245  (XCAFDoc_DocumentTool::ShapeTool(fDoc->Main())->NbComponents(labelMother) == motherNode->GetVolume()->GetIndex(currentNode))) {
246  AddChildLabel(labelMother, fLabel, loc);
247  }
248  currentNode = motherNode;
249  fLabel = labelMother;
250  nd = currentNode->GetNdaughters();
251  }
252  }
253  }
254 }
255  //______________________________________________________________________________
256 
257 bool TOCCToStep::OCCPartialTreeCreation(TGeoManager * m, const char* node_name, int max_level)
258 {
259  TGeoIterator nextNode(m->GetTopVolume());
260  std::string search_n = node_name;
261  bool found_once = false;
262  bool found_in_level_1 = false;
263  auto volume = m->GetVolume(node_name);
264  int level1_skipped = 0;
265  TGeoNode* currentNode = 0;
266 
267  nextNode.SetType(0);
268  while ((currentNode = nextNode())) {
269  nextNode.SetType(0);
270  int level = nextNode.GetLevel();
271  if( level > max_level ){
272  continue;
273  }
274  if(level == 1) {
275  found_in_level_1 = false;
276  if( volume == currentNode->GetVolume() ) {
277  found_in_level_1 = true;
278  found_once = true;
279  }
280  }
281  if(!found_in_level_1) {
282  if(level == 1) {
283  level1_skipped++;
284  }
285  nextNode.SetType(1);
286  continue;
287  }
288  FillOCCWithNode(m, currentNode, nextNode, level, max_level, level1_skipped);
289  }
290  return found_once;
291 }
292  //______________________________________________________________________________
293 
294 bool TOCCToStep::OCCPartialTreeCreation(TGeoManager * m, std::map<std::string,int> part_name_levels)
295 {
296  bool found_once = false;
297  bool found_in_level_1 = false;
298  int level1_skipped = 0;
299 
300  std::map<TGeoVolume*,std::string> part_name_vols;
301  std::vector<TGeoVolume*> vols;
302 
303  for(const auto& pl : part_name_levels) {
304  TGeoVolume* avol = m->GetVolume(pl.first.c_str());
305  part_name_vols[avol] = pl.first;
306  vols.push_back(avol);
307  }
308 
309  TGeoIterator nextNode(m->GetTopVolume());
310  TGeoNode* currentNode = nullptr;
311  TGeoVolume* matched_vol = nullptr;
312 
313  nextNode.SetType(0);
314  while ((currentNode = nextNode())) {
315  nextNode.SetType(0);
316  int level = nextNode.GetLevel();
317 
318  // Currently we only isolate level 1 node/volumes.
319  // In the future this could be generalized.
320  if(level == 1) {
321  found_in_level_1 = false;
322  for(auto v: vols) {
323  if( v == currentNode->GetVolume() ) {
324  // could there be more than one?
325  matched_vol = v;
326  found_in_level_1 = true;
327  found_once = true;
328  }
329  }
330  }
331  if(!found_in_level_1) {
332  if(level == 1) {
333  level1_skipped++;
334  }
335  // switch the iterator type to go directly to sibling nodes
336  nextNode.SetType(1);
337  continue;
338  }
339  int max_level = part_name_levels[ part_name_vols[matched_vol]];
340  if( level > max_level ){
341  continue;
342  }
343 
344  FillOCCWithNode(m, currentNode, nextNode, level, max_level, level1_skipped);
345  }
346  return found_once;
347 }
348  //______________________________________________________________________________
349 
350 
351 void TOCCToStep::FillOCCWithNode(TGeoManager* m, TGeoNode* currentNode, TGeoIterator& nextNode, int level, int max_level, int level1_skipped)
352 {
353  // This loop looks for nodes which are the end of line (ancestrally) then navigates
354  // back up the family tree. As it does so, the OCC tree is constructed.
355  // It is not clear why it must be done this way, but it could be an idiosyncracy
356  // in OCC (which I am not too familar with at the moment).
357  int nd = currentNode->GetNdaughters();
358  if(level == max_level) {
359  nd = 0;
360  }
361  if( nd == 0 ) {
362  int level_start = std::min(level,max_level);
363  for (int i = level_start; i > 0; i--) {
364  TGeoNode* motherNode = 0;
365  TDF_Label labelMother;
366  TopLoc_Location loc;
367 
368  if (i == 1) {
369  motherNode = m->GetTopNode();
370  } else {
371  motherNode = nextNode.GetNode(i-1);
372  }
373  labelMother = GetLabelOfVolume(motherNode->GetVolume());
374  Int_t ndMother = motherNode->GetNdaughters();
375  // Why are we using a data member here?
376  fLabel = GetLabelOfVolume(currentNode->GetVolume());
377  loc = CalcLocation((*(currentNode->GetMatrix())));
378  // Need to account for the missing daughters from those nodes skipped in level 1
379  int skipped_this_level = 0;
380  if(i == 1 ) skipped_this_level = level1_skipped;
381  if ((XCAFDoc_DocumentTool::ShapeTool(fDoc->Main())->NbComponents(labelMother) < ndMother) && (!nd)) {
382 
383  AddChildLabel(labelMother, fLabel, loc);
384  } else if ((XCAFDoc_DocumentTool::ShapeTool(fDoc->Main())->NbComponents(fLabel) == currentNode->GetNdaughters()) &&
385  (XCAFDoc_DocumentTool::ShapeTool(fDoc->Main())->NbComponents(labelMother)+skipped_this_level == motherNode->GetVolume()->GetIndex(currentNode))) {
386  AddChildLabel(labelMother, fLabel, loc);
387  }
388  currentNode = motherNode;
389  fLabel = labelMother; // again, why a data member?
390  nd = currentNode->GetNdaughters();
391  }
392  }
393 }
394 ////////////////////////////////////////////////////////////////////////////////
395 
397 {
398 #if OCC_VERSION_MAJOR == 6 && OCC_VERSION_MINOR < 8
399  XCAFDoc_DocumentTool::ShapeTool(fDoc->Main())->Dump();
400 #else
401  XCAFDoc_DocumentTool::ShapeTool(fDoc->Main())->Dump(std::cout);
402 #endif
403 }
404 
405 
virtual const char * GetName() const
Returns name of object.
Definition: TNamed.h:47
The manager class for any TGeo geometry.
Definition: TGeoManager.h:38
auto * m
Definition: textangle.C:8
void FillOCCWithNode(TGeoManager *m, TGeoNode *currentNode, TGeoIterator &nextNode, int level, int max_level, int level1_skipped)
Definition: TOCCToStep.cxx:351
void OCCWriteStep(const char *fname)
Definition: TOCCToStep.cxx:144
virtual const Double_t * GetRotationMatrix() const
Definition: TGeoMatrix.h:468
virtual const Double_t * GetTranslation() const
Definition: TGeoMatrix.h:467
An identity transformation.
Definition: TGeoMatrix.h:383
TGeoVolume, TGeoVolumeMulti, TGeoVolumeAssembly are the volume classes.
Definition: TGeoVolume.h:48
TGeoVolume * GetVolume(const char *name) const
Search for a named volume. All trailing blanks stripped.
void AddChildLabel(TDF_Label mother, TDF_Label child, TopLoc_Location loc)
Definition: TOCCToStep.cxx:181
TGeoVolume * GetVolumeOfLabel(TDF_Label fLabel)
Definition: TOCCToStep.cxx:170
Matrix class used for computing global transformations Should NOT be used for node definition...
Definition: TGeoMatrix.h:420
int Int_t
Definition: RtypesCore.h:41
TGeoNode * GetNode(Int_t level) const
Returns current node at a given level.
Definition: TGeoNode.cxx:1172
STL namespace.
void PrintAssembly()
Definition: TOCCToStep.cxx:396
static double A[]
null_t< F > null()
Int_t GetLevel() const
Definition: TGeoNode.h:274
void Class()
Definition: Class.C:29
A geometry iterator.
Definition: TGeoNode.h:243
virtual TGeoMatrix * GetMatrix() const =0
void Error(const char *location, const char *msgfmt,...)
Class handling Boolean composition of shapes.
ROOT::R::TRInterface & r
Definition: Object.C:4
SVector< double, 2 > v
Definition: Dict.h:5
Int_t GetIndex(const TGeoNode *node) const
get index number for a given daughter
TGeoNode * GetTopNode() const
Definition: TGeoManager.h:504
void OCCDocCreation()
Definition: TOCCToStep.cxx:58
TopLoc_Location CalcLocation(TGeoHMatrix matrix)
Definition: TOCCToStep.cxx:189
double Double_t
Definition: RtypesCore.h:55
void OCCTreeCreation(TGeoManager *m, int max_level=-1)
Definition: TOCCToStep.cxx:210
TDF_Label OCCShapeCreation(TGeoManager *m)
Logical fTree creation.
Definition: TOCCToStep.cxx:71
A node represent a volume positioned inside another.They store links to both volumes and to the TGeoM...
Definition: TGeoNode.h:39
TObjArray * GetListOfVolumes() const
Definition: TGeoManager.h:468
TDF_Label GetLabelOfVolume(TGeoVolume *v)
Definition: TOCCToStep.cxx:159
Int_t GetNdaughters() const
Definition: TGeoNode.h:90
bool OCCPartialTreeCreation(TGeoManager *m, const char *node_name, int max_level=-1)
Definition: TOCCToStep.cxx:257
TGeoVolume * GetTopVolume() const
Definition: TGeoManager.h:503
TGeoShape * GetShape() const
Definition: TGeoVolume.h:191
TGeoVolume * GetVolume() const
Definition: TGeoNode.h:94