[Bf-blender-cvs] [df280824e41] temp-new-hair: Curves: Deform curves based on surface node. (WIP)
Jacques Lucke
noreply at git.blender.org
Mon Jul 4 16:14:32 CEST 2022
Commit: df280824e419936a1c514aafd71de38adeb8f5dd
Author: Jacques Lucke
Date: Mon Jul 4 16:14:18 2022 +0200
Branches: temp-new-hair
https://developer.blender.org/rBdf280824e419936a1c514aafd71de38adeb8f5dd
Curves: Deform curves based on surface node. (WIP)
{F13245862}
Notes:
* The reverse uv lookup implementation is still fairly trivial (and can have quadratic behavior for some uv maps).
* There is still a discontinuity between faces when faces are rotated (although that seems to exist in the old hair system as well). See todo comment in code.
Todo:
* Decide on the inputs of the deform node? (original/deformed mesh, rest position, uv map, attachment uv coords)
* Is using parenting to deal with object transforms fine?
* Where/when/how to store the rest position?
Maniphest Tasks: T96436, T95776
Differential Revision: https://developer.blender.org/D14864
===================================================================
M release/scripts/startup/bl_ui/properties_data_mesh.py
M release/scripts/startup/nodeitems_builtins.py
M source/blender/blenkernel/BKE_node.h
M source/blender/blenkernel/intern/DerivedMesh.cc
M source/blender/blenkernel/intern/node.cc
M source/blender/blenkernel/intern/node_tree_update.cc
M source/blender/blenlib/BLI_float3x3.hh
M source/blender/editors/curves/intern/curves_add.cc
M source/blender/editors/curves/intern/curves_ops.cc
M source/blender/editors/include/ED_curves.h
M source/blender/editors/object/object_add.cc
M source/blender/editors/object/object_relations.c
M source/blender/geometry/GEO_reverse_uv_sampler.hh
M source/blender/geometry/intern/reverse_uv_sampler.cc
M source/blender/makesdna/DNA_node_types.h
M source/blender/makesdna/DNA_object_types.h
M source/blender/makesrna/intern/rna_object.c
M source/blender/modifiers/intern/MOD_nodes.cc
M source/blender/nodes/NOD_geometry.h
M source/blender/nodes/NOD_static_types.h
M source/blender/nodes/geometry/CMakeLists.txt
A source/blender/nodes/geometry/nodes/node_geo_deform_curves_with_surface.cc
===================================================================
diff --git a/release/scripts/startup/bl_ui/properties_data_mesh.py b/release/scripts/startup/bl_ui/properties_data_mesh.py
index 0b043905713..2fc949f4aae 100644
--- a/release/scripts/startup/bl_ui/properties_data_mesh.py
+++ b/release/scripts/startup/bl_ui/properties_data_mesh.py
@@ -411,6 +411,8 @@ class DATA_PT_shape_keys(MeshButtonsPanel, Panel):
row.active = enable_edit_value
row.prop(key, "eval_time")
+ layout.prop(ob, "add_rest_position_attribute")
+
class DATA_PT_uv_texture(MeshButtonsPanel, Panel):
bl_label = "UV Maps"
diff --git a/release/scripts/startup/nodeitems_builtins.py b/release/scripts/startup/nodeitems_builtins.py
index 21bb3d01616..14032937af0 100644
--- a/release/scripts/startup/nodeitems_builtins.py
+++ b/release/scripts/startup/nodeitems_builtins.py
@@ -73,6 +73,7 @@ def curve_node_items(context):
yield NodeItem("GeometryNodeCurveLength")
yield NodeItem("GeometryNodeCurveToMesh")
yield NodeItem("GeometryNodeCurveToPoints")
+ yield NodeItem("GeometryNodeDeformCurvesWithSurface")
yield NodeItem("GeometryNodeFillCurve")
yield NodeItem("GeometryNodeFilletCurve")
yield NodeItem("GeometryNodeResampleCurve")
diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h
index e13ac3180ec..71eb3f6664f 100644
--- a/source/blender/blenkernel/BKE_node.h
+++ b/source/blender/blenkernel/BKE_node.h
@@ -1501,6 +1501,7 @@ struct TexResult;
#define GEO_NODE_MESH_TO_VOLUME 1164
#define GEO_NODE_UV_UNWRAP 1165
#define GEO_NODE_UV_PACK_ISLANDS 1166
+#define GEO_NODE_DEFORM_CURVES_WITH_SURFACE 1167
/** \} */
diff --git a/source/blender/blenkernel/intern/DerivedMesh.cc b/source/blender/blenkernel/intern/DerivedMesh.cc
index ffac89c15e6..c2ea01bcadf 100644
--- a/source/blender/blenkernel/intern/DerivedMesh.cc
+++ b/source/blender/blenkernel/intern/DerivedMesh.cc
@@ -66,6 +66,9 @@
# include "DNA_userdef_types.h"
#endif
+using blender::float3;
+using blender::IndexRange;
+
/* very slow! enable for testing only! */
//#define USE_MODIFIER_VALIDATE
@@ -814,6 +817,25 @@ static void mesh_calc_modifiers(struct Depsgraph *depsgraph,
/* Clear errors before evaluation. */
BKE_modifiers_clear_errors(ob);
+ if (ob->modifier_flag & OB_MODIFIER_FLAG_ADD_REST_POSITION) {
+ if (mesh_final == nullptr) {
+ mesh_final = BKE_mesh_copy_for_eval(mesh_input, true);
+ ASSERT_IS_VALID_MESH(mesh_final);
+ }
+ float3 *rest_positions = static_cast<float3 *>(CustomData_add_layer_named(&mesh_final->vdata,
+ CD_PROP_FLOAT3,
+ CD_DEFAULT,
+ nullptr,
+ mesh_final->totvert,
+ "rest_position"));
+ blender::threading::parallel_for(
+ IndexRange(mesh_final->totvert), 1024, [&](const IndexRange range) {
+ for (const int i : range) {
+ rest_positions[i] = mesh_final->mvert[i].co;
+ }
+ });
+ }
+
/* Apply all leading deform modifiers. */
if (use_deform) {
for (; md; md = md->next, md_datamask = md_datamask->next) {
diff --git a/source/blender/blenkernel/intern/node.cc b/source/blender/blenkernel/intern/node.cc
index 5be912ffb2b..1c797f29ce1 100644
--- a/source/blender/blenkernel/intern/node.cc
+++ b/source/blender/blenkernel/intern/node.cc
@@ -4749,6 +4749,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/blenkernel/intern/node_tree_update.cc b/source/blender/blenkernel/intern/node_tree_update.cc
index 019ab114b83..9a0e669b966 100644
--- a/source/blender/blenkernel/intern/node_tree_update.cc
+++ b/source/blender/blenkernel/intern/node_tree_update.cc
@@ -1294,6 +1294,12 @@ class NodeTreeMainUpdater {
break;
}
}
+
+ if (!(ntree.runtime->runtime_flag & NTREE_RUNTIME_FLAG_HAS_SURFACE_DEFORMATION)) {
+ if (!tree_ref.nodes_by_type("GeometryNodeDeformCurvesWithSurface").is_empty()) {
+ ntree.runtime->runtime_flag |= NTREE_RUNTIME_FLAG_HAS_SURFACE_DEFORMATION;
+ }
+ }
}
void update_node_levels(bNodeTree &ntree)
diff --git a/source/blender/blenlib/BLI_float3x3.hh b/source/blender/blenlib/BLI_float3x3.hh
index 62478556d9b..6a9e7dd04f0 100644
--- a/source/blender/blenlib/BLI_float3x3.hh
+++ b/source/blender/blenlib/BLI_float3x3.hh
@@ -152,6 +152,13 @@ struct float3x3 {
return result;
}
+ friend float3 operator*(const float3x3 &a, const float3 &b)
+ {
+ float3 result;
+ mul_v3_m3v3(result, a.values, b);
+ return result;
+ }
+
void operator*=(const float3x3 &other)
{
mul_m3_m3_post(values, other.values);
diff --git a/source/blender/editors/curves/intern/curves_add.cc b/source/blender/editors/curves/intern/curves_add.cc
index 552ef1d96c8..95f54d963c2 100644
--- a/source/blender/editors/curves/intern/curves_add.cc
+++ b/source/blender/editors/curves/intern/curves_add.cc
@@ -6,12 +6,79 @@
#include "BLI_rand.hh"
+#include "BKE_context.h"
#include "BKE_curves.hh"
+#include "BKE_node.h"
+#include "BKE_node_runtime.hh"
#include "ED_curves.h"
+#include "ED_node.h"
+#include "ED_object.h"
+
+#include "DNA_modifier_types.h"
+#include "DNA_node_types.h"
+#include "DNA_object_types.h"
namespace blender::ed::curves {
+static bool has_surface_deformation_node(const Object &curves_ob)
+{
+ LISTBASE_FOREACH (const ModifierData *, md, &curves_ob.modifiers) {
+ if (md->type != eModifierType_Nodes) {
+ continue;
+ }
+ const NodesModifierData *nmd = reinterpret_cast<const NodesModifierData *>(md);
+ if (nmd->node_group == nullptr) {
+ continue;
+ }
+ if (nmd->node_group->runtime->runtime_flag & NTREE_RUNTIME_FLAG_HAS_SURFACE_DEFORMATION) {
+ return true;
+ }
+ }
+ return false;
+}
+
+void ensure_surface_deformation_node_exists(bContext &C, Object &curves_ob)
+{
+ if (has_surface_deformation_node(curves_ob)) {
+ return;
+ }
+
+ Main *bmain = CTX_data_main(&C);
+ Scene *scene = CTX_data_scene(&C);
+
+ ModifierData *md = ED_object_modifier_add(
+ nullptr, bmain, scene, &curves_ob, "Hair Deform", eModifierType_Nodes);
+ NodesModifierData &nmd = *reinterpret_cast<NodesModifierData *>(md);
+ nmd.node_group = ntreeAddTree(bmain, "Hair Deform", "GeometryNodeTree");
+
+ bNodeTree *ntree = nmd.node_group;
+ ntreeAddSocketInterface(ntree, SOCK_IN, "NodeSocketGeometry", "Geometry");
+ ntreeAddSocketInterface(ntree, SOCK_OUT, "NodeSocketGeometry", "Geometry");
+ bNode *group_input = nodeAddStaticNode(&C, ntree, NODE_GROUP_INPUT);
+ bNode *group_output = nodeAddStaticNode(&C, ntree, NODE_GROUP_OUTPUT);
+ bNode *deform_node = nodeAddStaticNode(&C, ntree, GEO_NODE_DEFORM_CURVES_WITH_SURFACE);
+
+ ED_node_tree_propagate_change(&C, bmain, nmd.node_group);
+
+ nodeAddLink(ntree,
+ group_input,
+ static_cast<bNodeSocket *>(group_input->outputs.first),
+ deform_node,
+ nodeFindSocket(deform_node, SOCK_IN, "Curves"));
+ nodeAddLink(ntree,
+ deform_node,
+ nodeFindSocket(deform_node, SOCK_OUT, "Curves"),
+ group_output,
+ static_cast<bNodeSocket *>(group_output->inputs.first));
+
+ group_input->locx = -200;
+ group_output->locx = 200;
+ deform_node->locx = 0;
+
+ ED_node_tree_propagate_change(&C, bmain, nmd.node_group);
+}
+
bke::CurvesGeometry primitive_random_sphere(const int curves_size, const int points_per_curve)
{
bke::CurvesGeometry curves(points_per_curve * curves_size, curves_size);
diff --git a/source/blender/editors/curves/intern/curves_ops.cc b/source/blender/editors/curves/intern/curves_ops.cc
index 1575912deb1..bd0505c65ee 100644
--- a/source/blender/editors/curves/intern/curves_ops.cc
+++ b/source/blender/editors/curves/intern/curves_ops.cc
@@ -520,154 +520,169 @@ static bool snap_curves_to_surface_poll(bContext *C)
return true;
}
+static void snap_curves_to_surface_exec_object(Object &curves_ob,
+ const Object &surface_ob,
+ const AttachMode attach_mode,
+ bool *r_invalid_uvs,
+ bool *r_missing_uvs)
+{
+ Curves &curves_id = *static_cast<Curves *>(curves_ob.data);
+ CurvesGeometry &curves = CurvesGeometry::wrap(curves_id.geometry);
+
+ Mesh &surface_mesh = *static_cast<Mesh *>(surface_ob.data);
+
+ MeshComponent surface_mesh_component;
+ surface_mesh_component.replace(&surface_mesh, GeometryOwnershipType::ReadOnly);
+
+ VArraySpan<float2> surface_uv_map;
+ if (curves_id.surface_uv_map != nullptr) {
+ surface_uv_map = surface_mesh_component
+ .attribute_try_get_for_read(
+ curves_id.surface_uv_map, ATTR_DOMAIN_CORNER, CD_PROP_FLOAT2)
+ .typed<float2>();
+ }
+
+ MutableSpan<float3> positions_cu = curves.positions_for_write();
+ MutableSpan<float2> surface_uv_coords = curves.surface_uv_coords_for_write();
+
+ const Span<MLoopTri> surface_looptris = {BKE_mesh_runtime_looptri_ensure(&surface_mesh),
+ BKE_mesh_runtime_looptri_len(&surface_mesh)};
+
+ const float4x4 curves_to_world_mat = curves_ob.obmat;
+ const float4x4 world_to_curves_mat = curves_to_world_mat.inverted();
+ const float4x4 surface_to_world_mat = surface_ob.obmat;
+ const float4x4 world_to_surface_mat = surface_to_world_mat.inverted();
+ const float4x4 curves_to_surface_mat = world_to_surface_mat * curves_to_world_mat;
+ const float4x4 surface
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list