HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
GEO_VolumeElement.h
Go to the documentation of this file.
1 /*
2  * PROPRIETARY INFORMATION. This software is proprietary to
3  * Side Effects Software Inc., and is not to be reproduced,
4  * transmitted, or disclosed in any way without written permission.
5  *
6  * NAME: GEO_VolumeElement.h (GEO Library, C++)
7  *
8  * COMMENTS: This is a wrapper to handle volume elements
9  * In particular it allows using these primitives without
10  * creating the underlying primitive type.
11  */
12 
13 #pragma once
14 
15 #ifndef __GEO_VolumeElement__
16 #define __GEO_VolumeElement__
17 
18 #include "GEO_API.h"
19 #include "GEO_PrimTetrahedron.h"
20 #include "GEO_PrimHexahedron.h"
21 #include <GA/GA_Defines.h>
22 #include <GA/GA_PrimitiveTypes.h>
23 #include <SYS/SYS_Inline.h>
24 #include <UT/UT_Array.h>
25 
26 #define DISPATCH(TYPEID, FUNCTION, ...) \
27 switch ((TYPEID).get()) \
28 { \
29  case GA_PRIMTETRAHEDRON: \
30  return GEO_PrimTetrahedron::FUNCTION(__VA_ARGS__); \
31  case GA_PRIMHEXAHEDRON: \
32  return GEO_PrimHexahedron::FUNCTION(__VA_ARGS__); \
33 } \
34 /**/
35 
36 
38 {
39 public:
42  {
43  myDetail = nullptr;
44  myOffset = GA_INVALID_OFFSET;
45  myType = GA_PRIMNONE;
46  }
47 
50  {
51  bind(gdp, offset);
52  }
53 
54  /// This lets you create a stack-version of the primitive so you can
55  /// duck-type directly to GEO_PrimTetrahedron, GEO_PrimHexahedron, etc.
56  /// Usage:
57  /// GEO_VolumeElement::dispatch(type, gdp, primoff,
58  /// [&](auto &prim)
59  /// {
60  /// prim.normal(comp);
61  /// });
62  /// will be the equivalent of creating a stack GEO_PrimTetrahedon(gdp,
63  /// primoff) and calling normal on it.
64  ///
65  /// To retreive the actual type you can use decltype
66  ///
67  /// GEO_VolumeElement::dispatch(type, gdp, primoff,
68  /// [&](auto &prim)
69  /// {
70  /// using PrimT = SYS_RemoveCVRef_t<decltype(prim)>;
71  /// typename PrimT::Face face(prim, i);
72  /// });
73  template <typename OP>
74  static void dispatch(GA_PrimitiveTypeId type, const GA_Detail *gdp, GA_Offset offset, OP op)
75  {
76  UT_ASSERT(gdp);
77  UT_ASSERT(GAisValid(offset));
78  switch (type.get())
79  {
80  case GA_PRIMTETRAHEDRON:
81  {
82  const GEO_PrimTetrahedron prim(SYSconst_cast(gdp), offset, gdp->getPrimitiveVertexList(offset));
83  op(prim);
84  break;
85  }
86  case GA_PRIMHEXAHEDRON:
87  {
88  const GEO_PrimHexahedron prim(SYSconst_cast(gdp), offset, gdp->getPrimitiveVertexList(offset));
89  op(prim);
90  break;
91  }
92  default:
93  {
94  UT_ASSERT(!"Unhandled volume type.");
95  break;
96  }
97  }
98  }
99 
100  template <typename OP>
101  static void dispatch(const GA_Detail *gdp, GA_Offset offset, OP op)
102  {
103  UT_ASSERT(gdp);
104  UT_ASSERT(GAisValid(offset));
105  dispatch(gdp->getPrimitiveTypeId(offset), gdp, offset, op);
106  }
107 
108  template <typename OP>
109  static void dispatch(GA_PrimitiveTypeId type, const GA_Primitive *baseprim, OP op)
110  {
111  UT_ASSERT(baseprim);
112  switch (type.get())
113  {
114  case GA_PRIMTETRAHEDRON:
115  {
116  const GEO_PrimTetrahedron *prim = (const GEO_PrimTetrahedron *) baseprim;
117  op(*prim);
118  break;
119  }
120  case GA_PRIMHEXAHEDRON:
121  {
122  const GEO_PrimHexahedron *prim = (const GEO_PrimHexahedron *) baseprim;
123  op(*prim);
124  break;
125  }
126  default:
127  {
128  UT_ASSERT(!"Unhandled volume type.");
129  break;
130  }
131  }
132  }
133 
134  bool isValid() const
135  {
136  if (!myDetail) return false;
137  if (!GAisValid(myOffset)) return false;
138  if (GAisVolumeElement(myType)) return true;
139  return false;
140  }
141 
142  void bind(const GA_Detail *gdp, GA_Offset offset)
143  {
144  myDetail = gdp;
145  myOffset = offset;
146  myType = GA_PRIMNONE;
147  if (myDetail && GAisValid(myOffset))
148  {
149  myType = myDetail->getPrimitiveTypeId(myOffset);
150  }
151  }
152 
153  /// Update the element to point to another primitive in same detail
155  {
156  UT_ASSERT(myDetail);
157  myOffset = offset;
158  if (myDetail && GAisValid(myOffset))
159  {
160  myType = myDetail->getPrimitiveTypeId(myOffset);
161  }
162  }
163 
164  const GA_Detail *detail() const { return myDetail; }
165  GA_Offset getMapOffset() const { return myOffset; }
166  GA_PrimitiveTypeId typeId() const { return myType; }
167 
169  { DISPATCH(type, rawVertexCount); return 0; }
171  { return getVertexCount(myType, myDetail, myOffset); }
172 
173  /// Return shallow copy of the vertex list
175  { return gdp->getPrimitiveVertexList(offset); }
177  { return getVertexList(myDetail, myOffset); }
178 
179  /// Return the vertex offset from a given vertex index.
181  { return gdp->getPrimitiveVertexOffset(offset, index); }
183  { return getVertexOffset(myDetail, myOffset, index); }
184 
185  /// Return the point offset from a given vertex index.
187  { return gdp->vertexPoint(getVertexOffset(gdp, offset, index)); }
189  { return getPointOffset(myDetail, myOffset, index); }
190 
191  /// The number of faces that make up this volume
193  { DISPATCH(type, rawFaceCount); return 0; }
195  { return getFaceCount(myType, myDetail, myOffset); }
196 
197  /// Returns the indices to the vertices, not the vertex offsets!
199  { DISPATCH(type, rawFaceIndices, gdp, offset, faceno, vtxlist); return 0; }
200  int getFaceIndices(GA_Size faceno, UT_Array<int> &vtxlist) const
201  { return getFaceIndices(myType, myDetail, myOffset, faceno, vtxlist); }
202 
203  /// Returns the number of indices in specified face
205  { DISPATCH(type, rawFaceIndexCount, gdp, offset, faceno); return 0; }
206  int getFaceIndexCount(GA_Size faceno) const
207  { return getFaceIndexCount(myType, myDetail, myOffset, faceno); }
208 
209  static GA_Offset findSharedFace(GA_PrimitiveTypeId type, const GA_Detail *gdp, GA_Offset offset, GA_Size faceno);
211  { return findSharedFace(myType, myDetail, myOffset, faceno); }
212 
213  /// The number of edges in this volume.
215  { DISPATCH(type, rawEdgeCount); return 0; }
217  { return getEdgeCount(myType, myDetail, myOffset); }
218 
219  /// Returns the indices of the edge. Note each edge shows up once
220  /// and due to the nature of volumes, is undirected.
221  static void getEdgeIndices(GA_PrimitiveTypeId type, const GA_Detail *gdp, GA_Offset offset, GA_Size edgeno, int &e0, int &e1)
222  { DISPATCH(type, rawEdgeIndices, gdp, offset, edgeno, e0, e1); }
223  void getEdgeIndices(GA_Size edgeno, int &e0, int &e1) const
224  { getEdgeIndices(myType, myDetail, myOffset, edgeno, e0, e1); }
225 
226  /// Evaluate the interior point weights
228  { DISPATCH(type, rawComputeInteriorPointWeights, gdp, offset, vtxlist, weightlist, u, v, w) }
230  { computeInteriorPointWeights(myType, myDetail, myOffset, vtxlist, weightlist, u, v, w); }
231 
232 protected:
236 };
237 
238 #endif
239 
240 
SYS_FORCE_INLINE GA_Offset getPrimitiveVertexOffset(GA_Offset primoff, GA_Size i) const
Definition: GA_Primitive.h:905
static GA_Offset getPointOffset(const GA_Detail *gdp, GA_Offset offset, GA_Size index)
Return the point offset from a given vertex index.
SYS_FORCE_INLINE int getPrimitiveTypeId(GA_Offset primoff) const
Definition: GA_Primitive.h:912
const GLdouble * v
Definition: glcorearb.h:837
static void computeInteriorPointWeights(GA_PrimitiveTypeId type, const GA_Detail *gdp, GA_Offset offset, UT_Array< GA_Offset > &vtxlist, UT_Array< float > &weightlist, fpreal u, fpreal v, fpreal w)
Evaluate the interior point weights.
SYS_FORCE_INLINE T * SYSconst_cast(const T *foo)
Definition: SYS_Types.h:136
int getFaceIndexCount(GA_Size faceno) const
#define DISPATCH(TYPEID, FUNCTION,...)
GA_PrimitiveTypeId typeId() const
const GA_Detail * detail() const
void getEdgeIndices(GA_Size edgeno, int &e0, int &e1) const
static GA_Size getFaceCount(GA_PrimitiveTypeId type, const GA_Detail *d, GA_Offset offset)
The number of faces that make up this volume.
SYS_FORCE_INLINE bool GAisValid(GA_Size v)
Definition: GA_Types.h:655
exint GA_Size
Defines the bit width for index and offset types in GA.
Definition: GA_Types.h:236
GA_Size getEdgeCount() const
#define GA_INVALID_OFFSET
Definition: GA_Types.h:687
GA_Size getVertexCount() const
int getFaceIndices(GA_Size faceno, UT_Array< int > &vtxlist) const
void bind(const GA_Detail *gdp, GA_Offset offset)
GA_Size GA_Offset
Definition: GA_Types.h:646
const GA_Detail * myDetail
static int getFaceIndices(GA_PrimitiveTypeId type, const GA_Detail *gdp, GA_Offset offset, GA_Size faceno, UT_Array< int > &vtxlist)
Returns the indices to the vertices, not the vertex offsets!
static void dispatch(GA_PrimitiveTypeId type, const GA_Detail *gdp, GA_Offset offset, OP op)
GLintptr offset
Definition: glcorearb.h:665
GA_Offset getPointOffset(GA_Size index) const
void setOffset(GA_Offset offset)
Update the element to point to another primitive in same detail.
SYS_FORCE_INLINE GA_OffsetListRef getPrimitiveVertexList(GA_Offset primoff) const
Definition: GA_Primitive.h:891
static GA_Offset getVertexOffset(const GA_Detail *gdp, GA_Offset offset, GA_Size index)
Return the vertex offset from a given vertex index.
#define SYS_FORCE_INLINE
Definition: SYS_Inline.h:45
#define GEO_API
Definition: GEO_API.h:14
GA_PrimitiveTypeId myType
static GA_OffsetListRef getVertexList(const GA_Detail *gdp, GA_Offset offset)
Return shallow copy of the vertex list.
GA_Offset getMapOffset() const
SYS_FORCE_INLINE int get() const
SYS_FORCE_INLINE GA_Offset vertexPoint(GA_Offset vertex) const
Given a vertex, return the point it references.
Definition: GA_Detail.h:529
static void dispatch(GA_PrimitiveTypeId type, const GA_Primitive *baseprim, OP op)
SYS_FORCE_INLINE GEO_VolumeElement()
static void getEdgeIndices(GA_PrimitiveTypeId type, const GA_Detail *gdp, GA_Offset offset, GA_Size edgeno, int &e0, int &e1)
bool isValid() const
static GA_Size getVertexCount(GA_PrimitiveTypeId type, const GA_Detail *gdp, GA_Offset offset)
static int getFaceIndexCount(GA_PrimitiveTypeId type, const GA_Detail *gdp, GA_Offset offset, GA_Size faceno)
Returns the number of indices in specified face.
static void dispatch(const GA_Detail *gdp, GA_Offset offset, OP op)
SYS_FORCE_INLINE GEO_VolumeElement(const GA_Detail *gdp, GA_Offset offset=GA_INVALID_OFFSET)
fpreal64 fpreal
Definition: SYS_Types.h:277
GLuint index
Definition: glcorearb.h:786
GA_Size getFaceCount() const
GA_Offset getVertexOffset(GA_Size index) const
GA_Offset findSharedFace(GA_Size faceno) const
void computeInteriorPointWeights(UT_Array< GA_Offset > &vtxlist, UT_Array< float > &weightlist, fpreal u, fpreal v, fpreal w)
Container class for all geometry.
Definition: GA_Detail.h:96
GLubyte GLubyte GLubyte GLubyte w
Definition: glcorearb.h:857
#define UT_ASSERT(ZZ)
Definition: UT_Assert.h:156
static GA_Size getEdgeCount(GA_PrimitiveTypeId type, const GA_Detail *gdp, GA_Offset offset)
The number of edges in this volume.
bool GAisVolumeElement(const GA_PrimitiveTypeId &id)
type
Definition: core.h:1059
GA_OffsetListRef getVertexList() const