Changeset View
Changeset View
Standalone View
Standalone View
source/blender/blenkernel/intern/DerivedMesh.cc
| Show First 20 Lines • Show All 877 Lines • ▼ Show 20 Lines | void BKE_mesh_wrapper_deferred_finalize(Mesh *me_eval, | ||||
| if (me_eval->runtime.wrapper_type_finalize & (1 << ME_WRAPPER_TYPE_BMESH)) { | if (me_eval->runtime.wrapper_type_finalize & (1 << ME_WRAPPER_TYPE_BMESH)) { | ||||
| editbmesh_calc_modifier_final_normals(me_eval, cd_mask_finalize); | editbmesh_calc_modifier_final_normals(me_eval, cd_mask_finalize); | ||||
| me_eval->runtime.wrapper_type_finalize &= ~(1 << ME_WRAPPER_TYPE_BMESH); | me_eval->runtime.wrapper_type_finalize &= ~(1 << ME_WRAPPER_TYPE_BMESH); | ||||
| } | } | ||||
| BLI_assert(me_eval->runtime.wrapper_type_finalize == 0); | BLI_assert(me_eval->runtime.wrapper_type_finalize == 0); | ||||
| } | } | ||||
| /** | /** | ||||
| * Modifies the given mesh and geometry set. The geometry set is expect to have NO mesh component. | * Modifies the given mesh and geometry set. The mesh is not passed as part of the mesh component | ||||
| * After this function ends, the geometry set will still have NO mesh component. Instead, an input | * in the \a geometry_set input, it is only passed in \a input_mesh and returned in the return | ||||
| * mesh is passed separately and is returned separately. | * value. | ||||
| * | * | ||||
| * The purpose of the geometry set is to store all non-mesh geometry components that are generated | * The purpose of the geometry set is to store all geometry components that are generated | ||||
| * by modifiers. | * by modifiers to allow outputting non-mesh data from modifiers. | ||||
| */ | */ | ||||
| static Mesh *modifier_modify_mesh_and_geometry_set(ModifierData *md, | static Mesh *modifier_modify_mesh_and_geometry_set(ModifierData *md, | ||||
| const ModifierEvalContext &mectx, | const ModifierEvalContext &mectx, | ||||
| Object *ob, | |||||
| Mesh *input_mesh, | Mesh *input_mesh, | ||||
JacquesLucke: Unused parameter. | |||||
| GeometrySet &geometry_set) | GeometrySet &geometry_set) | ||||
| { | { | ||||
| Mesh *mesh_output = nullptr; | Mesh *mesh_output = nullptr; | ||||
| const ModifierTypeInfo *mti = BKE_modifier_get_info((ModifierType)md->type); | const ModifierTypeInfo *mti = BKE_modifier_get_info((ModifierType)md->type); | ||||
| if (mti->modifyGeometrySet == nullptr) { | if (mti->modifyGeometrySet == nullptr) { | ||||
| mesh_output = BKE_modifier_modify_mesh(md, &mectx, input_mesh); | mesh_output = BKE_modifier_modify_mesh(md, &mectx, input_mesh); | ||||
| } | } | ||||
| else { | else { | ||||
| /* For performance reasons, this should be called by the modifier and/or nodes themselves at | /* For performance reasons, this should be called by the modifier and/or nodes themselves at | ||||
| * some point. */ | * some point. */ | ||||
| BKE_mesh_wrapper_ensure_mdata(input_mesh); | BKE_mesh_wrapper_ensure_mdata(input_mesh); | ||||
| /* Adds a new mesh component to the geometry set based on the #input_mesh. */ | /* Adds a new mesh component to the geometry set based on the #input_mesh. */ | ||||
| BLI_assert(!geometry_set.has<MeshComponent>()); | |||||
| MeshComponent &mesh_component = geometry_set.get_component_for_write<MeshComponent>(); | MeshComponent &mesh_component = geometry_set.get_component_for_write<MeshComponent>(); | ||||
| mesh_component.replace(input_mesh, GeometryOwnershipType::Editable); | /* Replace only the mesh rather than the whole component, because the entire #MeshComponent | ||||
| mesh_component.copy_vertex_group_names_from_object(*ob); | * might have been replaced by data from a different object in the node tree, which means the | ||||
| * component contain vertex group name data for that object that should not be removed. */ | |||||
JacquesLuckeUnsubmitted Not Done Inline Actionsconstains JacquesLucke: `constains` | |||||
| mesh_component.replace_mesh_but_keep_vertex_group_names(input_mesh, | |||||
| GeometryOwnershipType::Editable); | |||||
| /* Let the modifier change the geometry set. */ | /* Let the modifier change the geometry set. */ | ||||
| mti->modifyGeometrySet(md, &mectx, &geometry_set); | mti->modifyGeometrySet(md, &mectx, &geometry_set); | ||||
| /* Release the mesh from the geometry set again. */ | /* Release the mesh from the geometry set again. */ | ||||
| if (geometry_set.has<MeshComponent>()) { | if (geometry_set.has<MeshComponent>()) { | ||||
| MeshComponent &mesh_component = geometry_set.get_component_for_write<MeshComponent>(); | MeshComponent &mesh_component = geometry_set.get_component_for_write<MeshComponent>(); | ||||
| mesh_output = mesh_component.release(); | mesh_output = mesh_component.release(); | ||||
| geometry_set.remove<MeshComponent>(); | |||||
| } | } | ||||
| /* Return an empty mesh instead of null. */ | /* Return an empty mesh instead of null. */ | ||||
| if (mesh_output == nullptr) { | if (mesh_output == nullptr) { | ||||
| mesh_output = BKE_mesh_new_nomain(0, 0, 0, 0, 0); | mesh_output = BKE_mesh_new_nomain(0, 0, 0, 0, 0); | ||||
| BKE_mesh_copy_settings(mesh_output, input_mesh); | BKE_mesh_copy_settings(mesh_output, input_mesh); | ||||
| } | } | ||||
| } | } | ||||
| Show All 18 Lines | static void mesh_calc_modifiers(struct Depsgraph *depsgraph, | ||||
| /* Input and final mesh. Final mesh is only created the moment the first | /* Input and final mesh. Final mesh is only created the moment the first | ||||
| * constructive modifier is executed, or a deform modifier needs normals | * constructive modifier is executed, or a deform modifier needs normals | ||||
| * or certain data layers. */ | * or certain data layers. */ | ||||
| Mesh *mesh_input = (Mesh *)ob->data; | Mesh *mesh_input = (Mesh *)ob->data; | ||||
| Mesh *mesh_final = nullptr; | Mesh *mesh_final = nullptr; | ||||
| Mesh *mesh_deform = nullptr; | Mesh *mesh_deform = nullptr; | ||||
| /* This geometry set contains the non-mesh data that might be generated by modifiers. */ | /* This geometry set contains the non-mesh data that might be generated by modifiers. */ | ||||
| GeometrySet geometry_set_final; | GeometrySet geometry_set_final; | ||||
| /* Add the initial mesh component, with a copy of the vertex group names from the object, | |||||
| * since they need to be stored in the geometry set for evaluation. */ | |||||
| MeshComponent &initial_mesh_component = | |||||
| geometry_set_final.get_component_for_write<MeshComponent>(); | |||||
| initial_mesh_component.copy_vertex_group_names_from_object(*ob); | |||||
| BLI_assert((mesh_input->id.tag & LIB_TAG_COPIED_ON_WRITE_EVAL_RESULT) == 0); | BLI_assert((mesh_input->id.tag & LIB_TAG_COPIED_ON_WRITE_EVAL_RESULT) == 0); | ||||
| /* Deformed vertex locations array. Deform only modifier need this type of | /* Deformed vertex locations array. Deform only modifier need this type of | ||||
| * float array rather than MVert*. Tracked along with mesh_final as an | * float array rather than MVert*. Tracked along with mesh_final as an | ||||
| * optimization to avoid copying coordinates back and forth if there are | * optimization to avoid copying coordinates back and forth if there are | ||||
| * multiple sequential deform only modifiers. */ | * multiple sequential deform only modifiers. */ | ||||
| float(*deformed_verts)[3] = nullptr; | float(*deformed_verts)[3] = nullptr; | ||||
| int num_deformed_verts = mesh_input->totvert; | int num_deformed_verts = mesh_input->totvert; | ||||
| ▲ Show 20 Lines • Show All 282 Lines • ▼ Show 20 Lines | else { | ||||
| if (!CustomData_has_layer(&mesh_final->ldata, CD_ORIGSPACE_MLOOP)) { | if (!CustomData_has_layer(&mesh_final->ldata, CD_ORIGSPACE_MLOOP)) { | ||||
| CustomData_add_layer( | CustomData_add_layer( | ||||
| &mesh_final->ldata, CD_ORIGSPACE_MLOOP, CD_CALLOC, nullptr, mesh_final->totloop); | &mesh_final->ldata, CD_ORIGSPACE_MLOOP, CD_CALLOC, nullptr, mesh_final->totloop); | ||||
| mesh_init_origspace(mesh_final); | mesh_init_origspace(mesh_final); | ||||
| } | } | ||||
| } | } | ||||
| Mesh *mesh_next = modifier_modify_mesh_and_geometry_set( | Mesh *mesh_next = modifier_modify_mesh_and_geometry_set( | ||||
| md, mectx, ob, mesh_final, geometry_set_final); | md, mectx, mesh_final, geometry_set_final); | ||||
| ASSERT_IS_VALID_MESH(mesh_next); | ASSERT_IS_VALID_MESH(mesh_next); | ||||
| if (mesh_next) { | if (mesh_next) { | ||||
| /* if the modifier returned a new mesh, release the old one */ | /* if the modifier returned a new mesh, release the old one */ | ||||
| if (mesh_final != mesh_next) { | if (mesh_final != mesh_next) { | ||||
| BLI_assert(mesh_final != mesh_input); | BLI_assert(mesh_final != mesh_input); | ||||
| BKE_id_free(nullptr, mesh_final); | BKE_id_free(nullptr, mesh_final); | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 448 Lines • ▼ Show 20 Lines | else { | ||||
| if (!CustomData_has_layer(&mesh_final->ldata, CD_ORIGSPACE_MLOOP)) { | if (!CustomData_has_layer(&mesh_final->ldata, CD_ORIGSPACE_MLOOP)) { | ||||
| CustomData_add_layer( | CustomData_add_layer( | ||||
| &mesh_final->ldata, CD_ORIGSPACE_MLOOP, CD_CALLOC, nullptr, mesh_final->totloop); | &mesh_final->ldata, CD_ORIGSPACE_MLOOP, CD_CALLOC, nullptr, mesh_final->totloop); | ||||
| mesh_init_origspace(mesh_final); | mesh_init_origspace(mesh_final); | ||||
| } | } | ||||
| } | } | ||||
| Mesh *mesh_next = modifier_modify_mesh_and_geometry_set( | Mesh *mesh_next = modifier_modify_mesh_and_geometry_set( | ||||
| md, mectx, ob, mesh_final, geometry_set_final); | md, mectx, mesh_final, geometry_set_final); | ||||
| ASSERT_IS_VALID_MESH(mesh_next); | ASSERT_IS_VALID_MESH(mesh_next); | ||||
| if (mesh_next) { | if (mesh_next) { | ||||
| if (mesh_final && mesh_final != mesh_next) { | if (mesh_final && mesh_final != mesh_next) { | ||||
| BKE_id_free(nullptr, mesh_final); | BKE_id_free(nullptr, mesh_final); | ||||
| } | } | ||||
| mesh_final = mesh_next; | mesh_final = mesh_next; | ||||
| ▲ Show 20 Lines • Show All 159 Lines • ▼ Show 20 Lines | #endif | ||||
| * Check ownership now, since later on we can not go to a mesh owned by someone else via | * Check ownership now, since later on we can not go to a mesh owned by someone else via | ||||
| * object's runtime: this could cause access freed data on depsgraph destruction (mesh who owns | * object's runtime: this could cause access freed data on depsgraph destruction (mesh who owns | ||||
| * the final result might be freed prior to object). */ | * the final result might be freed prior to object). */ | ||||
| Mesh *mesh = (Mesh *)ob->data; | Mesh *mesh = (Mesh *)ob->data; | ||||
| const bool is_mesh_eval_owned = (mesh_eval != mesh->runtime.mesh_eval); | const bool is_mesh_eval_owned = (mesh_eval != mesh->runtime.mesh_eval); | ||||
| BKE_object_eval_assign_data(ob, &mesh_eval->id, is_mesh_eval_owned); | BKE_object_eval_assign_data(ob, &mesh_eval->id, is_mesh_eval_owned); | ||||
| /* Add the final mesh as read-only non-owning component to the geometry set. */ | /* Add the final mesh as read-only non-owning component to the geometry set. */ | ||||
| BLI_assert(!geometry_set_eval->has<MeshComponent>()); | |||||
| MeshComponent &mesh_component = geometry_set_eval->get_component_for_write<MeshComponent>(); | MeshComponent &mesh_component = geometry_set_eval->get_component_for_write<MeshComponent>(); | ||||
| mesh_component.replace(mesh_eval, GeometryOwnershipType::ReadOnly); | mesh_component.replace_mesh_but_keep_vertex_group_names(mesh_eval, | ||||
| GeometryOwnershipType::ReadOnly); | |||||
| ob->runtime.geometry_set_eval = geometry_set_eval; | ob->runtime.geometry_set_eval = geometry_set_eval; | ||||
| ob->runtime.mesh_deform_eval = mesh_deform_eval; | ob->runtime.mesh_deform_eval = mesh_deform_eval; | ||||
| ob->runtime.last_data_mask = *dataMask; | ob->runtime.last_data_mask = *dataMask; | ||||
| ob->runtime.last_need_mapping = need_mapping; | ob->runtime.last_need_mapping = need_mapping; | ||||
| BKE_object_boundbox_calc_from_mesh(ob, mesh_eval); | BKE_object_boundbox_calc_from_mesh(ob, mesh_eval); | ||||
| ▲ Show 20 Lines • Show All 583 Lines • Show Last 20 Lines | |||||
Unused parameter.