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