0022728: STEP export API does not provide possibility to control output stream
[occt.git] / src / XSDRAWSTEP / XSDRAWSTEP.cxx
1 //:k8 abv 6 Jan 98: using parameter "step.group" for writing assemblies/shapes
2 #include <XSDRAWSTEP.ixx>
3 #include <STEPControl_Controller.hxx>
4 #include <STEPControl_ActorWrite.hxx>
5 #include <STEPControl_Reader.hxx>
6 #include <STEPControl_Writer.hxx>
7 #include <STEPControl_StepModelType.hxx>
8 #include <XSDRAW.hxx>
9 #include <StepSelect_Activator.hxx>
10
11 #include <Draw_Appli.hxx>
12 #include <Draw_Interpretor.hxx>
13 #include <Draw_Printer.hxx>
14 #include <Message_Messenger.hxx>
15
16 #include <DBRep.hxx>
17
18 #include <TCollection_HAsciiString.hxx>
19 #include <Interface_Macros.hxx>
20 #include <Interface_InterfaceModel.hxx>
21
22 //  Pour le transfert (write)
23 //  Pour NewModel et Write : definition de produit (temporaire ...)
24 #include <Transfer_FinderProcess.hxx>
25 #include <TransferBRep_ShapeMapper.hxx>
26 #include <StepShape_ShapeRepresentation.hxx>
27 #include <TColStd_HSequenceOfTransient.hxx>
28
29 #include <XSControl_Controller.hxx>
30 #include <XSControl_WorkSession.hxx>
31 #include <StepData_StepModel.hxx>
32
33 #include <TopoDS.hxx>
34
35 // steptrans
36 #include <StepToTopoDS_MakeTransformed.hxx>
37 #include <StepGeom_Axis2Placement3d.hxx>
38
39 #include <stdio.h>
40 #include <Interface_Static.hxx>
41 #include <IFSelect_SessionPilot.hxx>
42 #include <STEPSelections_Counter.hxx>
43 #include <STEPSelections_AssemblyExplorer.hxx>
44
45 #include <Draw_ProgressIndicator.hxx>
46 #include <Transfer_TransientProcess.hxx>
47
48 #include <TopExp_Explorer.hxx>
49 #include <XSControl_TransferWriter.hxx>
50 #include <Message_ProgressSentry.hxx>
51
52
53 extern "C" {
54 static void cleanpilot ()
55 {
56   XSDRAW::Session()->ClearData(1);
57 }
58 }
59
60
61 //=======================================================================
62 //function : Init
63 //purpose  : 
64 //=======================================================================
65
66 void XSDRAWSTEP::Init ()
67 {
68   Handle(StepSelect_Activator)   stepact = new StepSelect_Activator;
69   if (STEPControl_Controller::Init()) // XSDRAW::SetNorm("STEP AP-214"); trop tot
70     XSDRAW::SetController(XSControl_Controller::Recorded("STEP"));
71   
72   atexit (cleanpilot);
73 }
74
75 //  ########  COMMANDE stepread  : teste le Reader  #########
76
77 //=======================================================================
78 //function : stepread
79 //purpose  : 
80 //=======================================================================
81
82 static Standard_Integer stepread (Draw_Interpretor& di/*theCommands*/, Standard_Integer argc, const char** argv) 
83 {
84 //  On admet le controller AP214 ou une variante
85   DeclareAndCast(STEPControl_Controller,ctl,XSDRAW::Controller());
86   if (ctl.IsNull()) XSDRAW::SetNorm("STEP");
87
88   // Progress indicator
89   Handle(Draw_ProgressIndicator) progress = new Draw_ProgressIndicator ( di, 1 );
90   progress->SetScale ( 0, 100, 1 );
91   progress->Show();
92   
93   STEPControl_Reader sr (XSDRAW::Session(),Standard_False);
94   TCollection_AsciiString fnom,rnom;
95   Standard_Boolean modfic = XSDRAW::FileAndVar
96     (argv[1],argv[2],"STEP",fnom,rnom);
97   if (modfic) di<<" File STEP to read : "<<fnom.ToCString()<<"\n";
98   else        di<<" Model taken from the session : "<<fnom.ToCString()<<"\n";
99   di<<" -- Names of variables BREP-DRAW prefixed by : "<<rnom.ToCString()<<"\n";
100   IFSelect_ReturnStatus readstat = IFSelect_RetVoid;
101
102   progress->NewScope ( 20, "Loading" ); // On average loading takes 20% 
103   progress->Show();
104
105   if (modfic) readstat = sr.ReadFile (fnom.ToCString());
106   else  if (XSDRAW::Session()->NbStartingEntities() > 0) readstat = IFSelect_RetDone;
107
108   progress->EndScope();
109   progress->Show();
110
111   if (readstat != IFSelect_RetDone) {
112     if (modfic) di<<"Could not read file "<<fnom.ToCString()<<" , abandon"<<"\n";
113     else di<<"No model loaded"<<"\n";
114     return 1;
115   }
116
117   Standard_Boolean fromtcl = (argc > 3);
118 //   nom = "." -> fichier deja lu
119   Standard_Integer i, num, nbs, modepri = 1;
120   if (fromtcl) modepri = 4;
121   Handle(Message_Messenger) aDIMessenger = 
122     new Message_Messenger (new Draw_Printer(di));
123   while (modepri) {
124     num = sr.NbRootsForTransfer();
125     if (!fromtcl) {
126       di<<"NbRootsForTransfer="<<num<<" :\n";
127       for (i = 1; i <= num; i ++) {
128         di<<"Root."<<i<<", Ent. ";
129         sr.Model()->Print(sr.RootForTransfer(i),aDIMessenger);
130         di<<" Type:"<<sr.RootForTransfer(i)->DynamicType()->Name()<<"\n";
131       }
132
133       cout<<"Mode (0 End, 1 root n0 1, 2 one root/n0, 3 one entity/n0, 4 Selection) : "<<flush;
134       cin>>modepri;
135     }
136
137     if (modepri == 0) { di<<"End Reading STEP"<<"\n"; return 0; }
138     if (modepri <= 2) {
139       num = 1;
140       if (modepri == 2) {
141         cout<<"Root N0 : "<<flush;  cin>>num;
142       }
143
144       progress->NewScope ( 80, "Translation" );
145       progress->Show();
146       sr.WS()->MapReader()->SetProgress ( progress );
147
148       if (!sr.TransferRoot (num)) di<<"Transfer root n0 "<<num<<" : no result"<<"\n";
149       else {
150         nbs = sr.NbShapes();
151         char shname[30];  sprintf (shname,"%s_%d",rnom.ToCString(),nbs);
152         di<<"Transfer root n0 "<<num<<" OK  -> DRAW Shape: "<<shname<<"\n";
153         di<<"Now, "<<nbs<<" Shapes produced"<<"\n";
154         TopoDS_Shape sh = sr.Shape(nbs);
155         DBRep::Set (shname,sh);
156       }
157
158       sr.WS()->MapReader()->SetProgress ( 0 );
159       progress->EndScope();
160       progress->Show();
161     }
162     else if (modepri == 3) {
163       cout<<"Entity : "<<flush;  num = XSDRAW::GetEntityNumber();
164       if (!sr.TransferOne (num)) di<<"Transfer entity n0 "<<num<<" : no result"<<"\n";
165       else {
166         nbs = sr.NbShapes();
167         char shname[30];  sprintf (shname,"%s_%d",rnom.ToCString(),num);
168         di<<"Transfer entity n0 "<<num<<" OK  -> DRAW Shape: "<<shname<<"\n";
169         di<<"Now, "<<nbs<<" Shapes produced"<<"\n";
170         TopoDS_Shape sh = sr.Shape(nbs);
171         DBRep::Set (shname,sh);
172       }
173     }
174     else if (modepri == 4) {
175 //      char snm[100];  Standard_Integer answer = 1;
176       Handle(TColStd_HSequenceOfTransient)  list;
177
178 //  Selection, nommee ou via tcl. tcl : raccourcis admis
179 //   * donne xst-transferrable-roots
180       if (fromtcl) {
181         modepri = 0;    // d ioffice une seule passe
182         if (argv[3][0] == '*' && argv[3][1] == '\0') {
183           di<<"Transferrable Roots : ";
184           list = XSDRAW::GetList("xst-transferrable-roots");
185           //list = new TColStd_HSequenceOfTransient;
186           //for(Standard_Integer j=1; j<=num; j++)
187           //  list->Append(sr.RootForTransfer(j));
188         }
189         else {
190           di<<"List given by "<<argv[3];
191           if (argc > 4) di<<" "<<argv[4];
192           di<<" : ";
193           list = XSDRAW::GetList (argv[3], ( argc > 4 ? argv[4] : 0 ) );
194         }
195         if (list.IsNull()) { di<<"No list defined. Give a selection name or * for all transferrable roots"<<"\n"; continue; }
196       } else {
197         cout<<"Name of Selection :"<<flush;
198         list = XSDRAW::GetList();
199         if (list.IsNull()) { di<<"No list defined"<<"\n"; continue; }
200       }
201
202       Standard_Integer ill, nbl = list->Length();
203       di<<"Nb entities selected : "<<nbl<<"\n";
204       if (nbl == 0) continue;
205
206       progress->NewScope ( 80, "Translation" );
207       progress->Show();
208       sr.WS()->MapReader()->SetProgress ( progress );
209
210       Message_ProgressSentry PSentry ( progress, "Root", 0, nbl, 1 );
211       for (ill = 1; ill <= nbl && PSentry.More(); ill ++, PSentry.Next()) {
212         num = sr.Model()->Number(list->Value(ill));
213         if (num == 0) continue;
214         if (!sr.TransferOne(num)) di<<"Transfer entity n0 "<<num<<" : no result"<<"\n";
215         else {
216           nbs = sr.NbShapes();
217           char shname[30];  sprintf (shname,"%s_%d",rnom.ToCString(),nbs);
218           di<<"Transfer entity n0 "<<num<<" OK  -> DRAW Shape: "<<shname<<"\n";
219           di<<"Now, "<<nbs<<" Shapes produced"<<"\n";
220           TopoDS_Shape sh = sr.Shape(nbs);
221           DBRep::Set (shname,sh);
222         }
223       }
224       sr.WS()->MapReader()->SetProgress ( 0 );
225       progress->EndScope();
226       progress->Show();
227     }
228     else di<<"Unknown mode n0 "<<modepri<<"\n";
229   }
230   return 0;
231 }
232
233 //=======================================================================
234 //function : testreadstep
235 //purpose  : 
236 //=======================================================================
237 static Standard_Integer testread (Draw_Interpretor& di, Standard_Integer argc, const char** argv)
238 {
239   if (argc != 3)                                                                                      
240     {                                                                                             
241       di << "ERROR in " << argv[0] << "Wrong Number of Arguments."<<"\n";                     
242       di << " Usage : " << argv[0] <<" file_name shape_name"<< "\n";                          
243       return 1;                                                                                 
244     }
245   STEPControl_Reader Reader;
246   Standard_CString filename = argv[1];
247   IFSelect_ReturnStatus readstat = Reader.ReadFile(filename);
248   di<<"Status from reading STEP file "<<filename<<" : ";  
249   switch(readstat) {                                                              
250     case IFSelect_RetVoid  : { di<<"empty file"<<"\n"; return 1; }            
251     case IFSelect_RetDone  : { di<<"file read"<<"\n";    break; }             
252     case IFSelect_RetError : { di<<"file not found"<<"\n";   return 1; }      
253     case IFSelect_RetFail  : { di<<"error during read"<<"\n";  return 1; }    
254     default  :  { di<<"failure"<<"\n";   return 1; }                          
255   }  
256   Reader.TransferRoots();
257   TopoDS_Shape shape = Reader.OneShape();
258   DBRep::Set(argv[2],shape); 
259   di<<"Count of shapes produced : "<<Reader.NbShapes()<<"\n";
260   return 0;
261 }
262  
263 //=======================================================================
264 //function : readstep
265 //purpose  : 
266 //=======================================================================
267
268 static Standard_Integer readstep (Draw_Interpretor& di, Standard_Integer /*argc*/, const char** argv) 
269 {
270 //  On admet le controller AP214 ou une variante
271   
272   
273   STEPControl_Reader sr;
274   
275   IFSelect_ReturnStatus readstat = IFSelect_RetVoid;
276
277    readstat = sr.ReadFile (argv[1]);
278  
279   if (readstat != IFSelect_RetDone) {
280     
281     di<<"No model loaded"<<"\n";
282     return 1;
283   }
284
285   
286   Standard_Integer  num = sr.NbRootsForTransfer();
287   Standard_Integer  modepri;
288   di<<"NbRootsForTransfer="<<num<<" :\n";
289
290   cout<<"Mode (0 End, 1 root n0 1, 2 one root/n0, 3 one entity/n0, 4 Selection) : "<<flush;
291   cin>>modepri;
292   if (modepri == 0) { di<<"End Reading STEP"<<"\n"; return 0; }
293     
294
295   if (!sr.TransferRoot (num)) di<<"Transfer root n0 "<<num<<" : no result"<<"\n";
296   else {
297     TopoDS_Shape sh = sr.OneShape();
298     DBRep::Set (argv[2],sh);
299   }
300   cin>>modepri;
301   return 0;
302 }
303
304 //  ########  COMMANDE steptrans  : teste les transformations  #########
305 //=======================================================================
306 //function : steptrans
307 //purpose  : 
308 //=======================================================================
309
310 static Standard_Integer steptrans (Draw_Interpretor& di, Standard_Integer argc, const char** argv) 
311 {
312   if (argc < 5) { di<<"give shape-name new-shape + entity-n0 entity-n0: AXIS2"<<"\n";
313                   return 1; }
314   TopoDS_Shape shape = DBRep::Get(argv[1]);
315   if (shape.IsNull()) { di<<"Not a shape : "<<argv[1]<<"\n"; return 1; }
316   Handle(StepGeom_Axis2Placement3d) ax1,ax2;
317   Standard_Integer n1 = 0, n2 = 0;
318   n1 = XSDRAW::GetEntityNumber(argv[3]);
319   if (argc > 4) n2 = XSDRAW::GetEntityNumber(argv[4]);
320   if (n1 > 0) ax1 = Handle(StepGeom_Axis2Placement3d)::DownCast
321     (XSDRAW::Entity(n1));
322   if (n2 > 0) ax2 = Handle(StepGeom_Axis2Placement3d)::DownCast
323     (XSDRAW::Entity(n2));
324   StepToTopoDS_MakeTransformed mktrans;
325   if (mktrans.Compute (ax1,ax2)) {
326     TopLoc_Location loc (mktrans.Transformation());
327     shape.Move (loc);
328 //    mktrans.Transform (shape);
329     DBRep::Set (argv[2],shape);
330     di<<"Transformed Shape as "<<argv[2]<<"\n";
331   }
332   else di<<"No transformation computed"<<"\n";
333   return 0;
334 }
335
336 //  ########  COMMANDE stepwrite : teste le Writer  #########
337
338 //=======================================================================
339 //function : stepwrite
340 //purpose  : 
341 //=======================================================================
342
343 static Standard_Integer stepwrite (Draw_Interpretor& di, Standard_Integer argc, const char** argv) 
344 {
345 //  On admet le controller AP214 ou une variante
346   DeclareAndCast(STEPControl_Controller,ctl,XSDRAW::Controller());
347   if (ctl.IsNull()) {
348     XSDRAW::SetNorm("STEP");
349     //sln 14.01.2002 OCC51: assign new value to ctl in order to avoid exception during using one in the function
350     ctl = Handle(STEPControl_Controller)::DownCast(XSDRAW::Controller());
351   }
352
353   if (argc < 3) {
354     di<<"Give mode[1-4] and Shape name + optional file. Mode possible"<<"\n";
355     di<<"f ou 1 : FacettedBRep        s ou 2 : ShellBasedSurfaceModel\n"
356         <<"m ou 3 : ManifoldSolidBrep   w ou 4 : GeometricCurveSet/WireFrame"<<"\n";
357     return 1; }
358   char modeshape = argv[1][0];
359   STEPControl_StepModelType mode;
360   switch (modeshape) {
361     case 'a' :
362     case '0' : mode = STEPControl_AsIs;                    break;
363     case 'f' :
364     case '1' : mode = STEPControl_FacetedBrep;             break;
365     case 's' :
366     case '2' : mode = STEPControl_ShellBasedSurfaceModel;  break;
367     case 'm' :
368     case '3' : mode = STEPControl_ManifoldSolidBrep;       break;
369     case 'w' :
370     case '4' : mode = STEPControl_GeometricCurveSet;       break;
371     default :  di<<"1st arg = mode, incorrect [give fsmw]"<<"\n"; return 1;
372   }
373
374   //:k8 abv 6 Jan 98: using parameter for writing mode (assemblies/shapes)
375   Handle(STEPControl_ActorWrite) ActWrite = 
376     Handle(STEPControl_ActorWrite)::DownCast ( ctl->ActorWrite() );
377   if ( ! ActWrite.IsNull() ) 
378     ActWrite->SetGroupMode (Interface_Static::IVal("write.step.assembly"));
379
380   TopoDS_Shape shape = DBRep::Get(argv[2]);
381   STEPControl_Writer sw (XSDRAW::Session(),Standard_False);
382   Handle(Interface_InterfaceModel) stepmodel = sw.Model();
383   Standard_Integer nbavant = (stepmodel.IsNull() ? 0 : stepmodel->NbEntities());
384
385   Handle(Draw_ProgressIndicator) progress = new Draw_ProgressIndicator ( di, 1 );
386   progress->NewScope(90,"Translating");
387   progress->Show();
388   sw.WS()->TransferWriter()->FinderProcess()->SetProgress(progress);
389
390   Standard_Integer stat = sw.Transfer (shape,mode);
391   di<<"execution status : "<<stat<<"\n";
392
393   sw.WS()->TransferWriter()->FinderProcess()->SetProgress(0);
394   progress->EndScope();
395   progress->Show();
396   progress->NewScope(10,"Writing");
397   progress->Show();
398
399 //   Que s est-il passe
400   stepmodel = sw.Model();
401   Standard_Integer nbapres = (stepmodel.IsNull() ? 0 : stepmodel->NbEntities());
402   if (nbavant > 0) di<<"Beware : Model not empty before transferring"<<"\n";
403   if (nbapres <= nbavant) di<<"Beware : No data produced by this transfer"<<"\n";
404   if (nbapres == 0) { di<<"No data to write"<<"\n"; return 0; }
405
406   char nomfic[150] ;
407   Standard_Integer modepri = 1;
408
409   if (argc <= 3) {
410     cout<<" Mode (0 end, 1 file) :"<<flush;
411     cin >> modepri; di << "Output mode " << modepri << "\n";
412   }
413   else modepri = 2;
414
415   if      (modepri == 0) return 0;
416   else if (modepri == 1) {
417     cout << " Output file name :" << flush;  cin  >> nomfic;
418   }
419   else if (modepri == 2) strcpy (nomfic,argv[3]);
420
421   di << " Output on file : " << nomfic << "\n";
422   stat = sw.Write(nomfic);
423   switch (stat) {
424     case IFSelect_RetVoid : di<<"No file written"<<"\n"; break;
425     case IFSelect_RetDone : di<<"File "<<nomfic<<" written"<<"\n"; break;
426     case IFSelect_RetStop : di<<"Error on writing file: no space on disk or destination is write protected"<<"\n"; break;
427     default : di<<"File "<<nomfic<<" written with fail messages"<<"\n"; break;
428   }
429
430   progress->EndScope();
431   progress->Show();
432
433   return 0;
434 }
435 //=======================================================================
436 //function : testwritestep
437 //purpose  : 
438 //=======================================================================
439 static Standard_Integer testwrite (Draw_Interpretor& di, Standard_Integer argc, const char** argv) 
440 {
441   if (argc != 3)                                                                                      
442     {                                                                                             
443       di << "ERROR in " << argv[0] << "Wrong Number of Arguments."<<"\n";                     
444       di << " Usage : " << argv[0] <<" file_name shape_name "<< "\n"; 
445       return 1;                                                                                 
446     }
447   STEPControl_Writer Writer;
448   Standard_CString filename = argv[1];
449   TopoDS_Shape shape = DBRep::Get(argv[2]); 
450   IFSelect_ReturnStatus stat = Writer.Transfer(shape,STEPControl_AsIs);
451   stat = Writer.Write(filename);
452   if(stat != IFSelect_RetDone){
453     di<<"Error on writing file"<<"\n";                                                               
454     return 1; 
455   }
456   di<<"File Is Written"<<"\n";
457   return 0;
458 }
459
460 //=======================================================================
461 //function : countexpected
462 //purpose  : 
463 //=======================================================================
464
465 static Standard_Integer countexpected
466   (Draw_Interpretor& di, Standard_Integer /*argc*/, const char** /*argv*/)
467 {
468   Handle(IFSelect_SessionPilot) pilot = XSDRAW::Pilot();
469   Handle(IFSelect_WorkSession) WS = pilot->Session();
470    const Interface_Graph& graph = WS->Graph();
471   
472   Handle(TColStd_HSequenceOfTransient) roots = WS->GiveList("xst-transferrable-roots", "");
473   STEPSelections_Counter cnt;
474   
475   for (Standard_Integer i =1 ; i <= roots->Length(); i++) {
476     cnt.Count(graph,roots->Value(i));
477   }
478   
479   di<< "Instances of Faces \t: "<<cnt.NbInstancesOfFaces()<<"\n";
480   di<< "Instances of Shells\t: "<<cnt.NbInstancesOfShells()<<"\n";
481   di<< "Instances of Solids\t: "<<cnt.NbInstancesOfSolids()<<"\n";
482   di<< "Instances of Wires in GS\t: "<<cnt.NbInstancesOfWires()<<"\n";
483   di<< "Instances of Edges in GS\t: "<<cnt.NbInstancesOfEdges()<<"\n";
484   
485   di<< "Source Faces \t: "<<cnt.NbSourceFaces()<<"\n";
486   di<< "Source Shells\t: "<<cnt.NbSourceShells()<<"\n";
487   di<< "Source Solids\t: "<<cnt.NbSourceSolids()<<"\n";
488   di<< "Source Wires in GS\t: "<<cnt.NbSourceWires()<<"\n";
489   di<< "Source Edges in GS\t: "<<cnt.NbSourceEdges()<<"\n";
490   
491   return 1;
492 }
493
494 static Standard_Integer dumpassembly
495   (Draw_Interpretor& /*di*/, Standard_Integer /*argc*/, const char** /*argv*/)
496 {
497   Handle(IFSelect_SessionPilot) pilot = XSDRAW::Pilot();
498   Handle(IFSelect_WorkSession) WS = pilot->Session();
499   const Interface_Graph& graph = WS->Graph();
500   
501   STEPSelections_AssemblyExplorer exp(graph);
502   exp.Dump(cout);
503   return 0;
504 }
505
506 //  ########  COMMANDE stepwrite : teste le Writer  #########
507
508 void XSDRAWSTEP::InitCommands (Draw_Interpretor& theCommands)
509 {
510   const char* g = "DE: STEP";  // Step transfer file commands
511   XSDRAWSTEP::Init();
512   XSDRAW::LoadDraw(theCommands);
513   theCommands.Add("stepwrite" ,    "stepwrite mode[0-4 afsmw] shape",  __FILE__, stepwrite,     g);
514   theCommands.Add("testwritestep", "testwritestep filename.stp shape", __FILE__, testwrite,     g);
515   theCommands.Add("stepread",      "stepread  [file]",                 __FILE__, stepread,      g);
516   theCommands.Add("testreadstep",  "testreadstep [file] [name DRAW]",  __FILE__, testread,      g);
517   theCommands.Add("steptrans",     "steptrans shape stepax1 stepax2",  __FILE__, steptrans,     g);
518   theCommands.Add("countexpected","TEST",                              __FILE__, countexpected, g);
519   theCommands.Add("dumpassembly", "TEST",                              __FILE__, dumpassembly,  g);
520   theCommands.Add("readstep",      "readstep  [file]",                 __FILE__, readstep,      g);
521 }