0031135: Visualization, TKOpenGl - texture sRGB -> linear conversion is applied twice...
[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{
f6abd02c 224 if ((theFlags & XCAFPrs_DocumentExplorerFlags_NoStyle) == 0)
fc552d84 225 {
226 myColorTool = XCAFDoc_DocumentTool::ColorTool (theDocument->Main());
227 }
228 else
229 {
230 myColorTool.Nullify();
231 }
232
fc552d84 233 myDefStyle = theDefStyle;
234 myRoots = theRoots;
235 myRootIter = TDF_LabelSequence::Iterator (myRoots);
236 myFlags = theFlags;
237 initRoot();
238}
239
240// =======================================================================
241// function : initRoot
242// purpose :
243// =======================================================================
244void XCAFPrs_DocumentExplorer::initRoot()
245{
246 for (;;)
247 {
248 // reset the stack
249 for (Standard_Integer aStackIter = 0; aStackIter <= myTop; ++aStackIter)
250 {
251 myNodeStack.SetValue (aStackIter, XCAFPrs_DocumentNode());
252 }
253 myTop = -1;
254 if (!myRootIter.More())
255 {
256 myHasMore = Standard_False;
257 initCurrent (Standard_False);
258 return;
259 }
260
261 const TDF_Label& aRootLab = myRootIter.Value();
262 if (aRootLab.IsNull())
263 {
264 // assert - invalid input
f6abd02c 265 //Standard_ProgramError::Raise ("XCAFPrs_DocumentExplorer - NULL label in the input");
fc552d84 266 myRootIter.Next();
267 continue;
268 }
269
270 myHasMore = Standard_True;
271 TDF_Label aRefLabel = aRootLab;
272 XCAFDoc_ShapeTool::GetReferredShape (aRootLab, aRefLabel);
273 if (XCAFDoc_ShapeTool::IsAssembly (aRefLabel))
274 {
275 Next();
276 }
277 else
278 {
279 initCurrent (Standard_False);
280 }
281 return;
282 }
283}
284
285// =======================================================================
286// function : initCurrent
287// purpose :
288// =======================================================================
289void XCAFPrs_DocumentExplorer::initCurrent (Standard_Boolean theIsAssmebly)
290{
291 myCurrent = XCAFPrs_DocumentNode();
292 if (theIsAssmebly)
293 {
294 if (myTop < 0)
295 {
f6abd02c 296 Standard_ProgramError::Raise ("XCAFPrs_DocumentExplorer - internal error");
fc552d84 297 }
298 myCurrent = myNodeStack.Value (myTop);
299 }
300 else if (myTop < 0)
301 {
302 if (!myRootIter.More())
303 {
304 return;
305 }
306
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());
314 }
315 else
316 {
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);
325 }
326}
327
328// =======================================================================
329// function : Next
330// purpose :
331// =======================================================================
332void XCAFPrs_DocumentExplorer::Next()
333{
334 if (!myHasMore)
335 {
f6abd02c 336 Standard_ProgramError::Raise ("XCAFPrs_DocumentExplorer::Next() - out of range");
fc552d84 337 return; // assert
338 }
339
340 if (myTop < 0)
341 {
342 const TDF_Label& aRootLab = myRootIter.Value();
343 TDF_Label aRefLabel = aRootLab;
344 XCAFDoc_ShapeTool::GetReferredShape (aRootLab, aRefLabel);
345 if (!XCAFDoc_ShapeTool::IsAssembly (aRefLabel))
346 {
347 // already visited once
348 myRootIter.Next();
349 initRoot();
350 return;
351 }
352
353 // push and try to find
354 myTop = 0;
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)
366 {
367 initCurrent (Standard_True);
368 return;
369 }
370 }
371 else
372 {
373 if (!myCurrent.IsAssembly)
374 {
375 myNodeStack.ChangeValue (myTop).ChildIter.Next();
376 }
377 }
378
379 for (;;)
380 {
381 if (myNodeStack.Value (myTop).ChildIter.More())
382 {
383 const TDF_Label& aNodeTop = myNodeStack.Value (myTop).ChildIter.Value();
384 if (aNodeTop.IsNull()
385 || (!aNodeTop.HasChild() && !aNodeTop.HasAttribute()))
386 {
387 myNodeStack.ChangeValue (myTop).ChildIter.Next();
388 continue;
389 }
390
391 TDF_Label aRefLabel = aNodeTop;
392 XCAFDoc_ShapeTool::GetReferredShape (aNodeTop, aRefLabel);
393 if (!XCAFDoc_ShapeTool::IsAssembly (aRefLabel))
394 {
395 myHasMore = Standard_True;
396 initCurrent (Standard_False);
397 return;
398 }
399 else if (aRefLabel.HasAttribute()
400 || aRefLabel.HasChild())
401 {
402 const XCAFPrs_DocumentNode& aParent = myNodeStack.Value (myTop);
403 ++myTop;
404
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)
416 {
417 initCurrent (Standard_True);
418 return;
419 }
420 }
421 else
422 {
423 myNodeStack.ChangeValue (myTop).ChildIter.Next();
424 }
425 }
426 else
427 {
428 myNodeStack.SetValue (myTop, XCAFPrs_DocumentNode());
429 --myTop;
430 if (myTop < 0)
431 {
432 myRootIter.Next();
433 initRoot();
434 return;
435 }
436
437 myNodeStack.ChangeValue (myTop).ChildIter.Next();
438 }
439 }
440}