[Bf-blender-cvs] [a58be397e2b] master: Curves: new Add brush

Jacques Lucke noreply at git.blender.org
Mon Mar 21 19:00:34 CET 2022


Commit: a58be397e2bfbefa0324dbe861b018dd2784ee0d
Author: Jacques Lucke
Date:   Mon Mar 21 18:54:31 2022 +0100
Branches: master
https://developer.blender.org/rBa58be397e2bfbefa0324dbe861b018dd2784ee0d

Curves: new Add brush

This adds a new Add brush for the new curves object type in sculpt mode.
The brush is used to insert new curves (typically hair) on the surface object.

Supported features:
* Add single curve exactly at the cursor position when `Add Amount` is 1.
* Front faces only.
* Independent interpolate shape and interpolate length settings.
* Smooth and flat shading affects curve shape interpolation.
* Spherical and projection brush.

This also adds the `surface_triangle_index` and `surface_triangle_coordinate`
attributes. Those store information about what position on the surface each
added curve is attached to:
* `surface_triangle_index` (`int`): Index of the internal triangle that a curve
  is attached to. `-1` when the curve is not attached to the surface.
* `surface_triangle_coordinate` (`float2`): First two numbers of a barycentric
  coordinate that reference a specific position within the triangle.

Ref T96444.

Differential Revision: https://developer.blender.org/D14340

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

M	release/scripts/startup/bl_ui/space_view3d.py
M	source/blender/blenkernel/BKE_brush.h
M	source/blender/blenkernel/BKE_curves.hh
M	source/blender/blenkernel/intern/brush.c
M	source/blender/blenkernel/intern/curves_geometry.cc
M	source/blender/blenkernel/intern/paint.c
M	source/blender/blenlib/BLI_kdopbvh.h
M	source/blender/blenloader/intern/versioning_300.c
M	source/blender/editors/sculpt_paint/CMakeLists.txt
A	source/blender/editors/sculpt_paint/curves_sculpt_add.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/paint_stroke.c
M	source/blender/makesdna/DNA_brush_enums.h
M	source/blender/makesdna/DNA_brush_types.h
M	source/blender/makesdna/DNA_scene_types.h
M	source/blender/makesrna/intern/rna_brush.c
M	source/blender/makesrna/intern/rna_sculpt_paint.c

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

diff --git a/release/scripts/startup/bl_ui/space_view3d.py b/release/scripts/startup/bl_ui/space_view3d.py
index 7c4ba575f00..45b0033e133 100644
--- a/release/scripts/startup/bl_ui/space_view3d.py
+++ b/release/scripts/startup/bl_ui/space_view3d.py
@@ -492,16 +492,25 @@ class _draw_tool_settings_context_mode:
             header=True
         )
 
-        UnifiedPaintPanel.prop_unified(
-            layout,
-            context,
-            brush,
-            "strength",
-            unified_name="use_unified_strength",
-            header=True
-        )
+        if brush.curves_sculpt_tool not in ("ADD", "DELETE"):
+            UnifiedPaintPanel.prop_unified(
+                layout,
+                context,
+                brush,
+                "strength",
+                unified_name="use_unified_strength",
+                header=True
+            )
+
+        if brush.curves_sculpt_tool == "ADD":
+            layout.prop(brush, "use_frontface")
+            layout.prop(brush, "falloff_shape", expand=True)
+            layout.prop(brush.curves_sculpt_settings, "add_amount")
+            layout.prop(tool_settings.curves_sculpt, "curve_length")
+            layout.prop(tool_settings.curves_sculpt, "interpolate_length")
+            layout.prop(tool_settings.curves_sculpt, "interpolate_shape")
 
-        if brush.curves_sculpt_tool == "TEST3":
+        if brush.curves_sculpt_tool == "TEST1":
             layout.prop(tool_settings.curves_sculpt, "distance")
 
 
diff --git a/source/blender/blenkernel/BKE_brush.h b/source/blender/blenkernel/BKE_brush.h
index 4b84c0cfe23..a98f4802991 100644
--- a/source/blender/blenkernel/BKE_brush.h
+++ b/source/blender/blenkernel/BKE_brush.h
@@ -52,6 +52,9 @@ bool BKE_brush_delete(struct Main *bmain, struct Brush *brush);
  * Add grease pencil settings.
  */
 void BKE_brush_init_gpencil_settings(struct Brush *brush);
+
+void BKE_brush_init_curves_sculpt_settings(struct Brush *brush);
+
 struct Brush *BKE_brush_first_search(struct Main *bmain, eObjectMode ob_mode);
 
 void BKE_brush_sculpt_reset(struct Brush *brush);
