0024406: Visualization - crash on re-usage of the same primitive array
[occt.git] / src / Graphic3d / Graphic3d_ArrayOfPrimitives.cxx
index 809f5ea..5550e3f 100644 (file)
 // Alternatively, this file may be used under the terms of Open CASCADE
 // commercial license or contractual agreement.
 
-#define TRACE 0
-
 #include <Graphic3d_ArrayOfPrimitives.ixx>
 #include <Standard.hxx>
 #include <TCollection_AsciiString.hxx>
 #include <OSD_Environment.hxx>
+#include <NCollection_AlignedAllocator.hxx>
 
 #include <stdio.h>
 #include <stdlib.h>
 
-Graphic3d_ArrayOfPrimitives :: Graphic3d_ArrayOfPrimitives (
-                        const Graphic3d_TypeOfPrimitiveArray aType,
-                        const Standard_Integer maxVertexs,
-                        const Standard_Integer maxBounds,
-                        const Standard_Integer maxEdges,
-                        const Standard_Boolean hasVNormals,
-                        const Standard_Boolean hasVColors,
-                        const Standard_Boolean hasFColors,
-                        const Standard_Boolean hasVTexels,
-                        const Standard_Boolean hasEdgeInfos )
-: myMaxBounds(0),myMaxVertexs(0),myMaxEdges(0)
-{
-  const Standard_Integer size = sizeof(CALL_DEF_PARRAY);
-  Standard_Integer format = MVERTICE;
-  if( hasVNormals ) format |= MVNORMAL;
-  if( hasVColors ) format |= MVCOLOR;
-  if( hasVTexels ) format |= MVTEXEL;
-    
-  myPrimitiveArray = (Graphic3d_PrimitiveArray) Standard::Allocate(size); 
-  memset ( myPrimitiveArray, 0, size );
-
-  if( maxVertexs > 0){
-    myPrimitiveArray->vertices = (TEL_POINT*) Standard::Allocate(maxVertexs *sizeof(TEL_POINT));
-    memset ( myPrimitiveArray->vertices, 0, maxVertexs *sizeof(TEL_POINT));
-  }
-
-  if( hasVNormals ){
-    myPrimitiveArray->vnormals = (TEL_POINT*) Standard::Allocate(sizeof(TEL_POINT) * maxVertexs);
-    memset ( myPrimitiveArray->vnormals, 0, sizeof(TEL_POINT) * maxVertexs);
+Graphic3d_ArrayOfPrimitives::Graphic3d_ArrayOfPrimitives (const Graphic3d_TypeOfPrimitiveArray theType,
+                                                          const Standard_Integer               theMaxVertexs,
+                                                          const Standard_Integer               theMaxBounds,
+                                                          const Standard_Integer               theMaxEdges,
+                                                          const Standard_Boolean               theHasVNormals,
+                                                          const Standard_Boolean               theHasVColors,
+                                                          const Standard_Boolean               theHasFColors,
+                                                          const Standard_Boolean               theHasVTexels)
+: myType       (theType),
+  myMaxBounds  (0),
+  myMaxVertexs (0),
+  myMaxEdges   (0),
+  myVNor       (0),
+  myVTex       (0),
+  myVCol       (0)
+{
+  Handle(NCollection_AlignedAllocator) anAlloc = new NCollection_AlignedAllocator (16);
+  myAttribs = new Graphic3d_Buffer (anAlloc);
+  if (theMaxVertexs < 1)
+  {
+    return;
   }
 
-  if( hasVColors ){
-    myPrimitiveArray->vcolours = (Tint*) Standard::Allocate(maxVertexs *sizeof(Tint));
-    memset ( myPrimitiveArray->vcolours, 0, sizeof(Tint) * maxVertexs);
+  if (theMaxEdges > 0)
+  {
+    myIndices = new Graphic3d_IndexBuffer (anAlloc);
+    if (theMaxEdges < Standard_Integer(USHRT_MAX))
+    {
+      if (!myIndices->Init<unsigned short> (theMaxEdges))
+      {
+        myIndices.Nullify();
+        return;
+      }
+    }
+    else
+    {
+      if (!myIndices->Init<unsigned int> (theMaxEdges))
+      {
+        myIndices.Nullify();
+        return;
+      }
+    }
+    myIndices->NbElements = 0;
   }
 
-  if( hasVTexels ){
-    myPrimitiveArray->vtexels = (TEL_TEXTURE_COORD*) Standard::Allocate(maxVertexs *sizeof(TEL_TEXTURE_COORD));
-    memset ( myPrimitiveArray->vtexels, 0, sizeof(TEL_TEXTURE_COORD) * maxVertexs);
+  Graphic3d_Attribute anAttribs[4];
+  Standard_Integer    aNbAttribs = 0;
+  anAttribs[aNbAttribs].Id       = Graphic3d_TOA_POS;
+  anAttribs[aNbAttribs].DataType = Graphic3d_TOD_VEC3;
+  ++aNbAttribs;
+  if (theHasVNormals)
+  {
+    anAttribs[aNbAttribs].Id       = Graphic3d_TOA_NORM;
+    anAttribs[aNbAttribs].DataType = Graphic3d_TOD_VEC3;
+    ++aNbAttribs;
   }
-
-  if( hasFColors && (maxBounds > 0) ){
-    myPrimitiveArray->fcolours = (TEL_COLOUR*) Standard::Allocate(maxBounds *sizeof(TEL_COLOUR));
-    memset ( myPrimitiveArray->fcolours, 0, sizeof(TEL_COLOUR) * maxBounds);
-  } 
-
-  if( maxBounds > 0 ){
-    myPrimitiveArray->bounds = (Tint*) Standard::Allocate(maxBounds *sizeof(Tint));
-    memset ( myPrimitiveArray->bounds, 0, maxBounds *sizeof(Tint));
+  if (theHasVTexels)
+  {
+    anAttribs[aNbAttribs].Id       = Graphic3d_TOA_UV;
+    anAttribs[aNbAttribs].DataType = Graphic3d_TOD_VEC2;
+    ++aNbAttribs;
   }
-
-  if( maxEdges > 0 ){
-    myPrimitiveArray->edges = (Tint*) Standard::Allocate(maxEdges *sizeof(Tint));
-    memset ( myPrimitiveArray->edges, 0,  maxEdges *sizeof(Tint));
+  if (theHasVColors)
+  {
+    anAttribs[aNbAttribs].Id       = Graphic3d_TOA_COLOR;
+    anAttribs[aNbAttribs].DataType = Graphic3d_TOD_VEC4UB;
+    ++aNbAttribs;
   }
 
-  if( hasEdgeInfos && (maxEdges > 0) ){
-    myPrimitiveArray->edge_vis = (Tchar*)Standard::Allocate(maxEdges *sizeof(Tchar));
-    memset ( myPrimitiveArray->edge_vis, 0, maxEdges *sizeof(Tchar));
+  if (!myAttribs->Init (theMaxVertexs, anAttribs, aNbAttribs))
+  {
+    myAttribs.Nullify();
+    myIndices.Nullify();
+    return;
   }
-
-  myPrimitiveArray->keys = NULL;
-  myMaxVertexs = maxVertexs;
-  myMaxBounds = maxBounds;
-  myMaxEdges = maxEdges;
-  myPrimitiveArray->type          = (TelPrimitivesArrayType) aType;
-  myPrimitiveArray->format        = format;
-  myPrimitiveArray->num_bounds    = 0;
-  myPrimitiveArray->num_vertexs   = 0;
-  myPrimitiveArray->num_edges     = 0;
-}
-
-void Graphic3d_ArrayOfPrimitives::Destroy ()
-{
-  if( myPrimitiveArray ) {
-    if( myPrimitiveArray->vertices ){
-      Standard::Free (myPrimitiveArray->vertices);
-      myPrimitiveArray->vertices = 0;
-    }
-
-    if( myPrimitiveArray->vnormals ){
-      Standard::Free (myPrimitiveArray->vnormals);
-      myPrimitiveArray->vnormals = 0;
-    }
-
-    if( myPrimitiveArray->vcolours ){
-      Standard::Free (myPrimitiveArray->vcolours);
-      myPrimitiveArray->vcolours = 0;
-    }
-
-    if( myPrimitiveArray->vtexels ){
-      Standard::Free (myPrimitiveArray->vtexels);
-      myPrimitiveArray->vtexels = 0;
-    }
-
-    if( myPrimitiveArray->fcolours ){
-      Standard::Free (myPrimitiveArray->fcolours);
-      myPrimitiveArray->fcolours = 0;
-    } 
-
-    if( myPrimitiveArray->bounds ){
-      Standard::Free (myPrimitiveArray->bounds);
-      myPrimitiveArray->bounds = 0;
-    }
-
-    if( myPrimitiveArray->edges ){
-      Standard::Free (myPrimitiveArray->edges);
-      myPrimitiveArray->edges = 0;
+  memset (myAttribs->ChangeData (0), 0, myAttribs->Stride * myAttribs->NbElements);
+
+  if (theMaxBounds > 0)
+  {
+    myBounds = new Graphic3d_BoundBuffer (anAlloc);
+    if (!myBounds->Init (theMaxBounds, theHasFColors))
+    {
+      myAttribs.Nullify();
+      myIndices.Nullify();
+      myBounds .Nullify();
+      return;
     }
+    myBounds->NbBounds = 0;
+  }
 
-    if( myPrimitiveArray->edge_vis ){
-      Standard::Free (myPrimitiveArray->edge_vis);
-      myPrimitiveArray->edge_vis = 0;
+  for (Standard_Integer anAttribIter = 0; anAttribIter < aNbAttribs; ++anAttribIter)
+  {
+    const Graphic3d_Attribute& anAttrib = anAttribs[anAttribIter];
+    switch (anAttrib.Id)
+    {
+      case Graphic3d_TOA_POS:
+      case Graphic3d_TOA_CUSTOM:
+        break;
+      case Graphic3d_TOA_NORM:
+      {
+        myVNor = static_cast<Standard_Byte>(myAttribs->AttributeOffset (anAttribIter));
+        break;
+      }
+      case Graphic3d_TOA_UV:
+      {
+        myVTex = static_cast<Standard_Byte>(myAttribs->AttributeOffset (anAttribIter));
+        break;
+      }
+      case Graphic3d_TOA_COLOR:
+      {
+        myVCol = static_cast<Standard_Byte>(myAttribs->AttributeOffset (anAttribIter));
+        break;
+      }
     }
-
-    Standard::Free (myPrimitiveArray);
-#if TRACE > 0
-    cout << " Graphic3d_ArrayOfPrimitives::Destroy()" << endl;
-#endif
   }
-}
 
-Standard_Integer Graphic3d_ArrayOfPrimitives::AddVertex(const Standard_ShortReal X, const Standard_ShortReal Y, const Standard_ShortReal Z)
-{
-  if( !myPrimitiveArray ) return 0;
-  const Standard_Integer index = myPrimitiveArray->num_vertexs + 1;
-  SetVertice(index,X,Y,Z);
-  return index;
+  myAttribs->NbElements = 0;
+  myMaxVertexs = theMaxVertexs;
+  myMaxBounds  = theMaxBounds;
+  myMaxEdges   = theMaxEdges;
 }
 
-Standard_Integer Graphic3d_ArrayOfPrimitives::AddVertex(const gp_Pnt& aVertice, const Quantity_Color& aColor)
+void Graphic3d_ArrayOfPrimitives::Destroy()
 {
-  const Standard_Integer index = AddVertex(aVertice);
-  Standard_Real r,g,b;
-  aColor.Values(r,g,b,Quantity_TOC_RGB);
-  SetVertexColor(index,r,g,b);
-  return index;
+  myVNor = 0;
+  myVTex = 0;
+  myVCol = 0;
+  myIndices.Nullify();
+  myAttribs.Nullify();
+  myBounds .Nullify();
 }
 
-Standard_Integer Graphic3d_ArrayOfPrimitives::AddVertex(const gp_Pnt& aVertice, const Standard_Integer aColor)
+Standard_Integer Graphic3d_ArrayOfPrimitives::AddVertex (const Standard_ShortReal theX,
+                                                         const Standard_ShortReal theY,
+                                                         const Standard_ShortReal theZ)
 {
-  const Standard_Integer index = AddVertex(aVertice);
-  SetVertexColor(index,aColor);
-  return index;
+  if (myAttribs.IsNull())
+  {
+    return 0;
+  }
+
+  const Standard_Integer anIndex = myAttribs->NbElements + 1;
+  SetVertice (anIndex, theX, theY, theZ);
+  return anIndex;
 }
 
-Standard_Integer Graphic3d_ArrayOfPrimitives::AddVertex(const Standard_ShortReal X, const Standard_ShortReal Y, const Standard_ShortReal Z,
-                                                        const Standard_ShortReal NX, const Standard_ShortReal NY, const Standard_ShortReal NZ)
+Standard_Integer Graphic3d_ArrayOfPrimitives::AddVertex (const gp_Pnt&         theVertex,
+                                                         const Quantity_Color& theColor)
 {
-  if( !myPrimitiveArray ) return 0;
-  const Standard_Integer index = myPrimitiveArray->num_vertexs + 1;
-  SetVertice(index,X,Y,Z);
-  SetVertexNormal(index,NX,NY,NZ);
-  return index;
+  const Standard_Integer anIndex = AddVertex (theVertex);
+  SetVertexColor (anIndex, theColor.Red(), theColor.Green(), theColor.Blue());
+  return anIndex;
 }
 
-Standard_Integer Graphic3d_ArrayOfPrimitives::AddVertex(const gp_Pnt& aVertice,
-                                                        const gp_Dir& aNormal,
-                                                        const Quantity_Color& aColor)
+Standard_Integer Graphic3d_ArrayOfPrimitives::AddVertex (const gp_Pnt&          theVertex,
+                                                         const Standard_Integer theColor32)
 {
-  const Standard_Integer index = AddVertex(aVertice,aNormal);
-  Standard_Real r,g,b;
-  aColor.Values(r,g,b,Quantity_TOC_RGB);
-  SetVertexColor(index,r,g,b);
-  return index;
+  const Standard_Integer anIndex = AddVertex (theVertex);
+  SetVertexColor (anIndex, theColor32);
+  return anIndex;
 }
 
-Standard_Integer Graphic3d_ArrayOfPrimitives::AddVertex(const gp_Pnt& aVertice,
-                                                        const gp_Dir& aNormal,
-                                                        const Standard_Integer aColor)
+Standard_Integer Graphic3d_ArrayOfPrimitives::AddVertex (const Standard_ShortReal theX,  const Standard_ShortReal theY,  const Standard_ShortReal theZ,
+                                                         const Standard_ShortReal theNX, const Standard_ShortReal theNY, const Standard_ShortReal theNZ)
 {
-  const Standard_Integer index = AddVertex(aVertice,aNormal);
-  SetVertexColor(index,aColor);
-  return index;
+  if (myAttribs.IsNull())
+  {
+    return 0;
+  }
+
+  const Standard_Integer anIndex = myAttribs->NbElements + 1;
+  SetVertice      (anIndex, theX,  theY,  theZ);
+  SetVertexNormal (anIndex, theNX, theNY, theNZ);
+  return anIndex;
 }
 
-Standard_Integer Graphic3d_ArrayOfPrimitives::AddVertex(
-        const Standard_ShortReal X, const Standard_ShortReal Y, const Standard_ShortReal Z,
-        const Standard_ShortReal TX, const Standard_ShortReal TY)
+Standard_Integer Graphic3d_ArrayOfPrimitives::AddVertex (const gp_Pnt&         theVertex,
+                                                         const gp_Dir&         theNormal,
+                                                         const Quantity_Color& theColor)
 {
-  if( !myPrimitiveArray ) return 0;
-  const Standard_Integer index = myPrimitiveArray->num_vertexs + 1;
-  SetVertice(index,X,Y,Z);
-  SetVertexTexel(index,TX,TY);
-  return index;
+  const Standard_Integer anIndex = AddVertex (theVertex, theNormal);
+  SetVertexColor (anIndex, theColor.Red(), theColor.Green(), theColor.Blue());
+  return anIndex;
 }
 
-Standard_Integer Graphic3d_ArrayOfPrimitives::AddVertex(
-        const Standard_ShortReal X, const Standard_ShortReal Y, const Standard_ShortReal Z,
-        const Standard_ShortReal NX, const Standard_ShortReal NY, const Standard_ShortReal NZ,
-        const Standard_ShortReal TX, const Standard_ShortReal TY)
+Standard_Integer Graphic3d_ArrayOfPrimitives::AddVertex (const gp_Pnt&          theVertex,
+                                                         const gp_Dir&          theNormal,
+                                                         const Standard_Integer theColor32)
 {
-  if( !myPrimitiveArray ) return 0;
-  const Standard_Integer index = myPrimitiveArray->num_vertexs + 1;
-  SetVertice(index,X,Y,Z);
-  SetVertexNormal(index,NX,NY,NZ);
-  SetVertexTexel(index,TX,TY);
-  return index;
+  const Standard_Integer anIndex = AddVertex (theVertex, theNormal);
+  SetVertexColor (anIndex, theColor32);
+  return anIndex;
 }
 
-Standard_Integer Graphic3d_ArrayOfPrimitives::AddBound( const Standard_Integer edgeNumber)
+Standard_Integer Graphic3d_ArrayOfPrimitives::AddVertex (const Standard_ShortReal theX,  const Standard_ShortReal theY, const Standard_ShortReal theZ,
+                                                         const Standard_ShortReal theTX, const Standard_ShortReal theTY)
 {
-  Standard_Integer index = 0;
-  if( myPrimitiveArray && myPrimitiveArray->bounds ) {
-    index = myPrimitiveArray->num_bounds;
-    if( index < myMaxBounds ) {
-      myPrimitiveArray->bounds[index] = edgeNumber;
-      myPrimitiveArray->num_bounds = ++index;
-    } else {
-      Standard_OutOfRange::Raise(" TOO many BOUNDS");
-    }
+  if (myAttribs.IsNull())
+  {
+    return 0;
   }
 
-  return index;
+  const Standard_Integer anIndex = myAttribs->NbElements + 1;
+  SetVertice     (anIndex, theX, theY, theZ);
+  SetVertexTexel (anIndex, theTX, theTY);
+  return anIndex;
 }
 
-Standard_Integer Graphic3d_ArrayOfPrimitives::AddBound( const Standard_Integer edgeNumber,
-                                                        const Quantity_Color& aFColor)
+Standard_Integer Graphic3d_ArrayOfPrimitives::AddVertex (const Standard_ShortReal theX,  const Standard_ShortReal theY,  const Standard_ShortReal theZ,
+                                                         const Standard_ShortReal theNX, const Standard_ShortReal theNY, const Standard_ShortReal theNZ,
+                                                         const Standard_ShortReal theTX, const Standard_ShortReal theTY)
 {
-  Standard_Real r,g,b;
-  aFColor.Values(r,g,b,Quantity_TOC_RGB);
-  return AddBound(edgeNumber,r,g,b);
-}
+  if (myAttribs.IsNull())
+  {
+    return 0;
+  }
 
-Standard_Integer Graphic3d_ArrayOfPrimitives::AddBound( const Standard_Integer edgeNumber,
-                                                        const Standard_Real R, 
-                                                        const Standard_Real G,
-                                                        const Standard_Real B)
-{
-  if( !myPrimitiveArray ) return 0;
-  Standard_Integer index = myPrimitiveArray->num_bounds;
-  if( index >= myMaxBounds ) {
-    Standard_OutOfRange::Raise(" TOO many BOUND");
-  }
-  myPrimitiveArray->bounds[index] = edgeNumber;
-  myPrimitiveArray->num_bounds = ++index;
-  SetBoundColor(index,R,G,B);
-  return index;
+  const Standard_Integer anIndex = myAttribs->NbElements + 1;
+  SetVertice      (anIndex, theX,  theY,  theZ);
+  SetVertexNormal (anIndex, theNX, theNY, theNZ);
+  SetVertexTexel  (anIndex, theTX, theTY);
+  return anIndex;
 }
 
-Standard_Integer Graphic3d_ArrayOfPrimitives::AddEdge(const Standard_Integer vertexIndex,
-                                                      const Standard_Boolean isVisible)
+Standard_Integer Graphic3d_ArrayOfPrimitives::AddBound (const Standard_Integer theEdgeNumber)
 {
-  if( !myPrimitiveArray ) return 0;
-
-  Standard_Integer index = myPrimitiveArray->num_edges;
-  if( index >= myMaxEdges ) {
-    Standard_OutOfRange::Raise(" TOO many EDGE");
+  if (myBounds.IsNull())
+  {
+    return 0;
   }
-  Standard_Integer vindex = vertexIndex-1;
-  if( vertexIndex > 0 && vindex < myMaxVertexs ) {
-    myPrimitiveArray->edges[index] = vindex;
-    if( myPrimitiveArray->edge_vis ) {
-      myPrimitiveArray->edge_vis[index] = (Tchar) (isVisible ? 1 : 0);
-    }
-    myPrimitiveArray->num_edges = ++index;
-  } else {
-    Standard_OutOfRange::Raise(" BAD EDGE vertex index");
+  Standard_Integer anIndex = myBounds->NbBounds;
+  if (anIndex >= myMaxBounds)
+  {
+    Standard_OutOfRange::Raise ("TOO many BOUNDS");
   }
 
-  return index;
+  myBounds->Bounds[anIndex] = theEdgeNumber;
+  myBounds->NbBounds        = ++anIndex;
+  return anIndex;
 }
 
-Standard_Boolean Graphic3d_ArrayOfPrimitives::Orientate(const gp_Dir& aNormal)
+Standard_Integer Graphic3d_ArrayOfPrimitives::AddBound (const Standard_Integer theEdgeNumber,
+                                                        const Quantity_Color&  theColor)
 {
-  return Orientate(1,Max(VertexNumber(),EdgeNumber()),aNormal);
+  return AddBound (theEdgeNumber, theColor.Red(), theColor.Green(), theColor.Blue());
 }
 
-Standard_Boolean Graphic3d_ArrayOfPrimitives::Orientate(const Standard_Integer aVertexIndex,
-                                                        const Standard_Integer aVertexNumber,
-                                                        const gp_Dir& aNormal)
+Standard_Integer Graphic3d_ArrayOfPrimitives::AddBound (const Standard_Integer theEdgeNumber,
+                                                        const Standard_Real    theR,
+                                                        const Standard_Real    theG,
+                                                        const Standard_Real    theB)
 {
-  Standard_Boolean somethingHasChange = Standard_False;
-  if( myPrimitiveArray && (myPrimitiveArray->num_vertexs > 2) ) {
-    Standard_Integer i,j,k=aVertexNumber,n=aVertexIndex-1;
-    Standard_ShortReal x,y,z;
-    if( myPrimitiveArray->edges ) {
-      if( n >= 0 && (n+k) <= myPrimitiveArray->num_edges ) {
-        Standard_Integer i1 = myPrimitiveArray->edges[n];
-        Standard_Integer i2 = myPrimitiveArray->edges[n+1];
-        Standard_Integer i3 = myPrimitiveArray->edges[n+2];
-        gp_Pnt p1(myPrimitiveArray->vertices[i1].xyz[0],
-                  myPrimitiveArray->vertices[i1].xyz[1],
-                  myPrimitiveArray->vertices[i1].xyz[2]);
-        gp_Pnt p2(myPrimitiveArray->vertices[i2].xyz[0],
-                  myPrimitiveArray->vertices[i2].xyz[1],
-                  myPrimitiveArray->vertices[i2].xyz[2]);
-        gp_Pnt p3(myPrimitiveArray->vertices[i3].xyz[0],
-                  myPrimitiveArray->vertices[i3].xyz[1],
-                  myPrimitiveArray->vertices[i3].xyz[2]);
-        gp_Vec v21(p1,p2),v31(p1,p3),fn = v21.Crossed(v31);
-        if( aNormal.IsOpposite(fn, M_PI / 4.) ) {
-          Standard_Integer e; char v;
-          for( i=0,j=k-1 ; i<k/2 ; i++,j-- ) {
-            e = myPrimitiveArray->edges[n+i];
-            myPrimitiveArray->edges[n+i] = myPrimitiveArray->edges[n+j];
-            myPrimitiveArray->edges[n+j] = e;
-            if( myPrimitiveArray->edge_vis ) {
-              v = myPrimitiveArray->edge_vis[n+i];
-              myPrimitiveArray->edge_vis[n+i] = myPrimitiveArray->edge_vis[n+j];
-              myPrimitiveArray->edge_vis[n+j] = v;
-            }
-            if( myPrimitiveArray->vnormals ) {
-              e = myPrimitiveArray->edges[n+i];
-              x = myPrimitiveArray->vnormals[e].xyz[0];
-              y = myPrimitiveArray->vnormals[e].xyz[1];
-              z = myPrimitiveArray->vnormals[e].xyz[2];
-              gp_Vec vn(x,y,z);
-              if( aNormal.IsOpposite(vn, M_PI / 4.) ) {
-                myPrimitiveArray->vnormals[e].xyz[0] = -x;
-                myPrimitiveArray->vnormals[e].xyz[1] = -y;
-                myPrimitiveArray->vnormals[e].xyz[2] = -z;
-              }
-            }
-          }
-          somethingHasChange = Standard_True;
-        }
-      } else {
-        Standard_OutOfRange::Raise(" BAD EDGE index or number");
-      }
-      return somethingHasChange;
-    } 
-
-    if( n >= 0 && (n+k) <= myPrimitiveArray->num_vertexs ) {
-      gp_Pnt p1(myPrimitiveArray->vertices[n].xyz[0],
-                  myPrimitiveArray->vertices[n].xyz[1],
-                  myPrimitiveArray->vertices[n].xyz[2]);
-      gp_Pnt p2(myPrimitiveArray->vertices[n+1].xyz[0],
-                  myPrimitiveArray->vertices[n+1].xyz[1],
-                  myPrimitiveArray->vertices[n+1].xyz[2]);
-      gp_Pnt p3(myPrimitiveArray->vertices[n+2].xyz[0],
-                  myPrimitiveArray->vertices[n+2].xyz[1],
-                  myPrimitiveArray->vertices[n+2].xyz[2]);
-      gp_Vec v21(p1,p2),v31(p1,p3),fn = v21.Crossed(v31);
-      if( aNormal.IsOpposite(fn, M_PI / 4.) ) {
-        for( i=0,j=k-1 ; i<k/2 ; i++,j-- ) {
-          x = myPrimitiveArray->vertices[n+i].xyz[0];
-          y = myPrimitiveArray->vertices[n+i].xyz[1];
-          z = myPrimitiveArray->vertices[n+i].xyz[2];
-          myPrimitiveArray->vertices[n+i].xyz[0] = myPrimitiveArray->vertices[n+j].xyz[0];
-          myPrimitiveArray->vertices[n+i].xyz[1] = myPrimitiveArray->vertices[n+j].xyz[1];
-          myPrimitiveArray->vertices[n+i].xyz[2] = myPrimitiveArray->vertices[n+j].xyz[2];
-          myPrimitiveArray->vertices[n+j].xyz[0] = x;
-          myPrimitiveArray->vertices[n+j].xyz[1] = y;
-          myPrimitiveArray->vertices[n+j].xyz[2] = z;
-          if( myPrimitiveArray->vnormals ) {
-            x = myPrimitiveArray->vnormals[n+i].xyz[0];
-            y = myPrimitiveArray->vnormals[n+i].xyz[1];
-            z = myPrimitiveArray->vnormals[n+i].xyz[2];
-            myPrimitiveArray->vnormals[n+i].xyz[0] = myPrimitiveArray->vnormals[n+j].xyz[0];
-            myPrimitiveArray->vnormals[n+i].xyz[1] = myPrimitiveArray->vnormals[n+j].xyz[1];
-            myPrimitiveArray->vnormals[n+i].xyz[2] = myPrimitiveArray->vnormals[n+j].xyz[2];
-            myPrimitiveArray->vnormals[n+j].xyz[0] = x;
-            myPrimitiveArray->vnormals[n+j].xyz[1] = y;
-            myPrimitiveArray->vnormals[n+j].xyz[2] = z;
-
-            x = myPrimitiveArray->vnormals[n+i].xyz[0];
-            y = myPrimitiveArray->vnormals[n+i].xyz[1];
-            z = myPrimitiveArray->vnormals[n+i].xyz[2];
-            gp_Vec vn(x,y,z);
-            if( aNormal.IsOpposite(vn, M_PI / 4.) ) {
-              myPrimitiveArray->vnormals[n+i].xyz[0] = -x;
-              myPrimitiveArray->vnormals[n+i].xyz[1] = -y;
-              myPrimitiveArray->vnormals[n+i].xyz[2] = -z;
-            }
-          }
-          if( myPrimitiveArray->vcolours ) {
-            x = (Standard_ShortReal)myPrimitiveArray->vcolours[n+i];
-            myPrimitiveArray->vcolours[n+i] = myPrimitiveArray->vcolours[n+j];
-            myPrimitiveArray->vcolours[n+j] = (Tint)x;
-          }
-          if( myPrimitiveArray->vtexels ) {
-            x = myPrimitiveArray->vtexels[n+i].xy[0];
-            y = myPrimitiveArray->vtexels[n+i].xy[1];
-            myPrimitiveArray->vtexels[n+i].xy[0] = myPrimitiveArray->vtexels[n+j].xy[0];
-            myPrimitiveArray->vtexels[n+i].xy[1] = myPrimitiveArray->vtexels[n+j].xy[1];
-            myPrimitiveArray->vtexels[n+j].xy[0] = x;
-            myPrimitiveArray->vtexels[n+j].xy[1] = y;
-          }
-        }
-        somethingHasChange = Standard_True;
-      }
-    }
+  if (myBounds.IsNull())
+  {
+    return 0;
+  }
+  Standard_Integer anIndex = myBounds->NbBounds;
+  if (anIndex >= myMaxBounds)
+  {
+    Standard_OutOfRange::Raise ("TOO many BOUND");
   }
-  return somethingHasChange;
+
+  myBounds->Bounds[anIndex] = theEdgeNumber;
+  myBounds->NbBounds        = ++anIndex;
+  SetBoundColor (anIndex, theR, theG, theB);
+  return anIndex;
 }
 
-Standard_Boolean Graphic3d_ArrayOfPrimitives::Orientate(const Standard_Integer aBoundIndex,
-                                                        const gp_Dir& aNormal)
+Standard_Integer Graphic3d_ArrayOfPrimitives::AddEdge (const Standard_Integer theVertexIndex)
 {
-  Standard_Boolean somethingHasChange = Standard_False;
-  if( myPrimitiveArray && myPrimitiveArray->vertices ) {
-    if( myPrimitiveArray->bounds && 
-        (aBoundIndex > 0) && (aBoundIndex <= myPrimitiveArray->num_bounds) ) {
-      Standard_Integer k,n;
-      for( k=n=1 ; k<aBoundIndex ; k++ )
-        n += myPrimitiveArray->bounds[k];
-      k = myPrimitiveArray->bounds[aBoundIndex-1];
-      somethingHasChange = Orientate(n,k,aNormal);
-    } else if( myPrimitiveArray->bounds ) {
-      Standard_OutOfRange::Raise(" BAD BOUND index");
-    } else if( (aBoundIndex > 0) && (aBoundIndex <= ItemNumber()) ) {
-      switch( myPrimitiveArray->type ) {
-        case TelPointsArrayType:
-        case TelPolylinesArrayType:
-        case TelSegmentsArrayType:
-          break;
-        case TelPolygonsArrayType:
-        case TelTriangleStripsArrayType:
-        case TelTriangleFansArrayType:
-        case TelQuadrangleStripsArrayType:
-          somethingHasChange = Orientate(1,VertexNumber(),aNormal);
-          break;
-        case TelTrianglesArrayType:
-          somethingHasChange = Orientate(aBoundIndex*3-2,3,aNormal);
-          break;
-        case TelQuadranglesArrayType:
-          somethingHasChange = Orientate(aBoundIndex*4-3,4,aNormal);
-          break;
-        default:
-          break;
-      }
-    } else {
-      Standard_OutOfRange::Raise(" BAD ITEM index");
-    }
+  if (myIndices.IsNull())
+  {
+    return 0;
+  }
+
+  Standard_Integer anIndex = myIndices->NbElements;
+  if (anIndex >= myMaxEdges)
+  {
+    Standard_OutOfRange::Raise ("TOO many EDGE");
+  }
+
+  Standard_Integer aVertIndex = theVertexIndex - 1;
+  if (theVertexIndex <= 0
+   || aVertIndex >= myMaxVertexs)
+  {
+    Standard_OutOfRange::Raise ("BAD EDGE vertex index");
   }
-  return somethingHasChange;
+
+  myIndices->SetIndex (anIndex, aVertIndex);
+  myIndices->NbElements = ++anIndex;
+  return anIndex;
 }
 
-void Graphic3d_ArrayOfPrimitives::SetVertice( const Standard_Integer anIndex,
-                                              const gp_Pnt& aVertice)
+void Graphic3d_ArrayOfPrimitives::SetVertice (const Standard_Integer theIndex,
+                                              const gp_Pnt&          theVertex)
 {
-  Standard_Real x,y,z;
-  aVertice.Coord(x,y,z);
-  SetVertice(anIndex,Standard_ShortReal(x),Standard_ShortReal(y),Standard_ShortReal(z));
+  SetVertice (theIndex,
+              Standard_ShortReal (theVertex.X()),
+              Standard_ShortReal (theVertex.Y()),
+              Standard_ShortReal (theVertex.Z()));
 }
 
-void Graphic3d_ArrayOfPrimitives::SetVertexColor( const Standard_Integer anIndex,
-                                                  const Quantity_Color& aColor)
+void Graphic3d_ArrayOfPrimitives::SetVertexColor (const Standard_Integer theIndex,
+                                                  const Quantity_Color&  theColor)
 {
-  Standard_Real r,g,b;
-  aColor.Values(r,g,b,Quantity_TOC_RGB);
-  SetVertexColor(anIndex,r,g,b);
+  SetVertexColor (theIndex, theColor.Red(), theColor.Green(), theColor.Blue());
 }
 
-void Graphic3d_ArrayOfPrimitives::SetVertexColor( const Standard_Integer anIndex,
-                                                  const Standard_Integer aColor)
+void Graphic3d_ArrayOfPrimitives::SetVertexColor (const Standard_Integer theIndex,
+                                                  const Standard_Integer theColor)
 {
-  if( !myPrimitiveArray ) return;
-  if( anIndex < 1 || anIndex > myMaxVertexs ) {
-    Standard_OutOfRange::Raise(" BAD VERTEX index");
-  }
-  Standard_Integer index = anIndex - 1;
-  if( myPrimitiveArray->vcolours ) {
-#if defined (sparc) || defined (__sparc__) || defined (__sparc)
-    /* 
-      Well known processor(x86) architectures that use the little-endian format. 
-      Processors use big-endian format is SPARC. In this case use platform with 
-      SPARC architecture(SUNOS). Byte order could have little-endian format.
-    */
-    const char* p_ch = (const char*)&aColor;
-    myPrimitiveArray->vcolours[index] += p_ch[0];
-    myPrimitiveArray->vcolours[index] += p_ch[1] << 8 ;
-    myPrimitiveArray->vcolours[index] += p_ch[2] << 16;
-    myPrimitiveArray->vcolours[index] += p_ch[3] << 24;
-#else
-    myPrimitiveArray->vcolours[index] = aColor;
-#endif
+  if (myAttribs.IsNull())
+  {
+    return;
+  }
 
+  if (theIndex < 1
+   || theIndex > myMaxVertexs)
+  {
+    Standard_OutOfRange::Raise ("BAD VERTEX index");
+  }
+
+  if (myVCol != 0)
+  {
+    *reinterpret_cast<Standard_Integer* >(myAttribs->changeValue (theIndex - 1) + size_t(myVCol)) = theColor;
   }
 }
 
-void Graphic3d_ArrayOfPrimitives::SetVertexNormal(const Standard_Integer anIndex,
-                                                  const gp_Dir& aNormal)
+void Graphic3d_ArrayOfPrimitives::SetVertexNormal (const Standard_Integer theIndex,
+                                                   const gp_Dir&          theNormal)
 {
-  Standard_Real x,y,z;
-  aNormal.Coord(x,y,z);
-  SetVertexNormal(anIndex,x,y,z);
+  SetVertexNormal (theIndex, theNormal.X(), theNormal.Y(), theNormal.Z());
 }
 
-void Graphic3d_ArrayOfPrimitives::SetVertexTexel( const Standard_Integer anIndex,
-                                                  const gp_Pnt2d& aTexel)
+void Graphic3d_ArrayOfPrimitives::SetVertexTexel (const Standard_Integer theIndex,
+                                                  const gp_Pnt2d&        theTexel)
 {
-  Standard_Real x,y;
-  aTexel.Coord(x,y);
-  SetVertexTexel(anIndex,x,y);
+  SetVertexTexel (theIndex, theTexel.X(), theTexel.Y());
 }
 
-void Graphic3d_ArrayOfPrimitives::SetBoundColor(const Standard_Integer anIndex,
-                                                const Quantity_Color& aColor)
+void Graphic3d_ArrayOfPrimitives::SetBoundColor (const Standard_Integer theIndex,
+                                                 const Quantity_Color&  theColor)
 {
-  Standard_Real r,g,b;
-  aColor.Values(r,g,b,Quantity_TOC_RGB);
-  SetBoundColor(anIndex,r,g,b);
+  SetBoundColor (theIndex, theColor.Red(), theColor.Green(), theColor.Blue());
 }
 
 Standard_CString Graphic3d_ArrayOfPrimitives::StringType() const
 {
-  TCollection_AsciiString name("UndefinedArray");
-  switch( myPrimitiveArray->type ) {
-    case TelPointsArrayType:
-      name = "ArrayOfPoints";
-      break;
-    case TelPolylinesArrayType:
-      name = "ArrayOfPolylines";
-      break;
-    case TelSegmentsArrayType:
-      name = "ArrayOfSegments";
-      break;
-    case TelPolygonsArrayType:
-      name = "ArrayOfPolygons";
-      break;
-    case TelTrianglesArrayType:
-      name = "ArrayOfTriangles";
-      break;
-    case TelQuadranglesArrayType:
-      name = "ArrayOfQuadrangles";
-      break;
-    case TelTriangleStripsArrayType:
-      name = "ArrayOfTriangleStrips";
-      break;
-    case TelQuadrangleStripsArrayType:
-      name = "ArrayOfQuadrangleStrips";
-      break;
-    case TelTriangleFansArrayType:
-      name = "ArrayOfTriangleFans";
-      break;
-    default:
-      break;
+  switch (myType)
+  {
+    case Graphic3d_TOPA_POINTS:           return "ArrayOfPoints";
+    case Graphic3d_TOPA_POLYLINES:        return "ArrayOfPolylines";
+    case Graphic3d_TOPA_SEGMENTS:         return "ArrayOfSegments";
+    case Graphic3d_TOPA_POLYGONS:         return "ArrayOfPolygons";
+    case Graphic3d_TOPA_TRIANGLES:        return "ArrayOfTriangles";
+    case Graphic3d_TOPA_QUADRANGLES:      return "ArrayOfQuadrangles";
+    case Graphic3d_TOPA_TRIANGLESTRIPS:   return "ArrayOfTriangleStrips";
+    case Graphic3d_TOPA_QUADRANGLESTRIPS: return "ArrayOfQuadrangleStrips";
+    case Graphic3d_TOPA_TRIANGLEFANS:     return "ArrayOfTriangleFans";
+    case Graphic3d_TOPA_UNDEFINED:        return "UndefinedArray";
   }
-
-  return name.ToCString();
+  return "UndefinedArray";
 }
 
-gp_Pnt Graphic3d_ArrayOfPrimitives::Vertice(const Standard_Integer aRank) const
+gp_Pnt Graphic3d_ArrayOfPrimitives::Vertice (const Standard_Integer theRank) const
 {
-  Standard_Real x,y,z;
-  Vertice(aRank,x,y,z);
-  return gp_Pnt(x,y,z);
+  Standard_Real anXYZ[3];
+  Vertice (theRank, anXYZ[0], anXYZ[1], anXYZ[2]);
+  return gp_Pnt (anXYZ[0], anXYZ[1], anXYZ[2]);
 }
 
-Quantity_Color Graphic3d_ArrayOfPrimitives::VertexColor(const Standard_Integer aRank) const
+Quantity_Color Graphic3d_ArrayOfPrimitives::VertexColor (const Standard_Integer theRank) const
 {
-  Standard_Real r,g,b;
-  VertexColor(aRank,r,g,b);
-  return Quantity_Color(r,g,b,Quantity_TOC_RGB);
+  Standard_Real anRGB[3];
+  VertexColor (theRank, anRGB[0], anRGB[1], anRGB[2]);
+  return Quantity_Color (anRGB[0], anRGB[1], anRGB[2], Quantity_TOC_RGB);
 }
 
-gp_Dir Graphic3d_ArrayOfPrimitives::VertexNormal(const Standard_Integer aRank) const
+gp_Dir Graphic3d_ArrayOfPrimitives::VertexNormal (const Standard_Integer theRank) const
 {
-  Standard_Real x,y,z;
-  VertexNormal(aRank,x,y,z);
-  return gp_Dir(x,y,z);
+  Standard_Real anXYZ[3];
+  VertexNormal (theRank, anXYZ[0], anXYZ[1], anXYZ[2]);
+  return gp_Dir (anXYZ[0], anXYZ[1], anXYZ[2]);
 }
 
-gp_Pnt2d Graphic3d_ArrayOfPrimitives::VertexTexel(const Standard_Integer aRank) const
+gp_Pnt2d Graphic3d_ArrayOfPrimitives::VertexTexel (const Standard_Integer theRank) const
 {
-  Standard_Real x,y;
-  VertexTexel(aRank,x,y);
-  return gp_Pnt2d(x,y);
+  Standard_Real anXY[2];
+  VertexTexel (theRank, anXY[0], anXY[1]);
+  return gp_Pnt2d (anXY[0], anXY[1]);
 }
 
-Quantity_Color Graphic3d_ArrayOfPrimitives::BoundColor(const Standard_Integer aRank) const
+Quantity_Color Graphic3d_ArrayOfPrimitives::BoundColor (const Standard_Integer theRank) const
 {
-  Standard_Real r = 0.0, g = 0.0, b = 0.0;
-  BoundColor(aRank,r,g,b);
-  return Quantity_Color(r,g,b,Quantity_TOC_RGB);
+  Standard_Real anRGB[3] = {0.0, 0.0, 0.0};
+  BoundColor (theRank, anRGB[0], anRGB[1], anRGB[2]);
+  return Quantity_Color (anRGB[0], anRGB[1], anRGB[2], Quantity_TOC_RGB);
 }
 
 Standard_Integer Graphic3d_ArrayOfPrimitives::ItemNumber() const
 {
-  Standard_Integer number=-1;
-  if( myPrimitiveArray ) switch( myPrimitiveArray->type ) {
-    case TelPointsArrayType:
-      number = myPrimitiveArray->num_vertexs;
-      break;
-    case TelPolylinesArrayType:
-    case TelPolygonsArrayType:
-      if( myPrimitiveArray->num_bounds > 0 ) 
-        number = myPrimitiveArray->num_bounds;
-      else number = 1;
-      break;
-    case TelSegmentsArrayType:
-      if( myPrimitiveArray->num_edges > 0 ) 
-        number = myPrimitiveArray->num_edges/2;
-      else number = myPrimitiveArray->num_vertexs/2;
-      break;
-    case TelTrianglesArrayType:
-      if( myPrimitiveArray->num_edges > 0 ) 
-        number = myPrimitiveArray->num_edges/3;
-      else number = myPrimitiveArray->num_vertexs/3;
-      break;
-    case TelQuadranglesArrayType:
-      if( myPrimitiveArray->num_edges > 0 ) 
-        number = myPrimitiveArray->num_edges/4;
-      else number = myPrimitiveArray->num_vertexs/4;
-      break;
-    case TelTriangleStripsArrayType:
-      if( myPrimitiveArray->num_bounds > 0 ) 
-        number = myPrimitiveArray->num_vertexs-2*myPrimitiveArray->num_bounds;
-      else number = myPrimitiveArray->num_vertexs-2;
-      break;
-    case TelQuadrangleStripsArrayType:
-      if( myPrimitiveArray->num_bounds > 0 ) 
-        number = myPrimitiveArray->num_vertexs/2-myPrimitiveArray->num_bounds;
-      else number = myPrimitiveArray->num_vertexs/2-1;
-      break;
-    case TelTriangleFansArrayType:
-      if( myPrimitiveArray->num_bounds > 0 ) 
-        number = myPrimitiveArray->num_vertexs-2*myPrimitiveArray->num_bounds;
-      else number = myPrimitiveArray->num_vertexs-2;
-      break;
-    default:
-      break;
+  if (myAttribs.IsNull())
+  {
+    return -1;
   }
 
-  return number;
+  switch (myType)
+  {
+    case Graphic3d_TOPA_POINTS:           return myAttribs->NbElements;
+    case Graphic3d_TOPA_POLYLINES:
+    case Graphic3d_TOPA_POLYGONS:         return !myBounds.IsNull() ? myBounds->NbBounds : 1;
+    case Graphic3d_TOPA_SEGMENTS:         return myIndices.IsNull() || myIndices->NbElements < 1
+                                               ? myAttribs->NbElements / 2
+                                               : myIndices->NbElements / 2;
+    case Graphic3d_TOPA_TRIANGLES:        return myIndices.IsNull() || myIndices->NbElements < 1
+                                               ? myAttribs->NbElements / 3
+                                               : myIndices->NbElements / 3;
+    case Graphic3d_TOPA_QUADRANGLES:      return myIndices.IsNull() || myIndices->NbElements < 1
+                                               ? myAttribs->NbElements / 4
+                                               : myIndices->NbElements / 4;
+    case Graphic3d_TOPA_TRIANGLESTRIPS:   return !myBounds.IsNull()
+                                               ? myAttribs->NbElements - 2 * myBounds->NbBounds
+                                               : myAttribs->NbElements - 2;
+    case Graphic3d_TOPA_QUADRANGLESTRIPS: return !myBounds.IsNull()
+                                               ? myAttribs->NbElements / 2 - myBounds->NbBounds
+                                               : myAttribs->NbElements / 2 - 1;
+    case Graphic3d_TOPA_TRIANGLEFANS:     return !myBounds.IsNull()
+                                               ? myAttribs->NbElements - 2 * myBounds->NbBounds
+                                               : myAttribs->NbElements - 2;
+    case Graphic3d_TOPA_UNDEFINED:        return -1;
+  }
+  return -1;
 }
 
-void Graphic3d_ArrayOfPrimitives::ComputeVNormals(const Standard_Integer from,
-                                                  const Standard_Integer to)
+void Graphic3d_ArrayOfPrimitives::ComputeVNormals (const Standard_Integer theFrom,
+                                                   const Standard_Integer theTo)
 {
-  Standard_Integer next = from+1;
-  Standard_Integer last = to+1;
-  gp_Pnt p1,p2,p3;
-
-  if( myMaxEdges > 0 ) {
-    p1 = Vertice(Edge(next++));
-    p2 = Vertice(Edge(next++));
-  } else {
-    p1 = Vertice(next++);
-    p2 = Vertice(next++);
+  Standard_Integer aNext = theFrom + 1;
+  Standard_Integer aLast = theTo   + 1;
+  gp_Pnt aTri[3];
+  if (myMaxEdges > 0)
+  {
+    aTri[0] = Vertice (Edge (aNext++));
+    aTri[1] = Vertice (Edge (aNext++));
+  }
+  else
+  {
+    aTri[0] = Vertice (aNext++);
+    aTri[1] = Vertice (aNext++);
   }
 
   gp_Vec vn;
-  
-  while ( next <= last ) {
-    if( myMaxEdges > 0 ) {
-      p3 = Vertice(Edge(next));
-    } else {
-      p3 = Vertice(next);
+  while (aNext <= aLast)
+  {
+    if (myMaxEdges > 0)
+    {
+      aTri[2] = Vertice (Edge (aNext));
     }
-    gp_Vec v21(p2,p1);
-    gp_Vec v31(p3,p1);
+    else
+    {
+      aTri[2] = Vertice (aNext);
+    }
+    gp_Vec v21 (aTri[1], aTri[0]);
+    gp_Vec v31 (aTri[2], aTri[0]);
     vn = v21 ^ v31;
-    if( vn.SquareMagnitude() > 0. ) break;
-    next++;
+    if (vn.SquareMagnitude() > 0.0)
+    {
+      break;
+    }
+    aNext++;
   }
 
-  if( next > last ) {
-#if TRACE > 0
-    cout << " An item has a NULL computed facet normal" << endl;
-#endif
+  if (aNext > aLast)
+  {
     return;
   }
 
   vn.Normalize();
-  if( myMaxEdges > 0 ) {
-    for( int i=from+1 ; i<=to+1 ; i++ ) {
-      SetVertexNormal(Edge(i),vn);
+  if (myMaxEdges > 0)
+  {
+    for (int i = theFrom + 1; i <= theTo + 1; i++)
+    {
+      SetVertexNormal (Edge (i), vn);
     }
-  } else {
-    for( int i=from+1 ; i<=to+1 ; i++ ) {
-      SetVertexNormal(i,vn);
+  }
+  else
+  {
+    for (int i = theFrom + 1; i <= theTo + 1; i++)
+    {
+      SetVertexNormal (i, vn);
     }
   }
 }
 
 Standard_Boolean Graphic3d_ArrayOfPrimitives::IsValid()
 {
-  if( !myPrimitiveArray ) return Standard_False;
-
-  Standard_Integer nvertexs = myPrimitiveArray->num_vertexs;
-  Standard_Integer nbounds = myPrimitiveArray->num_bounds;
-  Standard_Integer nedges = myPrimitiveArray->num_edges;
-  Standard_Integer i,n;
-
-#if TRACE > 0
-  Standard_CString name = StringType();
-  cout << " !!! An " << name << " has " << ItemNumber() << " items" << endl;
-#endif
-
-  switch( myPrimitiveArray->type ) {
-    case TelPointsArrayType:
-      if( nvertexs < 1 ) {
-#if TRACE > 0
-        cout << " *** An " << name << " is unavailable with a too lower number of vertex " << nvertexs << endl;
-#endif
+  if (myAttribs.IsNull())
+  {
+    return Standard_False;
+  }
+
+  Standard_Integer nvertexs = myAttribs->NbElements;
+  Standard_Integer nbounds  = myBounds.IsNull()  ? 0 : myBounds->NbBounds;
+  Standard_Integer nedges   = myIndices.IsNull() ? 0 : myIndices->NbElements;
+  switch (myType)
+  {
+    case Graphic3d_TOPA_POINTS:
+      if (nvertexs < 1)
+      {
         return Standard_False;
       }
       break;
-    case TelPolylinesArrayType:
-      if( nedges > 0 && nedges < 2 ) {
-#if TRACE > 0
-        cout << " *** An " << name << " is unavailable with a too lower number of edges " << nedges << endl;
-#endif
+    case Graphic3d_TOPA_POLYLINES:
+      if (nedges > 0
+       && nedges < 2)
+      {
         return Standard_False;
       }
-      if( nvertexs < 2 ) {
-#if TRACE > 0
-        cout << " *** An " << name << " is unavailable with a too lower number of vertex " << nvertexs << endl;
-#endif
+      if (nvertexs < 2)
+      {
         return Standard_False;
       }
       break;
-    case TelSegmentsArrayType:
-      if( nvertexs < 2 ) {
-#if TRACE > 0
-        cout << " *** An " << name << " is unavailable with a too lower number of vertex " << nvertexs << endl;
-#endif
+    case Graphic3d_TOPA_SEGMENTS:
+      if (nvertexs < 2)
+      {
         return Standard_False;
       }
       break;
-    case TelPolygonsArrayType:
-      if( nedges > 0 && nedges < 3 ) {
-#if TRACE > 0
-        cout << " *** An " << name << " is unavailable with a too lower number of edges " << nedges << endl;
-#endif
+    case Graphic3d_TOPA_POLYGONS:
+      if (nedges > 0
+       && nedges < 3)
+      {
         return Standard_False;
       }
-      if( nvertexs < 3 ) {
-#if TRACE > 0
-        cout << " *** An " << name << " is unavailable with a too lower number of vertex " << nvertexs << endl;
-#endif
+      if (nvertexs < 3)
+      {
         return Standard_False;
       }
       break;
-    case TelTrianglesArrayType:
-      if( nedges > 0 ) {
-        if( nedges < 3 || nedges % 3 != 0 ) {
-#if TRACE > 0
-          cout << " *** An " << name << " is unavailable with a too lower number of edges " << nedges << endl;
-#endif
-          if( nedges > 3 ) myPrimitiveArray->num_edges = 3 * (nedges / 3);
-          else return Standard_False;
+    case Graphic3d_TOPA_TRIANGLES:
+      if (nedges > 0)
+      {
+        if (nedges < 3
+         || nedges % 3 != 0)
+        {
+          if (nedges <= 3)
+          {
+            return Standard_False;
+          }
+          myIndices->NbElements = 3 * (nedges / 3);
+        }
+      }
+      else if (nvertexs < 3
+            || nvertexs % 3 != 0 )
+      {
+        if (nvertexs <= 3)
+        {
+          return Standard_False;
         }
-      } else if( nvertexs < 3 || nvertexs % 3 != 0 ) {
-#if TRACE > 0
-        cout << " *** An " << name << " is unavailable with a too lower number of vertex " << nvertexs << endl;
-#endif
-        if( nvertexs > 3 ) myPrimitiveArray->num_vertexs = 3 * (nvertexs / 3);
-        else return Standard_False;
+        myAttribs->NbElements = 3 * (nvertexs / 3);
       }
       break;
-    case TelQuadranglesArrayType:
-      if( nedges > 0 ) {
-        if( nedges < 4 || nedges % 4 != 0 ) {
-#if TRACE > 0
-          cout << " *** An " << name << " is unavailable with a too lower number of edges " << nedges << endl;
-#endif
-          if( nedges > 4 ) myPrimitiveArray->num_edges = 4 * (nedges / 4);
-          else return Standard_False;
+    case Graphic3d_TOPA_QUADRANGLES:
+      if (nedges > 0)
+      {
+        if (nedges < 4
+         || nedges % 4 != 0)
+        {
+          if (nedges <= 4)
+          {
+            return Standard_False;
+          }
+          myIndices->NbElements = 4 * (nedges / 4);
+        }
+      }
+      else if (nvertexs < 4
+            || nvertexs % 4 != 0)
+      {
+        if (nvertexs <= 4)
+        {
+          return Standard_False;
         }
-      } else if( nvertexs < 4 || nvertexs % 4 != 0 ) {
-#if TRACE > 0
-        cout << " *** An " << name << " is unavailable with a too lower number of vertex " << nvertexs << endl;
-#endif
-        if( nvertexs > 4 ) myPrimitiveArray->num_vertexs = 4 * (nvertexs / 4);
-        else return Standard_False;
+        myAttribs->NbElements = 4 * (nvertexs / 4);
       }
       break;
-    case TelTriangleFansArrayType:
-    case TelTriangleStripsArrayType:
-      if( nvertexs < 3 ) {
-#if TRACE > 0
-        cout << " *** An " << name << " is unavailable with a too lower number of vertex " << nvertexs << endl;
-#endif
+    case Graphic3d_TOPA_TRIANGLEFANS:
+    case Graphic3d_TOPA_TRIANGLESTRIPS:
+      if (nvertexs < 3)
+      {
         return Standard_False;
       }
       break;
-    case TelQuadrangleStripsArrayType:
-      if( nvertexs < 4 ) {
-#if TRACE > 0
-        cout << " *** An " << name << " is unavailable with a too lower number of vertex " << nvertexs << endl;
-#endif
+    case Graphic3d_TOPA_QUADRANGLESTRIPS:
+      if (nvertexs < 4)
+      {
         return Standard_False;
       }
       break;
+    case Graphic3d_TOPA_UNDEFINED:
     default:
-#if TRACE > 0
-      cout << " *** UNKNOWN Array of primitives type found" << endl;
-#endif
       return Standard_False;
   }
 
-  // total number of edges(verticies) in bounds should be the same as variable
-  // of total number of defined edges(verticies); if no edges - only verticies 
+  // total number of edges(vertices) in bounds should be the same as variable
+  // of total number of defined edges(vertices); if no edges - only vertices
   // could be in bounds.
-  if( nbounds > 0 ) {
-    for( i=n=0 ; i<nbounds ; i++ ) {
-      n += myPrimitiveArray->bounds[i];
+  if (nbounds > 0)
+  {
+    Standard_Integer n = 0;
+    for (Standard_Integer aBoundIter = 0; aBoundIter < nbounds; ++aBoundIter)
+    {
+      n += myBounds->Bounds[aBoundIter];
     }
-    if( nedges > 0 && n != nedges ) {
-#if TRACE > 0
-      cout << " *** An " << name << " has an incoherent number of edges " << nedges << endl;
-#endif
-      if( nedges > n ) myPrimitiveArray->num_edges = n;
-      else return Standard_False;
-    } else if ( nedges == 0 && n != nvertexs ) {
-#if TRACE > 0
-      cout << " *** An " << name << " has an incoherent number of vertexs " << nvertexs << endl;
-#endif
-      if( nvertexs > n ) myPrimitiveArray->num_vertexs = n;
-      else return Standard_False;
+    if (nedges > 0
+     && n != nedges)
+    {
+      if (nedges <= n)
+      {
+        return Standard_False;
+      }
+      myIndices->NbElements = n;
+    }
+    else if (nedges == 0
+          && n != nvertexs)
+    {
+      if (nvertexs <= n)
+      {
+        return Standard_False;
+      }
+      myAttribs->NbElements = n;
     }
   }
 
-  // check that edges (indexes to an array of verticies) are in range.
-  if( nedges > 0 ) {
-    for( i=0 ; i<nedges ; i++ ) {
-      if( myPrimitiveArray->edges[i] >= myPrimitiveArray->num_vertexs ) {
-#if TRACE > 0
-        cout << " *** An " << name << " has a vertex index " << myPrimitiveArray->edges[i] << " greater than the number of defined vertexs " << myPrimitiveArray->num_vertexs << endl;
-#endif
-        myPrimitiveArray->edges[i] = myPrimitiveArray->num_vertexs-1;
+  // check that edges (indexes to an array of vertices) are in range.
+  if (nedges > 0)
+  {
+    for (Standard_Integer anEdgeIter = 0; anEdgeIter < nedges; ++anEdgeIter)
+    {
+      if (myIndices->Index (anEdgeIter) >= myAttribs->NbElements)
+      {
+        return Standard_False;
       }
     }
   }
-
   return Standard_True;
 }