0027349: XtControl_Reader is not thread-safe
[occt.git] / src / XSControl / XSControl_FuncShape.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 <BRep_Builder.hxx>
16 #include <BRepTools.hxx>
17 #include <Geom2d_Curve.hxx>
18 #include <Geom_Geometry.hxx>
19 #include <IFSelect_Act.hxx>
20 #include <IFSelect_CheckCounter.hxx>
21 #include <IFSelect_Functions.hxx>
22 #include <IFSelect_SessionPilot.hxx>
23 #include <Interface_CheckIterator.hxx>
24 #include <Interface_InterfaceModel.hxx>
25 #include <Interface_Macros.hxx>
26 #include <Message.hxx>
27 #include <Message_Messenger.hxx>
28 #include <ShapeExtend_Explorer.hxx>
29 #include <Standard_ErrorHandler.hxx>
30 #include <Standard_Failure.hxx>
31 #include <TCollection_AsciiString.hxx>
32 #include <TColStd_HSequenceOfTransient.hxx>
33 #include <TColStd_SequenceOfInteger.hxx>
34 #include <TopExp_Explorer.hxx>
35 #include <TopoDS.hxx>
36 #include <TopoDS_Compound.hxx>
37 #include <TopoDS_Iterator.hxx>
38 #include <TopTools_HSequenceOfShape.hxx>
39 #include <Transfer_Binder.hxx>
40 #include <Transfer_Finder.hxx>
41 #include <Transfer_FinderProcess.hxx>
42 #include <Transfer_ResultFromModel.hxx>
43 #include <Transfer_SimpleBinderOfTransient.hxx>
44 #include <Transfer_TransientListBinder.hxx>
45 #include <Transfer_TransientProcess.hxx>
46 #include <TransferBRep.hxx>
47 #include <TransferBRep_ShapeBinder.hxx>
48 #include <TransferBRep_ShapeListBinder.hxx>
49 #include <TransferBRep_ShapeMapper.hxx>
50 #include <XSControl.hxx>
51 #include <XSControl_ConnectedShapes.hxx>
52 #include <XSControl_Controller.hxx>
53 #include <XSControl_FuncShape.hxx>
54 #include <XSControl_TransferReader.hxx>
55 #include <XSControl_TransferWriter.hxx>
56 #include <XSControl_Vars.hxx>
57 #include <XSControl_WorkSession.hxx>
58
59 #include <stdio.h>
60 //#include <TransferBRep_Analyzer.hxx>
61 //  ######################################################################
62 //  ####                                                              ####
63 //  ####                           COMMANDS                           ####
64 //  ####                                                              ####
65 //  ######################################################################
66 //=======================================================================
67 //function : XSControl_tpdraw
68 //purpose  : 
69 //=======================================================================
70 static IFSelect_ReturnStatus XSControl_tpdraw
71   (const Handle(IFSelect_SessionPilot)& pilot)
72 {
73   Standard_Integer argc = pilot->NbWords();
74   const Standard_CString arg1 = pilot->Arg(1);
75   const Standard_CString arg2 = pilot->Arg(2);
76   const Standard_CString arg3 = pilot->Arg(3);
77   const Handle(Transfer_TransientProcess) &TP = XSControl::Session(pilot)->TransferReader()->TransientProcess();
78   Handle(Message_Messenger) sout = Message::DefaultMessenger();
79   if (TP.IsNull()) { sout<<"No Transfer Read"<<endl; return IFSelect_RetError;}
80   //        ****    tpdraw        ****
81   if (argc < 2) {
82     sout<<"Donner [mode facultatif : item ou root] , NUMERO , nom DRAW facultatif"<<endl;
83     sout<<"  mode si present : item ou root, sinon n0 d entite modele"<<endl;
84     sout<<"  NUMERO entier : d entite, d item transfert ou de root transfert\n"
85       <<  "    ou * pour dire tous"<<endl;
86     return IFSelect_RetError;
87   }
88   Standard_Integer mode = 0, num=0;
89   if      (arg1[0] == 'i') mode = 1;
90   else if (arg1[0] == 'r') mode = 2;
91   Standard_Boolean tout = Standard_False;
92   if (mode == 0) {
93     if (argc < 2) { sout<<"Donner au moins un NUMERO ou *"<<endl; return IFSelect_RetError; }
94     if (arg1[0] == '*') tout = Standard_True;
95     else num = IFSelect_Functions::GiveEntityNumber(XSControl::Session(pilot),arg1);
96   } else {
97     if (arg2[0] == '*') tout = Standard_True;
98     else num = IFSelect_Functions::GiveEntityNumber(XSControl::Session(pilot),arg2);
99   }
100
101   Standard_Integer nbvar = 0;
102   Handle(Transfer_Binder) binder;
103   Handle(Standard_Transient) ent;
104   TopoDS_Shape sh;    char nomvar[40];
105   //  Standard_Boolean moderoot =  (pilot->Word(0).Value(3) == 'r');
106
107   Standard_Integer n1, n2, i, max=0, index=0;
108   Handle(Interface_InterfaceModel) model = TP->Model();
109   if (model.IsNull()) {
110     if (mode == 0) {
111       sout<<"Pas de modele, preciser n0 d item de transfert"<<endl;
112       return IFSelect_RetError;
113     }
114   }
115   if (mode == 0) { sout<<"Entite de modele";    max = model->NbEntities(); }
116   if (mode == 1) { sout<<"Item de transfert";   max = TP->NbMapped(); }
117   if (mode == 2) { sout<<"Racine de transfert"; max = TP->NbRoots(); }
118   if (tout) {
119     n1 = 1;  n2 = max;
120     sout<<", listage de 1 a "<<max<<endl;
121   }
122   else if (num <= 0 || num > max) {
123     sout<<" - Num="<<num<<" hors limite (de 1 a "<<max<<")"<<endl;
124     return IFSelect_RetError;
125   } else {
126     n1 = n2 = num;  nbvar = -1;  // nbvar : 1ere shape simple = pas de n0
127     sout<<", n0 "<<num<<endl;
128   }
129
130   for (i = n1; i <= n2; i ++) {
131     if        (mode == 0) {
132       ent = model->Value(i);
133       num = i;
134       index = TP->MapIndex(ent);
135     } else if (mode == 1) {
136       ent = TP->Mapped(i);
137       if (model.IsNull()) num = 0;
138       else num = model->Number(ent);
139       index = i;
140     } else if (mode == 2) {
141       ent = TP->Root(i);
142       if (model.IsNull()) num = 0;
143       else num = model->Number(ent);
144       index = TP->MapIndex(ent);
145     }
146
147     if (index > 0) binder = TP->MapItem (index);
148     if (binder.IsNull()) index = 0;
149     if (index == 0) {
150       if (!tout) sout<<"Entite n0 "<<num<<" : non repertoriee"<<endl;
151       continue;
152     }
153     if (!binder->HasResult()) {
154       if (!tout) sout<<"Entite n0 "<<num<<" : pas de resultat"<<endl;
155       continue;
156     }
157     sh = TransferBRep::ShapeResult (binder);
158     //DeclareAndCast(TransferBRep_ShapeBinder,shb,binder);
159     if (!sh.IsNull()) {
160       //sh = shb->Result();
161       nbvar ++;
162       if (sh.IsNull()) { sout<<" (no Shape recorded)"<<endl; continue; }
163       if (tout) sout<<"[ "<<i<<" ]:";
164       if (num == 0) sout<<" pas dans le modele";
165       else sout<<" ent.n0 "<<num;
166       sout<<", item transfert n0 "<<index;
167       if (nbvar == 0) {
168         if      (argc > 3 && mode  > 0) sprintf (nomvar,"%s",arg3);
169         else if (argc > 2 && mode == 0) sprintf (nomvar,"%s",arg2);
170         else                            sprintf (nomvar,"tp_%d",i);
171       } else {
172         if      (argc > 3 && mode  > 0) sprintf (nomvar,"%s_%d",arg3,nbvar);
173         else if (argc > 2 && mode == 0) sprintf (nomvar,"%s_%d",arg2,nbvar);
174         else                            sprintf (nomvar,"tp_%d",i);
175       }
176       sout<<" -> 1 DRAW Shape: "<<nomvar<<endl;
177       XSControl::Vars(pilot)->SetShape(nomvar,sh);
178       continue;
179     }
180     DeclareAndCast(TransferBRep_ShapeListBinder,slb,binder);
181     if (!slb.IsNull()) {
182       Standard_Integer nbs = slb->NbShapes();
183       if (tout) sout<<"[ "<<i<<" ]:";
184       if (num == 0) sout<<" pas dans le modele";
185       else sout<<" ent.n0 "<<num;
186       sout<<", item transfert n0 "<<index;
187       sout<<" -> "<<nbs<<" DRAW Shapes :";
188       for (Standard_Integer j = 1; j <= nbs; j ++)  {
189         sh = slb->Shape(j);  if (nbvar < 0) nbvar = 0;  nbvar ++;
190         if (sh.IsNull()) { sout<<" (no Shape recorded)"<<endl; continue; }
191         if      (argc > 3 && mode  > 0) sprintf (nomvar,"%s_%d",arg3,nbvar);
192         else if (argc > 2 && mode == 0) sprintf (nomvar,"%s_%d",arg2,nbvar);
193         else                        sprintf (nomvar,"tp_%d_%d",i,nbvar);
194         sout<<" "<<nomvar;
195         XSControl::Vars(pilot)->SetShape(nomvar,sh);
196       }
197       sout<<endl;
198       continue;
199     }
200     DeclareAndCast(Transfer_SimpleBinderOfTransient,trb,binder);
201     if (!trb.IsNull()) {
202       Handle(Standard_Transient) resu = trb->Result();
203       if (resu.IsNull()) {
204         sout<<"Entite n0 "<<num<<" : pas de resultat"<<endl;
205         continue;
206       }
207       DeclareAndCast(Geom_Geometry,geom,resu);
208       sout<<"Entite n0 "<<num<<" : resultat "<<resu->DynamicType()->Name();
209       if (geom.IsNull()) { sout<<endl; continue; }
210       nbvar ++;
211       if (nbvar == 0) {
212         if      (argc > 3 && mode  > 0) sprintf (nomvar,"%s",arg3);
213         else if (argc > 2 && mode == 0) sprintf (nomvar,"%s",arg2);
214         else                            sprintf (nomvar,"tp_%d",i);
215       } else {
216         if      (argc > 3 && mode  > 0) sprintf (nomvar,"%s_%d",arg3,nbvar);
217         else if (argc > 2 && mode == 0) sprintf (nomvar,"%s_%d",arg2,nbvar);
218         else                            sprintf (nomvar,"tp_%d",i);
219       }
220       char* nomv = nomvar;
221       XSControl::Vars(pilot)->Set (nomv,geom);
222       sout<<" -> DRAW Geom : "<<nomvar<<endl;
223       continue;
224     }
225
226     if (sh.IsNull() && trb.IsNull())
227       if (!tout) sout<<"Entite n0 "<<num<<" : resultat pas une Shape mais "<<binder->ResultTypeName()<<endl;
228   }
229
230   if (sh.IsNull()) sout<<" (No Shape)"<<endl;
231   return IFSelect_RetDone;
232 }
233
234 //=======================================================================
235 //function : XSControl_tpcompound
236 //purpose  : 
237 //=======================================================================
238 static IFSelect_ReturnStatus XSControl_tpcompound
239   (const Handle(IFSelect_SessionPilot)& pilot)
240 {
241   Standard_Integer argc = pilot->NbWords();
242   const Standard_CString arg1 = pilot->Arg(1);
243   const Handle(Transfer_TransientProcess) &TP = XSControl::Session(pilot)->TransferReader()->TransientProcess();
244   Handle(Message_Messenger) sout = Message::DefaultMessenger();
245   if (TP.IsNull()) { sout<<"No Transfer Read"<<endl; return IFSelect_RetError;}
246   //        ****    tpcompound        ****
247   if (argc < 2) { sout<<"Give a NAME for the Compound  + optional givelist, else roots are taken"<<endl; return IFSelect_RetError; }
248   Handle(TopTools_HSequenceOfShape) list;
249   if (argc == 2) list = TransferBRep::Shapes(TP);
250   else {
251     Handle(TColStd_HSequenceOfTransient) lise = IFSelect_Functions::GiveList(pilot->Session(),pilot->CommandPart(2));
252     if (lise.IsNull()) { sout<<"Not a valid entity list : "<<pilot->CommandPart(2)<<endl; return IFSelect_RetError; }
253     list = TransferBRep::Shapes (TP,lise);
254     sout<<lise->Length()<<" Entities, ";
255   }
256   if (list.IsNull()) { sout<<"No Shape listed"<<endl; return IFSelect_RetError; }
257   Standard_Integer nb = list->Length();
258   sout<<nb<<" Shape(s) listed"<<endl;
259   TopoDS_Compound C;
260   BRep_Builder B;
261   B.MakeCompound(C);
262   for (Standard_Integer i = 1; i <= nb; i ++)  B.Add (C,list->Value(i));
263   XSControl::Vars(pilot)->SetShape (arg1,C);
264   return IFSelect_RetDone;
265 }
266
267
268
269 //=======================================================================
270 //function : XSControl_traccess
271 //purpose  : 
272 //=======================================================================
273 static IFSelect_ReturnStatus XSControl_traccess
274   (const Handle(IFSelect_SessionPilot)& pilot)
275 {
276   Standard_Integer argc = pilot->NbWords();
277   const Standard_CString arg1 = pilot->Arg(1);
278   const Standard_CString arg2 = pilot->Arg(2);
279   //        ****    trdraw : TransferReader        **** 26
280   //        ****    trsave : TransferReader        **** 27
281   //        ****    trcomp  (comp -> DRAW)         **** 28
282   //        ****    trscomp (comp -> save)         **** 29
283   Standard_Boolean cascomp = (pilot->Word(0).Location(1,'o',1,5) > 0);
284   Standard_Boolean cassave = (pilot->Word(0).Location(1,'s',1,5) > 0);
285   char nomsh[100], noms[100];
286   const Handle(XSControl_TransferReader) &TR = XSControl::Session(pilot)->TransferReader();
287   Handle(Message_Messenger) sout = Message::DefaultMessenger();
288   if (TR.IsNull()) { sout<<" manque init"<<endl; return IFSelect_RetError; }
289   const Handle(Interface_InterfaceModel) &mdl = TR->Model();
290   if (mdl.IsNull()) { sout<<" modele absent"<<endl; return IFSelect_RetError; }
291   Standard_Integer num = (argc > 1 ? IFSelect_Functions::GiveEntityNumber(XSControl::Session(pilot),arg1) : 0);
292
293   if (argc > 1) strcpy (nomsh,arg1);
294   else    strcpy (nomsh,(cascomp ? "TREAD_COMP" : "TREAD_LIST"));
295   if (cassave) sout<<" save shapes -> current directory"<<endl;
296
297   if (num == 0 || cascomp) {
298     TopoDS_Compound C;        // pour cas compound
299     BRep_Builder B;
300     B.MakeCompound(C);
301
302     const Handle(TopTools_HSequenceOfShape) &list = TR->ShapeResultList(Standard_True);
303     Standard_Integer i,  nb = list->Length();
304     sout<<" TOUS RESULTATS par ShapeResultList, soit "<<nb<<endl;
305     for (i = 1; i <= nb; i ++) {
306       sprintf (noms,"%s_%d",nomsh,i);
307       if      ( (i%1000) == 0) sout<<"("<<i<<")"<<endl;
308       else if ( (i%100)  == 0) sout<<"*";
309       else if ( (i%10)   == 0) sout<<"0";
310       else                     sout<<".";
311       if (list->Value(i).IsNull()) continue;
312       if      (!cascomp && !cassave) XSControl::Vars(pilot)->SetShape(noms,list->Value(i));
313       else if (!cascomp &&  cassave) BRepTools::Write (list->Value(i),noms);
314       else if (cascomp) B.Add (C,list->Value(i));
315     }
316     sout<<endl;
317     if      (cascomp && !cassave) XSControl::Vars(pilot)->SetShape(nomsh,C);
318     else if (cascomp &&  cassave) BRepTools::Write (C,nomsh);
319   } else {
320     if (num < 1 || num > mdl->NbEntities()) { sout<<" incorrect:"<<arg1<<endl; return IFSelect_RetError; }
321     TopoDS_Shape sh = TR->ShapeResult(mdl->Value(num));
322     if (sh.IsNull()) { sout<<" Pas de resultat pour "<<arg1<<endl; return IFSelect_RetError; }
323     if (argc > 2) sprintf (nomsh,"%s",arg2);
324     else sprintf (nomsh,"TREAD_%d",num);
325     if      (!cascomp && !cassave) XSControl::Vars(pilot)->SetShape(nomsh,sh);
326     else if (!cascomp &&  cassave) BRepTools::Write (sh,nomsh);
327     else sout<<"Option non comprise"<<endl;
328   }
329   return IFSelect_RetDone;
330 }
331
332 //=======================================================================
333 //function : XSControl_IsEqualSubShape
334 //purpose  : 
335 //=======================================================================
336 // PTV 23.08.2000 Added for checking where are an entity from.
337 static Standard_Boolean XSControl_IsEqualSubShape (const TopoDS_Shape& Shape,
338                                                    TopoDS_Shape& sh, Standard_Integer aLevel)
339 {
340   if ( sh.IsSame(Shape) ) return Standard_True;
341   if (aLevel > 0) {
342     TopoDS_Shape varShape;
343     aLevel--;
344     TopoDS_Iterator it(sh);
345     for (; it.More(); it.Next() ) {
346       varShape = it.Value();
347       if ( XSControl_IsEqualSubShape(Shape, varShape, aLevel) ) return Standard_True;
348     }
349   }
350   return Standard_False; 
351 }
352
353 //=======================================================================
354 //function : XSControl_fromshape
355 //purpose  : 
356 //=======================================================================
357 static IFSelect_ReturnStatus XSControl_fromshape
358   (const Handle(IFSelect_SessionPilot)& pilot)
359 {
360   Standard_Integer argc = pilot->NbWords();
361   const Standard_CString arg1 = pilot->Arg(1);
362   //        ****    fromshape (tread)         ****
363   Handle(Message_Messenger) sout = Message::DefaultMessenger();
364   if (argc < 2) {
365     sout<<"Give name of a DRAW Shape"<<endl;
366     return IFSelect_RetError;
367   }
368   const char* a1 = (char *)arg1;
369   TopoDS_Shape Shape = XSControl::Vars(pilot)->GetShape(a1);
370   if (Shape.IsNull()) {
371     sout<<"Not a DRAW Shape:"<<arg1<<endl;
372     return IFSelect_RetError;
373   }
374   Standard_Boolean yena = Standard_False;
375   Standard_Integer aLevel = 1;
376   if (argc >=3 )
377     aLevel = atoi(pilot->Arg(2));
378   Standard_Boolean silent = Standard_False;
379   if (aLevel <0 ) {
380     silent = Standard_True;
381     aLevel = -aLevel;
382   }
383   
384   //    IMPORT
385   const Handle(XSControl_TransferReader) &TR = XSControl::Session(pilot)->TransferReader();
386   if (TR.IsNull()) { }  // sout<<"No read transfer (import) recorded"<<endl;
387   else {
388     yena = Standard_True;
389     if ( ! silent ) sout<<"Shape "<<arg1<<" : ";
390     Standard_Integer modrec = 1;
391     Handle(Standard_Transient) ent = TR->EntityFromShapeResult (Shape,modrec);
392     if (ent.IsNull()) {
393       modrec = -1;
394       ent = TR->EntityFromShapeResult (Shape,modrec);
395     }
396     if (ent.IsNull()) {
397       modrec = 2;
398       Handle(Transfer_TransientProcess) TP = TR->TransientProcess();
399       if (TP.IsNull()) {
400         if ( silent )
401           sout << "Shape "<<arg1<<" : ";
402         sout<<"no map"<<endl;
403       }
404       else {
405         TopoDS_Shape S0 = Shape;
406         TopLoc_Location L;
407         S0.Location ( L );
408         Standard_Integer i, nb = TP->NbMapped();
409         if ( ! silent ) sout<<"searching in map among "<<nb<<" ...";
410         for (i = 1; i <= nb; i ++) {
411           ent = TP->Mapped(i);
412           TopoDS_Shape sh = TransferBRep::ShapeResult(TP,ent);
413           if (sh.IsNull()) {
414             ent.Nullify();
415             continue;
416           }
417           if (XSControl_IsEqualSubShape(Shape, sh, aLevel)) break;
418           modrec = -2;
419           sh.Location ( L );
420           if (XSControl_IsEqualSubShape(S0, sh, aLevel)) break;
421           ent.Nullify();
422           modrec = 2;
423         }
424       }
425     }
426     if ( ! ent.IsNull() ) {
427       if ( silent ) sout << "Shape " << arg1 << ": ";
428       if (modrec <0) sout<<"(moved from origin) ";
429       //else sout<<"(origin) ";
430     }
431     //  on affiche
432     if (ent.IsNull()) {
433       if ( ! silent ) sout<<" unknown as imported";
434       // skl 11.05.2004
435       // if Shape is a compound try to make "fromshape" for its subshapes
436       if(Shape.ShapeType()==TopAbs_COMPOUND) {
437         sout<<endl<<"Subshapes imported from entities:";
438         TopoDS_Iterator Iter(Shape);
439         for (; Iter.More(); Iter.Next()) {
440           TopoDS_Shape subsh = Iter.Value();
441           Standard_Integer submodrec = 1;
442           Handle(Standard_Transient) subent = TR->EntityFromShapeResult(subsh,submodrec);
443           if (subent.IsNull()) {
444             submodrec = -1;
445             subent = TR->EntityFromShapeResult(subsh,submodrec);
446           }
447           if (!subent.IsNull()) {
448             sout<<"  "<<XSControl::Session(pilot)->Model()->Number(subent); 
449           }
450         }
451       }
452     }
453     else { 
454       sout<<"imported from entity "; 
455       XSControl::Session(pilot)->Model()->Print(ent,sout); 
456       if ( silent ) sout << " in file " << XSControl::Session(pilot)->LoadedFile() << endl;
457     }
458     if ( ! silent ) sout<<endl;
459   }
460
461   //   ET EN EXPORT ?
462   const Handle(Transfer_FinderProcess) &FP = XSControl::Session(pilot)->TransferWriter()->FinderProcess();
463   if (FP.IsNull()) { }
464   else {
465     yena = Standard_True;
466     Handle(Transfer_Finder) fnd = TransferBRep::ShapeMapper (FP,Shape);
467     Handle(Standard_Transient) ent;
468     if (!fnd.IsNull()) ent = FP->FindTransient (fnd);
469     if (!ent.IsNull()) {
470       sout<<"Shape "<<arg1<<": exported to entity ";
471       XSControl::Session(pilot)->Model()->Print(ent,sout);
472       if ( silent ) sout << " in file " << XSControl::Session(pilot)->LoadedFile();
473       sout<<endl;
474     }
475     // abv 31.08.00: treat case of splitted shape (several results)
476     // it is supposed that results are of the same type and lie in one-level comp
477     else {
478       Handle(Transfer_Binder) bnd = FP->Find ( fnd );
479       if ( ! bnd.IsNull() ) {
480         Handle(Transfer_TransientListBinder) TransientListBinder =
481           //Handle(Transfer_TransientListBinder)::DownCast( bnd->Next(Standard_True) ); //skl
482           Handle(Transfer_TransientListBinder)::DownCast( bnd ); //skl
483         if (! TransientListBinder.IsNull() ) {
484           Standard_Integer i = 1, nb = TransientListBinder->NbTransients();
485           if (nb > 0) sout<<"Shape "<<arg1<<": exported to entities ";
486           for (; i<=nb; i++) {
487             XSControl::Session(pilot)->Model()->Print( TransientListBinder->Transient(i), sout );
488             if (i < nb) sout<<", ";
489           }
490           if (nb > 0) {
491             if ( silent ) sout << " in file " << XSControl::Session(pilot)->LoadedFile();
492             sout<<endl;
493           }
494         }
495 /*      else {
496           TopoDS_Shape comp = TransferBRep::ShapeResult(bnd);
497           if ( ! comp.IsNull() && comp.ShapeType() < Shape.ShapeType() ) {
498             Standard_Boolean start = Standard_True;
499             for ( TopoDS_Iterator it(comp); it.More(); it.Next() ) {
500               Handle(Transfer_Finder) cfnd = TransferBRep::ShapeMapper (FP,it.Value());
501               if ( cfnd.IsNull() ) continue;
502               Handle(Standard_Transient) cent = FP->FindTransient (cfnd);
503               if ( cent.IsNull() ) continue;
504               if ( start ) 
505                 sout<<"Shape "<<arg1<<" : exported to entities ";
506               else sout << ", ";
507               start = Standard_False;
508               XSControl::Session(pilot)->Model()->Print(cent,sout);
509             }
510             if ( ! start ) sout<<endl;
511           }
512         }  */
513       }
514     }
515   }
516   if (!yena) sout<<"No transfer (either import or export) recorded"<<endl;
517
518   return IFSelect_RetVoid;
519 }
520
521 //=======================================================================
522 //function : XSControl_trconnexentities
523 //purpose  : 
524 //=======================================================================
525 static IFSelect_ReturnStatus XSControl_trconnexentities
526   (const Handle(IFSelect_SessionPilot)& pilot)
527 {
528   Standard_Integer argc = pilot->NbWords();
529   const Standard_CString arg1 = pilot->Arg(1);
530   //        ****    connected entities (last transfer)         ****
531   const Handle(XSControl_TransferReader) &TR  = XSControl::Session(pilot)->TransferReader();
532   Handle(Transfer_TransientProcess) TP;
533   if (!TR.IsNull()) TP = TR->TransientProcess();
534   Handle(Message_Messenger) sout = Message::DefaultMessenger();
535   if (TP.IsNull()) { sout<<"no transfer map"<<endl; return IFSelect_RetVoid; }
536   if (argc < 2) { 
537     sout<<"Give name of a DRAW Shape + optional shape type v-e-w-f(D)-s"<<endl; 
538     return IFSelect_RetError; 
539   }
540   const char* a1 = (const char *)arg1;
541   TopoDS_Shape Shape = XSControl::Vars(pilot)->GetShape(a1);
542   if (Shape.IsNull()) { sout<<"Not a DRAW Shape:"<<arg1<<endl; return IFSelect_RetError; }
543   sout<<"Shape "<<arg1<<" : ";
544
545   Handle(TColStd_HSequenceOfTransient) list =
546     XSControl_ConnectedShapes::AdjacentEntities (Shape,TP,TopAbs_FACE);
547   Standard_Integer i, nb = list->Length();
548   sout<<nb<<" Entities produced Connected Shapes :"<<endl;
549   const Handle(Interface_InterfaceModel) &model = XSControl::Session(pilot)->Model();
550   sout<<"(";
551   for (i = 1; i <= nb; i ++) {
552     if (i > 1) sout<<",";
553     sout<<model->Number(list->Value(i));
554   }
555   sout<<")"<<endl;
556   return IFSelect_RetDone;
557 }
558   
559 //=======================================================================
560 //function : XSControl_trimport
561 //purpose  : 
562 //=======================================================================
563 static IFSelect_ReturnStatus XSControl_trimport
564   (const Handle(IFSelect_SessionPilot)& pilot)
565 {
566   //  FileName ou . (pour courant)  VarName  GiveList (obligatoire)
567   //    GiveList : * pour xst-transferrable-roots
568   Handle(XSControl_WorkSession) WS = XSControl::Session(pilot);
569
570   Standard_Integer argc = pilot->NbWords();
571   Handle(Message_Messenger) sout = Message::DefaultMessenger();
572   if (argc < 4) {
573     sout<<"Give : filename or . for current model;  varname or . to take fileroot\n  GiveList, * for all transferrable roots"<<endl;
574     return IFSelect_RetError;
575   }
576   const Standard_CString arg1 = pilot->Arg(1);
577   const Standard_CString arg2 = pilot->Arg(2);
578   const Standard_CString arg3 = pilot->Arg(3);
579
580   //  File Name and Variable (root) Name
581
582   TCollection_AsciiString fnom,rnom;
583   Standard_Boolean modfic = XSControl_FuncShape::FileAndVar
584     (WS,arg1,arg2,"IMPORT",fnom,rnom);
585   if (modfic) sout<<" File to read : "<<fnom<<endl;
586   else        sout<<" Model taken from the session : "<<fnom<<endl;
587   sout<<" -- Names of variables BREP-DRAW prefixed by : "<<rnom<<endl;
588
589   //  keep the current command, because sub-commands will be called
590   TCollection_AsciiString compart = pilot->CommandPart (3);
591
592   //  Reading file if required
593
594   if (modfic) {
595     TCollection_AsciiString comload ("xload ");
596     comload.AssignCat(arg1);
597     IFSelect_ReturnStatus status = pilot->Execute(comload);
598     if (status != IFSelect_RetDone)
599       { sout<<"Abandon import"<<endl; return status; }
600   } else {
601     sout<<"Currently Loaded Model"<<endl;
602   }
603
604   //  Selecting Entities
605
606   Handle(TColStd_HSequenceOfTransient)  list;
607   if (arg3[0] == '*' && arg3[1] == '\0') {
608     list = WS->GiveList ("xst-transferrable-roots");
609     sout<<"All Transferrable Roots : ";
610   } else {
611     sout<<"List given by "<<compart.ToCString()<<" : ";
612     list = WS->GiveList (compart.ToCString());
613   }
614   if (list.IsNull()) { sout<<"No list defined. Abandon"<<endl; return IFSelect_RetError; }
615   Standard_Integer nbl = list->Length();
616   sout<<"Nb entities selected : "<<nbl<<endl;
617
618   //  Starting Transfer
619
620   WS->InitTransferReader (0);
621   const Handle(XSControl_TransferReader) &TR = WS->TransferReader();
622   if (TR.IsNull()) { sout<<" init not done or failed"<<endl; return IFSelect_RetError; }
623
624   TR->BeginTransfer();
625
626   //  Transferring
627   Standard_Integer nbt = TR->TransferList(list);
628   sout<<"Nb Entities Selected : "<<nbl<<" have given "<<nbt<<" results"<<endl;
629
630   //  Filling VARS. one compound (trimpcomp) or one shape per ent (trimport)
631   Standard_Boolean iscomp = (pilot->Arg(0)[5] == 'c');
632   Standard_Integer nbs = 0;
633   TopoDS_Shape sh;
634   TopoDS_Compound C;
635   BRep_Builder B;
636   B.MakeCompound (C);
637   Handle(Interface_InterfaceModel)  mdl = TR->Model();
638   if (mdl.IsNull()) { sout<<" modele absent"<<endl; return IFSelect_RetError; }
639   for (Standard_Integer il= 1; il <= nbl; il ++) {
640     Handle(Standard_Transient) ent = list->Value(il);
641     sh = TR->ShapeResult(ent);
642     if (sh.IsNull()) continue;
643     nbs ++;
644     if (iscomp) B.Add (C,sh);
645     else {
646       char nomsh[50];
647       sprintf (nomsh,"%s_%d",rnom.ToCString(),nbs);
648       XSControl::Vars(pilot)->SetShape(nomsh,sh);
649     }
650   }
651   if (nbs == 0) sout<<"No Shape produced"<<endl;
652   else if (nbs == 1) {
653     sout<<"One Shape produced, named "<<rnom.ToCString()<<endl;
654     XSControl::Vars(pilot)->SetShape(rnom.ToCString(),sh);
655   } else if (iscomp) {
656     sout<<"One compound made of "<<nbs<<" Shapes, named "<<rnom.ToCString()<<endl;
657     XSControl::Vars(pilot)->SetShape(rnom.ToCString(),C);
658   } else {  // several individual shapes
659     sout<<nbs<<" Shapes, named "<<rnom.ToCString()<<"_1 to "<<rnom.ToCString()<<"_"<<nbs<<endl;
660   }
661
662   return IFSelect_RetDone;
663 }
664
665 //=======================================================================
666 //function : XSControl_twrite
667 //purpose  : 
668 //=======================================================================
669 static IFSelect_ReturnStatus XSControl_twrite
670   (const Handle(IFSelect_SessionPilot)& pilot)
671 {
672   Standard_Integer argc = pilot->NbWords();
673   const Standard_CString arg1 = pilot->Arg(1);
674   //        ****    twrite         ****
675   Handle(Message_Messenger) sout = Message::DefaultMessenger();
676   Handle(XSControl_TransferWriter) TW = XSControl::Session(pilot)->TransferWriter();
677   if (argc < 2) { sout<<" donner nom de shape draw"<<endl; return IFSelect_RetError; }
678   sout<<"Attention, on alimente le modele courant ..."<<endl;
679
680   // Shape
681   for (Standard_Integer i = 1; i < argc; i ++) {
682     const char* ai = (const char *)pilot->Arg(i);
683     TopoDS_Shape Shape = XSControl::Vars(pilot)->GetShape(ai);
684     if (Shape.IsNull()) { sout<<"pas un nom de shape draw:"<<arg1<<endl; continue; }
685     sout<<"Pour Shape : "<<ai;
686     Standard_Integer stat = TW->TransferWriteShape (XSControl::Session(pilot)->Model(),Shape);
687     sout<<" Transfer Write Status = "<<stat<<endl;
688   }
689   pilot->Session()->ComputeGraph();
690   // Transient ? (Geom) : ignore
691   return IFSelect_RetDone;
692 }
693
694 //  ######################################################################
695 //  ####                    TIMERS                                    ####
696 //  ######################################################################
697
698
699 //  ######################################################################
700 //  ####                                                              ####
701 //  ####                    Initialising Commands                     ####
702 //  ####                                                              ####
703 //  ######################################################################
704
705 static int initactor = 0;
706
707
708 //=======================================================================
709 //function : Init
710 //purpose  : 
711 //=======================================================================
712
713 void  XSControl_FuncShape::Init ()
714 {
715   if (initactor) return;  initactor = 1;
716
717   IFSelect_Act::SetGroup("DE: General");
718
719   IFSelect_Act::AddFunc ("tpdraw","[mode:item or root]  num|*  [nomvar] Passes an ITEM to Shape Draw (Start or Result)",XSControl_tpdraw);
720
721   IFSelect_Act::AddFunc ("tpcompound","name:cstring [givelist] : -> compound with Shapes Root or from givelist",XSControl_tpcompound);
722
723   IFSelect_Act::AddFunc ("trdraw","results ->DRAW : all;  or num [name] : from ent.num -> DRAW [name/tread_num]",XSControl_traccess);
724   IFSelect_Act::AddFunc ("trsave","results ->files : all;  or num [name] : from ent.num -> DRAW [name/tread_num]",XSControl_traccess);
725   IFSelect_Act::AddFunc ("trcomp","results -> 1 compound -> DRAW + name optional",XSControl_traccess);
726   IFSelect_Act::AddFunc ("trscomp","results -> 1 compound -> file + name optional",XSControl_traccess);
727
728   IFSelect_Act::AddFunc ("fromshape","shape [level=1]: imported/exported entity (when known)",XSControl_fromshape);
729   IFSelect_Act::AddFunc ("trconnexent","name of draw shape : entities -> connected shapes (when known)",XSControl_trconnexentities);
730
731   IFSelect_Act::AddFunc ("trimport","filename or .  varname  givelist  -> 1 shape per entity",XSControl_trimport);
732   IFSelect_Act::AddFunc ("trimpcomp","filename or .  varname  givelist -> one xcompound",XSControl_trimport);
733
734   IFSelect_Act::AddFunc ("twrite","shape : transfer write for this shape, AFTER newmodel !",XSControl_twrite);
735
736   //skl IFSelect_Act::AddFunc ("checkbrep","shapename or * [+ rootname for expurged and faulties [+ mode f-s]]",XSHAPE_checkbrep);
737   //skl IFSelect_Act::AddFunc ("dblist","option : clear  nb  index  set n1  data n1 n2",XSHAPE_dblist);
738 }
739
740 //  ######################################################################
741 //  ####                                                              ####
742 //  ####                      Additional Methods                      ####
743 //  ####                                                              ####
744 //  ######################################################################
745
746
747 //=======================================================================
748 //function : MoreShapes
749 //purpose  : 
750 //=======================================================================
751
752 Standard_Integer  XSControl_FuncShape::MoreShapes
753   (const Handle(XSControl_WorkSession)& session,
754    Handle(TopTools_HSequenceOfShape)& list, const Standard_CString name)
755 {
756   //  name = un nom -> Draw
757   //  name = "*"    -> tous les transferts RACINES du TP
758   //  name = "**"   -> tous les transferts du TP : VRAIMENT TOUS
759   //  name = "."    -> reperage graphique (not yet impl)
760   //  name = nom(n1-n2) avec n1,n2 entiers :  les variables de nom  nomn1 a nomn2
761   Handle(Message_Messenger) sout = Message::DefaultMessenger();
762   if (list.IsNull()) list = new TopTools_HSequenceOfShape();
763   if (name[0] == '*' && (name[1] == '\0' || (name[1] == '*' && name[2] == '\0'))) {
764     const Handle(Transfer_TransientProcess) &TP = session->TransferReader()->TransientProcess();
765     if (TP.IsNull()) { sout<<"last transfer : unknown"<<endl;return 0; }
766     Handle(TopTools_HSequenceOfShape) li = TransferBRep::Shapes(TP,(name[1] == '\0'));
767     if (li.IsNull()) return 0;
768     list->Append (li);
769     return li->Length();
770   }
771   Standard_Integer i, paro = 0, parf = 0, moins = 0, n1 = 0, n2 = 0;
772   for (i = 0; name[i] != '\0'; i ++) {
773     if (name[i] == '(') paro  = i;
774     if (name[i] == '-') moins = i;
775     if (name[i] == ')') parf  = i;
776   }
777   if (paro && moins && parf) {
778     n2 = atoi (&name[moins+1]);
779     n1 = atoi (&name[paro +1]);  if (n1 < 0) n1 += n2; // sinon on a n1-n2
780   }
781   //  liste
782   if (n1 <= n2 && n1 > 0) {
783     char nom[50], nomsh[60];  Standard_Integer nbsh = 0;
784     for (i = 0; i < paro; i ++) nom[i]=name[i];   nom[paro] = '\0';
785     sout<<"Shapes DRAW named : "<<nom<<n1<<" to "<<nom<<n2;
786     for (i = n1; i <= n2 ; i ++) {
787       const char* nomshh = &nomsh[0];
788       sprintf (nomsh,"%s%d",nom,i);
789       TopoDS_Shape Shape = session->Vars()->GetShape(nomshh);
790       if (Shape.IsNull()) continue;
791       list->Append(Shape);
792       nbsh ++;
793     }
794     sout<<"  -> taken "<<nbsh<<" Shapes"<<endl;
795     return nbsh;
796   }
797   const char* a1 = (const char *)name;
798   TopoDS_Shape Shape = session->Vars()->GetShape(a1);
799   if (Shape.IsNull()) { sout<<"not a shape draw:"<<a1<<endl; return 0; }
800   list->Append(Shape);
801   return 1;
802 }
803
804
805 //=======================================================================
806 //function : FileAndVar
807 //purpose  : 
808 //=======================================================================
809
810 Standard_Boolean  XSControl_FuncShape::FileAndVar
811   (const Handle(XSControl_WorkSession)& session,
812    const Standard_CString file, const Standard_CString var,
813    const Standard_CString def,
814    TCollection_AsciiString& resfile,   TCollection_AsciiString& resvar)
815 {
816   Standard_Boolean iafic = Standard_True;
817   resfile.Clear();  resvar.Clear();
818   if (file)
819     if ( file[0] == '\0' ||
820         (file[0] == '.' && file[1] == '\0')) iafic = Standard_False;
821   if (!iafic) resfile.AssignCat (session->LoadedFile());
822   else        resfile.AssignCat (file);
823  
824   if (var && var[0] != '\0' && (var[0] != '.' || var[1] != '\0') )
825     resvar.AssignCat (var);
826   else if (resfile.Length() == 0) resvar.AssignCat (def);
827   else {
828     Standard_Integer nomdeb, nomfin;
829     nomdeb = resfile.SearchFromEnd ("/");
830     if (nomdeb <= 0) nomdeb = resfile.SearchFromEnd("\\");  // pour NT
831     if (nomdeb <  0) nomdeb = 0;
832     nomfin = resfile.SearchFromEnd (".");
833     if (nomfin < nomdeb) nomfin = resfile.Length() + 1;
834     resvar = resfile.SubString(nomdeb+1,nomfin-1);
835   }
836   return iafic;
837 }