cf86dc0b4ffff29104f2dc15faaee7aa0003d9d5
[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   if (!writer.Write(aShape, argv[2], aVersion))
536   {
537     di << "Error: File " << argv[2] << " was not written\n";
538   }
539
540   return 0;
541 }
542
543 //=======================================================================
544 //function : loadvrml
545 //purpose  :
546 //=======================================================================
547
548 static Standard_Integer loadvrml
549 (Draw_Interpretor& di, Standard_Integer argc, const char** argv)
550 {
551   if (argc<3) di << "wrong number of parameters"    << "\n";
552   else {
553     TopoDS_Shape aShape ;
554     VrmlData_DataMapOfShapeAppearance aShapeAppMap;
555
556     //-----------------------------------------------------------
557     std::filebuf aFic;
558     std::istream aStream (&aFic);
559
560     if (aFic.open(argv[2], std::ios::in)) {
561
562       // Get path of the VRML file.
563       OSD_Path aPath(argv[2]);
564       TCollection_AsciiString aVrmlDir(".");
565       TCollection_AsciiString aDisk = aPath.Disk();
566       TCollection_AsciiString aTrek = aPath.Trek();
567       if (!aTrek.IsEmpty())
568       {
569         if (!aDisk.IsEmpty())
570           aVrmlDir = aDisk;
571         else
572           aVrmlDir.Clear();
573         aTrek.ChangeAll('|', '/');
574         aVrmlDir += aTrek;
575       }
576
577       VrmlData_Scene aScene;
578       Standard_Real anOCCUnit = UnitsMethods::GetCasCadeLengthUnit();
579       aScene.SetLinearScale(1000. / anOCCUnit);
580
581       aScene.SetVrmlDir (aVrmlDir);
582       aScene << aStream;
583       const char * aStr = 0L;
584       switch (aScene.Status()) {
585
586       case VrmlData_StatusOK:
587         {
588           aShape = aScene.GetShape(aShapeAppMap);
589           break;
590         }
591       case VrmlData_EmptyData:            aStr = "EmptyData"; break;
592       case VrmlData_UnrecoverableError:   aStr = "UnrecoverableError"; break;
593       case VrmlData_GeneralError:         aStr = "GeneralError"; break;
594       case VrmlData_EndOfFile:            aStr = "EndOfFile"; break;
595       case VrmlData_NotVrmlFile:          aStr = "NotVrmlFile"; break;
596       case VrmlData_CannotOpenFile:       aStr = "CannotOpenFile"; break;
597       case VrmlData_VrmlFormatError:      aStr = "VrmlFormatError"; break;
598       case VrmlData_NumericInputError:    aStr = "NumericInputError"; break;
599       case VrmlData_IrrelevantNumber:     aStr = "IrrelevantNumber"; break;
600       case VrmlData_BooleanInputError:    aStr = "BooleanInputError"; break;
601       case VrmlData_StringInputError:     aStr = "StringInputError"; break;
602       case VrmlData_NodeNameUnknown:      aStr = "NodeNameUnknown"; break;
603       case VrmlData_NonPositiveSize:      aStr = "NonPositiveSize"; break;
604       case VrmlData_ReadUnknownNode:      aStr = "ReadUnknownNode"; break;
605       case VrmlData_NonSupportedFeature:  aStr = "NonSupportedFeature"; break;
606       case VrmlData_OutputStreamUndefined:aStr = "OutputStreamUndefined"; break;
607       case VrmlData_NotImplemented:       aStr = "NotImplemented"; break;
608       default:
609         break;
610       }
611       if (aStr) {
612         di << " ++ VRML Error: " << aStr << " in line "
613           << aScene.GetLineError() << "\n";
614       }
615       else {
616         DBRep::Set(argv[1],aShape);
617       }
618     }
619     else {
620       di << "cannot open file\n";
621     }
622
623
624     //-----------------------------------------------------------
625   }
626   return 0;
627 }
628
629 //-----------------------------------------------------------------------------
630 static Standard_Integer createmesh
631 (Draw_Interpretor& di, Standard_Integer argc, const char** argv )
632 {
633   if (argc<3)
634   {
635     di << "Wrong number of parameters\n";
636     di << "Use: " << argv[0] << " <mesh name> <stl file>\n";
637     return 0;
638   }
639
640   Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
641   if (aContext.IsNull())
642   {
643     di << "No active view. Please call 'vinit' first\n";
644     return 0;
645   }
646
647   // Progress indicator
648   OSD_Path aFile( argv[2] );
649   Handle(Draw_ProgressIndicator) aProgress = new Draw_ProgressIndicator (di, 1);
650   Handle(Poly_Triangulation) aSTLMesh = RWStl::ReadFile (aFile, aProgress);
651
652   di << "Reading OK...\n";
653   Handle( XSDRAWSTLVRML_DataSource ) aDS = new XSDRAWSTLVRML_DataSource( aSTLMesh );
654   di << "Data source is created successful\n";
655   Handle( MeshVS_Mesh ) aMesh = new MeshVS_Mesh();
656   di << "MeshVS_Mesh is created successful\n";
657
658   aMesh->SetDataSource( aDS );
659   aMesh->AddBuilder( new MeshVS_MeshPrsBuilder( aMesh.operator->() ), Standard_True );
660
661   aMesh->GetDrawer()->SetColor( MeshVS_DA_EdgeColor, Quantity_NOC_YELLOW );
662
663   // Hide all nodes by default
664   Handle(TColStd_HPackedMapOfInteger) aNodes = new TColStd_HPackedMapOfInteger();
665   Standard_Integer aLen = aSTLMesh->Nodes().Length();
666   for ( Standard_Integer anIndex = 1; anIndex <= aLen; anIndex++ )
667     aNodes->ChangeMap().Add( anIndex );
668   aMesh->SetHiddenNodes( aNodes );
669   aMesh->SetSelectableNodes ( aNodes );
670
671   VDisplayAISObject(argv[1], aMesh);
672   aContext->Deactivate( aMesh );
673
674   Draw::Set( argv[1], new XSDRAWSTLVRML_DrawableMesh( aMesh ) );
675   Handle( V3d_View ) aView = ViewerTest::CurrentView();
676   if ( !aView.IsNull() )
677     aView->FitAll();
678
679   return 0;
680 }
681 //-----------------------------------------------------------------------------
682
683 static Standard_Integer create3d
684 (Draw_Interpretor& di, Standard_Integer argc, const char** argv )
685 {
686   if (argc<2)
687   {
688     di << "Wrong number of parameters\n";
689     di << "Use: " << argv[0] << " <mesh name>\n";
690     return 0;
691   }
692
693   Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
694   if (aContext.IsNull())
695   {
696     di << "No active view. Please call 'vinit' first\n";
697     return 0;
698   }
699
700   Handle( XSDRAWSTLVRML_DataSource3D ) aDS = new XSDRAWSTLVRML_DataSource3D();
701   di << "Data source is created successful\n";
702   Handle( MeshVS_Mesh ) aMesh = new MeshVS_Mesh();
703   di << "MeshVS_Mesh is created successful\n";
704
705   aMesh->SetDataSource( aDS );
706   aMesh->AddBuilder( new MeshVS_MeshPrsBuilder( aMesh.operator->() ), Standard_True );
707
708   aMesh->GetDrawer()->SetColor( MeshVS_DA_EdgeColor, Quantity_NOC_YELLOW );
709
710   // Hide all nodes by default
711   Handle(TColStd_HPackedMapOfInteger) aNodes = new TColStd_HPackedMapOfInteger();
712   Standard_Integer aLen = aDS->GetAllNodes().Extent();
713   for ( Standard_Integer anIndex = 1; anIndex <= aLen; anIndex++ )
714     aNodes->ChangeMap().Add( anIndex );
715   aMesh->SetHiddenNodes( aNodes );
716   aMesh->SetSelectableNodes ( aNodes );
717
718   VDisplayAISObject(argv[1], aMesh);
719   aContext->Deactivate( aMesh );
720
721   Draw::Set( argv[1], new XSDRAWSTLVRML_DrawableMesh( aMesh ) );
722   Handle( V3d_View ) aView = ViewerTest::CurrentView();
723   if ( !aView.IsNull() )
724     aView->FitAll();
725
726   return 0;
727 }
728
729 Handle( MeshVS_Mesh ) getMesh( const char* theName, Draw_Interpretor& di)
730 {
731   Handle( XSDRAWSTLVRML_DrawableMesh ) aDrawMesh =
732     Handle( XSDRAWSTLVRML_DrawableMesh )::DownCast( Draw::Get( theName ) );
733
734   if( aDrawMesh.IsNull() )
735   {
736     di << "There is no such object\n";
737     return NULL;
738   }
739   else
740   {
741     Handle( MeshVS_Mesh ) aMesh = aDrawMesh->GetMesh();
742     if( aMesh.IsNull() )
743     {
744       di << "There is invalid mesh\n";
745       return NULL;
746     }
747     else
748       return aMesh;
749   }
750 }
751
752 //-----------------------------------------------------------------------------
753 static Standard_Integer setcolor
754 (Draw_Interpretor& di, Standard_Integer argc, const char** argv, Standard_Integer theParam )
755 {
756   if (argc<5)
757     di << "Wrong number of parameters\n";
758   else
759   {
760     Handle( MeshVS_Mesh ) aMesh = getMesh( argv[1], di );
761     if( !aMesh.IsNull() )
762     {
763       Standard_Real aRed = Draw::Atof (argv[2]);
764       Standard_Real aGreen = Draw::Atof (argv[3]);
765       Standard_Real aBlue = Draw::Atof (argv[4]);
766       aMesh->GetDrawer()->SetColor( (MeshVS_DrawerAttribute)theParam,
767                                     Quantity_Color( aRed, aGreen, aBlue, Quantity_TOC_RGB ) );
768
769       Handle( AIS_InteractiveContext ) aContext = ViewerTest::GetAISContext();
770
771       if( aContext.IsNull() )
772         di << "The context is null\n";
773       else
774         aContext->Redisplay (aMesh, Standard_True);
775     }
776   }
777   return 0;
778 }
779 //-----------------------------------------------------------------------------
780 static Standard_Integer meshcolor
781 (Draw_Interpretor& theInterp, Standard_Integer argc, const char** argv )
782 {
783   return setcolor( theInterp, argc, argv, MeshVS_DA_InteriorColor );
784 }
785 //-----------------------------------------------------------------------------
786 static Standard_Integer linecolor
787 (Draw_Interpretor& theInterp, Standard_Integer argc, const char** argv )
788 {
789   return setcolor( theInterp, argc, argv, MeshVS_DA_EdgeColor );
790 }
791 //-----------------------------------------------------------------------------
792 static Standard_Integer meshmat
793 (Draw_Interpretor& di, Standard_Integer argc, const char** argv )
794 {
795   if (argc<3)
796     di << "Wrong number of parameters\n";
797   else
798   {
799     Handle( MeshVS_Mesh ) aMesh = getMesh( argv[1], di );
800     if( !aMesh.IsNull() )
801     {
802       Standard_Integer aMaterial = Draw::Atoi (argv[2]);
803
804       Graphic3d_MaterialAspect aMatAsp =
805         (Graphic3d_MaterialAspect)(Graphic3d_NameOfMaterial)aMaterial;
806
807       if (argc == 4)
808       {
809         Standard_Real aTransparency = Draw::Atof(argv[3]);
810         aMatAsp.SetTransparency (Standard_ShortReal (aTransparency));
811       }
812       aMesh->GetDrawer()->SetMaterial( MeshVS_DA_FrontMaterial, aMatAsp );
813       aMesh->GetDrawer()->SetMaterial( MeshVS_DA_BackMaterial, aMatAsp );
814
815       Handle( AIS_InteractiveContext ) aContext = ViewerTest::GetAISContext();
816
817       if( aContext.IsNull() )
818         di << "The context is null\n";
819       else
820         aContext->Redisplay (aMesh, Standard_True);
821     }
822   }
823   return 0;
824 }
825 //-----------------------------------------------------------------------------
826 static Standard_Integer shrink
827 (Draw_Interpretor& di, Standard_Integer argc, const char** argv )
828 {
829   if (argc<3)
830     di << "Wrong number of parameters\n";
831   else
832   {
833     Handle( MeshVS_Mesh ) aMesh = getMesh( argv[1], di );
834     if( !aMesh.IsNull() )
835     {
836       Standard_Real aShrinkCoeff = Draw::Atof (argv[2]);
837       aMesh->GetDrawer()->SetDouble( MeshVS_DA_ShrinkCoeff, aShrinkCoeff );
838
839       Handle( AIS_InteractiveContext ) aContext = ViewerTest::GetAISContext();
840
841       if( aContext.IsNull() )
842         di << "The context is null\n";
843       else
844         aContext->Redisplay (aMesh, Standard_True);
845     }
846   }
847   return 0;
848 }
849
850 //-----------------------------------------------------------------------------
851 static Standard_Integer closed (Draw_Interpretor& theDI, Standard_Integer theArgc, const char** theArgv)
852 {
853   if (theArgc < 3)
854   {
855     theDI << "Wrong number of parameters.\n";
856   }
857   else
858   {
859     Handle(MeshVS_Mesh) aMesh = getMesh (theArgv[1], theDI);
860     if (!aMesh.IsNull())
861     {
862       Standard_Boolean aFlag = Draw::Atoi (theArgv[2]) != 0;
863       aMesh->GetDrawer()->SetBoolean (MeshVS_DA_SupressBackFaces, aFlag);
864
865       Handle( AIS_InteractiveContext ) aContext = ViewerTest::GetAISContext();
866       if (aContext.IsNull())
867       {
868         theDI << "The context is null\n";
869       }
870       else
871       {
872         aContext->Redisplay (aMesh, Standard_True);
873       }
874     }
875   }
876   return 0;
877 }
878
879 //-----------------------------------------------------------------------------
880
881 static Standard_Integer mdisplay
882 (Draw_Interpretor& di, Standard_Integer argc, const char** argv )
883 {
884   if (argc<2)
885     di << "Wrong number of parameters\n";
886   else
887   {
888     Handle( MeshVS_Mesh ) aMesh = getMesh( argv[1], di );
889     if( !aMesh.IsNull() )
890     {
891       Handle( AIS_InteractiveContext ) aContext = ViewerTest::GetAISContext();
892
893       if( aContext.IsNull() )
894         di << "The context is null\n";
895       else
896       {
897         aContext->Display (aMesh, Standard_True);
898       }
899     }
900   }
901   return 0;
902 }
903 //-----------------------------------------------------------------------------
904 static Standard_Integer merase
905 (Draw_Interpretor& di, Standard_Integer argc, const char** argv )
906 {
907   if (argc<2)
908     di << "Wrong number of parameters\n";
909   else
910   {
911     Handle( MeshVS_Mesh ) aMesh = getMesh( argv[1], di );
912     if( !aMesh.IsNull() )
913     {
914       Handle( AIS_InteractiveContext ) aContext = ViewerTest::GetAISContext();
915
916       if( aContext.IsNull() )
917         di << "The context is null\n";
918       else
919       {
920         aContext->Erase (aMesh, Standard_True);
921       }
922     }
923     else
924       di << "Mesh is null\n";
925   }
926   return 0;
927 }
928 //-----------------------------------------------------------------------------
929 static Standard_Integer hidesel
930 (Draw_Interpretor& di, Standard_Integer argc, const char** argv )
931 {
932   if (argc<2)
933   {
934     di << "Wrong number of parameters\n";
935     di << "Use: " << argv[0] << " <mesh name>\n";
936     return 0;
937   }
938
939   Handle( AIS_InteractiveContext ) aContext = ViewerTest::GetAISContext();
940   Handle( MeshVS_Mesh ) aMesh = getMesh( argv[1], di );
941   if( aMesh.IsNull() )
942   {
943     di << "The mesh is invalid\n";
944     return 0;
945   }
946
947   if( aContext.IsNull() )
948     di << "The context is null\n";
949   else
950   {
951     Handle(TColStd_HPackedMapOfInteger) aHiddenNodes = aMesh->GetHiddenNodes();
952     if (aHiddenNodes.IsNull())
953     {
954       aHiddenNodes = new TColStd_HPackedMapOfInteger();
955     }
956     Handle(TColStd_HPackedMapOfInteger) aHiddenElements = aMesh->GetHiddenElems();
957     if (aHiddenElements.IsNull())
958     {
959       aHiddenElements = new TColStd_HPackedMapOfInteger();
960     }
961     for( aContext->InitSelected(); aContext->MoreSelected(); aContext->NextSelected() )
962     {
963       Handle( MeshVS_MeshEntityOwner ) anOwner =
964         Handle( MeshVS_MeshEntityOwner )::DownCast( aContext->SelectedOwner() );
965       if( !anOwner.IsNull() )
966       {
967         if( anOwner->Type()==MeshVS_ET_Node )
968         {
969           aHiddenNodes->ChangeMap().Add( anOwner->ID() );
970         }
971         else
972         {
973           aHiddenElements->ChangeMap().Add( anOwner->ID() );
974         }
975       }
976     }
977     aContext->ClearSelected (Standard_False);
978     aMesh->SetHiddenNodes( aHiddenNodes );
979     aMesh->SetHiddenElems( aHiddenElements );
980     aContext->Redisplay (aMesh, Standard_True);
981   }
982
983   return 0;
984 }
985 //-----------------------------------------------------------------------------
986 static Standard_Integer showonly
987 (Draw_Interpretor& di, Standard_Integer argc, const char** argv )
988 {
989   if (argc<2)
990   {
991     di << "Wrong number of parameters\n";
992     di << "Use: " << argv[0] << " <mesh name>\n";
993     return 0;
994   }
995
996
997   Handle( AIS_InteractiveContext ) aContext = ViewerTest::GetAISContext();
998   Handle( MeshVS_Mesh ) aMesh = getMesh( argv[1], di );
999   if( aMesh.IsNull() )
1000   {
1001     di << "The mesh is invalid\n";
1002     return 0;
1003   }
1004
1005   if( aContext.IsNull() )
1006     di << "The context is null\n";
1007   else
1008   {
1009     Handle(TColStd_HPackedMapOfInteger) aHiddenNodes =
1010       new TColStd_HPackedMapOfInteger(aMesh->GetDataSource()->GetAllNodes());
1011     Handle(TColStd_HPackedMapOfInteger) aHiddenElements =
1012       new TColStd_HPackedMapOfInteger(aMesh->GetDataSource()->GetAllElements());
1013     for( aContext->InitSelected(); aContext->MoreSelected(); aContext->NextSelected() )
1014     {
1015       Handle( MeshVS_MeshEntityOwner ) anOwner =
1016         Handle( MeshVS_MeshEntityOwner )::DownCast( aContext->SelectedOwner() );
1017       if( !anOwner.IsNull() )
1018       {
1019         if( anOwner->Type() == MeshVS_ET_Node )
1020         {
1021           aHiddenNodes->ChangeMap().Remove( anOwner->ID() );
1022         }
1023         else
1024         {
1025           aHiddenElements->ChangeMap().Remove( anOwner->ID() );
1026         }
1027       }
1028     }
1029     aMesh->SetHiddenNodes( aHiddenNodes );
1030     aMesh->SetHiddenElems( aHiddenElements );
1031     aContext->Redisplay (aMesh, Standard_True);
1032   }
1033
1034   return 0;
1035 }
1036 //-----------------------------------------------------------------------------
1037 static Standard_Integer showall
1038 (Draw_Interpretor& di, Standard_Integer argc, const char** argv )
1039 {
1040   if (argc<2)
1041   {
1042     di << "Wrong number of parameters\n";
1043     di << "Use: " << argv[0] << " <mesh name>\n";
1044     return 0;
1045   }
1046
1047   Handle( AIS_InteractiveContext ) aContext = ViewerTest::GetAISContext();
1048   Handle( MeshVS_Mesh ) aMesh = getMesh( argv[1], di );
1049   if( aMesh.IsNull() )
1050   {
1051     di << "The mesh is invalid\n";
1052     return 0;
1053   }
1054
1055   if( aContext.IsNull() )
1056     di << "The context is null\n";
1057   else
1058   {
1059     aMesh->SetHiddenNodes( new TColStd_HPackedMapOfInteger() );
1060     aMesh->SetHiddenElems( new TColStd_HPackedMapOfInteger() );
1061     aContext->Redisplay (aMesh, Standard_True);
1062   }
1063
1064   return 0;
1065 }
1066
1067 //-----------------------------------------------------------------------------
1068 static Standard_Integer meshcolors( Draw_Interpretor& di,
1069                                     Standard_Integer argc,
1070                                     const char** argv )
1071 {
1072   try
1073   {
1074     OCC_CATCH_SIGNALS
1075       if ( argc < 4 )
1076       {
1077         di << "Wrong number of parameters\n";
1078         di << "Use : meshcolors <mesh name> <mode> <isreflect>\n";
1079         di << "mode : {elem1|elem2|nodal|nodaltex|none}\n";
1080         di << "       elem1 - different color for each element\n";
1081         di << "       elem2 - one color for one side\n";
1082         di << "       nodal - different color for each node\n";
1083         di << "       nodaltex - different color for each node with texture interpolation\n";
1084         di << "       none  - clear\n";
1085         di << "isreflect : {0|1} \n";
1086
1087         return 0;
1088       }
1089
1090       Handle( MeshVS_Mesh ) aMesh = getMesh( argv[ 1 ], di );
1091
1092       if ( aMesh.IsNull() )
1093       {
1094         di << "Mesh not found\n";
1095         return 0;
1096       }
1097       Handle(AIS_InteractiveContext) anIC = ViewerTest::GetAISContext();
1098       if ( anIC.IsNull() )
1099       {
1100         di << "The context is null\n";
1101         return 0;
1102       }
1103       if( !aMesh.IsNull() )
1104       {
1105         TCollection_AsciiString aMode = TCollection_AsciiString (argv[2]);
1106         Quantity_Color aColor1(Quantity_NOC_BLUE1);
1107         Quantity_Color aColor2(Quantity_NOC_RED1);
1108         if( aMode.IsEqual("elem1") || aMode.IsEqual("elem2") || aMode.IsEqual("nodal") || aMode.IsEqual("nodaltex") || aMode.IsEqual("none") )
1109         {
1110           Handle(MeshVS_PrsBuilder) aTempBuilder;
1111           Standard_Integer aReflection = Draw::Atoi(argv[3]);
1112
1113           for (Standard_Integer aCount = 0 ; aCount < aMesh->GetBuildersCount(); aCount++ ){
1114             aTempBuilder = aMesh->FindBuilder("MeshVS_ElementalColorPrsBuilder");
1115             if( !aTempBuilder.IsNull())
1116               aMesh->RemoveBuilderById(aTempBuilder->GetId());
1117
1118             aTempBuilder = aMesh->FindBuilder("MeshVS_NodalColorPrsBuilder");
1119             if( !aTempBuilder.IsNull())
1120               aMesh->RemoveBuilderById(aTempBuilder->GetId());
1121           }
1122
1123           if( aMode.IsEqual("elem1") || aMode.IsEqual("elem2") )
1124           {
1125             Handle(MeshVS_ElementalColorPrsBuilder) aBuilder = new MeshVS_ElementalColorPrsBuilder(
1126                 aMesh, MeshVS_DMF_ElementalColorDataPrs | MeshVS_DMF_OCCMask );
1127               // Color
1128             const TColStd_PackedMapOfInteger& anAllElements = aMesh->GetDataSource()->GetAllElements();
1129             TColStd_MapIteratorOfPackedMapOfInteger anIter( anAllElements );
1130
1131             if( aMode.IsEqual("elem1") )
1132               for ( ; anIter.More(); anIter.Next() )
1133               {
1134                 Quantity_Color aColor( (Quantity_NameOfColor)( anIter.Key() % Quantity_NOC_WHITE ) );
1135                 aBuilder->SetColor1( anIter.Key(), aColor );
1136               }
1137             else
1138               for ( ; anIter.More(); anIter.Next() )
1139                 aBuilder->SetColor2( anIter.Key(), aColor1, aColor2 );
1140
1141             aMesh->AddBuilder( aBuilder, Standard_True );
1142           }
1143
1144
1145           if( aMode.IsEqual("nodal") )
1146           {
1147             Handle(MeshVS_NodalColorPrsBuilder) aBuilder = new MeshVS_NodalColorPrsBuilder(
1148                 aMesh, MeshVS_DMF_NodalColorDataPrs | MeshVS_DMF_OCCMask );
1149             aMesh->AddBuilder( aBuilder, Standard_True );
1150
1151             // Color
1152             const TColStd_PackedMapOfInteger& anAllNodes =
1153               aMesh->GetDataSource()->GetAllNodes();
1154             TColStd_MapIteratorOfPackedMapOfInteger anIter( anAllNodes );
1155             for ( ; anIter.More(); anIter.Next() )
1156             {
1157               Quantity_Color aColor( (Quantity_NameOfColor)(
1158                 anIter.Key() % Quantity_NOC_WHITE ) );
1159               aBuilder->SetColor( anIter.Key(), aColor );
1160             }
1161             aMesh->AddBuilder( aBuilder, Standard_True );
1162           }
1163
1164           if(aMode.IsEqual("nodaltex"))
1165           {
1166             // assign nodal builder to the mesh
1167             Handle(MeshVS_NodalColorPrsBuilder) aBuilder = new MeshVS_NodalColorPrsBuilder(
1168                    aMesh, MeshVS_DMF_NodalColorDataPrs | MeshVS_DMF_OCCMask);
1169             aMesh->AddBuilder(aBuilder, Standard_True);
1170             aBuilder->UseTexture(Standard_True);
1171
1172             // prepare color map for texture
1173             Aspect_SequenceOfColor aColorMap;
1174             aColorMap.Append((Quantity_NameOfColor) Quantity_NOC_RED);
1175             aColorMap.Append((Quantity_NameOfColor) Quantity_NOC_YELLOW);
1176             aColorMap.Append((Quantity_NameOfColor) Quantity_NOC_BLUE1);
1177
1178             // prepare scale map for mesh - it will be assigned to mesh as texture coordinates
1179             // make mesh color interpolated from minimum X coord to maximum X coord
1180             Handle(MeshVS_DataSource) aDataSource = aMesh->GetDataSource();
1181             Standard_Real aMinX, aMinY, aMinZ, aMaxX, aMaxY, aMaxZ;
1182
1183             // get bounding box for calculations
1184             aDataSource->GetBoundingBox().Get(aMinX, aMinY, aMinZ, aMaxX, aMaxY, aMaxZ);
1185             Standard_Real aDelta = aMaxX - aMinX;
1186
1187             // assign color scale map values (0..1) to nodes
1188             TColStd_DataMapOfIntegerReal aScaleMap;
1189             TColStd_Array1OfReal aCoords(1, 3);
1190             Standard_Integer     aNbNodes;
1191             MeshVS_EntityType    aType;
1192
1193             // iterate nodes
1194             const TColStd_PackedMapOfInteger& anAllNodes =
1195                   aMesh->GetDataSource()->GetAllNodes();
1196             TColStd_MapIteratorOfPackedMapOfInteger anIter(anAllNodes);
1197             for (; anIter.More(); anIter.Next())
1198             {
1199               //get node coordinates to aCoord variable
1200               aDataSource->GetGeom(anIter.Key(), Standard_False, aCoords, aNbNodes, aType);
1201
1202               Standard_Real aScaleValue;
1203               try {
1204                 OCC_CATCH_SIGNALS
1205                 aScaleValue = (aCoords.Value(1) - (Standard_Real) aMinX) / aDelta;
1206               } catch(Standard_Failure const&) {
1207                 aScaleValue = 0;
1208               }
1209
1210               aScaleMap.Bind(anIter.Key(), aScaleValue);
1211             }
1212
1213             //set color map for builder and a color for invalid scale value
1214             aBuilder->SetColorMap(aColorMap);
1215             aBuilder->SetInvalidColor(Quantity_NOC_BLACK);
1216             aBuilder->SetTextureCoords(aScaleMap);
1217             aMesh->AddBuilder(aBuilder, Standard_True);
1218           }
1219
1220           aMesh->GetDrawer()->SetBoolean (MeshVS_DA_ColorReflection, aReflection != 0);
1221
1222           anIC->Redisplay (aMesh, Standard_True);
1223         }
1224         else
1225         {
1226           di << "Wrong mode name\n";
1227           return 0;
1228         }
1229       }
1230   }
1231   catch ( Standard_Failure const& )
1232   {
1233     di << "Error\n";
1234   }
1235
1236   return 0;
1237 }
1238 //-----------------------------------------------------------------------------
1239 static Standard_Integer meshvectors( Draw_Interpretor& di,
1240                                      Standard_Integer argc,
1241                                      const char** argv )
1242 {
1243   if ( argc < 3 )
1244   {
1245     di << "Wrong number of parameters\n";
1246     di << "Use : meshvectors <mesh name> < -mode {elem|nodal|none} > [-maxlen len] [-color name] [-arrowpart ratio] [-issimple {1|0}]\n";
1247     di << "Supported mode values:\n";
1248     di << "       elem  - vector per element\n";
1249     di << "       nodal - vector per node\n";
1250     di << "       none  - clear\n";
1251
1252     return 0;
1253   }
1254
1255   Handle( MeshVS_Mesh ) aMesh = getMesh( argv[ 1 ], di );
1256
1257   if ( aMesh.IsNull() )
1258   {
1259     di << "Mesh not found\n";
1260     return 0;
1261   }
1262   Handle(AIS_InteractiveContext) anIC = ViewerTest::GetAISContext();
1263   if ( anIC.IsNull() )
1264   {
1265     di << "The context is null\n";
1266     return 0;
1267   }
1268
1269   TCollection_AsciiString aParam;
1270   TCollection_AsciiString aMode("none");
1271   Standard_Real           aMaxlen(1.0);
1272   Quantity_Color          aColor(Quantity_NOC_ORANGE);
1273   Standard_Real           anArrowPart(0.1);
1274   Standard_Boolean        isSimplePrs(Standard_False);
1275
1276   for (Standard_Integer anIdx = 2; anIdx < argc; anIdx++)
1277   {
1278     if (!aParam.IsEmpty())
1279     {
1280       if (aParam == "-mode")
1281       {
1282         aMode       = argv[anIdx];
1283       }
1284       else if (aParam == "-maxlen")
1285       {
1286         aMaxlen     = Draw::Atof(argv[anIdx]);
1287       }
1288       else if (aParam == "-color")
1289       {
1290         aColor      = ViewerTest::GetColorFromName(argv[anIdx]);
1291       }
1292       else if (aParam == "-arrowpart")
1293       {
1294         anArrowPart = Draw::Atof(argv[anIdx]);
1295       }
1296       else if (aParam == "-issimple")
1297       {
1298         isSimplePrs = Draw::Atoi(argv[anIdx]) != 0;
1299       }
1300       aParam.Clear();
1301     }
1302     else if (argv[anIdx][0] == '-')
1303     {
1304       aParam = argv[anIdx];
1305     }
1306   }
1307
1308   if( !aMode.IsEqual("elem") && !aMode.IsEqual("nodal") && !aMode.IsEqual("none") )
1309   {
1310     di << "Wrong mode name\n";
1311     return 0;
1312   }
1313
1314   Handle(MeshVS_PrsBuilder) aTempBuilder;
1315
1316   aTempBuilder = aMesh->FindBuilder("MeshVS_VectorPrsBuilder");
1317   if( !aTempBuilder.IsNull())
1318     aMesh->RemoveBuilderById(aTempBuilder->GetId());
1319
1320   if( !aMode.IsEqual("none") )
1321   {
1322     Handle(MeshVS_VectorPrsBuilder) aBuilder = new MeshVS_VectorPrsBuilder( aMesh.operator->(), 
1323                                                                             aMaxlen,
1324                                                                             aColor,
1325                                                                             MeshVS_DMF_VectorDataPrs,
1326                                                                             0,
1327                                                                             -1,
1328                                                                             MeshVS_BP_Vector,
1329                                                                             isSimplePrs);
1330
1331     Standard_Boolean anIsElement = aMode.IsEqual("elem");
1332     const TColStd_PackedMapOfInteger& anAllIDs = anIsElement ? aMesh->GetDataSource()->GetAllElements() :
1333                                                                aMesh->GetDataSource()->GetAllNodes();
1334
1335     Standard_Integer aNbNodes;
1336     MeshVS_EntityType aEntType;
1337
1338     TColStd_Array1OfReal aCoords(1, 3);
1339     aCoords.Init (0.);
1340     TColStd_MapIteratorOfPackedMapOfInteger anIter( anAllIDs );
1341     for ( ; anIter.More(); anIter.Next() )
1342     {
1343       Standard_Boolean IsValidData = Standard_False; 
1344       if (anIsElement) {
1345         aMesh->GetDataSource()->GetGeomType(anIter.Key(), anIsElement, aEntType);
1346         if (aEntType == MeshVS_ET_Face)
1347           IsValidData = aMesh->GetDataSource()->GetNormal(anIter.Key(), 3, aCoords.ChangeValue(1), aCoords.ChangeValue(2), aCoords.ChangeValue(3));
1348       } else
1349         IsValidData = aMesh->GetDataSource()->GetGeom(anIter.Key(), Standard_False, aCoords, aNbNodes, aEntType);
1350
1351       gp_Vec aNorm;
1352       if(IsValidData)
1353       { 
1354         aNorm = gp_Vec(aCoords.Value(1), aCoords.Value(2), aCoords.Value(3));
1355         if(aNorm.Magnitude() < gp::Resolution())
1356         {
1357           aNorm = gp_Vec(0,0,1); //method GetGeom(...) returns coordinates of nodes
1358         }
1359       }
1360       else
1361       {
1362         aNorm = gp_Vec(0,0,1);
1363       }
1364       aBuilder->SetVector(anIsElement, anIter.Key(), aNorm.Normalized());
1365     }
1366
1367     aMesh->AddBuilder( aBuilder, Standard_False );
1368     aMesh->GetDrawer()->SetDouble ( MeshVS_DA_VectorArrowPart, anArrowPart );
1369   }
1370
1371   anIC->Redisplay (aMesh, Standard_True);
1372
1373   return 0;
1374 }
1375 //-----------------------------------------------------------------------------
1376
1377 static Standard_Integer meshtext( Draw_Interpretor& di,
1378                                   Standard_Integer argc,
1379                                   const char** argv )
1380 {
1381   if ( argc < 2 )
1382   {
1383     di << "Wrong number of parameters\n";
1384     di << "Use : meshtext <mesh name>\n";
1385     return 0;
1386   }
1387
1388   Handle( MeshVS_Mesh ) aMesh = getMesh( argv[ 1 ], di );
1389
1390   if ( aMesh.IsNull() )
1391   {
1392     di << "Mesh not found\n";
1393     return 0;
1394   }
1395
1396   Handle(AIS_InteractiveContext) anIC = ViewerTest::GetAISContext();
1397   if ( anIC.IsNull() )
1398   {
1399     di << "The context is null\n";
1400     return 0;
1401   }
1402
1403   // Prepare triangle labels
1404   MeshVS_DataMapOfIntegerAsciiString aLabels;
1405   Standard_Integer aLen = aMesh->GetDataSource()->GetAllElements().Extent();
1406   for ( Standard_Integer anIndex = 1; anIndex <= aLen; anIndex++ ){
1407     aLabels.Bind( anIndex, TCollection_AsciiString( anIndex ) );
1408   }
1409
1410   Handle(MeshVS_TextPrsBuilder) aTextBuilder = new MeshVS_TextPrsBuilder( aMesh.operator->(), 20., Quantity_NOC_YELLOW );
1411   aTextBuilder->SetTexts( Standard_True, aLabels );
1412   aMesh->AddBuilder( aTextBuilder );
1413
1414   return 0;
1415 }
1416
1417 static Standard_Integer meshdeform( Draw_Interpretor& di,
1418                                     Standard_Integer argc,
1419                                     const char** argv )
1420 {
1421   if ( argc < 3 )
1422   {
1423     di << "Wrong number of parameters\n";
1424     di << "Use : meshdeform <mesh name> < -mode {on|off} > [-scale scalefactor]\n";
1425     return 0;
1426   }
1427
1428   Handle( MeshVS_Mesh ) aMesh = getMesh( argv[ 1 ], di );
1429
1430   if ( aMesh.IsNull() )
1431   {
1432     di << "Mesh not found\n";
1433     return 0;
1434   }
1435   Handle(AIS_InteractiveContext) anIC = ViewerTest::GetAISContext();
1436   if ( anIC.IsNull() )
1437   {
1438     di << "The context is null\n";
1439     return 0;
1440   }
1441
1442   TCollection_AsciiString aParam;
1443   TCollection_AsciiString aMode("off");
1444   Standard_Real           aScale(1.0);
1445
1446   for (Standard_Integer anIdx = 2; anIdx < argc; anIdx++)
1447   {
1448     if (!aParam.IsEmpty())
1449     {
1450       if (aParam == "-mode")
1451       {
1452         aMode = argv[anIdx];
1453       }
1454       else if (aParam == "-scale")
1455       {
1456         aScale = Draw::Atof(argv[anIdx]);
1457       }
1458       aParam.Clear();
1459     }
1460     else if (argv[anIdx][0] == '-')
1461     {
1462       aParam = argv[anIdx];
1463     }
1464   }
1465
1466   if(!aMode.IsEqual("on") && !aMode.IsEqual("off"))
1467   {
1468     di << "Wrong mode name\n";
1469     return 0;
1470   }
1471
1472   Handle ( MeshVS_DeformedDataSource ) aDefDS =
1473     new MeshVS_DeformedDataSource( aMesh->GetDataSource() , aScale );
1474
1475   const TColStd_PackedMapOfInteger& anAllIDs = aMesh->GetDataSource()->GetAllNodes();
1476
1477   Standard_Integer aNbNodes;
1478   MeshVS_EntityType aEntType;
1479
1480   TColStd_MapIteratorOfPackedMapOfInteger anIter( anAllIDs );
1481   for ( ; anIter.More(); anIter.Next() )
1482   {
1483     TColStd_Array1OfReal aCoords(1, 3);
1484     aMesh->GetDataSource()->GetGeom(anIter.Key(), Standard_False, aCoords, aNbNodes, aEntType);
1485
1486     gp_Vec aNorm = gp_Vec(aCoords.Value(1), aCoords.Value(2), aCoords.Value(3));
1487     if( !aNorm.Magnitude() )
1488       aNorm = gp_Vec(0,0,1);
1489     aDefDS->SetVector(anIter.Key(), aNorm.Normalized());
1490   }
1491
1492   aMesh->SetDataSource(aDefDS);
1493
1494   anIC->Redisplay (aMesh, Standard_False);
1495
1496   Handle( V3d_View ) aView = ViewerTest::CurrentView();
1497   if ( !aView.IsNull() )
1498     aView->FitAll();
1499
1500   return 0;
1501 }
1502
1503 static Standard_Integer mesh_edge_width( Draw_Interpretor& di,
1504                                         Standard_Integer argc,
1505                                         const char** argv )
1506 {
1507   try
1508   {
1509     OCC_CATCH_SIGNALS
1510       if ( argc < 3 )
1511       {
1512         di << "Wrong number of parameters\n";
1513         di << "Use : mesh_edge_width <mesh name> <width>\n";
1514         return 0;
1515       }
1516
1517       Handle(MeshVS_Mesh) aMesh = getMesh( argv[ 1 ], di );
1518       if ( aMesh.IsNull() )
1519       {
1520         di << "Mesh not found\n";
1521         return 0;
1522       }
1523
1524       const char* aWidthStr = argv[ 2 ];
1525       if ( aWidthStr == 0 || Draw::Atof( aWidthStr ) <= 0 )
1526       {
1527         di << "Width must be real value more than zero\n";
1528         return 0;
1529       }
1530
1531       double aWidth = Draw::Atof( aWidthStr );
1532
1533       Handle(AIS_InteractiveContext) anIC = ViewerTest::GetAISContext();
1534       if ( anIC.IsNull() )
1535       {
1536         di << "The context is null\n";
1537         return 0;
1538       }
1539
1540       Handle(MeshVS_Drawer) aDrawer = aMesh->GetDrawer();
1541       if ( aDrawer.IsNull() )
1542       {
1543         di << "The drawer is null\n";
1544         return 0;
1545       }
1546
1547       aDrawer->SetDouble( MeshVS_DA_EdgeWidth, aWidth );
1548       anIC->Redisplay (aMesh, Standard_True);
1549   }
1550   catch ( Standard_Failure const& )
1551   {
1552     di << "Error\n";
1553   }
1554
1555   return 0;
1556 }
1557
1558 //-----------------------------------------------------------------------------
1559
1560 static Standard_Integer meshinfo(Draw_Interpretor& di,
1561                                  Standard_Integer argc,
1562                                  const char** argv)
1563 {
1564   if ( argc != 2 )
1565   {
1566     di << "Wrong number of parameters. Use : meshinfo mesh\n";
1567     return 0;
1568   }
1569
1570   Handle(MeshVS_Mesh) aMesh = getMesh(argv[ 1 ], di);
1571   if ( aMesh.IsNull() )
1572   {
1573     di << "Mesh not found\n";
1574     return 0;
1575   }
1576
1577   Handle(XSDRAWSTLVRML_DataSource) stlMeshSource = Handle(XSDRAWSTLVRML_DataSource)::DownCast(aMesh->GetDataSource());
1578   if (!stlMeshSource.IsNull())
1579   {
1580     const TColStd_PackedMapOfInteger& nodes = stlMeshSource->GetAllNodes();
1581     const TColStd_PackedMapOfInteger& tris  = stlMeshSource->GetAllElements();
1582
1583     di << "Nb nodes = " << nodes.Extent() << "\n";
1584     di << "Nb triangles = " << tris.Extent() << "\n";
1585   }
1586
1587   return 0;
1588 }
1589
1590 //-----------------------------------------------------------------------------
1591
1592 void  XSDRAWSTLVRML::InitCommands (Draw_Interpretor& theCommands)
1593 {
1594   const char* g = "XSTEP-STL/VRML";  // Step transfer file commands
1595   //XSDRAW::LoadDraw(theCommands);
1596
1597   theCommands.Add ("ReadGltf",
1598                    "ReadGltf Doc file [-parallel {on|off}] [-listExternalFiles] [-noCreateDoc]"
1599                    "\n\t\t: Read glTF file into XDE document."
1600                    "\n\t\t:   -listExternalFiles do not read mesh and only list external files"
1601                    "\n\t\t:   -noCreateDoc read into existing XDE document",
1602                    __FILE__, ReadGltf, g);
1603   theCommands.Add ("readgltf",
1604                    "readgltf shape file"
1605                    "\n\t\t: Same as ReadGltf but reads glTF file into a shape instead of a document.",
1606                    __FILE__, ReadGltf, g);
1607   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);
1608   theCommands.Add ("writestl",  "shape file [ascii/binary (0/1) : 1 by default] [InParallel (0/1) : 0 by default]",__FILE__,writestl,g);
1609   theCommands.Add ("readstl",
1610                    "readstl shape file [-brep]"
1611                    "\n\t\t: Reads STL file and creates a new shape with specified name."
1612                    "\n\t\t: When -brep is specified, creates a Compound of per-triangle Faces."
1613                    "\n\t\t: Single triangulation-only Face is created otherwise (default).",
1614                    __FILE__, readstl, g);
1615   theCommands.Add ("loadvrml" , "shape file",__FILE__,loadvrml,g);
1616   theCommands.Add ("ReadObj",
1617                    "ReadObj Doc file [-fileCoordSys {Zup|Yup}] [-fileUnit Unit]"
1618            "\n\t\t:                  [-resultCoordSys {Zup|Yup}] [-singlePrecision]"
1619            "\n\t\t:                  [-listExternalFiles] [-noCreateDoc]"
1620            "\n\t\t: Read OBJ file into XDE document."
1621            "\n\t\t:   -fileUnit       length unit of OBJ file content;"
1622            "\n\t\t:   -fileCoordSys   coordinate system defined by OBJ file; Yup when not specified."
1623            "\n\t\t:   -resultCoordSys result coordinate system; Zup when not specified."
1624            "\n\t\t:   -singlePrecision truncate vertex data to single precision during read; FALSE by default."
1625            "\n\t\t:   -listExternalFiles do not read mesh and only list external files."
1626            "\n\t\t:   -noCreateDoc    read into existing XDE document.",
1627                    __FILE__, ReadObj, g);
1628   theCommands.Add ("readobj",
1629                    "readobj shape file [-fileCoordSys {Zup|Yup}] [-fileUnit Unit]"
1630            "\n\t\t:                    [-resultCoordSys {Zup|Yup}] [-singlePrecision]"
1631            "\n\t\t:                    [-singleFace]"
1632            "\n\t\t: Same as ReadObj but reads OBJ file into a shape instead of a document."
1633            "\n\t\t:   -singleFace merge OBJ content into a single triangulation Face.",
1634            __FILE__, ReadObj, g);
1635
1636   theCommands.Add ("meshfromstl",     "creates MeshVS_Mesh from STL file",            __FILE__, createmesh,      g );
1637   theCommands.Add ("mesh3delem",      "creates 3d element mesh to test",              __FILE__, create3d,        g );
1638   theCommands.Add ("meshshadcolor",   "change MeshVS_Mesh shading color",             __FILE__, meshcolor,       g );
1639   theCommands.Add ("meshlinkcolor",   "change MeshVS_Mesh line color",                __FILE__, linecolor,       g );
1640   theCommands.Add ("meshmat",         "change MeshVS_Mesh material and transparency", __FILE__, meshmat,         g );
1641   theCommands.Add ("meshshrcoef",     "change MeshVS_Mesh shrink coeff",              __FILE__, shrink,          g );
1642   theCommands.Add ("meshclosed",      "meshclosed meshname (0/1) \nChange MeshVS_Mesh drawing mode. 0 - not closed object, 1 - closed object", __FILE__, closed, g);
1643   theCommands.Add ("meshshow",        "display MeshVS_Mesh object",                   __FILE__, mdisplay,        g );
1644   theCommands.Add ("meshhide",        "erase MeshVS_Mesh object",                     __FILE__, merase,          g );
1645   theCommands.Add ("meshhidesel",     "hide selected entities",                       __FILE__, hidesel,         g );
1646   theCommands.Add ("meshshowsel",     "show only selected entities",                  __FILE__, showonly,        g );
1647   theCommands.Add ("meshshowall",     "show all entities",                            __FILE__, showall,         g );
1648   theCommands.Add ("meshcolors",      "display color presentation",                   __FILE__, meshcolors,      g );
1649   theCommands.Add ("meshvectors",     "display sample vectors",                       __FILE__, meshvectors,     g );
1650   theCommands.Add ("meshtext",        "display text labels",                          __FILE__, meshtext,        g );
1651   theCommands.Add ("meshdeform",      "display deformed mesh",                        __FILE__, meshdeform,      g );
1652   theCommands.Add ("mesh_edge_width", "set width of edges",                           __FILE__, mesh_edge_width, g );
1653   theCommands.Add ("meshinfo",        "displays the number of nodes and triangles",   __FILE__, meshinfo,        g );
1654 }
1655
1656 //==============================================================================
1657 // XSDRAWSTLVRML::Factory
1658 //==============================================================================
1659 void XSDRAWSTLVRML::Factory(Draw_Interpretor& theDI)
1660 {
1661   XSDRAWIGES::InitSelect();
1662   XSDRAWIGES::InitToBRep(theDI);
1663   XSDRAWIGES::InitFromBRep(theDI);
1664   XSDRAWSTEP::InitCommands(theDI);
1665   XSDRAWSTLVRML::InitCommands(theDI);
1666   XSDRAW::LoadDraw(theDI);
1667 #ifdef OCCT_DEBUG
1668   theDI << "Draw Plugin : All TKXSDRAW commands are loaded\n";
1669 #endif
1670 }
1671
1672 // Declare entry point PLUGINFACTORY
1673 DPLUGIN(XSDRAWSTLVRML)
1674