Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender')
-rw-r--r--source/blender/blenkernel/BKE_camera.h14
-rw-r--r--source/blender/blenkernel/BKE_constraint.h3
-rw-r--r--source/blender/blenkernel/BKE_icons.h2
-rw-r--r--source/blender/blenkernel/BKE_layer.h2
-rw-r--r--source/blender/blenkernel/BKE_modifier.h4
-rw-r--r--source/blender/blenkernel/BKE_node.h1
-rw-r--r--source/blender/blenkernel/BKE_object.h3
-rw-r--r--source/blender/blenkernel/BKE_outliner_treehash.h3
-rw-r--r--source/blender/blenkernel/BKE_particle.h4
-rw-r--r--source/blender/blenkernel/BKE_studiolight.h17
-rw-r--r--source/blender/blenkernel/BKE_workspace.h13
-rw-r--r--source/blender/blenkernel/intern/armature.c2
-rw-r--r--source/blender/blenkernel/intern/bpath.c8
-rw-r--r--source/blender/blenkernel/intern/camera.c25
-rw-r--r--source/blender/blenkernel/intern/collection.c2
-rw-r--r--source/blender/blenkernel/intern/constraint.c44
-rw-r--r--source/blender/blenkernel/intern/icons.c5
-rw-r--r--source/blender/blenkernel/intern/layer.c5
-rw-r--r--source/blender/blenkernel/intern/library_query.c4
-rw-r--r--source/blender/blenkernel/intern/modifier.c15
-rw-r--r--source/blender/blenkernel/intern/node.c1
-rw-r--r--source/blender/blenkernel/intern/object.c22
-rw-r--r--source/blender/blenkernel/intern/object_update.c5
-rw-r--r--source/blender/blenkernel/intern/outliner_treehash.c30
-rw-r--r--source/blender/blenkernel/intern/paint.c10
-rw-r--r--source/blender/blenkernel/intern/particle.c14
-rw-r--r--source/blender/blenkernel/intern/particle_distribute.c4
-rw-r--r--source/blender/blenkernel/intern/particle_system.c8
-rw-r--r--source/blender/blenkernel/intern/pointcache.c17
-rw-r--r--source/blender/blenkernel/intern/rigidbody.c4
-rw-r--r--source/blender/blenkernel/intern/scene.c3
-rw-r--r--source/blender/blenkernel/intern/shrinkwrap.c4
-rw-r--r--source/blender/blenkernel/intern/studiolight.c247
-rw-r--r--source/blender/blenkernel/intern/workspace.c80
-rw-r--r--source/blender/blenlib/BLI_string.h1
-rw-r--r--source/blender/blenlib/BLI_utildefines.h4
-rw-r--r--source/blender/blenlib/intern/string.c36
-rw-r--r--source/blender/blenlib/intern/threads.c3
-rw-r--r--source/blender/blenloader/intern/readfile.c111
-rw-r--r--source/blender/blenloader/intern/versioning_280.c18
-rw-r--r--source/blender/blenloader/intern/versioning_defaults.c3
-rw-r--r--source/blender/blenloader/intern/writefile.c10
-rw-r--r--source/blender/bmesh/CMakeLists.txt2
-rw-r--r--source/blender/compositor/nodes/COM_MathNode.cpp3
-rw-r--r--source/blender/compositor/operations/COM_MathBaseOperation.cpp13
-rw-r--r--source/blender/compositor/operations/COM_MathBaseOperation.h6
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_relations.cc6
-rw-r--r--source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.cc93
-rw-r--r--source/blender/draw/CMakeLists.txt4
-rw-r--r--source/blender/draw/engines/basic/basic_engine.c3
-rw-r--r--source/blender/draw/engines/clay/clay_engine.c10
-rw-r--r--source/blender/draw/engines/eevee/eevee_bloom.c2
-rw-r--r--source/blender/draw/engines/eevee/eevee_depth_of_field.c2
-rw-r--r--source/blender/draw/engines/eevee/eevee_effects.c28
-rw-r--r--source/blender/draw/engines/eevee/eevee_engine.c6
-rw-r--r--source/blender/draw/engines/eevee/eevee_lightprobes.c13
-rw-r--r--source/blender/draw/engines/eevee/eevee_lights.c16
-rw-r--r--source/blender/draw/engines/eevee/eevee_lookdev.c130
-rw-r--r--source/blender/draw/engines/eevee/eevee_materials.c177
-rw-r--r--source/blender/draw/engines/eevee/eevee_occlusion.c10
-rw-r--r--source/blender/draw/engines/eevee/eevee_private.h56
-rw-r--r--source/blender/draw/engines/eevee/eevee_subsurface.c2
-rw-r--r--source/blender/draw/engines/eevee/shaders/ambient_occlusion_lib.glsl3
-rw-r--r--source/blender/draw/engines/eevee/shaders/bsdf_direct_lib.glsl30
-rw-r--r--source/blender/draw/engines/eevee/shaders/default_frag.glsl4
-rw-r--r--source/blender/draw/engines/eevee/shaders/default_world_frag.glsl50
-rw-r--r--source/blender/draw/engines/eevee/shaders/lamps_lib.glsl31
-rw-r--r--source/blender/draw/engines/eevee/shaders/lightprobe_lib.glsl3
-rw-r--r--source/blender/draw/engines/eevee/shaders/raytrace_lib.glsl3
-rw-r--r--source/blender/draw/engines/eevee/shaders/volumetric_lib.glsl5
-rw-r--r--source/blender/draw/engines/workbench/shaders/workbench_checkerboard_depth_frag.glsl2
-rw-r--r--source/blender/draw/engines/workbench/shaders/workbench_common_lib.glsl9
-rw-r--r--source/blender/draw/engines/workbench/shaders/workbench_forward_composite_frag.glsl12
-rw-r--r--source/blender/draw/engines/workbench/shaders/workbench_forward_transparent_accum_frag.glsl9
-rw-r--r--source/blender/draw/engines/workbench/shaders/workbench_forward_transparent_revealage_frag.glsl7
-rw-r--r--source/blender/draw/engines/workbench/shaders/workbench_shadow_caps_geom.glsl2
-rw-r--r--source/blender/draw/engines/workbench/shaders/workbench_shadow_geom.glsl2
-rw-r--r--source/blender/draw/engines/workbench/workbench_data.c2
-rw-r--r--source/blender/draw/engines/workbench/workbench_deferred.c218
-rw-r--r--source/blender/draw/engines/workbench/workbench_forward.c121
-rw-r--r--source/blender/draw/engines/workbench/workbench_materials.c7
-rw-r--r--source/blender/draw/engines/workbench/workbench_private.h31
-rw-r--r--source/blender/draw/engines/workbench/workbench_studiolight.c139
-rw-r--r--source/blender/draw/intern/DRW_render.h25
-rw-r--r--source/blender/draw/intern/draw_armature.c58
-rw-r--r--source/blender/draw/intern/draw_cache.c149
-rw-r--r--source/blender/draw/intern/draw_cache.h24
-rw-r--r--source/blender/draw/intern/draw_cache_impl.h20
-rw-r--r--source/blender/draw/intern/draw_cache_impl_displist.c3
-rw-r--r--source/blender/draw/intern/draw_cache_impl_mesh.c24
-rw-r--r--source/blender/draw/intern/draw_cache_impl_particles.c4
-rw-r--r--source/blender/draw/intern/draw_common.c172
-rw-r--r--source/blender/draw/intern/draw_debug.c151
-rw-r--r--source/blender/draw/intern/draw_debug.h39
-rw-r--r--source/blender/draw/intern/draw_instance_data.h2
-rw-r--r--source/blender/draw/intern/draw_manager.c15
-rw-r--r--source/blender/draw/intern/draw_manager.h16
-rw-r--r--source/blender/draw/intern/draw_manager_data.c3
-rw-r--r--source/blender/draw/intern/draw_manager_exec.c19
-rw-r--r--source/blender/draw/intern/draw_view.c2
-rw-r--r--source/blender/draw/modes/edit_metaball_mode.c4
-rw-r--r--source/blender/draw/modes/edit_surface_mode.c4
-rw-r--r--source/blender/draw/modes/object_mode.c25
-rw-r--r--source/blender/draw/modes/overlay_mode.c6
-rw-r--r--source/blender/draw/modes/shaders/armature_shape_outline_geom.glsl74
-rw-r--r--source/blender/draw/modes/shaders/armature_shape_outline_vert.glsl17
-rw-r--r--source/blender/draw/modes/shaders/armature_shape_solid_frag.glsl2
-rw-r--r--source/blender/draw/modes/shaders/armature_shape_solid_vert.glsl2
-rw-r--r--source/blender/draw/modes/shaders/object_grid_frag.glsl60
-rw-r--r--source/blender/editors/animation/anim_deps.c3
-rw-r--r--source/blender/editors/animation/anim_intern.h1
-rw-r--r--source/blender/editors/animation/anim_ops.c1
-rw-r--r--source/blender/editors/animation/drivers.c41
-rw-r--r--source/blender/editors/armature/pose_select.c24
-rw-r--r--source/blender/editors/armature/pose_transform.c6
-rw-r--r--source/blender/editors/curve/editcurve.c2
-rw-r--r--source/blender/editors/include/ED_screen.h1
-rw-r--r--source/blender/editors/include/ED_transform.h4
-rw-r--r--source/blender/editors/include/ED_transform_snap_object_context.h4
-rw-r--r--source/blender/editors/include/ED_uvedit.h5
-rw-r--r--source/blender/editors/include/ED_view3d.h9
-rw-r--r--source/blender/editors/include/UI_interface.h7
-rw-r--r--source/blender/editors/interface/interface.c12
-rw-r--r--source/blender/editors/interface/interface_handlers.c18
-rw-r--r--source/blender/editors/interface/interface_icons.c2
-rw-r--r--source/blender/editors/interface/interface_intern.h2
-rw-r--r--source/blender/editors/interface/interface_layout.c140
-rw-r--r--source/blender/editors/interface/interface_panel.c4
-rw-r--r--source/blender/editors/interface/interface_region_popover.c65
-rw-r--r--source/blender/editors/interface/interface_widgets.c6
-rw-r--r--source/blender/editors/interface/resources.c12
-rw-r--r--source/blender/editors/mesh/editmesh_path.c113
-rw-r--r--source/blender/editors/mesh/editmesh_select.c75
-rw-r--r--source/blender/editors/mesh/editmesh_tools.c13
-rw-r--r--source/blender/editors/object/object_transform.c4
-rw-r--r--source/blender/editors/physics/particle_edit.c14
-rw-r--r--source/blender/editors/physics/particle_object.c2
-rw-r--r--source/blender/editors/scene/scene_edit.c5
-rw-r--r--source/blender/editors/screen/screen_ops.c12
-rw-r--r--source/blender/editors/screen/workspace_edit.c4
-rw-r--r--source/blender/editors/sculpt_paint/paint_image.c9
-rw-r--r--source/blender/editors/sculpt_paint/paint_image_proj.c11
-rw-r--r--source/blender/editors/sculpt_paint/paint_utils.c46
-rw-r--r--source/blender/editors/space_action/space_action.c54
-rw-r--r--source/blender/editors/space_graph/space_graph.c37
-rw-r--r--source/blender/editors/space_image/space_image.c4
-rw-r--r--source/blender/editors/space_info/info_stats.c18
-rw-r--r--source/blender/editors/space_nla/space_nla.c36
-rw-r--r--source/blender/editors/space_node/drawnode.c18
-rw-r--r--source/blender/editors/space_outliner/outliner_draw.c2
-rw-r--r--source/blender/editors/space_outliner/outliner_intern.h1
-rw-r--r--source/blender/editors/space_outliner/outliner_tree.c19
-rw-r--r--source/blender/editors/space_outliner/outliner_utils.c12
-rw-r--r--source/blender/editors/space_view3d/drawobject.c14
-rw-r--r--source/blender/editors/space_view3d/view3d_draw.c20
-rw-r--r--source/blender/editors/space_view3d/view3d_draw_legacy.c14
-rw-r--r--source/blender/editors/space_view3d/view3d_edit.c22
-rw-r--r--source/blender/editors/space_view3d/view3d_header.c20
-rw-r--r--source/blender/editors/space_view3d/view3d_intern.h6
-rw-r--r--source/blender/editors/space_view3d/view3d_iterators.c12
-rw-r--r--source/blender/editors/space_view3d/view3d_manipulator_camera.c4
-rw-r--r--source/blender/editors/space_view3d/view3d_manipulator_lamp.c30
-rw-r--r--source/blender/editors/space_view3d/view3d_manipulator_ruler.c2
-rw-r--r--source/blender/editors/space_view3d/view3d_ops.c8
-rw-r--r--source/blender/editors/space_view3d/view3d_project.c5
-rw-r--r--source/blender/editors/space_view3d/view3d_ruler.c2
-rw-r--r--source/blender/editors/space_view3d/view3d_select.c14
-rw-r--r--source/blender/editors/space_view3d/view3d_utils.c10
-rw-r--r--source/blender/editors/space_view3d/view3d_view.c12
-rw-r--r--source/blender/editors/space_view3d/view3d_walk.c2
-rw-r--r--source/blender/editors/transform/transform.c6
-rw-r--r--source/blender/editors/transform/transform.h6
-rw-r--r--source/blender/editors/transform/transform_conversions.c104
-rw-r--r--source/blender/editors/transform/transform_generics.c18
-rw-r--r--source/blender/editors/transform/transform_input.c6
-rw-r--r--source/blender/editors/transform/transform_manipulator_3d.c14
-rw-r--r--source/blender/editors/transform/transform_ops.c11
-rw-r--r--source/blender/editors/transform/transform_orientations.c12
-rw-r--r--source/blender/editors/transform/transform_snap.c11
-rw-r--r--source/blender/editors/transform/transform_snap_object.c16
-rw-r--r--source/blender/editors/uvedit/uvedit_ops.c122
-rw-r--r--source/blender/gpu/shaders/gpu_shader_material.glsl5
-rw-r--r--source/blender/makesdna/DNA_ID.h4
-rw-r--r--source/blender/makesdna/DNA_lamp_types.h2
-rw-r--r--source/blender/makesdna/DNA_modifier_types.h3
-rw-r--r--source/blender/makesdna/DNA_node_types.h10
-rw-r--r--source/blender/makesdna/DNA_scene_types.h37
-rw-r--r--source/blender/makesdna/DNA_userdef_types.h1
-rw-r--r--source/blender/makesdna/DNA_view3d_types.h2
-rw-r--r--source/blender/makesdna/DNA_workspace_types.h12
-rw-r--r--source/blender/makesrna/RNA_access.h1
-rw-r--r--source/blender/makesrna/intern/makesrna.c2
-rw-r--r--source/blender/makesrna/intern/rna_ID.c5
-rw-r--r--source/blender/makesrna/intern/rna_access.c21
-rw-r--r--source/blender/makesrna/intern/rna_armature.c10
-rw-r--r--source/blender/makesrna/intern/rna_lamp.c2
-rw-r--r--source/blender/makesrna/intern/rna_lightprobe.c6
-rw-r--r--source/blender/makesrna/intern/rna_material.c9
-rw-r--r--source/blender/makesrna/intern/rna_nodetree.c174
-rw-r--r--source/blender/makesrna/intern/rna_object_api.c17
-rw-r--r--source/blender/makesrna/intern/rna_scene.c45
-rw-r--r--source/blender/makesrna/intern/rna_scene_api.c8
-rw-r--r--source/blender/makesrna/intern/rna_space.c59
-rw-r--r--source/blender/makesrna/intern/rna_ui.c13
-rw-r--r--source/blender/makesrna/intern/rna_userdef.c22
-rw-r--r--source/blender/modifiers/intern/MOD_array.c4
-rw-r--r--source/blender/modifiers/intern/MOD_boolean.c20
-rw-r--r--source/blender/modifiers/intern/MOD_meshdeform.c12
-rw-r--r--source/blender/modifiers/intern/MOD_particlesystem.c51
-rw-r--r--source/blender/modifiers/intern/MOD_surfacedeform.c16
-rw-r--r--source/blender/modifiers/intern/MOD_uvproject.c22
-rw-r--r--source/blender/modifiers/intern/MOD_weightvgproximity.c2
-rw-r--r--source/blender/nodes/CMakeLists.txt1
-rw-r--r--source/blender/nodes/NOD_shader.h1
-rw-r--r--source/blender/nodes/NOD_static_types.h1
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_image.c1
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_ies_light.c61
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_math.c7
-rw-r--r--source/blender/nodes/texture/nodes/node_texture_image.c1
-rw-r--r--source/blender/nodes/texture/nodes/node_texture_math.c6
-rw-r--r--source/blender/python/intern/stubs.c2
-rw-r--r--source/blender/windowmanager/intern/wm_event_system.c9
-rw-r--r--source/blender/windowmanager/intern/wm_keymap.c6
-rw-r--r--source/blender/windowmanager/intern/wm_operators.c2
-rw-r--r--source/blender/windowmanager/manipulators/intern/wm_manipulator.c2
225 files changed, 3710 insertions, 1391 deletions
diff --git a/source/blender/blenkernel/BKE_camera.h b/source/blender/blenkernel/BKE_camera.h
index c647dd3cc0f..eb05e66cf06 100644
--- a/source/blender/blenkernel/BKE_camera.h
+++ b/source/blender/blenkernel/BKE_camera.h
@@ -129,9 +129,9 @@ bool BKE_camera_view_frame_fit_to_scene(
struct Scene *scene, struct ViewLayer *view_layer, struct Object *camera_ob,
float r_co[3], float *r_scale);
bool BKE_camera_view_frame_fit_to_coords(
- const struct Scene *scene,
+ const struct Depsgraph *depsgraph,
const float (*cos)[3], int num_cos,
- const struct Object *camera_ob,
+ struct Object *camera_ob,
float r_co[3], float *r_scale);
void BKE_camera_to_gpu_dof(struct Object *camera, struct GPUFXSettings *r_fx_settings);
@@ -139,11 +139,11 @@ void BKE_camera_to_gpu_dof(struct Object *camera, struct GPUFXSettings *r_fx_set
/* Camera multi-view API */
struct Object *BKE_camera_multiview_render(struct Scene *scene, struct Object *camera, const char *viewname);
-void BKE_camera_multiview_view_matrix(struct RenderData *rd, struct Object *camera, const bool is_left, float r_viewmat[4][4]);
-void BKE_camera_multiview_model_matrix(struct RenderData *rd, struct Object *camera, const char *viewname, float r_modelmat[4][4]);
-float BKE_camera_multiview_shift_x(struct RenderData *rd, struct Object *camera, const char *viewname);
-void BKE_camera_multiview_params(struct RenderData *rd, struct CameraParams *params, struct Object *camera, const char *viewname);
-bool BKE_camera_multiview_spherical_stereo(struct RenderData *rd, struct Object *camera);
+void BKE_camera_multiview_view_matrix(struct RenderData *rd, const struct Object *camera, const bool is_left, float r_viewmat[4][4]);
+void BKE_camera_multiview_model_matrix(struct RenderData *rd, const struct Object *camera, const char *viewname, float r_modelmat[4][4]);
+float BKE_camera_multiview_shift_x(struct RenderData *rd, const struct Object *camera, const char *viewname);
+void BKE_camera_multiview_params(struct RenderData *rd, struct CameraParams *params, const struct Object *camera, const char *viewname);
+bool BKE_camera_multiview_spherical_stereo(struct RenderData *rd, const struct Object *camera);
/* Camera background image API */
struct CameraBGImage *BKE_camera_background_image_new(struct Camera *cam);
diff --git a/source/blender/blenkernel/BKE_constraint.h b/source/blender/blenkernel/BKE_constraint.h
index 18f6301953c..98ba0f6f2a4 100644
--- a/source/blender/blenkernel/BKE_constraint.h
+++ b/source/blender/blenkernel/BKE_constraint.h
@@ -49,6 +49,7 @@ extern "C" {
/* special struct for use in constraint evaluation */
typedef struct bConstraintOb {
+ struct Depsgraph *depsgraph;/* to get evaluated armature. */
struct Scene *scene; /* for system time, part of deglobalization, code nicer later with local time (ton) */
struct Object *ob; /* if pchan, then armature that it comes from, otherwise constraint owner */
struct bPoseChannel *pchan; /* pose channel that owns the constraints being evaluated */
@@ -144,7 +145,7 @@ void BKE_constraints_proxylocal_extract(struct ListBase *dst, struct ListBase *s
bool BKE_constraints_proxylocked_owner(struct Object *ob, struct bPoseChannel *pchan);
/* Constraint Evaluation function prototypes */
-struct bConstraintOb *BKE_constraints_make_evalob(struct Scene *scene, struct Object *ob, void *subdata, short datatype);
+struct bConstraintOb *BKE_constraints_make_evalob(struct Depsgraph *depsgraph, struct Scene *scene, struct Object *ob, void *subdata, short datatype);
void BKE_constraints_clear_evalob(struct bConstraintOb *cob);
void BKE_constraint_mat_convertspace(
diff --git a/source/blender/blenkernel/BKE_icons.h b/source/blender/blenkernel/BKE_icons.h
index e54531bdb0e..22897d2ea80 100644
--- a/source/blender/blenkernel/BKE_icons.h
+++ b/source/blender/blenkernel/BKE_icons.h
@@ -160,7 +160,7 @@ struct ImBuf *BKE_icon_geom_rasterize(
const struct Icon_Geom *geom,
const unsigned int size_x, const unsigned int size_y);
-int BKE_icon_ensure_studio_light(struct StudioLight *sl);
+int BKE_icon_ensure_studio_light(struct StudioLight *sl, int id_type);
#define ICON_RENDER_DEFAULT_HEIGHT 32
diff --git a/source/blender/blenkernel/BKE_layer.h b/source/blender/blenkernel/BKE_layer.h
index 626a1cd09e3..60204d177f2 100644
--- a/source/blender/blenkernel/BKE_layer.h
+++ b/source/blender/blenkernel/BKE_layer.h
@@ -80,7 +80,7 @@ void BKE_view_layer_copy_data(
struct ViewLayer *view_layer_dst, const struct ViewLayer *view_layer_src,
const int flag);
-void BKE_view_layer_rename(struct Scene *scene, struct ViewLayer *view_layer, const char *name);
+void BKE_view_layer_rename(struct Main *bmain, struct Scene *scene, struct ViewLayer *view_layer, const char *name);
struct LayerCollection *BKE_layer_collection_get_active(struct ViewLayer *view_layer);
bool BKE_layer_collection_activate(struct ViewLayer *view_layer, struct LayerCollection *lc);
diff --git a/source/blender/blenkernel/BKE_modifier.h b/source/blender/blenkernel/BKE_modifier.h
index ab00b8174b5..c8d50793e76 100644
--- a/source/blender/blenkernel/BKE_modifier.h
+++ b/source/blender/blenkernel/BKE_modifier.h
@@ -557,7 +557,9 @@ struct DerivedMesh *modifier_applyModifierEM_DM_deprecated(
struct ModifierData *md, const struct ModifierEvalContext *ctx,
struct BMEditMesh *editData, struct DerivedMesh *dm);
-struct Mesh *BKE_modifier_get_evaluated_mesh_from_object(struct Object *ob, const ModifierApplyFlag flag);
+struct Mesh *BKE_modifier_get_evaluated_mesh_from_object(
+ const struct ModifierEvalContext *ctx,
+ struct Object *ob);
#endif
diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h
index f3cbcd7b99f..c654dd51e2a 100644
--- a/source/blender/blenkernel/BKE_node.h
+++ b/source/blender/blenkernel/BKE_node.h
@@ -796,6 +796,7 @@ void BKE_nodetree_remove_layer_n(struct bNodeTree *ntree, struct Scene *scene, c
#define SH_NODE_UVALONGSTROKE 191
#define SH_NODE_TEX_POINTDENSITY 192
#define SH_NODE_BSDF_PRINCIPLED 193
+#define SH_NODE_TEX_IES 194
#define SH_NODE_EEVEE_SPECULAR 195
#define SH_NODE_BEVEL 197
#define SH_NODE_DISPLACEMENT 198
diff --git a/source/blender/blenkernel/BKE_object.h b/source/blender/blenkernel/BKE_object.h
index 7dbdac1b835..db6c7aa9c4f 100644
--- a/source/blender/blenkernel/BKE_object.h
+++ b/source/blender/blenkernel/BKE_object.h
@@ -45,6 +45,7 @@ struct View3D;
struct SoftBody;
struct MovieClip;
struct Main;
+struct Mesh;
struct RigidBodyWorld;
struct HookModifierData;
struct ModifierData;
@@ -269,6 +270,8 @@ void BKE_object_sculpt_modifiers_changed(struct Object *ob);
int BKE_object_obdata_texspace_get(struct Object *ob, short **r_texflag, float **r_loc, float **r_size, float **r_rot);
+struct Mesh *BKE_object_get_evaluated_mesh(const struct Depsgraph *depsgraph, struct Object *ob);
+
int BKE_object_insert_ptcache(struct Object *ob);
void BKE_object_delete_ptcache(struct Object *ob, int index);
struct KeyBlock *BKE_object_shapekey_insert(struct Object *ob, const char *name, const bool from_mix);
diff --git a/source/blender/blenkernel/BKE_outliner_treehash.h b/source/blender/blenkernel/BKE_outliner_treehash.h
index b82bc692402..8a14f8fb041 100644
--- a/source/blender/blenkernel/BKE_outliner_treehash.h
+++ b/source/blender/blenkernel/BKE_outliner_treehash.h
@@ -36,6 +36,9 @@ void *BKE_outliner_treehash_create_from_treestore(struct BLI_mempool *treestore)
/* full rebuild for already allocated hashtable */
void *BKE_outliner_treehash_rebuild_from_treestore(void *treehash, struct BLI_mempool *treestore);
+/* clear element usage flags */
+void BKE_outliner_treehash_clear_used(void *treehash);
+
/* Add/remove hashtable elements */
void BKE_outliner_treehash_add_element(void *treehash, struct TreeStoreElem *elem);
void BKE_outliner_treehash_remove_element(void *treehash, struct TreeStoreElem *elem);
diff --git a/source/blender/blenkernel/BKE_particle.h b/source/blender/blenkernel/BKE_particle.h
index b6a87ae333e..4820f0173bf 100644
--- a/source/blender/blenkernel/BKE_particle.h
+++ b/source/blender/blenkernel/BKE_particle.h
@@ -439,8 +439,8 @@ void psys_particle_on_dm(struct Mesh *mesh_final, int from, int index, int index
/* particle_system.c */
void distribute_particles(struct ParticleSimulationData *sim, int from);
void initialize_particle(struct ParticleSimulationData *sim, struct ParticleData *pa);
-void psys_calc_dmcache(struct Object *ob, struct Mesh *mesh_final, struct Mesh *mesh_deformed, struct ParticleSystem *psys);
-int psys_particle_dm_face_lookup(struct Mesh *mesh_final, struct Mesh *mesh_deformed, int findex, const float fw[4], struct LinkNode **poly_nodes);
+void psys_calc_dmcache(struct Object *ob, struct Mesh *mesh_final, struct Mesh *mesh_original, struct ParticleSystem *psys);
+int psys_particle_dm_face_lookup(struct Mesh *mesh_final, struct Mesh *mesh_original, int findex, const float fw[4], struct LinkNode **poly_nodes);
void reset_particle(struct ParticleSimulationData *sim, struct ParticleData *pa, float dtime, float cfra);
diff --git a/source/blender/blenkernel/BKE_studiolight.h b/source/blender/blenkernel/BKE_studiolight.h
index 2fcf6ab2f19..213de712abd 100644
--- a/source/blender/blenkernel/BKE_studiolight.h
+++ b/source/blender/blenkernel/BKE_studiolight.h
@@ -51,6 +51,10 @@
#define STUDIOLIGHT_Y_NEG 3
#define STUDIOLIGHT_Z_POS 4
#define STUDIOLIGHT_Z_NEG 5
+#define STUDIOLIGHT_ICON_ID_TYPE_RADIANCE 0
+#define STUDIOLIGHT_ICON_ID_TYPE_IRRADIANCE 1
+
+struct GPUTexture;
enum StudioLightFlag {
STUDIOLIGHT_DIFFUSE_LIGHT_CALCULATED = (1 << 0),
@@ -58,7 +62,9 @@ enum StudioLightFlag {
STUDIOLIGHT_EXTERNAL_FILE = (1 << 2),
STUDIOLIGHT_ORIENTATION_CAMERA = (1 << 3),
STUDIOLIGHT_ORIENTATION_WORLD = (1 << 4),
- STUDIOLIGHT_RADIANCE_BUFFERS_CALCULATED = (1 << 5),
+ STUDIOLIGHT_EQUIRECTANGULAR_IMAGE_LOADED = (1 << 5),
+ STUDIOLIGHT_EQUIRECTANGULAR_GPUTEXTURE = (1 << 6),
+ STUDIOLIGHT_RADIANCE_BUFFERS_CALCULATED = (1 << 7),
} StudioLightFlag;
typedef struct StudioLight {
@@ -66,18 +72,21 @@ typedef struct StudioLight {
int flag;
char name[FILE_MAXFILE];
char path[FILE_MAX];
- int icon_id;
+ int irradiance_icon_id;
+ int radiance_icon_id;
int index;
float diffuse_light[6][3];
float light_direction[3];
+ ImBuf *equirectangular_buffer;
ImBuf *radiance_buffers[6];
+ struct GPUTexture *equirectangular_gputexture;
} StudioLight;
void BKE_studiolight_init(void);
void BKE_studiolight_free(void);
-struct StudioLight *BKE_studiolight_find(const char *name);
+struct StudioLight *BKE_studiolight_find(const char *name, int flag);
struct StudioLight *BKE_studiolight_findindex(int index);
-unsigned int *BKE_studiolight_preview(StudioLight *sl, int icon_size);
+unsigned int *BKE_studiolight_preview(StudioLight *sl, int icon_size, int icon_id_type);
const struct ListBase *BKE_studiolight_listbase(void);
void BKE_studiolight_ensure_flag(StudioLight *sl, int flag);
diff --git a/source/blender/blenkernel/BKE_workspace.h b/source/blender/blenkernel/BKE_workspace.h
index 5ee15a08f9b..5442fd43ce5 100644
--- a/source/blender/blenkernel/BKE_workspace.h
+++ b/source/blender/blenkernel/BKE_workspace.h
@@ -53,12 +53,20 @@ void BKE_workspace_layout_remove(
void BKE_workspace_relations_free(
ListBase *relation_list);
+void BKE_workspace_scene_relations_free_invalid(
+ struct WorkSpace *workspace);
/* -------------------------------------------------------------------- */
/* General Utils */
-void BKE_workspace_view_layer_remove_references(
+void BKE_workspace_view_layer_rename(
+ const struct Main *bmain,
+ const struct Scene *scene,
+ const char *old_name,
+ const char *new_name) ATTR_NONNULL();
+
+void BKE_workspace_view_layer_remove(
const struct Main *bmain,
const struct ViewLayer *view_layer) ATTR_NONNULL();
@@ -92,6 +100,9 @@ struct Base *BKE_workspace_active_base_get(const struct WorkSpace *workspace, co
struct ViewLayer *BKE_workspace_view_layer_get(
const struct WorkSpace *workspace,
const struct Scene *scene) GETTER_ATTRS;
+struct ViewLayer *BKE_workspace_view_layer_exists(
+ const struct WorkSpace *workspace,
+ const struct Scene *scene) GETTER_ATTRS;
void BKE_workspace_view_layer_set(
struct WorkSpace *workspace,
struct ViewLayer *layer,
diff --git a/source/blender/blenkernel/intern/armature.c b/source/blender/blenkernel/intern/armature.c
index f80096b39eb..8dbfc35c774 100644
--- a/source/blender/blenkernel/intern/armature.c
+++ b/source/blender/blenkernel/intern/armature.c
@@ -2239,7 +2239,7 @@ void BKE_pose_where_is_bone(
/* prepare PoseChannel for Constraint solving
* - makes a copy of matrix, and creates temporary struct to use
*/
- cob = BKE_constraints_make_evalob(scene, ob, pchan, CONSTRAINT_OBTYPE_BONE);
+ cob = BKE_constraints_make_evalob(depsgraph, scene, ob, pchan, CONSTRAINT_OBTYPE_BONE);
/* Solve PoseChannel's Constraints */
BKE_constraints_solve(depsgraph, &pchan->constraints, cob, ctime); /* ctime doesnt alter objects */
diff --git a/source/blender/blenkernel/intern/bpath.c b/source/blender/blenkernel/intern/bpath.c
index 259c5189896..dbaf3f2ee9e 100644
--- a/source/blender/blenkernel/intern/bpath.c
+++ b/source/blender/blenkernel/intern/bpath.c
@@ -560,6 +560,10 @@ void BKE_bpath_traverse_id(Main *bmain, ID *id, BPathVisitor visit_cb, const int
NodeShaderScript *nss = (NodeShaderScript *)node->storage;
rewrite_path_fixed(nss->filepath, visit_cb, absbase, bpath_user_data);
}
+ else if (node->type == SH_NODE_TEX_IES) {
+ NodeShaderTexIES *ies = (NodeShaderTexIES *)node->storage;
+ rewrite_path_fixed(ies->filepath, visit_cb, absbase, bpath_user_data);
+ }
}
}
break;
@@ -576,6 +580,10 @@ void BKE_bpath_traverse_id(Main *bmain, ID *id, BPathVisitor visit_cb, const int
NodeShaderScript *nss = (NodeShaderScript *)node->storage;
rewrite_path_fixed(nss->filepath, visit_cb, absbase, bpath_user_data);
}
+ else if (node->type == SH_NODE_TEX_IES) {
+ NodeShaderTexIES *ies = (NodeShaderTexIES *)node->storage;
+ rewrite_path_fixed(ies->filepath, visit_cb, absbase, bpath_user_data);
+ }
}
}
break;
diff --git a/source/blender/blenkernel/intern/camera.c b/source/blender/blenkernel/intern/camera.c
index a18fd9ead87..b1b4f18a6d5 100644
--- a/source/blender/blenkernel/intern/camera.c
+++ b/source/blender/blenkernel/intern/camera.c
@@ -268,7 +268,7 @@ void BKE_camera_params_from_view3d(CameraParams *params, Depsgraph *depsgraph, c
if (rv3d->persp == RV3D_CAMOB) {
/* camera view */
- Object *ob_camera_eval = DEG_get_evaluated_object(depsgraph, v3d->camera);
+ const Object *ob_camera_eval = DEG_get_evaluated_object(depsgraph, v3d->camera);
BKE_camera_params_from_object(params, ob_camera_eval);
params->zoom = BKE_screen_view3d_zoom_to_fac(rv3d->camzoom);
@@ -666,16 +666,18 @@ bool BKE_camera_view_frame_fit_to_scene(
}
bool BKE_camera_view_frame_fit_to_coords(
- const Scene *scene, const float (*cos)[3], int num_cos, const Object *camera_ob,
+ const Depsgraph *depsgraph, const float (*cos)[3], int num_cos, Object *camera_ob,
float r_co[3], float *r_scale)
{
+ Scene *scene_eval = DEG_get_evaluated_scene(depsgraph);
+ Object *camera_ob_eval = DEG_get_evaluated_object(depsgraph, camera_ob);
CameraParams params;
CameraViewFrameData data_cb;
/* just in case */
*r_scale = 1.0f;
- camera_frame_fit_data_init(scene, camera_ob, &params, &data_cb);
+ camera_frame_fit_data_init(scene_eval, camera_ob_eval, &params, &data_cb);
/* run callback on all given coordinates */
while (num_cos--) {
@@ -687,12 +689,12 @@ bool BKE_camera_view_frame_fit_to_coords(
/******************* multiview matrix functions ***********************/
-static void camera_model_matrix(Object *camera, float r_modelmat[4][4])
+static void camera_model_matrix(const Object *camera, float r_modelmat[4][4])
{
copy_m4_m4(r_modelmat, camera->obmat);
}
-static void camera_stereo3d_model_matrix(Object *camera, const bool is_left, float r_modelmat[4][4])
+static void camera_stereo3d_model_matrix(const Object *camera, const bool is_left, float r_modelmat[4][4])
{
Camera *data = (Camera *)camera->data;
float interocular_distance, convergence_distance;
@@ -790,7 +792,7 @@ static void camera_stereo3d_model_matrix(Object *camera, const bool is_left, flo
}
/* the view matrix is used by the viewport drawing, it is basically the inverted model matrix */
-void BKE_camera_multiview_view_matrix(RenderData *rd, Object *camera, const bool is_left, float r_viewmat[4][4])
+void BKE_camera_multiview_view_matrix(RenderData *rd, const Object *camera, const bool is_left, float r_viewmat[4][4])
{
BKE_camera_multiview_model_matrix(rd, camera, is_left ? STEREO_LEFT_NAME : STEREO_RIGHT_NAME, r_viewmat);
invert_m4(r_viewmat);
@@ -805,7 +807,7 @@ static bool camera_is_left(const char *viewname)
return true;
}
-void BKE_camera_multiview_model_matrix(RenderData *rd, Object *camera, const char *viewname, float r_modelmat[4][4])
+void BKE_camera_multiview_model_matrix(RenderData *rd, const Object *camera, const char *viewname, float r_modelmat[4][4])
{
const bool is_multiview = (rd && rd->scemode & R_MULTIVIEW) != 0;
@@ -822,7 +824,7 @@ void BKE_camera_multiview_model_matrix(RenderData *rd, Object *camera, const cha
normalize_m4(r_modelmat);
}
-bool BKE_camera_multiview_spherical_stereo(RenderData *rd, Object *camera)
+bool BKE_camera_multiview_spherical_stereo(RenderData *rd, const Object *camera)
{
Camera *cam;
const bool is_multiview = (rd && rd->scemode & R_MULTIVIEW) != 0;
@@ -895,7 +897,7 @@ Object *BKE_camera_multiview_render(Scene *scene, Object *camera, const char *vi
}
}
-static float camera_stereo3d_shift_x(Object *camera, const char *viewname)
+static float camera_stereo3d_shift_x(const Object *camera, const char *viewname)
{
Camera *data = camera->data;
float shift = data->shiftx;
@@ -933,7 +935,7 @@ static float camera_stereo3d_shift_x(Object *camera, const char *viewname)
return shift;
}
-float BKE_camera_multiview_shift_x(RenderData *rd, Object *camera, const char *viewname)
+float BKE_camera_multiview_shift_x(RenderData *rd, const Object *camera, const char *viewname)
{
const bool is_multiview = (rd && rd->scemode & R_MULTIVIEW) != 0;
Camera *data = camera->data;
@@ -951,7 +953,7 @@ float BKE_camera_multiview_shift_x(RenderData *rd, Object *camera, const char *v
}
}
-void BKE_camera_multiview_params(RenderData *rd, CameraParams *params, Object *camera, const char *viewname)
+void BKE_camera_multiview_params(RenderData *rd, CameraParams *params, const Object *camera, const char *viewname)
{
if (camera->type == OB_CAMERA) {
params->shiftx = BKE_camera_multiview_shift_x(rd, camera, viewname);
@@ -977,6 +979,7 @@ CameraBGImage *BKE_camera_background_image_new(Camera *cam)
bgpic->alpha = 0.5f;
bgpic->iuser.fie_ima = 2;
bgpic->iuser.ok = 1;
+ bgpic->iuser.flag |= IMA_ANIM_ALWAYS;
bgpic->flag |= CAM_BGIMG_FLAG_EXPANDED;
BLI_addtail(&cam->bg_images, bgpic);
diff --git a/source/blender/blenkernel/intern/collection.c b/source/blender/blenkernel/intern/collection.c
index 30ed796d73f..c4709a32f78 100644
--- a/source/blender/blenkernel/intern/collection.c
+++ b/source/blender/blenkernel/intern/collection.c
@@ -614,7 +614,7 @@ bool BKE_collection_object_remove(Main *bmain, Collection *collection, Object *o
return false;
}
- if (collection_object_remove(bmain, collection, ob, free_us)) {
+ if (!collection_object_remove(bmain, collection, ob, free_us)) {
return false;
}
diff --git a/source/blender/blenkernel/intern/constraint.c b/source/blender/blenkernel/intern/constraint.c
index 6a477c9c06e..28c6fe852c2 100644
--- a/source/blender/blenkernel/intern/constraint.c
+++ b/source/blender/blenkernel/intern/constraint.c
@@ -84,6 +84,9 @@
#include "BIK_api.h"
+#include "DEG_depsgraph.h"
+#include "DEG_depsgraph_query.h"
+
#ifdef WITH_PYTHON
# include "BPY_extern.h"
#endif
@@ -116,7 +119,7 @@ void BKE_constraint_unique_name(bConstraint *con, ListBase *list)
/* package an object/bone for use in constraint evaluation */
/* This function MEM_calloc's a bConstraintOb struct, that will need to be freed after evaluation */
-bConstraintOb *BKE_constraints_make_evalob(Scene *scene, Object *ob, void *subdata, short datatype)
+bConstraintOb *BKE_constraints_make_evalob(Depsgraph *depsgraph, Scene *scene, Object *ob, void *subdata, short datatype)
{
bConstraintOb *cob;
@@ -125,6 +128,7 @@ bConstraintOb *BKE_constraints_make_evalob(Scene *scene, Object *ob, void *subda
/* for system time, part of deglobalization, code nicer later with local time (ton) */
cob->scene = scene;
+ cob->depsgraph = depsgraph;
/* based on type of available data */
switch (datatype) {
@@ -3903,20 +3907,25 @@ static void followtrack_id_looper(bConstraint *con, ConstraintIDFunc func, void
static void followtrack_evaluate(bConstraint *con, bConstraintOb *cob, ListBase *UNUSED(targets))
{
+ Depsgraph *depsgraph = cob->depsgraph;
Scene *scene = cob->scene;
bFollowTrackConstraint *data = con->data;
MovieClip *clip = data->clip;
MovieTracking *tracking;
MovieTrackingTrack *track;
MovieTrackingObject *tracking_object;
- Object *camob = data->camera ? data->camera : scene->camera;
- float ctime = BKE_scene_frame_get(scene);
+
+ Object *camob_eval = DEG_get_evaluated_object(
+ depsgraph,
+ data->camera ? data->camera : scene->camera);
+
+ float ctime = DEG_get_ctime(depsgraph);;
float framenr;
if (data->flag & FOLLOWTRACK_ACTIVECLIP)
clip = scene->clip;
- if (!clip || !data->track[0] || !camob)
+ if (!clip || !data->track[0] || !camob_eval)
return;
tracking = &clip->tracking;
@@ -3945,7 +3954,7 @@ static void followtrack_evaluate(bConstraint *con, bConstraintOb *cob, ListBase
if ((tracking_object->flag & TRACKING_OBJECT_CAMERA) == 0) {
float imat[4][4];
- copy_m4_m4(mat, camob->obmat);
+ copy_m4_m4(mat, camob_eval->obmat);
BKE_tracking_camera_get_reconstructed_interpolate(tracking, tracking_object, framenr, imat);
invert_m4(imat);
@@ -3954,7 +3963,7 @@ static void followtrack_evaluate(bConstraint *con, bConstraintOb *cob, ListBase
translate_m4(cob->matrix, track->bundle_pos[0], track->bundle_pos[1], track->bundle_pos[2]);
}
else {
- BKE_tracking_get_camera_object_matrix(cob->scene, camob, mat);
+ BKE_tracking_get_camera_object_matrix(cob->scene, camob_eval, mat);
mul_m4_m4m4(cob->matrix, obmat, mat);
translate_m4(cob->matrix, track->bundle_pos[0], track->bundle_pos[1], track->bundle_pos[2]);
@@ -3966,7 +3975,7 @@ static void followtrack_evaluate(bConstraint *con, bConstraintOb *cob, ListBase
float aspect = (scene->r.xsch * scene->r.xasp) / (scene->r.ysch * scene->r.yasp);
float len, d;
- BKE_object_where_is_calc_mat4(scene, camob, mat);
+ BKE_object_where_is_calc_mat4(scene, camob_eval, mat);
/* camera axis */
vec[0] = 0.0f;
@@ -4034,7 +4043,7 @@ static void followtrack_evaluate(bConstraint *con, bConstraintOb *cob, ListBase
}
BKE_camera_params_init(&params);
- BKE_camera_params_from_object(&params, camob);
+ BKE_camera_params_from_object(&params, camob_eval);
if (params.is_ortho) {
vec[0] = params.ortho_scale * (pos[0] - 0.5f + params.shiftx);
@@ -4046,9 +4055,9 @@ static void followtrack_evaluate(bConstraint *con, bConstraintOb *cob, ListBase
else
vec[0] *= aspect;
- mul_v3_m4v3(disp, camob->obmat, vec);
+ mul_v3_m4v3(disp, camob_eval->obmat, vec);
- copy_m4_m4(rmat, camob->obmat);
+ copy_m4_m4(rmat, camob_eval->obmat);
zero_v3(rmat[3]);
mul_m4_m4m4(cob->matrix, cob->matrix, rmat);
@@ -4066,10 +4075,10 @@ static void followtrack_evaluate(bConstraint *con, bConstraintOb *cob, ListBase
else
vec[0] *= aspect;
- mul_v3_m4v3(disp, camob->obmat, vec);
+ mul_v3_m4v3(disp, camob_eval->obmat, vec);
/* apply camera rotation so Z-axis would be co-linear */
- copy_m4_m4(rmat, camob->obmat);
+ copy_m4_m4(rmat, camob_eval->obmat);
zero_v3(rmat[3]);
mul_m4_m4m4(cob->matrix, cob->matrix, rmat);
@@ -4088,7 +4097,7 @@ static void followtrack_evaluate(bConstraint *con, bConstraintOb *cob, ListBase
invert_m4_m4(imat, depth_ob->obmat);
- mul_v3_m4v3(ray_start, imat, camob->obmat[3]);
+ mul_v3_m4v3(ray_start, imat, camob_eval->obmat[3]);
mul_v3_m4v3(ray_end, imat, cob->matrix[3]);
sub_v3_v3v3(ray_nor, ray_end, ray_start);
@@ -4147,6 +4156,7 @@ static void camerasolver_id_looper(bConstraint *con, ConstraintIDFunc func, void
static void camerasolver_evaluate(bConstraint *con, bConstraintOb *cob, ListBase *UNUSED(targets))
{
+ Depsgraph *depsgraph = cob->depsgraph;
Scene *scene = cob->scene;
bCameraSolverConstraint *data = con->data;
MovieClip *clip = data->clip;
@@ -4158,7 +4168,7 @@ static void camerasolver_evaluate(bConstraint *con, bConstraintOb *cob, ListBase
float mat[4][4], obmat[4][4];
MovieTracking *tracking = &clip->tracking;
MovieTrackingObject *object = BKE_tracking_object_get_camera(tracking);
- float ctime = BKE_scene_frame_get(scene);
+ float ctime = DEG_get_ctime(depsgraph);
float framenr = BKE_movieclip_remap_scene_to_clip_frame(clip, ctime);
BKE_tracking_camera_get_reconstructed_interpolate(tracking, object, framenr, mat);
@@ -4205,6 +4215,7 @@ static void objectsolver_id_looper(bConstraint *con, ConstraintIDFunc func, void
static void objectsolver_evaluate(bConstraint *con, bConstraintOb *cob, ListBase *UNUSED(targets))
{
+ Depsgraph *depsgraph = cob->depsgraph;
Scene *scene = cob->scene;
bObjectSolverConstraint *data = con->data;
MovieClip *clip = data->clip;
@@ -4224,7 +4235,7 @@ static void objectsolver_evaluate(bConstraint *con, bConstraintOb *cob, ListBase
if (object) {
float mat[4][4], obmat[4][4], imat[4][4], cammat[4][4], camimat[4][4], parmat[4][4];
- float ctime = BKE_scene_frame_get(scene);
+ float ctime = DEG_get_ctime(depsgraph);
float framenr = BKE_movieclip_remap_scene_to_clip_frame(clip, ctime);
BKE_object_where_is_calc_mat4(scene, camob, cammat);
@@ -4279,7 +4290,7 @@ static void transformcache_evaluate(bConstraint *con, bConstraintOb *cob, ListBa
return;
}
- const float frame = BKE_scene_frame_get(scene);
+ const float frame = DEG_get_ctime(cob->depsgraph);
const float time = BKE_cachefile_time_offset(cache_file, frame, FPS);
BKE_cachefile_ensure_handle(G.main, cache_file);
@@ -4811,6 +4822,7 @@ void BKE_constraint_target_matrix_get(struct Depsgraph *depsgraph, Scene *scene,
cob = MEM_callocN(sizeof(bConstraintOb), "tempConstraintOb");
cob->type = ownertype;
cob->scene = scene;
+ cob->depsgraph = depsgraph;
switch (ownertype) {
case CONSTRAINT_OBTYPE_OBJECT: /* it is usually this case */
{
diff --git a/source/blender/blenkernel/intern/icons.c b/source/blender/blenkernel/intern/icons.c
index bfd4e07606f..e409f8c91f0 100644
--- a/source/blender/blenkernel/intern/icons.c
+++ b/source/blender/blenkernel/intern/icons.c
@@ -806,10 +806,11 @@ struct Icon_Geom *BKE_icon_geom_from_file(const char *filename)
/** \name Studio Light Icon
* \{ */
-int BKE_icon_ensure_studio_light(struct StudioLight *sl)
+int BKE_icon_ensure_studio_light(struct StudioLight *sl, int id_type)
{
int icon_id = get_next_free_id();
- icon_create(icon_id, ICON_DATA_STUDIOLIGHT, sl);
+ Icon *icon = icon_create(icon_id, ICON_DATA_STUDIOLIGHT, sl);
+ icon->id_type = id_type;
return icon_id;
}
/** \} */
diff --git a/source/blender/blenkernel/intern/layer.c b/source/blender/blenkernel/intern/layer.c
index fd231971121..3a6d599ccd3 100644
--- a/source/blender/blenkernel/intern/layer.c
+++ b/source/blender/blenkernel/intern/layer.c
@@ -397,7 +397,7 @@ void BKE_view_layer_copy_data(
// TODO: not always safe to free BKE_layer_collection_sync(scene_dst, view_layer_dst);
}
-void BKE_view_layer_rename(Scene *scene, ViewLayer *view_layer, const char *newname)
+void BKE_view_layer_rename(Main *bmain, Scene *scene, ViewLayer *view_layer, const char *newname)
{
char oldname[sizeof(view_layer->name)];
@@ -418,8 +418,9 @@ void BKE_view_layer_rename(Scene *scene, ViewLayer *view_layer, const char *newn
}
}
- /* fix all the animation data which may link to this */
+ /* fix all the animation data and workspace which may link to this */
BKE_animdata_fix_paths_rename_all(NULL, "view_layers", oldname, view_layer->name);
+ BKE_workspace_view_layer_rename(bmain, scene, oldname, view_layer->name);
/* Dependency graph uses view layer name based lookups. */
DEG_id_tag_update(&scene->id, 0);
diff --git a/source/blender/blenkernel/intern/library_query.c b/source/blender/blenkernel/intern/library_query.c
index dbfe619153d..37b5b62b06e 100644
--- a/source/blender/blenkernel/intern/library_query.c
+++ b/source/blender/blenkernel/intern/library_query.c
@@ -932,6 +932,9 @@ void BKE_library_foreach_ID_link(Main *bmain, ID *id, LibraryIDLinkCallback call
BKE_workspace_layout_screen_set(layout, screen);
}
+ for (WorkSpaceSceneRelation *relation = workspace->scene_layer_relations.first; relation; relation = relation->next) {
+ CALLBACK_INVOKE(relation->scene, IDWALK_CB_NOP);
+ }
break;
}
case ID_GD:
@@ -1080,6 +1083,7 @@ bool BKE_library_id_can_use_idtype(ID *id_owner, const short id_type_used)
case ID_LP:
return ELEM(id_type_used, ID_IM);
case ID_WS:
+ return ELEM(id_type_used, ID_SCR, ID_SCE);
case ID_IM:
case ID_VF:
case ID_TXT:
diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c
index c43a2e3b8ec..111968ba018 100644
--- a/source/blender/blenkernel/intern/modifier.c
+++ b/source/blender/blenkernel/intern/modifier.c
@@ -66,6 +66,7 @@
#include "BKE_library_query.h"
#include "BKE_mesh.h"
#include "BKE_multires.h"
+#include "BKE_object.h"
#include "BKE_DerivedMesh.h"
/* may move these, only for modifier_path_relbase */
@@ -74,6 +75,7 @@
/* end */
#include "DEG_depsgraph.h"
+#include "DEG_depsgraph_query.h"
#include "MOD_modifiertypes.h"
@@ -1213,13 +1215,10 @@ struct DerivedMesh *modifier_applyModifierEM_DM_deprecated(struct ModifierData *
/** Get evaluated mesh for other object, which is used as an operand for the modifier,
* i.e. second operand for boolean modifier.
*/
-Mesh *BKE_modifier_get_evaluated_mesh_from_object(Object *ob, const ModifierApplyFlag flag)
+Mesh *BKE_modifier_get_evaluated_mesh_from_object(const ModifierEvalContext *ctx, Object *ob)
{
- if (flag & MOD_APPLY_RENDER) {
- /* TODO(sergey): Use proper derived render in the future. */
- return ob->mesh_evaluated;
- }
- else {
- return ob->mesh_evaluated;
- }
+ /* Note: we do not care about RENDER setting here, since we get data from despgraph
+ * (and render depsgraph shall be different from realtime one)
+ */
+ return BKE_object_get_evaluated_mesh(ctx->depsgraph, ob);
}
diff --git a/source/blender/blenkernel/intern/node.c b/source/blender/blenkernel/intern/node.c
index d86b73ab1a9..a25b21a995a 100644
--- a/source/blender/blenkernel/intern/node.c
+++ b/source/blender/blenkernel/intern/node.c
@@ -3545,6 +3545,7 @@ static void registerShaderNodes(void)
register_node_type_sh_tex_checker();
register_node_type_sh_tex_brick();
register_node_type_sh_tex_pointdensity();
+ register_node_type_sh_tex_ies();
}
static void registerTextureNodes(void)
diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c
index 9a1799ffb09..ab3300c4ff7 100644
--- a/source/blender/blenkernel/intern/object.c
+++ b/source/blender/blenkernel/intern/object.c
@@ -118,6 +118,7 @@
#include "BKE_image.h"
#include "DEG_depsgraph.h"
+#include "DEG_depsgraph_query.h"
#include "DRW_engine.h"
@@ -378,9 +379,9 @@ void BKE_object_free_caches(Object *object)
if (psmd->mesh_final) {
BKE_id_free(NULL, psmd->mesh_final);
psmd->mesh_final = NULL;
- if (psmd->mesh_deformed) {
- BKE_id_free(NULL, psmd->mesh_deformed);
- psmd->mesh_deformed = NULL;
+ if (psmd->mesh_original) {
+ BKE_id_free(NULL, psmd->mesh_original);
+ psmd->mesh_original = NULL;
}
psmd->flag |= eParticleSystemFlag_file_loaded;
update_flag |= OB_RECALC_DATA;
@@ -890,8 +891,7 @@ ParticleSystem *BKE_object_copy_particlesystem(ParticleSystem *psys, const int f
BLI_listbase_clear(&psysn->pathcachebufs);
BLI_listbase_clear(&psysn->childcachebufs);
- /* XXX Never copy caches here? */
- psysn->pointcache = BKE_ptcache_copy_list(&psysn->ptcaches, &psys->ptcaches, flag & ~LIB_ID_COPY_CACHES);
+ psysn->pointcache = BKE_ptcache_copy_list(&psysn->ptcaches, &psys->ptcaches, flag);
/* XXX - from reading existing code this seems correct but intended usage of
* pointcache should /w cloth should be added in 'ParticleSystem' - campbell */
@@ -2131,7 +2131,7 @@ void BKE_object_where_is_calc_time_ex(
/* solve constraints */
if (ob->constraints.first && !(ob->transflag & OB_NO_CONSTRAINTS)) {
bConstraintOb *cob;
- cob = BKE_constraints_make_evalob(scene, ob, NULL, CONSTRAINT_OBTYPE_OBJECT);
+ cob = BKE_constraints_make_evalob(depsgraph, scene, ob, NULL, CONSTRAINT_OBTYPE_OBJECT);
BKE_constraints_solve(depsgraph, &ob->constraints, cob, ctime);
BKE_constraints_clear_evalob(cob);
}
@@ -2457,6 +2457,7 @@ void BKE_object_empty_draw_type_set(Object *ob, const int value)
if (!ob->iuser) {
ob->iuser = MEM_callocN(sizeof(ImageUser), "image user");
ob->iuser->ok = 1;
+ ob->iuser->flag |= IMA_ANIM_ALWAYS;
ob->iuser->frames = 100;
ob->iuser->sfra = 1;
ob->iuser->fie_ima = 2;
@@ -2801,6 +2802,15 @@ int BKE_object_obdata_texspace_get(Object *ob, short **r_texflag, float **r_loc,
return 1;
}
+/** Get evaluated mesh for given (main, original) object and depsgraph. */
+Mesh *BKE_object_get_evaluated_mesh(const Depsgraph *depsgraph, Object *ob)
+{
+ Object *ob_eval = DEG_get_evaluated_object(depsgraph, ob);
+
+ return ob_eval->mesh_evaluated;
+}
+
+
static int pc_cmp(const void *a, const void *b)
{
const LinkData *ad = a, *bd = b;
diff --git a/source/blender/blenkernel/intern/object_update.c b/source/blender/blenkernel/intern/object_update.c
index 91571e8bf62..d21a1326392 100644
--- a/source/blender/blenkernel/intern/object_update.c
+++ b/source/blender/blenkernel/intern/object_update.c
@@ -128,7 +128,7 @@ void BKE_object_eval_constraints(Depsgraph *depsgraph,
* Not sure why, this is from Joshua - sergey
*
*/
- cob = BKE_constraints_make_evalob(scene, ob, NULL, CONSTRAINT_OBTYPE_OBJECT);
+ cob = BKE_constraints_make_evalob(depsgraph, scene, ob, NULL, CONSTRAINT_OBTYPE_OBJECT);
BKE_constraints_solve(depsgraph, &ob->constraints, cob, ctime);
BKE_constraints_clear_evalob(cob);
}
@@ -276,11 +276,12 @@ void BKE_object_handle_data_update(
/* quick cache removed */
}
-bool BKE_object_eval_proxy_copy(Depsgraph *UNUSED(depsgraph),
+bool BKE_object_eval_proxy_copy(Depsgraph *depsgraph,
Object *object)
{
/* Handle proxy copy for target, */
if (ID_IS_LINKED(object) && object->proxy_from) {
+ DEG_debug_print_eval(depsgraph, __func__, object->id.name, object);
if (object->proxy_from->proxy_group) {
/* Transform proxy into group space. */
Object *obg = object->proxy_from->proxy_group;
diff --git a/source/blender/blenkernel/intern/outliner_treehash.c b/source/blender/blenkernel/intern/outliner_treehash.c
index 9bbde607b80..fb62645ef43 100644
--- a/source/blender/blenkernel/intern/outliner_treehash.c
+++ b/source/blender/blenkernel/intern/outliner_treehash.c
@@ -41,6 +41,7 @@
typedef struct TseGroup {
TreeStoreElem **elems;
+ int lastused;
int size;
int allocated;
} TseGroup;
@@ -54,6 +55,7 @@ static TseGroup *tse_group_create(void)
tse_group->elems = MEM_mallocN(sizeof(TreeStoreElem *), "TseGroupElems");
tse_group->size = 0;
tse_group->allocated = 1;
+ tse_group->lastused = 0;
return tse_group;
}
@@ -143,6 +145,16 @@ static void free_treehash_group(void *key)
tse_group_free(key);
}
+void BKE_outliner_treehash_clear_used(void *treehash)
+{
+ GHashIterator gh_iter;
+
+ GHASH_ITER(gh_iter, treehash) {
+ TseGroup *group = BLI_ghashIterator_getValue(&gh_iter);
+ group->lastused = 0;
+ }
+}
+
void *BKE_outliner_treehash_rebuild_from_treestore(void *treehash, BLI_mempool *treestore)
{
BLI_assert(treehash);
@@ -161,6 +173,7 @@ void BKE_outliner_treehash_add_element(void *treehash, TreeStoreElem *elem)
*val_p = tse_group_create();
}
group = *val_p;
+ group->lastused = 0;
tse_group_add_element(group, elem);
}
@@ -198,10 +211,19 @@ TreeStoreElem *BKE_outliner_treehash_lookup_unused(void *treehash, short type, s
group = BKE_outliner_treehash_lookup_group(treehash, type, nr, id);
if (group) {
- int i;
- for (i = 0; i < group->size; i++) {
- if (!group->elems[i]->used) {
- return group->elems[i];
+ /* Find unused element, with optimization to start from previously
+ * found element assuming we do repeated lookups. */
+ int size = group->size;
+ int offset = group->lastused;
+
+ for (int i = 0; i < size; i++, offset++) {
+ if (offset >= size) {
+ offset = 0;
+ }
+
+ if (!group->elems[offset]->used) {
+ group->lastused = offset;
+ return group->elems[offset];
}
}
}
diff --git a/source/blender/blenkernel/intern/paint.c b/source/blender/blenkernel/intern/paint.c
index 4056a15fe47..f961510984a 100644
--- a/source/blender/blenkernel/intern/paint.c
+++ b/source/blender/blenkernel/intern/paint.c
@@ -338,8 +338,8 @@ void BKE_paint_palette_set(Paint *p, Palette *palette)
{
if (p) {
id_us_min((ID *)p->palette);
- id_us_plus((ID *)palette);
p->palette = palette;
+ id_us_plus((ID *)p->palette);
}
}
@@ -347,8 +347,8 @@ void BKE_paint_curve_set(Brush *br, PaintCurve *pc)
{
if (br) {
id_us_min((ID *)br->paint_curve);
- id_us_plus((ID *)pc);
br->paint_curve = pc;
+ id_us_plus((ID *)br->paint_curve);
}
}
@@ -381,9 +381,7 @@ void BKE_palette_clear(Palette *palette)
Palette *BKE_palette_add(Main *bmain, const char *name)
{
- Palette *palette;
-
- palette = BKE_libblock_alloc(bmain, ID_PAL, name, 0);
+ Palette *palette = BKE_id_new(bmain, ID_PAL, name);
/* enable fake user by default */
id_fake_user_set(&palette->id);
@@ -424,7 +422,7 @@ void BKE_palette_free(Palette *palette)
PaletteColor *BKE_palette_color_add(Palette *palette)
{
- PaletteColor *color = MEM_callocN(sizeof(*color), "Pallete Color");
+ PaletteColor *color = MEM_callocN(sizeof(*color), "Palette Color");
BLI_addtail(&palette->colors, color);
return color;
}
diff --git a/source/blender/blenkernel/intern/particle.c b/source/blender/blenkernel/intern/particle.c
index 26c822f5fef..a42826a1f89 100644
--- a/source/blender/blenkernel/intern/particle.c
+++ b/source/blender/blenkernel/intern/particle.c
@@ -1295,7 +1295,7 @@ static void psys_origspace_to_w(OrigSpaceFace *osface, int quad, const float w[4
* \return the DM tessface index.
*/
int psys_particle_dm_face_lookup(
- Mesh *mesh_final, Mesh *mesh_deformed,
+ Mesh *mesh_final, Mesh *mesh_original,
int findex_orig, const float fw[4], struct LinkNode **poly_nodes)
{
MFace *mtessface_final;
@@ -1308,7 +1308,7 @@ int psys_particle_dm_face_lookup(
const int *index_mp_to_orig = NULL;
const int totface_final = mesh_final->totface;
- const int totface_deformed = mesh_deformed ? mesh_deformed->totface : totface_final;
+ const int totface_deformed = mesh_original ? mesh_original->totface : totface_final;
if (ELEM(0, totface_final, totface_deformed)) {
return DMCACHE_NOTFOUND;
@@ -1318,8 +1318,8 @@ int psys_particle_dm_face_lookup(
index_mp_to_orig = CustomData_get_layer(&mesh_final->pdata, CD_ORIGINDEX);
BLI_assert(index_mf_to_mpoly);
- if (mesh_deformed) {
- index_mf_to_mpoly_deformed = CustomData_get_layer(&mesh_deformed->fdata, CD_ORIGINDEX);
+ if (mesh_original) {
+ index_mf_to_mpoly_deformed = CustomData_get_layer(&mesh_original->fdata, CD_ORIGINDEX);
}
else {
BLI_assert(mesh_final->runtime.deformed_only);
@@ -1329,8 +1329,8 @@ int psys_particle_dm_face_lookup(
pindex_orig = index_mf_to_mpoly_deformed[findex_orig];
- if (mesh_deformed == NULL) {
- mesh_deformed = mesh_final;
+ if (mesh_original == NULL) {
+ mesh_original = mesh_final;
}
index_mf_to_mpoly_deformed = NULL;
@@ -1349,7 +1349,7 @@ int psys_particle_dm_face_lookup(
return DMCACHE_NOTFOUND;
}
}
- else if (findex_orig >= mesh_deformed->totface) {
+ else if (findex_orig >= mesh_original->totface) {
return DMCACHE_NOTFOUND; /* index not in the original mesh */
}
diff --git a/source/blender/blenkernel/intern/particle_distribute.c b/source/blender/blenkernel/intern/particle_distribute.c
index e85a3f15022..846afd48064 100644
--- a/source/blender/blenkernel/intern/particle_distribute.c
+++ b/source/blender/blenkernel/intern/particle_distribute.c
@@ -847,7 +847,7 @@ static int psys_thread_context_init_distribute(ParticleThreadContext *ctx, Parti
/* Simple children */
if (part->childtype != PART_CHILD_FACES) {
BLI_srandom(31415926 + psys->seed + psys->child_seed);
- distribute_simple_children(scene, ob, final_mesh, sim->psmd->mesh_deformed, psys, use_render_params);
+ distribute_simple_children(scene, ob, final_mesh, sim->psmd->mesh_original, psys, use_render_params);
return 0;
}
}
@@ -1233,7 +1233,7 @@ static void distribute_particles_on_dm(ParticleSimulationData *sim, int from)
BLI_task_pool_free(task_pool);
- psys_calc_dmcache(sim->ob, final_mesh, sim->psmd->mesh_deformed, sim->psys);
+ psys_calc_dmcache(sim->ob, final_mesh, sim->psmd->mesh_original, sim->psys);
if (ctx.mesh != final_mesh)
BKE_id_free(NULL, ctx.mesh);
diff --git a/source/blender/blenkernel/intern/particle_system.c b/source/blender/blenkernel/intern/particle_system.c
index 6c454cfa0b1..cba0721ab3f 100644
--- a/source/blender/blenkernel/intern/particle_system.c
+++ b/source/blender/blenkernel/intern/particle_system.c
@@ -311,7 +311,7 @@ int psys_get_tot_child(Scene *scene, ParticleSystem *psys, const bool use_render
/* Distribution */
/************************************************/
-void psys_calc_dmcache(Object *ob, Mesh *mesh_final, Mesh *mesh_deformed, ParticleSystem *psys)
+void psys_calc_dmcache(Object *ob, Mesh *mesh_final, Mesh *mesh_original, ParticleSystem *psys)
{
/* use for building derived mesh mapping info:
*
@@ -350,7 +350,7 @@ void psys_calc_dmcache(Object *ob, Mesh *mesh_final, Mesh *mesh_deformed, Partic
origindex_poly= NULL;
}
else {
- totelem = mesh_deformed->totface;
+ totelem = mesh_original->totface;
origindex = CustomData_get_layer(&mesh_final->fdata, CD_ORIGINDEX);
/* for face lookups we need the poly origindex too */
@@ -414,7 +414,7 @@ void psys_calc_dmcache(Object *ob, Mesh *mesh_final, Mesh *mesh_deformed, Partic
pa->num_dmcache = DMCACHE_NOTFOUND;
}
else { /* FROM_FACE/FROM_VOLUME */
- pa->num_dmcache = psys_particle_dm_face_lookup(mesh_final, mesh_deformed, pa->num, pa->fuv, nodearray);
+ pa->num_dmcache = psys_particle_dm_face_lookup(mesh_final, mesh_original, pa->num, pa->fuv, nodearray);
}
}
}
@@ -3242,7 +3242,7 @@ static void hair_step(ParticleSimulationData *sim, float cfra, const bool use_re
if (psys->recalc & PSYS_RECALC_RESET) {
/* need this for changing subsurf levels */
- psys_calc_dmcache(sim->ob, sim->psmd->mesh_final, sim->psmd->mesh_deformed, psys);
+ psys_calc_dmcache(sim->ob, sim->psmd->mesh_final, sim->psmd->mesh_original, psys);
if (psys->clmd)
cloth_free_modifier(psys->clmd);
diff --git a/source/blender/blenkernel/intern/pointcache.c b/source/blender/blenkernel/intern/pointcache.c
index 7fd7b791a3f..a99057ac0ad 100644
--- a/source/blender/blenkernel/intern/pointcache.c
+++ b/source/blender/blenkernel/intern/pointcache.c
@@ -50,6 +50,7 @@
#include "BLI_blenlib.h"
#include "BLI_threads.h"
#include "BLI_math.h"
+#include "BLI_string.h"
#include "BLI_utildefines.h"
#include "BLT_translation.h"
@@ -4071,9 +4072,11 @@ void BKE_ptcache_update_info(PTCacheID *pid)
}
else {
PTCacheMem *pm = cache->mem_cache.first;
- float bytes = 0.0f;
- int i, mb;
-
+ char formatted_tot[16];
+ char formatted_mem[15];
+ long long int bytes = 0.0f;
+ int i;
+
for (; pm; pm=pm->next) {
for (i=0; i<BPHYS_TOT_DATA; i++)
bytes += MEM_allocN_len(pm->data[i]);
@@ -4088,12 +4091,10 @@ void BKE_ptcache_update_info(PTCacheID *pid)
totframes++;
}
- mb = (bytes > 1024.0f * 1024.0f);
+ BLI_str_format_int_grouped(formatted_tot, totframes);
+ BLI_str_format_byte_unit(formatted_mem, bytes, true);
- BLI_snprintf(mem_info, sizeof(mem_info), IFACE_("%i frames in memory (%.1f %s)"),
- totframes,
- bytes / (mb ? 1024.0f * 1024.0f : 1024.0f),
- mb ? IFACE_("Mb") : IFACE_("kb"));
+ BLI_snprintf(mem_info, sizeof(mem_info), IFACE_("%s frames in memory (%s)"), formatted_tot, formatted_mem);
}
if (cache->flag & PTCACHE_OUTDATED) {
diff --git a/source/blender/blenkernel/intern/rigidbody.c b/source/blender/blenkernel/intern/rigidbody.c
index 28d5cad3da8..75018bbe5bd 100644
--- a/source/blender/blenkernel/intern/rigidbody.c
+++ b/source/blender/blenkernel/intern/rigidbody.c
@@ -1660,7 +1660,7 @@ void BKE_rigidbody_do_simulation(struct Depsgraph *depsgraph, Scene *scene, floa
#else /* WITH_BULLET */
/* stubs */
-#ifdef __GNUC__
+#if defined(__GNUC__) || defined(__clang__)
# pragma GCC diagnostic push
# pragma GCC diagnostic ignored "-Wunused-parameter"
#endif
@@ -1686,7 +1686,7 @@ void BKE_rigidbody_cache_reset(RigidBodyWorld *rbw) {}
void BKE_rigidbody_rebuild_world(struct Depsgraph *depsgraph, Scene *scene, float ctime) {}
void BKE_rigidbody_do_simulation(struct Depsgraph *depsgraph, Scene *scene, float ctime) {}
-#ifdef __GNUC__
+#if defined(__GNUC__) || defined(__clang__)
# pragma GCC diagnostic pop
#endif
diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c
index d4ffc90c797..1a9a2d5b36d 100644
--- a/source/blender/blenkernel/intern/scene.c
+++ b/source/blender/blenkernel/intern/scene.c
@@ -571,6 +571,8 @@ void BKE_scene_init(Scene *sce)
*/
sce->r.color_mgt_flag |= R_COLOR_MANAGEMENT;
+ sce->r.dither_intensity = 1.0f;
+
sce->r.bake_mode = 0;
sce->r.bake_filter = 16;
sce->r.bake_flag = R_BAKE_CLEAR;
@@ -633,6 +635,7 @@ void BKE_scene_init(Scene *sce)
sce->toolsettings->doublimit = 0.001;
sce->toolsettings->vgroup_weight = 1.0f;
sce->toolsettings->uvcalc_margin = 0.001f;
+ sce->toolsettings->uvcalc_flag = UVCALC_TRANSFORM_CORRECT;
sce->toolsettings->unwrapper = 1;
sce->toolsettings->select_thresh = 0.01f;
diff --git a/source/blender/blenkernel/intern/shrinkwrap.c b/source/blender/blenkernel/intern/shrinkwrap.c
index 8e8bf395f38..3d3130486cb 100644
--- a/source/blender/blenkernel/intern/shrinkwrap.c
+++ b/source/blender/blenkernel/intern/shrinkwrap.c
@@ -414,7 +414,7 @@ static void shrinkwrap_calc_normal_projection(ShrinkwrapCalcData *calc, const Mo
}
if (calc->smd->auxTarget) {
- auxMesh = BKE_modifier_get_evaluated_mesh_from_object(calc->smd->auxTarget, ctx->flag);
+ auxMesh = BKE_modifier_get_evaluated_mesh_from_object(ctx, calc->smd->auxTarget);
if (!auxMesh)
return;
BLI_SPACE_TRANSFORM_SETUP(&local2aux, calc->ob, calc->smd->auxTarget);
@@ -625,7 +625,7 @@ void shrinkwrapModifier_deform(ShrinkwrapModifierData *smd, Object *ob, Mesh *me
if (smd->target) {
- calc.target = BKE_modifier_get_evaluated_mesh_from_object(smd->target, ctx->flag);
+ calc.target = BKE_modifier_get_evaluated_mesh_from_object(ctx, smd->target);
/* TODO there might be several "bugs" on non-uniform scales matrixs
* because it will no longer be nearest surface, not sphere projection
diff --git a/source/blender/blenkernel/intern/studiolight.c b/source/blender/blenkernel/intern/studiolight.c
index 8086156d3af..f139ea5fbe6 100644
--- a/source/blender/blenkernel/intern/studiolight.c
+++ b/source/blender/blenkernel/intern/studiolight.c
@@ -48,6 +48,8 @@
#include "IMB_imbuf.h"
#include "IMB_imbuf_types.h"
+#include "GPU_texture.h"
+
#include "MEM_guardedalloc.h"
@@ -67,6 +69,16 @@ static void studiolight_free(struct StudioLight *sl)
IMB_freeImBuf(sl->radiance_buffers[index]);
sl->radiance_buffers[index] = NULL;
}
+
+ if (sl->equirectangular_gputexture) {
+ GPU_texture_free(sl->equirectangular_gputexture);
+ sl->equirectangular_gputexture = NULL;
+ }
+
+ if (sl->equirectangular_buffer) {
+ IMB_freeImBuf(sl->equirectangular_buffer);
+ sl->equirectangular_buffer = NULL;
+ }
}
MEM_freeN(sl);
}
@@ -78,7 +90,8 @@ static struct StudioLight *studiolight_create(void)
sl->name[0] = 0x00;
sl->flag = 0;
sl->index = BLI_listbase_count(&studiolights);
- sl->icon_id = BKE_icon_ensure_studio_light(sl);
+ sl->radiance_icon_id = BKE_icon_ensure_studio_light(sl, STUDIOLIGHT_ICON_ID_TYPE_RADIANCE);
+ sl->irradiance_icon_id = BKE_icon_ensure_studio_light(sl, STUDIOLIGHT_ICON_ID_TYPE_IRRADIANCE);
for (int index = 0 ; index < 6 ; index ++) {
sl->radiance_buffers[index] = NULL;
@@ -109,7 +122,11 @@ static void studiolight_calculate_radiance(ImBuf *ibuf, float color[4], const fl
nearest_interpolation_color_wrap(ibuf, NULL, color, uv[0] * ibuf->x, uv[1] * ibuf->y);
}
-static void studiolight_calculate_radiance_buffer(ImBuf *ibuf, float *colbuf, const float start_x, const float add_x, const float start_y, const float add_y, const float z, const int index_x, const int index_y, const int index_z)
+static void studiolight_calculate_radiance_buffer(
+ ImBuf *ibuf, float *colbuf,
+ const float start_x, const float add_x,
+ const float start_y, const float add_y, const float z,
+ const int index_x, const int index_y, const int index_z)
{
float direction[3];
float yf = start_y;
@@ -129,40 +146,71 @@ static void studiolight_calculate_radiance_buffer(ImBuf *ibuf, float *colbuf, co
}
}
-static void studiolight_calculate_radiance_buffers(StudioLight *sl)
+static void studiolight_load_equierectangular_image(StudioLight *sl)
{
if (sl->flag & STUDIOLIGHT_EXTERNAL_FILE) {
- ImBuf* ibuf = NULL;
+ ImBuf *ibuf = NULL;
ibuf = IMB_loadiffname(sl->path, 0, NULL);
if (ibuf) {
IMB_float_from_rect(ibuf);
- float *colbuf = MEM_mallocN(4*STUDIOLIGHT_RADIANCE_CUBEMAP_SIZE*STUDIOLIGHT_RADIANCE_CUBEMAP_SIZE*sizeof(float), __func__);
+ sl->equirectangular_buffer = ibuf;
+ }
+ }
+ sl->flag |= STUDIOLIGHT_EQUIRECTANGULAR_IMAGE_LOADED;
+}
+
+static void studiolight_create_equierectangular_gputexture(StudioLight *sl)
+{
+ if (sl->flag & STUDIOLIGHT_EXTERNAL_FILE) {
+ char error[256];
+ BKE_studiolight_ensure_flag(sl, STUDIOLIGHT_EQUIRECTANGULAR_IMAGE_LOADED);
+ ImBuf *ibuf = sl->equirectangular_buffer;
+ sl->equirectangular_gputexture = GPU_texture_create_2D(ibuf->x, ibuf->y, GPU_RGBA16F, ibuf->rect_float, error);
+ }
+ sl->flag |= STUDIOLIGHT_EQUIRECTANGULAR_GPUTEXTURE;
+}
+
+
+
+static void studiolight_calculate_radiance_buffers(StudioLight *sl)
+{
+ if (sl->flag & STUDIOLIGHT_EXTERNAL_FILE) {
+ BKE_studiolight_ensure_flag(sl, STUDIOLIGHT_EQUIRECTANGULAR_IMAGE_LOADED);
+ ImBuf* ibuf = sl->equirectangular_buffer;
+ if (ibuf) {
+ float *colbuf = MEM_mallocN(SQUARE(STUDIOLIGHT_RADIANCE_CUBEMAP_SIZE) * sizeof(float[4]), __func__);
const float add = 1.0f / (STUDIOLIGHT_RADIANCE_CUBEMAP_SIZE + 1);
const float start = ((1.0f / STUDIOLIGHT_RADIANCE_CUBEMAP_SIZE) * 0.5f) - 0.5f;
/* front */
studiolight_calculate_radiance_buffer(ibuf, colbuf, start, add, start, add, 0.5f, 0, 2, 1);
- sl->radiance_buffers[STUDIOLIGHT_Y_POS] = IMB_allocFromBuffer(NULL, colbuf, STUDIOLIGHT_RADIANCE_CUBEMAP_SIZE, STUDIOLIGHT_RADIANCE_CUBEMAP_SIZE);
+ sl->radiance_buffers[STUDIOLIGHT_Y_POS] = IMB_allocFromBuffer(
+ NULL, colbuf, STUDIOLIGHT_RADIANCE_CUBEMAP_SIZE, STUDIOLIGHT_RADIANCE_CUBEMAP_SIZE);
/* back */
studiolight_calculate_radiance_buffer(ibuf, colbuf, -start, -add, start, add, -0.5f, 0, 2, 1);
- sl->radiance_buffers[STUDIOLIGHT_Y_NEG] = IMB_allocFromBuffer(NULL, colbuf, STUDIOLIGHT_RADIANCE_CUBEMAP_SIZE, STUDIOLIGHT_RADIANCE_CUBEMAP_SIZE);
+ sl->radiance_buffers[STUDIOLIGHT_Y_NEG] = IMB_allocFromBuffer(
+ NULL, colbuf, STUDIOLIGHT_RADIANCE_CUBEMAP_SIZE, STUDIOLIGHT_RADIANCE_CUBEMAP_SIZE);
/* left */
studiolight_calculate_radiance_buffer(ibuf, colbuf, -start, -add, start, add, 0.5f, 1, 2, 0);
- sl->radiance_buffers[STUDIOLIGHT_X_POS] = IMB_allocFromBuffer(NULL, colbuf, STUDIOLIGHT_RADIANCE_CUBEMAP_SIZE, STUDIOLIGHT_RADIANCE_CUBEMAP_SIZE);
+ sl->radiance_buffers[STUDIOLIGHT_X_POS] = IMB_allocFromBuffer(
+ NULL, colbuf, STUDIOLIGHT_RADIANCE_CUBEMAP_SIZE, STUDIOLIGHT_RADIANCE_CUBEMAP_SIZE);
/* right */
studiolight_calculate_radiance_buffer(ibuf, colbuf, start, add, start, add, -0.5f, 1, 2, 0);
- sl->radiance_buffers[STUDIOLIGHT_X_NEG] = IMB_allocFromBuffer(NULL, colbuf, STUDIOLIGHT_RADIANCE_CUBEMAP_SIZE, STUDIOLIGHT_RADIANCE_CUBEMAP_SIZE);
+ sl->radiance_buffers[STUDIOLIGHT_X_NEG] = IMB_allocFromBuffer(
+ NULL, colbuf, STUDIOLIGHT_RADIANCE_CUBEMAP_SIZE, STUDIOLIGHT_RADIANCE_CUBEMAP_SIZE);
/* top */
studiolight_calculate_radiance_buffer(ibuf, colbuf, start, add, start, add, -0.5f, 0, 1, 2);
- sl->radiance_buffers[STUDIOLIGHT_Z_NEG] = IMB_allocFromBuffer(NULL, colbuf, STUDIOLIGHT_RADIANCE_CUBEMAP_SIZE, STUDIOLIGHT_RADIANCE_CUBEMAP_SIZE);
+ sl->radiance_buffers[STUDIOLIGHT_Z_NEG] = IMB_allocFromBuffer(
+ NULL, colbuf, STUDIOLIGHT_RADIANCE_CUBEMAP_SIZE, STUDIOLIGHT_RADIANCE_CUBEMAP_SIZE);
/* bottom */
studiolight_calculate_radiance_buffer(ibuf, colbuf, start, add, -start, -add, 0.5f, 0, 1, 2);
- sl->radiance_buffers[STUDIOLIGHT_Z_POS] = IMB_allocFromBuffer(NULL, colbuf, STUDIOLIGHT_RADIANCE_CUBEMAP_SIZE, STUDIOLIGHT_RADIANCE_CUBEMAP_SIZE);
+ sl->radiance_buffers[STUDIOLIGHT_Z_POS] = IMB_allocFromBuffer(
+ NULL, colbuf, STUDIOLIGHT_RADIANCE_CUBEMAP_SIZE, STUDIOLIGHT_RADIANCE_CUBEMAP_SIZE);
#if 0
IMB_saveiff(sl->radiance_buffers[STUDIOLIGHT_X_POS], "/tmp/studiolight_radiance_left.png", IB_rectfloat);
@@ -173,7 +221,6 @@ static void studiolight_calculate_radiance_buffers(StudioLight *sl)
IMB_saveiff(sl->radiance_buffers[STUDIOLIGHT_Z_NEG], "/tmp/studiolight_radiance_top.png", IB_rectfloat);
#endif
MEM_freeN(colbuf);
- IMB_freeImBuf(ibuf);
}
}
sl->flag |= STUDIOLIGHT_RADIANCE_BUFFERS_CALCULATED;
@@ -441,6 +488,114 @@ static int studiolight_cmp(const void *a, const void *b)
return BLI_strcasecmp(sl1->name, sl2->name);
}
}
+
+/* icons */
+static unsigned int* studiolight_radiance_preview(StudioLight *sl, int icon_size)
+{
+ BKE_studiolight_ensure_flag(sl, STUDIOLIGHT_EQUIRECTANGULAR_IMAGE_LOADED);
+
+ uint *rect = MEM_mallocN(icon_size * icon_size * sizeof(uint), __func__);
+ int icon_center = icon_size / 2;
+ float sphere_radius = icon_center * 0.9;
+
+ int offset = 0;
+ for (int y = 0; y < icon_size; y++) {
+ float dy = y - icon_center;
+ for (int x = 0; x < icon_size; x++) {
+ float dx = x - icon_center;
+ /* calculate aliasing */
+ float alias = 0;
+ const float alias_step = 0.333;
+ for (float ay = dy - 0.5; ay < dy + 0.5; ay += alias_step) {
+ for (float ax = dx - 0.5; ax < dx + 0.5; ax += alias_step) {
+ if (sqrt(ay * ay + ax * ax) < sphere_radius) {
+ alias += alias_step * alias_step;
+ }
+ }
+ }
+ uint pixelresult = 0x0;
+ uint alias_i = clamp_i(alias * 256, 0, 255);
+ if (alias_i != 0) {
+ /* calculate normal */
+ uint alias_mask = alias_i << 24;
+ float incoming[3];
+ copy_v3_fl3(incoming, 0.0, 1.0, 0.0);
+
+ float normal[3];
+ normal[0] = dx / sphere_radius;
+ normal[2] = dy / sphere_radius;
+ normal[1] = -sqrt(-(normal[0] * normal[0]) - (normal[2] * normal[2]) + 1);
+ normalize_v3(normal);
+
+ float direction[3];
+ reflect_v3_v3v3(direction, incoming, normal);
+
+ float color[4];
+ studiolight_calculate_radiance(sl->equirectangular_buffer, color, direction);
+
+ pixelresult = rgb_to_cpack(
+ linearrgb_to_srgb(color[0]),
+ linearrgb_to_srgb(color[1]),
+ linearrgb_to_srgb(color[2])) | alias_mask;
+ }
+ rect[offset++] = pixelresult;
+ }
+ }
+ return rect;
+}
+
+static unsigned int* studiolight_irradiance_preview(StudioLight *sl, int icon_size)
+{
+ BKE_studiolight_ensure_flag(sl, STUDIOLIGHT_DIFFUSE_LIGHT_CALCULATED);
+
+ uint *rect = MEM_mallocN(icon_size * icon_size * sizeof(uint), __func__);
+ int icon_center = icon_size / 2;
+ float sphere_radius = icon_center * 0.9;
+
+ int offset = 0;
+ for (int y = 0; y < icon_size; y++) {
+ float dy = y - icon_center;
+ for (int x = 0; x < icon_size; x++) {
+ float dx = x - icon_center;
+ /* calculate aliasing */
+ float alias = 0;
+ const float alias_step = 0.333;
+ for (float ay = dy - 0.5; ay < dy + 0.5; ay += alias_step) {
+ for (float ax = dx - 0.5; ax < dx + 0.5; ax += alias_step) {
+ if (sqrt(ay * ay + ax * ax) < sphere_radius) {
+ alias += alias_step * alias_step;
+ }
+ }
+ }
+ uint pixelresult = 0x0;
+ uint alias_i = clamp_i(alias * 256, 0, 255);
+ if (alias_i != 0) {
+ /* calculate normal */
+ uint alias_mask = alias_i << 24;
+ float normal[3];
+ normal[0] = dx / sphere_radius;
+ normal[1] = dy / sphere_radius;
+ normal[2] = sqrt(-(normal[0] * normal[0]) - (normal[1] * normal[1]) + 1);
+ normalize_v3(normal);
+
+ float color[3];
+ mul_v3_v3fl(color, sl->diffuse_light[STUDIOLIGHT_X_POS], clamp_f(normal[0], 0.0, 1.0));
+ interp_v3_v3v3(color, color, sl->diffuse_light[STUDIOLIGHT_X_NEG], clamp_f(-normal[0], 0.0, 1.0));
+ interp_v3_v3v3(color, color, sl->diffuse_light[STUDIOLIGHT_Z_POS], clamp_f(normal[1], 0.0, 1.0));
+ interp_v3_v3v3(color, color, sl->diffuse_light[STUDIOLIGHT_Z_NEG], clamp_f(-normal[1], 0.0, 1.0));
+ interp_v3_v3v3(color, color, sl->diffuse_light[STUDIOLIGHT_Y_POS], clamp_f(normal[2], 0.0, 1.0));
+
+ pixelresult = rgb_to_cpack(
+ linearrgb_to_srgb(color[0]),
+ linearrgb_to_srgb(color[1]),
+ linearrgb_to_srgb(color[2])) | alias_mask;
+ }
+ rect[offset++] = pixelresult;
+ }
+ }
+ return rect;
+}
+
/* API */
void BKE_studiolight_init(void)
{
@@ -477,11 +632,16 @@ void BKE_studiolight_free(void)
}
}
-struct StudioLight *BKE_studiolight_find(const char *name)
+struct StudioLight *BKE_studiolight_find(const char *name, int flag)
{
LISTBASE_FOREACH(StudioLight *, sl, &studiolights) {
if (STREQLEN(sl->name, name, FILE_MAXFILE)) {
- return sl;
+ if ((sl->flag & flag) == flag) {
+ return sl;
+ } else {
+ /* flags do not match, so use default */
+ return studiolights.first;
+ }
}
}
/* When not found, use the default studio light */
@@ -504,56 +664,13 @@ const struct ListBase *BKE_studiolight_listbase(void)
return &studiolights;
}
-unsigned int *BKE_studiolight_preview(StudioLight *sl, int icon_size)
+unsigned int *BKE_studiolight_preview(StudioLight *sl, int icon_size, int icon_id_type)
{
- BKE_studiolight_ensure_flag(sl, STUDIOLIGHT_DIFFUSE_LIGHT_CALCULATED);
-
- uint *rect = MEM_mallocN(icon_size * icon_size * sizeof(uint), __func__);
- int icon_center = icon_size / 2;
- float sphere_radius = icon_center * 0.9;
-
- int offset = 0;
- for (int y = 0; y < icon_size; y++) {
- float dy = y - icon_center;
- for (int x = 0; x < icon_size; x++) {
- float dx = x - icon_center;
- /* calculate aliasing */
- float alias = 0;
- const float alias_step = 0.333;
- for (float ay = dy - 0.5; ay < dy + 0.5; ay += alias_step) {
- for (float ax = dx - 0.5; ax < dx + 0.5; ax += alias_step) {
- if (sqrt(ay * ay + ax * ax) < sphere_radius) {
- alias += alias_step * alias_step;
- }
- }
- }
- uint pixelresult = 0x0;
- uint alias_i = clamp_i(alias * 256, 0, 255);
- if (alias_i != 0) {
- /* calculate normal */
- uint alias_mask = alias_i << 24;
- float normal[3];
- normal[0] = dx / sphere_radius;
- normal[1] = dy / sphere_radius;
- normal[2] = sqrt(-(normal[0] * normal[0]) - (normal[1] * normal[1]) + 1);
- normalize_v3(normal);
-
- float color[3];
- mul_v3_v3fl(color, sl->diffuse_light[STUDIOLIGHT_X_POS], clamp_f(normal[0], 0.0, 1.0));
- interp_v3_v3v3(color, color, sl->diffuse_light[STUDIOLIGHT_X_NEG], clamp_f(-normal[0], 0.0, 1.0));
- interp_v3_v3v3(color, color, sl->diffuse_light[STUDIOLIGHT_Z_POS], clamp_f(normal[1], 0.0, 1.0));
- interp_v3_v3v3(color, color, sl->diffuse_light[STUDIOLIGHT_Z_NEG], clamp_f(-normal[1], 0.0, 1.0));
- interp_v3_v3v3(color, color, sl->diffuse_light[STUDIOLIGHT_Y_POS], clamp_f(normal[2], 0.0, 1.0));
-
- pixelresult = rgb_to_cpack(
- linearrgb_to_srgb(color[0]),
- linearrgb_to_srgb(color[1]),
- linearrgb_to_srgb(color[2])) | alias_mask;
- }
- rect[offset++] = pixelresult;
- }
+ if (icon_id_type == STUDIOLIGHT_ICON_ID_TYPE_IRRADIANCE) {
+ return studiolight_irradiance_preview(sl, icon_size);
+ } else {
+ return studiolight_radiance_preview(sl, icon_size);
}
- return rect;
}
void BKE_studiolight_ensure_flag(StudioLight *sl, int flag)
@@ -562,12 +679,18 @@ void BKE_studiolight_ensure_flag(StudioLight *sl, int flag)
return;
}
+ if ((flag & STUDIOLIGHT_EQUIRECTANGULAR_IMAGE_LOADED)) {
+ studiolight_load_equierectangular_image(sl);
+ }
if ((flag & STUDIOLIGHT_RADIANCE_BUFFERS_CALCULATED)) {
studiolight_calculate_radiance_buffers(sl);
}
if ((flag & STUDIOLIGHT_DIFFUSE_LIGHT_CALCULATED)) {
studiolight_calculate_diffuse_light(sl);
}
+ if ((flag & STUDIOLIGHT_EQUIRECTANGULAR_GPUTEXTURE)) {
+ studiolight_create_equierectangular_gputexture(sl);
+ }
if ((flag & STUDIOLIGHT_LIGHT_DIRECTION_CALCULATED)) {
studiolight_calculate_light_direction(sl);
}
diff --git a/source/blender/blenkernel/intern/workspace.c b/source/blender/blenkernel/intern/workspace.c
index 7fc0d814089..fb768333bb6 100644
--- a/source/blender/blenkernel/intern/workspace.c
+++ b/source/blender/blenkernel/intern/workspace.c
@@ -26,6 +26,7 @@
#define DNA_PRIVATE_WORKSPACE_ALLOW
#include <stdlib.h>
+#include <string.h>
#include "BLI_utildefines.h"
#include "BLI_string.h"
@@ -117,18 +118,6 @@ static void *workspace_relation_get_data_matching_parent(
}
}
-static void workspace_relation_remove_from_value(
- ListBase *relation_list, const void *value)
-{
- for (WorkSpaceDataRelation *relation = relation_list->first, *relation_next; relation; relation = relation_next) {
- relation_next = relation->next;
-
- if (relation->value == value) {
- workspace_relation_remove(relation_list, relation);
- }
- }
-}
-
/**
* Checks if \a screen is already used within any workspace. A screen should never be assigned to multiple
* WorkSpaceLayouts, but that should be ensured outside of the BKE_workspace module and without such checks.
@@ -168,7 +157,7 @@ WorkSpace *BKE_workspace_add(Main *bmain, const char *name)
void BKE_workspace_free(WorkSpace *workspace)
{
BKE_workspace_relations_free(&workspace->hook_layout_relations);
- BKE_workspace_relations_free(&workspace->scene_viewlayer_relations);
+ BLI_freelistN(&workspace->scene_layer_relations);
BLI_freelistN(&workspace->owner_ids);
BLI_freelistN(&workspace->layouts);
@@ -269,16 +258,45 @@ void BKE_workspace_relations_free(
}
}
+void BKE_workspace_scene_relations_free_invalid(
+ WorkSpace *workspace)
+{
+ for (WorkSpaceSceneRelation *relation = workspace->scene_layer_relations.first, *relation_next; relation; relation = relation_next) {
+ relation_next = relation->next;
+
+ if (relation->scene == NULL) {
+ BLI_freelinkN(&workspace->scene_layer_relations, relation);
+ }
+ else if (!BLI_findstring(&relation->scene->view_layers, relation->view_layer, offsetof(ViewLayer, name))) {
+ BLI_freelinkN(&workspace->scene_layer_relations, relation);
+ }
+ }
+}
/* -------------------------------------------------------------------- */
/* General Utils */
-void BKE_workspace_view_layer_remove_references(
+void BKE_workspace_view_layer_rename(
const Main *bmain,
- const ViewLayer *view_layer)
+ const Scene *scene,
+ const char *old_name,
+ const char *new_name)
{
for (WorkSpace *workspace = bmain->workspaces.first; workspace; workspace = workspace->id.next) {
- workspace_relation_remove_from_value(&workspace->scene_viewlayer_relations, view_layer);
+ for (WorkSpaceSceneRelation *relation = workspace->scene_layer_relations.first; relation; relation = relation->next) {
+ if (relation->scene == scene && STREQ(relation->view_layer, old_name)) {
+ STRNCPY(relation->view_layer, new_name);
+ }
+ }
+ }
+}
+
+void BKE_workspace_view_layer_remove(
+ const Main *bmain,
+ const ViewLayer *UNUSED(view_layer))
+{
+ for (WorkSpace *workspace = bmain->workspaces.first; workspace; workspace = workspace->id.next) {
+ BKE_workspace_scene_relations_free_invalid(workspace);
}
}
@@ -408,13 +426,38 @@ Base *BKE_workspace_active_base_get(const WorkSpace *workspace, const Scene *sce
return view_layer->basact;
}
+ViewLayer *BKE_workspace_view_layer_exists(const WorkSpace *workspace, const Scene *scene)
+{
+ WorkSpaceSceneRelation *relation = BLI_findptr(&workspace->scene_layer_relations, scene, offsetof(WorkSpaceSceneRelation, scene));
+ return (relation) ? BLI_findstring(&scene->view_layers, relation->view_layer, offsetof(ViewLayer, name)) : NULL;
+}
+
ViewLayer *BKE_workspace_view_layer_get(const WorkSpace *workspace, const Scene *scene)
{
- return workspace_relation_get_data_matching_parent(&workspace->scene_viewlayer_relations, scene);
+ ViewLayer *layer = BKE_workspace_view_layer_exists(workspace, scene);
+
+ if (layer == NULL) {
+ BKE_workspace_view_layer_set((WorkSpace *)workspace, scene->view_layers.first, (Scene *)scene);
+ layer = scene->view_layers.first;
+ }
+
+ return layer;
}
+
void BKE_workspace_view_layer_set(WorkSpace *workspace, ViewLayer *layer, Scene *scene)
{
- workspace_relation_ensure_updated(&workspace->scene_viewlayer_relations, scene, layer);
+ WorkSpaceSceneRelation *relation = BLI_findptr(&workspace->scene_layer_relations, scene, offsetof(WorkSpaceSceneRelation, scene));
+ if (relation == NULL) {
+ relation = MEM_callocN(sizeof(*relation), __func__);
+ }
+ else {
+ BLI_remlink(&workspace->scene_layer_relations, relation);
+ }
+
+ /* (Re)insert at the head of the list, for faster lookups. */
+ relation->scene = scene;
+ STRNCPY(relation->view_layer, layer->name);
+ BLI_addhead(&workspace->scene_layer_relations, relation);
}
ListBase *BKE_workspace_layouts_get(WorkSpace *workspace)
@@ -422,7 +465,6 @@ ListBase *BKE_workspace_layouts_get(WorkSpace *workspace)
return &workspace->layouts;
}
-
const char *BKE_workspace_layout_name_get(const WorkSpaceLayout *layout)
{
return layout->name;
diff --git a/source/blender/blenlib/BLI_string.h b/source/blender/blenlib/BLI_string.h
index 48be9d1842f..faa8dc03615 100644
--- a/source/blender/blenlib/BLI_string.h
+++ b/source/blender/blenlib/BLI_string.h
@@ -71,6 +71,7 @@ char *BLI_sprintfN(const char *__restrict format, ...) ATTR_WARN_UNUSED_RESULT A
size_t BLI_strescape(char *__restrict dst, const char *__restrict src, const size_t maxncpy) ATTR_NONNULL();
size_t BLI_str_format_int_grouped(char dst[16], int num) ATTR_NONNULL();
+void BLI_str_format_byte_unit(char dst[15], long long int size, const bool base_10) ATTR_NONNULL();
int BLI_strcaseeq(const char *a, const char *b) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
char *BLI_strcasestr(const char *s, const char *find) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
diff --git a/source/blender/blenlib/BLI_utildefines.h b/source/blender/blenlib/BLI_utildefines.h
index c0b76aa9cbf..75ddb5e739c 100644
--- a/source/blender/blenlib/BLI_utildefines.h
+++ b/source/blender/blenlib/BLI_utildefines.h
@@ -552,13 +552,13 @@ extern bool BLI_memory_is_zero(const void *arr, const size_t arr_size);
/* UNUSED macro, for function argument */
-#ifdef __GNUC__
+#if defined(__GNUC__) || defined(__clang__)
# define UNUSED(x) UNUSED_ ## x __attribute__((__unused__))
#else
# define UNUSED(x) UNUSED_ ## x
#endif
-#ifdef __GNUC__
+#if defined(__GNUC__) || defined(__clang__)
# define UNUSED_FUNCTION(x) __attribute__((__unused__)) UNUSED_ ## x
#else
# define UNUSED_FUNCTION(x) UNUSED_ ## x
diff --git a/source/blender/blenlib/intern/string.c b/source/blender/blenlib/intern/string.c
index 1a6fd082e95..49630347032 100644
--- a/source/blender/blenlib/intern/string.c
+++ b/source/blender/blenlib/intern/string.c
@@ -799,6 +799,7 @@ int BLI_str_rstrip_float_zero(char *str, const char pad)
while (end_p != p && *end_p == '0') {
*end_p = pad;
end_p--;
+ totstrip++;
}
}
}
@@ -995,6 +996,41 @@ size_t BLI_str_format_int_grouped(char dst[16], int num)
}
/**
+ * Format a size in bytes using binary units.
+ * 1000 -> 1 KB
+ * Number of decimal places grows with the used unit (e.g. 1.5 MB, 1.55 GB, 1.545 TB).
+ *
+ * \param dst The resulting string. Dimension of 14 to support largest possible value for \a bytes (LLONG_MAX).
+ * \param bytes Number to format
+ * \param base_10 Calculate using base 10 (GB, MB, ...) or 2 (GiB, MiB, ...)
+ */
+void BLI_str_format_byte_unit(char dst[15], long long int bytes, const bool base_10)
+{
+ double bytes_converted = bytes;
+ int order = 0;
+ int decimals;
+ const int base = base_10 ? 1000 : 1024;
+ const char *units_base_10[] = {"B", "KB", "MB", "GB", "TB", "PB"};
+ const char *units_base_2[] = {"B", "KiB", "MiB", "GiB", "TiB", "PiB"};
+ const int tot_units = ARRAY_SIZE(units_base_2);
+
+ BLI_STATIC_ASSERT(ARRAY_SIZE(units_base_2) == ARRAY_SIZE(units_base_10), "array size mismatch");
+
+ while ((ABS(bytes_converted) >= base) && ((order + 1) < tot_units)) {
+ bytes_converted /= base;
+ order++;
+ }
+ decimals = MAX2(order - 1, 0);
+
+ /* Format value first, stripping away floating zeroes. */
+ const size_t dst_len = 15;
+ size_t len = BLI_snprintf_rlen(dst, dst_len, "%.*f", decimals, bytes_converted);
+ len -= (size_t)BLI_str_rstrip_float_zero(dst, '\0');
+ dst[len++] = ' ';
+ BLI_strncpy(dst + len, base_10 ? units_base_10[order] : units_base_2[order], dst_len - len);
+}
+
+/**
* Find the ranges needed to split \a str into its individual words.
*
* \param str: The string to search for words.
diff --git a/source/blender/blenlib/intern/threads.c b/source/blender/blenlib/intern/threads.c
index 761f3982e28..e6f5d9839ea 100644
--- a/source/blender/blenlib/intern/threads.c
+++ b/source/blender/blenlib/intern/threads.c
@@ -488,7 +488,8 @@ void BLI_spin_lock(SpinLock *spin)
#elif defined(_MSC_VER)
while (InterlockedExchangeAcquire(spin, 1)) {
while (*spin) {
- /* pass */
+ /* Spinlock hint for processors with hyperthreading. */
+ YieldProcessor();
}
}
#else
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index 70c898a374e..bc4b8daf0d3 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -2865,6 +2865,19 @@ static void direct_link_cachefile(FileData *fd, CacheFile *cache_file)
/* ************ READ WORKSPACES *************** */
+static void lib_link_workspace_scene_data(FileData *fd, WorkSpace *workspace)
+{
+ for (WorkSpaceSceneRelation *relation = workspace->scene_layer_relations.first;
+ relation != NULL;
+ relation = relation->next)
+ {
+ relation->scene = newlibadr(fd, workspace->id.lib, relation->scene);
+ }
+
+ /* Free any relations that got lost due to missing datablocks. */
+ BKE_workspace_scene_relations_free_invalid(workspace);
+}
+
static void lib_link_workspaces(FileData *fd, Main *bmain)
{
for (WorkSpace *workspace = bmain->workspaces.first; workspace; workspace = workspace->id.next) {
@@ -2877,31 +2890,7 @@ static void lib_link_workspaces(FileData *fd, Main *bmain)
IDP_LibLinkProperty(id->properties, fd);
id_us_ensure_real(id);
- for (WorkSpaceDataRelation *relation = workspace->scene_viewlayer_relations.first,
- *relation_next = NULL;
- relation != NULL;
- relation = relation_next)
- {
- relation_next = relation->next;
-
- relation->parent = newlibadr(fd, id->lib, relation->parent);
- /* relation->value is set in direct_link_workspace_link_scene_data,
- * except when loading linked data. */
- Scene *scene = relation->parent;
-
- if (scene) {
- if (scene->id.lib != NULL) {
- relation->value = BLI_findstring(&scene->view_layers, relation->value_name, offsetof(ViewLayer, name));
- }
- if (relation->value == NULL) {
- relation->value = scene->view_layers.first;
- }
- }
- else {
- /* Remove empty relation if scene got lost. */
- BLI_freelinkN(&workspace->scene_viewlayer_relations, relation);
- }
- }
+ lib_link_workspace_scene_data(fd, workspace);
for (WorkSpaceLayout *layout = layouts->first, *layout_next; layout; layout = layout_next) {
bScreen *screen = newlibadr(fd, id->lib, BKE_workspace_layout_screen_get(layout));
@@ -2928,7 +2917,7 @@ static void direct_link_workspace(FileData *fd, WorkSpace *workspace, const Main
{
link_list(fd, BKE_workspace_layouts_get(workspace));
link_list(fd, &workspace->hook_layout_relations);
- link_list(fd, &workspace->scene_viewlayer_relations);
+ link_list(fd, &workspace->scene_layer_relations);
link_list(fd, &workspace->owner_ids);
link_list(fd, &workspace->tools);
@@ -2940,12 +2929,6 @@ static void direct_link_workspace(FileData *fd, WorkSpace *workspace, const Main
relation->value = newdataadr(fd, relation->value);
}
- if (ID_IS_LINKED(&workspace->id)) {
- /* Appending workspace so render layer is likely from a different scene. Unset
- * now, when activating workspace later we set a valid one from current scene. */
- BKE_workspace_relations_free(&workspace->scene_viewlayer_relations);
- }
-
/* Same issue/fix as in direct_link_workspace_link_scene_data: Can't read workspace data
* when reading windows, so have to update windows after/when reading workspaces. */
for (wmWindowManager *wm = main->wm.first; wm; wm = wm->id.next) {
@@ -5247,7 +5230,7 @@ static void direct_link_modifiers(FileData *fd, ListBase *lb)
ParticleSystemModifierData *psmd = (ParticleSystemModifierData *)md;
psmd->mesh_final = NULL;
- psmd->mesh_deformed = NULL;
+ psmd->mesh_original = NULL;
psmd->psys= newdataadr(fd, psmd->psys);
psmd->flag &= ~eParticleSystemFlag_psys_updated;
psmd->flag |= eParticleSystemFlag_file_loaded;
@@ -5717,7 +5700,6 @@ static void lib_link_collection_data(FileData *fd, Library *lib, Collection *col
cob->ob = newlibadr_us(fd, lib, cob->ob);
if (cob->ob == NULL) {
- BLI_assert(!"Collection linked object got lost"); // TODO: remove, only for testing now
BLI_freelinkN(&collection->gobject, cob);
}
}
@@ -5729,7 +5711,6 @@ static void lib_link_collection_data(FileData *fd, Library *lib, Collection *col
if (child->collection == NULL ||
BKE_collection_find_cycle(collection, child->collection))
{
- BLI_assert(!"Collection child got lost"); // TODO: remove, only for testing now
BLI_freelinkN(&collection->children, child);
}
else {
@@ -6073,31 +6054,7 @@ static void direct_link_sequence_modifiers(FileData *fd, ListBase *lb)
}
}
-/**
- * Workspaces store a render layer pointer which can only be read after scene is read.
- */
-static void direct_link_workspace_link_scene_data(
- FileData *fd, Scene *scene, const ListBase *workspaces)
-{
- for (WorkSpace *workspace = workspaces->first; workspace; workspace = workspace->id.next) {
- for (WorkSpaceDataRelation *relation = workspace->scene_viewlayer_relations.first;
- relation != NULL;
- relation = relation->next)
- {
- ViewLayer *view_layer = newdataadr(fd, relation->value);
- if (view_layer != NULL) {
- BLI_assert(BLI_findindex(&scene->view_layers, view_layer) != -1);
- /* relation->parent is set in lib_link_workspaces */
- }
- if (UNLIKELY(view_layer == NULL)) {
- view_layer = scene->view_layers.first;
- }
- relation->value = view_layer;
- }
- }
-}
-
-static void direct_link_scene(FileData *fd, Scene *sce, Main *bmain)
+static void direct_link_scene(FileData *fd, Scene *sce)
{
Editing *ed;
Sequence *seq;
@@ -6363,8 +6320,6 @@ static void direct_link_scene(FileData *fd, Scene *sce, Main *bmain)
sce->layer_properties = newdataadr(fd, sce->layer_properties);
IDP_DirectLinkGroup_OrFree(&sce->layer_properties, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd);
-
- direct_link_workspace_link_scene_data(fd, sce, &bmain->workspaces);
}
/* ****************** READ GREASE PENCIL ***************** */
@@ -7176,7 +7131,20 @@ static void lib_link_clipboard_restore(struct IDNameLib_Map *id_map)
BKE_sequencer_base_recursive_apply(&seqbase_clipboard, lib_link_seq_clipboard_cb, id_map);
}
-static void lib_link_workspace_scene_data_restore(wmWindow *win, Scene *scene)
+static void lib_link_workspace_scene_data_restore(struct IDNameLib_Map *id_map, WorkSpace *workspace)
+{
+ for (WorkSpaceSceneRelation *relation = workspace->scene_layer_relations.first;
+ relation != NULL;
+ relation = relation->next)
+ {
+ relation->scene = restore_pointer_by_name(id_map, &relation->scene->id, USER_IGNORE);
+ }
+
+ /* Free any relations that got lost due to missing datablocks or view layers. */
+ BKE_workspace_scene_relations_free_invalid(workspace);
+}
+
+static void lib_link_window_scene_data_restore(wmWindow *win, Scene *scene)
{
bScreen *screen = BKE_workspace_active_screen_get(win->workspace_hook);
@@ -7437,12 +7405,14 @@ void blo_lib_link_restore(Main *newmain, wmWindowManager *curwm, Scene *curscene
struct IDNameLib_Map *id_map = BKE_main_idmap_create(newmain);
for (WorkSpace *workspace = newmain->workspaces.first; workspace; workspace = workspace->id.next) {
+ lib_link_workspace_scene_data_restore(id_map, workspace);
+ BKE_workspace_view_layer_set(workspace, cur_view_layer, curscene);
+
ListBase *layouts = BKE_workspace_layouts_get(workspace);
for (WorkSpaceLayout *layout = layouts->first; layout; layout = layout->next) {
lib_link_workspace_layout_restore(id_map, newmain, layout);
}
- BKE_workspace_view_layer_set(workspace, cur_view_layer, curscene);
}
for (wmWindow *win = curwm->windows.first; win; win = win->next) {
@@ -7461,7 +7431,7 @@ void blo_lib_link_restore(Main *newmain, wmWindowManager *curwm, Scene *curscene
/* keep cursor location through undo */
copy_v3_v3(win->scene->cursor.location, oldscene->cursor.location);
copy_qt_qt(win->scene->cursor.rotation, oldscene->cursor.rotation);
- lib_link_workspace_scene_data_restore(win, win->scene);
+ lib_link_window_scene_data_restore(win, win->scene);
BLI_assert(win->screen == NULL);
}
@@ -8373,7 +8343,7 @@ static BHead *read_libblock(FileData *fd, Main *main, BHead *bhead, const short
wrong_id = direct_link_screen(fd, (bScreen *)id);
break;
case ID_SCE:
- direct_link_scene(fd, (Scene *)id, main);
+ direct_link_scene(fd, (Scene *)id);
break;
case ID_OB:
direct_link_object(fd, (Object *)id);
@@ -9096,6 +9066,14 @@ static void expand_constraint_channels(FileData *fd, Main *mainvar, ListBase *ch
}
}
+static void expand_id(FileData *fd, Main *mainvar, ID *id)
+{
+ if (id->override_static) {
+ expand_doit(fd, mainvar, id->override_static->reference);
+ expand_doit(fd, mainvar, id->override_static->storage);
+ }
+}
+
static void expand_idprops(FileData *fd, Main *mainvar, IDProperty *prop)
{
if (!prop)
@@ -9870,6 +9848,7 @@ void BLO_expand_main(void *fdhandle, Main *mainvar)
id = lbarray[a]->first;
while (id) {
if (id->tag & LIB_TAG_NEED_EXPAND) {
+ expand_id(fd, mainvar, id);
expand_idprops(fd, mainvar, id->properties);
switch (GS(id->name)) {
diff --git a/source/blender/blenloader/intern/versioning_280.c b/source/blender/blenloader/intern/versioning_280.c
index 7bb20c38308..a25c744afc4 100644
--- a/source/blender/blenloader/intern/versioning_280.c
+++ b/source/blender/blenloader/intern/versioning_280.c
@@ -262,6 +262,7 @@ static void do_version_layer_collection_post(
static void do_version_scene_collection_convert(
Main *bmain,
+ ID *id,
SceneCollection *sc,
Collection *collection,
GHash *collection_map)
@@ -273,7 +274,8 @@ static void do_version_scene_collection_convert(
for (SceneCollection *nsc = sc->scene_collections.first; nsc;) {
SceneCollection *nsc_next = nsc->next;
Collection *ncollection = BKE_collection_add(bmain, collection, nsc->name);
- do_version_scene_collection_convert(bmain, nsc, ncollection, collection_map);
+ ncollection->id.lib = id->lib;
+ do_version_scene_collection_convert(bmain, id, nsc, ncollection, collection_map);
nsc = nsc_next;
}
@@ -293,7 +295,7 @@ static void do_version_group_collection_to_collection(Main *bmain, Collection *g
{
/* Convert old 2.8 group collections to new unified collections. */
if (group->collection) {
- do_version_scene_collection_convert(bmain, group->collection, group, NULL);
+ do_version_scene_collection_convert(bmain, &group->id, group->collection, group, NULL);
}
group->collection = NULL;
@@ -317,7 +319,7 @@ static void do_version_scene_collection_to_collection(Main *bmain, Scene *scene)
/* Convert scene collections. */
GHash *collection_map = BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp, __func__);
if (scene->collection) {
- do_version_scene_collection_convert(bmain, scene->collection, scene->master_collection, collection_map);
+ do_version_scene_collection_convert(bmain, &scene->id, scene->collection, scene->master_collection, collection_map);
scene->collection = NULL;
}
@@ -434,6 +436,7 @@ static void do_version_layers_to_collections(Main *bmain, Scene *scene)
collections[DO_VERSION_COLLECTION_VISIBLE].suffix);
Collection *collection = BKE_collection_add(bmain, collection_master, name);
+ collection->id.lib = scene->id.lib;
collection->flag |= collections[DO_VERSION_COLLECTION_VISIBLE].flag;
collections[DO_VERSION_COLLECTION_VISIBLE].collections[layer] = collection;
collections[DO_VERSION_COLLECTION_VISIBLE].created |= (1 << layer);
@@ -453,6 +456,7 @@ static void do_version_layers_to_collections(Main *bmain, Scene *scene)
collections[collection_index].suffix);
Collection *collection = BKE_collection_add(bmain, collection_parent, name);
+ collection->id.lib = scene->id.lib;
collection->flag |= collections[collection_index].flag;
collections[collection_index].collections[layer] = collection;
collections[collection_index].created |= (1 << layer);
@@ -676,12 +680,14 @@ void do_versions_after_linking_280(Main *main)
/* Convert group layer visibility flags to hidden nested collection. */
for (Collection *collection = main->collection.first; collection; collection = collection->id.next) {
- Collection *collection_hidden = NULL;
+ /* Add fake user for all existing groups. */
+ id_fake_user_set(&collection->id);
if (collection->flag & (COLLECTION_RESTRICT_VIEW | COLLECTION_RESTRICT_RENDER)) {
continue;
}
+ Collection *collection_hidden = NULL;
for (CollectionObject *cob = collection->gobject.first, *cob_next = NULL; cob; cob = cob_next) {
cob_next = cob->next;
Object *ob = cob->ob;
@@ -689,6 +695,7 @@ void do_versions_after_linking_280(Main *main)
if (!(ob->lay & collection->layer)) {
if (collection_hidden == NULL) {
collection_hidden = BKE_collection_add(main, collection, "Hidden");
+ collection_hidden->id.lib = collection->id.lib;
collection_hidden->flag |= COLLECTION_RESTRICT_VIEW | COLLECTION_RESTRICT_RENDER;
}
@@ -696,9 +703,6 @@ void do_versions_after_linking_280(Main *main)
BKE_collection_object_remove(main, collection, ob, true);
}
}
-
- /* Add fake user for all existing groups. */
- id_fake_user_set(&collection->id);
}
/* Convert layers to collections. */
diff --git a/source/blender/blenloader/intern/versioning_defaults.c b/source/blender/blenloader/intern/versioning_defaults.c
index f7a69931f9f..764eaecd1e9 100644
--- a/source/blender/blenloader/intern/versioning_defaults.c
+++ b/source/blender/blenloader/intern/versioning_defaults.c
@@ -141,6 +141,8 @@ void BLO_update_defaults_startup_blend(Main *bmain)
if (scene->toolsettings) {
ToolSettings *ts = scene->toolsettings;
+ ts->uvcalc_flag |= UVCALC_TRANSFORM_CORRECT;
+
if (ts->sculpt) {
Sculpt *sculpt = ts->sculpt;
sculpt->paint.symmetry_flags |= PAINT_SYMM_X;
@@ -354,6 +356,7 @@ void BLO_update_defaults_startup_blend(Main *bmain)
for (Scene *scene = bmain->scene.first; scene; scene = scene->id.next) {
scene->r.displaymode = R_OUTPUT_WINDOW;
scene->r.size = 100;
+ scene->r.dither_intensity = 1.0f;
scene->unit.system = USER_UNIT_METRIC;
STRNCPY(scene->view_settings.view_transform, "Filmic");
}
diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c
index f3042dc84db..de1699e24b7 100644
--- a/source/blender/blenloader/intern/writefile.c
+++ b/source/blender/blenloader/intern/writefile.c
@@ -3599,18 +3599,10 @@ static void write_workspace(WriteData *wd, WorkSpace *workspace)
{
ListBase *layouts = BKE_workspace_layouts_get(workspace);
- /* Update the names for file (only need to set on write). */
- for (WorkSpaceDataRelation *relation = workspace->scene_viewlayer_relations.first;
- relation;
- relation = relation->next)
- {
- STRNCPY(relation->value_name, ((ViewLayer *)relation->value)->name);
- }
-
writestruct(wd, ID_WS, WorkSpace, 1, workspace);
writelist(wd, DATA, WorkSpaceLayout, layouts);
writelist(wd, DATA, WorkSpaceDataRelation, &workspace->hook_layout_relations);
- writelist(wd, DATA, WorkSpaceDataRelation, &workspace->scene_viewlayer_relations);
+ writelist(wd, DATA, WorkSpaceSceneRelation, &workspace->scene_layer_relations);
writelist(wd, DATA, wmOwnerID, &workspace->owner_ids);
writelist(wd, DATA, bToolRef, &workspace->tools);
for (bToolRef *tref = workspace->tools.first; tref; tref = tref->next) {
diff --git a/source/blender/bmesh/CMakeLists.txt b/source/blender/bmesh/CMakeLists.txt
index 5245d24a075..320bebc9958 100644
--- a/source/blender/bmesh/CMakeLists.txt
+++ b/source/blender/bmesh/CMakeLists.txt
@@ -169,7 +169,7 @@ set(SRC
bmesh_tools.h
)
-if(MSVC)
+if(MSVC AND NOT MSVC_CLANG)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /WX /wd4101")
endif()
diff --git a/source/blender/compositor/nodes/COM_MathNode.cpp b/source/blender/compositor/nodes/COM_MathNode.cpp
index eb6bb2caf56..0fb6933afe7 100644
--- a/source/blender/compositor/nodes/COM_MathNode.cpp
+++ b/source/blender/compositor/nodes/COM_MathNode.cpp
@@ -86,6 +86,9 @@ void MathNode::convertToOperations(NodeConverter &converter, const CompositorCon
case NODE_MATH_ABS:
operation = new MathAbsoluteOperation();
break;
+ case NODE_MATH_ATAN2:
+ operation = new MathArcTan2Operation();
+ break;
}
if (operation) {
diff --git a/source/blender/compositor/operations/COM_MathBaseOperation.cpp b/source/blender/compositor/operations/COM_MathBaseOperation.cpp
index 32a1e77b9a7..dbc91980acd 100644
--- a/source/blender/compositor/operations/COM_MathBaseOperation.cpp
+++ b/source/blender/compositor/operations/COM_MathBaseOperation.cpp
@@ -343,3 +343,16 @@ void MathAbsoluteOperation::executePixelSampled(float output[4], float x, float
clampIfNeeded(output);
}
+
+void MathArcTan2Operation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler)
+{
+ float inputValue1[4];
+ float inputValue2[4];
+
+ this->m_inputValue1Operation->readSampled(inputValue1, x, y, sampler);
+ this->m_inputValue2Operation->readSampled(inputValue2, x, y, sampler);
+
+ output[0] = atan2(inputValue1[0], inputValue2[0]);
+
+ clampIfNeeded(output);
+} \ No newline at end of file
diff --git a/source/blender/compositor/operations/COM_MathBaseOperation.h b/source/blender/compositor/operations/COM_MathBaseOperation.h
index 32cd19f1fb9..04019372711 100644
--- a/source/blender/compositor/operations/COM_MathBaseOperation.h
+++ b/source/blender/compositor/operations/COM_MathBaseOperation.h
@@ -169,4 +169,10 @@ public:
void executePixelSampled(float output[4], float x, float y, PixelSampler sampler);
};
+class MathArcTan2Operation : public MathBaseOperation {
+public:
+ MathArcTan2Operation() : MathBaseOperation() {}
+ void executePixelSampled(float output[4], float x, float y, PixelSampler sampler);
+};
+
#endif
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc
index 9a1bd87f93d..64bdbe49dac 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc
@@ -549,7 +549,11 @@ void DepsgraphRelationBuilder::build_object(Base *base, Object *object)
*/
ComponentKey ob_pose_key(&object->id, DEG_NODE_TYPE_EVAL_POSE);
ComponentKey proxy_pose_key(&object->proxy->id, DEG_NODE_TYPE_EVAL_POSE);
- add_relation(ob_pose_key, proxy_pose_key, "Proxy");
+ add_relation(ob_pose_key, proxy_pose_key, "Proxy Pose");
+
+ ComponentKey ob_transform_key(&object->id, DEG_NODE_TYPE_TRANSFORM);
+ ComponentKey proxy_transform_key(&object->proxy->id, DEG_NODE_TYPE_TRANSFORM);
+ add_relation(ob_transform_key, proxy_transform_key, "Proxy Transform");
}
/* Object dupligroup. */
if (object->dup_group != NULL) {
diff --git a/source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.cc b/source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.cc
index c8b9702621e..0e8d4669108 100644
--- a/source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.cc
+++ b/source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.cc
@@ -49,6 +49,7 @@
#include "BLI_threads.h"
#include "BLI_string.h"
+#include "BKE_curve.h"
#include "BKE_global.h"
#include "BKE_idprop.h"
#include "BKE_layer.h"
@@ -76,6 +77,7 @@ extern "C" {
# include "DNA_lattice_types.h"
# include "DNA_linestyle_types.h"
# include "DNA_material_types.h"
+# include "DNA_meta_types.h"
# include "DNA_node_types.h"
# include "DNA_texture_types.h"
# include "DNA_world_types.h"
@@ -276,10 +278,11 @@ bool id_copy_inplace_no_main(const ID *id, ID *newid)
bool result = BKE_id_copy_ex(NULL,
(ID *)id_for_copy,
&newid,
- LIB_ID_CREATE_NO_MAIN |
- LIB_ID_CREATE_NO_USER_REFCOUNT |
- LIB_ID_CREATE_NO_ALLOCATE |
- LIB_ID_CREATE_NO_DEG_TAG,
+ (LIB_ID_CREATE_NO_MAIN |
+ LIB_ID_CREATE_NO_USER_REFCOUNT |
+ LIB_ID_CREATE_NO_ALLOCATE |
+ LIB_ID_CREATE_NO_DEG_TAG |
+ LIB_ID_COPY_CACHES),
false);
#ifdef NESTED_ID_NASTY_WORKAROUND
@@ -410,7 +413,7 @@ int foreach_libblock_remap_callback(void *user_data_v,
return IDWALK_RET_NOP;
}
-void updata_armature_edit_mode_pointers(const Depsgraph * /*depsgraph*/,
+void update_armature_edit_mode_pointers(const Depsgraph * /*depsgraph*/,
const ID *id_orig, ID *id_cow)
{
const bArmature *armature_orig = (const bArmature *)id_orig;
@@ -418,7 +421,32 @@ void updata_armature_edit_mode_pointers(const Depsgraph * /*depsgraph*/,
armature_cow->edbo = armature_orig->edbo;
}
-void updata_mesh_edit_mode_pointers(const Depsgraph *depsgraph,
+void update_curve_edit_mode_pointers(const Depsgraph * /*depsgraph*/,
+ const ID *id_orig, ID *id_cow)
+{
+ const Curve *curve_orig = (const Curve *)id_orig;
+ Curve *curve_cow = (Curve *)id_cow;
+ curve_cow->editnurb = curve_orig->editnurb;
+ curve_cow->editfont = curve_orig->editfont;
+}
+
+void update_mball_edit_mode_pointers(const Depsgraph * /*depsgraph*/,
+ const ID *id_orig, ID *id_cow)
+{
+ const MetaBall *mball_orig = (const MetaBall *)id_orig;
+ MetaBall *mball_cow = (MetaBall *)id_cow;
+ mball_cow->editelems = mball_orig->editelems;
+}
+
+void update_lattice_edit_mode_pointers(const Depsgraph * /*depsgraph*/,
+ const ID *id_orig, ID *id_cow)
+{
+ const Lattice *lt_orig = (const Lattice *)id_orig;
+ Lattice *lt_cow = (Lattice *)id_cow;
+ lt_cow->editlatt = lt_orig->editlatt;
+}
+
+void update_mesh_edit_mode_pointers(const Depsgraph *depsgraph,
const ID *id_orig, ID *id_cow)
{
/* For meshes we need to update edit_btmesh to make it to point
@@ -443,16 +471,25 @@ void updata_mesh_edit_mode_pointers(const Depsgraph *depsgraph,
/* Edit data is stored and owned by original datablocks, copied ones
* are simply referencing to them.
*/
-void updata_edit_mode_pointers(const Depsgraph *depsgraph,
+void update_edit_mode_pointers(const Depsgraph *depsgraph,
const ID *id_orig, ID *id_cow)
{
const ID_Type type = GS(id_orig->name);
switch (type) {
case ID_AR:
- updata_armature_edit_mode_pointers(depsgraph, id_orig, id_cow);
+ update_armature_edit_mode_pointers(depsgraph, id_orig, id_cow);
break;
case ID_ME:
- updata_mesh_edit_mode_pointers(depsgraph, id_orig, id_cow);
+ update_mesh_edit_mode_pointers(depsgraph, id_orig, id_cow);
+ break;
+ case ID_CU:
+ update_curve_edit_mode_pointers(depsgraph, id_orig, id_cow);
+ break;
+ case ID_MB:
+ update_mball_edit_mode_pointers(depsgraph, id_orig, id_cow);
+ break;
+ case ID_LT:
+ update_lattice_edit_mode_pointers(depsgraph, id_orig, id_cow);
break;
default:
break;
@@ -504,7 +541,7 @@ void update_special_pointers(const Depsgraph *depsgraph,
default:
break;
}
- updata_edit_mode_pointers(depsgraph, id_orig, id_cow);
+ update_edit_mode_pointers(depsgraph, id_orig, id_cow);
}
/* This callback is used to validate that all nested ID datablocks are
@@ -680,6 +717,7 @@ ID *deg_update_copy_on_write_datablock(const Depsgraph *depsgraph,
ListBase gpumaterial_backup;
ListBase *gpumaterial_ptr = NULL;
Mesh *mesh_evaluated = NULL;
+ CurveCache *curve_cache = NULL;
short base_flag = 0;
if (check_datablock_expanded(id_cow)) {
switch (id_type) {
@@ -729,6 +767,10 @@ ID *deg_update_copy_on_write_datablock(const Depsgraph *depsgraph,
object->data = mesh_evaluated->id.orig_id;
}
}
+ /* Store curve cache and make sure we don't free it. */
+ curve_cache = object->curve_cache;
+ object->curve_cache = NULL;
+
/* Make a backup of base flags. */
base_flag = object->base_flag;
break;
@@ -764,6 +806,9 @@ ID *deg_update_copy_on_write_datablock(const Depsgraph *depsgraph,
((Mesh *)mesh_evaluated->id.orig_id)->edit_btmesh;
}
}
+ if (curve_cache != NULL) {
+ object->curve_cache = curve_cache;
+ }
object->base_flag = base_flag;
}
return id_cow;
@@ -786,6 +831,25 @@ void discard_armature_edit_mode_pointers(ID *id_cow)
armature_cow->edbo = NULL;
}
+void discard_curve_edit_mode_pointers(ID *id_cow)
+{
+ Curve *curve_cow = (Curve *)id_cow;
+ curve_cow->editnurb = NULL;
+ curve_cow->editfont = NULL;
+}
+
+void discard_mball_edit_mode_pointers(ID *id_cow)
+{
+ MetaBall *mball_cow = (MetaBall *)id_cow;
+ mball_cow->editelems = NULL;
+}
+
+void discard_lattice_edit_mode_pointers(ID *id_cow)
+{
+ Lattice *lt_cow = (Lattice *)id_cow;
+ lt_cow->editlatt = NULL;
+}
+
void discard_mesh_edit_mode_pointers(ID *id_cow)
{
Mesh *mesh_cow = (Mesh *)id_cow;
@@ -810,6 +874,15 @@ void discard_edit_mode_pointers(ID *id_cow)
case ID_ME:
discard_mesh_edit_mode_pointers(id_cow);
break;
+ case ID_CU:
+ discard_curve_edit_mode_pointers(id_cow);
+ break;
+ case ID_MB:
+ discard_mball_edit_mode_pointers(id_cow);
+ break;
+ case ID_LT:
+ discard_lattice_edit_mode_pointers(id_cow);
+ break;
default:
break;
}
diff --git a/source/blender/draw/CMakeLists.txt b/source/blender/draw/CMakeLists.txt
index 96dcac5b2d2..965faa7ba53 100644
--- a/source/blender/draw/CMakeLists.txt
+++ b/source/blender/draw/CMakeLists.txt
@@ -62,6 +62,7 @@ set(SRC
intern/draw_cache_impl_metaball.c
intern/draw_cache_impl_particles.c
intern/draw_common.c
+ intern/draw_debug.c
intern/draw_instance_data.c
intern/draw_manager.c
intern/draw_manager_data.c
@@ -96,6 +97,7 @@ set(SRC
engines/eevee/eevee_engine.c
engines/eevee/eevee_lightprobes.c
engines/eevee/eevee_lights.c
+ engines/eevee/eevee_lookdev.c
engines/eevee/eevee_materials.c
engines/eevee/eevee_mist.c
engines/eevee/eevee_motion_blur.c
@@ -120,6 +122,7 @@ set(SRC
intern/draw_cache.h
intern/draw_cache_impl.h
intern/draw_common.h
+ intern/draw_debug.h
intern/draw_instance_data.h
intern/draw_manager.h
intern/draw_manager_text.h
@@ -220,6 +223,7 @@ data_to_c_simple(engines/workbench/shaders/workbench_deferred_composite_frag.gls
data_to_c_simple(engines/workbench/shaders/workbench_forward_composite_frag.glsl SRC)
data_to_c_simple(engines/workbench/shaders/workbench_forward_depth_frag.glsl SRC)
data_to_c_simple(engines/workbench/shaders/workbench_forward_transparent_accum_frag.glsl SRC)
+data_to_c_simple(engines/workbench/shaders/workbench_forward_transparent_revealage_frag.glsl SRC)
data_to_c_simple(engines/workbench/shaders/workbench_object_outline_lib.glsl SRC)
data_to_c_simple(engines/workbench/shaders/workbench_prepass_vert.glsl SRC)
data_to_c_simple(engines/workbench/shaders/workbench_prepass_frag.glsl SRC)
diff --git a/source/blender/draw/engines/basic/basic_engine.c b/source/blender/draw/engines/basic/basic_engine.c
index 204990de5b0..c86574f7557 100644
--- a/source/blender/draw/engines/basic/basic_engine.c
+++ b/source/blender/draw/engines/basic/basic_engine.c
@@ -119,7 +119,8 @@ static void basic_cache_init(void *vedata)
#ifdef USE_DEPTH
/* Depth Pass */
{
- psl->depth_pass = DRW_pass_create("Depth Pass", DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL | DRW_STATE_WIRE);
+ psl->depth_pass = DRW_pass_create(
+ "Depth Pass", DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL | DRW_STATE_WIRE);
stl->g_data->depth_shgrp = DRW_shgroup_create(e_data.depth_sh, psl->depth_pass);
psl->depth_pass_cull = DRW_pass_create(
diff --git a/source/blender/draw/engines/clay/clay_engine.c b/source/blender/draw/engines/clay/clay_engine.c
index bcbc37ac7af..d08fee6039f 100644
--- a/source/blender/draw/engines/clay/clay_engine.c
+++ b/source/blender/draw/engines/clay/clay_engine.c
@@ -224,7 +224,8 @@ static void clay_view_layer_data_free(void *storage)
static CLAY_ViewLayerData *CLAY_view_layer_data_get(void)
{
- CLAY_ViewLayerData **sldata = (CLAY_ViewLayerData **)DRW_view_layer_engine_data_ensure(&draw_engine_clay_type, &clay_view_layer_data_free);
+ CLAY_ViewLayerData **sldata = (CLAY_ViewLayerData **)DRW_view_layer_engine_data_ensure(
+ &draw_engine_clay_type, &clay_view_layer_data_free);
if (*sldata == NULL) {
*sldata = MEM_callocN(sizeof(**sldata), "CLAY_ViewLayerData");
@@ -751,7 +752,8 @@ static DRWShadingGroup *CLAY_object_shgrp_get(CLAY_Data *vedata, Object *ob, boo
return shgrps[id];
}
-static DRWShadingGroup *CLAY_hair_shgrp_get(CLAY_Data *UNUSED(vedata), Object *ob, CLAY_StorageList *stl, CLAY_PassList *psl)
+static DRWShadingGroup *CLAY_hair_shgrp_get(
+ CLAY_Data *UNUSED(vedata), Object *ob, CLAY_StorageList *stl, CLAY_PassList *psl)
{
DRWShadingGroup **hair_shgrps = stl->storage->hair_shgrps;
@@ -803,8 +805,8 @@ static void clay_cache_init(void *vedata)
/* Hair Pass */
{
psl->hair_pass = DRW_pass_create(
- "Hair Pass",
- DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL | DRW_STATE_WIRE);
+ "Hair Pass",
+ DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL | DRW_STATE_WIRE);
}
{
diff --git a/source/blender/draw/engines/eevee/eevee_bloom.c b/source/blender/draw/engines/eevee/eevee_bloom.c
index f644b59c0b7..8be9c637fbc 100644
--- a/source/blender/draw/engines/eevee/eevee_bloom.c
+++ b/source/blender/draw/engines/eevee/eevee_bloom.c
@@ -92,7 +92,7 @@ int EEVEE_bloom_init(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *vedata)
const DRWContextState *draw_ctx = DRW_context_state_get();
const Scene *scene_eval = DEG_get_evaluated_scene(draw_ctx->depsgraph);
- if (scene_eval->flag & SCE_EEVEE_BLOOM_ENABLED) {
+ if (scene_eval->eevee.flag & SCE_EEVEE_BLOOM_ENABLED) {
const float *viewport_size = DRW_viewport_size_get();
/* Shaders */
diff --git a/source/blender/draw/engines/eevee/eevee_depth_of_field.c b/source/blender/draw/engines/eevee/eevee_depth_of_field.c
index c275a5005ff..60c6175f4fa 100644
--- a/source/blender/draw/engines/eevee/eevee_depth_of_field.c
+++ b/source/blender/draw/engines/eevee/eevee_depth_of_field.c
@@ -84,7 +84,7 @@ int EEVEE_depth_of_field_init(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *v
const DRWContextState *draw_ctx = DRW_context_state_get();
const Scene *scene_eval = DEG_get_evaluated_scene(draw_ctx->depsgraph);
- if (scene_eval->flag & SCE_EEVEE_DOF_ENABLED) {
+ if (scene_eval->eevee.flag & SCE_EEVEE_DOF_ENABLED) {
RegionView3D *rv3d = draw_ctx->rv3d;
if (!e_data.dof_downsample_sh) {
diff --git a/source/blender/draw/engines/eevee/eevee_effects.c b/source/blender/draw/engines/eevee/eevee_effects.c
index 646c7a03afd..211a8abd42c 100644
--- a/source/blender/draw/engines/eevee/eevee_effects.c
+++ b/source/blender/draw/engines/eevee/eevee_effects.c
@@ -305,7 +305,8 @@ void EEVEE_effects_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
struct Gwn_Batch *quad = DRW_cache_fullscreen_quad_get();
{
- psl->color_downsample_ps = DRW_pass_create("Downsample", DRW_STATE_WRITE_COLOR);
+ psl->color_downsample_ps = DRW_pass_create(
+ "Downsample", DRW_STATE_WRITE_COLOR);
DRWShadingGroup *grp = DRW_shgroup_create(e_data.downsample_sh, psl->color_downsample_ps);
DRW_shgroup_uniform_texture_ref(grp, "source", &e_data.color_src);
DRW_shgroup_uniform_float(grp, "fireflyFactor", &sldata->common_data.ssr_firefly_fac, 1);
@@ -315,7 +316,8 @@ void EEVEE_effects_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
{
static int zero = 0;
static uint six = 6;
- psl->color_downsample_cube_ps = DRW_pass_create("Downsample Cube", DRW_STATE_WRITE_COLOR);
+ psl->color_downsample_cube_ps = DRW_pass_create(
+ "Downsample Cube", DRW_STATE_WRITE_COLOR);
DRWShadingGroup *grp = DRW_shgroup_create(e_data.downsample_cube_sh, psl->color_downsample_cube_ps);
DRW_shgroup_uniform_texture_ref(grp, "source", &e_data.color_src);
DRW_shgroup_uniform_float(grp, "texelSize", &e_data.cube_texel_size, 1);
@@ -327,25 +329,29 @@ void EEVEE_effects_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
/* Perform min/max downsample */
DRWShadingGroup *grp;
- psl->maxz_downlevel_ps = DRW_pass_create("HiZ Max Down Level", downsample_write | DRW_STATE_DEPTH_ALWAYS);
+ psl->maxz_downlevel_ps = DRW_pass_create(
+ "HiZ Max Down Level", downsample_write | DRW_STATE_DEPTH_ALWAYS);
grp = DRW_shgroup_create(e_data.maxz_downlevel_sh, psl->maxz_downlevel_ps);
DRW_shgroup_uniform_texture_ref(grp, "depthBuffer", &txl->maxzbuffer);
DRW_shgroup_call_add(grp, quad, NULL);
/* Copy depth buffer to halfres top level of HiZ */
- psl->maxz_downdepth_ps = DRW_pass_create("HiZ Max Copy Depth Halfres", downsample_write | DRW_STATE_DEPTH_ALWAYS);
+ psl->maxz_downdepth_ps = DRW_pass_create(
+ "HiZ Max Copy Depth Halfres", downsample_write | DRW_STATE_DEPTH_ALWAYS);
grp = DRW_shgroup_create(e_data.maxz_downdepth_sh, psl->maxz_downdepth_ps);
DRW_shgroup_uniform_texture_ref(grp, "depthBuffer", &e_data.depth_src);
DRW_shgroup_call_add(grp, quad, NULL);
- psl->maxz_downdepth_layer_ps = DRW_pass_create("HiZ Max Copy DepthLayer Halfres", downsample_write | DRW_STATE_DEPTH_ALWAYS);
+ psl->maxz_downdepth_layer_ps = DRW_pass_create(
+ "HiZ Max Copy DepthLayer Halfres", downsample_write | DRW_STATE_DEPTH_ALWAYS);
grp = DRW_shgroup_create(e_data.maxz_downdepth_layer_sh, psl->maxz_downdepth_layer_ps);
DRW_shgroup_uniform_texture_ref(grp, "depthBuffer", &e_data.depth_src);
DRW_shgroup_uniform_int(grp, "depthLayer", &e_data.depth_src_layer, 1);
DRW_shgroup_call_add(grp, quad, NULL);
- psl->maxz_copydepth_ps = DRW_pass_create("HiZ Max Copy Depth Fullres", downsample_write | DRW_STATE_DEPTH_ALWAYS);
+ psl->maxz_copydepth_ps = DRW_pass_create(
+ "HiZ Max Copy Depth Fullres", downsample_write | DRW_STATE_DEPTH_ALWAYS);
grp = DRW_shgroup_create(e_data.maxz_copydepth_sh, psl->maxz_copydepth_ps);
DRW_shgroup_uniform_texture_ref(grp, "depthBuffer", &e_data.depth_src);
DRW_shgroup_call_add(grp, quad, NULL);
@@ -353,7 +359,8 @@ void EEVEE_effects_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
if ((effects->enabled_effects & EFFECT_VELOCITY_BUFFER) != 0) {
/* This pass compute camera motions to the non moving objects. */
- psl->velocity_resolve = DRW_pass_create("Velocity Resolve", DRW_STATE_WRITE_COLOR);
+ psl->velocity_resolve = DRW_pass_create(
+ "Velocity Resolve", DRW_STATE_WRITE_COLOR);
DRWShadingGroup *grp = DRW_shgroup_create(e_data.velocity_resolve_sh, psl->velocity_resolve);
DRW_shgroup_uniform_texture_ref(grp, "depthBuffer", &e_data.depth_src);
DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo);
@@ -504,6 +511,13 @@ void EEVEE_draw_effects(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *vedata)
/* Save the final texture and framebuffer for final transformation or read. */
effects->final_tx = effects->source_buffer;
effects->final_fb = (effects->target_buffer != fbl->main_color_fb) ? fbl->main_fb : fbl->effect_fb;
+ if ((effects->enabled_effects & EFFECT_TAA) && (effects->enabled_effects & (EFFECT_BLOOM | EFFECT_DOF | EFFECT_MOTION_BLUR)) == 0) {
+ if (!effects->swap_double_buffer) {
+ effects->final_fb = fbl->double_buffer_fb;
+ } else {
+ effects->final_fb = fbl->main_fb;
+ }
+ }
/* If no post processes is enabled, buffers are still not swapped, do it now. */
SWAP_DOUBLE_BUFFERS();
diff --git a/source/blender/draw/engines/eevee/eevee_engine.c b/source/blender/draw/engines/eevee/eevee_engine.c
index 8448393aa97..f6776d43665 100644
--- a/source/blender/draw/engines/eevee/eevee_engine.c
+++ b/source/blender/draw/engines/eevee/eevee_engine.c
@@ -187,7 +187,6 @@ static void eevee_draw_background(void *vedata)
/* Default framebuffer and texture */
DefaultTextureList *dtxl = DRW_viewport_texture_list_get();
DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get();
-
/* Sort transparents before the loop. */
DRW_pass_sort_shgroup_z(psl->transparent_pass);
@@ -310,6 +309,11 @@ static void eevee_draw_background(void *vedata)
}
}
+ /* LookDev */
+ EEVEE_lookdev_draw_background(vedata);
+ /* END */
+
+
/* Tonemapping and transfer result to default framebuffer. */
GPU_framebuffer_bind(dfbl->default_fb);
DRW_transform_to_display(stl->effects->final_tx);
diff --git a/source/blender/draw/engines/eevee/eevee_lightprobes.c b/source/blender/draw/engines/eevee/eevee_lightprobes.c
index d2faeb6ed39..c7a2951a670 100644
--- a/source/blender/draw/engines/eevee/eevee_lightprobes.c
+++ b/source/blender/draw/engines/eevee/eevee_lightprobes.c
@@ -71,6 +71,7 @@
static struct {
struct GPUShader *probe_default_sh;
+ struct GPUShader *probe_default_studiolight_sh;
struct GPUShader *probe_filter_glossy_sh;
struct GPUShader *probe_filter_diffuse_sh;
struct GPUShader *probe_filter_visibility_sh;
@@ -214,6 +215,9 @@ static void lightprobe_shaders_init(void)
e_data.probe_default_sh = DRW_shader_create(
datatoc_background_vert_glsl, NULL, datatoc_default_world_frag_glsl, NULL);
+ e_data.probe_default_studiolight_sh = DRW_shader_create(
+ datatoc_background_vert_glsl, NULL, datatoc_default_world_frag_glsl, "#define LOOKDEV\n");
+
MEM_freeN(shader_str);
shader_str = BLI_string_joinN(
@@ -411,7 +415,11 @@ void EEVEE_lightprobes_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedat
World *wo = scene->world;
float *col = ts.colorBackground;
- if (wo) {
+
+ /* LookDev */
+ EEVEE_lookdev_cache_init(vedata, &grp, e_data.probe_default_studiolight_sh, psl->probe_background, pinfo);
+ /* END */
+ if (!grp && wo) {
col = &wo->horr;
bool wo_sh_compiled = true;
@@ -445,6 +453,7 @@ void EEVEE_lightprobes_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedat
if (wo->update_flag != 0 || pinfo->prev_world != wo || pinfo->prev_wo_sh_compiled != wo_sh_compiled) {
pinfo->update_world |= PROBE_UPDATE_ALL;
+ pinfo->studiolight_index = 0;
pinfo->prev_wo_sh_compiled = wo_sh_compiled;
pinfo->prev_world = wo;
}
@@ -452,6 +461,7 @@ void EEVEE_lightprobes_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedat
}
else if (pinfo->prev_world) {
pinfo->update_world |= PROBE_UPDATE_ALL;
+ pinfo->studiolight_index = 0;
pinfo->prev_wo_sh_compiled = false;
pinfo->prev_world = NULL;
}
@@ -1830,6 +1840,7 @@ void EEVEE_lightprobes_free(void)
MEM_SAFE_FREE(e_data.format_probe_display_cube);
MEM_SAFE_FREE(e_data.format_probe_display_planar);
DRW_SHADER_FREE_SAFE(e_data.probe_default_sh);
+ DRW_SHADER_FREE_SAFE(e_data.probe_default_studiolight_sh);
DRW_SHADER_FREE_SAFE(e_data.probe_filter_glossy_sh);
DRW_SHADER_FREE_SAFE(e_data.probe_filter_diffuse_sh);
DRW_SHADER_FREE_SAFE(e_data.probe_filter_visibility_sh);
diff --git a/source/blender/draw/engines/eevee/eevee_lights.c b/source/blender/draw/engines/eevee/eevee_lights.c
index 123dabbe226..dd69e19e7c1 100644
--- a/source/blender/draw/engines/eevee/eevee_lights.c
+++ b/source/blender/draw/engines/eevee/eevee_lights.c
@@ -82,7 +82,8 @@ static bool lightbits_get(const EEVEE_LightBits *r, uint idx)
return r->fields[idx / 8] & (1 << (idx % 8));
}
-static void lightbits_convert(EEVEE_LightBits *r, const EEVEE_LightBits *bitf, const int *light_bit_conv_table, uint table_length)
+static void lightbits_convert(
+ EEVEE_LightBits *r, const EEVEE_LightBits *bitf, const int *light_bit_conv_table, uint table_length)
{
for (int i = 0; i < table_length; ++i) {
if (lightbits_get(bitf, i) != 0) {
@@ -591,7 +592,7 @@ static void eevee_light_setup(Object *ob, EEVEE_Light *evli)
}
else if (la->type == LA_AREA) {
evli->sizex = max_ff(0.0001f, la->area_size * scale[0] * 0.5f);
- if (la->area_shape == LA_AREA_RECT) {
+ if (ELEM(la->area_shape, LA_AREA_RECT, LA_AREA_ELLIPSE)) {
evli->sizey = max_ff(0.0001f, la->area_sizey * scale[1] * 0.5f);
}
else {
@@ -602,10 +603,18 @@ static void eevee_light_setup(Object *ob, EEVEE_Light *evli)
evli->radius = max_ff(0.001f, la->area_size);
}
+ /* Lamp Type */
+ evli->lamptype = (float)la->type;
+
/* Make illumination power constant */
if (la->type == LA_AREA) {
power = 1.0f / (evli->sizex * evli->sizey * 4.0f * M_PI) * /* 1/(w*h*Pi) */
80.0f; /* XXX : Empirical, Fit cycles power */
+ if (ELEM(la->area_shape, LA_AREA_DISK, LA_AREA_ELLIPSE)) {
+ evli->lamptype = LAMPTYPE_AREA_ELLIPSE;
+ /* Scale power to account for the lower area of the ellipse compared to the surrouding rectangle. */
+ power *= 4.0f / M_PI;
+ }
}
else if (la->type == LA_SPOT || la->type == LA_LOCAL) {
power = 1.0f / (4.0f * evli->radius * evli->radius * M_PI * M_PI) * /* 1/(4*r²*Pi²) */
@@ -620,9 +629,6 @@ static void eevee_light_setup(Object *ob, EEVEE_Light *evli)
}
mul_v3_fl(evli->color, power * la->energy);
- /* Lamp Type */
- evli->lamptype = (float)la->type;
-
/* No shadow by default */
evli->shadowid = -1.0f;
}
diff --git a/source/blender/draw/engines/eevee/eevee_lookdev.c b/source/blender/draw/engines/eevee/eevee_lookdev.c
new file mode 100644
index 00000000000..4ae13669a01
--- /dev/null
+++ b/source/blender/draw/engines/eevee/eevee_lookdev.c
@@ -0,0 +1,130 @@
+/*
+ * Copyright 2016, Blender Foundation.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Contributor(s): Blender Institute
+ *
+ */
+
+/** \file eevee_lookdev.c
+ * \ingroup draw_engine
+ */
+#include "DRW_render.h"
+
+#include "BKE_camera.h"
+#include "BKE_studiolight.h"
+
+#include "DNA_screen_types.h"
+
+#include "eevee_private.h"
+
+void EEVEE_lookdev_cache_init(EEVEE_Data *vedata, DRWShadingGroup **grp, GPUShader *shader, DRWPass *pass, EEVEE_LightProbesInfo *pinfo)
+{
+ EEVEE_StorageList *stl = vedata->stl;
+ const DRWContextState *draw_ctx = DRW_context_state_get();
+ View3D *v3d = draw_ctx->v3d;
+ if (v3d && v3d->drawtype == OB_MATERIAL)
+ {
+ StudioLight *sl = BKE_studiolight_find(v3d->shading.studio_light, STUDIOLIGHT_ORIENTATION_WORLD);
+ if ((sl->flag & STUDIOLIGHT_ORIENTATION_WORLD)) {
+ struct Gwn_Batch *geom = DRW_cache_fullscreen_quad_get();
+
+ BKE_studiolight_ensure_flag(sl, STUDIOLIGHT_EQUIRECTANGULAR_GPUTEXTURE);
+ *grp = DRW_shgroup_create(shader, pass);
+ GPUTexture *tex = sl->equirectangular_gputexture;
+ DRW_shgroup_uniform_texture(*grp, "image", tex);
+
+ axis_angle_to_mat3_single(stl->g_data->studiolight_matrix, 'Z', v3d->shading.studiolight_rot_z);
+ DRW_shgroup_uniform_mat3(*grp, "StudioLightMatrix", stl->g_data->studiolight_matrix);
+
+ DRW_shgroup_uniform_float(*grp, "backgroundAlpha", &stl->g_data->background_alpha, 1);
+ DRW_shgroup_call_add(*grp, geom, NULL);
+
+ /* Do we need to recalc the lightprobes? */
+ if (pinfo && (pinfo->studiolight_index != sl->index || pinfo->studiolight_rot_z != v3d->shading.studiolight_rot_z)) {
+ pinfo->update_world |= PROBE_UPDATE_ALL;
+ pinfo->studiolight_index = sl->index;
+ pinfo->studiolight_rot_z = v3d->shading.studiolight_rot_z;
+ pinfo->prev_wo_sh_compiled = false;
+ pinfo->prev_world = NULL;
+ }
+ }
+ }
+}
+
+void EEVEE_lookdev_draw_background(EEVEE_Data *vedata)
+{
+ EEVEE_PassList *psl = vedata->psl;
+ EEVEE_StorageList *stl = ((EEVEE_Data *)vedata)->stl;
+ EEVEE_EffectsInfo *effects = stl->effects;
+ EEVEE_ViewLayerData *sldata = EEVEE_view_layer_data_ensure();
+
+ const DRWContextState *draw_ctx = DRW_context_state_get();
+
+ if (psl->lookdev_pass && draw_ctx->v3d) {
+ DRW_stats_group_start("Look Dev");
+ CameraParams params;
+ BKE_camera_params_init(&params);
+ View3D *v3d = draw_ctx->v3d;
+ RegionView3D *rv3d = draw_ctx->rv3d;
+ ARegion *ar = draw_ctx->ar;
+
+ BKE_camera_params_from_view3d(&params, draw_ctx->depsgraph, v3d, rv3d);
+ params.is_ortho = true;
+ params.ortho_scale = 4.0;
+ params.zoom = CAMERA_PARAM_ZOOM_INIT_PERSP;
+ BKE_camera_params_compute_viewplane(&params, ar->winx, ar->winy, 1.0f, 1.0f);
+ BKE_camera_params_compute_matrix(&params);
+
+ const float *viewport_size = DRW_viewport_size_get();
+ int viewport_inset_x = viewport_size[0]/4;
+ int viewport_inset_y = viewport_size[1]/4;
+
+ EEVEE_CommonUniformBuffer *common = &sldata->common_data;
+ common->la_num_light = 0;
+ common->prb_num_planar = 0;
+ common->prb_num_render_cube = 1;
+ common->prb_num_render_grid = 1;
+ common->ao_dist = 0.0f;
+ common->ao_factor = 0.0f;
+ common->ao_settings = 0.0f;
+ DRW_uniformbuffer_update(sldata->common_ubo, common);
+
+ /* override matrices */
+ float winmat[4][4];
+ float winmat_inv[4][4];
+ copy_m4_m4(winmat, params.winmat);
+ invert_m4_m4(winmat_inv, winmat);
+ DRW_viewport_matrix_override_set(winmat, DRW_MAT_WIN);
+ DRW_viewport_matrix_override_set(winmat_inv, DRW_MAT_WININV);
+ float viewmat[4][4];
+ DRW_viewport_matrix_get(viewmat, DRW_MAT_VIEW);
+ float persmat[4][4];
+ float persmat_inv[4][4];
+ mul_m4_m4m4(persmat, winmat, viewmat);
+ invert_m4_m4(persmat_inv, persmat);
+ DRW_viewport_matrix_override_set(persmat, DRW_MAT_PERS);
+ DRW_viewport_matrix_override_set(persmat_inv, DRW_MAT_PERSINV);
+
+ GPUFrameBuffer *fb = effects->final_fb;
+ GPU_framebuffer_bind(fb);
+ GPU_framebuffer_viewport_set(fb, viewport_size[0]-viewport_inset_x, 0, viewport_inset_x, viewport_inset_y);
+ DRW_draw_pass(psl->lookdev_pass);
+
+ DRW_viewport_matrix_override_unset_all();
+ DRW_stats_group_end();
+ }
+} \ No newline at end of file
diff --git a/source/blender/draw/engines/eevee/eevee_materials.c b/source/blender/draw/engines/eevee/eevee_materials.c
index b585b1a4f85..1134c82954c 100644
--- a/source/blender/draw/engines/eevee/eevee_materials.c
+++ b/source/blender/draw/engines/eevee/eevee_materials.c
@@ -34,6 +34,7 @@
#include "BKE_particle.h"
#include "BKE_paint.h"
#include "BKE_pbvh.h"
+#include "BKE_studiolight.h"
#include "DNA_world_types.h"
#include "DNA_modifier_types.h"
@@ -54,6 +55,7 @@ static struct {
struct GPUShader *default_prepass_clip_sh;
struct GPUShader *default_lit[VAR_MAT_MAX];
struct GPUShader *default_background;
+ struct GPUShader *default_studiolight_background;
struct GPUShader *update_noise_sh;
/* 64*64 array texture containing all LUTs and other utilitarian arrays.
@@ -320,6 +322,9 @@ static char *eevee_get_defines(int options)
if (((options & VAR_MAT_VOLUME) != 0) && ((options & VAR_MAT_BLEND) != 0)) {
BLI_dynstr_appendf(ds, "#define USE_ALPHA_BLEND_VOLUMETRICS\n");
}
+ if ((options & VAR_MAT_LOOKDEV) != 0) {
+ BLI_dynstr_appendf(ds, "#define LOOKDEV\n");
+ }
str = BLI_dynstr_get_cstring(ds);
BLI_dynstr_free(ds);
@@ -578,6 +583,10 @@ void EEVEE_materials_init(EEVEE_ViewLayerData *sldata, EEVEE_StorageList *stl, E
datatoc_background_vert_glsl, NULL, datatoc_default_world_frag_glsl,
NULL);
+ e_data.default_studiolight_background = DRW_shader_create(
+ datatoc_background_vert_glsl, NULL, datatoc_default_world_frag_glsl,
+ "#define LOOKDEV\n");
+
e_data.default_prepass_sh = DRW_shader_create(
datatoc_prepass_vert_glsl, NULL, datatoc_prepass_frag_glsl,
NULL);
@@ -861,6 +870,35 @@ static struct DRWShadingGroup *EEVEE_default_shading_group_get(
return DRW_shgroup_create(e_data.default_lit[options], vedata->psl->default_pass[options]);
}
+/**
+ * Create a default shading group inside the lookdev pass without standard uniforms.
+ **/
+static struct DRWShadingGroup *EEVEE_lookdev_shading_group_get(
+ EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata,
+ bool use_ssr, int shadow_method)
+{
+ static int ssr_id;
+ ssr_id = (use_ssr) ? 1 : -1;
+ int options = VAR_MAT_MESH | VAR_MAT_LOOKDEV;
+
+ options |= eevee_material_shadow_option(shadow_method);
+
+ if (e_data.default_lit[options] == NULL) {
+ create_default_shader(options);
+ }
+
+ if (vedata->psl->lookdev_pass == NULL) {
+ DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_ALWAYS | DRW_STATE_CULL_BACK;
+ vedata->psl->lookdev_pass = DRW_pass_create("LookDev Pass", state);
+
+ DRWShadingGroup *shgrp = DRW_shgroup_create(e_data.default_lit[options], vedata->psl->lookdev_pass);
+ /* XXX / WATCH: This creates non persistent binds for the ubos and textures.
+ * But it's currently OK because the following shgroups does not add any bind. */
+ add_standard_uniforms(shgrp, sldata, vedata, &ssr_id, NULL, false, false);
+ }
+
+ return DRW_shgroup_create(e_data.default_lit[options], vedata->psl->lookdev_pass);
+}
void EEVEE_materials_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
{
EEVEE_PassList *psl = ((EEVEE_Data *)vedata)->psl;
@@ -884,7 +922,11 @@ void EEVEE_materials_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
float *col = ts.colorBackground;
- if (wo) {
+ /* LookDev */
+ EEVEE_lookdev_cache_init(vedata, &grp, e_data.default_studiolight_background, psl->background_pass, NULL);
+ /* END */
+
+ if (!grp && wo) {
col = &wo->horr;
if (wo->use_nodes && wo->nodetree) {
@@ -936,7 +978,8 @@ void EEVEE_materials_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
state = DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL | DRW_STATE_CLIP_PLANES | DRW_STATE_CULL_BACK;
psl->depth_pass_clip_cull = DRW_pass_create("Depth Pass Cull Clip", state);
- stl->g_data->depth_shgrp_clip_cull = DRW_shgroup_create(e_data.default_prepass_clip_sh, psl->depth_pass_clip_cull);
+ stl->g_data->depth_shgrp_clip_cull = DRW_shgroup_create(
+ e_data.default_prepass_clip_sh, psl->depth_pass_clip_cull);
DRW_shgroup_uniform_block(stl->g_data->depth_shgrp_clip_cull, "clip_block", sldata->clip_ubo);
}
@@ -952,26 +995,33 @@ void EEVEE_materials_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
state = DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL | DRW_STATE_CULL_BACK;
psl->refract_depth_pass_cull = DRW_pass_create("Refract Depth Pass Cull", state);
- stl->g_data->refract_depth_shgrp_cull = DRW_shgroup_create(e_data.default_prepass_sh, psl->refract_depth_pass_cull);
+ stl->g_data->refract_depth_shgrp_cull = DRW_shgroup_create(
+ e_data.default_prepass_sh, psl->refract_depth_pass_cull);
state = DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL | DRW_STATE_CLIP_PLANES | DRW_STATE_WIRE;
psl->refract_depth_pass_clip = DRW_pass_create("Refract Depth Pass Clip", state);
- stl->g_data->refract_depth_shgrp_clip = DRW_shgroup_create(e_data.default_prepass_clip_sh, psl->refract_depth_pass_clip);
+ stl->g_data->refract_depth_shgrp_clip = DRW_shgroup_create(
+ e_data.default_prepass_clip_sh, psl->refract_depth_pass_clip);
DRW_shgroup_uniform_block(stl->g_data->refract_depth_shgrp_clip, "clip_block", sldata->clip_ubo);
state = DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL | DRW_STATE_CLIP_PLANES | DRW_STATE_CULL_BACK;
psl->refract_depth_pass_clip_cull = DRW_pass_create("Refract Depth Pass Cull Clip", state);
- stl->g_data->refract_depth_shgrp_clip_cull = DRW_shgroup_create(e_data.default_prepass_clip_sh, psl->refract_depth_pass_clip_cull);
+ stl->g_data->refract_depth_shgrp_clip_cull = DRW_shgroup_create(
+ e_data.default_prepass_clip_sh, psl->refract_depth_pass_clip_cull);
DRW_shgroup_uniform_block(stl->g_data->refract_depth_shgrp_clip_cull, "clip_block", sldata->clip_ubo);
}
{
- DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_EQUAL | DRW_STATE_CLIP_PLANES | DRW_STATE_WIRE;
+ DRWState state = (
+ DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_EQUAL | DRW_STATE_CLIP_PLANES |
+ DRW_STATE_WIRE);
psl->refract_pass = DRW_pass_create("Opaque Refraction Pass", state);
}
{
- DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_EQUAL | DRW_STATE_CLIP_PLANES | DRW_STATE_WIRE | DRW_STATE_WRITE_STENCIL;
+ DRWState state = (
+ DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_EQUAL | DRW_STATE_CLIP_PLANES |
+ DRW_STATE_WIRE | DRW_STATE_WRITE_STENCIL);
psl->sss_pass = DRW_pass_create("Subsurface Pass", state);
e_data.sss_count = 0;
}
@@ -1062,16 +1112,16 @@ static void material_opaque(
static float half = 0.5f;
/* Shading */
- *gpumat = EEVEE_material_mesh_get(scene, ma, vedata, false, false, use_refract,
- use_sss, use_translucency, linfo->shadow_method);
+ *gpumat = EEVEE_material_mesh_get(
+ scene, ma, vedata, false, false, use_refract,
+ use_sss, use_translucency, linfo->shadow_method);
GPUMaterialStatus status_mat_surface = GPU_material_status(*gpumat);
/* Alpha CLipped : Discard pixel from depth pass, then
* fail the depth test for shading. */
if (ELEM(ma->blend_method, MA_BM_CLIP, MA_BM_HASHED)) {
- *gpumat_depth = EEVEE_material_mesh_depth_get(scene, ma,
- (ma->blend_method == MA_BM_HASHED), false);
+ *gpumat_depth = EEVEE_material_mesh_depth_get(scene, ma, (ma->blend_method == MA_BM_HASHED), false);
GPUMaterialStatus status_mat_depth = GPU_material_status(*gpumat_depth);
if (status_mat_depth != GPU_MAT_SUCCESS) {
@@ -1080,12 +1130,16 @@ static void material_opaque(
status_mat_surface = status_mat_depth;
}
else if (use_refract) {
- *shgrp_depth = DRW_shgroup_material_create(*gpumat_depth, (do_cull) ? psl->refract_depth_pass_cull : psl->refract_depth_pass);
- *shgrp_depth_clip = DRW_shgroup_material_create(*gpumat_depth, (do_cull) ? psl->refract_depth_pass_clip_cull : psl->refract_depth_pass_clip);
+ *shgrp_depth = DRW_shgroup_material_create(
+ *gpumat_depth, (do_cull) ? psl->refract_depth_pass_cull : psl->refract_depth_pass);
+ *shgrp_depth_clip = DRW_shgroup_material_create(
+ *gpumat_depth, (do_cull) ? psl->refract_depth_pass_clip_cull : psl->refract_depth_pass_clip);
}
else {
- *shgrp_depth = DRW_shgroup_material_create(*gpumat_depth, (do_cull) ? psl->depth_pass_cull : psl->depth_pass);
- *shgrp_depth_clip = DRW_shgroup_material_create(*gpumat_depth, (do_cull) ? psl->depth_pass_clip_cull : psl->depth_pass_clip);
+ *shgrp_depth = DRW_shgroup_material_create(
+ *gpumat_depth, (do_cull) ? psl->depth_pass_cull : psl->depth_pass);
+ *shgrp_depth_clip = DRW_shgroup_material_create(
+ *gpumat_depth, (do_cull) ? psl->depth_pass_clip_cull : psl->depth_pass_clip);
}
if (*shgrp_depth != NULL) {
@@ -1110,16 +1164,18 @@ static void material_opaque(
static int first_ssr = 1;
int *ssr_id = (((effects->enabled_effects & EFFECT_SSR) != 0) && !use_refract) ? &first_ssr : &no_ssr;
- *shgrp = DRW_shgroup_material_create(*gpumat,
- (use_refract) ? psl->refract_pass :
- (use_sss) ? psl->sss_pass : psl->material_pass);
+ *shgrp = DRW_shgroup_material_create(
+ *gpumat,
+ (use_refract) ? psl->refract_pass :
+ (use_sss) ? psl->sss_pass : psl->material_pass);
add_standard_uniforms(*shgrp, sldata, vedata, ssr_id, &ma->refract_depth, use_refract, false);
if (use_sss) {
struct GPUTexture *sss_tex_profile = NULL;
- struct GPUUniformBuffer *sss_profile = GPU_material_sss_profile_get(*gpumat,
- stl->effects->sss_sample_count,
- &sss_tex_profile);
+ struct GPUUniformBuffer *sss_profile = GPU_material_sss_profile_get(
+ *gpumat,
+ stl->effects->sss_sample_count,
+ &sss_tex_profile);
if (sss_profile) {
if (use_translucency) {
@@ -1188,7 +1244,8 @@ static void material_opaque(
static void material_transparent(
Material *ma, EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata,
- bool do_cull, bool use_flat_nor, struct GPUMaterial **gpumat, struct DRWShadingGroup **shgrp, struct DRWShadingGroup **shgrp_depth)
+ bool do_cull, bool use_flat_nor,
+ struct GPUMaterial **gpumat, struct DRWShadingGroup **shgrp, struct DRWShadingGroup **shgrp_depth)
{
const DRWContextState *draw_ctx = DRW_context_state_get();
Scene *scene = draw_ctx->scene;
@@ -1196,8 +1253,10 @@ static void material_transparent(
EEVEE_PassList *psl = ((EEVEE_Data *)vedata)->psl;
EEVEE_LampsInfo *linfo = sldata->lamps;
- const bool use_refract = ((ma->blend_flag & MA_BL_SS_REFRACTION) != 0) && ((stl->effects->enabled_effects & EFFECT_REFRACT) != 0);
-
+ const bool use_refract = (
+ ((ma->blend_flag & MA_BL_SS_REFRACTION) != 0) &&
+ ((stl->effects->enabled_effects & EFFECT_REFRACT) != 0)
+ );
float *color_p = &ma->r;
float *metal_p = &ma->ray_mirror;
float *spec_p = &ma->spec;
@@ -1209,8 +1268,9 @@ static void material_transparent(
static float half = 0.5f;
/* Shading */
- *gpumat = EEVEE_material_mesh_get(scene, ma, vedata, true, (ma->blend_method == MA_BM_MULTIPLY), use_refract,
- false, false, linfo->shadow_method);
+ *gpumat = EEVEE_material_mesh_get(
+ scene, ma, vedata, true, (ma->blend_method == MA_BM_MULTIPLY), use_refract,
+ false, false, linfo->shadow_method);
switch (GPU_material_status(*gpumat)) {
case GPU_MAT_SUCCESS:
@@ -1251,8 +1311,11 @@ static void material_transparent(
const bool use_prepass = ((ma->blend_flag & MA_BL_HIDE_BACKSIDE) != 0);
- DRWState all_state = DRW_STATE_WRITE_DEPTH | DRW_STATE_WRITE_COLOR | DRW_STATE_CULL_BACK | DRW_STATE_DEPTH_LESS_EQUAL | DRW_STATE_DEPTH_EQUAL |
- DRW_STATE_BLEND | DRW_STATE_ADDITIVE | DRW_STATE_MULTIPLY;
+ DRWState all_state = (
+ DRW_STATE_WRITE_DEPTH | DRW_STATE_WRITE_COLOR | DRW_STATE_CULL_BACK |
+ DRW_STATE_DEPTH_LESS_EQUAL | DRW_STATE_DEPTH_EQUAL |
+ DRW_STATE_BLEND | DRW_STATE_ADDITIVE | DRW_STATE_MULTIPLY
+ );
DRWState cur_state = DRW_STATE_WRITE_COLOR;
cur_state |= (use_prepass) ? DRW_STATE_DEPTH_EQUAL : DRW_STATE_DEPTH_LESS_EQUAL;
@@ -1383,10 +1446,11 @@ void EEVEE_materials_cache_populate(EEVEE_Data *vedata, EEVEE_ViewLayerData *sld
char *auto_layer_names;
int *auto_layer_is_srgb;
int auto_layer_count;
- struct Gwn_Batch **mat_geom = DRW_cache_object_surface_material_get(ob, gpumat_array, materials_len,
- &auto_layer_names,
- &auto_layer_is_srgb,
- &auto_layer_count);
+ struct Gwn_Batch **mat_geom = DRW_cache_object_surface_material_get(
+ ob, gpumat_array, materials_len,
+ &auto_layer_names,
+ &auto_layer_is_srgb,
+ &auto_layer_count);
if (mat_geom) {
for (int i = 0; i < materials_len; ++i) {
EEVEE_ObjectEngineData *oedata = NULL;
@@ -1440,17 +1504,20 @@ void EEVEE_materials_cache_populate(EEVEE_Data *vedata, EEVEE_ViewLayerData *sld
struct GPUMaterial *gpumat;
switch (ma->blend_shadow) {
case MA_BS_SOLID:
- EEVEE_lights_cache_shcaster_add(sldata, stl, mat_geom[i], ob);
+ EEVEE_lights_cache_shcaster_add(
+ sldata, stl, mat_geom[i], ob);
*cast_shadow = true;
break;
case MA_BS_CLIP:
gpumat = EEVEE_material_mesh_depth_get(scene, ma, false, true);
- EEVEE_lights_cache_shcaster_material_add(sldata, psl, gpumat, mat_geom[i], ob, &ma->alpha_threshold);
+ EEVEE_lights_cache_shcaster_material_add(
+ sldata, psl, gpumat, mat_geom[i], ob, &ma->alpha_threshold);
*cast_shadow = true;
break;
case MA_BS_HASHED:
gpumat = EEVEE_material_mesh_depth_get(scene, ma, true, true);
- EEVEE_lights_cache_shcaster_material_add(sldata, psl, gpumat, mat_geom[i], ob, NULL);
+ EEVEE_lights_cache_shcaster_material_add(
+ sldata, psl, gpumat, mat_geom[i], ob, NULL);
*cast_shadow = true;
break;
case MA_BS_NONE:
@@ -1563,6 +1630,45 @@ void EEVEE_materials_cache_finish(EEVEE_Data *vedata)
{
EEVEE_StorageList *stl = ((EEVEE_Data *)vedata)->stl;
+ /* Look-Dev */
+ const DRWContextState *draw_ctx = DRW_context_state_get();
+ const View3D *v3d = draw_ctx->v3d;
+ if (v3d && v3d->drawtype == OB_MATERIAL) {
+ EEVEE_ViewLayerData *sldata = EEVEE_view_layer_data_ensure();
+ EEVEE_LampsInfo *linfo = sldata->lamps;
+ struct Gwn_Batch *sphere = DRW_cache_sphere_get();
+ static float mat1[4][4];
+ static float color[3] = {0.8f, 0.8f, 0.8f};
+ static float metallic_on = 1.0f;
+ static float metallic_off = 0.00f;
+ static float specular_off = 0.5f;
+ static float specular_on = 1.0f;
+ static float roughness_off = 0.05f;
+ static float roughness_on = 1.00f;
+
+ float view_mat[4][4];
+ DRW_viewport_matrix_get(view_mat, DRW_MAT_VIEWINV);
+
+ DRWShadingGroup *shgrp = EEVEE_lookdev_shading_group_get(sldata, vedata, false, linfo->shadow_method);
+ DRW_shgroup_uniform_vec3(shgrp, "basecol", color, 1);
+ DRW_shgroup_uniform_float(shgrp, "metallic", &metallic_on, 1);
+ DRW_shgroup_uniform_float(shgrp, "specular", &specular_on, 1);
+ DRW_shgroup_uniform_float(shgrp, "roughness", &roughness_off, 1);
+ unit_m4(mat1);
+ mul_m4_m4m4(mat1, mat1, view_mat);
+ translate_m4(mat1, -1.5f, 0.0f, -5.0f);
+ DRW_shgroup_call_add(shgrp, sphere, mat1);
+
+ shgrp = EEVEE_lookdev_shading_group_get(sldata, vedata, false, linfo->shadow_method);
+ DRW_shgroup_uniform_vec3(shgrp, "basecol", color, 1);
+ DRW_shgroup_uniform_float(shgrp, "metallic", &metallic_off, 1);
+ DRW_shgroup_uniform_float(shgrp, "specular", &specular_off, 1);
+ DRW_shgroup_uniform_float(shgrp, "roughness", &roughness_on, 1);
+ translate_m4(mat1, 3.0f, 0.0f, 0.0f);
+ DRW_shgroup_call_add(shgrp, sphere, mat1);
+ }
+ /* END */
+
BLI_ghash_free(stl->g_data->material_hash, NULL, MEM_freeN);
BLI_ghash_free(stl->g_data->hair_material_hash, NULL, NULL);
}
@@ -1578,6 +1684,7 @@ void EEVEE_materials_free(void)
DRW_SHADER_FREE_SAFE(e_data.default_prepass_sh);
DRW_SHADER_FREE_SAFE(e_data.default_prepass_clip_sh);
DRW_SHADER_FREE_SAFE(e_data.default_background);
+ DRW_SHADER_FREE_SAFE(e_data.default_studiolight_background);
DRW_SHADER_FREE_SAFE(e_data.update_noise_sh);
DRW_TEXTURE_FREE_SAFE(e_data.util_tex);
DRW_TEXTURE_FREE_SAFE(e_data.noise_tex);
diff --git a/source/blender/draw/engines/eevee/eevee_occlusion.c b/source/blender/draw/engines/eevee/eevee_occlusion.c
index 305daef87d1..f39fbe33a71 100644
--- a/source/blender/draw/engines/eevee/eevee_occlusion.c
+++ b/source/blender/draw/engines/eevee/eevee_occlusion.c
@@ -77,7 +77,7 @@ int EEVEE_occlusion_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
const DRWContextState *draw_ctx = DRW_context_state_get();
const Scene *scene_eval = DEG_get_evaluated_scene(draw_ctx->depsgraph);
- if (scene_eval->flag & SCE_EEVEE_GTAO_ENABLED) {
+ if (scene_eval->eevee.flag & SCE_EEVEE_GTAO_ENABLED) {
const float *viewport_size = DRW_viewport_size_get();
const int fs_size[2] = {(int)viewport_size[0], (int)viewport_size[1]};
@@ -91,14 +91,14 @@ int EEVEE_occlusion_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
common_data->ao_quality = 1.0f - scene_eval->eevee.gtao_quality;
common_data->ao_settings = 1.0f; /* USE_AO */
- if (scene_eval->flag & SCE_EEVEE_GTAO_BENT_NORMALS) {
+ if (scene_eval->eevee.flag & SCE_EEVEE_GTAO_BENT_NORMALS) {
common_data->ao_settings += 2.0f; /* USE_BENT_NORMAL */
}
- if (scene_eval->flag & SCE_EEVEE_GTAO_BOUNCE) {
+ if (scene_eval->eevee.flag & SCE_EEVEE_GTAO_BOUNCE) {
common_data->ao_settings += 4.0f; /* USE_DENOISE */
}
- common_data->ao_bounce_fac = (scene_eval->flag & SCE_EEVEE_GTAO_BOUNCE) ? 1.0f : 0.0f;
+ common_data->ao_bounce_fac = (scene_eval->eevee.flag & SCE_EEVEE_GTAO_BOUNCE) ? 1.0f : 0.0f;
effects->gtao_horizons = DRW_texture_pool_query_2D(fs_size[0], fs_size[1], GPU_RGBA8,
&draw_engine_eevee_type);
@@ -141,7 +141,7 @@ void EEVEE_occlusion_output_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata
const DRWContextState *draw_ctx = DRW_context_state_get();
const Scene *scene_eval = DEG_get_evaluated_scene(draw_ctx->depsgraph);
- if (scene_eval->flag & SCE_EEVEE_GTAO_ENABLED) {
+ if (scene_eval->eevee.flag & SCE_EEVEE_GTAO_ENABLED) {
DefaultTextureList *dtxl = DRW_viewport_texture_list_get();
float clear[4] = {0.0f, 0.0f, 0.0f, 0.0f};
diff --git a/source/blender/draw/engines/eevee/eevee_private.h b/source/blender/draw/engines/eevee/eevee_private.h
index c95e51548d0..10a53db5e35 100644
--- a/source/blender/draw/engines/eevee/eevee_private.h
+++ b/source/blender/draw/engines/eevee/eevee_private.h
@@ -101,28 +101,29 @@ enum {
/* Material shader variations */
enum {
- VAR_MAT_MESH = (1 << 0),
- VAR_MAT_PROBE = (1 << 1),
- VAR_MAT_HAIR = (1 << 2),
- VAR_MAT_FLAT = (1 << 3),
- VAR_MAT_BLEND = (1 << 4),
- VAR_MAT_VSM = (1 << 5),
- VAR_MAT_ESM = (1 << 6),
- VAR_MAT_VOLUME = (1 << 7),
+ VAR_MAT_MESH = (1 << 0),
+ VAR_MAT_PROBE = (1 << 1),
+ VAR_MAT_HAIR = (1 << 2),
+ VAR_MAT_FLAT = (1 << 3),
+ VAR_MAT_BLEND = (1 << 4),
+ VAR_MAT_VSM = (1 << 5),
+ VAR_MAT_ESM = (1 << 6),
+ VAR_MAT_VOLUME = (1 << 7),
+ VAR_MAT_LOOKDEV = (1 << 8),
/* Max number of variation */
/* IMPORTANT : Leave it last and set
* it's value accordingly. */
- VAR_MAT_MAX = (1 << 8),
+ VAR_MAT_MAX = (1 << 9),
/* These are options that are not counted in VAR_MAT_MAX
* because they are not cumulative with the others above. */
- VAR_MAT_CLIP = (1 << 9),
- VAR_MAT_HASH = (1 << 10),
- VAR_MAT_MULT = (1 << 11),
- VAR_MAT_SHADOW = (1 << 12),
- VAR_MAT_REFRACT = (1 << 13),
- VAR_MAT_SSS = (1 << 14),
- VAR_MAT_TRANSLUC = (1 << 15),
- VAR_MAT_SSSALBED = (1 << 16),
+ VAR_MAT_CLIP = (1 << 10),
+ VAR_MAT_HASH = (1 << 11),
+ VAR_MAT_MULT = (1 << 12),
+ VAR_MAT_SHADOW = (1 << 13),
+ VAR_MAT_REFRACT = (1 << 14),
+ VAR_MAT_SSS = (1 << 15),
+ VAR_MAT_TRANSLUC = (1 << 16),
+ VAR_MAT_SSSALBED = (1 << 17),
};
typedef struct EEVEE_BoundSphere {
@@ -205,6 +206,7 @@ typedef struct EEVEE_PassList {
struct DRWPass *transparent_pass;
struct DRWPass *background_pass;
struct DRWPass *update_noise_pass;
+ struct DRWPass *lookdev_pass;
} EEVEE_PassList;
typedef struct EEVEE_FramebufferList {
@@ -277,6 +279,7 @@ typedef struct EEVEE_StorageList {
struct EEVEE_EffectsInfo *effects;
struct EEVEE_PrivateData *g_data;
+
} EEVEE_StorageList;
/* ************ LIGHT UBO ************* */
@@ -289,6 +292,9 @@ typedef struct EEVEE_Light {
float forwardvec[3], lamptype;
} EEVEE_Light;
+/* Special type for elliptic area lamps, matches lamps_lib.glsl */
+#define LAMPTYPE_AREA_ELLIPSE 100.0f
+
typedef struct EEVEE_Shadow {
float near, far, bias, exp;
float shadow_start, data_start, multi_shadow_count, shadow_blur;
@@ -449,6 +455,8 @@ typedef struct EEVEE_LightProbesInfo {
float visibility_blur;
float intensity_fac;
int shres;
+ int studiolight_index;
+ float studiolight_rot_z;
/* List of probes in the scene. */
/* XXX This is fragile, can get out of sync quickly. */
struct Object *probes_cube_ref[MAX_PROBE];
@@ -458,7 +466,7 @@ typedef struct EEVEE_LightProbesInfo {
struct EEVEE_LightProbe probe_data[MAX_PROBE];
struct EEVEE_LightGrid grid_data[MAX_GRID];
struct EEVEE_PlanarReflection planar_data[MAX_PLANAR];
- /* Probe Visibility Group */
+ /* Probe Visibility Collection */
EEVEE_LightProbeVisTest vis_data;
} EEVEE_LightProbesInfo;
@@ -780,6 +788,8 @@ typedef struct EEVEE_PrivateData {
float persmat[4][4], persinv[4][4];
float viewmat[4][4], viewinv[4][4];
float winmat[4][4], wininv[4][4];
+ float studiolight_matrix[3][3];
+
/* Mist Settings */
float mist_start, mist_inv_dist, mist_falloff;
} EEVEE_PrivateData; /* Transient data */
@@ -806,8 +816,10 @@ struct GPUMaterial *EEVEE_material_world_volume_get(struct Scene *scene, struct
struct GPUMaterial *EEVEE_material_mesh_get(
struct Scene *scene, Material *ma, EEVEE_Data *vedata,
bool use_blend, bool use_multiply, bool use_refract, bool use_sss, bool use_translucency, int shadow_method);
-struct GPUMaterial *EEVEE_material_mesh_volume_get(struct Scene *scene, Material *ma);
-struct GPUMaterial *EEVEE_material_mesh_depth_get(struct Scene *scene, Material *ma, bool use_hashed_alpha, bool is_shadow);
+struct GPUMaterial *EEVEE_material_mesh_volume_get(
+ struct Scene *scene, Material *ma);
+struct GPUMaterial *EEVEE_material_mesh_depth_get(
+ struct Scene *scene, Material *ma, bool use_hashed_alpha, bool is_shadow);
struct GPUMaterial *EEVEE_material_hair_get(struct Scene *scene, Material *ma, int shadow_method);
void EEVEE_materials_free(void);
void EEVEE_draw_default_passes(EEVEE_PassList *psl);
@@ -924,6 +936,10 @@ void EEVEE_render_cache(void *vedata, struct Object *ob, struct RenderEngine *en
void EEVEE_render_draw(EEVEE_Data *vedata, struct RenderEngine *engine, struct RenderLayer *render_layer, const struct rcti *rect);
void EEVEE_render_update_passes(struct RenderEngine *engine, struct Scene *scene, struct ViewLayer *view_layer);
+/** eevee_lookdev.c */
+void EEVEE_lookdev_cache_init(EEVEE_Data *vedata, DRWShadingGroup **grp, GPUShader *shader, DRWPass *pass, EEVEE_LightProbesInfo *pinfo);
+void EEVEE_lookdev_draw_background(EEVEE_Data *vedata);
+
/* Shadow Matrix */
static const float texcomat[4][4] = { /* From NDC to TexCo */
{0.5f, 0.0f, 0.0f, 0.0f},
diff --git a/source/blender/draw/engines/eevee/eevee_subsurface.c b/source/blender/draw/engines/eevee/eevee_subsurface.c
index 1a46e0b5c33..6ee3b9cc286 100644
--- a/source/blender/draw/engines/eevee/eevee_subsurface.c
+++ b/source/blender/draw/engines/eevee/eevee_subsurface.c
@@ -150,7 +150,7 @@ void EEVEE_subsurface_output_init(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Dat
const DRWContextState *draw_ctx = DRW_context_state_get();
const Scene *scene_eval = DEG_get_evaluated_scene(draw_ctx->depsgraph);
- if (scene_eval->flag & SCE_EEVEE_SSS_ENABLED) {
+ if (scene_eval->eevee.flag & SCE_EEVEE_SSS_ENABLED) {
DRW_texture_ensure_fullscreen_2D(&txl->sss_dir_accum, GPU_RGBA16F, 0);
DRW_texture_ensure_fullscreen_2D(&txl->sss_col_accum, GPU_RGBA16F, 0);
diff --git a/source/blender/draw/engines/eevee/shaders/ambient_occlusion_lib.glsl b/source/blender/draw/engines/eevee/shaders/ambient_occlusion_lib.glsl
index 55f66f5500a..9d27224b5c9 100644
--- a/source/blender/draw/engines/eevee/shaders/ambient_occlusion_lib.glsl
+++ b/source/blender/draw/engines/eevee/shaders/ambient_occlusion_lib.glsl
@@ -184,7 +184,8 @@ void integrate_slice(vec3 normal, vec2 t_phi, vec2 horizons, inout float visibil
bent_normal += vec3(sin(b_angle) * -t_phi, cos(b_angle) * 0.5);
}
-void gtao_deferred(vec3 normal, vec3 position, vec4 noise, float frag_depth, out float visibility, out vec3 bent_normal)
+void gtao_deferred(
+ vec3 normal, vec3 position, vec4 noise, float frag_depth, out float visibility, out vec3 bent_normal)
{
/* Fetch early, hide latency! */
vec4 horizons = texelFetch(horizonBuffer, ivec2(gl_FragCoord.xy), 0);
diff --git a/source/blender/draw/engines/eevee/shaders/bsdf_direct_lib.glsl b/source/blender/draw/engines/eevee/shaders/bsdf_direct_lib.glsl
index d5b54097638..aad71b3e48e 100644
--- a/source/blender/draw/engines/eevee/shaders/bsdf_direct_lib.glsl
+++ b/source/blender/draw/engines/eevee/shaders/bsdf_direct_lib.glsl
@@ -47,6 +47,16 @@ float direct_diffuse_rectangle(LightData ld, vec3 N, vec3 V, vec4 l_vector)
return ltc_evaluate_quad(corners, N);
}
+float direct_diffuse_ellipse(LightData ld, vec3 N, vec3 V, vec4 l_vector)
+{
+ vec3 points[3];
+ points[0] = l_vector.xyz + ld.l_right * -ld.l_sizex + ld.l_up * -ld.l_sizey;
+ points[1] = l_vector.xyz + ld.l_right * ld.l_sizex + ld.l_up * -ld.l_sizey;
+ points[2] = l_vector.xyz + ld.l_right * ld.l_sizex + ld.l_up * ld.l_sizey;
+
+ return ltc_evaluate_disk(N, V, mat3(1), points);
+}
+
float direct_diffuse_unit_disc(LightData ld, vec3 N, vec3 V)
{
float NL = dot(N, -ld.l_forward);
@@ -107,6 +117,26 @@ vec3 direct_ggx_sphere(LightData ld, vec3 N, vec3 V, vec4 l_vector, float roughn
return spec;
}
+vec3 direct_ggx_ellipse(LightData ld, vec3 N, vec3 V, vec4 l_vector, float roughness, vec3 f0)
+{
+ vec3 points[3];
+ points[0] = l_vector.xyz + ld.l_right * -ld.l_sizex + ld.l_up * -ld.l_sizey;
+ points[1] = l_vector.xyz + ld.l_right * ld.l_sizex + ld.l_up * -ld.l_sizey;
+ points[2] = l_vector.xyz + ld.l_right * ld.l_sizex + ld.l_up * ld.l_sizey;
+
+ vec2 uv = lut_coords(dot(N, V), sqrt(roughness));
+ vec3 brdf_lut = texture(utilTex, vec3(uv, 1.0)).rgb;
+ vec4 ltc_lut = texture(utilTex, vec3(uv, 0.0)).rgba;
+ mat3 ltc_mat = ltc_matrix(ltc_lut);
+
+ float bsdf = ltc_evaluate_disk(N, V, ltc_mat, points);
+ bsdf *= brdf_lut.b; /* Bsdf intensity */
+
+ vec3 spec = F_area(f0, brdf_lut.xy) * bsdf;
+
+ return spec;
+}
+
vec3 direct_ggx_rectangle(LightData ld, vec3 N, vec3 V, vec4 l_vector, float roughness, vec3 f0)
{
vec3 corners[4];
diff --git a/source/blender/draw/engines/eevee/shaders/default_frag.glsl b/source/blender/draw/engines/eevee/shaders/default_frag.glsl
index 6d941ae6ec3..fd1a10de548 100644
--- a/source/blender/draw/engines/eevee/shaders/default_frag.glsl
+++ b/source/blender/draw/engines/eevee/shaders/default_frag.glsl
@@ -15,5 +15,9 @@ Closure nodetree_exec(void)
Closure result = Closure(out_spec + out_diff * albedo, 1.0, vec4(ssr_spec, roughness), normal_encode(normalize(viewNormal), viewCameraVec), 0);
+#ifdef LOOKDEV
+ gl_FragDepth = 0.0;
+#endif
+
return result;
}
diff --git a/source/blender/draw/engines/eevee/shaders/default_world_frag.glsl b/source/blender/draw/engines/eevee/shaders/default_world_frag.glsl
index 90af87756f0..472d9c577b4 100644
--- a/source/blender/draw/engines/eevee/shaders/default_world_frag.glsl
+++ b/source/blender/draw/engines/eevee/shaders/default_world_frag.glsl
@@ -1,9 +1,57 @@
+#define M_PI 3.14159265358979323846
uniform float backgroundAlpha;
+uniform mat4 ProjectionMatrix;
+uniform mat4 ProjectionMatrixInverse;
+uniform mat4 ViewMatrixInverse;
+#ifdef LOOKDEV
+uniform mat3 StudioLightMatrix;
+uniform sampler2D image;
+in vec3 viewPosition;
+#else
uniform vec3 color;
+#endif
out vec4 FragColor;
+void background_transform_to_world(vec3 viewvec, out vec3 worldvec)
+{
+ vec4 v = (ProjectionMatrix[3][3] == 0.0) ? vec4(viewvec, 1.0) : vec4(0.0, 0.0, 1.0, 1.0);
+ vec4 co_homogenous = (ProjectionMatrixInverse * v);
+
+ vec4 co = vec4(co_homogenous.xyz / co_homogenous.w, 0.0);
+ worldvec = (ViewMatrixInverse * co).xyz;
+}
+
+float hypot(float x, float y)
+{
+ return sqrt(x * x + y * y);
+}
+
+void node_tex_environment_equirectangular(vec3 co, sampler2D ima, out vec4 color)
+{
+ vec3 nco = normalize(co);
+ float u = -atan(nco.y, nco.x) / (2.0 * M_PI) + 0.5;
+ float v = atan(nco.z, hypot(nco.x, nco.y)) / M_PI + 0.5;
+
+ /* Fix pole bleeding */
+ float half_width = 0.5 / float(textureSize(ima, 0).x);
+ v = clamp(v, half_width, 1.0 - half_width);
+
+ /* Fix u = 0 seam */
+ /* This is caused by texture filtering, since uv don't have smooth derivatives
+ * at u = 0 or 2PI, hardware filtering is using the smallest mipmap for certain
+ * texels. So we force the highest mipmap and don't do anisotropic filtering. */
+ color = textureLod(ima, vec2(u, v), 0.0);
+}
+
void main() {
- FragColor = vec4(color, backgroundAlpha);
+#ifdef LOOKDEV
+ vec3 worldvec;
+ vec4 color;
+ background_transform_to_world(viewPosition, worldvec);
+ node_tex_environment_equirectangular(StudioLightMatrix * worldvec, image, color);
+#endif
+
+ FragColor = vec4(clamp(color.rgb, vec3(0.0), vec3(1e10)), backgroundAlpha);
}
diff --git a/source/blender/draw/engines/eevee/shaders/lamps_lib.glsl b/source/blender/draw/engines/eevee/shaders/lamps_lib.glsl
index 198a05ccf97..0e6f976187a 100644
--- a/source/blender/draw/engines/eevee/shaders/lamps_lib.glsl
+++ b/source/blender/draw/engines/eevee/shaders/lamps_lib.glsl
@@ -15,11 +15,13 @@ layout(std140) uniform light_block {
};
/* type */
-#define POINT 0.0
-#define SUN 1.0
-#define SPOT 2.0
-#define HEMI 3.0
-#define AREA 4.0
+#define POINT 0.0
+#define SUN 1.0
+#define SPOT 2.0
+#define HEMI 3.0
+#define AREA_RECT 4.0
+/* Used to define the area lamp shape, doesn't directly correspond to a Blender lamp type. */
+#define AREA_ELLIPSE 100.0
#if defined(SHADOW_VSM)
#define ShadowSample vec2
@@ -174,7 +176,7 @@ float light_visibility(LightData ld, vec3 W,
vis *= spotmask;
vis *= step(0.0, -dot(l_vector.xyz, ld.l_forward));
}
- else if (ld.l_type == AREA) {
+ else if (ld.l_type == AREA_RECT || ld.l_type == AREA_ELLIPSE) {
vis *= step(0.0, -dot(l_vector.xyz, ld.l_forward));
}
@@ -253,9 +255,12 @@ float light_diffuse(LightData ld, vec3 N, vec3 V, vec4 l_vector)
if (ld.l_type == SUN) {
return direct_diffuse_unit_disc(ld, N, V);
}
- else if (ld.l_type == AREA) {
+ else if (ld.l_type == AREA_RECT) {
return direct_diffuse_rectangle(ld, N, V, l_vector);
}
+ else if (ld.l_type == AREA_ELLIPSE) {
+ return direct_diffuse_ellipse(ld, N, V, l_vector);
+ }
else {
return direct_diffuse_sphere(ld, N, l_vector);
}
@@ -275,9 +280,12 @@ vec3 light_specular(LightData ld, vec3 N, vec3 V, vec4 l_vector, float roughness
if (ld.l_type == SUN) {
return direct_ggx_unit_disc(ld, N, V, roughness, f0);
}
- else if (ld.l_type == AREA) {
+ else if (ld.l_type == AREA_RECT) {
return direct_ggx_rectangle(ld, N, V, l_vector, roughness, f0);
}
+ else if (ld.l_type == AREA_ELLIPSE) {
+ return direct_ggx_ellipse(ld, N, V, l_vector, roughness, f0);
+ }
else {
return direct_ggx_sphere(ld, N, V, l_vector, roughness, f0);
}
@@ -373,8 +381,11 @@ vec3 light_translucent(LightData ld, vec3 W, vec3 N, vec4 l_vector, float scale)
/* XXX : Removing Area Power. */
/* TODO : put this out of the shader. */
float falloff;
- if (ld.l_type == AREA) {
+ if (ld.l_type == AREA_RECT || ld.l_type == AREA_ELLIPSE) {
vis *= (ld.l_sizex * ld.l_sizey * 4.0 * M_PI) * (1.0 / 80.0);
+ if (ld.l_type == AREA_ELLIPSE) {
+ vis *= M_PI * 0.25;
+ }
vis *= 0.3 * 20.0 * max(0.0, dot(-ld.l_forward, l_vector.xyz / l_vector.w)); /* XXX ad hoc, empirical */
vis /= (l_vector.w * l_vector.w);
falloff = dot(N, l_vector.xyz / l_vector.w);
@@ -412,7 +423,7 @@ vec3 light_translucent(LightData ld, vec3 W, vec3 N, vec4 l_vector, float scale)
vis *= spotmask;
vis *= step(0.0, -dot(l_vector.xyz, ld.l_forward));
}
- else if (ld.l_type == AREA) {
+ else if (ld.l_type == AREA_RECT || ld.l_type == AREA_ELLIPSE) {
vis *= step(0.0, -dot(l_vector.xyz, ld.l_forward));
}
}
diff --git a/source/blender/draw/engines/eevee/shaders/lightprobe_lib.glsl b/source/blender/draw/engines/eevee/shaders/lightprobe_lib.glsl
index 6c1571d5306..0ffc0cc4b49 100644
--- a/source/blender/draw/engines/eevee/shaders/lightprobe_lib.glsl
+++ b/source/blender/draw/engines/eevee/shaders/lightprobe_lib.glsl
@@ -120,7 +120,8 @@ float probe_attenuation_planar(PlanarData pd, vec3 W, vec3 N, float roughness)
vec2 dist_to_clip;
dist_to_clip.x = dot(pd.pl_clip_pos_x, W);
dist_to_clip.y = dot(pd.pl_clip_pos_y, W);
- fac *= step(2.0, dot(step(pd.pl_clip_edges, dist_to_clip.xxyy), vec2(-1.0, 1.0).xyxy)); /* compare and add all tests */
+ /* compare and add all tests */
+ fac *= step(2.0, dot(step(pd.pl_clip_edges, dist_to_clip.xxyy), vec2(-1.0, 1.0).xyxy));
/* Decrease influence for high roughness */
fac *= saturate(1.0 - roughness * 10.0);
diff --git a/source/blender/draw/engines/eevee/shaders/raytrace_lib.glsl b/source/blender/draw/engines/eevee/shaders/raytrace_lib.glsl
index aa1dda6b3b5..d035a4329b1 100644
--- a/source/blender/draw/engines/eevee/shaders/raytrace_lib.glsl
+++ b/source/blender/draw/engines/eevee/shaders/raytrace_lib.glsl
@@ -61,7 +61,8 @@ float refine_isect(float prev_delta, float curr_delta)
return saturate(prev_delta / (prev_delta - curr_delta));
}
-void prepare_raycast(vec3 ray_origin, vec3 ray_dir, float thickness, out vec4 ss_step, out vec4 ss_ray, out float max_time)
+void prepare_raycast(
+ vec3 ray_origin, vec3 ray_dir, float thickness, out vec4 ss_step, out vec4 ss_ray, out float max_time)
{
/* Negate the ray direction if it goes towards the camera.
* This way we don't need to care if the projected point
diff --git a/source/blender/draw/engines/eevee/shaders/volumetric_lib.glsl b/source/blender/draw/engines/eevee/shaders/volumetric_lib.glsl
index 1a8167c2830..5f641c5d490 100644
--- a/source/blender/draw/engines/eevee/shaders/volumetric_lib.glsl
+++ b/source/blender/draw/engines/eevee/shaders/volumetric_lib.glsl
@@ -66,8 +66,11 @@ vec3 light_volume(LightData ld, vec4 l_vector)
/* XXX : Removing Area Power. */
/* TODO : put this out of the shader. */
/* See eevee_light_setup(). */
- if (ld.l_type == AREA) {
+ if (ld.l_type == AREA_RECT || ld.l_type == AREA_ELLIPSE) {
power = (ld.l_sizex * ld.l_sizey * 4.0 * M_PI) * (1.0 / 80.0);
+ if (ld.l_type == AREA_ELLIPSE) {
+ power *= M_PI * 0.25;
+ }
power *= 20.0 * max(0.0, dot(-ld.l_forward, l_vector.xyz / l_vector.w)); /* XXX ad hoc, empirical */
}
else if (ld.l_type == SUN) {
diff --git a/source/blender/draw/engines/workbench/shaders/workbench_checkerboard_depth_frag.glsl b/source/blender/draw/engines/workbench/shaders/workbench_checkerboard_depth_frag.glsl
index 19838161a73..4e44f6e1914 100644
--- a/source/blender/draw/engines/workbench/shaders/workbench_checkerboard_depth_frag.glsl
+++ b/source/blender/draw/engines/workbench/shaders/workbench_checkerboard_depth_frag.glsl
@@ -7,4 +7,4 @@ void main()
} else {
gl_FragDepth = 1.0;
}
-} \ No newline at end of file
+}
diff --git a/source/blender/draw/engines/workbench/shaders/workbench_common_lib.glsl b/source/blender/draw/engines/workbench/shaders/workbench_common_lib.glsl
index 2550f44271b..88b715f55a8 100644
--- a/source/blender/draw/engines/workbench/shaders/workbench_common_lib.glsl
+++ b/source/blender/draw/engines/workbench/shaders/workbench_common_lib.glsl
@@ -1,5 +1,5 @@
#define NO_OBJECT_ID uint(0)
-
+#define EPSILON 0.00001
/* 4x4 bayer matrix prepared for 8bit UNORM precision error. */
#define P(x) (((x + 0.5) * (1.0 / 16.0) - 0.5) * (1.0 / 255.0))
const vec4 dither_mat4x4[4] = vec4[4](
@@ -62,3 +62,10 @@ void fresnel(vec3 I, vec3 N, float ior, out float kr)
// As a consequence of the conservation of energy, transmittance is given by:
// kt = 1 - kr;
}
+
+vec4 calculate_transparent_accum(vec4 premultiplied) {
+ float a = min(1.0, premultiplied.a) * 8.0 + 0.01;
+ float b = -gl_FragCoord.z * 0.95 + 1.0;
+ float w = clamp(a * a * a * 1e8 * b * b * b, 1e-2, 3e2);
+ return premultiplied * w;
+}
diff --git a/source/blender/draw/engines/workbench/shaders/workbench_forward_composite_frag.glsl b/source/blender/draw/engines/workbench/shaders/workbench_forward_composite_frag.glsl
index 2d6f78082e3..12d6296655d 100644
--- a/source/blender/draw/engines/workbench/shaders/workbench_forward_composite_frag.glsl
+++ b/source/blender/draw/engines/workbench/shaders/workbench_forward_composite_frag.glsl
@@ -2,7 +2,9 @@ out vec4 fragColor;
uniform usampler2D objectId;
uniform sampler2D transparentAccum;
+#ifdef WORKBENCH_REVEALAGE_ENABLED
uniform sampler2D transparentRevealage;
+#endif
uniform vec2 invertedViewportSize;
layout(std140) uniform world_block {
@@ -15,7 +17,9 @@ void main()
vec2 uv_viewport = gl_FragCoord.xy * invertedViewportSize;
uint object_id = texelFetch(objectId, texel, 0).r;
vec4 transparent_accum = texelFetch(transparentAccum, texel, 0);
- float revealage = texelFetch(transparentRevealage, texel, 0).r;
+#ifdef WORKBENCH_REVEALAGE_ENABLED
+ float transparent_revealage = texelFetch(transparentRevealage, texel, 0).r;
+#endif
vec4 color;
#ifdef V3D_SHADING_OBJECT_OUTLINE
@@ -27,7 +31,11 @@ void main()
if (object_id == NO_OBJECT_ID) {
color = vec4(background_color(world_data, uv_viewport.y), 0.0);
} else {
- color = transparent_accum / transparent_accum.a;
+#ifdef WORKBENCH_REVEALAGE_ENABLED
+ color = vec4((transparent_accum.xyz / max(transparent_accum.a, EPSILON)) * (1.0 - transparent_revealage), 1.0);
+#else
+ color = vec4(transparent_accum.xyz / max(transparent_accum.a, EPSILON), 1.0);
+#endif
}
fragColor = vec4(mix(world_data.object_outline_color.rgb, color.xyz, outline), 1.0);
diff --git a/source/blender/draw/engines/workbench/shaders/workbench_forward_transparent_accum_frag.glsl b/source/blender/draw/engines/workbench/shaders/workbench_forward_transparent_accum_frag.glsl
index 6428ed44f6b..309ae063284 100644
--- a/source/blender/draw/engines/workbench/shaders/workbench_forward_transparent_accum_frag.glsl
+++ b/source/blender/draw/engines/workbench/shaders/workbench_forward_transparent_accum_frag.glsl
@@ -17,12 +17,7 @@ layout(std140) uniform world_block {
layout(location=0) out vec4 transparentAccum;
-vec4 calculate_transparent_accum(vec4 premultiplied) {
- float a = min(1.0, premultiplied.a) * 8.0 + 0.01;
- float b = -gl_FragCoord.z * 0.95 + 1.0;
- float w = clamp(a * a * a * 1e8 * b * b * b, 1e-2, 3e2);
- return vec4(premultiplied.rgb, premultiplied.a);
-}
+
void main()
{
vec4 diffuse_color;
@@ -47,7 +42,7 @@ void main()
vec3 shaded_color = diffuse_color.rgb;
#endif /* V3D_LIGHTING_STUDIO */
- float alpha = 0.1;
+ float alpha = 0.5 ;
vec4 premultiplied = vec4(shaded_color.rgb * alpha, alpha);
transparentAccum = calculate_transparent_accum(premultiplied);
}
diff --git a/source/blender/draw/engines/workbench/shaders/workbench_forward_transparent_revealage_frag.glsl b/source/blender/draw/engines/workbench/shaders/workbench_forward_transparent_revealage_frag.glsl
new file mode 100644
index 00000000000..da87fe8f542
--- /dev/null
+++ b/source/blender/draw/engines/workbench/shaders/workbench_forward_transparent_revealage_frag.glsl
@@ -0,0 +1,7 @@
+layout(location=0) out float transparentRevealage;
+
+void main()
+{
+ transparentRevealage = 0.5;
+}
+
diff --git a/source/blender/draw/engines/workbench/shaders/workbench_shadow_caps_geom.glsl b/source/blender/draw/engines/workbench/shaders/workbench_shadow_caps_geom.glsl
index 5d286bd1090..32b31718cf8 100644
--- a/source/blender/draw/engines/workbench/shaders/workbench_shadow_caps_geom.glsl
+++ b/source/blender/draw/engines/workbench/shaders/workbench_shadow_caps_geom.glsl
@@ -4,8 +4,6 @@
#define USE_INVOC_EXT
#endif
-#define DOUBLE_MANIFOLD
-
#ifdef DOUBLE_MANIFOLD
# ifdef USE_INVOC_EXT
# define invoc_ct 4
diff --git a/source/blender/draw/engines/workbench/shaders/workbench_shadow_geom.glsl b/source/blender/draw/engines/workbench/shaders/workbench_shadow_geom.glsl
index ff835326236..5a31aa34932 100644
--- a/source/blender/draw/engines/workbench/shaders/workbench_shadow_geom.glsl
+++ b/source/blender/draw/engines/workbench/shaders/workbench_shadow_geom.glsl
@@ -4,8 +4,6 @@
#define USE_INVOC_EXT
#endif
-#define DOUBLE_MANIFOLD
-
#ifdef DOUBLE_MANIFOLD
# ifdef USE_INVOC_EXT
# define invoc_ct 2
diff --git a/source/blender/draw/engines/workbench/workbench_data.c b/source/blender/draw/engines/workbench/workbench_data.c
index 9f8023b38aa..bbd8c57a5b9 100644
--- a/source/blender/draw/engines/workbench/workbench_data.c
+++ b/source/blender/draw/engines/workbench/workbench_data.c
@@ -11,7 +11,7 @@ void workbench_private_data_init(WORKBENCH_PrivateData *wpd)
if (v3d) {
wpd->shading = v3d->shading;
wpd->drawtype = v3d->drawtype;
- wpd->studio_light = BKE_studiolight_find(wpd->shading.studio_light);
+ wpd->studio_light = BKE_studiolight_find(wpd->shading.studio_light, 0);
}
else {
memset(&wpd->shading, 0, sizeof(wpd->shading));
diff --git a/source/blender/draw/engines/workbench/workbench_deferred.c b/source/blender/draw/engines/workbench/workbench_deferred.c
index 70de6f71ae8..6a96822984d 100644
--- a/source/blender/draw/engines/workbench/workbench_deferred.c
+++ b/source/blender/draw/engines/workbench/workbench_deferred.c
@@ -49,12 +49,19 @@
// #define DEBUG_SHADOW_VOLUME
+#ifdef DEBUG_SHADOW_VOLUME
+# include "draw_debug.h"
+#endif
+
static struct {
struct GPUShader *prepass_sh_cache[MAX_SHADERS];
struct GPUShader *composite_sh_cache[MAX_SHADERS];
struct GPUShader *shadow_fail_sh;
+ struct GPUShader *shadow_fail_manifold_sh;
struct GPUShader *shadow_pass_sh;
+ struct GPUShader *shadow_pass_manifold_sh;
struct GPUShader *shadow_caps_sh;
+ struct GPUShader *shadow_caps_manifold_sh;
struct GPUTexture *object_id_tx; /* ref only, not alloced */
struct GPUTexture *color_buffer_tx; /* ref only, not alloced */
@@ -65,7 +72,7 @@ static struct {
float light_direction_vs[3];
int next_object_id;
float normal_world_matrix[3][3];
-} e_data = {NULL};
+} e_data = {{NULL}};
/* Shaders */
extern char datatoc_workbench_prepass_vert_glsl[];
@@ -83,8 +90,6 @@ extern char datatoc_workbench_data_lib_glsl[];
extern char datatoc_workbench_object_outline_lib_glsl[];
extern char datatoc_workbench_world_light_lib_glsl[];
-
-
static char *workbench_build_composite_frag(WORKBENCH_PrivateData *wpd)
{
char *str = NULL;
@@ -123,15 +128,14 @@ static char *workbench_build_prepass_frag(void)
return str;
}
-
-
static void ensure_deferred_shaders(WORKBENCH_PrivateData *wpd, int index, int drawtype)
{
if (e_data.prepass_sh_cache[index] == NULL) {
char *defines = workbench_material_build_defines(wpd, drawtype);
char *composite_frag = workbench_build_composite_frag(wpd);
char *prepass_frag = workbench_build_prepass_frag();
- e_data.prepass_sh_cache[index] = DRW_shader_create(datatoc_workbench_prepass_vert_glsl, NULL, prepass_frag, defines);
+ e_data.prepass_sh_cache[index] = DRW_shader_create(
+ datatoc_workbench_prepass_vert_glsl, NULL, prepass_frag, defines);
if (drawtype == OB_SOLID) {
e_data.composite_sh_cache[index] = DRW_shader_create_fullscreen(composite_frag, defines);
}
@@ -161,6 +165,7 @@ static void workbench_init_object_data(ObjectEngineData *engine_data)
{
WORKBENCH_ObjectData *data = (WORKBENCH_ObjectData *)engine_data;
data->object_id = e_data.next_object_id++;
+ data->shadow_bbox_dirty = true;
}
void workbench_deferred_engine_init(WORKBENCH_Data *vedata)
@@ -174,26 +179,44 @@ void workbench_deferred_engine_init(WORKBENCH_Data *vedata)
memset(e_data.prepass_sh_cache, 0x00, sizeof(struct GPUShader *) * MAX_SHADERS);
memset(e_data.composite_sh_cache, 0x00, sizeof(struct GPUShader *) * MAX_SHADERS);
e_data.next_object_id = 1;
- #ifdef DEBUG_SHADOW_VOLUME
- const char *shadow_frag = datatoc_workbench_shadow_debug_frag_glsl;
- #else
- const char *shadow_frag = NULL;
- #endif
- e_data.shadow_pass_sh = DRW_shader_create(
- datatoc_workbench_shadow_vert_glsl,
- datatoc_workbench_shadow_geom_glsl,
- shadow_frag,
- "#define SHADOW_PASS\n");
- e_data.shadow_fail_sh = DRW_shader_create(
- datatoc_workbench_shadow_vert_glsl,
- datatoc_workbench_shadow_geom_glsl,
- shadow_frag,
- "#define SHADOW_FAIL\n");
- e_data.shadow_caps_sh = DRW_shader_create(
- datatoc_workbench_shadow_vert_glsl,
- datatoc_workbench_shadow_caps_geom_glsl,
- shadow_frag,
- NULL);
+#ifdef DEBUG_SHADOW_VOLUME
+ const char *shadow_frag = datatoc_workbench_shadow_debug_frag_glsl;
+#else
+ const char *shadow_frag = NULL;
+#endif
+ e_data.shadow_pass_sh = DRW_shader_create(
+ datatoc_workbench_shadow_vert_glsl,
+ datatoc_workbench_shadow_geom_glsl,
+ shadow_frag,
+ "#define SHADOW_PASS\n"
+ "#define DOUBLE_MANIFOLD\n");
+ e_data.shadow_pass_manifold_sh = DRW_shader_create(
+ datatoc_workbench_shadow_vert_glsl,
+ datatoc_workbench_shadow_geom_glsl,
+ shadow_frag,
+ "#define SHADOW_PASS\n");
+ e_data.shadow_fail_sh = DRW_shader_create(
+ datatoc_workbench_shadow_vert_glsl,
+ datatoc_workbench_shadow_geom_glsl,
+ shadow_frag,
+ "#define SHADOW_FAIL\n"
+ "#define DOUBLE_MANIFOLD\n");
+ e_data.shadow_fail_manifold_sh = DRW_shader_create(
+ datatoc_workbench_shadow_vert_glsl,
+ datatoc_workbench_shadow_geom_glsl,
+ shadow_frag,
+ "#define SHADOW_FAIL\n");
+ e_data.shadow_caps_sh = DRW_shader_create(
+ datatoc_workbench_shadow_vert_glsl,
+ datatoc_workbench_shadow_caps_geom_glsl,
+ shadow_frag,
+ "#define SHADOW_FAIL\n"
+ "#define DOUBLE_MANIFOLD\n");
+ e_data.shadow_caps_manifold_sh = DRW_shader_create(
+ datatoc_workbench_shadow_vert_glsl,
+ datatoc_workbench_shadow_caps_geom_glsl,
+ shadow_frag,
+ "#define SHADOW_FAIL\n");
}
if (!stl->g_data) {
@@ -208,12 +231,16 @@ void workbench_deferred_engine_init(WORKBENCH_Data *vedata)
const int size[2] = {(int)viewport_size[0], (int)viewport_size[1]};
e_data.object_id_tx = DRW_texture_pool_query_2D(size[0], size[1], GPU_R32UI, &draw_engine_workbench_solid);
e_data.color_buffer_tx = DRW_texture_pool_query_2D(size[0], size[1], GPU_RGBA8, &draw_engine_workbench_solid);
- e_data.composite_buffer_tx = DRW_texture_pool_query_2D(size[0], size[1], GPU_RGBA16F, &draw_engine_workbench_solid);
+ e_data.composite_buffer_tx = DRW_texture_pool_query_2D(
+ size[0], size[1], GPU_RGBA16F, &draw_engine_workbench_solid);
if (NORMAL_ENCODING_ENABLED()) {
- e_data.normal_buffer_tx = DRW_texture_pool_query_2D(size[0], size[1], GPU_RG16, &draw_engine_workbench_solid);
- } else {
- e_data.normal_buffer_tx = DRW_texture_pool_query_2D(size[0], size[1], GPU_RGBA32F, &draw_engine_workbench_solid);
+ e_data.normal_buffer_tx = DRW_texture_pool_query_2D(
+ size[0], size[1], GPU_RG16, &draw_engine_workbench_solid);
+ }
+ else {
+ e_data.normal_buffer_tx = DRW_texture_pool_query_2D(
+ size[0], size[1], GPU_RGBA32F, &draw_engine_workbench_solid);
}
GPU_framebuffer_ensure_config(&fbl->prepass_fb, {
@@ -242,8 +269,11 @@ void workbench_deferred_engine_free()
DRW_SHADER_FREE_SAFE(e_data.composite_sh_cache[index]);
}
DRW_SHADER_FREE_SAFE(e_data.shadow_pass_sh);
+ DRW_SHADER_FREE_SAFE(e_data.shadow_pass_manifold_sh);
DRW_SHADER_FREE_SAFE(e_data.shadow_fail_sh);
+ DRW_SHADER_FREE_SAFE(e_data.shadow_fail_manifold_sh);
DRW_SHADER_FREE_SAFE(e_data.shadow_caps_sh);
+ DRW_SHADER_FREE_SAFE(e_data.shadow_caps_manifold_sh);
}
static void workbench_composite_uniforms(WORKBENCH_PrivateData *wpd, DRWShadingGroup *grp)
@@ -292,7 +322,8 @@ void workbench_deferred_cache_init(WORKBENCH_Data *vedata)
e_data.display.shadow_shift = scene->display.shadow_shift;
if (SHADOW_ENABLED(wpd)) {
- psl->composite_pass = DRW_pass_create("Composite", DRW_STATE_WRITE_COLOR | DRW_STATE_STENCIL_EQUAL);
+ psl->composite_pass = DRW_pass_create(
+ "Composite", DRW_STATE_WRITE_COLOR | DRW_STATE_STENCIL_EQUAL);
grp = DRW_shgroup_create(wpd->composite_sh, psl->composite_pass);
workbench_composite_uniforms(wpd, grp);
DRW_shgroup_stencil_mask(grp, 0x00);
@@ -302,23 +333,36 @@ void workbench_deferred_cache_init(WORKBENCH_Data *vedata)
DRW_shgroup_uniform_float(grp, "shadowShift", &scene->display.shadow_shift, 1);
DRW_shgroup_call_add(grp, DRW_cache_fullscreen_quad_get(), NULL);
+ /* Stencil Shadow passes. */
#ifdef DEBUG_SHADOW_VOLUME
- psl->shadow_depth_pass_pass = DRW_pass_create("Shadow Debug Pass", DRW_STATE_DEPTH_LESS | DRW_STATE_WRITE_COLOR | DRW_STATE_ADDITIVE);
- grp = DRW_shgroup_create(e_data.shadow_pass_sh, psl->shadow_depth_pass_pass);
- psl->shadow_depth_fail_pass = DRW_pass_create("Shadow Debug Fail", DRW_STATE_DEPTH_GREATER_EQUAL | DRW_STATE_WRITE_COLOR | DRW_STATE_ADDITIVE);
- grp = DRW_shgroup_create(e_data.shadow_fail_sh, psl->shadow_depth_fail_pass);
- psl->shadow_depth_fail_caps_pass = DRW_pass_create("Shadow Depth Fail Caps", DRW_STATE_DEPTH_GREATER_EQUAL | DRW_STATE_WRITE_COLOR | DRW_STATE_ADDITIVE);
- grp = DRW_shgroup_create(e_data.shadow_caps_sh, psl->shadow_depth_fail_caps_pass);
+ DRWState depth_pass_state = DRW_STATE_DEPTH_LESS | DRW_STATE_WRITE_COLOR | DRW_STATE_ADDITIVE;
+ DRWState depth_fail_state = DRW_STATE_DEPTH_GREATER_EQUAL | DRW_STATE_WRITE_COLOR | DRW_STATE_ADDITIVE;
#else
- psl->shadow_depth_pass_pass = DRW_pass_create("Shadow Depth Pass", DRW_STATE_DEPTH_LESS | DRW_STATE_WRITE_STENCIL_SHADOW_PASS);
+ DRWState depth_pass_state = DRW_STATE_DEPTH_LESS | DRW_STATE_WRITE_STENCIL_SHADOW_PASS;
+ DRWState depth_fail_state = DRW_STATE_DEPTH_LESS | DRW_STATE_WRITE_STENCIL_SHADOW_FAIL;
+#endif
+ psl->shadow_depth_pass_pass = DRW_pass_create("Shadow Pass", depth_pass_state);
+ psl->shadow_depth_pass_mani_pass = DRW_pass_create("Shadow Pass Mani", depth_pass_state);
+ psl->shadow_depth_fail_pass = DRW_pass_create("Shadow Fail", depth_fail_state);
+ psl->shadow_depth_fail_mani_pass = DRW_pass_create("Shadow Fail Mani", depth_fail_state);
+ psl->shadow_depth_fail_caps_pass = DRW_pass_create("Shadow Fail Caps", depth_fail_state);
+ psl->shadow_depth_fail_caps_mani_pass = DRW_pass_create("Shadow Fail Caps Mani", depth_fail_state);
+
+#ifndef DEBUG_SHADOW_VOLUME
+ grp = DRW_shgroup_create(e_data.shadow_caps_sh, psl->shadow_depth_fail_caps_pass);
+ DRW_shgroup_stencil_mask(grp, 0xFF);
grp = DRW_shgroup_create(e_data.shadow_pass_sh, psl->shadow_depth_pass_pass);
DRW_shgroup_stencil_mask(grp, 0xFF);
- psl->shadow_depth_fail_pass = DRW_pass_create("Shadow Depth Fail", DRW_STATE_DEPTH_LESS | DRW_STATE_WRITE_STENCIL_SHADOW_FAIL);
+ grp = DRW_shgroup_create(e_data.shadow_pass_manifold_sh, psl->shadow_depth_pass_mani_pass);
+ DRW_shgroup_stencil_mask(grp, 0xFF);
grp = DRW_shgroup_create(e_data.shadow_fail_sh, psl->shadow_depth_fail_pass);
DRW_shgroup_stencil_mask(grp, 0xFF);
- psl->shadow_depth_fail_caps_pass = DRW_pass_create("Shadow Depth Fail Caps", DRW_STATE_DEPTH_LESS | DRW_STATE_WRITE_STENCIL_SHADOW_FAIL);
+ grp = DRW_shgroup_create(e_data.shadow_fail_manifold_sh, psl->shadow_depth_fail_mani_pass);
+ DRW_shgroup_stencil_mask(grp, 0xFF);
grp = DRW_shgroup_create(e_data.shadow_caps_sh, psl->shadow_depth_fail_caps_pass);
DRW_shgroup_stencil_mask(grp, 0xFF);
+ grp = DRW_shgroup_create(e_data.shadow_caps_manifold_sh, psl->shadow_depth_fail_caps_mani_pass);
+ DRW_shgroup_stencil_mask(grp, 0xFF);
psl->composite_shadow_pass = DRW_pass_create("Composite Shadow", DRW_STATE_WRITE_COLOR | DRW_STATE_STENCIL_NEQUAL);
grp = DRW_shgroup_create(wpd->composite_sh, psl->composite_shadow_pass);
@@ -330,16 +374,21 @@ void workbench_deferred_cache_init(WORKBENCH_Data *vedata)
DRW_shgroup_uniform_float(grp, "shadowShift", &scene->display.shadow_shift, 1);
DRW_shgroup_call_add(grp, DRW_cache_fullscreen_quad_get(), NULL);
#endif
+
+ studiolight_update_light(wpd, e_data.display.light_direction);
}
else {
- psl->composite_pass = DRW_pass_create("Composite", DRW_STATE_WRITE_COLOR);
+ psl->composite_pass = DRW_pass_create(
+ "Composite", DRW_STATE_WRITE_COLOR);
grp = DRW_shgroup_create(wpd->composite_sh, psl->composite_pass);
workbench_composite_uniforms(wpd, grp);
DRW_shgroup_call_add(grp, DRW_cache_fullscreen_quad_get(), NULL);
}
}
}
-static WORKBENCH_MaterialData *get_or_create_material_data(WORKBENCH_Data *vedata, Object *ob, Material *mat, Image *ima, int drawtype)
+
+static WORKBENCH_MaterialData *get_or_create_material_data(
+ WORKBENCH_Data *vedata, Object *ob, Material *mat, Image *ima, int drawtype)
{
WORKBENCH_StorageList *stl = vedata->stl;
WORKBENCH_PassList *psl = vedata->psl;
@@ -359,7 +408,8 @@ static WORKBENCH_MaterialData *get_or_create_material_data(WORKBENCH_Data *vedat
material = BLI_ghash_lookup(wpd->material_hash, SET_UINT_IN_POINTER(hash));
if (material == NULL) {
material = MEM_mallocN(sizeof(WORKBENCH_MaterialData), __func__);
- material->shgrp = DRW_shgroup_create(drawtype == OB_SOLID ? wpd->prepass_solid_sh : wpd->prepass_texture_sh, psl->prepass_pass);
+ material->shgrp = DRW_shgroup_create(
+ drawtype == OB_SOLID ? wpd->prepass_solid_sh : wpd->prepass_texture_sh, psl->prepass_pass);
DRW_shgroup_stencil_mask(material->shgrp, 0xFF);
material->object_id = engine_object_data->object_id;
copy_v4_v4(material->color, material_template.color);
@@ -473,7 +523,8 @@ void workbench_deferred_solid_cache_populate(WORKBENCH_Data *vedata, Object *ob)
gpumat_array[i] = NULL;
}
- struct Gwn_Batch **mat_geom = DRW_cache_object_surface_material_get(ob, gpumat_array, materials_len, NULL, NULL, NULL);
+ struct Gwn_Batch **mat_geom = DRW_cache_object_surface_material_get(
+ ob, gpumat_array, materials_len, NULL, NULL, NULL);
if (mat_geom) {
for (int i = 0; i < materials_len; ++i) {
Material *mat = give_current_material(ob, i + 1);
@@ -485,7 +536,8 @@ void workbench_deferred_solid_cache_populate(WORKBENCH_Data *vedata, Object *ob)
}
if (SHADOW_ENABLED(wpd) && (ob->display.flag & OB_SHOW_SHADOW) > 0) {
- struct Gwn_Batch *geom_shadow = DRW_cache_object_edge_detection_get(ob);
+ bool is_manifold;
+ struct Gwn_Batch *geom_shadow = DRW_cache_object_edge_detection_get(ob, &is_manifold);
if (geom_shadow) {
if (is_sculpt_mode) {
/* Currently unsupported in sculpt mode. We could revert to the slow
@@ -497,26 +549,60 @@ void workbench_deferred_solid_cache_populate(WORKBENCH_Data *vedata, Object *ob)
WORKBENCH_ObjectData *engine_object_data = (WORKBENCH_ObjectData *)DRW_object_engine_data_ensure(
ob, &draw_engine_workbench_solid, sizeof(WORKBENCH_ObjectData), &workbench_init_object_data, NULL);
- invert_m4_m4(ob->imat, ob->obmat);
- mul_v3_mat3_m4v3(engine_object_data->shadow_dir, ob->imat, e_data.display.light_direction);
+ if (studiolight_object_cast_visible_shadow(wpd, ob, engine_object_data)) {
- DRWShadingGroup *grp;
- if (true) {
- grp = DRW_shgroup_create(e_data.shadow_pass_sh, psl->shadow_depth_pass_pass);
- DRW_shgroup_uniform_vec3(grp, "lightDirection", engine_object_data->shadow_dir, 1);
- DRW_shgroup_call_object_add(grp, geom_shadow, ob);
- }
- else {
- struct Gwn_Batch *geom_caps = DRW_cache_object_surface_get(ob);
- if (geom_caps) {
- grp = DRW_shgroup_create(e_data.shadow_caps_sh, psl->shadow_depth_fail_caps_pass);
- DRW_shgroup_uniform_vec3(grp, "lightDirection", engine_object_data->shadow_dir, 1);
- DRW_shgroup_call_object_add(grp, geom_caps, ob);
+ invert_m4_m4(ob->imat, ob->obmat);
+ mul_v3_mat3_m4v3(engine_object_data->shadow_dir, ob->imat, e_data.display.light_direction);
+
+ DRWShadingGroup *grp;
+ bool use_shadow_pass_technique = !studiolight_camera_in_object_shadow(wpd, ob, engine_object_data);
+
+ /* Unless we expose a parameter to the user, it's better to use the depth pass technique if the object is
+ * non manifold. Exposing a switch to the user to force depth fail in this case can be beneficial for
+ * planes and non-closed terrains. */
+ if (!is_manifold) {
+ use_shadow_pass_technique = true;
}
- grp = DRW_shgroup_create(e_data.shadow_fail_sh, psl->shadow_depth_fail_pass);
- DRW_shgroup_uniform_vec3(grp, "lightDirection", engine_object_data->shadow_dir, 1);
- DRW_shgroup_call_object_add(grp, geom_shadow, ob);
+ if (use_shadow_pass_technique) {
+ if (is_manifold) {
+ grp = DRW_shgroup_create(e_data.shadow_pass_manifold_sh, psl->shadow_depth_pass_mani_pass);
+ }
+ else {
+ grp = DRW_shgroup_create(e_data.shadow_pass_sh, psl->shadow_depth_pass_pass);
+ }
+ DRW_shgroup_uniform_vec3(grp, "lightDirection", engine_object_data->shadow_dir, 1);
+ DRW_shgroup_call_add(grp, geom_shadow, ob->obmat);
+#ifdef DEBUG_SHADOW_VOLUME
+ DRW_debug_bbox(&engine_object_data->shadow_bbox, (float[4]){1.0f, 0.0f, 0.0f, 1.0f});
+#endif
+ }
+ else {
+ /* TODO(fclem): only use caps if they are in the view frustum. */
+ const bool need_caps = true;
+ if (need_caps) {
+ if (is_manifold) {
+ grp = DRW_shgroup_create(e_data.shadow_caps_manifold_sh, psl->shadow_depth_fail_caps_mani_pass);
+ }
+ else {
+ grp = DRW_shgroup_create(e_data.shadow_caps_sh, psl->shadow_depth_fail_caps_pass);
+ }
+ DRW_shgroup_uniform_vec3(grp, "lightDirection", engine_object_data->shadow_dir, 1);
+ DRW_shgroup_call_add(grp, DRW_cache_object_surface_get(ob), ob->obmat);
+ }
+
+ if (is_manifold) {
+ grp = DRW_shgroup_create(e_data.shadow_fail_manifold_sh, psl->shadow_depth_fail_mani_pass);
+ }
+ else {
+ grp = DRW_shgroup_create(e_data.shadow_fail_sh, psl->shadow_depth_fail_pass);
+ }
+ DRW_shgroup_uniform_vec3(grp, "lightDirection", engine_object_data->shadow_dir, 1);
+ DRW_shgroup_call_add(grp, geom_shadow, ob->obmat);
+#ifdef DEBUG_SHADOW_VOLUME
+ DRW_debug_bbox(&engine_object_data->shadow_bbox, (float[4]){0.0f, 1.0f, 0.0f, 1.0f});
+#endif
+ }
}
}
}
@@ -560,14 +646,16 @@ void workbench_deferred_draw_scene(WORKBENCH_Data *vedata)
#ifdef DEBUG_SHADOW_VOLUME
GPU_framebuffer_bind(fbl->composite_fb);
DRW_draw_pass(psl->composite_pass);
- DRW_draw_pass(psl->shadow_depth_pass_pass);
- DRW_draw_pass(psl->shadow_depth_fail_pass);
- DRW_draw_pass(psl->shadow_depth_fail_caps_pass);
#else
GPU_framebuffer_bind(dfbl->depth_only_fb);
+#endif
DRW_draw_pass(psl->shadow_depth_pass_pass);
+ DRW_draw_pass(psl->shadow_depth_pass_mani_pass);
DRW_draw_pass(psl->shadow_depth_fail_pass);
+ DRW_draw_pass(psl->shadow_depth_fail_mani_pass);
DRW_draw_pass(psl->shadow_depth_fail_caps_pass);
+ DRW_draw_pass(psl->shadow_depth_fail_caps_mani_pass);
+#ifndef DEBUG_SHADOW_VOLUME
GPU_framebuffer_bind(fbl->composite_fb);
DRW_draw_pass(psl->composite_pass);
DRW_draw_pass(psl->composite_shadow_pass);
diff --git a/source/blender/draw/engines/workbench/workbench_forward.c b/source/blender/draw/engines/workbench/workbench_forward.c
index 823ca904415..d2c262bc4ac 100644
--- a/source/blender/draw/engines/workbench/workbench_forward.c
+++ b/source/blender/draw/engines/workbench/workbench_forward.c
@@ -50,21 +50,28 @@
static struct {
struct GPUShader *composite_sh_cache[MAX_SHADERS];
struct GPUShader *transparent_accum_sh_cache[MAX_SHADERS];
+ struct GPUShader *transparent_revealage_sh;
struct GPUShader *object_outline_sh;
struct GPUShader *depth_sh;
struct GPUShader *checker_depth_sh;
struct GPUTexture *object_id_tx; /* ref only, not alloced */
struct GPUTexture *transparent_accum_tx; /* ref only, not alloced */
+#ifdef WORKBENCH_REVEALAGE_ENABLED
+ struct GPUTexture *transparent_revealage_tx; /* ref only, not alloced */
+#endif
struct GPUTexture *composite_buffer_tx; /* ref only, not alloced */
int next_object_id;
float normal_world_matrix[3][3];
-} e_data = {NULL};
+} e_data = {{NULL}};
/* Shaders */
extern char datatoc_workbench_forward_composite_frag_glsl[];
extern char datatoc_workbench_forward_depth_frag_glsl[];
extern char datatoc_workbench_forward_transparent_accum_frag_glsl[];
+#ifdef WORKBENCH_REVEALAGE_ENABLED
+extern char datatoc_workbench_forward_transparent_revealage_frag_glsl[];
+#endif
extern char datatoc_workbench_data_lib_glsl[];
extern char datatoc_workbench_background_lib_glsl[];
extern char datatoc_workbench_checkerboard_depth_frag_glsl[];
@@ -104,6 +111,22 @@ static char *workbench_build_forward_transparent_accum_frag(void)
return str;
}
+#ifdef WORKBENCH_REVEALAGE_ENABLED
+static char *workbench_build_forward_transparent_revealage_frag(void)
+{
+ char *str = NULL;
+
+ DynStr *ds = BLI_dynstr_new();
+
+ BLI_dynstr_append(ds, datatoc_workbench_common_lib_glsl);
+ BLI_dynstr_append(ds, datatoc_workbench_forward_transparent_revealage_frag_glsl);
+
+ str = BLI_dynstr_get_cstring(ds);
+ BLI_dynstr_free(ds);
+ return str;
+}
+#endif
+
static char *workbench_build_forward_composite_frag(void)
{
char *str = NULL;
@@ -127,7 +150,8 @@ static void workbench_init_object_data(ObjectEngineData *engine_data)
data->object_id = e_data.next_object_id++;
}
-static WORKBENCH_MaterialData *get_or_create_material_data(WORKBENCH_Data *vedata, Object *ob, Material *mat, Image *ima, int drawtype)
+static WORKBENCH_MaterialData *get_or_create_material_data(
+ WORKBENCH_Data *vedata, Object *ob, Material *mat, Image *ima, int drawtype)
{
WORKBENCH_StorageList *stl = vedata->stl;
WORKBENCH_PassList *psl = vedata->psl;
@@ -150,7 +174,9 @@ static WORKBENCH_MaterialData *get_or_create_material_data(WORKBENCH_Data *vedat
material = MEM_mallocN(sizeof(WORKBENCH_MaterialData), __func__);
/* transparent accum */
- grp = DRW_shgroup_create(drawtype == OB_SOLID ? wpd->transparent_accum_sh : wpd->transparent_accum_texture_sh, psl->transparent_accum_pass);
+ grp = DRW_shgroup_create(
+ drawtype == OB_SOLID ? wpd->transparent_accum_sh : wpd->transparent_accum_texture_sh,
+ psl->transparent_accum_pass);
DRW_shgroup_uniform_block(grp, "world_block", wpd->world_ubo);
workbench_material_set_normal_world_matrix(grp, wpd, e_data.normal_world_matrix);
copy_v4_v4(material->color, material_template.color);
@@ -190,7 +216,8 @@ static void ensure_forward_shaders(WORKBENCH_PrivateData *wpd, int index, int dr
if (e_data.transparent_accum_sh_cache[index] == NULL) {
char *defines = workbench_material_build_defines(wpd, drawtype);
char *transparent_accum_frag = workbench_build_forward_transparent_accum_frag();
- e_data.transparent_accum_sh_cache[index] = DRW_shader_create(datatoc_workbench_prepass_vert_glsl, NULL, transparent_accum_frag, defines);
+ e_data.transparent_accum_sh_cache[index] = DRW_shader_create(
+ datatoc_workbench_prepass_vert_glsl, NULL, transparent_accum_frag, defines);
MEM_freeN(transparent_accum_frag);
MEM_freeN(defines);
@@ -231,12 +258,21 @@ void workbench_forward_engine_init(WORKBENCH_Data *vedata)
memset(e_data.composite_sh_cache, 0x00, sizeof(struct GPUShader *) * MAX_SHADERS);
memset(e_data.transparent_accum_sh_cache, 0x00, sizeof(struct GPUShader *) * MAX_SHADERS);
- /* XXX: forward depth does not use any defines ATM. */
char *defines = workbench_material_build_defines(wpd, OB_SOLID);
char *forward_depth_frag = workbench_build_forward_depth_frag();
- e_data.object_outline_sh = DRW_shader_create(datatoc_workbench_prepass_vert_glsl, NULL, forward_depth_frag, defines);
+ e_data.object_outline_sh = DRW_shader_create(
+ datatoc_workbench_prepass_vert_glsl, NULL, forward_depth_frag, defines);
+
+#ifdef WORKBENCH_REVEALAGE_ENABLED
+ char *forward_transparent_revealage_frag = workbench_build_forward_transparent_revealage_frag();
+ e_data.transparent_revealage_sh = DRW_shader_create(
+ datatoc_workbench_prepass_vert_glsl, NULL, forward_transparent_revealage_frag, defines);
+ MEM_freeN(forward_transparent_revealage_frag);
+#endif
+
e_data.depth_sh = DRW_shader_create_3D_depth_only();
- e_data.checker_depth_sh = DRW_shader_create_fullscreen(datatoc_workbench_checkerboard_depth_frag_glsl, NULL);
+ e_data.checker_depth_sh = DRW_shader_create_fullscreen(
+ datatoc_workbench_checkerboard_depth_frag_glsl, NULL);
MEM_freeN(forward_depth_frag);
MEM_freeN(defines);
}
@@ -245,9 +281,16 @@ void workbench_forward_engine_init(WORKBENCH_Data *vedata)
const float *viewport_size = DRW_viewport_size_get();
const int size[2] = {(int)viewport_size[0], (int)viewport_size[1]};
- e_data.object_id_tx = DRW_texture_pool_query_2D(size[0], size[1], GPU_R32UI, &draw_engine_workbench_transparent);
- e_data.transparent_accum_tx = DRW_texture_pool_query_2D(size[0], size[1], GPU_RGBA16F, &draw_engine_workbench_transparent);
- e_data.composite_buffer_tx = DRW_texture_pool_query_2D(size[0], size[1], GPU_RGBA16F, &draw_engine_workbench_transparent);
+ e_data.object_id_tx = DRW_texture_pool_query_2D(
+ size[0], size[1], GPU_R32UI, &draw_engine_workbench_transparent);
+ e_data.transparent_accum_tx = DRW_texture_pool_query_2D(
+ size[0], size[1], GPU_RGBA16F, &draw_engine_workbench_transparent);
+#ifdef WORKBENCH_REVEALAGE_ENABLED
+ e_data.transparent_revealage_tx = DRW_texture_pool_query_2D(
+ size[0], size[1], GPU_R16F, &draw_engine_workbench_transparent);
+#endif
+ e_data.composite_buffer_tx = DRW_texture_pool_query_2D(
+ size[0], size[1], GPU_RGBA16F, &draw_engine_workbench_transparent);
GPU_framebuffer_ensure_config(&fbl->object_outline_fb, {
GPU_ATTACHMENT_TEXTURE(dtxl->depth),
GPU_ATTACHMENT_TEXTURE(e_data.object_id_tx),
@@ -256,6 +299,14 @@ void workbench_forward_engine_init(WORKBENCH_Data *vedata)
GPU_ATTACHMENT_NONE,
GPU_ATTACHMENT_TEXTURE(e_data.transparent_accum_tx),
});
+
+#ifdef WORKBENCH_REVEALAGE_ENABLED
+ GPU_framebuffer_ensure_config(&fbl->transparent_revealage_fb, {
+ GPU_ATTACHMENT_NONE,
+ GPU_ATTACHMENT_TEXTURE(e_data.transparent_revealage_tx),
+ });
+#endif
+
GPU_framebuffer_ensure_config(&fbl->composite_fb, {
GPU_ATTACHMENT_NONE,
GPU_ATTACHMENT_TEXTURE(e_data.composite_buffer_tx),
@@ -264,6 +315,12 @@ void workbench_forward_engine_init(WORKBENCH_Data *vedata)
DRW_stats_group_start("Clear Buffers");
GPU_framebuffer_bind(fbl->transparent_accum_fb);
GPU_framebuffer_clear_color(fbl->transparent_accum_fb, clear_color);
+
+#ifdef WORKBENCH_REVEALAGE_ENABLED
+ const float clear_color1[4] = {1.0f, 1.0f, 1.0f, 1.0f};
+ GPU_framebuffer_bind(fbl->transparent_revealage_fb);
+ GPU_framebuffer_clear_color(fbl->transparent_revealage_fb, clear_color1);
+#endif
GPU_framebuffer_bind(fbl->object_outline_fb);
GPU_framebuffer_clear_color_depth(fbl->object_outline_fb, clear_color, 1.0f);
DRW_stats_group_end();
@@ -273,6 +330,17 @@ void workbench_forward_engine_init(WORKBENCH_Data *vedata)
int state = DRW_STATE_WRITE_COLOR | DRW_STATE_ADDITIVE_FULL;
psl->transparent_accum_pass = DRW_pass_create("Transparent Accum", state);
}
+
+#ifdef WORKBENCH_REVEALAGE_ENABLED
+ /* Treansparecy Revealage */
+ {
+ int state = DRW_STATE_WRITE_COLOR | DRW_STATE_TRANSPARENT_REVEALAGE;
+ psl->transparent_revealage_pass = DRW_pass_create("Transparent Revealage", state);
+ grp = DRW_shgroup_create(e_data.transparent_revealage_sh, psl->transparent_revealage_pass);
+ wpd->transparent_revealage_shgrp = grp;
+ }
+#endif
+
/* Depth */
{
int state = DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS;
@@ -286,6 +354,9 @@ void workbench_forward_engine_init(WORKBENCH_Data *vedata)
grp = DRW_shgroup_create(wpd->composite_sh, psl->composite_pass);
DRW_shgroup_uniform_texture_ref(grp, "objectId", &e_data.object_id_tx);
DRW_shgroup_uniform_texture_ref(grp, "transparentAccum", &e_data.transparent_accum_tx);
+#ifdef WORKBENCH_REVEALAGE_ENABLED
+ DRW_shgroup_uniform_texture_ref(grp, "transparentRevealage", &e_data.transparent_revealage_tx);
+#endif
DRW_shgroup_uniform_block(grp, "world_block", wpd->world_ubo);
DRW_shgroup_uniform_vec2(grp, "invertedViewportSize", DRW_viewport_invert_size_get(), 1);
DRW_shgroup_call_add(grp, DRW_cache_fullscreen_quad_get(), NULL);
@@ -305,6 +376,9 @@ void workbench_forward_engine_free()
DRW_SHADER_FREE_SAFE(e_data.composite_sh_cache[index]);
DRW_SHADER_FREE_SAFE(e_data.transparent_accum_sh_cache[index]);
}
+#ifdef WORKBENCH_REVEALAGE_ENABLED
+ DRW_SHADER_FREE_SAFE(e_data.transparent_revealage_sh);
+#endif
DRW_SHADER_FREE_SAFE(e_data.object_outline_sh);
DRW_SHADER_FREE_SAFE(e_data.checker_depth_sh);
}
@@ -315,6 +389,10 @@ void workbench_forward_cache_init(WORKBENCH_Data *UNUSED(vedata))
static void workbench_forward_cache_populate_particles(WORKBENCH_Data *vedata, Object *ob)
{
+#ifdef WORKBENCH_REVEALAGE_ENABLED
+ WORKBENCH_StorageList *stl = vedata->stl;
+ WORKBENCH_PrivateData *wpd = stl->g_data;
+#endif
const DRWContextState *draw_ctx = DRW_context_state_get();
if (ob == draw_ctx->object_edit) {
return;
@@ -335,6 +413,9 @@ static void workbench_forward_cache_populate_particles(WORKBENCH_Data *vedata, O
if (draw_as == PART_DRAW_PATH) {
struct Gwn_Batch *geom = DRW_cache_particles_get_hair(ob, psys, NULL);
WORKBENCH_MaterialData *material = get_or_create_material_data(vedata, ob, NULL, NULL, OB_SOLID);
+#ifdef WORKBENCH_REVEALAGE_ENABLED
+ DRW_shgroup_call_add(wpd->transparent_revealage_shgrp, geom, mat);
+#endif
DRW_shgroup_call_add(material->shgrp_object_outline, geom, mat);
DRW_shgroup_call_add(material->shgrp, geom, mat);
}
@@ -376,6 +457,9 @@ void workbench_forward_cache_populate(WORKBENCH_Data *vedata, Object *ob)
mat_drawtype = OB_TEXTURE;
}
material = get_or_create_material_data(vedata, ob, mat, image, mat_drawtype);
+#ifdef WORKBENCH_REVEALAGE_ENABLED
+ DRW_shgroup_call_object_add(wpd->transparent_revealage_shgrp, geom_array[i], ob);
+#endif
DRW_shgroup_call_object_add(material->shgrp_object_outline, geom_array[i], ob);
DRW_shgroup_call_object_add(material->shgrp, geom_array[i], ob);
}
@@ -391,10 +475,16 @@ void workbench_forward_cache_populate(WORKBENCH_Data *vedata, Object *ob)
struct Gwn_Batch *geom = DRW_cache_object_surface_get(ob);
if (geom) {
if (is_sculpt_mode) {
+#ifdef WORKBENCH_REVEALAGE_ENABLED
+ DRW_shgroup_call_sculpt_add(wpd->transparent_revealage_shgrp, ob, ob->obmat);
+#endif
DRW_shgroup_call_sculpt_add(material->shgrp_object_outline, ob, ob->obmat);
DRW_shgroup_call_sculpt_add(material->shgrp, ob, ob->obmat);
}
else {
+#ifdef WORKBENCH_REVEALAGE_ENABLED
+ DRW_shgroup_call_object_add(wpd->transparent_revealage_shgrp, geom, ob);
+#endif
DRW_shgroup_call_object_add(material->shgrp_object_outline, geom, ob);
DRW_shgroup_call_object_add(material->shgrp, geom, ob);
}
@@ -407,11 +497,15 @@ void workbench_forward_cache_populate(WORKBENCH_Data *vedata, Object *ob)
gpumat_array[i] = NULL;
}
- struct Gwn_Batch **mat_geom = DRW_cache_object_surface_material_get(ob, gpumat_array, materials_len, NULL, NULL, NULL);
+ struct Gwn_Batch **mat_geom = DRW_cache_object_surface_material_get(
+ ob, gpumat_array, materials_len, NULL, NULL, NULL);
if (mat_geom) {
for (int i = 0; i < materials_len; ++i) {
Material *mat = give_current_material(ob, i + 1);
material = get_or_create_material_data(vedata, ob, mat, NULL, OB_SOLID);
+#ifdef WORKBENCH_REVEALAGE_ENABLED
+ DRW_shgroup_call_object_add(wpd->transparent_revealage_shgrp, mat_geom[i], ob);
+#endif
DRW_shgroup_call_object_add(material->shgrp_object_outline, mat_geom[i], ob);
DRW_shgroup_call_object_add(material->shgrp, mat_geom[i], ob);
}
@@ -450,7 +544,10 @@ void workbench_forward_draw_scene(WORKBENCH_Data *vedata)
/* Shade */
GPU_framebuffer_bind(fbl->transparent_accum_fb);
DRW_draw_pass(psl->transparent_accum_pass);
-
+#ifdef WORKBENCH_REVEALAGE_ENABLED
+ GPU_framebuffer_bind(fbl->transparent_revealage_fb);
+ DRW_draw_pass(psl->transparent_revealage_pass);
+#endif
/* Composite */
GPU_framebuffer_bind(fbl->composite_fb);
DRW_draw_pass(psl->composite_pass);
diff --git a/source/blender/draw/engines/workbench/workbench_materials.c b/source/blender/draw/engines/workbench/workbench_materials.c
index 9b364d8ff09..6028d3816d4 100644
--- a/source/blender/draw/engines/workbench/workbench_materials.c
+++ b/source/blender/draw/engines/workbench/workbench_materials.c
@@ -77,6 +77,10 @@ char *workbench_material_build_defines(WORKBENCH_PrivateData *wpd, int drawtype)
BLI_dynstr_appendf(ds, "#define WORKBENCH_ENCODE_NORMALS\n");
}
+#ifdef WORKBENCH_REVEALAGE_ENABLED
+ BLI_dynstr_appendf(ds, "#define WORKBENCH_REVEALAGE_ENABLED\n");
+#endif
+
str = BLI_dynstr_get_cstring(ds);
BLI_dynstr_free(ds);
return str;
@@ -117,7 +121,8 @@ int workbench_material_get_shader_index(WORKBENCH_PrivateData *wpd, int drawtype
return index;
}
-void workbench_material_set_normal_world_matrix(DRWShadingGroup *grp, WORKBENCH_PrivateData *wpd, float persistent_matrix[3][3])
+void workbench_material_set_normal_world_matrix(
+ DRWShadingGroup *grp, WORKBENCH_PrivateData *wpd, float persistent_matrix[3][3])
{
if (STUDIOLIGHT_ORIENTATION_WORLD_ENABLED(wpd)) {
float view_matrix_inverse[4][4];
diff --git a/source/blender/draw/engines/workbench/workbench_private.h b/source/blender/draw/engines/workbench/workbench_private.h
index 087ed5100d9..bffac99c6d7 100644
--- a/source/blender/draw/engines/workbench/workbench_private.h
+++ b/source/blender/draw/engines/workbench/workbench_private.h
@@ -44,6 +44,7 @@
#define SHADOW_ENABLED(wpd) (wpd->shading.flag & V3D_SHADING_SHADOW)
#define NORMAL_VIEWPORT_PASS_ENABLED(wpd) (wpd->shading.light & V3D_LIGHTING_STUDIO || SHADOW_ENABLED(wpd))
#define NORMAL_ENCODING_ENABLED() (true)
+#define WORKBENCH_REVEALAGE_ENABLED
#define STUDIOLIGHT_ORIENTATION_WORLD_ENABLED(wpd) (wpd->studio_light->flag & STUDIOLIGHT_ORIENTATION_WORLD)
@@ -55,6 +56,10 @@ typedef struct WORKBENCH_FramebufferList {
/* Forward render buffers */
struct GPUFrameBuffer *object_outline_fb;
struct GPUFrameBuffer *transparent_accum_fb;
+
+#ifdef WORKBENCH_REVEALAGE_ENABLED
+ struct GPUFrameBuffer *transparent_revealage_fb;
+#endif
} WORKBENCH_FramebufferList;
typedef struct WORKBENCH_StorageList {
@@ -65,13 +70,19 @@ typedef struct WORKBENCH_PassList {
/* deferred rendering */
struct DRWPass *prepass_pass;
struct DRWPass *shadow_depth_pass_pass;
+ struct DRWPass *shadow_depth_pass_mani_pass;
struct DRWPass *shadow_depth_fail_pass;
+ struct DRWPass *shadow_depth_fail_mani_pass;
struct DRWPass *shadow_depth_fail_caps_pass;
+ struct DRWPass *shadow_depth_fail_caps_mani_pass;
struct DRWPass *composite_pass;
struct DRWPass *composite_shadow_pass;
/* forward rendering */
struct DRWPass *transparent_accum_pass;
+#ifdef WORKBENCH_REVEALAGE_ENABLED
+ struct DRWPass *transparent_revealage_pass;
+#endif
struct DRWPass *object_outline_pass;
struct DRWPass *depth_pass;
struct DRWPass *checker_depth_pass;
@@ -111,8 +122,19 @@ typedef struct WORKBENCH_PrivateData {
struct GPUUniformBuffer *world_ubo;
struct DRWShadingGroup *shadow_shgrp;
struct DRWShadingGroup *depth_shgrp;
+#ifdef WORKBENCH_REVEALAGE_ENABLED
+ struct DRWShadingGroup *transparent_revealage_shgrp;
+#endif
WORKBENCH_UBO_World world_data;
float shadow_multiplier;
+ float cached_shadow_direction[3];
+ float shadow_mat[4][4];
+ float shadow_inv[4][4];
+ float shadow_near_corners[4][3]; /* Near plane corners in shadow space. */
+ float shadow_near_min[3]; /* min and max of shadow_near_corners. allow fast test */
+ float shadow_near_max[3];
+ float shadow_near_sides[2][4]; /* This is a parallelogram, so only 2 normal and distance to the edges. */
+ bool shadow_changed;
} WORKBENCH_PrivateData; /* Transient data */
typedef struct WORKBENCH_MaterialData {
@@ -137,6 +159,9 @@ typedef struct WORKBENCH_ObjectData {
int recalc;
/* Shadow direction in local object space. */
float shadow_dir[3];
+ float shadow_min[3], shadow_max[3]; /* Min, max in shadow space */
+ BoundBox shadow_bbox;
+ bool shadow_bbox_dirty;
int object_id;
} WORKBENCH_ObjectData;
@@ -172,10 +197,14 @@ char *workbench_material_build_defines(WORKBENCH_PrivateData *wpd, int drawtype)
void workbench_material_get_solid_color(WORKBENCH_PrivateData *wpd, Object *ob, Material *mat, float *color);
uint workbench_material_get_hash(WORKBENCH_MaterialData *material_template);
int workbench_material_get_shader_index(WORKBENCH_PrivateData *wpd, int drawtype);
-void workbench_material_set_normal_world_matrix(DRWShadingGroup *grp, WORKBENCH_PrivateData *wpd, float persistent_matrix[3][3]);
+void workbench_material_set_normal_world_matrix(
+ DRWShadingGroup *grp, WORKBENCH_PrivateData *wpd, float persistent_matrix[3][3]);
/* workbench_studiolight.c */
void studiolight_update_world(StudioLight *sl, WORKBENCH_UBO_World *wd);
+void studiolight_update_light(WORKBENCH_PrivateData *wpd, const float light_direction[3]);
+bool studiolight_object_cast_visible_shadow(WORKBENCH_PrivateData *wpd, Object *ob, WORKBENCH_ObjectData *oed);
+bool studiolight_camera_in_object_shadow(WORKBENCH_PrivateData *wpd, Object *ob, WORKBENCH_ObjectData *oed);
/* workbench_data.c */
void workbench_private_data_init(WORKBENCH_PrivateData *wpd);
diff --git a/source/blender/draw/engines/workbench/workbench_studiolight.c b/source/blender/draw/engines/workbench/workbench_studiolight.c
index 2142be3eaf4..4db89717b2a 100644
--- a/source/blender/draw/engines/workbench/workbench_studiolight.c
+++ b/source/blender/draw/engines/workbench/workbench_studiolight.c
@@ -27,7 +27,10 @@
#include "DRW_engine.h"
#include "workbench_private.h"
+#include "BKE_object.h"
+
#include "BLI_math.h"
+#include "BKE_global.h"
void studiolight_update_world(StudioLight *sl, WORKBENCH_UBO_World *wd)
{
@@ -40,3 +43,139 @@ void studiolight_update_world(StudioLight *sl, WORKBENCH_UBO_World *wd)
copy_v3_v3(wd->diffuse_light_z_pos, sl->diffuse_light[STUDIOLIGHT_Z_POS]);
copy_v3_v3(wd->diffuse_light_z_neg, sl->diffuse_light[STUDIOLIGHT_Z_NEG]);
}
+
+static void compute_parallel_lines_nor_and_dist(const float v1[2], const float v2[2], const float v3[2], float r_line[2])
+{
+ sub_v2_v2v2(r_line, v2, v1);
+ /* Find orthogonal vector. */
+ SWAP(float, r_line[0], r_line[1]);
+ r_line[0] = -r_line[0];
+ /* Edge distances. */
+ r_line[2] = dot_v2v2(r_line, v1);
+ r_line[3] = dot_v2v2(r_line, v3);
+ /* Make sure r_line[2] is the minimum. */
+ if (r_line[2] > r_line[3]) {
+ SWAP(float, r_line[2], r_line[3]);
+ }
+}
+
+void studiolight_update_light(WORKBENCH_PrivateData *wpd, const float light_direction[3])
+{
+ wpd->shadow_changed = !compare_v3v3(wpd->cached_shadow_direction, light_direction, 1e-5f);
+
+ if (wpd->shadow_changed) {
+ float up[3] = {0.0f, 0.0f, 1.0f};
+ unit_m4(wpd->shadow_mat);
+
+ /* TODO fix singularity. */
+ copy_v3_v3(wpd->shadow_mat[2], light_direction);
+ cross_v3_v3v3(wpd->shadow_mat[0], wpd->shadow_mat[2], up);
+ normalize_v3(wpd->shadow_mat[0]);
+ cross_v3_v3v3(wpd->shadow_mat[1], wpd->shadow_mat[2], wpd->shadow_mat[0]);
+
+ invert_m4_m4(wpd->shadow_inv, wpd->shadow_mat);
+
+ copy_v3_v3(wpd->cached_shadow_direction, light_direction);
+
+ }
+
+ BoundBox frustum_corners;
+ DRW_culling_frustum_corners_get(&frustum_corners);
+
+ mul_v3_mat3_m4v3(wpd->shadow_near_corners[0], wpd->shadow_inv, frustum_corners.vec[0]);
+ mul_v3_mat3_m4v3(wpd->shadow_near_corners[1], wpd->shadow_inv, frustum_corners.vec[3]);
+ mul_v3_mat3_m4v3(wpd->shadow_near_corners[2], wpd->shadow_inv, frustum_corners.vec[7]);
+ mul_v3_mat3_m4v3(wpd->shadow_near_corners[3], wpd->shadow_inv, frustum_corners.vec[4]);
+
+ INIT_MINMAX(wpd->shadow_near_min, wpd->shadow_near_max);
+ for (int i = 0; i < 4; ++i) {
+ minmax_v3v3_v3(wpd->shadow_near_min, wpd->shadow_near_max, wpd->shadow_near_corners[i]);
+ }
+
+ compute_parallel_lines_nor_and_dist(wpd->shadow_near_corners[0], wpd->shadow_near_corners[1], wpd->shadow_near_corners[2], wpd->shadow_near_sides[0]);
+ compute_parallel_lines_nor_and_dist(wpd->shadow_near_corners[1], wpd->shadow_near_corners[2], wpd->shadow_near_corners[0], wpd->shadow_near_sides[1]);
+}
+
+static BoundBox *studiolight_object_shadow_bbox_get(WORKBENCH_PrivateData *wpd, Object *ob, WORKBENCH_ObjectData *oed)
+{
+ if ((oed->shadow_bbox_dirty) || (wpd->shadow_changed)) {
+ float tmp_mat[4][4];
+ mul_m4_m4m4(tmp_mat, wpd->shadow_inv, ob->obmat);
+
+ /* Get AABB in shadow space. */
+ INIT_MINMAX(oed->shadow_min, oed->shadow_max);
+
+ /* From object space to shadow space */
+ BoundBox *bbox = BKE_object_boundbox_get(ob);
+ for (int i = 0; i < 8; ++i) {
+ float corner[3];
+ mul_v3_m4v3(corner, tmp_mat, bbox->vec[i]);
+ minmax_v3v3_v3(oed->shadow_min, oed->shadow_max, corner);
+ }
+ /* Extend towards infinity. */
+ oed->shadow_max[2] += 1e4;
+
+ /* Get extended AABB in world space. */
+ BKE_boundbox_init_from_minmax(&oed->shadow_bbox, oed->shadow_min, oed->shadow_max);
+ for (int i = 0; i < 8; ++i) {
+ mul_m4_v3(wpd->shadow_mat, oed->shadow_bbox.vec[i]);
+ }
+ }
+
+ return &oed->shadow_bbox;
+}
+
+bool studiolight_object_cast_visible_shadow(WORKBENCH_PrivateData *wpd, Object *ob, WORKBENCH_ObjectData *oed)
+{
+ BoundBox *shadow_bbox = studiolight_object_shadow_bbox_get(wpd, ob, oed);
+ return DRW_culling_box_test(shadow_bbox);
+}
+
+bool studiolight_camera_in_object_shadow(WORKBENCH_PrivateData *wpd, Object *ob, WORKBENCH_ObjectData *oed)
+{
+ /* Just to be sure the min, max are updated. */
+ studiolight_object_shadow_bbox_get(wpd, ob, oed);
+
+ /* Test if near plane is in front of the shadow. */
+ if (oed->shadow_min[2] > wpd->shadow_near_max[2]) {
+ return false;
+ }
+
+ /* Separation Axis Theorem test */
+
+ /* Test bbox sides first (faster) */
+ if ((oed->shadow_min[0] > wpd->shadow_near_max[0]) ||
+ (oed->shadow_max[0] < wpd->shadow_near_min[0]) ||
+ (oed->shadow_min[1] > wpd->shadow_near_max[1]) ||
+ (oed->shadow_max[1] < wpd->shadow_near_min[1]))
+ {
+ return false;
+ }
+
+ /* Test projected near rectangle sides */
+ float pts[4][2] = {
+ {oed->shadow_min[0], oed->shadow_min[1]},
+ {oed->shadow_min[0], oed->shadow_max[1]},
+ {oed->shadow_max[0], oed->shadow_min[1]},
+ {oed->shadow_max[0], oed->shadow_max[1]}
+ };
+
+ for (int i = 0; i < 2; ++i) {
+ float min_dst = FLT_MAX, max_dst = -FLT_MAX;
+ for (int j = 0; j < 4; ++j) {
+ float dst = dot_v2v2(wpd->shadow_near_sides[i], pts[j]);
+ /* Do min max */
+ if (min_dst > dst) min_dst = dst;
+ if (max_dst < dst) max_dst = dst;
+ }
+
+ if ((wpd->shadow_near_sides[i][2] > max_dst) ||
+ (wpd->shadow_near_sides[i][3] < min_dst))
+ {
+ return false;
+ }
+ }
+
+ /* No separation axis found. Both shape intersect. */
+ return true;
+}
diff --git a/source/blender/draw/intern/DRW_render.h b/source/blender/draw/intern/DRW_render.h
index 8af3e6c7859..25806062f68 100644
--- a/source/blender/draw/intern/DRW_render.h
+++ b/source/blender/draw/intern/DRW_render.h
@@ -152,7 +152,9 @@ typedef struct DrawEngineType {
void (*view_update)(void *vedata);
void (*id_update)(void *vedata, struct ID *id);
- void (*render_to_image)(void *vedata, struct RenderEngine *engine, struct RenderLayer *layer, const struct rcti *rect);
+ void (*render_to_image)(
+ void *vedata, struct RenderEngine *engine,
+ struct RenderLayer *layer, const struct rcti *rect);
} DrawEngineType;
#ifndef __DRW_ENGINE_H__
@@ -280,6 +282,7 @@ typedef enum {
DRW_STATE_BLEND_PREMUL = (1 << 21), /* Use that if color is already premult by alpha. */
DRW_STATE_WIRE_SMOOTH = (1 << 22),
DRW_STATE_TRANS_FEEDBACK = (1 << 23),
+ DRW_STATE_TRANSPARENT_REVEALAGE = (1 << 24),
DRW_STATE_WRITE_STENCIL = (1 << 27),
DRW_STATE_WRITE_STENCIL_SHADOW_PASS = (1 << 28),
@@ -317,10 +320,14 @@ DRWShadingGroup *DRW_shgroup_material_empty_tri_batch_create(struct GPUMaterial
DRWShadingGroup *DRW_shgroup_instance_create(
struct GPUShader *shader, DRWPass *pass, struct Gwn_Batch *geom, struct Gwn_VertFormat *format);
DRWShadingGroup *DRW_shgroup_point_batch_create(struct GPUShader *shader, DRWPass *pass);
-DRWShadingGroup *DRW_shgroup_line_batch_create_with_format(struct GPUShader *shader, DRWPass *pass, struct Gwn_VertFormat *format);
-DRWShadingGroup *DRW_shgroup_line_batch_create(struct GPUShader *shader, DRWPass *pass);
-DRWShadingGroup *DRW_shgroup_empty_tri_batch_create(struct GPUShader *shader, DRWPass *pass, int size);
-DRWShadingGroup *DRW_shgroup_transform_feedback_create(struct GPUShader *shader, DRWPass *pass, struct Gwn_VertBuf *tf_target);
+DRWShadingGroup *DRW_shgroup_line_batch_create_with_format(
+ struct GPUShader *shader, DRWPass *pass, struct Gwn_VertFormat *format);
+DRWShadingGroup *DRW_shgroup_line_batch_create(
+ struct GPUShader *shader, DRWPass *pass);
+DRWShadingGroup *DRW_shgroup_empty_tri_batch_create(
+ struct GPUShader *shader, DRWPass *pass, int size);
+DRWShadingGroup *DRW_shgroup_transform_feedback_create(
+ struct GPUShader *shader, DRWPass *pass, struct Gwn_VertBuf *tf_target);
typedef void (DRWCallGenerateFn)(
DRWShadingGroup *shgroup,
@@ -439,8 +446,10 @@ void DRW_render_instance_buffer_finish(void);
/* ViewLayers */
void *DRW_view_layer_engine_data_get(DrawEngineType *engine_type);
-void **DRW_view_layer_engine_data_ensure_ex(struct ViewLayer *view_layer, DrawEngineType *engine_type, void (*callback)(void *storage));
-void **DRW_view_layer_engine_data_ensure(DrawEngineType *engine_type, void (*callback)(void *storage));
+void **DRW_view_layer_engine_data_ensure_ex(
+ struct ViewLayer *view_layer, DrawEngineType *engine_type, void (*callback)(void *storage));
+void **DRW_view_layer_engine_data_ensure(
+ DrawEngineType *engine_type, void (*callback)(void *storage));
/* Objects */
ObjectEngineData *DRW_object_engine_data_get(Object *ob, DrawEngineType *engine_type);
@@ -488,6 +497,8 @@ bool DRW_culling_sphere_test(BoundSphere *bsphere);
bool DRW_culling_box_test(BoundBox *bbox);
bool DRW_culling_plane_test(float plane[4]);
+void DRW_culling_frustum_corners_get(BoundBox *corners);
+
/* Selection */
void DRW_select_load_id(uint id);
diff --git a/source/blender/draw/intern/draw_armature.c b/source/blender/draw/intern/draw_armature.c
index ed2b52700d9..ed9bb6f8ca9 100644
--- a/source/blender/draw/intern/draw_armature.c
+++ b/source/blender/draw/intern/draw_armature.c
@@ -134,7 +134,7 @@ static void drw_shgroup_bone_octahedral(
const float bone_color[4], const float hint_color[4], const float outline_color[4])
{
if (g_data.bone_octahedral_outline == NULL) {
- struct Gwn_Batch *geom = DRW_cache_bone_octahedral_get();
+ struct Gwn_Batch *geom = DRW_cache_bone_octahedral_wire_get();
g_data.bone_octahedral_outline = shgroup_instance_bone_shape_outline(g_data.passes.bone_outline, geom);
}
if (g_data.bone_octahedral_solid == NULL) {
@@ -155,7 +155,7 @@ static void drw_shgroup_bone_box(
const float bone_color[4], const float hint_color[4], const float outline_color[4])
{
if (g_data.bone_box_wire == NULL) {
- struct Gwn_Batch *geom = DRW_cache_bone_box_get();
+ struct Gwn_Batch *geom = DRW_cache_bone_box_wire_get();
g_data.bone_box_outline = shgroup_instance_bone_shape_outline(g_data.passes.bone_outline, geom);
}
if (g_data.bone_box_solid == NULL) {
@@ -313,19 +313,32 @@ static void drw_shgroup_bone_envelope(
/* Custom (geometry) */
-static void drw_shgroup_bone_custom_solid(const float (*bone_mat)[4], const float color[4], Object *custom)
+static void drw_shgroup_bone_custom_solid(
+ const float (*bone_mat)[4],
+ const float bone_color[4], const float hint_color[4], const float outline_color[4],
+ Object *custom)
{
/* grr, not re-using instances! */
struct Gwn_Batch *geom = DRW_cache_object_surface_get(custom);
if (geom) {
- DRWShadingGroup *shgrp_geom_solid = shgroup_instance_solid(g_data.passes.bone_solid, geom);
+ DRWShadingGroup *shgrp_geom_solid = shgroup_instance_bone_shape_solid(g_data.passes.bone_solid, geom);
+ float final_bonemat[4][4];
+ mul_m4_m4m4(final_bonemat, g_data.ob->obmat, bone_mat);
+ DRW_shgroup_call_dynamic_add(shgrp_geom_solid, final_bonemat, bone_color, hint_color);
+ }
+
+ geom = DRW_cache_object_edge_detection_get(custom, NULL);
+ if (geom && outline_color[3] > 0.0f) {
+ DRWShadingGroup *shgrp_geom_wire = shgroup_instance_bone_shape_outline(g_data.passes.bone_outline, geom);
float final_bonemat[4][4];
mul_m4_m4m4(final_bonemat, g_data.ob->obmat, bone_mat);
- DRW_shgroup_call_dynamic_add(shgrp_geom_solid, final_bonemat, color);
+ DRW_shgroup_call_dynamic_add(shgrp_geom_wire, final_bonemat, outline_color);
}
}
-static void drw_shgroup_bone_custom_wire(const float (*bone_mat)[4], const float color[4], Object *custom)
+static void drw_shgroup_bone_custom_wire(
+ const float (*bone_mat)[4],
+ const float color[4], Object *custom)
{
/* grr, not re-using instances! */
struct Gwn_Batch *geom = DRW_cache_object_wire_outline_get(custom);
@@ -373,7 +386,8 @@ static void drw_shgroup_bone_axes(const float (*bone_mat)[4], const float color[
static void drw_shgroup_bone_relationship_lines(const float start[3], const float end[3])
{
if (g_data.lines_relationship == NULL) {
- g_data.lines_relationship = shgroup_dynlines_dashed_uniform_color(g_data.passes.relationship_lines, g_theme.wire_color);
+ g_data.lines_relationship = shgroup_dynlines_dashed_uniform_color(
+ g_data.passes.relationship_lines, g_theme.wire_color);
}
/* reverse order to have less stipple overlap */
float v[3];
@@ -956,7 +970,8 @@ static void ebone_spline_preview(EditBone *ebone, float result_array[MAX_BBONE_S
size_to_mat4(bscalemat, bscale);
- /* Note: don't multiply by inverse scale mat here, as it causes problems with scaling shearing and breaking segment chains */
+ /* Note: don't multiply by inverse scale mat here,
+ * as it causes problems with scaling shearing and breaking segment chains */
mul_m4_series(result_array[a], result_array[a], bscalemat);
}
}
@@ -1055,7 +1070,8 @@ static void draw_axes(EditBone *eBone, bPoseChannel *pchan)
const float *col = (g_theme.const_color) ? g_theme.const_color :
(BONE_FLAG(eBone, pchan) & BONE_SELECTED) ? g_theme.text_hi_color : g_theme.text_color;
copy_v4_v4(final_col, col);
- final_col[3] = (g_theme.const_color) ? 1.0 : (BONE_FLAG(eBone, pchan) & BONE_SELECTED) ? 0.3 : 0.8; /* Mix with axes color. */
+ /* Mix with axes color. */
+ final_col[3] = (g_theme.const_color) ? 1.0 : (BONE_FLAG(eBone, pchan) & BONE_SELECTED) ? 0.3 : 0.8;
drw_shgroup_bone_axes(BONE_VAR(eBone, pchan, disp_mat), final_col);
}
@@ -1107,8 +1123,9 @@ static void draw_points(
if (eBone) {
if (!((eBone->parent) && !EBONE_VISIBLE(arm, eBone->parent))) {
if (is_envelope_draw) {
- drw_shgroup_bone_envelope(eBone->disp_mat, col_solid_root, col_hint_root, col_wire_root,
- &eBone->rad_head, &envelope_ignore);
+ drw_shgroup_bone_envelope(
+ eBone->disp_mat, col_solid_root, col_hint_root, col_wire_root,
+ &eBone->rad_head, &envelope_ignore);
}
else {
drw_shgroup_bone_point(eBone->disp_mat, col_solid_root, col_hint_root, col_wire_root);
@@ -1119,8 +1136,9 @@ static void draw_points(
Bone *bone = pchan->bone;
if (!((bone->parent) && (bone->parent->flag & (BONE_HIDDEN_P | BONE_HIDDEN_PG)))) {
if (is_envelope_draw) {
- drw_shgroup_bone_envelope(pchan->disp_mat, col_solid_root, col_hint_root, col_wire_root,
- &bone->rad_head, &envelope_ignore);
+ drw_shgroup_bone_envelope(
+ pchan->disp_mat, col_solid_root, col_hint_root, col_wire_root,
+ &bone->rad_head, &envelope_ignore);
}
else {
drw_shgroup_bone_point(pchan->disp_mat, col_solid_root, col_hint_root, col_wire_root);
@@ -1137,7 +1155,8 @@ static void draw_points(
if (is_envelope_draw) {
const float *rad_tail = eBone ? &eBone->rad_tail : &pchan->bone->rad_tail;
drw_shgroup_bone_envelope(
- BONE_VAR(eBone, pchan, disp_mat), col_solid_tail, col_hint_tail, col_wire_tail, &envelope_ignore, rad_tail);
+ BONE_VAR(eBone, pchan, disp_mat), col_solid_tail, col_hint_tail, col_wire_tail,
+ &envelope_ignore, rad_tail);
}
else {
drw_shgroup_bone_point(BONE_VAR(eBone, pchan, disp_tail_mat), col_solid_tail, col_hint_tail, col_wire_tail);
@@ -1163,6 +1182,7 @@ static void draw_bone_custom_shape(
{
const float *col_solid = get_bone_solid_color(eBone, pchan, arm, boneflag, constflag);
const float *col_wire = get_bone_wire_color(eBone, pchan, arm, boneflag, constflag);
+ const float *col_hint = get_bone_hint_color(eBone, pchan, arm, boneflag, constflag);
const float (*disp_mat)[4] = pchan->disp_mat;
if (select_id != -1) {
@@ -1170,9 +1190,11 @@ static void draw_bone_custom_shape(
}
if ((boneflag & BONE_DRAWWIRE) == 0) {
- drw_shgroup_bone_custom_solid(disp_mat, col_solid, pchan->custom);
+ drw_shgroup_bone_custom_solid(disp_mat, col_solid, col_hint, col_wire, pchan->custom);
+ }
+ else {
+ drw_shgroup_bone_custom_wire(disp_mat, col_wire, pchan->custom);
}
- drw_shgroup_bone_custom_wire(disp_mat, col_wire, pchan->custom);
if (select_id != -1) {
DRW_select_load_id(-1);
@@ -1211,7 +1233,9 @@ static void draw_bone_envelope(
DRW_select_load_id(select_id | BONESEL_BONE);
}
- drw_shgroup_bone_envelope(BONE_VAR(eBone, pchan, disp_mat), col_solid, col_hint, col_wire, rad_head, rad_tail);
+ drw_shgroup_bone_envelope(
+ BONE_VAR(eBone, pchan, disp_mat), col_solid, col_hint, col_wire,
+ rad_head, rad_tail);
if (select_id != -1) {
DRW_select_load_id(-1);
diff --git a/source/blender/draw/intern/draw_cache.c b/source/blender/draw/intern/draw_cache.c
index 6065e7f0fc5..b08735860c9 100644
--- a/source/blender/draw/intern/draw_cache.c
+++ b/source/blender/draw/intern/draw_cache.c
@@ -72,7 +72,8 @@ static struct DRWShapeCache {
Gwn_Batch *drw_lamp;
Gwn_Batch *drw_lamp_shadows;
Gwn_Batch *drw_lamp_sunrays;
- Gwn_Batch *drw_lamp_area;
+ Gwn_Batch *drw_lamp_area_square;
+ Gwn_Batch *drw_lamp_area_disk;
Gwn_Batch *drw_lamp_hemi;
Gwn_Batch *drw_lamp_spot;
Gwn_Batch *drw_lamp_spot_square;
@@ -502,11 +503,11 @@ Gwn_Batch *DRW_cache_object_wire_outline_get(Object *ob)
}
/* Returns a buffer texture. */
-Gwn_Batch *DRW_cache_object_edge_detection_get(Object *ob)
+Gwn_Batch *DRW_cache_object_edge_detection_get(Object *ob, bool *r_is_manifold)
{
switch (ob->type) {
case OB_MESH:
- return DRW_cache_mesh_edge_detection_get(ob);
+ return DRW_cache_mesh_edge_detection_get(ob, r_is_manifold);
/* TODO, should match 'DRW_cache_object_surface_get' */
default:
@@ -1122,9 +1123,9 @@ Gwn_Batch *DRW_cache_lamp_sunrays_get(void)
return SHC.drw_lamp_sunrays;
}
-Gwn_Batch *DRW_cache_lamp_area_get(void)
+Gwn_Batch *DRW_cache_lamp_area_square_get(void)
{
- if (!SHC.drw_lamp_area) {
+ if (!SHC.drw_lamp_area_square) {
float v1[3] = {0.0f, 0.0f, 0.0f};
/* Position Only 3D format */
@@ -1151,9 +1152,40 @@ Gwn_Batch *DRW_cache_lamp_area_get(void)
v1[1] = 0.5f;
GWN_vertbuf_attr_set(vbo, attr_id.pos, 7, v1);
- SHC.drw_lamp_area = GWN_batch_create_ex(GWN_PRIM_LINES, vbo, NULL, GWN_BATCH_OWNS_VBO);
+ SHC.drw_lamp_area_square = GWN_batch_create_ex(GWN_PRIM_LINES, vbo, NULL, GWN_BATCH_OWNS_VBO);
}
- return SHC.drw_lamp_area;
+ return SHC.drw_lamp_area_square;
+}
+
+Gwn_Batch *DRW_cache_lamp_area_disk_get(void)
+{
+#define NSEGMENTS 32
+ if (!SHC.drw_lamp_area_disk) {
+ /* Position Only 3D format */
+ static Gwn_VertFormat format = { 0 };
+ static struct { uint pos; } attr_id;
+ if (format.attrib_ct == 0) {
+ attr_id.pos = GWN_vertformat_attr_add(&format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT);
+ }
+
+ Gwn_VertBuf *vbo = GWN_vertbuf_create_with_format(&format);
+ GWN_vertbuf_data_alloc(vbo, 2 * NSEGMENTS);
+
+ float v[3] = {0.0f, 0.5f, 0.0f};
+ GWN_vertbuf_attr_set(vbo, attr_id.pos, 0, v);
+ for (int a = 1; a < NSEGMENTS; a++) {
+ v[0] = 0.5f * sinf(2.0f * (float)M_PI * a / NSEGMENTS);
+ v[1] = 0.5f * cosf(2.0f * (float)M_PI * a / NSEGMENTS);
+ GWN_vertbuf_attr_set(vbo, attr_id.pos, 2 * a - 1, v);
+ GWN_vertbuf_attr_set(vbo, attr_id.pos, 2 * a, v);
+ }
+ copy_v3_fl3(v, 0.0f, 0.5f, 0.0f);
+ GWN_vertbuf_attr_set(vbo, attr_id.pos, (2 * NSEGMENTS) - 1, v);
+
+ SHC.drw_lamp_area_disk = GWN_batch_create_ex(GWN_PRIM_LINES, vbo, NULL, GWN_BATCH_OWNS_VBO);
+ }
+ return SHC.drw_lamp_area_disk;
+#undef NSEGMENTS
}
Gwn_Batch *DRW_cache_lamp_hemi_get(void)
@@ -1562,6 +1594,7 @@ static const float bone_octahedral_smooth_normals[6][3] = {
};
#if 0 /* UNUSED */
+
static const uint bone_octahedral_wire[24] = {
0, 1, 1, 5, 5, 3, 3, 0,
0, 4, 4, 5, 5, 2, 2, 0,
@@ -1600,6 +1633,13 @@ static const uint bone_octahedral_solid_tris[8][3] = {
* the first vertex of the first face aka. vertex 2):
* {0, 12, 1, 10, 2, 3}
**/
+static const uint bone_octahedral_wire_lines_adjacency[12][4] = {
+ { 0, 1, 2, 6}, { 0, 12, 1, 6}, { 0, 3, 12, 6}, { 0, 2, 3, 6},
+ { 1, 6, 2, 3}, { 1, 12, 6, 3}, { 1, 0, 12, 3}, { 1, 2, 0, 3},
+ { 2, 0, 1, 12}, { 2, 3, 0, 12}, { 2, 6, 3, 12}, { 2, 1, 6, 12},
+};
+
+#if 0 /* UNUSED */
static const uint bone_octahedral_solid_tris_adjacency[8][6] = {
{ 0, 12, 1, 10, 2, 3},
{ 3, 15, 4, 1, 5, 6},
@@ -1611,6 +1651,7 @@ static const uint bone_octahedral_solid_tris_adjacency[8][6] = {
{18, 16, 19, 8, 20, 23},
{21, 19, 22, 11, 23, 14},
};
+#endif
/* aligned with bone_octahedral_solid_tris */
static const float bone_octahedral_solid_normals[8][3] = {
@@ -1641,30 +1682,43 @@ Gwn_Batch *DRW_cache_bone_octahedral_get(void)
Gwn_VertBuf *vbo = GWN_vertbuf_create_with_format(&format);
GWN_vertbuf_data_alloc(vbo, 24);
- Gwn_IndexBufBuilder elb;
- GWN_indexbuf_init_ex(&elb, GWN_PRIM_TRIS_ADJ, 6 * 8, 24, false);
-
for (int i = 0; i < 8; i++) {
- GWN_vertbuf_attr_set(vbo, attr_id.nor, v_idx, bone_octahedral_solid_normals[i]);
- GWN_vertbuf_attr_set(vbo, attr_id.snor, v_idx, bone_octahedral_smooth_normals[bone_octahedral_solid_tris[i][0]]);
- GWN_vertbuf_attr_set(vbo, attr_id.pos, v_idx++, bone_octahedral_verts[bone_octahedral_solid_tris[i][0]]);
- GWN_vertbuf_attr_set(vbo, attr_id.nor, v_idx, bone_octahedral_solid_normals[i]);
- GWN_vertbuf_attr_set(vbo, attr_id.snor, v_idx, bone_octahedral_smooth_normals[bone_octahedral_solid_tris[i][1]]);
- GWN_vertbuf_attr_set(vbo, attr_id.pos, v_idx++, bone_octahedral_verts[bone_octahedral_solid_tris[i][1]]);
- GWN_vertbuf_attr_set(vbo, attr_id.nor, v_idx, bone_octahedral_solid_normals[i]);
- GWN_vertbuf_attr_set(vbo, attr_id.snor, v_idx, bone_octahedral_smooth_normals[bone_octahedral_solid_tris[i][2]]);
- GWN_vertbuf_attr_set(vbo, attr_id.pos, v_idx++, bone_octahedral_verts[bone_octahedral_solid_tris[i][2]]);
- for (int j = 0; j < 6; ++j) {
- GWN_indexbuf_add_generic_vert(&elb, bone_octahedral_solid_tris_adjacency[i][j]);
+ for (int j = 0; j < 3; ++j) {
+ GWN_vertbuf_attr_set(vbo, attr_id.nor, v_idx, bone_octahedral_solid_normals[i]);
+ GWN_vertbuf_attr_set(vbo, attr_id.snor, v_idx, bone_octahedral_smooth_normals[bone_octahedral_solid_tris[i][j]]);
+ GWN_vertbuf_attr_set(vbo, attr_id.pos, v_idx++, bone_octahedral_verts[bone_octahedral_solid_tris[i][j]]);
}
}
- SHC.drw_bone_octahedral = GWN_batch_create_ex(GWN_PRIM_TRIS_ADJ, vbo, GWN_indexbuf_build(&elb),
- GWN_BATCH_OWNS_VBO | GWN_BATCH_OWNS_INDEX);
+ SHC.drw_bone_octahedral = GWN_batch_create_ex(GWN_PRIM_TRIS, vbo, NULL,
+ GWN_BATCH_OWNS_VBO);
}
return SHC.drw_bone_octahedral;
}
+Gwn_Batch *DRW_cache_bone_octahedral_wire_get(void)
+{
+ if (!SHC.drw_bone_octahedral_wire) {
+ Gwn_IndexBufBuilder elb;
+ GWN_indexbuf_init(&elb, GWN_PRIM_LINES_ADJ, 12, 24);
+
+ for (int i = 0; i < 12; i++) {
+ GWN_indexbuf_add_line_adj_verts(&elb,
+ bone_octahedral_wire_lines_adjacency[i][0],
+ bone_octahedral_wire_lines_adjacency[i][1],
+ bone_octahedral_wire_lines_adjacency[i][2],
+ bone_octahedral_wire_lines_adjacency[i][3]);
+ }
+
+ /* HACK Reuse vertex buffer. */
+ Gwn_Batch *pos_nor_batch = DRW_cache_bone_octahedral_get();
+
+ SHC.drw_bone_octahedral_wire = GWN_batch_create_ex(GWN_PRIM_LINES_ADJ, pos_nor_batch->verts[0], GWN_indexbuf_build(&elb),
+ GWN_BATCH_OWNS_INDEX);
+ }
+ return SHC.drw_bone_octahedral_wire;
+}
+
/* XXX TODO move that 1 unit cube to more common/generic place? */
static const float bone_box_verts[8][3] = {
{ 1.0f, 0.0f, 1.0f},
@@ -1728,6 +1782,13 @@ static const uint bone_box_solid_tris[12][3] = {
* Store indices of generated verts from bone_box_solid_tris to define adjacency infos.
* See bone_octahedral_solid_tris for more infos.
**/
+static const uint bone_box_wire_lines_adjacency[12][4] = {
+ { 4, 2, 0, 11}, { 0, 1, 2, 8}, { 2, 4, 1, 14}, { 1, 0, 4, 20}, /* bottom */
+ { 0, 8, 11, 14}, { 2, 14, 8, 20}, { 1, 20, 14, 11}, { 4, 11, 20, 8}, /* top */
+ { 20, 0, 11, 2}, { 11, 2, 8, 1}, { 8, 1, 14, 4}, { 14, 4, 20, 0}, /* sides */
+};
+
+#if 0 /* UNUSED */
static const uint bone_box_solid_tris_adjacency[12][6] = {
{ 0, 5, 1, 14, 2, 8},
{ 3, 26, 4, 20, 5, 1},
@@ -1747,6 +1808,7 @@ static const uint bone_box_solid_tris_adjacency[12][6] = {
{30, 9, 31, 15, 32, 35},
{33, 31, 34, 21, 35, 27},
};
+#endif
/* aligned with bone_box_solid_tris */
static const float bone_box_solid_normals[12][3] = {
@@ -1786,26 +1848,43 @@ Gwn_Batch *DRW_cache_bone_box_get(void)
Gwn_VertBuf *vbo = GWN_vertbuf_create_with_format(&format);
GWN_vertbuf_data_alloc(vbo, 36);
- Gwn_IndexBufBuilder elb;
- GWN_indexbuf_init_ex(&elb, GWN_PRIM_TRIS_ADJ, 6 * 12, 36, false);
-
for (int i = 0; i < 12; i++) {
for (int j = 0; j < 3; j++) {
GWN_vertbuf_attr_set(vbo, attr_id.nor, v_idx, bone_box_solid_normals[i]);
GWN_vertbuf_attr_set(vbo, attr_id.snor, v_idx, bone_box_smooth_normals[bone_box_solid_tris[i][j]]);
GWN_vertbuf_attr_set(vbo, attr_id.pos, v_idx++, bone_box_verts[bone_box_solid_tris[i][j]]);
}
- for (int j = 0; j < 6; ++j) {
- GWN_indexbuf_add_generic_vert(&elb, bone_box_solid_tris_adjacency[i][j]);
- }
}
- SHC.drw_bone_box = GWN_batch_create_ex(GWN_PRIM_TRIS_ADJ, vbo, GWN_indexbuf_build(&elb),
- GWN_BATCH_OWNS_VBO | GWN_BATCH_OWNS_INDEX);
+ SHC.drw_bone_box = GWN_batch_create_ex(GWN_PRIM_TRIS, vbo, NULL,
+ GWN_BATCH_OWNS_VBO);
}
return SHC.drw_bone_box;
}
+Gwn_Batch *DRW_cache_bone_box_wire_get(void)
+{
+ if (!SHC.drw_bone_box_wire) {
+ Gwn_IndexBufBuilder elb;
+ GWN_indexbuf_init(&elb, GWN_PRIM_LINES_ADJ, 12, 36);
+
+ for (int i = 0; i < 12; i++) {
+ GWN_indexbuf_add_line_adj_verts(&elb,
+ bone_box_wire_lines_adjacency[i][0],
+ bone_box_wire_lines_adjacency[i][1],
+ bone_box_wire_lines_adjacency[i][2],
+ bone_box_wire_lines_adjacency[i][3]);
+ }
+
+ /* HACK Reuse vertex buffer. */
+ Gwn_Batch *pos_nor_batch = DRW_cache_bone_box_get();
+
+ SHC.drw_bone_box_wire = GWN_batch_create_ex(GWN_PRIM_LINES_ADJ, pos_nor_batch->verts[0], GWN_indexbuf_build(&elb),
+ GWN_BATCH_OWNS_INDEX);
+ }
+ return SHC.drw_bone_box_wire;
+}
+
/* Helpers for envelope bone's solid sphere-with-hidden-equatorial-cylinder.
* Note that here we only encode head/tail in forth component of the vector. */
static void benv_lat_lon_to_co(const float lat, const float lon, float r_nor[3])
@@ -2014,9 +2093,9 @@ Gwn_Batch *DRW_cache_bone_point_wire_outline_get(void)
for (int a = 0; a < CIRCLE_RESOL; a++) {
v1[0] = radius * sinf((2.0f * M_PI * a) / ((float)CIRCLE_RESOL));
v1[1] = radius * cosf((2.0f * M_PI * a) / ((float)CIRCLE_RESOL));
- GWN_vertbuf_attr_set(vbo, attr_id.pos0, v , v0);
+ GWN_vertbuf_attr_set(vbo, attr_id.pos0, v, v0);
GWN_vertbuf_attr_set(vbo, attr_id.pos1, v++, v1);
- GWN_vertbuf_attr_set(vbo, attr_id.pos0, v , v0);
+ GWN_vertbuf_attr_set(vbo, attr_id.pos0, v, v0);
GWN_vertbuf_attr_set(vbo, attr_id.pos1, v++, v1);
copy_v2_v2(v0, v1);
}
@@ -2506,12 +2585,12 @@ Gwn_Batch *DRW_cache_mesh_wire_outline_get(Object *ob)
return DRW_mesh_batch_cache_get_fancy_edges(me);
}
-Gwn_Batch *DRW_cache_mesh_edge_detection_get(Object *ob)
+Gwn_Batch *DRW_cache_mesh_edge_detection_get(Object *ob, bool *r_is_manifold)
{
BLI_assert(ob->type == OB_MESH);
Mesh *me = ob->data;
- return DRW_mesh_batch_cache_get_edge_detection(me);
+ return DRW_mesh_batch_cache_get_edge_detection(me, r_is_manifold);
}
Gwn_Batch *DRW_cache_mesh_surface_get(Object *ob)
diff --git a/source/blender/draw/intern/draw_cache.h b/source/blender/draw/intern/draw_cache.h
index 8bc609ffe1f..1fd6b22c221 100644
--- a/source/blender/draw/intern/draw_cache.h
+++ b/source/blender/draw/intern/draw_cache.h
@@ -48,7 +48,7 @@ struct Gwn_Batch *DRW_cache_screenspace_circle_get(void);
/* Common Object */
struct Gwn_Batch *DRW_cache_object_wire_outline_get(struct Object *ob);
-struct Gwn_Batch *DRW_cache_object_edge_detection_get(struct Object *ob);
+struct Gwn_Batch *DRW_cache_object_edge_detection_get(struct Object *ob, bool *r_is_manifold);
struct Gwn_Batch *DRW_cache_object_surface_get(struct Object *ob);
struct Gwn_Batch **DRW_cache_object_surface_material_get(
struct Object *ob, struct GPUMaterial **gpumat_array, uint gpumat_array_len,
@@ -78,7 +78,8 @@ struct Gwn_Batch *DRW_cache_field_cone_limit_get(void);
struct Gwn_Batch *DRW_cache_lamp_get(void);
struct Gwn_Batch *DRW_cache_lamp_shadows_get(void);
struct Gwn_Batch *DRW_cache_lamp_sunrays_get(void);
-struct Gwn_Batch *DRW_cache_lamp_area_get(void);
+struct Gwn_Batch *DRW_cache_lamp_area_square_get(void);
+struct Gwn_Batch *DRW_cache_lamp_area_disk_get(void);
struct Gwn_Batch *DRW_cache_lamp_hemi_get(void);
struct Gwn_Batch *DRW_cache_lamp_spot_get(void);
struct Gwn_Batch *DRW_cache_lamp_spot_square_get(void);
@@ -98,7 +99,9 @@ struct Gwn_Batch *DRW_cache_lightprobe_planar_get(void);
/* Bones */
struct Gwn_Batch *DRW_cache_bone_octahedral_get(void);
+struct Gwn_Batch *DRW_cache_bone_octahedral_wire_get(void);
struct Gwn_Batch *DRW_cache_bone_box_get(void);
+struct Gwn_Batch *DRW_cache_bone_box_wire_get(void);
struct Gwn_Batch *DRW_cache_bone_envelope_solid_get(void);
struct Gwn_Batch *DRW_cache_bone_envelope_outline_get(void);
struct Gwn_Batch *DRW_cache_bone_envelope_head_wire_outline_get(void);
@@ -117,7 +120,7 @@ void DRW_cache_mesh_normals_overlay_get(
struct Gwn_Batch **r_tris, struct Gwn_Batch **r_ledges, struct Gwn_Batch **r_lverts);
struct Gwn_Batch *DRW_cache_face_centers_get(struct Object *ob);
struct Gwn_Batch *DRW_cache_mesh_wire_outline_get(struct Object *ob);
-struct Gwn_Batch *DRW_cache_mesh_edge_detection_get(struct Object *ob);
+struct Gwn_Batch *DRW_cache_mesh_edge_detection_get(struct Object *ob, bool *r_is_manifold);
struct Gwn_Batch *DRW_cache_mesh_surface_get(struct Object *ob);
struct Gwn_Batch *DRW_cache_mesh_surface_weights_get(struct Object *ob);
struct Gwn_Batch *DRW_cache_mesh_surface_vert_colors_get(struct Object *ob);
@@ -166,11 +169,16 @@ struct Gwn_Batch *DRW_cache_lattice_wire_get(struct Object *ob, bool use_weight)
struct Gwn_Batch *DRW_cache_lattice_vert_overlay_get(struct Object *ob);
/* Particles */
-struct Gwn_Batch *DRW_cache_particles_get_hair(struct Object *object, struct ParticleSystem *psys, struct ModifierData *md);
-struct Gwn_Batch *DRW_cache_particles_get_dots(struct Object *object, struct ParticleSystem *psys);
-struct Gwn_Batch *DRW_cache_particles_get_edit_strands(struct Object *object, struct ParticleSystem *psys, struct PTCacheEdit *edit);
-struct Gwn_Batch *DRW_cache_particles_get_edit_inner_points(struct Object *object, struct ParticleSystem *psys, struct PTCacheEdit *edit);
-struct Gwn_Batch *DRW_cache_particles_get_edit_tip_points(struct Object *object, struct ParticleSystem *psys, struct PTCacheEdit *edit);
+struct Gwn_Batch *DRW_cache_particles_get_hair(
+ struct Object *object, struct ParticleSystem *psys, struct ModifierData *md);
+struct Gwn_Batch *DRW_cache_particles_get_dots(
+ struct Object *object, struct ParticleSystem *psys);
+struct Gwn_Batch *DRW_cache_particles_get_edit_strands(
+ struct Object *object, struct ParticleSystem *psys, struct PTCacheEdit *edit);
+struct Gwn_Batch *DRW_cache_particles_get_edit_inner_points(
+ struct Object *object, struct ParticleSystem *psys, struct PTCacheEdit *edit);
+struct Gwn_Batch *DRW_cache_particles_get_edit_tip_points(
+ struct Object *object, struct ParticleSystem *psys, struct PTCacheEdit *edit);
struct Gwn_Batch *DRW_cache_particles_get_prim(int type);
/* Metaball */
diff --git a/source/blender/draw/intern/draw_cache_impl.h b/source/blender/draw/intern/draw_cache_impl.h
index 3ca53b92946..f77dafc9b31 100644
--- a/source/blender/draw/intern/draw_cache_impl.h
+++ b/source/blender/draw/intern/draw_cache_impl.h
@@ -64,7 +64,8 @@ struct Gwn_Batch *DRW_curve_batch_cache_get_normal_edge(
struct Gwn_Batch *DRW_curve_batch_cache_get_overlay_edges(struct Curve *cu);
struct Gwn_Batch *DRW_curve_batch_cache_get_overlay_verts(struct Curve *cu);
-struct Gwn_Batch *DRW_curve_batch_cache_get_triangles_with_normals(struct Curve *cu, struct CurveCache *ob_curve_cache);
+struct Gwn_Batch *DRW_curve_batch_cache_get_triangles_with_normals(
+ struct Curve *cu, struct CurveCache *ob_curve_cache);
struct Gwn_Batch **DRW_curve_batch_cache_get_surface_shaded(
struct Curve *cu, struct CurveCache *ob_curve_cache,
struct GPUMaterial **gpumat_array, uint gpumat_array_len);
@@ -109,7 +110,7 @@ struct Gwn_Batch *DRW_mesh_batch_cache_get_triangles_with_select_mask(struct Mes
struct Gwn_Batch *DRW_mesh_batch_cache_get_points_with_normals(struct Mesh *me);
struct Gwn_Batch *DRW_mesh_batch_cache_get_all_verts(struct Mesh *me);
struct Gwn_Batch *DRW_mesh_batch_cache_get_fancy_edges(struct Mesh *me);
-struct Gwn_Batch *DRW_mesh_batch_cache_get_edge_detection(struct Mesh *me);
+struct Gwn_Batch *DRW_mesh_batch_cache_get_edge_detection(struct Mesh *me, bool *r_is_manifold);
struct Gwn_Batch *DRW_mesh_batch_cache_get_overlay_triangles(struct Mesh *me);
struct Gwn_Batch *DRW_mesh_batch_cache_get_overlay_triangles_nor(struct Mesh *me);
struct Gwn_Batch *DRW_mesh_batch_cache_get_overlay_loose_edges(struct Mesh *me);
@@ -124,10 +125,15 @@ struct Gwn_Batch *DRW_mesh_batch_cache_get_verts_with_select_id(struct Mesh *me,
void DRW_mesh_cache_sculpt_coords_ensure(struct Mesh *me);
/* Particles */
-struct Gwn_Batch *DRW_particles_batch_cache_get_hair(struct Object *object, struct ParticleSystem *psys, struct ModifierData *md);
-struct Gwn_Batch *DRW_particles_batch_cache_get_dots(struct Object *object, struct ParticleSystem *psys);
-struct Gwn_Batch *DRW_particles_batch_cache_get_edit_strands(struct Object *object, struct ParticleSystem *psys, struct PTCacheEdit *edit);
-struct Gwn_Batch *DRW_particles_batch_cache_get_edit_inner_points(struct Object *object, struct ParticleSystem *psys, struct PTCacheEdit *edit);
-struct Gwn_Batch *DRW_particles_batch_cache_get_edit_tip_points(struct Object *object, struct ParticleSystem *psys, struct PTCacheEdit *edit);
+struct Gwn_Batch *DRW_particles_batch_cache_get_hair(
+ struct Object *object, struct ParticleSystem *psys, struct ModifierData *md);
+struct Gwn_Batch *DRW_particles_batch_cache_get_dots(
+ struct Object *object, struct ParticleSystem *psys);
+struct Gwn_Batch *DRW_particles_batch_cache_get_edit_strands(
+ struct Object *object, struct ParticleSystem *psys, struct PTCacheEdit *edit);
+struct Gwn_Batch *DRW_particles_batch_cache_get_edit_inner_points(
+ struct Object *object, struct ParticleSystem *psys, struct PTCacheEdit *edit);
+struct Gwn_Batch *DRW_particles_batch_cache_get_edit_tip_points(
+ struct Object *object, struct ParticleSystem *psys, struct PTCacheEdit *edit);
#endif /* __DRAW_CACHE_IMPL_H__ */
diff --git a/source/blender/draw/intern/draw_cache_impl_displist.c b/source/blender/draw/intern/draw_cache_impl_displist.c
index 09531220d9a..3eecff024a1 100644
--- a/source/blender/draw/intern/draw_cache_impl_displist.c
+++ b/source/blender/draw/intern/draw_cache_impl_displist.c
@@ -176,7 +176,8 @@ Gwn_IndexBuf *DRW_displist_indexbuf_calc_triangles_in_order(ListBase *lb)
Gwn_IndexBuf **DRW_displist_indexbuf_calc_triangles_in_order_split_by_material(ListBase *lb, uint gpumat_array_len)
{
- Gwn_IndexBuf **shaded_triangles_in_order = MEM_callocN(sizeof(*shaded_triangles_in_order) * gpumat_array_len, __func__);
+ Gwn_IndexBuf **shaded_triangles_in_order = MEM_callocN(
+ sizeof(*shaded_triangles_in_order) * gpumat_array_len, __func__);
Gwn_IndexBufBuilder *elb = BLI_array_alloca(elb, gpumat_array_len);
const int tri_len = curve_render_surface_tri_len_get(lb);
diff --git a/source/blender/draw/intern/draw_cache_impl_mesh.c b/source/blender/draw/intern/draw_cache_impl_mesh.c
index e8add4890d8..cf972434ba5 100644
--- a/source/blender/draw/intern/draw_cache_impl_mesh.c
+++ b/source/blender/draw/intern/draw_cache_impl_mesh.c
@@ -1633,6 +1633,9 @@ typedef struct MeshBatchCache {
/* XXX, only keep for as long as sculpt mode uses shaded drawing. */
bool is_sculpt_points_tag;
+
+ /* Valid only if edges_adjacency is up to date. */
+ bool is_manifold;
} MeshBatchCache;
/* Gwn_Batch cache management. */
@@ -1953,7 +1956,8 @@ static Gwn_VertBuf *mesh_batch_cache_get_tri_shading_data(MeshRenderData *rdata,
GWN_vertformat_alias_add(format, attrib_name);
/* +1 include null terminator. */
- auto_ofs += 1 + BLI_snprintf_rlen(cache->auto_layer_names + auto_ofs, auto_names_len - auto_ofs, "b%s", attrib_name);
+ auto_ofs += 1 + BLI_snprintf_rlen(
+ cache->auto_layer_names + auto_ofs, auto_names_len - auto_ofs, "b%s", attrib_name);
cache->auto_layer_is_srgb[auto_id++] = 0; /* tag as not srgb */
if (i == rdata->cd.layers.uv_active) {
@@ -1988,7 +1992,8 @@ static Gwn_VertBuf *mesh_batch_cache_get_tri_shading_data(MeshRenderData *rdata,
GWN_vertformat_alias_add(format, attrib_name);
/* +1 include null terminator. */
- auto_ofs += 1 + BLI_snprintf_rlen(cache->auto_layer_names + auto_ofs, auto_names_len - auto_ofs, "b%s", attrib_name);
+ auto_ofs += 1 + BLI_snprintf_rlen(
+ cache->auto_layer_names + auto_ofs, auto_names_len - auto_ofs, "b%s", attrib_name);
cache->auto_layer_is_srgb[auto_id++] = 1; /* tag as srgb */
}
@@ -3232,6 +3237,8 @@ static Gwn_IndexBuf *mesh_batch_cache_get_edges_adjacency(MeshRenderData *rdata,
const int vert_len = mesh_render_data_verts_len_get(rdata);
const int tri_len = mesh_render_data_looptri_len_get(rdata);
+ cache->is_manifold = true;
+
/* Allocate max but only used indices are sent to GPU. */
Gwn_IndexBufBuilder elb;
GWN_indexbuf_init(&elb, GWN_PRIM_LINES_ADJ, tri_len * 3, vert_len);
@@ -3277,6 +3284,7 @@ static Gwn_IndexBuf *mesh_batch_cache_get_edges_adjacency(MeshRenderData *rdata,
/* Don't share edge if triangles have non matching winding. */
GWN_indexbuf_add_line_adj_verts(&elb, v0, v1, v2, v0);
GWN_indexbuf_add_line_adj_verts(&elb, v_opposite, v1, v2, v_opposite);
+ cache->is_manifold = false;
}
else {
GWN_indexbuf_add_line_adj_verts(&elb, v0, v1, v2, v_opposite);
@@ -3301,6 +3309,7 @@ static Gwn_IndexBuf *mesh_batch_cache_get_edges_adjacency(MeshRenderData *rdata,
SWAP(unsigned int, v1, v2);
}
GWN_indexbuf_add_line_adj_verts(&elb, v0, v1, v2, v0);
+ cache->is_manifold = false;
}
BLI_edgehashIterator_free(ehi);
BLI_edgehash_free(eh, NULL);
@@ -3820,7 +3829,7 @@ Gwn_Batch *DRW_mesh_batch_cache_get_fancy_edges(Mesh *me)
return cache->fancy_edges;
}
-Gwn_Batch *DRW_mesh_batch_cache_get_edge_detection(Mesh *me)
+Gwn_Batch *DRW_mesh_batch_cache_get_edge_detection(Mesh *me, bool *r_is_manifold)
{
MeshBatchCache *cache = mesh_batch_cache_get(me);
@@ -3829,12 +3838,17 @@ Gwn_Batch *DRW_mesh_batch_cache_get_edge_detection(Mesh *me)
MeshRenderData *rdata = mesh_render_data_create(me, options);
- cache->edge_detection = GWN_batch_create_ex(GWN_PRIM_LINES_ADJ, mesh_batch_cache_get_vert_pos_and_nor_in_order(rdata, cache),
- mesh_batch_cache_get_edges_adjacency(rdata, cache), 0);
+ cache->edge_detection = GWN_batch_create_ex(
+ GWN_PRIM_LINES_ADJ, mesh_batch_cache_get_vert_pos_and_nor_in_order(rdata, cache),
+ mesh_batch_cache_get_edges_adjacency(rdata, cache), 0);
mesh_render_data_free(rdata);
}
+ if (r_is_manifold) {
+ *r_is_manifold = cache->is_manifold;
+ }
+
return cache->edge_detection;
}
diff --git a/source/blender/draw/intern/draw_cache_impl_particles.c b/source/blender/draw/intern/draw_cache_impl_particles.c
index c6cc243638b..c89ea67a39c 100644
--- a/source/blender/draw/intern/draw_cache_impl_particles.c
+++ b/source/blender/draw/intern/draw_cache_impl_particles.c
@@ -599,7 +599,9 @@ static void particle_batch_cache_ensure_pos(Object *object,
val = len_v3(pa->state.vel) / psys->part->color_vec_max;
break;
case PART_DRAW_COL_ACC:
- val = len_v3v3(pa->state.vel, pa->prev_state.vel) / ((pa->state.time - pa->prev_state.time) * psys->part->color_vec_max);
+ val = len_v3v3(
+ pa->state.vel,
+ pa->prev_state.vel) / ((pa->state.time - pa->prev_state.time) * psys->part->color_vec_max);
break;
default:
val = -1.0f;
diff --git a/source/blender/draw/intern/draw_common.c b/source/blender/draw/intern/draw_common.c
index b51b15b20ed..11e04306143 100644
--- a/source/blender/draw/intern/draw_common.c
+++ b/source/blender/draw/intern/draw_common.c
@@ -224,8 +224,8 @@ DRWShadingGroup *shgroup_dynlines_flat_color(DRWPass *pass)
GPUShader *sh = GPU_shader_get_builtin_shader(GPU_SHADER_3D_FLAT_COLOR);
DRW_shgroup_instance_format(g_formats.dynlines_color, {
- {"pos" , DRW_ATTRIB_FLOAT, 3},
- {"color" , DRW_ATTRIB_FLOAT, 4}
+ {"pos", DRW_ATTRIB_FLOAT, 3},
+ {"color", DRW_ATTRIB_FLOAT, 4}
});
DRWShadingGroup *grp = DRW_shgroup_line_batch_create_with_format(sh, pass, g_formats.dynlines_color);
@@ -288,7 +288,7 @@ DRWShadingGroup *shgroup_instance_screenspace(DRWPass *pass, struct Gwn_Batch *g
DRW_shgroup_instance_format(g_formats.instance_screenspace, {
{"world_pos", DRW_ATTRIB_FLOAT, 3},
- {"color" , DRW_ATTRIB_FLOAT, 3}
+ {"color", DRW_ATTRIB_FLOAT, 3}
});
DRWShadingGroup *grp = DRW_shgroup_instance_create(sh, pass, geom, g_formats.instance_screenspace);
@@ -307,7 +307,7 @@ DRWShadingGroup *shgroup_instance_solid(DRWPass *pass, struct Gwn_Batch *geom)
DRW_shgroup_instance_format(g_formats.instance_color, {
{"InstanceModelMatrix", DRW_ATTRIB_FLOAT, 16},
- {"color" , DRW_ATTRIB_FLOAT, 4}
+ {"color", DRW_ATTRIB_FLOAT, 4}
});
DRWShadingGroup *grp = DRW_shgroup_instance_create(sh, pass, geom, g_formats.instance_color);
@@ -322,7 +322,7 @@ DRWShadingGroup *shgroup_instance_wire(DRWPass *pass, struct Gwn_Batch *geom)
DRW_shgroup_instance_format(g_formats.instance_color, {
{"InstanceModelMatrix", DRW_ATTRIB_FLOAT, 16},
- {"color" , DRW_ATTRIB_FLOAT, 4}
+ {"color", DRW_ATTRIB_FLOAT, 4}
});
DRWShadingGroup *grp = DRW_shgroup_instance_create(sh, pass, geom, g_formats.instance_color);
@@ -335,8 +335,8 @@ DRWShadingGroup *shgroup_instance_screen_aligned(DRWPass *pass, struct Gwn_Batch
GPUShader *sh = GPU_shader_get_builtin_shader(GPU_SHADER_3D_INSTANCE_SCREEN_ALIGNED);
DRW_shgroup_instance_format(g_formats.instance_screen_aligned, {
- {"color" , DRW_ATTRIB_FLOAT, 3},
- {"size" , DRW_ATTRIB_FLOAT, 1},
+ {"color", DRW_ATTRIB_FLOAT, 3},
+ {"size", DRW_ATTRIB_FLOAT, 1},
{"InstanceModelMatrix", DRW_ATTRIB_FLOAT, 16}
});
@@ -351,8 +351,8 @@ DRWShadingGroup *shgroup_instance_axis_names(DRWPass *pass, struct Gwn_Batch *ge
GPUShader *sh = GPU_shader_get_builtin_shader(GPU_SHADER_3D_INSTANCE_SCREEN_ALIGNED_AXIS);
DRW_shgroup_instance_format(g_formats.instance_screen_aligned, {
- {"color" , DRW_ATTRIB_FLOAT, 3},
- {"size" , DRW_ATTRIB_FLOAT, 1},
+ {"color", DRW_ATTRIB_FLOAT, 3},
+ {"size", DRW_ATTRIB_FLOAT, 1},
{"InstanceModelMatrix", DRW_ATTRIB_FLOAT, 16}
});
@@ -367,8 +367,8 @@ DRWShadingGroup *shgroup_instance_scaled(DRWPass *pass, struct Gwn_Batch *geom)
GPUShader *sh_inst = GPU_shader_get_builtin_shader(GPU_SHADER_INSTANCE_VARIYING_COLOR_VARIYING_SCALE);
DRW_shgroup_instance_format(g_formats.instance_scaled, {
- {"color" , DRW_ATTRIB_FLOAT, 3},
- {"size" , DRW_ATTRIB_FLOAT, 3},
+ {"color", DRW_ATTRIB_FLOAT, 3},
+ {"size", DRW_ATTRIB_FLOAT, 3},
{"InstanceModelMatrix", DRW_ATTRIB_FLOAT, 16}
});
@@ -382,8 +382,8 @@ DRWShadingGroup *shgroup_instance(DRWPass *pass, struct Gwn_Batch *geom)
GPUShader *sh_inst = GPU_shader_get_builtin_shader(GPU_SHADER_INSTANCE_VARIYING_COLOR_VARIYING_SIZE);
DRW_shgroup_instance_format(g_formats.instance_sized, {
- {"color" , DRW_ATTRIB_FLOAT, 3},
- {"size" , DRW_ATTRIB_FLOAT, 1},
+ {"color", DRW_ATTRIB_FLOAT, 3},
+ {"size", DRW_ATTRIB_FLOAT, 1},
{"InstanceModelMatrix", DRW_ATTRIB_FLOAT, 16}
});
@@ -397,8 +397,8 @@ DRWShadingGroup *shgroup_instance_outline(DRWPass *pass, struct Gwn_Batch *geom,
GPUShader *sh_inst = GPU_shader_get_builtin_shader(GPU_SHADER_INSTANCE_VARIYING_ID_VARIYING_SIZE);
DRW_shgroup_instance_format(g_formats.instance_outline, {
- {"callId" , DRW_ATTRIB_INT, 1},
- {"size" , DRW_ATTRIB_FLOAT, 1},
+ {"callId", DRW_ATTRIB_INT, 1},
+ {"size", DRW_ATTRIB_FLOAT, 1},
{"InstanceModelMatrix", DRW_ATTRIB_FLOAT, 16}
});
@@ -413,10 +413,10 @@ DRWShadingGroup *shgroup_camera_instance(DRWPass *pass, struct Gwn_Batch *geom)
GPUShader *sh_inst = GPU_shader_get_builtin_shader(GPU_SHADER_CAMERA);
DRW_shgroup_instance_format(g_formats.instance_camera, {
- {"color" , DRW_ATTRIB_FLOAT, 3},
- {"corners" , DRW_ATTRIB_FLOAT, 8},
- {"depth" , DRW_ATTRIB_FLOAT, 1},
- {"tria" , DRW_ATTRIB_FLOAT, 4},
+ {"color", DRW_ATTRIB_FLOAT, 3},
+ {"corners", DRW_ATTRIB_FLOAT, 8},
+ {"depth", DRW_ATTRIB_FLOAT, 1},
+ {"tria", DRW_ATTRIB_FLOAT, 4},
{"InstanceModelMatrix", DRW_ATTRIB_FLOAT, 16}
});
@@ -431,9 +431,9 @@ DRWShadingGroup *shgroup_distance_lines_instance(DRWPass *pass, struct Gwn_Batch
static float point_size = 4.0f;
DRW_shgroup_instance_format(g_formats.instance_distance_lines, {
- {"color" , DRW_ATTRIB_FLOAT, 3},
- {"start" , DRW_ATTRIB_FLOAT, 1},
- {"end" , DRW_ATTRIB_FLOAT, 1},
+ {"color", DRW_ATTRIB_FLOAT, 3},
+ {"start", DRW_ATTRIB_FLOAT, 1},
+ {"end", DRW_ATTRIB_FLOAT, 1},
{"InstanceModelMatrix", DRW_ATTRIB_FLOAT, 16}
});
@@ -450,7 +450,7 @@ DRWShadingGroup *shgroup_spot_instance(DRWPass *pass, struct Gwn_Batch *geom)
static const int False = false;
DRW_shgroup_instance_format(g_formats.instance_spot, {
- {"color" , DRW_ATTRIB_FLOAT, 3},
+ {"color", DRW_ATTRIB_FLOAT, 3},
{"InstanceModelMatrix", DRW_ATTRIB_FLOAT, 16}
});
@@ -472,12 +472,13 @@ DRWShadingGroup *shgroup_instance_bone_axes(DRWPass *pass)
DRW_shgroup_instance_format(g_formats.instance_color, {
{"InstanceModelMatrix", DRW_ATTRIB_FLOAT, 16},
- {"color" , DRW_ATTRIB_FLOAT, 4}
+ {"color", DRW_ATTRIB_FLOAT, 4}
});
- DRWShadingGroup *grp = DRW_shgroup_instance_create(g_shaders.bone_axes,
- pass, DRW_cache_bone_arrows_get(),
- g_formats.instance_color);
+ DRWShadingGroup *grp = DRW_shgroup_instance_create(
+ g_shaders.bone_axes,
+ pass, DRW_cache_bone_arrows_get(),
+ g_formats.instance_color);
DRW_shgroup_uniform_vec3(grp, "screenVecs[0]", DRW_viewport_screenvecs_get(), 2);
return grp;
@@ -492,15 +493,16 @@ DRWShadingGroup *shgroup_instance_bone_envelope_outline(DRWPass *pass)
}
DRW_shgroup_instance_format(g_formats.instance_bone_envelope_outline, {
- {"headSphere" , DRW_ATTRIB_FLOAT, 4},
- {"tailSphere" , DRW_ATTRIB_FLOAT, 4},
- {"outlineColorSize" , DRW_ATTRIB_FLOAT, 4},
- {"xAxis" , DRW_ATTRIB_FLOAT, 3}
+ {"headSphere", DRW_ATTRIB_FLOAT, 4},
+ {"tailSphere", DRW_ATTRIB_FLOAT, 4},
+ {"outlineColorSize", DRW_ATTRIB_FLOAT, 4},
+ {"xAxis", DRW_ATTRIB_FLOAT, 3}
});
- DRWShadingGroup *grp = DRW_shgroup_instance_create(g_shaders.bone_envelope_outline,
- pass, DRW_cache_bone_envelope_outline_get(),
- g_formats.instance_bone_envelope_outline);
+ DRWShadingGroup *grp = DRW_shgroup_instance_create(
+ g_shaders.bone_envelope_outline,
+ pass, DRW_cache_bone_envelope_outline_get(),
+ g_formats.instance_bone_envelope_outline);
DRW_shgroup_uniform_vec2(grp, "viewportSize", DRW_viewport_size_get(), 1);
return grp;
@@ -515,14 +517,15 @@ DRWShadingGroup *shgroup_instance_bone_envelope_distance(DRWPass *pass)
}
DRW_shgroup_instance_format(g_formats.instance_bone_envelope_distance, {
- {"headSphere" , DRW_ATTRIB_FLOAT, 4},
- {"tailSphere" , DRW_ATTRIB_FLOAT, 4},
- {"xAxis" , DRW_ATTRIB_FLOAT, 3}
+ {"headSphere", DRW_ATTRIB_FLOAT, 4},
+ {"tailSphere", DRW_ATTRIB_FLOAT, 4},
+ {"xAxis", DRW_ATTRIB_FLOAT, 3}
});
- DRWShadingGroup *grp = DRW_shgroup_instance_create(g_shaders.bone_envelope_distance,
- pass, DRW_cache_bone_envelope_solid_get(),
- g_formats.instance_bone_envelope_distance);
+ DRWShadingGroup *grp = DRW_shgroup_instance_create(
+ g_shaders.bone_envelope_distance,
+ pass, DRW_cache_bone_envelope_solid_get(),
+ g_formats.instance_bone_envelope_distance);
return grp;
}
@@ -536,16 +539,17 @@ DRWShadingGroup *shgroup_instance_bone_envelope_solid(DRWPass *pass)
}
DRW_shgroup_instance_format(g_formats.instance_bone_envelope, {
- {"headSphere" , DRW_ATTRIB_FLOAT, 4},
- {"tailSphere" , DRW_ATTRIB_FLOAT, 4},
- {"boneColor" , DRW_ATTRIB_FLOAT, 3},
- {"stateColor" , DRW_ATTRIB_FLOAT, 3},
- {"xAxis" , DRW_ATTRIB_FLOAT, 3}
+ {"headSphere", DRW_ATTRIB_FLOAT, 4},
+ {"tailSphere", DRW_ATTRIB_FLOAT, 4},
+ {"boneColor", DRW_ATTRIB_FLOAT, 3},
+ {"stateColor", DRW_ATTRIB_FLOAT, 3},
+ {"xAxis", DRW_ATTRIB_FLOAT, 3}
});
- DRWShadingGroup *grp = DRW_shgroup_instance_create(g_shaders.bone_envelope,
- pass, DRW_cache_bone_envelope_solid_get(),
- g_formats.instance_bone_envelope);
+ DRWShadingGroup *grp = DRW_shgroup_instance_create(
+ g_shaders.bone_envelope,
+ pass, DRW_cache_bone_envelope_solid_get(),
+ g_formats.instance_bone_envelope);
return grp;
}
@@ -559,14 +563,15 @@ DRWShadingGroup *shgroup_instance_mball_handles(DRWPass *pass)
}
DRW_shgroup_instance_format(g_formats.instance_mball_handles, {
- {"ScaleTranslationMatrix" , DRW_ATTRIB_FLOAT, 12},
- {"radius" , DRW_ATTRIB_FLOAT, 1},
- {"color" , DRW_ATTRIB_FLOAT, 3}
+ {"ScaleTranslationMatrix", DRW_ATTRIB_FLOAT, 12},
+ {"radius", DRW_ATTRIB_FLOAT, 1},
+ {"color", DRW_ATTRIB_FLOAT, 3}
});
- DRWShadingGroup *grp = DRW_shgroup_instance_create(g_shaders.mball_handles, pass,
- DRW_cache_screenspace_circle_get(),
- g_formats.instance_mball_handles);
+ DRWShadingGroup *grp = DRW_shgroup_instance_create(
+ g_shaders.mball_handles, pass,
+ DRW_cache_screenspace_circle_get(),
+ g_formats.instance_mball_handles);
DRW_shgroup_uniform_vec3(grp, "screen_vecs[0]", DRW_viewport_screenvecs_get(), 2);
return grp;
@@ -585,11 +590,12 @@ DRWShadingGroup *shgroup_instance_bone_shape_outline(DRWPass *pass, struct Gwn_B
DRW_shgroup_instance_format(g_formats.instance_bone_outline, {
{"InstanceModelMatrix", DRW_ATTRIB_FLOAT, 16},
- {"outlineColorSize" , DRW_ATTRIB_FLOAT, 4}
+ {"outlineColorSize", DRW_ATTRIB_FLOAT, 4}
});
- DRWShadingGroup *grp = DRW_shgroup_instance_create(g_shaders.shape_outline,
- pass, geom, g_formats.instance_bone_outline);
+ DRWShadingGroup *grp = DRW_shgroup_instance_create(
+ g_shaders.shape_outline,
+ pass, geom, g_formats.instance_bone_outline);
DRW_shgroup_uniform_vec2(grp, "viewportSize", DRW_viewport_size_get(), 1);
return grp;
@@ -605,12 +611,13 @@ DRWShadingGroup *shgroup_instance_bone_shape_solid(DRWPass *pass, struct Gwn_Bat
DRW_shgroup_instance_format(g_formats.instance_bone, {
{"InstanceModelMatrix", DRW_ATTRIB_FLOAT, 16},
- {"boneColor" , DRW_ATTRIB_FLOAT, 3},
- {"stateColor" , DRW_ATTRIB_FLOAT, 3}
+ {"boneColor", DRW_ATTRIB_FLOAT, 3},
+ {"stateColor", DRW_ATTRIB_FLOAT, 3}
});
- DRWShadingGroup *grp = DRW_shgroup_instance_create(g_shaders.shape_solid,
- pass, geom, g_formats.instance_bone);
+ DRWShadingGroup *grp = DRW_shgroup_instance_create(
+ g_shaders.shape_solid,
+ pass, geom, g_formats.instance_bone);
DRW_shgroup_uniform_vec2(grp, "viewportSize", DRW_viewport_size_get(), 1);
return grp;
@@ -626,12 +633,13 @@ DRWShadingGroup *shgroup_instance_bone_sphere_solid(DRWPass *pass)
DRW_shgroup_instance_format(g_formats.instance_bone, {
{"InstanceModelMatrix", DRW_ATTRIB_FLOAT, 16},
- {"boneColor" , DRW_ATTRIB_FLOAT, 3},
- {"stateColor" , DRW_ATTRIB_FLOAT, 3}
+ {"boneColor", DRW_ATTRIB_FLOAT, 3},
+ {"stateColor", DRW_ATTRIB_FLOAT, 3}
});
- DRWShadingGroup *grp = DRW_shgroup_instance_create(g_shaders.bone_sphere,
- pass, DRW_cache_bone_point_get(), g_formats.instance_bone);
+ DRWShadingGroup *grp = DRW_shgroup_instance_create(
+ g_shaders.bone_sphere,
+ pass, DRW_cache_bone_point_get(), g_formats.instance_bone);
return grp;
}
@@ -646,12 +654,13 @@ DRWShadingGroup *shgroup_instance_bone_sphere_outline(DRWPass *pass)
DRW_shgroup_instance_format(g_formats.instance_bone_outline, {
{"InstanceModelMatrix", DRW_ATTRIB_FLOAT, 16},
- {"outlineColorSize" , DRW_ATTRIB_FLOAT, 4}
+ {"outlineColorSize", DRW_ATTRIB_FLOAT, 4}
});
- DRWShadingGroup *grp = DRW_shgroup_instance_create(g_shaders.bone_sphere_outline,
- pass, DRW_cache_bone_point_wire_outline_get(),
- g_formats.instance_bone_outline);
+ DRWShadingGroup *grp = DRW_shgroup_instance_create(
+ g_shaders.bone_sphere_outline,
+ pass, DRW_cache_bone_point_wire_outline_get(),
+ g_formats.instance_bone_outline);
DRW_shgroup_uniform_vec2(grp, "viewportSize", DRW_viewport_size_get(), 1);
return grp;
@@ -667,16 +676,17 @@ DRWShadingGroup *shgroup_instance_bone_stick(DRWPass *pass)
DRW_shgroup_instance_format(g_formats.instance_bone_stick, {
{"boneStart", DRW_ATTRIB_FLOAT, 3},
- {"boneEnd" , DRW_ATTRIB_FLOAT, 3},
+ {"boneEnd", DRW_ATTRIB_FLOAT, 3},
{"wireColor", DRW_ATTRIB_FLOAT, 4}, /* TODO port theses to uchar color */
{"boneColor", DRW_ATTRIB_FLOAT, 4},
{"headColor", DRW_ATTRIB_FLOAT, 4},
{"tailColor", DRW_ATTRIB_FLOAT, 4}
});
- DRWShadingGroup *grp = DRW_shgroup_instance_create(g_shaders.bone_stick,
- pass, DRW_cache_bone_stick_get(),
- g_formats.instance_bone_stick);
+ DRWShadingGroup *grp = DRW_shgroup_instance_create(
+ g_shaders.bone_stick,
+ pass, DRW_cache_bone_stick_get(),
+ g_formats.instance_bone_stick);
DRW_shgroup_uniform_vec2(grp, "viewportSize", DRW_viewport_size_get(), 1);
return grp;
@@ -727,10 +737,10 @@ int DRW_object_wire_theme_get(Object *ob, ViewLayer *view_layer, float **r_color
case TH_ACTIVE: *r_color = ts.colorActive; break;
case TH_SELECT: *r_color = ts.colorSelect; break;
case TH_TRANSFORM: *r_color = ts.colorTransform; break;
- case OB_SPEAKER: *r_color = ts.colorSpeaker; break;
- case OB_CAMERA: *r_color = ts.colorCamera; break;
- case OB_EMPTY: *r_color = ts.colorEmpty; break;
- case OB_LAMP: *r_color = ts.colorLamp; break;
+ case TH_SPEAKER: *r_color = ts.colorSpeaker; break;
+ case TH_CAMERA: *r_color = ts.colorCamera; break;
+ case TH_EMPTY: *r_color = ts.colorEmpty; break;
+ case TH_LAMP: *r_color = ts.colorLamp; break;
default: *r_color = ts.colorWire; break;
}
}
@@ -749,10 +759,10 @@ float *DRW_color_background_blend_get(int theme_id)
case TH_ACTIVE: ret = colors[1]; break;
case TH_SELECT: ret = colors[2]; break;
case TH_TRANSFORM: ret = colors[5]; break;
- case OB_SPEAKER: ret = colors[6]; break;
- case OB_CAMERA: ret = colors[7]; break;
- case OB_EMPTY: ret = colors[8]; break;
- case OB_LAMP: ret = colors[9]; break;
+ case TH_SPEAKER: ret = colors[6]; break;
+ case TH_CAMERA: ret = colors[7]; break;
+ case TH_EMPTY: ret = colors[8]; break;
+ case TH_LAMP: ret = colors[9]; break;
default: ret = colors[10]; break;
}
diff --git a/source/blender/draw/intern/draw_debug.c b/source/blender/draw/intern/draw_debug.c
new file mode 100644
index 00000000000..b30f7936758
--- /dev/null
+++ b/source/blender/draw/intern/draw_debug.c
@@ -0,0 +1,151 @@
+/*
+ * Copyright 2018, Blender Foundation.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Contributor(s): Blender Institute
+ *
+ */
+
+/** \file blender/draw/intern/draw_debug.c
+ * \ingroup draw
+ *
+ * \brief Simple API to draw debug shapes in the viewport.
+ */
+
+#include "MEM_guardedalloc.h"
+
+#include "DNA_object_types.h"
+
+#include "BLI_link_utils.h"
+
+#include "GPU_immediate.h"
+
+#include "draw_debug.h"
+#include "draw_manager.h"
+
+/* --------- Register --------- */
+
+/* Matrix applied to all points before drawing. Could be a stack if needed. */
+static float g_modelmat[4][4];
+
+void DRW_debug_modelmat_reset(void)
+{
+ unit_m4(g_modelmat);
+}
+
+void DRW_debug_modelmat(const float modelmat[4][4])
+{
+ copy_m4_m4(g_modelmat, modelmat);
+}
+
+void DRW_debug_line_v3v3(const float v1[3], const float v2[3], const float color[4])
+{
+ DRWDebugLine *line = MEM_mallocN(sizeof(DRWDebugLine), "DRWDebugLine");
+ mul_v3_m4v3(line->pos[0], g_modelmat, v1);
+ mul_v3_m4v3(line->pos[1], g_modelmat, v2);
+ copy_v4_v4(line->color, color);
+ BLI_LINKS_PREPEND(DST.debug.lines, line);
+}
+
+void DRW_debug_polygon_v3(const float (*v)[3], const int vert_len, const float color[4])
+{
+ BLI_assert(vert_len > 1);
+
+ for (int i = 0; i < vert_len; ++i) {
+ DRW_debug_line_v3v3(v[i], v[(i+1)%vert_len], color);
+ }
+}
+
+/* NOTE: g_modelmat is still applied on top. */
+void DRW_debug_m4(const float m[4][4])
+{
+ float v0[3] = {0.0f, 0.0f, 0.0f};
+ float v1[3] = {1.0f, 0.0f, 0.0f};
+ float v2[3] = {0.0f, 1.0f, 0.0f};
+ float v3[3] = {0.0f, 0.0f, 1.0f};
+
+ mul_m4_v3(m, v0);
+ mul_m4_v3(m, v1);
+ mul_m4_v3(m, v2);
+ mul_m4_v3(m, v3);
+
+ DRW_debug_line_v3v3(v0, v1, (float[4]){1.0f, 0.0f, 0.0f, 1.0f});
+ DRW_debug_line_v3v3(v0, v2, (float[4]){0.0f, 1.0f, 0.0f, 1.0f});
+ DRW_debug_line_v3v3(v0, v3, (float[4]){0.0f, 0.0f, 1.0f, 1.0f});
+}
+
+void DRW_debug_bbox(const BoundBox *bbox, const float color[4])
+{
+ DRW_debug_line_v3v3(bbox->vec[0], bbox->vec[1], color);
+ DRW_debug_line_v3v3(bbox->vec[1], bbox->vec[2], color);
+ DRW_debug_line_v3v3(bbox->vec[2], bbox->vec[3], color);
+ DRW_debug_line_v3v3(bbox->vec[3], bbox->vec[0], color);
+
+ DRW_debug_line_v3v3(bbox->vec[4], bbox->vec[5], color);
+ DRW_debug_line_v3v3(bbox->vec[5], bbox->vec[6], color);
+ DRW_debug_line_v3v3(bbox->vec[6], bbox->vec[7], color);
+ DRW_debug_line_v3v3(bbox->vec[7], bbox->vec[4], color);
+
+ DRW_debug_line_v3v3(bbox->vec[0], bbox->vec[4], color);
+ DRW_debug_line_v3v3(bbox->vec[1], bbox->vec[5], color);
+ DRW_debug_line_v3v3(bbox->vec[2], bbox->vec[6], color);
+ DRW_debug_line_v3v3(bbox->vec[3], bbox->vec[7], color);
+}
+
+/* --------- Render --------- */
+
+static void drw_debug_draw_lines(void)
+{
+ int count = BLI_linklist_count((LinkNode *)DST.debug.lines);
+
+ if (count == 0) {
+ return;
+ }
+
+ Gwn_VertFormat *vert_format = immVertexFormat();
+ uint pos = GWN_vertformat_attr_add(vert_format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT);
+ uint col = GWN_vertformat_attr_add(vert_format, "color", GWN_COMP_F32, 4, GWN_FETCH_FLOAT);
+
+ immBindBuiltinProgram(GPU_SHADER_3D_FLAT_COLOR);
+
+ immBegin(GWN_PRIM_LINES, count * 2);
+
+ while (DST.debug.lines) {
+ void *next = DST.debug.lines->next;
+
+ immAttrib4fv(col, DST.debug.lines->color);
+ immVertex3fv(pos, DST.debug.lines->pos[0]);
+
+ immAttrib4fv(col, DST.debug.lines->color);
+ immVertex3fv(pos, DST.debug.lines->pos[1]);
+
+ MEM_freeN(DST.debug.lines);
+ DST.debug.lines = next;
+ }
+ immEnd();
+
+ immUnbindProgram();
+}
+
+void drw_debug_draw(void)
+{
+ drw_debug_draw_lines();
+}
+
+void drw_debug_init(void)
+{
+ DRW_debug_modelmat_reset();
+} \ No newline at end of file
diff --git a/source/blender/draw/intern/draw_debug.h b/source/blender/draw/intern/draw_debug.h
new file mode 100644
index 00000000000..1dab431fc88
--- /dev/null
+++ b/source/blender/draw/intern/draw_debug.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2018, Blender Foundation.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Contributor(s): Blender Institute
+ *
+ */
+
+/** \file draw_debug.h
+ * \ingroup draw
+ */
+
+#ifndef __DRAW_DEBUG_H__
+#define __DRAW_DEBUG_H__
+
+struct BoundBox;
+
+void DRW_debug_modelmat_reset(void);
+void DRW_debug_modelmat(const float modelmat[4][4]);
+
+void DRW_debug_line_v3v3(const float v1[3], const float v2[3], const float color[4]);
+void DRW_debug_polygon_v3(const float (*v)[3], const int vert_len, const float color[4]);
+void DRW_debug_m4(const float m[4][4]);
+void DRW_debug_bbox(const BoundBox *bbox, const float color[4]);
+
+#endif /* __DRAW_DEBUG_H__ */
diff --git a/source/blender/draw/intern/draw_instance_data.h b/source/blender/draw/intern/draw_instance_data.h
index a4a02941ddb..bc3c0c2e04c 100644
--- a/source/blender/draw/intern/draw_instance_data.h
+++ b/source/blender/draw/intern/draw_instance_data.h
@@ -31,7 +31,7 @@
#include "GPU_batch.h"
-#define MAX_INSTANCE_DATA_SIZE 42 /* Can be adjusted for more */
+#define MAX_INSTANCE_DATA_SIZE 48 /* Can be adjusted for more */
typedef struct DRWInstanceData DRWInstanceData;
typedef struct DRWInstanceDataList DRWInstanceDataList;
diff --git a/source/blender/draw/intern/draw_manager.c b/source/blender/draw/intern/draw_manager.c
index 29adb6b47f4..a57a91363eb 100644
--- a/source/blender/draw/intern/draw_manager.c
+++ b/source/blender/draw/intern/draw_manager.c
@@ -587,7 +587,8 @@ static void drw_viewport_var_init(void)
void DRW_viewport_matrix_get(float mat[4][4], DRWViewportMatrixType type)
{
BLI_assert(type >= 0 && type < DRW_MAT_COUNT);
- BLI_assert(((DST.override_mat & (1 << type)) != 0) || DST.draw_ctx.rv3d != NULL); /* Can't use this in render mode. */
+ /* Can't use this in render mode. */
+ BLI_assert(((DST.override_mat & (1 << type)) != 0) || DST.draw_ctx.rv3d != NULL);
copy_m4_m4(mat, DST.view_data.matstate.mat[type]);
}
@@ -700,7 +701,8 @@ void *DRW_view_layer_engine_data_get(DrawEngineType *engine_type)
return NULL;
}
-void **DRW_view_layer_engine_data_ensure_ex(ViewLayer *view_layer, DrawEngineType *engine_type, void (*callback)(void *storage))
+void **DRW_view_layer_engine_data_ensure_ex(
+ ViewLayer *view_layer, DrawEngineType *engine_type, void (*callback)(void *storage))
{
ViewLayerEngineData *sled;
@@ -1023,7 +1025,7 @@ static void drw_engines_enable_from_engine(RenderEngineType *engine_type, int dr
case OB_SOLID:
case OB_TEXTURE:
- if (shading_flags & V3D_SHADING_SEE_THROUGH) {
+ if (shading_flags & V3D_SHADING_XRAY) {
use_drw_engine(&draw_engine_workbench_transparent);
}
else {
@@ -1273,6 +1275,8 @@ void DRW_draw_render_loop_ex(
/* Update ubos */
DRW_globals_update();
+ drw_debug_init();
+
/* No framebuffer allowed before drawing. */
BLI_assert(GPU_framebuffer_current_get() == 0);
@@ -1340,6 +1344,8 @@ void DRW_draw_render_loop_ex(
DRW_state_reset();
+ drw_debug_draw();
+
drw_engines_draw_text();
if (DST.draw_ctx.evil_C) {
@@ -1558,7 +1564,8 @@ static void draw_select_framebuffer_setup(const rcti *rect)
}
if (g_select_buffer.texture_depth == NULL) {
- g_select_buffer.texture_depth = GPU_texture_create_2D(BLI_rcti_size_x(rect), BLI_rcti_size_y(rect), GPU_DEPTH_COMPONENT24, NULL, NULL);
+ g_select_buffer.texture_depth = GPU_texture_create_2D(
+ BLI_rcti_size_x(rect), BLI_rcti_size_y(rect), GPU_DEPTH_COMPONENT24, NULL, NULL);
GPU_framebuffer_texture_attach(g_select_buffer.framebuffer, g_select_buffer.texture_depth, 0, 0);
diff --git a/source/blender/draw/intern/draw_manager.h b/source/blender/draw/intern/draw_manager.h
index 0f9a68552fe..267826d2d9a 100644
--- a/source/blender/draw/intern/draw_manager.h
+++ b/source/blender/draw/intern/draw_manager.h
@@ -272,6 +272,14 @@ typedef struct ViewUboStorage {
float clipplanes[2][4];
} ViewUboStorage;
+/* ------------- DRAW DEBUG ------------ */
+
+typedef struct DRWDebugLine {
+ struct DRWDebugLine *next; /* linked list */
+ float pos[2][3];
+ float color[4];
+} DRWDebugLine;
+
/* ------------- DRAW MANAGER ------------ */
#define MAX_CLIP_PLANES 6 /* GL_MAX_CLIP_PLANES is at least 6 */
@@ -359,6 +367,11 @@ typedef struct DRWManager {
char *bound_ubo_slots;
int bind_ubo_inc;
} RST;
+
+ struct {
+ /* TODO(fclem) optimize: use chunks. */
+ DRWDebugLine *lines;
+ } debug;
} DRWManager;
extern DRWManager DST; /* TODO : get rid of this and allow multithreaded rendering */
@@ -374,4 +387,7 @@ void *drw_viewport_engine_data_ensure(void *engine_type);
void drw_state_set(DRWState state);
+void drw_debug_draw(void);
+void drw_debug_init(void);
+
#endif /* __DRAW_MANAGER_H__ */
diff --git a/source/blender/draw/intern/draw_manager_data.c b/source/blender/draw/intern/draw_manager_data.c
index 1e2036714bf..b4dce47413e 100644
--- a/source/blender/draw/intern/draw_manager_data.c
+++ b/source/blender/draw/intern/draw_manager_data.c
@@ -797,7 +797,8 @@ DRWShadingGroup *DRW_shgroup_point_batch_create(struct GPUShader *shader, DRWPas
return shgroup;
}
-DRWShadingGroup *DRW_shgroup_line_batch_create_with_format(struct GPUShader *shader, DRWPass *pass, Gwn_VertFormat *format)
+DRWShadingGroup *DRW_shgroup_line_batch_create_with_format(
+ struct GPUShader *shader, DRWPass *pass, Gwn_VertFormat *format)
{
DRWShadingGroup *shgroup = drw_shgroup_create_ex(shader, pass);
shgroup->type = DRW_SHG_LINE_BATCH;
diff --git a/source/blender/draw/intern/draw_manager_exec.c b/source/blender/draw/intern/draw_manager_exec.c
index 9f4adac0106..110691373ab 100644
--- a/source/blender/draw/intern/draw_manager_exec.c
+++ b/source/blender/draw/intern/draw_manager_exec.c
@@ -221,7 +221,8 @@ void drw_state_set(DRWState state)
int test;
if (CHANGED_ANY_STORE_VAR(
DRW_STATE_BLEND | DRW_STATE_BLEND_PREMUL | DRW_STATE_ADDITIVE |
- DRW_STATE_MULTIPLY | DRW_STATE_TRANSMISSION | DRW_STATE_ADDITIVE_FULL,
+ DRW_STATE_MULTIPLY | DRW_STATE_TRANSMISSION | DRW_STATE_ADDITIVE_FULL |
+ DRW_STATE_TRANSPARENT_REVEALAGE,
test))
{
if (test) {
@@ -240,6 +241,9 @@ void drw_state_set(DRWState state)
else if ((state & DRW_STATE_TRANSMISSION) != 0) {
glBlendFunc(GL_ONE, GL_SRC_ALPHA);
}
+ else if ((state & DRW_STATE_TRANSPARENT_REVEALAGE) != 0) {
+ glBlendFunc(GL_ZERO, GL_ONE_MINUS_SRC_COLOR);
+ }
else if ((state & DRW_STATE_ADDITIVE) != 0) {
/* Do not let alpha accumulate but premult the source RGB by it. */
glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE, /* RGB */
@@ -329,8 +333,8 @@ void drw_state_set(DRWState state)
}
else if ((state & DRW_STATE_WRITE_STENCIL_SHADOW_FAIL) != 0) {
glStencilMask(0xFF);
- glStencilOpSeparate(GL_BACK, GL_KEEP, GL_INCR_WRAP, GL_KEEP);
- glStencilOpSeparate(GL_FRONT, GL_KEEP, GL_DECR_WRAP, GL_KEEP);
+ glStencilOpSeparate(GL_BACK, GL_KEEP, GL_DECR_WRAP, GL_KEEP);
+ glStencilOpSeparate(GL_FRONT, GL_KEEP, GL_INCR_WRAP, GL_KEEP);
}
/* Stencil Test */
else if ((state & (DRW_STATE_STENCIL_EQUAL | DRW_STATE_STENCIL_NEQUAL)) != 0) {
@@ -703,6 +707,12 @@ bool DRW_culling_plane_test(float plane[4])
return false;
}
+void DRW_culling_frustum_corners_get(BoundBox *corners)
+{
+ draw_clipping_setup_from_view();
+ memcpy(corners, &DST.clipping.frustum_corners, sizeof(BoundBox));
+}
+
/** \} */
/* -------------------------------------------------------------------- */
@@ -818,7 +828,8 @@ static void draw_geometry_execute_ex(
}
/* step 2 : bind vertex array & draw */
- GWN_batch_program_set_no_use(geom, GPU_shader_get_program(shgroup->shader), GPU_shader_get_interface(shgroup->shader));
+ GWN_batch_program_set_no_use(
+ geom, GPU_shader_get_program(shgroup->shader), GPU_shader_get_interface(shgroup->shader));
/* XXX hacking gawain. we don't want to call glUseProgram! (huge performance loss) */
geom->program_in_use = true;
diff --git a/source/blender/draw/intern/draw_view.c b/source/blender/draw/intern/draw_view.c
index 2c4e5f8b151..726d77a9925 100644
--- a/source/blender/draw/intern/draw_view.c
+++ b/source/blender/draw/intern/draw_view.c
@@ -682,7 +682,7 @@ void DRW_draw_cursor(void)
immUniformThemeColor3(TH_VIEW_OVERLAY);
immBegin(GWN_PRIM_LINES, 12);
- const float scale = ED_view3d_pixel_size(rv3d, cursor->location) * 20;
+ const float scale = ED_view3d_pixel_size_no_ui_scale(rv3d, cursor->location) * U.widget_unit;
#define CURSOR_VERT(axis_vec, axis, fac) \
immVertex3f( \
diff --git a/source/blender/draw/modes/edit_metaball_mode.c b/source/blender/draw/modes/edit_metaball_mode.c
index 8ac3cff2e1c..c0c4e7e4295 100644
--- a/source/blender/draw/modes/edit_metaball_mode.c
+++ b/source/blender/draw/modes/edit_metaball_mode.c
@@ -116,7 +116,9 @@ static void EDIT_METABALL_cache_init(void *vedata)
{
/* Create a pass */
- DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL | DRW_STATE_BLEND | DRW_STATE_WIRE;
+ DRWState state = (
+ DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL |
+ DRW_STATE_BLEND | DRW_STATE_WIRE);
psl->pass = DRW_pass_create("My Pass", state);
/* Create a shadingGroup using a function in draw_common.c or custom one */
diff --git a/source/blender/draw/modes/edit_surface_mode.c b/source/blender/draw/modes/edit_surface_mode.c
index b5cbb1baa55..7074ba3d024 100644
--- a/source/blender/draw/modes/edit_surface_mode.c
+++ b/source/blender/draw/modes/edit_surface_mode.c
@@ -149,7 +149,9 @@ static void EDIT_SURFACE_cache_init(void *vedata)
{
/* Create a pass */
- DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL | DRW_STATE_BLEND | DRW_STATE_WIRE;
+ DRWState state = (
+ DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL |
+ DRW_STATE_BLEND | DRW_STATE_WIRE);
psl->pass = DRW_pass_create("My Pass", state);
/* Create a shadingGroup using a function in draw_common.c or custom one */
diff --git a/source/blender/draw/modes/object_mode.c b/source/blender/draw/modes/object_mode.c
index 58cdfd4e413..52749a5429f 100644
--- a/source/blender/draw/modes/object_mode.c
+++ b/source/blender/draw/modes/object_mode.c
@@ -175,7 +175,8 @@ typedef struct OBJECT_PrivateData {
DRWShadingGroup *lamp_distance;
DRWShadingGroup *lamp_buflimit;
DRWShadingGroup *lamp_buflimit_points;
- DRWShadingGroup *lamp_area;
+ DRWShadingGroup *lamp_area_square;
+ DRWShadingGroup *lamp_area_disk;
DRWShadingGroup *lamp_hemi;
DRWShadingGroup *lamp_spot_cone;
DRWShadingGroup *lamp_spot_blend;
@@ -288,6 +289,7 @@ enum {
PLANE_YZ = (1 << 6),
CLIP_ZPOS = (1 << 7),
CLIP_ZNEG = (1 << 8),
+ GRID_BACK = (1 << 9),
};
/* *********** FUNCTIONS *********** */
@@ -446,18 +448,21 @@ static void OBJECT_engine_init(void *vedata)
e_data.grid_flag |= SHOW_AXIS_Y;
e_data.grid_flag |= SHOW_AXIS_Z;
e_data.grid_flag |= SHOW_GRID;
+ e_data.grid_flag |= GRID_BACK;
}
else if (ELEM(rv3d->view, RV3D_VIEW_TOP, RV3D_VIEW_BOTTOM)) {
e_data.grid_flag = PLANE_XY;
e_data.grid_flag |= SHOW_AXIS_X;
e_data.grid_flag |= SHOW_AXIS_Y;
e_data.grid_flag |= SHOW_GRID;
+ e_data.grid_flag |= GRID_BACK;
}
else if (ELEM(rv3d->view, RV3D_VIEW_FRONT, RV3D_VIEW_BACK)) {
e_data.grid_flag = PLANE_XZ;
e_data.grid_flag |= SHOW_AXIS_X;
e_data.grid_flag |= SHOW_AXIS_Z;
e_data.grid_flag |= SHOW_GRID;
+ e_data.grid_flag |= GRID_BACK;
}
else { /* RV3D_VIEW_USER */
e_data.grid_flag = PLANE_XY;
@@ -987,7 +992,7 @@ static void OBJECT_cache_init(void *vedata)
{
/* Solid bones */
- DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL | DRW_STATE_CULL_BACK;
+ DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL;
psl->bone_solid = DRW_pass_create("Bone Solid Pass", state);
psl->bone_outline = DRW_pass_create("Bone Outline Pass", state);
}
@@ -1164,8 +1169,11 @@ static void OBJECT_cache_init(void *vedata)
stl->g_data->lamp_groundline = shgroup_groundlines_uniform_color(psl->non_meshes, ts.colorLamp);
stl->g_data->lamp_groundpoint = shgroup_groundpoints_uniform_color(psl->non_meshes, ts.colorLamp);
- geom = DRW_cache_lamp_area_get();
- stl->g_data->lamp_area = shgroup_instance(psl->non_meshes, geom);
+ geom = DRW_cache_lamp_area_square_get();
+ stl->g_data->lamp_area_square = shgroup_instance(psl->non_meshes, geom);
+
+ geom = DRW_cache_lamp_area_disk_get();
+ stl->g_data->lamp_area_disk = shgroup_instance(psl->non_meshes, geom);
geom = DRW_cache_lamp_hemi_get();
stl->g_data->lamp_hemi = shgroup_instance(psl->non_meshes, geom);
@@ -1398,13 +1406,18 @@ static void DRW_shgroup_lamp(OBJECT_StorageList *stl, Object *ob, ViewLayer *vie
else if (la->type == LA_AREA) {
float size[3] = {1.0f, 1.0f, 1.0f}, sizemat[4][4];
- if (la->area_shape == LA_AREA_RECT) {
+ if (ELEM(la->area_shape, LA_AREA_RECT, LA_AREA_ELLIPSE)) {
size[1] = la->area_sizey / la->area_size;
size_to_mat4(sizemat, size);
mul_m4_m4m4(shapemat, shapemat, sizemat);
}
- DRW_shgroup_call_dynamic_add(stl->g_data->lamp_area, color, &la->area_size, shapemat);
+ if (ELEM(la->area_shape, LA_AREA_DISK, LA_AREA_ELLIPSE)) {
+ DRW_shgroup_call_dynamic_add(stl->g_data->lamp_area_disk, color, &la->area_size, shapemat);
+ }
+ else {
+ DRW_shgroup_call_dynamic_add(stl->g_data->lamp_area_square, color, &la->area_size, shapemat);
+ }
}
/* Line and point going to the ground */
diff --git a/source/blender/draw/modes/overlay_mode.c b/source/blender/draw/modes/overlay_mode.c
index e2b381347ff..c4b64e03c48 100644
--- a/source/blender/draw/modes/overlay_mode.c
+++ b/source/blender/draw/modes/overlay_mode.c
@@ -76,7 +76,8 @@ static void overlay_engine_init(void *vedata)
if (!e_data.face_orientation_sh) {
/* Face orientation */
- e_data.face_orientation_sh = DRW_shader_create(datatoc_overlay_face_orientation_vert_glsl, NULL, datatoc_overlay_face_orientation_frag_glsl, "\n");
+ e_data.face_orientation_sh = DRW_shader_create(
+ datatoc_overlay_face_orientation_vert_glsl, NULL, datatoc_overlay_face_orientation_frag_glsl, "\n");
}
}
@@ -100,7 +101,8 @@ static void overlay_cache_init(void *vedata)
if (stl->g_data->overlay.flag & V3D_OVERLAY_FACE_ORIENTATION) {
int state = DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_EQUAL | DRW_STATE_BLEND;
psl->face_orientation_pass = DRW_pass_create("Face Orientation", state);
- stl->g_data->face_orientation_shgrp = DRW_shgroup_create(e_data.face_orientation_sh, psl->face_orientation_pass);
+ stl->g_data->face_orientation_shgrp = DRW_shgroup_create(
+ e_data.face_orientation_sh, psl->face_orientation_pass);
}
}
diff --git a/source/blender/draw/modes/shaders/armature_shape_outline_geom.glsl b/source/blender/draw/modes/shaders/armature_shape_outline_geom.glsl
index dc7ed5e202a..11924b19cf8 100644
--- a/source/blender/draw/modes/shaders/armature_shape_outline_geom.glsl
+++ b/source/blender/draw/modes/shaders/armature_shape_outline_geom.glsl
@@ -1,11 +1,9 @@
-/* TODO: See perf with multiple invocations. */
-layout(triangles_adjacency) in;
-layout(triangle_strip, max_vertices = 16) out;
+layout(lines_adjacency) in;
+layout(triangle_strip, max_vertices = 6) out;
in vec4 pPos[];
-in float vZ[];
-in float vFacing[];
+in vec3 vPos[];
in vec2 ssPos[];
in vec2 ssNor[];
in vec4 vColSize[];
@@ -22,21 +20,18 @@ vec2 compute_dir(vec2 v0, vec2 v1)
return dir;
}
-void emit_edge(const ivec3 edges, vec2 thick, bool is_persp)
+void emit_edge(vec2 edge_dir, vec2 hidden_dir, vec2 thick, bool is_persp)
{
- vec2 edge_dir = compute_dir(ssPos[edges.x], ssPos[edges.y]);
- vec2 hidden_dir = normalize(ssPos[edges.z] - ssPos[edges.x]);
-
float fac = dot(-hidden_dir, edge_dir);
- vec2 t = thick * (is_persp ? vZ[edges.x] : 1.0);
- gl_Position = pPos[edges.x];
+ vec2 t = thick * (is_persp ? abs(vPos[1].z) : 1.0);
+ gl_Position = pPos[1];
EmitVertex();
gl_Position.xy += t * edge_dir * sign(fac);
EmitVertex();
- t = thick * (is_persp ? vZ[edges.y] : 1.0);
- gl_Position = pPos[edges.y];
+ t = thick * (is_persp ? abs(vPos[2].z) : 1.0);
+ gl_Position = pPos[2];
EmitVertex();
gl_Position.xy += t * edge_dir * sign(fac);
EmitVertex();
@@ -45,7 +40,7 @@ void emit_edge(const ivec3 edges, vec2 thick, bool is_persp)
void emit_corner(const int e, vec2 thick, bool is_persp)
{
vec2 corner_dir = ssNor[e];
- vec2 t = thick * (is_persp ? vZ[e] : 1.0);
+ vec2 t = thick * (is_persp ? abs(vPos[e].z) : 1.0);
gl_Position = pPos[e] + vec4(t * corner_dir, 0.0, 0.0);
EmitVertex();
@@ -55,41 +50,38 @@ void main(void)
{
finalColor = vec4(vColSize[0].rgb, 1.0);
- vec2 thick = vColSize[0].w * (lineThickness / viewportSize);
bool is_persp = (ProjectionMatrix[3][3] == 0.0);
- const ivec3 edges = ivec3(0, 2, 4);
- vec4 facing = vec4(vFacing[1], vFacing[3], vFacing[5], vFacing[0]);
- bvec4 do_edge = greaterThanEqual(facing, vec4(0.0));
+ vec3 view_vec = (is_persp) ? normalize(vPos[1]) : vec3(0.0, 0.0, -1.0);
+ vec3 v10 = vPos[0] - vPos[1];
+ vec3 v12 = vPos[2] - vPos[1];
+ vec3 v13 = vPos[3] - vPos[1];
- /* Only generate outlines from backfaces. */
- if (do_edge.w)
- return;
+ vec3 n0 = cross(v12, v10);
+ vec3 n3 = cross(v13, v12);
- if (do_edge.x) {
- emit_corner(edges.x, thick, is_persp);
- emit_edge(edges.xyz, thick, is_persp);
- }
+ float fac0 = dot(view_vec, n0);
+ float fac3 = dot(view_vec, n3);
- if (any(do_edge.xy)) {
- emit_corner(edges.y, thick, is_persp);
- }
+ /* If both adjacent verts are facing the camera the same way,
+ * then it isn't an outline edge. */
+ if (sign(fac0) == sign(fac3))
+ return;
- if (do_edge.y) {
- emit_edge(edges.yzx, thick, is_persp);
- }
- else {
- EndPrimitive();
- }
+ /* Don't outline if concave edge. */
+ if (dot(n0, v13) > 0.0)
+ return;
- if (any(do_edge.yz)) {
- emit_corner(edges.z, thick, is_persp);
- }
+ vec2 thick = vColSize[0].w * (lineThickness / viewportSize);
+ vec2 edge_dir = compute_dir(ssPos[1], ssPos[2]);
- if (do_edge.z) {
- emit_edge(edges.zxy, thick, is_persp);
- emit_corner(edges.x, thick, is_persp);
- }
+ /* Take the farthest point to compute edge direction
+ * (avoid problems with point behind near plane). */
+ vec2 hidden_point = (vPos[0].z < vPos[3].z) ? ssPos[0] : ssPos[3];
+ vec2 hidden_dir = normalize(hidden_point - ssPos[1]);
+ emit_corner(1, thick, is_persp);
+ emit_edge(edge_dir, hidden_dir, thick, is_persp);
+ emit_corner(2, thick, is_persp);
EndPrimitive();
}
diff --git a/source/blender/draw/modes/shaders/armature_shape_outline_vert.glsl b/source/blender/draw/modes/shaders/armature_shape_outline_vert.glsl
index 0d09114579c..3e7a185bb62 100644
--- a/source/blender/draw/modes/shaders/armature_shape_outline_vert.glsl
+++ b/source/blender/draw/modes/shaders/armature_shape_outline_vert.glsl
@@ -15,8 +15,7 @@ in mat4 InstanceModelMatrix;
in vec4 outlineColorSize;
out vec4 pPos;
-out float vZ;
-out float vFacing;
+out vec3 vPos;
out vec2 ssPos;
out vec2 ssNor;
out vec4 vColSize;
@@ -34,25 +33,15 @@ void main()
mat3 NormalMatrix = transpose(inverse(mat3(ViewMatrix * InstanceModelMatrix)));
vec4 viewpos = ViewMatrix * (InstanceModelMatrix * vec4(pos, 1.0));
- pPos = ProjectionMatrix * viewpos;
- vZ = abs(viewpos.z);
- /* if perspective */
- vec3 V = (ProjectionMatrix[3][3] == 0.0) ? normalize(-viewpos.xyz) : vec3(0.0, 0.0, 1.0);
+ vPos = viewpos.xyz;
+ pPos = ProjectionMatrix * viewpos;
/* TODO FIX: there is still a problem with this vector
* when the bone is scaled or in persp mode. But it's
* barelly visible at the outline corners. */
ssNor = normalize((NormalMatrix * snor).xy);
- vec3 normal = normalize(NormalMatrix * nor);
- /* Add a small bias to avoid loosing outline
- * on faces orthogonal to the view.
- * (test case: octahedral bone without rotation in front view.) */
- normal.z += 1e-6;
-
- vFacing = dot(V, normal);
-
ssPos = proj(pPos);
vColSize = outlineColorSize;
diff --git a/source/blender/draw/modes/shaders/armature_shape_solid_frag.glsl b/source/blender/draw/modes/shaders/armature_shape_solid_frag.glsl
index 248281f4e79..89f4d97f29b 100644
--- a/source/blender/draw/modes/shaders/armature_shape_solid_frag.glsl
+++ b/source/blender/draw/modes/shaders/armature_shape_solid_frag.glsl
@@ -1,5 +1,5 @@
-flat in vec4 finalColor;
+in vec4 finalColor;
out vec4 fragColor;
diff --git a/source/blender/draw/modes/shaders/armature_shape_solid_vert.glsl b/source/blender/draw/modes/shaders/armature_shape_solid_vert.glsl
index 701fc9c38ab..505868c9dcf 100644
--- a/source/blender/draw/modes/shaders/armature_shape_solid_vert.glsl
+++ b/source/blender/draw/modes/shaders/armature_shape_solid_vert.glsl
@@ -16,7 +16,7 @@ in mat4 InstanceModelMatrix;
in vec3 boneColor;
in vec3 stateColor;
-flat out vec4 finalColor;
+out vec4 finalColor;
void main()
{
diff --git a/source/blender/draw/modes/shaders/object_grid_frag.glsl b/source/blender/draw/modes/shaders/object_grid_frag.glsl
index baf508fd854..2b04bb0d855 100644
--- a/source/blender/draw/modes/shaders/object_grid_frag.glsl
+++ b/source/blender/draw/modes/shaders/object_grid_frag.glsl
@@ -29,22 +29,23 @@ uniform int gridFlag;
#define PLANE_XY (1 << 4)
#define PLANE_XZ (1 << 5)
#define PLANE_YZ (1 << 6)
+#define GRID_BACK (1 << 9) /* grid is behind objects */
#define GRID_LINE_SMOOTH 1.15
-float get_grid(vec3 co, vec3 fwidthCos, float grid_size)
+float get_grid(vec2 co, vec2 fwidthCos, float grid_size)
{
float half_size = grid_size / 2.0;
- /* triangular wave pattern, amplitude is [0, grid_size] */
- vec3 grid_domain = abs(mod(co + half_size, grid_size) - half_size);
+ /* triangular wave pattern, amplitude is [0, half_size] */
+ vec2 grid_domain = abs(mod(co + half_size, grid_size) - half_size);
/* modulate by the absolute rate of change of the coordinates
* (make lines have the same width under perspective) */
grid_domain /= fwidthCos;
/* collapse waves and normalize */
- grid_domain.x = min(grid_domain.x, min(grid_domain.y, grid_domain.z)) / grid_size;
+ grid_domain.x = min(grid_domain.x, grid_domain.y) / half_size;
- return 1.0 - smoothstep(0.0, GRID_LINE_SMOOTH / grid_size, grid_domain.x);
+ return 1.0 - smoothstep(0.0, GRID_LINE_SMOOTH / grid_size, grid_domain.x * 0.5);
}
vec3 get_axes(vec3 co, vec3 fwidthCos, float line_size)
@@ -137,18 +138,6 @@ void main()
}
}
- /* Manual, non hard, depth test:
- * Progressively fade the grid below occluders
- * (avoids poping visuals due to depth buffer precision) */
- float scene_depth = texture(depthBuffer, sPos).r;
- /* Add a small bias so the grid will always
- * be on top of a mesh with the same depth. */
- float grid_depth = gl_FragCoord.z - 1e-8;
- /* Harder settings tend to flicker more,
- * but have less "see through" appearance. */
- const float test_hardness = 1e4;
- fade *= 1.0 - clamp((grid_depth - scene_depth) * test_hardness, 0.0, 1.0);
-
if ((gridFlag & GRID) > 0) {
float grid_res = log(dist * gridResolution) * gridOneOverLogSubdiv;
@@ -160,9 +149,23 @@ void main()
float scaleB = gridScale * pow(gridSubdiv, max(lvl + 0.0, 0.0));
float scaleC = gridScale * pow(gridSubdiv, max(lvl + 1.0, 1.0));
- float gridA = get_grid(wPos, fwidthPos, scaleA);
- float gridB = get_grid(wPos, fwidthPos, scaleB);
- float gridC = get_grid(wPos, fwidthPos, scaleC);
+ vec2 grid_pos, grid_fwidth;
+ if ((gridFlag & PLANE_XZ) > 0) {
+ grid_pos = wPos.xz;
+ grid_fwidth = fwidthPos.xz;
+ }
+ else if ((gridFlag & PLANE_YZ) > 0) {
+ grid_pos = wPos.yz;
+ grid_fwidth = fwidthPos.yz;
+ }
+ else {
+ grid_pos = wPos.xy;
+ grid_fwidth = fwidthPos.xy;
+ }
+
+ float gridA = get_grid(grid_pos, grid_fwidth, scaleA);
+ float gridB = get_grid(grid_pos, grid_fwidth, scaleB);
+ float gridC = get_grid(grid_pos, grid_fwidth, scaleC);
FragColor = vec4(colorGrid.rgb, gridA * blend);
FragColor = mix(FragColor, vec4(mix(colorGrid.rgb, colorGridEmphasise.rgb, blend), 1.0), gridB);
@@ -203,5 +206,22 @@ void main()
}
}
+ float scene_depth = texture(depthBuffer, sPos).r;
+ if ((gridFlag & GRID_BACK) > 0) {
+ fade *= (scene_depth == 1.0) ? 1.0 : 0.0;
+ }
+ else {
+ /* Manual, non hard, depth test:
+ * Progressively fade the grid below occluders
+ * (avoids poping visuals due to depth buffer precision) */
+ /* Add a small bias so the grid will always
+ * be on top of a mesh with the same depth. */
+ float grid_depth = gl_FragCoord.z - 1e-8;
+ /* Harder settings tend to flicker more,
+ * but have less "see through" appearance. */
+ const float test_hardness = 1e4;
+ fade *= 1.0 - clamp((grid_depth - scene_depth) * test_hardness, 0.0, 1.0);
+ }
+
FragColor.a *= fade;
}
diff --git a/source/blender/editors/animation/anim_deps.c b/source/blender/editors/animation/anim_deps.c
index abdc6450abd..9169df1407b 100644
--- a/source/blender/editors/animation/anim_deps.c
+++ b/source/blender/editors/animation/anim_deps.c
@@ -79,6 +79,9 @@ void ANIM_list_elem_update(Scene *scene, bAnimListElem *ale)
if (adt) {
adt->recalc |= ADT_RECALC_ANIM;
DEG_id_tag_update(id, OB_RECALC_TIME);
+ if (adt->action != NULL) {
+ DEG_id_tag_update(&adt->action->id, DEG_TAG_COPY_ON_WRITE);
+ }
}
/* update data */
diff --git a/source/blender/editors/animation/anim_intern.h b/source/blender/editors/animation/anim_intern.h
index c571da1ba74..824c1d58f44 100644
--- a/source/blender/editors/animation/anim_intern.h
+++ b/source/blender/editors/animation/anim_intern.h
@@ -79,6 +79,7 @@ void ANIM_OT_keying_set_active_set(struct wmOperatorType *ot);
/* Driver management operators for UI buttons (RMB menu) */
void ANIM_OT_driver_button_add(struct wmOperatorType *ot);
void ANIM_OT_driver_button_remove(struct wmOperatorType *ot);
+void ANIM_OT_driver_button_edit(struct wmOperatorType *ot);
void ANIM_OT_copy_driver_button(struct wmOperatorType *ot);
void ANIM_OT_paste_driver_button(struct wmOperatorType *ot);
diff --git a/source/blender/editors/animation/anim_ops.c b/source/blender/editors/animation/anim_ops.c
index eace5af4701..1136dcd129e 100644
--- a/source/blender/editors/animation/anim_ops.c
+++ b/source/blender/editors/animation/anim_ops.c
@@ -512,6 +512,7 @@ void ED_operatortypes_anim(void)
WM_operatortype_append(ANIM_OT_driver_button_add);
WM_operatortype_append(ANIM_OT_driver_button_remove);
+ WM_operatortype_append(ANIM_OT_driver_button_edit);
WM_operatortype_append(ANIM_OT_copy_driver_button);
WM_operatortype_append(ANIM_OT_paste_driver_button);
diff --git a/source/blender/editors/animation/drivers.c b/source/blender/editors/animation/drivers.c
index f792bd2ea9b..2c28ecfac5d 100644
--- a/source/blender/editors/animation/drivers.c
+++ b/source/blender/editors/animation/drivers.c
@@ -41,6 +41,7 @@
#include "DNA_anim_types.h"
#include "DNA_object_types.h"
+#include "DNA_space_types.h"
#include "DNA_texture_types.h"
#include "BKE_animsys.h"
@@ -967,6 +968,46 @@ void ANIM_OT_driver_button_remove(wmOperatorType *ot)
RNA_def_boolean(ot->srna, "all", 1, "All", "Delete drivers for all elements of the array");
}
+/* Edit Driver Button Operator ------------------------ */
+
+static int edit_driver_button_exec(bContext *C, wmOperator *op)
+{
+ PointerRNA ptr = {{NULL}};
+ PropertyRNA *prop = NULL;
+ int index;
+ const bool all = 0; // RNA_boolean_get(op->ptr, "all");
+
+ /* try to find driver using property retrieved from UI */
+ UI_context_active_but_prop_get(C, &ptr, &prop, &index);
+
+ if (all)
+ index = -1;
+
+ if (ptr.id.data && ptr.data && prop) {
+ UI_popover_panel_invoke(C, SPACE_IPO, RGN_TYPE_UI, "GRAPH_PT_drivers_popover", true, op->reports);
+ }
+
+ return OPERATOR_INTERFACE;
+}
+
+void ANIM_OT_driver_button_edit(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Edit Driver";
+ ot->idname = "ANIM_OT_driver_button_edit";
+ ot->description = "Edit the drivers for the property connected represented by the highlighted button";
+
+ /* callbacks */
+ ot->exec = edit_driver_button_exec;
+ //op->poll = ??? // TODO: need to have some driver to be able to do this...
+
+ /* flags */
+ ot->flag = OPTYPE_UNDO | OPTYPE_INTERNAL;
+
+ /* properties */
+ //RNA_def_boolean(ot->srna, "all", 1, "All", "Edit drivers for all elements of the array");
+}
+
/* Copy Driver Button Operator ------------------------ */
static int copy_driver_button_exec(bContext *C, wmOperator *op)
diff --git a/source/blender/editors/armature/pose_select.c b/source/blender/editors/armature/pose_select.c
index b03aa66df04..f0dc680598c 100644
--- a/source/blender/editors/armature/pose_select.c
+++ b/source/blender/editors/armature/pose_select.c
@@ -299,7 +299,22 @@ void ED_pose_deselect_all_multi(Object **objects, uint objects_len, int select_m
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *ob_iter = objects[ob_index];
+ bArmature *arm = ob_iter->data;
+
ED_pose_deselect_all(ob_iter, select_mode, ignore_visibility);
+
+ /* if there are some dependencies for visualizing armature state
+ * (e.g. Mask Modifier in 'Armature' mode), force update
+ */
+ if (arm->flag & ARM_HAS_VIZ_DEPS) {
+ /* NOTE: ob not ob_act here is intentional - it's the source of the
+ * bones being selected [T37247]
+ */
+ DEG_id_tag_update(&ob_iter->id, OB_RECALC_DATA);
+ }
+
+ /* need to tag armature for cow updates, or else selection doesn't update */
+ DEG_id_tag_update(&arm->id, DEG_TAG_COPY_ON_WRITE);
}
}
@@ -368,6 +383,9 @@ static int pose_select_connected_invoke(bContext *C, wmOperator *op, const wmEve
/* mask modifier ('armature' mode), etc. */
DEG_id_tag_update(&base->object->id, OB_RECALC_DATA);
}
+
+ /* need to tag armature for cow updates, or else selection doesn't update */
+ DEG_id_tag_update(&arm->id, DEG_TAG_COPY_ON_WRITE);
return OPERATOR_FINISHED;
}
@@ -907,6 +925,9 @@ static int pose_select_grouped_exec(bContext *C, wmOperator *op)
DEG_id_tag_update(&ob->id, OB_RECALC_DATA);
}
+ /* need to tag armature for cow updates, or else selection doesn't update */
+ DEG_id_tag_update(&arm->id, DEG_TAG_COPY_ON_WRITE);
+
/* report done status */
if (changed)
return OPERATOR_FINISHED;
@@ -1001,6 +1022,9 @@ static int pose_select_mirror_exec(bContext *C, wmOperator *op)
}
WM_event_add_notifier(C, NC_OBJECT | ND_BONE_SELECT, ob);
+
+ /* need to tag armature for cow updates, or else selection doesn't update */
+ DEG_id_tag_update(&arm->id, DEG_TAG_COPY_ON_WRITE);
}
FOREACH_OBJECT_IN_MODE_END;
diff --git a/source/blender/editors/armature/pose_transform.c b/source/blender/editors/armature/pose_transform.c
index af9d94c0bac..1657fe4eaea 100644
--- a/source/blender/editors/armature/pose_transform.c
+++ b/source/blender/editors/armature/pose_transform.c
@@ -780,6 +780,7 @@ static int pose_clear_transform_generic_exec(bContext *C, wmOperator *op,
ViewLayer *view_layer = CTX_data_view_layer(C);
FOREACH_OBJECT_IN_MODE_BEGIN (view_layer, OB_MODE_POSE, ob_iter)
{
+ Object *ob_eval = DEG_get_evaluated_object(CTX_data_depsgraph(C), ob_iter); // XXX: UGLY HACK (for autokey + clear transforms)
ListBase dsources = {NULL, NULL};
bool changed = false;
@@ -797,6 +798,11 @@ static int pose_clear_transform_generic_exec(bContext *C, wmOperator *op,
}
/* tag for autokeying later */
ANIM_relative_keyingset_add_source(&dsources, &ob_iter->id, &RNA_PoseBone, pchan);
+
+#if 1 /* XXX: Ugly Hack - Run clearing function on evaluated copy of pchan */
+ bPoseChannel *pchan_eval = BKE_pose_channel_find_name(ob_eval->pose, pchan->name);
+ clear_func(pchan_eval);
+#endif
}
else {
/* add unkeyed tags */
diff --git a/source/blender/editors/curve/editcurve.c b/source/blender/editors/curve/editcurve.c
index eb180c6bde9..1987fe56bdb 100644
--- a/source/blender/editors/curve/editcurve.c
+++ b/source/blender/editors/curve/editcurve.c
@@ -5026,7 +5026,7 @@ static int add_vertex_invoke(bContext *C, wmOperator *op, const wmEvent *event)
const float mval[2] = {UNPACK2(event->mval)};
struct SnapObjectContext *snap_context = ED_transform_snap_object_context_create_view3d(
- CTX_data_main(C), vc.scene, CTX_data_depsgraph(C), 0, vc.ar, vc.v3d);
+ vc.scene, CTX_data_depsgraph(C), 0, vc.ar, vc.v3d);
ED_transform_snap_object_project_view3d(
snap_context,
diff --git a/source/blender/editors/include/ED_screen.h b/source/blender/editors/include/ED_screen.h
index a91d373ac46..b10d915553e 100644
--- a/source/blender/editors/include/ED_screen.h
+++ b/source/blender/editors/include/ED_screen.h
@@ -248,6 +248,7 @@ int ED_operator_screen_mainwinactive(struct bContext *C);
int ED_operator_areaactive(struct bContext *C);
int ED_operator_regionactive(struct bContext *C);
+int ED_operator_scene(struct bContext *C);
int ED_operator_scene_editable(struct bContext *C);
int ED_operator_objectmode(struct bContext *C);
diff --git a/source/blender/editors/include/ED_transform.h b/source/blender/editors/include/ED_transform.h
index 36f87e1b494..c005f83b3fb 100644
--- a/source/blender/editors/include/ED_transform.h
+++ b/source/blender/editors/include/ED_transform.h
@@ -103,6 +103,7 @@ enum TfmMode {
#define CTX_MASK (1 << 7)
#define CTX_PAINT_CURVE (1 << 8)
#define CTX_GPENCIL_STROKES (1 << 9)
+#define CTX_CURSOR (1 << 10)
/* Standalone call to get the transformation center corresponding to the current situation
* returns 1 if successful, 0 otherwise (usually means there's no selection)
@@ -153,7 +154,8 @@ int BIF_countTransformOrientation(const struct bContext *C);
#define P_NO_TEXSPACE (1 << 11)
#define P_CENTER (1 << 12)
#define P_GPENCIL_EDIT (1 << 13)
-#define P_CLNOR_INVALIDATE (1 << 14)
+#define P_CURSOR_EDIT (1 << 14)
+#define P_CLNOR_INVALIDATE (1 << 15)
void Transform_Properties(struct wmOperatorType *ot, int flags);
diff --git a/source/blender/editors/include/ED_transform_snap_object_context.h b/source/blender/editors/include/ED_transform_snap_object_context.h
index 8ac7dfcf9d8..18d5101ebf7 100644
--- a/source/blender/editors/include/ED_transform_snap_object_context.h
+++ b/source/blender/editors/include/ED_transform_snap_object_context.h
@@ -79,9 +79,9 @@ struct SnapObjectParams {
typedef struct SnapObjectContext SnapObjectContext;
SnapObjectContext *ED_transform_snap_object_context_create(
- struct Main *bmain, struct Scene *scene, struct Depsgraph *depsgraph, int flag);
+ struct Scene *scene, struct Depsgraph *depsgraph, int flag);
SnapObjectContext *ED_transform_snap_object_context_create_view3d(
- struct Main *bmain, struct Scene *scene, struct Depsgraph *depsgraph, int flag,
+ struct Scene *scene, struct Depsgraph *depsgraph, int flag,
/* extra args for view3d */
const struct ARegion *ar, const struct View3D *v3d);
void ED_transform_snap_object_context_destroy(SnapObjectContext *sctx);
diff --git a/source/blender/editors/include/ED_uvedit.h b/source/blender/editors/include/ED_uvedit.h
index d6e8b6e9504..4d5e4585221 100644
--- a/source/blender/editors/include/ED_uvedit.h
+++ b/source/blender/editors/include/ED_uvedit.h
@@ -54,6 +54,11 @@ bool ED_uvedit_minmax(struct Scene *scene, struct Image *ima, struct Object *obe
bool ED_uvedit_center(Scene *scene, Image *ima, struct Object *obedit, float cent[2], char mode);
void ED_uvedit_select_all(struct BMesh *bm);
+bool ED_uvedit_minmax_multi(
+ struct Scene *scene, struct Image *ima, struct Object **objects_edit, uint objects_len, float r_min[2], float r_max[2]);
+bool ED_uvedit_center_multi(
+ Scene *scene, Image *ima, struct Object **objects_edit, uint objects_len, float r_cent[2], char mode);
+
bool ED_object_get_active_image(
struct Object *ob, int mat_nr,
struct Image **r_ima, struct ImageUser **r_iuser, struct bNode **r_node, struct bNodeTree **r_ntree);
diff --git a/source/blender/editors/include/ED_view3d.h b/source/blender/editors/include/ED_view3d.h
index 28e2c5e0d71..e1a6d59a748 100644
--- a/source/blender/editors/include/ED_view3d.h
+++ b/source/blender/editors/include/ED_view3d.h
@@ -106,9 +106,11 @@ void ED_view3d_cursor3d_update(struct bContext *C, const int mval[2]);
struct Camera *ED_view3d_camera_data_get(struct View3D *v3d, struct RegionView3D *rv3d);
void ED_view3d_to_m4(float mat[4][4], const float ofs[3], const float quat[4], const float dist);
-void ED_view3d_from_m4(float mat[4][4], float ofs[3], float quat[4], float *dist);
+void ED_view3d_from_m4(const float mat[4][4], float ofs[3], float quat[4], float *dist);
-void ED_view3d_from_object(struct Object *ob, float ofs[3], float quat[4], float *dist, float *lens);
+void ED_view3d_from_object(
+ const struct Object *ob,
+ float ofs[3], float quat[4], float *dist, float *lens);
void ED_view3d_to_object(
const struct Depsgraph *depsgraph, struct Object *ob,
const float ofs[3], const float quat[4], const float dist);
@@ -227,6 +229,7 @@ eV3DProjStatus ED_view3d_project_float_global(const struct ARegion *ar, const fl
eV3DProjStatus ED_view3d_project_float_object(const struct ARegion *ar, const float co[3], float r_co[2], const eV3DProjTest flag);
float ED_view3d_pixel_size(const struct RegionView3D *rv3d, const float co[3]);
+float ED_view3d_pixel_size_no_ui_scale(const struct RegionView3D *rv3d, const float co[3]);
float ED_view3d_calc_zfac(const struct RegionView3D *rv3d, const float co[3], bool *r_flip);
bool ED_view3d_clip_segment(const struct RegionView3D *rv3d, float ray_start[3], float ray_end[3]);
@@ -304,12 +307,14 @@ float ED_view3d_radius_to_dist_persp(const float angle, const float radius);
float ED_view3d_radius_to_dist_ortho(const float lens, const float radius);
float ED_view3d_radius_to_dist(
const struct View3D *v3d, const struct ARegion *ar,
+ const struct Depsgraph *depsgraph,
const char persp, const bool use_aspect,
const float radius);
void imm_drawcircball(const float cent[3], float rad, const float tmat[4][4], unsigned pos);
/* backbuffer select and draw support */
+void ED_view3d_backbuf_validate_with_select_mode(struct ViewContext *vc, short select_mode);
void ED_view3d_backbuf_validate(struct ViewContext *vc);
struct ImBuf *ED_view3d_backbuf_read(
struct ViewContext *vc, int xmin, int ymin, int xmax, int ymax);
diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h
index 142f4590c16..896d161f664 100644
--- a/source/blender/editors/include/UI_interface.h
+++ b/source/blender/editors/include/UI_interface.h
@@ -429,11 +429,9 @@ void UI_popup_menu_but_set(uiPopupMenu *pup, struct ARegion *butregion, uiBut *b
typedef struct uiPopover uiPopover;
-void UI_popover_panel_from_type(
- struct bContext *C, struct uiLayout *layout, struct PanelType *pt);
int UI_popover_panel_invoke(
struct bContext *C, int space_id, int region_id, const char *idname,
- struct ReportList *reports);
+ bool keep_open, struct ReportList *reports);
uiPopover *UI_popover_begin(struct bContext *C) ATTR_NONNULL(1);
void UI_popover_end(struct bContext *C, struct uiPopover *head, struct wmKeyMap *keymap);
@@ -949,6 +947,7 @@ const char *uiLayoutIntrospect(uiLayout *layout); // XXX - testing
struct MenuType *UI_but_menutype_get(uiBut *but);
struct PanelType *UI_but_paneltype_get(uiBut *but);
void UI_menutype_draw(struct bContext *C, struct MenuType *mt, struct uiLayout *layout);
+void UI_paneltype_draw(struct bContext *C, struct PanelType *pt, struct uiLayout *layout);
/* Only for convenience. */
void uiLayoutSetContextFromBut(uiLayout *layout, uiBut *but);
@@ -962,6 +961,7 @@ void uiLayoutSetKeepAspect(uiLayout *layout, bool keepaspect);
void uiLayoutSetScaleX(uiLayout *layout, float scale);
void uiLayoutSetScaleY(uiLayout *layout, float scale);
void uiLayoutSetEmboss(uiLayout *layout, char emboss);
+void uiLayoutSetPropSep(uiLayout *layout, bool is_sep);
int uiLayoutGetOperatorContext(uiLayout *layout);
bool uiLayoutGetActive(uiLayout *layout);
@@ -973,6 +973,7 @@ int uiLayoutGetWidth(uiLayout *layout);
float uiLayoutGetScaleX(uiLayout *layout);
float uiLayoutGetScaleY(uiLayout *layout);
int uiLayoutGetEmboss(uiLayout *layout);
+bool uiLayoutGetPropSep(uiLayout *layout);
/* layout specifiers */
uiLayout *uiLayoutRow(uiLayout *layout, int align);
diff --git a/source/blender/editors/interface/interface.c b/source/blender/editors/interface/interface.c
index e4b298fecf0..a9995001659 100644
--- a/source/blender/editors/interface/interface.c
+++ b/source/blender/editors/interface/interface.c
@@ -2887,7 +2887,7 @@ void ui_but_update_ex(uiBut *but, const bool validate)
switch (but->type) {
case UI_BTYPE_MENU:
- if (BLI_rctf_size_x(&but->rect) > 24.0f) {
+ if (BLI_rctf_size_x(&but->rect) >= (UI_UNIT_X * 2)) {
/* only needed for menus in popup blocks that don't recreate buttons on redraw */
if (but->block->flag & UI_BLOCK_LOOP) {
if (but->rnaprop && (RNA_property_type(but->rnaprop) == PROP_ENUM)) {
@@ -3212,7 +3212,9 @@ static uiBut *ui_def_but(
}
#ifdef USE_NUMBUTS_LR_ALIGN
else if (ELEM(but->type, UI_BTYPE_NUM, UI_BTYPE_NUM_SLIDER)) {
- but->drawflag |= UI_BUT_TEXT_LEFT;
+ if (slen != 0) {
+ but->drawflag |= UI_BUT_TEXT_LEFT;
+ }
}
#endif
@@ -4626,6 +4628,9 @@ void UI_but_string_info_get(bContext *C, uiBut *but, ...)
PointerRNA *opptr = UI_but_operator_ptr_get(but);
wmOperatorType *ot = but->optype;
+ /* so the context is passed to itemf functions */
+ WM_operator_properties_sanitize(opptr, false);
+
/* if the default property of the operator is enum and it is set,
* fetch the tooltip of the selected value so that "Snap" and "Mirror"
* operator menus in the Anim Editors will show tooltips for the different
@@ -4645,9 +4650,6 @@ void UI_but_string_info_get(bContext *C, uiBut *but, ...)
if (!item) {
int i;
- /* so the context is passed to itemf functions */
- WM_operator_properties_sanitize(ptr, false);
-
RNA_property_enum_items_gettexted(C, ptr, prop, &items, &totitems, &free_items);
for (i = 0, item = items; i < totitems; i++, item++) {
if (item->identifier[0] && item->value == value)
diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c
index 70cd53c440f..0ebe079703b 100644
--- a/source/blender/editors/interface/interface_handlers.c
+++ b/source/blender/editors/interface/interface_handlers.c
@@ -1780,23 +1780,20 @@ static bool ui_but_drag_init(
/* TODO support more button pointer types */
if (but->rnaprop && RNA_property_subtype(but->rnaprop) == PROP_COLOR_GAMMA) {
- RNA_property_float_get_array(&but->rnapoin, but->rnaprop, drag_info->color);
+ ui_but_v3_get(but, drag_info->color);
drag_info->gamma_corrected = true;
valid = true;
}
else if (but->rnaprop && RNA_property_subtype(but->rnaprop) == PROP_COLOR) {
- RNA_property_float_get_array(&but->rnapoin, but->rnaprop, drag_info->color);
+ ui_but_v3_get(but, drag_info->color);
drag_info->gamma_corrected = false;
valid = true;
}
- else if (but->pointype == UI_BUT_POIN_FLOAT) {
+ else if (ELEM(but->pointype, UI_BUT_POIN_FLOAT, UI_BUT_POIN_CHAR)) {
+ ui_but_v3_get(but, drag_info->color);
copy_v3_v3(drag_info->color, (float *)but->poin);
valid = true;
}
- else if (but->pointype == UI_BUT_POIN_CHAR) {
- rgb_uchar_to_float(drag_info->color, (unsigned char *)but->poin);
- valid = true;
- }
if (valid) {
WM_event_start_drag(C, ICON_COLOR, WM_DRAG_COLOR, drag_info, 0.0, WM_DRAG_FREE_DATA);
@@ -6783,8 +6780,11 @@ static bool ui_but_menu(bContext *C, uiBut *but)
ICON_NONE, "ANIM_OT_paste_driver_button");
}
+ uiItemO(layout, CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Edit Driver"),
+ ICON_DRIVER, "ANIM_OT_driver_button_edit");
+
uiItemO(layout, CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Open Drivers Editor"),
- ICON_DRIVER, "SCREEN_OT_drivers_editor_show");
+ ICON_NONE, "SCREEN_OT_drivers_editor_show");
}
else if (but->flag & (UI_BUT_ANIMATED_KEY | UI_BUT_ANIMATED)) {
/* pass */
@@ -6809,7 +6809,7 @@ static bool ui_but_menu(bContext *C, uiBut *but)
}
uiItemO(layout, CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Open Drivers Editor"),
- ICON_DRIVER, "SCREEN_OT_drivers_editor_show");
+ ICON_NONE, "SCREEN_OT_drivers_editor_show");
}
/* Keying Sets */
diff --git a/source/blender/editors/interface/interface_icons.c b/source/blender/editors/interface/interface_icons.c
index 51c3cff721a..bacea087677 100644
--- a/source/blender/editors/interface/interface_icons.c
+++ b/source/blender/editors/interface/interface_icons.c
@@ -783,7 +783,7 @@ static DrawInfo *icon_create_drawinfo(Icon *icon)
IconImage *img = MEM_mallocN(sizeof(IconImage), __func__);
img->w = STUDIOLIGHT_SIZE;
img->h = STUDIOLIGHT_SIZE;
- img->rect = BKE_studiolight_preview(sl, STUDIOLIGHT_SIZE);
+ img->rect = BKE_studiolight_preview(sl, STUDIOLIGHT_SIZE, icon->id_type);
di->data.buffer.image = img;
}
else {
diff --git a/source/blender/editors/interface/interface_intern.h b/source/blender/editors/interface/interface_intern.h
index b851d1d8c5b..c7cf03a44dd 100644
--- a/source/blender/editors/interface/interface_intern.h
+++ b/source/blender/editors/interface/interface_intern.h
@@ -794,6 +794,8 @@ void ui_resources_free(void);
void ui_layout_add_but(uiLayout *layout, uiBut *but);
void ui_but_add_search(uiBut *but, PointerRNA *ptr, PropertyRNA *prop, PointerRNA *searchptr, PropertyRNA *searchprop);
void ui_layout_list_set_labels_active(uiLayout *layout);
+/* menu callback */
+void ui_item_paneltype_func(struct bContext *C, struct uiLayout *layout, void *arg_pt);
/* interface_align.c */
bool ui_but_can_align(const uiBut *but) ATTR_WARN_UNUSED_RESULT;
diff --git a/source/blender/editors/interface/interface_layout.c b/source/blender/editors/interface/interface_layout.c
index 3a4d35296f7..7991f03ea31 100644
--- a/source/blender/editors/interface/interface_layout.c
+++ b/source/blender/editors/interface/interface_layout.c
@@ -71,6 +71,7 @@
return_statement; \
} (void)0 \
+#define UI_ITEM_PROP_SEP_DIVIDE 0.5f
/* uiLayoutRoot */
@@ -128,6 +129,7 @@ enum {
UI_ITEM_MIN = 1 << 1,
UI_ITEM_BOX_ITEM = 1 << 2, /* The item is "inside" a box item */
+ UI_ITEM_PROP_SEP = 1 << 3,
};
typedef struct uiButtonItem {
@@ -181,7 +183,7 @@ static const char *ui_item_name_add_colon(const char *name, char namestr[UI_MAX_
int len = strlen(name);
if (len != 0 && len + 1 < UI_MAX_NAME_STR) {
- BLI_strncpy(namestr, name, UI_MAX_NAME_STR);
+ memcpy(namestr, name, len);
namestr[len] = ':';
namestr[len + 1] = '\0';
return namestr;
@@ -394,7 +396,7 @@ static void ui_layer_but_cb(bContext *C, void *arg_but, void *arg_index)
static void ui_item_array(
uiLayout *layout, uiBlock *block, const char *name, int icon,
PointerRNA *ptr, PropertyRNA *prop, int len, int x, int y, int w, int UNUSED(h),
- bool expand, bool slider, bool toggle, bool icon_only, bool compact)
+ bool expand, bool slider, bool toggle, bool icon_only, bool compact, bool show_text)
{
uiStyle *style = layout->root->style;
uiBut *but;
@@ -411,8 +413,9 @@ static void ui_item_array(
UI_block_layout_set_current(block, sub);
/* create label */
- if (name[0])
+ if (name[0] && show_text) {
uiDefBut(block, UI_BTYPE_LABEL, 0, name, 0, 0, w, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, "");
+ }
/* create buttons */
if (type == PROP_BOOLEAN && ELEM(subtype, PROP_LAYER, PROP_LAYER_MEMBER)) {
@@ -530,7 +533,7 @@ static void ui_item_array(
/* layout for known array subtypes */
char str[3] = {'\0'};
- if (!icon_only) {
+ if (!icon_only && show_text) {
if (type != PROP_BOOLEAN) {
str[1] = ':';
}
@@ -542,19 +545,21 @@ static void ui_item_array(
RNA_property_boolean_get_array(ptr, prop, boolarr);
}
+ const char *str_buf = show_text ? str: "";
for (a = 0; a < len; a++) {
int width_item;
- if (!icon_only) {
+ if (!icon_only && show_text) {
str[0] = RNA_property_array_item_char(prop, a);
}
if (boolarr) {
icon = boolarr[a] ? ICON_CHECKBOX_HLT : ICON_CHECKBOX_DEHLT;
}
+
width_item = (compact && type == PROP_BOOLEAN) ?
- min_ii(w, ui_text_icon_width(layout, str, icon, false)) : w;
+ min_ii(w, ui_text_icon_width(layout, str_buf, icon, false)) : w;
- but = uiDefAutoButR(block, ptr, prop, a, str, icon, 0, 0, width_item, UI_UNIT_Y);
+ but = uiDefAutoButR(block, ptr, prop, a, str_buf, icon, 0, 0, width_item, UI_UNIT_Y);
if (slider && but->type == UI_BTYPE_NUM)
but->type = UI_BTYPE_NUM_SLIDER;
if (toggle && but->type == UI_BTYPE_CHECKBOX)
@@ -1401,7 +1406,8 @@ static void ui_item_rna_size(
if (index == RNA_NO_INDEX && len > 0) {
if (!name[0] && icon == ICON_NONE)
h = 0;
-
+ if (layout->item.flag & UI_ITEM_PROP_SEP)
+ h = 0;
if (ELEM(subtype, PROP_LAYER, PROP_LAYER_MEMBER))
h += 2 * UI_UNIT_Y;
else if (subtype == PROP_MATRIX)
@@ -1431,6 +1437,7 @@ void uiItemFullR(uiLayout *layout, PointerRNA *ptr, PropertyRNA *prop, int index
int len, w, h;
bool slider, toggle, expand, icon_only, no_bg, compact;
bool is_array;
+ const bool use_prop_sep = ((layout->item.flag & UI_ITEM_PROP_SEP) != 0);
UI_block_layout_set_current(block, layout);
@@ -1456,17 +1463,23 @@ void uiItemFullR(uiLayout *layout, PointerRNA *ptr, PropertyRNA *prop, int index
/* pass */
}
else if (ELEM(type, PROP_INT, PROP_FLOAT, PROP_STRING, PROP_POINTER)) {
- name = ui_item_name_add_colon(name, namestr);
+ if (use_prop_sep == false) {
+ name = ui_item_name_add_colon(name, namestr);
+ }
}
else if (type == PROP_BOOLEAN && is_array && index == RNA_NO_INDEX) {
- name = ui_item_name_add_colon(name, namestr);
+ if (use_prop_sep == false) {
+ name = ui_item_name_add_colon(name, namestr);
+ }
}
else if (type == PROP_ENUM && index != RNA_ENUM_VALUE) {
if (flag & UI_ITEM_R_COMPACT) {
name = "";
}
else {
- name = ui_item_name_add_colon(name, namestr);
+ if (use_prop_sep == false) {
+ name = ui_item_name_add_colon(name, namestr);
+ }
}
}
@@ -1505,11 +1518,56 @@ void uiItemFullR(uiLayout *layout, PointerRNA *ptr, PropertyRNA *prop, int index
layout->emboss = UI_EMBOSS_NONE;
}
+ /* Split the label / property. */
+ if (use_prop_sep) {
+ uiLayout *layout_split = uiLayoutSplit(layout, UI_ITEM_PROP_SEP_DIVIDE, true);
+ layout_split->space = 0;
+ uiLayout *layout_sub = uiLayoutColumn(layout_split, true);
+ layout_sub->space = 0;
+
+ if (index == RNA_NO_INDEX && is_array) {
+ char name_with_suffix[UI_MAX_DRAW_STR + 2];
+ char str[2] = {'\0'};
+ for (int a = 0; a < len; a++) {
+ str[0] = RNA_property_array_item_char(prop, a);
+ const bool use_prefix = (a == 0 && name && name[0]);
+ if (use_prefix) {
+ char *s = name_with_suffix;
+ s += STRNCPY_RLEN(name_with_suffix, name);
+ *s++ = ' ';
+ *s++ = str[0];
+ *s++ = '\0';
+ }
+ but = uiDefBut(
+ block, UI_BTYPE_LABEL, 0, use_prefix ? name_with_suffix : str,
+ 0, 0, w, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, "");
+ but->drawflag |= UI_BUT_TEXT_RIGHT;
+ but->drawflag &= ~UI_BUT_TEXT_LEFT;
+ }
+ }
+ else {
+ if (name) {
+ but = uiDefBut(
+ block, UI_BTYPE_LABEL, 0, name,
+ 0, 0, w, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, "");
+ but->drawflag |= UI_BUT_TEXT_RIGHT;
+ but->drawflag &= ~UI_BUT_TEXT_LEFT;
+ }
+ }
+
+ /* Watch out! We can only write into the new column now. */
+ layout = uiLayoutColumn(layout_split, true);
+ layout->space = 0;
+ name = "";
+ }
+ /* End split. */
+
/* array property */
- if (index == RNA_NO_INDEX && is_array)
+ if (index == RNA_NO_INDEX && is_array) {
ui_item_array(
- layout, block, name, icon, ptr, prop, len, 0, 0, w, h,
- expand, slider, toggle, icon_only, compact);
+ layout, block, name, icon, ptr, prop, len, 0, 0, w, h,
+ expand, slider, toggle, icon_only, compact, !use_prop_sep);
+ }
/* enum item */
else if (type == PROP_ENUM && index == RNA_ENUM_VALUE) {
if (icon && name[0] && !icon_only)
@@ -1848,19 +1906,13 @@ static void ui_item_menutype_func(bContext *C, uiLayout *layout, void *arg_mt)
layout->root->block->flag ^= UI_BLOCK_IS_FLIP;
}
-static void ui_item_paneltype_func(bContext *C, uiLayout *layout, void *arg_pt)
+void ui_item_paneltype_func(bContext *C, uiLayout *layout, void *arg_pt)
{
PanelType *pt = (PanelType *)arg_pt;
+ UI_paneltype_draw(C, pt, layout);
- if (layout->context) {
- CTX_store_set(C, layout->context);
- }
-
- UI_popover_panel_from_type(C, layout, pt);
-
- if (layout->context) {
- CTX_store_set(C, NULL);
- }
+ /* panels are created flipped (from event handling pov) */
+ layout->root->block->flag ^= UI_BLOCK_IS_FLIP;
}
static uiBut *ui_item_menu(
@@ -2935,6 +2987,7 @@ static void ui_litem_init_from_parent(uiLayout *litem, uiLayout *layout, int ali
litem->redalert = layout->redalert;
litem->w = layout->w;
litem->emboss = layout->emboss;
+ litem->item.flag = (layout->item.flag & UI_ITEM_PROP_SEP);
BLI_addtail(&layout->items, litem);
}
@@ -3169,6 +3222,16 @@ void uiLayoutSetEmboss(uiLayout *layout, char emboss)
layout->emboss = emboss;
}
+bool uiLayoutGetPropSep(uiLayout *layout)
+{
+ return (layout->item.flag & UI_ITEM_PROP_SEP) != 0;
+}
+
+void uiLayoutSetPropSep(uiLayout *layout, bool is_sep)
+{
+ SET_FLAG_FROM_TEST(layout->item.flag, is_sep, UI_ITEM_PROP_SEP);
+}
+
bool uiLayoutGetActive(uiLayout *layout)
{
return layout->active;
@@ -3740,3 +3803,32 @@ void UI_menutype_draw(bContext *C, MenuType *mt, struct uiLayout *layout)
CTX_store_set(C, NULL);
}
}
+
+/**
+ * Used for popup panels only.
+ */
+void UI_paneltype_draw(bContext *C, PanelType *pt, uiLayout *layout)
+{
+ Panel *panel = MEM_callocN(sizeof(Panel), "popover panel");
+ panel->type = pt;
+
+ if (layout->context) {
+ CTX_store_set(C, layout->context);
+ }
+
+ if (pt->draw_header) {
+ panel->layout = uiLayoutRow(layout, false);
+ pt->draw_header(C, panel);
+ panel->layout = NULL;
+ }
+
+ panel->layout = layout;
+ pt->draw(C, panel);
+ panel->layout = NULL;
+
+ if (layout->context) {
+ CTX_store_set(C, NULL);
+ }
+
+ MEM_freeN(panel);
+}
diff --git a/source/blender/editors/interface/interface_panel.c b/source/blender/editors/interface/interface_panel.c
index 7bf70b3d6fe..5711f76e3e9 100644
--- a/source/blender/editors/interface/interface_panel.c
+++ b/source/blender/editors/interface/interface_panel.c
@@ -753,12 +753,12 @@ void ui_draw_aligned_panel(uiStyle *style, uiBlock *block, const rcti *rect, con
/* draw collapse icon */
/* itemrect smaller */
- itemrect.xmin = headrect.xmin + 5.0f / block->aspect;
+ itemrect.xmin = headrect.xmin + 3.0f / block->aspect;
itemrect.xmax = itemrect.xmin + BLI_rcti_size_y(&headrect);
itemrect.ymin = headrect.ymin;
itemrect.ymax = headrect.ymax;
- BLI_rctf_scale(&itemrect, 0.35f);
+ BLI_rctf_scale(&itemrect, 0.25f);
if (is_closed_y)
ui_draw_tria_rect(&itemrect, 'h');
diff --git a/source/blender/editors/interface/interface_region_popover.c b/source/blender/editors/interface/interface_region_popover.c
index b6248d3daa1..9d10713c868 100644
--- a/source/blender/editors/interface/interface_region_popover.c
+++ b/source/blender/editors/interface/interface_region_popover.c
@@ -189,17 +189,20 @@ static uiBlock *ui_block_func_POPOVER(bContext *C, uiPopupBlockHandle *handle, v
UI_block_flag_enable(block, UI_BLOCK_LOOP);
UI_block_direction_set(block, block->direction);
block->minbounds = UI_MENU_WIDTH_MIN;
+ bool use_place_under_active = !handle->refresh;
- uiBut *but = NULL;
- for (but = block->buttons.first; but; but = but->next) {
- if (but->flag & (UI_SELECT | UI_SELECT_DRAW)) {
- break;
+ if (use_place_under_active) {
+ uiBut *but = NULL;
+ for (but = block->buttons.first; but; but = but->next) {
+ if (but->flag & (UI_SELECT | UI_SELECT_DRAW)) {
+ break;
+ }
}
- }
- if (but) {
- offset[0] = -(but->rect.xmin + 0.8f * BLI_rctf_size_x(&but->rect));
- offset[1] = -(but->rect.ymin + 0.5f * BLI_rctf_size_y(&but->rect));
+ if (but) {
+ offset[0] = -(but->rect.xmin + 0.8f * BLI_rctf_size_x(&but->rect));
+ offset[1] = -(but->rect.ymin + 0.5f * BLI_rctf_size_y(&but->rect));
+ }
}
UI_block_bounds_set_popup(block, block_margin, offset[0], offset[1]);
@@ -256,30 +259,9 @@ uiPopupBlockHandle *ui_popover_panel_create(
/** \name Standard Popover Panels
* \{ */
-
-void UI_popover_panel_from_type(bContext *C, uiLayout *layout, PanelType *pt)
-{
- /* TODO: move into UI_paneltype_draw */
- Panel *panel = MEM_callocN(sizeof(Panel), "popover panel");
- panel->type = pt;
-
-
- if (pt->draw_header) {
- panel->layout = uiLayoutRow(layout, false);
- pt->draw_header(C, panel);
- panel->layout = NULL;
- }
-
- panel->layout = layout;
- pt->draw(C, panel);
- panel->layout = NULL;
-
- MEM_freeN(panel);
-}
-
int UI_popover_panel_invoke(
bContext *C, int space_id, int region_id, const char *idname,
- ReportList *reports)
+ bool keep_open, ReportList *reports)
{
uiLayout *layout;
PanelType *pt = UI_paneltype_find(space_id, region_id, idname);
@@ -296,13 +278,15 @@ int UI_popover_panel_invoke(
return (OPERATOR_CANCELLED | OPERATOR_PASS_THROUGH);
}
- uiPopover *pup = UI_popover_begin(C);
-
- layout = UI_popover_layout(pup);
-
- UI_popover_panel_from_type(C, layout, pt);
-
- UI_popover_end(C, pup, NULL);
+ if (keep_open) {
+ ui_popover_panel_create(C, NULL, NULL, ui_item_paneltype_func, pt);
+ }
+ else {
+ uiPopover *pup = UI_popover_begin(C);
+ layout = UI_popover_layout(pup);
+ UI_paneltype_draw(C, pt, layout);
+ UI_popover_end(C, pup, NULL);
+ }
return OPERATOR_INTERFACE;
}
@@ -371,6 +355,9 @@ void UI_popover_end(bContext *C, uiPopover *pup, wmKeyMap *keymap)
* The begin/end stype of calling popups doesn't allow to 'can_refresh' to be set.
* For now close this style of popvers when accessed. */
UI_block_flag_disable(pup->block, UI_BLOCK_KEEP_OPEN);
+
+ /* panels are created flipped (from event handling pov) */
+ pup->block->flag ^= UI_BLOCK_IS_FLIP;
}
uiLayout *UI_popover_layout(uiPopover *pup)
@@ -386,7 +373,3 @@ void UI_popover_once_clear(uiPopover *pup)
#endif
/** \} */
-
-/* We may want to support this in future */
-/* Similar to UI_popup_menu_invoke */
-// int UI_popover_panel_invoke(bContext *C, const char *idname, ReportList *reports);
diff --git a/source/blender/editors/interface/interface_widgets.c b/source/blender/editors/interface/interface_widgets.c
index 0cea9824249..e4faac5129e 100644
--- a/source/blender/editors/interface/interface_widgets.c
+++ b/source/blender/editors/interface/interface_widgets.c
@@ -1881,7 +1881,9 @@ static void widget_draw_text(uiFontStyle *fstyle, uiWidgetColors *wcol, uiBut *b
}
#ifdef USE_NUMBUTS_LR_ALIGN
- if (!drawstr_right && ELEM(but->type, UI_BTYPE_NUM, UI_BTYPE_NUM_SLIDER) &&
+ if (!drawstr_right &&
+ (but->drawflag & UI_BUT_TEXT_LEFT) &&
+ ELEM(but->type, UI_BTYPE_NUM, UI_BTYPE_NUM_SLIDER) &&
/* if we're editing or multi-drag (fake editing), then use left alignment */
(but->editstr == NULL) && (drawstr == but->drawstr))
{
@@ -4755,7 +4757,7 @@ void ui_draw_popover_back(ARegion *ar, uiStyle *UNUSED(style), uiBlock *block, r
if (block) {
float mval_origin[2] = {block->mx, block->my};
ui_window_to_block_fl(ar, block, &mval_origin[0], &mval_origin[1]);
- ui_draw_popover_back_impl(&wcol_menu_back, rect, block->direction, mval_origin);
+ ui_draw_popover_back_impl(wt->wcol_theme, rect, block->direction, mval_origin);
}
else {
wt->state(wt, 0);
diff --git a/source/blender/editors/interface/resources.c b/source/blender/editors/interface/resources.c
index acfae0a6f0a..979a2164199 100644
--- a/source/blender/editors/interface/resources.c
+++ b/source/blender/editors/interface/resources.c
@@ -165,6 +165,9 @@ const unsigned char *UI_ThemeGetColorPtr(bTheme *btheme, int spacetype, int colo
case SPACE_TOPBAR:
ts = &btheme->ttopbar;
break;
+ case SPACE_STATUSBAR:
+ ts = &btheme->tstatusbar;
+ break;
default:
ts = &btheme->tv3d;
break;
@@ -1238,6 +1241,9 @@ void ui_theme_init_default(void)
copy_v4_v4_char(tmp, btheme->ttopbar.header);
copy_v4_v4_char(btheme->ttopbar.header, btheme->ttopbar.tab_inactive);
copy_v4_v4_char(btheme->ttopbar.back, tmp);
+
+ /* space statusbar */
+ btheme->tstatusbar = btheme->tv3d;
}
void ui_style_init_default(void)
@@ -3001,6 +3007,12 @@ void init_userdef_do_versions(void)
}
}
+ if (!USER_VERSION_ATLEAST(280, 16)) {
+ for (bTheme *btheme = U.themes.first; btheme; btheme = btheme->next) {
+ btheme->tstatusbar = btheme->tv3d;
+ }
+ }
+
/**
* Include next version bump.
*/
diff --git a/source/blender/editors/mesh/editmesh_path.c b/source/blender/editors/mesh/editmesh_path.c
index 4081e3b0302..64d890a7314 100644
--- a/source/blender/editors/mesh/editmesh_path.c
+++ b/source/blender/editors/mesh/editmesh_path.c
@@ -29,6 +29,8 @@
* \ingroup edmesh
*/
+#include "MEM_guardedalloc.h"
+
#include "DNA_scene_types.h"
#include "DNA_object_types.h"
#include "DNA_mesh_types.h"
@@ -41,6 +43,7 @@
#include "BLI_math.h"
#include "BLI_linklist.h"
+#include "BKE_layer.h"
#include "BKE_context.h"
#include "BKE_editmesh.h"
#include "BKE_report.h"
@@ -726,67 +729,87 @@ void MESH_OT_shortest_path_pick(wmOperatorType *ot)
static int edbm_shortest_path_select_exec(bContext *C, wmOperator *op)
{
Scene *scene = CTX_data_scene(C);
- Object *obedit = CTX_data_edit_object(C);
- BMEditMesh *em = BKE_editmesh_from_object(obedit);
- BMesh *bm = em->bm;
- BMIter iter;
- BMEditSelection *ese_src, *ese_dst;
- BMElem *ele_src = NULL, *ele_dst = NULL, *ele;
+ bool found_valid_elements = false;
+
+ ViewLayer *view_layer = CTX_data_view_layer(C);
+ uint objects_len = 0;
+ Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(view_layer, &objects_len);
+ for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
+ Object *obedit = objects[ob_index];
+ BMEditMesh *em = BKE_editmesh_from_object(obedit);
+ BMesh *bm = em->bm;
+ BMIter iter;
+ BMEditSelection *ese_src, *ese_dst;
+ BMElem *ele_src = NULL, *ele_dst = NULL, *ele;
+
+ if ((em->bm->totvertsel == 0) &&
+ (em->bm->totedgesel == 0) &&
+ (em->bm->totfacesel == 0))
+ {
+ continue;
+ }
- /* first try to find vertices in edit selection */
- ese_src = bm->selected.last;
- if (ese_src && (ese_dst = ese_src->prev) && (ese_src->htype == ese_dst->htype)) {
- ele_src = ese_src->ele;
- ele_dst = ese_dst->ele;
- }
- else {
- /* if selection history isn't available, find two selected elements */
- ele_src = ele_dst = NULL;
- if ((em->selectmode & SCE_SELECT_VERTEX) && (bm->totvertsel >= 2)) {
- BM_ITER_MESH (ele, &iter, bm, BM_VERTS_OF_MESH) {
- if (BM_elem_flag_test(ele, BM_ELEM_SELECT)) {
- if (ele_src == NULL) ele_src = ele;
- else if (ele_dst == NULL) ele_dst = ele;
- else break;
+ /* first try to find vertices in edit selection */
+ ese_src = bm->selected.last;
+ if (ese_src && (ese_dst = ese_src->prev) && (ese_src->htype == ese_dst->htype)) {
+ ele_src = ese_src->ele;
+ ele_dst = ese_dst->ele;
+ }
+ else {
+ /* if selection history isn't available, find two selected elements */
+ ele_src = ele_dst = NULL;
+ if ((em->selectmode & SCE_SELECT_VERTEX) && (bm->totvertsel >= 2)) {
+ BM_ITER_MESH (ele, &iter, bm, BM_VERTS_OF_MESH) {
+ if (BM_elem_flag_test(ele, BM_ELEM_SELECT)) {
+ if (ele_src == NULL) ele_src = ele;
+ else if (ele_dst == NULL) ele_dst = ele;
+ else break;
+ }
}
}
- }
- if ((ele_dst == NULL) && (em->selectmode & SCE_SELECT_EDGE) && (bm->totedgesel >= 2)) {
- ele_src = NULL;
- BM_ITER_MESH (ele, &iter, bm, BM_EDGES_OF_MESH) {
- if (BM_elem_flag_test(ele, BM_ELEM_SELECT)) {
- if (ele_src == NULL) ele_src = ele;
- else if (ele_dst == NULL) ele_dst = ele;
- else break;
+ if ((ele_dst == NULL) && (em->selectmode & SCE_SELECT_EDGE) && (bm->totedgesel >= 2)) {
+ ele_src = NULL;
+ BM_ITER_MESH (ele, &iter, bm, BM_EDGES_OF_MESH) {
+ if (BM_elem_flag_test(ele, BM_ELEM_SELECT)) {
+ if (ele_src == NULL) ele_src = ele;
+ else if (ele_dst == NULL) ele_dst = ele;
+ else break;
+ }
}
}
- }
- if ((ele_dst == NULL) && (em->selectmode & SCE_SELECT_FACE) && (bm->totfacesel >= 2)) {
- ele_src = NULL;
- BM_ITER_MESH (ele, &iter, bm, BM_FACES_OF_MESH) {
- if (BM_elem_flag_test(ele, BM_ELEM_SELECT)) {
- if (ele_src == NULL) ele_src = ele;
- else if (ele_dst == NULL) ele_dst = ele;
- else break;
+ if ((ele_dst == NULL) && (em->selectmode & SCE_SELECT_FACE) && (bm->totfacesel >= 2)) {
+ ele_src = NULL;
+ BM_ITER_MESH (ele, &iter, bm, BM_FACES_OF_MESH) {
+ if (BM_elem_flag_test(ele, BM_ELEM_SELECT)) {
+ if (ele_src == NULL) ele_src = ele;
+ else if (ele_dst == NULL) ele_dst = ele;
+ else break;
+ }
}
}
}
- }
- if (ele_src && ele_dst) {
- struct PathSelectParams op_params;
- path_select_params_from_op(op, &op_params);
+ if (ele_src && ele_dst) {
+ struct PathSelectParams op_params;
+ path_select_params_from_op(op, &op_params);
- edbm_shortest_path_pick_ex(scene, obedit, &op_params, ele_src, ele_dst);
+ edbm_shortest_path_pick_ex(scene, obedit, &op_params, ele_src, ele_dst);
- return OPERATOR_FINISHED;
+ found_valid_elements = true;
+ }
}
- else {
- BKE_report(op->reports, RPT_WARNING, "Path selection requires two matching elements to be selected");
+ MEM_freeN(objects);
+
+ if (!found_valid_elements) {
+ BKE_report(op->reports,
+ RPT_WARNING,
+ "Path selection requires two matching elements to be selected");
return OPERATOR_CANCELLED;
}
+
+ return OPERATOR_FINISHED;
}
void MESH_OT_shortest_path_select(wmOperatorType *ot)
diff --git a/source/blender/editors/mesh/editmesh_select.c b/source/blender/editors/mesh/editmesh_select.c
index 11f87b3710d..fd8efcd84e3 100644
--- a/source/blender/editors/mesh/editmesh_select.c
+++ b/source/blender/editors/mesh/editmesh_select.c
@@ -397,6 +397,18 @@ bool EDBM_backbuf_circle_init(
* to avoid the bias interfering with distance comparisons when mixing types.
* \{ */
+#define FAKE_SELECT_MODE_BEGIN(vc, fake_select_mode, select_mode, select_mode_required) \
+ short select_mode = select_mode_required; \
+ bool fake_select_mode = (select_mode & (vc)->scene->toolsettings->selectmode) == 0; \
+ if (fake_select_mode) { \
+ (vc)->v3d->flag |= V3D_INVALID_BACKBUF; \
+ } ((void)0)
+
+#define FAKE_SELECT_MODE_END(vc, fake_select_mode) \
+ if (fake_select_mode) { \
+ (vc)->v3d->flag |= V3D_INVALID_BACKBUF; \
+ } ((void)0)
+
#define FIND_NEAR_SELECT_BIAS 5
#define FIND_NEAR_CYCLE_THRESHOLD_MIN 3
@@ -470,11 +482,16 @@ BMVert *EDBM_vert_find_nearest_ex(
BMVert *eve;
/* No afterqueue (yet), so we check it now, otherwise the bm_xxxofs indices are bad. */
- ED_view3d_backbuf_validate(vc);
+ {
+ FAKE_SELECT_MODE_BEGIN(vc, fake_select_mode, select_mode, SCE_SELECT_VERTEX);
+ ED_view3d_backbuf_validate_with_select_mode(vc, select_mode);
- index = ED_view3d_backbuf_sample_rect(
- vc, vc->mval, dist_px, bm_wireoffs, 0xFFFFFF, &dist_test);
- eve = index ? BM_vert_at_index_find_or_table(bm, index - 1) : NULL;
+ index = ED_view3d_backbuf_sample_rect(
+ vc, vc->mval, dist_px, bm_wireoffs, 0xFFFFFF, &dist_test);
+ eve = index ? BM_vert_at_index_find_or_table(bm, index - 1) : NULL;
+
+ FAKE_SELECT_MODE_END(vc, fake_select_mode);
+ }
if (eve) {
if (dist_test < *r_dist) {
@@ -657,23 +674,16 @@ BMEdge *EDBM_edge_find_nearest_ex(
unsigned int index;
BMEdge *eed;
- /* Make sure that the edges also are considered to find nearest.
- * TODO: cleanup: add `selectmode` as a parameter
- * XXX: Without selectmode as parameter we need to resort to this super ugly hack,
- * because we should never write to evaluate data. */
- const short ts_selectmode = vc->scene->toolsettings->selectmode;
-
- Scene *scene_eval = (Scene *)DEG_get_evaluated_id(vc->depsgraph, &vc->scene->id);
- scene_eval->toolsettings->selectmode |= SCE_SELECT_EDGE;
-
/* No afterqueue (yet), so we check it now, otherwise the bm_xxxofs indices are bad. */
- ED_view3d_backbuf_validate(vc);
-
- /* restore `selectmode` */
- scene_eval->toolsettings->selectmode = ts_selectmode;
-
- index = ED_view3d_backbuf_sample_rect(vc, vc->mval, dist_px, bm_solidoffs, bm_wireoffs, &dist_test);
- eed = index ? BM_edge_at_index_find_or_table(bm, index - 1) : NULL;
+ {
+ FAKE_SELECT_MODE_BEGIN(vc, fake_select_mode, select_mode, SCE_SELECT_EDGE);
+ ED_view3d_backbuf_validate_with_select_mode(vc, select_mode);
+
+ index = ED_view3d_backbuf_sample_rect(vc, vc->mval, dist_px, bm_solidoffs, bm_wireoffs, &dist_test);
+ eed = index ? BM_edge_at_index_find_or_table(bm, index - 1) : NULL;
+
+ FAKE_SELECT_MODE_END(vc, fake_select_mode);
+ }
if (r_eed_zbuf) {
*r_eed_zbuf = eed;
@@ -834,10 +844,15 @@ BMFace *EDBM_face_find_nearest_ex(
unsigned int index;
BMFace *efa;
- ED_view3d_backbuf_validate(vc);
+ {
+ FAKE_SELECT_MODE_BEGIN(vc, fake_select_mode, select_mode, SCE_SELECT_FACE);
+ ED_view3d_backbuf_validate_with_select_mode(vc, select_mode);
+
+ index = ED_view3d_backbuf_sample(vc, vc->mval[0], vc->mval[1]);
+ efa = index ? BM_face_at_index_find_or_table(bm, index - 1) : NULL;
- index = ED_view3d_backbuf_sample(vc, vc->mval[0], vc->mval[1]);
- efa = index ? BM_face_at_index_find_or_table(bm, index - 1) : NULL;
+ FAKE_SELECT_MODE_END(vc, fake_select_mode);
+ }
if (r_efa_zbuf) {
*r_efa_zbuf = efa;
@@ -1067,6 +1082,9 @@ static bool unified_findnearest(
return (hit.v.ele || hit.e.ele || hit.f.ele);
}
+#undef FAKE_SELECT_MODE_BEGIN
+#undef FAKE_SELECT_MODE_END
+
/** \} */
/* -------------------------------------------------------------------- */
@@ -1703,17 +1721,6 @@ static bool mouse_mesh_loop(bContext *C, const int mval[2], bool extend, bool de
mvalf[1] = (float)(vc.mval[1] = mval[1]);
em = vc.em;
- /* Make sure that the edges are also considered for selection.
- * TODO: cleanup: add `selectmode` as a parameter */
- const short ts_selectmode = vc.scene->toolsettings->selectmode;
- vc.scene->toolsettings->selectmode |= SCE_SELECT_EDGE;
-
- /* no afterqueue (yet), so we check it now, otherwise the bm_xxxofs indices are bad */
- ED_view3d_backbuf_validate(&vc);
-
- /* restore `selectmode` */
- vc.scene->toolsettings->selectmode = ts_selectmode;
-
eed = EDBM_edge_find_nearest_ex(&vc, &dist, NULL, true, true, NULL);
if (eed == NULL) {
return false;
diff --git a/source/blender/editors/mesh/editmesh_tools.c b/source/blender/editors/mesh/editmesh_tools.c
index 77c90a6591b..07812cefb6b 100644
--- a/source/blender/editors/mesh/editmesh_tools.c
+++ b/source/blender/editors/mesh/editmesh_tools.c
@@ -372,7 +372,7 @@ void EMBM_project_snap_verts(bContext *C, ARegion *ar, BMEditMesh *em)
ED_view3d_init_mats_rv3d(obedit, ar->regiondata);
struct SnapObjectContext *snap_context = ED_transform_snap_object_context_create_view3d(
- CTX_data_main(C), CTX_data_scene(C), CTX_data_depsgraph(C), 0,
+ CTX_data_scene(C), CTX_data_depsgraph(C), 0,
ar, CTX_wm_view3d(C));
BM_ITER_MESH (eve, &iter, em->bm, BM_VERTS_OF_MESH) {
@@ -444,7 +444,7 @@ static int edbm_delete_exec(bContext *C, wmOperator *op)
break;
case MESH_DELETE_EDGE: /* Erase Edges */
if (!(em->bm->totedgesel &&
- EDBM_op_callf(em, op, "delete geom=%he context=%i", BM_ELEM_SELECT, DEL_FACES)))
+ EDBM_op_callf(em, op, "delete geom=%he context=%i", BM_ELEM_SELECT, DEL_EDGES)))
{
continue;
}
@@ -2318,7 +2318,7 @@ void MESH_OT_vertices_smooth_laplacian(wmOperatorType *ot)
RNA_def_int(ot->srna, "repeat", 1, 1, 1000,
"Number of iterations to smooth the mesh", "", 1, 200);
- RNA_def_float(ot->srna, "lambda_factor", 5e-5f, 1e-7f, 1000.0f,
+ RNA_def_float(ot->srna, "lambda_factor", 1.0f, 1e-7f, 1000.0f,
"Lambda factor", "", 1e-7f, 1000.0f);
RNA_def_float(ot->srna, "lambda_border", 5e-5f, 1e-7f, 1000.0f,
"Lambda factor in border", "", 1e-7f, 1000.0f);
@@ -5453,11 +5453,12 @@ static int edbm_split_exec(bContext *C, wmOperator *op)
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *obedit = objects[ob_index];
BMEditMesh *em = BKE_editmesh_from_object(obedit);
-
- if (em->bm->totfacesel == 0) {
+ if ((em->bm->totvertsel == 0) &&
+ (em->bm->totedgesel == 0) &&
+ (em->bm->totfacesel == 0))
+ {
continue;
}
-
BMOperator bmop;
EDBM_op_init(em, &bmop, op, "split geom=%hvef use_only_faces=%b", BM_ELEM_SELECT, false);
BMO_op_exec(em->bm, &bmop);
diff --git a/source/blender/editors/object/object_transform.c b/source/blender/editors/object/object_transform.c
index 6b22521eedd..77514ca1e8e 100644
--- a/source/blender/editors/object/object_transform.c
+++ b/source/blender/editors/object/object_transform.c
@@ -631,6 +631,10 @@ static int apply_objects_internal(
la->area_shape = LA_AREA_RECT;
la->area_sizey = la->area_size;
}
+ else if ((la->area_shape == LA_AREA_DISK) && !keeps_aspect_ratio) {
+ la->area_shape = LA_AREA_ELLIPSE;
+ la->area_sizey = la->area_size;
+ }
la->area_size *= rsmat[0][0];
la->area_sizey *= rsmat[1][1];
diff --git a/source/blender/editors/physics/particle_edit.c b/source/blender/editors/physics/particle_edit.c
index 7fc3cb8863f..b8a5c138a57 100644
--- a/source/blender/editors/physics/particle_edit.c
+++ b/source/blender/editors/physics/particle_edit.c
@@ -428,7 +428,11 @@ static void PE_set_view3d_data(bContext *C, PEData *data)
static bool PE_create_shape_tree(PEData *data, Object *shapeob)
{
- Mesh *mesh = BKE_modifier_get_evaluated_mesh_from_object(shapeob, 0);
+ ModifierEvalContext ctx = {
+ .depsgraph = data->depsgraph,
+ .flag = 0,
+ };
+ Mesh *mesh = BKE_modifier_get_evaluated_mesh_from_object(&ctx, shapeob);
memset(&data->shape_bvh, 0, sizeof(data->shape_bvh));
@@ -2959,7 +2963,7 @@ static void PE_mirror_x(
}
else {
newpa->num_dmcache = psys_particle_dm_face_lookup(
- psmd->mesh_final, psmd->mesh_deformed, newpa->num, newpa->fuv, NULL);
+ psmd->mesh_final, psmd->mesh_original, newpa->num, newpa->fuv, NULL);
}
/* update edit key pointers */
@@ -3553,7 +3557,7 @@ static int brush_add(const bContext *C, PEData *data, short number)
mesh = psmd->mesh_final;
}
else {
- mesh = psmd->mesh_deformed;
+ mesh = psmd->mesh_original;
}
BLI_assert(mesh);
@@ -3587,11 +3591,11 @@ static int brush_add(const bContext *C, PEData *data, short number)
add_pars[n].num = add_pars[n].num_dmcache;
add_pars[n].num_dmcache = DMCACHE_ISCHILD;
}
- else if (mesh == psmd->mesh_deformed) {
+ else if (mesh == psmd->mesh_original) {
/* Final DM is not same topology as orig mesh, we have to map num_dmcache to real final dm. */
add_pars[n].num = add_pars[n].num_dmcache;
add_pars[n].num_dmcache = psys_particle_dm_face_lookup(
- psmd->mesh_final, psmd->mesh_deformed,
+ psmd->mesh_final, psmd->mesh_original,
add_pars[n].num, add_pars[n].fuv, NULL);
}
else {
diff --git a/source/blender/editors/physics/particle_object.c b/source/blender/editors/physics/particle_object.c
index cb7c90a6c3d..55f518a2a8c 100644
--- a/source/blender/editors/physics/particle_object.c
+++ b/source/blender/editors/physics/particle_object.c
@@ -680,7 +680,7 @@ static bool remap_hair_emitter(
mesh = target_psmd->mesh_final;
}
else {
- mesh = target_psmd->mesh_deformed;
+ mesh = target_psmd->mesh_original;
}
target_mesh = target_psmd->mesh_final;
if (mesh == NULL) {
diff --git a/source/blender/editors/scene/scene_edit.c b/source/blender/editors/scene/scene_edit.c
index b6608ce600f..677fc0a068e 100644
--- a/source/blender/editors/scene/scene_edit.c
+++ b/source/blender/editors/scene/scene_edit.c
@@ -116,7 +116,7 @@ bool ED_scene_delete(bContext *C, Main *bmain, wmWindow *win, Scene *scene)
static ViewLayer *scene_change_get_new_view_layer(const WorkSpace *workspace, const Scene *scene_new)
{
- ViewLayer *layer_new = BKE_workspace_view_layer_get(workspace, scene_new);
+ ViewLayer *layer_new = BKE_workspace_view_layer_exists(workspace, scene_new);
return layer_new ? layer_new : BKE_view_layer_default_view(scene_new);
}
@@ -202,10 +202,11 @@ bool ED_scene_view_layer_delete(
BLI_assert(BLI_listbase_is_empty(&scene->view_layers) == false);
ED_workspace_view_layer_unset(bmain, scene, layer, scene->view_layers.first);
- BKE_workspace_view_layer_remove_references(bmain, layer);
BKE_view_layer_free(layer);
+ BKE_workspace_view_layer_remove(bmain, layer);
+
DEG_id_tag_update(&scene->id, 0);
DEG_relations_tag_update(bmain);
WM_main_add_notifier(NC_SCENE | ND_LAYER | NA_REMOVED, scene);
diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c
index 6392af2a5e0..9b7f767798f 100644
--- a/source/blender/editors/screen/screen_ops.c
+++ b/source/blender/editors/screen/screen_ops.c
@@ -147,6 +147,14 @@ int ED_operator_screen_mainwinactive(bContext *C)
return 1;
}
+int ED_operator_scene(bContext *C)
+{
+ Scene *scene = CTX_data_scene(C);
+ if (scene)
+ return 1;
+ return 0;
+}
+
int ED_operator_scene_editable(bContext *C)
{
Scene *scene = CTX_data_scene(C);
@@ -4720,10 +4728,8 @@ void ED_keymap_screen(wmKeyConfig *keyconf)
RNA_int_set(WM_keymap_add_item(keymap, "SCREEN_OT_screen_set", RIGHTARROWKEY, KM_PRESS, KM_CTRL, 0)->ptr, "delta", 1);
RNA_int_set(WM_keymap_add_item(keymap, "SCREEN_OT_screen_set", LEFTARROWKEY, KM_PRESS, KM_CTRL, 0)->ptr, "delta", -1);
- WM_keymap_add_item(keymap, "SCREEN_OT_screen_full_area", UPARROWKEY, KM_PRESS, KM_CTRL, 0);
- WM_keymap_add_item(keymap, "SCREEN_OT_screen_full_area", DOWNARROWKEY, KM_PRESS, KM_CTRL, 0);
WM_keymap_add_item(keymap, "SCREEN_OT_screen_full_area", SPACEKEY, KM_PRESS, KM_SHIFT, 0);
- kmi = WM_keymap_add_item(keymap, "SCREEN_OT_screen_full_area", F10KEY, KM_PRESS, KM_ALT, 0);
+ kmi = WM_keymap_add_item(keymap, "SCREEN_OT_screen_full_area", SPACEKEY, KM_PRESS, KM_CTRL | KM_SHIFT, 0);
RNA_boolean_set(kmi->ptr, "use_hide_panels", true);
WM_keymap_add_item(keymap, "SCREEN_OT_screenshot", F3KEY, KM_PRESS, KM_CTRL, 0);
diff --git a/source/blender/editors/screen/workspace_edit.c b/source/blender/editors/screen/workspace_edit.c
index a054949df22..d54996bad59 100644
--- a/source/blender/editors/screen/workspace_edit.c
+++ b/source/blender/editors/screen/workspace_edit.c
@@ -110,7 +110,7 @@ static void workspace_change_update_view_layer(
WorkSpace *workspace_new, const WorkSpace *workspace_old,
Scene *scene)
{
- if (!BKE_workspace_view_layer_get(workspace_new, scene)) {
+ if (!BKE_workspace_view_layer_exists(workspace_new, scene)) {
BKE_workspace_view_layer_set(workspace_new, BKE_workspace_view_layer_get(workspace_old, scene), scene);
}
}
@@ -199,7 +199,7 @@ bool ED_workspace_change(
screen_change_update(C, win, screen_new);
workspace_change_update(workspace_new, workspace_old, C, wm);
- BLI_assert(BKE_workspace_view_layer_get(workspace_new, CTX_data_scene(C)) != NULL);
+ BLI_assert(BKE_workspace_view_layer_exists(workspace_new, CTX_data_scene(C)) != NULL);
BLI_assert(CTX_wm_workspace(C) == workspace_new);
WM_toolsystem_unlink_all(C, workspace_old);
diff --git a/source/blender/editors/sculpt_paint/paint_image.c b/source/blender/editors/sculpt_paint/paint_image.c
index 0479af3c58f..9ecdc44cd10 100644
--- a/source/blender/editors/sculpt_paint/paint_image.c
+++ b/source/blender/editors/sculpt_paint/paint_image.c
@@ -299,7 +299,7 @@ static int image_paint_poll(bContext *C)
return image_paint_poll_ex(C, true);
}
-static int image_paint_poll_ignore_tool(bContext *C)
+static int image_paint_ignore_tool_poll(bContext *C)
{
return image_paint_poll_ex(C, false);
}
@@ -1011,11 +1011,6 @@ static int sample_color_modal(bContext *C, wmOperator *op, const wmEvent *event)
return OPERATOR_RUNNING_MODAL;
}
-static int sample_color_poll(bContext *C)
-{
- return (image_paint_poll_ignore_tool(C) || image_paint_poll_ignore_tool(C));
-}
-
void PAINT_OT_sample_color(wmOperatorType *ot)
{
/* identifiers */
@@ -1027,7 +1022,7 @@ void PAINT_OT_sample_color(wmOperatorType *ot)
ot->exec = sample_color_exec;
ot->invoke = sample_color_invoke;
ot->modal = sample_color_modal;
- ot->poll = sample_color_poll;
+ ot->poll = image_paint_ignore_tool_poll;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
diff --git a/source/blender/editors/sculpt_paint/paint_image_proj.c b/source/blender/editors/sculpt_paint/paint_image_proj.c
index a1435d5916a..76449b61d4d 100644
--- a/source/blender/editors/sculpt_paint/paint_image_proj.c
+++ b/source/blender/editors/sculpt_paint/paint_image_proj.c
@@ -81,6 +81,7 @@
#include "BKE_texture.h"
#include "DEG_depsgraph.h"
+#include "DEG_depsgraph_query.h"
#include "UI_interface.h"
@@ -3083,7 +3084,7 @@ static void proj_paint_state_non_cddm_init(ProjPaintState *ps)
}
static void proj_paint_state_viewport_init(
- ProjPaintState *ps, const char symmetry_flag)
+ ProjPaintState *ps, const Depsgraph *depsgraph, const char symmetry_flag)
{
float mat[3][3];
float viewmat[4][4];
@@ -3144,17 +3145,17 @@ static void proj_paint_state_viewport_init(
invert_m4_m4(viewinv, viewmat);
}
else if (ps->source == PROJ_SRC_IMAGE_CAM) {
- Object *cam_ob = ps->scene->camera;
+ Object *cam_ob_eval = DEG_get_evaluated_object(depsgraph, ps->scene->camera);
CameraParams params;
/* viewmat & viewinv */
- copy_m4_m4(viewinv, cam_ob->obmat);
+ copy_m4_m4(viewinv, cam_ob_eval->obmat);
normalize_m4(viewinv);
invert_m4_m4(viewmat, viewinv);
/* window matrix, clipping and ortho */
BKE_camera_params_init(&params);
- BKE_camera_params_from_object(&params, cam_ob);
+ BKE_camera_params_from_object(&params, cam_ob_eval);
BKE_camera_params_compute_viewplane(&params, ps->winx, ps->winy, 1.0f, 1.0f);
BKE_camera_params_compute_matrix(&params);
@@ -3858,7 +3859,7 @@ static void project_paint_begin(
proj_paint_state_cavity_init(ps);
}
- proj_paint_state_viewport_init(ps, symmetry_flag);
+ proj_paint_state_viewport_init(ps, CTX_data_depsgraph(C), symmetry_flag);
/* calculate vert screen coords
* run this early so we can calculate the x/y resolution of our bucket rect */
diff --git a/source/blender/editors/sculpt_paint/paint_utils.c b/source/blender/editors/sculpt_paint/paint_utils.c
index f8888ad9809..b2f3c49cb00 100644
--- a/source/blender/editors/sculpt_paint/paint_utils.c
+++ b/source/blender/editors/sculpt_paint/paint_utils.c
@@ -50,13 +50,15 @@
#include "BKE_brush.h"
#include "BKE_context.h"
-#include "BKE_DerivedMesh.h"
+#include "BKE_customdata.h"
#include "BKE_image.h"
#include "BKE_material.h"
+#include "BKE_object.h"
#include "BKE_paint.h"
#include "BKE_report.h"
#include "DEG_depsgraph.h"
+#include "DEG_depsgraph_query.h"
#include "RNA_access.h"
#include "RNA_define.h"
@@ -274,26 +276,26 @@ static void imapaint_tri_weights(float matrix[4][4], GLint view[4],
}
/* compute uv coordinates of mouse in face */
-static void imapaint_pick_uv(Depsgraph *depsgraph, Scene *scene, Object *ob, unsigned int faceindex, const int xy[2], float uv[2])
+static void imapaint_pick_uv(Mesh *me_eval, Scene *scene, Object *ob_eval, unsigned int faceindex, const int xy[2], float uv[2])
{
- DerivedMesh *dm = mesh_get_derived_final(depsgraph, scene, ob, CD_MASK_BAREMESH);
- const int tottri = dm->getNumLoopTri(dm);
+ const int tottri = me_eval->runtime.looptris.len;
int i, findex;
float p[2], w[3], absw, minabsw;
float matrix[4][4], proj[4][4];
GLint view[4];
const eImagePaintMode mode = scene->toolsettings->imapaint.mode;
- const MLoopTri *lt = dm->getLoopTriArray(dm);
- const MPoly *mpoly = dm->getPolyArray(dm);
- const MLoop *mloop = dm->getLoopArray(dm);
- const int *index_mp_to_orig = dm->getPolyDataArray(dm, CD_ORIGINDEX);
+ const MLoopTri *lt = me_eval->runtime.looptris.array;
+ const MVert *mvert = me_eval->mvert;
+ const MPoly *mpoly = me_eval->mpoly;
+ const MLoop *mloop = me_eval->mloop;
+ const int *index_mp_to_orig = CustomData_get_layer(&me_eval->pdata, CD_ORIGINDEX);
/* get the needed opengl matrices */
glGetIntegerv(GL_VIEWPORT, view);
gpuGetModelViewMatrix(matrix);
gpuGetProjectionMatrix(proj);
view[0] = view[1] = 0;
- mul_m4_m4m4(matrix, matrix, ob->obmat);
+ mul_m4_m4m4(matrix, matrix, ob_eval->obmat);
mul_m4_m4m4(matrix, proj, matrix);
minabsw = 1e10;
@@ -310,25 +312,25 @@ static void imapaint_pick_uv(Depsgraph *depsgraph, Scene *scene, Object *ob, uns
const MLoopUV *tri_uv[3];
float tri_co[3][3];
- dm->getVertCo(dm, mloop[lt->tri[0]].v, tri_co[0]);
- dm->getVertCo(dm, mloop[lt->tri[1]].v, tri_co[1]);
- dm->getVertCo(dm, mloop[lt->tri[2]].v, tri_co[2]);
+ for (int j = 3; j--; ) {
+ copy_v3_v3(tri_co[j], mvert[mloop[lt->tri[j]].v].co);
+ }
if (mode == IMAGEPAINT_MODE_MATERIAL) {
const Material *ma;
const TexPaintSlot *slot;
- ma = dm->mat[mp->mat_nr];
+ ma = give_current_material(ob_eval, mp->mat_nr);
slot = &ma->texpaintslot[ma->paint_active_slot];
if (!(slot && slot->uvname &&
- (mloopuv = CustomData_get_layer_named(&dm->loopData, CD_MLOOPUV, slot->uvname))))
+ (mloopuv = CustomData_get_layer_named(&me_eval->ldata, CD_MLOOPUV, slot->uvname))))
{
- mloopuv = CustomData_get_layer(&dm->loopData, CD_MLOOPUV);
+ mloopuv = CustomData_get_layer(&me_eval->ldata, CD_MLOOPUV);
}
}
else {
- mloopuv = CustomData_get_layer(&dm->loopData, CD_MLOOPUV);
+ mloopuv = CustomData_get_layer(&me_eval->ldata, CD_MLOOPUV);
}
tri_uv[0] = &mloopuv[lt->tri[0]];
@@ -347,8 +349,6 @@ static void imapaint_pick_uv(Depsgraph *depsgraph, Scene *scene, Object *ob, uns
}
}
}
-
- dm->release(dm);
}
/* returns 0 if not found, otherwise 1 */
@@ -452,20 +452,21 @@ void paint_sample_color(bContext *C, ARegion *ar, int x, int y, bool texpaint_pr
/* first try getting a colour directly from the mesh faces if possible */
ViewLayer *view_layer = CTX_data_view_layer(C);
Object *ob = OBACT(view_layer);
+ Object *ob_eval = DEG_get_evaluated_object(depsgraph, ob);
bool sample_success = false;
ImagePaintSettings *imapaint = &scene->toolsettings->imapaint;
bool use_material = (imapaint->mode == IMAGEPAINT_MODE_MATERIAL);
if (ob) {
Mesh *me = (Mesh *)ob->data;
- DerivedMesh *dm = mesh_get_derived_final(depsgraph, scene, ob, CD_MASK_BAREMESH);
+ Mesh *me_eval = BKE_object_get_evaluated_mesh(depsgraph, ob); /* Or shall we just do ob_eval->mesh_evaluated ? */
ViewContext vc;
const int mval[2] = {x, y};
unsigned int faceindex;
unsigned int totpoly = me->totpoly;
- if (dm->getLoopDataArray(dm, CD_MLOOPUV)) {
+ if (CustomData_has_layer(&me_eval->ldata, CD_MLOOPUV)) {
ED_view3d_viewcontext_init(C, &vc);
view3d_operator_needs_opengl(C);
@@ -474,7 +475,7 @@ void paint_sample_color(bContext *C, ARegion *ar, int x, int y, bool texpaint_pr
Image *image;
if (use_material)
- image = imapaint_face_image(ob, me, faceindex);
+ image = imapaint_face_image(ob_eval, me_eval, faceindex);
else
image = imapaint->canvas;
@@ -483,7 +484,7 @@ void paint_sample_color(bContext *C, ARegion *ar, int x, int y, bool texpaint_pr
if (ibuf && ibuf->rect) {
float uv[2];
float u, v;
- imapaint_pick_uv(depsgraph, scene, ob, faceindex, mval, uv);
+ imapaint_pick_uv(me_eval, scene, ob_eval, faceindex, mval, uv);
sample_success = true;
u = fmodf(uv[0], 1.0f);
@@ -525,7 +526,6 @@ void paint_sample_color(bContext *C, ARegion *ar, int x, int y, bool texpaint_pr
}
}
}
- dm->release(dm);
}
if (!sample_success) {
diff --git a/source/blender/editors/space_action/space_action.c b/source/blender/editors/space_action/space_action.c
index 2a0be4eaf0d..cb826d86a21 100644
--- a/source/blender/editors/space_action/space_action.c
+++ b/source/blender/editors/space_action/space_action.c
@@ -379,6 +379,52 @@ static void action_channel_region_listener(
}
}
+static void saction_channel_region_message_subscribe(
+ const struct bContext *UNUSED(C),
+ struct WorkSpace *UNUSED(workspace), struct Scene *UNUSED(scene),
+ struct bScreen *screen, struct ScrArea *sa, struct ARegion *ar,
+ struct wmMsgBus *mbus)
+{
+ PointerRNA ptr;
+ RNA_pointer_create(&screen->id, &RNA_SpaceDopeSheetEditor, sa->spacedata.first, &ptr);
+
+ wmMsgSubscribeValue msg_sub_value_region_tag_redraw = {
+ .owner = ar,
+ .user_data = ar,
+ .notify = ED_region_do_msg_notify_tag_redraw,
+ };
+
+ /* All dopesheet filter settings, etc. affect the drawing of this editor,
+ * also same applies for all animation-related datatypes that may appear here,
+ * so just whitelist the entire structs for updates
+ */
+ {
+ wmMsgParams_RNA msg_key_params = {{{0}}};
+ StructRNA *type_array[] = {
+ &RNA_DopeSheet, /* dopesheet filters */
+
+ &RNA_ActionGroup, /* channel groups */
+
+ &RNA_FCurve, /* F-Curve */
+ &RNA_Keyframe,
+ &RNA_FCurveSample,
+
+ &RNA_GreasePencil, /* Grease Pencil */
+ &RNA_GPencilLayer,
+ &RNA_GPencilFrame,
+ };
+
+ for (int i = 0; i < ARRAY_SIZE(type_array); i++) {
+ msg_key_params.ptr.type = type_array[i];
+ WM_msg_subscribe_rna_params(
+ mbus,
+ &msg_key_params,
+ &msg_sub_value_region_tag_redraw,
+ __func__);
+ }
+ }
+}
+
static void action_main_region_listener(
bScreen *UNUSED(sc), ScrArea *UNUSED(sa), ARegion *ar,
wmNotifier *wmn, const Scene *UNUSED(scene))
@@ -435,8 +481,8 @@ static void action_main_region_listener(
}
static void saction_main_region_message_subscribe(
- const struct bContext *UNUSED(C),
- struct WorkSpace *UNUSED(workspace), struct Scene *scene,
+ const struct bContext *C,
+ struct WorkSpace *workspace, struct Scene *scene,
struct bScreen *screen, struct ScrArea *sa, struct ARegion *ar,
struct wmMsgBus *mbus)
{
@@ -472,6 +518,9 @@ static void saction_main_region_message_subscribe(
WM_msg_subscribe_rna(mbus, &idptr, props[i], &msg_sub_value_region_tag_redraw, __func__);
}
}
+
+ /* Now run the general "channels region" one - since channels and main should be in sync */
+ saction_channel_region_message_subscribe(C, workspace, scene, screen, sa, ar, mbus);
}
/* editor level listener */
@@ -835,6 +884,7 @@ void ED_spacetype_action(void)
art->init = action_channel_region_init;
art->draw = action_channel_region_draw;
art->listener = action_channel_region_listener;
+ art->message_subscribe = saction_channel_region_message_subscribe;
BLI_addhead(&st->regiontypes, art);
diff --git a/source/blender/editors/space_graph/space_graph.c b/source/blender/editors/space_graph/space_graph.c
index 8d3647def9e..6ecb454096d 100644
--- a/source/blender/editors/space_graph/space_graph.c
+++ b/source/blender/editors/space_graph/space_graph.c
@@ -525,6 +525,42 @@ static void graph_region_message_subscribe(
WM_msg_subscribe_rna(mbus, &idptr, props[i], &msg_sub_value_region_tag_redraw, __func__);
}
}
+
+ /* All dopesheet filter settings, etc. affect the drawing of this editor,
+ * also same applies for all animation-related datatypes that may appear here,
+ * so just whitelist the entire structs for updates
+ */
+ {
+ wmMsgParams_RNA msg_key_params = {{{0}}};
+ StructRNA *type_array[] = {
+ &RNA_DopeSheet, /* dopesheet filters */
+
+ &RNA_ActionGroup, /* channel groups */
+ &RNA_FCurve, /* F-Curve */
+ &RNA_Keyframe,
+ &RNA_FCurveSample,
+
+ &RNA_FModifier, /* F-Modifiers (XXX: Why can't we just do all subclasses too?) */
+ &RNA_FModifierCycles,
+ &RNA_FModifierEnvelope,
+ &RNA_FModifierEnvelopeControlPoint,
+ &RNA_FModifierFunctionGenerator,
+ &RNA_FModifierGenerator,
+ &RNA_FModifierLimits,
+ &RNA_FModifierNoise,
+ &RNA_FModifierPython,
+ &RNA_FModifierStepped,
+ };
+
+ for (int i = 0; i < ARRAY_SIZE(type_array); i++) {
+ msg_key_params.ptr.type = type_array[i];
+ WM_msg_subscribe_rna_params(
+ mbus,
+ &msg_key_params,
+ &msg_sub_value_region_tag_redraw,
+ __func__);
+ }
+ }
}
/* editor level listener */
@@ -810,6 +846,7 @@ void ED_spacetype_ipo(void)
art->prefsizex = 200 + V2D_SCROLL_WIDTH; /* 200 is the 'standard', but due to scrollers, we want a bit more to fit the lock icons in */
art->keymapflag = ED_KEYMAP_UI | ED_KEYMAP_VIEW2D | ED_KEYMAP_FRAMES;
art->listener = graph_region_listener;
+ art->message_subscribe = graph_region_message_subscribe;
art->init = graph_channel_region_init;
art->draw = graph_channel_region_draw;
diff --git a/source/blender/editors/space_image/space_image.c b/source/blender/editors/space_image/space_image.c
index 1943cb2c00b..c303a78594d 100644
--- a/source/blender/editors/space_image/space_image.c
+++ b/source/blender/editors/space_image/space_image.c
@@ -171,12 +171,12 @@ static SpaceLink *image_new(const ScrArea *UNUSED(area), const Scene *UNUSED(sce
simage->spacetype = SPACE_IMAGE;
simage->zoom = 1.0f;
simage->lock = true;
- simage->flag = SI_SHOW_GPENCIL | SI_USE_ALPHA;
+ simage->flag = SI_SHOW_GPENCIL | SI_USE_ALPHA | SI_COORDFLOATS;
simage->iuser.ok = true;
simage->iuser.fie_ima = 2;
simage->iuser.frames = 100;
- simage->iuser.flag = IMA_SHOW_STEREO;
+ simage->iuser.flag = IMA_SHOW_STEREO | IMA_ANIM_ALWAYS;
scopes_new(&simage->scopes);
simage->sample_line_hist.height = 100;
diff --git a/source/blender/editors/space_info/info_stats.c b/source/blender/editors/space_info/info_stats.c
index dfcf5fd5d8d..d2bfcfa76df 100644
--- a/source/blender/editors/space_info/info_stats.c
+++ b/source/blender/editors/space_info/info_stats.c
@@ -410,6 +410,7 @@ static void stats_string(ViewLayer *view_layer)
uintptr_t mem_in_use, mmap_in_use;
char memstr[MAX_INFO_MEM_LEN];
char gpumemstr[MAX_INFO_MEM_LEN] = "";
+ char formatted_mem[15];
char *s;
size_t ofs = 0;
@@ -445,20 +446,25 @@ static void stats_string(ViewLayer *view_layer)
/* get memory statistics */
- ofs = BLI_snprintf(memstr, MAX_INFO_MEM_LEN, IFACE_(" | Mem:%.2fM"),
- (double)((mem_in_use - mmap_in_use) >> 10) / 1024.0);
- if (mmap_in_use)
- BLI_snprintf(memstr + ofs, MAX_INFO_MEM_LEN - ofs, IFACE_(" (%.2fM)"), (double)((mmap_in_use) >> 10) / 1024.0);
+ BLI_str_format_byte_unit(formatted_mem, mem_in_use - mmap_in_use, true);
+ ofs = BLI_snprintf(memstr, MAX_INFO_MEM_LEN, IFACE_(" | Mem: %s"), formatted_mem);
+
+ if (mmap_in_use) {
+ BLI_str_format_byte_unit(formatted_mem, mmap_in_use, true);
+ BLI_snprintf(memstr + ofs, MAX_INFO_MEM_LEN - ofs, IFACE_(" (%s)"), formatted_mem);
+ }
if (GPU_mem_stats_supported()) {
int gpu_free_mem, gpu_tot_memory;
GPU_mem_stats_get(&gpu_tot_memory, &gpu_free_mem);
- ofs = BLI_snprintf(gpumemstr, MAX_INFO_MEM_LEN, IFACE_(" | Free GPU Mem:%.2fM"), (double)((gpu_free_mem)) / 1024.0);
+ BLI_str_format_byte_unit(formatted_mem, gpu_free_mem, true);
+ ofs = BLI_snprintf(gpumemstr, MAX_INFO_MEM_LEN, IFACE_(" | Free GPU Mem: %s"), formatted_mem);
if (gpu_tot_memory) {
- BLI_snprintf(gpumemstr + ofs, MAX_INFO_MEM_LEN - ofs, IFACE_("/%.2fM"), (double)((gpu_tot_memory)) / 1024.0);
+ BLI_str_format_byte_unit(formatted_mem, gpu_tot_memory, true);
+ BLI_snprintf(gpumemstr + ofs, MAX_INFO_MEM_LEN - ofs, IFACE_("/%s"), formatted_mem);
}
}
diff --git a/source/blender/editors/space_nla/space_nla.c b/source/blender/editors/space_nla/space_nla.c
index 7245fd9c17f..e56fc12c75b 100644
--- a/source/blender/editors/space_nla/space_nla.c
+++ b/source/blender/editors/space_nla/space_nla.c
@@ -527,6 +527,41 @@ static void nla_channel_region_listener(
}
}
+static void nla_channel_region_message_subscribe(
+ const struct bContext *UNUSED(C),
+ struct WorkSpace *UNUSED(workspace), struct Scene *UNUSED(scene),
+ struct bScreen *screen, struct ScrArea *sa, struct ARegion *ar,
+ struct wmMsgBus *mbus)
+{
+ PointerRNA ptr;
+ RNA_pointer_create(&screen->id, &RNA_SpaceNLA, sa->spacedata.first, &ptr);
+
+ wmMsgSubscribeValue msg_sub_value_region_tag_redraw = {
+ .owner = ar,
+ .user_data = ar,
+ .notify = ED_region_do_msg_notify_tag_redraw,
+ };
+
+ /* All dopesheet filter settings, etc. affect the drawing of this editor,
+ * so just whitelist the entire struct for updates
+ */
+ {
+ wmMsgParams_RNA msg_key_params = {{{0}}};
+ StructRNA *type_array[] = {
+ &RNA_DopeSheet,
+ };
+
+ for (int i = 0; i < ARRAY_SIZE(type_array); i++) {
+ msg_key_params.ptr.type = type_array[i];
+ WM_msg_subscribe_rna_params(
+ mbus,
+ &msg_key_params,
+ &msg_sub_value_region_tag_redraw,
+ __func__);
+ }
+ }
+}
+
/* editor level listener */
static void nla_listener(bScreen *UNUSED(sc), ScrArea *sa, wmNotifier *wmn, Scene *UNUSED(scene),
WorkSpace *UNUSED(workspace))
@@ -628,6 +663,7 @@ void ED_spacetype_nla(void)
art->init = nla_channel_region_init;
art->draw = nla_channel_region_draw;
art->listener = nla_channel_region_listener;
+ art->message_subscribe = nla_channel_region_message_subscribe;
BLI_addhead(&st->regiontypes, art);
diff --git a/source/blender/editors/space_node/drawnode.c b/source/blender/editors/space_node/drawnode.c
index ca6ae5955a9..19e2ae9808a 100644
--- a/source/blender/editors/space_node/drawnode.c
+++ b/source/blender/editors/space_node/drawnode.c
@@ -1021,6 +1021,21 @@ static void node_shader_buts_hair(uiLayout *layout, bContext *UNUSED(C), Pointer
uiItemR(layout, ptr, "component", 0, "", ICON_NONE);
}
+static void node_shader_buts_ies(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+{
+ uiLayout *row;
+
+ row = uiLayoutRow(layout, false);
+ uiItemR(row, ptr, "mode", UI_ITEM_R_EXPAND, NULL, ICON_NONE);
+
+ row = uiLayoutRow(layout, true);
+
+ if (RNA_enum_get(ptr, "mode") == NODE_IES_INTERNAL)
+ uiItemR(row, ptr, "ies", 0, "", ICON_NONE);
+ else
+ uiItemR(row, ptr, "filepath", 0, "", ICON_NONE);
+}
+
static void node_shader_buts_script(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
{
uiLayout *row;
@@ -1189,6 +1204,9 @@ static void node_shader_set_butfunc(bNodeType *ntype)
case SH_NODE_OUTPUT_LINESTYLE:
ntype->draw_buttons = node_buts_output_linestyle;
break;
+ case SH_NODE_TEX_IES:
+ ntype->draw_buttons = node_shader_buts_ies;
+ break;
case SH_NODE_BEVEL:
ntype->draw_buttons = node_shader_buts_bevel;
break;
diff --git a/source/blender/editors/space_outliner/outliner_draw.c b/source/blender/editors/space_outliner/outliner_draw.c
index 883078bc83c..172669ed122 100644
--- a/source/blender/editors/space_outliner/outliner_draw.c
+++ b/source/blender/editors/space_outliner/outliner_draw.c
@@ -402,7 +402,7 @@ static void namebutton_cb(bContext *C, void *tsep, char *oldname)
BLI_strncpy(view_layer->name, oldname, sizeof(view_layer->name));
/* Rename, preserving animation and compositing data. */
- BKE_view_layer_rename(scene, view_layer, newname);
+ BKE_view_layer_rename(bmain, scene, view_layer, newname);
WM_event_add_notifier(C, NC_ID | NA_RENAME, NULL);
break;
}
diff --git a/source/blender/editors/space_outliner/outliner_intern.h b/source/blender/editors/space_outliner/outliner_intern.h
index 73494b890ed..7ca1bc9cc9b 100644
--- a/source/blender/editors/space_outliner/outliner_intern.h
+++ b/source/blender/editors/space_outliner/outliner_intern.h
@@ -191,7 +191,6 @@ typedef enum {
void outliner_free_tree(ListBase *tree);
void outliner_cleanup_tree(struct SpaceOops *soops);
void outliner_free_tree_element(TreeElement *element, ListBase *parent_subtree);
-void outliner_remove_treestore_element(struct SpaceOops *soops, TreeStoreElem *tselem);
void outliner_build_tree(
struct Main *mainvar,
diff --git a/source/blender/editors/space_outliner/outliner_tree.c b/source/blender/editors/space_outliner/outliner_tree.c
index f42addb30bf..d865896e524 100644
--- a/source/blender/editors/space_outliner/outliner_tree.c
+++ b/source/blender/editors/space_outliner/outliner_tree.c
@@ -153,6 +153,9 @@ static void outliner_storage_cleanup(SpaceOops *soops)
}
}
}
+ else if (soops->treehash) {
+ BKE_outliner_treehash_clear_used(soops->treehash);
+ }
}
}
@@ -813,8 +816,11 @@ static void outliner_add_id_contents(SpaceOops *soops, TreeElement *te, TreeStor
}
case ID_GR:
{
- Collection *collection = (Collection *)id;
- outliner_add_collection_recursive(soops, collection, te);
+ /* Don't expand for instances, creates too many elements. */
+ if (!(te->parent && te->parent->idcode == ID_OB)) {
+ Collection *collection = (Collection *)id;
+ outliner_add_collection_recursive(soops, collection, te);
+ }
}
default:
break;
@@ -1182,15 +1188,6 @@ static TreeElement *outliner_add_element(SpaceOops *soops, ListBase *lb, void *i
return te;
}
-/**
- * \note Really only removes \a tselem, not it's TreeElement instance or any children.
- */
-void outliner_remove_treestore_element(SpaceOops *soops, TreeStoreElem *tselem)
-{
- BKE_outliner_treehash_remove_element(soops->treehash, tselem);
- BLI_mempool_free(soops->treestore, tselem);
-}
-
/* ======================================================= */
/* Sequencer mode tree building */
diff --git a/source/blender/editors/space_outliner/outliner_utils.c b/source/blender/editors/space_outliner/outliner_utils.c
index 896f6c016d0..6b7035dd326 100644
--- a/source/blender/editors/space_outliner/outliner_utils.c
+++ b/source/blender/editors/space_outliner/outliner_utils.c
@@ -142,13 +142,11 @@ TreeElement *outliner_find_id(SpaceOops *soops, ListBase *lb, const ID *id)
if (tselem->id == id) {
return te;
}
- /* only deeper on scene collection or object */
- if (ELEM(te->idcode, ID_OB, ID_SCE, ID_GR)) {
- TreeElement *tes = outliner_find_id(soops, &te->subtree, id);
- if (tes) {
- return tes;
- }
- }
+ }
+
+ TreeElement *tes = outliner_find_id(soops, &te->subtree, id);
+ if (tes) {
+ return tes;
}
}
return NULL;
diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c
index 8e04a2e17b8..b87d6c0b85e 100644
--- a/source/blender/editors/space_view3d/drawobject.c
+++ b/source/blender/editors/space_view3d/drawobject.c
@@ -610,9 +610,13 @@ static void bbs_mesh_solid_faces(Scene *UNUSED(scene), Object *ob)
}
void draw_object_backbufsel(
- Depsgraph *depsgraph, Scene *scene, View3D *v3d, RegionView3D *rv3d, Object *ob)
+ Depsgraph *depsgraph, Scene *scene, View3D *v3d, RegionView3D *rv3d, Object *ob,
+ short select_mode)
{
ToolSettings *ts = scene->toolsettings;
+ if (select_mode == -1) {
+ select_mode = ts->selectmode;
+ }
gpuMultMatrix(ob->obmat);
@@ -631,8 +635,8 @@ void draw_object_backbufsel(
DM_update_materials(dm, ob);
- bbs_mesh_solid_EM(em, scene, v3d, ob, dm, (ts->selectmode & SCE_SELECT_FACE) != 0);
- if (ts->selectmode & SCE_SELECT_FACE)
+ bbs_mesh_solid_EM(em, scene, v3d, ob, dm, (select_mode & SCE_SELECT_FACE) != 0);
+ if (select_mode & SCE_SELECT_FACE)
bm_solidoffs = 1 + em->bm->totface;
else {
bm_solidoffs = 1;
@@ -641,7 +645,7 @@ void draw_object_backbufsel(
ED_view3d_polygon_offset(rv3d, 1.0);
/* we draw edges if edge select mode */
- if (ts->selectmode & SCE_SELECT_EDGE) {
+ if (select_mode & SCE_SELECT_EDGE) {
bbs_mesh_wire(em, dm, bm_solidoffs);
bm_wireoffs = bm_solidoffs + em->bm->totedge;
}
@@ -651,7 +655,7 @@ void draw_object_backbufsel(
}
/* we draw verts if vert select mode. */
- if (ts->selectmode & SCE_SELECT_VERTEX) {
+ if (select_mode & SCE_SELECT_VERTEX) {
bbs_mesh_verts(em, dm, bm_wireoffs);
bm_vertoffs = bm_wireoffs + em->bm->totvert;
}
diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c
index 99f7abba065..b44e2da3583 100644
--- a/source/blender/editors/space_view3d/view3d_draw.c
+++ b/source/blender/editors/space_view3d/view3d_draw.c
@@ -302,6 +302,7 @@ static void view3d_camera_border(
{
CameraParams params;
rctf rect_view, rect_camera;
+ Object *camera_eval = DEG_get_evaluated_object(depsgraph, v3d->camera);
/* get viewport viewplane */
BKE_camera_params_init(&params);
@@ -316,7 +317,7 @@ static void view3d_camera_border(
/* fallback for non camera objects */
params.clipsta = v3d->near;
params.clipend = v3d->far;
- BKE_camera_params_from_object(&params, v3d->camera);
+ BKE_camera_params_from_object(&params, camera_eval);
if (no_shift) {
params.shiftx = 0.0f;
params.shifty = 0.0f;
@@ -1172,7 +1173,7 @@ static void draw_selected_name(Scene *scene, Object *ob, rcti *rect)
if (U.uiflag & USER_SHOW_ROTVIEWICON)
offset = U.widget_unit + (U.rvisize * 2) + rect->xmin;
- BLF_draw_default(offset, 0.5f * U.widget_unit, 0.0f, info, sizeof(info));
+ BLF_draw_default(offset, rect->ymin + 0.5f * U.widget_unit, 0.0f, info, sizeof(info));
}
/* ******************** view loop ***************** */
@@ -1417,13 +1418,16 @@ ImBuf *ED_view3d_draw_offscreen_imbuf(
if (rv3d->persp == RV3D_CAMOB && v3d->camera) {
CameraParams params;
Object *camera = BKE_camera_multiview_render(scene, v3d->camera, viewname);
+ const Object *camera_eval = DEG_get_evaluated_object(
+ depsgraph,
+ camera);
BKE_camera_params_init(&params);
/* fallback for non camera objects */
params.clipsta = v3d->near;
params.clipend = v3d->far;
- BKE_camera_params_from_object(&params, camera);
- BKE_camera_multiview_params(&scene->r, &params, camera, viewname);
+ BKE_camera_params_from_object(&params, camera_eval);
+ BKE_camera_multiview_params(&scene->r, &params, camera_eval, viewname);
BKE_camera_params_compute_viewplane(&params, sizex, sizey, scene->r.xasp, scene->r.yasp);
BKE_camera_params_compute_matrix(&params);
@@ -1597,11 +1601,13 @@ ImBuf *ED_view3d_draw_offscreen_imbuf_simple(
{
CameraParams params;
- Object *view_camera = BKE_camera_multiview_render(scene, v3d.camera, viewname);
+ const Object *view_camera_eval = DEG_get_evaluated_object(
+ depsgraph,
+ BKE_camera_multiview_render(scene, v3d.camera, viewname));
BKE_camera_params_init(&params);
- BKE_camera_params_from_object(&params, view_camera);
- BKE_camera_multiview_params(&scene->r, &params, view_camera, viewname);
+ BKE_camera_params_from_object(&params, view_camera_eval);
+ BKE_camera_multiview_params(&scene->r, &params, view_camera_eval, viewname);
BKE_camera_params_compute_viewplane(&params, width, height, scene->r.xasp, scene->r.yasp);
BKE_camera_params_compute_matrix(&params);
diff --git a/source/blender/editors/space_view3d/view3d_draw_legacy.c b/source/blender/editors/space_view3d/view3d_draw_legacy.c
index 5b0f50b7a68..8505de4c7e0 100644
--- a/source/blender/editors/space_view3d/view3d_draw_legacy.c
+++ b/source/blender/editors/space_view3d/view3d_draw_legacy.c
@@ -163,7 +163,8 @@ bool ED_view3d_clipping_test(const RegionView3D *rv3d, const float co[3], const
static void backdrawview3d(
struct Depsgraph *depsgraph, Scene *scene,
ARegion *ar, View3D *v3d,
- Object *obact, Object *obedit)
+ Object *obact, Object *obedit,
+ short select_mode)
{
RegionView3D *rv3d = ar->regiondata;
Scene *scene_eval = (Scene *)DEG_get_evaluated_id(depsgraph, &scene->id);
@@ -263,7 +264,7 @@ static void backdrawview3d(
G.f |= G_BACKBUFSEL;
if (obact_eval && ((obact_eval->base_flag & BASE_VISIBLED) != 0)) {
- draw_object_backbufsel(depsgraph, scene_eval, v3d, rv3d, obact_eval);
+ draw_object_backbufsel(depsgraph, scene_eval, v3d, rv3d, obact_eval, select_mode);
}
if (rv3d->gpuoffscreen)
@@ -301,13 +302,18 @@ static void view3d_opengl_read_Z_pixels(ARegion *ar, int x, int y, int w, int h,
glReadPixels(ar->winrct.xmin + x, ar->winrct.ymin + y, w, h, format, type, data);
}
-void ED_view3d_backbuf_validate(ViewContext *vc)
+void ED_view3d_backbuf_validate_with_select_mode(ViewContext *vc, short select_mode)
{
if (vc->v3d->flag & V3D_INVALID_BACKBUF) {
- backdrawview3d(vc->depsgraph, vc->scene, vc->ar, vc->v3d, vc->obact, vc->obedit);
+ backdrawview3d(vc->depsgraph, vc->scene, vc->ar, vc->v3d, vc->obact, vc->obedit, select_mode);
}
}
+void ED_view3d_backbuf_validate(ViewContext *vc)
+{
+ ED_view3d_backbuf_validate_with_select_mode(vc, -1);
+}
+
/**
* allow for small values [0.5 - 2.5],
* and large values, FLT_MAX by clamping by the area size
diff --git a/source/blender/editors/space_view3d/view3d_edit.c b/source/blender/editors/space_view3d/view3d_edit.c
index 29a61fdf969..3f59a5db9b3 100644
--- a/source/blender/editors/space_view3d/view3d_edit.c
+++ b/source/blender/editors/space_view3d/view3d_edit.c
@@ -1110,7 +1110,7 @@ static void view3d_ndof_pan_zoom(
static void view3d_ndof_orbit(
const struct wmNDOFMotionData *ndof, ScrArea *sa, ARegion *ar,
/* optional, can be NULL*/
- ViewOpsData *vod)
+ ViewOpsData *vod, const bool apply_dyn_ofs)
{
View3D *v3d = sa->spacedata.first;
RegionView3D *rv3d = ar->regiondata;
@@ -1173,7 +1173,7 @@ static void view3d_ndof_orbit(
mul_qt_qtqt(rv3d->viewquat, rv3d->viewquat, quat);
}
- if (vod) {
+ if (apply_dyn_ofs) {
viewrotate_apply_dyn_ofs(vod, rv3d->viewquat);
}
}
@@ -1342,7 +1342,7 @@ static int ndof_orbit_invoke(bContext *C, wmOperator *op, const wmEvent *event)
}
if (has_rotation) {
- view3d_ndof_orbit(ndof, vod->sa, vod->ar, vod);
+ view3d_ndof_orbit(ndof, vod->sa, vod->ar, vod, true);
}
}
@@ -1424,7 +1424,7 @@ static int ndof_orbit_zoom_invoke(bContext *C, wmOperator *op, const wmEvent *ev
}
if (has_rotation) {
- view3d_ndof_orbit(ndof, vod->sa, vod->ar, vod);
+ view3d_ndof_orbit(ndof, vod->sa, vod->ar, vod, true);
}
}
else { /* free/explore (like fly mode) */
@@ -1442,7 +1442,7 @@ static int ndof_orbit_zoom_invoke(bContext *C, wmOperator *op, const wmEvent *ev
ED_view3d_distance_set(rv3d, 0.0f);
if (has_rotation) {
- view3d_ndof_orbit(ndof, vod->sa, vod->ar, NULL);
+ view3d_ndof_orbit(ndof, vod->sa, vod->ar, NULL, false);
}
ED_view3d_distance_set(rv3d, dist_backup);
@@ -2654,7 +2654,7 @@ static void view3d_from_minmax(
}
if (ok_dist) {
- new_dist = ED_view3d_radius_to_dist(v3d, ar, persp, true, (size / 2) * VIEW3D_MARGIN);
+ new_dist = ED_view3d_radius_to_dist(v3d, ar, CTX_data_depsgraph(C), persp, true, (size / 2) * VIEW3D_MARGIN);
if (rv3d->is_persp) {
/* don't zoom closer than the near clipping plane */
new_dist = max_ff(new_dist, v3d->near * 1.5f);
@@ -2765,6 +2765,10 @@ static int view3d_all_exec(bContext *C, wmOperator *op)
view3d_from_minmax(C, v3d, ar, min, max, true, smooth_viewtx);
}
+ if (center) {
+ DEG_id_tag_update(&scene->id, DEG_TAG_COPY_ON_WRITE);
+ }
+
return OPERATOR_FINISHED;
}
@@ -3678,7 +3682,8 @@ static void axis_set_view(
dist = rv3d->dist;
/* so we animate _from_ the camera location */
- ED_view3d_from_object(v3d->camera, rv3d->ofs, NULL, &rv3d->dist, NULL);
+ Object *camera_eval = DEG_get_evaluated_object(CTX_data_depsgraph(C), v3d->camera);
+ ED_view3d_from_object(camera_eval, rv3d->ofs, NULL, &rv3d->dist, NULL);
ED_view3d_smooth_view(
C, v3d, ar, smooth_viewtx,
@@ -4599,12 +4604,11 @@ void ED_view3d_cursor3d_update(bContext *C, const int mval[2])
cursor_curr->rotation[0] *= -1.0f;
{
- struct Main *bmain = CTX_data_main(C);
const float mval_fl[2] = {UNPACK2(mval)};
float ray_no[3];
struct SnapObjectContext *snap_context = ED_transform_snap_object_context_create_view3d(
- bmain, scene, CTX_data_depsgraph(C), 0, ar, v3d);
+ scene, CTX_data_depsgraph(C), 0, ar, v3d);
float obmat[4][4];
Object *ob_dummy = NULL;
diff --git a/source/blender/editors/space_view3d/view3d_header.c b/source/blender/editors/space_view3d/view3d_header.c
index 0ee9adfc396..e0f3c412c56 100644
--- a/source/blender/editors/space_view3d/view3d_header.c
+++ b/source/blender/editors/space_view3d/view3d_header.c
@@ -225,18 +225,18 @@ void VIEW3D_OT_layers(wmOperatorType *ot)
/** \name Toggle Bone selection Overlay Operator
* \{ */
-static int toggle_show_see_through(bContext *C, wmOperator *UNUSED(op))
+static int toggle_show_xray(bContext *C, wmOperator *UNUSED(op))
{
View3D *v3d = CTX_wm_view3d(C);
- v3d->shading.flag ^= V3D_SHADING_SEE_THROUGH;
+ v3d->shading.flag ^= V3D_SHADING_XRAY;
ED_view3d_shade_update(CTX_data_main(C), v3d, CTX_wm_area(C));
WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, v3d);
return OPERATOR_FINISHED;
}
-static int toggle_show_see_through_poll(bContext *C)
+static int toggle_show_xray_poll(bContext *C)
{
- bool result = (ED_operator_view3d_active(C) && !ED_operator_posemode(C));
+ bool result = (ED_operator_view3d_active(C) && !ED_operator_posemode(C) && !ED_operator_editmesh(C));
if (result) {
// Additional test for SOLID or TEXTURE mode
View3D *v3d = CTX_wm_view3d(C);
@@ -245,16 +245,16 @@ static int toggle_show_see_through_poll(bContext *C)
return result;
}
-void VIEW3D_OT_toggle_see_through_draw_option(wmOperatorType *ot)
+void VIEW3D_OT_toggle_xray_draw_option(wmOperatorType *ot)
{
/* identifiers */
- ot->name = "Toggle Show See Though";
- ot->description = "Toggle show see through";
- ot->idname = "VIEW3D_OT_toggle_see_through_draw_option";
+ ot->name = "Toggle Show X-Ray";
+ ot->description = "Toggle show X-Ray";
+ ot->idname = "VIEW3D_OT_toggle_xray_draw_option";
/* api callbacks */
- ot->exec = toggle_show_see_through;
- ot->poll = toggle_show_see_through_poll;
+ ot->exec = toggle_show_xray;
+ ot->poll = toggle_show_xray_poll;
}
/** \} */
diff --git a/source/blender/editors/space_view3d/view3d_intern.h b/source/blender/editors/space_view3d/view3d_intern.h
index 794ca0dcad9..da8afa7a390 100644
--- a/source/blender/editors/space_view3d/view3d_intern.h
+++ b/source/blender/editors/space_view3d/view3d_intern.h
@@ -65,7 +65,7 @@ enum {
/* view3d_header.c */
void VIEW3D_OT_layers(struct wmOperatorType *ot);
-void VIEW3D_OT_toggle_see_through_draw_option(struct wmOperatorType *ot);
+void VIEW3D_OT_toggle_xray_draw_option(struct wmOperatorType *ot);
/* view3d_ops.c */
void view3d_operatortypes(void);
@@ -133,7 +133,9 @@ void VIEW3D_OT_walk(struct wmOperatorType *ot);
void VIEW3D_OT_ruler(struct wmOperatorType *ot);
/* drawobject.c */
-void draw_object_backbufsel(struct Depsgraph *depsgraph, Scene *scene, View3D *v3d, RegionView3D *rv3d, struct Object *ob);
+void draw_object_backbufsel(
+ struct Depsgraph *depsgraph, Scene *scene, View3D *v3d, RegionView3D *rv3d, struct Object *ob,
+ short select_mode);
int view3d_effective_drawtype(const struct View3D *v3d);
diff --git a/source/blender/editors/space_view3d/view3d_iterators.c b/source/blender/editors/space_view3d/view3d_iterators.c
index 35127c7c8c6..145f57174fd 100644
--- a/source/blender/editors/space_view3d/view3d_iterators.c
+++ b/source/blender/editors/space_view3d/view3d_iterators.c
@@ -35,6 +35,7 @@
#include "BLI_utildefines.h"
#include "BLI_rect.h"
+#include "BKE_action.h"
#include "BKE_armature.h"
#include "BKE_curve.h"
#include "BKE_DerivedMesh.h"
@@ -43,6 +44,7 @@
#include "BKE_context.h"
#include "DEG_depsgraph.h"
+#include "DEG_depsgraph_query.h"
#include "bmesh.h"
@@ -449,19 +451,21 @@ void pose_foreachScreenBone(
void (*func)(void *userData, struct bPoseChannel *pchan, const float screen_co_a[2], const float screen_co_b[2]),
void *userData, const eV3DProjTest clip_flag)
{
- bArmature *arm = vc->obact->data;
+ const Object *ob_eval = DEG_get_evaluated_object(vc->depsgraph, vc->obact);
+ const bArmature *arm_eval = ob_eval->data;
bPose *pose = vc->obact->pose;
bPoseChannel *pchan;
ED_view3d_check_mats_rv3d(vc->rv3d);
for (pchan = pose->chanbase.first; pchan; pchan = pchan->next) {
- if (PBONE_VISIBLE(arm, pchan->bone)) {
+ if (PBONE_VISIBLE(arm_eval, pchan->bone)) {
+ bPoseChannel *pchan_eval = BKE_pose_channel_find_name(ob_eval->pose, pchan->name);
float screen_co_a[2], screen_co_b[2];
int points_proj_tot = 0;
/* project head location to screenspace */
- if (ED_view3d_project_float_object(vc->ar, pchan->pose_head, screen_co_a, clip_flag) == V3D_PROJ_RET_OK) {
+ if (ED_view3d_project_float_object(vc->ar, pchan_eval->pose_head, screen_co_a, clip_flag) == V3D_PROJ_RET_OK) {
points_proj_tot++;
}
else {
@@ -470,7 +474,7 @@ void pose_foreachScreenBone(
}
/* project tail location to screenspace */
- if (ED_view3d_project_float_object(vc->ar, pchan->pose_tail, screen_co_b, clip_flag) == V3D_PROJ_RET_OK) {
+ if (ED_view3d_project_float_object(vc->ar, pchan_eval->pose_tail, screen_co_b, clip_flag) == V3D_PROJ_RET_OK) {
points_proj_tot++;
}
else {
diff --git a/source/blender/editors/space_view3d/view3d_manipulator_camera.c b/source/blender/editors/space_view3d/view3d_manipulator_camera.c
index 87e550ba638..d3fe17123a0 100644
--- a/source/blender/editors/space_view3d/view3d_manipulator_camera.c
+++ b/source/blender/editors/space_view3d/view3d_manipulator_camera.c
@@ -132,7 +132,7 @@ static void WIDGETGROUP_camera_refresh(const bContext *C, wmManipulatorGroup *mg
struct CameraWidgetGroup *camgroup = mgroup->customdata;
Object *ob = CTX_data_active_object(C);
const Object *ob_eval = DEG_get_evaluated_object(depsgraph, ob);
- Camera *ca = ob->data;
+ Camera *ca = ob_eval->data;
PointerRNA camera_ptr;
float dir[3];
@@ -252,6 +252,7 @@ static void WIDGETGROUP_camera_message_subscribe(
extern PropertyRNA rna_Camera_shift_x;
extern PropertyRNA rna_Camera_shift_y;
extern PropertyRNA rna_Camera_type;
+ extern PropertyRNA rna_Camera_lens;
const PropertyRNA *props[] = {
&rna_Camera_dof_distance,
&rna_Camera_draw_size,
@@ -261,6 +262,7 @@ static void WIDGETGROUP_camera_message_subscribe(
&rna_Camera_shift_x,
&rna_Camera_shift_y,
&rna_Camera_type,
+ &rna_Camera_lens,
};
PointerRNA idptr;
diff --git a/source/blender/editors/space_view3d/view3d_manipulator_lamp.c b/source/blender/editors/space_view3d/view3d_manipulator_lamp.c
index 93b6b69a105..e659c67396d 100644
--- a/source/blender/editors/space_view3d/view3d_manipulator_lamp.c
+++ b/source/blender/editors/space_view3d/view3d_manipulator_lamp.c
@@ -45,6 +45,8 @@
#include "WM_api.h"
#include "WM_types.h"
+#include "DEG_depsgraph_query.h"
+
#include "view3d_intern.h" /* own include */
/* -------------------------------------------------------------------- */
@@ -80,16 +82,18 @@ static void WIDGETGROUP_lamp_spot_setup(const bContext *UNUSED(C), wmManipulator
static void WIDGETGROUP_lamp_spot_refresh(const bContext *C, wmManipulatorGroup *mgroup)
{
+ const Depsgraph *depsgraph = CTX_data_depsgraph(C);
wmManipulatorWrapper *wwrapper = mgroup->customdata;
wmManipulator *mpr = wwrapper->manipulator;
Object *ob = CTX_data_active_object(C);
+ const Object *ob_eval = DEG_get_evaluated_object(depsgraph, ob);
Lamp *la = ob->data;
float dir[3];
- negate_v3_v3(dir, ob->obmat[2]);
+ negate_v3_v3(dir, ob_eval->obmat[2]);
WM_manipulator_set_matrix_rotation_from_z_axis(mpr, dir);
- WM_manipulator_set_matrix_location(mpr, ob->obmat[3]);
+ WM_manipulator_set_matrix_location(mpr, ob_eval->obmat[3]);
/* need to set property here for undo. TODO would prefer to do this in _init */
PointerRNA lamp_ptr;
@@ -129,7 +133,7 @@ static void manipulator_area_lamp_prop_matrix_get(
const Lamp *la = mpr_prop->custom_func.user_data;
matrix[0][0] = la->area_size;
- matrix[1][1] = (la->area_shape == LA_AREA_RECT) ? la->area_sizey : la->area_size;
+ matrix[1][1] = ELEM(la->area_shape, LA_AREA_RECT, LA_AREA_ELLIPSE) ? la->area_sizey : la->area_size;
}
static void manipulator_area_lamp_prop_matrix_set(
@@ -140,7 +144,7 @@ static void manipulator_area_lamp_prop_matrix_set(
BLI_assert(mpr_prop->type->array_length == 16);
Lamp *la = mpr_prop->custom_func.user_data;
- if (la->area_shape == LA_AREA_RECT) {
+ if (ELEM(la->area_shape, LA_AREA_RECT, LA_AREA_ELLIPSE)) {
la->area_size = len_v3(matrix[0]);
la->area_sizey = len_v3(matrix[1]);
}
@@ -179,15 +183,19 @@ static void WIDGETGROUP_lamp_area_setup(const bContext *UNUSED(C), wmManipulator
static void WIDGETGROUP_lamp_area_refresh(const bContext *C, wmManipulatorGroup *mgroup)
{
wmManipulatorWrapper *wwrapper = mgroup->customdata;
+ const Depsgraph *depsgraph = CTX_data_depsgraph(C);
Object *ob = CTX_data_active_object(C);
- Lamp *la = ob->data;
+ const Object *ob_eval = DEG_get_evaluated_object(depsgraph, ob);
+ Lamp *la = ob_eval->data;
wmManipulator *mpr = wwrapper->manipulator;
- copy_m4_m4(mpr->matrix_basis, ob->obmat);
+ copy_m4_m4(mpr->matrix_basis, ob_eval->obmat);
- RNA_enum_set(mpr->ptr, "transform",
- ED_MANIPULATOR_CAGE2D_XFORM_FLAG_SCALE |
- ((la->area_shape == LA_AREA_SQUARE) ? ED_MANIPULATOR_CAGE2D_XFORM_FLAG_SCALE_UNIFORM : 0));
+ int flag = ED_MANIPULATOR_CAGE2D_XFORM_FLAG_SCALE;
+ if (ELEM(la->area_shape, LA_AREA_SQUARE, LA_AREA_DISK)) {
+ flag |= ED_MANIPULATOR_CAGE2D_XFORM_FLAG_SCALE_UNIFORM;
+ }
+ RNA_enum_set(mpr->ptr, "transform", flag);
/* need to set property here for undo. TODO would prefer to do this in _init */
WM_manipulator_target_property_def_func(
@@ -264,10 +272,12 @@ static void WIDGETGROUP_lamp_target_setup(const bContext *UNUSED(C), wmManipulat
static void WIDGETGROUP_lamp_target_draw_prepare(const bContext *C, wmManipulatorGroup *mgroup)
{
wmManipulatorWrapper *wwrapper = mgroup->customdata;
+ const Depsgraph *depsgraph = CTX_data_depsgraph(C);
Object *ob = CTX_data_active_object(C);
+ const Object *ob_eval = DEG_get_evaluated_object(depsgraph, ob);
wmManipulator *mpr = wwrapper->manipulator;
- copy_m4_m4(mpr->matrix_basis, ob->obmat);
+ copy_m4_m4(mpr->matrix_basis, ob_eval->obmat);
unit_m4(mpr->matrix_offset);
mpr->matrix_offset[3][2] = -2.4f / mpr->scale_basis;
WM_manipulator_set_flag(mpr, WM_MANIPULATOR_DRAW_OFFSET_SCALE, true);
diff --git a/source/blender/editors/space_view3d/view3d_manipulator_ruler.c b/source/blender/editors/space_view3d/view3d_manipulator_ruler.c
index 8c3b28ffdd8..9cde5ffc5e3 100644
--- a/source/blender/editors/space_view3d/view3d_manipulator_ruler.c
+++ b/source/blender/editors/space_view3d/view3d_manipulator_ruler.c
@@ -278,7 +278,7 @@ static void ruler_state_set(bContext *C, RulerInfo *ruler_info, int state)
}
else if (state == RULER_STATE_DRAG) {
ruler_info->snap_context = ED_transform_snap_object_context_create_view3d(
- CTX_data_main(C), CTX_data_scene(C), CTX_data_depsgraph(C), 0,
+ CTX_data_scene(C), CTX_data_depsgraph(C), 0,
ruler_info->ar, CTX_wm_view3d(C));
}
else {
diff --git a/source/blender/editors/space_view3d/view3d_ops.c b/source/blender/editors/space_view3d/view3d_ops.c
index dd168c26f07..4d362ae5425 100644
--- a/source/blender/editors/space_view3d/view3d_ops.c
+++ b/source/blender/editors/space_view3d/view3d_ops.c
@@ -112,7 +112,7 @@ static void VIEW3D_OT_copybuffer(wmOperatorType *ot)
/* api callbacks */
ot->exec = view3d_copybuffer_exec;
- ot->poll = ED_operator_view3d_active;
+ ot->poll = ED_operator_scene;
}
static int view3d_pastebuffer_exec(bContext *C, wmOperator *op)
@@ -149,7 +149,7 @@ static void VIEW3D_OT_pastebuffer(wmOperatorType *ot)
/* api callbacks */
ot->exec = view3d_pastebuffer_exec;
- ot->poll = ED_operator_view3d_active;
+ ot->poll = ED_operator_scene_editable;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
@@ -222,7 +222,7 @@ void view3d_operatortypes(void)
WM_operatortype_append(VIEW3D_OT_snap_cursor_to_active);
WM_operatortype_append(VIEW3D_OT_toggle_render);
- WM_operatortype_append(VIEW3D_OT_toggle_see_through_draw_option);
+ WM_operatortype_append(VIEW3D_OT_toggle_xray_draw_option);
WM_operatortype_append(VIEW3D_OT_ruler_add);
@@ -409,7 +409,7 @@ void view3d_keymap(wmKeyConfig *keyconf)
RNA_string_set(kmi->ptr, "value_2", "TEXTURED");
WM_keymap_add_item(keymap, "VIEW3D_OT_toggle_render", ZKEY, KM_PRESS, KM_SHIFT, 0);
- WM_keymap_add_item(keymap, "VIEW3D_OT_toggle_see_through_draw_option", ZKEY, KM_PRESS, 0, 0);
+ WM_keymap_add_item(keymap, "VIEW3D_OT_toggle_xray_draw_option", ZKEY, KM_PRESS, 0, 0);
kmi = WM_keymap_add_item(keymap, "WM_OT_context_toggle", ZKEY, KM_PRESS, 0, 0);
RNA_string_set(kmi->ptr, "data_path", "space_data.use_occlude_geometry");
diff --git a/source/blender/editors/space_view3d/view3d_project.c b/source/blender/editors/space_view3d/view3d_project.c
index eb86800f4a9..d0fb82eaaf4 100644
--- a/source/blender/editors/space_view3d/view3d_project.c
+++ b/source/blender/editors/space_view3d/view3d_project.c
@@ -282,6 +282,11 @@ float ED_view3d_pixel_size(const RegionView3D *rv3d, const float co[3])
return mul_project_m4_v3_zfac((float(*)[4])rv3d->persmat, co) * rv3d->pixsize * U.pixelsize;
}
+float ED_view3d_pixel_size_no_ui_scale(const RegionView3D *rv3d, const float co[3])
+{
+ return mul_project_m4_v3_zfac((float(*)[4])rv3d->persmat, co) * rv3d->pixsize;
+}
+
/**
* Calculate a depth value from \a co, use with #ED_view3d_win_to_delta
*/
diff --git a/source/blender/editors/space_view3d/view3d_ruler.c b/source/blender/editors/space_view3d/view3d_ruler.c
index 5b616f29c60..c0af3c7caaa 100644
--- a/source/blender/editors/space_view3d/view3d_ruler.c
+++ b/source/blender/editors/space_view3d/view3d_ruler.c
@@ -282,7 +282,7 @@ static void ruler_state_set(bContext *C, RulerInfo *ruler_info, int state)
}
else if (state == RULER_STATE_DRAG) {
ruler_info->snap_context = ED_transform_snap_object_context_create_view3d(
- CTX_data_main(C), CTX_data_scene(C), CTX_data_depsgraph(C), 0,
+ CTX_data_scene(C), CTX_data_depsgraph(C), 0,
ruler_info->ar, CTX_wm_view3d(C));
}
else {
diff --git a/source/blender/editors/space_view3d/view3d_select.c b/source/blender/editors/space_view3d/view3d_select.c
index 711bdac9dc0..be5653a3021 100644
--- a/source/blender/editors/space_view3d/view3d_select.c
+++ b/source/blender/editors/space_view3d/view3d_select.c
@@ -2122,25 +2122,24 @@ static int do_object_pose_box_select(bContext *C, ViewContext *vc, rcti *rect, b
continue;
}
/* Loop over contiguous bone hits for 'base'. */
- bool bone_selected = false;
+ bool changed = false;
for (; col != col_end; col += 4) {
/* should never fail */
if (bone != NULL) {
if (select) {
if ((bone->flag & BONE_UNSELECTABLE) == 0) {
bone->flag |= BONE_SELECTED;
- bone_selected = true;
}
}
else {
bArmature *arm = base->object->data;
if ((bone->flag & BONE_UNSELECTABLE) == 0) {
bone->flag &= ~BONE_SELECTED;
- bone_selected = true;
if (arm->act_bone == bone)
arm->act_bone = NULL;
}
}
+ changed = true;
}
else if (!bone_only) {
ED_object_base_select(base, select ? BA_SELECT : BA_DESELECT);
@@ -2154,7 +2153,7 @@ static int do_object_pose_box_select(bContext *C, ViewContext *vc, rcti *rect, b
if ((base->object->pose != NULL) && bone_only) {
const uint hit_bone = (col[4] & ~BONESEL_ANY) >> 16;
- bPoseChannel *pchan = BLI_findlink(&base->object->pose->chanbase, hit_bone);;
+ bPoseChannel *pchan = BLI_findlink(&base->object->pose->chanbase, hit_bone);
bone = pchan ? pchan->bone : NULL;
}
else {
@@ -2163,7 +2162,7 @@ static int do_object_pose_box_select(bContext *C, ViewContext *vc, rcti *rect, b
}
}
- if (bone_selected) {
+ if (changed) {
if (base->object && (base->object->type == OB_ARMATURE)) {
bArmature *arm = base->object->data;
@@ -2174,6 +2173,8 @@ static int do_object_pose_box_select(bContext *C, ViewContext *vc, rcti *rect, b
DEG_id_tag_update(&vc->obact->id, OB_RECALC_DATA);
}
+ /* copy on write tag is needed (for the armature), or else no refresh happens */
+ DEG_id_tag_update(&arm->id, DEG_TAG_COPY_ON_WRITE);
}
}
}
@@ -2750,6 +2751,9 @@ static void pose_circle_select(ViewContext *vc, const bool select, const int mva
/* mask modifier ('armature' mode), etc. */
DEG_id_tag_update(&vc->obact->id, OB_RECALC_DATA);
}
+
+ /* copy on write tag is needed (for the armature), or else no refresh happens */
+ DEG_id_tag_update(&arm->id, DEG_TAG_COPY_ON_WRITE);
}
}
diff --git a/source/blender/editors/space_view3d/view3d_utils.c b/source/blender/editors/space_view3d/view3d_utils.c
index e18370d04a9..90b1b043de6 100644
--- a/source/blender/editors/space_view3d/view3d_utils.c
+++ b/source/blender/editors/space_view3d/view3d_utils.c
@@ -1067,6 +1067,7 @@ float ED_view3d_radius_to_dist_ortho(const float lens, const float radius)
*/
float ED_view3d_radius_to_dist(
const View3D *v3d, const ARegion *ar,
+ const struct Depsgraph *depsgraph,
const char persp, const bool use_aspect,
const float radius)
{
@@ -1087,7 +1088,8 @@ float ED_view3d_radius_to_dist(
BKE_camera_params_init(&params);
params.clipsta = v3d->near;
params.clipend = v3d->far;
- BKE_camera_params_from_object(&params, v3d->camera);
+ Object *camera_eval = DEG_get_evaluated_object(depsgraph, v3d->camera);
+ BKE_camera_params_from_object(&params, camera_eval);
lens = params.lens;
sensor_size = BKE_camera_sensor_size(params.sensor_fit, params.sensor_x, params.sensor_y);
@@ -1277,7 +1279,7 @@ bool ED_view3d_lock(RegionView3D *rv3d)
* \param quat The view rotation, quaternion normally from RegionView3D.viewquat.
* \param dist The view distance from ofs, normally from RegionView3D.dist.
*/
-void ED_view3d_from_m4(float mat[4][4], float ofs[3], float quat[4], float *dist)
+void ED_view3d_from_m4(const float mat[4][4], float ofs[3], float quat[4], float *dist)
{
float nmat[3][3];
@@ -1322,13 +1324,14 @@ void ED_view3d_to_m4(float mat[4][4], const float ofs[3], const float quat[4], c
/**
* Set the RegionView3D members from an objects transformation and optionally lens.
+ * \param depsgraph The depsgraph to get the evaluated object for the lens calculation.
* \param ob The object to set the view to.
* \param ofs The view offset to be set, normally from RegionView3D.ofs.
* \param quat The view rotation to be set, quaternion normally from RegionView3D.viewquat.
* \param dist The view distance from ofs to be set, normally from RegionView3D.dist.
* \param lens The view lens angle set for cameras and lamps, normally from View3D.lens.
*/
-void ED_view3d_from_object(Object *ob, float ofs[3], float quat[4], float *dist, float *lens)
+void ED_view3d_from_object(const Object *ob, float ofs[3], float quat[4], float *dist, float *lens)
{
ED_view3d_from_m4(ob->obmat, ofs, quat, dist);
@@ -1343,6 +1346,7 @@ void ED_view3d_from_object(Object *ob, float ofs[3], float quat[4], float *dist,
/**
* Set the object transformation from RegionView3D members.
+ * \param depsgraph The depsgraph to get the evaluated object parent for the transformation calculation.
* \param ob The object which has the transformation assigned.
* \param ofs The view offset, normally from RegionView3D.ofs.
* \param quat The view rotation, quaternion normally from RegionView3D.viewquat.
diff --git a/source/blender/editors/space_view3d/view3d_view.c b/source/blender/editors/space_view3d/view3d_view.c
index 2fe95f596c8..0a490a8b494 100644
--- a/source/blender/editors/space_view3d/view3d_view.c
+++ b/source/blender/editors/space_view3d/view3d_view.c
@@ -48,6 +48,7 @@
#include "BKE_scene.h"
#include "DEG_depsgraph.h"
+#include "DEG_depsgraph_query.h"
#include "UI_resources.h"
@@ -62,8 +63,6 @@
#include "DRW_engine.h"
-#include "DEG_depsgraph_query.h"
-
#include "view3d_intern.h" /* own include */
/* -------------------------------------------------------------------- */
@@ -513,25 +512,26 @@ static int view3d_camera_to_view_selected_exec(bContext *C, wmOperator *op)
ViewLayer *view_layer = CTX_data_view_layer(C);
View3D *v3d = CTX_wm_view3d(C); /* can be NULL */
Object *camera_ob = v3d ? v3d->camera : scene->camera;
+ Object *camera_ob_eval = DEG_get_evaluated_object(depsgraph, camera_ob);
float r_co[3]; /* the new location to apply */
float r_scale; /* only for ortho cameras */
- if (camera_ob == NULL) {
+ if (camera_ob_eval == NULL) {
BKE_report(op->reports, RPT_ERROR, "No active camera");
return OPERATOR_CANCELLED;
}
/* this function does all the important stuff */
- if (BKE_camera_view_frame_fit_to_scene(depsgraph, scene, view_layer, camera_ob, r_co, &r_scale)) {
+ if (BKE_camera_view_frame_fit_to_scene(depsgraph, scene, view_layer, camera_ob_eval, r_co, &r_scale)) {
ObjectTfmProtectedChannels obtfm;
float obmat_new[4][4];
- if ((camera_ob->type == OB_CAMERA) && (((Camera *)camera_ob->data)->type == CAM_ORTHO)) {
+ if ((camera_ob_eval->type == OB_CAMERA) && (((Camera *)camera_ob_eval->data)->type == CAM_ORTHO)) {
((Camera *)camera_ob->data)->ortho_scale = r_scale;
}
- copy_m4_m4(obmat_new, camera_ob->obmat);
+ copy_m4_m4(obmat_new, camera_ob_eval->obmat);
copy_v3_v3(obmat_new[3], r_co);
/* only touch location */
diff --git a/source/blender/editors/space_view3d/view3d_walk.c b/source/blender/editors/space_view3d/view3d_walk.c
index 6bbc0b7d985..a7c97ba4d4a 100644
--- a/source/blender/editors/space_view3d/view3d_walk.c
+++ b/source/blender/editors/space_view3d/view3d_walk.c
@@ -602,7 +602,7 @@ static bool initWalkInfo(bContext *C, WalkInfo *walk, wmOperator *op)
walk->rv3d->rflag |= RV3D_NAVIGATING;
walk->snap_context = ED_transform_snap_object_context_create_view3d(
- CTX_data_main(C), walk->scene, CTX_data_depsgraph(C), 0,
+ walk->scene, CTX_data_depsgraph(C), 0,
walk->ar, walk->v3d);
walk->v3d_camera_control = ED_view3d_cameracontrol_acquire(
diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c
index 569cd4efafc..b713f18da4c 100644
--- a/source/blender/editors/transform/transform.c
+++ b/source/blender/editors/transform/transform.c
@@ -2137,6 +2137,12 @@ bool initTransform(bContext *C, TransInfo *t, wmOperator *op, const wmEvent *eve
t->state = TRANS_STARTING;
+ if ((prop = RNA_struct_find_property(op->ptr, "cursor_transform")) && RNA_property_is_set(op->ptr, prop)) {
+ if (RNA_property_boolean_get(op->ptr, prop)) {
+ options |= CTX_CURSOR;
+ }
+ }
+
if ((prop = RNA_struct_find_property(op->ptr, "texture_space")) && RNA_property_is_set(op->ptr, prop)) {
if (RNA_property_boolean_get(op->ptr, prop)) {
options |= CTX_TEXTURE;
diff --git a/source/blender/editors/transform/transform.h b/source/blender/editors/transform/transform.h
index 136512516e8..3718f1be9a8 100644
--- a/source/blender/editors/transform/transform.h
+++ b/source/blender/editors/transform/transform.h
@@ -557,6 +557,8 @@ typedef struct TransInfo {
#define T_TEXTURE (1 << 3)
/* transforming the camera while in camera view */
#define T_CAMERA (1 << 4)
+ /* transforming the 3D cursor. */
+#define T_CURSOR (1 << 5)
// trans on points, having no rotation/scale
#define T_POINTS (1 << 6)
/**
@@ -601,7 +603,9 @@ typedef struct TransInfo {
/** #TransInfo.center has been set, don't change it. */
#define T_OVERRIDE_CENTER (1 << 25)
-#define T_CLNOR_REBUILD (1 << 26)
+#define T_MODAL_CURSOR_SET (1 << 26)
+
+#define T_CLNOR_REBUILD (1 << 27)
/* TransInfo->modifiers */
#define MOD_CONSTRAINT_SELECT 0x01
diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c
index 73a722d897d..c8b09eef04b 100644
--- a/source/blender/editors/transform/transform_conversions.c
+++ b/source/blender/editors/transform/transform_conversions.c
@@ -345,6 +345,43 @@ static void createTransTexspace(TransInfo *t)
copy_v3_v3(td->ext->isize, td->ext->size);
}
+static void createTransCursor3D(TransInfo *t)
+{
+ TransData *td;
+
+ Scene *scene = t->scene;
+ View3D *v3d = ((t->spacetype == SPACE_VIEW3D) && (t->ar->regiontype == RGN_TYPE_WINDOW)) ? t->view : NULL;
+ View3DCursor *cursor = ED_view3d_cursor3d_get(scene, v3d);
+
+ if ((cursor == &scene->cursor) && ID_IS_LINKED(scene)) {
+ BKE_report(t->reports, RPT_ERROR, "Linked data can't text-space transform");
+ return;
+ }
+
+ {
+ BLI_assert(t->data_container_len == 1);
+ TransDataContainer *tc = t->data_container;
+ tc->data_len = 1;
+ td = tc->data = MEM_callocN(sizeof(TransData), "TransTexspace");
+ td->ext = tc->data_ext = MEM_callocN(sizeof(TransDataExtension), "TransTexspace");
+ }
+
+ td->flag = TD_SELECTED;
+ copy_v3_v3(td->center, cursor->location);
+ td->ob = NULL;
+
+ unit_m3(td->mtx);
+ quat_to_mat3(td->axismtx, cursor->rotation);
+ normalize_m3(td->axismtx);
+ pseudoinverse_m3_m3(td->smtx, td->mtx, PSEUDOINVERSE_EPSILON);
+
+ td->loc = cursor->location;
+ copy_v3_v3(td->iloc, cursor->location);
+
+ td->ext->quat = cursor->rotation;
+ copy_qt_qt(td->ext->iquat, cursor->rotation);
+}
+
/* ********************* edge (for crease) ***** */
static void createTransEdge(TransInfo *t)
@@ -5583,39 +5620,41 @@ static bool constraints_list_needinv(TransInfo *t, ListBase *list)
/* transcribe given object into TransData for Transforming */
static void ObjectToTransData(TransInfo *t, TransData *td, Object *ob)
{
+ Depsgraph *depsgraph = t->depsgraph;
Scene *scene = t->scene;
+ Object *ob_eval = DEG_get_evaluated_object(depsgraph, ob);
bool constinv;
bool skip_invert = false;
if (t->mode != TFM_DUMMY && ob->rigidbody_object) {
float rot[3][3], scale[3];
- float ctime = BKE_scene_frame_get(scene);
+ float ctime = DEG_get_ctime(depsgraph);
/* only use rigid body transform if simulation is running, avoids problems with initial setup of rigid bodies */
+ // XXX: This needs fixing for COW. May need rigidbody_world from scene
if (BKE_rigidbody_check_sim_running(scene->rigidbody_world, ctime)) {
-
/* save original object transform */
- copy_v3_v3(td->ext->oloc, ob->loc);
+ copy_v3_v3(td->ext->oloc, ob_eval->loc);
if (ob->rotmode > 0) {
- copy_v3_v3(td->ext->orot, ob->rot);
+ copy_v3_v3(td->ext->orot, ob_eval->rot);
}
else if (ob->rotmode == ROT_MODE_AXISANGLE) {
- td->ext->orotAngle = ob->rotAngle;
- copy_v3_v3(td->ext->orotAxis, ob->rotAxis);
+ td->ext->orotAngle = ob_eval->rotAngle;
+ copy_v3_v3(td->ext->orotAxis, ob_eval->rotAxis);
}
else {
- copy_qt_qt(td->ext->oquat, ob->quat);
+ copy_qt_qt(td->ext->oquat, ob_eval->quat);
}
/* update object's loc/rot to get current rigid body transform */
- mat4_to_loc_rot_size(ob->loc, rot, scale, ob->obmat);
- sub_v3_v3(ob->loc, ob->dloc);
+ mat4_to_loc_rot_size(ob->loc, rot, scale, ob_eval->obmat);
+ sub_v3_v3(ob->loc, ob_eval->dloc);
BKE_object_mat3_to_rot(ob, rot, false); /* drot is already corrected here */
}
}
/* axismtx has the real orientation */
- copy_m3_m4(td->axismtx, ob->obmat);
+ copy_m3_m4(td->axismtx, ob_eval->obmat);
normalize_m3(td->axismtx);
td->con = ob->constraints.first;
@@ -5628,6 +5667,7 @@ static void ObjectToTransData(TransInfo *t, TransData *td, Object *ob)
constinv = constraints_list_needinv(t, &ob->constraints);
/* disable constraints inversion for dummy pass */
+ // XXX: Should this use ob or ob_eval?! It's not clear!
if (t->mode == TFM_DUMMY)
skip_invert = true;
@@ -5642,7 +5682,7 @@ static void ObjectToTransData(TransInfo *t, TransData *td, Object *ob)
td->ob = ob;
td->loc = ob->loc;
- copy_v3_v3(td->iloc, td->loc);
+ copy_v3_v3(td->iloc, ob_eval->loc);
if (ob->rotmode > 0) {
td->ext->rot = ob->rot;
@@ -5650,8 +5690,8 @@ static void ObjectToTransData(TransInfo *t, TransData *td, Object *ob)
td->ext->rotAngle = NULL;
td->ext->quat = NULL;
- copy_v3_v3(td->ext->irot, ob->rot);
- copy_v3_v3(td->ext->drot, ob->drot);
+ copy_v3_v3(td->ext->irot, ob_eval->rot);
+ copy_v3_v3(td->ext->drot, ob_eval->drot);
}
else if (ob->rotmode == ROT_MODE_AXISANGLE) {
td->ext->rot = NULL;
@@ -5659,10 +5699,10 @@ static void ObjectToTransData(TransInfo *t, TransData *td, Object *ob)
td->ext->rotAngle = &ob->rotAngle;
td->ext->quat = NULL;
- td->ext->irotAngle = ob->rotAngle;
- copy_v3_v3(td->ext->irotAxis, ob->rotAxis);
- // td->ext->drotAngle = ob->drotAngle; // XXX, not implemented
- // copy_v3_v3(td->ext->drotAxis, ob->drotAxis); // XXX, not implemented
+ td->ext->irotAngle = ob_eval->rotAngle;
+ copy_v3_v3(td->ext->irotAxis, ob_eval->rotAxis);
+ // td->ext->drotAngle = ob_eval->drotAngle; // XXX, not implemented
+ // copy_v3_v3(td->ext->drotAxis, ob_eval->drotAxis); // XXX, not implemented
}
else {
td->ext->rot = NULL;
@@ -5670,18 +5710,18 @@ static void ObjectToTransData(TransInfo *t, TransData *td, Object *ob)
td->ext->rotAngle = NULL;
td->ext->quat = ob->quat;
- copy_qt_qt(td->ext->iquat, ob->quat);
- copy_qt_qt(td->ext->dquat, ob->dquat);
+ copy_qt_qt(td->ext->iquat, ob_eval->quat);
+ copy_qt_qt(td->ext->dquat, ob_eval->dquat);
}
- td->ext->rotOrder = ob->rotmode;
+ td->ext->rotOrder = ob_eval->rotmode;
td->ext->size = ob->size;
- copy_v3_v3(td->ext->isize, ob->size);
- copy_v3_v3(td->ext->dscale, ob->dscale);
+ copy_v3_v3(td->ext->isize, ob_eval->size);
+ copy_v3_v3(td->ext->dscale, ob_eval->dscale);
- copy_v3_v3(td->center, ob->obmat[3]);
+ copy_v3_v3(td->center, ob_eval->obmat[3]);
- copy_m4_m4(td->ext->obmat, ob->obmat);
+ copy_m4_m4(td->ext->obmat, ob_eval->obmat);
/* is there a need to set the global<->data space conversion matrices? */
if (ob->parent || constinv) {
@@ -5691,8 +5731,8 @@ static void ObjectToTransData(TransInfo *t, TransData *td, Object *ob)
* NOTE: some Constraints, and also Tracking should never get this
* done, as it doesn't work well.
*/
- BKE_object_to_mat3(ob, obmtx);
- copy_m3_m4(totmat, ob->obmat);
+ BKE_object_to_mat3(ob_eval, obmtx);
+ copy_m3_m4(totmat, ob_eval->obmat);
invert_m3_m3(obinv, totmat);
mul_m3_m3m3(td->smtx, obmtx, obinv);
invert_m3_m3(td->mtx, td->smtx);
@@ -6693,6 +6733,9 @@ void special_aftertrans_update(bContext *C, TransInfo *t)
{
/* do nothing */
}
+ else if (t->flag & T_CURSOR) {
+ /* do nothing */
+ }
else { /* Objects */
int i;
@@ -8325,7 +8368,14 @@ void createTransData(bContext *C, TransInfo *t)
t->data_len_all = -1;
/* if tests must match recalcData for correct updates */
- if (t->options & CTX_TEXTURE) {
+ if (t->options & CTX_CURSOR) {
+ t->flag |= T_CURSOR;
+ t->obedit_type = -1;
+
+ createTransCursor3D(t);
+ countAndCleanTransDataContainer(t);
+ }
+ else if (t->options & CTX_TEXTURE) {
t->flag |= T_TEXTURE;
t->obedit_type = -1;
diff --git a/source/blender/editors/transform/transform_generics.c b/source/blender/editors/transform/transform_generics.c
index 818ac86cf0c..576bfddd28c 100644
--- a/source/blender/editors/transform/transform_generics.c
+++ b/source/blender/editors/transform/transform_generics.c
@@ -1007,6 +1007,11 @@ static void recalcData_objects(TransInfo *t)
}
}
+static void recalcData_cursor(TransInfo *t)
+{
+ DEG_id_tag_update(&t->scene->id, DEG_TAG_COPY_ON_WRITE);
+}
+
/* helper for recalcData() - for sequencer transforms */
static void recalcData_sequencer(TransInfo *t)
{
@@ -1056,7 +1061,10 @@ static void recalcData_gpencil_strokes(TransInfo *t)
void recalcData(TransInfo *t)
{
/* if tests must match createTransData for correct updates */
- if (t->options & CTX_TEXTURE) {
+ if (t->options & CTX_CURSOR) {
+ recalcData_cursor(t);
+ }
+ else if (t->options & CTX_TEXTURE) {
recalcData_objects(t);
}
else if (t->options & CTX_EDGE) {
@@ -1323,9 +1331,7 @@ void initTransInfo(bContext *C, TransInfo *t, wmOperator *op, const wmEvent *eve
prop_id = "use_even_offset";
}
- if (prop_id && (prop = RNA_struct_find_property(op->ptr, prop_id)) &&
- RNA_property_is_set(op->ptr, prop))
- {
+ if (prop_id && (prop = RNA_struct_find_property(op->ptr, prop_id))) {
SET_FLAG_FROM_TEST(t->flag, RNA_property_boolean_get(op->ptr, prop), T_ALT_TRANSFORM);
}
}
@@ -1629,6 +1635,10 @@ void postTrans(bContext *C, TransInfo *t)
if (t->draw_handle_cursor)
WM_paint_cursor_end(CTX_wm_manager(C), t->draw_handle_cursor);
+ if (t->flag & T_MODAL_CURSOR_SET) {
+ WM_cursor_modal_restore(CTX_wm_window(C));
+ }
+
/* Free all custom-data */
freeTransCustomDataContainer(t, NULL, &t->custom);
FOREACH_TRANS_DATA_CONTAINER (t, tc) {
diff --git a/source/blender/editors/transform/transform_input.c b/source/blender/editors/transform/transform_input.c
index 2004bba4f09..270ef08be50 100644
--- a/source/blender/editors/transform/transform_input.c
+++ b/source/blender/editors/transform/transform_input.c
@@ -351,7 +351,8 @@ void initMouseInputMode(TransInfo *t, MouseInput *mi, MouseInputMode mode)
case HLP_NONE:
/* INPUT_VECTOR, INPUT_CUSTOM_RATIO, INPUT_CUSTOM_RATIO_FLIP */
if (t->flag & T_MODAL) {
- WM_cursor_set(win, BC_NSEW_SCROLLCURSOR);
+ t->flag |= T_MODAL_CURSOR_SET;
+ WM_cursor_modal_set(win, BC_NSEW_SCROLLCURSOR);
}
break;
case HLP_SPRING:
@@ -360,7 +361,8 @@ void initMouseInputMode(TransInfo *t, MouseInput *mi, MouseInputMode mode)
case HLP_HARROW:
case HLP_VARROW:
if (t->flag & T_MODAL) {
- WM_cursor_set(win, CURSOR_NONE);
+ t->flag |= T_MODAL_CURSOR_SET;
+ WM_cursor_modal_set(win, CURSOR_NONE);
}
break;
default:
diff --git a/source/blender/editors/transform/transform_manipulator_3d.c b/source/blender/editors/transform/transform_manipulator_3d.c
index 891d9cf67f1..b94ccf42325 100644
--- a/source/blender/editors/transform/transform_manipulator_3d.c
+++ b/source/blender/editors/transform/transform_manipulator_3d.c
@@ -596,8 +596,8 @@ int ED_transform_calc_manipulator_stats(
RegionView3D *rv3d = ar->regiondata;
Base *base;
Object *ob = OBACT(view_layer);
- const Object *ob_eval = NULL;
- const Object *obedit_eval = NULL;
+ Object *ob_eval = NULL;
+ Object *obedit_eval = NULL;
bGPdata *gpd = CTX_data_gpencil_data(C);
const bool is_gp_edit = ((gpd) && (gpd->flag & GP_DATA_STROKE_EDITMODE));
int a, totsel = 0;
@@ -629,7 +629,7 @@ int ED_transform_calc_manipulator_stats(
case V3D_MANIP_GIMBAL:
{
float mat[3][3];
- if (gimbal_axis(ob, mat)) {
+ if (gimbal_axis(ob_eval, mat)) {
copy_m4_m3(rv3d->twmat, mat);
break;
}
@@ -947,7 +947,7 @@ int ED_transform_calc_manipulator_stats(
int mode = TFM_ROTATION; // mislead counting bones... bah. We don't know the manipulator mode, could be mixed
bool ok = false;
- if ((pivot_point == V3D_AROUND_ACTIVE) && (pchan = BKE_pose_channel_active(ob))) {
+ if ((pivot_point == V3D_AROUND_ACTIVE) && (pchan = BKE_pose_channel_active(ob_eval))) {
/* doesn't check selection or visibility intentionally */
Bone *bone = pchan->bone;
if (bone) {
@@ -958,11 +958,11 @@ int ED_transform_calc_manipulator_stats(
}
}
else {
- totsel = count_set_pose_transflags(&mode, 0, ob);
+ totsel = count_set_pose_transflags(&mode, 0, ob_eval);
if (totsel) {
/* use channels to get stats */
- for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) {
+ for (pchan = ob_eval->pose->chanbase.first; pchan; pchan = pchan->next) {
Bone *bone = pchan->bone;
if (bone && (bone->flag & BONE_TRANSFORM)) {
calc_tw_center(tbounds, pchan->pose_head);
@@ -1018,7 +1018,7 @@ int ED_transform_calc_manipulator_stats(
if (!TESTBASELIB(base)) {
continue;
}
- const Object *base_object_eval = DEG_get_evaluated_object(depsgraph, base->object);
+ Object *base_object_eval = DEG_get_evaluated_object(depsgraph, base->object);
if (ob == NULL) {
ob = base->object;
ob_eval = base_object_eval;
diff --git a/source/blender/editors/transform/transform_ops.c b/source/blender/editors/transform/transform_ops.c
index 4fbb50d678e..a1b78403fc4 100644
--- a/source/blender/editors/transform/transform_ops.c
+++ b/source/blender/editors/transform/transform_ops.c
@@ -566,6 +566,10 @@ void Transform_Properties(struct wmOperatorType *ot, int flags)
RNA_def_boolean(ot->srna, "gpencil_strokes", 0, "Edit Grease Pencil", "Edit selected Grease Pencil strokes");
}
+ if (flags & P_CURSOR_EDIT) {
+ RNA_def_boolean(ot->srna, "cursor_transform", 0, "Transform Cursor", "");
+ }
+
if ((flags & P_OPTIONS) && !(flags & P_NO_TEXSPACE)) {
RNA_def_boolean(ot->srna, "texture_space", 0, "Edit Texture Space", "Edit Object data texture space");
prop = RNA_def_boolean(ot->srna, "remove_on_cancel", 0, "Remove on Cancel", "Remove elements on cancel");
@@ -573,7 +577,7 @@ void Transform_Properties(struct wmOperatorType *ot, int flags)
}
if (flags & P_CORRECT_UV) {
- RNA_def_boolean(ot->srna, "correct_uv", 0, "Correct UVs", "Correct UV coordinates when transforming");
+ RNA_def_boolean(ot->srna, "correct_uv", true, "Correct UVs", "Correct UV coordinates when transforming");
}
if (flags & P_CENTER) {
@@ -612,7 +616,10 @@ static void TRANSFORM_OT_translate(struct wmOperatorType *ot)
WM_operatortype_props_advanced_begin(ot);
- Transform_Properties(ot, P_CONSTRAINT | P_PROPORTIONAL | P_MIRROR | P_ALIGN_SNAP | P_OPTIONS | P_GPENCIL_EDIT);
+ Transform_Properties(
+ ot,
+ P_CONSTRAINT | P_PROPORTIONAL | P_MIRROR | P_ALIGN_SNAP | P_OPTIONS |
+ P_GPENCIL_EDIT | P_CURSOR_EDIT);
}
static void TRANSFORM_OT_resize(struct wmOperatorType *ot)
diff --git a/source/blender/editors/transform/transform_orientations.c b/source/blender/editors/transform/transform_orientations.c
index 19df46455d7..3065007ea6b 100644
--- a/source/blender/editors/transform/transform_orientations.c
+++ b/source/blender/editors/transform/transform_orientations.c
@@ -56,6 +56,8 @@
#include "BKE_scene.h"
#include "BKE_workspace.h"
+#include "DEG_depsgraph_query.h"
+
#include "BLT_translation.h"
#include "ED_armature.h"
@@ -1014,12 +1016,14 @@ int getTransformOrientation_ex(const bContext *C, float normal[3], float plane[3
}
}
else if (ob && (ob->mode & OB_MODE_POSE)) {
- bArmature *arm = ob->data;
+ const Depsgraph *depsgraph = CTX_data_depsgraph(C);
+ Object *ob_eval = DEG_get_evaluated_object(depsgraph, ob);
+ bArmature *arm = ob_eval->data;
bPoseChannel *pchan;
float imat[3][3], mat[3][3];
bool ok = false;
- if (activeOnly && (pchan = BKE_pose_channel_active(ob))) {
+ if (activeOnly && (pchan = BKE_pose_channel_active(ob_eval))) {
add_v3_v3(normal, pchan->pose_mat[2]);
add_v3_v3(plane, pchan->pose_mat[1]);
ok = true;
@@ -1030,7 +1034,7 @@ int getTransformOrientation_ex(const bContext *C, float normal[3], float plane[3
totsel = count_bone_select(arm, &arm->bonebase, true);
if (totsel) {
/* use channels to get stats */
- for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) {
+ for (pchan = ob_eval->pose->chanbase.first; pchan; pchan = pchan->next) {
if (pchan->bone && pchan->bone->flag & BONE_TRANSFORM) {
add_v3_v3(normal, pchan->pose_mat[2]);
add_v3_v3(plane, pchan->pose_mat[1]);
@@ -1043,7 +1047,7 @@ int getTransformOrientation_ex(const bContext *C, float normal[3], float plane[3
/* use for both active & all */
if (ok) {
/* we need the transpose of the inverse for a normal... */
- copy_m3_m4(imat, ob->obmat);
+ copy_m3_m4(imat, ob_eval->obmat);
invert_m3_m3(mat, imat);
transpose_m3(mat);
diff --git a/source/blender/editors/transform/transform_snap.c b/source/blender/editors/transform/transform_snap.c
index b858f40a3ff..10de7f3ea36 100644
--- a/source/blender/editors/transform/transform_snap.c
+++ b/source/blender/editors/transform/transform_snap.c
@@ -406,11 +406,6 @@ void applyGridAbsolute(TransInfo *t)
void applySnapping(TransInfo *t, float *vec)
{
- if (t->tsnap.project && t->tsnap.mode == SCE_SNAP_MODE_FACE) {
- /* Each Trans Data already makes the snap to face */
- return;
- }
-
if (t->tsnap.status & SNAP_FORCED) {
t->tsnap.targetSnap(t);
@@ -555,7 +550,9 @@ static void initSnappingMode(TransInfo *t)
{
/* In "Edit Strokes" mode, Snap tool can perform snap to selected or active objects (see T49632)
* TODO: perform self snap in gpencil_strokes */
- t->tsnap.modeSelect = ((t->options & CTX_GPENCIL_STROKES) != 0) ? SNAP_ALL : SNAP_NOT_SELECTED;
+ t->tsnap.modeSelect = (
+ ((t->options & (CTX_GPENCIL_STROKES | CTX_CURSOR)) != 0) ?
+ SNAP_ALL : SNAP_NOT_SELECTED);
}
else {
/* Grid if snap is not possible */
@@ -585,7 +582,7 @@ static void initSnappingMode(TransInfo *t)
if (t->spacetype == SPACE_VIEW3D) {
if (t->tsnap.object_context == NULL) {
t->tsnap.object_context = ED_transform_snap_object_context_create_view3d(
- G.main, t->scene, t->depsgraph, 0, t->ar, t->view);
+ t->scene, t->depsgraph, 0, t->ar, t->view);
ED_transform_snap_object_context_set_editmesh_callbacks(
t->tsnap.object_context,
diff --git a/source/blender/editors/transform/transform_snap_object.c b/source/blender/editors/transform/transform_snap_object.c
index db1a6cc4240..29497fe801c 100644
--- a/source/blender/editors/transform/transform_snap_object.c
+++ b/source/blender/editors/transform/transform_snap_object.c
@@ -113,7 +113,6 @@ typedef struct SnapObjectData_EditMesh {
} SnapObjectData_EditMesh;
struct SnapObjectContext {
- Main *bmain;
Scene *scene;
Depsgraph *depsgraph;
@@ -535,6 +534,10 @@ static bool raycastEditMesh(
return retval;
}
}
+ else {
+ /* COW hack: Update pointers */
+ treedata->em = em;
+ }
float imat[4][4];
float timat[3][3]; /* transpose inverse matrix for normals */
@@ -2265,13 +2268,12 @@ static short snapObjectsRay(
* \{ */
SnapObjectContext *ED_transform_snap_object_context_create(
- Main *bmain, Scene *scene, Depsgraph *depsgraph, int flag)
+ Scene *scene, Depsgraph *depsgraph, int flag)
{
SnapObjectContext *sctx = MEM_callocN(sizeof(*sctx), __func__);
sctx->flag = flag;
- sctx->bmain = bmain;
sctx->scene = scene;
sctx->depsgraph = depsgraph;
@@ -2282,11 +2284,11 @@ SnapObjectContext *ED_transform_snap_object_context_create(
}
SnapObjectContext *ED_transform_snap_object_context_create_view3d(
- Main *bmain, Scene *scene, Depsgraph *depsgraph, int flag,
+ Scene *scene, Depsgraph *depsgraph, int flag,
/* extra args for view3d */
const ARegion *ar, const View3D *v3d)
{
- SnapObjectContext *sctx = ED_transform_snap_object_context_create(bmain, scene, depsgraph, flag);
+ SnapObjectContext *sctx = ED_transform_snap_object_context_create(scene, depsgraph, flag);
sctx->use_v3d = true;
sctx->v3d_data.ar = ar;
@@ -2511,6 +2513,10 @@ static short transform_snap_context_project_view3d_mixed_impl(
/* Compute the new clip_pane but do not add it yet. */
float new_clipplane[4];
plane_from_point_normal_v3(new_clipplane, loc, no);
+ if (dot_v3v3(snapdata.clip_plane[0], new_clipplane) > 0.0f) {
+ /* The plane is facing the wrong direction. */
+ negate_v4(new_clipplane);
+ }
/* Try to snap only to the polygon. */
elem = snap_mesh_polygon(
diff --git a/source/blender/editors/uvedit/uvedit_ops.c b/source/blender/editors/uvedit/uvedit_ops.c
index f07c32370fd..fceb1532077 100644
--- a/source/blender/editors/uvedit/uvedit_ops.c
+++ b/source/blender/editors/uvedit/uvedit_ops.c
@@ -567,35 +567,45 @@ void uv_poly_copy_aspect(float uv_orig[][2], float uv[][2], float aspx, float as
}
}
-bool ED_uvedit_minmax(Scene *scene, Image *ima, Object *obedit, float r_min[2], float r_max[2])
+bool ED_uvedit_minmax_multi(
+ Scene *scene, Image *ima, Object **objects_edit, uint objects_len,
+ float r_min[2], float r_max[2])
{
- BMEditMesh *em = BKE_editmesh_from_object(obedit);
- BMFace *efa;
- BMLoop *l;
- BMIter iter, liter;
- MLoopUV *luv;
bool changed = false;
+ INIT_MINMAX2(r_min, r_max);
- const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
+ for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
+ Object *obedit = objects_edit[ob_index];
- INIT_MINMAX2(r_min, r_max);
+ BMEditMesh *em = BKE_editmesh_from_object(obedit);
+ BMFace *efa;
+ BMLoop *l;
+ BMIter iter, liter;
+ MLoopUV *luv;
- BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
- if (!uvedit_face_visible_test(scene, obedit, ima, efa))
- continue;
-
- BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
- if (uvedit_uv_select_test(scene, l, cd_loop_uv_offset)) {
- luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
- minmax_v2v2_v2(r_min, r_max, luv->uv);
- changed = true;
+ const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
+
+ BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
+ if (!uvedit_face_visible_test(scene, obedit, ima, efa))
+ continue;
+
+ BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
+ if (uvedit_uv_select_test(scene, l, cd_loop_uv_offset)) {
+ luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
+ minmax_v2v2_v2(r_min, r_max, luv->uv);
+ changed = true;
+ }
}
}
}
-
return changed;
}
+bool ED_uvedit_minmax(Scene *scene, Image *ima, Object *obedit, float r_min[2], float r_max[2])
+{
+ return ED_uvedit_minmax_multi(scene, ima, &obedit, 1, r_min, r_max);
+}
+
/* Be careful when using this, it bypasses all synchronization options */
void ED_uvedit_select_all(BMesh *bm)
{
@@ -614,27 +624,32 @@ void ED_uvedit_select_all(BMesh *bm)
}
}
-static bool ED_uvedit_median(Scene *scene, Image *ima, Object *obedit, float co[2])
+static bool ED_uvedit_median_multi(Scene *scene, Image *ima, Object **objects_edit, uint objects_len, float co[2])
{
- BMEditMesh *em = BKE_editmesh_from_object(obedit);
- BMFace *efa;
- BMLoop *l;
- BMIter iter, liter;
- MLoopUV *luv;
unsigned int sel = 0;
+ zero_v2(co);
- const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
+ for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
+ Object *obedit = objects_edit[ob_index];
- zero_v2(co);
- BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
- if (!uvedit_face_visible_test(scene, obedit, ima, efa))
- continue;
-
- BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
- luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
- if (uvedit_uv_select_test(scene, l, cd_loop_uv_offset)) {
- add_v2_v2(co, luv->uv);
- sel++;
+ BMEditMesh *em = BKE_editmesh_from_object(obedit);
+ BMFace *efa;
+ BMLoop *l;
+ BMIter iter, liter;
+ MLoopUV *luv;
+
+ const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
+
+ BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
+ if (!uvedit_face_visible_test(scene, obedit, ima, efa))
+ continue;
+
+ BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
+ luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
+ if (uvedit_uv_select_test(scene, l, cd_loop_uv_offset)) {
+ add_v2_v2(co, luv->uv);
+ sel++;
+ }
}
}
}
@@ -644,19 +659,24 @@ static bool ED_uvedit_median(Scene *scene, Image *ima, Object *obedit, float co[
return (sel != 0);
}
-bool ED_uvedit_center(Scene *scene, Image *ima, Object *obedit, float cent[2], char mode)
+static bool UNUSED_FUNCTION(ED_uvedit_median)(Scene *scene, Image *ima, Object *obedit, float co[2])
+{
+ return ED_uvedit_median_multi(scene, ima, &obedit, 1, co);
+}
+
+bool ED_uvedit_center_multi(Scene *scene, Image *ima, Object **objects_edit, uint objects_len, float cent[2], char mode)
{
bool changed = false;
if (mode == V3D_AROUND_CENTER_BOUNDS) { /* bounding box */
float min[2], max[2];
- if (ED_uvedit_minmax(scene, ima, obedit, min, max)) {
+ if (ED_uvedit_minmax_multi(scene, ima, objects_edit, objects_len, min, max)) {
mid_v2_v2v2(cent, min, max);
changed = true;
}
}
else {
- if (ED_uvedit_median(scene, ima, obedit, cent)) {
+ if (ED_uvedit_median_multi(scene, ima, objects_edit, objects_len, cent)) {
changed = true;
}
}
@@ -664,6 +684,11 @@ bool ED_uvedit_center(Scene *scene, Image *ima, Object *obedit, float cent[2], c
return changed;
}
+bool ED_uvedit_center(Scene *scene, Image *ima, Object *obedit, float cent[2], char mode)
+{
+ return ED_uvedit_center_multi(scene, ima, &obedit, 1, cent, mode);
+}
+
/** \} */
/* -------------------------------------------------------------------- */
@@ -3357,17 +3382,16 @@ static void uv_snap_cursor_to_pixels(SpaceImage *sima)
uv_snap_to_pixel(sima->cursor, width, height);
}
-static bool uv_snap_cursor_to_selection(Scene *scene, Image *ima, Object *obedit, SpaceImage *sima)
+static bool uv_snap_cursor_to_selection(
+ Scene *scene, Image *ima, Object **objects_edit, uint objects_len, SpaceImage *sima)
{
- return ED_uvedit_center(scene, ima, obedit, sima->cursor, sima->around);
+ return ED_uvedit_center_multi(scene, ima, objects_edit, objects_len, sima->cursor, sima->around);
}
static int uv_snap_cursor_exec(bContext *C, wmOperator *op)
{
SpaceImage *sima = CTX_wm_space_image(C);
- Scene *scene = CTX_data_scene(C);
- Object *obedit = CTX_data_edit_object(C);
- Image *ima = CTX_data_edit_image(C);
+
bool changed = false;
switch (RNA_enum_get(op->ptr, "target")) {
@@ -3376,8 +3400,18 @@ static int uv_snap_cursor_exec(bContext *C, wmOperator *op)
changed = true;
break;
case 1:
- changed = uv_snap_cursor_to_selection(scene, ima, obedit, sima);
+ {
+ Scene *scene = CTX_data_scene(C);
+ Image *ima = CTX_data_edit_image(C);
+ ViewLayer *view_layer = CTX_data_view_layer(C);
+
+ uint objects_len = 0;
+ Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data_with_uvs(
+ view_layer, &objects_len);
+ changed = uv_snap_cursor_to_selection(scene, ima, objects, objects_len, sima);
+ MEM_freeN(objects);
break;
+ }
}
if (!changed)
diff --git a/source/blender/gpu/shaders/gpu_shader_material.glsl b/source/blender/gpu/shaders/gpu_shader_material.glsl
index 4306fe17e96..a6bfb09141c 100644
--- a/source/blender/gpu/shaders/gpu_shader_material.glsl
+++ b/source/blender/gpu/shaders/gpu_shader_material.glsl
@@ -396,6 +396,11 @@ void math_abs(float val1, out float outval)
outval = abs(val1);
}
+void math_atan2(float val1, float val2, out float outval)
+{
+ outval = atan(val1, val2);
+}
+
void squeeze(float val, float width, float center, out float outval)
{
outval = 1.0 / (1.0 + pow(2.71828183, -((val - center) * width)));
diff --git a/source/blender/makesdna/DNA_ID.h b/source/blender/makesdna/DNA_ID.h
index acf054a94d5..4d59a7c9669 100644
--- a/source/blender/makesdna/DNA_ID.h
+++ b/source/blender/makesdna/DNA_ID.h
@@ -397,6 +397,10 @@ typedef enum ID_Type {
ID_IS_STATIC_OVERRIDE((_id)) && \
(((ID *)(_id))->override_static->flag & STATICOVERRIDE_AUTO))
+/* No copy-on-write for these types. */
+#define ID_TYPE_IS_COW(_id_type) \
+ (!ELEM(_id_type, ID_WM, ID_SCR, ID_SCRN, ID_IM, ID_MC, ID_LI))
+
#ifdef GS
# undef GS
#endif
diff --git a/source/blender/makesdna/DNA_lamp_types.h b/source/blender/makesdna/DNA_lamp_types.h
index 6294afe00e7..3a4b07cc791 100644
--- a/source/blender/makesdna/DNA_lamp_types.h
+++ b/source/blender/makesdna/DNA_lamp_types.h
@@ -148,6 +148,8 @@ typedef struct Lamp {
#define LA_AREA_RECT 1
#define LA_AREA_CUBE 2
#define LA_AREA_BOX 3
+#define LA_AREA_DISK 4
+#define LA_AREA_ELLIPSE 5
#endif /* __DNA_LAMP_TYPES_H__ */
diff --git a/source/blender/makesdna/DNA_modifier_types.h b/source/blender/makesdna/DNA_modifier_types.h
index 989e0768fc1..1d7d1b34f6b 100644
--- a/source/blender/makesdna/DNA_modifier_types.h
+++ b/source/blender/makesdna/DNA_modifier_types.h
@@ -740,7 +740,7 @@ typedef struct ParticleSystemModifierData {
struct ParticleSystem *psys;
struct Mesh *mesh_final; /* Final Mesh - its topology may differ from orig mesh. */
- struct Mesh *mesh_deformed; /* Deformed-only Mesh - its topology is same as orig mesh one. */
+ struct Mesh *mesh_original; /* Original mesh that particles are attached to. */
int totdmvert, totdmedge, totdmface;
short flag, pad;
} ParticleSystemModifierData;
@@ -1615,6 +1615,7 @@ typedef struct SDefVert {
typedef struct SurfaceDeformModifierData {
ModifierData modifier;
+ struct Depsgraph *depsgraph;
struct Object *target; /* bind target object */
SDefVert *verts; /* vertex bind data */
float falloff;
diff --git a/source/blender/makesdna/DNA_node_types.h b/source/blender/makesdna/DNA_node_types.h
index b5a3752072b..af1045ee059 100644
--- a/source/blender/makesdna/DNA_node_types.h
+++ b/source/blender/makesdna/DNA_node_types.h
@@ -891,6 +891,12 @@ typedef struct NodeShaderUVMap {
char uv_map[64];
} NodeShaderUVMap;
+typedef struct NodeShaderTexIES {
+ int mode;
+
+ char filepath[1024]; /* 1024 = FILE_MAX */
+} NodeShaderTexIES;
+
typedef struct NodeSunBeams {
float source[2];
@@ -904,6 +910,9 @@ typedef struct NodeSunBeams {
/* script node flag */
#define NODE_SCRIPT_AUTO_UPDATE 1
+/* ies node mode */
+#define NODE_IES_INTERNAL 0
+#define NODE_IES_EXTERNAL 1
/* frame node flags */
#define NODE_FRAME_SHRINK 1 /* keep the bounding box minimal */
@@ -1058,6 +1067,7 @@ enum {
NODE_MATH_GREATER = 16,
NODE_MATH_MOD = 17,
NODE_MATH_ABS = 18,
+ NODE_MATH_ATAN2 = 19,
};
/* mix rgb node flags */
diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h
index 2c39576d0c9..0559df7950d 100644
--- a/source/blender/makesdna/DNA_scene_types.h
+++ b/source/blender/makesdna/DNA_scene_types.h
@@ -2064,43 +2064,6 @@ typedef enum eGPencil_Placement_Flags {
#define PE_TYPE_SOFTBODY 1
#define PE_TYPE_CLOTH 2
-/* ToolSettings.skgen_options */
-#define SKGEN_FILTER_INTERNAL (1 << 0)
-#define SKGEN_FILTER_EXTERNAL (1 << 1)
-#define SKGEN_SYMMETRY (1 << 2)
-#define SKGEN_CUT_LENGTH (1 << 3)
-#define SKGEN_CUT_ANGLE (1 << 4)
-#define SKGEN_CUT_CORRELATION (1 << 5)
-#define SKGEN_HARMONIC (1 << 6)
-#define SKGEN_STICK_TO_EMBEDDING (1 << 7)
-#define SKGEN_ADAPTIVE_DISTANCE (1 << 8)
-#define SKGEN_FILTER_SMART (1 << 9)
-#define SKGEN_DISP_LENGTH (1 << 10)
-#define SKGEN_DISP_WEIGHT (1 << 11)
-#define SKGEN_DISP_ORIG (1 << 12)
-#define SKGEN_DISP_EMBED (1 << 13)
-#define SKGEN_DISP_INDEX (1 << 14)
-
-#define SKGEN_SUB_LENGTH 0
-#define SKGEN_SUB_ANGLE 1
-#define SKGEN_SUB_CORRELATION 2
-#define SKGEN_SUB_TOTAL 3
-
-/* ToolSettings.skgen_postpro */
-#define SKGEN_SMOOTH 0
-#define SKGEN_AVERAGE 1
-#define SKGEN_SHARPEN 2
-
-/* ToolSettings.bone_sketching */
-#define BONE_SKETCHING 1
-#define BONE_SKETCHING_QUICK 2
-#define BONE_SKETCHING_ADJUST 4
-
-/* ToolSettings.skgen_retarget_roll */
-#define SK_RETARGET_ROLL_NONE 0
-#define SK_RETARGET_ROLL_VIEW 1
-#define SK_RETARGET_ROLL_JOINT 2
-
/* PhysicsSettings.flag */
#define PHYS_GLOBAL_GRAVITY 1
diff --git a/source/blender/makesdna/DNA_userdef_types.h b/source/blender/makesdna/DNA_userdef_types.h
index 326d42d9cb3..9817d44c96b 100644
--- a/source/blender/makesdna/DNA_userdef_types.h
+++ b/source/blender/makesdna/DNA_userdef_types.h
@@ -406,6 +406,7 @@ typedef struct bTheme {
ThemeSpace tconsole;
ThemeSpace tclip;
ThemeSpace ttopbar;
+ ThemeSpace tstatusbar;
/* 20 sets of bone colors for this theme */
ThemeWireColor tarm[20];
diff --git a/source/blender/makesdna/DNA_view3d_types.h b/source/blender/makesdna/DNA_view3d_types.h
index cb6031b0a3e..dd3e0c25992 100644
--- a/source/blender/makesdna/DNA_view3d_types.h
+++ b/source/blender/makesdna/DNA_view3d_types.h
@@ -338,7 +338,7 @@ enum {
/* View3DShading->flag */
enum {
V3D_SHADING_OBJECT_OUTLINE = (1 << 0),
- V3D_SHADING_SEE_THROUGH = (1 << 1),
+ V3D_SHADING_XRAY = (1 << 1),
V3D_SHADING_SHADOW = (1 << 2),
};
diff --git a/source/blender/makesdna/DNA_workspace_types.h b/source/blender/makesdna/DNA_workspace_types.h
index 83b6867afd3..b29e1f808c0 100644
--- a/source/blender/makesdna/DNA_workspace_types.h
+++ b/source/blender/makesdna/DNA_workspace_types.h
@@ -126,7 +126,7 @@ typedef struct WorkSpace {
/* Store for each hook (so for each window) which layout has
* been activated the last time this workspace was visible. */
ListBase hook_layout_relations DNA_PRIVATE_WORKSPACE_READ_WRITE; /* WorkSpaceDataRelation */
- ListBase scene_viewlayer_relations DNA_PRIVATE_WORKSPACE_READ_WRITE; /* WorkSpaceDataRelation */
+ ListBase scene_layer_relations; /* WorkSpaceSceneRelation */
/* Feature tagging (use for addons) */
ListBase owner_ids DNA_PRIVATE_WORKSPACE_READ_WRITE; /* wmOwnerID */
@@ -180,13 +180,17 @@ typedef struct WorkSpaceDataRelation {
void *parent;
/* The value for this parent-data/workspace relation */
void *value;
-
- /** Use when we reference non-ID data, this allows use to look it up when linking in a workspace. */
- char value_name[64]; /* MAX_NAME. */
} WorkSpaceDataRelation;
#endif /* DNA_PRIVATE_WORKSPACE_READ_WRITE */
+typedef struct WorkSpaceSceneRelation {
+ struct WorkSpaceSceneRelation *next, *prev;
+
+ struct Scene *scene;
+ char view_layer[64]; /* MAX_NAME */
+} WorkSpaceSceneRelation;
+
/**
* Little wrapper to store data that is going to be per window, but comming from the workspace.
* It allows us to keep workspace and window data completely separate.
diff --git a/source/blender/makesrna/RNA_access.h b/source/blender/makesrna/RNA_access.h
index 8e0264e208d..7431f48367c 100644
--- a/source/blender/makesrna/RNA_access.h
+++ b/source/blender/makesrna/RNA_access.h
@@ -527,6 +527,7 @@ extern StructRNA RNA_ShaderNodeCombineRGB;
extern StructRNA RNA_ShaderNodeExtendedMaterial;
extern StructRNA RNA_ShaderNodeGeometry;
extern StructRNA RNA_ShaderNodeHueSaturation;
+extern StructRNA RNA_ShaderNodeIESLight;
extern StructRNA RNA_ShaderNodeInvert;
extern StructRNA RNA_ShaderNodeLampData;
extern StructRNA RNA_ShaderNodeMapping;
diff --git a/source/blender/makesrna/intern/makesrna.c b/source/blender/makesrna/intern/makesrna.c
index 1c55925809a..80d1897f604 100644
--- a/source/blender/makesrna/intern/makesrna.c
+++ b/source/blender/makesrna/intern/makesrna.c
@@ -3482,7 +3482,7 @@ static void rna_generate(BlenderRNA *brna, FILE *f, const char *filename, const
/* we want the included C files to have warnings enabled but for the generated code
* ignore unused-parameter warnings which are hard to prevent */
-#ifdef __GNUC__
+#if defined( __GNUC__) || defined(__clang__)
fprintf(f, "#pragma GCC diagnostic ignored \"-Wunused-parameter\"\n\n");
#endif
diff --git a/source/blender/makesrna/intern/rna_ID.c b/source/blender/makesrna/intern/rna_ID.c
index 952d27fa18d..1ea452bf389 100644
--- a/source/blender/makesrna/intern/rna_ID.c
+++ b/source/blender/makesrna/intern/rna_ID.c
@@ -500,9 +500,9 @@ static Material *rna_IDMaterials_pop_id(ID *id, Main *bmain, ReportList *reports
return ma;
}
-static void rna_IDMaterials_clear_id(ID *id, int remove_material_slot)
+static void rna_IDMaterials_clear_id(ID *id, Main *bmain, int remove_material_slot)
{
- BKE_material_clear_id(G.main, id, remove_material_slot);
+ BKE_material_clear_id(bmain, id, remove_material_slot);
DEG_id_tag_update(id, OB_RECALC_DATA);
WM_main_add_notifier(NC_OBJECT | ND_DRAW, id);
@@ -945,6 +945,7 @@ static void rna_def_ID_materials(BlenderRNA *brna)
RNA_def_function_return(func, parm);
func = RNA_def_function(srna, "clear", "rna_IDMaterials_clear_id");
+ RNA_def_function_flag(func, FUNC_USE_MAIN);
RNA_def_function_ui_description(func, "Remove all materials from the data-block");
RNA_def_boolean(func, "update_data", 0, "", "Update data by re-adjusting the material slots assigned");
}
diff --git a/source/blender/makesrna/intern/rna_access.c b/source/blender/makesrna/intern/rna_access.c
index a6a834465ff..5a0dec28324 100644
--- a/source/blender/makesrna/intern/rna_access.c
+++ b/source/blender/makesrna/intern/rna_access.c
@@ -2064,10 +2064,15 @@ static void rna_property_update(bContext *C, Main *bmain, Scene *scene, PointerR
else
prop->update(bmain, scene, ptr);
}
-#if 0
- if (prop->noteflag)
+
+#if 1
+ /* TODO(campbell): Should eventually be replaced entirely by message bus (below)
+ * for now keep since COW, bugs are hard to track when we have other missing updates. */
+ if (prop->noteflag) {
WM_main_add_notifier(prop->noteflag, ptr->id.data);
-#else
+ }
+#endif
+
/* if C is NULL, we're updating from animation.
* avoid slow-down from f-curves by not publishing (for now). */
if (C != NULL) {
@@ -2075,9 +2080,15 @@ static void rna_property_update(bContext *C, Main *bmain, Scene *scene, PointerR
/* we could add NULL check, for now don't */
WM_msg_publish_rna(mbus, ptr, prop);
}
-#endif
+ if (ptr->id.data != NULL) {
+ const short id_type = GS(((ID *)ptr->id.data)->name);
+ if (ID_TYPE_IS_COW(id_type)) {
+ DEG_id_tag_update(ptr->id.data, DEG_TAG_COPY_ON_WRITE);
+ }
+ }
+ /* End message bus. */
}
-
+
if (!is_rna || (prop->flag & PROP_IDPROPERTY)) {
/* WARNING! This is so property drivers update the display!
* not especially nice */
diff --git a/source/blender/makesrna/intern/rna_armature.c b/source/blender/makesrna/intern/rna_armature.c
index 0819a5e828e..30c643388af 100644
--- a/source/blender/makesrna/intern/rna_armature.c
+++ b/source/blender/makesrna/intern/rna_armature.c
@@ -168,8 +168,10 @@ static void rna_Bone_select_update(Main *UNUSED(bmain), Scene *UNUSED(scene), Po
{
ID *id = ptr->id.data;
- /* special updates for cases where rigs try to hook into armature drawing stuff
- * e.g. Mask Modifier - 'Armature' option
+ /* 1) special updates for cases where rigs try to hook into armature drawing stuff
+ * e.g. Mask Modifier - 'Armature' option
+ * 2) tag armature for copy-on-write, so that selection status (set by addons)
+ * will update properly, like standard tools do already
*/
if (id) {
if (GS(id->name) == ID_AR) {
@@ -178,6 +180,8 @@ static void rna_Bone_select_update(Main *UNUSED(bmain), Scene *UNUSED(scene), Po
if (arm->flag & ARM_HAS_VIZ_DEPS) {
DEG_id_tag_update(id, OB_RECALC_DATA);
}
+
+ DEG_id_tag_update(id, DEG_TAG_COPY_ON_WRITE);
}
else if (GS(id->name) == ID_OB) {
Object *ob = (Object *)id;
@@ -186,6 +190,8 @@ static void rna_Bone_select_update(Main *UNUSED(bmain), Scene *UNUSED(scene), Po
if (arm->flag & ARM_HAS_VIZ_DEPS) {
DEG_id_tag_update(id, OB_RECALC_DATA);
}
+
+ DEG_id_tag_update(&arm->id, DEG_TAG_COPY_ON_WRITE);
}
}
diff --git a/source/blender/makesrna/intern/rna_lamp.c b/source/blender/makesrna/intern/rna_lamp.c
index 5bb24f0270d..d123cdb9773 100644
--- a/source/blender/makesrna/intern/rna_lamp.c
+++ b/source/blender/makesrna/intern/rna_lamp.c
@@ -394,6 +394,8 @@ static void rna_def_area_lamp(BlenderRNA *brna)
static const EnumPropertyItem prop_areashape_items[] = {
{LA_AREA_SQUARE, "SQUARE", 0, "Square", ""},
{LA_AREA_RECT, "RECTANGLE", 0, "Rectangle", ""},
+ {LA_AREA_DISK, "DISK", 0, "Disk", ""},
+ {LA_AREA_ELLIPSE, "ELLIPSE", 0, "Ellipse", ""},
{0, NULL, 0, NULL, NULL}
};
diff --git a/source/blender/makesrna/intern/rna_lightprobe.c b/source/blender/makesrna/intern/rna_lightprobe.c
index d4b94bfb3be..f3091ae5ee1 100644
--- a/source/blender/makesrna/intern/rna_lightprobe.c
+++ b/source/blender/makesrna/intern/rna_lightprobe.c
@@ -187,17 +187,17 @@ static void rna_def_lightprobe(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Intensity", "Modify the intensity of the lighting captured by this probe");
RNA_def_property_update(prop, NC_MATERIAL | ND_SHADING, "rna_LightProbe_recalc");
- prop = RNA_def_property(srna, "visibility_group", PROP_POINTER, PROP_NONE);
+ prop = RNA_def_property(srna, "visibility_collection", PROP_POINTER, PROP_NONE);
RNA_def_property_struct_type(prop, "Collection");
RNA_def_property_pointer_sdna(prop, NULL, "visibility_grp");
RNA_def_property_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "Visibility Collection", "Restrict objects visible for this probe");
RNA_def_property_update(prop, NC_MATERIAL | ND_SHADING, "rna_LightProbe_recalc");
- prop = RNA_def_property(srna, "invert_visibility_group", PROP_BOOLEAN, PROP_NONE);
+ prop = RNA_def_property(srna, "invert_visibility_collection", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", LIGHTPROBE_FLAG_INVERT_GROUP);
RNA_def_property_flag(prop, PROP_EDITABLE);
- RNA_def_property_ui_text(prop, "Invert Group", "Invert visibility group");
+ RNA_def_property_ui_text(prop, "Invert Collection", "Invert visibility collection");
RNA_def_property_update(prop, NC_MATERIAL | ND_SHADING, "rna_LightProbe_recalc");
/* Data preview */
diff --git a/source/blender/makesrna/intern/rna_material.c b/source/blender/makesrna/intern/rna_material.c
index 7dc76120097..a40606018e7 100644
--- a/source/blender/makesrna/intern/rna_material.c
+++ b/source/blender/makesrna/intern/rna_material.c
@@ -372,9 +372,9 @@ void RNA_def_material(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Clip Threshold", "A pixel is rendered only if its alpha value is above this threshold");
RNA_def_property_update(prop, 0, "rna_Material_draw_update");
- prop = RNA_def_property(srna, "transparent_hide_backside", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_sdna(prop, NULL, "blend_flag", MA_BL_HIDE_BACKSIDE);
- RNA_def_property_ui_text(prop, "Hide Backside", "Limit transparency to a single layer "
+ prop = RNA_def_property(srna, "show_transparent_backside", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_negative_sdna(prop, NULL, "blend_flag", MA_BL_HIDE_BACKSIDE);
+ RNA_def_property_ui_text(prop, "Show Backside", "Limit transparency to a single layer "
"(avoids transparency sorting problems)");
RNA_def_property_update(prop, 0, "rna_Material_draw_update");
@@ -519,7 +519,8 @@ static void rna_def_tex_slot(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "UV Map", "Name of UV map");
RNA_def_property_update(prop, NC_GEOM | ND_DATA, "rna_Material_update");
- prop = RNA_def_property(srna, "valid", PROP_BOOLEAN, PROP_NONE);
+ prop = RNA_def_property(srna, "is_valid", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "valid", 1);
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "Valid", "Slot has a valid image and UV map");
}
diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c
index 79a1ce73071..d2fb9d19acc 100644
--- a/source/blender/makesrna/intern/rna_nodetree.c
+++ b/source/blender/makesrna/intern/rna_nodetree.c
@@ -143,6 +143,7 @@ const EnumPropertyItem rna_enum_node_math_items[] = {
{NODE_MATH_GREATER, "GREATER_THAN", 0, "Greater Than", ""},
{NODE_MATH_MOD, "MODULO", 0, "Modulo", ""},
{NODE_MATH_ABS, "ABSOLUTE", 0, "Absolute", ""},
+ {NODE_MATH_ATAN2, "ARCTAN2", 0, "Arctan2", ""},
{0, NULL, 0, NULL, NULL}
};
@@ -730,7 +731,7 @@ static bNode *rna_NodeTree_node_new(bNodeTree *ntree, bContext *C, ReportList *r
return node;
}
-static void rna_NodeTree_node_remove(bNodeTree *ntree, ReportList *reports, PointerRNA *node_ptr)
+static void rna_NodeTree_node_remove(bNodeTree *ntree, Main *bmain, ReportList *reports, PointerRNA *node_ptr)
{
bNode *node = node_ptr->data;
@@ -746,11 +747,11 @@ static void rna_NodeTree_node_remove(bNodeTree *ntree, ReportList *reports, Poin
nodeFreeNode(ntree, node);
RNA_POINTER_INVALIDATE(node_ptr);
- ntreeUpdateTree(G.main, ntree); /* update group node socket links */
+ ntreeUpdateTree(bmain, ntree); /* update group node socket links */
WM_main_add_notifier(NC_NODE | NA_EDITED, ntree);
}
-static void rna_NodeTree_node_clear(bNodeTree *ntree, ReportList *reports)
+static void rna_NodeTree_node_clear(bNodeTree *ntree, Main *bmain, ReportList *reports)
{
bNode *node = ntree->nodes.first;
@@ -768,7 +769,7 @@ static void rna_NodeTree_node_clear(bNodeTree *ntree, ReportList *reports)
node = next_node;
}
- ntreeUpdateTree(G.main, ntree);
+ ntreeUpdateTree(bmain, ntree);
WM_main_add_notifier(NC_NODE | NA_EDITED, ntree);
}
@@ -791,7 +792,7 @@ static void rna_NodeTree_active_node_set(PointerRNA *ptr, const PointerRNA value
nodeClearActive(ntree);
}
-static bNodeLink *rna_NodeTree_link_new(bNodeTree *ntree, ReportList *reports,
+static bNodeLink *rna_NodeTree_link_new(bNodeTree *ntree, Main *bmain, ReportList *reports,
bNodeSocket *fromsock, bNodeSocket *tosock,
int verify_limits)
{
@@ -833,15 +834,15 @@ static bNodeLink *rna_NodeTree_link_new(bNodeTree *ntree, ReportList *reports,
if (tonode)
nodeUpdate(ntree, tonode);
- ntreeUpdateTree(G.main, ntree);
+ ntreeUpdateTree(bmain, ntree);
- ED_node_tag_update_nodetree(G.main, ntree, ret->tonode);
+ ED_node_tag_update_nodetree(bmain, ntree, ret->tonode);
WM_main_add_notifier(NC_NODE | NA_EDITED, ntree);
}
return ret;
}
-static void rna_NodeTree_link_remove(bNodeTree *ntree, ReportList *reports, PointerRNA *link_ptr)
+static void rna_NodeTree_link_remove(bNodeTree *ntree, Main *bmain, ReportList *reports, PointerRNA *link_ptr)
{
bNodeLink *link = link_ptr->data;
@@ -856,11 +857,11 @@ static void rna_NodeTree_link_remove(bNodeTree *ntree, ReportList *reports, Poin
nodeRemLink(ntree, link);
RNA_POINTER_INVALIDATE(link_ptr);
- ntreeUpdateTree(G.main, ntree);
+ ntreeUpdateTree(bmain, ntree);
WM_main_add_notifier(NC_NODE | NA_EDITED, ntree);
}
-static void rna_NodeTree_link_clear(bNodeTree *ntree, ReportList *reports)
+static void rna_NodeTree_link_clear(bNodeTree *ntree, Main *bmain, ReportList *reports)
{
bNodeLink *link = ntree->links.first;
@@ -874,7 +875,7 @@ static void rna_NodeTree_link_clear(bNodeTree *ntree, ReportList *reports)
link = next_link;
}
- ntreeUpdateTree(G.main, ntree);
+ ntreeUpdateTree(bmain, ntree);
WM_main_add_notifier(NC_NODE | NA_EDITED, ntree);
}
@@ -937,7 +938,7 @@ static void rna_NodeTree_active_output_set(PointerRNA *ptr, int value)
}
}
-static bNodeSocket *rna_NodeTree_inputs_new(bNodeTree *ntree, ReportList *reports, const char *type, const char *name)
+static bNodeSocket *rna_NodeTree_inputs_new(bNodeTree *ntree, Main *bmain, ReportList *reports, const char *type, const char *name)
{
bNodeSocket *sock;
@@ -946,13 +947,13 @@ static bNodeSocket *rna_NodeTree_inputs_new(bNodeTree *ntree, ReportList *report
sock = ntreeAddSocketInterface(ntree, SOCK_IN, type, name);
- ntreeUpdateTree(G.main, ntree);
+ ntreeUpdateTree(bmain, ntree);
WM_main_add_notifier(NC_NODE | NA_EDITED, ntree);
return sock;
}
-static bNodeSocket *rna_NodeTree_outputs_new(bNodeTree *ntree, ReportList *reports, const char *type, const char *name)
+static bNodeSocket *rna_NodeTree_outputs_new(bNodeTree *ntree, Main *bmain, ReportList *reports, const char *type, const char *name)
{
bNodeSocket *sock;
@@ -961,13 +962,13 @@ static bNodeSocket *rna_NodeTree_outputs_new(bNodeTree *ntree, ReportList *repor
sock = ntreeAddSocketInterface(ntree, SOCK_OUT, type, name);
- ntreeUpdateTree(G.main, ntree);
+ ntreeUpdateTree(bmain, ntree);
WM_main_add_notifier(NC_NODE | NA_EDITED, ntree);
return sock;
}
-static void rna_NodeTree_socket_remove(bNodeTree *ntree, ReportList *reports, bNodeSocket *sock)
+static void rna_NodeTree_socket_remove(bNodeTree *ntree, Main *bmain, ReportList *reports, bNodeSocket *sock)
{
if (!rna_NodeTree_check(ntree, reports))
return;
@@ -978,12 +979,12 @@ static void rna_NodeTree_socket_remove(bNodeTree *ntree, ReportList *reports, bN
else {
ntreeRemoveSocketInterface(ntree, sock);
- ntreeUpdateTree(G.main, ntree);
+ ntreeUpdateTree(bmain, ntree);
WM_main_add_notifier(NC_NODE | NA_EDITED, ntree);
}
}
-static void rna_NodeTree_inputs_clear(bNodeTree *ntree, ReportList *reports)
+static void rna_NodeTree_inputs_clear(bNodeTree *ntree, Main *bmain, ReportList *reports)
{
bNodeSocket *sock, *nextsock;
@@ -995,11 +996,11 @@ static void rna_NodeTree_inputs_clear(bNodeTree *ntree, ReportList *reports)
ntreeRemoveSocketInterface(ntree, sock);
}
- ntreeUpdateTree(G.main, ntree);
+ ntreeUpdateTree(bmain, ntree);
WM_main_add_notifier(NC_NODE | NA_EDITED, ntree);
}
-static void rna_NodeTree_outputs_clear(bNodeTree *ntree, ReportList *reports)
+static void rna_NodeTree_outputs_clear(bNodeTree *ntree, Main *bmain, ReportList *reports)
{
bNodeSocket *sock, *nextsock;
@@ -1011,11 +1012,11 @@ static void rna_NodeTree_outputs_clear(bNodeTree *ntree, ReportList *reports)
ntreeRemoveSocketInterface(ntree, sock);
}
- ntreeUpdateTree(G.main, ntree);
+ ntreeUpdateTree(bmain, ntree);
WM_main_add_notifier(NC_NODE | NA_EDITED, ntree);
}
-static void rna_NodeTree_inputs_move(bNodeTree *ntree, int from_index, int to_index)
+static void rna_NodeTree_inputs_move(bNodeTree *ntree, Main *bmain, int from_index, int to_index)
{
bNodeSocket *sock;
@@ -1042,11 +1043,11 @@ static void rna_NodeTree_inputs_move(bNodeTree *ntree, int from_index, int to_in
ntree->update |= NTREE_UPDATE_GROUP_IN;
- ntreeUpdateTree(G.main, ntree);
+ ntreeUpdateTree(bmain, ntree);
WM_main_add_notifier(NC_NODE | NA_EDITED, ntree);
}
-static void rna_NodeTree_outputs_move(bNodeTree *ntree, int from_index, int to_index)
+static void rna_NodeTree_outputs_move(bNodeTree *ntree, Main *bmain, int from_index, int to_index)
{
bNodeSocket *sock;
@@ -1073,16 +1074,18 @@ static void rna_NodeTree_outputs_move(bNodeTree *ntree, int from_index, int to_i
ntree->update |= NTREE_UPDATE_GROUP_OUT;
- ntreeUpdateTree(G.main, ntree);
+ ntreeUpdateTree(bmain, ntree);
WM_main_add_notifier(NC_NODE | NA_EDITED, ntree);
}
static void rna_NodeTree_interface_update(bNodeTree *ntree, bContext *C)
{
+ Main *bmain = CTX_data_main(C);
+
ntree->update |= NTREE_UPDATE_GROUP;
- ntreeUpdateTree(G.main, ntree);
+ ntreeUpdateTree(bmain, ntree);
- ED_node_tag_update_nodetree(CTX_data_main(C), ntree, NULL);
+ ED_node_tag_update_nodetree(bmain, ntree, NULL);
}
@@ -1612,7 +1615,7 @@ static void rna_Node_name_set(PointerRNA *ptr, const char *value)
BKE_animdata_fix_paths_rename_all(NULL, "nodes", oldname, node->name);
}
-static bNodeSocket *rna_Node_inputs_new(ID *id, bNode *node, ReportList *reports, const char *type, const char *name, const char *identifier)
+static bNodeSocket *rna_Node_inputs_new(ID *id, bNode *node, Main *bmain, ReportList *reports, const char *type, const char *name, const char *identifier)
{
bNodeTree *ntree = (bNodeTree *)id;
bNodeSocket *sock;
@@ -1623,14 +1626,14 @@ static bNodeSocket *rna_Node_inputs_new(ID *id, bNode *node, ReportList *reports
BKE_report(reports, RPT_ERROR, "Unable to create socket");
}
else {
- ntreeUpdateTree(G.main, ntree);
+ ntreeUpdateTree(bmain, ntree);
WM_main_add_notifier(NC_NODE | NA_EDITED, ntree);
}
return sock;
}
-static bNodeSocket *rna_Node_outputs_new(ID *id, bNode *node, ReportList *reports, const char *type, const char *name, const char *identifier)
+static bNodeSocket *rna_Node_outputs_new(ID *id, bNode *node, Main *bmain, ReportList *reports, const char *type, const char *name, const char *identifier)
{
bNodeTree *ntree = (bNodeTree *)id;
bNodeSocket *sock;
@@ -1641,14 +1644,14 @@ static bNodeSocket *rna_Node_outputs_new(ID *id, bNode *node, ReportList *report
BKE_report(reports, RPT_ERROR, "Unable to create socket");
}
else {
- ntreeUpdateTree(G.main, ntree);
+ ntreeUpdateTree(bmain, ntree);
WM_main_add_notifier(NC_NODE | NA_EDITED, ntree);
}
return sock;
}
-static void rna_Node_socket_remove(ID *id, bNode *node, ReportList *reports, bNodeSocket *sock)
+static void rna_Node_socket_remove(ID *id, bNode *node, Main *bmain, ReportList *reports, bNodeSocket *sock)
{
bNodeTree *ntree = (bNodeTree *)id;
@@ -1658,12 +1661,12 @@ static void rna_Node_socket_remove(ID *id, bNode *node, ReportList *reports, bNo
else {
nodeRemoveSocket(ntree, node, sock);
- ntreeUpdateTree(G.main, ntree);
+ ntreeUpdateTree(bmain, ntree);
WM_main_add_notifier(NC_NODE | NA_EDITED, ntree);
}
}
-static void rna_Node_inputs_clear(ID *id, bNode *node)
+static void rna_Node_inputs_clear(ID *id, bNode *node, Main *bmain)
{
bNodeTree *ntree = (bNodeTree *)id;
bNodeSocket *sock, *nextsock;
@@ -1673,11 +1676,11 @@ static void rna_Node_inputs_clear(ID *id, bNode *node)
nodeRemoveSocket(ntree, node, sock);
}
- ntreeUpdateTree(G.main, ntree);
+ ntreeUpdateTree(bmain, ntree);
WM_main_add_notifier(NC_NODE | NA_EDITED, ntree);
}
-static void rna_Node_outputs_clear(ID *id, bNode *node)
+static void rna_Node_outputs_clear(ID *id, bNode *node, Main *bmain)
{
bNodeTree *ntree = (bNodeTree *)id;
bNodeSocket *sock, *nextsock;
@@ -1687,11 +1690,11 @@ static void rna_Node_outputs_clear(ID *id, bNode *node)
nodeRemoveSocket(ntree, node, sock);
}
- ntreeUpdateTree(G.main, ntree);
+ ntreeUpdateTree(bmain, ntree);
WM_main_add_notifier(NC_NODE | NA_EDITED, ntree);
}
-static void rna_Node_inputs_move(ID *id, bNode *node, int from_index, int to_index)
+static void rna_Node_inputs_move(ID *id, bNode *node, Main *bmain, int from_index, int to_index)
{
bNodeTree *ntree = (bNodeTree *)id;
bNodeSocket *sock;
@@ -1717,11 +1720,11 @@ static void rna_Node_inputs_move(ID *id, bNode *node, int from_index, int to_ind
}
}
- ntreeUpdateTree(G.main, ntree);
+ ntreeUpdateTree(bmain, ntree);
WM_main_add_notifier(NC_NODE | NA_EDITED, ntree);
}
-static void rna_Node_outputs_move(ID *id, bNode *node, int from_index, int to_index)
+static void rna_Node_outputs_move(ID *id, bNode *node, Main *bmain, int from_index, int to_index)
{
bNodeTree *ntree = (bNodeTree *)id;
bNodeSocket *sock;
@@ -1747,7 +1750,7 @@ static void rna_Node_outputs_move(ID *id, bNode *node, int from_index, int to_in
}
}
- ntreeUpdateTree(G.main, ntree);
+ ntreeUpdateTree(bmain, ntree);
WM_main_add_notifier(NC_NODE | NA_EDITED, ntree);
}
@@ -2220,7 +2223,7 @@ static void rna_NodeSocketInterface_update(Main *bmain, Scene *UNUSED(scene), Po
return;
ntree->update |= NTREE_UPDATE_GROUP;
- ntreeUpdateTree(G.main, ntree);
+ ntreeUpdateTree(bmain, ntree);
ED_node_tag_update_nodetree(bmain, ntree, NULL);
}
@@ -2949,6 +2952,30 @@ static bNodeSocket *rna_NodeOutputFile_slots_new(ID *id, bNode *node, bContext *
return sock;
}
+static void rna_ShaderNodeTexIES_mode_set(PointerRNA *ptr, int value)
+{
+ bNode *node = (bNode *)ptr->data;
+ NodeShaderTexIES *nss = node->storage;
+
+ if (nss->mode != value) {
+ nss->mode = value;
+ nss->filepath[0] = '\0';
+
+ /* replace text datablock by filepath */
+ if (node->id) {
+ Text *text = (Text *)node->id;
+
+ if (value == NODE_IES_EXTERNAL && text->name) {
+ BLI_strncpy(nss->filepath, text->name, sizeof(nss->filepath));
+ BLI_path_rel(nss->filepath, G.main->name);
+ }
+
+ id_us_min(node->id);
+ node->id = NULL;
+ }
+ }
+}
+
static void rna_ShaderNodeScript_mode_set(PointerRNA *ptr, int value)
{
bNode *node = (bNode *)ptr->data;
@@ -3291,6 +3318,12 @@ static const EnumPropertyItem node_script_mode_items[] = {
{0, NULL, 0, NULL, NULL}
};
+static EnumPropertyItem node_ies_mode_items[] = {
+ {NODE_IES_INTERNAL, "INTERNAL", 0, "Internal", "Use internal text datablock"},
+ {NODE_IES_EXTERNAL, "EXTERNAL", 0, "External", "Use external .ies file"},
+ {0, NULL, 0, NULL, NULL}
+};
+
static const EnumPropertyItem node_principled_distribution_items[] = {
{SHD_GLOSSY_GGX, "GGX", 0, "GGX", ""},
{SHD_GLOSSY_MULTI_GGX, "MULTI_GGX", 0, "Multiscatter GGX", ""},
@@ -4402,6 +4435,32 @@ static void def_sh_subsurface(StructRNA *srna)
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_ShaderNodeSubsurface_update");
}
+static void def_sh_tex_ies(StructRNA *srna)
+{
+ PropertyRNA *prop;
+
+ prop = RNA_def_property(srna, "ies", PROP_POINTER, PROP_NONE);
+ RNA_def_property_pointer_sdna(prop, NULL, "id");
+ RNA_def_property_struct_type(prop, "Text");
+ RNA_def_property_flag(prop, PROP_EDITABLE | PROP_ID_REFCOUNT);
+ RNA_def_property_ui_text(prop, "IES Text", "Internal IES file");
+ RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
+
+ RNA_def_struct_sdna_from(srna, "NodeShaderTexIES", "storage");
+
+ prop = RNA_def_property(srna, "filepath", PROP_STRING, PROP_FILEPATH);
+ RNA_def_property_ui_text(prop, "File Path", "IES light path");
+ RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
+
+ prop = RNA_def_property(srna, "mode", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_funcs(prop, NULL, "rna_ShaderNodeTexIES_mode_set", NULL);
+ RNA_def_property_enum_items(prop, node_ies_mode_items);
+ RNA_def_property_ui_text(prop, "Source", "Whether the IES file is loaded from disk or from a Text datablock");
+ RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
+
+ RNA_def_struct_sdna_from(srna, "bNode", NULL);
+}
+
static void def_sh_script(StructRNA *srna)
{
PropertyRNA *prop;
@@ -4897,17 +4956,17 @@ static void rna_def_cmp_output_file_slots_api(BlenderRNA *brna, PropertyRNA *cpr
func = RNA_def_function(srna, "remove", "rna_Node_socket_remove");
RNA_def_function_ui_description(func, "Remove a file slot from this node");
- RNA_def_function_flag(func, FUNC_USE_SELF_ID | FUNC_USE_REPORTS);
+ RNA_def_function_flag(func, FUNC_USE_SELF_ID | FUNC_USE_MAIN | FUNC_USE_REPORTS);
parm = RNA_def_pointer(func, "socket", "NodeSocket", "", "The socket to remove");
RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
func = RNA_def_function(srna, "clear", "rna_Node_inputs_clear");
RNA_def_function_ui_description(func, "Remove all file slots from this node");
- RNA_def_function_flag(func, FUNC_USE_SELF_ID);
+ RNA_def_function_flag(func, FUNC_USE_SELF_ID | FUNC_USE_MAIN);
func = RNA_def_function(srna, "move", "rna_Node_inputs_move");
RNA_def_function_ui_description(func, "Move a file slot to another position");
- RNA_def_function_flag(func, FUNC_USE_SELF_ID);
+ RNA_def_function_flag(func, FUNC_USE_SELF_ID | FUNC_USE_MAIN);
parm = RNA_def_int(func, "from_index", -1, 0, INT_MAX, "From Index", "Index of the socket to move", 0, 10000);
RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
parm = RNA_def_int(func, "to_index", -1, 0, INT_MAX, "To Index", "Target index for the socket", 0, 10000);
@@ -7640,7 +7699,7 @@ static void rna_def_node_sockets_api(BlenderRNA *brna, PropertyRNA *cprop, int i
func = RNA_def_function(srna, "new", newfunc);
RNA_def_function_ui_description(func, "Add a socket to this node");
- RNA_def_function_flag(func, FUNC_USE_SELF_ID | FUNC_USE_REPORTS);
+ RNA_def_function_flag(func, FUNC_USE_SELF_ID | FUNC_USE_MAIN | FUNC_USE_REPORTS);
parm = RNA_def_string(func, "type", NULL, MAX_NAME, "Type", "Data type");
RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
parm = RNA_def_string(func, "name", NULL, MAX_NAME, "Name", "");
@@ -7652,17 +7711,17 @@ static void rna_def_node_sockets_api(BlenderRNA *brna, PropertyRNA *cprop, int i
func = RNA_def_function(srna, "remove", "rna_Node_socket_remove");
RNA_def_function_ui_description(func, "Remove a socket from this node");
- RNA_def_function_flag(func, FUNC_USE_SELF_ID | FUNC_USE_REPORTS);
+ RNA_def_function_flag(func, FUNC_USE_SELF_ID | FUNC_USE_MAIN | FUNC_USE_REPORTS);
parm = RNA_def_pointer(func, "socket", "NodeSocket", "", "The socket to remove");
RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
func = RNA_def_function(srna, "clear", clearfunc);
RNA_def_function_ui_description(func, "Remove all sockets from this node");
- RNA_def_function_flag(func, FUNC_USE_SELF_ID);
+ RNA_def_function_flag(func, FUNC_USE_SELF_ID | FUNC_USE_MAIN);
func = RNA_def_function(srna, "move", movefunc);
RNA_def_function_ui_description(func, "Move a socket to another position");
- RNA_def_function_flag(func, FUNC_USE_SELF_ID);
+ RNA_def_function_flag(func, FUNC_USE_SELF_ID | FUNC_USE_MAIN);
parm = RNA_def_int(func, "from_index", -1, 0, INT_MAX, "From Index", "Index of the socket to move", 0, 10000);
RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
parm = RNA_def_int(func, "to_index", -1, 0, INT_MAX, "To Index", "Target index for the socket", 0, 10000);
@@ -8033,14 +8092,14 @@ static void rna_def_nodetree_nodes_api(BlenderRNA *brna, PropertyRNA *cprop)
func = RNA_def_function(srna, "remove", "rna_NodeTree_node_remove");
RNA_def_function_ui_description(func, "Remove a node from this node tree");
- RNA_def_function_flag(func, FUNC_USE_REPORTS);
+ RNA_def_function_flag(func, FUNC_USE_MAIN | FUNC_USE_REPORTS);
parm = RNA_def_pointer(func, "node", "Node", "", "The node to remove");
RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED | PARM_RNAPTR);
RNA_def_parameter_clear_flags(parm, PROP_THICK_WRAP, 0);
func = RNA_def_function(srna, "clear", "rna_NodeTree_node_clear");
RNA_def_function_ui_description(func, "Remove all nodes from this node tree");
- RNA_def_function_flag(func, FUNC_USE_REPORTS);
+ RNA_def_function_flag(func, FUNC_USE_MAIN | FUNC_USE_REPORTS);
prop = RNA_def_property(srna, "active", PROP_POINTER, PROP_NONE);
RNA_def_property_struct_type(prop, "Node");
@@ -8063,7 +8122,7 @@ static void rna_def_nodetree_link_api(BlenderRNA *brna, PropertyRNA *cprop)
func = RNA_def_function(srna, "new", "rna_NodeTree_link_new");
RNA_def_function_ui_description(func, "Add a node link to this node tree");
- RNA_def_function_flag(func, FUNC_USE_REPORTS);
+ RNA_def_function_flag(func, FUNC_USE_MAIN | FUNC_USE_REPORTS);
parm = RNA_def_pointer(func, "input", "NodeSocket", "", "The input socket");
RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED);
parm = RNA_def_pointer(func, "output", "NodeSocket", "", "The output socket");
@@ -8075,14 +8134,14 @@ static void rna_def_nodetree_link_api(BlenderRNA *brna, PropertyRNA *cprop)
func = RNA_def_function(srna, "remove", "rna_NodeTree_link_remove");
RNA_def_function_ui_description(func, "remove a node link from the node tree");
- RNA_def_function_flag(func, FUNC_USE_REPORTS);
+ RNA_def_function_flag(func, FUNC_USE_MAIN | FUNC_USE_REPORTS);
parm = RNA_def_pointer(func, "link", "NodeLink", "", "The node link to remove");
RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED | PARM_RNAPTR);
RNA_def_parameter_clear_flags(parm, PROP_THICK_WRAP, 0);
func = RNA_def_function(srna, "clear", "rna_NodeTree_link_clear");
RNA_def_function_ui_description(func, "remove all node links from the node tree");
- RNA_def_function_flag(func, FUNC_USE_REPORTS);
+ RNA_def_function_flag(func, FUNC_USE_MAIN | FUNC_USE_REPORTS);
}
static void rna_def_node_tree_sockets_api(BlenderRNA *brna, PropertyRNA *cprop, int in_out)
@@ -8103,7 +8162,7 @@ static void rna_def_node_tree_sockets_api(BlenderRNA *brna, PropertyRNA *cprop,
func = RNA_def_function(srna, "new", newfunc);
RNA_def_function_ui_description(func, "Add a socket to this node tree");
- RNA_def_function_flag(func, FUNC_USE_REPORTS);
+ RNA_def_function_flag(func, FUNC_USE_MAIN | FUNC_USE_REPORTS);
parm = RNA_def_string(func, "type", NULL, MAX_NAME, "Type", "Data type");
RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
parm = RNA_def_string(func, "name", NULL, MAX_NAME, "Name", "");
@@ -8114,16 +8173,17 @@ static void rna_def_node_tree_sockets_api(BlenderRNA *brna, PropertyRNA *cprop,
func = RNA_def_function(srna, "remove", "rna_NodeTree_socket_remove");
RNA_def_function_ui_description(func, "Remove a socket from this node tree");
- RNA_def_function_flag(func, FUNC_USE_REPORTS);
+ RNA_def_function_flag(func, FUNC_USE_MAIN | FUNC_USE_REPORTS);
parm = RNA_def_pointer(func, "socket", "NodeSocketInterface", "", "The socket to remove");
RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
func = RNA_def_function(srna, "clear", clearfunc);
RNA_def_function_ui_description(func, "Remove all sockets from this node tree");
- RNA_def_function_flag(func, FUNC_USE_REPORTS);
+ RNA_def_function_flag(func, FUNC_USE_MAIN | FUNC_USE_REPORTS);
func = RNA_def_function(srna, "move", movefunc);
RNA_def_function_ui_description(func, "Move a socket to another position");
+ RNA_def_function_flag(func, FUNC_USE_MAIN);
parm = RNA_def_int(func, "from_index", -1, 0, INT_MAX, "From Index", "Index of the socket to move", 0, 10000);
RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
parm = RNA_def_int(func, "to_index", -1, 0, INT_MAX, "To Index", "Target index for the socket", 0, 10000);
diff --git a/source/blender/makesrna/intern/rna_object_api.c b/source/blender/makesrna/intern/rna_object_api.c
index 04507d1ed7e..a01192dad68 100644
--- a/source/blender/makesrna/intern/rna_object_api.c
+++ b/source/blender/makesrna/intern/rna_object_api.c
@@ -89,6 +89,8 @@ static const EnumPropertyItem space_items[] = {
#include "DNA_scene_types.h"
#include "DNA_view3d_types.h"
+#include "DEG_depsgraph_query.h"
+
#include "MEM_guardedalloc.h"
static void rna_Object_select_set(Object *ob, bContext *C, ReportList *reports, int action)
@@ -173,13 +175,14 @@ static void rna_Object_mat_convert_space(Object *ob, ReportList *reports, bPoseC
}
static void rna_Object_calc_matrix_camera(
- Object *ob, float mat_ret[16], int width, int height, float scalex, float scaley)
+ Object *ob, Depsgraph *depsgraph, float mat_ret[16], int width, int height, float scalex, float scaley)
{
+ const Object *ob_eval = DEG_get_evaluated_object(depsgraph, ob);
CameraParams params;
/* setup parameters */
BKE_camera_params_init(&params);
- BKE_camera_params_from_object(&params, ob);
+ BKE_camera_params_from_object(&params, ob_eval);
/* compute matrix, viewplane, .. */
BKE_camera_params_compute_viewplane(&params, width, height, scalex, scaley);
@@ -189,9 +192,9 @@ static void rna_Object_calc_matrix_camera(
}
static void rna_Object_camera_fit_coords(
- Object *ob, Scene *scene, int num_cos, float *cos, float co_ret[3], float *scale_ret)
+ Object *ob, Depsgraph *depsgraph, int num_cos, float *cos, float co_ret[3], float *scale_ret)
{
- BKE_camera_view_frame_fit_to_coords(scene, (const float (*)[3])cos, num_cos / 3, ob, co_ret, scale_ret);
+ BKE_camera_view_frame_fit_to_coords(depsgraph, (const float (*)[3])cos, num_cos / 3, ob, co_ret, scale_ret);
}
/* copied from Mesh_getFromObject and adapted to RNA interface */
@@ -518,6 +521,9 @@ void RNA_api_object(StructRNA *srna)
func = RNA_def_function(srna, "calc_matrix_camera", "rna_Object_calc_matrix_camera");
RNA_def_function_ui_description(func, "Generate the camera projection matrix of this object "
"(mostly useful for Camera and Lamp types)");
+ parm = RNA_def_pointer(func, "depsgraph", "Depsgraph", "",
+ "Depsgraph to get evaluated data from");
+ RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
parm = RNA_def_property(func, "result", PROP_FLOAT, PROP_MATRIX);
RNA_def_property_multi_array(parm, 2, rna_matrix_dimsize_4x4);
RNA_def_property_ui_text(parm, "", "The camera projection matrix");
@@ -530,7 +536,8 @@ void RNA_api_object(StructRNA *srna)
func = RNA_def_function(srna, "camera_fit_coords", "rna_Object_camera_fit_coords");
RNA_def_function_ui_description(func, "Compute the coordinate (and scale for ortho cameras) "
"given object should be to 'see' all given coordinates");
- parm = RNA_def_pointer(func, "scene", "Scene", "", "Scene to get render size information from, if available");
+ parm = RNA_def_pointer(func, "depsgraph", "Depsgraph", "",
+ "Depsgraph to get evaluated data from");
RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
parm = RNA_def_float_array(func, "coordinates", 1, NULL, -FLT_MAX, FLT_MAX, "", "Coordinates to fit in",
-FLT_MAX, FLT_MAX);
diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c
index 27f9932ebde..4599ec0f9c5 100644
--- a/source/blender/makesrna/intern/rna_scene.c
+++ b/source/blender/makesrna/intern/rna_scene.c
@@ -175,11 +175,10 @@ const EnumPropertyItem rna_enum_snap_element_items[] = {
};
const EnumPropertyItem rna_enum_snap_node_element_items[] = {
- {SCE_SNAP_MODE_GRID , "GRID" , ICON_SNAP_GRID, "Grid", "Snap to grid"},
- {SCE_SNAP_MODE_NODE_X, "NODE_X" , ICON_SNAP_EDGE, "Node X", "Snap to left/right node border"},
- {SCE_SNAP_MODE_NODE_Y, "NODE_Y" , ICON_SNAP_EDGE, "Node Y", "Snap to top/bottom node border"},
- {SCE_SNAP_MODE_NODE_X | SCE_SNAP_MODE_NODE_Y,
- "NODE_XY", ICON_SNAP_EDGE, "Node X / Y", "Snap to any node border"},
+ {SCE_SNAP_MODE_GRID, "GRID", ICON_SNAP_GRID, "Grid", "Snap to grid"},
+ {SCE_SNAP_MODE_NODE_X, "NODE_X", ICON_SNAP_EDGE, "Node X", "Snap to left/right node border"},
+ {SCE_SNAP_MODE_NODE_Y, "NODE_Y", ICON_SNAP_EDGE, "Node Y", "Snap to top/bottom node border"},
+ {SCE_SNAP_MODE_NODE_X | SCE_SNAP_MODE_NODE_Y, "NODE_XY", ICON_SNAP_EDGE, "Node X / Y", "Snap to any node border"},
{0, NULL, 0, NULL, NULL}
};
@@ -1486,7 +1485,7 @@ void rna_ViewLayer_name_set(PointerRNA *ptr, const char *value)
{
Scene *scene = (Scene *)ptr->id.data;
ViewLayer *view_layer = (ViewLayer *)ptr->data;
- BKE_view_layer_rename(scene, view_layer, value);
+ BKE_view_layer_rename(G.main, scene, view_layer, value);
}
static void rna_SceneRenderView_name_set(PointerRNA *ptr, const char *value)
@@ -5866,7 +5865,7 @@ static void rna_def_scene_eevee(BlenderRNA *brna)
RNA_def_property_range(prop, 1, INT_MAX);
RNA_def_property_flag(prop, PROP_OVERRIDABLE_STATIC);
- prop = RNA_def_property(srna, "taa_reprojection", PROP_BOOLEAN, PROP_NONE);
+ prop = RNA_def_property(srna, "use_taa_reprojection", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", SCE_EEVEE_TAA_REPROJECTION);
RNA_def_property_boolean_default(prop, 1);
RNA_def_property_ui_text(prop, "Viewport Denoising", "Denoise image using temporal reprojection "
@@ -5874,7 +5873,7 @@ static void rna_def_scene_eevee(BlenderRNA *brna)
RNA_def_property_flag(prop, PROP_OVERRIDABLE_STATIC);
/* Screen Space Subsurface Scattering */
- prop = RNA_def_property(srna, "sss_enable", PROP_BOOLEAN, PROP_NONE);
+ prop = RNA_def_property(srna, "use_sss", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", SCE_EEVEE_SSS_ENABLED);
RNA_def_property_boolean_default(prop, 0);
RNA_def_property_ui_text(prop, "Subsurface Scattering", "Enable screen space subsurface scattering");
@@ -5892,7 +5891,7 @@ static void rna_def_scene_eevee(BlenderRNA *brna)
RNA_def_property_range(prop, 0.0f, 1.0f);
RNA_def_property_flag(prop, PROP_OVERRIDABLE_STATIC);
- prop = RNA_def_property(srna, "sss_separate_albedo", PROP_BOOLEAN, PROP_NONE);
+ prop = RNA_def_property(srna, "use_sss_separate_albedo", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", SCE_EEVEE_SSS_SEPARATE_ALBEDO);
RNA_def_property_boolean_default(prop, 0);
RNA_def_property_ui_text(prop, "Separate Albedo", "Avoid albedo being blured by the subsurface scattering "
@@ -5900,19 +5899,19 @@ static void rna_def_scene_eevee(BlenderRNA *brna)
RNA_def_property_flag(prop, PROP_OVERRIDABLE_STATIC);
/* Screen Space Reflection */
- prop = RNA_def_property(srna, "ssr_enable", PROP_BOOLEAN, PROP_NONE);
+ prop = RNA_def_property(srna, "use_ssr", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", SCE_EEVEE_SSR_ENABLED);
RNA_def_property_boolean_default(prop, 0);
RNA_def_property_ui_text(prop, "Screen Space Reflections", "Enable screen space reflection");
RNA_def_property_flag(prop, PROP_OVERRIDABLE_STATIC);
- prop = RNA_def_property(srna, "ssr_refraction", PROP_BOOLEAN, PROP_NONE);
+ prop = RNA_def_property(srna, "use_ssr_refraction", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", SCE_EEVEE_SSR_REFRACTION);
RNA_def_property_boolean_default(prop, 0);
RNA_def_property_ui_text(prop, "Screen Space Refractions", "Enable screen space Refractions");
RNA_def_property_flag(prop, PROP_OVERRIDABLE_STATIC);
- prop = RNA_def_property(srna, "ssr_halfres", PROP_BOOLEAN, PROP_NONE);
+ prop = RNA_def_property(srna, "use_ssr_halfres", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", SCE_EEVEE_SSR_HALF_RESOLUTION);
RNA_def_property_boolean_default(prop, 1);
RNA_def_property_ui_text(prop, "Half Res Trace", "Raytrace at a lower resolution");
@@ -5950,7 +5949,7 @@ static void rna_def_scene_eevee(BlenderRNA *brna)
RNA_def_property_flag(prop, PROP_OVERRIDABLE_STATIC);
/* Volumetrics */
- prop = RNA_def_property(srna, "volumetric_enable", PROP_BOOLEAN, PROP_NONE);
+ prop = RNA_def_property(srna, "use_volumetric", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", SCE_EEVEE_VOLUMETRIC_ENABLED);
RNA_def_property_boolean_default(prop, 0);
RNA_def_property_ui_text(prop, "Volumetrics", "Enable scattering and absorbance of volumetric material");
@@ -5988,7 +5987,7 @@ static void rna_def_scene_eevee(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Exponential Sampling", "Distribute more samples closer to the camera");
RNA_def_property_flag(prop, PROP_OVERRIDABLE_STATIC);
- prop = RNA_def_property(srna, "volumetric_lights", PROP_BOOLEAN, PROP_NONE);
+ prop = RNA_def_property(srna, "use_volumetric_lights", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", SCE_EEVEE_VOLUMETRIC_LIGHTS);
RNA_def_property_boolean_default(prop, 1);
RNA_def_property_ui_text(prop, "Volumetric Lighting", "Enable scene lamps interactions with volumetrics");
@@ -6000,7 +5999,7 @@ static void rna_def_scene_eevee(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Clamp", "Maximum light contribution, reducing noise");
RNA_def_property_flag(prop, PROP_OVERRIDABLE_STATIC);
- prop = RNA_def_property(srna, "volumetric_shadows", PROP_BOOLEAN, PROP_NONE);
+ prop = RNA_def_property(srna, "use_volumetric_shadows", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", SCE_EEVEE_VOLUMETRIC_SHADOWS);
RNA_def_property_boolean_default(prop, 0);
RNA_def_property_ui_text(prop, "Volumetric Shadows", "Generate shadows from volumetric material (Very expensive)");
@@ -6012,26 +6011,26 @@ static void rna_def_scene_eevee(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Volumetric Shadow Samples", "Number of samples to compute volumetric shadowing");
RNA_def_property_flag(prop, PROP_OVERRIDABLE_STATIC);
- prop = RNA_def_property(srna, "volumetric_colored_transmittance", PROP_BOOLEAN, PROP_NONE);
+ prop = RNA_def_property(srna, "use_volumetric_colored_transmittance", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", SCE_EEVEE_VOLUMETRIC_COLORED);
RNA_def_property_boolean_default(prop, 1);
RNA_def_property_ui_text(prop, "Colored Transmittance", "Enable wavelength dependent volumetric transmittance");
RNA_def_property_flag(prop, PROP_OVERRIDABLE_STATIC);
/* Ambient Occlusion */
- prop = RNA_def_property(srna, "gtao_enable", PROP_BOOLEAN, PROP_NONE);
+ prop = RNA_def_property(srna, "use_gtao", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", SCE_EEVEE_GTAO_ENABLED);
RNA_def_property_boolean_default(prop, 0);
RNA_def_property_ui_text(prop, "Ambient Occlusion", "Enable ambient occlusion to simulate medium scale indirect shadowing");
RNA_def_property_flag(prop, PROP_OVERRIDABLE_STATIC);
- prop = RNA_def_property(srna, "gtao_use_bent_normals", PROP_BOOLEAN, PROP_NONE);
+ prop = RNA_def_property(srna, "use_gtao_bent_normals", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", SCE_EEVEE_GTAO_BENT_NORMALS);
RNA_def_property_boolean_default(prop, 1);
RNA_def_property_ui_text(prop, "Bent Normals", "Compute main non occluded direction to sample the environment");
RNA_def_property_flag(prop, PROP_OVERRIDABLE_STATIC);
- prop = RNA_def_property(srna, "gtao_bounce", PROP_BOOLEAN, PROP_NONE);
+ prop = RNA_def_property(srna, "use_gtao_bounce", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", SCE_EEVEE_GTAO_BOUNCE);
RNA_def_property_boolean_default(prop, 1);
RNA_def_property_ui_text(prop, "Bounces Approximation", "An approximation to simulate light bounces "
@@ -6059,7 +6058,7 @@ static void rna_def_scene_eevee(BlenderRNA *brna)
RNA_def_property_flag(prop, PROP_OVERRIDABLE_STATIC);
/* Depth of Field */
- prop = RNA_def_property(srna, "dof_enable", PROP_BOOLEAN, PROP_NONE);
+ prop = RNA_def_property(srna, "use_dof", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", SCE_EEVEE_DOF_ENABLED);
RNA_def_property_boolean_default(prop, 0);
RNA_def_property_ui_text(prop, "Depth of Field", "Enable depth of field using the values from the active camera");
@@ -6080,7 +6079,7 @@ static void rna_def_scene_eevee(BlenderRNA *brna)
RNA_def_property_flag(prop, PROP_OVERRIDABLE_STATIC);
/* Bloom */
- prop = RNA_def_property(srna, "bloom_enable", PROP_BOOLEAN, PROP_NONE);
+ prop = RNA_def_property(srna, "use_bloom", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", SCE_EEVEE_BLOOM_ENABLED);
RNA_def_property_boolean_default(prop, 0);
RNA_def_property_ui_text(prop, "Bloom", "High brighness pixels generate a glowing effect");
@@ -6127,7 +6126,7 @@ static void rna_def_scene_eevee(BlenderRNA *brna)
RNA_def_property_flag(prop, PROP_OVERRIDABLE_STATIC);
/* Motion blur */
- prop = RNA_def_property(srna, "motion_blur_enable", PROP_BOOLEAN, PROP_NONE);
+ prop = RNA_def_property(srna, "use_motion_blur", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", SCE_EEVEE_MOTION_BLUR_ENABLED);
RNA_def_property_boolean_default(prop, 0);
RNA_def_property_ui_text(prop, "Motion Blur", "Enable motion blur effect (only in camera view)");
@@ -6164,7 +6163,7 @@ static void rna_def_scene_eevee(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Directional Shadows Resolution", "Size of sun lamps shadow maps");
RNA_def_property_flag(prop, PROP_OVERRIDABLE_STATIC);
- prop = RNA_def_property(srna, "shadow_high_bitdepth", PROP_BOOLEAN, PROP_NONE);
+ prop = RNA_def_property(srna, "use_shadow_high_bitdepth", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", SCE_EEVEE_SHADOW_HIGH_BITDEPTH);
RNA_def_property_boolean_default(prop, 0);
RNA_def_property_ui_text(prop, "High Bitdepth", "Use 32bit shadows");
diff --git a/source/blender/makesrna/intern/rna_scene_api.c b/source/blender/makesrna/intern/rna_scene_api.c
index a3e403154f9..a307aff6e96 100644
--- a/source/blender/makesrna/intern/rna_scene_api.c
+++ b/source/blender/makesrna/intern/rna_scene_api.c
@@ -144,7 +144,8 @@ static void rna_Scene_update_tagged(Scene *scene, Main *bmain)
#endif
}
-static void rna_SceneRender_get_frame_path(RenderData *rd, int frame, int preview, const char *view, char *name)
+static void rna_SceneRender_get_frame_path(
+ RenderData *rd, Main *bmain, int frame, int preview, const char *view, char *name)
{
const char *suffix = BKE_scene_multiview_view_suffix_get(rd, view);
@@ -157,7 +158,7 @@ static void rna_SceneRender_get_frame_path(RenderData *rd, int frame, int previe
}
else {
BKE_image_path_from_imformat(
- name, rd->pic, G.main->name, (frame == INT_MIN) ? rd->cfra : frame,
+ name, rd->pic, bmain->name, (frame == INT_MIN) ? rd->cfra : frame,
&rd->im_format, (rd->scemode & R_EXTENSION) != 0, true, suffix);
}
}
@@ -172,7 +173,7 @@ static void rna_Scene_ray_cast(
Depsgraph *depsgraph = BKE_scene_get_depsgraph(scene, view_layer, true);
SnapObjectContext *sctx = ED_transform_snap_object_context_create(
- G.main, scene, depsgraph, 0);
+ scene, depsgraph, 0);
bool ret = ED_transform_snap_object_project_ray_ex(
sctx,
@@ -390,6 +391,7 @@ void RNA_api_scene_render(StructRNA *srna)
PropertyRNA *parm;
func = RNA_def_function(srna, "frame_path", "rna_SceneRender_get_frame_path");
+ RNA_def_function_flag(func, FUNC_USE_MAIN);
RNA_def_function_ui_description(func, "Return the absolute path to the filename to be written for a given frame");
RNA_def_int(func, "frame", INT_MIN, INT_MIN, INT_MAX, "",
"Frame number to use, if unset the current frame will be used", MINAFRAME, MAXFRAME);
diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c
index e555c2ae52a..65edc619ced 100644
--- a/source/blender/makesrna/intern/rna_space.c
+++ b/source/blender/makesrna/intern/rna_space.c
@@ -655,12 +655,7 @@ static int rna_3DViewShading_type_get(PointerRNA *ptr)
RenderEngineType *type = RE_engines_find(scene->r.engine);
View3D *v3d = (View3D *)ptr->data;
- if (BKE_scene_uses_blender_eevee(scene)) {
- if (v3d->drawtype == OB_MATERIAL) {
- return OB_RENDER;
- }
- }
- else if (v3d->drawtype == OB_RENDER) {
+ if (!BKE_scene_uses_blender_eevee(scene) && v3d->drawtype == OB_RENDER) {
if (!(type && type->render_to_view)) {
return OB_MATERIAL;
}
@@ -693,6 +688,7 @@ static const EnumPropertyItem *rna_3DViewShading_type_itemf(
RNA_enum_items_add_value(&item, &totitem, rna_enum_shading_type_items, OB_TEXTURE);
if (BKE_scene_uses_blender_eevee(scene)) {
+ RNA_enum_items_add_value(&item, &totitem, rna_enum_shading_type_items, OB_MATERIAL);
RNA_enum_items_add_value(&item, &totitem, rna_enum_shading_type_items, OB_RENDER);
}
else {
@@ -711,7 +707,7 @@ static const EnumPropertyItem *rna_3DViewShading_type_itemf(
static int rna_View3DShading_studio_light_orientation_get(PointerRNA *ptr)
{
View3D *v3d = (View3D *)ptr->data;
- StudioLight *sl = BKE_studiolight_find(v3d->shading.studio_light);
+ StudioLight *sl = BKE_studiolight_find(v3d->shading.studio_light, 0);
return sl->flag & (STUDIOLIGHT_ORIENTATION_WORLD | STUDIOLIGHT_ORIENTATION_CAMERA);
}
static void rna_View3DShading_studio_light_orientation_set(PointerRNA *UNUSED(ptr), int UNUSED(value))
@@ -721,7 +717,9 @@ static void rna_View3DShading_studio_light_orientation_set(PointerRNA *UNUSED(pt
static int rna_View3DShading_studio_light_get(PointerRNA *ptr)
{
View3D *v3d = (View3D *)ptr->data;
- StudioLight *sl = BKE_studiolight_find(v3d->shading.studio_light);
+ const int flag = v3d->drawtype == OB_MATERIAL? STUDIOLIGHT_ORIENTATION_WORLD: 0;
+ StudioLight *sl = BKE_studiolight_find(v3d->shading.studio_light, flag);
+ BLI_strncpy(v3d->shading.studio_light, sl->name, FILE_MAXFILE);
return sl->index;
}
@@ -733,19 +731,40 @@ static void rna_View3DShading_studio_light_set(PointerRNA *ptr, int value)
}
static const EnumPropertyItem *rna_View3DShading_studio_light_itemf(
- bContext *UNUSED(C), PointerRNA *UNUSED(ptr),
+ bContext *UNUSED(C), PointerRNA *ptr,
PropertyRNA *UNUSED(prop), bool *r_free)
{
+ View3D *v3d = (View3D *)ptr->data;
EnumPropertyItem *item = NULL;
EnumPropertyItem *lastitem;
int totitem = 0;
+ bool show_studiolight;
LISTBASE_FOREACH(StudioLight *, sl, BKE_studiolight_listbase()) {
- if (totitem < NUM_STUDIOLIGHT_ITEMS) {
- RNA_enum_items_add_value(&item, &totitem, rna_enum_studio_light_items, totitem);
+ show_studiolight = false;
+ int icon_id = sl->irradiance_icon_id;
+
+ if ((sl->flag & STUDIOLIGHT_EXTERNAL_FILE) == 0) {
+ /* always show internal lights */
+ show_studiolight = true;
+ } else {
+ switch (v3d->drawtype) {
+ case OB_SOLID:
+ case OB_TEXTURE:
+ show_studiolight = true;
+ break;
+ case OB_MATERIAL:
+ show_studiolight = (sl->flag & STUDIOLIGHT_ORIENTATION_WORLD) > 0;
+ icon_id = sl->radiance_icon_id;
+ break;
+ }
+ }
+
+ if (show_studiolight && totitem < NUM_STUDIOLIGHT_ITEMS) {
+ RNA_enum_items_add_value(&item, &totitem, rna_enum_studio_light_items, sl->index);
lastitem = &item[totitem - 1];
lastitem->value = sl->index;
- lastitem->icon = sl->icon_id;
+ lastitem->icon = icon_id;
lastitem->name = sl->name;
}
}
@@ -2038,10 +2057,10 @@ static void rna_def_space_image_uv(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Draw Texture Paint UVs", "Draw overlay of texture paint uv layer");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_IMAGE, NULL);
- prop = RNA_def_property(srna, "show_normalized_coords", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_sdna(prop, NULL, "flag", SI_COORDFLOATS);
- RNA_def_property_ui_text(prop, "Normalized Coordinates",
- "Display UV coordinates from 0.0 to 1.0 rather than in pixels");
+ prop = RNA_def_property(srna, "show_pixel_coords", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", SI_COORDFLOATS);
+ RNA_def_property_ui_text(prop, "Pixel Coordinates",
+ "Display UV coordinates in pixels rather than from 0.0 to 1.0");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_IMAGE, NULL);
prop = RNA_def_property(srna, "show_faces", PROP_BOOLEAN, PROP_NONE);
@@ -2305,10 +2324,10 @@ static void rna_def_space_view3d_shading(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Shadow", "Show Shadow");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL);
- prop = RNA_def_property(srna, "show_see_through", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_sdna(prop, NULL, "shading.flag", V3D_SHADING_SEE_THROUGH);
+ prop = RNA_def_property(srna, "show_xray", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "shading.flag", V3D_SHADING_XRAY);
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
- RNA_def_property_ui_text(prop, "See Through", "Show whole scene transparent");
+ RNA_def_property_ui_text(prop, "X-Ray", "Show whole scene transparent");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL);
prop = RNA_def_property(srna, "object_outline_color", PROP_FLOAT, PROP_COLOR);
@@ -2475,7 +2494,7 @@ static void rna_def_space_view3d_overlay(BlenderRNA *brna)
RNA_def_property_range(prop, 0.0f, 1.0f);
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL);
- prop = RNA_def_property(srna, "transparent_bones", PROP_BOOLEAN, PROP_NONE);
+ prop = RNA_def_property(srna, "show_transparent_bones", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "overlay.arm_flag", V3D_OVERLAY_ARM_TRANSP_BONES);
RNA_def_property_ui_text(prop, "Transparent Bones", "Display bones as transparent");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL);
diff --git a/source/blender/makesrna/intern/rna_ui.c b/source/blender/makesrna/intern/rna_ui.c
index 9e868cf17e9..173eaf56f0c 100644
--- a/source/blender/makesrna/intern/rna_ui.c
+++ b/source/blender/makesrna/intern/rna_ui.c
@@ -914,6 +914,16 @@ static void rna_UILayout_emboss_set(PointerRNA *ptr, int value)
uiLayoutSetEmboss(ptr->data, value);
}
+static int rna_UILayout_property_split_get(PointerRNA *ptr)
+{
+ return uiLayoutGetPropSep(ptr->data);
+}
+
+static void rna_UILayout_property_split_set(PointerRNA *ptr, int value)
+{
+ uiLayoutSetPropSep(ptr->data, value);
+}
+
#else /* RNA_RUNTIME */
static void rna_def_ui_layout(BlenderRNA *brna)
@@ -978,6 +988,9 @@ static void rna_def_ui_layout(BlenderRNA *brna)
prop = RNA_def_property(srna, "emboss", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_items(prop, emboss_items);
RNA_def_property_enum_funcs(prop, "rna_UILayout_emboss_get", "rna_UILayout_emboss_set", NULL);
+
+ prop = RNA_def_property(srna, "use_property_split", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_funcs(prop, "rna_UILayout_property_split_get", "rna_UILayout_property_split_set");
}
static void rna_def_panel(BlenderRNA *brna)
diff --git a/source/blender/makesrna/intern/rna_userdef.c b/source/blender/makesrna/intern/rna_userdef.c
index 741a1a87eb1..fef4cc3ed8e 100644
--- a/source/blender/makesrna/intern/rna_userdef.c
+++ b/source/blender/makesrna/intern/rna_userdef.c
@@ -2962,6 +2962,20 @@ static void rna_def_userdef_theme_space_topbar(BlenderRNA *brna)
rna_def_userdef_theme_spaces_main(srna);
}
+static void rna_def_userdef_theme_space_statusbar(BlenderRNA *brna)
+{
+ StructRNA *srna;
+
+ /* space_statusbar */
+
+ srna = RNA_def_struct(brna, "ThemeStatusBar", NULL);
+ RNA_def_struct_sdna(srna, "ThemeSpace");
+ RNA_def_struct_clear_flag(srna, STRUCT_UNDO);
+ RNA_def_struct_ui_text(srna, "Theme Status Bar", "Theme settings for the Status Bar");
+
+ rna_def_userdef_theme_spaces_main(srna);
+}
+
static void rna_def_userdef_themes(BlenderRNA *brna)
{
StructRNA *srna;
@@ -2987,6 +3001,7 @@ static void rna_def_userdef_themes(BlenderRNA *brna)
{17, "CONSOLE", ICON_CONSOLE, "Python Console", ""},
{20, "CLIP_EDITOR", ICON_CLIP, "Movie Clip Editor", ""},
{21, "TOPBAR", ICON_NONE, "Top Bar", ""},
+ {22, "STATUSBAR", ICON_NONE, "Status Bar", ""},
{0, NULL, 0, NULL, NULL}
};
@@ -3114,6 +3129,12 @@ static void rna_def_userdef_themes(BlenderRNA *brna)
RNA_def_property_pointer_sdna(prop, NULL, "ttopbar");
RNA_def_property_struct_type(prop, "ThemeTopBar");
RNA_def_property_ui_text(prop, "Top Bar", "");
+
+ prop = RNA_def_property(srna, "statusbar", PROP_POINTER, PROP_NONE);
+ RNA_def_property_flag(prop, PROP_NEVER_NULL);
+ RNA_def_property_pointer_sdna(prop, NULL, "tstatusbar");
+ RNA_def_property_struct_type(prop, "ThemeStatusBar");
+ RNA_def_property_ui_text(prop, "Status Bar", "");
}
static void rna_def_userdef_addon(BlenderRNA *brna)
@@ -3204,6 +3225,7 @@ static void rna_def_userdef_dothemes(BlenderRNA *brna)
rna_def_userdef_theme_space_console(brna);
rna_def_userdef_theme_space_clip(brna);
rna_def_userdef_theme_space_topbar(brna);
+ rna_def_userdef_theme_space_statusbar(brna);
rna_def_userdef_theme_colorset(brna);
rna_def_userdef_themes(brna);
}
diff --git a/source/blender/modifiers/intern/MOD_array.c b/source/blender/modifiers/intern/MOD_array.c
index 4a67b8318bb..e74d9087427 100644
--- a/source/blender/modifiers/intern/MOD_array.c
+++ b/source/blender/modifiers/intern/MOD_array.c
@@ -390,7 +390,7 @@ static Mesh *arrayModifier_doArray(
vgroup_start_cap_remap = BKE_object_defgroup_index_map_create(
amd->start_cap, ctx->object, &vgroup_start_cap_remap_len);
- start_cap_mesh = BKE_modifier_get_evaluated_mesh_from_object(amd->start_cap, ctx->flag);
+ start_cap_mesh = BKE_modifier_get_evaluated_mesh_from_object(ctx, amd->start_cap);
if (start_cap_mesh) {
start_cap_nverts = start_cap_mesh->totvert;
start_cap_nedges = start_cap_mesh->totedge;
@@ -402,7 +402,7 @@ static Mesh *arrayModifier_doArray(
vgroup_end_cap_remap = BKE_object_defgroup_index_map_create(
amd->end_cap, ctx->object, &vgroup_end_cap_remap_len);
- end_cap_mesh = BKE_modifier_get_evaluated_mesh_from_object(amd->end_cap, ctx->flag);
+ end_cap_mesh = BKE_modifier_get_evaluated_mesh_from_object(ctx, amd->end_cap);
if (end_cap_mesh) {
end_cap_nverts = end_cap_mesh->totvert;
end_cap_nedges = end_cap_mesh->totedge;
diff --git a/source/blender/modifiers/intern/MOD_boolean.c b/source/blender/modifiers/intern/MOD_boolean.c
index ebe5aacd888..73d1388d88f 100644
--- a/source/blender/modifiers/intern/MOD_boolean.c
+++ b/source/blender/modifiers/intern/MOD_boolean.c
@@ -56,6 +56,8 @@
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
+#include "DEG_depsgraph_query.h"
+
#include "MEM_guardedalloc.h"
#include "bmesh.h"
@@ -173,18 +175,19 @@ static Mesh *applyModifier(ModifierData *md, const ModifierEvalContext *ctx, Mes
if (!bmd->object)
return mesh;
- mesh_other = BKE_modifier_get_evaluated_mesh_from_object(bmd->object, ctx->flag);
-
+ mesh_other = BKE_modifier_get_evaluated_mesh_from_object(ctx, bmd->object);
if (mesh_other) {
Mesh *result;
+ Object *object_eval = DEG_get_evaluated_object(ctx->depsgraph, ctx->object);
+ Object *other_eval = DEG_get_evaluated_object(ctx->depsgraph, bmd->object);
/* when one of objects is empty (has got no faces) we could speed up
* calculation a bit returning one of objects' derived meshes (or empty one)
* Returning mesh is depended on modifiers operation (sergey) */
- result = get_quick_mesh(ctx->object, mesh, bmd->object, mesh_other, bmd->operation);
+ result = get_quick_mesh(object_eval, mesh, other_eval, mesh_other, bmd->operation);
if (result == NULL) {
- const bool is_flip = (is_negative_m4(ctx->object->obmat) != is_negative_m4(bmd->object->obmat));
+ const bool is_flip = (is_negative_m4(object_eval->obmat) != is_negative_m4(other_eval->obmat));
BMesh *bm;
const BMAllocTemplate allocsize = BMALLOC_TEMPLATE_FROM_ME(mesh, mesh_other);
@@ -231,8 +234,8 @@ static Mesh *applyModifier(ModifierData *md, const ModifierEvalContext *ctx, Mes
float imat[4][4];
float omat[4][4];
- invert_m4_m4(imat, ctx->object->obmat);
- mul_m4_m4m4(omat, imat, bmd->object->obmat);
+ invert_m4_m4(imat, object_eval->obmat);
+ mul_m4_m4m4(omat, imat, other_eval->obmat);
BMVert *eve;
i = 0;
@@ -254,10 +257,11 @@ static Mesh *applyModifier(ModifierData *md, const ModifierEvalContext *ctx, Mes
negate_m3(nmat);
}
- const short ob_src_totcol = bmd->object->totcol;
+ const short ob_src_totcol = other_eval->totcol;
short *material_remap = BLI_array_alloca(material_remap, ob_src_totcol ? ob_src_totcol : 1);
- BKE_material_remap_object_calc(ctx->object, bmd->object, material_remap);
+ /* Using original (not evaluated) object here since we are writing to it. */
+ BKE_material_remap_object_calc(ctx->object, other_eval, material_remap);
BMFace *efa;
i = 0;
diff --git a/source/blender/modifiers/intern/MOD_meshdeform.c b/source/blender/modifiers/intern/MOD_meshdeform.c
index 94adb3d9ebc..48653856178 100644
--- a/source/blender/modifiers/intern/MOD_meshdeform.c
+++ b/source/blender/modifiers/intern/MOD_meshdeform.c
@@ -275,7 +275,7 @@ static void meshdeform_vert_task(
}
static void meshdeformModifier_do(
- ModifierData *md, Object *ob, Mesh *mesh,
+ ModifierData *md, Depsgraph *depsgraph, Object *ob, Mesh *mesh,
float (*vertexCos)[3], int numVerts)
{
MeshDeformModifierData *mmd = (MeshDeformModifierData *) md;
@@ -307,7 +307,11 @@ static void meshdeformModifier_do(
free_cagemesh = true;
}
else {
- cagemesh = BKE_modifier_get_evaluated_mesh_from_object(ob, md->mode & eModifierMode_Render ? MOD_APPLY_RENDER : 0);
+ ModifierEvalContext ctx = {
+ .depsgraph = depsgraph,
+ .flag = md->mode & eModifierMode_Render ? MOD_APPLY_RENDER : 0,
+ };
+ cagemesh = BKE_modifier_get_evaluated_mesh_from_object(&ctx, ob);
}
/* if we don't have one computed, use derivedmesh from data
@@ -421,7 +425,7 @@ static void deformVerts(
modifier_vgroup_cache(md, vertexCos); /* if next modifier needs original vertices */
- meshdeformModifier_do(md, ctx->object, mesh_src, vertexCos, numVerts);
+ meshdeformModifier_do(md, ctx->depsgraph, ctx->object, mesh_src, vertexCos, numVerts);
if (mesh_src && mesh_src != mesh) {
BKE_id_free(NULL, mesh_src);
@@ -437,7 +441,7 @@ static void deformVertsEM(
{
Mesh *mesh_src = get_mesh(ctx->object, NULL, mesh, NULL, false, false);
- meshdeformModifier_do(md, ctx->object, mesh_src, vertexCos, numVerts);
+ meshdeformModifier_do(md, ctx->depsgraph, ctx->object, mesh_src, vertexCos, numVerts);
if (mesh_src && mesh_src != mesh) {
BKE_id_free(NULL, mesh_src);
diff --git a/source/blender/modifiers/intern/MOD_particlesystem.c b/source/blender/modifiers/intern/MOD_particlesystem.c
index c2493e6d8f3..72bdcc779ea 100644
--- a/source/blender/modifiers/intern/MOD_particlesystem.c
+++ b/source/blender/modifiers/intern/MOD_particlesystem.c
@@ -42,6 +42,7 @@
#include "BKE_cdderivedmesh.h"
+#include "BKE_editmesh.h"
#include "BKE_mesh.h"
#include "BKE_library.h"
#include "BKE_modifier.h"
@@ -55,7 +56,7 @@ static void initData(ModifierData *md)
ParticleSystemModifierData *psmd = (ParticleSystemModifierData *) md;
psmd->psys = NULL;
psmd->mesh_final = NULL;
- psmd->mesh_deformed = NULL;
+ psmd->mesh_original = NULL;
psmd->totdmvert = psmd->totdmedge = psmd->totdmface = 0;
}
static void freeData(ModifierData *md)
@@ -65,9 +66,9 @@ static void freeData(ModifierData *md)
if (psmd->mesh_final) {
BKE_id_free(NULL, psmd->mesh_final);
psmd->mesh_final = NULL;
- if (psmd->mesh_deformed) {
- BKE_id_free(NULL, psmd->mesh_deformed);
- psmd->mesh_deformed = NULL;
+ if (psmd->mesh_original) {
+ BKE_id_free(NULL, psmd->mesh_original);
+ psmd->mesh_original = NULL;
}
}
psmd->totdmvert = psmd->totdmedge = psmd->totdmface = 0;
@@ -88,7 +89,7 @@ static void copyData(const ModifierData *md, ModifierData *target)
modifier_copyData_generic(md, target);
tpsmd->mesh_final = NULL;
- tpsmd->mesh_deformed = NULL;
+ tpsmd->mesh_original = NULL;
tpsmd->totdmvert = tpsmd->totdmedge = tpsmd->totdmface = 0;
}
@@ -129,9 +130,9 @@ static void deformVerts(
if (psmd->mesh_final) {
BKE_id_free(NULL, psmd->mesh_final);
psmd->mesh_final = NULL;
- if (psmd->mesh_deformed) {
- BKE_id_free(NULL, psmd->mesh_deformed);
- psmd->mesh_deformed = NULL;
+ if (psmd->mesh_original) {
+ BKE_id_free(NULL, psmd->mesh_original);
+ psmd->mesh_original = NULL;
}
}
else if (psmd->flag & eParticleSystemFlag_file_loaded) {
@@ -156,20 +157,40 @@ static void deformVerts(
BKE_mesh_tessface_ensure(psmd->mesh_final);
if (!psmd->mesh_final->runtime.deformed_only) {
- /* XXX Think we can assume here that if current DM is not only-deformed, ob->deformedOnly has been set.
- * This is awfully weak though. :| */
- if (ctx->object->derivedDeform) {
- DM_to_mesh(ctx->object->derivedDeform, psmd->mesh_deformed, ctx->object, CD_MASK_EVERYTHING, false);
+ /* Get the original mesh from the object, this is what the particles
+ * are attached to so in case of non-deform modifiers we need to remap
+ * them to the final mesh (typically subdivision surfaces). */
+ Mesh *mesh_original = NULL;
+
+ if (ctx->object->type == OB_MESH) {
+ BMEditMesh *edit_btmesh = BKE_editmesh_from_object(ctx->object);
+
+ if (edit_btmesh) {
+ /* In edit mode get directly from the edit mesh. */
+ psmd->mesh_original = BKE_bmesh_to_mesh_nomain(edit_btmesh->bm, &(struct BMeshToMeshParams){0});
+ }
+ else {
+ /* Otherwise get regular mesh. */
+ mesh_original = ctx->object->data;
+ }
}
- else { /* Can happen in some cases, e.g. when rendering from Edit mode... */
- BKE_id_copy_ex(NULL, &mesh_src->id, (ID **)&psmd->mesh_deformed,
+ else {
+ mesh_original = mesh_src;
+ }
+
+ if (mesh_original) {
+ /* Make a persistent copy of the mesh. We don't actually need
+ * all this data, just some topology for remapping. Could be
+ * optimized once. */
+ BKE_id_copy_ex(NULL, &mesh_original->id, (ID **)&psmd->mesh_original,
LIB_ID_CREATE_NO_MAIN |
LIB_ID_CREATE_NO_USER_REFCOUNT |
LIB_ID_CREATE_NO_DEG_TAG |
LIB_ID_COPY_NO_PREVIEW,
false);
}
- BKE_mesh_tessface_ensure(psmd->mesh_deformed);
+
+ BKE_mesh_tessface_ensure(psmd->mesh_original);
}
if (mesh_src != psmd->mesh_final && mesh_src != mesh) {
diff --git a/source/blender/modifiers/intern/MOD_surfacedeform.c b/source/blender/modifiers/intern/MOD_surfacedeform.c
index ab0b31812b2..f03ae73e2bb 100644
--- a/source/blender/modifiers/intern/MOD_surfacedeform.c
+++ b/source/blender/modifiers/intern/MOD_surfacedeform.c
@@ -1041,7 +1041,7 @@ static bool surfacedeformBind(
return data.success == 1;
}
-static Mesh *surfacedeform_get_mesh(SurfaceDeformModifierData *smd, bool *r_needsfree)
+static Mesh *surfacedeform_get_mesh(Depsgraph *depsgraph, SurfaceDeformModifierData *smd, bool *r_needsfree)
{
Mesh *mesh;
@@ -1052,8 +1052,11 @@ static Mesh *surfacedeform_get_mesh(SurfaceDeformModifierData *smd, bool *r_need
*r_needsfree = true;
}
else {
- mesh = BKE_modifier_get_evaluated_mesh_from_object(
- smd->target, smd->modifier.mode & eModifierMode_Render ? MOD_APPLY_RENDER : 0);
+ ModifierEvalContext ctx = {
+ .depsgraph = depsgraph,
+ .flag = smd->modifier.mode & eModifierMode_Render ? MOD_APPLY_RENDER : 0,
+ };
+ mesh = BKE_modifier_get_evaluated_mesh_from_object(&ctx, smd->target);
*r_needsfree = false;
}
@@ -1124,6 +1127,7 @@ static void deformVert(
static void surfacedeformModifier_do(
ModifierData *md,
+ const ModifierEvalContext *ctx,
float (*vertexCos)[3], unsigned int numverts, Object *ob)
{
SurfaceDeformModifierData *smd = (SurfaceDeformModifierData *)md;
@@ -1137,7 +1141,7 @@ static void surfacedeformModifier_do(
return;
}
- target = surfacedeform_get_mesh(smd, &free_target);
+ target = surfacedeform_get_mesh(ctx->depsgraph, smd, &free_target);
if (!target) {
modifier_setError(md, "No valid target mesh");
return;
@@ -1204,7 +1208,7 @@ static void deformVerts(
Mesh *UNUSED(mesh),
float (*vertexCos)[3], int numVerts)
{
- surfacedeformModifier_do(md, vertexCos, numVerts, ctx->object);
+ surfacedeformModifier_do(md, ctx, vertexCos, numVerts, ctx->object);
}
static void deformVertsEM(
@@ -1213,7 +1217,7 @@ static void deformVertsEM(
Mesh *UNUSED(mesh),
float (*vertexCos)[3], int numVerts)
{
- surfacedeformModifier_do(md, vertexCos, numVerts, ctx->object);
+ surfacedeformModifier_do(md, ctx, vertexCos, numVerts, ctx->object);
}
static bool isDisabled(ModifierData *md, int UNUSED(useRenderParams))
diff --git a/source/blender/modifiers/intern/MOD_uvproject.c b/source/blender/modifiers/intern/MOD_uvproject.c
index 207c692071c..b491496caa4 100644
--- a/source/blender/modifiers/intern/MOD_uvproject.c
+++ b/source/blender/modifiers/intern/MOD_uvproject.c
@@ -55,7 +55,9 @@
#include "MEM_guardedalloc.h"
+#include "DEG_depsgraph.h"
#include "DEG_depsgraph_build.h"
+#include "DEG_depsgraph_query.h"
static void initData(ModifierData *md)
{
@@ -111,7 +113,7 @@ static void updateDepsgraph(ModifierData *md, const ModifierUpdateDepsgraphConte
}
typedef struct Projector {
- Object *ob; /* object this projector is derived from */
+ Object *ob_eval; /* object this projector is derived from */
float projmat[4][4]; /* projection matrix */
float normal[3]; /* projector normal in world space */
void *uci; /* optional uv-project info (panorama projection) */
@@ -119,6 +121,7 @@ typedef struct Projector {
static Mesh *uvprojectModifier_do(
UVProjectModifierData *umd,
+ Depsgraph *depsgraph,
Object *ob, Mesh *mesh)
{
float (*coords)[3], (*co)[3];
@@ -137,7 +140,7 @@ static Mesh *uvprojectModifier_do(
for (i = 0; i < umd->num_projectors; ++i)
if (umd->projectors[i])
- projectors[num_projectors++].ob = umd->projectors[i];
+ projectors[num_projectors++].ob_eval = DEG_get_evaluated_object(depsgraph, umd->projectors[i]);
if (num_projectors == 0) return mesh;
@@ -154,15 +157,14 @@ static Mesh *uvprojectModifier_do(
float offsetmat[4][4];
Camera *cam = NULL;
/* calculate projection matrix */
- invert_m4_m4(projectors[i].projmat, projectors[i].ob->obmat);
+ invert_m4_m4(projectors[i].projmat, projectors[i].ob_eval->obmat);
projectors[i].uci = NULL;
- if (projectors[i].ob->type == OB_CAMERA) {
-
- cam = (Camera *)projectors[i].ob->data;
+ if (projectors[i].ob_eval->type == OB_CAMERA) {
+ cam = (Camera *)projectors[i].ob_eval->data;
if (cam->type == CAM_PANO) {
- projectors[i].uci = BLI_uvproject_camera_info(projectors[i].ob, NULL, aspx, aspy);
+ projectors[i].uci = BLI_uvproject_camera_info(projectors[i].ob_eval, NULL, aspx, aspy);
BLI_uvproject_camera_info_scale(projectors[i].uci, scax, scay);
free_uci = 1;
}
@@ -171,7 +173,7 @@ static Mesh *uvprojectModifier_do(
/* setup parameters */
BKE_camera_params_init(&params);
- BKE_camera_params_from_object(&params, projectors[i].ob);
+ BKE_camera_params_from_object(&params, projectors[i].ob_eval);
/* compute matrix, viewplane, .. */
BKE_camera_params_compute_viewplane(&params, 1, 1, aspx, aspy);
@@ -200,7 +202,7 @@ static Mesh *uvprojectModifier_do(
projectors[i].normal[0] = 0;
projectors[i].normal[1] = 0;
projectors[i].normal[2] = 1;
- mul_mat3_m4_v3(projectors[i].ob->obmat, projectors[i].normal);
+ mul_mat3_m4_v3(projectors[i].ob_eval->obmat, projectors[i].normal);
}
numPolys = mesh->totpoly;
@@ -312,7 +314,7 @@ static Mesh *applyModifier(
Mesh *result;
UVProjectModifierData *umd = (UVProjectModifierData *) md;
- result = uvprojectModifier_do(umd, ctx->object, mesh);
+ result = uvprojectModifier_do(umd, ctx->depsgraph, ctx->object, mesh);
return result;
}
diff --git a/source/blender/modifiers/intern/MOD_weightvgproximity.c b/source/blender/modifiers/intern/MOD_weightvgproximity.c
index 64133222c1e..9e77e0d3794 100644
--- a/source/blender/modifiers/intern/MOD_weightvgproximity.c
+++ b/source/blender/modifiers/intern/MOD_weightvgproximity.c
@@ -506,7 +506,7 @@ static Mesh *applyModifier(ModifierData *md, const ModifierEvalContext *ctx, Mes
const bool use_trgt_faces = (wmd->proximity_flags & MOD_WVG_PROXIMITY_GEOM_FACES) != 0;
if (use_trgt_verts || use_trgt_edges || use_trgt_faces) {
- Mesh *target_mesh = BKE_modifier_get_evaluated_mesh_from_object(obr, ctx->flag);
+ Mesh *target_mesh = BKE_modifier_get_evaluated_mesh_from_object(ctx, obr);
/* We must check that we do have a valid target_mesh! */
if (target_mesh != NULL) {
diff --git a/source/blender/nodes/CMakeLists.txt b/source/blender/nodes/CMakeLists.txt
index 5acd0a9fcea..67c86180188 100644
--- a/source/blender/nodes/CMakeLists.txt
+++ b/source/blender/nodes/CMakeLists.txt
@@ -173,6 +173,7 @@ set(SRC
shader/nodes/node_shader_fresnel.c
shader/nodes/node_shader_geometry.c
shader/nodes/node_shader_holdout.c
+ shader/nodes/node_shader_ies_light.c
shader/nodes/node_shader_layer_weight.c
shader/nodes/node_shader_light_falloff.c
shader/nodes/node_shader_light_path.c
diff --git a/source/blender/nodes/NOD_shader.h b/source/blender/nodes/NOD_shader.h
index 3d6a8647628..158d20a5c19 100644
--- a/source/blender/nodes/NOD_shader.h
+++ b/source/blender/nodes/NOD_shader.h
@@ -136,6 +136,7 @@ void register_node_type_sh_tex_musgrave(void);
void register_node_type_sh_tex_noise(void);
void register_node_type_sh_tex_checker(void);
void register_node_type_sh_bump(void);
+void register_node_type_sh_tex_ies(void);
#endif
diff --git a/source/blender/nodes/NOD_static_types.h b/source/blender/nodes/NOD_static_types.h
index efb8eb66737..437093a9cb3 100644
--- a/source/blender/nodes/NOD_static_types.h
+++ b/source/blender/nodes/NOD_static_types.h
@@ -126,6 +126,7 @@ DefNode( ShaderNode, SH_NODE_COMBXYZ, 0, "CO
DefNode( ShaderNode, SH_NODE_BEVEL, def_sh_bevel, "BEVEL", Bevel, "Bevel", "" )
DefNode( ShaderNode, SH_NODE_DISPLACEMENT, def_sh_displacement, "DISPLACEMENT", Displacement, "Displacement", "" )
DefNode( ShaderNode, SH_NODE_VECTOR_DISPLACEMENT,def_sh_vector_displacement,"VECTOR_DISPLACEMENT",VectorDisplacement,"Vector Displacement","" )
+DefNode( ShaderNode, SH_NODE_TEX_IES, def_sh_tex_ies, "TEX_IES", TexIES, "IES Texture", "" )
DefNode( CompositorNode, CMP_NODE_VIEWER, def_cmp_viewer, "VIEWER", Viewer, "Viewer", "" )
DefNode( CompositorNode, CMP_NODE_RGB, 0, "RGB", RGB, "RGB", "" )
diff --git a/source/blender/nodes/composite/nodes/node_composite_image.c b/source/blender/nodes/composite/nodes/node_composite_image.c
index be23c535cba..a1beadbdc03 100644
--- a/source/blender/nodes/composite/nodes/node_composite_image.c
+++ b/source/blender/nodes/composite/nodes/node_composite_image.c
@@ -306,6 +306,7 @@ static void node_composit_init_image(bNodeTree *ntree, bNode *node)
iuser->sfra = 1;
iuser->fie_ima = 2;
iuser->ok = 1;
+ iuser->flag |= IMA_ANIM_ALWAYS;
/* setup initial outputs */
cmp_node_image_verify_outputs(ntree, node, false);
diff --git a/source/blender/nodes/shader/nodes/node_shader_ies_light.c b/source/blender/nodes/shader/nodes/node_shader_ies_light.c
new file mode 100644
index 00000000000..8084f445e34
--- /dev/null
+++ b/source/blender/nodes/shader/nodes/node_shader_ies_light.c
@@ -0,0 +1,61 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2018 Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#include "../node_shader_util.h"
+
+/* **************** IES Light ******************** */
+
+static bNodeSocketTemplate sh_node_tex_ies_in[] = {
+ { SOCK_VECTOR, 1, N_("Vector"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_NONE, SOCK_HIDE_VALUE},
+ { SOCK_FLOAT, 1, N_("Strength"), 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1000000.0f, PROP_NONE},
+ { -1, 0, "" }
+};
+
+static bNodeSocketTemplate sh_node_tex_ies_out[] = {
+ { SOCK_FLOAT, 0, N_("Fac")},
+ { -1, 0, "" }
+};
+
+static void node_shader_init_tex_ies(bNodeTree *UNUSED(ntree), bNode *node)
+{
+ NodeShaderTexIES *tex = MEM_callocN(sizeof(NodeShaderTexIES), "NodeShaderIESLight");
+ node->storage = tex;
+}
+
+/* node type definition */
+void register_node_type_sh_tex_ies(void)
+{
+ static bNodeType ntype;
+
+ sh_node_type_base(&ntype, SH_NODE_TEX_IES, "IES Texture", NODE_CLASS_TEXTURE, 0);
+ node_type_compatibility(&ntype, NODE_NEW_SHADING);
+ node_type_socket_templates(&ntype, sh_node_tex_ies_in, sh_node_tex_ies_out);
+ node_type_init(&ntype, node_shader_init_tex_ies);
+ node_type_storage(&ntype, "NodeShaderTexIES", node_free_standard_storage, node_copy_standard_storage);
+
+ nodeRegisterType(&ntype);
+}
diff --git a/source/blender/nodes/shader/nodes/node_shader_math.c b/source/blender/nodes/shader/nodes/node_shader_math.c
index 6cd58d2fb85..f36310f4d00 100644
--- a/source/blender/nodes/shader/nodes/node_shader_math.c
+++ b/source/blender/nodes/shader/nodes/node_shader_math.c
@@ -221,6 +221,11 @@ static void node_shader_exec_math(void *UNUSED(data), int UNUSED(thread), bNode
r = fabsf(a);
break;
}
+ case NODE_MATH_ATAN2:
+ {
+ r = atan2(a, b);
+ break;
+ }
}
if (node->custom2 & SHD_MATH_CLAMP) {
CLAMP(r, 0.0f, 1.0f);
@@ -235,6 +240,7 @@ static int gpu_shader_math(GPUMaterial *mat, bNode *node, bNodeExecData *UNUSED(
"math_divide", "math_sine", "math_cosine", "math_tangent", "math_asin",
"math_acos", "math_atan", "math_pow", "math_log", "math_min", "math_max",
"math_round", "math_less_than", "math_greater_than", "math_modulo", "math_abs",
+ "math_atan2"
};
switch (node->custom1) {
@@ -249,6 +255,7 @@ static int gpu_shader_math(GPUMaterial *mat, bNode *node, bNodeExecData *UNUSED(
case NODE_MATH_LESS:
case NODE_MATH_GREATER:
case NODE_MATH_MOD:
+ case NODE_MATH_ATAN2:
GPU_stack_link(mat, node, names[node->custom1], in, out);
break;
case NODE_MATH_SIN:
diff --git a/source/blender/nodes/texture/nodes/node_texture_image.c b/source/blender/nodes/texture/nodes/node_texture_image.c
index 69c8f4b7262..fd1e818b63b 100644
--- a/source/blender/nodes/texture/nodes/node_texture_image.c
+++ b/source/blender/nodes/texture/nodes/node_texture_image.c
@@ -95,6 +95,7 @@ static void init(bNodeTree *UNUSED(ntree), bNode *node)
iuser->sfra = 1;
iuser->fie_ima = 2;
iuser->ok = 1;
+ iuser->flag |= IMA_ANIM_ALWAYS;
}
void register_node_type_tex_image(void)
diff --git a/source/blender/nodes/texture/nodes/node_texture_math.c b/source/blender/nodes/texture/nodes/node_texture_math.c
index 19bc16fb82d..d8dc2a62625 100644
--- a/source/blender/nodes/texture/nodes/node_texture_math.c
+++ b/source/blender/nodes/texture/nodes/node_texture_math.c
@@ -189,6 +189,12 @@ static void valuefn(float *out, TexParams *p, bNode *node, bNodeStack **in, shor
break;
}
+ case NODE_MATH_ATAN2:
+ {
+ *out = atan2(in0, in1);
+ break;
+ }
+
default:
{
BLI_assert(0);
diff --git a/source/blender/python/intern/stubs.c b/source/blender/python/intern/stubs.c
index cc186be60ea..3b3a4d6d2fe 100644
--- a/source/blender/python/intern/stubs.c
+++ b/source/blender/python/intern/stubs.c
@@ -32,7 +32,7 @@
#include "BPY_extern.h"
-#if defined(__GNUC__)
+#if defined(__GNUC__) || defined(__clang__)
# pragma GCC diagnostic error "-Wmissing-prototypes"
# pragma GCC diagnostic ignored "-Wunused-parameter"
#endif
diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c
index 4f3f8ece1f0..c800370a85d 100644
--- a/source/blender/windowmanager/intern/wm_event_system.c
+++ b/source/blender/windowmanager/intern/wm_event_system.c
@@ -1958,14 +1958,7 @@ static int wm_handler_operator_call(bContext *C, ListBase *handlers, wmEventHand
/* remove modal handler, operator itself should have been canceled and freed */
if (retval & (OPERATOR_CANCELLED | OPERATOR_FINISHED)) {
- /* set cursor back to the default for the region */
- wmWindow *win = CTX_wm_window(C);
- WM_cursor_grab_disable(win, NULL);
- /* Causes crash when joining areas: T55166, seems this is not even needed. */
-#if 0
- ED_region_cursor_set(win, area, region);
-#endif
-
+ WM_cursor_grab_disable(CTX_wm_window(C), NULL);
BLI_remlink(handlers, handler);
wm_event_free_handler(handler);
diff --git a/source/blender/windowmanager/intern/wm_keymap.c b/source/blender/windowmanager/intern/wm_keymap.c
index 9d26c7e92d5..f2387846fd2 100644
--- a/source/blender/windowmanager/intern/wm_keymap.c
+++ b/source/blender/windowmanager/intern/wm_keymap.c
@@ -1215,9 +1215,11 @@ static wmKeyMapItem *wm_keymap_item_find_props(
/* look into multiple handler lists to find the item */
if (win) {
- found = wm_keymap_item_find_handlers(C, &win->modalhandlers, opname, opcontext, properties, is_strict, is_hotkey, r_keymap);
+ found = wm_keymap_item_find_handlers(
+ C, &win->modalhandlers, opname, opcontext, properties, is_strict, is_hotkey, r_keymap);
if (found == NULL) {
- found = wm_keymap_item_find_handlers(C, &win->handlers, opname, opcontext, properties, is_strict, is_hotkey, r_keymap);
+ found = wm_keymap_item_find_handlers(
+ C, &win->handlers, opname, opcontext, properties, is_strict, is_hotkey, r_keymap);
}
}
diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c
index 1fe0799d6c1..7cf1fe3bdfa 100644
--- a/source/blender/windowmanager/intern/wm_operators.c
+++ b/source/blender/windowmanager/intern/wm_operators.c
@@ -2248,7 +2248,7 @@ static int wm_call_panel_exec(bContext *C, wmOperator *op)
const int space_type = RNA_enum_get(op->ptr, "space_type");
const int region_type = RNA_enum_get(op->ptr, "region_type");
- return UI_popover_panel_invoke(C, space_type, region_type, idname, op->reports);
+ return UI_popover_panel_invoke(C, space_type, region_type, idname, true, op->reports);
}
static void WM_OT_call_panel(wmOperatorType *ot)
diff --git a/source/blender/windowmanager/manipulators/intern/wm_manipulator.c b/source/blender/windowmanager/manipulators/intern/wm_manipulator.c
index f5a8746f807..5634a1a3ee7 100644
--- a/source/blender/windowmanager/manipulators/intern/wm_manipulator.c
+++ b/source/blender/windowmanager/manipulators/intern/wm_manipulator.c
@@ -509,7 +509,7 @@ void wm_manipulator_calculate_scale(wmManipulator *mpr, const bContext *C)
}
/* Exclude matrix_offset from scale. */
- scale *= ED_view3d_pixel_size(rv3d, matrix_world[3]) / U.pixelsize;
+ scale *= ED_view3d_pixel_size_no_ui_scale(rv3d, matrix_world[3]);
}
else {
scale *= 0.02f;