diff options
Diffstat (limited to 'source/blender/editors/curve/editcurve_paint.c')
-rw-r--r-- | source/blender/editors/curve/editcurve_paint.c | 93 |
1 files changed, 83 insertions, 10 deletions
diff --git a/source/blender/editors/curve/editcurve_paint.c b/source/blender/editors/curve/editcurve_paint.c index 38018541929..4d0a2fa53cd 100644 --- a/source/blender/editors/curve/editcurve_paint.c +++ b/source/blender/editors/curve/editcurve_paint.c @@ -55,6 +55,8 @@ #include "RNA_access.h" #include "RNA_define.h" +#include "RNA_enum_types.h" + #define USE_SPLINE_FIT #ifdef USE_SPLINE_FIT @@ -65,6 +67,9 @@ #define STROKE_SAMPLE_DIST_MIN_PX 3 #define STROKE_SAMPLE_DIST_MAX_PX 6 +/* Distance between start/end points to consider cyclic */ +#define STROKE_CYCLIC_DIST_PX 8 + /* -------------------------------------------------------------------- */ @@ -730,6 +735,11 @@ static void curve_draw_exec_precalc(wmOperator *op) const CurvePaintSettings *cps = &cdd->vc.scene->toolsettings->curve_paint_settings; PropertyRNA *prop; + prop = RNA_struct_find_property(op->ptr, "fit_method"); + if (!RNA_property_is_set(op->ptr, prop)) { + RNA_property_enum_set(op->ptr, prop, cps->fit_method); + } + prop = RNA_struct_find_property(op->ptr, "corner_angle"); if (!RNA_property_is_set(op->ptr, prop)) { const float corner_angle = (cps->flag & CURVE_PAINT_FLAG_CORNERS_DETECT) ? cps->corner_angle : (float)M_PI; @@ -759,6 +769,32 @@ static void curve_draw_exec_precalc(wmOperator *op) RNA_property_float_set(op->ptr, prop, error_threshold); } + prop = RNA_struct_find_property(op->ptr, "use_cyclic"); + if (!RNA_property_is_set(op->ptr, prop)) { + bool use_cyclic = false; + + if (BLI_mempool_count(cdd->stroke_elem_pool) > 2) { + BLI_mempool_iter iter; + const struct StrokeElem *selem, *selem_first, *selem_last; + + BLI_mempool_iternew(cdd->stroke_elem_pool, &iter); + selem_first = BLI_mempool_iterstep(&iter); + for (selem = BLI_mempool_iterstep(&iter); selem; selem = BLI_mempool_iterstep(&iter)) { + selem_last = selem; + } + + if (len_squared_v2v2( + selem_first->mval, + selem_last->mval) <= SQUARE(STROKE_CYCLIC_DIST_PX * U.pixelsize)) + { + use_cyclic = true; + } + } + + RNA_property_boolean_set(op->ptr, prop, use_cyclic); + } + + if ((cps->radius_taper_start != 0.0f) || (cps->radius_taper_end != 0.0f)) { @@ -868,8 +904,10 @@ static int curve_draw_exec(bContext *C, wmOperator *op) unsigned int cubic_spline_len = 0; /* error in object local space */ + const int fit_method = RNA_enum_get(op->ptr, "fit_method"); const float error_threshold = RNA_float_get(op->ptr, "error_threshold"); const float corner_angle = RNA_float_get(op->ptr, "corner_angle"); + const bool use_cyclic = RNA_boolean_get(op->ptr, "use_cyclic"); { BLI_mempool_iter iter; @@ -894,14 +932,14 @@ static int curve_draw_exec(bContext *C, wmOperator *op) unsigned int *corners = NULL; unsigned int corners_len = 0; - if (corner_angle < (float)M_PI) { + if ((fit_method == CURVE_PAINT_FIT_METHOD_SPLIT) && (corner_angle < (float)M_PI)) { /* this could be configurable... */ const float corner_radius_min = error_threshold / 8; const float corner_radius_max = error_threshold * 2; const unsigned int samples_max = 16; curve_fit_corners_detect_fl( - (const float *)coords, stroke_len, dims, + coords, stroke_len, dims, corner_radius_min, corner_radius_max, samples_max, corner_angle, &corners, &corners_len); @@ -909,13 +947,29 @@ static int curve_draw_exec(bContext *C, wmOperator *op) unsigned int *corners_index = NULL; unsigned int corners_index_len = 0; + unsigned int calc_flag = CURVE_FIT_CALC_HIGH_QUALIY; - const int result = curve_fit_cubic_to_points_fl( - coords, stroke_len, dims, error_threshold, CURVE_FIT_CALC_HIGH_QUALIY, - corners, corners_len, - &cubic_spline, &cubic_spline_len, - NULL, - &corners_index, &corners_index_len); + if ((stroke_len > 2) && use_cyclic) { + calc_flag |= CURVE_FIT_CALC_CYCLIC; + } + + int result; + if (fit_method == CURVE_PAINT_FIT_METHOD_REFIT) { + result = curve_fit_cubic_to_points_refit_fl( + coords, stroke_len, dims, error_threshold, calc_flag, + NULL, 0, corner_angle, + &cubic_spline, &cubic_spline_len, + NULL, + &corners_index, &corners_index_len); + } + else { + result = curve_fit_cubic_to_points_fl( + coords, stroke_len, dims, error_threshold, calc_flag, + corners, corners_len, + &cubic_spline, &cubic_spline_len, + NULL, + &corners_index, &corners_index_len); + } MEM_freeN(coords); if (corners) { @@ -950,11 +1004,24 @@ static int curve_draw_exec(bContext *C, wmOperator *op) if (corners_index) { /* ignore the first and last */ - for (unsigned int i = 1; i < corners_index_len - 1; i++) { + unsigned int i_start = 0, i_end = corners_index_len; + + if ((corners_index_len >= 2) && + (calc_flag & CURVE_FIT_CALC_CYCLIC) == 0) + { + i_start += 1; + i_end -= 1; + } + + for (unsigned int i = i_start; i < i_end; i++) { bezt = &nu->bezt[corners_index[i]]; bezt->h1 = bezt->h2 = HD_FREE; } } + + if (calc_flag & CURVE_FIT_CALC_CYCLIC) { + nu->flagu |= CU_NURB_CYCLIC; + } } if (corners_index) { @@ -1220,13 +1287,19 @@ void CURVE_OT_draw(wmOperatorType *ot) 0.0001f, 10.0f); RNA_def_property_ui_range(prop, 0.0, 10, 1, 4); + RNA_def_enum(ot->srna, "fit_method", rna_enum_curve_fit_method_items, CURVE_PAINT_FIT_METHOD_REFIT, + "Fit Method", ""); + prop = RNA_def_float_distance( ot->srna, "corner_angle", DEG2RADF(70.0f), 0.0f, M_PI, "Corner Angle", "", 0.0f, M_PI); RNA_def_property_subtype(prop, PROP_ANGLE); - prop = RNA_def_collection_runtime(ot->srna, "stroke", &RNA_OperatorStrokeElement, "Stroke", ""); + prop = RNA_def_boolean(ot->srna, "use_cyclic", true, "Cyclic", ""); RNA_def_property_flag(prop, PROP_SKIP_SAVE); + prop = RNA_def_collection_runtime(ot->srna, "stroke", &RNA_OperatorStrokeElement, "Stroke", ""); + RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE); + prop = RNA_def_boolean(ot->srna, "wait_for_input", true, "Wait for Input", ""); RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE); } |