7fd59977 |
1 | // File: TDF_ComparisonTool.cxx |
2 | // ---------------------- |
3 | // Author: DAUTRY Philippe |
4 | // <fid@fox.paris1.matra-dtv.fr> |
5 | // Copyright: Matra Datavision 1997 |
6 | |
7 | // Version: 0.0 |
8 | // History: Version Date Purpose |
9 | // 0.0 Sep 4 1997 Creation |
10 | |
11 | |
12 | |
13 | #include <TDF_ComparisonTool.ixx> |
14 | |
15 | #include <TDF_Attribute.hxx> |
16 | #include <TDF_AttributeDataMap.hxx> |
17 | #include <TDF_AttributeIterator.hxx> |
18 | #include <TDF_AttributeMap.hxx> |
19 | #include <TDF_ChildIterator.hxx> |
20 | #include <TDF_DataMapIteratorOfAttributeDataMap.hxx> |
21 | #include <TDF_DataMapIteratorOfLabelDataMap.hxx> |
22 | #include <TDF_Label.hxx> |
23 | #include <TDF_LabelDataMap.hxx> |
24 | #include <TDF_LabelMap.hxx> |
25 | #include <TDF_ListIteratorOfLabelList.hxx> |
26 | #include <TDF_MapIteratorOfAttributeMap.hxx> |
27 | #include <TDF_MapIteratorOfLabelMap.hxx> |
28 | |
29 | |
30 | //======================================================================= |
31 | //function : Compare |
32 | //purpose : Comparison method between 2 DataSets. |
33 | //======================================================================= |
34 | |
35 | void TDF_ComparisonTool::Compare |
36 | (const Handle(TDF_DataSet)& aSourceDataSet, |
37 | const Handle(TDF_DataSet)& aTargetDataSet, |
38 | const TDF_IDFilter& aFilter, |
39 | const Handle(TDF_RelocationTable)& aRelocationTable) |
40 | { |
41 | if (aSourceDataSet->IsEmpty() || aTargetDataSet->IsEmpty()) return; |
42 | |
43 | const TDF_LabelList& srcRoots = aSourceDataSet->Roots(); |
44 | TDF_ListIteratorOfLabelList srcRootItr(srcRoots); |
45 | |
46 | const TDF_LabelList& trgRoots = aTargetDataSet->Roots(); |
47 | TDF_ListIteratorOfLabelList trgRootItr; |
48 | |
49 | TDF_LabelDataMap& the2LabMap = aRelocationTable->LabelTable(); |
50 | |
51 | // Try to match source and target roots by their tag. |
52 | for (; srcRootItr.More(); srcRootItr.Next()) { |
53 | const TDF_Label& srcLab = srcRootItr.Value(); |
54 | for (trgRootItr.Initialize(trgRoots);trgRootItr.More();trgRootItr.Next()){ |
55 | const TDF_Label& trgLab = trgRootItr.Value(); |
56 | if (srcLab.Tag() == trgLab.Tag()) { |
57 | the2LabMap.Bind(srcLab, trgLab); |
58 | // Now, compare recursively! |
59 | TDF_ComparisonTool::Compare(srcLab,trgLab, |
60 | aSourceDataSet, aTargetDataSet, aFilter, |
61 | aRelocationTable); |
62 | break; |
63 | } |
64 | } |
65 | } |
66 | |
67 | // The relocation attribute table is now ready, |
68 | // except for the label unattached attributes, |
69 | // because we cannot treat them. |
70 | } |
71 | |
72 | |
73 | //======================================================================= |
74 | //function : Compare |
75 | //purpose : Internal recursive comparison method. |
76 | //======================================================================= |
77 | |
78 | void TDF_ComparisonTool::Compare |
79 | (const TDF_Label& aSrcLabel, |
80 | const TDF_Label& aTrgLabel, |
81 | const Handle(TDF_DataSet)& aSourceDataSet, |
82 | const Handle(TDF_DataSet)& aTargetDataSet, |
83 | const TDF_IDFilter& aFilter, |
84 | const Handle(TDF_RelocationTable)& aRelocationTable) |
85 | { |
86 | TDF_LabelDataMap& the2LabMap = aRelocationTable->LabelTable(); |
87 | TDF_AttributeDataMap& the2AttMap = aRelocationTable->AttributeTable(); |
88 | |
89 | Handle(TDF_Attribute) tAtt; |
90 | |
91 | // Compare source and target attributes. |
92 | for (TDF_AttributeIterator attItr(aSrcLabel); attItr.More(); attItr.Next()){ |
93 | const Handle(TDF_Attribute) sAtt = attItr.Value(); |
94 | if (aFilter.IsKept(sAtt) && aSourceDataSet->ContainsAttribute(sAtt)) { |
95 | if (aTrgLabel.FindAttribute(sAtt->ID(),tAtt)) { |
96 | if (aTargetDataSet->ContainsAttribute(tAtt)) |
97 | the2AttMap.Bind(sAtt,tAtt); |
98 | } |
99 | } |
100 | } |
101 | |
102 | // Do the same for the children. |
103 | TDF_ChildIterator childItr1, childItr2; |
104 | for (childItr1.Initialize(aSrcLabel); childItr1.More(); childItr1.Next()){ |
105 | const TDF_Label& childSrcLab = childItr1.Value(); |
106 | if (aSourceDataSet->ContainsLabel(childSrcLab)) { |
107 | for (childItr2.Initialize(aSrcLabel);childItr2.More();childItr2.Next()){ |
108 | const TDF_Label& childTrgLab = childItr2.Value(); |
109 | if (aTargetDataSet->ContainsLabel(childTrgLab)) { |
110 | if (childSrcLab.Tag() == childTrgLab.Tag()) { |
111 | the2LabMap.Bind(childSrcLab, childTrgLab); |
112 | TDF_ComparisonTool::Compare(childSrcLab,childTrgLab, |
113 | aSourceDataSet,aTargetDataSet,aFilter, |
114 | aRelocationTable); |
115 | break; |
116 | } |
117 | } |
118 | } |
119 | } |
120 | } |
121 | } |
122 | |
123 | |
124 | //======================================================================= |
125 | //function : SourceUnbound |
126 | //purpose : |
127 | //======================================================================= |
128 | |
129 | Standard_Boolean TDF_ComparisonTool::SourceUnbound |
130 | (const Handle(TDF_DataSet)& aRefDataSet, |
131 | const Handle(TDF_RelocationTable)& aRelocationTable, |
132 | const TDF_IDFilter& aFilter, |
133 | const Handle(TDF_DataSet)& aDiffDataSet, |
134 | const Standard_Integer anOption) |
135 | { |
136 | if (aRefDataSet->IsEmpty()) return Standard_False; |
137 | else return Unbound(aRefDataSet, aRelocationTable, aFilter, |
138 | aDiffDataSet, anOption, Standard_True); |
139 | } |
140 | |
141 | |
142 | //======================================================================= |
143 | //function : TargetUnbound |
144 | //purpose : |
145 | //======================================================================= |
146 | |
147 | Standard_Boolean TDF_ComparisonTool::TargetUnbound |
148 | (const Handle(TDF_DataSet)& aRefDataSet, |
149 | const Handle(TDF_RelocationTable)& aRelocationTable, |
150 | const TDF_IDFilter& aFilter, |
151 | const Handle(TDF_DataSet)& aDiffDataSet, |
152 | const Standard_Integer anOption) |
153 | { |
154 | if (aRefDataSet->IsEmpty()) return Standard_False; |
155 | else return Unbound(aRefDataSet, aRelocationTable, aFilter, |
156 | aDiffDataSet, anOption, Standard_False); |
157 | } |
158 | |
159 | |
160 | //======================================================================= |
161 | //function : Unbound |
162 | //purpose : Internal function used by SourceUnbound and TargetUnbound. |
163 | //======================================================================= |
164 | |
165 | Standard_Boolean TDF_ComparisonTool::Unbound |
166 | (const Handle(TDF_DataSet)& aRefDataSet, |
167 | const Handle(TDF_RelocationTable)& aRelocationTable, |
168 | const TDF_IDFilter& aFilter, |
169 | const Handle(TDF_DataSet)& aDiffDataSet, |
170 | const Standard_Integer anOption, |
171 | const Standard_Boolean theSource) |
172 | { |
173 | Standard_Boolean hasDiff = Standard_False; |
174 | |
175 | // Labels |
176 | if ((anOption & 1) != 0) { |
177 | const TDF_LabelMap& refLabs = aRefDataSet->Labels(); |
178 | TDF_LabelMap& diffLabs = aDiffDataSet->Labels(); |
179 | const TDF_LabelDataMap& the2LabMap = aRelocationTable->LabelTable(); |
180 | TDF_LabelMap theTLabMap; |
181 | if (!theSource) aRelocationTable->TargetLabelMap(theTLabMap); |
182 | for (TDF_MapIteratorOfLabelMap refLabMItr(refLabs); |
183 | refLabMItr.More(); refLabMItr.Next()) { |
184 | const TDF_Label& refLab = refLabMItr.Key(); |
185 | if (!(theSource ? |
186 | the2LabMap.IsBound(refLab) |
187 | : theTLabMap.Contains(refLab))) |
188 | diffLabs.Add(refLab); |
189 | } |
190 | hasDiff = (diffLabs.Extent()>0); |
191 | } |
192 | |
193 | // Attributes |
194 | if ((anOption & 2) != 0) { |
195 | const TDF_AttributeMap& refAtts = aRefDataSet->Attributes(); |
196 | TDF_AttributeMap& diffAtts = aDiffDataSet->Attributes(); |
197 | const TDF_AttributeDataMap& the2AttMap =aRelocationTable->AttributeTable(); |
198 | TDF_AttributeMap theTAttMap; |
199 | if (!theSource) aRelocationTable->TargetAttributeMap(theTAttMap); |
200 | for (TDF_MapIteratorOfAttributeMap refAttMItr(refAtts); |
201 | refAttMItr.More(); refAttMItr.Next()) { |
202 | const Handle(TDF_Attribute)& refAtt = refAttMItr.Key(); |
203 | if (aFilter.IsKept(refAtt)) { |
204 | if (!(theSource ? |
205 | the2AttMap.IsBound(refAtt) |
206 | : theTAttMap.Contains(refAtt))) |
207 | diffAtts.Add(refAtt); |
208 | } |
209 | } |
210 | hasDiff = (hasDiff || diffAtts.Extent()>0); |
211 | } |
212 | |
213 | return hasDiff; |
214 | } |
215 | |
216 | |
217 | //======================================================================= |
218 | //function : Cut |
219 | //purpose : Removes the attributes contained into <aDataSet> |
220 | //======================================================================= |
221 | |
222 | void TDF_ComparisonTool::Cut |
223 | (const Handle(TDF_DataSet)& aDataSet) |
224 | { |
225 | if (aDataSet->IsEmpty()) return; |
226 | |
7fd59977 |
227 | const TDF_AttributeMap& refAtts = aDataSet->Attributes(); |
228 | |
229 | // Removes the attributes. |
230 | TDF_MapIteratorOfAttributeMap refAttMItr(refAtts); |
231 | for (; refAttMItr.More(); refAttMItr.Next()) { |
232 | const Handle(TDF_Attribute)& locAtt = refAttMItr.Key(); |
233 | locAtt->Label().ForgetAttribute(locAtt); |
234 | } |
235 | } |
236 | |
237 | |
238 | //======================================================================= |
239 | //function : IsSelfContained |
240 | //purpose : Returns true if all the labels of <aDataSet> are |
241 | // descendant of <aLabel>. |
242 | //======================================================================= |
243 | |
244 | Standard_Boolean TDF_ComparisonTool::IsSelfContained |
245 | (const TDF_Label& aLabel, |
246 | const Handle(TDF_DataSet)& aDataSet) |
247 | { |
248 | if (!aDataSet->IsEmpty()) { |
249 | const TDF_LabelMap& refLabs = aDataSet->Labels(); |
250 | for (TDF_MapIteratorOfLabelMap refLabMItr(refLabs); |
251 | refLabMItr.More(); |
252 | refLabMItr.Next()) { |
253 | if (!refLabMItr.Key().IsDescendant(aLabel)) return Standard_False; |
254 | } |
255 | } |
256 | return Standard_True; |
257 | } |