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 spline basis. 00018 * 00019 * 00020 */ 00021 00022 #ifndef __GB_BezBasis_h__ 00023 #define __GB_BezBasis_h__ 00024 00025 #include "GB_API.h" 00026 #include <math.h> 00027 #include "GB_Basis.h" 00028 00029 class UT_Vector4Array; 00030 00031 class GB_API GB_BezBasis : public GB_Basis { 00032 public: 00033 // Class constructors. The basis is cubic by default and always valid in 00034 // terms of its order (therefore len >= 2). 00035 GB_BezBasis(unsigned len = 2, unsigned ord = 4) 00036 : GB_Basis((len>1)?len:2,(ord>1)?ord:2) {} 00037 GB_BezBasis(float *bVec, unsigned len, unsigned ord = 4) 00038 : GB_Basis(bVec, (len>1)?len:2, (ord>1)?ord:2) {} 00039 GB_BezBasis(fpreal bFirst, fpreal step, unsigned len, unsigned ord = 4) 00040 : GB_Basis(bFirst, step, (len>1)?len:2, (ord>1)?ord:2) {} 00041 00042 // Class destructor. Virtual by inheritance. 00043 virtual ~GB_BezBasis(); 00044 00045 // Evaluate on a specific domain interval, on which at least one 00046 // basis function is non-zero given domain point u. 00047 virtual void evalInterval(fpreal u, int offset, int derv, 00048 float *vals) const; 00049 00050 // Evaluate the all the derivs of the basis from 0 to derv (inclusive). 00051 void evaluateDerivMatrix(fpreal u, int offset, int derv, 00052 float bmatx[][GB_MAXORDER])const; 00053 00054 // Compute one basis function (ie. the one with the given index) 00055 // value at u. 00056 virtual fpreal computeBValue(int index, fpreal u) const; 00057 00058 // Find out if two knot sequences are similar (ie if the knot spacings 00059 // are the same all over) and their knot count is the same. We assume 00060 // "b" is a BezBasis! For a Bezier basis, the similarity condition 00061 // reduces to a simple knot count test. 00062 virtual int isSimilar(const GB_Basis &b) const; 00063 00064 // Find the breakpoint at index i, or the index of the breakpoint of 00065 // domain value 'param'. The second function returns -1 if the paramenter 00066 // is less than the 0th breakpoint; if the parameter if greater than the 00067 // last breakpoint, it returns the index of last bkp + 1. 00068 fpreal breakpnt(int i) const { return getVector()((unsigned)i); } 00069 int breakpnt(fpreal param) const; 00070 00071 // Like breakpnt(param) except it is virtual. 00072 virtual int findOffset(fpreal k, int startIdx=0) const; 00073 00074 // Compute an array of breakpoints (i.e. unique knots) in the valid 00075 // interval and return their number: 00076 virtual int breakpoints(UT_FloatArray &arr) const; 00077 virtual int breakpoints(UT_FloatArray &arr, fpreal tol) const; 00078 00079 // Return the multiplicity of a domain point or -1 if outside the domain. 00080 // "uidx" is the index of the largest breakpoint <= u. 00081 virtual int multiplicity(fpreal u, int &uidx) const; 00082 00083 // Given a domain range in the valid interval, compute the range of CVs 00084 // that will be involved in the evaluation of the curve in that range. 00085 // Since the basis doesn't know about wrapping, the endcv index might 00086 // be higher than the spline's number of CVs. 00087 virtual void cvRangeOfDomain(int ustartidx, int ustopidx, 00088 int &startcv, int &endcv) const; 00089 virtual void cvRangeOfDomain(fpreal ustart, fpreal ustop, 00090 int &startcv, int &endcv) const; 00091 00092 // Given valid breakpoint index, compute the range of CVs that have a 00093 // non-zero influence at the knot of the breakpoint. Since the basis 00094 // doesn't know about wrapping, the endcv index might be higher than the 00095 // spline's number of CVs. 00096 virtual void cvRangeOfBreakpoint(int bkp, int &startcv, 00097 int &endcv) const; 00098 00099 // Compute the idx'th greville abscissa of the breakpoint vector. The 00100 // function does not do boundary checking. 00101 virtual fpreal greville(unsigned idx, int=1, int wrapped = 0) const; 00102 00103 // Grow the length of the basis by one, and set the value of the new 00104 // breakpoint to something valid. A basis with length 0 gets a size of 2. 00105 // This method returns the index of the last element. 00106 virtual int grow(int=0); 00107 00108 // Shrink the basis by one unless the length of the basis is <= 2. 00109 // Return the new length. 00110 virtual int shrink(int=0); 00111 00112 // Attach another basis to us and grow our basis as a result. The bases 00113 // must have the same type and order. Return 0 if successful and -1 00114 // otherwise. If "overlap" is true, we overlap the beginning of b with 00115 // our end. Spreading makes sense when you can have multiple knots in the 00116 // basis, and causes identical knots to be spread within range of the 00117 // neighbouring knots. 00118 virtual int attach(const GB_Basis &b, int overlap = 1, 00119 int spread = 0); 00120 00121 // Change the size of the basis (and maybe some of its values too) to 00122 // make it a valid basis for wrapped splines. The second method applies 00123 // the reversed processs: 00124 virtual void wrap(void); 00125 virtual void unwrap(void); 00126 00127 // Reverse the breakpoints in the basis. 00128 virtual void reverse(int); 00129 00130 // Reparameterize the basis using the chord-length method, and clamp it 00131 // to the valid interval. The origin and length of the valid domain remains 00132 // unchanged. 00133 virtual void chord(UT_Vector4Array &cvs); 00134 00135 // Slide the knots found in the given range left or right by an amount at 00136 // most as large as the distance to the nearest knot outside the range. 00137 // The bias is a percentage value of the left-right distance, its default 00138 // value is 0.5 (i.e. don't change anything), and is clamped to [0,1]. 00139 // The method returns 0 if OK and -1 if out of range. 00140 virtual int slideRange(fpreal umin, fpreal umax, 00141 fpreal ubias=0.5F); 00142 00143 // Query functions redefined from the base class. 00144 virtual const char *getName(void) const; 00145 virtual unsigned getType(void) const; 00146 virtual int getDimension(void) const; 00147 00148 // Given the index of a knot (kidx) and two bounds in the knot sequence 00149 // (a and b) find out the index of the breakpoint that the knot represents 00150 // (relative to a), and possibly adjust kidx so that 00151 // knot[kidx+1] > knot[kidx]. Return -1 if not found. 00152 virtual int knotToBreakpoint(int &kidx,int a=0,int b=0) const; 00153 00154 // Return the boundaries of the valid evaluation interval: 00155 virtual void validInterval(int &a, int &b) const; 00156 00157 // Return the number of breakpoints (ie. unique knots) in the knot 00158 // vector, in the valid interval. 00159 virtual int breakCount(void) const; 00160 00161 // Validate the basis given CV information: return 1 if OK, 0 if NOK. 00162 virtual bool validate(int = 0); 00163 virtual bool validate(int cvLen, int doesWrap) const; 00164 virtual bool validate(int cvLen, int basisLen, int doesWrap) const; 00165 00166 // Return the discontinuity information for the basis at the given 00167 // parameter value u. If discont_derv is returned as -1, the curve 00168 // is infinitely differentiable here (of course, derivatives >= order 00169 // will be zero). Otherwise, discont_derv contains the lowest derivative 00170 // number that is discontinuous at this point. It also returns the u 00171 // value at the other side of the discontinuity, if such a discontinuity 00172 // exists. 00173 virtual void getDiscontinuityInfo(fpreal u, int &discont_derv, 00174 float &prev_span_u, 00175 int wrapped=0) const; 00176 00177 // Load the basis and build it to match the given parameters. 00178 virtual int save(ostream &os, int wrapped = 0, 00179 int binary = 0) const; 00180 virtual bool load(UT_IStream &is, int cvs, int wrapped = 0); 00181 protected: 00182 // Compute the values or the derivatives at a domain point in the 00183 // correct interval. The calling functions must ensure the biCoeff 00184 // matrix is large enough! 00185 void computeBezValues(fpreal u, int degree, float* vals) const; 00186 void computeBezDerivs(fpreal u,int degree,int derv,float* vals) const; 00187 00188 private: 00189 // Nothing. 00190 00191 }; 00192 00193 #endif
1.5.9