1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-08-14 13:30:48 +03:00

0030115: Implementation of import from XCAF to VRML.

This commit is contained in:
skl
2018-09-06 11:18:13 +03:00
committed by bugmaster
parent eaac086605
commit a3506de770
14 changed files with 641 additions and 150 deletions

View File

@@ -30,7 +30,12 @@
#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>
@@ -45,6 +50,10 @@
#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,131 +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;
const Standard_Boolean isReverse=(aShape.Orientation()==TopAbs_REVERSED);
TopoDS_Shape aTestedShape;
aTestedShape.TShape (aShape.TShape());
aTestedShape.Orientation (isReverse ? TopAbs_REVERSED : TopAbs_FORWARD);
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() == 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) {
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;
}
//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,
theDeflAngle, aDeflection, 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 (aDeflection);
}
}
if (aPol.IsNull())
continue;
aTShapeNode = polToIndexedLineSet (aPol);
myScene.AddNode (aTShapeNode, Standard_False);
// Bind the converted face
aRelMap.Bind (aTestedShape, aTShapeNode);
}
}
break;
default:
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 ?
@@ -301,6 +328,21 @@ Handle(VrmlData_Geometry) VrmlData_ShapeConvert::triToIndexedFaceSet
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
@@ -312,15 +354,15 @@ Handle(VrmlData_Geometry) VrmlData_ShapeConvert::triToIndexedFaceSet
// 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;
@@ -396,7 +438,7 @@ Handle(VrmlData_Geometry) VrmlData_ShapeConvert::triToIndexedFaceSet
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;
@@ -537,3 +579,331 @@ 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())
{
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;
}

View File

@@ -18,7 +18,9 @@
#include <VrmlData_Geometry.hxx>
#include <VrmlData_Appearance.hxx>
#include <VrmlData_Group.hxx>
#include <NCollection_List.hxx>
#include <NCollection_DataMap.hxx>
#include <TopoDS_Shape.hxx>
class VrmlData_Scene;
@@ -26,6 +28,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 +91,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 +112,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&);
};