Refactor: Paint: Migrate runtime data out of UnifiedPaintSettings

This commit moves 23 total existing runtime-only properties from the
`UnifiedPaintSettings` struct into the `PaintRuntime` BKE struct. This
shrinks the amount of persisted data by 224 bytes per paint mode per
scene.

In doing this conversion, fields that were previously `char` booleans
have been converted to `bool` types, and C++ math vector types have been
used where appropriate as well.

Some of these attributes may move again in the future to better
distinguish stroke level data from mode level data.

Pull Request: https://projects.blender.org/blender/blender/pulls/141366
This commit is contained in:
Sean Kim
2025-07-18 23:18:27 +02:00
committed by Sean Kim
parent 3816c665a5
commit fef8c23e9e
21 changed files with 357 additions and 351 deletions

View File

@@ -94,7 +94,7 @@ void BKE_brush_jitter_pos(const Paint &paint,
const Brush &brush,
const float pos[2],
float jitterpos[2]);
void BKE_brush_randomize_texture_coords(UnifiedPaintSettings *ups, bool mask);
void BKE_brush_randomize_texture_coords(Paint *paint, bool mask);
/* Brush curve. */

View File

@@ -319,14 +319,12 @@ void BKE_paint_face_set_overlay_color_get(int face_set, int seed, uchar r_color[
* gets a different starting point in the perlin noise. */
blender::float3 seed_hsv_jitter();
bool paint_calculate_rake_rotation(UnifiedPaintSettings &ups,
bool paint_calculate_rake_rotation(Paint &paint,
const Brush &brush,
const float mouse_pos[2],
PaintMode paint_mode,
bool stroke_has_started);
void paint_update_brush_rake_rotation(UnifiedPaintSettings &ups,
const Brush &brush,
float rotation);
void paint_update_brush_rake_rotation(Paint &paint, const Brush &brush, float rotation);
void BKE_paint_stroke_get_average(const Paint *paint, const Object *ob, float stroke[3]);

View File

@@ -4,6 +4,7 @@
#pragma once
#include "BLI_math_vector_types.hh"
#include "BLI_utildefines.h"
#include "BLI_utility_mixins.hh"
@@ -11,6 +12,11 @@
* \ingroup bke
*/
namespace blender {
namespace ocio {
class ColorSpace;
}
} // namespace blender
struct AssetWeakReference;
namespace blender::bke {
@@ -19,6 +25,65 @@ struct PaintRuntime : NonCopyable, NonMovable {
uint16_t ob_mode = 0;
AssetWeakReference *previous_active_brush_reference = nullptr;
blender::float2 last_rake = float2(0.0f, 0.0f);
float last_rake_angle = 0.0f;
int last_stroke_valid = false;
blender::float3 average_stroke_accum = float3(0.0f, 0.0f, 0.0f);
int average_stroke_counter = 0;
/* How much brush should be rotated in the view plane, 0 means x points right, y points up.
* The convention is that the brush's _negative_ Y axis points in the tangent direction (of the
* mouse curve, Bezier curve, etc.) */
float brush_rotation = 0.0f;
float brush_rotation_sec = 0.0f;
/*******************************************************************************
* all data below are used to communicate with cursor drawing and tex sampling *
*******************************************************************************/
bool draw_anchored = false;
int anchored_size = 0;
/**
* Normalization factor due to accumulated value of curve along spacing.
* Calculated when brush spacing changes to dampen strength of stroke
* if space attenuation is used.
*/
float overlap_factor = 0.0f;
bool draw_inverted = false;
/** Check is there an ongoing stroke right now. */
bool stroke_active = false;
/**
* Store last location of stroke or whether the mesh was hit.
* Valid only while stroke is active.
*/
blender::float3 last_location = float3(0.0f, 0.0f, 0.0f);
bool last_hit = false;
blender::float2 anchored_initial_mouse = float2(0.0f, 0.0f);
/**
* Radius of brush, pre-multiplied with pressure.
* In case of anchored brushes contains the anchored radius.
*/
float pixel_radius = 0.0f;
float initial_pixel_radius = 0.0f;
float start_pixel_radius = 0.0f;
/** Drawing pressure. */
float size_pressure_value = 0.0f;
/** Position of mouse, used to sample the texture. */
blender::float2 tex_mouse = float2(0.0f, 0.0f);
/** Position of mouse, used to sample the mask texture. */
blender::float2 mask_tex_mouse = float2(0.0f, 0.0f);
/** ColorSpace cache to avoid locking up during sampling. */
bool do_linear_conversion = false;
const blender::ocio::ColorSpace *colorspace = nullptr;
PaintRuntime();
~PaintRuntime();
};

View File

@@ -38,6 +38,7 @@
#include "BKE_main.hh"
#include "BKE_material.hh"
#include "BKE_paint.hh"
#include "BKE_paint_types.hh"
#include "BKE_preview_image.hh"
#include "BKE_texture.h"
@@ -872,7 +873,7 @@ float BKE_brush_sample_tex_3d(const Paint *paint,
const int thread,
ImagePool *pool)
{
const UnifiedPaintSettings *ups = &paint->unified_paint_settings;
const blender::bke::PaintRuntime *paint_runtime = paint->runtime;
float intensity = 1.0;
bool hasrgb = false;
@@ -924,30 +925,30 @@ float BKE_brush_sample_tex_3d(const Paint *paint,
if (mtex->brush_map_mode == MTEX_MAP_MODE_VIEW) {
/* keep coordinates relative to mouse */
rotation -= ups->brush_rotation;
rotation -= paint_runtime->brush_rotation;
x = point_2d[0] - ups->tex_mouse[0];
y = point_2d[1] - ups->tex_mouse[1];
x = point_2d[0] - paint_runtime->tex_mouse[0];
y = point_2d[1] - paint_runtime->tex_mouse[1];
/* use pressure adjusted size for fixed mode */
invradius = 1.0f / ups->pixel_radius;
invradius = 1.0f / paint_runtime->pixel_radius;
}
else if (mtex->brush_map_mode == MTEX_MAP_MODE_TILED) {
/* leave the coordinates relative to the screen */
/* use unadjusted size for tiled mode */
invradius = 1.0f / ups->start_pixel_radius;
invradius = 1.0f / paint_runtime->start_pixel_radius;
x = point_2d[0];
y = point_2d[1];
}
else if (mtex->brush_map_mode == MTEX_MAP_MODE_RANDOM) {
rotation -= ups->brush_rotation;
rotation -= paint_runtime->brush_rotation;
/* these contain a random coordinate */
x = point_2d[0] - ups->tex_mouse[0];
y = point_2d[1] - ups->tex_mouse[1];
x = point_2d[0] - paint_runtime->tex_mouse[0];
y = point_2d[1] - paint_runtime->tex_mouse[1];
invradius = 1.0f / ups->pixel_radius;
invradius = 1.0f / paint_runtime->pixel_radius;
}
x *= invradius;
@@ -980,8 +981,8 @@ float BKE_brush_sample_tex_3d(const Paint *paint,
rgba[3] = 1.0f;
}
/* For consistency, sampling always returns color in linear space */
else if (ups->do_linear_conversion) {
IMB_colormanagement_colorspace_to_scene_linear_v3(rgba, ups->colorspace);
else if (paint_runtime->do_linear_conversion) {
IMB_colormanagement_colorspace_to_scene_linear_v3(rgba, paint_runtime->colorspace);
}
return intensity;
@@ -990,7 +991,7 @@ float BKE_brush_sample_tex_3d(const Paint *paint,
float BKE_brush_sample_masktex(
const Paint *paint, Brush *br, const float point[2], const int thread, ImagePool *pool)
{
const UnifiedPaintSettings *ups = &paint->unified_paint_settings;
const blender::bke::PaintRuntime *paint_runtime = paint->runtime;
MTex *mtex = &br->mask_mtex;
float rgba[4], intensity;
@@ -1037,30 +1038,30 @@ float BKE_brush_sample_masktex(
if (mtex->brush_map_mode == MTEX_MAP_MODE_VIEW) {
/* keep coordinates relative to mouse */
rotation -= ups->brush_rotation_sec;
rotation -= paint_runtime->brush_rotation_sec;
x = point_2d[0] - ups->mask_tex_mouse[0];
y = point_2d[1] - ups->mask_tex_mouse[1];
x = point_2d[0] - paint_runtime->mask_tex_mouse[0];
y = point_2d[1] - paint_runtime->mask_tex_mouse[1];
/* use pressure adjusted size for fixed mode */
invradius = 1.0f / ups->pixel_radius;
invradius = 1.0f / paint_runtime->pixel_radius;
}
else if (mtex->brush_map_mode == MTEX_MAP_MODE_TILED) {
/* leave the coordinates relative to the screen */
/* use unadjusted size for tiled mode */
invradius = 1.0f / ups->start_pixel_radius;
invradius = 1.0f / paint_runtime->start_pixel_radius;
x = point_2d[0];
y = point_2d[1];
}
else if (mtex->brush_map_mode == MTEX_MAP_MODE_RANDOM) {
rotation -= ups->brush_rotation_sec;
rotation -= paint_runtime->brush_rotation_sec;
/* these contain a random coordinate */
x = point_2d[0] - ups->mask_tex_mouse[0];
y = point_2d[1] - ups->mask_tex_mouse[1];
x = point_2d[0] - paint_runtime->mask_tex_mouse[0];
y = point_2d[1] - paint_runtime->mask_tex_mouse[1];
invradius = 1.0f / ups->pixel_radius;
invradius = 1.0f / paint_runtime->pixel_radius;
}
x *= invradius;
@@ -1088,10 +1089,11 @@ float BKE_brush_sample_masktex(
switch (br->mask_pressure) {
case BRUSH_MASK_PRESSURE_CUTOFF:
intensity = ((1.0f - intensity) < ups->size_pressure_value) ? 1.0f : 0.0f;
intensity = ((1.0f - intensity) < paint_runtime->size_pressure_value) ? 1.0f : 0.0f;
break;
case BRUSH_MASK_PRESSURE_RAMP:
intensity = ups->size_pressure_value + intensity * (1.0f - ups->size_pressure_value);
intensity = paint_runtime->size_pressure_value +
intensity * (1.0f - paint_runtime->size_pressure_value);
break;
default:
break;
@@ -1352,17 +1354,18 @@ void BKE_brush_jitter_pos(const Paint &paint,
jitterpos[1] = pos[1] + 2 * rand_pos[1] * diameter * spread;
}
void BKE_brush_randomize_texture_coords(UnifiedPaintSettings *ups, bool mask)
void BKE_brush_randomize_texture_coords(Paint *paint, bool mask)
{
blender::bke::PaintRuntime &paint_runtime = *paint->runtime;
/* we multiply with brush radius as an optimization for the brush
* texture sampling functions */
if (mask) {
ups->mask_tex_mouse[0] = BLI_rng_get_float(brush_rng) * ups->pixel_radius;
ups->mask_tex_mouse[1] = BLI_rng_get_float(brush_rng) * ups->pixel_radius;
paint_runtime.mask_tex_mouse[0] = BLI_rng_get_float(brush_rng) * paint_runtime.pixel_radius;
paint_runtime.mask_tex_mouse[1] = BLI_rng_get_float(brush_rng) * paint_runtime.pixel_radius;
}
else {
ups->tex_mouse[0] = BLI_rng_get_float(brush_rng) * ups->pixel_radius;
ups->tex_mouse[1] = BLI_rng_get_float(brush_rng) * ups->pixel_radius;
paint_runtime.tex_mouse[0] = BLI_rng_get_float(brush_rng) * paint_runtime.pixel_radius;
paint_runtime.tex_mouse[1] = BLI_rng_get_float(brush_rng) * paint_runtime.pixel_radius;
}
}

View File

@@ -1805,7 +1805,6 @@ void BKE_paint_init(
BKE_paint_ensure_from_paintmode(sce, mode);
Paint *paint = BKE_paint_get_active_from_paintmode(sce, mode);
UnifiedPaintSettings *ups = &paint->unified_paint_settings;
if (ensure_brushes) {
BKE_paint_brushes_ensure(bmain, paint);
@@ -1813,9 +1812,6 @@ void BKE_paint_init(
copy_v3_v3_uchar(paint->paint_cursor_col, col);
paint->paint_cursor_col[3] = 128;
ups->last_stroke_valid = false;
zero_v3(ups->average_stroke_accum);
ups->average_stroke_counter = 0;
if (!paint->cavity_curve) {
BKE_paint_cavity_curve_preset(paint, CURVE_PRESET_LINE);
}
@@ -1886,10 +1882,10 @@ void BKE_paint_copy(const Paint *src, Paint *dst, const int flag)
void BKE_paint_stroke_get_average(const Paint *paint, const Object *ob, float stroke[3])
{
const UnifiedPaintSettings *ups = &paint->unified_paint_settings;
if (ups->last_stroke_valid && ups->average_stroke_counter > 0) {
float fac = 1.0f / ups->average_stroke_counter;
mul_v3_v3fl(stroke, ups->average_stroke_accum, fac);
const blender::bke::PaintRuntime &paint_runtime = *paint->runtime;
if (paint_runtime.last_stroke_valid && paint_runtime.average_stroke_counter > 0) {
float fac = 1.0f / paint_runtime.average_stroke_counter;
mul_v3_v3fl(stroke, paint_runtime.average_stroke_accum, fac);
}
else {
copy_v3_v3(stroke, ob->object_to_world().location());
@@ -2058,11 +2054,6 @@ void BKE_paint_blend_read_data(BlendDataReader *reader, const Scene *scene, Pain
paint->paint_cursor = nullptr;
/* Reset last_location and last_hit, so they are not remembered across sessions. In some files
* these are also NaN, which could lead to crashes in painting. */
zero_v3(ups->last_location);
ups->last_hit = 0;
paint->runtime = MEM_new<blender::bke::PaintRuntime>(__func__);
paint_runtime_init(scene->toolsettings, paint);
@@ -2103,22 +2094,21 @@ float paint_grid_paint_mask(const GridPaintMask *gpm, uint level, uint x, uint y
}
/* Threshold to move before updating the brush rotation, reduces jitter. */
static float paint_rake_rotation_spacing(const UnifiedPaintSettings & /*ups*/, const Brush &brush)
static float paint_rake_rotation_spacing(const Paint & /*ups*/, const Brush &brush)
{
return brush.sculpt_brush_type == SCULPT_BRUSH_TYPE_CLAY_STRIPS ? 1.0f : 20.0f;
}
void paint_update_brush_rake_rotation(UnifiedPaintSettings &ups,
const Brush &brush,
float rotation)
void paint_update_brush_rake_rotation(Paint &paint, const Brush &brush, float rotation)
{
ups.brush_rotation = rotation;
blender::bke::PaintRuntime &paint_runtime = *paint.runtime;
paint_runtime.brush_rotation = rotation;
if (brush.mask_mtex.brush_angle_mode & MTEX_ANGLE_RAKE) {
ups.brush_rotation_sec = rotation;
paint_runtime.brush_rotation_sec = rotation;
}
else {
ups.brush_rotation_sec = 0.0f;
paint_runtime.brush_rotation_sec = 0.0f;
}
}
@@ -2133,15 +2123,17 @@ static bool paint_rake_rotation_active(const Brush &brush, PaintMode paint_mode)
BKE_brush_has_cube_tip(&brush, paint_mode);
}
bool paint_calculate_rake_rotation(UnifiedPaintSettings &ups,
bool paint_calculate_rake_rotation(Paint &paint,
const Brush &brush,
const float mouse_pos[2],
const PaintMode paint_mode,
bool stroke_has_started)
{
blender::bke::PaintRuntime &paint_runtime = *paint.runtime;
bool ok = false;
if (paint_rake_rotation_active(brush, paint_mode)) {
float r = paint_rake_rotation_spacing(ups, brush);
float r = paint_rake_rotation_spacing(paint, brush);
float rotation;
/* Use a smaller limit if the stroke hasn't started to prevent excessive pre-roll. */
@@ -2150,28 +2142,28 @@ bool paint_calculate_rake_rotation(UnifiedPaintSettings &ups,
}
float dpos[2];
sub_v2_v2v2(dpos, mouse_pos, ups.last_rake);
sub_v2_v2v2(dpos, mouse_pos, paint_runtime.last_rake);
/* Limit how often we update the angle to prevent jitter. */
if (len_squared_v2(dpos) >= r * r) {
rotation = atan2f(dpos[1], dpos[0]) + float(0.5f * M_PI);
copy_v2_v2(ups.last_rake, mouse_pos);
copy_v2_v2(paint_runtime.last_rake, mouse_pos);
ups.last_rake_angle = rotation;
paint_runtime.last_rake_angle = rotation;
paint_update_brush_rake_rotation(ups, brush, rotation);
paint_update_brush_rake_rotation(paint, brush, rotation);
ok = true;
}
/* Make sure we reset here to the last rotation to avoid accumulating
* values in case a random rotation is also added. */
else {
paint_update_brush_rake_rotation(ups, brush, ups.last_rake_angle);
paint_update_brush_rake_rotation(paint, brush, paint_runtime.last_rake_angle);
ok = false;
}
}
else {
ups.brush_rotation = ups.brush_rotation_sec = 0.0f;
paint_runtime.brush_rotation = paint_runtime.brush_rotation_sec = 0.0f;
ok = true;
}
return ok;

View File

@@ -1248,12 +1248,7 @@ static void scene_blend_read_data(BlendDataReader *reader, ID *id)
BLO_read_struct(reader, ToolSettings, &sce->toolsettings);
if (sce->toolsettings) {
/* Reset last_location and last_hit, so they are not remembered across sessions. In some files
* these are also NaN, which could lead to crashes in painting. */
UnifiedPaintSettings *ups = &sce->toolsettings->unified_paint_settings;
zero_v3(ups->last_location);
ups->last_hit = 0;
/* Prior to 5.0, the brush->size value is expected to be the radius, not the diameter. To
* ensure correct behavior, convert this when reading newer files. */

View File

@@ -22,6 +22,7 @@
#include "BKE_modifier.hh"
#include "BKE_object.hh"
#include "BKE_paint.hh"
#include "BKE_paint_types.hh"
#include "BKE_report.hh"
#include "BLI_math_vector.h"
@@ -402,10 +403,10 @@ static void object_transfer_mode_reposition_view_pivot(ARegion *region,
if (!ED_view3d_autodist_simple(region, mval, global_loc, 0, nullptr)) {
return;
}
UnifiedPaintSettings *ups = &paint->unified_paint_settings;
copy_v3_v3(ups->average_stroke_accum, global_loc);
ups->average_stroke_counter = 1;
ups->last_stroke_valid = true;
bke::PaintRuntime *paint_runtime = paint->runtime;
copy_v3_v3(paint_runtime->average_stroke_accum, global_loc);
paint_runtime->average_stroke_counter = 1;
paint_runtime->last_stroke_valid = true;
}
constexpr float mode_transfer_flash_length = 0.55f;

View File

@@ -14,6 +14,7 @@
#include "BKE_context.hh"
#include "BKE_curves.hh"
#include "BKE_object.hh"
#include "BKE_paint_types.hh"
#include "BKE_report.hh"
#include "ED_view3d.hh"
@@ -347,10 +348,10 @@ Vector<float4x4> get_symmetry_brush_transforms(const eCurvesSymmetryType symmetr
void remember_stroke_position(CurvesSculpt &curves_sculpt, const float3 &brush_position_wo)
{
UnifiedPaintSettings &ups = curves_sculpt.paint.unified_paint_settings;
copy_v3_v3(ups.average_stroke_accum, brush_position_wo);
ups.average_stroke_counter = 1;
ups.last_stroke_valid = true;
bke::PaintRuntime &paint_runtime = *curves_sculpt.paint.runtime;
copy_v3_v3(paint_runtime.average_stroke_accum, brush_position_wo);
paint_runtime.average_stroke_counter = 1;
paint_runtime.last_stroke_valid = true;
}
float transform_brush_radius(const float4x4 &transform,

View File

@@ -37,6 +37,7 @@
#include "BKE_node_runtime.hh"
#include "BKE_object.hh"
#include "BKE_paint.hh"
#include "BKE_paint_types.hh"
#include "BKE_screen.hh"
#include "NOD_texture.h"
@@ -567,7 +568,7 @@ static int project_brush_radius_grease_pencil(ViewContext *vc,
/* Draw an overlay that shows what effect the brush's texture will
* have on brush strength. */
static bool paint_draw_tex_overlay(UnifiedPaintSettings *ups,
static bool paint_draw_tex_overlay(Paint *paint,
Brush *brush,
ViewContext *vc,
int x,
@@ -603,6 +604,7 @@ static bool paint_draw_tex_overlay(UnifiedPaintSettings *ups,
return false;
}
bke::PaintRuntime *paint_runtime = paint->runtime;
if (load_tex(brush, vc, zoom, col, primary)) {
GPU_color_mask(true, true, true, true);
GPU_depth_test(GPU_DEPTH_NONE);
@@ -611,32 +613,32 @@ static bool paint_draw_tex_overlay(UnifiedPaintSettings *ups,
GPU_matrix_push();
float center[2] = {
ups->draw_anchored ? ups->anchored_initial_mouse[0] : x,
ups->draw_anchored ? ups->anchored_initial_mouse[1] : y,
paint_runtime->draw_anchored ? paint_runtime->anchored_initial_mouse[0] : x,
paint_runtime->draw_anchored ? paint_runtime->anchored_initial_mouse[1] : y,
};
/* Brush rotation. */
GPU_matrix_translate_2fv(center);
GPU_matrix_rotate_2d(RAD2DEGF(primary ? ups->brush_rotation : ups->brush_rotation_sec));
GPU_matrix_rotate_2d(
RAD2DEGF(primary ? paint_runtime->brush_rotation : paint_runtime->brush_rotation_sec));
GPU_matrix_translate_2f(-center[0], -center[1]);
/* Scale based on tablet pressure. */
if (primary && ups->stroke_active && BKE_brush_use_size_pressure(brush)) {
const float scale = ups->size_pressure_value;
if (primary && paint_runtime->stroke_active && BKE_brush_use_size_pressure(brush)) {
const float scale = paint_runtime->size_pressure_value;
GPU_matrix_translate_2fv(center);
GPU_matrix_scale_2f(scale, scale);
GPU_matrix_translate_2f(-center[0], -center[1]);
}
if (ups->draw_anchored) {
quad.xmin = center[0] - ups->anchored_size;
quad.ymin = center[1] - ups->anchored_size;
quad.xmax = center[0] + ups->anchored_size;
quad.ymax = center[1] + ups->anchored_size;
if (paint_runtime->draw_anchored) {
quad.xmin = center[0] - paint_runtime->anchored_size;
quad.ymin = center[1] - paint_runtime->anchored_size;
quad.xmax = center[0] + paint_runtime->anchored_size;
quad.ymax = center[1] + paint_runtime->anchored_size;
}
else {
const Paint &paint = *BKE_paint_get_active_from_paintmode(vc->scene, mode);
const int radius = BKE_brush_size_get(&paint, brush) * zoom;
const int radius = BKE_brush_size_get(paint, brush) * zoom;
quad.xmin = center[0] - radius;
quad.ymin = center[1] - radius;
quad.xmax = center[0] + radius;
@@ -726,7 +728,7 @@ static bool paint_draw_tex_overlay(UnifiedPaintSettings *ups,
/* Draw an overlay that shows what effect the brush's texture will
* have on brush strength. */
static bool paint_draw_cursor_overlay(
UnifiedPaintSettings *ups, Brush *brush, ViewContext *vc, int x, int y, float zoom)
Paint *paint, Brush *brush, ViewContext *vc, int x, int y, float zoom)
{
rctf quad;
/* Check for overlay mode. */
@@ -742,15 +744,15 @@ static bool paint_draw_cursor_overlay(
GPU_color_mask(true, true, true, true);
GPU_depth_test(GPU_DEPTH_NONE);
if (ups->draw_anchored) {
copy_v2_v2(center, ups->anchored_initial_mouse);
quad.xmin = ups->anchored_initial_mouse[0] - ups->anchored_size;
quad.ymin = ups->anchored_initial_mouse[1] - ups->anchored_size;
quad.xmax = ups->anchored_initial_mouse[0] + ups->anchored_size;
quad.ymax = ups->anchored_initial_mouse[1] + ups->anchored_size;
bke::PaintRuntime *paint_runtime = paint->runtime;
if (paint_runtime->draw_anchored) {
copy_v2_v2(center, paint_runtime->anchored_initial_mouse);
quad.xmin = paint_runtime->anchored_initial_mouse[0] - paint_runtime->anchored_size;
quad.ymin = paint_runtime->anchored_initial_mouse[1] - paint_runtime->anchored_size;
quad.xmax = paint_runtime->anchored_initial_mouse[0] + paint_runtime->anchored_size;
quad.ymax = paint_runtime->anchored_initial_mouse[1] + paint_runtime->anchored_size;
}
else {
const Paint *paint = BKE_paint_get_active_from_context(vc->C);
const int radius = BKE_brush_size_get(paint, brush) * zoom;
center[0] = x;
center[1] = y;
@@ -762,11 +764,11 @@ static bool paint_draw_cursor_overlay(
}
/* Scale based on tablet pressure. */
if (ups->stroke_active && BKE_brush_use_size_pressure(brush)) {
if (paint_runtime->stroke_active && BKE_brush_use_size_pressure(brush)) {
do_pop = true;
GPU_matrix_push();
GPU_matrix_translate_2fv(center);
GPU_matrix_scale_1f(ups->size_pressure_value);
GPU_matrix_scale_1f(paint_runtime->size_pressure_value);
GPU_matrix_translate_2f(-center[0], -center[1]);
}
@@ -812,13 +814,8 @@ static bool paint_draw_cursor_overlay(
return true;
}
static bool paint_draw_alpha_overlay(UnifiedPaintSettings *ups,
Brush *brush,
ViewContext *vc,
int x,
int y,
float zoom,
PaintMode mode)
static bool paint_draw_alpha_overlay(
Paint *paint, Brush *brush, ViewContext *vc, int x, int y, float zoom, PaintMode mode)
{
/* Color means that primary brush texture is colored and
* secondary is used for alpha/mask control. */
@@ -839,22 +836,24 @@ static bool paint_draw_alpha_overlay(UnifiedPaintSettings *ups,
/* Colored overlay should be drawn separately. */
if (col) {
if (!(flags & PAINT_OVERLAY_OVERRIDE_PRIMARY)) {
alpha_overlay_active = paint_draw_tex_overlay(ups, brush, vc, x, y, zoom, mode, true, true);
alpha_overlay_active = paint_draw_tex_overlay(
paint, brush, vc, x, y, zoom, mode, true, true);
}
if (!(flags & PAINT_OVERLAY_OVERRIDE_SECONDARY)) {
alpha_overlay_active = paint_draw_tex_overlay(
ups, brush, vc, x, y, zoom, mode, false, false);
paint, brush, vc, x, y, zoom, mode, false, false);
}
if (!(flags & PAINT_OVERLAY_OVERRIDE_CURSOR)) {
alpha_overlay_active = paint_draw_cursor_overlay(ups, brush, vc, x, y, zoom);
alpha_overlay_active = paint_draw_cursor_overlay(paint, brush, vc, x, y, zoom);
}
}
else {
if (!(flags & PAINT_OVERLAY_OVERRIDE_PRIMARY) && (mode != PaintMode::Weight)) {
alpha_overlay_active = paint_draw_tex_overlay(ups, brush, vc, x, y, zoom, mode, false, true);
alpha_overlay_active = paint_draw_tex_overlay(
paint, brush, vc, x, y, zoom, mode, false, true);
}
if (!(flags & PAINT_OVERLAY_OVERRIDE_CURSOR)) {
alpha_overlay_active = paint_draw_cursor_overlay(ups, brush, vc, x, y, zoom);
alpha_overlay_active = paint_draw_cursor_overlay(paint, brush, vc, x, y, zoom);
}
}
@@ -1042,18 +1041,18 @@ static void paint_draw_curve_cursor(Brush *brush, ViewContext *vc)
/* Special actions taken when paint cursor goes over mesh */
/* TODO: sculpt only for now. */
static void paint_cursor_update_unprojected_radius(const UnifiedPaintSettings &ups,
static void paint_cursor_update_unprojected_radius(Paint &paint,
Brush &brush,
const ViewContext &vc,
const float location[3])
{
Paint &paint = *BKE_paint_get_active_from_context(vc.C);
const bke::PaintRuntime &paint_runtime = *paint.runtime;
/* Update the brush's cached 3D radius. */
if (!BKE_brush_use_locked_size(&paint, &brush)) {
float projected_radius;
/* Get 2D brush radius. */
if (ups.draw_anchored) {
projected_radius = ups.anchored_size;
if (paint_runtime.draw_anchored) {
projected_radius = paint_runtime.anchored_size;
}
else {
if (brush.flag & BRUSH_ANCHORED) {
@@ -1068,8 +1067,8 @@ static void paint_cursor_update_unprojected_radius(const UnifiedPaintSettings &u
float unprojected_radius = paint_calc_object_space_radius(vc, location, projected_radius);
/* Scale 3D brush radius by pressure. */
if (ups.stroke_active && BKE_brush_use_size_pressure(&brush)) {
unprojected_radius *= ups.size_pressure_value;
if (paint_runtime.stroke_active && BKE_brush_use_size_pressure(&brush)) {
unprojected_radius *= paint_runtime.size_pressure_value;
}
/* Set cached value in either Brush or UnifiedPaintSettings. */
@@ -1376,9 +1375,10 @@ static bool paint_cursor_context_init(bContext *C,
pcontext.zoomx = max_ff(zoomx, zoomy);
pcontext.final_radius = (BKE_brush_size_get(pcontext.paint, pcontext.brush) * zoomx);
const bke::PaintRuntime &paint_runtime = *pcontext.paint->runtime;
/* There is currently no way to check if the direction is inverted before starting the stroke,
* so this does not reflect the state of the brush in the UI. */
if (((pcontext.ups->draw_inverted == 0) ^ ((pcontext.brush->flag & BRUSH_DIR_IN) == 0)) &&
if (((!paint_runtime.draw_inverted) ^ ((pcontext.brush->flag & BRUSH_DIR_IN) == 0)) &&
bke::brush::supports_secondary_cursor_color(*pcontext.brush))
{
pcontext.outline_col = float3(pcontext.brush->sub_col);
@@ -1403,7 +1403,7 @@ static bool paint_cursor_context_init(bContext *C,
pcontext.outline_col = float3(0.8f);
}
pcontext.is_stroke_active = pcontext.ups->stroke_active;
pcontext.is_stroke_active = paint_runtime.stroke_active;
return true;
}
@@ -1438,7 +1438,7 @@ static void paint_cursor_sculpt_session_update_and_init(PaintCursorContext &pcon
bContext *C = pcontext.C;
SculptSession &ss = *pcontext.ss;
Brush &brush = *pcontext.brush;
UnifiedPaintSettings &ups = *pcontext.ups;
bke::PaintRuntime &paint_runtime = *pcontext.paint->runtime;
ViewContext &vc = pcontext.vc;
CursorGeometryInfo gi;
@@ -1455,15 +1455,15 @@ static void paint_cursor_sculpt_session_update_and_init(PaintCursorContext &pcon
* work correctly */
vert_random_access_ensure(*vc.obact);
pcontext.prev_active_vert_index = ss.active_vert_index();
if (!ups.stroke_active) {
if (!paint_runtime.stroke_active) {
pcontext.is_cursor_over_mesh = cursor_geometry_info_update(
C, &gi, mval_fl, (pcontext.brush->falloff_shape == PAINT_FALLOFF_SHAPE_SPHERE));
pcontext.location = gi.location;
pcontext.normal = gi.normal;
}
else {
pcontext.is_cursor_over_mesh = ups.last_hit;
pcontext.location = ups.last_location;
pcontext.is_cursor_over_mesh = paint_runtime.last_hit;
pcontext.location = paint_runtime.last_location;
}
paint_cursor_update_pixel_radius(pcontext);
@@ -1473,7 +1473,8 @@ static void paint_cursor_sculpt_session_update_and_init(PaintCursorContext &pcon
}
if (pcontext.is_cursor_over_mesh) {
paint_cursor_update_unprojected_radius(ups, brush, vc, pcontext.scene_space_location);
paint_cursor_update_unprojected_radius(
*pcontext.paint, brush, vc, pcontext.scene_space_location);
}
pcontext.sd = CTX_data_tool_settings(pcontext.C)->sculpt;
@@ -1507,13 +1508,14 @@ static void paint_update_mouse_cursor(PaintCursorContext &pcontext)
static void paint_draw_2D_view_brush_cursor_default(PaintCursorContext &pcontext)
{
immUniformColor3fvAlpha(pcontext.outline_col, pcontext.outline_alpha);
const bke::PaintRuntime *paint_runtime = pcontext.paint->runtime;
/* Draw brush outline. */
if (pcontext.ups->stroke_active && BKE_brush_use_size_pressure(pcontext.brush)) {
if (paint_runtime->stroke_active && BKE_brush_use_size_pressure(pcontext.brush)) {
imm_draw_circle_wire_2d(pcontext.pos,
pcontext.translation[0],
pcontext.translation[1],
pcontext.final_radius * pcontext.ups->size_pressure_value,
pcontext.final_radius * paint_runtime->size_pressure_value,
40);
/* Outer at half alpha. */
immUniformColor3fvAlpha(pcontext.outline_col, pcontext.outline_alpha * 0.5f);
@@ -2125,15 +2127,16 @@ static void paint_cursor_update_rake_rotation(PaintCursorContext &pcontext)
/* Don't calculate rake angles while a stroke is active because the rake variables are global
* and we may get interference with the stroke itself.
* For line strokes, such interference is visible. */
if (!pcontext.ups->stroke_active) {
const bke::PaintRuntime *paint_runtime = pcontext.paint->runtime;
if (!paint_runtime->stroke_active) {
paint_calculate_rake_rotation(
*pcontext.ups, *pcontext.brush, pcontext.translation, pcontext.mode, true);
*pcontext.paint, *pcontext.brush, pcontext.translation, pcontext.mode, true);
}
}
static void paint_cursor_check_and_draw_alpha_overlays(PaintCursorContext &pcontext)
{
pcontext.alpha_overlay_drawn = paint_draw_alpha_overlay(pcontext.ups,
pcontext.alpha_overlay_drawn = paint_draw_alpha_overlay(pcontext.paint,
pcontext.brush,
&pcontext.vc,
pcontext.mval.x,
@@ -2144,11 +2147,12 @@ static void paint_cursor_check_and_draw_alpha_overlays(PaintCursorContext &pcont
static void paint_cursor_update_anchored_location(PaintCursorContext &pcontext)
{
UnifiedPaintSettings *ups = pcontext.ups;
if (ups->draw_anchored) {
pcontext.final_radius = ups->anchored_size;
pcontext.translation = {ups->anchored_initial_mouse[0] + pcontext.region->winrct.xmin,
ups->anchored_initial_mouse[1] + pcontext.region->winrct.ymin};
bke::PaintRuntime *paint_runtime = pcontext.paint->runtime;
if (paint_runtime->draw_anchored) {
pcontext.final_radius = paint_runtime->anchored_size;
pcontext.translation = {
paint_runtime->anchored_initial_mouse[0] + pcontext.region->winrct.xmin,
paint_runtime->anchored_initial_mouse[1] + pcontext.region->winrct.ymin};
}
}

View File

@@ -44,6 +44,7 @@
#include "BKE_node_runtime.hh"
#include "BKE_object.hh"
#include "BKE_paint.hh"
#include "BKE_paint_types.hh"
#include "BKE_report.hh"
#include "BKE_scene.hh"
@@ -677,9 +678,10 @@ static blender::float3 paint_init_pivot_grease_pencil(Object *ob, const int fram
return float3(0.0f);
}
/* TODO: Move this out of paint image... */
void paint_init_pivot(Object *ob, Scene *scene, Paint *paint)
{
UnifiedPaintSettings *ups = &paint->unified_paint_settings;
blender::bke::PaintRuntime &paint_runtime = *paint->runtime;
blender::float3 location;
switch (ob->type) {
@@ -694,15 +696,15 @@ void paint_init_pivot(Object *ob, Scene *scene, Paint *paint)
break;
default:
BLI_assert_unreachable();
ups->last_stroke_valid = false;
paint_runtime.last_stroke_valid = false;
return;
}
mul_m4_v3(ob->object_to_world().ptr(), location);
ups->last_stroke_valid = true;
ups->average_stroke_counter = 1;
copy_v3_v3(ups->average_stroke_accum, location);
paint_runtime.last_stroke_valid = true;
paint_runtime.average_stroke_counter = 1;
copy_v3_v3(paint_runtime.average_stroke_accum, location);
}
void ED_object_texture_paint_mode_enter_ex(Main &bmain,

View File

@@ -27,6 +27,7 @@
#include "BKE_context.hh"
#include "BKE_image.hh"
#include "BKE_paint.hh"
#include "BKE_paint_types.hh"
#include "BKE_report.hh"
#include "DEG_depsgraph.hh"
@@ -716,7 +717,7 @@ static void brush_painter_2d_refresh_cache(ImagePaintState *s,
float distance,
float size)
{
const UnifiedPaintSettings *ups = &painter->paint->unified_paint_settings;
const blender::bke::PaintRuntime *paint_runtime = painter->paint->runtime;
Brush *brush = painter->brush;
BrushPainterCache *cache = &tile->cache;
/* Adding 4 pixels of padding for brush anti-aliasing. */
@@ -738,7 +739,7 @@ static void brush_painter_2d_refresh_cache(ImagePaintState *s,
/* determine how can update based on textures used */
if (cache->is_texbrush) {
if (brush->mtex.brush_map_mode == MTEX_MAP_MODE_VIEW) {
tex_rotation += ups->brush_rotation;
tex_rotation += paint_runtime->brush_rotation;
}
else if (brush->mtex.brush_map_mode == MTEX_MAP_MODE_RANDOM) {
do_random = true;
@@ -756,7 +757,7 @@ static void brush_painter_2d_refresh_cache(ImagePaintState *s,
bool do_partial_update_mask = false;
/* invalidate case for all mapping modes */
if (brush->mask_mtex.brush_map_mode == MTEX_MAP_MODE_VIEW) {
mask_rotation += ups->brush_rotation_sec;
mask_rotation += paint_runtime->brush_rotation_sec;
}
else if (brush->mask_mtex.brush_map_mode == MTEX_MAP_MODE_RANDOM) {
renew_maxmask = true;

View File

@@ -18,6 +18,7 @@
#include "BKE_context.hh"
#include "BKE_layer.hh"
#include "BKE_paint.hh"
#include "BKE_paint_types.hh"
#include "BKE_undo_system.hh"
#include "ED_paint.hh"
@@ -336,10 +337,10 @@ static void paint_stroke_update_step(bContext *C,
{
PaintOperation *pop = static_cast<PaintOperation *>(paint_stroke_mode_data(stroke));
Paint *paint = BKE_paint_get_active_from_context(C);
UnifiedPaintSettings *ups = &paint->unified_paint_settings;
bke::PaintRuntime *paint_runtime = paint->runtime;
Brush *brush = BKE_paint_brush(paint);
float alphafac = (brush->flag & BRUSH_ACCUMULATE) ? ups->overlap_factor : 1.0f;
float alphafac = (brush->flag & BRUSH_ACCUMULATE) ? paint_runtime->overlap_factor : 1.0f;
/* initial brush values. Maybe it should be considered moving these to stroke system */
float startalpha = BKE_brush_alpha_get(paint, brush);

View File

@@ -73,6 +73,7 @@
#include "BKE_node_runtime.hh"
#include "BKE_object.hh"
#include "BKE_paint.hh"
#include "BKE_paint_types.hh"
#include "BKE_report.hh"
#include "BKE_scene.hh"
#include "BKE_screen.hh"
@@ -5727,7 +5728,7 @@ static bool project_paint_op(void *state, const float lastpos[2], const float po
const int3 &tri = ps->corner_tris_eval[tri_index];
const int vert_tri[3] = {PS_CORNER_TRI_AS_VERT_INDEX_3(ps, tri)};
float world[3];
UnifiedPaintSettings *ups = &ps->paint->unified_paint_settings;
blender::bke::PaintRuntime *paint_runtime = ps->paint->runtime;
interp_v3_v3v3v3(world,
ps->vert_positions_eval[vert_tri[0]],
@@ -5735,10 +5736,10 @@ static bool project_paint_op(void *state, const float lastpos[2], const float po
ps->vert_positions_eval[vert_tri[2]],
w);
ups->average_stroke_counter++;
paint_runtime->average_stroke_counter++;
mul_m4_v3(ps->obmat, world);
add_v3_v3(ups->average_stroke_accum, world);
ups->last_stroke_valid = true;
add_v3_v3(paint_runtime->average_stroke_accum, world);
paint_runtime->last_stroke_valid = true;
}
}

View File

@@ -31,6 +31,7 @@
#include "BKE_curve.hh"
#include "BKE_image.hh"
#include "BKE_paint.hh"
#include "BKE_paint_types.hh"
#include "WM_api.hh"
#include "WM_types.hh"
@@ -317,7 +318,7 @@ bool paint_brush_update(bContext *C,
{
Scene *scene = CTX_data_scene(C);
Paint *paint = BKE_paint_get_active_from_paintmode(scene, mode);
UnifiedPaintSettings &ups = *stroke->ups;
bke::PaintRuntime &paint_runtime = *paint->runtime;
bool location_sampled = false;
bool location_success = false;
/* Use to perform all operations except applying the stroke,
@@ -333,30 +334,30 @@ bool paint_brush_update(bContext *C,
* changing events. We should avoid this after events system re-design */
if (!stroke->brush_init) {
copy_v2_v2(stroke->initial_mouse, mouse);
copy_v2_v2(ups.last_rake, mouse);
copy_v2_v2(ups.tex_mouse, mouse);
copy_v2_v2(ups.mask_tex_mouse, mouse);
copy_v2_v2(paint_runtime.last_rake, mouse);
copy_v2_v2(paint_runtime.tex_mouse, mouse);
copy_v2_v2(paint_runtime.mask_tex_mouse, mouse);
stroke->cached_size_pressure = pressure;
stroke->brush_init = true;
}
if (paint_supports_dynamic_size(brush, mode)) {
copy_v2_v2(ups.tex_mouse, mouse);
copy_v2_v2(ups.mask_tex_mouse, mouse);
copy_v2_v2(paint_runtime.tex_mouse, mouse);
copy_v2_v2(paint_runtime.mask_tex_mouse, mouse);
stroke->cached_size_pressure = pressure;
}
/* Truly temporary data that isn't stored in properties */
ups.stroke_active = true;
ups.size_pressure_value = stroke->cached_size_pressure;
paint_runtime.stroke_active = true;
paint_runtime.size_pressure_value = stroke->cached_size_pressure;
ups.pixel_radius = BKE_brush_size_get(paint, &brush);
ups.initial_pixel_radius = BKE_brush_size_get(paint, &brush);
paint_runtime.pixel_radius = BKE_brush_size_get(paint, &brush);
paint_runtime.initial_pixel_radius = BKE_brush_size_get(paint, &brush);
if (BKE_brush_use_size_pressure(&brush) && paint_supports_dynamic_size(brush, mode)) {
ups.pixel_radius *= stroke->cached_size_pressure;
paint_runtime.pixel_radius *= stroke->cached_size_pressure;
}
if (paint_supports_dynamic_tex_coords(brush, mode)) {
@@ -370,10 +371,10 @@ bool paint_brush_update(bContext *C,
}
if (brush.mtex.brush_map_mode == MTEX_MAP_MODE_RANDOM) {
BKE_brush_randomize_texture_coords(&ups, false);
BKE_brush_randomize_texture_coords(paint, false);
}
else {
copy_v2_v2(ups.tex_mouse, mouse);
copy_v2_v2(paint_runtime.tex_mouse, mouse);
}
/* take care of mask texture, if any */
@@ -388,10 +389,10 @@ bool paint_brush_update(bContext *C,
}
if (brush.mask_mtex.brush_map_mode == MTEX_MAP_MODE_RANDOM) {
BKE_brush_randomize_texture_coords(&ups, true);
BKE_brush_randomize_texture_coords(paint, true);
}
else {
copy_v2_v2(ups.mask_tex_mouse, mouse);
copy_v2_v2(paint_runtime.mask_tex_mouse, mouse);
}
}
}
@@ -403,9 +404,10 @@ bool paint_brush_update(bContext *C,
const float dx = mouse[0] - stroke->initial_mouse[0];
const float dy = mouse[1] - stroke->initial_mouse[1];
ups.anchored_size = ups.pixel_radius = sqrtf(dx * dx + dy * dy);
paint_runtime.anchored_size = paint_runtime.pixel_radius = sqrtf(dx * dx + dy * dy);
ups.brush_rotation = ups.brush_rotation_sec = atan2f(dy, dx) + float(0.5f * M_PI);
paint_runtime.brush_rotation = paint_runtime.brush_rotation_sec = atan2f(dy, dx) +
float(0.5f * M_PI);
if (brush.flag & BRUSH_EDGE_TO_EDGE) {
halfway[0] = dx * 0.5f + stroke->initial_mouse[0];
@@ -427,26 +429,26 @@ bool paint_brush_update(bContext *C,
}
}
if (hit) {
copy_v2_v2(ups.anchored_initial_mouse, halfway);
copy_v2_v2(ups.tex_mouse, halfway);
copy_v2_v2(ups.mask_tex_mouse, halfway);
copy_v2_v2(paint_runtime.anchored_initial_mouse, halfway);
copy_v2_v2(paint_runtime.tex_mouse, halfway);
copy_v2_v2(paint_runtime.mask_tex_mouse, halfway);
copy_v2_v2(mouse, halfway);
ups.anchored_size /= 2.0f;
ups.pixel_radius /= 2.0f;
stroke->stroke_distance = ups.pixel_radius;
paint_runtime.anchored_size /= 2.0f;
paint_runtime.pixel_radius /= 2.0f;
stroke->stroke_distance = paint_runtime.pixel_radius;
}
else {
copy_v2_v2(ups.anchored_initial_mouse, stroke->initial_mouse);
copy_v2_v2(paint_runtime.anchored_initial_mouse, stroke->initial_mouse);
copy_v2_v2(mouse, stroke->initial_mouse);
stroke->stroke_distance = ups.pixel_radius;
stroke->stroke_distance = paint_runtime.pixel_radius;
}
ups.pixel_radius /= stroke->zoom_2d;
ups.draw_anchored = true;
paint_runtime.pixel_radius /= stroke->zoom_2d;
paint_runtime.draw_anchored = true;
}
else {
/* curve strokes do their own rake calculation */
if (!(brush.flag & BRUSH_CURVE)) {
if (!paint_calculate_rake_rotation(ups, brush, mouse_init, mode, stroke->rake_started)) {
if (!paint_calculate_rake_rotation(*paint, brush, mouse_init, mode, stroke->rake_started)) {
/* Not enough motion to define an angle. */
if (!stroke->rake_started) {
is_dry_run = true;
@@ -465,15 +467,15 @@ bool paint_brush_update(bContext *C,
if (do_random) {
if (brush.mtex.brush_angle_mode & MTEX_ANGLE_RANDOM) {
ups.brush_rotation += -brush.mtex.random_angle / 2.0f +
brush.mtex.random_angle * stroke->rng->get_float();
paint_runtime.brush_rotation += -brush.mtex.random_angle / 2.0f +
brush.mtex.random_angle * stroke->rng->get_float();
}
}
if (do_random_mask) {
if (brush.mask_mtex.brush_angle_mode & MTEX_ANGLE_RANDOM) {
ups.brush_rotation_sec += -brush.mask_mtex.random_angle / 2.0f +
brush.mask_mtex.random_angle * stroke->rng->get_float();
paint_runtime.brush_rotation_sec += -brush.mask_mtex.random_angle / 2.0f +
brush.mask_mtex.random_angle * stroke->rng->get_float();
}
}
@@ -555,7 +557,7 @@ static void paint_brush_stroke_add_step(
const Paint &paint = *BKE_paint_get_active_from_context(C);
const PaintMode mode = BKE_paintmode_get_active_from_context(C);
const Brush &brush = *BKE_paint_brush_for_read(&paint);
UnifiedPaintSettings *ups = stroke->ups;
bke::PaintRuntime *paint_runtime = stroke->paint->runtime;
/* the following code is adapted from texture paint. It may not be needed but leaving here
* just in case for reference (code in texpaint removed as part of refactoring).
@@ -609,12 +611,12 @@ static void paint_brush_stroke_add_step(
float3 location;
bool is_location_is_set;
ups->last_hit = paint_brush_update(
paint_runtime->last_hit = paint_brush_update(
C, brush, mode, stroke, mval, mouse_out, pressure, location, &is_location_is_set);
if (is_location_is_set) {
copy_v3_v3(ups->last_location, location);
copy_v3_v3(paint_runtime->last_location, location);
}
if (!ups->last_hit) {
if (!paint_runtime->last_hit) {
return;
}
@@ -632,7 +634,7 @@ static void paint_brush_stroke_add_step(
if (add_step) {
PointerRNA itemptr;
RNA_collection_add(op->ptr, "stroke", &itemptr);
RNA_float_set(&itemptr, "size", ups->pixel_radius);
RNA_float_set(&itemptr, "size", paint_runtime->pixel_radius);
RNA_float_set_array(&itemptr, "location", location);
/* Mouse coordinates modified by the stroke type options. */
RNA_float_set_array(&itemptr, "mouse", mouse_out);
@@ -813,7 +815,7 @@ static int paint_space_stroke(bContext *C,
const float final_pressure)
{
const ARegion *region = CTX_wm_region(C);
UnifiedPaintSettings *ups = stroke->ups;
bke::PaintRuntime *paint_runtime = stroke->paint->runtime;
const Paint &paint = *BKE_paint_get_active_from_context(C);
const PaintMode mode = BKE_paintmode_get_active_from_context(C);
const Brush &brush = *BKE_paint_brush_for_read(&paint);
@@ -869,8 +871,8 @@ static int paint_space_stroke(bContext *C,
}
pressure = stroke->last_pressure + (spacing / length) * pressure_delta;
ups->overlap_factor = paint_stroke_integrate_overlap(*stroke->brush,
spacing / no_pressure_spacing);
paint_runtime->overlap_factor = paint_stroke_integrate_overlap(
*stroke->brush, spacing / no_pressure_spacing);
stroke->stroke_distance += spacing / stroke->zoom_2d;
paint_brush_stroke_add_step(C, op, stroke, mouse, pressure);
@@ -905,6 +907,7 @@ PaintStroke *paint_stroke_new(bContext *C,
Paint *paint = BKE_paint_get_active_from_context(C);
stroke->paint = paint;
UnifiedPaintSettings *ups = &paint->unified_paint_settings;
bke::PaintRuntime *paint_runtime = paint->runtime;
Brush *br = stroke->brush = BKE_paint_brush(paint);
RegionView3D *rv3d = CTX_wm_region_view3d(C);
@@ -929,15 +932,15 @@ PaintStroke *paint_stroke_new(bContext *C,
/* Check here if color sampling the main brush should do color conversion. This is done here
* to avoid locking up to get the image buffer during sampling. */
ups->do_linear_conversion = false;
ups->colorspace = nullptr;
paint_runtime->do_linear_conversion = false;
paint_runtime->colorspace = nullptr;
if (br->mtex.tex && br->mtex.tex->type == TEX_IMAGE && br->mtex.tex->ima) {
ImBuf *tex_ibuf = BKE_image_pool_acquire_ibuf(
br->mtex.tex->ima, &br->mtex.tex->iuser, nullptr);
if (tex_ibuf && tex_ibuf->float_buffer.data == nullptr) {
ups->do_linear_conversion = true;
ups->colorspace = tex_ibuf->byte_buffer.colorspace;
paint_runtime->do_linear_conversion = true;
paint_runtime->colorspace = tex_ibuf->byte_buffer.colorspace;
}
BKE_image_pool_release_ibuf(br->mtex.tex->ima, tex_ibuf, nullptr);
}
@@ -948,8 +951,8 @@ PaintStroke *paint_stroke_new(bContext *C,
}
}
/* initialize here */
ups->overlap_factor = 1.0;
ups->stroke_active = true;
paint_runtime->overlap_factor = 1.0;
paint_runtime->stroke_active = true;
if (rv3d) {
rv3d->rflag |= RV3D_PAINTING;
@@ -958,9 +961,10 @@ PaintStroke *paint_stroke_new(bContext *C,
/* Preserve location from last stroke while applying and resetting
* ups->average_stroke_counter to 1.
*/
if (ups->average_stroke_counter) {
mul_v3_fl(ups->average_stroke_accum, 1.0f / float(ups->average_stroke_counter));
ups->average_stroke_counter = 1;
if (paint_runtime->average_stroke_counter) {
mul_v3_fl(paint_runtime->average_stroke_accum,
1.0f / float(paint_runtime->average_stroke_counter));
paint_runtime->average_stroke_counter = 1;
}
/* initialize here to avoid initialization conflict with threaded strokes */
@@ -971,7 +975,7 @@ PaintStroke *paint_stroke_new(bContext *C,
BKE_paint_set_overlay_override(eOverlayFlags(br->overlay_flags));
ups->start_pixel_radius = BKE_brush_size_get(stroke->paint, br);
paint_runtime->start_pixel_radius = BKE_brush_size_get(stroke->paint, br);
return stroke;
}
@@ -988,9 +992,9 @@ void paint_stroke_free(bContext *C, wmOperator * /*op*/, PaintStroke *stroke)
return;
}
UnifiedPaintSettings *ups = stroke->ups;
ups->draw_anchored = false;
ups->stroke_active = false;
bke::PaintRuntime *paint_runtime = stroke->paint->runtime;
paint_runtime->draw_anchored = false;
paint_runtime->stroke_active = false;
if (stroke->timer) {
WM_event_timer_remove(CTX_wm_manager(C), CTX_wm_window(C), stroke->timer);
@@ -1005,15 +1009,15 @@ void paint_stroke_free(bContext *C, wmOperator * /*op*/, PaintStroke *stroke)
static void stroke_done(bContext *C, wmOperator *op, PaintStroke *stroke)
{
UnifiedPaintSettings *ups = stroke->ups;
bke::PaintRuntime *paint_runtime = stroke->paint->runtime;
/* reset rotation here to avoid doing so in cursor display */
if (!(stroke->brush->mtex.brush_angle_mode & MTEX_ANGLE_RAKE)) {
ups->brush_rotation = 0.0f;
paint_runtime->brush_rotation = 0.0f;
}
if (!(stroke->brush->mask_mtex.brush_angle_mode & MTEX_ANGLE_RAKE)) {
ups->brush_rotation_sec = 0.0f;
paint_runtime->brush_rotation_sec = 0.0f;
}
if (stroke->stroke_started) {
@@ -1229,8 +1233,8 @@ static void paint_line_strokes_spacing(bContext *C,
const float2 old_pos,
const float2 new_pos)
{
UnifiedPaintSettings *ups = stroke->ups;
Paint *paint = BKE_paint_get_active_from_context(C);
bke::PaintRuntime *paint_runtime = stroke->paint->runtime;
const Brush &brush = *BKE_paint_brush(paint);
const PaintMode mode = BKE_paintmode_get_active_from_context(C);
const ARegion *region = CTX_wm_region(C);
@@ -1298,7 +1302,7 @@ static void paint_line_strokes_spacing(bContext *C,
mouse = stroke->last_mouse_position + mouse_delta * spacing_final;
}
ups->overlap_factor = paint_stroke_integrate_overlap(*stroke->brush, 1.0);
paint_runtime->overlap_factor = paint_stroke_integrate_overlap(*stroke->brush, 1.0);
stroke->stroke_distance += spacing / stroke->zoom_2d;
paint_brush_stroke_add_step(C, op, stroke, mouse, 1.0);
@@ -1320,8 +1324,9 @@ static void paint_stroke_line_end(bContext *C,
const float2 mouse)
{
Brush *br = stroke->brush;
bke::PaintRuntime *paint_runtime = stroke->paint->runtime;
if (stroke->stroke_started && (br->flag & BRUSH_LINE)) {
stroke->ups->overlap_factor = paint_stroke_integrate_overlap(*br, 1.0);
paint_runtime->overlap_factor = paint_stroke_integrate_overlap(*br, 1.0);
paint_brush_stroke_add_step(C, op, stroke, stroke->last_mouse_position, 1.0);
paint_space_stroke(C, op, stroke, mouse, 1.0);
@@ -1336,7 +1341,7 @@ static bool paint_stroke_curve_end(bContext *C, wmOperator *op, PaintStroke *str
}
Paint *paint = BKE_paint_get_active_from_context(C);
UnifiedPaintSettings &ups = paint->unified_paint_settings;
bke::PaintRuntime *paint_runtime = stroke->paint->runtime;
const float spacing = paint_space_stroke_spacing(C, stroke, 1.0f, 1.0f);
const PaintCurve *pc = br.paint_curve;
@@ -1349,7 +1354,7 @@ static bool paint_stroke_curve_end(bContext *C, wmOperator *op, PaintStroke *str
#endif
const PaintCurvePoint *pcp = pc->points;
stroke->ups->overlap_factor = paint_stroke_integrate_overlap(br, 1.0);
paint_runtime->overlap_factor = paint_stroke_integrate_overlap(br, 1.0);
float length_residue = 0.0f;
for (int i = 0; i < pc->tot_points - 1; i++, pcp++) {
@@ -1386,7 +1391,7 @@ static bool paint_stroke_curve_end(bContext *C, wmOperator *op, PaintStroke *str
for (int j = 0; j < PAINT_CURVE_NUM_SEGMENTS; j++) {
if (do_rake) {
const float rotation = atan2f(tangents[2 * j + 1], tangents[2 * j]) + float(0.5f * M_PI);
paint_update_brush_rake_rotation(ups, br, rotation);
paint_update_brush_rake_rotation(*paint, br, rotation);
}
if (!stroke->stroke_started) {
@@ -1456,6 +1461,7 @@ wmOperatorStatus paint_stroke_modal(bContext *C,
{
Paint *paint = BKE_paint_get_active_from_context(C);
const PaintMode mode = BKE_paintmode_get_active_from_context(C);
bke::PaintRuntime &paint_runtime = *paint->runtime;
PaintStroke *stroke = *stroke_p;
const Brush *br = stroke->brush = BKE_paint_brush(paint);
bool first_dab = false;
@@ -1619,9 +1625,9 @@ wmOperatorStatus paint_stroke_modal(bContext *C,
if ((br->mtex.brush_angle_mode & MTEX_ANGLE_RAKE) ||
(br->mask_mtex.brush_angle_mode & MTEX_ANGLE_RAKE))
{
copy_v2_v2(stroke->ups->last_rake, stroke->last_mouse_position);
copy_v2_v2(paint_runtime.last_rake, stroke->last_mouse_position);
}
paint_calculate_rake_rotation(*stroke->ups, *br, mouse, mode, true);
paint_calculate_rake_rotation(*stroke->paint, *br, mouse, mode, true);
}
}
else if (first_modal ||
@@ -1651,7 +1657,7 @@ wmOperatorStatus paint_stroke_modal(bContext *C,
/* we want the stroke to have the first daub at the start location
* instead of waiting till we have moved the space distance */
if (first_dab && paint_space_stroke_enabled(*br, mode) && !(br->flag & BRUSH_SMOOTH_STROKE)) {
stroke->ups->overlap_factor = paint_stroke_integrate_overlap(*br, 1.0);
paint_runtime.overlap_factor = paint_stroke_integrate_overlap(*br, 1.0);
paint_brush_stroke_add_step(C, op, stroke, sample_average.mouse, sample_average.pressure);
redraw = true;
}

View File

@@ -434,7 +434,7 @@ void update_cache_invariants(
bContext *C, VPaint &vp, SculptSession &ss, wmOperator *op, const float mval[2])
{
StrokeCache *cache;
UnifiedPaintSettings &ups = vp.paint.unified_paint_settings;
bke::PaintRuntime &paint_runtime = *vp.paint.runtime;
ViewContext *vc = paint_stroke_view_context((PaintStroke *)op->customdata);
Object &ob = *CTX_data_active_object(C);
float mat[3][3];
@@ -464,10 +464,10 @@ void update_cache_invariants(
/* not very nice, but with current events system implementation
* we can't handle brush appearance inversion hotkey separately (sergey) */
if (cache->invert) {
ups.draw_inverted = true;
paint_runtime.draw_inverted = true;
}
else {
ups.draw_inverted = false;
paint_runtime.draw_inverted = false;
}
if (cache->alt_smooth) {
@@ -565,10 +565,10 @@ void get_brush_alpha_data(const SculptSession &ss,
void last_stroke_update(const float location[3], Paint &paint)
{
UnifiedPaintSettings &ups = paint.unified_paint_settings;
ups.average_stroke_counter++;
add_v3_v3(ups.average_stroke_accum, location);
ups.last_stroke_valid = true;
bke::PaintRuntime &paint_runtime = *paint.runtime;
paint_runtime.average_stroke_counter++;
add_v3_v3(paint_runtime.average_stroke_accum, location);
paint_runtime.last_stroke_valid = true;
}
/* -------------------------------------------------------------------- */

View File

@@ -59,6 +59,7 @@
#include "BKE_object_types.hh"
#include "BKE_paint.hh"
#include "BKE_paint_bvh.hh"
#include "BKE_paint_types.hh"
#include "BKE_report.hh"
#include "BKE_subdiv_ccg.hh"
#include "BKE_subsurf.hh"
@@ -2157,16 +2158,16 @@ static float brush_flip(const Brush &brush, const blender::ed::sculpt_paint::Str
static float brush_strength(const Sculpt &sd,
const blender::ed::sculpt_paint::StrokeCache &cache,
const float feather,
const UnifiedPaintSettings &ups,
const PaintModeSettings & /*paint_mode_settings*/)
{
const Brush &brush = *BKE_paint_brush_for_read(&sd.paint);
const blender::bke::PaintRuntime &paint_runtime = *sd.paint.runtime;
/* Primary strength input; square it to make lower values more sensitive. */
const float root_alpha = BKE_brush_alpha_get(&sd.paint, &brush);
const float alpha = root_alpha * root_alpha;
const float pressure = BKE_brush_use_alpha_pressure(&brush) ? cache.pressure : 1.0f;
float overlap = ups.overlap_factor;
float overlap = paint_runtime.overlap_factor;
/* Spacing is integer percentage of radius, divide by 50 to get
* normalized diameter. */
@@ -2988,10 +2989,9 @@ namespace blender::ed::sculpt_paint {
static void dynamic_topology_update(const Depsgraph &depsgraph,
const Scene & /*scene*/,
const Sculpt &sd,
Sculpt &sd,
Object &ob,
const Brush &brush,
UnifiedPaintSettings & /*ups*/,
PaintModeSettings & /*paint_mode_settings*/)
{
SculptSession &ss = *ob.sculpt;
@@ -3177,10 +3177,9 @@ static void push_undo_nodes(const Depsgraph &depsgraph,
static void do_brush_action(const Depsgraph &depsgraph,
const Scene & /*scene*/,
const Sculpt &sd,
Sculpt &sd,
Object &ob,
const Brush &brush,
UnifiedPaintSettings &ups,
PaintModeSettings &paint_mode_settings)
{
SculptSession &ss = *ob.sculpt;
@@ -3433,10 +3432,11 @@ static void do_brush_action(const Depsgraph &depsgraph,
/* Update average stroke position. */
const float3 world_location = math::project_point(ob.object_to_world(), ss.cache->location);
add_v3_v3(ups.average_stroke_accum, world_location);
ups.average_stroke_counter++;
bke::PaintRuntime &paint_runtime = *sd.paint.runtime;
add_v3_v3(paint_runtime.average_stroke_accum, world_location);
paint_runtime.average_stroke_counter++;
/* Update last stroke position. */
ups.last_stroke_valid = true;
paint_runtime.last_stroke_valid = true;
}
} // namespace blender::ed::sculpt_paint
@@ -3503,18 +3503,16 @@ namespace blender::ed::sculpt_paint {
using BrushActionFunc = void (*)(const Depsgraph &depsgraph,
const Scene &scene,
const Sculpt &sd,
Sculpt &sd,
Object &ob,
const Brush &brush,
UnifiedPaintSettings &ups,
PaintModeSettings &paint_mode_settings);
static void do_tiled(const Depsgraph &depsgraph,
const Scene &scene,
const Sculpt &sd,
Sculpt &sd,
Object &ob,
const Brush &brush,
UnifiedPaintSettings &ups,
PaintModeSettings &paint_mode_settings,
const BrushActionFunc action)
{
@@ -3550,7 +3548,7 @@ static void do_tiled(const Depsgraph &depsgraph,
/* First do the "un-tiled" position to initialize the stroke for this location. */
cache->tile_pass = 0;
action(depsgraph, scene, sd, ob, brush, ups, paint_mode_settings);
action(depsgraph, scene, sd, ob, brush, paint_mode_settings);
/* Now do it for all the tiles. */
copy_v3_v3_int(cur, start);
@@ -3570,7 +3568,7 @@ static void do_tiled(const Depsgraph &depsgraph,
cache->initial_location_symm[dim] = cur[dim] * step[dim] +
original_initial_location[dim];
}
action(depsgraph, scene, sd, ob, brush, ups, paint_mode_settings);
action(depsgraph, scene, sd, ob, brush, paint_mode_settings);
}
}
}
@@ -3578,10 +3576,9 @@ static void do_tiled(const Depsgraph &depsgraph,
static void do_radial_symmetry(const Depsgraph &depsgraph,
const Scene &scene,
const Sculpt &sd,
Sculpt &sd,
Object &ob,
const Brush &brush,
UnifiedPaintSettings &ups,
PaintModeSettings &paint_mode_settings,
const BrushActionFunc action,
const ePaintSymmetryFlags symm,
@@ -3595,7 +3592,7 @@ static void do_radial_symmetry(const Depsgraph &depsgraph,
const float angle = 2.0f * M_PI * i / mesh.radial_symmetry[axis - 'X'];
ss.cache->radial_symmetry_pass = i;
SCULPT_cache_calc_brushdata_symm(*ss.cache, symm, axis, angle);
do_tiled(depsgraph, scene, sd, ob, brush, ups, paint_mode_settings, action);
do_tiled(depsgraph, scene, sd, ob, brush, paint_mode_settings, action);
}
}
@@ -3616,10 +3613,9 @@ static void sculpt_fix_noise_tear(const Sculpt &sd, Object &ob)
static void do_symmetrical_brush_actions(const Depsgraph &depsgraph,
const Scene &scene,
const Sculpt &sd,
Sculpt &sd,
Object &ob,
const BrushActionFunc action,
UnifiedPaintSettings &ups,
PaintModeSettings &paint_mode_settings)
{
const Brush &brush = *BKE_paint_brush_for_read(&sd.paint);
@@ -3630,7 +3626,7 @@ static void do_symmetrical_brush_actions(const Depsgraph &depsgraph,
float feather = calc_symmetry_feather(sd, mesh, *ss.cache);
cache.bstrength = brush_strength(sd, cache, feather, ups, paint_mode_settings);
cache.bstrength = brush_strength(sd, cache, feather, paint_mode_settings);
cache.symmetry = symm;
/* `symm` is a bit combination of XYZ -
@@ -3644,14 +3640,14 @@ static void do_symmetrical_brush_actions(const Depsgraph &depsgraph,
cache.radial_symmetry_pass = 0;
SCULPT_cache_calc_brushdata_symm(cache, symm, 0, 0);
do_tiled(depsgraph, scene, sd, ob, brush, ups, paint_mode_settings, action);
do_tiled(depsgraph, scene, sd, ob, brush, paint_mode_settings, action);
do_radial_symmetry(
depsgraph, scene, sd, ob, brush, ups, paint_mode_settings, action, symm, 'X', feather);
depsgraph, scene, sd, ob, brush, paint_mode_settings, action, symm, 'X', feather);
do_radial_symmetry(
depsgraph, scene, sd, ob, brush, ups, paint_mode_settings, action, symm, 'Y', feather);
depsgraph, scene, sd, ob, brush, paint_mode_settings, action, symm, 'Y', feather);
do_radial_symmetry(
depsgraph, scene, sd, ob, brush, ups, paint_mode_settings, action, symm, 'Z', feather);
depsgraph, scene, sd, ob, brush, paint_mode_settings, action, symm, 'Z', feather);
}
}
@@ -3923,7 +3919,7 @@ static void sculpt_update_cache_invariants(
bContext *C, Sculpt &sd, SculptSession &ss, const wmOperator &op, const float mval[2])
{
StrokeCache *cache = MEM_new<StrokeCache>(__func__);
UnifiedPaintSettings *ups = &sd.paint.unified_paint_settings;
bke::PaintRuntime *paint_runtime = sd.paint.runtime;
ToolSettings *tool_settings = CTX_data_tool_settings(C);
const Brush *brush = BKE_paint_brush_for_read(&sd.paint);
ViewContext *vc = paint_stroke_view_context(static_cast<PaintStroke *>(op.customdata));
@@ -3973,10 +3969,10 @@ static void sculpt_update_cache_invariants(
/* Not very nice, but with current events system implementation
* we can't handle brush appearance inversion hotkey separately (sergey). */
if (cache->invert) {
ups->draw_inverted = true;
paint_runtime->draw_inverted = true;
}
else {
ups->draw_inverted = false;
paint_runtime->draw_inverted = false;
}
/* Alt-Smooth. */
@@ -3988,7 +3984,7 @@ static void sculpt_update_cache_invariants(
cache->mouse = cache->initial_mouse;
cache->mouse_event = cache->initial_mouse;
copy_v2_v2(ups->tex_mouse, cache->initial_mouse);
copy_v2_v2(paint_runtime->tex_mouse, cache->initial_mouse);
cache->initial_direction_flipped = brush_flip(*brush, *cache) < 0.0f;
@@ -4123,10 +4119,11 @@ static bool need_delta_for_tip_orientation(const Brush &brush)
}
static void brush_delta_update(const Depsgraph &depsgraph,
UnifiedPaintSettings &ups,
Paint &paint,
const Object &ob,
const Brush &brush)
{
bke::PaintRuntime &paint_runtime = *paint.runtime;
SculptSession &ss = *ob.sculpt;
const bke::pbvh::Tree &pbvh = *bke::object::pbvh_get(ob);
StrokeCache *cache = ss.cache;
@@ -4222,9 +4219,9 @@ static void brush_delta_update(const Depsgraph &depsgraph,
/* Location stays the same for finding vertices in brush radius. */
copy_v3_v3(cache->location, cache->orig_grab_location);
ups.draw_anchored = true;
copy_v2_v2(ups.anchored_initial_mouse, cache->initial_mouse);
ups.anchored_size = ups.pixel_radius;
paint_runtime.draw_anchored = true;
copy_v2_v2(paint_runtime.anchored_initial_mouse, cache->initial_mouse);
paint_runtime.anchored_size = paint_runtime.pixel_radius;
}
/* Handle 'rake' */
@@ -4318,7 +4315,7 @@ static void sculpt_update_cache_variants(bContext *C, Sculpt &sd, Object &ob, Po
{
const Depsgraph &depsgraph = *CTX_data_depsgraph_pointer(C);
Paint &paint = *BKE_paint_get_active_from_context(C);
UnifiedPaintSettings &ups = paint.unified_paint_settings;
bke::PaintRuntime &paint_runtime = *paint.runtime;
SculptSession &ss = *ob.sculpt;
StrokeCache &cache = *ss.cache;
Brush &brush = *BKE_paint_brush(&sd.paint);
@@ -4375,11 +4372,12 @@ static void sculpt_update_cache_variants(bContext *C, Sculpt &sd, Object &ob, Po
if (BKE_brush_use_size_pressure(&brush) && paint_supports_dynamic_size(brush, PaintMode::Sculpt))
{
cache.radius = brush_dynamic_size_get(brush, cache, cache.initial_radius);
cache.dyntopo_pixel_radius = brush_dynamic_size_get(brush, cache, ups.initial_pixel_radius);
cache.dyntopo_pixel_radius = brush_dynamic_size_get(
brush, cache, paint_runtime.initial_pixel_radius);
}
else {
cache.radius = cache.initial_radius;
cache.dyntopo_pixel_radius = ups.initial_pixel_radius;
cache.dyntopo_pixel_radius = paint_runtime.initial_pixel_radius;
}
cache_paint_invariants_update(cache, brush);
@@ -4392,21 +4390,22 @@ static void sculpt_update_cache_variants(bContext *C, Sculpt &sd, Object &ob, Po
RNA_float_get_array(ptr, "location", cache.location);
}
cache.radius = paint_calc_object_space_radius(*cache.vc, cache.location, ups.pixel_radius);
cache.radius = paint_calc_object_space_radius(
*cache.vc, cache.location, paint_runtime.pixel_radius);
cache.radius_squared = cache.radius * cache.radius;
}
brush_delta_update(depsgraph, ups, ob, brush);
brush_delta_update(depsgraph, paint, ob, brush);
if (brush.sculpt_brush_type == SCULPT_BRUSH_TYPE_ROTATE) {
cache.vertex_rotation = -BLI_dial_angle(cache.dial, cache.mouse) * cache.bstrength;
ups.draw_anchored = true;
copy_v2_v2(ups.anchored_initial_mouse, cache.initial_mouse);
ups.anchored_size = ups.pixel_radius;
paint_runtime.draw_anchored = true;
copy_v2_v2(paint_runtime.anchored_initial_mouse, cache.initial_mouse);
paint_runtime.anchored_size = paint_runtime.pixel_radius;
}
cache.special_rotation = ups.brush_rotation;
cache.special_rotation = paint_runtime.brush_rotation;
cache.iteration_count++;
}
@@ -5510,7 +5509,6 @@ static void stroke_update_step(bContext *C,
const Scene &scene = *CTX_data_scene(C);
const Depsgraph &depsgraph = *CTX_data_depsgraph_pointer(C);
Sculpt &sd = *CTX_data_tool_settings(C)->sculpt;
UnifiedPaintSettings &ups = sd.paint.unified_paint_settings;
Object &ob = *CTX_data_active_object(C);
SculptSession &ss = *ob.sculpt;
const Brush &brush = *BKE_paint_brush_for_read(&sd.paint);
@@ -5524,11 +5522,11 @@ static void stroke_update_step(bContext *C,
if (dyntopo::stroke_is_dyntopo(ob, brush)) {
do_symmetrical_brush_actions(
depsgraph, scene, sd, ob, dynamic_topology_update, ups, tool_settings.paint_mode);
depsgraph, scene, sd, ob, dynamic_topology_update, tool_settings.paint_mode);
}
do_symmetrical_brush_actions(
depsgraph, scene, sd, ob, do_brush_action, ups, tool_settings.paint_mode);
depsgraph, scene, sd, ob, do_brush_action, tool_settings.paint_mode);
/* Hack to fix noise texture tearing mesh. */
sculpt_fix_noise_tear(sd, ob);
@@ -5575,10 +5573,10 @@ static void stroke_done(const bContext *C, PaintStroke * /*stroke*/)
brush_exit_tex(sd);
return;
}
UnifiedPaintSettings *ups = &sd.paint.unified_paint_settings;
bke::PaintRuntime *paint_runtime = sd.paint.runtime;
Brush *brush = BKE_paint_brush(&sd.paint);
BLI_assert(brush == ss.cache->brush); /* const, so we shouldn't change. */
ups->draw_inverted = false;
paint_runtime->draw_inverted = false;
SCULPT_stroke_modifiers_check(C, ob, *brush);

View File

@@ -44,6 +44,7 @@
#include "BKE_object.hh"
#include "BKE_paint.hh"
#include "BKE_paint_bvh.hh"
#include "BKE_paint_types.hh"
#include "BKE_subdiv_ccg.hh"
#include "DEG_depsgraph.hh"
@@ -1065,17 +1066,17 @@ static wmOperatorStatus change_visibility_exec(bContext *C, wmOperator *op)
* navigation. */
if (ELEM(mode, VisibilityMode::Toggle, VisibilityMode::ShowActive)) {
Paint *paint = BKE_paint_get_active_from_context(C);
UnifiedPaintSettings *ups = &paint->unified_paint_settings;
bke::PaintRuntime *paint_runtime = paint->runtime;
if (std::holds_alternative<std::monostate>(ss.active_vert())) {
ups->last_stroke_valid = false;
paint_runtime->last_stroke_valid = false;
}
else {
float location[3];
copy_v3_v3(location, ss.active_vert_position(depsgraph, object));
mul_m4_v3(object.object_to_world().ptr(), location);
copy_v3_v3(ups->average_stroke_accum, location);
ups->average_stroke_counter = 1;
ups->last_stroke_valid = true;
copy_v3_v3(paint_runtime->average_stroke_accum, location);
paint_runtime->average_stroke_counter = 1;
paint_runtime->last_stroke_valid = true;
}
}

View File

@@ -32,6 +32,7 @@
#include "BKE_object_types.hh"
#include "BKE_paint.hh"
#include "BKE_paint_bvh.hh"
#include "BKE_paint_types.hh"
#include "WM_api.hh"
#include "WM_types.hh"
@@ -161,7 +162,8 @@ void cache_init(bContext *C,
copy_m4_m4(ss.filter_cache->viewmat_inv.ptr(), vc.rv3d->viewinv);
}
UnifiedPaintSettings *ups = &sd.paint.unified_paint_settings;
const UnifiedPaintSettings *ups = &sd.paint.unified_paint_settings;
bke::PaintRuntime *paint_runtime = sd.paint.runtime;
float3 co;
@@ -198,9 +200,9 @@ void cache_init(bContext *C,
mul_m4_v3(ob.object_to_world().ptr(), co);
add_v3_v3(ups->average_stroke_accum, co);
ups->average_stroke_counter++;
ups->last_stroke_valid = true;
add_v3_v3(paint_runtime->average_stroke_accum, co);
paint_runtime->average_stroke_counter++;
paint_runtime->last_stroke_valid = true;
}
else {
/* Use last normal. */

View File

@@ -33,6 +33,7 @@
#include "BKE_object.hh"
#include "BKE_paint.hh"
#include "BKE_paint_bvh.hh"
#include "BKE_paint_types.hh"
#include "BKE_report.hh"
#include "BKE_scene.hh"
#include "BKE_subdiv_ccg.hh"
@@ -358,7 +359,7 @@ static void init_sculpt_mode_session(Main &bmain, Depsgraph &depsgraph, Scene &s
void ensure_valid_pivot(const Object &ob, Paint &paint)
{
UnifiedPaintSettings &ups = paint.unified_paint_settings;
bke::PaintRuntime &paint_runtime = *paint.runtime;
const bke::pbvh::Tree *pbvh = bke::object::pbvh_get(ob);
/* Account for the case where no objects are evaluated. */
@@ -367,16 +368,16 @@ void ensure_valid_pivot(const Object &ob, Paint &paint)
}
/* No valid pivot? Use bounding box center. */
if (ups.average_stroke_counter == 0 || !ups.last_stroke_valid) {
if (paint_runtime.average_stroke_counter == 0 || !paint_runtime.last_stroke_valid) {
const Bounds<float3> bounds = bke::pbvh::bounds_get(*pbvh);
const float3 center = math::midpoint(bounds.min, bounds.max);
const float3 location = math::transform_point(ob.object_to_world(), center);
copy_v3_v3(ups.average_stroke_accum, location);
ups.average_stroke_counter = 1;
copy_v3_v3(paint_runtime.average_stroke_accum, location);
paint_runtime.average_stroke_counter = 1;
/* Update last stroke position. */
ups.last_stroke_valid = true;
paint_runtime.last_stroke_valid = true;
}
}

View File

@@ -25,6 +25,7 @@
#include "BKE_mesh.hh"
#include "BKE_paint.hh"
#include "BKE_paint_bvh.hh"
#include "BKE_paint_types.hh"
#include "BKE_subdiv_ccg.hh"
#include "WM_api.hh"
@@ -954,10 +955,10 @@ static wmOperatorStatus set_pivot_position_exec(bContext *C, wmOperator *op)
/* Update the viewport navigation rotation origin. */
Paint *paint = BKE_paint_get_active_from_context(C);
UnifiedPaintSettings *ups = &paint->unified_paint_settings;
copy_v3_v3(ups->average_stroke_accum, ss.pivot_pos);
ups->average_stroke_counter = 1;
ups->last_stroke_valid = true;
bke::PaintRuntime *paint_runtime = paint->runtime;
copy_v3_v3(paint_runtime->average_stroke_accum, ss.pivot_pos);
paint_runtime->average_stroke_counter = 1;
paint_runtime->last_stroke_valid = true;
ED_region_tag_redraw(region);
WM_event_add_notifier(C, NC_GEOM | ND_SELECT, ob.data);

View File

@@ -1058,73 +1058,6 @@ typedef struct UnifiedPaintSettings {
/** User preferences for sculpt and paint. */
int flag;
char _pad[4];
/* TODO: Many of the following values should not be on this struct, as it causes them to be
* persisted. PaintRuntime may be a better choice for some of these. */
/* Rake rotation. */
/** Record movement of mouse so that rake can start at an intuitive angle. */
float last_rake[2];
float last_rake_angle;
int last_stroke_valid;
float average_stroke_accum[3];
int average_stroke_counter;
/* How much brush should be rotated in the view plane, 0 means x points right, y points up.
* The convention is that the brush's _negative_ Y axis points in the tangent direction (of the
* mouse curve, Bezier curve, etc.) */
float brush_rotation;
float brush_rotation_sec;
/*******************************************************************************
* all data below are used to communicate with cursor drawing and tex sampling *
*******************************************************************************/
int anchored_size;
/**
* Normalization factor due to accumulated value of curve along spacing.
* Calculated when brush spacing changes to dampen strength of stroke
* if space attenuation is used.
*/
float overlap_factor;
char draw_inverted;
/** Check is there an ongoing stroke right now. */
char stroke_active;
char draw_anchored;
char do_linear_conversion;
/**
* Store last location of stroke or whether the mesh was hit.
* Valid only while stroke is active.
*/
float last_location[3];
int last_hit;
float anchored_initial_mouse[2];
/**
* Radius of brush, pre-multiplied with pressure.
* In case of anchored brushes contains the anchored radius.
*/
float pixel_radius;
float initial_pixel_radius;
float start_pixel_radius;
/** Drawing pressure. */
float size_pressure_value;
/** Position of mouse, used to sample the texture. */
float tex_mouse[2];
/** Position of mouse, used to sample the mask texture. */
float mask_tex_mouse[2];
/** ColorSpace cache to avoid locking up during sampling. */
const ColorSpaceHandle *colorspace;
} UnifiedPaintSettings;
/** \} */