]> OCCT Git - occt-copy.git/commitdiff
Implementation of import to VRML from TDocStd_Document. CR0_CAD_to_VRML_Converter
authorskl <skl@opencascade.com>
Thu, 6 Sep 2018 08:18:13 +0000 (11:18 +0300)
committerskl <skl@opencascade.com>
Thu, 6 Sep 2018 08:37:24 +0000 (11:37 +0300)
src/TKVRML/EXTERNLIB
src/TKXDEDRAW/EXTERNLIB
src/VrmlAPI/VrmlAPI_Writer.cxx
src/VrmlAPI/VrmlAPI_Writer.hxx
src/VrmlData/VrmlData_ShapeConvert.cxx
src/VrmlData/VrmlData_ShapeConvert.hxx
src/XDEDRAW/XDEDRAW_Common.cxx

index 6f521bbafa11e1913f515b66aa2191139414c423..b659b109c86e9866d561033a0426871b6b8251b0 100755 (executable)
@@ -11,3 +11,5 @@ TKHLR
 TKService
 TKGeomAlgo
 TKV3d
+TKLCAF
+TKXCAF
index 85edbded0ef6ce80c36de8dbcb7e54ced3994b3d..7d9d7033c020e24d8602bf028976e8ab8bb0746b 100755 (executable)
@@ -24,3 +24,5 @@ TKDCAF
 TKViewerTest
 TKBinXCAF
 TKXmlXCAF
+TKVRML
+
index d39b3b62a5cebfc4252e06ca2962e479f6a3ba7e..6c96d167fb6642903425fb9240b559ba9e01117e 100644 (file)
@@ -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;
+
+}
+
index 77b33b03e3abbec46f26b729a8f89e3ce507c192..74df6c50f5b902dc4b837411bcb9bbba4b4f0dad 100644 (file)
@@ -25,6 +25,8 @@
 #include <Quantity_HArray1OfColor.hxx>
 #include <Standard_CString.hxx>
 #include <Standard_Integer.hxx>
+#include <TDocStd_Document.hxx>
+
 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
index 151d1978b18ac225979b53ca745d8cd52c11c593..eb5504e249a3939937c3de9fb8c0dbe119240db6 100644 (file)
 #include <Poly_PolygonOnTriangulation.hxx>
 #include <Poly_Polygon3D.hxx>
 #include <Precision.hxx>
+#include <Quantity_ColorRGBA.hxx>
 #include <TColgp_Array1OfPnt2d.hxx>
+#include <TDataStd_Name.hxx>
+#include <TDF_Label.hxx>
+//#include <TDF_LabelSequence.hxx>
+#include <TDocStd_Document.hxx>
 #include <TopExp_Explorer.hxx>
 #include <TopoDS.hxx>
 #include <TopoDS_Edge.hxx>
 #include <GeomLib.hxx>
 #include <TShort_HArray1OfShortReal.hxx>
 #include <VrmlData_Appearance.hxx>
+#include <XCAFDoc_ColorTool.hxx>
+#include <XCAFDoc_DocumentTool.hxx>
+#include <XCAFDoc_ShapeTool.hxx>
+
 
 //=======================================================================
 //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 <TopoDS_Shape,Handle(VrmlData_Geometry)>
-    aRelMap (100, anAlloc);
-
+  //NCollection_DataMap <TopoDS_Shape,Handle(VrmlData_Geometry)>
+  //  aRelMap (100, anAlloc);
+  myRelMap = NCollection_DataMap <TopoDS_Shape, Handle(VrmlData_Geometry)>(100, anAlloc);
 
   NCollection_List<ShapeData>::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<TopoDS_Shape, TDF_Label> 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;
+}
+
+
index 7251d6b40ee98dcaa549994be54988a254f825c3..94f3f451106b5e6d29bbacca9f06a034c1b70729 100644 (file)
@@ -19,6 +19,7 @@
 #include <VrmlData_Geometry.hxx>
 #include <VrmlData_Appearance.hxx>
 #include <NCollection_List.hxx>
+#include <NCollection_DataMap.hxx>
 #include <TopoDS_Shape.hxx>
 
 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 <ShapeData>          myShapes;
+
+  Standard_Real myDeflection;
+  Standard_Real myDeflAngle;
+  NCollection_DataMap <TopoDS_Shape, Handle(VrmlData_Geometry)> myRelMap;
+
   // ---------- PRIVATE METHODS ----------
   void operator= (const VrmlData_ShapeConvert&);
 };
index 5fabb0eb259455b6d75bc7127a178ed56542569b..1349e13f884dc9a022f026981c13c1b844c6a9e8 100644 (file)
@@ -39,6 +39,7 @@
 #include <XSDRAW_Vars.hxx>
 #include <XSDRAWIGES.hxx>
 #include <XSDRAWSTEP.hxx>
+#include <VrmlAPI_Writer.hxx>
 #include <DDF.hxx>
 
 #include <DBRep.hxx>
@@ -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);
+
 }