Commit: abaed315d5fc6914b824a2684e3e91891841ad86
Author: Jacques Lucke
Date: Tue Jan 4 20:13:35 2022 +0100
Branches: temp-scale-elements-node-test
https://developer.blender.org/rBabaed315d5fc6914b824a2684e3e91891841ad86
initial scale faces mode
===================================================================
M source/blender/makesrna/intern/rna_nodetree.c
M source/blender/nodes/geometry/nodes/node_geo_scale_elements.cc
===================================================================
diff --git a/source/blender/makesrna/intern/rna_nodetree.c
b/source/blender/makesrna/intern/rna_nodetree.c
index f7596d59d39..ba380583e88 100644
--- a/source/blender/makesrna/intern/rna_nodetree.c
+++ b/source/blender/makesrna/intern/rna_nodetree.c
@@ -11307,10 +11307,10 @@ static void def_geo_scale_elements(StructRNA *srna)
};
prop = RNA_def_property(srna, "mode", PROP_ENUM, PROP_NONE);
- RNA_def_property_enum_items(prop, rna_enum_attribute_type_items);
- RNA_def_property_enum_funcs(prop, NULL, NULL,
"rna_GeometryNodeAttributeFill_type_itemf");
- RNA_def_property_enum_default(prop, CD_PROP_FLOAT);
- RNA_def_property_ui_text(prop, "Data Type", "");
+ RNA_def_property_enum_sdna(prop, NULL, "custom1");
+ RNA_def_property_enum_items(prop, scale_elements_mode_items);
+ RNA_def_property_enum_default(prop, GEO_NODE_SCALE_ELEMENTS_MODE_FACE);
+ RNA_def_property_ui_text(prop, "Mode", "Element type to transform");
RNA_def_property_update(prop, NC_NODE | NA_EDITED,
"rna_GeometryNode_socket_update");
}
diff --git a/source/blender/nodes/geometry/nodes/node_geo_scale_elements.cc
b/source/blender/nodes/geometry/nodes/node_geo_scale_elements.cc
index e2a4ec96f17..d62d148326f 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_scale_elements.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_scale_elements.cc
@@ -14,8 +14,12 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
+#include "BLI_disjoint_set.hh"
#include "BLI_task.hh"
+#include "DNA_mesh_types.h"
+#include "DNA_meshdata_types.h"
+
#include "node_geometry_util.hh"
namespace blender::nodes::node_geo_scale_elements_cc {
@@ -24,13 +28,112 @@ static void node_declare(NodeDeclarationBuilder &b)
{
b.add_input<decl::Geometry>(N_("Geometry")).supported_type(GEO_COMPONENT_TYPE_MESH);
b.add_input<decl::Bool>(N_("Selection")).default_value(true).hide_value().supports_field();
- b.add_input<decl::Float>(N_("Scale")).subtype(PROP_EULER).supports_field();
-
b.add_input<decl::Vector>(N_("Pivot")).subtype(PROP_TRANSLATION).supports_field();
+ b.add_input<decl::Float>(N_("Scale")).default_value(1.0f).supports_field();
+
b.add_input<decl::Vector>(N_("Pivot")).subtype(PROP_TRANSLATION).implicit_field();
b.add_output<decl::Geometry>(N_("Geometry"));
};
+static void scale_faces(MeshComponent &mesh_component,
+ const Field<bool> &selection_field,
+ const Field<float> &scale_field,
+ const Field<float3> &pivot_field)
+{
+ Mesh *mesh = mesh_component.get_for_write();
+ mesh->mvert = static_cast<MVert *>(
+ CustomData_duplicate_referenced_layer(&mesh->vdata, CD_MVERT,
mesh->totvert));
+
+ GeometryComponentFieldContext field_context{mesh_component,
ATTR_DOMAIN_FACE};
+ FieldEvaluator evaluator{field_context, mesh->totpoly};
+ evaluator.set_selection(selection_field);
+ evaluator.add(scale_field);
+ evaluator.add(pivot_field);
+ evaluator.evaluate();
+ const IndexMask selection = evaluator.get_evaluated_selection_as_mask();
+ const VArray<float> scales = evaluator.get_evaluated<float>(0);
+ const VArray<float3> pivots = evaluator.get_evaluated<float3>(1);
+
+ DisjointSet disjoint_set(mesh->totvert);
+ for (const int poly_index : selection) {
+ const MPoly &poly = mesh->mpoly[poly_index];
+ const Span<MLoop> poly_loops{mesh->mloop + poly.loopstart, poly.totloop};
+ for (const int loop_index : IndexRange(poly.totloop - 1)) {
+ const int v1 = poly_loops[loop_index].v;
+ const int v2 = poly_loops[loop_index + 1].v;
+ disjoint_set.join(v1, v2);
+ }
+ disjoint_set.join(poly_loops.first().v, poly_loops.last().v);
+ }
+
+ struct GroupData {
+ float scale = 0.0f;
+ float3 pivot = {0.0f, 0.0f, 0.0f};
+ int tot_faces = 0;
+ };
+
+ const int max_group_index = mesh->totvert;
+ Array<GroupData> groups_data(max_group_index);
+ for (const int poly_index : selection) {
+ const MPoly &poly = mesh->mpoly[poly_index];
+ const int first_vertex = mesh->mloop[poly.loopstart].v;
+ const int group_index = disjoint_set.find_root(first_vertex);
+ const float scale = scales[poly_index];
+ const float3 pivot = pivots[poly_index];
+ GroupData &group_info = groups_data[group_index];
+ group_info.pivot += pivot;
+ group_info.scale += scale;
+ group_info.tot_faces++;
+ }
+
+ for (GroupData &group_data : groups_data) {
+ if (group_data.tot_faces >= 2) {
+ const float f = 1.0f / group_data.tot_faces;
+ group_data.scale *= f;
+ group_data.pivot *= f;
+ }
+ }
+
+ for (const int vert_index : IndexRange(mesh->totvert)) {
+ const int group_index = disjoint_set.find_root(vert_index);
+ const GroupData &group_data = groups_data[group_index];
+ if (group_data.tot_faces == 0) {
+ continue;
+ }
+ MVert &vert = mesh->mvert[vert_index];
+ const float3 diff = float3(vert.co) - group_data.pivot;
+ const float3 new_diff = diff * group_data.scale;
+ copy_v3_v3(vert.co, group_data.pivot + new_diff);
+ }
+}
+
static void node_geo_exec(GeoNodeExecParams params)
{
+ const GeometryNodeScaleElementsMode mode =
static_cast<GeometryNodeScaleElementsMode>(
+ params.node().custom1);
+
+ GeometrySet geometry = params.extract_input<GeometrySet>("Geometry");
+ const Field<bool> &selection_field =
params.get_input<Field<bool>>("Selection");
+ const Field<float> &scale_field = params.get_input<Field<float>>("Scale");
+ const Field<float3> &pivot_field = params.get_input<Field<float3>>("Pivot");
+
+ geometry.modify_geometry_sets([&](GeometrySet &geometry) {
+ switch (mode) {
+ case GEO_NODE_SCALE_ELEMENTS_MODE_FACE: {
+ if (geometry.has_mesh()) {
+ MeshComponent &mesh_component =
geometry.get_component_for_write<MeshComponent>();
+ scale_faces(mesh_component, selection_field, scale_field,
pivot_field);
+ }
+ break;
+ }
+ case GEO_NODE_SCALE_ELEMENTS_MODE_EDGE: {
+ break;
+ }
+ case GEO_NODE_SCALE_ELEMENTS_MODE_CURVE: {
+ break;
+ }
+ }
+ });
+
+ params.set_output("Geometry", std::move(geometry));
}
} // namespace blender::nodes::node_geo_scale_elements_cc
_______________________________________________
Bf-blender-cvs mailing list
[email protected]
List details, subscription details or unsubscribe:
https://lists.blender.org/mailman/listinfo/bf-blender-cvs