diff options
-rw-r--r-- | source/blender/blenkernel/BKE_blender_version.h | 2 | ||||
-rw-r--r-- | source/blender/blenkernel/BKE_geometry_set_instances.hh | 1 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/DerivedMesh.cc | 44 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/geometry_set_instances.cc | 66 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/lib_id.c | 5 | ||||
-rw-r--r-- | source/blender/blenloader/intern/versioning_300.c | 81 | ||||
-rw-r--r-- | source/blender/modifiers/intern/MOD_nodes.cc | 6 |
7 files changed, 95 insertions, 110 deletions
diff --git a/source/blender/blenkernel/BKE_blender_version.h b/source/blender/blenkernel/BKE_blender_version.h index d8112de760d..5ee86f9446e 100644 --- a/source/blender/blenkernel/BKE_blender_version.h +++ b/source/blender/blenkernel/BKE_blender_version.h @@ -39,7 +39,7 @@ extern "C" { /* Blender file format version. */ #define BLENDER_FILE_VERSION BLENDER_VERSION -#define BLENDER_FILE_SUBVERSION 34 +#define BLENDER_FILE_SUBVERSION 35 /* Minimum Blender version that supports reading file written with the current * version. Older Blender versions will test this and show a warning if the file diff --git a/source/blender/blenkernel/BKE_geometry_set_instances.hh b/source/blender/blenkernel/BKE_geometry_set_instances.hh index d7a60162e81..e5b28e4fbab 100644 --- a/source/blender/blenkernel/BKE_geometry_set_instances.hh +++ b/source/blender/blenkernel/BKE_geometry_set_instances.hh @@ -44,7 +44,6 @@ struct GeometryInstanceGroup { void geometry_set_gather_instances(const GeometrySet &geometry_set, Vector<GeometryInstanceGroup> &r_instance_groups); -GeometrySet geometry_set_realize_mesh_for_modifier(const GeometrySet &geometry_set); GeometrySet geometry_set_realize_instances(const GeometrySet &geometry_set); /** diff --git a/source/blender/blenkernel/intern/DerivedMesh.cc b/source/blender/blenkernel/intern/DerivedMesh.cc index 59e81938e79..3ec0ab9c512 100644 --- a/source/blender/blenkernel/intern/DerivedMesh.cc +++ b/source/blender/blenkernel/intern/DerivedMesh.cc @@ -886,33 +886,6 @@ void BKE_mesh_wrapper_deferred_finalize(Mesh *me_eval, } /** - * 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 * in the \a geometry_set input, it is only passed in \a input_mesh and returned in the return * value. @@ -928,14 +901,7 @@ 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 *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); - } + mesh_output = BKE_modifier_modify_mesh(md, &mectx, input_mesh); } else { /* For performance reasons, this should be called by the modifier and/or nodes themselves at @@ -1177,14 +1143,6 @@ static void mesh_calc_modifiers(struct Depsgraph *depsgraph, /* No existing verts to deform, need to build them. */ if (!deformed_verts) { 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 * out of the mesh and deform them. Once done with this * run of deformers verts will be written back. */ diff --git a/source/blender/blenkernel/intern/geometry_set_instances.cc b/source/blender/blenkernel/intern/geometry_set_instances.cc index d92df386575..35c6a7df2c7 100644 --- a/source/blender/blenkernel/intern/geometry_set_instances.cc +++ b/source/blender/blenkernel/intern/geometry_set_instances.cc @@ -224,8 +224,7 @@ void geometry_set_gather_instances_attribute_info(Span<GeometryInstanceGroup> se } } -static Mesh *join_mesh_topology_and_builtin_attributes(Span<GeometryInstanceGroup> set_groups, - const bool convert_points_to_vertices) +static Mesh *join_mesh_topology_and_builtin_attributes(Span<GeometryInstanceGroup> set_groups) { int totverts = 0; int totloops = 0; @@ -255,10 +254,6 @@ static Mesh *join_mesh_topology_and_builtin_attributes(Span<GeometryInstanceGrou materials.add(material); } } - if (convert_points_to_vertices && set.has_pointcloud()) { - const PointCloud &pointcloud = *set.get_pointcloud_for_read(); - totverts += pointcloud.totpoint * tot_transforms; - } } /* Don't create an empty mesh. */ @@ -345,24 +340,6 @@ static Mesh *join_mesh_topology_and_builtin_attributes(Span<GeometryInstanceGrou poly_offset += mesh.totpoly; } } - - const float3 point_normal{0.0f, 0.0f, 1.0f}; - short point_normal_short[3]; - normal_float_to_short_v3(point_normal_short, point_normal); - - if (convert_points_to_vertices && set.has_pointcloud()) { - const PointCloud &pointcloud = *set.get_pointcloud_for_read(); - for (const float4x4 &transform : set_group.transforms) { - for (const int i : IndexRange(pointcloud.totpoint)) { - MVert &new_vert = new_mesh->mvert[vert_offset + i]; - const float3 old_position = pointcloud.co[i]; - const float3 new_position = transform * old_position; - copy_v3_v3(new_vert.co, new_position); - memcpy(&new_vert.no, point_normal_short, sizeof(point_normal_short)); - } - vert_offset += pointcloud.totpoint; - } - } } /* A possible optimization is to only tag the normals dirty when there are transforms that change @@ -495,12 +472,9 @@ static CurveEval *join_curve_splines_and_builtin_attributes(Span<GeometryInstanc return new_curve; } -static void join_instance_groups_mesh(Span<GeometryInstanceGroup> set_groups, - bool convert_points_to_vertices, - GeometrySet &result) +static void join_instance_groups_mesh(Span<GeometryInstanceGroup> set_groups, GeometrySet &result) { - Mesh *new_mesh = join_mesh_topology_and_builtin_attributes(set_groups, - convert_points_to_vertices); + Mesh *new_mesh = join_mesh_topology_and_builtin_attributes(set_groups); if (new_mesh == nullptr) { return; } @@ -508,21 +482,17 @@ static void join_instance_groups_mesh(Span<GeometryInstanceGroup> set_groups, MeshComponent &dst_component = result.get_component_for_write<MeshComponent>(); dst_component.replace(new_mesh); - Vector<GeometryComponentType> component_types; - component_types.append(GEO_COMPONENT_TYPE_MESH); - if (convert_points_to_vertices) { - component_types.append(GEO_COMPONENT_TYPE_POINT_CLOUD); - } - /* Don't copy attributes that are stored directly in the mesh data structs. */ Map<AttributeIDRef, AttributeKind> attributes; geometry_set_gather_instances_attribute_info( set_groups, - component_types, + {GEO_COMPONENT_TYPE_MESH}, {"position", "material_index", "normal", "shade_smooth", "crease"}, attributes); - join_attributes( - set_groups, component_types, attributes, static_cast<GeometryComponent &>(dst_component)); + join_attributes(set_groups, + {GEO_COMPONENT_TYPE_MESH}, + attributes, + static_cast<GeometryComponent &>(dst_component)); } static void join_instance_groups_pointcloud(Span<GeometryInstanceGroup> set_groups, @@ -582,24 +552,6 @@ static void join_instance_groups_curve(Span<GeometryInstanceGroup> set_groups, G static_cast<GeometryComponent &>(dst_component)); } -GeometrySet geometry_set_realize_mesh_for_modifier(const GeometrySet &geometry_set) -{ - if (!geometry_set.has_instances() && !geometry_set.has_pointcloud()) { - return geometry_set; - } - - GeometrySet new_geometry_set = geometry_set; - Vector<GeometryInstanceGroup> set_groups; - geometry_set_gather_instances(geometry_set, set_groups); - join_instance_groups_mesh(set_groups, true, new_geometry_set); - /* Remove all instances, even though some might contain other non-mesh data. We can't really - * keep only non-mesh instances in general. */ - new_geometry_set.remove<InstancesComponent>(); - /* If there was a point cloud, it is now part of the mesh. */ - new_geometry_set.remove<PointCloudComponent>(); - return new_geometry_set; -} - GeometrySet geometry_set_realize_instances(const GeometrySet &geometry_set) { if (!geometry_set.has_instances()) { @@ -610,7 +562,7 @@ GeometrySet geometry_set_realize_instances(const GeometrySet &geometry_set) Vector<GeometryInstanceGroup> set_groups; geometry_set_gather_instances(geometry_set, set_groups); - join_instance_groups_mesh(set_groups, false, new_geometry_set); + join_instance_groups_mesh(set_groups, new_geometry_set); join_instance_groups_pointcloud(set_groups, new_geometry_set); join_instance_groups_volume(set_groups, new_geometry_set); join_instance_groups_curve(set_groups, new_geometry_set); diff --git a/source/blender/blenkernel/intern/lib_id.c b/source/blender/blenkernel/intern/lib_id.c index 3b2d2c5d2c3..3c85ba62d07 100644 --- a/source/blender/blenkernel/intern/lib_id.c +++ b/source/blender/blenkernel/intern/lib_id.c @@ -1121,8 +1121,9 @@ void *BKE_libblock_alloc(Main *bmain, short type, const char *name, const int fl id->us = 1; } if ((flag & LIB_ID_CREATE_NO_MAIN) == 0) { - /* Note that 2.8x versioning has tested not to cause conflicts. */ - BLI_assert(bmain->is_locked_for_linking == false || ELEM(type, ID_WS, ID_GR)); + /* Note that 2.8x versioning has tested not to cause conflicts. Node trees are + * skipped in this check to allow adding a geometry node tree for versioning. */ + BLI_assert(bmain->is_locked_for_linking == false || ELEM(type, ID_WS, ID_GR, ID_NT)); ListBase *lb = which_libbase(bmain, type); BKE_main_lock(bmain); diff --git a/source/blender/blenloader/intern/versioning_300.c b/source/blender/blenloader/intern/versioning_300.c index 035642a561a..4c6b70982a4 100644 --- a/source/blender/blenloader/intern/versioning_300.c +++ b/source/blender/blenloader/intern/versioning_300.c @@ -55,6 +55,7 @@ #include "BKE_idprop.h" #include "BKE_lib_id.h" #include "BKE_main.h" +#include "BKE_modifier.h" #include "BKE_node.h" #include "RNA_access.h" @@ -539,6 +540,54 @@ static void version_geometry_nodes_add_realize_instance_nodes(bNodeTree *ntree) } } +/** + * The geometry nodes modifier used to realize instances for the next modifier implicitly. Now it + * is done with the realize instances node. It also used to convert meshes to point clouds + * automatically, which is also now done with a specific node. + */ +static bNodeTree *add_realize_node_tree(Main *bmain) +{ + bNodeTree *node_tree = ntreeAddTree(bmain, "Realize Instances 2.93 Legacy", "GeometryNodeTree"); + + ntreeAddSocketInterface(node_tree, SOCK_IN, "NodeSocketGeometry", "Geometry"); + ntreeAddSocketInterface(node_tree, SOCK_OUT, "NodeSocketGeometry", "Geometry"); + + bNode *group_input = nodeAddStaticNode(NULL, node_tree, NODE_GROUP_INPUT); + group_input->locx = -400.0f; + bNode *group_output = nodeAddStaticNode(NULL, node_tree, NODE_GROUP_OUTPUT); + group_output->locx = 500.0f; + group_output->flag |= NODE_DO_OUTPUT; + + bNode *join = nodeAddStaticNode(NULL, node_tree, GEO_NODE_JOIN_GEOMETRY); + join->locx = group_output->locx - 175.0f; + join->locy = group_output->locy; + bNode *conv = nodeAddStaticNode(NULL, node_tree, GEO_NODE_POINTS_TO_VERTICES); + conv->locx = join->locx - 175.0f; + conv->locy = join->locy - 70.0; + bNode *separate = nodeAddStaticNode(NULL, node_tree, GEO_NODE_SEPARATE_COMPONENTS); + separate->locx = join->locx - 350.0f; + separate->locy = join->locy + 50.0f; + bNode *realize = nodeAddStaticNode(NULL, node_tree, GEO_NODE_REALIZE_INSTANCES); + realize->locx = separate->locx - 200.0f; + realize->locy = join->locy; + + nodeAddLink(node_tree, group_input, group_input->outputs.first, realize, realize->inputs.first); + nodeAddLink(node_tree, realize, realize->outputs.first, separate, separate->inputs.first); + nodeAddLink(node_tree, conv, conv->outputs.first, join, join->inputs.first); + nodeAddLink(node_tree, separate, BLI_findlink(&separate->outputs, 3), join, join->inputs.first); + nodeAddLink(node_tree, separate, BLI_findlink(&separate->outputs, 1), conv, conv->inputs.first); + nodeAddLink(node_tree, separate, BLI_findlink(&separate->outputs, 2), join, join->inputs.first); + nodeAddLink(node_tree, separate, separate->outputs.first, join, join->inputs.first); + nodeAddLink(node_tree, join, join->outputs.first, group_output, group_output->inputs.first); + + LISTBASE_FOREACH (bNode *, node, &node_tree->nodes) { + nodeSetSelected(node, false); + } + + ntreeUpdateTree(bmain, node_tree); + return node_tree; +} + void do_versions_after_linking_300(Main *bmain, ReportList *UNUSED(reports)) { if (MAIN_VERSION_ATLEAST(bmain, 300, 0) && !MAIN_VERSION_ATLEAST(bmain, 300, 1)) { @@ -672,6 +721,38 @@ void do_versions_after_linking_300(Main *bmain, ReportList *UNUSED(reports)) } } + if (!MAIN_VERSION_ATLEAST(bmain, 300, 35)) { + /* Add a new modifier to realize instances from previous modifiers. + * Previously that was done automatically by geometry nodes. */ + bNodeTree *realize_instances_node_tree = NULL; + LISTBASE_FOREACH (Object *, ob, &bmain->objects) { + LISTBASE_FOREACH_MUTABLE (ModifierData *, md, &ob->modifiers) { + if (md->type != eModifierType_Nodes) { + continue; + } + if (md->next == NULL) { + break; + } + if (md->next->type == eModifierType_Nodes) { + continue; + } + NodesModifierData *nmd = (NodesModifierData *)md; + if (nmd->node_group == NULL) { + continue; + } + + NodesModifierData *new_nmd = (NodesModifierData *)BKE_modifier_new(eModifierType_Nodes); + STRNCPY(new_nmd->modifier.name, "Realize Instances 2.93 Legacy"); + BKE_modifier_unique_name(&ob->modifiers, &new_nmd->modifier); + BLI_insertlinkafter(&ob->modifiers, md, new_nmd); + if (realize_instances_node_tree == NULL) { + realize_instances_node_tree = add_realize_node_tree(bmain); + } + new_nmd->node_group = realize_instances_node_tree; + } + } + } + /** * Versioning code until next subversion bump goes here. * diff --git a/source/blender/modifiers/intern/MOD_nodes.cc b/source/blender/modifiers/intern/MOD_nodes.cc index b28fead299d..b5ca5f3545f 100644 --- a/source/blender/modifiers/intern/MOD_nodes.cc +++ b/source/blender/modifiers/intern/MOD_nodes.cc @@ -1093,12 +1093,6 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * modifyGeometry(md, ctx, geometry_set); - if (ctx->flag & MOD_APPLY_TO_BASE_MESH) { - /* In this case it makes sense to realize instances, otherwise in some cases there might be no - * results when applying the modifier. */ - geometry_set = blender::bke::geometry_set_realize_mesh_for_modifier(geometry_set); - } - Mesh *new_mesh = geometry_set.get_component_for_write<MeshComponent>().release(); if (new_mesh == nullptr) { return BKE_mesh_new_nomain(0, 0, 0, 0, 0); |