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>2020-05-28 09:04:49 +0300
committerCampbell Barton <ideasman42@gmail.com>2020-05-28 09:17:00 +0300
commit5c8ccad652197fd4473168dd2a7c2e24fca2548c (patch)
tree9788ff583f7d149cc80226e89dde2a3f5872dc6f /source/blender/bmesh
parent122cb1aea82362d1b2ff3dda4fc7d309933308be (diff)
Fix cone primitive creating duplicate vertices
Using remove double wasn't reliable as the matrix argument could cause vertices to be further apart than the threshold allowed for. This happened when adding cones using the new add tool.
Diffstat (limited to 'source/blender/bmesh')
-rw-r--r--source/blender/bmesh/operators/bmo_primitive.c57
1 files changed, 41 insertions, 16 deletions
diff --git a/source/blender/bmesh/operators/bmo_primitive.c b/source/blender/bmesh/operators/bmo_primitive.c
index 64687ac154c..d661859c8e3 100644
--- a/source/blender/bmesh/operators/bmo_primitive.c
+++ b/source/blender/bmesh/operators/bmo_primitive.c
@@ -1393,16 +1393,15 @@ void bmo_create_cone_exec(BMesh *bm, BMOperator *op)
BMVert *v1, *v2, *lastv1 = NULL, *lastv2 = NULL, *cent1, *cent2, *firstv1, *firstv2;
BMFace *f;
float vec[3], mat[4][4], phi, phid;
- float dia1 = BMO_slot_float_get(op->slots_in, "diameter1");
- float dia2 = BMO_slot_float_get(op->slots_in, "diameter2");
- float depth = BMO_slot_float_get(op->slots_in, "depth");
+ const float dia1 = BMO_slot_float_get(op->slots_in, "diameter1");
+ const float dia2 = BMO_slot_float_get(op->slots_in, "diameter2");
+ const float depth_half = 0.5f * BMO_slot_float_get(op->slots_in, "depth");
int segs = BMO_slot_int_get(op->slots_in, "segments");
const bool cap_ends = BMO_slot_bool_get(op->slots_in, "cap_ends");
const bool cap_tris = BMO_slot_bool_get(op->slots_in, "cap_tris");
const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV);
const bool calc_uvs = (cd_loop_uv_offset != -1) && BMO_slot_bool_get(op->slots_in, "calc_uvs");
- int a;
if (!segs) {
return;
@@ -1413,16 +1412,15 @@ void bmo_create_cone_exec(BMesh *bm, BMOperator *op)
phid = 2.0f * (float)M_PI / segs;
phi = 0;
- depth *= 0.5f;
if (cap_ends) {
vec[0] = vec[1] = 0.0f;
- vec[2] = -depth;
+ vec[2] = -depth_half;
mul_m4_v3(mat, vec);
cent1 = BM_vert_create(bm, vec, NULL, BM_CREATE_NOP);
vec[0] = vec[1] = 0.0f;
- vec[2] = depth;
+ vec[2] = depth_half;
mul_m4_v3(mat, vec);
cent2 = BM_vert_create(bm, vec, NULL, BM_CREATE_NOP);
@@ -1431,23 +1429,26 @@ void bmo_create_cone_exec(BMesh *bm, BMOperator *op)
BMO_vert_flag_enable(bm, cent2, VERT_MARK);
}
- for (a = 0; a < segs; a++, phi += phid) {
+ const int side_faces_len = segs - 1;
+ BMFace **side_faces = MEM_mallocN(sizeof(*side_faces) * side_faces_len, __func__);
+
+ for (int i = 0; i < segs; i++, phi += phid) {
vec[0] = dia1 * sinf(phi);
vec[1] = dia1 * cosf(phi);
- vec[2] = -depth;
+ vec[2] = -depth_half;
mul_m4_v3(mat, vec);
v1 = BM_vert_create(bm, vec, NULL, BM_CREATE_NOP);
vec[0] = dia2 * sinf(phi);
vec[1] = dia2 * cosf(phi);
- vec[2] = depth;
+ vec[2] = depth_half;
mul_m4_v3(mat, vec);
v2 = BM_vert_create(bm, vec, NULL, BM_CREATE_NOP);
BMO_vert_flag_enable(bm, v1, VERT_MARK);
BMO_vert_flag_enable(bm, v2, VERT_MARK);
- if (a) {
+ if (i) {
if (cap_ends) {
f = BM_face_create_quad_tri(bm, cent1, lastv1, v1, NULL, NULL, BM_CREATE_NOP);
if (calc_uvs) {
@@ -1466,6 +1467,7 @@ void bmo_create_cone_exec(BMesh *bm, BMOperator *op)
if (calc_uvs) {
BMO_face_flag_enable(bm, f, FACE_MARK);
}
+ side_faces[i - 1] = f;
}
else {
firstv1 = v1;
@@ -1476,10 +1478,6 @@ void bmo_create_cone_exec(BMesh *bm, BMOperator *op)
lastv2 = v2;
}
- if (!a) {
- return;
- }
-
if (cap_ends) {
f = BM_face_create_quad_tri(bm, cent1, v1, firstv1, NULL, NULL, BM_CREATE_NOP);
if (calc_uvs) {
@@ -1503,11 +1501,38 @@ void bmo_create_cone_exec(BMesh *bm, BMOperator *op)
BM_mesh_calc_uvs_cone(bm, mat, dia2, dia1, segs, cap_ends, FACE_MARK, cd_loop_uv_offset);
}
+ /* Collapse vertices at the first end. */
+ if (dia1 == 0.0f) {
+ if (cap_ends) {
+ BM_vert_kill(bm, cent1);
+ }
+ for (int i = 0; i < side_faces_len; i++) {
+ f = side_faces[i];
+ BMLoop *l = BM_FACE_FIRST_LOOP(f);
+ BM_edge_collapse(bm, l->prev->e, l->prev->v, true, true);
+ }
+ }
+
+ /* Collapse vertices at the second end. */
+ if (dia2 == 0.0f) {
+ if (cap_ends) {
+ BM_vert_kill(bm, cent2);
+ }
+ for (int i = 0; i < side_faces_len; i++) {
+ f = side_faces[i];
+ BMLoop *l = BM_FACE_FIRST_LOOP(f);
+ BM_edge_collapse(bm, l->next->e, l->next->v, true, true);
+ }
+ }
+
if (!cap_tris) {
BMO_op_callf(bm, op->flag, "dissolve_faces faces=%ff", FACE_NEW);
}
- BMO_op_callf(bm, op->flag, "remove_doubles verts=%fv dist=%f", VERT_MARK, 0.0000005 * depth);
+ if (side_faces != NULL) {
+ MEM_freeN(side_faces);
+ }
+
BMO_slot_buffer_from_enabled_flag(bm, op, op->slots_out, "verts.out", BM_VERT, VERT_MARK);
}