[Bf-blender-cvs] [190334b47df] master: Curves: new Grow/Shrink brush
Jacques Lucke
noreply at git.blender.org
Tue Apr 5 15:24:27 CEST 2022
Commit: 190334b47df46f0e912c873077163e6129e4cbae
Author: Jacques Lucke
Date: Tue Apr 5 15:24:12 2022 +0200
Branches: master
https://developer.blender.org/rB190334b47df46f0e912c873077163e6129e4cbae
Curves: new Grow/Shrink brush
This adds a new Grow/Shrink brush which is similar to the Length
brush in the old hair system.
* It's possible to switch between growing and shrinking by hold
down ctrl and/or by changing the direction enum.
* 3d brush is supported.
* Different brush falloffs are supported.
* Supports scaling curves uniformly or shrinking/extrapolating
them. Extrapolation is linear only in this patch.
* A minimum length settings helps to avoid creating zero-sized curves.
Differential Revision: https://developer.blender.org/D14474
===================================================================
R100 release/datafiles/icons/ops.curves.sculpt_grow.dat release/datafiles/icons/ops.curves.sculpt_grow_shrink.dat
M release/scripts/presets/keyconfig/keymap_data/blender_default.py
M release/scripts/startup/bl_ui/space_view3d.py
M source/blender/blenkernel/intern/brush.c
M source/blender/blenlib/BLI_math_geom.h
M source/blender/blenlib/intern/math_geom.c
M source/blender/editors/datafiles/CMakeLists.txt
M source/blender/editors/sculpt_paint/CMakeLists.txt
A 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/makesdna/DNA_brush_enums.h
M source/blender/makesdna/DNA_brush_types.h
M source/blender/makesrna/intern/rna_brush.c
===================================================================
diff --git a/release/datafiles/icons/ops.curves.sculpt_grow.dat b/release/datafiles/icons/ops.curves.sculpt_grow_shrink.dat
similarity index 100%
rename from release/datafiles/icons/ops.curves.sculpt_grow.dat
rename to release/datafiles/icons/ops.curves.sculpt_grow_shrink.dat
diff --git a/release/scripts/presets/keyconfig/keymap_data/blender_default.py b/release/scripts/presets/keyconfig/keymap_data/blender_default.py
index 2c30859a2f3..0422f1afc58 100644
--- a/release/scripts/presets/keyconfig/keymap_data/blender_default.py
+++ b/release/scripts/presets/keyconfig/keymap_data/blender_default.py
@@ -5576,7 +5576,10 @@ def km_sculpt_curves(params):
)
items.extend([
- ("sculpt_curves.brush_stroke", {"type": 'LEFTMOUSE', "value": 'PRESS'}, None),
+ ("sculpt_curves.brush_stroke", {"type": 'LEFTMOUSE', "value": 'PRESS'},
+ {"properties": [("mode", 'NORMAL')]}),
+ ("sculpt_curves.brush_stroke", {"type": 'LEFTMOUSE', "value": 'PRESS', "ctrl": True},
+ {"properties": [("mode", 'INVERT')]}),
*_template_paint_radial_control("curves_sculpt"),
])
diff --git a/release/scripts/startup/bl_ui/space_view3d.py b/release/scripts/startup/bl_ui/space_view3d.py
index 3c663f1371a..b786f5adf33 100644
--- a/release/scripts/startup/bl_ui/space_view3d.py
+++ b/release/scripts/startup/bl_ui/space_view3d.py
@@ -514,6 +514,13 @@ class _draw_tool_settings_context_mode:
layout.prop(tool_settings.curves_sculpt, "interpolate_length")
layout.prop(tool_settings.curves_sculpt, "interpolate_shape")
+ if brush.curves_sculpt_tool == 'GROW_SHRINK':
+ layout.prop(brush, "direction", expand=True, text="")
+ layout.prop(brush, "falloff_shape", expand=True)
+ layout.prop(brush.curves_sculpt_settings, "scale_uniform")
+ layout.prop(brush.curves_sculpt_settings, "minimum_length")
+ layout.prop(brush, "curve_preset")
+
if brush.curves_sculpt_tool == 'SNAKE_HOOK':
layout.prop(brush, "falloff_shape", expand=True)
layout.prop(brush, "curve_preset")
diff --git a/source/blender/blenkernel/intern/brush.c b/source/blender/blenkernel/intern/brush.c
index ff07d061a20..601c867d8db 100644
--- a/source/blender/blenkernel/intern/brush.c
+++ b/source/blender/blenkernel/intern/brush.c
@@ -1558,6 +1558,7 @@ void BKE_brush_init_curves_sculpt_settings(Brush *brush)
brush->curves_sculpt_settings = MEM_callocN(sizeof(BrushCurvesSculptSettings), __func__);
}
brush->curves_sculpt_settings->add_amount = 1;
+ brush->curves_sculpt_settings->minimum_length = 0.01f;
}
struct Brush *BKE_brush_first_search(struct Main *bmain, const eObjectMode ob_mode)
diff --git a/source/blender/blenlib/BLI_math_geom.h b/source/blender/blenlib/BLI_math_geom.h
index 9e65093a05f..5c1b6c8d774 100644
--- a/source/blender/blenlib/BLI_math_geom.h
+++ b/source/blender/blenlib/BLI_math_geom.h
@@ -329,6 +329,24 @@ float closest_to_line_segment_v2(float r_close[2],
const float p[2],
const float l1[2],
const float l2[2]);
+
+/**
+ * Finds the points where two line segments are closest to each other.
+ *
+ * `lambda_*` is a value between 0 and 1 for each segment that indicates where `r_closest_*` is on
+ * the corresponding segment.
+ *
+ * \return Squared distance between both segments.
+ */
+float closest_seg_seg_v2(float r_closest_a[2],
+ float r_closest_b[2],
+ float *r_lambda_a,
+ float *r_lambda_b,
+ const float a1[2],
+ const float a2[2],
+ const float b1[2],
+ const float b2[2]);
+
/**
* Point closest to v1 on line v2-v3 in 3D.
*
diff --git a/source/blender/blenlib/intern/math_geom.c b/source/blender/blenlib/intern/math_geom.c
index 1b13493e00c..e7ccdeab80a 100644
--- a/source/blender/blenlib/intern/math_geom.c
+++ b/source/blender/blenlib/intern/math_geom.c
@@ -294,6 +294,66 @@ float dist_to_line_segment_v2(const float p[2], const float l1[2], const float l
return sqrtf(dist_squared_to_line_segment_v2(p, l1, l2));
}
+float closest_seg_seg_v2(float r_closest_a[2],
+ float r_closest_b[2],
+ float *r_lambda_a,
+ float *r_lambda_b,
+ const float a1[2],
+ const float a2[2],
+ const float b1[2],
+ const float b2[2])
+{
+ if (isect_seg_seg_v2_simple(a1, a2, b1, b2)) {
+ float intersection[2];
+ isect_line_line_v2_point(a1, a2, b1, b2, intersection);
+ copy_v2_v2(r_closest_a, intersection);
+ copy_v2_v2(r_closest_b, intersection);
+ float tmp[2];
+ *r_lambda_a = closest_to_line_v2(tmp, intersection, a1, a2);
+ *r_lambda_b = closest_to_line_v2(tmp, intersection, b1, b2);
+ const float min_dist_sq = len_squared_v2v2(r_closest_a, r_closest_b);
+ return min_dist_sq;
+ }
+
+ float p1[2], p2[2], p3[2], p4[2];
+ const float lambda1 = closest_to_line_segment_v2(p1, a1, b1, b2);
+ const float lambda2 = closest_to_line_segment_v2(p2, a2, b1, b2);
+ const float lambda3 = closest_to_line_segment_v2(p3, b1, a1, a2);
+ const float lambda4 = closest_to_line_segment_v2(p4, b2, a1, a2);
+ const float dist_sq1 = len_squared_v2v2(p1, a1);
+ const float dist_sq2 = len_squared_v2v2(p2, a2);
+ const float dist_sq3 = len_squared_v2v2(p3, b1);
+ const float dist_sq4 = len_squared_v2v2(p4, b2);
+
+ const float min_dist_sq = min_ffff(dist_sq1, dist_sq2, dist_sq3, dist_sq4);
+ if (min_dist_sq == dist_sq1) {
+ copy_v2_v2(r_closest_a, a1);
+ copy_v2_v2(r_closest_b, p1);
+ *r_lambda_a = 0.0f;
+ *r_lambda_b = lambda1;
+ }
+ else if (min_dist_sq == dist_sq2) {
+ copy_v2_v2(r_closest_a, a2);
+ copy_v2_v2(r_closest_b, p2);
+ *r_lambda_a = 1.0f;
+ *r_lambda_b = lambda2;
+ }
+ else if (min_dist_sq == dist_sq3) {
+ copy_v2_v2(r_closest_a, p3);
+ copy_v2_v2(r_closest_b, b1);
+ *r_lambda_a = lambda3;
+ *r_lambda_b = 0.0f;
+ }
+ else {
+ BLI_assert(min_dist_sq == dist_sq4);
+ copy_v2_v2(r_closest_a, p4);
+ copy_v2_v2(r_closest_b, b2);
+ *r_lambda_a = lambda4;
+ *r_lambda_b = 1.0f;
+ }
+ return min_dist_sq;
+}
+
float closest_to_line_segment_v2(float r_close[2],
const float p[2],
const float l1[2],
diff --git a/source/blender/editors/datafiles/CMakeLists.txt b/source/blender/editors/datafiles/CMakeLists.txt
index 0810e76fe37..ebe61d217ed 100644
--- a/source/blender/editors/datafiles/CMakeLists.txt
+++ b/source/blender/editors/datafiles/CMakeLists.txt
@@ -774,7 +774,7 @@ set_property(GLOBAL PROPERTY ICON_GEOM_NAMES
ops.curves.sculpt_comb
ops.curves.sculpt_cut
ops.curves.sculpt_delete
- ops.curves.sculpt_grow
+ ops.curves.sculpt_grow_shrink
ops.generic.cursor
ops.generic.select
ops.generic.select_box
diff --git a/source/blender/editors/sculpt_paint/CMakeLists.txt b/source/blender/editors/sculpt_paint/CMakeLists.txt
index c422c8c2033..fe7683d12f5 100644
--- a/source/blender/editors/sculpt_paint/CMakeLists.txt
+++ b/source/blender/editors/sculpt_paint/CMakeLists.txt
@@ -31,6 +31,7 @@ set(SRC
curves_sculpt_add.cc
curves_sculpt_comb.cc
curves_sculpt_delete.cc
+ curves_sculpt_grow_shrink.cc
curves_sculpt_ops.cc
curves_sculpt_snake_hook.cc
paint_cursor.c
diff --git a/source/blender/editors/sculpt_paint/curves_sculpt_grow_shrink.cc b/source/blender/editors/sculpt_paint/curves_sculpt_grow_shrink.cc
new file mode 100644
index 00000000000..d26af20799e
--- /dev/null
+++ b/source/blender/editors/sculpt_paint/curves_sculpt_grow_shrink.cc
@@ -0,0 +1,526 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#include <algorithm>
+
+#include "curves_sculpt_intern.hh"
+
+#include "BLI_enumerable_thread_specific.hh"
+#include "BLI_float4x4.hh"
+#include "BLI_kdtree.h"
+#include "BLI_rand.hh"
+#include "BLI_vector.hh"
+
+#include "PIL_time.h"
+
+#include "DEG_depsgraph.h"
+
+#include "BKE_attribute_math.hh"
+#include "BKE_brush.h"
+#include "BKE_bvhutils.h"
+#include "BKE_context.h"
+#include "BKE_curves.hh"
+#include "BKE_mesh.h"
+#include "BKE_mesh_runtime.h"
+#include "BKE_paint.h"
+#include "BKE_spline.hh"
+
+#include "DNA_brush_enums.h"
+#include "DNA_brush_types.h"
+#include "DNA_curves_types.h"
+#include "DNA_mesh_types.h"
+#include "DNA_meshdata_types.h"
+#include "DNA_object_types.h"
+#include "DNA_screen_types.h"
+#include "DNA_space_types.h"
+
+#include "ED_screen.h"
+#include "ED_view3d.h"
+
+#include "curves_sculpt_intern.hh"
+
+/**
+ * The code below uses a suffix naming convention to indicate the coordinate space:
+ * - `cu`: Local space of the curves object that is being edited.
+ * - `su`: Local space of the surface object.
+ * - `wo`: World space.
+ * - `re`: 2D coordinates within the region.
+ */
+
+namespace blender::ed::sculpt_paint {
+
+using bke::CurvesGeometry;
+
+/**
+ * Utility class to wrap different grow/shrink behaviors.
+ * It might be useful to use this for other future brushes as well, but better see if this
+ * abstraction holds up for a while before using it in more places.
+ */
+class CurvesEffect {
+ public:
+ virtual void execute(CurvesGeometry &curves,
+ Span<int> curve_indices,
+ Span<float> move_distances_cu) = 0;
+};
+
+/**
+ * Make curves smaller by trimming the end off.
+ */
+class ShrinkCurvesEffect : public CurvesEffect {
+ private:
+ Brush &brush_;
+
+ public:
+ ShrinkCurvesEffect(Brush &brush) : brush_(brush)
+ {
+ }
+
+ void execute(CurvesGeometry &curves,
+ const Span<int> curve_indices,
+ const Span<float> move_distances_cu) override
+ {
+ MutableSpan<float3> positions_cu = curves.positions();
+ threading::parallel_for(curve_indices.index_range(), 256, [&](const IndexRange range) {
+ for (const int influence_i : range) {
+ const int curve_i = curve_indices[influence_i];
+ const float move_distance_cu = move_dist
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list