RNA: Spline.calc_length() utility function
D1810 by @Matpi w/ edits
This commit is contained in:
@@ -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]);
|
||||
float BKE_nurb_calc_length(const struct Nurb *nu, int resolution);
|
||||
|
||||
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);
|
||||
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,
|
||||
|
@@ -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;
|
||||
|
@@ -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)
|
||||
|
@@ -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
|
||||
|
@@ -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);
|
||||
|
Reference in New Issue
Block a user