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 | |
25 | namespace |
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 | // ======================================================================= |
89 | TCollection_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 | // ======================================================================= |
103 | TDF_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 | // ======================================================================= |
140 | TopoDS_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 | // ======================================================================= |
171 | XCAFPrs_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 | // ======================================================================= |
183 | XCAFPrs_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 | // ======================================================================= |
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) |
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 | // ======================================================================= |
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) |
219 | { |
220 | TDF_LabelSequence aSeq; |
221 | aSeq.Append (theRoot); |
222 | Init (theDocument, aSeq, theFlags, theDefStyle); |
223 | } |
224 | |
225 | // ======================================================================= |
226 | // function : Init |
227 | // purpose : |
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) |
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 | // ======================================================================= |
256 | void 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 |
301 | void 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 | // ======================================================================= |
344 | void 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 | } |