Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 10:03:46

0001 // Created on: 2000-06-16
0002 // Copyright (c) 2000-2014 OPEN CASCADE SAS
0003 //
0004 // This file is part of Open CASCADE Technology software library.
0005 //
0006 // This library is free software; you can redistribute it and/or modify it under
0007 // the terms of the GNU Lesser General Public License version 2.1 as published
0008 // by the Free Software Foundation, with special exception defined in the file
0009 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
0010 // distribution for complete text of the license and disclaimer of any warranty.
0011 //
0012 // Alternatively, this file may be used under the terms of Open CASCADE
0013 // commercial license or contractual agreement.
0014 
0015 #ifndef _Graphic3d_ArrayOfPrimitives_HeaderFile
0016 #define _Graphic3d_ArrayOfPrimitives_HeaderFile
0017 
0018 #include <Graphic3d_BoundBuffer.hxx>
0019 #include <Graphic3d_ArrayFlags.hxx>
0020 #include <Graphic3d_Buffer.hxx>
0021 #include <Graphic3d_IndexBuffer.hxx>
0022 #include <Graphic3d_TypeOfPrimitiveArray.hxx>
0023 #include <gp_Dir.hxx>
0024 #include <gp_Pnt.hxx>
0025 #include <Standard_OutOfRange.hxx>
0026 #include <Standard_TypeMismatch.hxx>
0027 #include <Quantity_Color.hxx>
0028 
0029 class Graphic3d_ArrayOfPrimitives;
0030 DEFINE_STANDARD_HANDLE(Graphic3d_ArrayOfPrimitives, Standard_Transient)
0031 
0032 //! This class furnish services to defined and fill an array of primitives
0033 //! which can be passed directly to graphics rendering API.
0034 //!
0035 //! The basic interface consists of the following parts:
0036 //! 1) Specifying primitive type.
0037 //!    WARNING! Particular primitive types might be unsupported by specific hardware/graphics API (like quads and polygons).
0038 //!             It is always preferred using one of basic types having maximum compatibility:
0039 //!             Point, Triangle (or Triangle strip), Segment aka Lines (or Polyline aka Line Strip).
0040 //!    Primitive strip types can be used to reduce memory usage as alternative to Indexed arrays.
0041 //! 2) Vertex array.
0042 //!    - Specifying the (maximum) number of vertexes within array.
0043 //!    - Specifying the vertex attributes, complementary to mandatory vertex Position (normal, color, UV texture coordinates).
0044 //!    - Defining vertex values by using various versions of AddVertex() or SetVertex*() methods.
0045 //! 3) Index array (optional).
0046 //!    - Specifying the (maximum) number of indexes (edges).
0047 //!    - Defining index values by using AddEdge() method; the index value should be within number of defined Vertexes.
0048 //!
0049 //!    Indexed array allows sharing vertex data across Primitives and thus reducing memory usage,
0050 //!    since index size is much smaller then size of vertex with all its attributes.
0051 //!    It is a preferred way for defining primitive array and main alternative to Primitive Strips for optimal memory usage,
0052 //!    although it is also possible (but unusual) defining Indexed Primitive Strip.
0053 //!    Note that it is NOT possible sharing Vertex Attributes partially (e.g. share Position, but have different Normals);
0054 //!    in such cases Vertex should be entirely duplicated with all Attributes.
0055 //! 4) Bounds array (optional).
0056 //!    - Specifying the (maximum) number of bounds.
0057 //!    - Defining bounds using AddBound() methods.
0058 //!
0059 //!    Bounds allow splitting Primitive Array into sub-groups.
0060 //!    This is useful only in two cases - for specifying per-group color and for restarting Primitive Strips.
0061 //!    WARNING! Bounds within Primitive Array break rendering batches into parts (additional for loops),
0062 //!             affecting rendering performance negatively (increasing CPU load).
0063 class Graphic3d_ArrayOfPrimitives : public Standard_Transient
0064 {
0065   DEFINE_STANDARD_RTTIEXT(Graphic3d_ArrayOfPrimitives, Standard_Transient)
0066 public:
0067 
0068   //! Create an array of specified type.
0069   static Handle(Graphic3d_ArrayOfPrimitives) CreateArray (Graphic3d_TypeOfPrimitiveArray theType,
0070                                                           Standard_Integer theMaxVertexs,
0071                                                           Standard_Integer theMaxEdges,
0072                                                           Graphic3d_ArrayFlags theArrayFlags)
0073   {
0074     return CreateArray (theType, theMaxVertexs, 0, theMaxEdges, theArrayFlags);
0075   }
0076 
0077   //! Create an array of specified type.
0078   static Standard_EXPORT Handle(Graphic3d_ArrayOfPrimitives) CreateArray (Graphic3d_TypeOfPrimitiveArray theType,
0079                                                                           Standard_Integer theMaxVertexs,
0080                                                                           Standard_Integer theMaxBounds,
0081                                                                           Standard_Integer theMaxEdges,
0082                                                                           Graphic3d_ArrayFlags theArrayFlags);
0083 public:
0084 
0085   //! Destructor.
0086   Standard_EXPORT virtual ~Graphic3d_ArrayOfPrimitives();
0087 
0088   //! Returns vertex attributes buffer (colors, normals, texture coordinates).
0089   const Handle(Graphic3d_Buffer)& Attributes() const { return myAttribs; }
0090 
0091   //! Returns the type of this primitive
0092   Graphic3d_TypeOfPrimitiveArray Type() const { return myType; }
0093 
0094   //! Returns the string type of this primitive
0095   Standard_EXPORT Standard_CString StringType() const;
0096 
0097   //! Returns TRUE when vertex normals array is defined.
0098   Standard_Boolean HasVertexNormals() const { return myNormData != NULL; }
0099 
0100   //! Returns TRUE when vertex colors array is defined.
0101   Standard_Boolean HasVertexColors() const { return myColData != NULL; }
0102 
0103   //! Returns TRUE when vertex texels array is defined.
0104   Standard_Boolean HasVertexTexels() const { return myTexData != NULL; }
0105 
0106   //! Returns the number of defined vertex
0107   Standard_Integer VertexNumber() const { return myAttribs->NbElements; }
0108 
0109   //! Returns the number of allocated vertex
0110   Standard_Integer VertexNumberAllocated() const { return myAttribs->NbMaxElements(); }
0111 
0112   //! Returns the number of total items according to the array type.
0113   Standard_EXPORT Standard_Integer ItemNumber() const;
0114 
0115   //! Returns TRUE only when the contains of this array is available.
0116   Standard_EXPORT Standard_Boolean IsValid();
0117 
0118   //! Adds a vertice in the array.
0119   //! @return the actual vertex number
0120   Standard_Integer AddVertex (const gp_Pnt& theVertex) { return AddVertex (theVertex.X(), theVertex.Y(), theVertex.Z()); }
0121 
0122   //! Adds a vertice in the array.
0123   //! @return the actual vertex number
0124   Standard_Integer AddVertex (const Graphic3d_Vec3& theVertex) { return AddVertex (theVertex.x(), theVertex.y(), theVertex.z()); }
0125 
0126   //! Adds a vertice in the array.
0127   //! @return the actual vertex number
0128   Standard_Integer AddVertex (const Standard_Real theX, const Standard_Real theY, const Standard_Real theZ)
0129   {
0130     return AddVertex (RealToShortReal (theX), RealToShortReal (theY), RealToShortReal (theZ));
0131   }
0132 
0133   //! Adds a vertice in the array.
0134   //! @return the actual vertex number.
0135   Standard_Integer AddVertex (const Standard_ShortReal theX, const Standard_ShortReal theY, const Standard_ShortReal theZ)
0136   {
0137     const Standard_Integer anIndex = myAttribs->NbElements + 1;
0138     SetVertice (anIndex, theX, theY, theZ);
0139     return anIndex;
0140   }
0141 
0142   //! Adds a vertice and vertex color in the vertex array.
0143   //! Warning: theColor is ignored when the hasVColors constructor parameter is FALSE
0144   //! @return the actual vertex number
0145   Standard_Integer AddVertex (const gp_Pnt& theVertex, const Quantity_Color& theColor)
0146   {
0147     const Standard_Integer anIndex = AddVertex (theVertex);
0148     SetVertexColor (anIndex, theColor.Red(), theColor.Green(), theColor.Blue());
0149     return anIndex;
0150   }
0151 
0152   //! Adds a vertice and vertex color in the vertex array.
0153   //! Warning: theColor is ignored when the hasVColors constructor parameter is FALSE
0154   //! @code
0155   //!   theColor32 = Alpha << 24 + Blue << 16 + Green << 8 + Red
0156   //! @endcode
0157   //! @return the actual vertex number
0158   Standard_Integer AddVertex (const gp_Pnt& theVertex, const Standard_Integer theColor32)
0159   {
0160     const Standard_Integer anIndex = AddVertex (theVertex);
0161     SetVertexColor (anIndex, theColor32);
0162     return anIndex;
0163   }
0164 
0165   //! Adds a vertice and vertex color in the vertex array.
0166   //! Warning: theColor is ignored when the hasVColors constructor parameter is FALSE
0167   //! @return the actual vertex number
0168   Standard_Integer AddVertex (const gp_Pnt&           theVertex,
0169                               const Graphic3d_Vec4ub& theColor)
0170   {
0171     const Standard_Integer anIndex = AddVertex (theVertex);
0172     SetVertexColor (anIndex, theColor);
0173     return anIndex;
0174   }
0175 
0176   //! Adds a vertice and vertex normal in the vertex array.
0177   //! Warning: theNormal is ignored when the hasVNormals constructor parameter is FALSE.
0178   //! @return the actual vertex number
0179   Standard_Integer AddVertex (const gp_Pnt& theVertex, const gp_Dir& theNormal)
0180   {
0181     return AddVertex (theVertex.X(), theVertex.Y(), theVertex.Z(),
0182                       theNormal.X(), theNormal.Y(), theNormal.Z());
0183   }
0184 
0185   //! Adds a vertice and vertex normal in the vertex array.
0186   //! Warning: Normal is ignored when the hasVNormals constructor parameter is FALSE.
0187   //! @return the actual vertex number
0188   Standard_Integer AddVertex (const Standard_Real theX,  const Standard_Real theY,  const Standard_Real theZ,
0189                               const Standard_Real theNX, const Standard_Real theNY, const Standard_Real theNZ)
0190   {
0191     return AddVertex (RealToShortReal (theX),  RealToShortReal (theY),  RealToShortReal (theZ),
0192                       Standard_ShortReal (theNX), Standard_ShortReal (theNY), Standard_ShortReal (theNZ));
0193   }
0194 
0195   //! Adds a vertice and vertex normal in the vertex array.
0196   //! Warning: Normal is ignored when the hasVNormals constructor parameter is FALSE.
0197   //! @return the actual vertex number
0198   Standard_Integer AddVertex (const Standard_ShortReal theX,  const Standard_ShortReal theY,  const Standard_ShortReal theZ,
0199                               const Standard_ShortReal theNX, const Standard_ShortReal theNY, const Standard_ShortReal theNZ)
0200   {
0201     const Standard_Integer anIndex = myAttribs->NbElements + 1;
0202     SetVertice      (anIndex, theX,  theY,  theZ);
0203     SetVertexNormal (anIndex, theNX, theNY, theNZ);
0204     return anIndex;
0205   }
0206 
0207   //! Adds a vertice,vertex normal and color in the vertex array.
0208   //! Warning: theNormal is ignored when the hasVNormals constructor parameter is FALSE
0209   //! and      theColor  is ignored when the hasVColors  constructor parameter is FALSE.
0210   //! @return the actual vertex number
0211   Standard_Integer AddVertex (const gp_Pnt& theVertex, const gp_Dir& theNormal, const Quantity_Color& theColor)
0212   {
0213     const Standard_Integer anIndex = AddVertex (theVertex, theNormal);
0214     SetVertexColor (anIndex, theColor.Red(), theColor.Green(), theColor.Blue());
0215     return anIndex;
0216   }
0217 
0218   //! Adds a vertice,vertex normal and color in the vertex array.
0219   //! Warning: theNormal is ignored when the hasVNormals constructor parameter is FALSE
0220   //! and      theColor  is ignored when the hasVColors  constructor parameter is FALSE.
0221   //! @code
0222   //!   theColor32 = Alpha << 24 + Blue << 16 + Green << 8 + Red
0223   //! @endcode
0224   //! @return the actual vertex number
0225   Standard_Integer AddVertex (const gp_Pnt& theVertex, const gp_Dir& theNormal, const Standard_Integer theColor32)
0226   {
0227     const Standard_Integer anIndex = AddVertex (theVertex, theNormal);
0228     SetVertexColor (anIndex, theColor32);
0229     return anIndex;
0230   }
0231 
0232   //! Adds a vertice and vertex texture in the vertex array.
0233   //! theTexel is ignored when the hasVTexels constructor parameter is FALSE.
0234   //! @return the actual vertex number
0235   Standard_Integer AddVertex (const gp_Pnt& theVertex, const gp_Pnt2d& theTexel)
0236   {
0237     return AddVertex (theVertex.X(), theVertex.Y(), theVertex.Z(),
0238                       theTexel.X(), theTexel.Y());
0239   }
0240 
0241   //! Adds a vertice and vertex texture coordinates in the vertex array.
0242   //! Texel is ignored when the hasVTexels constructor parameter is FALSE.
0243   //! @return the actual vertex number
0244   Standard_Integer AddVertex (const Standard_Real theX, const Standard_Real theY, const Standard_Real theZ,
0245                               const Standard_Real theTX, const Standard_Real theTY)
0246   {
0247     return AddVertex (RealToShortReal (theX),  RealToShortReal (theY),  RealToShortReal (theZ),
0248                       Standard_ShortReal (theTX), Standard_ShortReal (theTY));
0249   }
0250 
0251   //! Adds a vertice and vertex texture coordinates in the vertex array.
0252   //! Texel is ignored when the hasVTexels constructor parameter is FALSE.
0253   //! @return the actual vertex number
0254   Standard_Integer AddVertex (const Standard_ShortReal theX, const Standard_ShortReal theY, const Standard_ShortReal theZ,
0255                               const Standard_ShortReal theTX, const Standard_ShortReal theTY)
0256   {
0257     const Standard_Integer anIndex = myAttribs->NbElements + 1;
0258     SetVertice     (anIndex, theX, theY, theZ);
0259     SetVertexTexel (anIndex, theTX, theTY);
0260     return anIndex;
0261   }
0262 
0263   //! Adds a vertice,vertex normal and texture in the vertex array.
0264   //! Warning: theNormal is ignored when the hasVNormals constructor parameter is FALSE
0265   //! and      theTexel  is ignored when the hasVTexels  constructor parameter is FALSE.
0266   //! @return the actual vertex number
0267   Standard_Integer AddVertex (const gp_Pnt& theVertex, const gp_Dir& theNormal, const gp_Pnt2d& theTexel)
0268   {
0269     return AddVertex (theVertex.X(), theVertex.Y(), theVertex.Z(),
0270                       theNormal.X(), theNormal.Y(), theNormal.Z(),
0271                       theTexel.X(),  theTexel.Y());
0272   }
0273 
0274   //! Adds a vertice,vertex normal and texture in the vertex array.
0275   //! Warning: Normal is ignored when the hasVNormals constructor parameter is FALSE
0276   //! and      Texel  is ignored when the hasVTexels  constructor parameter is FALSE.
0277   //! @return the actual vertex number
0278   Standard_Integer AddVertex (const Standard_Real theX,  const Standard_Real theY,  const Standard_Real theZ,
0279                               const Standard_Real theNX, const Standard_Real theNY, const Standard_Real theNZ,
0280                               const Standard_Real theTX, const Standard_Real theTY)
0281   {
0282     return AddVertex (RealToShortReal (theX), RealToShortReal (theY), RealToShortReal (theZ),
0283                       Standard_ShortReal (theNX), Standard_ShortReal (theNY), Standard_ShortReal (theNZ),
0284                       Standard_ShortReal (theTX), Standard_ShortReal (theTY));
0285   }
0286 
0287   //! Adds a vertice,vertex normal and texture in the vertex array.
0288   //! Warning: Normal is ignored when the hasVNormals constructor parameter is FALSE
0289   //!     and  Texel  is ignored when the hasVTexels  constructor parameter is FALSE.
0290   //! @return the actual vertex number
0291   Standard_Integer AddVertex (const Standard_ShortReal theX,  const Standard_ShortReal theY,  const Standard_ShortReal theZ,
0292                               const Standard_ShortReal theNX, const Standard_ShortReal theNY, const Standard_ShortReal theNZ,
0293                               const Standard_ShortReal theTX, const Standard_ShortReal theTY)
0294   {
0295     const Standard_Integer anIndex = myAttribs->NbElements + 1;
0296     SetVertice     (anIndex, theX,  theY,  theZ);
0297     SetVertexNormal(anIndex, theNX, theNY, theNZ);
0298     SetVertexTexel (anIndex, theTX, theTY);
0299     return anIndex;
0300   }
0301 
0302   //! Change the vertice of rank theIndex in the array.
0303   //! @param[in] theIndex  node index within [1, VertexNumberAllocated()] range
0304   //! @param[in] theVertex 3D coordinates
0305   void SetVertice (const Standard_Integer theIndex, const gp_Pnt& theVertex)
0306   {
0307     SetVertice (theIndex, Standard_ShortReal (theVertex.X()), Standard_ShortReal (theVertex.Y()), Standard_ShortReal (theVertex.Z()));
0308   }
0309 
0310   //! Change the vertice in the array.
0311   //! @param[in] theIndex node index within [1, VertexNumberAllocated()] range
0312   //! @param[in] theX coordinate X
0313   //! @param[in] theY coordinate Y
0314   //! @param[in] theZ coordinate Z
0315   void SetVertice (const Standard_Integer theIndex, const Standard_ShortReal theX, const Standard_ShortReal theY, const Standard_ShortReal theZ)
0316   {
0317     Standard_OutOfRange_Raise_if (theIndex < 1 || theIndex > myAttribs->NbMaxElements(), "BAD VERTEX index");
0318     Graphic3d_Vec3& aVec = *reinterpret_cast<Graphic3d_Vec3*> (myAttribs->ChangeData() + myPosStride * ((Standard_Size)theIndex - 1));
0319     aVec.x() = theX;
0320     aVec.y() = theY;
0321     aVec.z() = theZ;
0322     if (myAttribs->NbElements < theIndex)
0323     {
0324       myAttribs->NbElements = theIndex;
0325     }
0326   }
0327 
0328   //! Change the vertex color in the array.
0329   //! @param[in] theIndex node index within [1, VertexNumberAllocated()] range
0330   //! @param[in] theColor node color
0331   void SetVertexColor (const Standard_Integer theIndex, const Quantity_Color& theColor)
0332   {
0333     SetVertexColor (theIndex, theColor.Red(), theColor.Green(), theColor.Blue());
0334   }
0335 
0336   //! Change the vertex color in the array.
0337   //! @param[in] theIndex node index within [1, VertexNumberAllocated()] range
0338   //! @param[in] theR red   color value within [0, 1] range
0339   //! @param[in] theG green color value within [0, 1] range
0340   //! @param[in] theB blue  color value within [0, 1] range
0341   void SetVertexColor (const Standard_Integer theIndex, const Standard_Real theR, const Standard_Real theG, const Standard_Real theB)
0342   {
0343     Standard_OutOfRange_Raise_if (theIndex < 1 || theIndex > myAttribs->NbMaxElements(), "BAD VERTEX index");
0344     if (myColData != NULL)
0345     {
0346       Graphic3d_Vec4ub* aColorPtr = reinterpret_cast<Graphic3d_Vec4ub* >(myColData + myColStride * ((Standard_Size)theIndex - 1));
0347       aColorPtr->SetValues (Standard_Byte(theR * 255.0),
0348                             Standard_Byte(theG * 255.0),
0349                             Standard_Byte(theB * 255.0), 255);
0350     }
0351     myAttribs->NbElements = Max (theIndex, myAttribs->NbElements);
0352   }
0353 
0354   //! Change the vertex color in the array.
0355   //! @param[in] theIndex node index within [1, VertexNumberAllocated()] range
0356   //! @param[in] theColor node RGBA color values within [0, 255] range
0357   void SetVertexColor (const Standard_Integer  theIndex,
0358                        const Graphic3d_Vec4ub& theColor)
0359   {
0360     Standard_OutOfRange_Raise_if (theIndex < 1 || theIndex > myAttribs->NbMaxElements(), "BAD VERTEX index");
0361     if (myColData != NULL)
0362     {
0363       Graphic3d_Vec4ub* aColorPtr =  reinterpret_cast<Graphic3d_Vec4ub* >(myColData + myColStride * ((Standard_Size)theIndex - 1));
0364       (*aColorPtr) = theColor;
0365     }
0366     myAttribs->NbElements = Max (theIndex, myAttribs->NbElements);
0367   }
0368 
0369   //! Change the vertex color in the array.
0370   //! @code
0371   //!   theColor32 = Alpha << 24 + Blue << 16 + Green << 8 + Red
0372   //! @endcode
0373   //! @param[in] theIndex   node index within [1, VertexNumberAllocated()] range
0374   //! @param[in] theColor32 packed RGBA color values
0375   void SetVertexColor (const Standard_Integer theIndex, const Standard_Integer theColor32)
0376   {
0377     Standard_OutOfRange_Raise_if (theIndex < 1 || theIndex > myAttribs->NbMaxElements(), "BAD VERTEX index");
0378     if (myColData != NULL)
0379     {
0380       *reinterpret_cast<Standard_Integer* >(myColData + myColStride * ((Standard_Size)theIndex - 1)) = theColor32;
0381     }
0382   }
0383 
0384   //! Change the vertex normal in the array.
0385   //! @param[in] theIndex  node index within [1, VertexNumberAllocated()] range
0386   //! @param[in] theNormal normalized surface normal
0387   void SetVertexNormal (const Standard_Integer theIndex, const gp_Dir& theNormal)
0388   {
0389     SetVertexNormal (theIndex, theNormal.X(), theNormal.Y(), theNormal.Z());
0390   }
0391 
0392   //! Change the vertex normal in the array.
0393   //! @param[in] theIndex node index within [1, VertexNumberAllocated()] range
0394   //! @param[in] theNX surface normal X component
0395   //! @param[in] theNY surface normal Y component
0396   //! @param[in] theNZ surface normal Z component
0397   void SetVertexNormal (const Standard_Integer theIndex, const Standard_Real theNX, const Standard_Real theNY, const Standard_Real theNZ)
0398   {
0399     Standard_OutOfRange_Raise_if (theIndex < 1 || theIndex > myAttribs->NbMaxElements(), "BAD VERTEX index");
0400     if (myNormData != NULL)
0401     {
0402       Graphic3d_Vec3& aVec = *reinterpret_cast<Graphic3d_Vec3* >(myNormData + myNormStride * ((Standard_Size)theIndex - 1));
0403       aVec.x() = Standard_ShortReal (theNX);
0404       aVec.y() = Standard_ShortReal (theNY);
0405       aVec.z() = Standard_ShortReal (theNZ);
0406     }
0407     myAttribs->NbElements = Max (theIndex, myAttribs->NbElements);
0408   }
0409 
0410   //! Change the vertex texel in the array.
0411   //! @param[in] theIndex node index within [1, VertexNumberAllocated()] range
0412   //! @param[in] theTexel node UV coordinates
0413   void SetVertexTexel (const Standard_Integer theIndex, const gp_Pnt2d& theTexel)
0414   {
0415     SetVertexTexel (theIndex, theTexel.X(), theTexel.Y());
0416   }
0417 
0418   //! Change the vertex texel in the array.
0419   //! @param[in] theIndex node index within [1, VertexNumberAllocated()] range
0420   //! @param[in] theTX node U coordinate
0421   //! @param[in] theTY node V coordinate
0422   void SetVertexTexel (const Standard_Integer theIndex, const Standard_Real theTX, const Standard_Real theTY)
0423   {
0424     Standard_OutOfRange_Raise_if (theIndex < 1 || theIndex > myAttribs->NbMaxElements(), "BAD VERTEX index");
0425     if (myTexData != NULL)
0426     {
0427       Graphic3d_Vec2& aVec = *reinterpret_cast<Graphic3d_Vec2* >(myTexData + myTexStride * ((Standard_Size)theIndex - 1));
0428       aVec.x() = Standard_ShortReal (theTX);
0429       aVec.y() = Standard_ShortReal (theTY);
0430     }
0431     myAttribs->NbElements = Max (theIndex, myAttribs->NbElements);
0432   }
0433 
0434   //! Returns the vertice from the vertex table if defined.
0435   //! @param[in] theRank node index within [1, VertexNumber()] range
0436   //! @return node 3D coordinates
0437   gp_Pnt Vertice (const Standard_Integer theRank) const
0438   {
0439     Standard_Real anXYZ[3];
0440     Vertice (theRank, anXYZ[0], anXYZ[1], anXYZ[2]);
0441     return gp_Pnt (anXYZ[0], anXYZ[1], anXYZ[2]);
0442   }
0443 
0444   //! Returns the vertice coordinates at rank theRank from the vertex table if defined.
0445   //! @param[in]  theRank node index within [1, VertexNumber()] range
0446   //! @param[out] theX node X coordinate value
0447   //! @param[out] theY node Y coordinate value
0448   //! @param[out] theZ node Z coordinate value
0449   void Vertice (const Standard_Integer theRank, Standard_Real& theX, Standard_Real& theY, Standard_Real& theZ) const
0450   {
0451     theX = theY = theZ = 0.0;
0452     Standard_OutOfRange_Raise_if (theRank < 1 || theRank > myAttribs->NbElements, "BAD VERTEX index");
0453     const Graphic3d_Vec3& aVec = *reinterpret_cast<const Graphic3d_Vec3*> (myAttribs->Data() + myPosStride * ((Standard_Size)theRank - 1));
0454     theX = Standard_Real(aVec.x());
0455     theY = Standard_Real(aVec.y());
0456     theZ = Standard_Real(aVec.z());
0457   }
0458 
0459   //! Returns the vertex color at rank theRank from the vertex table if defined.
0460   //! @param[in] theRank node index within [1, VertexNumber()] range
0461   //! @return node color RGB value
0462   Quantity_Color VertexColor (const Standard_Integer theRank) const
0463   {
0464     Standard_Real anRGB[3];
0465     VertexColor (theRank, anRGB[0], anRGB[1], anRGB[2]);
0466     return Quantity_Color (anRGB[0], anRGB[1], anRGB[2], Quantity_TOC_RGB);
0467   }
0468 
0469   //! Returns the vertex color from the vertex table if defined.
0470   //! @param[in]  theIndex node index within [1, VertexNumber()] range
0471   //! @param[out] theColor node RGBA color values within [0, 255] range
0472   void VertexColor (const Standard_Integer theIndex,
0473                     Graphic3d_Vec4ub&      theColor) const
0474   {
0475     Standard_OutOfRange_Raise_if (myColData == NULL || theIndex < 1 || theIndex > myAttribs->NbElements, "BAD VERTEX index");
0476     theColor = *reinterpret_cast<const Graphic3d_Vec4ub* >(myColData + myColStride * ((Standard_Size)theIndex - 1));
0477   }
0478 
0479   //! Returns the vertex color values from the vertex table if defined.
0480   //! @param[in]  theRank node index within [1, VertexNumber()] range
0481   //! @param[out] theR node red   color component value within [0, 1] range
0482   //! @param[out] theG node green color component value within [0, 1] range
0483   //! @param[out] theB node blue  color component value within [0, 1] range
0484   void VertexColor (const Standard_Integer theRank, Standard_Real& theR, Standard_Real& theG, Standard_Real& theB) const
0485   {
0486     theR = theG = theB = 0.0;
0487     Standard_OutOfRange_Raise_if (theRank < 1 || theRank > myAttribs->NbElements, "BAD VERTEX index");
0488     if (myColData == NULL)
0489     {
0490       return;
0491     }
0492     const Graphic3d_Vec4ub& aColor = *reinterpret_cast<const Graphic3d_Vec4ub* >(myColData + myColStride * ((Standard_Size)theRank - 1));
0493     theR = Standard_Real(aColor.r()) / 255.0;
0494     theG = Standard_Real(aColor.g()) / 255.0;
0495     theB = Standard_Real(aColor.b()) / 255.0;
0496   }
0497 
0498   //! Returns the vertex color values from the vertex table if defined.
0499   //! @param[in]  theRank  node index within [1, VertexNumber()] range
0500   //! @param[out] theColor node RGBA color packed into 32-bit integer
0501   void VertexColor (const Standard_Integer theRank, Standard_Integer& theColor) const
0502   {
0503     Standard_OutOfRange_Raise_if (theRank < 1 || theRank > myAttribs->NbElements, "BAD VERTEX index");
0504     if (myColData != NULL)
0505     {
0506       theColor = *reinterpret_cast<const Standard_Integer* >(myColData + myColStride * ((Standard_Size)theRank - 1));
0507     }
0508   }
0509 
0510   //! Returns the vertex normal from the vertex table if defined.
0511   //! @param[in] theRank node index within [1, VertexNumber()] range
0512   //! @return normalized 3D vector defining surface normal
0513   gp_Dir VertexNormal (const Standard_Integer theRank) const
0514   {
0515     Standard_Real anXYZ[3];
0516     VertexNormal (theRank, anXYZ[0], anXYZ[1], anXYZ[2]);
0517     return gp_Dir (anXYZ[0], anXYZ[1], anXYZ[2]);
0518   }
0519 
0520   //! Returns the vertex normal coordinates at rank theRank from the vertex table if defined.
0521   //! @param[in]  theRank node index within [1, VertexNumber()] range
0522   //! @param[out] theNX   normal X coordinate
0523   //! @param[out] theNY   normal Y coordinate
0524   //! @param[out] theNZ   normal Z coordinate
0525   void VertexNormal (const Standard_Integer theRank, Standard_Real& theNX, Standard_Real& theNY, Standard_Real& theNZ) const
0526   {
0527     theNX = theNY = theNZ = 0.0;
0528     Standard_OutOfRange_Raise_if (theRank < 1 || theRank > myAttribs->NbElements, "BAD VERTEX index");
0529     if (myNormData != NULL)
0530     {
0531       const Graphic3d_Vec3& aVec = *reinterpret_cast<const Graphic3d_Vec3* >(myNormData + myNormStride * ((Standard_Size)theRank - 1));
0532       theNX = Standard_Real(aVec.x());
0533       theNY = Standard_Real(aVec.y());
0534       theNZ = Standard_Real(aVec.z());
0535     }
0536   }
0537 
0538   //! Returns the vertex texture at rank theRank from the vertex table if defined.
0539   //! @param[in] theRank node index within [1, VertexNumber()] range
0540   //! @return UV coordinates
0541   gp_Pnt2d VertexTexel (const Standard_Integer theRank) const
0542   {
0543     Standard_Real anXY[2];
0544     VertexTexel (theRank, anXY[0], anXY[1]);
0545     return gp_Pnt2d (anXY[0], anXY[1]);
0546   }
0547 
0548   //! Returns the vertex texture coordinates at rank theRank from the vertex table if defined.
0549   //! @param[in]  theRank node index within [1, VertexNumber()] range
0550   //! @param[out] theTX texel U coordinate value
0551   //! @param[out] theTY texel V coordinate value
0552   void VertexTexel (const Standard_Integer theRank, Standard_Real& theTX, Standard_Real& theTY) const
0553   {
0554     theTX = theTY = 0.0;
0555     Standard_OutOfRange_Raise_if (theRank < 1 || theRank > myAttribs->NbElements, "BAD VERTEX index");
0556     if (myTexData != NULL)
0557     {
0558       const Graphic3d_Vec2& aVec = *reinterpret_cast<const Graphic3d_Vec2* >(myTexData + myTexStride * ((Standard_Size)theRank - 1));
0559       theTX = Standard_Real(aVec.x());
0560       theTY = Standard_Real(aVec.y());
0561     }
0562   }
0563 
0564 public: //! @name optional array of Indices/Edges for using shared Vertex data
0565 
0566   //! Returns optional index buffer.
0567   const Handle(Graphic3d_IndexBuffer)& Indices() const { return myIndices; }
0568 
0569   //! Returns the number of defined edges
0570   Standard_Integer EdgeNumber() const { return !myIndices.IsNull() ? myIndices->NbElements : -1; }
0571 
0572   //! Returns the number of allocated edges
0573   Standard_Integer EdgeNumberAllocated() const { return !myIndices.IsNull() ? myIndices->NbMaxElements() : 0; }
0574 
0575   //! Returns the vertex index at rank theRank in the range [1,EdgeNumber()]
0576   Standard_Integer Edge (const Standard_Integer theRank) const
0577   {
0578     Standard_OutOfRange_Raise_if (myIndices.IsNull() || theRank < 1 || theRank > myIndices->NbElements, "BAD EDGE index");
0579     return Standard_Integer(myIndices->Index (theRank - 1) + 1);
0580   }
0581 
0582   //! Adds an edge in the range [1,VertexNumber()] in the array.
0583   //! @return the actual edges number
0584   Standard_EXPORT Standard_Integer AddEdge (const Standard_Integer theVertexIndex);
0585 
0586   //! Convenience method, adds two vertex indices (a segment) in the range [1,VertexNumber()] in the array.
0587   //! @return the actual edges number
0588   Standard_Integer AddEdges (Standard_Integer theVertexIndex1,
0589                              Standard_Integer theVertexIndex2)
0590   {
0591     AddEdge (theVertexIndex1);
0592     return AddEdge (theVertexIndex2);
0593   }
0594 
0595   //! Convenience method, adds two vertex indices (a segment) in the range [1,VertexNumber()] in the array of segments (Graphic3d_TOPA_SEGMENTS).
0596   //! Raises exception if array is not of type Graphic3d_TOPA_SEGMENTS.
0597   //! @return the actual edges number
0598   Standard_Integer AddSegmentEdges (Standard_Integer theVertexIndex1,
0599                                     Standard_Integer theVertexIndex2)
0600   {
0601     Standard_TypeMismatch_Raise_if (myType != Graphic3d_TOPA_SEGMENTS, "Not array of segments");
0602     return AddEdges (theVertexIndex1, theVertexIndex2);
0603   }
0604 
0605   //! Convenience method, adds three vertex indices (a triangle) in the range [1,VertexNumber()] in the array.
0606   //! @return the actual edges number
0607   Standard_Integer AddEdges (Standard_Integer theVertexIndex1,
0608                              Standard_Integer theVertexIndex2,
0609                              Standard_Integer theVertexIndex3)
0610   {
0611     AddEdge (theVertexIndex1);
0612     AddEdge (theVertexIndex2);
0613     return AddEdge (theVertexIndex3);
0614   }
0615 
0616   //! Convenience method, adds three vertex indices of triangle in the range [1,VertexNumber()] in the array of triangles.
0617   //! Raises exception if array is not of type Graphic3d_TOPA_TRIANGLES.
0618   //! @return the actual edges number
0619   Standard_Integer AddTriangleEdges (Standard_Integer theVertexIndex1,
0620                                      Standard_Integer theVertexIndex2,
0621                                      Standard_Integer theVertexIndex3)
0622   {
0623     Standard_TypeMismatch_Raise_if (myType != Graphic3d_TOPA_TRIANGLES, "Not array of triangles");
0624     return AddEdges (theVertexIndex1, theVertexIndex2, theVertexIndex3);
0625   }
0626 
0627   //! Convenience method, adds three vertex indices of triangle in the range [1,VertexNumber()] in the array of triangles.
0628   //! Raises exception if array is not of type Graphic3d_TOPA_TRIANGLES.
0629   //! @return the actual edges number
0630   Standard_Integer AddTriangleEdges (const Graphic3d_Vec3i& theIndexes)
0631   {
0632     Standard_TypeMismatch_Raise_if (myType != Graphic3d_TOPA_TRIANGLES, "Not array of triangles");
0633     return AddEdges (theIndexes[0], theIndexes[1], theIndexes[2]);
0634   }
0635 
0636   //! Convenience method, adds three vertex indices (4th component is ignored) of triangle in the range [1,VertexNumber()] in the array of triangles.
0637   //! Raises exception if array is not of type Graphic3d_TOPA_TRIANGLES.
0638   //! @return the actual edges number
0639   Standard_Integer AddTriangleEdges (const Graphic3d_Vec4i& theIndexes)
0640   {
0641     Standard_TypeMismatch_Raise_if (myType != Graphic3d_TOPA_TRIANGLES, "Not array of triangles");
0642     return AddEdges (theIndexes[0], theIndexes[1], theIndexes[2]);
0643   }
0644 
0645   //! Convenience method, adds four vertex indices (a quad) in the range [1,VertexNumber()] in the array.
0646   //! @return the actual edges number
0647   Standard_Integer AddEdges (Standard_Integer theVertexIndex1,
0648                              Standard_Integer theVertexIndex2,
0649                              Standard_Integer theVertexIndex3,
0650                              Standard_Integer theVertexIndex4)
0651   {
0652     AddEdge (theVertexIndex1);
0653     AddEdge (theVertexIndex2);
0654     AddEdge (theVertexIndex3);
0655     return AddEdge (theVertexIndex4);
0656   }
0657 
0658   //! Convenience method, adds four vertex indices (a quad) in the range [1,VertexNumber()] in the array of quads.
0659   //! Raises exception if array is not of type Graphic3d_TOPA_QUADRANGLES.
0660   //! @return the actual edges number
0661   Standard_Integer AddQuadEdges (Standard_Integer theVertexIndex1,
0662                                  Standard_Integer theVertexIndex2,
0663                                  Standard_Integer theVertexIndex3,
0664                                  Standard_Integer theVertexIndex4)
0665   {
0666     Standard_TypeMismatch_Raise_if (myType != Graphic3d_TOPA_QUADRANGLES, "Not array of quads");
0667     return AddEdges (theVertexIndex1, theVertexIndex2, theVertexIndex3, theVertexIndex4);
0668   }
0669 
0670   //! Convenience method, adds quad indices in the range [1,VertexNumber()] into array or triangles as two triangles.
0671   //! Raises exception if array is not of type Graphic3d_TOPA_TRIANGLES.
0672   //! @return the actual edges number
0673   Standard_Integer AddQuadTriangleEdges (Standard_Integer theVertexIndex1,
0674                                          Standard_Integer theVertexIndex2,
0675                                          Standard_Integer theVertexIndex3,
0676                                          Standard_Integer theVertexIndex4)
0677   {
0678     AddTriangleEdges (theVertexIndex3, theVertexIndex1, theVertexIndex2);
0679     return AddTriangleEdges (theVertexIndex1, theVertexIndex3, theVertexIndex4);
0680   }
0681 
0682   //! Convenience method, adds quad indices in the range [1,VertexNumber()] into array or triangles as two triangles.
0683   //! Raises exception if array is not of type Graphic3d_TOPA_TRIANGLES.
0684   //! @return the actual edges number
0685   Standard_Integer AddQuadTriangleEdges (const Graphic3d_Vec4i& theIndexes)
0686   {
0687     return AddQuadTriangleEdges (theIndexes[0], theIndexes[1], theIndexes[2], theIndexes[3]);
0688   }
0689 
0690   //! Add triangle strip into indexed triangulation array.
0691   //! N-2 triangles are added from N input nodes.
0692   //! Raises exception if array is not of type Graphic3d_TOPA_TRIANGLES.
0693   //! @param theVertexLower [in] index of first node defining triangle strip
0694   //! @param theVertexUpper [in] index of last  node defining triangle strip
0695   Standard_EXPORT void AddTriangleStripEdges (Standard_Integer theVertexLower,
0696                                               Standard_Integer theVertexUpper);
0697 
0698   //! Add triangle fan into indexed triangulation array.
0699   //! N-2 triangles are added from N input nodes (or N-1 with closed flag).
0700   //! Raises exception if array is not of type Graphic3d_TOPA_TRIANGLES.
0701   //! @param theVertexLower [in] index of first node defining triangle fun (center)
0702   //! @param theVertexUpper [in] index of last  node defining triangle fun
0703   //! @param theToClose [in] close triangle fan (connect first and last points)
0704   Standard_EXPORT void AddTriangleFanEdges (Standard_Integer theVertexLower,
0705                                             Standard_Integer theVertexUpper,
0706                                             Standard_Boolean theToClose);
0707 
0708   //! Add line strip (polyline) into indexed segments array.
0709   //! N-1 segments are added from N input nodes (or N with closed flag).
0710   //! Raises exception if array is not of type Graphic3d_TOPA_SEGMENTS.
0711   //! @param theVertexLower [in] index of first node defining line strip fun (center)
0712   //! @param theVertexUpper [in] index of last  node defining triangle fun
0713   //! @param theToClose [in] close triangle fan (connect first and last points)
0714   Standard_EXPORT void AddPolylineEdges (Standard_Integer theVertexLower,
0715                                          Standard_Integer theVertexUpper,
0716                                          Standard_Boolean theToClose);
0717 
0718 public: //! @name optional array of Bounds/Subgroups within primitive array (e.g. restarting primitives / assigning colors)
0719 
0720   //! Returns optional bounds buffer.
0721   const Handle(Graphic3d_BoundBuffer)& Bounds() const { return myBounds; }
0722 
0723   //! Returns TRUE when bound colors array is defined.
0724   Standard_Boolean HasBoundColors() const { return !myBounds.IsNull() && myBounds->Colors != NULL; }
0725 
0726   //! Returns the number of defined bounds
0727   Standard_Integer BoundNumber() const { return !myBounds.IsNull() ? myBounds->NbBounds : -1; }
0728 
0729   //! Returns the number of allocated bounds
0730   Standard_Integer BoundNumberAllocated() const { return !myBounds.IsNull() ? myBounds->NbMaxBounds : 0; }
0731 
0732   //! Returns the edge number at rank theRank.
0733   Standard_Integer Bound (const Standard_Integer theRank) const
0734   {
0735     Standard_OutOfRange_Raise_if (myBounds.IsNull() || theRank < 1 || theRank > myBounds->NbBounds, "BAD BOUND index");
0736     return myBounds->Bounds[theRank - 1];
0737   }
0738 
0739   //! Returns the bound color at rank theRank from the bound table if defined.
0740   Quantity_Color BoundColor (const Standard_Integer theRank) const
0741   {
0742     Standard_Real anRGB[3] = {0.0, 0.0, 0.0};
0743     BoundColor (theRank, anRGB[0], anRGB[1], anRGB[2]);
0744     return Quantity_Color (anRGB[0], anRGB[1], anRGB[2], Quantity_TOC_RGB);
0745   }
0746 
0747   //! Returns the bound color values at rank theRank from the bound table if defined.
0748   void BoundColor (const Standard_Integer theRank, Standard_Real& theR, Standard_Real& theG, Standard_Real& theB) const
0749   {
0750     Standard_OutOfRange_Raise_if (myBounds.IsNull() || myBounds->Colors == NULL || theRank < 1 || theRank > myBounds->NbBounds, "BAD BOUND index");
0751     const Graphic3d_Vec4& aVec = myBounds->Colors[theRank - 1];
0752     theR = Standard_Real(aVec.r());
0753     theG = Standard_Real(aVec.g());
0754     theB = Standard_Real(aVec.b());
0755   }
0756 
0757   //! Adds a bound of length theEdgeNumber in the bound array
0758   //! @return the actual bounds number
0759   Standard_EXPORT Standard_Integer AddBound (const Standard_Integer theEdgeNumber);
0760 
0761   //! Adds a bound of length theEdgeNumber and bound color theBColor in the bound array.
0762   //! Warning: theBColor is ignored when the hasBColors constructor parameter is FALSE
0763   //! @return the actual bounds number
0764   Standard_Integer AddBound (const Standard_Integer theEdgeNumber, const Quantity_Color& theBColor)
0765   {
0766     return AddBound (theEdgeNumber, theBColor.Red(), theBColor.Green(), theBColor.Blue());
0767   }
0768 
0769   //! Adds a bound of length theEdgeNumber and bound color coordinates in the bound array.
0770   //! Warning: <theR,theG,theB> are ignored when the hasBColors constructor parameter is FALSE
0771   //! @return the actual bounds number
0772   Standard_EXPORT Standard_Integer AddBound (const Standard_Integer theEdgeNumber, const Standard_Real theR, const Standard_Real theG, const Standard_Real theB);
0773 
0774   //! Change the bound color of rank theIndex in the array.
0775   void SetBoundColor (const Standard_Integer theIndex, const Quantity_Color& theColor)
0776   {
0777     SetBoundColor (theIndex, theColor.Red(), theColor.Green(), theColor.Blue());
0778   }
0779 
0780   //! Change the bound color of rank theIndex in the array.
0781   void SetBoundColor (const Standard_Integer theIndex, const Standard_Real theR, const Standard_Real theG, const Standard_Real theB)
0782   {
0783     if (myBounds.IsNull())
0784     {
0785       return;
0786     }
0787     Standard_OutOfRange_Raise_if (myBounds.IsNull() || myBounds->Colors == NULL || theIndex < 1 || theIndex > myBounds->NbMaxBounds, "BAD BOUND index");
0788     Graphic3d_Vec4& aVec = myBounds->Colors[theIndex - 1];
0789     aVec.r() = Standard_ShortReal (theR);
0790     aVec.g() = Standard_ShortReal (theG);
0791     aVec.b() = Standard_ShortReal (theB);
0792     aVec.a() = 1.0f;
0793     myBounds->NbBounds = Max (theIndex, myBounds->NbBounds);
0794   }
0795 
0796 protected: //! @name protected constructors
0797 
0798   //! Main constructor.
0799   //! @param theType       type of primitive
0800   //! @param theMaxVertexs length of vertex attributes buffer to be allocated (maximum number of vertexes, @sa ::AddVertex())
0801   //! @param theMaxBounds  length of bounds buffer to be allocated (maximum number of bounds, @sa ::AddBound())
0802   //! @param theMaxEdges   length of edges (index) buffer to be allocated (maximum number of indexes @sa ::AddEdge())
0803   //! @param theArrayFlags array flags
0804   Graphic3d_ArrayOfPrimitives (Graphic3d_TypeOfPrimitiveArray theType,
0805                                Standard_Integer theMaxVertexs,
0806                                Standard_Integer theMaxBounds,
0807                                Standard_Integer theMaxEdges,
0808                                Graphic3d_ArrayFlags theArrayFlags)
0809   : myNormData (NULL), myTexData (NULL), myColData (NULL), myPosStride (0), myNormStride (0), myTexStride (0), myColStride (0),
0810     myType (Graphic3d_TOPA_UNDEFINED)
0811   {
0812     init (theType, theMaxVertexs, theMaxBounds, theMaxEdges, theArrayFlags);
0813   }
0814 
0815   //! Array constructor.
0816   Standard_EXPORT void init (Graphic3d_TypeOfPrimitiveArray theType,
0817                              Standard_Integer theMaxVertexs,
0818                              Standard_Integer theMaxBounds,
0819                              Standard_Integer theMaxEdges,
0820                              Graphic3d_ArrayFlags theArrayFlags);
0821 
0822 private: //! @name private fields
0823 
0824   Handle(Graphic3d_IndexBuffer)  myIndices;
0825   Handle(Graphic3d_Buffer)       myAttribs;
0826   Handle(Graphic3d_BoundBuffer)  myBounds;
0827   Standard_Byte* myNormData;
0828   Standard_Byte* myTexData;
0829   Standard_Byte* myColData;
0830   Standard_Size  myPosStride;
0831   Standard_Size  myNormStride;
0832   Standard_Size  myTexStride;
0833   Standard_Size  myColStride;
0834   Graphic3d_TypeOfPrimitiveArray myType;
0835 
0836 };
0837 
0838 #endif // _Graphic3d_ArrayOfPrimitives_HeaderFile