HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups 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  const GA_PrimitiveDefinition &getTypeDef() const override
45  {
46  UT_ASSERT_P(theDefinition);
47  return *theDefinition;
48  }
49 
50  /// Report approximate memory usage.
51  int64 getMemoryUsage() const override;
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  void countMemory(UT_MemoryCounter &counter) const override;
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  int unroll(int append_pts = 1) override;
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  int loft(int newcount, int start=-1, int stop=-1) override;
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  int warp(float u, const UT_Vector3 &delta,
75  GA_AttributeRefMap &map,
76  float sharpness = 0.0f,
77  float bias = -1.0f) override;
78 
79  // Compute the location of the breakpoint. Return 0 if OK, else -1.
80  int evaluateBreakpoint(int uidx, UT_Vector4 &pos,
81  int du=0) const override;
82 
84  UT_Array<GA_Offset> &vtxlist,
85  UT_Array<float> &weightlist,
86  fpreal u, fpreal v, fpreal w) const override final;
87 
88  // Append another face to us in one of two ways: blend the two endpoints
89  // or connect them straight. The bias ranges from 0 to 1 and is
90  // relevant only to blending. The tolerance is for blending: if 0, the two
91  // endpoints will merge into one point with a discontinuity; if less than
92  // 1, we insert points into the polys to minimize the affected areas; if 1,
93  // no refinement is done. We return 0 if OK and -1 if error.
94  // Both polys must be open.
95  int attach(const GEO_Face &face, int blend = 1,
96  float bias = .5f, float tolerance = 1.f,
97  int=0, GA_PointGroup *ptgroup=0) override;
98 
99  // Build a planar (domain) face of the same type as us and with the same
100  // number of vertices. Copying the (x,y) values of our points to the planar
101  // face is optional.
102  GD_Face *planar(GD_Detail &dgdp, int copyxy = 0) const override;
103 
104  unsigned getOrder() const override;
105  bool isDegenerate() const override;
106  int breakCount() const override;
107 
108  // Map the normalized length (distance value [0,1]) parameter to the unit
109  // parameterization of the primitve. The tolerance specifies max
110  // error of the returned value (cannot be 0.0f)
112  float ulength,
113  float tolerance = 1e-05F) const override;
114  float unitToUnitLengthDomain(float uparm) const override;
115 
116  const GA_PrimitiveJSON *getJSON() const override;
117 
119  GA_Offset vtx,
120  GA_Offset &prev_vtx,
121  GA_Offset &next_vtx) const override;
122  int deleteVertex(GA_Size num) override;
123  GA_Size insertVertex(GA_Offset ptoff, GA_Size where=0) override;
124  GA_Size appendVertex(GA_Offset ptoff) override;
125  bool supportsHedge() const override
126  { return true; }
127 
129  GA_Offset vtx,
130  GA_Offset insert_before_vtx=GA_INVALID_OFFSET
131  ) override;
132 
133  /// Builds a GEO_PrimPoly with nvertices vertices, and
134  /// optionally adds a point to the detail for each vertex.
135  static GEO_PrimPoly *build(GA_Detail *gdp, GA_Size nvertices,
136  bool open=false,
137  bool appendpts=true);
138 
139  /// Builds npoints new points with the specified positions, and then
140  /// creates polygons that use those points, as dictated by polygonsizelist
141  /// and polygonpointnumbers, in parallel. polygonpointnumbers lists the
142  /// numbers of the points used by each polygon, relative to the first
143  /// point created by this method. The offset of the first polygon is
144  /// returned, and the rest are at consecutive offsets. All
145  /// polygonpointnumbers must be between 0 (inclusive) and
146  /// npoints (exclusive).
147  ///
148  /// NOTE: It's not strictly necessary that the polygons being created use
149  /// all of the points created.
150  /// @{
151  static GA_Offset buildBlock(GA_Detail *detail,
152  const UT_Vector3 *points,
153  const GA_Size npoints,
154  const GEO_PolyCounts &polygonsizelist,
155  const int *polygonpointnumbers,
156  const bool closed = true);
157  static GA_Offset buildBlock(GA_Detail *detail,
158  const UT_Vector3 *points,
159  const GA_Size npoints,
160  const GA_PolyCounts &polygonsizelist,
161  const int *polygonpointnumbers,
162  const bool closed = true);
163  /// @}
164 
165  /// Builds polygons using the specified range of point offsets,
166  /// as dictated by polygonsizelist and polygonpointnumbers, in parallel.
167  /// polygonpointnumbers lists the *offsets* of the points used by
168  /// each polygon *MINUS* startpt, i.e. they are offsets relative to startpt,
169  /// *not* indices relative to startpt. The offset of the first polygon is
170  /// returned, and the rest are at consecutive offsets. All
171  /// polygonpointnumbers must be between 0 (inclusive) and
172  /// npoints (exclusive).
173  ///
174  /// NOTE: Existing primitives *are* allowed to be using the points in
175  /// the specified range already, and the polygons being created do not
176  /// need to use all of the points in the range. However,
177  /// these cases may impact performance.
178  /// @{
180  GA_Detail *detail,
181  const GA_Offset startpt,
182  const GA_Size npoints,
183  const GEO_PolyCounts &polygonsizelist,
184  const int *polygonpointnumbers,
185  const bool closed = true)
186  {
187  return GEO_Face::buildBlock(
188  GA_PRIMPOLY,
189  detail,
190  startpt,
191  npoints,
192  polygonsizelist,
193  polygonpointnumbers,
194  closed);
195  }
197  GA_Detail *detail,
198  const GA_Offset startpt,
199  const GA_Size npoints,
200  const GA_PolyCounts &polygonsizelist,
201  const int *polygonpointnumbers,
202  const bool closed = true)
203  {
204  return GEO_Face::buildBlock(
205  GA_PRIMPOLY,
206  detail,
207  startpt,
208  npoints,
209  polygonsizelist,
210  polygonpointnumbers,
211  closed);
212  }
213  /// @}
214 
215  /// Flips a shared edge of two triangles
216  /// |
217  /// j+2 j+2 i+1 |
218  /// / \ /|\ |
219  /// / \ / | \ |
220  /// / that\ / t|t \ |
221  /// j-------j+1 flips to j h|h i |
222  /// i+1\ this/i \ a|i / |
223  /// \ / \t|s/ |
224  /// \ / \|/ |
225  /// i+2 j+1 i+2 |
226  ///
227  /// i and j are indices into this and that, respectively,
228  /// and are on opposite ends of the common edge,
229  /// which is (i, i+1) in this and (j, j+1) in the
230  /// opposite direction in that.
231  /// The vertex i+1 in this is moved to where j+2 is in that.
232  /// The vertex j+1 in that is moved to where i+2 is in this.
233  /// NOTE: Vertex attributes will be copied from j+2 onto i+1,
234  /// and from i+2 onto j+1.
235  /// NOTE: The two triangles must be in the same detail.
236  void flipEdge(GEO_PrimPoly *that,
237  GA_Size i, GA_Size j,
238  GA_ElementWranglerCache &wranglers);
239 
240  /// Determine if the polygon is planar
241  bool isPlanar(float tolerance = 0.0001F) const;
242 
243  /// Determine if the polygon is convex
244  bool isConvex(float tolerance = 0.0001F) const;
245 
246 protected:
248  { return GEO_Face::buildFamilyMask(); }
249 
250  /// All subclasses should call this method to register the curve intrinsics.
251  /// @see GA_IntrinsicManager
254  { return GEO_Face::registerIntrinsics(defn); }
255 
256  // We don't need to save anything other than what's in a face
257  bool savePrivateH9(std::ostream &, bool binary) const override;
258  bool loadPrivateH9(UT_IStream &) override;
259 
260  // Return the squared max distance between any two successive vertices
261  // and the index of the "left" vertex. If the polygon is closed we
262  // compare the 1st and last vertices as well and if their distance is the
263  // largest, we return the index of the last vertex.
264  int findMaxDistance(float &maxdist2,
265  int start, int stop) const;
266  // Evaluates the position at domain point (u,v) in the interior of the
267  // geometry, rather than on the perimeter of the poly.
268  // (Note that u, v don't have to be converted to unit domain. We assume
269  // that the barycentric coords or bilinear interpolants are already
270  // correctly scaled).
272  GA_Offset result_vtx,
273  GA_AttributeRefMap &hlist,
274  fpreal u, fpreal v, fpreal w=0) const override;
276  UT_Vector4 &pos,
277  fpreal u, fpreal v, fpreal w=0) const override;
278 
279  GA_Offset nextBoundaryVertex(unsigned int i) const
280  { return (i < getFastVertexCount() - 1) ? getFastVertexOffset(i+1) :
282  GA_Offset prevBoundaryVertex(unsigned int i) const
283  { return i > 0 ? getFastVertexOffset(i - 1) :
285 
286 
287  // The following are just stubs, so that a GEO_PrimPoly can be made
288  // on the stack. You can't all any of these functions unless they
289  // get moved to GEO_PrimPoly!
290 
292  GA_PointGroup *usedpts = 0) override
293  {
294  UT_ASSERT_MSG(0, "Implemented in GU_PrimPoly! This is just a stub so that GEO_PrimPoly is not abstract!");
295  return nullptr;
296  }
297 
299  {
300  UT_ASSERT_MSG(0, "Implemented in GU_PrimPoly! This is just a stub so that GEO_PrimPoly is not abstract!");
301  return nullptr;
302  }
303 
304  int intersectRay(const UT_Vector3 &o, const UT_Vector3 &d,
305  float tmax = 1E17F, float tol = 1E-12F,
306  float *distance = 0, UT_Vector3 *pos = 0,
307  UT_Vector3 *nml = 0, int accurate = 0,
308  float *u = 0, float *v = 0,
309  int ignoretrim=1) const override
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  int intersect(const GEO_Primitive &prim,
316  UT_Array<GU_RayInfoHit> &hit_list,
317  float tol = 0.01F, int ignoretrim=1) const override
318  {
319  UT_ASSERT_MSG(0, "Implemented in GU_PrimPoly! This is just a stub so that GEO_PrimPoly is not abstract!");
320  return 0;
321  }
322 
323  void clip(UT_Vector3 normal, float distance=0,
324  GA_PrimitiveGroup *clipgrp = NULL) override
325  { UT_ASSERT_MSG(0, "Implemented in GU_PrimPoly! This is just a stub so that GEO_PrimPoly is not abstract!"); }
326 
327 
328 private:
329  friend std::ostream &operator<<(std::ostream &os, const GEO_PrimPoly &d)
330  {
331  d.saveH9(os, 0,
334  return os;
335  }
336 
337  static GA_PrimitiveDefinition *theDefinition;
338  friend class GU_PrimitiveFactory;
339 };
340 #endif
static GA_IntrinsicManager::Registrar registerIntrinsics(GA_PrimitiveDefinition &defn)
Definition: GEO_TriMesh.h:193
virtual int breakCount() const =0
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 override
Definition: GEO_PrimPoly.h:304
SYS_FORCE_INLINE GEO_PrimPoly(GA_Detail *gdp, GA_Offset offset, const GA_OffsetListRef &vertex_list)
Definition: GEO_PrimPoly.h:40
GLdouble GLdouble GLint GLint const GLdouble * points
Definition: glad.h:2676
const GA_PrimitiveDefinition & getTypeDef() const override
Definition: GEO_PrimPoly.h:44
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:179
SYS_FORCE_INLINE GEO_PrimPoly(GA_Detail *d, GA_Offset offset=GA_INVALID_OFFSET)
Definition: GEO_PrimPoly.h:32
const GLdouble * v
Definition: glcorearb.h:837
GLuint start
Definition: glcorearb.h:475
const GLuint GLenum const void * binary
Definition: glcorearb.h:1924
int intersect(const GEO_Primitive &prim, UT_Array< GU_RayInfoHit > &hit_list, float tol=0.01F, int ignoretrim=1) const override
Definition: GEO_PrimPoly.h:315
GA_Offset prevBoundaryVertex(unsigned int i) const
Definition: GEO_PrimPoly.h:282
virtual GA_Size stealVertex(GA_Offset vtx, GA_Offset insert_before_vtx=GA_INVALID_OFFSET)
bool loadPrivateH9(UT_IStream &is) override=0
virtual int loft(int newcount, int start=-1, int stop=-1)=0
virtual int64 getMemoryUsage() const
Definition: GA_Primitive.h:209
SYS_FORCE_INLINE bool isClosed() const
Definition: GEO_Face.h:248
virtual int warp(float u, const UT_Vector3 &delta, GA_AttributeRefMap &map, float sharpness=0.0f, float bias=-1.0f)=0
exint GA_Size
Defines the bit width for index and offset types in GA.
Definition: GA_Types.h:235
virtual float unitLengthToUnitDomain(float ulength, float tolerance=1e-04F) const
GA_PrimitiveFamilyMask
#define GA_INVALID_OFFSET
Definition: GA_Types.h:678
SYS_FORCE_INLINE GA_Offset getFastVertexOffset(GA_Size index) const
Definition: GEO_TriMesh.h:126
#define UT_ASSERT_MSG(ZZ,...)
Definition: UT_Assert.h:159
GA_Size GA_Offset
Definition: GA_Types.h:641
vint4 blend(const vint4 &a, const vint4 &b, const vbool4 &mask)
Definition: simd.h:4784
GLfloat f
Definition: glcorearb.h:1926
GLintptr offset
Definition: glcorearb.h:665
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:196
virtual int evaluateInteriorPointV4(UT_Vector4 &pos, fpreal u, fpreal v, fpreal w=0) const
int open(float queuesize) override
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
#define UT_ASSERT_P(ZZ)
Definition: UT_Assert.h:155
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
Provide a JSON interface to a primitive.
#define GEO_API
Definition: GEO_API.h:14
bool supportsHedge() const override
Definition: GEO_PrimPoly.h:125
long long int64
Definition: SYS_Types.h:116
A handle to simplify manipulation of multiple attributes.
static GA_IntrinsicManager::Registrar registerIntrinsics(GA_PrimitiveDefinition &defn)
Definition: GEO_PrimPoly.h:253
GEO_Primitive * convertNew(GEO_ConvertParms &parms) override
Definition: GEO_PrimPoly.h:298
void clip(UT_Vector3 normal, float distance=0, GA_PrimitiveGroup *clipgrp=NULL) override
Definition: GEO_PrimPoly.h:323
static GA_PrimitiveFamilyMask buildFamilyMask()
Definition: GEO_PrimPoly.h:247
virtual bool evaluateInteriorPointRefMap(GA_Offset result_vtx, GA_AttributeRefMap &map, fpreal u, fpreal v, fpreal w=0) const
GLint j
Definition: glad.h:2733
friend std::ostream & operator<<(std::ostream &os, const GEO_PrimPoly &d)
Definition: GEO_PrimPoly.h:329
virtual unsigned getOrder() const =0
virtual void getAdjacentBoundaryVertices(GA_Offset vtx, GA_Offset &prev_vtx, GA_Offset &next_vtx) const
Definition: GA_Primitive.h:694
static const UT_Array< GA_AttribSaveDataH9 > & theEmptySaveAttribs
Convience objects to pass as arguments to saveH9()/loadH9().
fpreal64 fpreal
Definition: SYS_Types.h:277
GA_Offset nextBoundaryVertex(unsigned int i) const
Definition: GEO_PrimPoly.h:279
bool savePrivateH9(std::ostream &os, bool binary) const override=0
static GA_PrimitiveFamilyMask buildFamilyMask()
Definition: GEO_Face.h:409
Container class for all geometry.
Definition: GA_Detail.h:96
GEO_Primitive * convert(GEO_ConvertParms &parms, GA_PointGroup *usedpts=0) override
Definition: GEO_PrimPoly.h:291
GLubyte GLubyte GLubyte GLubyte w
Definition: glcorearb.h:857
SYS_FORCE_INLINE GA_Size getFastVertexCount() const
Definition: GEO_TriMesh.h:123
virtual float unitToUnitLengthDomain(float uparm) const
virtual GA_Size insertVertex(GA_Offset ppt, GA_Size where=0)
Definition of a geometric primitive.
SIM_API const UT_StringHolder distance
bool isDegenerate() const override
Is the primitive degenerate.
virtual int evaluateBreakpoint(int uidx, UT_Vector4 &pos, int du=0) const =0
virtual int deleteVertex(GA_Size num)
void computeInteriorPointWeights(UT_Array< GA_Offset > &vtxlist, UT_Array< float > &weightlist, fpreal u, fpreal v, fpreal w) const override
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)