0024406: Visualization - crash on re-usage of the same primitive array
authorkgv <kgv@opencascade.com>
Thu, 17 Apr 2014 14:01:04 +0000 (18:01 +0400)
committerapn <apn@opencascade.com>
Thu, 17 Apr 2014 14:01:51 +0000 (18:01 +0400)
Redesign Graphic3d_ArrayOfPrimitives
Store vertices data in buffer objects managed using smart-pointers
- no more low-level memory corruption by memory releasing after VBO creation.
Remove broken hasEdgeInfos.

Interleave vertex attributes (position, color, normal, uv) in single buffer.
Remove from Graphic3d_ArrayOfPrimitives methods ::Orientate().
Remove structures Graphic3d_PrimitiveArray, CALL_DEF_PARRAY.
Add support for 2D vertex arrays.

Graphic3d_Group - remove array or primitive arrays.
Introduce more universal method Graphic3d_Group::AddPrimitiveArray().

Fix warning

45 files changed:
src/AIS/AIS_Triangulation.cxx
src/Graphic3d/FILES
src/Graphic3d/Graphic3d.cdl
src/Graphic3d/Graphic3d_ArrayOfPoints.cxx
src/Graphic3d/Graphic3d_ArrayOfPolygons.cdl
src/Graphic3d/Graphic3d_ArrayOfPolygons.cxx
src/Graphic3d/Graphic3d_ArrayOfPolylines.cdl
src/Graphic3d/Graphic3d_ArrayOfPolylines.cxx
src/Graphic3d/Graphic3d_ArrayOfPrimitives.cdl
src/Graphic3d/Graphic3d_ArrayOfPrimitives.cxx
src/Graphic3d/Graphic3d_ArrayOfPrimitives.lxx
src/Graphic3d/Graphic3d_ArrayOfQuadrangleStrips.cxx
src/Graphic3d/Graphic3d_ArrayOfQuadrangles.cdl
src/Graphic3d/Graphic3d_ArrayOfQuadrangles.cxx
src/Graphic3d/Graphic3d_ArrayOfSegments.cxx
src/Graphic3d/Graphic3d_ArrayOfTriangleFans.cxx
src/Graphic3d/Graphic3d_ArrayOfTriangleStrips.cxx
src/Graphic3d/Graphic3d_ArrayOfTriangles.cdl
src/Graphic3d/Graphic3d_ArrayOfTriangles.cxx
src/Graphic3d/Graphic3d_BoundBuffer.hxx [new file with mode: 0644]
src/Graphic3d/Graphic3d_BoundBuffer_Handle.hxx [copied from src/Graphic3d/Graphic3d_PrimitiveArray.hxx with 57% similarity]
src/Graphic3d/Graphic3d_Buffer.hxx [new file with mode: 0644]
src/Graphic3d/Graphic3d_Buffer_Handle.hxx [copied from src/Graphic3d/Graphic3d_PrimitiveArray.hxx with 57% similarity]
src/Graphic3d/Graphic3d_GraphicDriver.cdl
src/Graphic3d/Graphic3d_Group.cdl
src/Graphic3d/Graphic3d_Group.cxx
src/Graphic3d/Graphic3d_IndexBuffer.hxx [new file with mode: 0644]
src/Graphic3d/Graphic3d_IndexBuffer_Handle.hxx [moved from src/Graphic3d/Graphic3d_PrimitiveArray.hxx with 57% similarity]
src/InterfaceGraphic/FILES
src/InterfaceGraphic/InterfaceGraphic_Graphic3d.hxx
src/InterfaceGraphic/InterfaceGraphic_PrimitiveArray.hxx [deleted file]
src/NCollection/NCollection_Vec4.hxx
src/OpenGl/OpenGl_CappingAlgo.cxx
src/OpenGl/OpenGl_GraphicDriver.hxx
src/OpenGl/OpenGl_Group.cxx
src/OpenGl/OpenGl_Group.hxx
src/OpenGl/OpenGl_PrimitiveArray.cxx
src/OpenGl/OpenGl_PrimitiveArray.hxx
src/OpenGl/OpenGl_SceneGeometry.cxx
src/OpenGl/OpenGl_VertexBuffer.cxx
src/OpenGl/OpenGl_VertexBuffer.hxx
src/OpenGl/OpenGl_Workspace.hxx
src/OpenGl/OpenGl_Workspace_Raytrace.cxx
src/StdPrs/StdPrs_ShadedShape.cxx
src/ViewerTest/ViewerTest_ObjectCommands.cxx

index b836b3a..aa3c4d5 100644 (file)
@@ -56,14 +56,8 @@ void AIS_Triangulation::Compute(const Handle(PrsMgr_PresentationManager3d)& /*aP
       Standard_Boolean hasVNormals = myTriangulation->HasNormals();
       Standard_Boolean hasVColors  = (myFlagColor == 1);
 
-      Handle(Graphic3d_ArrayOfTriangles) anArray =
-         new Graphic3d_ArrayOfTriangles ( myNbNodes,        //maxVertexs
-                                          myNbTriangles * 3,//maxEdges
-                                          hasVNormals,      //hasVNormals
-                                          hasVColors,       //hasVColors
-                                          Standard_False,   //hasTexels
-                                          Standard_True     //hasEdgeInfos
-                                         );
+      Handle(Graphic3d_ArrayOfTriangles) anArray = new Graphic3d_ArrayOfTriangles (myNbNodes, myNbTriangles * 3,
+                                                                                   hasVNormals, hasVColors, Standard_False);
       Handle(Graphic3d_Group) TheGroup = Prs3d_Root::CurrentGroup(aPresentation);
       Handle(Graphic3d_AspectFillArea3d) aspect = myDrawer->ShadingAspect()->Aspect();
 
index ba0abf0..b17e375 100755 (executable)
@@ -1,3 +1,9 @@
+Graphic3d_Buffer.hxx
+Graphic3d_Buffer_Handle.hxx
+Graphic3d_BoundBuffer.hxx
+Graphic3d_BoundBuffer_Handle.hxx
+Graphic3d_IndexBuffer.hxx
+Graphic3d_IndexBuffer_Handle.hxx
 Graphic3d_CAspectFillArea.hxx
 Graphic3d_CAspectLine.hxx
 Graphic3d_CAspectMarker.hxx
@@ -34,7 +40,6 @@ Graphic3d_StructureManager.pxx
 Graphic3d.edl
 Graphic3d_CMPLRS.edl
 Graphic3d_WOKSteps.edl
-Graphic3d_PrimitiveArray.hxx
 Graphic3d_TransModeFlags.hxx
 Graphic3d_CTransPersStruct.hxx
 Graphic3d_NListOfHAsciiString.hxx
index dd2567c..e330fc5 100644 (file)
@@ -336,7 +336,13 @@ is
     -- Category: Imported types
     ---------------------------
 
-    imported PrimitiveArray;
+    imported Buffer;
+    imported Buffer_Handle;
+    imported BoundBuffer;
+    imported BoundBuffer_Handle;
+    imported IndexBuffer;
+    imported IndexBuffer_Handle;
+
     imported BufferType;
 
     imported CBitFields20;
@@ -519,10 +525,6 @@ is
     -- Category: Instantiated classes
     ---------------------------------
 
-    class ListOfPArray instantiates
-        List from TCollection (ArrayOfPrimitives from Graphic3d);
-        ---Category: Instantiated classes
-
     class SequenceOfAddress instantiates
             Sequence from TCollection
             (Address from Standard);
index 253838b..841000f 100644 (file)
@@ -14,7 +14,7 @@
 
 #include <Graphic3d_ArrayOfPoints.ixx>
 
-Graphic3d_ArrayOfPoints :: Graphic3d_ArrayOfPoints (const Standard_Integer maxVertexs,
-                                                    const Standard_Boolean hasVColors)
-: Graphic3d_ArrayOfPrimitives (Graphic3d_TOPA_POINTS, maxVertexs, 0, 0, Standard_False, hasVColors, Standard_False, Standard_False, Standard_False)
+Graphic3d_ArrayOfPoints::Graphic3d_ArrayOfPoints (const Standard_Integer theMaxVertexs,
+                                                  const Standard_Boolean theHasVColors)
+: Graphic3d_ArrayOfPrimitives (Graphic3d_TOPA_POINTS, theMaxVertexs, 0, 0, Standard_False, theHasVColors, Standard_False, Standard_False)
 {}
index 1812c5d..4a6a366 100644 (file)
@@ -24,8 +24,7 @@ is
                 hasVNormals: Boolean from Standard = Standard_False;
                 hasVColors: Boolean from Standard = Standard_False;
                 hasBColors: Boolean from Standard = Standard_False;
-                hasTexels: Boolean from Standard = Standard_False;
-                hasEdgeInfos: Boolean from Standard = Standard_False)
+                hasTexels: Boolean from Standard = Standard_False)
        returns mutable ArrayOfPolygons from Graphic3d;
         ---Purpose: Creates an array of polygons,
        -- a polygon can be filled as:
@@ -105,9 +104,6 @@ is
        -- When <hasBColors> is TRUE , <maxBounds> must be > 0 and
        --      you must use the
        --      AddBound(number,Color) method.
-       -- When <hasEdgeInfos> is TRUE , <maxEdges> must be > 0 and
-       --      you must use the
-       --      AddEdge(number,visibillity) method.
        --  Warning:
        -- the user is responsible about the orientation of the polygon
        -- depending of the order of the created vertex or edges and this
index 7a98943..bc5c5a2 100644 (file)
 
 #include <Graphic3d_ArrayOfPolygons.ixx>
 
-Graphic3d_ArrayOfPolygons :: Graphic3d_ArrayOfPolygons (
-                        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)
-       : Graphic3d_ArrayOfPrimitives(Graphic3d_TOPA_POLYGONS,maxVertexs,maxBounds,maxEdges,hasVNormals,hasVColors,hasFColors,hasVTexels,hasEdgeInfos) {}
+Graphic3d_ArrayOfPolygons::Graphic3d_ArrayOfPolygons (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)
+: Graphic3d_ArrayOfPrimitives (Graphic3d_TOPA_POLYGONS, theMaxVertexs, theMaxBounds, theMaxEdges, theHasVNormals, theHasVColors, theHasFColors, theHasVTexels)
+{}
index 10f5934..fe8a82a 100644 (file)
@@ -22,8 +22,7 @@ is
                 maxBounds: Integer from Standard = 0;
                 maxEdges: Integer from Standard = 0;
                 hasVColors: Boolean from Standard = Standard_False;
-                hasBColors: Boolean from Standard = Standard_False;
-                hasEdgeInfos: Boolean from Standard = Standard_False)
+                hasBColors: Boolean from Standard = Standard_False)
        returns mutable ArrayOfPolylines from Graphic3d;
         ---Purpose: Creates an array of polylines,
         -- a polyline can be filled as:
@@ -97,8 +96,5 @@ is
         -- When <hasBColors> is TRUE , <maxBounds> must be > 0 and
         --      you must use the
         --      AddBound(number,Color) method.
-        -- When <hasEdgeInfos> is TRUE , <maxEdges> must be > 0 and
-        --      you must use the
-        --      AddEdge(number,visibillity) method.
 
 end;
index 6d3ffc3..23fea53 100644 (file)
 
 #include <Graphic3d_ArrayOfPolylines.ixx>
 
-Graphic3d_ArrayOfPolylines :: Graphic3d_ArrayOfPolylines (
-                        const Standard_Integer maxVertexs,
-                        const Standard_Integer maxBounds,
-                        const Standard_Integer maxEdges,
-                        const Standard_Boolean hasVColors,
-                        const Standard_Boolean hasFColors,
-                       const Standard_Boolean hasEdgeInfos)
-       : Graphic3d_ArrayOfPrimitives(Graphic3d_TOPA_POLYLINES,maxVertexs,maxBounds,maxEdges,Standard_False,hasVColors,hasFColors,Standard_False,hasEdgeInfos) {}
+Graphic3d_ArrayOfPolylines::Graphic3d_ArrayOfPolylines (const Standard_Integer theMaxVertexs,
+                                                        const Standard_Integer theMaxBounds,
+                                                        const Standard_Integer theMaxEdges,
+                                                        const Standard_Boolean theHasVColors,
+                                                        const Standard_Boolean theHasFColors)
+: Graphic3d_ArrayOfPrimitives (Graphic3d_TOPA_POLYLINES, theMaxVertexs, theMaxBounds, theMaxEdges, Standard_False, theHasVColors, theHasFColors, Standard_False)
+{}
index e2bb9a7..b056281 100644 (file)
@@ -34,12 +34,14 @@ deferred class ArrayOfPrimitives from Graphic3d inherits TShared
 
 uses
 
-    TypeOfPrimitiveArray    from Graphic3d,
-    PrimitiveArray      from Graphic3d,
-    Color           from Quantity,
-    Pnt         from gp,
-    Pnt2d           from gp,
-    Dir         from gp
+    TypeOfPrimitiveArray from Graphic3d,
+    Buffer_Handle        from Graphic3d,
+    BoundBuffer_Handle   from Graphic3d,
+    IndexBuffer_Handle   from Graphic3d,
+    Color                from Quantity,
+    Pnt                  from gp,
+    Pnt2d                from gp,
+    Dir                  from gp
 
 raises
     OutOfRange from Standard,
@@ -56,8 +58,7 @@ is
                 hasVNormals: Boolean from Standard;
                 hasVColors: Boolean from Standard;
                 hasBColors: Boolean from Standard;
-                hasTexels: Boolean from Standard;
-            hasEdgeInfos: Boolean from Standard)
+                hasTexels: Boolean from Standard)
     returns mutable ArrayOfPrimitives from Graphic3d
         raises  InitialisationError from Graphic3d;
     ---Purpose:  Warning
@@ -68,8 +69,6 @@ is
     -- constructor parameter is > 0.
     -- You must use AddEdge() method only if the <maxEdges>
     -- constructor parameter is > 0.
-    -- You must use a coherent set of AddEdge() methods according to the
-    -- <hasEdgeInfos> constructor parameter.
 
     Destroy( me: mutable);
     -- destructor
@@ -327,17 +326,11 @@ is
     -- if the actual Bound number is >= <maxBounds>
 
     AddEdge( me:mutable;
-         vertexIndex: Integer from Standard;
-         isVisible: Boolean from Standard = Standard_True)
+         vertexIndex: Integer from Standard)
         returns Integer from Standard
         ---Level: Public
-    ---Purpose: Adds an edge in the range [1,VertexNumber()] in the array,
-    -- if <isVisible> is FALSE the edge between <vertexIndex> and
-    -- the next edge will not be visible even if the SetEdgeOn() method
-    -- is activated in Graphic3d_AspectFillArea3d class.
-    -- returns the actual edges number.
-    --  Warning: <isVisible> is ignored when the <hasEdgeInfos>
-    -- constructor parameter is FALSE.
+    ---Purpose: Adds an edge in the range [1,VertexNumber()] in the array.
+    -- Returns the actual edges number.
         raises OutOfRange from Standard;
     -- if the actual edge number is >= <maxEdges>
 
@@ -345,47 +338,6 @@ is
     --      Methods to modify the array
     -- -------------------------------------------------------------------
 
-    Orientate( me:mutable; 
-        aNormal: Dir from gp)
-    returns Boolean from Standard;
-    ---Level: Public 
-    ---Purpose: Orientate correctly all vertexs & normals of this array 
-    -- according to the <aNormal> parameter and
-    -- returns TRUE when something has change in the array.
-    --  Warning: When the array has edges this method is apply
-    -- on edge sub array instead on vertex sub array.
-
-    Orientate( me:mutable;
-        aVertexIndex: Integer from Standard;
-        aVertexNumber: Integer from Standard;
-        aNormal: Dir from gp)
-    returns Boolean from Standard
-    ---Level: Internal 
-    ---Purpose: Orientate correctly a set of vertexs & normal
-    -- from <aVertexIndex> to <aVertexIndex>+<aVertexNumber>-1 
-    -- according to the <aNormal> parameter and
-    -- returns TRUE when something has change in the array.
-    --  Warning: When the array has edges this method is apply
-    -- on edge sub array instead on vertex sub array.
-        raises OutOfRange from Standard is private;
-    -- if the <aVertexIndex> parameter is < 1 or > VertexNumber() or
-    -- EdgeNumber()
-
-    Orientate( me:mutable;
-        aBoundIndex: Integer from Standard;
-        aNormal: Dir from gp)
-    returns Boolean from Standard
-    ---Level: Public 
-    ---Purpose: Orientate correctly all vertexs & normal of the bound <aBound> 
-    -- according to the <aNormal> parameter and
-    -- returns TRUE when something has change in the array.
-    --  Warning: When the array has edges this method is apply
-    -- on edge sub array instead on vertex sub array.
-    -- When this array has no bound, <aBoundIndex> design the item number
-        raises OutOfRange from Standard;
-    -- if the <aBoundIndex> parameter is < 1 or > BoundNumber()
-    -- or if the <aBoundIndex> parameter is < 1 or > ItemNumber()
-
     SetVertice( me:mutable;
                 anIndex: Integer from Standard;
                 aVertice: Pnt from gp)
@@ -487,11 +439,23 @@ is
     -- Category Inquiries on array
     -------------------------------------------------------------------
 
-    Array( me ) 
-    returns PrimitiveArray from Graphic3d;
-    ---Level: Internal
-    ---Purpose: Returns the array address. 
+    Indices (me)
+    returns IndexBuffer_Handle from Graphic3d;
+    ---Purpose: Returns optional index buffer.
     ---C++: inline
+    ---C++: return const &
+
+    Attributes (me)
+    returns Buffer_Handle from Graphic3d;
+    ---Purpose: Returns vertex attributes buffer (colors, normals, texture coordinates).
+    ---C++: inline
+    ---C++: return const &
+
+    Bounds (me)
+    returns BoundBuffer_Handle from Graphic3d;
+    ---Purpose: Returns optional bounds buffer.
+    ---C++: inline
+    ---C++: return const &
 
     Type( me )
     returns TypeOfPrimitiveArray from Graphic3d;
@@ -606,12 +570,6 @@ is
     -- when the rank is < 1 or > VertexNumber().
     ---C++: inline
 
-    HasEdgeInfos( me )
-    returns Boolean from Standard;
-    ---Level: Public 
-    ---Purpose: Returns TRUE when edge visibillity array is defined. 
-    ---C++: inline
-
     EdgeNumber( me ) 
     returns Integer from Standard;  
     ---Level: Public 
@@ -627,15 +585,6 @@ is
     -- when the rank is < 1 or > EdgeNumber() 
     ---C++: inline
 
-    EdgeIsVisible( me ; aRank: Integer from Standard)
-    returns Boolean from Standard   
-    ---Level: Public 
-    ---Purpose: Returns TRUE when the edge at rank <aRank>
-    -- is visible. 
-    raises OutOfRange from Standard;
-    -- when the rank is < 1 or > EdgeNumber() 
-    ---C++: inline
-
     HasBoundColors( me )
     returns Boolean from Standard;
     ---Level: Public 
@@ -692,10 +641,19 @@ is
     is private;
 
 fields
-    myPrimitiveArray:   PrimitiveArray from Graphic3d;
-    myMaxBounds:        Integer from Standard;
-    myMaxVertexs:       Integer from Standard;
-    myMaxEdges:     Integer from Standard;
+
+  myIndices        : IndexBuffer_Handle from Graphic3d; -- optional index buffer
+  myAttribs        : Buffer_Handle      from Graphic3d; -- vertex attributes buffer (colors, normals, texture coordinates)
+  myBounds         : BoundBuffer_Handle from Graphic3d; -- vertex attributes buffer (colors, normals, texture coordinates)
+
+  myType           : TypeOfPrimitiveArray from Graphic3d;
+
+  myMaxBounds      : Integer from Standard;
+  myMaxVertexs     : Integer from Standard;
+  myMaxEdges       : Integer from Standard;
+  myVNor           : Byte from Standard; -- offset to normal attribute
+  myVTex           : Byte from Standard; -- offset to texel  attribute
+  myVCol           : Byte from Standard; -- offset to color  attribute
 
 friends
     class Group from Graphic3d
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;
 }
index 81d7154..34708f1 100644 (file)
 #include <Graphic3d_ArrayOfPrimitives.hxx>
 #include <Standard_OutOfRange.hxx>
 
-#include <stdio.h>
-#include <stdlib.h>
-
 #include <gp_Dir.hxx>
 #include <gp_Pnt.hxx>
 
-inline Graphic3d_PrimitiveArray Graphic3d_ArrayOfPrimitives::Array() const
+inline const Handle(Graphic3d_IndexBuffer)& Graphic3d_ArrayOfPrimitives::Indices() const
+{
+  return myIndices;
+}
+
+inline const Handle(Graphic3d_Buffer)& Graphic3d_ArrayOfPrimitives::Attributes() const
 {
-  return myPrimitiveArray;
+  return myAttribs;
+}
+
+inline const Handle(Graphic3d_BoundBuffer)& Graphic3d_ArrayOfPrimitives::Bounds() const
+{
+  return myBounds;
 }
 
 inline Graphic3d_TypeOfPrimitiveArray Graphic3d_ArrayOfPrimitives::Type() const
 {
-  Graphic3d_TypeOfPrimitiveArray type = Graphic3d_TOPA_UNDEFINED;
-  if( myPrimitiveArray ) type = (Graphic3d_TypeOfPrimitiveArray) myPrimitiveArray->type;
-  return type;
+  return myType;
 }
 
 inline Standard_Boolean Graphic3d_ArrayOfPrimitives::HasVertexNormals() const
 {
-  Standard_Boolean defined = Standard_False;
-  if( myPrimitiveArray && myPrimitiveArray->vnormals ) defined = Standard_True;
-  return defined;
+  return myVNor != 0;
 }
 
 inline Standard_Boolean Graphic3d_ArrayOfPrimitives::HasVertexColors() const
 {
-  Standard_Boolean defined = Standard_False;
-  if( myPrimitiveArray && myPrimitiveArray->vcolours ) defined = Standard_True;
-  return defined;
+  return myVCol != 0;
 }
 
 inline Standard_Boolean Graphic3d_ArrayOfPrimitives::HasVertexTexels() const
 {
-  Standard_Boolean defined = Standard_False;
-  if( myPrimitiveArray && myPrimitiveArray->vtexels ) defined = Standard_True;
-  return defined;
-}
-
-inline Standard_Boolean Graphic3d_ArrayOfPrimitives::HasEdgeInfos() const
-{
-  Standard_Boolean defined = Standard_False;
-  if( myPrimitiveArray && myPrimitiveArray->edge_vis ) defined = Standard_True;
-  return defined;
+  return myVTex != 0;
 }
 
 inline Standard_Integer Graphic3d_ArrayOfPrimitives::VertexNumber() const
 {
-  Standard_Integer number = -1;
-  if( myPrimitiveArray ) number = myPrimitiveArray->num_vertexs;
-  return number;
+  return !myAttribs.IsNull() ? myAttribs->NbElements : -1;
 }
 
-inline Standard_Integer Graphic3d_ArrayOfPrimitives::AddVertex(const gp_Pnt& aVertice)
+inline Standard_Integer Graphic3d_ArrayOfPrimitives::AddVertex (const gp_Pnt& theVertex)
 {
-  return AddVertex(aVertice.X(),aVertice.Y(),aVertice.Z());
+  return AddVertex (theVertex.X(), theVertex.Y(), theVertex.Z());
 }
 
-inline Standard_Integer Graphic3d_ArrayOfPrimitives::AddVertex(
-        const Standard_Real X, const Standard_Real Y, const Standard_Real Z)
+inline Standard_Integer Graphic3d_ArrayOfPrimitives::AddVertex (const Standard_Real theX,
+                                                                const Standard_Real theY,
+                                                                const Standard_Real theZ)
 {
-  return AddVertex(Standard_ShortReal(X),Standard_ShortReal(Y),Standard_ShortReal(Z));
+  return AddVertex (Standard_ShortReal (theX),
+                    Standard_ShortReal (theY),
+                    Standard_ShortReal (theZ));
 }
 
-inline Standard_Integer Graphic3d_ArrayOfPrimitives::AddVertex(const gp_Pnt& aVertice, const gp_Dir& aNormal)
+inline Standard_Integer Graphic3d_ArrayOfPrimitives::AddVertex (const gp_Pnt& theVertex,
+                                                                const gp_Dir& theNormal)
 {
-  return AddVertex(aVertice.X(),aVertice.Y(),aVertice.Z(),aNormal.X(),aNormal.Y(),aNormal.Z());
+  return AddVertex (theVertex.X(), theVertex.Y(), theVertex.Z(),
+                    theNormal.X(), theNormal.Y(), theNormal.Z());
 }
 
-inline Standard_Integer Graphic3d_ArrayOfPrimitives::AddVertex(
-        const Standard_Real X, const Standard_Real Y, const Standard_Real Z,
-        const Standard_Real NX, const Standard_Real NY, const Standard_Real NZ)
+inline Standard_Integer Graphic3d_ArrayOfPrimitives::AddVertex (const Standard_Real theX,  const Standard_Real theY,  const Standard_Real theZ,
+                                                                const Standard_Real theNX, const Standard_Real theNY, const Standard_Real theNZ)
 {
-  return AddVertex(Standard_ShortReal(X),Standard_ShortReal(Y),Standard_ShortReal(Z),
-                   Standard_ShortReal(NX),Standard_ShortReal(NY),Standard_ShortReal(NZ));
+  return AddVertex (Standard_ShortReal (theX),  Standard_ShortReal (theY),  Standard_ShortReal (theZ),
+                    Standard_ShortReal (theNX), Standard_ShortReal (theNY), Standard_ShortReal (theNZ));
 }
 
-inline Standard_Integer Graphic3d_ArrayOfPrimitives::AddVertex(const gp_Pnt& aVertice, const gp_Pnt2d& aTexel)
+inline Standard_Integer Graphic3d_ArrayOfPrimitives::AddVertex (const gp_Pnt&   theVertex,
+                                                                const gp_Pnt2d& theTexel)
 {
-  return AddVertex(aVertice.X(),aVertice.Y(),aVertice.Z(),aTexel.X(),aTexel.Y());
+  return AddVertex (theVertex.X(), theVertex.Y(), theVertex.Z(),
+                    theTexel.X(), theTexel.Y());
 }
 
-inline Standard_Integer Graphic3d_ArrayOfPrimitives::AddVertex(
-        const Standard_Real X, const Standard_Real Y, const Standard_Real Z,
-        const Standard_Real TX, const Standard_Real TY)
+inline Standard_Integer Graphic3d_ArrayOfPrimitives::AddVertex (const Standard_Real theX,  const Standard_Real theY,  const Standard_Real theZ,
+                                                                const Standard_Real theTX, const Standard_Real theTY)
 {
-  return AddVertex(Standard_ShortReal(X),Standard_ShortReal(Y),Standard_ShortReal(Z),
-                   Standard_ShortReal(TX),Standard_ShortReal(TY));
+  return AddVertex (Standard_ShortReal (theX),  Standard_ShortReal (theY),  Standard_ShortReal (theZ),
+                    Standard_ShortReal (theTX), Standard_ShortReal (theTY));
 }
 
-inline Standard_Integer Graphic3d_ArrayOfPrimitives::AddVertex(const gp_Pnt& aVertice, const gp_Dir& aNormal, const gp_Pnt2d& aTexel)
+inline Standard_Integer Graphic3d_ArrayOfPrimitives::AddVertex (const gp_Pnt&   theVertex,
+                                                                const gp_Dir&   theNormal,
+                                                                const gp_Pnt2d& theTexel)
 {
-  return AddVertex(aVertice.X(),aVertice.Y(),aVertice.Z(),aNormal.X(),aNormal.Y(),aNormal.Z(),aTexel.X(),aTexel.Y());
+  return AddVertex (theVertex.X(), theVertex.Y(), theVertex.Z(),
+                    theNormal.X(), theNormal.Y(), theNormal.Z(),
+                    theTexel.X(),  theTexel.Y());
 }
 
-inline Standard_Integer Graphic3d_ArrayOfPrimitives::AddVertex(
-        const Standard_Real X, const Standard_Real Y, const Standard_Real Z,
-        const Standard_Real NX, const Standard_Real NY, const Standard_Real NZ,
-        const Standard_Real TX, const Standard_Real TY)
+inline Standard_Integer Graphic3d_ArrayOfPrimitives::AddVertex (const Standard_Real theX,  const Standard_Real theY,  const Standard_Real theZ,
+                                                                const Standard_Real theNX, const Standard_Real theNY, const Standard_Real theNZ,
+                                                                const Standard_Real theTX, const Standard_Real theTY)
 {
-  return AddVertex(Standard_ShortReal(X),Standard_ShortReal(Y),Standard_ShortReal(Z),
-                   Standard_ShortReal(NX),Standard_ShortReal(NY),Standard_ShortReal(NZ),
-                   Standard_ShortReal(TX),Standard_ShortReal(TY));
+  return AddVertex (Standard_ShortReal (theX),  Standard_ShortReal (theY),  Standard_ShortReal (theZ),
+                    Standard_ShortReal (theNX), Standard_ShortReal (theNY), Standard_ShortReal (theNZ),
+                    Standard_ShortReal (theTX), Standard_ShortReal (theTY));
 }
 
-inline void Graphic3d_ArrayOfPrimitives::SetVertice(
-        const Standard_Integer anIndex,
-        const Standard_ShortReal X, const Standard_ShortReal Y, const Standard_ShortReal Z)
+inline void Graphic3d_ArrayOfPrimitives::SetVertice (const Standard_Integer   theIndex,
+                                                     const Standard_ShortReal theX,
+                                                     const Standard_ShortReal theY,
+                                                     const Standard_ShortReal theZ)
 {
-  if( !myPrimitiveArray ) return;
-  if( anIndex < 1 || anIndex > myMaxVertexs )
-    Standard_OutOfRange::Raise(" BAD VERTEX index");
+  if (myAttribs.IsNull())
+  {
+    return;
+  }
 
-  if( myPrimitiveArray->vertices ) {
-    Tfloat *p = myPrimitiveArray->vertices[anIndex-1].xyz;
-    *p++ = X;
-    *p++ = Y;
-    *p   = Z;
+  if (theIndex < 1
+   || theIndex > myMaxVertexs)
+  {
+    Standard_OutOfRange::Raise ("BAD VERTEX index");
   }
-  myPrimitiveArray->num_vertexs = Max(anIndex,myPrimitiveArray->num_vertexs);
+
+  Graphic3d_Vec3& aVec = myAttribs->ChangeValue<Graphic3d_Vec3> (theIndex - 1);
+  aVec.x() = theX;
+  aVec.y() = theY;
+  aVec.z() = theZ;
+
+  myAttribs->NbElements = Max (theIndex, myAttribs->NbElements);
 }
 
-inline void Graphic3d_ArrayOfPrimitives::SetVertexColor(const Standard_Integer anIndex,
-                                                        const Standard_Real R,
-                                                        const Standard_Real G,
-                                                        const Standard_Real B)
+inline void Graphic3d_ArrayOfPrimitives::SetVertexColor (const Standard_Integer theIndex,
+                                                         const Standard_Real    theR,
+                                                         const Standard_Real    theG,
+                                                         const Standard_Real    theB)
 {
-  if( !myPrimitiveArray ) return;
-  if( anIndex < 1 || anIndex > myMaxVertexs ) {
-    Standard_OutOfRange::Raise(" BAD VERTEX index");
+  if (myAttribs.IsNull())
+  {
+    return;
+  }
+
+  if (theIndex < 1
+   || theIndex > myMaxVertexs)
+  {
+    Standard_OutOfRange::Raise ("BAD VERTEX index");
   }
 
-  if( myPrimitiveArray->vcolours ) {
-    unsigned int red   = (unsigned int)(R * 255.);
-    unsigned int green = (unsigned int)(G * 255.);
-    unsigned int blue  = (unsigned int)(B * 255.);
-    unsigned int alpha = 0;
-    Standard_Integer outColor = alpha << 24 | blue << 16 | green << 8 | red;
-    SetVertexColor( anIndex, outColor );
+  if (myVCol != 0)
+  {
+    Graphic3d_Vec4ub aColor (Standard_Byte(theR * 255.0),
+                             Standard_Byte(theG * 255.0),
+                             Standard_Byte(theB * 255.0), 0);
+    SetVertexColor (theIndex, *reinterpret_cast<Standard_Integer*>(&aColor));
   }
-  myPrimitiveArray->num_vertexs = Max(anIndex,myPrimitiveArray->num_vertexs);
+  myAttribs->NbElements = Max (theIndex, myAttribs->NbElements);
 }
 
-inline void Graphic3d_ArrayOfPrimitives::SetVertexNormal(
-        const Standard_Integer anIndex,
-        const Standard_Real NX, const Standard_Real NY, const Standard_Real NZ)
+inline void Graphic3d_ArrayOfPrimitives::SetVertexNormal (const Standard_Integer theIndex,
+                                                          const Standard_Real    theNX,
+                                                          const Standard_Real    theNY,
+                                                          const Standard_Real    theNZ)
 {
-  if( !myPrimitiveArray ) return;
-  if( anIndex < 1 || anIndex > myMaxVertexs ) {
-    Standard_OutOfRange::Raise(" BAD VERTEX index");
+  if (myAttribs.IsNull())
+  {
+    return;
   }
 
-  Standard_Integer index = anIndex-1;
+  if (theIndex < 1
+   || theIndex > myMaxVertexs)
+  {
+    Standard_OutOfRange::Raise ("BAD VERTEX index");
+  }
 
+  if (myVNor != 0)
   {
-    if( myPrimitiveArray->vnormals ) {
-      Tfloat *p = myPrimitiveArray->vnormals[index].xyz;
-      *p++ = Standard_ShortReal(NX);
-      *p++ = Standard_ShortReal(NY);
-      *p = Standard_ShortReal(NZ);
-    }
+    Graphic3d_Vec3& aVec = *reinterpret_cast<Graphic3d_Vec3* >(myAttribs->changeValue (theIndex - 1) + size_t(myVNor));
+    aVec.x() = Standard_ShortReal (theNX);
+    aVec.y() = Standard_ShortReal (theNY);
+    aVec.z() = Standard_ShortReal (theNZ);
   }
-  myPrimitiveArray->num_vertexs = Max(anIndex,myPrimitiveArray->num_vertexs);
+  myAttribs->NbElements = Max (theIndex, myAttribs->NbElements);
 }
 
-inline void Graphic3d_ArrayOfPrimitives::SetVertexTexel(
-        const Standard_Integer anIndex,
-        const Standard_Real TX, const Standard_Real TY)
+inline void Graphic3d_ArrayOfPrimitives::SetVertexTexel (const Standard_Integer theIndex,
+                                                         const Standard_Real    theTX,
+                                                         const Standard_Real    theTY)
 {
-  if( !myPrimitiveArray ) return;
-  if( anIndex < 1 || anIndex > myMaxVertexs ) {
-    Standard_OutOfRange::Raise(" BAD VERTEX index");
+  if (myAttribs.IsNull())
+  {
+    return;
   }
 
-  Standard_Integer index = anIndex-1;
-  if( myPrimitiveArray->vtexels ) {
-    Tfloat *p = myPrimitiveArray->vtexels[index].xy;
-    *p++ = Standard_ShortReal(TX);
-    *p = Standard_ShortReal(TY);
+  if (theIndex < 1
+   || theIndex > myMaxVertexs)
+  {
+    Standard_OutOfRange::Raise ("BAD VERTEX index");
   }
-  myPrimitiveArray->num_vertexs = Max(anIndex,myPrimitiveArray->num_vertexs);
+
+  if (myVTex != 0)
+  {
+    Graphic3d_Vec2& aVec = *reinterpret_cast<Graphic3d_Vec2* >(myAttribs->changeValue (theIndex - 1) + size_t(myVTex));
+    aVec.x() = Standard_ShortReal (theTX);
+    aVec.y() = Standard_ShortReal (theTY);
+  }
+  myAttribs->NbElements = Max (theIndex, myAttribs->NbElements);
 }
 
-inline void Graphic3d_ArrayOfPrimitives::SetBoundColor(
-        const Standard_Integer anIndex,
-        const Standard_Real R, const Standard_Real G, const Standard_Real B)
+inline void Graphic3d_ArrayOfPrimitives::SetBoundColor (const Standard_Integer theIndex,
+                                                        const Standard_Real    theR,
+                                                        const Standard_Real    theG,
+                                                        const Standard_Real    theB)
 {
-  if( !myPrimitiveArray ) return;
-  if( anIndex < 1 || anIndex > myMaxBounds ) {
-    Standard_OutOfRange::Raise(" BAD BOUND index");
+  if (myBounds.IsNull())
+  {
+    return;
   }
 
-  Standard_Integer index = anIndex-1;
-  Tfloat *p = myPrimitiveArray->fcolours[index].rgb;
-  *p++ = Standard_ShortReal(R);
-  *p++ = Standard_ShortReal(G);
-  *p = Standard_ShortReal(B);
+  if (theIndex < 1
+   || theIndex > myMaxBounds)
+  {
+    Standard_OutOfRange::Raise ("BAD BOUND index");
+  }
 
-  myPrimitiveArray->num_bounds = Max(anIndex,myPrimitiveArray->num_bounds);
+  Graphic3d_Vec4& aVec = myBounds->Colors[theIndex - 1];
+  aVec.r() = Standard_ShortReal (theR);
+  aVec.g() = Standard_ShortReal (theG);
+  aVec.b() = Standard_ShortReal (theB);
+  aVec.a() = 1.0f;
+  myBounds->NbBounds = Max (theIndex, myBounds->NbBounds);
 }
 
-inline void Graphic3d_ArrayOfPrimitives::Vertice(const Standard_Integer anIndex,
-        Standard_Real& X, Standard_Real& Y, Standard_Real& Z) const
+inline void Graphic3d_ArrayOfPrimitives::Vertice (const Standard_Integer theIndex,
+                                                  Standard_Real&         theX,
+                                                  Standard_Real&         theY,
+                                                  Standard_Real&         theZ) const
 {
-  X = Y = Z = 0.;
-  if( !myPrimitiveArray ) return;
-  if( anIndex < 1 || anIndex > myPrimitiveArray->num_vertexs ) {
-    Standard_OutOfRange::Raise(" BAD VERTEX index");
+  theX = theY = theZ = 0.0;
+  if (myAttribs.IsNull())
+  {
+    return;
   }
 
-  Standard_Integer index = anIndex-1;
-  if( myPrimitiveArray->vertices ) {
-    Tfloat *p = myPrimitiveArray->vertices[index].xyz;
-    X = Standard_Real(*p++); Y = Standard_Real(*p++); Z = Standard_Real(*p);
+  if (theIndex < 1
+   || theIndex > myAttribs->NbElements)
+  {
+    Standard_OutOfRange::Raise ("BAD VERTEX index");
   }
+
+  const Graphic3d_Vec3& aVec = myAttribs->Value<Graphic3d_Vec3> (theIndex - 1);
+  theX = Standard_Real(aVec.x());
+  theY = Standard_Real(aVec.y());
+  theZ = Standard_Real(aVec.z());
 }
 
-inline void Graphic3d_ArrayOfPrimitives::VertexColor(const Standard_Integer anIndex,
-        Standard_Real& R, Standard_Real& G, Standard_Real& B) const
+inline void Graphic3d_ArrayOfPrimitives::VertexColor (const Standard_Integer theIndex,
+                                                      Standard_Real&         theR,
+                                                      Standard_Real&         theG,
+                                                      Standard_Real&         theB) const
 {
-  R = G = B = 0;
-  if( !myPrimitiveArray ) return;
-  if( anIndex < 1 || anIndex > myPrimitiveArray->num_vertexs ) {
-    Standard_OutOfRange::Raise(" BAD VERTEX index");
+  theR = theG = theB = 0.0;
+  if (myAttribs.IsNull())
+  {
+    return;
   }
-  Standard_Integer aColor;
-  VertexColor(anIndex, aColor);
-  if( myPrimitiveArray->vcolours ) {
-    Standard_Integer r,g,b;
-    Standard_Integer aColor;
-    VertexColor(anIndex, aColor);
-    /*Standard_Real A;
-    Standard_Integer a = aColor & 0xff000000;
-    a >>= 24;
-    A = ((Standard_Real) a) / 255.;*/
-
-    b = aColor & 0x00ff0000;
-    b >>= 16;
-    B =((Standard_Real) b) / 255.;
-
-    g = aColor & 0x0000ff00;
-    g >>= 8;
-    G = ((Standard_Real) g) / 255.;
-
-    r = aColor & 0x000000ff;
-    r >>= 0;
-    R = ((Standard_Real) r) / 255.;
+
+  if (theIndex < 1
+   || theIndex > myAttribs->NbElements)
+  {
+    Standard_OutOfRange::Raise ("BAD VERTEX index");
   }
+  Standard_Integer aColorInt = 0;
+  VertexColor (theIndex, aColorInt);
+  const Graphic3d_Vec4ub& aColor = *reinterpret_cast<const Graphic3d_Vec4ub* >(aColorInt);
+  theR = Standard_Real(aColor.r()) / 255.0;
+  theG = Standard_Real(aColor.g()) / 255.0;
+  theB = Standard_Real(aColor.b()) / 255.0;
 }
 
