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