Changeset View
Changeset View
Standalone View
Standalone View
source/blender/blenkernel/intern/DerivedMesh.cc
| Context not available. | |||||
| 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 | ||||
| Context not available. | |||||
| 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 | ||||
| Context not available. | |||||
| /* 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. */ | ||||
| Context not available. | |||||