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')
-rw-r--r--source/blender/nodes/geometry/nodes/legacy/node_geo_material_assign.cc95
-rw-r--r--source/blender/nodes/geometry/nodes/legacy/node_geo_select_by_material.cc (renamed from source/blender/nodes/geometry/nodes/node_geo_select_by_material.cc)12
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_attribute_remove.cc29
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_attribute_sample_texture.cc2
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_attribute_vector_rotate.cc48
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_boolean.cc41
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_collection_info.cc2
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_curve_primitive_spiral.cc2
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_curve_reverse.cc62
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_curve_to_mesh.cc3
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_delete_geometry.cc2
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_join_geometry.cc27
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_material_assign.cc31
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_material_selection.cc131
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_object_info.cc2
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_point_instance.cc4
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_set_position.cc2
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_subdivision_surface.cc7
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_transform.cc3
19 files changed, 315 insertions, 190 deletions
diff --git a/source/blender/nodes/geometry/nodes/legacy/node_geo_material_assign.cc b/source/blender/nodes/geometry/nodes/legacy/node_geo_material_assign.cc
new file mode 100644
index 00000000000..7d3481c1067
--- /dev/null
+++ b/source/blender/nodes/geometry/nodes/legacy/node_geo_material_assign.cc
@@ -0,0 +1,95 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "node_geometry_util.hh"
+
+#include "UI_interface.h"
+#include "UI_resources.h"
+
+#include "DNA_mesh_types.h"
+#include "DNA_meshdata_types.h"
+
+#include "BKE_material.h"
+
+namespace blender::nodes {
+
+static void geo_node_legacy_material_assign_declare(NodeDeclarationBuilder &b)
+{
+ b.add_input<decl::Geometry>("Geometry");
+ b.add_input<decl::Material>("Material").hide_label(true);
+ b.add_input<decl::String>("Selection");
+ b.add_output<decl::Geometry>("Geometry");
+}
+
+static void assign_material_to_faces(Mesh &mesh, const VArray<bool> &face_mask, Material *material)
+{
+ int new_material_index = -1;
+ for (const int i : IndexRange(mesh.totcol)) {
+ Material *other_material = mesh.mat[i];
+ if (other_material == material) {
+ new_material_index = i;
+ break;
+ }
+ }
+ if (new_material_index == -1) {
+ /* Append a new material index. */
+ new_material_index = mesh.totcol;
+ BKE_id_material_eval_assign(&mesh.id, new_material_index + 1, material);
+ }
+
+ mesh.mpoly = (MPoly *)CustomData_duplicate_referenced_layer(&mesh.pdata, CD_MPOLY, mesh.totpoly);
+ for (const int i : IndexRange(mesh.totpoly)) {
+ if (face_mask[i]) {
+ MPoly &poly = mesh.mpoly[i];
+ poly.mat_nr = new_material_index;
+ }
+ }
+}
+
+static void geo_node_legacy_material_assign_exec(GeoNodeExecParams params)
+{
+ Material *material = params.extract_input<Material *>("Material");
+ const std::string mask_name = params.extract_input<std::string>("Selection");
+
+ GeometrySet geometry_set = params.extract_input<GeometrySet>("Geometry");
+
+ geometry_set = geometry_set_realize_instances(geometry_set);
+
+ if (geometry_set.has<MeshComponent>()) {
+ MeshComponent &mesh_component = geometry_set.get_component_for_write<MeshComponent>();
+ Mesh *mesh = mesh_component.get_for_write();
+ if (mesh != nullptr) {
+ GVArray_Typed<bool> face_mask = mesh_component.attribute_get_for_read<bool>(
+ mask_name, ATTR_DOMAIN_FACE, true);
+ assign_material_to_faces(*mesh, face_mask, material);
+ }
+ }
+
+ params.set_output("Geometry", std::move(geometry_set));
+}
+
+} // namespace blender::nodes
+
+void register_node_type_geo_legacy_material_assign()
+{
+ static bNodeType ntype;
+
+ geo_node_type_base(
+ &ntype, GEO_NODE_LEGACY_MATERIAL_ASSIGN, "Material Assign", NODE_CLASS_GEOMETRY, 0);
+ ntype.declare = blender::nodes::geo_node_legacy_material_assign_declare;
+ ntype.geometry_node_execute = blender::nodes::geo_node_legacy_material_assign_exec;
+ nodeRegisterType(&ntype);
+}
diff --git a/source/blender/nodes/geometry/nodes/node_geo_select_by_material.cc b/source/blender/nodes/geometry/nodes/legacy/node_geo_select_by_material.cc
index 40c990346e5..eabdd2bcd5a 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_select_by_material.cc
+++ b/source/blender/nodes/geometry/nodes/legacy/node_geo_select_by_material.cc
@@ -28,10 +28,10 @@
namespace blender::nodes {
-static void geo_node_select_by_material_declare(NodeDeclarationBuilder &b)
+static void geo_node_legacy_select_by_material_declare(NodeDeclarationBuilder &b)
{
b.add_input<decl::Geometry>("Geometry");
- b.add_input<decl::Material>("Material").hide_label(true);
+ b.add_input<decl::Material>("Material").hide_label();
b.add_input<decl::String>("Selection");
b.add_output<decl::Geometry>("Geometry");
}
@@ -54,7 +54,7 @@ static void select_mesh_by_material(const Mesh &mesh,
});
}
-static void geo_node_select_by_material_exec(GeoNodeExecParams params)
+static void geo_node_legacy_select_by_material_exec(GeoNodeExecParams params)
{
Material *material = params.extract_input<Material *>("Material");
const std::string selection_name = params.extract_input<std::string>("Selection");
@@ -80,13 +80,13 @@ static void geo_node_select_by_material_exec(GeoNodeExecParams params)
} // namespace blender::nodes
-void register_node_type_geo_select_by_material()
+void register_node_type_geo_legacy_select_by_material()
{
static bNodeType ntype;
geo_node_type_base(
&ntype, GEO_NODE_LEGACY_SELECT_BY_MATERIAL, "Select by Material", NODE_CLASS_GEOMETRY, 0);
- ntype.declare = blender::nodes::geo_node_select_by_material_declare;
- ntype.geometry_node_execute = blender::nodes::geo_node_select_by_material_exec;
+ ntype.declare = blender::nodes::geo_node_legacy_select_by_material_declare;
+ ntype.geometry_node_execute = blender::nodes::geo_node_legacy_select_by_material_exec;
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/geometry/nodes/node_geo_attribute_remove.cc b/source/blender/nodes/geometry/nodes/node_geo_attribute_remove.cc
index e4f3230ebb9..21a9a338857 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_attribute_remove.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_attribute_remove.cc
@@ -16,28 +16,15 @@
#include "node_geometry_util.hh"
-static bNodeSocketTemplate geo_node_attribute_remove_in[] = {
- {SOCK_GEOMETRY, N_("Geometry")},
- {SOCK_STRING,
- N_("Attribute"),
- 0.0f,
- 0.0f,
- 0.0f,
- 1.0f,
- -1.0f,
- 1.0f,
- PROP_NONE,
- SOCK_MULTI_INPUT},
- {-1, ""},
-};
-
-static bNodeSocketTemplate geo_node_attribute_remove_out[] = {
- {SOCK_GEOMETRY, N_("Geometry")},
- {-1, ""},
-};
-
namespace blender::nodes {
+static void geo_node_attribute_remove_declare(NodeDeclarationBuilder &b)
+{
+ b.add_input<decl::Geometry>("Geometry");
+ b.add_input<decl::String>("Attribute").multi_input();
+ b.add_output<decl::Geometry>("Geometry");
+}
+
static void remove_attribute(GeometryComponent &component,
GeoNodeExecParams &params,
Span<std::string> attribute_names)
@@ -85,7 +72,7 @@ void register_node_type_geo_attribute_remove()
geo_node_type_base(
&ntype, GEO_NODE_ATTRIBUTE_REMOVE, "Attribute Remove", NODE_CLASS_ATTRIBUTE, 0);
- node_type_socket_templates(&ntype, geo_node_attribute_remove_in, geo_node_attribute_remove_out);
ntype.geometry_node_execute = blender::nodes::geo_node_attribute_remove_exec;
+ ntype.declare = blender::nodes::geo_node_attribute_remove_declare;
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/geometry/nodes/node_geo_attribute_sample_texture.cc b/source/blender/nodes/geometry/nodes/node_geo_attribute_sample_texture.cc
index c4fd0ca4008..52f97475941 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_attribute_sample_texture.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_attribute_sample_texture.cc
@@ -33,7 +33,7 @@ namespace blender::nodes {
static void geo_node_attribute_sample_texture_declare(NodeDeclarationBuilder &b)
{
b.add_input<decl::Geometry>("Geometry");
- b.add_input<decl::Texture>("Texture").hide_label(true);
+ b.add_input<decl::Texture>("Texture").hide_label();
b.add_input<decl::String>("Mapping");
b.add_input<decl::String>("Result");
b.add_output<decl::Geometry>("Geometry");
diff --git a/source/blender/nodes/geometry/nodes/node_geo_attribute_vector_rotate.cc b/source/blender/nodes/geometry/nodes/node_geo_attribute_vector_rotate.cc
index da753dfc11b..adaa4de3029 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_attribute_vector_rotate.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_attribute_vector_rotate.cc
@@ -21,27 +21,26 @@
#include "UI_interface.h"
#include "UI_resources.h"
-static bNodeSocketTemplate geo_node_attribute_vector_rotate_in[] = {
- {SOCK_GEOMETRY, N_("Geometry")},
- {SOCK_STRING, N_("Vector")},
- {SOCK_VECTOR, N_("Vector"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_NONE, SOCK_HIDE_VALUE},
- {SOCK_STRING, N_("Center")},
- {SOCK_VECTOR, N_("Center"), 0.0f, 0.0f, 0.0f, 1.0f, -FLT_MAX, FLT_MAX, PROP_XYZ},
- {SOCK_STRING, N_("Axis")},
- {SOCK_VECTOR, N_("Axis"), 0.0f, 0.0f, 1.0f, 0.0f, -1.0f, 1.0f, PROP_XYZ, PROP_NONE},
- {SOCK_STRING, N_("Angle")},
- {SOCK_FLOAT, N_("Angle"), 0.0f, 0.0f, 0.0f, 1.0f, -FLT_MAX, FLT_MAX, PROP_ANGLE, PROP_NONE},
- {SOCK_STRING, N_("Rotation")},
- {SOCK_VECTOR, N_("Rotation"), 0.0f, 0.0f, 0.0f, 1.0f, -FLT_MAX, FLT_MAX, PROP_EULER},
- {SOCK_BOOLEAN, N_("Invert")},
- {SOCK_STRING, N_("Result")},
- {-1, ""},
-};
-
-static bNodeSocketTemplate geo_node_attribute_vector_rotate_out[] = {
- {SOCK_GEOMETRY, N_("Geometry")},
- {-1, ""},
-};
+namespace blender::nodes {
+
+static void geo_node_attribute_vector_rotate_declare(NodeDeclarationBuilder &b)
+{
+ b.add_input<decl::Geometry>("Geometry");
+ b.add_input<decl::String>("Vector");
+ b.add_input<decl::Vector>("Vector", "Vector_001").min(0.0f).max(1.0f).hide_value();
+ b.add_input<decl::String>("Center");
+ b.add_input<decl::Vector>("Center", "Center_001").subtype(PROP_XYZ);
+ b.add_input<decl::String>("Axis");
+ b.add_input<decl::Vector>("Axis", "Axis_001").min(-1.0f).max(1.0f).subtype(PROP_XYZ);
+ b.add_input<decl::String>("Angle");
+ b.add_input<decl::Float>("Angle", "Angle_001").subtype(PROP_ANGLE);
+ b.add_input<decl::String>("Rotation");
+ b.add_input<decl::Vector>("Rotation", "Rotation_001").subtype(PROP_EULER);
+ b.add_input<decl::Bool>("Invert");
+ b.add_input<decl::String>("Result");
+
+ b.add_output<decl::Geometry>("Geometry");
+}
static void geo_node_attribute_vector_rotate_layout(uiLayout *layout,
bContext *UNUSED(C),
@@ -71,8 +70,6 @@ static void geo_node_attribute_vector_rotate_layout(uiLayout *layout,
}
}
-namespace blender::nodes {
-
static void geo_node_attribute_vector_rotate_update(bNodeTree *UNUSED(ntree), bNode *node)
{
const NodeAttributeVectorRotate *node_storage = (NodeAttributeVectorRotate *)node->storage;
@@ -339,14 +336,13 @@ void register_node_type_geo_attribute_vector_rotate()
"Attribute Vector Rotate",
NODE_CLASS_ATTRIBUTE,
0);
- node_type_socket_templates(
- &ntype, geo_node_attribute_vector_rotate_in, geo_node_attribute_vector_rotate_out);
node_type_update(&ntype, blender::nodes::geo_node_attribute_vector_rotate_update);
node_type_init(&ntype, blender::nodes::geo_node_attribute_vector_rotate_init);
node_type_size(&ntype, 165, 100, 600);
node_type_storage(
&ntype, "NodeAttributeVectorRotate", node_free_standard_storage, node_copy_standard_storage);
ntype.geometry_node_execute = blender::nodes::geo_node_attribute_vector_rotate_exec;
- ntype.draw_buttons = geo_node_attribute_vector_rotate_layout;
+ ntype.draw_buttons = blender::nodes::geo_node_attribute_vector_rotate_layout;
+ ntype.declare = blender::nodes::geo_node_attribute_vector_rotate_declare;
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/geometry/nodes/node_geo_boolean.cc b/source/blender/nodes/geometry/nodes/node_geo_boolean.cc
index d8029ea1eeb..2a1c43a89fe 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_boolean.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_boolean.cc
@@ -23,27 +23,16 @@
#include "node_geometry_util.hh"
-static bNodeSocketTemplate geo_node_boolean_in[] = {
- {SOCK_GEOMETRY, N_("Geometry 1")},
- {SOCK_GEOMETRY,
- N_("Geometry 2"),
- 0.0f,
- 0.0f,
- 0.0f,
- 0.0f,
- 0.0f,
- 0.0f,
- PROP_NONE,
- SOCK_MULTI_INPUT},
- {SOCK_BOOLEAN, N_("Self Intersection")},
- {SOCK_BOOLEAN, N_("Hole Tolerant")},
- {-1, ""},
-};
-
-static bNodeSocketTemplate geo_node_boolean_out[] = {
- {SOCK_GEOMETRY, N_("Geometry")},
- {-1, ""},
-};
+namespace blender::nodes {
+
+static void geo_node_boolean_declare(NodeDeclarationBuilder &b)
+{
+ b.add_input<decl::Geometry>("Geometry 1");
+ b.add_input<decl::Geometry>("Geometry 2").multi_input();
+ b.add_input<decl::Bool>("Self Intersection");
+ b.add_input<decl::Bool>("Hole Tolerant");
+ b.add_output<decl::Geometry>("Geometry");
+}
static void geo_node_boolean_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
{
@@ -77,8 +66,6 @@ static void geo_node_boolean_init(bNodeTree *UNUSED(tree), bNode *node)
node->custom1 = GEO_NODE_BOOLEAN_DIFFERENCE;
}
-namespace blender::nodes {
-
static void geo_node_boolean_exec(GeoNodeExecParams params)
{
GeometryNodeBooleanOperation operation = (GeometryNodeBooleanOperation)params.node().custom1;
@@ -138,10 +125,10 @@ void register_node_type_geo_boolean()
static bNodeType ntype;
geo_node_type_base(&ntype, GEO_NODE_BOOLEAN, "Boolean", NODE_CLASS_GEOMETRY, 0);
- node_type_socket_templates(&ntype, geo_node_boolean_in, geo_node_boolean_out);
- ntype.draw_buttons = geo_node_boolean_layout;
- ntype.updatefunc = geo_node_boolean_update;
- node_type_init(&ntype, geo_node_boolean_init);
+ ntype.declare = blender::nodes::geo_node_boolean_declare;
+ ntype.draw_buttons = blender::nodes::geo_node_boolean_layout;
+ ntype.updatefunc = blender::nodes::geo_node_boolean_update;
+ node_type_init(&ntype, blender::nodes::geo_node_boolean_init);
ntype.geometry_node_execute = blender::nodes::geo_node_boolean_exec;
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/geometry/nodes/node_geo_collection_info.cc b/source/blender/nodes/geometry/nodes/node_geo_collection_info.cc
index e731b4c0cdc..f4c295b06fb 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_collection_info.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_collection_info.cc
@@ -27,7 +27,7 @@ namespace blender::nodes {
static void geo_node_collection_info_declare(NodeDeclarationBuilder &b)
{
- b.add_input<decl::Collection>("Collection").hide_label(true);
+ b.add_input<decl::Collection>("Collection").hide_label();
b.add_output<decl::Geometry>("Geometry");
}
diff --git a/source/blender/nodes/geometry/nodes/node_geo_curve_primitive_spiral.cc b/source/blender/nodes/geometry/nodes/node_geo_curve_primitive_spiral.cc
index 169a169bb1c..0803d43e5c3 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_curve_primitive_spiral.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_curve_primitive_spiral.cc
@@ -41,7 +41,7 @@ static std::unique_ptr<CurveEval> create_spiral_curve(const float rotations,
std::unique_ptr<CurveEval> curve = std::make_unique<CurveEval>();
std::unique_ptr<PolySpline> spline = std::make_unique<PolySpline>();
- const int totalpoints = resolution * rotations;
+ const int totalpoints = std::max(int(resolution * rotations), 1);
const float delta_radius = (end_radius - start_radius) / (float)totalpoints;
float radius = start_radius;
const float delta_height = height / (float)totalpoints;
diff --git a/source/blender/nodes/geometry/nodes/node_geo_curve_reverse.cc b/source/blender/nodes/geometry/nodes/node_geo_curve_reverse.cc
index 2cb75eda202..32bcbe2c608 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_curve_reverse.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_curve_reverse.cc
@@ -29,31 +29,6 @@ static void geo_node_curve_reverse_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Geometry>("Curve");
}
-/**
- * Reverse the data in a MutableSpan object.
- */
-template<typename T> static void reverse_data(MutableSpan<T> r_data)
-{
- const int size = r_data.size();
- for (const int i : IndexRange(size / 2)) {
- std::swap(r_data[size - 1 - i], r_data[i]);
- }
-}
-
-/**
- * Reverse and Swap the data between 2 MutableSpans.
- */
-template<typename T> static void reverse_data(MutableSpan<T> left, MutableSpan<T> right)
-{
- BLI_assert(left.size() == right.size());
- const int size = left.size();
-
- for (const int i : IndexRange(size / 2 + size % 2)) {
- std::swap(left[i], right[size - 1 - i]);
- std::swap(right[i], left[size - 1 - i]);
- }
-}
-
static void geo_node_curve_reverse_exec(GeoNodeExecParams params)
{
GeometrySet geometry_set = params.extract_input<GeometrySet>("Curve");
@@ -74,42 +49,9 @@ static void geo_node_curve_reverse_exec(GeoNodeExecParams params)
threading::parallel_for(splines.index_range(), 128, [&](IndexRange range) {
for (const int i : range) {
- if (!selection[i]) {
- continue;
- }
-
- reverse_data<float3>(splines[i]->positions());
- reverse_data<float>(splines[i]->radii());
- reverse_data<float>(splines[i]->tilts());
-
- splines[i]->attributes.foreach_attribute(
- [&](const AttributeIDRef &attribute_id, const AttributeMetaData &meta_data) {
- std::optional<blender::fn::GMutableSpan> output_attribute =
- splines[i]->attributes.get_for_write(attribute_id);
- if (!output_attribute) {
- BLI_assert_unreachable();
- return false;
- }
- attribute_math::convert_to_static_type(meta_data.data_type, [&](auto dummy) {
- using T = decltype(dummy);
- reverse_data(output_attribute->typed<T>());
- });
- return true;
- },
- ATTR_DOMAIN_POINT);
-
- /* Deal with extra info on derived types. */
- if (BezierSpline *spline = dynamic_cast<BezierSpline *>(splines[i].get())) {
- reverse_data<BezierSpline::HandleType>(spline->handle_types_left());
- reverse_data<BezierSpline::HandleType>(spline->handle_types_right());
- reverse_data<float3>(spline->handle_positions_left(), spline->handle_positions_right());
+ if (selection[i]) {
+ splines[i]->reverse();
}
- else if (NURBSpline *spline = dynamic_cast<NURBSpline *>(splines[i].get())) {
- reverse_data<float>(spline->weights());
- }
- /* Nothing to do for poly splines. */
-
- splines[i]->mark_cache_invalid();
}
});
diff --git a/source/blender/nodes/geometry/nodes/node_geo_curve_to_mesh.cc b/source/blender/nodes/geometry/nodes/node_geo_curve_to_mesh.cc
index b0c763c7d06..2eae11d1705 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_curve_to_mesh.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_curve_to_mesh.cc
@@ -294,8 +294,7 @@ static Mesh *curve_to_mesh_calculate(const CurveEval &curve, const CurveEval &pr
BKE_id_material_eval_ensure_default_slot(&mesh->id);
mesh->flag |= ME_AUTOSMOOTH;
mesh->smoothresh = DEG2RADF(180.0f);
- mesh->runtime.cd_dirty_vert |= CD_MASK_NORMAL;
- mesh->runtime.cd_dirty_poly |= CD_MASK_NORMAL;
+ BKE_mesh_normals_tag_dirty(mesh);
threading::parallel_for(curves.index_range(), 128, [&](IndexRange curves_range) {
for (const int i_spline : curves_range) {
diff --git a/source/blender/nodes/geometry/nodes/node_geo_delete_geometry.cc b/source/blender/nodes/geometry/nodes/node_geo_delete_geometry.cc
index 5845eb357e0..1e2f652cd78 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_delete_geometry.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_delete_geometry.cc
@@ -559,7 +559,7 @@ static Mesh *delete_mesh_selection(const Mesh &mesh_in,
mesh_in, *result, vertex_map, edge_map, selected_poly_indices, new_loop_starts);
BKE_mesh_calc_edges_loose(result);
/* Tag to recalculate normals later. */
- result->runtime.cd_dirty_vert |= CD_MASK_NORMAL;
+ BKE_mesh_normals_tag_dirty(result);
return result;
}
diff --git a/source/blender/nodes/geometry/nodes/node_geo_join_geometry.cc b/source/blender/nodes/geometry/nodes/node_geo_join_geometry.cc
index 5792ee1485a..93643298f92 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_join_geometry.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_join_geometry.cc
@@ -29,27 +29,14 @@
using blender::fn::GVArray_For_GSpan;
-static bNodeSocketTemplate geo_node_join_geometry_in[] = {
- {SOCK_GEOMETRY,
- N_("Geometry"),
- 0.0f,
- 0.0f,
- 0.0f,
- 1.0f,
- -1.0f,
- 1.0f,
- PROP_NONE,
- SOCK_MULTI_INPUT},
- {-1, ""},
-};
-
-static bNodeSocketTemplate geo_node_join_geometry_out[] = {
- {SOCK_GEOMETRY, N_("Geometry")},
- {-1, ""},
-};
-
namespace blender::nodes {
+static void geo_node_join_geometry_declare(NodeDeclarationBuilder &b)
+{
+ b.add_input<decl::Geometry>("Geometry").multi_input();
+ b.add_output<decl::Geometry>("Geometry");
+}
+
static Mesh *join_mesh_topology_and_builtin_attributes(Span<const MeshComponent *> src_components)
{
int totverts = 0;
@@ -508,7 +495,7 @@ void register_node_type_geo_join_geometry()
static bNodeType ntype;
geo_node_type_base(&ntype, GEO_NODE_JOIN_GEOMETRY, "Join Geometry", NODE_CLASS_GEOMETRY, 0);
- node_type_socket_templates(&ntype, geo_node_join_geometry_in, geo_node_join_geometry_out);
ntype.geometry_node_execute = blender::nodes::geo_node_join_geometry_exec;
+ ntype.declare = blender::nodes::geo_node_join_geometry_declare;
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/geometry/nodes/node_geo_material_assign.cc b/source/blender/nodes/geometry/nodes/node_geo_material_assign.cc
index d7d3d0eded8..43818947272 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_material_assign.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_material_assign.cc
@@ -29,12 +29,12 @@ namespace blender::nodes {
static void geo_node_material_assign_declare(NodeDeclarationBuilder &b)
{
b.add_input<decl::Geometry>("Geometry");
- b.add_input<decl::Material>("Material").hide_label(true);
- b.add_input<decl::String>("Selection");
+ b.add_input<decl::Material>("Material").hide_label();
+ b.add_input<decl::Bool>("Selection").default_value(true).hide_value();
b.add_output<decl::Geometry>("Geometry");
}
-static void assign_material_to_faces(Mesh &mesh, const VArray<bool> &face_mask, Material *material)
+static void assign_material_to_faces(Mesh &mesh, const IndexMask selection, Material *material)
{
int new_material_index = -1;
for (const int i : IndexRange(mesh.totcol)) {
@@ -51,18 +51,16 @@ static void assign_material_to_faces(Mesh &mesh, const VArray<bool> &face_mask,
}
mesh.mpoly = (MPoly *)CustomData_duplicate_referenced_layer(&mesh.pdata, CD_MPOLY, mesh.totpoly);
- for (const int i : IndexRange(mesh.totpoly)) {
- if (face_mask[i]) {
- MPoly &poly = mesh.mpoly[i];
- poly.mat_nr = new_material_index;
- }
+ for (const int i : selection) {
+ MPoly &poly = mesh.mpoly[i];
+ poly.mat_nr = new_material_index;
}
}
static void geo_node_material_assign_exec(GeoNodeExecParams params)
{
Material *material = params.extract_input<Material *>("Material");
- const std::string mask_name = params.extract_input<std::string>("Selection");
+ const Field<bool> selection_field = params.extract_input<Field<bool>>("Selection");
GeometrySet geometry_set = params.extract_input<GeometrySet>("Geometry");
@@ -72,9 +70,15 @@ static void geo_node_material_assign_exec(GeoNodeExecParams params)
MeshComponent &mesh_component = geometry_set.get_component_for_write<MeshComponent>();
Mesh *mesh = mesh_component.get_for_write();
if (mesh != nullptr) {
- GVArray_Typed<bool> face_mask = mesh_component.attribute_get_for_read<bool>(
- mask_name, ATTR_DOMAIN_FACE, true);
- assign_material_to_faces(*mesh, face_mask, material);
+
+ GeometryComponentFieldContext field_context{mesh_component, ATTR_DOMAIN_FACE};
+
+ fn::FieldEvaluator selection_evaluator{field_context, mesh->totpoly};
+ selection_evaluator.add(selection_field);
+ selection_evaluator.evaluate();
+ const IndexMask selection = selection_evaluator.get_evaluated_as_mask(0);
+
+ assign_material_to_faces(*mesh, selection, material);
}
}
@@ -87,8 +91,7 @@ void register_node_type_geo_material_assign()
{
static bNodeType ntype;
- geo_node_type_base(
- &ntype, GEO_NODE_LEGACY_MATERIAL_ASSIGN, "Material Assign", NODE_CLASS_GEOMETRY, 0);
+ geo_node_type_base(&ntype, GEO_NODE_MATERIAL_ASSIGN, "Material Assign", NODE_CLASS_GEOMETRY, 0);
ntype.declare = blender::nodes::geo_node_material_assign_declare;
ntype.geometry_node_execute = blender::nodes::geo_node_material_assign_exec;
nodeRegisterType(&ntype);
diff --git a/source/blender/nodes/geometry/nodes/node_geo_material_selection.cc b/source/blender/nodes/geometry/nodes/node_geo_material_selection.cc
new file mode 100644
index 00000000000..22c24e34314
--- /dev/null
+++ b/source/blender/nodes/geometry/nodes/node_geo_material_selection.cc
@@ -0,0 +1,131 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "node_geometry_util.hh"
+
+#include "UI_interface.h"
+#include "UI_resources.h"
+
+#include "DNA_mesh_types.h"
+#include "DNA_meshdata_types.h"
+
+#include "BLI_task.hh"
+
+#include "BKE_material.h"
+
+namespace blender::nodes {
+
+static void geo_node_material_selection_declare(NodeDeclarationBuilder &b)
+{
+ b.add_input<decl::Material>("Material").hide_label(true);
+ b.add_output<decl::Bool>("Selection");
+}
+
+static void select_mesh_by_material(const Mesh &mesh,
+ const Material *material,
+ const IndexMask mask,
+ const MutableSpan<bool> r_selection)
+{
+ BLI_assert(mesh.totpoly >= r_selection.size());
+ Vector<int> material_indices;
+ for (const int i : IndexRange(mesh.totcol)) {
+ if (mesh.mat[i] == material) {
+ material_indices.append(i);
+ }
+ }
+ threading::parallel_for(mask.index_range(), 1024, [&](IndexRange range) {
+ for (const int i : range) {
+ const int face_index = mask[i];
+ r_selection[i] = material_indices.contains(mesh.mpoly[face_index].mat_nr);
+ }
+ });
+}
+
+class MaterialSelectionFieldInput final : public fn::FieldInput {
+ Material *material_;
+
+ public:
+ MaterialSelectionFieldInput(Material *material)
+ : fn::FieldInput(CPPType::get<bool>(), "Material Selection"), material_(material)
+ {
+ }
+
+ const GVArray *get_varray_for_context(const fn::FieldContext &context,
+ IndexMask mask,
+ ResourceScope &scope) const final
+ {
+ if (const GeometryComponentFieldContext *geometry_context =
+ dynamic_cast<const GeometryComponentFieldContext *>(&context)) {
+ const GeometryComponent &component = geometry_context->geometry_component();
+ const AttributeDomain domain = geometry_context->domain();
+ if (component.type() != GEO_COMPONENT_TYPE_MESH) {
+ return nullptr;
+ }
+ const MeshComponent &mesh_component = static_cast<const MeshComponent &>(component);
+ const Mesh *mesh = mesh_component.get_for_read();
+ if (mesh == nullptr) {
+ return nullptr;
+ }
+
+ if (domain == ATTR_DOMAIN_FACE) {
+ Array<bool> selection(mask.min_array_size());
+ select_mesh_by_material(*mesh, material_, mask, selection);
+ return &scope.construct<fn::GVArray_For_ArrayContainer<Array<bool>>>(std::move(selection));
+ }
+
+ Array<bool> selection(mesh->totpoly);
+ select_mesh_by_material(*mesh, material_, IndexMask(mesh->totpoly), selection);
+ GVArrayPtr face_selection = std::make_unique<fn::GVArray_For_ArrayContainer<Array<bool>>>(
+ std::move(selection));
+ GVArrayPtr final_selection = mesh_component.attribute_try_adapt_domain(
+ std::move(face_selection), ATTR_DOMAIN_FACE, domain);
+ return scope.add_value(std::move(final_selection)).get();
+ }
+
+ return nullptr;
+ }
+
+ uint64_t hash() const override
+ {
+ /* Some random constant hash. */
+ return 91619626;
+ }
+
+ bool is_equal_to(const fn::FieldNode &other) const override
+ {
+ return dynamic_cast<const MaterialSelectionFieldInput *>(&other) != nullptr;
+ }
+};
+
+static void geo_node_material_selection_exec(GeoNodeExecParams params)
+{
+ Material *material = params.extract_input<Material *>("Material");
+ Field<bool> material_field{std::make_shared<MaterialSelectionFieldInput>(material)};
+ params.set_output("Selection", std::move(material_field));
+}
+
+} // namespace blender::nodes
+
+void register_node_type_geo_material_selection()
+{
+ static bNodeType ntype;
+
+ geo_node_type_base(
+ &ntype, GEO_NODE_MATERIAL_SELECTION, "Material Selection", NODE_CLASS_GEOMETRY, 0);
+ ntype.declare = blender::nodes::geo_node_material_selection_declare;
+ ntype.geometry_node_execute = blender::nodes::geo_node_material_selection_exec;
+ nodeRegisterType(&ntype);
+}
diff --git a/source/blender/nodes/geometry/nodes/node_geo_object_info.cc b/source/blender/nodes/geometry/nodes/node_geo_object_info.cc
index ab99c9bb3f8..389acc40f0f 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_object_info.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_object_info.cc
@@ -25,7 +25,7 @@ namespace blender::nodes {
static void geo_node_object_info_declare(NodeDeclarationBuilder &b)
{
- b.add_input<decl::Object>("Object").hide_label(true);
+ b.add_input<decl::Object>("Object").hide_label();
b.add_output<decl::Vector>("Location");
b.add_output<decl::Vector>("Rotation");
b.add_output<decl::Vector>("Scale");
diff --git a/source/blender/nodes/geometry/nodes/node_geo_point_instance.cc b/source/blender/nodes/geometry/nodes/node_geo_point_instance.cc
index 902ccfff179..fb45c22ced4 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_point_instance.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_point_instance.cc
@@ -29,8 +29,8 @@ namespace blender::nodes {
static void geo_node_point_instance_declare(NodeDeclarationBuilder &b)
{
b.add_input<decl::Geometry>("Geometry");
- b.add_input<decl::Object>("Object").hide_label(true);
- b.add_input<decl::Collection>("Collection").hide_label(true);
+ b.add_input<decl::Object>("Object").hide_label();
+ b.add_input<decl::Collection>("Collection").hide_label();
b.add_input<decl::Geometry>("Instance Geometry");
b.add_input<decl::Int>("Seed").min(-10000).max(10000);
b.add_output<decl::Geometry>("Geometry");
diff --git a/source/blender/nodes/geometry/nodes/node_geo_set_position.cc b/source/blender/nodes/geometry/nodes/node_geo_set_position.cc
index e8591616f55..4c754ddb643 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_set_position.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_set_position.cc
@@ -24,7 +24,7 @@ static void geo_node_set_position_declare(NodeDeclarationBuilder &b)
{
b.add_input<decl::Geometry>("Geometry");
b.add_input<decl::Vector>("Position");
- b.add_input<decl::Bool>("Selection").default_value(true);
+ b.add_input<decl::Bool>("Selection").default_value(true).hide_value();
b.add_output<decl::Geometry>("Geometry");
}
diff --git a/source/blender/nodes/geometry/nodes/node_geo_subdivision_surface.cc b/source/blender/nodes/geometry/nodes/node_geo_subdivision_surface.cc
index d127f7dc0ba..4541bf3569f 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_subdivision_surface.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_subdivision_surface.cc
@@ -37,14 +37,13 @@ static void geo_node_subdivision_surface_layout(uiLayout *layout,
bContext *UNUSED(C),
PointerRNA *ptr)
{
-#ifndef WITH_OPENSUBDIV
- UNUSED_VARS(ptr);
- uiItemL(layout, IFACE_("Disabled, built without OpenSubdiv"), ICON_ERROR);
-#else
+#ifdef WITH_OPENSUBDIV
uiLayoutSetPropSep(layout, true);
uiLayoutSetPropDecorate(layout, false);
uiItemR(layout, ptr, "uv_smooth", 0, nullptr, ICON_NONE);
uiItemR(layout, ptr, "boundary_smooth", 0, nullptr, ICON_NONE);
+#else
+ UNUSED_VARS(layout, ptr);
#endif
}
diff --git a/source/blender/nodes/geometry/nodes/node_geo_transform.cc b/source/blender/nodes/geometry/nodes/node_geo_transform.cc
index d7423aa6d32..d5eb067cad0 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_transform.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_transform.cc
@@ -69,8 +69,7 @@ void transform_mesh(Mesh *mesh,
else {
const float4x4 matrix = float4x4::from_loc_eul_scale(translation, rotation, scale);
BKE_mesh_transform(mesh, matrix.values, false);
- mesh->runtime.cd_dirty_vert |= CD_MASK_NORMAL;
- mesh->runtime.cd_dirty_poly |= CD_MASK_NORMAL;
+ BKE_mesh_normals_tag_dirty(mesh);
}
}