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