GPv3: Set Uniform operator for Thickness and Opacity #114006
|
@ -5848,6 +5848,10 @@ class VIEW3D_MT_edit_greasepencil_point(Menu):
|
|||
layout = self.layout
|
||||
layout.operator("grease_pencil.stroke_smooth", text="Smooth Points")
|
||||
|
||||
layout.separator()
|
||||
layout.operator("grease_pencil.set_uniform_thickness")
|
||||
layout.operator("grease_pencil.set_uniform_opacity")
|
||||
|
||||
|
||||
class VIEW3D_MT_edit_curves(Menu):
|
||||
bl_label = "Curves"
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#include "BLI_stack.hh"
|
||||
|
||||
#include "BKE_context.h"
|
||||
#include "BKE_curves_utils.hh"
|
||||
#include "BKE_grease_pencil.hh"
|
||||
|
||||
#include "RNA_access.hh"
|
||||
|
@ -1005,6 +1006,123 @@ static void GREASE_PENCIL_OT_set_active_material(wmOperatorType *ot)
|
|||
}
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Set stroke uniform Thickness
|
||||
* \{ */
|
||||
|
||||
static int grease_pencil_set_uniform_thickness_exec(bContext *C, wmOperator *op)
|
||||
{
|
||||
const Scene *scene = CTX_data_scene(C);
|
||||
Object *object = CTX_data_active_object(C);
|
||||
GreasePencil &grease_pencil = *static_cast<GreasePencil *>(object->data);
|
||||
antoniov marked this conversation as resolved
|
||||
|
||||
/* Radius is half of the thickness. */
|
||||
const float radius = RNA_float_get(op->ptr, "thickness") * 0.5f;
|
||||
|
||||
bool changed = false;
|
||||
antoniov marked this conversation as resolved
Outdated
Hans Goudey
commented
Retrieve the attribute once outside of the loop, then affect it inside, without checking the mode. Retrieve the attribute once outside of the loop, then affect it inside, without checking the mode.
Retrieving the attribute by name is very slow compared to everything else, and it also isn't threadsafe when retrieving with write access.
|
||||
const Array<MutableDrawingInfo> drawings = retrieve_editable_drawings(*scene, grease_pencil);
|
||||
antoniov marked this conversation as resolved
Outdated
Hans Goudey
commented
Retrieve the necessary attribute in the call to Getting an attribute with write access is potentially expensive. It's important to avoid it when possible. Retrieve the necessary attribute in the call to `fill_points`.
Getting an attribute with write access is potentially expensive. It's important to avoid it when possible.
|
||||
threading::parallel_for_each(drawings, [&](const MutableDrawingInfo &info) {
|
||||
bke::CurvesGeometry &curves = info.drawing.strokes_for_write();
|
||||
|
||||
IndexMaskMemory memory;
|
||||
const IndexMask selected_curves = ed::curves::retrieve_selected_curves(curves, memory);
|
||||
|
||||
antoniov marked this conversation as resolved
Outdated
Hans Goudey
commented
`else if`, or even better `switch (mode)` so that adding a mode without changing this gives a compilation error
|
||||
if (selected_curves.is_empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
const OffsetIndices<int> points_by_curve = curves.points_by_curve();
|
||||
MutableSpan<float> radii = info.drawing.radii_for_write();
|
||||
bke::curves::fill_points<float>(points_by_curve, selected_curves, radius, radii);
|
||||
antoniov marked this conversation as resolved
Outdated
Falk David
commented
Use Use `math::clamp(...)`
Antonio Vazquez
commented
Removed the line because the paramter is filtered already. Removed the line because the paramter is filtered already.
|
||||
changed = true;
|
||||
});
|
||||
|
||||
if (changed) {
|
||||
DEG_id_tag_update(&grease_pencil.id, ID_RECALC_GEOMETRY);
|
||||
WM_event_add_notifier(C, NC_GEOM | ND_DATA, &grease_pencil);
|
||||
}
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
static void GREASE_PENCIL_OT_set_uniform_thickness(wmOperatorType *ot)
|
||||
{
|
||||
/* Identifiers. */
|
||||
ot->name = "Set Uniform Thickness";
|
||||
ot->idname = "GREASE_PENCIL_OT_set_uniform_thickness";
|
||||
ot->description = "Set all stroke points to same thickness";
|
||||
|
||||
/* Callbacks. */
|
||||
ot->exec = grease_pencil_set_uniform_thickness_exec;
|
||||
ot->poll = editable_grease_pencil_poll;
|
||||
|
||||
/* flags */
|
||||
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
|
||||
|
||||
/* props */
|
||||
ot->prop = RNA_def_float(
|
||||
ot->srna, "thickness", 0.1f, 0.0f, 1000.0f, "Thickness", "Thickness", 0.0f, 1000.0f);
|
||||
}
|
||||
|
||||
/** \} */
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Set stroke uniform Opacity
|
||||
* \{ */
|
||||
|
||||
static int grease_pencil_set_uniform_opacity_exec(bContext *C, wmOperator *op)
|
||||
{
|
||||
const Scene *scene = CTX_data_scene(C);
|
||||
Object *object = CTX_data_active_object(C);
|
||||
GreasePencil &grease_pencil = *static_cast<GreasePencil *>(object->data);
|
||||
|
||||
const float opacity = RNA_float_get(op->ptr, "opacity");
|
||||
|
||||
bool changed = false;
|
||||
const Array<MutableDrawingInfo> drawings = retrieve_editable_drawings(*scene, grease_pencil);
|
||||
threading::parallel_for_each(drawings, [&](const MutableDrawingInfo &info) {
|
||||
bke::CurvesGeometry &curves = info.drawing.strokes_for_write();
|
||||
|
||||
IndexMaskMemory memory;
|
||||
const IndexMask selected_curves = ed::curves::retrieve_selected_curves(curves, memory);
|
||||
|
||||
if (selected_curves.is_empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
const OffsetIndices<int> points_by_curve = curves.points_by_curve();
|
||||
MutableSpan<float> opacities = info.drawing.opacities_for_write();
|
||||
bke::curves::fill_points<float>(points_by_curve, selected_curves, opacity, opacities);
|
||||
changed = true;
|
||||
});
|
||||
|
||||
if (changed) {
|
||||
DEG_id_tag_update(&grease_pencil.id, ID_RECALC_GEOMETRY);
|
||||
WM_event_add_notifier(C, NC_GEOM | ND_DATA, &grease_pencil);
|
||||
}
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
static void GREASE_PENCIL_OT_set_uniform_opacity(wmOperatorType *ot)
|
||||
{
|
||||
/* Identifiers. */
|
||||
ot->name = "Set Uniform Opacity";
|
||||
ot->idname = "GREASE_PENCIL_OT_set_uniform_opacity";
|
||||
ot->description = "Set all stroke points to same opacity";
|
||||
|
||||
/* Callbacks. */
|
||||
ot->exec = grease_pencil_set_uniform_opacity_exec;
|
||||
ot->poll = editable_grease_pencil_poll;
|
||||
|
||||
/* flags */
|
||||
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
|
||||
|
||||
/* props */
|
||||
ot->prop = RNA_def_float(ot->srna, "opacity", 1.0f, 0.0f, 1.0f, "Opacity", "", 0.0f, 1.0f);
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Switch Direction Operator
|
||||
* \{ */
|
||||
|
@ -1070,6 +1188,8 @@ void ED_operatortypes_grease_pencil_edit()
|
|||
WM_operatortype_append(GREASE_PENCIL_OT_cyclical_set);
|
||||
WM_operatortype_append(GREASE_PENCIL_OT_set_active_material);
|
||||
WM_operatortype_append(GREASE_PENCIL_OT_stroke_switch_direction);
|
||||
WM_operatortype_append(GREASE_PENCIL_OT_set_uniform_thickness);
|
||||
WM_operatortype_append(GREASE_PENCIL_OT_set_uniform_opacity);
|
||||
}
|
||||
|
||||
void ED_keymap_grease_pencil(wmKeyConfig *keyconf)
|
||||
|
|
Loading…
Reference in New Issue
Seems that this should be exposed as "Thickness" and then divided by 2 before it's assigned to the points.
I'm not sure about that. The name "Radius" is the same name used in Blender for the brush size. If we use "Thickness" as a name, we are breaking the thickness logic of the Drawing. Actually, the thickness is the result of applying the radius.
@mendio What do you think here?
The thickness is twice the radius. And the operator is called "Set Thickness"
Yes, agree. What I mean is, if we use here Thickness then maybe we need change also Radius in the Draw operator, because the "thickness" of the stroke in DRaw mode is set using "radius" parameter.
My concern is to be sure we keep consistency, so I will wait, before change the name, for @mendio because he has been working all these years to keep consistency, so his opinion is important here. If all agree I can change it easily.
For the UI we use Radius and Strength names only in brush settings, once applied, it becomes Stroke Thickness and Stroke Opacity. So yes, Thickness fot the parameter is correct in this case because we are affecting an already existing stroke.
I have talked with @mendio and we agree to use Thickness instead of Radius.