diff --git a/source/blender/blenkernel/BKE_curves.hh b/source/blender/blenkernel/BKE_curves.hh
index ea378c5a0a5..eb4f8f5d5c8 100644
--- a/source/blender/blenkernel/BKE_curves.hh
+++ b/source/blender/blenkernel/BKE_curves.hh
@@ -202,6 +202,24 @@ class CurvesGeometry : public ::CurvesGeometry {
   Span<float> nurbs_weights() const;
   MutableSpan<float> nurbs_weights();
 
+  /**
+   * The index of a triangle (#MLoopTri) that a curve is attached to.
+   * The index is -1, if the curve is not attached.
+   */
+  VArray<int> surface_triangle_indices() const;
+  MutableSpan<int> surface_triangle_indices();
+
+  /**
+   * Barycentric coordinates of the attachment point within a triangle.
+   * Only the first two coordinates are stored. The third coordinate can be derived because the sum
+   * of the three coordinates is 1.
+   *
+   * When the triangle index is -1, this coordinate should be ignored.
+   * The span can be empty, when all triangle indices are -1.
+   */
+  Span<float2> surface_triangle_coords() const;
+  MutableSpan<float2> surface_triangle_coords();
+
   /**
    * Calculate the largest and smallest position values, only including control points
    * (rather than evaluated points). The existing values of `min` and `max` are taken into account.
diff --git a/source/blender/blenkernel/intern/brush.c b/source/blender/blenkernel/intern/brush.c
index 6ee6ff7f41d..ff07d061a20 100644
--- a/source/blender/blenkernel/intern/brush.c
+++ b/source/blender/blenkernel/intern/brush.c
@@ -94,6 +94,9 @@ static void brush_copy_data(Main *UNUSED(bmain), ID *id_dst, const ID *id_src, c
     brush_dst->gpencil_settings->curve_rand_value = BKE_curvemapping_copy(
         brush_src->gpencil_settings->curve_rand_value);
   }
+  if (brush_src->curves_sculpt_settings != NULL) {
+    brush_dst->curves_sculpt_settings = MEM_dupallocN(brush_src->curves_sculpt_settings);
+  }
 
   /* enable fake user by default */
   id_fake_user_set(&brush_dst->id);
@@ -121,6 +124,9 @@ static void brush_free_data(ID *id)
 
     MEM_SAFE_FREE(brush->gpencil_settings);
   }
+  if (brush->curves_sculpt_settings != NULL) {
+    MEM_freeN(brush->curves_sculpt_settings);
+  }
 
   MEM_SAFE_FREE(brush->gradient);
 
@@ -236,6 +242,9 @@ static void brush_blend_write(BlendWriter *writer, ID *id, const void *id_addres
       BKE_curvemapping_blend_write(writer, brush->gpencil_settings->curve_rand_value);
     }
   }
+  if (brush->curves_sculpt_settings) {
+    BLO_write_struct(writer, BrushCurvesSculptSettings, brush->curves_sculpt_settings);
+  }
   if (brush->gradient) {
     BLO_write_struct(writer, ColorBand, brush->gradient);
   }
@@ -308,6 +317,8 @@ static void brush_blend_read_data(BlendDataReader *reader, ID *id)
     }
   }
 
+  BLO_read_data_address(reader, &brush->curves_sculpt_settings);
+
   brush->preview = NULL;
   brush->icon_imbuf = NULL;
 }
@@ -489,6 +500,10 @@ Brush *BKE_brush_add(Main *bmain, const char *name, const eObjectMode ob_mode)
 
   brush->ob_mode = ob_mode;
 
+  if (ob_mode == OB_MODE_SCULPT_CURVES) {
+    BKE_brush_init_curves_sculpt_settings(brush);
+  }
+
   return brush;
 }
 
@@ -1537,6 +1552,14 @@ void BKE_brush_gpencil_weight_presets(Main *bmain, ToolSettings *ts, const bool
   }
 }
 
