Max 5 API Reference
00001 /* 00002 * jit.curve.cubicspline.c 00003 * 00004 * Copyright 2001-2005 - Cycling '74 00005 * Derek Gerstmann - derek@cycling74.com 00006 * 00007 * functor for a one-dimensional cubic spline 00008 * 00009 */ 00010 00011 #include "jit.common.h" 00012 #include "jit.functor.h" 00013 #include "jit.cubicspline.h" 00014 00015 // -------------------------------------------------------------------------- 00016 00017 typedef struct _jit_functor_curve_cubicspline_cvdata_fixed 00018 { 00019 long stepcount; 00020 long spancount; 00021 long knotcount; 00022 long *knots; 00023 t_jit_cubicspline_basismatrix_fixed matrix; 00024 } t_jit_functor_curve_cubicspline_cvdata_fixed; 00025 00026 typedef struct _jit_functor_curve_cubicspline_cvdata_float32 00027 { 00028 long stepcount; 00029 long spancount; 00030 long knotcount; 00031 float *knots; 00032 t_jit_cubicspline_basismatrix_float32 matrix; 00033 } t_jit_functor_curve_cubicspline_cvdata_float32; 00034 00035 typedef struct _jit_functor_curve_cubicspline_cvdata_float64 00036 { 00037 long stepcount; 00038 long spancount; 00039 long knotcount; 00040 double *knots; 00041 t_jit_cubicspline_basismatrix_float64 matrix; 00042 } t_jit_functor_curve_cubicspline_cvdata_float64; 00043 00044 typedef struct _jit_functor_curve_cubicspline_cvdata 00045 { 00046 t_jit_functor_curve_cubicspline_cvdata_fixed fixed; 00047 t_jit_functor_curve_cubicspline_cvdata_float32 float32; 00048 t_jit_functor_curve_cubicspline_cvdata_float64 float64; 00049 } t_jit_functor_curve_cubicspline_cvdata; 00050 00051 typedef struct _jit_functor_curve_cubicspline 00052 { 00053 t_jit_object ob; 00054 t_symbol *basis; 00055 t_jit_functor_curve_cubicspline_cvdata cvdata; 00056 } t_jit_functor_curve_cubicspline; 00057 00058 // -------------------------------------------------------------------------- 00059 00060 t_jit_object *jit_functor_curve_cubicspline_new(void); 00061 t_jit_err jit_functor_curve_cubicspline_free(t_jit_functor_curve_cubicspline *x); 00062 t_jit_err jit_functor_curve_cubicspline_setattr_knots(t_jit_functor_curve_cubicspline *x, void *attr, long argc, t_atom *argv); 00063 t_jit_err jit_functor_curve_cubicspline_setattr_basis(t_jit_functor_curve_cubicspline *x, void *attr, long argc, t_atom *argv); 00064 t_jit_err jit_functor_curve_cubicspline_recalc(t_jit_functor_curve_cubicspline *x); 00065 00066 t_jit_err jit_functor_curve_cubicspline_resize(t_jit_functor_curve_cubicspline *x, long count); 00067 t_jit_err jit_functor_curve_cubicspline_resize_fixed(t_jit_functor_curve_cubicspline *x, long count); 00068 t_jit_err jit_functor_curve_cubicspline_resize_float32(t_jit_functor_curve_cubicspline *x, long count); 00069 t_jit_err jit_functor_curve_cubicspline_resize_float64(t_jit_functor_curve_cubicspline *x, long count); 00070 00071 double *jit_functor_curve_cubicspline_getknots(t_jit_functor_curve_cubicspline *x); 00072 t_jit_err jit_functor_curve_cubicspline_getknotcount(t_jit_functor_curve_cubicspline *x, long *count); 00073 t_jit_err jit_functor_curve_cubicspline_setknot(t_jit_functor_curve_cubicspline *x, long index, double value); 00074 t_jit_err jit_functor_curve_cubicspline_getknot(t_jit_functor_curve_cubicspline *x, long index, double *value); 00075 t_jit_err jit_functor_curve_cubicspline_setbasis(t_jit_functor_curve_cubicspline *x, t_symbol *name); 00076 00077 t_jit_err jit_functor_curve_cubicspline_resize(t_jit_functor_curve_cubicspline *x, long count); 00078 00079 long jit_functor_curve_cubicspline_eval_fixed(t_jit_functor_curve_cubicspline *x, long dimcount, long *vals); 00080 float jit_functor_curve_cubicspline_eval_float32(t_jit_functor_curve_cubicspline *x, long dimcount, float *vals); 00081 double jit_functor_curve_cubicspline_eval_float64(t_jit_functor_curve_cubicspline *x, long dimcount, double *vals); 00082 00083 long jit_functor_curve_cubicspline_eval_fixed_scalar(t_jit_functor_curve_cubicspline *x, long val); 00084 float jit_functor_curve_cubicspline_eval_float32_scalar(t_jit_functor_curve_cubicspline *x, float val); 00085 double jit_functor_curve_cubicspline_eval_float64_scalar(t_jit_functor_curve_cubicspline *x, double val); 00086 00087 t_class * _jit_functor_curve_cubicspline_class; 00088 00089 // -------------------------------------------------------------------------- 00090 00091 t_jit_err jit_functor_curve_cubicspline_init(void) 00092 { 00093 t_jit_object *attr; 00094 00095 // create the class 00096 _jit_functor_curve_cubicspline_class = jit_class_new("jit_functor_curve_cubicspline", 00097 (method)jit_functor_curve_cubicspline_new,(method)jit_functor_curve_cubicspline_free, 00098 sizeof(t_jit_functor_curve_cubicspline),0L); 00099 00100 // add attribute methods 00101 attr = (t_jit_object*)jit_object_new(_jit_sym_jit_attr_offset, "basis", 00102 _jit_sym_symbol, 0, (method)0L,(method)jit_functor_curve_cubicspline_setattr_basis, 00103 calcoffset(t_jit_functor_curve_cubicspline, basis) ); 00104 jit_class_addattr(_jit_functor_curve_cubicspline_class,attr); 00105 attr = (t_jit_object*)jit_object_new(_jit_sym_jit_attr_offset, "knots", 00106 _jit_sym_float64, 0, (method)0L,(method)jit_functor_curve_cubicspline_setattr_knots, 0L ); 00107 jit_class_addattr(_jit_functor_curve_cubicspline_class,attr); 00108 00109 // add functor evaluation methods 00110 jit_class_addmethod(_jit_functor_curve_cubicspline_class, 00111 (method)jit_functor_curve_cubicspline_eval_fixed, "evalfixed", A_CANT, 0L); 00112 jit_class_addmethod(_jit_functor_curve_cubicspline_class, 00113 (method)jit_functor_curve_cubicspline_eval_float32, "evalfloat32", A_CANT, 0L); 00114 jit_class_addmethod(_jit_functor_curve_cubicspline_class, 00115 (method)jit_functor_curve_cubicspline_eval_float64, "evalfloat64", A_CANT, 0L); 00116 00117 // add data access methods 00118 jit_class_addmethod(_jit_functor_curve_cubicspline_class, 00119 (method)jit_functor_curve_cubicspline_resize, "resize", A_CANT, 0L); 00120 // jit_class_addmethod(_jit_functor_curve_cubicspline_class, 00121 // (method)jit_functor_curve_cubicspline_getknot, "getknot", A_CANT, 0L); 00122 // jit_class_addmethod(_jit_functor_curve_cubicspline_class, 00123 // (method)jit_functor_curve_cubicspline_setknot, "setknot", A_CANT, 0L); 00124 jit_class_addmethod(_jit_functor_curve_cubicspline_class, 00125 (method)jit_functor_curve_cubicspline_setbasis, "setbasis", A_CANT, 0L); 00126 // jit_class_addmethod(_jit_functor_curve_cubicspline_class, 00127 // (method)jit_functor_curve_cubicspline_getknots, "getknots", A_CANT, 0L); 00128 // jit_class_addmethod(_jit_functor_curve_cubicspline_class, 00129 // (method)jit_functor_curve_cubicspline_getknotcount, "getknotcount", A_CANT, 0L); 00130 00131 // add to functor registry and register class 00132 jit_functor_setup_class(_jit_functor_curve_cubicspline_class,"curve","cubicspline"); 00133 jit_class_register(_jit_functor_curve_cubicspline_class); 00134 return JIT_ERR_NONE; 00135 } 00136 00137 t_jit_object *jit_functor_curve_cubicspline_new(void) 00138 { 00139 t_jit_functor_curve_cubicspline *x; 00140 00141 if (x = (t_jit_functor_curve_cubicspline *)jit_object_alloc(_jit_functor_curve_cubicspline_class)) { 00142 00143 // initialization 00144 x->basis = NULL; 00145 00146 x->cvdata.fixed.knots = NULL; 00147 x->cvdata.fixed.knotcount = 0; 00148 x->cvdata.fixed.stepcount = 0; 00149 x->cvdata.fixed.spancount = 0; 00150 00151 x->cvdata.float32.knots = NULL; 00152 x->cvdata.float32.knotcount = 0; 00153 x->cvdata.float32.stepcount = 0; 00154 x->cvdata.float32.spancount = 0; 00155 00156 x->cvdata.float64.knots = NULL; 00157 x->cvdata.float64.knotcount = 0; 00158 x->cvdata.float64.stepcount = 0; 00159 x->cvdata.float64.spancount = 0; 00160 00161 jit_functor_curve_cubicspline_setbasis(x, ps_jit_cubicspline_basisname_catmullrom); 00162 jit_functor_curve_cubicspline_recalc(x); 00163 } 00164 00165 return (t_jit_object *)x; 00166 } 00167 00168 t_jit_err jit_functor_curve_cubicspline_free(t_jit_functor_curve_cubicspline *x) 00169 { 00170 if(x->cvdata.fixed.knots) 00171 jit_disposeptr((char*)x->cvdata.fixed.knots); 00172 x->cvdata.fixed.knots = NULL; 00173 00174 if(x->cvdata.float32.knots) 00175 jit_disposeptr((char*)x->cvdata.float32.knots); 00176 x->cvdata.float32.knots = NULL; 00177 00178 if(x->cvdata.float64.knots) 00179 jit_disposeptr((char*)x->cvdata.float64.knots); 00180 x->cvdata.float64.knots = NULL; 00181 00182 return JIT_ERR_NONE; 00183 } 00184 00185 t_jit_err jit_functor_curve_cubicspline_resize( 00186 t_jit_functor_curve_cubicspline *x, long count) 00187 { 00188 t_jit_err err = JIT_ERR_NONE; 00189 00190 if(x) 00191 { 00192 err = jit_functor_curve_cubicspline_resize_fixed(x, count); 00193 if(err) return err; 00194 00195 err = jit_functor_curve_cubicspline_resize_float32(x, count); 00196 if(err) return err; 00197 00198 err = jit_functor_curve_cubicspline_resize_float64(x, count); 00199 if(err) return err; 00200 } 00201 00202 return JIT_ERR_NONE; 00203 } 00204 00205 t_jit_err jit_functor_curve_cubicspline_resize_fixed( 00206 t_jit_functor_curve_cubicspline *x, long count) 00207 { 00208 long i; 00209 long *newknots; 00210 long *oldknots; 00211 00212 if(x) 00213 { 00214 // copy old knots 00215 if(x->cvdata.fixed.knots) 00216 { 00217 oldknots = x->cvdata.fixed.knots; 00218 newknots = (long*)jit_newptr(count * sizeof(long)); 00219 if(!newknots) return JIT_ERR_INVALID_PTR; 00220 00221 for(i = 0; i < x->cvdata.fixed.knotcount; i++) 00222 newknots[i] = oldknots[i]; 00223 00224 for(i = x->cvdata.fixed.knotcount; i < count; i++) 00225 newknots[i] = FloatToFixed(0.0f); 00226 00227 jit_disposeptr((char*)x->cvdata.fixed.knots); 00228 x->cvdata.fixed.knots = NULL; 00229 00230 x->cvdata.fixed.knots = newknots; 00231 x->cvdata.fixed.knotcount = count; 00232 } 00233 else 00234 { 00235 newknots = (long*)jit_newptr(count * sizeof(long)); 00236 if(!newknots) return JIT_ERR_INVALID_PTR; 00237 00238 for(i = 0; i < count; i++) 00239 newknots[i] = FloatToFixed(0.0f); 00240 00241 x->cvdata.fixed.knots = newknots; 00242 x->cvdata.fixed.knotcount = count; 00243 } 00244 } 00245 00246 return JIT_ERR_NONE; 00247 } 00248 00249 t_jit_err jit_functor_curve_cubicspline_resize_float32( 00250 t_jit_functor_curve_cubicspline *x, long count) 00251 { 00252 long i; 00253 float *newknots; 00254 float *oldknots; 00255 00256 if(x) 00257 { 00258 // copy old knots 00259 if(x->cvdata.float32.knots) 00260 { 00261 oldknots = x->cvdata.float32.knots; 00262 newknots = (float*)jit_newptr(count * sizeof(float)); 00263 if(!newknots) return JIT_ERR_INVALID_PTR; 00264 00265 for(i = 0; i < x->cvdata.float32.knotcount; i++) 00266 newknots[i] = oldknots[i]; 00267 00268 for(i = x->cvdata.float32.knotcount; i < count; i++) 00269 newknots[i] = 0.0; 00270 00271 jit_disposeptr((char*)x->cvdata.float32.knots); 00272 x->cvdata.float32.knots = NULL; 00273 00274 x->cvdata.float32.knots = newknots; 00275 x->cvdata.float32.knotcount = count; 00276 } 00277 else 00278 { 00279 newknots = (float*)jit_newptr(count * sizeof(float)); 00280 if(!newknots) return JIT_ERR_INVALID_PTR; 00281 00282 for(i = 0; i < count; i++) 00283 newknots[i] = 0.0; 00284 00285 x->cvdata.float32.knots = newknots; 00286 x->cvdata.float32.knotcount = count; 00287 } 00288 } 00289 00290 return JIT_ERR_NONE; 00291 } 00292 00293 t_jit_err jit_functor_curve_cubicspline_resize_float64( 00294 t_jit_functor_curve_cubicspline *x, long count) 00295 { 00296 long i; 00297 double *newknots; 00298 double *oldknots; 00299 00300 if(x) 00301 { 00302 // copy old knots 00303 if(x->cvdata.float64.knots) 00304 { 00305 oldknots = x->cvdata.float64.knots; 00306 newknots = (double*)jit_newptr(count * sizeof(double)); 00307 if(!newknots) return JIT_ERR_INVALID_PTR; 00308 00309 for(i = 0; i < x->cvdata.float64.knotcount; i++) 00310 newknots[i] = oldknots[i]; 00311 00312 for(i = x->cvdata.float64.knotcount; i < count; i++) 00313 newknots[i] = 0.0; 00314 00315 jit_disposeptr((char*)x->cvdata.float64.knots); 00316 x->cvdata.float64.knots = NULL; 00317 00318 x->cvdata.float64.knots = newknots; 00319 x->cvdata.float64.knotcount = count; 00320 } 00321 else 00322 { 00323 newknots = (double*)jit_newptr(count * sizeof(double)); 00324 if(!newknots) return JIT_ERR_INVALID_PTR; 00325 00326 for(i = 0; i < count; i++) 00327 newknots[i] = 0.0; 00328 00329 x->cvdata.float64.knots = newknots; 00330 x->cvdata.float64.knotcount = count; 00331 } 00332 } 00333 00334 return JIT_ERR_NONE; 00335 } 00336 00337 /* 00338 t_jit_err jit_functor_curve_cubicspline_setknot( 00339 t_jit_functor_curve_cubicspline *x, long index, double value) 00340 { 00341 t_jit_err err = JIT_ERR_NONE; 00342 00343 if(x && index >= 0) 00344 { 00345 if(x->cvdata.float64.knots && index < x->cvdata.float64.knotcount) 00346 { 00347 x->cvdata.float64.knots[index] = (double)value; 00348 } 00349 else 00350 { 00351 // resize 00352 err = jit_functor_curve_cubicspline_resize(x, index); 00353 if(err) return err; 00354 00355 // assign 00356 x->knots[index] = value; 00357 } 00358 return JIT_ERR_NONE; 00359 } 00360 00361 // invalid pointer or index 00362 return JIT_ERR_GENERIC; 00363 } 00364 */ 00365 t_jit_err jit_functor_curve_cubicspline_setknot_float32( 00366 t_jit_functor_curve_cubicspline *x, long index, float value) 00367 { 00368 t_jit_err err = JIT_ERR_NONE; 00369 00370 if(x && index >= 0) 00371 { 00372 if(x->cvdata.float32.knots && index < x->cvdata.float32.knotcount) 00373 { 00374 x->cvdata.float32.knots[index] = value; 00375 } 00376 else 00377 { 00378 // resize 00379 err = jit_functor_curve_cubicspline_resize_float32(x, index); 00380 if(err) return err; 00381 00382 // assign 00383 x->cvdata.float32.knots[index] = value; 00384 } 00385 return JIT_ERR_NONE; 00386 } 00387 00388 // invalid pointer or index 00389 return JIT_ERR_GENERIC; 00390 } 00391 00392 t_jit_err jit_functor_curve_cubicspline_setknot_float64( 00393 t_jit_functor_curve_cubicspline *x, long index, double value) 00394 { 00395 t_jit_err err = JIT_ERR_NONE; 00396 00397 if(x && index >= 0) 00398 { 00399 if(x->cvdata.float64.knots && index < x->cvdata.float64.knotcount) 00400 { 00401 x->cvdata.float64.knots[index] = value; 00402 } 00403 else 00404 { 00405 // resize 00406 err = jit_functor_curve_cubicspline_resize_float64(x, index); 00407 if(err) return err; 00408 00409 // assign 00410 x->cvdata.float64.knots[index] = value; 00411 } 00412 return JIT_ERR_NONE; 00413 } 00414 00415 // invalid pointer or index 00416 return JIT_ERR_GENERIC; 00417 } 00418 00419 /* 00420 t_jit_err jit_functor_curve_cubicspline_getknot( 00421 t_jit_functor_curve_cubicspline *x, long index, double *value) 00422 { 00423 if(x && x->knots && index < x->knotcount && index >= 0 && value) 00424 { 00425 *value = x->knots[index]; 00426 return JIT_ERR_NONE; 00427 } 00428 00429 return JIT_ERR_INVALID_PTR; 00430 00431 } 00432 00433 t_jit_err jit_functor_curve_cubicspline_getknotcount( 00434 t_jit_functor_curve_cubicspline *x, long *count) 00435 { 00436 if(x && count) 00437 { 00438 *count = x->knotcount; 00439 return JIT_ERR_NONE; 00440 } 00441 00442 return JIT_ERR_INVALID_PTR; 00443 } 00444 */ 00445 00446 t_jit_err jit_functor_curve_cubicspline_setbasis( 00447 t_jit_functor_curve_cubicspline *x, t_symbol *name) 00448 { 00449 long i, j; 00450 00451 if(x && name) 00452 { 00453 if (x->basis != name) 00454 { 00455 x->basis = name; 00456 jit_cubicspline_fillbasis_fixed(x->basis, &x->cvdata.fixed.matrix, &x->cvdata.fixed.stepcount); 00457 jit_cubicspline_fillbasis_float32(x->basis, &x->cvdata.float32.matrix, &x->cvdata.float32.stepcount); 00458 jit_cubicspline_fillbasis_float64(x->basis, &x->cvdata.float64.matrix, &x->cvdata.float64.stepcount); 00459 jit_functor_curve_cubicspline_recalc(x); 00460 } 00461 return JIT_ERR_NONE; 00462 } 00463 00464 // invalid pointer or index 00465 return JIT_ERR_GENERIC; 00466 } 00467 00468 t_jit_err jit_functor_curve_cubicspline_setattr_knots( 00469 t_jit_functor_curve_cubicspline *x, void *attr, long argc, t_atom *argv) 00470 { 00471 long i; 00472 double v; 00473 t_jit_err err; 00474 00475 if (x) { 00476 00477 // allocate mem for knot array 00478 err = jit_functor_curve_cubicspline_resize_fixed(x, argc); 00479 if(err) return err; 00480 err = jit_functor_curve_cubicspline_resize_float32(x, argc); 00481 if(err) return err; 00482 err = jit_functor_curve_cubicspline_resize_float64(x, argc); 00483 if(err) return err; 00484 00485 // copy all data values 00486 for(i = 0; i < argc; i++) { 00487 v = jit_atom_getfloat(argv + i); 00488 x->cvdata.fixed.knots[i] = DoubleToFixed(v); 00489 x->cvdata.float32.knots[i] = (float)v; 00490 x->cvdata.float64.knots[i] = (double)v; 00491 } 00492 00493 // recalc 00494 jit_functor_curve_cubicspline_recalc(x); 00495 00496 return JIT_ERR_NONE; 00497 } 00498 return JIT_ERR_INVALID_PTR; 00499 } 00500 00501 t_jit_err jit_functor_curve_cubicspline_setattr_basis( 00502 t_jit_functor_curve_cubicspline *x, void *attr, long argc, t_atom *argv) 00503 { 00504 t_symbol *v; 00505 00506 if (x) { 00507 v = jit_atom_getsym(argv); 00508 jit_functor_curve_cubicspline_setbasis(x, v); 00509 return JIT_ERR_NONE; 00510 } 00511 return JIT_ERR_INVALID_PTR; 00512 } 00513 00514 t_jit_err jit_functor_curve_cubicspline_recalc(t_jit_functor_curve_cubicspline *x) 00515 { 00516 // calculate intermediary values for efficiency 00517 if(x->cvdata.fixed.stepcount > 0) 00518 x->cvdata.fixed.spancount = ((x->cvdata.fixed.knotcount - 1) / x->cvdata.fixed.stepcount) + 1; 00519 else 00520 x->cvdata.fixed.spancount = 0; 00521 00522 if(x->cvdata.float32.stepcount > 0) 00523 x->cvdata.float32.spancount = ((x->cvdata.float32.knotcount - 1) / x->cvdata.float32.stepcount) + 1; 00524 else 00525 x->cvdata.float32.spancount = 0; 00526 00527 if(x->cvdata.float64.stepcount > 0) 00528 x->cvdata.float64.spancount = ((x->cvdata.float64.knotcount - 1) / x->cvdata.float64.stepcount) + 1; 00529 else 00530 x->cvdata.float64.spancount = 0; 00531 00532 return JIT_ERR_NONE; 00533 } 00534 00535 // -------------------------------------------------------------------------- 00536 // vector evaluation functions 00537 // -------------------------------------------------------------------------- 00538 long jit_functor_curve_cubicspline_eval_fixed( 00539 t_jit_functor_curve_cubicspline *x, long dimcount, long *vals) 00540 { 00541 return jit_functor_eval_fixed_with_float64((t_jit_object *)x,dimcount,vals, 00542 (t_jit_functor_float64_sig)jit_functor_curve_cubicspline_eval_float64); 00543 } 00544 00545 float jit_functor_curve_cubicspline_eval_float32( 00546 t_jit_functor_curve_cubicspline *x, long dimcount, float *vals) 00547 { 00548 return jit_functor_eval_float32_with_scalar_product((t_jit_object *)x,dimcount,vals, 00549 (t_jit_functor_float32_scalar_sig)jit_functor_curve_cubicspline_eval_float32_scalar); 00550 } 00551 00552 double jit_functor_curve_cubicspline_eval_float64( 00553 t_jit_functor_curve_cubicspline *x, long dimcount, double *vals) 00554 { 00555 return jit_functor_eval_float64_with_scalar_product((t_jit_object *)x,dimcount,vals, 00556 (t_jit_functor_float64_scalar_sig)jit_functor_curve_cubicspline_eval_float64_scalar); 00557 } 00558 00559 // -------------------------------------------------------------------------- 00560 // scalar evaluation functions 00561 // -------------------------------------------------------------------------- 00562 long jit_functor_curve_cubicspline_eval_fixed_scalar( 00563 t_jit_functor_curve_cubicspline *x, long val) 00564 { 00565 return jit_cubicspline_general_eval_fixed( 00566 val, x->cvdata.fixed.stepcount, x->cvdata.fixed.knotcount, 00567 x->cvdata.fixed.knots, x->cvdata.fixed.matrix); 00568 } 00569 00570 float jit_functor_curve_cubicspline_eval_float32_scalar( 00571 t_jit_functor_curve_cubicspline *x, float val) 00572 { 00573 return jit_cubicspline_general_eval_float32( 00574 val, x->cvdata.float32.stepcount, x->cvdata.float32.knotcount, 00575 x->cvdata.float32.knots, x->cvdata.float32.matrix); 00576 } 00577 00578 double jit_functor_curve_cubicspline_eval_float64_scalar( 00579 t_jit_functor_curve_cubicspline *x, double val) 00580 { 00581 return jit_cubicspline_general_eval_float64( 00582 val, x->cvdata.float32.stepcount, x->cvdata.float32.knotcount, 00583 x->cvdata.float64.knots, x->cvdata.float64.matrix); 00584 } 00585 // --------------------------------------------------------------------------
Copyright © 2008, Cycling '74