0024023: Revamp the OCCT Handle -- general
[occt.git] / src / Graphic3d / Graphic3d_ArrayOfPrimitives.cxx
CommitLineData
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 29Graphic3d_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 151void 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 161Standard_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 175Standard_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 183Standard_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 191Standard_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 205Standard_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 214Standard_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 223Standard_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 237Standard_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 253Standard_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 270Standard_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 276Standard_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 297Standard_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 322void 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 331void 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 337void 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 357void 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 363void 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 369void 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 375Standard_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 393gp_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 400Quantity_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 407gp_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 414gp_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 421Quantity_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 428Standard_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 463void 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 523Standard_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}