[Bf-blender-cvs] [1f94b56d774] master: Curves: support sculpting on deformed curves

Jacques Lucke noreply at git.blender.org
Fri Jul 22 15:40:03 CEST 2022


Commit: 1f94b56d774440d08eb92f2a7a47b9a6a7aa7b84
Author: Jacques Lucke
Date:   Fri Jul 22 15:39:41 2022 +0200
Branches: master
https://developer.blender.org/rB1f94b56d774440d08eb92f2a7a47b9a6a7aa7b84

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

===================================================================

A	source/blender/blenkernel/BKE_crazyspace.hh
M	source/blender/blenkernel/BKE_curves.hh
M	source/blender/blenkernel/BKE_geometry_set.h
M	source/blender/blenkernel/BKE_geometry_set.hh
M	source/blender/blenkernel/BKE_mesh_sample.hh
M	source/blender/blenkernel/CMakeLists.txt
M	source/blender/blenkernel/intern/crazyspace.cc
M	source/blender/blenkernel/intern/curves.cc
A	source/blender/blenkernel/intern/geometry_component_edit_data.cc
M	source/blender/blenkernel/intern/geometry_set.cc
M	source/blender/blenlib/BLI_kdopbvh.h
M	source/blender/editors/sculpt_paint/curves_sculpt_add.cc
M	source/blender/editors/sculpt_paint/curves_sculpt_brush.cc
M	source/blender/editors/sculpt_paint/curves_sculpt_comb.cc
M	source/blender/editors/sculpt_paint/curves_sculpt_delete.cc
M	source/blender/editors/sculpt_paint/curves_sculpt_density.cc
M	source/blender/editors/sculpt_paint/curves_sculpt_grow_shrink.cc
M	source/blender/editors/sculpt_paint/curves_sculpt_intern.hh
M	source/blender/editors/sculpt_paint/curves_sculpt_ops.cc
M	source/blender/editors/sculpt_paint/curves_sculpt_pinch.cc
M	source/blender/editors/sculpt_paint/curves_sculpt_puff.cc
M	source/blender/editors/sculpt_paint/curves_sculpt_selection_paint.cc
M	source/blender/editors/sculpt_paint/curves_sculpt_slide.cc
M	source/blender/editors/sculpt_paint/curves_sculpt_smooth.cc
M	source/blender/editors/sculpt_paint/curves_sculpt_snake_hook.cc
M	source/blender/editors/space_node/node_draw.cc
M	source/blender/geometry/GEO_add_curves_on_mesh.hh
M	source/blender/geometry/intern/add_curves_on_mesh.cc
M	source/blender/geometry/intern/realize_instances.cc
M	source/blender/nodes/NOD_geometry_exec.hh
M	source/blender/nodes/NOD_geometry_nodes_eval_log.hh
M	source/blender/nodes/geometry/nodes/node_geo_bounding_box.cc
M	source/blender/nodes/geometry/nodes/node_geo_convex_hull.cc
M	source/blender/nodes/geometry/nodes/node_geo_curve_resample.cc
M	source/blender/nodes/geometry/nodes/node_geo_curve_to_mesh.cc
M	source/blender/nodes/geometry/nodes/node_geo_curve_to_points.cc
M	source/blender/nodes/geometry/nodes/node_geo_curve_trim.cc
M	source/blender/nodes/geometry/nodes/node_geo_deform_curves_on_surface.cc
M	source/blender/nodes/geometry/nodes/node_geo_distribute_points_on_faces.cc
M	source/blender/nodes/geometry/nodes/node_geo_duplicate_elements.cc
M	source/blender/nodes/geometry/nodes/node_geo_instance_on_points.cc
M	source/blender/nodes/geometry/nodes/node_geo_instances_to_points.cc
M	source/blender/nodes/geometry/nodes/node_geo_mesh_to_curve.cc
M	source/blender/nodes/geometry/nodes/node_geo_mesh_to_points.cc
M	source/blender/nodes/geometry/nodes/node_geo_mesh_to_volume.cc
M	source/blender/nodes/geometry/nodes/node_geo_points_to_vertices.cc
M	source/blender/nodes/geometry/nodes/node_geo_points_to_volume.cc
M	source/blender/nodes/geometry/nodes/node_geo_transform.cc
M	source/blender/nodes/geometry/nodes/node_geo_volume_to_mesh.cc
M	source/blender/nodes/intern/geometry_nodes_eval_log.cc
M	source/blender/nodes/intern/node_geometry_exec.cc

