0026937: Eliminate NO_CXX_EXCEPTION macro support
[occt.git] / src / Interface / Interface_CopyTool.cxx
CommitLineData
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 39Interface_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
343Interface_CopyTool::~Interface_CopyTool()
344{
345}