diff options
Diffstat (limited to 'source/blender/blenkernel/intern/mesh_convert.cc')
-rw-r--r-- | source/blender/blenkernel/intern/mesh_convert.cc | 125 |
1 files changed, 91 insertions, 34 deletions
diff --git a/source/blender/blenkernel/intern/mesh_convert.cc b/source/blender/blenkernel/intern/mesh_convert.cc index 59cdb6a2b27..7d5f156040d 100644 --- a/source/blender/blenkernel/intern/mesh_convert.cc +++ b/source/blender/blenkernel/intern/mesh_convert.cc @@ -32,6 +32,7 @@ #include "DNA_scene_types.h" #include "BLI_edgehash.h" +#include "BLI_index_range.hh" #include "BLI_listbase.h" #include "BLI_math.h" #include "BLI_string.h" @@ -65,6 +66,8 @@ #include "DEG_depsgraph.h" #include "DEG_depsgraph_query.h" +using blender::IndexRange; + /* Define for cases when you want extra validation of mesh * after certain modifications. */ @@ -85,7 +88,6 @@ void BKE_mesh_from_metaball(ListBase *lb, Mesh *me) MVert *mvert; MLoop *mloop, *allloop; MPoly *mpoly; - const float *nors, *verts; int a, *index; dl = (DispList *)lb->first; @@ -104,15 +106,8 @@ void BKE_mesh_from_metaball(ListBase *lb, Mesh *me) me->totvert = dl->nr; me->totpoly = dl->parts; - a = dl->nr; - nors = dl->nors; - verts = dl->verts; - while (a--) { - copy_v3_v3(mvert->co, verts); - normal_float_to_short_v3(mvert->no, nors); - mvert++; - nors += 3; - verts += 3; + for (const int i : IndexRange(dl->nr)) { + copy_v3_v3(me->mvert[i].co, &dl->verts[3 * i]); } a = dl->parts; @@ -139,7 +134,7 @@ void BKE_mesh_from_metaball(ListBase *lb, Mesh *me) BKE_mesh_update_customdata_pointers(me, true); - BKE_mesh_calc_normals(me); + BKE_mesh_normals_tag_dirty(me); BKE_mesh_calc_edges(me, true, false); } @@ -454,10 +449,10 @@ static int mesh_nurbs_displist_to_mdata(const Curve *cu, mloopuv->uv[1] = (v % dl->nr) / (float)orco_sizeu; /* cyclic correction */ - if ((i == 1 || i == 2) && mloopuv->uv[0] == 0.0f) { + if ((ELEM(i, 1, 2)) && mloopuv->uv[0] == 0.0f) { mloopuv->uv[0] = 1.0f; } - if ((i == 0 || i == 1) && mloopuv->uv[1] == 0.0f) { + if ((ELEM(i, 0, 1)) && mloopuv->uv[1] == 0.0f) { mloopuv->uv[1] = 1.0f; } } @@ -589,14 +584,14 @@ struct VertLink { static void prependPolyLineVert(ListBase *lb, uint index) { - VertLink *vl = (VertLink *)MEM_callocN(sizeof(VertLink), "VertLink"); + VertLink *vl = MEM_cnew<VertLink>("VertLink"); vl->index = index; BLI_addhead(lb, vl); } static void appendPolyLineVert(ListBase *lb, uint index) { - VertLink *vl = (VertLink *)MEM_callocN(sizeof(VertLink), "VertLink"); + VertLink *vl = MEM_cnew<VertLink>("VertLink"); vl->index = index; BLI_addtail(lb, vl); } @@ -632,7 +627,7 @@ void BKE_mesh_to_curve_nurblist(const Mesh *me, ListBase *nurblist, const int ed med = medge; for (i = 0; i < medge_len; i++, med++) { if (edge_users[i] == edge_users_test) { - EdgeLink *edl = (EdgeLink *)MEM_callocN(sizeof(EdgeLink), "EdgeLink"); + EdgeLink *edl = MEM_cnew<EdgeLink>("EdgeLink"); edl->edge = med; BLI_addtail(&edges, edl); @@ -719,7 +714,7 @@ void BKE_mesh_to_curve_nurblist(const Mesh *me, ListBase *nurblist, const int ed VertLink *vl; /* create new 'nurb' within the curve */ - nu = (Nurb *)MEM_callocN(sizeof(Nurb), "MeshNurb"); + nu = MEM_cnew<Nurb>("MeshNurb"); nu->pntsu = totpoly; nu->pntsv = 1; @@ -901,6 +896,20 @@ static Object *object_for_curve_to_mesh_create(const Object *object) return temp_object; } +static void object_for_curve_to_mesh_free(Object *temp_object) +{ + /* Clear edit mode pointers that were explicitly copied to the temporary curve. */ + ID *final_object_data = static_cast<ID *>(temp_object->data); + if (GS(final_object_data->name) == ID_CU) { + Curve &curve = *reinterpret_cast<Curve *>(final_object_data); + curve.editfont = nullptr; + curve.editnurb = nullptr; + } + + BKE_id_free(nullptr, temp_object->data); + BKE_id_free(nullptr, temp_object); +} + /** * Populate `object->runtime.curve_cache` which is then used to create the mesh. */ @@ -917,7 +926,7 @@ static void curve_to_mesh_eval_ensure(Object &object) * will have no modifiers. */ Object bevel_object = {{nullptr}}; if (curve.bevobj != nullptr) { - bevel_object = *curve.bevobj; + memcpy(&bevel_object, curve.bevobj, sizeof(bevel_object)); BLI_listbase_clear(&bevel_object.modifiers); BKE_object_runtime_reset(&bevel_object); curve.bevobj = &bevel_object; @@ -926,7 +935,7 @@ static void curve_to_mesh_eval_ensure(Object &object) /* Same thing for taper. */ Object taper_object = {{nullptr}}; if (curve.taperobj != nullptr) { - taper_object = *curve.taperobj; + memcpy(&taper_object, curve.taperobj, sizeof(taper_object)); BLI_listbase_clear(&taper_object.modifiers); BKE_object_runtime_reset(&taper_object); curve.taperobj = &taper_object; @@ -1003,8 +1012,7 @@ static Mesh *mesh_new_from_curve_type_object(const Object *object) Mesh *mesh = mesh_new_from_evaluated_curve_type_object(temp_object); - BKE_id_free(nullptr, temp_object->data); - BKE_id_free(nullptr, temp_object); + object_for_curve_to_mesh_free(temp_object); return mesh; } @@ -1065,7 +1073,8 @@ static Mesh *mesh_new_from_mesh_object_with_layers(Depsgraph *depsgraph, return nullptr; } - Object object_for_eval = *object; + Object object_for_eval; + memcpy(&object_for_eval, object, sizeof(object_for_eval)); if (object_for_eval.runtime.data_orig != nullptr) { object_for_eval.data = object_for_eval.runtime.data_orig; } @@ -1093,8 +1102,11 @@ static Mesh *mesh_new_from_mesh_object(Depsgraph *depsgraph, Mesh *mesh_input = (Mesh *)object->data; /* If we are in edit mode, use evaluated mesh from edit structure, matching to what * viewport is using for visualization. */ - if (mesh_input->edit_mesh != nullptr && mesh_input->edit_mesh->mesh_eval_final) { - mesh_input = mesh_input->edit_mesh->mesh_eval_final; + if (mesh_input->edit_mesh != nullptr) { + Mesh *editmesh_eval_final = BKE_object_get_editmesh_eval_final(object); + if (editmesh_eval_final != nullptr) { + mesh_input = editmesh_eval_final; + } } return mesh_new_from_mesh(object, mesh_input); } @@ -1281,6 +1293,7 @@ Mesh *BKE_mesh_create_derived_for_modifier(struct Depsgraph *depsgraph, Scene *scene, Object *ob_eval, ModifierData *md_eval, + const bool use_virtual_modifiers, const bool build_shapekey_layers) { Mesh *me = ob_eval->runtime.data_orig ? (Mesh *)ob_eval->runtime.data_orig : @@ -1303,22 +1316,49 @@ Mesh *BKE_mesh_create_derived_for_modifier(struct Depsgraph *depsgraph, BKE_keyblock_convert_to_mesh(kb, me); } - if (mti->type == eModifierTypeType_OnlyDeform) { - int numVerts; - float(*deformedVerts)[3] = BKE_mesh_vert_coords_alloc(me, &numVerts); + Mesh *mesh_temp = (Mesh *)BKE_id_copy_ex(nullptr, &me->id, nullptr, LIB_ID_COPY_LOCALIZE); + int numVerts = 0; + float(*deformedVerts)[3] = nullptr; + + if (use_virtual_modifiers) { + VirtualModifierData virtualModifierData; + for (ModifierData *md_eval_virt = + BKE_modifiers_get_virtual_modifierlist(ob_eval, &virtualModifierData); + md_eval_virt && (md_eval_virt != ob_eval->modifiers.first); + md_eval_virt = md_eval_virt->next) { + if (!BKE_modifier_is_enabled(scene, md_eval_virt, eModifierMode_Realtime)) { + continue; + } + /* All virtual modifiers are deform modifiers. */ + const ModifierTypeInfo *mti_virt = BKE_modifier_get_info((ModifierType)md_eval_virt->type); + BLI_assert(mti_virt->type == eModifierTypeType_OnlyDeform); + if (mti_virt->type != eModifierTypeType_OnlyDeform) { + continue; + } + + if (deformedVerts == nullptr) { + deformedVerts = BKE_mesh_vert_coords_alloc(me, &numVerts); + } + mti_virt->deformVerts(md_eval_virt, &mectx, mesh_temp, deformedVerts, numVerts); + } + } - result = (Mesh *)BKE_id_copy_ex(nullptr, &me->id, nullptr, LIB_ID_COPY_LOCALIZE); + if (mti->type == eModifierTypeType_OnlyDeform) { + if (deformedVerts == nullptr) { + deformedVerts = BKE_mesh_vert_coords_alloc(me, &numVerts); + } + result = mesh_temp; mti->deformVerts(md_eval, &mectx, result, deformedVerts, numVerts); BKE_mesh_vert_coords_apply(result, deformedVerts); if (build_shapekey_layers) { add_shapekey_layers(result, me); } - - MEM_freeN(deformedVerts); } else { - Mesh *mesh_temp = (Mesh *)BKE_id_copy_ex(nullptr, &me->id, nullptr, LIB_ID_COPY_LOCALIZE); + if (deformedVerts != nullptr) { + BKE_mesh_vert_coords_apply(mesh_temp, deformedVerts); + } if (build_shapekey_layers) { add_shapekey_layers(mesh_temp, me); @@ -1332,6 +1372,10 @@ Mesh *BKE_mesh_create_derived_for_modifier(struct Depsgraph *depsgraph, } } + if (deformedVerts != nullptr) { + MEM_freeN(deformedVerts); + } + return result; } @@ -1408,7 +1452,8 @@ void BKE_mesh_nomain_to_mesh(Mesh *mesh_src, /* mesh_src might depend on mesh_dst, so we need to do everything with a local copy */ /* TODO(Sybren): the above claim came from 2.7x derived-mesh code (DM_to_mesh); * check whether it is still true with Mesh */ - Mesh tmp = *mesh_dst; + Mesh tmp; + memcpy(&tmp, mesh_dst, sizeof(tmp)); int totvert, totedge /*, totface */ /* UNUSED */, totloop, totpoly; bool did_shapekeys = false; eCDAllocType alloctype = CD_DUPLICATE; @@ -1429,8 +1474,6 @@ void BKE_mesh_nomain_to_mesh(Mesh *mesh_src, CustomData_reset(&tmp.ldata); CustomData_reset(&tmp.pdata); - BKE_mesh_ensure_normals(mesh_src); - totvert = tmp.totvert = mesh_src->totvert; totedge = tmp.totedge = mesh_src->totedge; totloop = tmp.totloop = mesh_src->totloop; @@ -1444,6 +1487,18 @@ void BKE_mesh_nomain_to_mesh(Mesh *mesh_src, tmp.cd_flag = mesh_src->cd_flag; tmp.runtime.deformed_only = mesh_src->runtime.deformed_only; + tmp.runtime.cd_dirty_poly = mesh_src->runtime.cd_dirty_poly; + tmp.runtime.cd_dirty_vert = mesh_src->runtime.cd_dirty_vert; + + /* Ensure that when no normal layers exist, they are marked dirty, because + * normals might not have been included in the mask of copied layers. */ + if (!CustomData_has_layer(&tmp.vdata, CD_NORMAL)) { + tmp.runtime.cd_dirty_vert |= CD_MASK_NORMAL; + } + if (!CustomData_has_layer(&tmp.pdata, CD_NORMAL)) { + tmp.runtime.cd_dirty_poly |= CD_MASK_NORMAL; + } + if (CustomData_has_layer(&mesh_src->vdata, CD_SHAPEKEY)) { KeyBlock *kb; int uid; @@ -1567,6 +1622,8 @@ void BKE_mesh_nomain_to_mesh(Mesh *mesh_src, } BKE_id_free(nullptr, mesh_src); } + + BKE_mesh_assert_normals_dirty_or_calculated(mesh_dst); } void BKE_mesh_nomain_to_meshkey(Mesh *mesh_src, Mesh *mesh_dst, KeyBlock *kb) |