===================================================================

diff --git a/source/blender/blenkernel/BKE_crazyspace.hh b/source/blender/blenkernel/BKE_crazyspace.hh
new file mode 100644
index 00000000000..adebf0b7884
--- /dev/null
+++ b/source/blender/blenkernel/BKE_crazyspace.hh
@@ -0,0 +1,53 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+/** \file
+ * \ingroup bke
+ */
+
+#pragma once
+
+#include "BLI_float3x3.hh"
+#include "BLI_math_vec_types.hh"
+#include "BLI_span.hh"
+
+struct Depsgraph;
+struct Object;
+
+namespace blender::bke::crazyspace {
+
+/**
+ * Contains information about how points have been deformed during evaluation.
+ * This allows mapping edits on evaluated data back to original data in some cases.
+ */
+struct GeometryDeformation {
+  /**
+   * Positions of the deformed points. This may also point to the original position if no
+   * deformation data is available.
+   */
+  Span<float3> positions;
+  /**
+   * Matrices that transform point translations on original data into corresponding translations in
+   * evaluated data. This may be empty if not available.
+   */
+  Span<float3x3> deform_mats;
+
+  float3 translation_from_deformed_to_original(const int position_i,
+                                               const float3 &translation) const
+  {
+    if (this->deform_mats.is_empty()) {
+      return translation;
+    }
+    const float3x3 &deform_mat = this->deform_mats[position_i];
+    return deform_mat.inverted() * translation;
+  }
+};
+
+/**
+ * During evaluation of the object, deformation data may have been generated for this object. This
+ * function either retrieves the deformation data from the evaluated object, or falls back to
+ * returning the original data.
+ */
+GeometryDeformation get_evaluated_curves_deformation(const Depsgraph &depsgraph,
+                                                     const Object &ob_orig);
+
+}  // namespace blender::bke::crazyspace
diff --git a/source/blender/blenkernel/BKE_curves.hh b/source/blender/blenkernel/BKE_curves.hh
index 68c90a45031..568899721a9 100644
--- a/source/blender/blenkernel/BKE_curves.hh
+++ b/source/blender/blenkernel/BKE_curves.hh
@@ -11,6 +11,7 @@
 
 #include <mutex>
 
+#include "BLI_float3x3.hh"
 #include "BLI_float4x4.hh"
 #include "BLI_generic_virtual_array.hh"
 #include "BLI_index_mask.hh"
@@ -414,6 +415,38 @@ class CurvesGeometry : public ::CurvesGeometry {
   }
 };
 
