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 | |
41 | void 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 | |
55 | void 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); |
6e779194 |
75 | if (aMode.Descendants()) |
76 | TDF_ClosureTool::Closure(lab,labMap,attMap,aFilter,aMode); |
7fd59977 |
77 | } |
78 | } |
79 | |
80 | |
81 | //======================================================================= |
82 | //function : Closure |
83 | //purpose : Internal closure method. |
84 | //======================================================================= |
85 | |
86 | void TDF_ClosureTool::Closure |
87 | (const TDF_Label& aLabel, |
88 | TDF_LabelMap& aLabMap, |
89 | TDF_AttributeMap& anAttMap, |
90 | const TDF_IDFilter& aFilter, |
91 | const TDF_ClosureMode& aMode) |
92 | { |
93 | TDF_Label upLab; |
94 | for (TDF_ChildIterator childItr(aLabel,Standard_True); |
95 | childItr.More();childItr.Next()){ |
96 | const TDF_Label& locLab = childItr.Value(); |
97 | // On ne peut faire cette optimisation car il faudrait d'abord |
98 | // qu'aucun label donne comme Root ne soit fils d'un autre label root! |
99 | if (locLab.HasAttribute()) { // && aLabMap.Add(locLab)) { |
100 | aLabMap.Add(locLab); |
101 | upLab = locLab.Father(); |
102 | while (aLabMap.Add(upLab)) upLab = upLab.Father(); |
103 | TDF_ClosureTool::LabelAttributes(locLab,aLabMap,anAttMap,aFilter,aMode); |
104 | } |
105 | } |
106 | } |
107 | |
108 | |
109 | |
110 | |
111 | //======================================================================= |
112 | //function : LabelAttributes |
113 | //purpose : Internal method: adds the attributes to <aDataSet>. |
114 | //======================================================================= |
115 | |
116 | void TDF_ClosureTool::LabelAttributes |
117 | (const TDF_Label& aLabel, |
118 | TDF_LabelMap& aLabMap, |
119 | TDF_AttributeMap& anAttMap, |
120 | const TDF_IDFilter& aFilter, |
121 | const TDF_ClosureMode& aMode) |
122 | { |
123 | Handle(TDF_DataSet) tmpDataSet; |
124 | Standard_Boolean BindLabel; |
125 | TDF_MapIteratorOfAttributeMap attMItr; |
126 | TDF_MapIteratorOfLabelMap labMItr; |
127 | |
128 | // Attributes directly attached to the label. |
129 | for (TDF_AttributeIterator attItr(aLabel); attItr.More(); attItr.Next()) { |
130 | const Handle(TDF_Attribute) locAtt1 = attItr.Value(); |
131 | if (aFilter.IsKept(locAtt1)) { |
132 | if (anAttMap.Add(locAtt1)) { |
133 | // locAtt1 not yet in the map. |
134 | |
135 | // Labels & Attributes referenced by the attribute. |
136 | tmpDataSet = new TDF_DataSet(); |
137 | if (aMode.References()) { |
138 | // 1 - The referenced attributes |
139 | // 1.1 - A referenced attribute has a label : adds the label; |
140 | // 1.2 - A referenced attribute has no label : adds the attribute; |
141 | // 2 - Adds the referenced labels. |
142 | |
143 | locAtt1->References(tmpDataSet); |
144 | |
145 | // 1 - The referenced attributes |
146 | const TDF_AttributeMap& tmpAttMap = tmpDataSet->Attributes(); |
147 | for (attMItr.Initialize(tmpAttMap); |
148 | attMItr.More(); attMItr.Next()) { |
149 | const Handle(TDF_Attribute)& locAtt2 = attMItr.Key(); |
150 | BindLabel = Standard_False; |
151 | if (!locAtt2.IsNull()) { |
152 | const TDF_Label& locLab2 = locAtt2->Label(); |
153 | BindLabel = !locLab2.IsNull(); |
154 | if (BindLabel) { |
155 | // 1.1 - A referenced attribute has a label. |
156 | if (aLabMap.Add(locLab2)) |
157 | TDF_ClosureTool::Closure(locLab2, |
158 | aLabMap,anAttMap,aFilter,aMode); |
159 | } |
160 | else { |
161 | // 1.2 - A referenced attribute has no label. |
162 | // We suppose locAtt2 has no referenced attribute itself. |
163 | anAttMap.Add(locAtt2); |
164 | } |
165 | } |
166 | } |
167 | |
168 | // 2 - Adds the referenced labels. |
169 | const TDF_LabelMap& tmpLabMap = tmpDataSet->Labels(); |
170 | for (labMItr.Initialize(tmpLabMap); |
171 | labMItr.More(); labMItr.Next()) { |
172 | const TDF_Label& locLab1 = labMItr.Key(); |
173 | if (aLabMap.Add(locLab1)) |
174 | TDF_ClosureTool::Closure(locLab1, |
175 | aLabMap,anAttMap,aFilter,aMode); |
176 | } |
177 | } |
178 | } |
179 | } |
180 | } |
181 | } |