101 return c.
r == 0.0f && c.
g == 0.0f && c.
b == 0.0f && c.
a == 0.0f;
106 return c.
r == 0 && c.
g == 0 && c.
b == 0 && c.
a == 0;
111 if constexpr (std::is_same_v<Color, ColorPaint4b>) {
121 if constexpr (std::is_same_v<Color, ColorPaint4b>) {
144 a->do_mask_normal = do_mask_normal;
145 if (do_mask_normal) {
146 a->angle_inner =
angle;
147 a->angle = (a->angle_inner + 90.0f) * 0.5f;
150 a->angle_inner = a->angle =
angle;
155 a->angle_range = a->angle - a->angle_inner;
157 if (a->angle_range <= 0.0f) {
158 a->do_mask_normal =
false;
161 a->angle__cos =
cosf(a->angle);
162 a->angle_inner__cos =
cosf(a->angle_inner);
167 if (angle_cos <= a->angle__cos) {
171 if (angle_cos < a->angle_inner__cos) {
172 *mask_p *= (a->angle -
acosf(angle_cos)) / a->angle_range;
180 const float angle_cos,
221 ss.
cache = MEM_new<StrokeCache>(__func__);
232 ob.
sculpt = MEM_new<SculptSession>(__func__);
267 initial_value.
flag = 1;
317 ob.
mode |= mode_flag;
367 ob.
mode &= ~mode_flag;
447 float view_dir[3] = {0.0f, 0.0f, 1.0f};
452 cache = MEM_new<StrokeCache>(__func__);
487 cache->
brush = brush;
558 float *r_brush_size_pressure,
559 float *r_brush_alpha_value,
560 float *r_brush_alpha_pressure)
590 CLOG_WARN(&
LOG,
"Switching to the blur (smooth) brush not possible, corresponding brush not");
664template<
typename Color,
typename Traits>
669 const typename Traits::ValueType alpha,
670 const typename Traits::BlendType brush_alpha_value)
672 using Value =
typename Traits::ValueType;
687 cp = (Value *)&color_blend;
688 ct = (Value *)&color_test;
689 co = (Value *)&color_orig;
691 for (a = 0; a < 4; a++) {
696 else if (cp[a] > co[a]) {
704 else if (cp[a] > ct[a]) {
714 cp = (Value *)&color_blend;
715 cc = (Value *)&color_curr;
741 const float co_ss_3d[3] = {co_ss[0], co_ss[1], 0.0f};
804 const bool is_mode_set = (ob.
mode & mode_flag) != 0;
843 ot->
name =
"Vertex Paint Mode";
844 ot->
idname =
"PAINT_OT_vertex_paint_toggle";
877template<
typename Func>
936 const AttrDomain domain,
940 std::unique_ptr<VPaintData> vpd = std::make_unique<VPaintData>();
943 vpd->domain = domain;
957 const GVArray attribute = *mesh.attributes().lookup(mesh.active_color_attribute, domain);
958 vpd->smear.color_prev =
GArray(attribute.type(), attribute.size());
959 attribute.materialize(vpd->smear.color_prev.data());
961 vpd->smear.color_curr = vpd->smear.color_prev;
965 if (vpd->is_texbrush) {
968 depsgraph, scene, ob, vpd->vert_positions, vpd->vert_normals);
973 if (vpd->prev_colors.is_empty()) {
974 const GVArray attribute = *mesh.attributes().lookup(mesh.active_color_attribute);
975 vpd->prev_colors =
GArray(attribute.type(), attribute.size());
976 attribute.type().value_initialize_n(vpd->prev_colors.data(), vpd->prev_colors.size());
980 vpd->prev_colors = {};
999 if (mesh ==
nullptr || mesh->faces_num == 0) {
1005 const std::optional<bke::AttributeMetaData> meta_data = *mesh->attributes().lookup_meta_data(
1006 mesh->active_color_attribute);
1012 C, op, scene,
depsgraph, vp, ob, *mesh, meta_data->domain, meta_data->data_type, brush);
1030 for (
const int i :
verts.index_range()) {
1031 if (!select_vert[
verts[i]]) {
1053 float brush_size_pressure, brush_alpha_value, brush_alpha_pressure;
1055 scene, ss, brush, &brush_size_pressure, &brush_alpha_value, &brush_alpha_pressure);
1068 const Span<int> corner_verts = mesh.corner_verts();
1072 const VArraySpan hide_vert = *attributes.lookup<
bool>(
".hide_vert", bke::AttrDomain::Point);
1075 select_vert = *attributes.lookup<
bool>(
".select_vert", bke::AttrDomain::Point);
1079 select_poly = *attributes.lookup<
bool>(
".select_poly", bke::AttrDomain::Face);
1093 if (!select_vert.is_empty()) {
1104 for (
const int i :
verts.index_range()) {
1105 const int vert =
verts[i];
1106 if (factors[i] == 0.0f) {
1111 const float angle_cos = use_normal ?
dot_v3v3(sculpt_normal_frontface, vert_normals[vert]) :
1119 const float brush_fade = factors[i];
1122 using T = decltype(dummy);
1124 std::conditional_t<std::is_same_v<T, ColorGeometry4f>, ColorPaint4f, ColorPaint4b>;
1125 using Traits = blender::color::Traits<Color>;
1126 using Blend = typename Traits::BlendType;
1127 MutableSpan<Color> previous_color = g_previous_color.typed<T>().template cast<Color>();
1128 MutableSpan<Color> colors = attribute.typed<T>().template cast<Color>();
1130 Color color_final(0, 0, 0, 0);
1132 int total_hit_loops = 0;
1133 Blend blend[4] = {0};
1135 for (
const int face : vert_to_face[vert]) {
1136 if (!select_poly.
is_empty() && !select_poly[face]) {
1139 total_hit_loops += faces[face].size();
1140 for (
const int corner : faces[face]) {
1141 const Color &
col = colors[corner];
1151 if (total_hit_loops == 0) {
1156 Color *
col = &color_final;
1158 color_final.r = Traits::round(
sqrtf(Traits::divide_round(
blend[0], total_hit_loops)));
1159 color_final.g = Traits::round(
sqrtf(Traits::divide_round(
blend[1], total_hit_loops)));
1160 color_final.b = Traits::round(
sqrtf(Traits::divide_round(
blend[2], total_hit_loops)));
1161 color_final.a = Traits::round(
sqrtf(Traits::divide_round(
blend[3], total_hit_loops)));
1165 for (
const int face : vert_to_face[vert]) {
1167 faces[face], corner_verts, vert);
1168 if (!select_poly.
is_empty() && !select_poly[face]) {
1171 Color color_orig(0, 0, 0, 0);
1173 if (!previous_color.is_empty()) {
1175 if (
isZero(previous_color[corner])) {
1176 previous_color[corner] = colors[corner];
1178 color_orig = previous_color[corner];
1180 const float final_alpha = Traits::range * brush_fade *
brush_strength *
1181 brush_alpha_pressure;
1185 vp, colors[corner], color_orig, *
col, final_alpha, Traits::range *
brush_strength);
1208 float brush_size_pressure, brush_alpha_value, brush_alpha_pressure;
1210 scene, ss, brush, &brush_size_pressure, &brush_alpha_value, &brush_alpha_pressure);
1223 const Span<int> corner_verts = mesh.corner_verts();
1227 const VArraySpan hide_vert = *attributes.lookup<
bool>(
".hide_vert", bke::AttrDomain::Point);
1230 select_vert = *attributes.lookup<
bool>(
".select_vert", bke::AttrDomain::Point);
1234 select_poly = *attributes.lookup<
bool>(
".select_poly", bke::AttrDomain::Face);
1248 if (!select_vert.is_empty()) {
1259 for (
const int i :
verts.index_range()) {
1260 const int vert =
verts[i];
1261 if (factors[i] == 0.0f) {
1266 const float angle_cos = use_normal ?
dot_v3v3(sculpt_normal_frontface, vert_normals[vert]) :
1273 const float brush_fade = factors[i];
1277 using T = decltype(dummy);
1279 std::conditional_t<std::is_same_v<T, ColorGeometry4f>, ColorPaint4f, ColorPaint4b>;
1280 using Traits = blender::color::Traits<Color>;
1281 using Blend = typename Traits::BlendType;
1282 MutableSpan<Color> previous_color = g_previous_color.typed<T>().template cast<Color>();
1283 MutableSpan<Color> colors = attribute.typed<T>().template cast<Color>();
1284 Color color_final(0, 0, 0, 0);
1286 int total_hit_loops = 0;
1287 Blend blend[4] = {0};
1289 for (
const int face : vert_to_face[vert]) {
1290 if (!select_poly.
is_empty() && !select_poly[face]) {
1293 total_hit_loops += faces[face].size();
1294 for (
const int vert : corner_verts.
slice(faces[face])) {
1295 const Color &
col = colors[vert];
1305 if (total_hit_loops == 0) {
1309 color_final.r = Traits::round(
sqrtf(Traits::divide_round(
blend[0], total_hit_loops)));
1310 color_final.g = Traits::round(
sqrtf(Traits::divide_round(
blend[1], total_hit_loops)));
1311 color_final.b = Traits::round(
sqrtf(Traits::divide_round(
blend[2], total_hit_loops)));
1312 color_final.a = Traits::round(
sqrtf(Traits::divide_round(
blend[3], total_hit_loops)));
1314 Color color_orig(0, 0, 0, 0);
1316 if (!previous_color.is_empty()) {
1318 if (
isZero(previous_color[vert])) {
1319 previous_color[vert] = colors[vert];
1321 color_orig = previous_color[vert];
1323 const float final_alpha = Traits::range * brush_fade *
brush_strength *
1324 brush_alpha_pressure;
1360 float brush_size_pressure, brush_alpha_value, brush_alpha_pressure;
1363 scene, ss, brush, &brush_size_pressure, &brush_alpha_value, &brush_alpha_pressure);
1381 const Span<int> corner_verts = mesh.corner_verts();
1385 const VArraySpan hide_vert = *attributes.lookup<
bool>(
".hide_vert", bke::AttrDomain::Point);
1388 select_vert = *attributes.lookup<
bool>(
".select_vert", bke::AttrDomain::Point);
1392 select_poly = *attributes.lookup<
bool>(
".select_poly", bke::AttrDomain::Face);
1406 if (!select_vert.is_empty()) {
1417 for (
const int i :
verts.index_range()) {
1418 const int vert =
verts[i];
1419 if (factors[i] == 0.0f) {
1426 const float angle_cos = use_normal ?
dot_v3v3(sculpt_normal_frontface, vert_normals[vert]) :
1433 const float brush_fade = factors[i];
1435 bool do_color =
false;
1438 float stroke_dot_max = 0.0f;
1443 using T = decltype(dummy);
1445 std::conditional_t<std::is_same_v<T, ColorGeometry4f>, ColorPaint4f, ColorPaint4b>;
1446 using Traits = blender::color::Traits<Color>;
1447 MutableSpan<Color> color_curr = g_color_curr.typed<T>().template cast<Color>();
1448 MutableSpan<Color> color_prev_smear = g_color_prev_smear.typed<T>().template cast<Color>();
1449 MutableSpan<Color> color_prev = g_color_prev.typed<T>().template cast<Color>();
1450 MutableSpan<Color> colors = attribute.typed<T>().template cast<Color>();
1452 Color color_final(0, 0, 0, 0);
1454 for (const int face : vert_to_face[vert]) {
1455 if (!select_poly.is_empty() && !select_poly[face]) {
1458 for (const int corner : faces[face]) {
1459 const int v_other_index = corner_verts[corner];
1460 if (v_other_index == vert) {
1467 sub_v3_v3v3(other_dir, vert_positions[vert], vert_positions[v_other_index]);
1468 project_plane_v3_v3v3(other_dir, other_dir, cache.view_normal_symm);
1470 normalize_v3(other_dir);
1472 const float stroke_dot = dot_v3v3(other_dir, brush_dir);
1475 if (vpd.domain == AttrDomain::Point) {
1476 elem_index = v_other_index;
1479 elem_index = corner;
1482 if (stroke_dot > stroke_dot_max) {
1483 stroke_dot_max = stroke_dot;
1484 color_final = color_prev_smear[elem_index];
1494 const float final_alpha = Traits::range * brush_fade *
brush_strength *
1495 brush_alpha_pressure;
1499 for (
const int face : vert_to_face[vert]) {
1502 if (vpd.
domain == AttrDomain::Point) {
1508 if (!select_poly.
is_empty() && !select_poly[face]) {
1513 Color color_orig(0, 0, 0, 0);
1515 if (!color_prev.is_empty()) {
1517 if (
isZero(color_prev[elem_index])) {
1518 color_prev[elem_index] = colors[elem_index];
1520 color_orig = color_prev[elem_index];
1531 color_curr[elem_index] = colors[elem_index];
1542 const GSpan attribute,
1555 const Span<int> corner_verts = mesh.corner_verts();
1558 const VArraySpan hide_vert = *attributes.lookup<
bool>(
".hide_vert", bke::AttrDomain::Point);
1561 select_vert = *attributes.lookup<
bool>(
".select_vert", bke::AttrDomain::Point);
1570 using T = decltype(dummy);
1572 std::conditional_t<std::is_same_v<T, ColorGeometry4f>, ColorPaint4f, ColorPaint4b>;
1573 using Traits = blender::color::Traits<Color>;
1574 using Blend = typename Traits::BlendType;
1575 const Span<Color> colors = attribute.typed<T>().template cast<Color>();
1577 Array<VPaintAverageAccum<Blend>> accum(nodes.size());
1578 node_mask.foreach_index(GrainSize(1), [&](const int i) {
1579 LocalData &tls = all_tls.local();
1580 VPaintAverageAccum<Blend> &accum2 = accum[i];
1582 memset(accum2.value, 0, sizeof(accum2.value));
1584 const Span<int> verts = nodes[i].verts();
1585 tls.factors.resize(verts.size());
1586 const MutableSpan<float> factors = tls.factors;
1587 fill_factor_from_hide(hide_vert, verts, factors);
1588 if (!select_vert.is_empty()) {
1589 filter_factors_with_selection(select_vert, verts, factors);
1592 tls.distances.resize(verts.size());
1593 const MutableSpan<float> distances = tls.distances;
1594 calc_brush_distances(
1595 ss, vert_positions, verts, eBrushFalloffShape(brush.falloff_shape), distances);
1596 filter_distances_with_radius(cache.radius, distances, factors);
1597 calc_brush_strength_factors(cache, brush, distances, factors);
1599 for (const int i : verts.index_range()) {
1600 const int vert = verts[i];
1601 if (factors[i] == 0.0f) {
1605 accum2.len += vert_to_face[vert].size();
1607 for (const int face : vert_to_face[vert]) {
1609 if (vpd.domain == AttrDomain::Corner) {
1610 elem_index = bke::mesh::face_find_corner_from_vert(faces[face], corner_verts, vert);
1617 const Color &col = colors[elem_index];
1618 accum2.value[0] += col.r * col.r;
1619 accum2.value[1] += col.g * col.g;
1620 accum2.value[2] += col.b * col.b;
1625 Blend accum_len = 0;
1626 Blend accum_value[3] = {0};
1627 Color
blend(0, 0, 0, 0);
1629 for (
int i = 0; i < nodes.size(); i++) {
1630 accum_len += accum[i].len;
1631 accum_value[0] += accum[i].value[0];
1632 accum_value[1] += accum[i].value[1];
1633 accum_value[2] += accum[i].value[2];
1635 if (accum_len != 0) {
1636 blend.r = Traits::round(
sqrtf(Traits::divide_round(accum_value[0], accum_len)));
1637 blend.g = Traits::round(
sqrtf(Traits::divide_round(accum_value[1], accum_len)));
1638 blend.b = Traits::round(
sqrtf(Traits::divide_round(accum_value[2], accum_len)));
1639 blend.a = Traits::range;
1646template<
typename Color>
1649 const float v_co[3],
1677 float brush_size_pressure, brush_alpha_value, brush_alpha_pressure;
1679 scene, ss, brush, &brush_size_pressure, &brush_alpha_value, &brush_alpha_pressure);
1692 const Span<int> corner_verts = mesh.corner_verts();
1696 const VArraySpan hide_vert = *attributes.lookup<
bool>(
".hide_vert", bke::AttrDomain::Point);
1699 select_vert = *attributes.lookup<
bool>(
".select_vert", bke::AttrDomain::Point);
1703 select_poly = *attributes.lookup<
bool>(
".select_poly", bke::AttrDomain::Face);
1717 if (!select_vert.is_empty()) {
1728 for (
const int i :
verts.index_range()) {
1729 const int vert =
verts[i];
1730 if (factors[i] == 0.0f) {
1737 const float angle_cos = use_normal ?
dot_v3v3(sculpt_normal_frontface, vert_normals[vert]) :
1744 const float brush_fade = factors[i];
1747 using T = decltype(dummy);
1749 std::conditional_t<std::is_same_v<T, ColorGeometry4f>, ColorPaint4f, ColorPaint4b>;
1750 using Traits = blender::color::Traits<Color>;
1751 MutableSpan<Color> colors = attribute.typed<T>().template cast<Color>();
1752 MutableSpan<Color> previous_color = g_previous_color.typed<T>().template cast<Color>();
1753 Color color_final = fromFloat<Color>(vpd.paintcol);
1756 float tex_alpha = 1.0;
1757 if (vpd.is_texbrush) {
1765 float3 position = vpd.vert_positions[vert];
1766 if (cache.radial_symmetry_pass) {
1767 position = blender::math::transform_point(cache.symm_rot_mat_inv, position);
1769 const float3 symm_point = blender::ed::sculpt_paint::symmetry_flip(
1770 position, cache.mirror_symmetry_pass);
1772 tex_alpha = paint_and_tex_color_alpha<Color>(vp, vpd, symm_point, &color_final);
1775 Color color_orig(0, 0, 0, 0);
1777 if (vpd.
domain == AttrDomain::Point) {
1778 if (!previous_color.is_empty()) {
1779 if (isZero(previous_color[vert])) {
1780 previous_color[vert] = colors[vert];
1782 color_orig = previous_color[vert];
1784 const float final_alpha = Traits::frange * brush_fade *
brush_strength * tex_alpha *
1785 brush_alpha_pressure;
1796 for (
const int face : vert_to_face[vert]) {
1798 faces[face], corner_verts, vert);
1799 if (!select_poly.
is_empty() && !select_poly[face]) {
1802 Color color_orig =
Color(0, 0, 0, 0);
1804 if (!previous_color.is_empty()) {
1805 if (
isZero(previous_color[corner])) {
1806 previous_color[corner] = colors[corner];
1808 color_orig = previous_color[corner];
1810 const float final_alpha = Traits::frange * brush_fade *
brush_strength * tex_alpha *
1811 brush_alpha_pressure;
1835 if (vpd.
domain == AttrDomain::Point) {
1860 vpaint_do_draw(C, vp, vpd, ob, mesh, nodes, node_mask, attribute);
1863 vpaint_do_draw(C, vp, vpd, ob, mesh, nodes, node_mask, attribute);
1866 vpaint_do_blur(C, vp, vpd, ob, mesh, nodes, node_mask, attribute);
1894 mesh.active_color_attribute);
1919 for (
int i = 1; i < vp.
radial_symm[axis -
'X']; i++) {
1942 vpaint_do_paint(C, vp, vpd, ob, mesh, brush, initial_symm,
'X', 0, 0);
1951 for (i = 1; i <= symm; i++) {
1952 if (symm & i && (symm != 5 || i != 3) && (symm != 6 || !
ELEM(i, 3, 5))) {
2106 ot->
name =
"Vertex Paint";
2107 ot->
idname =
"PAINT_OT_vertex_paint";
2108 ot->
description =
"Paint a stroke in the active color attribute layer";
2132 const AttrDomain domain,
2133 const int cd_offset,
2134 const bool use_vert_sel)
2142 if (domain == AttrDomain::Corner) {
2145 else if (domain == AttrDomain::Point) {
2156 const AttrDomain domain,
2158 const bool use_vert_sel,
2159 const bool use_face_sel,
2160 const bool affect_alpha)
2173 const Span<int> corner_verts = mesh.corner_verts();
2175 for (
const int i : faces.index_range()) {
2176 if (!select_poly.
is_empty() && !select_poly[i]) {
2179 for (
const int corner : faces[i]) {
2180 const int vert = corner_verts[corner];
2181 if (!select_vert.
is_empty() && !select_vert[vert]) {
2184 const int data_index = domain == AttrDomain::Corner ? corner : vert;
2185 data[data_index].r = value.r;
2186 data[data_index].g = value.g;
2187 data[data_index].b = value.b;
2189 data[data_index].a = value.a;
2200 const bool use_vert_sel,
2201 const bool use_face_sel,
2202 const bool affect_alpha)
2204 if (
BMEditMesh *em = mesh.runtime->edit_mesh.get()) {
2206 const std::string name = attribute_name;
2212 *
bm, color, domain, layer->offset, use_vert_sel);
2216 *
bm, color.encode(), domain, layer->offset, use_vert_sel);
2248 bool only_selected =
true,
2249 bool affect_alpha =
true)
2259 *mesh, fill_color, mesh->active_color_attribute, use_vert_sel, use_face_sel, affect_alpha);
2313 ot->
name =
"Set Vertex Colors";
2314 ot->
idname =
"PAINT_OT_vertex_color_set";
2315 ot->
description =
"Fill the active vertex color layer with the current paint color";
2326 "Set color completely opaque instead of reusing existing alpha");
const struct CustomDataLayer * BKE_id_attributes_color_find(const struct ID *id, const char *name)
bool BKE_color_attribute_supported(const struct Mesh &mesh, const blender::StringRef name)
blender::bke::AttrDomain BKE_attribute_domain(const AttributeOwner &owner, const struct CustomDataLayer *layer)
const MTex * BKE_brush_mask_texture_get(const Brush *brush, const eObjectMode object_mode)
bool BKE_brush_use_alpha_pressure(const Brush *brush)
int BKE_brush_size_get(const Scene *scene, const Brush *brush)
void BKE_brush_unprojected_radius_set(Scene *scene, Brush *brush, float unprojected_radius)
void BKE_brush_size_set(Scene *scene, Brush *brush, int size)
float BKE_brush_sample_tex_3d(const Scene *scene, const Brush *br, const MTex *mtex, const float point[3], float rgba[4], int thread, ImagePool *pool)
const float * BKE_brush_secondary_color_get(const Scene *scene, const Paint *paint, const Brush *brush)
bool BKE_brush_use_size_pressure(const Brush *brush)
float BKE_brush_alpha_get(const Scene *scene, const Brush *brush)
const float * BKE_brush_color_get(const Scene *scene, 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)
void BKE_mesh_tessface_clear(Mesh *mesh)
Mesh * BKE_mesh_from_object(Object *ob)
@ BKE_MESH_BATCH_DIRTY_ALL
General operations, lookup, etc. for blender objects.
void BKE_object_free_derived_caches(Object *ob)
bool BKE_paint_brush_set_essentials(Main *bmain, Paint *paint, const char *name)
bool BKE_paint_brush_set(Paint *paint, Brush *brush)
void BKE_sculptsession_free(Object *ob)
const uchar PAINT_CURSOR_WEIGHT_PAINT[3]
const Brush * BKE_paint_brush_for_read(const Paint *paint)
Paint * BKE_paint_get_active_from_paintmode(Scene *sce, PaintMode mode)
void BKE_paint_init(Main *bmain, Scene *sce, PaintMode mode, const uchar col[3], bool ensure_brushes=true)
void BKE_sculpt_update_object_for_edit(Depsgraph *depsgraph, Object *ob_orig, bool is_paint_tool)
bool BKE_paint_ensure(ToolSettings *ts, Paint **r_paint)
Brush * BKE_paint_brush(Paint *paint)
void BKE_sculpt_toolsettings_data_ensure(Main *bmain, Scene *scene)
const uchar PAINT_CURSOR_VERTEX_PAINT[3]
void BKE_paint_brushes_validate(Main *bmain, Paint *paint)
Generic array manipulation API.
#define BLI_assert_unreachable()
struct DistRayAABB_Precalc dist_squared_ray_to_aabb_v3_precalc(const float ray_origin[3], const float ray_direction[3])
void mul_m3_v3(const float M[3][3], float r[3])
void mul_m4_m4m4(float R[4][4], const float A[4][4], const float B[4][4])
void copy_m3_m4(float m1[3][3], const float m2[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])
bool invert_m4_m4(float inverse[4][4], const float mat[4][4])
MINLINE void mul_v3_v3(float r[3], const float a[3])
MINLINE void sub_v3_v3v3(float r[3], const float a[3], const float b[3])
MINLINE void copy_v2_v2(float r[2], const float a[2])
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 void zero_v4(float r[4])
MINLINE float normalize_v3_v3(float r[3], const float a[3])
MINLINE void zero_v2(float r[2])
MINLINE void add_v3_v3(float r[3], const float a[3])
MINLINE float normalize_v3(float n[3])
#define CLOG_WARN(clg_ref,...)
void DEG_id_tag_update(ID *id, unsigned int flags)
#define ID_IS_EDITABLE(_id)
@ WPAINT_BRUSH_TYPE_SMEAR
@ BRUSH_FRONTFACE_FALLOFF
@ VPAINT_BRUSH_TYPE_AVERAGE
@ VPAINT_BRUSH_TYPE_SMEAR
@ PAINT_FALLOFF_SHAPE_SPHERE
Object is a sort of wrapper for general info.
#define OPERATOR_RETVAL_CHECK(ret)
void ED_paint_cursor_start(Paint *paint, bool(*poll)(bContext *C))
bool ED_mesh_color_ensure(Mesh *mesh, const char *name)
void ED_mesh_mirror_topo_table_end(Object *ob)
void ED_mesh_mirror_spatial_table_end(Object *ob)
void ED_region_tag_redraw(ARegion *region)
@ V3D_PROJ_TEST_CLIP_NEAR
eV3DProjStatus ED_view3d_project_float_object(const ARegion *region, const float co[3], float r_co[2], eV3DProjTest flag)
void ED_view3d_init_mats_rv3d(const Object *ob, RegionView3D *rv3d)
ViewContext ED_view3d_viewcontext_init(bContext *C, Depsgraph *depsgraph)
blender::float4x4 ED_view3d_ob_project_mat_get(const RegionView3D *rv3d, const Object *ob)
static double angle(const Eigen::Vector3d &v1, const Eigen::Vector3d &v2)
BLI_INLINE void IMB_colormanagement_srgb_to_scene_linear_v3(float scene_linear[3], const float srgb[3])
Read Guarded memory(de)allocation.
#define BM_ELEM_CD_GET_VOID_P(ele, offset)
#define BM_elem_flag_test(ele, hflag)
#define BM_ITER_MESH(ele, iter, bm, itype)
ATTR_WARN_UNUSED_RESULT BMesh * bm
ATTR_WARN_UNUSED_RESULT const BMLoop * l
SIMD_FORCE_INLINE bool isZero() const
static AttributeOwner from_id(ID *id)
ColorSceneLinearByteEncoded4b< Alpha > encode() const
constexpr int64_t size() const
constexpr Span slice(int64_t start, int64_t size) const
constexpr bool is_empty() const
void resize(const int64_t new_size)
void tag_attribute_changed(const IndexMask &node_mask, StringRef attribute_name)
Span< NodeT > nodes() const
void foreach_index(Fn &&fn) const
const Depsgraph * depsgraph
draw_view in_light_buf[] float
void *(* MEM_callocN)(size_t len, const char *str)
int face_find_corner_from_vert(const IndexRange face, const Span< int > corner_verts, const int vert)
pbvh::Tree * pbvh_get(Object &object)
IndexMask search_nodes(const Tree &pbvh, IndexMaskMemory &memory, FunctionRef< bool(const Node &)> filter_fn)
void update_bounds(const Depsgraph &depsgraph, const Object &object, Tree &pbvh)
IndexMask all_leaf_nodes(const Tree &pbvh, IndexMaskMemory &memory)
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 mesh_select_vert_flush(Mesh &mesh)
void mesh_select_face_flush(Mesh &mesh)
BLI_INLINE Color BLI_mix_colors(const IMB_BlendMode tool, const Color a, const Color b, const typename Traits::BlendType alpha)
bool vgroup_sync_from_pose(Object *ob)
bool mode_compat_set(bContext *C, Object *ob, eObjectMode mode, ReportList *reports)
void push_end(Object &ob)
void push_nodes(const Depsgraph &depsgraph, Object &object, const IndexMask &node_mask, const Type type)
void push_begin_ex(const Scene &, Object &ob, const char *name)
void push_begin(const Scene &scene, Object &ob, const wmOperator *op)
float view_angle_limits_apply_falloff(const NormalAnglePrecalc *a, float angle_cos, float *mask_p)
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 smooth_brush_toggle_on(const bContext *C, Paint *paint, StrokeCache *cache)
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 init_session(Main &bmain, Depsgraph &depsgraph, Scene &scene, Object &ob, eObjectMode object_mode)
void last_stroke_update(Scene &scene, const float location[3])
int paint_stroke_exec(bContext *C, wmOperator *op, PaintStroke *stroke)
bool node_in_sphere(const bke::pbvh::Node &node, const float3 &location, const float radius_sq, const bool original)
bool node_in_cylinder(const DistRayAABB_Precalc &ray_dist_precalc, const bke::pbvh::Node &node, const float radius_sq, const bool original)
void calc_brush_strength_factors(const StrokeCache &cache, const Brush &brush, Span< float > distances, MutableSpan< float > factors)
void filter_distances_with_radius(float radius, Span< float > distances, MutableSpan< float > factors)
static bool fill_active_color(Object &ob, ColorPaint4f fill_color, bool only_selected=true, bool affect_alpha=true)
static void fill_mesh_face_or_corner_attribute(Mesh &mesh, const T &value, const AttrDomain domain, const MutableSpan< T > data, const bool use_vert_sel, const bool use_face_sel, const bool affect_alpha)
static void fill_mesh_color(Mesh &mesh, const ColorPaint4f &color, const StringRef attribute_name, const bool use_vert_sel, const bool use_face_sel, const bool affect_alpha)
void calc_brush_distances(const SculptSession &ss, Span< float3 > vert_positions, Span< int > vert_indices, eBrushFalloffShape falloff_shape, MutableSpan< float > r_distances)
void paint_stroke_cancel(bContext *C, wmOperator *op, PaintStroke *stroke)
bool paint_supports_dynamic_size(const Brush &br, PaintMode mode)
void ensure_valid_pivot(const Object &ob, Scene &scene)
std::optional< float3 > calc_area_normal(const Depsgraph &depsgraph, const Brush &brush, const Object &ob, const IndexMask &node_mask)
ViewContext * paint_stroke_view_context(PaintStroke *stroke)
static void fill_bm_face_or_corner_attribute(BMesh &bm, const T &value, const AttrDomain domain, const int cd_offset, const bool use_vert_sel)
int paint_stroke_modal(bContext *C, wmOperator *op, const wmEvent *event, PaintStroke **stroke_p)
void * paint_stroke_mode_data(PaintStroke *stroke)
bool object_active_color_fill(Object &ob, const float fill_color[4], bool only_selected)
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)
ColorSceneLinear4f< eAlpha::Straight > ColorPaint4f
ColorSceneLinear4f< eAlpha::Premultiplied > ColorGeometry4f
VecBase< float, 3 > float3
ColorSceneLinearByteEncoded4b< eAlpha::Premultiplied > ColorGeometry4b
void paint_cursor_delete_textures()
VertProjHandle * ED_vpaint_proj_handle_create(Depsgraph &depsgraph, Scene &scene, Object &ob, blender::Span< blender::float3 > &r_vert_positions, blender::Span< blender::float3 > &r_vert_normals)
bool weight_paint_poll(bContext *C)
float paint_calc_object_space_radius(const ViewContext &vc, const blender::float3 ¢er, float pixel_radius)
void ED_vpaint_proj_handle_free(VertProjHandle *vp_handle)
void paint_stroke_operator_properties(wmOperatorType *ot)
bool vertex_paint_poll(bContext *C)
static void to_static_color_type(const eCustomDataType type, const Func &func)
static float paint_and_tex_color_alpha(const VPaint &vp, VPaintData &vpd, const float v_co[3], Color *r_color)
void PAINT_OT_vertex_color_set(wmOperatorType *ot)
static void calculate_average_color(VPaintData &vpd, Object &ob, Mesh &mesh, const Brush &brush, const GSpan attribute, const Span< bke::pbvh::MeshNode > nodes, const IndexMask &node_mask)
static int vertex_color_set_exec(bContext *C, wmOperator *op)
static bool vpaint_stroke_test_start(bContext *C, wmOperator *op, const float mouse[2])
void PAINT_OT_vertex_paint(wmOperatorType *ot)
static int vpaint_mode_toggle_exec(bContext *C, wmOperator *op)
static int vpaint_invoke(bContext *C, wmOperator *op, const wmEvent *event)
static bool vertex_paint_poll_ex(bContext *C, bool check_tool)
static void do_vpaint_brush_blur_loops(const bContext *C, const VPaint &vp, VPaintData &vpd, Object &ob, Mesh &mesh, const Span< bke::pbvh::MeshNode > nodes, const IndexMask &node_mask, GMutableSpan attribute)
static void filter_factors_with_selection(const Span< bool > select_vert, const Span< int > verts, const MutableSpan< float > factors)
static void vpaint_stroke_done(const bContext *C, PaintStroke *stroke)
static void do_vpaint_brush_blur_verts(const bContext *C, const VPaint &vp, VPaintData &vpd, Object &ob, Mesh &mesh, const Span< bke::pbvh::MeshNode > nodes, const IndexMask &node_mask, GMutableSpan attribute)
static Color vpaint_blend(const VPaint &vp, Color color_curr, Color color_orig, Color color_paint, const typename Traits::ValueType alpha, const typename Traits::BlendType brush_alpha_value)
static int vpaint_exec(bContext *C, wmOperator *op)
static ColorPaint4f vpaint_get_current_col(Scene &scene, VPaint &vp, bool secondary)
bool vertex_paint_poll_ignore_tool(bContext *C)
void ED_object_vpaintmode_enter(bContext *C, Depsgraph &depsgraph)
static ColorPaint4f toFloat(const Color &c)
static void vpaint_do_blur(const bContext *C, const VPaint &vp, VPaintData &vpd, Object &ob, Mesh &mesh, const Span< bke::pbvh::MeshNode > nodes, const IndexMask &node_mask, GMutableSpan attribute)
static void vpaint_do_symmetrical_brush_actions(bContext *C, const VPaint &vp, VPaintData &vpd, Object &ob)
void ED_object_vpaintmode_exit(bContext *C)
static void vpaint_do_draw(const bContext *C, const VPaint &vp, VPaintData &vpd, Object &ob, Mesh &mesh, const Span< bke::pbvh::MeshNode > nodes, const IndexMask &node_mask, GMutableSpan attribute)
bool vertex_paint_mode_poll(bContext *C)
void ED_object_vpaintmode_exit_ex(Object &ob)
static std::unique_ptr< VPaintData > vpaint_init_vpaint(bContext *C, wmOperator *op, Scene &scene, Depsgraph &depsgraph, VPaint &vp, Object &ob, Mesh &mesh, const AttrDomain domain, const eCustomDataType type, const Brush &brush)
void ED_object_vpaintmode_enter_ex(Main &bmain, Depsgraph &depsgraph, Scene &scene, Object &ob)
static void do_vpaint_brush_smear(const bContext *C, const VPaint &vp, VPaintData &vpd, Object &ob, Mesh &mesh, const Span< bke::pbvh::MeshNode > nodes, const IndexMask &node_mask, GMutableSpan attribute)
static void vertex_paint_init_stroke(Depsgraph &depsgraph, Object &ob)
static void vpaint_do_radial_symmetry(bContext *C, const VPaint &vp, VPaintData &vpd, Object &ob, Mesh &mesh, const Brush &brush, const ePaintSymmetryFlags symm, const int axis)
static void vpaint_paint_leaves(bContext *C, const VPaint &vp, VPaintData &vpd, Object &ob, Mesh &mesh, GMutableSpan attribute, const Span< bke::pbvh::MeshNode > nodes, const IndexMask &node_mask)
static Color fromFloat(const ColorPaint4f &c)
void PAINT_OT_vertex_paint_toggle(wmOperatorType *ot)
static int vpaint_modal(bContext *C, wmOperator *op, const wmEvent *event)
static void vpaint_stroke_update_step(bContext *C, wmOperator *, PaintStroke *stroke, PointerRNA *itemptr)
static void vpaint_do_paint(bContext *C, const VPaint &vp, VPaintData &vpd, Object &ob, Mesh &mesh, const Brush &brush, const ePaintSymmetryFlags symm, const int axis, const int i, const float angle)
static void vpaint_cancel(bContext *C, wmOperator *op)
bool vertex_paint_poll(bContext *C)
static void paint_and_tex_color_alpha_intern(const VPaint &vp, const ViewContext *vc, const float co[3], float r_rgba[4])
void RNA_float_get_array(PointerRNA *ptr, const char *name, float *values)
float RNA_float_get(PointerRNA *ptr, const char *name)
bool RNA_boolean_get(PointerRNA *ptr, const char *name)
int RNA_enum_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)
ePaintSymmetryFlags SCULPT_mesh_symmetry_xyz_get(const Object &object)
bool SCULPT_stroke_get_location(bContext *C, float out[3], const float mval[2], bool force_original)
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 CurveMapping * curve
ObjectRuntimeHandle * runtime
struct SculptSession * sculpt
struct Paint_Runtime runtime
blender::ed::sculpt_paint::StrokeCache * cache
blender::Array< MDeformVert > dvert_prev
struct SculptSession::@49 mode
struct SculptSession::@49::@50 wpaint
float average_stroke_accum[3]
int average_stroke_counter
Span< float3 > vert_positions
Span< float3 > vert_normals
VertProjHandle * vp_handle
struct VPaintData::@471 smear
NormalAnglePrecalc normal_angle_precalc
Vector< float > distances
float3 sculpt_normal_symm
float3 last_location_symm
ePaintSymmetryFlags mirror_symmetry_pass
Brush * saved_active_brush
bool(* poll)(bContext *C) ATTR_WARN_UNUSED_RESULT
int(* modal)(bContext *C, wmOperator *op, const wmEvent *event) ATTR_WARN_UNUSED_RESULT
int(* invoke)(bContext *C, wmOperator *op, const wmEvent *event) ATTR_WARN_UNUSED_RESULT
int(* exec)(bContext *C, wmOperator *op) ATTR_WARN_UNUSED_RESULT
void(* cancel)(bContext *C, wmOperator *op)
struct ReportList * reports
struct wmOperatorType * type
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_)