HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
GEO_Hull.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  * This class is used as a base class for all patch types supported.
10  * The vertex list management is handled by this class, however, all
11  * other function should be handled by the subclass.
12  * The insertRow and insertCol are meant to be virtual since it
13  * may be possible for the patch type to insert a row or column
14  * without distorting the shape of the patch (as in NURBs or MESH)
15  *
16  */
17 
18 #pragma once
19 
20 #ifndef __GEO_Hull_H__
21 #define __GEO_Hull_H__
22 
23 #include "GEO_API.h"
24 #include "GEO_Primitive.h"
25 #include "GEO_SurfaceType.h"
26 #include "GEO_Vertex.h"
27 #include <GA/GA_OffsetMatrix.h>
28 #include <UT/UT_Assert.h>
29 #include <UT/UT_RefMatrix.h>
30 #include <UT/UT_Vector3.h>
31 #include <iosfwd>
32 
33 class UT_BitArray;
34 class GA_Detail;
35 class GA_EdgeGroup;
36 class UT_JSONWriter;
37 class UT_JSONParser;
38 class GA_SaveMap;
39 class GA_LoadMap;
40 
41 template<typename T, bool B> class GA_EdgeT;
43 
45 {
46 public:
48  {
49  wrapu = 0;
50  wrapv = 0;
51  }
52  bool wrapu:1;
53  bool wrapv:1;
54  bool loadBinary( UT_IStream &is );
55  int saveBinary( std::ostream &os ) const;
56 };
57 
59 {
60 public:
62  {
63  wrapu = 0; wrapv = 0;
64  dupTop = 0; dupLeft = 0;
65  dupBottom = 0; dupRight = 0;
66  breakThread = 0; breakBridge = 0;
67  recurse = 1;
68  }
69 
70  unsigned wrapu:1,
71  wrapv:1,
72  dupTop:1,
73  dupLeft:1,
74  dupBottom:1,
75  dupRight:1,
76  breakThread:1,
77  breakBridge:1,
78  recurse:1;
79 };
80 
82 {
83 public:
84  GEO_SubHullPart() { h_edge = v_edge = d_edge = flags = 0; }
85 
86  int h_edge;
87  int v_edge;
88  int d_edge;
89  int flags;
90  // `flags' is used as follows:
91  // Bit 0 - horizontal edge is used to break into a subhull
92  // Bit 1 - vertical edge " "
93  // Bit 2 - diagonal edge " "
94 
95  bool operator==(const GEO_SubHullPart &p) const
96  { return( (h_edge==p.h_edge) &&
97  (v_edge==p.v_edge) &&
98  (d_edge==p.d_edge) &&
99  (flags ==p.flags ) );
100  }
101  bool operator!=(const GEO_SubHullPart &p) const
102  { return !(*this == p); }
103 };
104 
106 {
107 public:
108  GEO_SubHull() : mat() {}
109 
111  int v_rows, v_cols;
112  int h_rows, h_cols;
113  int d_rows, d_cols;
114 };
115 
117 {
118 protected:
119  /// NOTE: The constructor should only be called from subclass
120  /// constructors.
122  : GEO_Primitive(d, offset)
124  , myRows(0)
125  , myCols(0)
126 #endif
127  {}
128 
129 #if !GA_PRIMITIVE_VERTEXLIST
130  /// NOTE: The destructor should only be called from subclass
131  /// destructors.
132  virtual ~GEO_Hull();
133 #endif
134 
135 public:
136  bool saveVertexArray(UT_JSONWriter &w,
137  const GA_SaveMap &save) const;
138  bool loadVertexArray(UT_JSONParser &p,
139  const GA_LoadMap &load);
140 
141  // Compute the location of the breakpoint. Return 0 if OK, else -1.
142  virtual int evaluateBreakpoint(int uidx, int vidx,
143  UT_Vector4 &pos,
144  int du=0, int dv=0) const = 0;
145 
146  // Evaluate one point (when du=dv=0), or the du-th dv-th derivative.
147  // Returns true if successful, and false otherwise.
148  bool evaluateIndex(fpreal u, fpreal v, GA_Offset result_vtx,
149  GA_AttributeRefMap &hlist,
150  unsigned du, unsigned dv) const
151  { return evaluateIndexRefMap(u, v, result_vtx, hlist, du, dv); }
152  int evaluateIndex(float iu, float iv, UT_Vector4 &pos,
153  unsigned du=0, unsigned dv=0) const
154  { return evaluateIndexV4(iu, iv, pos, du, dv); }
155 
157  UT_Array<GA_Offset> &vtxlist, UT_FloatArray &weightlist,
158  fpreal u, fpreal v, fpreal w) const override;
159 
160  void normal(NormalComp &output) const override;
161 
162  // Evaluate the normal using unit u and v coordinates (i.e. in [0,1]).
163  // The normal is not normalized. The method does NOT fail if the point
164  // attribute is missing. We return 0 if OK and -1 if error.
165  int evaluateNormalVector(UT_Vector3 &nml, float u,
166  float v = 0, float w = 0) const override;
167 
168  // Evaluate the normal at real (u,v). The method does not fail if there
169  // is no point attribute, it instead just returns the face normal.
170  // Return 0 if successful, and -1 otherwise.
171  virtual int evaluateNormal(float u,float v, UT_Vector3 &nml) const;
172  virtual int normalIndex(float iu, float iv, UT_Vector3 &nml) const;
173 
174  virtual int uMinValidIndex() const;
175  virtual int uMaxValidIndex() const;
176  virtual int vMinValidIndex() const;
177  virtual int vMaxValidIndex() const;
178 
179  bool saveH9(std::ostream &os, bool binary,
180  const UT_Array<GA_AttribSaveDataH9> &prim_attribs,
181  const UT_Array<GA_AttribSaveDataH9> &vtx_attribs) const override;
182  bool loadH9(UT_IStream &is,
183  const UT_Array<GA_AttribLoadDataH9> &prim_attribs,
184  const UT_Array<GA_AttribLoadDataH9> &vtx_attribs) override;
185  int getBBox(UT_BoundingBox *bbox) const override;
186  void addToBSphere(UT_BoundingSphere *bsphere) const override;
187  UT_Vector3 baryCenter() const override;
188  UT_Vector3 computeNormal() const override;
189  void copyPrimitive(const GEO_Primitive *src) override;
190  GEO_Primitive *copy(int preserve_shared_pts = 0) const override;
191 
193  const GA_MergeMap &map) override;
194 
195 #if !GA_PRIMITIVE_VERTEXLIST
196  void addPointRefToGroup(GA_PointGroup &grp) const override;
197 #endif
198 
199  // Reverse rows (V) and/or columns (U):
200  void reverse () override;
201  virtual void reverseU();
202  virtual void reverseV();
203 
204  // Shift the array of vertices by an offset and wrap around. The offset
205  // can be either negative or positive. Cycles in complete rows/cols
206  virtual int cycleU(int amount, int = 1);
207  virtual int cycleV(int amount, int = 1);
208 
209  // All current rows and columns will be reinitialized
210  int setRowCol(int r, int c);
211  virtual int insertRow(unsigned int beforeWhich, bool appendPts=true);
212  int appendRow(bool appendPts=true)
213  {
214 #if GA_PRIMITIVE_VERTEXLIST
215  return insertRow(myRows, appendPts);
216 #else
217  return insertRow(myVertexMatx.getRows(), appendPts);
218 #endif
219  }
220  virtual int insertCol(unsigned int beforeWhich, bool appendPts=true);
221  int appendCol(bool appendPts=true)
222  {
223 #if GA_PRIMITIVE_VERTEXLIST
224  return insertCol(myCols, appendPts);
225 #else
226  return insertCol(myVertexMatx.getCols(), appendPts);
227 #endif
228  }
229 
230  virtual int deleteRow(unsigned int which);
231  virtual int deleteCol(unsigned int which);
232 
233  // Take the whole set of points into consideration when applying the
234  // point removal operation to this primitive. The method returns 0 if
235  // successful, -1 if it failed because it would have become degenerate,
236  // and -2 if it failed because it would have had to remove the primitive
237  // altogether.
238  int detachPoints (GA_PointGroup &grp) override;
239 
240  /// Before a point is deleted, all primitives using the point will be
241  /// notified. The method should return "false" if it's impossible to
242  /// delete the point. Otherwise, the vertices should be removed.
243  GA_DereferenceStatus dereferencePoint(
244  GA_Offset point, bool dry_run=false) override;
245  GA_DereferenceStatus dereferencePoints(
246  const GA_RangeMemberQuery &pt_q, bool dry_run=false) override;
247 
248  // Given a parameter in the domain, insert as many CVs as necessary to
249  // create a discontinuity at the corresponding point on the curve.The shape
250  // of the curve should NOT change. Return u's index upon success and -1
251  // otherwise.
252  int subdivideU(float u, GA_AttributeRefMap &map)
253  { return subdivideURefMap(u, map); }
254  int subdivideU(float u)
255  { return subdivideUFloat(u); }
256  int subdivideV(float u, GA_AttributeRefMap &map)
257  { return subdivideVRefMap(u, map); }
258  int subdivideV(float u)
259  { return subdivideVFloat(u); }
260 
261  virtual void subdivide(int numdivs, GA_PointGroup *ptgroup=0);
262 
263  // Warp the hull at u,v by the given delta. Change 1 or 4 Cvs and possibly
264  // insert a knot once or more as well. If a knot is inserted or we happen
265  // to land exactly on a knot, we change only one CV. The bias makes sense
266  // only when changing 4 CVs, and will be ignored altogether if < 0.
267  // We return the CV index in warpU/V and 0 in warp() if OK; -1 otherwise.
268  virtual int warpU(float u, const UT_Vector3 &delta,
269  GA_AttributeRefMap &map,
270  float sharpness = 0.0f, float bias = -1.0f) = 0;
271  virtual int warpV(float v, const UT_Vector3 &delta,
272  GA_AttributeRefMap &map,
273  float sharpness = 0.0f, float bias = -1.0f) = 0;
274  virtual int warp (float u, float v, const UT_Vector3 &delta,
275  GA_AttributeRefMap &map,
276  float usharpness = 0.0f, float vsharpness = 0.f,
277  float ubias = -1.0f, float vbias = -1.0f) = 0;
278 
279 
280  // Warp the hull along its normal at u,v. We warp u if the flag is 0,
281  // warp v if flag is 1, and warp both if flag is 2.
282  // We return 0 if OK, or -1 if there's an error.
283  int warpAlongNormal (float u, float v, float distance,
284  GA_AttributeRefMap &map,
285  float usharpness, float vsharpness,
286  float ubias, float vbias,
287  int u_v_both);
288 
289  // Append another hull to us in one of two ways: blend the two endpoints
290  // or connect them straight or rounded. The bias ranges from 0 to 1 and is
291  // relevant only to blending. The tolerance for blending: if 0, the two
292  // endpoints will merge into one point with a discontinuity; if less than
293  // 1, we insert knots into the hulls to minimize the affected areas; if 1,
294  // no refinement is done. For the non-blend case, the tolerance will
295  // generate a span whose shape goes from round to straight; 0 tolerance
296  // means straight connection. If unrefine is on, we'll try to reduce the
297  // complexity of the hull if we're connecting rounded. We return 0 if OK
298  // and -1 if error. Both hulls must be open and have the same order.
299  virtual int attachU(const GEO_Hull &hull, int blend = 1,
300  float bias = 0.5f, float tolerance = 1.0f,
301  int unrefine=1, GA_PointGroup *ptgroup=0) = 0;
302  virtual int attachV(const GEO_Hull &hull, int blend = 1,
303  float bias = 0.5f, float tolerance = 1.0f,
304  int unrefine=1, GA_PointGroup *ptgroup=0) = 0;
305 
306  // Change the multiplicity of the domain value by inserting it after
307  // checking its current multiplicity. Return -1 if invalid, otherwise
308  // return the index of the inserted knot
309 
310  virtual int refineU(float k,
311  GA_AttributeRefMap &hlist,
312  int i=1);
313 
314  virtual int refineU ( float k, int i=1);
315  virtual int refineV(float k,
316  GA_AttributeRefMap &hlist,
317  int i=1);
318  virtual int refineV ( float k, int i=1);
319 
320  // Refine numdivs times in each span.
322  int numdivs=1)
323  { spanRefineURefMap(map, numdivs); }
324  void spanRefineU( int numdivs=1)
325  { spanRefineUInt(numdivs); }
327  int numdivs=1)
328  { spanRefineVRefMap(map, numdivs); }
329  void spanRefineV( int numdivs=1)
330  { spanRefineVInt(numdivs); }
331 
332  // Remove rows and or columns based on a curvature tolerance. Return 1 of
333  // something was removed, else 0.
335  int mult=0, float tol=1e-4f,
336  GA_PointGroup *delgroup=0)
337  { return unrefineURefMap(kidx, h, mult,
338  tol, delgroup); }
339  int unrefineU(int kidx, int mult = 0,
340  float tol = 1e-4F,
341  GA_PointGroup *delgroup = 0)
342  { return unrefineUFloat(kidx, mult, tol,
343  delgroup); }
345  int mult=0, float tol=1e-4f,
346  GA_PointGroup *delgroup=0)
347  { return unrefineVRefMap(kidx, h, mult,
348  tol, delgroup); }
349  int unrefineV(int kidx, int mult = 0,
350  float tol = 1e-4F,
351  GA_PointGroup *delgroup = 0)
352  { return unrefineVFloat(kidx, mult, tol,
353  delgroup); }
354 
355  // If the hull is wrapped in U and/or V, explicitly add the wrapped vertex
356  // and open the hull in the direction(s) it's wrapped in.
357  virtual void fixSeamsU(void);
358  virtual void fixSeamsV(void);
359 
360  /// Apply row-column texture. If ptattrib is true, we deal with
361  /// points, else with vertices. Returns false iff problems.
362  bool rowColTexture(const GA_RWHandleV3 &txth, bool ptattrib);
363 
366 #if GA_PRIMITIVE_VERTEXLIST
367  { return myRows; }
368 #else
369  { return (int)myVertexMatx.getRows(); }
370 #endif
373 #if GA_PRIMITIVE_VERTEXLIST
374  { return myCols; }
375 #else
376  { return (int)myVertexMatx.getCols(); }
377 #endif
378 
379  // Subscript operators. The const version does not check the boundaries.
380  // For safer but slower use, call getVertex() and setVertex().
382  SYS_DEPRECATED_HDK(13.0)
383  const GEO_Vertex operator()(unsigned int r, unsigned int c) const
384  { return getVertexElement(r, c); }
385  SYS_DEPRECATED_HDK(13.0)
386  GEO_Vertex operator()(unsigned int r, unsigned int c)
387  { return getVertexElement(r, c); }
388 
390  SYS_DEPRECATED_HDK(13.0)
391  const GEO_Vertex getVertexElement(unsigned int r, unsigned int c) const;
392 
393 #if GA_PRIMITIVE_VERTEXLIST
395 #endif
396 
397  SYS_FORCE_INLINE GA_Offset getVertexOffset(unsigned int r, unsigned int c) const
398  {
399  UT_ASSERT_P(r < getNumRows() && c < getNumCols());
400  if (r >= getNumRows() || c >= getNumCols())
401  return GA_INVALID_OFFSET;
402 #if GA_PRIMITIVE_VERTEXLIST
403  return getVertexOffset(r*exint(myCols) + c);
404 #else
405  return myVertexMatx(r, c);
406 #endif
407  }
408  SYS_FORCE_INLINE GA_Index getVertexIndex(unsigned int r, unsigned int c) const
409  {
410  GA_Offset vtxoff = getVertexOffset(r, c);
411  return GAisValid(vtxoff) ? getDetail().vertexIndex(vtxoff)
413  }
414  SYS_FORCE_INLINE GA_Offset getPointOffset(unsigned int r, unsigned int c) const
415  {
416  if (r >= getNumRows() || c >= getNumCols())
417  {
418  UT_ASSERT(!"Invalid offset");
419  return GA_INVALID_OFFSET;
420  }
421 
422  return vertexPoint(r, c);
423  }
424  SYS_FORCE_INLINE GA_Index getPointIndex(unsigned int r, unsigned int c) const
425  {
426  GA_Offset ptoff = getPointOffset(r, c);
427  return GAisValid(ptoff) ? getDetail().pointIndex(ptoff)
429  }
430  SYS_FORCE_INLINE UT_Vector3 getPos3(unsigned int r, unsigned int c) const
431  { return getDetail().getPos3(getPointOffset(r, c)); }
432  SYS_FORCE_INLINE void setPos3(unsigned int r, unsigned int c, const UT_Vector3 &pos) const
433  { getDetail().setPos3(getPointOffset(r, c), pos); }
434  SYS_FORCE_INLINE UT_Vector4 getPos4(unsigned int r, unsigned int c) const
435  { return getDetail().getPos4(getPointOffset(r, c)); }
436  SYS_FORCE_INLINE void setPos4(unsigned int r, unsigned int c, const UT_Vector4 &pos) const
437  { getDetail().setPos4(getPointOffset(r, c), pos); }
438  SYS_FORCE_INLINE void setPointOffset(unsigned int r, unsigned int c, GA_Offset ptoff) const
440 
442  {
443  return exint(getNumRows()) * exint(getNumCols());
444  }
445  void setVertexPoint(unsigned int r, unsigned int c, GA_Offset pt)
446  {
447  if (r >= getNumRows() || c >= getNumCols())
448  return;
449 
450  setPointOffset(r, c, pt);
451  }
452 
453 #if !GA_PRIMITIVE_VERTEXLIST
454  void beginVertex(const_iterator &i) const override;
455  void nextVertex(const_iterator &i) const override;
456 #endif
457 
458  GEO_SurfaceType getSurfaceType() const { return surfaceType; }
459  void setSurfaceType(GEO_SurfaceType t) { surfaceType = t; }
460 
461  /// @{
462  /// Get or set the surface type by name token
463  const char *getSurfaceTypeName() const;
464  bool setSurfaceTypeName(const char *name);
465  /// @}
466 
467  bool isWrappedU() const { return flags.wrapu; }
468  bool isWrappedV() const { return flags.wrapv; }
469 
470  /// @{
471  /// Convenience method to set wrapping based on intrinsic properties
472  bool setWrapU(bool dowrap);
473  bool setWrapV(bool dowrap);
474  /// @}
475 
476  virtual void wrapU(int rounded = 1, int preserveShape = 0);
477  virtual void openU(int preserveShape = 0, int safe = 0);
478  virtual void wrapV(int rounded = 1, int preserveShape = 0);
479  virtual void openV(int preserveShape = 0, int safe = 0);
480 
481  virtual bool isClampedU() const;
482  virtual bool isClampedV() const;
483 
484  // Assuming the hull is closed in u/v, "unroll" it so that the CVs that are
485  // shared to form a wrapped surface are made unique. Also, the hull becomes
486  // open. The base class method only flips the open flag. If the face is
487  // not closed, the method returns -1. Otherwise it returns 0.
488  virtual int unrollU(int append_pts = 1);
489  virtual int unrollV(int append_pts = 1);
490 
491  bool hasEdge(const GA_Edge &edge) const override;
492 
493  // Check degenerate condition by testing face area in u and v
494  bool isDegenerate() const override;
495 
496 #if !GA_PRIMITIVE_VERTEXLIST
497  bool vertexApply(bool (*apply)(GA_Offset vtx, void *),
498  void *data = nullptr) const override;
499 #endif
500 
501  void iterateEdges(GA_IterateEdgesFunc apply_func) const override;
502  void iterateEdgesByVertex(GA_IterateEdgesByVertexFunc apply_func) const override;
503 
504 #if !GA_PRIMITIVE_VERTEXLIST
505  GA_Size getVertexCount() const override;
506  GA_Offset getVertexOffset(GA_Size index) const override;
507 #endif
508 
509  /// return the index of a vertex within our vertex list
510 #if GA_PRIMITIVE_VERTEXLIST
511  GA_Size findVertex(GA_Offset vtx) const { return myVertexList.find(vtx); }
512 #else
513  GA_Size findVertex(GA_Offset vtx) const { return myVertexMatx.find(vtx); }
514 #endif
515 
516  // Have we been deactivated and stashed?
517  virtual void stashed(bool beingstashed,
518  GA_Offset offset = GA_INVALID_OFFSET) override;
519 
520  // Raise the number of CVs to match the newcount. The shape of the face
521  // (especially if parametric) should NOT change. Return 0 upon success
522  // and -1 otherwise. start and stop define which indices to examine
523  // if newcount is negative it is taken as a relative value.
524  virtual int loftU(int newcount, int start=-1, int stop=-1) = 0;
525  virtual int loftV(int newcount, int start=-1, int stop=-1) = 0;
526 
527 
528  // Convert the real domain values of the primitive to unit values to be
529  // used in the common evaluation methods:
530  void realToUnitPair(float ureal, float vreal,
531  float &uunit, float &vunit) const override;
532  // and vice versa
533  void unitToRealPair(float uunit, float vunit,
534  float &ureal, float &vreal) const override;
535 
536  // Go from a normalized domain ([0,1]) to the real domain or vice versa.
537  // In the base class (i.e. here) the real domain ranges from 0 to
538  // vertexcount - 1 + isWrapped() for u and v respectively.
539  virtual void unitToRealDomain(float u_unit, float v_unit,
540  float &u_real, float &v_real) const;
541  virtual void realToUnitDomain(float u_real, float v_real,
542  float &u_unit, float &v_unit) const;
543 
544  // Calculate the real domains for n consecutive operations on the domain
545  // given n normalized domains and the operation
546 
547  virtual void unitToRealSequenceU(float *uunit, float *ureal,
548  int ulen) const;
549  virtual void unitToRealSequenceV(float *vunit, float *vreal,
550  int vlen) const;
551 
552  // Finds the vertex#'s of the end points of an edge.
553  // returns 0 if it fails (the edge is not on the hull) , 1 if it succeeds
554  virtual int findEdgePoints(const GA_Edge &edge,
555  int *pr0, int *pc0,
556  int *pr1, int *pc1) const;
557 
558  virtual int findEdgePoints(GA_Offset a, GA_Offset b,
559  int *pr0, int *pc0,
560  int *pr1, int *pc1) const;
561 
562  // This method fills the horizontal and vertical edge matrices
563  // based on the input linked list. An element of the matrix is
564  // non-zero if one of the selected edges exists on that spot on the
565  // hull, and zero otherwise. It returns 0 if no edges are on the hull,
566  // and 1 if at least one edge matches.
567  int makeEdgeMatrix(const GA_EdgeGroup &edges,
568  GEO_SubHull &subhull);
569 
570  // Append n points equally spaced between the 1st and last vertex.
571  void sampleEndsU(int n);
572  void sampleEndsV(int n);
573 
574  // Return the bounds of the valid evaluation interval in domain space:
575  // For meshes this refers to cv indices.
576  virtual void validURange(float &ua, float &ub) const;
577  virtual void validVRange(float &va, float &vb) const;
578  virtual void validUInterval(int &a, int &b) const;
579  virtual void validVInterval(int &a, int &b) const;
580 
581  // Find enclosing integral values(c1, c2) which validly enclose c
582  // and return the distance to c1
583  float getIndices(float c, int &c1, int &c2,
584  int maxIndex, int wrap) const;
585 
586  // Reverse the roles of rows and columns
587  virtual void transpose();
588 
589  // Return the surrounding values of the real-space u,v parameters.
590  // Returns 1 if succesful, 0 if out-of-range.
591  int parametricBBox(float u, float v,
592  float *u0, float *u1,
593  float *v0, float *v1) override;
594 
595  // Find distance in parameter space, aware of wrapping.
596  float uvDist(float u1, float v1, float u2, float v2) const override;
597 
598  virtual void weights(unsigned short onOff);
599 
600  fpreal calcVolume(const UT_Vector3 &refpt) const override;
601  fpreal calcArea() const override;
602  fpreal calcPerimeter() const override;
603 
604  static const inline UT_Vector3 quadNormal(
605  const UT_Vector3 &p1, const UT_Vector3 &p2,
606  const UT_Vector3 &p3, const UT_Vector3 &p4)
607  {
608  UT_Vector3 nml(0, 0, 0);
609  nml.normal(p1, p2);
610  nml.normal(p2, p3);
611  nml.normal(p3, p4);
612  nml.normal(p4, p1);
613 
614  nml.normalize();
615  return nml;
616  }
617 
618  /// This is a wrapper for a single quad of a GEO_Hull, so that
619  /// it can be treated like a GEO_PrimPoly in a template.
620  class Poly {
621  public:
622  Poly(const GEO_Hull &hull, const exint row, const exint col)
623  : myHull(hull)
624  , myRow(row)
625  , myCol(col)
626  , myRowP1((row+1 == hull.getNumRows()) ? 0 : (row+1))
627  , myColP1((col+1 == hull.getNumCols()) ? 0 : (col+1))
628  {}
630  { return 4; }
632  { return myHull.getVertexOffset((i >= 2) ? myRowP1 : myRow, (i==1 || i==2) ? myColP1 : myCol); }
634  { return myHull.getPointOffset((i >= 2) ? myRowP1 : myRow, (i==1 || i==2) ? myColP1 : myCol); }
636  { return myHull.getPos3((i >= 2) ? myRowP1 : myRow, (i==1 || i==2) ? myColP1 : myCol); }
638  { return true; }
639  float calcArea() const
640  {
641  UT_Vector3 p[4];
642  for (GA_Size i = 0; i < getFastVertexCount(); ++i)
643  p[i] = getPos3(i);
644  float area = cross(p[0]-p[1],p[2]-p[1]).length()
645  + cross(p[0]-p[3],p[2]-p[3]).length();
646  area *= 0.5f;
647  return area;
648  }
649  private:
650  const GEO_Hull &myHull;
651  const exint myRow;
652  const exint myRowP1;
653  const exint myCol;
654  const exint myColP1;
655  };
656 
657 protected:
658 #if !GA_PRIMITIVE_VERTEXLIST
659  void clearForDeletion() override;
660 #endif
661 
662  void cycleOffsetListRows(int shift);
663  void cycleOffsetListCols(int shift);
664 
666  { return GEO_FAMILY_HULL; }
667 
668  // Declare intrinsic attribute functions
669  GA_DECLARE_INTRINSICS(override);
670 
671  // The following three methods are used by removeEdges to
672  // remove all possible selected edges from a hull.
673 
674  // This computes where the hull needs to be split, recursing downwards
675  // if necessary. It calls getSubHull to split the hulls. Returns 1 if
676  // the hull needs to be deleted as a result of breaking.
677  int breakHull(GEO_SubHull &subhull,
678  int top, int left, int bottom, int right,
679  GEO_SubHullFlags break_flags);
680 
681  // This figures out which edges were actually used in the edge deletion.
682  // It returns 1 if all the selected edges were used, 0 if some were not
683  int checkUsedEdges(UT_BitArray *remove_edges,
684  const GEO_SubHull &subhull);
685 
686  // Implemented in GU. Gets a part of this hull, creating a new one
687  // if break_flags.recurse is set.
688  virtual GEO_Hull *getSubHull(int top, int left, int bottom, int right,
689  GEO_SubHullFlags break_flags) = 0;
690 
691  // Speacial save and load methods for the sub-classes:
692  virtual bool savePrivateH9(std::ostream &os, bool binary) const = 0;
693  virtual bool loadPrivateH9(UT_IStream &is) = 0;
694  virtual bool saveExtraH9 (std::ostream &os, bool binary) const = 0;
695  virtual bool loadExtraH9 (UT_IStream &is) = 0;
696 
697  // Check the validity of the data. Meant to be called especially at loading
698  // time. The method returns 1 if OK and 0 if trouble.
699  virtual bool validate(void) const = 0;
700 
701  // Clip or wrap c to find enclosing integral values(c1, c2)
702  // and return the distance to c1
703  float getLRIndex(float c, int &c1, int &c2,
704  int minIndex, int maxIndex, int wrap) const;
705 
706  /// @warning vertexPoint() doesn't check the bounds. Use with caution.
708  {
709  UT_ASSERT_P(r < getNumRows() && c < getNumCols());
710 #if GA_PRIMITIVE_VERTEXLIST
711  return getDetail().vertexPoint(getVertexOffset(r*exint(myCols) + c));
712 #else
713  return getDetail().vertexPoint(myVertexMatx(r,c));
714 #endif
715  }
716 
717 #if !GA_PRIMITIVE_VERTEXLIST
718  /// Defragmentation
719  void swapVertexOffsets(const GA_Defragment &defrag) override;
720 #endif
721 
722 #if GA_PRIMITIVE_VERTEXLIST
724  GA_Size matrixIndex(int r, int c) const
725  {
726  UT_ASSERT_P(r < getNumRows() && c < getNumCols());
727  return r*exint(myCols) + c;
728  }
729 
730  int myRows;
731  int myCols;
732 #else
734 #endif
737 
738  bool evaluateBaryCenterRefMap(GA_Offset result_vertex,
739  GA_AttributeRefMap &map) const override;
740 
741  // Evaluate one point (when du=dv=0), or the du-th dv-th derivative.
742  // Return 0 if successful, and -1 otherwise.
743  virtual bool evaluateIndexRefMap(fpreal u, fpreal v, GA_Offset result_vtx,
744  GA_AttributeRefMap &hlist,
745  unsigned du, unsigned dv) const;
746  virtual int evaluateIndexV4(float iu, float iv, UT_Vector4 &pos,
747  unsigned du=0, unsigned dv=0) const;
748 
749  virtual int subdivideURefMap(float u, GA_AttributeRefMap &map);
750  virtual int subdivideUFloat(float u);
751  virtual int subdivideVRefMap(float u, GA_AttributeRefMap &map);
752  virtual int subdivideVFloat(float u);
753 
754  // Refine numdivs times in each span.
755  virtual void spanRefineURefMap(GA_AttributeRefMap &map,
756  int numdivs=1) = 0;
757  virtual void spanRefineUInt( int numdivs=1) = 0;
758  virtual void spanRefineVRefMap(GA_AttributeRefMap &map,
759  int numdivs=1) = 0;
760  virtual void spanRefineVInt( int numdivs=1) = 0;
761 
762  virtual int unrefineURefMap(int kidx, GA_AttributeRefMap &h,
763  int mult=0, float tol=1e-4f,
764  GA_PointGroup *delgroup=0);
765  virtual int unrefineUFloat(int kidx, int mult = 0,
766  float tol = 1e-4F,
767  GA_PointGroup *delgroup = 0);
768  virtual int unrefineVRefMap(int kidx, GA_AttributeRefMap &h,
769  int mult=0, float tol=1e-4f,
770  GA_PointGroup *delgroup=0);
771  virtual int unrefineVFloat(int kidx, int mult = 0,
772  float tol = 1e-4F,
773  GA_PointGroup *delgroup = 0);
774 
775 #if !GA_PRIMITIVE_VERTEXLIST
776  /// Report approximate memory usage for myVertexMatx (exclusive)
777  int64 getBaseMemoryUsage() const;
778 
779  // This is called by the subclasses to count the
780  // memory used by myVertexMatx (exclusive)
781  void countBaseMemory(UT_MemoryCounter &counter) const;
782 #endif
783 
784 private:
785  friend std::ostream &operator<<(std::ostream &os, const GEO_Hull &d)
786  {
787  d.saveH9(os, 0,
790  return os;
791  }
792  void increaseDensityInRows(GA_AttributeRefMap &m,
793  int numdivs, GA_PointGroup *pgp);
794  void increaseDensityInCols(GA_AttributeRefMap &m,
795  int numdivs, GA_PointGroup *pgp);
797 };
799 #endif
bool isWrappedU() const
Definition: GEO_Hull.h:467
SYS_FORCE_INLINE void setPos3(unsigned int r, unsigned int c, const UT_Vector3 &pos) const
Definition: GEO_Hull.h:432
virtual void copyUnwiredForMerge(const GA_Primitive *src, const GA_MergeMap &map)
SYS_FORCE_INLINE void setPos3(GA_Offset ptoff, const UT_Vector3 &P)
Set P from a UT_Vector3.
Definition: GA_Detail.h:203
virtual GEO_Primitive * copy(int preserve_shared_pts=0) const
bool findEdgePoints(GA_Offset ptoff0, GA_Offset ptoff1, GA_Size &vtx0, GA_Size &vtx1) const
static const UT_Vector3 quadNormal(const UT_Vector3 &p1, const UT_Vector3 &p2, const UT_Vector3 &p3, const UT_Vector3 &p4)
Definition: GEO_Hull.h:604
void spanRefineU(GA_AttributeRefMap &map, int numdivs=1)
Definition: GEO_Hull.h:321
SYS_FORCE_INLINE GA_Offset getPointOffset(GA_Size i) const
Definition: GA_Primitive.h:249
virtual UT_Vector3 baryCenter() const
SYS_FORCE_INLINE GA_Detail & getDetail() const
Definition: GA_Primitive.h:132
virtual void copyPrimitive(const GEO_Primitive *src)=0
SYS_FORCE_INLINE GA_Index getVertexIndex(unsigned int r, unsigned int c) const
Definition: GEO_Hull.h:408
bool isWrappedV() const
Definition: GEO_Hull.h:468
virtual void clearForDeletion()
Definition: GA_Primitive.h:598
Used to pass options and map offset values during saving.
Definition: GA_SaveMap.h:48
void spanRefineU(int numdivs=1)
Definition: GEO_Hull.h:324
SYS_FORCE_INLINE GA_Size getVertexCount() const
Return the number of vertices used by this primitive.
Definition: GA_Primitive.h:227
int unrefineU(int kidx, GA_AttributeRefMap &h, int mult=0, float tol=1e-4f, GA_PointGroup *delgroup=0)
Definition: GEO_Hull.h:334
GA_OffsetMatrix myVertexMatx
Definition: GEO_Hull.h:733
GEO_Vertex getVertexElement(GA_Size i) const
GLint left
Definition: glcorearb.h:2004
#define SYS_DEPRECATED_PUSH_DISABLE()
const GLdouble * v
Definition: glcorearb.h:836
UT_Vector4 getPos4(GA_Offset ptoff) const
The ptoff passed is the point offset.
Definition: GA_Detail.h:248
#define SYS_DEPRECATED_POP_DISABLE()
GLuint start
Definition: glcorearb.h:474
bool GAisValid(GA_Size v)
Definition: GA_Types.h:625
SYS_FORCE_INLINE GA_Size getFastVertexCount() const
Definition: GEO_Hull.h:441
int unrefineU(int kidx, int mult=0, float tol=1e-4F, GA_PointGroup *delgroup=0)
Definition: GEO_Hull.h:339
const GLuint GLenum const void * binary
Definition: glcorearb.h:1923
static GA_PrimitiveFamilyMask buildFamilyMask()
Definition: GEO_Hull.h:665
SYS_FORCE_INLINE GA_Size getFastVertexCount() const
Definition: GEO_Hull.h:629
The merge map keeps track of information when merging details.
Definition: GA_MergeMap.h:53
GEO_SurfaceType surfaceType
Definition: GEO_Hull.h:736
SYS_FORCE_INLINE void setPointOffset(GA_Size i, GA_Offset ptoff)
Definition: GA_Primitive.h:255
SYS_FORCE_INLINE GA_Offset getVertexOffset(unsigned int r, unsigned int c) const
Definition: GEO_Hull.h:397
SYS_FORCE_INLINE GA_Index getPointIndex(unsigned int r, unsigned int c) const
Definition: GEO_Hull.h:424
GLboolean GLboolean GLboolean GLboolean a
Definition: glcorearb.h:1221
int appendCol(bool appendPts=true)
Definition: GEO_Hull.h:221
GLbitfield flags
Definition: glcorearb.h:1595
int h_rows
Definition: GEO_Hull.h:112
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:72
#define GA_DECLARE_INTRINSICS(OVERRIDE)
Definition: GA_Primitive.h:79
SYS_FORCE_INLINE GA_Offset getPointOffset(unsigned int r, unsigned int c) const
Definition: GEO_Hull.h:414
Class which writes ASCII or binary JSON streams.
Definition: UT_JSONWriter.h:32
SYS_FORCE_INLINE void setPos4(unsigned int r, unsigned int c, const UT_Vector4 &pos) const
Definition: GEO_Hull.h:436
Abstract base class for a range membership query object.
SYS_FORCE_INLINE UT_Vector3 getPos3(GA_Offset ptoff) const
The ptoff passed is the point offset.
Definition: GA_Detail.h:170
SYS_FORCE_INLINE bool isClosed() const
Definition: GEO_Hull.h:637
GLfloat GLfloat GLfloat v2
Definition: glcorearb.h:817
int unrefineV(int kidx, int mult=0, float tol=1e-4F, GA_PointGroup *delgroup=0)
Definition: GEO_Hull.h:349
virtual int parametricBBox(float u, float v, float *u0, float *u1, float *v0, float *v1)
3D Vector class.
float calcArea() const
Definition: GEO_Hull.h:639
virtual void realToUnitPair(float ureal, float vreal, float &uunit, float &vunit) const
#define GEO_FAMILY_HULL
Definition: GEO_PrimType.h:74
png_uint_32 i
Definition: png.h:2877
virtual void swapVertexOffsets(const GA_Defragment &defrag)
exint GA_Size
Defines the bit width for index and offset types in GA.
Definition: GA_Types.h:211
SYS_FORCE_INLINE int64 getBaseMemoryUsage() const
Report approximate memory usage for myVertexList for subclasses.
Definition: GA_Primitive.h:753
SYS_FORCE_INLINE GA_Offset getPointOffset(GA_Size i) const
Definition: GEO_Hull.h:633
virtual bool loadH9(UT_IStream &is, const UT_Array< GA_AttribLoadDataH9 > &prim_attribs, const UT_Array< GA_AttribLoadDataH9 > &vtx_attribs)
GA_PrimitiveFamilyMask
bool saveH9(std::ostream &os, bool binary, const UT_Array< GA_AttribSaveDataH9 > &prim_attribs, const UT_Array< GA_AttribSaveDataH9 > &vtx_attribs) const override
virtual UT_Vector3 computeNormal() const =0
Return a normal vector for the primitive.
#define GA_INVALID_OFFSET
Definition: GA_Types.h:654
virtual void normal(NormalComp &output) const =0
#define UT_ASSERT_P(ZZ)
Definition: UT_Assert.h:101
bool evaluateIndex(fpreal u, fpreal v, GA_Offset result_vtx, GA_AttributeRefMap &hlist, unsigned du, unsigned dv) const
Definition: GEO_Hull.h:148
GEO_SurfaceType getSurfaceType() const
Definition: GEO_Hull.h:458
virtual bool isDegenerate() const =0
Is the primitive degenerate.
GA_Size GA_Offset
Definition: GA_Types.h:617
GLsizei GLboolean transpose
Definition: glcorearb.h:831
long long int64
Definition: SYS_Types.h:100
Poly(const GEO_Hull &hull, const exint row, const exint col)
Definition: GEO_Hull.h:622
GLdouble n
Definition: glcorearb.h:2007
GLfloat f
Definition: glcorearb.h:1925
void wireVertexPoint(GA_Offset vtx, GA_Offset pt)
int v_rows
Definition: GEO_Hull.h:111
int subdivideU(float u)
Definition: GEO_Hull.h:254
SIM_DerScalar length() const
friend std::ostream & operator<<(std::ostream &os, const GEO_Hull &d)
Definition: GEO_Hull.h:785
#define UT_ASSERT(ZZ)
Definition: UT_Assert.h:102
T distance(const UT_Vector4T< T > &v1, const UT_Vector4T< T > &v2)
Definition: UT_Vector4.h:634
virtual fpreal calcArea() const
int64 exint
Definition: SYS_Types.h:109
int evaluateIndex(float iu, float iv, UT_Vector4 &pos, unsigned du=0, unsigned dv=0) const
Definition: GEO_Hull.h:152
SYS_FORCE_INLINE int getNumRows() const
Definition: GEO_Hull.h:365
#define SYS_FORCE_INLINE
Definition: SYS_Inline.h:45
GLintptr offset
Definition: glcorearb.h:664
bool operator==(const GEO_SubHullPart &p) const
Definition: GEO_Hull.h:95
int appendRow(bool appendPts=true)
Definition: GEO_Hull.h:212
#define GEO_API
Definition: GEO_API.h:10
std::function< bool(const GA_Edge &edge)> GA_IterateEdgesFunc
Definition: GA_Primitive.h:72
void setVertexPoint(unsigned int r, unsigned int c, GA_Offset pt)
Definition: GEO_Hull.h:445
virtual void computeInteriorPointWeights(UT_Array< GA_Offset > &vtxlist, UT_FloatArray &weightlist, fpreal u, fpreal v, fpreal w) const
virtual void reverse()=0
Reverse the order of vertices.
A handle to simplify manipulation of multiple attributes.
virtual void iterateEdges(GA_IterateEdgesFunc apply_func) const
Definition: GA_Primitive.h:342
SYS_FORCE_INLINE GA_Index vertexIndex(GA_Offset offset) const
Given a vertex's data offset, return its index.
Definition: GA_Detail.h:459
Options during loading.
Definition: GA_LoadMap.h:42
virtual int getBBox(UT_BoundingBox *bbox) const =0
virtual float uvDist(float u1, float v1, float u2, float v2) const
Defragmentation of IndexMaps.
Definition: GA_Defragment.h:45
SYS_FORCE_INLINE GA_Offset vertexPoint(GA_Offset vertex) const
Given a vertex, return the point it references.
Definition: GA_Detail.h:469
void addPointRefToGroup(GA_PointGroup &grp) const
GLboolean * data
Definition: glcorearb.h:130
png_bytepp row
Definition: png.h:1836
#define SYS_DEPRECATED_HDK(__V__)
std::function< bool(GA_Size, GA_Size)> GA_IterateEdgesByVertexFunc
Definition: GA_Primitive.h:73
GLuint const GLchar * name
Definition: glcorearb.h:785
bool operator!=(const GEO_SubHullPart &p) const
Definition: GEO_Hull.h:101
GLboolean GLboolean GLboolean b
Definition: glcorearb.h:1221
GA_Size GA_Index
Define the strictness of GA_Offset/GA_Index.
Definition: GA_Types.h:611
virtual fpreal calcPerimeter() const
virtual GA_DereferenceStatus dereferencePoints(const GA_RangeMemberQuery &pt_q, bool dry_run=false)=0
virtual bool saveH9(std::ostream &os, bool binary, const UT_Array< GA_AttribSaveDataH9 > &prim_attribs, const UT_Array< GA_AttribSaveDataH9 > &vtx_attribs) const
void spanRefineV(int numdivs=1)
Definition: GEO_Hull.h:329
GA_Topology & getTopology()
Definition: GA_Detail.h:721
GLfloat v0
Definition: glcorearb.h:815
virtual bool evaluateBaryCenterRefMap(GA_Offset result_vtx, GA_AttributeRefMap &map) const
GLint GLint bottom
Definition: glcorearb.h:2004
SYS_FORCE_INLINE GA_Index pointIndex(GA_Offset offset) const
Given a point's data offset, return its index.
Definition: GA_Detail.h:296
virtual bool vertexApply(bool(*apply)(GA_Offset vtx, void *), void *data=0) const
GLfloat GLfloat GLfloat GLfloat h
Definition: glcorearb.h:2001
double fpreal
Definition: SYS_Types.h:263
int subdivideU(float u, GA_AttributeRefMap &map)
Definition: GEO_Hull.h:252
void spanRefineV(GA_AttributeRefMap &map, int numdivs=1)
Definition: GEO_Hull.h:326
virtual int detachPoints(GA_PointGroup &grp)=0
SYS_FORCE_INLINE GA_Offset vertexPoint(GA_Size r, GA_Size c) const
Definition: GEO_Hull.h:707
static const UT_Array< GA_AttribSaveDataH9 > & theEmptySaveAttribs
Convience objects to pass as arguments to saveH9()/loadH9().
virtual bool hasEdge(const GA_Edge &edge) const
Method to determine if a primitive has an edge (undirected).
int d_rows
Definition: GEO_Hull.h:113
GLuint index
Definition: glcorearb.h:785
virtual void unitToRealPair(float uunit, float vunit, float &ureal, float &vreal) const
SYS_FORCE_INLINE UT_Vector3 getPos3(unsigned int r, unsigned int c) const
Definition: GEO_Hull.h:430
GLfloat GLfloat v1
Definition: glcorearb.h:816
virtual fpreal calcVolume(const UT_Vector3 &) const
virtual int evaluateNormalVector(UT_Vector3 &nml, float u, float v=0, float w=0) const
SYS_FORCE_INLINE GA_Offset getVertexOffset(GA_Size primvertexnum) const
Definition: GA_Primitive.h:235
#define GA_INVALID_INDEX
Definition: GA_Types.h:653
#define GA_PRIMITIVE_VERTEXLIST
Definition: GA_Primitive.h:16
SYS_FORCE_INLINE Storage::MathFloat normalize()
virtual void addToBSphere(UT_BoundingSphere *bsphere) const
SYS_FORCE_INLINE void setPointOffset(unsigned int r, unsigned int c, GA_Offset ptoff) const
Definition: GEO_Hull.h:438
GEO_SurfaceType
SYS_FORCE_INLINE UT_Vector3 getPos3(GA_Size i) const
Definition: GEO_Hull.h:635
Container class for all geometry.
Definition: GA_Detail.h:96
GLubyte GLubyte GLubyte GLubyte w
Definition: glcorearb.h:856
SYS_FORCE_INLINE int getNumCols() const
Definition: GEO_Hull.h:372
int unrefineV(int kidx, GA_AttributeRefMap &h, int mult=0, float tol=1e-4f, GA_PointGroup *delgroup=0)
Definition: GEO_Hull.h:344
GLboolean r
Definition: glcorearb.h:1221
#define const
Definition: zconf.h:214
SYS_FORCE_INLINE void normal(const UT_Vector3T< T > &va, const UT_Vector3T< T > &vb)
Definition: UT_Vector3.h:457
void countBaseMemory(UT_MemoryCounter &counter) const
UT_RefMatrix< GEO_SubHullPart > mat
Definition: GEO_Hull.h:110
SIM_DerVector3 cross(const SIM_DerVector3 &lhs, const SIM_DerVector3 &rhs)
virtual void iterateEdgesByVertex(GA_IterateEdgesByVertexFunc apply_func) const
Definition: GA_Primitive.h:352
void setPos4(GA_Offset ptoff, const UT_Vector4 &P)
Set P from a UT_Vector4.
Definition: GA_Detail.h:254
GA_Size findVertex(GA_Offset vtx) const
return the index of a vertex within our vertex list
Definition: GEO_Hull.h:513
SYS_FORCE_INLINE UT_Vector4 getPos4(unsigned int r, unsigned int c) const
Definition: GEO_Hull.h:434
GEO_Hull(GA_Detail *d, GA_Offset offset=GA_INVALID_OFFSET)
Definition: GEO_Hull.h:121
virtual void stashed(bool beingstashed, GA_Offset offset=GA_INVALID_OFFSET)
int subdivideV(float u)
Definition: GEO_Hull.h:258
int subdivideV(float u, GA_AttributeRefMap &map)
Definition: GEO_Hull.h:256
GA_API const UT_StringHolder area
GEO_HullFlags flags
Definition: GEO_Hull.h:735
void setSurfaceType(GEO_SurfaceType t)
Definition: GEO_Hull.h:459
SYS_FORCE_INLINE GA_Offset getFastVertexOffset(GA_Size i) const
Definition: GEO_Hull.h:631
GLenum src
Definition: glcorearb.h:1792