HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
GEO_PrimRBezCurve.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 implements a piecewise Bezier curve defined by
10  * a set of breakpoints, basis function, and CVs.
11  *
12  *
13  */
14 
15 #pragma once
16 
17 #ifndef __GEO_PrimRBezCurve_h__
18 #define __GEO_PrimRBezCurve_h__
19 
20 #include "GEO_API.h"
21 #include "GEO_Curve.h"
22 #include "GEO_PrimType.h"
23 
24 class GA_Detail;
25 
27 {
28 public:
29  using GEO_Face::refine;
30 
31 protected:
32  /// NOTE: The constructor should only be called from subclass
33  /// constructors.
35  : GEO_Curve(d, offset)
36  {}
37 
38  /// NOTE: The destructor should only be called from subclass
39  /// destructors.
40  /// Please read the comments on the parent class destructor.
41  ~GEO_PrimRBezCurve() override {}
42 
43 public:
44  /// Increases div to the first valid number of divisions, given
45  /// the order and closed flag. For NURBs, this is a straightforward
46  /// minimum.
47  /// Returns true if the divisions changed.
48  static bool forceValidDivisions(int &div, int order, bool closed);
49 
50  // Given a domain value (u), store all the basis derivatives (from 0 to du
51  // inclusive) into bmatx. Return the min index of the CVs needed
52  // for the linear combination. The indices may exceed the number of
53  // vertices if the curve is wrapped, so remember to use % getVertexCount().
54  int evaluateBasisDerivs(float u,float bmatx[][GA_MAXORDER],
55  int &cvoffset, unsigned du = 0,
56  int uoffset = -1) const override;
57 
58  // Evaluate the basis at the given point in the domain and also return
59  // the index of the first CV to linearly combine the basis with. The CV
60  // index may exceed the number of vertices if the curve is wrapped,
61  // so remember to use modulus (%). This method handles both rational and
62  // non-rational curves.
63  int evaluateBasis(
64  float u,float *ubvals, int &cvoffset,
65  unsigned du=0, int uoffset=-1) const override;
66 
67  // Compute the location of the breakpoint. Return 0 if OK, else -1.
68  int evaluateBreakpoint(int uidx, UT_Vector4 &pos,
69  int du = 0) const override;
70 
71  // Remove all repeated vertices - (only gets consecutive vertices)
72  GA_Size removeRepeatedVertices(bool check_order = false,
73  bool count_only = false,
74  bool deleteOrphanedPoints = false) override;
75 
76  // compute the un-normalized lengths corresponding to points on the curve
77  // evaluated at the valid knots parameter values
78  // (ones with which lie within curve paramer domain) and store them
79  // in the 'lengths' array. Returns the curve "length" (same as last knot).
80  // The meaning of "length" depends on ptype, and can mean chord length,
81  // square chord length, approximate arc length.
83  UT_Array<float> &lengths) const override;
84 
85  // Given a CV index figure out the min/max indicies of the knots between
86  // which the curve needs to be re-evaluated if the CV changes. If not
87  // given a valid CV index, the method returns -1. Otherwise it returns 0.
88  // If the curve wraps the domain we return will be rather large.
89  int domainRangeOfCV(int cvidx,
90  int &mink,int &maxk) const override;
91 
92  // Given a CV index figure out the min/max breakpoints which are
93  // affected if the CV changes. If not given a valid CV index, the
94  // method returns -1. Otherwise it returns 0. Also returns -1 if
95  // no breakpoints are affected.
96  // NOTE: use % breakCount since maxbkp may be >= breakCount
97  int breakpointRangeOfCV(int cvidx, int &minbkp,
98  int &maxbkp) const override;
99 
100  // Reparameterize the curve by changing its basis. The first breakpoint
101  // remains unchanged.
102  void reparameterize(GA_ParameterizationType ptype) override;
103 
104  // Set the closed or open flag, and make sure the basis knot vector is
105  // consistent with the change. These functions are virtual by inheritance.
106  // They change the number of CVs, so use them with care. Also, they do
107  // not keep a history of changes: if you start with a closed curve
108  // and then you open and close it again, the re-closed curve uses
109  // 'degree-2' new CVs that have been generated for this purpose.
110 
111  // Close up an open curve.
112  //
113  // If preserveShape = 1:
114  // add extra cvs at the end to define the last span.
115  // if rounded,
116  // the new cvs just added will be arranged to
117  // give a rounded appearance.
118  // else
119  // the new cvs just added will form a straight
120  // line between the first and last endpoint.
121  // If preserveShape = 0:
122  // just grow the basis by one span, without adding any new cvs.
123  // ignore the rounded flag.
124  void close(int rounded = 1, int preserveShape = 0) override;
125 
126  // Open up a closed curve.
127  //
128  // If preserveShape = 1:
129  // the open curve will have exactly the same geometry
130  // (ie. still look closed) with the first point duplicated.
131  // If preserveShape = 0:
132  // the open curve will remove the last span in the basis,
133  // thus open up a gap in the curve.
134  // last few cvs are dangling which do not form a valid
135  // curve segment, if the safe flag = 0.
136  // The safe flag is to remove unneed cvs for ensuring the resulting
137  // curve is a valid bezier curve.
138  void open(int preserveShape = 0, int safe = 0) override;
139 
140  // Insert or delete vertices. The insertion methods return the index if
141  // successful and -1 otherwise. The deletion methods return 0 if ok and
142  // -1 otherwise. The insertion methods create the point if it does not
143  // exist.
145  GA_Size where=0) override;
147  int deleteVertex(GA_Size num) override;
148 
149  // Assuming the curve is closed, "unroll" it so that the CVs that are
150  // shared to form a wrapped curve are made unique. Also, the curve becomes
151  // open. The base class method only flips the open flag. If the curve is
152  // not closed, the method returns -1. Otherwise it returns 0.
153  int unroll(int append_pts = 1) override;
154 
155  // Raise the number of CVs to match the newcount. The shape of the curve
156  // (especially if parametric) should NOT change. Return 0 upon success
157  // and -1 otherwise. start and stop define which indices to examine
158  // if newcount is negative it is taken as a relative value.
159  int loft(int newcount, int start=-1, int stop=-1) override;
160 
161  // Warp the curve at u by the given delta. Change 1 or 2 Cvs and possibly
162  // insert a knot once or more as well. If a knot is inserted or we happen
163  // to land exactly on a knot, we change only one CV. The bias makes sense
164  // only when changing 2 CVs, and will be ignored altogether if < 0.
165  // We return the index of the affected knot in the sequence, or -1 if
166  // there's an error.
167  int warp(float u, const UT_Vector3 &delta,
168  GA_AttributeRefMap &map,
169  float sharpness = 0.0f,
170  float bias = -1.0f) override;
171 
172  // Translate the CVs such that the given breakpoint change positions by
173  // the given delta. Return -1 if something goes wrong, 0 if translation
174  // was successful.
175  // NOTE: uindices cannot contain any duplicates. If the curve is closed,
176  // the first and last breakpoint are considered the same.
177  int translateBreakpoints(const UT_IntArray &uindices,
178  const UT_Vector3 &delta,
179  int fixbkpts = 1,
180  GA_PointGroup *ptgroup = NULL,
181  GEO_Delta *geodelta = 0) override;
182 
183  int transformBreakpoints(const UT_IntArray &uindices,
184  const UT_Matrix4 &matx,
185  int fixbkpts = 1,
186  GA_PointGroup *ptgroup = NULL,
187  GEO_Delta *geodelta = 0) override;
188 
189  // Append another face to us in one of two ways: blend the two endpoints
190  // or connect them straight or rounded. The bias ranges from 0 to 1 and is
191  // relevant only to blending. The tolerance for blending: if 0, the two
192  // endpoints will merge into one point with a discontinuity; if less than
193  // 1, we insert knots into the curves to minimize the affected areas; if 1,
194  // no refinement is done. For the non-blend case, the tolerance will
195  // generate a span whose shape goes from round to straight; 0 tolerance
196  // means straight connection. We return 0 if OK and -1 if error. Both
197  // curves must be open and have the same order.
198  int attach(const GEO_Face &face, int blend = 1,
199  float bias = .5f, float tolerance = 1.f, int=0,
200  GA_PointGroup *ptgroup=0) override;
201 
202  // Build a planar (domain) face of the same type as us and with the same
203  // number of vertices. Copying the (x,y) values of our points to the planar
204  // face is optional.
205  GD_Face *planar(GD_Detail &dgdp, int copyxy = 0) const override;
206 
207  // reverse the vertices of the curve, preserving shape
208  void reverse() override;
209 
210  // If ustart and ustop are two values in the valid interval,ustart < ustop,
211  // return the part of curve defined by ustart and ustop in a new primitive.
212  // Return 0 if a problem is encountered.
213  GEO_Curve *extract(float ustart,float ustop) const override;
214 
215  const GA_PrimitiveJSON *getJSON() const override;
216 
217  /// Builds Bezier curves using the specified range of point offsets,
218  /// as dictated by curvesizelist and curvepointnumbers, in parallel.
219  /// curvepointnumbers lists the *offsets* of the points used by
220  /// each curve *MINUS* startpt, i.e. they are offsets relative to startpt,
221  /// *not* indices relative to startpt. The offset of the first curve is
222  /// returned, and the rest are at consecutive offsets. All
223  /// curvepointnumbers must be between 0 (inclusive) and
224  /// npoints (exclusive).
225  ///
226  /// NOTE: Existing primitives *are* allowed to be using the points in
227  /// the specified range already, and the curves being created do not
228  /// need to use all of the points in the range. However,
229  /// these cases may impact performance.
230  /// @{
231  static GA_Offset buildBlock(GA_Detail *detail,
232  const GA_Offset startpt,
233  const GA_Size npoints,
234  const GEO_PolyCounts &curvesizelist,
235  const int *curvepointnumbers,
236  const UT_Array<int> &porders,
237  const int uorder = 4,
238  const bool closed = false);
239  static GA_Offset buildBlock(GA_Detail *detail,
240  const GA_Offset startpt,
241  const GA_Size npoints,
242  const GA_PolyCounts &curvesizelist,
243  const int *curvepointnumbers,
244  const UT_Array<int> &porders,
245  const int uorder = 4,
246  const bool closed = false);
247  /// @}
248 
249  fpreal calcPerimeter() const override;
250 
251 protected:
253  { return GEO_Curve::buildFamilyMask(); }
254 
255  /// All subclasses should call this method to register the curve intrinsics.
256  /// @see GA_IntrinsicManager
259  { return GEO_Curve::registerIntrinsics(defn); }
260 
261  // Get a new basis of a type that matches our type:
262  GA_Basis *newBasis() const override;
263 
264  /// Set the basis to a copy of the passed-in basis.
265  /// NOTE: basis *must* be valid for this curve!
266  void setBasisCopy(const GA_Basis *basis) override;
267 
268  // Two different closing methods:
269  void closeSharp();
270  void closeRounded();
271 
272  // increase order by 1.
273  void incrementOrder(GA_AttributeRefMap &map);
274  void incrementOrder();
275 
276  // Increase the order. Return 0 if successful, -1 otherwise (eg.
277  // order cannot be increased because it's >= MAXORDER).
278  int raiseOrderRefMap(int neworder,
279  GA_AttributeRefMap &map) override;
280  int raiseOrderInt(int neworder) override;
281 
282  // Insert a breakpoint at the given point in the domain and return its
283  // index if successful. Return -1 in case of failure (eg. if outside the
284  // valid domain or equal to an existing breakpoint).
285  int refineRefMap(float k, GA_AttributeRefMap &hlist,
286  int=0) override;
287  int refineInt(float k, int=0) override;
288 
289 private:
290  // Nothing.
292 };
294 #endif
static GA_IntrinsicManager::Registrar registerIntrinsics(GA_PrimitiveDefinition &defn)
Definition: GEO_TriMesh.h:193
virtual int refineInt(float k, int r=1)
GA_API const UT_StringHolder div
virtual int domainRangeOfCV(int cvidx, int &mink, int &maxk) const =0
void reverse() override
Reverse the order of vertices.
int attach(const GEO_Face &face, int blend=1, float bias=0.5f, float tolerance=1.0f, int unrefine=1, GA_PointGroup *ptgroup=0) override
virtual int breakpointRangeOfCV(int cvidx, int &minbkp, int &maxbkp) const =0
#define SYS_DEPRECATED_PUSH_DISABLE()
#define SYS_DEPRECATED_POP_DISABLE()
GLuint start
Definition: glcorearb.h:475
#define GA_MAXORDER
Definition: GA_Defines.h:17
virtual int loft(int newcount, int start=-1, int stop=-1)=0
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
GA_PrimitiveFamilyMask
virtual int transformBreakpoints(const UT_IntArray &uindices, const UT_Matrix4 &matx, int fixbkpts=1, GA_PointGroup *ptgroup=NULL, GEO_Delta *geodelta=0)=0
#define GA_INVALID_OFFSET
Definition: GA_Types.h:678
static GA_PrimitiveFamilyMask buildFamilyMask()
GA_ParameterizationType
Definition: GA_Types.h:196
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
virtual GA_Size appendVertex(GA_Offset ppt)
virtual int translateBreakpoints(const UT_IntArray &uindices, const UT_Vector3 &delta, int fixbkpts=1, GA_PointGroup *ptgroup=NULL, GEO_Delta *geodelta=0)=0
virtual GEO_Curve * extract(float ustart, float ustop) const =0
int refine(float k, GA_AttributeRefMap &gah, int r=1)
Definition: GEO_Face.h:306
virtual GD_Face * planar(GD_Detail &dgdp, int copyxy=0) const =0
virtual const GA_PrimitiveJSON * getJSON() const =0
Provide a JSON interface to a primitive.
fpreal calcPerimeter() const override
#define GEO_API
Definition: GEO_API.h:14
Bezier or NURBS basis classes which maintain knot vectors.
Definition: GA_Basis.h:49
virtual GA_Basis * newBasis() const =0
GLdouble GLdouble GLint GLint order
Definition: glad.h:2676
A handle to simplify manipulation of multiple attributes.
~GEO_PrimRBezCurve() override
virtual void close(int rounded=1, int preserve_shape=0)
virtual int raiseOrderRefMap(int neworder, GA_AttributeRefMap &map)=0
static GA_IntrinsicManager::Registrar registerIntrinsics(GA_PrimitiveDefinition &defn)
virtual int raiseOrderInt(int neworder)=0
virtual GA_Size removeRepeatedVertices(bool check_order=false, bool count_only=false, bool delete_orphaned_points=false)
GEO_PrimRBezCurve(GA_Detail *d, GA_Offset offset=GA_INVALID_OFFSET)
virtual int refineRefMap(float k, GA_AttributeRefMap &gah, int r=1)
fpreal64 fpreal
Definition: SYS_Types.h:277
Container class for all geometry.
Definition: GA_Detail.h:96
virtual GA_Size insertVertex(GA_Offset ppt, GA_Size where=0)
Definition of a geometric primitive.
virtual void reparameterize(GA_ParameterizationType ptype)=0
virtual int evaluateBasis(float u, float *ubvals, int &cvoffset, unsigned du=0, int uoffset=-1) const =0
virtual int evaluateBreakpoint(int uidx, UT_Vector4 &pos, int du=0) const =0
virtual float getKnotLengths(GA_ParameterizationType ptype, UT_Array< float > &lengths) const =0
GLdouble GLdouble GLint GLint uorder
Definition: glad.h:2682
virtual int deleteVertex(GA_Size num)
static GA_PrimitiveFamilyMask buildFamilyMask()
Definition: GEO_Curve.h:434
virtual void open(int preserve_shape=0, int safe=0)
virtual int unroll(int append_pts=1)
virtual int evaluateBasisDerivs(float u, float bmatx[][GA_MAXORDER], int &cvoffset, unsigned du=0, int uoffset=-1) const =0
GLsizei GLenum GLenum GLuint GLenum GLsizei * lengths
Definition: glcorearb.h:2542
virtual void setBasisCopy(const GA_Basis *basis)=0
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)