0029526: Test Harness command "ReadIges" does not support "read.iges.onlyvisible...
[occt.git] / src / XDEDRAW / XDEDRAW_Common.cxx
1 // Created on: 2003-08-15
2 // Created by: Sergey ZARITCHNY
3 // Copyright (c) 2003-2014 OPEN CASCADE SAS
4 //
5 // This file is part of Open CASCADE Technology software library.
6 //
7 // This library is free software; you can redistribute it and/or modify it under
8 // the terms of the GNU Lesser General Public License version 2.1 as published
9 // by the Free Software Foundation, with special exception defined in the file
10 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
11 // distribution for complete text of the license and disclaimer of any warranty.
12 //
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
15
16
17 #include <DDocStd.hxx>
18 #include <DDocStd_DrawDocument.hxx>
19 #include <Draw.hxx>
20 #include <Draw_Interpretor.hxx>
21 #include <IFSelect_SessionPilot.hxx>
22 #include <IGESCAFControl_Reader.hxx>
23 #include <IGESCAFControl_Writer.hxx>
24 #include <IGESControl_Controller.hxx>
25 #include <Interface_Macros.hxx>
26 #include <STEPCAFControl_ExternFile.hxx>
27 #include <STEPCAFControl_Reader.hxx>
28 #include <STEPCAFControl_Writer.hxx>
29 #include <STEPControl_Controller.hxx>
30 #include <TCollection_ExtendedString.hxx>
31 #include <TDataStd_Name.hxx>
32 #include <TDF_Data.hxx>
33 #include <TDocStd_Application.hxx>
34 #include <TDocStd_Document.hxx>
35 #include <XDEDRAW.hxx>
36 #include <XDEDRAW_Common.hxx>
37 #include <XSControl_WorkSession.hxx>
38 #include <XSDRAW.hxx>
39 #include <XSDRAW_Vars.hxx>
40 #include <XSDRAWIGES.hxx>
41 #include <XSDRAWSTEP.hxx>
42 #include <DDF.hxx>
43
44 #include <DBRep.hxx>
45 #include <XCAFDoc_DocumentTool.hxx>
46 #include <XCAFDoc_ShapeTool.hxx>
47 #include <XCAFDoc_Editor.hxx>
48 #include <TDF_Tool.hxx>
49 #include <TopoDS_Shape.hxx>
50 #include <Interface_Static.hxx>
51
52 #include <stdio.h>
53 //============================================================
54 // Support for several models in DRAW
55 //============================================================
56 static NCollection_DataMap<TCollection_AsciiString, Handle(Standard_Transient)> thedictws;
57
58 static Standard_Boolean ClearDicWS()
59 {
60   thedictws.Clear();
61   return Standard_True;
62 }
63
64 static void AddWS(TCollection_AsciiString filename,
65                   const Handle(XSControl_WorkSession)& WS)
66 {
67   WS->SetVars ( new XSDRAW_Vars ); // support of DRAW variables
68   thedictws.Bind( filename, WS );
69 }
70
71
72 static Standard_Boolean FillDicWS(NCollection_DataMap<TCollection_AsciiString, Handle(STEPCAFControl_ExternFile)>& dicFile)
73 {
74   ClearDicWS();
75   if ( dicFile.IsEmpty() ) {
76     return Standard_False;
77   }
78   Handle(STEPCAFControl_ExternFile) EF;
79   NCollection_DataMap<TCollection_AsciiString, Handle(STEPCAFControl_ExternFile)>::Iterator DicEFIt(dicFile);
80   for (; DicEFIt.More(); DicEFIt.Next() ) {
81     TCollection_AsciiString filename = DicEFIt.Key();
82     EF = DicEFIt.Value();
83     AddWS ( filename, EF->GetWS() );
84   }
85   return Standard_True;  
86 }
87
88 static Standard_Boolean SetCurrentWS (TCollection_AsciiString filename)
89 {
90   if ( !thedictws.IsBound(filename) ) return Standard_False;
91   Handle(XSControl_WorkSession) CurrentWS = 
92     Handle(XSControl_WorkSession)::DownCast( thedictws.ChangeFind(filename) );
93   XSDRAW::Pilot()->SetSession( CurrentWS );
94   
95   return Standard_True;
96 }
97
98
99 //=======================================================================
100 //function : SetCurWS
101 //purpose  : Set current file if many files are read
102 //=======================================================================
103
104 static Standard_Integer SetCurWS (Draw_Interpretor& di , Standard_Integer argc, const char** argv)
105 {
106   if (argc <2) {
107     di<<"Use: "<<argv[0]<<" filename \n";
108     return 1;
109   }
110   TCollection_AsciiString filename (argv[1]);
111   SetCurrentWS( filename );
112   return 0;
113 }
114
115
116 //=======================================================================
117 //function : GetDicWSList
118 //purpose  : List all files recorded after translation
119 //=======================================================================
120
121 static Standard_Integer GetDicWSList (Draw_Interpretor& di, Standard_Integer /*argc*/, const char** /*argv*/)
122 {
123   NCollection_DataMap<TCollection_AsciiString, Handle(Standard_Transient)> DictWS = thedictws;
124   if ( DictWS.IsEmpty() ) return 1;
125   NCollection_DataMap<TCollection_AsciiString, Handle(Standard_Transient)>::Iterator DicIt(DictWS);
126   di << " The list of last translated files:\n";
127   Standard_Integer num = 0;
128   for (; DicIt.More() ; DicIt.Next(), num++ ) {
129     TCollection_AsciiString strng ( DicIt.Key() );
130     if ( num ) di << "\n";
131     di << "\"" << strng.ToCString() << "\"";
132   }
133   return 0;
134 }
135
136 //=======================================================================
137 //function : GetCurWS
138 //purpose  : Return name of file which is current
139 //=======================================================================
140
141 static Standard_Integer GetCurWS (Draw_Interpretor& di, Standard_Integer /*argc*/, const char** /*argv*/)
142 {
143   Handle(XSControl_WorkSession) WS = XSDRAW::Session();
144   di << "\"" << WS->LoadedFile() << "\"";
145   return 0;
146 }
147
148 //=======================================================================
149 //function : FromShape
150 //purpose  : Apply fromshape command to all the loaded WSs
151 //=======================================================================
152
153 static Standard_Integer FromShape (Draw_Interpretor& di, Standard_Integer argc, const char** argv)
154 {
155   if ( argc <2 ) {
156     di << argv[0] << " shape: search for shape origin among all last tranalated files\n";
157     return 0;
158   }
159   
160   char command[256];
161   Sprintf ( command, "fromshape %.200s -1", argv[1] );
162   NCollection_DataMap<TCollection_AsciiString, Handle(Standard_Transient)> DictWS = thedictws;
163   if ( DictWS.IsEmpty() ) return di.Eval ( command );
164   
165   Handle(XSControl_WorkSession) WS = XSDRAW::Session();
166
167   NCollection_DataMap<TCollection_AsciiString, Handle(Standard_Transient)>::Iterator DicIt ( DictWS );
168 //  di << "Searching for shape among all the loaded files:\n";
169   Standard_Integer num = 0;
170   for (; DicIt.More() ; DicIt.Next(), num++ ) {
171     Handle(XSControl_WorkSession) CurrentWS = 
172       Handle(XSControl_WorkSession)::DownCast( DicIt.Value() );
173     XSDRAW::Pilot()->SetSession( CurrentWS );
174     di.Eval ( command );
175   }
176
177   XSDRAW::Pilot()->SetSession( WS );
178   return 0;
179 }
180
181 //=======================================================================
182 //function : ReadIges
183 //purpose  : Read IGES to DECAF document
184 //=======================================================================
185
186 static Standard_Integer ReadIges (Draw_Interpretor& di, Standard_Integer argc, const char** argv)
187 {
188   if ( argc <3 ) {
189     di << "Use: " << argv[0] << " Doc filename [mode]: read IGES file to a document\n";
190     return 0;
191   }
192   
193   DeclareAndCast(IGESControl_Controller,ctl,XSDRAW::Controller());
194   if (ctl.IsNull()) XSDRAW::SetNorm("IGES");
195  
196
197   IGESCAFControl_Reader reader ( XSDRAW::Session(),Standard_True);
198   Standard_Integer onlyvisible = Interface_Static::IVal("read.iges.onlyvisible");
199   reader.SetReadVisible(onlyvisible == 1);
200   
201   if (argc == 4) {
202     Standard_Boolean mode = Standard_True;
203     for ( Standard_Integer i = 0; argv[3][i] ; i++ ) 
204       switch (argv[3][i]) {
205       case '-' : mode = Standard_False; break;
206       case '+' : mode = Standard_True; break;
207       case 'c' : reader.SetColorMode (mode); break;
208       case 'n' : reader.SetNameMode (mode); break;
209       case 'l' : reader.SetLayerMode (mode); break;
210       }
211   }
212   TCollection_AsciiString fnom,rnom;
213   Standard_Boolean modfic = XSDRAW::FileAndVar (argv[2],argv[1],"IGES",fnom,rnom);
214   if (modfic) di<<" File IGES to read : "<<fnom.ToCString()<<"\n";
215   else        di<<" Model taken from the session : "<<fnom.ToCString()<<"\n";
216 //  di<<" -- Names of variables BREP-DRAW prefixed by : "<<rnom<<"\n";
217   IFSelect_ReturnStatus readstat = IFSelect_RetVoid;
218   if (modfic) readstat = reader.ReadFile (fnom.ToCString());
219   else  if (XSDRAW::Session()->NbStartingEntities() > 0) readstat = IFSelect_RetDone;
220   if (readstat != IFSelect_RetDone) {
221     if (modfic) di<<"Could not read file "<<fnom.ToCString()<<" , abandon\n";
222     else di<<"No model loaded\n";
223     return 1;
224   }
225
226   Handle(TDocStd_Document) doc;
227   if (!DDocStd::GetDocument(argv[1],doc,Standard_False)) {  
228     Handle(TDocStd_Application) A = DDocStd::GetApplication();
229     A->NewDocument("BinXCAF",doc);  
230     TDataStd_Name::Set(doc->GetData()->Root(),argv[1]);  
231     Handle(DDocStd_DrawDocument) DD = new DDocStd_DrawDocument(doc);  
232     Draw::Set(argv[1],DD);       
233 //     di << "Document saved with name " << argv[1];
234   }
235   if ( ! reader.Transfer ( doc ) ) {
236     di << "Cannot read any relevant data from the IGES file\n";
237     return 1;
238   }
239   
240 //  Handle(DDocStd_DrawDocument) DD = new DDocStd_DrawDocument(doc);  
241 //  Draw::Set(argv[1],DD);       
242   di << "Document saved with name " << argv[1];
243   
244   return 0;
245 }
246
247 //=======================================================================
248 //function : WriteIges
249 //purpose  : Write DECAF document to IGES
250 //=======================================================================
251
252 static Standard_Integer WriteIges (Draw_Interpretor& di, Standard_Integer argc, const char** argv) 
253 {
254   if ( argc <3 ) {
255     di << "Use: " << argv[0] << " Doc filename [mode]: write document to IGES file\n";
256     return 0;
257   }
258   
259   Handle(TDocStd_Document) Doc;
260   DDocStd::GetDocument(argv[1], Doc);
261   if ( Doc.IsNull() ) {
262     di << argv[1] << " is not a document\n";
263     return 1;
264   }
265   
266   XSDRAW::SetNorm ("IGES");
267   
268 //  IGESControl_Writer ICW (Interface_Static::CVal("write.iges.unit"),
269 //                        Interface_Static::IVal("write.iges.brep.mode"));
270     
271   IGESCAFControl_Writer writer ( XSDRAW::Session(), Standard_True );
272   if (argc == 4) {
273     Standard_Boolean mode = Standard_True;
274     for ( Standard_Integer i = 0; argv[3][i] ; i++ ) 
275       switch (argv[3][i]) {
276       case '-' : mode = Standard_False; break;
277       case '+' : mode = Standard_True; break;
278       case 'c' : writer.SetColorMode (mode); break;
279       case 'n' : writer.SetNameMode (mode); break;
280       case 'l' : writer.SetLayerMode (mode); break;
281       }
282   }
283   writer.Transfer ( Doc );
284
285   di << "Writig IGES model to file " << argv[2] << "\n";
286   if ( writer.Write ( argv[2] ) ) di<<" Write OK\n";
287   else di<<" Write failed\n";
288
289   return 0;
290 }
291
292 //=======================================================================
293 //function : ReadStep
294 //purpose  : Read STEP file to DECAF document 
295 //=======================================================================
296
297 static Standard_Integer ReadStep (Draw_Interpretor& di, Standard_Integer argc, const char** argv)
298 {
299   if ( argc <3 ) {
300     di << "Use: " << argv[0] << " Doc filename [mode]: read STEP file to a document\n";
301     return 0;
302   }
303   
304   DeclareAndCast(STEPControl_Controller,ctl,XSDRAW::Controller());
305   if (ctl.IsNull()) XSDRAW::SetNorm("STEP");
306
307   STEPCAFControl_Reader reader ( XSDRAW::Session(),Standard_True);
308   
309   if (argc == 4) {
310     Standard_Boolean mode = Standard_True;
311     for ( Standard_Integer i = 0; argv[3][i] ; i++ ) 
312       switch (argv[3][i]) {
313       case '-' : mode = Standard_False; break;
314       case '+' : mode = Standard_True; break;
315       case 'c' : reader.SetColorMode (mode); break;
316       case 'n' : reader.SetNameMode (mode); break;
317       case 'l' : reader.SetLayerMode (mode); break;
318       case 'v' : reader.SetPropsMode (mode); break;
319       }
320   }
321   
322   TCollection_AsciiString fnom,rnom;
323   Standard_Boolean modfic = XSDRAW::FileAndVar (argv[2],argv[1],"STEP",fnom,rnom);
324   if (modfic) di<<" File STEP to read : "<<fnom.ToCString()<<"\n";
325   else        di<<" Model taken from the session : "<<fnom.ToCString()<<"\n";
326 //  di<<" -- Names of variables BREP-DRAW prefixed by : "<<rnom<<"\n";
327   IFSelect_ReturnStatus readstat = IFSelect_RetVoid;
328   if (modfic) readstat = reader.ReadFile (fnom.ToCString());
329   else  if (XSDRAW::Session()->NbStartingEntities() > 0) readstat = IFSelect_RetDone;
330   if (readstat != IFSelect_RetDone) {
331     if (modfic) di<<"Could not read file "<<fnom.ToCString()<<" , abandon\n";
332     else di<<"No model loaded\n";
333     return 1;
334   }
335
336   Handle(TDocStd_Document) doc;
337   if (!DDocStd::GetDocument(argv[1],doc,Standard_False)) {  
338     Handle(TDocStd_Application) A = DDocStd::GetApplication();
339     A->NewDocument("BinXCAF",doc);  
340     TDataStd_Name::Set(doc->GetData()->Root(),argv[1]);  
341     Handle(DDocStd_DrawDocument) DD = new DDocStd_DrawDocument(doc);  
342     Draw::Set(argv[1],DD);       
343 //     di << "Document saved with name " << argv[1];
344   }
345   if ( ! reader.Transfer ( doc ) ) {
346     di << "Cannot read any relevant data from the STEP file\n";
347     return 1;
348   }
349   
350   Handle(DDocStd_DrawDocument) DD = new DDocStd_DrawDocument(doc);  
351   Draw::Set(argv[1],DD);       
352   di << "Document saved with name " << argv[1];
353
354   NCollection_DataMap<TCollection_AsciiString, Handle(STEPCAFControl_ExternFile)> DicFile = reader.ExternFiles();
355   FillDicWS( DicFile );
356   AddWS ( fnom , XSDRAW::Session() );
357   
358   return 0;
359 }
360
361 //=======================================================================
362 //function : WriteStep
363 //purpose  : Write DECAF document to STEP
364 //=======================================================================
365
366 static Standard_Integer WriteStep (Draw_Interpretor& di, Standard_Integer argc, const char** argv)
367 {
368   if ( argc <3 ) {
369     di << "Use: " << argv[0] << " Doc filename [mode [multifile_prefix [label]]]: write document to the STEP file\n";
370     di << "mode can be: a or 0 : AsIs (default)\n";
371     di << "             f or 1 : FacettedBRep        s or 2 : ShellBasedSurfaceModel\n";
372     di << "             m or 3 : ManifoldSolidBrep   w or 4 : GeometricCurveSet/WireFrame\n";
373     di << "multifile_prefix: triggers writing assembly components as separate files,\n";
374     di << "                  and defines common prefix for their names\n";
375     di << "label: tag of the sub-assembly label to save only that sub-assembly\n";
376     return 0;
377   }
378   
379   Handle(TDocStd_Document) Doc;   
380   DDocStd::GetDocument(argv[1], Doc);
381   if ( Doc.IsNull() ) {
382     di << argv[1] << " is not a document\n";
383     return 1;
384   }
385   Standard_CString multifile = 0;
386   
387   Standard_Integer k = 3;
388   DeclareAndCast(STEPControl_Controller,ctl,XSDRAW::Controller());
389   if (ctl.IsNull()) XSDRAW::SetNorm("STEP");
390   STEPCAFControl_Writer writer ( XSDRAW::Session(), Standard_True );
391    
392   STEPControl_StepModelType mode = STEPControl_AsIs;
393   if ( argc > k ) {
394     switch (argv[k][0]) {
395     case 'a' :
396     case '0' : mode = STEPControl_AsIs;                    break;
397     case 'f' :
398     case '1' : mode = STEPControl_FacetedBrep;             break;
399     case 's' :
400     case '2' : mode = STEPControl_ShellBasedSurfaceModel;  break;
401     case 'm' :
402     case '3' : mode = STEPControl_ManifoldSolidBrep;       break;
403     case 'w' :
404     case '4' : mode = STEPControl_GeometricCurveSet;       break;
405     default :  di<<"3st arg = mode, incorrect [give fsmw]\n"; return 1;
406     }
407     Standard_Boolean wrmode = Standard_True;
408     for ( Standard_Integer i = 0; argv[k][i] ; i++ ) 
409       switch (argv[3][i]) {
410       case '-' : wrmode = Standard_False; break;
411       case '+' : wrmode = Standard_True; break;
412       case 'c' : writer.SetColorMode (wrmode); break;
413       case 'n' : writer.SetNameMode (wrmode); break;
414       case 'l' : writer.SetLayerMode (wrmode); break;
415       case 'v' : writer.SetPropsMode (wrmode); break;
416       }
417     k++;
418   }
419
420   TDF_Label label;
421   if( argc > k)
422   {
423     TCollection_AsciiString aStr(argv[k]);
424     if( aStr.Search(":") ==-1)
425       multifile = argv[k++];
426     
427   }
428   if( argc > k)
429   {
430       
431     if( !DDF::FindLabel(Doc->Main().Data(), argv[k], label) || label.IsNull()) {  
432       di << "No label for entry"  << "\n";
433       return 1; 
434       
435     }
436   }
437   if( !label.IsNull())
438   {  
439     di << "Translating label "<< argv[k]<<" of document " << argv[1] << " to STEP\n";
440     if(!writer.Transfer ( label, mode, multifile )) 
441     {
442       di << "The label of document cannot be translated or gives no result\n";
443       return 1;
444     }
445
446   }
447   else
448   {
449     di << "Translating document " << argv[1] << " to STEP\n";
450     if ( ! writer.Transfer ( Doc, mode, multifile ) ) {
451       di << "The document cannot be translated or gives no result\n";
452     }
453   }
454   
455
456   di << "Writing STEP file " << argv[2] << "\n";
457   IFSelect_ReturnStatus stat = writer.Write(argv[2]);
458   switch (stat) {
459     case IFSelect_RetVoid : di<<"No file written\n"; break;
460     case IFSelect_RetDone : {
461       di<<"File "<<argv[2]<<" written\n";
462
463       NCollection_DataMap<TCollection_AsciiString, Handle(STEPCAFControl_ExternFile)> DicFile = writer.ExternFiles();
464       FillDicWS( DicFile );
465       AddWS( argv[2], XSDRAW::Session() );
466       break;
467     }
468     default : di<<"Error on writing file\n"; break;
469   }
470   return 0;
471 }
472
473 static Standard_Integer Expand (Draw_Interpretor& di, Standard_Integer argc, const char** argv)
474 {
475   if (argc < 3) {
476     di<<"Use: "<<argv[0]<<" Doc recurs(0/1) or Doc recurs(0/1) label1 label2 ... or Doc recurs(0/1 shape1 shape2 ...\n";
477     return 1;
478   }
479   Handle(TDocStd_Document) Doc;   
480   DDocStd::GetDocument(argv[1], Doc);
481   if ( Doc.IsNull() ) { di << argv[1] << " is not a document\n"; return 1; }
482
483   Handle(XCAFDoc_ShapeTool) aShapeTool = XCAFDoc_DocumentTool::ShapeTool(Doc->Main());
484   Standard_Boolean recurs = Standard_False;
485   if(atoi(argv[2]) != 0)
486     recurs = Standard_True;
487
488   if (argc == 3)
489   {
490     if(!XCAFDoc_Editor::Expand(Doc->Main(), recurs)){
491       di << "No suitable labels to expand\n";
492       return 1;
493     }
494   }
495   else 
496   {
497     for (Standard_Integer i = 3; i < argc; i++)
498     {
499       TDF_Label aLabel;
500       TDF_Tool::Label(Doc->GetData(), argv[i], aLabel);
501       if(aLabel.IsNull()){
502         TopoDS_Shape aShape;
503         aShape = DBRep::Get(argv[i]);
504         aLabel = aShapeTool->FindShape(aShape);
505       }
506
507       if (!aLabel.IsNull()){
508         if(!XCAFDoc_Editor::Expand(Doc->Main(), aLabel, recurs)){
509           di << "The shape is assembly or not compound\n";
510           return 1;
511         }
512       }
513       else
514       { di << argv[i] << " is not a shape\n"; return 1; }
515     }
516   }
517   return 0;
518 }
519
520 void XDEDRAW_Common::InitCommands(Draw_Interpretor& di)
521 {
522   static Standard_Boolean initactor = Standard_False;
523   if (initactor)
524   {
525     return;
526   }
527   initactor = Standard_True;
528
529   Standard_CString g = "XDE translation commands";
530
531   di.Add("ReadIges" , "Doc filename: Read IGES file to DECAF document" ,__FILE__, ReadIges, g);
532   di.Add("WriteIges" , "Doc filename: Write DECAF document to IGES file" ,__FILE__, WriteIges, g);
533   di.Add("ReadStep" , "Doc filename: Read STEP file to DECAF document" ,__FILE__, ReadStep, g);
534   di.Add("WriteStep" , "Doc filename [mode=a [multifile_prefix] [label]]: Write DECAF document to STEP file" ,__FILE__, WriteStep, g);  
535   
536   di.Add("XFileList","Print list of files that was transfered by the last transfer" ,__FILE__, GetDicWSList , g);
537   di.Add("XFileCur", ": returns name of file which is set as current",__FILE__, GetCurWS, g);
538   di.Add("XFileSet", "filename: Set the specified file to be the current one",__FILE__, SetCurWS, g);
539   di.Add("XFromShape", "shape: do fromshape command for all the files",__FILE__, FromShape, g);
540
541   di.Add("XExpand", "XExpand Doc recursively(0/1) or XExpand Doc recursively(0/1) label1 label2 ..."  
542           "or XExpand Doc recursively(0/1) shape1 shape2 ...",__FILE__, Expand, g);
543
544 }