1 // Created by: DAUTRY Philippe
2 // Copyright (c) 1998-1999 Matra Datavision
3 // Copyright (c) 1999-2012 OPEN CASCADE SAS
5 // The content of this file is subject to the Open CASCADE Technology Public
6 // License Version 6.5 (the "License"). You may not use the content of this file
7 // except in compliance with the License. Please obtain a copy of the License
8 // at http://www.opencascade.org and read it completely before using this file.
10 // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
11 // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
13 // The Original Code and all software distributed under the License is
14 // distributed on an "AS IS" basis, without warranty of any kind, and the
15 // Initial Developer hereby disclaims all such warranties, including without
16 // limitation, any warranties of merchantability, fitness for a particular
17 // purpose or non-infringement. Please see the License for the specific terms
18 // and conditions governing the rights and limitations under the License.
20 // -------------------
23 //Version Date Purpose
24 // 0.0 Sep 8 1998 Creation
27 #include <TDF_ClosureTool.ixx>
29 //#include <TDF_Reference.hxx>
30 #include <TDF_Attribute.hxx>
31 #include <TDF_AttributeIterator.hxx>
32 #include <TDF_AttributeMap.hxx>
33 #include <TDF_ChildIterator.hxx>
34 #include <TDF_Label.hxx>
35 #include <TDF_LabelMap.hxx>
36 #include <TDF_ListIteratorOfLabelList.hxx>
37 #include <TDF_MapIteratorOfAttributeMap.hxx>
38 #include <TDF_MapIteratorOfLabelMap.hxx>
40 #include <Standard_TypeMismatch.hxx>
42 #define DeclareAndSpeedCast(V,T,Vdown) Handle(T) Vdown = *((Handle(T)*)& V)
43 #define DeclareConstAndSpeedCast(V,T,Vdown) const Handle(T)& Vdown = (Handle(T)&) V
44 #define SpeedCast(V,T,Vdown) Vdown = *((Handle(T)*)& V)
47 //=======================================================================
49 //purpose : Builds the transitive closure whithout attribute filter.
50 //=======================================================================
52 void TDF_ClosureTool::Closure
53 (const Handle(TDF_DataSet)& aDataSet)
55 TDF_IDFilter Filter(Standard_False); // "Keep all"
56 TDF_ClosureMode Mode; // All modes are set to true.
57 TDF_ClosureTool::Closure(aDataSet, Filter, Mode);
61 //=======================================================================
63 //purpose : Builds the transitive closure with an attribute filter.
64 //=======================================================================
66 void TDF_ClosureTool::Closure
67 (const Handle(TDF_DataSet)& aDataSet,
68 const TDF_IDFilter& aFilter,
69 const TDF_ClosureMode& aMode)
71 TDF_LabelMap& labMap = aDataSet->Labels();
72 TDF_AttributeMap& attMap = aDataSet->Attributes();
73 TDF_LabelList& rootLst = aDataSet->Roots();
75 // Memorizes the roots for future uses.
77 TDF_MapIteratorOfLabelMap labMItr(labMap);
78 for (; labMItr.More(); labMItr.Next()) rootLst.Append(labMItr.Key());
81 TDF_ListIteratorOfLabelList labLItr(rootLst);
82 for (; labLItr.More(); labLItr.Next()) {
83 const TDF_Label& lab = labLItr.Value();
84 if (lab.HasAttribute())
85 TDF_ClosureTool::LabelAttributes(lab,labMap,attMap,aFilter,aMode);
86 TDF_ClosureTool::Closure(lab,labMap,attMap,aFilter,aMode);
91 //=======================================================================
93 //purpose : Internal closure method.
94 //=======================================================================
96 void TDF_ClosureTool::Closure
97 (const TDF_Label& aLabel,
98 TDF_LabelMap& aLabMap,
99 TDF_AttributeMap& anAttMap,
100 const TDF_IDFilter& aFilter,
101 const TDF_ClosureMode& aMode)
104 for (TDF_ChildIterator childItr(aLabel,Standard_True);
105 childItr.More();childItr.Next()){
106 const TDF_Label& locLab = childItr.Value();
107 // On ne peut faire cette optimisation car il faudrait d'abord
108 // qu'aucun label donne comme Root ne soit fils d'un autre label root!
109 if (locLab.HasAttribute()) { // && aLabMap.Add(locLab)) {
111 upLab = locLab.Father();
112 while (aLabMap.Add(upLab)) upLab = upLab.Father();
113 TDF_ClosureTool::LabelAttributes(locLab,aLabMap,anAttMap,aFilter,aMode);
121 //=======================================================================
122 //function : LabelAttributes
123 //purpose : Internal method: adds the attributes to <aDataSet>.
124 //=======================================================================
126 void TDF_ClosureTool::LabelAttributes
127 (const TDF_Label& aLabel,
128 TDF_LabelMap& aLabMap,
129 TDF_AttributeMap& anAttMap,
130 const TDF_IDFilter& aFilter,
131 const TDF_ClosureMode& aMode)
133 Handle(TDF_DataSet) tmpDataSet;
134 Standard_Boolean BindLabel;
135 TDF_MapIteratorOfAttributeMap attMItr;
136 TDF_MapIteratorOfLabelMap labMItr;
138 // Attributes directly attached to the label.
139 for (TDF_AttributeIterator attItr(aLabel); attItr.More(); attItr.Next()) {
140 const Handle(TDF_Attribute) locAtt1 = attItr.Value();
141 if (aFilter.IsKept(locAtt1)) {
142 if (anAttMap.Add(locAtt1)) {
143 // locAtt1 not yet in the map.
145 // Labels & Attributes referenced by the attribute.
146 tmpDataSet = new TDF_DataSet();
147 if (aMode.References()) {
148 // 1 - The referenced attributes
149 // 1.1 - A referenced attribute has a label : adds the label;
150 // 1.2 - A referenced attribute has no label : adds the attribute;
151 // 2 - Adds the referenced labels.
153 locAtt1->References(tmpDataSet);
155 // 1 - The referenced attributes
156 const TDF_AttributeMap& tmpAttMap = tmpDataSet->Attributes();
157 for (attMItr.Initialize(tmpAttMap);
158 attMItr.More(); attMItr.Next()) {
159 const Handle(TDF_Attribute)& locAtt2 = attMItr.Key();
160 BindLabel = Standard_False;
161 if (!locAtt2.IsNull()) {
162 const TDF_Label& locLab2 = locAtt2->Label();
163 BindLabel = !locLab2.IsNull();
165 // 1.1 - A referenced attribute has a label.
166 if (aLabMap.Add(locLab2))
167 TDF_ClosureTool::Closure(locLab2,
168 aLabMap,anAttMap,aFilter,aMode);
171 // 1.2 - A referenced attribute has no label.
172 // We suppose locAtt2 has no referenced attribute itself.
173 anAttMap.Add(locAtt2);
178 // 2 - Adds the referenced labels.
179 const TDF_LabelMap& tmpLabMap = tmpDataSet->Labels();
180 for (labMItr.Initialize(tmpLabMap);
181 labMItr.More(); labMItr.Next()) {
182 const TDF_Label& locLab1 = labMItr.Key();
183 if (aLabMap.Add(locLab1))
184 TDF_ClosureTool::Closure(locLab1,
185 aLabMap,anAttMap,aFilter,aMode);