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

Reply via email to