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