0031501: Foundation Classes, Message_Printer - remove theToPutEndl argument -- prepar...
[occt.git] / src / IFSelect / IFSelect_ModelCopier.cxx
1 // Copyright (c) 1999-2014 OPEN CASCADE SAS
2 //
3 // This file is part of Open CASCADE Technology software library.
4 //
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.
10 //
11 // Alternatively, this file may be used under the terms of Open CASCADE
12 // commercial license or contractual agreement.
13
14
15 #include <IFSelect_AppliedModifiers.hxx>
16 #include <IFSelect_ContextModif.hxx>
17 #include <IFSelect_ContextWrite.hxx>
18 #include <IFSelect_GeneralModifier.hxx>
19 #include <IFSelect_ModelCopier.hxx>
20 #include <IFSelect_Modifier.hxx>
21 #include <IFSelect_Selection.hxx>
22 #include <IFSelect_ShareOut.hxx>
23 #include <IFSelect_ShareOutResult.hxx>
24 #include <IFSelect_WorkLibrary.hxx>
25 #include <Interface_Check.hxx>
26 #include <Interface_CheckIterator.hxx>
27 #include <Interface_CopyTool.hxx>
28 #include <Interface_EntityIterator.hxx>
29 #include <Interface_GeneralLib.hxx>
30 #include <Interface_Graph.hxx>
31 #include <Interface_InterfaceModel.hxx>
32 #include <Interface_Protocol.hxx>
33 #include <Message.hxx>
34 #include <Message_Messenger.hxx>
35 #include <Standard_Type.hxx>
36 #include <TCollection_AsciiString.hxx>
37 #include <TCollection_HAsciiString.hxx>
38 #include <TColStd_HSequenceOfInteger.hxx>
39
40 #include <stdio.h>
41 IMPLEMENT_STANDARD_RTTIEXT(IFSelect_ModelCopier,Standard_Transient)
42
43 //#define MISOPOINT
44 IFSelect_ModelCopier::IFSelect_ModelCopier ()    {  }
45
46     void  IFSelect_ModelCopier::SetShareOut
47   (const Handle(IFSelect_ShareOut)& sho)
48       {  theshareout = sho;  }
49
50
51 //  ########################################################################
52 //  ########    OPERATIONS DE TRANSFERT GLOBAL (memorise ou non)    ########
53
54
55     void  IFSelect_ModelCopier::ClearResult ()
56       {  thefilemodels.Clear();  thefilenames.Clear();  theapplieds.Clear();
57          theremain.Nullify();  }
58
59
60     Standard_Boolean  IFSelect_ModelCopier::AddFile
61   (const TCollection_AsciiString& filename,
62    const Handle(Interface_InterfaceModel)& content)
63 {
64   Standard_Integer nb = thefilenames.Length();
65   for (Standard_Integer i = 1; i <= nb; i ++) {
66     if (filename.IsEmpty()) continue;
67     if (thefilenames(i).IsEqual(filename)) return Standard_False;
68   }
69   Handle(IFSelect_AppliedModifiers) nulapplied;
70   thefilenames.Append  (filename);
71   thefilemodels.Append (content);
72   theapplieds.Append   (nulapplied);
73   return Standard_True;
74 }
75
76     Standard_Boolean  IFSelect_ModelCopier::NameFile
77   (const Standard_Integer num,
78    const TCollection_AsciiString& filename)
79 {
80   Standard_Integer nb = thefilenames.Length();
81   if (num <= 0 || num > nb) return Standard_False;
82   for (Standard_Integer i = 1; i <= nb; i ++) {
83     if (filename.IsEmpty()) continue;
84     if (thefilenames(i).IsEqual(filename)) return Standard_False;
85   }
86   thefilenames.SetValue(num,filename);
87   return Standard_True;
88 }
89
90     Standard_Boolean  IFSelect_ModelCopier::ClearFile
91   (const Standard_Integer num)
92 {
93   Standard_Integer nb = thefilenames.Length();
94   if (num <= 0 || num > nb) return Standard_False;
95   thefilenames.ChangeValue(num).Clear();
96   return Standard_True;
97 }
98
99     Standard_Boolean  IFSelect_ModelCopier::SetAppliedModifiers
100   (const Standard_Integer num, const Handle(IFSelect_AppliedModifiers)& applied)
101 {
102   Standard_Integer nb = theapplieds.Length();
103   if (num <= 0 || num > nb) return Standard_False;
104   theapplieds.SetValue(num,applied);
105   return Standard_True;
106 }
107
108     Standard_Boolean  IFSelect_ModelCopier::ClearAppliedModifiers
109   (const Standard_Integer num)
110 {
111   Standard_Integer nb = theapplieds.Length();
112   if (num <= 0 || num > nb) return Standard_False;
113   theapplieds.ChangeValue(num).Nullify();
114   return Standard_True;
115 }
116
117 //  ....    Copy : Opere les Transferts, les Memorise (pas d envoi fichier ici)
118
119       Interface_CheckIterator IFSelect_ModelCopier::Copy
120   (IFSelect_ShareOutResult& eval,
121    const Handle(IFSelect_WorkLibrary)& WL,
122    const Handle(Interface_Protocol)& protocol) 
123 {
124   Interface_CopyTool TC (eval.Graph().Model(), protocol);
125   return Copying (eval,WL,protocol,TC);
126 }
127
128 //  Copy Interne
129
130     Interface_CheckIterator  IFSelect_ModelCopier::Copying
131   (IFSelect_ShareOutResult& eval,
132    const Handle(IFSelect_WorkLibrary)& WL,
133    const Handle(Interface_Protocol)& protocol,
134    Interface_CopyTool& TC)
135 {
136   Message::SendInfo() << "** WorkSession : Copying split data before sending"<<std::endl;
137   const Interface_Graph& G = eval.Graph();
138   Interface_CheckIterator checks;
139   theshareout = eval.ShareOut();
140   theremain = new TColStd_HArray1OfInteger(0,G.Size()); theremain->Init(0);
141   for (eval.Evaluate(); eval.More(); eval.Next()) {
142     Handle(Interface_InterfaceModel) model;
143     TCollection_AsciiString filename = eval.FileName();
144     Standard_Integer dispnum = eval.DispatchRank();
145     Standard_Integer numod, nbmod;
146     eval.PacketsInDispatch (numod,nbmod);
147     Handle(IFSelect_AppliedModifiers) curapp;
148     CopiedModel (G, WL,protocol, eval.PacketRoot(), filename,dispnum,numod, TC,
149                  model, curapp,checks);
150
151     AddFile (filename, model);
152     theapplieds.SetValue (theapplieds.Length(), curapp);
153   }
154   theshareout->SetLastRun (theshareout->NbDispatches());
155   checks.SetName ("X-STEP WorkSession : Split Copy (no Write)");
156   return checks;
157 }
158
159 //  Send a deux arguments : Envoi Fichier du Resultat deja memorise
160
161     Interface_CheckIterator  IFSelect_ModelCopier::SendCopied
162   (const Handle(IFSelect_WorkLibrary)& WL,
163    const Handle(Interface_Protocol)& protocol)
164 {
165   Message::SendInfo() << "** WorkSession : Sending split data already copied"<<std::endl;
166   Standard_Integer nb = NbFiles();
167   Interface_CheckIterator checks;
168   if (nb > 0) {
169     for (Standard_Integer i = 1; i <= nb; i ++) {
170       if (FileName(i).Length() == 0) continue;
171       Handle(IFSelect_AppliedModifiers) curapp = theapplieds.Value(i);
172       IFSelect_ContextWrite ctx (FileModel(i),protocol,curapp,FileName(i).ToCString());
173       Standard_Boolean res = WL->WriteFile (ctx);
174       Interface_CheckIterator checklst = ctx.CheckList();
175       checks.Merge(checklst);
176 //      (FileName(i).ToCString(), FileModel(i),protocol,curapp,checks);
177 //      if (!checks.IsEmpty(Standard_False)) {
178 //      sout<<"  **  On Sending File n0."<<i<<", Check Messages :  **"<<std::endl;
179 //      checks.Print (sout,Standard_False);
180 //      }
181       if (!res) {
182         char mess[100];  sprintf(mess,"Split Send (WriteFile) abandon on file n0.%d",i);
183         checks.CCheck(0)->AddFail (mess);
184         Message::SendInfo() << "  **  Sending File n0."<<i<<" has failed, abandon  **"<<std::endl;
185         return checks;
186       }
187       AddSentFile (FileName(i).ToCString());
188     }
189     ClearResult();
190   }
191   checks.SetName ("X-STEP WorkSession : Split Send (Copy+Write)");
192   return checks;
193 }
194
195
196 //  .... Send a 4 arguments : Calcul du Transfert et Envoi sur Fichier
197
198     Interface_CheckIterator  IFSelect_ModelCopier::Send
199   (IFSelect_ShareOutResult& eval,
200    const Handle(IFSelect_WorkLibrary)& WL,
201    const Handle(Interface_Protocol)& protocol)
202 {
203   Interface_CopyTool TC (eval.Graph().Model(), protocol);
204   return Sending (eval,WL,protocol,TC);
205 }
206
207     Interface_CheckIterator  IFSelect_ModelCopier::Sending
208   (IFSelect_ShareOutResult& eval,
209    const Handle(IFSelect_WorkLibrary)& WL,
210    const Handle(Interface_Protocol)& protocol,
211    Interface_CopyTool& TC)
212 {
213   const Interface_Graph& G = eval.Graph();
214   Interface_CheckIterator checks;
215   Standard_Integer i = 0;
216   Message::SendInfo() << "** WorkSession : Copying then sending split data"<<std::endl;
217   theshareout = eval.ShareOut();
218   theremain = new TColStd_HArray1OfInteger(0,G.Size()); theremain->Init(0);
219   for (eval.Evaluate(); eval.More(); eval.Next()) {
220     i ++;
221     Handle(Interface_InterfaceModel) model;
222     TCollection_AsciiString filename = eval.FileName();
223     Standard_Integer dispnum = eval.DispatchRank();
224     Standard_Integer numod, nbmod;
225     eval.PacketsInDispatch (numod,nbmod);
226     Handle(IFSelect_AppliedModifiers) curapp;
227     CopiedModel (G, WL,protocol, eval.PacketRoot(), filename,dispnum,numod, TC,
228                  model, curapp, checks);
229     IFSelect_ContextWrite ctx (model,protocol,curapp,filename.ToCString());
230     Standard_Boolean res = WL->WriteFile (ctx);
231     Interface_CheckIterator checklst = ctx.CheckList();
232     checks.Merge(checklst);
233 //      (filename.ToCString(), model, protocol, curapp, checks);
234 //    if (!checks.IsEmpty(Standard_False)) {
235 //      sout<<"  **  On Sending File "<<filename<<", Check Messages :  **"<<std::endl;
236 //      checks.Print (sout,model,Standard_False);
237 //    }
238     if (!res) {
239       char mess[100];  sprintf(mess,"Split Send (WriteFile) abandon on file n0.%d",i);
240       checks.CCheck(0)->AddFail (mess);
241       Message::SendInfo() << "  **  Sending File "<<filename<<" has failed, abandon  **"<<std::endl;
242       checks.SetName ("X-STEP WorkSession : Split Send (only Write)");
243       return checks;
244     }
245     AddSentFile (filename.ToCString());
246   }
247   theshareout->SetLastRun (theshareout->NbDispatches());
248   checks.SetName ("X-STEP WorkSession : Split Send (only Write)");
249   return checks;
250 }
251
252
253 //  .... SendAll : Donnees a tranferer dans G, aucun split, envoi sur fichier
254
255     Interface_CheckIterator  IFSelect_ModelCopier::SendAll
256   (const Standard_CString filename,   const Interface_Graph& G,
257    const Handle(IFSelect_WorkLibrary)& WL,
258    const Handle(Interface_Protocol)& protocol)
259 {
260   Interface_CheckIterator checks;
261   checks.SetName ("X-STEP WorkSession : Send All");
262   Message::SendInfo() << "** WorkSession : Sending all data"<<std::endl;
263   Handle(Interface_InterfaceModel)  model = G.Model();
264   if (model.IsNull() || protocol.IsNull() || WL.IsNull()) return checks;
265
266   Interface_CopyTool TC (model, protocol);
267   Standard_Integer i, nb = model->NbEntities();
268   for (i = 1; i <= nb; i ++)  TC.Bind (model->Value(i),model->Value(i));
269
270   Interface_EntityIterator pipo;
271   Handle(Interface_InterfaceModel)  newmod;
272   Handle(IFSelect_AppliedModifiers) applied;
273   CopiedModel (G, WL,protocol,pipo,TCollection_AsciiString(filename),
274                0,0,TC,newmod, applied,checks);
275
276   IFSelect_ContextWrite ctx (model,protocol,applied,filename);
277   Standard_Boolean res = WL->WriteFile (ctx);
278   Interface_CheckIterator checklst = ctx.CheckList();
279   checks.Merge(checklst);
280   if (!res) checks.CCheck(0)->AddFail ("SendAll (WriteFile) has failed");
281 //  if (!checks.IsEmpty(Standard_False)) {
282 //    Message::SendWarning() <<
283 //      "  **    SendAll has produced Check Messages :    **"<<std::endl;
284 //    checks.Print (sout,model,Standard_False);
285 //  }
286   return checks;
287 }
288
289
290 //  .... SendSelected : Donnees a tranferer dans G, filtrees par iter,
291 //       aucun split, envoi sur fichier
292
293     Interface_CheckIterator  IFSelect_ModelCopier::SendSelected
294   (const Standard_CString filename,   const Interface_Graph& G,
295    const Handle(IFSelect_WorkLibrary)& WL,
296    const Handle(Interface_Protocol)& protocol,
297    const Interface_EntityIterator& list)
298 {
299   Interface_CheckIterator checks;
300   checks.SetName ("X-STEP WorkSession : Send Selected");
301   Message::SendInfo() << "** WorkSession : Sending selected data"<<std::endl;
302   Handle(Interface_InterfaceModel)  original = G.Model();
303   if (original.IsNull() || protocol.IsNull() || WL.IsNull()) return checks;
304   Handle(Interface_InterfaceModel) newmod  = original->NewEmptyModel();
305   Interface_CopyTool TC (original, protocol);
306   TC.FillModel(newmod);    // pour Header ...
307
308 //  Pas de copie : AddWithRefs plus declaration de Bind
309   Interface_GeneralLib lib(protocol);
310   for (list.Start(); list.More(); list.Next()) {
311     newmod->AddWithRefs (list.Value(),lib);
312   }
313   Standard_Integer i, nb = newmod->NbEntities();
314   for (i = 1; i <= nb; i ++)  TC.Bind (newmod->Value(i),newmod->Value(i));
315   if (theremain.IsNull())
316     { theremain = new TColStd_HArray1OfInteger(0,G.Size()); theremain->Init(0); }
317
318   Interface_EntityIterator pipo;
319   Handle(IFSelect_AppliedModifiers) applied;
320   CopiedModel (G, WL,protocol, pipo,TCollection_AsciiString(filename),
321                0,0,TC,newmod, applied,checks);
322 //  Alimenter Remaining : les entites copiees sont a noter
323   Handle(Standard_Transient) ent1,ent2;
324   for (Standard_Integer ic = TC.LastCopiedAfter (0,ent1,ent2); ic > 0;
325        ic = TC.LastCopiedAfter (ic,ent1,ent2) ) {
326     if (ic <= theremain->Upper())
327       theremain->SetValue(ic,theremain->Value(ic)+1);
328   }
329   IFSelect_ContextWrite ctx (newmod,protocol,applied,filename);
330   Standard_Boolean res = WL->WriteFile (ctx);
331   Interface_CheckIterator checklst = ctx.CheckList();
332   checks.Merge(checklst);
333   if (!res) checks.CCheck(0)->AddFail ("SendSelected (WriteFile) has failed");
334 //  if (!checks.IsEmpty(Standard_False)) {
335 //    Message::SendWarning() <<
336 //      "  **    SendSelected has produced Check Messages :    **"<<std::endl;
337 //    checks.Print (sout,original,Standard_False);
338 //  }
339   return checks;
340 }
341
342
343 //  ##########################################################################
344 //  ########        UN TRANSFERT UNITAIRE (avec Modifications)        ########
345
346     void  IFSelect_ModelCopier::CopiedModel
347   (const Interface_Graph& G,
348    const Handle(IFSelect_WorkLibrary)& WL,
349    const Handle(Interface_Protocol)& protocol,
350    const Interface_EntityIterator& tocopy,
351    const TCollection_AsciiString& filename,
352    const Standard_Integer dispnum, const Standard_Integer /* numod */,
353    Interface_CopyTool& TC,
354    Handle(Interface_InterfaceModel)& newmod,
355    Handle(IFSelect_AppliedModifiers)& applied,
356    Interface_CheckIterator& checks) const
357 {
358 //  ...  Premiere partie "standard" : remplissage du modele  ...
359 //  On cree le Modele, on le remplit avec les Entites, et avec le Header depart
360
361 //  ATTENTION : dispnum = 0  signifie prendre modele original, ne rien copier
362 //                             et aussi : pas de Dispatch (envoi en bloc)
363
364   applied.Nullify();
365   Handle(Interface_InterfaceModel) original = G.Model();
366   if (dispnum > 0) {
367     newmod  = original->NewEmptyModel();
368     TC.Clear();
369     WL->CopyModel (original,newmod,tocopy,TC);
370
371     Handle(Standard_Transient) ent1,ent2;
372 //  Alimenter Remaining : les entites copiees sont a noter
373     for (Standard_Integer ic = TC.LastCopiedAfter (0,ent1,ent2); ic > 0;
374          ic = TC.LastCopiedAfter (ic,ent1,ent2) ) {
375       if (ic <= theremain->Upper())
376         theremain->SetValue(ic,theremain->Value(ic)+1);
377     }
378   }
379   else if (newmod.IsNull()) newmod = original;
380
381 //  ...  Ensuite : On prend en compte les Model Modifiers  ...
382   Standard_Integer nbmod = 0;
383   if (!theshareout.IsNull()) nbmod = theshareout->NbModifiers(Standard_True);
384   Standard_Integer i; // svv Jan11 2000 : porting on DEC
385   for (i = 1; i <= nbmod; i ++) {
386     Handle(IFSelect_Modifier) unmod = theshareout->ModelModifier(i);
387
388 //    D abord,  critere Dispatch/Packet
389     if (dispnum > 0)
390       if (!unmod->Applies (theshareout->Dispatch(dispnum))) continue;
391     IFSelect_ContextModif ctx (G,TC,filename.ToCString());
392 //    Ensuite, la Selection
393     Handle(IFSelect_Selection) sel = unmod->Selection();
394     if (!sel.IsNull()) {
395       Interface_EntityIterator entiter = sel->UniqueResult(G);
396       ctx.Select (entiter);
397     }
398     if (ctx.IsForNone()) continue;
399     unmod->Perform (ctx,newmod,protocol,TC);
400     Interface_CheckIterator checklst = ctx.CheckList();
401     checks.Merge (checklst);
402
403 //    Faut-il enregistrer les erreurs dans newmod ? bonne question
404 //    if (!checks.IsEmpty(Standard_False)) {
405 //      Message::SendWarning() <<
406 //        " Messages on Copied Model n0 "<<numod<<", Dispatch Rank "<<dispnum<<std::endl;
407 //      checks.Print(sout,newmod,Standard_False);
408 //    }
409   }
410
411 //  ...  Puis les File Modifiers : en fait, on les enregistre  ...
412   nbmod = 0;
413   if (!theshareout.IsNull()) nbmod = theshareout->NbModifiers(Standard_False);
414   if (nbmod == 0) return;
415   applied = new IFSelect_AppliedModifiers (nbmod,newmod->NbEntities());
416   for (i = 1; i <= nbmod; i ++) {
417     Handle(IFSelect_GeneralModifier) unmod = theshareout->GeneralModifier(Standard_False,i);
418
419 //    D abord,  critere Dispatch/Packet
420     if (dispnum > 0)
421       if (!unmod->Applies (theshareout->Dispatch(dispnum))) continue;
422 //    Ensuite, la Selection
423     Handle(IFSelect_Selection) sel = unmod->Selection();
424     if (sel.IsNull()) applied->AddModif (unmod);    // vide -> on prend tout
425     else {
426       Interface_EntityIterator list = sel->UniqueResult(G);
427       Handle(Standard_Transient) newent;
428
429 //    Entites designees par la Selection et Copiees ?
430 //    -> s ilyena au moins une, le Modifier s applique, sinon il est rejete
431 //    -> et cette liste est exploitable par le Modifier ...
432       for (list.Start(); list.More(); list.Next()) {
433         if (TC.Search (list.Value(),newent))
434           applied->AddNum (newmod->Number(newent));
435       }
436     }
437   }
438 }
439
440
441     void  IFSelect_ModelCopier::CopiedRemaining
442   (const Interface_Graph& G, const Handle(IFSelect_WorkLibrary)& WL,
443    Interface_CopyTool& TC,   Handle(Interface_InterfaceModel)& newmod)
444 {
445   Handle(Interface_InterfaceModel) original = G.Model();
446 //  Interface_CopyTool TC(original,protocol);
447   newmod  = original->NewEmptyModel();
448   TC.Clear();
449   Interface_EntityIterator tocopy;
450   Standard_Integer nb = G.Size();
451   theremain = new TColStd_HArray1OfInteger(0,nb+1); theremain->Init(0);
452   for (Standard_Integer i = 1; i <= nb; i ++) {
453     if (G.Status(i) == 0) tocopy.AddItem (original->Value(i));
454     else theremain->SetValue(i,-1);  //  ?? -1
455   }
456   WL->CopyModel (original,newmod,tocopy,TC);
457
458   if (newmod->NbEntities() == 0) newmod.Nullify();
459   else {
460 //  CE QUI SUIT NE DOIT PAS ETRE SUPPRIME ! cf theremain
461     Handle(Standard_Transient) ent1,ent2;
462     for (Standard_Integer ic = TC.LastCopiedAfter (0,ent1,ent2); ic > 0;
463          ic = TC.LastCopiedAfter (ic,ent1,ent2) ) {
464       if (ic <= theremain->Upper())
465         theremain->SetValue(ic,1);
466     }
467 //  qq impressions de mise au point
468 #ifdef MISOPOINT
469     std::cout << " Remaining Model : " << newmod->NbEntities() << " Entities"<<std::endl;
470     Standard_Integer ne = 0;
471     for (i = 1; i <= nb; i ++) {
472       if (theremain->Value(i) == 0) {
473         if (ne == 0)     std::cout << " Refractaires : ";
474         ne ++;  std::cout << " " << i;
475       }
476     }
477     if (ne > 0) std::cout << "  -- " << ne << " Entities" << std::endl;
478     else std::cout<<"  -- Remaining data complete"<<std::endl;
479 #endif
480   }
481 }
482
483     Standard_Boolean  IFSelect_ModelCopier::SetRemaining
484   (Interface_Graph& CG) const
485 {
486   Standard_Integer nb = CG.Size();
487   if (theremain.IsNull()) return (nb == 0);
488   if (nb != theremain->Upper()) return Standard_False;
489   for (Standard_Integer i = 1; i <= nb; i ++) {
490     if (CG.Status(i) >= 0) CG.SetStatus(i,CG.Status(i)+theremain->Value(i));
491   }
492   theremain->Init(0);
493   return Standard_True;
494 }
495
496 //  ##########################################################################
497 //  ########        RESULTAT de la Memorisation des Transferts        ########
498
499     Standard_Integer  IFSelect_ModelCopier::NbFiles () const 
500       {  return thefilemodels.Length();  }
501
502     TCollection_AsciiString  IFSelect_ModelCopier::FileName
503   (const Standard_Integer num) const 
504       {  return thefilenames.Value(num);  }
505
506     Handle(Interface_InterfaceModel)  IFSelect_ModelCopier::FileModel
507   (const Standard_Integer num) const
508       {  return thefilemodels.Value(num);  }
509
510     Handle(IFSelect_AppliedModifiers)  IFSelect_ModelCopier::AppliedModifiers
511   (const Standard_Integer num) const
512       {  return theapplieds.Value(num);  }
513
514
515     void  IFSelect_ModelCopier::BeginSentFiles
516   (const Handle(IFSelect_ShareOut)& sho, const Standard_Boolean record)
517 {
518   thesentfiles.Nullify();
519   if (record) thesentfiles = new TColStd_HSequenceOfHAsciiString();
520 //  et numerotation des fichiers par defaut : detenue par ShareOut
521   if (sho.IsNull()) return;
522   Standard_Integer lastrun = sho->LastRun();
523   sho->ClearResult (Standard_True);
524   sho->SetLastRun (lastrun);        // on ne s interesse quaux numeros
525 }
526
527     void  IFSelect_ModelCopier::AddSentFile (const Standard_CString filename)
528       {  if (!thesentfiles.IsNull())
529            thesentfiles->Append(new TCollection_HAsciiString(filename));  }
530
531     Handle(TColStd_HSequenceOfHAsciiString)  IFSelect_ModelCopier::SentFiles () const
532       {  return thesentfiles;  }