+/**
+ * Used to propagate deformation data through modifier evaluation so that sculpt tools can work on
+ * evaluated data.
+ */
+class CurvesEditHints {
+ public:
+  /**
+   * Original data that the edit hints below are meant to be used for.
+   */
+  const Curves &curves_id_orig;
+  /**
+   * Evaluated positions for the points in #curves_orig. If this is empty, the positions from the
+   * evaluated #Curves should be used if possible.
+   */
+  std::optional<Array<float3>> positions;
+  /**
+   * Matrices which transform point movement vectors from original data to corresponding movements
+   * of evaluated data.
+   */
+  std::optional<Array<float3x3>> deform_mats;
+
+  CurvesEditHints(const Curves &curves_id_orig) : curves_id_orig(curves_id_orig)
+  {
+  }
+
+  /**
+   * The edit hints have to correspond to the original curves, i.e. the number of deformed points
+   * is the same as the number of original points.
+   */
+  bool is_valid() const;
+};
+
 namespace curves {
 
 /* -------------------------------------------------------------------- */
diff --git a/source/blender/blenkernel/BKE_geometry_set.h b/source/blender/blenkernel/BKE_geometry_set.h
index a28e9e6bdf6..97e69f3fe1f 100644
--- a/source/blender/blenkernel/BKE_geometry_set.h
+++ b/source/blender/blenkernel/BKE_geometry_set.h
@@ -23,9 +23,10 @@ typedef enum GeometryComponentType {
   GEO_COMPONENT_TYPE_INSTANCES = 2,
   GEO_COMPONENT_TYPE_VOLUME = 3,
   GEO_COMPONENT_TYPE_CURVE = 4,
+  GEO_COMPONENT_TYPE_EDIT = 5,
 } GeometryComponentType;
 
-#define GEO_COMPONENT_TYPE_ENUM_SIZE 5
+#define GEO_COMPONENT_TYPE_ENUM_SIZE 6
 
 void BKE_geometry_set_free(struct GeometrySet *geometry_set);
 
diff --git a/source/blender/blenkernel/BKE_geometry_set.hh b/source/blender/blenkernel/BKE_geometry_set.hh
index 4108e2f7e2e..be2ec3e3dca 100644
--- a/source/blender/blenkernel/BKE_geometry_set.hh
+++ b/source/blender/blenkernel/BKE_geometry_set.hh
@@ -43,7 +43,8 @@ enum class GeometryOwnershipType {
 
 namespace blender::bke {
 class ComponentAttributeProviders;
-}
+class CurvesEditHints;
+}  // namespace blender::bke
 
 class GeometryComponent;
 
@@ -168,6 +169,12 @@ struct GeometrySet {
    * Remove all geometry components with types that are not in the provided list.
    */
   void keep_only(const blender::Span<GeometryComponentType> component_types);
+  /**
+   * Keeps the provided geometry types, but also instances and edit data.
+   * Instances must not be removed while using #modify_geometry_sets.
+   */
+  void keep_only_during_modify(const blender::Span<GeometryComponentType> component_types);
+  void remove_geometry_during_modify();
 
   void add(const GeometryComponent &component);
 
@@ -287,6 +294,10 @@ struct GeometrySet {
    * Returns a read-only curves data-block or null.
    */
   const Curves *get_curves_for_read() const;
+  /**
+   * Returns read-only curve edit hints or null.
+   */
+  const blender::bke::CurvesEditHints *get_curve_edit_hints_for_read() const;
 
   /**
    * Returns a mutable mesh or null. No ownership is transferred.
@@ -304,6 +315,10 @@ struct GeometrySet {
    * Returns a mutable curves data-block or null. No ownership is transferred.
    */
   Curves *get_curves_for_write();
+  /**
+   * Returns mutable curve edit hints or null.
+   */
+  blender::bke::CurvesEditHints *get_curve_edit_hints_for_write();
 
   /* Utility methods for replacement. */
   /**
@@ -825,3 +840,37 @@ class VolumeComponent : public GeometryComponent {
 
   static constexpr inline GeometryComponentType static_type = GEO_COMPONENT_TYPE_VOLUME;
 };
+
+/**
+ * When the original data is in some edit mode, we want to propagate some additional information
+ * through object evaluation. This information can be used by edit modes to support working on
+ * evaluated data.
+ *
+ * This component is added at the beginning of modifier evaluation.
+ */
+class GeometryComponentEditData final : public GeometryComponent {
+ public:
+  /**
+   * Information about how original curves are manipulated during evaluation. This data is used so
+   * that curve sculpt tools can work on evaluated data. It is not stored in #CurveComponent
+   * because the data remains valid even when there is no actual curves geometry anymore, for
+   * example, when the curves have been converted to a mesh.
+   */
+  std::unique_ptr<blender::bke::CurvesEditHints> curves_edit_hints_;
+
+  GeometryComponentEditData();
+
+  GeometryComponent *copy() const final;
+  bool owns_direct_data() const final;
+  void ensure_owns_direct_data() final;
+
+  /**
+   * The first node that does topology changing operations on curves should store the curve point
+   * positions it retrieved as input. Without this, information about the deformed positions is
+   * lost, which would make curves sculpt mode fall back to using original curve positions instead
+   * of deformed ones.
+   */
+  static void remember_deformed_curve_positions_if_necessary(GeometrySet &geometry);
+
+  static constexpr inline GeometryComponentType static_type = GEO_COMPONENT_TYPE_EDIT;
+};
diff --git a/source/blender/blenkernel/BKE_mesh_sample.hh b/source/blender/blenkernel/BKE_mesh_sample.hh
index 356709d8942..0b7d1a1835f 100644
--- a/source/blender/blenkernel/BKE_mesh_sample.hh
+++ b/source/blender/blenkernel/BKE_mesh_sample.hh
@@ -137,4 +137,15 @@ float3 compute_bary_coord_in_triangle(const Mesh &mesh,
                                       const MLoopTri &looptri,
                                       const float3 &position);
 
+template<typename T>
+inline T sample_corner_attrribute_with_bary_coords(const float3 &bary_weights,
+                                                   const MLoopTri &looptri,
+                                                   const Span<T> corner_attribute)
+{
+  return attribute_math::mix3(bary_weights,
+                              corner_attribute[looptri.tri[0]],
+                              corner_attribute[looptri.tri[1]],
+                              corner_attribute[looptri.tri[2]]);
+}
+
 }  // namespace blender::bke::mesh_surface_sample
diff --git a/source/blender/blenkernel/CMakeLists.txt b/source/blender/blenkernel/CMakeLists.txt
index df4b70d4fe6..2ac42037198 100644
--- a/source/blender/blenkernel/CMakeLists.txt
+++ b/source/blender/blenkernel/CMakeLists.txt
@@ -139,6 +139,7 @@ set(SRC
   intern/freestyle.c
   intern/geometry_component_curve.cc
   intern/geometry_component_curves.cc
+  intern/geometry_component_edit_data.cc
   intern/geometry_component_instances.cc
   intern/geometry_component_mesh.cc
   intern/geometry_component_pointcloud.cc
@@ -353,6 +354,7 @@ set(SRC
   BKE_constraint.h
   BKE_context.h
   BKE_crazyspace.h
+  BKE_crazyspace.hh
   BKE_cryptomatte.h
   BKE_cryptomatte.hh
   BKE_curve.h
diff --git a/source/blender/blenkernel/intern/crazyspace.cc b/source/blender/blenkernel/intern/crazyspace.cc
index c3db3095343..978606ef1fa 100644
--- a/source/blender/blenkernel/intern/crazyspace.cc
+++ b/source/blender/blenkernel/intern/crazyspace.cc
@@ -19,7 +19,10 @@
 
 #include "BKE_DerivedMesh.h"
 #include "BKE_crazyspace.h"
+#include "BKE_crazyspace.hh"
+#include "BKE_curves.hh"
 #include "BKE_editmesh.h"
+#include "BKE_geometry_set.hh"
 #include "BKE_lib_id.h"
 #include "BKE_mesh.h"
 #include "BKE_mesh_wrapper.h"
@@ -586,3 +589,64 @@ void BKE_crazyspace_api_eval_clear(Object *object)
 }
 
 /** \} */
+
+namespace blender::bke::crazyspace {
+
+GeometryDeformation get_evaluated_curves_deformation(const Depsgraph &depsgraph,
+                                                     const Object &ob_orig)
+{
+  BLI_assert(ob_orig.type == OB_CURVES);
+  const Curves &curves_id_orig = *static_cast<const Curves *>(ob_orig.data);
+  const CurvesGeometry &curves_orig = CurvesGeometry::wrap(curves_id_orig.geometry);
+  const int points_num = curves_orig.points_num();
+
+  GeometryDeformation deformation;
+  /* Use the

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list