Merge branch 'master' into sculpt-dev

This commit is contained in:
Pablo Dobarro 2021-01-29 22:44:44 +01:00
commit a2df63e996
79 changed files with 928 additions and 541 deletions

View File

@ -10,8 +10,9 @@
# Changes that belong here:
# - Massive comment, doxy-sections, or spelling corrections.
# - Clang-format, PEP8 or other automated changes which are *strictly* "no functional change".
# - Several smaller commits should be added to this list at once, because adding
# one extra commit (to edit this file) after every small cleanup is noisy.
# - Several commits should be added to this list at once, because adding
# one extra commit (to edit this file) after every cleanup is noisy.
# - No clang-tidy changes.
#
# Note:
# - The comment above the SHA should be the first line of the commit.
@ -92,78 +93,12 @@ c42a6b77b52560d257279de2cb624b4ef2c0d24c
# Cleanup: use doxy sections for imbuf
c207f7c22e1439e0b285fba5d2c072bdae23f981
# Cleanup: Clang-Tidy, modernize-use-bool-literals
af35ada2f3fa8da4d46b3a71de724d353d716820
# Cleanup: Use nullptr everywhere in fluid code
311031ecd03dbfbf43e1df672a395f24b2e7d4d3
# Cleanup: Clang-Tidy, modernize-redundant-void-arg
a331d5c99299c4514ca33c843b1c79b872f2728d
# Cleanup: Clang-Tidy modernize-use-nullptr
16732def37c5a66f3ea28dbe247b09cc6bca6677
# Cleanup: Clang-tidy, modernize-concat-nested-namespaces
4525049aa0cf818f6483dce589ac9791eb562338
# Cleanup: Clang-tidy else-after-return
ae342ed4511cf2e144dcd27ce2c635d3d536f9ad
# Cleanup: Clang-Tidy, readability-redundant-member-init
190170d4cc92ff34abe1744a10474ac4f1074086
# Cleanup: use 'filepath' instead of 'name' for ImBuf utilities
99f56b4c16323f96c0cbf54e392fb509fcac5bda
# Cleanup: clang-format
c4d8f6a4a8ddc29ed27311ed7578b3c8c31399d2
b5d310b569e07a937798a2d38539cfd290149f1c
8c846cccd6bdfd3e90a695fabbf05f53e5466a57
40d4a4cb1a6b4c3c2a486e8f2868f547530e0811
4eac03d821fa17546f562485f7d073813a5e5943
1166110a9d66af9c5a47cee2be591f50fdc445e8
# Cleanup: use preprocessor version check for PyTypeObject declaration
cd9acfed4f7674b84be965d469a367aef96f8af3
# Cycles: fix compilation of OSL shaders following API change
b980cd163a9d5d77eeffc2e353333e739fa9e719
# Cleanup: clang-tidy suppress warnings for PyTypeObject.tp_print
efd71aad4f22ec0073d80b8dd296015d3f395aa8
# Cleanup: fix wrong merge, remove extra unique_ptr.
6507449e54a167c63a72229e4d0119dd2af68ae5
# Cleanup: fix some clang tidy issues
525a042c5c7513c41240b118acca002f6c60cc12
# Fix T82520: error building freestyle with Python3.8
e118426e4695a97d67e65d69677f3c4e2db50a56
# Cleanup: Clang-tidy, readability-else-after-return
7be47dadea5066ae095c644e0b4f1f10d75f5ab3
# Cleanup: Add `r_` to return parameter
45dca05b1cd2a5ead59144c93d790fdfe7c35ee6
# Cleanup: Typo in `print_default_info` function name.
41a73909dec716642f044e60b40a28335c9fdb10
# Cleanup: Reduce indentation
1cc3a0e2cf73a5ff4f9e0a7f5338eda77266b300
# Build-system: Force C linkage for all DNA type headers
ad4b7741dba45a2be210942c18af6b6e4438f129
# Cleanup: Move function to proper section
c126e27cdc8b28365a9d5f9fafc4d521d1eb83df
# Cleanup: remove break after return statements
bbdfeb751e16d939482d2e4b95c4d470f53f18a5
# Cleanup: clang-tidy
af013ff76feef7e8b8ba642279c62a5dc275d59f
# Cleanup: Make panel type flag names more clear
9d28353b525ecfbcca1501be72e4276dfb2bbc2a
# Cleanup: clang-format.
40d4a4cb1a6b4c3c2a486e8f2868f547530e0811

View File

@ -520,7 +520,7 @@ format: .FORCE
# Simple version of ./doc/python_api/sphinx_doc_gen.sh with no PDF generation.
doc_py: .FORCE
ASAN_OPTIONS=halt_on_error=0 \
ASAN_OPTIONS=halt_on_error=0:${ASAN_OPTIONS} \
$(BLENDER_BIN) --background -noaudio --factory-startup \
--python doc/python_api/sphinx_doc_gen.py
sphinx-build -b html -j $(NPROCS) doc/python_api/sphinx-in doc/python_api/sphinx-out

View File

@ -99,7 +99,9 @@ macro(BLENDER_SRC_GTEST_EX)
# Don't fail tests on leaks since these often happen in external libraries
# that we can't fix.
set_tests_properties(${TARGET_NAME} PROPERTIES ENVIRONMENT LSAN_OPTIONS=exitcode=0)
set_tests_properties(${TARGET_NAME} PROPERTIES
ENVIRONMENT LSAN_OPTIONS=exitcode=0:$ENV{LSAN_OPTIONS}
)
endif()
if(WIN32)
set_target_properties(${TARGET_NAME} PROPERTIES VS_GLOBAL_VcpkgEnabled "false")

View File

@ -52,10 +52,11 @@ outfilename = sys.argv[2]
cmd = [blender_bin, "--help"]
print(" executing:", " ".join(cmd))
ASAN_OPTIONS = "exitcode=0:" + os.environ.get("ASAN_OPTIONS", "")
blender_help = subprocess.run(
cmd, env={"ASAN_OPTIONS": "exitcode=0"}, check=True, stdout=subprocess.PIPE).stdout.decode(encoding="utf-8")
cmd, env={"ASAN_OPTIONS": ASAN_OPTIONS}, check=True, stdout=subprocess.PIPE).stdout.decode(encoding="utf-8")
blender_version = subprocess.run(
[blender_bin, "--version"], env={"ASAN_OPTIONS": "exitcode=0"}, check=True, stdout=subprocess.PIPE).stdout.decode(encoding="utf-8").strip()
[blender_bin, "--version"], env={"ASAN_OPTIONS": ASAN_OPTIONS}, check=True, stdout=subprocess.PIPE).stdout.decode(encoding="utf-8").strip()
blender_version, blender_date = (blender_version.split("build") + [None, None])[0:2]
blender_version = blender_version.rstrip().partition(" ")[2] # remove 'Blender' prefix.
if blender_date is None:

View File

@ -55,7 +55,7 @@ if $DO_EXE_BLENDER ; then
# Don't delete existing docs, now partial updates are used for quick builds.
#
# Disable ASAN error halt since it results in nonzero exit code on any minor issue.
ASAN_OPTIONS=halt_on_error=0 \
ASAN_OPTIONS=halt_on_error=0:${ASAN_OPTIONS} \
$BLENDER_BIN \
--background \
-noaudio \

View File

@ -100,7 +100,9 @@ class DenoiseParams {
neighbor_frames = 2;
clamp_input = true;
input_passes = DENOISER_INPUT_RGB_ALBEDO_NORMAL;
/* Default to color + albedo only, since normal input does not always have the desired effect
* when denoising with OptiX. */
input_passes = DENOISER_INPUT_RGB_ALBEDO;
start_sample = 0;
}

View File

