184 if (dv_prev->
flag == 1) {
204 paintval = 1.0f - paintval;
225 CLAMP(weight, 0.0f, 1.0f);
228 constexpr float threshold = 0.0001f;
229 return weight < threshold ? 0.0f : weight;
234 if (newval < oldval) {
235 return std::min(newval, curval);
237 if (newval > oldval) {
238 return std::max(newval, curval);
244 float weight,
float old_weight,
float locked_weight,
float free_weight,
bool auto_normalize)
248 if (auto_normalize || free_weight <= 0.0f) {
250 weight *= (1.0f - locked_weight);
258 if (old_weight >= free_weight) {
262 else if (weight < 1.0f) {
263 weight = weight * (free_weight - old_weight) / (1 - weight);
276 const int defbase_tot,
277 const bool *vgroup_validmap)
279 float sum = 0.0f, fac;
284 if (dw->
def_nr < defbase_tot && vgroup_validmap[dw->
def_nr]) {
290 if ((tot == 0) || (
sum == 1.0f)) {
298 if (dw->
def_nr < defbase_tot && vgroup_validmap[dw->
def_nr]) {
308 if (dw->
def_nr < defbase_tot && vgroup_validmap[dw->
def_nr]) {
320 const int defbase_tot,
321 const bool *vgroup_validmap,
322 const bool *lock_flags)
324 float sum = 0.0f, fac;
325 float sum_unlock = 0.0f;
326 float lock_weight = 0.0f;
330 if (lock_flags ==
nullptr) {
336 if (dw->
def_nr < defbase_tot && vgroup_validmap[dw->
def_nr]) {
339 if (lock_flags[dw->
def_nr]) {
340 lock_weight += dw->
weight;
361 if (dw->
def_nr < defbase_tot && vgroup_validmap[dw->
def_nr]) {
362 if (lock_flags[dw->
def_nr] ==
false) {
368 return (lock_weight == 1.0f);
370 if (sum_unlock != 0.0f) {
371 fac = (1.0f - lock_weight) / sum_unlock;
374 if (dw->
def_nr < defbase_tot && vgroup_validmap[dw->
def_nr]) {
375 if (lock_flags[dw->
def_nr] ==
false) {
385 fac = (1.0f - lock_weight) / tot;
387 CLAMP(fac, 0.0f, 1.0f);
390 if (dw->
def_nr < defbase_tot && vgroup_validmap[dw->
def_nr]) {
391 if (lock_flags[dw->
def_nr] ==
false) {
406 const int defbase_tot,
407 const bool *vgroup_validmap,
408 const bool *lock_flags,
409 const bool *lock_with_active)
414 dvert, defbase_tot, vgroup_validmap, lock_with_active);
431static bool has_unselected_unlocked_bone_group(
int defbase_tot,
434 const bool *lock_flags,
435 const bool *vgroup_validmap)
438 if (defbase_tot == selected) {
441 for (
i = 0;
i < defbase_tot;
i++) {
442 if (vgroup_validmap[
i] && !defbase_sel[
i] && !lock_flags[
i]) {
450 const int defbase_tot,
451 const bool *defbase_sel,
457 float change = *change_p;
461 if (dw->
def_nr < defbase_tot && defbase_sel[dw->
def_nr]) {
463 val = dw->
weight * change;
465 change = 1.0f / dw->
weight;
475 const int defbase_tot,
477 const bool *defbase_sel)
487 if (dw->
def_nr < defbase_tot && defbase_sel[dw->
def_nr]) {
489 val = dw->
weight * change;
503 const int defbase_tot,
505 const bool *defbase_sel)
511 if (dw->
def_nr < defbase_tot && defbase_sel[dw->
def_nr]) {
532 float weight_prev, weight_cur;
533 float dw_rel_locked = 0.0f, dw_rel_free = 1.0f;
548 if (index_mirr == index && vgroup_mirr == wpi.
active.
index) {
549 index_mirr = vgroup_mirr = -1;
553 index_mirr = vgroup_mirr = -1;
563 CLAMP(dw_rel_locked, 0.0f, 1.0f);
569 restrict_to_existing =
true;
574 if (restrict_to_existing) {
585 if (index_mirr != -1) {
586 dv_mirr = &wpi.
dvert[index_mirr];
590 if (dw_mirr ==
nullptr) {
591 index_mirr = vgroup_mirr = -1;
596 if (index != index_mirr) {
602 int dw_offset = int(dw - dv_mirr->
dw);
606 if (totweight_prev != dv_mirr->
totweight) {
607 dw = &dv_mirr->
dw[dw_offset];
627 if (index_mirr != -1) {
639 weight_prev = weight_cur;
653 if (index_mirr == index) {
667 CLAMP(weight, 0.0f, 1.0f);
675 if (index_mirr != -1) {
695 if (index_mirr != -1) {
698 if (index != index_mirr) {
739 float curw, curw_real, oldw, neww, change, curw_mirr, change_mirr;
740 float dw_rel_free, dw_rel_locked;
746 if (!
ELEM(index_mirr, -1, index)) {
747 dv_mirr = &wpi.
dvert[index_mirr];
767 CLAMP(dw_rel_locked, 0.0f, 1.0f);
775 if (index_mirr != -1) {
799 change = neww / curw_real;
804 if (dv_mirr !=
nullptr) {
808 if (curw_mirr == 0.0f) {
814 float orig = change_mirr = curw_real * change / curw_mirr;
822 change *= change_mirr / orig;
833 if (dv_mirr !=
nullptr) {
841 if (dv_mirr !=
nullptr) {
871 int defbase_tot, defbase_tot_sel;
890 if (vgroup_index.
mirror != -1) {
909 &ob, defbase_tot, defbase_sel, defbase_sel, &defbase_tot_sel);
912 for (
i = 0;
i < defbase_tot;
i++) {
913 if (defbase_sel[
i]) {
924 std::unique_ptr<WPaintData> wpd = std::make_unique<WPaintData>();
932 wpd->active.index = vgroup_index.
active;
933 wpd->mirror.index = vgroup_index.
mirror;
936 wpd->defbase_tot = defbase_tot;
937 wpd->defbase_sel = defbase_sel;
938 wpd->defbase_tot_sel = defbase_tot_sel > 1 ? defbase_tot_sel : 1;
939 wpd->do_multipaint = (ts.
multipaint && defbase_tot_sel > 1);
952 wpd->lock_flags, wpd->vgroup_validmap, wpd->active.index) &&
954 defbase_tot, wpd->lock_flags, defbase_sel, defbase_tot_sel)))
956 wpd->do_lock_relative =
true;
959 if (wpd->do_lock_relative || (ts.
auto_normalize && wpd->lock_flags && !wpd->do_multipaint)) {
960 bool *unlocked = (
bool *)
MEM_dupallocN(wpd->vgroup_validmap);
962 if (wpd->lock_flags) {
965 wpd->defbase_tot, wpd->lock_flags, wpd->vgroup_validmap, locked, unlocked);
966 wpd->vgroup_locked = locked;
969 wpd->vgroup_unlocked = unlocked;
975 if (wpd->lock_flags) {
979 memcpy(tmpflags, wpd->defbase_sel,
sizeof(*tmpflags) * wpd->defbase_tot);
981 wpd->active.lock = tmpflags;
986 tmpflags = wpd->lock_flags ? (
bool *)
MEM_dupallocN(wpd->lock_flags) :
988 tmpflags[wpd->active.index] =
true;
989 wpd->active.lock = tmpflags;
991 tmpflags = wpd->lock_flags ? (
bool *)
MEM_dupallocN(wpd->lock_flags) :
993 tmpflags[(wpd->mirror.index != -1) ? wpd->mirror.index : wpd->active.index] =
true;
994 wpd->mirror.lock = tmpflags;
1010 for (
int i = 0;
i <
mesh.verts_num;
i++, dv++) {
1038 CLAMP(weight, 0.0f, 1.0f);
1053 for (const int i : range) {
1054 const MDeformVert &dv = wpi.dvert[i];
1055 wpd.precomputed_weight[i] = wpaint_get_active_weight(dv, wpi);
1059 wpd.precomputed_weight_ready =
true;
1086 for (
const int i :
verts.index_range()) {
1087 if (!select_vert[
verts[
i]]) {
1109 float brush_size_pressure, brush_alpha_value, brush_alpha_pressure;
1111 scene, ss, brush, &brush_size_pressure, &brush_alpha_value, &brush_alpha_pressure);
1126 if (use_vert_sel || use_face_sel) {
1136 LocalData &tls = all_tls.
local();
1139 tls.factors.resize(
verts.size());
1143 if (!select_vert.is_empty()) {
1147 tls.distances.resize(
verts.size());
1154 for (
const int i :
verts.index_range()) {
1155 const int vert =
verts[
i];
1156 if (factors[
i] == 0.0f) {
1161 int total_hit_loops = 0;
1162 float weight_final = 0.0f;
1163 for (
const int face : vert_to_face[vert]) {
1164 total_hit_loops +=
faces[face].size();
1165 for (
const int vert : corner_verts.
slice(
faces[face])) {
1170 if (total_hit_loops == 0) {
1175 const float angle_cos = use_normal ?
1176 dot_v3v3(sculpt_normal_frontface, vert_normals[vert]) :
1184 const float final_alpha = factors[
i] *
brush_strength * brush_alpha_pressure;
1195 weight_final /= total_hit_loops;
1221 float brush_size_pressure, brush_alpha_value, brush_alpha_pressure;
1223 scene, ss, brush, &brush_size_pressure, &brush_alpha_value, &brush_alpha_pressure);
1242 if (use_vert_sel || use_face_sel) {
1255 LocalData &tls = all_tls.
local();
1258 tls.factors.resize(
verts.size());
1262 if (!select_vert.is_empty()) {
1266 tls.distances.resize(
verts.size());
1273 for (
const int i :
verts.index_range()) {
1274 const int vert =
verts[
i];
1275 if (factors[
i] == 0.0f) {
1280 const float angle_cos = use_normal ?
1281 dot_v3v3(sculpt_normal_frontface, vert_normals[vert]) :
1289 bool do_color =
false;
1292 float stroke_dot_max = 0.0f;
1296 float weight_final = 0.0;
1297 for (
const int face : vert_to_face[vert]) {
1298 for (
const int vert_other : corner_verts.
slice(
faces[face])) {
1299 if (vert_other == vert) {
1305 sub_v3_v3v3(other_dir, vert_positions[vert], vert_positions[vert_other]);
1310 const float stroke_dot =
dot_v3v3(other_dir, brush_dir);
1312 if (stroke_dot > stroke_dot_max) {
1313 stroke_dot_max = stroke_dot;
1321 const float final_alpha = factors[
i] *
brush_strength * brush_alpha_pressure;
1337 const float strength,
1347 const float paintweight = strength;
1348 float brush_size_pressure, brush_alpha_value, brush_alpha_pressure;
1350 scene, ss, brush, &brush_size_pressure, &brush_alpha_value, &brush_alpha_pressure);
1363 if (use_vert_sel || use_face_sel) {
1373 LocalData &tls = all_tls.
local();
1376 tls.factors.resize(
verts.size());
1380 if (!select_vert.is_empty()) {
1384 tls.distances.resize(
verts.size());
1391 for (
const int i :
verts.index_range()) {
1392 const int vert =
verts[
i];
1393 if (factors[
i] == 0.0f) {
1397 const float angle_cos = use_normal ?
1398 dot_v3v3(sculpt_normal_frontface, vert_normals[vert]) :
1405 const float final_alpha = factors[
i] *
brush_strength * brush_alpha_pressure;
1447 if (use_vert_sel || use_face_sel) {
1461 LocalData &tls = all_tls.local();
1462 node_mask.slice(range).foreach_index([&](const int i) {
1463 const Span<int> verts = nodes[i].verts();
1464 tls.factors.resize(verts.size());
1465 const MutableSpan<float> factors = tls.factors;
1466 fill_factor_from_hide(hide_vert, verts, factors);
1467 filter_region_clip_factors(ss, vert_positions, verts, factors);
1468 if (!select_vert.is_empty()) {
1469 filter_factors_with_selection(select_vert, verts, factors);
1472 tls.distances.resize(verts.size());
1473 const MutableSpan<float> distances = tls.distances;
1474 calc_brush_distances(
1475 ss, vert_positions, verts, eBrushFalloffShape(brush.falloff_shape), distances);
1476 filter_distances_with_radius(cache.radius, distances, factors);
1477 calc_brush_strength_factors(cache, brush, distances, factors);
1479 for (const int i : verts.index_range()) {
1480 const int vert = verts[i];
1481 if (factors[i] == 0.0f) {
1484 const float angle_cos = use_normal ?
1485 dot_v3v3(sculpt_normal_frontface, vert_normals[vert]) :
1487 if (angle_cos <= 0.0f) {
1490 const MDeformVert &dv = wpi.dvert[vert];
1492 accum.value += wpaint_get_active_weight(dv, wpi);
1638 const bool is_mode_set = (ob.
mode & mode_flag) != 0;
1682 ot->name =
"Weight Paint Mode";
1683 ot->idname =
"PAINT_OT_weight_paint_toggle";
1684 ot->description =
"Toggle weight paint mode in 3D view";
1732 wpaint_do_paint(
C, ob, wp, wpd, wpi,
mesh, brush, symm, axis,
i,
angle);
1750 wpaint_do_paint(
C, ob, wp, wpd, wpi,
mesh, brush,
ePaintSymmetryFlags(0),
'X', 0, 0);
1764 for (
i = 1;
i <= symm;
i++) {
1772 wpaint_do_paint(
C, ob, wp, wpd, wpi,
mesh, brush, symm,
'X', 0, 0);
1776 wpaint_do_paint(
C, ob, wp, wpd, wpi,
mesh, brush, symm,
'Y', 0, 0);
1780 wpaint_do_paint(
C, ob, wp, wpd, wpi,
mesh, brush, symm,
'Z', 0, 0);
1813 if (wpd ==
nullptr) {
1831 wpi.
dvert =
mesh.deform_verts_for_write();
1963 ot->name =
"Weight Paint";
1964 ot->idname =
"PAINT_OT_weight_paint";
1965 ot->description =
"Paint a stroke in the current vertex group's weights";
1978 "override_location",
1980 "Override Location",
1981 "Override the given `location` array by recalculating object space positions from the "
1982 "provided `mouse_event` positions");
float BKE_brush_weight_get(const Scene *scene, const Brush *brush)
float BKE_brush_alpha_get(const Scene *scene, 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)
General operations, lookup, etc. for blender objects.
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
#define ME_USING_MIRROR_X_VERTEX_GROUPS(_me)
@ ME_EDIT_MIRROR_VERTEX_GROUPS
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)
void get_brush_alpha_data(const Scene &scene, const SculptSession &ss, const Brush &brush, float *r_brush_size_pressure, float *r_brush_alpha_value, float *r_brush_alpha_pressure)
bool use_normal(const VPaint &vp)
void mode_exit_generic(Object &ob, eObjectMode mode_flag)
void init_session_data(const ToolSettings &ts, Object &ob)
bool test_brush_angle_falloff(const Brush &brush, const NormalAnglePrecalc &normal_angle_precalc, const float angle_cos, float *brush_strength)
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 smooth_brush_toggle_off(const bContext *C, Paint *paint, StrokeCache *cache)
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)
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 last_stroke_update(Scene &scene, const float location[3])
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 weight_paint_poll(bContext *C)
bool ED_wpaint_ensure_data(bContext *C, ReportList *reports, enum eWPaintFlag flag, WPaintVGroupIndex *vgroup_index)
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 void do_wpaint_brush_smear(const Depsgraph &depsgraph, const Scene &scene, Object &ob, const Brush &brush, VPaint &vp, WPaintData &wpd, const WeightPaintInfo &wpi, Mesh &mesh, const IndexMask &node_mask)
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 void do_wpaint_brush_blur(const Depsgraph &depsgraph, const Scene &scene, Object &ob, const Brush &brush, VPaint &vp, WPaintData &wpd, const 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 void do_wpaint_brush_draw(const Depsgraph &depsgraph, const Scene &scene, Object &ob, const Brush &brush, VPaint &vp, WPaintData &wpd, const WeightPaintInfo &wpi, Mesh &mesh, const float strength, const IndexMask &node_mask)
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 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 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_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 UnifiedPaintSettings &ups, const PaintModeSettings &)
struct SculptSession * sculpt
struct ToolSettings * toolsettings
blender::ed::sculpt_paint::StrokeCache * cache
blender::Array< MDeformVert > dvert_prev
struct SculptSession::@370306015203351072222037331336123026254172011056::@312313020143064270273330131075310027202022322222 wpaint
struct SculptSession::@370306015203351072222037331336123026254172011056 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_)