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