103 const float target_weight,
107 const float old_weight = drawing_weight.
deform_weights[point.drawing_point_index];
108 const float weight_delta = (this->invert_brush_weight ? (1.0f - target_weight) :
112 point.drawing_point_index,
114 old_weight +
math::interpolate(0.0f, weight_delta, point.influence), 0.0f, 1.0f));
124 this->grease_pencil =
static_cast<GreasePencil *
>(this->
object->data);
133 this->invert_brush_weight =
false;
147 if (object_defgroup_nr == -1) {
149 object_defgroup_nr = 0;
161 this->object_locked_defgroups.
add(dg->name);
173 const int frame_group)
183 for (const int drawing_index : range) {
184 const ed::greasepencil::MutableDrawingInfo &drawing_info = drawings[drawing_index];
185 bke::CurvesGeometry &curves = drawing_info.drawing.strokes_for_write();
188 DrawingWeightData &drawing_weight_data =
189 this->drawing_weight_data[frame_group][drawing_index];
190 drawing_weight_data.active_vertex_group = bke::greasepencil::ensure_vertex_group(
191 this->object_defgroup->name, curves.vertex_group_names);
193 drawing_weight_data.multi_frame_falloff = drawing_info.multi_frame_falloff;
194 drawing_weight_data.deform_verts = curves.deform_verts_for_write();
195 drawing_weight_data.deform_weights = bke::varray_for_mutable_deform_verts(
196 drawing_weight_data.deform_verts, drawing_weight_data.active_vertex_group);
200 if (this->auto_normalize) {
201 LISTBASE_FOREACH (bDeformGroup *, dg, &curves.vertex_group_names) {
202 drawing_weight_data.locked_vgroups.append(
203 this->object_locked_defgroups.contains(dg->name));
204 drawing_weight_data.bone_deformed_vgroups.append(
205 this->object_bone_deformed_defgroups.contains(dg->name));
210 const bke::greasepencil::Layer &layer = this->grease_pencil->layer(
211 drawing_info.layer_index);
212 const float4x4 layer_to_world = layer.to_world_space(*ob_eval);
213 const float4x4 projection = ED_view3d_ob_project_mat_get_from_obmat(rv3d, layer_to_world);
215 bke::crazyspace::GeometryDeformation deformation =
216 bke::crazyspace::get_evaluated_grease_pencil_drawing_deformation(
217 ob_eval, *this->object, drawing_info.layer_index, drawing_info.frame_number);
218 drawing_weight_data.point_positions.reinitialize(deformation.positions.size());
219 threading::parallel_for(curves.points_range(), 1024, [&](const IndexRange point_range) {
220 for (const int point : point_range) {
221 drawing_weight_data.point_positions[point] = ED_view3d_project_float_v2_m4(
222 region, deformation.positions[point], projection);
227 drawing_weight_data.points_touched_by_brush_num = 0;
228 drawing_weight_data.points_touched_by_brush = Array<bool>(deformation.positions.size(),
236 const float brush_widen_factor = 1.0f)
247 this->brush_radius_wide = this->
brush_radius * brush_widen_factor;
250 this->mouse_position.x - this->brush_radius_wide,
251 this->mouse_position.x + this->brush_radius_wide,
252 this->mouse_position.y - this->brush_radius_wide,
253 this->mouse_position.y + this->brush_radius_wide);
259 const int point_index)
264 const float dist_point_to_brush_center =
math::distance(point_position, this->mouse_position);
265 if (dist_point_to_brush_center > this->brush_radius_wide) {
282 this->brush, dist_point_to_brush_center, this->
brush_radius);
283 if (influence != 0.0f) {
294 point_num += drawing_weight.points_touched_by_brush_num;
298 KDTree_2d *touched_points = BLI_kdtree_2d_new(point_num);
300 int kdtree_index = 0;
302 for (
const int point_index : drawing_weight.point_positions.index_range()) {
303 if (drawing_weight.points_touched_by_brush[point_index]) {
304 BLI_kdtree_2d_insert(
305 touched_points, kdtree_index, drawing_weight.point_positions[point_index]);
306 touched_points_weights[kdtree_index] = drawing_weight.deform_weights[point_index];
311 BLI_kdtree_2d_balance(touched_points);
313 return {touched_points, touched_points_weights};
bool BKE_brush_use_alpha_pressure(const Brush *brush)
float BKE_brush_weight_get(const Scene *scene, const Brush *brush)
int BKE_brush_size_get(const Scene *scene, 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_alpha_get(const Scene *scene, const Brush *brush)
Depsgraph * CTX_data_depsgraph_pointer(const bContext *C)
Object * CTX_data_active_object(const bContext *C)
Scene * CTX_data_scene(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.
#define LISTBASE_FOREACH(type, var, list)
void * BLI_findlink(const struct ListBase *listbase, int number) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
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)
Object * DEG_get_evaluated_object(const Depsgraph *depsgraph, Object *object)
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
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)
const Depsgraph * depsgraph
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
float brush_radius(const Scene &scene, const Brush &brush, float pressure)
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))
static float brush_strength(const Sculpt &sd, const blender::ed::sculpt_paint::StrokeCache &cache, const float feather, const UnifiedPaintSettings &ups, const PaintModeSettings &)
struct CurveMapping * curve
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