Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCampbell Barton <ideasman42@gmail.com>2013-07-24 18:30:45 +0400
committerCampbell Barton <ideasman42@gmail.com>2013-07-24 18:30:45 +0400
commitdf0114a17a3b80ec30e78aa8baaa172f06bcf2da (patch)
treeeac63c62f106a181a2c2270329480ca9cfdbad3c /source/blender
parentb6f58d0ea1c2d1b3b87293da1858b370d857a481 (diff)
curve only supported radius smoothing, add smooth for tilt and weight.
Diffstat (limited to 'source/blender')
-rw-r--r--source/blender/editors/curve/curve_intern.h2
-rw-r--r--source/blender/editors/curve/curve_ops.c2
-rw-r--r--source/blender/editors/curve/editcurve.c160
3 files changed, 120 insertions, 44 deletions
diff --git a/source/blender/editors/curve/curve_intern.h b/source/blender/editors/curve/curve_intern.h
index 0521297d049..d197697e60b 100644
--- a/source/blender/editors/curve/curve_intern.h
+++ b/source/blender/editors/curve/curve_intern.h
@@ -88,7 +88,9 @@ void CURVE_OT_shade_flat(struct wmOperatorType *ot);
void CURVE_OT_tilt_clear(struct wmOperatorType *ot);
void CURVE_OT_smooth(struct wmOperatorType *ot);
+void CURVE_OT_smooth_weight(struct wmOperatorType *ot);
void CURVE_OT_smooth_radius(struct wmOperatorType *ot);
+void CURVE_OT_smooth_tilt(struct wmOperatorType *ot);
void CURVE_OT_primitive_bezier_curve_add(struct wmOperatorType *ot);
void CURVE_OT_primitive_bezier_circle_add(struct wmOperatorType *ot);
diff --git a/source/blender/editors/curve/curve_ops.c b/source/blender/editors/curve/curve_ops.c
index 5b525a089b3..2452a5d1a4b 100644
--- a/source/blender/editors/curve/curve_ops.c
+++ b/source/blender/editors/curve/curve_ops.c
@@ -112,7 +112,9 @@ void ED_operatortypes_curve(void)
WM_operatortype_append(SURFACE_OT_primitive_nurbs_surface_torus_add);
WM_operatortype_append(CURVE_OT_smooth);
+ WM_operatortype_append(CURVE_OT_smooth_weight);
WM_operatortype_append(CURVE_OT_smooth_radius);
+ WM_operatortype_append(CURVE_OT_smooth_tilt);
WM_operatortype_append(CURVE_OT_de_select_first);
WM_operatortype_append(CURVE_OT_de_select_last);
diff --git a/source/blender/editors/curve/editcurve.c b/source/blender/editors/curve/editcurve.c
index a988b2295dc..660f8098a38 100644
--- a/source/blender/editors/curve/editcurve.c
+++ b/source/blender/editors/curve/editcurve.c
@@ -2260,29 +2260,33 @@ void CURVE_OT_smooth(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
-/**************** smooth curve radius operator *************/
+/* -------------------------------------------------------------------- */
+/* Smooth radius/weight/tilt
+ *
+ * TODO: make smoothing distance based
+ * TODO: support cyclic curves
+ */
-/* TODO, make smoothing distance based */
-static int smooth_radius_exec(bContext *C, wmOperator *UNUSED(op))
+static void curve_smooth_value(ListBase *editnurb,
+ const int bezt_offsetof, const int bp_offset)
{
- Object *obedit = CTX_data_edit_object(C);
- ListBase *editnurb = object_editcurve_get(obedit);
Nurb *nu;
BezTriple *bezt;
BPoint *bp;
int a;
-
+
/* use for smoothing */
int last_sel;
int start_sel, end_sel; /* selection indices, inclusive */
float start_rad, end_rad, fac, range;
-
+
for (nu = editnurb->first; nu; nu = nu->next) {
if (nu->bezt) {
-
+#define BEZT_VALUE(bezt) (*((float *)((char *)bezt + bezt_offsetof)))
+
for (last_sel = 0; last_sel < nu->pntsu; last_sel++) {
/* loop over selection segments of a curve, smooth each */
-
+
/* Start BezTriple code, this is duplicated below for points, make sure these functions stay in sync */
start_sel = -1;
for (bezt = &nu->bezt[last_sel], a = last_sel; a < nu->pntsu; a++, bezt++) {
@@ -2299,57 +2303,60 @@ static int smooth_radius_exec(bContext *C, wmOperator *UNUSED(op))
}
end_sel = a;
}
-
+
if (start_sel == -1) {
last_sel = nu->pntsu; /* next... */
}
else {
last_sel = end_sel; /* before we modify it */
-
+
/* now blend between start and end sel */
- start_rad = end_rad = -1.0;
-
+ start_rad = end_rad = FLT_MAX;
+
if (start_sel == end_sel) {
/* simple, only 1 point selected */
- if (start_sel > 0) start_rad = nu->bezt[start_sel - 1].radius;
- if (end_sel != -1 && end_sel < nu->pntsu) end_rad = nu->bezt[start_sel + 1].radius;
-
- if (start_rad >= 0.0f && end_rad >= 0.0f) nu->bezt[start_sel].radius = (start_rad + end_rad) / 2.0f;
- else if (start_rad >= 0.0f) nu->bezt[start_sel].radius = start_rad;
- else if (end_rad >= 0.0f) nu->bezt[start_sel].radius = end_rad;
+ if (start_sel > 0) start_rad = BEZT_VALUE(&nu->bezt[start_sel - 1]);
+ if (end_sel != -1 && end_sel < nu->pntsu) end_rad = BEZT_VALUE(&nu->bezt[start_sel + 1]);
+
+ if (start_rad != FLT_MAX && end_rad >= FLT_MAX) BEZT_VALUE(&nu->bezt[start_sel]) = (start_rad + end_rad) / 2.0f;
+ else if (start_rad != FLT_MAX) BEZT_VALUE(&nu->bezt[start_sel]) = start_rad;
+ else if (end_rad != FLT_MAX) BEZT_VALUE(&nu->bezt[start_sel]) = end_rad;
}
else {
/* if endpoints selected, then use them */
if (start_sel == 0) {
- start_rad = nu->bezt[start_sel].radius;
+ start_rad = BEZT_VALUE(&nu->bezt[start_sel]);
start_sel++; /* we don't want to edit the selected endpoint */
}
else {
- start_rad = nu->bezt[start_sel - 1].radius;
+ start_rad = BEZT_VALUE(&nu->bezt[start_sel - 1]);
}
if (end_sel == nu->pntsu - 1) {
- end_rad = nu->bezt[end_sel].radius;
+ end_rad = BEZT_VALUE(&nu->bezt[end_sel]);
end_sel--; /* we don't want to edit the selected endpoint */
}
else {
- end_rad = nu->bezt[end_sel + 1].radius;
+ end_rad = BEZT_VALUE(&nu->bezt[end_sel + 1]);
}
-
+
/* Now Blend between the points */
range = (float)(end_sel - start_sel) + 2.0f;
for (bezt = &nu->bezt[start_sel], a = start_sel; a <= end_sel; a++, bezt++) {
fac = (float)(1 + a - start_sel) / range;
- bezt->radius = start_rad * (1.0f - fac) + end_rad * fac;
+ BEZT_VALUE(bezt) = start_rad * (1.0f - fac) + end_rad * fac;
}
}
}
}
+#undef BEZT_VALUE
}
else if (nu->bp) {
+#define BP_VALUE(bp) (*((float *)((char *)bp + bp_offset)))
+
/* Same as above, keep these the same! */
for (last_sel = 0; last_sel < nu->pntsu; last_sel++) {
/* loop over selection segments of a curve, smooth each */
-
+
/* Start BezTriple code, this is duplicated below for points, make sure these functions stay in sync */
start_sel = -1;
for (bp = &nu->bp[last_sel], a = last_sel; a < nu->pntsu; a++, bp++) {
@@ -2366,53 +2373,90 @@ static int smooth_radius_exec(bContext *C, wmOperator *UNUSED(op))
}
end_sel = a;
}
-
+
if (start_sel == -1) {
last_sel = nu->pntsu; /* next... */
}
else {
last_sel = end_sel; /* before we modify it */
-
+
/* now blend between start and end sel */
- start_rad = end_rad = -1.0;
-
+ start_rad = end_rad = FLT_MAX;
+
if (start_sel == end_sel) {
/* simple, only 1 point selected */
- if (start_sel > 0) start_rad = nu->bp[start_sel - 1].radius;
- if (end_sel != -1 && end_sel < nu->pntsu) end_rad = nu->bp[start_sel + 1].radius;
-
- if (start_rad >= 0.0f && end_rad >= 0.0f) nu->bp[start_sel].radius = (start_rad + end_rad) / 2;
- else if (start_rad >= 0.0f) nu->bp[start_sel].radius = start_rad;
- else if (end_rad >= 0.0f) nu->bp[start_sel].radius = end_rad;
+ if (start_sel > 0) start_rad = BP_VALUE(&nu->bp[start_sel - 1]);
+ if (end_sel != -1 && end_sel < nu->pntsu) end_rad = BP_VALUE(&nu->bp[start_sel + 1]);
+
+ if (start_rad != FLT_MAX && end_rad != FLT_MAX) BP_VALUE(&nu->bp[start_sel]) = (start_rad + end_rad) / 2;
+ else if (start_rad != FLT_MAX) BP_VALUE(&nu->bp[start_sel]) = start_rad;
+ else if (end_rad != FLT_MAX) BP_VALUE(&nu->bp[start_sel]) = end_rad;
}
else {
/* if endpoints selected, then use them */
if (start_sel == 0) {
- start_rad = nu->bp[start_sel].radius;
+ start_rad = BP_VALUE(&nu->bp[start_sel]);
start_sel++; /* we don't want to edit the selected endpoint */
}
else {
- start_rad = nu->bp[start_sel - 1].radius;
+ start_rad = BP_VALUE(&nu->bp[start_sel - 1]);
}
if (end_sel == nu->pntsu - 1) {
- end_rad = nu->bp[end_sel].radius;
+ end_rad = BP_VALUE(&nu->bp[end_sel]);
end_sel--; /* we don't want to edit the selected endpoint */
}
else {
- end_rad = nu->bp[end_sel + 1].radius;
+ end_rad = BP_VALUE(&nu->bp[end_sel + 1]);
}
-
+
/* Now Blend between the points */
range = (float)(end_sel - start_sel) + 2.0f;
for (bp = &nu->bp[start_sel], a = start_sel; a <= end_sel; a++, bp++) {
fac = (float)(1 + a - start_sel) / range;
- bp->radius = start_rad * (1.0f - fac) + end_rad * fac;
+ BP_VALUE(bp) = start_rad * (1.0f - fac) + end_rad * fac;
}
}
}
}
+#undef BP_VALUE
}
}
+}
+
+static int curve_smooth_weight_exec(bContext *C, wmOperator *UNUSED(op))
+{
+ Object *obedit = CTX_data_edit_object(C);
+ ListBase *editnurb = object_editcurve_get(obedit);
+
+ curve_smooth_value(editnurb, offsetof(BezTriple, weight), offsetof(BPoint, weight));
+
+ WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data);
+ DAG_id_tag_update(obedit->data, 0);
+
+ return OPERATOR_FINISHED;
+}
+
+void CURVE_OT_smooth_weight(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Smooth Curve Weight";
+ ot->description = "Interpolate weight of selected points";
+ ot->idname = "CURVE_OT_smooth_weight";
+
+ /* api clastbacks */
+ ot->exec = curve_smooth_weight_exec;
+ ot->poll = ED_operator_editsurfcurve;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+}
+
+static int curve_smooth_radius_exec(bContext *C, wmOperator *UNUSED(op))
+{
+ Object *obedit = CTX_data_edit_object(C);
+ ListBase *editnurb = object_editcurve_get(obedit);
+
+ curve_smooth_value(editnurb, offsetof(BezTriple, radius), offsetof(BPoint, radius));
WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data);
DAG_id_tag_update(obedit->data, 0);
@@ -2424,17 +2468,45 @@ void CURVE_OT_smooth_radius(wmOperatorType *ot)
{
/* identifiers */
ot->name = "Smooth Curve Radius";
- ot->description = "Flatten radii of selected points";
+ ot->description = "Interpolate radii of selected points";
ot->idname = "CURVE_OT_smooth_radius";
/* api clastbacks */
- ot->exec = smooth_radius_exec;
+ ot->exec = curve_smooth_radius_exec;
ot->poll = ED_operator_editsurfcurve;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
+static int curve_smooth_tilt_exec(bContext *C, wmOperator *UNUSED(op))
+{
+ Object *obedit = CTX_data_edit_object(C);
+ ListBase *editnurb = object_editcurve_get(obedit);
+
+ curve_smooth_value(editnurb, offsetof(BezTriple, alfa), offsetof(BPoint, alfa));
+
+ WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data);
+ DAG_id_tag_update(obedit->data, 0);
+
+ return OPERATOR_FINISHED;
+}
+
+void CURVE_OT_smooth_tilt(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Smooth Curve Tilt";
+ ot->description = "Interpolate tilt of selected points";
+ ot->idname = "CURVE_OT_smooth_tilt";
+
+ /* api clastbacks */
+ ot->exec = curve_smooth_tilt_exec;
+ ot->poll = ED_operator_editsurfcurve;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+}
+
/***************** selection utility *************************/
/* next == 1 -> select next */