solidify: dont add poly-normal layer to the derived mesh, since this is no longer a convention.

This commit is contained in:
2013-06-12 09:35:02 +00:00
parent 8e2e590484
commit 31e667c10e
4 changed files with 52 additions and 61 deletions

View File

@@ -221,7 +221,8 @@ void BKE_mesh_calc_normals_mapping_ex(
void BKE_mesh_calc_normals_poly(
struct MVert *mverts, int numVerts,
struct MLoop *mloop, struct MPoly *mpolys,
int numLoops, int numPolys, float (*polyNors_r)[3]);
int numLoops, int numPolys, float (*polyNors_r)[3],
const bool only_face_normals);
void BKE_mesh_calc_normals(struct Mesh *me);

View File

@@ -2291,7 +2291,7 @@ void CDDM_calc_normals(DerivedMesh *dm)
}
BKE_mesh_calc_normals_poly(cddm->mvert, dm->numVertData, CDDM_get_loops(dm), CDDM_get_polys(dm),
dm->numLoopData, dm->numPolyData, poly_nors);
dm->numLoopData, dm->numPolyData, poly_nors, false);
cddm->dm.dirty &= ~DM_DIRTY_NORMALS;
}
@@ -2306,7 +2306,7 @@ void CDDM_calc_normals(DerivedMesh *dm)
cddm->mvert = CustomData_duplicate_referenced_layer(&dm->vertData, CD_MVERT, dm->numVertData);
BKE_mesh_calc_normals_poly(cddm->mvert, dm->numVertData, CDDM_get_loops(dm), CDDM_get_polys(dm),
dm->numLoopData, dm->numPolyData, NULL);
dm->numLoopData, dm->numPolyData, NULL, false);
cddm->dm.dirty &= ~DM_DIRTY_NORMALS;
}

View File

