diff options
author | Campbell Barton <ideasman42@gmail.com> | 2012-09-25 04:20:42 +0400 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2012-09-25 04:20:42 +0400 |
commit | b0bf816ececfaf56281e1539577656df3c995aa0 (patch) | |
tree | 0e289fc19194472a88e08528efb9e8fb9947d9a1 | |
parent | 687cacfdd0aec599e56f7f5e2ed69f0bf6c61b4e (diff) |
fix [#32646] Duplifaces can have wrong orientation with ngons
concave ngons could flip the dupliface, now use the faces normal when calculating the dupli-face.
-rw-r--r-- | source/blender/blenkernel/BKE_mesh.h | 4 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/anim.c | 12 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/mesh.c | 10 | ||||
-rw-r--r-- | source/blender/blenlib/BLI_math_rotation.h | 2 | ||||
-rw-r--r-- | source/blender/blenlib/intern/math_rotation.c | 17 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_mesh.c | 2 | ||||
-rw-r--r-- | source/blender/modifiers/intern/MOD_solidify.c | 4 |
7 files changed, 32 insertions, 19 deletions
diff --git a/source/blender/blenkernel/BKE_mesh.h b/source/blender/blenkernel/BKE_mesh.h index 954fb47806b..0b082c46471 100644 --- a/source/blender/blenkernel/BKE_mesh.h +++ b/source/blender/blenkernel/BKE_mesh.h @@ -88,8 +88,8 @@ int BKE_mesh_mpoly_to_mface(struct CustomData *fdata, struct CustomData *ldata, struct CustomData *pdata, int totface, int totloop, int totpoly); /*calculates a face normal.*/ -void mesh_calc_poly_normal(struct MPoly *mpoly, struct MLoop *loopstart, - struct MVert *mvarray, float no[3]); +void BKE_mesh_calc_poly_normal(struct MPoly *mpoly, struct MLoop *loopstart, + struct MVert *mvarray, float no[3]); void BKE_mesh_calc_poly_normal_coords(struct MPoly *mpoly, struct MLoop *loopstart, const float (*vertex_coords)[3], float no[3]); diff --git a/source/blender/blenkernel/intern/anim.c b/source/blender/blenkernel/intern/anim.c index 1b301ba43b3..8dbffc5628b 100644 --- a/source/blender/blenkernel/intern/anim.c +++ b/source/blender/blenkernel/intern/anim.c @@ -1140,21 +1140,17 @@ static void face_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, floa float *v3; /* float *v4; */ /* UNUSED */ float cent[3], quat[4], mat[3][3], mat3[3][3], tmat[4][4], obmat[4][4]; + float f_no[3]; MLoop *loopstart = mloop + mp->loopstart; - if (mp->totloop < 3) { - /* highly unlikely but to be safe */ + if (UNLIKELY(mp->totloop < 3)) { continue; } else { + BKE_mesh_calc_poly_normal(mp, mloop + mp->loopstart, mvert, f_no); v1 = mvert[(mv1 = loopstart[0].v)].co; v2 = mvert[(mv2 = loopstart[1].v)].co; v3 = mvert[(mv3 = loopstart[2].v)].co; -#if 0 - if (mp->totloop > 3) { - v4 = mvert[(mv4 = loopstart[3].v)].co; - } -#endif } /* translation */ @@ -1170,7 +1166,7 @@ static void face_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, floa copy_v3_v3(obmat[3], cent); /* rotation */ - tri_to_quat(quat, v1, v2, v3); + tri_to_quat_ex(quat, v1, v2, v3, f_no); quat_to_mat3(mat, quat); /* scale */ diff --git a/source/blender/blenkernel/intern/mesh.c b/source/blender/blenkernel/intern/mesh.c index 206d80a6ff0..f0354b892b7 100644 --- a/source/blender/blenkernel/intern/mesh.c +++ b/source/blender/blenkernel/intern/mesh.c @@ -1864,7 +1864,7 @@ void BKE_mesh_calc_normals_mapping_ex(MVert *mverts, int numVerts, /* only calc poly normals */ mp = mpolys; for (i = 0; i < numPolys; i++, mp++) { - mesh_calc_poly_normal(mp, mloop + mp->loopstart, mverts, pnors[i]); + BKE_mesh_calc_poly_normal(mp, mloop + mp->loopstart, mverts, pnors[i]); } } @@ -1914,7 +1914,7 @@ void BKE_mesh_calc_normals(MVert *mverts, int numVerts, MLoop *mloop, MPoly *mpo mp = mpolys; for (i = 0; i < numPolys; i++, mp++) { - mesh_calc_poly_normal(mp, mloop + mp->loopstart, mverts, pnors[i]); + BKE_mesh_calc_poly_normal(mp, mloop + mp->loopstart, mverts, pnors[i]); ml = mloop + mp->loopstart; BLI_array_empty(vertcos); @@ -2900,8 +2900,8 @@ static void mesh_calc_ngon_normal(MPoly *mpoly, MLoop *loopstart, } } -void mesh_calc_poly_normal(MPoly *mpoly, MLoop *loopstart, - MVert *mvarray, float no[3]) +void BKE_mesh_calc_poly_normal(MPoly *mpoly, MLoop *loopstart, + MVert *mvarray, float no[3]) { if (mpoly->totloop > 4) { mesh_calc_ngon_normal(mpoly, loopstart, mvarray, no); @@ -3045,7 +3045,7 @@ float BKE_mesh_calc_poly_area(MPoly *mpoly, MLoop *loopstart, /* need normal for area_poly_v3 as well */ if (polynormal == NULL) { - mesh_calc_poly_normal(mpoly, loopstart, mvarray, no); + BKE_mesh_calc_poly_normal(mpoly, loopstart, mvarray, no); } /* finally calculate the area */ diff --git a/source/blender/blenlib/BLI_math_rotation.h b/source/blender/blenlib/BLI_math_rotation.h index 8a439c7cf7a..8260331b808 100644 --- a/source/blender/blenlib/BLI_math_rotation.h +++ b/source/blender/blenlib/BLI_math_rotation.h @@ -78,6 +78,8 @@ void quat_to_mat4(float mat[4][4], const float q[4]); void mat3_to_quat(float q[4], float mat[3][3]); void mat4_to_quat(float q[4], float mat[4][4]); +void tri_to_quat_ex(float quat[4], const float v1[3], const float v2[3], const float v3[3], + const float no_orig[3]); void tri_to_quat(float q[4], const float a[3], const float b[3], const float c[3]); void vec_to_quat(float q[4], const float vec[3], short axis, const short upflag); /* note: v1 and v2 must be normalized */ diff --git a/source/blender/blenlib/intern/math_rotation.c b/source/blender/blenlib/intern/math_rotation.c index e10b0b3298c..1392e88c168 100644 --- a/source/blender/blenlib/intern/math_rotation.c +++ b/source/blender/blenlib/intern/math_rotation.c @@ -613,13 +613,21 @@ void add_qt_qtqt(float result[4], const float quat1[4], const float quat2[4], co result[3] = quat1[3] + t * quat2[3]; } -void tri_to_quat(float quat[4], const float v1[3], const float v2[3], const float v3[3]) +/* same as tri_to_quat() but takes pre-computed normal from the triangle + * used for ngons when we know their normal */ +void tri_to_quat_ex(float quat[4], const float v1[3], const float v2[3], const float v3[3], + const float no_orig[3]) { /* imaginary x-axis, y-axis triangle is being rotated */ float vec[3], q1[4], q2[4], n[3], si, co, angle, mat[3][3], imat[3][3]; /* move z-axis to face-normal */ +#if 0 normal_tri_v3(vec, v1, v2, v3); +#else + copy_v3_v3(vec, no_orig); + (void)v3; +#endif n[0] = vec[1]; n[1] = -vec[0]; @@ -659,6 +667,13 @@ void tri_to_quat(float quat[4], const float v1[3], const float v2[3], const floa mul_qt_qtqt(quat, q1, q2); } +void tri_to_quat(float quat[4], const float v1[3], const float v2[3], const float v3[3]) +{ + float vec[3]; + normal_tri_v3(vec, v1, v2, v3); + tri_to_quat_ex(quat, v1, v2, v3, vec); +} + void print_qt(const char *str, const float q[4]) { printf("%s: %.3f %.3f %.3f %.3f\n", str, q[0], q[1], q[2], q[3]); diff --git a/source/blender/makesrna/intern/rna_mesh.c b/source/blender/makesrna/intern/rna_mesh.c index a2212eab729..59cf202a416 100644 --- a/source/blender/makesrna/intern/rna_mesh.c +++ b/source/blender/makesrna/intern/rna_mesh.c @@ -224,7 +224,7 @@ static void rna_MeshPolygon_normal_get(PointerRNA *ptr, float *values) MPoly *mp = (MPoly *)ptr->data; /* BMESH_TODO: might be faster to look for a CD_NORMALS layer and use that */ - mesh_calc_poly_normal(mp, me->mloop + mp->loopstart, me->mvert, values); + BKE_mesh_calc_poly_normal(mp, me->mloop + mp->loopstart, me->mvert, values); } static float rna_MeshPolygon_area_get(PointerRNA *ptr) diff --git a/source/blender/modifiers/intern/MOD_solidify.c b/source/blender/modifiers/intern/MOD_solidify.c index fc74b446762..035dda0c95c 100644 --- a/source/blender/modifiers/intern/MOD_solidify.c +++ b/source/blender/modifiers/intern/MOD_solidify.c @@ -107,7 +107,7 @@ static void dm_calc_normal(DerivedMesh *dm, float (*temp_nors)[3]) f_no = face_nors[i]; if (calc_face_nors) - mesh_calc_poly_normal(mp, mloop + mp->loopstart, mvert, f_no); + BKE_mesh_calc_poly_normal(mp, mloop + mp->loopstart, mvert, f_no); ml = mloop + mp->loopstart; @@ -483,7 +483,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, /* --- not related to angle calc --- */ if (face_nors_calc) - mesh_calc_poly_normal(mp, ml, mvert, face_nors[i]); + BKE_mesh_calc_poly_normal(mp, ml, mvert, face_nors[i]); /* --- end non-angle-calc section --- */ sub_v3_v3v3(nor_prev, mvert[ml[i_this - 1].v].co, mvert[ml[i_this].v].co); |