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')
-rw-r--r--source/blender/blenkernel/BKE_node.h1
-rw-r--r--source/blender/blenkernel/intern/node.cc1
-rw-r--r--source/blender/nodes/NOD_geometry.h1
-rw-r--r--source/blender/nodes/NOD_static_types.h1
-rw-r--r--source/blender/nodes/geometry/CMakeLists.txt1
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_deform_curves_with_surface.cc167
6 files changed, 172 insertions, 0 deletions
diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h
index 1ff10d06b00..d9a0b841708 100644
--- a/source/blender/blenkernel/BKE_node.h
+++ b/source/blender/blenkernel/BKE_node.h
@@ -1493,6 +1493,7 @@ struct TexResult;
#define GEO_NODE_STORE_NAMED_ATTRIBUTE 1156
#define GEO_NODE_INPUT_NAMED_ATTRIBUTE 1157
#define GEO_NODE_REMOVE_ATTRIBUTE 1158
+#define GEO_NODE_DEFORM_CURVES_WITH_SURFACE 1159
/** \} */
diff --git a/source/blender/blenkernel/intern/node.cc b/source/blender/blenkernel/intern/node.cc
index ffa39f79e7c..20e190526c4 100644
--- a/source/blender/blenkernel/intern/node.cc
+++ b/source/blender/blenkernel/intern/node.cc
@@ -4735,6 +4735,7 @@ static void registerGeometryNodes()
register_node_type_geo_curve_to_mesh();
register_node_type_geo_curve_to_points();
register_node_type_geo_curve_trim();
+ register_node_type_geo_deform_curves_with_surface();
register_node_type_geo_delete_geometry();
register_node_type_geo_duplicate_elements();
register_node_type_geo_distribute_points_on_faces();
diff --git a/source/blender/nodes/NOD_geometry.h b/source/blender/nodes/NOD_geometry.h
index 064112b7efd..61e89409882 100644
--- a/source/blender/nodes/NOD_geometry.h
+++ b/source/blender/nodes/NOD_geometry.h
@@ -47,6 +47,7 @@ void register_node_type_geo_curve_subdivide(void);
void register_node_type_geo_curve_to_mesh(void);
void register_node_type_geo_curve_to_points(void);
void register_node_type_geo_curve_trim(void);
+void register_node_type_geo_deform_curves_with_surface(void);
void register_node_type_geo_delete_geometry(void);
void register_node_type_geo_duplicate_elements(void);
void register_node_type_geo_distribute_points_on_faces(void);
diff --git a/source/blender/nodes/NOD_static_types.h b/source/blender/nodes/NOD_static_types.h
index 7dd732e7fad..69f2e29eb41 100644
--- a/source/blender/nodes/NOD_static_types.h
+++ b/source/blender/nodes/NOD_static_types.h
@@ -396,6 +396,7 @@ DefNode(GeometryNode, GEO_NODE_TRIANGULATE, def_geo_triangulate, "TRIANGULATE",
DefNode(GeometryNode, GEO_NODE_TRIM_CURVE, def_geo_curve_trim, "TRIM_CURVE", TrimCurve, "Trim Curve", "")
DefNode(GeometryNode, GEO_NODE_VIEWER, def_geo_viewer, "VIEWER", Viewer, "Viewer", "")
DefNode(GeometryNode, GEO_NODE_VOLUME_TO_MESH, def_geo_volume_to_mesh, "VOLUME_TO_MESH", VolumeToMesh, "Volume to Mesh", "")
+DefNode(GeometryNode, GEO_NODE_DEFORM_CURVES_WITH_SURFACE, 0, "DEFORM_CURVES_WITH_SURFACE", DeformCurvesWithSurface, "Deform Curves with Surface", "")
/* undefine macros */
#undef DefNode
diff --git a/source/blender/nodes/geometry/CMakeLists.txt b/source/blender/nodes/geometry/CMakeLists.txt
index 84280c0889a..52fd5f49e8f 100644
--- a/source/blender/nodes/geometry/CMakeLists.txt
+++ b/source/blender/nodes/geometry/CMakeLists.txt
@@ -57,6 +57,7 @@ set(SRC
nodes/node_geo_curve_to_mesh.cc
nodes/node_geo_curve_to_points.cc
nodes/node_geo_curve_trim.cc
+ nodes/node_geo_deform_curves_with_surface.cc
nodes/node_geo_delete_geometry.cc
nodes/node_geo_distribute_points_on_faces.cc
nodes/node_geo_dual_mesh.cc
diff --git a/source/blender/nodes/geometry/nodes/node_geo_deform_curves_with_surface.cc b/source/blender/nodes/geometry/nodes/node_geo_deform_curves_with_surface.cc
new file mode 100644
index 00000000000..97b74e91466
--- /dev/null
+++ b/source/blender/nodes/geometry/nodes/node_geo_deform_curves_with_surface.cc
@@ -0,0 +1,167 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#include "BKE_curves.hh"
+#include "BKE_mesh_runtime.h"
+#include "BKE_spline.hh"
+
+#include "BLI_task.hh"
+
+#include "UI_interface.h"
+#include "UI_resources.h"
+
+#include "DNA_mesh_types.h"
+#include "DNA_meshdata_types.h"
+
+#include "NOD_socket_search_link.hh"
+
+#include "node_geometry_util.hh"
+
+namespace blender::nodes::node_geo_deform_curves_with_surface_cc {
+
+using blender::attribute_math::mix2;
+
+NODE_STORAGE_FUNCS(NodeGeometryCurveTrim)
+
+static void node_declare(NodeDeclarationBuilder &b)
+{
+ b.add_input<decl::Geometry>(N_("Curves")).supported_type(GEO_COMPONENT_TYPE_CURVE);
+ b.add_input<decl::Geometry>(N_("Mesh")).supported_type(GEO_COMPONENT_TYPE_MESH);
+ b.add_input<decl::Vector>(N_("Rest Position")).hide_value().supports_field();
+ b.add_output<decl::Geometry>(N_("Curves"));
+}
+
+static void node_layout(uiLayout *UNUSED(layout), bContext *UNUSED(C), PointerRNA *UNUSED(ptr))
+{
+}
+
+static void node_init(bNodeTree *UNUSED(tree), bNode *UNUSED(node))
+{
+}
+
+static void node_update(bNodeTree *UNUSED(ntree), bNode *UNUSED(node))
+{
+}
+
+static void deform_curves(const MeshComponent &mesh_component,
+ const Span<float3> rest_positions,
+ CurveComponent &curves_component)
+{
+ bke::CurvesGeometry &curves = bke::CurvesGeometry::wrap(
+ curves_component.get_for_write()->geometry);
+
+ const MutableSpan<float3> positions = curves.positions_for_write();
+ const VArray<int> surface_triangle_indices_varray = curves.surface_triangle_indices();
+ if (surface_triangle_indices_varray.is_single() &&
+ surface_triangle_indices_varray.get_internal_single() < 0) {
+ return;
+ }
+ const VArray_Span<int> surface_triangle_indices{surface_triangle_indices_varray};
+ const Span<float2> surface_triangle_coordinates = curves.surface_triangle_coords();
+ if (surface_triangle_coordinates.is_empty()) {
+ return;
+ }
+
+ const Mesh &mesh = *mesh_component.get_for_read();
+ const Span<MLoopTri> looptris{BKE_mesh_runtime_looptri_ensure(&mesh),
+ BKE_mesh_runtime_looptri_len(&mesh)};
+
+ threading::parallel_for(curves.curves_range(), 512, [&](const IndexRange curves_range) {
+ for (const int curve_i : curves_range) {
+ const int looptri_i = surface_triangle_indices[curve_i];
+ if (looptri_i < 0 || looptri_i >= looptris.size()) {
+ continue;
+ }
+ const IndexRange points = curves.points_for_curve(curve_i);
+ const int root_point_i = points[0];
+
+ const float3 bary_coord = bke::curves::decode_surface_bary_coord(
+ surface_triangle_coordinates[curve_i]);
+ const MLoopTri &looptri = looptris[looptri_i];
+ const int v0 = mesh.mloop[looptri.tri[0]].v;
+ const int v1 = mesh.mloop[looptri.tri[1]].v;
+ const int v2 = mesh.mloop[looptri.tri[2]].v;
+
+ const float3 &rest_v0 = rest_positions[v0];
+ const float3 &rest_v1 = rest_positions[v1];
+ const float3 &rest_v2 = rest_positions[v2];
+
+ const float3 &deformed_v0 = mesh.mvert[v0].co;
+ const float3 &deformed_v1 = mesh.mvert[v1].co;
+ const float3 &deformed_v2 = mesh.mvert[v2].co;
+
+ float3 old_normal;
+ normal_tri_v3(old_normal, rest_v0, rest_v1, rest_v2);
+ float3 new_normal;
+ normal_tri_v3(new_normal, deformed_v0, deformed_v1, deformed_v2);
+
+ float rotation_mat[3][3];
+ rotation_between_vecs_to_mat3(rotation_mat, old_normal, new_normal);
+
+ const float3 old_curve_root = positions[root_point_i];
+ const float3 old_surface_pos = attribute_math::mix3(bary_coord, rest_v0, rest_v1, rest_v2);
+ const float3 new_surface_pos = attribute_math::mix3(
+ bary_coord, deformed_v0, deformed_v1, deformed_v2);
+ const float3 root_pos_diff = new_surface_pos - old_surface_pos;
+
+ for (const int point_i : points) {
+ const float3 old_pos = positions[point_i];
+ const float3 old_relative_pos = old_pos - old_surface_pos;
+ float3 new_relative_pos = old_relative_pos;
+ mul_m3_v3(rotation_mat, new_relative_pos);
+ const float3 new_pos = new_surface_pos + new_relative_pos;
+ positions[point_i] = new_pos;
+ }
+ }
+ });
+
+ curves.tag_positions_changed();
+}
+
+static void node_geo_exec(GeoNodeExecParams params)
+{
+ GeometrySet curves_geometry = params.extract_input<GeometrySet>("Curves");
+ GeometrySet mesh_geometry = params.extract_input<GeometrySet>("Mesh");
+ Field<float3> rest_positions_field = params.extract_input<Field<float3>>("Rest Position");
+
+ if (!mesh_geometry.has_mesh()) {
+ params.set_output("Curves", std::move(curves_geometry));
+ return;
+ }
+
+ const MeshComponent &mesh_component = *mesh_geometry.get_component_for_read<MeshComponent>();
+ GeometryComponentFieldContext field_context{mesh_component, ATTR_DOMAIN_POINT};
+ FieldEvaluator field_evaluator{field_context,
+ mesh_component.attribute_domain_size(ATTR_DOMAIN_POINT)};
+ field_evaluator.add(rest_positions_field);
+ field_evaluator.evaluate();
+ const VArray_Span<float3> rest_positions = field_evaluator.get_evaluated<float3>(0);
+
+ curves_geometry.modify_geometry_sets([&](GeometrySet &curve_geometry) {
+ if (!curve_geometry.has_curves()) {
+ return;
+ }
+ CurveComponent &curves_component = curves_geometry.get_component_for_write<CurveComponent>();
+ deform_curves(mesh_component, rest_positions, curves_component);
+ });
+
+ params.set_output("Curves", std::move(curves_geometry));
+}
+
+} // namespace blender::nodes::node_geo_deform_curves_with_surface_cc
+
+void register_node_type_geo_deform_curves_with_surface()
+{
+ namespace file_ns = blender::nodes::node_geo_deform_curves_with_surface_cc;
+
+ static bNodeType ntype;
+ geo_node_type_base(&ntype,
+ GEO_NODE_DEFORM_CURVES_WITH_SURFACE,
+ "Deform Curves with Surface",
+ NODE_CLASS_GEOMETRY);
+ ntype.geometry_node_execute = file_ns::node_geo_exec;
+ ntype.draw_buttons = file_ns::node_layout;
+ ntype.declare = file_ns::node_declare;
+ node_type_init(&ntype, file_ns::node_init);
+ node_type_update(&ntype, file_ns::node_update);
+ nodeRegisterType(&ntype);
+}