1 // Created on: 2000-05-30
2 // Created by: Sergey MOZOKHIN
3 // Copyright (c) 2000-2014 OPEN CASCADE SAS
5 // This file is part of Open CASCADE Technology software library.
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.
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
16 #include <XSDRAWSTLVRML.hxx>
18 #include <AIS_InteractiveContext.hxx>
19 #include <Aspect_TypeOfMarker.hxx>
20 #include <Bnd_Box.hxx>
21 #include <BRep_Builder.hxx>
22 #include <BRepLib_PointCloudShape.hxx>
24 #include <DDocStd.hxx>
25 #include <DDocStd_DrawDocument.hxx>
27 #include <Draw_Interpretor.hxx>
28 #include <Draw_PluginMacro.hxx>
29 #include <Draw_ProgressIndicator.hxx>
30 #include <Graphic3d_MaterialAspect.hxx>
31 #include <MeshVS_DataMapOfIntegerAsciiString.hxx>
32 #include <MeshVS_DeformedDataSource.hxx>
33 #include <MeshVS_Drawer.hxx>
34 #include <MeshVS_DrawerAttribute.hxx>
35 #include <MeshVS_ElementalColorPrsBuilder.hxx>
36 #include <MeshVS_Mesh.hxx>
37 #include <MeshVS_MeshEntityOwner.hxx>
38 #include <MeshVS_MeshPrsBuilder.hxx>
39 #include <MeshVS_NodalColorPrsBuilder.hxx>
40 #include <MeshVS_PrsBuilder.hxx>
41 #include <MeshVS_TextPrsBuilder.hxx>
42 #include <MeshVS_VectorPrsBuilder.hxx>
43 #include <OSD_Path.hxx>
44 #include <Quantity_Color.hxx>
45 #include <Quantity_HArray1OfColor.hxx>
46 #include <Quantity_NameOfColor.hxx>
47 #include <RWGltf_DracoParameters.hxx>
48 #include <RWGltf_CafReader.hxx>
49 #include <RWGltf_CafWriter.hxx>
50 #include <RWMesh_FaceIterator.hxx>
53 #include <RWObj_CafReader.hxx>
54 #include <RWObj_CafWriter.hxx>
55 #include <RWPly_CafWriter.hxx>
56 #include <RWPly_PlyWriterContext.hxx>
57 #include <SelectMgr_SelectionManager.hxx>
58 #include <Standard_ErrorHandler.hxx>
59 #include <StdSelect_ViewerSelector3d.hxx>
61 #include <StlAPI_Writer.hxx>
62 #include <TColgp_SequenceOfXYZ.hxx>
63 #include <TCollection_AsciiString.hxx>
64 #include <TColStd_Array1OfReal.hxx>
65 #include <TColStd_HPackedMapOfInteger.hxx>
66 #include <TColStd_MapIteratorOfPackedMapOfInteger.hxx>
67 #include <TDataStd_Name.hxx>
68 #include <TDocStd_Application.hxx>
69 #include <TDocStd_Document.hxx>
71 #include <TopoDS_Face.hxx>
72 #include <TopoDS_Shape.hxx>
73 #include <UnitsAPI.hxx>
74 #include <UnitsMethods.hxx>
75 #include <V3d_View.hxx>
76 #include <ViewerTest.hxx>
77 #include <VrmlAPI.hxx>
78 #include <VrmlAPI_Writer.hxx>
79 #include <VrmlData_DataMapOfShapeAppearance.hxx>
80 #include <VrmlData_Scene.hxx>
81 #include <VrmlData_ShapeConvert.hxx>
82 #include <XCAFDoc_DocumentTool.hxx>
83 #include <XCAFDoc_ShapeTool.hxx>
84 #include <XCAFPrs_DocumentExplorer.hxx>
86 #include <XSAlgo_AlgoContainer.hxx>
88 #include <XSDRAWIGES.hxx>
89 #include <XSDRAWSTEP.hxx>
90 #include <XSDRAWSTLVRML_DataSource.hxx>
91 #include <XSDRAWSTLVRML_DataSource3D.hxx>
92 #include <XSDRAWSTLVRML_DrawableMesh.hxx>
98 extern Standard_Boolean VDisplayAISObject (const TCollection_AsciiString& theName,
99 const Handle(AIS_InteractiveObject)& theAISObj,
100 Standard_Boolean theReplaceIfExists = Standard_True);
102 //! Parse RWMesh_NameFormat enumeration.
103 static bool parseNameFormat (const char* theArg,
104 RWMesh_NameFormat& theFormat)
106 TCollection_AsciiString aName (theArg);
108 if (aName == "empty")
110 theFormat = RWMesh_NameFormat_Empty;
112 else if (aName == "product"
115 theFormat = RWMesh_NameFormat_Product;
117 else if (aName == "instance"
120 theFormat = RWMesh_NameFormat_Instance;
122 else if (aName == "instanceorproduct"
123 || aName == "instance||product"
124 || aName == "instance|product"
125 || aName == "instorprod"
126 || aName == "inst||prod"
127 || aName == "inst|prod")
129 theFormat = RWMesh_NameFormat_InstanceOrProduct;
131 else if (aName == "productorinstance"
132 || aName == "product||instance"
133 || aName == "product|instance"
134 || aName == "prodorinst"
135 || aName == "prod||inst"
136 || aName == "prod|inst")
138 theFormat = RWMesh_NameFormat_ProductOrInstance;
140 else if (aName == "productandinstance"
141 || aName == "prodandinst"
142 || aName == "product&instance"
143 || aName == "prod&inst")
145 theFormat = RWMesh_NameFormat_ProductAndInstance;
147 else if (aName == "productandinstanceandocaf"
148 || aName == "verbose"
151 theFormat = RWMesh_NameFormat_ProductAndInstanceAndOcaf;
160 //! Parse RWMesh_CoordinateSystem enumeration.
161 static bool parseCoordinateSystem (const char* theArg,
162 RWMesh_CoordinateSystem& theSystem)
164 TCollection_AsciiString aCSStr (theArg);
168 theSystem = RWMesh_CoordinateSystem_Zup;
170 else if (aCSStr == "yup")
172 theSystem = RWMesh_CoordinateSystem_Yup;
176 return Standard_False;
178 return Standard_True;
181 //=============================================================================
182 //function : ReadGltf
183 //purpose : Reads glTF file
184 //=============================================================================
185 static Standard_Integer ReadGltf (Draw_Interpretor& theDI,
186 Standard_Integer theNbArgs,
187 const char** theArgVec)
189 TCollection_AsciiString aDestName, aFilePath;
190 Standard_Boolean toUseExistingDoc = Standard_False;
191 Standard_Boolean toListExternalFiles = Standard_False;
192 Standard_Boolean isParallel = Standard_False;
193 Standard_Boolean isDoublePrec = Standard_False;
194 Standard_Boolean toSkipLateDataLoading = Standard_False;
195 Standard_Boolean toKeepLateData = Standard_True;
196 Standard_Boolean toPrintDebugInfo = Standard_False;
197 Standard_Boolean toLoadAllScenes = Standard_False;
198 Standard_Boolean toPrintAssetInfo = Standard_False;
199 Standard_Boolean isNoDoc = (TCollection_AsciiString(theArgVec[0]) == "readgltf");
200 for (Standard_Integer anArgIter = 1; anArgIter < theNbArgs; ++anArgIter)
202 TCollection_AsciiString anArgCase (theArgVec[anArgIter]);
203 anArgCase.LowerCase();
205 && (anArgCase == "-nocreate"
206 || anArgCase == "-nocreatedoc"))
208 toUseExistingDoc = Draw::ParseOnOffIterator (theNbArgs, theArgVec, anArgIter);
210 else if (anArgCase == "-parallel")
212 isParallel = Draw::ParseOnOffIterator (theNbArgs, theArgVec, anArgIter);
214 else if (anArgCase == "-doubleprec"
215 || anArgCase == "-doubleprecision"
216 || anArgCase == "-singleprec"
217 || anArgCase == "-singleprecision")
219 isDoublePrec = Draw::ParseOnOffIterator (theNbArgs, theArgVec, anArgIter);
220 if (anArgCase.StartsWith ("-single"))
222 isDoublePrec = !isDoublePrec;
225 else if (anArgCase == "-skiplateloading")
227 toSkipLateDataLoading = Draw::ParseOnOffIterator (theNbArgs, theArgVec, anArgIter);
229 else if (anArgCase == "-keeplate")
231 toKeepLateData = Draw::ParseOnOffIterator (theNbArgs, theArgVec, anArgIter);
233 else if (anArgCase == "-allscenes")
235 toLoadAllScenes = Draw::ParseOnOffIterator (theNbArgs, theArgVec, anArgIter);
237 else if (anArgCase == "-toprintinfo"
238 || anArgCase == "-toprintdebuginfo")
240 toPrintDebugInfo = Draw::ParseOnOffIterator (theNbArgs, theArgVec, anArgIter);
242 else if (anArgCase == "-listexternalfiles"
243 || anArgCase == "-listexternals"
244 || anArgCase == "-listexternal"
245 || anArgCase == "-external"
246 || anArgCase == "-externalfiles")
248 toListExternalFiles = Draw::ParseOnOffIterator (theNbArgs, theArgVec, anArgIter);
250 else if (anArgCase == "-assetinfo"
251 || anArgCase == "-metadata")
253 toPrintAssetInfo = Draw::ParseOnOffIterator (theNbArgs, theArgVec, anArgIter);
255 else if (aDestName.IsEmpty())
257 aDestName = theArgVec[anArgIter];
259 else if (aFilePath.IsEmpty())
261 aFilePath = theArgVec[anArgIter];
265 Message::SendFail() << "Syntax error at '" << theArgVec[anArgIter] << "'";
269 if (aFilePath.IsEmpty() && !aDestName.IsEmpty())
271 if (toListExternalFiles || toPrintAssetInfo)
273 std::swap (aFilePath, aDestName);
276 if (aFilePath.IsEmpty())
278 Message::SendFail() << "Syntax error: wrong number of arguments";
282 Handle(Draw_ProgressIndicator) aProgress = new Draw_ProgressIndicator (theDI, 1);
283 Handle(TDocStd_Document) aDoc;
284 if (!aDestName.IsEmpty()
287 Handle(TDocStd_Application) anApp = DDocStd::GetApplication();
288 Standard_CString aNameVar = aDestName.ToCString();
289 DDocStd::GetDocument (aNameVar, aDoc, Standard_False);
292 if (toUseExistingDoc)
294 Message::SendFail() << "Error: document with name " << aDestName << " does not exist";
297 anApp->NewDocument (TCollection_ExtendedString ("BinXCAF"), aDoc);
299 else if (!toUseExistingDoc)
301 Message::SendFail() << "Error: document with name " << aDestName << " already exists";
306 Standard_Real aScaleFactorM = 1.;
307 if (!XCAFDoc_DocumentTool::GetLengthUnit(aDoc, aScaleFactorM, UnitsMethods_LengthUnit_Meter))
309 XSAlgo::AlgoContainer()->PrepareForTransfer(); // update unit info
310 aScaleFactorM = UnitsMethods::GetCasCadeLengthUnit(UnitsMethods_LengthUnit_Meter);
313 RWGltf_CafReader aReader;
314 aReader.SetSystemLengthUnit (aScaleFactorM);
315 aReader.SetSystemCoordinateSystem (RWMesh_CoordinateSystem_Zup);
316 aReader.SetDocument (aDoc);
317 aReader.SetParallel (isParallel);
318 aReader.SetDoublePrecision (isDoublePrec);
319 aReader.SetToSkipLateDataLoading (toSkipLateDataLoading);
320 aReader.SetToKeepLateData (toKeepLateData);
321 aReader.SetToPrintDebugMessages (toPrintDebugInfo);
322 aReader.SetLoadAllScenes (toLoadAllScenes);
323 if (aDestName.IsEmpty())
325 aReader.ProbeHeader (aFilePath);
329 aReader.Perform (aFilePath, aProgress->Start());
332 DBRep::Set (aDestName.ToCString(), aReader.SingleShape());
336 Handle(DDocStd_DrawDocument) aDrawDoc = new DDocStd_DrawDocument (aDoc);
337 TDataStd_Name::Set (aDoc->GetData()->Root(), aDestName);
338 Draw::Set (aDestName.ToCString(), aDrawDoc);
342 bool isFirstLine = true;
343 if (toPrintAssetInfo)
345 for (TColStd_IndexedDataMapOfStringString::Iterator aKeyIter (aReader.Metadata()); aKeyIter.More(); aKeyIter.Next())
352 theDI << aKeyIter.Key() << ": " << aKeyIter.Value();
355 if (toListExternalFiles)
361 for (NCollection_IndexedMap<TCollection_AsciiString>::Iterator aFileIter (aReader.ExternalFiles()); aFileIter.More(); aFileIter.Next())
363 theDI << "\"" << aFileIter.Value() << "\" ";
370 //=============================================================================
371 //function : WriteGltf
372 //purpose : Writes glTF file
373 //=============================================================================
374 static Standard_Integer WriteGltf (Draw_Interpretor& theDI,
375 Standard_Integer theNbArgs,
376 const char** theArgVec)
378 TCollection_AsciiString aGltfFilePath;
379 Handle(TDocStd_Document) aDoc;
380 Handle(TDocStd_Application) anApp = DDocStd::GetApplication();
381 TColStd_IndexedDataMapOfStringString aFileInfo;
382 RWGltf_WriterTrsfFormat aTrsfFormat = RWGltf_WriterTrsfFormat_Compact;
383 RWMesh_CoordinateSystem aSystemCoordSys = RWMesh_CoordinateSystem_Zup;
384 bool toForceUVExport = false, toEmbedTexturesInGlb = true;
385 bool toMergeFaces = false, toSplitIndices16 = false;
386 RWMesh_NameFormat aNodeNameFormat = RWMesh_NameFormat_InstanceOrProduct;
387 RWMesh_NameFormat aMeshNameFormat = RWMesh_NameFormat_Product;
388 RWGltf_DracoParameters aDracoParameters;
389 for (Standard_Integer anArgIter = 1; anArgIter < theNbArgs; ++anArgIter)
391 TCollection_AsciiString anArgCase (theArgVec[anArgIter]);
392 anArgCase.LowerCase();
393 if (anArgCase == "-comments"
394 && anArgIter + 1 < theNbArgs)
396 aFileInfo.Add ("Comments", theArgVec[++anArgIter]);
398 else if (anArgCase == "-author"
399 && anArgIter + 1 < theNbArgs)
401 aFileInfo.Add ("Author", theArgVec[++anArgIter]);
403 else if (anArgCase == "-forceuvexport"
404 || anArgCase == "-forceuv")
406 toForceUVExport = true;
407 if (anArgIter + 1 < theNbArgs
408 && Draw::ParseOnOff (theArgVec[anArgIter + 1], toForceUVExport))
413 else if (anArgCase == "-mergefaces")
416 if (anArgIter + 1 < theNbArgs
417 && Draw::ParseOnOff (theArgVec[anArgIter + 1], toMergeFaces))
422 else if (anArgCase == "-splitindices16"
423 || anArgCase == "-splitindexes16"
424 || anArgCase == "-splitindices"
425 || anArgCase == "-splitindexes"
426 || anArgCase == "-splitind")
428 toSplitIndices16 = true;
429 if (anArgIter + 1 < theNbArgs
430 && Draw::ParseOnOff (theArgVec[anArgIter + 1], toSplitIndices16))
435 else if (anArgIter + 1 < theNbArgs
436 && (anArgCase == "-systemcoordinatesystem"
437 || anArgCase == "-systemcoordsystem"
438 || anArgCase == "-systemcoordsys"
439 || anArgCase == "-syscoordsys"))
441 if (!parseCoordinateSystem (theArgVec[++anArgIter], aSystemCoordSys))
443 Message::SendFail() << "Syntax error: unknown coordinate system '" << theArgVec[anArgIter] << "'";
447 else if (anArgCase == "-trsfformat"
448 && anArgIter + 1 < theNbArgs)
450 TCollection_AsciiString aTrsfStr (theArgVec[++anArgIter]);
451 aTrsfStr.LowerCase();
452 if (aTrsfStr == "compact")
454 aTrsfFormat = RWGltf_WriterTrsfFormat_Compact;
456 else if (aTrsfStr == "mat4")
458 aTrsfFormat = RWGltf_WriterTrsfFormat_Mat4;
460 else if (aTrsfStr == "trs")
462 aTrsfFormat = RWGltf_WriterTrsfFormat_TRS;
466 Message::SendFail() << "Syntax error at '" << anArgCase << "'";
470 else if (anArgCase == "-nodenameformat"
471 || anArgCase == "-nodename")
474 if (anArgIter >= theNbArgs
475 || !parseNameFormat (theArgVec[anArgIter], aNodeNameFormat))
477 Message::SendFail() << "Syntax error at '" << anArgCase << "'";
481 else if (anArgCase == "-meshnameformat"
482 || anArgCase == "-meshname")
485 if (anArgIter >= theNbArgs
486 || !parseNameFormat (theArgVec[anArgIter], aMeshNameFormat))
488 Message::SendFail() << "Syntax error at '" << anArgCase << "'";
492 else if (aDoc.IsNull())
494 Standard_CString aNameVar = theArgVec[anArgIter];
495 DDocStd::GetDocument (aNameVar, aDoc, false);
498 TopoDS_Shape aShape = DBRep::Get (aNameVar);
501 Message::SendFail() << "Syntax error: '" << aNameVar << "' is not a shape nor document";
505 anApp->NewDocument (TCollection_ExtendedString ("BinXCAF"), aDoc);
506 Handle(XCAFDoc_ShapeTool) aShapeTool = XCAFDoc_DocumentTool::ShapeTool (aDoc->Main());
507 // auto-naming doesn't generate meaningful instance names
508 //aShapeTool->SetAutoNaming (false);
509 aNodeNameFormat = RWMesh_NameFormat_Product;
510 aShapeTool->AddShape (aShape);
513 else if (aGltfFilePath.IsEmpty())
515 aGltfFilePath = theArgVec[anArgIter];
517 else if (anArgCase == "-texturesSeparate")
519 toEmbedTexturesInGlb = false;
521 else if (anArgCase == "-draco")
523 aDracoParameters.DracoCompression = Draw::ParseOnOffIterator(theNbArgs, theArgVec, anArgIter);
525 else if (anArgCase == "-compressionlevel" && (anArgIter + 1) < theNbArgs
526 && Draw::ParseInteger(theArgVec[anArgIter + 1], aDracoParameters.CompressionLevel))
530 else if (anArgCase == "-quantizepositionbits" && (anArgIter + 1) < theNbArgs
531 && Draw::ParseInteger(theArgVec[anArgIter + 1], aDracoParameters.QuantizePositionBits))
535 else if (anArgCase == "-quantizenormalbits" && (anArgIter + 1) < theNbArgs
536 && Draw::ParseInteger(theArgVec[anArgIter + 1], aDracoParameters.QuantizeNormalBits))
540 else if (anArgCase == "-quantizetexcoordbits" && (anArgIter + 1) < theNbArgs
541 && Draw::ParseInteger(theArgVec[anArgIter + 1], aDracoParameters.QuantizeTexcoordBits))
545 else if (anArgCase == "-quantizecolorbits" && (anArgIter + 1) < theNbArgs
546 && Draw::ParseInteger(theArgVec[anArgIter + 1], aDracoParameters.QuantizeColorBits))
550 else if (anArgCase == "-quantizegenericbits" && (anArgIter + 1) < theNbArgs
551 && Draw::ParseInteger(theArgVec[anArgIter + 1], aDracoParameters.QuantizeGenericBits))
555 else if (anArgCase == "-unifiedquantization")
557 aDracoParameters.UnifiedQuantization = Draw::ParseOnOffIterator(theNbArgs, theArgVec, anArgIter);
561 Message::SendFail() << "Syntax error at '" << theArgVec[anArgIter] << "'";
565 if (aGltfFilePath.IsEmpty())
567 Message::SendFail() << "Syntax error: wrong number of arguments";
571 Handle(Draw_ProgressIndicator) aProgress = new Draw_ProgressIndicator (theDI, 1);
573 TCollection_AsciiString anExt = aGltfFilePath;
575 Standard_Real aScaleFactorM = 1.;
576 if (!XCAFDoc_DocumentTool::GetLengthUnit(aDoc, aScaleFactorM, UnitsMethods_LengthUnit_Meter))
578 XSAlgo::AlgoContainer()->PrepareForTransfer(); // update unit info
579 aScaleFactorM = UnitsMethods::GetCasCadeLengthUnit(UnitsMethods_LengthUnit_Meter);
582 RWGltf_CafWriter aWriter (aGltfFilePath, anExt.EndsWith (".glb"));
583 aWriter.SetTransformationFormat (aTrsfFormat);
584 aWriter.SetNodeNameFormat (aNodeNameFormat);
585 aWriter.SetMeshNameFormat (aMeshNameFormat);
586 aWriter.SetForcedUVExport (toForceUVExport);
587 aWriter.SetToEmbedTexturesInGlb (toEmbedTexturesInGlb);
588 aWriter.SetMergeFaces (toMergeFaces);
589 aWriter.SetSplitIndices16 (toSplitIndices16);
590 aWriter.SetCompressionParameters(aDracoParameters);
591 aWriter.ChangeCoordinateSystemConverter().SetInputLengthUnit (aScaleFactorM);
592 aWriter.ChangeCoordinateSystemConverter().SetInputCoordinateSystem (aSystemCoordSys);
593 aWriter.Perform (aDoc, aFileInfo, aProgress->Start());
597 static Standard_Integer writestl
598 (Draw_Interpretor& di, Standard_Integer argc, const char** argv)
600 if (argc < 3 || argc > 4) {
601 di << "Use: " << argv[0]
602 << " shape file [ascii/binary (0/1) : 1 by default]\n";
604 TopoDS_Shape aShape = DBRep::Get(argv[1]);
605 Standard_Boolean isASCIIMode = Standard_False;
607 isASCIIMode = (Draw::Atoi(argv[3]) == 0);
609 StlAPI_Writer aWriter;
610 aWriter.ASCIIMode() = isASCIIMode;
611 Handle(Draw_ProgressIndicator) aProgress = new Draw_ProgressIndicator (di);
612 Standard_Boolean isOK = aWriter.Write (aShape, argv[2], aProgress->Start());
614 di << "** Error **: Mesh writing has been failed.\n";
619 //=============================================================================
621 //purpose : Reads stl file
622 //=============================================================================
623 static Standard_Integer readstl(Draw_Interpretor& theDI,
624 Standard_Integer theArgc,
625 const char** theArgv)
627 TCollection_AsciiString aShapeName, aFilePath;
628 bool toCreateCompOfTris = false;
629 bool anIsMulti = false;
630 double aMergeAngle = M_PI / 2.0;
631 for (Standard_Integer anArgIter = 1; anArgIter < theArgc; ++anArgIter)
633 TCollection_AsciiString anArg (theArgv[anArgIter]);
635 if (aShapeName.IsEmpty())
637 aShapeName = theArgv[anArgIter];
639 else if (aFilePath.IsEmpty())
641 aFilePath = theArgv[anArgIter];
643 else if (anArg == "-brep")
645 toCreateCompOfTris = true;
646 if (anArgIter + 1 < theArgc
647 && Draw::ParseOnOff (theArgv[anArgIter + 1], toCreateCompOfTris))
652 else if (anArg == "-multi")
655 if (anArgIter + 1 < theArgc
656 && Draw::ParseOnOff (theArgv[anArgIter + 1], anIsMulti))
661 else if (anArg == "-mergeangle"
662 || anArg == "-smoothangle"
663 || anArg == "-nomergeangle"
664 || anArg == "-nosmoothangle")
666 if (anArg.StartsWith ("-no"))
668 aMergeAngle = M_PI / 2.0;
672 aMergeAngle = M_PI / 4.0;
673 if (anArgIter + 1 < theArgc
674 && Draw::ParseReal (theArgv[anArgIter + 1], aMergeAngle))
676 if (aMergeAngle < 0.0 || aMergeAngle > 90.0)
678 theDI << "Syntax error: angle should be within [0,90] range";
683 aMergeAngle = aMergeAngle * M_PI / 180.0;
689 Message::SendFail() << "Syntax error: unknown argument '" << theArgv[anArgIter] << "'";
693 if (aFilePath.IsEmpty())
695 Message::SendFail() << "Syntax error: not enough arguments";
700 if (!toCreateCompOfTris)
702 Handle(Draw_ProgressIndicator) aProgress = new Draw_ProgressIndicator (theDI,1);
705 NCollection_Sequence<Handle(Poly_Triangulation)> aTriangList;
706 // Read STL file to the triangulation list.
707 RWStl::ReadFile(aFilePath.ToCString(),aMergeAngle,aTriangList,aProgress->Start());
710 if (aTriangList.Size() == 1)
713 aB.UpdateFace (aFace,aTriangList.First());
718 TopoDS_Compound aCmp;
719 aB.MakeCompound (aCmp);
721 NCollection_Sequence<Handle(Poly_Triangulation)>::Iterator anIt (aTriangList);
722 for (; anIt.More(); anIt.Next())
725 aB.UpdateFace (aFace,anIt.Value());
733 // Read STL file to the triangulation.
734 Handle(Poly_Triangulation) aTriangulation = RWStl::ReadFile (aFilePath.ToCString(),aMergeAngle,aProgress->Start());
739 aB.UpdateFace (aFace,aTriangulation);
745 Standard_DISABLE_DEPRECATION_WARNINGS
746 StlAPI::Read(aShape, aFilePath.ToCString());
747 Standard_ENABLE_DEPRECATION_WARNINGS
749 DBRep::Set (aShapeName.ToCString(), aShape);
753 //=============================================================================
755 //purpose : Reads OBJ file
756 //=============================================================================
757 static Standard_Integer ReadObj (Draw_Interpretor& theDI,
758 Standard_Integer theNbArgs,
759 const char** theArgVec)
761 TCollection_AsciiString aDestName, aFilePath;
762 Standard_Boolean toUseExistingDoc = Standard_False;
763 Standard_Real aFileUnitFactor = -1.0;
764 RWMesh_CoordinateSystem aResultCoordSys = RWMesh_CoordinateSystem_Zup, aFileCoordSys = RWMesh_CoordinateSystem_Yup;
765 Standard_Boolean toListExternalFiles = Standard_False, isSingleFace = Standard_False, isSinglePrecision = Standard_False;
766 Standard_Boolean isNoDoc = (TCollection_AsciiString(theArgVec[0]) == "readobj");
767 for (Standard_Integer anArgIter = 1; anArgIter < theNbArgs; ++anArgIter)
769 TCollection_AsciiString anArgCase (theArgVec[anArgIter]);
770 anArgCase.LowerCase();
771 if (anArgIter + 1 < theNbArgs
772 && (anArgCase == "-unit"
773 || anArgCase == "-units"
774 || anArgCase == "-fileunit"
775 || anArgCase == "-fileunits"))
777 const TCollection_AsciiString aUnitStr (theArgVec[++anArgIter]);
778 aFileUnitFactor = UnitsAPI::AnyToSI (1.0, aUnitStr.ToCString());
779 if (aFileUnitFactor <= 0.0)
781 Message::SendFail() << "Syntax error: wrong length unit '" << aUnitStr << "'";
785 else if (anArgIter + 1 < theNbArgs
786 && (anArgCase == "-filecoordinatesystem"
787 || anArgCase == "-filecoordsystem"
788 || anArgCase == "-filecoordsys"))
790 if (!parseCoordinateSystem (theArgVec[++anArgIter], aFileCoordSys))
792 Message::SendFail() << "Syntax error: unknown coordinate system '" << theArgVec[anArgIter] << "'";
796 else if (anArgIter + 1 < theNbArgs
797 && (anArgCase == "-resultcoordinatesystem"
798 || anArgCase == "-resultcoordsystem"
799 || anArgCase == "-resultcoordsys"
800 || anArgCase == "-rescoordsys"))
802 if (!parseCoordinateSystem (theArgVec[++anArgIter], aResultCoordSys))
804 Message::SendFail() << "Syntax error: unknown coordinate system '" << theArgVec[anArgIter] << "'";
808 else if (anArgCase == "-singleprecision"
809 || anArgCase == "-singleprec")
811 isSinglePrecision = Standard_True;
812 if (anArgIter + 1 < theNbArgs
813 && Draw::ParseOnOff (theArgVec[anArgIter + 1], isSinglePrecision))
819 && (anArgCase == "-singleface"
820 || anArgCase == "-singletriangulation"))
822 isSingleFace = Standard_True;
825 && (anArgCase == "-nocreate"
826 || anArgCase == "-nocreatedoc"))
828 toUseExistingDoc = Standard_True;
829 if (anArgIter + 1 < theNbArgs
830 && Draw::ParseOnOff (theArgVec[anArgIter + 1], toUseExistingDoc))
835 else if (anArgCase == "-listexternalfiles"
836 || anArgCase == "-listexternals"
837 || anArgCase == "-listexternal"
838 || anArgCase == "-external"
839 || anArgCase == "-externalfiles")
841 toListExternalFiles = Standard_True;
843 else if (aDestName.IsEmpty())
845 aDestName = theArgVec[anArgIter];
847 else if (aFilePath.IsEmpty())
849 aFilePath = theArgVec[anArgIter];
853 Message::SendFail() << "Syntax error at '" << theArgVec[anArgIter] << "'";
857 if (aFilePath.IsEmpty())
859 Message::SendFail() << "Syntax error: wrong number of arguments";
863 Handle(Draw_ProgressIndicator) aProgress = new Draw_ProgressIndicator (theDI, 1);
864 Handle(TDocStd_Document) aDoc;
866 && !toListExternalFiles)
868 Handle(TDocStd_Application) anApp = DDocStd::GetApplication();
869 Standard_CString aNameVar = aDestName.ToCString();
870 DDocStd::GetDocument (aNameVar, aDoc, Standard_False);
873 if (toUseExistingDoc)
875 Message::SendFail() << "Error: document with name " << aDestName << " does not exist";
878 anApp->NewDocument (TCollection_ExtendedString ("BinXCAF"), aDoc);
880 else if (!toUseExistingDoc)
882 Message::SendFail() << "Error: document with name " << aDestName << " already exists";
886 Standard_Real aScaleFactorM = 1.;
887 if (!XCAFDoc_DocumentTool::GetLengthUnit(aDoc, aScaleFactorM, UnitsMethods_LengthUnit_Meter))
889 XSAlgo::AlgoContainer()->PrepareForTransfer(); // update unit info
890 aScaleFactorM = UnitsMethods::GetCasCadeLengthUnit(UnitsMethods_LengthUnit_Meter);
893 RWObj_CafReader aReader;
894 aReader.SetSinglePrecision (isSinglePrecision);
895 aReader.SetSystemLengthUnit (aScaleFactorM);
896 aReader.SetSystemCoordinateSystem (aResultCoordSys);
897 aReader.SetFileLengthUnit (aFileUnitFactor);
898 aReader.SetFileCoordinateSystem (aFileCoordSys);
899 aReader.SetDocument (aDoc);
902 RWObj_TriangulationReader aSimpleReader;
903 aSimpleReader.SetSinglePrecision (isSinglePrecision);
904 aSimpleReader.SetCreateShapes (Standard_False);
905 aSimpleReader.SetTransformation (aReader.CoordinateSystemConverter());
906 aSimpleReader.Read (aFilePath.ToCString(), aProgress->Start());
908 Handle(Poly_Triangulation) aTriangulation = aSimpleReader.GetTriangulation();
910 BRep_Builder aBuiler;
911 aBuiler.MakeFace (aFace);
912 aBuiler.UpdateFace (aFace, aTriangulation);
913 DBRep::Set (aDestName.ToCString(), aFace);
917 if (toListExternalFiles)
919 aReader.ProbeHeader (aFilePath);
920 for (NCollection_IndexedMap<TCollection_AsciiString>::Iterator aFileIter (aReader.ExternalFiles()); aFileIter.More(); aFileIter.Next())
922 theDI << "\"" << aFileIter.Value() << "\" ";
927 aReader.Perform (aFilePath, aProgress->Start());
930 DBRep::Set (aDestName.ToCString(), aReader.SingleShape());
934 Handle(DDocStd_DrawDocument) aDrawDoc = new DDocStd_DrawDocument (aDoc);
935 TDataStd_Name::Set (aDoc->GetData()->Root(), aDestName);
936 Draw::Set (aDestName.ToCString(), aDrawDoc);
942 //=============================================================================
943 //function : WriteObj
944 //purpose : Writes OBJ file
945 //=============================================================================
946 static Standard_Integer WriteObj (Draw_Interpretor& theDI,
947 Standard_Integer theNbArgs,
948 const char** theArgVec)
950 TCollection_AsciiString anObjFilePath;
951 Handle(TDocStd_Document) aDoc;
952 Handle(TDocStd_Application) anApp = DDocStd::GetApplication();
953 TColStd_IndexedDataMapOfStringString aFileInfo;
954 Standard_Real aFileUnitFactor = -1.0;
955 RWMesh_CoordinateSystem aSystemCoordSys = RWMesh_CoordinateSystem_Zup, aFileCoordSys = RWMesh_CoordinateSystem_Yup;
956 for (Standard_Integer anArgIter = 1; anArgIter < theNbArgs; ++anArgIter)
958 TCollection_AsciiString anArgCase (theArgVec[anArgIter]);
959 anArgCase.LowerCase();
960 if (anArgIter + 1 < theNbArgs
961 && (anArgCase == "-unit"
962 || anArgCase == "-units"
963 || anArgCase == "-fileunit"
964 || anArgCase == "-fileunits"))
966 const TCollection_AsciiString aUnitStr (theArgVec[++anArgIter]);
967 aFileUnitFactor = UnitsAPI::AnyToSI (1.0, aUnitStr.ToCString());
968 if (aFileUnitFactor <= 0.0)
970 Message::SendFail() << "Syntax error: wrong length unit '" << aUnitStr << "'";
974 else if (anArgIter + 1 < theNbArgs
975 && (anArgCase == "-filecoordinatesystem"
976 || anArgCase == "-filecoordsystem"
977 || anArgCase == "-filecoordsys"))
979 if (!parseCoordinateSystem (theArgVec[++anArgIter], aFileCoordSys))
981 Message::SendFail() << "Syntax error: unknown coordinate system '" << theArgVec[anArgIter] << "'";
985 else if (anArgIter + 1 < theNbArgs
986 && (anArgCase == "-systemcoordinatesystem"
987 || anArgCase == "-systemcoordsystem"
988 || anArgCase == "-systemcoordsys"
989 || anArgCase == "-syscoordsys"))
991 if (!parseCoordinateSystem (theArgVec[++anArgIter], aSystemCoordSys))
993 Message::SendFail() << "Syntax error: unknown coordinate system '" << theArgVec[anArgIter] << "'";
997 else if (anArgCase == "-comments"
998 && anArgIter + 1 < theNbArgs)
1000 aFileInfo.Add ("Comments", theArgVec[++anArgIter]);
1002 else if (anArgCase == "-author"
1003 && anArgIter + 1 < theNbArgs)
1005 aFileInfo.Add ("Author", theArgVec[++anArgIter]);
1007 else if (aDoc.IsNull())
1009 Standard_CString aNameVar = theArgVec[anArgIter];
1010 DDocStd::GetDocument (aNameVar, aDoc, false);
1013 TopoDS_Shape aShape = DBRep::Get (aNameVar);
1014 if (aShape.IsNull())
1016 Message::SendFail() << "Syntax error: '" << aNameVar << "' is not a shape nor document";
1020 anApp->NewDocument (TCollection_ExtendedString ("BinXCAF"), aDoc);
1021 Handle(XCAFDoc_ShapeTool) aShapeTool = XCAFDoc_DocumentTool::ShapeTool (aDoc->Main());
1022 aShapeTool->AddShape (aShape);
1025 else if (anObjFilePath.IsEmpty())
1027 anObjFilePath = theArgVec[anArgIter];
1031 Message::SendFail() << "Syntax error at '" << theArgVec[anArgIter] << "'";
1035 if (anObjFilePath.IsEmpty())
1037 Message::SendFail() << "Syntax error: wrong number of arguments";
1041 Handle(Draw_ProgressIndicator) aProgress = new Draw_ProgressIndicator (theDI, 1);
1043 const Standard_Real aSystemUnitFactor = UnitsMethods::GetCasCadeLengthUnit() * 0.001;
1044 RWObj_CafWriter aWriter (anObjFilePath);
1045 aWriter.ChangeCoordinateSystemConverter().SetInputLengthUnit (aSystemUnitFactor);
1046 aWriter.ChangeCoordinateSystemConverter().SetInputCoordinateSystem (aSystemCoordSys);
1047 aWriter.ChangeCoordinateSystemConverter().SetOutputLengthUnit (aFileUnitFactor);
1048 aWriter.ChangeCoordinateSystemConverter().SetOutputCoordinateSystem (aFileCoordSys);
1049 aWriter.Perform (aDoc, aFileInfo, aProgress->Start());
1053 static Standard_Integer writevrml
1054 (Draw_Interpretor& di, Standard_Integer argc, const char** argv)
1056 if (argc < 3 || argc > 5)
1058 di << "wrong number of parameters\n";
1062 TopoDS_Shape aShape = DBRep::Get(argv[1]);
1064 // Get the optional parameters
1065 Standard_Integer aVersion = 2;
1066 Standard_Integer aType = 1;
1069 aVersion = Draw::Atoi(argv[3]);
1071 aType = Draw::Atoi(argv[4]);
1075 aVersion = Max(1, aVersion);
1076 aVersion = Min(2, aVersion);
1077 aType = Max(0, aType);
1078 aType = Min(2, aType);
1080 VrmlAPI_Writer writer;
1084 case 0: writer.SetRepresentation(VrmlAPI_ShadedRepresentation); break;
1085 case 1: writer.SetRepresentation(VrmlAPI_WireFrameRepresentation); break;
1086 case 2: writer.SetRepresentation(VrmlAPI_BothRepresentation); break;
1089 if (!writer.Write(aShape, argv[2], aVersion))
1091 di << "Error: File " << argv[2] << " was not written\n";
1097 //=======================================================================
1098 //function : loadvrml
1100 //=======================================================================
1102 static Standard_Integer loadvrml
1103 (Draw_Interpretor& di, Standard_Integer argc, const char** argv)
1105 if (argc<3) di << "wrong number of parameters" << "\n";
1107 TopoDS_Shape aShape ;
1108 VrmlData_DataMapOfShapeAppearance aShapeAppMap;
1110 //-----------------------------------------------------------
1112 std::istream aStream (&aFic);
1114 if (aFic.open(argv[2], std::ios::in)) {
1116 // Get path of the VRML file.
1117 OSD_Path aPath(argv[2]);
1118 TCollection_AsciiString aVrmlDir(".");
1119 TCollection_AsciiString aDisk = aPath.Disk();
1120 TCollection_AsciiString aTrek = aPath.Trek();
1121 if (!aTrek.IsEmpty())
1123 if (!aDisk.IsEmpty())
1127 aTrek.ChangeAll('|', '/');
1131 VrmlData_Scene aScene;
1132 XSAlgo::AlgoContainer()->PrepareForTransfer(); // update unit info
1133 Standard_Real anOCCUnitMM = UnitsMethods::GetCasCadeLengthUnit();
1134 aScene.SetLinearScale(1000. / anOCCUnitMM);
1136 aScene.SetVrmlDir (aVrmlDir);
1138 const char * aStr = 0L;
1139 switch (aScene.Status()) {
1141 case VrmlData_StatusOK:
1143 aShape = aScene.GetShape(aShapeAppMap);
1146 case VrmlData_EmptyData: aStr = "EmptyData"; break;
1147 case VrmlData_UnrecoverableError: aStr = "UnrecoverableError"; break;
1148 case VrmlData_GeneralError: aStr = "GeneralError"; break;
1149 case VrmlData_EndOfFile: aStr = "EndOfFile"; break;
1150 case VrmlData_NotVrmlFile: aStr = "NotVrmlFile"; break;
1151 case VrmlData_CannotOpenFile: aStr = "CannotOpenFile"; break;
1152 case VrmlData_VrmlFormatError: aStr = "VrmlFormatError"; break;
1153 case VrmlData_NumericInputError: aStr = "NumericInputError"; break;
1154 case VrmlData_IrrelevantNumber: aStr = "IrrelevantNumber"; break;
1155 case VrmlData_BooleanInputError: aStr = "BooleanInputError"; break;
1156 case VrmlData_StringInputError: aStr = "StringInputError"; break;
1157 case VrmlData_NodeNameUnknown: aStr = "NodeNameUnknown"; break;
1158 case VrmlData_NonPositiveSize: aStr = "NonPositiveSize"; break;
1159 case VrmlData_ReadUnknownNode: aStr = "ReadUnknownNode"; break;
1160 case VrmlData_NonSupportedFeature: aStr = "NonSupportedFeature"; break;
1161 case VrmlData_OutputStreamUndefined:aStr = "OutputStreamUndefined"; break;
1162 case VrmlData_NotImplemented: aStr = "NotImplemented"; break;
1167 di << " ++ VRML Error: " << aStr << " in line "
1168 << aScene.GetLineError() << "\n";
1171 DBRep::Set(argv[1],aShape);
1175 di << "cannot open file\n";
1179 //-----------------------------------------------------------
1184 //-----------------------------------------------------------------------------
1185 static Standard_Integer createmesh
1186 (Draw_Interpretor& di, Standard_Integer argc, const char** argv )
1190 di << "Wrong number of parameters\n";
1191 di << "Use: " << argv[0] << " <mesh name> <stl file>\n";
1195 Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
1196 if (aContext.IsNull())
1198 di << "No active view. Please call 'vinit' first\n";
1202 // Progress indicator
1203 OSD_Path aFile( argv[2] );
1204 Handle(Draw_ProgressIndicator) aProgress = new Draw_ProgressIndicator (di, 1);
1205 Handle(Poly_Triangulation) aSTLMesh = RWStl::ReadFile (aFile, aProgress->Start());
1207 di << "Reading OK...\n";
1208 Handle( XSDRAWSTLVRML_DataSource ) aDS = new XSDRAWSTLVRML_DataSource( aSTLMesh );
1209 di << "Data source is created successful\n";
1210 Handle( MeshVS_Mesh ) aMesh = new MeshVS_Mesh();
1211 di << "MeshVS_Mesh is created successful\n";
1213 aMesh->SetDataSource( aDS );
1214 aMesh->AddBuilder( new MeshVS_MeshPrsBuilder( aMesh.operator->() ), Standard_True );
1216 aMesh->GetDrawer()->SetColor( MeshVS_DA_EdgeColor, Quantity_NOC_YELLOW );
1218 // Hide all nodes by default
1219 Handle(TColStd_HPackedMapOfInteger) aNodes = new TColStd_HPackedMapOfInteger();
1220 const Standard_Integer aLen = aSTLMesh->NbNodes();
1221 for ( Standard_Integer anIndex = 1; anIndex <= aLen; anIndex++ )
1222 aNodes->ChangeMap().Add( anIndex );
1223 aMesh->SetHiddenNodes( aNodes );
1224 aMesh->SetSelectableNodes ( aNodes );
1226 VDisplayAISObject(argv[1], aMesh);
1227 aContext->Deactivate( aMesh );
1229 Draw::Set( argv[1], new XSDRAWSTLVRML_DrawableMesh( aMesh ) );
1230 Handle( V3d_View ) aView = ViewerTest::CurrentView();
1231 if ( !aView.IsNull() )
1236 //-----------------------------------------------------------------------------
1238 static Standard_Integer create3d
1239 (Draw_Interpretor& di, Standard_Integer argc, const char** argv )
1243 di << "Wrong number of parameters\n";
1244 di << "Use: " << argv[0] << " <mesh name>\n";
1248 Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
1249 if (aContext.IsNull())
1251 di << "No active view. Please call 'vinit' first\n";
1255 Handle( XSDRAWSTLVRML_DataSource3D ) aDS = new XSDRAWSTLVRML_DataSource3D();
1256 di << "Data source is created successful\n";
1257 Handle( MeshVS_Mesh ) aMesh = new MeshVS_Mesh();
1258 di << "MeshVS_Mesh is created successful\n";
1260 aMesh->SetDataSource( aDS );
1261 aMesh->AddBuilder( new MeshVS_MeshPrsBuilder( aMesh.operator->() ), Standard_True );
1263 aMesh->GetDrawer()->SetColor( MeshVS_DA_EdgeColor, Quantity_NOC_YELLOW );
1265 // Hide all nodes by default
1266 Handle(TColStd_HPackedMapOfInteger) aNodes = new TColStd_HPackedMapOfInteger();
1267 Standard_Integer aLen = aDS->GetAllNodes().Extent();
1268 for ( Standard_Integer anIndex = 1; anIndex <= aLen; anIndex++ )
1269 aNodes->ChangeMap().Add( anIndex );
1270 aMesh->SetHiddenNodes( aNodes );
1271 aMesh->SetSelectableNodes ( aNodes );
1273 VDisplayAISObject(argv[1], aMesh);
1274 aContext->Deactivate( aMesh );
1276 Draw::Set( argv[1], new XSDRAWSTLVRML_DrawableMesh( aMesh ) );
1277 Handle( V3d_View ) aView = ViewerTest::CurrentView();
1278 if ( !aView.IsNull() )
1284 Handle( MeshVS_Mesh ) getMesh( const char* theName, Draw_Interpretor& di)
1286 Handle( XSDRAWSTLVRML_DrawableMesh ) aDrawMesh =
1287 Handle( XSDRAWSTLVRML_DrawableMesh )::DownCast( Draw::Get( theName ) );
1289 if( aDrawMesh.IsNull() )
1291 di << "There is no such object\n";
1296 Handle( MeshVS_Mesh ) aMesh = aDrawMesh->GetMesh();
1297 if( aMesh.IsNull() )
1299 di << "There is invalid mesh\n";
1307 //-----------------------------------------------------------------------------
1308 static Standard_Integer setcolor
1309 (Draw_Interpretor& di, Standard_Integer argc, const char** argv, Standard_Integer theParam )
1312 di << "Wrong number of parameters\n";
1315 Handle( MeshVS_Mesh ) aMesh = getMesh( argv[1], di );
1316 if( !aMesh.IsNull() )
1318 Standard_Real aRed = Draw::Atof (argv[2]);
1319 Standard_Real aGreen = Draw::Atof (argv[3]);
1320 Standard_Real aBlue = Draw::Atof (argv[4]);
1321 aMesh->GetDrawer()->SetColor( (MeshVS_DrawerAttribute)theParam,
1322 Quantity_Color( aRed, aGreen, aBlue, Quantity_TOC_RGB ) );
1324 Handle( AIS_InteractiveContext ) aContext = ViewerTest::GetAISContext();
1326 if( aContext.IsNull() )
1327 di << "The context is null\n";
1329 aContext->Redisplay (aMesh, Standard_True);
1334 //-----------------------------------------------------------------------------
1335 static Standard_Integer meshcolor
1336 (Draw_Interpretor& theInterp, Standard_Integer argc, const char** argv )
1338 return setcolor( theInterp, argc, argv, MeshVS_DA_InteriorColor );
1340 //-----------------------------------------------------------------------------
1341 static Standard_Integer linecolor
1342 (Draw_Interpretor& theInterp, Standard_Integer argc, const char** argv )
1344 return setcolor( theInterp, argc, argv, MeshVS_DA_EdgeColor );
1346 //-----------------------------------------------------------------------------
1347 static Standard_Integer meshmat
1348 (Draw_Interpretor& di, Standard_Integer argc, const char** argv )
1351 di << "Wrong number of parameters\n";
1354 Handle( MeshVS_Mesh ) aMesh = getMesh( argv[1], di );
1355 if( !aMesh.IsNull() )
1357 Standard_Integer aMaterial = Draw::Atoi (argv[2]);
1359 Graphic3d_MaterialAspect aMatAsp =
1360 (Graphic3d_MaterialAspect)(Graphic3d_NameOfMaterial)aMaterial;
1364 Standard_Real aTransparency = Draw::Atof(argv[3]);
1365 aMatAsp.SetTransparency (Standard_ShortReal (aTransparency));
1367 aMesh->GetDrawer()->SetMaterial( MeshVS_DA_FrontMaterial, aMatAsp );
1368 aMesh->GetDrawer()->SetMaterial( MeshVS_DA_BackMaterial, aMatAsp );
1370 Handle( AIS_InteractiveContext ) aContext = ViewerTest::GetAISContext();
1372 if( aContext.IsNull() )
1373 di << "The context is null\n";
1375 aContext->Redisplay (aMesh, Standard_True);
1380 //-----------------------------------------------------------------------------
1381 static Standard_Integer shrink
1382 (Draw_Interpretor& di, Standard_Integer argc, const char** argv )
1385 di << "Wrong number of parameters\n";
1388 Handle( MeshVS_Mesh ) aMesh = getMesh( argv[1], di );
1389 if( !aMesh.IsNull() )
1391 Standard_Real aShrinkCoeff = Draw::Atof (argv[2]);
1392 aMesh->GetDrawer()->SetDouble( MeshVS_DA_ShrinkCoeff, aShrinkCoeff );
1394 Handle( AIS_InteractiveContext ) aContext = ViewerTest::GetAISContext();
1396 if( aContext.IsNull() )
1397 di << "The context is null\n";
1399 aContext->Redisplay (aMesh, Standard_True);
1405 //-----------------------------------------------------------------------------
1406 static Standard_Integer closed (Draw_Interpretor& theDI, Standard_Integer theArgc, const char** theArgv)
1410 theDI << "Wrong number of parameters.\n";
1414 Handle(MeshVS_Mesh) aMesh = getMesh (theArgv[1], theDI);
1415 if (!aMesh.IsNull())
1417 Standard_Boolean aFlag = Draw::Atoi (theArgv[2]) != 0;
1418 aMesh->GetDrawer()->SetBoolean (MeshVS_DA_SupressBackFaces, aFlag);
1420 Handle( AIS_InteractiveContext ) aContext = ViewerTest::GetAISContext();
1421 if (aContext.IsNull())
1423 theDI << "The context is null\n";
1427 aContext->Redisplay (aMesh, Standard_True);
1434 //-----------------------------------------------------------------------------
1436 static Standard_Integer mdisplay
1437 (Draw_Interpretor& di, Standard_Integer argc, const char** argv )
1440 di << "Wrong number of parameters\n";
1443 Handle( MeshVS_Mesh ) aMesh = getMesh( argv[1], di );
1444 if( !aMesh.IsNull() )
1446 Handle( AIS_InteractiveContext ) aContext = ViewerTest::GetAISContext();
1448 if( aContext.IsNull() )
1449 di << "The context is null\n";
1452 aContext->Display (aMesh, Standard_True);
1458 //-----------------------------------------------------------------------------
1459 static Standard_Integer merase
1460 (Draw_Interpretor& di, Standard_Integer argc, const char** argv )
1463 di << "Wrong number of parameters\n";
1466 Handle( MeshVS_Mesh ) aMesh = getMesh( argv[1], di );
1467 if( !aMesh.IsNull() )
1469 Handle( AIS_InteractiveContext ) aContext = ViewerTest::GetAISContext();
1471 if( aContext.IsNull() )
1472 di << "The context is null\n";
1475 aContext->Erase (aMesh, Standard_True);
1479 di << "Mesh is null\n";
1483 //-----------------------------------------------------------------------------
1484 static Standard_Integer hidesel
1485 (Draw_Interpretor& di, Standard_Integer argc, const char** argv )
1489 di << "Wrong number of parameters\n";
1490 di << "Use: " << argv[0] << " <mesh name>\n";
1494 Handle( AIS_InteractiveContext ) aContext = ViewerTest::GetAISContext();
1495 Handle( MeshVS_Mesh ) aMesh = getMesh( argv[1], di );
1496 if( aMesh.IsNull() )
1498 di << "The mesh is invalid\n";
1502 if( aContext.IsNull() )
1503 di << "The context is null\n";
1506 Handle(TColStd_HPackedMapOfInteger) aHiddenNodes = aMesh->GetHiddenNodes();
1507 if (aHiddenNodes.IsNull())
1509 aHiddenNodes = new TColStd_HPackedMapOfInteger();
1511 Handle(TColStd_HPackedMapOfInteger) aHiddenElements = aMesh->GetHiddenElems();
1512 if (aHiddenElements.IsNull())
1514 aHiddenElements = new TColStd_HPackedMapOfInteger();
1516 for( aContext->InitSelected(); aContext->MoreSelected(); aContext->NextSelected() )
1518 Handle( MeshVS_MeshEntityOwner ) anOwner =
1519 Handle( MeshVS_MeshEntityOwner )::DownCast( aContext->SelectedOwner() );
1520 if( !anOwner.IsNull() )
1522 if( anOwner->Type()==MeshVS_ET_Node )
1524 aHiddenNodes->ChangeMap().Add( anOwner->ID() );
1528 aHiddenElements->ChangeMap().Add( anOwner->ID() );
1532 aContext->ClearSelected (Standard_False);
1533 aMesh->SetHiddenNodes( aHiddenNodes );
1534 aMesh->SetHiddenElems( aHiddenElements );
1535 aContext->Redisplay (aMesh, Standard_True);
1540 //-----------------------------------------------------------------------------
1541 static Standard_Integer showonly
1542 (Draw_Interpretor& di, Standard_Integer argc, const char** argv )
1546 di << "Wrong number of parameters\n";
1547 di << "Use: " << argv[0] << " <mesh name>\n";
1552 Handle( AIS_InteractiveContext ) aContext = ViewerTest::GetAISContext();
1553 Handle( MeshVS_Mesh ) aMesh = getMesh( argv[1], di );
1554 if( aMesh.IsNull() )
1556 di << "The mesh is invalid\n";
1560 if( aContext.IsNull() )
1561 di << "The context is null\n";
1564 Handle(TColStd_HPackedMapOfInteger) aHiddenNodes =
1565 new TColStd_HPackedMapOfInteger(aMesh->GetDataSource()->GetAllNodes());
1566 Handle(TColStd_HPackedMapOfInteger) aHiddenElements =
1567 new TColStd_HPackedMapOfInteger(aMesh->GetDataSource()->GetAllElements());
1568 for( aContext->InitSelected(); aContext->MoreSelected(); aContext->NextSelected() )
1570 Handle( MeshVS_MeshEntityOwner ) anOwner =
1571 Handle( MeshVS_MeshEntityOwner )::DownCast( aContext->SelectedOwner() );
1572 if( !anOwner.IsNull() )
1574 if( anOwner->Type() == MeshVS_ET_Node )
1576 aHiddenNodes->ChangeMap().Remove( anOwner->ID() );
1580 aHiddenElements->ChangeMap().Remove( anOwner->ID() );
1584 aMesh->SetHiddenNodes( aHiddenNodes );
1585 aMesh->SetHiddenElems( aHiddenElements );
1586 aContext->Redisplay (aMesh, Standard_True);
1591 //-----------------------------------------------------------------------------
1592 static Standard_Integer showall
1593 (Draw_Interpretor& di, Standard_Integer argc, const char** argv )
1597 di << "Wrong number of parameters\n";
1598 di << "Use: " << argv[0] << " <mesh name>\n";
1602 Handle( AIS_InteractiveContext ) aContext = ViewerTest::GetAISContext();
1603 Handle( MeshVS_Mesh ) aMesh = getMesh( argv[1], di );
1604 if( aMesh.IsNull() )
1606 di << "The mesh is invalid\n";
1610 if( aContext.IsNull() )
1611 di << "The context is null\n";
1614 aMesh->SetHiddenNodes( new TColStd_HPackedMapOfInteger() );
1615 aMesh->SetHiddenElems( new TColStd_HPackedMapOfInteger() );
1616 aContext->Redisplay (aMesh, Standard_True);
1622 //-----------------------------------------------------------------------------
1623 static Standard_Integer meshcolors( Draw_Interpretor& di,
1624 Standard_Integer argc,
1632 di << "Wrong number of parameters\n";
1633 di << "Use : meshcolors <mesh name> <mode> <isreflect>\n";
1634 di << "mode : {elem1|elem2|nodal|nodaltex|none}\n";
1635 di << " elem1 - different color for each element\n";
1636 di << " elem2 - one color for one side\n";
1637 di << " nodal - different color for each node\n";
1638 di << " nodaltex - different color for each node with texture interpolation\n";
1639 di << " none - clear\n";
1640 di << "isreflect : {0|1} \n";
1645 Handle( MeshVS_Mesh ) aMesh = getMesh( argv[ 1 ], di );
1647 if ( aMesh.IsNull() )
1649 di << "Mesh not found\n";
1652 Handle(AIS_InteractiveContext) anIC = ViewerTest::GetAISContext();
1653 if ( anIC.IsNull() )
1655 di << "The context is null\n";
1658 if( !aMesh.IsNull() )
1660 TCollection_AsciiString aMode = TCollection_AsciiString (argv[2]);
1661 Quantity_Color aColor1(Quantity_NOC_BLUE1);
1662 Quantity_Color aColor2(Quantity_NOC_RED1);
1663 if( aMode.IsEqual("elem1") || aMode.IsEqual("elem2") || aMode.IsEqual("nodal") || aMode.IsEqual("nodaltex") || aMode.IsEqual("none") )
1665 Handle(MeshVS_PrsBuilder) aTempBuilder;
1666 Standard_Integer aReflection = Draw::Atoi(argv[3]);
1668 for (Standard_Integer aCount = 0 ; aCount < aMesh->GetBuildersCount(); aCount++ ){
1669 aTempBuilder = aMesh->FindBuilder("MeshVS_ElementalColorPrsBuilder");
1670 if( !aTempBuilder.IsNull())
1671 aMesh->RemoveBuilderById(aTempBuilder->GetId());
1673 aTempBuilder = aMesh->FindBuilder("MeshVS_NodalColorPrsBuilder");
1674 if( !aTempBuilder.IsNull())
1675 aMesh->RemoveBuilderById(aTempBuilder->GetId());
1678 if( aMode.IsEqual("elem1") || aMode.IsEqual("elem2") )
1680 Handle(MeshVS_ElementalColorPrsBuilder) aBuilder = new MeshVS_ElementalColorPrsBuilder(
1681 aMesh, MeshVS_DMF_ElementalColorDataPrs | MeshVS_DMF_OCCMask );
1683 const TColStd_PackedMapOfInteger& anAllElements = aMesh->GetDataSource()->GetAllElements();
1684 TColStd_MapIteratorOfPackedMapOfInteger anIter( anAllElements );
1686 if( aMode.IsEqual("elem1") )
1687 for ( ; anIter.More(); anIter.Next() )
1689 Quantity_Color aColor( (Quantity_NameOfColor)( anIter.Key() % Quantity_NOC_WHITE ) );
1690 aBuilder->SetColor1( anIter.Key(), aColor );
1693 for ( ; anIter.More(); anIter.Next() )
1694 aBuilder->SetColor2( anIter.Key(), aColor1, aColor2 );
1696 aMesh->AddBuilder( aBuilder, Standard_True );
1700 if( aMode.IsEqual("nodal") )
1702 Handle(MeshVS_NodalColorPrsBuilder) aBuilder = new MeshVS_NodalColorPrsBuilder(
1703 aMesh, MeshVS_DMF_NodalColorDataPrs | MeshVS_DMF_OCCMask );
1704 aMesh->AddBuilder( aBuilder, Standard_True );
1707 const TColStd_PackedMapOfInteger& anAllNodes =
1708 aMesh->GetDataSource()->GetAllNodes();
1709 TColStd_MapIteratorOfPackedMapOfInteger anIter( anAllNodes );
1710 for ( ; anIter.More(); anIter.Next() )
1712 Quantity_Color aColor( (Quantity_NameOfColor)(
1713 anIter.Key() % Quantity_NOC_WHITE ) );
1714 aBuilder->SetColor( anIter.Key(), aColor );
1716 aMesh->AddBuilder( aBuilder, Standard_True );
1719 if(aMode.IsEqual("nodaltex"))
1721 // assign nodal builder to the mesh
1722 Handle(MeshVS_NodalColorPrsBuilder) aBuilder = new MeshVS_NodalColorPrsBuilder(
1723 aMesh, MeshVS_DMF_NodalColorDataPrs | MeshVS_DMF_OCCMask);
1724 aMesh->AddBuilder(aBuilder, Standard_True);
1725 aBuilder->UseTexture(Standard_True);
1727 // prepare color map for texture
1728 Aspect_SequenceOfColor aColorMap;
1729 aColorMap.Append((Quantity_NameOfColor) Quantity_NOC_RED);
1730 aColorMap.Append((Quantity_NameOfColor) Quantity_NOC_YELLOW);
1731 aColorMap.Append((Quantity_NameOfColor) Quantity_NOC_BLUE1);
1733 // prepare scale map for mesh - it will be assigned to mesh as texture coordinates
1734 // make mesh color interpolated from minimum X coord to maximum X coord
1735 Handle(MeshVS_DataSource) aDataSource = aMesh->GetDataSource();
1736 Standard_Real aMinX, aMinY, aMinZ, aMaxX, aMaxY, aMaxZ;
1738 // get bounding box for calculations
1739 aDataSource->GetBoundingBox().Get(aMinX, aMinY, aMinZ, aMaxX, aMaxY, aMaxZ);
1740 Standard_Real aDelta = aMaxX - aMinX;
1742 // assign color scale map values (0..1) to nodes
1743 TColStd_DataMapOfIntegerReal aScaleMap;
1744 TColStd_Array1OfReal aCoords(1, 3);
1745 Standard_Integer aNbNodes;
1746 MeshVS_EntityType aType;
1749 const TColStd_PackedMapOfInteger& anAllNodes =
1750 aMesh->GetDataSource()->GetAllNodes();
1751 TColStd_MapIteratorOfPackedMapOfInteger anIter(anAllNodes);
1752 for (; anIter.More(); anIter.Next())
1754 //get node coordinates to aCoord variable
1755 aDataSource->GetGeom(anIter.Key(), Standard_False, aCoords, aNbNodes, aType);
1757 Standard_Real aScaleValue;
1760 aScaleValue = (aCoords.Value(1) - (Standard_Real) aMinX) / aDelta;
1761 } catch(Standard_Failure const&) {
1765 aScaleMap.Bind(anIter.Key(), aScaleValue);
1768 //set color map for builder and a color for invalid scale value
1769 aBuilder->SetColorMap(aColorMap);
1770 aBuilder->SetInvalidColor(Quantity_NOC_BLACK);
1771 aBuilder->SetTextureCoords(aScaleMap);
1772 aMesh->AddBuilder(aBuilder, Standard_True);
1775 aMesh->GetDrawer()->SetBoolean (MeshVS_DA_ColorReflection, aReflection != 0);
1777 anIC->Redisplay (aMesh, Standard_True);
1781 di << "Wrong mode name\n";
1786 catch ( Standard_Failure const& )
1793 //-----------------------------------------------------------------------------
1794 static Standard_Integer meshvectors( Draw_Interpretor& di,
1795 Standard_Integer argc,
1800 di << "Wrong number of parameters\n";
1801 di << "Use : meshvectors <mesh name> < -mode {elem|nodal|none} > [-maxlen len] [-color name] [-arrowpart ratio] [-issimple {1|0}]\n";
1802 di << "Supported mode values:\n";
1803 di << " elem - vector per element\n";
1804 di << " nodal - vector per node\n";
1805 di << " none - clear\n";
1810 Handle( MeshVS_Mesh ) aMesh = getMesh( argv[ 1 ], di );
1812 if ( aMesh.IsNull() )
1814 di << "Mesh not found\n";
1817 Handle(AIS_InteractiveContext) anIC = ViewerTest::GetAISContext();
1818 if ( anIC.IsNull() )
1820 di << "The context is null\n";
1824 TCollection_AsciiString aParam;
1825 TCollection_AsciiString aMode("none");
1826 Standard_Real aMaxlen(1.0);
1827 Quantity_Color aColor(Quantity_NOC_ORANGE);
1828 Standard_Real anArrowPart(0.1);
1829 Standard_Boolean isSimplePrs(Standard_False);
1831 for (Standard_Integer anIdx = 2; anIdx < argc; anIdx++)
1833 if (!aParam.IsEmpty())
1835 if (aParam == "-mode")
1837 aMode = argv[anIdx];
1839 else if (aParam == "-maxlen")
1841 aMaxlen = Draw::Atof(argv[anIdx]);
1843 else if (aParam == "-color")
1845 if (!Quantity_Color::ColorFromName (argv[anIdx], aColor))
1847 Message::SendFail() << "Syntax error at " << aParam;
1851 else if (aParam == "-arrowpart")
1853 anArrowPart = Draw::Atof(argv[anIdx]);
1855 else if (aParam == "-issimple")
1857 isSimplePrs = Draw::Atoi(argv[anIdx]) != 0;
1861 else if (argv[anIdx][0] == '-')
1863 aParam = argv[anIdx];
1867 if( !aMode.IsEqual("elem") && !aMode.IsEqual("nodal") && !aMode.IsEqual("none") )
1869 di << "Wrong mode name\n";
1873 Handle(MeshVS_PrsBuilder) aTempBuilder;
1875 aTempBuilder = aMesh->FindBuilder("MeshVS_VectorPrsBuilder");
1876 if( !aTempBuilder.IsNull())
1877 aMesh->RemoveBuilderById(aTempBuilder->GetId());
1879 if( !aMode.IsEqual("none") )
1881 Handle(MeshVS_VectorPrsBuilder) aBuilder = new MeshVS_VectorPrsBuilder( aMesh.operator->(),
1884 MeshVS_DMF_VectorDataPrs,
1890 Standard_Boolean anIsElement = aMode.IsEqual("elem");
1891 const TColStd_PackedMapOfInteger& anAllIDs = anIsElement ? aMesh->GetDataSource()->GetAllElements() :
1892 aMesh->GetDataSource()->GetAllNodes();
1894 Standard_Integer aNbNodes;
1895 MeshVS_EntityType aEntType;
1897 TColStd_Array1OfReal aCoords(1, 3);
1899 TColStd_MapIteratorOfPackedMapOfInteger anIter( anAllIDs );
1900 for ( ; anIter.More(); anIter.Next() )
1902 Standard_Boolean IsValidData = Standard_False;
1904 aMesh->GetDataSource()->GetGeomType(anIter.Key(), anIsElement, aEntType);
1905 if (aEntType == MeshVS_ET_Face)
1906 IsValidData = aMesh->GetDataSource()->GetNormal(anIter.Key(), 3, aCoords.ChangeValue(1), aCoords.ChangeValue(2), aCoords.ChangeValue(3));
1908 IsValidData = aMesh->GetDataSource()->GetGeom(anIter.Key(), Standard_False, aCoords, aNbNodes, aEntType);
1913 aNorm = gp_Vec(aCoords.Value(1), aCoords.Value(2), aCoords.Value(3));
1914 if(aNorm.Magnitude() < gp::Resolution())
1916 aNorm = gp_Vec(0,0,1); //method GetGeom(...) returns coordinates of nodes
1921 aNorm = gp_Vec(0,0,1);
1923 aBuilder->SetVector(anIsElement, anIter.Key(), aNorm.Normalized());
1926 aMesh->AddBuilder( aBuilder, Standard_False );
1927 aMesh->GetDrawer()->SetDouble ( MeshVS_DA_VectorArrowPart, anArrowPart );
1930 anIC->Redisplay (aMesh, Standard_True);
1934 //-----------------------------------------------------------------------------
1936 static Standard_Integer meshtext( Draw_Interpretor& di,
1937 Standard_Integer argc,
1942 di << "Wrong number of parameters\n";
1943 di << "Use : meshtext <mesh name>\n";
1947 Handle( MeshVS_Mesh ) aMesh = getMesh( argv[ 1 ], di );
1949 if ( aMesh.IsNull() )
1951 di << "Mesh not found\n";
1955 Handle(AIS_InteractiveContext) anIC = ViewerTest::GetAISContext();
1956 if ( anIC.IsNull() )
1958 di << "The context is null\n";
1962 // Prepare triangle labels
1963 MeshVS_DataMapOfIntegerAsciiString aLabels;
1964 Standard_Integer aLen = aMesh->GetDataSource()->GetAllElements().Extent();
1965 for ( Standard_Integer anIndex = 1; anIndex <= aLen; anIndex++ ){
1966 aLabels.Bind( anIndex, TCollection_AsciiString( anIndex ) );
1969 Handle(MeshVS_TextPrsBuilder) aTextBuilder = new MeshVS_TextPrsBuilder( aMesh.operator->(), 20., Quantity_NOC_YELLOW );
1970 aTextBuilder->SetTexts( Standard_True, aLabels );
1971 aMesh->AddBuilder( aTextBuilder );
1976 static Standard_Integer meshdeform( Draw_Interpretor& di,
1977 Standard_Integer argc,
1982 di << "Wrong number of parameters\n";
1983 di << "Use : meshdeform <mesh name> < -mode {on|off} > [-scale scalefactor]\n";
1987 Handle( MeshVS_Mesh ) aMesh = getMesh( argv[ 1 ], di );
1989 if ( aMesh.IsNull() )
1991 di << "Mesh not found\n";
1994 Handle(AIS_InteractiveContext) anIC = ViewerTest::GetAISContext();
1995 if ( anIC.IsNull() )
1997 di << "The context is null\n";
2001 TCollection_AsciiString aParam;
2002 TCollection_AsciiString aMode("off");
2003 Standard_Real aScale(1.0);
2005 for (Standard_Integer anIdx = 2; anIdx < argc; anIdx++)
2007 if (!aParam.IsEmpty())
2009 if (aParam == "-mode")
2011 aMode = argv[anIdx];
2013 else if (aParam == "-scale")
2015 aScale = Draw::Atof(argv[anIdx]);
2019 else if (argv[anIdx][0] == '-')
2021 aParam = argv[anIdx];
2025 if(!aMode.IsEqual("on") && !aMode.IsEqual("off"))
2027 di << "Wrong mode name\n";
2031 Handle ( MeshVS_DeformedDataSource ) aDefDS =
2032 new MeshVS_DeformedDataSource( aMesh->GetDataSource() , aScale );
2034 const TColStd_PackedMapOfInteger& anAllIDs = aMesh->GetDataSource()->GetAllNodes();
2036 Standard_Integer aNbNodes;
2037 MeshVS_EntityType aEntType;
2039 TColStd_MapIteratorOfPackedMapOfInteger anIter( anAllIDs );
2040 for ( ; anIter.More(); anIter.Next() )
2042 TColStd_Array1OfReal aCoords(1, 3);
2043 aMesh->GetDataSource()->GetGeom(anIter.Key(), Standard_False, aCoords, aNbNodes, aEntType);
2045 gp_Vec aNorm = gp_Vec(aCoords.Value(1), aCoords.Value(2), aCoords.Value(3));
2046 if( !aNorm.Magnitude() )
2047 aNorm = gp_Vec(0,0,1);
2048 aDefDS->SetVector(anIter.Key(), aNorm.Normalized());
2051 aMesh->SetDataSource(aDefDS);
2053 anIC->Redisplay (aMesh, Standard_False);
2055 Handle( V3d_View ) aView = ViewerTest::CurrentView();
2056 if ( !aView.IsNull() )
2062 static Standard_Integer mesh_edge_width( Draw_Interpretor& di,
2063 Standard_Integer argc,
2071 di << "Wrong number of parameters\n";
2072 di << "Use : mesh_edge_width <mesh name> <width>\n";
2076 Handle(MeshVS_Mesh) aMesh = getMesh( argv[ 1 ], di );
2077 if ( aMesh.IsNull() )
2079 di << "Mesh not found\n";
2083 const char* aWidthStr = argv[ 2 ];
2084 if ( aWidthStr == 0 || Draw::Atof( aWidthStr ) <= 0 )
2086 di << "Width must be real value more than zero\n";
2090 double aWidth = Draw::Atof( aWidthStr );
2092 Handle(AIS_InteractiveContext) anIC = ViewerTest::GetAISContext();
2093 if ( anIC.IsNull() )
2095 di << "The context is null\n";
2099 Handle(MeshVS_Drawer) aDrawer = aMesh->GetDrawer();
2100 if ( aDrawer.IsNull() )
2102 di << "The drawer is null\n";
2106 aDrawer->SetDouble( MeshVS_DA_EdgeWidth, aWidth );
2107 anIC->Redisplay (aMesh, Standard_True);
2109 catch ( Standard_Failure const& )
2117 //-----------------------------------------------------------------------------
2119 static Standard_Integer meshinfo(Draw_Interpretor& di,
2120 Standard_Integer argc,
2125 di << "Wrong number of parameters. Use : meshinfo mesh\n";
2129 Handle(MeshVS_Mesh) aMesh = getMesh(argv[ 1 ], di);
2130 if ( aMesh.IsNull() )
2132 di << "Mesh not found\n";
2136 Handle(XSDRAWSTLVRML_DataSource) stlMeshSource = Handle(XSDRAWSTLVRML_DataSource)::DownCast(aMesh->GetDataSource());
2137 if (!stlMeshSource.IsNull())
2139 const TColStd_PackedMapOfInteger& nodes = stlMeshSource->GetAllNodes();
2140 const TColStd_PackedMapOfInteger& tris = stlMeshSource->GetAllElements();
2142 di << "Nb nodes = " << nodes.Extent() << "\n";
2143 di << "Nb triangles = " << tris.Extent() << "\n";
2149 //=======================================================================
2150 //function : writeply
2151 //purpose : write PLY file
2152 //=======================================================================
2153 static Standard_Integer WritePly (Draw_Interpretor& theDI,
2154 Standard_Integer theNbArgs,
2155 const char** theArgVec)
2157 Handle(TDocStd_Document) aDoc;
2158 Handle(TDocStd_Application) anApp = DDocStd::GetApplication();
2159 TCollection_AsciiString aShapeName, aFileName;
2161 Standard_Real aDist = 0.0;
2162 Standard_Real aDens = Precision::Infinite();
2163 Standard_Real aTol = Precision::Confusion();
2164 bool hasColors = true, hasNormals = true, hasTexCoords = false, hasPartId = true, hasFaceId = false;
2165 bool isPntSet = false, isDensityPoints = false;
2166 TColStd_IndexedDataMapOfStringString aFileInfo;
2167 for (Standard_Integer anArgIter = 1; anArgIter < theNbArgs; ++anArgIter)
2169 TCollection_AsciiString anArg (theArgVec[anArgIter]);
2171 if (anArg == "-normal")
2173 hasNormals = Draw::ParseOnOffIterator (theNbArgs, theArgVec, anArgIter);
2175 else if (anArg == "-nonormal")
2177 hasNormals = !Draw::ParseOnOffIterator (theNbArgs, theArgVec, anArgIter);
2179 else if (anArg == "-color"
2180 || anArg == "-nocolor"
2181 || anArg == "-colors"
2182 || anArg == "-nocolors")
2184 hasColors = Draw::ParseOnOffNoIterator (theNbArgs, theArgVec, anArgIter);
2186 else if (anArg == "-uv"
2187 || anArg == "-nouv")
2189 hasTexCoords = Draw::ParseOnOffNoIterator (theNbArgs, theArgVec, anArgIter);
2191 else if (anArg == "-partid")
2193 hasPartId = Draw::ParseOnOffNoIterator (theNbArgs, theArgVec, anArgIter);
2194 hasFaceId = hasFaceId && !hasPartId;
2196 else if (anArg == "-surfid"
2197 || anArg == "-surfaceid"
2198 || anArg == "-faceid")
2200 hasFaceId = Draw::ParseOnOffNoIterator (theNbArgs, theArgVec, anArgIter);
2201 hasPartId = hasPartId && !hasFaceId;
2203 else if (anArg == "-pntset"
2204 || anArg == "-pntcloud"
2205 || anArg == "-pointset"
2206 || anArg == "-pointcloud"
2207 || anArg == "-cloud"
2208 || anArg == "-points")
2210 isPntSet = Draw::ParseOnOffIterator (theNbArgs, theArgVec, anArgIter);
2212 else if ((anArg == "-dist"
2213 || anArg == "-distance")
2214 && anArgIter + 1 < theNbArgs
2215 && Draw::ParseReal (theArgVec[anArgIter + 1], aDist))
2221 theDI << "Syntax error: -distance value should be >= 0.0";
2224 aDist = Max (aDist, Precision::Confusion());
2226 else if ((anArg == "-dens"
2227 || anArg == "-density")
2228 && anArgIter + 1 < theNbArgs
2229 && Draw::ParseReal (theArgVec[anArgIter + 1], aDens))
2232 isDensityPoints = Standard_True;
2236 theDI << "Syntax error: -density value should be > 0.0";
2240 else if ((anArg == "-tol"
2241 || anArg == "-tolerance")
2242 && anArgIter + 1 < theNbArgs
2243 && Draw::ParseReal (theArgVec[anArgIter + 1], aTol))
2247 if (aTol < Precision::Confusion())
2249 theDI << "Syntax error: -tol value should be >= " << Precision::Confusion();
2253 else if (anArg == "-comments"
2254 && anArgIter + 1 < theNbArgs)
2256 aFileInfo.Add ("Comments", theArgVec[++anArgIter]);
2258 else if (anArg == "-author"
2259 && anArgIter + 1 < theNbArgs)
2261 aFileInfo.Add ("Author", theArgVec[++anArgIter]);
2263 else if (aDoc.IsNull())
2265 if (aShapeName.IsEmpty())
2267 aShapeName = theArgVec[anArgIter];
2270 Standard_CString aNameVar = theArgVec[anArgIter];
2271 DDocStd::GetDocument (aNameVar, aDoc, false);
2274 TopoDS_Shape aShape = DBRep::Get (aNameVar);
2275 if (!aShape.IsNull())
2277 anApp->NewDocument (TCollection_ExtendedString ("BinXCAF"), aDoc);
2278 Handle(XCAFDoc_ShapeTool) aShapeTool = XCAFDoc_DocumentTool::ShapeTool (aDoc->Main());
2279 aShapeTool->AddShape (aShape);
2283 else if (aFileName.IsEmpty())
2285 aFileName = theArgVec[anArgIter];
2289 theDI << "Syntax error at '" << theArgVec[anArgIter] << "'";
2294 && !aShapeName.IsEmpty())
2296 theDI << "Syntax error: '" << aShapeName << "' is not a shape nor document";
2299 else if (aDoc.IsNull()
2300 || aFileName.IsEmpty())
2302 theDI << "Syntax error: wrong number of arguments";
2306 TDF_LabelSequence aRootLabels;
2307 Handle(XCAFDoc_ShapeTool) aShapeTool = XCAFDoc_DocumentTool::ShapeTool (aDoc->Main());
2308 aShapeTool->GetFreeShapes (aRootLabels);
2309 if (aRootLabels.IsEmpty())
2311 theDI << "Error: empty document";
2317 class PointCloudPlyWriter : public BRepLib_PointCloudShape, public RWPly_PlyWriterContext
2320 PointCloudPlyWriter (Standard_Real theTol)
2321 : BRepLib_PointCloudShape (TopoDS_Shape(), theTol) {}
2323 void AddFaceColor (const TopoDS_Shape& theFace, const Graphic3d_Vec4ub& theColor)
2324 { myFaceColor.Bind (theFace, theColor); }
2327 virtual void addPoint (const gp_Pnt& thePoint,
2328 const gp_Vec& theNorm,
2329 const gp_Pnt2d& theUV,
2330 const TopoDS_Shape& theFace)
2332 Graphic3d_Vec4ub aColor;
2333 myFaceColor.Find (theFace, aColor);
2334 RWPly_PlyWriterContext::WriteVertex (thePoint,
2335 Graphic3d_Vec3 ((float )theNorm.X(), (float )theNorm.Y(), (float )theNorm.Z()),
2336 Graphic3d_Vec2 ((float )theUV.X(), (float )theUV.Y()),
2341 NCollection_DataMap<TopoDS_Shape, Graphic3d_Vec4ub> myFaceColor;
2344 PointCloudPlyWriter aPlyCtx (aTol);
2345 aPlyCtx.SetNormals (hasNormals);
2346 aPlyCtx.SetColors (hasColors);
2347 aPlyCtx.SetTexCoords (hasTexCoords);
2349 TopoDS_Compound aComp;
2350 BRep_Builder().MakeCompound (aComp);
2351 for (XCAFPrs_DocumentExplorer aDocExplorer (aDoc, aRootLabels, XCAFPrs_DocumentExplorerFlags_OnlyLeafNodes);
2352 aDocExplorer.More(); aDocExplorer.Next())
2354 const XCAFPrs_DocumentNode& aDocNode = aDocExplorer.Current();
2355 for (RWMesh_FaceIterator aFaceIter (aDocNode.RefLabel, aDocNode.Location, true, aDocNode.Style); aFaceIter.More(); aFaceIter.Next())
2357 BRep_Builder().Add (aComp, aFaceIter.Face());
2358 Graphic3d_Vec4ub aColorVec (255);
2359 if (aFaceIter.HasFaceColor())
2361 Graphic3d_Vec4 aColorF = aFaceIter.FaceColor();
2362 aColorVec.SetValues ((unsigned char )int(aColorF.r() * 255.0f),
2363 (unsigned char )int(aColorF.g() * 255.0f),
2364 (unsigned char )int(aColorF.b() * 255.0f),
2365 (unsigned char )int(aColorF.a() * 255.0f));
2367 aPlyCtx.AddFaceColor (aFaceIter.Face(), aColorVec);
2370 aPlyCtx.SetShape (aComp);
2372 Standard_Integer aNbPoints = isDensityPoints
2373 ? aPlyCtx.NbPointsByDensity (aDens)
2374 : aPlyCtx.NbPointsByTriangulation();
2377 theDI << "Error: unable to generate points";
2381 if (!aPlyCtx.Open (aFileName)
2382 || !aPlyCtx.WriteHeader (aNbPoints, 0, TColStd_IndexedDataMapOfStringString()))
2384 theDI << "Error: unable to create file '" << aFileName << "'";
2388 Standard_Boolean isDone = isDensityPoints
2389 ? aPlyCtx.GeneratePointsByDensity (aDens)
2390 : aPlyCtx.GeneratePointsByTriangulation();
2393 theDI << "Error: Point cloud was not generated in file '" << aFileName << "'";
2395 else if (!aPlyCtx.Close())
2397 theDI << "Error: Point cloud file '" << aFileName << "' was not written";
2406 Handle(Draw_ProgressIndicator) aProgress = new Draw_ProgressIndicator (theDI, 1);
2407 RWPly_CafWriter aPlyCtx (aFileName);
2408 aPlyCtx.SetNormals (hasNormals);
2409 aPlyCtx.SetColors (hasColors);
2410 aPlyCtx.SetTexCoords (hasTexCoords);
2411 aPlyCtx.SetPartId (hasPartId);
2412 aPlyCtx.SetFaceId (hasFaceId);
2413 aPlyCtx.Perform (aDoc, aFileInfo, aProgress->Start());
2418 //-----------------------------------------------------------------------------
2420 void XSDRAWSTLVRML::InitCommands (Draw_Interpretor& theCommands)
2422 const char* g = "XSTEP-STL/VRML"; // Step transfer file commands
2423 //XSDRAW::LoadDraw(theCommands);
2425 theCommands.Add ("ReadGltf",
2426 "ReadGltf Doc file [-parallel {on|off}] [-listExternalFiles] [-noCreateDoc] [-doublePrecision {on|off}] [-assetInfo]"
2427 "\n\t\t: Read glTF file into XDE document."
2428 "\n\t\t: -listExternalFiles do not read mesh and only list external files"
2429 "\n\t\t: -noCreateDoc read into existing XDE document"
2430 "\n\t\t: -doublePrecision store triangulation with double or single floating point"
2431 "\n\t\t: precision (single by default)"
2432 "\n\t\t: -skipLateLoading data loading is skipped and can be performed later"
2433 "\n\t\t: (false by default)"
2434 "\n\t\t: -keepLate data is loaded into itself with preservation of information"
2435 "\n\t\t: about deferred storage to load/unload this data later."
2436 "\n\t\t: -allScenes load all scenes defined in the document instead of default one (false by default)"
2437 "\n\t\t: -toPrintDebugInfo print additional debug information during data reading"
2438 "\n\t\t: -assetInfo print asset information",
2439 __FILE__, ReadGltf, g);
2440 theCommands.Add ("readgltf",
2441 "readgltf shape file"
2442 "\n\t\t: Same as ReadGltf but reads glTF file into a shape instead of a document.",
2443 __FILE__, ReadGltf, g);
2444 theCommands.Add ("WriteGltf",
2445 "WriteGltf Doc file [-trsfFormat {compact|TRS|mat4}]=compact"
2446 "\n\t\t: [-systemCoordSys {Zup|Yup}]=Zup"
2447 "\n\t\t: [-comments Text] [-author Name]"
2448 "\n\t\t: [-forceUVExport]=0 [-texturesSeparate]=0 [-mergeFaces]=0 [-splitIndices16]=0"
2449 "\n\t\t: [-nodeNameFormat {empty|product|instance|instOrProd|prodOrInst|prodAndInst|verbose}]=instOrProd"
2450 "\n\t\t: [-meshNameFormat {empty|product|instance|instOrProd|prodOrInst|prodAndInst|verbose}]=product"
2451 "\n\t\t: [-draco]=0 [-compressionLevel {0-10}]=7 [-quantizePositionBits Value]=14 [-quantizeNormalBits Value]=10"
2452 "\n\t\t: [-quantizeTexcoordBits Value]=12 [-quantizeColorBits Value]=8 [-quantizeGenericBits Value]=12"
2453 "\n\t\t: [-unifiedQuantization]=0"
2454 "\n\t\t: Write XDE document into glTF file."
2455 "\n\t\t: -trsfFormat preferred transformation format"
2456 "\n\t\t: -systemCoordSys system coordinate system; Zup when not specified"
2457 "\n\t\t: -mergeFaces merge Faces within the same Mesh"
2458 "\n\t\t: -splitIndices16 split Faces to keep 16-bit indices when -mergeFaces is enabled"
2459 "\n\t\t: -forceUVExport always export UV coordinates"
2460 "\n\t\t: -texturesSeparate write textures to separate files"
2461 "\n\t\t: -nodeNameFormat name format for Nodes"
2462 "\n\t\t: -meshNameFormat name format for Meshes"
2463 "\n\t\t: -draco use Draco compression 3D geometric meshes"
2464 "\n\t\t: -compressionLevel draco compression level [0-10] (by default 7), a value of 0 will apply sequential encoding and preserve face order"
2465 "\n\t\t: -quantizePositionBits quantization bits for position attribute when using Draco compression (by default 14)"
2466 "\n\t\t: -quantizeNormalBits quantization bits for normal attribute when using Draco compression (by default 10)"
2467 "\n\t\t: -quantizeTexcoordBits quantization bits for texture coordinate attribute when using Draco compression (by default 12)"
2468 "\n\t\t: -quantizeColorBits quantization bits for color attribute when using Draco compression (by default 8)"
2469 "\n\t\t: -quantizeGenericBits quantization bits for skinning attribute (joint indices and joint weights)"
2470 "\n and custom attributes when using Draco compression (by default 12)"
2471 "\n\t\t: -unifiedQuantization quantization is applied on each primitive separately if this option is false",
2472 __FILE__, WriteGltf, g);
2473 theCommands.Add ("writegltf",
2474 "writegltf shape file",
2475 __FILE__, WriteGltf, g);
2476 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);
2477 theCommands.Add ("writestl", "shape file [ascii/binary (0/1) : 1 by default] [InParallel (0/1) : 0 by default]",__FILE__,writestl,g);
2478 theCommands.Add ("readstl",
2479 "readstl shape file [-brep] [-mergeAngle Angle] [-multi]"
2480 "\n\t\t: Reads STL file and creates a new shape with specified name."
2481 "\n\t\t: When -brep is specified, creates a Compound of per-triangle Faces."
2482 "\n\t\t: Single triangulation-only Face is created otherwise (default)."
2483 "\n\t\t: -mergeAngle specifies maximum angle in degrees between triangles to merge equal nodes; disabled by default."
2484 "\n\t\t: -multi creates a face per solid in multi-domain files; ignored when -brep is set.",
2485 __FILE__, readstl, g);
2486 theCommands.Add ("loadvrml" , "shape file",__FILE__,loadvrml,g);
2487 theCommands.Add ("ReadObj",
2488 "ReadObj Doc file [-fileCoordSys {Zup|Yup}] [-fileUnit Unit]"
2489 "\n\t\t: [-resultCoordSys {Zup|Yup}] [-singlePrecision]"
2490 "\n\t\t: [-listExternalFiles] [-noCreateDoc]"
2491 "\n\t\t: Read OBJ file into XDE document."
2492 "\n\t\t: -fileUnit length unit of OBJ file content;"
2493 "\n\t\t: -fileCoordSys coordinate system defined by OBJ file; Yup when not specified."
2494 "\n\t\t: -resultCoordSys result coordinate system; Zup when not specified."
2495 "\n\t\t: -singlePrecision truncate vertex data to single precision during read; FALSE by default."
2496 "\n\t\t: -listExternalFiles do not read mesh and only list external files."
2497 "\n\t\t: -noCreateDoc read into existing XDE document.",
2498 __FILE__, ReadObj, g);
2499 theCommands.Add ("readobj",
2500 "readobj shape file [-fileCoordSys {Zup|Yup}] [-fileUnit Unit]"
2501 "\n\t\t: [-resultCoordSys {Zup|Yup}] [-singlePrecision]"
2502 "\n\t\t: [-singleFace]"
2503 "\n\t\t: Same as ReadObj but reads OBJ file into a shape instead of a document."
2504 "\n\t\t: -singleFace merge OBJ content into a single triangulation Face.",
2505 __FILE__, ReadObj, g);
2506 theCommands.Add ("WriteObj",
2507 "WriteObj Doc file [-fileCoordSys {Zup|Yup}] [-fileUnit Unit]"
2508 "\n\t\t: [-systemCoordSys {Zup|Yup}]"
2509 "\n\t\t: [-comments Text] [-author Name]"
2510 "\n\t\t: Write XDE document into OBJ file."
2511 "\n\t\t: -fileUnit length unit of OBJ file content;"
2512 "\n\t\t: -fileCoordSys coordinate system defined by OBJ file; Yup when not specified."
2513 "\n\t\t: -systemCoordSys system coordinate system; Zup when not specified.",
2514 __FILE__, WriteObj, g);
2515 theCommands.Add ("writeobj",
2516 "writeobj shape file",
2517 __FILE__, WriteObj, g);
2519 theCommands.Add ("meshfromstl", "creates MeshVS_Mesh from STL file", __FILE__, createmesh, g );
2520 theCommands.Add ("mesh3delem", "creates 3d element mesh to test", __FILE__, create3d, g );
2521 theCommands.Add ("meshshadcolor", "change MeshVS_Mesh shading color", __FILE__, meshcolor, g );
2522 theCommands.Add ("meshlinkcolor", "change MeshVS_Mesh line color", __FILE__, linecolor, g );
2523 theCommands.Add ("meshmat", "change MeshVS_Mesh material and transparency", __FILE__, meshmat, g );
2524 theCommands.Add ("meshshrcoef", "change MeshVS_Mesh shrink coeff", __FILE__, shrink, g );
2525 theCommands.Add ("meshclosed", "meshclosed meshname (0/1) \nChange MeshVS_Mesh drawing mode. 0 - not closed object, 1 - closed object", __FILE__, closed, g);
2526 theCommands.Add ("meshshow", "display MeshVS_Mesh object", __FILE__, mdisplay, g );
2527 theCommands.Add ("meshhide", "erase MeshVS_Mesh object", __FILE__, merase, g );
2528 theCommands.Add ("meshhidesel", "hide selected entities", __FILE__, hidesel, g );
2529 theCommands.Add ("meshshowsel", "show only selected entities", __FILE__, showonly, g );
2530 theCommands.Add ("meshshowall", "show all entities", __FILE__, showall, g );
2531 theCommands.Add ("meshcolors", "display color presentation", __FILE__, meshcolors, g );
2532 theCommands.Add ("meshvectors", "display sample vectors", __FILE__, meshvectors, g );
2533 theCommands.Add ("meshtext", "display text labels", __FILE__, meshtext, g );
2534 theCommands.Add ("meshdeform", "display deformed mesh", __FILE__, meshdeform, g );
2535 theCommands.Add ("mesh_edge_width", "set width of edges", __FILE__, mesh_edge_width, g );
2536 theCommands.Add ("meshinfo", "displays the number of nodes and triangles", __FILE__, meshinfo, g );
2537 theCommands.Add ("WritePly", R"(
2538 WritePly Doc file [-normals {0|1}]=1 [-colors {0|1}]=1 [-uv {0|1}]=0 [-partId {0|1}]=1 [-faceId {0|1}]=0
2539 [-pointCloud {0|1}]=0 [-distance Value]=0.0 [-density Value] [-tolerance Value]
2540 Write document or triangulated shape into PLY file.
2541 -normals write per-vertex normals
2542 -colors write per-vertex colors
2543 -uv write per-vertex UV coordinates
2544 -partId write per-element part index (alternative to -faceId)
2545 -faceId write per-element face index (alternative to -partId)
2547 Generate point cloud out of the shape and write it into PLY file.
2548 -pointCloud write point cloud instead without triangulation indices
2549 -distance sets distance from shape into the range [0, Value];
2550 -density sets density of points to generate randomly on surface;
2551 -tolerance sets tolerance; default value is Precision::Confusion();
2552 )", __FILE__, WritePly, g);
2553 theCommands.Add ("writeply",
2554 "writeply shape file",
2555 __FILE__, WritePly, g);
2558 //==============================================================================
2559 // XSDRAWSTLVRML::Factory
2560 //==============================================================================
2561 void XSDRAWSTLVRML::Factory(Draw_Interpretor& theDI)
2563 XSDRAWIGES::InitSelect();
2564 XSDRAWIGES::InitToBRep(theDI);
2565 XSDRAWIGES::InitFromBRep(theDI);
2566 XSDRAWSTEP::InitCommands(theDI);
2567 XSDRAWSTLVRML::InitCommands(theDI);
2568 XSDRAW::LoadDraw(theDI);
2570 theDI << "Draw Plugin : All TKXSDRAW commands are loaded\n";
2574 // Declare entry point PLUGINFACTORY
2575 DPLUGIN(XSDRAWSTLVRML)