Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/nodes/geometry/nodes/node_geo_collapse.cc')
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_collapse.cc103
1 files changed, 59 insertions, 44 deletions
diff --git a/source/blender/nodes/geometry/nodes/node_geo_collapse.cc b/source/blender/nodes/geometry/nodes/node_geo_collapse.cc
index c13ab362f17..899afcc68d3 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_collapse.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_collapse.cc
@@ -27,19 +27,20 @@
#include "node_geometry_util.hh"
-static bNodeSocketTemplate geo_node_collapse_in[] = {
- {SOCK_GEOMETRY, N_("Geometry")},
- {SOCK_FLOAT, N_("Factor"), 1.0f, 0.0f, 0.0f, 0.0f, 0, 1.0f, PROP_FACTOR},
- {SOCK_STRING, N_("Selection")},
- {-1, ""},
-};
-
-static bNodeSocketTemplate geo_node_collapse_out[] = {
- {SOCK_GEOMETRY, N_("Geometry")},
- {-1, ""},
-};
-
-static void geo_node_collapse_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+namespace blender::nodes::node_geo_collapse {
+static void node_declare(NodeDeclarationBuilder &b)
+{
+ b.add_input<decl::Geometry>(N_("Mesh")).supported_type(GEO_COMPONENT_TYPE_MESH);
+ b.add_input<decl::Float>(N_("Factor"))
+ .default_value(1.0f)
+ .min(0.0f)
+ .max(1.0f)
+ .subtype(PROP_FACTOR);
+ b.add_input<decl::Bool>(N_("Selection")).default_value(true).supports_field().hide_value();
+ b.add_output<decl::Geometry>(N_("Mesh"));
+}
+
+static void node_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
{
uiLayoutSetPropSep(layout, true);
uiLayoutSetPropDecorate(layout, false);
@@ -55,10 +56,8 @@ static void geo_node_collapse_init(bNodeTree *UNUSED(tree), bNode *node)
node_storage->symmetry_axis = GEO_NODE_COLLAPSE_SYMMETRY_AXIS_NONE;
}
-namespace blender::nodes {
-
static Mesh *collapse_mesh(const float factor,
- const VArray<float> &selection,
+ const IndexMask selection,
const bool triangulate,
const int symmetry_axis,
const Mesh *mesh)
@@ -69,11 +68,17 @@ static Mesh *collapse_mesh(const float factor,
BMesh *bm = BKE_mesh_to_bmesh_ex(mesh, &bmesh_create_params, &bmesh_from_mesh_params);
const float symmetry_eps = 0.00002f;
- Array<float> mask(selection.size());
- selection.materialize(mask);
+
+ /* Selection (bool) is converted to float array because BM_mesh_decimate_collapse takes it this
+ * way. While from the description one could think that BM_mesh_decimate_collapse uses the actual
+ * weight, it just uses it as mask. */
+ Array<float> weights(mesh->totvert);
+ for (int i_vert : selection) {
+ weights[i_vert] = 1.0f;
+ }
BM_mesh_decimate_collapse(
- bm, factor, mask.data(), 1.0f, triangulate, symmetry_axis, symmetry_eps);
+ bm, factor, weights.begin(), 1.0f, triangulate, symmetry_axis, symmetry_eps);
Mesh *result = BKE_mesh_from_bmesh_for_eval_nomain(bm, NULL, mesh);
BM_mesh_free(bm);
@@ -81,42 +86,52 @@ static Mesh *collapse_mesh(const float factor,
return result;
}
-static void geo_node_collapse_exec(GeoNodeExecParams params)
+static void node_geo_exec(GeoNodeExecParams params)
{
- GeometrySet geometry_set = params.extract_input<GeometrySet>("Geometry");
+ GeometrySet geometry_set = params.extract_input<GeometrySet>("Mesh");
const float factor = params.extract_input<float>("Factor");
- if (factor < 1.0f && geometry_set.has_mesh()) {
- MeshComponent &mesh_component = geometry_set.get_component_for_write<MeshComponent>();
-
- const float default_factor = 1.0f;
- GVArray_Typed<float> selection_attribute = params.get_input_attribute<float>(
- "Selection", mesh_component, ATTR_DOMAIN_POINT, default_factor);
- // VArray<float> selection(selection_attribute.to);
- const Mesh *input_mesh = mesh_component.get_for_read();
-
- const bNode &node = params.node();
- const NodeGeometryCollapse &node_storage = *(NodeGeometryCollapse *)node.storage;
- Mesh *result = collapse_mesh(
- factor, selection_attribute, false, node_storage.symmetry_axis, input_mesh);
- geometry_set.replace_mesh(result);
- }
-
- params.set_output("Geometry", std::move(geometry_set));
+ MeshComponent &mesh_component = geometry_set.get_component_for_write<MeshComponent>();
+
+ Field<bool> selection_field = params.extract_input<Field<bool>>("Selection");
+ const int domain_size = mesh_component.attribute_domain_size(ATTR_DOMAIN_POINT);
+ GeometryComponentFieldContext context{mesh_component, ATTR_DOMAIN_POINT};
+ FieldEvaluator evaluator{context, domain_size};
+ evaluator.add(selection_field);
+ evaluator.evaluate();
+
+ geometry_set.modify_geometry_sets([&](GeometrySet &geometry_set) {
+ if (geometry_set.has_mesh()) {
+ const Mesh *input_mesh = mesh_component.get_for_read();
+
+ const bNode &node = params.node();
+ const NodeGeometryCollapse &node_storage = *(NodeGeometryCollapse *)node.storage;
+ Mesh *result = collapse_mesh(factor,
+ evaluator.get_evaluated_as_mask(0),
+ false,
+ node_storage.symmetry_axis,
+ input_mesh);
+ geometry_set.replace_mesh(result);
+ }
+ });
+
+ params.set_output("Mesh", std::move(geometry_set));
}
-} // namespace blender::nodes
+} // namespace blender::nodes::node_geo_collapse
void register_node_type_geo_collapse()
{
+ namespace file_ns = blender::nodes::node_geo_collapse;
+
static bNodeType ntype;
- geo_node_type_base(&ntype, GEO_NODE_COLLAPSE, "Collapse", NODE_CLASS_GEOMETRY, 0);
- node_type_socket_templates(&ntype, geo_node_collapse_in, geo_node_collapse_out);
+ geo_node_type_base(&ntype, GEO_NODE_COLLAPSE, "Collapse", NODE_CLASS_GEOMETRY);
+ ntype.declare = file_ns::node_declare;
node_type_storage(
&ntype, "NodeGeometryCollapse", node_free_standard_storage, node_copy_standard_storage);
- node_type_init(&ntype, geo_node_collapse_init);
- ntype.geometry_node_execute = blender::nodes::geo_node_collapse_exec;
- ntype.draw_buttons = geo_node_collapse_layout;
+ node_type_init(&ntype, file_ns::geo_node_collapse_init);
+ ntype.geometry_node_execute = file_ns::node_geo_exec;
+ ntype.draw_buttons = file_ns::node_layout;
ntype.width = 180;
nodeRegisterType(&ntype);
}