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