#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
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 =
+ makeTShapeNode(aShape, ShapeType[i], aLoc);
+ /*
Handle(VrmlData_Geometry) aTShapeNode;
const Standard_Boolean isReverse=(aShape.Orientation()==TopAbs_REVERSED);
Handle(Poly_Triangulation) aTri =
BRep_Tool::Triangulation (aFace, aLoc);
- if (aRelMap.IsBound (aTestedShape)) {
- aTShapeNode = aRelMap(aTestedShape);
+ if (myRelMap.IsBound (aTestedShape)) {
+ aTShapeNode = myRelMap(aTestedShape);
break;
}
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)
aTShapeNode = triToIndexedFaceSet (aTri, aFace, aCoordToReuse);
myScene.AddNode (aTShapeNode, Standard_False);
// Bind the converted face
- aRelMap.Bind (aTestedShape, aTShapeNode);
+ myRelMap.Bind (aTestedShape, aTShapeNode);
}
}
}
{
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;
}
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);
}
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;
+}
+
+