Changeset View
Changeset View
Standalone View
Standalone View
source/blender/blenkernel/intern/DerivedMesh.cc
| Show First 20 Lines • Show All 880 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); | ||||
| } | } | ||||
| /** | /** | ||||
| * Some modifiers don't work on geometry sets directly, but expect a single mesh as input. | |||||
| * Therefore, we convert data from the geometry set into a single mesh, so that those | |||||
| * modifiers can work on it as well. | |||||
| */ | |||||
| static Mesh *prepare_geometry_set_for_mesh_modifier(Mesh *mesh, GeometrySet &r_geometry_set) | |||||
| { | |||||
| if (!r_geometry_set.has_instances() && !r_geometry_set.has_pointcloud()) { | |||||
| return mesh; | |||||
| } | |||||
| { | |||||
| /* Add the mesh to the geometry set. */ | |||||
| MeshComponent &mesh_component = r_geometry_set.get_component_for_write<MeshComponent>(); | |||||
| mesh_component.replace(mesh, GeometryOwnershipType::Editable); | |||||
| } | |||||
| { | |||||
| /* Combine mesh and all instances into a single mesh that can be passed to the modifier. */ | |||||
| GeometrySet new_geometry_set = blender::bke::geometry_set_realize_mesh_for_modifier( | |||||
| r_geometry_set); | |||||
| MeshComponent &mesh_component = new_geometry_set.get_component_for_write<MeshComponent>(); | |||||
| Mesh *new_mesh = mesh_component.release(); | |||||
| r_geometry_set = new_geometry_set; | |||||
| return new_mesh; | |||||
| } | |||||
| } | |||||
| /** | |||||
| * Modifies the given mesh and geometry set. The mesh is not passed as part of the mesh component | * Modifies the given mesh and geometry set. The mesh is not passed as part of the mesh component | ||||
| * in the \a geometry_set input, it is only passed in \a input_mesh and returned in the return | * in the \a geometry_set input, it is only passed in \a input_mesh and returned in the return | ||||
| * value. | * value. | ||||
| * | * | ||||
| * The purpose of the geometry set is to store all geometry components that are generated | * The purpose of the geometry set is to store all geometry components that are generated | ||||
| * by modifiers to allow outputting non-mesh data from 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, | ||||
| Mesh *input_mesh, | Mesh *input_mesh, | ||||
| 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 *new_input_mesh = prepare_geometry_set_for_mesh_modifier(input_mesh, geometry_set); | mesh_output = BKE_modifier_modify_mesh(md, &mectx, input_mesh); | ||||
| mesh_output = BKE_modifier_modify_mesh(md, &mectx, new_input_mesh); | |||||
| /* The caller is responsible for freeing `input_mesh` and `mesh_output`. The intermediate | |||||
| * `new_input_mesh` has to be freed here. */ | |||||
| if (!ELEM(new_input_mesh, input_mesh, mesh_output)) { | |||||
| BKE_id_free(nullptr, new_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. */ | ||||
| MeshComponent &mesh_component = geometry_set.get_component_for_write<MeshComponent>(); | MeshComponent &mesh_component = geometry_set.get_component_for_write<MeshComponent>(); | ||||
| ▲ Show 20 Lines • Show All 225 Lines • ▼ Show 20 Lines | for (; md; md = md->next, md_datamask = md_datamask->next) { | ||||
| /* How to apply modifier depends on (a) what we already have as | /* How to apply modifier depends on (a) what we already have as | ||||
| * a result of previous modifiers (could be a Mesh or just | * a result of previous modifiers (could be a Mesh or just | ||||
| * deformed vertices) and (b) what type the modifier is. */ | * deformed vertices) and (b) what type the modifier is. */ | ||||
| if (mti->type == eModifierTypeType_OnlyDeform) { | if (mti->type == eModifierTypeType_OnlyDeform) { | ||||
| /* No existing verts to deform, need to build them. */ | /* No existing verts to deform, need to build them. */ | ||||
| if (!deformed_verts) { | if (!deformed_verts) { | ||||
| if (mesh_final) { | if (mesh_final) { | ||||
| Mesh *mesh_final_new = prepare_geometry_set_for_mesh_modifier(mesh_final, | |||||
| geometry_set_final); | |||||
| if (mesh_final_new != mesh_final) { | |||||
| BLI_assert(mesh_final != mesh_input); | |||||
| BKE_id_free(nullptr, mesh_final); | |||||
| mesh_final = mesh_final_new; | |||||
| } | |||||
| /* Deforming a mesh, read the vertex locations | /* Deforming a mesh, read the vertex locations | ||||
| * out of the mesh and deform them. Once done with this | * out of the mesh and deform them. Once done with this | ||||
| * run of deformers verts will be written back. */ | * run of deformers verts will be written back. */ | ||||
| deformed_verts = BKE_mesh_vert_coords_alloc(mesh_final, &num_deformed_verts); | deformed_verts = BKE_mesh_vert_coords_alloc(mesh_final, &num_deformed_verts); | ||||
| } | } | ||||
| else { | else { | ||||
| deformed_verts = BKE_mesh_vert_coords_alloc(mesh_input, &num_deformed_verts); | deformed_verts = BKE_mesh_vert_coords_alloc(mesh_input, &num_deformed_verts); | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 1,335 Lines • Show Last 20 Lines | |||||