Geometry Nodes: allow naming geometry sets #114910
@ -197,6 +197,7 @@ class NODE_MT_geometry_node_GEO_GEOMETRY_WRITE(Menu):
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
node_add_menu.add_node_type(layout, "GeometryNodeSetGeometryName")
|
||||
node_add_menu.add_node_type(layout, "GeometryNodeSetID")
|
||||
node_add_menu.add_node_type(layout, "GeometryNodeSetPosition", search_weight=1.0)
|
||||
if context.space_data.geometry_nodes_type == 'TOOL':
|
||||
|
@ -147,6 +147,13 @@ struct GeometrySet {
|
||||
std::array<GeometryComponentPtr, GEO_COMPONENT_TYPE_ENUM_SIZE> components_;
|
||||
|
||||
public:
|
||||
/**
|
||||
* A user defined name for this geometry. It is not expected to be unique. Its main
|
||||
* purpose is help debugging instance trees. It may eventually also be used when exporting
|
||||
* instance trees or when creating separate objects from them.
|
||||
*/
|
||||
std::string name;
|
||||
|
||||
|
||||
/**
|
||||
* The methods are defaulted here so that they are not instantiated in every translation unit.
|
||||
*/
|
||||
@ -420,7 +427,7 @@ struct GeometrySet {
|
||||
friend bool operator==(const GeometrySet &a, const GeometrySet &b)
|
||||
{
|
||||
/* This compares only the component pointers, not the actual geometry data. */
|
||||
return Span(a.components_) == Span(b.components_);
|
||||
return Span(a.components_) == Span(b.components_) && a.name == b.name;
|
||||
}
|
||||
|
||||
private:
|
||||
|
@ -1337,6 +1337,7 @@ void BKE_nodetree_remove_layer_n(bNodeTree *ntree, Scene *scene, int layer_index
|
||||
#define GEO_NODE_INPUT_INSTANCE_TRANSFORM 2137
|
||||
#define GEO_NODE_IMPORT_STL 2138
|
||||
#define GEO_NODE_IMPORT_OBJ 2139
|
||||
#define GEO_NODE_SET_GEOMETRY_NAME 2140
|
||||
|
||||
/** \} */
|
||||
|
||||
|
@ -104,7 +104,7 @@ std::string InstanceReference::name() const
|
||||
case Type::Collection:
|
||||
return this->collection().id.name + 2;
|
||||
case Type::GeometrySet:
|
||||
return IFACE_("Geometry");
|
||||
return this->geometry_set().name;
|
||||
case Type::None:
|
||||
break;
|
||||
}
|
||||
|
@ -1500,6 +1500,9 @@ static void create_inspection_string_for_geometry_info(const geo_log::GeometryIn
|
||||
}
|
||||
|
||||
fmt::format_to(fmt::appender(buf), TIP_("Geometry:"));
|
||||
if (!value_log.name.empty()) {
|
||||
fmt::format_to(fmt::appender(buf), " \"{}\"", value_log.name);
|
||||
}
|
||||
fmt::format_to(fmt::appender(buf), "\n");
|
||||
for (bke::GeometryComponent::Type type : component_types) {
|
||||
switch (type) {
|
||||
|
@ -194,6 +194,7 @@ GeometrySet join_geometries(const Span<GeometrySet> geometries,
|
||||
const bke::AnonymousAttributePropagationInfo &propagation_info)
|
||||
{
|
||||
GeometrySet result;
|
||||
result.name = geometries.is_empty() ? "" : geometries[0].name;
|
||||
static const Array<GeometryComponent::Type> supported_types({GeometryComponent::Type::Mesh,
|
||||
GeometryComponent::Type::PointCloud,
|
||||
GeometryComponent::Type::Instance,
|
||||
|
@ -123,6 +123,7 @@ struct GeometryAttributeInfo {
|
||||
*/
|
||||
class GeometryInfoLog : public ValueLog {
|
||||
public:
|
||||
std::string name;
|
||||
Vector<GeometryAttributeInfo> attributes;
|
||||
Vector<bke::GeometryComponent::Type> component_types;
|
||||
|
||||
|
@ -454,6 +454,7 @@ DefNode(GeometryNode, GEO_NODE_SET_CURVE_HANDLES, 0, "SET_CURVE_HANDLES", SetCur
|
||||
DefNode(GeometryNode, GEO_NODE_SET_CURVE_NORMAL, 0, "SET_CURVE_NORMAL", SetCurveNormal, "Set Curve Normal", "Set the evaluation mode for curve normals")
|
||||
DefNode(GeometryNode, GEO_NODE_SET_CURVE_RADIUS, 0, "SET_CURVE_RADIUS", SetCurveRadius, "Set Curve Radius", "Set the radius of the curve at each control point")
|
||||
DefNode(GeometryNode, GEO_NODE_SET_CURVE_TILT, 0, "SET_CURVE_TILT", SetCurveTilt, "Set Curve Tilt", "Set the tilt angle at each curve control point")
|
||||
DefNode(GeometryNode, GEO_NODE_SET_GEOMETRY_NAME, 0, "SET_GEOMETRY_NAME", SetGeometryName, "Set Geometry Name", "Set the name of a geometry for easier debugging")
|
||||
DefNode(GeometryNode, GEO_NODE_SET_ID, 0, "SET_ID", SetID, "Set ID", "Set the id attribute on the input geometry, mainly used internally for randomizing")
|
||||
DefNode(GeometryNode, GEO_NODE_SET_MATERIAL_INDEX, 0, "SET_MATERIAL_INDEX", SetMaterialIndex, "Set Material Index", "Set the material index for each selected geometry element")
|
||||
DefNode(GeometryNode, GEO_NODE_SET_MATERIAL, 0, "SET_MATERIAL", SetMaterial, "Set Material", "Assign a material to geometry elements")
|
||||
|
@ -185,6 +185,7 @@ set(SRC
|
||||
nodes/node_geo_set_curve_normal.cc
|
||||
nodes/node_geo_set_curve_radius.cc
|
||||
nodes/node_geo_set_curve_tilt.cc
|
||||
nodes/node_geo_set_geometry_name.cc
|
||||
nodes/node_geo_set_id.cc
|
||||
nodes/node_geo_set_instance_transform.cc
|
||||
nodes/node_geo_set_material.cc
|
||||
|
@ -206,10 +206,11 @@ static void node_geo_exec(GeoNodeExecParams params)
|
||||
}
|
||||
selection.finish();
|
||||
}
|
||||
|
||||
geometry::debug_randomize_mesh_order(result);
|
||||
|
||||
params.set_output("Mesh", GeometrySet::from_mesh(result));
|
||||
GeometrySet result_geometry = GeometrySet::from_mesh(result);
|
||||
result_geometry.name = set_a.name;
|
||||
params.set_output("Mesh", std::move(result_geometry));
|
||||
#else
|
||||
params.error_message_add(NodeWarningType::Error,
|
||||
TIP_("Disabled, Blender was compiled without GMP"));
|
||||
|
@ -149,8 +149,10 @@ static void node_geo_exec(GeoNodeExecParams params)
|
||||
const int handle = instances->add_reference(*collection);
|
||||
instances->add_instance(handle, transform);
|
||||
}
|
||||
GeometrySet geometry = GeometrySet::from_instances(instances.release());
|
||||
geometry.name = collection->id.name + 2;
|
||||
|
||||
params.set_output("Instances", GeometrySet::from_instances(instances.release()));
|
||||
params.set_output("Instances", std::move(geometry));
|
||||
}
|
||||
|
||||
static void node_rna(StructRNA *srna)
|
||||
|
@ -18,12 +18,15 @@ static void node_geo_exec(GeoNodeExecParams params)
|
||||
{
|
||||
Vector<GeometrySet> geometries = params.extract_input<Vector<GeometrySet>>("Geometry");
|
||||
std::unique_ptr<bke::Instances> instances = std::make_unique<bke::Instances>();
|
||||
|
||||
for (GeometrySet &geometry : geometries) {
|
||||
geometry.ensure_owns_direct_data();
|
||||
const int handle = instances->add_reference(std::move(geometry));
|
||||
instances->add_instance(handle, float4x4::identity());
|
||||
}
|
||||
params.set_output("Instances", GeometrySet::from_instances(instances.release()));
|
||||
|
||||
GeometrySet new_geometry = GeometrySet::from_instances(instances.release());
|
||||
params.set_output("Instances", std::move(new_geometry));
|
||||
}
|
||||
|
||||
static void node_register()
|
||||
|
@ -869,6 +869,7 @@ static void node_geo_exec(GeoNodeExecParams params)
|
||||
{
|
||||
new_curves.add(*curve_edit_data);
|
||||
}
|
||||
new_curves.name = guide_curves_geometry.name;
|
||||
|
||||
params.set_output("Curves", std::move(new_curves));
|
||||
}
|
||||
|
@ -155,6 +155,7 @@ static void node_geo_exec(GeoNodeExecParams params)
|
||||
}
|
||||
}
|
||||
|
||||
geometry_set.name = object->id.name + 2;
|
||||
params.set_output("Geometry", geometry_set);
|
||||
}
|
||||
|
||||
|
@ -77,8 +77,10 @@ static void node_geo_exec(GeoNodeExecParams params)
|
||||
options.keep_original_ids = false;
|
||||
options.realize_instance_attributes = true;
|
||||
options.propagation_info = params.get_output_propagation_info("Geometry");
|
||||
geometry_set = geometry::realize_instances(geometry_set, options, varied_depth_option);
|
||||
params.set_output("Geometry", std::move(geometry_set));
|
||||
GeometrySet new_geometry_set = geometry::realize_instances(
|
||||
geometry_set, options, varied_depth_option);
|
||||
new_geometry_set.name = geometry_set.name;
|
||||
params.set_output("Geometry", std::move(new_geometry_set));
|
||||
}
|
||||
|
||||
static void node_register()
|
||||
|
@ -30,6 +30,14 @@ static void node_geo_exec(GeoNodeExecParams params)
|
||||
GeometrySet volumes;
|
||||
GeometrySet instances;
|
||||
|
||||
const std::string &name = geometry_set.name;
|
||||
meshes.name = name;
|
||||
curves.name = name;
|
||||
grease_pencil.name = name;
|
||||
point_clouds.name = name;
|
||||
volumes.name = name;
|
||||
instances.name = name;
|
||||
|
||||
if (geometry_set.has<MeshComponent>()) {
|
||||
meshes.add(*geometry_set.get_component<MeshComponent>());
|
||||
}
|
||||
|
@ -0,0 +1,35 @@
|
||||
/* SPDX-FileCopyrightText: 2023 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#include "node_geometry_util.hh"
|
||||
|
||||
namespace blender::nodes::node_geo_set_geometry_name {
|
||||
|
||||
static void node_declare(NodeDeclarationBuilder &b)
|
||||
{
|
||||
b.add_input<decl::Geometry>("Geometry");
|
||||
b.add_input<decl::String>("Name");
|
||||
b.add_output<decl::Geometry>("Geometry").propagate_all();
|
||||
}
|
||||
|
||||
static void node_geo_exec(GeoNodeExecParams params)
|
||||
{
|
||||
GeometrySet geometry_set = params.extract_input<GeometrySet>("Geometry");
|
||||
std::string name = params.extract_input<std::string>("Name");
|
||||
geometry_set.name = std::move(name);
|
||||
params.set_output("Geometry", std::move(geometry_set));
|
||||
}
|
||||
|
||||
static void node_register()
|
||||
{
|
||||
static bke::bNodeType ntype;
|
||||
|
||||
geo_node_type_base(&ntype, GEO_NODE_SET_GEOMETRY_NAME, "Set Geometry Name", NODE_CLASS_GEOMETRY);
|
||||
ntype.geometry_node_execute = node_geo_exec;
|
||||
ntype.declare = node_declare;
|
||||
bke::nodeRegisterType(&ntype);
|
||||
}
|
||||
NOD_REGISTER_NODE(node_register)
|
||||
|
||||
} // namespace blender::nodes::node_geo_set_geometry_name
|
@ -330,6 +330,8 @@ static void node_geo_exec(GeoNodeExecParams params)
|
||||
dst_instances->add_reference(std::move(group_geometry));
|
||||
}
|
||||
|
||||
dst_geometry.name = src_geometry.name;
|
||||
|
||||
geometry::debug_randomize_instance_order(dst_instances);
|
||||
|
||||
params.set_output("Instances", std::move(dst_geometry));
|
||||
|
@ -62,6 +62,8 @@ FieldInfoLog::FieldInfoLog(const GField &field) : type(field.cpp_type())
|
||||
|
||||
GeometryInfoLog::GeometryInfoLog(const bke::GeometrySet &geometry_set)
|
||||
{
|
||||
this->name = geometry_set.name;
|
||||
|
||||
static std::array all_component_types = {bke::GeometryComponent::Type::Curve,
|
||||
bke::GeometryComponent::Type::Instance,
|
||||
bke::GeometryComponent::Type::Mesh,
|
||||
|
Loading…
Reference in New Issue
Block a user
This string can not be shared and will be cause of large memory usage in common case with a lot of levels of nesting instances. In one level, here is just one instance handler so there is no a lot of geometry copy. But in case there is 2 levels, there is N copies of geometry. And since this string is not limited for its length here is can be really long text.
It does use some extra memory, but I don't quite get the case that you describe. The
GeometrySet
is not stored for each instance separately, so it's not copied as often as you make it sound. I don't think this is something we need to be concerned about right now. There are ways to optimize it if we really need to in the future, but those also increase complexity.The case that i describe is:
GeometrySet -> InstanceComponent -> InstanceHandle -> GeometrySet -> InstanceComponent -> InstanceHandle -> GeometrySet.
In this chain, 1 first geometry set, 1 second geometry set that is instantiated. So, last one is also just one.
But let there will be 2 different geometry at second level, with the same instances at 3 level. Now here is 2 copy of the most nested geometry.
Yeah, not a cause of concern for me currently.