1 // Created on: 2000-06-16
2 // Copyright (c) 2000-2014 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 <Graphic3d_ArrayOfPrimitives.hxx>
16
17 #include <Graphic3d_ArrayOfPoints.hxx>
18 #include <Graphic3d_ArrayOfSegments.hxx>
19 #include <Graphic3d_ArrayOfPolylines.hxx>
20 #include <Graphic3d_ArrayOfTriangles.hxx>
21 #include <Graphic3d_ArrayOfTriangleStrips.hxx>
22 #include <Graphic3d_ArrayOfTriangleFans.hxx>
23 #include <Graphic3d_ArrayOfQuadrangles.hxx>
24 #include <Graphic3d_ArrayOfQuadrangleStrips.hxx>
25 #include <Graphic3d_ArrayOfPolygons.hxx>
26 #include <Graphic3d_AttribBuffer.hxx>
27 #include <Graphic3d_MutableIndexBuffer.hxx>
28
29 #include <TCollection_AsciiString.hxx>
30
31 #include <stdio.h>
32 #include <stdlib.h>
33
IMPLEMENT_STANDARD_RTTIEXT(Graphic3d_ArrayOfPrimitives,Standard_Transient)34 IMPLEMENT_STANDARD_RTTIEXT(Graphic3d_ArrayOfPrimitives, Standard_Transient)
35
36 IMPLEMENT_STANDARD_RTTIEXT(Graphic3d_ArrayOfPoints, Graphic3d_ArrayOfPrimitives)
37 IMPLEMENT_STANDARD_RTTIEXT(Graphic3d_ArrayOfSegments, Graphic3d_ArrayOfPrimitives)
38 IMPLEMENT_STANDARD_RTTIEXT(Graphic3d_ArrayOfPolylines, Graphic3d_ArrayOfPrimitives)
39 IMPLEMENT_STANDARD_RTTIEXT(Graphic3d_ArrayOfTriangles, Graphic3d_ArrayOfPrimitives)
40 IMPLEMENT_STANDARD_RTTIEXT(Graphic3d_ArrayOfTriangleStrips, Graphic3d_ArrayOfPrimitives)
41 IMPLEMENT_STANDARD_RTTIEXT(Graphic3d_ArrayOfTriangleFans, Graphic3d_ArrayOfPrimitives)
42 IMPLEMENT_STANDARD_RTTIEXT(Graphic3d_ArrayOfQuadrangles, Graphic3d_ArrayOfPrimitives)
43 IMPLEMENT_STANDARD_RTTIEXT(Graphic3d_ArrayOfQuadrangleStrips, Graphic3d_ArrayOfPrimitives)
44 IMPLEMENT_STANDARD_RTTIEXT(Graphic3d_ArrayOfPolygons, Graphic3d_ArrayOfPrimitives)
45
46 // =======================================================================
47 // function : CreateArray
48 // purpose :
49 // =======================================================================
50 Handle(Graphic3d_ArrayOfPrimitives) Graphic3d_ArrayOfPrimitives::CreateArray (Graphic3d_TypeOfPrimitiveArray theType,
51 Standard_Integer theMaxVertexs,
52 Standard_Integer theMaxBounds,
53 Standard_Integer theMaxEdges,
54 Graphic3d_ArrayFlags theArrayFlags)
55 {
56 switch (theType)
57 {
58 case Graphic3d_TOPA_UNDEFINED:
59 return Handle(Graphic3d_ArrayOfPrimitives)();
60 case Graphic3d_TOPA_POINTS:
61 return new Graphic3d_ArrayOfPoints (theMaxVertexs, theArrayFlags);
62 case Graphic3d_TOPA_SEGMENTS:
63 return new Graphic3d_ArrayOfSegments (theMaxVertexs, theMaxEdges, theArrayFlags);
64 case Graphic3d_TOPA_POLYLINES:
65 return new Graphic3d_ArrayOfPolylines (theMaxVertexs, theMaxBounds, theMaxEdges, theArrayFlags);
66 case Graphic3d_TOPA_TRIANGLES:
67 return new Graphic3d_ArrayOfTriangles (theMaxVertexs, theMaxEdges, theArrayFlags);
68 case Graphic3d_TOPA_TRIANGLESTRIPS:
69 return new Graphic3d_ArrayOfTriangleStrips (theMaxVertexs, theMaxBounds, theArrayFlags);
70 case Graphic3d_TOPA_TRIANGLEFANS:
71 return new Graphic3d_ArrayOfTriangleFans (theMaxVertexs, theMaxBounds, theArrayFlags);
72 case Graphic3d_TOPA_LINES_ADJACENCY:
73 case Graphic3d_TOPA_LINE_STRIP_ADJACENCY:
74 case Graphic3d_TOPA_TRIANGLES_ADJACENCY:
75 case Graphic3d_TOPA_TRIANGLE_STRIP_ADJACENCY:
76 return new Graphic3d_ArrayOfPrimitives (theType, theMaxVertexs, theMaxBounds, theMaxEdges, theArrayFlags);
77 case Graphic3d_TOPA_QUADRANGLES:
78 return new Graphic3d_ArrayOfQuadrangles (theMaxVertexs, theMaxEdges, theArrayFlags);
79 case Graphic3d_TOPA_QUADRANGLESTRIPS:
80 return new Graphic3d_ArrayOfQuadrangleStrips (theMaxVertexs, theMaxBounds, theArrayFlags);
81 case Graphic3d_TOPA_POLYGONS:
82 return new Graphic3d_ArrayOfPolygons (theMaxVertexs, theMaxBounds, theMaxEdges, theArrayFlags);
83 }
84 return Handle(Graphic3d_ArrayOfPrimitives)();
85 }
86
87 // =======================================================================
88 // function : init
89 // purpose :
90 // =======================================================================
init(Graphic3d_TypeOfPrimitiveArray theType,Standard_Integer theMaxVertexs,Standard_Integer theMaxBounds,Standard_Integer theMaxEdges,Graphic3d_ArrayFlags theArrayOptions)91 void Graphic3d_ArrayOfPrimitives::init (Graphic3d_TypeOfPrimitiveArray theType,
92 Standard_Integer theMaxVertexs,
93 Standard_Integer theMaxBounds,
94 Standard_Integer theMaxEdges,
95 Graphic3d_ArrayFlags theArrayOptions)
96 {
97 myType = theType;
98 myNormData = NULL;
99 myTexData = NULL;
100 myColData = NULL;
101 myAttribs.Nullify();
102 myIndices.Nullify();
103 myBounds.Nullify();
104
105 const Handle(NCollection_BaseAllocator)& anAlloc = Graphic3d_Buffer::DefaultAllocator();
106 if ((theArrayOptions & Graphic3d_ArrayFlags_AttribsMutable) != 0
107 || (theArrayOptions & Graphic3d_ArrayFlags_AttribsDeinterleaved) != 0)
108 {
109 Graphic3d_AttribBuffer* anAttribs = new Graphic3d_AttribBuffer (anAlloc);
110 anAttribs->SetMutable ((theArrayOptions & Graphic3d_ArrayFlags_AttribsMutable) != 0);
111 anAttribs->SetInterleaved ((theArrayOptions & Graphic3d_ArrayFlags_AttribsDeinterleaved) == 0);
112 myAttribs = anAttribs;
113 }
114 else
115 {
116 myAttribs = new Graphic3d_Buffer (anAlloc);
117 }
118 if (theMaxVertexs < 1)
119 {
120 return;
121 }
122
123 if (theMaxEdges > 0)
124 {
125 if ((theArrayOptions & Graphic3d_ArrayFlags_IndexesMutable) != 0)
126 {
127 myIndices = new Graphic3d_MutableIndexBuffer (anAlloc);
128 }
129 else
130 {
131 myIndices = new Graphic3d_IndexBuffer (anAlloc);
132 }
133 if (theMaxVertexs < Standard_Integer(USHRT_MAX))
134 {
135 if (!myIndices->Init<unsigned short> (theMaxEdges))
136 {
137 myIndices.Nullify();
138 return;
139 }
140 }
141 else
142 {
143 if (!myIndices->Init<unsigned int> (theMaxEdges))
144 {
145 myIndices.Nullify();
146 return;
147 }
148 }
149 myIndices->NbElements = 0;
150 }
151
152 Graphic3d_Attribute anAttribs[4];
153 Standard_Integer aNbAttribs = 0;
154 anAttribs[aNbAttribs].Id = Graphic3d_TOA_POS;
155 anAttribs[aNbAttribs].DataType = Graphic3d_TOD_VEC3;
156 ++aNbAttribs;
157 if ((theArrayOptions & Graphic3d_ArrayFlags_VertexNormal) != 0)
158 {
159 anAttribs[aNbAttribs].Id = Graphic3d_TOA_NORM;
160 anAttribs[aNbAttribs].DataType = Graphic3d_TOD_VEC3;
161 ++aNbAttribs;
162 }
163 if ((theArrayOptions & Graphic3d_ArrayFlags_VertexTexel) != 0)
164 {
165 anAttribs[aNbAttribs].Id = Graphic3d_TOA_UV;
166 anAttribs[aNbAttribs].DataType = Graphic3d_TOD_VEC2;
167 ++aNbAttribs;
168 }
169 if ((theArrayOptions & Graphic3d_ArrayFlags_VertexColor) != 0)
170 {
171 anAttribs[aNbAttribs].Id = Graphic3d_TOA_COLOR;
172 anAttribs[aNbAttribs].DataType = Graphic3d_TOD_VEC4UB;
173 ++aNbAttribs;
174 }
175
176 if (!myAttribs->Init (theMaxVertexs, anAttribs, aNbAttribs))
177 {
178 myAttribs.Nullify();
179 myIndices.Nullify();
180 return;
181 }
182
183 Standard_Integer anAttribDummy = 0;
184 myAttribs->ChangeAttributeData (Graphic3d_TOA_POS, anAttribDummy, myPosStride);
185 myNormData = myAttribs->ChangeAttributeData (Graphic3d_TOA_NORM, anAttribDummy, myNormStride);
186 myTexData = myAttribs->ChangeAttributeData (Graphic3d_TOA_UV, anAttribDummy, myTexStride);
187 myColData = myAttribs->ChangeAttributeData (Graphic3d_TOA_COLOR, anAttribDummy, myColStride);
188
189 memset (myAttribs->ChangeData(), 0, size_t(myAttribs->Stride) * size_t(myAttribs->NbMaxElements()));
190 if ((theArrayOptions & Graphic3d_ArrayFlags_AttribsMutable) == 0
191 && (theArrayOptions & Graphic3d_ArrayFlags_AttribsDeinterleaved) == 0)
192 {
193 myAttribs->NbElements = 0;
194 }
195
196 if (theMaxBounds > 0)
197 {
198 myBounds = new Graphic3d_BoundBuffer (anAlloc);
199 if (!myBounds->Init (theMaxBounds, (theArrayOptions & Graphic3d_ArrayFlags_BoundColor) != 0))
200 {
201 myAttribs.Nullify();
202 myIndices.Nullify();
203 myBounds .Nullify();
204 return;
205 }
206 myBounds->NbBounds = 0;
207 }
208 }
209
210 // =======================================================================
211 // function : ~Graphic3d_ArrayOfPrimitives
212 // purpose :
213 // =======================================================================
~Graphic3d_ArrayOfPrimitives()214 Graphic3d_ArrayOfPrimitives::~Graphic3d_ArrayOfPrimitives()
215 {
216 myIndices.Nullify();
217 myAttribs.Nullify();
218 myBounds .Nullify();
219 }
220
221 // =======================================================================
222 // function : AddBound
223 // purpose :
224 // =======================================================================
AddBound(const Standard_Integer theEdgeNumber)225 Standard_Integer Graphic3d_ArrayOfPrimitives::AddBound (const Standard_Integer theEdgeNumber)
226 {
227 Standard_OutOfRange_Raise_if (myBounds.IsNull() || myBounds->NbBounds >= myBounds->NbMaxBounds, "TOO many BOUND");
228 myBounds->Bounds[myBounds->NbBounds] = theEdgeNumber;
229 return ++myBounds->NbBounds;
230 }
231
232 // =======================================================================
233 // function : AddBound
234 // purpose :
235 // =======================================================================
AddBound(const Standard_Integer theEdgeNumber,const Standard_Real theR,const Standard_Real theG,const Standard_Real theB)236 Standard_Integer Graphic3d_ArrayOfPrimitives::AddBound (const Standard_Integer theEdgeNumber,
237 const Standard_Real theR,
238 const Standard_Real theG,
239 const Standard_Real theB)
240 {
241 Standard_OutOfRange_Raise_if (myBounds.IsNull() || myBounds->NbBounds >= myBounds->NbMaxBounds, "TOO many BOUND");
242 myBounds->Bounds[myBounds->NbBounds] = theEdgeNumber;
243 ++myBounds->NbBounds;
244 SetBoundColor (myBounds->NbBounds, theR, theG, theB);
245 return myBounds->NbBounds;
246 }
247
248 // =======================================================================
249 // function : AddEdge
250 // purpose :
251 // =======================================================================
AddEdge(const Standard_Integer theVertexIndex)252 Standard_Integer Graphic3d_ArrayOfPrimitives::AddEdge (const Standard_Integer theVertexIndex)
253 {
254 Standard_OutOfRange_Raise_if (myIndices.IsNull() || myIndices->NbElements >= myIndices->NbMaxElements(), "TOO many EDGE");
255 Standard_OutOfRange_Raise_if (theVertexIndex < 1 || theVertexIndex > myAttribs->NbElements, "BAD VERTEX index");
256 const Standard_Integer aVertIndex = theVertexIndex - 1;
257 myIndices->SetIndex (myIndices->NbElements, aVertIndex);
258 return ++myIndices->NbElements;
259 }
260
261 // =======================================================================
262 // function : AddTriangleStripEdges
263 // purpose :
264 // =======================================================================
AddTriangleStripEdges(Standard_Integer theVertexLower,Standard_Integer theVertexUpper)265 void Graphic3d_ArrayOfPrimitives::AddTriangleStripEdges (Standard_Integer theVertexLower,
266 Standard_Integer theVertexUpper)
267 {
268 if (myType != Graphic3d_TOPA_TRIANGLES)
269 {
270 throw Standard_TypeMismatch ("Not array of triangles");
271 }
272
273 Standard_Boolean isOdd = Standard_True;
274 for (Standard_Integer aNodeIter = theVertexLower + 2; aNodeIter <= theVertexUpper; ++aNodeIter)
275 {
276 if (isOdd)
277 {
278 AddTriangleEdges (aNodeIter - 2, aNodeIter - 1, aNodeIter);
279 }
280 else
281 {
282 AddTriangleEdges (aNodeIter - 1, aNodeIter - 2, aNodeIter);
283 }
284 isOdd = !isOdd;
285 }
286 }
287
288 // =======================================================================
289 // function : AddTriangleFanEdges
290 // purpose :
291 // =======================================================================
AddTriangleFanEdges(Standard_Integer theVertexLower,Standard_Integer theVertexUpper,Standard_Boolean theToClose)292 void Graphic3d_ArrayOfPrimitives::AddTriangleFanEdges (Standard_Integer theVertexLower,
293 Standard_Integer theVertexUpper,
294 Standard_Boolean theToClose)
295 {
296 if (myType != Graphic3d_TOPA_TRIANGLES)
297 {
298 throw Standard_TypeMismatch ("Not array of triangles");
299 }
300
301 for (Standard_Integer aNodeIter = theVertexLower + 1; aNodeIter <= theVertexUpper; ++aNodeIter)
302 {
303 AddTriangleEdges (theVertexLower, aNodeIter - 1, aNodeIter);
304 }
305 if (theToClose)
306 {
307 AddTriangleEdges (theVertexLower, theVertexUpper, theVertexLower + 1);
308 }
309 }
310
311 // =======================================================================
312 // function : AddPolylineEdges
313 // purpose :
314 // =======================================================================
AddPolylineEdges(Standard_Integer theVertexLower,Standard_Integer theVertexUpper,Standard_Boolean theToClose)315 void Graphic3d_ArrayOfPrimitives::AddPolylineEdges (Standard_Integer theVertexLower,
316 Standard_Integer theVertexUpper,
317 Standard_Boolean theToClose)
318 {
319 if (myType != Graphic3d_TOPA_SEGMENTS)
320 {
321 throw Standard_TypeMismatch ("Not array of segments");
322 }
323
324 for (Standard_Integer aNodeIter = theVertexLower; aNodeIter < theVertexUpper; ++aNodeIter)
325 {
326 AddSegmentEdges (aNodeIter, aNodeIter + 1);
327 }
328 if (theToClose)
329 {
330 AddSegmentEdges (theVertexUpper, theVertexLower);
331 }
332 }
333
334 // =======================================================================
335 // function : StringType
336 // purpose :
337 // =======================================================================
StringType() const338 Standard_CString Graphic3d_ArrayOfPrimitives::StringType() const
339 {
340 switch (myType)
341 {
342 case Graphic3d_TOPA_POINTS: return "ArrayOfPoints";
343 case Graphic3d_TOPA_SEGMENTS: return "ArrayOfSegments";
344 case Graphic3d_TOPA_POLYLINES: return "ArrayOfPolylines";
345 case Graphic3d_TOPA_TRIANGLES: return "ArrayOfTriangles";
346 case Graphic3d_TOPA_TRIANGLESTRIPS: return "ArrayOfTriangleStrips";
347 case Graphic3d_TOPA_TRIANGLEFANS: return "ArrayOfTriangleFans";
348 case Graphic3d_TOPA_LINES_ADJACENCY: return "ArrayOfLinesAdjacency";
349 case Graphic3d_TOPA_LINE_STRIP_ADJACENCY: return "ArrayOfLineStripAdjacency";
350 case Graphic3d_TOPA_TRIANGLES_ADJACENCY: return "ArrayOfTrianglesAdjacency";
351 case Graphic3d_TOPA_TRIANGLE_STRIP_ADJACENCY: return "ArrayOfTriangleStripAdjacency";
352 case Graphic3d_TOPA_QUADRANGLES: return "ArrayOfQuadrangles";
353 case Graphic3d_TOPA_QUADRANGLESTRIPS: return "ArrayOfQuadrangleStrips";
354 case Graphic3d_TOPA_POLYGONS: return "ArrayOfPolygons";
355 case Graphic3d_TOPA_UNDEFINED: return "UndefinedArray";
356 }
357 return "UndefinedArray";
358 }
359
360 // =======================================================================
361 // function : ItemNumber
362 // purpose :
363 // =======================================================================
ItemNumber() const364 Standard_Integer Graphic3d_ArrayOfPrimitives::ItemNumber() const
365 {
366 if (myAttribs.IsNull())
367 {
368 return -1;
369 }
370
371 switch (myType)
372 {
373 case Graphic3d_TOPA_POINTS: return myAttribs->NbElements;
374 case Graphic3d_TOPA_POLYLINES:
375 case Graphic3d_TOPA_POLYGONS: return !myBounds.IsNull() ? myBounds->NbBounds : 1;
376 case Graphic3d_TOPA_SEGMENTS: return myIndices.IsNull() || myIndices->NbElements < 1
377 ? myAttribs->NbElements / 2
378 : myIndices->NbElements / 2;
379 case Graphic3d_TOPA_TRIANGLES: return myIndices.IsNull() || myIndices->NbElements < 1
380 ? myAttribs->NbElements / 3
381 : myIndices->NbElements / 3;
382 case Graphic3d_TOPA_QUADRANGLES: return myIndices.IsNull() || myIndices->NbElements < 1
383 ? myAttribs->NbElements / 4
384 : myIndices->NbElements / 4;
385 case Graphic3d_TOPA_TRIANGLESTRIPS: return !myBounds.IsNull()
386 ? myAttribs->NbElements - 2 * myBounds->NbBounds
387 : myAttribs->NbElements - 2;
388 case Graphic3d_TOPA_QUADRANGLESTRIPS: return !myBounds.IsNull()
389 ? myAttribs->NbElements / 2 - myBounds->NbBounds
390 : myAttribs->NbElements / 2 - 1;
391 case Graphic3d_TOPA_TRIANGLEFANS: return !myBounds.IsNull()
392 ? myAttribs->NbElements - 2 * myBounds->NbBounds
393 : myAttribs->NbElements - 2;
394 case Graphic3d_TOPA_LINES_ADJACENCY: return myIndices.IsNull() || myIndices->NbElements < 1
395 ? myAttribs->NbElements / 4
396 : myIndices->NbElements / 4;
397 case Graphic3d_TOPA_LINE_STRIP_ADJACENCY: return !myBounds.IsNull()
398 ? myAttribs->NbElements - 4 * myBounds->NbBounds
399 : myAttribs->NbElements - 4;
400 case Graphic3d_TOPA_TRIANGLES_ADJACENCY: return myIndices.IsNull() || myIndices->NbElements < 1
401 ? myAttribs->NbElements / 6
402 : myIndices->NbElements / 6;
403 case Graphic3d_TOPA_TRIANGLE_STRIP_ADJACENCY: return !myBounds.IsNull()
404 ? myAttribs->NbElements - 4 * myBounds->NbBounds
405 : myAttribs->NbElements - 4;
406 case Graphic3d_TOPA_UNDEFINED: return -1;
407 }
408 return -1;
409 }
410
411 // =======================================================================
412 // function : IsValid
413 // purpose :
414 // =======================================================================
IsValid()415 Standard_Boolean Graphic3d_ArrayOfPrimitives::IsValid()
416 {
417 if (myAttribs.IsNull())
418 {
419 return Standard_False;
420 }
421
422 Standard_Integer nvertexs = myAttribs->NbElements;
423 Standard_Integer nbounds = myBounds.IsNull() ? 0 : myBounds->NbBounds;
424 Standard_Integer nedges = myIndices.IsNull() ? 0 : myIndices->NbElements;
425 switch (myType)
426 {
427 case Graphic3d_TOPA_POINTS:
428 if (nvertexs < 1)
429 {
430 return Standard_False;
431 }
432 break;
433 case Graphic3d_TOPA_POLYLINES:
434 if (nedges > 0
435 && nedges < 2)
436 {
437 return Standard_False;
438 }
439 if (nvertexs < 2)
440 {
441 return Standard_False;
442 }
443 break;
444 case Graphic3d_TOPA_SEGMENTS:
445 if (nvertexs < 2)
446 {
447 return Standard_False;
448 }
449 break;
450 case Graphic3d_TOPA_POLYGONS:
451 if (nedges > 0
452 && nedges < 3)
453 {
454 return Standard_False;
455 }
456 if (nvertexs < 3)
457 {
458 return Standard_False;
459 }
460 break;
461 case Graphic3d_TOPA_TRIANGLES:
462 if (nedges > 0)
463 {
464 if (nedges < 3
465 || nedges % 3 != 0)
466 {
467 if (nedges <= 3)
468 {
469 return Standard_False;
470 }
471 myIndices->NbElements = 3 * (nedges / 3);
472 }
473 }
474 else if (nvertexs < 3
475 || nvertexs % 3 != 0 )
476 {
477 if (nvertexs <= 3)
478 {
479 return Standard_False;
480 }
481 myAttribs->NbElements = 3 * (nvertexs / 3);
482 }
483 break;
484 case Graphic3d_TOPA_QUADRANGLES:
485 if (nedges > 0)
486 {
487 if (nedges < 4
488 || nedges % 4 != 0)
489 {
490 if (nedges <= 4)
491 {
492 return Standard_False;
493 }
494 myIndices->NbElements = 4 * (nedges / 4);
495 }
496 }
497 else if (nvertexs < 4
498 || nvertexs % 4 != 0)
499 {
500 if (nvertexs <= 4)
501 {
502 return Standard_False;
503 }
504 myAttribs->NbElements = 4 * (nvertexs / 4);
505 }
506 break;
507 case Graphic3d_TOPA_TRIANGLEFANS:
508 case Graphic3d_TOPA_TRIANGLESTRIPS:
509 if (nvertexs < 3)
510 {
511 return Standard_False;
512 }
513 break;
514 case Graphic3d_TOPA_QUADRANGLESTRIPS:
515 if (nvertexs < 4)
516 {
517 return Standard_False;
518 }
519 break;
520 case Graphic3d_TOPA_LINES_ADJACENCY:
521 case Graphic3d_TOPA_LINE_STRIP_ADJACENCY:
522 if (nvertexs < 4)
523 {
524 return Standard_False;
525 }
526 break;
527 case Graphic3d_TOPA_TRIANGLES_ADJACENCY:
528 case Graphic3d_TOPA_TRIANGLE_STRIP_ADJACENCY:
529 if (nvertexs < 6)
530 {
531 return Standard_False;
532 }
533 break;
534 case Graphic3d_TOPA_UNDEFINED:
535 default:
536 return Standard_False;
537 }
538
539 // total number of edges(vertices) in bounds should be the same as variable
540 // of total number of defined edges(vertices); if no edges - only vertices
541 // could be in bounds.
542 if (nbounds > 0)
543 {
544 Standard_Integer n = 0;
545 for (Standard_Integer aBoundIter = 0; aBoundIter < nbounds; ++aBoundIter)
546 {
547 n += myBounds->Bounds[aBoundIter];
548 }
549 if (nedges > 0
550 && n != nedges)
551 {
552 if (nedges <= n)
553 {
554 return Standard_False;
555 }
556 myIndices->NbElements = n;
557 }
558 else if (nedges == 0
559 && n != nvertexs)
560 {
561 if (nvertexs <= n)
562 {
563 return Standard_False;
564 }
565 myAttribs->NbElements = n;
566 }
567 }
568
569 // check that edges (indexes to an array of vertices) are in range.
570 if (nedges > 0)
571 {
572 for (Standard_Integer anEdgeIter = 0; anEdgeIter < nedges; ++anEdgeIter)
573 {
574 if (myIndices->Index (anEdgeIter) >= myAttribs->NbElements)
575 {
576 return Standard_False;
577 }
578 }
579 }
580 return Standard_True;
581 }
582