0029303: Data Exchange - add RWObj_CafWriter tool for wavefront OBJ file
[occt.git] / src / XSDRAWSTLVRML / XSDRAWSTLVRML.cxx
1 // Created on: 2000-05-30
2 // Created by: Sergey MOZOKHIN
3 // Copyright (c) 2000-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 <AIS_InteractiveContext.hxx>
18 #include <Aspect_TypeOfMarker.hxx>
19 #include <Bnd_Box.hxx>
20 #include <BRep_Builder.hxx>
21 #include <DBRep.hxx>
22 #include <DDocStd.hxx>
23 #include <DDocStd_DrawDocument.hxx>
24 #include <Draw.hxx>
25 #include <Draw_Interpretor.hxx>
26 #include <Draw_PluginMacro.hxx>
27 #include <Draw_ProgressIndicator.hxx>
28 #include <Graphic3d_MaterialAspect.hxx>
29 #include <MeshVS_DataMapOfIntegerAsciiString.hxx>
30 #include <MeshVS_DeformedDataSource.hxx>
31 #include <MeshVS_Drawer.hxx>
32 #include <MeshVS_DrawerAttribute.hxx>
33 #include <MeshVS_ElementalColorPrsBuilder.hxx>
34 #include <MeshVS_Mesh.hxx>
35 #include <MeshVS_MeshEntityOwner.hxx>
36 #include <MeshVS_MeshPrsBuilder.hxx>
37 #include <MeshVS_NodalColorPrsBuilder.hxx>
38 #include <MeshVS_PrsBuilder.hxx>
39 #include <MeshVS_TextPrsBuilder.hxx>
40 #include <MeshVS_VectorPrsBuilder.hxx>
41 #include <OSD_Path.hxx>
42 #include <Quantity_Color.hxx>
43 #include <Quantity_HArray1OfColor.hxx>
44 #include <Quantity_NameOfColor.hxx>
45 #include <RWGltf_CafReader.hxx>
46 #include <RWGltf_CafWriter.hxx>
47 #include <RWStl.hxx>
48 #include <RWObj.hxx>
49 #include <RWObj_CafReader.hxx>
50 #include <RWObj_CafWriter.hxx>
51 #include <SelectMgr_SelectionManager.hxx>
52 #include <Standard_ErrorHandler.hxx>
53 #include <StdSelect_ViewerSelector3d.hxx>
54 #include <StlAPI.hxx>
55 #include <StlAPI_Writer.hxx>
56 #include <TColgp_SequenceOfXYZ.hxx>
57 #include <TCollection_AsciiString.hxx>
58 #include <TColStd_Array1OfReal.hxx>
59 #include <TColStd_HPackedMapOfInteger.hxx>
60 #include <TColStd_MapIteratorOfPackedMapOfInteger.hxx>
61 #include <TDataStd_Name.hxx>
62 #include <TDocStd_Application.hxx>
63 #include <TDocStd_Document.hxx>
64 #include <TopoDS_Face.hxx>
65 #include <TopoDS_Shape.hxx>
66 #include <UnitsAPI.hxx>
67 #include <UnitsMethods.hxx>
68 #include <V3d_View.hxx>
69 #include <ViewerTest.hxx>
70 #include <VrmlAPI.hxx>
71 #include <VrmlAPI_Writer.hxx>
72 #include <VrmlData_DataMapOfShapeAppearance.hxx>
73 #include <VrmlData_Scene.hxx>
74 #include <VrmlData_ShapeConvert.hxx>
75 #include <XCAFDoc_DocumentTool.hxx>
76 #include <XCAFDoc_ShapeTool.hxx>
77 #include <XSDRAW.hxx>
78 #include <XSDRAWIGES.hxx>
79 #include <XSDRAWSTEP.hxx>
80 #include <XSDRAWSTLVRML.hxx>
81 #include <XSDRAWSTLVRML_DataSource.hxx>
82 #include <XSDRAWSTLVRML_DataSource3D.hxx>
83 #include <XSDRAWSTLVRML_DrawableMesh.hxx>
84
85 #ifndef _STDIO_H
86 #include <stdio.h>
87 #endif
88
89 extern Standard_Boolean VDisplayAISObject (const TCollection_AsciiString& theName,
90                                            const Handle(AIS_InteractiveObject)& theAISObj,
91                                            Standard_Boolean theReplaceIfExists = Standard_True);
92
93 //=============================================================================
94 //function : ReadGltf
95 //purpose  : Reads glTF file
96 //=============================================================================
97 static Standard_Integer ReadGltf (Draw_Interpretor& theDI,
98                                   Standard_Integer theNbArgs,
99                                   const char** theArgVec)
100 {
101   TCollection_AsciiString aDestName, aFilePath;
102   Standard_Boolean toUseExistingDoc = Standard_False;
103   Standard_Real aSystemUnitFactor = UnitsMethods::GetCasCadeLengthUnit() * 0.001;
104   Standard_Boolean toListExternalFiles = Standard_False;
105   Standard_Boolean isParallel = Standard_False;
106   Standard_Boolean isDoublePrec = Standard_False;
107   Standard_Boolean toSkipLateDataLoading = Standard_False;
108   Standard_Boolean toKeepLateData = Standard_True;
109   Standard_Boolean toPrintDebugInfo = Standard_False;
110   Standard_Boolean isNoDoc = (TCollection_AsciiString(theArgVec[0]) == "readgltf");
111   for (Standard_Integer anArgIter = 1; anArgIter < theNbArgs; ++anArgIter)
112   {
113     TCollection_AsciiString anArgCase (theArgVec[anArgIter]);
114     anArgCase.LowerCase();
115     if (!isNoDoc
116      && (anArgCase == "-nocreate"
117       || anArgCase == "-nocreatedoc"))
118     {
119       toUseExistingDoc = Standard_True;
120       if (anArgIter + 1 < theNbArgs
121        && Draw::ParseOnOff (theArgVec[anArgIter + 1], toUseExistingDoc))
122       {
123         ++anArgIter;
124       }
125     }
126     else if (anArgCase == "-parallel")
127     {
128       isParallel = Standard_True;
129       if (anArgIter + 1 < theNbArgs
130        && Draw::ParseOnOff (theArgVec[anArgIter + 1], isParallel))
131       {
132         ++anArgIter;
133       }
134     }
135     else if (anArgCase == "-doubleprec"
136           || anArgCase == "-doubleprecision"
137           || anArgCase == "-singleprec"
138           || anArgCase == "-singleprecision")
139     {
140       isDoublePrec = Standard_True;
141       if (anArgIter + 1 < theNbArgs
142        && Draw::ParseOnOff (theArgVec[anArgIter + 1], isDoublePrec))
143       {
144         ++anArgIter;
145       }
146       if (anArgCase.StartsWith ("-single"))
147       {
148         isDoublePrec = !isDoublePrec;
149       }
150     }
151     else if (anArgCase == "-skiplateloading")
152     {
153       toSkipLateDataLoading = Standard_True;
154       if (anArgIter + 1 < theNbArgs
155        && Draw::ParseOnOff (theArgVec[anArgIter + 1], toSkipLateDataLoading))
156       {
157         ++anArgIter;
158       }
159     }
160     else if (anArgCase == "-keeplate")
161     {
162       toKeepLateData = Standard_True;
163       if (anArgIter + 1 < theNbArgs
164        && Draw::ParseOnOff (theArgVec[anArgIter + 1], toKeepLateData))
165       {
166         ++anArgIter;
167       }
168     }
169     else if (anArgCase == "-toprintinfo"
170           || anArgCase == "-toprintdebuginfo")
171     {
172       toPrintDebugInfo = Standard_True;
173       if (anArgIter + 1 < theNbArgs
174        && Draw::ParseOnOff (theArgVec[anArgIter + 1], toPrintDebugInfo))
175       {
176         ++anArgIter;
177       }
178     }
179     else if (anArgCase == "-listexternalfiles"
180           || anArgCase == "-listexternals"
181           || anArgCase == "-listexternal"
182           || anArgCase == "-external"
183           || anArgCase == "-externalfiles")
184     {
185       toListExternalFiles = Standard_True;
186     }
187     else if (aDestName.IsEmpty())
188     {
189       aDestName = theArgVec[anArgIter];
190     }
191     else if (aFilePath.IsEmpty())
192     {
193       aFilePath = theArgVec[anArgIter];
194     }
195     else
196     {
197       Message::SendFail() << "Syntax error at '" << theArgVec[anArgIter] << "'";
198       return 1;
199     }
200   }
201   if (aFilePath.IsEmpty())
202   {
203     Message::SendFail() << "Syntax error: wrong number of arguments";
204     return 1;
205   }
206
207   Handle(Draw_ProgressIndicator) aProgress = new Draw_ProgressIndicator (theDI, 1);
208   Handle(TDocStd_Document) aDoc;
209   if (!toListExternalFiles
210    && !isNoDoc)
211   {
212     Handle(TDocStd_Application) anApp = DDocStd::GetApplication();
213     Standard_CString aNameVar = aDestName.ToCString();
214     DDocStd::GetDocument (aNameVar, aDoc, Standard_False);
215     if (aDoc.IsNull())
216     {
217       if (toUseExistingDoc)
218       {
219         Message::SendFail() << "Error: document with name " << aDestName << " does not exist";
220         return 1;
221       }
222       anApp->NewDocument (TCollection_ExtendedString ("BinXCAF"), aDoc);
223     }
224     else if (!toUseExistingDoc)
225     {
226       Message::SendFail() << "Error: document with name " << aDestName << " already exists";
227       return 1;
228     }
229   }
230
231   RWGltf_CafReader aReader;
232   aReader.SetSystemLengthUnit (aSystemUnitFactor);
233   aReader.SetSystemCoordinateSystem (RWMesh_CoordinateSystem_Zup);
234   aReader.SetDocument (aDoc);
235   aReader.SetParallel (isParallel);
236   aReader.SetDoublePrecision (isDoublePrec);
237   aReader.SetToSkipLateDataLoading (toSkipLateDataLoading);
238   aReader.SetToKeepLateData (toKeepLateData);
239   aReader.SetToPrintDebugMessages (toPrintDebugInfo);
240   if (toListExternalFiles)
241   {
242     aReader.ProbeHeader (aFilePath);
243     for (NCollection_IndexedMap<TCollection_AsciiString>::Iterator aFileIter (aReader.ExternalFiles()); aFileIter.More(); aFileIter.Next())
244     {
245       theDI << "\"" << aFileIter.Value() << "\" ";
246     }
247   }
248   else
249   {
250     aReader.Perform (aFilePath, aProgress->Start());
251     if (isNoDoc)
252     {
253       DBRep::Set (aDestName.ToCString(), aReader.SingleShape());
254     }
255     else
256     {
257       Handle(DDocStd_DrawDocument) aDrawDoc = new DDocStd_DrawDocument (aDoc);
258       TDataStd_Name::Set (aDoc->GetData()->Root(), aDestName);
259       Draw::Set (aDestName.ToCString(), aDrawDoc);
260     }
261   }
262   return 0;
263 }
264
265 //=============================================================================
266 //function : WriteGltf
267 //purpose  : Writes glTF file
268 //=============================================================================
269 static Standard_Integer WriteGltf (Draw_Interpretor& theDI,
270                                    Standard_Integer theNbArgs,
271                                    const char** theArgVec)
272 {
273   TCollection_AsciiString aGltfFilePath;
274   Handle(TDocStd_Document) aDoc;
275   Handle(TDocStd_Application) anApp = DDocStd::GetApplication();
276   TColStd_IndexedDataMapOfStringString aFileInfo;
277   RWGltf_WriterTrsfFormat aTrsfFormat = RWGltf_WriterTrsfFormat_Compact;
278   bool toForceUVExport = false, toEmbedTexturesInGlb = true;
279   for (Standard_Integer anArgIter = 1; anArgIter < theNbArgs; ++anArgIter)
280   {
281     TCollection_AsciiString anArgCase (theArgVec[anArgIter]);
282     anArgCase.LowerCase();
283     if (anArgCase == "-comments"
284      && anArgIter + 1 < theNbArgs)
285     {
286       aFileInfo.Add ("Comments", theArgVec[++anArgIter]);
287     }
288     else if (anArgCase == "-author"
289           && anArgIter + 1 < theNbArgs)
290     {
291       aFileInfo.Add ("Author", theArgVec[++anArgIter]);
292     }
293     else if (anArgCase == "-forceuvexport"
294           || anArgCase == "-forceuv")
295     {
296       toForceUVExport = true;
297       if (anArgIter + 1 < theNbArgs
298        && Draw::ParseOnOff (theArgVec[anArgIter + 1], toForceUVExport))
299       {
300         ++anArgIter;
301       }
302     }
303     else if (anArgCase == "-trsfformat"
304           && anArgIter + 1 < theNbArgs)
305     {
306       TCollection_AsciiString aTrsfStr (theArgVec[++anArgIter]);
307       aTrsfStr.LowerCase();
308       if (aTrsfStr == "compact")
309       {
310         aTrsfFormat = RWGltf_WriterTrsfFormat_Compact;
311       }
312       else if (aTrsfStr == "mat4")
313       {
314         aTrsfFormat = RWGltf_WriterTrsfFormat_Mat4;
315       }
316       else if (aTrsfStr == "trs")
317       {
318         aTrsfFormat = RWGltf_WriterTrsfFormat_TRS;
319       }
320       else
321       {
322         Message::SendFail() << "Syntax error at '" << anArgCase << "'";
323         return 1;
324       }
325     }
326     else if (aDoc.IsNull())
327     {
328       Standard_CString aNameVar = theArgVec[anArgIter];
329       DDocStd::GetDocument (aNameVar, aDoc, false);
330       if (aDoc.IsNull())
331       {
332         TopoDS_Shape aShape = DBRep::Get (aNameVar);
333         if (aShape.IsNull())
334         {
335           Message::SendFail() << "Syntax error: '" << aNameVar << "' is not a shape nor document";
336           return 1;
337         }
338
339         anApp->NewDocument (TCollection_ExtendedString ("BinXCAF"), aDoc);
340         Handle(XCAFDoc_ShapeTool) aShapeTool = XCAFDoc_DocumentTool::ShapeTool (aDoc->Main());
341         aShapeTool->AddShape (aShape);
342       }
343     }
344     else if (aGltfFilePath.IsEmpty())
345     {
346       aGltfFilePath = theArgVec[anArgIter];
347     }
348     else if (anArgCase == "-texturesSeparate")
349     {
350       toEmbedTexturesInGlb = false;
351     }
352     else
353     {
354       Message::SendFail() << "Syntax error at '" << theArgVec[anArgIter] << "'";
355       return 1;
356     }
357   }
358   if (aGltfFilePath.IsEmpty())
359   {
360     Message::SendFail() << "Syntax error: wrong number of arguments";
361     return 1;
362   }
363
364   Handle(Draw_ProgressIndicator) aProgress = new Draw_ProgressIndicator (theDI, 1);
365
366   TCollection_AsciiString anExt = aGltfFilePath;
367   anExt.LowerCase();
368
369   const Standard_Real aSystemUnitFactor = UnitsMethods::GetCasCadeLengthUnit() * 0.001;
370
371   RWGltf_CafWriter aWriter (aGltfFilePath, anExt.EndsWith (".glb"));
372   aWriter.SetTransformationFormat (aTrsfFormat);
373   aWriter.SetForcedUVExport (toForceUVExport);
374   aWriter.SetToEmbedTexturesInGlb (toEmbedTexturesInGlb);
375   aWriter.ChangeCoordinateSystemConverter().SetInputLengthUnit (aSystemUnitFactor);
376   aWriter.ChangeCoordinateSystemConverter().SetInputCoordinateSystem (RWMesh_CoordinateSystem_Zup);
377   aWriter.Perform (aDoc, aFileInfo, aProgress->Start());
378   return 0;
379 }
380
381 static Standard_Integer writestl
382 (Draw_Interpretor& di, Standard_Integer argc, const char** argv)
383 {
384   if (argc < 3 || argc > 4) {
385     di << "Use: " << argv[0]
386     << " shape file [ascii/binary (0/1) : 1 by default]\n";
387   } else {
388     TopoDS_Shape aShape = DBRep::Get(argv[1]);
389     Standard_Boolean isASCIIMode = Standard_False;
390     if (argc == 4) {
391       isASCIIMode = (Draw::Atoi(argv[3]) == 0);
392     }
393     StlAPI_Writer aWriter;
394     aWriter.ASCIIMode() = isASCIIMode;
395     Handle(Draw_ProgressIndicator) aProgress = new Draw_ProgressIndicator (di);
396     Standard_Boolean isOK = aWriter.Write (aShape, argv[2], aProgress->Start());
397     if (!isOK)
398        di << "** Error **: Mesh writing has been failed.\n";
399   }
400   return 0;
401 }
402
403 //=============================================================================
404 //function : readstl
405 //purpose  : Reads stl file
406 //=============================================================================
407 static Standard_Integer readstl(Draw_Interpretor& theDI,
408                                 Standard_Integer theArgc,
409                                 const char** theArgv)
410 {
411   TCollection_AsciiString aShapeName, aFilePath;
412   bool toCreateCompOfTris = false;
413   for (Standard_Integer anArgIter = 1; anArgIter < theArgc; ++anArgIter)
414   {
415     TCollection_AsciiString anArg (theArgv[anArgIter]);
416     anArg.LowerCase();
417     if (aShapeName.IsEmpty())
418     {
419       aShapeName = theArgv[anArgIter];
420     }
421     else if (aFilePath.IsEmpty())
422     {
423       aFilePath = theArgv[anArgIter];
424     }
425     else if (anArg == "-brep")
426     {
427       toCreateCompOfTris = true;
428       if (anArgIter + 1 < theArgc
429        && Draw::ParseOnOff (theArgv[anArgIter + 1], toCreateCompOfTris))
430       {
431         ++anArgIter;
432       }
433     }
434     else
435     {
436       Message::SendFail() << "Syntax error: unknown argument '" << theArgv[anArgIter] << "'";
437       return 1;
438     }
439   }
440   if (aFilePath.IsEmpty())
441   {
442     Message::SendFail() << "Syntax error: not enough arguments";
443     return 1;
444   }
445
446   TopoDS_Shape aShape;
447   if (!toCreateCompOfTris)
448   {
449     // Read STL file to the triangulation.
450     Handle(Draw_ProgressIndicator) aProgress = new Draw_ProgressIndicator (theDI, 1);
451     Handle(Poly_Triangulation) aTriangulation = RWStl::ReadFile (aFilePath.ToCString(), aProgress->Start());
452
453     TopoDS_Face aFace;
454     BRep_Builder aB;
455     aB.MakeFace (aFace);
456     aB.UpdateFace (aFace, aTriangulation);
457     aShape = aFace;
458   }
459   else
460   {
461     Standard_DISABLE_DEPRECATION_WARNINGS
462     StlAPI::Read(aShape, aFilePath.ToCString());
463     Standard_ENABLE_DEPRECATION_WARNINGS
464   }
465   DBRep::Set (aShapeName.ToCString(), aShape);
466   return 0;
467 }
468
469 //! Parse RWMesh_CoordinateSystem enumeration.
470 static Standard_Boolean parseCoordinateSystem (const char* theArg,
471                                                RWMesh_CoordinateSystem& theSystem)
472 {
473   TCollection_AsciiString aCSStr (theArg);
474   aCSStr.LowerCase();
475   if (aCSStr == "zup")
476   {
477     theSystem = RWMesh_CoordinateSystem_Zup;
478   }
479   else if (aCSStr == "yup")
480   {
481     theSystem = RWMesh_CoordinateSystem_Yup;
482   }
483   else
484   {
485     return Standard_False;
486   }
487   return Standard_True;
488 }
489
490 //=============================================================================
491 //function : ReadObj
492 //purpose  : Reads OBJ file
493 //=============================================================================
494 static Standard_Integer ReadObj (Draw_Interpretor& theDI,
495                                  Standard_Integer theNbArgs,
496                                  const char** theArgVec)
497 {
498   TCollection_AsciiString aDestName, aFilePath;
499   Standard_Boolean toUseExistingDoc = Standard_False;
500   Standard_Real aFileUnitFactor = -1.0;
501   RWMesh_CoordinateSystem aResultCoordSys = RWMesh_CoordinateSystem_Zup, aFileCoordSys = RWMesh_CoordinateSystem_Yup;
502   Standard_Boolean toListExternalFiles = Standard_False, isSingleFace = Standard_False, isSinglePrecision = Standard_False;
503   Standard_Boolean isNoDoc = (TCollection_AsciiString(theArgVec[0]) == "readobj");
504   for (Standard_Integer anArgIter = 1; anArgIter < theNbArgs; ++anArgIter)
505   {
506     TCollection_AsciiString anArgCase (theArgVec[anArgIter]);
507     anArgCase.LowerCase();
508     if (anArgIter + 1 < theNbArgs
509      && (anArgCase == "-unit"
510       || anArgCase == "-units"
511       || anArgCase == "-fileunit"
512       || anArgCase == "-fileunits"))
513     {
514       const TCollection_AsciiString aUnitStr (theArgVec[++anArgIter]);
515       aFileUnitFactor = UnitsAPI::AnyToSI (1.0, aUnitStr.ToCString());
516       if (aFileUnitFactor <= 0.0)
517       {
518         Message::SendFail() << "Syntax error: wrong length unit '" << aUnitStr << "'";
519         return 1;
520       }
521     }
522     else if (anArgIter + 1 < theNbArgs
523           && (anArgCase == "-filecoordinatesystem"
524            || anArgCase == "-filecoordsystem"
525            || anArgCase == "-filecoordsys"))
526     {
527       if (!parseCoordinateSystem (theArgVec[++anArgIter], aFileCoordSys))
528       {
529         Message::SendFail() << "Syntax error: unknown coordinate system '" << theArgVec[anArgIter] << "'";
530         return 1;
531       }
532     }
533     else if (anArgIter + 1 < theNbArgs
534           && (anArgCase == "-resultcoordinatesystem"
535            || anArgCase == "-resultcoordsystem"
536            || anArgCase == "-resultcoordsys"
537            || anArgCase == "-rescoordsys"))
538     {
539       if (!parseCoordinateSystem (theArgVec[++anArgIter], aResultCoordSys))
540       {
541         Message::SendFail() << "Syntax error: unknown coordinate system '" << theArgVec[anArgIter] << "'";
542         return 1;
543       }
544     }
545     else if (anArgCase == "-singleprecision"
546           || anArgCase == "-singleprec")
547     {
548       isSinglePrecision = Standard_True;
549       if (anArgIter + 1 < theNbArgs
550        && Draw::ParseOnOff (theArgVec[anArgIter + 1], isSinglePrecision))
551       {
552         ++anArgIter;
553       }
554     }
555     else if (isNoDoc
556           && (anArgCase == "-singleface"
557            || anArgCase == "-singletriangulation"))
558     {
559       isSingleFace = Standard_True;
560     }
561     else if (!isNoDoc
562           && (anArgCase == "-nocreate"
563            || anArgCase == "-nocreatedoc"))
564     {
565       toUseExistingDoc = Standard_True;
566       if (anArgIter + 1 < theNbArgs
567        && Draw::ParseOnOff (theArgVec[anArgIter + 1], toUseExistingDoc))
568       {
569         ++anArgIter;
570       }
571     }
572     else if (anArgCase == "-listexternalfiles"
573           || anArgCase == "-listexternals"
574           || anArgCase == "-listexternal"
575           || anArgCase == "-external"
576           || anArgCase == "-externalfiles")
577     {
578       toListExternalFiles = Standard_True;
579     }
580     else if (aDestName.IsEmpty())
581     {
582       aDestName = theArgVec[anArgIter];
583     }
584     else if (aFilePath.IsEmpty())
585     {
586       aFilePath = theArgVec[anArgIter];
587     }
588     else
589     {
590       Message::SendFail() << "Syntax error at '" << theArgVec[anArgIter] << "'";
591       return 1;
592     }
593   }
594   if (aFilePath.IsEmpty())
595   {
596     Message::SendFail() << "Syntax error: wrong number of arguments";
597     return 1;
598   }
599
600   Handle(Draw_ProgressIndicator) aProgress = new Draw_ProgressIndicator (theDI, 1);
601   Handle(TDocStd_Document) aDoc;
602   if (!isNoDoc
603    && !toListExternalFiles)
604   {
605     Handle(TDocStd_Application) anApp = DDocStd::GetApplication();
606     Standard_CString aNameVar = aDestName.ToCString();
607     DDocStd::GetDocument (aNameVar, aDoc, Standard_False);
608     if (aDoc.IsNull())
609     {
610       if (toUseExistingDoc)
611       {
612         Message::SendFail() << "Error: document with name " << aDestName << " does not exist";
613         return 1;
614       }
615       anApp->NewDocument (TCollection_ExtendedString ("BinXCAF"), aDoc);
616     }
617     else if (!toUseExistingDoc)
618     {
619       Message::SendFail() << "Error: document with name " << aDestName << " already exists";
620       return 1;
621     }
622   }
623
624   RWObj_CafReader aReader;
625   aReader.SetSinglePrecision (isSinglePrecision);
626   aReader.SetSystemLengthUnit (UnitsMethods::GetCasCadeLengthUnit() * 0.001);
627   aReader.SetSystemCoordinateSystem (aResultCoordSys);
628   aReader.SetFileLengthUnit (aFileUnitFactor);
629   aReader.SetFileCoordinateSystem (aFileCoordSys);
630   aReader.SetDocument (aDoc);
631   if (isSingleFace)
632   {
633     RWObj_TriangulationReader aSimpleReader;
634     aSimpleReader.SetSinglePrecision (isSinglePrecision);
635     aSimpleReader.SetCreateShapes (Standard_False);
636     aSimpleReader.SetTransformation (aReader.CoordinateSystemConverter());
637     aSimpleReader.Read (aFilePath.ToCString(), aProgress->Start());
638
639     Handle(Poly_Triangulation) aTriangulation = aSimpleReader.GetTriangulation();
640     TopoDS_Face aFace;
641     BRep_Builder aBuiler;
642     aBuiler.MakeFace (aFace);
643     aBuiler.UpdateFace (aFace, aTriangulation);
644     DBRep::Set (aDestName.ToCString(), aFace);
645     return 0;
646   }
647
648   if (toListExternalFiles)
649   {
650     aReader.ProbeHeader (aFilePath);
651     for (NCollection_IndexedMap<TCollection_AsciiString>::Iterator aFileIter (aReader.ExternalFiles()); aFileIter.More(); aFileIter.Next())
652     {
653       theDI << "\"" << aFileIter.Value() << "\" ";
654     }
655   }
656   else
657   {
658     aReader.Perform (aFilePath, aProgress->Start());
659     if (isNoDoc)
660     {
661       DBRep::Set (aDestName.ToCString(), aReader.SingleShape());
662     }
663     else
664     {
665       Handle(DDocStd_DrawDocument) aDrawDoc = new DDocStd_DrawDocument (aDoc);
666       TDataStd_Name::Set (aDoc->GetData()->Root(), aDestName);
667       Draw::Set (aDestName.ToCString(), aDrawDoc);
668     }
669   }
670   return 0;
671 }
672
673 //=============================================================================
674 //function : WriteObj
675 //purpose  : Writes OBJ file
676 //=============================================================================
677 static Standard_Integer WriteObj (Draw_Interpretor& theDI,
678                                   Standard_Integer theNbArgs,
679                                   const char** theArgVec)
680 {
681   TCollection_AsciiString anObjFilePath;
682   Handle(TDocStd_Document) aDoc;
683   Handle(TDocStd_Application) anApp = DDocStd::GetApplication();
684   TColStd_IndexedDataMapOfStringString aFileInfo;
685   Standard_Real aFileUnitFactor = -1.0;
686   RWMesh_CoordinateSystem aSystemCoordSys = RWMesh_CoordinateSystem_Zup, aFileCoordSys = RWMesh_CoordinateSystem_Yup;
687   for (Standard_Integer anArgIter = 1; anArgIter < theNbArgs; ++anArgIter)
688   {
689     TCollection_AsciiString anArgCase (theArgVec[anArgIter]);
690     anArgCase.LowerCase();
691         if (anArgIter + 1 < theNbArgs
692      && (anArgCase == "-unit"
693       || anArgCase == "-units"
694       || anArgCase == "-fileunit"
695       || anArgCase == "-fileunits"))
696     {
697       const TCollection_AsciiString aUnitStr (theArgVec[++anArgIter]);
698       aFileUnitFactor = UnitsAPI::AnyToSI (1.0, aUnitStr.ToCString());
699       if (aFileUnitFactor <= 0.0)
700       {
701         Message::SendFail() << "Syntax error: wrong length unit '" << aUnitStr << "'";
702         return 1;
703       }
704     }
705     else if (anArgIter + 1 < theNbArgs
706           && (anArgCase == "-filecoordinatesystem"
707            || anArgCase == "-filecoordsystem"
708            || anArgCase == "-filecoordsys"))
709     {
710       if (!parseCoordinateSystem (theArgVec[++anArgIter], aFileCoordSys))
711       {
712         Message::SendFail() << "Syntax error: unknown coordinate system '" << theArgVec[anArgIter] << "'";
713         return 1;
714       }
715     }
716     else if (anArgIter + 1 < theNbArgs
717           && (anArgCase == "-systemcoordinatesystem"
718            || anArgCase == "-systemcoordsystem"
719            || anArgCase == "-systemcoordsys"
720            || anArgCase == "-syscoordsys"))
721     {
722       if (!parseCoordinateSystem (theArgVec[++anArgIter], aSystemCoordSys))
723       {
724         Message::SendFail() << "Syntax error: unknown coordinate system '" << theArgVec[anArgIter] << "'";
725         return 1;
726       }
727     }
728     else if (anArgCase == "-comments"
729           && anArgIter + 1 < theNbArgs)
730     {
731       aFileInfo.Add ("Comments", theArgVec[++anArgIter]);
732     }
733     else if (anArgCase == "-author"
734           && anArgIter + 1 < theNbArgs)
735     {
736       aFileInfo.Add ("Author", theArgVec[++anArgIter]);
737     }
738     else if (aDoc.IsNull())
739     {
740       Standard_CString aNameVar = theArgVec[anArgIter];
741       DDocStd::GetDocument (aNameVar, aDoc, false);
742       if (aDoc.IsNull())
743       {
744         TopoDS_Shape aShape = DBRep::Get (aNameVar);
745         if (aShape.IsNull())
746         {
747           Message::SendFail() << "Syntax error: '" << aNameVar << "' is not a shape nor document";
748           return 1;
749         }
750
751         anApp->NewDocument (TCollection_ExtendedString ("BinXCAF"), aDoc);
752         Handle(XCAFDoc_ShapeTool) aShapeTool = XCAFDoc_DocumentTool::ShapeTool (aDoc->Main());
753         aShapeTool->AddShape (aShape);
754       }
755     }
756     else if (anObjFilePath.IsEmpty())
757     {
758       anObjFilePath = theArgVec[anArgIter];
759     }
760     else
761     {
762       Message::SendFail() << "Syntax error at '" << theArgVec[anArgIter] << "'";
763       return 1;
764     }
765   }
766   if (anObjFilePath.IsEmpty())
767   {
768     Message::SendFail() << "Syntax error: wrong number of arguments";
769     return 1;
770   }
771
772   Handle(Draw_ProgressIndicator) aProgress = new Draw_ProgressIndicator (theDI, 1);
773
774   const Standard_Real aSystemUnitFactor = UnitsMethods::GetCasCadeLengthUnit() * 0.001;
775   RWObj_CafWriter aWriter (anObjFilePath);
776   aWriter.ChangeCoordinateSystemConverter().SetInputLengthUnit (aSystemUnitFactor);
777   aWriter.ChangeCoordinateSystemConverter().SetInputCoordinateSystem (aSystemCoordSys);
778   aWriter.ChangeCoordinateSystemConverter().SetOutputLengthUnit (aFileUnitFactor);
779   aWriter.ChangeCoordinateSystemConverter().SetOutputCoordinateSystem (aFileCoordSys);
780   aWriter.Perform (aDoc, aFileInfo, aProgress->Start());
781   return 0;
782 }
783
784 static Standard_Integer writevrml
785 (Draw_Interpretor& di, Standard_Integer argc, const char** argv)
786 {
787   if (argc < 3 || argc > 5) 
788   {
789     di << "wrong number of parameters\n";
790     return 0;
791   }
792
793   TopoDS_Shape aShape = DBRep::Get(argv[1]);
794
795   // Get the optional parameters
796   Standard_Integer aVersion = 2;
797   Standard_Integer aType = 1;
798   if (argc >= 4)
799   {
800     aVersion = Draw::Atoi(argv[3]);
801     if (argc == 5)
802       aType = Draw::Atoi(argv[4]);
803   }
804
805   // Bound parameters
806   aVersion = Max(1, aVersion);
807   aVersion = Min(2, aVersion);
808   aType = Max(0, aType);
809   aType = Min(2, aType);
810
811   VrmlAPI_Writer writer;
812
813   switch (aType)
814   {
815   case 0: writer.SetRepresentation(VrmlAPI_ShadedRepresentation); break;
816   case 1: writer.SetRepresentation(VrmlAPI_WireFrameRepresentation); break;
817   case 2: writer.SetRepresentation(VrmlAPI_BothRepresentation); break;
818   }
819
820   if (!writer.Write(aShape, argv[2], aVersion))
821   {
822     di << "Error: File " << argv[2] << " was not written\n";
823   }
824
825   return 0;
826 }
827
828 //=======================================================================
829 //function : loadvrml
830 //purpose  :
831 //=======================================================================
832
833 static Standard_Integer loadvrml
834 (Draw_Interpretor& di, Standard_Integer argc, const char** argv)
835 {
836   if (argc<3) di << "wrong number of parameters"    << "\n";
837   else {
838     TopoDS_Shape aShape ;
839     VrmlData_DataMapOfShapeAppearance aShapeAppMap;
840
841     //-----------------------------------------------------------
842     std::filebuf aFic;
843     std::istream aStream (&aFic);
844
845     if (aFic.open(argv[2], std::ios::in)) {
846
847       // Get path of the VRML file.
848       OSD_Path aPath(argv[2]);
849       TCollection_AsciiString aVrmlDir(".");
850       TCollection_AsciiString aDisk = aPath.Disk();
851       TCollection_AsciiString aTrek = aPath.Trek();
852       if (!aTrek.IsEmpty())
853       {
854         if (!aDisk.IsEmpty())
855           aVrmlDir = aDisk;
856         else
857           aVrmlDir.Clear();
858         aTrek.ChangeAll('|', '/');
859         aVrmlDir += aTrek;
860       }
861
862       VrmlData_Scene aScene;
863       Standard_Real anOCCUnit = UnitsMethods::GetCasCadeLengthUnit();
864       aScene.SetLinearScale(1000. / anOCCUnit);
865
866       aScene.SetVrmlDir (aVrmlDir);
867       aScene << aStream;
868       const char * aStr = 0L;
869       switch (aScene.Status()) {
870
871       case VrmlData_StatusOK:
872         {
873           aShape = aScene.GetShape(aShapeAppMap);
874           break;
875         }
876       case VrmlData_EmptyData:            aStr = "EmptyData"; break;
877       case VrmlData_UnrecoverableError:   aStr = "UnrecoverableError"; break;
878       case VrmlData_GeneralError:         aStr = "GeneralError"; break;
879       case VrmlData_EndOfFile:            aStr = "EndOfFile"; break;
880       case VrmlData_NotVrmlFile:          aStr = "NotVrmlFile"; break;
881       case VrmlData_CannotOpenFile:       aStr = "CannotOpenFile"; break;
882       case VrmlData_VrmlFormatError:      aStr = "VrmlFormatError"; break;
883       case VrmlData_NumericInputError:    aStr = "NumericInputError"; break;
884       case VrmlData_IrrelevantNumber:     aStr = "IrrelevantNumber"; break;
885       case VrmlData_BooleanInputError:    aStr = "BooleanInputError"; break;
886       case VrmlData_StringInputError:     aStr = "StringInputError"; break;
887       case VrmlData_NodeNameUnknown:      aStr = "NodeNameUnknown"; break;
888       case VrmlData_NonPositiveSize:      aStr = "NonPositiveSize"; break;
889       case VrmlData_ReadUnknownNode:      aStr = "ReadUnknownNode"; break;
890       case VrmlData_NonSupportedFeature:  aStr = "NonSupportedFeature"; break;
891       case VrmlData_OutputStreamUndefined:aStr = "OutputStreamUndefined"; break;
892       case VrmlData_NotImplemented:       aStr = "NotImplemented"; break;
893       default:
894         break;
895       }
896       if (aStr) {
897         di << " ++ VRML Error: " << aStr << " in line "
898           << aScene.GetLineError() << "\n";
899       }
900       else {
901         DBRep::Set(argv[1],aShape);
902       }
903     }
904     else {
905       di << "cannot open file\n";
906     }
907
908
909     //-----------------------------------------------------------
910   }
911   return 0;
912 }
913
914 //-----------------------------------------------------------------------------
915 static Standard_Integer createmesh
916 (Draw_Interpretor& di, Standard_Integer argc, const char** argv )
917 {
918   if (argc<3)
919   {
920     di << "Wrong number of parameters\n";
921     di << "Use: " << argv[0] << " <mesh name> <stl file>\n";
922     return 0;
923   }
924
925   Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
926   if (aContext.IsNull())
927   {
928     di << "No active view. Please call 'vinit' first\n";
929     return 0;
930   }
931
932   // Progress indicator
933   OSD_Path aFile( argv[2] );
934   Handle(Draw_ProgressIndicator) aProgress = new Draw_ProgressIndicator (di, 1);
935   Handle(Poly_Triangulation) aSTLMesh = RWStl::ReadFile (aFile, aProgress->Start());
936
937   di << "Reading OK...\n";
938   Handle( XSDRAWSTLVRML_DataSource ) aDS = new XSDRAWSTLVRML_DataSource( aSTLMesh );
939   di << "Data source is created successful\n";
940   Handle( MeshVS_Mesh ) aMesh = new MeshVS_Mesh();
941   di << "MeshVS_Mesh is created successful\n";
942
943   aMesh->SetDataSource( aDS );
944   aMesh->AddBuilder( new MeshVS_MeshPrsBuilder( aMesh.operator->() ), Standard_True );
945
946   aMesh->GetDrawer()->SetColor( MeshVS_DA_EdgeColor, Quantity_NOC_YELLOW );
947
948   // Hide all nodes by default
949   Handle(TColStd_HPackedMapOfInteger) aNodes = new TColStd_HPackedMapOfInteger();
950   const Standard_Integer aLen = aSTLMesh->NbNodes();
951   for ( Standard_Integer anIndex = 1; anIndex <= aLen; anIndex++ )
952     aNodes->ChangeMap().Add( anIndex );
953   aMesh->SetHiddenNodes( aNodes );
954   aMesh->SetSelectableNodes ( aNodes );
955
956   VDisplayAISObject(argv[1], aMesh);
957   aContext->Deactivate( aMesh );
958
959   Draw::Set( argv[1], new XSDRAWSTLVRML_DrawableMesh( aMesh ) );
960   Handle( V3d_View ) aView = ViewerTest::CurrentView();
961   if ( !aView.IsNull() )
962     aView->FitAll();
963
964   return 0;
965 }
966 //-----------------------------------------------------------------------------
967
968 static Standard_Integer create3d
969 (Draw_Interpretor& di, Standard_Integer argc, const char** argv )
970 {
971   if (argc<2)
972   {
973     di << "Wrong number of parameters\n";
974     di << "Use: " << argv[0] << " <mesh name>\n";
975     return 0;
976   }
977
978   Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
979   if (aContext.IsNull())
980   {
981     di << "No active view. Please call 'vinit' first\n";
982     return 0;
983   }
984
985   Handle( XSDRAWSTLVRML_DataSource3D ) aDS = new XSDRAWSTLVRML_DataSource3D();
986   di << "Data source is created successful\n";
987   Handle( MeshVS_Mesh ) aMesh = new MeshVS_Mesh();
988   di << "MeshVS_Mesh is created successful\n";
989
990   aMesh->SetDataSource( aDS );
991   aMesh->AddBuilder( new MeshVS_MeshPrsBuilder( aMesh.operator->() ), Standard_True );
992
993   aMesh->GetDrawer()->SetColor( MeshVS_DA_EdgeColor, Quantity_NOC_YELLOW );
994
995   // Hide all nodes by default
996   Handle(TColStd_HPackedMapOfInteger) aNodes = new TColStd_HPackedMapOfInteger();
997   Standard_Integer aLen = aDS->GetAllNodes().Extent();
998   for ( Standard_Integer anIndex = 1; anIndex <= aLen; anIndex++ )
999     aNodes->ChangeMap().Add( anIndex );
1000   aMesh->SetHiddenNodes( aNodes );
1001   aMesh->SetSelectableNodes ( aNodes );
1002
1003   VDisplayAISObject(argv[1], aMesh);
1004   aContext->Deactivate( aMesh );
1005
1006   Draw::Set( argv[1], new XSDRAWSTLVRML_DrawableMesh( aMesh ) );
1007   Handle( V3d_View ) aView = ViewerTest::CurrentView();
1008   if ( !aView.IsNull() )
1009     aView->FitAll();
1010
1011   return 0;
1012 }
1013
1014 Handle( MeshVS_Mesh ) getMesh( const char* theName, Draw_Interpretor& di)
1015 {
1016   Handle( XSDRAWSTLVRML_DrawableMesh ) aDrawMesh =
1017     Handle( XSDRAWSTLVRML_DrawableMesh )::DownCast( Draw::Get( theName ) );
1018
1019   if( aDrawMesh.IsNull() )
1020   {
1021     di << "There is no such object\n";
1022     return NULL;
1023   }
1024   else
1025   {
1026     Handle( MeshVS_Mesh ) aMesh = aDrawMesh->GetMesh();
1027     if( aMesh.IsNull() )
1028     {
1029       di << "There is invalid mesh\n";
1030       return NULL;
1031     }
1032     else
1033       return aMesh;
1034   }
1035 }
1036
1037 //-----------------------------------------------------------------------------
1038 static Standard_Integer setcolor
1039 (Draw_Interpretor& di, Standard_Integer argc, const char** argv, Standard_Integer theParam )
1040 {
1041   if (argc<5)
1042     di << "Wrong number of parameters\n";
1043   else
1044   {
1045     Handle( MeshVS_Mesh ) aMesh = getMesh( argv[1], di );
1046     if( !aMesh.IsNull() )
1047     {
1048       Standard_Real aRed = Draw::Atof (argv[2]);
1049       Standard_Real aGreen = Draw::Atof (argv[3]);
1050       Standard_Real aBlue = Draw::Atof (argv[4]);
1051       aMesh->GetDrawer()->SetColor( (MeshVS_DrawerAttribute)theParam,
1052                                     Quantity_Color( aRed, aGreen, aBlue, Quantity_TOC_RGB ) );
1053
1054       Handle( AIS_InteractiveContext ) aContext = ViewerTest::GetAISContext();
1055
1056       if( aContext.IsNull() )
1057         di << "The context is null\n";
1058       else
1059         aContext->Redisplay (aMesh, Standard_True);
1060     }
1061   }
1062   return 0;
1063 }
1064 //-----------------------------------------------------------------------------
1065 static Standard_Integer meshcolor
1066 (Draw_Interpretor& theInterp, Standard_Integer argc, const char** argv )
1067 {
1068   return setcolor( theInterp, argc, argv, MeshVS_DA_InteriorColor );
1069 }
1070 //-----------------------------------------------------------------------------
1071 static Standard_Integer linecolor
1072 (Draw_Interpretor& theInterp, Standard_Integer argc, const char** argv )
1073 {
1074   return setcolor( theInterp, argc, argv, MeshVS_DA_EdgeColor );
1075 }
1076 //-----------------------------------------------------------------------------
1077 static Standard_Integer meshmat
1078 (Draw_Interpretor& di, Standard_Integer argc, const char** argv )
1079 {
1080   if (argc<3)
1081     di << "Wrong number of parameters\n";
1082   else
1083   {
1084     Handle( MeshVS_Mesh ) aMesh = getMesh( argv[1], di );
1085     if( !aMesh.IsNull() )
1086     {
1087       Standard_Integer aMaterial = Draw::Atoi (argv[2]);
1088
1089       Graphic3d_MaterialAspect aMatAsp =
1090         (Graphic3d_MaterialAspect)(Graphic3d_NameOfMaterial)aMaterial;
1091
1092       if (argc == 4)
1093       {
1094         Standard_Real aTransparency = Draw::Atof(argv[3]);
1095         aMatAsp.SetTransparency (Standard_ShortReal (aTransparency));
1096       }
1097       aMesh->GetDrawer()->SetMaterial( MeshVS_DA_FrontMaterial, aMatAsp );
1098       aMesh->GetDrawer()->SetMaterial( MeshVS_DA_BackMaterial, aMatAsp );
1099
1100       Handle( AIS_InteractiveContext ) aContext = ViewerTest::GetAISContext();
1101
1102       if( aContext.IsNull() )
1103         di << "The context is null\n";
1104       else
1105         aContext->Redisplay (aMesh, Standard_True);
1106     }
1107   }
1108   return 0;
1109 }
1110 //-----------------------------------------------------------------------------
1111 static Standard_Integer shrink
1112 (Draw_Interpretor& di, Standard_Integer argc, const char** argv )
1113 {
1114   if (argc<3)
1115     di << "Wrong number of parameters\n";
1116   else
1117   {
1118     Handle( MeshVS_Mesh ) aMesh = getMesh( argv[1], di );
1119     if( !aMesh.IsNull() )
1120     {
1121       Standard_Real aShrinkCoeff = Draw::Atof (argv[2]);
1122       aMesh->GetDrawer()->SetDouble( MeshVS_DA_ShrinkCoeff, aShrinkCoeff );
1123
1124       Handle( AIS_InteractiveContext ) aContext = ViewerTest::GetAISContext();
1125
1126       if( aContext.IsNull() )
1127         di << "The context is null\n";
1128       else
1129         aContext->Redisplay (aMesh, Standard_True);
1130     }
1131   }
1132   return 0;
1133 }
1134
1135 //-----------------------------------------------------------------------------
1136 static Standard_Integer closed (Draw_Interpretor& theDI, Standard_Integer theArgc, const char** theArgv)
1137 {
1138   if (theArgc < 3)
1139   {
1140     theDI << "Wrong number of parameters.\n";
1141   }
1142   else
1143   {
1144     Handle(MeshVS_Mesh) aMesh = getMesh (theArgv[1], theDI);
1145     if (!aMesh.IsNull())
1146     {
1147       Standard_Boolean aFlag = Draw::Atoi (theArgv[2]) != 0;
1148       aMesh->GetDrawer()->SetBoolean (MeshVS_DA_SupressBackFaces, aFlag);
1149
1150       Handle( AIS_InteractiveContext ) aContext = ViewerTest::GetAISContext();
1151       if (aContext.IsNull())
1152       {
1153         theDI << "The context is null\n";
1154       }
1155       else
1156       {
1157         aContext->Redisplay (aMesh, Standard_True);
1158       }
1159     }
1160   }
1161   return 0;
1162 }
1163
1164 //-----------------------------------------------------------------------------
1165
1166 static Standard_Integer mdisplay
1167 (Draw_Interpretor& di, Standard_Integer argc, const char** argv )
1168 {
1169   if (argc<2)
1170     di << "Wrong number of parameters\n";
1171   else
1172   {
1173     Handle( MeshVS_Mesh ) aMesh = getMesh( argv[1], di );
1174     if( !aMesh.IsNull() )
1175     {
1176       Handle( AIS_InteractiveContext ) aContext = ViewerTest::GetAISContext();
1177
1178       if( aContext.IsNull() )
1179         di << "The context is null\n";
1180       else
1181       {
1182         aContext->Display (aMesh, Standard_True);
1183       }
1184     }
1185   }
1186   return 0;
1187 }
1188 //-----------------------------------------------------------------------------
1189 static Standard_Integer merase
1190 (Draw_Interpretor& di, Standard_Integer argc, const char** argv )
1191 {
1192   if (argc<2)
1193     di << "Wrong number of parameters\n";
1194   else
1195   {
1196     Handle( MeshVS_Mesh ) aMesh = getMesh( argv[1], di );
1197     if( !aMesh.IsNull() )
1198     {
1199       Handle( AIS_InteractiveContext ) aContext = ViewerTest::GetAISContext();
1200
1201       if( aContext.IsNull() )
1202         di << "The context is null\n";
1203       else
1204       {
1205         aContext->Erase (aMesh, Standard_True);
1206       }
1207     }
1208     else
1209       di << "Mesh is null\n";
1210   }
1211   return 0;
1212 }
1213 //-----------------------------------------------------------------------------
1214 static Standard_Integer hidesel
1215 (Draw_Interpretor& di, Standard_Integer argc, const char** argv )
1216 {
1217   if (argc<2)
1218   {
1219     di << "Wrong number of parameters\n";
1220     di << "Use: " << argv[0] << " <mesh name>\n";
1221     return 0;
1222   }
1223
1224   Handle( AIS_InteractiveContext ) aContext = ViewerTest::GetAISContext();
1225   Handle( MeshVS_Mesh ) aMesh = getMesh( argv[1], di );
1226   if( aMesh.IsNull() )
1227   {
1228     di << "The mesh is invalid\n";
1229     return 0;
1230   }
1231
1232   if( aContext.IsNull() )
1233     di << "The context is null\n";
1234   else
1235   {
1236     Handle(TColStd_HPackedMapOfInteger) aHiddenNodes = aMesh->GetHiddenNodes();
1237     if (aHiddenNodes.IsNull())
1238     {
1239       aHiddenNodes = new TColStd_HPackedMapOfInteger();
1240     }
1241     Handle(TColStd_HPackedMapOfInteger) aHiddenElements = aMesh->GetHiddenElems();
1242     if (aHiddenElements.IsNull())
1243     {
1244       aHiddenElements = new TColStd_HPackedMapOfInteger();
1245     }
1246     for( aContext->InitSelected(); aContext->MoreSelected(); aContext->NextSelected() )
1247     {
1248       Handle( MeshVS_MeshEntityOwner ) anOwner =
1249         Handle( MeshVS_MeshEntityOwner )::DownCast( aContext->SelectedOwner() );
1250       if( !anOwner.IsNull() )
1251       {
1252         if( anOwner->Type()==MeshVS_ET_Node )
1253         {
1254           aHiddenNodes->ChangeMap().Add( anOwner->ID() );
1255         }
1256         else
1257         {
1258           aHiddenElements->ChangeMap().Add( anOwner->ID() );
1259         }
1260       }
1261     }
1262     aContext->ClearSelected (Standard_False);
1263     aMesh->SetHiddenNodes( aHiddenNodes );
1264     aMesh->SetHiddenElems( aHiddenElements );
1265     aContext->Redisplay (aMesh, Standard_True);
1266   }
1267
1268   return 0;
1269 }
1270 //-----------------------------------------------------------------------------
1271 static Standard_Integer showonly
1272 (Draw_Interpretor& di, Standard_Integer argc, const char** argv )
1273 {
1274   if (argc<2)
1275   {
1276     di << "Wrong number of parameters\n";
1277     di << "Use: " << argv[0] << " <mesh name>\n";
1278     return 0;
1279   }
1280
1281
1282   Handle( AIS_InteractiveContext ) aContext = ViewerTest::GetAISContext();
1283   Handle( MeshVS_Mesh ) aMesh = getMesh( argv[1], di );
1284   if( aMesh.IsNull() )
1285   {
1286     di << "The mesh is invalid\n";
1287     return 0;
1288   }
1289
1290   if( aContext.IsNull() )
1291     di << "The context is null\n";
1292   else
1293   {
1294     Handle(TColStd_HPackedMapOfInteger) aHiddenNodes =
1295       new TColStd_HPackedMapOfInteger(aMesh->GetDataSource()->GetAllNodes());
1296     Handle(TColStd_HPackedMapOfInteger) aHiddenElements =
1297       new TColStd_HPackedMapOfInteger(aMesh->GetDataSource()->GetAllElements());
1298     for( aContext->InitSelected(); aContext->MoreSelected(); aContext->NextSelected() )
1299     {
1300       Handle( MeshVS_MeshEntityOwner ) anOwner =
1301         Handle( MeshVS_MeshEntityOwner )::DownCast( aContext->SelectedOwner() );
1302       if( !anOwner.IsNull() )
1303       {
1304         if( anOwner->Type() == MeshVS_ET_Node )
1305         {
1306           aHiddenNodes->ChangeMap().Remove( anOwner->ID() );
1307         }
1308         else
1309         {
1310           aHiddenElements->ChangeMap().Remove( anOwner->ID() );
1311         }
1312       }
1313     }
1314     aMesh->SetHiddenNodes( aHiddenNodes );
1315     aMesh->SetHiddenElems( aHiddenElements );
1316     aContext->Redisplay (aMesh, Standard_True);
1317   }
1318
1319   return 0;
1320 }
1321 //-----------------------------------------------------------------------------
1322 static Standard_Integer showall
1323 (Draw_Interpretor& di, Standard_Integer argc, const char** argv )
1324 {
1325   if (argc<2)
1326   {
1327     di << "Wrong number of parameters\n";
1328     di << "Use: " << argv[0] << " <mesh name>\n";
1329     return 0;
1330   }
1331
1332   Handle( AIS_InteractiveContext ) aContext = ViewerTest::GetAISContext();
1333   Handle( MeshVS_Mesh ) aMesh = getMesh( argv[1], di );
1334   if( aMesh.IsNull() )
1335   {
1336     di << "The mesh is invalid\n";
1337     return 0;
1338   }
1339
1340   if( aContext.IsNull() )
1341     di << "The context is null\n";
1342   else
1343   {
1344     aMesh->SetHiddenNodes( new TColStd_HPackedMapOfInteger() );
1345     aMesh->SetHiddenElems( new TColStd_HPackedMapOfInteger() );
1346     aContext->Redisplay (aMesh, Standard_True);
1347   }
1348
1349   return 0;
1350 }
1351
1352 //-----------------------------------------------------------------------------
1353 static Standard_Integer meshcolors( Draw_Interpretor& di,
1354                                     Standard_Integer argc,
1355                                     const char** argv )
1356 {
1357   try
1358   {
1359     OCC_CATCH_SIGNALS
1360       if ( argc < 4 )
1361       {
1362         di << "Wrong number of parameters\n";
1363         di << "Use : meshcolors <mesh name> <mode> <isreflect>\n";
1364         di << "mode : {elem1|elem2|nodal|nodaltex|none}\n";
1365         di << "       elem1 - different color for each element\n";
1366         di << "       elem2 - one color for one side\n";
1367         di << "       nodal - different color for each node\n";
1368         di << "       nodaltex - different color for each node with texture interpolation\n";
1369         di << "       none  - clear\n";
1370         di << "isreflect : {0|1} \n";
1371
1372         return 0;
1373       }
1374
1375       Handle( MeshVS_Mesh ) aMesh = getMesh( argv[ 1 ], di );
1376
1377       if ( aMesh.IsNull() )
1378       {
1379         di << "Mesh not found\n";
1380         return 0;
1381       }
1382       Handle(AIS_InteractiveContext) anIC = ViewerTest::GetAISContext();
1383       if ( anIC.IsNull() )
1384       {
1385         di << "The context is null\n";
1386         return 0;
1387       }
1388       if( !aMesh.IsNull() )
1389       {
1390         TCollection_AsciiString aMode = TCollection_AsciiString (argv[2]);
1391         Quantity_Color aColor1(Quantity_NOC_BLUE1);
1392         Quantity_Color aColor2(Quantity_NOC_RED1);
1393         if( aMode.IsEqual("elem1") || aMode.IsEqual("elem2") || aMode.IsEqual("nodal") || aMode.IsEqual("nodaltex") || aMode.IsEqual("none") )
1394         {
1395           Handle(MeshVS_PrsBuilder) aTempBuilder;
1396           Standard_Integer aReflection = Draw::Atoi(argv[3]);
1397
1398           for (Standard_Integer aCount = 0 ; aCount < aMesh->GetBuildersCount(); aCount++ ){
1399             aTempBuilder = aMesh->FindBuilder("MeshVS_ElementalColorPrsBuilder");
1400             if( !aTempBuilder.IsNull())
1401               aMesh->RemoveBuilderById(aTempBuilder->GetId());
1402
1403             aTempBuilder = aMesh->FindBuilder("MeshVS_NodalColorPrsBuilder");
1404             if( !aTempBuilder.IsNull())
1405               aMesh->RemoveBuilderById(aTempBuilder->GetId());
1406           }
1407
1408           if( aMode.IsEqual("elem1") || aMode.IsEqual("elem2") )
1409           {
1410             Handle(MeshVS_ElementalColorPrsBuilder) aBuilder = new MeshVS_ElementalColorPrsBuilder(
1411                 aMesh, MeshVS_DMF_ElementalColorDataPrs | MeshVS_DMF_OCCMask );
1412               // Color
1413             const TColStd_PackedMapOfInteger& anAllElements = aMesh->GetDataSource()->GetAllElements();
1414             TColStd_MapIteratorOfPackedMapOfInteger anIter( anAllElements );
1415
1416             if( aMode.IsEqual("elem1") )
1417               for ( ; anIter.More(); anIter.Next() )
1418               {
1419                 Quantity_Color aColor( (Quantity_NameOfColor)( anIter.Key() % Quantity_NOC_WHITE ) );
1420                 aBuilder->SetColor1( anIter.Key(), aColor );
1421               }
1422             else
1423               for ( ; anIter.More(); anIter.Next() )
1424                 aBuilder->SetColor2( anIter.Key(), aColor1, aColor2 );
1425
1426             aMesh->AddBuilder( aBuilder, Standard_True );
1427           }
1428
1429
1430           if( aMode.IsEqual("nodal") )
1431           {
1432             Handle(MeshVS_NodalColorPrsBuilder) aBuilder = new MeshVS_NodalColorPrsBuilder(
1433                 aMesh, MeshVS_DMF_NodalColorDataPrs | MeshVS_DMF_OCCMask );
1434             aMesh->AddBuilder( aBuilder, Standard_True );
1435
1436             // Color
1437             const TColStd_PackedMapOfInteger& anAllNodes =
1438               aMesh->GetDataSource()->GetAllNodes();
1439             TColStd_MapIteratorOfPackedMapOfInteger anIter( anAllNodes );
1440             for ( ; anIter.More(); anIter.Next() )
1441             {
1442               Quantity_Color aColor( (Quantity_NameOfColor)(
1443                 anIter.Key() % Quantity_NOC_WHITE ) );
1444               aBuilder->SetColor( anIter.Key(), aColor );
1445             }
1446             aMesh->AddBuilder( aBuilder, Standard_True );
1447           }
1448
1449           if(aMode.IsEqual("nodaltex"))
1450           {
1451             // assign nodal builder to the mesh
1452             Handle(MeshVS_NodalColorPrsBuilder) aBuilder = new MeshVS_NodalColorPrsBuilder(
1453                    aMesh, MeshVS_DMF_NodalColorDataPrs | MeshVS_DMF_OCCMask);
1454             aMesh->AddBuilder(aBuilder, Standard_True);
1455             aBuilder->UseTexture(Standard_True);
1456
1457             // prepare color map for texture
1458             Aspect_SequenceOfColor aColorMap;
1459             aColorMap.Append((Quantity_NameOfColor) Quantity_NOC_RED);
1460             aColorMap.Append((Quantity_NameOfColor) Quantity_NOC_YELLOW);
1461             aColorMap.Append((Quantity_NameOfColor) Quantity_NOC_BLUE1);
1462
1463             // prepare scale map for mesh - it will be assigned to mesh as texture coordinates
1464             // make mesh color interpolated from minimum X coord to maximum X coord
1465             Handle(MeshVS_DataSource) aDataSource = aMesh->GetDataSource();
1466             Standard_Real aMinX, aMinY, aMinZ, aMaxX, aMaxY, aMaxZ;
1467
1468             // get bounding box for calculations
1469             aDataSource->GetBoundingBox().Get(aMinX, aMinY, aMinZ, aMaxX, aMaxY, aMaxZ);
1470             Standard_Real aDelta = aMaxX - aMinX;
1471
1472             // assign color scale map values (0..1) to nodes
1473             TColStd_DataMapOfIntegerReal aScaleMap;
1474             TColStd_Array1OfReal aCoords(1, 3);
1475             Standard_Integer     aNbNodes;
1476             MeshVS_EntityType    aType;
1477
1478             // iterate nodes
1479             const TColStd_PackedMapOfInteger& anAllNodes =
1480                   aMesh->GetDataSource()->GetAllNodes();
1481             TColStd_MapIteratorOfPackedMapOfInteger anIter(anAllNodes);
1482             for (; anIter.More(); anIter.Next())
1483             {
1484               //get node coordinates to aCoord variable
1485               aDataSource->GetGeom(anIter.Key(), Standard_False, aCoords, aNbNodes, aType);
1486
1487               Standard_Real aScaleValue;
1488               try {
1489                 OCC_CATCH_SIGNALS
1490                 aScaleValue = (aCoords.Value(1) - (Standard_Real) aMinX) / aDelta;
1491               } catch(Standard_Failure const&) {
1492                 aScaleValue = 0;
1493               }
1494
1495               aScaleMap.Bind(anIter.Key(), aScaleValue);
1496             }
1497
1498             //set color map for builder and a color for invalid scale value
1499             aBuilder->SetColorMap(aColorMap);
1500             aBuilder->SetInvalidColor(Quantity_NOC_BLACK);
1501             aBuilder->SetTextureCoords(aScaleMap);
1502             aMesh->AddBuilder(aBuilder, Standard_True);
1503           }
1504
1505           aMesh->GetDrawer()->SetBoolean (MeshVS_DA_ColorReflection, aReflection != 0);
1506
1507           anIC->Redisplay (aMesh, Standard_True);
1508         }
1509         else
1510         {
1511           di << "Wrong mode name\n";
1512           return 0;
1513         }
1514       }
1515   }
1516   catch ( Standard_Failure const& )
1517   {
1518     di << "Error\n";
1519   }
1520
1521   return 0;
1522 }
1523 //-----------------------------------------------------------------------------
1524 static Standard_Integer meshvectors( Draw_Interpretor& di,
1525                                      Standard_Integer argc,
1526                                      const char** argv )
1527 {
1528   if ( argc < 3 )
1529   {
1530     di << "Wrong number of parameters\n";
1531     di << "Use : meshvectors <mesh name> < -mode {elem|nodal|none} > [-maxlen len] [-color name] [-arrowpart ratio] [-issimple {1|0}]\n";
1532     di << "Supported mode values:\n";
1533     di << "       elem  - vector per element\n";
1534     di << "       nodal - vector per node\n";
1535     di << "       none  - clear\n";
1536
1537     return 0;
1538   }
1539
1540   Handle( MeshVS_Mesh ) aMesh = getMesh( argv[ 1 ], di );
1541
1542   if ( aMesh.IsNull() )
1543   {
1544     di << "Mesh not found\n";
1545     return 0;
1546   }
1547   Handle(AIS_InteractiveContext) anIC = ViewerTest::GetAISContext();
1548   if ( anIC.IsNull() )
1549   {
1550     di << "The context is null\n";
1551     return 0;
1552   }
1553
1554   TCollection_AsciiString aParam;
1555   TCollection_AsciiString aMode("none");
1556   Standard_Real           aMaxlen(1.0);
1557   Quantity_Color          aColor(Quantity_NOC_ORANGE);
1558   Standard_Real           anArrowPart(0.1);
1559   Standard_Boolean        isSimplePrs(Standard_False);
1560
1561   for (Standard_Integer anIdx = 2; anIdx < argc; anIdx++)
1562   {
1563     if (!aParam.IsEmpty())
1564     {
1565       if (aParam == "-mode")
1566       {
1567         aMode       = argv[anIdx];
1568       }
1569       else if (aParam == "-maxlen")
1570       {
1571         aMaxlen     = Draw::Atof(argv[anIdx]);
1572       }
1573       else if (aParam == "-color")
1574       {
1575         if (!Quantity_Color::ColorFromName (argv[anIdx], aColor))
1576         {
1577           Message::SendFail() << "Syntax error at " << aParam;
1578           return 1;
1579         }
1580       }
1581       else if (aParam == "-arrowpart")
1582       {
1583         anArrowPart = Draw::Atof(argv[anIdx]);
1584       }
1585       else if (aParam == "-issimple")
1586       {
1587         isSimplePrs = Draw::Atoi(argv[anIdx]) != 0;
1588       }
1589       aParam.Clear();
1590     }
1591     else if (argv[anIdx][0] == '-')
1592     {
1593       aParam = argv[anIdx];
1594     }
1595   }
1596
1597   if( !aMode.IsEqual("elem") && !aMode.IsEqual("nodal") && !aMode.IsEqual("none") )
1598   {
1599     di << "Wrong mode name\n";
1600     return 0;
1601   }
1602
1603   Handle(MeshVS_PrsBuilder) aTempBuilder;
1604
1605   aTempBuilder = aMesh->FindBuilder("MeshVS_VectorPrsBuilder");
1606   if( !aTempBuilder.IsNull())
1607     aMesh->RemoveBuilderById(aTempBuilder->GetId());
1608
1609   if( !aMode.IsEqual("none") )
1610   {
1611     Handle(MeshVS_VectorPrsBuilder) aBuilder = new MeshVS_VectorPrsBuilder( aMesh.operator->(), 
1612                                                                             aMaxlen,
1613                                                                             aColor,
1614                                                                             MeshVS_DMF_VectorDataPrs,
1615                                                                             0,
1616                                                                             -1,
1617                                                                             MeshVS_BP_Vector,
1618                                                                             isSimplePrs);
1619
1620     Standard_Boolean anIsElement = aMode.IsEqual("elem");
1621     const TColStd_PackedMapOfInteger& anAllIDs = anIsElement ? aMesh->GetDataSource()->GetAllElements() :
1622                                                                aMesh->GetDataSource()->GetAllNodes();
1623
1624     Standard_Integer aNbNodes;
1625     MeshVS_EntityType aEntType;
1626
1627     TColStd_Array1OfReal aCoords(1, 3);
1628     aCoords.Init (0.);
1629     TColStd_MapIteratorOfPackedMapOfInteger anIter( anAllIDs );
1630     for ( ; anIter.More(); anIter.Next() )
1631     {
1632       Standard_Boolean IsValidData = Standard_False; 
1633       if (anIsElement) {
1634         aMesh->GetDataSource()->GetGeomType(anIter.Key(), anIsElement, aEntType);
1635         if (aEntType == MeshVS_ET_Face)
1636           IsValidData = aMesh->GetDataSource()->GetNormal(anIter.Key(), 3, aCoords.ChangeValue(1), aCoords.ChangeValue(2), aCoords.ChangeValue(3));
1637       } else
1638         IsValidData = aMesh->GetDataSource()->GetGeom(anIter.Key(), Standard_False, aCoords, aNbNodes, aEntType);
1639
1640       gp_Vec aNorm;
1641       if(IsValidData)
1642       { 
1643         aNorm = gp_Vec(aCoords.Value(1), aCoords.Value(2), aCoords.Value(3));
1644         if(aNorm.Magnitude() < gp::Resolution())
1645         {
1646           aNorm = gp_Vec(0,0,1); //method GetGeom(...) returns coordinates of nodes
1647         }
1648       }
1649       else
1650       {
1651         aNorm = gp_Vec(0,0,1);
1652       }
1653       aBuilder->SetVector(anIsElement, anIter.Key(), aNorm.Normalized());
1654     }
1655
1656     aMesh->AddBuilder( aBuilder, Standard_False );
1657     aMesh->GetDrawer()->SetDouble ( MeshVS_DA_VectorArrowPart, anArrowPart );
1658   }
1659
1660   anIC->Redisplay (aMesh, Standard_True);
1661
1662   return 0;
1663 }
1664 //-----------------------------------------------------------------------------
1665
1666 static Standard_Integer meshtext( Draw_Interpretor& di,
1667                                   Standard_Integer argc,
1668                                   const char** argv )
1669 {
1670   if ( argc < 2 )
1671   {
1672     di << "Wrong number of parameters\n";
1673     di << "Use : meshtext <mesh name>\n";
1674     return 0;
1675   }
1676
1677   Handle( MeshVS_Mesh ) aMesh = getMesh( argv[ 1 ], di );
1678
1679   if ( aMesh.IsNull() )
1680   {
1681     di << "Mesh not found\n";
1682     return 0;
1683   }
1684
1685   Handle(AIS_InteractiveContext) anIC = ViewerTest::GetAISContext();
1686   if ( anIC.IsNull() )
1687   {
1688     di << "The context is null\n";
1689     return 0;
1690   }
1691
1692   // Prepare triangle labels
1693   MeshVS_DataMapOfIntegerAsciiString aLabels;
1694   Standard_Integer aLen = aMesh->GetDataSource()->GetAllElements().Extent();
1695   for ( Standard_Integer anIndex = 1; anIndex <= aLen; anIndex++ ){
1696     aLabels.Bind( anIndex, TCollection_AsciiString( anIndex ) );
1697   }
1698
1699   Handle(MeshVS_TextPrsBuilder) aTextBuilder = new MeshVS_TextPrsBuilder( aMesh.operator->(), 20., Quantity_NOC_YELLOW );
1700   aTextBuilder->SetTexts( Standard_True, aLabels );
1701   aMesh->AddBuilder( aTextBuilder );
1702
1703   return 0;
1704 }
1705
1706 static Standard_Integer meshdeform( Draw_Interpretor& di,
1707                                     Standard_Integer argc,
1708                                     const char** argv )
1709 {
1710   if ( argc < 3 )
1711   {
1712     di << "Wrong number of parameters\n";
1713     di << "Use : meshdeform <mesh name> < -mode {on|off} > [-scale scalefactor]\n";
1714     return 0;
1715   }
1716
1717   Handle( MeshVS_Mesh ) aMesh = getMesh( argv[ 1 ], di );
1718
1719   if ( aMesh.IsNull() )
1720   {
1721     di << "Mesh not found\n";
1722     return 0;
1723   }
1724   Handle(AIS_InteractiveContext) anIC = ViewerTest::GetAISContext();
1725   if ( anIC.IsNull() )
1726   {
1727     di << "The context is null\n";
1728     return 0;
1729   }
1730
1731   TCollection_AsciiString aParam;
1732   TCollection_AsciiString aMode("off");
1733   Standard_Real           aScale(1.0);
1734
1735   for (Standard_Integer anIdx = 2; anIdx < argc; anIdx++)
1736   {
1737     if (!aParam.IsEmpty())
1738     {
1739       if (aParam == "-mode")
1740       {
1741         aMode = argv[anIdx];
1742       }
1743       else if (aParam == "-scale")
1744       {
1745         aScale = Draw::Atof(argv[anIdx]);
1746       }
1747       aParam.Clear();
1748     }
1749     else if (argv[anIdx][0] == '-')
1750     {
1751       aParam = argv[anIdx];
1752     }
1753   }
1754
1755   if(!aMode.IsEqual("on") && !aMode.IsEqual("off"))
1756   {
1757     di << "Wrong mode name\n";
1758     return 0;
1759   }
1760
1761   Handle ( MeshVS_DeformedDataSource ) aDefDS =
1762     new MeshVS_DeformedDataSource( aMesh->GetDataSource() , aScale );
1763
1764   const TColStd_PackedMapOfInteger& anAllIDs = aMesh->GetDataSource()->GetAllNodes();
1765
1766   Standard_Integer aNbNodes;
1767   MeshVS_EntityType aEntType;
1768
1769   TColStd_MapIteratorOfPackedMapOfInteger anIter( anAllIDs );
1770   for ( ; anIter.More(); anIter.Next() )
1771   {
1772     TColStd_Array1OfReal aCoords(1, 3);
1773     aMesh->GetDataSource()->GetGeom(anIter.Key(), Standard_False, aCoords, aNbNodes, aEntType);
1774
1775     gp_Vec aNorm = gp_Vec(aCoords.Value(1), aCoords.Value(2), aCoords.Value(3));
1776     if( !aNorm.Magnitude() )
1777       aNorm = gp_Vec(0,0,1);
1778     aDefDS->SetVector(anIter.Key(), aNorm.Normalized());
1779   }
1780
1781   aMesh->SetDataSource(aDefDS);
1782
1783   anIC->Redisplay (aMesh, Standard_False);
1784
1785   Handle( V3d_View ) aView = ViewerTest::CurrentView();
1786   if ( !aView.IsNull() )
1787     aView->FitAll();
1788
1789   return 0;
1790 }
1791
1792 static Standard_Integer mesh_edge_width( Draw_Interpretor& di,
1793                                         Standard_Integer argc,
1794                                         const char** argv )
1795 {
1796   try
1797   {
1798     OCC_CATCH_SIGNALS
1799       if ( argc < 3 )
1800       {
1801         di << "Wrong number of parameters\n";
1802         di << "Use : mesh_edge_width <mesh name> <width>\n";
1803         return 0;
1804       }
1805
1806       Handle(MeshVS_Mesh) aMesh = getMesh( argv[ 1 ], di );
1807       if ( aMesh.IsNull() )
1808       {
1809         di << "Mesh not found\n";
1810         return 0;
1811       }
1812
1813       const char* aWidthStr = argv[ 2 ];
1814       if ( aWidthStr == 0 || Draw::Atof( aWidthStr ) <= 0 )
1815       {
1816         di << "Width must be real value more than zero\n";
1817         return 0;
1818       }
1819
1820       double aWidth = Draw::Atof( aWidthStr );
1821
1822       Handle(AIS_InteractiveContext) anIC = ViewerTest::GetAISContext();
1823       if ( anIC.IsNull() )
1824       {
1825         di << "The context is null\n";
1826         return 0;
1827       }
1828
1829       Handle(MeshVS_Drawer) aDrawer = aMesh->GetDrawer();
1830       if ( aDrawer.IsNull() )
1831       {
1832         di << "The drawer is null\n";
1833         return 0;
1834       }
1835
1836       aDrawer->SetDouble( MeshVS_DA_EdgeWidth, aWidth );
1837       anIC->Redisplay (aMesh, Standard_True);
1838   }
1839   catch ( Standard_Failure const& )
1840   {
1841     di << "Error\n";
1842   }
1843
1844   return 0;
1845 }
1846
1847 //-----------------------------------------------------------------------------
1848
1849 static Standard_Integer meshinfo(Draw_Interpretor& di,
1850                                  Standard_Integer argc,
1851                                  const char** argv)
1852 {
1853   if ( argc != 2 )
1854   {
1855     di << "Wrong number of parameters. Use : meshinfo mesh\n";
1856     return 0;
1857   }
1858
1859   Handle(MeshVS_Mesh) aMesh = getMesh(argv[ 1 ], di);
1860   if ( aMesh.IsNull() )
1861   {
1862     di << "Mesh not found\n";
1863     return 0;
1864   }
1865
1866   Handle(XSDRAWSTLVRML_DataSource) stlMeshSource = Handle(XSDRAWSTLVRML_DataSource)::DownCast(aMesh->GetDataSource());
1867   if (!stlMeshSource.IsNull())
1868   {
1869     const TColStd_PackedMapOfInteger& nodes = stlMeshSource->GetAllNodes();
1870     const TColStd_PackedMapOfInteger& tris  = stlMeshSource->GetAllElements();
1871
1872     di << "Nb nodes = " << nodes.Extent() << "\n";
1873     di << "Nb triangles = " << tris.Extent() << "\n";
1874   }
1875
1876   return 0;
1877 }
1878
1879 //-----------------------------------------------------------------------------
1880
1881 void  XSDRAWSTLVRML::InitCommands (Draw_Interpretor& theCommands)
1882 {
1883   const char* g = "XSTEP-STL/VRML";  // Step transfer file commands
1884   //XSDRAW::LoadDraw(theCommands);
1885
1886   theCommands.Add ("ReadGltf",
1887                    "ReadGltf Doc file [-parallel {on|off}] [-listExternalFiles] [-noCreateDoc] [-doublePrecision {on|off}]"
1888                    "\n\t\t: Read glTF file into XDE document."
1889                    "\n\t\t:   -listExternalFiles do not read mesh and only list external files"
1890                    "\n\t\t:   -noCreateDoc read into existing XDE document"
1891                    "\n\t\t:   -doublePrecision store triangulation with double or single floating point"
1892                    "\n\t\t:                    precision (single by default)"
1893                    "\n\t\t:   -skipLateLoading data loading is skipped and can be performed later"
1894                    "\n\t\t:                    (false by default)"
1895                    "\n\t\t:   -keepLate data is loaded into itself with preservation of information"
1896                    "\n\t\t:             about deferred storage to load/unload this data later.",
1897                    "\n\t\t:   -toPrintDebugInfo print additional debug information during data reading"
1898                    __FILE__, ReadGltf, g);
1899   theCommands.Add ("readgltf",
1900                    "readgltf shape file"
1901                    "\n\t\t: Same as ReadGltf but reads glTF file into a shape instead of a document.",
1902                    __FILE__, ReadGltf, g);
1903   theCommands.Add ("WriteGltf",
1904                    "WriteGltf Doc file [-trsfFormat {compact|TRS|mat4}=compact]"
1905            "\n\t\t:                    [-comments Text] [-author Name]"
1906            "\n\t\t:                    [-forceUVExport] [-texturesSeparate]"
1907            "\n\t\t: Write XDE document into glTF file."
1908            "\n\t\t:   -trsfFormat preferred transformation format"
1909            "\n\t\t:   -forceUVExport always export UV coordinates"
1910            "\n\t\t:   -texturesSeparate write textures to separate files",
1911                    __FILE__, WriteGltf, g);
1912   theCommands.Add ("writegltf",
1913                    "writegltf shape file",
1914                    __FILE__, WriteGltf, g);
1915   theCommands.Add ("writevrml", "shape file [version VRML#1.0/VRML#2.0 (1/2): 2 by default] [representation shaded/wireframe/both (0/1/2): 1 by default]",__FILE__,writevrml,g);
1916   theCommands.Add ("writestl",  "shape file [ascii/binary (0/1) : 1 by default] [InParallel (0/1) : 0 by default]",__FILE__,writestl,g);
1917   theCommands.Add ("readstl",
1918                    "readstl shape file [-brep]"
1919                    "\n\t\t: Reads STL file and creates a new shape with specified name."
1920                    "\n\t\t: When -brep is specified, creates a Compound of per-triangle Faces."
1921                    "\n\t\t: Single triangulation-only Face is created otherwise (default).",
1922                    __FILE__, readstl, g);
1923   theCommands.Add ("loadvrml" , "shape file",__FILE__,loadvrml,g);
1924   theCommands.Add ("ReadObj",
1925                    "ReadObj Doc file [-fileCoordSys {Zup|Yup}] [-fileUnit Unit]"
1926            "\n\t\t:                  [-resultCoordSys {Zup|Yup}] [-singlePrecision]"
1927            "\n\t\t:                  [-listExternalFiles] [-noCreateDoc]"
1928            "\n\t\t: Read OBJ file into XDE document."
1929            "\n\t\t:   -fileUnit       length unit of OBJ file content;"
1930            "\n\t\t:   -fileCoordSys   coordinate system defined by OBJ file; Yup when not specified."
1931            "\n\t\t:   -resultCoordSys result coordinate system; Zup when not specified."
1932            "\n\t\t:   -singlePrecision truncate vertex data to single precision during read; FALSE by default."
1933            "\n\t\t:   -listExternalFiles do not read mesh and only list external files."
1934            "\n\t\t:   -noCreateDoc    read into existing XDE document.",
1935                    __FILE__, ReadObj, g);
1936   theCommands.Add ("readobj",
1937                    "readobj shape file [-fileCoordSys {Zup|Yup}] [-fileUnit Unit]"
1938            "\n\t\t:                    [-resultCoordSys {Zup|Yup}] [-singlePrecision]"
1939            "\n\t\t:                    [-singleFace]"
1940            "\n\t\t: Same as ReadObj but reads OBJ file into a shape instead of a document."
1941            "\n\t\t:   -singleFace merge OBJ content into a single triangulation Face.",
1942            __FILE__, ReadObj, g);
1943   theCommands.Add ("WriteObj",
1944                    "WriteObj Doc file [-fileCoordSys {Zup|Yup}] [-fileUnit Unit]"
1945            "\n\t\t:                   [-systemCoordSys {Zup|Yup}]"
1946            "\n\t\t:                   [-comments Text] [-author Name]"
1947            "\n\t\t: Write XDE document into OBJ file."
1948            "\n\t\t:   -fileUnit       length unit of OBJ file content;"
1949            "\n\t\t:   -fileCoordSys   coordinate system defined by OBJ file; Yup when not specified."
1950            "\n\t\t:   -systemCoordSys system coordinate system; Zup when not specified.",
1951                    __FILE__, WriteObj, g);
1952   theCommands.Add ("writeobj",
1953                    "writeobj shape file",
1954                    __FILE__, WriteObj, g);
1955
1956   theCommands.Add ("meshfromstl",     "creates MeshVS_Mesh from STL file",            __FILE__, createmesh,      g );
1957   theCommands.Add ("mesh3delem",      "creates 3d element mesh to test",              __FILE__, create3d,        g );
1958   theCommands.Add ("meshshadcolor",   "change MeshVS_Mesh shading color",             __FILE__, meshcolor,       g );
1959   theCommands.Add ("meshlinkcolor",   "change MeshVS_Mesh line color",                __FILE__, linecolor,       g );
1960   theCommands.Add ("meshmat",         "change MeshVS_Mesh material and transparency", __FILE__, meshmat,         g );
1961   theCommands.Add ("meshshrcoef",     "change MeshVS_Mesh shrink coeff",              __FILE__, shrink,          g );
1962   theCommands.Add ("meshclosed",      "meshclosed meshname (0/1) \nChange MeshVS_Mesh drawing mode. 0 - not closed object, 1 - closed object", __FILE__, closed, g);
1963   theCommands.Add ("meshshow",        "display MeshVS_Mesh object",                   __FILE__, mdisplay,        g );
1964   theCommands.Add ("meshhide",        "erase MeshVS_Mesh object",                     __FILE__, merase,          g );
1965   theCommands.Add ("meshhidesel",     "hide selected entities",                       __FILE__, hidesel,         g );
1966   theCommands.Add ("meshshowsel",     "show only selected entities",                  __FILE__, showonly,        g );
1967   theCommands.Add ("meshshowall",     "show all entities",                            __FILE__, showall,         g );
1968   theCommands.Add ("meshcolors",      "display color presentation",                   __FILE__, meshcolors,      g );
1969   theCommands.Add ("meshvectors",     "display sample vectors",                       __FILE__, meshvectors,     g );
1970   theCommands.Add ("meshtext",        "display text labels",                          __FILE__, meshtext,        g );
1971   theCommands.Add ("meshdeform",      "display deformed mesh",                        __FILE__, meshdeform,      g );
1972   theCommands.Add ("mesh_edge_width", "set width of edges",                           __FILE__, mesh_edge_width, g );
1973   theCommands.Add ("meshinfo",        "displays the number of nodes and triangles",   __FILE__, meshinfo,        g );
1974 }
1975
1976 //==============================================================================
1977 // XSDRAWSTLVRML::Factory
1978 //==============================================================================
1979 void XSDRAWSTLVRML::Factory(Draw_Interpretor& theDI)
1980 {
1981   XSDRAWIGES::InitSelect();
1982   XSDRAWIGES::InitToBRep(theDI);
1983   XSDRAWIGES::InitFromBRep(theDI);
1984   XSDRAWSTEP::InitCommands(theDI);
1985   XSDRAWSTLVRML::InitCommands(theDI);
1986   XSDRAW::LoadDraw(theDI);
1987 #ifdef OCCT_DEBUG
1988   theDI << "Draw Plugin : All TKXSDRAW commands are loaded\n";
1989 #endif
1990 }
1991
1992 // Declare entry point PLUGINFACTORY
1993 DPLUGIN(XSDRAWSTLVRML)
1994