GPv3: Weight gradient tool #118671

Open
Sietse Brouwer wants to merge 7 commits from SietseB/blender:gpv3-weight-gradient-tool into main

When changing the target branch, be careful to rebase the branch in your fork to match. See documentation.
2 changed files with 54 additions and 31 deletions
Showing only changes of commit 9ed53a7a61 - Show all commits

View File

@ -276,20 +276,21 @@ static void GREASE_PENCIL_OT_weight_toggle_direction(wmOperatorType *ot)
/** \name Weight Gradient Operator
* \{ */
enum {
WPAINT_GRADIENT_TYPE_LINEAR,
WPAINT_GRADIENT_TYPE_RADIAL,
enum class WeightGradientType : uint8_t {
SietseB marked this conversation as resolved Outdated
enum class WeightGradientType : int8_t {
  Linear,
  Radial,
};
```Cpp enum class WeightGradientType : int8_t { Linear, Radial, }; ```
Linear,
Radial,
};
enum {
BRUSH_STROKE_NORMAL,
BRUSH_STROKE_INVERT,
enum class BrushMode : uint8_t {
Normal,
Invert,
};
enum {
enum WeightGradientFlags : uint8_t {
WPAINT_GRADIENT_POINT_DW_EXISTS = (1 << 0),
WPAINT_GRADIENT_POINT_IS_MODIFIED = (1 << 1),
};
ENUM_OPERATORS(WeightGradientFlags, WPAINT_GRADIENT_POINT_IS_MODIFIED);
struct WeightGradientDrawingCache {
int active_vertex_group;
@ -332,7 +333,7 @@ static int weight_gradient_exec(bContext *C, wmOperator *op)
WeightGradientToolData &tool = *static_cast<WeightGradientToolData *>(gesture->user_data.data);
/* Get gradient type (linear/radial). */
const int gradient_type = RNA_enum_get(op->ptr, "type");
const WeightGradientType gradient_type = WeightGradientType(RNA_enum_get(op->ptr, "type"));
/* Get position and length of the interactive gradient line in the viewport. */
const int x_start = RNA_int_get(op->ptr, "xstart");
@ -366,23 +367,30 @@ static int weight_gradient_exec(bContext *C, wmOperator *op)
/* Calculate weight change. */
float gradient_factor = 0.0f;
SietseB marked this conversation as resolved Outdated

Should be switch.

Should be switch.
if (gradient_type == WPAINT_GRADIENT_TYPE_LINEAR) {
/* For the linear gradient, get the orthogonal position of the stroke point towards
* the gradient line. */
const float dist_on_gradient_line = math::max(
0.0f, math::dot(vec_point_to_gradient, gradient_vector));
if (dist_on_gradient_line > gradient_length_sq) {
continue;
switch (gradient_type) {
case WeightGradientType::Linear: {
/* For the linear gradient, get the orthogonal position of the stroke point towards
* the gradient line. */
const float dist_on_gradient_line = math::max(
0.0f, math::dot(vec_point_to_gradient, gradient_vector));
if (dist_on_gradient_line > gradient_length_sq) {
continue;
}
gradient_factor = (dist_on_gradient_line / gradient_length_sq) * gradient_length;
break;
}
gradient_factor = (dist_on_gradient_line / gradient_length_sq) * gradient_length;
}
else if (gradient_type == WPAINT_GRADIENT_TYPE_RADIAL) {
/* For the radial gradient, get the distance of the stroke point to the center of the
* gradient. */
gradient_factor = math::length(vec_point_to_gradient);
if (gradient_factor > gradient_length) {
continue;
case WeightGradientType::Radial: {
/* For the radial gradient, get the distance of the stroke point to the center of
* the gradient. */
gradient_factor = math::length(vec_point_to_gradient);
if (gradient_factor > gradient_length) {
continue;
}
break;
}
default:
BLI_assert_unreachable();
break;
}
/* Set new weight. */
@ -495,7 +503,7 @@ static void init_weight_gradient_cache(const bContext &C,
/* Get the add/subtract mode of the gradient tool. */
tool.weight_direction = (tool.brush->flag & BRUSH_DIR_IN) ? -1.0f : 1.0f;
if (RNA_enum_get(op.ptr, "mode") == BRUSH_STROKE_INVERT) {
if (RNA_enum_get(op.ptr, "mode") == int(BrushMode::Invert)) {
tool.weight_direction *= -1.0f;
}
@ -566,9 +574,10 @@ static void init_weight_gradient_cache(const bContext &C,
bke::crazyspace::get_evaluated_grease_pencil_drawing_deformation(
ob_eval, *tool.object, drawing_info.layer_index, drawing_info.frame_number);
cache.point_positions = Array<float2>(deformation.positions.size());
cache.point_original_weights = Array<float>(deformation.positions.size());
cache.point_flags = Array<uint8_t>(deformation.positions.size(), 0);
cache.point_positions.reinitialize(deformation.positions.size());
cache.point_original_weights.reinitialize(deformation.positions.size());
cache.point_flags.reinitialize(deformation.positions.size());
cache.point_flags.fill(0);
threading::parallel_for(curves.points_range(), 1024, [&](const IndexRange point_range) {
for (const int point : point_range) {
@ -614,13 +623,13 @@ static int weight_gradient_invoke(bContext *C, wmOperator *op, const wmEvent *ev
static void GREASE_PENCIL_OT_weight_gradient(wmOperatorType *ot)
{
static const EnumPropertyItem gradient_types[] = {
{WPAINT_GRADIENT_TYPE_LINEAR, "LINEAR", 0, "Linear", ""},
{WPAINT_GRADIENT_TYPE_RADIAL, "RADIAL", 0, "Radial", ""},
{int(WeightGradientType::Linear), "LINEAR", 0, "Linear", ""},
{int(WeightGradientType::Radial), "RADIAL", 0, "Radial", ""},
{0, nullptr, 0, nullptr, nullptr},
};
static const EnumPropertyItem brush_modes[] = {
{BRUSH_STROKE_NORMAL, "NORMAL", 0, "Normal", ""},
{BRUSH_STROKE_INVERT, "INVERT", 0, "Invert", ""},
{int(BrushMode::Normal), "NORMAL", 0, "Normal", ""},
{int(BrushMode::Invert), "INVERT", 0, "Invert", ""},
{0, nullptr, 0, nullptr, nullptr},
};

View File

@ -13,6 +13,7 @@
#include "BLI_generic_span.hh"
#include "BLI_index_mask.hh"
#include "BLI_math_matrix_types.hh"
#include "BLI_set.hh"
#include "ED_keyframes_edit.hh"
@ -237,4 +238,17 @@ IndexMask polyline_detect_corners(Span<float2> points,
float angle_threshold,
IndexMaskMemory &memory);
/** Create a vertex group in a GP object with a general name or the name of an active bone. */
int create_vertex_group_in_object(Object &ob);
/** Returns a set of vertex group names that are deformed by a bone in an armature. */
Set<std::string> get_bone_deformed_vertex_groups(Object &object);
/** For a point in a stroke, normalize the weights of vertex groups deformed by bones so that the
* sum is 1.0f. */
void normalize_vertex_weights(const MDeformVert &dvert,
int active_vertex_group,
const Span<bool> &vertex_group_is_locked,
const Span<bool> &vertex_group_is_bone_deformed);
} // namespace blender::ed::greasepencil