+void BKE_brush_init_curves_sculpt_settings(Brush *brush)
+{
+  if (brush->curves_sculpt_settings == NULL) {
+    brush->curves_sculpt_settings = MEM_callocN(sizeof(BrushCurvesSculptSettings), __func__);
+  }
+  brush->curves_sculpt_settings->add_amount = 1;
+}
+
 struct Brush *BKE_brush_first_search(struct Main *bmain, const eObjectMode ob_mode)
 {
   Brush *brush;
diff --git a/source/blender/blenkernel/intern/curves_geometry.cc b/source/blender/blenkernel/intern/curves_geometry.cc
index 45f3bf36381..db69fbc4063 100644
--- a/source/blender/blenkernel/intern/curves_geometry.cc
+++ b/source/blender/blenkernel/intern/curves_geometry.cc
@@ -31,6 +31,8 @@ static const std::string ATTR_HANDLE_POSITION_RIGHT = "handle_right";
 static const std::string ATTR_NURBS_ORDER = "nurbs_order";
 static const std::string ATTR_NURBS_WEIGHT = "nurbs_weight";
 static const std::string ATTR_NURBS_KNOTS_MODE = "knots_mode";
+static const std::string ATTR_SURFACE_TRIANGLE_INDEX = "surface_triangle_index";
+static const std::string ATTR_SURFACE_TRIANGLE_COORDINATE = "surface_triangle_coordinate";
 
 /* -------------------------------------------------------------------- */
 /** \name Constructors/Destructor
@@ -378,6 +380,26 @@ MutableSpan<int8_t> CurvesGeometry::nurbs_knots_modes()
   return get_mutable_attribute<int8_t>(*this, ATTR_DOMAIN_CURVE, ATTR_NURBS_KNOTS_MODE);
 }
 
+VArray<int> CurvesGeometry::surface_triangle_indices() const
+{
+  return get_varray_attribute<int>(*this, ATTR_DOMAIN_CURVE, ATTR_SURFACE_TRIANGLE_INDEX, -1);
+}
+
+MutableSpan<int> CurvesGeometry::surface_triangle_indices()
+{
+  return get_mutable_attribute<int>(*this, ATTR_DOMAIN_CURVE, ATTR_SURFACE_TRIANGLE_INDEX);
+}
+
+Span<float2> CurvesGeometry::surface_triangle_coords() const
+{
+  return get_span_attribute<float2>(*this, ATTR_DOMAIN_CURVE, ATTR_SURFACE_TRIANGLE_COORDINATE);
+}
+
+MutableSpan<float2> CurvesGeometry::surface_triangle_coords()
+{
+  return get_mutable_attribute<float2>(*this, ATTR_DOMAIN_CURVE, ATTR_SURFACE_TRIANGLE_COORDINATE);
+}
+
 /** \} */
 
 /* -------------------------------------------------------------------- */
diff --git a/source/blender/blenkernel/intern/paint.c b/source/blender/blenkernel/intern/paint.c
index 238cf1ad74e..1c58173f570 100644
--- a/source/blender/blenkernel/intern/paint.c
+++ b/source/blender/blenkernel/intern/paint.c
@@ -1099,6 +1099,7 @@ bool BKE_paint_ensure(ToolSettings *ts, struct Paint **r_paint)
   }
   else if ((CurvesSculpt **)r_paint == &ts->curves_sculpt) {
     CurvesSculpt *data = MEM_callocN(sizeof(*data), __func__);
+    data->curve_length = 0.3f;
     paint = &data->paint;
   }
   else if (*r_paint == &ts->imapaint.paint) {
diff --git a/source/blender/blenlib/BLI_kdopbvh.h b/source/blender/blenlib/BLI_kdopbvh.h
index 5e56eec2ec6..38f3e1ee290 100644
--- a/source/blender/blenlib/BLI_kdopbvh.h
+++ b/source/blender/blenlib/BLI_kdopbvh.h
@@ -324,3 +324,32 @@ extern const float bvhtree_kdop_axes[13][3];
 #ifdef __cplusplus
 }
 #endif
+
+#ifdef __cplusplus
+
+#  include "BLI_function_ref.hh"
+#  include "BLI_math_vector.hh"
+
+namespace blender {
+
+using BVHTree_RangeQuery_CPP = FunctionRef<void(int index, const float3 &co, float dist_sq)>;
+
+inline void BLI_bvhtree_range_query_cpp(BVHTree &tree,
+                                        const float3 co,
+                                        float radius,
+                                        BVHTree_RangeQuery_CPP fn)
+{
+  BLI_bvhtree_range_query(
+      &tree,
+      co,
+      radius,
+      [](void *userdata, const int index, const float co[3], const float dist_sq) {
+        BVHTree_RangeQuery_CPP fn = *static_cast<BVHTree_RangeQuery_CPP *>(userdata);
+        fn(index, co, dist_sq);
+      },
+      &fn);
+}
+
+}  // namespace blender
+
+#endif
diff --git a/source/blender/blenloader/intern/versioning_300.c b/source/blender/blenloader/intern/versioning_300.c
index 5b1964aa35c..19b7e1e4f3c 100644
--- a/source/blender/blenloader/intern/versioning_300.c
+++ b/source/blender/blenloader/intern/versioning_300.c
@@ -2428,5 +2428,23 @@ void blo_do_versions_300(FileData *fd, Library *UNUSED(lib), Main *bmain)
    */
   {
     /* Keep this block, even when empty. */
+
+    /* Initialize brush curves sculpt settings. */
+    LISTBASE_FOREACH (Brush *, brush, &bmain->brushes) {
+      if (brush->ob_mode != OB_MODE_SCULPT_CURVES) {
+        continue;
+      }
+      if (brush->curves_sculpt_settings != NULL) {
+        continue;
+      }
+      brush->curves_sculpt_settings = MEM_callocN(sizeof(BrushCurvesSculptSettings), __func__);
+      brush->curves_sculpt_settings->add_amount = 1;
+    }
+    LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
+      if (scene->toolsettings && scene->toolsettings->curves_sculpt &&
+          scene->toolsettings->curves_sculpt->curve_length == 0.0f) {
+        scene->toolsettings->curves_sculpt->curve_length = 0.3f;
+      }
+

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list