From 0446f5d7914e7d3d03d75f241986de636bb3fb02 Mon Sep 17 00:00:00 2001 From: skl Date: Thu, 6 Sep 2018 11:18:13 +0300 Subject: [PATCH] Implementation of import to VRML from TDocStd_Document. --- src/TKVRML/EXTERNLIB | 2 + src/TKXDEDRAW/EXTERNLIB | 2 + src/VrmlAPI/VrmlAPI_Writer.cxx | 21 + src/VrmlAPI/VrmlAPI_Writer.hxx | 8 + src/VrmlData/VrmlData_ShapeConvert.cxx | 524 ++++++++++++++++++++++++- src/VrmlData/VrmlData_ShapeConvert.hxx | 37 ++ src/XDEDRAW/XDEDRAW_Common.cxx | 37 ++ 7 files changed, 615 insertions(+), 16 deletions(-) diff --git a/src/TKVRML/EXTERNLIB b/src/TKVRML/EXTERNLIB index 6f521bbafa..b659b109c8 100755 --- a/src/TKVRML/EXTERNLIB +++ b/src/TKVRML/EXTERNLIB @@ -11,3 +11,5 @@ TKHLR TKService TKGeomAlgo TKV3d +TKLCAF +TKXCAF diff --git a/src/TKXDEDRAW/EXTERNLIB b/src/TKXDEDRAW/EXTERNLIB index 85edbded0e..7d9d7033c0 100755 --- a/src/TKXDEDRAW/EXTERNLIB +++ b/src/TKXDEDRAW/EXTERNLIB @@ -24,3 +24,5 @@ TKDCAF TKViewerTest TKBinXCAF TKXmlXCAF +TKVRML + diff --git a/src/VrmlAPI/VrmlAPI_Writer.cxx b/src/VrmlAPI/VrmlAPI_Writer.cxx index d39b3b62a5..6c96d167fb 100644 --- a/src/VrmlAPI/VrmlAPI_Writer.cxx +++ b/src/VrmlAPI/VrmlAPI_Writer.cxx @@ -376,3 +376,24 @@ void VrmlAPI_Writer::write_v2(const TopoDS_Shape& aShape,const Standard_CString if (aFoc.open (aFile, ios::out)) outStream << aScene; } + +//======================================================================= +//function : WriteDoc +//purpose : +//======================================================================= +void VrmlAPI_Writer::WriteDoc( + const Handle(TDocStd_Document) &theDoc, + const Standard_CString theFile) const +{ + + VrmlData_Scene aScene; + VrmlData_ShapeConvert aConv(aScene); + aConv.ConvertDocument(theDoc); + + filebuf aFoc; + ostream outStream(&aFoc); + if (aFoc.open(theFile, ios::out)) + outStream << aScene; + +} + diff --git a/src/VrmlAPI/VrmlAPI_Writer.hxx b/src/VrmlAPI/VrmlAPI_Writer.hxx index 77b33b03e3..74df6c50f5 100644 --- a/src/VrmlAPI/VrmlAPI_Writer.hxx +++ b/src/VrmlAPI/VrmlAPI_Writer.hxx @@ -25,6 +25,8 @@ #include #include #include +#include + class VrmlConverter_Drawer; class VrmlConverter_Projector; class Vrml_Material; @@ -105,6 +107,12 @@ public: //! VRML format of the passed version and writes it to the file identified by aFile. Standard_EXPORT void Write (const TopoDS_Shape& aShape, const Standard_CString aFile, const Standard_Integer aVersion = 2) const; + //! Converts the document to VRML format of the passed version + //! and writes it to the file identified by aFile. + Standard_EXPORT void WriteDoc( + const Handle(TDocStd_Document) &theDoc, + const Standard_CString theFile) const; + protected: //! Converts the shape aShape to VRML format of version 1.0 and writes it diff --git a/src/VrmlData/VrmlData_ShapeConvert.cxx b/src/VrmlData/VrmlData_ShapeConvert.cxx index 151d1978b1..eb5504e249 100644 --- a/src/VrmlData/VrmlData_ShapeConvert.cxx +++ b/src/VrmlData/VrmlData_ShapeConvert.cxx @@ -30,7 +30,12 @@ #include #include #include +#include #include +#include +#include +//#include +#include #include #include #include @@ -45,6 +50,10 @@ #include #include #include +#include +#include +#include + //======================================================================= //function : AddShape @@ -87,6 +96,143 @@ void VrmlData_ShapeConvert::AddShape (const TopoDS_Shape& theShape, myShapes.Append (aData); } + +//======================================================================= +//function : makeTShapeNode +//purpose : auxilary +//======================================================================= +Handle(VrmlData_Geometry) VrmlData_ShapeConvert::makeTShapeNode(const TopoDS_Shape& theShape, + const TopAbs_ShapeEnum theShapeType, + TopLoc_Location& theLoc) +{ + Handle(VrmlData_Geometry) aTShapeNode = 0L; + const Standard_Boolean isReverse = (theShape.Orientation() == TopAbs_REVERSED); + + TopoDS_Shape aTestedShape; + aTestedShape.TShape(theShape.TShape()); + aTestedShape.Orientation(isReverse ? TopAbs_REVERSED : TopAbs_FORWARD); + switch (theShapeType) { + case TopAbs_FACE: + { + const TopoDS_Face& aFace = TopoDS::Face(theShape); + if (aFace.IsNull() == Standard_False) { + Handle(Poly_Triangulation) aTri = + BRep_Tool::Triangulation(aFace, theLoc); + + if (myRelMap.IsBound(aTestedShape)) { + aTShapeNode = myRelMap(aTestedShape); + break; + } + + if (aTri.IsNull() == Standard_False) { + TopoDS_Shape aTestedShapeRev = aTestedShape; + aTestedShapeRev.Orientation(isReverse ? + TopAbs_FORWARD : TopAbs_REVERSED); + Handle(VrmlData_IndexedFaceSet) aFaceSetToReuse; + if (myRelMap.IsBound(aTestedShapeRev)) + aFaceSetToReuse = Handle(VrmlData_IndexedFaceSet)::DownCast + (myRelMap(aTestedShapeRev)); + + Handle(VrmlData_Coordinate) aCoordToReuse; + if (aFaceSetToReuse.IsNull() == Standard_False) + aCoordToReuse = aFaceSetToReuse->Coordinates(); + + aTShapeNode = triToIndexedFaceSet(aTri, aFace, aCoordToReuse); + myScene.AddNode(aTShapeNode, Standard_False); + // Bind the converted face + myRelMap.Bind(aTestedShape, aTShapeNode); + } + } + } + break; + case TopAbs_WIRE: + { + const TopoDS_Wire& aWire = TopoDS::Wire(theShape); + if (aWire.IsNull() == Standard_False) { + } + } + break; + case TopAbs_EDGE: + { + const TopoDS_Edge& aEdge = TopoDS::Edge(theShape); + if (aEdge.IsNull() == Standard_False) { + if (myRelMap.IsBound(aTestedShape)) { + aTShapeNode = myRelMap(aTestedShape); + break; + } + // Check the presence of reversly oriented Edge. It can also be used + // because we do not distinguish the orientation for edges. + aTestedShape.Orientation(isReverse ? + TopAbs_FORWARD : TopAbs_REVERSED); + if (myRelMap.IsBound(aTestedShape)) { + aTShapeNode = myRelMap(aTestedShape); + break; + } + + //try to find PolygonOnTriangulation + Handle(Poly_PolygonOnTriangulation) aPT; + Handle(Poly_Triangulation) aT; + TopLoc_Location aL; + BRep_Tool::PolygonOnTriangulation(aEdge, aPT, aT, aL); + + // If PolygonOnTriangulation was found -> get the Polygon3D + Handle(Poly_Polygon3D) aPol; + if (!aPT.IsNull() && !aT.IsNull() && aPT->HasParameters()) { + BRepAdaptor_Curve aCurve(aEdge); + Handle(TColStd_HArray1OfReal) aPrs = aPT->Parameters(); + Standard_Integer nbNodes = aPT->NbNodes(); + TColgp_Array1OfPnt arrNodes(1, nbNodes); + TColStd_Array1OfReal arrUVNodes(1, nbNodes); + + for (Standard_Integer j = 1; j <= nbNodes; j++) { + arrUVNodes(j) = aPrs->Value(aPrs->Lower() + j - 1); + arrNodes(j) = aCurve.Value(arrUVNodes(j)); + } + aPol = new Poly_Polygon3D(arrNodes, arrUVNodes); + aPol->Deflection(aPT->Deflection()); + } + else { + aPol = BRep_Tool::Polygon3D(aEdge, aL); + + // If polygon was not found -> generate it + if (aPol.IsNull()) { + BRepAdaptor_Curve aCurve(aEdge); + const Standard_Real aFirst = aCurve.FirstParameter(); + const Standard_Real aLast = aCurve.LastParameter(); + + GCPnts_TangentialDeflection TD(aCurve, aFirst, aLast, + myDeflAngle, myDeflection, 2); + const Standard_Integer nbNodes = TD.NbPoints(); + + TColgp_Array1OfPnt arrNodes(1, nbNodes); + TColStd_Array1OfReal arrUVNodes(1, nbNodes); + for (Standard_Integer j = 1; j <= nbNodes; j++) { + arrNodes(j) = TD.Value(j); + arrUVNodes(j) = TD.Parameter(j); + } + aPol = new Poly_Polygon3D(arrNodes, arrUVNodes); + aPol->Deflection(myDeflection); + } + } + + if (!aPol.IsNull()) + { + aTShapeNode = polToIndexedLineSet(aPol); + myScene.AddNode(aTShapeNode, Standard_False); + // Bind the converted face + myRelMap.Bind(aTestedShape, aTShapeNode); + } + } + } + break; + default: + break; + } + + return aTShapeNode; +} + + //======================================================================= //function : Convert //purpose : @@ -97,8 +243,11 @@ void VrmlData_ShapeConvert::Convert (const Standard_Boolean theExtractFaces, const Standard_Real theDeflection, const Standard_Real theDeflAngle) { - const Standard_Real aDeflection = - theDeflection < 0.0001 ? 0.0001 : theDeflection; + //const Standard_Real aDeflection = + // theDeflection < 0.0001 ? 0.0001 : theDeflection; + + myDeflection = theDeflection < 0.0001 ? 0.0001 : theDeflection; + myDeflAngle = theDeflAngle; Standard_Boolean Extract[2] = {theExtractFaces, theExtractEdges}; TopAbs_ShapeEnum ShapeType[2] = {TopAbs_FACE, TopAbs_EDGE}; @@ -108,9 +257,9 @@ void VrmlData_ShapeConvert::Convert (const Standard_Boolean theExtractFaces, // Relocation map for converted shapes. We should distinguish both TShape // and Orientation in this map. - NCollection_DataMap - aRelMap (100, anAlloc); - + //NCollection_DataMap + // aRelMap (100, anAlloc); + myRelMap = NCollection_DataMap (100, anAlloc); NCollection_List::Iterator anIter (myShapes); for (; anIter.More(); anIter.Next()) { @@ -128,6 +277,9 @@ void VrmlData_ShapeConvert::Convert (const Standard_Boolean theExtractFaces, for (; anExp.More(); anExp.Next()) { const TopoDS_Shape& aShape = anExp.Current(); TopLoc_Location aLoc; + Handle(VrmlData_Geometry) aTShapeNode = + makeTShapeNode(aShape, ShapeType[i], aLoc); + /* Handle(VrmlData_Geometry) aTShapeNode; const Standard_Boolean isReverse=(aShape.Orientation()==TopAbs_REVERSED); @@ -142,8 +294,8 @@ void VrmlData_ShapeConvert::Convert (const Standard_Boolean theExtractFaces, Handle(Poly_Triangulation) aTri = BRep_Tool::Triangulation (aFace, aLoc); - if (aRelMap.IsBound (aTestedShape)) { - aTShapeNode = aRelMap(aTestedShape); + if (myRelMap.IsBound (aTestedShape)) { + aTShapeNode = myRelMap(aTestedShape); break; } @@ -152,9 +304,9 @@ void VrmlData_ShapeConvert::Convert (const Standard_Boolean theExtractFaces, aTestedShapeRev.Orientation (isReverse ? TopAbs_FORWARD : TopAbs_REVERSED); Handle(VrmlData_IndexedFaceSet) aFaceSetToReuse; - if (aRelMap.IsBound (aTestedShapeRev)) + if (myRelMap.IsBound (aTestedShapeRev)) aFaceSetToReuse = Handle(VrmlData_IndexedFaceSet)::DownCast - (aRelMap(aTestedShapeRev)); + (myRelMap(aTestedShapeRev)); Handle(VrmlData_Coordinate) aCoordToReuse; if (aFaceSetToReuse.IsNull() == Standard_False) @@ -163,7 +315,7 @@ void VrmlData_ShapeConvert::Convert (const Standard_Boolean theExtractFaces, aTShapeNode = triToIndexedFaceSet (aTri, aFace, aCoordToReuse); myScene.AddNode (aTShapeNode, Standard_False); // Bind the converted face - aRelMap.Bind (aTestedShape, aTShapeNode); + myRelMap.Bind (aTestedShape, aTShapeNode); } } } @@ -179,16 +331,16 @@ void VrmlData_ShapeConvert::Convert (const Standard_Boolean theExtractFaces, { const TopoDS_Edge& aEdge = TopoDS::Edge (aShape); if (aEdge.IsNull() == Standard_False) { - if (aRelMap.IsBound (aTestedShape)) { - aTShapeNode = aRelMap(aTestedShape); + if (myRelMap.IsBound (aTestedShape)) { + aTShapeNode = myRelMap(aTestedShape); break; } // Check the presence of reversly oriented Edge. It can also be used // because we do not distinguish the orientation for edges. aTestedShape.Orientation (isReverse ? TopAbs_FORWARD : TopAbs_REVERSED); - if (aRelMap.IsBound (aTestedShape)) { - aTShapeNode = aRelMap(aTestedShape); + if (myRelMap.IsBound (aTestedShape)) { + aTShapeNode = myRelMap(aTestedShape); break; } @@ -244,14 +396,15 @@ void VrmlData_ShapeConvert::Convert (const Standard_Boolean theExtractFaces, aTShapeNode = polToIndexedLineSet (aPol); myScene.AddNode (aTShapeNode, Standard_False); // Bind the converted face - aRelMap.Bind (aTestedShape, aTShapeNode); + myRelMap.Bind (aTestedShape, aTShapeNode); } } break; default: break; } - + */ + if (aTShapeNode.IsNull() == Standard_False) { const Handle(VrmlData_ShapeNode) aShapeNode = new VrmlData_ShapeNode (myScene, 0L); @@ -537,3 +690,342 @@ Handle(VrmlData_Appearance) VrmlData_ShapeConvert::defaultMaterialEdge () const } return anAppearance; } + + +//======================================================================= +//function : addShape +//purpose : Adds the shape from the document +//======================================================================= +void VrmlData_ShapeConvert::addShape (const Handle(VrmlData_Group)& theParent, + const TDF_Label& theLabel, + const Handle(TDocStd_Document)& theDoc) +{ + Handle(XCAFDoc_ShapeTool) aShapeTool = XCAFDoc_DocumentTool::ShapeTool(theDoc->Main()); + Handle(XCAFDoc_ColorTool) aColorTool = XCAFDoc_DocumentTool::ColorTool(theDoc->Main()); + + NCollection_DataMap aChildShapeToLabels; + TDF_LabelSequence aChildLabels; + aShapeTool->GetSubShapes(theLabel, aChildLabels); + for (TDF_LabelSequence::Iterator aChildIter(aChildLabels); aChildIter.More(); aChildIter.Next()) + { + const TDF_Label& aChildLabel = aChildIter.Value(); + TopoDS_Shape aChildShape; + if (aShapeTool->GetShape(aChildLabel, aChildShape)) + { + aChildShapeToLabels.Bind(aChildShape, aChildLabel); + } + } + + const TopoDS_Shape aShape = aShapeTool->GetShape(theLabel); + Handle(VrmlData_Group) aGroup = 0L; + TopExp_Explorer anExp(aShape, TopAbs_FACE); + Standard_Integer nbFaces = 0; + for (; anExp.More(); anExp.Next()) { + nbFaces++; + } + Handle(TDataStd_Name) aNameAttribute; + theLabel.FindAttribute(TDataStd_Name::GetID(), aNameAttribute); + if (nbFaces > 1) + { + if (!aNameAttribute.IsNull()) + { + TCollection_AsciiString aName = aNameAttribute->Get(); + aGroup = new VrmlData_Group(myScene, aName.ToCString()); + } + else + { + aGroup = new VrmlData_Group(myScene, 0L); + } + myScene.AddNode(aGroup, theParent.IsNull()); + if (!theParent.IsNull()) + { + theParent->AddNode(aGroup); + } + } + + anExp.Init(aShape, TopAbs_FACE); + for (; anExp.More(); anExp.Next()) { + TopLoc_Location aLoc; + Handle(VrmlData_Geometry) aTShapeNode = + makeTShapeNode(anExp.Current(), TopAbs_FACE, aLoc); + if (aTShapeNode.IsNull() == Standard_False) + { + Handle(VrmlData_ShapeNode) aShapeNode = 0L; + if (aGroup.IsNull() && !aNameAttribute.IsNull()) + { + TCollection_AsciiString aName = aNameAttribute->Get(); + aShapeNode = new VrmlData_ShapeNode(myScene, aName.ToCString()); + } + else + { + aShapeNode = new VrmlData_ShapeNode(myScene, 0L); + } + + // set color + TDF_Label aColorL; + Standard_Boolean findColor = Standard_False; + const TDF_Label* aLabel = aChildShapeToLabels.Seek(anExp.Current()); + if (aLabel != NULL) + { + findColor = Standard_True; + if (!aColorTool->GetColor(*aLabel, XCAFDoc_ColorSurf, aColorL) + && !aColorTool->GetColor(*aLabel, XCAFDoc_ColorGen, aColorL)) + { + findColor = Standard_False; + } + } + if (!findColor) + { + findColor = Standard_True; + if (!aColorTool->GetColor(theLabel, XCAFDoc_ColorSurf, aColorL) + && !aColorTool->GetColor(theLabel, XCAFDoc_ColorGen, aColorL)) + { + findColor = Standard_False; + } + } + if (!findColor) + { + aShapeNode->SetAppearance(defaultMaterialFace()); + } + else + { + aShapeNode->SetAppearance(makeMaterialFromColor(aColorL, aColorTool)); + } + + myScene.AddNode(aShapeNode, Standard_False); + aShapeNode->SetGeometry(aTShapeNode); + if (aLoc.IsIdentity()) + { + // Store the shape node directly into the main Group. + if (!aGroup.IsNull()) + { + aGroup->AddNode(aShapeNode); + } + else + { + theParent->AddNode(aShapeNode); + } + } + else + { + // Create a Transform grouping node + Handle(VrmlData_Group) aTrans = new VrmlData_Group(myScene, 0L, + Standard_True); + gp_Trsf aTrsf(aLoc); + if (fabs(myScale - 1.) > Precision::Confusion()) + { + const gp_XYZ aTransl = aTrsf.TranslationPart() * myScale; + aTrsf.SetTranslationPart(aTransl); + } + aTrans->SetTransform(aTrsf); + myScene.AddNode(aTrans, Standard_False); + if (!aGroup.IsNull()) + { + aGroup->AddNode(aTrans); + } + else + { + theParent->AddNode(aTrans); + } + // Store the shape node under the transform. + aTrans->AddNode(aShapeNode); + } + } + } +} + + +//======================================================================= +//function : addInstance +//purpose : Adds the reference from the document +//======================================================================= +void VrmlData_ShapeConvert::addInstance (const Handle(VrmlData_Group)& theParent, + const TDF_Label& theLabel, + const Handle(TDocStd_Document)& theDoc) +{ + Handle(XCAFDoc_ShapeTool) aShapeTool = XCAFDoc_DocumentTool::ShapeTool(theDoc->Main()); + + const TopLoc_Location aLoc = aShapeTool->GetLocation(theLabel); + Handle(VrmlData_Group) aTrans = 0L; + if (!aLoc.IsIdentity()) + { + // Create a Transform grouping node + aTrans = new VrmlData_Group(myScene, 0L, Standard_True); + gp_Trsf aTrsf(aLoc); + if (fabs(myScale - 1.) > Precision::Confusion()) { + const gp_XYZ aTransl = aTrsf.TranslationPart() * myScale; + aTrsf.SetTranslationPart(aTransl); + } + aTrans->SetTransform(aTrsf); + myScene.AddNode(aTrans, theParent.IsNull()); + if (!theParent.IsNull()) + { + theParent->AddNode(aTrans); + } + } + + Handle(TDataStd_Name) aNameAttribute; + theLabel.FindAttribute(TDataStd_Name::GetID(), aNameAttribute); + + TDF_Label aRefLabel; + aShapeTool->GetReferredShape(theLabel, aRefLabel); + Handle(TDataStd_Name) aRefNameAttribute; + aRefLabel.FindAttribute(TDataStd_Name::GetID(), aRefNameAttribute); + + if (aShapeTool->IsSimpleShape(aRefLabel)) + { + addShape((aTrans.IsNull() ? theParent : aTrans), aRefLabel, theDoc); + } + else if (aShapeTool->IsReference(aRefLabel)) + { + } + else if (aShapeTool->IsAssembly(aRefLabel)) + { + addAssembly((aTrans.IsNull() ? theParent : aTrans), aRefLabel, theDoc, aTrans.IsNull()); + } +} + + +//======================================================================= +//function : addAssembly +//purpose : Adds the assembly from the document +//======================================================================= +void VrmlData_ShapeConvert::addAssembly (const Handle(VrmlData_Group)& theParent, + const TDF_Label& theLabel, + const Handle(TDocStd_Document)& theDoc, + const Standard_Boolean theNeedCreateGroup) +{ + Handle(XCAFDoc_ShapeTool) aShapeTool = XCAFDoc_DocumentTool::ShapeTool(theDoc->Main()); + + Handle(VrmlData_Group) anAssembly = 0L; + if (theNeedCreateGroup) + { + Handle(TDataStd_Name) aNameAttribute; + theLabel.FindAttribute(TDataStd_Name::GetID(), aNameAttribute); + if (!aNameAttribute.IsNull()) + { + TCollection_AsciiString aName = aNameAttribute->Get(); + anAssembly = new VrmlData_Group(myScene, aName.ToCString()); + } + else + { + anAssembly = new VrmlData_Group(myScene, 0L); + } + TopLoc_Location aLoc = aShapeTool->GetLocation(theLabel); + if (!aLoc.IsIdentity()) + { + gp_Trsf aTrsf(aLoc); + if (fabs(myScale - 1.) > Precision::Confusion()) { + const gp_XYZ aTransl = aTrsf.TranslationPart() * myScale; + aTrsf.SetTranslationPart(aTransl); + } + anAssembly->SetTransform(aTrsf); + } + myScene.AddNode(anAssembly, theParent.IsNull()); + if (!theParent.IsNull()) + { + theParent->AddNode(anAssembly); + } + } + + TDF_LabelSequence aChildLabels; + aShapeTool->GetComponents(theLabel, aChildLabels); + for (TDF_LabelSequence::Iterator aChildIter(aChildLabels); aChildIter.More(); aChildIter.Next()) + { + const TDF_Label& aChildLabel = aChildIter.Value(); + if (aShapeTool->IsAssembly(aChildLabel)) + { + addAssembly((anAssembly.IsNull() ? theParent : anAssembly), aChildLabel, theDoc, anAssembly.IsNull()); + } + else if (aShapeTool->IsReference(aChildLabel)) + { + addInstance((anAssembly.IsNull() ? theParent : anAssembly), aChildLabel, theDoc); + } + else if (aShapeTool->IsSimpleShape(aChildLabel)) + { + addShape((anAssembly.IsNull() ? theParent : anAssembly), aChildLabel, theDoc); + } + } +} + + +//======================================================================= +//function : ConvertDocument +//purpose : +//======================================================================= +void VrmlData_ShapeConvert::ConvertDocument(const Handle(TDocStd_Document) &theDoc) +{ + Handle(XCAFDoc_ShapeTool) aShapeTool = XCAFDoc_DocumentTool::ShapeTool(theDoc->Main()); + + TDF_LabelSequence aFreeShapeLabels; + aShapeTool->GetFreeShapes(aFreeShapeLabels); + + Handle(VrmlData_Group) aGroup = 0L; + if (aFreeShapeLabels.Size() > 1) + { + aGroup = new VrmlData_Group(myScene, 0L); + myScene.AddNode(aGroup); + } + + for (TDF_LabelSequence::Iterator aRootIter(aFreeShapeLabels); aRootIter.More(); aRootIter.Next()) + { + const TDF_Label& aFreeShapeLabel = aRootIter.Value(); + if (aShapeTool->IsSimpleShape(aFreeShapeLabel)) + { + addShape(aGroup, aFreeShapeLabel, theDoc); + } + else if (aShapeTool->IsReference(aFreeShapeLabel)) + { + addInstance(aGroup, aFreeShapeLabel, theDoc); + } + else if (aShapeTool->IsAssembly(aFreeShapeLabel)) + { + addAssembly(aGroup, aFreeShapeLabel, theDoc, Standard_True); + } + } +} + + +//======================================================================= +//function : makeMaterialFromColor +//purpose : +//======================================================================= + +Handle(VrmlData_Appearance) VrmlData_ShapeConvert::makeMaterialFromColor( + const TDF_Label& theColorL, + const Handle(XCAFDoc_ColorTool)& theColorTool) const +{ + Quantity_ColorRGBA aColor; + theColorTool->GetColor(theColorL, aColor); + + TCollection_AsciiString aNodeName = "_materialFace_"; + Handle(TDataStd_Name) aNameAttribute; + if (theColorL.FindAttribute(TDataStd_Name::GetID(), aNameAttribute)) + { + aNodeName.AssignCat(aNameAttribute->Get()); + } + else + { + aNodeName.AssignCat(aColor.GetRGB().Red()); + aNodeName.AssignCat("_"); + aNodeName.AssignCat(aColor.GetRGB().Green()); + aNodeName.AssignCat("_"); + aNodeName.AssignCat(aColor.GetRGB().Blue()); + } + + Handle(VrmlData_Appearance) anAppearance = + Handle(VrmlData_Appearance)::DownCast(myScene.FindNode(aNodeName.ToCString())); + if (anAppearance.IsNull()) { + const Handle(VrmlData_Material) aMaterial = + new VrmlData_Material(myScene, 0L); + aMaterial->SetDiffuseColor(aColor.GetRGB()); + myScene.AddNode(aMaterial, Standard_False); + anAppearance = new VrmlData_Appearance(myScene, aNodeName.ToCString()); + anAppearance->SetMaterial(aMaterial); + myScene.AddNode(anAppearance, Standard_False); + } + + return anAppearance; +} + + diff --git a/src/VrmlData/VrmlData_ShapeConvert.hxx b/src/VrmlData/VrmlData_ShapeConvert.hxx index 7251d6b40e..94f3f45110 100644 --- a/src/VrmlData/VrmlData_ShapeConvert.hxx +++ b/src/VrmlData/VrmlData_ShapeConvert.hxx @@ -19,6 +19,7 @@ #include #include #include +#include #include class VrmlData_Scene; @@ -26,6 +27,10 @@ class VrmlData_Coordinate; class TopoDS_Face; class Poly_Polygon3D; class Poly_Triangulation; +class XCAFDoc_ColorTool; +class TDocStd_Document; +class TDF_Label; + /** * Algorithm converting one shape or a set of shapes to VrmlData_Scene. @@ -85,6 +90,12 @@ class VrmlData_ShapeConvert const Standard_Real theDeflAngle = 20.*M_PI/180.); //this value of theDeflAngle is used by default //for tesselation while shading (Drawer->HLRAngle()) + + /** + * Add all shapes start from given document with colors and names to the internal structure + */ + Standard_EXPORT void ConvertDocument(const Handle(TDocStd_Document)& theDoc); + protected: // ---------- PROTECTED METHODS ---------- @@ -100,12 +111,38 @@ class VrmlData_ShapeConvert Handle(VrmlData_Appearance) defaultMaterialEdge () const; + Handle(VrmlData_Geometry) makeTShapeNode(const TopoDS_Shape& theShape, + const TopAbs_ShapeEnum theShapeType, + TopLoc_Location& theLoc); + + void addAssembly (const Handle(VrmlData_Group)& theParent, + const TDF_Label& theLabel, + const Handle(TDocStd_Document)& theDoc, + const Standard_Boolean theNeedCreateGroup); + + void addInstance (const Handle(VrmlData_Group)& theParent, + const TDF_Label& theLabel, + const Handle(TDocStd_Document)& theDoc); + + void addShape (const Handle(VrmlData_Group)& theParent, + const TDF_Label& theLabel, + const Handle(TDocStd_Document)& theDoc); + + Handle(VrmlData_Appearance) makeMaterialFromColor(const TDF_Label& theColorL, + const Handle(XCAFDoc_ColorTool)& theColorTool) const; + + private: // ---------- PRIVATE FIELDS ---------- VrmlData_Scene& myScene; Standard_Real myScale; NCollection_List myShapes; + + Standard_Real myDeflection; + Standard_Real myDeflAngle; + NCollection_DataMap myRelMap; + // ---------- PRIVATE METHODS ---------- void operator= (const VrmlData_ShapeConvert&); }; diff --git a/src/XDEDRAW/XDEDRAW_Common.cxx b/src/XDEDRAW/XDEDRAW_Common.cxx index 5fabb0eb25..1349e13f88 100644 --- a/src/XDEDRAW/XDEDRAW_Common.cxx +++ b/src/XDEDRAW/XDEDRAW_Common.cxx @@ -39,6 +39,7 @@ #include #include #include +#include #include #include @@ -534,6 +535,40 @@ static Standard_Integer Expand (Draw_Interpretor& di, Standard_Integer argc, con return 0; } + +//======================================================================= +//function : WriteVrml +//purpose : Write DECAF document to Vrml +//======================================================================= + +static Standard_Integer WriteVrml(Draw_Interpretor& di, Standard_Integer argc, const char** argv) +{ + if (argc <3) { + di << "Use: " << argv[0] << " Doc filename: write document to Vrml file\n"; + return 0; + } + + Handle(TDocStd_Document) aDoc; + DDocStd::GetDocument(argv[1], aDoc); + if (aDoc.IsNull()) { + di << argv[1] << " is not a document\n"; + return 1; + } + + if (argc < 3 || argc > 5) + { + di << "wrong number of parameters\n"; + return 0; + } + + VrmlAPI_Writer writer; + writer.SetRepresentation(VrmlAPI_ShadedRepresentation); + writer.WriteDoc(aDoc, argv[2]); + + return 0; +} + + void XDEDRAW_Common::InitCommands(Draw_Interpretor& di) { static Standard_Boolean initactor = Standard_False; @@ -558,4 +593,6 @@ void XDEDRAW_Common::InitCommands(Draw_Interpretor& di) di.Add("XExpand", "XExpand Doc recursively(0/1) or XExpand Doc recursively(0/1) label1 label2 ..." "or XExpand Doc recursively(0/1) shape1 shape2 ...",__FILE__, Expand, g); + di.Add("WriteVrml", "Doc filename [version VRML#1.0/VRML#2.0 (1/2): 2 by default] [representation shaded/wireframe/both (0/1/2): 0 by default]", __FILE__, WriteVrml, g); + } -- 2.39.5