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
path: root/source
diff options
context:
space:
mode:
Diffstat (limited to 'source')
-rw-r--r--source/blender/bmesh/intern/bmesh_mesh.c75
-rw-r--r--source/blender/bmesh/intern/bmesh_mesh.h8
-rw-r--r--source/blender/makesdna/DNA_node_types.h12
-rw-r--r--source/blender/nodes/geometry/CMakeLists.txt3
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_collapse.cc103
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_dissolve.cc88
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_unsubdivide.cc67
7 files changed, 165 insertions, 191 deletions
diff --git a/source/blender/bmesh/intern/bmesh_mesh.c b/source/blender/bmesh/intern/bmesh_mesh.c
index 61c5fdb75e4..b8d4210dba2 100644
--- a/source/blender/bmesh/intern/bmesh_mesh.c
+++ b/source/blender/bmesh/intern/bmesh_mesh.c
@@ -1364,79 +1364,4 @@ void BM_mesh_vert_coords_apply_with_mat4(BMesh *bm,
mul_v3_m4v3(v->co, mat, vert_coords[i]);
}
}
-
-/**
- * Use to select bmesh vertex data based on an array of bool.
- */
-void BM_select_vertices(BMesh *bm, const bool *mask)
-{
- BMIter iter;
- BMVert *v;
- int i;
- BM_ITER_MESH_INDEX (v, &iter, bm, BM_VERTS_OF_MESH, i) {
- BM_elem_flag_set(v, BM_ELEM_SELECT, mask[i]);
- }
-}
-
-/**
- * Use to select bmesh edge data based on an array of bool.
- */
-void BM_select_edges(BMesh *bm, const bool *mask)
-{
- BMIter iter;
- BMEdge *e;
- int i;
- BM_ITER_MESH_INDEX (e, &iter, bm, BM_EDGES_OF_MESH, i) {
- BM_elem_flag_set(e, BM_ELEM_SELECT, mask[i]);
- }
-}
-
-/**
- * Use to select bmesh face data based on an array of bool.
- */
-void BM_select_faces(BMesh *bm, const bool *mask)
-{
- BMIter iter;
- BMFace *f;
- int i;
- BM_ITER_MESH_INDEX (f, &iter, bm, BM_FACES_OF_MESH, i) {
- BM_elem_flag_set(f, BM_ELEM_SELECT, mask[i]);
- }
-}
-
-void BM_tag_vertices(BMesh *bm, const bool *mask)
-{
- BMIter iter;
- BMVert *v;
- int i;
- BM_ITER_MESH_INDEX (v, &iter, bm, BM_VERTS_OF_MESH, i) {
- BM_elem_flag_set(v, BM_ELEM_TAG, mask[i]);
- }
-}
-
-/**
- * Use to temporary tag bmesh edge data based on an array of bool.
- */
-void BM_tag_edges(BMesh *bm, const bool *mask)
-{
- BMIter iter;
- BMEdge *e;
- int i;
- BM_ITER_MESH_INDEX (e, &iter, bm, BM_EDGES_OF_MESH, i) {
- BM_elem_flag_set(e, BM_ELEM_TAG, mask[i]);
- }
-}
-
-/**
- * Use to temporary tag bmesh face data based on an array of bool.
- */
-void BM_tag_faces(BMesh *bm, const bool *mask)
-{
- BMIter iter;
- BMFace *f;
- int i;
- BM_ITER_MESH_INDEX (f, &iter, bm, BM_FACES_OF_MESH, i) {
- BM_elem_flag_set(f, BM_ELEM_TAG, mask[i]);
- }
-}
/** \} */
diff --git a/source/blender/bmesh/intern/bmesh_mesh.h b/source/blender/bmesh/intern/bmesh_mesh.h
index 3c0eb700d37..51a60aae5c9 100644
--- a/source/blender/bmesh/intern/bmesh_mesh.h
+++ b/source/blender/bmesh/intern/bmesh_mesh.h
@@ -217,10 +217,4 @@ float (*BM_mesh_vert_coords_alloc(BMesh *bm, int *r_vert_len))[3];
void BM_mesh_vert_coords_apply(BMesh *bm, const float (*vert_coords)[3]);
void BM_mesh_vert_coords_apply_with_mat4(BMesh *bm,
const float (*vert_coords)[3],
- const float mat[4][4]);
-void BM_select_vertices(BMesh *bm, const bool *mask);
-void BM_select_edges(BMesh *bm, const bool *mask);
-void BM_select_faces(BMesh *bm, const bool *mask);
-void BM_tag_vertices(BMesh *bm, const bool *mask);
-void BM_tag_edges(BMesh *bm, const bool *mask);
-void BM_tag_faces(BMesh *bm, const bool *mask); \ No newline at end of file
+ const float mat[4][4]); \ No newline at end of file
diff --git a/source/blender/makesdna/DNA_node_types.h b/source/blender/makesdna/DNA_node_types.h
index 127fb901270..8e6f6808d88 100644
--- a/source/blender/makesdna/DNA_node_types.h
+++ b/source/blender/makesdna/DNA_node_types.h
@@ -2380,6 +2380,18 @@ typedef enum GeometryNodeScaleElementsMode {
GEO_NODE_SCALE_ELEMENTS_SINGLE_AXIS = 1,
} GeometryNodeScaleElementsMode;
+typedef enum GeometryNodeCollapseSymmetryAxis {
+ GEO_NODE_COLLAPSE_SYMMETRY_AXIS_NONE = -1,
+ GEO_NODE_COLLAPSE_SYMMETRY_AXIS_X = 0,
+ GEO_NODE_COLLAPSE_SYMMETRY_AXIS_Y = 1,
+ GEO_NODE_COLLAPSE_SYMMETRY_AXIS_Z = 2,
+} GeometryNodeCollapseSymmetryAxis;
+
+typedef enum GeometryNodeDissolveDelimiter {
+ GEO_NODE_DISSOLVE_DELIMITTER_UNSELECTED = 0,
+ GEO_NODE_DISSOLVE_DELIMITTER_LIMIT = 1,
+ GEO_NODE_DISSOLVE_DELIMITTER_SELECTION_BORDER = 2,
+} GeometryNodeDissolveDelimiter;
#ifdef __cplusplus
}
#endif
diff --git a/source/blender/nodes/geometry/CMakeLists.txt b/source/blender/nodes/geometry/CMakeLists.txt
index b4add633b0c..6d33d402e4a 100644
--- a/source/blender/nodes/geometry/CMakeLists.txt
+++ b/source/blender/nodes/geometry/CMakeLists.txt
@@ -87,6 +87,7 @@ set(SRC
nodes/node_geo_attribute_statistic.cc
nodes/node_geo_boolean.cc
nodes/node_geo_bounding_box.cc
+ nodes/node_geo_collapse.cc
nodes/node_geo_collection_info.cc
nodes/node_geo_common.cc
nodes/node_geo_convex_hull.cc
@@ -114,6 +115,7 @@ set(SRC
nodes/node_geo_curve_to_points.cc
nodes/node_geo_curve_trim.cc
nodes/node_geo_delete_geometry.cc
+ nodes/node_geo_dissolve.cc
nodes/node_geo_distribute_points_on_faces.cc
nodes/node_geo_dual_mesh.cc
nodes/node_geo_edge_split.cc
@@ -192,6 +194,7 @@ set(SRC
nodes/node_geo_transform.cc
nodes/node_geo_translate_instances.cc
nodes/node_geo_triangulate.cc
+ nodes/node_geo_unsubdivide.cc
nodes/node_geo_viewer.cc
nodes/node_geo_volume_to_mesh.cc
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);
}
diff --git a/source/blender/nodes/geometry/nodes/node_geo_dissolve.cc b/source/blender/nodes/geometry/nodes/node_geo_dissolve.cc
index 3d41fa80e75..5c5384124a4 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_dissolve.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_dissolve.cc
@@ -27,20 +27,22 @@
#include "math.h"
#include "node_geometry_util.hh"
-static bNodeSocketTemplate geo_node_dissolve_in[] = {
- {SOCK_GEOMETRY, N_("Geometry")},
- {SOCK_FLOAT, N_("Angle"), 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, M_PI, PROP_ANGLE},
- {SOCK_BOOLEAN, N_("All Boundaries"), false},
- {SOCK_STRING, N_("Selection")},
- {-1, ""},
-};
-
-static bNodeSocketTemplate geo_node_dissolve_out[] = {
- {SOCK_GEOMETRY, N_("Geometry")},
- {-1, ""},
-};
-
-static void geo_node_dissolve_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+namespace blender::nodes::node_geo_dissolve {
+
+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_("Angle"))
+ .default_value(0.0f)
+ .min(0.0f)
+ .max(M_PI)
+ .subtype(PROP_ANGLE);
+ b.add_input<decl::Bool>(N_("All Boundaries")).default_value(false);
+ 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);
@@ -56,11 +58,10 @@ static void geo_node_dissolve_init(bNodeTree *UNUSED(tree), bNode *node)
node_storage->selection_type = GEO_NODE_DISSOLVE_DELIMITTER_UNSELECTED;
}
-namespace blender::nodes {
static Mesh *dissolve_mesh(const float angle,
const bool all_boundaries,
const int delimiter,
- const Span<bool> selection,
+ const IndexMask selection,
const Mesh *mesh)
{
const BMeshCreateParams bmesh_create_params = {0};
@@ -68,10 +69,18 @@ static Mesh *dissolve_mesh(const float angle,
true, 0, 0, 0, {CD_MASK_ORIGINDEX, CD_MASK_ORIGINDEX, CD_MASK_ORIGINDEX}};
BMesh *bm = BKE_mesh_to_bmesh_ex(mesh, &bmesh_create_params, &bmesh_from_mesh_params);
if (delimiter & BMO_DELIM_FACE_SELECTION) {
- BM_tag_faces(bm, selection.data());
+ // BM_tag_faces(bm, selection.data());
+ BM_mesh_elem_table_ensure(bm, BM_FACE);
+ for (int i_face : selection) {
+ BM_elem_flag_set(BM_face_at_index(bm, i_face), BM_ELEM_TAG, true);
+ }
}
else {
- BM_select_edges(bm, selection.data());
+ // BM_select_edges(bm, selection.data());
+ for (int i_edge : selection) {
+ BM_mesh_elem_table_ensure(bm, BM_EDGE);
+ BM_elem_flag_set(BM_edge_at_index(bm, i_edge), BM_ELEM_SELECT, true);
+ }
}
BM_mesh_decimate_dissolve(bm, angle, all_boundaries, (BMO_Delimit)delimiter);
@@ -82,9 +91,9 @@ static Mesh *dissolve_mesh(const float angle,
return result;
}
-static void geo_node_dissolve_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 angle = params.extract_input<float>("Angle");
if (angle > 0.0f && geometry_set.has_mesh()) {
@@ -95,7 +104,7 @@ static void geo_node_dissolve_exec(GeoNodeExecParams params)
const bNode &node = params.node();
const NodeGeometryDissolve &node_storage = *(NodeGeometryDissolve *)node.storage;
- bool default_selection = false;
+ // bool default_selection = false;
AttributeDomain selection_domain = ATTR_DOMAIN_FACE;
BMO_Delimit delimiter = BMO_DELIM_FACE_SELECTION;
@@ -106,32 +115,41 @@ static void geo_node_dissolve_exec(GeoNodeExecParams params)
else if (node_storage.selection_type == GEO_NODE_DISSOLVE_DELIMITTER_LIMIT) {
selection_domain = ATTR_DOMAIN_EDGE;
delimiter = BMO_DELIM_EDGE_SELECTION;
- default_selection = true;
+ // default_selection = true;
};
- GVArray_Typed<bool> selection_attribute = params.get_input_attribute<bool>(
- "Selection", mesh_component, selection_domain, default_selection);
- VArray_Span<bool> selection{selection_attribute};
-
- Mesh *result = dissolve_mesh(angle, all_boundaries, delimiter, selection, input_mesh);
- geometry_set.replace_mesh(result);
+ Field<bool> selection_field = params.extract_input<Field<bool>>("Selection");
+ const int domain_size = mesh_component.attribute_domain_size(selection_domain);
+ GeometryComponentFieldContext context{mesh_component, selection_domain};
+ FieldEvaluator evaluator{context, domain_size};
+ evaluator.add(selection_field);
+ evaluator.evaluate();
+ const IndexMask selection = evaluator.get_evaluated_as_mask(0);
+
+ geometry_set.modify_geometry_sets([&](GeometrySet &geometry_set) {
+ Mesh *result = dissolve_mesh(angle, all_boundaries, delimiter, selection, input_mesh);
+ geometry_set.replace_mesh(result);
+ });
}
- params.set_output("Geometry", std::move(geometry_set));
+ params.set_output("Mesh", std::move(geometry_set));
}
-} // namespace blender::nodes
+} // namespace blender::nodes::node_geo_dissolve
void register_node_type_geo_dissolve()
{
+ namespace file_ns = blender::nodes::node_geo_dissolve;
+
static bNodeType ntype;
- geo_node_type_base(&ntype, GEO_NODE_DISSOLVE, "Dissolve", NODE_CLASS_GEOMETRY, 0);
- node_type_socket_templates(&ntype, geo_node_dissolve_in, geo_node_dissolve_out);
+ geo_node_type_base(&ntype, GEO_NODE_DISSOLVE, "Dissolve", NODE_CLASS_GEOMETRY);
+ ntype.declare = file_ns::node_declare;
+
node_type_storage(
&ntype, "NodeGeometryDissolve", node_free_standard_storage, node_copy_standard_storage);
- node_type_init(&ntype, geo_node_dissolve_init);
- ntype.geometry_node_execute = blender::nodes::geo_node_dissolve_exec;
- ntype.draw_buttons = geo_node_dissolve_layout;
+ node_type_init(&ntype, file_ns::geo_node_dissolve_init);
+ ntype.geometry_node_execute = file_ns::node_geo_exec;
+ ntype.draw_buttons = file_ns::node_layout;
ntype.width = 165;
nodeRegisterType(&ntype);
} \ No newline at end of file
diff --git a/source/blender/nodes/geometry/nodes/node_geo_unsubdivide.cc b/source/blender/nodes/geometry/nodes/node_geo_unsubdivide.cc
index 7f0fc66ff28..fd9b6dbaff5 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_unsubdivide.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_unsubdivide.cc
@@ -23,27 +23,28 @@
#include "bmesh_tools.h"
#include "node_geometry_util.hh"
-static bNodeSocketTemplate geo_node_unsubdivide_in[] = {
- {SOCK_GEOMETRY, N_("Geometry")},
- {SOCK_INT, N_("Iterations"), 1, 0, 0, 0, 0, 10},
- {SOCK_STRING, N_("Selection")},
- {-1, ""},
-};
+namespace blender::nodes::node_geo_unsubdivide {
-static bNodeSocketTemplate geo_node_unsubdivide_out[] = {
- {SOCK_GEOMETRY, N_("Geometry")},
- {-1, ""},
-};
-
-namespace blender::nodes {
+static void node_declare(NodeDeclarationBuilder &b)
+{
+ b.add_input<decl::Geometry>(N_("Mesh")).supported_type(GEO_COMPONENT_TYPE_MESH);
+ b.add_input<decl::Int>(N_("Iterations")).default_value(1).min(0).max(10);
+ b.add_input<decl::Bool>(N_("Selection")).default_value(true).supports_field().hide_value();
+ b.add_output<decl::Geometry>(N_("Mesh"));
+}
-static Mesh *unsubdivide_mesh(const int iterations, const Array<bool> &selection, const Mesh *mesh)
+static Mesh *unsubdivide_mesh(const int iterations, const IndexMask selection, const Mesh *mesh)
{
const BMeshCreateParams bmesh_create_params = {0};
const BMeshFromMeshParams bmesh_from_mesh_params = {
true, 0, 0, 0, {CD_MASK_ORIGINDEX, CD_MASK_ORIGINDEX, CD_MASK_ORIGINDEX}};
BMesh *bm = BKE_mesh_to_bmesh_ex(mesh, &bmesh_create_params, &bmesh_from_mesh_params);
- BM_tag_vertices(bm, selection.data());
+
+ BM_mesh_elem_table_ensure(bm, BM_VERT);
+ for (int i_point : selection) {
+ BM_elem_flag_set(BM_vert_at_index(bm, i_point), BM_ELEM_TAG, true);
+ }
+
BM_mesh_decimate_unsubdivide_ex(bm, iterations, true);
Mesh *result = BKE_mesh_from_bmesh_for_eval_nomain(bm, NULL, mesh);
@@ -53,35 +54,41 @@ static Mesh *unsubdivide_mesh(const int iterations, const Array<bool> &selection
return result;
}
-static void geo_node_unsubdivide_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 int iterations = params.extract_input<int>("Iterations");
if (iterations > 0 && geometry_set.has_mesh()) {
const MeshComponent &mesh_component = geometry_set.get_component_for_write<MeshComponent>();
const Mesh *input_mesh = mesh_component.get_for_read();
- const bool default_selection = true;
- GVArray_Typed<bool> selection_attribute = params.get_input_attribute<bool>(
- "Selection", mesh_component, ATTR_DOMAIN_POINT, default_selection);
- VArray_Span<bool> selection{selection_attribute};
+ 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();
+ const IndexMask selection = evaluator.get_evaluated_as_mask(0);
- Mesh *result = unsubdivide_mesh(iterations, selection, input_mesh);
- if (result != input_mesh) {
- geometry_set.replace_mesh(result);
- }
+ geometry_set.modify_geometry_sets([&](GeometrySet &geometry_set) {
+ Mesh *result = unsubdivide_mesh(iterations, selection, input_mesh);
+ if (result != input_mesh) {
+ geometry_set.replace_mesh(result);
+ }
+ });
}
- params.set_output("Geometry", std::move(geometry_set));
+ params.set_output("Mesh", std::move(geometry_set));
}
-} // namespace blender::nodes
+} // namespace blender::nodes::node_geo_unsubdivide
void register_node_type_geo_unsubdivide()
{
+ namespace file_ns = blender::nodes::node_geo_unsubdivide;
+
static bNodeType ntype;
- geo_node_type_base(&ntype, GEO_NODE_UNSUBDIVIDE, "Unsubdivide", NODE_CLASS_GEOMETRY, 0);
- node_type_socket_templates(&ntype, geo_node_unsubdivide_in, geo_node_unsubdivide_out);
- ntype.geometry_node_execute = blender::nodes::geo_node_unsubdivide_exec;
- ntype.width = 165;
+ geo_node_type_base(&ntype, GEO_NODE_UNSUBDIVIDE, "Unsubdivide", NODE_CLASS_GEOMETRY);
+ ntype.declare = file_ns::node_declare;
+ ntype.geometry_node_execute = file_ns::node_geo_exec;
nodeRegisterType(&ntype);
}