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:
authorGermano Cavalcante <germano.costa@ig.com.br>2020-04-14 23:14:04 +0300
committerGermano Cavalcante <germano.costa@ig.com.br>2020-04-14 23:14:16 +0300
commit04f006ea9efec81146a6fd98756f7c2177dde9c4 (patch)
treee040fbc7c31cf022eddb7d75e6ff93a23943a23c /source/blender/editors/curve
parent47f46637be1bef9672ede0ab6795a7e9ea97fc6a (diff)
Fix T75733: Curve extrusion does not include endpoints
This error only occurs when the end points are part of a sequence of selected points.
Diffstat (limited to 'source/blender/editors/curve')
-rw-r--r--source/blender/editors/curve/editcurve.c63
1 files changed, 59 insertions, 4 deletions
diff --git a/source/blender/editors/curve/editcurve.c b/source/blender/editors/curve/editcurve.c
index 8984c090a0e..c0e5e11ac22 100644
--- a/source/blender/editors/curve/editcurve.c
+++ b/source/blender/editors/curve/editcurve.c
@@ -5175,8 +5175,11 @@ static bool ed_editcurve_extrude(Curve *cu, EditNurb *editnurb, View3D *v3d)
int new_points = 0;
int offset = 0;
bool is_prev_selected = false;
+ bool duplic_first = false;
+ bool duplic_last = false;
if (nu->type == CU_BEZIER) {
BezTriple *bezt, *bezt_prev = NULL;
+ BezTriple bezt_stack;
bool is_cyclic = false;
if (pnt_len == 1) {
/* Single point extrusion.
@@ -5188,6 +5191,22 @@ static bool ed_editcurve_extrude(Curve *cu, EditNurb *editnurb, View3D *v3d)
bezt_prev = &nu->bezt[pnt_len - 1];
is_prev_selected = BEZT_ISSEL_ANY_HIDDENHANDLES(v3d, bezt_prev);
}
+ else {
+ duplic_first = BEZT_ISSEL_ANY_HIDDENHANDLES(v3d, &nu->bezt[0]) &&
+ BEZT_ISSEL_ANY_HIDDENHANDLES(v3d, &nu->bezt[1]);
+
+ duplic_last = BEZT_ISSEL_ANY_HIDDENHANDLES(v3d, &nu->bezt[pnt_len - 2]) &&
+ BEZT_ISSEL_ANY_HIDDENHANDLES(v3d, &nu->bezt[pnt_len - 1]);
+
+ if (duplic_first) {
+ bezt_stack = nu->bezt[0];
+ BEZT_DESEL_ALL(&bezt_stack);
+ bezt_prev = &bezt_stack;
+ }
+ if (duplic_last) {
+ new_points++;
+ }
+ }
i = pnt_len;
for (bezt = &nu->bezt[0]; i--; bezt++) {
bool is_selected = BEZT_ISSEL_ANY_HIDDENHANDLES(v3d, bezt);
@@ -5212,12 +5231,18 @@ static bool ed_editcurve_extrude(Curve *cu, EditNurb *editnurb, View3D *v3d)
BLI_assert(bezt_prev == &nu->bezt[pnt_len - 1]);
BLI_assert(is_prev_selected == BEZT_ISSEL_ANY_HIDDENHANDLES(v3d, bezt_prev));
}
+ else if (duplic_first) {
+ bezt_prev = &bezt_stack;
+ is_prev_selected = false;
+ }
else {
bezt_prev = NULL;
}
BezTriple *bezt_src, *bezt_dst, *bezt_src_iter, *bezt_dst_iter;
+ const int new_len = pnt_len + new_points;
+
bezt_src = nu->bezt;
- bezt_dst = MEM_mallocN((pnt_len + new_points) * sizeof(BezTriple), __func__);
+ bezt_dst = MEM_mallocN(new_len * sizeof(BezTriple), __func__);
bezt_src_iter = &bezt_src[0];
bezt_dst_iter = &bezt_dst[0];
i = 0;
@@ -5251,7 +5276,12 @@ static bool ed_editcurve_extrude(Curve *cu, EditNurb *editnurb, View3D *v3d)
int remain = pnt_len - offset;
if (remain) {
- ED_curve_beztcpy(editnurb, bezt_dst_iter, bezt_src_iter, pnt_len - offset);
+ ED_curve_beztcpy(editnurb, bezt_dst_iter, bezt_src_iter, remain);
+ }
+
+ if (duplic_last) {
+ ED_curve_beztcpy(editnurb, &bezt_dst[new_len - 1], &bezt_src[pnt_len - 1], 1);
+ BEZT_DESEL_ALL(&bezt_dst[new_len - 1]);
}
MEM_freeN(nu->bezt);
@@ -5262,11 +5292,25 @@ static bool ed_editcurve_extrude(Curve *cu, EditNurb *editnurb, View3D *v3d)
}
else {
BPoint *bp, *bp_prev = NULL;
+ BPoint bp_stack;
if (pnt_len == 1) {
/* Single point extrusion.
* Reference a `prev_bp` to force extrude. */
bp_prev = &nu->bp[0];
}
+ else {
+ duplic_first = (nu->bp[0].f1 & SELECT) && (nu->bp[1].f1 & SELECT);
+ duplic_last = (nu->bp[pnt_len - 2].f1 & SELECT) && (nu->bp[pnt_len - 1].f1 & SELECT);
+ if (duplic_first) {
+ bp_stack = nu->bp[0];
+ bp_stack.f1 &= ~SELECT;
+ bp_prev = &bp_stack;
+ }
+ if (duplic_last) {
+ new_points++;
+ }
+ }
+
i = pnt_len;
for (bp = &nu->bp[0]; i--; bp++) {
bool is_selected = (bp->f1 & SELECT) != 0;
@@ -5282,17 +5326,23 @@ static bool ed_editcurve_extrude(Curve *cu, EditNurb *editnurb, View3D *v3d)
if (new_points) {
BPoint *bp_src, *bp_dst, *bp_src_iter, *bp_dst_iter;
+ const int new_len = pnt_len + new_points;
+
is_prev_selected = false;
if (pnt_len == 1) {
/* Single point extrusion.
* Keep `is_prev_selected` false to force extrude. */
BLI_assert(bp_prev == &nu->bp[0]);
}
+ else if (duplic_first) {
+ bp_prev = &bp_stack;
+ is_prev_selected = false;
+ }
else {
bp_prev = NULL;
}
bp_src = nu->bp;
- bp_dst = MEM_mallocN((pnt_len + new_points) * sizeof(BPoint), __func__);
+ bp_dst = MEM_mallocN(new_len * sizeof(BPoint), __func__);
bp_src_iter = &bp_src[0];
bp_dst_iter = &bp_dst[0];
i = 0;
@@ -5320,7 +5370,12 @@ static bool ed_editcurve_extrude(Curve *cu, EditNurb *editnurb, View3D *v3d)
int remain = pnt_len - offset;
if (remain) {
- ED_curve_bpcpy(editnurb, bp_dst_iter, bp_src_iter, pnt_len - offset);
+ ED_curve_bpcpy(editnurb, bp_dst_iter, bp_src_iter, remain);
+ }
+
+ if (duplic_last) {
+ ED_curve_bpcpy(editnurb, &bp_dst[new_len - 1], &bp_src[pnt_len - 1], 1);
+ bp_dst[new_len - 1].f1 &= ~SELECT;
}
MEM_freeN(nu->bp);