HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
GEO_PrimPoly.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: polygon definition
9  *
10  */
11 
12 #pragma once
13 
14 #ifndef __GEO_PrimPoly_H__
15 #define __GEO_PrimPoly_H__
16 
17 #include "GEO_API.h"
18 #include "GEO_Face.h"
19 #include "GEO_PrimType.h"
20 #include <iosfwd>
21 
22 class GEO_Detail;
24 
26 {
27 protected:
28 public:
29  /// NOTE: The constructor should only be called from subclass
30  /// constructors.
33  : GEO_Face(d, offset)
34  {}
35 
36  /// This constructor is for making a representation of a polygon
37  /// on the stack, so that you can call GU_PrimPoly functions on
38  /// the polygon without needing the detail to allocate one.
41  : GEO_Face(gdp, offset)
42  { myVertexList = vertex_list; }
43 
44  virtual const GA_PrimitiveDefinition &getTypeDef() const
45  {
46  UT_ASSERT_P(theDefinition);
47  return *theDefinition;
48  }
49 
50  /// Report approximate memory usage.
51  virtual int64 getMemoryUsage() const;
52 
53  /// Count memory usage using a UT_MemoryCounter in order to count
54  /// shared memory correctly.
55  /// NOTE: This should always include sizeof(*this).
56  virtual void countMemory(UT_MemoryCounter &counter) const;
57 
58  // Assuming the poly is closed, "unroll" it so that the CVs that are
59  // shared to form a wrapped poly are made unique. Also, the poly becomes
60  // open. The base class method only flips the open flag. If the poly is
61  // not closed, the method returns -1. Otherwise it returns 0.
62  virtual int unroll(int append_pts = 1);
63 
64  // Raise the number of CVs to match the newcount. The shape of the poly
65  // (especially if parametric) should NOT change. Return 0 upon success
66  // and -1 otherwise. start and stop define which indices to examine
67  // if newcount is negative it is taken as a relative value.
68  virtual int loft(int newcount, int start=-1, int stop=-1);
69 
70  // Warp the poly at u by the given delta. The bias makes sense
71  // only when changing 2 CVs, and will be ignored altogether if < 0.
72  // We return the index of the affected CV in the sequence, or -1 if
73  // there's an error.
74  virtual int warp(float u, const UT_Vector3 &delta,
75  GA_AttributeRefMap &map,
76  float sharpness = 0.0f, float bias = -1.0f);
77 
78  // Compute the location of the breakpoint. Return 0 if OK, else -1.
79  virtual int evaluateBreakpoint(int uidx, UT_Vector4 &pos,
80  int du=0) const;
81 
82  virtual void computeInteriorPointWeights(
83  UT_Array<GA_Offset> &vtxlist,
84  UT_FloatArray &weightlist,
85  fpreal u, fpreal v, fpreal w) const final;
86 
87  // Append another face to us in one of two ways: blend the two endpoints
88  // or connect them straight. The bias ranges from 0 to 1 and is
89  // relevant only to blending. The tolerance is for blending: if 0, the two
90  // endpoints will merge into one point with a discontinuity; if less than
91  // 1, we insert points into the polys to minimize the affected areas; if 1,
92  // no refinement is done. We return 0 if OK and -1 if error.
93  // Both polys must be open.
94  virtual int attach(const GEO_Face &face, int blend = 1,
95  float bias = .5f, float tolerance = 1.f,
96  int=0, GA_PointGroup *ptgroup=0);
97 
98  // Build a planar (domain) face of the same type as us and with the same
99  // number of vertices. Copying the (x,y) values of our points to the planar
100  // face is optional.
101  virtual GD_Face *planar(GD_Detail &dgdp, int copyxy = 0) const;
102 
103  virtual unsigned getOrder() const;
104  virtual bool isDegenerate() const;
105  virtual int breakCount() const;
106 
107  // Map the normalized length (distance value [0,1]) parameter to the unit
108  // parameterization of the primitve. The tolerance specifies max
109  // error of the returned value (cannot be 0.0f)
110  virtual float unitLengthToUnitDomain(float ulength,
111  float tolerance = 1e-05F) const;
112  virtual float unitToUnitLengthDomain(float uparm) const;
113 
114  virtual const GA_PrimitiveJSON *getJSON() const;
115 
116  virtual void getAdjacentBoundaryVertices(GA_Offset vtx,
117  GA_Offset &prev_vtx,
118  GA_Offset &next_vtx) const;
119  virtual int deleteVertex(GA_Size num);
120  virtual GA_Size insertVertex(GA_Offset ptoff, GA_Size where=0);
121  virtual GA_Size appendVertex(GA_Offset ptoff);
122  virtual bool supportsHedge() const
123  { return true; }
124 
125  virtual GA_Size stealVertex(GA_Offset vtx, GA_Offset insert_before_vtx=GA_INVALID_OFFSET);
126 
127  /// Builds a GEO_PrimPoly with nvertices vertices, and
128  /// optionally adds a point to the detail for each vertex.
129  static GEO_PrimPoly *build(GA_Detail *gdp, GA_Size nvertices,
130  bool open=false,
131  bool appendpts=true);
132 
133  /// Builds npoints new points with the specified positions, and then
134  /// creates polygons that use those points, as dictated by polygonsizelist
135  /// and polygonpointnumbers, in parallel. polygonpointnumbers lists the
136  /// numbers of the points used by each polygon, relative to the first
137  /// point created by this method. The offset of the first polygon is
138  /// returned, and the rest are at consecutive offsets. All
139  /// polygonpointnumbers must be between 0 (inclusive) and
140  /// npoints (exclusive).
141  ///
142  /// NOTE: It's not strictly necessary that the polygons being created use
143  /// all of the points created.
144  /// @{
145  static GA_Offset buildBlock(GA_Detail *detail,
146  const UT_Vector3 *points,
147  const GA_Size npoints,
148  const GEO_PolyCounts &polygonsizelist,
149  const int *polygonpointnumbers,
150  const bool closed = true);
151  static GA_Offset buildBlock(GA_Detail *detail,
152  const UT_Vector3 *points,
153  const GA_Size npoints,
154  const GA_PolyCounts &polygonsizelist,
155  const int *polygonpointnumbers,
156  const bool closed = true);
157  /// @}
158 
159  /// Builds polygons using the specified range of point offsets,
160  /// as dictated by polygonsizelist and polygonpointnumbers, in parallel.
161  /// polygonpointnumbers lists the *offsets* of the points used by
162  /// each polygon *MINUS* startpt, i.e. they are offsets relative to startpt,
163  /// *not* indices relative to startpt. The offset of the first polygon is
164  /// returned, and the rest are at consecutive offsets. All
165  /// polygonpointnumbers must be between 0 (inclusive) and
166  /// npoints (exclusive).
167  ///
168  /// NOTE: Existing primitives *are* allowed to be using the points in
169  /// the specified range already, and the polygons being created do not
170  /// need to use all of the points in the range. However,
171  /// these cases may impact performance.
172  /// @{
174  GA_Detail *detail,
175  const GA_Offset startpt,
176  const GA_Size npoints,
177  const GEO_PolyCounts &polygonsizelist,
178  const int *polygonpointnumbers,
179  const bool closed = true)
180  {
181  return GEO_Face::buildBlock(
182  GA_PRIMPOLY,
183  detail,
184  startpt,
185  npoints,
186  polygonsizelist,
187  polygonpointnumbers,
188  closed);
189  }
191  GA_Detail *detail,
192  const GA_Offset startpt,
193  const GA_Size npoints,
194  const GA_PolyCounts &polygonsizelist,
195  const int *polygonpointnumbers,
196  const bool closed = true)
197  {
198  return GEO_Face::buildBlock(
199  GA_PRIMPOLY,
200  detail,
201  startpt,
202  npoints,
203  polygonsizelist,
204  polygonpointnumbers,
205  closed);
206  }
207  /// @}
208 
209  /// Flips a shared edge of two triangles
210  /// |
211  /// j+2 j+2 i+1 |
212  /// / \ /|\ |
213  /// / \ / | \ |
214  /// / that\ / t|t \ |
215  /// j-------j+1 flips to j h|h i |
216  /// i+1\ this/i \ a|i / |
217  /// \ / \t|s/ |
218  /// \ / \|/ |
219  /// i+2 j+1 i+2 |
220  ///
221  /// i and j are indices into this and that, respectively,
222  /// and are on opposite ends of the common edge,
223  /// which is (i, i+1) in this and (j, j+1) in the
224  /// opposite direction in that.
225  /// The vertex i+1 in this is moved to where j+2 is in that.
226  /// The vertex j+1 in that is moved to where i+2 is in this.
227  /// NOTE: Vertex attributes will be copied from j+2 onto i+1,
228  /// and from i+2 onto j+1.
229  /// NOTE: The two triangles must be in the same detail.
230  void flipEdge(GEO_PrimPoly *that,
231  GA_Size i, GA_Size j,
232  GA_ElementWranglerCache &wranglers);
233 
234  /// Determine if the polygon is planar
235  bool isPlanar(float tolerance = 0.0001F) const;
236 
237  /// Determine if the polygon is convex
238  bool isConvex(float tolerance = 0.0001F) const;
239 
240 protected:
242  { return GEO_Face::buildFamilyMask(); }
243 
244  /// All subclasses should call this method to register the curve intrinsics.
245  /// @see GA_IntrinsicManager
248  { return GEO_Face::registerIntrinsics(defn); }
249 
250  // We don't need to save anything other than what's in a face
251  virtual bool savePrivateH9(std::ostream &, bool binary) const;
252  virtual bool loadPrivateH9(UT_IStream &);
253 
254  // Return the squared max distance between any two successive vertices
255  // and the index of the "left" vertex. If the polygon is closed we
256  // compare the 1st and last vertices as well and if their distance is the
257  // largest, we return the index of the last vertex.
258  int findMaxDistance(float &maxdist2,
259  int start, int stop) const;
260  // Evaluates the position at domain point (u,v) in the interior of the
261  // geometry, rather than on the perimeter of the poly.
262  // (Note that u, v don't have to be converted to unit domain. We assume
263  // that the barycentric coords or bilinear interpolants are already
264  // correctly scaled).
265  virtual bool evaluateInteriorPointRefMap(GA_Offset result_vtx,
266  GA_AttributeRefMap &hlist,
267  fpreal u, fpreal v, fpreal w = 0) const;
268  virtual int evaluateInteriorPointV4(UT_Vector4 &pos,
269  fpreal u, fpreal v, fpreal w = 0) const;
270 
271  GA_Offset nextBoundaryVertex(unsigned int i) const
272  { return (i < getFastVertexCount() - 1) ? getFastVertexOffset(i+1) :
274  GA_Offset prevBoundaryVertex(unsigned int i) const
275  { return i > 0 ? getFastVertexOffset(i - 1) :
277 
278 
279  // The following are just stubs, so that a GEO_PrimPoly can be made
280  // on the stack. You can't all any of these functions unless they
281  // get moved to GEO_PrimPoly!
282 
284  GA_PointGroup *usedpts = 0)
285  {
286  UT_ASSERT_MSG(0, "Implemented in GU_PrimPoly! This is just a stub so that GEO_PrimPoly is not abstract!");
287  return nullptr;
288  }
289 
291  {
292  UT_ASSERT_MSG(0, "Implemented in GU_PrimPoly! This is just a stub so that GEO_PrimPoly is not abstract!");
293  return nullptr;
294  }
295 
296  virtual int intersectRay(const UT_Vector3 &o, const UT_Vector3 &d,
297  float tmax = 1E17F, float tol = 1E-12F,
298  float *distance = 0, UT_Vector3 *pos = 0,
299  UT_Vector3 *nml = 0, int accurate = 0,
300  float *u = 0, float *v = 0,
301  int ignoretrim=1) const
302  {
303  UT_ASSERT_MSG(0, "Implemented in GU_PrimPoly! This is just a stub so that GEO_PrimPoly is not abstract!");
304  return 0;
305  }
306 
307  virtual int intersect(const GEO_Primitive &prim,
308  UT_Array<GU_RayInfoHit> &hitList,
309  float tol = 0.01F, int ignoretrim=1) const
310  {
311  UT_ASSERT_MSG(0, "Implemented in GU_PrimPoly! This is just a stub so that GEO_PrimPoly is not abstract!");
312  return 0;
313  }
314 
315  virtual void clip(UT_Vector3 normal, float distance=0,
316  GA_PrimitiveGroup *clipgrp = NULL)
317  { UT_ASSERT_MSG(0, "Implemented in GU_PrimPoly! This is just a stub so that GEO_PrimPoly is not abstract!"); }
318 
319 
320 private:
321  friend std::ostream &operator<<(std::ostream &os, const GEO_PrimPoly &d)
322  {
323  d.saveH9(os, 0,
326  return os;
327  }
328 
329  static GA_PrimitiveDefinition *theDefinition;
330  friend class GU_PrimitiveFactory;
331 };
332 #endif
static GA_IntrinsicManager::Registrar registerIntrinsics(GA_PrimitiveDefinition &defn)
Definition: GEO_TriMesh.h:256
virtual int breakCount() const =0
SYS_FORCE_INLINE GEO_PrimPoly(GA_Detail *gdp, GA_Offset offset, const GA_OffsetListRef &vertex_list)
Definition: GEO_PrimPoly.h:40
virtual void clip(UT_Vector3 normal, float distance=0, GA_PrimitiveGroup *clipgrp=NULL)
Definition: GEO_PrimPoly.h:315
static GA_Offset buildBlock(GA_Detail *detail, const GA_Offset startpt, const GA_Size npoints, const GEO_PolyCounts &polygonsizelist, const int *polygonpointnumbers, const bool closed=true)
Definition: GEO_PrimPoly.h:173
SYS_FORCE_INLINE GEO_PrimPoly(GA_Detail *d, GA_Offset offset=GA_INVALID_OFFSET)
Definition: GEO_PrimPoly.h:32
void computeInteriorPointWeights(UT_Array< GA_Offset > &vtxlist, UT_FloatArray &weightlist, fpreal u, fpreal v, fpreal w) const override
const GLdouble * v
Definition: glcorearb.h:836
GLuint start
Definition: glcorearb.h:474
const GLuint GLenum const void * binary
Definition: glcorearb.h:1923
GA_Offset prevBoundaryVertex(unsigned int i) const
Definition: GEO_PrimPoly.h:274
virtual GA_Size stealVertex(GA_Offset vtx, GA_Offset insert_before_vtx=GA_INVALID_OFFSET)
bool loadPrivateH9(UT_IStream &is) override=0
3D Vector class.
virtual int loft(int newcount, int start=-1, int stop=-1)=0
virtual int64 getMemoryUsage() const
Definition: GA_Primitive.h:204
SYS_FORCE_INLINE bool isClosed() const
Definition: GEO_Face.h:242
virtual int warp(float u, const UT_Vector3 &delta, GA_AttributeRefMap &map, float sharpness=0.0f, float bias=-1.0f)=0
png_uint_32 i
Definition: png.h:2877
exint GA_Size
Defines the bit width for index and offset types in GA.
Definition: GA_Types.h:211
virtual float unitLengthToUnitDomain(float ulength, float tolerance=1e-04F) const
GA_PrimitiveFamilyMask
#define GA_INVALID_OFFSET
Definition: GA_Types.h:654
#define UT_ASSERT_P(ZZ)
Definition: UT_Assert.h:101
SYS_FORCE_INLINE GA_Offset getFastVertexOffset(GA_Size index) const
Definition: GEO_TriMesh.h:155
GA_Size GA_Offset
Definition: GA_Types.h:617
long long int64
Definition: SYS_Types.h:106
virtual int intersect(const GEO_Primitive &prim, UT_Array< GU_RayInfoHit > &hitList, float tol=0.01F, int ignoretrim=1) const
Definition: GEO_PrimPoly.h:307
GLfloat f
Definition: glcorearb.h:1925
static GA_Offset buildBlock(GA_Detail *detail, const GA_Offset startpt, const GA_Size npoints, const GA_PolyCounts &polygonsizelist, const int *polygonpointnumbers, const bool closed=true)
Definition: GEO_PrimPoly.h:190
virtual int evaluateInteriorPointV4(UT_Vector4 &pos, fpreal u, fpreal v, fpreal w=0) const
T distance(const UT_Vector4T< T > &v1, const UT_Vector4T< T > &v2)
Definition: UT_Vector4.h:634
virtual GA_Size appendVertex(GA_Offset ppt)
virtual void countMemory(UT_MemoryCounter &counter) const
virtual int attach(const GEO_Face &face, int blend=1, float bias=0.5f, float tolerance=1.0f, int unrefine=1, GA_PointGroup *ptgroup=0)=0
virtual GD_Face * planar(GD_Detail &dgdp, int copyxy=0) const =0
#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.
#define GEO_API
Definition: GEO_API.h:10
virtual unsigned getOrder(void) const =0
A handle to simplify manipulation of multiple attributes.
virtual const GA_PrimitiveDefinition & getTypeDef() const
Definition: GEO_PrimPoly.h:44
static GA_IntrinsicManager::Registrar registerIntrinsics(GA_PrimitiveDefinition &defn)
Definition: GEO_PrimPoly.h:247
virtual int open(float queuesize)
static GA_PrimitiveFamilyMask buildFamilyMask()
Definition: GEO_PrimPoly.h:241
virtual bool evaluateInteriorPointRefMap(GA_Offset result_vtx, GA_AttributeRefMap &map, fpreal u, fpreal v, fpreal w=0) const
friend std::ostream & operator<<(std::ostream &os, const GEO_PrimPoly &d)
Definition: GEO_PrimPoly.h:321
double fpreal
Definition: SYS_Types.h:269
virtual void getAdjacentBoundaryVertices(GA_Offset vtx, GA_Offset &prev_vtx, GA_Offset &next_vtx) const
Definition: GA_Primitive.h:610
static const UT_Array< GA_AttribSaveDataH9 > & theEmptySaveAttribs
Convience objects to pass as arguments to saveH9()/loadH9().
virtual bool supportsHedge() const
Definition: GEO_PrimPoly.h:122
GA_Offset nextBoundaryVertex(unsigned int i) const
Definition: GEO_PrimPoly.h:271
bool savePrivateH9(std::ostream &os, bool binary) const override=0
static GA_PrimitiveFamilyMask buildFamilyMask()
Definition: GEO_Face.h:394
Container class for all geometry.
Definition: GA_Detail.h:96
png_infop png_uint_32 int num
Definition: png.h:2158
GLubyte GLubyte GLubyte GLubyte w
Definition: glcorearb.h:856
SYS_FORCE_INLINE GA_Size getFastVertexCount() const
Definition: GEO_TriMesh.h:145
virtual float unitToUnitLengthDomain(float uparm) const
virtual GA_Size insertVertex(GA_Offset ppt, GA_Size where=0)
Definition of a geometric primitive.
bool isDegenerate() const override
Is the primitive degenerate.
virtual int evaluateBreakpoint(int uidx, UT_Vector4 &pos, int du=0) const =0
virtual int intersectRay(const UT_Vector3 &o, const UT_Vector3 &d, float tmax=1E17F, float tol=1E-12F, float *distance=0, UT_Vector3 *pos=0, UT_Vector3 *nml=0, int accurate=0, float *u=0, float *v=0, int ignoretrim=1) const
Definition: GEO_PrimPoly.h:296
#define UT_ASSERT_MSG(ZZ, MM)
Definition: UT_Assert.h:105
virtual int deleteVertex(GA_Size num)
virtual GEO_Primitive * convertNew(GEO_ConvertParms &parms)
Definition: GEO_PrimPoly.h:290
virtual GEO_Primitive * convert(GEO_ConvertParms &parms, GA_PointGroup *usedpts=0)
Definition: GEO_PrimPoly.h:283
virtual int unroll(int append_pts=1)
bool saveH9(std::ostream &os, bool binary, const UT_Array< GA_AttribSaveDataH9 > &prim_attribs, const UT_Array< GA_AttribSaveDataH9 > &vtx_attribs) const override
static GA_Offset buildBlock(GA_PrimitiveTypeId type, GA_Detail *detail, const GA_Offset startpt, const GA_Size npoints, const GEO_PolyCounts &facesizelist, const int *facepointnumbers, const bool closed=true)