diff options
Diffstat (limited to 'source/blender/nodes/geometry/nodes/node_geo_collapse.cc')
-rw-r--r-- | source/blender/nodes/geometry/nodes/node_geo_collapse.cc | 103 |
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); } |