973c2be1 |
1 | // Copyright (c) 1999-2014 OPEN CASCADE SAS |
b311480e |
2 | // |
973c2be1 |
3 | // This file is part of Open CASCADE Technology software library. |
b311480e |
4 | // |
d5f74e42 |
5 | // This library is free software; you can redistribute it and/or modify it under |
6 | // the terms of the GNU Lesser General Public License version 2.1 as published |
973c2be1 |
7 | // by the Free Software Foundation, with special exception defined in the file |
8 | // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT |
9 | // distribution for complete text of the license and disclaimer of any warranty. |
b311480e |
10 | // |
973c2be1 |
11 | // Alternatively, this file may be used under the terms of Open CASCADE |
12 | // commercial license or contractual agreement. |
b311480e |
13 | |
7fd59977 |
14 | #include <Interface_CopyTool.ixx> |
15 | #include <Interface_GeneralModule.hxx> |
16 | #include <Interface_ReportEntity.hxx> |
17 | #include <Interface_InterfaceError.hxx> |
18 | #include <TCollection_HAsciiString.hxx> |
19 | |
20 | |
21 | // Se souvenir qu une version plus riche de CopyTool existe : c est |
22 | // TransferDispatch (package Transfer). Cette classe offre beaucoup plus de |
23 | // possibilite (parametrage des actions, gestion du Mapping ...) |
24 | // Mais le principe (transfert en 2 passes) reste le meme, a savoir : |
25 | // Passe 1 normale : les entites a transferer sont designees, elles entrainent |
26 | // leurs sous-references vraies |
27 | // Passe 2 : une fois tous les transferts faits, les relations "Imply" sont |
28 | // mises, pour les entites designees ET QUI ONT ETE AUSSI TRANSFEREES, la |
29 | // relation est reconduite (pas de nouveau Share) |
30 | |
31 | |
32 | // ##################################################################### |
33 | // .... CONSTRUCTEURS .... |
34 | |
b311480e |
35 | Interface_CopyTool::Interface_CopyTool |
7fd59977 |
36 | (const Handle(Interface_InterfaceModel)& amodel, |
37 | const Interface_GeneralLib& lib) |
38 | : thelib (lib) , thelst (amodel->NbEntities()) |
39 | { |
40 | thelst.Init(Standard_False); |
41 | themod = amodel; |
42 | themap = new Interface_CopyMap (amodel); |
43 | therep = new Interface_CopyMap (amodel); |
44 | thelev = 0; theimp = Standard_False; |
45 | } |
46 | |
47 | Interface_CopyTool::Interface_CopyTool |
48 | (const Handle(Interface_InterfaceModel)& amodel, |
49 | const Handle(Interface_Protocol)& protocol) |
50 | : thelib (protocol) , thelst (amodel->NbEntities()) |
51 | { |
52 | thelst.Init(Standard_False); |
53 | themod = amodel; |
54 | themap = new Interface_CopyMap (amodel); |
55 | therep = new Interface_CopyMap (amodel); |
56 | thelev = 0; theimp = Standard_False; |
57 | } |
58 | |
59 | |
60 | Interface_CopyTool::Interface_CopyTool |
61 | (const Handle(Interface_InterfaceModel)& amodel) |
62 | : thelib (Interface_Protocol::Active()) , thelst (amodel->NbEntities()) |
63 | { |
64 | if (Interface_Protocol::Active().IsNull()) Interface_InterfaceError::Raise |
65 | ("Interface CopyTool : Create with Active Protocol undefined"); |
66 | |
67 | thelst.Init(Standard_False); |
68 | themod = amodel; |
69 | themap = new Interface_CopyMap (amodel); |
70 | therep = new Interface_CopyMap (amodel); |
71 | thelev = 0; theimp = Standard_False; |
72 | } |
73 | |
74 | Handle(Interface_InterfaceModel) Interface_CopyTool::Model () const |
75 | { return themod; } |
76 | |
77 | void Interface_CopyTool::SetControl |
78 | (const Handle(Interface_CopyControl)& othermap) |
79 | { themap = othermap; } |
80 | |
81 | Handle(Interface_CopyControl) Interface_CopyTool::Control () const |
82 | { return themap; } |
83 | |
84 | |
85 | // ##################################################################### |
86 | // .... Actions Individuelles .... |
87 | |
88 | void Interface_CopyTool::Clear () |
89 | { |
90 | themap->Clear(); |
91 | therep->Clear(); |
92 | thelev = 0; theimp = Standard_False; |
93 | therts.Clear(); |
94 | ClearLastFlags(); |
95 | } |
96 | |
97 | Standard_Boolean Interface_CopyTool::NewVoid |
98 | (const Handle(Standard_Transient)& entfrom, |
99 | Handle(Standard_Transient)& entto) |
100 | { |
101 | if (entfrom == theent) { |
102 | if (themdu.IsNull()) return Standard_False; |
103 | return themdu->NewVoid(theCN,entto); |
104 | } |
105 | theent = entfrom; |
106 | Standard_Boolean res = thelib.Select (entfrom,themdu,theCN); |
107 | if (res) res = themdu->NewVoid (theCN,entto); |
108 | if (!res) res = themdu->NewCopiedCase (theCN,entfrom,entto,*this); |
109 | // if (!res) entto = entfrom->ShallowCopy(); sorry, nothing more possible |
110 | return res; |
111 | } |
112 | |
113 | |
114 | Standard_Boolean Interface_CopyTool::Copy |
115 | (const Handle(Standard_Transient)& entfrom, |
116 | Handle(Standard_Transient)& entto, |
117 | const Standard_Boolean mapped, const Standard_Boolean errstat) |
118 | { |
119 | Standard_Boolean res = Standard_True; |
120 | if (entfrom == theent) { |
121 | if (themdu.IsNull()) res = Standard_False; |
122 | } else { |
123 | theent = entfrom; |
124 | res = thelib.Select(entfrom,themdu,theCN); |
125 | } |
126 | if (!res) { |
127 | // Built-in : |
128 | if (entfrom.IsNull()) return res; |
129 | if (entfrom->DynamicType() == STANDARD_TYPE(TCollection_HAsciiString)) { |
130 | entto = new TCollection_HAsciiString |
131 | ( Handle(TCollection_HAsciiString)::DownCast(entfrom)->ToCString() ); |
132 | res = Standard_True; |
133 | } |
134 | return res; |
135 | } |
136 | // On cree l Entite vide (NewVoid), la Copie reste a faire |
137 | res = NewVoid(entfrom,entto); |
138 | if (mapped) themap->Bind (entfrom,entto); // Mapper avant de continuer ... |
139 | |
140 | // A present, on effectue la Copie (selon cas; si ShallowCopy ne suffit pas : |
141 | // c est <themdu> qui decide) |
142 | |
143 | // Une Entite en Erreur n est pas copiee (pas de sens et c est risque ...) |
144 | // Cependant, elle est "Copiee a Vide (NewVoid)" donc referencable |
145 | if (!errstat) themdu->CopyCase(theCN,entfrom,entto,*this); |
146 | return res; |
147 | } |
148 | |
149 | void Interface_CopyTool::Implied |
150 | (const Handle(Standard_Transient)& entfrom, |
151 | const Handle(Standard_Transient)& entto) |
152 | { |
153 | Handle(Interface_GeneralModule) module; |
154 | Standard_Integer CN; |
155 | if (thelib.Select(entfrom,module,CN)) |
156 | module->RenewImpliedCase(CN,entfrom,entto,*this); |
157 | } |
158 | |
159 | |
160 | // .... Alimentation de la Map .... |
161 | |
162 | Handle(Standard_Transient) Interface_CopyTool::Transferred |
163 | (const Handle(Standard_Transient)& ent) |
164 | { |
165 | Handle(Standard_Transient) res; |
166 | if (ent.IsNull()) return res; // Copie d un Null : tres simple ... |
167 | Standard_Integer nument = themod->Number(ent); |
168 | |
169 | // <nument> == 0 -> Peut etre une sous-partie non partagee ... |
170 | // On accepte mais on se protege contre un bouclage |
171 | if (nument == 0 && thelev > 100) Interface_InterfaceError::Raise |
172 | ("CopyTool : Transferred, Entity is not contained in Starting Model"); |
173 | if (!themap->Search(ent,res)) { // deja transfere ? sinon, le faire |
174 | |
175 | // On opere la Copie (enfin, on tente) |
176 | // En cas d echec, rien n est enregistre |
177 | if (!Copy(ent,res, (nument != 0), themod->IsRedefinedContent(nument) )) |
178 | return res; |
179 | |
180 | thelev ++; |
181 | if (nument != 0) thelst.SetTrue (nument); |
182 | Handle(Interface_ReportEntity) rep; |
183 | if (nument != 0) rep = themod->ReportEntity (nument); |
184 | if (!rep.IsNull()) { |
185 | // ATTENTION ATTENTION, si ReportEntity : Copier aussi Content et refaire une |
186 | // ReportEntity avec les termes initiaux |
187 | if (rep->IsUnknown()) therep->Bind |
188 | (ent, new Interface_ReportEntity(res)); |
189 | else { |
190 | Handle(Standard_Transient) contfrom, contto; |
191 | contfrom = rep->Content(); |
192 | Handle(Interface_ReportEntity) repto = |
193 | new Interface_ReportEntity (rep->Check(),res); |
194 | if (!contfrom.IsNull()) { |
195 | if (contfrom == ent) contto = res; |
196 | else Copy (contfrom,contto, themod->Contains(contfrom), Standard_False); |
197 | repto->SetContent (contto); |
198 | } |
199 | therep->Bind (ent,repto); |
200 | } |
201 | } |
202 | // Gerer le niveau d imbrication (0 = racine du transfert) |
203 | thelev --; |
204 | } |
205 | if (thelev == 0 && nument > 0) therts.Append(nument); |
206 | return res; |
207 | } |
208 | |
209 | void Interface_CopyTool::Bind |
210 | (const Handle(Standard_Transient)& ent, |
211 | const Handle(Standard_Transient)& res) |
212 | { |
213 | Standard_Integer num = themod->Number(ent); |
214 | themap->Bind (ent,res); |
215 | thelst.SetTrue (num); |
216 | } |
217 | |
218 | Standard_Boolean Interface_CopyTool::Search |
219 | (const Handle(Standard_Transient)& ent, |
220 | Handle(Standard_Transient)& res) const |
221 | { return themap->Search (ent,res); } |
222 | |
223 | // ## ## ## ## ## ## ## ## ## ## ## ## ## |
224 | // LastFlag |
225 | |
226 | void Interface_CopyTool::ClearLastFlags () |
227 | { thelst.Init(Standard_False); } |
228 | |
229 | Standard_Integer Interface_CopyTool::LastCopiedAfter |
230 | (const Standard_Integer numfrom, |
231 | Handle(Standard_Transient)& ent, Handle(Standard_Transient)& res) const |
232 | { |
233 | Standard_Integer nb = thelst.Length(); |
234 | for (Standard_Integer num = numfrom + 1; num <= nb; num ++) { |
235 | if (thelst.Value(num)) { |
236 | ent = themod->Value(num); |
237 | if (themap->Search(ent,res)) return num; |
238 | } |
239 | } |
240 | return 0; |
241 | } |
242 | |
243 | |
244 | // ######################################################################### |
245 | // .... Actions Generales .... |
246 | |
247 | void Interface_CopyTool::TransferEntity |
248 | (const Handle(Standard_Transient)& ent) |
249 | { Handle(Standard_Transient) res = Transferred(ent); } |
250 | |
251 | void Interface_CopyTool::RenewImpliedRefs () |
252 | { |
253 | if (theimp) return; // deja fait |
254 | theimp = Standard_True; |
255 | |
256 | // Transfert Passe 2 : recuperation des relations non "Share" (mais "Imply") |
257 | // c-a-d portant sur des entites qui ont pu ou non etre transferees |
258 | // (Et que la 1re passe n a pas copie mais laisse en Null) |
259 | // N.B. : on devrait interdire de commander des nouveaux transferts ... |
260 | |
261 | Standard_Integer nb = themod->NbEntities(); |
262 | for (Standard_Integer i = 1; i <= nb; i ++) { |
263 | Handle(Standard_Transient) ent = themod->Value(i); |
264 | Handle(Standard_Transient) res; |
265 | if (!themap->Search(ent,res)) continue; // entite pas transferee |
266 | // Reconduction des references "Imply". Attention, ne pas copier si non chargee |
267 | Handle(Interface_ReportEntity) rep; |
268 | if (!therep->Search(ent,rep)) Implied (ent,res); |
269 | else if (!rep->HasNewContent()) Implied (ent,res); |
270 | } |
271 | } |
272 | |
273 | |
274 | void Interface_CopyTool::FillModel |
275 | (const Handle(Interface_InterfaceModel)& bmodel) |
276 | { |
277 | // Travaux preparatoires concernant les modeles |
278 | // On commence : cela implique le Header |
279 | bmodel->Clear(); |
280 | bmodel->GetFromAnother(themod); |
281 | |
282 | // Transfert Passe 1 : On prend les Entites prealablement copiees |
283 | Interface_EntityIterator list = CompleteResult(Standard_True); |
284 | bmodel->GetFromTransfer(list); |
285 | |
286 | // Transfert Passe 2 : recuperation des relations non "Share" (mais "Imply") |
287 | RenewImpliedRefs(); |
288 | } |
289 | |
290 | |
291 | Interface_EntityIterator Interface_CopyTool::CompleteResult |
292 | (const Standard_Boolean withreports) const |
293 | { |
294 | Interface_EntityIterator iter; |
295 | Standard_Integer nb = themod->NbEntities(); |
296 | for (Standard_Integer i = 1; i <= nb; i ++) { |
297 | Handle(Standard_Transient) ent = themod->Value(i); |
298 | Handle(Standard_Transient) res; |
299 | if (!themap->Search(ent,res)) continue; |
300 | if (withreports) { |
301 | Handle(Interface_ReportEntity) rep; |
302 | if (therep->Search(ent,rep)) res = rep; |
303 | } |
304 | iter.GetOneItem(res); |
305 | } |
306 | return iter; |
307 | } |
308 | |
309 | Interface_EntityIterator Interface_CopyTool::RootResult |
310 | (const Standard_Boolean withreports) const |
311 | { |
312 | Interface_EntityIterator iter; |
313 | Standard_Integer nb = therts.Length(); |
314 | for (Standard_Integer i = 1; i <= nb; i ++) { |
315 | Standard_Integer j = therts.Value(i); |
316 | Handle(Standard_Transient) ent = themod->Value(j); |
317 | Handle(Standard_Transient) res; |
318 | if (!themap->Search(ent,res)) continue; |
319 | if (withreports) { |
320 | Handle(Interface_ReportEntity) rep; |
321 | if (therep->Search(ent,rep)) res = rep; |
322 | } |
323 | iter.GetOneItem(res); |
324 | } |
325 | return iter; |
326 | } |
327 | |
328 | void Interface_CopyTool::Destroy(){} |