0031501: Foundation Classes, Message_Printer - remove theToPutEndl argument -- use...
[occt.git] / src / RWObj / RWObj_TriangulationReader.cxx
CommitLineData
4151c94d 1// Author: Kirill Gavrilov
2// Copyright (c) 2019 OPEN CASCADE SAS
3//
4// This file is part of Open CASCADE Technology software library.
5//
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.
11//
12// Alternatively, this file may be used under the terms of Open CASCADE
13// commercial license or contractual agreement.
14
15#include <RWObj_TriangulationReader.hxx>
16
17#include <BRep_Builder.hxx>
18#include <TopoDS.hxx>
19#include <TopoDS_Iterator.hxx>
20
21IMPLEMENT_STANDARD_RTTIEXT(RWObj_TriangulationReader, RWObj_Reader)
22
23//================================================================
24// Function : addMesh
25// Purpose :
26//================================================================
27Standard_Boolean RWObj_TriangulationReader::addMesh (const RWObj_SubMesh& theMesh,
28 const RWObj_SubMeshReason theReason)
29{
30 if (!myToCreateShapes)
31 {
32 return Standard_False;
33 }
34
4151c94d 35 if (Handle(Poly_Triangulation) aTris = GetTriangulation())
36 {
37 myNodes.Clear();
38 myNodesUV.Clear();
39 myNormals.Clear();
40 myTriangles.Clear();
41 if (theMesh.Group != myLastGroupName)
42 {
43 // flush previous group and start a new one
44 if (addSubShape (myLastObjectShape, myLastGroupShape, Standard_False))
45 {
46 if (myShapeReceiver != NULL)
47 {
d9dd0754 48 const RWObj_Material* aMaterial = myLastGroupShape.ShapeType() == TopAbs_FACE
49 && !myLastFaceMaterial.IsEmpty()
50 ? myMaterials.Seek (myLastFaceMaterial)
51 : NULL;
52 myShapeReceiver->BindNamedShape (myLastGroupShape, myLastGroupName, aMaterial, Standard_False);
4151c94d 53 }
54 }
55 myLastGroupShape = TopoDS_Shape();
56 myLastGroupName = theMesh.Group;
57 }
58
59 TopoDS_Face aNewFace;
60 BRep_Builder aBuilder;
61 aBuilder.MakeFace (aNewFace, aTris);
62 addSubShape (myLastGroupShape, aNewFace, Standard_True);
d9dd0754 63 myLastFaceMaterial = theMesh.Material;
4151c94d 64 if (myShapeReceiver != NULL)
65 {
d9dd0754 66 const RWObj_Material* aMaterial = myMaterials.Seek (theMesh.Material);
4151c94d 67 myShapeReceiver->BindNamedShape (aNewFace, "", aMaterial, Standard_False);
68 }
69 }
70
71 if (theReason == RWObj_SubMeshReason_NewObject)
72 {
73 // forced flush at the end of the object
74 if (addSubShape (myLastObjectShape, myLastGroupShape, Standard_False))
75 {
76 if (myShapeReceiver != NULL)
77 {
d9dd0754 78 const RWObj_Material* aMaterial = myLastGroupShape.ShapeType() == TopAbs_FACE
79 && !myLastFaceMaterial.IsEmpty()
80 ? myMaterials.Seek (myLastFaceMaterial)
81 : NULL;
82 myShapeReceiver->BindNamedShape (myLastGroupShape, myLastGroupName, aMaterial, Standard_False);
4151c94d 83 }
84 }
85 myLastGroupShape = TopoDS_Shape();
86 myLastGroupName.Clear();
87
88 if (addSubShape (myResultShape, myLastObjectShape, Standard_False))
89 {
90 if (myShapeReceiver != NULL)
91 {
92 myShapeReceiver->BindNamedShape (myLastObjectShape, theMesh.Object, NULL, Standard_True);
93 }
94 }
95 myLastObjectShape = TopoDS_Compound();
96 }
97 return Standard_True;
98}
99
100// =======================================================================
101// function : addSubShape
102// purpose :
103// =======================================================================
104Standard_Boolean RWObj_TriangulationReader::addSubShape (TopoDS_Shape& theParent,
105 const TopoDS_Shape& theSubShape,
106 const Standard_Boolean theToExpandCompound)
107{
108 if (theSubShape.IsNull())
109 {
110 return Standard_False;
111 }
112
113 BRep_Builder aBuilder;
114 if (theParent.IsNull()
115 && theToExpandCompound)
116 {
117 theParent = theSubShape;
118 return Standard_True;
119 }
120
121 TopoDS_Compound aComp;
122 if (!theParent.IsNull()
123 && theParent.ShapeType() == TopAbs_COMPOUND)
124 {
125 aComp = TopoDS::Compound (theParent);
126 }
127 else
128 {
129 aBuilder.MakeCompound (aComp);
130 if (!theParent.IsNull())
131 {
132 aBuilder.Add (aComp, theParent);
133 }
134 }
135 aBuilder.Add (aComp, theSubShape);
136 theParent = aComp;
137 return Standard_True;
138}
139
140//=============================================================================
141//function : GetTriangulation
142//purpose :
143//=============================================================================
144Handle(Poly_Triangulation) RWObj_TriangulationReader::GetTriangulation()
145{
146 if (myTriangles.IsEmpty())
147 {
148 return Handle(Poly_Triangulation)();
149 }
150
151 const Standard_Boolean hasNormals = myNodes.Length() == myNormals.Length();
152 const Standard_Boolean hasUV = myNodes.Length() == myNodesUV.Length();
153
154 Handle(Poly_Triangulation) aPoly = new Poly_Triangulation (myNodes.Length(), myTriangles.Length(), hasUV);
155 for (Standard_Integer aNodeIter = 0; aNodeIter < myNodes.Size(); ++aNodeIter)
156 {
157 const gp_Pnt& aNode = myNodes.Value (aNodeIter);
158 aPoly->ChangeNode (aNodeIter + 1) = aNode;
159 }
160 if (hasUV)
161 {
162 for (Standard_Integer aNodeIter = 0; aNodeIter < myNodes.Size(); ++aNodeIter)
163 {
164 const Graphic3d_Vec2& aNode = myNodesUV.Value (aNodeIter);
165 aPoly->ChangeUVNode (aNodeIter + 1).SetCoord (aNode.x(), aNode.y());
166 }
167 }
168 if (hasNormals)
169 {
170 const Handle(TShort_HArray1OfShortReal) aNormals = new TShort_HArray1OfShortReal (1, myNodes.Length() * 3);
171 Standard_ShortReal* aNormArr = &aNormals->ChangeFirst();
172 Standard_Integer aNbInvalid = 0;
173 for (Standard_Integer aNodeIter = 0; aNodeIter < myNodes.Size(); ++aNodeIter)
174 {
175 const Graphic3d_Vec3& aNorm = myNormals.Value (aNodeIter);
176 const float aMod2 = aNorm.SquareModulus();
177 if (aMod2 > 0.001f)
178 {
179 aNormArr[aNodeIter * 3 + 0] = aNorm.x();
180 aNormArr[aNodeIter * 3 + 1] = aNorm.y();
181 aNormArr[aNodeIter * 3 + 2] = aNorm.z();
182 }
183 else
184 {
185 ++aNbInvalid;
186 aNormArr[aNodeIter * 3 + 0] = 0.0f;
187 aNormArr[aNodeIter * 3 + 1] = 0.0f;
188 aNormArr[aNodeIter * 3 + 2] = 1.0f;
189 }
190 }
191 if (aNbInvalid != myNodes.Length())
192 {
193 aPoly->SetNormals (aNormals);
194 }
195 }
196
197 for (Standard_Integer aTriIter = 0; aTriIter < myTriangles.Size(); ++aTriIter)
198 {
199 aPoly->ChangeTriangle (aTriIter + 1) = myTriangles (aTriIter);
200 }
201
202 return aPoly;
203}
204
205//================================================================
206// Function : ResultShape
207// Purpose :
208//================================================================
209TopoDS_Shape RWObj_TriangulationReader::ResultShape()
210{
211 if (!myToCreateShapes)
212 {
213 if (Handle(Poly_Triangulation) aTris = GetTriangulation())
214 {
215 TopoDS_Face aFace;
216 BRep_Builder aBuilder;
217 aBuilder.MakeFace (aFace, aTris);
218 return aFace;
219 }
220 return TopoDS_Shape();
221 }
222
223 if (!myResultShape.IsNull()
224 && myResultShape.ShapeType() == TopAbs_COMPOUND
225 && myResultShape.NbChildren() == 1
226 && myActiveSubMesh.Object.IsEmpty())
227 {
228 TopoDS_Iterator aChildIter (myResultShape);
229 return aChildIter.Value();
230 }
231 return myResultShape;
232}