0029170: GCC 7.1 warnings -Wstrict-aliasing in Graphic3d_ArrayOfPrimitives.hxx
[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_Buffer.hxx>
20 #include <Graphic3d_IndexBuffer.hxx>
21 #include <Graphic3d_TypeOfPrimitiveArray.hxx>
22 #include <gp_Dir.hxx>
23 #include <gp_Pnt.hxx>
24 #include <Standard_OutOfRange.hxx>
25 #include <Quantity_Color.hxx>
26
27 class Graphic3d_ArrayOfPrimitives;
28 DEFINE_STANDARD_HANDLE(Graphic3d_ArrayOfPrimitives, Standard_Transient)
29
30 //! This class furnish services to defined and fill an array of primitives
31 //! which can be passed directly to graphics rendering API.
32 //!
33 //! The basic interface consists of the following parts:
34 //! 1) Specifying primitive type.
35 //!    WARNING! Particular primitive types might be unsupported by specific hardware/graphics API (like quads and polygons).
36 //!             It is always preferred using one of basic types having maximum compatibility:
37 //!             Point, Triangle (or Triangle strip), Segment aka Lines (or Polyline aka Line Strip).
38 //!    Primitive strip types can be used to reduce memory usage as alternative to Indexed arrays.
39 //! 2) Vertex array.
40 //!    - Specifying the (maximum) number of vertexes within array.
41 //!    - Specifying the vertex attributes, complementary to mandatory vertex Position (normal, color, UV texture coordinates).
42 //!    - Defining vertex values by using various versions of AddVertex() or SetVertex*() methods.
43 //! 3) Index array (optional).
44 //!    - Specifying the (maximum) number of indexes (edges).
45 //!    - Defining index values by using AddEdge() method; the index value should be within number of defined Vertexes.
46 //!
47 //!    Indexed array allows sharing vertex data across Primitives and thus reducing memory usage,
48 //!    since index size is much smaller then size of vertex with all its attributes.
49 //!    It is a preferred way for defining primitive array and main alternative to Primitive Strips for optimal memory usage,
50 //!    although it is also possible (but unusual) defining Indexed Primitive Strip.
51 //!    Note that it is NOT possible sharing Vertex Attributes partially (e.g. share Position, but have different Normals);
52 //!    in such cases Vertex should be entirely duplicated with all Attributes.
53 //! 4) Bounds array (optional).
54 //!    - Specifying the (maximum) number of bounds.
55 //!    - Defining bounds using AddBound() methods.
56 //!
57 //!    Bounds allow splitting Primitive Array into sub-groups.
58 //!    This is useful only in two cases - for specifying per-group color and for restarting Primitive Strips.
59 //!    WARNING! Bounds within Primitive Array break rendering batches into parts (additional for loops),
60 //!             affecting rendering performance negatively (increasing CPU load).
61
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.IsNull() ? myAttribs->NbElements : -1; }
90
91   //! Returns the number of total items according to the array type.
92   Standard_EXPORT Standard_Integer ItemNumber() const;
93
94   //! Returns TRUE only when the contains of this array is available.
95   Standard_EXPORT Standard_Boolean IsValid();
96
97   //! Adds a vertice in the array.
98   //! @return the actual vertex number
99   Standard_Integer AddVertex (const gp_Pnt& theVertex) { return AddVertex (theVertex.X(), theVertex.Y(), theVertex.Z()); }
100
101   //! Adds a vertice in the array.
102   //! @return the actual vertex number
103   Standard_Integer AddVertex (const Graphic3d_Vec3& theVertex) { return AddVertex (theVertex.x(), theVertex.y(), theVertex.z()); }
104
105   //! Adds a vertice in the array.
106   //! @return the actual vertex number
107   Standard_Integer AddVertex (const Standard_Real theX, const Standard_Real theY, const Standard_Real theZ)
108   {
109     return AddVertex (RealToShortReal (theX), RealToShortReal (theY), RealToShortReal (theZ));
110   }
111
112   //! Adds a vertice in the array.
113   //! @return the actual vertex number.
114   Standard_Integer AddVertex (const Standard_ShortReal theX, const Standard_ShortReal theY, const Standard_ShortReal theZ)
115   {
116     if (myAttribs.IsNull())
117     {
118       return 0;
119     }
120     const Standard_Integer anIndex = myAttribs->NbElements + 1;
121     SetVertice (anIndex, theX, theY, theZ);
122     return anIndex;
123   }
124
125   //! Adds a vertice and vertex color in the vertex array.
126   //! Warning: theColor is ignored when the hasVColors constructor parameter is FALSE
127   //! @return the actual vertex number
128   Standard_Integer AddVertex (const gp_Pnt& theVertex, const Quantity_Color& theColor)
129   {
130     const Standard_Integer anIndex = AddVertex (theVertex);
131     SetVertexColor (anIndex, theColor.Red(), theColor.Green(), theColor.Blue());
132     return anIndex;
133   }
134
135   //! Adds a vertice and vertex color in the vertex array.
136   //! Warning: theColor is ignored when the hasVColors constructor parameter is FALSE
137   //! @code
138   //!   theColor32 = Alpha << 24 + Blue << 16 + Green << 8 + Red
139   //! @endcode
140   //! @return the actual vertex number
141   Standard_Integer AddVertex (const gp_Pnt& theVertex, const Standard_Integer theColor32)
142   {
143     const Standard_Integer anIndex = AddVertex (theVertex);
144     SetVertexColor (anIndex, theColor32);
145     return anIndex;
146   }
147
148   //! Adds a vertice and vertex color in the vertex array.
149   //! Warning: theColor is ignored when the hasVColors constructor parameter is FALSE
150   //! @return the actual vertex number
151   Standard_Integer AddVertex (const gp_Pnt&           theVertex,
152                               const Graphic3d_Vec4ub& theColor)
153   {
154     const Standard_Integer anIndex = AddVertex (theVertex);
155     SetVertexColor (anIndex, theColor);
156     return anIndex;
157   }
158
159   //! Adds a vertice and vertex normal in the vertex array.
160   //! Warning: theNormal is ignored when the hasVNormals constructor parameter is FALSE.
161   //! @return the actual vertex number
162   Standard_Integer AddVertex (const gp_Pnt& theVertex, const gp_Dir& theNormal)
163   {
164     return AddVertex (theVertex.X(), theVertex.Y(), theVertex.Z(),
165                       theNormal.X(), theNormal.Y(), theNormal.Z());
166   }
167
168   //! Adds a vertice and vertex normal in the vertex array.
169   //! Warning: Normal is ignored when the hasVNormals constructor parameter is FALSE.
170   //! @return the actual vertex number
171   Standard_Integer AddVertex (const Standard_Real theX,  const Standard_Real theY,  const Standard_Real theZ,
172                               const Standard_Real theNX, const Standard_Real theNY, const Standard_Real theNZ)
173   {
174     return AddVertex (RealToShortReal (theX),  RealToShortReal (theY),  RealToShortReal (theZ),
175                       Standard_ShortReal (theNX), Standard_ShortReal (theNY), Standard_ShortReal (theNZ));
176   }
177
178   //! Adds a vertice and vertex normal in the vertex array.
179   //! Warning: Normal is ignored when the hasVNormals constructor parameter is FALSE.
180   //! @return the actual vertex number
181   Standard_Integer AddVertex (const Standard_ShortReal theX,  const Standard_ShortReal theY,  const Standard_ShortReal theZ,
182                               const Standard_ShortReal theNX, const Standard_ShortReal theNY, const Standard_ShortReal theNZ)
183   {
184     if (myAttribs.IsNull())
185     {
186       return 0;
187     }
188     const Standard_Integer anIndex = myAttribs->NbElements + 1;
189     SetVertice      (anIndex, theX,  theY,  theZ);
190     SetVertexNormal (anIndex, theNX, theNY, theNZ);
191     return anIndex;
192   }
193
194   //! Adds a vertice,vertex normal and color in the vertex array.
195   //! Warning: theNormal is ignored when the hasVNormals constructor parameter is FALSE
196   //! and      theColor  is ignored when the hasVColors  constructor parameter is FALSE.
197   //! @return the actual vertex number
198   Standard_Integer AddVertex (const gp_Pnt& theVertex, const gp_Dir& theNormal, const Quantity_Color& theColor)
199   {
200     const Standard_Integer anIndex = AddVertex (theVertex, theNormal);
201     SetVertexColor (anIndex, theColor.Red(), theColor.Green(), theColor.Blue());
202     return anIndex;
203   }
204
205   //! Adds a vertice,vertex normal and color in the vertex array.
206   //! Warning: theNormal is ignored when the hasVNormals constructor parameter is FALSE
207   //! and      theColor  is ignored when the hasVColors  constructor parameter is FALSE.
208   //! @code
209   //!   theColor32 = Alpha << 24 + Blue << 16 + Green << 8 + Red
210   //! @endcode
211   //! @return the actual vertex number
212   Standard_Integer AddVertex (const gp_Pnt& theVertex, const gp_Dir& theNormal, const Standard_Integer theColor32)
213   {
214     const Standard_Integer anIndex = AddVertex (theVertex, theNormal);
215     SetVertexColor (anIndex, theColor32);
216     return anIndex;
217   }
218
219   //! Adds a vertice and vertex texture in the vertex array.
220   //! theTexel is ignored when the hasVTexels constructor parameter is FALSE.
221   //! @return the actual vertex number
222   Standard_Integer AddVertex (const gp_Pnt& theVertex, const gp_Pnt2d& theTexel)
223   {
224     return AddVertex (theVertex.X(), theVertex.Y(), theVertex.Z(),
225                       theTexel.X(), theTexel.Y());
226   }
227
228   //! Adds a vertice and vertex texture coordinates in the vertex array.
229   //! Texel is ignored when the hasVTexels constructor parameter is FALSE.
230   //! @return the actual vertex number
231   Standard_Integer AddVertex (const Standard_Real theX, const Standard_Real theY, const Standard_Real theZ,
232                               const Standard_Real theTX, const Standard_Real theTY)
233   {
234     return AddVertex (RealToShortReal (theX),  RealToShortReal (theY),  RealToShortReal (theZ),
235                       Standard_ShortReal (theTX), Standard_ShortReal (theTY));
236   }
237
238   //! Adds a vertice and vertex texture coordinates in the vertex array.
239   //! Texel is ignored when the hasVTexels constructor parameter is FALSE.
240   //! @return the actual vertex number
241   Standard_Integer AddVertex (const Standard_ShortReal theX, const Standard_ShortReal theY, const Standard_ShortReal theZ,
242                               const Standard_ShortReal theTX, const Standard_ShortReal theTY)
243   {
244     if (myAttribs.IsNull())
245     {
246       return 0;
247     }
248     const Standard_Integer anIndex = myAttribs->NbElements + 1;
249     SetVertice     (anIndex, theX, theY, theZ);
250     SetVertexTexel (anIndex, theTX, theTY);
251     return anIndex;
252   }
253
254   //! Adds a vertice,vertex normal and texture in the vertex array.
255   //! Warning: theNormal is ignored when the hasVNormals constructor parameter is FALSE
256   //! and      theTexel  is ignored when the hasVTexels  constructor parameter is FALSE.
257   //! @return the actual vertex number
258   Standard_Integer AddVertex (const gp_Pnt& theVertex, const gp_Dir& theNormal, const gp_Pnt2d& theTexel)
259   {
260     return AddVertex (theVertex.X(), theVertex.Y(), theVertex.Z(),
261                       theNormal.X(), theNormal.Y(), theNormal.Z(),
262                       theTexel.X(),  theTexel.Y());
263   }
264
265   //! Adds a vertice,vertex normal and texture in the vertex array.
266   //! Warning: Normal is ignored when the hasVNormals constructor parameter is FALSE
267   //! and      Texel  is ignored when the hasVTexels  constructor parameter is FALSE.
268   //! @return the actual vertex number
269   Standard_Integer AddVertex (const Standard_Real theX,  const Standard_Real theY,  const Standard_Real theZ,
270                               const Standard_Real theNX, const Standard_Real theNY, const Standard_Real theNZ,
271                               const Standard_Real theTX, const Standard_Real theTY)
272   {
273     return AddVertex (RealToShortReal (theX), RealToShortReal (theY), RealToShortReal (theZ),
274                       Standard_ShortReal (theNX), Standard_ShortReal (theNY), Standard_ShortReal (theNZ),
275                       Standard_ShortReal (theTX), Standard_ShortReal (theTY));
276   }
277
278   //! Adds a vertice,vertex normal and texture in the vertex array.
279   //! Warning: Normal is ignored when the hasVNormals constructor parameter is FALSE
280   //!     and  Texel  is ignored when the hasVTexels  constructor parameter is FALSE.
281   //! @return the actual vertex number
282   Standard_Integer AddVertex (const Standard_ShortReal theX,  const Standard_ShortReal theY,  const Standard_ShortReal theZ,
283                               const Standard_ShortReal theNX, const Standard_ShortReal theNY, const Standard_ShortReal theNZ,
284                               const Standard_ShortReal theTX, const Standard_ShortReal theTY)
285   {
286     if (myAttribs.IsNull())
287     {
288       return 0;
289     }
290     const Standard_Integer anIndex = myAttribs->NbElements + 1;
291     SetVertice     (anIndex, theX,  theY,  theZ);
292     SetVertexNormal(anIndex, theNX, theNY, theNZ);
293     SetVertexTexel (anIndex, theTX, theTY);
294     return anIndex;
295   }
296
297   //! Change the vertice of rank theIndex in the array.
298   void SetVertice (const Standard_Integer theIndex, const gp_Pnt& theVertex)
299   {
300     SetVertice (theIndex, Standard_ShortReal (theVertex.X()), Standard_ShortReal (theVertex.Y()), Standard_ShortReal (theVertex.Z()));
301   }
302
303   //! Change the vertice of rank theIndex in the array.
304   void SetVertice (const Standard_Integer theIndex, const Standard_ShortReal theX, const Standard_ShortReal theY, const Standard_ShortReal theZ)
305   {
306     if (myAttribs.IsNull())
307     {
308       return;
309     }
310     else if (theIndex < 1
311           || theIndex > myMaxVertexs)
312     {
313       throw Standard_OutOfRange ("BAD VERTEX index");
314     }
315
316     Graphic3d_Vec3& aVec = myAttribs->ChangeValue<Graphic3d_Vec3> (theIndex - 1);
317     aVec.x() = theX;
318     aVec.y() = theY;
319     aVec.z() = theZ;
320     if (myAttribs->NbElements < theIndex)
321     {
322       myAttribs->NbElements = theIndex;
323     }
324   }
325
326   //! Change the vertex color of rank theIndex in the array.
327   void SetVertexColor (const Standard_Integer theIndex, const Quantity_Color& theColor)
328   {
329     SetVertexColor (theIndex, theColor.Red(), theColor.Green(), theColor.Blue());
330   }
331
332   //! Change the vertex color of rank theIndex in the array.
333   void SetVertexColor (const Standard_Integer theIndex, const Standard_Real theR, const Standard_Real theG, const Standard_Real theB)
334   {
335     if (myAttribs.IsNull())
336     {
337       return;
338     }
339     else if (theIndex < 1
340           || theIndex > myMaxVertexs)
341     {
342       throw Standard_OutOfRange ("BAD VERTEX index");
343     }
344
345     if (myVCol != 0)
346     {
347       Graphic3d_Vec4ub *aColorPtr = 
348         reinterpret_cast<Graphic3d_Vec4ub* >(myAttribs->changeValue (theIndex - 1) + size_t(myVCol));
349       aColorPtr->SetValues (Standard_Byte(theR * 255.0),
350                             Standard_Byte(theG * 255.0),
351                             Standard_Byte(theB * 255.0), 255);
352     }
353     myAttribs->NbElements = Max (theIndex, myAttribs->NbElements);
354   }
355
356   //! Change the vertex color of rank theIndex in the array.
357   void SetVertexColor (const Standard_Integer  theIndex,
358                        const Graphic3d_Vec4ub& theColor)
359   {
360     if (myAttribs.IsNull())
361     {
362       return;
363     }
364     else if (theIndex < 1
365           || theIndex > myMaxVertexs)
366     {
367       throw Standard_OutOfRange ("BAD VERTEX index");
368     }
369
370     if (myVCol != 0)
371     {
372       Graphic3d_Vec4ub *aColorPtr = 
373         reinterpret_cast<Graphic3d_Vec4ub* >(myAttribs->changeValue (theIndex - 1) + size_t(myVCol));
374       (*aColorPtr) = theColor;
375     }
376     myAttribs->NbElements = Max (theIndex, myAttribs->NbElements);
377   }
378
379   //! Change the vertex color of rank theIndex> in the array.
380   //! @code
381   //!   theColor32 = Alpha << 24 + Blue << 16 + Green << 8 + Red
382   //! @endcode
383   void SetVertexColor (const Standard_Integer theIndex, const Standard_Integer theColor32)
384   {
385     if (myAttribs.IsNull())
386     {
387       return;
388     }
389     else if (theIndex < 1
390           || theIndex > myMaxVertexs)
391     {
392       throw Standard_OutOfRange ("BAD VERTEX index");
393     }
394
395     if (myVCol != 0)
396     {
397       *reinterpret_cast<Standard_Integer* >(myAttribs->changeValue (theIndex - 1) + size_t(myVCol)) = theColor32;
398     }
399   }
400
401   //! Change the vertex normal of rank theIndex in the array.
402   void SetVertexNormal (const Standard_Integer theIndex, const gp_Dir& theNormal)
403   {
404     SetVertexNormal (theIndex, theNormal.X(), theNormal.Y(), theNormal.Z());
405   }
406
407   //! Change the vertex normal of rank theIndex in the array.
408   void SetVertexNormal (const Standard_Integer theIndex, const Standard_Real theNX, const Standard_Real theNY, const Standard_Real theNZ)
409   {
410     if (myAttribs.IsNull())
411     {
412       return;
413     }
414     else if (theIndex < 1
415           || theIndex > myMaxVertexs)
416     {
417       throw Standard_OutOfRange("BAD VERTEX index");
418     }
419
420     if (myVNor != 0)
421     {
422       Graphic3d_Vec3& aVec = *reinterpret_cast<Graphic3d_Vec3* >(myAttribs->changeValue (theIndex - 1) + size_t(myVNor));
423       aVec.x() = Standard_ShortReal (theNX);
424       aVec.y() = Standard_ShortReal (theNY);
425       aVec.z() = Standard_ShortReal (theNZ);
426     }
427     myAttribs->NbElements = Max (theIndex, myAttribs->NbElements);
428   }
429
430   //! Change the vertex texel of rank theIndex in the array.
431   void SetVertexTexel (const Standard_Integer theIndex, const gp_Pnt2d& theTexel)
432   {
433     SetVertexTexel (theIndex, theTexel.X(), theTexel.Y());
434   }
435
436   //! Change the vertex texel of rank theIndex in the array.
437   void SetVertexTexel (const Standard_Integer theIndex, const Standard_Real theTX, const Standard_Real theTY)
438   {
439     if (myAttribs.IsNull())
440     {
441       return;
442     }
443     else if (theIndex < 1
444           || theIndex > myMaxVertexs)
445     {
446       throw Standard_OutOfRange("BAD VERTEX index");
447     }
448
449     if (myVTex != 0)
450     {
451       Graphic3d_Vec2& aVec = *reinterpret_cast<Graphic3d_Vec2* >(myAttribs->changeValue (theIndex - 1) + size_t(myVTex));
452       aVec.x() = Standard_ShortReal (theTX);
453       aVec.y() = Standard_ShortReal (theTY);
454     }
455     myAttribs->NbElements = Max (theIndex, myAttribs->NbElements);
456   }
457
458   //! Returns the vertice at rank theRank from the vertex table if defined.
459   gp_Pnt Vertice (const Standard_Integer theRank) const
460   {
461     Standard_Real anXYZ[3];
462     Vertice (theRank, anXYZ[0], anXYZ[1], anXYZ[2]);
463     return gp_Pnt (anXYZ[0], anXYZ[1], anXYZ[2]);
464   }
465
466   //! Returns the vertice coordinates at rank theRank from the vertex table if defined.
467   void Vertice (const Standard_Integer theRank, Standard_Real& theX, Standard_Real& theY, Standard_Real& theZ) const
468   {
469     theX = theY = theZ = 0.0;
470     if (myAttribs.IsNull())
471     {
472       return;
473     }
474     else if (theRank < 1
475           || theRank > myAttribs->NbElements)
476     {
477       throw Standard_OutOfRange ("BAD VERTEX index");
478     }
479
480     const Graphic3d_Vec3& aVec = myAttribs->Value<Graphic3d_Vec3> (theRank - 1);
481     theX = Standard_Real(aVec.x());
482     theY = Standard_Real(aVec.y());
483     theZ = Standard_Real(aVec.z());
484   }
485
486   //! Returns the vertex color at rank theRank from the vertex table if defined.
487   Quantity_Color VertexColor (const Standard_Integer theRank) const
488   {
489     Standard_Real anRGB[3];
490     VertexColor (theRank, anRGB[0], anRGB[1], anRGB[2]);
491     return Quantity_Color (anRGB[0], anRGB[1], anRGB[2], Quantity_TOC_RGB);
492   }
493
494   //! Returns the vertex color at rank theIndex from the vertex table if defined.
495   void VertexColor (const Standard_Integer theIndex,
496                     Graphic3d_Vec4ub&      theColor) const
497   {
498     if (myAttribs.IsNull()
499      || myVCol == 0)
500     {
501       throw Standard_OutOfRange ("Primitive array does not define color attribute");
502     }
503
504     if (theIndex < 1
505      || theIndex > myAttribs->NbElements)
506     {
507       throw Standard_OutOfRange ("BAD VERTEX index");
508     }
509
510     theColor = *reinterpret_cast<const Graphic3d_Vec4ub* >(myAttribs->value (theIndex - 1) + size_t(myVCol));
511   }
512
513   //! Returns the vertex color values at rank theRank from the vertex table if defined.
514   void VertexColor (const Standard_Integer theRank, Standard_Real& theR, Standard_Real& theG, Standard_Real& theB) const
515   {
516     theR = theG = theB = 0.0;
517     if (myAttribs.IsNull()
518      || myVCol == 0)
519     {
520       return;
521     }
522     else if (theRank < 1
523           || theRank > myAttribs->NbElements)
524     {
525       throw Standard_OutOfRange ("BAD VERTEX index");
526     }
527
528     const Graphic3d_Vec4ub& aColor = *reinterpret_cast<const Graphic3d_Vec4ub* >(myAttribs->value (theRank - 1) + size_t(myVCol));
529     theR = Standard_Real(aColor.r()) / 255.0;
530     theG = Standard_Real(aColor.g()) / 255.0;
531     theB = Standard_Real(aColor.b()) / 255.0;
532   }
533
534   //! Returns the vertex color values at rank theRank from the vertex table if defined.
535   void VertexColor (const Standard_Integer theRank, Standard_Integer& theColor) const
536   {
537     if (myVCol != 0)
538     {
539       theColor = *reinterpret_cast<const Standard_Integer* >(myAttribs->value (theRank - 1) + size_t(myVCol));
540     }
541   }
542
543   //! Returns the vertex normal at rank theRank from the vertex table if defined.
544   gp_Dir VertexNormal (const Standard_Integer theRank) const
545   {
546     Standard_Real anXYZ[3];
547     VertexNormal (theRank, anXYZ[0], anXYZ[1], anXYZ[2]);
548     return gp_Dir (anXYZ[0], anXYZ[1], anXYZ[2]);
549   }
550
551   //! Returns the vertex normal coordinates at rank theRank from the vertex table if defined.
552   void VertexNormal (const Standard_Integer theRank, Standard_Real& theNX, Standard_Real& theNY, Standard_Real& theNZ) const
553   {
554     theNX = theNY = theNZ = 0.0;
555     if (myAttribs.IsNull())
556     {
557       return;
558     }
559     else if (theRank < 1
560           || theRank > myAttribs->NbElements)
561     {
562       throw Standard_OutOfRange ("BAD VERTEX index");
563     }
564
565     if (myVNor != 0)
566     {
567       const Graphic3d_Vec3& aVec = *reinterpret_cast<const Graphic3d_Vec3* >(myAttribs->value (theRank - 1) + size_t(myVNor));
568       theNX = Standard_Real(aVec.x());
569       theNY = Standard_Real(aVec.y());
570       theNZ = Standard_Real(aVec.z());
571     }
572   }
573
574   //! Returns the vertex texture at rank theRank from the vertex table if defined.
575   gp_Pnt2d VertexTexel (const Standard_Integer theRank) const
576   {
577     Standard_Real anXY[2];
578     VertexTexel (theRank, anXY[0], anXY[1]);
579     return gp_Pnt2d (anXY[0], anXY[1]);
580   }
581
582   //! Returns the vertex texture coordinates at rank theRank from the vertex table if defined.
583   void VertexTexel (const Standard_Integer theRank, Standard_Real& theTX, Standard_Real& theTY) const
584   {
585     theTX = theTY = 0.0;
586     if (myAttribs.IsNull())
587     {
588       return;
589     }
590     else if (theRank < 1
591           || theRank > myAttribs->NbElements)
592     {
593       throw Standard_OutOfRange ("BAD VERTEX index");
594     }
595
596     if (myVTex != 0)
597     {
598       const Graphic3d_Vec2& aVec = *reinterpret_cast<const Graphic3d_Vec2* >(myAttribs->value (theRank - 1) + size_t(myVTex));
599       theTX = Standard_Real(aVec.x());
600       theTY = Standard_Real(aVec.y());
601     }
602   }
603
604 public: //! @name optional array of Indices/Edges for using shared Vertex data
605
606   //! Returns optional index buffer.
607   const Handle(Graphic3d_IndexBuffer)& Indices() const { return myIndices; }
608
609   //! Returns the number of defined edges
610   Standard_Integer EdgeNumber() const { return !myIndices.IsNull() ? myIndices->NbElements : -1; }
611
612   //! Returns the vertex index at rank theRank in the range [1,EdgeNumber()]
613   Standard_Integer Edge (const Standard_Integer theRank) const
614   {
615     if (myIndices.IsNull()
616      || theRank <= 0
617      || theRank > myIndices->NbElements)
618     {
619       throw Standard_OutOfRange ("BAD EDGE index");
620     }
621     return Standard_Integer(myIndices->Index (theRank - 1) + 1);
622   }
623
624   //! Adds an edge in the range [1,VertexNumber()] in the array.
625   //! @return the actual edges number
626   Standard_EXPORT Standard_Integer AddEdge (const Standard_Integer theVertexIndex);
627
628 public: //! @name optional array of Bounds/Subgroups within primitive array (e.g. restarting primitives / assigning colors)
629
630   //! Returns optional bounds buffer.
631   const Handle(Graphic3d_BoundBuffer)& Bounds() const { return myBounds; }
632
633   //! Returns TRUE when bound colors array is defined.
634   Standard_Boolean HasBoundColors() const { return !myBounds.IsNull() && myBounds->Colors != NULL; }
635
636   //! Returns the number of defined bounds
637   Standard_Integer BoundNumber() const { return !myBounds.IsNull() ? myBounds->NbBounds : -1; }
638
639   //! Returns the edge number at rank theRank.
640   Standard_Integer Bound (const Standard_Integer theRank) const
641   {
642     if (myBounds.IsNull()
643      || theRank <= 0
644      || theRank > myBounds->NbBounds)
645     {
646       throw Standard_OutOfRange ("BAD BOUND index");
647     }
648     return myBounds->Bounds[theRank - 1];
649   }
650
651   //! Returns the bound color at rank theRank from the bound table if defined.
652   Quantity_Color BoundColor (const Standard_Integer theRank) const
653   {
654     Standard_Real anRGB[3] = {0.0, 0.0, 0.0};
655     BoundColor (theRank, anRGB[0], anRGB[1], anRGB[2]);
656     return Quantity_Color (anRGB[0], anRGB[1], anRGB[2], Quantity_TOC_RGB);
657   }
658
659   //! Returns the bound color values at rank theRank from the bound table if defined.
660   void BoundColor (const Standard_Integer theRank, Standard_Real& theR, Standard_Real& theG, Standard_Real& theB) const
661   {
662     if (myBounds.IsNull()
663      || myBounds->Colors == NULL
664      || theRank <= 0
665      || theRank > myBounds->NbBounds)
666     {
667       throw Standard_OutOfRange (" BAD BOUND index");
668     }
669
670     const Graphic3d_Vec4& aVec = myBounds->Colors[theRank - 1];
671     theR = Standard_Real(aVec.r());
672     theG = Standard_Real(aVec.g());
673     theB = Standard_Real(aVec.b());
674   }
675
676   //! Adds a bound of length theEdgeNumber in the bound array
677   //! @return the actual bounds number
678   Standard_EXPORT Standard_Integer AddBound (const Standard_Integer theEdgeNumber);
679
680   //! Adds a bound of length theEdgeNumber and bound color theBColor in the bound array.
681   //! Warning: theBColor is ignored when the hasBColors constructor parameter is FALSE
682   //! @return the actual bounds number
683   Standard_Integer AddBound (const Standard_Integer theEdgeNumber, const Quantity_Color& theBColor)
684   {
685     return AddBound (theEdgeNumber, theBColor.Red(), theBColor.Green(), theBColor.Blue());
686   }
687
688   //! Adds a bound of length theEdgeNumber and bound color coordinates in the bound array.
689   //! Warning: <theR,theG,theB> are ignored when the hasBColors constructor parameter is FALSE
690   //! @return the actual bounds number
691   Standard_EXPORT Standard_Integer AddBound (const Standard_Integer theEdgeNumber, const Standard_Real theR, const Standard_Real theG, const Standard_Real theB);
692
693   //! Change the bound color of rank theIndex in the array.
694   void SetBoundColor (const Standard_Integer theIndex, const Quantity_Color& theColor)
695   {
696     SetBoundColor (theIndex, theColor.Red(), theColor.Green(), theColor.Blue());
697   }
698
699   //! Change the bound color of rank theIndex in the array.
700   void SetBoundColor (const Standard_Integer theIndex, const Standard_Real theR, const Standard_Real theG, const Standard_Real theB)
701   {
702     if (myBounds.IsNull())
703     {
704       return;
705     }
706     else if (theIndex < 1
707           || theIndex > myMaxBounds)
708     {
709       throw Standard_OutOfRange("BAD BOUND index");
710     }
711
712     Graphic3d_Vec4& aVec = myBounds->Colors[theIndex - 1];
713     aVec.r() = Standard_ShortReal (theR);
714     aVec.g() = Standard_ShortReal (theG);
715     aVec.b() = Standard_ShortReal (theB);
716     aVec.a() = 1.0f;
717     myBounds->NbBounds = Max (theIndex, myBounds->NbBounds);
718   }
719
720 protected: //! @name protected constructors
721
722   //! Warning
723   //! You must use a coherent set of AddVertex() methods according to the theHasVNormals,theHasVColors,theHasVTexels,theHasBColors.
724   //! User is responsible of confuse vertex and bad normal orientation.
725   //! You must use AddBound() method only if the theMaxBounds constructor parameter is > 0.
726   //! You must use AddEdge()  method only if the theMaxEdges  constructor parameter is > 0.
727   Standard_EXPORT Graphic3d_ArrayOfPrimitives (const Graphic3d_TypeOfPrimitiveArray theType,
728                                                const Standard_Integer theMaxVertexs,
729                                                const Standard_Integer theMaxBounds,
730                                                const Standard_Integer theMaxEdges,
731                                                const Standard_Boolean theHasVNormals,
732                                                const Standard_Boolean theHasVColors,
733                                                const Standard_Boolean theHasBColors,
734                                                const Standard_Boolean theHasVTexels);
735
736 private: //! @name private fields
737
738   Handle(Graphic3d_IndexBuffer)  myIndices;
739   Handle(Graphic3d_Buffer)       myAttribs;
740   Handle(Graphic3d_BoundBuffer)  myBounds;
741   Graphic3d_TypeOfPrimitiveArray myType;
742   Standard_Integer myMaxBounds;
743   Standard_Integer myMaxVertexs;
744   Standard_Integer myMaxEdges;
745   Standard_Byte myVNor;
746   Standard_Byte myVTex;
747   Standard_Byte myVCol;
748
749 };
750
751 #endif // _Graphic3d_ArrayOfPrimitives_HeaderFile