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