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 <IFSelect_ModelCopier.ixx>
15 #include <IFSelect_Selection.hxx>
16 #include <IFSelect_GeneralModifier.hxx>
17 #include <IFSelect_Modifier.hxx>
18 #include <IFSelect_ContextModif.hxx>
19 #include <IFSelect_ContextWrite.hxx>
20 #include <TColStd_HSequenceOfInteger.hxx>
21 #include <TCollection_HAsciiString.hxx>
22 #include <Interface_Check.hxx>
23 #include <Interface_CheckIterator.hxx>
24 #include <Interface_GeneralLib.hxx>
25 #include <Message_Messenger.hxx>
26 #include <Message.hxx>
32 IFSelect_ModelCopier::IFSelect_ModelCopier () { }
34 void IFSelect_ModelCopier::SetShareOut
35 (const Handle(IFSelect_ShareOut)& sho)
36 { theshareout = sho; }
39 // ########################################################################
40 // ######## OPERATIONS DE TRANSFERT GLOBAL (memorise ou non) ########
43 void IFSelect_ModelCopier::ClearResult ()
44 { thefilemodels.Clear(); thefilenames.Clear(); theapplieds.Clear();
45 theremain.Nullify(); }
48 Standard_Boolean IFSelect_ModelCopier::AddFile
49 (const TCollection_AsciiString& filename,
50 const Handle(Interface_InterfaceModel)& content)
52 Standard_Integer nb = thefilenames.Length();
53 for (Standard_Integer i = 1; i <= nb; i ++) {
54 if (filename.IsEmpty()) continue;
55 if (thefilenames(i).IsEqual(filename)) return Standard_False;
57 Handle(IFSelect_AppliedModifiers) nulapplied;
58 thefilenames.Append (filename);
59 thefilemodels.Append (content);
60 theapplieds.Append (nulapplied);
64 Standard_Boolean IFSelect_ModelCopier::NameFile
65 (const Standard_Integer num,
66 const TCollection_AsciiString& filename)
68 Standard_Integer nb = thefilenames.Length();
69 if (num <= 0 || num > nb) return Standard_False;
70 for (Standard_Integer i = 1; i <= nb; i ++) {
71 if (filename.IsEmpty()) continue;
72 if (thefilenames(i).IsEqual(filename)) return Standard_False;
74 thefilenames.SetValue(num,filename);
78 Standard_Boolean IFSelect_ModelCopier::ClearFile
79 (const Standard_Integer num)
81 Standard_Integer nb = thefilenames.Length();
82 if (num <= 0 || num > nb) return Standard_False;
83 thefilenames.ChangeValue(num).Clear();
87 Standard_Boolean IFSelect_ModelCopier::SetAppliedModifiers
88 (const Standard_Integer num, const Handle(IFSelect_AppliedModifiers)& applied)
90 Standard_Integer nb = theapplieds.Length();
91 if (num <= 0 || num > nb) return Standard_False;
92 theapplieds.SetValue(num,applied);
96 Standard_Boolean IFSelect_ModelCopier::ClearAppliedModifiers
97 (const Standard_Integer num)
99 Standard_Integer nb = theapplieds.Length();
100 if (num <= 0 || num > nb) return Standard_False;
101 theapplieds.ChangeValue(num).Nullify();
102 return Standard_True;
105 // .... Copy : Opere les Transferts, les Memorise (pas d envoi fichier ici)
107 Interface_CheckIterator IFSelect_ModelCopier::Copy
108 (IFSelect_ShareOutResult& eval,
109 const Handle(IFSelect_WorkLibrary)& WL,
110 const Handle(Interface_Protocol)& protocol)
112 Interface_CopyTool TC (eval.Graph().Model(), protocol);
113 return Copying (eval,WL,protocol,TC);
118 Interface_CheckIterator IFSelect_ModelCopier::Copying
119 (IFSelect_ShareOutResult& eval,
120 const Handle(IFSelect_WorkLibrary)& WL,
121 const Handle(Interface_Protocol)& protocol,
122 Interface_CopyTool& TC)
124 Message::DefaultMessenger() <<
125 "** WorkSession : Copying split data before sending"<<endl;
126 const Interface_Graph& G = eval.Graph();
127 Interface_CheckIterator checks;
128 theshareout = eval.ShareOut();
129 theremain = new TColStd_HArray1OfInteger(0,G.Size()); theremain->Init(0);
130 for (eval.Evaluate(); eval.More(); eval.Next()) {
131 Handle(Interface_InterfaceModel) model;
132 TCollection_AsciiString filename = eval.FileName();
133 Standard_Integer dispnum = eval.DispatchRank();
134 Standard_Integer numod, nbmod;
135 eval.PacketsInDispatch (numod,nbmod);
136 Handle(IFSelect_AppliedModifiers) curapp;
137 CopiedModel (G, WL,protocol, eval.PacketRoot(), filename,dispnum,numod, TC,
138 model, curapp,checks);
140 AddFile (filename, model);
141 theapplieds.SetValue (theapplieds.Length(), curapp);
143 theshareout->SetLastRun (theshareout->NbDispatches());
144 checks.SetName ("X-STEP WorkSession : Split Copy (no Write)");
148 // Send a deux arguments : Envoi Fichier du Resultat deja memorise
150 Interface_CheckIterator IFSelect_ModelCopier::SendCopied
151 (const Handle(IFSelect_WorkLibrary)& WL,
152 const Handle(Interface_Protocol)& protocol)
154 Message::DefaultMessenger() <<
155 "** WorkSession : Sending split data already copied"<<endl;
156 Standard_Integer nb = NbFiles();
157 Interface_CheckIterator checks;
159 for (Standard_Integer i = 1; i <= nb; i ++) {
160 if (FileName(i).Length() == 0) continue;
161 Handle(IFSelect_AppliedModifiers) curapp = theapplieds.Value(i);
162 IFSelect_ContextWrite ctx (FileModel(i),protocol,curapp,FileName(i).ToCString());
163 Standard_Boolean res = WL->WriteFile (ctx);
164 Interface_CheckIterator checklst = ctx.CheckList();
165 checks.Merge(checklst);
166 // (FileName(i).ToCString(), FileModel(i),protocol,curapp,checks);
167 // if (!checks.IsEmpty(Standard_False)) {
168 // sout<<" ** On Sending File n0."<<i<<", Check Messages : **"<<endl;
169 // checks.Print (sout,Standard_False);
172 char mess[100]; sprintf(mess,"Split Send (WriteFile) abandon on file n0.%d",i);
173 checks.CCheck(0)->AddFail (mess);
174 Message::DefaultMessenger() <<
175 " ** Sending File n0."<<i<<" has failed, abandon **"<<endl;
178 AddSentFile (FileName(i).ToCString());
182 checks.SetName ("X-STEP WorkSession : Split Send (Copy+Write)");
187 // .... Send a 4 arguments : Calcul du Transfert et Envoi sur Fichier
189 Interface_CheckIterator IFSelect_ModelCopier::Send
190 (IFSelect_ShareOutResult& eval,
191 const Handle(IFSelect_WorkLibrary)& WL,
192 const Handle(Interface_Protocol)& protocol)
194 Interface_CopyTool TC (eval.Graph().Model(), protocol);
195 return Sending (eval,WL,protocol,TC);
198 Interface_CheckIterator IFSelect_ModelCopier::Sending
199 (IFSelect_ShareOutResult& eval,
200 const Handle(IFSelect_WorkLibrary)& WL,
201 const Handle(Interface_Protocol)& protocol,
202 Interface_CopyTool& TC)
204 const Interface_Graph& G = eval.Graph();
205 Interface_CheckIterator checks;
206 Standard_Integer i = 0;
207 Message::DefaultMessenger() <<
208 "** WorkSession : Copying then sending split data"<<endl;
209 theshareout = eval.ShareOut();
210 theremain = new TColStd_HArray1OfInteger(0,G.Size()); theremain->Init(0);
211 for (eval.Evaluate(); eval.More(); eval.Next()) {
213 Handle(Interface_InterfaceModel) model;
214 TCollection_AsciiString filename = eval.FileName();
215 Standard_Integer dispnum = eval.DispatchRank();
216 Standard_Integer numod, nbmod;
217 eval.PacketsInDispatch (numod,nbmod);
218 Handle(IFSelect_AppliedModifiers) curapp;
219 CopiedModel (G, WL,protocol, eval.PacketRoot(), filename,dispnum,numod, TC,
220 model, curapp, checks);
221 IFSelect_ContextWrite ctx (model,protocol,curapp,filename.ToCString());
222 Standard_Boolean res = WL->WriteFile (ctx);
223 Interface_CheckIterator checklst = ctx.CheckList();
224 checks.Merge(checklst);
225 // (filename.ToCString(), model, protocol, curapp, checks);
226 // if (!checks.IsEmpty(Standard_False)) {
227 // sout<<" ** On Sending File "<<filename<<", Check Messages : **"<<endl;
228 // checks.Print (sout,model,Standard_False);
231 char mess[100]; sprintf(mess,"Split Send (WriteFile) abandon on file n0.%d",i);
232 checks.CCheck(0)->AddFail (mess);
233 Message::DefaultMessenger() <<
234 " ** Sending File "<<filename<<" has failed, abandon **"<<endl;
235 checks.SetName ("X-STEP WorkSession : Split Send (only Write)");
238 AddSentFile (filename.ToCString());
240 theshareout->SetLastRun (theshareout->NbDispatches());
241 checks.SetName ("X-STEP WorkSession : Split Send (only Write)");
246 // .... SendAll : Donnees a tranferer dans G, aucun split, envoi sur fichier
248 Interface_CheckIterator IFSelect_ModelCopier::SendAll
249 (const Standard_CString filename, const Interface_Graph& G,
250 const Handle(IFSelect_WorkLibrary)& WL,
251 const Handle(Interface_Protocol)& protocol)
253 Interface_CheckIterator checks;
254 checks.SetName ("X-STEP WorkSession : Send All");
255 Message::DefaultMessenger() <<
256 "** WorkSession : Sending all data"<<endl;
257 Handle(Interface_InterfaceModel) model = G.Model();
258 if (model.IsNull() || protocol.IsNull() || WL.IsNull()) return checks;
260 Interface_CopyTool TC (model, protocol);
261 Standard_Integer i, nb = model->NbEntities();
262 for (i = 1; i <= nb; i ++) TC.Bind (model->Value(i),model->Value(i));
264 Interface_EntityIterator pipo;
265 Handle(Interface_InterfaceModel) newmod;
266 Handle(IFSelect_AppliedModifiers) applied;
267 CopiedModel (G, WL,protocol,pipo,TCollection_AsciiString(filename),
268 0,0,TC,newmod, applied,checks);
270 IFSelect_ContextWrite ctx (model,protocol,applied,filename);
271 Standard_Boolean res = WL->WriteFile (ctx);
272 Interface_CheckIterator checklst = ctx.CheckList();
273 checks.Merge(checklst);
274 if (!res) checks.CCheck(0)->AddFail ("SendAll (WriteFile) has failed");
275 // if (!checks.IsEmpty(Standard_False)) {
276 // Message::DefaultMessenger() <<
277 // " ** SendAll has produced Check Messages : **"<<endl;
278 // checks.Print (sout,model,Standard_False);
284 // .... SendSelected : Donnees a tranferer dans G, filtrees par iter,
285 // aucun split, envoi sur fichier
287 Interface_CheckIterator IFSelect_ModelCopier::SendSelected
288 (const Standard_CString filename, const Interface_Graph& G,
289 const Handle(IFSelect_WorkLibrary)& WL,
290 const Handle(Interface_Protocol)& protocol,
291 const Interface_EntityIterator& list)
293 Interface_CheckIterator checks;
294 checks.SetName ("X-STEP WorkSession : Send Selected");
295 Message::DefaultMessenger() <<
296 "** WorkSession : Sending selected data"<<endl;
297 Handle(Interface_InterfaceModel) original = G.Model();
298 if (original.IsNull() || protocol.IsNull() || WL.IsNull()) return checks;
299 Handle(Interface_InterfaceModel) newmod = original->NewEmptyModel();
300 Interface_CopyTool TC (original, protocol);
301 TC.FillModel(newmod); // pour Header ...
303 // Pas de copie : AddWithRefs plus declaration de Bind
304 Interface_GeneralLib lib(protocol);
305 for (list.Start(); list.More(); list.Next()) {
306 newmod->AddWithRefs (list.Value(),lib);
308 Standard_Integer i, nb = newmod->NbEntities();
309 for (i = 1; i <= nb; i ++) TC.Bind (newmod->Value(i),newmod->Value(i));
310 if (theremain.IsNull())
311 { theremain = new TColStd_HArray1OfInteger(0,G.Size()); theremain->Init(0); }
313 Interface_EntityIterator pipo;
314 Handle(IFSelect_AppliedModifiers) applied;
315 CopiedModel (G, WL,protocol, pipo,TCollection_AsciiString(filename),
316 0,0,TC,newmod, applied,checks);
317 // Alimenter Remaining : les entites copiees sont a noter
318 Handle(Standard_Transient) ent1,ent2;
319 for (Standard_Integer ic = TC.LastCopiedAfter (0,ent1,ent2); ic > 0;
320 ic = TC.LastCopiedAfter (ic,ent1,ent2) ) {
321 if (ic <= theremain->Upper())
322 theremain->SetValue(ic,theremain->Value(ic)+1);
324 IFSelect_ContextWrite ctx (newmod,protocol,applied,filename);
325 Standard_Boolean res = WL->WriteFile (ctx);
326 Interface_CheckIterator checklst = ctx.CheckList();
327 checks.Merge(checklst);
328 if (!res) checks.CCheck(0)->AddFail ("SendSelected (WriteFile) has failed");
329 // if (!checks.IsEmpty(Standard_False)) {
330 // Message::DefaultMessenger() <<
331 // " ** SendSelected has produced Check Messages : **"<<endl;
332 // checks.Print (sout,original,Standard_False);
338 // ##########################################################################
339 // ######## UN TRANSFERT UNITAIRE (avec Modifications) ########
341 void IFSelect_ModelCopier::CopiedModel
342 (const Interface_Graph& G,
343 const Handle(IFSelect_WorkLibrary)& WL,
344 const Handle(Interface_Protocol)& protocol,
345 const Interface_EntityIterator& tocopy,
346 const TCollection_AsciiString& filename,
347 const Standard_Integer dispnum, const Standard_Integer /* numod */,
348 Interface_CopyTool& TC,
349 Handle(Interface_InterfaceModel)& newmod,
350 Handle(IFSelect_AppliedModifiers)& applied,
351 Interface_CheckIterator& checks) const
353 // ... Premiere partie "standard" : remplissage du modele ...
354 // On cree le Modele, on le remplit avec les Entites, et avec le Header depart
356 // ATTENTION : dispnum = 0 signifie prendre modele original, ne rien copier
357 // et aussi : pas de Dispatch (envoi en bloc)
360 Handle(Interface_InterfaceModel) original = G.Model();
362 newmod = original->NewEmptyModel();
364 WL->CopyModel (original,newmod,tocopy,TC);
366 Handle(Standard_Transient) ent1,ent2;
367 // Alimenter Remaining : les entites copiees sont a noter
368 for (Standard_Integer ic = TC.LastCopiedAfter (0,ent1,ent2); ic > 0;
369 ic = TC.LastCopiedAfter (ic,ent1,ent2) ) {
370 if (ic <= theremain->Upper())
371 theremain->SetValue(ic,theremain->Value(ic)+1);
374 else if (newmod.IsNull()) newmod = original;
376 // ... Ensuite : On prend en compte les Model Modifiers ...
377 Standard_Integer nbmod = 0;
378 if (!theshareout.IsNull()) nbmod = theshareout->NbModifiers(Standard_True);
379 Standard_Integer i; // svv Jan11 2000 : porting on DEC
380 for (i = 1; i <= nbmod; i ++) {
381 Handle(IFSelect_Modifier) unmod = theshareout->ModelModifier(i);
383 // D abord, critere Dispatch/Packet
385 if (!unmod->Applies (theshareout->Dispatch(dispnum))) continue;
386 IFSelect_ContextModif ctx (G,TC,filename.ToCString());
387 // Ensuite, la Selection
388 Handle(IFSelect_Selection) sel = unmod->Selection();
390 Interface_EntityIterator entiter = sel->UniqueResult(G);
391 ctx.Select (entiter);
393 if (ctx.IsForNone()) continue;
394 unmod->Perform (ctx,newmod,protocol,TC);
395 Interface_CheckIterator checklst = ctx.CheckList();
396 checks.Merge (checklst);
398 // Faut-il enregistrer les erreurs dans newmod ? bonne question
399 // if (!checks.IsEmpty(Standard_False)) {
400 // Message::DefaultMessenger() <<
401 // " Messages on Copied Model n0 "<<numod<<", Dispatch Rank "<<dispnum<<endl;
402 // checks.Print(sout,newmod,Standard_False);
406 // ... Puis les File Modifiers : en fait, on les enregistre ...
408 if (!theshareout.IsNull()) nbmod = theshareout->NbModifiers(Standard_False);
409 if (nbmod == 0) return;
410 applied = new IFSelect_AppliedModifiers (nbmod,newmod->NbEntities());
411 for (i = 1; i <= nbmod; i ++) {
412 Handle(IFSelect_GeneralModifier) unmod = theshareout->GeneralModifier(Standard_False,i);
414 // D abord, critere Dispatch/Packet
416 if (!unmod->Applies (theshareout->Dispatch(dispnum))) continue;
417 // Ensuite, la Selection
418 Handle(IFSelect_Selection) sel = unmod->Selection();
419 if (sel.IsNull()) applied->AddModif (unmod); // vide -> on prend tout
421 Interface_EntityIterator list = sel->UniqueResult(G);
422 Handle(Standard_Transient) newent;
424 // Entites designees par la Selection et Copiees ?
425 // -> s ilyena au moins une, le Modifier s applique, sinon il est rejete
426 // -> et cette liste est exploitable par le Modifier ...
427 for (list.Start(); list.More(); list.Next()) {
428 if (TC.Search (list.Value(),newent))
429 applied->AddNum (newmod->Number(newent));
436 void IFSelect_ModelCopier::CopiedRemaining
437 (const Interface_Graph& G, const Handle(IFSelect_WorkLibrary)& WL,
438 Interface_CopyTool& TC, Handle(Interface_InterfaceModel)& newmod)
440 Handle(Interface_InterfaceModel) original = G.Model();
441 // Interface_CopyTool TC(original,protocol);
442 newmod = original->NewEmptyModel();
444 Interface_EntityIterator tocopy;
445 Standard_Integer nb = G.Size();
446 theremain = new TColStd_HArray1OfInteger(0,nb+1); theremain->Init(0);
447 for (Standard_Integer i = 1; i <= nb; i ++) {
448 if (G.Status(i) == 0) tocopy.AddItem (original->Value(i));
449 else theremain->SetValue(i,-1); // ?? -1
451 WL->CopyModel (original,newmod,tocopy,TC);
453 if (newmod->NbEntities() == 0) newmod.Nullify();
455 // CE QUI SUIT NE DOIT PAS ETRE SUPPRIME ! cf theremain
456 Handle(Standard_Transient) ent1,ent2;
457 for (Standard_Integer ic = TC.LastCopiedAfter (0,ent1,ent2); ic > 0;
458 ic = TC.LastCopiedAfter (ic,ent1,ent2) ) {
459 if (ic <= theremain->Upper())
460 theremain->SetValue(ic,1);
462 // qq impressions de mise au point
464 cout << " Remaining Model : " << newmod->NbEntities() << " Entities"<<endl;
465 Standard_Integer ne = 0;
466 for (i = 1; i <= nb; i ++) {
467 if (theremain->Value(i) == 0) {
468 if (ne == 0) cout << " Refractaires : ";
469 ne ++; cout << " " << i;
472 if (ne > 0) cout << " -- " << ne << " Entities" << endl;
473 else cout<<" -- Remaining data complete"<<endl;
478 Standard_Boolean IFSelect_ModelCopier::SetRemaining
479 (Interface_Graph& CG) const
481 Standard_Integer nb = CG.Size();
482 if (theremain.IsNull()) return (nb == 0);
483 if (nb != theremain->Upper()) return Standard_False;
484 for (Standard_Integer i = 1; i <= nb; i ++) {
485 if (CG.Status(i) >= 0) CG.SetStatus(i,CG.Status(i)+theremain->Value(i));
488 return Standard_True;
491 // ##########################################################################
492 // ######## RESULTAT de la Memorisation des Transferts ########
494 Standard_Integer IFSelect_ModelCopier::NbFiles () const
495 { return thefilemodels.Length(); }
497 TCollection_AsciiString IFSelect_ModelCopier::FileName
498 (const Standard_Integer num) const
499 { return thefilenames.Value(num); }
501 Handle(Interface_InterfaceModel) IFSelect_ModelCopier::FileModel
502 (const Standard_Integer num) const
503 { return thefilemodels.Value(num); }
505 Handle(IFSelect_AppliedModifiers) IFSelect_ModelCopier::AppliedModifiers
506 (const Standard_Integer num) const
507 { return theapplieds.Value(num); }
510 void IFSelect_ModelCopier::BeginSentFiles
511 (const Handle(IFSelect_ShareOut)& sho, const Standard_Boolean record)
513 thesentfiles.Nullify();
514 if (record) thesentfiles = new TColStd_HSequenceOfHAsciiString();
515 // et numerotation des fichiers par defaut : detenue par ShareOut
516 if (sho.IsNull()) return;
517 Standard_Integer lastrun = sho->LastRun();
518 sho->ClearResult (Standard_True);
519 sho->SetLastRun (lastrun); // on ne s interesse quaux numeros
522 void IFSelect_ModelCopier::AddSentFile (const Standard_CString filename)
523 { if (!thesentfiles.IsNull())
524 thesentfiles->Append(new TCollection_HAsciiString(filename)); }
526 Handle(TColStd_HSequenceOfHAsciiString) IFSelect_ModelCopier::SentFiles () const
527 { return thesentfiles; }