From c83848722a5c99bebe8ee3b8f363f633e08c2960 Mon Sep 17 00:00:00 2001 From: Sebastian Parborg Date: Mon, 17 Jun 2019 16:33:16 +0200 Subject: Fix T59915: Skin modifier produces inverted normals on end-cap faces when vertically aligned edge is assigned root Sometimes when the end caps pointed strait up (z axis) their faces would become inverted. It seems like the code tried to rely on a certain vertex order to always happen. However this edge case did manage to produce an order that would produce inverted cap faces. So now I introduce a normal check instead so we can be certain that the face will have the normal direction we want. Reviewed By: Jacques Lucke Differential Revision: http://developer.blender.org/D4138 --- source/blender/modifiers/intern/MOD_skin.c | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) (limited to 'source/blender/modifiers/intern/MOD_skin.c') diff --git a/source/blender/modifiers/intern/MOD_skin.c b/source/blender/modifiers/intern/MOD_skin.c index a344141bf4a..b6ab3f5b4fe 100644 --- a/source/blender/modifiers/intern/MOD_skin.c +++ b/source/blender/modifiers/intern/MOD_skin.c @@ -58,6 +58,7 @@ #include "BLI_bitmap.h" #include "BLI_heap_simple.h" #include "BLI_math.h" +#include "BLI_math_geom.h" #include "BLI_stack.h" #include "DNA_mesh_types.h" @@ -86,7 +87,7 @@ typedef enum { CAP_START = 1, CAP_END = 2, SEAM_FRAME = 4, - ROOT = 8, + FLIP_NORMAL = 8, } SkinNodeFlag; typedef struct Frame { @@ -513,12 +514,18 @@ static void end_node_frames(int v, negate_v3(mat[0]); } - /* End frame */ - create_frame(&skin_nodes[v].frames[0], mvert[v].co, rad, mat, 0); - } + Frame *frame = &skin_nodes[v].frames[0]; - if (nodes[v].flag & MVERT_SKIN_ROOT) { - skin_nodes[v].flag |= ROOT; + /* End frame */ + create_frame(frame, mvert[v].co, rad, mat, 0); + + /* The caps might need to have their normals inverted. So check if they + * need to be flipped when creating faces. */ + float normal[3]; + normal_quad_v3(normal, frame->co[0], frame->co[1], frame->co[2], frame->co[3]); + if (dot_v3v3(mat[0], normal) < 0.0f) { + skin_nodes[v].flag |= FLIP_NORMAL; + } } } @@ -1577,7 +1584,7 @@ static void skin_output_end_nodes(SkinOutput *so, SkinNode *skin_nodes, int totv } if (sn->flag & CAP_START) { - if (sn->flag & ROOT) { + if (sn->flag & FLIP_NORMAL) { add_poly(so, sn->frames[0].verts[0], sn->frames[0].verts[1], -- cgit v1.2.3