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 | |
21 | IMPLEMENT_STANDARD_RTTIEXT(RWObj_TriangulationReader, RWObj_Reader) |
22 | |
23 | //================================================================ |
24 | // Function : addMesh |
25 | // Purpose : |
26 | //================================================================ |
27 | Standard_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 | // ======================================================================= |
104 | Standard_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 | //============================================================================= |
144 | Handle(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 | //================================================================ |
209 | TopoDS_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 | } |