[Bf-blender-cvs] [ea1752c] gsoc2016-improved_extrusion: Curves: Offset operator
João Araújo
noreply at git.blender.org
Wed Jul 27 01:01:28 CEST 2016
Commit: ea1752cae129cf89b141cd7dc2592b12dfec75ea
Author: João Araújo
Date: Wed Jul 27 00:00:38 2016 +0100
Branches: gsoc2016-improved_extrusion
https://developer.blender.org/rBea1752cae129cf89b141cd7dc2592b12dfec75ea
Curves: Offset operator
The operator works if there are no inflection points. Function "reverse_offset" will fix that once complete.
===================================================================
M source/blender/editors/curve/editcurve.c
===================================================================
diff --git a/source/blender/editors/curve/editcurve.c b/source/blender/editors/curve/editcurve.c
index 6275328..2542671 100644
--- a/source/blender/editors/curve/editcurve.c
+++ b/source/blender/editors/curve/editcurve.c
@@ -7451,12 +7451,50 @@ static void get_offset_vecs(BezTriple *bezt1, BezTriple *bezt2, float *r_v1, flo
MEM_freeN(helper);
}
-static void get_handles_offset_vecs(float *p1, float *p2, float *r_v1)
+static void get_handles_offset_plane(float *p1, float *p2, float *p3, float *r_v1)
+{
+ float v1[3] = {0.0, 0.0, 0.0};
+ float v2[3] = {0.0, 0.0, 0.0};
+ float v3[3] = {0.0, 0.0, 0.0};
+ float v4[3] = {0.0, 0.0, 0.0};
+ float normal[3] = {0.0, 0.0, 0.0};
+ float point_plane_normal[3] = {0.0, 0.0, 0.0};
+ sub_v3_v3v3(v1, p3, p2);
+ normalize_v3(v1);
+ sub_v3_v3v3(v2, p2, p1);
+ normalize_v3(v2);
+
+ copy_v3_v3(normal, v1);
+ add_v3_v3(normal, v2);
+
+ float plane_a[4], plane_b[4];
+ float isect_co[3], isect_no[3];
+ plane_from_point_normal_v3(plane_a, p2, normal);
+ sub_v3_v3v3(v3, p1, p2);
+ sub_v3_v3v3(v4, p3, p2);
+ cross_v3_v3v3(point_plane_normal, v3, v4);
+ plane_from_point_normal_v3(plane_b, p2, point_plane_normal);
+
+ if (isect_plane_plane_v3(plane_a, plane_b,
+ isect_co, isect_no))
+ {
+ normalize_v3(isect_no);
+ copy_v3_v3(r_v1, isect_no);
+ }
+}
+
+static bool reverse_offset(BezTriple *orig1, BezTriple *orig2, BezTriple *offset1, BezTriple *offset2)
{
+ Nurb *nu;
+ nu = MEM_callocN(sizeof(Nurb), "reverseoffset1");
+ BKE_nurb_bezierPoints_add(nu, 2);
+ memcpy(nu->bezt, orig1, sizeof(BezTriple));
+ memcpy(nu->bezt + 1, orig2, sizeof(BezTriple));
+ return 1;
}
-static int offset_curve_exec(bContext *C, wmOperator *op)
+static int offset_curve_exec(bContext *C, wmOperator *UNUSED(op))
{
Object *obedit = CTX_data_edit_object(C);
ListBase *nubase = object_editcurve_get(obedit);
@@ -7472,23 +7510,91 @@ static int offset_curve_exec(bContext *C, wmOperator *op)
float *centroid = MEM_callocN(3 * sizeof(float), "offset_curve_exec_get_centroid");
get_curve_centroid(nu, centroid);
- float *v1, *v2;
+ /* offset the first handle */
+ /* control point */
+ float *v1, *v2, *co, *p1;
v1 = MEM_callocN(3 * sizeof(float), "offset_curve_exec1");
v2 = MEM_callocN(3 * sizeof(float), "offset_curve_exec2");
- for (int i = 0; i < nu->pntsu - 1; i++)
+ co = MEM_callocN(3 * sizeof(float), "offset_curve_exec3");
+ p1 = MEM_callocN(3 * sizeof(float), "offset_curve_exec4");
+ get_offset_vecs(bezt, bezt + 1, v1, v2);
+ get_handles_offset_plane(bezt[0].vec[1], bezt[0].vec[2], bezt[1].vec[0], v2);
+ add_v3_v3(new_bezt->vec[0], v1);
+ add_v3_v3(new_bezt->vec[1], v1);
+ add_v3_v3(new_bezt->vec[2], v1);
+ copy_v3_v3(co, bezt->vec[2]);
+ add_v3_v3(co, v2);
+ int result = isect_line_line_v3(new_bezt->vec[1], new_bezt->vec[2], bezt->vec[2], co, v1, v2);
+ if (result == 1) {
+ copy_v3_v3(new_bezt->vec[2], v1);
+ }
+ copy_v3_v3(p1, new_bezt->vec[1]);
+
+ reverse_offset(bezt, bezt + 1, new_bezt, new_bezt + 1);
+ /* offset all the handles between the first and the last */
+ bezt++;
+ new_bezt++;
+ /* helpful checks */
+ ListBase temp_nubase = {NULL, NULL}, il = {NULL, NULL};
+ Nurb *check_nurb;
+ check_nurb = BKE_nurb_duplicate(nu);
+ BLI_addtail(&temp_nubase, check_nurb);
+ for (int i = 1; i < nu->pntsu - 1; i++)
{
- add_v3_v3(new_bezt->vec[0], v2);
- add_v3_v3(new_bezt->vec[1], v2);
- add_v3_v3(new_bezt->vec[2], v2);
get_offset_vecs(bezt, bezt + 1, v1, v2);
+ get_handles_offset_plane(bezt[0].vec[1], bezt[0].vec[2], bezt[1].vec[0], v2);
add_v3_v3(new_bezt->vec[0], v1);
add_v3_v3(new_bezt->vec[1], v1);
add_v3_v3(new_bezt->vec[2], v1);
+ copy_v3_v3(co, bezt->vec[2]);
+ add_v3_v3(co, v2);
+ get_intersections(&il, p1, new_bezt->vec[1], &temp_nubase);
+ if (BLI_listbase_count(&il) > 0) { /* we got the wrong direction. Fix that */
+ mul_v3_fl(v1, -2);
+ add_v3_v3(new_bezt->vec[0], v1);
+ add_v3_v3(new_bezt->vec[1], v1);
+ add_v3_v3(new_bezt->vec[2], v1);
+ for (LinkData* d = il.first; d; d = d->next) {
+ MEM_freeN(d->data);
+ }
+ BLI_freelistN(&il);
+ }
+ result = isect_line_line_v3(new_bezt->vec[1], new_bezt->vec[2], bezt->vec[2], co, v1, v2);
+ if (result == 1) {
+ copy_v3_v3(new_bezt->vec[2], v1);
+ }
+ copy_v3_v3(p1, new_bezt->vec[1]);
bezt++;
new_bezt++;
}
+
+ /* offset the last handle */
+ get_offset_vecs(bezt - 1, bezt, v1, v2);
+ get_handles_offset_plane(bezt[nu->pntsu-2].vec[2], bezt[nu->pntsu-1].vec[0], bezt[nu->pntsu-1].vec[1], v1);
+ add_v3_v3(new_bezt->vec[0], v2);
+ add_v3_v3(new_bezt->vec[1], v2);
+ add_v3_v3(new_bezt->vec[2], v2);
+ copy_v3_v3(co, bezt->vec[2]);
+ add_v3_v3(co, v2);
+ get_intersections(&il, p1, new_bezt->vec[1], &temp_nubase);
+ if (BLI_listbase_count(&il) > 0) { /* we got the wrong direction. Fix that */
+ mul_v3_fl(v2, -2);
+ add_v3_v3(new_bezt->vec[0], v2);
+ add_v3_v3(new_bezt->vec[1], v2);
+ add_v3_v3(new_bezt->vec[2], v2);
+ for (LinkData* d = il.first; d; d = d->next) {
+ MEM_freeN(d->data);
+ }
+ BLI_freelistN(&il);
+ }
+ result = isect_line_line_v3(new_bezt->vec[1], new_bezt->vec[2], bezt->vec[2], co, v1, v2);
+ if (result == 1) {
+ copy_v3_v3(new_bezt->vec[0], v1);
+ }
+
MEM_freeN(v1);
MEM_freeN(v2);
+ MEM_freeN(co);
MEM_freeN(centroid);
BKE_nurb_handles_calc(new_nu);
More information about the Bf-blender-cvs
mailing list