0033661: Data Exchange, Step Import - Tessellated GDTs are not imported
[occt.git] / src / XCAFPrs / XCAFPrs_DocumentExplorer.cxx
CommitLineData
fc552d84 1// Author: Kirill Gavrilov
2// Copyright (c) 2017-2019 OPEN CASCADE SAS
3//
4// This file is part of Open CASCADE Technology software library.
5//
6// This library is free software; you can redistribute it and/or modify it under
7// the terms of the GNU Lesser General Public License version 2.1 as published
8// by the Free Software Foundation, with special exception defined in the file
9// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
10// distribution for complete text of the license and disclaimer of any warranty.
11//
12// Alternatively, this file may be used under the terms of Open CASCADE
13// commercial license or contractual agreement.
14
15#include <XCAFPrs_DocumentExplorer.hxx>
16
17#include <TDF_Tool.hxx>
18#include <TDocStd_Document.hxx>
19#include <XCAFDoc_ColorTool.hxx>
20#include <XCAFDoc_DocumentTool.hxx>
21#include <XCAFDoc_ShapeTool.hxx>
a14f2b47 22#include <XCAFDoc_VisMaterialTool.hxx>
fc552d84 23#include <XCAFPrs_DocumentIdIterator.hxx>
24
25namespace
26{
27 //! Return merged style for the child node.
28 static XCAFPrs_Style mergedStyle (const Handle(XCAFDoc_ColorTool)& theColorTool,
a14f2b47 29 const Handle(XCAFDoc_VisMaterialTool)& theVisMatTool,
fc552d84 30 const XCAFPrs_Style& theParenStyle,
31 const TDF_Label& theLabel,
32 const TDF_Label& theRefLabel)
33 {
34 if (theColorTool.IsNull())
35 {
36 return theParenStyle;
37 }
38
39 XCAFPrs_Style aStyle = theParenStyle;
a14f2b47 40 if (Handle(XCAFDoc_VisMaterial) aVisMat = theVisMatTool->GetShapeMaterial (theRefLabel))
41 {
42 aStyle.SetMaterial (aVisMat);
43 }
fc552d84 44 Quantity_ColorRGBA aColor;
45 if (theColorTool->GetColor (theRefLabel, XCAFDoc_ColorGen, aColor))
46 {
47 aStyle.SetColorCurv (aColor.GetRGB());
48 aStyle.SetColorSurf (aColor);
49 }
50 if (theColorTool->GetColor (theRefLabel, XCAFDoc_ColorSurf, aColor))
51 {
52 aStyle.SetColorSurf (aColor);
53 }
54 if (theColorTool->GetColor (theRefLabel, XCAFDoc_ColorCurv, aColor))
55 {
56 aStyle.SetColorCurv (aColor.GetRGB());
57 }
58
59 if (theLabel != theRefLabel)
60 {
61 // override Reference style with Instance style when defined (bad model?)
a14f2b47 62 if (Handle(XCAFDoc_VisMaterial) aVisMat = theVisMatTool->GetShapeMaterial (theLabel))
63 {
64 aStyle.SetMaterial (aVisMat);
65 }
fc552d84 66 if (theColorTool->GetColor (theLabel, XCAFDoc_ColorGen, aColor))
67 {
68 aStyle.SetColorCurv (aColor.GetRGB());
69 aStyle.SetColorSurf (aColor);
70 }
71 if (theColorTool->GetColor (theLabel, XCAFDoc_ColorSurf, aColor))
72 {
73 aStyle.SetColorSurf (aColor);
74 }
75 if (theColorTool->GetColor (theLabel, XCAFDoc_ColorCurv, aColor))
76 {
77 aStyle.SetColorCurv (aColor.GetRGB());
78 }
79 }
80
81 return aStyle;
82 }
83}
84
85// =======================================================================
86// function : DefineChildId
87// purpose :
88// =======================================================================
89TCollection_AsciiString XCAFPrs_DocumentExplorer::DefineChildId (const TDF_Label& theLabel,
90 const TCollection_AsciiString& theParentId)
91{
92 TCollection_AsciiString anEntryId;
93 TDF_Tool::Entry (theLabel, anEntryId);
94 return !theParentId.IsEmpty()
95 ? theParentId + "/" + anEntryId + "."
96 : anEntryId + ".";
97}
98
99// =======================================================================
100// function : FindLabelFromPathId
101// purpose :
102// =======================================================================
103TDF_Label XCAFPrs_DocumentExplorer::FindLabelFromPathId (const Handle(TDocStd_Document)& theDocument,
104 const TCollection_AsciiString& theId,
105 TopLoc_Location& theParentLocation,
106 TopLoc_Location& theLocation)
107{
108 theParentLocation = TopLoc_Location();
109 theLocation = TopLoc_Location();
110 TDF_Label anInstanceLabel;
111 for (XCAFPrs_DocumentIdIterator anPathIter (theId); anPathIter.More();)
112 {
113 TDF_Label aSubLabel;
114 {
115 const TCollection_AsciiString& anOcafId = anPathIter.Value();
116 TDF_Tool::Label (theDocument->Main().Data(), anOcafId, aSubLabel);
117 if (aSubLabel.IsNull())
118 {
119 return TDF_Label();
120 }
121 }
122
123 anPathIter.Next();
124 if (!anPathIter.More())
125 {
126 theParentLocation = theLocation;
127 }
128
129 TopLoc_Location aLocTrsf = XCAFDoc_ShapeTool::GetLocation (aSubLabel);
130 theLocation = theLocation * aLocTrsf;
131 anInstanceLabel = aSubLabel;
132 }
133 return anInstanceLabel;
134}
135
136// =======================================================================
137// function : FindShapeFromPathId
138// purpose :
139// =======================================================================
140TopoDS_Shape XCAFPrs_DocumentExplorer::FindShapeFromPathId (const Handle(TDocStd_Document)& theDocument,
141 const TCollection_AsciiString& theId)
142{
143 TopLoc_Location aLocation;
144 TDF_Label anInstanceLabel = FindLabelFromPathId (theDocument, theId, aLocation);
145 if (anInstanceLabel.IsNull())
146 {
147 return TopoDS_Shape();
148 }
149
150 TDF_Label aRefLabel = anInstanceLabel;
151 XCAFDoc_ShapeTool::GetReferredShape (anInstanceLabel, aRefLabel);
152 if (aRefLabel.IsNull())
153 {
154 return TopoDS_Shape();
155 }
156
157 TopoDS_Shape aShape = XCAFDoc_ShapeTool::GetShape (aRefLabel);
158 if (aShape.IsNull())
159 {
160 return TopoDS_Shape();
161 }
162
163 aShape.Location (aLocation);
164 return aShape;
165}
166
167// =======================================================================
168// function : XCAFPrs_DocumentExplorer
169// purpose :
170// =======================================================================
171XCAFPrs_DocumentExplorer::XCAFPrs_DocumentExplorer()
172: myTop (-1),
173 myHasMore (Standard_False),
174 myFlags (XCAFPrs_DocumentExplorerFlags_None)
175{
176 //
177}
178
179// =======================================================================
180// function : XCAFPrs_DocumentExplorer
181// purpose :
182// =======================================================================
183XCAFPrs_DocumentExplorer::XCAFPrs_DocumentExplorer (const Handle(TDocStd_Document)& theDocument,
184 const XCAFPrs_DocumentExplorerFlags theFlags,
185 const XCAFPrs_Style& theDefStyle)
186: myTop (-1),
187 myHasMore (Standard_False),
188 myFlags (XCAFPrs_DocumentExplorerFlags_None)
189{
190 Handle(XCAFDoc_ShapeTool) aShapeTool = XCAFDoc_DocumentTool::ShapeTool (theDocument->Main());
191 TDF_LabelSequence aRootLabels;
192 aShapeTool->GetFreeShapes (aRootLabels);
193 Init (theDocument, aRootLabels, theFlags, theDefStyle);
194}
195
196// =======================================================================
197// function : XCAFPrs_DocumentExplorer
198// purpose :
199// =======================================================================
200XCAFPrs_DocumentExplorer::XCAFPrs_DocumentExplorer (const Handle(TDocStd_Document)& theDocument,
201 const TDF_LabelSequence& theRoots,
202 const XCAFPrs_DocumentExplorerFlags theFlags,
203 const XCAFPrs_Style& theDefStyle)
204: myTop (-1),
205 myHasMore (Standard_False),
206 myFlags (XCAFPrs_DocumentExplorerFlags_None)
207{
208 Init (theDocument, theRoots, theFlags, theDefStyle);
209}
210
211// =======================================================================
212// function : Init
213// purpose :
214// =======================================================================
215void XCAFPrs_DocumentExplorer::Init (const Handle(TDocStd_Document)& theDocument,
216 const TDF_Label& theRoot,
217 const XCAFPrs_DocumentExplorerFlags theFlags,
218 const XCAFPrs_Style& theDefStyle)
219{
220 TDF_LabelSequence aSeq;
221 aSeq.Append (theRoot);
222 Init (theDocument, aSeq, theFlags, theDefStyle);
223}
224
225// =======================================================================
226// function : Init
227// purpose :
228// =======================================================================
229void XCAFPrs_DocumentExplorer::Init (const Handle(TDocStd_Document)& theDocument,
230 const TDF_LabelSequence& theRoots,
231 const XCAFPrs_DocumentExplorerFlags theFlags,
232 const XCAFPrs_Style& theDefStyle)
233{
f6abd02c 234 if ((theFlags & XCAFPrs_DocumentExplorerFlags_NoStyle) == 0)
fc552d84 235 {
236 myColorTool = XCAFDoc_DocumentTool::ColorTool (theDocument->Main());
a14f2b47 237 myVisMatTool = XCAFDoc_DocumentTool::VisMaterialTool (theDocument->Main());
fc552d84 238 }
239 else
240 {
241 myColorTool.Nullify();
a14f2b47 242 myVisMatTool.Nullify();
fc552d84 243 }
244
fc552d84 245 myDefStyle = theDefStyle;
246 myRoots = theRoots;
247 myRootIter = TDF_LabelSequence::Iterator (myRoots);
248 myFlags = theFlags;
249 initRoot();
250}
251
252// =======================================================================
253// function : initRoot
254// purpose :
255// =======================================================================
256void XCAFPrs_DocumentExplorer::initRoot()
257{
258 for (;;)
259 {
260 // reset the stack
261 for (Standard_Integer aStackIter = 0; aStackIter <= myTop; ++aStackIter)
262 {
263 myNodeStack.SetValue (aStackIter, XCAFPrs_DocumentNode());
264 }
265 myTop = -1;
266 if (!myRootIter.More())
267 {
268 myHasMore = Standard_False;
269 initCurrent (Standard_False);
270 return;
271 }
272
273 const TDF_Label& aRootLab = myRootIter.Value();
274 if (aRootLab.IsNull())
275 {
276 // assert - invalid input
f6abd02c 277 //Standard_ProgramError::Raise ("XCAFPrs_DocumentExplorer - NULL label in the input");
fc552d84 278 myRootIter.Next();
279 continue;
280 }
281
282 myHasMore = Standard_True;
283 TDF_Label aRefLabel = aRootLab;
284 XCAFDoc_ShapeTool::GetReferredShape (aRootLab, aRefLabel);
285 if (XCAFDoc_ShapeTool::IsAssembly (aRefLabel))
286 {
287 Next();
288 }
289 else
290 {
291 initCurrent (Standard_False);
292 }
293 return;
294 }
295}
296
297// =======================================================================
298// function : initCurrent
299// purpose :
300// =======================================================================
2641792e 301void XCAFPrs_DocumentExplorer::initCurrent (Standard_Boolean theIsAssembly)
fc552d84 302{
303 myCurrent = XCAFPrs_DocumentNode();
2641792e 304 if (theIsAssembly)
fc552d84 305 {
306 if (myTop < 0)
307 {
f6abd02c 308 Standard_ProgramError::Raise ("XCAFPrs_DocumentExplorer - internal error");
fc552d84 309 }
310 myCurrent = myNodeStack.Value (myTop);
311 }
312 else if (myTop < 0)
313 {
314 if (!myRootIter.More())
315 {
316 return;
317 }
318
319 myCurrent.Label = myRootIter.Value();
320 myCurrent.RefLabel = myCurrent.Label;
321 XCAFDoc_ShapeTool::GetReferredShape (myCurrent.Label, myCurrent.RefLabel);
322 myCurrent.LocalTrsf= XCAFDoc_ShapeTool::GetLocation (myCurrent.Label);
323 myCurrent.Location = myCurrent.LocalTrsf;
a14f2b47 324 myCurrent.Style = mergedStyle (myColorTool, myVisMatTool, myDefStyle, myCurrent.Label, myCurrent.RefLabel);
fc552d84 325 myCurrent.Id = DefineChildId (myCurrent.Label, TCollection_AsciiString());
326 }
327 else
328 {
329 const XCAFPrs_DocumentNode& aTopNodeInStack = myNodeStack.Value (myTop);
330 myCurrent.Label = aTopNodeInStack.ChildIter.Value();
331 myCurrent.RefLabel = myCurrent.Label;
332 XCAFDoc_ShapeTool::GetReferredShape (myCurrent.Label, myCurrent.RefLabel);
333 myCurrent.LocalTrsf= XCAFDoc_ShapeTool::GetLocation (myCurrent.Label);
334 myCurrent.Location = aTopNodeInStack.Location * myCurrent.LocalTrsf;
a14f2b47 335 myCurrent.Style = mergedStyle (myColorTool, myVisMatTool, aTopNodeInStack.Style, myCurrent.Label, myCurrent.RefLabel);
fc552d84 336 myCurrent.Id = DefineChildId (myCurrent.Label, aTopNodeInStack.Id);
337 }
338}
339
340// =======================================================================
341// function : Next
342// purpose :
343// =======================================================================
344void XCAFPrs_DocumentExplorer::Next()
345{
346 if (!myHasMore)
347 {
f6abd02c 348 Standard_ProgramError::Raise ("XCAFPrs_DocumentExplorer::Next() - out of range");
fc552d84 349 return; // assert
350 }
351
352 if (myTop < 0)
353 {
354 const TDF_Label& aRootLab = myRootIter.Value();
355 TDF_Label aRefLabel = aRootLab;
356 XCAFDoc_ShapeTool::GetReferredShape (aRootLab, aRefLabel);
357 if (!XCAFDoc_ShapeTool::IsAssembly (aRefLabel))
358 {
359 // already visited once
360 myRootIter.Next();
361 initRoot();
362 return;
363 }
364
365 // push and try to find
366 myTop = 0;
367 XCAFPrs_DocumentNode aNodeInStack;
368 aNodeInStack.IsAssembly = Standard_True;
369 aNodeInStack.Label = aRootLab;
370 aNodeInStack.RefLabel = aRefLabel;
371 aNodeInStack.ChildIter = TDF_ChildIterator (aNodeInStack.RefLabel);
372 aNodeInStack.LocalTrsf = XCAFDoc_ShapeTool::GetLocation (aNodeInStack.Label);
373 aNodeInStack.Location = aNodeInStack.LocalTrsf;
a14f2b47 374 aNodeInStack.Style = mergedStyle (myColorTool, myVisMatTool, myDefStyle, aNodeInStack.Label, aNodeInStack.RefLabel);
fc552d84 375 aNodeInStack.Id = DefineChildId (aNodeInStack.Label, TCollection_AsciiString());
376 myNodeStack.SetValue (0, aNodeInStack);
377 if ((myFlags & XCAFPrs_DocumentExplorerFlags_OnlyLeafNodes) == 0)
378 {
379 initCurrent (Standard_True);
380 return;
381 }
382 }
383 else
384 {
385 if (!myCurrent.IsAssembly)
386 {
387 myNodeStack.ChangeValue (myTop).ChildIter.Next();
388 }
389 }
390
391 for (;;)
392 {
393 if (myNodeStack.Value (myTop).ChildIter.More())
394 {
395 const TDF_Label& aNodeTop = myNodeStack.Value (myTop).ChildIter.Value();
396 if (aNodeTop.IsNull()
397 || (!aNodeTop.HasChild() && !aNodeTop.HasAttribute()))
398 {
399 myNodeStack.ChangeValue (myTop).ChildIter.Next();
400 continue;
401 }
402
403 TDF_Label aRefLabel = aNodeTop;
404 XCAFDoc_ShapeTool::GetReferredShape (aNodeTop, aRefLabel);
405 if (!XCAFDoc_ShapeTool::IsAssembly (aRefLabel))
406 {
407 myHasMore = Standard_True;
408 initCurrent (Standard_False);
409 return;
410 }
411 else if (aRefLabel.HasAttribute()
412 || aRefLabel.HasChild())
413 {
414 const XCAFPrs_DocumentNode& aParent = myNodeStack.Value (myTop);
415 ++myTop;
416
417 XCAFPrs_DocumentNode aNodeInStack;
418 aNodeInStack.IsAssembly = Standard_True;
419 aNodeInStack.Label = aNodeTop;
420 aNodeInStack.RefLabel = aRefLabel;
421 aNodeInStack.LocalTrsf = XCAFDoc_ShapeTool::GetLocation (aNodeInStack.Label);
422 aNodeInStack.Location = aParent.Location * aNodeInStack.LocalTrsf;
a14f2b47 423 aNodeInStack.Style = mergedStyle (myColorTool, myVisMatTool, aParent.Style, aNodeInStack.Label, aNodeInStack.RefLabel);
fc552d84 424 aNodeInStack.Id = DefineChildId (aNodeInStack.Label, aParent.Id);
425 aNodeInStack.ChildIter = TDF_ChildIterator (aNodeInStack.RefLabel);
426 myNodeStack.SetValue (myTop, aNodeInStack);
427 if ((myFlags & XCAFPrs_DocumentExplorerFlags_OnlyLeafNodes) == 0)
428 {
429 initCurrent (Standard_True);
430 return;
431 }
432 }
433 else
434 {
435 myNodeStack.ChangeValue (myTop).ChildIter.Next();
436 }
437 }
438 else
439 {
440 myNodeStack.SetValue (myTop, XCAFPrs_DocumentNode());
441 --myTop;
442 if (myTop < 0)
443 {
444 myRootIter.Next();
445 initRoot();
446 return;
447 }
448
449 myNodeStack.ChangeValue (myTop).ChildIter.Next();
450 }
451 }
452}