1 // Author: Kirill Gavrilov
2 // Copyright (c) 2017-2019 OPEN CASCADE SAS
4 // This file is part of Open CASCADE Technology software library.
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.
12 // Alternatively, this file may be used under the terms of Open CASCADE
13 // commercial license or contractual agreement.
15 #include <XCAFPrs_DocumentExplorer.hxx>
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>
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)
32 if (theColorTool.IsNull())
37 XCAFPrs_Style aStyle = theParenStyle;
38 Quantity_ColorRGBA aColor;
39 if (theColorTool->GetColor (theRefLabel, XCAFDoc_ColorGen, aColor))
41 aStyle.SetColorCurv (aColor.GetRGB());
42 aStyle.SetColorSurf (aColor);
44 if (theColorTool->GetColor (theRefLabel, XCAFDoc_ColorSurf, aColor))
46 aStyle.SetColorSurf (aColor);
48 if (theColorTool->GetColor (theRefLabel, XCAFDoc_ColorCurv, aColor))
50 aStyle.SetColorCurv (aColor.GetRGB());
53 if (theLabel != theRefLabel)
55 // override Reference style with Instance style when defined (bad model?)
56 if (theColorTool->GetColor (theLabel, XCAFDoc_ColorGen, aColor))
58 aStyle.SetColorCurv (aColor.GetRGB());
59 aStyle.SetColorSurf (aColor);
61 if (theColorTool->GetColor (theLabel, XCAFDoc_ColorSurf, aColor))
63 aStyle.SetColorSurf (aColor);
65 if (theColorTool->GetColor (theLabel, XCAFDoc_ColorCurv, aColor))
67 aStyle.SetColorCurv (aColor.GetRGB());
75 // =======================================================================
76 // function : DefineChildId
78 // =======================================================================
79 TCollection_AsciiString XCAFPrs_DocumentExplorer::DefineChildId (const TDF_Label& theLabel,
80 const TCollection_AsciiString& theParentId)
82 TCollection_AsciiString anEntryId;
83 TDF_Tool::Entry (theLabel, anEntryId);
84 return !theParentId.IsEmpty()
85 ? theParentId + "/" + anEntryId + "."
89 // =======================================================================
90 // function : FindLabelFromPathId
92 // =======================================================================
93 TDF_Label XCAFPrs_DocumentExplorer::FindLabelFromPathId (const Handle(TDocStd_Document)& theDocument,
94 const TCollection_AsciiString& theId,
95 TopLoc_Location& theParentLocation,
96 TopLoc_Location& theLocation)
98 theParentLocation = TopLoc_Location();
99 theLocation = TopLoc_Location();
100 TDF_Label anInstanceLabel;
101 for (XCAFPrs_DocumentIdIterator anPathIter (theId); anPathIter.More();)
105 const TCollection_AsciiString& anOcafId = anPathIter.Value();
106 TDF_Tool::Label (theDocument->Main().Data(), anOcafId, aSubLabel);
107 if (aSubLabel.IsNull())
114 if (!anPathIter.More())
116 theParentLocation = theLocation;
119 TopLoc_Location aLocTrsf = XCAFDoc_ShapeTool::GetLocation (aSubLabel);
120 theLocation = theLocation * aLocTrsf;
121 anInstanceLabel = aSubLabel;
123 return anInstanceLabel;
126 // =======================================================================
127 // function : FindShapeFromPathId
129 // =======================================================================
130 TopoDS_Shape XCAFPrs_DocumentExplorer::FindShapeFromPathId (const Handle(TDocStd_Document)& theDocument,
131 const TCollection_AsciiString& theId)
133 TopLoc_Location aLocation;
134 TDF_Label anInstanceLabel = FindLabelFromPathId (theDocument, theId, aLocation);
135 if (anInstanceLabel.IsNull())
137 return TopoDS_Shape();
140 TDF_Label aRefLabel = anInstanceLabel;
141 XCAFDoc_ShapeTool::GetReferredShape (anInstanceLabel, aRefLabel);
142 if (aRefLabel.IsNull())
144 return TopoDS_Shape();
147 TopoDS_Shape aShape = XCAFDoc_ShapeTool::GetShape (aRefLabel);
150 return TopoDS_Shape();
153 aShape.Location (aLocation);
157 // =======================================================================
158 // function : XCAFPrs_DocumentExplorer
160 // =======================================================================
161 XCAFPrs_DocumentExplorer::XCAFPrs_DocumentExplorer()
163 myHasMore (Standard_False),
164 myFlags (XCAFPrs_DocumentExplorerFlags_None)
169 // =======================================================================
170 // function : XCAFPrs_DocumentExplorer
172 // =======================================================================
173 XCAFPrs_DocumentExplorer::XCAFPrs_DocumentExplorer (const Handle(TDocStd_Document)& theDocument,
174 const XCAFPrs_DocumentExplorerFlags theFlags,
175 const XCAFPrs_Style& theDefStyle)
177 myHasMore (Standard_False),
178 myFlags (XCAFPrs_DocumentExplorerFlags_None)
180 Handle(XCAFDoc_ShapeTool) aShapeTool = XCAFDoc_DocumentTool::ShapeTool (theDocument->Main());
181 TDF_LabelSequence aRootLabels;
182 aShapeTool->GetFreeShapes (aRootLabels);
183 Init (theDocument, aRootLabels, theFlags, theDefStyle);
186 // =======================================================================
187 // function : XCAFPrs_DocumentExplorer
189 // =======================================================================
190 XCAFPrs_DocumentExplorer::XCAFPrs_DocumentExplorer (const Handle(TDocStd_Document)& theDocument,
191 const TDF_LabelSequence& theRoots,
192 const XCAFPrs_DocumentExplorerFlags theFlags,
193 const XCAFPrs_Style& theDefStyle)
195 myHasMore (Standard_False),
196 myFlags (XCAFPrs_DocumentExplorerFlags_None)
198 Init (theDocument, theRoots, theFlags, theDefStyle);
201 // =======================================================================
204 // =======================================================================
205 void XCAFPrs_DocumentExplorer::Init (const Handle(TDocStd_Document)& theDocument,
206 const TDF_Label& theRoot,
207 const XCAFPrs_DocumentExplorerFlags theFlags,
208 const XCAFPrs_Style& theDefStyle)
210 TDF_LabelSequence aSeq;
211 aSeq.Append (theRoot);
212 Init (theDocument, aSeq, theFlags, theDefStyle);
215 // =======================================================================
218 // =======================================================================
219 void XCAFPrs_DocumentExplorer::Init (const Handle(TDocStd_Document)& theDocument,
220 const TDF_LabelSequence& theRoots,
221 const XCAFPrs_DocumentExplorerFlags theFlags,
222 const XCAFPrs_Style& theDefStyle)
224 if ((theFlags & XCAFPrs_DocumentExplorerFlags_NoStyle) == 0)
226 myColorTool = XCAFDoc_DocumentTool::ColorTool (theDocument->Main());
230 myColorTool.Nullify();
233 myDefStyle = theDefStyle;
235 myRootIter = TDF_LabelSequence::Iterator (myRoots);
240 // =======================================================================
241 // function : initRoot
243 // =======================================================================
244 void XCAFPrs_DocumentExplorer::initRoot()
249 for (Standard_Integer aStackIter = 0; aStackIter <= myTop; ++aStackIter)
251 myNodeStack.SetValue (aStackIter, XCAFPrs_DocumentNode());
254 if (!myRootIter.More())
256 myHasMore = Standard_False;
257 initCurrent (Standard_False);
261 const TDF_Label& aRootLab = myRootIter.Value();
262 if (aRootLab.IsNull())
264 // assert - invalid input
265 //Standard_ProgramError::Raise ("XCAFPrs_DocumentExplorer - NULL label in the input");
270 myHasMore = Standard_True;
271 TDF_Label aRefLabel = aRootLab;
272 XCAFDoc_ShapeTool::GetReferredShape (aRootLab, aRefLabel);
273 if (XCAFDoc_ShapeTool::IsAssembly (aRefLabel))
279 initCurrent (Standard_False);
285 // =======================================================================
286 // function : initCurrent
288 // =======================================================================
289 void XCAFPrs_DocumentExplorer::initCurrent (Standard_Boolean theIsAssmebly)
291 myCurrent = XCAFPrs_DocumentNode();
296 Standard_ProgramError::Raise ("XCAFPrs_DocumentExplorer - internal error");
298 myCurrent = myNodeStack.Value (myTop);
302 if (!myRootIter.More())
307 myCurrent.Label = myRootIter.Value();
308 myCurrent.RefLabel = myCurrent.Label;
309 XCAFDoc_ShapeTool::GetReferredShape (myCurrent.Label, myCurrent.RefLabel);
310 myCurrent.LocalTrsf= XCAFDoc_ShapeTool::GetLocation (myCurrent.Label);
311 myCurrent.Location = myCurrent.LocalTrsf;
312 myCurrent.Style = mergedStyle (myColorTool, myDefStyle, myCurrent.Label, myCurrent.RefLabel);
313 myCurrent.Id = DefineChildId (myCurrent.Label, TCollection_AsciiString());
317 const XCAFPrs_DocumentNode& aTopNodeInStack = myNodeStack.Value (myTop);
318 myCurrent.Label = aTopNodeInStack.ChildIter.Value();
319 myCurrent.RefLabel = myCurrent.Label;
320 XCAFDoc_ShapeTool::GetReferredShape (myCurrent.Label, myCurrent.RefLabel);
321 myCurrent.LocalTrsf= XCAFDoc_ShapeTool::GetLocation (myCurrent.Label);
322 myCurrent.Location = aTopNodeInStack.Location * myCurrent.LocalTrsf;
323 myCurrent.Style = mergedStyle (myColorTool, aTopNodeInStack.Style, myCurrent.Label, myCurrent.RefLabel);
324 myCurrent.Id = DefineChildId (myCurrent.Label, aTopNodeInStack.Id);
328 // =======================================================================
331 // =======================================================================
332 void XCAFPrs_DocumentExplorer::Next()
336 Standard_ProgramError::Raise ("XCAFPrs_DocumentExplorer::Next() - out of range");
342 const TDF_Label& aRootLab = myRootIter.Value();
343 TDF_Label aRefLabel = aRootLab;
344 XCAFDoc_ShapeTool::GetReferredShape (aRootLab, aRefLabel);
345 if (!XCAFDoc_ShapeTool::IsAssembly (aRefLabel))
347 // already visited once
353 // push and try to find
355 XCAFPrs_DocumentNode aNodeInStack;
356 aNodeInStack.IsAssembly = Standard_True;
357 aNodeInStack.Label = aRootLab;
358 aNodeInStack.RefLabel = aRefLabel;
359 aNodeInStack.ChildIter = TDF_ChildIterator (aNodeInStack.RefLabel);
360 aNodeInStack.LocalTrsf = XCAFDoc_ShapeTool::GetLocation (aNodeInStack.Label);
361 aNodeInStack.Location = aNodeInStack.LocalTrsf;
362 aNodeInStack.Style = mergedStyle (myColorTool, myDefStyle, aNodeInStack.Label, aNodeInStack.RefLabel);
363 aNodeInStack.Id = DefineChildId (aNodeInStack.Label, TCollection_AsciiString());
364 myNodeStack.SetValue (0, aNodeInStack);
365 if ((myFlags & XCAFPrs_DocumentExplorerFlags_OnlyLeafNodes) == 0)
367 initCurrent (Standard_True);
373 if (!myCurrent.IsAssembly)
375 myNodeStack.ChangeValue (myTop).ChildIter.Next();
381 if (myNodeStack.Value (myTop).ChildIter.More())
383 const TDF_Label& aNodeTop = myNodeStack.Value (myTop).ChildIter.Value();
384 if (aNodeTop.IsNull()
385 || (!aNodeTop.HasChild() && !aNodeTop.HasAttribute()))
387 myNodeStack.ChangeValue (myTop).ChildIter.Next();
391 TDF_Label aRefLabel = aNodeTop;
392 XCAFDoc_ShapeTool::GetReferredShape (aNodeTop, aRefLabel);
393 if (!XCAFDoc_ShapeTool::IsAssembly (aRefLabel))
395 myHasMore = Standard_True;
396 initCurrent (Standard_False);
399 else if (aRefLabel.HasAttribute()
400 || aRefLabel.HasChild())
402 const XCAFPrs_DocumentNode& aParent = myNodeStack.Value (myTop);
405 XCAFPrs_DocumentNode aNodeInStack;
406 aNodeInStack.IsAssembly = Standard_True;
407 aNodeInStack.Label = aNodeTop;
408 aNodeInStack.RefLabel = aRefLabel;
409 aNodeInStack.LocalTrsf = XCAFDoc_ShapeTool::GetLocation (aNodeInStack.Label);
410 aNodeInStack.Location = aParent.Location * aNodeInStack.LocalTrsf;
411 aNodeInStack.Style = mergedStyle (myColorTool, aParent.Style, aNodeInStack.Label, aNodeInStack.RefLabel);
412 aNodeInStack.Id = DefineChildId (aNodeInStack.Label, aParent.Id);
413 aNodeInStack.ChildIter = TDF_ChildIterator (aNodeInStack.RefLabel);
414 myNodeStack.SetValue (myTop, aNodeInStack);
415 if ((myFlags & XCAFPrs_DocumentExplorerFlags_OnlyLeafNodes) == 0)
417 initCurrent (Standard_True);
423 myNodeStack.ChangeValue (myTop).ChildIter.Next();
428 myNodeStack.SetValue (myTop, XCAFPrs_DocumentNode());
437 myNodeStack.ChangeValue (myTop).ChildIter.Next();