fix [#34098] Crash after using Decimate or Remesh modifiers
[blender.git] / source / blender / blenkernel / intern / DerivedMesh.c
index 2dc01513149111cc5b57badaffcc1332d3f40673..8e740075bc64a2cf9f0203fb7e2ccc9e55982c2a 100644 (file)
@@ -169,7 +169,7 @@ static MPoly *dm_getPolyArray(DerivedMesh *dm)
 
 static MVert *dm_dupVertArray(DerivedMesh *dm)
 {
-       MVert *tmp = MEM_callocN(sizeof(*tmp) * dm->getNumVerts(dm),
+       MVert *tmp = MEM_mallocN(sizeof(*tmp) * dm->getNumVerts(dm),
                                 "dm_dupVertArray tmp");
 
        if (tmp) dm->copyVertArray(dm, tmp);
@@ -179,7 +179,7 @@ static MVert *dm_dupVertArray(DerivedMesh *dm)
 
 static MEdge *dm_dupEdgeArray(DerivedMesh *dm)
 {
-       MEdge *tmp = MEM_callocN(sizeof(*tmp) * dm->getNumEdges(dm),
+       MEdge *tmp = MEM_mallocN(sizeof(*tmp) * dm->getNumEdges(dm),
                                 "dm_dupEdgeArray tmp");
 
        if (tmp) dm->copyEdgeArray(dm, tmp);
@@ -189,7 +189,7 @@ static MEdge *dm_dupEdgeArray(DerivedMesh *dm)
 
 static MFace *dm_dupFaceArray(DerivedMesh *dm)
 {
-       MFace *tmp = MEM_callocN(sizeof(*tmp) * dm->getNumTessFaces(dm),
+       MFace *tmp = MEM_mallocN(sizeof(*tmp) * dm->getNumTessFaces(dm),
                                 "dm_dupFaceArray tmp");
 
        if (tmp) dm->copyTessFaceArray(dm, tmp);
@@ -199,7 +199,7 @@ static MFace *dm_dupFaceArray(DerivedMesh *dm)
 
 static MLoop *dm_dupLoopArray(DerivedMesh *dm)
 {
-       MLoop *tmp = MEM_callocN(sizeof(*tmp) * dm->getNumLoops(dm),
+       MLoop *tmp = MEM_mallocN(sizeof(*tmp) * dm->getNumLoops(dm),
                                 "dm_dupLoopArray tmp");
 
        if (tmp) dm->copyLoopArray(dm, tmp);
@@ -209,7 +209,7 @@ static MLoop *dm_dupLoopArray(DerivedMesh *dm)
 
 static MPoly *dm_dupPolyArray(DerivedMesh *dm)
 {
-       MPoly *tmp = MEM_callocN(sizeof(*tmp) * dm->getNumPolys(dm),
+       MPoly *tmp = MEM_mallocN(sizeof(*tmp) * dm->getNumPolys(dm),
                                 "dm_dupPolyArray tmp");
 
        if (tmp) dm->copyPolyArray(dm, tmp);
@@ -313,6 +313,8 @@ void DM_from_template(DerivedMesh *dm, DerivedMesh *source, DerivedMeshType type
        CustomData_copy(&source->polyData, &dm->polyData, CD_MASK_DERIVEDMESH,
                        CD_CALLOC, numPolys);
 
+       dm->cd_flag = source->cd_flag;
+
        dm->type = type;
        dm->numVertData = numVerts;
        dm->numEdgeData = numEdges;
@@ -483,11 +485,13 @@ void DM_to_mesh(DerivedMesh *dm, Mesh *me, Object *ob)
        totedge = tmp.totedge = dm->getNumEdges(dm);
        totloop = tmp.totloop = dm->getNumLoops(dm);
        totpoly = tmp.totpoly = dm->getNumPolys(dm);
+       tmp.totface = 0;
 
        CustomData_copy(&dm->vertData, &tmp.vdata, CD_MASK_MESH, CD_DUPLICATE, totvert);
        CustomData_copy(&dm->edgeData, &tmp.edata, CD_MASK_MESH, CD_DUPLICATE, totedge);
        CustomData_copy(&dm->loopData, &tmp.ldata, CD_MASK_MESH, CD_DUPLICATE, totloop);
        CustomData_copy(&dm->polyData, &tmp.pdata, CD_MASK_MESH, CD_DUPLICATE, totpoly);
+       me->cd_flag = dm->cd_flag;
 
        if (CustomData_has_layer(&dm->vertData, CD_SHAPEKEY)) {
                KeyBlock *kb;
@@ -538,9 +542,10 @@ void DM_to_mesh(DerivedMesh *dm, Mesh *me, Object *ob)
        }
 
        /* yes, must be before _and_ after tessellate */
-       mesh_update_customdata_pointers(&tmp, TRUE);
+       mesh_update_customdata_pointers(&tmp, false);
 
-       BKE_mesh_tessface_calc(&tmp);
+       /* since 2.65 caller must do! */
+       // BKE_mesh_tessface_calc(&tmp);
 
        CustomData_free(&me->vdata, me->totvert);
        CustomData_free(&me->edata, me->totedge);
@@ -557,6 +562,13 @@ void DM_to_mesh(DerivedMesh *dm, Mesh *me, Object *ob)
                tmp.key = NULL;
        }
 
+       /* Clear selection history */
+       tmp.mselect = NULL;
+       tmp.totselect = 0;
+       if (me->mselect) {
+               MEM_freeN(me->mselect);
+       }
+
        *me = tmp;
 }
 
@@ -569,7 +581,7 @@ void DM_to_meshkey(DerivedMesh *dm, Mesh *me, KeyBlock *kb)
        if (totvert == 0 || me->totvert == 0 || me->totvert != totvert) return;
        
        if (kb->data) MEM_freeN(kb->data);
-       kb->data = MEM_callocN(me->key->elemsize * me->totvert, "kb->data");
+       kb->data = MEM_mallocN(me->key->elemsize * me->totvert, "kb->data");
        kb->totelem = totvert;
        
        fp = kb->data;
@@ -1340,6 +1352,7 @@ static void mesh_calc_modifiers(Scene *scene, Object *ob, float (*inputVertexCos
        MultiresModifierData *mmd = get_multires_modifier(scene, ob, 0);
        int has_multires = mmd != NULL, multires_applied = 0;
        int sculpt_mode = ob->mode & OB_MODE_SCULPT && ob->sculpt;
+       int sculpt_dyntopo = (sculpt_mode && ob->sculpt->bm);
 
        const int draw_flag = ((scene->toolsettings->multipaint ? CALC_WP_MULTIPAINT : 0) |
                               (scene->toolsettings->auto_normalize ? CALC_WP_AUTO_NORMALIZE : 0));
@@ -1407,7 +1420,7 @@ static void mesh_calc_modifiers(Scene *scene, Object *ob, float (*inputVertexCos
                        if (!modifier_isEnabled(scene, md, required_mode)) continue;
                        if (useDeform < 0 && mti->dependsOnTime && mti->dependsOnTime(md)) continue;
 
-                       if (mti->type == eModifierTypeType_OnlyDeform) {
+                       if (mti->type == eModifierTypeType_OnlyDeform && !sculpt_dyntopo) {
                                if (!deformedVerts)
                                        deformedVerts = mesh_getVertexCos(me, &numVerts);
 
@@ -1465,9 +1478,14 @@ static void mesh_calc_modifiers(Scene *scene, Object *ob, float (*inputVertexCos
                        modifier_setError(md, "Modifier requires original data, bad stack position");
                        continue;
                }
-               if (sculpt_mode && (!has_multires || multires_applied)) {
+               if (sculpt_mode &&
+                       (!has_multires || multires_applied || ob->sculpt->bm))
+               {
                        int unsupported = 0;
 
+                       if (sculpt_dyntopo)
+                               unsupported = TRUE;
+
                        if (scene->toolsettings->sculpt->flags & SCULPT_ONLY_DEFORM)
                                unsupported |= mti->type != eModifierTypeType_OnlyDeform;
 
@@ -1573,9 +1591,15 @@ static void mesh_calc_modifiers(Scene *scene, Object *ob, float (*inputVertexCos
                                        DM_add_edge_layer(dm, CD_ORIGINDEX, CD_CALLOC, NULL);
                                        DM_add_poly_layer(dm, CD_ORIGINDEX, CD_CALLOC, NULL);
 
-                                       range_vn_i(DM_get_vert_data_layer(dm, CD_ORIGINDEX), dm->numVertData, 0);
-                                       range_vn_i(DM_get_edge_data_layer(dm, CD_ORIGINDEX), dm->numEdgeData, 0);
-                                       range_vn_i(DM_get_poly_data_layer(dm, CD_ORIGINDEX), dm->numPolyData, 0);
+#pragma omp parallel sections if (dm->numVertData + dm->numEdgeData + dm->numPolyData >= DM_OMP_LIMIT)
+                                       {
+#pragma omp section
+                                               { range_vn_i(DM_get_vert_data_layer(dm, CD_ORIGINDEX), dm->numVertData, 0); }
+#pragma omp section
+                                               { range_vn_i(DM_get_edge_data_layer(dm, CD_ORIGINDEX), dm->numEdgeData, 0); }
+#pragma omp section
+                                               { range_vn_i(DM_get_poly_data_layer(dm, CD_ORIGINDEX), dm->numPolyData, 0); }
+                                       }
                                }
                        }
 
@@ -2310,20 +2334,19 @@ DerivedMesh *editbmesh_get_derived_base(Object *obedit, BMEditMesh *em)
 static void make_vertexcosnos__mapFunc(void *userData, int index, const float co[3],
                                        const float no_f[3], const short no_s[3])
 {
-       float *vec = userData;
-       
-       vec += 6 * index;
+       DMCoNo *co_no = &((DMCoNo *)userData)[index];
 
        /* check if we've been here before (normal should not be 0) */
-       if (vec[3] || vec[4] || vec[5]) return;
+       if (!is_zero_v3(co_no->no)) {
+               return;
+       }
 
-       copy_v3_v3(vec, co);
-       vec += 3;
+       copy_v3_v3(co_no->co, co);
        if (no_f) {
-               copy_v3_v3(vec, no_f);
+               copy_v3_v3(co_no->no, no_f);
        }
        else {
-               normal_short_to_float_v3(vec, no_s);
+               normal_short_to_float_v3(co_no->no, no_s);
        }
 }
 
@@ -2343,15 +2366,14 @@ DMCoNo *mesh_get_mapped_verts_nors(Scene *scene, Object *ob)
                return NULL;
        
        dm = mesh_get_derived_final(scene, ob, CD_MASK_BAREMESH | CD_MASK_ORIGINDEX);
-       vertexcosnos = MEM_callocN(sizeof(DMCoNo) * me->totvert, "vertexcosnos map");
        
        if (dm->foreachMappedVert) {
+               vertexcosnos = MEM_callocN(sizeof(DMCoNo) * me->totvert, "vertexcosnos map");
                dm->foreachMappedVert(dm, make_vertexcosnos__mapFunc, vertexcosnos);
        }
        else {
-               DMCoNo *v_co_no = vertexcosnos;
+               DMCoNo *v_co_no = vertexcosnos = MEM_mallocN(sizeof(DMCoNo) * me->totvert, "vertexcosnos map");
                int a;
-               
                for (a = 0; a < me->totvert; a++, v_co_no++) {
                        dm->getVertCo(dm, a, v_co_no->co);
                        dm->getVertNo(dm, a, v_co_no->no);