-inline void Graphic3d_ArrayOfPrimitives::VertexColor(const Standard_Integer anIndex,
-        Standard_Integer& aColor) const
+inline void Graphic3d_ArrayOfPrimitives::VertexColor (const Standard_Integer theIndex,
+                                                      Standard_Integer&      theColor) const
 {
-  Standard_Integer index = anIndex-1;
-
-  if( myPrimitiveArray->vcolours ) {
-#if defined (sparc) || defined (__sparc__) || defined (__sparc)
-    aColor = 0;
-    const char* p_ch = (const char*)&(myPrimitiveArray->vcolours[index]);
-    aColor += p_ch[0];
-    aColor += p_ch[1] << 8 ;
-    aColor += p_ch[2] << 16;
-    aColor += p_ch[3] << 24;
-#else
-    aColor = myPrimitiveArray->vcolours[index];
-#endif
-    }
+  if (myVCol != 0)
+  {
+    theColor = *reinterpret_cast<const Standard_Integer* >(myAttribs->value (theIndex - 1) + size_t(myVCol));
+  }
 }
 
-inline void Graphic3d_ArrayOfPrimitives::VertexNormal(const Standard_Integer anIndex,
-        Standard_Real& NX, Standard_Real& NY, Standard_Real& NZ) const
+inline void Graphic3d_ArrayOfPrimitives::VertexNormal (const Standard_Integer theIndex,
+                                                       Standard_Real&         theNX,
+                                                       Standard_Real&         theNY,
+                                                       Standard_Real&         theNZ) const
 {
-  NX = NY = NZ = 0.;
-  if( !myPrimitiveArray ) return;
-  if( anIndex < 1 || anIndex > myPrimitiveArray->num_vertexs ) {
-    Standard_OutOfRange::Raise(" BAD VERTEX index");
+  theNX = theNY = theNZ = 0.0;
+  if (myAttribs.IsNull())
+  {
+    return;
+  }
+
+  if (theIndex < 1
+   || theIndex > myAttribs->NbElements)
+  {
+    Standard_OutOfRange::Raise ("BAD VERTEX index");
   }
 
-  Standard_Integer index = anIndex-1;
-  if( myPrimitiveArray->vnormals ) {
-    Tfloat *p = myPrimitiveArray->vnormals[index].xyz;
-    NX = Standard_Real(*p++); NY = Standard_Real(*p++); NZ = Standard_Real(*p);
+  if (myVNor != 0)
+  {
+    const Graphic3d_Vec3& aVec = *reinterpret_cast<const Graphic3d_Vec3* >(myAttribs->value (theIndex - 1) + size_t(myVNor));
+    theNX = Standard_Real(aVec.x());
+    theNY = Standard_Real(aVec.y());
+    theNZ = Standard_Real(aVec.z());
   }
 }
 
-inline void Graphic3d_ArrayOfPrimitives::VertexTexel(const Standard_Integer anIndex,
-        Standard_Real& TX, Standard_Real& TY) const
+inline void Graphic3d_ArrayOfPrimitives::VertexTexel (const Standard_Integer theIndex,
+                                                      Standard_Real&         theTX,
+                                                      Standard_Real&         theTY) const
 {
-  TX = TY = 0.;
-  if( !myPrimitiveArray ) return;
-  if( anIndex < 1 || anIndex > myPrimitiveArray->num_vertexs ) {
-    Standard_OutOfRange::Raise(" BAD VERTEX index");
+  theTX = theTY = 0.0;
+  if (myAttribs.IsNull())
+  {
+    return;
   }
 
-  Standard_Integer index = anIndex-1;
-  if( myPrimitiveArray->vtexels ) {
-    Tfloat *p = myPrimitiveArray->vtexels[index].xy;
-    TX = Standard_Real(*p++); TY = Standard_Real(*p);
+  if (theIndex < 1
+   || theIndex > myAttribs->NbElements)
+  {
+    Standard_OutOfRange::Raise ("BAD VERTEX index");
   }
-}
 
-inline Standard_Integer Graphic3d_ArrayOfPrimitives::EdgeNumber() const
-{
-  Standard_Integer number = -1;
-  if( myPrimitiveArray ) number = myPrimitiveArray->num_edges;
-  return number;
+  if (myVTex != 0)
+  {
+    const Graphic3d_Vec2& aVec = *reinterpret_cast<const Graphic3d_Vec2* >(myAttribs->value (theIndex - 1) + size_t(myVTex));
+    theTX = Standard_Real(aVec.x());
+    theTY = Standard_Real(aVec.y());
+  }
 }
 
-inline Standard_Integer Graphic3d_ArrayOfPrimitives::Edge(const Standard_Integer anIndex ) const
+inline Standard_Integer Graphic3d_ArrayOfPrimitives::EdgeNumber() const
 {
-  Standard_Integer index=0;
-  if( myPrimitiveArray && myPrimitiveArray->edge_vis &&
-    (anIndex > 0) && (anIndex <= myPrimitiveArray->num_edges) ) {
-    index = myPrimitiveArray->edges[anIndex-1];
-  } else {
-    Standard_OutOfRange::Raise(" BAD EDGE index");
-  }
-  return index+1;
+  return !myIndices.IsNull() ? myIndices->NbElements : -1;
 }
 
-inline Standard_Boolean Graphic3d_ArrayOfPrimitives::EdgeIsVisible(const Standard_Integer anIndex ) const
+inline Standard_Integer Graphic3d_ArrayOfPrimitives::Edge (const Standard_Integer theIndex) const
 {
-  Standard_Boolean isVisible = Standard_False;
-  if( myPrimitiveArray && myPrimitiveArray->edge_vis &&
-    (anIndex > 0) && (anIndex <= myPrimitiveArray->num_edges) ) {
-    isVisible = (myPrimitiveArray->edge_vis[anIndex-1] == 0) ?
-                    Standard_False : Standard_True;
-  } else {
-    Standard_OutOfRange::Raise(" BAD EDGE index");
+  if (myIndices.IsNull()
+   || theIndex <= 0
+   || theIndex > myIndices->NbElements)
+  {
+    Standard_OutOfRange::Raise ("BAD EDGE index");
   }
-  return isVisible;
+  return Standard_Integer(myIndices->Index (theIndex - 1) + 1);
 }
 
 inline Standard_Boolean Graphic3d_ArrayOfPrimitives::HasBoundColors() const
 {
-  Standard_Boolean defined = Standard_False;
-  if( myPrimitiveArray && myPrimitiveArray->fcolours ) defined = Standard_True;
-  return defined;
+  return !myBounds.IsNull() && myBounds->Colors != NULL;
 }
 
 inline Standard_Integer Graphic3d_ArrayOfPrimitives::BoundNumber() const
 {
-  Standard_Integer number = -1;
-  if( myPrimitiveArray ) number = myPrimitiveArray->num_bounds;
-  return number;
+  return !myBounds.IsNull() ? myBounds->NbBounds : -1;
 }
 
-inline Standard_Integer Graphic3d_ArrayOfPrimitives::Bound(const Standard_Integer anIndex) const
+inline Standard_Integer Graphic3d_ArrayOfPrimitives::Bound (const Standard_Integer theIndex) const
 {
-  Standard_Integer number=-1;
-  if( myPrimitiveArray && myPrimitiveArray->bounds &&
-    (anIndex > 0) && (anIndex <= myPrimitiveArray->num_bounds) ) {
-    number = myPrimitiveArray->bounds[anIndex-1];
-  } else {
-    Standard_OutOfRange::Raise(" BAD BOUND index");
+  if (myBounds.IsNull()
+   || theIndex <= 0
+   || theIndex > myBounds->NbBounds)
+  {
+    Standard_OutOfRange::Raise ("BAD BOUND index");
   }
-  return number;
+  return myBounds->Bounds[theIndex - 1];
 }
 
-inline void Graphic3d_ArrayOfPrimitives::BoundColor(const Standard_Integer anIndex,
-        Standard_Real& R, Standard_Real& G, Standard_Real& B) const
+inline void Graphic3d_ArrayOfPrimitives::BoundColor (const Standard_Integer theIndex,
+                                                     Standard_Real&         theR,
+                                                     Standard_Real&         theG,
+                                                     Standard_Real&         theB) const
 {
-  if( myPrimitiveArray && myPrimitiveArray->fcolours &&
-    (anIndex > 0) && (anIndex <= myPrimitiveArray->num_bounds) ) {
-    Tfloat *p = myPrimitiveArray->fcolours[anIndex-1].rgb;
-    R = Standard_Real(*p++); G = Standard_Real(*p++); B = Standard_Real(*p);
-  } else {
+  if (myBounds.IsNull()
+   || myBounds->Colors == NULL
+   || theIndex <= 0
+   || theIndex > myBounds->NbBounds)
+  {
     Standard_OutOfRange::Raise(" BAD BOUND index");
   }
+
+  const Graphic3d_Vec4& aVec = myBounds->Colors[theIndex - 1];
+  theR = Standard_Real(aVec.r());
+  theG = Standard_Real(aVec.g());
+  theB = Standard_Real(aVec.b());
 }
index ab1bd54..72c0520 100644 (file)
 
 #include <Graphic3d_ArrayOfQuadrangleStrips.ixx>
 
-Graphic3d_ArrayOfQuadrangleStrips :: Graphic3d_ArrayOfQuadrangleStrips (
-                        const Standard_Integer maxVertexs,
-                        const Standard_Integer maxStrips,
-                        const Standard_Boolean hasVNormals,
-                        const Standard_Boolean hasVColors,
-                        const Standard_Boolean hasSColors,
-                        const Standard_Boolean hasVTexels)
-       : Graphic3d_ArrayOfPrimitives(Graphic3d_TOPA_QUADRANGLESTRIPS,maxVertexs,maxStrips,0,hasVNormals,hasVColors,hasSColors,hasVTexels,Standard_False) {}
+Graphic3d_ArrayOfQuadrangleStrips::Graphic3d_ArrayOfQuadrangleStrips (const Standard_Integer theMaxVertexs,
+                                                                      const Standard_Integer theMaxStrips,
+                                                                      const Standard_Boolean theHasVNormals,
+                                                                      const Standard_Boolean theHasVColors,
+                                                                      const Standard_Boolean theHasSColors,
+                                                                      const Standard_Boolean theHasVTexels)
+: Graphic3d_ArrayOfPrimitives (Graphic3d_TOPA_QUADRANGLESTRIPS, theMaxVertexs, theMaxStrips, 0, theHasVNormals, theHasVColors, theHasSColors, theHasVTexels)
+{}
index 0d2be5c..f5e6be5 100644 (file)
@@ -31,8 +31,7 @@ is
                 maxEdges: Integer from Standard = 0;
                 hasVNormals: Boolean from Standard = Standard_False;
                 hasVColors: Boolean from Standard = Standard_False;
-                hasTexels: Boolean from Standard = Standard_False;
-               hasEdgeInfos: Boolean from Standard = Standard_False)
+                hasTexels: Boolean from Standard = Standard_False)
        returns mutable ArrayOfQuadrangles from Graphic3d;
         ---Purpose: Creates an array of quadrangles,
        -- a quadrangle can be filled as:
@@ -71,9 +70,6 @@ is
        -- When <hasTexels> is TRUE , you must use one of
        --      AddVertex(Point,Texel) 
        --  or  AddVertex(Point,Normal,Texel) methods.
-       -- When <hasEdgeInfos> is TRUE , <maxEdges> must be > 0 and
-       --      you must use the
-       --      AddEdge(number,visibillity) method.
        --  Warning:
        -- the user is responsible about the orientation of the quadrangle
        -- depending of the order of the created vertex or edges and this
index b2b5788..88c8ed7 100644 (file)
 
 #include <Graphic3d_ArrayOfQuadrangles.ixx>
 
-Graphic3d_ArrayOfQuadrangles :: Graphic3d_ArrayOfQuadrangles (
-                        const Standard_Integer maxVertexs,
-                        const Standard_Integer maxEdges,
-                        const Standard_Boolean hasVNormals,
-                        const Standard_Boolean hasVColors,
-                        const Standard_Boolean hasVTexels,
-                       const Standard_Boolean hasEdgesInfos)
-       : Graphic3d_ArrayOfPrimitives(Graphic3d_TOPA_QUADRANGLES,maxVertexs,0,maxEdges,hasVNormals,hasVColors,Standard_False,hasVTexels,hasEdgesInfos) {}
+Graphic3d_ArrayOfQuadrangles::Graphic3d_ArrayOfQuadrangles (const Standard_Integer theMaxVertexs,
+                                                            const Standard_Integer theMaxEdges,
+                                                            const Standard_Boolean theHasVNormals,
+                                                            const Standard_Boolean theHasVColors,
+                                                            const Standard_Boolean theHasVTexels)
+: Graphic3d_ArrayOfPrimitives (Graphic3d_TOPA_QUADRANGLES, theMaxVertexs, 0, theMaxEdges, theHasVNormals, theHasVColors, Standard_False, theHasVTexels)
+{}
index 5e14310..7e4d208 100644 (file)
@@ -14,8 +14,8 @@
 
 #include <Graphic3d_ArrayOfSegments.ixx>
 
-Graphic3d_ArrayOfSegments :: Graphic3d_ArrayOfSegments (
-                        const Standard_Integer maxVertexs,
-                        const Standard_Integer maxEdges,
-                        const Standard_Boolean hasVColors)
-       : Graphic3d_ArrayOfPrimitives(Graphic3d_TOPA_SEGMENTS,maxVertexs,0,maxEdges,Standard_False,hasVColors,Standard_False,Standard_False,Standard_False) {}
+Graphic3d_ArrayOfSegments::Graphic3d_ArrayOfSegments (const Standard_Integer theMaxVertexs,
+                                                      const Standard_Integer theMaxEdges,
+                                                      const Standard_Boolean theHasVColors)
+: Graphic3d_ArrayOfPrimitives (Graphic3d_TOPA_SEGMENTS, theMaxVertexs, 0, theMaxEdges, Standard_False, theHasVColors, Standard_False, Standard_False)
+{}
index ca888cd..cbf5ba8 100644 (file)
 
 #include <Graphic3d_ArrayOfTriangleFans.ixx>
 
-Graphic3d_ArrayOfTriangleFans :: Graphic3d_ArrayOfTriangleFans (
-                        const Standard_Integer maxVertexs,
-                        const Standard_Integer maxFans,
-                        const Standard_Boolean hasVNormals,
-                        const Standard_Boolean hasVColors,
-                        const Standard_Boolean hasFColors,
-                        const Standard_Boolean hasVTexels)
-       : Graphic3d_ArrayOfPrimitives(Graphic3d_TOPA_TRIANGLEFANS,maxVertexs,maxFans,0,hasVNormals,hasVColors,hasFColors,hasVTexels,Standard_False) {}
+Graphic3d_ArrayOfTriangleFans::Graphic3d_ArrayOfTriangleFans (const Standard_Integer theMaxVertexs,
+                                                              const Standard_Integer theMaxFans,
+                                                              const Standard_Boolean theHasVNormals,
+                                                              const Standard_Boolean theHasVColors,
+                                                              const Standard_Boolean theHasFColors,
+                                                              const Standard_Boolean theHasVTexels)
+: Graphic3d_ArrayOfPrimitives (Graphic3d_TOPA_TRIANGLEFANS, theMaxVertexs, theMaxFans, 0, theHasVNormals, theHasVColors, theHasFColors, theHasVTexels)
+{}
index cac3c76..09f368c 100644 (file)
 
 #include <Graphic3d_ArrayOfTriangleStrips.ixx>
 
-Graphic3d_ArrayOfTriangleStrips :: Graphic3d_ArrayOfTriangleStrips (
-                        const Standard_Integer maxVertexs,
-                        const Standard_Integer maxStrips,
-                        const Standard_Boolean hasVNormals,
-                        const Standard_Boolean hasVColors,
-                        const Standard_Boolean hasSColors,
-                        const Standard_Boolean hasVTexels)
-       : Graphic3d_ArrayOfPrimitives(Graphic3d_TOPA_TRIANGLESTRIPS,maxVertexs,maxStrips,0,hasVNormals,hasVColors,hasSColors,hasVTexels,Standard_False) {}
+Graphic3d_ArrayOfTriangleStrips::Graphic3d_ArrayOfTriangleStrips (const Standard_Integer theMaxVertexs,
+                                                                  const Standard_Integer theMaxStrips,
+                                                                  const Standard_Boolean theHasVNormals,
+                                                                  const Standard_Boolean theHasVColors,
+                                                                  const Standard_Boolean theHasSColors,
+                                                                  const Standard_Boolean theHasVTexels)
+: Graphic3d_ArrayOfPrimitives (Graphic3d_TOPA_TRIANGLESTRIPS, theMaxVertexs, theMaxStrips, 0, theHasVNormals, theHasVColors, theHasSColors, theHasVTexels)
+{}
index 1306df4..fc78e9d 100644 (file)
@@ -22,8 +22,7 @@ is
                maxEdges: Integer from Standard = 0;
                 hasVNormals: Boolean from Standard = Standard_False;
                 hasVColors: Boolean from Standard = Standard_False;
-                hasTexels: Boolean from Standard = Standard_False;
-                hasEdgeInfos: Boolean from Standard = Standard_False)
+                hasTexels: Boolean from Standard = Standard_False)
        returns mutable ArrayOfTriangles from Graphic3d;
         ---Purpose: Creates an array of triangles,
         -- a triangle can be filled as:
@@ -60,9 +59,6 @@ is
         -- When <hasTexels> is TRUE , you must use one of
         --      AddVertex(Point,Texel)
         --  or  AddVertex(Point,Normal,Texel) methods.
-        -- When <hasEdgeInfos> is TRUE , <maxEdges> must be > 0 and
-        --      you must use the
-        --      AddEdge(number,visibillity) method.
         --  Warning:
         -- the user is responsible about the orientation of the triangle
         -- depending of the order of the created vertex or edges and this
index 5ac5daf..7446b28 100644 (file)
 
 #include <Graphic3d_ArrayOfTriangles.ixx>
 
-Graphic3d_ArrayOfTriangles :: Graphic3d_ArrayOfTriangles (
-                        const Standard_Integer maxVertexs,
-                        const Standard_Integer maxEdges,
-                        const Standard_Boolean hasVNormals,
-                        const Standard_Boolean hasVColors,
-                        const Standard_Boolean hasVTexels,
-                       const Standard_Boolean hasEdgeInfos)
-       : Graphic3d_ArrayOfPrimitives(Graphic3d_TOPA_TRIANGLES,maxVertexs,0,maxEdges,hasVNormals,hasVColors,Standard_False,hasVTexels,hasEdgeInfos) {}
+Graphic3d_ArrayOfTriangles::Graphic3d_ArrayOfTriangles (const Standard_Integer theMaxVertexs,
+                                                        const Standard_Integer theMaxEdges,
+                                                        const Standard_Boolean theHasVNormals,
+                                                        const Standard_Boolean theHasVColors,
+                                                        const Standard_Boolean theHasVTexels)
+: Graphic3d_ArrayOfPrimitives (Graphic3d_TOPA_TRIANGLES, theMaxVertexs, 0, theMaxEdges, theHasVNormals, theHasVColors, Standard_False, theHasVTexels)
+{}
diff --git a/src/Graphic3d/Graphic3d_BoundBuffer.hxx b/src/Graphic3d/Graphic3d_BoundBuffer.hxx
new file mode 100644 (file)
index 0000000..7c93703
--- /dev/null
@@ -0,0 +1,70 @@
+// Copyright (c) 2014 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#ifndef _Graphic3d_BoundBuffer_HeaderFile
+#define _Graphic3d_BoundBuffer_HeaderFile
+
+#include <Graphic3d_Buffer.hxx>
+
+//! Bounds buffer.
+class Graphic3d_BoundBuffer : public NCollection_Buffer
+{
+public:
+
+  //! Empty constructor.
+  Graphic3d_BoundBuffer (const Handle(NCollection_BaseAllocator)& theAlloc)
+  : NCollection_Buffer (theAlloc),
+    Colors   (NULL),
+    Bounds   (NULL),
+    NbBounds (0) {}
+
+  //! Allocates new empty array
+  bool Init (const Standard_Integer theNbBounds,
+             const Standard_Boolean theHasColors)
+  {
+    Colors   = NULL;
+    Bounds   = NULL;
+    NbBounds = 0;
+    Free();
+    if (theNbBounds < 1)
+    {
+      return false;
+    }
+
+    const size_t aBoundsSize = sizeof(Standard_Integer) * theNbBounds;
+    const size_t aColorsSize = theHasColors
+                             ? sizeof(Graphic3d_Vec4) * theNbBounds
+                             : 0;
+    if (!Allocate (aColorsSize + aBoundsSize))
+    {
+      Free();
+      return false;
+    }
+
+    NbBounds = theNbBounds;
+    Colors   = theHasColors ? reinterpret_cast<Graphic3d_Vec4* >(myData) : NULL;
+    Bounds   = reinterpret_cast<Standard_Integer* >(theHasColors ? (myData + aColorsSize) : myData);
+    return true;
+  }
+
+public:
+
+  Graphic3d_Vec4*   Colors;   //!< pointer to facet color values
+  Standard_Integer* Bounds;   //!< pointer to bounds array
+  Standard_Integer  NbBounds; //!< number of bounds
+
+};
+
+typedef NCollection_Handle<Graphic3d_BoundBuffer> Handle(Graphic3d_BoundBuffer);
+
+#endif // _Graphic3d_BoundBuffer_HeaderFile
@@ -1,4 +1,4 @@
-// Copyright (c) 1999-2014 OPEN CASCADE SAS
+// Copyright (c) 2014 OPEN CASCADE SAS
 //
 // This file is part of Open CASCADE Technology software library.
 //
 // Alternatively, this file may be used under the terms of Open CASCADE
 // commercial license or contractual agreement.
 
-/*
-       File Graphic3d_PrimitiveArray.hxx
-       Created 16/06/2000 : ATS : G005 : This structure is an enumeration of all internal structures for PARRAY primitives
-*/
-#ifndef _Graphic3d_PrimitiveArray_HeaderFile
-#define _Graphic3d_PrimitiveArray_HeaderFile
+#ifndef _Graphic3d_BoundBuffer_Handle_HeaderFile
+#define _Graphic3d_BoundBuffer_Handle_HeaderFile
 
-#include <InterfaceGraphic_PrimitiveArray.hxx>
-typedef CALL_DEF_PARRAY *Graphic3d_PrimitiveArray;
+#include <Graphic3d_BoundBuffer.hxx>
+typedef Handle(Graphic3d_BoundBuffer) Graphic3d_BoundBuffer_Handle;
 
-#endif /* _Graphic3d_PrimitiveArray_HeaderFile */
+#endif // _Graphic3d_BoundBuffer_Handle_HeaderFile
diff --git a/src/Graphic3d/Graphic3d_Buffer.hxx b/src/Graphic3d/Graphic3d_Buffer.hxx
new file mode 100644 (file)
index 0000000..d16efe6
--- /dev/null
@@ -0,0 +1,208 @@
+// Copyright (c) 2014 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#ifndef _Graphic3d_Buffer_HeaderFile
+#define _Graphic3d_Buffer_HeaderFile
+
+#include <Graphic3d_Vec.hxx>
+#include <NCollection_Buffer.hxx>
+
+//! Type of attribute in Vertex Buffer
+enum Graphic3d_TypeOfAttribute
+{
+  Graphic3d_TOA_POS   =  0,   //!< vertex position
+  Graphic3d_TOA_NORM,         //!< normal
+  Graphic3d_TOA_UV,           //!< texture coordinates
+  Graphic3d_TOA_COLOR,        //!< per-vertex color
+  Graphic3d_TOA_CUSTOM = 10,  //!< custom attributes
+};
+
+//! Type of the element in Vertex or Index Buffer
+enum Graphic3d_TypeOfData
+{
+  Graphic3d_TOD_USHORT,  //!< unsigned 16-bit integer
+  Graphic3d_TOD_UINT,    //!< unsigned 32-bit integer
+  Graphic3d_TOD_VEC2,    //!< 2-components float vector
+  Graphic3d_TOD_VEC3,    //!< 3-components float vector
+  Graphic3d_TOD_VEC4,    //!< 4-components float vector
+  Graphic3d_TOD_VEC4UB,  //!< 4-components unsigned byte vector
+};
+
+//! Vertex attribute definition.
+struct Graphic3d_Attribute
+{
+  Graphic3d_TypeOfAttribute Id;       //!< attribute identifier in vertex shader, 0 is reserved for vertex position
+  Graphic3d_TypeOfData      DataType; //!< vec2,vec3,vec4,vec4ub
+
+  Standard_Integer Stride() const { return Stride (DataType); }
+
+  //! @return size of attribute of specified data type
+  static Standard_Integer Stride (const Graphic3d_TypeOfData theType)
+  {
+    switch (theType)
+    {
+      case Graphic3d_TOD_USHORT: return sizeof(unsigned short);
+      case Graphic3d_TOD_UINT:   return sizeof(unsigned int);
+      case Graphic3d_TOD_VEC2:   return sizeof(Graphic3d_Vec2);
+      case Graphic3d_TOD_VEC3:   return sizeof(Graphic3d_Vec3);
+      case Graphic3d_TOD_VEC4:   return sizeof(Graphic3d_Vec4);
+      case Graphic3d_TOD_VEC4UB: return sizeof(Graphic3d_Vec4ub);
+    }
+    return 0;
+  }
+
+};
+
+//! Buffer of vertex attributes.
+class Graphic3d_Buffer : public NCollection_Buffer
+{
+public:
+
+  //! Empty constructor.
+  Graphic3d_Buffer (const Handle(NCollection_BaseAllocator)& theAlloc)
+  : NCollection_Buffer (theAlloc),
+    Stride       (0),
+    NbElements   (0),
+    NbAttributes (0)
+  {
+    //
+  }
+
+  //! @return array of attributes definitions
+  const Graphic3d_Attribute* AttributesArray() const
+  {
+    return (Graphic3d_Attribute* )(myData + mySize);
+  }
+
+  //! @return attribute definition
+  const Graphic3d_Attribute& Attribute (const Standard_Integer theAttribIndex) const
+  {
+    return AttributesArray()[theAttribIndex];
+  }
+
+  //! @return attribute definition
+  Graphic3d_Attribute& ChangeAttribute (const Standard_Integer theAttribIndex)
+  {
+    return *((Graphic3d_Attribute* )(myData + mySize) + theAttribIndex);
+  }
+
+  //! @return data offset to specified attribute
+  Standard_Integer AttributeOffset (const Standard_Integer theAttribIndex) const
+  {
+    Standard_Integer anOffset = 0;
+    for (Standard_Integer anAttribIter = 0; anAttribIter < theAttribIndex; ++anAttribIter)
+    {
+      anOffset += Graphic3d_Attribute::Stride (Attribute (anAttribIter).DataType);
+    }
+    return anOffset;
+  }
+
+  using NCollection_Buffer::Data;
+  using NCollection_Buffer::ChangeData;
+
+  //! @return data for specified attribute
+  const Standard_Byte* Data (const Standard_Integer theAttribIndex) const
+  {
+    return myData + AttributeOffset (theAttribIndex);
+  }
+
+  //! @return data for specified attribute
+  Standard_Byte* ChangeData (const Standard_Integer theAttribIndex)
+  {
+    return myData + AttributeOffset (theAttribIndex);
+  }
+
+  //! Access specified element.
+  inline const Standard_Byte* value (const Standard_Integer theElem) const
+  {
+    return myData + Stride * size_t(theElem);
+  }
+
+  //! Access specified element.
+  inline Standard_Byte* changeValue (const Standard_Integer theElem)
+  {
+    return myData + Stride * size_t(theElem);
+  }
+
+  //! Access element with specified position and type.
+  template <typename Type_t>
+  inline const Type_t& Value (const Standard_Integer theElem) const
+  {
+    return *reinterpret_cast<const Type_t*>(value (theElem));
+  }
+
+  //! Access element with specified position and type.
+  template <typename Type_t>
+  inline Type_t& ChangeValue (const Standard_Integer theElem)
+  {
+    return *reinterpret_cast<Type_t* >(changeValue (theElem));
+  }
+
+  //! Release buffer.
+  void release()
+  {
+    Free();
+    Stride       = 0;
+    NbElements   = 0;
+    NbAttributes = 0;
+  }
+
+  //! Allocates new empty array
+  bool Init (const Standard_Integer     theNbElems,
+             const Graphic3d_Attribute* theAttribs,
+             const Standard_Integer     theNbAttribs)
+  {
+    release();
+    Standard_Integer aStride = 0;
+    for (Standard_Integer anAttribIter = 0; anAttribIter < theNbAttribs; ++anAttribIter)
+    {
+      const Graphic3d_Attribute& anAttrib = theAttribs[anAttribIter];
+      aStride += anAttrib.Stride();
+    }
+    if (aStride == 0)
+    {
+      return false;
+    }
+
+    Stride       = aStride;
+    NbElements   = theNbElems;
+    NbAttributes = theNbAttribs;
+    if (NbElements != 0)
+    {
+      const size_t aDataSize = size_t(Stride) * size_t(NbElements);
+      if (!Allocate (aDataSize + sizeof(Graphic3d_Attribute) * NbAttributes))
+      {
+        release();
+        return false;
+      }
+
+      mySize = aDataSize;
+      for (Standard_Integer anAttribIter = 0; anAttribIter < theNbAttribs; ++anAttribIter)
+      {
+        ChangeAttribute (anAttribIter) = theAttribs[anAttribIter];
+      }
+    }
+    return true;
+  }
+
+public:
+
+  Standard_Integer Stride;       //!< the distance to the attributes of the next vertex
+  Standard_Integer NbElements;   //!< number of the elements
+  Standard_Integer NbAttributes; //!< number of vertex attributes
+
+};
+
+typedef NCollection_Handle<Graphic3d_Buffer> Handle(Graphic3d_Buffer);
+
+#endif // _Graphic3d_Buffer_HeaderFile
similarity index 57%
copy from src/Graphic3d/Graphic3d_PrimitiveArray.hxx
copy to src/Graphic3d/Graphic3d_Buffer_Handle.hxx
index 50fe074..9e8173e 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (c) 1999-2014 OPEN CASCADE SAS
+// Copyright (c) 2014 OPEN CASCADE SAS
 //
 // This file is part of Open CASCADE Technology software library.
 //
 // Alternatively, this file may be used under the terms of Open CASCADE
 // commercial license or contractual agreement.
 
-/*
-       File Graphic3d_PrimitiveArray.hxx
-       Created 16/06/2000 : ATS : G005 : This structure is an enumeration of all internal structures for PARRAY primitives
-*/
-#ifndef _Graphic3d_PrimitiveArray_HeaderFile
-#define _Graphic3d_PrimitiveArray_HeaderFile
+#ifndef _Graphic3d_Buffer_Handle_HeaderFile
+#define _Graphic3d_Buffer_Handle_HeaderFile
 
-#include <InterfaceGraphic_PrimitiveArray.hxx>
-typedef CALL_DEF_PARRAY *Graphic3d_PrimitiveArray;
+#include <Graphic3d_Buffer.hxx>
+typedef Handle(Graphic3d_Buffer) Graphic3d_Buffer_Handle;
 
-#endif /* _Graphic3d_PrimitiveArray_HeaderFile */
+#endif // _Graphic3d_Buffer_Handle_HeaderFile
index acdcb19..5794670 100644 (file)
@@ -79,7 +79,6 @@ uses
     Array2OfVertex      from Graphic3d,
     Vertex              from Graphic3d,
     VerticalTextAlignment   from Graphic3d,
-    PrimitiveArray      from Graphic3d,
     PtrFrameBuffer      from Graphic3d,
     HArray1OfByte       from TColStd,
     FillMethod          from Aspect,
index 89af47c..4590b5c 100644 (file)
@@ -83,9 +83,12 @@ deferred class Group from Graphic3d inherits TShared
         Array1OfVertex              from Graphic3d,
         Array2OfVertex              from Graphic3d,
         Vertex                      from Graphic3d,
-        VerticalTextAlignment       from Graphic3d, 
+        VerticalTextAlignment       from Graphic3d,
         ArrayOfPrimitives           from Graphic3d,
-        ListOfPArray                from Graphic3d,
+        TypeOfPrimitiveArray        from Graphic3d,
+        IndexBuffer_Handle          from Graphic3d,
+        Buffer_Handle               from Graphic3d,
+        BoundBuffer_Handle          from Graphic3d,
         TransModeFlags              from Graphic3d,
         CBounds                     from Graphic3d,
         Ax2                         from gp
@@ -365,9 +368,18 @@ deferred class Group from Graphic3d inherits TShared
         ---Category: Methods to create Triangle
         ---------------------------------------
 
+    AddPrimitiveArray (me              : mutable;
+                       theType         : TypeOfPrimitiveArray from Graphic3d;
+                       theIndices      : IndexBuffer_Handle   from Graphic3d;
+                       theAttribs      : Buffer_Handle        from Graphic3d;
+                       theBounds       : BoundBuffer_Handle   from Graphic3d;
+                       theToEvalMinMax : Boolean from Standard = Standard_True) is virtual;
+    ---Level: Public
+    ---Purpose: Adds an array of primitives for display
+
     AddPrimitiveArray( me      : mutable;
                        thePrim : ArrayOfPrimitives from Graphic3d;
-                       theToEvalMinMax : Boolean from Standard = Standard_True ) is virtual;
+                       theToEvalMinMax : Boolean from Standard = Standard_True );
     ---Level: Public
     ---Purpose: Adds an array of primitives for display
 
@@ -523,9 +535,6 @@ deferred class Group from Graphic3d inherits TShared
   ContextMarker   : CAspectMarker   from Graphic3d is protected;
   ContextText     : CAspectText     from Graphic3d is protected;
 
-  -- temporary field - to be removed
-  myListOfPArray : ListOfPArray from Graphic3d is protected;
-
 friends
 
   class Structure from Graphic3d
index 80757e2..24879de 100644 (file)
@@ -988,30 +988,79 @@ void Graphic3d_Group::AddPrimitiveArray (const Handle(Graphic3d_ArrayOfPrimitive
     return;
   }
 
+  AddPrimitiveArray (thePrim->Type(), thePrim->Indices(), thePrim->Attributes(), thePrim->Bounds(), theToEvalMinMax);
+}
+
+// =======================================================================
+// function : AddPrimitiveArray
+// purpose  :
+// =======================================================================
+void Graphic3d_Group::AddPrimitiveArray (const Graphic3d_TypeOfPrimitiveArray theType,
+                                         const Handle(Graphic3d_IndexBuffer)& ,
+                                         const Handle(Graphic3d_Buffer)&      theAttribs,
+                                         const Handle(Graphic3d_BoundBuffer)& ,
+                                         const Standard_Boolean               theToEvalMinMax)
+{
+  if (IsDeleted()
+   || theAttribs.IsNull())
+  {
+    return;
+  }
+
   if (!MyContainsFacet
-    && thePrim->Type() != Graphic3d_TOPA_POLYLINES
-    && thePrim->Type() != Graphic3d_TOPA_SEGMENTS
-    && thePrim->Type() != Graphic3d_TOPA_POINTS)
+    && theType != Graphic3d_TOPA_POLYLINES
+    && theType != Graphic3d_TOPA_SEGMENTS
+    && theType != Graphic3d_TOPA_POINTS)
   {
     myStructure->GroupsWithFacet (1);
     MyContainsFacet = Standard_True;
   }
 
   MyIsEmpty = Standard_False;
-  myListOfPArray.Append (thePrim);
   if (theToEvalMinMax)
   {
-    Standard_Real x, y, z;
-    const Standard_Integer aNbVerts = thePrim->VertexNumber();
-    for (Standard_Integer aVertIter = 1; aVertIter <= aNbVerts; ++aVertIter)
+    const Standard_Integer aNbVerts = theAttribs->NbElements;
+    for (Standard_Integer anAttribIter = 0; anAttribIter < theAttribs->NbAttributes; ++anAttribIter)
     {
-      thePrim->Vertice (aVertIter, x, y, z);
-      if (x < myBounds.XMin) myBounds.XMin = Standard_ShortReal (x);
-      if (y < myBounds.YMin) myBounds.YMin = Standard_ShortReal (y);
-      if (z < myBounds.ZMin) myBounds.ZMin = Standard_ShortReal (z);
-      if (x > myBounds.XMax) myBounds.XMax = Standard_ShortReal (x);
-      if (y > myBounds.YMax) myBounds.YMax = Standard_ShortReal (y);
-      if (z > myBounds.ZMax) myBounds.ZMax = Standard_ShortReal (z);
+      const Graphic3d_Attribute& anAttrib = theAttribs->Attribute (anAttribIter);
+      if (anAttrib.Id != Graphic3d_TOA_POS)
+      {
+        continue;
+      }
+
+      const size_t anOffset = theAttribs->AttributeOffset (anAttribIter);
+      switch (anAttrib.DataType)
+      {
+        case Graphic3d_TOD_VEC2:
+        {
+          for (Standard_Integer aVertIter = 0; aVertIter < aNbVerts; ++aVertIter)
+          {
+            const Graphic3d_Vec2& aVert = *reinterpret_cast<const Graphic3d_Vec2* >(theAttribs->value (aVertIter) + anOffset);
+            if (aVert.x() < myBounds.XMin) myBounds.XMin = aVert.x();
+            if (aVert.y() < myBounds.YMin) myBounds.YMin = aVert.y();
+            if (aVert.x() > myBounds.XMax) myBounds.XMax = aVert.x();
+            if (aVert.y() > myBounds.YMax) myBounds.YMax = aVert.y();
+          }
+          break;
+        }
+        case Graphic3d_TOD_VEC3:
+        case Graphic3d_TOD_VEC4:
+        {
+          for (Standard_Integer aVertIter = 0; aVertIter < aNbVerts; ++aVertIter)
+          {
+            const Graphic3d_Vec3& aVert = *reinterpret_cast<const Graphic3d_Vec3* >(theAttribs->value (aVertIter) + anOffset);
+            if (aVert.x() < myBounds.XMin) myBounds.XMin = aVert.x();
+            if (aVert.y() < myBounds.YMin) myBounds.YMin = aVert.y();
+            if (aVert.z() < myBounds.ZMin) myBounds.ZMin = aVert.z();
+            if (aVert.x() > myBounds.XMax) myBounds.XMax = aVert.x();
+            if (aVert.y() > myBounds.YMax) myBounds.YMax = aVert.y();
+            if (aVert.z() > myBounds.ZMax) myBounds.ZMax = aVert.z();
+          }
+          break;
+        }
+        default: break;
+      }
+      break;
     }
   }
 
diff --git a/src/Graphic3d/Graphic3d_IndexBuffer.hxx b/src/Graphic3d/Graphic3d_IndexBuffer.hxx
new file mode 100644 (file)
index 0000000..ec69dfc
--- /dev/null
@@ -0,0 +1,77 @@
+// Copyright (c) 2014 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#ifndef _Graphic3d_IndexBuffer_HeaderFile
+#define _Graphic3d_IndexBuffer_HeaderFile
+
+#include <Graphic3d_Buffer.hxx>
+
+//! Index buffer.
+class Graphic3d_IndexBuffer : public Graphic3d_Buffer
+{
+public:
+
+  //! Empty constructor.
+  Graphic3d_IndexBuffer (const Handle(NCollection_BaseAllocator)& theAlloc)
+  : Graphic3d_Buffer (theAlloc) {}
+
+  //! Allocates new empty index array
+  template<typename IndexType_t>
+  bool Init (const Standard_Integer theNbElems)
+  {
+    release();
+    Stride = sizeof(IndexType_t);
+    if (Stride != sizeof(unsigned short)
+     && Stride != sizeof(unsigned int))
+    {
+      return false;
+    }
+
+    NbElements   = theNbElems;
+    NbAttributes = 0;
+    if (NbElements != 0
+    && !Allocate (size_t(Stride) * size_t(NbElements)))
+    {
+      release();
+      return false;
+    }
+    return true;
+  }
+
+  //! Access index at specified position
+  Standard_Integer Index (const Standard_Integer theIndex) const
+  {
+    return Stride == sizeof(unsigned short)
+         ? Standard_Integer(Value<unsigned short> (theIndex))
+         : Standard_Integer(Value<unsigned int>   (theIndex));
+  }
+
+  //! Change index at specified position
+  void SetIndex (const Standard_Integer theIndex,
+                 const Standard_Integer theValue)
+  {
+    if (Stride == sizeof(unsigned short))
+    {
+      ChangeValue<unsigned short> (theIndex) = (unsigned short )theValue;
+    }
+    else
+    {
+      ChangeValue<unsigned int>   (theIndex) = (unsigned int   )theValue;
+    }
+  }
+
+};
+
+typedef NCollection_Handle<Graphic3d_IndexBuffer> Handle(Graphic3d_IndexBuffer);
+
+#endif // _Graphic3d_IndexBuffer_HeaderFile
similarity index 57%
rename from src/Graphic3d/Graphic3d_PrimitiveArray.hxx
rename to src/Graphic3d/Graphic3d_IndexBuffer_Handle.hxx
index 50fe074..1d6db7f 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (c) 1999-2014 OPEN CASCADE SAS
+// Copyright (c) 2014 OPEN CASCADE SAS
 //
 // This file is part of Open CASCADE Technology software library.
 //
 // Alternatively, this file may be used under the terms of Open CASCADE
 // commercial license or contractual agreement.
 
-/*
-       File Graphic3d_PrimitiveArray.hxx
-       Created 16/06/2000 : ATS : G005 : This structure is an enumeration of all internal structures for PARRAY primitives
-*/
-#ifndef _Graphic3d_PrimitiveArray_HeaderFile
-#define _Graphic3d_PrimitiveArray_HeaderFile
+#ifndef _Graphic3d_IndexBuffer_Handle_HeaderFile
+#define _Graphic3d_IndexBuffer_Handle_HeaderFile
 
-#include <InterfaceGraphic_PrimitiveArray.hxx>
-typedef CALL_DEF_PARRAY *Graphic3d_PrimitiveArray;
+#include <Graphic3d_IndexBuffer.hxx>
+typedef Handle(Graphic3d_IndexBuffer) Graphic3d_IndexBuffer_Handle;
 
-#endif /* _Graphic3d_PrimitiveArray_HeaderFile */
+#endif // _Graphic3d_IndexBuffer_Handle_HeaderFile
index cdd779c..d398999 100755 (executable)
@@ -9,6 +9,5 @@ InterfaceGraphic_XWD.hxx
 InterfaceGraphic_wntio.hxx
 InterfaceGraphic_cPrintf.cxx
 InterfaceGraphic_Palette.c
-InterfaceGraphic_PrimitiveArray.hxx
 InterfaceGraphic_telem.hxx
 InterfaceGraphic_tgl_all.hxx
index 324a537..525e082 100644 (file)
@@ -15,7 +15,7 @@
 #ifndef InterfaceGraphic_Graphic3dHeader
 #define InterfaceGraphic_Graphic3dHeader
 
-#include <InterfaceGraphic_PrimitiveArray.hxx>
+#include <InterfaceGraphic_telem.hxx>
 #include <Standard_Transient.hxx>
 
 /* COULEUR */
diff --git a/src/InterfaceGraphic/InterfaceGraphic_PrimitiveArray.hxx b/src/InterfaceGraphic/InterfaceGraphic_PrimitiveArray.hxx
deleted file mode 100644 (file)
index cbf7b5a..0000000
+++ /dev/null
@@ -1,65 +0,0 @@
-// Copyright (c) 1991-1999 Matra Datavision
-// Copyright (c) 1999-2014 OPEN CASCADE SAS
-//
-// This file is part of Open CASCADE Technology software library.
-//
-// This library is free software; you can redistribute it and/or modify it under
-// the terms of the GNU Lesser General Public License version 2.1 as published
-// by the Free Software Foundation, with special exception defined in the file
-// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
-// distribution for complete text of the license and disclaimer of any warranty.
-//
-// Alternatively, this file may be used under the terms of Open CASCADE
-// commercial license or contractual agreement.
-
-#ifndef _InterfaceGraphic_PrimitiveArray_header_file_
-#define _InterfaceGraphic_PrimitiveArray_header_file_
-
-/*
-FILE: InterfaceGraphic_PrimitiveArray.hxx
-
-Created 16/06/2000 : ATS,SPK : G005
-
-This file contains definitios of internal structures for 
-PARRAY and DARRAY primitives, used in OpenGl package for presentation
-
-*/
-
-#include <InterfaceGraphic_telem.hxx>
-
-#define MVERTICE 1
-#define MVNORMAL 2
-#define MVCOLOR 4
-#define MVTEXEL 8
-
-typedef enum {
-  TelUnknownArrayType,
-  TelPointsArrayType,
-  TelPolylinesArrayType,
-  TelSegmentsArrayType,
-  TelPolygonsArrayType,
-  TelTrianglesArrayType,
-  TelQuadranglesArrayType,
-  TelTriangleStripsArrayType,
-  TelQuadrangleStripsArrayType,
-  TelTriangleFansArrayType
-} TelPrimitivesArrayType;
-
-typedef struct {
-  TelPrimitivesArrayType type;                    /* Array type */
-  Tint                   format;                  /* Array datas format */
-  Tint                   num_vertexs;             /* Number of vertexs */
-  Tint                   num_bounds;              /* Number of bounds */
-  Tint                   num_edges;               /* Number of edges */
-  Tint                  *bounds;                  /* Bounds array */
-  Tint                  *edges;                   /* Edges array vertex index */
-  tel_colour             fcolours;                /* Facet colour values */
-  tel_point              vertices;                /* Vertices */
-  Tint                  *vcolours;                /* Vertex colour values */
-  tel_point              vnormals;                /* Vertex normals */
-  tel_texture_coord      vtexels;                 /* Texture Coordinates */
-  Tchar                 *edge_vis;                /* Edge visibility flag*/
-  Tchar                 *keys;                    /* Vertex keys*/
-} CALL_DEF_PARRAY;
-
-#endif /* _InterfaceGraphic_PrimitiveArray_header_file_ */
index e110ed4..1758217 100644 (file)
@@ -29,7 +29,7 @@ class NCollection_Vec4
 public:
 
   //! Returns the number of components.
-  static size_t Length()
+  static int Length()
   {
     return 4;
   }
index 48fd812..927ef24 100755 (executable)
@@ -257,22 +257,8 @@ void OpenGl_CappingAlgo::Init()
 // =======================================================================
 Standard_Boolean OpenGl_CappingAlgoFilter::CanRender (const OpenGl_Element* theElement)
 {
-  const OpenGl_PrimitiveArray* aPArray =
-    dynamic_cast<const OpenGl_PrimitiveArray*> (theElement);
-  if (!aPArray)
-    return Standard_False;
-
-  switch (aPArray->PArray()->type)
-  {
-    case TelPolygonsArrayType :
-    case TelTrianglesArrayType :
-    case TelQuadranglesArrayType :
-    case TelTriangleStripsArrayType :
-    case TelQuadrangleStripsArrayType :
-    case TelTriangleFansArrayType :
-      return Standard_True;
-
-    default:
-      return Standard_False;
-  }
+  const OpenGl_PrimitiveArray* aPArray = dynamic_cast<const OpenGl_PrimitiveArray*> (theElement);
+  return aPArray != NULL
+      && aPArray->DrawMode() >= GL_TRIANGLES
+      && aPArray->DrawMode() <= GL_POLYGON;
 }
index 0c561e0..e8e012f 100644 (file)
 #include <gp_Ax2.hxx>
 #include <Graphic3d_CView.hxx>
 #include <Graphic3d_CStructure.hxx>
-#include <Graphic3d_TypeOfPrimitive.hxx>
 #include <Graphic3d_CPick.hxx>
 #include <Graphic3d_TextPath.hxx>
 #include <Graphic3d_HorizontalTextAlignment.hxx>
 #include <Graphic3d_VerticalTextAlignment.hxx>
-#include <Graphic3d_PrimitiveArray.hxx>
 #include <Graphic3d_CUserDraw.hxx>
 #include <Graphic3d_CGraduatedTrihedron.hxx>
 #include <Graphic3d_TypeOfComposition.hxx>
index 10af74d..6872137 100644 (file)
@@ -183,19 +183,22 @@ void OpenGl_Group::UpdateAspectText (const Standard_Boolean theIsGlobal)
 // function : AddPrimitiveArray
 // purpose  :
 // =======================================================================
-void OpenGl_Group::AddPrimitiveArray (const Handle(Graphic3d_ArrayOfPrimitives)& thePrim,
-                                      const Standard_Boolean                     theToEvalMinMax)
+void OpenGl_Group::AddPrimitiveArray (const Graphic3d_TypeOfPrimitiveArray theType,
+                                      const Handle(Graphic3d_IndexBuffer)& theIndices,
+                                      const Handle(Graphic3d_Buffer)&      theAttribs,
+                                      const Handle(Graphic3d_BoundBuffer)& theBounds,
+                                      const Standard_Boolean               theToEvalMinMax)
 {
   if (IsDeleted()
-  || !thePrim->IsValid())
+   || theAttribs.IsNull())
   {
     return;
   }
 
-  OpenGl_PrimitiveArray* anArray = new OpenGl_PrimitiveArray ((CALL_DEF_PARRAY *)thePrim->Array());
+  OpenGl_PrimitiveArray* anArray = new OpenGl_PrimitiveArray (theType, theIndices, theAttribs, theBounds);
   AddElement (anArray);
 
-  Graphic3d_Group::AddPrimitiveArray (thePrim, theToEvalMinMax);
+  Graphic3d_Group::AddPrimitiveArray (theType, theIndices, theAttribs, theBounds, theToEvalMinMax);
 }
 
 // =======================================================================
index bc942c4..07e0c70 100644 (file)
@@ -61,8 +61,11 @@ public:
   Standard_EXPORT virtual void UpdateAspectText   (const Standard_Boolean theIsGlobal);
 
   //! Add primitive array element
-  Standard_EXPORT virtual void AddPrimitiveArray (const Handle(Graphic3d_ArrayOfPrimitives)& thePrim,
-                                                  const Standard_Boolean                     theToEvalMinMax);
+  Standard_EXPORT virtual void AddPrimitiveArray (const Graphic3d_TypeOfPrimitiveArray theType,
+                                                  const Handle(Graphic3d_IndexBuffer)& theIndices,
+                                                  const Handle(Graphic3d_Buffer)&      theAttribs,
+                                                  const Handle(Graphic3d_BoundBuffer)& theBounds,
+                                                  const Standard_Boolean               theToEvalMinMax);
 
   //! Add text element
   Standard_EXPORT virtual void Text (const Standard_CString                  theTextUtf,
index b8bbcd5..bcb90ab 100755 (executable)
@@ -24,8 +24,6 @@
 #include <OpenGl_Structure.hxx>
 #include <OpenGl_Workspace.hxx>
 
-#include <InterfaceGraphic_PrimitiveArray.hxx>
-
 namespace
 {
   template<class T>
@@ -49,28 +47,157 @@ namespace
 
     aCtx->ShaderManager()->PushState (aProgram);
   }
+
+  //! Convert index data type from size
+  inline GLenum toGlIndexType (const Standard_Integer theStride)
+  {
+    switch (theStride)
+    {
+      case 2:  return GL_UNSIGNED_SHORT;
+      case 4:  return GL_UNSIGNED_INT;
+      default: return GL_NONE;
+    }
+  }
+
+  //! Convert data type to GL info
+  inline GLenum toGlDataType (const Graphic3d_TypeOfData theType,
+                              GLint&                     theNbComp)
+  {
+    switch (theType)
+    {
+      case Graphic3d_TOD_USHORT:
+        theNbComp = 1;
+        return GL_UNSIGNED_SHORT;
+      case Graphic3d_TOD_UINT:
+        theNbComp = 1;
+        return GL_UNSIGNED_INT;
+      case Graphic3d_TOD_VEC2:
+        theNbComp = 2;
+        return GL_FLOAT;
+      case Graphic3d_TOD_VEC3:
+        theNbComp = 3;
+        return GL_FLOAT;
+      case Graphic3d_TOD_VEC4:
+        theNbComp = 4;
+        return GL_FLOAT;
+      case Graphic3d_TOD_VEC4UB:
+        theNbComp = 4;
+        return GL_UNSIGNED_BYTE;
+    }
+    theNbComp = 0;
+    return GL_NONE;
+  }
+
 }
 
-// =======================================================================
-// function : clearMemoryOwn
-// purpose  :
-// =======================================================================
-void OpenGl_PrimitiveArray::clearMemoryOwn() const
+//! Auxiliary template for VBO with interleaved attributes.
+template<int NbAttributes>
+class OpenGl_VertexBufferT : public OpenGl_VertexBuffer
 {
-  Standard::Free (myPArray->edges);
-  Standard::Free (myPArray->vertices);
-  Standard::Free (myPArray->vcolours);
-  Standard::Free (myPArray->vnormals);
-  Standard::Free (myPArray->vtexels);
-  Standard::Free (myPArray->edge_vis); /// ???
-
-  myPArray->edges    = NULL;
-  myPArray->vertices = NULL;
-  myPArray->vcolours = NULL;
-  myPArray->vnormals = NULL;
-  myPArray->vtexels  = NULL;
-  myPArray->edge_vis = NULL;
-}
+
+public:
+
+  //! Create uninitialized VBO.
+  OpenGl_VertexBufferT (const Graphic3d_Attribute* theAttribs,
+                        const Standard_Integer     theStride)
+  : Stride (theStride)
+  {
+    memcpy (Attribs, theAttribs, sizeof(Graphic3d_Attribute) * NbAttributes);
+  }
+
+  //! Create uninitialized VBO.
+  OpenGl_VertexBufferT (const Graphic3d_Buffer& theAttribs)
+  : Stride (theAttribs.Stride)
+  {
+    memcpy (Attribs, theAttribs.AttributesArray(), sizeof(Graphic3d_Attribute) * NbAttributes);
+  }
+
+  virtual bool HasColorAttribute() const
+  {
+    for (Standard_Integer anAttribIter = 0; anAttribIter < NbAttributes; ++anAttribIter)
+    {
+      const Graphic3d_Attribute& anAttrib = Attribs[anAttribIter];
+      if (anAttrib.Id == Graphic3d_TOA_COLOR)
+      {
+        return true;
+      }
+    }
+    return false;
+  }
+
+  virtual void BindFixedPosition (const Handle(OpenGl_Context)& theGlCtx) const
+  {
+    if (!IsValid())
+    {
+      return;
+    }
+
+    Bind (theGlCtx);
+    GLint aNbComp;
+    const GLubyte* anOffset = NULL;
+    for (Standard_Integer anAttribIter = 0; anAttribIter < NbAttributes; ++anAttribIter)
+    {
+      const Graphic3d_Attribute& anAttrib = Attribs[anAttribIter];
+      const GLenum   aDataType = toGlDataType (anAttrib.DataType, aNbComp);
+      if (aDataType == GL_NONE)
+      {
+        continue;
+      }
+      else if (anAttrib.Id == Graphic3d_TOA_POS)
+      {
+        bindFixed (theGlCtx, Graphic3d_TOA_POS, aNbComp, aDataType, Stride, anOffset);
+        break;
+      }
+
+      anOffset += Graphic3d_Attribute::Stride (anAttrib.DataType);
+    }
+  }
+
+  virtual void BindFixed (const Handle(OpenGl_Context)& theGlCtx) const
+  {
+    if (!IsValid())
+    {
+      return;
+    }
+
+    Bind (theGlCtx);
+    GLint aNbComp;
+    const GLubyte* anOffset = NULL;
+    for (Standard_Integer anAttribIter = 0; anAttribIter < NbAttributes; ++anAttribIter)
+    {
+      const Graphic3d_Attribute& anAttrib = Attribs[anAttribIter];
+      const GLenum   aDataType = toGlDataType (anAttrib.DataType, aNbComp);
+      if (aDataType == GL_NONE)
+      {
+        continue;
+      }
+
+      bindFixed (theGlCtx, anAttrib.Id, aNbComp, aDataType, Stride, anOffset);
+      anOffset += Graphic3d_Attribute::Stride (anAttrib.DataType);
+    }
+  }
+
+  virtual void UnbindFixed (const Handle(OpenGl_Context)& theGlCtx) const
+  {
+    if (!IsValid())
+    {
+      return;
+    }
+    Unbind (theGlCtx);
+
+    for (Standard_Integer anAttribIter = 0; anAttribIter < NbAttributes; ++anAttribIter)
+    {
+      const Graphic3d_Attribute& anAttrib = Attribs[anAttribIter];
+      unbindFixed (theGlCtx, anAttrib.Id);
+    }
+  }
+
+public:
+
+  Graphic3d_Attribute Attribs[NbAttributes];
+  Standard_Integer    Stride;
+
+};
 
 // =======================================================================
 // function : clearMemoryGL
