From 5946352ae2cd3ef14d8af07f8d4bd047954b9fd1 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 30 Apr 2021 00:22:02 +1000 Subject: Fix T87779: Asymmetric position vertices in circles primitives. Incrementing a floating point value in a loop resulted in the vertex locations for circles in primitives being slightly asymmetric. --- source/blender/bmesh/operators/bmo_primitive.c | 29 +++++++++++++------------- 1 file changed, 14 insertions(+), 15 deletions(-) (limited to 'source/blender/bmesh') diff --git a/source/blender/bmesh/operators/bmo_primitive.c b/source/blender/bmesh/operators/bmo_primitive.c index a0a31ab6154..f47c8dfb405 100644 --- a/source/blender/bmesh/operators/bmo_primitive.c +++ b/source/blender/bmesh/operators/bmo_primitive.c @@ -867,19 +867,19 @@ void bmo_create_uvsphere_exec(BMesh *bm, BMOperator *op) BMIter iter; const float axis[3] = {0, 0, 1}; float vec[3], mat[4][4], cmat[3][3]; - float phi, phid; int a; BMO_slot_mat4_get(op->slots_in, "matrix", mat); - phid = 2.0f * (float)M_PI / tot; + const float phid = (float)M_PI / tot; /* phi = 0.25f * (float)M_PI; */ /* UNUSED */ /* one segment first */ - phi = 0; - phid /= 2; for (a = 0; a <= tot; a++) { /* Going in this direction, then edge extruding, makes normals face outward */ + /* Calculate with doubles for higher precision, see: T87779. */ + const float phi = M_PI * ((double)a / (double)tot); + vec[0] = 0.0; vec[1] = dia * sinf(phi); vec[2] = dia * cosf(phi); @@ -891,7 +891,6 @@ void bmo_create_uvsphere_exec(BMesh *bm, BMOperator *op) BMO_edge_flag_enable(bm, e, EDGE_ORIG); } - phi += phid; preveve = eve; } @@ -1272,7 +1271,7 @@ void bmo_create_circle_exec(BMesh *bm, BMOperator *op) const bool calc_uvs = (cd_loop_uv_offset != -1) && BMO_slot_bool_get(op->slots_in, "calc_uvs"); BMVert *v1, *lastv1 = NULL, *cent1, *firstv1 = NULL; - float vec[3], mat[4][4], phi, phid; + float vec[3], mat[4][4]; int a; if (!segs) { @@ -1281,9 +1280,6 @@ void bmo_create_circle_exec(BMesh *bm, BMOperator *op) BMO_slot_mat4_get(op->slots_in, "matrix", mat); - phid = 2.0f * (float)M_PI / segs; - phi = 0; - if (cap_ends) { zero_v3(vec); mul_m4_v3(mat, vec); @@ -1292,8 +1288,11 @@ void bmo_create_circle_exec(BMesh *bm, BMOperator *op) BMO_vert_flag_enable(bm, cent1, VERT_MARK); } - for (a = 0; a < segs; a++, phi += phid) { + for (a = 0; a < segs; a++) { /* Going this way ends up with normal(s) upward */ + + /* Calculate with doubles for higher precision, see: T87779. */ + const float phi = (2.0 * M_PI) * ((double)a / (double)segs); vec[0] = -radius * sinf(phi); vec[1] = radius * cosf(phi); vec[2] = 0.0f; @@ -1392,7 +1391,7 @@ 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 vec[3], mat[4][4]; 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"); @@ -1409,9 +1408,6 @@ void bmo_create_cone_exec(BMesh *bm, BMOperator *op) BMO_slot_mat4_get(op->slots_in, "matrix", mat); - phid = 2.0f * (float)M_PI / segs; - phi = 0; - if (cap_ends) { vec[0] = vec[1] = 0.0f; vec[2] = -depth_half; @@ -1432,7 +1428,10 @@ void bmo_create_cone_exec(BMesh *bm, BMOperator *op) 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) { + for (int i = 0; i < segs; i++) { + /* Calculate with doubles for higher precision, see: T87779. */ + const float phi = (2.0 * M_PI) * ((double)i / (double)segs); + vec[0] = dia1 * sinf(phi); vec[1] = dia1 * cosf(phi); vec[2] = -depth_half; -- cgit v1.2.3