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.
This commit is contained in:
@@ -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]);
|
||||
|
@@ -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 */
|
||||
|
@@ -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 */
|
||||
|
@@ -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 */
|
||||
|
@@ -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]);
|
||||
|
@@ -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)
|
||||
|
@@ -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);
|
||||
|
Reference in New Issue
Block a user