00001 /* $NoKeywords: $ */ 00002 /* 00003 // 00004 // Copyright (c) 1993-2012 Robert McNeel & Associates. All rights reserved. 00005 // OpenNURBS, Rhinoceros, and Rhino3D are registered trademarks of Robert 00006 // McNeel & Associates. 00007 // 00008 // THIS SOFTWARE IS PROVIDED "AS IS" WITHOUT EXPRESS OR IMPLIED WARRANTY. 00009 // ALL IMPLIED WARRANTIES OF FITNESS FOR ANY PARTICULAR PURPOSE AND OF 00010 // MERCHANTABILITY ARE HEREBY DISCLAIMED. 00011 // 00012 // For complete openNURBS copyright information see <http://www.opennurbs.org>. 00013 // 00015 */ 00016 00017 #if !defined(OPENNURBS_KNOT_INC_) 00018 #define OPENNURBS_KNOT_INC_ 00019 00020 ON_DECL 00021 double ON_DomainTolerance( 00022 double, // start of domain 00023 double // end of domain 00024 ); 00025 00026 ON_DECL 00027 double ON_KnotTolerance( 00028 int, // order (>=2) 00029 int, // cv count 00030 const double*, // knot[] array 00031 int // knot index 00032 ); 00033 00034 ON_DECL 00035 double ON_SpanTolerance( 00036 int, // order (>=2) 00037 int, // cv count 00038 const double*, // knot[] array 00039 int // span index 00040 ); 00041 00042 ON_DECL 00043 int ON_KnotCount( // returns (order + cv_count - 2) 00044 int, // order (>=2) 00045 int // cv_count (>=order) 00046 ); 00047 00048 ON_DECL 00049 int ON_KnotMultiplicity( 00050 int, // order (>=2) 00051 int, // cv_count (>=order) 00052 const double*, // knot[] 00053 int // knot_index 00054 ); 00055 00056 ON_DECL 00057 int ON_KnotVectorSpanCount( 00058 int, // order (>=2) 00059 int, // cv count 00060 const double* // knot[] array 00061 ); 00062 00063 ON_DECL 00064 bool ON_GetKnotVectorSpanVector( 00065 int, // order (>=2) 00066 int, // cv count 00067 const double*, // knot[] array 00068 double* // s[] array 00069 ); 00070 00071 /* 00072 Description: 00073 Given an evaluation parameter t in the domain of a NURBS curve, 00074 ON_NurbsSpanIndex(order,cv_count,knot,t,0,0) returns the integer 00075 i such that (knot[i],...,knot[i+2*degree-1]), and 00076 (cv[i],...,cv[i+degree]) are the knots and control points that 00077 define the span of the NURBS that are used for evaluation at t. 00078 Parameters: 00079 order - [in] order >= 2 00080 cv_count - [in] cv_count >= order 00081 knot - [in] valid knot vector 00082 t - [in] evaluation parameter 00083 side - [in] determines which span is used when t is at a knot 00084 value; side = 0 for the default (from above), 00085 side = -1 means from below, and 00086 side = +1 means from above. 00087 hint - [in] Search hint, or 0 if not hint is available. 00088 Returns: 00089 Returns the index described above. 00090 */ 00091 ON_DECL 00092 int ON_NurbsSpanIndex( 00093 int order, 00094 int cv_count, 00095 const double* knot, 00096 double t, 00097 int side, 00098 int hint 00099 ); 00100 00101 ON_DECL 00102 int ON_NextNurbsSpanIndex( 00103 // returns 0: input span_index < 0 00104 // cv_count-order: input span_index = cv_count-order 00105 // -1: input span_index > cv_count-order; 00106 // otherwise next span index 00107 int order, 00108 int cv_count, 00109 const double* knot, 00110 int // current span_index 00111 ); 00112 00113 ON_DECL 00114 int ON_GetSpanIndices( // returns span count, which is one less than length of span_indices[] 00115 int order, 00116 int cv_count, 00117 const double* knot, 00118 int* // span_indices[cv_count-order+2]. 00119 //Indices of knots at end of group of mult knots 00120 //at start of span, and knot at start of group of mult knots 00121 //at end of spline. 00122 ); 00123 00124 ON_DECL 00125 double ON_SuperfluousKnot( 00126 int order, 00127 int cv_count, 00128 const double* knot, 00129 int // 0 = first superfluous knot 00130 // 1 = last superfluous knot 00131 ); 00132 00133 ON_DECL 00134 bool ON_IsKnotVectorPeriodic( 00135 int order, 00136 int cv_count, 00137 const double* knot 00138 ); 00139 00140 ON_DECL 00141 bool ON_IsKnotVectorClamped( 00142 int order, 00143 int cv_count, 00144 const double* knot, 00145 int = 2 // 0 = check left end, 1 = check right end, 2 = check both 00146 ); 00147 00148 ON_DECL 00149 bool ON_IsKnotVectorUniform( 00150 int order, 00151 int cv_count, 00152 const double* knot 00153 ); 00154 00156 // returns true if all knots have multiplicity = degree 00157 ON_DECL 00158 bool ON_KnotVectorHasBezierSpans( 00159 int order, 00160 int cv_count, 00161 const double* knot 00162 ); 00163 00164 00165 ON_DECL 00166 ON::knot_style ON_KnotVectorStyle( 00167 int order, 00168 int cv_count, 00169 const double* knot 00170 ); 00171 00172 /* 00173 Description: 00174 Set the domain of a knot vector. 00175 Parameters: 00176 order - [in] order >= 2 00177 cv_count - [in] cv_count >= order 00178 knot - [in/out] input existing knots and returns knots with new domain. 00179 t0 - [in] 00180 t1 - [in] New domain will be the interval (t0,t1). 00181 Returns: 00182 True if input is valid and the returned knot vector 00183 has the requested domain. False if the input is 00184 invalid, in which case the input knot vector is not 00185 changed. 00186 */ 00187 ON_DECL 00188 bool ON_SetKnotVectorDomain( 00189 int order, 00190 int cv_count, 00191 double* knot, 00192 double t0, 00193 double t1 00194 ); 00195 00196 ON_DECL 00197 bool ON_GetKnotVectorDomain( 00198 int, // order (>=2) 00199 int, // cv count 00200 const double*, // knot[] array 00201 double*, double* 00202 ); 00203 00204 ON_DECL 00205 bool ON_ReverseKnotVector( 00206 int, // order (>=2) 00207 int, // cv count 00208 double* // knot[] array 00209 ); 00210 00211 ON_DECL 00212 int ON_CompareKnotVector( // returns 00213 // -1: first < second 00214 // 0: first == second 00215 // +1: first > second 00216 // first knot vector 00217 int, // order (>=2) 00218 int, // cv count 00219 const double*, // knot[] array 00220 // second knot vector 00221 int, // order (>=2) 00222 int, // cv count 00223 const double* // knot[] array 00224 ); 00225 00226 ON_DECL 00227 bool ON_IsValidKnotVector( 00228 int order, 00229 int cv_count, 00230 const double* knot, 00231 ON_TextLog* text_log = 0 00232 ); 00233 00234 ON_DECL 00235 bool ON_ClampKnotVector( 00236 // Sets inital/final order-2 knots to values in 00237 // knot[order-2]/knot[cv_count-1]. 00238 int, // order (>=2) 00239 int, // cv count 00240 double*, // knot[] array 00241 int // 0 = clamp left end, 1 = right end, 2 = clamp both ends 00242 ); 00243 00244 ON_DECL 00245 bool ON_MakeKnotVectorPeriodic( 00246 // Sets inital and final order-2 knots to values 00247 // that make the knot vector periodic 00248 int, // order (>=2) 00249 int, // cv count 00250 double* // knot[] array 00251 ); 00252 00253 /* 00254 Description: 00255 Fill in knot values for a clamped uniform knot 00256 vector. 00257 Parameters: 00258 order - [in] (>=2) order (degree+1) of the NURBS 00259 cv_count - [in] (>=order) total number of control points 00260 in the NURBS. 00261 knot - [in/out] Input is an array with room for 00262 ON_KnotCount(order,cv_count) doubles. Output is 00263 a clamped uniform knot vector with domain 00264 (0, (1+cv_count-order)*delta). 00265 delta - [in] (>0, default=1.0) spacing between knots. 00266 Returns: 00267 true if successful 00268 See Also: 00269 ON_NurbsCurve::MakeClampedUniformKnotVector 00270 */ 00271 ON_DECL 00272 bool ON_MakeClampedUniformKnotVector( 00273 int order, 00274 int cv_count, 00275 double* knot, 00276 double delta = 1.0 00277 ); 00278 00279 /* 00280 Description: 00281 Fill in knot values for a clamped uniform knot 00282 vector. 00283 Parameters: 00284 order - [in] (>=2) order (degree+1) of the NURBS 00285 cv_count - [in] (>=order) total number of control points 00286 in the NURBS. 00287 knot - [in/out] Input is an array with room for 00288 ON_KnotCount(order,cv_count) doubles. Output is 00289 a periodic uniform knot vector with domain 00290 (0, (1+cv_count-order)*delta). 00291 delta - [in] (>0, default=1.0) spacing between knots. 00292 Returns: 00293 true if successful 00294 See Also: 00295 ON_NurbsCurve::MakePeriodicUniformKnotVector 00296 */ 00297 ON_DECL 00298 bool ON_MakePeriodicUniformKnotVector( 00299 int order, 00300 int cv_count, 00301 double* knot, 00302 double delta = 1.0 00303 ); 00304 00305 ON_DECL 00306 double ON_GrevilleAbcissa( // get Greville abcissae from knots 00307 int, // order (>=2) 00308 const double* // knot[] array (length = order-1) 00309 ); 00310 00311 ON_DECL 00312 bool ON_GetGrevilleAbcissae( // get Greville abcissae from knots 00313 int, // order (>=2) 00314 int, // cv count 00315 const double*, // knot[] array 00316 bool, // true for periodic case 00317 double* // g[] array has length cv_count in non-periodic case 00318 // and cv_count-order+1 in periodic case 00319 ); 00320 00321 ON_DECL 00322 bool ON_GetGrevilleKnotVector( // get knots from Greville abcissa 00323 int, // g[] array stride (>=1) 00324 const double*, // g[] array 00325 // if not periodic, length = cv_count 00326 // if periodic, length = cv_count-order+2 00327 bool, // true for periodic knots 00328 int, // order (>=2) 00329 int, // cv_count (>=order) 00330 double* // knot[cv_count+order-2] 00331 ); 00332 00333 ON_DECL 00334 bool ON_ClampKnotVector( 00335 int, // cv_dim ( = dim+1 for rational cvs ) 00336 int, // order (>=2) 00337 int, // cv_count, 00338 int, // cv_stride, 00339 double*, // cv[] NULL or array of order many cvs 00340 double*, // knot[] array with room for at least knot_multiplicity new knots 00341 int // end 0 = clamp start, 1 = clamp end, 2 = clamp both ends 00342 ); 00343 00344 /* 00345 Returns: 00346 Number of knots added. 00347 */ 00348 ON_DECL 00349 int ON_InsertKnot( 00350 double, // knot_value, 00351 int, // knot_multiplicity, (1 to order-1 including multiplicity of any existing knots) 00352 int, // cv_dim ( = dim+1 for rational cvs ) 00353 int, // order (>=2) 00354 int, // cv_count, 00355 int, // cv_stride (>=cv_dim) 00356 double*, // cv[] NULL or cv array with room for at least knot_multiplicity new cvs 00357 double*, // knot[] knot array with room for at least knot_multiplicity new knots 00358 int* // hint, optional hint about where to search for span to add knots to 00359 // pass NULL if no hint is available 00360 ); 00361 00362 /* 00363 Description: 00364 Reparameterize a rational Bezier curve. 00365 Parameters: 00366 c - [in] 00367 reparameterization constant (generally speaking, c should be > 0). 00368 The control points are adjusted so that 00369 output_bezier(t) = input_bezier(lambda(t)), where 00370 lambda(t) = c*t/( (c-1)*t + 1 ). 00371 Note that lambda(0) = 0, lambda(1) = 1, lambda'(t) > 0, 00372 lambda'(0) = c and lambda'(1) = 1/c. 00373 dim - [in] 00374 order - [in] 00375 cvstride - [in] (>= dim+1) 00376 cv - [in/out] homogeneous rational control points 00377 Returns: 00378 The cv values are changed so that 00379 output_bezier(t) = input_bezier(lambda(t)). 00380 */ 00381 ON_DECL 00382 bool ON_ReparameterizeRationalBezierCurve( 00383 double c, 00384 int dim, 00385 int order, 00386 int cvstride, 00387 double* cv 00388 ); 00389 00390 /* 00391 Description: 00392 Use a combination of scaling and reparameterization to set two rational 00393 Bezier weights to specified values. 00394 Parameters: 00395 dim - [in] 00396 order - [in] 00397 cvstride - [in] ( >= dim+1) 00398 cv - [in/out] homogeneous rational control points 00399 i0 - [in] 00400 w0 - [in] 00401 i1 - [in] 00402 w1 - [in] 00403 The i0-th cv will have weight w0 and the i1-th cv will have weight w1. 00404 If v0 and v1 are the cv's input weights, then v0, v1, w0 and w1 must 00405 all be nonzero, and w0*v0 and w1*v1 must have the same sign. 00406 Returns: 00407 true if successful 00408 Remarks: 00409 The equations 00410 s * r^i0 = w0/v0 00411 s * r^i1 = w1/v1 00412 determine the scaling and reparameterization necessary to change v0,v1 to 00413 w0,w1. 00414 00415 If the input Bezier has control vertices {B_0, ..., B_d}, then the 00416 output Bezier has control vertices {s*B_0, ... s*r^i * B_i, ..., s*r^d * B_d}. 00417 */ 00418 ON_DECL 00419 bool ON_ChangeRationalBezierCurveWeights( 00420 int dim, int order, int cvstride, double* cv, 00421 int i0, double w0, 00422 int i1, double w1 00423 ); 00424 00425 /* 00426 Description: 00427 Reparameterize a rational NURBS curve. 00428 Parameters: 00429 c - [in] 00430 reparameterization constant (generally speaking, c should be > 0). 00431 The control points and knots are adjusted so that 00432 output_nurbs(t) = input_nurbs(lambda(t)), where 00433 lambda(t) = c*t/( (c-1)*t + 1 ). 00434 Note that lambda(0) = 0, lambda(1) = 1, lambda'(t) > 0, 00435 lambda'(0) = c and lambda'(1) = 1/c. 00436 dim - [in] 00437 order - [in] 00438 cvstride - [in] (>=dim+1) 00439 cv - [in/out] homogeneous rational control points 00440 knot - [in/out] 00441 NURBS curve knots 00442 Returns: 00443 The cv values are changed so that 00444 output_bezier(t) = input_bezier(lambda(t)). 00445 See Also: 00446 ON_ChangeRationalNurbsCurveEndWeights 00447 */ 00448 ON_DECL 00449 bool ON_ReparameterizeRationalNurbsCurve( 00450 double c, 00451 int dim, 00452 int order, 00453 int cv_count, 00454 int cvstride, 00455 double* cv, 00456 double* knot 00457 ); 00458 00459 /* 00460 Description: 00461 Use a combination of scaling and reparameterization to set the end 00462 weights to the specified values. This 00463 Parameters: 00464 dim - [in] 00465 order - [in] 00466 cvstride - [in] (>=dim+1) 00467 cv - [in/out] homogeneous rational control points 00468 knot - [in/out] (output knot vector will be clamped and internal 00469 knots may be shifted.) 00470 w0 - [in] 00471 w1 - [in] 00472 The first cv will have weight w0 and the last cv will have weight w1. 00473 If v0 and v1 are the cv's input weights, then v0, v1, w0 and w1 must 00474 all be nonzero, and w0*v0 and w1*v1 must have the same sign. 00475 Returns: 00476 true if successful 00477 See Also: 00478 ON_ReparameterizeRationalNurbsCurve 00479 */ 00480 ON_DECL 00481 bool ON_ChangeRationalNurbsCurveEndWeights( 00482 int dim, 00483 int order, 00484 int cv_count, 00485 int cvstride, 00486 double* cv, 00487 double* knot, 00488 double w0, 00489 double w1 00490 ); 00491 00492 #endif