0029229: Crash at Poly_Triangulation::Normal
[occt.git] / src / Poly / Poly_Triangulation.cxx
1 // Created on: 1995-03-06
2 // Created by: Laurent PAINNOT
3 // Copyright (c) 1995-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
5 //
6 // This file is part of Open CASCADE Technology software library.
7 //
8 // This library is free software; you can redistribute it and/or modify it under
9 // the terms of the GNU Lesser General Public License version 2.1 as published
10 // by the Free Software Foundation, with special exception defined in the file
11 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12 // distribution for complete text of the license and disclaimer of any warranty.
13 //
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
16
17 #include <Poly_Triangulation.hxx>
18
19 #include <gp_Pnt.hxx>
20 #include <Poly_Triangle.hxx>
21 #include <Standard_DomainError.hxx>
22 #include <Standard_NullObject.hxx>
23 #include <Standard_Type.hxx>
24
25 IMPLEMENT_STANDARD_RTTIEXT (Poly_Triangulation, Standard_Transient)
26
27 //=======================================================================
28 //function : Poly_Triangulation
29 //purpose  : 
30 //=======================================================================
31 Poly_Triangulation::Poly_Triangulation(const Standard_Integer theNbNodes,
32                                        const Standard_Integer theNbTriangles,
33                                        const Standard_Boolean theHasUVNodes)
34 : myDeflection(0),
35   myNodes     (1, theNbNodes),
36   myTriangles (1, theNbTriangles)
37 {
38   if (theHasUVNodes) myUVNodes = new TColgp_HArray1OfPnt2d(1, theNbNodes);
39 }
40
41 //=======================================================================
42 //function : Poly_Triangulation
43 //purpose  : 
44 //=======================================================================
45
46 Poly_Triangulation::Poly_Triangulation(const TColgp_Array1OfPnt&    theNodes,
47                                        const Poly_Array1OfTriangle& theTriangles)
48 : myDeflection(0),
49   myNodes     (1, theNodes.Length()),
50   myTriangles (1, theTriangles.Length())
51 {
52   myNodes = theNodes;
53   myTriangles = theTriangles;
54 }
55
56 //=======================================================================
57 //function : Poly_Triangulation
58 //purpose  : 
59 //=======================================================================
60
61 Poly_Triangulation::Poly_Triangulation(const TColgp_Array1OfPnt&    theNodes,
62                                        const TColgp_Array1OfPnt2d&  theUVNodes,
63                                        const Poly_Array1OfTriangle& theTriangles)
64 : myDeflection(0),
65   myNodes     (1, theNodes.Length()),
66   myTriangles (1, theTriangles.Length())
67 {
68   myNodes = theNodes;
69   myTriangles = theTriangles;
70   myUVNodes = new TColgp_HArray1OfPnt2d (1, theNodes.Length());
71   myUVNodes->ChangeArray1() = theUVNodes;
72 }
73
74 //=======================================================================
75 //function : Copy
76 //purpose  : 
77 //=======================================================================
78
79 Handle(Poly_Triangulation) Poly_Triangulation::Copy() const
80 {
81   Handle(Poly_Triangulation) aCopy;
82   if (HasUVNodes())
83     aCopy = new Poly_Triangulation(Nodes(), UVNodes(), Triangles());
84   else
85     aCopy = new Poly_Triangulation(Nodes(), Triangles());
86   aCopy->Deflection(myDeflection);
87   if (HasNormals())
88     aCopy->myNormals = new TShort_HArray1OfShortReal(myNormals->Array1());
89
90   return aCopy;
91 }
92
93 //=======================================================================
94 //function : Poly_Triangulation
95 //purpose  : 
96 //=======================================================================
97
98 Poly_Triangulation::Poly_Triangulation (const Handle(Poly_Triangulation)& theTriangulation)
99 : myDeflection ( theTriangulation->myDeflection ),
100   myNodes(theTriangulation->Nodes()),
101   myTriangles(theTriangulation->Triangles())
102 {
103   if (theTriangulation->HasUVNodes())
104   {
105     myUVNodes = new TColgp_HArray1OfPnt2d(theTriangulation->myUVNodes->Array1());
106   }
107   if (theTriangulation->HasNormals())
108   {
109     myNormals = new TShort_HArray1OfShortReal(theTriangulation->myNormals->Array1());
110   }
111 }
112
113 //=======================================================================
114 //function : Deflection
115 //purpose  : 
116 //=======================================================================
117
118 void Poly_Triangulation::Deflection(const Standard_Real theDeflection)
119 {
120   myDeflection = theDeflection;
121 }
122
123 //=======================================================================
124 //function : RemoveUVNodes
125 //purpose  : 
126 //=======================================================================
127
128 void Poly_Triangulation::RemoveUVNodes()
129 {
130   myUVNodes.Nullify();
131 }
132
133 //=======================================================================
134 //function : Node
135 //purpose  : 
136 //=======================================================================
137
138 const gp_Pnt& Poly_Triangulation::Node (const Standard_Integer theIndex) const
139 {
140   if (theIndex < 1 || theIndex > myNodes.Size())
141   {
142     throw Standard_OutOfRange ("Poly_Triangulation::Node : index out of range");
143   }
144   return myNodes.Value (theIndex);
145 }
146
147 //=======================================================================
148 //function : ChangeNode
149 //purpose  : 
150 //=======================================================================
151
152 gp_Pnt& Poly_Triangulation::ChangeNode (const Standard_Integer theIndex)
153 {
154   if (theIndex < 1 || theIndex > myNodes.Size())
155   {
156     throw Standard_OutOfRange ("Poly_Triangulation::ChangeNode : index out of range");
157   }
158   return myNodes.ChangeValue (theIndex);
159 }
160
161 //=======================================================================
162 //function : UVNode
163 //purpose  : 
164 //=======================================================================
165
166 const gp_Pnt2d& Poly_Triangulation::UVNode (const Standard_Integer theIndex) const
167 {
168   if (myUVNodes.IsNull() || theIndex < 1 || theIndex > myUVNodes->Size())
169   {
170     throw Standard_OutOfRange ("Poly_Triangulation::UVNode : index out of range");
171   }
172   return myUVNodes->Value (theIndex);
173 }
174
175 //=======================================================================
176 //function : ChangeUVNode
177 //purpose  : 
178 //=======================================================================
179
180 gp_Pnt2d& Poly_Triangulation::ChangeUVNode (const Standard_Integer theIndex)
181 {
182   if (myUVNodes.IsNull() || theIndex < 1 || theIndex > myUVNodes->Size())
183   {
184     throw Standard_OutOfRange ("Poly_Triangulation::ChangeUVNode : index out of range");
185   }
186   return myUVNodes->ChangeValue (theIndex);
187 }
188
189 //=======================================================================
190 //function : Triangle
191 //purpose  : 
192 //=======================================================================
193
194 const Poly_Triangle& Poly_Triangulation::Triangle (const Standard_Integer theIndex) const
195 {
196   if (theIndex < 1 || theIndex > myTriangles.Size())
197   {
198     throw Standard_OutOfRange ("Poly_Triangulation::Triangle : index out of range");
199   }
200   return myTriangles.Value (theIndex);
201 }
202
203 //=======================================================================
204 //function : ChangeTriangle
205 //purpose  : 
206 //=======================================================================
207
208 Poly_Triangle& Poly_Triangulation::ChangeTriangle (const Standard_Integer theIndex)
209 {
210   if (theIndex < 1 || theIndex > myTriangles.Size())
211   {
212     throw Standard_OutOfRange ("Poly_Triangulation::ChangeTriangle : index out of range");
213   }
214   return myTriangles.ChangeValue (theIndex);
215 }
216
217 //=======================================================================
218 //function : SetNormals
219 //purpose  : 
220 //=======================================================================
221
222 void Poly_Triangulation::SetNormals (const Handle(TShort_HArray1OfShortReal)& theNormals)
223 {
224
225   if(theNormals.IsNull() || theNormals->Length() != 3 * NbNodes()) {
226     throw Standard_DomainError("Poly_Triangulation::SetNormals : wrong length");
227   }
228
229   myNormals = theNormals;
230 }
231
232 //=======================================================================
233 //function : Normals
234 //purpose  : 
235 //=======================================================================
236
237 const TShort_Array1OfShortReal& Poly_Triangulation::Normals() const
238 {
239
240   if(myNormals.IsNull() || myNormals->Length() != 3 * NbNodes()) {
241     throw Standard_NullObject("Poly_Triangulation::Normals : "
242                               "wrong length or null array");
243   }
244
245   return myNormals->Array1();
246 }
247
248 //=======================================================================
249 //function : ChangeNormals
250 //purpose  : 
251 //=======================================================================
252
253 TShort_Array1OfShortReal& Poly_Triangulation::ChangeNormals()
254 {
255
256   if(myNormals.IsNull() || myNormals->Length() != 3 * NbNodes()) {
257     throw Standard_NullObject("Poly_Triangulation::ChangeNormals : "
258                               "wrong length or null array");
259   }
260
261   return myNormals->ChangeArray1();
262 }
263
264 //=======================================================================
265 //function : HasNormals
266 //purpose  : 
267 //=======================================================================
268
269 Standard_Boolean Poly_Triangulation::HasNormals() const
270 {
271   if(myNormals.IsNull() || myNormals->Length() != 3 * NbNodes()) {
272     return Standard_False;
273   }
274   return Standard_True;
275 }
276
277 //=======================================================================
278 //function : SetNormal
279 //purpose  : 
280 //=======================================================================
281
282 void Poly_Triangulation::SetNormal (const Standard_Integer theIndex, const gp_Dir& theNormal)
283 {
284   if (myNormals.IsNull() || theIndex < 1 || theIndex > myNodes.Size())
285   {
286     throw Standard_NullObject ("Poly_Triangulation::SetNormal : empty array or index out of range");
287   }
288
289   myNormals->ChangeValue (theIndex * 3 - 2) = (Standard_ShortReal) theNormal.X();
290   myNormals->ChangeValue (theIndex * 3 - 1) = (Standard_ShortReal) theNormal.Y();
291   myNormals->ChangeValue (theIndex * 3)     = (Standard_ShortReal) theNormal.Z();
292 }
293
294 //=======================================================================
295 //function : Normal
296 //purpose  : 
297 //=======================================================================
298
299 gp_Dir Poly_Triangulation::Normal (const Standard_Integer theIndex) const
300 {
301   if (myNormals.IsNull() || theIndex < 1 || theIndex > myNodes.Size())
302   {
303     throw Standard_NullObject ("Poly_Triangulation::Normal : empty array or index out of range");
304   }
305
306   gp_Dir N(myNormals->Value(theIndex * 3 - 2),
307            myNormals->Value(theIndex * 3 - 1),
308            myNormals->Value(theIndex * 3));
309
310   return N;
311 }