// Created on: 2007-08-04
// Created by: Alexander GRIGORIEV
-// Copyright (c) 2007-2012 OPEN CASCADE SAS
+// Copyright (c) 2007-2014 OPEN CASCADE SAS
//
-// The content of this file is subject to the Open CASCADE Technology Public
-// License Version 6.5 (the "License"). You may not use the content of this file
-// except in compliance with the License. Please obtain a copy of the License
-// at http://www.opencascade.org and read it completely before using this file.
+// This file is part of Open CASCADE Technology software library.
//
-// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
-// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
//
-// The Original Code and all software distributed under the License is
-// distributed on an "AS IS" basis, without warranty of any kind, and the
-// Initial Developer hereby disclaims all such warranties, including without
-// limitation, any warranties of merchantability, fitness for a particular
-// purpose or non-infringement. Please see the License for the specific terms
-// and conditions governing the rights and limitations under the License.
-
-
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
#include <VrmlData_ShapeConvert.hxx>
#include <VrmlData_Scene.hxx>
#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 <TShort_Array1OfShortReal.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 : IsEqual
-//purpose : for NCollection_DataMap interface
-//=======================================================================
-
-inline Standard_Boolean IsEqual (const TopoDS_Shape& one,
- const TopoDS_Shape& two)
-{
- return one == two;
-}
//=======================================================================
//function : AddShape
char buf[2048], * optr = &buf[0];
char * eptr = &buf[sizeof(buf)-1];
for (const char * ptr = theName;; ptr++) {
- int sym = *ptr;
+ char sym = *ptr;
if (sym == '\0' || sym == '\n' || sym == '\r') {
* optr = '\0';
break;
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 :
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};
// 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()) {
for (; anExp.More(); anExp.Next()) {
const TopoDS_Shape& aShape = anExp.Current();
TopLoc_Location aLoc;
- Handle(VrmlData_Geometry) aTShapeNode;
- const Standard_Boolean isReverse=(aShape.Orientation()==TopAbs_REVERSED);
-
- TopoDS_Shape aTestedShape;
- aTestedShape.TShape (aShape.TShape());
- aTestedShape.Orientation (isReverse ? TopAbs_REVERSED : TopAbs_FORWARD);
- Standard_Boolean isTessellate (Standard_False);
- switch (ShapeType[i]) {
- case TopAbs_FACE:
- {
- const TopoDS_Face& aFace = TopoDS::Face (aShape);
- if (aFace.IsNull() == Standard_False) {
- Handle(Poly_Triangulation) aTri =
- BRep_Tool::Triangulation (aFace, aLoc);
-
- if (aRelMap.IsBound (aTestedShape)) {
- aTShapeNode = aRelMap(aTestedShape);
- break;
- }
-
- if (aTri.IsNull())
- isTessellate = Standard_True;
- // Check the existing deflection
- else if (aTri->Deflection() > aDeflection+ Precision::Confusion())
- isTessellate = Standard_True;
- if (isTessellate) {
- // Triangulate the face by the standard OCC mesher
- BRepMesh_IncrementalMesh IM (aFace, aDeflection, Standard_False, theDeflAngle);
- aTri = BRep_Tool::Triangulation (aFace, aLoc);
- }
- if (aTri.IsNull() == Standard_False) {
- TopoDS_Shape aTestedShapeRev = aTestedShape;
- aTestedShapeRev.Orientation (isReverse ?
- TopAbs_FORWARD : TopAbs_REVERSED);
- Handle(VrmlData_IndexedFaceSet) aFaceSetToReuse;
- if (aRelMap.IsBound (aTestedShapeRev))
- aFaceSetToReuse = Handle(VrmlData_IndexedFaceSet)::DownCast
- (aRelMap(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
- aRelMap.Bind (aTestedShape, aTShapeNode);
- }
- }
- }
- break;
- case TopAbs_WIRE:
- {
- const TopoDS_Wire& aWire = TopoDS::Wire (aShape);
- if (aWire.IsNull() == Standard_False) {
- }
- }
- break;
- case TopAbs_EDGE:
- {
- const TopoDS_Edge& aEdge = TopoDS::Edge (aShape);
- if (aEdge.IsNull() == Standard_False) {
- Handle(Poly_Polygon3D) aPol = BRep_Tool::Polygon3D (aEdge, aLoc);
-
- if (aRelMap.IsBound (aTestedShape)) {
- aTShapeNode = aRelMap(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);
- break;
- }
-
- if (aPol.IsNull())
- isTessellate = Standard_True;
- // Check the existing deflection
- else if (aPol->Deflection() > aDeflection+ Precision::Confusion()
- && BRep_Tool::IsGeometric(aEdge))
- isTessellate = Standard_True;
-
- if (isTessellate && BRep_Tool::IsGeometric(aEdge)) {
- //try to find PolygonOnTriangulation
- Handle(Poly_PolygonOnTriangulation) aPT;
- Handle(Poly_Triangulation) aT;
- TopLoc_Location aL;
-
- Standard_Boolean found = Standard_False;
- for(i = 1; Standard_True; i++) {
-
- BRep_Tool::PolygonOnTriangulation(aEdge, aPT, aT, aL, i);
-
- if(aPT.IsNull() || aT.IsNull()) break;
-
- if(aPT->Deflection() <= aDeflection + Precision::Confusion() &&
- aPT->HasParameters()) {
- found = Standard_True;
- break;
- }
-
- }
-
- if(found) {
-
- 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(i = 1; i <= nbNodes; i++) {
- arrUVNodes(i) = aPrs->Value(aPrs->Lower() + i - 1);
- arrNodes(i) = aCurve.Value(arrUVNodes(i));
- }
- aPol = new Poly_Polygon3D(arrNodes, arrUVNodes);
- aPol->Deflection (aPT->Deflection());
- }
- else{
-
- BRepAdaptor_Curve aCurve(aEdge);
- const Standard_Real aFirst = aCurve.FirstParameter();
- const Standard_Real aLast = aCurve.LastParameter();
-
- GCPnts_TangentialDeflection TD (aCurve, aFirst, aLast,
- theDeflAngle, aDeflection, 2);
- const Standard_Integer nbNodes = TD.NbPoints();
-
- TColgp_Array1OfPnt arrNodes(1, nbNodes);
- TColStd_Array1OfReal arrUVNodes(1, nbNodes);
- for (i = 1; i <= nbNodes; i++) {
- arrNodes(i) = TD.Value(i);
- arrUVNodes(i) = TD.Parameter(i);
- }
- aPol = new Poly_Polygon3D(arrNodes, arrUVNodes);
- aPol->Deflection (aDeflection);
- }
-
- BRep_Builder aBld;
- aBld.UpdateEdge (aEdge, aPol);
- }
- aTShapeNode = polToIndexedLineSet (aPol);
- myScene.AddNode (aTShapeNode, Standard_False);
- // Bind the converted face
- aRelMap.Bind (aTestedShape, aTShapeNode);
- }
- }
- break;
- }
-
- if (aTShapeNode.IsNull() == Standard_False) {
+ Handle(VrmlData_Geometry) aTShapeNode =
+ makeTShapeNode(aShape, ShapeType[i], aLoc);
+ if (!aTShapeNode.IsNull()) {
const Handle(VrmlData_ShapeNode) aShapeNode =
new VrmlData_ShapeNode (myScene, 0L);
aShapeNode->SetAppearance (ShapeType[i] == TopAbs_FACE ?
//purpose :
//=======================================================================
-Handle_VrmlData_Geometry VrmlData_ShapeConvert::triToIndexedFaceSet
- (const Handle_Poly_Triangulation& theTri,
+Handle(VrmlData_Geometry) VrmlData_ShapeConvert::triToIndexedFaceSet
+ (const Handle(Poly_Triangulation)& theTri,
const TopoDS_Face& theFace,
- const Handle_VrmlData_Coordinate& theCoord)
+ const Handle(VrmlData_Coordinate)& theCoord)
{
Standard_Integer i;
const Standard_Integer nNodes (theTri->NbNodes());
const TColgp_Array1OfPnt& arrPolyNodes = theTri->Nodes();
const Poly_Array1OfTriangle& arrTriangles = theTri->Triangles();
+ // protection against creation degenerative triangles
+ Standard_Integer nbTri = 0;
+ Poly_Array1OfTriangle aTriangles(1, nTriangles);
+ for (i = 0; i < nTriangles; i++) {
+ Standard_Integer idx[3];
+ arrTriangles(i + 1).Get(idx[0], idx[1], idx[2]);
+ if (idx[0] == idx[1] || idx[0] == idx[2] || idx[1] == idx[2])
+ {
+ continue;
+ }
+ nbTri++;
+ aTriangles.SetValue(nbTri, arrTriangles(i + 1));
+ }
+ aTriangles.Resize(1, nbTri, Standard_True);
+
const Handle(VrmlData_IndexedFaceSet) aFaceSet =
new VrmlData_IndexedFaceSet (myScene,
0L, // no name
// Create the array of triangles
const Standard_Integer ** arrPolygons = static_cast<const Standard_Integer **>
- (anAlloc->Allocate (nTriangles * sizeof(const Standard_Integer *)));
- aFaceSet->SetPolygons (nTriangles, arrPolygons);
+ (anAlloc->Allocate (nbTri * sizeof(const Standard_Integer *)));
+ aFaceSet->SetPolygons (nbTri, arrPolygons);
// Store the triangles
- for (i = 0; i < nTriangles; i++) {
+ for (i = 0; i < nbTri; i++) {
Standard_Integer * aPolygon = static_cast<Standard_Integer *>
(anAlloc->Allocate (4*sizeof(Standard_Integer)));
aPolygon[0] = 3;
- arrTriangles(i+1).Get (aPolygon[1],aPolygon[2],aPolygon[3]);
+ aTriangles(i + 1).Get(aPolygon[1], aPolygon[2], aPolygon[3]);
aPolygon[1]--;
if (isReverse) {
const Standard_Integer aTmp = aPolygon[2]-1;
new VrmlData_Normal (myScene, 0L, nNodes, arrVec);
myScene.AddNode (aNormalNode, Standard_False);
aFaceSet->SetNormals (aNormalNode);
- return aFaceSet;
+ return Handle(VrmlData_Geometry) (aFaceSet);
}
Poly_Connect PC(theTri);
// Create the Normals node (if UV- values are available)
TopLoc_Location aLoc;
- const Standard_Real aConf2 = Precision::Confusion()*Precision::Confusion();
+ const Standard_Real aConf2 = Precision::SquareConfusion();
const Handle(Geom_Surface) aSurface = BRep_Tool::Surface (theFace, aLoc);
if (theTri->HasUVNodes() && aSurface.IsNull() == Standard_False) {
if (aSurface->IsCNu(1) && aSurface->IsCNv(1))
gp_XYZ eqPlan(0., 0., 0.);
for (PC.Initialize(i+1); PC.More(); PC.Next()) {
- arrTriangles(PC.Value()).Get(n[0], n[1], n[2]);
+ aTriangles(PC.Value()).Get(n[0], n[1], n[2]);
gp_XYZ v1(arrPolyNodes(n[1]).Coord()-arrPolyNodes(n[0]).Coord());
gp_XYZ v2(arrPolyNodes(n[2]).Coord()-arrPolyNodes(n[1]).Coord());
gp_XYZ vv = v1^v2;
arrVec[i] = aNormal.XYZ();
Standard_Integer j = i * 3;
- Normals->SetValue(j + 1, aNormal.X());
- Normals->SetValue(j + 2, aNormal.Y());
- Normals->SetValue(j + 3, aNormal.Z());
+ Normals->SetValue(j + 1, (Standard_ShortReal)aNormal.X());
+ Normals->SetValue(j + 2, (Standard_ShortReal)aNormal.Y());
+ Normals->SetValue(j + 3, (Standard_ShortReal)aNormal.Z());
}
}
}
- return aFaceSet;
+ return Handle(VrmlData_Geometry) (aFaceSet);
}
//=======================================================================
//purpose : single polygon3D => IndexedLineSet
//=======================================================================
-Handle_VrmlData_Geometry VrmlData_ShapeConvert::polToIndexedLineSet
- (const Handle_Poly_Polygon3D& thePol)
+Handle(VrmlData_Geometry) VrmlData_ShapeConvert::polToIndexedLineSet
+ (const Handle(Poly_Polygon3D)& thePol)
{
Standard_Integer i;
const Standard_Integer nNodes (thePol->NbNodes());
myScene.AddNode (aCoordNode, Standard_False);
aLineSet->SetCoordinates (aCoordNode);
- return aLineSet;
+ return Handle(VrmlData_Geometry) (aLineSet);
}
//=======================================================================
}
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())
+ {
+ Handle(VrmlData_ShapeNode) aShapeNode = 0L;
+ if (aGroup.IsNull() && !aNameAttribute.IsNull())
+ {
+ TCollection_AsciiString aName = aNameAttribute->Get();
+ aName.ChangeAll(' ', '_');
+ 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 = aColorTool->GetColor(*aLabel, XCAFDoc_ColorSurf, aColorL)
+ || aColorTool->GetColor(*aLabel, XCAFDoc_ColorGen, aColorL);
+ }
+ if (!findColor)
+ {
+ findColor = aColorTool->GetColor(theLabel, XCAFDoc_ColorSurf, aColorL)
+ || aColorTool->GetColor(theLabel, XCAFDoc_ColorGen, aColorL);
+ }
+ 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())
+ {
+ aTrsf.SetScaleFactor(myScale);
+ }
+ 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()) {
+ aTrsf.SetScaleFactor(myScale);
+ }
+ 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->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->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());
+ Standard_Integer n = aNodeName.Search(" ");
+ if (n > 0)
+ {
+ aNodeName = aNodeName.SubString(1, n - 1);
+ }
+ }
+ 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;
+}
+
+