@@ -78,13 +205,15 @@ void OpenGl_PrimitiveArray::clearMemoryOwn() const
 // =======================================================================
 void OpenGl_PrimitiveArray::clearMemoryGL (const Handle(OpenGl_Context)& theGlCtx) const
 {
-  for (Standard_Integer anIter = 0; anIter < VBOMaxType; ++anIter)
+  if (!myVboIndices.IsNull())
   {
-    if (!myVbos[anIter].IsNull())
-    {
-      myVbos[anIter]->Release (theGlCtx.operator->());
-      myVbos[anIter].Nullify();
-    }
+    myVboIndices->Release (theGlCtx.operator->());
+    myVboIndices.Nullify();
+  }
+  if (!myVboAttribs.IsNull())
+  {
+    myVboAttribs->Release (theGlCtx.operator->());
+    myVboAttribs.Nullify();
   }
 }
 
@@ -95,50 +224,54 @@ void OpenGl_PrimitiveArray::clearMemoryGL (const Handle(OpenGl_Context)& theGlCt
 Standard_Boolean OpenGl_PrimitiveArray::BuildVBO (const Handle(OpenGl_Workspace)& theWorkspace) const
 {
   const Handle(OpenGl_Context)& aGlCtx = theWorkspace->GetGlContext();
-  if (myPArray->vertices == NULL)
+  if (myAttribs.IsNull()
+   || myAttribs->IsEmpty()
+   || myAttribs->NbElements < 1)
   {
     // vertices should be always defined - others are optional
     return Standard_False;
   }
-  myVbos[VBOVertices] = new OpenGl_VertexBuffer();
-  if (!myVbos[VBOVertices]->Init (aGlCtx, 3, myPArray->num_vertexs, &myPArray->vertices[0].xyz[0]))
-  {
-    clearMemoryGL (aGlCtx);
-    return Standard_False;
-  }
 
-  if (myPArray->edges != NULL
-   && myPArray->num_edges > 0)
+  switch (myAttribs->NbAttributes)
   {
-    myVbos[VBOEdges] = new OpenGl_IndexBuffer();
-    if (!myVbos[VBOEdges]->Init (aGlCtx, 1, myPArray->num_edges, (GLuint* )myPArray->edges))
-    {
-      clearMemoryGL (aGlCtx);
-      return Standard_False;
-    }
+    case 1:  myVboAttribs = new OpenGl_VertexBufferT<1> (*myAttribs); break;
+    case 2:  myVboAttribs = new OpenGl_VertexBufferT<2> (*myAttribs); break;
+    case 3:  myVboAttribs = new OpenGl_VertexBufferT<3> (*myAttribs); break;
+    case 4:  myVboAttribs = new OpenGl_VertexBufferT<4> (*myAttribs); break;
+    case 5:  myVboAttribs = new OpenGl_VertexBufferT<5> (*myAttribs); break;
+    case 6:  myVboAttribs = new OpenGl_VertexBufferT<6> (*myAttribs); break;
+    case 7:  myVboAttribs = new OpenGl_VertexBufferT<7> (*myAttribs); break;
+    case 8:  myVboAttribs = new OpenGl_VertexBufferT<8> (*myAttribs); break;
+    case 9:  myVboAttribs = new OpenGl_VertexBufferT<9> (*myAttribs); break;
+    case 10: myVboAttribs = new OpenGl_VertexBufferT<10>(*myAttribs); break;
+    default: return Standard_False;
   }
-  if (myPArray->vcolours != NULL)
+
+  if (!myVboAttribs->init (aGlCtx, 0, myAttribs->NbElements, myAttribs->Data(), GL_NONE, myAttribs->Stride))
   {
-    myVbos[VBOVcolours] = new OpenGl_VertexBuffer();
-    if (!myVbos[VBOVcolours]->Init (aGlCtx, 4, myPArray->num_vertexs, (GLubyte* )myPArray->vcolours))
-    {
-      clearMemoryGL (aGlCtx);
-      return Standard_False;
-    }
+    clearMemoryGL (aGlCtx);
+    return Standard_False;
   }
-  if (myPArray->vnormals != NULL)
+
+  if (!myIndices.IsNull())
   {
-    myVbos[VBOVnormals] = new OpenGl_VertexBuffer();
-    if (!myVbos[VBOVnormals]->Init (aGlCtx, 3, myPArray->num_vertexs, &myPArray->vnormals[0].xyz[0]))
+    myVboIndices = new OpenGl_IndexBuffer();
+    bool isOk = Standard_False;
+    switch (myIndices->Stride)
     {
-      clearMemoryGL (aGlCtx);
-      return Standard_False;
+      case 2:
+      {
+        isOk = myVboIndices->Init (aGlCtx, 1, myIndices->NbElements, reinterpret_cast<const GLushort*> (myIndices->Data()));
+        break;
+      }
+      case 4:
+      {
+        isOk = myVboIndices->Init (aGlCtx, 1, myIndices->NbElements, reinterpret_cast<const GLuint*> (myIndices->Data()));
+        break;
+      }
+      default: break;
     }
-  }
-  if (myPArray->vtexels)
-  {
-    myVbos[VBOVtexels] = new OpenGl_VertexBuffer();
-    if (!myVbos[VBOVtexels]->Init (aGlCtx, 2, myPArray->num_vertexs, &myPArray->vtexels[0].xy[0]))
+    if (!isOk)
     {
       clearMemoryGL (aGlCtx);
       return Standard_False;
@@ -147,7 +280,8 @@ Standard_Boolean OpenGl_PrimitiveArray::BuildVBO (const Handle(OpenGl_Workspace)
 
   if (!aGlCtx->caps->keepArrayData)
   {
-    clearMemoryOwn();
+    myIndices.Nullify();
+    myAttribs.Nullify();
   }
   
   return Standard_True;
@@ -163,49 +297,14 @@ void OpenGl_PrimitiveArray::DrawArray (Tint theLightingModel,
                                        const TEL_COLOUR* theInteriorColour,
                                        const TEL_COLOUR* theLineColour,
                                        const TEL_COLOUR* theEdgeColour,
-                                       const OPENGL_SURF_PROP* theFaceProp,
                                        const Handle(OpenGl_Workspace)& theWorkspace) const
 {
-  const Handle(OpenGl_Context)& aGlContext = theWorkspace->GetGlContext();
-
-  Tint i,n;
-  Tint transp = 0;
-  // Following pointers have been provided for performance improvement
-  tel_colour pfc = myPArray->fcolours;
-  Tint* pvc = myPArray->vcolours;
-  if (pvc != NULL)
-  {
-    for (i = 0; i < myPArray->num_vertexs; ++i)
-    {
-      transp = int(theFaceProp->trans * 255.0f);
-    #if defined (sparc) || defined (__sparc__) || defined (__sparc)
-      pvc[i] = (pvc[i] & 0xffffff00);
-      pvc[i] += transp;
-    #else
-      pvc[i] = (pvc[i] & 0x00ffffff);
-      pvc[i] += transp << 24;
-    #endif
-    }
-  }
+  const Handle(OpenGl_Context)& aGlContext  = theWorkspace->GetGlContext();
+  const Graphic3d_Vec4*         aFaceColors = myBounds.IsNull() ? NULL : myBounds->Colors;
+  const bool                    toHilight   = (theWorkspace->NamedStatus & OPENGL_NS_HIGHLIGHT) != 0;
+  bool                          hasVColors  = false;
 
-  switch (myPArray->type)
-  {
-    case TelPointsArrayType:
-    case TelPolylinesArrayType:
-    case TelSegmentsArrayType:
-      glColor3fv (theLineColour->rgb);
-      break;
-    case TelPolygonsArrayType:
-    case TelTrianglesArrayType:
-    case TelQuadranglesArrayType:
-    case TelTriangleStripsArrayType:
-    case TelQuadrangleStripsArrayType:
-    case TelTriangleFansArrayType:
-      glColor3fv (theInteriorColour->rgb);
-      break;
-    case TelUnknownArrayType:
-      break;
-  }
+  glColor3fv (myDrawMode <= GL_LINE_STRIP ? theLineColour->rgb : theInteriorColour->rgb);
 
   // Temporarily disable environment mapping
   if (myDrawMode <= GL_LINE_STRIP)
@@ -218,17 +317,15 @@ void OpenGl_PrimitiveArray::DrawArray (Tint theLightingModel,
   if ((myDrawMode >  GL_LINE_STRIP && theInteriorStyle != Aspect_IS_EMPTY) ||
       (myDrawMode <= GL_LINE_STRIP))
   {
-    if (theWorkspace->NamedStatus & OPENGL_NS_HIGHLIGHT)
+    if (toHilight)
     {
-      pfc = NULL;
-      pvc = NULL;
+      aFaceColors = NULL;
     }
 
     if (theInteriorStyle == Aspect_IS_HIDDENLINE)
     {
       theEdgeFlag = 1;
-      pfc = NULL;
-      pvc = NULL;
+      aFaceColors = NULL;
     }
 
     // Sometimes the GL_LIGHTING mode is activated here
@@ -239,86 +336,53 @@ void OpenGl_PrimitiveArray::DrawArray (Tint theLightingModel,
     else
       glEnable (GL_LIGHTING);
 
-    if (!toDrawVbo())
-    {
-      if (myPArray->vertices != NULL)
-      {
-        glVertexPointer (3, GL_FLOAT, 0, myPArray->vertices); // array of vertices
-        glEnableClientState (GL_VERTEX_ARRAY);
-      }
-      if (myPArray->vnormals != NULL)
-      {
-        glNormalPointer (GL_FLOAT, 0, myPArray->vnormals); // array of normals
-        glEnableClientState (GL_NORMAL_ARRAY);
-      }
-      if (myPArray->vtexels != NULL)
-      {
-        glTexCoordPointer (2, GL_FLOAT, 0, myPArray->vtexels); // array of texture coordinates
-        glEnableClientState (GL_TEXTURE_COORD_ARRAY);
-      }
-
-      if ((pvc != NULL) && (theWorkspace->NamedStatus & OPENGL_NS_HIGHLIGHT) == 0)
-      {
-        glColorPointer (4, GL_UNSIGNED_BYTE, 0, pvc);  // array of colors
-        glEnableClientState (GL_COLOR_ARRAY);
-        glColorMaterial (GL_FRONT_AND_BACK,GL_AMBIENT_AND_DIFFUSE);
-        glEnable (GL_COLOR_MATERIAL);
-      }
-    }
-    else
+    if (!myVboAttribs.IsNull())
     {
-      // Bindings concrete pointer in accordance with VBO buffer
-      myVbos[VBOVertices]->BindFixed (aGlContext, GL_VERTEX_ARRAY);
-      if (!myVbos[VBOVnormals].IsNull())
-      {
-        myVbos[VBOVnormals]->BindFixed (aGlContext, GL_NORMAL_ARRAY);
-      }
-      if (!myVbos[VBOVtexels].IsNull() && (theWorkspace->NamedStatus & OPENGL_NS_FORBIDSETTEX) == 0)
-      {
-        myVbos[VBOVtexels]->BindFixed (aGlContext, GL_TEXTURE_COORD_ARRAY);
-      }
-      if (!myVbos[VBOVcolours].IsNull() && (theWorkspace->NamedStatus & OPENGL_NS_HIGHLIGHT) == 0)
+      myVboAttribs->BindFixed (aGlContext);
+      if (myVboAttribs->HasColorAttribute())
       {
-        myVbos[VBOVcolours]->BindFixed (aGlContext, GL_COLOR_ARRAY);
-        glColorMaterial (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
-        glEnable (GL_COLOR_MATERIAL);
+        if (toHilight)
+        {
+          // disable per-vertex colors
+          OpenGl_VertexBuffer::unbindFixed (aGlContext, Graphic3d_TOA_COLOR);
+        }
+        else
+        {
+          hasVColors = true;
+        }
       }
-    }
-
-    /// OCC22236 NOTE: draw for all situations:
-    /// 1) draw elements from myPArray->bufferVBO[VBOEdges] indicies array
-    /// 2) draw elements from vertice array, when bounds defines count of primitive's verts.
-    /// 3) draw primitive by vertexes if no edges and bounds array is specified
-    if (toDrawVbo())
-    {
-      if (!myVbos[VBOEdges].IsNull())
+      if (!myVboIndices.IsNull())
       {
-        myVbos[VBOEdges]->Bind (aGlContext);
-        if (myPArray->num_bounds > 0)
+        myVboIndices->Bind (aGlContext);
+        if (!myBounds.IsNull())
         {
-          // draw primitives by vertex count with the indicies
-          Tint* anOffset = NULL;
-          for (i = 0; i < myPArray->num_bounds; ++i)
+          // draw primitives by vertex count with the indices
+          const size_t aStride  = myVboIndices->GetDataType() == GL_UNSIGNED_SHORT ? sizeof(unsigned short) : sizeof(unsigned int);
+          GLubyte*     anOffset = NULL;
+          for (Standard_Integer aGroupIter = 0; aGroupIter < myBounds->NbBounds; ++aGroupIter)
           {
-            if (pfc != NULL) glColor3fv (pfc[i].rgb);
-            glDrawElements (myDrawMode, myPArray->bounds[i], myVbos[VBOEdges]->GetDataType(), anOffset);
-            anOffset += myPArray->bounds[i];
+            const GLint aNbElemsInGroup = myBounds->Bounds[aGroupIter];
+            if (aFaceColors != NULL) glColor3fv (aFaceColors[aGroupIter].GetData());
+            glDrawElements (myDrawMode, aNbElemsInGroup, myVboIndices->GetDataType(), anOffset);
+            anOffset += aStride * aNbElemsInGroup;
           }
         }
         else
         {
-          // draw one (or sequential) primitive by the indicies
-          glDrawElements (myDrawMode, myPArray->num_edges, myVbos[VBOEdges]->GetDataType(), NULL);
+          // draw one (or sequential) primitive by the indices
+          glDrawElements (myDrawMode, myVboIndices->GetElemsNb(), myVboIndices->GetDataType(), NULL);
         }
-        myVbos[VBOEdges]->Unbind (aGlContext);
+        myVboIndices->Unbind (aGlContext);
       }
-      else if (myPArray->num_bounds > 0)
+      else if (!myBounds.IsNull())
       {
-        for (i = n = 0; i < myPArray->num_bounds; ++i)
+        GLint aFirstElem = 0;
+        for (Standard_Integer aGroupIter = 0; aGroupIter < myBounds->NbBounds; ++aGroupIter)
         {
-          if (pfc != NULL) glColor3fv (pfc[i].rgb);
-          glDrawArrays (myDrawMode, n, myPArray->bounds[i]);
-          n += myPArray->bounds[i];
+          const GLint aNbElemsInGroup = myBounds->Bounds[aGroupIter];
+          if (aFaceColors != NULL) glColor3fv (aFaceColors[aGroupIter].GetData());
+          glDrawArrays (myDrawMode, aFirstElem, aNbElemsInGroup);
+          aFirstElem += aNbElemsInGroup;
         }
       }
       else
@@ -329,53 +393,65 @@ void OpenGl_PrimitiveArray::DrawArray (Tint theLightingModel,
         }
         else
         {
-          glDrawArrays (myDrawMode, 0, myVbos[VBOVertices]->GetElemsNb());
+          glDrawArrays (myDrawMode, 0, myVboAttribs->GetElemsNb());
         }
       }
 
       // bind with 0
-      myVbos[VBOVertices]->UnbindFixed (aGlContext, GL_VERTEX_ARRAY);
-      if (!myVbos[VBOVnormals].IsNull())
-      {
-        myVbos[VBOVnormals]->UnbindFixed (aGlContext, GL_NORMAL_ARRAY);
-      }
-      if (!myVbos[VBOVtexels].IsNull() && (theWorkspace->NamedStatus & OPENGL_NS_FORBIDSETTEX) == 0)
-      {
-        myVbos[VBOVtexels]->UnbindFixed (aGlContext, GL_TEXTURE_COORD_ARRAY);
-      }
-      if (!myVbos[VBOVcolours].IsNull())
-      {
-        myVbos[VBOVcolours]->UnbindFixed (aGlContext, GL_COLOR_ARRAY);
-        glDisable (GL_COLOR_MATERIAL);
-        theWorkspace->NamedStatus |= OPENGL_NS_RESMAT; // Reset material
-      }
+      myVboAttribs->UnbindFixed (aGlContext);
     }
     else
     {
-      if (myPArray->num_bounds > 0)
+      GLint aNbComp;
+      for (Standard_Integer anAttribIter = 0; anAttribIter < myAttribs->NbAttributes; ++anAttribIter)
       {
-        if (myPArray->num_edges > 0)
+        const Graphic3d_Attribute& anAttrib = myAttribs->Attribute (anAttribIter);
+        if (anAttrib.Id == Graphic3d_TOA_COLOR)
         {
-          for (i = n = 0; i < myPArray->num_bounds; ++i)
+          if (toHilight)
           {
-            if (pfc != NULL) glColor3fv (pfc[i].rgb);
-            glDrawElements (myDrawMode, myPArray->bounds[i], GL_UNSIGNED_INT, (GLenum* )&myPArray->edges[n]);
-            n += myPArray->bounds[i];
+            continue;
+          }
+          hasVColors = true;
+        }
+        const GLenum  aDataType = toGlDataType (anAttrib.DataType, aNbComp);
+        const GLvoid* aData     = myAttribs->Data (anAttribIter);
+        if (aDataType == GL_NONE)
+        {
+          continue;
+        }
+
+        OpenGl_VertexBuffer::bindFixed (aGlContext, anAttrib.Id, aNbComp, aDataType, myAttribs->Stride, aData);
+      }
+
+      if (!myBounds.IsNull())
+      {
+        GLint aFirstElem = 0;
+        if (!myIndices.IsNull())
+        {
+          const GLenum anIndexType = toGlIndexType (myIndices->Stride);
+          for (Standard_Integer aGroupIter = 0; aGroupIter < myBounds->NbBounds; ++aGroupIter)
+          {
+            const GLint aNbElemsInGroup = myBounds->Bounds[aGroupIter];
+            if (aFaceColors != NULL) glColor3fv (aFaceColors[aGroupIter].GetData());
+            glDrawElements (myDrawMode, aNbElemsInGroup, anIndexType, myIndices->value (aFirstElem));
+            aFirstElem += aNbElemsInGroup;
           }
         }
         else
         {
-          for (i = n = 0; i < myPArray->num_bounds; ++i)
+          for (Standard_Integer aGroupIter = 0; aGroupIter < myBounds->NbBounds; ++aGroupIter)
           {
-            if (pfc != NULL) glColor3fv (pfc[i].rgb);
-            glDrawArrays (myDrawMode, n, myPArray->bounds[i]);
-            n += myPArray->bounds[i];
+            const GLint aNbElemsInGroup = myBounds->Bounds[aGroupIter];
+            if (aFaceColors != NULL) glColor3fv (aFaceColors[aGroupIter].GetData());
+            glDrawArrays (myDrawMode, aFirstElem, aNbElemsInGroup);
+            aFirstElem += aNbElemsInGroup;
           }
         }
       }
-      else if (myPArray->num_edges > 0)
+      else if (!myIndices.IsNull())
       {
-        glDrawElements (myDrawMode, myPArray->num_edges, GL_UNSIGNED_INT, (GLenum* )myPArray->edges);
+        glDrawElements (myDrawMode, myIndices->NbElements, toGlIndexType (myIndices->Stride), myIndices->Data());
       }
       else
       {
@@ -385,34 +461,23 @@ void OpenGl_PrimitiveArray::DrawArray (Tint theLightingModel,
         }
         else
         {
-          glDrawArrays (myDrawMode, 0, myPArray->num_vertexs);
+          glDrawArrays (myDrawMode, 0, myAttribs->NbElements);
         }
       }
 
-      if (pvc != NULL)
+      for (Standard_Integer anAttribIter = 0; anAttribIter < myAttribs->NbAttributes; ++anAttribIter)
       {
-        glDisable (GL_COLOR_MATERIAL);
-        theWorkspace->NamedStatus |= OPENGL_NS_RESMAT; // Reset material
+        const Graphic3d_Attribute& anAttrib = myAttribs->Attribute (anAttribIter);
+        OpenGl_VertexBuffer::unbindFixed (aGlContext, anAttrib.Id);
       }
-
-      glDisableClientState (GL_VERTEX_ARRAY);
-      if (myPArray->vcolours != NULL)
-        glDisableClientState (GL_COLOR_ARRAY);
-      if (myPArray->vnormals != NULL)
-        glDisableClientState (GL_NORMAL_ARRAY);
-      if (myPArray->vtexels != NULL)
-        glDisableClientState (GL_TEXTURE_COORD_ARRAY);
     }
   }
 
-  // On some NVIDIA graphic cards, using glEdgeFlagPointer() in
-  // combination with VBO (edge flag data put into a VBO buffer)
-  // leads to a crash in a driver. Therefore, edge flags are simply
-  // igonored when VBOs are enabled, so all the edges are drawn if
-  // edge visibility is turned on. In order to draw edges selectively,
-  // either disable VBO or turn off edge visibilty in the current
-  // primitive array and create a separate primitive array (segments)
-  // and put edges to be drawn into it.
+  if (hasVColors)
+  {
+    theWorkspace->NamedStatus |= OPENGL_NS_RESMAT;
+  }
+
   if (theEdgeFlag && myDrawMode > GL_LINE_STRIP)
   {
     DrawEdges (theEdgeColour, theWorkspace);
@@ -447,111 +512,102 @@ void OpenGl_PrimitiveArray::DrawEdges (const TEL_COLOUR*               theEdgeCo
     }
   }
 
-  Tint i, j, n;
-
   /// OCC22236 NOTE: draw edges for all situations:
-  /// 1) draw elements with GL_LINE style as edges from myPArray->bufferVBO[VBOEdges] indicies array
-  /// 2) draw elements from vertice array, when bounds defines count of primitive's verts.
+  /// 1) draw elements with GL_LINE style as edges from myPArray->bufferVBO[VBOEdges] indices array
+  /// 2) draw elements from vertex array, when bounds defines count of primitive's vertices.
   /// 3) draw primitive's edges by vertexes if no edges and bounds array is specified
-  if (toDrawVbo())
+  if (!myVboAttribs.IsNull())
   {
-    myVbos[VBOVertices]->BindFixed (aGlContext, GL_VERTEX_ARRAY);
+    myVboAttribs->BindFixedPosition (aGlContext);
     glColor3fv (theEdgeColour->rgb);
-    if (!myVbos[VBOEdges].IsNull())
+    if (!myVboIndices.IsNull())
     {
-      myVbos[VBOEdges]->Bind (aGlContext);
+      myVboIndices->Bind (aGlContext);
 
-      // draw primitives by vertex count with the indicies
-      if (myPArray->num_bounds > 0)
+      // draw primitives by vertex count with the indices
+      if (!myBounds.IsNull())
       {
-        Tint* offset = 0;
-        for (i = 0, offset = 0; i < myPArray->num_bounds; ++i)
+        const size_t aStride  = myVboIndices->GetDataType() == GL_UNSIGNED_SHORT ? sizeof(unsigned short) : sizeof(unsigned int);
+        GLubyte*     anOffset = NULL;
+        for (Standard_Integer aGroupIter = 0; aGroupIter < myBounds->NbBounds; ++aGroupIter)
         {
-          glDrawElements (myDrawMode, myPArray->bounds[i], myVbos[VBOEdges]->GetDataType(), offset);
-          offset += myPArray->bounds[i];
+          const GLint aNbElemsInGroup = myBounds->Bounds[aGroupIter];
+          glDrawElements (myDrawMode, aNbElemsInGroup, myVboIndices->GetDataType(), anOffset);
+          anOffset += aStride * aNbElemsInGroup;
         }
       }
-      // draw one (or sequential) primitive by the indicies
+      // draw one (or sequential) primitive by the indices
       else
       {
-        glDrawElements (myDrawMode, myVbos[VBOEdges]->GetElemsNb(), myVbos[VBOEdges]->GetDataType(), NULL);
+        glDrawElements (myDrawMode, myVboIndices->GetElemsNb(), myVboIndices->GetDataType(), NULL);
       }
-      myVbos[VBOEdges]->Unbind (aGlContext);
+      myVboIndices->Unbind (aGlContext);
     }
-    else if (myPArray->num_bounds > 0)
+    else if (!myBounds.IsNull())
     {
-      for (i = n = 0; i < myPArray->num_bounds; ++i)
+      GLint aFirstElem = 0;
+      for (Standard_Integer aGroupIter = 0; aGroupIter < myBounds->NbBounds; ++aGroupIter)
       {
-        glDrawArrays (myDrawMode, n, myPArray->bounds[i]);
-        n += myPArray->bounds[i];
+        const GLint aNbElemsInGroup = myBounds->Bounds[aGroupIter];
+        glDrawArrays (myDrawMode, aFirstElem, aNbElemsInGroup);
+        aFirstElem += aNbElemsInGroup;
       }
     }
     else
     {
-      glDrawArrays (myDrawMode, 0, myPArray->num_vertexs);
+      glDrawArrays (myDrawMode, 0, myAttribs->NbElements);
     }
 
     // unbind buffers
-    myVbos[VBOVertices]->UnbindFixed (aGlContext, GL_VERTEX_ARRAY);
+    myVboAttribs->UnbindFixed (aGlContext, GL_VERTEX_ARRAY);
   }
   else
   {
-    glEnableClientState (GL_VERTEX_ARRAY);
-    glVertexPointer (3, GL_FLOAT, 0, myPArray->vertices); // array of vertices
+    GLint aNbComp;
+    for (Standard_Integer anAttribIter = 0; anAttribIter < myAttribs->NbAttributes; ++anAttribIter)
+    {
+      const Graphic3d_Attribute& anAttrib = myAttribs->Attribute (anAttribIter);
+      if (anAttrib.Id == Graphic3d_TOA_POS)
+      {
+        const GLenum  aDataType = toGlDataType (anAttrib.DataType, aNbComp);
+        const GLvoid* aData     = myAttribs->Data (anAttribIter);
+        OpenGl_VertexBuffer::bindFixed (aGlContext, anAttrib.Id, aNbComp, aDataType, myAttribs->Stride, aData);
+        break;
+      }
+    }
 
     glColor3fv (theEdgeColour->rgb);
-    if (myPArray->num_bounds > 0)
+    if (!myBounds.IsNull())
     {
-      if (myPArray->num_edges > 0)
+      if (!myIndices.IsNull())
       {
-        for (i = n = 0; i < myPArray->num_bounds; ++i)
+        const GLenum anIndexType = toGlIndexType (myIndices->Stride);
+        GLint aFirstElem = 0;
+        for (Standard_Integer aGroupIter = 0; aGroupIter < myBounds->NbBounds; ++aGroupIter)
         {
-          if (myPArray->edge_vis)
-          {
-            glBegin (myDrawMode);
-            for (j = 0; j < myPArray->bounds[i]; ++j)
-            {
-              glEdgeFlag (myPArray->edge_vis[n+j]);
-              glVertex3fv (&myPArray->vertices[myPArray->edges[n+j]].xyz[0]);
-            }
-            glEnd();
-          }
-          else
-          {
-            glDrawElements (myDrawMode, myPArray->bounds[i], GL_UNSIGNED_INT, (GLenum* )&myPArray->edges[n]);
-          }
-          n += myPArray->bounds[i];
+          const GLint aNbElemsInGroup = myBounds->Bounds[aGroupIter];
+          glDrawElements (myDrawMode, aNbElemsInGroup, anIndexType, myIndices->value (aFirstElem));
+          aFirstElem += aNbElemsInGroup;
         }
       }
       else
       {
-        for (i = n = 0 ; i < myPArray->num_bounds; ++i)
+        GLint aFirstElem = 0;
+        for (Standard_Integer aGroupIter = 0; aGroupIter < myBounds->NbBounds; ++aGroupIter)
         {
-          glDrawArrays (myDrawMode, n, myPArray->bounds[i]);
-          n += myPArray->bounds[i];
+          const GLint aNbElemsInGroup = myBounds->Bounds[aGroupIter];
+          glDrawArrays (myDrawMode, aFirstElem, aNbElemsInGroup);
+          aFirstElem += aNbElemsInGroup;
         }
       }
     }
-    else if (myPArray->num_edges > 0)
+    else if (!myIndices.IsNull())
     {
-      if (myPArray->edge_vis)
-      {
-        glBegin (myDrawMode);
-        for (i = 0; i < myPArray->num_edges; ++i)
-        {
-          glEdgeFlag (myPArray->edge_vis[i]);
-          glVertex3fv (&myPArray->vertices[myPArray->edges[i]].xyz[0]);
-        }
-        glEnd();
-      }
-      else
-      {
-        glDrawElements (myDrawMode, myPArray->num_edges, GL_UNSIGNED_INT, (GLenum* )myPArray->edges);
-      }
+      glDrawElements (myDrawMode, myIndices->NbElements, toGlIndexType (myIndices->Stride), myIndices->Data());
     }
     else
     {
-      glDrawArrays (myDrawMode, 0, myPArray->num_vertexs);
+      glDrawArrays (myDrawMode, 0, myAttribs->NbElements);
     }
   }
 
@@ -594,7 +650,7 @@ void OpenGl_PrimitiveArray::DrawMarkers (const Handle(OpenGl_Workspace)& theWork
       glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
     }
 
-    glDrawArrays (myDrawMode, 0, toDrawVbo() ? myVbos[VBOVertices]->GetElemsNb() : myPArray->num_vertexs);
+    glDrawArrays (myDrawMode, 0, !myVboAttribs.IsNull() ? myVboAttribs->GetElemsNb() : myAttribs->NbElements);
 
     glDisable (GL_BLEND);
     glDisable (GL_ALPHA_TEST);
@@ -617,7 +673,7 @@ void OpenGl_PrimitiveArray::DrawMarkers (const Handle(OpenGl_Workspace)& theWork
     {
       glPointSize (aPntSize);
     }
-    glDrawArrays (myDrawMode, 0, toDrawVbo() ? myVbos[VBOVertices]->GetElemsNb() : myPArray->num_vertexs);
+    glDrawArrays (myDrawMode, 0, !myVboAttribs.IsNull() ? myVboAttribs->GetElemsNb() : myAttribs->NbElements);
     if (aPntSize > 0.0f)
     {
       glPointSize (1.0f);
@@ -627,20 +683,20 @@ void OpenGl_PrimitiveArray::DrawMarkers (const Handle(OpenGl_Workspace)& theWork
   if (anAspectMarker->Type() != Aspect_TOM_POINT
    && !aSpriteNorm.IsNull())
   {
-    if (!isHilight && (myPArray->vcolours != NULL))
+    /**if (!isHilight && (myPArray->vcolours != NULL))
     {
-      for (Standard_Integer anIter = 0; anIter < myPArray->num_vertexs; anIter++)
+      for (Standard_Integer anIter = 0; anIter < myAttribs->NbElements; anIter++)
       {
-        glColor4ubv ((GLubyte* )&myPArray->vcolours[anIter]);
-        glRasterPos3fv (myPArray->vertices[anIter].xyz);
+        glColor4ubv    (myPArray->vcolours[anIter].GetData());
+        glRasterPos3fv (myAttribs->Value<Graphic3d_Vec3> (anIter).GetData());
         aSpriteNorm->DrawBitmap (theWorkspace->GetGlContext());
       }
     }
-    else
+    else*/
     {
-      for (Standard_Integer anIter = 0; anIter < myPArray->num_vertexs; anIter++)
+      for (Standard_Integer anIter = 0; anIter < myAttribs->NbElements; anIter++)
       {
-        glRasterPos3fv (myPArray->vertices[anIter].xyz);
+        glRasterPos3fv (myAttribs->Value<Graphic3d_Vec3> (anIter).GetData());
         aSpriteNorm->DrawBitmap (theWorkspace->GetGlContext());
       }
     }
@@ -651,41 +707,57 @@ void OpenGl_PrimitiveArray::DrawMarkers (const Handle(OpenGl_Workspace)& theWork
 // function : OpenGl_PrimitiveArray
 // purpose  :
 // =======================================================================
-OpenGl_PrimitiveArray::OpenGl_PrimitiveArray (CALL_DEF_PARRAY* thePArray)
-: myPArray (thePArray),
-  myDrawMode (DRAW_MODE_NONE),
+OpenGl_PrimitiveArray::OpenGl_PrimitiveArray (const Graphic3d_TypeOfPrimitiveArray theType,
+                                              const Handle(Graphic3d_IndexBuffer)& theIndices,
+                                              const Handle(Graphic3d_Buffer)&      theAttribs,
+                                              const Handle(Graphic3d_BoundBuffer)& theBounds)
+: myIndices   (theIndices),
+  myAttribs   (theAttribs),
+  myBounds    (theBounds),
+  myDrawMode  (DRAW_MODE_NONE),
   myIsVboInit (Standard_False)
 {
-  switch (myPArray->type)
+  if (!myIndices.IsNull()
+    && myIndices->NbElements < 1)
+  {
+    // dummy index buffer?
+    myIndices.Nullify();
+  }
+  if (myAttribs.IsNull())
+  {
+    return;
+  }
+
+  switch (theType)
   {
-    case TelPointsArrayType:
+    case Graphic3d_TOPA_POINTS:
       myDrawMode = GL_POINTS;
       break;
-    case TelPolylinesArrayType:
+    case Graphic3d_TOPA_POLYLINES:
       myDrawMode = GL_LINE_STRIP;
       break;
-    case TelSegmentsArrayType:
+    case Graphic3d_TOPA_SEGMENTS:
       myDrawMode = GL_LINES;
       break;
-    case TelPolygonsArrayType:
+    case Graphic3d_TOPA_POLYGONS:
       myDrawMode = GL_POLYGON;
       break;
-    case TelTrianglesArrayType:
+    case Graphic3d_TOPA_TRIANGLES:
       myDrawMode = GL_TRIANGLES;
       break;
-    case TelQuadranglesArrayType:
+    case Graphic3d_TOPA_QUADRANGLES:
       myDrawMode = GL_QUADS;
       break;
-    case TelTriangleStripsArrayType:
+    case Graphic3d_TOPA_TRIANGLESTRIPS:
       myDrawMode = GL_TRIANGLE_STRIP;
       break;
-    case TelQuadrangleStripsArrayType:
+    case Graphic3d_TOPA_QUADRANGLESTRIPS:
       myDrawMode = GL_QUAD_STRIP;
       break;
-    case TelTriangleFansArrayType:
+    case Graphic3d_TOPA_TRIANGLEFANS:
       myDrawMode = GL_TRIANGLE_FAN;
       break;
-    case TelUnknownArrayType:
+    case Graphic3d_TOPA_UNDEFINED:
       break;
   }
 }
@@ -705,16 +777,21 @@ OpenGl_PrimitiveArray::~OpenGl_PrimitiveArray()
 // =======================================================================
 void OpenGl_PrimitiveArray::Release (const Handle(OpenGl_Context)& theContext)
 {
-  for (Standard_Integer anIter = 0; anIter < VBOMaxType; ++anIter)
+  if (!myVboIndices.IsNull())
   {
-    if (!myVbos[anIter].IsNull())
+    if (!theContext.IsNull())
     {
-      if (!theContext.IsNull())
-      {
-        theContext->DelayedRelease (myVbos[anIter]);
-      }
-      myVbos[anIter].Nullify();
+      theContext->DelayedRelease (myVboIndices);
+    }
+    myVboIndices.Nullify();
+  }
+  if (!myVboAttribs.IsNull())
+  {
+    if (!theContext.IsNull())
+    {
+      theContext->DelayedRelease (myVboAttribs);
     }
+    myVboAttribs.Nullify();
   }
 }
 
@@ -724,7 +801,7 @@ void OpenGl_PrimitiveArray::Release (const Handle(OpenGl_Context)& theContext)
 // =======================================================================
 void OpenGl_PrimitiveArray::Render (const Handle(OpenGl_Workspace)& theWorkspace) const
 {
-  if (myPArray == NULL || myDrawMode == DRAW_MODE_NONE || myPArray->num_vertexs <= 0)
+  if (myDrawMode == DRAW_MODE_NONE)
   {
     return;
   }
@@ -744,30 +821,22 @@ void OpenGl_PrimitiveArray::Render (const Handle(OpenGl_Workspace)& theWorkspace
     {
       TCollection_ExtendedString aMsg;
       aMsg += "VBO creation for Primitive Array has failed for ";
-      aMsg += myPArray->num_vertexs;
+      aMsg += myAttribs->NbElements;
       aMsg += " vertices. Out of memory?";
       aCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB, GL_DEBUG_TYPE_PERFORMANCE_ARB, 0, GL_DEBUG_SEVERITY_LOW_ARB, aMsg);
     }
     myIsVboInit = Standard_True;
   }
 
-  switch (myPArray->type)
+  if (myDrawMode <= GL_LINE_STRIP)
   {
-    case TelPointsArrayType:
-    case TelPolylinesArrayType:
-    case TelSegmentsArrayType:
-    {
-      glDisable (GL_LIGHTING);
-      break;
-    }
-    default:
-      break;
+    glDisable (GL_LIGHTING);
   }
 
   Tint aFrontLightingModel = anAspectFace->IntFront().color_mask;
   const TEL_COLOUR* anInteriorColor = &anAspectFace->IntFront().matcol;
   const TEL_COLOUR* anEdgeColor = &anAspectFace->AspectEdge()->Color();
-  const TEL_COLOUR* aLineColor = (myPArray->type == TelPointsArrayType) ? &anAspectMarker->Color() : &anAspectLine->Color();
+  const TEL_COLOUR* aLineColor  = myDrawMode == GL_POINTS ? &anAspectMarker->Color() : &anAspectLine->Color();
 
   // Use highlight colors
   if (theWorkspace->NamedStatus & OPENGL_NS_HIGHLIGHT)
@@ -778,15 +847,15 @@ void OpenGl_PrimitiveArray::Render (const Handle(OpenGl_Workspace)& theWorkspace
 
   if (aCtx->IsGlGreaterEqual (2, 0))
   {
-    switch (myPArray->type)
+    switch (myDrawMode)
     {
-      case TelPointsArrayType:
+      case GL_POINTS:
       {
         BindProgramWithMaterial (theWorkspace, anAspectMarker);
         break;
       }
-      case TelSegmentsArrayType:
-      case TelPolylinesArrayType:
+      case GL_LINES:
+      case GL_LINE_STRIP:
       {
         BindProgramWithMaterial (theWorkspace, anAspectLine);
         break;
@@ -805,6 +874,5 @@ void OpenGl_PrimitiveArray::Render (const Handle(OpenGl_Workspace)& theWorkspace
              anInteriorColor,
              aLineColor,
              anEdgeColor,
-             &anAspectFace->IntFront(),
              theWorkspace);
 }
index f006b0f..581e5af 100644 (file)
 #ifndef OpenGl_PrimitiveArray_Header
 #define OpenGl_PrimitiveArray_Header
 
-#include <OpenGl_VertexBuffer.hxx>
+#include <OpenGl_IndexBuffer.hxx>
 
 #include <InterfaceGraphic_Graphic3d.hxx>
 #include <Aspect_InteriorStyle.hxx>
 #include <Aspect_TypeOfMarker.hxx>
+#include <Graphic3d_TypeOfPrimitiveArray.hxx>
+#include <Graphic3d_IndexBuffer.hxx>
+#include <Graphic3d_BoundBuffer.hxx>
 
 #include <OpenGl_Element.hxx>
 
-struct OPENGL_SURF_PROP;
-
 class OpenGl_PrimitiveArray : public OpenGl_Element
 {
 public:
-  // OpenGL does not provie a constant for "none" draw mode.
+  // OpenGL does not provide a constant for "none" draw mode.
   // So we define our own one that does not conflict with GL constants
-  // and untilizes common GL invalid value
+  // and utilizes common GL invalid value
   enum
   {
     DRAW_MODE_NONE = -1
   };
 
   //! Default constructor
-  OpenGl_PrimitiveArray (CALL_DEF_PARRAY* thePArray);
+  OpenGl_PrimitiveArray (const Graphic3d_TypeOfPrimitiveArray theType,
+                         const Handle(Graphic3d_IndexBuffer)& theIndices,
+                         const Handle(Graphic3d_Buffer)&      theAttribs,
+                         const Handle(Graphic3d_BoundBuffer)& theBounds);
 
   //! Render primitives to the window
   virtual void Render  (const Handle(OpenGl_Workspace)& theWorkspace) const;
 
   virtual void Release (const Handle(OpenGl_Context)&   theContext);
 
-  CALL_DEF_PARRAY* PArray() const { return myPArray; }
+  //! @return primitive type (GL_LINES, GL_TRIANGLES and others)
+  GLint DrawMode() const { return myDrawMode; }
 
-private:
+  //! @return indices array
+  const Handle(Graphic3d_IndexBuffer)& Indices() const { return myIndices; }
 
-  Standard_Boolean toDrawVbo() const
-  {
-    return !myVbos[VBOVertices].IsNull();
-  }
+  //! @return attributes array
+  const Handle(Graphic3d_Buffer)& Attributes() const { return myAttribs; }
+
+  //! @return bounds array
+  const Handle(Graphic3d_BoundBuffer)& Bounds() const { return myBounds; }
+
+private:
 
   //! VBO initialization procedures
   Standard_Boolean BuildVBO (const Handle(OpenGl_Workspace)& theWorkspace) const;
-  void clearMemoryOwn() const;
   void clearMemoryGL (const Handle(OpenGl_Context)& theGlCtx) const;
 
   //! Main procedure to draw array
@@ -66,7 +74,6 @@ private:
                   const TEL_COLOUR* theInteriorColour,
                   const TEL_COLOUR* theLineColour,
                   const TEL_COLOUR* theEdgeColour,
-                  const OPENGL_SURF_PROP* theFaceProp,
                   const Handle(OpenGl_Workspace)& theWorkspace) const;
 
   //! Auxiliary procedures
@@ -82,20 +89,14 @@ protected:
 
 protected:
 
-  typedef enum
-  {
-    VBOEdges,
-    VBOVertices,
-    VBOVcolours,
-    VBOVnormals,
-    VBOVtexels,
-    VBOMaxType
-  } VBODataType;
-
-  mutable CALL_DEF_PARRAY*            myPArray;
-  mutable Handle(OpenGl_VertexBuffer) myVbos[VBOMaxType];
-  GLint                               myDrawMode;
-  mutable Standard_Boolean            myIsVboInit;
+  mutable Handle(OpenGl_IndexBuffer)    myVboIndices;
+  mutable Handle(OpenGl_VertexBuffer)   myVboAttribs;
+
+  mutable Handle(Graphic3d_IndexBuffer) myIndices;
+  mutable Handle(Graphic3d_Buffer)      myAttribs;
+  mutable Handle(Graphic3d_BoundBuffer) myBounds;
+  GLint                                 myDrawMode;
+  mutable Standard_Boolean              myIsVboInit;
 
 public:
 
index 73ecc43..60e69de 100755 (executable)
@@ -346,7 +346,7 @@ namespace OpenGl_Raytrace
   {
     OpenGl_PrimitiveArray* anArray = dynamic_cast< OpenGl_PrimitiveArray* > (theNode->elem);
     return anArray != NULL
-        && anArray->PArray()->type >= TelPolygonsArrayType;
+        && anArray->DrawMode() >= GL_TRIANGLES;
   }
 
   // =======================================================================
index 071f531..6c7a632 100644 (file)
@@ -106,13 +106,15 @@ void OpenGl_VertexBuffer::Unbind (const Handle(OpenGl_Context)& theGlCtx) const
 }
 
 // =======================================================================
-// function : Init
+// function : init
 // purpose  :
 // =======================================================================
-bool OpenGl_VertexBuffer::Init (const Handle(OpenGl_Context)& theGlCtx,
+bool OpenGl_VertexBuffer::init (const Handle(OpenGl_Context)& theGlCtx,
                                 const GLuint   theComponentsNb,
                                 const GLsizei  theElemsNb,
-                                const GLfloat* theData)
+                                const void*    theData,
+                                const GLenum   theDataType,
+                                const GLsizei  theStride)
 {
   if (!Create (theGlCtx))
   {
@@ -120,34 +122,36 @@ bool OpenGl_VertexBuffer::Init (const Handle(OpenGl_Context)& theGlCtx,
   }
 
   Bind (theGlCtx);
-  myDataType     = GL_FLOAT;
+  myDataType     = theDataType;
   myComponentsNb = theComponentsNb;
   myElemsNb      = theElemsNb;
-  theGlCtx->core15->glBufferData (GetTarget(), GLsizeiptr(myElemsNb) * GLsizeiptr(myComponentsNb) * sizeof(GLfloat), theData, GL_STATIC_DRAW);
+  theGlCtx->core15->glBufferData (GetTarget(), GLsizeiptr(myElemsNb) * theStride, theData, GL_STATIC_DRAW);
   bool isDone = (glGetError() == GL_NO_ERROR); // GL_OUT_OF_MEMORY
   Unbind (theGlCtx);
   return isDone;
 }
 
 // =======================================================================
-// function : SubData
+// function : subData
 // purpose  :
 // =======================================================================
-bool OpenGl_VertexBuffer::SubData (const Handle(OpenGl_Context)& theGlCtx,
+bool OpenGl_VertexBuffer::subData (const Handle(OpenGl_Context)& theGlCtx,
                                    const GLsizei  theElemFrom,
                                    const GLsizei  theElemsNb,
-                                   const GLfloat* theData)
+                                   const void*    theData,
+                                   const GLenum   theDataType)
 {
-  if (!IsValid() || myDataType != GL_FLOAT ||
+  if (!IsValid() || myDataType != theDataType ||
       theElemFrom < 0 || ((theElemFrom + theElemsNb) > myElemsNb))
   {
     return false;
   }
 
   Bind (theGlCtx);
+  const size_t aDataSize = sizeOfGlType (theDataType);
   theGlCtx->core15->glBufferSubData (GetTarget(),
-                                     GLintptr(theElemFrom)  * GLintptr(myComponentsNb)   * sizeof(GLfloat), // offset in bytes
-                                     GLsizeiptr(theElemsNb) * GLsizeiptr(myComponentsNb) * sizeof(GLfloat), // size   in bytes
+                                     GLintptr(theElemFrom)  * GLintptr  (myComponentsNb) * aDataSize, // offset in bytes
+                                     GLsizeiptr(theElemsNb) * GLsizeiptr(myComponentsNb) * aDataSize, // size   in bytes
                                      theData);
   bool isDone = (glGetError() == GL_NO_ERROR); // some dummy error
   Unbind (theGlCtx);
@@ -155,104 +159,6 @@ bool OpenGl_VertexBuffer::SubData (const Handle(OpenGl_Context)& theGlCtx,
 }
 
 // =======================================================================
-// function : Init
-// purpose  :
-// =======================================================================
-bool OpenGl_VertexBuffer::Init (const Handle(OpenGl_Context)& theGlCtx,
-                                const GLuint  theComponentsNb,
-                                const GLsizei theElemsNb,
-                                const GLuint* theData)
-{
-  if (!Create (theGlCtx))
-  {
-    return false;
-  }
-
-  Bind (theGlCtx);
-  myDataType     = GL_UNSIGNED_INT;  
-  myComponentsNb = theComponentsNb;
-  myElemsNb      = theElemsNb;
-  theGlCtx->core15->glBufferData (GetTarget(), GLsizeiptr(myElemsNb) * GLsizeiptr(myComponentsNb) * sizeof(GLuint), theData, GL_STATIC_DRAW);
-  bool isDone = (glGetError() == GL_NO_ERROR); // GL_OUT_OF_MEMORY
-  Unbind (theGlCtx);
-  return isDone;
-}
-
-// =======================================================================
-// function : SubData
-// purpose  :
-// =======================================================================
-bool OpenGl_VertexBuffer::SubData (const Handle(OpenGl_Context)& theGlCtx,
-                                   const GLsizei theElemFrom,
-                                   const GLsizei theElemsNb,
-                                   const GLuint* theData)
-{
-  if (!IsValid() || myDataType != GL_UNSIGNED_INT
-   || theElemFrom < 0 || ((theElemFrom + theElemsNb) > myElemsNb))
-  {
-    return false;
-  }
-
-  Bind (theGlCtx);
-  theGlCtx->core15->glBufferSubData (GetTarget(),
-                                     GLintptr(theElemFrom)  * GLintptr(myComponentsNb)   * sizeof(GLuint), // offset in bytes
-                                     GLsizeiptr(theElemsNb) * GLsizeiptr(myComponentsNb) * sizeof(GLuint), // size   in bytes
-                                     theData);
-  bool isDone = (glGetError() == GL_NO_ERROR); // GL_OUT_OF_MEMORY
-  Unbind (theGlCtx);
-  return isDone;
-}
-
-// =======================================================================
-// function : Init
-// purpose  :
-// =======================================================================
-bool OpenGl_VertexBuffer::Init (const Handle(OpenGl_Context)& theGlCtx,
-                                const GLuint   theComponentsNb,
-                                const GLsizei  theElemsNb,
-                                const GLubyte* theData)
-{
-  if (!Create (theGlCtx))
-  {
-    return false;
-  }
-
-  Bind (theGlCtx);
-  myDataType     = GL_UNSIGNED_BYTE;
-  myComponentsNb = theComponentsNb;
-  myElemsNb      = theElemsNb;
-  theGlCtx->core15->glBufferData (GetTarget(), GLsizeiptr(myElemsNb) * GLsizeiptr(myComponentsNb) * sizeof(GLubyte), theData, GL_STATIC_DRAW);
-  bool isDone = (glGetError() == GL_NO_ERROR); // GL_OUT_OF_MEMORY
-  Unbind (theGlCtx);
-  return isDone;
-}
-
-// =======================================================================
-// function : SubData
-// purpose  :
-// =======================================================================
-bool OpenGl_VertexBuffer::SubData (const Handle(OpenGl_Context)& theGlCtx,
-                                   const GLsizei  theElemFrom,
-                                   const GLsizei  theElemsNb,
-                                   const GLubyte* theData)
-{
-  if (!IsValid() || myDataType != GL_UNSIGNED_BYTE
-   || theElemFrom < 0 || ((theElemFrom + theElemsNb) > myElemsNb))
-  {
-    return false;
-  }
-
-  Bind (theGlCtx);
-  theGlCtx->core15->glBufferSubData (GetTarget(),
-                                     GLintptr(theElemFrom)  * GLintptr(myComponentsNb)   * sizeof(GLubyte), // offset in bytes
-                                     GLsizeiptr(theElemsNb) * GLsizeiptr(myComponentsNb) * sizeof(GLubyte), // size   in bytes
-                                     theData);
-  bool isDone = (glGetError() == GL_NO_ERROR); // GL_OUT_OF_MEMORY
-  Unbind (theGlCtx);
-  return isDone;
-}
-
-// =======================================================================
 // function : BindVertexAttrib
 // purpose  :
 // =======================================================================
@@ -317,6 +223,8 @@ void OpenGl_VertexBuffer::BindFixed (const Handle(OpenGl_Context)& theGlCtx,
     case GL_COLOR_ARRAY:
     {
       glColorPointer (static_cast<GLint> (myComponentsNb), myDataType, 0, NULL);
+      glColorMaterial (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
+      glEnable (GL_COLOR_MATERIAL);
       break;
     }
     default: break;
@@ -336,4 +244,44 @@ void OpenGl_VertexBuffer::UnbindFixed (const Handle(OpenGl_Context)& theGlCtx,
   }
   Unbind (theGlCtx);
   glDisableClientState (theMode);
+  if (theMode == GL_COLOR_ARRAY)
+  {
+    glDisable (GL_COLOR_MATERIAL);
+  }
+}
+
+// =======================================================================
+// function : BindFixed
+// purpose  :
+// =======================================================================
+void OpenGl_VertexBuffer::BindFixed (const Handle(OpenGl_Context)& ) const
+{
+  //
+}
+
+// =======================================================================
+// function : BindFixedPosition
+// purpose  :
+// =======================================================================
+void OpenGl_VertexBuffer::BindFixedPosition (const Handle(OpenGl_Context)& ) const
+{
+  //
+}
+
+// =======================================================================
+// function : UnbindFixed
+// purpose  :
+// =======================================================================
+void OpenGl_VertexBuffer::UnbindFixed (const Handle(OpenGl_Context)& ) const
+{
+    //
+}
+
+// =======================================================================
+// function : HasColorAttribute
+// purpose  :
+// =======================================================================
+bool OpenGl_VertexBuffer::HasColorAttribute() const
+{
+  return false;
 }
index 46417f7..c78a85f 100644 (file)
@@ -17,9 +17,9 @@
 
 #include <OpenGl_GlCore20.hxx>
 #include <OpenGl_Resource.hxx>
+#include <OpenGl_Context.hxx>
 
-class Handle(OpenGl_Context);
-class OpenGl_Context;
+#include <Graphic3d_IndexBuffer.hxx>
 
 //! Vertex Buffer Object - is a general storage object for vertex attributes (position, normal, color).
 //! Notice that you should use OpenGl_IndexBuffer specialization for array of indices.
@@ -82,28 +82,49 @@ public:
   //! @param theComponentsNb - specifies the number of components per generic vertex attribute; must be 1, 2, 3, or 4;
   //! @param theElemsNb      - elements count;
   //! @param theData         - pointer to GLfloat data (vertices/normals etc.).
-  Standard_EXPORT bool Init (const Handle(OpenGl_Context)& theGlCtx,
-                             const GLuint   theComponentsNb,
-                             const GLsizei  theElemsNb,
-                             const GLfloat* theData);
+  bool Init (const Handle(OpenGl_Context)& theGlCtx,
+             const GLuint   theComponentsNb,
+             const GLsizei  theElemsNb,
+             const GLfloat* theData)
+  {
+    return init (theGlCtx, theComponentsNb, theElemsNb, theData, GL_FLOAT);
+  }
 
   //! Notice that VBO will be unbound after this call.
   //! @param theComponentsNb - specifies the number of components per generic vertex attribute; must be 1, 2, 3, or 4;
   //! @param theElemsNb      - elements count;
   //! @param theData         - pointer to GLuint data (indices etc.).
-  Standard_EXPORT bool Init (const Handle(OpenGl_Context)& theGlCtx,
-                             const GLuint  theComponentsNb,
-                             const GLsizei theElemsNb,
-                             const GLuint* theData);
+  bool Init (const Handle(OpenGl_Context)& theGlCtx,
+             const GLuint  theComponentsNb,
+             const GLsizei theElemsNb,
+             const GLuint* theData)
+  {
+    return init (theGlCtx, theComponentsNb, theElemsNb, theData, GL_UNSIGNED_INT);
+  }
+
+  //! Notice that VBO will be unbound after this call.
+  //! @param theComponentsNb - specifies the number of components per generic vertex attribute; must be 1, 2, 3, or 4;
+  //! @param theElemsNb      - elements count;
+  //! @param theData         - pointer to GLushort data (indices etc.).
+  bool Init (const Handle(OpenGl_Context)& theGlCtx,
+             const GLuint    theComponentsNb,
+             const GLsizei   theElemsNb,
+             const GLushort* theData)
+  {
+    return init (theGlCtx, theComponentsNb, theElemsNb, theData, GL_UNSIGNED_SHORT);
+  }
 
   //! Notice that VBO will be unbound after this call.
   //! @param theComponentsNb - specifies the number of components per generic vertex attribute; must be 1, 2, 3, or 4;
   //! @param theElemsNb      - elements count;
   //! @param theData         - pointer to GLubyte data (indices/colors etc.).
-  Standard_EXPORT bool Init (const Handle(OpenGl_Context)& theGlCtx,
-                             const GLuint   theComponentsNb,
-                             const GLsizei  theElemsNb,
-                             const GLubyte* theData);
+  bool Init (const Handle(OpenGl_Context)& theGlCtx,
+             const GLuint   theComponentsNb,
+             const GLsizei  theElemsNb,
+             const GLubyte* theData)
+  {
+    return init (theGlCtx, theComponentsNb, theElemsNb, theData, GL_UNSIGNED_BYTE);
+  }
 
   //! Notice that VBO will be unbound after this call.
   //! Function replaces portion of data within this VBO using glBufferSubData().
@@ -111,10 +132,13 @@ public:
   //! @param theElemFrom - element id from which replace buffer data (>=0);
   //! @param theElemsNb  - elements count (theElemFrom + theElemsNb <= GetElemsNb());
   //! @param theData     - pointer to GLfloat data.
-  Standard_EXPORT bool SubData (const Handle(OpenGl_Context)& theGlCtx,
-                                const GLsizei  theElemFrom,
-                                const GLsizei  theElemsNb,
-                                const GLfloat* theData);
+  bool SubData (const Handle(OpenGl_Context)& theGlCtx,
+                const GLsizei  theElemFrom,
+                const GLsizei  theElemsNb,
+                const GLfloat* theData)
+  {
+    return subData (theGlCtx, theElemFrom, theElemsNb, theData, GL_FLOAT);
+  }
 
   //! Notice that VBO will be unbound after this call.
   //! Function replaces portion of data within this VBO using glBufferSubData().
@@ -122,10 +146,27 @@ public:
   //! @param theElemFrom element id from which replace buffer data (>=0);
   //! @param theElemsNb  elements count (theElemFrom + theElemsNb <= GetElemsNb());
   //! @param theData     pointer to GLuint data.
-  Standard_EXPORT bool SubData (const Handle(OpenGl_Context)& theGlCtx,
-                                const GLsizei theElemFrom,
-                                const GLsizei theElemsNb,
-                                const GLuint* theData);
+  bool SubData (const Handle(OpenGl_Context)& theGlCtx,
+                const GLsizei theElemFrom,
+                const GLsizei theElemsNb,
+                const GLuint* theData)
+  {
+    return subData (theGlCtx, theElemFrom, theElemsNb, theData, GL_UNSIGNED_INT);
+  }
+
+  //! Notice that VBO will be unbound after this call.
+  //! Function replaces portion of data within this VBO using glBufferSubData().
+  //! The VBO should be initialized before call.
+  //! @param theElemFrom element id from which replace buffer data (>=0);
+  //! @param theElemsNb  elements count (theElemFrom + theElemsNb <= GetElemsNb());
+  //! @param theData     pointer to GLushort data.
+  bool SubData (const Handle(OpenGl_Context)& theGlCtx,
+                const GLsizei   theElemFrom,
+                const GLsizei   theElemsNb,
+                const GLushort* theData)
+  {
+    return subData (theGlCtx, theElemFrom, theElemsNb, theData, GL_UNSIGNED_SHORT);
+  }
 
   //! Notice that VBO will be unbound after this call.
   //! Function replaces portion of data within this VBO using glBufferSubData().
@@ -133,10 +174,13 @@ public:
   //! @param theElemFrom element id from which replace buffer data (>=0);
   //! @param theElemsNb  elements count (theElemFrom + theElemsNb <= GetElemsNb());
   //! @param theData     pointer to GLubyte data.
-  Standard_EXPORT bool SubData (const Handle(OpenGl_Context)& theGlCtx,
-                                const GLsizei  theElemFrom,
-                                const GLsizei  theElemsNb,
-                                const GLubyte* theData);
+  bool SubData (const Handle(OpenGl_Context)& theGlCtx,
+                const GLsizei  theElemFrom,
+                const GLsizei  theElemsNb,
+                const GLubyte* theData)
+  {
+    return subData (theGlCtx, theElemFrom, theElemsNb, theData, GL_UNSIGNED_BYTE);
+  }
 
   //! Bind this VBO to active GLSL program.
   Standard_EXPORT void BindVertexAttrib (const Handle(OpenGl_Context)& theGlCtx,
@@ -158,6 +202,129 @@ public:
   Standard_EXPORT void UnbindFixed (const Handle(OpenGl_Context)& theGlCtx,
                                     const GLenum                  theMode) const;
 
+public: //! @name advanced methods
+
+  //! @return size of specified GL type
+  static size_t sizeOfGlType (const GLenum theType)
+  {
+    switch (theType)
+    {
+      case GL_BYTE:
+      case GL_UNSIGNED_BYTE:  return sizeof(GLubyte);
+      case GL_SHORT:
+      case GL_UNSIGNED_SHORT: return sizeof(GLushort);
+      case GL_INT:
+      case GL_UNSIGNED_INT:   return sizeof(GLuint);
+      case GL_FLOAT:          return sizeof(GLfloat);
+      case GL_DOUBLE:         return sizeof(GLdouble);
+      default:                return 0;
+    }
+  }
+
+  //! Initialize buffer with new data.
+  Standard_EXPORT bool init (const Handle(OpenGl_Context)& theGlCtx,
+                             const GLuint   theComponentsNb,
+                             const GLsizei  theElemsNb,
+                             const void*    theData,
+                             const GLenum   theDataType,
+                             const GLsizei  theStride);
+
+  //! Initialize buffer with new data.
+  bool init (const Handle(OpenGl_Context)& theGlCtx,
+             const GLuint   theComponentsNb,
+             const GLsizei  theElemsNb,
+             const void*    theData,
+             const GLenum   theDataType)
+  {
+    return init (theGlCtx, theComponentsNb, theElemsNb, theData, theDataType, GLsizei(theComponentsNb) * GLsizei(sizeOfGlType (theDataType)));
+  }
+
+  //! Update part of the buffer with new data.
+  Standard_EXPORT bool subData (const Handle(OpenGl_Context)& theGlCtx,
+                                const GLsizei  theElemFrom,
+                                const GLsizei  theElemsNb,
+                                const void*    theData,
+                                const GLenum   theDataType);
+
+  //! Setup FFP array pointer.
+  static void bindFixed (const Handle(OpenGl_Context)&   theGlCtx,
+                         const Graphic3d_TypeOfAttribute theMode,
+                         const GLint                     theNbComp,
+                         const GLenum                    theDataType,
+                         const GLsizei                   theStride,
+                         const GLvoid*                   theOffset)
+  {
+    switch (theMode)
+    {
+      case Graphic3d_TOA_POS:
+      {
+        theGlCtx->core11->glEnableClientState (GL_VERTEX_ARRAY);
+        theGlCtx->core11->glVertexPointer (theNbComp, theDataType, theStride, theOffset);
+        break;
+      }
+      case Graphic3d_TOA_NORM:
+      {
+        theGlCtx->core11->glEnableClientState (GL_NORMAL_ARRAY);
+        theGlCtx->core11->glNormalPointer (theDataType, theStride, theOffset);
+        break;
+      }
+      case Graphic3d_TOA_UV:
+      {
+        theGlCtx->core11->glEnableClientState (GL_TEXTURE_COORD_ARRAY);
+        theGlCtx->core11->glTexCoordPointer (theNbComp, theDataType, theStride, theOffset);
+        break;
+      }
+      case Graphic3d_TOA_COLOR:
+      {
+        theGlCtx->core11->glEnableClientState (GL_COLOR_ARRAY);
+        theGlCtx->core11->glColorPointer (theNbComp, theDataType, theStride, theOffset);
+        theGlCtx->core11->glColorMaterial (GL_FRONT_AND_BACK,GL_AMBIENT_AND_DIFFUSE);
+        theGlCtx->core11fwd->glEnable (GL_COLOR_MATERIAL);
+        break;
+      }
+      case Graphic3d_TOA_CUSTOM:
+      {
+        break;
+      }
+    }
+  }
+
+  //! Disable FFP array pointer.
+  static void unbindFixed (const Handle(OpenGl_Context)&   theGlCtx,
+                           const Graphic3d_TypeOfAttribute theMode)
+  {
+    switch (theMode)
+    {
+      case Graphic3d_TOA_POS:    theGlCtx->core11->glDisableClientState (GL_VERTEX_ARRAY);        break;
+      case Graphic3d_TOA_NORM:   theGlCtx->core11->glDisableClientState (GL_NORMAL_ARRAY);        break;
+      case Graphic3d_TOA_UV:     theGlCtx->core11->glDisableClientState (GL_TEXTURE_COORD_ARRAY); break;
+      case Graphic3d_TOA_COLOR:
+      {
+        theGlCtx->core11->glDisableClientState (GL_COLOR_ARRAY);
+        theGlCtx->core11fwd->glDisable (GL_COLOR_MATERIAL);
+        break;
+      }
+      case Graphic3d_TOA_CUSTOM:
+      {
+        break;
+      }
+    }
+  }
+
+public: //! @name methods for interleaved attributes array
+
+  //! Bind all vertex attributes. Default implementation does nothing.
+  Standard_EXPORT virtual void BindFixed   (const Handle(OpenGl_Context)& theGlCtx) const;
+
+  //! Bind all vertex position attribute only. Default implementation does nothing.
+  Standard_EXPORT virtual void BindFixedPosition (const Handle(OpenGl_Context)& theGlCtx) const;
+
+  //! Unbind all vertex attributes. Default implementation does nothing.
+  Standard_EXPORT virtual void UnbindFixed (const Handle(OpenGl_Context)& theGlCtx) const;
+
+  //! @return true if buffer contains per-vertex color attribute
+  Standard_EXPORT virtual bool HasColorAttribute() const;
+
 protected:
 
   GLuint  myBufferId;     //!< VBO name (index)
index 3042912..9c32f49 100755 (executable)
@@ -380,32 +380,53 @@ protected: //! @name methods related to ray-tracing
     const OpenGl_PrimitiveArray* theArray, int theMatID, const Standard_ShortReal* theTrans);
 
   //! Adds vertex indices from OpenGL primitive array to ray-traced scene geometry.
-  Standard_Boolean AddRaytraceVertexIndices (OpenGl_TriangleSet* theSet,
-    const CALL_DEF_PARRAY* theArray, Standard_Integer theOffset, Standard_Integer theCount, Standard_Integer theMatID);
+  Standard_Boolean AddRaytraceVertexIndices (OpenGl_TriangleSet&          theSet,
+                                             const OpenGl_PrimitiveArray& theArray,
+                                             Standard_Integer             theOffset,
+                                             Standard_Integer             theCount,
+                                             Standard_Integer             theMatID);
 
   //! Adds OpenGL triangle array to ray-traced scene geometry.
-  Standard_Boolean AddRaytraceTriangleArray (OpenGl_TriangleSet* theSet,
-    const CALL_DEF_PARRAY* theArray, Standard_Integer theOffset, Standard_Integer theCount, Standard_Integer theMatID);
+  Standard_Boolean AddRaytraceTriangleArray (OpenGl_TriangleSet&                  theSet,
+                                             const Handle(Graphic3d_IndexBuffer)& theIndices,
+                                             Standard_Integer                     theOffset,
+                                             Standard_Integer                     theCount,
+                                             Standard_Integer                     theMatID);
 
   //! Adds OpenGL triangle fan array to ray-traced scene geometry.
-  Standard_Boolean AddRaytraceTriangleFanArray (OpenGl_TriangleSet* theSet,
-    const CALL_DEF_PARRAY* theArray, Standard_Integer theOffset, Standard_Integer theCount, Standard_Integer theMatID);
+  Standard_Boolean AddRaytraceTriangleFanArray (OpenGl_TriangleSet&                  theSet,
+                                                const Handle(Graphic3d_IndexBuffer)& theIndices,
+                                                Standard_Integer                     theOffset,
+                                                Standard_Integer                     theCount,
+                                                Standard_Integer                     theMatID);
 
   //! Adds OpenGL triangle strip array to ray-traced scene geometry.
-  Standard_Boolean AddRaytraceTriangleStripArray (OpenGl_TriangleSet* theSet,
-    const CALL_DEF_PARRAY* theArray, Standard_Integer theOffset, Standard_Integer theCount, Standard_Integer theMatID);
+  Standard_Boolean AddRaytraceTriangleStripArray (OpenGl_TriangleSet&                  theSet,
+                                                  const Handle(Graphic3d_IndexBuffer)& theIndices,
+                                                  Standard_Integer                     theOffset,
+                                                  Standard_Integer                     theCount,
+                                                  Standard_Integer                     theMatID);
 
   //! Adds OpenGL quadrangle array to ray-traced scene geometry.
-  Standard_Boolean AddRaytraceQuadrangleArray (OpenGl_TriangleSet* theSet,
-    const CALL_DEF_PARRAY* theArray, Standard_Integer theOffset, Standard_Integer theCount, Standard_Integer theMatID);
+  Standard_Boolean AddRaytraceQuadrangleArray (OpenGl_TriangleSet&                  theSet,
+                                               const Handle(Graphic3d_IndexBuffer)& theIndices,
+                                               Standard_Integer                     theOffset,
+                                               Standard_Integer                     theCount,
+                                               Standard_Integer                     theMatID);
 
   //! Adds OpenGL quadrangle strip array to ray-traced scene geometry.
-  Standard_Boolean AddRaytraceQuadrangleStripArray (OpenGl_TriangleSet* theSet,
-    const CALL_DEF_PARRAY* theArray, Standard_Integer theOffset, Standard_Integer theCount, Standard_Integer theMatID);
+  Standard_Boolean AddRaytraceQuadrangleStripArray (OpenGl_TriangleSet&                  theSet,
+                                                    const Handle(Graphic3d_IndexBuffer)& theIndices,
+                                                    Standard_Integer                     theOffset,
+                                                    Standard_Integer                     theCount,
+                                                    Standard_Integer                     theMatID);
 
   //! Adds OpenGL polygon array to ray-traced scene geometry.
-  Standard_Boolean AddRaytracePolygonArray (OpenGl_TriangleSet* theSet,
-    const CALL_DEF_PARRAY* theArray, Standard_Integer theOffset, Standard_Integer theCount, Standard_Integer theMatID);
+  Standard_Boolean AddRaytracePolygonArray (OpenGl_TriangleSet&                  theSet,
+                                            const Handle(Graphic3d_IndexBuffer)& theIndices,
+                                            Standard_Integer                     theOffset,
+                                            Standard_Integer                     theCount,
+                                            Standard_Integer                     theMatID);
 
   //! Loads and compiles shader object from specified source.
   Handle(OpenGl_ShaderObject) LoadShader (const ShaderSource& theSource, GLenum theType);
index b280ff8..cfd3500 100755 (executable)
@@ -452,100 +452,114 @@ Standard_Boolean OpenGl_Workspace::AddRaytraceStructure (const OpenGl_Structure*
 // function : AddRaytracePrimitiveArray
 // purpose  : Adds OpenGL primitive array to ray-traced scene geometry
 // =======================================================================
-OpenGl_TriangleSet* OpenGl_Workspace::AddRaytracePrimitiveArray (
-  const OpenGl_PrimitiveArray* theArray, Standard_Integer theMatID, const Standard_ShortReal* theTransform)
+OpenGl_TriangleSet* OpenGl_Workspace::AddRaytracePrimitiveArray (const OpenGl_PrimitiveArray* theArray,
+                                                                 Standard_Integer             theMatID,
+                                                                 const Standard_ShortReal*    theTransform)
 {
-  CALL_DEF_PARRAY* aPArray = theArray->PArray();
-
-  if (aPArray->type != TelPolygonsArrayType &&
-      aPArray->type != TelTrianglesArrayType &&
-      aPArray->type != TelQuadranglesArrayType &&
-      aPArray->type != TelTriangleFansArrayType &&
-      aPArray->type != TelTriangleStripsArrayType &&
-      aPArray->type != TelQuadrangleStripsArrayType)
+  const Handle(Graphic3d_IndexBuffer)& anIndices = theArray->Indices();
+  const Handle(Graphic3d_Buffer)&      anAttribs = theArray->Attributes();
+  const Handle(Graphic3d_BoundBuffer)& aBounds   = theArray->Bounds();
+  if (theArray->DrawMode() < GL_TRIANGLES
+   || theArray->DrawMode() > GL_POLYGON
+   || anAttribs.IsNull())
   {
     return NULL;
   }
 
-  if (aPArray->vertices == NULL)
-    return NULL;
-
 #ifdef RAY_TRACE_PRINT_INFO
-  switch (aPArray->type)
-  {
-    case TelPolygonsArrayType:
-      std::cout << "\tAdding TelPolygonsArrayType" << std::endl; break;
-    case TelTrianglesArrayType:
-      std::cout << "\tAdding TelTrianglesArrayType" << std::endl; break;
-    case TelQuadranglesArrayType:
-      std::cout << "\tAdding TelQuadranglesArrayType" << std::endl; break;
-    case TelTriangleFansArrayType:
-      std::cout << "\tAdding TelTriangleFansArrayType" << std::endl; break;
-    case TelTriangleStripsArrayType:
-      std::cout << "\tAdding TelTriangleStripsArrayType" << std::endl; break;
-    case TelQuadrangleStripsArrayType:
-      std::cout << "\tAdding TelQuadrangleStripsArrayType" << std::endl; break;
+  switch (aPArray->DrawMode())
+  {
+    case GL_POLYGON:        std::cout << "\tAdding GL_POLYGON\n";        break;
+    case GL_TRIANGLES:      std::cout << "\tAdding GL_TRIANGLES\n";      break;
+    case GL_QUADS:          std::cout << "\tAdding GL_QUADS\n";          break;
+    case GL_TRIANGLE_FAN:   std::cout << "\tAdding GL_TRIANGLE_FAN\n";   break;
+    case GL_TRIANGLE_STRIP: std::cout << "\tAdding GL_TRIANGLE_STRIP\n"; break;
+    case GL_QUAD_STRIP:     std::cout << "\tAdding GL_QUAD_STRIP\n";     break;
   }
 #endif
 
   OpenGl_TriangleSet* aSet = new OpenGl_TriangleSet (theArray);
-
   {
-    aSet->Vertices.reserve (aPArray->num_vertexs);
-
-    for (Standard_Integer aVert = 0; aVert < aPArray->num_vertexs; ++aVert)
+    aSet->Vertices.reserve (anAttribs->NbElements);
+    aSet->Normals .reserve (anAttribs->NbElements);
+    const size_t aVertFrom = aSet->Vertices.size();
+    for (Standard_Integer anAttribIter = 0; anAttribIter < anAttribs->NbAttributes; ++anAttribIter)
     {
-      BVH_Vec4f aVertex (aPArray->vertices[aVert].xyz[0],
-                         aPArray->vertices[aVert].xyz[1],
-                         aPArray->vertices[aVert].xyz[2],
-                         1.f);
-      if (theTransform)
-        aVertex = MatVecMult (theTransform, aVertex);
-
-      aSet->Vertices.push_back (aVertex);
+      const Graphic3d_Attribute& anAttrib = anAttribs->Attribute       (anAttribIter);
+      const size_t               anOffset = anAttribs->AttributeOffset (anAttribIter);
+      if (anAttrib.Id == Graphic3d_TOA_POS)
+      {
+        if (anAttrib.DataType == Graphic3d_TOD_VEC3
+         || anAttrib.DataType == Graphic3d_TOD_VEC4)
+        {
+          for (Standard_Integer aVertIter = 0; aVertIter < anAttribs->NbElements; ++aVertIter)
+          {
+            const Graphic3d_Vec3& aVert = *reinterpret_cast<const Graphic3d_Vec3* >(anAttribs->value (aVertIter) + anOffset);
+            aSet->Vertices.push_back (BVH_Vec4f (aVert.x(), aVert.y(), aVert.z(), 1.0f));
+          }
+        }
+        else if (anAttrib.DataType == Graphic3d_TOD_VEC2)
+        {
+          for (Standard_Integer aVertIter = 0; aVertIter < anAttribs->NbElements; ++aVertIter)
+          {
+            const Graphic3d_Vec2& aVert = *reinterpret_cast<const Graphic3d_Vec2* >(anAttribs->value (aVertIter) + anOffset);
+            aSet->Vertices.push_back (BVH_Vec4f (aVert.x(), aVert.y(), 0.0f, 1.0f));
+          }
+        }
+      }
+      else if (anAttrib.Id == Graphic3d_TOA_NORM)
+      {
+        if (anAttrib.DataType == Graphic3d_TOD_VEC3
+         || anAttrib.DataType == Graphic3d_TOD_VEC4)
+        {
+          for (Standard_Integer aVertIter = 0; aVertIter < anAttribs->NbElements; ++aVertIter)
+          {
+            const Graphic3d_Vec3& aNorm = *reinterpret_cast<const Graphic3d_Vec3* >(anAttribs->value (aVertIter) + anOffset);
+            aSet->Normals.push_back (BVH_Vec4f (aNorm.x(), aNorm.y(), aNorm.z(), 0.0f));
+          }
+        }
+      }
     }
 
-    aSet->Normals.reserve (aPArray->num_vertexs);
-
-    for (Standard_Integer aNorm = 0; aNorm < aPArray->num_vertexs; ++aNorm)
+    if (aSet->Normals.size() != aSet->Vertices.size())
     {
-      BVH_Vec4f aNormal;
-
-      // Note: In case of absence of normals, the
-      // renderer uses generated geometric normals
-
-      if (aPArray->vnormals != NULL)
+      for (Standard_Integer aVertIter = 0; aVertIter < anAttribs->NbElements; ++aVertIter)
       {
-        aNormal = BVH_Vec4f (aPArray->vnormals[aNorm].xyz[0],
-                             aPArray->vnormals[aNorm].xyz[1],
-                             aPArray->vnormals[aNorm].xyz[2],
-                             0.f);
-
-        if (theTransform)
-          aNormal = MatVecMult (theTransform, aNormal);
+        aSet->Normals.push_back (BVH_Vec4f());
       }
+    }
 
-      aSet->Normals.push_back (aNormal);
+    if (theTransform)
+    {
+      for (size_t aVertIter = aVertFrom; aVertIter < aSet->Vertices.size(); ++aVertIter)
+      {
+        BVH_Vec4f& aVertex = aSet->Vertices[aVertIter];
+        aVertex = MatVecMult (theTransform, aVertex);
+      }
+      for (size_t aVertIter = aVertFrom; aVertIter < aSet->Normals.size(); ++aVertIter)
+      {
+        BVH_Vec4f& aNorm = aSet->Normals[aVertIter];
+        aNorm = MatVecMult (theTransform, aNorm);
+      }
     }
 
-    if (aPArray->num_bounds > 0)
+    if (!aBounds.IsNull())
     {
   #ifdef RAY_TRACE_PRINT_INFO
       std::cout << "\tNumber of bounds = " << aPArray->num_bounds << std::endl;
   #endif
 
       Standard_Integer aBoundStart = 0;
-
-      for (Standard_Integer aBound = 0; aBound < aPArray->num_bounds; ++aBound)
+      for (Standard_Integer aBound = 0; aBound < aBounds->NbBounds; ++aBound)
       {
-        const Standard_Integer aVertNum = aPArray->bounds[aBound];
+        const Standard_Integer aVertNum = aBounds->Bounds[aBound];
 
   #ifdef RAY_TRACE_PRINT_INFO
         std::cout << "\tAdding indices from bound " << aBound << ": " <<
                                       aBoundStart << " .. " << aVertNum << std::endl;
   #endif
 
-        if (!AddRaytraceVertexIndices (aSet, aPArray, aBoundStart, aVertNum, theMatID))
+        if (!AddRaytraceVertexIndices (*aSet, *theArray, aBoundStart, aVertNum, theMatID))
         {
           delete aSet;
           return NULL;
@@ -556,13 +570,13 @@ OpenGl_TriangleSet* OpenGl_Workspace::AddRaytracePrimitiveArray (
     }
     else
     {
-      const Standard_Integer aVertNum = aPArray->num_edges > 0 ? aPArray->num_edges : aPArray->num_vertexs;
+      const Standard_Integer aVertNum = !anIndices.IsNull() ? anIndices->NbElements : anAttribs->NbElements;
 
   #ifdef RAY_TRACE_PRINT_INFO
         std::cout << "\tAdding indices from array: " << aVertNum << std::endl;
   #endif
 
-      if (!AddRaytraceVertexIndices (aSet, aPArray, 0, aVertNum, theMatID))
+      if (!AddRaytraceVertexIndices (*aSet, *theArray, 0, aVertNum, theMatID))
       {
         delete aSet;
         return NULL;
@@ -580,61 +594,55 @@ OpenGl_TriangleSet* OpenGl_Workspace::AddRaytracePrimitiveArray (
 // function : AddRaytraceVertexIndices
 // purpose  : Adds vertex indices to ray-traced scene geometry
 // =======================================================================
-Standard_Boolean OpenGl_Workspace::AddRaytraceVertexIndices (OpenGl_TriangleSet* theSet,
-  const CALL_DEF_PARRAY* theArray, Standard_Integer theOffset, Standard_Integer theCount, Standard_Integer theMatID)
+Standard_Boolean OpenGl_Workspace::AddRaytraceVertexIndices (OpenGl_TriangleSet&          theSet,
+                                                             const OpenGl_PrimitiveArray& theArray,
+                                                             Standard_Integer             theOffset,
+                                                             Standard_Integer             theCount,
+                                                             Standard_Integer             theMatID)
 {
-  switch (theArray->type)
+  switch (theArray.DrawMode())
   {
-    case TelTrianglesArrayType:
-      return AddRaytraceTriangleArray (theSet, theArray, theOffset, theCount, theMatID);
-
-    case TelQuadranglesArrayType:
-      return AddRaytraceQuadrangleArray (theSet, theArray, theOffset, theCount, theMatID);
-
-    case TelTriangleFansArrayType:
-      return AddRaytraceTriangleFanArray (theSet, theArray, theOffset, theCount, theMatID);
-
-    case TelTriangleStripsArrayType:
-      return AddRaytraceTriangleStripArray (theSet, theArray, theOffset, theCount, theMatID);
-
-    case TelQuadrangleStripsArrayType:
-      return AddRaytraceQuadrangleStripArray (theSet, theArray, theOffset, theCount, theMatID);
-
-    default:
-      return AddRaytracePolygonArray (theSet, theArray, theOffset, theCount, theMatID);
+    case GL_TRIANGLES:      return AddRaytraceTriangleArray        (theSet, theArray.Indices(), theOffset, theCount, theMatID);
+    case GL_QUADS:          return AddRaytraceQuadrangleArray      (theSet, theArray.Indices(), theOffset, theCount, theMatID);
+    case GL_TRIANGLE_FAN:   return AddRaytraceTriangleFanArray     (theSet, theArray.Indices(), theOffset, theCount, theMatID);
+    case GL_TRIANGLE_STRIP: return AddRaytraceTriangleStripArray   (theSet, theArray.Indices(), theOffset, theCount, theMatID);
+    case GL_QUAD_STRIP:     return AddRaytraceQuadrangleStripArray (theSet, theArray.Indices(), theOffset, theCount, theMatID);
+    case GL_POLYGON:        return AddRaytracePolygonArray         (theSet, theArray.Indices(), theOffset, theCount, theMatID);
   }
+  return Standard_False;
 }
 
 // =======================================================================
 // function : AddRaytraceTriangleArray
 // purpose  : Adds OpenGL triangle array to ray-traced scene geometry
 // =======================================================================
-Standard_Boolean OpenGl_Workspace::AddRaytraceTriangleArray (OpenGl_TriangleSet* theSet,
-  const CALL_DEF_PARRAY* theArray, Standard_Integer theOffset, Standard_Integer theCount, Standard_Integer theMatID)
+Standard_Boolean OpenGl_Workspace::AddRaytraceTriangleArray (OpenGl_TriangleSet&                  theSet,
+                                                             const Handle(Graphic3d_IndexBuffer)& theIndices,
+                                                             Standard_Integer                     theOffset,
+                                                             Standard_Integer                     theCount,
+                                                             Standard_Integer                     theMatID)
 {
   if (theCount < 3)
     return Standard_True;
 
-  theSet->Elements.reserve (theSet->Elements.size() + theCount / 3);
+  theSet.Elements.reserve (theSet.Elements.size() + theCount / 3);
 
-  if (theArray->num_edges > 0)
+  if (!theIndices.IsNull())
   {
     for (Standard_Integer aVert = theOffset; aVert < theOffset + theCount - 2; aVert += 3)
     {
-      theSet->Elements.push_back (BVH_Vec4i (theArray->edges[aVert + 0],
-                                             theArray->edges[aVert + 1],
-                                             theArray->edges[aVert + 2],
-                                             theMatID));
+      theSet.Elements.push_back (BVH_Vec4i (theIndices->Index (aVert + 0),
+                                            theIndices->Index (aVert + 1),
+                                            theIndices->Index (aVert + 2),
+                                            theMatID));
     }
   }
   else
   {
     for (Standard_Integer aVert = theOffset; aVert < theOffset + theCount - 2; aVert += 3)
     {
-      theSet->Elements.push_back (BVH_Vec4i (aVert + 0,
-                                             aVert + 1,
-                                             aVert + 2,
-                                             theMatID));
+      theSet.Elements.push_back (BVH_Vec4i (aVert + 0, aVert + 1, aVert + 2,
+                                            theMatID));
     }
   }
 
@@ -645,32 +653,35 @@ Standard_Boolean OpenGl_Workspace::AddRaytraceTriangleArray (OpenGl_TriangleSet*
 // function : AddRaytraceTriangleFanArray
 // purpose  : Adds OpenGL triangle fan array to ray-traced scene geometry
 // =======================================================================
-Standard_Boolean OpenGl_Workspace::AddRaytraceTriangleFanArray (OpenGl_TriangleSet* theSet,
-  const CALL_DEF_PARRAY* theArray, Standard_Integer theOffset, Standard_Integer theCount, Standard_Integer theMatID)
+Standard_Boolean OpenGl_Workspace::AddRaytraceTriangleFanArray (OpenGl_TriangleSet&                  theSet,
+                                                                const Handle(Graphic3d_IndexBuffer)& theIndices,
+                                                                Standard_Integer                     theOffset,
+                                                                Standard_Integer                     theCount,
+                                                                Standard_Integer                     theMatID)
 {
   if (theCount < 3)
     return Standard_True;
 
-  theSet->Elements.reserve (theSet->Elements.size() + theCount - 2);
+  theSet.Elements.reserve (theSet.Elements.size() + theCount - 2);
 
-  if (theArray->num_edges > 0)
+  if (!theIndices.IsNull())
   {
     for (Standard_Integer aVert = theOffset; aVert < theOffset + theCount - 2; ++aVert)
     {
-      theSet->Elements.push_back (BVH_Vec4i (theArray->edges[theOffset],
-                                             theArray->edges[aVert + 1],
-                                             theArray->edges[aVert + 2],
-                                             theMatID));
+      theSet.Elements.push_back (BVH_Vec4i (theIndices->Index (theOffset),
+                                            theIndices->Index (aVert + 1),
+                                            theIndices->Index (aVert + 2),
+                                            theMatID));
     }
   }
   else
   {
     for (Standard_Integer aVert = theOffset; aVert < theOffset + theCount - 2; ++aVert)
     {
-      theSet->Elements.push_back (BVH_Vec4i (theOffset,
-                                             aVert + 1,
-                                             aVert + 2,
-                                             theMatID));
+      theSet.Elements.push_back (BVH_Vec4i (theOffset,
+                                            aVert + 1,
+                                            aVert + 2,
+                                            theMatID));
     }
   }
 
@@ -681,32 +692,35 @@ Standard_Boolean OpenGl_Workspace::AddRaytraceTriangleFanArray (OpenGl_TriangleS
 // function : AddRaytraceTriangleStripArray
 // purpose  : Adds OpenGL triangle strip array to ray-traced scene geometry
 // =======================================================================
-Standard_Boolean OpenGl_Workspace::AddRaytraceTriangleStripArray (OpenGl_TriangleSet* theSet,
-  const CALL_DEF_PARRAY* theArray, Standard_Integer theOffset, Standard_Integer theCount, Standard_Integer theMatID)
+Standard_Boolean OpenGl_Workspace::AddRaytraceTriangleStripArray (OpenGl_TriangleSet&                  theSet,
+                                                                  const Handle(Graphic3d_IndexBuffer)& theIndices,
+                                                                  Standard_Integer                     theOffset,
+                                                                  Standard_Integer                     theCount,
+                                                                  Standard_Integer                     theMatID)
 {
   if (theCount < 3)
     return Standard_True;
 
-  theSet->Elements.reserve (theSet->Elements.size() + theCount - 2);
+  theSet.Elements.reserve (theSet.Elements.size() + theCount - 2);
 
-  if (theArray->num_edges > 0)
+  if (!theIndices.IsNull())
   {
     for (Standard_Integer aVert = theOffset, aCW = 0; aVert < theOffset + theCount - 2; ++aVert, aCW = (aCW + 1) % 2)
     {
-      theSet->Elements.push_back (BVH_Vec4i (theArray->edges[aVert + aCW ? 1 : 0],
-                                             theArray->edges[aVert + aCW ? 0 : 1],
-                                             theArray->edges[aVert + 2],
-                                             theMatID));
+      theSet.Elements.push_back (BVH_Vec4i (theIndices->Index (aVert + aCW ? 1 : 0),
+                                            theIndices->Index (aVert + aCW ? 0 : 1),
+                                            theIndices->Index (aVert + 2),
+                                            theMatID));
     }
   }
   else
   {
     for (Standard_Integer aVert = theOffset, aCW = 0; aVert < theOffset + theCount - 2; ++aVert, aCW = (aCW + 1) % 2)
     {
-      theSet->Elements.push_back (BVH_Vec4i (aVert + aCW ? 1 : 0,
-                                             aVert + aCW ? 0 : 1,
-                                             aVert + 2,
-                                             theMatID));
+      theSet.Elements.push_back (BVH_Vec4i (aVert + aCW ? 1 : 0,
+                                            aVert + aCW ? 0 : 1,
+                                            aVert + 2,
+                                            theMatID));
     }
   }
 
@@ -717,42 +731,39 @@ Standard_Boolean OpenGl_Workspace::AddRaytraceTriangleStripArray (OpenGl_Triangl
 // function : AddRaytraceQuadrangleArray
 // purpose  : Adds OpenGL quad array to ray-traced scene geometry
 // =======================================================================
-Standard_Boolean OpenGl_Workspace::AddRaytraceQuadrangleArray (OpenGl_TriangleSet* theSet,
-  const CALL_DEF_PARRAY* theArray, Standard_Integer theOffset, Standard_Integer theCount, Standard_Integer theMatID)
+Standard_Boolean OpenGl_Workspace::AddRaytraceQuadrangleArray (OpenGl_TriangleSet&                  theSet,
+                                                               const Handle(Graphic3d_IndexBuffer)& theIndices,
+                                                               Standard_Integer                     theOffset,
+                                                               Standard_Integer                     theCount,
+                                                               Standard_Integer                     theMatID)
 {
   if (theCount < 4)
     return Standard_True;
 
-  theSet->Elements.reserve (theSet->Elements.size() + theCount / 2);
+  theSet.Elements.reserve (theSet.Elements.size() + theCount / 2);
 
-  if (theArray->num_edges > 0)
+  if (!theIndices.IsNull())
   {
     for (Standard_Integer aVert = theOffset; aVert < theOffset + theCount - 3; aVert += 4)
     {
-      theSet->Elements.push_back (BVH_Vec4i (theArray->edges[aVert + 0],
-                                             theArray->edges[aVert + 1],
-                                             theArray->edges[aVert + 2],
-                                             theMatID));
-
-      theSet->Elements.push_back (BVH_Vec4i (theArray->edges[aVert + 0],
-                                             theArray->edges[aVert + 2],
-                                             theArray->edges[aVert + 3],
-                                             theMatID));
+      theSet.Elements.push_back (BVH_Vec4i (theIndices->Index (aVert + 0),
+                                            theIndices->Index (aVert + 1),
+                                            theIndices->Index (aVert + 2),
+                                            theMatID));
+      theSet.Elements.push_back (BVH_Vec4i (theIndices->Index (aVert + 0),
+                                            theIndices->Index (aVert + 2),
+                                            theIndices->Index (aVert + 3),
+                                            theMatID));
     }
   }
   else
   {
     for (Standard_Integer aVert = theOffset; aVert < theOffset + theCount - 3; aVert += 4)
     {
-      theSet->Elements.push_back (BVH_Vec4i (aVert + 0,
-                                             aVert + 1,
-                                             aVert + 2,
-                                             theMatID));
-
-      theSet->Elements.push_back (BVH_Vec4i (aVert + 0,
-                                             aVert + 2,
-                                             aVert + 3,
-                                             theMatID));
+      theSet.Elements.push_back (BVH_Vec4i (aVert + 0, aVert + 1, aVert + 2,
+                                            theMatID));
+      theSet.Elements.push_back (BVH_Vec4i (aVert + 0, aVert + 2, aVert + 3,
+                                            theMatID));
     }
   }
 
@@ -763,42 +774,45 @@ Standard_Boolean OpenGl_Workspace::AddRaytraceQuadrangleArray (OpenGl_TriangleSe
 // function : AddRaytraceQuadrangleStripArray
 // purpose  : Adds OpenGL quad strip array to ray-traced scene geometry
 // =======================================================================
-Standard_Boolean OpenGl_Workspace::AddRaytraceQuadrangleStripArray (OpenGl_TriangleSet* theSet,
-  const CALL_DEF_PARRAY* theArray, Standard_Integer theOffset, Standard_Integer theCount, Standard_Integer theMatID)
+Standard_Boolean OpenGl_Workspace::AddRaytraceQuadrangleStripArray (OpenGl_TriangleSet&                  theSet,
+                                                                    const Handle(Graphic3d_IndexBuffer)& theIndices,
+                                                                    Standard_Integer                     theOffset,
+                                                                    Standard_Integer                     theCount,
+                                                                    Standard_Integer                     theMatID)
 {
   if (theCount < 4)
     return Standard_True;
 
-  theSet->Elements.reserve (theSet->Elements.size() + 2 * theCount - 6);
+  theSet.Elements.reserve (theSet.Elements.size() + 2 * theCount - 6);
 
-  if (theArray->num_edges > 0)
+  if (!theIndices.IsNull())
   {
     for (Standard_Integer aVert = theOffset; aVert < theOffset + theCount - 3; aVert += 2)
     {
-      theSet->Elements.push_back (BVH_Vec4i (theArray->edges[aVert + 0],
-                                             theArray->edges[aVert + 1],
-                                             theArray->edges[aVert + 2],
-                                             theMatID));
-
-      theSet->Elements.push_back (BVH_Vec4i (theArray->edges[aVert + 1],
-                                             theArray->edges[aVert + 3],
-                                             theArray->edges[aVert + 2],
-                                             theMatID));
+      theSet.Elements.push_back (BVH_Vec4i (theIndices->Index (aVert + 0),
+                                            theIndices->Index (aVert + 1),
+                                            theIndices->Index (aVert + 2),
+                                            theMatID));
+
+      theSet.Elements.push_back (BVH_Vec4i (theIndices->Index (aVert + 1),
+                                            theIndices->Index (aVert + 3),
+                                            theIndices->Index (aVert + 2),
+                                            theMatID));
     }
   }
   else
   {
     for (Standard_Integer aVert = theOffset; aVert < theOffset + theCount - 3; aVert += 2)
     {
-      theSet->Elements.push_back (BVH_Vec4i (aVert + 0,
-                                             aVert + 1,
-                                             aVert + 2,
-                                             theMatID));
-
-      theSet->Elements.push_back (BVH_Vec4i (aVert + 1,
-                                             aVert + 3,
-                                             aVert + 2,
-                                             theMatID));
+      theSet.Elements.push_back (BVH_Vec4i (aVert + 0,
+                                            aVert + 1,
+                                            aVert + 2,
+                                            theMatID));
+
+      theSet.Elements.push_back (BVH_Vec4i (aVert + 1,
+                                            aVert + 3,
+                                            aVert + 2,
+                                            theMatID));
     }
   }
 
@@ -809,32 +823,35 @@ Standard_Boolean OpenGl_Workspace::AddRaytraceQuadrangleStripArray (OpenGl_Trian
 // function : AddRaytracePolygonArray
 // purpose  : Adds OpenGL polygon array to ray-traced scene geometry
 // =======================================================================
-Standard_Boolean OpenGl_Workspace::AddRaytracePolygonArray (OpenGl_TriangleSet* theSet,
-  const CALL_DEF_PARRAY* theArray, Standard_Integer theOffset, Standard_Integer theCount, Standard_Integer theMatID)
+Standard_Boolean OpenGl_Workspace::AddRaytracePolygonArray (OpenGl_TriangleSet&                  theSet,
+                                                            const Handle(Graphic3d_IndexBuffer)& theIndices,
+                                                            Standard_Integer                     theOffset,
+                                                            Standard_Integer                     theCount,
+                                                            Standard_Integer                     theMatID)
 {
   if (theCount < 3)
     return Standard_True;
 
-  theSet->Elements.reserve (theSet->Elements.size() + theCount - 2);
+  theSet.Elements.reserve (theSet.Elements.size() + theCount - 2);
 
-  if (theArray->num_edges > 0)
+  if (!theIndices.IsNull())
   {
     for (Standard_Integer aVert = theOffset; aVert < theOffset + theCount - 2; ++aVert)
     {
-      theSet->Elements.push_back (BVH_Vec4i (theArray->edges[theOffset],
-                                             theArray->edges[aVert + 1],
-                                             theArray->edges[aVert + 2],
-                                             theMatID));
+      theSet.Elements.push_back (BVH_Vec4i (theIndices->Index (theOffset),
+                                            theIndices->Index (aVert + 1),
+                                            theIndices->Index (aVert + 2),
+                                            theMatID));
     }
   }
   else
   {
     for (Standard_Integer aVert = theOffset; aVert < theOffset + theCount - 2; ++aVert)
     {
-      theSet->Elements.push_back (BVH_Vec4i (theOffset,
-                                             aVert + 1,
-                                             aVert + 2,
-                                             theMatID));
+      theSet.Elements.push_back (BVH_Vec4i (theOffset,
+                                            aVert + 1,
+                                            aVert + 2,
+                                            theMatID));
     }
   }
 
index 4c8adf4..ff58503 100644 (file)
@@ -95,7 +95,7 @@ namespace
     TopLoc_Location aLoc;
     gp_Pnt p;
     Standard_Integer decal;
-    Standard_Integer t[3], n[3];
+    Standard_Integer n[3];
     Standard_Integer nbTriangles = 0, nbVertices = 0;
     Standard_Real    aUmin (0.0), aUmax (0.0), aVmin (0.0), aVmax (0.0), dUmax (0.0), dVmax (0.0);
 
@@ -132,9 +132,8 @@ namespace
       return Standard_False;
     }
 
-    Handle(Graphic3d_ArrayOfTriangles) aPArray
-      = new Graphic3d_ArrayOfTriangles (nbVertices, 3 * nbTriangles,
-                                        Standard_True, Standard_False, theHasTexels, Standard_True);
+    Handle(Graphic3d_ArrayOfTriangles) aPArray = new Graphic3d_ArrayOfTriangles (nbVertices, 3 * nbTriangles,
+                                                                                 Standard_True, Standard_False, theHasTexels);
     for (SST.Init (theShape); SST.MoreFace(); SST.NextFace())
     {
       const TopoDS_Face& aFace = SST.CurrentFace();
@@ -184,7 +183,6 @@ namespace
       const Poly_Array1OfTriangle& aTriangles = T->Triangles();
       for (Standard_Integer aTriIter = 1; aTriIter <= T->NbTriangles(); ++aTriIter)
       {
-        pc.Triangles (aTriIter, t[0], t[1], t[2]);
         if (SST.Orientation (aFace) == TopAbs_REVERSED)
           aTriangles (aTriIter).Get (n[0], n[2], n[1]);
         else
@@ -214,9 +212,9 @@ namespace
         V1.Cross (V2);
         if (V1.SquareMagnitude() > aPreci)
         {
-          aPArray->AddEdge (n[0] + decal, t[0] == 0);
-          aPArray->AddEdge (n[1] + decal, t[1] == 0);
-          aPArray->AddEdge (n[2] + decal, t[2] == 0);
+          aPArray->AddEdge (n[0] + decal);
+          aPArray->AddEdge (n[1] + decal);
+          aPArray->AddEdge (n[2] + decal);
         }
       }
     }
index 833dd02..f306fef 100644 (file)
@@ -3186,8 +3186,8 @@ void MyPArrayObject::Compute (const Handle(PrsMgr_PresentationManager3d)& /*aPre
 
   // Parsing array description
   Standard_Integer aVertexNum = 0, aBoundNum = 0, aEdgeNum = 0;
-  Standard_Boolean hasVColors, hasBColors, hasNormals, hasInfos, hasTexels;
-  hasVColors = hasNormals = hasBColors = hasInfos = hasTexels = Standard_False;
+  Standard_Boolean hasVColors, hasBColors, hasNormals, hasTexels;
+  hasVColors = hasNormals = hasBColors = hasTexels = Standard_False;
 
   Standard_Integer anArgIndex = 0;
   Standard_Integer anArgsCount = myArrayDescription->Length();
@@ -3228,10 +3228,6 @@ void MyPArrayObject::Compute (const Handle(PrsMgr_PresentationManager3d)& /*aPre
     // edge command
     else if (CheckInputCommand ("e", myArrayDescription, anArgIndex, 1, anArgsCount))
     {
-      // edge has a hide flag
-      if (CheckInputCommand ("h", myArrayDescription, anArgIndex, 0, anArgsCount))
-        hasInfos = Standard_True;
-
       aEdgeNum++;
     }
     // unknown command
@@ -3248,10 +3244,10 @@ void MyPArrayObject::Compute (const Handle(PrsMgr_PresentationManager3d)& /*aPre
     anArray = new Graphic3d_ArrayOfSegments (aVertexNum, aEdgeNum, hasVColors);
   else if (anArrayType == "polylines")
     anArray = new Graphic3d_ArrayOfPolylines (aVertexNum, aBoundNum, aEdgeNum,
-                                              hasVColors, hasBColors, hasInfos);
+                                              hasVColors, hasBColors);
   else if (anArrayType == "triangles")
     anArray = new Graphic3d_ArrayOfTriangles (aVertexNum, aEdgeNum, hasNormals,
-                                              hasVColors, hasTexels, hasInfos);
+                                              hasVColors, hasTexels);
   else if (anArrayType == "trianglefans")
     anArray = new Graphic3d_ArrayOfTriangleFans (aVertexNum, aBoundNum,
                                                  hasNormals, hasVColors,
@@ -3263,7 +3259,7 @@ void MyPArrayObject::Compute (const Handle(PrsMgr_PresentationManager3d)& /*aPre
   else if (anArrayType == "quads")
     anArray = new Graphic3d_ArrayOfQuadrangles (aVertexNum, aEdgeNum,
                                                 hasNormals, hasVColors,
-                                                hasTexels, hasInfos);
+                                                hasTexels);
   else if (anArrayType == "quadstrips")
     anArray = new Graphic3d_ArrayOfQuadrangleStrips (aVertexNum, aBoundNum,
                                                      hasNormals, hasVColors,
@@ -3271,7 +3267,7 @@ void MyPArrayObject::Compute (const Handle(PrsMgr_PresentationManager3d)& /*aPre
   else if (anArrayType == "polygons")
     anArray = new Graphic3d_ArrayOfPolygons (aVertexNum, aBoundNum, aEdgeNum,
                                              hasNormals, hasVColors, hasBColors,
-                                             hasTexels, hasInfos);
+                                             hasTexels);
 
   anArgIndex = 1;
   while (anArgIndex < anArgsCount)
@@ -3287,22 +3283,23 @@ void MyPArrayObject::Compute (const Handle(PrsMgr_PresentationManager3d)& /*aPre
       anArray->AddVertex (myArrayDescription->Value (anArgIndex - 3).RealValue(),
                           myArrayDescription->Value (anArgIndex - 2).RealValue(),
                           myArrayDescription->Value (anArgIndex - 1).RealValue());
+      const Standard_Integer aVertIndex = anArray->VertexNumber();
 
       // vertex has a normal or normal with color or texel
       if (CheckInputCommand ("n", myArrayDescription, anArgIndex, 3, anArgsCount))
-        anArray->SetVertexNormal (anArray->VertexNumber (),
+        anArray->SetVertexNormal (aVertIndex,
                                   myArrayDescription->Value (anArgIndex - 3).RealValue(),
                                   myArrayDescription->Value (anArgIndex - 2).RealValue(),
                                   myArrayDescription->Value (anArgIndex - 1).RealValue());
       
       if (CheckInputCommand ("c", myArrayDescription, anArgIndex, 3, anArgsCount))
-        anArray->SetVertexColor (anArray->VertexNumber (),
+        anArray->SetVertexColor (aVertIndex,
                                  myArrayDescription->Value (anArgIndex - 3).RealValue(),
                                  myArrayDescription->Value (anArgIndex - 2).RealValue(),
                                  myArrayDescription->Value (anArgIndex - 1).RealValue());
       
       if (CheckInputCommand ("t", myArrayDescription, anArgIndex, 2, anArgsCount))
-        anArray->SetVertexTexel (anArray->VertexNumber (),
+        anArray->SetVertexTexel (aVertIndex,
                                  myArrayDescription->Value (anArgIndex - 2).RealValue(),
                                  myArrayDescription->Value (anArgIndex - 1).RealValue());
     }
@@ -3323,13 +3320,8 @@ void MyPArrayObject::Compute (const Handle(PrsMgr_PresentationManager3d)& /*aPre
     // edge command
     else if (CheckInputCommand ("e", myArrayDescription, anArgIndex, 1, anArgsCount))
     {
-      Standard_Integer aVertIndex = myArrayDescription->Value (anArgIndex - 1).IntegerValue();
-
-      // edge has/hasn't hide flag
-      if (CheckInputCommand ("h", myArrayDescription, anArgIndex, 0, anArgsCount))
-        anArray->AddEdge (aVertIndex, Standard_False);
-      else
-        anArray->AddEdge (aVertIndex, Standard_True);
+      const Standard_Integer aVertIndex = myArrayDescription->Value (anArgIndex - 1).IntegerValue();
+      anArray->AddEdge (aVertIndex);
     }
     // unknown command
     else
@@ -3420,7 +3412,7 @@ static int VDrawPArray (Draw_Interpretor& di, Standard_Integer argc, const char*
        << "  vertex={ 'v' x y z [normal={ 'n' nx ny nz }] [color={ 'c' r g b }]"
        << " [texel={ 't' tx ty }] } \n"
        << "  bounds={ 'b' verticies_count [color={ 'c' r g b }] }\n"
-       << "  edges={ 'e' vertex_id [hidden_edge={'h'}] }\n";
+       << "  edges={ 'e' vertex_id }\n";
     return 1;
   }
 
@@ -5120,7 +5112,7 @@ void ViewerTest::ObjectCommands(Draw_Interpretor& theCommands)
     __FILE__, VComputeHLR, group);
 
   theCommands.Add("vdrawparray",
-    "vdrawparray : vdrawparray Name TypeOfArray [vertex = { 'v' x y z [vertex_normal = { 'n' x y z }] [vertex_color = { 'c' r g b }] ] ... [bound = { 'b' vertex_count [bound_color = { 'c' r g b }] ] ... [edge = { 'e' vertex_id [edge_hidden = { 'h' }] ]",
+    "vdrawparray : vdrawparray Name TypeOfArray [vertex = { 'v' x y z [vertex_normal = { 'n' x y z }] [vertex_color = { 'c' r g b }] ] ... [bound = { 'b' vertex_count [bound_color = { 'c' r g b }] ] ... [edge = { 'e' vertex_id ]",
     __FILE__,VDrawPArray,group);
 
   theCommands.Add("vconnect",