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