0031313: Foundation Classes - Dump improvement for classes
[occt.git] / src / Graphic3d / Graphic3d_Buffer.hxx
1 // Copyright (c) 2014 OPEN CASCADE SAS
2 //
3 // This file is part of Open CASCADE Technology software library.
4 //
5 // This library is free software; you can redistribute it and/or modify it under
6 // the terms of the GNU Lesser General Public License version 2.1 as published
7 // by the Free Software Foundation, with special exception defined in the file
8 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
9 // distribution for complete text of the license and disclaimer of any warranty.
10 //
11 // Alternatively, this file may be used under the terms of Open CASCADE
12 // commercial license or contractual agreement.
13
14 #ifndef _Graphic3d_Buffer_HeaderFile
15 #define _Graphic3d_Buffer_HeaderFile
16
17 #include <Graphic3d_BufferRange.hxx>
18 #include <Graphic3d_Vec.hxx>
19 #include <NCollection_Array1.hxx>
20 #include <NCollection_Buffer.hxx>
21 #include <Standard_NotImplemented.hxx>
22
23 //! Type of attribute in Vertex Buffer
24 enum Graphic3d_TypeOfAttribute
25 {
26   Graphic3d_TOA_POS   =  0,   //!< vertex position
27   Graphic3d_TOA_NORM,         //!< normal
28   Graphic3d_TOA_UV,           //!< texture coordinates
29   Graphic3d_TOA_COLOR,        //!< per-vertex color
30   Graphic3d_TOA_CUSTOM,       //!< custom attributes
31 };
32
33 //! Type of the element in Vertex or Index Buffer
34 enum Graphic3d_TypeOfData
35 {
36   Graphic3d_TOD_USHORT,  //!< unsigned 16-bit integer
37   Graphic3d_TOD_UINT,    //!< unsigned 32-bit integer
38   Graphic3d_TOD_VEC2,    //!< 2-components float vector
39   Graphic3d_TOD_VEC3,    //!< 3-components float vector
40   Graphic3d_TOD_VEC4,    //!< 4-components float vector
41   Graphic3d_TOD_VEC4UB,  //!< 4-components unsigned byte vector
42   Graphic3d_TOD_FLOAT,   //!< float value
43 };
44
45 //! Vertex attribute definition.
46 struct Graphic3d_Attribute
47 {
48   Graphic3d_TypeOfAttribute Id;       //!< attribute identifier in vertex shader, 0 is reserved for vertex position
49   Graphic3d_TypeOfData      DataType; //!< vec2,vec3,vec4,vec4ub
50
51   Standard_Integer Stride() const { return Stride (DataType); }
52
53   //! @return size of attribute of specified data type
54   static Standard_Integer Stride (const Graphic3d_TypeOfData theType)
55   {
56     switch (theType)
57     {
58       case Graphic3d_TOD_USHORT: return sizeof(unsigned short);
59       case Graphic3d_TOD_UINT:   return sizeof(unsigned int);
60       case Graphic3d_TOD_VEC2:   return sizeof(Graphic3d_Vec2);
61       case Graphic3d_TOD_VEC3:   return sizeof(Graphic3d_Vec3);
62       case Graphic3d_TOD_VEC4:   return sizeof(Graphic3d_Vec4);
63       case Graphic3d_TOD_VEC4UB: return sizeof(Graphic3d_Vec4ub);
64       case Graphic3d_TOD_FLOAT:  return sizeof(float);
65     }
66     return 0;
67   }
68
69 };
70
71 typedef NCollection_Array1<Graphic3d_Attribute> Graphic3d_Array1OfAttribute;
72
73 //! Buffer of vertex attributes.
74 class Graphic3d_Buffer : public NCollection_Buffer
75 {
76   DEFINE_STANDARD_RTTIEXT(Graphic3d_Buffer, NCollection_Buffer)
77 public:
78
79   //! Empty constructor.
80   Graphic3d_Buffer (const Handle(NCollection_BaseAllocator)& theAlloc)
81   : NCollection_Buffer (theAlloc),
82     Stride       (0),
83     NbElements   (0),
84     NbAttributes (0)
85   {
86     //
87   }
88
89   //! Return number of initially allocated elements which can fit into this buffer,
90   //! while NbElements can be overwritten to smaller value.
91   Standard_Integer NbMaxElements() const { return Stride != 0 ? Standard_Integer(mySize / size_t(Stride)) : 0; }
92
93   //! @return array of attributes definitions
94   const Graphic3d_Attribute* AttributesArray() const
95   {
96     return (Graphic3d_Attribute* )(myData + mySize);
97   }
98
99   //! @return attribute definition
100   const Graphic3d_Attribute& Attribute (const Standard_Integer theAttribIndex) const
101   {
102     return AttributesArray()[theAttribIndex];
103   }
104
105   //! @return attribute definition
106   Graphic3d_Attribute& ChangeAttribute (const Standard_Integer theAttribIndex)
107   {
108     return *((Graphic3d_Attribute* )(myData + mySize) + theAttribIndex);
109   }
110
111   //! Find attribute index.
112   //! @param theAttrib attribute to find
113   //! @return attribute index or -1 if not found
114   Standard_Integer FindAttribute (Graphic3d_TypeOfAttribute theAttrib) const
115   {
116     for (Standard_Integer anAttribIter = 0; anAttribIter < NbAttributes; ++anAttribIter)
117     {
118       const Graphic3d_Attribute& anAttrib = Attribute (anAttribIter);
119       if (anAttrib.Id == theAttrib)
120       {
121         return anAttribIter;
122       }
123     }
124     return -1;
125   }
126
127 //! @name data accessors for interleaved array
128 public:
129
130   //! @return data offset to specified attribute
131   Standard_Integer AttributeOffset (const Standard_Integer theAttribIndex) const
132   {
133     Standard_Integer anOffset = 0;
134     for (Standard_Integer anAttribIter = 0; anAttribIter < theAttribIndex; ++anAttribIter)
135     {
136       anOffset += Graphic3d_Attribute::Stride (Attribute (anAttribIter).DataType);
137     }
138     return anOffset;
139   }
140
141   //! @return data for specified attribute
142   const Standard_Byte* Data (const Standard_Integer theAttribIndex) const
143   {
144     return myData + AttributeOffset (theAttribIndex);
145   }
146
147   //! @return data for specified attribute
148   Standard_Byte* ChangeData (const Standard_Integer theAttribIndex)
149   {
150     return myData + AttributeOffset (theAttribIndex);
151   }
152
153   //! Access specified element.
154   inline const Standard_Byte* value (const Standard_Integer theElem) const
155   {
156     return myData + Stride * size_t(theElem);
157   }
158
159   //! Access specified element.
160   inline Standard_Byte* changeValue (const Standard_Integer theElem)
161   {
162     return myData + Stride * size_t(theElem);
163   }
164
165   //! Access element with specified position and type.
166   template <typename Type_t>
167   inline const Type_t& Value (const Standard_Integer theElem) const
168   {
169     return *reinterpret_cast<const Type_t*>(value (theElem));
170   }
171
172   //! Access element with specified position and type.
173   template <typename Type_t>
174   inline Type_t& ChangeValue (const Standard_Integer theElem)
175   {
176     return *reinterpret_cast<Type_t* >(changeValue (theElem));
177   }
178
179 //! @name general accessors
180 public:
181
182   using NCollection_Buffer::Data;
183   using NCollection_Buffer::ChangeData;
184
185   //! Return the attribute data with stride size specific to this attribute.
186   //! @param theAttrib       attribute to find
187   //! @param theAttribIndex  index of found attribute
188   //! @param theAttribStride stride in bytes between values of this attribute within returned data pointer
189   Standard_Byte* ChangeAttributeData (Graphic3d_TypeOfAttribute theAttrib,
190                                       Standard_Integer& theAttribIndex,
191                                       Standard_Size& theAttribStride)
192   {
193     return (Standard_Byte* )AttributeData (theAttrib, theAttribIndex, theAttribStride);
194   }
195
196   //! Return the attribute data with stride size specific to this attribute.
197   //! @param theAttrib       attribute to find
198   //! @param theAttribIndex  index of found attribute
199   //! @param theAttribStride stride in bytes between values of this attribute within returned data pointer
200   const Standard_Byte* AttributeData (Graphic3d_TypeOfAttribute theAttrib,
201                                       Standard_Integer& theAttribIndex,
202                                       Standard_Size& theAttribStride) const
203   {
204     const Standard_Byte* aDataPtr = Data();
205     if (IsInterleaved())
206     {
207       for (Standard_Integer anAttribIter = 0; anAttribIter < NbAttributes; ++anAttribIter)
208       {
209         const Graphic3d_Attribute& anAttrib = Attribute (anAttribIter);
210         const Standard_Size anAttribStride = Graphic3d_Attribute::Stride (anAttrib.DataType);
211         if (anAttrib.Id == theAttrib)
212         {
213           theAttribIndex  = anAttribIter;
214           theAttribStride = Stride;
215           return aDataPtr;
216         }
217
218         aDataPtr += anAttribStride;
219       }
220     }
221     else
222     {
223       const Standard_Integer aNbMaxVerts = NbMaxElements();
224       for (Standard_Integer anAttribIter = 0; anAttribIter < NbAttributes; ++anAttribIter)
225       {
226         const Graphic3d_Attribute& anAttrib = Attribute (anAttribIter);
227         const Standard_Size anAttribStride = Graphic3d_Attribute::Stride (anAttrib.DataType);
228         if (anAttrib.Id == theAttrib)
229         {
230           theAttribIndex  = anAttribIter;
231           theAttribStride = anAttribStride;
232           return aDataPtr;
233         }
234
235         aDataPtr += anAttribStride * aNbMaxVerts;
236       }
237     }
238     return NULL;
239   }
240
241 public:
242
243   //! Release buffer.
244   void release()
245   {
246     Free();
247     Stride       = 0;
248     NbElements   = 0;
249     NbAttributes = 0;
250   }
251
252   //! Allocates new empty array
253   bool Init (const Standard_Integer     theNbElems,
254              const Graphic3d_Attribute* theAttribs,
255              const Standard_Integer     theNbAttribs)
256   {
257     release();
258     Standard_Integer aStride = 0;
259     for (Standard_Integer anAttribIter = 0; anAttribIter < theNbAttribs; ++anAttribIter)
260     {
261       const Graphic3d_Attribute& anAttrib = theAttribs[anAttribIter];
262       aStride += anAttrib.Stride();
263     }
264     if (aStride == 0)
265     {
266       return false;
267     }
268
269     Stride       = aStride;
270     NbElements   = theNbElems;
271     NbAttributes = theNbAttribs;
272     if (NbElements != 0)
273     {
274       const size_t aDataSize = size_t(Stride) * size_t(NbElements);
275       if (!Allocate (aDataSize + sizeof(Graphic3d_Attribute) * NbAttributes))
276       {
277         release();
278         return false;
279       }
280
281       mySize = aDataSize;
282       for (Standard_Integer anAttribIter = 0; anAttribIter < theNbAttribs; ++anAttribIter)
283       {
284         ChangeAttribute (anAttribIter) = theAttribs[anAttribIter];
285       }
286     }
287     return true;
288   }
289
290   //! Allocates new empty array
291   bool Init (const Standard_Integer             theNbElems,
292              const Graphic3d_Array1OfAttribute& theAttribs)
293   {
294     return Init (theNbElems, &theAttribs.First(), theAttribs.Size());
295   }
296
297 public:
298
299   //! Flag indicating that attributes in the buffer are interleaved; TRUE by default.
300   //! Requires sub-classing for creating a non-interleaved buffer (advanced usage).
301   virtual Standard_Boolean IsInterleaved() const { return Standard_True; }
302
303   //! Return TRUE if data can be invalidated; FALSE by default.
304   //! Requires sub-classing for creating a mutable buffer (advanced usage).
305   virtual Standard_Boolean IsMutable() const { return Standard_False; }
306
307   //! Return invalidated range; EMPTY by default.
308   //! Requires sub-classing for creating a mutable buffer (advanced usage).
309   virtual Graphic3d_BufferRange InvalidatedRange() const { return Graphic3d_BufferRange(); }
310
311   //! Reset invalidated range.
312   //! Requires sub-classing for creating a mutable buffer (advanced usage).
313   virtual void Validate() {}
314
315   //! Invalidate entire buffer.
316   virtual void Invalidate() {}
317
318   //! Dumps the content of me into the stream
319   Standard_EXPORT virtual void DumpJson (Standard_OStream& theOStream, Standard_Integer theDepth = -1) const Standard_OVERRIDE;
320
321 public:
322
323   Standard_Integer Stride;       //!< the distance to the attributes of the next vertex within interleaved array
324   Standard_Integer NbElements;   //!< number of the elements (@sa NbMaxElements() specifying the number of initially allocated number of elements)
325   Standard_Integer NbAttributes; //!< number of vertex attributes
326
327 };
328
329 DEFINE_STANDARD_HANDLE(Graphic3d_Buffer, NCollection_Buffer)
330
331 #endif // _Graphic3d_Buffer_HeaderFile