1 // Created on: 2000-06-16
2 // Copyright (c) 2000-2014 OPEN CASCADE SAS
4 // This file is part of Open CASCADE Technology software library.
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.
12 // Alternatively, this file may be used under the terms of Open CASCADE
13 // commercial license or contractual agreement.
15 #ifndef _Graphic3d_ArrayOfPrimitives_HeaderFile
16 #define _Graphic3d_ArrayOfPrimitives_HeaderFile
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>
25 #include <Standard_OutOfRange.hxx>
26 #include <Standard_TypeMismatch.hxx>
27 #include <Quantity_Color.hxx>
29 class Graphic3d_ArrayOfPrimitives;
30 DEFINE_STANDARD_HANDLE(Graphic3d_ArrayOfPrimitives, Standard_Transient)
32 //! This class furnish services to defined and fill an array of primitives
33 //! which can be passed directly to graphics rendering API.
35 //! The basic interface consists of the following parts:
36 //! 1) Specifying primitive type.
37 //! WARNING! Particular primitive types might be unsupported by specific hardware/graphics API (like quads and polygons).
38 //! It is always preferred using one of basic types having maximum compatibility:
39 //! Point, Triangle (or Triangle strip), Segment aka Lines (or Polyline aka Line Strip).
40 //! Primitive strip types can be used to reduce memory usage as alternative to Indexed arrays.
42 //! - Specifying the (maximum) number of vertexes within array.
43 //! - Specifying the vertex attributes, complementary to mandatory vertex Position (normal, color, UV texture coordinates).
44 //! - Defining vertex values by using various versions of AddVertex() or SetVertex*() methods.
45 //! 3) Index array (optional).
46 //! - Specifying the (maximum) number of indexes (edges).
47 //! - Defining index values by using AddEdge() method; the index value should be within number of defined Vertexes.
49 //! Indexed array allows sharing vertex data across Primitives and thus reducing memory usage,
50 //! since index size is much smaller then size of vertex with all its attributes.
51 //! It is a preferred way for defining primitive array and main alternative to Primitive Strips for optimal memory usage,
52 //! although it is also possible (but unusual) defining Indexed Primitive Strip.
53 //! Note that it is NOT possible sharing Vertex Attributes partially (e.g. share Position, but have different Normals);
54 //! in such cases Vertex should be entirely duplicated with all Attributes.
55 //! 4) Bounds array (optional).
56 //! - Specifying the (maximum) number of bounds.
57 //! - Defining bounds using AddBound() methods.
59 //! Bounds allow splitting Primitive Array into sub-groups.
60 //! This is useful only in two cases - for specifying per-group color and for restarting Primitive Strips.
61 //! WARNING! Bounds within Primitive Array break rendering batches into parts (additional for loops),
62 //! affecting rendering performance negatively (increasing CPU load).
63 class Graphic3d_ArrayOfPrimitives : public Standard_Transient
65 DEFINE_STANDARD_RTTIEXT(Graphic3d_ArrayOfPrimitives, Standard_Transient)
68 //! Create an array of specified type.
69 static Handle(Graphic3d_ArrayOfPrimitives) CreateArray (Graphic3d_TypeOfPrimitiveArray theType,
70 Standard_Integer theMaxVertexs,
71 Standard_Integer theMaxEdges,
72 Graphic3d_ArrayFlags theArrayFlags)
74 return CreateArray (theType, theMaxVertexs, 0, theMaxEdges, theArrayFlags);
77 //! Create an array of specified type.
78 static Standard_EXPORT Handle(Graphic3d_ArrayOfPrimitives) CreateArray (Graphic3d_TypeOfPrimitiveArray theType,
79 Standard_Integer theMaxVertexs,
80 Standard_Integer theMaxBounds,
81 Standard_Integer theMaxEdges,
82 Graphic3d_ArrayFlags theArrayFlags);
86 Standard_EXPORT virtual ~Graphic3d_ArrayOfPrimitives();
88 //! Returns vertex attributes buffer (colors, normals, texture coordinates).
89 const Handle(Graphic3d_Buffer)& Attributes() const { return myAttribs; }
91 //! Returns the type of this primitive
92 Graphic3d_TypeOfPrimitiveArray Type() const { return myType; }
94 //! Returns the string type of this primitive
95 Standard_EXPORT Standard_CString StringType() const;
97 //! Returns TRUE when vertex normals array is defined.
98 Standard_Boolean HasVertexNormals() const { return myNormData != NULL; }
100 //! Returns TRUE when vertex colors array is defined.
101 Standard_Boolean HasVertexColors() const { return myColData != NULL; }
103 //! Returns TRUE when vertex texels array is defined.
104 Standard_Boolean HasVertexTexels() const { return myTexData != NULL; }
106 //! Returns the number of defined vertex
107 Standard_Integer VertexNumber() const { return myAttribs->NbElements; }
109 //! Returns the number of allocated vertex
110 Standard_Integer VertexNumberAllocated() const { return myAttribs->NbMaxElements(); }
112 //! Returns the number of total items according to the array type.
113 Standard_EXPORT Standard_Integer ItemNumber() const;
115 //! Returns TRUE only when the contains of this array is available.
116 Standard_EXPORT Standard_Boolean IsValid();
118 //! Adds a vertice in the array.
119 //! @return the actual vertex number
120 Standard_Integer AddVertex (const gp_Pnt& theVertex) { return AddVertex (theVertex.X(), theVertex.Y(), theVertex.Z()); }
122 //! Adds a vertice in the array.
123 //! @return the actual vertex number
124 Standard_Integer AddVertex (const Graphic3d_Vec3& theVertex) { return AddVertex (theVertex.x(), theVertex.y(), theVertex.z()); }
126 //! Adds a vertice in the array.
127 //! @return the actual vertex number
128 Standard_Integer AddVertex (const Standard_Real theX, const Standard_Real theY, const Standard_Real theZ)
130 return AddVertex (RealToShortReal (theX), RealToShortReal (theY), RealToShortReal (theZ));
133 //! Adds a vertice in the array.
134 //! @return the actual vertex number.
135 Standard_Integer AddVertex (const Standard_ShortReal theX, const Standard_ShortReal theY, const Standard_ShortReal theZ)
137 const Standard_Integer anIndex = myAttribs->NbElements + 1;
138 SetVertice (anIndex, theX, theY, theZ);
142 //! Adds a vertice and vertex color in the vertex array.
143 //! Warning: theColor is ignored when the hasVColors constructor parameter is FALSE
144 //! @return the actual vertex number
145 Standard_Integer AddVertex (const gp_Pnt& theVertex, const Quantity_Color& theColor)
147 const Standard_Integer anIndex = AddVertex (theVertex);
148 SetVertexColor (anIndex, theColor.Red(), theColor.Green(), theColor.Blue());
152 //! Adds a vertice and vertex color in the vertex array.
153 //! Warning: theColor is ignored when the hasVColors constructor parameter is FALSE
155 //! theColor32 = Alpha << 24 + Blue << 16 + Green << 8 + Red
157 //! @return the actual vertex number
158 Standard_Integer AddVertex (const gp_Pnt& theVertex, const Standard_Integer theColor32)
160 const Standard_Integer anIndex = AddVertex (theVertex);
161 SetVertexColor (anIndex, theColor32);
165 //! Adds a vertice and vertex color in the vertex array.
166 //! Warning: theColor is ignored when the hasVColors constructor parameter is FALSE
167 //! @return the actual vertex number
168 Standard_Integer AddVertex (const gp_Pnt& theVertex,
169 const Graphic3d_Vec4ub& theColor)
171 const Standard_Integer anIndex = AddVertex (theVertex);
172 SetVertexColor (anIndex, theColor);
176 //! Adds a vertice and vertex normal in the vertex array.
177 //! Warning: theNormal is ignored when the hasVNormals constructor parameter is FALSE.
178 //! @return the actual vertex number
179 Standard_Integer AddVertex (const gp_Pnt& theVertex, const gp_Dir& theNormal)
181 return AddVertex (theVertex.X(), theVertex.Y(), theVertex.Z(),
182 theNormal.X(), theNormal.Y(), theNormal.Z());
185 //! Adds a vertice and vertex normal in the vertex array.
186 //! Warning: Normal is ignored when the hasVNormals constructor parameter is FALSE.
187 //! @return the actual vertex number
188 Standard_Integer AddVertex (const Standard_Real theX, const Standard_Real theY, const Standard_Real theZ,
189 const Standard_Real theNX, const Standard_Real theNY, const Standard_Real theNZ)
191 return AddVertex (RealToShortReal (theX), RealToShortReal (theY), RealToShortReal (theZ),
192 Standard_ShortReal (theNX), Standard_ShortReal (theNY), Standard_ShortReal (theNZ));
195 //! Adds a vertice and vertex normal in the vertex array.
196 //! Warning: Normal is ignored when the hasVNormals constructor parameter is FALSE.
197 //! @return the actual vertex number
198 Standard_Integer AddVertex (const Standard_ShortReal theX, const Standard_ShortReal theY, const Standard_ShortReal theZ,
199 const Standard_ShortReal theNX, const Standard_ShortReal theNY, const Standard_ShortReal theNZ)
201 const Standard_Integer anIndex = myAttribs->NbElements + 1;
202 SetVertice (anIndex, theX, theY, theZ);
203 SetVertexNormal (anIndex, theNX, theNY, theNZ);
207 //! Adds a vertice,vertex normal and color in the vertex array.
208 //! Warning: theNormal is ignored when the hasVNormals constructor parameter is FALSE
209 //! and theColor is ignored when the hasVColors constructor parameter is FALSE.
210 //! @return the actual vertex number
211 Standard_Integer AddVertex (const gp_Pnt& theVertex, const gp_Dir& theNormal, const Quantity_Color& theColor)
213 const Standard_Integer anIndex = AddVertex (theVertex, theNormal);
214 SetVertexColor (anIndex, theColor.Red(), theColor.Green(), theColor.Blue());
218 //! Adds a vertice,vertex normal and color in the vertex array.
219 //! Warning: theNormal is ignored when the hasVNormals constructor parameter is FALSE
220 //! and theColor is ignored when the hasVColors constructor parameter is FALSE.
222 //! theColor32 = Alpha << 24 + Blue << 16 + Green << 8 + Red
224 //! @return the actual vertex number
225 Standard_Integer AddVertex (const gp_Pnt& theVertex, const gp_Dir& theNormal, const Standard_Integer theColor32)
227 const Standard_Integer anIndex = AddVertex (theVertex, theNormal);
228 SetVertexColor (anIndex, theColor32);
232 //! Adds a vertice and vertex texture in the vertex array.
233 //! theTexel is ignored when the hasVTexels constructor parameter is FALSE.
234 //! @return the actual vertex number
235 Standard_Integer AddVertex (const gp_Pnt& theVertex, const gp_Pnt2d& theTexel)
237 return AddVertex (theVertex.X(), theVertex.Y(), theVertex.Z(),
238 theTexel.X(), theTexel.Y());
241 //! Adds a vertice and vertex texture coordinates in the vertex array.
242 //! Texel is ignored when the hasVTexels constructor parameter is FALSE.
243 //! @return the actual vertex number
244 Standard_Integer AddVertex (const Standard_Real theX, const Standard_Real theY, const Standard_Real theZ,
245 const Standard_Real theTX, const Standard_Real theTY)
247 return AddVertex (RealToShortReal (theX), RealToShortReal (theY), RealToShortReal (theZ),
248 Standard_ShortReal (theTX), Standard_ShortReal (theTY));
251 //! Adds a vertice and vertex texture coordinates in the vertex array.
252 //! Texel is ignored when the hasVTexels constructor parameter is FALSE.
253 //! @return the actual vertex number
254 Standard_Integer AddVertex (const Standard_ShortReal theX, const Standard_ShortReal theY, const Standard_ShortReal theZ,
255 const Standard_ShortReal theTX, const Standard_ShortReal theTY)
257 const Standard_Integer anIndex = myAttribs->NbElements + 1;
258 SetVertice (anIndex, theX, theY, theZ);
259 SetVertexTexel (anIndex, theTX, theTY);
263 //! Adds a vertice,vertex normal and texture in the vertex array.
264 //! Warning: theNormal is ignored when the hasVNormals constructor parameter is FALSE
265 //! and theTexel is ignored when the hasVTexels constructor parameter is FALSE.
266 //! @return the actual vertex number
267 Standard_Integer AddVertex (const gp_Pnt& theVertex, const gp_Dir& theNormal, const gp_Pnt2d& theTexel)
269 return AddVertex (theVertex.X(), theVertex.Y(), theVertex.Z(),
270 theNormal.X(), theNormal.Y(), theNormal.Z(),
271 theTexel.X(), theTexel.Y());
274 //! Adds a vertice,vertex normal and texture in the vertex array.
275 //! Warning: Normal is ignored when the hasVNormals constructor parameter is FALSE
276 //! and Texel is ignored when the hasVTexels constructor parameter is FALSE.
277 //! @return the actual vertex number
278 Standard_Integer AddVertex (const Standard_Real theX, const Standard_Real theY, const Standard_Real theZ,
279 const Standard_Real theNX, const Standard_Real theNY, const Standard_Real theNZ,
280 const Standard_Real theTX, const Standard_Real theTY)
282 return AddVertex (RealToShortReal (theX), RealToShortReal (theY), RealToShortReal (theZ),
283 Standard_ShortReal (theNX), Standard_ShortReal (theNY), Standard_ShortReal (theNZ),
284 Standard_ShortReal (theTX), Standard_ShortReal (theTY));
287 //! Adds a vertice,vertex normal and texture in the vertex array.
288 //! Warning: Normal is ignored when the hasVNormals constructor parameter is FALSE
289 //! and Texel is ignored when the hasVTexels constructor parameter is FALSE.
290 //! @return the actual vertex number
291 Standard_Integer AddVertex (const Standard_ShortReal theX, const Standard_ShortReal theY, const Standard_ShortReal theZ,
292 const Standard_ShortReal theNX, const Standard_ShortReal theNY, const Standard_ShortReal theNZ,
293 const Standard_ShortReal theTX, const Standard_ShortReal theTY)
295 const Standard_Integer anIndex = myAttribs->NbElements + 1;
296 SetVertice (anIndex, theX, theY, theZ);
297 SetVertexNormal(anIndex, theNX, theNY, theNZ);
298 SetVertexTexel (anIndex, theTX, theTY);
302 //! Change the vertice of rank theIndex in the array.
303 //! @param[in] theIndex node index within [1, VertexNumberAllocated()] range
304 //! @param[in] theVertex 3D coordinates
305 void SetVertice (const Standard_Integer theIndex, const gp_Pnt& theVertex)
307 SetVertice (theIndex, Standard_ShortReal (theVertex.X()), Standard_ShortReal (theVertex.Y()), Standard_ShortReal (theVertex.Z()));
310 //! Change the vertice in the array.
311 //! @param[in] theIndex node index within [1, VertexNumberAllocated()] range
312 //! @param[in] theX coordinate X
313 //! @param[in] theY coordinate Y
314 //! @param[in] theZ coordinate Z
315 void SetVertice (const Standard_Integer theIndex, const Standard_ShortReal theX, const Standard_ShortReal theY, const Standard_ShortReal theZ)
317 Standard_OutOfRange_Raise_if (theIndex < 1 || theIndex > myAttribs->NbMaxElements(), "BAD VERTEX index");
318 Graphic3d_Vec3& aVec = *reinterpret_cast<Graphic3d_Vec3*> (myAttribs->ChangeData() + myPosStride * ((Standard_Size)theIndex - 1));
322 if (myAttribs->NbElements < theIndex)
324 myAttribs->NbElements = theIndex;
328 //! Change the vertex color in the array.
329 //! @param[in] theIndex node index within [1, VertexNumberAllocated()] range
330 //! @param[in] theColor node color
331 void SetVertexColor (const Standard_Integer theIndex, const Quantity_Color& theColor)
333 SetVertexColor (theIndex, theColor.Red(), theColor.Green(), theColor.Blue());
336 //! Change the vertex color in the array.
337 //! @param[in] theIndex node index within [1, VertexNumberAllocated()] range
338 //! @param[in] theR red color value within [0, 1] range
339 //! @param[in] theG green color value within [0, 1] range
340 //! @param[in] theB blue color value within [0, 1] range
341 void SetVertexColor (const Standard_Integer theIndex, const Standard_Real theR, const Standard_Real theG, const Standard_Real theB)
343 Standard_OutOfRange_Raise_if (theIndex < 1 || theIndex > myAttribs->NbMaxElements(), "BAD VERTEX index");
344 if (myColData != NULL)
346 Graphic3d_Vec4ub* aColorPtr = reinterpret_cast<Graphic3d_Vec4ub* >(myColData + myColStride * ((Standard_Size)theIndex - 1));
347 aColorPtr->SetValues (Standard_Byte(theR * 255.0),
348 Standard_Byte(theG * 255.0),
349 Standard_Byte(theB * 255.0), 255);
351 myAttribs->NbElements = Max (theIndex, myAttribs->NbElements);
354 //! Change the vertex color in the array.
355 //! @param[in] theIndex node index within [1, VertexNumberAllocated()] range
356 //! @param[in] theColor node RGBA color values within [0, 255] range
357 void SetVertexColor (const Standard_Integer theIndex,
358 const Graphic3d_Vec4ub& theColor)
360 Standard_OutOfRange_Raise_if (theIndex < 1 || theIndex > myAttribs->NbMaxElements(), "BAD VERTEX index");
361 if (myColData != NULL)
363 Graphic3d_Vec4ub* aColorPtr = reinterpret_cast<Graphic3d_Vec4ub* >(myColData + myColStride * ((Standard_Size)theIndex - 1));
364 (*aColorPtr) = theColor;
366 myAttribs->NbElements = Max (theIndex, myAttribs->NbElements);
369 //! Change the vertex color in the array.
371 //! theColor32 = Alpha << 24 + Blue << 16 + Green << 8 + Red
373 //! @param[in] theIndex node index within [1, VertexNumberAllocated()] range
374 //! @param[in] theColor32 packed RGBA color values
375 void SetVertexColor (const Standard_Integer theIndex, const Standard_Integer theColor32)
377 Standard_OutOfRange_Raise_if (theIndex < 1 || theIndex > myAttribs->NbMaxElements(), "BAD VERTEX index");
378 if (myColData != NULL)
380 *reinterpret_cast<Standard_Integer* >(myColData + myColStride * ((Standard_Size)theIndex - 1)) = theColor32;
384 //! Change the vertex normal in the array.
385 //! @param[in] theIndex node index within [1, VertexNumberAllocated()] range
386 //! @param[in] theNormal normalized surface normal
387 void SetVertexNormal (const Standard_Integer theIndex, const gp_Dir& theNormal)
389 SetVertexNormal (theIndex, theNormal.X(), theNormal.Y(), theNormal.Z());
392 //! Change the vertex normal in the array.
393 //! @param[in] theIndex node index within [1, VertexNumberAllocated()] range
394 //! @param[in] theNX surface normal X component
395 //! @param[in] theNY surface normal Y component
396 //! @param[in] theNZ surface normal Z component
397 void SetVertexNormal (const Standard_Integer theIndex, const Standard_Real theNX, const Standard_Real theNY, const Standard_Real theNZ)
399 Standard_OutOfRange_Raise_if (theIndex < 1 || theIndex > myAttribs->NbMaxElements(), "BAD VERTEX index");
400 if (myNormData != NULL)
402 Graphic3d_Vec3& aVec = *reinterpret_cast<Graphic3d_Vec3* >(myNormData + myNormStride * ((Standard_Size)theIndex - 1));
403 aVec.x() = Standard_ShortReal (theNX);
404 aVec.y() = Standard_ShortReal (theNY);
405 aVec.z() = Standard_ShortReal (theNZ);
407 myAttribs->NbElements = Max (theIndex, myAttribs->NbElements);
410 //! Change the vertex texel in the array.
411 //! @param[in] theIndex node index within [1, VertexNumberAllocated()] range
412 //! @param[in] theTexel node UV coordinates
413 void SetVertexTexel (const Standard_Integer theIndex, const gp_Pnt2d& theTexel)
415 SetVertexTexel (theIndex, theTexel.X(), theTexel.Y());
418 //! Change the vertex texel in the array.
419 //! @param[in] theIndex node index within [1, VertexNumberAllocated()] range
420 //! @param[in] theTX node U coordinate
421 //! @param[in] theTY node V coordinate
422 void SetVertexTexel (const Standard_Integer theIndex, const Standard_Real theTX, const Standard_Real theTY)
424 Standard_OutOfRange_Raise_if (theIndex < 1 || theIndex > myAttribs->NbMaxElements(), "BAD VERTEX index");
425 if (myTexData != NULL)
427 Graphic3d_Vec2& aVec = *reinterpret_cast<Graphic3d_Vec2* >(myTexData + myTexStride * ((Standard_Size)theIndex - 1));
428 aVec.x() = Standard_ShortReal (theTX);
429 aVec.y() = Standard_ShortReal (theTY);
431 myAttribs->NbElements = Max (theIndex, myAttribs->NbElements);
434 //! Returns the vertice from the vertex table if defined.
435 //! @param[in] theRank node index within [1, VertexNumber()] range
436 //! @return node 3D coordinates
437 gp_Pnt Vertice (const Standard_Integer theRank) const
439 Standard_Real anXYZ[3];
440 Vertice (theRank, anXYZ[0], anXYZ[1], anXYZ[2]);
441 return gp_Pnt (anXYZ[0], anXYZ[1], anXYZ[2]);
444 //! Returns the vertice coordinates at rank theRank from the vertex table if defined.
445 //! @param[in] theRank node index within [1, VertexNumber()] range
446 //! @param[out] theX node X coordinate value
447 //! @param[out] theY node Y coordinate value
448 //! @param[out] theZ node Z coordinate value
449 void Vertice (const Standard_Integer theRank, Standard_Real& theX, Standard_Real& theY, Standard_Real& theZ) const
451 theX = theY = theZ = 0.0;
452 Standard_OutOfRange_Raise_if (theRank < 1 || theRank > myAttribs->NbElements, "BAD VERTEX index");
453 const Graphic3d_Vec3& aVec = *reinterpret_cast<const Graphic3d_Vec3*> (myAttribs->Data() + myPosStride * ((Standard_Size)theRank - 1));
454 theX = Standard_Real(aVec.x());
455 theY = Standard_Real(aVec.y());
456 theZ = Standard_Real(aVec.z());
459 //! Returns the vertex color at rank theRank from the vertex table if defined.
460 //! @param[in] theRank node index within [1, VertexNumber()] range
461 //! @return node color RGB value
462 Quantity_Color VertexColor (const Standard_Integer theRank) const
464 Standard_Real anRGB[3];
465 VertexColor (theRank, anRGB[0], anRGB[1], anRGB[2]);
466 return Quantity_Color (anRGB[0], anRGB[1], anRGB[2], Quantity_TOC_RGB);
469 //! Returns the vertex color from the vertex table if defined.
470 //! @param[in] theIndex node index within [1, VertexNumber()] range
471 //! @param[out] theColor node RGBA color values within [0, 255] range
472 void VertexColor (const Standard_Integer theIndex,
473 Graphic3d_Vec4ub& theColor) const
475 Standard_OutOfRange_Raise_if (myColData == NULL || theIndex < 1 || theIndex > myAttribs->NbElements, "BAD VERTEX index");
476 theColor = *reinterpret_cast<const Graphic3d_Vec4ub* >(myColData + myColStride * ((Standard_Size)theIndex - 1));
479 //! Returns the vertex color values from the vertex table if defined.
480 //! @param[in] theRank node index within [1, VertexNumber()] range
481 //! @param[out] theR node red color component value within [0, 1] range
482 //! @param[out] theG node green color component value within [0, 1] range
483 //! @param[out] theB node blue color component value within [0, 1] range
484 void VertexColor (const Standard_Integer theRank, Standard_Real& theR, Standard_Real& theG, Standard_Real& theB) const
486 theR = theG = theB = 0.0;
487 Standard_OutOfRange_Raise_if (theRank < 1 || theRank > myAttribs->NbElements, "BAD VERTEX index");
488 if (myColData == NULL)
492 const Graphic3d_Vec4ub& aColor = *reinterpret_cast<const Graphic3d_Vec4ub* >(myColData + myColStride * ((Standard_Size)theRank - 1));
493 theR = Standard_Real(aColor.r()) / 255.0;
494 theG = Standard_Real(aColor.g()) / 255.0;
495 theB = Standard_Real(aColor.b()) / 255.0;
498 //! Returns the vertex color values from the vertex table if defined.
499 //! @param[in] theRank node index within [1, VertexNumber()] range
500 //! @param[out] theColor node RGBA color packed into 32-bit integer
501 void VertexColor (const Standard_Integer theRank, Standard_Integer& theColor) const
503 Standard_OutOfRange_Raise_if (theRank < 1 || theRank > myAttribs->NbElements, "BAD VERTEX index");
504 if (myColData != NULL)
506 theColor = *reinterpret_cast<const Standard_Integer* >(myColData + myColStride * ((Standard_Size)theRank - 1));
510 //! Returns the vertex normal from the vertex table if defined.
511 //! @param[in] theRank node index within [1, VertexNumber()] range
512 //! @return normalized 3D vector defining surface normal
513 gp_Dir VertexNormal (const Standard_Integer theRank) const
515 Standard_Real anXYZ[3];
516 VertexNormal (theRank, anXYZ[0], anXYZ[1], anXYZ[2]);
517 return gp_Dir (anXYZ[0], anXYZ[1], anXYZ[2]);
520 //! Returns the vertex normal coordinates at rank theRank from the vertex table if defined.
521 //! @param[in] theRank node index within [1, VertexNumber()] range
522 //! @param[out] theNX normal X coordinate
523 //! @param[out] theNY normal Y coordinate
524 //! @param[out] theNZ normal Z coordinate
525 void VertexNormal (const Standard_Integer theRank, Standard_Real& theNX, Standard_Real& theNY, Standard_Real& theNZ) const
527 theNX = theNY = theNZ = 0.0;
528 Standard_OutOfRange_Raise_if (theRank < 1 || theRank > myAttribs->NbElements, "BAD VERTEX index");
529 if (myNormData != NULL)
531 const Graphic3d_Vec3& aVec = *reinterpret_cast<const Graphic3d_Vec3* >(myNormData + myNormStride * ((Standard_Size)theRank - 1));
532 theNX = Standard_Real(aVec.x());
533 theNY = Standard_Real(aVec.y());
534 theNZ = Standard_Real(aVec.z());
538 //! Returns the vertex texture at rank theRank from the vertex table if defined.
539 //! @param[in] theRank node index within [1, VertexNumber()] range
540 //! @return UV coordinates
541 gp_Pnt2d VertexTexel (const Standard_Integer theRank) const
543 Standard_Real anXY[2];
544 VertexTexel (theRank, anXY[0], anXY[1]);
545 return gp_Pnt2d (anXY[0], anXY[1]);
548 //! Returns the vertex texture coordinates at rank theRank from the vertex table if defined.
549 //! @param[in] theRank node index within [1, VertexNumber()] range
550 //! @param[out] theTX texel U coordinate value
551 //! @param[out] theTY texel V coordinate value
552 void VertexTexel (const Standard_Integer theRank, Standard_Real& theTX, Standard_Real& theTY) const
555 Standard_OutOfRange_Raise_if (theRank < 1 || theRank > myAttribs->NbElements, "BAD VERTEX index");
556 if (myTexData != NULL)
558 const Graphic3d_Vec2& aVec = *reinterpret_cast<const Graphic3d_Vec2* >(myTexData + myTexStride * ((Standard_Size)theRank - 1));
559 theTX = Standard_Real(aVec.x());
560 theTY = Standard_Real(aVec.y());
564 public: //! @name optional array of Indices/Edges for using shared Vertex data
566 //! Returns optional index buffer.
567 const Handle(Graphic3d_IndexBuffer)& Indices() const { return myIndices; }
569 //! Returns the number of defined edges
570 Standard_Integer EdgeNumber() const { return !myIndices.IsNull() ? myIndices->NbElements : -1; }
572 //! Returns the number of allocated edges
573 Standard_Integer EdgeNumberAllocated() const { return !myIndices.IsNull() ? myIndices->NbMaxElements() : 0; }
575 //! Returns the vertex index at rank theRank in the range [1,EdgeNumber()]
576 Standard_Integer Edge (const Standard_Integer theRank) const
578 Standard_OutOfRange_Raise_if (myIndices.IsNull() || theRank < 1 || theRank > myIndices->NbElements, "BAD EDGE index");
579 return Standard_Integer(myIndices->Index (theRank - 1) + 1);
582 //! Adds an edge in the range [1,VertexNumber()] in the array.
583 //! @return the actual edges number
584 Standard_EXPORT Standard_Integer AddEdge (const Standard_Integer theVertexIndex);
586 //! Convenience method, adds two vertex indices (a segment) in the range [1,VertexNumber()] in the array.
587 //! @return the actual edges number
588 Standard_Integer AddEdges (Standard_Integer theVertexIndex1,
589 Standard_Integer theVertexIndex2)
591 AddEdge (theVertexIndex1);
592 return AddEdge (theVertexIndex2);
595 //! Convenience method, adds two vertex indices (a segment) in the range [1,VertexNumber()] in the array of segments (Graphic3d_TOPA_SEGMENTS).
596 //! Raises exception if array is not of type Graphic3d_TOPA_SEGMENTS.
597 //! @return the actual edges number
598 Standard_Integer AddSegmentEdges (Standard_Integer theVertexIndex1,
599 Standard_Integer theVertexIndex2)
601 Standard_TypeMismatch_Raise_if (myType != Graphic3d_TOPA_SEGMENTS, "Not array of segments");
602 return AddEdges (theVertexIndex1, theVertexIndex2);
605 //! Convenience method, adds three vertex indices (a triangle) in the range [1,VertexNumber()] in the array.
606 //! @return the actual edges number
607 Standard_Integer AddEdges (Standard_Integer theVertexIndex1,
608 Standard_Integer theVertexIndex2,
609 Standard_Integer theVertexIndex3)
611 AddEdge (theVertexIndex1);
612 AddEdge (theVertexIndex2);
613 return AddEdge (theVertexIndex3);
616 //! Convenience method, adds three vertex indices of triangle in the range [1,VertexNumber()] in the array of triangles.
617 //! Raises exception if array is not of type Graphic3d_TOPA_TRIANGLES.
618 //! @return the actual edges number
619 Standard_Integer AddTriangleEdges (Standard_Integer theVertexIndex1,
620 Standard_Integer theVertexIndex2,
621 Standard_Integer theVertexIndex3)
623 Standard_TypeMismatch_Raise_if (myType != Graphic3d_TOPA_TRIANGLES, "Not array of triangles");
624 return AddEdges (theVertexIndex1, theVertexIndex2, theVertexIndex3);
627 //! Convenience method, adds three vertex indices of triangle in the range [1,VertexNumber()] in the array of triangles.
628 //! Raises exception if array is not of type Graphic3d_TOPA_TRIANGLES.
629 //! @return the actual edges number
630 Standard_Integer AddTriangleEdges (const Graphic3d_Vec3i& theIndexes)
632 Standard_TypeMismatch_Raise_if (myType != Graphic3d_TOPA_TRIANGLES, "Not array of triangles");
633 return AddEdges (theIndexes[0], theIndexes[1], theIndexes[2]);
636 //! Convenience method, adds three vertex indices (4th component is ignored) of triangle in the range [1,VertexNumber()] in the array of triangles.
637 //! Raises exception if array is not of type Graphic3d_TOPA_TRIANGLES.
638 //! @return the actual edges number
639 Standard_Integer AddTriangleEdges (const Graphic3d_Vec4i& theIndexes)
641 Standard_TypeMismatch_Raise_if (myType != Graphic3d_TOPA_TRIANGLES, "Not array of triangles");
642 return AddEdges (theIndexes[0], theIndexes[1], theIndexes[2]);
645 //! Convenience method, adds four vertex indices (a quad) in the range [1,VertexNumber()] in the array.
646 //! @return the actual edges number
647 Standard_Integer AddEdges (Standard_Integer theVertexIndex1,
648 Standard_Integer theVertexIndex2,
649 Standard_Integer theVertexIndex3,
650 Standard_Integer theVertexIndex4)
652 AddEdge (theVertexIndex1);
653 AddEdge (theVertexIndex2);
654 AddEdge (theVertexIndex3);
655 return AddEdge (theVertexIndex4);
658 //! Convenience method, adds four vertex indices (a quad) in the range [1,VertexNumber()] in the array of quads.
659 //! Raises exception if array is not of type Graphic3d_TOPA_QUADRANGLES.
660 //! @return the actual edges number
661 Standard_Integer AddQuadEdges (Standard_Integer theVertexIndex1,
662 Standard_Integer theVertexIndex2,
663 Standard_Integer theVertexIndex3,
664 Standard_Integer theVertexIndex4)
666 Standard_TypeMismatch_Raise_if (myType != Graphic3d_TOPA_QUADRANGLES, "Not array of quads");
667 return AddEdges (theVertexIndex1, theVertexIndex2, theVertexIndex3, theVertexIndex4);
670 //! Convenience method, adds quad indices in the range [1,VertexNumber()] into array or triangles as two triangles.
671 //! Raises exception if array is not of type Graphic3d_TOPA_TRIANGLES.
672 //! @return the actual edges number
673 Standard_Integer AddQuadTriangleEdges (Standard_Integer theVertexIndex1,
674 Standard_Integer theVertexIndex2,
675 Standard_Integer theVertexIndex3,
676 Standard_Integer theVertexIndex4)
678 AddTriangleEdges (theVertexIndex3, theVertexIndex1, theVertexIndex2);
679 return AddTriangleEdges (theVertexIndex1, theVertexIndex3, theVertexIndex4);
682 //! Convenience method, adds quad indices in the range [1,VertexNumber()] into array or triangles as two triangles.
683 //! Raises exception if array is not of type Graphic3d_TOPA_TRIANGLES.
684 //! @return the actual edges number
685 Standard_Integer AddQuadTriangleEdges (const Graphic3d_Vec4i& theIndexes)
687 return AddQuadTriangleEdges (theIndexes[0], theIndexes[1], theIndexes[2], theIndexes[3]);
690 //! Add triangle strip into indexed triangulation array.
691 //! N-2 triangles are added from N input nodes.
692 //! Raises exception if array is not of type Graphic3d_TOPA_TRIANGLES.
693 //! @param theVertexLower [in] index of first node defining triangle strip
694 //! @param theVertexUpper [in] index of last node defining triangle strip
695 Standard_EXPORT void AddTriangleStripEdges (Standard_Integer theVertexLower,
696 Standard_Integer theVertexUpper);
698 //! Add triangle fan into indexed triangulation array.
699 //! N-2 triangles are added from N input nodes (or N-1 with closed flag).
700 //! Raises exception if array is not of type Graphic3d_TOPA_TRIANGLES.
701 //! @param theVertexLower [in] index of first node defining triangle fun (center)
702 //! @param theVertexUpper [in] index of last node defining triangle fun
703 //! @param theToClose [in] close triangle fan (connect first and last points)
704 Standard_EXPORT void AddTriangleFanEdges (Standard_Integer theVertexLower,
705 Standard_Integer theVertexUpper,
706 Standard_Boolean theToClose);
708 //! Add line strip (polyline) into indexed segments array.
709 //! N-1 segments are added from N input nodes (or N with closed flag).
710 //! Raises exception if array is not of type Graphic3d_TOPA_SEGMENTS.
711 //! @param theVertexLower [in] index of first node defining line strip fun (center)
712 //! @param theVertexUpper [in] index of last node defining triangle fun
713 //! @param theToClose [in] close triangle fan (connect first and last points)
714 Standard_EXPORT void AddPolylineEdges (Standard_Integer theVertexLower,
715 Standard_Integer theVertexUpper,
716 Standard_Boolean theToClose);
718 public: //! @name optional array of Bounds/Subgroups within primitive array (e.g. restarting primitives / assigning colors)
720 //! Returns optional bounds buffer.
721 const Handle(Graphic3d_BoundBuffer)& Bounds() const { return myBounds; }
723 //! Returns TRUE when bound colors array is defined.
724 Standard_Boolean HasBoundColors() const { return !myBounds.IsNull() && myBounds->Colors != NULL; }
726 //! Returns the number of defined bounds
727 Standard_Integer BoundNumber() const { return !myBounds.IsNull() ? myBounds->NbBounds : -1; }
729 //! Returns the number of allocated bounds
730 Standard_Integer BoundNumberAllocated() const { return !myBounds.IsNull() ? myBounds->NbMaxBounds : 0; }
732 //! Returns the edge number at rank theRank.
733 Standard_Integer Bound (const Standard_Integer theRank) const
735 Standard_OutOfRange_Raise_if (myBounds.IsNull() || theRank < 1 || theRank > myBounds->NbBounds, "BAD BOUND index");
736 return myBounds->Bounds[theRank - 1];
739 //! Returns the bound color at rank theRank from the bound table if defined.
740 Quantity_Color BoundColor (const Standard_Integer theRank) const
742 Standard_Real anRGB[3] = {0.0, 0.0, 0.0};
743 BoundColor (theRank, anRGB[0], anRGB[1], anRGB[2]);
744 return Quantity_Color (anRGB[0], anRGB[1], anRGB[2], Quantity_TOC_RGB);
747 //! Returns the bound color values at rank theRank from the bound table if defined.
748 void BoundColor (const Standard_Integer theRank, Standard_Real& theR, Standard_Real& theG, Standard_Real& theB) const
750 Standard_OutOfRange_Raise_if (myBounds.IsNull() || myBounds->Colors == NULL || theRank < 1 || theRank > myBounds->NbBounds, "BAD BOUND index");
751 const Graphic3d_Vec4& aVec = myBounds->Colors[theRank - 1];
752 theR = Standard_Real(aVec.r());
753 theG = Standard_Real(aVec.g());
754 theB = Standard_Real(aVec.b());
757 //! Adds a bound of length theEdgeNumber in the bound array
758 //! @return the actual bounds number
759 Standard_EXPORT Standard_Integer AddBound (const Standard_Integer theEdgeNumber);
761 //! Adds a bound of length theEdgeNumber and bound color theBColor in the bound array.
762 //! Warning: theBColor is ignored when the hasBColors constructor parameter is FALSE
763 //! @return the actual bounds number
764 Standard_Integer AddBound (const Standard_Integer theEdgeNumber, const Quantity_Color& theBColor)
766 return AddBound (theEdgeNumber, theBColor.Red(), theBColor.Green(), theBColor.Blue());
769 //! Adds a bound of length theEdgeNumber and bound color coordinates in the bound array.
770 //! Warning: <theR,theG,theB> are ignored when the hasBColors constructor parameter is FALSE
771 //! @return the actual bounds number
772 Standard_EXPORT Standard_Integer AddBound (const Standard_Integer theEdgeNumber, const Standard_Real theR, const Standard_Real theG, const Standard_Real theB);
774 //! Change the bound color of rank theIndex in the array.
775 void SetBoundColor (const Standard_Integer theIndex, const Quantity_Color& theColor)
777 SetBoundColor (theIndex, theColor.Red(), theColor.Green(), theColor.Blue());
780 //! Change the bound color of rank theIndex in the array.
781 void SetBoundColor (const Standard_Integer theIndex, const Standard_Real theR, const Standard_Real theG, const Standard_Real theB)
783 if (myBounds.IsNull())
787 Standard_OutOfRange_Raise_if (myBounds.IsNull() || myBounds->Colors == NULL || theIndex < 1 || theIndex > myBounds->NbMaxBounds, "BAD BOUND index");
788 Graphic3d_Vec4& aVec = myBounds->Colors[theIndex - 1];
789 aVec.r() = Standard_ShortReal (theR);
790 aVec.g() = Standard_ShortReal (theG);
791 aVec.b() = Standard_ShortReal (theB);
793 myBounds->NbBounds = Max (theIndex, myBounds->NbBounds);
796 protected: //! @name protected constructors
798 //! Main constructor.
799 //! @param theType type of primitive
800 //! @param theMaxVertexs length of vertex attributes buffer to be allocated (maximum number of vertexes, @sa ::AddVertex())
801 //! @param theMaxBounds length of bounds buffer to be allocated (maximum number of bounds, @sa ::AddBound())
802 //! @param theMaxEdges length of edges (index) buffer to be allocated (maximum number of indexes @sa ::AddEdge())
803 //! @param theArrayFlags array flags
804 Graphic3d_ArrayOfPrimitives (Graphic3d_TypeOfPrimitiveArray theType,
805 Standard_Integer theMaxVertexs,
806 Standard_Integer theMaxBounds,
807 Standard_Integer theMaxEdges,
808 Graphic3d_ArrayFlags theArrayFlags)
809 : myNormData (NULL), myTexData (NULL), myColData (NULL), myPosStride (0), myNormStride (0), myTexStride (0), myColStride (0),
810 myType (Graphic3d_TOPA_UNDEFINED)
812 init (theType, theMaxVertexs, theMaxBounds, theMaxEdges, theArrayFlags);
815 //! Array constructor.
816 Standard_EXPORT void init (Graphic3d_TypeOfPrimitiveArray theType,
817 Standard_Integer theMaxVertexs,
818 Standard_Integer theMaxBounds,
819 Standard_Integer theMaxEdges,
820 Graphic3d_ArrayFlags theArrayFlags);
822 private: //! @name private fields
824 Handle(Graphic3d_IndexBuffer) myIndices;
825 Handle(Graphic3d_Buffer) myAttribs;
826 Handle(Graphic3d_BoundBuffer) myBounds;
827 Standard_Byte* myNormData;
828 Standard_Byte* myTexData;
829 Standard_Byte* myColData;
830 Standard_Size myPosStride;
831 Standard_Size myNormStride;
832 Standard_Size myTexStride;
833 Standard_Size myColStride;
834 Graphic3d_TypeOfPrimitiveArray myType;
838 #endif // _Graphic3d_ArrayOfPrimitives_HeaderFile