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 <XCAFDoc_VisMaterialTool.hxx>
23 #include <XCAFPrs_DocumentIdIterator.hxx>
27 //! Return merged style for the child node.
28 static XCAFPrs_Style mergedStyle (const Handle(XCAFDoc_ColorTool)& theColorTool,
29 const Handle(XCAFDoc_VisMaterialTool)& theVisMatTool,
30 const XCAFPrs_Style& theParenStyle,
31 const TDF_Label& theLabel,
32 const TDF_Label& theRefLabel)
34 if (theColorTool.IsNull())
39 XCAFPrs_Style aStyle = theParenStyle;
40 if (Handle(XCAFDoc_VisMaterial) aVisMat = theVisMatTool->GetShapeMaterial (theRefLabel))
42 aStyle.SetMaterial (aVisMat);
44 Quantity_ColorRGBA aColor;
45 if (theColorTool->GetColor (theRefLabel, XCAFDoc_ColorGen, aColor))
47 aStyle.SetColorCurv (aColor.GetRGB());
48 aStyle.SetColorSurf (aColor);
50 if (theColorTool->GetColor (theRefLabel, XCAFDoc_ColorSurf, aColor))
52 aStyle.SetColorSurf (aColor);
54 if (theColorTool->GetColor (theRefLabel, XCAFDoc_ColorCurv, aColor))
56 aStyle.SetColorCurv (aColor.GetRGB());
59 if (theLabel != theRefLabel)
61 // override Reference style with Instance style when defined (bad model?)
62 if (Handle(XCAFDoc_VisMaterial) aVisMat = theVisMatTool->GetShapeMaterial (theLabel))
64 aStyle.SetMaterial (aVisMat);
66 if (theColorTool->GetColor (theLabel, XCAFDoc_ColorGen, aColor))
68 aStyle.SetColorCurv (aColor.GetRGB());
69 aStyle.SetColorSurf (aColor);
71 if (theColorTool->GetColor (theLabel, XCAFDoc_ColorSurf, aColor))
73 aStyle.SetColorSurf (aColor);
75 if (theColorTool->GetColor (theLabel, XCAFDoc_ColorCurv, aColor))
77 aStyle.SetColorCurv (aColor.GetRGB());
85 // =======================================================================
86 // function : DefineChildId
88 // =======================================================================
89 TCollection_AsciiString XCAFPrs_DocumentExplorer::DefineChildId (const TDF_Label& theLabel,
90 const TCollection_AsciiString& theParentId)
92 TCollection_AsciiString anEntryId;
93 TDF_Tool::Entry (theLabel, anEntryId);
94 return !theParentId.IsEmpty()
95 ? theParentId + "/" + anEntryId + "."
99 // =======================================================================
100 // function : FindLabelFromPathId
102 // =======================================================================
103 TDF_Label XCAFPrs_DocumentExplorer::FindLabelFromPathId (const Handle(TDocStd_Document)& theDocument,
104 const TCollection_AsciiString& theId,
105 TopLoc_Location& theParentLocation,
106 TopLoc_Location& theLocation)
108 theParentLocation = TopLoc_Location();
109 theLocation = TopLoc_Location();
110 TDF_Label anInstanceLabel;
111 for (XCAFPrs_DocumentIdIterator anPathIter (theId); anPathIter.More();)
115 const TCollection_AsciiString& anOcafId = anPathIter.Value();
116 TDF_Tool::Label (theDocument->Main().Data(), anOcafId, aSubLabel);
117 if (aSubLabel.IsNull())
124 if (!anPathIter.More())
126 theParentLocation = theLocation;
129 TopLoc_Location aLocTrsf = XCAFDoc_ShapeTool::GetLocation (aSubLabel);
130 theLocation = theLocation * aLocTrsf;
131 anInstanceLabel = aSubLabel;
133 return anInstanceLabel;
136 // =======================================================================
137 // function : FindShapeFromPathId
139 // =======================================================================
140 TopoDS_Shape XCAFPrs_DocumentExplorer::FindShapeFromPathId (const Handle(TDocStd_Document)& theDocument,
141 const TCollection_AsciiString& theId)
143 TopLoc_Location aLocation;
144 TDF_Label anInstanceLabel = FindLabelFromPathId (theDocument, theId, aLocation);
145 if (anInstanceLabel.IsNull())
147 return TopoDS_Shape();
150 TDF_Label aRefLabel = anInstanceLabel;
151 XCAFDoc_ShapeTool::GetReferredShape (anInstanceLabel, aRefLabel);
152 if (aRefLabel.IsNull())
154 return TopoDS_Shape();
157 TopoDS_Shape aShape = XCAFDoc_ShapeTool::GetShape (aRefLabel);
160 return TopoDS_Shape();
163 aShape.Location (aLocation);
167 // =======================================================================
168 // function : XCAFPrs_DocumentExplorer
170 // =======================================================================
171 XCAFPrs_DocumentExplorer::XCAFPrs_DocumentExplorer()
173 myHasMore (Standard_False),
174 myFlags (XCAFPrs_DocumentExplorerFlags_None)
179 // =======================================================================
180 // function : XCAFPrs_DocumentExplorer
182 // =======================================================================
183 XCAFPrs_DocumentExplorer::XCAFPrs_DocumentExplorer (const Handle(TDocStd_Document)& theDocument,
184 const XCAFPrs_DocumentExplorerFlags theFlags,
185 const XCAFPrs_Style& theDefStyle)
187 myHasMore (Standard_False),
188 myFlags (XCAFPrs_DocumentExplorerFlags_None)
190 Handle(XCAFDoc_ShapeTool) aShapeTool = XCAFDoc_DocumentTool::ShapeTool (theDocument->Main());
191 TDF_LabelSequence aRootLabels;
192 aShapeTool->GetFreeShapes (aRootLabels);
193 Init (theDocument, aRootLabels, theFlags, theDefStyle);
196 // =======================================================================
197 // function : XCAFPrs_DocumentExplorer
199 // =======================================================================
200 XCAFPrs_DocumentExplorer::XCAFPrs_DocumentExplorer (const Handle(TDocStd_Document)& theDocument,
201 const TDF_LabelSequence& theRoots,
202 const XCAFPrs_DocumentExplorerFlags theFlags,
203 const XCAFPrs_Style& theDefStyle)
205 myHasMore (Standard_False),
206 myFlags (XCAFPrs_DocumentExplorerFlags_None)
208 Init (theDocument, theRoots, theFlags, theDefStyle);
211 // =======================================================================
214 // =======================================================================
215 void XCAFPrs_DocumentExplorer::Init (const Handle(TDocStd_Document)& theDocument,
216 const TDF_Label& theRoot,
217 const XCAFPrs_DocumentExplorerFlags theFlags,
218 const XCAFPrs_Style& theDefStyle)
220 TDF_LabelSequence aSeq;
221 aSeq.Append (theRoot);
222 Init (theDocument, aSeq, theFlags, theDefStyle);
225 // =======================================================================
228 // =======================================================================
229 void XCAFPrs_DocumentExplorer::Init (const Handle(TDocStd_Document)& theDocument,
230 const TDF_LabelSequence& theRoots,
231 const XCAFPrs_DocumentExplorerFlags theFlags,
232 const XCAFPrs_Style& theDefStyle)
234 if ((theFlags & XCAFPrs_DocumentExplorerFlags_NoStyle) == 0)
236 myColorTool = XCAFDoc_DocumentTool::ColorTool (theDocument->Main());
237 myVisMatTool = XCAFDoc_DocumentTool::VisMaterialTool (theDocument->Main());
241 myColorTool.Nullify();
242 myVisMatTool.Nullify();
245 myDefStyle = theDefStyle;
247 myRootIter = TDF_LabelSequence::Iterator (myRoots);
252 // =======================================================================
253 // function : initRoot
255 // =======================================================================
256 void XCAFPrs_DocumentExplorer::initRoot()
261 for (Standard_Integer aStackIter = 0; aStackIter <= myTop; ++aStackIter)
263 myNodeStack.SetValue (aStackIter, XCAFPrs_DocumentNode());
266 if (!myRootIter.More())
268 myHasMore = Standard_False;
269 initCurrent (Standard_False);
273 const TDF_Label& aRootLab = myRootIter.Value();
274 if (aRootLab.IsNull())
276 // assert - invalid input
277 //Standard_ProgramError::Raise ("XCAFPrs_DocumentExplorer - NULL label in the input");
282 myHasMore = Standard_True;
283 TDF_Label aRefLabel = aRootLab;
284 XCAFDoc_ShapeTool::GetReferredShape (aRootLab, aRefLabel);
285 if (XCAFDoc_ShapeTool::IsAssembly (aRefLabel))
291 initCurrent (Standard_False);
297 // =======================================================================
298 // function : initCurrent
300 // =======================================================================
301 void XCAFPrs_DocumentExplorer::initCurrent (Standard_Boolean theIsAssmebly)
303 myCurrent = XCAFPrs_DocumentNode();
308 Standard_ProgramError::Raise ("XCAFPrs_DocumentExplorer - internal error");
310 myCurrent = myNodeStack.Value (myTop);
314 if (!myRootIter.More())
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;
324 myCurrent.Style = mergedStyle (myColorTool, myVisMatTool, myDefStyle, myCurrent.Label, myCurrent.RefLabel);
325 myCurrent.Id = DefineChildId (myCurrent.Label, TCollection_AsciiString());
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;
335 myCurrent.Style = mergedStyle (myColorTool, myVisMatTool, aTopNodeInStack.Style, myCurrent.Label, myCurrent.RefLabel);
336 myCurrent.Id = DefineChildId (myCurrent.Label, aTopNodeInStack.Id);
340 // =======================================================================
343 // =======================================================================
344 void XCAFPrs_DocumentExplorer::Next()
348 Standard_ProgramError::Raise ("XCAFPrs_DocumentExplorer::Next() - out of range");
354 const TDF_Label& aRootLab = myRootIter.Value();
355 TDF_Label aRefLabel = aRootLab;
356 XCAFDoc_ShapeTool::GetReferredShape (aRootLab, aRefLabel);
357 if (!XCAFDoc_ShapeTool::IsAssembly (aRefLabel))
359 // already visited once
365 // push and try to find
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;
374 aNodeInStack.Style = mergedStyle (myColorTool, myVisMatTool, myDefStyle, aNodeInStack.Label, aNodeInStack.RefLabel);
375 aNodeInStack.Id = DefineChildId (aNodeInStack.Label, TCollection_AsciiString());
376 myNodeStack.SetValue (0, aNodeInStack);
377 if ((myFlags & XCAFPrs_DocumentExplorerFlags_OnlyLeafNodes) == 0)
379 initCurrent (Standard_True);
385 if (!myCurrent.IsAssembly)
387 myNodeStack.ChangeValue (myTop).ChildIter.Next();
393 if (myNodeStack.Value (myTop).ChildIter.More())
395 const TDF_Label& aNodeTop = myNodeStack.Value (myTop).ChildIter.Value();
396 if (aNodeTop.IsNull()
397 || (!aNodeTop.HasChild() && !aNodeTop.HasAttribute()))
399 myNodeStack.ChangeValue (myTop).ChildIter.Next();
403 TDF_Label aRefLabel = aNodeTop;
404 XCAFDoc_ShapeTool::GetReferredShape (aNodeTop, aRefLabel);
405 if (!XCAFDoc_ShapeTool::IsAssembly (aRefLabel))
407 myHasMore = Standard_True;
408 initCurrent (Standard_False);
411 else if (aRefLabel.HasAttribute()
412 || aRefLabel.HasChild())
414 const XCAFPrs_DocumentNode& aParent = myNodeStack.Value (myTop);
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;
423 aNodeInStack.Style = mergedStyle (myColorTool, myVisMatTool, aParent.Style, aNodeInStack.Label, aNodeInStack.RefLabel);
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)
429 initCurrent (Standard_True);
435 myNodeStack.ChangeValue (myTop).ChildIter.Next();
440 myNodeStack.SetValue (myTop, XCAFPrs_DocumentNode());
449 myNodeStack.ChangeValue (myTop).ChildIter.Next();