@@ -1907,7 +1907,7 @@ void BKE_mesh_calc_normals_mapping_ex(MVert *mverts, int numVerts,
if (only_face_normals == FALSE) {
/* vertex normals are optional, they require some extra calculations,
* so make them optional */
BKE_mesh_calc_normals_poly(mverts, numVerts, mloop, mpolys, numLoops, numPolys, pnors);
BKE_mesh_calc_normals_poly(mverts, numVerts, mloop, mpolys, numLoops, numPolys, pnors, false);
}
else {
/* only calc poly normals */
@@ -1994,13 +1994,24 @@ static void mesh_calc_normals_poly_accum(MPoly *mp, MLoop *ml,
}
void BKE_mesh_calc_normals_poly(MVert *mverts, int numVerts, MLoop *mloop, MPoly *mpolys,
int UNUSED(numLoops), int numPolys, float (*r_polynors)[3])
int UNUSED(numLoops), int numPolys, float (*r_polynors)[3],
const bool only_face_normals)
{
float (*pnors)[3] = r_polynors;
float (*tnorms)[3];
int i;
MPoly *mp;
if (only_face_normals) {
BLI_assert(pnors != NULL);
#pragma omp parallel for if (numPolys > BM_OMP_LIMIT)
for (i = 0; i < numPolys; i++) {
BKE_mesh_calc_poly_normal(&mpolys[i], mloop + mpolys[i].loopstart, mverts, pnors[i]);
}
return;
}
/* first go through and calculate normals for all the polys */
tnorms = MEM_callocN(sizeof(*tnorms) * numVerts, __func__);
@@ -2037,7 +2048,7 @@ void BKE_mesh_calc_normals(Mesh *mesh)
{
BKE_mesh_calc_normals_poly(mesh->mvert, mesh->totvert,
mesh->mloop, mesh->mpoly, mesh->totloop, mesh->totpoly,
NULL);
NULL, false);
}
void BKE_mesh_calc_normals_tessface(MVert *mverts, int numVerts, MFace *mfaces, int numFaces, float (*faceNors_r)[3])

View File

@@ -63,7 +63,12 @@ BLI_INLINE bool edgeref_is_init(const EdgeFaceRef *edge_ref)
return !((edge_ref->f1 == 0) && (edge_ref->f2 == 0));
}
static void dm_calc_normal(DerivedMesh *dm, float (*temp_nors)[3])
/**
* \param dm Mesh to calculate normals for.
* \param face_nors Precalculated face normals.
* \param r_vert_nors Return vert normals.
*/
static void dm_calc_normal(DerivedMesh *dm, float (*face_nors)[3], float (*r_vert_nors)[3])
{
int i, numVerts, numEdges, numFaces;
MPoly *mpoly, *mp;
@@ -71,10 +76,6 @@ static void dm_calc_normal(DerivedMesh *dm, float (*temp_nors)[3])
MEdge *medge, *ed;
MVert *mvert, *mv;
float (*face_nors)[3];
float *f_no;
bool calc_face_nors = false;
numVerts = dm->getNumVerts(dm);
numEdges = dm->getNumEdges(dm);
numFaces = dm->getNumPolys(dm);
@@ -91,12 +92,6 @@ static void dm_calc_normal(DerivedMesh *dm, float (*temp_nors)[3])
cddm->mvert = mv;
#endif
face_nors = CustomData_get_layer(&dm->polyData, CD_NORMAL);
if (!face_nors) {
calc_face_nors = true;
face_nors = CustomData_add_layer(&dm->polyData, CD_NORMAL, CD_CALLOC, NULL, numFaces);
}
mv = mvert;
mp = mpoly;
@@ -109,10 +104,6 @@ static void dm_calc_normal(DerivedMesh *dm, float (*temp_nors)[3])
for (i = 0; i < numFaces; i++, mp++) {
int j;
f_no = face_nors[i];
if (calc_face_nors)
BKE_mesh_calc_poly_normal(mp, mloop + mp->loopstart, mvert, f_no);
ml = mloop + mp->loopstart;
for (j = 0; j < mp->totloop; j++, ml++) {
@@ -155,8 +146,8 @@ static void dm_calc_normal(DerivedMesh *dm, float (*temp_nors)[3])
/* an edge without another attached- the weight on this is undefined */
copy_v3_v3(edge_normal, face_nors[edge_ref->f1]);
}
add_v3_v3(temp_nors[ed->v1], edge_normal);
add_v3_v3(temp_nors[ed->v2], edge_normal);
add_v3_v3(r_vert_nors[ed->v1], edge_normal);
add_v3_v3(r_vert_nors[ed->v2], edge_normal);
}
}
MEM_freeN(edge_ref_array);
@@ -164,8 +155,8 @@ static void dm_calc_normal(DerivedMesh *dm, float (*temp_nors)[3])
/* normalize vertex normals and assign */
for (i = 0; i < numVerts; i++, mv++) {
if (normalize_v3(temp_nors[i]) == 0.0f) {
normal_short_to_float_v3(temp_nors[i], mv->no);
if (normalize_v3(r_vert_nors[i]) == 0.0f) {
normal_short_to_float_v3(r_vert_nors[i], mv->no);
}
}
}
@@ -230,7 +221,8 @@ static DerivedMesh *applyModifier(
const unsigned int numVerts = (unsigned int)dm->getNumVerts(dm);
const unsigned int numEdges = (unsigned int)dm->getNumEdges(dm);
const unsigned int numFaces = (unsigned int)dm->getNumPolys(dm);
unsigned int numLoops = 0, newLoops = 0, newFaces = 0, newEdges = 0;
const unsigned int numLoops = (unsigned int)dm->getNumLoops(dm);
unsigned int newLoops = 0, newFaces = 0, newEdges = 0;
/* only use material offsets if we have 2 or more materials */
const short mat_nr_max = ob->totcol > 1 ? ob->totcol - 1 : 0;
@@ -251,8 +243,9 @@ static DerivedMesh *applyModifier(
char *edge_order = NULL;
float (*vert_nors)[3] = NULL;
float (*face_nors)[3] = NULL;
float (*face_nors_result)[3] = NULL;
const bool need_face_normals = (smd->flag & MOD_SOLIDIFY_NORMAL_CALC) || (smd->flag & MOD_SOLIDIFY_EVEN);
const float ofs_orig = -(((-smd->offset_fac + 1.0f) * 0.5f) * smd->offset);
const float ofs_new = smd->offset + ofs_orig;
@@ -268,14 +261,21 @@ static DerivedMesh *applyModifier(
modifier_get_vgroup(ob, dm, smd->defgrp_name, &dvert, &defgrp_index);
numLoops = (unsigned int)dm->numLoopData;
newLoops = 0;
orig_mvert = dm->getVertArray(dm);
orig_medge = dm->getEdgeArray(dm);
orig_mloop = dm->getLoopArray(dm);
orig_mpoly = dm->getPolyArray(dm);
if (need_face_normals) {
/* calculate only face normals */
face_nors = MEM_mallocN(sizeof(*face_nors) * (size_t)numFaces, __func__);
BKE_mesh_calc_normals_poly(
orig_mvert, (int)numVerts,
orig_mloop, orig_mpoly,
(int)numLoops, (int)numFaces,
face_nors, true);
}
STACK_INIT(new_vert_arr);
STACK_INIT(new_edge_arr);
@@ -355,7 +355,7 @@ static DerivedMesh *applyModifier(
if (smd->flag & MOD_SOLIDIFY_NORMAL_CALC) {
vert_nors = MEM_callocN(sizeof(float) * (size_t)numVerts * 3, "mod_solid_vno_hq");
dm_calc_normal(dm, vert_nors);
dm_calc_normal(dm, face_nors, vert_nors);
}
result = CDDM_from_template(dm,
@@ -381,9 +381,6 @@ static DerivedMesh *applyModifier(
DM_copy_poly_data(dm, result, 0, 0, (int)numFaces);
DM_copy_poly_data(dm, result, 0, (int)numFaces, (int)numFaces);
/* if the original has it, get the result so we can update it */
face_nors_result = CustomData_get_layer(&result->polyData, CD_NORMAL);
/* flip normals */
mp = mpoly + numFaces;
for (i = 0; i < dm->numPolyData; i++, mp++) {
@@ -414,10 +411,6 @@ static DerivedMesh *applyModifier(
ml2[j].e += numEdges;
ml2[j].v += numVerts;
}
if (face_nors_result) {
negate_v3_v3(face_nors_result[numFaces + i], face_nors_result[i]);
}
}
for (i = 0, ed = medge + numEdges; i < numEdges; i++, ed++) {
@@ -503,20 +496,12 @@ static DerivedMesh *applyModifier(
else {
/* make a face normal layer if not present */
const bool check_non_manifold = (smd->flag & MOD_SOLIDIFY_NORMAL_CALC) != 0;
float (*face_nors)[3];
bool face_nors_calc = false;
/* same as EM_solidify() in editmesh_lib.c */
float *vert_angles = MEM_callocN(sizeof(float) * numVerts * 2, "mod_solid_pair"); /* 2 in 1 */
float *vert_accum = vert_angles + numVerts;
unsigned int vidx;
face_nors = CustomData_get_layer(&dm->polyData, CD_NORMAL);
if (!face_nors) {
face_nors = CustomData_add_layer(&dm->polyData, CD_NORMAL, CD_CALLOC, NULL, dm->numPolyData);
face_nors_calc = true;
}
if (vert_nors == NULL) {
vert_nors = MEM_mallocN(sizeof(float) * numVerts * 3, "mod_solid_vno");
for (i = 0, mv = mvert; i < numVerts; i++, mv++) {
@@ -529,22 +514,17 @@ static DerivedMesh *applyModifier(
float nor_prev[3];
float nor_next[3];
int i_this = mp->totloop - 1;
int i_curr = mp->totloop - 1;
int i_next = 0;
ml = &mloop[mp->loopstart];
/* --- not related to angle calc --- */
if (face_nors_calc)
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);
sub_v3_v3v3(nor_prev, mvert[ml[i_curr - 1].v].co, mvert[ml[i_curr].v].co);
normalize_v3(nor_prev);
while (i_next < mp->totloop) {
float angle;
sub_v3_v3v3(nor_next, mvert[ml[i_this].v].co, mvert[ml[i_next].v].co);
sub_v3_v3v3(nor_next, mvert[ml[i_curr].v].co, mvert[ml[i_next].v].co);
normalize_v3(nor_next);
angle = angle_normalized_v3v3(nor_prev, nor_next);
@@ -554,12 +534,12 @@ static DerivedMesh *applyModifier(
angle = FLT_EPSILON;
}
vidx = ml[i_this].v;
vidx = ml[i_curr].v;
vert_accum[vidx] += angle;
/* skip 3+ face user edges */
if ((check_non_manifold == false) ||
LIKELY(((orig_medge[ml[i_this].e].flag & ME_EDGE_TMP_TAG) == 0) &&
LIKELY(((orig_medge[ml[i_curr].e].flag & ME_EDGE_TMP_TAG) == 0) &&
((orig_medge[ml[i_next].e].flag & ME_EDGE_TMP_TAG) == 0)))
{
vert_angles[vidx] += shell_angle_to_dist(angle_normalized_v3v3(vert_nors[vidx], face_nors[i])) * angle;
@@ -572,7 +552,7 @@ static DerivedMesh *applyModifier(
/* step */
copy_v3_v3(nor_prev, nor_next);
i_this = i_next;
i_curr = i_next;
i_next++;
}
}
@@ -800,10 +780,6 @@ static DerivedMesh *applyModifier(
add_v3_v3(edge_vert_nos[ed->v1], nor);
add_v3_v3(edge_vert_nos[ed->v2], nor);
if (face_nors_result) {
copy_v3_v3(face_nors_result[(numFaces * 2) + i], nor);
}
}
#endif
}
@@ -845,6 +821,9 @@ static DerivedMesh *applyModifier(
if (old_vert_arr)
MEM_freeN(old_vert_arr);
if (face_nors)
MEM_freeN(face_nors);
if (numFaces == 0 && numEdges != 0) {
modifier_setError(md, "Faces needed for useful output");
}