1 // Created by: DAUTRY Philippe
2 // Copyright (c) 1997-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 Mar 11 1997 Creation
28 #include <TDF_CopyTool.ixx>
30 #include <TDF_ClosureTool.hxx>
31 #include <TDF_Attribute.hxx>
32 #include <TDF_AttributeDataMap.hxx>
33 #include <TDF_AttributeIterator.hxx>
34 #include <TDF_AttributeMap.hxx>
35 #include <TDF_ChildIterator.hxx>
36 #include <TDF_DataMapIteratorOfAttributeDataMap.hxx>
37 #include <TDF_DataMapIteratorOfLabelDataMap.hxx>
38 #include <TDF_Label.hxx>
39 #include <TDF_LabelDataMap.hxx>
40 #include <TDF_LabelMap.hxx>
41 #include <TDF_ListIteratorOfLabelList.hxx>
42 #include <TDF_MapIteratorOfAttributeMap.hxx>
43 #include <TDF_MapIteratorOfLabelMap.hxx>
45 #include <Standard_TypeMismatch.hxx>
47 #define DeclareAndSpeedCast(V,T,Vdown) Handle(T) Vdown = *((Handle(T)*)& V)
48 #define DeclareConstAndSpeedCast(V,T,Vdown) const Handle(T)& Vdown = (Handle(T)&) V
49 #define SpeedCast(V,T,Vdown) Vdown = *((Handle(T)*)& V)
52 //=======================================================================
55 //=======================================================================
57 void TDF_CopyTool::Copy
58 (const Handle(TDF_DataSet)& aSourceDataSet,
59 const Handle(TDF_RelocationTable)& aRelocationTable)
61 TDF_IDFilter privilegeFilter; // Ignore the target attribute's privilege!
62 TDF_IDFilter refFilter; // Will not be used.
64 (aSourceDataSet, aRelocationTable, privilegeFilter,
65 refFilter, Standard_False);
69 //=======================================================================
72 //=======================================================================
74 void TDF_CopyTool::Copy
75 (const Handle(TDF_DataSet)& aSourceDataSet,
76 const Handle(TDF_RelocationTable)& aRelocationTable,
77 const TDF_IDFilter& aPrivilegeFilter)
79 TDF_IDFilter refFilter; // Will not be used.
81 (aSourceDataSet, aRelocationTable, aPrivilegeFilter,
82 refFilter, Standard_False);
86 //=======================================================================
89 //=======================================================================
91 void TDF_CopyTool::Copy
92 (const Handle(TDF_DataSet)& aSourceDataSet,
93 const Handle(TDF_RelocationTable)& aRelocationTable,
94 const TDF_IDFilter& aPrivilegeFilter,
95 const TDF_IDFilter& /* aRefFilter */,
96 const Standard_Boolean /* setSelfContained */)
98 if (aSourceDataSet->IsEmpty()) return;
100 TDF_LabelMap& srcLabs = aSourceDataSet->Labels();
101 TDF_AttributeMap& srcAtts = aSourceDataSet->Attributes();
102 TDF_LabelList& rootLst = aSourceDataSet->Roots();
104 TDF_LabelDataMap& theLabMap = aRelocationTable->LabelTable();
105 TDF_AttributeDataMap& theAttMap = aRelocationTable->AttributeTable();
107 // Parallel exploration of the root label structures:
108 // * builds the target labels not found;
109 // * binds the source attributes with the target ones;
110 // * binds the source attributes with new target ones if there is none.
112 // Label pre-binding is tested before paste.
113 // For it is possible to copy the roots at another place with OTHER TAGS,
114 // we first ask <theLabMap> if each source root label is already bound.
116 for (TDF_ListIteratorOfLabelList labLItr(rootLst);
117 labLItr.More(); labLItr.Next()) {
118 const TDF_Label& sLab = labLItr.Value();
119 if (theLabMap.IsBound(sLab)) {
120 TDF_Label tIns(theLabMap.Find(sLab));
121 TDF_CopyTool::CopyLabels(sLab,tIns,
122 theLabMap,theAttMap,srcLabs,srcAtts);
124 // if not bound : do nothing!
127 // The relocation attribute table is now ready,
128 // except for the label unattached attributes,
129 // but everybody can update the relocation table...
131 // Now: the paste phasis!
132 TDF_DataMapIteratorOfAttributeDataMap attItr2(theAttMap);
133 for (;attItr2.More(); attItr2.Next()) {
134 const Handle(TDF_Attribute)& sAtt = attItr2.Key();
135 if (!sAtt.IsNull()) { // This condition looks superfluous; and below also.
136 const Handle(TDF_Attribute)& tAtt = attItr2.Value();
137 // 1 - No copy on itself.
138 // 2 - The target attribute is present BUT its privilege over the
139 // source one must be ignored. The source attribute can be copied.
140 if ((sAtt != tAtt) && aPrivilegeFilter.IsIgnored(tAtt->ID()))
141 sAtt->Paste(tAtt,aRelocationTable);
148 //=======================================================================
149 //function : CopyLabels
150 //purpose : Internal root label copy recursive method.
151 //=======================================================================
153 void TDF_CopyTool::CopyLabels
154 (const TDF_Label& aSLabel,
155 TDF_Label& aTargetLabel,
156 TDF_LabelDataMap& aLabMap,
157 TDF_AttributeDataMap& aAttMap,
158 const TDF_LabelMap& aSrcLabelMap,
159 const TDF_AttributeMap& aSrcAttributeMap)
161 TDF_CopyTool::CopyAttributes(aSLabel,aTargetLabel,
162 aAttMap,aSrcAttributeMap);
164 // Does the same for the children.
165 for (TDF_ChildIterator childItr(aSLabel); childItr.More(); childItr.Next()){
166 const TDF_Label& childSLab = childItr.Value();
167 if (aSrcLabelMap.Contains(childSLab)) {
168 TDF_Label childTIns = aTargetLabel.FindChild(childSLab.Tag());
169 aLabMap.Bind(childSLab,childTIns);
170 TDF_CopyTool::CopyLabels(childSLab,childTIns,
172 aSrcLabelMap,aSrcAttributeMap);
178 //=======================================================================
179 //function : CopyAttributes
180 //purpose : Internal attribute copy method.
181 //=======================================================================
183 void TDF_CopyTool::CopyAttributes
184 (const TDF_Label& aSLabel,
185 TDF_Label& aTargetLabel,
186 TDF_AttributeDataMap& aAttMap,
187 const TDF_AttributeMap& aSrcAttributeMap)
189 Handle(TDF_Attribute) tAtt;
191 // Finds the target attributes or creates them empty.
192 for (TDF_AttributeIterator attItr(aSLabel);
193 attItr.More(); attItr.Next()) {
194 const Handle(TDF_Attribute) sAtt = attItr.Value();
195 if (aSrcAttributeMap.Contains(sAtt)) {
196 const Standard_GUID& id = sAtt->ID();
197 if (!aTargetLabel.FindAttribute(id,tAtt)) {
198 tAtt = sAtt->NewEmpty();
199 aTargetLabel.AddAttribute(tAtt);
200 aAttMap.Bind(sAtt,tAtt);
203 // Some attributes have the same ID, but are different and
204 // exclusive. This obliged to test the dynamic type identity.
205 if (tAtt->IsInstance(sAtt->DynamicType()))
206 aAttMap.Bind(sAtt,tAtt);
208 Standard_TypeMismatch::Raise
209 ("TDF_CopyTool: Cannot paste to a different type attribute.");