solidify: dont add poly-normal layer to the derived mesh, since this is no longer...
authorCampbell Barton <ideasman42@gmail.com>
Wed, 12 Jun 2013 09:35:02 +0000 (09:35 +0000)
committerCampbell Barton <ideasman42@gmail.com>
Wed, 12 Jun 2013 09:35:02 +0000 (09:35 +0000)
source/blender/blenkernel/BKE_mesh.h
source/blender/blenkernel/intern/cdderivedmesh.c
source/blender/blenkernel/intern/mesh.c
source/blender/modifiers/intern/MOD_solidify.c

index 7bb188d5ff6b732aa436d4d49a53dbad98369ef7..3054849999c8e8b09c6cfd7b90a0a174a5eabf40 100644 (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);
 
index af0dadeccab7c2a51b151bd6e03e62096a7ffda5..64d6ca6666eb58e428e953bfeb8a947af717d245 100644 (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;
 }
index 2eb318c316f2e069b543e6febd22bab9e2b6f19f..d02884f1a7bdeea94561d67bc3fd7c16395ec4ec 100644 (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])
index 2c9170522d5227f0ae20653bffa70c5299a16868..ce1896fc9719ebf9eabb5e2882b42ae8f0fd3327 100644 (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");
        }