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:
authorJacques Lucke <jacques@blender.org>2022-07-22 16:39:41 +0300
committerJacques Lucke <jacques@blender.org>2022-07-22 16:39:41 +0300
commit1f94b56d774440d08eb92f2a7a47b9a6a7aa7b84 (patch)
tree06928c94d524852c7031aa310d578691735dc0a8 /source/blender/nodes
parent98bf714b37c1f1b05a162b6ffdaca367b312de1f (diff)
Curves: support sculpting on deformed curves
Previously, curves sculpt tools only worked on original data. This was very limiting, because one could effectively only sculpt the curves when all procedural effects were turned off. This patch adds support for curves sculpting while looking the result of procedural effects (like deformation based on the surface mesh). This functionality is also known as "crazy space" support in Blender. For more details see D15407. Differential Revision: https://developer.blender.org/D15407
Diffstat (limited to 'source/blender/nodes')
-rw-r--r--source/blender/nodes/NOD_geometry_exec.hh4
-rw-r--r--source/blender/nodes/NOD_geometry_nodes_eval_log.hh5
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_bounding_box.cc4
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_convex_hull.cc2
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_curve_resample.cc2
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_curve_to_mesh.cc5
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_curve_to_points.cc8
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_curve_trim.cc1
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_deform_curves_on_surface.cc88
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_distribute_points_on_faces.cc2
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_duplicate_elements.cc13
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_instance_on_points.cc2
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_instances_to_points.cc2
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_mesh_to_curve.cc6
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_mesh_to_points.cc6
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_mesh_to_volume.cc2
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_points_to_vertices.cc6
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_points_to_volume.cc2
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_transform.cc34
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_volume_to_mesh.cc2
-rw-r--r--source/blender/nodes/intern/geometry_nodes_eval_log.cc12
-rw-r--r--source/blender/nodes/intern/node_geometry_exec.cc17
22 files changed, 180 insertions, 45 deletions
diff --git a/source/blender/nodes/NOD_geometry_exec.hh b/source/blender/nodes/NOD_geometry_exec.hh
index 0d5ba6cf5db..c5bc42b059d 100644
--- a/source/blender/nodes/NOD_geometry_exec.hh
+++ b/source/blender/nodes/NOD_geometry_exec.hh
@@ -163,6 +163,7 @@ class GeoNodeExecParams {
}
void check_input_geometry_set(StringRef identifier, const GeometrySet &geometry_set) const;
+ void check_output_geometry_set(const GeometrySet &geometry_set) const;
/**
* Get input as vector for multi input socket with the given identifier.
@@ -231,6 +232,9 @@ class GeoNodeExecParams {
#ifdef DEBUG
this->check_output_access(identifier, type);
#endif
+ if constexpr (std::is_same_v<StoredT, GeometrySet>) {
+ this->check_output_geometry_set(value);
+ }
GMutablePointer gvalue = provider_->alloc_output_value(type);
new (gvalue.get()) StoredT(std::forward<T>(value));
provider_->set_output(identifier, gvalue);
diff --git a/source/blender/nodes/NOD_geometry_nodes_eval_log.hh b/source/blender/nodes/NOD_geometry_nodes_eval_log.hh
index 05c97c3903d..46ba72d14d8 100644
--- a/source/blender/nodes/NOD_geometry_nodes_eval_log.hh
+++ b/source/blender/nodes/NOD_geometry_nodes_eval_log.hh
@@ -115,11 +115,16 @@ class GeometryValueLog : public ValueLog {
struct InstancesInfo {
int instances_num;
};
+ struct EditDataInfo {
+ bool has_deformed_positions;
+ bool has_deform_matrices;
+ };
std::optional<MeshInfo> mesh_info;
std::optional<CurveInfo> curve_info;
std::optional<PointCloudInfo> pointcloud_info;
std::optional<InstancesInfo> instances_info;
+ std::optional<EditDataInfo> edit_data_info;
GeometryValueLog(const GeometrySet &geometry_set, bool log_full_geometry = false);
diff --git a/source/blender/nodes/geometry/nodes/node_geo_bounding_box.cc b/source/blender/nodes/geometry/nodes/node_geo_bounding_box.cc
index 00b10cc8a2f..75c198f7bdd 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_bounding_box.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_bounding_box.cc
@@ -50,7 +50,7 @@ static void node_geo_exec(GeoNodeExecParams params)
}
if (sub_min == float3(FLT_MAX)) {
- sub_geometry.keep_only({GEO_COMPONENT_TYPE_INSTANCES});
+ sub_geometry.remove_geometry_during_modify();
}
else {
const float3 scale = sub_max - sub_min;
@@ -58,7 +58,7 @@ static void node_geo_exec(GeoNodeExecParams params)
Mesh *mesh = geometry::create_cuboid_mesh(scale, 2, 2, 2, "uv_map");
transform_mesh(*mesh, center, float3(0), float3(1));
sub_geometry.replace_mesh(mesh);
- sub_geometry.keep_only({GEO_COMPONENT_TYPE_MESH, GEO_COMPONENT_TYPE_INSTANCES});
+ sub_geometry.keep_only_during_modify({GEO_COMPONENT_TYPE_MESH});
}
});
diff --git a/source/blender/nodes/geometry/nodes/node_geo_convex_hull.cc b/source/blender/nodes/geometry/nodes/node_geo_convex_hull.cc
index 7c26ffc2099..03892501c89 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_convex_hull.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_convex_hull.cc
@@ -224,7 +224,7 @@ static void node_geo_exec(GeoNodeExecParams params)
geometry_set.modify_geometry_sets([&](GeometrySet &geometry_set) {
Mesh *mesh = compute_hull(geometry_set);
geometry_set.replace_mesh(mesh);
- geometry_set.keep_only({GEO_COMPONENT_TYPE_MESH, GEO_COMPONENT_TYPE_INSTANCES});
+ geometry_set.keep_only_during_modify({GEO_COMPONENT_TYPE_MESH});
});
params.set_output("Convex Hull", std::move(geometry_set));
diff --git a/source/blender/nodes/geometry/nodes/node_geo_curve_resample.cc b/source/blender/nodes/geometry/nodes/node_geo_curve_resample.cc
index 2815dd5b2e8..37fc6823b9a 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_curve_resample.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_curve_resample.cc
@@ -60,6 +60,8 @@ static void node_geo_exec(GeoNodeExecParams params)
const Field<bool> selection = params.extract_input<Field<bool>>("Selection");
+ GeometryComponentEditData::remember_deformed_curve_positions_if_necessary(geometry_set);
+
switch (mode) {
case GEO_NODE_CURVE_RESAMPLE_COUNT: {
Field<int> count = params.extract_input<Field<int>>("Count");
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 903a5e7c1d7..bc319ce905a 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
@@ -28,9 +28,10 @@ static void geometry_set_curve_to_mesh(GeometrySet &geometry_set,
const bool fill_caps)
{
const Curves &curves = *geometry_set.get_curves_for_read();
-
const Curves *profile_curves = profile_set.get_curves_for_read();
+ GeometryComponentEditData::remember_deformed_curve_positions_if_necessary(geometry_set);
+
if (profile_curves == nullptr) {
Mesh *mesh = bke::curve_to_wire_mesh(bke::CurvesGeometry::wrap(curves.geometry));
geometry_set.replace_mesh(mesh);
@@ -55,7 +56,7 @@ static void node_geo_exec(GeoNodeExecParams params)
has_curves = true;
geometry_set_curve_to_mesh(geometry_set, profile_set, fill_caps);
}
- geometry_set.keep_only({GEO_COMPONENT_TYPE_MESH, GEO_COMPONENT_TYPE_INSTANCES});
+ geometry_set.keep_only_during_modify({GEO_COMPONENT_TYPE_MESH});
});
params.set_output("Mesh", std::move(curve_set));
diff --git a/source/blender/nodes/geometry/nodes/node_geo_curve_to_points.cc b/source/blender/nodes/geometry/nodes/node_geo_curve_to_points.cc
index 6c4fb2e0855..fd75855bddb 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_curve_to_points.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_curve_to_points.cc
@@ -316,9 +316,11 @@ static void node_geo_exec(GeoNodeExecParams params)
attribute_outputs.normal_id = StrongAnonymousAttributeID("Normal");
attribute_outputs.rotation_id = StrongAnonymousAttributeID("Rotation");
+ GeometryComponentEditData::remember_deformed_curve_positions_if_necessary(geometry_set);
+
geometry_set.modify_geometry_sets([&](GeometrySet &geometry_set) {
if (!geometry_set.has_curves()) {
- geometry_set.keep_only({GEO_COMPONENT_TYPE_INSTANCES});
+ geometry_set.remove_geometry_during_modify();
return;
}
const std::unique_ptr<CurveEval> curve = curves_to_curve_eval(
@@ -329,7 +331,7 @@ static void node_geo_exec(GeoNodeExecParams params)
const Array<int> offsets = calculate_spline_point_offsets(params, mode, *curve, splines);
const int total_num = offsets.last();
if (total_num == 0) {
- geometry_set.keep_only({GEO_COMPONENT_TYPE_INSTANCES});
+ geometry_set.remove_geometry_during_modify();
return;
}
@@ -355,7 +357,7 @@ static void node_geo_exec(GeoNodeExecParams params)
point_attributes.tangents, point_attributes.normals, point_attributes.rotations);
}
- geometry_set.keep_only({GEO_COMPONENT_TYPE_INSTANCES, GEO_COMPONENT_TYPE_POINT_CLOUD});
+ geometry_set.keep_only_during_modify({GEO_COMPONENT_TYPE_POINT_CLOUD});
});
params.set_output("Points", std::move(geometry_set));
diff --git a/source/blender/nodes/geometry/nodes/node_geo_curve_trim.cc b/source/blender/nodes/geometry/nodes/node_geo_curve_trim.cc
index 51994cb8a41..0932de237a9 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_curve_trim.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_curve_trim.cc
@@ -579,6 +579,7 @@ static void node_geo_exec(GeoNodeExecParams params)
const GeometryNodeCurveSampleMode mode = (GeometryNodeCurveSampleMode)storage.mode;
GeometrySet geometry_set = params.extract_input<GeometrySet>("Curve");
+ GeometryComponentEditData::remember_deformed_curve_positions_if_necessary(geometry_set);
if (mode == GEO_NODE_CURVE_SAMPLE_FACTOR) {
Field<float> start_field = params.extract_input<Field<float>>("Start");
diff --git a/source/blender/nodes/geometry/nodes/node_geo_deform_curves_on_surface.cc b/source/blender/nodes/geometry/nodes/node_geo_deform_curves_on_surface.cc
index bd08abbd070..8b653296e12 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_deform_curves_on_surface.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_deform_curves_on_surface.cc
@@ -41,7 +41,7 @@ static void node_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Geometry>(N_("Curves"));
}
-static void deform_curves(CurvesGeometry &curves,
+static void deform_curves(const CurvesGeometry &curves,
const Mesh &surface_mesh_old,
const Mesh &surface_mesh_new,
const Span<float2> curve_attachment_uvs,
@@ -51,6 +51,8 @@ static void deform_curves(CurvesGeometry &curves,
const Span<float3> corner_normals_new,
const Span<float3> rest_positions,
const float4x4 &surface_to_curves,
+ MutableSpan<float3> r_positions,
+ MutableSpan<float3x3> r_rotations,
std::atomic<int> &r_invalid_uv_count)
{
/* Find attachment points on old and new mesh. */
@@ -61,8 +63,6 @@ static void deform_curves(CurvesGeometry &curves,
[&]() { reverse_uv_sampler_old.sample_many(curve_attachment_uvs, surface_samples_old); },
[&]() { reverse_uv_sampler_new.sample_many(curve_attachment_uvs, surface_samples_new); });
- MutableSpan<float3> positions = curves.positions_for_write();
-
const float4x4 curves_to_surface = surface_to_curves.inverted();
threading::parallel_for(curves.curves_range(), 256, [&](const IndexRange range) {
@@ -190,9 +190,15 @@ static void deform_curves(CurvesGeometry &curves,
/* Actually transform all points. */
const IndexRange points = curves.points_for_curve(curve_i);
for (const int point_i : points) {
- const float3 old_point_pos = positions[point_i];
+ const float3 old_point_pos = r_positions[point_i];
const float3 new_point_pos = curve_transform * old_point_pos;
- positions[point_i] = new_point_pos;
+ r_positions[point_i] = new_point_pos;
+ }
+
+ if (!r_rotations.is_empty()) {
+ for (const int point_i : points) {
+ r_rotations[point_i] = rotation * r_rotations[point_i];
+ }
}
}
});
@@ -320,17 +326,67 @@ static void node_geo_exec(GeoNodeExecParams params)
const bke::CurvesSurfaceTransforms transforms{*self_ob_eval, surface_ob_eval};
- deform_curves(curves,
- *surface_mesh_orig,
- *surface_mesh_eval,
- surface_uv_coords,
- reverse_uv_sampler_orig,
- reverse_uv_sampler_eval,
- corner_normals_orig,
- corner_normals_eval,
- rest_positions,
- transforms.surface_to_curves,
- invalid_uv_count);
+ bke::CurvesEditHints *edit_hints = curves_geometry.get_curve_edit_hints_for_write();
+ MutableSpan<float3> edit_hint_positions;
+ MutableSpan<float3x3> edit_hint_rotations;
+ if (edit_hints != nullptr) {
+ if (edit_hints->positions.has_value()) {
+ edit_hint_positions = *edit_hints->positions;
+ }
+ if (!edit_hints->deform_mats.has_value()) {
+ edit_hints->deform_mats.emplace(edit_hints->curves_id_orig.geometry.point_num,
+ float3x3::identity());
+ edit_hints->deform_mats->fill(float3x3::identity());
+ }
+ edit_hint_rotations = *edit_hints->deform_mats;
+ }
+
+ if (edit_hint_positions.is_empty()) {
+ deform_curves(curves,
+ *surface_mesh_orig,
+ *surface_mesh_eval,
+ surface_uv_coords,
+ reverse_uv_sampler_orig,
+ reverse_uv_sampler_eval,
+ corner_normals_orig,
+ corner_normals_eval,
+ rest_positions,
+ transforms.surface_to_curves,
+ curves.positions_for_write(),
+ edit_hint_rotations,
+ invalid_uv_count);
+ }
+ else {
+ /* First deform the actual curves in the input geometry. */
+ deform_curves(curves,
+ *surface_mesh_orig,
+ *surface_mesh_eval,
+ surface_uv_coords,
+ reverse_uv_sampler_orig,
+ reverse_uv_sampler_eval,
+ corner_normals_orig,
+ corner_normals_eval,
+ rest_positions,
+ transforms.surface_to_curves,
+ curves.positions_for_write(),
+ {},
+ invalid_uv_count);
+ /* Then also deform edit curve information for use in sculpt mode. */
+ const CurvesGeometry &curves_orig = CurvesGeometry::wrap(edit_hints->curves_id_orig.geometry);
+ deform_curves(curves_orig,
+ *surface_mesh_orig,
+ *surface_mesh_eval,
+ surface_uv_coords,
+ reverse_uv_sampler_orig,
+ reverse_uv_sampler_eval,
+ corner_normals_orig,
+ corner_normals_eval,
+ rest_positions,
+ transforms.surface_to_curves,
+ edit_hint_positions,
+ edit_hint_rotations,
+ invalid_uv_count);
+ }
curves.tag_positions_changed();
diff --git a/source/blender/nodes/geometry/nodes/node_geo_distribute_points_on_faces.cc b/source/blender/nodes/geometry/nodes/node_geo_distribute_points_on_faces.cc
index 44793926bbd..cfb9cbf7e24 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_distribute_points_on_faces.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_distribute_points_on_faces.cc
@@ -550,7 +550,7 @@ static void node_geo_exec(GeoNodeExecParams params)
geometry_set, selection_field, method, seed, attribute_outputs, params);
/* Keep instances because the original geometry set may contain instances that are processed as
* well. */
- geometry_set.keep_only({GEO_COMPONENT_TYPE_POINT_CLOUD, GEO_COMPONENT_TYPE_INSTANCES});
+ geometry_set.keep_only_during_modify({GEO_COMPONENT_TYPE_POINT_CLOUD});
});
params.set_output("Points", std::move(geometry_set));
diff --git a/source/blender/nodes/geometry/nodes/node_geo_duplicate_elements.cc b/source/blender/nodes/geometry/nodes/node_geo_duplicate_elements.cc
index 679a8ba4f8c..c6b0fb4c068 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_duplicate_elements.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_duplicate_elements.cc
@@ -328,10 +328,11 @@ static void duplicate_curves(GeometrySet &geometry_set,
const IndexAttributes &attribute_outputs)
{
if (!geometry_set.has_curves()) {
- geometry_set.keep_only({GEO_COMPONENT_TYPE_INSTANCES});
+ geometry_set.remove_geometry_during_modify();
return;
}
- geometry_set.keep_only({GEO_COMPONENT_TYPE_CURVE, GEO_COMPONENT_TYPE_INSTANCES});
+ geometry_set.keep_only_during_modify({GEO_COMPONENT_TYPE_CURVE});
+ GeometryComponentEditData::remember_deformed_curve_positions_if_necessary(geometry_set);
const CurveComponent &src_component = *geometry_set.get_component_for_read<CurveComponent>();
const Curves &curves_id = *src_component.get_for_read();
@@ -516,10 +517,10 @@ static void duplicate_faces(GeometrySet &geometry_set,
const IndexAttributes &attribute_outputs)
{
if (!geometry_set.has_mesh()) {
- geometry_set.keep_only({GEO_COMPONENT_TYPE_INSTANCES});
+ geometry_set.remove_geometry_during_modify();
return;
}
- geometry_set.keep_only({GEO_COMPONENT_TYPE_MESH, GEO_COMPONENT_TYPE_INSTANCES});
+ geometry_set.keep_only_during_modify({GEO_COMPONENT_TYPE_MESH});
const MeshComponent &src_component = *geometry_set.get_component_for_read<MeshComponent>();
const Mesh &mesh = *src_component.get_for_read();
@@ -720,7 +721,7 @@ static void duplicate_edges(GeometrySet &geometry_set,
const IndexAttributes &attribute_outputs)
{
if (!geometry_set.has_mesh()) {
- geometry_set.keep_only({GEO_COMPONENT_TYPE_INSTANCES});
+ geometry_set.remove_geometry_during_modify();
return;
};
const MeshComponent &src_component = *geometry_set.get_component_for_read<MeshComponent>();
@@ -1032,7 +1033,7 @@ static void duplicate_points(GeometrySet &geometry_set,
}
}
component_types.append(GEO_COMPONENT_TYPE_INSTANCES);
- geometry_set.keep_only(component_types);
+ geometry_set.keep_only_during_modify(component_types);
}
/** \} */
diff --git a/source/blender/nodes/geometry/nodes/node_geo_instance_on_points.cc b/source/blender/nodes/geometry/nodes/node_geo_instance_on_points.cc
index 3ce26a086e2..119d895fead 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_instance_on_points.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_instance_on_points.cc
@@ -213,7 +213,7 @@ static void node_geo_exec(GeoNodeExecParams params)
}
}
- geometry_set.keep_only({GEO_COMPONENT_TYPE_INSTANCES});
+ geometry_set.remove_geometry_during_modify();
});
/* Unused references may have been added above. Remove those now so that other nodes don't
diff --git a/source/blender/nodes/geometry/nodes/node_geo_instances_to_points.cc b/source/blender/nodes/geometry/nodes/node_geo_instances_to_points.cc
index f14329c96da..5e0789e557b 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_instances_to_points.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_instances_to_points.cc
@@ -94,7 +94,7 @@ static void node_geo_exec(GeoNodeExecParams params)
params.extract_input<Field<float3>>("Position"),
params.extract_input<Field<float>>("Radius"),
params.extract_input<Field<bool>>("Selection"));
- geometry_set.keep_only({GEO_COMPONENT_TYPE_POINT_CLOUD});
+ geometry_set.keep_only({GEO_COMPONENT_TYPE_POINT_CLOUD, GEO_COMPONENT_TYPE_EDIT});
params.set_output("Points", std::move(geometry_set));
}
else {
diff --git a/source/blender/nodes/geometry/nodes/node_geo_mesh_to_curve.cc b/source/blender/nodes/geometry/nodes/node_geo_mesh_to_curve.cc
index 4a79ec159f4..40169def51e 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_mesh_to_curve.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_mesh_to_curve.cc
@@ -20,7 +20,7 @@ static void node_geo_exec(GeoNodeExecParams params)
geometry_set.modify_geometry_sets([&](GeometrySet &geometry_set) {
const Mesh *mesh = geometry_set.get_mesh_for_read();
if (mesh == nullptr) {
- geometry_set.keep_only({GEO_COMPONENT_TYPE_INSTANCES});
+ geometry_set.remove_geometry_during_modify();
return;
}
@@ -31,13 +31,13 @@ static void node_geo_exec(GeoNodeExecParams params)
evaluator.evaluate();
const IndexMask selection = evaluator.get_evaluated_as_mask(0);
if (selection.size() == 0) {
- geometry_set.keep_only({GEO_COMPONENT_TYPE_INSTANCES});
+ geometry_set.remove_geometry_during_modify();
return;
}
bke::CurvesGeometry curves = geometry::mesh_to_curve_convert(*mesh, selection);
geometry_set.replace_curves(bke::curves_new_nomain(std::move(curves)));
- geometry_set.keep_only({GEO_COMPONENT_TYPE_CURVE, GEO_COMPONENT_TYPE_INSTANCES});
+ geometry_set.keep_only_during_modify({GEO_COMPONENT_TYPE_CURVE});
});
params.set_output("Curve", std::move(geometry_set));
diff --git a/source/blender/nodes/geometry/nodes/node_geo_mesh_to_points.cc b/source/blender/nodes/geometry/nodes/node_geo_mesh_to_points.cc
index 8e621d3ed97..d3d1312be6d 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_mesh_to_points.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_mesh_to_points.cc
@@ -62,13 +62,13 @@ static void geometry_set_mesh_to_points(GeometrySet &geometry_set,
{
const MeshComponent *mesh_component = geometry_set.get_component_for_read<MeshComponent>();
if (mesh_component == nullptr) {
- geometry_set.keep_only({GEO_COMPONENT_TYPE_INSTANCES});
+ geometry_set.remove_geometry_during_modify();
return;
}
GeometryComponentFieldContext field_context{*mesh_component, domain};
const int domain_num = mesh_component->attribute_domain_size(domain);
if (domain_num == 0) {
- geometry_set.keep_only({GEO_COMPONENT_TYPE_INSTANCES});
+ geometry_set.remove_geometry_during_modify();
return;
}
fn::FieldEvaluator evaluator{field_context, domain_num};
@@ -115,7 +115,7 @@ static void geometry_set_mesh_to_points(GeometrySet &geometry_set,
}
}
- geometry_set.keep_only({GEO_COMPONENT_TYPE_POINT_CLOUD, GEO_COMPONENT_TYPE_INSTANCES});
+ geometry_set.keep_only_during_modify({GEO_COMPONENT_TYPE_POINT_CLOUD});
}
static void node_geo_exec(GeoNodeExecParams params)
diff --git a/source/blender/nodes/geometry/nodes/node_geo_mesh_to_volume.cc b/source/blender/nodes/geometry/nodes/node_geo_mesh_to_volume.cc
index 5890e070b2f..92814a8bc5e 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_mesh_to_volume.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_mesh_to_volume.cc
@@ -154,7 +154,7 @@ static void node_geo_exec(GeoNodeExecParams params)
if (geometry_set.has_mesh()) {
Volume *volume = create_volume_from_mesh(*geometry_set.get_mesh_for_read(), params);
geometry_set.replace_volume(volume);
- geometry_set.keep_only({GEO_COMPONENT_TYPE_VOLUME, GEO_COMPONENT_TYPE_INSTANCES});
+ geometry_set.keep_only_during_modify({GEO_COMPONENT_TYPE_VOLUME});
}
});
params.set_output("Volume", std::move(geometry_set));
diff --git a/source/blender/nodes/geometry/nodes/node_geo_points_to_vertices.cc b/source/blender/nodes/geometry/nodes/node_geo_points_to_vertices.cc
index 74fff8efeee..ed7ef9b7c71 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_points_to_vertices.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_points_to_vertices.cc
@@ -25,14 +25,14 @@ static void geometry_set_points_to_vertices(GeometrySet &geometry_set,
const PointCloudComponent *point_component =
geometry_set.get_component_for_read<PointCloudComponent>();
if (point_component == nullptr) {
- geometry_set.keep_only({GEO_COMPONENT_TYPE_INSTANCES});
+ geometry_set.remove_geometry_during_modify();
return;
}
GeometryComponentFieldContext field_context{*point_component, ATTR_DOMAIN_POINT};
const int domain_num = point_component->attribute_domain_size(ATTR_DOMAIN_POINT);
if (domain_num == 0) {
- geometry_set.keep_only({GEO_COMPONENT_TYPE_INSTANCES});
+ geometry_set.remove_geometry_during_modify();
return;
}
@@ -63,7 +63,7 @@ static void geometry_set_points_to_vertices(GeometrySet &geometry_set,
}
}
- geometry_set.keep_only({GEO_COMPONENT_TYPE_MESH, GEO_COMPONENT_TYPE_INSTANCES});
+ geometry_set.keep_only_during_modify({GEO_COMPONENT_TYPE_MESH});
}
static void node_geo_exec(GeoNodeExecParams params)
diff --git a/source/blender/nodes/geometry/nodes/node_geo_points_to_volume.cc b/source/blender/nodes/geometry/nodes/node_geo_points_to_volume.cc
index 28a01a5cbce..4a3048e5f4a 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_points_to_volume.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_points_to_volume.cc
@@ -224,7 +224,7 @@ static void initialize_volume_component_from_points(GeoNodeExecParams &params,
new_grid->transform().postScale(voxel_size);
BKE_volume_grid_add_vdb(*volume, "density", std::move(new_grid));
- r_geometry_set.keep_only({GEO_COMPONENT_TYPE_VOLUME, GEO_COMPONENT_TYPE_INSTANCES});
+ r_geometry_set.keep_only_during_modify({GEO_COMPONENT_TYPE_VOLUME});
r_geometry_set.replace_volume(volume);
}
#endif
diff --git a/source/blender/nodes/geometry/nodes/node_geo_transform.cc b/source/blender/nodes/geometry/nodes/node_geo_transform.cc
index 8e65e73d1e2..945d5fbdcac 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_transform.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_transform.cc
@@ -123,6 +123,34 @@ static void translate_volume(Volume &volume, const float3 translation, const Dep
transform_volume(volume, float4x4::from_location(translation), depsgraph);
}
+static void transform_curve_edit_hints(bke::CurvesEditHints &edit_hints, const float4x4 &transform)
+{
+ if (edit_hints.positions.has_value()) {
+ for (float3 &pos : *edit_hints.positions) {
+ pos = transform * pos;
+ }
+ }
+ float3x3 deform_mat;
+ copy_m3_m4(deform_mat.values, transform.values);
+ if (edit_hints.deform_mats.has_value()) {
+ for (float3x3 &mat : *edit_hints.deform_mats) {
+ mat = deform_mat * mat;
+ }
+ }
+ else {
+ edit_hints.deform_mats.emplace(edit_hints.curves_id_orig.geometry.point_num, deform_mat);
+ }
+}
+
+static void translate_curve_edit_hints(bke::CurvesEditHints &edit_hints, const float3 &translation)
+{
+ if (edit_hints.positions.has_value()) {
+ for (float3 &pos : *edit_hints.positions) {
+ pos += translation;
+ }
+ }
+}
+
static void translate_geometry_set(GeometrySet &geometry,
const float3 translation,
const Depsgraph &depsgraph)
@@ -142,6 +170,9 @@ static void translate_geometry_set(GeometrySet &geometry,
if (geometry.has_instances()) {
translate_instances(geometry.get_component_for_write<InstancesComponent>(), translation);
}
+ if (bke::CurvesEditHints *curve_edit_hints = geometry.get_curve_edit_hints_for_write()) {
+ translate_curve_edit_hints(*curve_edit_hints, translation);
+ }
}
void transform_geometry_set(GeometrySet &geometry,
@@ -163,6 +194,9 @@ void transform_geometry_set(GeometrySet &geometry,
if (geometry.has_instances()) {
transform_instances(geometry.get_component_for_write<InstancesComponent>(), transform);
}
+ if (bke::CurvesEditHints *curve_edit_hints = geometry.get_curve_edit_hints_for_write()) {
+ transform_curve_edit_hints(*curve_edit_hints, transform);
+ }
}
void transform_mesh(Mesh &mesh,
diff --git a/source/blender/nodes/geometry/nodes/node_geo_volume_to_mesh.cc b/source/blender/nodes/geometry/nodes/node_geo_volume_to_mesh.cc
index e1d1c67b8c8..91429560ac8 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_volume_to_mesh.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_volume_to_mesh.cc
@@ -193,7 +193,7 @@ static void node_geo_exec(GeoNodeExecParams params)
geometry_set.modify_geometry_sets([&](GeometrySet &geometry_set) {
Mesh *mesh = create_mesh_from_volume(geometry_set, params);
geometry_set.replace_mesh(mesh);
- geometry_set.keep_only({GEO_COMPONENT_TYPE_MESH, GEO_COMPONENT_TYPE_INSTANCES});
+ geometry_set.keep_only_during_modify({GEO_COMPONENT_TYPE_MESH});
});
#else
params.error_message_add(NodeWarningType::Error,
diff --git a/source/blender/nodes/intern/geometry_nodes_eval_log.cc b/source/blender/nodes/intern/geometry_nodes_eval_log.cc
index cf7cbbdc4bf..55930dcb1ee 100644
--- a/source/blender/nodes/intern/geometry_nodes_eval_log.cc
+++ b/source/blender/nodes/intern/geometry_nodes_eval_log.cc
@@ -2,6 +2,7 @@
#include "NOD_geometry_nodes_eval_log.hh"
+#include "BKE_curves.hh"
#include "BKE_geometry_set_instances.hh"
#include "DNA_modifier_types.h"
@@ -264,6 +265,17 @@ GeometryValueLog::GeometryValueLog(const GeometrySet &geometry_set, bool log_ful
info.instances_num = instances_component.instances_num();
break;
}
+ case GEO_COMPONENT_TYPE_EDIT: {
+ const GeometryComponentEditData &edit_component = *(
+ const GeometryComponentEditData *)component;
+ if (const bke::CurvesEditHints *curve_edit_hints =
+ edit_component.curves_edit_hints_.get()) {
+ EditDataInfo &info = this->edit_data_info.emplace();
+ info.has_deform_matrices = curve_edit_hints->deform_mats.has_value();
+ info.has_deformed_positions = curve_edit_hints->positions.has_value();
+ }
+ break;
+ }
case GEO_COMPONENT_TYPE_VOLUME: {
break;
}
diff --git a/source/blender/nodes/intern/node_geometry_exec.cc b/source/blender/nodes/intern/node_geometry_exec.cc
index 56e9c9f0496..c6ebc22c43c 100644
--- a/source/blender/nodes/intern/node_geometry_exec.cc
+++ b/source/blender/nodes/intern/node_geometry_exec.cc
@@ -4,6 +4,7 @@
#include "DEG_depsgraph_query.h"
+#include "BKE_curves.hh"
#include "BKE_type_conversions.hh"
#include "NOD_geometry_exec.hh"
@@ -94,11 +95,27 @@ void GeoNodeExecParams::check_input_geometry_set(StringRef identifier,
message += TIP_("Curve");
break;
}
+ case GEO_COMPONENT_TYPE_EDIT: {
+ continue;
+ }
}
this->error_message_add(NodeWarningType::Info, std::move(message));
}
}
+void GeoNodeExecParams::check_output_geometry_set(const GeometrySet &geometry_set) const
+{
+ UNUSED_VARS_NDEBUG(geometry_set);
+#ifdef DEBUG
+ if (const bke::CurvesEditHints *curve_edit_hints =
+ geometry_set.get_curve_edit_hints_for_read()) {
+ /* If this is not valid, it's likely that the number of stored deformed points does not match
+ * the number of points in the original data. */
+ BLI_assert(curve_edit_hints->is_valid());
+ }
+#endif
+}
+
const bNodeSocket *GeoNodeExecParams::find_available_socket(const StringRef name) const
{
for (const InputSocketRef *socket : provider_->dnode->inputs()) {