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