b311480e |
1 | // Created on: 2000-06-16 |
973c2be1 |
2 | // Copyright (c) 2000-2014 OPEN CASCADE SAS |
b311480e |
3 | // |
973c2be1 |
4 | // This file is part of Open CASCADE Technology software library. |
b311480e |
5 | // |
d5f74e42 |
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 |
973c2be1 |
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. |
b311480e |
11 | // |
973c2be1 |
12 | // Alternatively, this file may be used under the terms of Open CASCADE |
13 | // commercial license or contractual agreement. |
7fd59977 |
14 | |
7fd59977 |
15 | #include <Graphic3d_ArrayOfPrimitives.ixx> |
16 | #include <Standard.hxx> |
17 | #include <TCollection_AsciiString.hxx> |
18 | #include <OSD_Environment.hxx> |
871fa103 |
19 | #include <NCollection_AlignedAllocator.hxx> |
7fd59977 |
20 | |
21 | #include <stdio.h> |
22 | #include <stdlib.h> |
23 | |
7d3e64ef |
24 | |
7d3e64ef |
25 | |
ec357c5c |
26 | |
27 | |
7d3e64ef |
28 | |
871fa103 |
29 | Graphic3d_ArrayOfPrimitives::Graphic3d_ArrayOfPrimitives (const Graphic3d_TypeOfPrimitiveArray theType, |
30 | const Standard_Integer theMaxVertexs, |
31 | const Standard_Integer theMaxBounds, |
32 | const Standard_Integer theMaxEdges, |
33 | const Standard_Boolean theHasVNormals, |
34 | const Standard_Boolean theHasVColors, |
35 | const Standard_Boolean theHasFColors, |
36 | const Standard_Boolean theHasVTexels) |
37 | : myType (theType), |
38 | myMaxBounds (0), |
39 | myMaxVertexs (0), |
40 | myMaxEdges (0), |
41 | myVNor (0), |
42 | myVTex (0), |
43 | myVCol (0) |
44 | { |
45 | Handle(NCollection_AlignedAllocator) anAlloc = new NCollection_AlignedAllocator (16); |
46 | myAttribs = new Graphic3d_Buffer (anAlloc); |
47 | if (theMaxVertexs < 1) |
48 | { |
49 | return; |
7fd59977 |
50 | } |
51 | |
871fa103 |
52 | if (theMaxEdges > 0) |
53 | { |
54 | myIndices = new Graphic3d_IndexBuffer (anAlloc); |
55 | if (theMaxEdges < Standard_Integer(USHRT_MAX)) |
56 | { |
57 | if (!myIndices->Init<unsigned short> (theMaxEdges)) |
58 | { |
59 | myIndices.Nullify(); |
60 | return; |
61 | } |
62 | } |
63 | else |
64 | { |
65 | if (!myIndices->Init<unsigned int> (theMaxEdges)) |
66 | { |
67 | myIndices.Nullify(); |
68 | return; |
69 | } |
70 | } |
71 | myIndices->NbElements = 0; |
7fd59977 |
72 | } |
73 | |
871fa103 |
74 | Graphic3d_Attribute anAttribs[4]; |
75 | Standard_Integer aNbAttribs = 0; |
76 | anAttribs[aNbAttribs].Id = Graphic3d_TOA_POS; |
77 | anAttribs[aNbAttribs].DataType = Graphic3d_TOD_VEC3; |
78 | ++aNbAttribs; |
79 | if (theHasVNormals) |
80 | { |
81 | anAttribs[aNbAttribs].Id = Graphic3d_TOA_NORM; |
82 | anAttribs[aNbAttribs].DataType = Graphic3d_TOD_VEC3; |
83 | ++aNbAttribs; |
7fd59977 |
84 | } |
871fa103 |
85 | if (theHasVTexels) |
86 | { |
87 | anAttribs[aNbAttribs].Id = Graphic3d_TOA_UV; |
88 | anAttribs[aNbAttribs].DataType = Graphic3d_TOD_VEC2; |
89 | ++aNbAttribs; |
7fd59977 |
90 | } |
871fa103 |
91 | if (theHasVColors) |
92 | { |
93 | anAttribs[aNbAttribs].Id = Graphic3d_TOA_COLOR; |
94 | anAttribs[aNbAttribs].DataType = Graphic3d_TOD_VEC4UB; |
95 | ++aNbAttribs; |
7fd59977 |
96 | } |
97 | |
871fa103 |
98 | if (!myAttribs->Init (theMaxVertexs, anAttribs, aNbAttribs)) |
99 | { |
100 | myAttribs.Nullify(); |
101 | myIndices.Nullify(); |
102 | return; |
7fd59977 |
103 | } |
871fa103 |
104 | memset (myAttribs->ChangeData (0), 0, myAttribs->Stride * myAttribs->NbElements); |
105 | |
106 | if (theMaxBounds > 0) |
107 | { |
108 | myBounds = new Graphic3d_BoundBuffer (anAlloc); |
109 | if (!myBounds->Init (theMaxBounds, theHasFColors)) |
110 | { |
111 | myAttribs.Nullify(); |
112 | myIndices.Nullify(); |
113 | myBounds .Nullify(); |
114 | return; |
7fd59977 |
115 | } |
871fa103 |
116 | myBounds->NbBounds = 0; |
117 | } |
7fd59977 |
118 | |
871fa103 |
119 | for (Standard_Integer anAttribIter = 0; anAttribIter < aNbAttribs; ++anAttribIter) |
120 | { |
121 | const Graphic3d_Attribute& anAttrib = anAttribs[anAttribIter]; |
122 | switch (anAttrib.Id) |
123 | { |
124 | case Graphic3d_TOA_POS: |
125 | case Graphic3d_TOA_CUSTOM: |
126 | break; |
127 | case Graphic3d_TOA_NORM: |
128 | { |
129 | myVNor = static_cast<Standard_Byte>(myAttribs->AttributeOffset (anAttribIter)); |
130 | break; |
131 | } |
132 | case Graphic3d_TOA_UV: |
133 | { |
134 | myVTex = static_cast<Standard_Byte>(myAttribs->AttributeOffset (anAttribIter)); |
135 | break; |
136 | } |
137 | case Graphic3d_TOA_COLOR: |
138 | { |
139 | myVCol = static_cast<Standard_Byte>(myAttribs->AttributeOffset (anAttribIter)); |
140 | break; |
141 | } |
7fd59977 |
142 | } |
7fd59977 |
143 | } |
7fd59977 |
144 | |
871fa103 |
145 | myAttribs->NbElements = 0; |
146 | myMaxVertexs = theMaxVertexs; |
147 | myMaxBounds = theMaxBounds; |
148 | myMaxEdges = theMaxEdges; |
7fd59977 |
149 | } |
150 | |
871fa103 |
151 | void Graphic3d_ArrayOfPrimitives::Destroy() |
b8ddfc2f |
152 | { |
871fa103 |
153 | myVNor = 0; |
154 | myVTex = 0; |
155 | myVCol = 0; |
156 | myIndices.Nullify(); |
157 | myAttribs.Nullify(); |
158 | myBounds .Nullify(); |
7fd59977 |
159 | } |
b8ddfc2f |
160 | |
871fa103 |
161 | Standard_Integer Graphic3d_ArrayOfPrimitives::AddVertex (const Standard_ShortReal theX, |
162 | const Standard_ShortReal theY, |
163 | const Standard_ShortReal theZ) |
b8ddfc2f |
164 | { |
871fa103 |
165 | if (myAttribs.IsNull()) |
166 | { |
167 | return 0; |
168 | } |
169 | |
170 | const Standard_Integer anIndex = myAttribs->NbElements + 1; |
171 | SetVertice (anIndex, theX, theY, theZ); |
172 | return anIndex; |
7fd59977 |
173 | } |
174 | |
871fa103 |
175 | Standard_Integer Graphic3d_ArrayOfPrimitives::AddVertex (const gp_Pnt& theVertex, |
176 | const Quantity_Color& theColor) |
b8ddfc2f |
177 | { |
871fa103 |
178 | const Standard_Integer anIndex = AddVertex (theVertex); |
179 | SetVertexColor (anIndex, theColor.Red(), theColor.Green(), theColor.Blue()); |
180 | return anIndex; |
7fd59977 |
181 | } |
182 | |
871fa103 |
183 | Standard_Integer Graphic3d_ArrayOfPrimitives::AddVertex (const gp_Pnt& theVertex, |
184 | const Standard_Integer theColor32) |
b8ddfc2f |
185 | { |
871fa103 |
186 | const Standard_Integer anIndex = AddVertex (theVertex); |
187 | SetVertexColor (anIndex, theColor32); |
188 | return anIndex; |
7fd59977 |
189 | } |
190 | |
871fa103 |
191 | Standard_Integer Graphic3d_ArrayOfPrimitives::AddVertex (const Standard_ShortReal theX, const Standard_ShortReal theY, const Standard_ShortReal theZ, |
192 | const Standard_ShortReal theNX, const Standard_ShortReal theNY, const Standard_ShortReal theNZ) |
b8ddfc2f |
193 | { |
871fa103 |
194 | if (myAttribs.IsNull()) |
195 | { |
196 | return 0; |
197 | } |
198 | |
199 | const Standard_Integer anIndex = myAttribs->NbElements + 1; |
200 | SetVertice (anIndex, theX, theY, theZ); |
201 | SetVertexNormal (anIndex, theNX, theNY, theNZ); |
202 | return anIndex; |
7fd59977 |
203 | } |
204 | |
871fa103 |
205 | Standard_Integer Graphic3d_ArrayOfPrimitives::AddVertex (const gp_Pnt& theVertex, |
206 | const gp_Dir& theNormal, |
207 | const Quantity_Color& theColor) |
b8ddfc2f |
208 | { |
871fa103 |
209 | const Standard_Integer anIndex = AddVertex (theVertex, theNormal); |
210 | SetVertexColor (anIndex, theColor.Red(), theColor.Green(), theColor.Blue()); |
211 | return anIndex; |
7fd59977 |
212 | } |
213 | |
871fa103 |
214 | Standard_Integer Graphic3d_ArrayOfPrimitives::AddVertex (const gp_Pnt& theVertex, |
215 | const gp_Dir& theNormal, |
216 | const Standard_Integer theColor32) |
b8ddfc2f |
217 | { |
871fa103 |
218 | const Standard_Integer anIndex = AddVertex (theVertex, theNormal); |
219 | SetVertexColor (anIndex, theColor32); |
220 | return anIndex; |
7fd59977 |
221 | } |
222 | |
871fa103 |
223 | Standard_Integer Graphic3d_ArrayOfPrimitives::AddVertex (const Standard_ShortReal theX, const Standard_ShortReal theY, const Standard_ShortReal theZ, |
224 | const Standard_ShortReal theTX, const Standard_ShortReal theTY) |
b8ddfc2f |
225 | { |
871fa103 |
226 | if (myAttribs.IsNull()) |
227 | { |
228 | return 0; |
7fd59977 |
229 | } |
230 | |
871fa103 |
231 | const Standard_Integer anIndex = myAttribs->NbElements + 1; |
232 | SetVertice (anIndex, theX, theY, theZ); |
233 | SetVertexTexel (anIndex, theTX, theTY); |
234 | return anIndex; |
7fd59977 |
235 | } |
236 | |
871fa103 |
237 | Standard_Integer Graphic3d_ArrayOfPrimitives::AddVertex (const Standard_ShortReal theX, const Standard_ShortReal theY, const Standard_ShortReal theZ, |
238 | const Standard_ShortReal theNX, const Standard_ShortReal theNY, const Standard_ShortReal theNZ, |
239 | const Standard_ShortReal theTX, const Standard_ShortReal theTY) |
b8ddfc2f |
240 | { |
871fa103 |
241 | if (myAttribs.IsNull()) |
242 | { |
243 | return 0; |
244 | } |
7fd59977 |
245 | |
871fa103 |
246 | const Standard_Integer anIndex = myAttribs->NbElements + 1; |
247 | SetVertice (anIndex, theX, theY, theZ); |
248 | SetVertexNormal (anIndex, theNX, theNY, theNZ); |
249 | SetVertexTexel (anIndex, theTX, theTY); |
250 | return anIndex; |
7fd59977 |
251 | } |
252 | |
871fa103 |
253 | Standard_Integer Graphic3d_ArrayOfPrimitives::AddBound (const Standard_Integer theEdgeNumber) |
b8ddfc2f |
254 | { |
871fa103 |
255 | if (myBounds.IsNull()) |
256 | { |
257 | return 0; |
7fd59977 |
258 | } |
871fa103 |
259 | Standard_Integer anIndex = myBounds->NbBounds; |
260 | if (anIndex >= myMaxBounds) |
261 | { |
262 | Standard_OutOfRange::Raise ("TOO many BOUNDS"); |
7fd59977 |
263 | } |
264 | |
871fa103 |
265 | myBounds->Bounds[anIndex] = theEdgeNumber; |
266 | myBounds->NbBounds = ++anIndex; |
267 | return anIndex; |
7fd59977 |
268 | } |
269 | |
871fa103 |
270 | Standard_Integer Graphic3d_ArrayOfPrimitives::AddBound (const Standard_Integer theEdgeNumber, |
271 | const Quantity_Color& theColor) |
b8ddfc2f |
272 | { |
871fa103 |
273 | return AddBound (theEdgeNumber, theColor.Red(), theColor.Green(), theColor.Blue()); |
7fd59977 |
274 | } |
275 | |
871fa103 |
276 | Standard_Integer Graphic3d_ArrayOfPrimitives::AddBound (const Standard_Integer theEdgeNumber, |
277 | const Standard_Real theR, |
278 | const Standard_Real theG, |
279 | const Standard_Real theB) |
b8ddfc2f |
280 | { |
871fa103 |
281 | if (myBounds.IsNull()) |
282 | { |
283 | return 0; |
284 | } |
285 | Standard_Integer anIndex = myBounds->NbBounds; |
286 | if (anIndex >= myMaxBounds) |
287 | { |
288 | Standard_OutOfRange::Raise ("TOO many BOUND"); |
7fd59977 |
289 | } |
871fa103 |
290 | |
291 | myBounds->Bounds[anIndex] = theEdgeNumber; |
292 | myBounds->NbBounds = ++anIndex; |
293 | SetBoundColor (anIndex, theR, theG, theB); |
294 | return anIndex; |
7fd59977 |
295 | } |
296 | |
871fa103 |
297 | Standard_Integer Graphic3d_ArrayOfPrimitives::AddEdge (const Standard_Integer theVertexIndex) |
b8ddfc2f |
298 | { |
871fa103 |
299 | if (myIndices.IsNull()) |
300 | { |
301 | return 0; |
302 | } |
303 | |
304 | Standard_Integer anIndex = myIndices->NbElements; |
305 | if (anIndex >= myMaxEdges) |
306 | { |
307 | Standard_OutOfRange::Raise ("TOO many EDGE"); |
308 | } |
309 | |
310 | Standard_Integer aVertIndex = theVertexIndex - 1; |
311 | if (theVertexIndex <= 0 |
312 | || aVertIndex >= myMaxVertexs) |
313 | { |
314 | Standard_OutOfRange::Raise ("BAD EDGE vertex index"); |
7fd59977 |
315 | } |
871fa103 |
316 | |
317 | myIndices->SetIndex (anIndex, aVertIndex); |
318 | myIndices->NbElements = ++anIndex; |
319 | return anIndex; |
7fd59977 |
320 | } |
321 | |
871fa103 |
322 | void Graphic3d_ArrayOfPrimitives::SetVertice (const Standard_Integer theIndex, |
323 | const gp_Pnt& theVertex) |
b8ddfc2f |
324 | { |
871fa103 |
325 | SetVertice (theIndex, |
326 | Standard_ShortReal (theVertex.X()), |
327 | Standard_ShortReal (theVertex.Y()), |
328 | Standard_ShortReal (theVertex.Z())); |
7fd59977 |
329 | } |
330 | |
871fa103 |
331 | void Graphic3d_ArrayOfPrimitives::SetVertexColor (const Standard_Integer theIndex, |
332 | const Quantity_Color& theColor) |
b8ddfc2f |
333 | { |
871fa103 |
334 | SetVertexColor (theIndex, theColor.Red(), theColor.Green(), theColor.Blue()); |
7fd59977 |
335 | } |
336 | |
871fa103 |
337 | void Graphic3d_ArrayOfPrimitives::SetVertexColor (const Standard_Integer theIndex, |
338 | const Standard_Integer theColor) |
b8ddfc2f |
339 | { |
871fa103 |
340 | if (myAttribs.IsNull()) |
341 | { |
342 | return; |
343 | } |
7fd59977 |
344 | |
871fa103 |
345 | if (theIndex < 1 |
346 | || theIndex > myMaxVertexs) |
347 | { |
348 | Standard_OutOfRange::Raise ("BAD VERTEX index"); |
349 | } |
350 | |
351 | if (myVCol != 0) |
352 | { |
353 | *reinterpret_cast<Standard_Integer* >(myAttribs->changeValue (theIndex - 1) + size_t(myVCol)) = theColor; |
7fd59977 |
354 | } |
355 | } |
b8ddfc2f |
356 | |
871fa103 |
357 | void Graphic3d_ArrayOfPrimitives::SetVertexNormal (const Standard_Integer theIndex, |
358 | const gp_Dir& theNormal) |
b8ddfc2f |
359 | { |
871fa103 |
360 | SetVertexNormal (theIndex, theNormal.X(), theNormal.Y(), theNormal.Z()); |
7fd59977 |
361 | } |
362 | |
871fa103 |
363 | void Graphic3d_ArrayOfPrimitives::SetVertexTexel (const Standard_Integer theIndex, |
364 | const gp_Pnt2d& theTexel) |
b8ddfc2f |
365 | { |
871fa103 |
366 | SetVertexTexel (theIndex, theTexel.X(), theTexel.Y()); |
7fd59977 |
367 | } |
368 | |
871fa103 |
369 | void Graphic3d_ArrayOfPrimitives::SetBoundColor (const Standard_Integer theIndex, |
370 | const Quantity_Color& theColor) |
b8ddfc2f |
371 | { |
871fa103 |
372 | SetBoundColor (theIndex, theColor.Red(), theColor.Green(), theColor.Blue()); |
7fd59977 |
373 | } |
374 | |
b8ddfc2f |
375 | Standard_CString Graphic3d_ArrayOfPrimitives::StringType() const |
376 | { |
871fa103 |
377 | switch (myType) |
378 | { |
379 | case Graphic3d_TOPA_POINTS: return "ArrayOfPoints"; |
380 | case Graphic3d_TOPA_POLYLINES: return "ArrayOfPolylines"; |
381 | case Graphic3d_TOPA_SEGMENTS: return "ArrayOfSegments"; |
382 | case Graphic3d_TOPA_POLYGONS: return "ArrayOfPolygons"; |
383 | case Graphic3d_TOPA_TRIANGLES: return "ArrayOfTriangles"; |
384 | case Graphic3d_TOPA_QUADRANGLES: return "ArrayOfQuadrangles"; |
385 | case Graphic3d_TOPA_TRIANGLESTRIPS: return "ArrayOfTriangleStrips"; |
386 | case Graphic3d_TOPA_QUADRANGLESTRIPS: return "ArrayOfQuadrangleStrips"; |
387 | case Graphic3d_TOPA_TRIANGLEFANS: return "ArrayOfTriangleFans"; |
388 | case Graphic3d_TOPA_UNDEFINED: return "UndefinedArray"; |
7fd59977 |
389 | } |
871fa103 |
390 | return "UndefinedArray"; |
7fd59977 |
391 | } |
392 | |
871fa103 |
393 | gp_Pnt Graphic3d_ArrayOfPrimitives::Vertice (const Standard_Integer theRank) const |
b8ddfc2f |
394 | { |
871fa103 |
395 | Standard_Real anXYZ[3]; |
396 | Vertice (theRank, anXYZ[0], anXYZ[1], anXYZ[2]); |
397 | return gp_Pnt (anXYZ[0], anXYZ[1], anXYZ[2]); |
7fd59977 |
398 | } |
399 | |
871fa103 |
400 | Quantity_Color Graphic3d_ArrayOfPrimitives::VertexColor (const Standard_Integer theRank) const |
b8ddfc2f |
401 | { |
871fa103 |
402 | Standard_Real anRGB[3]; |
403 | VertexColor (theRank, anRGB[0], anRGB[1], anRGB[2]); |
404 | return Quantity_Color (anRGB[0], anRGB[1], anRGB[2], Quantity_TOC_RGB); |
7fd59977 |
405 | } |
406 | |
871fa103 |
407 | gp_Dir Graphic3d_ArrayOfPrimitives::VertexNormal (const Standard_Integer theRank) const |
b8ddfc2f |
408 | { |
871fa103 |
409 | Standard_Real anXYZ[3]; |
410 | VertexNormal (theRank, anXYZ[0], anXYZ[1], anXYZ[2]); |
411 | return gp_Dir (anXYZ[0], anXYZ[1], anXYZ[2]); |
7fd59977 |
412 | } |
413 | |
871fa103 |
414 | gp_Pnt2d Graphic3d_ArrayOfPrimitives::VertexTexel (const Standard_Integer theRank) const |
b8ddfc2f |
415 | { |
871fa103 |
416 | Standard_Real anXY[2]; |
417 | VertexTexel (theRank, anXY[0], anXY[1]); |
418 | return gp_Pnt2d (anXY[0], anXY[1]); |
7fd59977 |
419 | } |
420 | |
871fa103 |
421 | Quantity_Color Graphic3d_ArrayOfPrimitives::BoundColor (const Standard_Integer theRank) const |
b8ddfc2f |
422 | { |
871fa103 |
423 | Standard_Real anRGB[3] = {0.0, 0.0, 0.0}; |
424 | BoundColor (theRank, anRGB[0], anRGB[1], anRGB[2]); |
425 | return Quantity_Color (anRGB[0], anRGB[1], anRGB[2], Quantity_TOC_RGB); |
7fd59977 |
426 | } |
427 | |
b8ddfc2f |
428 | Standard_Integer Graphic3d_ArrayOfPrimitives::ItemNumber() const |
429 | { |
871fa103 |
430 | if (myAttribs.IsNull()) |
431 | { |
432 | return -1; |
7fd59977 |
433 | } |
434 | |
871fa103 |
435 | switch (myType) |
436 | { |
437 | case Graphic3d_TOPA_POINTS: return myAttribs->NbElements; |
438 | case Graphic3d_TOPA_POLYLINES: |
439 | case Graphic3d_TOPA_POLYGONS: return !myBounds.IsNull() ? myBounds->NbBounds : 1; |
440 | case Graphic3d_TOPA_SEGMENTS: return myIndices.IsNull() || myIndices->NbElements < 1 |
441 | ? myAttribs->NbElements / 2 |
442 | : myIndices->NbElements / 2; |
443 | case Graphic3d_TOPA_TRIANGLES: return myIndices.IsNull() || myIndices->NbElements < 1 |
444 | ? myAttribs->NbElements / 3 |
445 | : myIndices->NbElements / 3; |
446 | case Graphic3d_TOPA_QUADRANGLES: return myIndices.IsNull() || myIndices->NbElements < 1 |
447 | ? myAttribs->NbElements / 4 |
448 | : myIndices->NbElements / 4; |
449 | case Graphic3d_TOPA_TRIANGLESTRIPS: return !myBounds.IsNull() |
450 | ? myAttribs->NbElements - 2 * myBounds->NbBounds |
451 | : myAttribs->NbElements - 2; |
452 | case Graphic3d_TOPA_QUADRANGLESTRIPS: return !myBounds.IsNull() |
453 | ? myAttribs->NbElements / 2 - myBounds->NbBounds |
454 | : myAttribs->NbElements / 2 - 1; |
455 | case Graphic3d_TOPA_TRIANGLEFANS: return !myBounds.IsNull() |
456 | ? myAttribs->NbElements - 2 * myBounds->NbBounds |
457 | : myAttribs->NbElements - 2; |
458 | case Graphic3d_TOPA_UNDEFINED: return -1; |
459 | } |
460 | return -1; |
7fd59977 |
461 | } |
462 | |
871fa103 |
463 | void Graphic3d_ArrayOfPrimitives::ComputeVNormals (const Standard_Integer theFrom, |
464 | const Standard_Integer theTo) |
b8ddfc2f |
465 | { |
871fa103 |
466 | Standard_Integer aNext = theFrom + 1; |
467 | Standard_Integer aLast = theTo + 1; |
468 | gp_Pnt aTri[3]; |
469 | if (myMaxEdges > 0) |
470 | { |
471 | aTri[0] = Vertice (Edge (aNext++)); |
472 | aTri[1] = Vertice (Edge (aNext++)); |
473 | } |
474 | else |
475 | { |
476 | aTri[0] = Vertice (aNext++); |
477 | aTri[1] = Vertice (aNext++); |
7fd59977 |
478 | } |
479 | |
480 | gp_Vec vn; |
871fa103 |
481 | while (aNext <= aLast) |
482 | { |
483 | if (myMaxEdges > 0) |
484 | { |
485 | aTri[2] = Vertice (Edge (aNext)); |
7fd59977 |
486 | } |
871fa103 |
487 | else |
488 | { |
489 | aTri[2] = Vertice (aNext); |
490 | } |
491 | gp_Vec v21 (aTri[1], aTri[0]); |
492 | gp_Vec v31 (aTri[2], aTri[0]); |
7fd59977 |
493 | vn = v21 ^ v31; |
871fa103 |
494 | if (vn.SquareMagnitude() > 0.0) |
495 | { |
496 | break; |
497 | } |
498 | aNext++; |
7fd59977 |
499 | } |
500 | |
871fa103 |
501 | if (aNext > aLast) |
502 | { |
7fd59977 |
503 | return; |
504 | } |
505 | |
506 | vn.Normalize(); |
871fa103 |
507 | if (myMaxEdges > 0) |
508 | { |
509 | for (int i = theFrom + 1; i <= theTo + 1; i++) |
510 | { |
511 | SetVertexNormal (Edge (i), vn); |
7fd59977 |
512 | } |
871fa103 |
513 | } |
514 | else |
515 | { |
516 | for (int i = theFrom + 1; i <= theTo + 1; i++) |
517 | { |
518 | SetVertexNormal (i, vn); |
7fd59977 |
519 | } |
520 | } |
521 | } |
522 | |
b8ddfc2f |
523 | Standard_Boolean Graphic3d_ArrayOfPrimitives::IsValid() |
524 | { |
871fa103 |
525 | if (myAttribs.IsNull()) |
526 | { |
527 | return Standard_False; |
528 | } |
529 | |
530 | Standard_Integer nvertexs = myAttribs->NbElements; |
531 | Standard_Integer nbounds = myBounds.IsNull() ? 0 : myBounds->NbBounds; |
532 | Standard_Integer nedges = myIndices.IsNull() ? 0 : myIndices->NbElements; |
533 | switch (myType) |
534 | { |
535 | case Graphic3d_TOPA_POINTS: |
536 | if (nvertexs < 1) |
537 | { |
7fd59977 |
538 | return Standard_False; |
539 | } |
540 | break; |
871fa103 |
541 | case Graphic3d_TOPA_POLYLINES: |
542 | if (nedges > 0 |
543 | && nedges < 2) |
544 | { |
7fd59977 |
545 | return Standard_False; |
546 | } |
871fa103 |
547 | if (nvertexs < 2) |
548 | { |
7fd59977 |
549 | return Standard_False; |
550 | } |
551 | break; |
871fa103 |
552 | case Graphic3d_TOPA_SEGMENTS: |
553 | if (nvertexs < 2) |
554 | { |
7fd59977 |
555 | return Standard_False; |
556 | } |
557 | break; |
871fa103 |
558 | case Graphic3d_TOPA_POLYGONS: |
559 | if (nedges > 0 |
560 | && nedges < 3) |
561 | { |
7fd59977 |
562 | return Standard_False; |
563 | } |
871fa103 |
564 | if (nvertexs < 3) |
565 | { |
7fd59977 |
566 | return Standard_False; |
567 | } |
568 | break; |
871fa103 |
569 | case Graphic3d_TOPA_TRIANGLES: |
570 | if (nedges > 0) |
571 | { |
572 | if (nedges < 3 |
573 | || nedges % 3 != 0) |
574 | { |
575 | if (nedges <= 3) |
576 | { |
577 | return Standard_False; |
578 | } |
579 | myIndices->NbElements = 3 * (nedges / 3); |
580 | } |
581 | } |
582 | else if (nvertexs < 3 |
583 | || nvertexs % 3 != 0 ) |
584 | { |
585 | if (nvertexs <= 3) |
586 | { |
587 | return Standard_False; |
7fd59977 |
588 | } |
871fa103 |
589 | myAttribs->NbElements = 3 * (nvertexs / 3); |
7fd59977 |
590 | } |
591 | break; |
871fa103 |
592 | case Graphic3d_TOPA_QUADRANGLES: |
593 | if (nedges > 0) |
594 | { |
595 | if (nedges < 4 |
596 | || nedges % 4 != 0) |
597 | { |
598 | if (nedges <= 4) |
599 | { |
600 | return Standard_False; |
601 | } |
602 | myIndices->NbElements = 4 * (nedges / 4); |
603 | } |
604 | } |
605 | else if (nvertexs < 4 |
606 | || nvertexs % 4 != 0) |
607 | { |
608 | if (nvertexs <= 4) |
609 | { |
610 | return Standard_False; |
7fd59977 |
611 | } |
871fa103 |
612 | myAttribs->NbElements = 4 * (nvertexs / 4); |
7fd59977 |
613 | } |
614 | break; |
871fa103 |
615 | case Graphic3d_TOPA_TRIANGLEFANS: |
616 | case Graphic3d_TOPA_TRIANGLESTRIPS: |
617 | if (nvertexs < 3) |
618 | { |
7fd59977 |
619 | return Standard_False; |
620 | } |
621 | break; |
871fa103 |
622 | case Graphic3d_TOPA_QUADRANGLESTRIPS: |
623 | if (nvertexs < 4) |
624 | { |
7fd59977 |
625 | return Standard_False; |
626 | } |
627 | break; |
871fa103 |
628 | case Graphic3d_TOPA_UNDEFINED: |
7fd59977 |
629 | default: |
7fd59977 |
630 | return Standard_False; |
631 | } |
632 | |
871fa103 |
633 | // total number of edges(vertices) in bounds should be the same as variable |
634 | // of total number of defined edges(vertices); if no edges - only vertices |
9558a876 |
635 | // could be in bounds. |
871fa103 |
636 | if (nbounds > 0) |
637 | { |
638 | Standard_Integer n = 0; |
639 | for (Standard_Integer aBoundIter = 0; aBoundIter < nbounds; ++aBoundIter) |
640 | { |
641 | n += myBounds->Bounds[aBoundIter]; |
7fd59977 |
642 | } |
871fa103 |
643 | if (nedges > 0 |
644 | && n != nedges) |
645 | { |
646 | if (nedges <= n) |
647 | { |
648 | return Standard_False; |
649 | } |
650 | myIndices->NbElements = n; |
651 | } |
652 | else if (nedges == 0 |
653 | && n != nvertexs) |
654 | { |
655 | if (nvertexs <= n) |
656 | { |
657 | return Standard_False; |
658 | } |
659 | myAttribs->NbElements = n; |
7fd59977 |
660 | } |
661 | } |
662 | |
871fa103 |
663 | // check that edges (indexes to an array of vertices) are in range. |
664 | if (nedges > 0) |
665 | { |
666 | for (Standard_Integer anEdgeIter = 0; anEdgeIter < nedges; ++anEdgeIter) |
667 | { |
668 | if (myIndices->Index (anEdgeIter) >= myAttribs->NbElements) |
669 | { |
670 | return Standard_False; |
7fd59977 |
671 | } |
672 | } |
673 | } |
7fd59977 |
674 | return Standard_True; |
675 | } |