Blender V4.3
workbench_state.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2023 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
6
7#include "BKE_camera.h"
8#include "BKE_editmesh.hh"
9#include "BKE_mesh_types.hh"
10#include "BKE_modifier.hh"
11#include "BKE_object.hh"
12#include "BKE_paint.hh"
13#include "BKE_particle.h"
14#include "BKE_pbvh_api.hh"
15
17#include "DNA_fluid_types.h"
18#include "ED_paint.hh"
19#include "ED_view3d.hh"
20#include "GPU_capabilities.hh"
21
22namespace blender::workbench {
23
24void SceneState::init(Object *camera_ob /*=nullptr*/)
25{
26 bool reset_taa = reset_taa_next_sample;
28
29 const DRWContextState *context = DRW_context_state_get();
30 View3D *v3d = context->v3d;
31 RegionView3D *rv3d = context->rv3d;
32
33 scene = DEG_get_evaluated_scene(context->depsgraph);
34
36 /* In some cases, the viewport can change resolution without a call to `workbench_view_update`.
37 * This is the case when dragging a window between two screen with different DPI settings.
38 * (See #128712) */
39 reset_taa = true;
40 }
41
42 camera_object = camera_ob;
43 if (camera_object == nullptr && v3d && rv3d) {
44 camera_object = (rv3d->persp == RV3D_CAMOB) ? v3d->camera : nullptr;
45 }
47 static_cast<Camera *>(camera_object->data) :
48 nullptr;
49
50 object_mode = CTX_data_mode_enum_ex(context->object_edit, context->obact, context->object_mode);
51
52 /* TODO(@pragma37):
53 * Check why Workbench Next exposes OB_MATERIAL, and Workbench exposes OB_RENDER */
54 bool is_render_mode = !v3d || ELEM(v3d->shading.type, OB_RENDER, OB_MATERIAL);
55
56 const View3DShading previous_shading = shading;
57 shading = is_render_mode ? scene->display.shading : v3d->shading;
58
61
62 /* FIXME: This reproduce old behavior when workbench was separated in 2 engines.
63 * But this is a workaround for a missing update tagging. */
64 DRWState new_clip_state = RV3D_CLIPPING_ENABLED(v3d, rv3d) ? DRW_STATE_CLIP_PLANES :
66 DRWState old_clip_state = clip_planes.size() > 0 ? DRW_STATE_CLIP_PLANES : DRW_STATE_NO_DRAW;
67 if (new_clip_state != old_clip_state) {
68 reset_taa = true;
69 }
70 clip_planes.clear();
71 if (new_clip_state & DRW_STATE_CLIP_PLANES) {
72 int plane_len = (RV3D_LOCK_FLAGS(rv3d) & RV3D_BOXCLIP) ? 4 : 6;
73 for (auto i : IndexRange(plane_len)) {
74 clip_planes.append(rv3d->clip[i]);
75 }
76 }
77
78 if (shading.type < OB_SOLID) {
79 shading.light = V3D_LIGHTING_FLAT;
80 shading.color_type = V3D_SHADING_OBJECT_COLOR;
81 shading.xray_alpha = 0.0f;
82 }
83 else if (SHADING_XRAY_ENABLED(shading)) {
84 shading.xray_alpha = SHADING_XRAY_ALPHA(shading);
85 }
86 else {
87 shading.xray_alpha = 1.0f;
88 }
89 xray_mode = shading.xray_alpha != 1.0f;
90
91 if (xray_mode) {
92 /* Disable shading options that aren't supported in transparency mode. */
94 }
95 if (SHADING_XRAY_ENABLED(shading) != SHADING_XRAY_ENABLED(previous_shading) ||
96 shading.flag != previous_shading.flag)
97 {
98 reset_taa = true;
99 }
100
102 material_override = Material(shading.single_color);
103
104 background_color = float4(0.0f);
105 if (is_render_mode && scene->r.alphamode != R_ALPHAPREMUL) {
106 if (World *w = scene->world) {
107 background_color = float4(w->horr, w->horg, w->horb, 1.0f);
108 }
109 }
110
111 if (rv3d && rv3d->rflag & RV3D_GPULIGHT_UPDATE) {
112 reset_taa = true;
113 /* FIXME: This reproduce old behavior when workbench was separated in 2 engines.
114 * But this is a workaround for a missing update tagging. */
115 rv3d->rflag &= ~RV3D_GPULIGHT_UPDATE;
116 }
117
118 float4x4 matrix;
119 /* TODO(@pragma37): New API? */
120 DRW_view_persmat_get(nullptr, matrix.ptr(), false);
121 if (matrix != view_projection_matrix) {
122 view_projection_matrix = matrix;
123 reset_taa = true;
124 }
125
126 bool is_playback = DRW_state_is_playback();
127 bool is_navigating = DRW_state_is_navigating();
128
129 /* Reset complete drawing when navigating or during viewport playback or when
130 * leaving one of those states. In case of multires modifier the navigation
131 * mesh differs from the viewport mesh, so we need to be sure to restart. */
132 if (is_playback || is_navigating) {
133 reset_taa = true;
135 }
136
137 int _samples_len = U.viewport_aa;
138 if (v3d && ELEM(v3d->shading.type, OB_RENDER, OB_MATERIAL)) {
139 _samples_len = scene->display.viewport_aa;
140 }
141 else if (DRW_state_is_scene_render()) {
142 _samples_len = scene->display.render_aa;
143 }
144 if (is_navigating || is_playback) {
145 /* Only draw using SMAA or no AA when navigating. */
146 _samples_len = min_ii(_samples_len, 1);
147 }
148 /* 0 samples means no AA */
149 draw_aa = _samples_len > 0;
150 _samples_len = max_ii(_samples_len, 1);
151
152 /* Reset the TAA when we have already draw a sample, but the sample count differs from previous
153 * time. This removes render artifacts when the viewport anti-aliasing in the user preferences
154 * is set to a lower value. */
155 if (samples_len != _samples_len) {
156 samples_len = _samples_len;
157 reset_taa = true;
158 }
159
160 if (reset_taa || samples_len <= 1) {
161 sample = 0;
162 }
163 else {
164 sample++;
165 }
167
168 /* TODO(@pragma37): volumes_do */
169
170 draw_cavity = shading.flag & V3D_SHADING_CAVITY &&
172 draw_curvature = shading.flag & V3D_SHADING_CAVITY && ELEM(shading.cavity_type,
175 draw_shadows = shading.flag & V3D_SHADING_SHADOW;
177 draw_dof = camera && camera->dof.flag & CAM_DOF_ENABLED &&
178 shading.flag & V3D_SHADING_DEPTH_OF_FIELD;
179
181};
182
183static const CustomData *get_loop_custom_data(const Mesh *mesh)
184{
185 if (mesh->runtime->wrapper_type == ME_WRAPPER_TYPE_BMESH) {
186 BLI_assert(mesh->runtime->edit_mesh != nullptr);
187 BLI_assert(mesh->runtime->edit_mesh->bm != nullptr);
188 return &mesh->runtime->edit_mesh->bm->ldata;
189 }
190 return &mesh->corner_data;
191}
192
193static const CustomData *get_vert_custom_data(const Mesh *mesh)
194{
195 if (mesh->runtime->wrapper_type == ME_WRAPPER_TYPE_BMESH) {
196 BLI_assert(mesh->runtime->edit_mesh != nullptr);
197 BLI_assert(mesh->runtime->edit_mesh->bm != nullptr);
198 return &mesh->runtime->edit_mesh->bm->vdata;
199 }
200 return &mesh->vert_data;
201}
202
204 const SceneResources &resources,
205 Object *ob)
206{
207 const DRWContextState *draw_ctx = DRW_context_state_get();
208 const bool is_active = (ob == draw_ctx->obact);
209
212 draw_shadow = scene_state.draw_shadows && (ob->dtx & OB_DRAW_NO_SHADOW_CAST) == 0 &&
213 !sculpt_pbvh && !(is_active && DRW_object_use_hide_faces(ob));
214
216
217 bool has_color = false;
218 bool has_uv = false;
219
220 if (ob->type == OB_MESH) {
221 const Mesh *mesh = static_cast<Mesh *>(ob->data);
222 const CustomData *cd_vdata = get_vert_custom_data(mesh);
223 const CustomData *cd_ldata = get_loop_custom_data(mesh);
224
225 has_color = (CustomData_has_layer(cd_vdata, CD_PROP_COLOR) ||
229
230 has_uv = CustomData_has_layer(cd_ldata, CD_PROP_FLOAT2);
231 }
232
233 if (color_type == V3D_SHADING_TEXTURE_COLOR && (!has_uv || ob->dt < OB_TEXTURE)) {
235 }
236 else if (color_type == V3D_SHADING_VERTEX_COLOR && !has_color) {
238 }
239
240 if (sculpt_pbvh) {
243 {
244 /* Force use of material color for sculpt. */
246 }
247
248 /* Bad call C is required to access the tool system that is context aware. Cast to non-const
249 * due to current API. */
251 if (C != nullptr) {
253 C, &scene_state.scene->toolsettings->paint_mode, *ob, color_type);
254 }
255 }
256 else if (ob->type == OB_MESH && !DRW_state_is_scene_render()) {
257 /* Force texture or vertex mode if object is in paint mode. */
258 const bool is_vertpaint_mode = is_active && (scene_state.object_mode == CTX_MODE_PAINT_VERTEX);
259 const bool is_texpaint_mode = is_active && (scene_state.object_mode == CTX_MODE_PAINT_TEXTURE);
260 if (is_vertpaint_mode && has_color) {
262 }
263 else if (is_texpaint_mode && has_uv) {
266 const ImagePaintSettings *imapaint = &scene_state.scene->toolsettings->imapaint;
267 if (imapaint->mode == IMAGEPAINT_MODE_IMAGE) {
268 if (imapaint->canvas) {
272 const bool use_linear_filter = imapaint->interp == IMAGEPAINT_INTERP_LINEAR;
274 GPU_SAMPLER_FILTERING_LINEAR, use_linear_filter);
275 }
276 else {
278 }
279 }
280 }
281 }
282
287}
288
289} // namespace blender::workbench
Camera data-block and utility functions.
@ CTX_MODE_PAINT_TEXTURE
@ CTX_MODE_PAINT_VERTEX
enum eContextObjectMode CTX_data_mode_enum_ex(const Object *obedit, const Object *ob, eObjectMode object_mode)
bool CustomData_has_layer(const CustomData *data, eCustomDataType type)
@ ME_WRAPPER_TYPE_BMESH
General operations, lookup, etc. for blender objects.
bool BKE_sculptsession_use_pbvh_draw(const Object *ob, const RegionView3D *rv3d)
Definition paint.cc:2862
A BVH for high poly meshes.
#define BLI_assert(a)
Definition BLI_assert.h:50
MINLINE int min_ii(int a, int b)
MINLINE int max_ii(int a, int b)
#define ELEM(...)
Scene * DEG_get_evaluated_scene(const Depsgraph *graph)
@ CAM_DOF_ENABLED
@ CD_PROP_BYTE_COLOR
@ CD_PROP_COLOR
@ CD_PROP_FLOAT2
struct Material Material
@ OB_TEXTURE
@ OB_SOLID
@ OB_RENDER
@ OB_MATERIAL
@ OB_CAMERA
@ OB_MESH
@ OB_DRAW_NO_SHADOW_CAST
@ IMAGEPAINT_INTERP_LINEAR
#define IMAGEPAINT_MODE_IMAGE
@ R_ALPHAPREMUL
eV3DShadingColorType
@ V3D_SHADING_TEXTURE_COLOR
@ V3D_SHADING_VERTEX_COLOR
@ V3D_SHADING_MATERIAL_COLOR
@ V3D_SHADING_OBJECT_COLOR
@ V3D_LIGHTING_FLAT
#define RV3D_LOCK_FLAGS(rv3d)
@ RV3D_GPULIGHT_UPDATE
#define RV3D_CLIPPING_ENABLED(v3d, rv3d)
@ V3D_SHADING_SHADOW
@ V3D_SHADING_DEPTH_OF_FIELD
@ V3D_SHADING_OBJECT_OUTLINE
@ V3D_SHADING_CAVITY
@ V3D_SHADING_BACKFACE_CULLING
@ V3D_SHADING_CAVITY_BOTH
@ V3D_SHADING_CAVITY_SSAO
@ V3D_SHADING_CAVITY_CURVATURE
@ RV3D_CAMOB
@ RV3D_BOXCLIP
eV3DShadingColorType ED_paint_shading_color_override(bContext *C, const PaintModeSettings *settings, Object &ob, eV3DShadingColorType orig_color_type)
#define SHADING_XRAY_ALPHA(shading)
#define SHADING_XRAY_ENABLED(shading)
@ GPU_SAMPLER_EXTEND_MODE_REPEAT
@ GPU_SAMPLER_FILTERING_LINEAR
unsigned int U
Definition btGjkEpa3.h:78
SIMD_FORCE_INLINE const btScalar & w() const
Return the w value.
Definition btQuadWord.h:119
const float * DRW_viewport_size_get()
bool DRW_object_use_hide_faces(const Object *ob)
bool DRW_state_is_image_render()
bool DRW_state_is_scene_render()
const DRWContextState * DRW_context_state_get()
bool DRW_state_is_navigating()
bool DRW_state_is_playback()
void DRW_view_persmat_get(const DRWView *view, float mat[4][4], bool inverse)
DRWState
Definition draw_state.hh:25
@ DRW_STATE_CLIP_PLANES
Definition draw_state.hh:69
@ DRW_STATE_NO_DRAW
Definition draw_state.hh:27
@ DRW_STATE_CULL_BACK
Definition draw_state.hh:43
pbvh::Tree * pbvh_get(Object &object)
Definition paint.cc:2846
static const CustomData * get_loop_custom_data(const Mesh *mesh)
static const CustomData * get_vert_custom_data(const Mesh *mesh)
static eLightingType lighting_type_from_v3d_lighting(char lighting)
bool assign_if_different(T &old_value, T new_value)
VecBase< float, 4 > float4
VecBase< int32_t, 2 > int2
VecBase< float, 2 > float2
const bContext * evil_C
RegionView3D * rv3d
GPUSamplerExtendMode extend_yz
GPUSamplerExtendMode extend_x
void set_filtering_flag_from_test(GPUSamplerFiltering filtering_flags, bool test)
GPUTexture * texture
Definition BKE_image.hh:583
struct Image * canvas
float clip[6][4]
struct ToolSettings * toolsettings
struct ImagePaintSettings imapaint
struct PaintModeSettings paint_mode
struct Object * camera
View3DShading shading
ObjectState(const SceneState &scene_state, const SceneResources &resources, Object *ob)
void init(Object *camera_ob=nullptr)