0027349: XtControl_Reader is not thread-safe
[occt.git] / src / XSControl / XSControl_TransferReader.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 //:   abv 09.04.99: S4136: remove parameter lastpreci
15 // szv#11:CASCADE30:01Feb00 BRepBuilderAPI::Precision(p) removed
16
17 #include <BRepBuilderAPI.hxx>
18 #include <BRepLib.hxx>
19 #include <Dico_DictionaryOfTransient.hxx>
20 #include <IFSelect_CheckCounter.hxx>
21 #include <IFSelect_SignatureList.hxx>
22 #include <Interface_Check.hxx>
23 #include <Interface_CheckIterator.hxx>
24 #include <Interface_EntityIterator.hxx>
25 #include <Interface_Graph.hxx>
26 #include <Interface_HGraph.hxx>
27 #include <Interface_InterfaceModel.hxx>
28 #include <Interface_Macros.hxx>
29 #include <Interface_MSG.hxx>
30 #include <Interface_SignLabel.hxx>
31 #include <Interface_Static.hxx>
32 #include <Message_Messenger.hxx>
33 #include <ShapeFix.hxx>
34 #include <Standard_ErrorHandler.hxx>
35 #include <Standard_Failure.hxx>
36 #include <Standard_Transient.hxx>
37 #include <Standard_Type.hxx>
38 #include <TCollection_HAsciiString.hxx>
39 #include <TColStd_HSequenceOfTransient.hxx>
40 #include <TopoDS_HShape.hxx>
41 #include <TopoDS_Shape.hxx>
42 #include <TopTools_MapOfShape.hxx>
43 #include <Transfer_ActorOfTransientProcess.hxx>
44 #include <Transfer_IteratorOfProcessForTransient.hxx>
45 #include <Transfer_ResultFromModel.hxx>
46 #include <Transfer_ResultFromTransient.hxx>
47 #include <Transfer_SimpleBinderOfTransient.hxx>
48 #include <Transfer_TransferOutput.hxx>
49 #include <Transfer_TransientProcess.hxx>
50 #include <TransferBRep.hxx>
51 #include <TransferBRep_BinderOfShape.hxx>
52 #include <TransferBRep_ShapeBinder.hxx>
53 #include <XSControl_Controller.hxx>
54 #include <XSControl_TransferReader.hxx>
55 #include <XSControl_Utils.hxx>
56
57 #include <stdio.h>
58 IMPLEMENT_STANDARD_RTTIEXT(XSControl_TransferReader,MMgt_TShared)
59
60 //=======================================================================
61 //function : SetController
62 //purpose  : 
63 //=======================================================================
64
65 void XSControl_TransferReader::SetController(const Handle(XSControl_Controller)& control)
66 {
67   myController = control;
68   myActor.Nullify();
69   Clear(-1);
70 }
71
72
73 //=======================================================================
74 //function : Actor
75 //purpose  : 
76 //=======================================================================
77
78 Handle(Transfer_ActorOfTransientProcess) XSControl_TransferReader::Actor ()
79 {
80   if ( myActor.IsNull() && !myController.IsNull() && !myModel.IsNull())
81     myActor = myController->ActorRead(myModel);
82   return myActor;
83 }
84
85
86 //=======================================================================
87 //function : SetModel
88 //purpose  : 
89 //=======================================================================
90
91 void XSControl_TransferReader::SetModel(const Handle(Interface_InterfaceModel)& model)
92 {
93   myModel = model;
94   if (!myTP.IsNull()) myTP->SetModel(model);
95 }
96
97
98 //=======================================================================
99 //function : SetGraph
100 //purpose  : 
101 //=======================================================================
102
103 void XSControl_TransferReader::SetGraph(const Handle(Interface_HGraph)& graph)
104 {
105   if (graph.IsNull())
106   {
107     myModel.Nullify();
108   }
109   else
110     myModel = graph->Graph().Model();
111
112   myGraph = graph;
113   
114   if (!myTP.IsNull()) myTP->SetGraph(graph);
115 }
116
117
118 //=======================================================================
119 //function : SetContext
120 //purpose  : 
121 //=======================================================================
122
123 void XSControl_TransferReader::SetContext(const Standard_CString name,
124                                           const Handle(Standard_Transient)& ctx)
125 {
126   if (myContext.IsNull()) myContext = new Dico_DictionaryOfTransient;
127   myContext->SetItem (name,ctx);
128 }
129
130
131 //=======================================================================
132 //function : GetContext
133 //purpose  : 
134 //=======================================================================
135
136 Standard_Boolean XSControl_TransferReader::GetContext
137   (const Standard_CString name, const Handle(Standard_Type)& type,
138    Handle(Standard_Transient)& ctx) const
139 {
140   if (myContext.IsNull()) return Standard_False;
141   if (!myContext->GetItem (name,ctx)) ctx.Nullify();
142   if (ctx.IsNull()) return Standard_False;
143   if (type.IsNull()) return Standard_True;
144   if (!ctx->IsKind(type)) ctx.Nullify();
145   return !ctx.IsNull();
146 }
147
148
149 //=======================================================================
150 //function : Clear
151 //purpose  : 
152 //=======================================================================
153
154 void XSControl_TransferReader::Clear (const Standard_Integer mode)
155 {
156   if (mode & 1) {
157     myResults.Clear();
158     myShapeResult.Nullify();
159   }
160   if (mode & 2) {
161     myModel.Nullify();
162     myGraph.Nullify();
163     myTP.Nullify();
164     myActor.Nullify();
165     myFileName.Clear();
166   }  
167 }
168
169
170 //  ########################################################
171 //  ###########            RESULTATS            ############
172
173
174 //=======================================================================
175 //function : RecordResult
176 //purpose  : 
177 //=======================================================================
178
179 Standard_Boolean XSControl_TransferReader::RecordResult
180   (const Handle(Standard_Transient)& ent)
181 {
182   if (myModel.IsNull() || myTP.IsNull()) return Standard_False;
183   Standard_Integer num = myModel->Number(ent);
184   if (num == 0) return Standard_False;
185   Handle(TCollection_HAsciiString) lab = myModel->StringLabel(ent);
186
187   Handle(Transfer_ResultFromModel) res = new Transfer_ResultFromModel;
188   res->Fill (myTP,ent);
189
190   //   Cas du resultat Shape : pour resultat principal, faire HShape ...
191   Handle(Transfer_Binder) binder = res->MainResult()->Binder();
192   DeclareAndCast(TransferBRep_ShapeBinder,shb,binder);
193   if (!shb.IsNull()) {
194     Handle(Transfer_SimpleBinderOfTransient) trb = new Transfer_SimpleBinderOfTransient;
195     trb->SetResult ( new TopoDS_HShape(shb->Result()) );
196     trb->Merge(binder);
197     res->MainResult()->SetBinder (trb);
198   }
199
200   res->SetFileName(myFileName.ToCString());
201   myResults.Bind(num,res);
202   return Standard_True;
203 }
204
205
206 //=======================================================================
207 //function : IsRecorded
208 //purpose  : 
209 //=======================================================================
210
211 Standard_Boolean XSControl_TransferReader::IsRecorded
212   (const Handle(Standard_Transient)& ent) const
213 {
214   if (myModel.IsNull()) return Standard_False;
215   Standard_Integer num = myModel->Number(ent);
216   if (num == 0) return Standard_False;
217   if(!myResults.IsBound(num)) return Standard_False;
218   return (myResults.Find(num)->DynamicType() == STANDARD_TYPE(Transfer_ResultFromModel) );
219 }
220
221
222 //=======================================================================
223 //function : HasResult
224 //purpose  : 
225 //=======================================================================
226
227 Standard_Boolean  XSControl_TransferReader::HasResult
228   (const Handle(Standard_Transient)& ent) const
229 {
230   if (myModel.IsNull()) return Standard_False;
231   Standard_Integer num = myModel->Number(ent);
232   if (num == 0) return Standard_False;
233   if(!myResults.IsBound(num)) return Standard_False;
234   DeclareAndCast(Transfer_ResultFromModel,fr,myResults.Find(num));
235   if (fr.IsNull()) return Standard_False;
236   return fr->HasResult();
237 }
238
239
240 //=======================================================================
241 //function : RecordedList
242 //purpose  : 
243 //=======================================================================
244
245 Handle(TColStd_HSequenceOfTransient) XSControl_TransferReader::RecordedList () const
246 {
247   Handle(TColStd_HSequenceOfTransient) li = new TColStd_HSequenceOfTransient();
248   if (myModel.IsNull())   return li;
249   Standard_Integer i, nb = myModel->NbEntities();
250   for (i = 1; i <= nb; i ++) {
251     if(myResults.IsBound(i))
252       if(!myResults.Find(i).IsNull()) li->Append (myModel->Value(i));
253   }
254   return li;
255 }
256
257
258 //=======================================================================
259 //function : Skip
260 //purpose  : 
261 //=======================================================================
262
263 Standard_Boolean XSControl_TransferReader::Skip(const Handle(Standard_Transient)& ent)
264 {
265   if (myModel.IsNull() || myTP.IsNull()) return Standard_False;
266   Standard_Integer num = myModel->Number(ent);
267   if (num == 0) return Standard_False;
268   myResults.Bind(num,ent);
269   return Standard_True;
270 }
271
272
273 //=======================================================================
274 //function : IsSkipped
275 //purpose  : 
276 //=======================================================================
277
278 Standard_Boolean XSControl_TransferReader::IsSkipped
279   (const Handle(Standard_Transient)& ent) const
280 {
281   if (myModel.IsNull()) return Standard_False;
282   Standard_Integer num = myModel->Number(ent);
283   if (num == 0) return Standard_False;
284   if(!myResults.IsBound(num)) return Standard_False;
285   return (myResults.Find(num)->DynamicType() != STANDARD_TYPE(Transfer_ResultFromModel) );
286 }
287
288
289 //=======================================================================
290 //function : IsMarked
291 //purpose  : 
292 //=======================================================================
293
294 Standard_Boolean XSControl_TransferReader::IsMarked
295   (const Handle(Standard_Transient)& ent) const
296 {
297   if (myModel.IsNull()) return Standard_False;
298   Standard_Integer num = myModel->Number(ent);
299   if (num == 0) return Standard_False;
300   if(!myResults.IsBound(num)) return Standard_False;
301   if (myResults.Find(num).IsNull()) return Standard_False;
302   return Standard_True;
303 }
304
305
306 //  #########    ACCES UN PEU PLUS FIN    #########
307
308
309 //=======================================================================
310 //function : FinalResult
311 //purpose  : 
312 //=======================================================================
313
314 Handle(Transfer_ResultFromModel) XSControl_TransferReader::FinalResult
315        (const Handle(Standard_Transient)& ent) const
316 {
317   Handle(Transfer_ResultFromModel) res;
318   if (myModel.IsNull())   return res;
319   Standard_Integer num = myModel->Number(ent);
320   if (num == 0) return res;
321   if(!myResults.IsBound(num)) return res;
322   res = GetCasted(Transfer_ResultFromModel,myResults.Find(num));
323   return res;
324 }
325
326
327 //=======================================================================
328 //function : FinalEntityLabel
329 //purpose  : 
330 //=======================================================================
331
332 Standard_CString XSControl_TransferReader::FinalEntityLabel
333   (const Handle(Standard_Transient)& ent) const
334 {
335   Handle(Transfer_ResultFromModel) resu = FinalResult (ent);
336   if (resu.IsNull()) return "";
337   return resu->MainLabel();
338 }
339
340
341 //=======================================================================
342 //function : FinalEntityNumber
343 //purpose  : 
344 //=======================================================================
345
346 Standard_Integer XSControl_TransferReader::FinalEntityNumber
347   (const Handle(Standard_Transient)& ent) const
348 {
349   Handle(Transfer_ResultFromModel) resu = FinalResult (ent);
350   if (resu.IsNull()) return 0;
351   return resu->MainNumber();
352 }
353
354
355 //=======================================================================
356 //function : ResultFromNumber
357 //purpose  : 
358 //=======================================================================
359
360 Handle(Transfer_ResultFromModel) XSControl_TransferReader::ResultFromNumber
361   (const Standard_Integer num) const
362 {
363   Handle(Transfer_ResultFromModel) res;
364   if ( num<1 || num>myModel->NbEntities() ) return res;
365   if(!myResults.IsBound(num)) return res;
366   res = GetCasted(Transfer_ResultFromModel,myResults.Find(num));
367   return res;
368 }
369
370
371 //=======================================================================
372 //function : TransientResult
373 //purpose  : 
374 //=======================================================================
375
376 Handle(Standard_Transient) XSControl_TransferReader::TransientResult
377        (const Handle(Standard_Transient)& ent) const
378 {
379   Handle(Standard_Transient) tres;
380   Handle(Transfer_ResultFromModel) res = FinalResult(ent);
381   if (res.IsNull()) return tres;
382   Handle(Transfer_ResultFromTransient) mres = res->MainResult();
383   if (mres.IsNull()) return tres;
384   DeclareAndCast(Transfer_SimpleBinderOfTransient,bnd,mres->Binder());
385   if (bnd.IsNull()) return tres;
386   if (!bnd->HasResult()) return tres;
387   return bnd->Result();
388 }
389
390
391 //=======================================================================
392 //function : ShapeResult
393 //purpose  : 
394 //=======================================================================
395
396 TopoDS_Shape XSControl_TransferReader::ShapeResult
397   (const Handle(Standard_Transient)& ent) const
398 {
399   TopoDS_Shape tres;    // DOIT RESTER NULL
400   Handle(Transfer_ResultFromModel) res = FinalResult(ent);
401   if (res.IsNull()) return tres;
402   Handle(Transfer_ResultFromTransient) mres = res->MainResult();
403   if (mres.IsNull()) return tres;
404   XSControl_Utils xu;
405   TopoDS_Shape sh = xu.BinderShape (mres->Binder());
406
407 //   Ouh la vilaine verrue
408   Standard_Real tolang = Interface_Static::RVal("read.encoderegularity.angle");
409   if (tolang <= 0 || sh.IsNull()) return sh;
410   ShapeFix::EncodeRegularity (sh,tolang);
411   return sh;
412 }
413
414
415 //=======================================================================
416 //function : ClearResult
417 //purpose  : 
418 //=======================================================================
419
420 Standard_Boolean XSControl_TransferReader::ClearResult
421   (const Handle(Standard_Transient)& ent, const Standard_Integer mode)
422 {
423   if (myModel.IsNull()) return Standard_False;
424   Standard_Integer num = myModel->Number(ent);
425   if (num == 0) return Standard_False;
426   if(!myResults.IsBound(num)) return Standard_False;
427   if (mode < 0)
428     myResults.ChangeFind(num).Nullify();
429   else {
430     DeclareAndCast(Transfer_ResultFromModel,resu,myResults.Find(num));
431     if (resu.IsNull()) return Standard_False;
432     resu->Strip (mode);
433   }
434   return Standard_True;
435 }
436
437
438 //  <<<< >>>>  ATTENTION, pas terrible : mieux vaudrait
439 //             faire une map inverse et la consulter
440 //             ou muscler ResultFromModel ...
441
442
443 //=======================================================================
444 //function : EntityFromResult
445 //purpose  : 
446 //=======================================================================
447
448 Handle(Standard_Transient) XSControl_TransferReader::EntityFromResult
449        (const Handle(Standard_Transient)& res, const Standard_Integer mode) const
450 {
451   Handle(Standard_Transient) nulh;
452   //  cas de la shape
453   XSControl_Utils xu;
454   TopoDS_Shape sh = xu.BinderShape (res);
455   if (!sh.IsNull()) return EntityFromShapeResult (sh,mode);
456
457   Handle(Transfer_Binder) abinder;
458   DeclareAndCast(Transfer_Binder,binder,res);
459   Standard_Integer i,j,nb;
460
461   if (mode == 0 || mode == 1) {
462     //  on regarde dans le TransientProcess (Roots ou tous Mappeds)
463     if (!myTP.IsNull()) {
464       nb = (mode == 0 ? myTP->NbRoots() : myTP->NbMapped());
465       for (j = 1; j <= nb; j ++) {
466         i = (mode == 0 ? myModel->Number (myTP->Root(j)) : j);
467         if (i == 0) continue;
468         abinder = myTP->MapItem(i);
469         if (abinder.IsNull()) continue;
470         if (!binder.IsNull()) {
471           if (binder == abinder) return myTP->Mapped(i);
472           continue;
473         }
474         DeclareAndCast(Transfer_SimpleBinderOfTransient,trb,abinder);
475         if (trb.IsNull()) continue;
476         if (trb->Result() == res) return myTP->Mapped(i);
477       }
478     }
479     return nulh;  // Null
480   }
481
482   //   Recherche dans myResults (racines)
483   //     2 : Main only  3 : Main + one sub;  4 : all
484   if (mode >= 2) {
485     nb = myModel->NbEntities();
486     for (i = 1; i <= nb; i ++) {
487       Handle(Transfer_ResultFromModel) rec = ResultFromNumber (i);
488       if (rec.IsNull()) return nulh;
489       Handle(TColStd_HSequenceOfTransient) list = rec->Results (mode-2);
490       Standard_Integer ir,nr = list->Length();
491       for (ir = 1; ir <= nr; ir ++) {
492         DeclareAndCast(Transfer_ResultFromTransient,rft,list->Value(ir));
493         if (rft.IsNull()) continue;
494         if (rft->Binder() == binder) return rft->Start();
495       }
496       
497     }
498   }
499
500   //  autres cas non encore implementes
501   return nulh;
502 }
503
504
505 //  <<<< >>>>  ATTENTION, encore moins bien que le precedent
506
507
508 //=======================================================================
509 //function : EntityFromShapeResult
510 //purpose  : 
511 //=======================================================================
512
513 Handle(Standard_Transient) XSControl_TransferReader::EntityFromShapeResult
514   (const TopoDS_Shape& res, const Standard_Integer mode) const
515 {
516   Handle(Standard_Transient) nulh, samesh, partner;
517   if (res.IsNull()) return nulh;
518   Standard_Integer i,j,nb;
519
520   XSControl_Utils xu;
521   if (mode == 0 || mode == 1 || mode == -1) {
522     //  on regarde dans le TransientProcess
523     if (!myTP.IsNull()) {
524       nb = (mode == 0 ? myTP->NbRoots() : myTP->NbMapped());
525       for (j = 1; j <= nb; j ++) {
526         i = (mode == 0 ? myModel->Number (myTP->Root(j)) : j);
527         if (i == 0) continue;
528         Handle(Standard_Transient) ent = myTP->Mapped(i);
529         TopoDS_Shape sh = TransferBRep::ShapeResult (myTP,ent);
530         if (!sh.IsNull()) {
531           if (sh == res) return ent;
532           // priorites moindre : Same (tjrs) ou Partner (mode < 0)
533           if (sh.IsSame(res)) samesh = ent;
534           if (mode == -1 && sh.IsPartner(res)) partner= ent;
535         }
536       }
537     }
538     //    Ici, pas trouve de vraie egalite. Priorites moindres : Same puis Partner
539     if (!samesh.IsNull())  return samesh;
540     if (!partner.IsNull()) return partner;  // calcule si mode = -1
541     return nulh;
542   }
543
544   //   Recherche dans myResults (racines)
545   //     2 : Main only  3 : Main + one sub;  4 : all
546   if (mode >= 2) {
547     nb = myModel->NbEntities();
548     for (i = 1; i <= nb; i ++) {
549       Handle(Transfer_ResultFromModel) rec = ResultFromNumber (i);
550       if (rec.IsNull()) continue;
551       
552       Handle(TColStd_HSequenceOfTransient) list = rec->Results (mode-2);
553       Standard_Integer ir,nr = list->Length();
554       for (ir = 1; ir <= nr; ir ++) {
555         DeclareAndCast(Transfer_ResultFromTransient,rft,list->Value(ir));
556         if (rft.IsNull()) continue;
557         TopoDS_Shape sh = xu.BinderShape (rft->Binder());
558         if (!sh.IsNull() && sh == res) return rft->Start();
559       }
560       
561     }
562   }
563
564   return nulh;
565 }
566
567
568 //=======================================================================
569 //function : EntitiesFromShapeList
570 //purpose  : 
571 //=======================================================================
572
573 Handle(TColStd_HSequenceOfTransient) XSControl_TransferReader::EntitiesFromShapeList
574        (const Handle(TopTools_HSequenceOfShape)& res,
575         const Standard_Integer mode) const
576 {
577   Handle(TColStd_HSequenceOfTransient) lt = new TColStd_HSequenceOfTransient();
578   if (res.IsNull()) return lt;
579   TopTools_MapOfShape shapes;
580
581   //  On convertit res en une map, pour test de presence rapide
582   Standard_Integer i, j, nb = res->Length();
583   if (nb == 0) return lt;
584   for (i = 1; i <= nb; i ++)  shapes.Add (res->Value(i));
585
586   //  A present, recherche et enregistrement
587
588   XSControl_Utils xu;
589   if (mode == 0 || mode == 1) {
590     //  on regarde dans le TransientProcess
591     if (!myTP.IsNull()) {
592       nb = (mode == 0 ? myTP->NbRoots() : myTP->NbMapped());
593       for (j = 1; j <= nb; j ++) {
594         i = (mode == 0 ? myModel->Number (myTP->Root(j)) : j);
595         if (i == 0) continue;
596         TopoDS_Shape sh = xu.BinderShape (myTP->MapItem(i));
597         if (!sh.IsNull() && shapes.Contains(sh)) {
598           lt->Append (myTP->Mapped(i));
599           j=nb; //skl (for looking for entities in checkbrep)
600         }
601       }
602     }
603   }
604
605   //   Recherche dans myResults (racines)
606   //     2 : Main only  3 : Main + one sub;  4 : all
607   if (mode >= 2) {
608     nb = myModel->NbEntities();
609     for (i = 1; i <= nb; i ++) {
610       Handle(Transfer_ResultFromModel) rec = ResultFromNumber (i);
611       if (rec.IsNull()) continue;
612       
613       Handle(TColStd_HSequenceOfTransient) list = rec->Results (mode-2);
614       Standard_Integer ir,nr = list->Length();
615       for (ir = 1; ir <= nr; ir ++) {
616         DeclareAndCast(Transfer_ResultFromTransient,rft,list->Value(i));
617         if (rft.IsNull()) continue;
618         TopoDS_Shape sh = xu.BinderShape (rft->Binder());
619         if (!sh.IsNull() && shapes.Contains(sh)) lt->Append (rft->Start());
620       }
621       
622     }
623   }
624
625   return lt;
626 }
627
628
629 //  <<<< >>>>  ATTENTION, level pas traite (utile ?) -> ResultFromModel
630
631
632 //=======================================================================
633 //function : CheckList
634 //purpose  : 
635 //=======================================================================
636
637 Interface_CheckIterator XSControl_TransferReader::CheckList
638   (const Handle(Standard_Transient)& ent, const Standard_Integer level) const
639 {
640   Interface_CheckIterator chl;
641   if (myModel.IsNull() || ent.IsNull()) return chl;
642   //  Check-List COMPLETE ... tout le Modele
643   if (ent == myModel) {
644     Standard_Integer i,nb = myModel->NbEntities();
645     for (i = 1; i <= nb; i ++) {
646       Handle(Transfer_ResultFromModel) rec = ResultFromNumber (i);
647       if (!rec.IsNull()) {
648         Interface_CheckIterator chiter  = rec->CheckList (Standard_False,2);
649         chl.Merge (chiter);
650       }
651     }
652   }
653   //  Check-List sur une LISTE ...
654   else if (ent->IsKind(STANDARD_TYPE(TColStd_HSequenceOfTransient))) {
655     DeclareAndCast(TColStd_HSequenceOfTransient,list,ent);
656     Standard_Integer i,nb = list->Length();
657     for (i = 1; i <= nb; i ++) {
658       Handle(Transfer_ResultFromModel) rec = FinalResult (list->Value(i));
659       if (!rec.IsNull()) {
660         Interface_CheckIterator chiter = rec->CheckList (Standard_False,level);
661         chl.Merge (chiter);
662       }
663     }
664   }
665
666   //  sinon, Check-List sur une entite : Last ou FinalResult
667   else if (level < 0) {
668     if (myTP.IsNull()) return chl;
669     chl.Add (myTP->Check(ent),myModel->Number(ent));
670   } else {
671     Handle(Transfer_ResultFromModel) rec = FinalResult (ent);
672     if (rec.IsNull()) return chl;
673     chl = rec->CheckList(Standard_False,level);  // manque level ...
674   }
675   if (ent == myModel) chl.SetName ("XSControl : CheckList complete Model");
676   else if (level <  0) chl.SetName ("XSControl : CheckList Last");
677   else if (level == 0) chl.SetName ("XSControl : CheckList Final Main");
678   else if (level == 1) chl.SetName ("XSControl : CheckList Final Main+Subs");
679   else if (level >= 2) chl.SetName ("XSControl : CheckList Final Complete");
680   return chl;
681 }
682
683
684 //=======================================================================
685 //function : HasChecks
686 //purpose  : 
687 //=======================================================================
688
689 Standard_Boolean XSControl_TransferReader::HasChecks
690   (const Handle(Standard_Transient)& ent, const Standard_Boolean failsonly) const
691 {
692   Handle(Transfer_ResultFromModel) resu = FinalResult (ent);
693   if (resu.IsNull()) return Standard_False;
694   Standard_Integer stat = resu->ComputeCheckStatus (Standard_False);
695   if (stat == 0) return Standard_False;
696   if (stat >  1) return Standard_True;
697   return (!failsonly);
698 }
699
700
701 //=======================================================================
702 //function : CheckedList
703 //purpose  : 
704 //=======================================================================
705
706 Handle(TColStd_HSequenceOfTransient)  XSControl_TransferReader::CheckedList
707        (const Handle(Standard_Transient)& ent,
708         const Interface_CheckStatus withcheck, const Standard_Boolean level) const
709 {
710   Handle(TColStd_HSequenceOfTransient) res = new TColStd_HSequenceOfTransient();
711   if (ent.IsNull()) return res;
712
713   if (ent == myModel) {
714     Standard_Integer i,nb = myModel->NbEntities();
715     for (i = 1; i <= nb; i ++) {
716       Handle(Transfer_ResultFromModel) rec = ResultFromNumber (i);
717       if (!rec.IsNull()) res->Append (rec->CheckedList(withcheck,level));
718     }
719   } else if (ent->IsKind(STANDARD_TYPE(TColStd_HSequenceOfTransient))) {
720     DeclareAndCast(TColStd_HSequenceOfTransient,list,ent);
721     Standard_Integer i,nb = list->Length();
722     for (i = 1; i <= nb; i ++) {
723       Handle(Transfer_ResultFromModel) rec = FinalResult (list->Value(i));
724       if (!rec.IsNull()) res->Append (rec->CheckedList(withcheck,level));
725     }
726   } else {
727     Handle(Transfer_ResultFromModel) rec = FinalResult (ent);
728     if (!rec.IsNull()) res = rec->CheckedList(withcheck,level);
729   }
730   return res;
731 }
732
733
734 //  ########################################################
735 //  ###########            TRANSFERT            ############
736 //  ########################################################
737
738
739 //=======================================================================
740 //function : BeginTransfer
741 //purpose  : 
742 //=======================================================================
743
744 Standard_Boolean XSControl_TransferReader::BeginTransfer ()
745 {
746   if (myModel.IsNull()) return Standard_False;
747   if (Actor().IsNull())  return Standard_False;
748   myShapeResult.Nullify();
749
750   if (myTP.IsNull()) myTP = new Transfer_TransientProcess
751     (myModel->NbEntities());
752
753   Handle(Transfer_ActorOfTransientProcess) actor;
754   myTP->SetActor (actor);        // -> RAZ
755   actor = Actor();
756   myTP->SetActor (actor);        // Set proprement dit
757   myTP->SetErrorHandle (Standard_True);
758   myTP->Context() = myContext;
759   return Standard_True;
760 }
761
762
763 //=======================================================================
764 //function : Recognize
765 //purpose  : 
766 //=======================================================================
767
768 Standard_Boolean XSControl_TransferReader::Recognize
769   (const Handle(Standard_Transient)& ent)
770 {
771   if (myActor.IsNull()) return Standard_False;
772   return myActor->Recognize (ent);
773 }
774
775
776 //=======================================================================
777 //function : TransferOne
778 //purpose  : 
779 //=======================================================================
780
781 Standard_Integer XSControl_TransferReader::TransferOne
782   (const Handle(Standard_Transient)& ent, const Standard_Boolean rec)
783 {
784   if (myActor.IsNull() || myModel.IsNull()) return 0;
785
786   if (myTP.IsNull())  {  if (!BeginTransfer()) return 0;  }
787
788   Handle(Message_Messenger) sout = myTP->Messenger();
789   Standard_Integer level = myTP->TraceLevel();
790   
791
792   Transfer_TransferOutput TP (myTP,myModel);
793   if (myGraph.IsNull()) myTP->SetModel(myModel);
794   else                  myTP->SetGraph(myGraph);
795
796   //  pour le log-file
797   if (level > 1) {
798     Standard_Integer num = myModel->Number(ent);
799     Handle(TCollection_HAsciiString) lab = myModel->StringLabel(ent);
800     sout<<"\n*******************************************************************\n";
801     sout << "******           Transferring one Entity                     ******"<<endl;
802     if (!lab.IsNull())
803       sout<<"******    N0 in file : "<<Interface_MSG::Blanks(num,5)<<num
804           <<"      Ident : "<<lab->ToCString()
805           <<  Interface_MSG::Blanks(14 - lab->Length())<<"******\n";
806     sout << "******    Type : "<<myModel->TypeName(ent,Standard_False)
807         <<  Interface_MSG::Blanks((Standard_Integer) (44 - strlen(myModel->TypeName(ent,Standard_False))))
808         <<  "******";
809     sout<<"\n*******************************************************************\n";
810   }
811
812   //  seule difference entre TransferRoots et TransferOne
813   Standard_Integer res = 0;
814   Handle(Standard_Transient) obj = ent;
815   TP.Transfer (obj);
816   myTP->SetRoot (obj);
817
818   //  Resultat ...
819   Handle(Transfer_Binder) binder = myTP->Find (obj);
820   if (binder.IsNull()) return res;
821   if (rec) RecordResult (obj);
822
823   if (!binder->HasResult()) return res;
824   res ++;
825
826   return res;
827 }
828
829
830 //=======================================================================
831 //function : TransferList
832 //purpose  : 
833 //=======================================================================
834
835 Standard_Integer XSControl_TransferReader::TransferList
836   (const Handle(TColStd_HSequenceOfTransient)& list, const Standard_Boolean rec)
837 {
838   if (myActor.IsNull() || myModel.IsNull()) return 0;
839
840   if (myTP.IsNull())  {  if (!BeginTransfer()) return 0;  }
841
842   Handle(Message_Messenger) sout = myTP->Messenger();
843   Standard_Integer level = myTP->TraceLevel();
844
845   Transfer_TransferOutput TP (myTP,myModel);
846   if (myGraph.IsNull()) myTP->SetModel(myModel);
847   else                  myTP->SetGraph(myGraph);
848
849   Standard_Integer i,nb = list->Length();
850
851   //   Pour le log-file
852   if (level > 0) {
853     sout<<"\n*******************************************************************\n";
854     sout << "******           Transferring a list of "<<Interface_MSG::Blanks(nb,5)<<" Entities       ******"<<endl;
855     sout<<"\n*******************************************************************\n";
856
857     Handle(IFSelect_SignatureList) sl = new IFSelect_SignatureList;
858     for (i = 1; i <= nb; i ++)
859       sl->Add (list->Value(i), myModel->TypeName(list->Value(i),Standard_False));
860     sl->SetName ("Entities to Transfer");
861     sl->PrintCount (sout);
862     sout<<"\n*******************************************************************\n";
863   }
864
865   //  seule difference entre TransferRoots et TransferOne
866   Standard_Integer res = 0;
867   nb = list->Length();
868   Handle(Standard_Transient) obj;
869
870   for (i = 1; i <= nb; i ++) {
871     obj = list->Value(i);
872     TP.Transfer (obj);
873     myTP->SetRoot (obj);
874
875     //  Resultat ...
876     Handle(Transfer_Binder) binder = myTP->Find (obj);
877     if (binder.IsNull()) continue;
878     if (rec) RecordResult (obj);
879
880     if (!binder->HasResult()) continue;
881     res ++;
882   }
883   return res;
884 }
885
886
887 //  <<<< >>>>  passage Graph : judicieux ?
888
889
890 //=======================================================================
891 //function : TransferRoots
892 //purpose  : 
893 //=======================================================================
894
895 Standard_Integer XSControl_TransferReader::TransferRoots(const Interface_Graph& G)
896 {
897   if (myModel != G.Model()) return -1;
898   if (!BeginTransfer()) return -1;
899   Handle(Message_Messenger) sout = myTP->Messenger();
900   Standard_Integer level = myTP->TraceLevel();
901
902   Transfer_TransferOutput TP (myTP,myModel);
903   if (myGraph.IsNull()) myTP->SetModel(myModel);
904   else                  myTP->SetGraph(myGraph);
905
906   //   Pour le log-file
907   if (level > 0) {
908     Interface_EntityIterator roots = G.RootEntities();
909     Standard_Integer nb = roots.NbEntities();
910     sout<<"\n*******************************************************************\n";
911     sout << "******           Transferring the "<<Interface_MSG::Blanks(nb,5)<<" Root Entities        ******"<<endl;
912     sout<<"\n*******************************************************************\n";
913     Handle(IFSelect_SignatureList) sl = new IFSelect_SignatureList;
914     for (roots.Start(); roots.More(); roots.Next())
915       sl->Add (roots.Value(),myModel->TypeName(roots.Value(),Standard_False));
916     sl->SetName ("Entities to Transfer");
917     sl->PrintCount (sout);
918     sout<<"\n*******************************************************************\n";
919   }
920
921   TP.TransferRoots (G);
922
923   //  Les entites transferees sont notees "asmain"
924   Standard_Integer i,n = myTP->NbMapped();
925   for (i = 1; i <= n; i ++) {
926     Handle(Standard_Transient) ent = myTP->Mapped(i);
927     Handle(Transfer_Binder)    bnd = myTP->MapItem(i);
928     if (bnd.IsNull()) continue;
929     if (!bnd->HasResult()) continue;
930     RecordResult (ent);
931   }
932
933   //  Resultat ... on note soigneuseument les Shapes
934   myShapeResult = TransferBRep::Shapes (myTP,Standard_True);
935   // ????  Et ici, il faut alimenter Imagine ...
936   return myShapeResult->Length();
937 }
938
939
940 //=======================================================================
941 //function : TransferClear
942 //purpose  : 
943 //=======================================================================
944
945 void XSControl_TransferReader::TransferClear(const Handle(Standard_Transient)& ent,
946                                              const Standard_Integer level)
947 {
948   if (myTP.IsNull()) return;
949   if (ent == myModel) {  myTP->Clear();  return;  }
950
951   myTP->RemoveResult (ent,level);
952   ClearResult (ent,-1);
953  
954 }
955
956
957 //=======================================================================
958 //function : PrintStats
959 //purpose  : 
960 //=======================================================================
961
962 void XSControl_TransferReader::PrintStats
963   (const Standard_Integer what, const Standard_Integer mode) const
964 {
965   Handle(Message_Messenger) sout = myTP->Messenger();
966   //  A ameliorer ... !
967   sout<<"\n*******************************************************************\n";
968   sout << "******        Statistics on Transfer (Read)                  ******"<<endl;
969   sout<<"\n*******************************************************************\n";
970   if (what > 10)  {  sout<<" ***  Not yet implemented"<<endl;  return;  }
971   if (what < 10)  {
972     sout << "******        Data recorded on Last Transfer                 ******"<<endl;
973     PrintStatsProcess (myTP,what,mode);
974   }
975   //  reste  what = 10 : on liste les racines des final results
976   sout << "******        Final Results                                  ******"<<endl;
977   if (myModel.IsNull())  {  sout<<"****    Model unknown"<<endl;  return;  }
978   Handle(TColStd_HSequenceOfTransient) list = RecordedList();
979   Standard_Integer i, nb = list->Length();
980   Handle(IFSelect_SignatureList) counter;
981   if (mode > 2) counter = new IFSelect_SignatureList (mode == 6);
982   IFSelect_PrintCount pcm = IFSelect_CountByItem;
983   if (mode == 6) pcm = IFSelect_ListByItem;
984
985   sout<<"****    Nb Recorded : "<<nb<<" : entities n0s : ";
986   for (i = 1; i <= nb; i ++) {
987     Handle(Standard_Transient) ent = list->Value(i);
988     if (mode == 0)  {  sout<<"  "<<myModel->Number(ent); continue;  }
989     if (mode == 1 || mode == 2) {
990       sout<<"[ "<<Interface_MSG::Blanks (i,6)<<" ]:";
991       myModel->Print (ent,sout);
992       sout<<"  Type:"<<myModel->TypeName(ent,Standard_False);
993     }
994     if (mode >= 3 && mode <= 6) {
995       counter->Add (ent,myModel->TypeName(ent,Standard_False));
996     }
997   }
998   if (!counter.IsNull()) counter->PrintList(sout,myModel,pcm);
999
1000   sout<<endl;
1001 }
1002
1003
1004 //  ########################################################
1005 //  ###########            TRANSFERT            ############
1006
1007
1008 //=======================================================================
1009 //function : LastCheckList
1010 //purpose  : 
1011 //=======================================================================
1012
1013 Interface_CheckIterator  XSControl_TransferReader::LastCheckList () const
1014 {
1015   Interface_CheckIterator chl;
1016   if (!myTP.IsNull()) chl = myTP->CheckList (Standard_False);
1017   return chl;
1018 }
1019
1020
1021 //=======================================================================
1022 //function : LastTransferList
1023 //purpose  : 
1024 //=======================================================================
1025
1026 Handle(TColStd_HSequenceOfTransient) XSControl_TransferReader::LastTransferList
1027        (const Standard_Boolean roots) const
1028 {
1029   Handle(TColStd_HSequenceOfTransient) li = new TColStd_HSequenceOfTransient();
1030   if (myTP.IsNull()) return li;
1031   Standard_Integer i,j,nb =
1032     (roots ? myTP->NbRoots() : myTP->NbMapped());
1033   for (j = 1; j <= nb; j ++) {
1034     i = (roots ? myModel->Number (myTP->Root(j)) : j);
1035     Handle(Transfer_Binder) bnd = myTP->MapItem(i);
1036     if (bnd.IsNull()) continue;
1037     if (!bnd->HasResult()) continue;
1038     li->Append (myTP->Mapped(i));
1039   }
1040   return li;
1041 }
1042
1043
1044 //=======================================================================
1045 //function : ShapeResultList
1046 //purpose  : 
1047 //=======================================================================
1048
1049 const Handle(TopTools_HSequenceOfShape) & XSControl_TransferReader::ShapeResultList
1050   (const Standard_Boolean rec)
1051 {
1052   if (!rec) {
1053     if (myShapeResult.IsNull()) myShapeResult = TransferBRep::Shapes (myTP,Standard_True);
1054     if (myShapeResult.IsNull()) myShapeResult = new TopTools_HSequenceOfShape();
1055   } else {
1056     if (myShapeResult.IsNull()) myShapeResult = new TopTools_HSequenceOfShape();
1057     if (myModel.IsNull()) return myShapeResult;
1058     Handle(TColStd_HSequenceOfTransient) li = RecordedList();
1059     myShapeResult = new TopTools_HSequenceOfShape();
1060     Standard_Integer i, nb = myModel->NbEntities();
1061     TopoDS_Shape sh;
1062     for (i = 1; i <= nb; i ++) {
1063       sh = ShapeResult (myModel->Value(i));
1064       if (!sh.IsNull()) myShapeResult->Append(sh);
1065     }
1066   }
1067   return myShapeResult;
1068 }
1069
1070
1071 //  ****    UTILITAIRE DE STATISTIQUES GENERALES
1072
1073 // BinderStatus retourne une valeur :
1074 // 0 Binder Null.   1 void  2 Warning seul  3 Fail seul
1075 // 11 Resultat OK. 12 Resultat+Warning. 13 Resultat+Fail
1076
1077 //=======================================================================
1078 //function : 
1079 //purpose  : 
1080 //=======================================================================
1081 static Standard_Integer BinderStatus (const Handle(Transfer_Binder)& binder, char* mess)
1082 {
1083   Standard_Integer stat = 0;
1084   mess[0] = '\0';
1085   if (binder.IsNull())  {  sprintf (mess,"(no data recorded)");  return 0;  }
1086   Interface_CheckStatus cst = binder->Check()->Status();
1087   if (cst == Interface_CheckOK) {
1088     stat = 11;
1089     if (binder->HasResult()) sprintf(mess,"%s",binder->ResultTypeName());
1090     else { sprintf(mess,"(no result)"); stat = 1; }
1091   } else if (cst == Interface_CheckWarning) {
1092     stat = 12;
1093     if (binder->HasResult()) sprintf(mess,"%s  (+ warning)",binder->ResultTypeName());
1094     else { sprintf(mess,"(warning)"); stat = 2; }
1095   } else if (cst == Interface_CheckFail) {
1096     stat = 13;
1097     if (binder->HasResult()) sprintf(mess,"%s  (+ FAIL)",binder->ResultTypeName());
1098     else { sprintf(mess,"(FAIL)"); stat = 3; }
1099   }
1100   return stat;
1101 }
1102
1103
1104 //=======================================================================
1105 //function : 
1106 //purpose  : 
1107 //=======================================================================
1108 static void PrintPercent(const Handle(Message_Messenger)& sout, const Standard_CString mess,
1109                          const Standard_Integer nb, const Standard_Integer nl)
1110 {
1111   if (nb <= 0 || nl == 0) return;
1112   sout<<"******      "<<mess<<": ";
1113   if      (nb == nl)       sout<<"100 %"<<endl;
1114   else if (nb*100/nl == 0) sout<<"< 1 %"<<endl;
1115   else            sout<<(nb*100/nl < 10 ? "  " : " ")<<nb*100/nl<<" %"<<endl;
1116 }
1117
1118
1119 //=======================================================================
1120 //function : PrintStatsProcess
1121 //purpose  : 
1122 //=======================================================================
1123
1124 void XSControl_TransferReader::PrintStatsProcess(const Handle(Transfer_TransientProcess)& TP,
1125                                                  const Standard_Integer what,
1126                                                  const Standard_Integer mode)
1127 {
1128   Handle(TColStd_HSequenceOfTransient) list;  // null
1129   XSControl_TransferReader::PrintStatsOnList (TP,list,what,mode);
1130 }
1131
1132
1133 //=======================================================================
1134 //function : PrintStatsOnList
1135 //purpose  : 
1136 //=======================================================================
1137
1138 void XSControl_TransferReader::PrintStatsOnList(const Handle(Transfer_TransientProcess)& TP,
1139                                                 const Handle(TColStd_HSequenceOfTransient)& list,
1140                                                 const Standard_Integer what,
1141                                                 const Standard_Integer mode)
1142 {
1143   Handle(Message_Messenger) sout = TP->Messenger();
1144   char mess[250];
1145   if (TP.IsNull()) return;
1146   if (what == 0) {  TP->PrintStats(0,sout);  return;  }
1147
1148   sout<<"\n*******************************************************************\n";
1149   sout << "******        Statistics on Transfer Process (Read)          ******"<<endl;
1150   if (what == 1) sout << "******        Individual Transfers  (Roots)                  ******\n";
1151   if (what == 2) sout << "******        All recorded data about Transfer               ******\n";
1152   if (what == 3) sout << "******        Abnormal records                               ******\n";
1153   if (what == 1 || what == 2 || what == 3) {
1154     if (mode == 0) sout<<"******        (n0s of recorded entities)                     ******\n";
1155     if (mode == 1) sout<<"******        (per entity : type + result)                   ******\n";
1156     if (mode == 2) sout<<"******        (per entity : type + result/status)            ******\n";
1157     if (mode == 3) sout<<"******        (count per type of entity)                     ******\n";
1158     if (mode == 4) sout<<"******        (count per type of result)                     ******\n";
1159     if (mode == 5) sout<<"******   (count per couple entity-type / result-type/status) ******\n";
1160     if (mode == 6) sout<<"******   (list per couple entity-type / result-type/status)  ******\n";
1161   }
1162   if (what == 4) sout << "******        Check messages                                 ******\n";
1163   if (what == 5) sout << "******        Fail  messages                                 ******\n";
1164   sout<<"*******************************************************************\n";
1165
1166   //  Cas what = 1,2,3 : contenu du TP (binders)
1167
1168   Standard_Boolean nolist = list.IsNull();
1169   Handle(Interface_InterfaceModel) model = TP->Model();
1170   if (what >= 1 && what <= 3) {
1171
1172     Standard_Integer stat;
1173     Standard_Integer nbv = 0, nbw = 0, nbf = 0, nbr = 0, nbrw = 0, nbrf = 0, nbnr = 0, nbi = 0;
1174     Transfer_IteratorOfProcessForTransient itrp(Standard_True);
1175     if (what == 1) itrp = TP->RootResult(Standard_True);
1176     if (what == 2) itrp = TP->CompleteResult(Standard_True);
1177     if (what == 3) itrp = TP->AbnormalResult();
1178     Standard_Integer i = 0, nb = itrp.Number();
1179     if (!nolist) itrp.Filter (list);
1180     Standard_Integer nl = itrp.Number();    // apres filtrage
1181     Handle(IFSelect_SignatureList) counter;
1182     if (mode > 2) counter = new IFSelect_SignatureList (mode == 6);
1183     Standard_Boolean notrec = (!nolist && mode > 2);  // noter les "no record"
1184     IFSelect_PrintCount pcm = IFSelect_CountByItem;
1185     if (mode == 6) pcm = IFSelect_ListByItem;
1186
1187     sout  <<"****        Entities in Model   : "<<model->NbEntities()<<endl;
1188     sout  <<"****        Nb Items (Transfer) : "<<nb<<endl;
1189     if (!nolist)
1190       sout<<"****        Nb Items (Listed)   : "<<nl<<endl;
1191
1192     for (itrp.Start(); itrp.More(); itrp.Next()) {
1193       nbi ++;
1194       Handle(Transfer_Binder) binder = itrp.Value();
1195       Handle(Standard_Transient) ent = itrp.Starting();
1196       if (binder.IsNull())  {
1197         nbnr ++;
1198         if (notrec) counter->Add(ent,"(not recorded)");
1199         else if (mode == 1 || mode == 2) {
1200           sout<<"["<<Interface_MSG::Blanks (nbi,4)<<nbi<<" ]:";
1201           model->Print (ent,sout);
1202           sout<<"   "<<model->TypeName(ent,Standard_False)<<"  (not recorded)"<<endl;
1203           continue;
1204         }
1205       }
1206       if (mode == 0)  {  sout<<"  "<<model->Number(ent); continue;  }
1207       if (mode != 3) {
1208         stat = BinderStatus(binder,mess);
1209         // 0 Binder Null.   1 void  2 Warning seul  3 Fail seul
1210         // 11 Resultat OK. 12 Resultat+Warning. 13 Resultat+Fail
1211         if (stat ==  0 || stat == 1) nbv ++;
1212         if (stat ==  2) nbw ++;
1213         if (stat ==  3) nbf ++;
1214         if (stat == 11) nbr ++;
1215         if (stat == 12) nbrw ++;
1216         if (stat == 13) nbrf ++;
1217       }
1218
1219       //  mode : 0 list num;  1 : num+label + type + result (abrege);  2 : complet
1220       if (mode == 1 || mode == 2) {
1221         sout<<"["<<Interface_MSG::Blanks (i,4)<<i<<" ]:";
1222         model->Print (ent,sout);
1223         sout<<"   "<<model->TypeName(ent,Standard_False);
1224         sout<<" Result:"<<mess<<endl;
1225         if (mode == 1) continue;
1226
1227         const Handle(Interface_Check)& ch = binder->Check();
1228         Standard_Integer newi,newnbw = ch->NbWarnings(), newnbf = ch->NbFails();
1229
1230         if (newnbw > 0) {
1231           sout<<" - Warnings : "<<newnbw<<":\n";
1232           for (newi = 1; newi <= newnbw; newi ++) sout<<ch->CWarning(newi)<<endl;
1233         }
1234         if (newnbf > 0) {
1235           sout<<" - Fails : "<<newnbf<<":\n";
1236           for (newi = 1; newi <= newnbf; newi ++) sout<<ch->CFail(newi)<<endl;
1237         }
1238         continue;
1239       }
1240
1241       //  mode : 3, counts per type of starting entity (class type)
1242       //         4 : counts per result type and/or status
1243       //         5 : counts per couple (starting type / result type/status)
1244       //         6 : idem plus gives for each item, the list of numbers of
1245       //                  entities in the starting model
1246       if (mode >= 3 && mode <= 6) {
1247         //IFSelect_PrintCount newpcm = IFSelect_CountByItem;
1248         //if (mode == 6) newpcm = IFSelect_ListByItem;
1249         if (mode == 3) counter->Add (ent,model->TypeName(ent,Standard_False));
1250         if (mode == 4) counter->Add (ent,mess);
1251         if (mode >= 5) {
1252           TCollection_AsciiString mest (model->TypeName(ent,Standard_False));
1253           mest.AssignCat("      -> ");
1254           mest.AssignCat(mess);
1255           //sprintf(mest,"%s    -> %s",model->TypeName(ent,Standard_False),mess);
1256           counter->Add (ent,mest.ToCString());
1257         }
1258       }
1259
1260       //    Fin de l iteration
1261     }
1262     if (!counter.IsNull()) counter->PrintList(sout,model,pcm);
1263     else sout<<endl;
1264     //    Pourcentages
1265     if (mode != 3 && nbi > 0) {
1266       sout << "******        Percentages according Transfer Status          ******"<<endl;
1267       PrintPercent (sout,"Result          ",nbr+nbrw,nl);
1268       PrintPercent (sout,"Result + FAIL   ",nbrf,nl);
1269       PrintPercent (sout,"FAIL, no Result ",nbf,nl);
1270       PrintPercent (sout,"Just Warning    ",nbw,nl);
1271       PrintPercent (sout,"Nothing Recorded",nbnr,nl);
1272 /*      if (nbr+nbrw > 0)
1273         sout<<"******      Result          : "<< (nbr+nbrw)*100/nl<<" %"<<endl;
1274       if (nbrf > 0)
1275         sout<<"******      Result + FAIL   : "<< (nbrf)*100/nl<<" %"<<endl;
1276       if (nbf > 0)
1277         sout<<"******      FAIL, no Result : "<< (nbf)*100/nl<<" %"<<endl;
1278       if (nbw > 0)
1279         sout<<"******      Just Warning    : "<< (nbw)*100/nl<<" %"<<endl;
1280       if (nbnr > 0)
1281         sout<<"******      Nothing Recorded: "<< (nbnr)*100/nl<<" %"<<endl; */
1282     }
1283     return;
1284   }
1285
1286   //  Cas  what = 4,5 : check-list
1287
1288   if (what == 4 || what == 5) {
1289
1290     Interface_CheckIterator chl = TP->CheckList(Standard_False);
1291     chl.SetName("** TRANSFER READ CHECK **");
1292     if (mode == 0) chl.Print (sout,model,(what == 5));
1293     else {
1294       IFSelect_PrintCount pcm = IFSelect_CountByItem;
1295       if (mode == 2) pcm = IFSelect_ListByItem;
1296       Handle(IFSelect_CheckCounter) counter = new IFSelect_CheckCounter(Standard_True);
1297       counter->Analyse   (chl,model,Standard_True,(what == 5));
1298       counter->PrintList (sout,model,pcm);
1299     }
1300   }
1301
1302 }