1 // Created by: DAUTRY Philippe
2 // Copyright (c) 1997-1999 Matra Datavision
3 // Copyright (c) 1999-2014 OPEN CASCADE SAS
5 // This file is part of Open CASCADE Technology software library.
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
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.
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
16 // ---------------------
18 //Version Date Purpose
19 // 0.0 Mar 11 1997 Creation
21 #include <Standard_TypeMismatch.hxx>
22 #include <TDF_Attribute.hxx>
23 #include <TDF_AttributeDataMap.hxx>
24 #include <TDF_AttributeIterator.hxx>
25 #include <TDF_AttributeMap.hxx>
26 #include <TDF_ChildIterator.hxx>
27 #include <TDF_ClosureTool.hxx>
28 #include <TDF_CopyTool.hxx>
29 #include <TDF_DataMapIteratorOfAttributeDataMap.hxx>
30 #include <TDF_DataMapIteratorOfLabelDataMap.hxx>
31 #include <TDF_DataSet.hxx>
32 #include <TDF_IDFilter.hxx>
33 #include <TDF_Label.hxx>
34 #include <TDF_LabelDataMap.hxx>
35 #include <TDF_LabelMap.hxx>
36 #include <TDF_ListIteratorOfLabelList.hxx>
37 #include <TDF_MapIteratorOfAttributeMap.hxx>
38 #include <TDF_MapIteratorOfLabelMap.hxx>
39 #include <TDF_RelocationTable.hxx>
41 #define DeclareAndSpeedCast(V,T,Vdown) Handle(T) Vdown = Handle(T)::DownCast (V)
42 #define DeclareConstAndSpeedCast(V,T,Vdown) const Handle(T)& Vdown = (Handle(T)&) V
43 #define SpeedCast(V,T,Vdown) Vdown = Handle(T)::DownCast (V)
46 //=======================================================================
49 //=======================================================================
51 void TDF_CopyTool::Copy
52 (const Handle(TDF_DataSet)& aSourceDataSet,
53 const Handle(TDF_RelocationTable)& aRelocationTable)
55 TDF_IDFilter privilegeFilter; // Ignore the target attribute's privilege!
56 TDF_IDFilter refFilter; // Will not be used.
58 (aSourceDataSet, aRelocationTable, privilegeFilter,
59 refFilter, Standard_False);
63 //=======================================================================
66 //=======================================================================
68 void TDF_CopyTool::Copy
69 (const Handle(TDF_DataSet)& aSourceDataSet,
70 const Handle(TDF_RelocationTable)& aRelocationTable,
71 const TDF_IDFilter& aPrivilegeFilter)
73 TDF_IDFilter refFilter; // Will not be used.
75 (aSourceDataSet, aRelocationTable, aPrivilegeFilter,
76 refFilter, Standard_False);
80 //=======================================================================
83 //=======================================================================
85 void TDF_CopyTool::Copy
86 (const Handle(TDF_DataSet)& aSourceDataSet,
87 const Handle(TDF_RelocationTable)& aRelocationTable,
88 const TDF_IDFilter& aPrivilegeFilter,
89 const TDF_IDFilter& /* aRefFilter */,
90 const Standard_Boolean /* setSelfContained */)
92 if (aSourceDataSet->IsEmpty()) return;
94 TDF_LabelMap& srcLabs = aSourceDataSet->Labels();
95 TDF_AttributeMap& srcAtts = aSourceDataSet->Attributes();
96 TDF_LabelList& rootLst = aSourceDataSet->Roots();
98 TDF_LabelDataMap& theLabMap = aRelocationTable->LabelTable();
99 TDF_AttributeDataMap& theAttMap = aRelocationTable->AttributeTable();
101 // Parallel exploration of the root label structures:
102 // * builds the target labels not found;
103 // * binds the source attributes with the target ones;
104 // * binds the source attributes with new target ones if there is none.
106 // Label pre-binding is tested before paste.
107 // For it is possible to copy the roots at another place with OTHER TAGS,
108 // we first ask <theLabMap> if each source root label is already bound.
110 for (TDF_ListIteratorOfLabelList labLItr(rootLst);
111 labLItr.More(); labLItr.Next()) {
112 const TDF_Label& sLab = labLItr.Value();
113 if (theLabMap.IsBound(sLab)) {
114 TDF_Label tIns(theLabMap.Find(sLab));
115 TDF_CopyTool::CopyLabels(sLab,tIns,
116 theLabMap,theAttMap,srcLabs,srcAtts);
118 // if not bound : do nothing!
121 // The relocation attribute table is now ready,
122 // except for the label unattached attributes,
123 // but everybody can update the relocation table...
125 // Now: the paste phasis!
126 TDF_DataMapIteratorOfAttributeDataMap attItr2(theAttMap);
127 for (;attItr2.More(); attItr2.Next()) {
128 const Handle(TDF_Attribute)& sAtt = attItr2.Key();
129 if (!sAtt.IsNull()) { // This condition looks superfluous; and below also.
130 const Handle(TDF_Attribute)& tAtt = attItr2.Value();
131 // 1 - No copy on itself.
132 // 2 - The target attribute is present BUT its privilege over the
133 // source one must be ignored. The source attribute can be copied.
134 if ((sAtt != tAtt) && aPrivilegeFilter.IsIgnored(tAtt->ID()))
135 sAtt->Paste(tAtt,aRelocationTable);
142 //=======================================================================
143 //function : CopyLabels
144 //purpose : Internal root label copy recursive method.
145 //=======================================================================
147 void TDF_CopyTool::CopyLabels
148 (const TDF_Label& aSLabel,
149 TDF_Label& aTargetLabel,
150 TDF_LabelDataMap& aLabMap,
151 TDF_AttributeDataMap& aAttMap,
152 const TDF_LabelMap& aSrcLabelMap,
153 const TDF_AttributeMap& aSrcAttributeMap)
155 TDF_CopyTool::CopyAttributes(aSLabel,aTargetLabel,
156 aAttMap,aSrcAttributeMap);
158 // Does the same for the children.
159 for (TDF_ChildIterator childItr(aSLabel); childItr.More(); childItr.Next()){
160 const TDF_Label& childSLab = childItr.Value();
161 if (aSrcLabelMap.Contains(childSLab)) {
162 TDF_Label childTIns = aTargetLabel.FindChild(childSLab.Tag());
163 aLabMap.Bind(childSLab,childTIns);
164 TDF_CopyTool::CopyLabels(childSLab,childTIns,
166 aSrcLabelMap,aSrcAttributeMap);
172 //=======================================================================
173 //function : CopyAttributes
174 //purpose : Internal attribute copy method.
175 //=======================================================================
177 void TDF_CopyTool::CopyAttributes
178 (const TDF_Label& aSLabel,
179 TDF_Label& aTargetLabel,
180 TDF_AttributeDataMap& aAttMap,
181 const TDF_AttributeMap& aSrcAttributeMap)
183 Handle(TDF_Attribute) tAtt;
185 // Finds the target attributes or creates them empty.
186 for (TDF_AttributeIterator attItr(aSLabel);
187 attItr.More(); attItr.Next()) {
188 const Handle(TDF_Attribute) sAtt = attItr.Value();
189 if (aSrcAttributeMap.Contains(sAtt)) {
190 const Standard_GUID& id = sAtt->ID();
191 if (!aTargetLabel.FindAttribute(id,tAtt)) {
192 tAtt = sAtt->NewEmpty();
193 aTargetLabel.AddAttribute(tAtt);
194 aAttMap.Bind(sAtt,tAtt);
197 // Some attributes have the same ID, but are different and
198 // exclusive. This obliged to test the dynamic type identity.
199 if (tAtt->IsInstance(sAtt->DynamicType()))
200 aAttMap.Bind(sAtt,tAtt);
202 Standard_TypeMismatch::Raise
203 ("TDF_CopyTool: Cannot paste to a different type attribute.");