1 // Author: Kirill Gavrilov
2 // Copyright (c) 2019 OPEN CASCADE SAS
4 // This file is part of Open CASCADE Technology software library.
6 // This library is free software; you can redistribute it and/or modify it under
7 // the terms of the GNU Lesser General Public License version 2.1 as published
8 // by the Free Software Foundation, with special exception defined in the file
9 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
10 // distribution for complete text of the license and disclaimer of any warranty.
12 // Alternatively, this file may be used under the terms of Open CASCADE
13 // commercial license or contractual agreement.
15 #include <RWObj_TriangulationReader.hxx>
17 #include <BRep_Builder.hxx>
19 #include <TopoDS_Iterator.hxx>
21 IMPLEMENT_STANDARD_RTTIEXT(RWObj_TriangulationReader, RWObj_Reader)
23 //================================================================
26 //================================================================
27 Standard_Boolean RWObj_TriangulationReader::addMesh (const RWObj_SubMesh& theMesh,
28 const RWObj_SubMeshReason theReason)
30 if (!myToCreateShapes)
32 return Standard_False;
35 if (Handle(Poly_Triangulation) aTris = GetTriangulation())
41 if (theMesh.Group != myLastGroupName)
43 // flush previous group and start a new one
44 if (addSubShape (myLastObjectShape, myLastGroupShape, Standard_False))
46 if (myShapeReceiver != NULL)
48 const RWObj_Material* aMaterial = myLastGroupShape.ShapeType() == TopAbs_FACE
49 && !myLastFaceMaterial.IsEmpty()
50 ? myMaterials.Seek (myLastFaceMaterial)
52 myShapeReceiver->BindNamedShape (myLastGroupShape, myLastGroupName, aMaterial, Standard_False);
55 myLastGroupShape = TopoDS_Shape();
56 myLastGroupName = theMesh.Group;
60 BRep_Builder aBuilder;
61 aBuilder.MakeFace (aNewFace, aTris);
62 addSubShape (myLastGroupShape, aNewFace, Standard_True);
63 myLastFaceMaterial = theMesh.Material;
64 if (myShapeReceiver != NULL)
66 const RWObj_Material* aMaterial = myMaterials.Seek (theMesh.Material);
67 myShapeReceiver->BindNamedShape (aNewFace, "", aMaterial, Standard_False);
71 if (theReason == RWObj_SubMeshReason_NewObject)
73 // forced flush at the end of the object
74 if (addSubShape (myLastObjectShape, myLastGroupShape, Standard_False))
76 if (myShapeReceiver != NULL)
78 const RWObj_Material* aMaterial = myLastGroupShape.ShapeType() == TopAbs_FACE
79 && !myLastFaceMaterial.IsEmpty()
80 ? myMaterials.Seek (myLastFaceMaterial)
82 myShapeReceiver->BindNamedShape (myLastGroupShape, myLastGroupName, aMaterial, Standard_False);
85 myLastGroupShape = TopoDS_Shape();
86 myLastGroupName.Clear();
88 if (addSubShape (myResultShape, myLastObjectShape, Standard_False))
90 if (myShapeReceiver != NULL)
92 myShapeReceiver->BindNamedShape (myLastObjectShape, theMesh.Object, NULL, Standard_True);
95 myLastObjectShape = TopoDS_Compound();
100 // =======================================================================
101 // function : addSubShape
103 // =======================================================================
104 Standard_Boolean RWObj_TriangulationReader::addSubShape (TopoDS_Shape& theParent,
105 const TopoDS_Shape& theSubShape,
106 const Standard_Boolean theToExpandCompound)
108 if (theSubShape.IsNull())
110 return Standard_False;
113 BRep_Builder aBuilder;
114 if (theParent.IsNull()
115 && theToExpandCompound)
117 theParent = theSubShape;
118 return Standard_True;
121 TopoDS_Compound aComp;
122 if (!theParent.IsNull()
123 && theParent.ShapeType() == TopAbs_COMPOUND)
125 aComp = TopoDS::Compound (theParent);
129 aBuilder.MakeCompound (aComp);
130 if (!theParent.IsNull())
132 aBuilder.Add (aComp, theParent);
135 aBuilder.Add (aComp, theSubShape);
137 return Standard_True;
140 //=============================================================================
141 //function : GetTriangulation
143 //=============================================================================
144 Handle(Poly_Triangulation) RWObj_TriangulationReader::GetTriangulation()
146 if (myTriangles.IsEmpty())
148 return Handle(Poly_Triangulation)();
151 const Standard_Boolean hasNormals = myNodes.Length() == myNormals.Length();
152 const Standard_Boolean hasUV = myNodes.Length() == myNodesUV.Length();
154 Handle(Poly_Triangulation) aPoly = new Poly_Triangulation (myNodes.Length(), myTriangles.Length(), hasUV);
155 for (Standard_Integer aNodeIter = 0; aNodeIter < myNodes.Size(); ++aNodeIter)
157 const gp_Pnt& aNode = myNodes.Value (aNodeIter);
158 aPoly->SetNode (aNodeIter + 1, aNode);
162 for (Standard_Integer aNodeIter = 0; aNodeIter < myNodes.Size(); ++aNodeIter)
164 const Graphic3d_Vec2& aNode = myNodesUV.Value (aNodeIter);
165 aPoly->SetUVNode (aNodeIter + 1, gp_Pnt2d (aNode.x(), aNode.y()));
171 Standard_Integer aNbInvalid = 0;
172 for (Standard_Integer aNodeIter = 0; aNodeIter < myNodes.Size(); ++aNodeIter)
174 const Graphic3d_Vec3& aNorm = myNormals.Value (aNodeIter);
175 const float aMod2 = aNorm.SquareModulus();
178 aPoly->SetNormal (aNodeIter + 1, aNorm);
183 aPoly->SetNormal (aNodeIter + 1, Graphic3d_Vec3 (0.0f, 0.0f, 1.0f));
186 if (aNbInvalid == myNodes.Length())
188 aPoly->RemoveNormals();
192 for (Standard_Integer aTriIter = 0; aTriIter < myTriangles.Size(); ++aTriIter)
194 aPoly->SetTriangle (aTriIter + 1, myTriangles[aTriIter]);
200 //================================================================
201 // Function : ResultShape
203 //================================================================
204 TopoDS_Shape RWObj_TriangulationReader::ResultShape()
206 if (!myToCreateShapes)
208 if (Handle(Poly_Triangulation) aTris = GetTriangulation())
211 BRep_Builder aBuilder;
212 aBuilder.MakeFace (aFace, aTris);
215 return TopoDS_Shape();
218 if (!myResultShape.IsNull()
219 && myResultShape.ShapeType() == TopAbs_COMPOUND
220 && myResultShape.NbChildren() == 1
221 && myActiveSubMesh.Object.IsEmpty())
223 TopoDS_Iterator aChildIter (myResultShape);
224 return aChildIter.Value();
226 return myResultShape;