00001 /* 00002 * PROPRIETARY INFORMATION. This software is proprietary to 00003 * Side Effects Software Inc., and is not to be reproduced, 00004 * transmitted, or disclosed in any way without written permission. 00005 * 00006 * Produced by: 00007 * Cristin Barghiel 00008 * Side Effects Software Inc. 00009 * 20 Maud St. 00010 * Toronto, Ontario, M5V 2M5 00011 * Canada 00012 * 416-366-4607 00013 * 00014 * NAME: Geometry Library (C++) 00015 * 00016 * COMMENTS: 00017 * This class implements a piecewise Bezier curve defined by 00018 * a set of breakpoints, basis function, and CVs. 00019 * 00020 * 00021 */ 00022 00023 #ifndef __GEO_PrimRBezCurve_h__ 00024 #define __GEO_PrimRBezCurve_h__ 00025 00026 #include "GEO_API.h" 00027 #include "GEO_Curve.h" 00028 #include "GEO_PrimType.h" 00029 00030 class UT_Vector4; 00031 00032 class GEO_API GEO_PrimRBezCurve : public GEO_Curve { 00033 public: 00034 // Constructor that attaches this curve to detail "d". You can optionally 00035 // specify the number of vertices. 00036 GEO_PrimRBezCurve(GEO_Detail *d, unsigned int m=0) 00037 : GEO_Curve(d, (int)m) {} 00038 00039 // Trivial class destructor, virtual by inheritance. Please read the 00040 // comments on the parent class d-tor. 00041 ~GEO_PrimRBezCurve(); 00042 00043 // Given a domain value (u), store all the basis derivatives (from 0 to du 00044 // inclusive) into bmatx. Return the min index of the CVs needed 00045 // for the linear combination. The indices may exceed the number of 00046 // vertices if the curve is wrapped, so remember to use % getVertexCount(). 00047 virtual int evaluateBasisDerivs(float u,float bmatx[][GB_MAXORDER], 00048 int &cvoffset, unsigned du = 0, 00049 int uoffset = -1) const; 00050 00051 // Evaluate the basis at the given point in the domain and also return 00052 // the index of the first CV to linearly combine the basis with. The CV 00053 // index may exceed the number of vertices if the curve is wrapped, 00054 // so remember to use modulus (%). This method handles both rational and 00055 // non-rational curves. 00056 virtual int evaluateBasis(float u,float *ubvals, int &cvoffset, 00057 unsigned du=0, int uoffset=-1) const; 00058 00059 // Two flavours of a bulk curve evaluator that computes points or 00060 // derivatives inside a parametric interval determined by: 00061 // a) the u value specified in uArr. The length of the parameter array is 00062 // arrLen. b) uStart and uStop. 00063 // The functions return 0 if successful, and -1 otherwise. 00064 virtual int evaluateSegm(float *uArr, unsigned uArrLen, 00065 UT_Vector4 *pos, unsigned du=0) const; 00066 virtual bool evaluateSegm(float uStart, float uStop, 00067 unsigned nu, GEO_Vertex **results, 00068 GEO_AttributeHandleList &hlist, 00069 unsigned du=0) const; 00070 virtual int evaluateSegm(float uStart, float uStop, unsigned nu, 00071 UT_Vector4 *pos, unsigned du=0) const; 00072 virtual int evaluateSegmWAttrib(float uStart, float uStop, 00073 unsigned nu, UT_Vector4 *pos, 00074 GB_AttributeData *adata, 00075 const GB_FloatOffsets &foffsets, 00076 unsigned du=0) const; 00077 00078 // Compute the location of the breakpoint. Return 0 if OK, else -1. 00079 virtual int evaluateBreakpoint(int uidx, UT_Vector4 &pos, 00080 int du = 0) const; 00081 00082 // Another pair of curve evaluators. These take a start and a stop index 00083 // in the valid knot domain and an lod representing number of points to 00084 // be interpolated between every two breakpoints. The methods ALWAYS 00085 // interpolate the encountered breakpoints (aka "edit points"). They return 00086 // the number of points in the list or -1 if unsuccessful. Please save 00087 // yourself headaches and pass VALID start and end indices (see the 00088 // method validInterval() in GB_Basis). 00089 virtual int evaluateBreakSegm(int uStartIdx, int uStopIdx, int lod, 00090 GEO_Vertex **results, 00091 GEO_AttributeHandleList &hlist, 00092 unsigned du=0) const; 00093 virtual int evaluateBreakSegm(int uStartIdx, int uStopIdx, int lod, 00094 UT_Vector4 *pos, unsigned du=0) const; 00095 virtual int evaluateBreakSegmWAttrib(int uStartIdx, int uStopIdx, 00096 int lod, UT_Vector4 *pos, 00097 GB_AttributeData *adata, 00098 const GB_FloatOffsets &foffsets, 00099 unsigned du=0) const; 00100 00101 // Remove all repeated vertices - (only gets consecutive vertices) 00102 virtual int removeRepeatedVertices(int check_order = 0); 00103 00104 // compute the un-normalized lengths corresponding to points on the curve 00105 // evaluated at the valid knots parameter values 00106 // (ones with which lie within curve paramer domain) and store them 00107 // in the 'lengths' array. Returns the curve "length" (same as last knot). 00108 // The meaning of "length" depends on ptype, and can mean chord length, 00109 // square chord length, approximate arc length. 00110 virtual float getKnotLengths(GB_ParmType ptype, 00111 UT_FloatArray &lengths) const; 00112 00113 // Evaluate the curve over the valid parametric interval, and place the 00114 // points in the pos array. Return 0 if successful, and -1 otherwise. 00115 virtual int fillCurve(int nu, UT_Vector4 *pos) const; 00116 00117 // Given a CV index figure out the min/max indicies of the knots between 00118 // which the curve needs to be re-evaluated if the CV changes. If not 00119 // given a valid CV index, the method returns -1. Otherwise it returns 0. 00120 // If the curve wraps the domain we return will be rather large. 00121 virtual int domainRangeOfCV(int cvidx, int &mink,int &maxk) const; 00122 00123 // Given a CV index figure out the min/max breakpoints which are 00124 // affected if the CV changes. If not given a valid CV index, the 00125 // method returns -1. Otherwise it returns 0. Also returns -1 if 00126 // no breakpoints are affected. 00127 // NOTE: use % breakCount since maxbkp may be >= breakCount 00128 virtual int breakpointRangeOfCV(int cvidx, int &minbkp, 00129 int &maxbkp) const; 00130 00131 // Reparameterize the curve by changing its basis. The first breakpoint 00132 // remains unchanged. 00133 virtual void reparameterize(GB_ParmType ptype); 00134 00135 // Notify whomever needs to know that we have changed the weight or the 00136 // coordinates of cv[r]. 00137 virtual int recordChange(unsigned r); 00138 00139 // Set the closed or open flag, and make sure the basis knot vector is 00140 // consistent with the change. These functions are virtual by inheritance. 00141 // They change the number of CVs, so use them with care. Also, they do 00142 // not keep a history of changes: if you start with a closed curve 00143 // and then you open and close it again, the re-closed curve uses 00144 // 'degree-2' new CVs that have been generated for this purpose. 00145 00146 // Close up an open curve. 00147 // 00148 // If preserveShape = 1: 00149 // add extra cvs at the end to define the last span. 00150 // if rounded, 00151 // the new cvs just added will be arranged to 00152 // give a rounded appearance. 00153 // else 00154 // the new cvs just added will form a straight 00155 // line between the first and last endpoint. 00156 // If preserveShape = 0: 00157 // just grow the basis by one span, without adding any new cvs. 00158 // ignore the rounded flag. 00159 virtual void close(int rounded = 1, int preserveShape = 0); 00160 00161 // Open up a closed curve. 00162 // 00163 // If preserveShape = 1: 00164 // the open curve will have exactly the same geometry 00165 // (ie. still look closed) with the first point duplicated. 00166 // If preserveShape = 0: 00167 // the open curve will remove the last span in the basis, 00168 // thus open up a gap in the curve. 00169 // last few cvs are dangling which do not form a valid 00170 // curve segment, if the safe flag = 0. 00171 // The safe flag is to remove unneed cvs for ensuring the resulting 00172 // curve is a valid bezier curve. 00173 virtual void open(int preserveShape = 0, int safe = 0); 00174 00175 // Insert or delete vertices. The insertion methods return the index if 00176 // successful and -1 otherwise. The deletion methods return 0 if ok and 00177 // -1 otherwise. The insertion methods create the point if it does not 00178 // exist. 00179 virtual int insertVertex(GEO_Point *ppt=0, unsigned int where=0); 00180 virtual int appendVertex(GEO_Point *ppt=0); 00181 virtual int deleteVertex(GEO_Vertex &vtx); 00182 virtual int deleteVertex(unsigned int num); 00183 00184 // Delete the vertex that uses the point. 00185 virtual int ifDetachPoint(GB_Element *ppt) const; 00186 00187 // Assuming the curve is closed, "unroll" it so that the CVs that are 00188 // shared to form a wrapped curve are made unique. Also, the curve becomes 00189 // open. The base class method only flips the open flag. If the curve is 00190 // not closed, the method returns -1. Otherwise it returns 0. 00191 virtual int unroll(int append_pts = 1); 00192 00193 // Raise the number of CVs to match the newcount. The shape of the curve 00194 // (especially if parametric) should NOT change. Return 0 upon success 00195 // and -1 otherwise. start and stop define which indices to examine 00196 // if newcount is negative it is taken as a relative value. 00197 virtual int loft(int newcount, int start=-1, int stop=-1); 00198 00199 00200 // Insert a breakpoint at the given point in the domain and return its 00201 // index if successful. Return -1 in case of failure (eg. if outside the 00202 // valid domain or equal to an existing breakpoint). 00203 virtual int refine(float k, GEO_AttributeHandleList &hlist, int=0); 00204 virtual int refine (float k, int=0); 00205 virtual int refineWAttrib(float k, const GB_FloatOffsets &foffsets, 00206 int=0); 00207 00208 // Increase the order. Return 0 if successful, -1 otherwise (eg. 00209 // order cannot be increased because it's >= MAXORDER). 00210 virtual int raiseOrder(int neworder, GEO_AttributeHandleList &hl); 00211 virtual int raiseOrder (int neworder); 00212 virtual int raiseOrderWAttrib(int neworder, 00213 const GB_FloatOffsets &foffsets); 00214 00215 // Warp the curve at u by the given delta. Change 1 or 2 Cvs and possibly 00216 // insert a knot once or more as well. If a knot is inserted or we happen 00217 // to land exactly on a knot, we change only one CV. The bias makes sense 00218 // only when changing 2 CVs, and will be ignored altogether if < 0. 00219 // We return the index of the affected knot in the sequence, or -1 if 00220 // there's an error. 00221 virtual int warp(float u, const UT_Vector3 &delta, 00222 GEO_AttributeHandleList &hlist, 00223 float sharpness = 0.0f, float bias = -1.0f); 00224 virtual int warp(float u, const UT_Vector3 &delta, 00225 GB_FloatOffsets *foffsets = 0, 00226 float sharpness = 0.0f, float bias = -1.0f); 00227 00228 // Translate the CVs such that the given breakpoint change positions by 00229 // the given delta. Return -1 if something goes wrong, 0 if translation 00230 // was successful. 00231 // NOTE: uindices cannot contain any duplicates. If the curve is closed, 00232 // the first and last breakpoint are considered the same. 00233 virtual int translateBreakpoints(const UT_IntArray &uindices, 00234 const UT_Vector3 &delta, 00235 int fixbkpts = 1, 00236 GB_PointGroup *ptgroup = NULL, 00237 GEO_Delta *geodelta = 0); 00238 00239 virtual int transformBreakpoints(const UT_IntArray &uindices, 00240 const UT_Matrix4 &matx, 00241 int fixbkpts = 1, 00242 GB_PointGroup *ptgroup = NULL, 00243 GEO_Delta *geodelta = 0); 00244 00245 // Append another face to us in one of two ways: blend the two endpoints 00246 // or connect them straight or rounded. The bias ranges from 0 to 1 and is 00247 // relevant only to blending. The tolerance for blending: if 0, the two 00248 // endpoints will merge into one point with a discontinuity; if less than 00249 // 1, we insert knots into the curves to minimize the affected areas; if 1, 00250 // no refinement is done. For the non-blend case, the tolerance will 00251 // generate a span whose shape goes from round to straight; 0 tolerance 00252 // means straight connection. We return 0 if OK and -1 if error. Both 00253 // curves must be open and have the same order. 00254 virtual int attach(const GEO_Face &face, int blend = 1, 00255 float bias = .5f, float tolerance = 1.f, int=0, 00256 GB_PointGroup *ptgroup=0); 00257 00258 // Build a planar (domain) face of the same type as us and with the same 00259 // number of vertices. Copying the (x,y) values of our points to the planar 00260 // face is optional. 00261 virtual GD_Face *planar(GD_Detail &dgdp, int copyxy = 0) const; 00262 00263 // Query the primitive type. The function is virtual by inheritance. 00264 virtual unsigned getPrimitiveId(void) const; 00265 00266 // reverse the vertices of the curve, preserving shape 00267 virtual void reverse(void); 00268 00269 // If ustart and ustop are two values in the valid interval,ustart < ustop, 00270 // return the part of curve defined by ustart and ustop in a new primitive. 00271 // Return 0 if a problem is encountered. 00272 virtual GEO_Curve *extract(float ustart,float ustop) const; 00273 00274 protected: 00275 // Get a new basis of a type that matches our type: 00276 virtual GB_Basis *newBasis(void) const; 00277 00278 // Two different closing methods: 00279 void closeSharp(void); 00280 void closeRounded(void); 00281 00282 // increase order by 1. 00283 void incrementOrder(GEO_AttributeHandleList &hlist); 00284 void incrementOrder(void); 00285 void incrementOrderWAttrib(const GB_FloatOffsets &foffsets); 00286 00287 private: 00288 // Nothing. 00289 }; 00290 #endif
1.5.9