0029915: Porting to VC 2017 : Regressions in Modeling Algorithms on VC 2017
[occt.git] / src / TDF / TDF_ClosureTool.cxx
CommitLineData
b311480e 1// Created by: DAUTRY Philippe
2// Copyright (c) 1998-1999 Matra Datavision
973c2be1 3// Copyright (c) 1999-2014 OPEN CASCADE SAS
b311480e 4//
973c2be1 5// This file is part of Open CASCADE Technology software library.
b311480e 6//
d5f74e42 7// This library is free software; you can redistribute it and/or modify it under
8// the terms of the GNU Lesser General Public License version 2.1 as published
973c2be1 9// by the Free Software Foundation, with special exception defined in the file
10// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
11// distribution for complete text of the license and disclaimer of any warranty.
b311480e 12//
973c2be1 13// Alternatively, this file may be used under the terms of Open CASCADE
14// commercial license or contractual agreement.
b311480e 15
7fd59977 16// -------------------
7fd59977 17// Version: 0.0
b311480e 18//Version Date Purpose
7fd59977 19// 0.0 Sep 8 1998 Creation
20
42cf5bc1 21#include <Standard_TypeMismatch.hxx>
7fd59977 22#include <TDF_Attribute.hxx>
23#include <TDF_AttributeIterator.hxx>
24#include <TDF_AttributeMap.hxx>
25#include <TDF_ChildIterator.hxx>
42cf5bc1 26#include <TDF_ClosureMode.hxx>
27#include <TDF_ClosureTool.hxx>
28#include <TDF_DataSet.hxx>
29#include <TDF_IDFilter.hxx>
7fd59977 30#include <TDF_Label.hxx>
31#include <TDF_LabelMap.hxx>
32#include <TDF_ListIteratorOfLabelList.hxx>
33#include <TDF_MapIteratorOfAttributeMap.hxx>
34#include <TDF_MapIteratorOfLabelMap.hxx>
35
7fd59977 36//=======================================================================
37//function : Closure
38//purpose : Builds the transitive closure whithout attribute filter.
39//=======================================================================
40
41void TDF_ClosureTool::Closure
42(const Handle(TDF_DataSet)& aDataSet)
43{
44 TDF_IDFilter Filter(Standard_False); // "Keep all"
45 TDF_ClosureMode Mode; // All modes are set to true.
46 TDF_ClosureTool::Closure(aDataSet, Filter, Mode);
47}
48
49
50//=======================================================================
51//function : Closure
52//purpose : Builds the transitive closure with an attribute filter.
53//=======================================================================
54
55void TDF_ClosureTool::Closure
56(const Handle(TDF_DataSet)& aDataSet,
57 const TDF_IDFilter& aFilter,
58 const TDF_ClosureMode& aMode)
59{
60 TDF_LabelMap& labMap = aDataSet->Labels();
61 TDF_AttributeMap& attMap = aDataSet->Attributes();
62 TDF_LabelList& rootLst = aDataSet->Roots();
63
64 // Memorizes the roots for future uses.
65 rootLst.Clear();
66 TDF_MapIteratorOfLabelMap labMItr(labMap);
67 for (; labMItr.More(); labMItr.Next()) rootLst.Append(labMItr.Key());
68
69 // Iterates on roots.
70 TDF_ListIteratorOfLabelList labLItr(rootLst);
71 for (; labLItr.More(); labLItr.Next()) {
72 const TDF_Label& lab = labLItr.Value();
73 if (lab.HasAttribute())
74 TDF_ClosureTool::LabelAttributes(lab,labMap,attMap,aFilter,aMode);
75 TDF_ClosureTool::Closure(lab,labMap,attMap,aFilter,aMode);
76 }
77}
78
79
80//=======================================================================
81//function : Closure
82//purpose : Internal closure method.
83//=======================================================================
84
85void TDF_ClosureTool::Closure
86(const TDF_Label& aLabel,
87 TDF_LabelMap& aLabMap,
88 TDF_AttributeMap& anAttMap,
89 const TDF_IDFilter& aFilter,
90 const TDF_ClosureMode& aMode)
91{
92 TDF_Label upLab;
93 for (TDF_ChildIterator childItr(aLabel,Standard_True);
94 childItr.More();childItr.Next()){
95 const TDF_Label& locLab = childItr.Value();
96 // On ne peut faire cette optimisation car il faudrait d'abord
97 // qu'aucun label donne comme Root ne soit fils d'un autre label root!
98 if (locLab.HasAttribute()) { // && aLabMap.Add(locLab)) {
99 aLabMap.Add(locLab);
100 upLab = locLab.Father();
101 while (aLabMap.Add(upLab)) upLab = upLab.Father();
102 TDF_ClosureTool::LabelAttributes(locLab,aLabMap,anAttMap,aFilter,aMode);
103 }
104 }
105}
106
107
108
109
110//=======================================================================
111//function : LabelAttributes
112//purpose : Internal method: adds the attributes to <aDataSet>.
113//=======================================================================
114
115void TDF_ClosureTool::LabelAttributes
116(const TDF_Label& aLabel,
117 TDF_LabelMap& aLabMap,
118 TDF_AttributeMap& anAttMap,
119 const TDF_IDFilter& aFilter,
120 const TDF_ClosureMode& aMode)
121{
122 Handle(TDF_DataSet) tmpDataSet;
123 Standard_Boolean BindLabel;
124 TDF_MapIteratorOfAttributeMap attMItr;
125 TDF_MapIteratorOfLabelMap labMItr;
126
127 // Attributes directly attached to the label.
128 for (TDF_AttributeIterator attItr(aLabel); attItr.More(); attItr.Next()) {
129 const Handle(TDF_Attribute) locAtt1 = attItr.Value();
130 if (aFilter.IsKept(locAtt1)) {
131 if (anAttMap.Add(locAtt1)) {
132 // locAtt1 not yet in the map.
133
134 // Labels & Attributes referenced by the attribute.
135 tmpDataSet = new TDF_DataSet();
136 if (aMode.References()) {
137 // 1 - The referenced attributes
138 // 1.1 - A referenced attribute has a label : adds the label;
139 // 1.2 - A referenced attribute has no label : adds the attribute;
140 // 2 - Adds the referenced labels.
141
142 locAtt1->References(tmpDataSet);
143
144 // 1 - The referenced attributes
145 const TDF_AttributeMap& tmpAttMap = tmpDataSet->Attributes();
146 for (attMItr.Initialize(tmpAttMap);
147 attMItr.More(); attMItr.Next()) {
148 const Handle(TDF_Attribute)& locAtt2 = attMItr.Key();
149 BindLabel = Standard_False;
150 if (!locAtt2.IsNull()) {
151 const TDF_Label& locLab2 = locAtt2->Label();
152 BindLabel = !locLab2.IsNull();
153 if (BindLabel) {
154 // 1.1 - A referenced attribute has a label.
155 if (aLabMap.Add(locLab2))
156 TDF_ClosureTool::Closure(locLab2,
157 aLabMap,anAttMap,aFilter,aMode);
158 }
159 else {
160 // 1.2 - A referenced attribute has no label.
161 // We suppose locAtt2 has no referenced attribute itself.
162 anAttMap.Add(locAtt2);
163 }
164 }
165 }
166
167 // 2 - Adds the referenced labels.
168 const TDF_LabelMap& tmpLabMap = tmpDataSet->Labels();
169 for (labMItr.Initialize(tmpLabMap);
170 labMItr.More(); labMItr.Next()) {
171 const TDF_Label& locLab1 = labMItr.Key();
172 if (aLabMap.Add(locLab1))
173 TDF_ClosureTool::Closure(locLab1,
174 aLabMap,anAttMap,aFilter,aMode);
175 }
176 }
177 }
178 }
179 }
180}