Geometry Nodes: realize instances before passing geometry to constructive mesh modifier
Previously, when the output of a Geometry Nodes modifier would contain instances, those could not be accessed by other existing modifiers (e.g. the Array modifier). That is because those modifiers don't know about instances. Upcoming commits will improve an this in two ways: * Also realize instances before deform modifiers. * Convert a point cloud in the geometry to mesh vertices so that they can be accessed as well. Note, making instances real can result in loosing some information that we do not support in Geometry Nodes yet. That includes some special builtin attributes like bevel weights. Ref T85281. Differential Revision: https://developer.blender.org/D10432
This commit is contained in:
parent
3a6d6299d7
commit
96da8e9ca3
Notes:
blender-bot
2023-02-14 00:13:36 +01:00
Referenced by commit 55a69d5707
, Geometry Nodes: realize instances before deform modifier
Referenced by issue #85281, Support piping legacy modifiers with the geometry nodes modifiers
|
@ -51,6 +51,7 @@
|
|||
#include "BKE_deform.h"
|
||||
#include "BKE_editmesh.h"
|
||||
#include "BKE_geometry_set.hh"
|
||||
#include "BKE_geometry_set_instances.hh"
|
||||
#include "BKE_key.h"
|
||||
#include "BKE_layer.h"
|
||||
#include "BKE_lib_id.h"
|
||||
|
@ -882,6 +883,32 @@ void BKE_mesh_wrapper_deferred_finalize(Mesh *me_eval,
|
|||
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
|
||||
* in the \a geometry_set input, it is only passed in \a input_mesh and returned in the return
|
||||
|
@ -898,7 +925,14 @@ static Mesh *modifier_modify_mesh_and_geometry_set(ModifierData *md,
|
|||
Mesh *mesh_output = nullptr;
|
||||
const ModifierTypeInfo *mti = BKE_modifier_get_info((ModifierType)md->type);
|
||||
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 {
|
||||
/* For performance reasons, this should be called by the modifier and/or nodes themselves at
|
||||
|
|
Loading…
Reference in New Issue