1 // Copyright (c) 1999-2014 OPEN CASCADE SAS
3 // This file is part of Open CASCADE Technology software library.
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
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.
11 // Alternatively, this file may be used under the terms of Open CASCADE
12 // commercial license or contractual agreement.
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>
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)
32 // #####################################################################
33 // .... CONSTRUCTEURS ....
35 Interface_CopyTool::Interface_CopyTool
36 (const Handle(Interface_InterfaceModel)& amodel,
37 const Interface_GeneralLib& lib)
38 : thelib (lib) , thelst (amodel->NbEntities())
40 thelst.Init(Standard_False);
42 themap = new Interface_CopyMap (amodel);
43 therep = new Interface_CopyMap (amodel);
44 thelev = 0; theimp = Standard_False;
47 Interface_CopyTool::Interface_CopyTool
48 (const Handle(Interface_InterfaceModel)& amodel,
49 const Handle(Interface_Protocol)& protocol)
50 : thelib (protocol) , thelst (amodel->NbEntities())
52 thelst.Init(Standard_False);
54 themap = new Interface_CopyMap (amodel);
55 therep = new Interface_CopyMap (amodel);
56 thelev = 0; theimp = Standard_False;
60 Interface_CopyTool::Interface_CopyTool
61 (const Handle(Interface_InterfaceModel)& amodel)
62 : thelib (Interface_Protocol::Active()) , thelst (amodel->NbEntities())
64 if (Interface_Protocol::Active().IsNull()) Interface_InterfaceError::Raise
65 ("Interface CopyTool : Create with Active Protocol undefined");
67 thelst.Init(Standard_False);
69 themap = new Interface_CopyMap (amodel);
70 therep = new Interface_CopyMap (amodel);
71 thelev = 0; theimp = Standard_False;
74 Handle(Interface_InterfaceModel) Interface_CopyTool::Model () const
77 void Interface_CopyTool::SetControl
78 (const Handle(Interface_CopyControl)& othermap)
79 { themap = othermap; }
81 Handle(Interface_CopyControl) Interface_CopyTool::Control () const
85 // #####################################################################
86 // .... Actions Individuelles ....
88 void Interface_CopyTool::Clear ()
92 thelev = 0; theimp = Standard_False;
97 Standard_Boolean Interface_CopyTool::NewVoid
98 (const Handle(Standard_Transient)& entfrom,
99 Handle(Standard_Transient)& entto)
101 if (entfrom == theent) {
102 if (themdu.IsNull()) return Standard_False;
103 return themdu->NewVoid(theCN,entto);
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
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)
119 Standard_Boolean res = Standard_True;
120 if (entfrom == theent) {
121 if (themdu.IsNull()) res = Standard_False;
124 res = thelib.Select(entfrom,themdu,theCN);
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() );
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 ...
140 // A present, on effectue la Copie (selon cas; si ShallowCopy ne suffit pas :
141 // c est <themdu> qui decide)
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);
149 void Interface_CopyTool::Implied
150 (const Handle(Standard_Transient)& entfrom,
151 const Handle(Standard_Transient)& entto)
153 Handle(Interface_GeneralModule) module;
155 if (thelib.Select(entfrom,module,CN))
156 module->RenewImpliedCase(CN,entfrom,entto,*this);
160 // .... Alimentation de la Map ....
162 Handle(Standard_Transient) Interface_CopyTool::Transferred
163 (const Handle(Standard_Transient)& ent)
165 Handle(Standard_Transient) res;
166 if (ent.IsNull()) return res; // Copie d un Null : tres simple ...
167 Standard_Integer nument = themod->Number(ent);
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
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) ))
181 if (nument != 0) thelst.SetTrue (nument);
182 Handle(Interface_ReportEntity) rep;
183 if (nument != 0) rep = themod->ReportEntity (nument);
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));
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);
199 therep->Bind (ent,repto);
202 // Gerer le niveau d imbrication (0 = racine du transfert)
205 if (thelev == 0 && nument > 0) therts.Append(nument);
209 void Interface_CopyTool::Bind
210 (const Handle(Standard_Transient)& ent,
211 const Handle(Standard_Transient)& res)
213 Standard_Integer num = themod->Number(ent);
214 themap->Bind (ent,res);
215 thelst.SetTrue (num);
218 Standard_Boolean Interface_CopyTool::Search
219 (const Handle(Standard_Transient)& ent,
220 Handle(Standard_Transient)& res) const
221 { return themap->Search (ent,res); }
223 // ## ## ## ## ## ## ## ## ## ## ## ## ##
226 void Interface_CopyTool::ClearLastFlags ()
227 { thelst.Init(Standard_False); }
229 Standard_Integer Interface_CopyTool::LastCopiedAfter
230 (const Standard_Integer numfrom,
231 Handle(Standard_Transient)& ent, Handle(Standard_Transient)& res) const
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;
244 // #########################################################################
245 // .... Actions Generales ....
247 void Interface_CopyTool::TransferEntity
248 (const Handle(Standard_Transient)& ent)
249 { Handle(Standard_Transient) res = Transferred(ent); }
251 void Interface_CopyTool::RenewImpliedRefs ()
253 if (theimp) return; // deja fait
254 theimp = Standard_True;
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 ...
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);
274 void Interface_CopyTool::FillModel
275 (const Handle(Interface_InterfaceModel)& bmodel)
277 // Travaux preparatoires concernant les modeles
278 // On commence : cela implique le Header
280 bmodel->GetFromAnother(themod);
282 // Transfert Passe 1 : On prend les Entites prealablement copiees
283 Interface_EntityIterator list = CompleteResult(Standard_True);
284 bmodel->GetFromTransfer(list);
286 // Transfert Passe 2 : recuperation des relations non "Share" (mais "Imply")
291 Interface_EntityIterator Interface_CopyTool::CompleteResult
292 (const Standard_Boolean withreports) const
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;
301 Handle(Interface_ReportEntity) rep;
302 if (therep->Search(ent,rep)) res = rep;
304 iter.GetOneItem(res);
309 Interface_EntityIterator Interface_CopyTool::RootResult
310 (const Standard_Boolean withreports) const
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;
320 Handle(Interface_ReportEntity) rep;
321 if (therep->Search(ent,rep)) res = rep;
323 iter.GetOneItem(res);
328 //=======================================================================
329 //function : ~Interface_CopyTool
330 //purpose : Destructor
331 //=======================================================================
333 Interface_CopyTool::~Interface_CopyTool()