HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
GEO_PrimTetrahedron.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_PrimTetrahedron.h (GEO Library, C++)
7  *
8  * COMMENTS: This is the tetrahedron primitive type.
9  */
10 
11 #pragma once
12 
13 #ifndef __GEO_PrimTetrahedron__
14 #define __GEO_PrimTetrahedron__
15 
16 #include "GEO_API.h"
17 #include "GEO_Primitive.h"
18 #include "GEO_VolumeElement.h"
19 #include <GA/GA_Defines.h>
20 #include <UT/UT_Array.h>
21 #include <SYS/SYS_Inline.h>
22 
23 class GA_Detail;
24 class GEO_ConvertParms;
25 
27 {
28 public:
29  /// NOTE: This constructor should only be called via GU_PrimitiveFactory.
33  {}
34 
35  /// This constructor is for making a representation of a tetrahedron
36  /// on the stack, so that you can call GEO_PrimTetrahedron functions on
37  /// the tetrahedron without needing the detail to allocate one.
40  : GEO_VolumeElement(gdp, offset)
41  {
42  UT_ASSERT_P(vertex_list.size() == 4);
43  myVertexList = vertex_list;
44  }
45 
46  virtual const GA_PrimitiveDefinition &getTypeDef() const override;
47 
48  /// Report approximate memory usage.
49  virtual int64 getMemoryUsage() const override;
50 
51  /// Count memory usage using a UT_MemoryCounter in order to count
52  /// shared memory correctly.
53  /// NOTE: This should always include sizeof(*this).
54  virtual void countMemory(UT_MemoryCounter &counter) const override;
55 
56  void reverse() override;
57  UT_Vector3 computeNormal() const override;
58 
59  // Compute the location of the breakpoint. Return 0 if OK, else -1.
60  fpreal calcVolume(const UT_Vector3 &refpt) const override;
61  fpreal calcArea() const override;
62  fpreal calcPerimeter() const override;
63 
64  /// @{
65  /// Save/Load vertex list to a JSON stream
66  bool saveVertexArray(UT_JSONWriter &w,
67  const GA_SaveMap &map) const;
68  bool loadVertexArray(UT_JSONParser &p,
69  const GA_LoadMap &map);
70  /// @}
71 
72  bool isDegenerate() const override;
73 
74  // Take the whole set of points into consideration when applying the
75  // point removal operation to this primitive. The method returns 0 if
76  // successful, -1 if it failed because it would have become degenerate,
77  // and -2 if it failed because it would have had to remove the primitive
78  // altogether.
79  int detachPoints (GA_PointGroup &grp) override;
80 
81  /// Before a point is deleted, all primitives using the point will be
82  /// notified. The method should return "false" if it's impossible to
83  /// delete the point. Otherwise, the vertices should be removed.
84  GA_DereferenceStatus dereferencePoint(
85  GA_Offset point, bool dry_run=false) override;
86  GA_DereferenceStatus dereferencePoints(
87  const GA_RangeMemberQuery &pt_q, bool dry_run=false) override;
88 
89  //
90  // Tetrahedron layout
91  //
92  // 0 //
93  // /|\ //
94  // 1-|-3 //
95  // \|/ //
96  // 2 //
97  //
98  // Face 0 is the face *opposite* to vertex 0, so is 1..2..3
99  // Each face starts with the least vertex #.
100 
102  { return getFastVertexOffset(index); }
104  { return 4; }
106  {
107  UT_ASSERT_P(index >= 0 && index < 4);
108  return getVertexOffset(index);
109  }
110 
111  /// Return the topology of the tetrahedron
112  GA_Size getFaceCount() const override;
113  int getFaceIndices(GA_Size faceno, UT_IntArray &vtxlist) const override;
114 
116  static const int *fastFaceIndices(GA_Size faceno)
117  {
118  static const int faceidx[4][3] =
119  {
120  { 1, 2, 3 },
121  { 0, 3, 2 },
122  { 0, 1, 3 },
123  { 0, 2, 1 }
124  };
125 
126  return faceidx[faceno];
127  }
128 
129  /// Get the vertex offsets of the specified tri.
131  GA_Size tri, GA_Offset &v0, GA_Offset &v1, GA_Offset &v2) const
132  {
133  const int *indices = fastFaceIndices(tri);
134  v0 = fastVertexOffset(indices[0]);
135  v1 = fastVertexOffset(indices[1]);
136  v2 = fastVertexOffset(indices[2]);
137  }
138 
139  GA_Size getEdgeCount() const override;
140  void getEdgeIndices(GA_Size edgeno, int &e0, int &e1) const override;
141 
142  bool hasEdge(const GA_Edge &edge) const override
143  {
144  for (GA_Size i = 0; i < 6; ++i)
145  {
146  int i0, i1;
147  getEdgeIndices(i, i0, i1);
148  GA_Offset p0 = getPointOffset(i0);
149  GA_Offset p1 = getPointOffset(i1);
150  if ((edge.p0() == p0 && edge.p1() == p1) ||
151  (edge.p0() == p1 && edge.p1() == p0))
152  return true;
153  }
154  return false;
155  }
156 
157 
158  void iterateEdges(GA_IterateEdgesFunc apply_func) const override
159  {
160  for (int i = 0; i < 6; ++i)
161  {
162  int i0; int i1;
163  getEdgeIndices(i, i0, i1);
164  // Both directions are present
165  if (!apply_func(GA_Edge(getPointOffset(i0), getPointOffset(i1))))
166  return;
167  if (!apply_func(GA_Edge(getPointOffset(i1), getPointOffset(i0))))
168  return;
169  }
170  }
171 
172  void iterateEdgesByVertex(GA_IterateEdgesByVertexFunc apply_func) const override
173  {
174  for (int i = 0; i < 6; ++i)
175  {
176  int i0; int i1;
177  getEdgeIndices(i, i0, i1);
178 
179  // Both directions are present
180  if (!apply_func(i0, i1) || !apply_func(i1, i0))
181  return;
182  }
183  }
184 
185  // Given two vertex indices giving a tet edge, this routine returns
186  // another vertex index, which forms an outward facing tet face with the
187  // original edge vertices e1 and e2.
188  GA_Size getVertexCompletingFace(GA_Size v1, GA_Size v2, GA_Size &v3) const;
189 
190  GA_Offset findSharedTet(GA_Size faceno) const;
192  bool isFaceShared(GA_Size faceno) const
193  { return GAisValid(findSharedTet(faceno)); }
194 
195  virtual GA_Offset findSharedFace(GA_Size faceno) const override
196  { return findSharedTet(faceno); }
197 
198  // These methods find the index of the given vertex (vtx or the vertex
199  // that contains a pt). Return -1 if not found.
201  {
202  for (GA_Size i = 0; i < 4; i++)
203  if (fastVertexOffset(i) == vtx) return i;
204  return -1;
205  }
206 
208  {
209  for (GA_Size i = 0; i < 4; i++)
210  if (vertexPoint(i) == pt) return i;
211  return -1;
212  }
213 
214  void setVertexPoint(int i, GA_Offset pt)
215  {
216  if (i < 4)
217  wireVertex(fastVertexOffset(i), pt);
218  }
219 
220  const GA_PrimitiveJSON *getJSON() const override;
221 
222  /// Takes (u,v,w) between 0 and 1, and reflects them inside the unit cube
223  /// so that they fall in the region where (1-u-v-w) >= 0 (and <= 1).
224  /// That value is written into uvw.
225  /// This is instantiated for float and double.
226  template<typename T>
227  static void remapTetCoords(T &u, T &v, T &w, T &uvw);
228 
229  class Face
230  {
231  public:
232  Face(const GEO_PrimTetrahedron &tet,int face)
233  : myTet(tet)
234  , myI(face)
235  // This is the face opposite myI
236  , myF(GEO_PrimTetrahedron::fastFaceIndices(myI))
237  {}
239  { return 3; }
240  inline GA_Size getVertexCount() const
241  { return 3; }
243  { return myTet.getFastVertexOffset(myF[i]); }
245  { return getFastVertexOffset(i); }
247  { return myTet.getPointOffset(myF[i]); }
248  inline UT_Vector3 getPos3(GA_Size i) const
249  { return myTet.getPos3(myF[i]); }
250  inline bool isClosed() const
251  { return true; }
252  private:
253  const GEO_PrimTetrahedron &myTet;
254  int myI;
255  const int *const myF;
256  };
257 
258  /// NOTE: Do not use this under normal circumstances!
259  /// This is for if a tet has been added using
260  /// GA_Detail::appendPrimitive[Block] and vertices have
261  /// to be added one at a time, e.g. from VEX.
262  /// It will return GA_INVALID_OFFSET and won't add a vertex
263  /// if all 4 have already been assigned.
264  GA_Offset unsafeAppendVertex();
265 
266  virtual void normal(NormalComp &output) const override;
267 
268  // Conversion Methods
269  virtual GEO_Primitive *convert(GEO_ConvertParms &parms,
270  GA_PointGroup *usedpts = nullptr) override;
271  virtual GEO_Primitive *convertNew(GEO_ConvertParms &parms) override;
272 
273  // A convenience member to determine if a particular location lies within
274  // the tetrahedron
275  bool isContainedInside(const UT_Vector3 &pt_pos,
276  fpreal64 tolerance = SYS_FTOLERANCE_D) const;
277 
278  /// Builds a single tetrahedron primitive, optionally creating new points
279  /// and wiring them to its vertices.
280  static GEO_PrimTetrahedron *build(GEO_Detail *gdp, bool appendPts = true);
281 
282  /// Builds tetrahedrons using the specified range of point offsets,
283  /// as dictated by ntets and tetpointnumbers, in parallel.
284  /// tetpointnumbers lists the *offsets* of the points used by
285  /// each tetrahedron *MINUS* startpt, i.e. they are offsets relative to
286  /// startpt, *not* indices relative to startpt. The offset of the first
287  /// tetrahedron is returned, and the rest are at consecutive offsets. All
288  /// tetpointnumbers must be between 0 (inclusive) and npoints (exclusive).
289  ///
290  /// NOTE: Existing primitives *are* allowed to be using the points in
291  /// the specified range already, and the tetrahedrons being created do not
292  /// do not need to use all of the points in the range. However,
293  /// these cases may impact performance.
294  static GA_Offset buildBlock(GA_Detail *detail,
295  const GA_Offset startpt,
296  const GA_Size npoints,
297  const GA_Size ntets,
298  const int *tetpointnumbers);
299 
300  virtual void computeInteriorPointWeights(
301  UT_Array<GA_Offset> &vtxlist, UT_Array<float> &weightlist,
302  fpreal u, fpreal v, fpreal w) const override final;
303 
304 protected:
305  void allocateVertices();
306 
307  GA_DECLARE_INTRINSICS(override)
308 
309  // Check the validity of the data. Meant to be called especially at loading
310  // time. The method returns 1 if OK and 0 if trouble.
311  virtual bool validate(void) const;
312 
313  /// @warning vertexPoint() doesn't check the bounds. Use with caution.
314  GA_Offset vertexPoint(GA_Size i) const
315  { return getDetail().vertexPoint(fastVertexOffset(i)); }
316 
317  // Evaluates the position at domain point (u,v,w) in the interior of the
318  // geometry, rather than on the perimeter of the poly.
319  // (Note that u, v, w don't have to be converted to unit domain. We assume
320  // that the barycentric coords or bilinear interpolants are already
321  // correctly scaled).
322  // Vertex 0 is the origin of this system, Vertex 1 the U axis
323  // Vertex 2 the V, and Vertex 3 the W.
325  GA_Offset result_vtx, GA_AttributeRefMap &map,
326  fpreal u, fpreal v, fpreal w = 0) const override;
328  UT_Vector4 &pos, fpreal u, fpreal v, fpreal w = 0) const override;
329 
331  friend class GU_PrimitiveFactory;
332 private:
333 };
334 
335 #endif
336 
virtual void getEdgeIndices(GA_Size edgeno, int &e0, int &e1) const =0
SYS_FORCE_INLINE GA_Offset getPointOffset(GA_Size i) const
Definition: GA_Primitive.h:246
GA_Size findVertex(GA_Offset vtx) const
GLsizei GLenum const void * indices
Definition: glcorearb.h:405
SYS_FORCE_INLINE GA_Detail & getDetail() const
Definition: GA_Primitive.h:133
Used to pass options and map offset values during saving.
Definition: GA_SaveMap.h:48
SYS_FORCE_INLINE GA_Size getFastVertexCount() const
Face(const GEO_PrimTetrahedron &tet, int face)
GA_Offset getVertexOffset(GA_Size i) const
void setVertexPoint(int i, GA_Offset pt)
virtual void computeInteriorPointWeights(UT_Array< GA_Offset > &vtxlist, UT_Array< float > &weightlist, fpreal u, fpreal v, fpreal w) const
const GLdouble * v
Definition: glcorearb.h:836
bool GAisValid(GA_Size v)
Definition: GA_Types.h:625
virtual GA_DereferenceStatus dereferencePoint(GA_Offset point, bool dry_run=false)=0
JSON reader class which handles parsing of JSON or bJSON files.
Definition: UT_JSONParser.h:75
bool hasEdge(const GA_Edge &edge) const override
Method to determine if a primitive has an edge (undirected).
#define GA_DECLARE_INTRINSICS(OVERRIDE)
Definition: GA_Primitive.h:80
Class which writes ASCII or binary JSON streams.
Definition: UT_JSONWriter.h:32
Abstract base class for a range membership query object.
#define SYS_FTOLERANCE_D
Definition: SYS_Types.h:204
void iterateEdges(GA_IterateEdgesFunc apply_func) const override
GLfloat GLfloat GLfloat v2
Definition: glcorearb.h:817
GA_EdgeT< GA_Offset, false > GA_Edge
Definition: GA_Edge.h:91
3D Vector class.
GLfloat GLfloat GLfloat GLfloat v3
Definition: glcorearb.h:818
virtual int64 getMemoryUsage() const
Definition: GA_Primitive.h:201
png_uint_32 i
Definition: png.h:2877
void wireVertex(GA_Offset vertex, GA_Offset point)
exint GA_Size
Defines the bit width for index and offset types in GA.
Definition: GA_Types.h:211
SYS_FORCE_INLINE GA_Offset fastVertexOffset(GA_Size index) const
#define GA_INVALID_OFFSET
Definition: GA_Types.h:654
virtual void normal(NormalComp &output) const =0
virtual GA_Size getFaceCount() const =0
The number of faces that make up this volume.
virtual bool isDegenerate() const =0
Is the primitive degenerate.
GA_Size GA_Offset
Definition: GA_Types.h:617
void getTriangleVertexOffsets(GA_Size tri, GA_Offset &v0, GA_Offset &v1, GA_Offset &v2) const
Get the vertex offsets of the specified tri.
UT_Vector3 getPos3(GA_Size i) const
long long int64
Definition: SYS_Types.h:107
virtual GA_Offset findSharedFace(GA_Size faceno) const override
virtual int evaluateInteriorPointV4(UT_Vector4 &pos, fpreal u, fpreal v, fpreal w=0) const
virtual void countMemory(UT_MemoryCounter &counter) const
virtual fpreal calcArea() const
#define UT_ASSERT_P(ZZ)
Definition: UT_Assert.h:125
double fpreal64
Definition: SYS_Types.h:192
#define SYS_FORCE_INLINE
Definition: SYS_Inline.h:45
virtual const GA_PrimitiveJSON * getJSON() const =0
GLintptr offset
Definition: glcorearb.h:664
Provide a JSON interface to a primitive.
void iterateEdgesByVertex(GA_IterateEdgesByVertexFunc apply_func) const override
#define GEO_API
Definition: GEO_API.h:10
std::function< bool(const GA_Edge &edge)> GA_IterateEdgesFunc
Definition: GA_Primitive.h:73
virtual void reverse()=0
Reverse the order of vertices.
A handle to simplify manipulation of multiple attributes.
virtual GA_Size getEdgeCount() const =0
The number of edges in this volume.
Options during loading.
Definition: GA_LoadMap.h:42
T p1() const
Definition: GA_Edge.h:33
SYS_FORCE_INLINE GA_Offset vertexPoint(GA_Offset vertex) const
Given a vertex, return the point it references.
Definition: GA_Detail.h:473
std::function< bool(GA_Size, GA_Size)> GA_IterateEdgesByVertexFunc
Definition: GA_Primitive.h:74
virtual fpreal calcPerimeter() const
virtual UT_Vector3 computeNormal() const
Return a normal vector for the primitive.
GA_Offset getFastVertexOffset(GA_Size i) const
virtual GA_DereferenceStatus dereferencePoints(const GA_RangeMemberQuery &pt_q, bool dry_run=false)=0
SYS_FORCE_INLINE GEO_PrimTetrahedron(GA_Detail *d, GA_Offset offset=GA_INVALID_OFFSET)
NOTE: This constructor should only be called via GU_PrimitiveFactory.
GLfloat v0
Definition: glcorearb.h:815
virtual bool evaluateInteriorPointRefMap(GA_Offset result_vtx, GA_AttributeRefMap &map, fpreal u, fpreal v, fpreal w=0) const
double fpreal
Definition: SYS_Types.h:270
virtual int detachPoints(GA_PointGroup &grp)=0
GA_Size getFastVertexCount() const
SYS_FORCE_INLINE GEO_PrimTetrahedron(GA_Detail *gdp, GA_Offset offset, const GA_OffsetListRef &vertex_list)
SYS_FORCE_INLINE GA_Offset getFastVertexOffset(GA_Size index) const
GLuint index
Definition: glcorearb.h:785
GA_Size find(GA_Offset pt) const
GLfloat GLfloat v1
Definition: glcorearb.h:816
virtual fpreal calcVolume(const UT_Vector3 &) const
SYS_FORCE_INLINE GA_Offset getVertexOffset(GA_Size primvertexnum) const
Definition: GA_Primitive.h:232
static GA_PrimitiveDefinition * theDefinition
SYS_FORCE_INLINE bool isFaceShared(GA_Size faceno) const
Container class for all geometry.
Definition: GA_Detail.h:95
virtual GEO_Primitive * convert(GEO_ConvertParms &parms, GA_PointGroup *usedpts=0)=0
GLubyte GLubyte GLubyte GLubyte w
Definition: glcorearb.h:856
T p0() const
Definition: GA_Edge.h:31
Definition of a geometric primitive.
#define const
Definition: zconf.h:214
GA_Offset getPointOffset(GA_Size i) const
virtual const GA_PrimitiveDefinition & getTypeDef() const =0
virtual int getFaceIndices(GA_Size faceno, UT_IntArray &vtxlist) const =0
Returns the indices to the vertices, not the vertex offsets!
virtual GEO_Primitive * convertNew(GEO_ConvertParms &parms)=0
SYS_FORCE_INLINE FromType size() const
Returns the number of used elements in the list (always <= capacity())
static SYS_FORCE_INLINE const int * fastFaceIndices(GA_Size faceno)