109 const float target_weight,
114 const float weight_delta = (this->invert_brush_weight ? (1.0f - target_weight) :
129 this->grease_pencil =
static_cast<GreasePencil *
>(this->
object->data);
138 this->invert_brush_weight =
false;
152 if (object_defgroup_nr == -1) {
156 const Bone *actbone =
static_cast<bArmature *
>(modob->data)->act_bone;
170 object_defgroup_nr = actdef;
177 object_defgroup_nr = 0;
190 this->object_locked_defgroups.
add(dg->name);
202 const int frame_group)
212 for (const int drawing_index : range) {
213 const ed::greasepencil::MutableDrawingInfo &drawing_info = drawings[drawing_index];
214 bke::CurvesGeometry &curves = drawing_info.drawing.strokes_for_write();
217 DrawingWeightData &drawing_weight_data =
218 this->drawing_weight_data[frame_group][drawing_index];
219 drawing_weight_data.active_vertex_group = bke::greasepencil::ensure_vertex_group(
220 this->object_defgroup->name, curves.vertex_group_names);
222 drawing_weight_data.multi_frame_falloff = drawing_info.multi_frame_falloff;
223 drawing_weight_data.deform_verts = curves.deform_verts_for_write();
224 drawing_weight_data.deform_weights = bke::varray_for_mutable_deform_verts(
225 drawing_weight_data.deform_verts, drawing_weight_data.active_vertex_group);
229 if (this->auto_normalize) {
230 LISTBASE_FOREACH (bDeformGroup *, dg, &curves.vertex_group_names) {
231 drawing_weight_data.locked_vgroups.append(
232 this->object_locked_defgroups.contains(dg->name));
233 drawing_weight_data.bone_deformed_vgroups.append(
234 this->object_bone_deformed_defgroups.contains(dg->name));
239 const bke::greasepencil::Layer &layer = this->grease_pencil->layer(
240 drawing_info.layer_index);
241 const float4x4 layer_to_world = layer.to_world_space(*ob_eval);
242 const float4x4 projection = ED_view3d_ob_project_mat_get_from_obmat(rv3d, layer_to_world);
244 bke::crazyspace::GeometryDeformation deformation =
245 bke::crazyspace::get_evaluated_grease_pencil_drawing_deformation(
246 ob_eval, *this->object, drawing_info.drawing);
247 drawing_weight_data.point_positions.reinitialize(deformation.positions.size());
248 threading::parallel_for(curves.points_range(), 1024, [&](const IndexRange point_range) {
249 for (const int point : point_range) {
250 drawing_weight_data.point_positions[point] = ED_view3d_project_float_v2_m4(
251 region, deformation.positions[point], projection);
256 drawing_weight_data.point_is_read_only.reinitialize(deformation.positions.size());
257 drawing_weight_data.point_is_read_only.fill(true);
258 IndexMaskMemory memory;
259 const IndexMask editable_points = ed::greasepencil::retrieve_editable_points(
260 *this->object, drawing_info.drawing, drawing_info.layer_index, memory);
261 editable_points.foreach_index(GrainSize(1024), [&](const int64_t index) {
262 drawing_weight_data.point_is_read_only[index] = false;
266 drawing_weight_data.points_touched_by_brush_num = 0;
267 drawing_weight_data.points_touched_by_brush = Array<bool>(deformation.positions.size(),
275 const float brush_widen_factor = 1.0f)
290 this->mouse_position.x + this->brush_radius_wide,
291 this->mouse_position.y - this->brush_radius_wide,
292 this->mouse_position.y + this->brush_radius_wide);
298 const int point_index)
322 if (influence != 0.0f) {
333 point_num += drawing_weight.points_touched_by_brush_num;
337 KDTree_2d *touched_points = BLI_kdtree_2d_new(point_num);
339 int kdtree_index = 0;
341 for (
const int point_index : drawing_weight.point_positions.index_range()) {
342 if (drawing_weight.points_touched_by_brush[point_index]) {
343 BLI_kdtree_2d_insert(
344 touched_points, kdtree_index, drawing_weight.point_positions[point_index]);
345 touched_points_weights[kdtree_index] = drawing_weight.deform_weights[point_index];
350 BLI_kdtree_2d_balance(touched_points);
352 return {touched_points, touched_points_weights};
bPoseChannel * BKE_pose_channel_find_name(const bPose *pose, const char *name)
bool BKE_brush_use_alpha_pressure(const Brush *brush)
float BKE_brush_alpha_get(const Paint *paint, const Brush *brush)
float BKE_brush_curve_strength(eBrushCurvePreset preset, const CurveMapping *cumap, float distance, float brush_radius)
bool BKE_brush_use_size_pressure(const Brush *brush)
float BKE_brush_radius_get(const Paint *paint, const Brush *brush)
float BKE_brush_weight_get(const Paint *paint, const Brush *brush)
Depsgraph * CTX_data_depsgraph_pointer(const bContext *C)
Object * CTX_data_active_object(const bContext *C)
ToolSettings * CTX_data_tool_settings(const bContext *C)
RegionView3D * CTX_wm_region_view3d(const bContext *C)
ARegion * CTX_wm_region(const bContext *C)
Low-level operations for curves.
Utility functions for vertex groups in grease pencil objects.
Object * BKE_modifiers_is_deformed_by_armature(Object *ob)
Paint * BKE_paint_get_active_from_context(const bContext *C)
Brush * BKE_paint_brush(Paint *paint)
A KD-tree for nearest neighbor search.
int BLI_findindex(const ListBase *listbase, const void *vlink) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
void * BLI_findlink(const ListBase *listbase, int number) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
#define LISTBASE_FOREACH(type, var, list)
BLI_INLINE bool BLI_listbase_is_empty(const ListBase *lb)
bool BLI_rctf_isect_pt_v(const struct rctf *rect, const float xy[2])
void BLI_rctf_init(struct rctf *rect, float xmin, float xmax, float ymin, float ymax)
T * DEG_get_evaluated(const Depsgraph *depsgraph, T *id)
BPy_StructRNA * depsgraph
void reinitialize(const int64_t new_size)
constexpr int64_t size() const
constexpr IndexRange index_range() const
void set(const int64_t index, T value)
~WeightPaintOperation() override=default
void ensure_active_vertex_group_in_object()
Set< std::string > object_locked_defgroups
void get_mouse_input_sample(const InputSample &input_sample, const float brush_widen_factor=1.0f)
BrushStrokeMode stroke_mode
Array< Array< DrawingWeightData > > drawing_weight_data
PointsTouchedByBrush create_affected_points_kdtree(const Span< DrawingWeightData > drawing_weights)
float initial_brush_radius
float2 mouse_position_previous
Set< std::string > object_bone_deformed_defgroups
float initial_brush_strength
void add_point_under_brush_to_brush_buffer(const float2 point_position, DrawingWeightData &drawing_weight, const int point_index)
bDeformGroup * object_defgroup
void get_brush_settings(const bContext &C, const InputSample &start_sample)
void get_locked_and_bone_deformed_vertex_groups()
GreasePencil * grease_pencil
void init_weight_data_for_drawings(const bContext &C, const Span< ed::greasepencil::MutableDrawingInfo > &drawings, const int frame_group)
void apply_weight_to_point(const BrushPoint &point, const float target_weight, DrawingWeightData &drawing_weight)
Set< std::string > get_bone_deformed_vertex_group_names(const Object &object)
static constexpr int BLUR_NEIGHBOUR_NUM
static constexpr float FIND_NEAREST_POINT_EPSILON
static constexpr int SMEAR_NEIGHBOUR_NUM
T clamp(const T &a, const T &min, const T &max)
T distance(const T &a, const T &b)
T interpolate(const T &a, const T &b, const FactorT &t)
void parallel_for(const IndexRange range, const int64_t grain_size, const Function &function, const TaskSizeHints &size_hints=detail::TaskSizeHints_Static(1))
VecBase< float, 2 > float2
int vertex_group_active_index
Vector< bool > locked_vgroups
Vector< BrushPoint > points_in_brush
float multi_frame_falloff
MutableSpan< MDeformVert > deform_verts
Array< float2 > point_positions
Array< bool > points_touched_by_brush
int points_touched_by_brush_num
VMutableArray< float > deform_weights
Vector< bool > bone_deformed_vgroups
Array< bool > point_is_read_only