Changeset View
Changeset View
Standalone View
Standalone View
source/blender/blenkernel/intern/DerivedMesh.cc
| Show First 20 Lines • Show All 45 Lines • ▼ Show 20 Lines | |||||
| #include "BLI_vector.hh" | #include "BLI_vector.hh" | ||||
| #include "BKE_DerivedMesh.h" | #include "BKE_DerivedMesh.h" | ||||
| #include "BKE_bvhutils.h" | #include "BKE_bvhutils.h" | ||||
| #include "BKE_colorband.h" | #include "BKE_colorband.h" | ||||
| #include "BKE_deform.h" | #include "BKE_deform.h" | ||||
| #include "BKE_editmesh.h" | #include "BKE_editmesh.h" | ||||
| #include "BKE_geometry_set.hh" | #include "BKE_geometry_set.hh" | ||||
| #include "BKE_geometry_set_instances.hh" | |||||
| #include "BKE_key.h" | #include "BKE_key.h" | ||||
| #include "BKE_layer.h" | #include "BKE_layer.h" | ||||
| #include "BKE_lib_id.h" | #include "BKE_lib_id.h" | ||||
| #include "BKE_material.h" | #include "BKE_material.h" | ||||
| #include "BKE_mesh.h" | #include "BKE_mesh.h" | ||||
| #include "BKE_mesh_iterators.h" | #include "BKE_mesh_iterators.h" | ||||
| #include "BKE_mesh_mapping.h" | #include "BKE_mesh_mapping.h" | ||||
| #include "BKE_mesh_runtime.h" | #include "BKE_mesh_runtime.h" | ||||
| ▲ Show 20 Lines • Show All 816 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()) { | |||||
| return mesh; | |||||
| } | |||||
| { | |||||
| /* Add the mesh to the geometry set. */ | |||||
| MeshComponent &mesh_component = r_geometry_set.get_component_for_write<MeshComponent>(); | |||||
| mesh_component.replace_mesh_but_keep_vertex_group_names(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_instances(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_output = BKE_modifier_modify_mesh(md, &mectx, input_mesh); | Mesh *new_input_mesh = prepare_geometry_set_for_mesh_modifier(input_mesh, geometry_set); | ||||
| 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 1,587 Lines • Show Last 20 Lines | |||||