180 if (dv_prev->
flag == 1) {
200 paintval = 1.0f - paintval;
221 CLAMP(weight, 0.0f, 1.0f);
224 constexpr float threshold = 0.0001f;
225 return weight < threshold ? 0.0f : weight;
230 if (newval < oldval) {
231 return std::min(newval, curval);
233 if (newval > oldval) {
234 return std::max(newval, curval);
240 float weight,
float old_weight,
float locked_weight,
float free_weight,
bool auto_normalize)
244 if (auto_normalize || free_weight <= 0.0f) {
246 weight *= (1.0f - locked_weight);
254 if (old_weight >= free_weight) {
258 else if (weight < 1.0f) {
259 weight = weight * (free_weight - old_weight) / (1 - weight);
272 const int defbase_tot,
273 const bool *vgroup_validmap)
275 float sum = 0.0f, fac;
280 if (dw->
def_nr < defbase_tot && vgroup_validmap[dw->
def_nr]) {
286 if ((tot == 0) || (
sum == 1.0f)) {
294 if (dw->
def_nr < defbase_tot && vgroup_validmap[dw->
def_nr]) {
304 if (dw->
def_nr < defbase_tot && vgroup_validmap[dw->
def_nr]) {
316 const int defbase_tot,
317 const bool *vgroup_validmap,
318 const bool *lock_flags)
320 float sum = 0.0f, fac;
321 float sum_unlock = 0.0f;
322 float lock_weight = 0.0f;
326 if (lock_flags ==
nullptr) {
332 if (dw->
def_nr < defbase_tot && vgroup_validmap[dw->
def_nr]) {
335 if (lock_flags[dw->
def_nr]) {
336 lock_weight += dw->
weight;
357 if (dw->
def_nr < defbase_tot && vgroup_validmap[dw->
def_nr]) {
358 if (lock_flags[dw->
def_nr] ==
false) {
364 return (lock_weight == 1.0f);
366 if (sum_unlock != 0.0f) {
367 fac = (1.0f - lock_weight) / sum_unlock;
370 if (dw->
def_nr < defbase_tot && vgroup_validmap[dw->
def_nr]) {
371 if (lock_flags[dw->
def_nr] ==
false) {
381 fac = (1.0f - lock_weight) / tot;
383 CLAMP(fac, 0.0f, 1.0f);
386 if (dw->
def_nr < defbase_tot && vgroup_validmap[dw->
def_nr]) {
387 if (lock_flags[dw->
def_nr] ==
false) {
402 const int defbase_tot,
403 const bool *vgroup_validmap,
404 const bool *lock_flags,
405 const bool *lock_with_active)
410 dvert, defbase_tot, vgroup_validmap, lock_with_active);
427static bool has_unselected_unlocked_bone_group(
int defbase_tot,
430 const bool *lock_flags,
431 const bool *vgroup_validmap)
434 if (defbase_tot == selected) {
437 for (
i = 0;
i < defbase_tot;
i++) {
438 if (vgroup_validmap[
i] && !defbase_sel[
i] && !lock_flags[
i]) {
446 const int defbase_tot,
447 const bool *defbase_sel,
453 float change = *change_p;
457 if (dw->
def_nr < defbase_tot && defbase_sel[dw->
def_nr]) {
459 val = dw->
weight * change;
461 change = 1.0f / dw->
weight;
471 const int defbase_tot,
473 const bool *defbase_sel)
483 if (dw->
def_nr < defbase_tot && defbase_sel[dw->
def_nr]) {
485 val = dw->
weight * change;
499 const int defbase_tot,
501 const bool *defbase_sel)
507 if (dw->
def_nr < defbase_tot && defbase_sel[dw->
def_nr]) {
528 float weight_prev, weight_cur;
529 float dw_rel_locked = 0.0f, dw_rel_free = 1.0f;
544 if (index_mirr == index && vgroup_mirr == wpi.
active.
index) {
545 index_mirr = vgroup_mirr = -1;
549 index_mirr = vgroup_mirr = -1;
559 CLAMP(dw_rel_locked, 0.0f, 1.0f);
565 restrict_to_existing =
true;
570 if (restrict_to_existing) {
581 if (index_mirr != -1) {
582 dv_mirr = &wpi.
dvert[index_mirr];
586 if (dw_mirr ==
nullptr) {
587 index_mirr = vgroup_mirr = -1;
592 if (index != index_mirr) {
598 int dw_offset = int(dw - dv_mirr->
dw);
602 if (totweight_prev != dv_mirr->
totweight) {
603 dw = &dv_mirr->
dw[dw_offset];
623 if (index_mirr != -1) {
635 weight_prev = weight_cur;
649 if (index_mirr == index) {
663 CLAMP(weight, 0.0f, 1.0f);
671 if (index_mirr != -1) {
691 if (index_mirr != -1) {
694 if (index != index_mirr) {
735 float curw, curw_real, oldw, neww, change, curw_mirr, change_mirr;
736 float dw_rel_free, dw_rel_locked;
742 if (!
ELEM(index_mirr, -1, index)) {
743 dv_mirr = &wpi.
dvert[index_mirr];
763 CLAMP(dw_rel_locked, 0.0f, 1.0f);
771 if (index_mirr != -1) {
795 change = neww / curw_real;
800 if (dv_mirr !=
nullptr) {
804 if (curw_mirr == 0.0f) {
810 float orig = change_mirr = curw_real * change / curw_mirr;
818 change *= change_mirr / orig;
829 if (dv_mirr !=
nullptr) {
837 if (dv_mirr !=
nullptr) {
867 int defbase_tot, defbase_tot_sel;
886 if (vgroup_index.
mirror != -1) {
905 &ob, defbase_tot, defbase_sel, defbase_sel, &defbase_tot_sel);
908 for (
i = 0;
i < defbase_tot;
i++) {
909 if (defbase_sel[
i]) {
920 std::unique_ptr<WPaintData> wpd = std::make_unique<WPaintData>();
928 wpd->active.index = vgroup_index.
active;
929 wpd->mirror.index = vgroup_index.
mirror;
932 wpd->defbase_tot = defbase_tot;
933 wpd->defbase_sel = defbase_sel;
934 wpd->defbase_tot_sel = defbase_tot_sel > 1 ? defbase_tot_sel : 1;
935 wpd->do_multipaint = (ts.
multipaint && defbase_tot_sel > 1);
948 wpd->lock_flags, wpd->vgroup_validmap, wpd->active.index) &&
950 defbase_tot, wpd->lock_flags, defbase_sel, defbase_tot_sel)))
952 wpd->do_lock_relative =
true;
955 if (wpd->do_lock_relative || (ts.
auto_normalize && wpd->lock_flags && !wpd->do_multipaint)) {
956 bool *unlocked = (
bool *)
MEM_dupallocN(wpd->vgroup_validmap);
958 if (wpd->lock_flags) {
961 wpd->defbase_tot, wpd->lock_flags, wpd->vgroup_validmap, locked, unlocked);
962 wpd->vgroup_locked = locked;
965 wpd->vgroup_unlocked = unlocked;
971 if (wpd->lock_flags) {
975 memcpy(tmpflags, wpd->defbase_sel,
sizeof(*tmpflags) * wpd->defbase_tot);
977 wpd->active.lock = tmpflags;
982 tmpflags = wpd->lock_flags ? (
bool *)
MEM_dupallocN(wpd->lock_flags) :
984 tmpflags[wpd->active.index] =
true;
985 wpd->active.lock = tmpflags;
987 tmpflags = wpd->lock_flags ? (
bool *)
MEM_dupallocN(wpd->lock_flags) :
989 tmpflags[(wpd->mirror.index != -1) ? wpd->mirror.index : wpd->active.index] =
true;
990 wpd->mirror.lock = tmpflags;
1006 for (
int i = 0;
i <
mesh.verts_num;
i++, dv++) {
1034 CLAMP(weight, 0.0f, 1.0f);
1049 for (const int i : range) {
1050 const MDeformVert &dv = wpi.dvert[i];
1051 wpd.precomputed_weight[i] = wpaint_get_active_weight(dv, wpi);
1055 wpd.precomputed_weight_ready =
true;
1082 for (
const int i :
verts.index_range()) {
1083 if (!select_vert[
verts[
i]]) {
1104 float brush_size_pressure, brush_alpha_value, brush_alpha_pressure;
1106 ss, vp.
paint, brush, &brush_size_pressure, &brush_alpha_value, &brush_alpha_pressure);
1121 if (use_vert_sel || use_face_sel) {
1131 LocalData &tls = all_tls.
local();
1134 tls.factors.resize(
verts.size());
1138 if (!select_vert.is_empty()) {
1142 tls.distances.resize(
verts.size());
1149 for (
const int i :
verts.index_range()) {
1150 const int vert =
verts[
i];
1151 if (factors[
i] == 0.0f) {
1156 int total_hit_loops = 0;
1157 float weight_final = 0.0f;
1158 for (
const int face : vert_to_face[vert]) {
1159 total_hit_loops +=
faces[face].size();
1160 for (
const int vert : corner_verts.
slice(
faces[face])) {
1165 if (total_hit_loops == 0) {
1170 const float angle_cos = use_normal ?
1171 dot_v3v3(sculpt_normal_frontface, vert_normals[vert]) :
1179 const float final_alpha = factors[
i] *
brush_strength * brush_alpha_pressure;
1190 weight_final /= total_hit_loops;
1215 float brush_size_pressure, brush_alpha_value, brush_alpha_pressure;
1217 ss, vp.
paint, brush, &brush_size_pressure, &brush_alpha_value, &brush_alpha_pressure);
1236 if (use_vert_sel || use_face_sel) {
1249 LocalData &tls = all_tls.
local();
1252 tls.factors.resize(
verts.size());
1256 if (!select_vert.is_empty()) {
1260 tls.distances.resize(
verts.size());
1267 for (
const int i :
verts.index_range()) {
1268 const int vert =
verts[
i];
1269 if (factors[
i] == 0.0f) {
1274 const float angle_cos = use_normal ?
1275 dot_v3v3(sculpt_normal_frontface, vert_normals[vert]) :
1283 bool do_color =
false;
1286 float stroke_dot_max = 0.0f;
1290 float weight_final = 0.0;
1291 for (
const int face : vert_to_face[vert]) {
1292 for (
const int vert_other : corner_verts.
slice(
faces[face])) {
1293 if (vert_other == vert) {
1299 sub_v3_v3v3(other_dir, vert_positions[vert], vert_positions[vert_other]);
1304 const float stroke_dot =
dot_v3v3(other_dir, brush_dir);
1306 if (stroke_dot > stroke_dot_max) {
1307 stroke_dot_max = stroke_dot;
1315 const float final_alpha = factors[
i] *
brush_strength * brush_alpha_pressure;
1330 const float strength,
1340 const float paintweight = strength;
1341 float brush_size_pressure, brush_alpha_value, brush_alpha_pressure;
1343 ss, vp.
paint, brush, &brush_size_pressure, &brush_alpha_value, &brush_alpha_pressure);
1356 if (use_vert_sel || use_face_sel) {
1366 LocalData &tls = all_tls.
local();
1369 tls.factors.resize(
verts.size());
1373 if (!select_vert.is_empty()) {
1377 tls.distances.resize(
verts.size());
1384 for (
const int i :
verts.index_range()) {
1385 const int vert =
verts[
i];
1386 if (factors[
i] == 0.0f) {
1390 const float angle_cos = use_normal ?
1391 dot_v3v3(sculpt_normal_frontface, vert_normals[vert]) :
1398 const float final_alpha = factors[
i] *
brush_strength * brush_alpha_pressure;
1440 if (use_vert_sel || use_face_sel) {
1454 LocalData &tls = all_tls.local();
1455 node_mask.slice(range).foreach_index([&](const int i) {
1456 const Span<int> verts = nodes[i].verts();
1457 tls.factors.resize(verts.size());
1458 const MutableSpan<float> factors = tls.factors;
1459 fill_factor_from_hide(hide_vert, verts, factors);
1460 filter_region_clip_factors(ss, vert_positions, verts, factors);
1461 if (!select_vert.is_empty()) {
1462 filter_factors_with_selection(select_vert, verts, factors);
1465 tls.distances.resize(verts.size());
1466 const MutableSpan<float> distances = tls.distances;
1467 calc_brush_distances(
1468 ss, vert_positions, verts, eBrushFalloffShape(brush.falloff_shape), distances);
1469 filter_distances_with_radius(cache.radius, distances, factors);
1470 calc_brush_strength_factors(cache, brush, distances, factors);
1472 for (const int i : verts.index_range()) {
1473 const int vert = verts[i];
1474 if (factors[i] == 0.0f) {
1477 const float angle_cos = use_normal ?
1478 dot_v3v3(sculpt_normal_frontface, vert_normals[vert]) :
1480 if (angle_cos <= 0.0f) {
1483 const MDeformVert &dv = wpi.dvert[vert];
1485 accum.value += wpaint_get_active_weight(dv, wpi);
1628 const bool is_mode_set = (ob.
mode & mode_flag) != 0;
1672 ot->name =
"Weight Paint Mode";
1673 ot->idname =
"PAINT_OT_weight_paint_toggle";
1674 ot->description =
"Toggle weight paint mode in 3D view";
1720 for (
int i = 1;
i <
mesh.radial_symmetry[axis -
'X'];
i++) {
1721 const float angle = (2.0 *
M_PI) *
i /
mesh.radial_symmetry[axis -
'X'];
1722 wpaint_do_paint(
C, ob, wp, wpd, wpi,
mesh, brush, symm, axis,
i,
angle);
1740 wpaint_do_paint(
C, ob, wp, wpd, wpi,
mesh, brush,
ePaintSymmetryFlags(0),
'X', 0, 0);
1754 for (
i = 1;
i <= symm;
i++) {
1762 wpaint_do_paint(
C, ob, wp, wpd, wpi,
mesh, brush, symm,
'X', 0, 0);
1766 wpaint_do_paint(
C, ob, wp, wpd, wpi,
mesh, brush, symm,
'Y', 0, 0);
1770 wpaint_do_paint(
C, ob, wp, wpd, wpi,
mesh, brush, symm,
'Z', 0, 0);
1802 if (wpd ==
nullptr) {
1820 wpi.
dvert =
mesh.deform_verts_for_write();
1952 ot->name =
"Weight Paint";
1953 ot->idname =
"PAINT_OT_weight_paint";
1954 ot->description =
"Paint a stroke in the current vertex group's weights";
1967 "override_location",
1969 "Override Location",
1970 "Override the given \"location\" array by recalculating object space positions from the "
1971 "provided \"mouse_event\" positions");
float BKE_brush_alpha_get(const Paint *paint, const Brush *brush)
float BKE_brush_weight_get(const Paint *paint, const Brush *brush)
Depsgraph * CTX_data_ensure_evaluated_depsgraph(const bContext *C)
ScrArea * CTX_wm_area(const bContext *C)
Depsgraph * CTX_data_depsgraph_pointer(const bContext *C)
Object * CTX_data_active_object(const bContext *C)
Scene * CTX_data_scene(const bContext *C)
Main * CTX_data_main(const bContext *C)
ToolSettings * CTX_data_tool_settings(const bContext *C)
ARegion * CTX_wm_region(const bContext *C)
Depsgraph * CTX_data_depsgraph_on_load(const bContext *C)
wmMsgBus * CTX_wm_message_bus(const bContext *C)
void BKE_mesh_batch_cache_dirty_tag(Mesh *mesh, eMeshBatchDirtyMode mode)
@ BKE_MESH_BATCH_DIRTY_ALL
Mesh * BKE_mesh_from_object(Object *ob)
const Brush * BKE_paint_brush_for_read(const Paint *paint)
Brush * BKE_paint_brush(Paint *paint)
void BKE_paint_brushes_validate(Main *bmain, Paint *paint)
void BKE_report(ReportList *reports, eReportType type, const char *message)
Generic array manipulation API.
#define BLI_array_binary_or(arr, arr_a, arr_b, arr_len)
void * BLI_findlink(const ListBase *listbase, int number) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
#define LISTBASE_FOREACH(type, var, list)
int BLI_listbase_count(const ListBase *listbase) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
void mul_m4_m4m4(float R[4][4], const float A[4][4], const float B[4][4])
void swap_m4m4(float m1[4][4], float m2[4][4])
void mul_v3_m4v3(float r[3], const float mat[4][4], const float vec[3])
MINLINE void sub_v3_v3v3(float r[3], const float a[3], const float b[3])
MINLINE void copy_v3_v3(float r[3], const float a[3])
void project_plane_v3_v3v3(float out[3], const float p[3], const float v_plane[3])
MINLINE float dot_v3v3(const float a[3], const float b[3]) ATTR_WARN_UNUSED_RESULT
MINLINE float normalize_v3(float n[3])
void DEG_id_tag_update(ID *id, unsigned int flags)
@ WPAINT_BRUSH_TYPE_AVERAGE
@ WPAINT_BRUSH_TYPE_SMEAR
@ BRUSH_FRONTFACE_FALLOFF
@ ME_EDIT_MIRROR_VERTEX_GROUPS
#define ME_USING_MIRROR_X_VERTEX_GROUPS(_me)
Object is a sort of wrapper for general info.
@ VP_FLAG_VGROUP_RESTRICT
#define OPERATOR_RETVAL_CHECK(ret)
int mesh_get_x_mirror_vert(Object *ob, Mesh *mesh_eval, int index, bool use_topology)
bool ED_operator_region_view3d_active(bContext *C)
void ED_region_tag_redraw(ARegion *region)
void ED_view3d_init_mats_rv3d(const Object *ob, RegionView3D *rv3d)
ViewContext ED_view3d_viewcontext_init(bContext *C, Depsgraph *depsgraph)
void view3d_operator_needs_gpu(const bContext *C)
static double angle(const Eigen::Vector3d &v1, const Eigen::Vector3d &v2)
Read Guarded memory(de)allocation.
BPy_StructRNA * depsgraph
static T sum(const btAlignedObjectArray< T > &items)
constexpr T * data() const
constexpr int64_t size() const
constexpr Span slice(int64_t start, int64_t size) const
GAttributeReader lookup(const StringRef attribute_id) const
Span< NodeT > nodes() const
IndexMask slice(IndexRange range) const
IndexRange index_range() const
void foreach_index(Fn &&fn) const
void * MEM_calloc_arrayN(size_t len, size_t size, const char *str)
void * MEM_malloc_arrayN(size_t len, size_t size, const char *str)
void * MEM_dupallocN(const void *vmemh)
void MEM_freeN(void *vmemh)
pbvh::Tree * pbvh_get(Object &object)
Span< float3 > vert_normals_eval(const Depsgraph &depsgraph, const Object &object_orig)
Span< float3 > vert_positions_eval(const Depsgraph &depsgraph, const Object &object_orig)
void posemode_set_for_weight_paint(bContext *C, Main *bmain, Object *ob, bool is_mode_set)
bool mode_compat_set(bContext *C, Object *ob, eObjectMode mode, ReportList *reports)
bool brush_use_accumulate_ex(const Brush &brush, eObjectMode ob_mode)
void view_angle_limits_init(NormalAnglePrecalc *a, float angle, bool do_mask_normal)
bool use_normal(const VPaint &vp)
void mode_exit_generic(Object &ob, eObjectMode mode_flag)
bool test_brush_angle_falloff(const Brush &brush, const NormalAnglePrecalc &normal_angle_precalc, float angle_cos, float *brush_strength)
void init_session_data(const ToolSettings &ts, Object &ob)
void mode_enter_generic(Main &bmain, Depsgraph &depsgraph, Scene &scene, Object &ob, eObjectMode mode_flag)
void update_cache_invariants(bContext *C, VPaint &vp, SculptSession &ss, wmOperator *op, const float mval[2])
void get_brush_alpha_data(const SculptSession &ss, const Paint &paint, const Brush &brush, float *r_brush_size_pressure, float *r_brush_alpha_value, float *r_brush_alpha_pressure)
bool brush_use_accumulate(const VPaint &vp)
void init_stroke(Depsgraph &depsgraph, Object &ob)
void update_cache_variants(bContext *C, VPaint &vp, Object &ob, PointerRNA *ptr)
void last_stroke_update(const float location[3], Paint &paint)
IndexMask pbvh_gather_generic(const Depsgraph &depsgraph, const Object &ob, const VPaint &wp, const Brush &brush, IndexMaskMemory &memory)
bool mode_toggle_poll_test(bContext *C)
void smooth_brush_toggle_off(Paint *paint, StrokeCache *cache)
bool stroke_get_location_bvh(bContext *C, float out[3], const float mval[2], const bool force_original)
void calc_brush_strength_factors(const StrokeCache &cache, const Brush &brush, Span< float > distances, MutableSpan< float > factors)
wmOperatorStatus paint_stroke_exec(bContext *C, wmOperator *op, PaintStroke *stroke)
void filter_distances_with_radius(float radius, Span< float > distances, MutableSpan< float > factors)
void filter_region_clip_factors(const SculptSession &ss, Span< float3 > vert_positions, Span< int > verts, MutableSpan< float > factors)
void paint_stroke_cancel(bContext *C, wmOperator *op, PaintStroke *stroke)
wmOperatorStatus paint_stroke_modal(bContext *C, wmOperator *op, const wmEvent *event, PaintStroke **stroke_p)
void calc_brush_distances(const SculptSession &ss, Span< float3 > vert_positions, Span< int > vert, eBrushFalloffShape falloff_shape, MutableSpan< float > r_distances)
void * paint_stroke_mode_data(PaintStroke *stroke)
void paint_stroke_free(bContext *C, wmOperator *op, PaintStroke *stroke)
PaintStroke * paint_stroke_new(bContext *C, wmOperator *op, StrokeGetLocation get_location, StrokeTestStart test_start, StrokeUpdateStep update_step, StrokeRedraw redraw, StrokeDone done, int event_type)
void fill_factor_from_hide(Span< bool > hide_vert, Span< int > verts, MutableSpan< float > r_factors)
void paint_stroke_set_mode_data(PaintStroke *stroke, std::unique_ptr< PaintModeData > mode_data)
bool is_symmetry_iteration_valid(const char i, const char symm)
T safe_divide(const T &a, const T &b)
void parallel_for(const IndexRange range, const int64_t grain_size, const Function &function, const TaskSizeHints &size_hints=detail::TaskSizeHints_Static(1))
Value parallel_reduce(IndexRange range, int64_t grain_size, const Value &identity, const Function &function, const Reduction &reduction)
float ED_wpaint_blend_tool(int tool, float weight, float paintval, float alpha)
bool ED_wpaint_ensure_data(bContext *C, ReportList *reports, eWPaintFlag flag, WPaintVGroupIndex *vgroup_index)
bool weight_paint_poll(bContext *C)
void paint_stroke_operator_properties(wmOperatorType *ot)
static bool wpaint_stroke_test_start(bContext *C, wmOperator *op, const float mouse[2])
static void do_weight_paint_normalize_all(MDeformVert *dvert, const int defbase_tot, const bool *vgroup_validmap)
void ED_object_wpaintmode_enter_ex(Main &bmain, Depsgraph &depsgraph, Scene &scene, Object &ob)
void PAINT_OT_weight_paint(wmOperatorType *ot)
static void wpaint_do_paint(bContext *C, Object &ob, VPaint &wp, WPaintData &wpd, WeightPaintInfo &wpi, Mesh &mesh, Brush &brush, const ePaintSymmetryFlags symm, const int axis, const int i, const float angle)
static bool weight_paint_poll_ex(bContext *C, bool check_tool)
bool weight_paint_mode_poll(bContext *C)
static void precompute_weight_values(Object &ob, const Brush &brush, WPaintData &wpd, WeightPaintInfo &wpi, Mesh &mesh)
static float wpaint_get_active_weight(const MDeformVert &dv, const WeightPaintInfo &wpi)
bool weight_paint_poll(bContext *C)
static float wpaint_blend(const VPaint &wp, float weight, const float alpha, float paintval, const float, const bool do_flip)
static void filter_factors_with_selection(const Span< bool > select_vert, const Span< int > verts, const MutableSpan< float > factors)
bool weight_paint_mode_region_view3d_poll(bContext *C)
static void do_weight_paint_vertex(const VPaint &wp, Object &ob, const WeightPaintInfo &wpi, const uint index, float alpha, float paintweight)
void ED_object_wpaintmode_exit(bContext *C)
static void wpaint_paint_leaves(bContext *C, Object &ob, VPaint &vp, WPaintData &wpd, WeightPaintInfo &wpi, Mesh &mesh, const IndexMask &node_mask)
static bool multipaint_verify_change(MDeformVert *dvert, const int defbase_tot, float change, const bool *defbase_sel)
static wmOperatorStatus wpaint_mode_toggle_exec(bContext *C, wmOperator *op)
static wmOperatorStatus wpaint_modal(bContext *C, wmOperator *op, const wmEvent *event)
static wmOperatorStatus wpaint_invoke(bContext *C, wmOperator *op, const wmEvent *event)
void ED_object_wpaintmode_exit_ex(Object &ob)
static float wpaint_clamp_monotonic(float oldval, float curval, float newval)
static void wpaint_stroke_done(const bContext *C, PaintStroke *)
static void do_wpaint_brush_draw(const Depsgraph &depsgraph, Object &ob, const Brush &brush, VPaint &vp, WPaintData &wpd, const WeightPaintInfo &wpi, Mesh &mesh, const float strength, const IndexMask &node_mask)
static float wpaint_undo_lock_relative(float weight, float old_weight, float locked_weight, float free_weight, bool auto_normalize)
static void wpaint_do_radial_symmetry(bContext *C, Object &ob, VPaint &wp, WPaintData &wpd, WeightPaintInfo &wpi, Mesh &mesh, Brush &brush, const ePaintSymmetryFlags symm, const int axis)
static MDeformVert * defweight_prev_init(MDeformVert *dvert_prev, MDeformVert *dvert_curr, int index)
bool weight_paint_poll_ignore_tool(bContext *C)
static void do_weight_paint_vertex_multi(const VPaint &wp, Object &ob, const WeightPaintInfo &wpi, const uint index, float alpha, float paintweight)
static void do_wpaint_brush_smear(const Depsgraph &depsgraph, Object &ob, const Brush &brush, VPaint &vp, WPaintData &wpd, const WeightPaintInfo &wpi, Mesh &mesh, const IndexMask &node_mask)
static void wpaint_cancel(bContext *C, wmOperator *op)
static void wpaint_stroke_update_step(bContext *C, wmOperator *op, PaintStroke *stroke, PointerRNA *itemptr)
void ED_object_wpaintmode_enter(bContext *C, Depsgraph &depsgraph)
void PAINT_OT_weight_paint_toggle(wmOperatorType *ot)
static float calculate_average_weight(const Depsgraph &depsgraph, Object &ob, const Mesh &mesh, const Brush &brush, const VPaint &vp, WeightPaintInfo &wpi, const IndexMask &node_mask)
static void wpaint_do_symmetrical_brush_actions(bContext *C, Object &ob, VPaint &wp, WPaintData &wpd, WeightPaintInfo &wpi)
static void multipaint_apply_change(MDeformVert *dvert, const int defbase_tot, float change, const bool *defbase_sel)
static void multipaint_clamp_change(MDeformVert *dvert, const int defbase_tot, const bool *defbase_sel, float *change_p)
static void do_wpaint_brush_blur(const Depsgraph &depsgraph, Object &ob, const Brush &brush, VPaint &vp, WPaintData &wpd, const WeightPaintInfo &wpi, Mesh &mesh, const IndexMask &node_mask)
static void do_weight_paint_vertex_single(const VPaint &wp, Object &ob, const WeightPaintInfo &wpi, const uint index, float alpha, float paintweight)
static void do_weight_paint_normalize_all_locked_try_active(MDeformVert *dvert, const int defbase_tot, const bool *vgroup_validmap, const bool *lock_flags, const bool *lock_with_active)
static wmOperatorStatus wpaint_exec(bContext *C, wmOperator *op)
static void parallel_nodes_loop_with_mirror_check(const Mesh &mesh, const IndexMask &node_mask, FunctionRef< void(IndexRange)> fn)
static bool do_weight_paint_normalize_all_locked(MDeformVert *dvert, const int defbase_tot, const bool *vgroup_validmap, const bool *lock_flags)
bool RNA_boolean_get(PointerRNA *ptr, const char *name)
PropertyRNA * RNA_def_boolean(StructOrFunctionRNA *cont_, const char *identifier, const bool default_value, const char *ui_name, const char *ui_description)
void RNA_def_property_flag(PropertyRNA *prop, PropertyFlag flag)
ePaintSymmetryFlags SCULPT_mesh_symmetry_xyz_get(const Object &object)
const float * SCULPT_brush_frontface_normal_from_falloff_shape(const SculptSession &ss, char falloff_shape)
void SCULPT_cache_calc_brushdata_symm(blender::ed::sculpt_paint::StrokeCache &cache, const ePaintSymmetryFlags symm, const char axis, const float angle)
static float brush_strength(const Sculpt &sd, const blender::ed::sculpt_paint::StrokeCache &cache, const float feather, const PaintModeSettings &)
struct SculptSession * sculpt
struct ToolSettings * toolsettings
blender::ed::sculpt_paint::StrokeCache * cache
blender::Array< MDeformVert > dvert_prev
struct SculptSession::@362240011116215270333121305340144315201335267314::@377352350121204263020240366015362210376116055117 wpaint
struct SculptSession::@362240011116215270333121305340144315201335267314 mode
const bool * vgroup_unlocked
NormalAnglePrecalc normal_angle_precalc
WeightPaintGroupData active
const bool * vgroup_validmap
const bool * vgroup_locked
bool precomputed_weight_ready
float * precomputed_weight
WeightPaintGroupData mirror
const bool * vgroup_locked
MutableSpan< MDeformVert > dvert
WeightPaintGroupData mirror
const bool * vgroup_unlocked
const bool * vgroup_validmap
WeightPaintGroupData active
float3 last_location_symm
ePaintSymmetryFlags mirror_symmetry_pass
wmOperatorStatus(* modal)(bContext *C, wmOperator *op, const wmEvent *event) ATTR_WARN_UNUSED_RESULT
struct ReportList * reports
struct wmOperatorType * type
static int blend(const Tex *tex, const float texvec[3], TexResult *texres)
wmEventHandler_Op * WM_event_add_modal_handler(bContext *C, wmOperator *op)
void WM_event_add_notifier(const bContext *C, uint type, void *reference)
#define WM_msg_publish_rna_prop(mbus, id_, data_, type_, prop_)