@ -115,7 +115,15 @@ void Integrator::device_update(Device *device, DeviceScene *dscene, Scene *scene
}
});
if (sampling_pattern_is_modified()) {
const bool need_update_lut = ao_samples_is_modified() || diffuse_samples_is_modified() ||
glossy_samples_is_modified() || max_bounce_is_modified() ||
max_transmission_bounce_is_modified() ||
mesh_light_samples_is_modified() || method_is_modified() ||
sampling_pattern_is_modified() ||
subsurface_samples_is_modified() ||
transmission_samples_is_modified() || volume_samples_is_modified();
if (need_update_lut) {
dscene->sample_pattern_lut.tag_realloc();
}
@ -248,7 +256,7 @@ void Integrator::device_update(Device *device, DeviceScene *dscene, Scene *scene
int dimensions = PRNG_BASE_NUM + max_samples * PRNG_BOUNCE_NUM;
dimensions = min(dimensions, SOBOL_MAX_DIMENSIONS);
if (sampling_pattern_is_modified()) {
if (need_update_lut) {
if (sampling_pattern == SAMPLING_PATTERN_SOBOL) {
uint *directions = dscene->sample_pattern_lut.alloc(SOBOL_BITS * dimensions);
@ -272,6 +280,7 @@ void Integrator::device_update(Device *device, DeviceScene *dscene, Scene *scene
}
}
dscene->sample_pattern_lut.clear_modified();
clear_modified();
}
@ -292,6 +301,11 @@ void Integrator::tag_update(Scene *scene, uint32_t flag)
tag_ao_bounces_modified();
}
if ((flag & LIGHT_SAMPLES_MODIFIED) && (method == BRANCHED_PATH)) {
/* the number of light samples may affect the size of the sample_pattern_lut */
tag_sampling_pattern_modified();
}
if (filter_glossy_is_modified()) {
foreach (Shader *shader, scene->shaders) {
if (shader->has_integrator_dependency) {

View File

@ -92,6 +92,7 @@ class Integrator : public Node {
enum : uint32_t {
AO_PASS_MODIFIED = (1 << 0),
BACKGROUND_AO_MODIFIED = (1 << 1),
LIGHT_SAMPLES_MODIFIED = (1 << 2),
/* tag everything in the manager for an update */
UPDATE_ALL = ~0u,

View File

@ -164,6 +164,10 @@ void Light::tag_update(Scene *scene)
{
if (is_modified()) {
scene->light_manager->tag_update(scene, LightManager::LIGHT_MODIFIED);
if (samples_is_modified()) {
scene->integrator->tag_update(scene, Integrator::LIGHT_SAMPLES_MODIFIED);
}
}
}

View File

@ -287,6 +287,7 @@ const bTheme U_theme_default = {
.outline_width = 1,
.facedot_size = 4,
.match = RGBA(0x5680c2ff),
.active = RGBA(0x5680c2ff),
},
.space_view3d = {
.back = RGBA(0x393939ff),

View File

@ -855,6 +855,7 @@
<properties>
<ThemeProperties
match="#5680c2"
active_modifier="#5680c2ff"
>
<space>
<ThemeSpaceGeneric

View File

@ -1,3 +1,28 @@
#
# Notes on this key-map:
#
# This uses Blender's key-map, running with `legacy=True`.
#
# The intention of this key-map is to match Blender 2.7x which had many more key-map items available.
#
# There are some differences with the original Blender 2.7x key-map.
# There is no intention to change these are they are not considered significant
# enough to make a 1:1 match with the previous Blender version.
#
# These include:
#
# 3D View
# =======
#
# - Border Render (`Shift-B` -> `Ctrl-B`)
# Both `Shift-B` and `Ctrl-B` were used.
#
# Time Line/Animation Views
# =========================
#
# - Start Frame/End Frame (`S/E` -> `Ctrl-Home/Ctrl-End`)
#
import os
import bpy
from bpy.props import (

View File

@ -2556,8 +2556,8 @@ def km_sequencer(params):
{"properties": [("unselected", False)]}),
("sequencer.unmute", {"type": 'H', "value": 'PRESS', "shift": True, "alt": True},
{"properties": [("unselected", True)]}),
("sequencer.lock", {"type": 'L', "value": 'PRESS', "shift": True}, None),
("sequencer.unlock", {"type": 'L', "value": 'PRESS', "shift": True, "alt": True}, None),
("sequencer.lock", {"type": 'H', "value": 'PRESS', "ctrl": True}, None),
("sequencer.unlock", {"type": 'H', "value": 'PRESS', "ctrl": True, "alt": True}, None),
("sequencer.reassign_inputs", {"type": 'R', "value": 'PRESS'}, None),
("sequencer.reload", {"type": 'R', "value": 'PRESS', "alt": True}, None),
("sequencer.reload", {"type": 'R', "value": 'PRESS', "shift": True, "alt": True},

View File

@ -6269,17 +6269,20 @@ class VIEW3D_PT_overlay_edit_mesh(Panel):
overlay = view.overlay
display_all = overlay.show_overlays
is_any_solid_shading = not (shading.show_xray or (shading.type == 'WIREFRAME'))
col = layout.column()
col.active = display_all
split = col.split()
sub = split.column()
sub.active = not ((shading.type == 'WIREFRAME') or shading.show_xray)
sub.active = is_any_solid_shading
sub.prop(overlay, "show_edges", text="Edges")
sub = split.column()
sub.prop(overlay, "show_faces", text="Faces")
sub = split.column()
sub.active = is_any_solid_shading
sub.prop(overlay, "show_face_center", text="Center")
row = col.row(align=True)

View File

@ -127,25 +127,25 @@ class MyCustomShapeWidgetGroup(GizmoGroup):
def setup(self, context):
# Assign the 'offset' target property to the light energy.
ob = context.object
mpr = self.gizmos.new(MyCustomShapeWidget.bl_idname)
mpr.target_set_prop("offset", ob.data, "energy")
gz = self.gizmos.new(MyCustomShapeWidget.bl_idname)
gz.target_set_prop("offset", ob.data, "energy")
mpr.color = 1.0, 0.5, 1.0
mpr.alpha = 0.5
gz.color = 1.0, 0.5, 1.0
gz.alpha = 0.5
mpr.color_highlight = 1.0, 1.0, 1.0
mpr.alpha_highlight = 0.5
gz.color_highlight = 1.0, 1.0, 1.0
gz.alpha_highlight = 0.5
# units are large, so shrink to something more reasonable.
mpr.scale_basis = 0.1
mpr.use_draw_modal = True
gz.scale_basis = 0.1
gz.use_draw_modal = True
self.energy_widget = mpr
self.energy_gizmo = gz
def refresh(self, context):
ob = context.object
mpr = self.energy_widget
mpr.matrix_basis = ob.matrix_world.normalized()
gz = self.energy_gizmo
gz.matrix_basis = ob.matrix_world.normalized()
classes = (

View File

@ -34,7 +34,7 @@ def main(context, plane_co, plane_no):
class SelectSideOfPlane(Operator):
"""UV Operator description"""
"""Select all vertices on one side of a plane defined by a location and a direction"""
bl_idname = "mesh.select_side_of_plane"
bl_label = "Select Side of Plane"
bl_options = {'REGISTER', 'UNDO'}
@ -126,20 +126,20 @@ class SelectSideOfPlaneGizmoGroup(GizmoGroup):
# XXX, this may change!
op.execute(context)
mpr = self.gizmos.new("GIZMO_GT_move_3d")
mpr.target_set_handler("offset", get=move_get_cb, set=move_set_cb)
gz = self.gizmos.new("GIZMO_GT_move_3d")
gz.target_set_handler("offset", get=move_get_cb, set=move_set_cb)
mpr.use_draw_value = True
gz.use_draw_value = True
mpr.color = 0.8, 0.8, 0.8
mpr.alpha = 0.5
gz.color = 0.8, 0.8, 0.8
gz.alpha = 0.5
mpr.color_highlight = 1.0, 1.0, 1.0
mpr.alpha_highlight = 1.0
gz.color_highlight = 1.0, 1.0, 1.0
gz.alpha_highlight = 1.0
mpr.scale_basis = 0.2
gz.scale_basis = 0.2
self.widget_move = mpr
self.gizmo_move = gz
# ----
# Dial
@ -147,7 +147,7 @@ class SelectSideOfPlaneGizmoGroup(GizmoGroup):
def direction_get_cb():
op = SelectSideOfPlaneGizmoGroup.my_target_operator(context)
no_a = self.widget_dial.matrix_basis.col[1].xyz
no_a = self.gizmo_dial.matrix_basis.col[1].xyz
no_b = Vector(op.plane_no)
no_a = (no_a @ self.view_inv).xy.normalized()
@ -157,23 +157,23 @@ class SelectSideOfPlaneGizmoGroup(GizmoGroup):
def direction_set_cb(value):
op = SelectSideOfPlaneGizmoGroup.my_target_operator(context)
matrix_rotate = Matrix.Rotation(-value, 3, self.rotate_axis)
no = matrix_rotate @ self.widget_dial.matrix_basis.col[1].xyz
no = matrix_rotate @ self.gizmo_dial.matrix_basis.col[1].xyz
op.plane_no = no
op.execute(context)
mpr = self.gizmos.new("GIZMO_GT_dial_3d")
mpr.target_set_handler("offset", get=direction_get_cb, set=direction_set_cb)
mpr.draw_options = {'ANGLE_START_Y'}
gz = self.gizmos.new("GIZMO_GT_dial_3d")
gz.target_set_handler("offset", get=direction_get_cb, set=direction_set_cb)
gz.draw_options = {'ANGLE_START_Y'}
mpr.use_draw_value = True
gz.use_draw_value = True
mpr.color = 0.8, 0.8, 0.8
mpr.alpha = 0.5
gz.color = 0.8, 0.8, 0.8
gz.alpha = 0.5
mpr.color_highlight = 1.0, 1.0, 1.0
mpr.alpha_highlight = 1.0
gz.color_highlight = 1.0, 1.0, 1.0
gz.alpha_highlight = 1.0
self.widget_dial = mpr
self.gizmo_dial = gz
def draw_prepare(self, context):
from mathutils import Vector
@ -194,7 +194,7 @@ class SelectSideOfPlaneGizmoGroup(GizmoGroup):
no_y = no_z.orthogonal()
no_x = no_z.cross(no_y)
matrix = self.widget_move.matrix_basis
matrix = self.gizmo_move.matrix_basis
matrix.identity()
matrix.col[0].xyz = no_x
matrix.col[1].xyz = no_y
@ -206,7 +206,7 @@ class SelectSideOfPlaneGizmoGroup(GizmoGroup):
no_y = (no - (no.project(no_z))).normalized()
no_x = self.rotate_axis.cross(no_y)
matrix = self.widget_dial.matrix_basis
matrix = self.gizmo_dial.matrix_basis
matrix.identity()
matrix.col[0].xyz = no_x
matrix.col[1].xyz = no_y

View File

@ -24,27 +24,27 @@ class MyCameraWidgetGroup(GizmoGroup):
def setup(self, context):
# Run an operator using the dial gizmo
ob = context.object
mpr = self.gizmos.new("GIZMO_GT_dial_3d")
props = mpr.target_set_operator("transform.rotate")
gz = self.gizmos.new("GIZMO_GT_dial_3d")
props = gz.target_set_operator("transform.rotate")
props.constraint_axis = False, False, True
props.orient_type = 'LOCAL'
props.release_confirm = True
mpr.matrix_basis = ob.matrix_world.normalized()
mpr.line_width = 3
gz.matrix_basis = ob.matrix_world.normalized()
gz.line_width = 3
mpr.color = 0.8, 0.8, 0.8
mpr.alpha = 0.5
gz.color = 0.8, 0.8, 0.8
gz.alpha = 0.5
mpr.color_highlight = 1.0, 1.0, 1.0
mpr.alpha_highlight = 1.0
gz.color_highlight = 1.0, 1.0, 1.0
gz.alpha_highlight = 1.0
self.roll_widget = mpr
self.roll_gizmo = gz
def refresh(self, context):
ob = context.object
mpr = self.roll_widget
mpr.matrix_basis = ob.matrix_world.normalized()
gz = self.roll_gizmo
gz.matrix_basis = ob.matrix_world.normalized()
bpy.utils.register_class(MyCameraWidgetGroup)

View File

@ -25,23 +25,23 @@ class MyLightWidgetGroup(GizmoGroup):
def setup(self, context):
# Arrow gizmo has one 'offset' property we can assign to the light energy.
ob = context.object
mpr = self.gizmos.new("GIZMO_GT_arrow_3d")
mpr.target_set_prop("offset", ob.data, "energy")
mpr.matrix_basis = ob.matrix_world.normalized()
mpr.draw_style = 'BOX'
gz = self.gizmos.new("GIZMO_GT_arrow_3d")
gz.target_set_prop("offset", ob.data, "energy")
gz.matrix_basis = ob.matrix_world.normalized()
gz.draw_style = 'BOX'
mpr.color = 1.0, 0.5, 0.0
mpr.alpha = 0.5
gz.color = 1.0, 0.5, 0.0
gz.alpha = 0.5
mpr.color_highlight = 1.0, 0.5, 1.0
mpr.alpha_highlight = 0.5
gz.color_highlight = 1.0, 0.5, 1.0
gz.alpha_highlight = 0.5
self.energy_widget = mpr
self.energy_gizmo = gz
def refresh(self, context):
ob = context.object
mpr = self.energy_widget
mpr.matrix_basis = ob.matrix_world.normalized()
gz = self.energy_gizmo
gz.matrix_basis = ob.matrix_world.normalized()
bpy.utils.register_class(MyLightWidgetGroup)

View File

@ -147,21 +147,18 @@ enum {
G_DEBUG_DEPSGRAPH = (G_DEBUG_DEPSGRAPH_BUILD | G_DEBUG_DEPSGRAPH_EVAL | G_DEBUG_DEPSGRAPH_TAG |
G_DEBUG_DEPSGRAPH_TIME | G_DEBUG_DEPSGRAPH_UUID),
G_DEBUG_SIMDATA = (1 << 15), /* sim debug data display */
G_DEBUG_GPU_MEM = (1 << 16), /* gpu memory in status bar */
G_DEBUG_GPU = (1 << 17), /* gpu debug */
G_DEBUG_IO = (1 << 18), /* IO Debugging (for Collada, ...)*/
G_DEBUG_GPU_SHADERS = (1 << 19), /* GLSL shaders */
G_DEBUG_GPU_FORCE_WORKAROUNDS = (1 << 20), /* force gpu workarounds bypassing detections. */
G_DEBUG_XR = (1 << 21), /* XR/OpenXR messages */
G_DEBUG_XR_TIME = (1 << 22), /* XR/OpenXR timing messages */
G_DEBUG_GPU = (1 << 16), /* gpu debug */
G_DEBUG_IO = (1 << 17), /* IO Debugging (for Collada, ...)*/
G_DEBUG_GPU_FORCE_WORKAROUNDS = (1 << 18), /* force gpu workarounds bypassing detections. */
G_DEBUG_XR = (1 << 19), /* XR/OpenXR messages */
G_DEBUG_XR_TIME = (1 << 20), /* XR/OpenXR timing messages */
G_DEBUG_GHOST = (1 << 23), /* Debug GHOST module. */
G_DEBUG_GHOST = (1 << 21), /* Debug GHOST module. */
};
#define G_DEBUG_ALL \
(G_DEBUG | G_DEBUG_FFMPEG | G_DEBUG_PYTHON | G_DEBUG_EVENTS | G_DEBUG_WM | G_DEBUG_JOBS | \
G_DEBUG_FREESTYLE | G_DEBUG_DEPSGRAPH | G_DEBUG_GPU_MEM | G_DEBUG_IO | G_DEBUG_GPU_SHADERS | \
G_DEBUG_GHOST)
G_DEBUG_FREESTYLE | G_DEBUG_DEPSGRAPH | G_DEBUG_IO | G_DEBUG_GHOST)
/** #Global.fileflags */
enum {

View File

@ -223,7 +223,8 @@ void BKE_scene_free_depsgraph_hash(struct Scene *scene);
void BKE_scene_free_view_layer_depsgraph(struct Scene *scene, struct ViewLayer *view_layer);
/* Do not allocate new depsgraph. */
struct Depsgraph *BKE_scene_get_depsgraph(struct Scene *scene, struct ViewLayer *view_layer);
struct Depsgraph *BKE_scene_get_depsgraph(const struct Scene *scene,
const struct ViewLayer *view_layer);
/* Allocate new depsgraph if necessary. */
struct Depsgraph *BKE_scene_ensure_depsgraph(struct Main *bmain,
struct Scene *scene,

View File

@ -139,6 +139,7 @@ typedef struct SpaceType {
/* region types are also defined using spacetypes_init, via a callback */
typedef struct wmRegionListenerParams {
struct wmWindow *window;
struct ScrArea *area; /* Can be NULL when the region is not part of an area. */
struct ARegion *region;
struct wmNotifier *notifier;

View File

@ -3316,7 +3316,7 @@ int BKE_scene_multiview_num_videos_get(const RenderData *rd)
/* This is a key which identifies depsgraph. */
typedef struct DepsgraphKey {
ViewLayer *view_layer;
const ViewLayer *view_layer;
/* TODO(sergey): Need to include window somehow (same layer might be in a
* different states in different windows).
*/
@ -3451,10 +3451,13 @@ static Depsgraph **scene_ensure_depsgraph_p(Main *bmain, Scene *scene, ViewLayer
return depsgraph_ptr;
}
Depsgraph *BKE_scene_get_depsgraph(Scene *scene, ViewLayer *view_layer)
Depsgraph *BKE_scene_get_depsgraph(const Scene *scene, const ViewLayer *view_layer)
{
Depsgraph **depsgraph_ptr = scene_get_depsgraph_p(scene, view_layer, false);
return (depsgraph_ptr != NULL) ? *depsgraph_ptr : NULL;
BLI_assert(BKE_scene_has_view_layer(scene, view_layer));
DepsgraphKey key;
key.view_layer = view_layer;
return BLI_ghash_lookup(scene->depsgraph_hash, &key);
}
Depsgraph *BKE_scene_ensure_depsgraph(Main *bmain, Scene *scene, ViewLayer *view_layer)

View File

@ -88,7 +88,11 @@ static void sigbus_handler(int sig, siginfo_t *siginfo, void *ptr)
file->io_error = true;
/* Replace the mapped memory with zeroes. */
mmap(file->memory, file->length, PROT_READ, MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, -1, 0);
const void *mapped_memory = mmap(
file->memory, file->length, PROT_READ, MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, -1, 0);
if (mapped_memory == MAP_FAILED) {
fprintf(stderr, "SIGBUS handler: Error replacing mapped file with zeros\n");
}
return;
}

View File

@ -272,6 +272,7 @@ static void do_versions_theme(const UserDef *userdef, bTheme *btheme)
*/
{
/* Keep this block, even when empty. */
FROM_DEFAULT_V4_UCHAR(space_properties.active);
}
#undef FROM_DEFAULT_V4_UCHAR

View File

@ -852,6 +852,10 @@ static void bmw_EdgeLoopWalker_begin(BMWalker *walker, void *data)
BM_vert_edge_count_nonwire(e->v1),
BM_vert_edge_count_nonwire(e->v2),
};
const int vert_face_count[2] = {
BM_vert_face_count(e->v1),
BM_vert_face_count(e->v2),
};
v = e->v1;
@ -863,8 +867,75 @@ static void bmw_EdgeLoopWalker_begin(BMWalker *walker, void *data)
lwalk->is_boundary = BM_edge_is_boundary(e);
lwalk->is_single = (lwalk->is_boundary && bm_edge_is_single(e));
/* could also check that vertex*/
if ((lwalk->is_boundary == false) && (vert_edge_count[0] == 3 || vert_edge_count[1] == 3)) {
/**
* Detect an NGon (face-hub)
* =========================
*
* The face-hub - #BMwEdgeLoopWalker.f_hub - is set when there is an ngon
* on one side of the edge and a series of faces on the other,
* loop around the ngon for as long as it's connected to faces which would form an edge loop
* in the absence of the ngon (used as the hub).
*
* This isn't simply ignoring the ngon though, as the edges looped over must all be
* connected to the hub.
*
* NGon in Grid Example
* --------------------
* \code{.txt}
* +-----+-----+-----+-----+-----+
* | | | | | |
* +-----va=ea=+==eb=+==ec=vb----+
* | | | |
* +-----+ +-----+
* | | f_hub | |
* +-----+ +-----+
* | | | |
* +-----+-----+-----+-----+-----+
* | | | | | |
* +-----+-----+-----+-----+-----+
* \endcode
*
* In the example above, starting from edges marked `ea/eb/ec`,
* the will detect `f_hub` and walk along the edge loop between `va -> vb`.
* The same is true for any of the un-marked sides of the ngon,
* walking stops for vertices with >= 3 connected faces (in this case they look like corners).
*
* Mixed Triangle-Fan & Quad Example
* ---------------------------------
* \code{.txt}
* +-----------------------------------------------+
* | f_hub |
* va-ea-vb=eb=+==ec=+=ed==+=ee=vc=ef=vd----------ve
* | |\ | | | / / \ |
* | | \ \ | / / / \ |
* | | \ | | | / / \ |
* | | \ \ | / / / \ |
* | | \ | | | / / \ |
* | | \ \ | / / / \ |
* | | \ | | | / / \ |
* | | \ \ | / / / \ |
* | | \| | |/ / \ |
* | | \\|// / \ |
* | | \|/ / \|
* +-----+-----------+-----+-----------------------+
* \endcode
*
* In the example above, starting from edges marked `eb/eb/ed/ed/ef`,
* the will detect `f_hub` and walk along the edge loop between `vb -> vd`.
*
* Notice `vb` and `vd` delimit the loop, since the faces connected to `vb`
* excluding `f_hub` don't share an edge, which isn't walked over in the case
* of boundaries either.
*
* Notice `vc` doesn't delimit stepping from `ee` onto `ef` as the stepping method used
* doesn't differentiate between the number of sides of faces opposite `f_hub`,
* only that each of the connected faces share an edge.
*/
if ((lwalk->is_boundary == false) &&
/* Without checking the face count, the 3 edges could be this edge
* plus two boundary edges (which would not be stepped over), see T84906. */
((vert_edge_count[0] == 3 && vert_face_count[0] == 3) ||
(vert_edge_count[1] == 3 && vert_face_count[1] == 3))) {
BMIter iter;
BMFace *f_iter;
BMFace *f_best = NULL;

View File

@ -68,6 +68,7 @@ void GaussianAlphaXBlurOperation::updateGauss()
if (this->m_distbuf_inv == nullptr) {
updateSize();
float rad = max_ff(m_size * m_data.sizex, 0.0f);
rad = min_ff(rad, MAX_GAUSSTAB_RADIUS);
m_filtersize = min_ii(ceil(rad), MAX_GAUSSTAB_RADIUS);
m_distbuf_inv = BlurBaseOperation::make_dist_fac_inverse(rad, m_filtersize, m_falloff);

View File

@ -60,6 +60,7 @@ void GaussianAlphaYBlurOperation::updateGauss()
if (this->m_gausstab == nullptr) {
updateSize();
float rad = max_ff(m_size * m_data.sizey, 0.0f);
rad = min_ff(rad, MAX_GAUSSTAB_RADIUS);
m_filtersize = min_ii(ceil(rad), MAX_GAUSSTAB_RADIUS);
m_gausstab = BlurBaseOperation::make_gausstab(rad, m_filtersize);

View File

@ -66,6 +66,7 @@ void GaussianXBlurOperation::updateGauss()
if (this->m_gausstab == nullptr) {
updateSize();
float rad = max_ff(m_size * m_data.sizex, 0.0f);
rad = min_ff(rad, MAX_GAUSSTAB_RADIUS);
m_filtersize = min_ii(ceil(rad), MAX_GAUSSTAB_RADIUS);
this->m_gausstab = BlurBaseOperation::make_gausstab(rad, m_filtersize);

View File

@ -65,6 +65,7 @@ void GaussianYBlurOperation::updateGauss()
if (this->m_gausstab == nullptr) {
updateSize();
float rad = max_ff(m_size * m_data.sizey, 0.0f);
rad = min_ff(rad, MAX_GAUSSTAB_RADIUS);
m_filtersize = min_ii(ceil(rad), MAX_GAUSSTAB_RADIUS);
this->m_gausstab = BlurBaseOperation::make_gausstab(rad, m_filtersize);

View File

@ -175,7 +175,8 @@ typedef struct DEGEditorUpdateContext {
} DEGEditorUpdateContext;
typedef void (*DEG_EditorUpdateIDCb)(const DEGEditorUpdateContext *update_ctx, struct ID *id);
typedef void (*DEG_EditorUpdateSceneCb)(const DEGEditorUpdateContext *update_ctx, int updated);
typedef void (*DEG_EditorUpdateSceneCb)(const DEGEditorUpdateContext *update_ctx,
const bool updated);
/* Set callbacks which are being called when depsgraph changes. */
void DEG_editors_set_update_cb(DEG_EditorUpdateIDCb id_func, DEG_EditorUpdateSceneCb scene_func);

View File

@ -387,7 +387,9 @@ void DepsgraphNodeBuilder::build_id(ID *id)
if (id == nullptr) {
return;
}
switch (GS(id->name)) {
const ID_Type id_type = GS(id->name);
switch (id_type) {
case ID_AC:
build_action((bAction *)id);
break;
@ -477,13 +479,39 @@ void DepsgraphNodeBuilder::build_id(ID *id)
case ID_SIM:
build_simulation((Simulation *)id);
break;
default:
fprintf(stderr, "Unhandled ID %s\n", id->name);
BLI_assert(!"Should never happen");
case ID_PA:
build_particle_settings((ParticleSettings *)id);
break;
case ID_GD:
build_gpencil((bGPdata *)id);
break;
case ID_LI:
case ID_IP:
case ID_SCR:
case ID_VF:
case ID_BR:
case ID_WM:
case ID_PAL:
case ID_PC:
case ID_WS:
BLI_assert(!deg_copy_on_write_is_needed(id_type));
build_generic_id(id);
break;
}
}
void DepsgraphNodeBuilder::build_generic_id(ID *id)
{
if (built_map_.checkIsBuiltAndTag(id)) {
return;
}
build_idproperties(id->properties);
build_animdata(id);
build_parameters(id);
}
static void build_idproperties_callback(IDProperty *id_property, void *user_data)
{
DepsgraphNodeBuilder *builder = reinterpret_cast<DepsgraphNodeBuilder *>(user_data);
@ -649,6 +677,11 @@ void DepsgraphNodeBuilder::build_object(int base_index,
if (object->particlesystem.first != nullptr) {
build_particle_systems(object, is_visible);
}
/* Force field Texture. */
if ((object->pd != nullptr) && (object->pd->forcefield == PFIELD_TEXTURE) &&
(object->pd->tex != nullptr)) {
build_texture(object->pd->tex);
}
/* Proxy object to copy from. */
build_object_proxy_from(object, is_visible);
build_object_proxy_group(object, is_visible);

View File

@ -152,6 +152,9 @@ class DepsgraphNodeBuilder : public DepsgraphBuilder {
virtual void build_id(ID *id);
/* Build function for ID types that do not need their own build_xxx() function. */
virtual void build_generic_id(ID *id);
virtual void build_idproperties(IDProperty *id_property);
virtual void build_scene_render(Scene *scene, ViewLayer *view_layer);

View File

@ -434,6 +434,13 @@ void DepsgraphRelationBuilder::add_particle_forcefield_relations(const Operation
add_relation(mod_key, key, name);
}
/* Force field Texture. */
if ((relation->pd != nullptr) && (relation->pd->forcefield == PFIELD_TEXTURE) &&
(relation->pd->tex != nullptr)) {
ComponentKey tex_key(&relation->pd->tex->id, NodeType::GENERIC_DATABLOCK);
add_relation(tex_key, key, "Force field Texture");
}
/* Smoke flow relations. */
if (relation->pd->forcefield == PFIELD_FLUIDFLOW && relation->pd->f_source) {
ComponentKey trf_key(&relation->pd->f_source->id, NodeType::TRANSFORM);
@ -484,7 +491,9 @@ void DepsgraphRelationBuilder::build_id(ID *id)
if (id == nullptr) {
return;
}
switch (GS(id->name)) {
const ID_Type id_type = GS(id->name);
switch (id_type) {
case ID_AC:
build_action((bAction *)id);
break;
@ -560,13 +569,40 @@ void DepsgraphRelationBuilder::build_id(ID *id)
case ID_SIM:
build_simulation((Simulation *)id);
break;
default:
fprintf(stderr, "Unhandled ID %s\n", id->name);
BLI_assert(!"Should never happen");
case ID_PA:
build_particle_settings((ParticleSettings *)id);
break;
case ID_GD:
build_gpencil((bGPdata *)id);
break;
case ID_LI:
case ID_IP:
case ID_SCR:
case ID_VF:
case ID_BR:
case ID_WM:
case ID_PAL:
case ID_PC:
case ID_WS:
BLI_assert(!deg_copy_on_write_is_needed(id_type));
build_generic_id(id);
break;
}
}
void DepsgraphRelationBuilder::build_generic_id(ID *id)
{
if (built_map_.checkIsBuiltAndTag(id)) {
return;
}
build_idproperties(id->properties);
build_animdata(id);
build_parameters(id);
}
static void build_idproperties_callback(IDProperty *id_property, void *user_data)
{
DepsgraphRelationBuilder *builder = reinterpret_cast<DepsgraphRelationBuilder *>(user_data);
@ -712,6 +748,11 @@ void DepsgraphRelationBuilder::build_object(Object *object)
if (object->particlesystem.first != nullptr) {
build_particle_systems(object);
}
/* Force field Texture. */
if ((object->pd != nullptr) && (object->pd->forcefield == PFIELD_TEXTURE) &&
(object->pd->tex != nullptr)) {
build_texture(object->pd->tex);
}
/* Proxy object to copy from. */
build_object_proxy_from(object);
build_object_proxy_group(object);
@ -1725,6 +1766,11 @@ void DepsgraphRelationBuilder::build_rigidbody(Scene *scene)
ComponentKey effector_geometry_key(&effector_relation->ob->id, NodeType::GEOMETRY);
add_relation(effector_geometry_key, rb_init_key, "RigidBody Field");
}
if ((effector_relation->pd->forcefield == PFIELD_TEXTURE) &&
(effector_relation->pd->tex != nullptr)) {
ComponentKey tex_key(&effector_relation->pd->tex->id, NodeType::GENERIC_DATABLOCK);
add_relation(tex_key, rb_init_key, "Force field Texture");
}
}
}
/* Objects. */

View File

@ -198,6 +198,9 @@ class DepsgraphRelationBuilder : public DepsgraphBuilder {
virtual void build_id(ID *id);
/* Build function for ID types that do not need their own build_xxx() function. */
virtual void build_generic_id(ID *id);
virtual void build_idproperties(IDProperty *id_property);
virtual void build_scene_render(Scene *scene, ViewLayer *view_layer);

View File

@ -142,6 +142,14 @@ static void clear_id_nodes_conditional(Depsgraph::IDDepsNodes *id_nodes, const F
* datablock for her own dirty needs. */
continue;
}
if (id_node->id_cow == id_node->id_orig) {
/* Copy-on-write version is not needed for this ID type.
*
* NOTE: Is important to not de-reference the original datablock here because it might be
* freed already (happens during main database free when some IDs are freed prior to a
* scene). */
continue;
}
if (!deg_copy_on_write_is_expanded(id_node->id_cow)) {
continue;
}

View File

@ -207,13 +207,15 @@ bool deg_iterator_components_step(BLI_Iterator *iter)
if (component != nullptr) {
const Volume *volume = component->get_for_read();
Object *temp_object = &data->temp_geometry_component_object;
*temp_object = *data->geometry_component_owner;
temp_object->type = OB_VOLUME;
temp_object->data = (void *)volume;
temp_object->runtime.select_id = data->geometry_component_owner->runtime.select_id;
iter->current = temp_object;
return true;
if (volume != nullptr) {
Object *temp_object = &data->temp_geometry_component_object;
*temp_object = *data->geometry_component_owner;
temp_object->type = OB_VOLUME;
temp_object->data = (void *)volume;
temp_object->runtime.select_id = data->geometry_component_owner->runtime.select_id;
iter->current = temp_object;
return true;
}
}
}

View File

@ -265,6 +265,10 @@ void depsgraph_update_editors_tag(Main *bmain, Depsgraph *graph, ID *id)
void depsgraph_id_tag_copy_on_write(Depsgraph *graph, IDNode *id_node, eUpdateSource update_source)
{
ComponentNode *cow_comp = id_node->find_component(NodeType::COPY_ON_WRITE);
if (cow_comp == nullptr) {
BLI_assert(!deg_copy_on_write_is_needed(GS(id_node->id_orig->name)));
return;
}
cow_comp->tag_update(graph, update_source);
}

View File

@ -620,6 +620,15 @@ void GPENCIL_cache_populate(void *ved, Object *ob)
bGPdata *gpd = (bGPdata *)ob->data;
bool do_onion = (!pd->is_render) ? pd->do_onion : (gpd->onion_flag & GP_ONION_GHOST_ALWAYS);
gpd->runtime.playing = (short)pd->playing;
/* When render in background the active frame could not be properly set due thread priority
* better set again. This is not required in viewport. */
if (txl->render_depth_tx) {
LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) {
gpl->actframe = BKE_gpencil_layer_frame_get(gpl, pd->cfra, GP_GETFRAME_USE_PREV);
}
}
BKE_gpencil_visible_stroke_iter(is_final_render ? pd->view_layer : NULL,
ob,
gpencil_layer_cache_populate,

View File

@ -1,13 +1,10 @@
uniform sampler2D depthBuf;
uniform float strokeDepth2d;
uniform bool strokeOrder3d;
noperspective in vec4 uvcoordsvar;
void main()
{
float depth = textureLod(depthBuf, uvcoordsvar.xy, 0).r;
float depth = textureLod(depthBuf, gl_FragCoord.xy / vec2(textureSize(depthBuf, 0)), 0).r;
if (strokeOrder3d) {
gl_FragDepth = depth;
}

View File

@ -1,8 +1,6 @@
uniform vec4 gpModelMatrix[4];
noperspective out vec4 uvcoordsvar;
void main()
{
mat4 model_matrix = mat4(gpModelMatrix[0], gpModelMatrix[1], gpModelMatrix[2], gpModelMatrix[3]);
@ -10,5 +8,4 @@ void main()
float x = -1.0 + float((v & 1) << 2);
float y = -1.0 + float((v & 2) << 1);
gl_Position = ViewProjectionMatrix * (model_matrix * vec4(x, y, 0.0, 1.0));
uvcoordsvar = vec4((gl_Position.xy / gl_Position.w + 1.0) * 0.5, 0.0, 0.0);
}

View File

@ -110,12 +110,6 @@ void OVERLAY_edit_mesh_cache_init(OVERLAY_Data *vedata)
float face_alpha = (do_occlude_wire || !pd->edit_mesh.do_faces) ? 0.0f : 1.0f;
GPUTexture **depth_tex = (pd->edit_mesh.do_zbufclip) ? &dtxl->depth : &txl->dummy_depth_tx;
if (select_face && !pd->edit_mesh.do_faces && pd->edit_mesh.do_edges) {
/* Force display of face centers in this case because that's
* the only way to see if a face is selected. */
show_face_dots = true;
}
/* Run Twice for in-front passes. */
for (int i = 0; i < 2; i++) {
/* Complementary Depth Pass */

View File

@ -29,15 +29,17 @@
extern "C" {
#endif
struct bContext;
struct bScreen;
struct DEGEditorUpdateContext;
struct Depsgraph;
struct ID;
struct MTex;
struct Main;
struct MTex;
struct Render;
struct Scene;
struct ScrArea;
struct bContext;
struct bScreen;
struct wmWindow;
struct wmWindowManager;
/* render_ops.c */
@ -53,7 +55,11 @@ void ED_render_view_layer_changed(struct Main *bmain, struct bScreen *screen);
/* Callbacks handling data update events coming from depsgraph. */
void ED_render_id_flush_update(const struct DEGEditorUpdateContext *update_ctx, struct ID *id);
void ED_render_scene_update(const struct DEGEditorUpdateContext *update_ctx, int updated);
void ED_render_scene_update(const struct DEGEditorUpdateContext *update_ctx, const bool updated);
void ED_render_view3d_update(struct Depsgraph *depsgraph,
struct wmWindow *window,
struct ScrArea *area,
const bool updated);
struct Scene *ED_render_job_get_scene(const struct bContext *C);
struct Scene *ED_render_job_get_current_scene(const struct bContext *C);

View File

@ -789,7 +789,7 @@ static void ui_but_update_old_active_from_new(uiBut *oldbut, uiBut *but)
BLI_assert(oldbut->active);
/* flags from the buttons we want to refresh, may want to add more here... */
const int flag_copy = UI_BUT_REDALERT | UI_HAS_ICON;
const int flag_copy = UI_BUT_REDALERT | UI_HAS_ICON | UI_SELECT_DRAW;
const int drawflag_copy = 0; /* None currently. */
/* still stuff needs to be copied */
@ -988,6 +988,11 @@ bool UI_but_active_only(const bContext *C, ARegion *region, uiBlock *block, uiBu
*/
bool UI_block_active_only_flagged_buttons(const bContext *C, ARegion *region, uiBlock *block)
{
/* Running this command before end-block has run, means buttons that open menus
* wont have those menus correctly positioned, see T83539. */
BLI_assert(block->endblock != 0);
bool done = false;
LISTBASE_FOREACH (uiBut *, but, &block->buttons) {
if (but->flag & UI_BUT_ACTIVATE_ON_INIT) {
@ -3194,6 +3199,7 @@ void ui_but_range_set_soft(uiBut *but)
if (but->rnaprop) {
const PropertyType type = RNA_property_type(but->rnaprop);
const PropertySubType subtype = RNA_property_subtype(but->rnaprop);
double softmin, softmax /*, step, precision*/;
double value_min;
double value_max;
@ -3217,7 +3223,7 @@ void ui_but_range_set_soft(uiBut *but)
value_max = (double)value_range[1];
}
else {
value_min = value_max = (double)RNA_property_int_get(&but->rnapoin, but->rnaprop);
value_min = value_max = ui_but_value_get(but);
}
}
else if (type == PROP_FLOAT) {
@ -3230,14 +3236,15 @@ void ui_but_range_set_soft(uiBut *but)
/*step = fstep;*/ /*UNUSED*/
/*precision = fprecision;*/ /*UNUSED*/
if (is_array) {
/* Use shared min/max for array values, except for color alpha. */
if (is_array && !(subtype == PROP_COLOR && but->rnaindex == 3)) {
float value_range[2];
RNA_property_float_get_array_range(&but->rnapoin, but->rnaprop, value_range);
value_min = (double)value_range[0];
value_max = (double)value_range[1];
}
else {
value_min = value_max = (double)RNA_property_float_get(&but->rnapoin, but->rnaprop);
value_min = value_max = ui_but_value_get(but);
}
}
else {

View File

@ -4193,9 +4193,17 @@ static uiButExtraOpIcon *ui_but_extra_operator_icon_mouse_over_get(uiBut *but,
return NULL;
}
/* Same as in 'widget_draw_extra_icons', icon padding from the right edge. */
xmax -= 0.2 * icon_size;
/* Handle the padding space from the right edge as the last button. */
if (x > xmax) {
return but->extra_op_icons.last;
}
/* Inverse order, from right to left. */
LISTBASE_FOREACH_BACKWARD (uiButExtraOpIcon *, op_icon, &but->extra_op_icons) {
if ((x > (xmax - icon_size)) && x < xmax) {
if ((x > (xmax - icon_size)) && x <= xmax) {
return op_icon;
}
xmax -= icon_size;
@ -9914,6 +9922,12 @@ static int ui_handle_menu_event(bContext *C,
break;
}
/* Only respond to explicit press to avoid the event that opened the menu
* activating an item when the key is held. */
if (event->is_repeat) {
break;
}
if (event->alt) {
act += 10;
}
@ -9993,8 +10007,11 @@ static int ui_handle_menu_event(bContext *C,
case EVT_XKEY:
case EVT_YKEY:
case EVT_ZKEY: {
if ((event->val == KM_PRESS || event->val == KM_DBL_CLICK) &&
!IS_EVENT_MOD(event, shift, ctrl, oskey)) {
if (ELEM(event->val, KM_PRESS, KM_DBL_CLICK) &&
!IS_EVENT_MOD(event, shift, ctrl, oskey) &&
/* Only respond to explicit press to avoid the event that opened the menu
* activating an item when the key is held. */
!event->is_repeat) {
if (ui_menu_pass_event_to_parent_if_nonactive(menu, but, level, retval)) {
break;
}

View File

@ -1119,10 +1119,9 @@ static void panel_draw_highlight_border(const Panel *panel,
radius = 0.0f;
}
/* Abuse the property search theme color for now. */
float color[4];
UI_GetThemeColor4fv(TH_MATCH, color);
UI_draw_roundbox_aa(
UI_GetThemeColor4fv(TH_SELECT_ACTIVE, color);
UI_draw_roundbox_4fv(
&(const rctf){
.xmin = rect->xmin,
.xmax = rect->xmax,

View File

@ -2254,20 +2254,33 @@ static void widget_draw_extra_icons(const uiWidgetColors *wcol,
rcti *rect,
float alpha)
{
/* inverse order, from right to left. */
const float icon_size = ICON_SIZE_FROM_BUTRECT(rect);
/* Offset of icons from the right edge. Keep in sync
with 'ui_but_extra_operator_icon_mouse_over_get'. */
if (!BLI_listbase_is_empty(&but->extra_op_icons)) {
/* Eyeballed. */
rect->xmax -= 0.2 * icon_size;
}
/* Inverse order, from right to left. */
LISTBASE_FOREACH_BACKWARD (uiButExtraOpIcon *, op_icon, &but->extra_op_icons) {
rcti temp = *rect;
float alpha_this = alpha;
temp.xmin = temp.xmax - (BLI_rcti_size_y(rect) * 1.08f);
temp.xmin = temp.xmax - icon_size;
if (!op_icon->highlighted) {
alpha_this *= 0.75f;
}
/* Draw the icon at the center, and restore the flags after. */
const int old_drawflags = but->drawflag;
UI_but_drawflag_disable(but, UI_BUT_ICON_LEFT);
widget_draw_icon(but, op_icon->icon, alpha_this, &temp, wcol->text);
but->drawflag = old_drawflags;
rect->xmax -= ICON_SIZE_FROM_BUTRECT(rect);
rect->xmax -= icon_size;
}
}

View File

@ -238,7 +238,7 @@ typedef struct SlidePointData {
bool is_sliding_new_point;
/* Data needed to restre the state. */
/* Data needed to restore the state. */
float vec[3][3];
char old_h1, old_h2;
@ -863,7 +863,7 @@ static int slide_point_modal(bContext *C, wmOperator *op, const wmEvent *event)
if (event->type == data->event_invoke_type && event->val == KM_RELEASE) {
Scene *scene = CTX_data_scene(C);
/* dont key sliding feather uw's */
/* Don't key sliding feather UW's. */
if ((data->action == SLIDE_ACTION_FEATHER && data->uw) == false) {
if (IS_AUTOKEY_ON(scene)) {
ED_mask_layer_shape_auto_key(data->mask_layer, CFRA);
@ -1053,7 +1053,7 @@ static SlideSplineCurvatureData *slide_spline_curvature_customdata(bContext *C,
slide_data->bezt_backup = *slide_data->adjust_bezt;
slide_data->other_bezt_backup = *slide_data->other_bezt;
/* Let's dont touch other side of the point for now, so set handle to FREE. */
/* Let's don't touch other side of the point for now, so set handle to FREE. */
if (u < 0.5f) {
if (slide_data->adjust_bezt->h2 <= HD_VECT) {
slide_data->adjust_bezt->h2 = HD_FREE;
@ -1270,7 +1270,7 @@ static int slide_spline_curvature_modal(bContext *C, wmOperator *op, const wmEve
case LEFTMOUSE:
case RIGHTMOUSE:
if (event->type == slide_data->event_invoke_type && event->val == KM_RELEASE) {
/* dont key sliding feather uw's */
/* Don't key sliding feather UW's. */
if (IS_AUTOKEY_ON(scene)) {
ED_mask_layer_shape_auto_key(slide_data->mask_layer, CFRA);
}

View File

@ -200,6 +200,11 @@ static bool check_engine_supports_preview(Scene *scene)
return (type->flag & RE_USE_PREVIEW) != 0;
}
static bool preview_method_is_render(int pr_method)
{
return ELEM(pr_method, PR_ICON_RENDER, PR_BUTS_RENDER, PR_NODE_RENDER);
}
void ED_preview_free_dbase(void)
{
if (G_pr_main) {
@ -1352,13 +1357,12 @@ static void common_preview_startjob(void *customdata,
*/
static void other_id_types_preview_render(IconPreview *ip,
IconPreviewSize *cur_size,
const bool is_deferred,
const int pr_method,
short *stop,
short *do_update,
float *progress)
{
ShaderPreview *sp = MEM_callocN(sizeof(ShaderPreview), "Icon ShaderPreview");
const bool is_render = !is_deferred;
/* These types don't use the ShaderPreview mess, they have their own types and functions. */
BLI_assert(!ip->id || !ELEM(GS(ip->id->name), ID_OB));
@ -1368,7 +1372,7 @@ static void other_id_types_preview_render(IconPreview *ip,
sp->owner = ip->owner;
sp->sizex = cur_size->sizex;
sp->sizey = cur_size->sizey;
sp->pr_method = is_render ? PR_ICON_RENDER : PR_ICON_DEFERRED;
sp->pr_method = pr_method;
sp->pr_rect = cur_size->rect;
sp->id = ip->id;
sp->id_copy = ip->id_copy;
@ -1376,7 +1380,7 @@ static void other_id_types_preview_render(IconPreview *ip,
sp->own_id_copy = false;
Material *ma = NULL;
if (is_render) {
if (sp->pr_method == PR_ICON_RENDER) {
BLI_assert(ip->id);
/* grease pencil use its own preview file */
@ -1424,6 +1428,8 @@ static void icon_preview_startjob_all_sizes(void *customdata,
for (cur_size = ip->sizes.first; cur_size; cur_size = cur_size->next) {
PreviewImage *prv = ip->owner;
/* Is this a render job or a deferred loading job? */
const int pr_method = (prv->tag & PRV_TAG_DEFFERED) ? PR_ICON_DEFERRED : PR_ICON_RENDER;
if (*stop) {
break;
@ -1434,7 +1440,7 @@ static void icon_preview_startjob_all_sizes(void *customdata,
continue;
}
if (!check_engine_supports_preview(ip->scene)) {
if (preview_method_is_render(pr_method) && !check_engine_supports_preview(ip->scene)) {
continue;
}
@ -1450,8 +1456,7 @@ static void icon_preview_startjob_all_sizes(void *customdata,
object_preview_render(ip, cur_size);
}
else {
other_id_types_preview_render(
ip, cur_size, (prv->tag & PRV_TAG_DEFFERED), stop, do_update, progress);
other_id_types_preview_render(ip, cur_size, pr_method, stop, do_update, progress);
}
}
}
@ -1634,7 +1639,7 @@ void ED_preview_shader_job(const bContext *C,
/* Use workspace render only for buttons Window,
* since the other previews are related to the datablock. */
if (!check_engine_supports_preview(scene)) {
if (preview_method_is_render(method) && !check_engine_supports_preview(scene)) {
return;
}

View File

@ -61,23 +61,79 @@
#include "ED_view3d.h"
#include "DEG_depsgraph.h"
#include "DEG_depsgraph_query.h"
#include "WM_api.h"
#include "render_intern.h" /* own include */
#include <stdio.h>
/***************************** Render Engines ********************************/
void ED_render_scene_update(const DEGEditorUpdateContext *update_ctx, int updated)
/* Update 3D viewport render or draw engine on changes to the scene or view settings . */
void ED_render_view3d_update(Depsgraph *depsgraph,
wmWindow *window,
ScrArea *area,
const bool updated)
{
Main *bmain = DEG_get_bmain(depsgraph);
Scene *scene = DEG_get_input_scene(depsgraph);
ViewLayer *view_layer = DEG_get_input_view_layer(depsgraph);
LISTBASE_FOREACH (ARegion *, region, &area->regionbase) {
if (region->regiontype != RGN_TYPE_WINDOW) {
continue;
}
View3D *v3d = area->spacedata.first;
RegionView3D *rv3d = region->regiondata;
RenderEngine *engine = rv3d->render_engine;
/* call update if the scene changed, or if the render engine
* tagged itself for update (e.g. because it was busy at the
* time of the last update) */
if (engine && (updated || (engine->flag & RE_ENGINE_DO_UPDATE))) {
/* Create temporary context to execute callback in. */
bContext *C = CTX_create();
CTX_data_main_set(C, bmain);
CTX_data_scene_set(C, scene);
CTX_wm_manager_set(C, bmain->wm.first);
CTX_wm_window_set(C, window);
CTX_wm_screen_set(C, WM_window_get_active_screen(window));
CTX_wm_area_set(C, area);
CTX_wm_region_set(C, region);
engine->flag &= ~RE_ENGINE_DO_UPDATE;
/* NOTE: Important to pass non-updated depsgraph, This is because this function is called
* from inside dependency graph evaluation. Additionally, if we pass fully evaluated one
* we will lose updates stored in the graph. */
engine->type->view_update(engine, C, CTX_data_depsgraph_pointer(C));
CTX_free(C);
}
else {
RenderEngineType *engine_type = ED_view3d_engine_type(scene, v3d->shading.type);
if (updated) {
DRW_notify_view_update((&(DRWUpdateContext){
.bmain = bmain,
.depsgraph = depsgraph,
.scene = scene,
.view_layer = view_layer,
.region = region,
.v3d = v3d,
.engine_type = engine_type,
}));
}
}
}
}
/* Update all 3D viewport render and draw engines on changes to the scene.
* This is called by the dependency graph when it detects changes. */
void ED_render_scene_update(const DEGEditorUpdateContext *update_ctx, const bool updated)
{
/* viewport rendering update on data changes, happens after depsgraph
* updates if there was any change. context is set to the 3d view */
Main *bmain = update_ctx->bmain;
Scene *scene = update_ctx->scene;
ViewLayer *view_layer = update_ctx->view_layer;
bContext *C;
wmWindowManager *wm;
wmWindow *win;
static bool recursive_check = false;
/* don't do this render engine update if we're updating the scene from
@ -98,66 +154,17 @@ void ED_render_scene_update(const DEGEditorUpdateContext *update_ctx, int update
recursive_check = true;
C = CTX_create();
CTX_data_main_set(C, bmain);
CTX_data_scene_set(C, scene);
wmWindowManager *wm = bmain->wm.first;
LISTBASE_FOREACH (wmWindow *, window, &wm->windows) {
bScreen *screen = WM_window_get_active_screen(window);
CTX_wm_manager_set(C, bmain->wm.first);
wm = bmain->wm.first;
for (win = wm->windows.first; win; win = win->next) {
bScreen *screen = WM_window_get_active_screen(win);
ScrArea *area;
ARegion *region;
CTX_wm_window_set(C, win);
for (area = screen->areabase.first; area; area = area->next) {
if (area->spacetype != SPACE_VIEW3D) {
continue;
}
View3D *v3d = area->spacedata.first;
for (region = area->regionbase.first; region; region = region->next) {
if (region->regiontype != RGN_TYPE_WINDOW) {
continue;
}
RegionView3D *rv3d = region->regiondata;
RenderEngine *engine = rv3d->render_engine;
/* call update if the scene changed, or if the render engine
* tagged itself for update (e.g. because it was busy at the
* time of the last update) */
if (engine && (updated || (engine->flag & RE_ENGINE_DO_UPDATE))) {
CTX_wm_screen_set(C, screen);
CTX_wm_area_set(C, area);
CTX_wm_region_set(C, region);
engine->flag &= ~RE_ENGINE_DO_UPDATE;
/* NOTE: Important to pass non-updated depsgraph, This is because this function is called
* from inside dependency graph evaluation. Additionally, if we pass fully evaluated one
* we will lose updates stored in the graph. */
engine->type->view_update(engine, C, CTX_data_depsgraph_pointer(C));
}
else {
RenderEngineType *engine_type = ED_view3d_engine_type(scene, v3d->shading.type);
if (updated) {
DRW_notify_view_update((&(DRWUpdateContext){
.bmain = bmain,
.depsgraph = update_ctx->depsgraph,
.scene = scene,
.view_layer = view_layer,
.region = region,
.v3d = (View3D *)area->spacedata.first,
.engine_type = engine_type,
}));
}
}
LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
if (area->spacetype == SPACE_VIEW3D) {
ED_render_view3d_update(update_ctx->depsgraph, window, area, updated);
}
}
}
CTX_free(C);
recursive_check = false;
}

View File

@ -178,6 +178,8 @@ void clip_view_center_to_point(SpaceClip *sc, float x, float y);
bool clip_view_calculate_view_selection(
const struct bContext *C, bool fit, float *r_offset_x, float *r_offset_y, float *r_zoom);
bool clip_view_has_locked_selection(const struct bContext *C);
void clip_draw_sfra_efra(struct View2D *v2d, struct Scene *scene);
/* tracking_ops.c */

View File

@ -125,7 +125,7 @@ static void sclip_zoom_set(const bContext *C,
dx = ((location[0] - 0.5f) * w - sc->xof) * (sc->zoom - oldzoom) / sc->zoom;
dy = ((location[1] - 0.5f) * h - sc->yof) * (sc->zoom - oldzoom) / sc->zoom;
if (sc->flag & SC_LOCK_SELECTION) {
if (clip_view_has_locked_selection(C)) {
sc->xlockof += dx;
sc->ylockof += dy;
}
@ -396,7 +396,7 @@ static void view_pan_init(bContext *C, wmOperator *op, const wmEvent *event)
vpd->x = event->x;
vpd->y = event->y;
if (sc->flag & SC_LOCK_SELECTION) {
if (clip_view_has_locked_selection(C)) {
vpd->vec = &sc->xlockof;
}
else {
@ -434,7 +434,7 @@ static int view_pan_exec(bContext *C, wmOperator *op)
RNA_float_get_array(op->ptr, "offset", offset);
if (sc->flag & SC_LOCK_SELECTION) {
if (clip_view_has_locked_selection(C)) {
sc->xlockof += offset[0];
sc->ylockof += offset[1];
}

View File

@ -465,6 +465,68 @@ static bool selected_tracking_boundbox(SpaceClip *sc, float min[2], float max[2]
return ok;
}
static bool tracking_has_selection(SpaceClip *space_clip)
{
MovieClip *clip = ED_space_clip_get_clip(space_clip);
ListBase *tracksbase = BKE_tracking_get_active_tracks(&clip->tracking);
const int framenr = ED_space_clip_get_clip_frame_number(space_clip);
LISTBASE_FOREACH (MovieTrackingTrack *, track, tracksbase) {
if (!TRACK_VIEW_SELECTED(space_clip, track)) {
continue;
}
const MovieTrackingMarker *marker = BKE_tracking_marker_get(track, framenr);
if (marker != NULL) {
return true;
}
}
return false;
}
static bool mask_has_selection(const bContext *C, bool include_handles)
{
Mask *mask = CTX_data_edit_mask(C);
if (mask == NULL) {
return false;
}
LISTBASE_FOREACH (MaskLayer *, mask_layer, &mask->masklayers) {
if (mask_layer->restrictflag & (MASK_RESTRICT_VIEW | MASK_RESTRICT_SELECT)) {
continue;
}
LISTBASE_FOREACH (MaskSpline *, spline, &mask_layer->splines) {
for (int i = 0; i < spline->tot_point; i++) {
const MaskSplinePoint *point = &spline->points[i];
const BezTriple *bezt = &point->bezt;
if (!MASKPOINT_ISSEL_ANY(point)) {
continue;
}
if (bezt->f2 & SELECT) {
return true;
}
if (!include_handles) {
/* Ignore handles. */
}
else if (BKE_mask_point_handles_mode_get(point) == MASK_HANDLE_MODE_STICK) {
return true;
}
else {
if ((bezt->f1 & SELECT) && (bezt->h1 != HD_VECT)) {
return true;
}
if ((bezt->f3 & SELECT) && (bezt->h2 != HD_VECT)) {
return true;
}
}
}
}
}
return false;
}
static bool selected_boundbox(const bContext *C, float min[2], float max[2], bool include_handles)
{
SpaceClip *sc = CTX_wm_space_clip(C);
@ -546,6 +608,23 @@ bool clip_view_calculate_view_selection(
return true;
}
/* Returns truth if lock-to-selection is enabled and possible.
* Locking to selection is not possible if there is no selection. */
bool clip_view_has_locked_selection(const bContext *C)
{
SpaceClip *space_clip = CTX_wm_space_clip(C);
if ((space_clip->flag & SC_LOCK_SELECTION) == 0) {
return false;
}
if (space_clip->mode == SC_MODE_TRACKING) {
return tracking_has_selection(space_clip);
}
return mask_has_selection(C, false);
}
void clip_draw_sfra_efra(View2D *v2d, Scene *scene)
{
UI_view2d_view_ortho(v2d);

View File

@ -243,8 +243,6 @@ static int delete_track_exec(bContext *C, wmOperator *UNUSED(op))
changed = true;
}
}
/* Nothing selected now, unlock view so it can be scrolled nice again. */
sc->flag &= ~SC_LOCK_SELECTION;
if (changed) {
WM_event_add_notifier(C, NC_MOVIECLIP | NA_EDITED, clip);
}
@ -313,11 +311,6 @@ static int delete_marker_exec(bContext *C, wmOperator *UNUSED(op))
}
}
if (!has_selection) {
/* Nothing selected now, unlock view so it can be scrolled nice again. */
sc->flag &= ~SC_LOCK_SELECTION;
}
if (!changed) {
return OPERATOR_CANCELLED;
}
@ -1224,13 +1217,6 @@ static int hide_tracks_exec(bContext *C, wmOperator *op)
clip->tracking.act_plane_track = NULL;
}
if (unselected == 0) {
/* No selection on screen now, unlock view so it can be
* scrolled nice again.
*/
sc->flag &= ~SC_LOCK_SELECTION;
}
BKE_tracking_dopesheet_tag_update(tracking);
WM_event_add_notifier(C, NC_MOVIECLIP | ND_DISPLAY, NULL);

View File

@ -875,10 +875,7 @@ static int select_all_exec(bContext *C, wmOperator *op)
bool has_selection = false;
ED_clip_select_all(sc, action, &has_selection);
if (!has_selection) {
sc->flag &= ~SC_LOCK_SELECTION;
}
else {
if (has_selection) {
ED_clip_view_lock_state_restore_no_jump(C, &lock_state);
}

View File

@ -167,8 +167,6 @@ static void outliner_storage_cleanup(SpaceOutliner *space_outliner)
static void check_persistent(
SpaceOutliner *space_outliner, TreeElement *te, ID *id, short type, short nr)
{
TreeStoreElem *tselem;
if (space_outliner->treestore == NULL) {
/* if treestore was not created in readfile.c, create it here */
space_outliner->treestore = BLI_mempool_create(
@ -181,7 +179,8 @@ static void check_persistent(
/* find any unused tree element in treestore and mark it as used
* (note that there may be multiple unused elements in case of linked objects) */
tselem = BKE_outliner_treehash_lookup_unused(space_outliner->runtime->treehash, type, nr, id);
TreeStoreElem *tselem = BKE_outliner_treehash_lookup_unused(
space_outliner->runtime->treehash, type, nr, id);
if (tselem) {
te->store_elem = tselem;
tselem->used = 1;
@ -204,8 +203,7 @@ static void check_persistent(
void outliner_free_tree(ListBase *tree)
{
for (TreeElement *element = tree->first, *element_next; element; element = element_next) {
element_next = element->next;
LISTBASE_FOREACH_MUTABLE (TreeElement *, element, tree) {
outliner_free_tree_element(element, tree);
}
}
@ -271,8 +269,8 @@ static void outliner_add_bone(SpaceOutliner *space_outliner,
te->name = curBone->name;
te->directdata = curBone;
for (curBone = curBone->childbase.first; curBone; curBone = curBone->next) {
outliner_add_bone(space_outliner, &te->subtree, id, curBone, te, a);
LISTBASE_FOREACH (Bone *, child_bone, &curBone->childbase) {
outliner_add_bone(space_outliner, &te->subtree, id, child_bone, te, a);
}
}
@ -381,35 +379,30 @@ static void outliner_add_object_contents(SpaceOutliner *space_outliner,
if (ob->pose) {
bArmature *arm = ob->data;
bPoseChannel *pchan;
TreeElement *tenla = outliner_add_element(
space_outliner, &te->subtree, ob, te, TSE_POSE_BASE, 0);
tenla->name = IFACE_("Pose");
/* channels undefined in editmode, but we want the 'tenla' pose icon itself */
if ((arm->edbo == NULL) && (ob->mode & OB_MODE_POSE)) {
TreeElement *ten;
int a = 0, const_index = 1000; /* ensure unique id for bone constraints */
for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next, a++) {
ten = outliner_add_element(
int const_index = 1000; /* ensure unique id for bone constraints */
int a;
LISTBASE_FOREACH_INDEX (bPoseChannel *, pchan, &ob->pose->chanbase, a) {
TreeElement *ten = outliner_add_element(
space_outliner, &tenla->subtree, ob, tenla, TSE_POSE_CHANNEL, a);
ten->name = pchan->name;
ten->directdata = pchan;
pchan->temp = (void *)ten;
if (pchan->constraints.first) {
if (!BLI_listbase_is_empty(&pchan->constraints)) {
/* Object *target; */
bConstraint *con;
TreeElement *ten1;
TreeElement *tenla1 = outliner_add_element(
space_outliner, &ten->subtree, ob, ten, TSE_CONSTRAINT_BASE, 0);
tenla1->name = IFACE_("Constraints");
/* char *str; */
tenla1->name = IFACE_("Constraints");
for (con = pchan->constraints.first; con; con = con->next, const_index++) {
ten1 = outliner_add_element(
LISTBASE_FOREACH (bConstraint *, con, &pchan->constraints) {
TreeElement *ten1 = outliner_add_element(
space_outliner, &tenla1->subtree, ob, tenla1, TSE_CONSTRAINT, const_index);
#if 0 /* disabled as it needs to be reworked for recoded constraints system */
target = get_constraint_target(con, &str);
@ -427,15 +420,16 @@ static void outliner_add_object_contents(SpaceOutliner *space_outliner,
ten1->directdata = con;
/* possible add all other types links? */
}
const_index++;
}
}
/* make hierarchy */
ten = tenla->subtree.first;
TreeElement *ten = tenla->subtree.first;
while (ten) {
TreeElement *nten = ten->next, *par;
tselem = TREESTORE(ten);
if (tselem->type == TSE_POSE_CHANNEL) {
pchan = (bPoseChannel *)ten->directdata;
bPoseChannel *pchan = (bPoseChannel *)ten->directdata;
if (pchan->parent) {
BLI_remlink(&tenla->subtree, ten);
par = (TreeElement *)pchan->parent->temp;
@ -448,17 +442,15 @@ static void outliner_add_object_contents(SpaceOutliner *space_outliner,
}
/* Pose Groups */
if (ob->pose->agroups.first) {
bActionGroup *agrp;
if (!BLI_listbase_is_empty(&ob->pose->agroups)) {
TreeElement *ten_bonegrp = outliner_add_element(
space_outliner, &te->subtree, ob, te, TSE_POSEGRP_BASE, 0);
int a = 0;
ten_bonegrp->name = IFACE_("Bone Groups");
for (agrp = ob->pose->agroups.first; agrp; agrp = agrp->next, a++) {
TreeElement *ten;
ten = outliner_add_element(
space_outliner, &ten_bonegrp->subtree, ob, ten_bonegrp, TSE_POSEGRP, a);
int index;
LISTBASE_FOREACH_INDEX (bActionGroup *, agrp, &ob->pose->agroups, index) {
TreeElement *ten = outliner_add_element(
space_outliner, &ten_bonegrp->subtree, ob, ten_bonegrp, TSE_POSEGRP, index);
ten->name = agrp->name;
ten->directdata = agrp;
}
@ -469,18 +461,15 @@ static void outliner_add_object_contents(SpaceOutliner *space_outliner,
outliner_add_element(space_outliner, &te->subtree, ob->mat[a], te, 0, a);
}
if (ob->constraints.first) {
/* Object *target; */
bConstraint *con;
TreeElement *ten;
if (!BLI_listbase_is_empty(&ob->constraints)) {
TreeElement *tenla = outliner_add_element(
space_outliner, &te->subtree, ob, te, TSE_CONSTRAINT_BASE, 0);
/* char *str; */
int a;
tenla->name = IFACE_("Constraints");
for (con = ob->constraints.first, a = 0; con; con = con->next, a++) {
ten = outliner_add_element(space_outliner, &tenla->subtree, ob, tenla, TSE_CONSTRAINT, a);
int index;
LISTBASE_FOREACH_INDEX (bConstraint *, con, &ob->constraints, index) {
TreeElement *ten = outliner_add_element(
space_outliner, &tenla->subtree, ob, tenla, TSE_CONSTRAINT, index);
#if 0 /* disabled due to constraints system targets recode... code here needs review */
target = get_constraint_target(con, &str);
if (str && str[0]) {
@ -499,14 +488,13 @@ static void outliner_add_object_contents(SpaceOutliner *space_outliner,
}
}
if (ob->modifiers.first) {
ModifierData *md;
if (!BLI_listbase_is_empty(&ob->modifiers)) {
TreeElement *ten_mod = outliner_add_element(
space_outliner, &te->subtree, ob, te, TSE_MODIFIER_BASE, 0);
int index;
ten_mod->name = IFACE_("Modifiers");
for (index = 0, md = ob->modifiers.first; md; index++, md = md->next) {
int index;
LISTBASE_FOREACH_INDEX (ModifierData *, md, &ob->modifiers, index) {
TreeElement *ten = outliner_add_element(
space_outliner, &ten_mod->subtree, ob, ten_mod, TSE_MODIFIER, index);
ten->name = md->name;
@ -559,8 +547,8 @@ static void outliner_add_object_contents(SpaceOutliner *space_outliner,
if (!BLI_listbase_is_empty(&ob->greasepencil_modifiers)) {
TreeElement *ten_mod = outliner_add_element(
space_outliner, &te->subtree, ob, te, TSE_MODIFIER_BASE, 0);
ten_mod->name = IFACE_("Modifiers");
int index;
LISTBASE_FOREACH_INDEX (GpencilModifierData *, md, &ob->greasepencil_modifiers, index) {
TreeElement *ten = outliner_add_element(
@ -599,8 +587,8 @@ static void outliner_add_object_contents(SpaceOutliner *space_outliner,
if (!BLI_listbase_is_empty(&ob->shader_fx)) {
TreeElement *ten_fx = outliner_add_element(
space_outliner, &te->subtree, ob, te, TSE_GPENCIL_EFFECT_BASE, 0);
ten_fx->name = IFACE_("Effects");
int index;
LISTBASE_FOREACH_INDEX (ShaderFxData *, fx, &ob->shader_fx, index) {
TreeElement *ten = outliner_add_element(
@ -620,16 +608,15 @@ static void outliner_add_object_contents(SpaceOutliner *space_outliner,
}
/* vertex groups */
if (ob->defbase.first) {
bDeformGroup *defgroup;
TreeElement *ten;
if (!BLI_listbase_is_empty(&ob->defbase)) {
TreeElement *tenla = outliner_add_element(
space_outliner, &te->subtree, ob, te, TSE_DEFGROUP_BASE, 0);
int a;
tenla->name = IFACE_("Vertex Groups");
for (defgroup = ob->defbase.first, a = 0; defgroup; defgroup = defgroup->next, a++) {
ten = outliner_add_element(space_outliner, &tenla->subtree, ob, tenla, TSE_DEFGROUP, a);
int index;
LISTBASE_FOREACH_INDEX (bDeformGroup *, defgroup, &ob->defbase, index) {
TreeElement *ten = outliner_add_element(
space_outliner, &tenla->subtree, ob, tenla, TSE_DEFGROUP, index);
ten->name = defgroup->name;
ten->directdata = defgroup;
}
@ -694,14 +681,13 @@ static void outliner_add_id_contents(SpaceOutliner *space_outliner,
}
case ID_ME: {
Mesh *me = (Mesh *)id;
int a;
if (outliner_animdata_test(me->adt)) {
outliner_add_element(space_outliner, &te->subtree, me, te, TSE_ANIM_DATA, 0);
}
outliner_add_element(space_outliner, &te->subtree, me->key, te, 0, 0);
for (a = 0; a < me->totcol; a++) {
for (int a = 0; a < me->totcol; a++) {
outliner_add_element(space_outliner, &te->subtree, me->mat[a], te, 0, a);
}
/* could do tfaces with image links, but the images are not grouped nicely.
@ -710,33 +696,30 @@ static void outliner_add_id_contents(SpaceOutliner *space_outliner,
}
case ID_CU: {
Curve *cu = (Curve *)id;
int a;
if (outliner_animdata_test(cu->adt)) {
outliner_add_element(space_outliner, &te->subtree, cu, te, TSE_ANIM_DATA, 0);
}
for (a = 0; a < cu->totcol; a++) {
for (int a = 0; a < cu->totcol; a++) {
outliner_add_element(space_outliner, &te->subtree, cu->mat[a], te, 0, a);
}
break;
}
case ID_MB: {
MetaBall *mb = (MetaBall *)id;
int a;
if (outliner_animdata_test(mb->adt)) {
outliner_add_element(space_outliner, &te->subtree, mb, te, TSE_ANIM_DATA, 0);
}
for (a = 0; a < mb->totcol; a++) {
for (int a = 0; a < mb->totcol; a++) {
outliner_add_element(space_outliner, &te->subtree, mb->mat[a], te, 0, a);
}
break;
}
case ID_MA: {
Material *ma = (Material *)id;
if (outliner_animdata_test(ma->adt)) {
outliner_add_element(space_outliner, &te->subtree, ma, te, TSE_ANIM_DATA, 0);
}
@ -744,7 +727,6 @@ static void outliner_add_id_contents(SpaceOutliner *space_outliner,
}
case ID_TE: {
Tex *tex = (Tex *)id;
if (outliner_animdata_test(tex->adt)) {
outliner_add_element(space_outliner, &te->subtree, tex, te, TSE_ANIM_DATA, 0);
}
@ -753,7 +735,6 @@ static void outliner_add_id_contents(SpaceOutliner *space_outliner,
}
case ID_CA: {
Camera *ca = (Camera *)id;
if (outliner_animdata_test(ca->adt)) {
outliner_add_element(space_outliner, &te->subtree, ca, te, TSE_ANIM_DATA, 0);
}
@ -761,7 +742,6 @@ static void outliner_add_id_contents(SpaceOutliner *space_outliner,
}
case ID_CF: {
CacheFile *cache_file = (CacheFile *)id;
if (outliner_animdata_test(cache_file->adt)) {
outliner_add_element(space_outliner, &te->subtree, cache_file, te, TSE_ANIM_DATA, 0);
}
@ -770,7 +750,6 @@ static void outliner_add_id_contents(SpaceOutliner *space_outliner,
}
case ID_LA: {
Light *la = (Light *)id;
if (outliner_animdata_test(la->adt)) {
outliner_add_element(space_outliner, &te->subtree, la, te, TSE_ANIM_DATA, 0);
}
@ -778,7 +757,6 @@ static void outliner_add_id_contents(SpaceOutliner *space_outliner,
}
case ID_SPK: {
Speaker *spk = (Speaker *)id;
if (outliner_animdata_test(spk->adt)) {
outliner_add_element(space_outliner, &te->subtree, spk, te, TSE_ANIM_DATA, 0);
}
@ -786,7 +764,6 @@ static void outliner_add_id_contents(SpaceOutliner *space_outliner,
}
case ID_LP: {
LightProbe *prb = (LightProbe *)id;
if (outliner_animdata_test(prb->adt)) {
outliner_add_element(space_outliner, &te->subtree, prb, te, TSE_ANIM_DATA, 0);
}
@ -794,7 +771,6 @@ static void outliner_add_id_contents(SpaceOutliner *space_outliner,
}
case ID_WO: {
World *wrld = (World *)id;
if (outliner_animdata_test(wrld->adt)) {
outliner_add_element(space_outliner, &te->subtree, wrld, te, TSE_ANIM_DATA, 0);
}
@ -802,7 +778,6 @@ static void outliner_add_id_contents(SpaceOutliner *space_outliner,
}
case ID_KE: {
Key *key = (Key *)id;
if (outliner_animdata_test(key->adt)) {
outliner_add_element(space_outliner, &te->subtree, key, te, TSE_ANIM_DATA, 0);
}
@ -815,27 +790,25 @@ static void outliner_add_id_contents(SpaceOutliner *space_outliner,
}
case ID_AR: {
bArmature *arm = (bArmature *)id;
int a = 0;
if (outliner_animdata_test(arm->adt)) {
outliner_add_element(space_outliner, &te->subtree, arm, te, TSE_ANIM_DATA, 0);
}
if (arm->edbo) {
EditBone *ebone;
TreeElement *ten;
for (ebone = arm->edbo->first; ebone; ebone = ebone->next, a++) {
ten = outliner_add_element(space_outliner, &te->subtree, id, te, TSE_EBONE, a);
int a = 0;
LISTBASE_FOREACH_INDEX (EditBone *, ebone, arm->edbo, a) {
TreeElement *ten = outliner_add_element(
space_outliner, &te->subtree, id, te, TSE_EBONE, a);
ten->directdata = ebone;
ten->name = ebone->name;
ebone->temp.p = ten;
}
/* make hierarchy */
ten = arm->edbo->first ? ((EditBone *)arm->edbo->first)->temp.p : NULL;
TreeElement *ten = arm->edbo->first ? ((EditBone *)arm->edbo->first)->temp.p : NULL;
while (ten) {
TreeElement *nten = ten->next, *par;
ebone = (EditBone *)ten->directdata;
EditBone *ebone = (EditBone *)ten->directdata;
if (ebone->parent) {
BLI_remlink(&te->subtree, ten);
par = ebone->parent->temp.p;
@ -852,9 +825,9 @@ static void outliner_add_id_contents(SpaceOutliner *space_outliner,
/* pass */
}
else {
Bone *curBone;
for (curBone = arm->bonebase.first; curBone; curBone = curBone->next) {
outliner_add_bone(space_outliner, &te->subtree, id, curBone, te, &a);
int a = 0;
LISTBASE_FOREACH (Bone *, bone, &arm->bonebase) {
outliner_add_bone(space_outliner, &te->subtree, id, bone, te, &a);
}
}
}
@ -862,13 +835,12 @@ static void outliner_add_id_contents(SpaceOutliner *space_outliner,
}
case ID_LS: {
FreestyleLineStyle *linestyle = (FreestyleLineStyle *)id;
int a;
if (outliner_animdata_test(linestyle->adt)) {
outliner_add_element(space_outliner, &te->subtree, linestyle, te, TSE_ANIM_DATA, 0);
}
for (a = 0; a < MAX_MTEX; a++) {
for (int a = 0; a < MAX_MTEX; a++) {
if (linestyle->mtex[a]) {
outliner_add_element(space_outliner, &te->subtree, linestyle->mtex[a]->tex, te, 0, a);
}
@ -877,17 +849,16 @@ static void outliner_add_id_contents(SpaceOutliner *space_outliner,
}
case ID_GD: {
bGPdata *gpd = (bGPdata *)id;
bGPDlayer *gpl;
int a = 0;
if (outliner_animdata_test(gpd->adt)) {
outliner_add_element(space_outliner, &te->subtree, gpd, te, TSE_ANIM_DATA, 0);
}
/* TODO: base element for layers? */
for (gpl = gpd->layers.last; gpl; gpl = gpl->prev) {
outliner_add_element(space_outliner, &te->subtree, gpl, te, TSE_GP_LAYER, a);
a++;
int index = 0;
LISTBASE_FOREACH_BACKWARD (bGPDlayer *, gpl, &gpd->layers) {
outliner_add_element(space_outliner, &te->subtree, gpl, te, TSE_GP_LAYER, index);
index++;
}
break;
}
@ -957,8 +928,6 @@ TreeElement *outliner_add_element(SpaceOutliner *space_outliner,
short type,
short index)
{
TreeElement *te;
TreeStoreElem *tselem;
ID *id = idv;
if (ELEM(type, TSE_RNA_STRUCT, TSE_RNA_PROPERTY, TSE_RNA_ARRAY_ELEM)) {
@ -985,12 +954,12 @@ TreeElement *outliner_add_element(SpaceOutliner *space_outliner,
BLI_assert(TREESTORE_ID_TYPE(id));
}
te = MEM_callocN(sizeof(TreeElement), "tree elem");
TreeElement *te = MEM_callocN(sizeof(TreeElement), __func__);
/* add to the visual tree */
BLI_addtail(lb, te);
/* add to the storage */
check_persistent(space_outliner, te, id, type, index);
tselem = TREESTORE(te);
TreeStoreElem *tselem = TREESTORE(te);
/* if we are searching for something expand to see child elements */
if (SEARCHING_OUTLINER(space_outliner)) {
@ -1062,7 +1031,6 @@ TreeElement *outliner_add_element(SpaceOutliner *space_outliner,
}
else if (type == TSE_SEQUENCE) {
Sequence *seq = (Sequence *)idv;
Sequence *p;
/*
* The idcode is a little hack, but the outliner
@ -1081,10 +1049,8 @@ TreeElement *outliner_add_element(SpaceOutliner *space_outliner,
*/
if (seq->type == SEQ_TYPE_META) {
p = seq->seqbase.first;
while (p) {
LISTBASE_FOREACH (Sequence *, p, &seq->seqbase) {
outliner_add_element(space_outliner, &te->subtree, (void *)p, te, TSE_SEQUENCE, index);
p = p->next;
}
}
else {
@ -1112,17 +1078,13 @@ TreeElement *outliner_add_element(SpaceOutliner *space_outliner,
te->name = seq->strip->stripdata->name;
}
else if (ELEM(type, TSE_RNA_STRUCT, TSE_RNA_PROPERTY, TSE_RNA_ARRAY_ELEM)) {
PointerRNA pptr, propptr, *ptr = (PointerRNA *)idv;
PropertyRNA *prop, *iterprop;
PropertyType proptype;
PointerRNA *ptr = (PointerRNA *)idv;
/* Don't display arrays larger, weak but index is stored as a short,
* also the outliner isn't intended for editing such large data-sets. */
BLI_STATIC_ASSERT(sizeof(te->index) == 2, "Index is no longer short!")
const int tot_limit = SHRT_MAX;
int a, tot;
/* we do lazy build, for speed and to avoid infinite recursion */
if (ptr->data == NULL) {
@ -1144,8 +1106,8 @@ TreeElement *outliner_add_element(SpaceOutliner *space_outliner,
tselem->flag &= ~TSE_CHILDSEARCH;
}
iterprop = RNA_struct_iterator_property(ptr->type);
tot = RNA_property_collection_length(ptr, iterprop);
PropertyRNA *iterprop = RNA_struct_iterator_property(ptr->type);
int tot = RNA_property_collection_length(ptr, iterprop);
CLAMP_MAX(tot, tot_limit);
/* auto open these cases */
@ -1156,7 +1118,8 @@ TreeElement *outliner_add_element(SpaceOutliner *space_outliner,
}
if (TSELEM_OPEN(tselem, space_outliner)) {
for (a = 0; a < tot; a++) {
for (int a = 0; a < tot; a++) {
PointerRNA propptr;
RNA_property_collection_lookup_int(ptr, iterprop, a, &propptr);
if (!(RNA_property_flag(propptr.data) & PROP_HIDDEN)) {
outliner_add_element(
@ -1172,11 +1135,12 @@ TreeElement *outliner_add_element(SpaceOutliner *space_outliner,
}
else if (type == TSE_RNA_PROPERTY) {
/* property */
iterprop = RNA_struct_iterator_property(ptr->type);
PointerRNA propptr;
PropertyRNA *iterprop = RNA_struct_iterator_property(ptr->type);
RNA_property_collection_lookup_int(ptr, iterprop, index, &propptr);
prop = propptr.data;
proptype = RNA_property_type(prop);
PropertyRNA *prop = propptr.data;
PropertyType proptype = RNA_property_type(prop);
te->name = RNA_property_ui_name(prop);
te->directdata = prop;
@ -1188,7 +1152,7 @@ TreeElement *outliner_add_element(SpaceOutliner *space_outliner,
}
if (proptype == PROP_POINTER) {
pptr = RNA_property_pointer_get(ptr, prop);
PointerRNA pptr = RNA_property_pointer_get(ptr, prop);
if (pptr.data) {
if (TSELEM_OPEN(tselem, space_outliner)) {
@ -1201,11 +1165,12 @@ TreeElement *outliner_add_element(SpaceOutliner *space_outliner,
}
}
else if (proptype == PROP_COLLECTION) {
tot = RNA_property_collection_length(ptr, prop);
int tot = RNA_property_collection_length(ptr, prop);
CLAMP_MAX(tot, tot_limit);
if (TSELEM_OPEN(tselem, space_outliner)) {
for (a = 0; a < tot; a++) {
for (int a = 0; a < tot; a++) {
PointerRNA pptr;
RNA_property_collection_lookup_int(ptr, prop, a, &pptr);
outliner_add_element(
space_outliner, &te->subtree, (void *)&pptr, te, TSE_RNA_STRUCT, a);
@ -1216,11 +1181,11 @@ TreeElement *outliner_add_element(SpaceOutliner *space_outliner,
}
}
else if (ELEM(proptype, PROP_BOOLEAN, PROP_INT, PROP_FLOAT)) {
tot = RNA_property_array_length(ptr, prop);
int tot = RNA_property_array_length(ptr, prop);
CLAMP_MAX(tot, tot_limit);
if (TSELEM_OPEN(tselem, space_outliner)) {
for (a = 0; a < tot; a++) {
for (int a = 0; a < tot; a++) {
outliner_add_element(
space_outliner, &te->subtree, (void *)ptr, te, TSE_RNA_ARRAY_ELEM, a);
}
@ -1231,15 +1196,13 @@ TreeElement *outliner_add_element(SpaceOutliner *space_outliner,
}
}
else if (type == TSE_RNA_ARRAY_ELEM) {
char c;
prop = parent->directdata;
PropertyRNA *prop = parent->directdata;
te->directdata = prop;
te->rnaptr = *ptr;
te->index = index;
c = RNA_property_array_item_char(prop, index);
char c = RNA_property_array_item_char(prop, index);
te->name = MEM_callocN(sizeof(char[20]), "OutlinerRNAArrayName");
if (c) {
@ -1253,16 +1216,14 @@ TreeElement *outliner_add_element(SpaceOutliner *space_outliner,
}
else if (type == TSE_KEYMAP) {
wmKeyMap *km = (wmKeyMap *)idv;
wmKeyMapItem *kmi;
char opname[OP_MAX_TYPENAME];
te->directdata = idv;
te->name = km->idname;
if (TSELEM_OPEN(tselem, space_outliner)) {
int a = 0;
for (kmi = km->items.first; kmi; kmi = kmi->next, a++) {
int a;
LISTBASE_FOREACH_INDEX (wmKeyMapItem *, kmi, &km->items, a) {
const char *key = WM_key_event_string(kmi->type, false);
if (key[0]) {
@ -1344,21 +1305,18 @@ static TreeElement *outliner_add_collection_recursive(SpaceOutliner *space_outli
/* make sure elements are correctly nested */
void outliner_make_object_parent_hierarchy(ListBase *lb)
{
TreeElement *te, *ten, *tep;
TreeStoreElem *tselem;
/* build hierarchy */
/* XXX also, set extents here... */
te = lb->first;
TreeElement *te = lb->first;
while (te) {
ten = te->next;
tselem = TREESTORE(te);
TreeElement *ten = te->next;
TreeStoreElem *tselem = TREESTORE(te);
if (tselem->type == 0 && te->idcode == ID_OB) {
Object *ob = (Object *)tselem->id;
if (ob->parent && ob->parent->id.newid) {
BLI_remlink(lb, te);
tep = (TreeElement *)ob->parent->id.newid;
TreeElement *tep = (TreeElement *)ob->parent->id.newid;
BLI_addtail(&tep->subtree, te);
te->parent = tep;
}
@ -1380,10 +1338,9 @@ typedef struct tTreeSort {
static int treesort_alpha_ob(const void *v1, const void *v2)
{
const tTreeSort *x1 = v1, *x2 = v2;
int comp;
/* first put objects last (hierarchy) */
comp = (x1->idcode == ID_OB);
int comp = (x1->idcode == ID_OB);
if (x2->idcode == ID_OB) {
comp += 2;
}
@ -1432,9 +1389,8 @@ static int treesort_child_not_in_collection(const void *v1, const void *v2)
static int treesort_alpha(const void *v1, const void *v2)
{
const tTreeSort *x1 = v1, *x2 = v2;
int comp;
comp = BLI_strcasecmp_natural(x1->name, x2->name);
int comp = BLI_strcasecmp_natural(x1->name, x2->name);
if (comp > 0) {
return 1;
@ -1489,14 +1445,11 @@ static int treesort_obtype_alpha(const void *v1, const void *v2)
/* sort happens on each subtree individual */
static void outliner_sort(ListBase *lb)
{
TreeElement *te;
TreeStoreElem *tselem;
te = lb->last;
TreeElement *te = lb->last;
if (te == NULL) {
return;
}
tselem = TREESTORE(te);
TreeStoreElem *tselem = TREESTORE(te);
/* sorting rules; only object lists, ID lists, or deformgroups */
if (ELEM(tselem->type, TSE_DEFGROUP, TSE_ID_BASE) ||
@ -1558,14 +1511,11 @@ static void outliner_sort(ListBase *lb)
static void outliner_collections_children_sort(ListBase *lb)
{
TreeElement *te;
TreeStoreElem *tselem;
te = lb->last;
TreeElement *te = lb->last;
if (te == NULL) {
return;
}
tselem = TREESTORE(te);
TreeStoreElem *tselem = TREESTORE(te);
/* Sorting rules: only object lists. */
if (tselem->type == 0 && te->idcode == ID_OB) {
@ -1687,8 +1637,7 @@ static TreeElement *outliner_find_first_desired_element_at_y(const SpaceOutliner
const float view_co,
const float view_co_limit)
{
TreeElement *te, *te_sub;
te = outliner_find_item_at_y(space_outliner, &space_outliner->tree, view_co);
TreeElement *te = outliner_find_item_at_y(space_outliner, &space_outliner->tree, view_co);
bool (*callback_test)(TreeElement *);
if ((space_outliner->outlinevis == SO_VIEW_LAYER) &&
@ -1700,7 +1649,7 @@ static TreeElement *outliner_find_first_desired_element_at_y(const SpaceOutliner
}
while (te != NULL) {
te_sub = outliner_find_first_desired_element_at_y_recursive(
TreeElement *te_sub = outliner_find_first_desired_element_at_y_recursive(
space_outliner, te, view_co_limit, callback_test);
if (te_sub != NULL) {
/* Skip the element if it was not visible to start with. */
@ -1742,12 +1691,12 @@ static void outliner_store_scrolling_position(SpaceOutliner *space_outliner,
ARegion *region,
OutlinerTreeElementFocus *focus)
{
TreeElement *te;
float limit = region->v2d.cur.ymin;
outliner_set_coordinates(region, space_outliner);
te = outliner_find_first_desired_element_at_y(space_outliner, region->v2d.cur.ymax, limit);
TreeElement *te = outliner_find_first_desired_element_at_y(
space_outliner, region->v2d.cur.ymax, limit);
if (te != NULL) {
focus->tselem = TREESTORE(te);

View File

@ -53,6 +53,7 @@
#include "BKE_screen.h"
#include "BKE_workspace.h"
#include "ED_render.h"
#include "ED_screen.h"
#include "ED_space_api.h"
#include "ED_transform.h"
@ -799,6 +800,7 @@ static void *view3d_main_region_duplicate(void *poin)
static void view3d_main_region_listener(const wmRegionListenerParams *params)
{
wmWindow *window = params->window;
ScrArea *area = params->area;
ARegion *region = params->region;
wmNotifier *wmn = params->notifier;
@ -1018,11 +1020,17 @@ static void view3d_main_region_listener(const wmRegionListenerParams *params)
if (wmn->subtype == NS_VIEW3D_GPU) {
rv3d->rflag |= RV3D_GPULIGHT_UPDATE;
}
#ifdef WITH_XR_OPENXR
else if (wmn->subtype == NS_VIEW3D_SHADING) {
#ifdef WITH_XR_OPENXR
ED_view3d_xr_shading_update(G_MAIN->wm.first, v3d, scene);
}
#endif
ViewLayer *view_layer = WM_window_get_active_view_layer(window);
Depsgraph *depsgraph = BKE_scene_get_depsgraph(scene, view_layer);
if (depsgraph) {
ED_render_view3d_update(depsgraph, window, area, true);
}
}
ED_region_tag_redraw(region);
WM_gizmomap_tag_refresh(gzmap);
}

View File

@ -1962,13 +1962,13 @@ ImBuf *ED_view3d_draw_offscreen_imbuf(Depsgraph *depsgraph,
/* XXX(jbakker): `do_color_management` should be controlled by the caller. Currently when doing a
* viewport render animation and saving to an 8bit file format, color management would be applied
* twice. Once here, and once when saving the saving to disk. In this case the Save As Render
* option cannot be controlled either. But when doing an offscreen render you want to do the
* option cannot be controlled either. But when doing an off-screen render you want to do the
* color management here.
*
* This option was added here to increase the performance when rendering for a playblast. When
* using workbench the color differences haven't been reported as a bug. But users also use the
* viewport rendering to render Eevee scenes. In the later situation the saved colors
* are totally wrong. */
* This option was added here to increase the performance for quick view-port preview renders.
* When using workbench the color differences haven't been reported as a bug. But users also use
* the viewport rendering to render Eevee scenes. In the later situation the saved colors are
* totally wrong. */
const bool do_color_management = (ibuf->rect_float == NULL);
ED_view3d_draw_offscreen(depsgraph,
scene,

View File

@ -618,7 +618,7 @@ static void gizmo2d_resize_setup(const bContext *UNUSED(C), wmGizmoGroup *gzgrou
/* set up widget data */
RNA_float_set(gz->ptr, "length", 1.0f);
float axis[3] = {0.0f};
axis[(i + 1) % 2] = 1.0f;
axis[i] = 1.0f;
WM_gizmo_set_matrix_rotation_from_z_axis(gz, axis);
RNA_enum_set(gz->ptr, "draw_style", ED_GIZMO_ARROW_STYLE_BOX);
@ -651,8 +651,8 @@ static void gizmo2d_resize_setup(const bContext *UNUSED(C), wmGizmoGroup *gzgrou
/* Assign operator. */
PointerRNA *ptr = WM_gizmo_operator_set(gz, 0, ot_resize, NULL);
if (i < 2) {
bool constraint[3] = {0};
constraint[(i + 1) % 2] = 1;
bool constraint[3] = {false};
constraint[i] = true;
if (RNA_struct_find_property(ptr, "constraint_axis")) {
RNA_boolean_set_array(ptr, "constraint_axis", constraint);
}

View File

@ -320,8 +320,9 @@ static int ed_undo_step_by_name(bContext *C, const char *undo_name, ReportList *
/* Pointers match on redo. */
const int target_step_index = BLI_findindex(&wm->undo_stack->steps, undo_step_from_name);
const int active_step_index = BLI_findindex(&wm->undo_stack->steps, wm->undo_stack->step_active);
const enum eUndoStepDir undo_dir = (target_step_index < active_step_index) ? STEP_UNDO :
STEP_REDO;
/* NOTE: when current and target active steps are the same, we are in undo case. */
const enum eUndoStepDir undo_dir = (target_step_index <= active_step_index) ? STEP_UNDO :
STEP_REDO;
CLOG_INFO(&LOG,
1,

View File

@ -344,6 +344,20 @@ void GPU_bgl_start()
/* Expected by many addons (see T80169, T81289).
* This will reset the blend function. */
GPU_blend(GPU_BLEND_NONE);
/* Equivalent of setting the depth func `glDepthFunc(GL_LEQUAL)`
* Needed since Python scripts may enable depth test.
* Without this block the depth test function is undefined. */
{
eGPUDepthTest depth_test_real = GPU_depth_test_get();
eGPUDepthTest depth_test_temp = GPU_DEPTH_LESS_EQUAL;
if (depth_test_real != depth_test_temp) {
GPU_depth_test(depth_test_temp);
state_manager.apply_state();
GPU_depth_test(depth_test_real);
}
}
state_manager.apply_state();
state_manager.use_bgl = true;
}

View File

@ -53,11 +53,6 @@ typedef struct img_folder {
float *rates;
} img_fol_t;
enum {
DCP_CINEMA2K = 3,
DCP_CINEMA4K = 4,
};
static bool check_jp2(const unsigned char *mem, const size_t size) /* J2K_CFMT */
{
if (size < sizeof(JP2_HEAD)) {
@ -733,7 +728,7 @@ static void cinema_setup_encoder(opj_cparameters_t *parameters,
parameters->cp_rsiz = OPJ_STD_RSIZ;
}
else {
parameters->cp_rsiz = DCP_CINEMA2K;
parameters->cp_rsiz = OPJ_CINEMA2K;
}
break;
@ -754,7 +749,7 @@ static void cinema_setup_encoder(opj_cparameters_t *parameters,
parameters->cp_rsiz = OPJ_STD_RSIZ;
}
else {
parameters->cp_rsiz = DCP_CINEMA2K;
parameters->cp_rsiz = OPJ_CINEMA4K;
}
parameters->numpocs = init_4K_poc(parameters->POC, parameters->numresolution);
break;

View File

@ -413,11 +413,22 @@ static ImBuf *ibJpegImageFromCinfo(struct jpeg_decompress_struct *cinfo, int fla
jpeg_finish_decompress(cinfo);
}
jpeg_destroy((j_common_ptr)cinfo);
if (ibuf) {
/* Density_unit may be 0 for unknown, 1 for dots/inch, or 2 for dots/cm. */
if (cinfo->density_unit == 1) {
/* Convert inches to meters. */
ibuf->ppm[0] = cinfo->X_density / 0.0254f;
ibuf->ppm[1] = cinfo->Y_density / 0.0254f;
}
else if (cinfo->density_unit == 2) {
ibuf->ppm[0] = cinfo->X_density * 100.0f;
ibuf->ppm[1] = cinfo->Y_density * 100.0f;
}
ibuf->ftype = IMB_FTYPE_JPG;
ibuf->foptions.quality = MIN2(ibuf_quality, 100);
}
jpeg_destroy((j_common_ptr)cinfo);
}
return ibuf;

View File

@ -530,7 +530,8 @@ typedef enum ID_Type {
#define ID_IS_ASSET(_id) (((const ID *)(_id))->asset_data != NULL)
/* Check whether datablock type is covered by copy-on-write. */
#define ID_TYPE_IS_COW(_id_type) (!ELEM(_id_type, ID_BR, ID_PAL, ID_IM))
#define ID_TYPE_IS_COW(_id_type) \
(!ELEM(_id_type, ID_LI, ID_IP, ID_SCR, ID_VF, ID_BR, ID_WM, ID_PAL, ID_PC, ID_WS, ID_IM))
#ifdef GS
# undef GS

View File

@ -128,6 +128,17 @@ static void rna_Image_colormanage_update(Main *bmain, Scene *UNUSED(scene), Poin
WM_main_add_notifier(NC_IMAGE | NA_EDITED, &ima->id);
}
static void rna_Image_alpha_mode_update(Main *bmain, Scene *scene, PointerRNA *ptr)
{
Image *ima = (Image *)ptr->owner_id;
/* When operating on a generated image, avoid re-generating when changing the alpha-mode
* as it doesn't impact generated images, causing them to reload pixel data, see T82785. */
if (ima->source == IMA_SRC_GENERATED) {
return;
}
rna_Image_colormanage_update(bmain, scene, ptr);
}
static void rna_Image_views_format_update(Main *bmain, Scene *scene, PointerRNA *ptr)
{
Image *ima = (Image *)ptr->owner_id;
@ -1133,7 +1144,7 @@ static void rna_def_image(BlenderRNA *brna)
"Alpha Mode",
"Representation of alpha in the image file, to convert to and from "
"when saving and loading the image");
RNA_def_property_update(prop, NC_IMAGE | ND_DISPLAY, "rna_Image_colormanage_update");
RNA_def_property_update(prop, NC_IMAGE | ND_DISPLAY, "rna_Image_alpha_mode_update");
prop = RNA_def_property(srna, "use_half_precision", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", IMA_HIGH_BITDEPTH);

View File

@ -494,22 +494,6 @@ static const EnumPropertyItem rna_node_geometry_attribute_input_type_items_no_bo
{0, NULL, 0, NULL, NULL},
};
static const EnumPropertyItem rna_node_geometry_object_info_transform_space_items[] = {
{GEO_NODE_TRANSFORM_SPACE_ORIGINAL,
"ORIGINAL",
0,
"Original",
"Output the geometry relative to the input object transform, and the location, rotation and "
"scale relative to the world origin"},
{GEO_NODE_TRANSFORM_SPACE_RELATIVE,
"RELATIVE",
0,
"Relative",
"Bring the input object geometry, location, rotation and scale into the modified object, "
"maintaining the relative position between the two objects in the scene"},
{0, NULL, 0, NULL, NULL},
};
#endif
#undef ITEM_ATTRIBUTE
@ -8870,6 +8854,23 @@ static void def_geo_object_info(StructRNA *srna)
{
PropertyRNA *prop;
static const EnumPropertyItem rna_node_geometry_object_info_transform_space_items[] = {
{GEO_NODE_TRANSFORM_SPACE_ORIGINAL,
"ORIGINAL",
0,
"Original",
"Output the geometry relative to the input object transform, and the location, rotation "
"and "
"scale relative to the world origin"},
{GEO_NODE_TRANSFORM_SPACE_RELATIVE,
"RELATIVE",
0,
"Relative",
"Bring the input object geometry, location, rotation and scale into the modified object, "
"maintaining the relative position between the two objects in the scene"},
{0, NULL, 0, NULL, NULL},
};
RNA_def_struct_sdna_from(srna, "NodeGeometryObjectInfo", "storage");
prop = RNA_def_property(srna, "transform_space", PROP_ENUM, PROP_NONE);

View File

@ -4016,7 +4016,7 @@ static void rna_def_particle_system(BlenderRNA *brna)
RNA_def_function_flag(func, FUNC_USE_REPORTS);
parm = RNA_def_pointer(func, "modifier", "ParticleSystemModifier", "", "Particle modifier");
RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED);
prop = RNA_def_pointer(func, "particle", "Particle", "", "Particle");
parm = RNA_def_pointer(func, "particle", "Particle", "", "Particle");
RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED);
RNA_def_int(func, "particle_no", 0, INT_MIN, INT_MAX, "Particle no", "", INT_MIN, INT_MAX);
RNA_def_int(func, "uv_no", 0, INT_MIN, INT_MAX, "UV no", "", INT_MIN, INT_MAX);

View File

@ -4038,7 +4038,10 @@ static void rna_def_space_view3d_overlay(BlenderRNA *brna)
prop = RNA_def_property(srna, "show_face_center", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "overlay.edit_flag", V3D_OVERLAY_EDIT_FACE_DOT);
RNA_def_property_ui_text(prop, "Draw Face Center", "Display face center");
RNA_def_property_ui_text(
prop,
"Draw Face Center",
"Display face center when face selection is enabled in solid shading modes");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL);
prop = RNA_def_property(srna, "show_edge_crease", PROP_BOOLEAN, PROP_NONE);

View File

@ -3005,6 +3005,12 @@ static void rna_def_userdef_theme_space_buts(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Search Match", "");
RNA_def_property_update(prop, 0, "rna_userdef_theme_update");
prop = RNA_def_property(srna, "active_modifier", PROP_FLOAT, PROP_COLOR_GAMMA);
RNA_def_property_float_sdna(prop, NULL, "active");
RNA_def_property_array(prop, 4);
RNA_def_property_ui_text(prop, "Active Modifier Outline", "");
RNA_def_property_update(prop, 0, "rna_userdef_theme_update");
rna_def_userdef_theme_spaces_main(srna);
}

View File

@ -600,6 +600,18 @@ static wmGizmo *rna_GizmoGroup_gizmo_new(wmGizmoGroup *gzgroup,
BKE_reportf(reports, RPT_ERROR, "GizmoType '%s' not known", idname);
return NULL;
}
if ((gzgroup->type->flag & WM_GIZMOGROUPTYPE_3D) == 0) {
/* Allow for neither callbacks to be set, while this doesn't seem like a valid use case,
* there may be rare situations where a developer wants a gizmo to be draw-only. */
if ((gzt->test_select == NULL) && (gzt->draw_select != NULL)) {
BKE_reportf(reports,
RPT_ERROR,
"GizmoType '%s' is for a 3D gizmo-group. "
"The 'draw_select' callback is set where only 'test_select' will be used.",
idname);
return NULL;
}
}
wmGizmo *gz = WM_gizmo_new_ptr(gzt, gzgroup, NULL);
return gz;
}

View File

@ -114,7 +114,12 @@ typedef struct SDefBindPoly {
float weight_dist_proj;
float weight_dist;
float weight;
/** Distances from the centroid to edges flanking the corner vertex, used to penalize
* small or long and narrow faces in favor of bigger and more square ones. */
float scales[2];
/** Distance weight from the corner vertex to the chord line, used to penalize
* cases with the three consecutive vertices being nearly in line. */
float scale_mid;
/** Center of `coords` */
float centroid[3];
/** Center of `coords_v2` */
@ -123,15 +128,18 @@ typedef struct SDefBindPoly {
* The calculated normal of coords (could be shared between faces).
*/
float normal[3];
/** Vectors pointing from the centroid to the midpoints of the two edges
* flanking the corner vertex. */
float cent_edgemid_vecs_v2[2][2];
/**
* The unsigned angle of this face-corner in `[0.0 .. PI]` range,
* where a small value is a thin corner. PI is a straight line.
* Take care dividing by this value as it can approach zero.
*/
/** Angle between the cent_edgemid_vecs_v2 vectors. */
float edgemid_angle;
/** Angles between the centroid-to-point and cent_edgemid_vecs_v2 vectors.
* Positive values measured towards the corner; clamped non-negative. */
float point_edgemid_angles[2];
/** Angles between the centroid-to-corner and cent_edgemid_vecs_v2 vectors. */
float corner_edgemid_angles[2];
/** Weight of the bind mode based on the corner and two adjacent vertices,
* versus the one based on the centroid and the dominant edge. */
float dominant_angle_weight;
/** Index of the input polygon. */
uint index;
@ -414,13 +422,14 @@ BLI_INLINE uint nearestVert(SDefBindCalcData *const data, const float point_co[3
BLI_INLINE int isPolyValid(const float coords[][2], const uint nr)
{
float prev_co[2];
float prev_co[2], prev_prev_co[2];
float curr_vec[2], prev_vec[2];
if (!is_poly_convex_v2(coords, nr)) {
return MOD_SDEF_BIND_RESULT_CONCAVE_ERR;
}
copy_v2_v2(prev_prev_co, coords[nr - 2]);
copy_v2_v2(prev_co, coords[nr - 1]);
sub_v2_v2v2(prev_vec, prev_co, coords[nr - 2]);
normalize_v2(prev_vec);
@ -428,15 +437,23 @@ BLI_INLINE int isPolyValid(const float coords[][2], const uint nr)
for (int i = 0; i < nr; i++) {
sub_v2_v2v2(curr_vec, coords[i], prev_co);
/* Check ovelap between directly adjacent vertices. */
const float curr_len = normalize_v2(curr_vec);
if (curr_len < FLT_EPSILON) {
return MOD_SDEF_BIND_RESULT_OVERLAP_ERR;
}
/* Check ovelap between vertices skipping one. */
if (len_squared_v2v2(prev_prev_co, coords[i]) < FLT_EPSILON * FLT_EPSILON) {
return MOD_SDEF_BIND_RESULT_OVERLAP_ERR;
}
/* Check for adjacent parallel edges. */
if (1.0f - dot_v2v2(prev_vec, curr_vec) < FLT_EPSILON) {
return MOD_SDEF_BIND_RESULT_CONCAVE_ERR;
}
copy_v2_v2(prev_prev_co, prev_co);
copy_v2_v2(prev_co, coords[i]);
copy_v2_v2(prev_vec, curr_vec);
}
@ -460,9 +477,9 @@ static void freeBindData(SDefBindWeightData *const bwdata)
MEM_freeN(bwdata);
}
BLI_INLINE float computeAngularWeight(const float point_angle)
BLI_INLINE float computeAngularWeight(const float point_angle, const float edgemid_angle)
{
return sinf(point_angle * M_PI_2);
return sinf(min_ff(point_angle / edgemid_angle, 1) * M_PI_2);
}
BLI_INLINE SDefBindWeightData *computeBindWeights(SDefBindCalcData *const data,
@ -603,33 +620,51 @@ BLI_INLINE SDefBindWeightData *computeBindWeights(SDefBindCalcData *const data,
avg_point_dist += bpoly->weight_dist;
/* Compute centroid to mid-edge vectors */
mid_v2_v2v2(bpoly->cent_edgemid_vecs_v2[0],
bpoly->coords_v2[bpoly->edge_vert_inds[0]],
bpoly->coords_v2[bpoly->corner_ind]);
/* Common vertex coordinates. */
const float *const vert0_v2 = bpoly->coords_v2[bpoly->edge_vert_inds[0]];
const float *const vert1_v2 = bpoly->coords_v2[bpoly->edge_vert_inds[1]];
const float *const corner_v2 = bpoly->coords_v2[bpoly->corner_ind];
mid_v2_v2v2(bpoly->cent_edgemid_vecs_v2[1],
bpoly->coords_v2[bpoly->edge_vert_inds[1]],
bpoly->coords_v2[bpoly->corner_ind]);
/* Compute centroid to mid-edge vectors */
mid_v2_v2v2(bpoly->cent_edgemid_vecs_v2[0], vert0_v2, corner_v2);
mid_v2_v2v2(bpoly->cent_edgemid_vecs_v2[1], vert1_v2, corner_v2);
sub_v2_v2(bpoly->cent_edgemid_vecs_v2[0], bpoly->centroid_v2);
sub_v2_v2(bpoly->cent_edgemid_vecs_v2[1], bpoly->centroid_v2);
/* Compute poly scales with respect to mid-edges, and normalize the vectors */
bpoly->scales[0] = normalize_v2(bpoly->cent_edgemid_vecs_v2[0]);
bpoly->scales[1] = normalize_v2(bpoly->cent_edgemid_vecs_v2[1]);
normalize_v2(bpoly->cent_edgemid_vecs_v2[0]);
normalize_v2(bpoly->cent_edgemid_vecs_v2[1]);
/* Compute the required polygon angles */
/* Compute poly scales with respect to the two edges. */
bpoly->scales[0] = dist_to_line_v2(bpoly->centroid_v2, vert0_v2, corner_v2);
bpoly->scales[1] = dist_to_line_v2(bpoly->centroid_v2, vert1_v2, corner_v2);
/* Compute the angle between the edge mid vectors. */
bpoly->edgemid_angle = angle_normalized_v2v2(bpoly->cent_edgemid_vecs_v2[0],
bpoly->cent_edgemid_vecs_v2[1]);
sub_v2_v2v2(tmp_vec_v2, bpoly->coords_v2[bpoly->corner_ind], bpoly->centroid_v2);
/* Compute the angles between the corner and the edge mid vectors. The angles
* are computed signed in order to correctly clamp point_edgemid_angles later. */
float corner_angles[2];
sub_v2_v2v2(tmp_vec_v2, corner_v2, bpoly->centroid_v2);
normalize_v2(tmp_vec_v2);
bpoly->corner_edgemid_angles[0] = angle_normalized_v2v2(tmp_vec_v2,
bpoly->cent_edgemid_vecs_v2[0]);
bpoly->corner_edgemid_angles[1] = angle_normalized_v2v2(tmp_vec_v2,
bpoly->cent_edgemid_vecs_v2[1]);
corner_angles[0] = angle_signed_v2v2(tmp_vec_v2, bpoly->cent_edgemid_vecs_v2[0]);
corner_angles[1] = angle_signed_v2v2(tmp_vec_v2, bpoly->cent_edgemid_vecs_v2[1]);
bpoly->corner_edgemid_angles[0] = fabsf(corner_angles[0]);
bpoly->corner_edgemid_angles[1] = fabsf(corner_angles[1]);
/* Verify that the computed values are valid (the polygon isn't somehow
* degenerate despite having passed isPolyValid). */
if (bpoly->scales[0] < FLT_EPSILON || bpoly->scales[1] < FLT_EPSILON ||
bpoly->edgemid_angle < FLT_EPSILON || bpoly->corner_edgemid_angles[0] < FLT_EPSILON ||
bpoly->corner_edgemid_angles[1] < FLT_EPSILON) {
freeBindData(bwdata);
data->success = MOD_SDEF_BIND_RESULT_GENERIC_ERR;
return NULL;
}
/* Check for infinite weights, and compute angular data otherwise. */
if (bpoly->weight_dist < FLT_EPSILON) {
@ -640,15 +675,54 @@ BLI_INLINE SDefBindWeightData *computeBindWeights(SDefBindCalcData *const data,
inf_weight_flags |= MOD_SDEF_INFINITE_WEIGHT_DIST_PROJ;
}
else {
float cent_point_vec[2];
/* Compute angles between the point and the edge mid vectors. */
float cent_point_vec[2], point_angles[2];
sub_v2_v2v2(cent_point_vec, bpoly->point_v2, bpoly->centroid_v2);
normalize_v2(cent_point_vec);
bpoly->point_edgemid_angles[0] = angle_normalized_v2v2(cent_point_vec,
bpoly->cent_edgemid_vecs_v2[0]);
bpoly->point_edgemid_angles[1] = angle_normalized_v2v2(cent_point_vec,
bpoly->cent_edgemid_vecs_v2[1]);
point_angles[0] = angle_signed_v2v2(cent_point_vec, bpoly->cent_edgemid_vecs_v2[0]) *
signf(corner_angles[0]);
point_angles[1] = angle_signed_v2v2(cent_point_vec, bpoly->cent_edgemid_vecs_v2[1]) *
signf(corner_angles[1]);
if (point_angles[0] <= 0 && point_angles[1] <= 0) {
/* If the point is outside the corner formed by the edge mid vectors,
* choose to clamp the closest side and flip the other. */
if (point_angles[0] < point_angles[1]) {
point_angles[0] = bpoly->edgemid_angle - point_angles[1];
}
else {
point_angles[1] = bpoly->edgemid_angle - point_angles[0];
}
}
bpoly->point_edgemid_angles[0] = max_ff(0, point_angles[0]);
bpoly->point_edgemid_angles[1] = max_ff(0, point_angles[1]);
/* Compute the distance scale for the corner. The base value is the orthogonal
* distance from the corner to the chord, scaled by sqrt(2) to preserve the old
* values in case of a square grid. This doesn't use the centroid because the
* LOOPTRI method only uses these three vertices. */
bpoly->scale_mid = area_tri_v2(vert0_v2, corner_v2, vert1_v2) /
len_v2v2(vert0_v2, vert1_v2) * sqrtf(2);
if (bpoly->inside) {
/* When inside, interpolate to centroid-based scale close to the center. */
float min_dist = min_ff(bpoly->scales[0], bpoly->scales[1]);
bpoly->scale_mid = interpf(bpoly->scale_mid,
(bpoly->scales[0] + bpoly->scales[1]) / 2,
min_ff(bpoly->weight_dist_proj / min_dist, 1));
}
/* Verify that the additional computed values are valid. */
if (bpoly->scale_mid < FLT_EPSILON ||
bpoly->point_edgemid_angles[0] + bpoly->point_edgemid_angles[1] < FLT_EPSILON) {
freeBindData(bwdata);
data->success = MOD_SDEF_BIND_RESULT_GENERIC_ERR;
return NULL;
}
}
}
}
@ -688,12 +762,15 @@ BLI_INLINE SDefBindWeightData *computeBindWeights(SDefBindCalcData *const data,
/* Compute angular weight component */
if (epolys->num == 1) {
ang_weights[0] = computeAngularWeight(bpolys[0]->point_edgemid_angles[edge_on_poly[0]]);
ang_weights[0] = computeAngularWeight(bpolys[0]->point_edgemid_angles[edge_on_poly[0]],
bpolys[0]->edgemid_angle);
bpolys[0]->weight_angular *= ang_weights[0] * ang_weights[0];
}
else if (epolys->num == 2) {
ang_weights[0] = computeAngularWeight(bpolys[0]->point_edgemid_angles[edge_on_poly[0]]);
ang_weights[1] = computeAngularWeight(bpolys[1]->point_edgemid_angles[edge_on_poly[1]]);
ang_weights[0] = computeAngularWeight(bpolys[0]->point_edgemid_angles[edge_on_poly[0]],
bpolys[0]->edgemid_angle);
ang_weights[1] = computeAngularWeight(bpolys[1]->point_edgemid_angles[edge_on_poly[1]],
bpolys[1]->edgemid_angle);
bpolys[0]->weight_angular *= ang_weights[0] * ang_weights[1];
bpolys[1]->weight_angular *= ang_weights[0] * ang_weights[1];
@ -731,6 +808,13 @@ BLI_INLINE SDefBindWeightData *computeBindWeights(SDefBindCalcData *const data,
bpoly->dominant_angle_weight = corner_angle_weights[1];
}
/* Check for invalid weights just in case computations fail. */
if (bpoly->dominant_angle_weight < 0 || bpoly->dominant_angle_weight > 1) {
freeBindData(bwdata);
data->success = MOD_SDEF_BIND_RESULT_GENERIC_ERR;
return NULL;
}
bpoly->dominant_angle_weight = sinf(bpoly->dominant_angle_weight * M_PI_2);
/* Compute quadratic angular scale interpolation weight */
@ -748,10 +832,15 @@ BLI_INLINE SDefBindWeightData *computeBindWeights(SDefBindCalcData *const data,
inv_sqr *= inv_sqr;
scale_weight = sqr / (sqr + inv_sqr);
BLI_assert(scale_weight >= 0 && scale_weight <= 1);
/* Compute interpolated scale (no longer need the individual scales,
* so simply storing the result over the scale in index zero) */
bpoly->scales[0] = bpoly->scales[bpoly->dominant_edge] * (1.0f - scale_weight) +
bpoly->scales[!bpoly->dominant_edge] * scale_weight;
bpoly->scales[0] = interpf(bpoly->scale_mid,
interpf(bpoly->scales[!bpoly->dominant_edge],
bpoly->scales[bpoly->dominant_edge],
scale_weight),
bpoly->dominant_angle_weight);
/* Scale the point distance weights, and introduce falloff */
bpoly->weight_dist_proj /= bpoly->scales[0];

View File

@ -163,6 +163,9 @@ static void fill_new_attribute(Span<const GeometryComponent *> src_components,
int offset = 0;
for (const GeometryComponent *component : src_components) {
const int domain_size = component->attribute_domain_size(domain);
if (domain_size == 0) {
continue;
}
ReadAttributePtr read_attribute = component->attribute_get_for_read(
attribute_name, domain, data_type, nullptr);

View File

@ -65,8 +65,7 @@ static int gpu_shader_displacement(GPUMaterial *mat,
mat, node, "node_displacement_object", in, out, GPU_builtin(GPU_OBJECT_MATRIX));
}
return GPU_stack_link(
mat, node, "node_displacement_world", in, out, GPU_builtin(GPU_OBJECT_MATRIX));
return GPU_stack_link(mat, node, "node_displacement_world", in, out);
}
/* node type definition */

View File

@ -424,11 +424,6 @@ static PyGetSetDef bpy_app_getsets[] = {
bpy_app_debug_set,
bpy_app_debug_doc,
(void *)G_DEBUG_SIMDATA},
{"debug_gpumem",
bpy_app_debug_get,
bpy_app_debug_set,
bpy_app_debug_doc,
(void *)G_DEBUG_GPU_MEM},
{"debug_io", bpy_app_debug_get, bpy_app_debug_set, bpy_app_debug_doc, (void *)G_DEBUG_IO},
{"use_event_simulate",

View File

@ -450,6 +450,13 @@ void BPY_python_start(bContext *C, int argc, const char **argv)
py_tstate = PyGILState_GetThisThreadState();
PyEval_ReleaseThread(py_tstate);
#endif
#ifdef WITH_PYTHON_MODULE
/* Disable all add-ons at exit, not essential, it just avoids resource leaks, see T71362. */
BPY_run_string_eval(C,
(const char *[]){"atexit", "addon_utils", NULL},
"atexit.register(addon_utils.disable_all)");
#endif
}
void BPY_python_end(void)

View File

@ -168,6 +168,9 @@ if(WITH_PYTHON)
../python
)
add_definitions(-DWITH_PYTHON)
if(WITH_PYTHON_MODULE)
add_definitions(-DWITH_PYTHON_MODULE)
endif()
endif()
if(WITH_BUILDINFO)

View File

@ -544,6 +544,7 @@ void wm_event_do_notifiers(bContext *C)
LISTBASE_FOREACH (ARegion *, region, &screen->regionbase) {
wmRegionListenerParams region_params = {
.window = win,
.area = NULL,
.region = region,
.scene = scene,
@ -562,6 +563,7 @@ void wm_event_do_notifiers(bContext *C)
ED_area_do_listen(&area_params);
LISTBASE_FOREACH (ARegion *, region, &area->regionbase) {
wmRegionListenerParams region_params = {
.window = win,
.area = area,
.region = region,
.scene = scene,

View File

@ -523,11 +523,15 @@ void WM_exit_ex(bContext *C, const bool do_python)
}
}
#ifdef WITH_PYTHON
#if defined(WITH_PYTHON) && !defined(WITH_PYTHON_MODULE)
/* Without this, we there isn't a good way to manage false-positive resource leaks
* where a #PyObject references memory allocated with guarded-alloc, T71362.
*
* This allows add-ons to free resources when unregistered (which is good practice anyway). */
* This allows add-ons to free resources when unregistered (which is good practice anyway).
*
* Don't run this code when built as a Python module as this runs when Python is in the
* process of shutting down, where running a snippet like this will crash, see T82675.
* Instead use the `atexit` module, installed by #BPY_python_start */
BPY_run_string_eval(C, (const char *[]){"addon_utils", NULL}, "addon_utils.disable_all()");
#endif

View File

@ -1403,8 +1403,6 @@ static uiBlock *wm_block_dialog_create(bContext *C, ARegion *region, void *userD
UI_block_bounds_set_popup(
block, 6 * U.dpi_fac, (const int[2]){data->width / -2, data->height / 2});
UI_block_active_only_flagged_buttons(C, region, block);
return block;
}

View File

@ -587,7 +587,6 @@ static int arg_handle_print_help(int UNUSED(argc), const char **UNUSED(argv), vo
BLI_args_print_arg_doc(ba, "--debug-depsgraph-time");
BLI_args_print_arg_doc(ba, "--debug-depsgraph-pretty");
BLI_args_print_arg_doc(ba, "--debug-gpu");
BLI_args_print_arg_doc(ba, "--debug-gpumem");
BLI_args_print_arg_doc(ba, "--debug-gpu-shaders");
BLI_args_print_arg_doc(ba, "--debug-gpu-force-workarounds");
BLI_args_print_arg_doc(ba, "--debug-wm");
@ -977,9 +976,9 @@ static const char arg_handle_debug_mode_generic_set_doc_depsgraph_no_threads[] =
static const char arg_handle_debug_mode_generic_set_doc_depsgraph_pretty[] =
"\n\t"
"Enable colors for dependency graph debug messages.";
static const char arg_handle_debug_mode_generic_set_doc_gpumem[] =
static const char arg_handle_debug_mode_generic_set_doc_gpu_force_workarounds[] =
"\n\t"
"Enable GPU memory stats in status bar.";
"Enable workarounds for typical GPU issues and disable all GPU extensions.";
static int arg_handle_debug_mode_generic_set(int UNUSED(argc),
const char **UNUSED(argv),
@ -2157,20 +2156,10 @@ void main_args_setup(bContext *C, bArgs *ba)
"--debug-depsgraph-uuid",
CB_EX(arg_handle_debug_mode_generic_set, depsgraph_build),
(void *)G_DEBUG_DEPSGRAPH_UUID);
BLI_args_add(ba,
NULL,
"--debug-gpumem",
CB_EX(arg_handle_debug_mode_generic_set, gpumem),
(void *)G_DEBUG_GPU_MEM);
BLI_args_add(ba,
NULL,
"--debug-gpu-shaders",
CB_EX(arg_handle_debug_mode_generic_set, gpumem),
(void *)G_DEBUG_GPU_SHADERS);
BLI_args_add(ba,
NULL,
"--debug-gpu-force-workarounds",
CB_EX(arg_handle_debug_mode_generic_set, gpumem),
CB_EX(arg_handle_debug_mode_generic_set, gpu_force_workarounds),
(void *)G_DEBUG_GPU_FORCE_WORKAROUNDS);
BLI_args_add(ba, NULL, "--debug-exit-on-error", CB(arg_handle_debug_exit_on_error), NULL);