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