0030239: Visualization, Graphic3d_ArrayOfPrimitives - pass Graphic3d_ArrayFlags bitma...
[occt.git] / src / Graphic3d / Graphic3d_ArrayOfPrimitives.hxx
1 // Created on: 2000-06-16
2 // Copyright (c) 2000-2014 OPEN CASCADE SAS
3 //
4 // This file is part of Open CASCADE Technology software library.
5 //
6 // This library is free software; you can redistribute it and/or modify it under
7 // the terms of the GNU Lesser General Public License version 2.1 as published
8 // by the Free Software Foundation, with special exception defined in the file
9 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
10 // distribution for complete text of the license and disclaimer of any warranty.
11 //
12 // Alternatively, this file may be used under the terms of Open CASCADE
13 // commercial license or contractual agreement.
14
15 #ifndef _Graphic3d_ArrayOfPrimitives_HeaderFile
16 #define _Graphic3d_ArrayOfPrimitives_HeaderFile
17
18 #include <Graphic3d_BoundBuffer.hxx>
19 #include <Graphic3d_ArrayFlags.hxx>
20 #include <Graphic3d_Buffer.hxx>
21 #include <Graphic3d_IndexBuffer.hxx>
22 #include <Graphic3d_TypeOfPrimitiveArray.hxx>
23 #include <gp_Dir.hxx>
24 #include <gp_Pnt.hxx>
25 #include <Standard_OutOfRange.hxx>
26 #include <Quantity_Color.hxx>
27
28 class Graphic3d_ArrayOfPrimitives;
29 DEFINE_STANDARD_HANDLE(Graphic3d_ArrayOfPrimitives, Standard_Transient)
30
31 //! This class furnish services to defined and fill an array of primitives
32 //! which can be passed directly to graphics rendering API.
33 //!
34 //! The basic interface consists of the following parts:
35 //! 1) Specifying primitive type.
36 //!    WARNING! Particular primitive types might be unsupported by specific hardware/graphics API (like quads and polygons).
37 //!             It is always preferred using one of basic types having maximum compatibility:
38 //!             Point, Triangle (or Triangle strip), Segment aka Lines (or Polyline aka Line Strip).
39 //!    Primitive strip types can be used to reduce memory usage as alternative to Indexed arrays.
40 //! 2) Vertex array.
41 //!    - Specifying the (maximum) number of vertexes within array.
42 //!    - Specifying the vertex attributes, complementary to mandatory vertex Position (normal, color, UV texture coordinates).
43 //!    - Defining vertex values by using various versions of AddVertex() or SetVertex*() methods.
44 //! 3) Index array (optional).
45 //!    - Specifying the (maximum) number of indexes (edges).
46 //!    - Defining index values by using AddEdge() method; the index value should be within number of defined Vertexes.
47 //!
48 //!    Indexed array allows sharing vertex data across Primitives and thus reducing memory usage,
49 //!    since index size is much smaller then size of vertex with all its attributes.
50 //!    It is a preferred way for defining primitive array and main alternative to Primitive Strips for optimal memory usage,
51 //!    although it is also possible (but unusual) defining Indexed Primitive Strip.
52 //!    Note that it is NOT possible sharing Vertex Attributes partially (e.g. share Position, but have different Normals);
53 //!    in such cases Vertex should be entirely duplicated with all Attributes.
54 //! 4) Bounds array (optional).
55 //!    - Specifying the (maximum) number of bounds.
56 //!    - Defining bounds using AddBound() methods.
57 //!
58 //!    Bounds allow splitting Primitive Array into sub-groups.
59 //!    This is useful only in two cases - for specifying per-group color and for restarting Primitive Strips.
60 //!    WARNING! Bounds within Primitive Array break rendering batches into parts (additional for loops),
61 //!             affecting rendering performance negatively (increasing CPU load).
62 class Graphic3d_ArrayOfPrimitives : public Standard_Transient
63 {
64   DEFINE_STANDARD_RTTIEXT(Graphic3d_ArrayOfPrimitives, Standard_Transient)
65 public:
66
67   //! Destructor.
68   Standard_EXPORT virtual ~Graphic3d_ArrayOfPrimitives();
69
70   //! Returns vertex attributes buffer (colors, normals, texture coordinates).
71   const Handle(Graphic3d_Buffer)& Attributes() const { return myAttribs; }
72
73   //! Returns the type of this primitive
74   Graphic3d_TypeOfPrimitiveArray Type() const { return myType; }
75
76   //! Returns the string type of this primitive
77   Standard_EXPORT Standard_CString StringType() const;
78
79   //! Returns TRUE when vertex normals array is defined.
80   Standard_Boolean HasVertexNormals() const { return myVNor != 0; }
81
82   //! Returns TRUE when vertex colors array is defined.
83   Standard_Boolean HasVertexColors() const { return myVCol != 0; }
84
85   //! Returns TRUE when vertex texels array is defined.
86   Standard_Boolean HasVertexTexels() const { return myVTex != 0; }
87
88   //! Returns the number of defined vertex
89   Standard_Integer VertexNumber() const { return myAttribs->NbElements; }
90
91   //! Returns the number of allocated vertex
92   Standard_Integer VertexNumberAllocated() const { return myAttribs->NbMaxElements(); }
93
94   //! Returns the number of total items according to the array type.
95   Standard_EXPORT Standard_Integer ItemNumber() const;
96
97   //! Returns TRUE only when the contains of this array is available.
98   Standard_EXPORT Standard_Boolean IsValid();
99
100   //! Adds a vertice in the array.
101   //! @return the actual vertex number
102   Standard_Integer AddVertex (const gp_Pnt& theVertex) { return AddVertex (theVertex.X(), theVertex.Y(), theVertex.Z()); }
103
104   //! Adds a vertice in the array.
105   //! @return the actual vertex number
106   Standard_Integer AddVertex (const Graphic3d_Vec3& theVertex) { return AddVertex (theVertex.x(), theVertex.y(), theVertex.z()); }
107
108   //! Adds a vertice in the array.
109   //! @return the actual vertex number
110   Standard_Integer AddVertex (const Standard_Real theX, const Standard_Real theY, const Standard_Real theZ)
111   {
112     return AddVertex (RealToShortReal (theX), RealToShortReal (theY), RealToShortReal (theZ));
113   }
114
115   //! Adds a vertice in the array.
116   //! @return the actual vertex number.
117   Standard_Integer AddVertex (const Standard_ShortReal theX, const Standard_ShortReal theY, const Standard_ShortReal theZ)
118   {
119     const Standard_Integer anIndex = myAttribs->NbElements + 1;
120     SetVertice (anIndex, theX, theY, theZ);
121     return anIndex;
122   }
123
124   //! Adds a vertice and vertex color in the vertex array.
125   //! Warning: theColor is ignored when the hasVColors constructor parameter is FALSE
126   //! @return the actual vertex number
127   Standard_Integer AddVertex (const gp_Pnt& theVertex, const Quantity_Color& theColor)
128   {
129     const Standard_Integer anIndex = AddVertex (theVertex);
130     SetVertexColor (anIndex, theColor.Red(), theColor.Green(), theColor.Blue());
131     return anIndex;
132   }
133
134   //! Adds a vertice and vertex color in the vertex array.
135   //! Warning: theColor is ignored when the hasVColors constructor parameter is FALSE
136   //! @code
137   //!   theColor32 = Alpha << 24 + Blue << 16 + Green << 8 + Red
138   //! @endcode
139   //! @return the actual vertex number
140   Standard_Integer AddVertex (const gp_Pnt& theVertex, const Standard_Integer theColor32)
141   {
142     const Standard_Integer anIndex = AddVertex (theVertex);
143     SetVertexColor (anIndex, theColor32);
144     return anIndex;
145   }
146
147   //! Adds a vertice and vertex color in the vertex array.
148   //! Warning: theColor is ignored when the hasVColors constructor parameter is FALSE
149   //! @return the actual vertex number
150   Standard_Integer AddVertex (const gp_Pnt&           theVertex,
151                               const Graphic3d_Vec4ub& theColor)
152   {
153     const Standard_Integer anIndex = AddVertex (theVertex);
154     SetVertexColor (anIndex, theColor);
155     return anIndex;
156   }
157
158   //! Adds a vertice and vertex normal in the vertex array.
159   //! Warning: theNormal is ignored when the hasVNormals constructor parameter is FALSE.
160   //! @return the actual vertex number
161   Standard_Integer AddVertex (const gp_Pnt& theVertex, const gp_Dir& theNormal)
162   {
163     return AddVertex (theVertex.X(), theVertex.Y(), theVertex.Z(),
164                       theNormal.X(), theNormal.Y(), theNormal.Z());
165   }
166
167   //! Adds a vertice and vertex normal in the vertex array.
168   //! Warning: Normal is ignored when the hasVNormals constructor parameter is FALSE.
169   //! @return the actual vertex number
170   Standard_Integer AddVertex (const Standard_Real theX,  const Standard_Real theY,  const Standard_Real theZ,
171                               const Standard_Real theNX, const Standard_Real theNY, const Standard_Real theNZ)
172   {
173     return AddVertex (RealToShortReal (theX),  RealToShortReal (theY),  RealToShortReal (theZ),
174                       Standard_ShortReal (theNX), Standard_ShortReal (theNY), Standard_ShortReal (theNZ));
175   }
176
177   //! Adds a vertice and vertex normal in the vertex array.
178   //! Warning: Normal is ignored when the hasVNormals constructor parameter is FALSE.
179   //! @return the actual vertex number
180   Standard_Integer AddVertex (const Standard_ShortReal theX,  const Standard_ShortReal theY,  const Standard_ShortReal theZ,
181                               const Standard_ShortReal theNX, const Standard_ShortReal theNY, const Standard_ShortReal theNZ)
182   {
183     const Standard_Integer anIndex = myAttribs->NbElements + 1;
184     SetVertice      (anIndex, theX,  theY,  theZ);
185     SetVertexNormal (anIndex, theNX, theNY, theNZ);
186     return anIndex;
187   }
188
189   //! Adds a vertice,vertex normal and color in the vertex array.
190   //! Warning: theNormal is ignored when the hasVNormals constructor parameter is FALSE
191   //! and      theColor  is ignored when the hasVColors  constructor parameter is FALSE.
192   //! @return the actual vertex number
193   Standard_Integer AddVertex (const gp_Pnt& theVertex, const gp_Dir& theNormal, const Quantity_Color& theColor)
194   {
195     const Standard_Integer anIndex = AddVertex (theVertex, theNormal);
196     SetVertexColor (anIndex, theColor.Red(), theColor.Green(), theColor.Blue());
197     return anIndex;
198   }
199
200   //! Adds a vertice,vertex normal and color in the vertex array.
201   //! Warning: theNormal is ignored when the hasVNormals constructor parameter is FALSE
202   //! and      theColor  is ignored when the hasVColors  constructor parameter is FALSE.
203   //! @code
204   //!   theColor32 = Alpha << 24 + Blue << 16 + Green << 8 + Red
205   //! @endcode
206   //! @return the actual vertex number
207   Standard_Integer AddVertex (const gp_Pnt& theVertex, const gp_Dir& theNormal, const Standard_Integer theColor32)
208   {
209     const Standard_Integer anIndex = AddVertex (theVertex, theNormal);
210     SetVertexColor (anIndex, theColor32);
211     return anIndex;
212   }
213
214   //! Adds a vertice and vertex texture in the vertex array.
215   //! theTexel is ignored when the hasVTexels constructor parameter is FALSE.
216   //! @return the actual vertex number
217   Standard_Integer AddVertex (const gp_Pnt& theVertex, const gp_Pnt2d& theTexel)
218   {
219     return AddVertex (theVertex.X(), theVertex.Y(), theVertex.Z(),
220                       theTexel.X(), theTexel.Y());
221   }
222
223   //! Adds a vertice and vertex texture coordinates in the vertex array.
224   //! Texel is ignored when the hasVTexels constructor parameter is FALSE.
225   //! @return the actual vertex number
226   Standard_Integer AddVertex (const Standard_Real theX, const Standard_Real theY, const Standard_Real theZ,
227                               const Standard_Real theTX, const Standard_Real theTY)
228   {
229     return AddVertex (RealToShortReal (theX),  RealToShortReal (theY),  RealToShortReal (theZ),
230                       Standard_ShortReal (theTX), Standard_ShortReal (theTY));
231   }
232
233   //! Adds a vertice and vertex texture coordinates in the vertex array.
234   //! Texel is ignored when the hasVTexels constructor parameter is FALSE.
235   //! @return the actual vertex number
236   Standard_Integer AddVertex (const Standard_ShortReal theX, const Standard_ShortReal theY, const Standard_ShortReal theZ,
237                               const Standard_ShortReal theTX, const Standard_ShortReal theTY)
238   {
239     const Standard_Integer anIndex = myAttribs->NbElements + 1;
240     SetVertice     (anIndex, theX, theY, theZ);
241     SetVertexTexel (anIndex, theTX, theTY);
242     return anIndex;
243   }
244
245   //! Adds a vertice,vertex normal and texture in the vertex array.
246   //! Warning: theNormal is ignored when the hasVNormals constructor parameter is FALSE
247   //! and      theTexel  is ignored when the hasVTexels  constructor parameter is FALSE.
248   //! @return the actual vertex number
249   Standard_Integer AddVertex (const gp_Pnt& theVertex, const gp_Dir& theNormal, const gp_Pnt2d& theTexel)
250   {
251     return AddVertex (theVertex.X(), theVertex.Y(), theVertex.Z(),
252                       theNormal.X(), theNormal.Y(), theNormal.Z(),
253                       theTexel.X(),  theTexel.Y());
254   }
255
256   //! Adds a vertice,vertex normal and texture in the vertex array.
257   //! Warning: Normal is ignored when the hasVNormals constructor parameter is FALSE
258   //! and      Texel  is ignored when the hasVTexels  constructor parameter is FALSE.
259   //! @return the actual vertex number
260   Standard_Integer AddVertex (const Standard_Real theX,  const Standard_Real theY,  const Standard_Real theZ,
261                               const Standard_Real theNX, const Standard_Real theNY, const Standard_Real theNZ,
262                               const Standard_Real theTX, const Standard_Real theTY)
263   {
264     return AddVertex (RealToShortReal (theX), RealToShortReal (theY), RealToShortReal (theZ),
265                       Standard_ShortReal (theNX), Standard_ShortReal (theNY), Standard_ShortReal (theNZ),
266                       Standard_ShortReal (theTX), Standard_ShortReal (theTY));
267   }
268
269   //! Adds a vertice,vertex normal and texture in the vertex array.
270   //! Warning: Normal is ignored when the hasVNormals constructor parameter is FALSE
271   //!     and  Texel  is ignored when the hasVTexels  constructor parameter is FALSE.
272   //! @return the actual vertex number
273   Standard_Integer AddVertex (const Standard_ShortReal theX,  const Standard_ShortReal theY,  const Standard_ShortReal theZ,
274                               const Standard_ShortReal theNX, const Standard_ShortReal theNY, const Standard_ShortReal theNZ,
275                               const Standard_ShortReal theTX, const Standard_ShortReal theTY)
276   {
277     const Standard_Integer anIndex = myAttribs->NbElements + 1;
278     SetVertice     (anIndex, theX,  theY,  theZ);
279     SetVertexNormal(anIndex, theNX, theNY, theNZ);
280     SetVertexTexel (anIndex, theTX, theTY);
281     return anIndex;
282   }
283
284   //! Change the vertice of rank theIndex in the array.
285   void SetVertice (const Standard_Integer theIndex, const gp_Pnt& theVertex)
286   {
287     SetVertice (theIndex, Standard_ShortReal (theVertex.X()), Standard_ShortReal (theVertex.Y()), Standard_ShortReal (theVertex.Z()));
288   }
289
290   //! Change the vertice of rank theIndex in the array.
291   void SetVertice (const Standard_Integer theIndex, const Standard_ShortReal theX, const Standard_ShortReal theY, const Standard_ShortReal theZ)
292   {
293     Standard_OutOfRange_Raise_if (theIndex < 1 || theIndex > myAttribs->NbMaxElements(), "BAD VERTEX index");
294     Graphic3d_Vec3& aVec = myAttribs->ChangeValue<Graphic3d_Vec3> (theIndex - 1);
295     aVec.x() = theX;
296     aVec.y() = theY;
297     aVec.z() = theZ;
298     if (myAttribs->NbElements < theIndex)
299     {
300       myAttribs->NbElements = theIndex;
301     }
302   }
303
304   //! Change the vertex color of rank theIndex in the array.
305   void SetVertexColor (const Standard_Integer theIndex, const Quantity_Color& theColor)
306   {
307     SetVertexColor (theIndex, theColor.Red(), theColor.Green(), theColor.Blue());
308   }
309
310   //! Change the vertex color of rank theIndex in the array.
311   void SetVertexColor (const Standard_Integer theIndex, const Standard_Real theR, const Standard_Real theG, const Standard_Real theB)
312   {
313     Standard_OutOfRange_Raise_if (theIndex < 1 || theIndex > myAttribs->NbMaxElements(), "BAD VERTEX index");
314     if (myVCol != 0)
315     {
316       Graphic3d_Vec4ub *aColorPtr = 
317         reinterpret_cast<Graphic3d_Vec4ub* >(myAttribs->changeValue (theIndex - 1) + size_t(myVCol));
318       aColorPtr->SetValues (Standard_Byte(theR * 255.0),
319                             Standard_Byte(theG * 255.0),
320                             Standard_Byte(theB * 255.0), 255);
321     }
322     myAttribs->NbElements = Max (theIndex, myAttribs->NbElements);
323   }
324
325   //! Change the vertex color of rank theIndex in the array.
326   void SetVertexColor (const Standard_Integer  theIndex,
327                        const Graphic3d_Vec4ub& theColor)
328   {
329     Standard_OutOfRange_Raise_if (theIndex < 1 || theIndex > myAttribs->NbMaxElements(), "BAD VERTEX index");
330     if (myVCol != 0)
331     {
332       Graphic3d_Vec4ub *aColorPtr = 
333         reinterpret_cast<Graphic3d_Vec4ub* >(myAttribs->changeValue (theIndex - 1) + size_t(myVCol));
334       (*aColorPtr) = theColor;
335     }
336     myAttribs->NbElements = Max (theIndex, myAttribs->NbElements);
337   }
338
339   //! Change the vertex color of rank theIndex> in the array.
340   //! @code
341   //!   theColor32 = Alpha << 24 + Blue << 16 + Green << 8 + Red
342   //! @endcode
343   void SetVertexColor (const Standard_Integer theIndex, const Standard_Integer theColor32)
344   {
345     Standard_OutOfRange_Raise_if (theIndex < 1 || theIndex > myAttribs->NbMaxElements(), "BAD VERTEX index");
346     if (myVCol != 0)
347     {
348       *reinterpret_cast<Standard_Integer* >(myAttribs->changeValue (theIndex - 1) + size_t(myVCol)) = theColor32;
349     }
350   }
351
352   //! Change the vertex normal of rank theIndex in the array.
353   void SetVertexNormal (const Standard_Integer theIndex, const gp_Dir& theNormal)
354   {
355     SetVertexNormal (theIndex, theNormal.X(), theNormal.Y(), theNormal.Z());
356   }
357
358   //! Change the vertex normal of rank theIndex in the array.
359   void SetVertexNormal (const Standard_Integer theIndex, const Standard_Real theNX, const Standard_Real theNY, const Standard_Real theNZ)
360   {
361     Standard_OutOfRange_Raise_if (theIndex < 1 || theIndex > myAttribs->NbMaxElements(), "BAD VERTEX index");
362     if (myVNor != 0)
363     {
364       Graphic3d_Vec3& aVec = *reinterpret_cast<Graphic3d_Vec3* >(myAttribs->changeValue (theIndex - 1) + size_t(myVNor));
365       aVec.x() = Standard_ShortReal (theNX);
366       aVec.y() = Standard_ShortReal (theNY);
367       aVec.z() = Standard_ShortReal (theNZ);
368     }
369     myAttribs->NbElements = Max (theIndex, myAttribs->NbElements);
370   }
371
372   //! Change the vertex texel of rank theIndex in the array.
373   void SetVertexTexel (const Standard_Integer theIndex, const gp_Pnt2d& theTexel)
374   {
375     SetVertexTexel (theIndex, theTexel.X(), theTexel.Y());
376   }
377
378   //! Change the vertex texel of rank theIndex in the array.
379   void SetVertexTexel (const Standard_Integer theIndex, const Standard_Real theTX, const Standard_Real theTY)
380   {
381     Standard_OutOfRange_Raise_if (theIndex < 1 || theIndex > myAttribs->NbMaxElements(), "BAD VERTEX index");
382     if (myVTex != 0)
383     {
384       Graphic3d_Vec2& aVec = *reinterpret_cast<Graphic3d_Vec2* >(myAttribs->changeValue (theIndex - 1) + size_t(myVTex));
385       aVec.x() = Standard_ShortReal (theTX);
386       aVec.y() = Standard_ShortReal (theTY);
387     }
388     myAttribs->NbElements = Max (theIndex, myAttribs->NbElements);
389   }
390
391   //! Returns the vertice at rank theRank from the vertex table if defined.
392   gp_Pnt Vertice (const Standard_Integer theRank) const
393   {
394     Standard_Real anXYZ[3];
395     Vertice (theRank, anXYZ[0], anXYZ[1], anXYZ[2]);
396     return gp_Pnt (anXYZ[0], anXYZ[1], anXYZ[2]);
397   }
398
399   //! Returns the vertice coordinates at rank theRank from the vertex table if defined.
400   void Vertice (const Standard_Integer theRank, Standard_Real& theX, Standard_Real& theY, Standard_Real& theZ) const
401   {
402     theX = theY = theZ = 0.0;
403     Standard_OutOfRange_Raise_if (theRank < 1 || theRank > myAttribs->NbElements, "BAD VERTEX index");
404     const Graphic3d_Vec3& aVec = myAttribs->Value<Graphic3d_Vec3> (theRank - 1);
405     theX = Standard_Real(aVec.x());
406     theY = Standard_Real(aVec.y());
407     theZ = Standard_Real(aVec.z());
408   }
409
410   //! Returns the vertex color at rank theRank from the vertex table if defined.
411   Quantity_Color VertexColor (const Standard_Integer theRank) const
412   {
413     Standard_Real anRGB[3];
414     VertexColor (theRank, anRGB[0], anRGB[1], anRGB[2]);
415     return Quantity_Color (anRGB[0], anRGB[1], anRGB[2], Quantity_TOC_RGB);
416   }
417
418   //! Returns the vertex color at rank theIndex from the vertex table if defined.
419   void VertexColor (const Standard_Integer theIndex,
420                     Graphic3d_Vec4ub&      theColor) const
421   {
422     Standard_OutOfRange_Raise_if (myVCol == 0 || theIndex < 1 || theIndex > myAttribs->NbElements, "BAD VERTEX index");
423     theColor = *reinterpret_cast<const Graphic3d_Vec4ub* >(myAttribs->value (theIndex - 1) + size_t(myVCol));
424   }
425
426   //! Returns the vertex color values at rank theRank from the vertex table if defined.
427   void VertexColor (const Standard_Integer theRank, Standard_Real& theR, Standard_Real& theG, Standard_Real& theB) const
428   {
429     theR = theG = theB = 0.0;
430     Standard_OutOfRange_Raise_if (theRank < 1 || theRank > myAttribs->NbElements, "BAD VERTEX index");
431     if (myVCol == 0)
432     {
433       return;
434     }
435     const Graphic3d_Vec4ub& aColor = *reinterpret_cast<const Graphic3d_Vec4ub* >(myAttribs->value (theRank - 1) + size_t(myVCol));
436     theR = Standard_Real(aColor.r()) / 255.0;
437     theG = Standard_Real(aColor.g()) / 255.0;
438     theB = Standard_Real(aColor.b()) / 255.0;
439   }
440
441   //! Returns the vertex color values at rank theRank from the vertex table if defined.
442   void VertexColor (const Standard_Integer theRank, Standard_Integer& theColor) const
443   {
444     Standard_OutOfRange_Raise_if (theRank < 1 || theRank > myAttribs->NbElements, "BAD VERTEX index");
445     if (myVCol != 0)
446     {
447       theColor = *reinterpret_cast<const Standard_Integer* >(myAttribs->value (theRank - 1) + size_t(myVCol));
448     }
449   }
450
451   //! Returns the vertex normal at rank theRank from the vertex table if defined.
452   gp_Dir VertexNormal (const Standard_Integer theRank) const
453   {
454     Standard_Real anXYZ[3];
455     VertexNormal (theRank, anXYZ[0], anXYZ[1], anXYZ[2]);
456     return gp_Dir (anXYZ[0], anXYZ[1], anXYZ[2]);
457   }
458
459   //! Returns the vertex normal coordinates at rank theRank from the vertex table if defined.
460   void VertexNormal (const Standard_Integer theRank, Standard_Real& theNX, Standard_Real& theNY, Standard_Real& theNZ) const
461   {
462     theNX = theNY = theNZ = 0.0;
463     Standard_OutOfRange_Raise_if (theRank < 1 || theRank > myAttribs->NbElements, "BAD VERTEX index");
464     if (myVNor != 0)
465     {
466       const Graphic3d_Vec3& aVec = *reinterpret_cast<const Graphic3d_Vec3* >(myAttribs->value (theRank - 1) + size_t(myVNor));
467       theNX = Standard_Real(aVec.x());
468       theNY = Standard_Real(aVec.y());
469       theNZ = Standard_Real(aVec.z());
470     }
471   }
472
473   //! Returns the vertex texture at rank theRank from the vertex table if defined.
474   gp_Pnt2d VertexTexel (const Standard_Integer theRank) const
475   {
476     Standard_Real anXY[2];
477     VertexTexel (theRank, anXY[0], anXY[1]);
478     return gp_Pnt2d (anXY[0], anXY[1]);
479   }
480
481   //! Returns the vertex texture coordinates at rank theRank from the vertex table if defined.
482   void VertexTexel (const Standard_Integer theRank, Standard_Real& theTX, Standard_Real& theTY) const
483   {
484     theTX = theTY = 0.0;
485     Standard_OutOfRange_Raise_if (theRank < 1 || theRank > myAttribs->NbElements, "BAD VERTEX index");
486     if (myVTex != 0)
487     {
488       const Graphic3d_Vec2& aVec = *reinterpret_cast<const Graphic3d_Vec2* >(myAttribs->value (theRank - 1) + size_t(myVTex));
489       theTX = Standard_Real(aVec.x());
490       theTY = Standard_Real(aVec.y());
491     }
492   }
493
494 public: //! @name optional array of Indices/Edges for using shared Vertex data
495
496   //! Returns optional index buffer.
497   const Handle(Graphic3d_IndexBuffer)& Indices() const { return myIndices; }
498
499   //! Returns the number of defined edges
500   Standard_Integer EdgeNumber() const { return !myIndices.IsNull() ? myIndices->NbElements : -1; }
501
502   //! Returns the number of allocated edges
503   Standard_Integer EdgeNumberAllocated() const { return !myIndices.IsNull() ? myIndices->NbMaxElements() : 0; }
504
505   //! Returns the vertex index at rank theRank in the range [1,EdgeNumber()]
506   Standard_Integer Edge (const Standard_Integer theRank) const
507   {
508     Standard_OutOfRange_Raise_if (myIndices.IsNull() || theRank < 1 || theRank > myIndices->NbElements, "BAD EDGE index");
509     return Standard_Integer(myIndices->Index (theRank - 1) + 1);
510   }
511
512   //! Adds an edge in the range [1,VertexNumber()] in the array.
513   //! @return the actual edges number
514   Standard_EXPORT Standard_Integer AddEdge (const Standard_Integer theVertexIndex);
515
516   //! Convenience method, adds two vertex indices (a segment) in the range [1,VertexNumber()] in the array.
517   //! @return the actual edges number
518   Standard_Integer AddEdges (Standard_Integer theVertexIndex1,
519                              Standard_Integer theVertexIndex2)
520   {
521     AddEdge (theVertexIndex1);
522     return AddEdge (theVertexIndex2);
523   }
524
525   //! Convenience method, adds three vertex indices (a triangle) in the range [1,VertexNumber()] in the array.
526   //! @return the actual edges number
527   Standard_Integer AddEdges (Standard_Integer theVertexIndex1,
528                              Standard_Integer theVertexIndex2,
529                              Standard_Integer theVertexIndex3)
530   {
531     AddEdge (theVertexIndex1);
532     AddEdge (theVertexIndex2);
533     return AddEdge (theVertexIndex3);
534   }
535
536   //! Convenience method, adds four vertex indices (a quad) in the range [1,VertexNumber()] in the array.
537   //! @return the actual edges number
538   Standard_Integer AddEdges (Standard_Integer theVertexIndex1,
539                              Standard_Integer theVertexIndex2,
540                              Standard_Integer theVertexIndex3,
541                              Standard_Integer theVertexIndex4)
542   {
543     AddEdge (theVertexIndex1);
544     AddEdge (theVertexIndex2);
545     AddEdge (theVertexIndex3);
546     return AddEdge (theVertexIndex4);
547   }
548
549 public: //! @name optional array of Bounds/Subgroups within primitive array (e.g. restarting primitives / assigning colors)
550
551   //! Returns optional bounds buffer.
552   const Handle(Graphic3d_BoundBuffer)& Bounds() const { return myBounds; }
553
554   //! Returns TRUE when bound colors array is defined.
555   Standard_Boolean HasBoundColors() const { return !myBounds.IsNull() && myBounds->Colors != NULL; }
556
557   //! Returns the number of defined bounds
558   Standard_Integer BoundNumber() const { return !myBounds.IsNull() ? myBounds->NbBounds : -1; }
559
560   //! Returns the number of allocated bounds
561   Standard_Integer BoundNumberAllocated() const { return !myBounds.IsNull() ? myBounds->NbMaxBounds : 0; }
562
563   //! Returns the edge number at rank theRank.
564   Standard_Integer Bound (const Standard_Integer theRank) const
565   {
566     Standard_OutOfRange_Raise_if (myBounds.IsNull() || theRank < 1 || theRank > myBounds->NbBounds, "BAD BOUND index");
567     return myBounds->Bounds[theRank - 1];
568   }
569
570   //! Returns the bound color at rank theRank from the bound table if defined.
571   Quantity_Color BoundColor (const Standard_Integer theRank) const
572   {
573     Standard_Real anRGB[3] = {0.0, 0.0, 0.0};
574     BoundColor (theRank, anRGB[0], anRGB[1], anRGB[2]);
575     return Quantity_Color (anRGB[0], anRGB[1], anRGB[2], Quantity_TOC_RGB);
576   }
577
578   //! Returns the bound color values at rank theRank from the bound table if defined.
579   void BoundColor (const Standard_Integer theRank, Standard_Real& theR, Standard_Real& theG, Standard_Real& theB) const
580   {
581     Standard_OutOfRange_Raise_if (myBounds.IsNull() || myBounds->Colors == NULL || theRank < 1 || theRank > myBounds->NbBounds, "BAD BOUND index");
582     const Graphic3d_Vec4& aVec = myBounds->Colors[theRank - 1];
583     theR = Standard_Real(aVec.r());
584     theG = Standard_Real(aVec.g());
585     theB = Standard_Real(aVec.b());
586   }
587
588   //! Adds a bound of length theEdgeNumber in the bound array
589   //! @return the actual bounds number
590   Standard_EXPORT Standard_Integer AddBound (const Standard_Integer theEdgeNumber);
591
592   //! Adds a bound of length theEdgeNumber and bound color theBColor in the bound array.
593   //! Warning: theBColor is ignored when the hasBColors constructor parameter is FALSE
594   //! @return the actual bounds number
595   Standard_Integer AddBound (const Standard_Integer theEdgeNumber, const Quantity_Color& theBColor)
596   {
597     return AddBound (theEdgeNumber, theBColor.Red(), theBColor.Green(), theBColor.Blue());
598   }
599
600   //! Adds a bound of length theEdgeNumber and bound color coordinates in the bound array.
601   //! Warning: <theR,theG,theB> are ignored when the hasBColors constructor parameter is FALSE
602   //! @return the actual bounds number
603   Standard_EXPORT Standard_Integer AddBound (const Standard_Integer theEdgeNumber, const Standard_Real theR, const Standard_Real theG, const Standard_Real theB);
604
605   //! Change the bound color of rank theIndex in the array.
606   void SetBoundColor (const Standard_Integer theIndex, const Quantity_Color& theColor)
607   {
608     SetBoundColor (theIndex, theColor.Red(), theColor.Green(), theColor.Blue());
609   }
610
611   //! Change the bound color of rank theIndex in the array.
612   void SetBoundColor (const Standard_Integer theIndex, const Standard_Real theR, const Standard_Real theG, const Standard_Real theB)
613   {
614     if (myBounds.IsNull())
615     {
616       return;
617     }
618     Standard_OutOfRange_Raise_if (myBounds.IsNull() || myBounds->Colors == NULL || theIndex < 1 || theIndex > myBounds->NbMaxBounds, "BAD BOUND index");
619     Graphic3d_Vec4& aVec = myBounds->Colors[theIndex - 1];
620     aVec.r() = Standard_ShortReal (theR);
621     aVec.g() = Standard_ShortReal (theG);
622     aVec.b() = Standard_ShortReal (theB);
623     aVec.a() = 1.0f;
624     myBounds->NbBounds = Max (theIndex, myBounds->NbBounds);
625   }
626
627 protected: //! @name protected constructors
628
629   //! Main constructor.
630   //! @param theType       type of primitive
631   //! @param theMaxVertexs length of vertex attributes buffer to be allocated (maximum number of vertexes, @sa ::AddVertex())
632   //! @param theMaxBounds  length of bounds buffer to be allocated (maximum number of bounds, @sa ::AddBound())
633   //! @param theMaxEdges   length of edges (index) buffer to be allocated (maximum number of indexes @sa ::AddEdge())
634   //! @param theArrayFlags array flags
635   Graphic3d_ArrayOfPrimitives (Graphic3d_TypeOfPrimitiveArray theType,
636                                Standard_Integer theMaxVertexs,
637                                Standard_Integer theMaxBounds,
638                                Standard_Integer theMaxEdges,
639                                Graphic3d_ArrayFlags theArrayFlags)
640   : myType (Graphic3d_TOPA_UNDEFINED), myVNor (0), myVTex (0), myVCol (0)
641   {
642     init (theType, theMaxVertexs, theMaxBounds, theMaxEdges, theArrayFlags);
643   }
644
645   //! Array constructor.
646   Standard_EXPORT void init (Graphic3d_TypeOfPrimitiveArray theType,
647                              Standard_Integer theMaxVertexs,
648                              Standard_Integer theMaxBounds,
649                              Standard_Integer theMaxEdges,
650                              Graphic3d_ArrayFlags theArrayFlags);
651
652 private: //! @name private fields
653
654   Handle(Graphic3d_IndexBuffer)  myIndices;
655   Handle(Graphic3d_Buffer)       myAttribs;
656   Handle(Graphic3d_BoundBuffer)  myBounds;
657   Graphic3d_TypeOfPrimitiveArray myType;
658   Standard_Byte myVNor;
659   Standard_Byte myVTex;
660   Standard_Byte myVCol;
661
662 };
663
664 #endif // _Graphic3d_ArrayOfPrimitives_HeaderFile