HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
GEO_Primitive.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: Geometry Library (C++)
7  *
8  * COMMENTS:
9  * The className method is used for saving/loading so there should
10  * be no spaces in the name.
11  *
12  */
13 
14 #pragma once
15 
16 #ifndef __GEO_Primitive_H__
17 #define __GEO_Primitive_H__
18 
19 #include "GEO_API.h"
20 #include <iosfwd>
21 #include <UT/UT_Matrix4.h>
22 #include <UT/UT_BoundingBox.h>
23 #include <UT/UT_BoundingSphere.h>
24 #include <GA/GA_Primitive.h>
25 #include "GEO_PrimType.h"
26 
27 class GA_AttributeRefMap;
28 class GA_Detail;
31 class GEO_ConvertParms;
32 class GEO_Detail;
33 class GEO_MetaPrim;
34 class GEO_Vertex;
35 
36 template<typename T, bool B> class GA_EdgeT;
38 
40 
42 {
43 protected:
44  /// NOTE: The constructor should only be called from subclass
45  /// constructors.
48  : GA_Primitive(*d, offset)
49  {}
50 
51  /// NOTE: The destructor should only be called from subclass
52  /// destructors; only GEO_Detail::destroyStashed() should be
53  /// calling delete on GEO_Primitive pointers, and GEO_Detail
54  /// is a friend.
55  ~GEO_Primitive() override {}
56 
57 public:
58  GA_PrimCompat::TypeMask getPrimitiveId() const override;
59 
60  /// Copy attribute data from the source primitive. Also, copy over all the
61  /// group membership information from the source primitive.
63  bool copy_groups=true)
64  {
65  copyAttributeData(src);
66  if (copy_groups)
67  copyGroupMembership(src);
68  }
70  GA_AttributeRefMap &gah,
71  bool copy_groups=true)
72  {
73  copyAttributeData(src, gah);
74  if (copy_groups)
75  copyGroupMembership(src);
76  }
77  /// NOTE: The copying of groups only works if src is in the same detail
79  GA_PrimitiveWrangler &wrangler,
80  bool copy_groups=true)
81  {
82  copyAttributeData(src, wrangler);
83  if (copy_groups)
84  copyGroupMembership(src);
85  }
86 
87  /// Copy the attribute data over from the source primitive. Often you will
88  /// want to call copyAttributesAndGroups() instead.
89  void copyAttributeData(const GEO_Primitive &src);
90  void copyAttributeData(const GEO_Primitive &src,
91  GA_AttributeRefMap &gah);
92  void copyAttributeData(const GEO_Primitive &src,
93  GA_PrimitiveWrangler &wrangler);
94 
95  void copyAttributeValues(const GEO_Primitive &src,
96  GA_PrimitiveWrangler &wrangler);
97 
98  /// Copy the group membership from the source primitive to the current
99  /// primitive. Both primitives must be in the same detail.
100  void copyGroupMembership(const GEO_Primitive &src);
101 
102  // NOTE: The point *indices* will be the same as in src.
103  // If this and src are in the same detail, this means that
104  // the point offsets will also be the same. There must be
105  // sufficient points in this' detail.
106  // NOTE: To remap the points, you can iterate through the vertices
107  // of the primitive after copying, and call getPointOffset
108  // and setPointOffset.
109  //
110  // copyPrimitive(), unlike copy(), will not copy the primitive attributes.
111  // (see copyAttributeData() or copyAttributesAndGroups()).
112 #if GA_PRIMITIVE_VERTEXLIST
113  virtual void copyPrimitive(const GEO_Primitive *src);
114 #else
115  virtual void copyPrimitive(const GEO_Primitive *src)=0;
116 #endif
117  virtual GEO_Primitive *copy(int preserve_shared_pts = 0) const;
118 
119  // Transforms the matrix associated with this primitive. The
120  // translate component is ignored: Translate the vertices of
121  // the primitive to translate the primitive.
122  // This only works with quadrics (sphere, tube, metaballs) and volumes.
123  virtual void transform(const UT_Matrix4 &);
124 
125  // Convert the real domain values of the primitive to unit values to be
126  // used in the evaluation methods below:
127  virtual void realToUnitPair(float ureal, float vreal,
128  float &uunit, float &vunit) const;
129 
130  // Convert the unit values of the primitive to the real domain values
131  virtual void unitToRealPair(float uunit, float vunit,
132  float &ureal, float &vreal) const;
133 
134  // Map the normalized length (distance value [0,1]) parameter to the unit
135  // parameterization of the primitve
136  virtual void unitLengthToUnitPair(float ulength, float vlength,
137  float &uparm, float &vparm)const;
138  virtual void unitLengthToUnitPair(float ulength, float vlength,
139  float &uparm, float &vparm, float tolerance)const;
140 
141  virtual void unitToUnitLengthPair(float uparm, float vparm,
142  float &ulength, float &vlength)
143  const;
144 
145  // Evaluate a set of attributes at the bary center of the primitive,
146  // returning true on success, false on failure.
147  bool evaluateBaryCenter(GA_Offset result_vtx,
148  GA_AttributeRefMap &map) const
149  { return evaluateBaryCenterRefMap(result_vtx, map); }
150 
151  // Evaluate a set of attributes at a u,v position. Optionally, evaluate
152  // the derivative in the u or v direction.
153  // The method returns true if the point could be evaluated
154  bool evaluatePoint(GA_Offset result_vtx,
155  GA_AttributeRefMap &map,
156  fpreal u, fpreal v=0,
157  uint du=0, uint dv=0) const
158  { return evaluatePointRefMap(result_vtx, map, u, v, du, dv); }
159 
160  // Evaluate the position, the derivative or the normal at domain point
161  // (u,v), where u and v MUST be in [0,1]. "v" and "dv" will be ignored
162  // when dealing with one-dimensional types such as circles and polygons.
163  // Return 0 if OK and -1 otherwise. The normal is not normalized.
164  int evaluatePoint( UT_Vector4 &pos, float u, float v = 0,
165  unsigned du=0, unsigned dv=0) const
166  { return evaluatePointV4(pos, u, v, du, dv); }
167 
168  virtual int evaluateNormalVector(UT_Vector3 &nml, float u,
169  float v = 0, float w = 0) const;
170 
171  // Evaluate the position at domain point (u,v) in the interior of the
172  // geometry. This calls evaluatePoint by default, but has a different
173  // implementation for triangles and quadrilaterals, where barycentric
174  // coords or bilinear interpolants are used to get an interior point,
175  // rather than a point on the perimeter of the poly. This was added
176  // so particles can stick to triangles and quads.
178  GA_AttributeRefMap &map,
179  fpreal u, fpreal v, fpreal w = 0) const
180  { return evaluateInteriorPointRefMap(
181  result_vtx, map, u, v, w); }
183  fpreal u, fpreal v, fpreal w = 0) const
184  { return evaluateInteriorPointV4(pos, u, v, w); }
185 
186 
187  /// Finds the weightings of the vertices that will compute an interior
188  /// point given the u,v,w coordinates. The offsets are into the gdp's
189  /// vertex list, not indices into this primitive's vertex list.
190  /// Weights are normalized.
191  /// Note this cannot be used to recover the Position as it often has
192  /// special case logic (as in spheres, or rational splines), in those
193  /// cases use evaluateInteriorPoint(UT_Vector4 &pos, ...)
194  /// It has the advantage over the other evaluateInteriorPoints in that
195  /// it allows you to avoid creating any temporary vertices.
196  /// Behaviour for non-sublcassed types is to return the 0th vertex.
197  virtual void computeInteriorPointWeights(
198  UT_Array<GA_Offset> &vtxlist,
199  UT_Array<float> &weightlist,
200  fpreal u, fpreal v, fpreal w) const;
201 
203  {
204  // We cannot do a static_cast because we have only forward
205  // declared GEO_Detail and GA_Detail
206  return reinterpret_cast<GEO_Detail *>(&getDetail());
207  }
208  static GA_PrimCompat::TypeMask getPrimitiveMaskH9(const char *maskstr);
209 
210  /// Compute the bounding box of the primitive. Return 0 if unable to
211  /// compute bounds (1 on successful computation).
212  /// This function should always initialize bbox, even if returning false,
213  /// in which case, the bbox->isValid() may be false, representing an
214  /// empty bounding box.
215  /// This function should also not use any initial value of bbox,
216  /// so it does not need to be initialized beforehand.
217  virtual int getBBox(UT_BoundingBox *bbox) const = 0;
218 
219  /// @{
220  /// If the attribute is "P" the base-class will call getBBox()
221  bool enlargeBoundingBox(
223  const GA_Attribute *P) const override;
224  bool enlargeBoundingBox(
225  UT_BoundingBox &b,
226  const GA_Attribute *P) const override;
227  /// @}
228 
229  /// Return a normal vector for the primitive
230  virtual UT_Vector3 computeNormal() const = 0;
231 
232  /// Reverse the order of vertices
233  void reverse() override = 0;
234 
235  /// Return the center of the primitive. This defaults to the center of the
236  /// bounding box. A better approximation might be the average value of the
237  /// vertex positions (which could be different).
238  virtual UT_Vector3 baryCenter() const;
239 
240  /// Enlarge the bounding sphere with the primitive's bounds.
241  /// By default, this will enlarge the bounding sphere by the primitive's
242  /// bounding box (i.e. getBBox()). It may be possible to have a tighter
243  /// bound (i.e. the vertex hull for many primitives is a much better
244  /// metric).
245  virtual void addToBSphere(UT_BoundingSphere *bsphere) const;
246 
247  /// Method to isolate a pasted surface
248  virtual void isolate() { /* No implementation here. */ }
249 
250  // Take the whole set of points into consideration when applying the
251  // point removal operation to this primitive. The method returns 0 if
252  // successful, -1 if it failed because it would have become degenerate,
253  // and -2 if it failed because it would have had to remove the primitive
254  // altogether.
255  virtual int detachPoints (GA_PointGroup &grp) = 0;
256 
257  bool hasEdge(const GA_Edge &edge) const override;
258 
259  /// These functions are only implemented to get guide points/edges
260  /// for spheres, tubes, and circles. The ID meaning is type-specific.
261  /// @{
262  virtual bool hasGuideEdge(int edgeid, UT_Vector3 &a,
263  UT_Vector3 &b) const;
264  virtual bool hasXsectPoint(int pointid, UT_Vector3 &p) const;
265  /// @}
266 
267  /// Apply the function to each vertex of the primitive. Break
268  /// when the function returns true. Return the value
269  /// of the last function applied (false if never called).
270 #if !GA_PRIMITIVE_VERTEXLIST
271  virtual bool vertexApply(bool (*apply)(GA_Offset vtx, void *),
272  void *data = 0) const;
273 #endif
274 
275  SYS_DEPRECATED_HDK(13.0)
276  GEO_Vertex getVertexElement(GA_Size i) const;
277 
278 //
279 // Method to get the tessera data for meta-primitives
280  virtual GEO_MetaPrim *castToMetaPrim();
281  virtual const GEO_MetaPrim *castToMetaPrim() const;
282 
283  // Return the surrounding values of the real-space u,v parameters.
284  // Returns 1 if succesful, 0 if out-of-range.
285 
286  virtual int parametricBBox(float u, float v,
287  float *u0, float *u1,
288  float *v0, float *v1);
289 
290  // Returns distance between two points in parameter space, aware
291  // of any possible wrapping.
292  virtual float uvDist(float u1, float v1, float u2, float v2) const;
293 
294  // Intersects a ray with the bounding box, iteratively growing it until
295  // an intersection is found or maxtries is reached.
296  int bboxIntersectRay(const UT_Vector3 &rayorig,
297  const UT_Vector3 &raydir,
298  int maxtries = 10,
299  float tmax = 1E17F,
300  float *distance = 0,
301  UT_Vector3 *nml=0) const;
302 
303  /// @{
304  /// If the method isn't known, or doesn't make sense, we return 0.
305  fpreal calcVolume(const UT_Vector3 &) const override
306  { return 0; }
307  fpreal calcArea() const override { return 0; }
308  fpreal calcPerimeter() const override { return 0; }
309  /// @}
310 
311  // Is this primitive a GEO_Quadric?
312  virtual bool isQuadric() const { return false; }
313 
314  // Compute normals on points using a subclass of NormalComp. This
315  // class receives the point offset and vertex normal at that point, and
316  // will either add or subtract the normal from the existing data.
318  public:
319  virtual ~NormalComp() {}
320  virtual void add(GA_Offset offset, const UT_Vector3 &nml) {}
321  virtual void sub(GA_Offset offset, const UT_Vector3 &nml) {}
322  };
323 
324  // Compute point normals into an array, indexed by the point order
325  // number
327  public:
329  : myGdp(gdp)
330  , myOutput(output) {}
331  void add(GA_Offset offset, const UT_Vector3 &nml) override
332  { myOutput(myGdp.pointIndex(offset)) += nml; }
333  void sub(GA_Offset offset, const UT_Vector3 &nml) override
334  { myOutput(myGdp.pointIndex(offset)) -= nml; }
335 
336  private:
337  const GA_Detail &myGdp;
338  UT_Vector3Array &myOutput;
339  };
340 
341  // Compute normals into a normal attribute
343  public:
345  : myHandle(attr.getAttribute()) {}
347  : myHandle(attr) {}
348  void add(GA_Offset offset, const UT_Vector3 &nml) override
349  { myHandle.add(offset, nml); }
350  void sub(GA_Offset offset, const UT_Vector3 &nml) override
351  { myHandle.add(offset, -nml); }
352 
353  GA_RWHandleV3 &getHandle() { return myHandle; }
354 
355  protected:
357  };
358 
359  // Compute normals into a normal attribute
361  {
362  public:
364  : myParent(parent)
365  , myLock(lock)
366  , myBufferEntries(0)
367  {}
369  {
370  flush();
371  }
372  void add(GA_Offset offset, const UT_Vector3 &nml) override
373  {
374  myOffsetBuffer[myBufferEntries] = offset;
375  myDataBuffer[myBufferEntries] = nml;
376  ++myBufferEntries;
377  if (myBufferEntries == theBufferSize)
378  flush();
379  }
380 
381  void sub(GA_Offset offset, const UT_Vector3 &nml) override
382  {
383  myOffsetBuffer[myBufferEntries] = offset;
384  myDataBuffer[myBufferEntries] = -nml;
385  ++myBufferEntries;
386  if (myBufferEntries == theBufferSize)
387  flush();
388  }
389 
390  void flush()
391  {
392  UT_AutoLock lock(myLock);
393  for (GA_Size i = 0; i < myBufferEntries; ++i)
394  {
395  myParent.add(myOffsetBuffer[i], myDataBuffer[i]);
396  }
397  myBufferEntries = 0;
398  }
399 
400  private:
401  static const GA_Size theBufferSize = 1024;
402 
403  NormalComp &myParent;
404  UT_Lock &myLock;
405  GA_Size myBufferEntries;
406  GA_Offset myOffsetBuffer[theBufferSize];
407  UT_Vector3 myDataBuffer[theBufferSize];
408  };
409 
410  virtual void normal(NormalComp &output) const = 0;
411 
412  // Conversion Methods
413 
414  // This method converts the primitive to the specified toType and deletes
415  // the old primitive.
416 
417  virtual GEO_Primitive *convert(GEO_ConvertParms &parms,
418  GA_PointGroup *usedpts = 0) = 0;
419 
420  // This method creates a new primitive by converting the old primitive to
421  // the specified toType.
422 
423  virtual GEO_Primitive *convertNew(GEO_ConvertParms &parms) = 0;
424 
425  // The default implementation just checks the bounding box and
426  // deletes the primitive if the bounding box is beyond the plane.
427  // NOTE: normal should be normalized
428  virtual void clip(UT_Vector3 normal, float distance = 0,
429  GA_PrimitiveGroup *clipgrp = NULL);
430 
431  // The default implementation just intersects against the bounding box
432  virtual int intersectRay(const UT_Vector3 &o, const UT_Vector3 &d,
433  float tmax = 1E17F, float tol = 1E-12F,
434  float *distance = 0, UT_Vector3 *pos = 0,
435  UT_Vector3 *nml = 0, int accurate = 0,
436  float *u = 0, float *v = 0,
437  int ignoretrim = 1) const;
438 
439 
440  /// Convience objects to pass as arguments to saveH9()/loadH9().
442 
443 protected:
444  /// All subclasses should call this method to register the primitive
445  /// intrinsics.
446  /// @see GA_IntrinsicManager
449  { return GA_Primitive::registerIntrinsics(defn); }
450 
451  virtual bool evaluatePointRefMap(GA_Offset result_vtx,
452  GA_AttributeRefMap &map,
453  fpreal u, fpreal v=0,
454  uint du=0, uint dv=0) const = 0;
455 
456  /// Evaluate the position for the given parametric coordinates (with the
457  /// given derivatives). Return 0 if successful, or -1 if failure.
458  /// The default implementation returns {0,0,0,0};
459  virtual int evaluatePointV4( UT_Vector4 &pos, float u, float v = 0,
460  unsigned du=0, unsigned dv=0) const;
461 
462  /// By default, this will call evaluateInteriorPointRefMap with u=.5 and
463  /// v=.5. This is likely not the perfect solution. At the current time,
464  /// this is only used in POPs to birth points at primitive centers.
465  virtual bool evaluateBaryCenterRefMap(GA_Offset result_vtx,
466  GA_AttributeRefMap &map) const;
467 
468  virtual bool evaluateInteriorPointRefMap(GA_Offset result_vtx,
469  GA_AttributeRefMap &map,
470  fpreal u, fpreal v, fpreal w = 0) const;
471  virtual int evaluateInteriorPointV4(UT_Vector4 &pos,
472  fpreal u, fpreal v, fpreal w = 0) const;
473 
474 private:
475  friend class GEO_Detail; // Allow detail to get at private stuff
476 
477  // TODO: Eliminate, deprecate, or switch to saving json format.
478  friend std::ostream &operator<<(std::ostream &os, const GEO_Primitive &d)
479  {
480  d.saveH9(os, /*binary*/false,
483  return os;
484  }
485 };
486 
488 
489 #endif
fpreal calcPerimeter() const override
Definition of a geometry attribute.
Definition: GA_Attribute.h:196
void add(GA_Offset offset, const UT_Vector3 &nml) override
NormalCompArray(const GA_Detail &gdp, UT_Vector3Array &output)
GLenum src
Definition: glew.h:2410
*get result *(waiting if necessary)*A common idiom is to fire a bunch of sub tasks at the and then *wait for them to all complete We provide a helper class
Definition: thread.h:643
GLuint GLenum GLenum transform
Definition: glew.h:14742
GLuint GLdouble u1
Definition: glew.h:3446
#define SYS_DEPRECATED_PUSH_DISABLE()
void copyAttributesAndGroups(const GEO_Primitive &src, GA_AttributeRefMap &gah, bool copy_groups=true)
Definition: GEO_Primitive.h:69
#define SYS_DEPRECATED_POP_DISABLE()
bool evaluateInteriorPoint(GA_Offset result_vtx, GA_AttributeRefMap &map, fpreal u, fpreal v, fpreal w=0) const
GLboolean GLboolean GLboolean GLboolean a
Definition: glew.h:9477
void copyAttributesAndGroups(const GEO_Primitive &src, bool copy_groups=true)
Definition: GEO_Primitive.h:62
NormalCompBuffered(NormalComp &parent, UT_Lock &lock)
virtual void add(GA_Offset offset, const UT_Vector3 &nml)
void reverse(I begin, I end)
Definition: pugixml.cpp:7190
SYS_FORCE_INLINE GEO_Detail * getParent() const
~GEO_Primitive() override
Definition: GEO_Primitive.h:55
Tto convert(const Tfrom &source)
const GLdouble * v
Definition: glew.h:1391
fpreal calcArea() const override
exint GA_Size
Defines the bit width for index and offset types in GA.
Definition: GA_Types.h:233
#define GA_INVALID_OFFSET
Definition: GA_Types.h:676
GA_Size GA_Offset
Definition: GA_Types.h:639
NormalCompAttr(const GA_RWHandleV3 &attr)
This class provides a way to manage a reference to an attribute permitting Read-Write access...
GLfloat GLfloat GLfloat v2
Definition: glew.h:1856
void sub(GA_Offset offset, const UT_Vector3 &nml) override
virtual void sub(GA_Offset offset, const UT_Vector3 &nml)
GLint GLenum GLsizei GLint GLsizei const void * data
Definition: glew.h:1379
void add(GA_Offset offset, const UT_Vector3 &nml) override
#define SYS_FORCE_INLINE
Definition: SYS_Inline.h:45
GLubyte GLubyte GLubyte GLubyte w
Definition: glew.h:1890
int evaluateInteriorPoint(UT_Vector4 &pos, fpreal u, fpreal v, fpreal w=0) const
GLsizei GLsizei GLfloat distance
Definition: glew.h:13640
#define GEO_API
Definition: GEO_API.h:14
bool evaluatePoint(GA_Offset result_vtx, GA_AttributeRefMap &map, fpreal u, fpreal v=0, uint du=0, uint dv=0) const
A handle to simplify manipulation of multiple attributes.
NormalCompAttr(const GA_RWAttributeRef &attr)
#define SYS_DEPRECATED_HDK(__V__)
virtual bool saveH9(std::ostream &os, bool binary, const UT_Array< GA_AttribSaveDataH9 > &prim_attribs, const UT_Array< GA_AttribSaveDataH9 > &vtx_attribs) const
void sub(GA_Offset offset, const UT_Vector3 &nml) override
GLdouble GLdouble GLdouble b
Definition: glew.h:9122
GLfloat GLfloat p
Definition: glew.h:16321
void sub(GA_Offset offset, const UT_Vector3 &nml) override
IMATH_INTERNAL_NAMESPACE_HEADER_ENTER T clip(const T &p, const Box< T > &box)
Definition: ImathBoxAlgo.h:89
SYS_FORCE_INLINE GEO_Primitive(GA_Detail *d, GA_Offset offset=GA_INVALID_OFFSET)
Definition: GEO_Primitive.h:47
int evaluatePoint(UT_Vector4 &pos, float u, float v=0, unsigned du=0, unsigned dv=0) const
static const UT_Array< GA_AttribSaveDataH9 > & theEmptySaveAttribs
Convience objects to pass as arguments to saveH9()/loadH9().
fpreal64 fpreal
Definition: SYS_Types.h:277
bool evaluateBaryCenter(GA_Offset result_vtx, GA_AttributeRefMap &map) const
OIIO_API bool copy(string_view from, string_view to, std::string &err)
GLfloat v0
Definition: glew.h:1848
GLuint GLdouble GLdouble u2
Definition: glew.h:3446
Container class for all geometry.
Definition: GA_Detail.h:95
friend std::ostream & operator<<(std::ostream &os, const GEO_Primitive &d)
Definition of a geometric primitive.
#define const
Definition: zconf.h:214
void add(GA_Offset offset, const UT_Vector3 &nml) override
virtual bool isQuadric() const
void copyAttributesAndGroups(const GEO_Primitive &src, GA_PrimitiveWrangler &wrangler, bool copy_groups=true)
NOTE: The copying of groups only works if src is in the same detail.
Definition: GEO_Primitive.h:78
static GA_IntrinsicManager::Registrar registerIntrinsics(GA_PrimitiveDefinition &defn)
unsigned int uint
Definition: SYS_Types.h:45
virtual void isolate()
Method to isolate a pasted surface.
GLfloat GLfloat v1
Definition: glew.h:1852
GLintptr offset
Definition: glew.h:1682