diff options
author | Campbell Barton <ideasman42@gmail.com> | 2018-08-20 04:10:09 +0300 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2018-08-20 04:23:40 +0300 |
commit | 537bf6af0cd80ac0ef0f55f7ab68540a09db8f37 (patch) | |
tree | 21d9e429abb7eefd0ce47ae984e6d69eb809b029 /source | |
parent | 2349273ade5b4c0362dce338462f02fcfdbfaebb (diff) |
RNA: Spline.calc_length() utility function
D1810 by @Matpi w/ edits
Diffstat (limited to 'source')
-rw-r--r-- | source/blender/blenkernel/BKE_curve.h | 11 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/curve.c | 113 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_curve.c | 2 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_curve_api.c | 21 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_internal.h | 1 |
5 files changed, 140 insertions, 8 deletions
diff --git a/source/blender/blenkernel/BKE_curve.h b/source/blender/blenkernel/BKE_curve.h index fc6e86910cf..08cff0c369d 100644 --- a/source/blender/blenkernel/BKE_curve.h +++ b/source/blender/blenkernel/BKE_curve.h @@ -156,9 +156,14 @@ struct Nurb *BKE_nurb_copy(struct Nurb *src, int pntsu, int pntsv); void BKE_nurb_test2D(struct Nurb *nu); void BKE_nurb_minmax(struct Nurb *nu, bool use_radius, float min[3], float max[3]); - -void BKE_nurb_makeFaces(struct Nurb *nu, float *coord_array, int rowstride, int resolu, int resolv); -void BKE_nurb_makeCurve(struct Nurb *nu, float *coord_array, float *tilt_array, float *radius_array, float *weight_array, int resolu, int stride); +float BKE_nurb_calc_length(const struct Nurb *nu, int resolution); + +void BKE_nurb_makeFaces( + const struct Nurb *nu, float *coord_array, + int rowstride, int resolu, int resolv); +void BKE_nurb_makeCurve( + const struct Nurb *nu, float *coord_array, float *tilt_array, float *radius_array, float *weight_array, + int resolu, int stride); unsigned int BKE_curve_calc_coords_axis_len( const unsigned int bezt_array_len, const unsigned int resolu, diff --git a/source/blender/blenkernel/intern/curve.c b/source/blender/blenkernel/intern/curve.c index 6d1d62f839c..792ba08358e 100644 --- a/source/blender/blenkernel/intern/curve.c +++ b/source/blender/blenkernel/intern/curve.c @@ -632,6 +632,107 @@ void BKE_nurb_minmax(Nurb *nu, bool use_radius, float min[3], float max[3]) } } +float BKE_nurb_calc_length(const Nurb *nu, int resolution) +{ + BezTriple *bezt, *prevbezt; + BPoint *bp, *prevbp; + int a, b; + float length = 0.0f; + int resolu = resolution ? resolution : nu->resolu; + int pntsu = nu->pntsu; + float *points, *pntsit, *prevpntsit; + + if (nu->type == CU_POLY) { + a = nu->pntsu - 1; + bp = nu->bp; + if (nu->flagu & CU_NURB_CYCLIC) { + ++a; + prevbp = nu->bp + (nu->pntsu - 1); + } + else { + prevbp = bp; + bp++; + } + + while (a--) { + length += len_v3v3(prevbp->vec, bp->vec); + prevbp = bp; + ++bp; + } + } + else if (nu->type == CU_BEZIER) { + points = MEM_mallocN(sizeof(float[3]) * (resolu + 1), "getLength_bezier"); + a = nu->pntsu - 1; + bezt = nu->bezt; + if (nu->flagu & CU_NURB_CYCLIC) { + ++a; + prevbezt = nu->bezt + (nu->pntsu - 1); + } + else { + prevbezt = bezt; + ++bezt; + } + + while (a--) { + if (prevbezt->h2 == HD_VECT && bezt->h1 == HD_VECT) { + length += len_v3v3(prevbezt->vec[1], bezt->vec[1]); + } + else { + for (int j = 0; j < 3; j++) { + BKE_curve_forward_diff_bezier( + prevbezt->vec[1][j], prevbezt->vec[2][j], + bezt->vec[0][j], bezt->vec[1][j], + points + j, resolu, 3 * sizeof(float)); + } + + prevpntsit = pntsit = points; + b = resolu; + while (b--) { + pntsit += 3; + length += len_v3v3(prevpntsit, pntsit); + prevpntsit = pntsit; + } + } + prevbezt = bezt; + ++bezt; + } + + MEM_freeN(points); + } + else if (nu->type == CU_NURBS) { + if (nu->pntsv == 1) { + /* important to zero for BKE_nurb_makeCurve. */ + points = MEM_callocN(sizeof(float[3]) * pntsu * resolu, "getLength_nurbs"); + + BKE_nurb_makeCurve( + nu, points, + NULL, NULL, NULL, + resolu, sizeof(float[3])); + + if (nu->flagu & CU_NURB_CYCLIC) { + b = pntsu * resolu + 1; + prevpntsit = points + 3 * (pntsu * resolu - 1); + pntsit = points; + } + else { + b = (pntsu - 1) * resolu; + prevpntsit = points; + pntsit = points + 3; + } + + while (--b) { + length += len_v3v3(prevpntsit, pntsit); + prevpntsit = pntsit; + pntsit += 3; + } + + MEM_freeN(points); + } + } + + return length; +} + /* be sure to call makeknots after this */ void BKE_nurb_points_add(Nurb *nu, int number) { @@ -1080,9 +1181,10 @@ static void basisNurb(float t, short order, int pnts, float *knots, float *basis } } - -void BKE_nurb_makeFaces(Nurb *nu, float *coord_array, int rowstride, int resolu, int resolv) -/* coord_array has to be (3 * 4 * resolu * resolv) in size, and zero-ed */ +/** + * \param coord_array: has to be (3 * 4 * resolu * resolv) in size, and zero-ed. + */ +void BKE_nurb_makeFaces(const Nurb *nu, float *coord_array, int rowstride, int resolu, int resolv) { BPoint *bp; float *basisu, *basis, *basisv, *sum, *fp, *in; @@ -1258,8 +1360,9 @@ void BKE_nurb_makeFaces(Nurb *nu, float *coord_array, int rowstride, int resolu, * \param tilt_array set when non-NULL * \param radius_array set when non-NULL */ -void BKE_nurb_makeCurve(Nurb *nu, float *coord_array, float *tilt_array, float *radius_array, float *weight_array, - int resolu, int stride) +void BKE_nurb_makeCurve( + const Nurb *nu, float *coord_array, float *tilt_array, float *radius_array, float *weight_array, + int resolu, int stride) { const float eps = 1e-6f; BPoint *bp; diff --git a/source/blender/makesrna/intern/rna_curve.c b/source/blender/makesrna/intern/rna_curve.c index 59fbde13ee3..233303ef613 100644 --- a/source/blender/makesrna/intern/rna_curve.c +++ b/source/blender/makesrna/intern/rna_curve.c @@ -1759,6 +1759,8 @@ static void rna_def_curve_nurb(BlenderRNA *brna) RNA_def_property_update(prop, 0, "rna_Curve_update_data"); RNA_def_struct_path_func(srna, "rna_Curve_spline_path"); + + RNA_api_curve_nurb(srna); } void RNA_def_curve(BlenderRNA *brna) diff --git a/source/blender/makesrna/intern/rna_curve_api.c b/source/blender/makesrna/intern/rna_curve_api.c index 695f1f75c16..d83a843c5c1 100644 --- a/source/blender/makesrna/intern/rna_curve_api.c +++ b/source/blender/makesrna/intern/rna_curve_api.c @@ -49,6 +49,11 @@ static void rna_Curve_transform(Curve *cu, float *mat, bool shape_keys) DAG_id_tag_update(&cu->id, 0); } +static float rna_Nurb_calc_length(Nurb *nu, int resolution_u) +{ + return BKE_nurb_calc_length(nu, resolution_u); +} + #else void RNA_api_curve(StructRNA *srna) @@ -69,4 +74,20 @@ void RNA_api_curve(StructRNA *srna) RNA_def_function_return(func, parm); } +void RNA_api_curve_nurb(StructRNA *srna) +{ + FunctionRNA *func; + PropertyRNA *parm; + + func = RNA_def_function(srna, "calc_length", "rna_Nurb_calc_length"); + RNA_def_function_ui_description(func, "Calculate spline length"); + RNA_def_int( + func, "resolution", 0, 0, 1024, "Resolution", + "Spline resolution to be used, 0 defaults to the resolution_u", 0, 64); + parm = RNA_def_float_distance( + func, "length", 0.0f, 0.0f, FLT_MAX, "Length", + "Length of the polygonaly approximated spline", 0.0f, FLT_MAX); + RNA_def_function_return(func, parm); +} + #endif diff --git a/source/blender/makesrna/intern/rna_internal.h b/source/blender/makesrna/intern/rna_internal.h index 67fbee8d0ef..c3ccdc6f446 100644 --- a/source/blender/makesrna/intern/rna_internal.h +++ b/source/blender/makesrna/intern/rna_internal.h @@ -261,6 +261,7 @@ void RNA_api_armature_edit_bone(StructRNA *srna); void RNA_api_bone(StructRNA *srna); void RNA_api_camera(StructRNA *srna); void RNA_api_curve(StructRNA *srna); +void RNA_api_curve_nurb(StructRNA *srna); void RNA_api_fcurves(StructRNA *srna); void RNA_api_drivers(StructRNA *srna); void RNA_api_image_packed_file(struct StructRNA *srna); |