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:
authorLukas Stockner <lukas.stockner@freenet.de>2018-07-27 22:42:50 +0300
committerLukas Stockner <lukas.stockner@freenet.de>2018-07-27 22:42:50 +0300
commite704c78d8799172aa0f5a9122c0ff72642db0203 (patch)
tree5610b07c0c489663c24809c88da967ba261c90c4
parent3c643440a3348e1fc8ddc79fcdbd3933e1245562 (diff)
parent48759580839aa4e2ad2541ff4c19baaaf751721d (diff)
Merge remote-tracking branch 'origin/blender2.8' into udimtemp-udim-images
-rw-r--r--CMakeLists.txt6
-rw-r--r--intern/cycles/blender/addon/engine.py12
-rw-r--r--intern/cycles/blender/addon/ui.py7
-rw-r--r--intern/cycles/blender/blender_mesh.cpp15
-rw-r--r--intern/cycles/blender/blender_object.cpp29
-rw-r--r--intern/cycles/blender/blender_python.cpp9
-rw-r--r--intern/cycles/blender/blender_session.cpp18
-rw-r--r--intern/cycles/blender/blender_session.h2
-rw-r--r--intern/cycles/blender/blender_sync.cpp17
-rw-r--r--intern/cycles/blender/blender_sync.h18
-rw-r--r--intern/cycles/graph/node.cpp85
-rw-r--r--intern/cycles/graph/node.h3
-rw-r--r--intern/cycles/graph/node_type.cpp2
-rw-r--r--intern/cycles/graph/node_type.h6
-rw-r--r--intern/cycles/kernel/kernel_montecarlo.h29
-rw-r--r--intern/cycles/kernel/shaders/node_bump.osl2
-rw-r--r--intern/cycles/kernel/shaders/node_normal_map.osl2
-rw-r--r--intern/cycles/kernel/shaders/stdosl.h30
-rw-r--r--intern/cycles/kernel/svm/svm_displace.h2
-rw-r--r--intern/cycles/kernel/svm/svm_tex_coord.h2
-rw-r--r--intern/cycles/render/CMakeLists.txt2
-rw-r--r--intern/cycles/render/image.cpp140
-rw-r--r--intern/cycles/render/image.h10
-rw-r--r--intern/cycles/render/mesh.cpp24
-rw-r--r--intern/cycles/render/mesh.h7
-rw-r--r--intern/cycles/render/scene.cpp6
-rw-r--r--intern/cycles/render/scene.h3
-rw-r--r--intern/cycles/render/stats.cpp119
-rw-r--r--intern/cycles/render/stats.h104
-rw-r--r--intern/ghost/intern/GHOST_ContextSDL.cpp20
-rw-r--r--intern/ghost/intern/GHOST_ContextSDL.h1
-rw-r--r--intern/ghost/intern/GHOST_System.cpp4
-rw-r--r--intern/ghost/intern/GHOST_SystemSDL.cpp29
-rw-r--r--intern/ghost/intern/GHOST_SystemSDL.h6
-rw-r--r--intern/ghost/intern/GHOST_WindowSDL.cpp2
-rw-r--r--intern/rigidbody/RBI_api.h9
-rw-r--r--intern/rigidbody/rb_bullet_api.cpp55
-rw-r--r--release/scripts/modules/bpy_extras/object_utils.py2
-rw-r--r--release/scripts/startup/bl_operators/clip.py4
-rw-r--r--release/scripts/startup/bl_operators/presets.py2
-rw-r--r--release/scripts/startup/bl_operators/rigidbody.py12
-rw-r--r--release/scripts/startup/bl_operators/uvcalc_lightmap.py2
-rw-r--r--release/scripts/startup/bl_ui/properties_data_camera.py9
-rw-r--r--release/scripts/startup/bl_ui/properties_data_mesh.py8
-rw-r--r--release/scripts/startup/bl_ui/properties_grease_pencil_common.py2
-rw-r--r--release/scripts/startup/bl_ui/properties_particle.py449
-rw-r--r--release/scripts/startup/bl_ui/properties_physics_cloth.py200
-rw-r--r--release/scripts/startup/bl_ui/properties_physics_dynamicpaint.py328
-rw-r--r--release/scripts/startup/bl_ui/properties_physics_rigidbody.py136
-rw-r--r--release/scripts/startup/bl_ui/properties_physics_rigidbody_constraint.py5
-rw-r--r--release/scripts/startup/bl_ui/properties_render.py2
-rw-r--r--release/scripts/startup/bl_ui/properties_texture.py560
-rw-r--r--release/scripts/startup/bl_ui/space_filebrowser.py4
-rw-r--r--release/scripts/startup/bl_ui/space_node.py24
-rw-r--r--release/scripts/startup/bl_ui/space_outliner.py11
-rw-r--r--release/scripts/startup/bl_ui/space_topbar.py57
-rw-r--r--release/scripts/startup/bl_ui/space_view3d.py16
-rw-r--r--release/scripts/templates_py/batch_export.py8
-rw-r--r--release/scripts/templates_py/operator_modal_view3d_raycast.py2
-rw-r--r--source/blender/blenfont/intern/blf_font.c3
-rw-r--r--source/blender/blenfont/intern/blf_glyph.c6
-rw-r--r--source/blender/blenkernel/BKE_blender_version.h2
-rw-r--r--source/blender/blenkernel/BKE_bvhutils.h8
-rw-r--r--source/blender/blenkernel/BKE_sequencer.h2
-rw-r--r--source/blender/blenkernel/BKE_subdiv.h20
-rw-r--r--source/blender/blenkernel/intern/anim.c2
-rw-r--r--source/blender/blenkernel/intern/bvhutils.c79
-rw-r--r--source/blender/blenkernel/intern/camera.c5
-rw-r--r--source/blender/blenkernel/intern/layer.c16
-rw-r--r--source/blender/blenkernel/intern/object.c1
-rw-r--r--source/blender/blenkernel/intern/particle_system.c2
-rw-r--r--source/blender/blenkernel/intern/rigidbody.c66
-rw-r--r--source/blender/blenkernel/intern/scene.c1
-rw-r--r--source/blender/blenkernel/intern/screen.c1
-rw-r--r--source/blender/blenkernel/intern/sequencer.c1
-rw-r--r--source/blender/blenkernel/intern/subdiv.c21
-rw-r--r--source/blender/blenkernel/intern/subdiv_mesh.c450
-rw-r--r--source/blender/blenlib/intern/BLI_kdtree.c10
-rw-r--r--source/blender/blenlib/intern/math_geom.c32
-rw-r--r--source/blender/blenloader/intern/readfile.c1
-rw-r--r--source/blender/blenloader/intern/versioning_250.c18
-rw-r--r--source/blender/blenloader/intern/versioning_280.c56
-rw-r--r--source/blender/blenloader/intern/writefile.c14
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder.cc6
-rw-r--r--source/blender/draw/engines/eevee/eevee_data.c6
-rw-r--r--source/blender/draw/engines/eevee/eevee_lightcache.c9
-rw-r--r--source/blender/draw/engines/eevee/eevee_private.h1
-rw-r--r--source/blender/draw/engines/workbench/workbench_data.c8
-rw-r--r--source/blender/draw/engines/workbench/workbench_deferred.c7
-rw-r--r--source/blender/draw/engines/workbench/workbench_forward.c13
-rw-r--r--source/blender/draw/intern/draw_manager_shader.c11
-rw-r--r--source/blender/draw/intern/draw_view.c11
-rw-r--r--source/blender/editors/armature/pose_edit.c3
-rw-r--r--source/blender/editors/gpencil/gpencil_convert.c17
-rw-r--r--source/blender/editors/include/ED_object.h1
-rw-r--r--source/blender/editors/include/UI_interface.h4
-rw-r--r--source/blender/editors/include/UI_interface_icons.h2
-rw-r--r--source/blender/editors/interface/interface_icons.c3
-rw-r--r--source/blender/editors/interface/interface_panel.c6
-rw-r--r--source/blender/editors/interface/interface_templates.c50
-rw-r--r--source/blender/editors/interface/interface_utils.c4
-rw-r--r--source/blender/editors/interface/resources.c2
-rw-r--r--source/blender/editors/mesh/editmesh_knife.c7
-rw-r--r--source/blender/editors/mesh/editmesh_select.c12
-rw-r--r--source/blender/editors/mesh/editmesh_tools.c18
-rw-r--r--source/blender/editors/mesh/mesh_ops.c18
-rw-r--r--source/blender/editors/object/object_bake_api.c24
-rw-r--r--source/blender/editors/object/object_data_transfer.c20
-rw-r--r--source/blender/editors/object/object_group.c11
-rw-r--r--source/blender/editors/object/object_ops.c24
-rw-r--r--source/blender/editors/object/object_relations.c19
-rw-r--r--source/blender/editors/screen/screendump.c4
-rw-r--r--source/blender/editors/sound/sound_ops.c4
-rw-r--r--source/blender/editors/space_file/file_panels.c28
-rw-r--r--source/blender/editors/space_image/image_ops.c8
-rw-r--r--source/blender/editors/space_node/node_draw.c8
-rw-r--r--source/blender/editors/space_node/node_intern.h2
-rw-r--r--source/blender/editors/space_outliner/outliner_collections.c129
-rw-r--r--source/blender/editors/space_outliner/outliner_draw.c13
-rw-r--r--source/blender/editors/space_outliner/outliner_intern.h6
-rw-r--r--source/blender/editors/space_outliner/outliner_ops.c9
-rw-r--r--source/blender/editors/space_sequencer/sequencer_add.c4
-rw-r--r--source/blender/editors/space_sequencer/sequencer_edit.c5
-rw-r--r--source/blender/editors/space_view3d/space_view3d.c2
-rw-r--r--source/blender/editors/space_view3d/view3d_draw.c2
-rw-r--r--source/blender/editors/space_view3d/view3d_snap.c58
-rw-r--r--source/blender/editors/transform/transform.c6
-rw-r--r--source/blender/editors/transform/transform_ops.c46
-rw-r--r--source/blender/editors/transform/transform_snap.c2
-rw-r--r--source/blender/editors/transform/transform_snap_object.c196
-rw-r--r--source/blender/editors/uvedit/uvedit_ops.c10
-rw-r--r--source/blender/gpu/GPU_extensions.h1
-rw-r--r--source/blender/gpu/GPU_material.h1
-rw-r--r--source/blender/gpu/intern/gpu_extensions.c7
-rw-r--r--source/blender/gpu/intern/gpu_texture.c7
-rw-r--r--source/blender/makesdna/DNA_layer_types.h4
-rw-r--r--source/blender/makesdna/DNA_object_types.h1
-rw-r--r--source/blender/makesdna/DNA_rigidbody_types.h11
-rw-r--r--source/blender/makesdna/DNA_scene_types.h2
-rw-r--r--source/blender/makesdna/DNA_view3d_types.h17
-rw-r--r--source/blender/makesrna/RNA_access.h2
-rw-r--r--source/blender/makesrna/RNA_enum_types.h1
-rw-r--r--source/blender/makesrna/intern/rna_access.c2
-rw-r--r--source/blender/makesrna/intern/rna_camera.c9
-rw-r--r--source/blender/makesrna/intern/rna_layer.c12
-rw-r--r--source/blender/makesrna/intern/rna_object_api.c73
-rw-r--r--source/blender/makesrna/intern/rna_particle.c3
-rw-r--r--source/blender/makesrna/intern/rna_rigidbody.c102
-rw-r--r--source/blender/makesrna/intern/rna_scene.c57
-rw-r--r--source/blender/makesrna/intern/rna_space.c26
-rw-r--r--source/blender/makesrna/intern/rna_world.c3
-rw-r--r--source/blender/python/mathutils/mathutils_Vector.c16
-rw-r--r--source/blender/render/intern/include/render_result.h2
-rw-r--r--source/blender/windowmanager/WM_keymap.h4
-rw-r--r--source/blender/windowmanager/WM_types.h6
-rw-r--r--source/blender/windowmanager/intern/wm.c59
-rw-r--r--source/blender/windowmanager/intern/wm_files.c12
-rw-r--r--source/blender/windowmanager/intern/wm_init_exit.c13
-rw-r--r--source/blender/windowmanager/intern/wm_keymap.c19
-rw-r--r--source/blender/windowmanager/intern/wm_operators.c17
-rw-r--r--source/blender/windowmanager/intern/wm_window.c11
-rw-r--r--source/blender/windowmanager/wm_window.h1
-rw-r--r--source/creator/creator_args.c10
163 files changed, 3343 insertions, 1524 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 2961aafe908..0d79ab2ed90 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1555,7 +1555,11 @@ if(WITH_PYTHON)
endif()
if(WITH_CXX11)
- if(CMAKE_COMPILER_IS_GNUCC OR CMAKE_C_COMPILER_ID MATCHES "Clang")
+ if(
+ CMAKE_COMPILER_IS_GNUCC OR
+ CMAKE_C_COMPILER_ID MATCHES "Clang" OR
+ CMAKE_C_COMPILER_ID MATCHES "Intel"
+ )
# TODO(sergey): Do we want c++11 or gnu-c++11 here?
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
elseif(MSVC)
diff --git a/intern/cycles/blender/addon/engine.py b/intern/cycles/blender/addon/engine.py
index 5c52a8bcce9..476cf975737 100644
--- a/intern/cycles/blender/addon/engine.py
+++ b/intern/cycles/blender/addon/engine.py
@@ -52,7 +52,9 @@ def _workaround_buggy_drivers():
def _configure_argument_parser():
import argparse
- parser = argparse.ArgumentParser(description="Cycles Addon argument parser")
+ # No help because it conflicts with general Python scripts argument parsing
+ parser = argparse.ArgumentParser(description="Cycles Addon argument parser",
+ add_help=False)
parser.add_argument("--cycles-resumable-num-chunks",
help="Number of chunks to split sample range into",
default=None)
@@ -65,6 +67,9 @@ def _configure_argument_parser():
parser.add_argument("--cycles-resumable-end-chunk",
help="End chunk to render",
default=None)
+ parser.add_argument("--cycles-print-stats",
+ help="Print rendering statistics to stderr",
+ action='store_true')
return parser
@@ -93,6 +98,9 @@ def _parse_command_line():
int(args.cycles_resumable_start_chunk),
int(args.cycles_resumable_end_chunk),
)
+ if args.cycles_print_stats:
+ import _cycles
+ _cycles.enable_print_stats()
def init():
@@ -168,7 +176,7 @@ def reset(engine, data, depsgraph):
import bpy
if bpy.app.debug_value == 256:
- _cycles.debug_flags_update(depsgraph.scene)
+ _cycles.debug_flags_update(depsgraph.scene.as_pointer())
else:
_cycles.debug_flags_reset()
diff --git a/intern/cycles/blender/addon/ui.py b/intern/cycles/blender/addon/ui.py
index 3d5ed6b9b44..a1941ce6176 100644
--- a/intern/cycles/blender/addon/ui.py
+++ b/intern/cycles/blender/addon/ui.py
@@ -883,14 +883,9 @@ class CYCLES_CAMERA_PT_dof_viewport(CyclesButtonsPanel, Panel):
cam = context.camera
dof_options = cam.gpu_dof
- hq_support = dof_options.is_hq_supported
sub = flow.column(align=True)
- subhq = sub.column()
- subhq.active = hq_support
- subhq.prop(dof_options, "use_high_quality")
sub.prop(dof_options, "fstop")
- if dof_options.use_high_quality and hq_support:
- sub.prop(dof_options, "blades")
+ sub.prop(dof_options, "blades")
class CYCLES_PT_context_material(CyclesButtonsPanel, Panel):
diff --git a/intern/cycles/blender/blender_mesh.cpp b/intern/cycles/blender/blender_mesh.cpp
index edb6d04f0bb..34f559674fa 100644
--- a/intern/cycles/blender/blender_mesh.cpp
+++ b/intern/cycles/blender/blender_mesh.cpp
@@ -1081,27 +1081,18 @@ Mesh *BlenderSync::sync_mesh(BL::Depsgraph& b_depsgraph,
/* test if we can instance or if the object is modified */
BL::ID b_ob_data = b_ob.data();
BL::ID key = (BKE_object_is_modified(b_ob))? b_ob_instance: b_ob_data;
- BL::Material material_override = view_layer.material_override;
/* find shader indices */
vector<Shader*> used_shaders;
BL::Object::material_slots_iterator slot;
for(b_ob.material_slots.begin(slot); slot != b_ob.material_slots.end(); ++slot) {
- if(material_override) {
- find_shader(material_override, used_shaders, scene->default_surface);
- }
- else {
- BL::ID b_material(slot->material());
- find_shader(b_material, used_shaders, scene->default_surface);
- }
+ BL::ID b_material(slot->material());
+ find_shader(b_material, used_shaders, scene->default_surface);
}
if(used_shaders.size() == 0) {
- if(material_override)
- find_shader(material_override, used_shaders, scene->default_surface);
- else
- used_shaders.push_back(scene->default_surface);
+ used_shaders.push_back(scene->default_surface);
}
/* test if we need to sync */
diff --git a/intern/cycles/blender/blender_object.cpp b/intern/cycles/blender/blender_object.cpp
index ed01d728931..a1f39d0848f 100644
--- a/intern/cycles/blender/blender_object.cpp
+++ b/intern/cycles/blender/blender_object.cpp
@@ -291,8 +291,8 @@ void BlenderSync::sync_background_light(bool use_portal)
/* Object */
Object *BlenderSync::sync_object(BL::Depsgraph& b_depsgraph,
+ BL::ViewLayer& b_view_layer,
BL::DepsgraphObjectInstance& b_instance,
- uint layer_flag,
float motion_time,
bool hide_tris,
BlenderObjectCulling& culling,
@@ -314,10 +314,13 @@ Object *BlenderSync::sync_object(BL::Depsgraph& b_depsgraph,
}
/* light is handled separately */
- if(object_is_light(b_ob)) {
- /* don't use lights for excluded layers used as mask layer */
- if(!motion && !((layer_flag & view_layer.holdout_layer) &&
- (layer_flag & view_layer.exclude_layer)))
+ if(!motion && object_is_light(b_ob)) {
+ /* TODO: don't use lights for excluded layers used as mask layer,
+ * when dynamic overrides are back. */
+#if 0
+ if(!((layer_flag & view_layer.holdout_layer) &&
+ (layer_flag & view_layer.exclude_layer)))
+#endif
{
sync_light(b_parent,
persistent_id,
@@ -343,21 +346,24 @@ Object *BlenderSync::sync_object(BL::Depsgraph& b_depsgraph,
/* Visibility flags for both parent and child. */
PointerRNA cobject = RNA_pointer_get(&b_ob.ptr, "cycles");
- bool use_holdout = (layer_flag & view_layer.holdout_layer) != 0 ||
- get_boolean(cobject, "is_holdout");
+ bool use_holdout = get_boolean(cobject, "is_holdout") ||
+ b_parent.holdout_get(b_view_layer);
uint visibility = object_ray_visibility(b_ob) & PATH_RAY_ALL_VISIBILITY;
if(b_parent.ptr.data != b_ob.ptr.data) {
visibility &= object_ray_visibility(b_parent);
}
- /* Make holdout objects on excluded layer invisible for non-camera rays. */
+ /* TODO: make holdout objects on excluded layer invisible for non-camera rays. */
+#if 0
if(use_holdout && (layer_flag & view_layer.exclude_layer)) {
visibility &= ~(PATH_RAY_ALL_VISIBILITY - PATH_RAY_CAMERA);
}
+#endif
- /* Hide objects not on render layer from camera rays. */
- if(!(layer_flag & view_layer.layer)) {
+ /* Clear camera visibility for indirect only objects. */
+ bool use_indirect_only = b_parent.indirect_only_get(b_view_layer);
+ if(use_indirect_only) {
visibility &= ~PATH_RAY_CAMERA;
}
@@ -583,6 +589,7 @@ void BlenderSync::sync_objects(BL::Depsgraph& b_depsgraph, float motion_time)
bool cancel = false;
bool use_portal = false;
+ BL::ViewLayer b_view_layer = b_depsgraph.view_layer_eval();
BL::Depsgraph::mode_enum depsgraph_mode = b_depsgraph.mode();
BL::Depsgraph::object_instances_iterator b_instance_iter;
@@ -604,8 +611,8 @@ void BlenderSync::sync_objects(BL::Depsgraph& b_depsgraph, float motion_time)
if(!object_render_hide(b_ob, true, true, hide_tris, depsgraph_mode)) {
/* object itself */
sync_object(b_depsgraph,
+ b_view_layer,
b_instance,
- ~(0), /* until we get rid of layers */
motion_time,
hide_tris,
culling,
diff --git a/intern/cycles/blender/blender_python.cpp b/intern/cycles/blender/blender_python.cpp
index 4c199f4838f..a79c28e43aa 100644
--- a/intern/cycles/blender/blender_python.cpp
+++ b/intern/cycles/blender/blender_python.cpp
@@ -738,6 +738,12 @@ static PyObject *set_resumable_chunk_range_func(PyObject * /*self*/, PyObject *a
Py_RETURN_NONE;
}
+static PyObject *enable_print_stats_func(PyObject * /*self*/, PyObject * /*args*/)
+{
+ BlenderSession::print_render_stats = true;
+ Py_RETURN_NONE;
+}
+
static PyObject *get_device_types_func(PyObject * /*self*/, PyObject * /*args*/)
{
vector<DeviceInfo>& devices = Device::available_devices();
@@ -776,6 +782,9 @@ static PyMethodDef methods[] = {
{"debug_flags_update", debug_flags_update_func, METH_VARARGS, ""},
{"debug_flags_reset", debug_flags_reset_func, METH_NOARGS, ""},
+ /* Statistics. */
+ {"enable_print_stats", enable_print_stats_func, METH_NOARGS, ""},
+
/* Resumable render */
{"set_resumable_chunk", set_resumable_chunk_func, METH_VARARGS, ""},
{"set_resumable_chunk_range", set_resumable_chunk_range_func, METH_VARARGS, ""},
diff --git a/intern/cycles/blender/blender_session.cpp b/intern/cycles/blender/blender_session.cpp
index 1f5d67e4064..2c5ecc02e6d 100644
--- a/intern/cycles/blender/blender_session.cpp
+++ b/intern/cycles/blender/blender_session.cpp
@@ -28,6 +28,7 @@
#include "render/scene.h"
#include "render/session.h"
#include "render/shader.h"
+#include "render/stats.h"
#include "util/util_color.h"
#include "util/util_foreach.h"
@@ -48,6 +49,7 @@ int BlenderSession::num_resumable_chunks = 0;
int BlenderSession::current_resumable_chunk = 0;
int BlenderSession::start_resumable_chunk = 0;
int BlenderSession::end_resumable_chunk = 0;
+bool BlenderSession::print_render_stats = false;
BlenderSession::BlenderSession(BL::RenderEngine& b_engine,
BL::UserPreferences& b_userpref,
@@ -461,15 +463,13 @@ void BlenderSession::render(BL::Depsgraph& b_depsgraph_)
scene->integrator->tag_update(scene);
}
- /* Update number of samples per layer. */
- int samples = sync->get_layer_samples();
- bool bound_samples = sync->get_layer_bound_samples();
- int effective_layer_samples;
+ int effective_layer_samples = session_params.samples;
+ /* TODO: Update number of samples per layer. */
+#if 0
if(samples != 0 && (!bound_samples || (samples < session_params.samples)))
effective_layer_samples = samples;
- else
- effective_layer_samples = session_params.samples;
+#endif
/* Update tile manager if we're doing resumable render. */
update_resumable_tile_manager(effective_layer_samples);
@@ -481,6 +481,12 @@ void BlenderSession::render(BL::Depsgraph& b_depsgraph_)
session->start();
session->wait();
+ if(!b_engine.is_preview() && background && print_render_stats) {
+ RenderStats stats;
+ session->scene->collect_statistics(&stats);
+ printf("Render statistics:\n%s\n", stats.full_report().c_str());
+ }
+
if(session->progress.get_cancel())
break;
}
diff --git a/intern/cycles/blender/blender_session.h b/intern/cycles/blender/blender_session.h
index 614da496081..250b8ca9967 100644
--- a/intern/cycles/blender/blender_session.h
+++ b/intern/cycles/blender/blender_session.h
@@ -145,6 +145,8 @@ public:
static int start_resumable_chunk;
static int end_resumable_chunk;
+ static bool print_render_stats;
+
protected:
void do_write_update_render_result(BL::RenderResult& b_rr,
BL::RenderLayer& b_rlay,
diff --git a/intern/cycles/blender/blender_sync.cpp b/intern/cycles/blender/blender_sync.cpp
index e7b6a570131..d19eed0ea6b 100644
--- a/intern/cycles/blender/blender_sync.cpp
+++ b/intern/cycles/blender/blender_sync.cpp
@@ -365,28 +365,11 @@ void BlenderSync::sync_film()
void BlenderSync::sync_view_layer(BL::SpaceView3D& /*b_v3d*/, BL::ViewLayer& b_view_layer)
{
/* render layer */
- uint layer_override = get_layer(b_engine.layer_override());
- uint view_layers = layer_override ? layer_override : get_layer(b_scene.layers());
-
view_layer.name = b_view_layer.name();
-
- view_layer.holdout_layer = 0;
- view_layer.exclude_layer = 0;
-
- view_layer.view_layer = view_layers & ~view_layer.exclude_layer;
- view_layer.view_layer |= view_layer.exclude_layer & view_layer.holdout_layer;
-
- view_layer.layer = (1 << 20) - 1;
- view_layer.layer |= view_layer.holdout_layer;
-
- view_layer.material_override = PointerRNA_NULL;
view_layer.use_background_shader = b_view_layer.use_sky();
view_layer.use_background_ao = b_view_layer.use_ao();
view_layer.use_surfaces = b_view_layer.use_solid();
view_layer.use_hair = b_view_layer.use_strand();
-
- view_layer.bound_samples = false;
- view_layer.samples = 0;
}
/* Images */
diff --git a/intern/cycles/blender/blender_sync.h b/intern/cycles/blender/blender_sync.h
index 0465f703c51..e63ef9e5e47 100644
--- a/intern/cycles/blender/blender_sync.h
+++ b/intern/cycles/blender/blender_sync.h
@@ -78,8 +78,6 @@ public:
void sync_view(BL::SpaceView3D& b_v3d,
BL::RegionView3D& b_rv3d,
int width, int height);
- inline int get_layer_samples() { return view_layer.samples; }
- inline int get_layer_bound_samples() { return view_layer.bound_samples; }
/* get parameters */
static SceneParams get_scene_params(BL::Scene& b_scene,
@@ -126,8 +124,8 @@ private:
bool motion,
int motion_step = 0);
Object *sync_object(BL::Depsgraph& b_depsgraph,
+ BL::ViewLayer& b_view_layer,
BL::DepsgraphObjectInstance& b_instance,
- uint layer_flag,
float motion_time,
bool hide_tris,
BlenderObjectCulling& culling,
@@ -191,28 +189,18 @@ private:
struct RenderLayerInfo {
RenderLayerInfo()
- : view_layer(0), layer(0),
- holdout_layer(0), exclude_layer(0),
- material_override(PointerRNA_NULL),
- use_background_shader(true),
+ : use_background_shader(true),
use_background_ao(true),
use_surfaces(true),
- use_hair(true),
- samples(0), bound_samples(false)
+ use_hair(true)
{}
string name;
uint view_layer;
- uint layer; /* This can be safely removed from Cycles. */
- uint holdout_layer; /* This can be safely removed from Cycles. */
- uint exclude_layer; /* This can be safely removed from Cycles. */
- BL::Material material_override; /* This can be safely removed from Cycles. */
bool use_background_shader;
bool use_background_ao;
bool use_surfaces;
bool use_hair;
- int samples; /* This can be safely removed from Cycles. */
- bool bound_samples; /* This can be safely removed from Cycles. */
} view_layer;
Progress &progress;
diff --git a/intern/cycles/graph/node.cpp b/intern/cycles/graph/node.cpp
index 45ffc8d7d6b..5960d9aa7d5 100644
--- a/intern/cycles/graph/node.cpp
+++ b/intern/cycles/graph/node.cpp
@@ -425,20 +425,22 @@ bool Node::equals(const Node& other) const
/* Hash */
+namespace {
+
template<typename T>
-static void value_hash(const Node *node, const SocketType& socket, MD5Hash& md5)
+void value_hash(const Node *node, const SocketType& socket, MD5Hash& md5)
{
md5.append(((uint8_t*)node) + socket.struct_offset, socket.size());
}
-static void float3_hash(const Node *node, const SocketType& socket, MD5Hash& md5)
+void float3_hash(const Node *node, const SocketType& socket, MD5Hash& md5)
{
/* Don't compare 4th element used for padding. */
md5.append(((uint8_t*)node) + socket.struct_offset, sizeof(float) * 3);
}
template<typename T>
-static void array_hash(const Node *node, const SocketType& socket, MD5Hash& md5)
+void array_hash(const Node *node, const SocketType& socket, MD5Hash& md5)
{
const array<T>& a = *(const array<T>*)(((char*)node) + socket.struct_offset);
for (size_t i = 0; i < a.size(); i++) {
@@ -446,7 +448,7 @@ static void array_hash(const Node *node, const SocketType& socket, MD5Hash& md5)
}
}
-static void float3_array_hash(const Node *node, const SocketType& socket, MD5Hash& md5)
+void float3_array_hash(const Node *node, const SocketType& socket, MD5Hash& md5)
{
/* Don't compare 4th element used for padding. */
const array<float3>& a = *(const array<float3>*)(((char*)node) + socket.struct_offset);
@@ -455,6 +457,8 @@ static void float3_array_hash(const Node *node, const SocketType& socket, MD5Has
}
}
+} // namespace
+
void Node::hash(MD5Hash& md5)
{
md5.append(type->name.string());
@@ -495,4 +499,77 @@ void Node::hash(MD5Hash& md5)
}
}
+namespace {
+
+template<typename T>
+size_t array_size_in_bytes(const Node *node, const SocketType& socket)
+{
+ const array<T>& a = *(const array<T>*)(((char*)node) + socket.struct_offset);
+ return a.size() * sizeof(T);
+}
+
+} // namespace
+
+size_t Node::get_total_size_in_bytes() const
+{
+ size_t total_size = 0;
+ foreach(const SocketType& socket, type->inputs) {
+ switch(socket.type) {
+ case SocketType::BOOLEAN:
+ case SocketType::FLOAT:
+ case SocketType::INT:
+ case SocketType::UINT:
+ case SocketType::COLOR:
+ case SocketType::VECTOR:
+ case SocketType::POINT:
+ case SocketType::NORMAL:
+ case SocketType::POINT2:
+ case SocketType::CLOSURE:
+ case SocketType::STRING:
+ case SocketType::ENUM:
+ case SocketType::TRANSFORM:
+ case SocketType::NODE:
+ total_size += socket.size();
+ break;
+
+ case SocketType::BOOLEAN_ARRAY:
+ total_size += array_size_in_bytes<bool>(this, socket);
+ break;
+ case SocketType::FLOAT_ARRAY:
+ total_size += array_size_in_bytes<float>(this, socket);
+ break;
+ case SocketType::INT_ARRAY:
+ total_size += array_size_in_bytes<int>(this, socket);
+ break;
+ case SocketType::COLOR_ARRAY:
+ total_size += array_size_in_bytes<float3>(this, socket);
+ break;
+ case SocketType::VECTOR_ARRAY:
+ total_size += array_size_in_bytes<float3>(this, socket);
+ break;
+ case SocketType::POINT_ARRAY:
+ total_size += array_size_in_bytes<float3>(this, socket);
+ break;
+ case SocketType::NORMAL_ARRAY:
+ total_size += array_size_in_bytes<float3>(this, socket);
+ break;
+ case SocketType::POINT2_ARRAY:
+ total_size += array_size_in_bytes<float2>(this, socket);
+ break;
+ case SocketType::STRING_ARRAY:
+ total_size += array_size_in_bytes<ustring>(this, socket);
+ break;
+ case SocketType::TRANSFORM_ARRAY:
+ total_size += array_size_in_bytes<Transform>(this, socket);
+ break;
+ case SocketType::NODE_ARRAY:
+ total_size += array_size_in_bytes<void*>(this, socket);
+ break;
+
+ case SocketType::UNDEFINED: break;
+ }
+ }
+ return total_size;
+}
+
CCL_NAMESPACE_END
diff --git a/intern/cycles/graph/node.h b/intern/cycles/graph/node.h
index a738bfe197e..11695a8631d 100644
--- a/intern/cycles/graph/node.h
+++ b/intern/cycles/graph/node.h
@@ -92,6 +92,9 @@ struct Node
/* compute hash of node and its socket values */
void hash(MD5Hash& md5);
+ /* Get total size of this node. */
+ size_t get_total_size_in_bytes() const;
+
ustring name;
const NodeType *type;
};
diff --git a/intern/cycles/graph/node_type.cpp b/intern/cycles/graph/node_type.cpp
index 671ae2d815a..e045777e969 100644
--- a/intern/cycles/graph/node_type.cpp
+++ b/intern/cycles/graph/node_type.cpp
@@ -134,7 +134,7 @@ NodeType::~NodeType()
void NodeType::register_input(ustring name, ustring ui_name, SocketType::Type type, int struct_offset,
const void *default_value, const NodeEnum *enum_values,
- const NodeType **node_type, int flags, int extra_flags)
+ const NodeType **node_type, int flags, int extra_flags)
{
SocketType socket;
socket.name = name;
diff --git a/intern/cycles/graph/node_type.h b/intern/cycles/graph/node_type.h
index d4e2dbceff6..1d565794b27 100644
--- a/intern/cycles/graph/node_type.h
+++ b/intern/cycles/graph/node_type.h
@@ -114,9 +114,9 @@ struct NodeType
void register_input(ustring name, ustring ui_name, SocketType::Type type,
int struct_offset, const void *default_value,
- const NodeEnum *enum_values = NULL,
- const NodeType **node_type = NULL,
- int flags = 0, int extra_flags = 0);
+ const NodeEnum *enum_values = NULL,
+ const NodeType **node_type = NULL,
+ int flags = 0, int extra_flags = 0);
void register_output(ustring name, ustring ui_name, SocketType::Type type);
const SocketType *find_input(ustring name) const;
diff --git a/intern/cycles/kernel/kernel_montecarlo.h b/intern/cycles/kernel/kernel_montecarlo.h
index 49dc1f08cc1..09a3fe8f23d 100644
--- a/intern/cycles/kernel/kernel_montecarlo.h
+++ b/intern/cycles/kernel/kernel_montecarlo.h
@@ -184,6 +184,35 @@ ccl_device float2 regular_polygon_sample(float corners, float rotation, float u,
return make_float2(cr*p.x - sr*p.y, sr*p.x + cr*p.y);
}
+ccl_device float3 ensure_valid_reflection(float3 Ng, float3 I, float3 N)
+{
+ float3 R = 2*dot(N, I)*N - I;
+ if(dot(Ng, R) >= 0.05f) {
+ return N;
+ }
+
+ /* Form coordinate system with Ng as the Z axis and N inside the X-Z-plane.
+ * The X axis is found by normalizing the component of N that's orthogonal to Ng.
+ * The Y axis isn't actually needed.
+ */
+ float3 X = normalize(N - dot(N, Ng)*Ng);
+
+ /* Calculate N.z and N.x in the local coordinate system. */
+ float Iz = dot(I, Ng);
+ float Ix2 = sqr(dot(I, X)), Iz2 = sqr(Iz);
+ float Ix2Iz2 = Ix2 + Iz2;
+
+ float a = sqrtf(Ix2*(Ix2Iz2 - sqr(0.05f)));
+ float b = Iz*0.05f + Ix2Iz2;
+ float c = (a + b > 0.0f)? (a + b) : (-a + b);
+
+ float Nz = sqrtf(0.5f * c * (1.0f / Ix2Iz2));
+ float Nx = sqrtf(1.0f - sqr(Nz));
+
+ /* Transform back into global coordinates. */
+ return Nx*X + Nz*Ng;
+}
+
CCL_NAMESPACE_END
#endif /* __KERNEL_MONTECARLO_CL__ */
diff --git a/intern/cycles/kernel/shaders/node_bump.osl b/intern/cycles/kernel/shaders/node_bump.osl
index 7f01cf2ca91..a2a4468d5f3 100644
--- a/intern/cycles/kernel/shaders/node_bump.osl
+++ b/intern/cycles/kernel/shaders/node_bump.osl
@@ -64,5 +64,7 @@ surface node_bump(
if (use_object_space) {
NormalOut = normalize(transform("object", "world", NormalOut));
}
+
+ NormalOut = ensure_valid_reflection(Ng, I, NormalOut);
}
diff --git a/intern/cycles/kernel/shaders/node_normal_map.osl b/intern/cycles/kernel/shaders/node_normal_map.osl
index 41bcac4fb10..fda6f12a5da 100644
--- a/intern/cycles/kernel/shaders/node_normal_map.osl
+++ b/intern/cycles/kernel/shaders/node_normal_map.osl
@@ -88,5 +88,7 @@ shader node_normal_map(
if (Strength != 1.0)
Normal = normalize(NormalIn + (Normal - NormalIn) * max(Strength, 0.0));
+
+ Normal = ensure_valid_reflection(Ng, I, Normal);
}
diff --git a/intern/cycles/kernel/shaders/stdosl.h b/intern/cycles/kernel/shaders/stdosl.h
index df9c2010872..4a8378796ba 100644
--- a/intern/cycles/kernel/shaders/stdosl.h
+++ b/intern/cycles/kernel/shaders/stdosl.h
@@ -282,6 +282,36 @@ point rotate (point p, float angle, point a, point b)
return transform (M, p-a) + a;
}
+normal ensure_valid_reflection(normal Ng, vector I, normal N)
+{
+ float sqr(float x) { return x*x; }
+
+ vector R = 2*dot(N, I)*N - I;
+ if (dot(Ng, R) >= 0.05) {
+ return N;
+ }
+
+ /* Form coordinate system with Ng as the Z axis and N inside the X-Z-plane.
+ * The X axis is found by normalizing the component of N that's orthogonal to Ng.
+ * The Y axis isn't actually needed.
+ */
+ vector X = normalize(N - dot(N, Ng)*Ng);
+
+ /* Calculate N.z and N.x in the local coordinate system. */
+ float Ix = dot(I, X), Iz = dot(I, Ng);
+ float Ix2 = sqr(dot(I, X)), Iz2 = sqr(dot(I, Ng));
+ float Ix2Iz2 = Ix2 + Iz2;
+
+ float a = sqrt(Ix2*(Ix2Iz2 - sqr(0.05)));
+ float b = Iz*0.05 + Ix2Iz2;
+ float c = (a + b > 0.0)? (a + b) : (-a + b);
+
+ float Nz = sqrt(0.5 * c * (1.0 / Ix2Iz2));
+ float Nx = sqrt(1.0 - sqr(Nz));
+
+ /* Transform back into global coordinates. */
+ return Nx*X + Nz*Ng;
+}
// Color functions
diff --git a/intern/cycles/kernel/svm/svm_displace.h b/intern/cycles/kernel/svm/svm_displace.h
index b85eb9c0458..0f5b3abef87 100644
--- a/intern/cycles/kernel/svm/svm_displace.h
+++ b/intern/cycles/kernel/svm/svm_displace.h
@@ -75,6 +75,8 @@ ccl_device void svm_node_set_bump(KernelGlobals *kg, ShaderData *sd, float *stac
object_normal_transform(kg, sd, &normal_out);
}
+ normal_out = ensure_valid_reflection(sd->Ng, sd->I, normal_out);
+
stack_store_float3(stack, node.w, normal_out);
#endif
}
diff --git a/intern/cycles/kernel/svm/svm_tex_coord.h b/intern/cycles/kernel/svm/svm_tex_coord.h
index 7c207083929..45c38d64763 100644
--- a/intern/cycles/kernel/svm/svm_tex_coord.h
+++ b/intern/cycles/kernel/svm/svm_tex_coord.h
@@ -345,6 +345,8 @@ ccl_device void svm_node_normal_map(KernelGlobals *kg, ShaderData *sd, float *st
N = safe_normalize(sd->N + (N - sd->N)*strength);
}
+ N = ensure_valid_reflection(sd->Ng, sd->I, N);
+
if(is_zero(N)) {
N = sd->N;
}
diff --git a/intern/cycles/render/CMakeLists.txt b/intern/cycles/render/CMakeLists.txt
index b7248354abd..7d2220f37f9 100644
--- a/intern/cycles/render/CMakeLists.txt
+++ b/intern/cycles/render/CMakeLists.txt
@@ -33,6 +33,7 @@ set(SRC
session.cpp
shader.cpp
sobol.cpp
+ stats.cpp
svm.cpp
tables.cpp
tile.cpp
@@ -60,6 +61,7 @@ set(SRC_HEADERS
session.h
shader.h
sobol.h
+ stats.h
svm.h
tables.h
tile.h
diff --git a/intern/cycles/render/image.cpp b/intern/cycles/render/image.cpp
index 94f3f38ec7a..bead0118a02 100644
--- a/intern/cycles/render/image.cpp
+++ b/intern/cycles/render/image.cpp
@@ -17,6 +17,7 @@
#include "device/device.h"
#include "render/image.h"
#include "render/scene.h"
+#include "render/stats.h"
#include "util/util_foreach.h"
#include "util/util_logging.h"
@@ -30,20 +31,58 @@
CCL_NAMESPACE_BEGIN
+namespace {
+
/* Some helpers to silence warning in templated function. */
-static bool isfinite(uchar /*value*/)
+bool isfinite(uchar /*value*/)
{
return true;
}
-static bool isfinite(half /*value*/)
+bool isfinite(half /*value*/)
{
return true;
}
-static bool isfinite(uint16_t /*value*/)
+bool isfinite(uint16_t /*value*/)
{
return true;
}
+/* The lower three bits of a device texture slot number indicate its type.
+ * These functions convert the slot ids from ImageManager "images" ones
+ * to device ones and vice verse.
+ */
+int type_index_to_flattened_slot(int slot, ImageDataType type)
+{
+ return (slot << IMAGE_DATA_TYPE_SHIFT) | (type);
+}
+
+int flattened_slot_to_type_index(int flat_slot, ImageDataType *type)
+{
+ *type = (ImageDataType)(flat_slot & IMAGE_DATA_TYPE_MASK);
+ return flat_slot >> IMAGE_DATA_TYPE_SHIFT;
+}
+
+const char* name_from_type(ImageDataType type)
+{
+ switch(type) {
+ case IMAGE_DATA_TYPE_FLOAT4: return "float4";
+ case IMAGE_DATA_TYPE_BYTE4: return "byte4";
+ case IMAGE_DATA_TYPE_HALF4: return "half4";
+ case IMAGE_DATA_TYPE_FLOAT: return "float";
+ case IMAGE_DATA_TYPE_BYTE: return "byte";
+ case IMAGE_DATA_TYPE_HALF: return "half";
+ case IMAGE_DATA_TYPE_USHORT4: return "ushort4";
+ case IMAGE_DATA_TYPE_USHORT: return "ushort";
+ case IMAGE_DATA_NUM_TYPES:
+ assert(!"System enumerator type, should never be used");
+ return "";
+ }
+ assert(!"Unhandled image data type");
+ return "";
+}
+
+} // namespace
+
ImageManager::ImageManager(const DeviceInfo& info)
{
need_update = true;
@@ -90,12 +129,12 @@ bool ImageManager::set_animation_frame_update(int frame)
device_memory *ImageManager::image_memory(int flat_slot)
{
- ImageDataType type;
- int slot = flattened_slot_to_type_index(flat_slot, &type);
+ ImageDataType type;
+ int slot = flattened_slot_to_type_index(flat_slot, &type);
- Image *img = images[type][slot];
+ Image *img = images[type][slot];
- return img->mem;
+ return img->mem;
}
bool ImageManager::get_image_metadata(int flat_slot,
@@ -133,10 +172,12 @@ bool ImageManager::get_image_metadata(const string& filename,
if(metadata.is_float) {
metadata.is_linear = true;
- metadata.type = (metadata.channels > 1) ? IMAGE_DATA_TYPE_FLOAT4 : IMAGE_DATA_TYPE_FLOAT;
+ metadata.type = (metadata.channels > 1) ? IMAGE_DATA_TYPE_FLOAT4
+ : IMAGE_DATA_TYPE_FLOAT;
}
else {
- metadata.type = (metadata.channels > 1) ? IMAGE_DATA_TYPE_BYTE4 : IMAGE_DATA_TYPE_BYTE;
+ metadata.type = (metadata.channels > 1) ? IMAGE_DATA_TYPE_BYTE4
+ : IMAGE_DATA_TYPE_BYTE;
}
return true;
@@ -148,7 +189,8 @@ bool ImageManager::get_image_metadata(const string& filename,
return false;
}
if(path_is_directory(filename)) {
- VLOG(1) << "File '" << filename << "' is a directory, can't use as image.";
+ VLOG(1) << "File '" << filename
+ << "' is a directory, can't use as image.";
return false;
}
@@ -211,16 +253,20 @@ bool ImageManager::get_image_metadata(const string& filename,
metadata.channels = spec.nchannels;
if(metadata.is_half) {
- metadata.type = (metadata.channels > 1) ? IMAGE_DATA_TYPE_HALF4 : IMAGE_DATA_TYPE_HALF;
+ metadata.type = (metadata.channels > 1) ? IMAGE_DATA_TYPE_HALF4
+ : IMAGE_DATA_TYPE_HALF;
}
else if(metadata.is_float) {
- metadata.type = (metadata.channels > 1) ? IMAGE_DATA_TYPE_FLOAT4 : IMAGE_DATA_TYPE_FLOAT;
+ metadata.type = (metadata.channels > 1) ? IMAGE_DATA_TYPE_FLOAT4
+ : IMAGE_DATA_TYPE_FLOAT;
}
else if(spec.format == TypeDesc::USHORT) {
- metadata.type = (metadata.channels > 1) ? IMAGE_DATA_TYPE_USHORT4 : IMAGE_DATA_TYPE_USHORT;
+ metadata.type = (metadata.channels > 1) ? IMAGE_DATA_TYPE_USHORT4
+ : IMAGE_DATA_TYPE_USHORT;
}
else {
- metadata.type = (metadata.channels > 1) ? IMAGE_DATA_TYPE_BYTE4 : IMAGE_DATA_TYPE_BYTE;
+ metadata.type = (metadata.channels > 1) ? IMAGE_DATA_TYPE_BYTE4
+ : IMAGE_DATA_TYPE_BYTE;
}
in->close();
@@ -229,50 +275,6 @@ bool ImageManager::get_image_metadata(const string& filename,
return true;
}
-int ImageManager::max_flattened_slot(ImageDataType type)
-{
- if(tex_num_images[type] == 0) {
- /* No textures for the type, no slots needs allocation. */
- return 0;
- }
- return type_index_to_flattened_slot(tex_num_images[type], type);
-}
-
-/* The lower three bits of a device texture slot number indicate its type.
- * These functions convert the slot ids from ImageManager "images" ones
- * to device ones and vice verse.
- */
-int ImageManager::type_index_to_flattened_slot(int slot, ImageDataType type)
-{
- return (slot << IMAGE_DATA_TYPE_SHIFT) | (type);
-}
-
-int ImageManager::flattened_slot_to_type_index(int flat_slot, ImageDataType *type)
-{
- *type = (ImageDataType)(flat_slot & IMAGE_DATA_TYPE_MASK);
- return flat_slot >> IMAGE_DATA_TYPE_SHIFT;
-}
-
-string ImageManager::name_from_type(int type)
-{
- if(type == IMAGE_DATA_TYPE_FLOAT4)
- return "float4";
- else if(type == IMAGE_DATA_TYPE_FLOAT)
- return "float";
- else if(type == IMAGE_DATA_TYPE_BYTE)
- return "byte";
- else if(type == IMAGE_DATA_TYPE_HALF4)
- return "half4";
- else if(type == IMAGE_DATA_TYPE_HALF)
- return "half";
- else if(type == IMAGE_DATA_TYPE_USHORT)
- return "ushort";
- else if(type == IMAGE_DATA_TYPE_USHORT4)
- return "ushort4";
- else
- return "byte4";
-}
-
static bool image_equals(ImageManager::Image *image,
const string& filename,
void *builtin_data,
@@ -348,14 +350,16 @@ int ImageManager::add_image(const string& filename,
}
/* Count if we're over the limit.
- * Very unlikely, since max_num_images is insanely big. But better safe than sorry. */
+ * Very unlikely, since max_num_images is insanely big. But better safe
+ * than sorry.
+ */
int tex_count = 0;
for(int type = 0; type < IMAGE_DATA_NUM_TYPES; type++) {
tex_count += tex_num_images[type];
}
if(tex_count > max_num_images) {
- printf("ImageManager::add_image: Reached image limit (%d), skipping '%s'\n",
- max_num_images, filename.c_str());
+ printf("ImageManager::add_image: Reached image limit (%d), "
+ "skipping '%s'\n", max_num_images, filename.c_str());
return -1;
}
@@ -743,7 +747,8 @@ void ImageManager::device_load_image(Device *device,
/* Slot assignment */
int flat_slot = type_index_to_flattened_slot(slot, type);
- img->mem_name = string_printf("__tex_image_%s_%03d", name_from_type(type).c_str(), flat_slot);
+ img->mem_name = string_printf("__tex_image_%s_%03d",
+ name_from_type(type), flat_slot);
/* Free previous texture in slot. */
if(img->mem) {
@@ -1082,4 +1087,15 @@ void ImageManager::device_free(Device *device)
}
}
+void ImageManager::collect_statistics(RenderStats *stats)
+{
+ for(int type = 0; type < IMAGE_DATA_NUM_TYPES; type++) {
+ foreach(const Image *image, images[type]) {
+ stats->image.textures.add_entry(
+ NamedSizeEntry(path_filename(image->filename),
+ image->mem->memory_size()));
+ }
+ }
+}
+
CCL_NAMESPACE_END
diff --git a/intern/cycles/render/image.h b/intern/cycles/render/image.h
index 5039abaa67e..c8996b70b38 100644
--- a/intern/cycles/render/image.h
+++ b/intern/cycles/render/image.h
@@ -29,6 +29,7 @@ CCL_NAMESPACE_BEGIN
class Device;
class Progress;
+class RenderStats;
class Scene;
class ImageMetaData {
@@ -96,6 +97,8 @@ public:
device_memory *image_memory(int flat_slot);
+ void collect_statistics(RenderStats *stats);
+
bool need_update;
/* NOTE: Here pixels_size is a size of storage, which equals to
@@ -159,16 +162,11 @@ private:
int texture_limit,
device_vector<DeviceType>& tex_img);
- int max_flattened_slot(ImageDataType type);
- int type_index_to_flattened_slot(int slot, ImageDataType type);
- int flattened_slot_to_type_index(int flat_slot, ImageDataType *type);
- string name_from_type(int type);
-
void device_load_image(Device *device,
Scene *scene,
ImageDataType type,
int slot,
- Progress *progess);
+ Progress *progress);
void device_free_image(Device *device,
ImageDataType type,
int slot);
diff --git a/intern/cycles/render/mesh.cpp b/intern/cycles/render/mesh.cpp
index 787814dba6b..3b85186948e 100644
--- a/intern/cycles/render/mesh.cpp
+++ b/intern/cycles/render/mesh.cpp
@@ -27,6 +27,7 @@
#include "render/nodes.h"
#include "render/object.h"
#include "render/scene.h"
+#include "render/stats.h"
#include "kernel/osl/osl_globals.h"
@@ -2069,8 +2070,8 @@ void MeshManager::device_update_displacement_images(Device *device,
}
void MeshManager::device_update_volume_images(Device *device,
- Scene *scene,
- Progress& progress)
+ Scene *scene,
+ Progress& progress)
{
progress.set_status("Updating Volume Images");
TaskPool pool;
@@ -2097,11 +2098,11 @@ void MeshManager::device_update_volume_images(Device *device,
foreach(int slot, volume_images) {
pool.push(function_bind(&ImageManager::device_update_slot,
- image_manager,
- device,
- scene,
- slot,
- &progress));
+ image_manager,
+ device,
+ scene,
+ slot,
+ &progress));
}
pool.wait_work();
}
@@ -2330,6 +2331,15 @@ void MeshManager::tag_update(Scene *scene)
scene->object_manager->need_update = true;
}
+void MeshManager::collect_statistics(const Scene *scene, RenderStats *stats)
+{
+ foreach(Mesh *mesh, scene->meshes) {
+ stats->mesh.geometry.add_entry(
+ NamedSizeEntry(string(mesh->name.c_str()),
+ mesh->get_total_size_in_bytes()));
+ }
+}
+
bool Mesh::need_attribute(Scene *scene, AttributeStandard std)
{
if(std == ATTR_STD_NONE)
diff --git a/intern/cycles/render/mesh.h b/intern/cycles/render/mesh.h
index e73291afaa3..0cd3919a49c 100644
--- a/intern/cycles/render/mesh.h
+++ b/intern/cycles/render/mesh.h
@@ -38,6 +38,7 @@ class Device;
class DeviceScene;
class Mesh;
class Progress;
+class RenderStats;
class Scene;
class SceneParams;
class AttributeRequest;
@@ -353,6 +354,8 @@ public:
void create_volume_mesh(Scene *scene, Mesh *mesh, Progress &progress);
+ void collect_statistics(const Scene *scene, RenderStats *stats);
+
protected:
/* Calculate verts/triangles/curves offsets in global arrays. */
void mesh_calc_offset(Scene *scene);
@@ -383,8 +386,8 @@ protected:
Progress& progress);
void device_update_volume_images(Device *device,
- Scene *scene,
- Progress& progress);
+ Scene *scene,
+ Progress& progress);
};
CCL_NAMESPACE_END
diff --git a/intern/cycles/render/scene.cpp b/intern/cycles/render/scene.cpp
index 1d65ef65980..9f93fed139c 100644
--- a/intern/cycles/render/scene.cpp
+++ b/intern/cycles/render/scene.cpp
@@ -379,4 +379,10 @@ void Scene::device_free()
free_memory(false);
}
+void Scene::collect_statistics(RenderStats *stats)
+{
+ mesh_manager->collect_statistics(this, stats);
+ image_manager->collect_statistics(stats);
+}
+
CCL_NAMESPACE_END
diff --git a/intern/cycles/render/scene.h b/intern/cycles/render/scene.h
index c4597c0e455..c107a0b073d 100644
--- a/intern/cycles/render/scene.h
+++ b/intern/cycles/render/scene.h
@@ -56,6 +56,7 @@ class ShaderManager;
class Progress;
class BakeManager;
class BakeData;
+class RenderStats;
/* Scene Device Data */
@@ -257,6 +258,8 @@ public:
void reset();
void device_free();
+ void collect_statistics(RenderStats *stats);
+
protected:
/* Check if some heavy data worth logging was updated.
* Mainly used to suppress extra annoying logging.
diff --git a/intern/cycles/render/stats.cpp b/intern/cycles/render/stats.cpp
new file mode 100644
index 00000000000..101d33fcf65
--- /dev/null
+++ b/intern/cycles/render/stats.cpp
@@ -0,0 +1,119 @@
+/*
+ * Copyright 2011-2018 Blender Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "render/stats.h"
+#include "util/util_algorithm.h"
+#include "util/util_foreach.h"
+#include "util/util_string.h"
+
+CCL_NAMESPACE_BEGIN
+
+static int kIndentNumSpaces = 2;
+
+/* Named size entry. */
+
+namespace {
+
+bool namedSizeEntryComparator(const NamedSizeEntry& a, const NamedSizeEntry& b)
+{
+ /* We sort in descending order. */
+ return a.size > b.size;
+}
+
+} // namespace
+
+NamedSizeEntry::NamedSizeEntry()
+ : name(""),
+ size(0) {
+}
+
+NamedSizeEntry::NamedSizeEntry(const string& name, size_t size)
+ : name(name),
+ size(size) {
+}
+
+/* Named size statistics. */
+
+NamedSizeStats::NamedSizeStats()
+ : total_size(0) {
+}
+
+void NamedSizeStats::add_entry(const NamedSizeEntry& entry) {
+ total_size += entry.size;
+ entries.push_back(entry);
+}
+
+string NamedSizeStats::full_report(int indent_level)
+{
+ const string indent(indent_level * kIndentNumSpaces, ' ');
+ const string double_indent = indent + indent;
+ string result = "";
+ result += string_printf("%sTotal memory: %s (%s)\n",
+ indent.c_str(),
+ string_human_readable_size(total_size).c_str(),
+ string_human_readable_number(total_size).c_str());
+ sort(entries.begin(), entries.end(), namedSizeEntryComparator);
+ foreach(const NamedSizeEntry& entry, entries) {
+ result += string_printf(
+ "%s%-32s %s (%s)\n",
+ double_indent.c_str(),
+ entry.name.c_str(),
+ string_human_readable_size(entry.size).c_str(),
+ string_human_readable_number(entry.size).c_str());
+ }
+ return result;
+}
+
+/* Mesh statistics. */
+
+MeshStats::MeshStats() {
+}
+
+string MeshStats::full_report(int indent_level)
+{
+ const string indent(indent_level * kIndentNumSpaces, ' ');
+ string result = "";
+ result += indent + "Geometry:\n" + geometry.full_report(indent_level + 1);
+ return result;
+}
+
+/* Image statistics. */
+
+ImageStats::ImageStats() {
+}
+
+string ImageStats::full_report(int indent_level)
+{
+ const string indent(indent_level * kIndentNumSpaces, ' ');
+ string result = "";
+ result += indent + "Textures:\n" + textures.full_report(indent_level + 1);
+ return result;
+}
+
+/* Overall statistics. */
+
+RenderStats::RenderStats() {
+}
+
+string RenderStats::full_report()
+{
+ string result = "";
+ result += "Mesh statistics:\n" + mesh.full_report(1);
+ result += "Image statistics:\n" + image.full_report(1);
+ return result;
+}
+
+CCL_NAMESPACE_END
diff --git a/intern/cycles/render/stats.h b/intern/cycles/render/stats.h
new file mode 100644
index 00000000000..72d5f1dd93d
--- /dev/null
+++ b/intern/cycles/render/stats.h
@@ -0,0 +1,104 @@
+/*
+ * Copyright 2011-2018 Blender Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __RENDER_STATS_H__
+#define __RENDER_STATS_H__
+
+#include "util/util_string.h"
+#include "util/util_vector.h"
+
+CCL_NAMESPACE_BEGIN
+
+/* Named statistics entry, which corresponds to a size. There is no real
+ * semantic around the units of size, it just should be the same for all
+ * entries.
+ *
+ * This is a generic entry foi all size-related statistics, which helps
+ * avoiding duplicating code for things like sorting.
+ */
+class NamedSizeEntry {
+public:
+ NamedSizeEntry();
+ NamedSizeEntry(const string& name, size_t size);
+
+ string name;
+ size_t size;
+};
+
+/* Container of named size entries. Used, for example, to store per-mesh memory
+ * usage statistics. But also keeps track of overall memory usage of the
+ * container.
+ */
+class NamedSizeStats {
+public:
+ NamedSizeStats();
+
+ /* Add entry to the statistics. */
+ void add_entry(const NamedSizeEntry& entry);
+
+ /* Generate full human-readable report. */
+ string full_report(int indent_level = 0);
+
+ /* Total size of all entries. */
+ size_t total_size;
+
+ /* NOTE: Is fine to read directly, but for adding use add_entry(), which
+ * makes sure all accumulating values are properly updated.
+ */
+ vector<NamedSizeEntry> entries;
+};
+
+/* Statistics about mesh in the render database. */
+class MeshStats {
+public:
+ MeshStats();
+
+ /* Generate full human-readable report. */
+ string full_report(int indent_level = 0);
+
+ /* Input geometry statistics, this is what is coming as an input to render
+ * from. say, Blender. This does not include runtime or engine specific
+ * memory like BVH.
+ */
+ NamedSizeStats geometry;
+};
+
+/* Statistics about images held in memory. */
+class ImageStats {
+public:
+ ImageStats();
+
+ /* Generate full human-readable report. */
+ string full_report(int indent_level = 0);
+
+ NamedSizeStats textures;
+};
+
+/* Render process statistics. */
+class RenderStats {
+public:
+ RenderStats();
+
+ /* Return full report as string. */
+ string full_report();
+
+ MeshStats mesh;
+ ImageStats image;
+};
+
+CCL_NAMESPACE_END
+
+#endif /* __RENDER_STATS_H__ */
diff --git a/intern/ghost/intern/GHOST_ContextSDL.cpp b/intern/ghost/intern/GHOST_ContextSDL.cpp
index 1ba591bd0b2..3b3cf7a2962 100644
--- a/intern/ghost/intern/GHOST_ContextSDL.cpp
+++ b/intern/ghost/intern/GHOST_ContextSDL.cpp
@@ -55,6 +55,7 @@ GHOST_ContextSDL::GHOST_ContextSDL(
int contextResetNotificationStrategy)
: GHOST_Context(stereoVisual, numOfAASamples),
m_window(window),
+ m_hidden_window(NULL),
m_contextProfileMask(contextProfileMask),
m_contextMajorVersion(contextMajorVersion),
m_contextMinorVersion(contextMinorVersion),
@@ -62,7 +63,7 @@ GHOST_ContextSDL::GHOST_ContextSDL(
m_contextResetNotificationStrategy(contextResetNotificationStrategy),
m_context(NULL)
{
- assert(m_window != NULL);
+ // assert(m_window != NULL);
}
@@ -70,7 +71,7 @@ GHOST_ContextSDL::~GHOST_ContextSDL()
{
if (m_context != NULL) {
if (m_window != NULL && m_context == SDL_GL_GetCurrentContext())
- SDL_GL_MakeCurrent(m_window, m_context);
+ SDL_GL_MakeCurrent(m_window, NULL);
if (m_context != s_sharedContext || s_sharedCount == 1) {
assert(s_sharedCount > 0);
@@ -82,6 +83,9 @@ GHOST_ContextSDL::~GHOST_ContextSDL()
SDL_GL_DeleteContext(m_context);
}
+
+ if (m_hidden_window != NULL)
+ SDL_DestroyWindow(m_hidden_window);
}
}
@@ -160,6 +164,18 @@ GHOST_TSuccess GHOST_ContextSDL::initializeDrawingContext()
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, m_numOfAASamples);
}
+ if (m_window == NULL) {
+ m_hidden_window = SDL_CreateWindow(
+ "Offscreen Context Windows",
+ SDL_WINDOWPOS_UNDEFINED,
+ SDL_WINDOWPOS_UNDEFINED,
+ 1, 1,
+ SDL_WINDOW_OPENGL | SDL_WINDOW_BORDERLESS | SDL_WINDOW_HIDDEN
+ );
+
+ m_window = m_hidden_window;
+ }
+
m_context = SDL_GL_CreateContext(m_window);
GHOST_TSuccess success;
diff --git a/intern/ghost/intern/GHOST_ContextSDL.h b/intern/ghost/intern/GHOST_ContextSDL.h
index 681d24bb7c6..1829819300c 100644
--- a/intern/ghost/intern/GHOST_ContextSDL.h
+++ b/intern/ghost/intern/GHOST_ContextSDL.h
@@ -120,6 +120,7 @@ public:
private:
SDL_Window *m_window;
+ SDL_Window *m_hidden_window;
const int m_contextProfileMask;
const int m_contextMajorVersion;
diff --git a/intern/ghost/intern/GHOST_System.cpp b/intern/ghost/intern/GHOST_System.cpp
index 0629eacc3ff..c3fd87c65af 100644
--- a/intern/ghost/intern/GHOST_System.cpp
+++ b/intern/ghost/intern/GHOST_System.cpp
@@ -297,7 +297,9 @@ GHOST_TSuccess GHOST_System::getButtonState(GHOST_TButtonMask mask, bool& isDown
#ifdef WITH_INPUT_NDOF
void GHOST_System::setNDOFDeadZone(float deadzone)
{
- this->m_ndofManager->setDeadZone(deadzone);
+ if (this->m_ndofManager) {
+ this->m_ndofManager->setDeadZone(deadzone);
+ }
}
#endif
diff --git a/intern/ghost/intern/GHOST_SystemSDL.cpp b/intern/ghost/intern/GHOST_SystemSDL.cpp
index d7860577338..094cbe76cb2 100644
--- a/intern/ghost/intern/GHOST_SystemSDL.cpp
+++ b/intern/ghost/intern/GHOST_SystemSDL.cpp
@@ -26,6 +26,7 @@
#include <assert.h>
+#include "GHOST_ContextSDL.h"
#include "GHOST_SystemSDL.h"
#include "GHOST_WindowSDL.h"
@@ -149,6 +150,34 @@ GHOST_SystemSDL::getNumDisplays() const
return SDL_GetNumVideoDisplays();
}
+GHOST_IContext *
+GHOST_SystemSDL::createOffscreenContext()
+{
+ GHOST_Context *context = new GHOST_ContextSDL(
+ 0,
+ 0,
+ NULL,
+ 0, // profile bit
+ 3, 3,
+ GHOST_OPENGL_SDL_CONTEXT_FLAGS,
+ GHOST_OPENGL_SDL_RESET_NOTIFICATION_STRATEGY);
+
+ if (context->initializeDrawingContext())
+ return context;
+ else
+ delete context;
+
+ return NULL;
+}
+
+GHOST_TSuccess
+GHOST_SystemSDL::disposeContext(GHOST_IContext *context)
+{
+ delete context;
+
+ return GHOST_kSuccess;
+}
+
GHOST_TSuccess
GHOST_SystemSDL::getModifierKeys(GHOST_ModifierKeys& keys) const
{
diff --git a/intern/ghost/intern/GHOST_SystemSDL.h b/intern/ghost/intern/GHOST_SystemSDL.h
index 41f110ed15d..0610a80ea5f 100644
--- a/intern/ghost/intern/GHOST_SystemSDL.h
+++ b/intern/ghost/intern/GHOST_SystemSDL.h
@@ -95,6 +95,12 @@ public:
getMainDisplayDimensions(GHOST_TUns32& width,
GHOST_TUns32& height) const;
+ GHOST_IContext *
+ createOffscreenContext();
+
+ GHOST_TSuccess
+ disposeContext(GHOST_IContext *context);
+
/**
* Informs if the system provides native dialogs (eg. confirm quit)
*/
diff --git a/intern/ghost/intern/GHOST_WindowSDL.cpp b/intern/ghost/intern/GHOST_WindowSDL.cpp
index aeb6188daef..9c41087bd59 100644
--- a/intern/ghost/intern/GHOST_WindowSDL.cpp
+++ b/intern/ghost/intern/GHOST_WindowSDL.cpp
@@ -93,7 +93,7 @@ GHOST_WindowSDL::newDrawingContext(GHOST_TDrawingContextType type)
m_wantNumOfAASamples,
m_sdl_win,
0, // profile bit
- 0, 0,
+ 3, 3,
GHOST_OPENGL_SDL_CONTEXT_FLAGS,
GHOST_OPENGL_SDL_RESET_NOTIFICATION_STRATEGY);
diff --git a/intern/rigidbody/RBI_api.h b/intern/rigidbody/RBI_api.h
index 556ca959e64..eec94bcea50 100644
--- a/intern/rigidbody/RBI_api.h
+++ b/intern/rigidbody/RBI_api.h
@@ -268,6 +268,7 @@ rbConstraint *RB_constraint_new_slider(float pivot[3], float orn[4], rbRigidBody
rbConstraint *RB_constraint_new_piston(float pivot[3], float orn[4], rbRigidBody *rb1, rbRigidBody *rb2);
rbConstraint *RB_constraint_new_6dof(float pivot[3], float orn[4], rbRigidBody *rb1, rbRigidBody *rb2);
rbConstraint *RB_constraint_new_6dof_spring(float pivot[3], float orn[4], rbRigidBody *rb1, rbRigidBody *rb2);
+rbConstraint *RB_constraint_new_6dof_spring2(float pivot[3], float orn[4], rbRigidBody *rb1, rbRigidBody *rb2);
rbConstraint *RB_constraint_new_motor(float pivot[3], float orn[4], rbRigidBody *rb1, rbRigidBody *rb2);
/* ............ */
@@ -299,12 +300,18 @@ void RB_constraint_set_limits_piston(rbConstraint *con, float lin_lower, float l
void RB_constraint_set_limits_6dof(rbConstraint *con, int axis, float lower, float upper);
/* 6dof spring specific */
-void RB_constraint_set_limits_6dof_spring(rbConstraint *con, int axis, float lower, float upper);
void RB_constraint_set_stiffness_6dof_spring(rbConstraint *con, int axis, float stiffness);
void RB_constraint_set_damping_6dof_spring(rbConstraint *con, int axis, float damping);
void RB_constraint_set_spring_6dof_spring(rbConstraint *con, int axis, int enable);
void RB_constraint_set_equilibrium_6dof_spring(rbConstraint *con);
+/* 6dof spring 2 specific */
+void RB_constraint_set_limits_6dof_spring2(rbConstraint *con, int axis, float lower, float upper);
+void RB_constraint_set_stiffness_6dof_spring2(rbConstraint *con, int axis, float stiffness);
+void RB_constraint_set_damping_6dof_spring2(rbConstraint *con, int axis, float damping);
+void RB_constraint_set_spring_6dof_spring2(rbConstraint *con, int axis, int enable);
+void RB_constraint_set_equilibrium_6dof_spring2(rbConstraint *con);
+
/* motors */
void RB_constraint_set_enable_motor(rbConstraint *con, int enable_lin, int enable_ang);
void RB_constraint_set_max_impulse_motor(rbConstraint *con, float max_impulse_lin, float max_impulse_ang);
diff --git a/intern/rigidbody/rb_bullet_api.cpp b/intern/rigidbody/rb_bullet_api.cpp
index a9fbcb28529..6a50c5c93ee 100644
--- a/intern/rigidbody/rb_bullet_api.cpp
+++ b/intern/rigidbody/rb_bullet_api.cpp
@@ -954,11 +954,25 @@ rbConstraint *RB_constraint_new_6dof_spring(float pivot[3], float orn[4], rbRigi
make_constraint_transforms(transform1, transform2, body1, body2, pivot, orn);
- btTypedConstraint *con = new btGeneric6DofSpring2Constraint(*body1, *body2, transform1, transform2);
+ btTypedConstraint *con = new btGeneric6DofSpringConstraint(*body1, *body2, transform1, transform2, true);
return (rbConstraint *)con;
}
+rbConstraint *RB_constraint_new_6dof_spring2(float pivot[3], float orn[4], rbRigidBody *rb1, rbRigidBody *rb2)
+{
+ btRigidBody *body1 = rb1->body;
+ btRigidBody *body2 = rb2->body;
+ btTransform transform1;
+ btTransform transform2;
+
+ make_constraint_transforms(transform1, transform2, body1, body2, pivot, orn);
+
+ btTypedConstraint *con = new btGeneric6DofSpring2Constraint(*body1, *body2, transform1, transform2);
+
+ return (rbConstraint *)con;
+}
+
rbConstraint *RB_constraint_new_motor(float pivot[3], float orn[4], rbRigidBody *rb1, rbRigidBody *rb2)
{
btRigidBody *body1 = rb1->body;
@@ -1034,7 +1048,7 @@ void RB_constraint_set_limits_6dof(rbConstraint *con, int axis, float lower, flo
constraint->setLimit(axis, lower, upper);
}
-void RB_constraint_set_limits_6dof_spring(rbConstraint *con, int axis, float lower, float upper)
+void RB_constraint_set_limits_6dof_spring2(rbConstraint *con, int axis, float lower, float upper)
{
btGeneric6DofSpring2Constraint *constraint = reinterpret_cast<btGeneric6DofSpring2Constraint*>(con);
@@ -1043,27 +1057,58 @@ void RB_constraint_set_limits_6dof_spring(rbConstraint *con, int axis, float low
void RB_constraint_set_stiffness_6dof_spring(rbConstraint *con, int axis, float stiffness)
{
- btGeneric6DofSpring2Constraint *constraint = reinterpret_cast<btGeneric6DofSpring2Constraint*>(con);
+ btGeneric6DofSpringConstraint *constraint = reinterpret_cast<btGeneric6DofSpringConstraint*>(con);
constraint->setStiffness(axis, stiffness);
}
void RB_constraint_set_damping_6dof_spring(rbConstraint *con, int axis, float damping)
{
- btGeneric6DofSpring2Constraint *constraint = reinterpret_cast<btGeneric6DofSpring2Constraint*>(con);
+ btGeneric6DofSpringConstraint *constraint = reinterpret_cast<btGeneric6DofSpringConstraint*>(con);
+
+ // invert damping range so that 0 = no damping
+ damping = (damping > 1.0f) ? 0.0f : 1.0f - damping;
constraint->setDamping(axis, damping);
}
void RB_constraint_set_spring_6dof_spring(rbConstraint *con, int axis, int enable)
{
- btGeneric6DofSpring2Constraint *constraint = reinterpret_cast<btGeneric6DofSpring2Constraint*>(con);
+ btGeneric6DofSpringConstraint *constraint = reinterpret_cast<btGeneric6DofSpringConstraint*>(con);
constraint->enableSpring(axis, enable);
}
void RB_constraint_set_equilibrium_6dof_spring(rbConstraint *con)
{
+ btGeneric6DofSpringConstraint *constraint = reinterpret_cast<btGeneric6DofSpringConstraint*>(con);
+
+ constraint->setEquilibriumPoint();
+}
+
+void RB_constraint_set_stiffness_6dof_spring2(rbConstraint *con, int axis, float stiffness)
+{
+ btGeneric6DofSpring2Constraint *constraint = reinterpret_cast<btGeneric6DofSpring2Constraint*>(con);
+
+ constraint->setStiffness(axis, stiffness);
+}
+
+void RB_constraint_set_damping_6dof_spring2(rbConstraint *con, int axis, float damping)
+{
+ btGeneric6DofSpring2Constraint *constraint = reinterpret_cast<btGeneric6DofSpring2Constraint*>(con);
+
+ constraint->setDamping(axis, damping);
+}
+
+void RB_constraint_set_spring_6dof_spring2(rbConstraint *con, int axis, int enable)
+{
+ btGeneric6DofSpring2Constraint *constraint = reinterpret_cast<btGeneric6DofSpring2Constraint*>(con);
+
+ constraint->enableSpring(axis, enable);
+}
+
+void RB_constraint_set_equilibrium_6dof_spring2(rbConstraint *con)
+{
btGeneric6DofSpring2Constraint *constraint = reinterpret_cast<btGeneric6DofSpring2Constraint*>(con);
constraint->setEquilibriumPoint();
diff --git a/release/scripts/modules/bpy_extras/object_utils.py b/release/scripts/modules/bpy_extras/object_utils.py
index 7719e2f6e30..fff73a4285a 100644
--- a/release/scripts/modules/bpy_extras/object_utils.py
+++ b/release/scripts/modules/bpy_extras/object_utils.py
@@ -166,7 +166,7 @@ def object_data_add(context, obdata, operator=None, name=None):
obj_act.select_set(action='SELECT')
scene.update() # apply location
- # scene.objects.active = obj_new
+ # layer.objects.active = obj_new
# Match up UV layers, this is needed so adding an object with UV's
# doesn't create new layers when there happens to be a naming mis-match.
diff --git a/release/scripts/startup/bl_operators/clip.py b/release/scripts/startup/bl_operators/clip.py
index 2717a4f62a3..a94076ab61b 100644
--- a/release/scripts/startup/bl_operators/clip.py
+++ b/release/scripts/startup/bl_operators/clip.py
@@ -238,7 +238,7 @@ class CLIP_OT_track_to_empty(Operator):
ob = bpy.data.objects.new(name=track.name, object_data=None)
ob.select_set(action='SELECT')
context.scene.objects.link(ob)
- context.scene.objects.active = ob
+ context.view_layer.objects.active = ob
for con in ob.constraints:
if con.type == 'FOLLOW_TRACK':
@@ -314,7 +314,7 @@ class CLIP_OT_bundles_to_mesh(Operator):
ob.matrix_world = matrix
context.scene.objects.link(ob)
ob.select = True
- context.scene.objects.active = ob
+ context.view_layer.objects.active = ob
else:
self.report({'WARNING'}, "No usable tracks selected")
diff --git a/release/scripts/startup/bl_operators/presets.py b/release/scripts/startup/bl_operators/presets.py
index 530194e5bb7..fe09fada297 100644
--- a/release/scripts/startup/bl_operators/presets.py
+++ b/release/scripts/startup/bl_operators/presets.py
@@ -257,7 +257,7 @@ class PresetMenu(Panel):
bl_space_type = 'PROPERTIES'
bl_region_type = 'HEADER'
bl_label = "Presets"
- path_menu: Menu.path_menu
+ path_menu = Menu.path_menu
@classmethod
def draw_panel_header(cls, layout):
diff --git a/release/scripts/startup/bl_operators/rigidbody.py b/release/scripts/startup/bl_operators/rigidbody.py
index 36150a63895..6b76fb96b62 100644
--- a/release/scripts/startup/bl_operators/rigidbody.py
+++ b/release/scripts/startup/bl_operators/rigidbody.py
@@ -60,7 +60,7 @@ class CopyRigidbodySettings(Operator):
def execute(self, context):
obj_act = context.object
- scene = context.scene
+ view_layer = context.view_layer
# deselect all but mesh objects
for o in context.selected_objects:
@@ -68,9 +68,9 @@ class CopyRigidbodySettings(Operator):
o.select_set(action='DESELECT')
elif o.rigid_body is None:
# Add rigidbody to object!
- scene.objects.active = o
+ view_layer.objects.active = o
bpy.ops.rigidbody.object_add()
- scene.objects.active = obj_act
+ view_layer.objects.active = obj_act
objects = context.selected_objects
if objects:
@@ -265,7 +265,7 @@ class ConnectRigidBodies(Operator):
ob = bpy.data.objects.new("Constraint", object_data=None)
ob.location = loc
context.scene.objects.link(ob)
- context.scene.objects.active = ob
+ context.view_layer.objects.active = ob
ob.select_set(action='SELECT')
bpy.ops.rigidbody.constraint_add()
@@ -278,7 +278,7 @@ class ConnectRigidBodies(Operator):
con.object2 = object2
def execute(self, context):
- scene = context.scene
+ view_layer = context.view_layer
objects = context.selected_objects
obj_act = context.active_object
change = False
@@ -312,7 +312,7 @@ class ConnectRigidBodies(Operator):
bpy.ops.object.select_all(action='DESELECT')
for obj in objects:
obj.select_set(action='SELECT')
- scene.objects.active = obj_act
+ view_layer.objects.active = obj_act
return {'FINISHED'}
else:
self.report({'WARNING'}, "No other objects selected")
diff --git a/release/scripts/startup/bl_operators/uvcalc_lightmap.py b/release/scripts/startup/bl_operators/uvcalc_lightmap.py
index 95a3d18304b..b866fb1ce40 100644
--- a/release/scripts/startup/bl_operators/uvcalc_lightmap.py
+++ b/release/scripts/startup/bl_operators/uvcalc_lightmap.py
@@ -579,7 +579,7 @@ def unwrap(operator, context, **kwargs):
# define list of meshes
meshes = []
if PREF_ACT_ONLY:
- obj = context.scene.objects.active
+ obj = context.view_layer.objects.active
if obj and obj.type == 'MESH':
meshes = [obj.data]
else:
diff --git a/release/scripts/startup/bl_ui/properties_data_camera.py b/release/scripts/startup/bl_ui/properties_data_camera.py
index f66419a7f8e..cc0bde46189 100644
--- a/release/scripts/startup/bl_ui/properties_data_camera.py
+++ b/release/scripts/startup/bl_ui/properties_data_camera.py
@@ -88,7 +88,7 @@ class DATA_PT_lens(CameraButtonsPanel, Panel):
if cam.lens_unit == 'MILLIMETERS':
col.prop(cam, "lens")
elif cam.lens_unit == 'FOV':
- row.prop(cam, "angle")
+ col.prop(cam, "angle")
col.prop(cam, "lens_unit")
elif cam.type == 'ORTHO':
@@ -250,15 +250,10 @@ class DATA_PT_camera_dof_aperture(CameraButtonsPanel, Panel):
col.prop(dof_options, "rotation")
col.prop(dof_options, "ratio")
else:
- hq_support = dof_options.is_hq_supported
col = flow.column()
col.label("Viewport")
- sub = col.column()
- sub.active = hq_support
- sub.prop(dof_options, "use_high_quality")
col.prop(dof_options, "fstop")
- if dof_options.use_high_quality and hq_support:
- col.prop(dof_options, "blades")
+ col.prop(dof_options, "blades")
class DATA_PT_camera_background_image(CameraButtonsPanel, Panel):
diff --git a/release/scripts/startup/bl_ui/properties_data_mesh.py b/release/scripts/startup/bl_ui/properties_data_mesh.py
index 214852cc826..f096ff83957 100644
--- a/release/scripts/startup/bl_ui/properties_data_mesh.py
+++ b/release/scripts/startup/bl_ui/properties_data_mesh.py
@@ -152,6 +152,7 @@ class DATA_PT_context_mesh(MeshButtonsPanel, Panel):
class DATA_PT_normals(MeshButtonsPanel, Panel):
bl_label = "Normals"
+ bl_options = {'DEFAULT_CLOSED'}
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'}
def draw(self, context):
@@ -239,6 +240,7 @@ class DATA_PT_vertex_groups(MeshButtonsPanel, Panel):
class DATA_PT_face_maps(MeshButtonsPanel, Panel):
bl_label = "Face Maps"
+ bl_options = {'DEFAULT_CLOSED'}
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'}
@classmethod
@@ -450,13 +452,13 @@ classes = (
MESH_UL_shape_keys,
MESH_UL_uvmaps_vcols,
DATA_PT_context_mesh,
- DATA_PT_normals,
- DATA_PT_texture_space,
DATA_PT_vertex_groups,
- DATA_PT_face_maps,
DATA_PT_shape_keys,
DATA_PT_uv_texture,
DATA_PT_vertex_colors,
+ DATA_PT_face_maps,
+ DATA_PT_normals,
+ DATA_PT_texture_space,
DATA_PT_customdata,
DATA_PT_custom_props_mesh,
)
diff --git a/release/scripts/startup/bl_ui/properties_grease_pencil_common.py b/release/scripts/startup/bl_ui/properties_grease_pencil_common.py
index a2ccfb4f1b8..55b798d103a 100644
--- a/release/scripts/startup/bl_ui/properties_grease_pencil_common.py
+++ b/release/scripts/startup/bl_ui/properties_grease_pencil_common.py
@@ -728,7 +728,7 @@ class GPENCIL_MT_snap(Menu):
layout.operator("gpencil.snap_to_grid", text="Selection to Grid")
layout.operator("gpencil.snap_to_cursor", text="Selection to Cursor").use_offset = False
- layout.operator("gpencil.snap_to_cursor", text="Selection to Cursor (Offset)").use_offset = True
+ layout.operator("gpencil.snap_to_cursor", text="Selection to Cursor (Keep Offset)").use_offset = True
layout.separator()
diff --git a/release/scripts/startup/bl_ui/properties_particle.py b/release/scripts/startup/bl_ui/properties_particle.py
index 9d891a07989..75b2d76d9c4 100644
--- a/release/scripts/startup/bl_ui/properties_particle.py
+++ b/release/scripts/startup/bl_ui/properties_particle.py
@@ -662,164 +662,336 @@ class PARTICLE_PT_physics(ParticleButtonsPanel, Panel):
if part.physics_type == 'FLUID':
fluid = part.fluid
- col.label(text="Fluid")
+ col.separator()
col.prop(fluid, "solver")
col.prop(fluid, "stiffness", text="Stiffness")
col.prop(fluid, "linear_viscosity", text="Viscosity")
col.prop(fluid, "buoyancy", text="Buoyancy", slider=True)
- col.label(text="Advanced")
+ elif part.physics_type == 'KEYED':
+
+ sub = col.column()
+ sub.active = not psys.use_keyed_timing
+ sub.prop(part, "keyed_loops", text="Loops")
+ if psys:
+ col.prop(psys, "use_keyed_timing", text="Use Timing")
+
+ col.label(text="Keys")
+
+
+class PARTICLE_PT_physics_fluid_advanced(ParticleButtonsPanel, Panel):
+ bl_label = "Advanced"
+ bl_parent_id = "PARTICLE_PT_physics"
+ bl_options = {'DEFAULT_CLOSED'}
+ COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'}
- if fluid.solver == 'DDR':
- sub = col.column()
- sub.prop(fluid, "repulsion", slider=fluid.factor_repulsion)
- sub.prop(fluid, "factor_repulsion")
+ @classmethod
+ def poll(cls, context):
+ part = particle_get_settings(context)
+ fluid = part.fluid
+ if part.physics_type == 'FLUID':
+ return True
+ else:
+ return False
- sub.prop(fluid, "stiff_viscosity", slider=fluid.factor_stiff_viscosity)
- sub.prop(fluid, "factor_stiff_viscosity")
+ def draw(self, context):
+ layout = self.layout
+ layout.use_property_split = True
+ psys = context.particle_system
+ part = particle_get_settings(context)
+ fluid = part.fluid
+
+ col = layout.column()
+
+ if fluid.solver == 'DDR':
sub = col.column()
- sub.prop(fluid, "fluid_radius", slider=fluid.factor_radius)
- sub.prop(fluid, "factor_radius")
+ sub.prop(fluid, "repulsion", slider=fluid.factor_repulsion)
+ sub.prop(fluid, "factor_repulsion")
- sub.prop(fluid, "rest_density", slider=fluid.use_factor_density)
- sub.prop(fluid, "use_factor_density")
+ sub.prop(fluid, "stiff_viscosity", slider=fluid.factor_stiff_viscosity)
+ sub.prop(fluid, "factor_stiff_viscosity")
- if fluid.solver == 'CLASSICAL':
- # With the classical solver, it is possible to calculate the
- # spacing between particles when the fluid is at rest. This
- # makes it easier to set stable initial conditions.
- particle_volume = part.mass / fluid.rest_density
- spacing = pow(particle_volume, 1.0 / 3.0)
+ sub = col.column()
+ sub.prop(fluid, "fluid_radius", slider=fluid.factor_radius)
+ sub.prop(fluid, "factor_radius")
- sub.label(text="Spacing: %g" % spacing)
+ sub.prop(fluid, "rest_density", slider=fluid.use_factor_density)
+ sub.prop(fluid, "use_factor_density")
- elif fluid.solver == 'DDR':
+ if fluid.solver == 'CLASSICAL':
+ # With the classical solver, it is possible to calculate the
+ # spacing between particles when the fluid is at rest. This
+ # makes it easier to set stable initial conditions.
+ particle_volume = part.mass / fluid.rest_density
+ spacing = pow(particle_volume, 1.0 / 3.0)
- col.label(text="Springs")
- col.prop(fluid, "spring_force", text="Force")
- col.prop(fluid, "use_viscoelastic_springs")
+ sub.label(text="Spacing: %g" % spacing)
- sub = col.column()
- sub.active = fluid.use_viscoelastic_springs
- sub.prop(fluid, "yield_ratio", slider=True)
- sub.prop(fluid, "plasticity", slider=True)
- col.label(text="Advanced")
- sub = col.column()
- sub.prop(fluid, "rest_length", slider=fluid.factor_rest_length)
- sub.prop(fluid, "factor_rest_length", text="")
+class PARTICLE_PT_physics_fluid_springs(ParticleButtonsPanel, Panel):
+ bl_label = "Springs"
+ bl_parent_id = "PARTICLE_PT_physics"
+ bl_options = {'DEFAULT_CLOSED'}
+ COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'}
- sub = col.column()
- sub.active = fluid.use_viscoelastic_springs
- sub.prop(fluid, "use_initial_rest_length")
- sub.prop(fluid, "spring_frames", text="Frames")
+ @classmethod
+ def poll(cls, context):
+ part = particle_get_settings(context)
+ fluid = part.fluid
+ if part.physics_type == 'FLUID' and fluid.solver == 'DDR':
+ return True
+ else:
+ return False
- elif part.physics_type == 'KEYED':
+ def draw(self, context):
+ layout = self.layout
+ layout.use_property_split = True
- sub = col.column()
- sub.active = not psys.use_keyed_timing
- sub.prop(part, "keyed_loops", text="Loops")
- if psys:
- col.prop(psys, "use_keyed_timing", text="Use Timing")
+ psys = context.particle_system
+ part = particle_get_settings(context)
+ fluid = part.fluid
- col.label(text="Keys")
+ col = layout.column()
- elif part.physics_type == 'BOIDS':
- boids = part.boids
+ col.prop(fluid, "spring_force", text="Force")
- row = layout.row()
- row.prop(boids, "use_flight")
- row.prop(boids, "use_land")
- row.prop(boids, "use_climb")
-
- split = layout.split()
-
- col = split.column(align=True)
- col.active = boids.use_flight
- col.prop(boids, "air_speed_max")
- col.prop(boids, "air_speed_min", slider=True)
- col.prop(boids, "air_acc_max", slider=True)
- col.prop(boids, "air_ave_max", slider=True)
- col.prop(boids, "air_personal_space")
- row = col.row(align=True)
- row.active = (boids.use_land or boids.use_climb) and boids.use_flight
- row.prop(boids, "land_smooth")
-
- col = split.column(align=True)
- col.active = boids.use_land or boids.use_climb
- col.prop(boids, "land_speed_max")
- col.prop(boids, "land_jump_speed")
- col.prop(boids, "land_acc_max", slider=True)
- col.prop(boids, "land_ave_max", slider=True)
- col.prop(boids, "land_personal_space")
- col.prop(boids, "land_stick_force")
-
- layout.prop(part, "collision_group")
-
- split = layout.split()
-
- col = split.column(align=True)
- col.label(text="Battle:")
- col.prop(boids, "health")
- col.prop(boids, "strength")
- col.prop(boids, "aggression")
- col.prop(boids, "accuracy")
- col.prop(boids, "range")
- col = split.column()
- col.label(text="Misc:")
- col.prop(boids, "bank", slider=True)
- col.prop(boids, "pitch", slider=True)
- col.prop(boids, "height", slider=True)
-
- if psys and part.physics_type in {'KEYED', 'BOIDS', 'FLUID'}:
- if part.physics_type == 'BOIDS':
- layout.label(text="Relations:")
+class PARTICLE_PT_physics_fluid_springs_viscoelastic(ParticleButtonsPanel, Panel):
+ bl_label = "Viscoelastic Springs"
+ bl_parent_id = "PARTICLE_PT_physics_fluid_springs"
+ bl_options = {'DEFAULT_CLOSED'}
+ COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'}
+
+ @classmethod
+ def poll(cls, context):
+ part = particle_get_settings(context)
+ fluid = part.fluid
+ if part.physics_type == 'FLUID' and fluid.solver == 'DDR':
+ return True
+ else:
+ return False
+
+ def draw_header(self, context):
+ psys = context.particle_system
+ part = particle_get_settings(context)
+ fluid = part.fluid
+
+ self.layout.prop(fluid, "use_viscoelastic_springs", text="")
+
+ def draw(self, context):
+ layout = self.layout
+ layout.use_property_split = True
+
+ psys = context.particle_system
+ part = particle_get_settings(context)
+ fluid = part.fluid
+
+ col = layout.column()
+ col.active = fluid.use_viscoelastic_springs
+ col.prop(fluid, "yield_ratio", slider=True)
+ col.prop(fluid, "plasticity", slider=True)
+
+ col.separator()
+
+ col.prop(fluid, "use_initial_rest_length")
+ col.prop(fluid, "spring_frames", text="Frames")
+
+
+class PARTICLE_PT_physics_fluid_springs_advanced(ParticleButtonsPanel, Panel):
+ bl_label = "Advanced"
+ bl_parent_id = "PARTICLE_PT_physics_fluid_springs"
+ bl_options = {'DEFAULT_CLOSED'}
+ COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'}
+
+ @classmethod
+ def poll(cls, context):
+ part = particle_get_settings(context)
+ fluid = part.fluid
+ if part.physics_type == 'FLUID' and fluid.solver == 'DDR':
+ return True
+ else:
+ return False
+
+ def draw(self, context):
+ layout = self.layout
+ layout.use_property_split = True
+
+ psys = context.particle_system
+ part = particle_get_settings(context)
+ fluid = part.fluid
+
+ sub = layout.column()
+ sub.prop(fluid, "rest_length", slider=fluid.factor_rest_length)
+ sub.prop(fluid, "factor_rest_length")
+
+
+class PARTICLE_PT_physics_boids_movement(ParticleButtonsPanel, Panel):
+ bl_label = "Movement"
+ bl_parent_id = "PARTICLE_PT_physics"
+ bl_options = {'DEFAULT_CLOSED'}
+ COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'}
+
+ @classmethod
+ def poll(cls, context):
+ part = particle_get_settings(context)
+ return part.physics_type in {'BOIDS'}
+
+ def draw(self, context):
+ layout = self.layout
+ layout.use_property_split = True
+
+ psys = context.particle_system
+ part = particle_get_settings(context)
+ boids = part.boids
+
+ col=layout.column()
+
+ col.prop(boids, "use_flight")
+ col.prop(boids, "use_land")
+ col.prop(boids, "use_climb")
+
+ col=layout.column()
+
+ col.active = boids.use_flight
+ sub = col.column()
+ sub.prop(boids, "air_speed_max")
+ sub.prop(boids, "air_speed_min", slider=True)
+ col.prop(boids, "air_acc_max", slider=True)
+ col.prop(boids, "air_ave_max", slider=True)
+ col.prop(boids, "air_personal_space")
+ row = col.row(align=True)
+ row.active = (boids.use_land or boids.use_climb) and boids.use_flight
+ row.prop(boids, "land_smooth")
+
+ layout.separator()
+
+ col=layout.column()
+ col.active = boids.use_land or boids.use_climb
+ col.prop(boids, "land_speed_max")
+ col.prop(boids, "land_jump_speed")
+ col.prop(boids, "land_acc_max", slider=True)
+ col.prop(boids, "land_ave_max", slider=True)
+ col.prop(boids, "land_personal_space")
+ col.prop(boids, "land_stick_force")
+
+ layout.separator()
+
+ layout.prop(part, "collision_group")
+
+class PARTICLE_PT_physics_boids_battle(ParticleButtonsPanel, Panel):
+ bl_label = "Battle"
+ bl_parent_id = "PARTICLE_PT_physics"
+ bl_options = {'DEFAULT_CLOSED'}
+ COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'}
+
+ @classmethod
+ def poll(cls, context):
+ part = particle_get_settings(context)
+ return part.physics_type in {'BOIDS'}
+
+ def draw(self, context):
+ layout = self.layout
+ layout.use_property_split = True
+
+ psys = context.particle_system
+ part = particle_get_settings(context)
+ boids = part.boids
+
+ col=layout.column()
+
+ col.prop(boids, "health")
+ col.prop(boids, "strength")
+ col.prop(boids, "aggression")
+ col.prop(boids, "accuracy")
+ col.prop(boids, "range")
+
+class PARTICLE_PT_physics_boids_misc(ParticleButtonsPanel, Panel):
+ bl_label = "Misc"
+ bl_parent_id = "PARTICLE_PT_physics"
+ bl_options = {'DEFAULT_CLOSED'}
+ COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'}
+
+ @classmethod
+ def poll(cls, context):
+ part = particle_get_settings(context)
+ return part.physics_type in {'BOIDS'}
+
+ def draw(self, context):
+ layout = self.layout
+ layout.use_property_split = True
+
+ psys = context.particle_system
+ part = particle_get_settings(context)
+ boids = part.boids
+
+ col=layout.column()
+
+ col.prop(boids, "bank", slider=True)
+ col.prop(boids, "pitch", slider=True)
+ col.prop(boids, "height", slider=True)
+
+
+class PARTICLE_PT_physics_relations(ParticleButtonsPanel, Panel):
+ bl_label = "Relations"
+ bl_parent_id = "PARTICLE_PT_physics"
+ bl_options = {'DEFAULT_CLOSED'}
+ COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'}
+
+ @classmethod
+ def poll(cls, context):
+ part = particle_get_settings(context)
+ return part.physics_type in {'KEYED', 'BOIDS', 'FLUID'}
+
+ def draw(self, context):
+ layout = self.layout
+ layout.use_property_split = True
+
+ psys = context.particle_system
+ part = particle_get_settings(context)
+
+
+ row = layout.row()
+ row.template_list("UI_UL_list", "particle_targets", psys, "targets",
+ psys, "active_particle_target_index", rows=4)
+
+ col = row.column()
+ sub = col.row()
+ subsub = sub.column(align=True)
+ subsub.operator("particle.new_target", icon='ZOOMIN', text="")
+ subsub.operator("particle.target_remove", icon='ZOOMOUT', text="")
+ sub = col.row()
+ subsub = sub.column(align=True)
+ subsub.operator("particle.target_move_up", icon='TRIA_UP', text="")
+ subsub.operator("particle.target_move_down", icon='TRIA_DOWN', text="")
+
+ key = psys.active_particle_target
+
+ if key:
+ if part.physics_type == 'KEYED':
+ col = layout.column()
+ # doesn't work yet
+ #col.alert = key.valid
+ col.prop(key, "object")
+ col.prop(key, "system", text="System")
+
+ col.active = psys.use_keyed_timing
+ col.prop(key, "time")
+ col.prop(key, "duration")
+ elif part.physics_type == 'BOIDS':
+ sub = layout.column()
+ # doesn't work yet
+ #sub.alert = key.valid
+ sub.prop(key, "object")
+ sub.prop(key, "system", text="System")
+ layout.prop(key, "alliance")
elif part.physics_type == 'FLUID':
- layout.label(text="Fluid Interaction:")
+ sub = layout.column()
+ # doesn't work yet
+ #sub.alert = key.valid
+ sub.prop(key, "object")
+ sub.prop(key, "system", text="System")
- row = layout.row()
- row.template_list("UI_UL_list", "particle_targets", psys, "targets",
- psys, "active_particle_target_index", rows=4)
-
- col = row.column()
- sub = col.row()
- subsub = sub.column(align=True)
- subsub.operator("particle.new_target", icon='ZOOMIN', text="")
- subsub.operator("particle.target_remove", icon='ZOOMOUT', text="")
- sub = col.row()
- subsub = sub.column(align=True)
- subsub.operator("particle.target_move_up", icon='TRIA_UP', text="")
- subsub.operator("particle.target_move_down", icon='TRIA_DOWN', text="")
-
- key = psys.active_particle_target
- if key:
- row = layout.row()
- if part.physics_type == 'KEYED':
- col = row.column()
- # doesn't work yet
- #col.alert = key.valid
- col.prop(key, "object", text="")
- col.prop(key, "system", text="System")
- col = row.column()
- col.active = psys.use_keyed_timing
- col.prop(key, "time")
- col.prop(key, "duration")
- elif part.physics_type == 'BOIDS':
- sub = row.row()
- # doesn't work yet
- #sub.alert = key.valid
- sub.prop(key, "object", text="")
- sub.prop(key, "system", text="System")
-
- layout.row().prop(key, "alliance", expand=True)
- elif part.physics_type == 'FLUID':
- sub = row.row()
- # doesn't work yet
- #sub.alert = key.valid
- sub.prop(key, "object", text="")
- sub.prop(key, "system", text="System")
class PARTICLE_PT_physics_deflection(ParticleButtonsPanel, Panel):
@@ -911,6 +1083,9 @@ class PARTICLE_PT_physics_integration(ParticleButtonsPanel, Panel):
class PARTICLE_PT_boidbrain(ParticleButtonsPanel, Panel):
bl_label = "Boid Brain"
+ bl_options = {'DEFAULT_CLOSED'}
+ bl_parent_id = "PARTICLE_PT_physics"
+
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'}
@classmethod
@@ -1941,9 +2116,17 @@ classes = (
PARTICLE_PT_rotation,
PARTICLE_PT_rotation_angular_velocity,
PARTICLE_PT_physics,
+ PARTICLE_PT_physics_fluid_springs,
+ PARTICLE_PT_physics_fluid_springs_viscoelastic,
+ PARTICLE_PT_physics_fluid_springs_advanced,
+ PARTICLE_PT_physics_fluid_advanced,
+ PARTICLE_PT_physics_boids_movement,
+ PARTICLE_PT_physics_boids_battle,
+ PARTICLE_PT_physics_boids_misc,
PARTICLE_PT_physics_forces,
PARTICLE_PT_physics_deflection,
PARTICLE_PT_physics_integration,
+ PARTICLE_PT_physics_relations,
PARTICLE_PT_boidbrain,
PARTICLE_PT_render,
PARTICLE_PT_render_line,
diff --git a/release/scripts/startup/bl_ui/properties_physics_cloth.py b/release/scripts/startup/bl_ui/properties_physics_cloth.py
index 7775722784b..0a7318864a3 100644
--- a/release/scripts/startup/bl_ui/properties_physics_cloth.py
+++ b/release/scripts/startup/bl_ui/properties_physics_cloth.py
@@ -17,8 +17,11 @@
# ##### END GPL LICENSE BLOCK #####
# <pep8 compliant>
+
import bpy
-from bpy.types import Menu, Panel
+from bpy.types import (
+ Panel,
+)
from bl_operators.presets import PresetMenu
from .properties_physics_common import (
@@ -58,6 +61,7 @@ class PHYSICS_PT_cloth(PhysicButtonsPanel, Panel):
def draw(self, context):
layout = self.layout
+ layout.use_property_split = True
md = context.cloth
ob = context.object
@@ -65,64 +69,82 @@ class PHYSICS_PT_cloth(PhysicButtonsPanel, Panel):
layout.active = cloth_panel_enabled(md)
- split = layout.split(percentage=0.25)
-
- split.label(text="Quality:")
- split.prop(cloth, "quality", text="Steps")
-
- split = layout.split(percentage=0.25)
+ flow = layout.grid_flow(row_major=False, columns=0, even_columns=True, even_rows=False, align=True)
- split.label(text="Speed:")
- split.prop(cloth, "time_scale", text="Multiplier")
+ col = flow.column()
+ col.prop(cloth, "quality", text="Quality Steps")
+ col.prop(cloth, "time_scale", text="Speed Multiplier")
- split = layout.split()
+ col.separator()
- col = split.column()
-
- col.label(text="Material:")
- col.prop(cloth, "mass")
+ col = flow.column()
+ col.prop(cloth, "mass", text="Material Mass")
col.prop(cloth, "structural_stiffness", text="Structural")
col.prop(cloth, "bending_stiffness", text="Bending")
- col = split.column()
+ col.separator()
- col.label(text="Damping:")
- col.prop(cloth, "spring_damping", text="Spring")
+ col = flow.column()
+ col.prop(cloth, "spring_damping", text="Damping Spring")
col.prop(cloth, "air_damping", text="Air")
col.prop(cloth, "vel_damping", text="Velocity")
- split = layout.split()
+ col = flow.column()
+ col.prop(cloth, "use_dynamic_mesh", text="Dynamic Mesh")
- col = split.column()
+ key = ob.data.shape_keys
- col.prop(cloth, "use_pin_cloth", text="Pinning:")
- sub = col.column()
- sub.active = cloth.use_pin_cloth
- sub.prop_search(cloth, "vertex_group_mass", ob, "vertex_groups", text="")
- sub.prop(cloth, "pin_stiffness", text="Stiffness")
+ if key:
+ # Note: TODO prop_search doesn't align on the right.
+ row = col.row(align=True)
+ row.active = not cloth.use_dynamic_mesh
+ row.prop_search(cloth, "rest_shape_key", key, "key_blocks", text="Rest Shape Key")
+ row.label(text="", icon='BLANK1')
- # Disabled for now
- """
- if cloth.vertex_group_mass:
- layout.label(text="Goal:")
- col = layout.column_flow()
- col.prop(cloth, "goal_default", text="Default")
- col.prop(cloth, "goal_spring", text="Stiffness")
- col.prop(cloth, "goal_friction", text="Friction")
- """
+class PHYSICS_PT_cloth_pinning(PhysicButtonsPanel, Panel):
+ bl_label = "Pinning"
+ bl_parent_id = 'PHYSICS_PT_cloth'
+ bl_options = {'DEFAULT_CLOSED'}
+ COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'}
- col = split.column()
+ def draw_header(self, context):
+ md = context.cloth
+ cloth = md.settings
- col.prop(cloth, "use_dynamic_mesh", text="Dynamic Mesh")
+ self.layout.active = cloth_panel_enabled(md) and cloth.use_pin_cloth
+ self.layout.prop(cloth, "use_pin_cloth", text="")
- key = ob.data.shape_keys
+ def draw(self, context):
+ layout = self.layout
+ layout.use_property_split = True
- if key:
- sub = col.column()
- sub.active = not cloth.use_dynamic_mesh
- sub.label(text="Rest Shape Key:")
- sub.prop_search(cloth, "rest_shape_key", key, "key_blocks", text="")
+ md = context.cloth
+ ob = context.object
+ cloth = md.settings
+
+ layout.active = cloth_panel_enabled(md) and cloth.use_pin_cloth
+
+ flow = layout.grid_flow(row_major=False, columns=0, even_columns=True, even_rows=False, align=True)
+
+ col = flow.column()
+
+ # Note: TODO prop_search doesn't align on the right.
+ row = col.row(align=True)
+ row.prop_search(cloth, "vertex_group_mass", ob, "vertex_groups", text="Mass Group")
+ row.label(text="", icon='BLANK1')
+
+ col = flow.column()
+ col.prop(cloth, "pin_stiffness", text="Stiffness")
+
+ # Disabled for now.
+ """
+ if cloth.vertex_group_mass:
+ col = flow.column()
+ col.prop(cloth, "goal_default", text="Goal Default")
+ col.prop(cloth, "goal_spring", text="Stiffness")
+ col.prop(cloth, "goal_friction", text="Friction")
+ """
class PHYSICS_PT_cloth_cache(PhysicButtonsPanel, Panel):
@@ -150,31 +172,59 @@ class PHYSICS_PT_cloth_collision(PhysicButtonsPanel, Panel):
def draw(self, context):
layout = self.layout
+ layout.use_property_split = True
cloth = context.cloth.collision_settings
md = context.cloth
- ob = context.object
layout.active = cloth.use_collision and cloth_panel_enabled(md)
- split = layout.split()
+ flow = layout.grid_flow(row_major=False, columns=0, even_columns=True, even_rows=False, align=True)
- col = split.column()
+ col = flow.column()
col.prop(cloth, "collision_quality", text="Quality")
col.prop(cloth, "distance_min", slider=True, text="Distance")
col.prop(cloth, "repel_force", slider=True, text="Repel")
+
+ col = flow.column()
col.prop(cloth, "distance_repel", slider=True, text="Repel Distance")
col.prop(cloth, "friction")
+ col.prop(cloth, "group")
- col = split.column()
- col.prop(cloth, "use_self_collision", text="Self Collision")
- sub = col.column()
- sub.active = cloth.use_self_collision
- sub.prop(cloth, "self_collision_quality", text="Quality")
- sub.prop(cloth, "self_distance_min", slider=True, text="Distance")
- sub.prop_search(cloth, "vertex_group_self_collisions", ob, "vertex_groups", text="")
- layout.prop(cloth, "group")
+class PHYSICS_PT_cloth_self_collision(PhysicButtonsPanel, Panel):
+ bl_label = "Self Collision"
+ bl_parent_id = 'PHYSICS_PT_cloth_collision'
+ bl_options = {'DEFAULT_CLOSED'}
+ COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'}
+
+ def draw_header(self, context):
+ cloth = context.cloth.collision_settings
+
+ self.layout.active = cloth_panel_enabled(context.cloth) and cloth.use_self_collision
+ self.layout.prop(cloth, "use_self_collision", text="")
+
+ def draw(self, context):
+ layout = self.layout
+ layout.use_property_split = True
+
+ cloth = context.cloth.collision_settings
+ md = context.cloth
+ ob = context.object
+
+ layout.active = cloth.use_collision and cloth_panel_enabled(md) and cloth.use_self_collision
+
+ flow = layout.grid_flow(row_major=False, columns=0, even_columns=True, even_rows=False, align=True)
+
+ col = flow.column()
+ col.prop(cloth, "self_collision_quality", text="Quality")
+ col.prop(cloth, "self_distance_min", slider=True, text="Distance")
+
+ col = flow.column()
+ # Note: TODO prop_search doesn't align on the right.
+ row = col.row(align=True)
+ row.prop_search(cloth, "vertex_group_self_collisions", ob, "vertex_groups", text="Vertex Group")
+ row.label(text="", icon='BLANK1')
class PHYSICS_PT_cloth_stiffness(PhysicButtonsPanel, Panel):
@@ -191,6 +241,7 @@ class PHYSICS_PT_cloth_stiffness(PhysicButtonsPanel, Panel):
def draw(self, context):
layout = self.layout
+ layout.use_property_split = True
md = context.cloth
ob = context.object
@@ -198,16 +249,27 @@ class PHYSICS_PT_cloth_stiffness(PhysicButtonsPanel, Panel):
layout.active = (cloth.use_stiffness_scale and cloth_panel_enabled(md))
- split = layout.split()
+ flow = layout.grid_flow(row_major=True, columns=0, even_columns=True, even_rows=False, align=True)
- col = split.column()
- col.label(text="Structural Stiffness:")
- col.prop_search(cloth, "vertex_group_structural_stiffness", ob, "vertex_groups", text="")
+ col = flow.column()
+ # Note: TODO prop_search doesn't align on the right.
+ row = col.row(align=True)
+ row.prop_search(
+ cloth, "vertex_group_structural_stiffness", ob, "vertex_groups",
+ text="Structural Group"
+ )
+ row.label(text="", icon='BLANK1')
col.prop(cloth, "structural_stiffness_max", text="Max")
- col = split.column()
- col.label(text="Bending Stiffness:")
- col.prop_search(cloth, "vertex_group_bending", ob, "vertex_groups", text="")
+ col.separator()
+
+ col = flow.column()
+ row = col.row(align=True)
+ row.prop_search(
+ cloth, "vertex_group_bending", ob, "vertex_groups",
+ text="Bending Group"
+ )
+ row.label(text="", icon='BLANK1')
col.prop(cloth, "bending_stiffness_max", text="Max")
@@ -225,23 +287,27 @@ class PHYSICS_PT_cloth_sewing(PhysicButtonsPanel, Panel):
def draw(self, context):
layout = self.layout
+ layout.use_property_split = True
md = context.cloth
ob = context.object
cloth = context.cloth.settings
layout.active = (cloth.use_sewing_springs and cloth_panel_enabled(md))
+ flow = layout.grid_flow(row_major=True, columns=0, even_columns=True, even_rows=False, align=True)
- layout.prop(cloth, "sewing_force_max", text="Sewing Force")
+ col = flow.column()
+ col.prop(cloth, "sewing_force_max", text="Sewing Force")
- split = layout.split()
+ col.separator()
- col = split.column(align=True)
- col.label(text="Shrinking:")
- col.prop_search(cloth, "vertex_group_shrink", ob, "vertex_groups", text="")
+ col = col.column()
+ # Note: TODO prop_search doesn't align on the right.
+ row = col.row(align=True)
+ row.prop_search(cloth, "vertex_group_shrink", ob, "vertex_groups", text="Shrinking Group")
+ row.label(text="", icon='BLANK1')
- col = split.column(align=True)
- col.label()
+ col = flow.column(align=True)
col.prop(cloth, "shrink_min", text="Min")
col.prop(cloth, "shrink_max", text="Max")
@@ -262,6 +328,8 @@ classes = (
PHYSICS_PT_cloth,
PHYSICS_PT_cloth_cache,
PHYSICS_PT_cloth_collision,
+ PHYSICS_PT_cloth_self_collision,
+ PHYSICS_PT_cloth_pinning,
PHYSICS_PT_cloth_stiffness,
PHYSICS_PT_cloth_sewing,
PHYSICS_PT_cloth_field_weights,
diff --git a/release/scripts/startup/bl_ui/properties_physics_dynamicpaint.py b/release/scripts/startup/bl_ui/properties_physics_dynamicpaint.py
index 611f477a31b..44d07ff53e6 100644
--- a/release/scripts/startup/bl_ui/properties_physics_dynamicpaint.py
+++ b/release/scripts/startup/bl_ui/properties_physics_dynamicpaint.py
@@ -87,24 +87,22 @@ class PHYSICS_PT_dynamic_paint(PhysicButtonsPanel, Panel):
col.operator("dpaint.surface_slot_add", icon='ZOOMIN', text="")
col.operator("dpaint.surface_slot_remove", icon='ZOOMOUT', text="")
+ layout.use_property_split = True
+
if surface:
layout.prop(surface, "surface_format")
col = layout.column()
if surface.surface_format != 'VERTEX':
- col.label(text="Quality:")
col.prop(surface, "image_resolution")
col.prop(surface, "use_antialiasing")
- col = layout.column()
- col.label(text="Frames:")
- split = col.split()
- col = split.column(align=True)
- col.prop(surface, "frame_start", text="Start")
- col.prop(surface, "frame_end", text="End")
+ sub = col.column(align=True)
+ sub.prop(surface, "frame_start", text="Frame Start")
+ sub.prop(surface, "frame_end", text="End")
- split.prop(surface, "frame_substeps")
+ col.prop(surface, "frame_substeps")
elif md.ui_type == 'BRUSH':
brush = md.brush_settings
@@ -114,16 +112,14 @@ class PHYSICS_PT_dynamic_paint(PhysicButtonsPanel, Panel):
else:
layout.operator("dpaint.type_toggle", text="Remove Brush", icon='X').type = 'BRUSH'
- split = layout.split()
+ layout.use_property_split = True
- col = split.column()
+ col = layout.column()
+ col.prop(brush, "paint_color")
+ col.prop(brush, "paint_alpha", text="Alpha", slider=True)
+ col.prop(brush, "paint_wetness", text="Wetness", slider=True)
col.prop(brush, "use_absolute_alpha")
col.prop(brush, "use_paint_erase")
- col.prop(brush, "paint_wetness", text="Wetness")
-
- col = split.column()
- col.prop(brush, "paint_color", text="")
- col.prop(brush, "paint_alpha", text="Alpha")
class PHYSICS_PT_dp_advanced_canvas(PhysicButtonsPanel, Panel):
@@ -141,65 +137,113 @@ class PHYSICS_PT_dp_advanced_canvas(PhysicButtonsPanel, Panel):
canvas = context.dynamic_paint.canvas_settings
surface = canvas.canvas_surfaces.active
-
surface_type = surface.surface_type
+ layout.use_property_split = True
+
layout.prop(surface, "surface_type")
+
layout.separator()
- # dissolve
- if surface_type == 'PAINT':
- split = layout.split(percentage=0.35)
- split.prop(surface, "use_drying", text="Dry:")
-
- col = split.column()
- col.active = surface.use_drying
- split = col.split(percentage=0.7)
- col = split.column(align=True)
- col.prop(surface, "dry_speed", text="Time")
- col.prop(surface, "color_dry_threshold")
- split.prop(surface, "use_dry_log", text="Slow")
-
- if surface_type != 'WAVE':
- split = layout.split(percentage=0.35)
- col = split.column()
- if surface_type == 'WEIGHT':
- col.prop(surface, "use_dissolve", text="Fade:")
- else:
- col.prop(surface, "use_dissolve", text="Dissolve:")
- col = split.column()
- col.active = surface.use_dissolve
- split = col.split(percentage=0.7)
- split.prop(surface, "dissolve_speed", text="Time")
- split.prop(surface, "use_dissolve_log", text="Slow")
+ col = layout.column()
# per type settings
if surface_type == 'DISPLACE':
- layout.prop(surface, "use_incremental_displace")
+ col.prop(surface, "use_incremental_displace")
if surface.surface_format == 'VERTEX':
- row = layout.row()
- row.prop(surface, "depth_clamp")
- row.prop(surface, "displace_factor")
-
- elif surface_type == 'WAVE':
- layout.prop(surface, "use_wave_open_border")
+ col.prop(surface, "depth_clamp")
+ col.prop(surface, "displace_factor")
- split = layout.split()
+ col.separator()
- col = split.column(align=True)
+ elif surface_type == 'WAVE':
+ col.prop(surface, "use_wave_open_border")
col.prop(surface, "wave_timescale")
col.prop(surface, "wave_speed")
-
- col = split.column(align=True)
col.prop(surface, "wave_damping")
col.prop(surface, "wave_spring")
col.prop(surface, "wave_smoothness")
- layout.separator()
- layout.prop(surface, "brush_group")
- row = layout.row()
- row.prop(surface, "brush_influence_scale")
- row.prop(surface, "brush_radius_scale")
+ col.separator()
+
+ col.prop(surface, "brush_group")
+ col.prop(surface, "brush_influence_scale")
+ col.prop(surface, "brush_radius_scale")
+
+
+class PHYSICS_PT_dp_advanced_canvas_paint_dry(PhysicButtonsPanel, Panel):
+ bl_label = "Dry"
+ bl_parent_id = "PHYSICS_PT_dp_advanced_canvas"
+ bl_options = {'DEFAULT_CLOSED'}
+ COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'}
+
+ @classmethod
+ def poll(cls, context):
+ md = context.dynamic_paint
+ canvas = context.dynamic_paint.canvas_settings
+ surface = canvas.canvas_surfaces.active
+ surface_type = surface.surface_type
+
+ return md and md.ui_type == 'CANVAS' and md.canvas_settings and md.canvas_settings.canvas_surfaces.active and surface_type == 'PAINT' and context.engine in cls.COMPAT_ENGINES
+
+ def draw_header(self, context):
+ canvas = context.dynamic_paint.canvas_settings
+ surface = canvas.canvas_surfaces.active
+ self.layout.prop(surface, "use_drying", text="")
+
+ def draw(self, context):
+ layout = self.layout
+
+ canvas = context.dynamic_paint.canvas_settings
+ surface = canvas.canvas_surfaces.active
+ surface_type = surface.surface_type
+
+ layout.use_property_split = True
+
+ layout.active = surface.use_drying
+
+ col = layout.column()
+ col.prop(surface, "dry_speed", text="Time")
+ col.prop(surface, "color_dry_threshold")
+ col.prop(surface, "use_dry_log", text="Slow")
+
+
+class PHYSICS_PT_dp_advanced_canvas_paint_dissolve(PhysicButtonsPanel, Panel):
+ bl_label = "Dissolve"
+ bl_parent_id = "PHYSICS_PT_dp_advanced_canvas"
+ bl_options = {'DEFAULT_CLOSED'}
+ COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'}
+
+ @classmethod
+ def poll(cls, context):
+ md = context.dynamic_paint
+ canvas = context.dynamic_paint.canvas_settings
+ surface = canvas.canvas_surfaces.active
+ surface_type = surface.surface_type
+
+ return md and md.ui_type == 'CANVAS' and md.canvas_settings and md.canvas_settings.canvas_surfaces.active and surface_type != 'WAVE' and context.engine in cls.COMPAT_ENGINES
+
+ def draw_header(self, context):
+ canvas = context.dynamic_paint.canvas_settings
+ surface = canvas.canvas_surfaces.active
+ self.layout.prop(surface, "use_dissolve", text="")
+
+
+ def draw(self, context):
+ layout = self.layout
+
+ canvas = context.dynamic_paint.canvas_settings
+ surface = canvas.canvas_surfaces.active
+ surface_type = surface.surface_type
+
+ layout.use_property_split = True
+
+ layout.active = surface.use_dissolve
+
+ col = layout.column()
+
+ col.prop(surface, "dissolve_speed", text="Time")
+ col.prop(surface, "use_dissolve_log", text="Slow")
class PHYSICS_PT_dp_canvas_output(PhysicButtonsPanel, Panel):
@@ -220,6 +264,7 @@ class PHYSICS_PT_dp_canvas_output(PhysicButtonsPanel, Panel):
def draw(self, context):
layout = self.layout
+ layout.use_property_split = True
canvas = context.dynamic_paint.canvas_settings
surface = canvas.canvas_surfaces.active
@@ -317,6 +362,8 @@ class PHYSICS_PT_dp_canvas_initial_color(PhysicButtonsPanel, Panel):
surface = canvas.canvas_surfaces.active
ob = context.object
+ layout.use_property_split = True
+
layout.prop(surface, "init_color_type", expand=False)
if surface.init_color_type != 'NONE':
layout.separator()
@@ -350,37 +397,86 @@ class PHYSICS_PT_dp_effects(PhysicButtonsPanel, Panel):
def draw(self, context):
layout = self.layout
+
+
+class PHYSICS_PT_dp_effects_spread(PhysicButtonsPanel, Panel):
+ bl_label = "Spread"
+ bl_parent_id = "PHYSICS_PT_dp_effects"
+ bl_options = {'DEFAULT_CLOSED'}
+ COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'}
+
+ def draw_header(self, context):
canvas = context.dynamic_paint.canvas_settings
surface = canvas.canvas_surfaces.active
- layout.row().prop(surface, "effect_ui", expand=True)
+ self.layout.prop(surface, "use_spread", text="")
- if surface.effect_ui == 'SPREAD':
- layout.prop(surface, "use_spread")
+ def draw(self, context):
+ layout = self.layout
- row = layout.row()
- row.active = surface.use_spread
- row.prop(surface, "spread_speed")
- row.prop(surface, "color_spread_speed")
+ layout.use_property_split = True
- elif surface.effect_ui == 'DRIP':
- layout.prop(surface, "use_drip")
+ canvas = context.dynamic_paint.canvas_settings
+ surface = canvas.canvas_surfaces.active
+ layout.active = surface.use_spread
- col = layout.column()
- col.active = surface.use_drip
- effector_weights_ui(self, context, surface.effector_weights, 'DYNAMIC_PAINT')
+ col = layout.column()
- layout.label(text="Surface Movement:")
- row = layout.row()
- row.prop(surface, "drip_velocity", slider=True)
- row.prop(surface, "drip_acceleration", slider=True)
+ col.prop(surface, "spread_speed")
+ col.prop(surface, "color_spread_speed")
- elif surface.effect_ui == 'SHRINK':
- layout.prop(surface, "use_shrink")
- row = layout.row()
- row.active = surface.use_shrink
- row.prop(surface, "shrink_speed")
+class PHYSICS_PT_dp_effects_drip(PhysicButtonsPanel, Panel):
+ bl_label = "Drip"
+ bl_parent_id = "PHYSICS_PT_dp_effects"
+ bl_options = {'DEFAULT_CLOSED'}
+ COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'}
+
+ def draw_header(self, context):
+ canvas = context.dynamic_paint.canvas_settings
+ surface = canvas.canvas_surfaces.active
+
+ self.layout.prop(surface, "use_drip", text="")
+
+ def draw(self, context):
+ layout = self.layout
+ layout.use_property_split = True
+
+ canvas = context.dynamic_paint.canvas_settings
+ surface = canvas.canvas_surfaces.active
+
+ layout.active = surface.use_drip
+
+ col = layout.column()
+ col.prop(surface, "drip_velocity", slider=True)
+ col.prop(surface, "drip_acceleration", slider=True)
+
+ col.separator()
+
+ effector_weights_ui(self, context, surface.effector_weights, 'DYNAMIC_PAINT')
+
+class PHYSICS_PT_dp_effects_shrink(PhysicButtonsPanel, Panel):
+ bl_label = "Shrink"
+ bl_parent_id = "PHYSICS_PT_dp_effects"
+ bl_options = {'DEFAULT_CLOSED'}
+ COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'}
+
+ def draw_header(self, context):
+ canvas = context.dynamic_paint.canvas_settings
+ surface = canvas.canvas_surfaces.active
+
+ self.layout.prop(surface, "use_shrink", text="")
+
+ def draw(self, context):
+ layout = self.layout
+
+ layout.use_property_split = True
+
+ canvas = context.dynamic_paint.canvas_settings
+ surface = canvas.canvas_surfaces.active
+ layout.active = surface.use_shrink
+
+ layout.prop(surface, "shrink_speed")
class PHYSICS_PT_dp_cache(PhysicButtonsPanel, Panel):
@@ -418,6 +514,7 @@ class PHYSICS_PT_dp_brush_source(PhysicButtonsPanel, Panel):
def draw(self, context):
layout = self.layout
+ layout.use_property_split = True
brush = context.dynamic_paint.brush_settings
ob = context.object
@@ -427,7 +524,7 @@ class PHYSICS_PT_dp_brush_source(PhysicButtonsPanel, Panel):
col.prop(brush, "paint_source")
if brush.paint_source == 'PARTICLE_SYSTEM':
- col.prop_search(brush, "particle_system", ob, "particle_systems", text="")
+ col.prop_search(brush, "particle_system", ob, "particle_systems")
if brush.particle_system:
col.label(text="Particle Effect:")
sub = col.column()
@@ -438,22 +535,19 @@ class PHYSICS_PT_dp_brush_source(PhysicButtonsPanel, Panel):
if brush.paint_source in {'DISTANCE', 'VOLUME_DISTANCE', 'POINT'}:
col.prop(brush, "paint_distance", text="Paint Distance")
- split = layout.row().split(percentage=0.4)
- sub = split.column()
+
if brush.paint_source in {'DISTANCE', 'VOLUME_DISTANCE'}:
- sub.prop(brush, "use_proximity_project")
+ col.prop(brush, "use_proximity_project")
if brush.paint_source == 'VOLUME_DISTANCE':
- sub.prop(brush, "invert_proximity")
- sub.prop(brush, "use_negative_volume")
-
- sub = split.column()
+ col.prop(brush, "invert_proximity")
+ col.prop(brush, "use_negative_volume")
if brush.paint_source in {'DISTANCE', 'VOLUME_DISTANCE'}:
- column = sub.column()
- column.active = brush.use_proximity_project
- column.prop(brush, "ray_direction")
- sub.prop(brush, "proximity_falloff")
+ sub = col.column()
+ sub.active = brush.use_proximity_project
+ sub.prop(brush, "ray_direction")
+ col.prop(brush, "proximity_falloff")
if brush.proximity_falloff == 'RAMP':
- col = layout.row().column()
+
col.separator()
col.prop(brush, "use_proximity_ramp_alpha", text="Only Use Alpha")
col.template_color_ramp(brush, "paint_ramp", expand=True)
@@ -472,28 +566,45 @@ class PHYSICS_PT_dp_brush_velocity(PhysicButtonsPanel, Panel):
def draw(self, context):
layout = self.layout
+ layout.use_property_split = True
brush = context.dynamic_paint.brush_settings
- split = layout.split()
-
- col = split.column()
+ col = layout.column()
col.prop(brush, "use_velocity_alpha")
col.prop(brush, "use_velocity_color")
-
- split.prop(brush, "use_velocity_depth")
+ col.prop(brush, "use_velocity_depth")
col = layout.column()
col.active = (brush.use_velocity_alpha or brush.use_velocity_color or brush.use_velocity_depth)
col.prop(brush, "velocity_max")
col.template_color_ramp(brush, "velocity_ramp", expand=True)
- layout.separator()
- row = layout.row()
- row.prop(brush, "use_smudge")
- sub = row.row()
- sub.active = brush.use_smudge
- sub.prop(brush, "smudge_strength")
+
+class PHYSICS_PT_dp_brush_velocity_smudge(PhysicButtonsPanel, Panel):
+ bl_label = "Smudge"
+ bl_parent_id = "PHYSICS_PT_dp_brush_velocity"
+ bl_options = {'DEFAULT_CLOSED'}
+ COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'}
+
+ @classmethod
+ def poll(cls, context):
+ md = context.dynamic_paint
+ return md and md.ui_type == 'BRUSH' and md.brush_settings and (context.engine in cls.COMPAT_ENGINES)
+
+ def draw_header(self, context):
+ brush = context.dynamic_paint.brush_settings
+
+ self.layout.prop(brush, "use_smudge", text="")
+
+ def draw(self, context):
+ layout = self.layout
+ layout.use_property_split = True
+
+ brush = context.dynamic_paint.brush_settings
+
+ layout.active = brush.use_smudge
+ layout.prop(brush, "smudge_strength", slider=True)
class PHYSICS_PT_dp_brush_wave(PhysicButtonsPanel, Panel):
@@ -509,26 +620,33 @@ class PHYSICS_PT_dp_brush_wave(PhysicButtonsPanel, Panel):
def draw(self, context):
layout = self.layout
+ layout.use_property_split = True
brush = context.dynamic_paint.brush_settings
layout.prop(brush, "wave_type")
if brush.wave_type != 'REFLECT':
- row = layout.row()
- row.prop(brush, "wave_factor")
- row.prop(brush, "wave_clamp")
+ col = layout.column()
+ col.prop(brush, "wave_factor")
+ col.prop(brush, "wave_clamp")
classes = (
PHYSICS_UL_dynapaint_surfaces,
PHYSICS_PT_dynamic_paint,
PHYSICS_PT_dp_advanced_canvas,
+ PHYSICS_PT_dp_advanced_canvas_paint_dry,
+ PHYSICS_PT_dp_advanced_canvas_paint_dissolve,
PHYSICS_PT_dp_canvas_output,
PHYSICS_PT_dp_canvas_initial_color,
PHYSICS_PT_dp_effects,
+ PHYSICS_PT_dp_effects_spread,
+ PHYSICS_PT_dp_effects_drip,
+ PHYSICS_PT_dp_effects_shrink,
PHYSICS_PT_dp_cache,
PHYSICS_PT_dp_brush_source,
PHYSICS_PT_dp_brush_velocity,
+ PHYSICS_PT_dp_brush_velocity_smudge,
PHYSICS_PT_dp_brush_wave,
)
diff --git a/release/scripts/startup/bl_ui/properties_physics_rigidbody.py b/release/scripts/startup/bl_ui/properties_physics_rigidbody.py
index 013822793de..00733e2fb12 100644
--- a/release/scripts/startup/bl_ui/properties_physics_rigidbody.py
+++ b/release/scripts/startup/bl_ui/properties_physics_rigidbody.py
@@ -39,20 +39,23 @@ class PHYSICS_PT_rigid_body(PHYSICS_PT_rigidbody_panel, Panel):
def draw(self, context):
layout = self.layout
+ layout.use_property_split = True
ob = context.object
rbo = ob.rigid_body
if rbo is not None:
layout.prop(rbo, "type", text="Type")
- row = layout.row()
- if rbo.type == 'ACTIVE':
- row.prop(rbo, "enabled", text="Dynamic")
- row.prop(rbo, "kinematic", text="Animated")
if rbo.type == 'ACTIVE':
layout.prop(rbo, "mass")
+ col = layout.column()
+ if rbo.type == 'ACTIVE':
+ col.prop(rbo, "enabled", text="Dynamic")
+ col.prop(rbo, "kinematic", text="Animated")
+
+
class PHYSICS_PT_rigid_body_collisions(PHYSICS_PT_rigidbody_panel, Panel):
bl_label = "Collisions"
@@ -70,6 +73,7 @@ class PHYSICS_PT_rigid_body_collisions(PHYSICS_PT_rigidbody_panel, Panel):
ob = context.object
rbo = ob.rigid_body
+ layout.use_property_split = True
layout.prop(rbo, "collision_shape", text="Shape")
@@ -79,15 +83,51 @@ class PHYSICS_PT_rigid_body_collisions(PHYSICS_PT_rigidbody_panel, Panel):
if rbo.collision_shape == 'MESH' and rbo.mesh_source == 'DEFORM':
layout.prop(rbo, "use_deform", text="Deforming")
- split = layout.split()
- col = split.column()
- col.label(text="Surface Response:")
+class PHYSICS_PT_rigid_body_collisions_surface(PHYSICS_PT_rigidbody_panel, Panel):
+ bl_label = "Surface Response"
+ bl_parent_id = 'PHYSICS_PT_rigid_body_collisions'
+ bl_options = {'DEFAULT_CLOSED'}
+ COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'}
+
+ @classmethod
+ def poll(cls, context):
+ obj = context.object
+ return (obj and obj.rigid_body and
+ (context.engine in cls.COMPAT_ENGINES))
+
+ def draw(self, context):
+ layout = self.layout
+
+ ob = context.object
+ rbo = ob.rigid_body
+ layout.use_property_split = True
+
+ col = layout.column()
col.prop(rbo, "friction")
col.prop(rbo, "restitution", text="Bounciness")
- col = split.column()
- col.label(text="Sensitivity:")
+class PHYSICS_PT_rigid_body_collisions_sensitivity(PHYSICS_PT_rigidbody_panel, Panel):
+ bl_label = "Sensitivity"
+ bl_parent_id = 'PHYSICS_PT_rigid_body_collisions'
+ bl_options = {'DEFAULT_CLOSED'}
+ COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'}
+
+ @classmethod
+ def poll(cls, context):
+ obj = context.object
+ return (obj and obj.rigid_body and
+ (context.engine in cls.COMPAT_ENGINES))
+
+ def draw(self, context):
+ layout = self.layout
+
+ ob = context.object
+ rbo = ob.rigid_body
+ layout.use_property_split = True
+
+ col = layout.column()
+
if rbo.collision_shape in {'MESH', 'CONE'}:
col.prop(rbo, "collision_margin", text="Margin")
else:
@@ -96,7 +136,25 @@ class PHYSICS_PT_rigid_body_collisions(PHYSICS_PT_rigidbody_panel, Panel):
sub.active = rbo.use_margin
sub.prop(rbo, "collision_margin", text="Margin")
- layout.prop(rbo, "collision_groups")
+class PHYSICS_PT_rigid_body_collisions_collections(PHYSICS_PT_rigidbody_panel, Panel):
+ bl_label = "Collision Collections"
+ bl_parent_id = 'PHYSICS_PT_rigid_body_collisions'
+ bl_options = {'DEFAULT_CLOSED'}
+ COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'}
+
+ @classmethod
+ def poll(cls, context):
+ obj = context.object
+ return (obj and obj.rigid_body and
+ (context.engine in cls.COMPAT_ENGINES))
+
+ def draw(self, context):
+ layout = self.layout
+
+ ob = context.object
+ rbo = ob.rigid_body
+
+ layout.prop(rbo, "collision_groups", text="")
class PHYSICS_PT_rigid_body_dynamics(PHYSICS_PT_rigidbody_panel, Panel):
@@ -114,6 +172,7 @@ class PHYSICS_PT_rigid_body_dynamics(PHYSICS_PT_rigidbody_panel, Panel):
def draw(self, context):
layout = self.layout
+ layout.use_property_split = True
ob = context.object
rbo = ob.rigid_body
@@ -122,28 +181,53 @@ class PHYSICS_PT_rigid_body_dynamics(PHYSICS_PT_rigidbody_panel, Panel):
# col.label(text="Activation:")
# XXX: settings such as activate on collison/etc.
- split = layout.split()
-
- col = split.column()
- col.label(text="Deactivation:")
- col.prop(rbo, "use_deactivation")
- sub = col.column()
- sub.active = rbo.use_deactivation
- sub.prop(rbo, "use_start_deactivated")
- sub.prop(rbo, "deactivate_linear_velocity", text="Linear Vel")
- sub.prop(rbo, "deactivate_angular_velocity", text="Angular Vel")
- # TODO: other params such as time?
-
- col = split.column()
- col.label(text="Damping:")
- col.prop(rbo, "linear_damping", text="Translation")
- col.prop(rbo, "angular_damping", text="Rotation")
+ col = layout.column()
+ col.prop(rbo, "linear_damping", text="Translation Damping")
+ col.prop(rbo, "angular_damping", text="Rotation Damping")
+
+
+class PHYSICS_PT_rigid_body_dynamics_deactivation(PHYSICS_PT_rigidbody_panel, Panel):
+ bl_label = "Deactivation"
+ bl_parent_id = 'PHYSICS_PT_rigid_body_dynamics'
+ bl_options = {'DEFAULT_CLOSED'}
+ COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'}
+
+ @classmethod
+ def poll(cls, context):
+ obj = context.object
+ return (obj and obj.rigid_body and
+ obj.rigid_body.type == 'ACTIVE' and
+ (context.engine in cls.COMPAT_ENGINES))
+
+ def draw_header(self, context):
+ ob = context.object
+ rbo = ob.rigid_body
+ self.layout.prop(rbo, "use_deactivation", text="")
+
+ def draw(self, context):
+ layout = self.layout
+ layout.use_property_split = True
+
+ ob = context.object
+ rbo = ob.rigid_body
+
+ layout.active = rbo.use_deactivation
+
+ col = layout.column()
+ col.prop(rbo, "use_start_deactivated")
+ col.prop(rbo, "deactivate_linear_velocity", text="Linear Velocity")
+ col.prop(rbo, "deactivate_angular_velocity", text="Angular Velocity")
+ # TODO: other params such as time?
classes = (
PHYSICS_PT_rigid_body,
PHYSICS_PT_rigid_body_collisions,
+ PHYSICS_PT_rigid_body_collisions_surface,
+ PHYSICS_PT_rigid_body_collisions_sensitivity,
+ PHYSICS_PT_rigid_body_collisions_collections,
PHYSICS_PT_rigid_body_dynamics,
+ PHYSICS_PT_rigid_body_dynamics_deactivation,
)
if __name__ == "__main__": # only for live edit.
diff --git a/release/scripts/startup/bl_ui/properties_physics_rigidbody_constraint.py b/release/scripts/startup/bl_ui/properties_physics_rigidbody_constraint.py
index 69491f36c63..5e67caadc90 100644
--- a/release/scripts/startup/bl_ui/properties_physics_rigidbody_constraint.py
+++ b/release/scripts/startup/bl_ui/properties_physics_rigidbody_constraint.py
@@ -139,6 +139,11 @@ class PHYSICS_PT_rigid_body_constraint(PHYSICS_PT_rigidbody_constraint_panel, Pa
sub.prop(rbc, "motor_ang_max_impulse", text="Max Impulse")
elif rbc.type in {'GENERIC', 'GENERIC_SPRING'}:
+ if rbc.type == 'GENERIC_SPRING':
+ row = layout.row()
+ row.label("Spring Type:")
+ row.prop(rbc, "spring_type", text="")
+
col = layout.column(align=True)
col.label("Limits:")
diff --git a/release/scripts/startup/bl_ui/properties_render.py b/release/scripts/startup/bl_ui/properties_render.py
index b1c5edf97e7..83d31ae6114 100644
--- a/release/scripts/startup/bl_ui/properties_render.py
+++ b/release/scripts/startup/bl_ui/properties_render.py
@@ -594,8 +594,6 @@ class RENDER_PT_eevee_volumetric(RenderButtonsPanel, Panel):
sub = col.column()
sub.active = props.use_volumetric_shadows
sub.prop(props, "volumetric_shadow_samples", text="Shadow Samples")
- col.separator()
- col.prop(props, "use_volumetric_colored_transmittance")
class RENDER_PT_eevee_subsurface_scattering(RenderButtonsPanel, Panel):
diff --git a/release/scripts/startup/bl_ui/properties_texture.py b/release/scripts/startup/bl_ui/properties_texture.py
index d937f2470b8..a4f6f753669 100644
--- a/release/scripts/startup/bl_ui/properties_texture.py
+++ b/release/scripts/startup/bl_ui/properties_texture.py
@@ -17,19 +17,21 @@
# ##### END GPL LICENSE BLOCK #####
# <pep8 compliant>
-import bpy
-from bpy.types import Menu, Panel, UIList
+import bpy
+from bpy.types import (
+ Menu,
+ Panel,
+ UIList,
+)
from bpy.types import (
Brush,
FreestyleLineStyle,
- Object,
ParticleSettings,
Texture,
)
from rna_prop_ui import PropertyPanel
-
from .properties_paint_common import brush_texture_settings
@@ -47,9 +49,9 @@ class TEXTURE_MT_specials(Menu):
class TEXTURE_UL_texslots(UIList):
def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index):
- ma = data
slot = item
tex = slot.texture if slot else None
+
if self.layout_type in {'DEFAULT', 'COMPACT'}:
if tex:
layout.prop(tex, "name", text="", emboss=False, icon_value=icon)
@@ -131,18 +133,18 @@ class TEXTURE_PT_context(TextureButtonsPanel, Panel):
if not pin_id:
col.template_texture_user()
- col.separator()
-
if user or pin_id:
+ col.separator()
+
if pin_id:
col.template_ID(space, "pin_id")
else:
propname = context.texture_user_property.identifier
col.template_ID(user, propname, new="texture.new")
- col.separator()
-
if tex:
+ col.separator()
+
split = col.split(percentage=0.2)
split.label(text="Type")
split.prop(tex, "type", text="")
@@ -179,25 +181,35 @@ class TEXTURE_PT_node_mapping(TextureButtonsPanel, Panel):
def draw(self, context):
layout = self.layout
+ layout.use_property_split = True
+ layout.use_property_decorate = False # No animation.
+
+ flow = layout.grid_flow(row_major=True, columns=0, even_columns=True, even_rows=False, align=False)
node = context.texture_node
mapping = node.texture_mapping
- layout.prop(mapping, "vector_type", expand=True)
+ col = flow.column()
+ col.prop(mapping, "vector_type")
+
+ col.separator()
+
+ col = col.column(align=True)
+ col.prop(mapping, "mapping_x", text="Projection X")
+ col.prop(mapping, "mapping_y", text="Y")
+ col.prop(mapping, "mapping_z", text="Z")
- row = layout.row()
+ col.separator()
- row.column().prop(mapping, "translation")
- row.column().prop(mapping, "rotation")
- row.column().prop(mapping, "scale")
+ col = flow.column()
+ col.column().prop(mapping, "translation")
- layout.label(text="Projection:")
+ col = flow.column()
+ col.column().prop(mapping, "rotation")
- row = layout.row()
- row.prop(mapping, "mapping_x", text="")
- row.prop(mapping, "mapping_y", text="")
- row.prop(mapping, "mapping_z", text="")
+ col = flow.column()
+ col.column().prop(mapping, "scale")
class TextureTypePanel(TextureButtonsPanel):
@@ -216,21 +228,29 @@ class TEXTURE_PT_clouds(TextureTypePanel, Panel):
def draw(self, context):
layout = self.layout
+ layout.use_property_split = True
+ flow = layout.grid_flow(row_major=True, columns=0, even_columns=True, even_rows=False, align=True)
tex = context.texture
- layout.row().prop(tex, "cloud_type", expand=True)
- layout.label(text="Noise:")
- layout.row().prop(tex, "noise_type", text="Type", expand=True)
- layout.prop(tex, "noise_basis", text="Basis")
+ col = flow.column()
+ col.prop(tex, "noise_basis", text="Noise Basis")
+
+ col.separator()
+
+ col.prop(tex, "noise_type", text="Type")
+
+ col.separator()
- split = layout.split()
+ col = flow.column()
+ col.prop(tex, "cloud_type")
- col = split.column()
+ col.separator()
+
+ col = flow.column()
col.prop(tex, "noise_scale", text="Size")
col.prop(tex, "noise_depth", text="Depth")
-
- split.prop(tex, "nabla", text="Nabla")
+ col.prop(tex, "nabla", text="Nabla")
class TEXTURE_PT_wood(TextureTypePanel, Panel):
@@ -240,26 +260,34 @@ class TEXTURE_PT_wood(TextureTypePanel, Panel):
def draw(self, context):
layout = self.layout
+ layout.use_property_split = True
+ flow = layout.grid_flow(row_major=True, columns=0, even_columns=False, even_rows=False, align=False)
tex = context.texture
- layout.row().prop(tex, "noise_basis_2", expand=True)
- layout.row().prop(tex, "wood_type", expand=True)
+ col = flow.column()
+ col.prop(tex, "noise_basis", text="Noise Basis")
- col = layout.column()
- col.active = tex.wood_type in {'RINGNOISE', 'BANDNOISE'}
- col.label(text="Noise:")
- col.row().prop(tex, "noise_type", text="Type", expand=True)
- layout.prop(tex, "noise_basis", text="Basis")
+ col.separator()
- split = layout.split()
- split.active = tex.wood_type in {'RINGNOISE', 'BANDNOISE'}
+ col.prop(tex, "wood_type")
- col = split.column()
- col.prop(tex, "noise_scale", text="Size")
- col.prop(tex, "turbulence")
+ col.separator()
- split.prop(tex, "nabla")
+ col = flow.column()
+ col.prop(tex, "noise_basis_2", text="Second Basis")
+
+ col = col.column()
+ col.active = tex.wood_type in {'RINGNOISE', 'BANDNOISE'}
+ col.prop(tex, "noise_type", text="Type")
+
+ col.separator()
+
+ sub = flow.column()
+ sub.active = tex.wood_type in {'RINGNOISE', 'BANDNOISE'}
+ sub.prop(tex, "noise_scale", text="Size")
+ sub.prop(tex, "turbulence")
+ sub.prop(tex, "nabla")
class TEXTURE_PT_marble(TextureTypePanel, Panel):
@@ -269,22 +297,29 @@ class TEXTURE_PT_marble(TextureTypePanel, Panel):
def draw(self, context):
layout = self.layout
+ layout.use_property_split = True
+ flow = layout.grid_flow(row_major=True, columns=0, even_columns=True, even_rows=False, align=True)
tex = context.texture
- layout.row().prop(tex, "marble_type", expand=True)
- layout.row().prop(tex, "noise_basis_2", expand=True)
- layout.label(text="Noise:")
- layout.row().prop(tex, "noise_type", text="Type", expand=True)
- layout.prop(tex, "noise_basis", text="Basis")
+ col = flow.column()
+ col.prop(tex, "noise_basis", text="Noise Basis")
+
+ col.separator()
+
+ col.prop(tex, "marble_type")
- split = layout.split()
+ col.separator()
- col = split.column()
+ col = flow.column()
+ col.prop(tex, "noise_basis_2", text="Second Basis")
+ col.prop(tex, "noise_type", text="Type")
+
+ col.separator()
+
+ col = flow.column()
col.prop(tex, "noise_scale", text="Size")
col.prop(tex, "noise_depth", text="Depth")
-
- col = split.column()
col.prop(tex, "turbulence")
col.prop(tex, "nabla")
@@ -296,12 +331,16 @@ class TEXTURE_PT_magic(TextureTypePanel, Panel):
def draw(self, context):
layout = self.layout
+ layout.use_property_split = True
+ flow = layout.grid_flow(row_major=True, columns=0, even_columns=True, even_rows=False, align=False)
tex = context.texture
- row = layout.row()
- row.prop(tex, "noise_depth", text="Depth")
- row.prop(tex, "turbulence")
+ col = flow.column()
+ col.prop(tex, "noise_depth", text="Depth")
+
+ col = flow.column()
+ col.prop(tex, "turbulence")
class TEXTURE_PT_blend(TextureTypePanel, Panel):
@@ -311,15 +350,19 @@ class TEXTURE_PT_blend(TextureTypePanel, Panel):
def draw(self, context):
layout = self.layout
+ layout.use_property_split = True
+ flow = layout.grid_flow(row_major=True, columns=0, even_columns=True, even_rows=False, align=True)
tex = context.texture
- layout.prop(tex, "progression")
+ col = flow.column()
+ col.prop(tex, "progression")
- sub = layout.row()
+ col.separator()
- sub.active = (tex.progression in {'LINEAR', 'QUADRATIC', 'EASING', 'RADIAL'})
- sub.prop(tex, "use_flip_axis", expand=True)
+ col = flow.column()
+ col.active = (tex.progression in {'LINEAR', 'QUADRATIC', 'EASING', 'RADIAL'})
+ col.prop(tex, "use_flip_axis", text="Orientation")
class TEXTURE_PT_stucci(TextureTypePanel, Panel):
@@ -329,17 +372,28 @@ class TEXTURE_PT_stucci(TextureTypePanel, Panel):
def draw(self, context):
layout = self.layout
+ layout.use_property_split = True
+ flow = layout.grid_flow(row_major=True, columns=0, even_columns=True, even_rows=False, align=False)
tex = context.texture
- layout.row().prop(tex, "stucci_type", expand=True)
- layout.label(text="Noise:")
- layout.row().prop(tex, "noise_type", text="Type", expand=True)
- layout.prop(tex, "noise_basis", text="Basis")
+ col = flow.column()
+ col.prop(tex, "noise_basis", text="Noise Basis")
+
+ col.separator()
- row = layout.row()
- row.prop(tex, "noise_scale", text="Size")
- row.prop(tex, "turbulence")
+ col.row().prop(tex, "stucci_type")
+
+ col.separator()
+
+ col = flow.column()
+ col.prop(tex, "noise_type", text="Type")
+
+ col.separator()
+
+ col = flow.column()
+ col.prop(tex, "noise_scale", text="Size")
+ col.prop(tex, "turbulence")
class TEXTURE_PT_image(TextureTypePanel, Panel):
@@ -348,6 +402,18 @@ class TEXTURE_PT_image(TextureTypePanel, Panel):
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'}
def draw(self, context):
+ # TODO: maybe expose the template_ID from the template image here.
+ layout = self.layout
+ del layout
+
+
+class TEXTURE_PT_image_settings(TextureTypePanel, Panel):
+ bl_label = "Settings"
+ bl_parent_id = 'TEXTURE_PT_image'
+ tex_type = 'IMAGE'
+ COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'}
+
+ def draw(self, context):
layout = self.layout
tex = context.texture
@@ -356,11 +422,13 @@ class TEXTURE_PT_image(TextureTypePanel, Panel):
def texture_filter_common(tex, layout):
layout.prop(tex, "filter_type", text="Filter Type")
+
if tex.use_mipmap and tex.filter_type in {'AREA', 'EWA', 'FELINE'}:
+ col = layout.column()
if tex.filter_type == 'FELINE':
- layout.prop(tex, "filter_lightprobes", text="Light Probes")
+ col.prop(tex, "filter_lightprobes", text="Light Probes")
else:
- layout.prop(tex, "filter_eccentricity", text="Eccentricity")
+ col.prop(tex, "filter_eccentricity", text="Eccentricity")
layout.prop(tex, "filter_size", text="Size")
layout.prop(tex, "use_filter_size_min", text="Minimum Size")
@@ -376,14 +444,11 @@ class TEXTURE_PT_image_sampling(TextureTypePanel, Panel):
def draw(self, context):
layout = self.layout
layout.use_property_split = True
- flow = layout.grid_flow(row_major=True, columns=0, even_columns=True, even_rows=False, align=False)
+ flow = layout.grid_flow(row_major=True, columns=0, even_columns=True, even_rows=False, align=True)
- idblock = context_tex_datablock(context)
tex = context.texture
- slot = getattr(context, "texture_slot", None)
col = flow.column()
- col.prop(tex, "use_flip_axis", text="Flip X/Y Axis")
col.prop(tex, "use_interpolation")
col.separator()
@@ -396,8 +461,7 @@ class TEXTURE_PT_image_sampling(TextureTypePanel, Panel):
col.separator()
- col = flow.column()
- texture_filter_common(tex, col)
+ texture_filter_common(tex, flow)
class TEXTURE_PT_image_alpha(TextureTypePanel, Panel):
@@ -433,43 +497,70 @@ class TEXTURE_PT_image_mapping(TextureTypePanel, Panel):
def draw(self, context):
layout = self.layout
layout.use_property_split = True
- flow = layout.grid_flow(row_major=True, columns=0, even_columns=True, even_rows=False, align=False)
tex = context.texture
- col = flow.column()
- col.prop(tex, "extension")
+ col = layout.column()
+ col.prop(tex, "use_flip_axis", text="Flip Axes")
+
+ col.separator()
+
+ subcol = layout.column()
+ subcol.prop(tex, "extension") # use layout, to keep the same location in case of button cycling.
+
+ flow = layout.grid_flow(row_major=True, columns=0, even_columns=True, even_rows=False, align=True)
if tex.extension == 'REPEAT':
+
+ col = flow.column()
sub = col.column(align=True)
sub.prop(tex, "repeat_x", text="Repeat X")
sub.prop(tex, "repeat_y", text="Y")
+ col = flow.column()
sub = col.column()
- sub.prop(tex, "use_mirror_x", text="Mirror X")
sub.active = (tex.repeat_x > 1)
+ sub.prop(tex, "use_mirror_x", text="Mirror X")
sub = col.column()
- sub.prop(tex, "use_mirror_y", text="Y")
sub.active = (tex.repeat_y > 1)
+ sub.prop(tex, "use_mirror_y", text="Y")
elif tex.extension == 'CHECKER':
- col = layout.column(align=True)
- col.prop(tex, "use_checker_even", text="Even")
- col.prop(tex, "use_checker_odd", text="Odd")
+ subcol.separator()
- col = layout.column()
+ col = flow.column()
col.prop(tex, "checker_distance", text="Distance")
- col = flow.column()
- sub = col.column(align=True)
+ col = flow.column()
+ col.prop(tex, "use_checker_even", text="Tiles Even")
+ col.prop(tex, "use_checker_odd", text="Odd")
+ else:
+ del flow
+
+
+class TEXTURE_PT_image_mapping_crop(TextureTypePanel, Panel):
+ bl_label = "Crop"
+ bl_options = {'DEFAULT_CLOSED'}
+ bl_parent_id = 'TEXTURE_PT_image_mapping'
+ tex_type = 'IMAGE'
+ COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'}
+
+ def draw(self, context):
+ layout = self.layout
+ layout.use_property_split = True
+ flow = layout.grid_flow(row_major=True, columns=0, even_columns=True, even_rows=False, align=False)
+
+ tex = context.texture
+
+ col = flow.column(align=True)
# col.prop(tex, "crop_rectangle")
- sub.prop(tex, "crop_min_x", text="Crop Minimum X")
- sub.prop(tex, "crop_min_y", text="Y")
+ col.prop(tex, "crop_min_x", text="Minimum X")
+ col.prop(tex, "crop_min_y", text="Y")
- sub = col.column(align=True)
- sub.prop(tex, "crop_max_x", text="Crop Maximum X")
- sub.prop(tex, "crop_max_y", text="Y")
+ col = flow.column(align=True)
+ col.prop(tex, "crop_max_x", text="Maximum X")
+ col.prop(tex, "crop_max_y", text="Y")
class TEXTURE_PT_musgrave(TextureTypePanel, Panel):
@@ -479,34 +570,43 @@ class TEXTURE_PT_musgrave(TextureTypePanel, Panel):
def draw(self, context):
layout = self.layout
+ layout.use_property_split = True
+ flow = layout.grid_flow(row_major=True, columns=0, even_columns=True, even_rows=False, align=True)
tex = context.texture
- layout.prop(tex, "musgrave_type")
+ col = flow.column()
+ col.prop(tex, "noise_basis", text="Noise Basis")
+
+ col.separator()
+
+ col.prop(tex, "musgrave_type")
+
+ col.separator()
+
+ col.prop(tex, "noise_scale", text="Size")
+ col.prop(tex, "nabla")
- split = layout.split()
+ col.separator()
- col = split.column()
+ col = flow.column()
col.prop(tex, "dimension_max", text="Dimension")
col.prop(tex, "lacunarity")
col.prop(tex, "octaves")
+ col.separator()
+
musgrave_type = tex.musgrave_type
- col = split.column()
+
+ col = flow.column()
+
if musgrave_type in {'HETERO_TERRAIN', 'RIDGED_MULTIFRACTAL', 'HYBRID_MULTIFRACTAL'}:
col.prop(tex, "offset")
col.prop(tex, "noise_intensity", text="Intensity")
+
if musgrave_type in {'RIDGED_MULTIFRACTAL', 'HYBRID_MULTIFRACTAL'}:
col.prop(tex, "gain")
- layout.label(text="Noise:")
-
- layout.prop(tex, "noise_basis", text="Basis")
-
- row = layout.row()
- row.prop(tex, "noise_scale", text="Size")
- row.prop(tex, "nabla")
-
class TEXTURE_PT_voronoi(TextureTypePanel, Panel):
bl_label = "Voronoi"
@@ -515,33 +615,51 @@ class TEXTURE_PT_voronoi(TextureTypePanel, Panel):
def draw(self, context):
layout = self.layout
+ layout.use_property_split = True
+ flow = layout.grid_flow(row_major=True, columns=0, even_columns=True, even_rows=False, align=False)
tex = context.texture
- split = layout.split()
+ col = flow.column()
+ col.prop(tex, "distance_metric")
- col = split.column()
- col.label(text="Distance Metric:")
- col.prop(tex, "distance_metric", text="")
sub = col.column()
sub.active = tex.distance_metric == 'MINKOVSKY'
sub.prop(tex, "minkovsky_exponent", text="Exponent")
- col.label(text="Coloring:")
- col.prop(tex, "color_mode", text="")
+
+ sub.separator()
+
+ col = flow.column()
+ col.prop(tex, "color_mode")
col.prop(tex, "noise_intensity", text="Intensity")
- col = split.column()
- sub = col.column(align=True)
- sub.label(text="Feature Weights:")
- sub.prop(tex, "weight_1", text="1", slider=True)
- sub.prop(tex, "weight_2", text="2", slider=True)
- sub.prop(tex, "weight_3", text="3", slider=True)
- sub.prop(tex, "weight_4", text="4", slider=True)
+ col.separator()
+
+ col = flow.column()
+ col.prop(tex, "noise_scale", text="Size")
+ col.prop(tex, "nabla")
+
+
+class TEXTURE_PT_voronoi_feature_weights(TextureTypePanel, Panel):
+ bl_label = "Feature Weights"
+ bl_parent_id = "TEXTURE_PT_voronoi"
+ tex_type = 'VORONOI'
+ COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'}
+
+ def draw(self, context):
+ layout = self.layout
+ layout.use_property_split = True
+ flow = layout.grid_flow(row_major=False, columns=0, even_columns=True, even_rows=False, align=True)
+
+ tex = context.texture
- layout.label(text="Noise:")
- row = layout.row()
- row.prop(tex, "noise_scale", text="Size")
- row.prop(tex, "nabla")
+ col = flow.column(align=True)
+ col.prop(tex, "weight_1", text="First", slider=True)
+ col.prop(tex, "weight_2", text="Second", slider=True)
+
+ sub = flow.column(align=True)
+ sub.prop(tex, "weight_3", text="Third", slider=True)
+ sub.prop(tex, "weight_4", text="Fourth", slider=True)
class TEXTURE_PT_distortednoise(TextureTypePanel, Panel):
@@ -551,19 +669,24 @@ class TEXTURE_PT_distortednoise(TextureTypePanel, Panel):
def draw(self, context):
layout = self.layout
+ layout.use_property_split = True
+ flow = layout.grid_flow(row_major=True, columns=0, even_columns=True, even_rows=False, align=True)
tex = context.texture
- layout.prop(tex, "noise_distortion")
- layout.prop(tex, "noise_basis", text="Basis")
+ col = flow.column()
+ col.prop(tex, "noise_basis", text="Noise Basis")
- split = layout.split()
+ col.separator()
- col = split.column()
- col.prop(tex, "distortion", text="Distortion")
- col.prop(tex, "noise_scale", text="Size")
+ col.prop(tex, "noise_distortion", text="Distortion")
- split.prop(tex, "nabla")
+ col.separator()
+
+ col = flow.column()
+ col.prop(tex, "distortion", text="Amount")
+ col.prop(tex, "noise_scale", text="Size")
+ col.prop(tex, "nabla")
class TextureSlotPanel(TextureButtonsPanel):
@@ -595,68 +718,64 @@ class TEXTURE_PT_mapping(TextureSlotPanel, Panel):
def draw(self, context):
layout = self.layout
+ layout.use_property_split = True
+ flow = layout.grid_flow(row_major=False, columns=0, even_columns=True, even_rows=False, align=True)
idblock = context_tex_datablock(context)
tex = context.texture_slot
- if not isinstance(idblock, Brush):
- split = layout.split(percentage=0.3)
- col = split.column()
- col.label(text="Coordinates:")
- col = split.column()
- col.prop(tex, "texture_coords", text="")
+ if isinstance(idblock, Brush):
+ if context.sculpt_object or context.image_paint_object:
+ brush_texture_settings(layout, idblock, context.sculpt_object)
+ else:
+ col = flow.column()
- if tex.texture_coords == 'ORCO':
- """
- ob = context.object
- if ob and ob.type == 'MESH':
- split = layout.split(percentage=0.3)
- split.label(text="Mesh:")
- split.prop(ob.data, "texco_mesh", text="")
- """
- elif tex.texture_coords == 'UV':
- split = layout.split(percentage=0.3)
- split.label(text="Map:")
+ col.prop(tex, "texture_coords", text="Coordinates")
+
+ # Note: the ORCO case used to call ob.data, "texco_mesh" prop.
+ if tex.texture_coords == 'UV':
ob = context.object
+
if ob and ob.type == 'MESH':
- split.prop_search(tex, "uv_layer", ob.data, "uv_layers", text="")
+ # Note: TODO prop_search doesn't align on the right.
+ row = col.row(align=True)
+ row.prop_search(tex, "uv_layer", ob.data, "uv_layers", text="Map")
+ row.label(text="", icon='BLANK1')
else:
- split.prop(tex, "uv_layer", text="")
+ col.prop(tex, "uv_layer", text="Map")
elif tex.texture_coords == 'OBJECT':
- split = layout.split(percentage=0.3)
- split.label(text="Object:")
- split.prop(tex, "object", text="")
+ col.prop(tex, "object", text="Object")
elif tex.texture_coords == 'ALONG_STROKE':
- split = layout.split(percentage=0.3)
- split.label(text="Use Tips:")
- split.prop(tex, "use_tips", text="")
+ col.prop(tex, "use_tips", text="Use Tips")
+
+ col.separator()
- if isinstance(idblock, Brush):
- if context.sculpt_object or context.image_paint_object:
- brush_texture_settings(layout, idblock, context.sculpt_object)
- else:
if isinstance(idblock, FreestyleLineStyle):
- split = layout.split(percentage=0.3)
- split.label(text="Projection:")
- split.prop(tex, "mapping", text="")
+ col = flow.column()
+ col.prop(tex, "mapping", text="Projection")
+
+ col.separator()
+
+ col = flow.column()
+ col.prop(tex, "mapping_x", text="Mapping X")
+ col.prop(tex, "mapping_y", text="Y")
+ col.prop(tex, "mapping_z", text="Z")
- split = layout.split(percentage=0.3)
- split.separator()
- row = split.row()
- row.prop(tex, "mapping_x", text="")
- row.prop(tex, "mapping_y", text="")
- row.prop(tex, "mapping_z", text="")
+ col.separator()
- row = layout.row()
- row.column().prop(tex, "offset")
- row.column().prop(tex, "scale")
+ col = flow.column(align=True)
+ col.column().prop(tex, "offset")
+
+ col = flow.column(align=True)
+ col.column().prop(tex, "scale")
class TEXTURE_PT_influence(TextureSlotPanel, Panel):
bl_label = "Influence"
+ bl_options = {'DEFAULT_CLOSED'}
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'}
@classmethod
@@ -672,107 +791,126 @@ class TEXTURE_PT_influence(TextureSlotPanel, Panel):
return (engine in cls.COMPAT_ENGINES)
def draw(self, context):
-
layout = self.layout
+ layout.use_property_split = True
+ flow = layout.grid_flow(row_major=False, columns=0, even_columns=False, even_rows=False, align=False)
idblock = context_tex_datablock(context)
-
tex = context.texture_slot
def factor_but(layout, toggle, factor, name):
row = layout.row(align=True)
- row.prop(tex, toggle, text="")
+ row.active = getattr(tex, toggle)
+
+ row.prop(tex, factor, text=name, slider=True)
sub = row.row(align=True)
- sub.active = getattr(tex, toggle)
- sub.prop(tex, factor, text=name, slider=True)
+ sub.prop(tex, toggle, text="")
return sub # XXX, temp. use_map_normal needs to override.
if isinstance(idblock, ParticleSettings):
- split = layout.split()
-
- col = split.column()
- col.label(text="General:")
- factor_but(col, "use_map_time", "time_factor", "Time")
+ col = flow.column()
+ factor_but(col, "use_map_time", "time_factor", "General Time")
factor_but(col, "use_map_life", "life_factor", "Lifetime")
factor_but(col, "use_map_density", "density_factor", "Density")
factor_but(col, "use_map_size", "size_factor", "Size")
- col = split.column()
- col.label(text="Physics:")
- factor_but(col, "use_map_velocity", "velocity_factor", "Velocity")
+ col.separator()
+
+ col = flow.column()
+ factor_but(col, "use_map_velocity", "velocity_factor", "Physics Velocity")
factor_but(col, "use_map_damp", "damp_factor", "Damp")
factor_but(col, "use_map_gravity", "gravity_factor", "Gravity")
factor_but(col, "use_map_field", "field_factor", "Force Fields")
- layout.label(text="Hair:")
-
- split = layout.split()
+ col.separator()
- col = split.column()
- factor_but(col, "use_map_length", "length_factor", "Length")
+ col = flow.column()
+ factor_but(col, "use_map_length", "length_factor", "Hair Length")
factor_but(col, "use_map_clump", "clump_factor", "Clump")
factor_but(col, "use_map_twist", "twist_factor", "Twist")
- col = split.column()
+ col = flow.column()
factor_but(col, "use_map_kink_amp", "kink_amp_factor", "Kink Amplitude")
factor_but(col, "use_map_kink_freq", "kink_freq_factor", "Kink Frequency")
factor_but(col, "use_map_rough", "rough_factor", "Rough")
elif isinstance(idblock, FreestyleLineStyle):
- split = layout.split()
-
- col = split.column()
+ col = flow.column()
factor_but(col, "use_map_color_diffuse", "diffuse_color_factor", "Color")
- col = split.column()
factor_but(col, "use_map_alpha", "alpha_factor", "Alpha")
- layout.separator()
-
if not isinstance(idblock, ParticleSettings):
- split = layout.split()
+ col = flow.column()
- col = split.column()
col.prop(tex, "blend_type", text="Blend")
col.prop(tex, "use_rgb_to_intensity")
+
# color is used on gray-scale textures even when use_rgb_to_intensity is disabled.
col.prop(tex, "color", text="")
- col = split.column()
+ col = flow.column()
col.prop(tex, "invert", text="Negative")
col.prop(tex, "use_stencil")
-class TEXTURE_PT_colors(TextureButtonsPanel, Panel):
- bl_label = "Colors"
- bl_options = {'DEFAULT_CLOSED'}
- COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'}
-
+class TextureColorsPoll:
@classmethod
def poll(cls, context):
tex = context.texture
return tex and (tex.type != 'NONE' or tex.use_nodes) and (context.engine in cls.COMPAT_ENGINES)
+
+class TEXTURE_PT_colors(TextureButtonsPanel, TextureColorsPoll, Panel):
+ bl_label = "Colors"
+ bl_options = {'DEFAULT_CLOSED'}
+ COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'}
+
def draw(self, context):
layout = self.layout
layout.use_property_split = True
+ flow = layout.grid_flow(row_major=False, columns=0, even_columns=False, even_rows=False, align=False)
tex = context.texture
- col = layout.column()
- sub = col.column(align=True)
- sub.prop(tex, "factor_red", text="Multiply R")
- sub.prop(tex, "factor_green", text="G")
- sub.prop(tex, "factor_blue", text="B")
+ col = flow.column()
+ col.prop(tex, "use_clamp", text="Clamp")
+
+ col = flow.column(align=True)
+ col.prop(tex, "factor_red", text="Multiply R")
+ col.prop(tex, "factor_green", text="G")
+ col.prop(tex, "factor_blue", text="B")
+ col.separator()
+
+ col = flow.column()
col.prop(tex, "intensity")
col.prop(tex, "contrast")
col.prop(tex, "saturation")
- col.prop(tex, "use_clamp", text="Clamp")
- col.prop(tex, "use_color_ramp", text="Ramp")
- if tex.use_color_ramp:
- layout.use_property_split = False
+
+class TEXTURE_PT_colors_ramp(TextureButtonsPanel, TextureColorsPoll, Panel):
+ bl_label = "Color Ramp"
+ bl_options = {'DEFAULT_CLOSED'}
+ bl_parent_id = 'TEXTURE_PT_colors'
+ COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_OPENGL'}
+
+ def draw_header(self, context):
+ tex = context.texture
+ self.layout.prop(tex, "use_color_ramp", text="")
+
+ def draw(self, context):
+ layout = self.layout
+
+ tex = context.texture
+
+ # Note: TODO after creation of a new texture, the template_color_ramp will be blank.
+ # Possibly needs to be fixed in the template itself.
+ is_active = bool(tex and tex.use_color_ramp)
+ if is_active:
layout.template_color_ramp(tex, "color_ramp", expand=True)
+ else:
+ layout.alignment = 'RIGHT'
+ layout.label("Please enable the Color Ramp first")
class TEXTURE_PT_custom_props(TextureButtonsPanel, PropertyPanel, Panel):
@@ -792,8 +930,6 @@ classes = (
TEXTURE_PT_context,
TEXTURE_PT_node,
TEXTURE_PT_node_mapping,
- TEXTURE_PT_mapping,
- TEXTURE_PT_influence,
TEXTURE_PT_clouds,
TEXTURE_PT_wood,
TEXTURE_PT_marble,
@@ -801,13 +937,19 @@ classes = (
TEXTURE_PT_blend,
TEXTURE_PT_stucci,
TEXTURE_PT_image,
+ TEXTURE_PT_image_settings,
TEXTURE_PT_image_alpha,
- TEXTURE_PT_image_sampling,
TEXTURE_PT_image_mapping,
+ TEXTURE_PT_image_mapping_crop,
+ TEXTURE_PT_image_sampling,
TEXTURE_PT_musgrave,
TEXTURE_PT_voronoi,
+ TEXTURE_PT_voronoi_feature_weights,
TEXTURE_PT_distortednoise,
+ TEXTURE_PT_influence,
+ TEXTURE_PT_mapping,
TEXTURE_PT_colors,
+ TEXTURE_PT_colors_ramp,
TEXTURE_PT_custom_props,
)
diff --git a/release/scripts/startup/bl_ui/space_filebrowser.py b/release/scripts/startup/bl_ui/space_filebrowser.py
index 9d903829bbb..a85dd591b2f 100644
--- a/release/scripts/startup/bl_ui/space_filebrowser.py
+++ b/release/scripts/startup/bl_ui/space_filebrowser.py
@@ -56,6 +56,8 @@ class FILEBROWSER_HT_header(Header):
layout.separator_spacer()
+ layout.template_running_jobs()
+
if params:
layout.prop(params, "use_filter", text="", icon='FILTER')
@@ -86,8 +88,6 @@ class FILEBROWSER_HT_header(Header):
row.separator()
row.prop(params, "filter_search", text="", icon='VIEWZOOM')
- layout.template_running_jobs()
-
class FILEBROWSER_UL_dir(UIList):
def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index):
diff --git a/release/scripts/startup/bl_ui/space_node.py b/release/scripts/startup/bl_ui/space_node.py
index 9d8c14ba9c3..45343c09b27 100644
--- a/release/scripts/startup/bl_ui/space_node.py
+++ b/release/scripts/startup/bl_ui/space_node.py
@@ -364,7 +364,6 @@ class NODE_PT_active_node_generic(Panel):
bl_space_type = 'NODE_EDITOR'
bl_region_type = 'UI'
bl_label = "Node"
-# bl_options = {'HIDE_HEADER'}
@classmethod
def poll(cls, context):
@@ -383,6 +382,7 @@ class NODE_PT_active_node_color(Panel):
bl_region_type = 'UI'
bl_label = "Color"
bl_options = {'DEFAULT_CLOSED'}
+ bl_parent_id = 'NODE_PT_active_node_generic'
@classmethod
def poll(cls, context):
@@ -410,6 +410,8 @@ class NODE_PT_active_node_properties(Panel):
bl_space_type = 'NODE_EDITOR'
bl_region_type = 'UI'
bl_label = "Properties"
+ bl_options = {'DEFAULT_CLOSED'}
+ bl_parent_id = 'NODE_PT_active_node_generic'
@classmethod
def poll(cls, context):
@@ -453,18 +455,22 @@ class NODE_PT_backdrop(Panel):
def draw(self, context):
layout = self.layout
+ layout.use_property_split = True
snode = context.space_data
layout.active = snode.show_backdrop
- layout.prop(snode, "backdrop_channels", text="")
- layout.prop(snode, "backdrop_zoom", text="Zoom")
- col = layout.column(align=True)
- col.label(text="Offset:")
- col.prop(snode, "backdrop_offset", text="")
- col.operator("node.backimage_move", text="Move")
+ col = layout.column()
+
+ col.prop(snode, "backdrop_channels", text="Channels")
+ col.prop(snode, "backdrop_zoom", text="Zoom")
- layout.operator("node.backimage_fit", text="Fit")
+ col.prop(snode, "backdrop_offset", text="Offset")
+
+ col.separator()
+
+ col.operator("node.backimage_move", text="Move")
+ col.operator("node.backimage_fit", text="Fit")
class NODE_PT_quality(bpy.types.Panel):
@@ -479,6 +485,7 @@ class NODE_PT_quality(bpy.types.Panel):
def draw(self, context):
layout = self.layout
+ layout.use_property_split = True
snode = context.space_data
tree = snode.node_tree
@@ -522,6 +529,7 @@ class NODE_UL_interface_sockets(bpy.types.UIList):
class NODE_PT_grease_pencil(GreasePencilDataPanel, Panel):
bl_space_type = 'NODE_EDITOR'
bl_region_type = 'UI'
+ bl_options = {'DEFAULT_CLOSED'}
# NOTE: this is just a wrapper around the generic GP Panel
diff --git a/release/scripts/startup/bl_ui/space_outliner.py b/release/scripts/startup/bl_ui/space_outliner.py
index 8f722c4d3ce..20ef5ae0c53 100644
--- a/release/scripts/startup/bl_ui/space_outliner.py
+++ b/release/scripts/startup/bl_ui/space_outliner.py
@@ -142,8 +142,15 @@ class OUTLINER_MT_collection_view_layer(Menu):
space = context.space_data
- layout.operator("outliner.collection_exclude_set", text="Exclude")
- layout.operator("outliner.collection_include_set", text="Include")
+ layout.operator("outliner.collection_exclude_set")
+ layout.operator("outliner.collection_exclude_clear")
+
+ if context.engine == 'CYCLES':
+ layout.operator("outliner.collection_indirect_only_set")
+ layout.operator("outliner.collection_indirect_only_clear")
+
+ layout.operator("outliner.collection_holdout_set")
+ layout.operator("outliner.collection_holdout_clear")
class OUTLINER_MT_collection(Menu):
diff --git a/release/scripts/startup/bl_ui/space_topbar.py b/release/scripts/startup/bl_ui/space_topbar.py
index 96ef2e51e60..55129aa0ce1 100644
--- a/release/scripts/startup/bl_ui/space_topbar.py
+++ b/release/scripts/startup/bl_ui/space_topbar.py
@@ -265,8 +265,8 @@ class INFO_MT_file(Menu):
layout.separator()
layout.operator_context = 'INVOKE_AREA'
- layout.operator("wm.link", text="Link", icon='LINK_BLEND')
- layout.operator("wm.append", text="Append", icon='APPEND_BLEND')
+ layout.operator("wm.link", text="Link...", icon='LINK_BLEND')
+ layout.operator("wm.append", text="Append...", icon='APPEND_BLEND')
layout.menu("INFO_MT_file_previews")
layout.separator()
@@ -495,12 +495,26 @@ class INFO_MT_help(Menu):
def draw(self, context):
layout = self.layout
+ show_developer = context.user_preferences.view.show_developer_ui
+
layout.operator(
"wm.url_open", text="Manual", icon='HELP',
).url = "https://docs.blender.org/manual/en/dev/"
+
+
layout.operator(
- "wm.url_open", text="Release Log", icon='URL',
- ).url = "http://wiki.blender.org/index.php/Dev:Ref/Release_Notes/%d.%d" % bpy.app.version[:2]
+ "wm.url_open", text="Report a Bug", icon='URL',
+ ).url = "https://developer.blender.org/maniphest/task/edit/form/1"
+
+ layout.separator()
+
+ layout.operator(
+ "wm.url_open", text="User Communities", icon='URL',
+ ).url = "https://www.blender.org/community/"
+ layout.operator(
+ "wm.url_open", text="Developer Community", icon='URL',
+ ).url = "https://www.blender.org/get-involved/developers/"
+
layout.separator()
layout.operator(
@@ -509,24 +523,22 @@ class INFO_MT_help(Menu):
layout.operator(
"wm.url_open", text="Blender Store", icon='URL',
).url = "https://store.blender.org"
+
layout.operator(
- "wm.url_open", text="Developer Community", icon='URL',
- ).url = "https://www.blender.org/get-involved/"
- layout.operator(
- "wm.url_open", text="User Community", icon='URL',
- ).url = "https://www.blender.org/support/user-community"
- layout.separator()
- layout.operator(
- "wm.url_open", text="Report a Bug", icon='URL',
- ).url = "https://developer.blender.org/maniphest/task/edit/form/1"
+ "wm.url_open", text="Release Notes", icon='URL',
+ ).url = "https://www.blender.org/download/releases/%d-%d/" % bpy.app.version[:2]
+
layout.separator()
- layout.operator(
- "wm.url_open", text="Python API Reference", icon='URL',
- ).url = bpy.types.WM_OT_doc_view._prefix
+ if show_developer:
+ layout.operator(
+ "wm.url_open", text="Python API Reference", icon='URL',
+ ).url = bpy.types.WM_OT_doc_view._prefix
+
+ layout.operator("wm.operator_cheat_sheet", icon='TEXT')
+
+ layout.operator("wm.sysinfo")
- layout.operator("wm.operator_cheat_sheet", icon='TEXT')
- layout.operator("wm.sysinfo", icon='TEXT')
layout.separator()
layout.operator("wm.splash", icon='BLENDER')
@@ -539,8 +551,13 @@ class TOPBAR_MT_file_specials(Menu):
layout = self.layout
layout.operator_context = 'INVOKE_AREA'
- layout.operator("wm.link", text="Link", icon='LINK_BLEND')
- layout.operator("wm.append", text="Append", icon='APPEND_BLEND')
+ layout.operator("wm.read_homefile", text="New", icon='NEW')
+ layout.operator("wm.open_mainfile", text="Open...", icon='FILE_FOLDER')
+
+ layout.separator()
+
+ layout.operator("wm.link", text="Link...", icon='LINK_BLEND')
+ layout.operator("wm.append", text="Append...", icon='APPEND_BLEND')
layout.separator()
diff --git a/release/scripts/startup/bl_ui/space_view3d.py b/release/scripts/startup/bl_ui/space_view3d.py
index e8c640721c8..e6d8b1ec2a7 100644
--- a/release/scripts/startup/bl_ui/space_view3d.py
+++ b/release/scripts/startup/bl_ui/space_view3d.py
@@ -453,7 +453,7 @@ class VIEW3D_MT_snap(Menu):
layout.operator("view3d.snap_selected_to_grid", text="Selection to Grid")
layout.operator("view3d.snap_selected_to_cursor", text="Selection to Cursor").use_offset = False
- layout.operator("view3d.snap_selected_to_cursor", text="Selection to Cursor (Offset)").use_offset = True
+ layout.operator("view3d.snap_selected_to_cursor", text="Selection to Cursor (Keep Offset)").use_offset = True
layout.operator("view3d.snap_selected_to_active", text="Selection to Active")
layout.separator()
@@ -3839,10 +3839,14 @@ class VIEW3D_PT_shading_color(Panel):
shading = VIEW3D_PT_shading.get_shading(context)
- layout.row().prop(shading, "color_type", expand=True)
-
+ layout.row().prop(shading, 'color_type', expand=True)
if shading.color_type == 'SINGLE':
- layout.row().prop(shading, "single_color", text="")
+ layout.row().prop(shading, 'single_color', text="")
+
+ layout.row().label("Background")
+ layout.row().prop(shading, 'background_type', expand=True)
+ if shading.background_type == 'VIEWPORT':
+ layout.row().prop(shading, "background_color", text="")
class VIEW3D_PT_shading_options(Panel):
@@ -3912,10 +3916,6 @@ class VIEW3D_PT_shading_options(Panel):
if not shading.light == 'MATCAP':
col.prop(shading, "show_specular_highlight")
- view = context.space_data
- if view.type == 'VIEW_3D':
- col.prop(view, "show_world")
-
class VIEW3D_PT_shading_options_shadow(Panel):
bl_label = "Shadow Settings"
diff --git a/release/scripts/templates_py/batch_export.py b/release/scripts/templates_py/batch_export.py
index 1463915886a..a07491742ec 100644
--- a/release/scripts/templates_py/batch_export.py
+++ b/release/scripts/templates_py/batch_export.py
@@ -9,9 +9,9 @@ basedir = os.path.dirname(bpy.data.filepath)
if not basedir:
raise Exception("Blend file is not saved")
-scene = bpy.context.scene
+view_layer = bpy.context.view_layer
-obj_active = scene.objects.active
+obj_active = view_layer.objects.active
selection = bpy.context.selected_objects
bpy.ops.object.select_all(action='DESELECT')
@@ -21,7 +21,7 @@ for obj in selection:
obj.select_set(action='SELECT')
# some exporters only use the active object
- scene.objects.active = obj
+ view_layer.objects.active = obj
name = bpy.path.clean_name(obj.name)
fn = os.path.join(basedir, name)
@@ -36,7 +36,7 @@ for obj in selection:
print("written:", fn)
-scene.objects.active = obj_active
+view_layer.objects.active = obj_active
for obj in selection:
obj.select_set(action='SELECT')
diff --git a/release/scripts/templates_py/operator_modal_view3d_raycast.py b/release/scripts/templates_py/operator_modal_view3d_raycast.py
index e3b63813fc4..613501143f7 100644
--- a/release/scripts/templates_py/operator_modal_view3d_raycast.py
+++ b/release/scripts/templates_py/operator_modal_view3d_raycast.py
@@ -68,7 +68,7 @@ def main(context, event):
# we could do lots of stuff but for the example just select.
if best_obj is not None:
best_obj.select_set(action='SELECT')
- context.scene.objects.active = best_obj
+ context.view_layer.objects.active = best_obj
class ViewOperatorRayCast(bpy.types.Operator):
diff --git a/source/blender/blenfont/intern/blf_font.c b/source/blender/blenfont/intern/blf_font.c
index ea81106e60f..f7a926275a9 100644
--- a/source/blender/blenfont/intern/blf_font.c
+++ b/source/blender/blenfont/intern/blf_font.c
@@ -133,7 +133,8 @@ void blf_batch_draw_begin(FontBLF *font)
if (simple_shader) {
/* Offset is applied to each glyph. */
- copy_v2_v2(g_batch.ofs, font->pos);
+ g_batch.ofs[0] = floorf(font->pos[0]);
+ g_batch.ofs[1] = floorf(font->pos[1]);
}
else {
/* Offset is baked in modelview mat. */
diff --git a/source/blender/blenfont/intern/blf_glyph.c b/source/blender/blenfont/intern/blf_glyph.c
index 99be8539d24..f7f1e10a480 100644
--- a/source/blender/blenfont/intern/blf_glyph.c
+++ b/source/blender/blenfont/intern/blf_glyph.c
@@ -244,7 +244,7 @@ static void blf_glyph_cache_texture(FontBLF *font, GlyphCacheBLF *gc)
gc->textures[gc->texture_current] = tex;
GPU_texture_bind(tex, 0);
GPU_texture_wrap_mode(tex, false);
- GPU_texture_filters(tex, GPU_NEAREST, GPU_NEAREST);
+ GPU_texture_filters(tex, GPU_NEAREST, GPU_LINEAR);
GPU_texture_unbind(tex);
}
@@ -427,8 +427,8 @@ static void blf_glyph_calc_rect(rctf *rect, GlyphBLF *g, float x, float y)
{
rect->xmin = floorf(x + g->pos_x);
rect->xmax = rect->xmin + (float)g->width;
- rect->ymin = y + g->pos_y;
- rect->ymax = y + g->pos_y - (float)g->height;
+ rect->ymin = floorf(y + g->pos_y);
+ rect->ymax = rect->ymin - (float)g->height;
}
void blf_glyph_render(FontBLF *font, GlyphBLF *g, float x, float y)
diff --git a/source/blender/blenkernel/BKE_blender_version.h b/source/blender/blenkernel/BKE_blender_version.h
index 8707fe3e11b..79ae904c73d 100644
--- a/source/blender/blenkernel/BKE_blender_version.h
+++ b/source/blender/blenkernel/BKE_blender_version.h
@@ -28,7 +28,7 @@
* and keep comment above the defines.
* Use STRINGIFY() rather than defining with quotes */
#define BLENDER_VERSION 280
-#define BLENDER_SUBVERSION 20
+#define BLENDER_SUBVERSION 21
/* Several breakages with 280, e.g. collections vs layers */
#define BLENDER_MINVERSION 280
#define BLENDER_MINSUBVERSION 0
diff --git a/source/blender/blenkernel/BKE_bvhutils.h b/source/blender/blenkernel/BKE_bvhutils.h
index d79a7eae53e..a0780a5be54 100644
--- a/source/blender/blenkernel/BKE_bvhutils.h
+++ b/source/blender/blenkernel/BKE_bvhutils.h
@@ -102,7 +102,7 @@ typedef struct BVHTreeFromMesh {
*/
BVHTree *bvhtree_from_editmesh_verts(
BVHTreeFromEditMesh *data, struct BMEditMesh *em,
- float epsilon, int tree_type, int axis);
+ float epsilon, int tree_type, int axis, BVHCache **bvh_cache);
BVHTree *bvhtree_from_editmesh_verts_ex(
BVHTreeFromEditMesh *data, struct BMEditMesh *em,
const BLI_bitmap *mask, int verts_num_active,
@@ -115,7 +115,7 @@ BVHTree *bvhtree_from_mesh_verts_ex(
BVHTree *bvhtree_from_editmesh_edges(
BVHTreeFromEditMesh *data, struct BMEditMesh *em,
- float epsilon, int tree_type, int axis);
+ float epsilon, int tree_type, int axis, BVHCache **bvh_cache);
BVHTree *bvhtree_from_editmesh_edges_ex(
BVHTreeFromEditMesh *data, struct BMEditMesh *em,
const BLI_bitmap *edges_mask, int edges_num_active,
@@ -190,7 +190,9 @@ enum {
BVHTREE_FROM_LOOSEVERTS = 4,
BVHTREE_FROM_LOOSEEDGES = 5,
- BVHTREE_FROM_EM_LOOPTRI = 6,
+ BVHTREE_FROM_EM_VERTS = 6,
+ BVHTREE_FROM_EM_EDGES = 7,
+ BVHTREE_FROM_EM_LOOPTRI = 8,
};
diff --git a/source/blender/blenkernel/BKE_sequencer.h b/source/blender/blenkernel/BKE_sequencer.h
index 51f61c8352c..00fd4ded8c6 100644
--- a/source/blender/blenkernel/BKE_sequencer.h
+++ b/source/blender/blenkernel/BKE_sequencer.h
@@ -395,7 +395,7 @@ typedef struct SeqLoadInfo {
/* seq_dupli' flags */
-#define SEQ_DUPE_UNIQUE_NAME (1 << 0)
+#define SEQ_DUPE_UNIQUE_NAME (1 << 0) /* WARNING: does NOT work when duplicating Meta strips! */
#define SEQ_DUPE_CONTEXT (1 << 1)
#define SEQ_DUPE_ANIM (1 << 2)
#define SEQ_DUPE_ALL (1 << 3) /* otherwise only selected are copied */
diff --git a/source/blender/blenkernel/BKE_subdiv.h b/source/blender/blenkernel/BKE_subdiv.h
index a1792866255..003dc7a37d3 100644
--- a/source/blender/blenkernel/BKE_subdiv.h
+++ b/source/blender/blenkernel/BKE_subdiv.h
@@ -94,26 +94,6 @@ typedef struct Subdiv {
*/
SubdivSettings settings;
- /* Total number of ptex faces on subdivision level 0.
- *
- * Ptex face is what is internally used by OpenSubdiv for evaluator. It is
- * a quad face, which corresponds to Blender's legacy Catmull Clark grids.
- *
- * Basically, here is a correspondence between polygons and ptex faces:
- * - Triangle consists of 3 PTex faces.
- * - Quad is a single PTex face.
- * - N-gon is N PTex faces.
- *
- * This value is initialized in BKE_subdiv_new_from_FOO() and is read-only
- * after this.
- */
- int num_ptex_faces;
-
- /* Indexed by base face index, element indicates total number of ptex faces
- * created for preceding base faces.
- */
- int *face_ptex_offset;
-
/* Topology refiner includes all the glue logic to feed Blender side
* topology to OpenSubdiv. It can be shared by both evaluator and GL mesh
* drawer.
diff --git a/source/blender/blenkernel/intern/anim.c b/source/blender/blenkernel/intern/anim.c
index eed8943cd5b..a867accfe44 100644
--- a/source/blender/blenkernel/intern/anim.c
+++ b/source/blender/blenkernel/intern/anim.c
@@ -99,6 +99,8 @@ void animviz_settings_init(bAnimVizSettings *avs)
avs->path_viewflag = (MOTIONPATH_VIEW_KFRAS | MOTIONPATH_VIEW_KFNOS);
avs->path_step = 1;
+
+ avs->path_bakeflag |= MOTIONPATH_BAKE_HEADS;
}
/* ------------------- */
diff --git a/source/blender/blenkernel/intern/bvhutils.c b/source/blender/blenkernel/intern/bvhutils.c
index 1a7c4e2a4a0..19ac81b4bb7 100644
--- a/source/blender/blenkernel/intern/bvhutils.c
+++ b/source/blender/blenkernel/intern/bvhutils.c
@@ -495,12 +495,39 @@ BVHTree *bvhtree_from_editmesh_verts_ex(
BVHTree *bvhtree_from_editmesh_verts(
BVHTreeFromEditMesh *data, BMEditMesh *em,
- float epsilon, int tree_type, int axis)
+ float epsilon, int tree_type, int axis, BVHCache **bvh_cache)
{
- return bvhtree_from_editmesh_verts_ex(
- data, em,
- NULL, -1,
- epsilon, tree_type, axis);
+ if (bvh_cache) {
+ BLI_rw_mutex_lock(&cache_rwlock, THREAD_LOCK_READ);
+ data->cached = bvhcache_find(*bvh_cache, BVHTREE_FROM_EM_VERTS, &data->tree);
+ BLI_rw_mutex_unlock(&cache_rwlock);
+
+ if (data->cached == false) {
+ BLI_rw_mutex_lock(&cache_rwlock, THREAD_LOCK_WRITE);
+ data->cached = bvhcache_find(
+ *bvh_cache, BVHTREE_FROM_EM_VERTS, &data->tree);
+ if (data->cached == false) {
+ data->tree = bvhtree_from_editmesh_verts_ex(
+ data, em,
+ NULL, -1,
+ epsilon, tree_type, axis);
+
+ /* Save on cache for later use */
+ /* printf("BVHTree built and saved on cache\n"); */
+ bvhcache_insert(
+ bvh_cache, data->tree, BVHTREE_FROM_EM_VERTS);
+ }
+ BLI_rw_mutex_unlock(&cache_rwlock);
+ }
+ }
+ else {
+ data->tree = bvhtree_from_editmesh_verts_ex(
+ data, em,
+ NULL, -1,
+ epsilon, tree_type, axis);
+ }
+
+ return data->tree;
}
/**
@@ -649,12 +676,39 @@ BVHTree *bvhtree_from_editmesh_edges_ex(
BVHTree *bvhtree_from_editmesh_edges(
BVHTreeFromEditMesh *data, BMEditMesh *em,
- float epsilon, int tree_type, int axis)
+ float epsilon, int tree_type, int axis, BVHCache **bvh_cache)
{
- return bvhtree_from_editmesh_edges_ex(
- data, em,
- NULL, -1,
- epsilon, tree_type, axis);
+ if (bvh_cache) {
+ BLI_rw_mutex_lock(&cache_rwlock, THREAD_LOCK_READ);
+ data->cached = bvhcache_find(*bvh_cache, BVHTREE_FROM_EM_EDGES, &data->tree);
+ BLI_rw_mutex_unlock(&cache_rwlock);
+
+ if (data->cached == false) {
+ BLI_rw_mutex_lock(&cache_rwlock, THREAD_LOCK_WRITE);
+ data->cached = bvhcache_find(
+ *bvh_cache, BVHTREE_FROM_EM_EDGES, &data->tree);
+ if (data->cached == false) {
+ data->tree = bvhtree_from_editmesh_edges_ex(
+ data, em,
+ NULL, -1,
+ epsilon, tree_type, axis);
+
+ /* Save on cache for later use */
+ /* printf("BVHTree built and saved on cache\n"); */
+ bvhcache_insert(
+ bvh_cache, data->tree, BVHTREE_FROM_EM_EDGES);
+ }
+ BLI_rw_mutex_unlock(&cache_rwlock);
+ }
+ }
+ else {
+ data->tree = bvhtree_from_editmesh_edges_ex(
+ data, em,
+ NULL, -1,
+ epsilon, tree_type, axis);
+ }
+
+ return data->tree;
}
/**
@@ -1407,6 +1461,11 @@ BVHTree *BKE_bvhtree_from_mesh_get(
BLI_rw_mutex_unlock(&cache_rwlock);
}
break;
+ case BVHTREE_FROM_EM_VERTS:
+ case BVHTREE_FROM_EM_EDGES:
+ case BVHTREE_FROM_EM_LOOPTRI:
+ BLI_assert(false);
+ break;
}
if (data_cp.tree != NULL) {
diff --git a/source/blender/blenkernel/intern/camera.c b/source/blender/blenkernel/intern/camera.c
index 4203e0455f8..1b5995de4f0 100644
--- a/source/blender/blenkernel/intern/camera.c
+++ b/source/blender/blenkernel/intern/camera.c
@@ -70,12 +70,15 @@ void BKE_camera_init(Camera *cam)
cam->sensor_x = DEFAULT_SENSOR_WIDTH;
cam->sensor_y = DEFAULT_SENSOR_HEIGHT;
cam->clipsta = 0.1f;
- cam->clipend = 100.0f;
+ cam->clipend = 1000.0f;
cam->drawsize = 0.5f;
cam->ortho_scale = 6.0;
cam->flag |= CAM_SHOWPASSEPARTOUT;
cam->passepartalpha = 0.5f;
+ cam->gpu_dof.fstop = 128.0f;
+ cam->gpu_dof.ratio = 1.0f;
+
/* stereoscopy 3d */
cam->stereo.interocular_distance = 0.065f;
cam->stereo.convergence_distance = 30.f * 0.065f;
diff --git a/source/blender/blenkernel/intern/layer.c b/source/blender/blenkernel/intern/layer.c
index 2f5c8e7817e..1396ad1f97c 100644
--- a/source/blender/blenkernel/intern/layer.c
+++ b/source/blender/blenkernel/intern/layer.c
@@ -715,6 +715,14 @@ static int layer_collection_sync(
lc->runtime_flag |= LAYER_COLLECTION_HAS_VISIBLE_OBJECTS;
}
+ /* Holdout and indirect only */
+ if (lc->flag & LAYER_COLLECTION_HOLDOUT) {
+ base->flag |= BASE_HOLDOUT;
+ }
+ if (lc->flag & LAYER_COLLECTION_INDIRECT_ONLY) {
+ base->flag |= BASE_INDIRECT_ONLY;
+ }
+
lc->runtime_flag |= LAYER_COLLECTION_HAS_OBJECTS;
}
@@ -750,7 +758,13 @@ void BKE_layer_collection_sync(const Scene *scene, ViewLayer *view_layer)
/* Clear visible and selectable flags to be reset. */
for (Base *base = view_layer->object_bases.first; base; base = base->next) {
- base->flag &= ~(BASE_VISIBLE | BASE_ENABLED | BASE_SELECTABLE | BASE_ENABLED_VIEWPORT | BASE_ENABLED_RENDER);
+ base->flag &= ~(BASE_VISIBLE |
+ BASE_ENABLED |
+ BASE_SELECTABLE |
+ BASE_ENABLED_VIEWPORT |
+ BASE_ENABLED_RENDER |
+ BASE_HOLDOUT |
+ BASE_INDIRECT_ONLY);
}
view_layer->runtime_flag = 0;
diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c
index 33ea13c9a38..1d6b23ce7f7 100644
--- a/source/blender/blenkernel/intern/object.c
+++ b/source/blender/blenkernel/intern/object.c
@@ -1204,7 +1204,6 @@ void BKE_object_copy_data(Main *bmain, Object *ob_dst, const Object *ob_src, con
ob_dst->derivedDeform = NULL;
ob_dst->derivedFinal = NULL;
- BLI_listbase_clear(&ob_dst->gpulamp);
BLI_listbase_clear((ListBase *)&ob_dst->drawdata);
BLI_listbase_clear(&ob_dst->pc_ids);
diff --git a/source/blender/blenkernel/intern/particle_system.c b/source/blender/blenkernel/intern/particle_system.c
index 35c8761f671..cee1c9147b5 100644
--- a/source/blender/blenkernel/intern/particle_system.c
+++ b/source/blender/blenkernel/intern/particle_system.c
@@ -2941,7 +2941,7 @@ static void psys_update_path_cache(ParticleSimulationData *sim, float cfra, cons
skip = 1; /* only hair, keyed and baked stuff can have paths */
else if (part->ren_as != PART_DRAW_PATH && !(part->type==PART_HAIR && ELEM(part->ren_as, PART_DRAW_OB, PART_DRAW_GR)))
skip = 1; /* particle visualization must be set as path */
- else {
+ else if (DEG_get_mode(sim->depsgraph) != DAG_EVAL_RENDER) {
if (part->draw_as != PART_DRAW_REND)
skip = 1; /* draw visualization */
else if (psys->pointcache->flag & PTCACHE_BAKING)
diff --git a/source/blender/blenkernel/intern/rigidbody.c b/source/blender/blenkernel/intern/rigidbody.c
index 59847b28785..e6b8312734f 100644
--- a/source/blender/blenkernel/intern/rigidbody.c
+++ b/source/blender/blenkernel/intern/rigidbody.c
@@ -716,6 +716,35 @@ static void rigidbody_validate_sim_object(RigidBodyWorld *rbw, Object *ob, bool
/* --------------------- */
+static void rigidbody_constraint_init_spring(
+ RigidBodyCon *rbc, void (*set_spring)(rbConstraint*,int,int),
+ void (*set_stiffness)(rbConstraint*,int,float), void (*set_damping)(rbConstraint*,int,float)
+) {
+ set_spring(rbc->physics_constraint, RB_LIMIT_LIN_X, rbc->flag & RBC_FLAG_USE_SPRING_X);
+ set_stiffness(rbc->physics_constraint, RB_LIMIT_LIN_X, rbc->spring_stiffness_x);
+ set_damping(rbc->physics_constraint, RB_LIMIT_LIN_X, rbc->spring_damping_x);
+
+ set_spring(rbc->physics_constraint, RB_LIMIT_LIN_Y, rbc->flag & RBC_FLAG_USE_SPRING_Y);
+ set_stiffness(rbc->physics_constraint, RB_LIMIT_LIN_Y, rbc->spring_stiffness_y);
+ set_damping(rbc->physics_constraint, RB_LIMIT_LIN_Y, rbc->spring_damping_y);
+
+ set_spring(rbc->physics_constraint, RB_LIMIT_LIN_Z, rbc->flag & RBC_FLAG_USE_SPRING_Z);
+ set_stiffness(rbc->physics_constraint, RB_LIMIT_LIN_Z, rbc->spring_stiffness_z);
+ set_damping(rbc->physics_constraint, RB_LIMIT_LIN_Z, rbc->spring_damping_z);
+
+ set_spring(rbc->physics_constraint, RB_LIMIT_ANG_X, rbc->flag & RBC_FLAG_USE_SPRING_ANG_X);
+ set_stiffness(rbc->physics_constraint, RB_LIMIT_ANG_X, rbc->spring_stiffness_ang_x);
+ set_damping(rbc->physics_constraint, RB_LIMIT_ANG_X, rbc->spring_damping_ang_x);
+
+ set_spring(rbc->physics_constraint, RB_LIMIT_ANG_Y, rbc->flag & RBC_FLAG_USE_SPRING_ANG_Y);
+ set_stiffness(rbc->physics_constraint, RB_LIMIT_ANG_Y, rbc->spring_stiffness_ang_y);
+ set_damping(rbc->physics_constraint, RB_LIMIT_ANG_Y, rbc->spring_damping_ang_y);
+
+ set_spring(rbc->physics_constraint, RB_LIMIT_ANG_Z, rbc->flag & RBC_FLAG_USE_SPRING_ANG_Z);
+ set_stiffness(rbc->physics_constraint, RB_LIMIT_ANG_Z, rbc->spring_stiffness_ang_z);
+ set_damping(rbc->physics_constraint, RB_LIMIT_ANG_Z, rbc->spring_damping_ang_z);
+}
+
static void rigidbody_constraint_set_limits(
RigidBodyCon *rbc, void (*set_limits)(rbConstraint *, int, float, float))
{
@@ -841,35 +870,24 @@ static void rigidbody_validate_sim_constraint(RigidBodyWorld *rbw, Object *ob, b
RB_constraint_set_limits_piston(rbc->physics_constraint, lin_lower, lin_upper, ang_lower, ang_upper);
break;
case RBC_TYPE_6DOF_SPRING:
- rbc->physics_constraint = RB_constraint_new_6dof_spring(loc, rot, rb1, rb2);
-
- RB_constraint_set_spring_6dof_spring(rbc->physics_constraint, RB_LIMIT_LIN_X, rbc->flag & RBC_FLAG_USE_SPRING_X);
- RB_constraint_set_stiffness_6dof_spring(rbc->physics_constraint, RB_LIMIT_LIN_X, rbc->spring_stiffness_x);
- RB_constraint_set_damping_6dof_spring(rbc->physics_constraint, RB_LIMIT_LIN_X, rbc->spring_damping_x);
-
- RB_constraint_set_spring_6dof_spring(rbc->physics_constraint, RB_LIMIT_LIN_Y, rbc->flag & RBC_FLAG_USE_SPRING_Y);
- RB_constraint_set_stiffness_6dof_spring(rbc->physics_constraint, RB_LIMIT_LIN_Y, rbc->spring_stiffness_y);
- RB_constraint_set_damping_6dof_spring(rbc->physics_constraint, RB_LIMIT_LIN_Y, rbc->spring_damping_y);
+ if (rbc->spring_type == RBC_SPRING_TYPE2) {
+ rbc->physics_constraint = RB_constraint_new_6dof_spring2(loc, rot, rb1, rb2);
- RB_constraint_set_spring_6dof_spring(rbc->physics_constraint, RB_LIMIT_LIN_Z, rbc->flag & RBC_FLAG_USE_SPRING_Z);
- RB_constraint_set_stiffness_6dof_spring(rbc->physics_constraint, RB_LIMIT_LIN_Z, rbc->spring_stiffness_z);
- RB_constraint_set_damping_6dof_spring(rbc->physics_constraint, RB_LIMIT_LIN_Z, rbc->spring_damping_z);
+ rigidbody_constraint_init_spring(rbc, RB_constraint_set_spring_6dof_spring2, RB_constraint_set_stiffness_6dof_spring2, RB_constraint_set_damping_6dof_spring2);
- RB_constraint_set_spring_6dof_spring(rbc->physics_constraint, RB_LIMIT_ANG_X, rbc->flag & RBC_FLAG_USE_SPRING_ANG_X);
- RB_constraint_set_stiffness_6dof_spring(rbc->physics_constraint, RB_LIMIT_ANG_X, rbc->spring_stiffness_ang_x);
- RB_constraint_set_damping_6dof_spring(rbc->physics_constraint, RB_LIMIT_ANG_X, rbc->spring_damping_ang_x);
+ RB_constraint_set_equilibrium_6dof_spring2(rbc->physics_constraint);
- RB_constraint_set_spring_6dof_spring(rbc->physics_constraint, RB_LIMIT_ANG_Y, rbc->flag & RBC_FLAG_USE_SPRING_ANG_Y);
- RB_constraint_set_stiffness_6dof_spring(rbc->physics_constraint, RB_LIMIT_ANG_Y, rbc->spring_stiffness_ang_y);
- RB_constraint_set_damping_6dof_spring(rbc->physics_constraint, RB_LIMIT_ANG_Y, rbc->spring_damping_ang_y);
+ rigidbody_constraint_set_limits(rbc, RB_constraint_set_limits_6dof_spring2);
+ }
+ else {
+ rbc->physics_constraint = RB_constraint_new_6dof_spring(loc, rot, rb1, rb2);
- RB_constraint_set_spring_6dof_spring(rbc->physics_constraint, RB_LIMIT_ANG_Z, rbc->flag & RBC_FLAG_USE_SPRING_ANG_Z);
- RB_constraint_set_stiffness_6dof_spring(rbc->physics_constraint, RB_LIMIT_ANG_Z, rbc->spring_stiffness_ang_z);
- RB_constraint_set_damping_6dof_spring(rbc->physics_constraint, RB_LIMIT_ANG_Z, rbc->spring_damping_ang_z);
+ rigidbody_constraint_init_spring(rbc, RB_constraint_set_spring_6dof_spring, RB_constraint_set_stiffness_6dof_spring, RB_constraint_set_damping_6dof_spring);
- RB_constraint_set_equilibrium_6dof_spring(rbc->physics_constraint);
+ RB_constraint_set_equilibrium_6dof_spring(rbc->physics_constraint);
- rigidbody_constraint_set_limits(rbc, RB_constraint_set_limits_6dof_spring);
+ rigidbody_constraint_set_limits(rbc, RB_constraint_set_limits_6dof);
+ }
break;
case RBC_TYPE_6DOF:
rbc->physics_constraint = RB_constraint_new_6dof(loc, rot, rb1, rb2);
@@ -1094,6 +1112,8 @@ RigidBodyCon *BKE_rigidbody_create_constraint(Scene *scene, Object *ob, short ty
rbc->flag |= RBC_FLAG_ENABLED;
rbc->flag |= RBC_FLAG_DISABLE_COLLISIONS;
+ rbc->spring_type = RBC_SPRING_TYPE2;
+
rbc->breaking_threshold = 10.0f; /* no good default here, just use 10 for now */
rbc->num_solver_iterations = 10; /* 10 is Bullet default */
diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c
index 3650fa21c1c..0574eef1a0f 100644
--- a/source/blender/blenkernel/intern/scene.c
+++ b/source/blender/blenkernel/intern/scene.c
@@ -878,7 +878,6 @@ void BKE_scene_init(Scene *sce)
sce->eevee.flag =
SCE_EEVEE_VOLUMETRIC_LIGHTS |
- SCE_EEVEE_VOLUMETRIC_COLORED |
SCE_EEVEE_GTAO_BENT_NORMALS |
SCE_EEVEE_GTAO_BOUNCE |
SCE_EEVEE_TAA_REPROJECTION |
diff --git a/source/blender/blenkernel/intern/screen.c b/source/blender/blenkernel/intern/screen.c
index f8d926a13ed..c107bb04e6e 100644
--- a/source/blender/blenkernel/intern/screen.c
+++ b/source/blender/blenkernel/intern/screen.c
@@ -869,6 +869,7 @@ void BKE_screen_view3d_shading_init(View3DShading *shading)
shading->cavity_valley_factor = 1.0f;
shading->cavity_ridge_factor = 1.0f;
copy_v3_fl(shading->single_color, 0.8f);
+ copy_v3_fl(shading->background_color, 0.05f);
}
/* magic zoom calculation, no idea what
diff --git a/source/blender/blenkernel/intern/sequencer.c b/source/blender/blenkernel/intern/sequencer.c
index d857db7e276..b5b4ec5cd41 100644
--- a/source/blender/blenkernel/intern/sequencer.c
+++ b/source/blender/blenkernel/intern/sequencer.c
@@ -5530,6 +5530,7 @@ static Sequence *seq_dupli(const Scene *scene_src, Scene *scene_dst, Sequence *s
if (scene_src == scene_dst) {
if (dupe_flag & SEQ_DUPE_UNIQUE_NAME) {
+ /* TODO this is broken in case of Meta strips recursive duplication... Not trivial to fix. */
BKE_sequence_base_unique_name_recursive(&scene_dst->ed->seqbase, seqn);
}
diff --git a/source/blender/blenkernel/intern/subdiv.c b/source/blender/blenkernel/intern/subdiv.c
index 794da2d3477..d8e0c517d91 100644
--- a/source/blender/blenkernel/intern/subdiv.c
+++ b/source/blender/blenkernel/intern/subdiv.c
@@ -42,23 +42,6 @@
# include "opensubdiv_topology_refiner_capi.h"
#endif
-#ifdef WITH_OPENSUBDIV
-static void update_subdiv_after_topology_change(Subdiv *subdiv)
-{
- /* Count ptex faces. */
- subdiv->num_ptex_faces = subdiv->topology_refiner->getNumPtexFaces(
- subdiv->topology_refiner);
- /* Initialize offset of base faces in ptex indices. */
- MEM_SAFE_FREE(subdiv->face_ptex_offset);
- subdiv->face_ptex_offset = MEM_malloc_arrayN(subdiv->num_ptex_faces,
- sizeof(int),
- "subdiv ptex offset");
- subdiv->topology_refiner->fillFacePtexIndexOffset(
- subdiv->topology_refiner,
- subdiv->face_ptex_offset);
-}
-#endif
-
Subdiv *BKE_subdiv_new_from_converter(const SubdivSettings *settings,
struct OpenSubdiv_Converter *converter)
{
@@ -79,7 +62,6 @@ Subdiv *BKE_subdiv_new_from_converter(const SubdivSettings *settings,
subdiv->settings = *settings;
subdiv->topology_refiner = osd_topology_refiner;
subdiv->evaluator = NULL;
- update_subdiv_after_topology_change(subdiv);
BKE_subdiv_stats_end(&stats, SUBDIV_STATS_TOPOLOGY_REFINER_CREATION_TIME);
subdiv->stats = stats;
return subdiv;
@@ -113,7 +95,8 @@ void BKE_subdiv_free(Subdiv *subdiv)
if (subdiv->topology_refiner != NULL) {
openSubdiv_deleteTopologyRefiner(subdiv->topology_refiner);
}
- MEM_SAFE_FREE(subdiv->face_ptex_offset);
MEM_freeN(subdiv);
+#else
+ UNUSED_VARS(subdiv);
#endif
}
diff --git a/source/blender/blenkernel/intern/subdiv_mesh.c b/source/blender/blenkernel/intern/subdiv_mesh.c
index 83f2069ea0f..76f41d512bc 100644
--- a/source/blender/blenkernel/intern/subdiv_mesh.c
+++ b/source/blender/blenkernel/intern/subdiv_mesh.c
@@ -38,27 +38,40 @@
#include "BKE_mesh.h"
-/* TODO(sergey): Somehow move this to subdiv code? */
-static int mpoly_ptex_faces_count_get(const MPoly *mp)
+#include "MEM_guardedalloc.h"
+
+/* =============================================================================
+ * General helpers.
+ */
+
+/* Number of ptex faces for a given polygon. */
+BLI_INLINE int num_ptex_faces_per_poly_get(const MPoly *poly)
{
- if (mp->totloop == 4) {
- return 1;
- }
- else {
- return mp->totloop;
- }
+ return (poly->totloop == 4) ? 1 : poly->totloop;
}
-static int num_edges_per_ptex_get(const int resolution)
+BLI_INLINE int num_edges_per_ptex_face_get(const int resolution)
{
return 2 * (resolution - 1) * resolution;
}
-static int num_polys_per_ptex_get(const int resolution)
+/* Number of subdivision polygons per ptex face. */
+BLI_INLINE int num_polys_per_ptex_get(const int resolution)
{
return (resolution - 1) * (resolution - 1);
}
+/* Subdivision resolution per given polygon's ptex faces. */
+BLI_INLINE int ptex_face_resolution_get(const MPoly *poly, int resolution)
+{
+ return (poly->totloop == 4) ? (resolution)
+ : ((resolution >> 1) + 1);
+}
+
+/* =============================================================================
+ * Mesh subdivision context.
+ */
+
typedef struct SubdivMeshContext {
const Mesh *coarse_mesh;
Subdiv *subdiv;
@@ -72,8 +85,127 @@ typedef struct SubdivMeshContext {
/* UV layers interpolation. */
int num_uv_layers;
MLoopUV *uv_layers[MAX_MTFACE];
+
+ /* Indexed by coarse polygon index, indicates offset in subdivided mesh
+ * vertices, edges and polygons arrays, where first element of the poly
+ * begins.
+ */
+ int *subdiv_vertex_offset;
+ int *subdiv_edge_offset;
+ int *subdiv_polygon_offset;
+ /* Indexed by base face index, element indicates total number of ptex faces
+ * created for preceding base faces.
+ */
+ int *face_ptex_offset;
+
+ /* Counters of geometry in subdivided mesh, initialized as a part of
+ * offsets calculation.
+ */
+ int num_subdiv_vertices;
+ int num_subdiv_edges;
+ int num_subdiv_loops;
+ int num_subdiv_polygons;
} SubdivMeshContext;
+static void subdiv_mesh_ctx_cache_uv_layers(SubdivMeshContext *ctx)
+{
+ Mesh *subdiv_mesh = ctx->subdiv_mesh;
+ ctx->num_uv_layers =
+ CustomData_number_of_layers(&subdiv_mesh->ldata, CD_MLOOPUV);
+ for (int layer_index = 0; layer_index < ctx->num_uv_layers; ++layer_index) {
+ ctx->uv_layers[layer_index] = CustomData_get_layer_n(
+ &subdiv_mesh->ldata, CD_MLOOPUV, layer_index);
+ }
+}
+
+static void subdiv_mesh_ctx_cache_custom_data_layers(SubdivMeshContext *ctx)
+{
+ Mesh *subdiv_mesh = ctx->subdiv_mesh;
+ /* Pointers to original indices layers. */
+ ctx->vert_origindex = CustomData_get_layer(
+ &subdiv_mesh->vdata, CD_ORIGINDEX);
+ ctx->edge_origindex = CustomData_get_layer(
+ &subdiv_mesh->edata, CD_ORIGINDEX);
+ ctx->loop_origindex = CustomData_get_layer(
+ &subdiv_mesh->ldata, CD_ORIGINDEX);
+ ctx->poly_origindex = CustomData_get_layer(
+ &subdiv_mesh->pdata, CD_ORIGINDEX);
+ /* UV layers interpolation. */
+ subdiv_mesh_ctx_cache_uv_layers(ctx);
+}
+
+static void subdiv_mesh_ctx_init_offsets(SubdivMeshContext *ctx)
+{
+ const Mesh *coarse_mesh = ctx->coarse_mesh;
+ const MPoly *coarse_mpoly = coarse_mesh->mpoly;
+ /* Allocate memory. */
+ ctx->subdiv_vertex_offset = MEM_malloc_arrayN(
+ coarse_mesh->totpoly,
+ sizeof(*ctx->subdiv_vertex_offset),
+ "vertex_offset");
+ ctx->subdiv_edge_offset = MEM_malloc_arrayN(
+ coarse_mesh->totpoly,
+ sizeof(*ctx->subdiv_edge_offset),
+ "subdiv_edge_offset");
+ ctx->subdiv_polygon_offset = MEM_malloc_arrayN(
+ coarse_mesh->totpoly,
+ sizeof(*ctx->subdiv_polygon_offset),
+ "subdiv_polygon_offset");
+ ctx->face_ptex_offset = MEM_malloc_arrayN(coarse_mesh->totpoly,
+ sizeof(*ctx->face_ptex_offset),
+ "face_ptex_offset");
+ /* Fill in offsets. */
+ int vertex_offset = 0;
+ int edge_offset = 0;
+ int polygon_offset = 0;
+ int face_ptex_offset = 0;
+ for (int poly_index = 0; poly_index < coarse_mesh->totpoly; poly_index++) {
+ const MPoly *coarse_poly = &coarse_mpoly[poly_index];
+ const int ptex_face_resolution = ptex_face_resolution_get(
+ coarse_poly, ctx->settings->resolution);
+ const int ptex_face_resolution2 =
+ ptex_face_resolution * ptex_face_resolution;
+ const int num_ptex_faces_per_poly =
+ num_ptex_faces_per_poly_get(coarse_poly);
+ ctx->subdiv_vertex_offset[poly_index] = vertex_offset;
+ ctx->subdiv_edge_offset[poly_index] = edge_offset;
+ ctx->subdiv_polygon_offset[poly_index] = polygon_offset;
+ ctx->face_ptex_offset[poly_index] = face_ptex_offset;
+ vertex_offset += num_ptex_faces_per_poly * ptex_face_resolution2;
+ edge_offset += num_ptex_faces_per_poly *
+ num_edges_per_ptex_face_get(ptex_face_resolution);
+ polygon_offset +=
+ num_ptex_faces_per_poly *
+ num_polys_per_ptex_get(ptex_face_resolution);
+ face_ptex_offset += num_ptex_faces_per_poly;
+ }
+ ctx->num_subdiv_vertices = vertex_offset;
+ ctx->num_subdiv_edges = edge_offset;
+ ctx->num_subdiv_polygons = polygon_offset;
+ ctx->num_subdiv_loops = 4 * ctx->num_subdiv_polygons;
+}
+
+static void subdiv_mesh_ctx_init(SubdivMeshContext *ctx)
+{
+ subdiv_mesh_ctx_init_offsets(ctx);
+}
+
+static void subdiv_mesh_ctx_init_result(SubdivMeshContext *ctx)
+{
+ subdiv_mesh_ctx_cache_custom_data_layers(ctx);
+}
+
+static void subdiv_mesh_ctx_free(SubdivMeshContext *ctx)
+{
+ MEM_freeN(ctx->subdiv_vertex_offset);
+ MEM_freeN(ctx->subdiv_edge_offset);
+ MEM_freeN(ctx->face_ptex_offset);
+}
+
+/* =============================================================================
+ * Loop custom data copy helpers.
+ */
+
typedef struct LoopsOfPtex {
/* First loop of the ptex, starts at ptex (0, 0) and goes in u direction. */
const MLoop *first_loop;
@@ -112,6 +244,10 @@ static void loops_of_ptex_get(
}
}
+/* =============================================================================
+ * Edge custom data copy helpers.
+ */
+
typedef struct EdgesOfPtex {
/* First edge of the ptex, starts at ptex (0, 0) and goes in u direction. */
const MEdge *first_edge;
@@ -145,6 +281,10 @@ static void edges_of_ptex_get(
}
}
+/* =============================================================================
+ * Vertex custom data interpolation helpers.
+ */
+
/* TODO(sergey): Somehow de-duplicate with loops storage, without too much
* exception cases all over the code.
*/
@@ -215,7 +355,7 @@ static void vertex_interpolation_init(
int *indices = BLI_array_alloca(indices, coarse_poly->totloop);
for (int i = 0; i < coarse_poly->totloop; ++i) {
weights[i] = weight;
- indices[i] = coarse_poly->loopstart + i;
+ indices[i] = coarse_mloop[coarse_poly->loopstart + i].v;
}
CustomData_interp(&coarse_mesh->vdata,
&vertex_interpolation->vertex_data_storage,
@@ -255,13 +395,15 @@ static void vertex_interpolation_from_ptex(
* iteration.
*/
const float weights[2] = {0.5f, 0.5f};
+ const int first_loop_index = loops_of_ptex.first_loop - coarse_mloop;
+ const int last_loop_index = loops_of_ptex.last_loop - coarse_mloop;
const int first_indices[2] = {
- coarse_mloop[loops_of_ptex.first_loop - coarse_mloop].v,
- coarse_mloop[(loops_of_ptex.first_loop + 1 - coarse_mloop) %
- coarse_poly->totloop].v};
- const int last_indices[2] = {
- coarse_mloop[loops_of_ptex.last_loop - coarse_mloop].v,
- coarse_mloop[loops_of_ptex.first_loop - coarse_mloop].v};
+ coarse_mloop[first_loop_index].v,
+ coarse_mloop[coarse_poly->loopstart +
+ (first_loop_index - coarse_poly->loopstart + 1) %
+ coarse_poly->totloop].v};
+ const int last_indices[2] = {coarse_mloop[first_loop_index].v,
+ coarse_mloop[last_loop_index].v};
CustomData_interp(vertex_data,
&vertex_interpolation->vertex_data_storage,
first_indices,
@@ -285,6 +427,10 @@ static void vertex_interpolation_end(
}
}
+/* =============================================================================
+ * Loop custom data interpolation helpers.
+ */
+
typedef struct LoopsForInterpolation {
/* This field points to a loop data which is to be used for interpolation.
* The idea is to avoid unnecessary allocations for regular faces, where
@@ -413,13 +559,17 @@ static void loop_interpolation_end(LoopsForInterpolation *loop_interpolation)
}
}
+/* =============================================================================
+ * Vertex subdivision process.
+ */
+
static void subdiv_copy_vertex_data(
const SubdivMeshContext *ctx,
MVert *subdiv_vertex,
- const Mesh *coarse_mesh,
+ const Mesh *UNUSED(coarse_mesh),
const MPoly *coarse_poly,
const VerticesForInterpolation *vertex_interpolation,
- const int ptex_of_poly_index,
+ const int UNUSED(ptex_of_poly_index),
const float u, const float v)
{
const int subdiv_vertex_index = subdiv_vertex - ctx->subdiv_mesh->mvert;
@@ -437,27 +587,33 @@ static void subdiv_copy_vertex_data(
ctx->vert_origindex[subdiv_vertex_index] = ORIGINDEX_NONE;
if (coarse_poly->totloop == 4) {
if (u == 0.0f && v == 0.0f) {
- ctx->vert_origindex[subdiv_vertex_index] =
- vertex_interpolation->vertex_indices[0];
+ // ctx->vert_origindex[subdiv_vertex_index] =
+ // vertex_interpolation->vertex_indices[0];
}
else if (u == 1.0f && v == 0.0f) {
- ctx->vert_origindex[subdiv_vertex_index] =
- vertex_interpolation->vertex_indices[1];
+ // ctx->vert_origindex[subdiv_vertex_index] =
+ // vertex_interpolation->vertex_indices[1];
}
else if (u == 1.0f && v == 1.0f) {
- ctx->vert_origindex[subdiv_vertex_index] =
- vertex_interpolation->vertex_indices[2];
+ // ctx->vert_origindex[subdiv_vertex_index] =
+ // vertex_interpolation->vertex_indices[2];
}
else if (u == 0.0f && v == 1.0f) {
- ctx->vert_origindex[subdiv_vertex_index] =
- vertex_interpolation->vertex_indices[3];
+ // ctx->vert_origindex[subdiv_vertex_index] =
+ // vertex_interpolation->vertex_indices[3];
+ }
+ else {
+ ctx->vert_origindex[subdiv_vertex_index] = ORIGINDEX_NONE;
}
} else {
if (u == 0.0f && v == 0.0f) {
- const MLoop *coarse_mloop = coarse_mesh->mloop;
- ctx->vert_origindex[subdiv_vertex_index] =
- coarse_mloop[coarse_poly->loopstart +
- ptex_of_poly_index].v;
+ // const MLoop *coarse_mloop = coarse_mesh->mloop;
+ // ctx->vert_origindex[subdiv_vertex_index] =
+ // coarse_mloop[coarse_poly->loopstart +
+ // ptex_of_poly_index].v;
+ }
+ else {
+ ctx->vert_origindex[subdiv_vertex_index] = ORIGINDEX_NONE;
}
}
}
@@ -468,23 +624,26 @@ static void subdiv_evaluate_vertices(SubdivMeshContext *ctx,
{
Subdiv *subdiv = ctx->subdiv;
const int resolution = ctx->settings->resolution;
- const int resolution2 = resolution * resolution;
- const float inv_resolution_1 = 1.0f / (float)(resolution - 1);
+ const int start_vertex_index = ctx->subdiv_vertex_offset[poly_index];
/* Base/coarse mesh information. */
const Mesh *coarse_mesh = ctx->coarse_mesh;
- const MPoly *coarse_polyoly = coarse_mesh->mpoly;
- const MPoly *coarse_poly = &coarse_polyoly[poly_index];
- const int num_poly_ptex_faces = mpoly_ptex_faces_count_get(coarse_poly);
+ const MPoly *coarse_mpoly = coarse_mesh->mpoly;
+ const MPoly *coarse_poly = &coarse_mpoly[poly_index];
+ const int num_ptex_faces_per_poly =
+ num_ptex_faces_per_poly_get(coarse_poly);
+ const int ptex_resolution =
+ ptex_face_resolution_get(coarse_poly, resolution);
+ const float inv_ptex_resolution_1 = 1.0f / (float)(ptex_resolution - 1);
/* Hi-poly subdivided mesh. */
Mesh *subdiv_mesh = ctx->subdiv_mesh;
MVert *subdiv_vertex = subdiv_mesh->mvert;
- const int ptex_face_index = subdiv->face_ptex_offset[poly_index];
+ MVert *subdiv_vert = &subdiv_vertex[start_vertex_index];
/* Actual evaluation. */
VerticesForInterpolation vertex_interpolation;
vertex_interpolation_init(ctx, &vertex_interpolation, coarse_poly);
- MVert *subdiv_vert = &subdiv_vertex[ptex_face_index * resolution2];
+ const int ptex_face_index = ctx->face_ptex_offset[poly_index];
for (int ptex_of_poly_index = 0;
- ptex_of_poly_index < num_poly_ptex_faces;
+ ptex_of_poly_index < num_ptex_faces_per_poly;
ptex_of_poly_index++)
{
vertex_interpolation_from_ptex(ctx,
@@ -496,13 +655,13 @@ static void subdiv_evaluate_vertices(SubdivMeshContext *ctx,
BKE_subdiv_eval_limit_patch_resolution_point_and_short_normal(
subdiv,
current_ptex_face_index,
- resolution,
+ ptex_resolution,
subdiv_vert, offsetof(MVert, co), sizeof(MVert),
subdiv_vert, offsetof(MVert, no), sizeof(MVert));
- for (int y = 0; y < resolution; y++) {
- const float v = y * inv_resolution_1;
- for (int x = 0; x < resolution; x++, subdiv_vert++) {
- const float u = x * inv_resolution_1;
+ for (int y = 0; y < ptex_resolution; y++) {
+ const float v = y * inv_ptex_resolution_1;
+ for (int x = 0; x < ptex_resolution; x++, subdiv_vert++) {
+ const float u = x * inv_ptex_resolution_1;
subdiv_copy_vertex_data(ctx,
subdiv_vert,
coarse_mesh,
@@ -516,6 +675,10 @@ static void subdiv_evaluate_vertices(SubdivMeshContext *ctx,
vertex_interpolation_end(&vertex_interpolation);
}
+/* =============================================================================
+ * Edge subdivision process.
+ */
+
static void subdiv_copy_edge_data(
SubdivMeshContext *ctx,
MEdge *subdiv_edge,
@@ -590,22 +753,22 @@ static MEdge *subdiv_create_edges_column(SubdivMeshContext *ctx,
static void subdiv_create_edges(SubdivMeshContext *ctx, int poly_index)
{
- Subdiv *subdiv = ctx->subdiv;
- const int resolution = ctx->settings->resolution;
- const int resolution2 = resolution * resolution;
- const int ptex_face_index = subdiv->face_ptex_offset[poly_index];
- const int num_edges_per_ptex = num_edges_per_ptex_get(resolution);
- const int start_edge_index = ptex_face_index * num_edges_per_ptex;
+ const int start_vertex_index = ctx->subdiv_vertex_offset[poly_index];
+ const int start_edge_index = ctx->subdiv_edge_offset[poly_index];
/* Base/coarse mesh information. */
const Mesh *coarse_mesh = ctx->coarse_mesh;
- const MPoly *coarse_polyoly = coarse_mesh->mpoly;
- const MPoly *coarse_poly = &coarse_polyoly[poly_index];
- const int num_poly_ptex_faces = mpoly_ptex_faces_count_get(coarse_poly);
+ const MPoly *coarse_mpoly = coarse_mesh->mpoly;
+ const MPoly *coarse_poly = &coarse_mpoly[poly_index];
+ const int num_ptex_faces_per_poly =
+ num_ptex_faces_per_poly_get(coarse_poly);
+ const int ptex_face_resolution = ptex_face_resolution_get(
+ coarse_poly, ctx->settings->resolution);
+ const int ptex_face_resolution2 =
+ ptex_face_resolution * ptex_face_resolution;
/* Hi-poly subdivided mesh. */
Mesh *subdiv_mesh = ctx->subdiv_mesh;
MEdge *subdiv_medge = subdiv_mesh->medge;
MEdge *subdiv_edge = &subdiv_medge[start_edge_index];
- const int start_poly_vertex_index = ptex_face_index * resolution2;
/* Consider a subdivision of base face at level 1:
*
* y
@@ -619,22 +782,25 @@ static void subdiv_create_edges(SubdivMeshContext *ctx, int poly_index)
*
* This is illustrate which parts of geometry is created by code below.
*/
- for (int i = 0; i < num_poly_ptex_faces; i++) {
+ for (int ptex_of_poly_index = 0;
+ ptex_of_poly_index < num_ptex_faces_per_poly;
+ ptex_of_poly_index++)
+ {
const int start_ptex_face_vertex_index =
- start_poly_vertex_index + i * resolution2;
+ start_vertex_index + ptex_of_poly_index * ptex_face_resolution2;
EdgesOfPtex edges_of_ptex;
- edges_of_ptex_get(ctx, &edges_of_ptex, coarse_poly, i);
+ edges_of_ptex_get(ctx, &edges_of_ptex, coarse_poly, ptex_of_poly_index);
/* Create bottom row of edges (0-1, 1-2). */
subdiv_edge = subdiv_create_edges_row(
ctx,
subdiv_edge,
edges_of_ptex.first_edge,
start_ptex_face_vertex_index,
- resolution);
+ ptex_face_resolution);
/* Create remaining edges. */
- for (int row = 0; row < resolution - 1; row++) {
+ for (int row = 0; row < ptex_face_resolution - 1; row++) {
const int start_row_vertex_index =
- start_ptex_face_vertex_index + row * resolution;
+ start_ptex_face_vertex_index + row * ptex_face_resolution;
/* Create vertical columns.
*
* At first iteration it will be edges (0-3. 1-4, 2-5), then it
@@ -646,7 +812,7 @@ static void subdiv_create_edges(SubdivMeshContext *ctx, int poly_index)
edges_of_ptex.last_edge,
edges_of_ptex.second_edge,
start_row_vertex_index,
- resolution);
+ ptex_face_resolution);
/* Create horizontal edge row.
*
* At first iteration it will be edges (3-4, 4-5), then it will be
@@ -655,14 +821,18 @@ static void subdiv_create_edges(SubdivMeshContext *ctx, int poly_index)
subdiv_edge = subdiv_create_edges_row(
ctx,
subdiv_edge,
- (row == resolution - 2) ? edges_of_ptex.third_edge
- : NULL,
- start_row_vertex_index + resolution,
- resolution);
+ (row == ptex_face_resolution - 2) ? edges_of_ptex.third_edge
+ : NULL,
+ start_row_vertex_index + ptex_face_resolution,
+ ptex_face_resolution);
}
}
}
+/* =============================================================================
+ * Loops creation/interpolation.
+ */
+
static void subdiv_copy_loop_data(
const SubdivMeshContext *ctx,
MLoop *subdiv_loop,
@@ -723,24 +893,25 @@ static void subdiv_eval_uv_layer(SubdivMeshContext *ctx,
static void subdiv_create_loops(SubdivMeshContext *ctx, int poly_index)
{
- Subdiv *subdiv = ctx->subdiv;
const int resolution = ctx->settings->resolution;
- const int resolution2 = resolution * resolution;
- const float inv_resolution_1 = 1.0f / (float)(resolution - 1);
- const int ptex_face_index = subdiv->face_ptex_offset[poly_index];
- const int num_edges_per_ptex = num_edges_per_ptex_get(resolution);
- const int start_edge_index = ptex_face_index * num_edges_per_ptex;
- const int num_polys_per_ptex = num_polys_per_ptex_get(resolution);
- const int start_poly_index = ptex_face_index * num_polys_per_ptex;
- const int start_loop_index = 4 * start_poly_index;
- const int start_vert_index = ptex_face_index * resolution2;
- const float du = inv_resolution_1;
- const float dv = inv_resolution_1;
+ const int ptex_face_index = ctx->face_ptex_offset[poly_index];
+ const int start_vertex_index = ctx->subdiv_vertex_offset[poly_index];
+ const int start_edge_index = ctx->subdiv_edge_offset[poly_index];
+ const int start_poly_index = ctx->subdiv_polygon_offset[poly_index];
/* Base/coarse mesh information. */
const Mesh *coarse_mesh = ctx->coarse_mesh;
- const MPoly *coarse_polyoly = coarse_mesh->mpoly;
- const MPoly *coarse_poly = &coarse_polyoly[poly_index];
- const int num_poly_ptex_faces = mpoly_ptex_faces_count_get(coarse_poly);
+ const MPoly *coarse_mpoly = coarse_mesh->mpoly;
+ const MPoly *coarse_poly = &coarse_mpoly[poly_index];
+ const int num_ptex_faces_per_poly =
+ num_ptex_faces_per_poly_get(coarse_poly);
+ const int ptex_resolution =
+ ptex_face_resolution_get(coarse_poly, resolution);
+ const int ptex_resolution2 = ptex_resolution * ptex_resolution;
+ const float inv_ptex_resolution_1 = 1.0f / (float)(ptex_resolution - 1);
+ const int num_edges_per_ptex = num_edges_per_ptex_face_get(ptex_resolution);
+ const int start_loop_index = 4 * start_poly_index;
+ const float du = inv_ptex_resolution_1;
+ const float dv = inv_ptex_resolution_1;
/* Hi-poly subdivided mesh. */
Mesh *subdiv_mesh = ctx->subdiv_mesh;
MLoop *subdiv_loopoop = subdiv_mesh->mloop;
@@ -748,7 +919,7 @@ static void subdiv_create_loops(SubdivMeshContext *ctx, int poly_index)
LoopsForInterpolation loop_interpolation;
loop_interpolation_init(ctx, &loop_interpolation, coarse_poly);
for (int ptex_of_poly_index = 0;
- ptex_of_poly_index < num_poly_ptex_faces;
+ ptex_of_poly_index < num_ptex_faces_per_poly;
ptex_of_poly_index++)
{
loop_interpolation_from_ptex(ctx,
@@ -757,24 +928,24 @@ static void subdiv_create_loops(SubdivMeshContext *ctx, int poly_index)
ptex_of_poly_index);
const int current_ptex_face_index =
ptex_face_index + ptex_of_poly_index;
- for (int y = 0; y < resolution - 1; y++) {
- const float v = y * inv_resolution_1;
- for (int x = 0; x < resolution - 1; x++, subdiv_loop += 4) {
- const float u = x * inv_resolution_1;
+ for (int y = 0; y < ptex_resolution - 1; y++) {
+ const float v = y * inv_ptex_resolution_1;
+ for (int x = 0; x < ptex_resolution - 1; x++, subdiv_loop += 4) {
+ const float u = x * inv_ptex_resolution_1;
/* Vertex indicies ordered counter-clockwise. */
- const int v0 = start_vert_index +
- (ptex_of_poly_index * resolution2) +
- (y * resolution + x);
+ const int v0 = start_vertex_index +
+ (ptex_of_poly_index * ptex_resolution2) +
+ (y * ptex_resolution + x);
const int v1 = v0 + 1;
- const int v2 = v0 + resolution + 1;
- const int v3 = v0 + resolution;
+ const int v2 = v0 + ptex_resolution + 1;
+ const int v3 = v0 + ptex_resolution;
/* Edge indicies ordered counter-clockwise. */
const int e0 = start_edge_index +
(ptex_of_poly_index * num_edges_per_ptex) +
- (y * (2 * resolution - 1) + x);
- const int e1 = e0 + resolution;
- const int e2 = e0 + (2 * resolution - 1);
- const int e3 = e0 + resolution - 1;
+ (y * (2 * ptex_resolution - 1) + x);
+ const int e1 = e0 + ptex_resolution;
+ const int e2 = e0 + (2 * ptex_resolution - 1);
+ const int e3 = e0 + ptex_resolution - 1;
/* Initialize 4 loops of corresponding hi-poly poly. */
/* TODO(sergey): For ptex boundaries we should use loops from
* coarse mesh.
@@ -808,13 +979,17 @@ static void subdiv_create_loops(SubdivMeshContext *ctx, int poly_index)
subdiv_loop,
current_ptex_face_index,
u, v,
- inv_resolution_1);
+ inv_ptex_resolution_1);
}
}
}
loop_interpolation_end(&loop_interpolation);
}
+/* =============================================================================
+ * Polygons subdivision process.
+ */
+
static void subdiv_copy_poly_data(const SubdivMeshContext *ctx,
MPoly *subdiv_poly,
const MPoly *coarse_poly)
@@ -827,30 +1002,31 @@ static void subdiv_copy_poly_data(const SubdivMeshContext *ctx,
subdiv_poly_index,
1);
if (ctx->poly_origindex != NULL) {
- ctx->poly_origindex[subdiv_poly_index] = coarse_poly_index;
+ // ctx->poly_origindex[subdiv_poly_index] = coarse_poly_index;
}
}
static void subdiv_create_polys(SubdivMeshContext *ctx, int poly_index)
{
- Subdiv *subdiv = ctx->subdiv;
const int resolution = ctx->settings->resolution;
- const int ptex_face_index = subdiv->face_ptex_offset[poly_index];
- const int num_polys_per_ptex = num_polys_per_ptex_get(resolution);
- const int num_loops_per_ptex = 4 * num_polys_per_ptex;
- const int start_poly_index = ptex_face_index * num_polys_per_ptex;
- const int start_loop_index = 4 * start_poly_index;
+ const int start_poly_index = ctx->subdiv_polygon_offset[poly_index];
/* Base/coarse mesh information. */
const Mesh *coarse_mesh = ctx->coarse_mesh;
- const MPoly *coarse_polyoly = coarse_mesh->mpoly;
- const MPoly *coarse_poly = &coarse_polyoly[poly_index];
- const int num_poly_ptex_faces = mpoly_ptex_faces_count_get(coarse_poly);
+ const MPoly *coarse_mpoly = coarse_mesh->mpoly;
+ const MPoly *coarse_poly = &coarse_mpoly[poly_index];
+ const int num_ptex_faces_per_poly =
+ num_ptex_faces_per_poly_get(coarse_poly);
+ const int ptex_resolution =
+ ptex_face_resolution_get(coarse_poly, resolution);
+ const int num_polys_per_ptex = num_polys_per_ptex_get(ptex_resolution);
+ const int num_loops_per_ptex = 4 * num_polys_per_ptex;
+ const int start_loop_index = 4 * start_poly_index;
/* Hi-poly subdivided mesh. */
Mesh *subdiv_mesh = ctx->subdiv_mesh;
MPoly *subdiv_mpoly = subdiv_mesh->mpoly;
MPoly *subdiv_mp = &subdiv_mpoly[start_poly_index];
for (int ptex_of_poly_index = 0;
- ptex_of_poly_index < num_poly_ptex_faces;
+ ptex_of_poly_index < num_ptex_faces_per_poly;
ptex_of_poly_index++)
{
for (int subdiv_poly_index = 0;
@@ -866,6 +1042,10 @@ static void subdiv_create_polys(SubdivMeshContext *ctx, int poly_index)
}
}
+/* =============================================================================
+ * Subdivision process entry points.
+ */
+
static void subdiv_eval_task(
void *__restrict userdata,
const int poly_index,
@@ -880,33 +1060,6 @@ static void subdiv_eval_task(
subdiv_create_polys(data, poly_index);
}
-static void cache_uv_layers(SubdivMeshContext *ctx)
-{
- Mesh *subdiv_mesh = ctx->subdiv_mesh;
- ctx->num_uv_layers =
- CustomData_number_of_layers(&subdiv_mesh->ldata, CD_MLOOPUV);
- for (int layer_index = 0; layer_index < ctx->num_uv_layers; ++layer_index) {
- ctx->uv_layers[layer_index] = CustomData_get_layer_n(
- &subdiv_mesh->ldata, CD_MLOOPUV, layer_index);
- }
-}
-
-static void cache_custom_data_layers(SubdivMeshContext *ctx)
-{
- Mesh *subdiv_mesh = ctx->subdiv_mesh;
- /* Pointers to original indices layers. */
- ctx->vert_origindex = CustomData_get_layer(
- &subdiv_mesh->vdata, CD_ORIGINDEX);
- ctx->edge_origindex = CustomData_get_layer(
- &subdiv_mesh->edata, CD_ORIGINDEX);
- ctx->loop_origindex = CustomData_get_layer(
- &subdiv_mesh->ldata, CD_ORIGINDEX);
- ctx->poly_origindex = CustomData_get_layer(
- &subdiv_mesh->pdata, CD_ORIGINDEX);
- /* UV layers interpolation. */
- cache_uv_layers(ctx);
-}
-
Mesh *BKE_subdiv_to_mesh(
Subdiv *subdiv,
const SubdivToMeshSettings *settings,
@@ -917,29 +1070,20 @@ Mesh *BKE_subdiv_to_mesh(
* is is refined for the new positions of coarse vertices.
*/
BKE_subdiv_eval_update_from_mesh(subdiv, coarse_mesh);
- const int resolution = settings->resolution;
- const int resolution2 = resolution * resolution;
- const int num_result_verts = subdiv->num_ptex_faces * resolution2;
- const int num_result_edges =
- subdiv->num_ptex_faces * num_edges_per_ptex_get(resolution);
- const int num_result_polys =
- subdiv->num_ptex_faces * num_polys_per_ptex_get(resolution);
- const int num_result_loops = 4 * num_result_polys;
- /* Create mesh and its arrays. */
+ SubdivMeshContext ctx = {0};
+ ctx.coarse_mesh = coarse_mesh;
+ ctx.subdiv = subdiv;
+ ctx.settings = settings;
+ subdiv_mesh_ctx_init(&ctx);
Mesh *result = BKE_mesh_new_nomain_from_template(
coarse_mesh,
- num_result_verts,
- num_result_edges,
+ ctx.num_subdiv_vertices,
+ ctx.num_subdiv_edges,
0,
- num_result_loops,
- num_result_polys);
- /* Evaluate subdivisions of base faces in threads. */
- SubdivMeshContext ctx;
- ctx.coarse_mesh = coarse_mesh;
- ctx.subdiv = subdiv;
+ ctx.num_subdiv_loops,
+ ctx.num_subdiv_polygons);
ctx.subdiv_mesh = result;
- ctx.settings = settings;
- cache_custom_data_layers(&ctx);
+ subdiv_mesh_ctx_init_result(&ctx);
/* Multi-threaded evaluation. */
ParallelRangeSettings parallel_range_settings;
BLI_parallel_range_settings_defaults(&parallel_range_settings);
@@ -947,6 +1091,8 @@ Mesh *BKE_subdiv_to_mesh(
&ctx,
subdiv_eval_task,
&parallel_range_settings);
+ subdiv_mesh_ctx_free(&ctx);
+ // BKE_mesh_validate(result, true, true);
BKE_subdiv_stats_end(&subdiv->stats, SUBDIV_STATS_SUBDIV_TO_MESH);
return result;
}
diff --git a/source/blender/blenlib/intern/BLI_kdtree.c b/source/blender/blenlib/intern/BLI_kdtree.c
index 700000b7717..80a2957d907 100644
--- a/source/blender/blenlib/intern/BLI_kdtree.c
+++ b/source/blender/blenlib/intern/BLI_kdtree.c
@@ -774,7 +774,12 @@ int BLI_kdtree_calc_duplicates_fast(
if (ELEM(duplicates[index], -1, index)) {
p.search = index;
copy_v3_v3(p.search_co, tree->nodes[node_index].co);
+ int found_prev = found;
deduplicate_recursive(&p, tree->root);
+ if (found != found_prev) {
+ /* Prevent chains of doubles. */
+ duplicates[index] = index;
+ }
}
}
MEM_freeN(order);
@@ -786,7 +791,12 @@ int BLI_kdtree_calc_duplicates_fast(
if (ELEM(duplicates[index], -1, index)) {
p.search = index;
copy_v3_v3(p.search_co, tree->nodes[node_index].co);
+ int found_prev = found;
deduplicate_recursive(&p, tree->root);
+ if (found != found_prev) {
+ /* Prevent chains of doubles. */
+ duplicates[index] = index;
+ }
}
}
}
diff --git a/source/blender/blenlib/intern/math_geom.c b/source/blender/blenlib/intern/math_geom.c
index b89647d5b9b..9425931133a 100644
--- a/source/blender/blenlib/intern/math_geom.c
+++ b/source/blender/blenlib/intern/math_geom.c
@@ -2763,9 +2763,11 @@ bool isect_ray_aabb_v3(
return true;
}
-/*
- * Test a bounding box (AABB) for ray intersection
- * assumes the ray is already local to the boundbox space
+/**
+ * Test a bounding box (AABB) for ray intersection.
+ * Assumes the ray is already local to the boundbox space.
+ *
+ * \note: \a direction should be normalized if you intend to use the \a tmin or \a tmax distance results!
*/
bool isect_ray_aabb_v3_simple(
const float orig[3], const float dir[3],
@@ -2774,19 +2776,25 @@ bool isect_ray_aabb_v3_simple(
{
double t[7];
float hit_dist[2];
- t[1] = (double)(bb_min[0] - orig[0]) / dir[0];
- t[2] = (double)(bb_max[0] - orig[0]) / dir[0];
- t[3] = (double)(bb_min[1] - orig[1]) / dir[1];
- t[4] = (double)(bb_max[1] - orig[1]) / dir[1];
- t[5] = (double)(bb_min[2] - orig[2]) / dir[2];
- t[6] = (double)(bb_max[2] - orig[2]) / dir[2];
+ const double invdirx = (dir[0] > 1e-35f || dir[0] < -1e-35f) ? 1.0 / (double)dir[0] : DBL_MAX;
+ const double invdiry = (dir[1] > 1e-35f || dir[1] < -1e-35f) ? 1.0 / (double)dir[1] : DBL_MAX;
+ const double invdirz = (dir[2] > 1e-35f || dir[2] < -1e-35f) ? 1.0 / (double)dir[2] : DBL_MAX;
+ t[1] = (double)(bb_min[0] - orig[0]) * invdirx;
+ t[2] = (double)(bb_max[0] - orig[0]) * invdirx;
+ t[3] = (double)(bb_min[1] - orig[1]) * invdiry;
+ t[4] = (double)(bb_max[1] - orig[1]) * invdiry;
+ t[5] = (double)(bb_min[2] - orig[2]) * invdirz;
+ t[6] = (double)(bb_max[2] - orig[2]) * invdirz;
hit_dist[0] = (float)fmax(fmax(fmin(t[1], t[2]), fmin(t[3], t[4])), fmin(t[5], t[6]));
hit_dist[1] = (float)fmin(fmin(fmax(t[1], t[2]), fmax(t[3], t[4])), fmax(t[5], t[6]));
- if ((hit_dist[1] < 0 || hit_dist[0] > hit_dist[1]))
+ if ((hit_dist[1] < 0.0f || hit_dist[0] > hit_dist[1])) {
return false;
+ }
else {
- if (tmin) *tmin = hit_dist[0];
- if (tmax) *tmax = hit_dist[1];
+ if (tmin)
+ *tmin = hit_dist[0];
+ if (tmax)
+ *tmax = hit_dist[1];
return true;
}
}
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index 5ddba2aa282..91abcdf7a89 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -5561,7 +5561,6 @@ static void direct_link_object(FileData *fd, Object *ob)
ob->derivedDeform = NULL;
ob->derivedFinal = NULL;
BKE_object_runtime_reset(ob);
- BLI_listbase_clear(&ob->gpulamp);
link_list(fd, &ob->pc_ids);
/* Runtime curve data */
diff --git a/source/blender/blenloader/intern/versioning_250.c b/source/blender/blenloader/intern/versioning_250.c
index 973591c49da..4b628bf816a 100644
--- a/source/blender/blenloader/intern/versioning_250.c
+++ b/source/blender/blenloader/intern/versioning_250.c
@@ -545,20 +545,6 @@ static void do_version_constraints_radians_degrees_250(ListBase *lb)
}
}
-/* NOTE: this version patch is intended for versions < 2.52.2, but was initially introduced in 2.27 already */
-static void do_versions_seq_unique_name_all_strips(Scene *sce, ListBase *seqbasep)
-{
- Sequence * seq = seqbasep->first;
-
- while (seq) {
- BKE_sequence_base_unique_name_recursive(&sce->ed->seqbase, seq);
- if (seq->seqbase.first) {
- do_versions_seq_unique_name_all_strips(sce, &seq->seqbase);
- }
- seq = seq->next;
- }
-}
-
static void do_version_bone_roll_256(Bone *bone)
{
Bone *child;
@@ -1029,10 +1015,6 @@ void blo_do_versions_250(FileData *fd, Library *lib, Main *bmain)
if (sce->r.frame_step == 0)
sce->r.frame_step = 1;
- if (sce->ed && sce->ed->seqbase.first) {
- do_versions_seq_unique_name_all_strips(sce, &sce->ed->seqbase);
- }
-
sce = sce->id.next;
}
}
diff --git a/source/blender/blenloader/intern/versioning_280.c b/source/blender/blenloader/intern/versioning_280.c
index 487e0e8b9ec..d10e9ff294a 100644
--- a/source/blender/blenloader/intern/versioning_280.c
+++ b/source/blender/blenloader/intern/versioning_280.c
@@ -70,6 +70,7 @@
#include "BKE_report.h"
#include "BKE_scene.h"
#include "BKE_screen.h"
+#include "BKE_sequencer.h"
#include "BKE_studiolight.h"
#include "BKE_workspace.h"
@@ -486,27 +487,15 @@ static void do_version_layers_to_collections(Main *bmain, Scene *scene)
nlc->flag |= LAYER_COLLECTION_EXCLUDE;
}
}
- else if ((scene->lay & srl->lay & ~(srl->lay_exclude) & (1 << layer)) ||
- (srl->lay_zmask & (scene->lay | srl->lay_exclude) & (1 << layer)))
- {
+ else {
if (srl->lay_zmask & (1 << layer)) {
have_override = true;
-
- BKE_override_layer_collection_boolean_add(
- lc,
- ID_OB,
- "cycles.is_holdout",
- true);
+ lc->flag |= LAYER_COLLECTION_HOLDOUT;
}
if ((srl->lay & (1 << layer)) == 0) {
have_override = true;
-
- BKE_override_layer_collection_boolean_add(
- lc,
- ID_OB,
- "cycles_visibility.camera",
- false);
+ lc->flag |= LAYER_COLLECTION_INDIRECT_ONLY;
}
}
}
@@ -753,6 +742,18 @@ void do_versions_after_linking_280(Main *bmain)
#endif
}
+/* NOTE: this version patch is intended for versions < 2.52.2, but was initially introduced in 2.27 already.
+ * But in 2.79 another case generating non-unique names was discovered (see T55668, involving Meta strips)... */
+static void do_versions_seq_unique_name_all_strips(Scene *sce, ListBase *seqbasep)
+{
+ for (Sequence *seq = seqbasep->first; seq != NULL; seq = seq->next) {
+ BKE_sequence_base_unique_name_recursive(&sce->ed->seqbase, seq);
+ if (seq->seqbase.first != NULL) {
+ do_versions_seq_unique_name_all_strips(sce, &seq->seqbase);
+ }
+ }
+}
+
void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain)
{
bool use_collection_compat_28 = true;
@@ -1200,7 +1201,6 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain)
scene->eevee.flag =
SCE_EEVEE_VOLUMETRIC_LIGHTS |
- SCE_EEVEE_VOLUMETRIC_COLORED |
SCE_EEVEE_GTAO_BENT_NORMALS |
SCE_EEVEE_GTAO_BOUNCE |
SCE_EEVEE_TAA_REPROJECTION |
@@ -1258,7 +1258,6 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain)
EEVEE_GET_BOOL(props, volumetric_enable, SCE_EEVEE_VOLUMETRIC_ENABLED);
EEVEE_GET_BOOL(props, volumetric_lights, SCE_EEVEE_VOLUMETRIC_LIGHTS);
EEVEE_GET_BOOL(props, volumetric_shadows, SCE_EEVEE_VOLUMETRIC_SHADOWS);
- EEVEE_GET_BOOL(props, volumetric_colored_transmittance, SCE_EEVEE_VOLUMETRIC_COLORED);
EEVEE_GET_BOOL(props, gtao_enable, SCE_EEVEE_GTAO_ENABLED);
EEVEE_GET_BOOL(props, gtao_use_bent_normals, SCE_EEVEE_GTAO_BENT_NORMALS);
EEVEE_GET_BOOL(props, gtao_bounce, SCE_EEVEE_GTAO_BOUNCE);
@@ -1525,7 +1524,13 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain)
}
- {
+ if (!MAIN_VERSION_ATLEAST(bmain, 280, 21)) {
+ for (Scene *sce = bmain->scene.first; sce != NULL; sce = sce->id.next) {
+ if (sce->ed != NULL && sce->ed->seqbase.first != NULL) {
+ do_versions_seq_unique_name_all_strips(sce, &sce->ed->seqbase);
+ }
+ }
+
if (!DNA_struct_elem_find(fd->filesdna, "View3DOverlay", "float", "texture_paint_mode_opacity")) {
for (bScreen *screen = bmain->screen.first; screen; screen = screen->id.next) {
for (ScrArea *sa = screen->areabase.first; sa; sa = sa->next) {
@@ -1542,6 +1547,20 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain)
}
}
+ if (!DNA_struct_elem_find(fd->filesdna, "View3DShadeing", "short", "background_type")) {
+ for (bScreen *screen = bmain->screen.first; screen; screen = screen->id.next) {
+ for (ScrArea *sa = screen->areabase.first; sa; sa = sa->next) {
+ for (SpaceLink *sl = sa->spacedata.first; sl; sl = sl->next) {
+ if (sl->spacetype == SPACE_VIEW3D) {
+ View3D *v3d = (View3D *)sl;
+ v3d->shading.background_type = (v3d->flag3 & V3D_SHOW_WORLD)? V3D_SHADING_BACKGROUND_WORLD: V3D_SHADING_BACKGROUND_THEME;
+ copy_v3_fl(v3d->shading.background_color, 0.05f);
+ }
+ }
+ }
+ }
+ }
+
if (!DNA_struct_elem_find(fd->filesdna, "SceneEEVEE", "float", "gi_cubemap_draw_size")) {
for (Scene *scene = bmain->scene.first; scene; scene = scene->id.next) {
scene->eevee.gi_irradiance_draw_size = 0.1f;
@@ -1645,4 +1664,5 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain)
}
}
}
+
}
diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c
index 24ac0737e27..ce2362dacc8 100644
--- a/source/blender/blenloader/intern/writefile.c
+++ b/source/blender/blenloader/intern/writefile.c
@@ -1147,7 +1147,7 @@ static void write_nodetree_nolib(WriteData *wd, bNodeTree *ntree)
*/
static void current_screen_compat(
Main *mainvar, bool use_active_win,
- bScreen **r_screen, Scene **r_scene, ViewLayer **r_render_layer)
+ bScreen **r_screen, Scene **r_scene, ViewLayer **r_view_layer)
{
wmWindowManager *wm;
wmWindow *window = NULL;
@@ -1177,7 +1177,7 @@ static void current_screen_compat(
*r_screen = (window) ? BKE_workspace_active_screen_get(window->workspace_hook) : NULL;
*r_scene = (window) ? window->scene : NULL;
- *r_render_layer = (window && *r_scene) ? BKE_view_layer_find(*r_scene, window->view_layer_name) : NULL;
+ *r_view_layer = (window && *r_scene) ? BKE_view_layer_find(*r_scene, window->view_layer_name) : NULL;
}
typedef struct RenderInfo {
@@ -1193,11 +1193,11 @@ static void write_renderinfo(WriteData *wd, Main *mainvar)
{
bScreen *curscreen;
Scene *sce, *curscene = NULL;
- ViewLayer *render_layer;
+ ViewLayer *view_layer;
RenderInfo data;
/* XXX in future, handle multiple windows with multiple screens? */
- current_screen_compat(mainvar, false, &curscreen, &curscene, &render_layer);
+ current_screen_compat(mainvar, false, &curscreen, &curscene, &view_layer);
for (sce = mainvar->scene.first; sce; sce = sce->id.next) {
if (sce->id.lib == NULL && (sce == curscene || (sce->r.scemode & R_BG_RENDER))) {
@@ -3688,7 +3688,7 @@ static void write_global(WriteData *wd, int fileflags, Main *mainvar)
FileGlobal fg;
bScreen *screen;
Scene *scene;
- ViewLayer *render_layer;
+ ViewLayer *view_layer;
char subvstr[8];
/* prevent mem checkers from complaining */
@@ -3697,12 +3697,12 @@ static void write_global(WriteData *wd, int fileflags, Main *mainvar)
memset(fg.build_hash, 0, sizeof(fg.build_hash));
fg.pad1 = NULL;
- current_screen_compat(mainvar, is_undo, &screen, &scene, &render_layer);
+ current_screen_compat(mainvar, is_undo, &screen, &scene, &view_layer);
/* XXX still remap G */
fg.curscreen = screen;
fg.curscene = scene;
- fg.cur_view_layer = render_layer;
+ fg.cur_view_layer = view_layer;
/* prevent to save this, is not good convention, and feature with concerns... */
fg.fileflags = (fileflags & ~G_FILE_FLAGS_RUNTIME);
diff --git a/source/blender/depsgraph/intern/builder/deg_builder.cc b/source/blender/depsgraph/intern/builder/deg_builder.cc
index 4cbc7700947..8f5925a5ce3 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder.cc
@@ -67,6 +67,12 @@ void deg_graph_build_finalize(Main *bmain, Depsgraph *graph)
}
if (!deg_copy_on_write_is_expanded(id_node->id_cow)) {
flag |= DEG_TAG_COPY_ON_WRITE;
+ /* This means ID is being added to the dependency graph first
+ * time, which is similar to "ob-visible-change"
+ */
+ if (GS(id->name) == ID_OB) {
+ flag |= OB_RECALC_OB | OB_RECALC_DATA;
+ }
}
if (flag != 0) {
DEG_graph_id_tag_update(bmain,
diff --git a/source/blender/draw/engines/eevee/eevee_data.c b/source/blender/draw/engines/eevee/eevee_data.c
index 96e784b524c..636e532555f 100644
--- a/source/blender/draw/engines/eevee/eevee_data.c
+++ b/source/blender/draw/engines/eevee/eevee_data.c
@@ -30,7 +30,7 @@
#include "eevee_private.h"
#include "eevee_lightcache.h"
-static void eevee_view_layer_data_free(void *storage)
+void EEVEE_view_layer_data_free(void *storage)
{
EEVEE_ViewLayerData *sldata = (EEVEE_ViewLayerData *)storage;
@@ -77,7 +77,7 @@ EEVEE_ViewLayerData *EEVEE_view_layer_data_get(void)
EEVEE_ViewLayerData *EEVEE_view_layer_data_ensure_ex(struct ViewLayer *view_layer)
{
EEVEE_ViewLayerData **sldata = (EEVEE_ViewLayerData **)DRW_view_layer_engine_data_ensure_ex(
- view_layer, &draw_engine_eevee_type, &eevee_view_layer_data_free);
+ view_layer, &draw_engine_eevee_type, &EEVEE_view_layer_data_free);
if (*sldata == NULL) {
*sldata = MEM_callocN(sizeof(**sldata), "EEVEE_ViewLayerData");
@@ -89,7 +89,7 @@ EEVEE_ViewLayerData *EEVEE_view_layer_data_ensure_ex(struct ViewLayer *view_laye
EEVEE_ViewLayerData *EEVEE_view_layer_data_ensure(void)
{
EEVEE_ViewLayerData **sldata = (EEVEE_ViewLayerData **)DRW_view_layer_engine_data_ensure(
- &draw_engine_eevee_type, &eevee_view_layer_data_free);
+ &draw_engine_eevee_type, &EEVEE_view_layer_data_free);
if (*sldata == NULL) {
*sldata = MEM_callocN(sizeof(**sldata), "EEVEE_ViewLayerData");
diff --git a/source/blender/draw/engines/eevee/eevee_lightcache.c b/source/blender/draw/engines/eevee/eevee_lightcache.c
index 4f5ad5159cf..b0b66ee50dc 100644
--- a/source/blender/draw/engines/eevee/eevee_lightcache.c
+++ b/source/blender/draw/engines/eevee/eevee_lightcache.c
@@ -93,6 +93,7 @@ typedef struct EEVEE_LightBake {
LightCache *lcache;
Scene *scene;
struct Main *bmain;
+ EEVEE_ViewLayerData *sldata;
LightProbe **probe; /* Current probe being rendered. */
GPUTexture *rt_color; /* Target cube color texture. */
@@ -597,6 +598,12 @@ static void eevee_lightbake_delete_resources(EEVEE_LightBake *lbake)
lbake->lcache = NULL;
}
+ /* XXX Free the resources contained in the viewlayer data
+ * to be able to free the context before deleting the depsgraph. */
+ if (lbake->sldata) {
+ EEVEE_view_layer_data_free(lbake->sldata);
+ }
+
DRW_TEXTURE_FREE_SAFE(lbake->rt_depth);
DRW_TEXTURE_FREE_SAFE(lbake->rt_color);
DRW_TEXTURE_FREE_SAFE(lbake->grid_prev);
@@ -633,6 +640,8 @@ static void eevee_lightbake_cache_create(EEVEE_Data *vedata, EEVEE_LightBake *lb
EEVEE_FramebufferList *fbl = vedata->fbl;
EEVEE_ViewLayerData *sldata = EEVEE_view_layer_data_ensure();
Scene *scene_eval = DEG_get_evaluated_scene(lbake->depsgraph);
+ lbake->sldata = sldata;
+
/* Disable all effects BUT high bitdepth shadows. */
scene_eval->eevee.flag &= SCE_EEVEE_SHADOW_HIGH_BITDEPTH;
scene_eval->eevee.taa_samples = 1;
diff --git a/source/blender/draw/engines/eevee/eevee_private.h b/source/blender/draw/engines/eevee/eevee_private.h
index 5aa331a9b99..349a27a1765 100644
--- a/source/blender/draw/engines/eevee/eevee_private.h
+++ b/source/blender/draw/engines/eevee/eevee_private.h
@@ -777,6 +777,7 @@ typedef struct EEVEE_PrivateData {
} EEVEE_PrivateData; /* Transient data */
/* eevee_data.c */
+void EEVEE_view_layer_data_free(void *sldata);
EEVEE_ViewLayerData *EEVEE_view_layer_data_get(void);
EEVEE_ViewLayerData *EEVEE_view_layer_data_ensure_ex(struct ViewLayer *view_layer);
EEVEE_ViewLayerData *EEVEE_view_layer_data_ensure(void);
diff --git a/source/blender/draw/engines/workbench/workbench_data.c b/source/blender/draw/engines/workbench/workbench_data.c
index 5c3ab5f6688..24eb0f38a46 100644
--- a/source/blender/draw/engines/workbench/workbench_data.c
+++ b/source/blender/draw/engines/workbench/workbench_data.c
@@ -45,10 +45,16 @@ void workbench_private_data_init(WORKBENCH_PrivateData *wpd)
wd->matcap_orientation = (wpd->shading.flag & V3D_SHADING_MATCAP_FLIP_X) != 0;
wd->background_alpha = (v3d || scene->r.alphamode == R_ADDSKY) ? 1.0f : 0.0f;
- if (!v3d || ((v3d->flag3 & V3D_SHOW_WORLD) && (scene->world != NULL))) {
+ if (!v3d || ((v3d->shading.background_type & V3D_SHADING_BACKGROUND_WORLD) &&
+ (scene->world != NULL)))
+ {
copy_v3_v3(wd->background_color_low, &scene->world->horr);
copy_v3_v3(wd->background_color_high, &scene->world->horr);
}
+ else if (v3d->shading.background_type & V3D_SHADING_BACKGROUND_VIEWPORT) {
+ copy_v3_v3(wd->background_color_low, v3d->shading.background_color);
+ copy_v3_v3(wd->background_color_high, v3d->shading.background_color);
+ }
else if (v3d) {
UI_GetThemeColor3fv(UI_GetThemeValue(TH_SHOW_BACK_GRAD) ? TH_LOW_GRAD : TH_HIGH_GRAD, wd->background_color_low);
UI_GetThemeColor3fv(TH_HIGH_GRAD, wd->background_color_high);
diff --git a/source/blender/draw/engines/workbench/workbench_deferred.c b/source/blender/draw/engines/workbench/workbench_deferred.c
index 2bf55e6313d..4692b026d76 100644
--- a/source/blender/draw/engines/workbench/workbench_deferred.c
+++ b/source/blender/draw/engines/workbench/workbench_deferred.c
@@ -143,9 +143,12 @@ static char *workbench_build_prepass_frag(void)
return str;
}
-static char *workbench_build_prepass_vert(void)
+static char *workbench_build_prepass_vert(bool is_hair)
{
char *str = NULL;
+ if (!is_hair) {
+ return BLI_strdup(datatoc_workbench_prepass_vert_glsl);
+ }
DynStr *ds = BLI_dynstr_new();
@@ -177,7 +180,7 @@ static void ensure_deferred_shaders(WORKBENCH_PrivateData *wpd, int index, bool
if (e_data.prepass_sh_cache[index] == NULL) {
char *defines = workbench_material_build_defines(wpd, use_textures, is_hair);
char *composite_frag = workbench_build_composite_frag(wpd);
- char *prepass_vert = workbench_build_prepass_vert();
+ char *prepass_vert = workbench_build_prepass_vert(is_hair);
char *prepass_frag = workbench_build_prepass_frag();
e_data.prepass_sh_cache[index] = DRW_shader_create(
prepass_vert, NULL,
diff --git a/source/blender/draw/engines/workbench/workbench_forward.c b/source/blender/draw/engines/workbench/workbench_forward.c
index 6c9353cc132..e4a9c8abe26 100644
--- a/source/blender/draw/engines/workbench/workbench_forward.c
+++ b/source/blender/draw/engines/workbench/workbench_forward.c
@@ -81,9 +81,12 @@ extern char datatoc_workbench_common_lib_glsl[];
extern char datatoc_workbench_world_light_lib_glsl[];
/* static functions */
-static char *workbench_build_forward_vert(void)
+static char *workbench_build_forward_vert(bool is_hair)
{
char *str = NULL;
+ if (!is_hair) {
+ return BLI_strdup(datatoc_workbench_prepass_vert_glsl);
+ }
DynStr *ds = BLI_dynstr_new();
@@ -211,7 +214,7 @@ static void ensure_forward_shaders(WORKBENCH_PrivateData *wpd, int index, bool u
if (e_data.transparent_accum_sh_cache[index] == NULL) {
char *defines = workbench_material_build_defines(wpd, use_textures, is_hair);
- char *transparent_accum_vert = workbench_build_forward_vert();
+ char *transparent_accum_vert = workbench_build_forward_vert(is_hair);
char *transparent_accum_frag = workbench_build_forward_transparent_accum_frag();
e_data.transparent_accum_sh_cache[index] = DRW_shader_create(
transparent_accum_vert, NULL,
@@ -272,7 +275,8 @@ void workbench_forward_engine_init(WORKBENCH_Data *vedata)
char *defines = workbench_material_build_defines(wpd, false, false);
char *defines_texture = workbench_material_build_defines(wpd, true, false);
char *defines_hair = workbench_material_build_defines(wpd, false, true);
- char *forward_vert = workbench_build_forward_vert();
+ char *forward_vert = workbench_build_forward_vert(false);
+ char *forward_hair_vert = workbench_build_forward_vert(true);
e_data.object_outline_sh = DRW_shader_create(
forward_vert, NULL,
datatoc_workbench_forward_depth_frag_glsl, defines);
@@ -280,12 +284,13 @@ void workbench_forward_engine_init(WORKBENCH_Data *vedata)
forward_vert, NULL,
datatoc_workbench_forward_depth_frag_glsl, defines_texture);
e_data.object_outline_hair_sh = DRW_shader_create(
- forward_vert, NULL,
+ forward_hair_vert, NULL,
datatoc_workbench_forward_depth_frag_glsl, defines_hair);
e_data.checker_depth_sh = DRW_shader_create_fullscreen(
datatoc_workbench_checkerboard_depth_frag_glsl, NULL);
+ MEM_freeN(forward_hair_vert);
MEM_freeN(forward_vert);
MEM_freeN(defines);
MEM_freeN(defines_texture);
diff --git a/source/blender/draw/intern/draw_manager_shader.c b/source/blender/draw/intern/draw_manager_shader.c
index b0aec4a7600..b85e6267687 100644
--- a/source/blender/draw/intern/draw_manager_shader.c
+++ b/source/blender/draw/intern/draw_manager_shader.c
@@ -72,6 +72,7 @@ typedef struct DRWShaderCompiler {
ThreadMutex compilation_lock;
void *gl_context;
+ bool own_context;
int shaders_done; /* To compute progress. */
} DRWShaderCompiler;
@@ -146,7 +147,7 @@ static void drw_deferred_shader_compilation_free(void *custom_data)
BLI_spin_end(&comp->list_lock);
BLI_mutex_end(&comp->compilation_lock);
- if (comp->gl_context) {
+ if (comp->own_context) {
/* Only destroy if the job owns the context. */
WM_opengl_context_dispose(comp->gl_context);
}
@@ -189,8 +190,11 @@ static void drw_deferred_shader_add(GPUMaterial *mat, bool deferred)
BLI_movelisttolist(&comp->queue, &old_comp->queue);
BLI_spin_unlock(&old_comp->list_lock);
/* Do not recreate context, just pass ownership. */
- comp->gl_context = old_comp->gl_context;
- old_comp->gl_context = NULL;
+ if (old_comp->gl_context) {
+ comp->gl_context = old_comp->gl_context;
+ old_comp->own_context = false;
+ comp->own_context = true;
+ }
}
BLI_addtail(&comp->queue, dsh);
@@ -199,6 +203,7 @@ static void drw_deferred_shader_add(GPUMaterial *mat, bool deferred)
if (comp->gl_context == NULL) {
comp->gl_context = WM_opengl_context_create();
WM_opengl_context_activate(DST.gl_context);
+ comp->own_context = true;
}
WM_jobs_customdata_set(wm_job, comp, drw_deferred_shader_compilation_free);
diff --git a/source/blender/draw/intern/draw_view.c b/source/blender/draw/intern/draw_view.c
index 05aecea1d7a..95835a691a3 100644
--- a/source/blender/draw/intern/draw_view.c
+++ b/source/blender/draw/intern/draw_view.c
@@ -561,21 +561,12 @@ void DRW_draw_grid(void)
void DRW_draw_background(void)
{
- const DRWContextState *draw_ctx = DRW_context_state_get();
-
/* Just to make sure */
glDepthMask(GL_TRUE);
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
glStencilMask(0xFF);
- if ((draw_ctx->v3d->flag3 & V3D_SHOW_WORLD) &&
- (draw_ctx->scene->world != NULL))
- {
- const World *world = draw_ctx->scene->world;
- glClearColor(world->horr, world->horg, world->horb, 1.0f);
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
- }
- else if (UI_GetThemeValue(TH_SHOW_BACK_GRAD)) {
+ if (UI_GetThemeValue(TH_SHOW_BACK_GRAD)) {
float m[4][4];
unit_m4(m);
diff --git a/source/blender/editors/armature/pose_edit.c b/source/blender/editors/armature/pose_edit.c
index a9ba8c405ba..3ae578279ca 100644
--- a/source/blender/editors/armature/pose_edit.c
+++ b/source/blender/editors/armature/pose_edit.c
@@ -287,7 +287,8 @@ void POSE_OT_paths_calculate(wmOperatorType *ot)
RNA_def_int(ot->srna, "end_frame", 250, MINAFRAME, MAXFRAME, "End",
"Last frame to calculate bone paths on", MINFRAME, MAXFRAME / 2.0);
- RNA_def_enum(ot->srna, "bake_location", rna_enum_motionpath_bake_location_items, 0,
+ RNA_def_enum(ot->srna, "bake_location", rna_enum_motionpath_bake_location_items,
+ MOTIONPATH_BAKE_HEADS,
"Bake Location",
"Which point on the bones is used when calculating paths");
}
diff --git a/source/blender/editors/gpencil/gpencil_convert.c b/source/blender/editors/gpencil/gpencil_convert.c
index ccdbcba71f9..79bfc5149ba 100644
--- a/source/blender/editors/gpencil/gpencil_convert.c
+++ b/source/blender/editors/gpencil/gpencil_convert.c
@@ -1382,8 +1382,9 @@ static int gp_convert_layer_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static bool gp_convert_draw_check_prop(PointerRNA *ptr, PropertyRNA *prop)
+static bool gp_convert_poll_property(const bContext *UNUSED(C), wmOperator *op, const PropertyRNA *prop)
{
+ PointerRNA *ptr = op->ptr;
const char *prop_id = RNA_property_identifier(prop);
const bool link_strokes = RNA_boolean_get(ptr, "use_link_strokes");
int timing_mode = RNA_enum_get(ptr, "timing_mode");
@@ -1446,18 +1447,6 @@ static bool gp_convert_draw_check_prop(PointerRNA *ptr, PropertyRNA *prop)
return false;
}
-static void gp_convert_ui(bContext *C, wmOperator *op)
-{
- uiLayout *layout = op->layout;
- wmWindowManager *wm = CTX_wm_manager(C);
- PointerRNA ptr;
-
- RNA_pointer_create(&wm->id, op->type->srna, op->properties, &ptr);
-
- /* Main auto-draw call */
- uiDefAutoButsRNA(layout, &ptr, gp_convert_draw_check_prop, UI_BUT_LABEL_ALIGN_NONE, false);
-}
-
void GPENCIL_OT_convert(wmOperatorType *ot)
{
PropertyRNA *prop;
@@ -1471,7 +1460,7 @@ void GPENCIL_OT_convert(wmOperatorType *ot)
ot->invoke = WM_menu_invoke;
ot->exec = gp_convert_layer_exec;
ot->poll = gp_convert_poll;
- ot->ui = gp_convert_ui;
+ ot->poll_property = gp_convert_poll_property;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
diff --git a/source/blender/editors/include/ED_object.h b/source/blender/editors/include/ED_object.h
index 38545137740..9fd5cc99073 100644
--- a/source/blender/editors/include/ED_object.h
+++ b/source/blender/editors/include/ED_object.h
@@ -112,6 +112,7 @@ void ED_keymap_proportional_obmode(struct wmKeyConfig *keyconf, struct wmKeyMap
void ED_keymap_proportional_maskmode(struct wmKeyConfig *keyconf, struct wmKeyMap *keymap);
void ED_keymap_proportional_editmode(struct wmKeyConfig *keyconf, struct wmKeyMap *keymap,
const bool do_connected);
+void ED_keymap_editmesh_elem_mode(struct wmKeyConfig *keyconf, struct wmKeyMap *keymap);
void ED_object_base_select(struct Base *base, eObjectSelect_Mode mode);
void ED_object_base_activate(struct bContext *C, struct Base *base);
diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h
index 087e0c4ab7b..b4756eaed0f 100644
--- a/source/blender/editors/include/UI_interface.h
+++ b/source/blender/editors/include/UI_interface.h
@@ -772,7 +772,7 @@ typedef enum {
uiBut *uiDefAutoButR(uiBlock *block, struct PointerRNA *ptr, struct PropertyRNA *prop, int index, const char *name, int icon, int x1, int y1, int x2, int y2);
eAutoPropButsReturn uiDefAutoButsRNA(
uiLayout *layout, struct PointerRNA *ptr,
- bool (*check_prop)(struct PointerRNA *, struct PropertyRNA *),
+ bool (*check_prop)(struct PointerRNA *ptr, struct PropertyRNA *prop, void *user_data), void *user_data,
eButLabelAlign label_align, const bool compact);
/* use inside searchfunc to add items */
@@ -935,6 +935,7 @@ enum {
UI_TEMPLATE_OP_PROPS_SHOW_TITLE = (1 << 0),
UI_TEMPLATE_OP_PROPS_SHOW_EMPTY = (1 << 1),
UI_TEMPLATE_OP_PROPS_COMPACT = (1 << 2),
+ UI_TEMPLATE_OP_PROPS_HIDE_ADVANCED = (1 << 3),
};
/* used for transp checkers */
@@ -1085,7 +1086,6 @@ void UI_but_func_operator_search(uiBut *but);
void uiTemplateOperatorSearch(uiLayout *layout);
eAutoPropButsReturn uiTemplateOperatorPropertyButs(
const struct bContext *C, uiLayout *layout, struct wmOperator *op,
- bool (*check_prop)(struct PointerRNA *, struct PropertyRNA *),
const eButLabelAlign label_align, const short flag);
void uiTemplateHeader3D_mode(uiLayout *layout, struct bContext *C);
void uiTemplateHeader3D(uiLayout *layout, struct bContext *C);
diff --git a/source/blender/editors/include/UI_interface_icons.h b/source/blender/editors/include/UI_interface_icons.h
index 651081c46bb..a34c4938b86 100644
--- a/source/blender/editors/include/UI_interface_icons.h
+++ b/source/blender/editors/include/UI_interface_icons.h
@@ -59,7 +59,7 @@ typedef struct IconFile {
/*
* Resizable Icons for Blender
*/
-void UI_icons_init(int first_dyn_id);
+void UI_icons_init(void);
int UI_icon_get_width(int icon_id);
int UI_icon_get_height(int icon_id);
diff --git a/source/blender/editors/interface/interface_icons.c b/source/blender/editors/interface/interface_icons.c
index 22b82898288..7255640bedc 100644
--- a/source/blender/editors/interface/interface_icons.c
+++ b/source/blender/editors/interface/interface_icons.c
@@ -934,9 +934,8 @@ int UI_icon_get_height(int icon_id)
return 0;
}
-void UI_icons_init(int first_dyn_id)
+void UI_icons_init()
{
- BKE_icons_init(first_dyn_id);
#ifndef WITH_HEADLESS
init_iconfile_list(&iconfilelist);
init_internal_icons();
diff --git a/source/blender/editors/interface/interface_panel.c b/source/blender/editors/interface/interface_panel.c
index 59fdf7e672d..aa67d58fd57 100644
--- a/source/blender/editors/interface/interface_panel.c
+++ b/source/blender/editors/interface/interface_panel.c
@@ -454,9 +454,9 @@ static void ui_offset_panel_block(uiBlock *block)
/* triangle 'icon' for panel header */
void UI_draw_icon_tri(float x, float y, char dir, const float color[4])
{
- float f3 = 0.15 * U.widget_unit;
- float f5 = 0.25 * U.widget_unit;
- float f7 = 0.35 * U.widget_unit;
+ float f3 = 0.05 * U.widget_unit;
+ float f5 = 0.15 * U.widget_unit;
+ float f7 = 0.25 * U.widget_unit;
if (dir == 'h') {
UI_draw_anti_tria(x - f3, y - f5, x - f3, y + f5, x + f7, y, color);
diff --git a/source/blender/editors/interface/interface_templates.c b/source/blender/editors/interface/interface_templates.c
index 2dcc18af4ea..131ffbca377 100644
--- a/source/blender/editors/interface/interface_templates.c
+++ b/source/blender/editors/interface/interface_templates.c
@@ -1542,11 +1542,6 @@ uiLayout *uiTemplateModifier(uiLayout *layout, bContext *C, PointerRNA *ptr)
/************************ Redo Buttons Template *************************/
-static bool template_operator_redo_property_buts_poll(PointerRNA *UNUSED(ptr), PropertyRNA *prop)
-{
- return (RNA_property_tags(prop) & OP_PROP_TAG_ADVANCED) == 0;
-}
-
static void template_operator_redo_property_buts_draw(
const bContext *C, wmOperator *op,
uiLayout *layout, int layout_flags,
@@ -1560,8 +1555,9 @@ static void template_operator_redo_property_buts_draw(
else {
/* Might want to make label_align adjustable somehow. */
eAutoPropButsReturn return_info = uiTemplateOperatorPropertyButs(
- C, layout, op, r_has_advanced ? template_operator_redo_property_buts_poll : NULL,
- UI_BUT_LABEL_ALIGN_NONE, layout_flags);
+ C, layout, op,
+ UI_BUT_LABEL_ALIGN_NONE,
+ layout_flags);
if (return_info & UI_PROP_BUTS_ANY_FAILED_CHECK) {
if (r_has_advanced) {
*r_has_advanced = true;
@@ -3948,13 +3944,30 @@ static void ui_layout_operator_buts__reset_cb(bContext *UNUSED(C), void *op_pt,
}
#endif
+struct uiTemplateOperatorPropertyPollParam {
+ const bContext *C;
+ wmOperator *op;
+ short flag;
+};
+
+static bool ui_layout_operator_buts_poll_property(
+ struct PointerRNA *UNUSED(ptr), struct PropertyRNA *prop, void *user_data)
+{
+ struct uiTemplateOperatorPropertyPollParam *params = user_data;
+ if ((params->flag & UI_TEMPLATE_OP_PROPS_HIDE_ADVANCED) &&
+ (RNA_property_tags(prop) & OP_PROP_TAG_ADVANCED))
+ {
+ return false;
+ }
+ return params->op->type->poll_property(params->C, params->op, prop);
+}
+
/**
* Draw Operator property buttons for redoing execution with different settings.
* This function does not initialize the layout, functions can be called on the layout before and after.
*/
eAutoPropButsReturn uiTemplateOperatorPropertyButs(
const bContext *C, uiLayout *layout, wmOperator *op,
- bool (*check_prop)(struct PointerRNA *, struct PropertyRNA *),
const eButLabelAlign label_align, const short flag)
{
uiBlock *block = uiLayoutGetBlock(layout);
@@ -4013,13 +4026,32 @@ eAutoPropButsReturn uiTemplateOperatorPropertyButs(
else {
wmWindowManager *wm = CTX_wm_manager(C);
PointerRNA ptr;
+ struct uiTemplateOperatorPropertyPollParam user_data = {.C = C, .op = op, .flag = flag};
+
+
+
+#if 0
+static bool template_operator_redo_property_buts_poll(PointerRNA *UNUSED(ptr), PropertyRNA *prop)
+{
+}
+#endif
+
+
+
+
+
+
RNA_pointer_create(&wm->id, op->type->srna, op->properties, &ptr);
uiLayoutSetPropSep(layout, true);
/* main draw call */
- return_info = uiDefAutoButsRNA(layout, &ptr, check_prop, label_align, (flag & UI_TEMPLATE_OP_PROPS_COMPACT));
+ return_info = uiDefAutoButsRNA(
+ layout, &ptr,
+ op->type->poll_property ? ui_layout_operator_buts_poll_property : NULL,
+ op->type->poll_property ? &user_data : NULL,
+ label_align, (flag & UI_TEMPLATE_OP_PROPS_COMPACT));
if ((return_info & UI_PROP_BUTS_NONE_ADDED) && (flag & UI_TEMPLATE_OP_PROPS_SHOW_EMPTY)) {
uiItemL(layout, IFACE_("No Properties"), ICON_NONE);
diff --git a/source/blender/editors/interface/interface_utils.c b/source/blender/editors/interface/interface_utils.c
index d080397c488..60aa79e1093 100644
--- a/source/blender/editors/interface/interface_utils.c
+++ b/source/blender/editors/interface/interface_utils.c
@@ -159,7 +159,7 @@ uiBut *uiDefAutoButR(uiBlock *block, PointerRNA *ptr, PropertyRNA *prop, int ind
*/
eAutoPropButsReturn uiDefAutoButsRNA(
uiLayout *layout, PointerRNA *ptr,
- bool (*check_prop)(PointerRNA *, PropertyRNA *),
+ bool (*check_prop)(PointerRNA *ptr, PropertyRNA *prop, void *user_data), void *user_data,
const eButLabelAlign label_align, const bool compact)
{
eAutoPropButsReturn return_info = UI_PROP_BUTS_NONE_ADDED;
@@ -174,7 +174,7 @@ eAutoPropButsReturn uiDefAutoButsRNA(
if (flag & PROP_HIDDEN) {
continue;
}
- if (check_prop && check_prop(ptr, prop) == 0) {
+ if (check_prop && check_prop(ptr, prop, user_data) == 0) {
return_info |= UI_PROP_BUTS_ANY_FAILED_CHECK;
continue;
}
diff --git a/source/blender/editors/interface/resources.c b/source/blender/editors/interface/resources.c
index 47d664eaeb2..3cb8a277e9a 100644
--- a/source/blender/editors/interface/resources.c
+++ b/source/blender/editors/interface/resources.c
@@ -83,7 +83,7 @@ static struct bThemeState g_theme_state = {
void ui_resources_init(void)
{
- UI_icons_init(BIFICONID_LAST);
+ UI_icons_init();
}
void ui_resources_free(void)
diff --git a/source/blender/editors/mesh/editmesh_knife.c b/source/blender/editors/mesh/editmesh_knife.c
index 99756269c1f..61f55451b17 100644
--- a/source/blender/editors/mesh/editmesh_knife.c
+++ b/source/blender/editors/mesh/editmesh_knife.c
@@ -1048,14 +1048,15 @@ static void knifetool_draw(const bContext *UNUSED(C), ARegion *UNUSED(ar), void
GPU_matrix_push();
GPU_matrix_mul(kcd->ob->obmat);
+ if (kcd->mode == MODE_DRAGGING && kcd->is_angle_snapping) {
+ knifetool_draw_angle_snapping(kcd);
+ }
+
uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
if (kcd->mode == MODE_DRAGGING) {
- if (kcd->is_angle_snapping)
- knifetool_draw_angle_snapping(kcd);
-
immUniformColor3ubv(kcd->colors.line);
GPU_line_width(2.0);
diff --git a/source/blender/editors/mesh/editmesh_select.c b/source/blender/editors/mesh/editmesh_select.c
index 2e7cf1fc76f..cdb8981801a 100644
--- a/source/blender/editors/mesh/editmesh_select.c
+++ b/source/blender/editors/mesh/editmesh_select.c
@@ -1462,6 +1462,18 @@ static int edbm_select_mode_exec(bContext *C, wmOperator *op)
static int edbm_select_mode_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
+ /* Bypass when in UV non sync-select mode, fall through to keymap that edits. */
+ if (CTX_wm_space_image(C)) {
+ ToolSettings *ts = CTX_data_tool_settings(C);
+ if ((ts->uv_flag & UV_SYNC_SELECTION) == 0) {
+ return OPERATOR_PASS_THROUGH;
+ }
+ /* Bypass when no action is needed. */
+ if (!RNA_struct_property_is_set(op->ptr, "type")) {
+ return OPERATOR_CANCELLED;
+ }
+ }
+
/* detecting these options based on shift/ctrl here is weak, but it's done
* to make this work when clicking buttons or menus */
if (!RNA_struct_property_is_set(op->ptr, "use_extend"))
diff --git a/source/blender/editors/mesh/editmesh_tools.c b/source/blender/editors/mesh/editmesh_tools.c
index d7617a14ff3..b2a2291f4f6 100644
--- a/source/blender/editors/mesh/editmesh_tools.c
+++ b/source/blender/editors/mesh/editmesh_tools.c
@@ -6001,10 +6001,10 @@ static int edbm_sort_elements_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static bool edbm_sort_elements_draw_check_prop(PointerRNA *ptr, PropertyRNA *prop)
+static bool edbm_sort_elements_poll_property(const bContext *UNUSED(C), wmOperator *op, const PropertyRNA *prop)
{
const char *prop_id = RNA_property_identifier(prop);
- const int action = RNA_enum_get(ptr, "type");
+ const int action = RNA_enum_get(op->ptr, "type");
/* Only show seed for randomize action! */
if (STREQ(prop_id, "seed")) {
@@ -6025,18 +6025,6 @@ static bool edbm_sort_elements_draw_check_prop(PointerRNA *ptr, PropertyRNA *pro
return true;
}
-static void edbm_sort_elements_ui(bContext *C, wmOperator *op)
-{
- uiLayout *layout = op->layout;
- wmWindowManager *wm = CTX_wm_manager(C);
- PointerRNA ptr;
-
- RNA_pointer_create(&wm->id, op->type->srna, op->properties, &ptr);
-
- /* Main auto-draw call. */
- uiDefAutoButsRNA(layout, &ptr, edbm_sort_elements_draw_check_prop, UI_BUT_LABEL_ALIGN_NONE, false);
-}
-
void MESH_OT_sort_elements(wmOperatorType *ot)
{
static const EnumPropertyItem type_items[] = {
@@ -6072,7 +6060,7 @@ void MESH_OT_sort_elements(wmOperatorType *ot)
ot->invoke = WM_menu_invoke;
ot->exec = edbm_sort_elements_exec;
ot->poll = ED_operator_editmesh;
- ot->ui = edbm_sort_elements_ui;
+ ot->poll_property = edbm_sort_elements_poll_property;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
diff --git a/source/blender/editors/mesh/mesh_ops.c b/source/blender/editors/mesh/mesh_ops.c
index 0fcc5ada854..79c8f5c0b09 100644
--- a/source/blender/editors/mesh/mesh_ops.c
+++ b/source/blender/editors/mesh/mesh_ops.c
@@ -335,22 +335,8 @@ void ED_keymap_mesh(wmKeyConfig *keyconf)
kmi = WM_keymap_add_item(keymap, "MESH_OT_bevel", BKEY, KM_PRESS, KM_CTRL | KM_SHIFT, 0);
RNA_boolean_set(kmi->ptr, "vertex_only", true);
- /* selecting */
- for (int i = 0; i < 4; i++) {
- const bool is_extend = (i & 1);
- const bool is_expand = (i & 2);
- const int key_modifier = (is_extend ? KM_SHIFT : 0) | (is_expand ? KM_CTRL : 0);
- for (int j = 0; j < 3; j++) {
- kmi = WM_keymap_add_item(keymap, "MESH_OT_select_mode", ONEKEY + j, KM_PRESS, key_modifier, 0);
- RNA_enum_set(kmi->ptr, "type", SCE_SELECT_VERTEX << j);
- if (is_extend) {
- RNA_boolean_set(kmi->ptr, "use_extend", true);
- }
- if (is_expand) {
- RNA_boolean_set(kmi->ptr, "use_expand", true);
- }
- }
- }
+ /* Selec Vert/Edge/Face. */
+ ED_keymap_editmesh_elem_mode(keyconf, keymap);
/* standard mouse selection goes via space_view3d */
kmi = WM_keymap_add_item(keymap, "MESH_OT_loop_select", SELECTMOUSE, KM_PRESS, KM_ALT, 0);
diff --git a/source/blender/editors/object/object_bake_api.c b/source/blender/editors/object/object_bake_api.c
index b456342f8f0..1d93d664a5a 100644
--- a/source/blender/editors/object/object_bake_api.c
+++ b/source/blender/editors/object/object_bake_api.c
@@ -49,6 +49,7 @@
#include "BKE_context.h"
#include "BKE_global.h"
#include "BKE_image.h"
+#include "BKE_layer.h"
#include "BKE_library.h"
#include "BKE_main.h"
#include "BKE_material.h"
@@ -360,17 +361,24 @@ static bool is_noncolor_pass(eScenePassType pass_type)
}
/* if all is good tag image and return true */
-static bool bake_object_check(Scene *scene, Object *ob, ReportList *reports)
+static bool bake_object_check(ViewLayer *view_layer, Object *ob, ReportList *reports)
{
Image *image;
+ Base *base = BKE_view_layer_base_find(view_layer, ob);
void *lock;
int i;
- if ((ob->lay & scene->lay) == 0) {
- BKE_reportf(reports, RPT_ERROR, "Object \"%s\" is not on a scene layer", ob->id.name + 2);
+ if (base == NULL) {
+ BKE_reportf(reports, RPT_ERROR, "Object \"%s\" is not in view layer", ob->id.name + 2);
return false;
}
+ if (!(base->flag & BASE_ENABLED_RENDER)) {
+ BKE_reportf(reports, RPT_ERROR, "Object \"%s\" is not enabled for rendering", ob->id.name + 2);
+ return false;
+ }
+
+
if (ob->type != OB_MESH) {
BKE_reportf(reports, RPT_ERROR, "Object \"%s\" is not a mesh", ob->id.name + 2);
return false;
@@ -500,7 +508,7 @@ static bool bake_pass_filter_check(eScenePassType pass_type, const int pass_filt
}
/* before even getting in the bake function we check for some basic errors */
-static bool bake_objects_check(Main *bmain, Scene *scene, Object *ob, ListBase *selected_objects,
+static bool bake_objects_check(Main *bmain, ViewLayer *view_layer, Object *ob, ListBase *selected_objects,
ReportList *reports, const bool is_selected_to_active)
{
CollectionPointerLink *link;
@@ -511,7 +519,7 @@ static bool bake_objects_check(Main *bmain, Scene *scene, Object *ob, ListBase *
if (is_selected_to_active) {
int tot_objects = 0;
- if (!bake_object_check(scene, ob, reports))
+ if (!bake_object_check(view_layer, ob, reports))
return false;
for (link = selected_objects->first; link; link = link->next) {
@@ -539,7 +547,7 @@ static bool bake_objects_check(Main *bmain, Scene *scene, Object *ob, ListBase *
}
for (link = selected_objects->first; link; link = link->next) {
- if (!bake_object_check(scene, link->ptr.data, reports))
+ if (!bake_object_check(view_layer, link->ptr.data, reports))
return false;
}
}
@@ -1207,7 +1215,7 @@ static int bake_exec(bContext *C, wmOperator *op)
goto finally;
}
- if (!bake_objects_check(bkr.main, bkr.scene, bkr.ob, &bkr.selected_objects, bkr.reports, bkr.is_selected_to_active)) {
+ if (!bake_objects_check(bkr.main, bkr.view_layer, bkr.ob, &bkr.selected_objects, bkr.reports, bkr.is_selected_to_active)) {
goto finally;
}
@@ -1266,7 +1274,7 @@ static void bake_startjob(void *bkv, short *UNUSED(stop), short *do_update, floa
return;
}
- if (!bake_objects_check(bkr->main, bkr->scene, bkr->ob, &bkr->selected_objects, bkr->reports, bkr->is_selected_to_active)) {
+ if (!bake_objects_check(bkr->main, bkr->view_layer, bkr->ob, &bkr->selected_objects, bkr->reports, bkr->is_selected_to_active)) {
bkr->result = OPERATOR_CANCELLED;
return;
}
diff --git a/source/blender/editors/object/object_data_transfer.c b/source/blender/editors/object/object_data_transfer.c
index f56fd560946..ad0b091ede9 100644
--- a/source/blender/editors/object/object_data_transfer.c
+++ b/source/blender/editors/object/object_data_transfer.c
@@ -450,8 +450,9 @@ static bool data_transfer_poll(bContext *C)
}
/* Used by both OBJECT_OT_data_transfer and OBJECT_OT_datalayout_transfer */
-static bool data_transfer_draw_check_prop(PointerRNA *ptr, PropertyRNA *prop)
+static bool data_transfer_poll_property(const bContext *UNUSED(C), wmOperator *op, const PropertyRNA *prop)
{
+ PointerRNA *ptr = op->ptr;
PropertyRNA *prop_other;
const char *prop_id = RNA_property_identifier(prop);
@@ -512,19 +513,6 @@ static bool data_transfer_draw_check_prop(PointerRNA *ptr, PropertyRNA *prop)
return true;
}
-/* Used by both OBJECT_OT_data_transfer and OBJECT_OT_datalayout_transfer */
-static void data_transfer_ui(bContext *C, wmOperator *op)
-{
- uiLayout *layout = op->layout;
- wmWindowManager *wm = CTX_wm_manager(C);
- PointerRNA ptr;
-
- RNA_pointer_create(&wm->id, op->type->srna, op->properties, &ptr);
-
- /* Main auto-draw call */
- uiDefAutoButsRNA(layout, &ptr, data_transfer_draw_check_prop, UI_BUT_LABEL_ALIGN_NONE, false);
-}
-
/* transfers weight from active to selected */
void OBJECT_OT_data_transfer(wmOperatorType *ot)
{
@@ -537,10 +525,10 @@ void OBJECT_OT_data_transfer(wmOperatorType *ot)
/* API callbacks.*/
ot->poll = data_transfer_poll;
+ ot->poll_property = data_transfer_poll_property;
ot->invoke = WM_menu_invoke;
ot->exec = data_transfer_exec;
ot->check = data_transfer_check;
- ot->ui = data_transfer_ui;
/* Flags.*/
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
@@ -700,10 +688,10 @@ void OBJECT_OT_datalayout_transfer(wmOperatorType *ot)
ot->idname = "OBJECT_OT_datalayout_transfer";
ot->poll = datalayout_transfer_poll;
+ ot->poll_property = data_transfer_poll_property;
ot->invoke = datalayout_transfer_invoke;
ot->exec = datalayout_transfer_exec;
ot->check = data_transfer_check;
- ot->ui = data_transfer_ui;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
diff --git a/source/blender/editors/object/object_group.c b/source/blender/editors/object/object_group.c
index 53cabe3759e..72c5fde2955 100644
--- a/source/blender/editors/object/object_group.c
+++ b/source/blender/editors/object/object_group.c
@@ -411,6 +411,9 @@ static int collection_add_exec(bContext *C, wmOperator *UNUSED(op))
id_fake_user_set(&collection->id);
BKE_collection_object_add(bmain, collection, ob);
+ DEG_id_tag_update(&collection->id, DEG_TAG_COPY_ON_WRITE);
+ DEG_relations_tag_update(bmain);
+
WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob);
return OPERATOR_FINISHED;
@@ -460,6 +463,9 @@ static int collection_link_exec(bContext *C, wmOperator *op)
BKE_collection_object_add(bmain, collection, ob);
+ DEG_id_tag_update(&collection->id, DEG_TAG_COPY_ON_WRITE);
+ DEG_relations_tag_update(bmain);
+
WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob);
return OPERATOR_FINISHED;
@@ -500,6 +506,9 @@ static int collection_remove_exec(bContext *C, wmOperator *UNUSED(op))
BKE_collection_object_remove(bmain, collection, ob, false);
+ DEG_id_tag_update(&collection->id, DEG_TAG_COPY_ON_WRITE);
+ DEG_relations_tag_update(bmain);
+
WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob);
return OPERATOR_FINISHED;
@@ -531,6 +540,8 @@ static int collection_unlink_exec(bContext *C, wmOperator *UNUSED(op))
BKE_libblock_delete(bmain, collection);
+ DEG_relations_tag_update(bmain);
+
WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, NULL);
return OPERATOR_FINISHED;
diff --git a/source/blender/editors/object/object_ops.c b/source/blender/editors/object/object_ops.c
index 5a83d085aee..7b6c1156874 100644
--- a/source/blender/editors/object/object_ops.c
+++ b/source/blender/editors/object/object_ops.c
@@ -40,6 +40,7 @@
#include "BKE_context.h"
#include "RNA_access.h"
+#include "RNA_enum_types.h"
#include "WM_api.h"
#include "WM_types.h"
@@ -490,3 +491,26 @@ void ED_keymap_proportional_editmode(struct wmKeyConfig *UNUSED(keyconf), struct
RNA_string_set(kmi->ptr, "value_2", "CONNECTED");
}
}
+
+/**
+ * Map 1..3 to Vert/Edge/Face.
+ */
+void ED_keymap_editmesh_elem_mode(struct wmKeyConfig *UNUSED(keyconf), struct wmKeyMap *keymap)
+{
+ for (int i = 0; i < 4; i++) {
+ const bool is_extend = (i & 1);
+ const bool is_expand = (i & 2);
+ const int key_modifier = (is_extend ? KM_SHIFT : 0) | (is_expand ? KM_CTRL : 0);
+ for (int j = 0; j < 3; j++) {
+ wmKeyMapItem *kmi = WM_keymap_add_item(
+ keymap, "MESH_OT_select_mode", ONEKEY + j, KM_PRESS, key_modifier, 0);
+ RNA_enum_set(kmi->ptr, "type", SCE_SELECT_VERTEX << j);
+ if (is_extend) {
+ RNA_boolean_set(kmi->ptr, "use_extend", true);
+ }
+ if (is_expand) {
+ RNA_boolean_set(kmi->ptr, "use_expand", true);
+ }
+ }
+ }
+}
diff --git a/source/blender/editors/object/object_relations.c b/source/blender/editors/object/object_relations.c
index 2c3ff8b6afe..4745a484475 100644
--- a/source/blender/editors/object/object_relations.c
+++ b/source/blender/editors/object/object_relations.c
@@ -947,13 +947,13 @@ static int parent_set_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent
return OPERATOR_INTERFACE;
}
-static bool parent_set_draw_check_prop(PointerRNA *ptr, PropertyRNA *prop)
+static bool parent_set_poll_property(const bContext *UNUSED(C), wmOperator *op, const PropertyRNA *prop)
{
const char *prop_id = RNA_property_identifier(prop);
- const int type = RNA_enum_get(ptr, "type");
/* Only show XMirror for PAR_ARMATURE_ENVELOPE and PAR_ARMATURE_AUTO! */
if (STREQ(prop_id, "xmirror")) {
+ const int type = RNA_enum_get(op->ptr, "type");
if (ELEM(type, PAR_ARMATURE_ENVELOPE, PAR_ARMATURE_AUTO))
return true;
else
@@ -963,18 +963,6 @@ static bool parent_set_draw_check_prop(PointerRNA *ptr, PropertyRNA *prop)
return true;
}
-static void parent_set_ui(bContext *C, wmOperator *op)
-{
- uiLayout *layout = op->layout;
- wmWindowManager *wm = CTX_wm_manager(C);
- PointerRNA ptr;
-
- RNA_pointer_create(&wm->id, op->type->srna, op->properties, &ptr);
-
- /* Main auto-draw call. */
- uiDefAutoButsRNA(layout, &ptr, parent_set_draw_check_prop, UI_BUT_LABEL_ALIGN_NONE, false);
-}
-
void OBJECT_OT_parent_set(wmOperatorType *ot)
{
/* identifiers */
@@ -986,7 +974,7 @@ void OBJECT_OT_parent_set(wmOperatorType *ot)
ot->invoke = parent_set_invoke;
ot->exec = parent_set_exec;
ot->poll = ED_operator_object_active;
- ot->ui = parent_set_ui;
+ ot->poll_property = parent_set_poll_property;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
@@ -2329,6 +2317,7 @@ static int make_override_static_exec(bContext *C, wmOperator *op)
if (new_ob != NULL && new_ob->id.override_static != NULL) {
if ((base = BKE_view_layer_base_find(view_layer, new_ob)) == NULL) {
BKE_collection_object_add_from(bmain, scene, obcollection, new_ob);
+ base = BKE_view_layer_base_find(view_layer, new_ob);
DEG_id_tag_update_ex(bmain, &new_ob->id, DEG_TAG_TRANSFORM | DEG_TAG_BASE_FLAGS_UPDATE);
}
/* parent to 'collection' empty */
diff --git a/source/blender/editors/screen/screendump.c b/source/blender/editors/screen/screendump.c
index afaad3963d5..9c0c59a7160 100644
--- a/source/blender/editors/screen/screendump.c
+++ b/source/blender/editors/screen/screendump.c
@@ -247,7 +247,7 @@ static void screenshot_cancel(bContext *UNUSED(C), wmOperator *op)
screenshot_data_free(op);
}
-static bool screenshot_draw_check_prop(PointerRNA *UNUSED(ptr), PropertyRNA *prop)
+static bool screenshot_draw_check_prop(PointerRNA *UNUSED(ptr), PropertyRNA *prop, void *UNUSED(user_data))
{
const char *prop_id = RNA_property_identifier(prop);
@@ -266,7 +266,7 @@ static void screenshot_draw(bContext *UNUSED(C), wmOperator *op)
/* main draw call */
RNA_pointer_create(NULL, op->type->srna, op->properties, &ptr);
- uiDefAutoButsRNA(layout, &ptr, screenshot_draw_check_prop, UI_BUT_LABEL_ALIGN_NONE, false);
+ uiDefAutoButsRNA(layout, &ptr, screenshot_draw_check_prop, NULL, UI_BUT_LABEL_ALIGN_NONE, false);
}
static bool screenshot_poll(bContext *C)
diff --git a/source/blender/editors/sound/sound_ops.c b/source/blender/editors/sound/sound_ops.c
index 3fc68a50057..15f688549a8 100644
--- a/source/blender/editors/sound/sound_ops.c
+++ b/source/blender/editors/sound/sound_ops.c
@@ -482,7 +482,7 @@ static int sound_mixdown_invoke(bContext *C, wmOperator *op, const wmEvent *even
#ifdef WITH_AUDASPACE
-static bool sound_mixdown_draw_check_prop(PointerRNA *UNUSED(ptr), PropertyRNA *prop)
+static bool sound_mixdown_draw_check_prop(PointerRNA *UNUSED(ptr), PropertyRNA *prop, void *UNUSED(user_data))
{
const char *prop_id = RNA_property_identifier(prop);
return !(STREQ(prop_id, "filepath") ||
@@ -635,7 +635,7 @@ static void sound_mixdown_draw(bContext *C, wmOperator *op)
RNA_pointer_create(&wm->id, op->type->srna, op->properties, &ptr);
/* main draw call */
- uiDefAutoButsRNA(layout, &ptr, sound_mixdown_draw_check_prop, UI_BUT_LABEL_ALIGN_NONE, false);
+ uiDefAutoButsRNA(layout, &ptr, sound_mixdown_draw_check_prop, NULL, UI_BUT_LABEL_ALIGN_NONE, false);
}
#endif // WITH_AUDASPACE
diff --git a/source/blender/editors/space_file/file_panels.c b/source/blender/editors/space_file/file_panels.c
index 812a671ff33..abe9f173b09 100644
--- a/source/blender/editors/space_file/file_panels.c
+++ b/source/blender/editors/space_file/file_panels.c
@@ -43,6 +43,7 @@
#include "MEM_guardedalloc.h"
#include "RNA_access.h"
+#include "RNA_define.h"
#include "ED_fileselect.h"
@@ -71,25 +72,28 @@ static void file_panel_operator_header(const bContext *C, Panel *pa)
BLI_strncpy(pa->drawname, RNA_struct_ui_name(op->type->srna), sizeof(pa->drawname));
}
-static bool file_panel_check_prop(PointerRNA *UNUSED(ptr), PropertyRNA *prop)
-{
- const char *prop_id = RNA_property_identifier(prop);
- return !(STREQ(prop_id, "filepath") ||
- STREQ(prop_id, "directory") ||
- STREQ(prop_id, "filename")
- );
-}
-
static void file_panel_operator(const bContext *C, Panel *pa)
{
SpaceFile *sfile = CTX_wm_space_file(C);
wmOperator *op = sfile->op;
- // int empty = 1, flag;
UI_block_func_set(uiLayoutGetBlock(pa->layout), file_draw_check_cb, NULL, NULL);
- uiTemplateOperatorPropertyButs(C, pa->layout, op, file_panel_check_prop, UI_BUT_LABEL_ALIGN_NONE,
- UI_TEMPLATE_OP_PROPS_SHOW_EMPTY);
+ /* Hack: temporary hide.*/
+ const char *hide[3] = {"filepath", "directory", "filename"};
+ for (int i = 0; i < ARRAY_SIZE(hide); i++) {
+ PropertyRNA *prop = RNA_struct_find_property(op->ptr, "filepath");
+ RNA_def_property_flag(prop, PROP_HIDDEN);
+ }
+
+ uiTemplateOperatorPropertyButs(
+ C, pa->layout, op, UI_BUT_LABEL_ALIGN_NONE,
+ UI_TEMPLATE_OP_PROPS_SHOW_EMPTY);
+
+ for (int i = 0; i < ARRAY_SIZE(hide); i++) {
+ PropertyRNA *prop = RNA_struct_find_property(op->ptr, "filepath");
+ RNA_def_property_clear_flag(prop, PROP_HIDDEN);
+ }
UI_block_func_set(uiLayoutGetBlock(pa->layout), NULL, NULL, NULL);
}
diff --git a/source/blender/editors/space_image/image_ops.c b/source/blender/editors/space_image/image_ops.c
index f1012c46f2f..bcbfa1342d5 100644
--- a/source/blender/editors/space_image/image_ops.c
+++ b/source/blender/editors/space_image/image_ops.c
@@ -1487,7 +1487,7 @@ static int image_open_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(
return OPERATOR_RUNNING_MODAL;
}
-static bool image_open_draw_check_prop(PointerRNA *UNUSED(ptr), PropertyRNA *prop)
+static bool image_open_draw_check_prop(PointerRNA *UNUSED(ptr), PropertyRNA *prop, void *UNUSED(user_data))
{
const char *prop_id = RNA_property_identifier(prop);
@@ -1506,7 +1506,7 @@ static void image_open_draw(bContext *UNUSED(C), wmOperator *op)
/* main draw call */
RNA_pointer_create(NULL, op->type->srna, op->properties, &ptr);
- uiDefAutoButsRNA(layout, &ptr, image_open_draw_check_prop, UI_BUT_LABEL_ALIGN_NONE, false);
+ uiDefAutoButsRNA(layout, &ptr, image_open_draw_check_prop, NULL, UI_BUT_LABEL_ALIGN_NONE, false);
/* image template */
RNA_pointer_create(NULL, &RNA_ImageFormatSettings, imf, &imf_ptr);
@@ -2243,7 +2243,7 @@ static void image_save_as_cancel(bContext *UNUSED(C), wmOperator *op)
image_save_as_free(op);
}
-static bool image_save_as_draw_check_prop(PointerRNA *ptr, PropertyRNA *prop)
+static bool image_save_as_draw_check_prop(PointerRNA *ptr, PropertyRNA *prop, void *UNUSED(user_data))
{
const char *prop_id = RNA_property_identifier(prop);
@@ -2268,7 +2268,7 @@ static void image_save_as_draw(bContext *UNUSED(C), wmOperator *op)
/* main draw call */
RNA_pointer_create(NULL, op->type->srna, op->properties, &ptr);
- uiDefAutoButsRNA(layout, &ptr, image_save_as_draw_check_prop, UI_BUT_LABEL_ALIGN_NONE, false);
+ uiDefAutoButsRNA(layout, &ptr, image_save_as_draw_check_prop, NULL, UI_BUT_LABEL_ALIGN_NONE, false);
/* multiview template */
if (is_multiview)
diff --git a/source/blender/editors/space_node/node_draw.c b/source/blender/editors/space_node/node_draw.c
index 4b3a3abc642..bba46771674 100644
--- a/source/blender/editors/space_node/node_draw.c
+++ b/source/blender/editors/space_node/node_draw.c
@@ -951,18 +951,18 @@ static void node_draw_basis(const bContext *C, ARegion *ar, SpaceNode *snode, bN
/* open/close entirely? */
{
uiBut *but;
- int but_size = UI_UNIT_X * 0.6f;
+ int but_size = UI_UNIT_X * 1.2f;
/* XXX button uses a custom triangle draw below, so make it invisible without icon */
UI_block_emboss_set(node->block, UI_EMBOSS_NONE);
but = uiDefBut(node->block, UI_BTYPE_BUT_TOGGLE, B_REDR, "",
- rct->xmin + 0.5f * U.widget_unit - but_size / 2, rct->ymax - NODE_DY / 2.0f - but_size / 2,
+ rct->xmin + 0.6f * U.widget_unit - but_size / 2, rct->ymax - NODE_DY / 2.2f - but_size / 2,
but_size, but_size, NULL, 0, 0, 0, 0, "");
UI_but_func_set(but, node_toggle_button_cb, node, (void *)"NODE_OT_hide_toggle");
UI_block_emboss_set(node->block, UI_EMBOSS);
UI_GetThemeColor4fv(TH_TEXT, color);
/* custom draw function for this button */
- UI_draw_icon_tri(rct->xmin + 0.5f * U.widget_unit, rct->ymax - NODE_DY / 2.0f, 'v', color);
+ UI_draw_icon_tri(rct->xmin + 0.6f * U.widget_unit, rct->ymax - NODE_DY / 2.2f, 'v', color);
}
nodeLabel(ntree, node, showname, sizeof(showname));
@@ -1071,7 +1071,7 @@ static void node_draw_hidden(const bContext *C, ARegion *ar, SpaceNode *snode, b
/* open entirely icon */
{
uiBut *but;
- int but_size = UI_UNIT_X * 0.6f;
+ int but_size = UI_UNIT_X * 1.2f;
/* XXX button uses a custom triangle draw below, so make it invisible without icon */
UI_block_emboss_set(node->block, UI_EMBOSS_NONE);
but = uiDefBut(node->block, UI_BTYPE_BUT_TOGGLE, B_REDR, "",
diff --git a/source/blender/editors/space_node/node_intern.h b/source/blender/editors/space_node/node_intern.h
index ed7379acca9..3644c8d09e6 100644
--- a/source/blender/editors/space_node/node_intern.h
+++ b/source/blender/editors/space_node/node_intern.h
@@ -238,7 +238,7 @@ extern const char *node_context_dir[];
// nodes draw without dpi - the view zoom is flexible
#define HIDDEN_RAD (0.75f * U.widget_unit)
-#define BASIS_RAD (0.4f * U.widget_unit)
+#define BASIS_RAD (0.2f * U.widget_unit)
#define NODE_DYS (U.widget_unit / 2)
#define NODE_DY U.widget_unit
#define NODE_SOCKDY (0.08f * U.widget_unit)
diff --git a/source/blender/editors/space_outliner/outliner_collections.c b/source/blender/editors/space_outliner/outliner_collections.c
index ad94615a0d2..e480cac2dcc 100644
--- a/source/blender/editors/space_outliner/outliner_collections.c
+++ b/source/blender/editors/space_outliner/outliner_collections.c
@@ -574,7 +574,7 @@ static TreeTraversalAction layer_collection_find_data_to_edit(TreeElement *te, v
return TRAVERSE_CONTINUE;
}
-static bool collections_view_layer_poll(bContext *C, bool include)
+static bool collections_view_layer_poll(bContext *C, bool clear, int flag)
{
/* Poll function so the right click menu show current state of selected collections. */
SpaceOops *soops = CTX_wm_space_outliner(C);
@@ -593,10 +593,10 @@ static bool collections_view_layer_poll(bContext *C, bool include)
GSET_ITER(collections_to_edit_iter, data.collections_to_edit) {
LayerCollection *lc = BLI_gsetIterator_getKey(&collections_to_edit_iter);
- if (include && (lc->flag & LAYER_COLLECTION_EXCLUDE)) {
+ if (clear && (lc->flag & flag)) {
result = true;
}
- else if (!include && !(lc->flag & LAYER_COLLECTION_EXCLUDE)) {
+ else if (!clear && !(lc->flag & flag)) {
result = true;
}
}
@@ -605,27 +605,47 @@ static bool collections_view_layer_poll(bContext *C, bool include)
return result;
}
-static bool collections_exclude_poll(bContext *C)
+static bool collections_exclude_set_poll(bContext *C)
{
- return collections_view_layer_poll(C, false);
+ return collections_view_layer_poll(C, false, LAYER_COLLECTION_EXCLUDE);
}
-static bool collections_include_poll(bContext *C)
+static bool collections_exclude_clear_poll(bContext *C)
{
- return collections_view_layer_poll(C, true);
+ return collections_view_layer_poll(C, true, LAYER_COLLECTION_EXCLUDE);
}
-static void layer_collection_exclude_recursive_set(LayerCollection *lc)
+static bool collections_holdout_set_poll(bContext *C)
+{
+ return collections_view_layer_poll(C, false, LAYER_COLLECTION_HOLDOUT);
+}
+
+static bool collections_holdout_clear_poll(bContext *C)
+{
+ return collections_view_layer_poll(C, true, LAYER_COLLECTION_HOLDOUT);
+}
+
+static bool collections_indirect_only_set_poll(bContext *C)
+{
+ return collections_view_layer_poll(C, false, LAYER_COLLECTION_INDIRECT_ONLY);
+}
+
+static bool collections_indirect_only_clear_poll(bContext *C)
+{
+ return collections_view_layer_poll(C, true, LAYER_COLLECTION_INDIRECT_ONLY);
+}
+
+static void layer_collection_flag_recursive_set(LayerCollection *lc, int flag)
{
for (LayerCollection *nlc = lc->layer_collections.first; nlc; nlc = nlc->next) {
- if (lc->flag & LAYER_COLLECTION_EXCLUDE) {
- nlc->flag |= LAYER_COLLECTION_EXCLUDE;
+ if (lc->flag & flag) {
+ nlc->flag |= flag;
}
else {
- nlc->flag &= ~LAYER_COLLECTION_EXCLUDE;
+ nlc->flag &= ~flag;
}
- layer_collection_exclude_recursive_set(nlc);
+ layer_collection_flag_recursive_set(nlc, flag);
}
}
@@ -636,7 +656,10 @@ static int collection_view_layer_exec(bContext *C, wmOperator *op)
ViewLayer *view_layer = CTX_data_view_layer(C);
SpaceOops *soops = CTX_wm_space_outliner(C);
struct CollectionEditData data = {.scene = scene, .soops = soops};
- bool include = STREQ(op->idname, "OUTLINER_OT_collection_include_set");
+ bool clear = strstr(op->idname, "clear") != NULL;
+ int flag = strstr(op->idname, "holdout") ? LAYER_COLLECTION_HOLDOUT :
+ strstr(op->idname, "indirect_only") ? LAYER_COLLECTION_INDIRECT_ONLY :
+ LAYER_COLLECTION_EXCLUDE;
data.collections_to_edit = BLI_gset_ptr_new(__func__);
@@ -647,14 +670,14 @@ static int collection_view_layer_exec(bContext *C, wmOperator *op)
LayerCollection *lc = BLI_gsetIterator_getKey(&collections_to_edit_iter);
if (!(lc->collection->flag & COLLECTION_IS_MASTER)) {
- if (include) {
- lc->flag &= ~LAYER_COLLECTION_EXCLUDE;
+ if (clear) {
+ lc->flag &= ~flag;
}
else {
- lc->flag |= LAYER_COLLECTION_EXCLUDE;
+ lc->flag |= flag;
}
- layer_collection_exclude_recursive_set(lc);
+ layer_collection_flag_recursive_set(lc, flag);
}
}
@@ -671,28 +694,88 @@ static int collection_view_layer_exec(bContext *C, wmOperator *op)
void OUTLINER_OT_collection_exclude_set(wmOperatorType *ot)
{
/* identifiers */
- ot->name = "Exclude from View Layer";
+ ot->name = "Set Exclude";
ot->idname = "OUTLINER_OT_collection_exclude_set";
ot->description = "Exclude collection from the active view layer";
/* api callbacks */
ot->exec = collection_view_layer_exec;
- ot->poll = collections_exclude_poll;
+ ot->poll = collections_exclude_set_poll;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
-void OUTLINER_OT_collection_include_set(wmOperatorType *ot)
+void OUTLINER_OT_collection_exclude_clear(wmOperatorType *ot)
{
/* identifiers */
- ot->name = "Include in View Layer";
- ot->idname = "OUTLINER_OT_collection_include_set";
+ ot->name = "Clear Exclude";
+ ot->idname = "OUTLINER_OT_collection_exclude_clear";
ot->description = "Include collection in the active view layer";
/* api callbacks */
ot->exec = collection_view_layer_exec;
- ot->poll = collections_include_poll;
+ ot->poll = collections_exclude_clear_poll;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+}
+
+void OUTLINER_OT_collection_holdout_set(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Set Holdout";
+ ot->idname = "OUTLINER_OT_collection_holdout_set";
+ ot->description = "Mask collection in the active view layer";
+
+ /* api callbacks */
+ ot->exec = collection_view_layer_exec;
+ ot->poll = collections_holdout_set_poll;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+}
+
+void OUTLINER_OT_collection_holdout_clear(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Clear Holdout";
+ ot->idname = "OUTLINER_OT_collection_holdout_clear";
+ ot->description = "Clear masking of collection in the active view layer";
+
+ /* api callbacks */
+ ot->exec = collection_view_layer_exec;
+ ot->poll = collections_holdout_clear_poll;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+}
+
+void OUTLINER_OT_collection_indirect_only_set(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Set Indirect Only";
+ ot->idname = "OUTLINER_OT_collection_indirect_only_set";
+ ot->description = "Set collection to only contribute indirectly (through shadows and reflections) in the view layer";
+
+ /* api callbacks */
+ ot->exec = collection_view_layer_exec;
+ ot->poll = collections_indirect_only_set_poll;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+}
+
+void OUTLINER_OT_collection_indirect_only_clear(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Clear Indirect Only";
+ ot->idname = "OUTLINER_OT_collection_indirect_only_clear";
+ ot->description = "Clear collection contributing only indirectly in the view layer";
+
+ /* api callbacks */
+ ot->exec = collection_view_layer_exec;
+ ot->poll = collections_indirect_only_clear_poll;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
diff --git a/source/blender/editors/space_outliner/outliner_draw.c b/source/blender/editors/space_outliner/outliner_draw.c
index 783a03f3993..e1049d02e37 100644
--- a/source/blender/editors/space_outliner/outliner_draw.c
+++ b/source/blender/editors/space_outliner/outliner_draw.c
@@ -1341,16 +1341,9 @@ static void tselem_draw_icon(
static void outliner_draw_iconrow_number(
const uiFontStyle *fstyle,
int offsx, int ys,
- const eOLDrawState active,
const int num_elements)
{
- float color[4] = {0.4f, 0.4f, 0.4f, 0.9f};
- copy_v3_fl(color, 0.2f);
- if (active != OL_DRAWSEL_NONE) {
- copy_v3_fl(color, 0.65f);
- color[3] = 1.0f;
- }
-
+ float color[4] = {0.0f, 0.0f, 0.0f, 1.0f};
float ufac = 0.25f * UI_UNIT_X;
float offset_x = (float) offsx + UI_UNIT_X * 0.35f;
@@ -1414,13 +1407,13 @@ static void outliner_draw_iconrow_doit(
}
/* No inlined icon should be clickable. */
- tselem_draw_icon(block, xmax, (float)*offsx, (float)ys, tselem, te, 0.5f * alpha_fac, false);
+ tselem_draw_icon(block, xmax, (float)*offsx, (float)ys, tselem, te, 0.8f * alpha_fac, false);
te->xs = *offsx;
te->ys = ys;
te->xend = (short)*offsx + UI_UNIT_X;
if (num_elements > 1) {
- outliner_draw_iconrow_number(fstyle, *offsx, ys, active, num_elements);
+ outliner_draw_iconrow_number(fstyle, *offsx, ys, num_elements);
}
(*offsx) += UI_UNIT_X;
}
diff --git a/source/blender/editors/space_outliner/outliner_intern.h b/source/blender/editors/space_outliner/outliner_intern.h
index 093ad9361c2..461d4bd7c56 100644
--- a/source/blender/editors/space_outliner/outliner_intern.h
+++ b/source/blender/editors/space_outliner/outliner_intern.h
@@ -358,7 +358,11 @@ void OUTLINER_OT_collection_objects_deselect(struct wmOperatorType *ot);
void OUTLINER_OT_collection_link(struct wmOperatorType *ot);
void OUTLINER_OT_collection_instance(struct wmOperatorType *ot);
void OUTLINER_OT_collection_exclude_set(struct wmOperatorType *ot);
-void OUTLINER_OT_collection_include_set(struct wmOperatorType *ot);
+void OUTLINER_OT_collection_exclude_clear(struct wmOperatorType *ot);
+void OUTLINER_OT_collection_holdout_set(struct wmOperatorType *ot);
+void OUTLINER_OT_collection_holdout_clear(struct wmOperatorType *ot);
+void OUTLINER_OT_collection_indirect_only_set(struct wmOperatorType *ot);
+void OUTLINER_OT_collection_indirect_only_clear(struct wmOperatorType *ot);
/* outliner_utils.c ---------------------------------------------- */
diff --git a/source/blender/editors/space_outliner/outliner_ops.c b/source/blender/editors/space_outliner/outliner_ops.c
index 0dd492839c9..576038979d3 100644
--- a/source/blender/editors/space_outliner/outliner_ops.c
+++ b/source/blender/editors/space_outliner/outliner_ops.c
@@ -457,7 +457,11 @@ void outliner_operatortypes(void)
WM_operatortype_append(OUTLINER_OT_collection_link);
WM_operatortype_append(OUTLINER_OT_collection_instance);
WM_operatortype_append(OUTLINER_OT_collection_exclude_set);
- WM_operatortype_append(OUTLINER_OT_collection_include_set);
+ WM_operatortype_append(OUTLINER_OT_collection_exclude_clear);
+ WM_operatortype_append(OUTLINER_OT_collection_holdout_set);
+ WM_operatortype_append(OUTLINER_OT_collection_holdout_clear);
+ WM_operatortype_append(OUTLINER_OT_collection_indirect_only_set);
+ WM_operatortype_append(OUTLINER_OT_collection_indirect_only_clear);
}
static wmKeyMap *outliner_item_drag_drop_modal_keymap(wmKeyConfig *keyconf)
@@ -570,6 +574,9 @@ void outliner_keymap(wmKeyConfig *keyconf)
WM_keymap_add_item(keymap, "OBJECT_OT_move_to_collection", MKEY, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, "OBJECT_OT_link_to_collection", MKEY, KM_PRESS, KM_SHIFT, 0);
+ WM_keymap_add_item(keymap, "OUTLINER_OT_collection_exclude_set", EKEY, KM_PRESS, 0, 0);
+ WM_keymap_add_item(keymap, "OUTLINER_OT_collection_exclude_clear", EKEY, KM_PRESS, KM_ALT, 0);
+
kmi = WM_keymap_add_item(keymap, "OBJECT_OT_hide_view_clear", HKEY, KM_PRESS, KM_ALT, 0);
RNA_boolean_set(kmi->ptr, "select", false);
kmi = WM_keymap_add_item(keymap, "OBJECT_OT_hide_view_set", HKEY, KM_PRESS, 0, 0);
diff --git a/source/blender/editors/space_sequencer/sequencer_add.c b/source/blender/editors/space_sequencer/sequencer_add.c
index 5d2ceced904..3cd5bfc3e58 100644
--- a/source/blender/editors/space_sequencer/sequencer_add.c
+++ b/source/blender/editors/space_sequencer/sequencer_add.c
@@ -627,7 +627,7 @@ static void sequencer_add_cancel(bContext *UNUSED(C), wmOperator *op)
op->customdata = NULL;
}
-static bool sequencer_add_draw_check_prop(PointerRNA *UNUSED(ptr), PropertyRNA *prop)
+static bool sequencer_add_draw_check_prop(PointerRNA *UNUSED(ptr), PropertyRNA *prop, void *UNUSED(user_data))
{
const char *prop_id = RNA_property_identifier(prop);
@@ -693,7 +693,7 @@ static void sequencer_add_draw(bContext *UNUSED(C), wmOperator *op)
/* main draw call */
RNA_pointer_create(NULL, op->type->srna, op->properties, &ptr);
- uiDefAutoButsRNA(layout, &ptr, sequencer_add_draw_check_prop, UI_BUT_LABEL_ALIGN_NONE, false);
+ uiDefAutoButsRNA(layout, &ptr, sequencer_add_draw_check_prop, NULL, UI_BUT_LABEL_ALIGN_NONE, false);
/* image template */
RNA_pointer_create(NULL, &RNA_ImageFormatSettings, imf, &imf_ptr);
diff --git a/source/blender/editors/space_sequencer/sequencer_edit.c b/source/blender/editors/space_sequencer/sequencer_edit.c
index cefc6cdd814..199ff06cc8b 100644
--- a/source/blender/editors/space_sequencer/sequencer_edit.c
+++ b/source/blender/editors/space_sequencer/sequencer_edit.c
@@ -739,7 +739,7 @@ static Sequence *cut_seq_hard(Scene *scene, Sequence *seq, int cutframe)
if (!skip_dup) {
/* Duplicate AFTER the first change */
- seqn = BKE_sequence_dupli_recursive(scene, scene, seq, SEQ_DUPE_UNIQUE_NAME | SEQ_DUPE_ANIM);
+ seqn = BKE_sequence_dupli_recursive(scene, scene, seq, SEQ_DUPE_ANIM);
}
if (seqn) {
@@ -848,7 +848,7 @@ static Sequence *cut_seq_soft(Scene *scene, Sequence *seq, int cutframe)
if (!skip_dup) {
/* Duplicate AFTER the first change */
- seqn = BKE_sequence_dupli_recursive(scene, scene, seq, SEQ_DUPE_UNIQUE_NAME | SEQ_DUPE_ANIM);
+ seqn = BKE_sequence_dupli_recursive(scene, scene, seq, SEQ_DUPE_ANIM);
}
if (seqn) {
@@ -2091,6 +2091,7 @@ static int sequencer_cut_exec(bContext *C, wmOperator *op)
SEQP_BEGIN (ed, seq)
{
+ BKE_sequence_base_unique_name_recursive(&ed->seqbase, seq);
if (seq->seq1 || seq->seq2 || seq->seq3) {
BKE_sequence_calc(scene, seq);
}
diff --git a/source/blender/editors/space_view3d/space_view3d.c b/source/blender/editors/space_view3d/space_view3d.c
index 71bdd2e20c2..2577077002e 100644
--- a/source/blender/editors/space_view3d/space_view3d.c
+++ b/source/blender/editors/space_view3d/space_view3d.c
@@ -1406,7 +1406,7 @@ static void space_view3d_listener(
switch (wmn->data) {
case ND_WORLD_DRAW:
case ND_WORLD:
- if (v3d->flag3 & V3D_SHOW_WORLD)
+ if (v3d->shading.background_type & V3D_SHADING_BACKGROUND_WORLD)
ED_area_tag_redraw_regiontype(sa, RGN_TYPE_WINDOW);
break;
}
diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c
index 552d84ebb39..941f9262694 100644
--- a/source/blender/editors/space_view3d/view3d_draw.c
+++ b/source/blender/editors/space_view3d/view3d_draw.c
@@ -1599,7 +1599,7 @@ ImBuf *ED_view3d_draw_offscreen_imbuf_simple(
v3d.flag2 |= V3D_SOLID_TEX;
}
- v3d.flag3 |= V3D_SHOW_WORLD;
+ v3d.shading.background_type = V3D_SHADING_BACKGROUND_WORLD;
if (draw_flags & V3D_OFSDRAW_USE_CAMERA_DOF) {
if (camera->type == OB_CAMERA) {
diff --git a/source/blender/editors/space_view3d/view3d_snap.c b/source/blender/editors/space_view3d/view3d_snap.c
index 7799854db49..6a8589f5468 100644
--- a/source/blender/editors/space_view3d/view3d_snap.c
+++ b/source/blender/editors/space_view3d/view3d_snap.c
@@ -72,6 +72,7 @@ static bool snap_calc_active_center(bContext *C, const bool select_only, float r
/* *********************** operators ******************** */
+/** Snaps every individual object center to its nearest point on the grid. **/
static int snap_sel_to_grid_exec(bContext *C, wmOperator *UNUSED(op))
{
Depsgraph *depsgraph = CTX_data_depsgraph(C);
@@ -212,7 +213,7 @@ void VIEW3D_OT_snap_selected_to_grid(wmOperatorType *ot)
{
/* identifiers */
ot->name = "Snap Selection to Grid";
- ot->description = "Snap selected item(s) to nearest grid division";
+ ot->description = "Snap selected item(s) to their nearest grid division";
ot->idname = "VIEW3D_OT_snap_selected_to_grid";
/* api callbacks */
@@ -225,6 +226,12 @@ void VIEW3D_OT_snap_selected_to_grid(wmOperatorType *ot)
/* *************************************************** */
+/** Snaps the selection as a whole (use_offset=true) or each selected object to the given location.
+ *
+ * \param snap_target_global: a location in global space to snap to (eg. 3D cursor or active object).
+ * \param use_offset: if the selected objects should maintain their relative offsets and be snapped by the selection
+ * pivot point (median, active), or if every object origin should be snapped to the given location.
+**/
static int snap_selected_to_location(bContext *C, const float snap_target_global[3], const bool use_offset)
{
Depsgraph *depsgraph = CTX_data_depsgraph(C);
@@ -434,7 +441,7 @@ void VIEW3D_OT_snap_selected_to_cursor(wmOperatorType *ot)
{
/* identifiers */
ot->name = "Snap Selection to Cursor";
- ot->description = "Snap selected item(s) to cursor";
+ ot->description = "Snap selected item(s) to the 3D cursor";
ot->idname = "VIEW3D_OT_snap_selected_to_cursor";
/* api callbacks */
@@ -445,9 +452,13 @@ void VIEW3D_OT_snap_selected_to_cursor(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
/* rna */
- RNA_def_boolean(ot->srna, "use_offset", 1, "Offset", "");
+ RNA_def_boolean(ot->srna, "use_offset", 1, "Offset",
+ "If the selection should be snapped as a whole or by each object center");
}
+/* *************************************************** */
+
+/** Snaps each selected object to the location of the active selected object. **/
static int snap_selected_to_active_exec(bContext *C, wmOperator *op)
{
float snap_target_global[3];
@@ -478,6 +489,7 @@ void VIEW3D_OT_snap_selected_to_active(wmOperatorType *ot)
/* *************************************************** */
+/** Snaps the 3D cursor location to its nearest point on the grid. **/
static int snap_curs_to_grid_exec(bContext *C, wmOperator *UNUSED(op))
{
Scene *scene = CTX_data_scene(C);
@@ -502,7 +514,7 @@ void VIEW3D_OT_snap_cursor_to_grid(wmOperatorType *ot)
{
/* identifiers */
ot->name = "Snap Cursor to Grid";
- ot->description = "Snap cursor to nearest grid division";
+ ot->description = "Snap 3D cursor to the nearest grid division";
ot->idname = "VIEW3D_OT_snap_cursor_to_grid";
/* api callbacks */
@@ -515,7 +527,8 @@ void VIEW3D_OT_snap_cursor_to_grid(wmOperatorType *ot)
/* **************************************************** */
-static void bundle_midpoint(Depsgraph *depsgraph, Scene *scene, Object *ob, float vec[3])
+/** Returns the center position of a tracking marker visible on the viewport (useful to snap to). **/
+static void bundle_midpoint(Depsgraph *depsgraph, Scene *scene, Object *ob, float r_vec[3])
{
MovieClip *clip = BKE_object_movieclip_get(scene, ob, false);
MovieTracking *tracking;
@@ -563,10 +576,11 @@ static void bundle_midpoint(Depsgraph *depsgraph, Scene *scene, Object *ob, floa
}
if (ok) {
- mid_v3_v3v3(vec, min, max);
+ mid_v3_v3v3(r_vec, min, max);
}
}
+/** Snaps the 3D cursor location to the median point of the selection. **/
static bool snap_curs_to_sel_ex(bContext *C, float cursor[3])
{
Depsgraph *depsgraph = CTX_data_depsgraph(C);
@@ -690,7 +704,7 @@ void VIEW3D_OT_snap_cursor_to_selected(wmOperatorType *ot)
{
/* identifiers */
ot->name = "Snap Cursor to Selected";
- ot->description = "Snap cursor to center of selected item(s)";
+ ot->description = "Snap 3D cursor to the middle of the selected item(s)";
ot->idname = "VIEW3D_OT_snap_cursor_to_selected";
/* api callbacks */
@@ -703,9 +717,11 @@ void VIEW3D_OT_snap_cursor_to_selected(wmOperatorType *ot)
/* ********************************************** */
-/* this could be exported to be a generic function
- * see: calculateCenterActive */
-
+/** Calculates the center position of the active object in global space.
+ *
+ * Note: this could be exported to be a generic function.
+ * see: calculateCenterActive
+**/
static bool snap_calc_active_center(bContext *C, const bool select_only, float r_center[3])
{
const Depsgraph *depsgraph = CTX_data_depsgraph(C);
@@ -770,7 +786,7 @@ void VIEW3D_OT_snap_cursor_to_active(wmOperatorType *ot)
{
/* identifiers */
ot->name = "Snap Cursor to Active";
- ot->description = "Snap cursor to active item";
+ ot->description = "Snap 3D cursor to the active item";
ot->idname = "VIEW3D_OT_snap_cursor_to_active";
/* api callbacks */
@@ -782,7 +798,8 @@ void VIEW3D_OT_snap_cursor_to_active(wmOperatorType *ot)
}
/* **************************************************** */
-/*New Code - Snap Cursor to Center -*/
+
+/** Snaps the 3D cursor location to the origin. **/
static int snap_curs_to_center_exec(bContext *C, wmOperator *UNUSED(op))
{
Scene *scene = CTX_data_scene(C);
@@ -802,7 +819,7 @@ void VIEW3D_OT_snap_cursor_to_center(wmOperatorType *ot)
{
/* identifiers */
ot->name = "Snap Cursor to Center";
- ot->description = "Snap cursor to world origin";
+ ot->description = "Snap 3D cursor to the world origin";
ot->idname = "VIEW3D_OT_snap_cursor_to_center";
/* api callbacks */
@@ -815,23 +832,22 @@ void VIEW3D_OT_snap_cursor_to_center(wmOperatorType *ot)
/* **************************************************** */
-
-bool ED_view3d_minmax_verts(Object *obedit, float min[3], float max[3])
+/** Calculates the bounding box corners (min and max) for \a obedit. The returned values are in global space. **/
+bool ED_view3d_minmax_verts(Object *obedit, float r_min[3], float r_max[3])
{
TransVertStore tvs = {NULL};
TransVert *tv;
float centroid[3], vec[3], bmat[3][3];
- int a;
- /* metaballs are an exception */
+ /* Metaballs are an exception. */
if (obedit->type == OB_MBALL) {
float ob_min[3], ob_max[3];
bool changed;
changed = BKE_mball_minmax_ex(obedit->data, ob_min, ob_max, obedit->obmat, SELECT);
if (changed) {
- minmax_v3v3_v3(min, max, ob_min);
- minmax_v3v3_v3(min, max, ob_max);
+ minmax_v3v3_v3(r_min, r_max, ob_min);
+ minmax_v3v3_v3(r_min, r_max, ob_max);
}
return changed;
}
@@ -845,12 +861,12 @@ bool ED_view3d_minmax_verts(Object *obedit, float min[3], float max[3])
copy_m3_m4(bmat, obedit->obmat);
tv = tvs.transverts;
- for (a = 0; a < tvs.transverts_tot; a++, tv++) {
+ for (int a = 0; a < tvs.transverts_tot; a++, tv++) {
copy_v3_v3(vec, (tv->flag & TX_VERT_USE_MAPLOC) ? tv->maploc : tv->loc);
mul_m3_v3(bmat, vec);
add_v3_v3(vec, obedit->obmat[3]);
add_v3_v3(centroid, vec);
- minmax_v3v3_v3(min, max, vec);
+ minmax_v3v3_v3(r_min, r_max, vec);
}
ED_transverts_free(&tvs);
diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c
index dab53c04806..07ef6b9a819 100644
--- a/source/blender/editors/transform/transform.c
+++ b/source/blender/editors/transform/transform.c
@@ -2153,7 +2153,11 @@ void saveTransform(bContext *C, TransInfo *t, wmOperator *op)
}
}
- RNA_property_boolean_set_array(op->ptr, prop, constraint_axis);
+ /* Only set if needed, so we can hide in the UI when nothing is set.
+ * See 'transform_poll_property'. */
+ if (ELEM(true, UNPACK3(constraint_axis))) {
+ RNA_property_boolean_set_array(op->ptr, prop, constraint_axis);
+ }
}
{
diff --git a/source/blender/editors/transform/transform_ops.c b/source/blender/editors/transform/transform_ops.c
index c9a97c8530c..580bae71cc8 100644
--- a/source/blender/editors/transform/transform_ops.c
+++ b/source/blender/editors/transform/transform_ops.c
@@ -507,6 +507,36 @@ static int transform_invoke(bContext *C, wmOperator *op, const wmEvent *event)
}
}
+static bool transform_poll_property(const bContext *UNUSED(C), wmOperator *op, const PropertyRNA *prop)
+{
+ const char *prop_id = RNA_property_identifier(prop);
+
+ /* Orientation/Constraints. */
+ {
+ /* Hide orientation axis if no constraints are set, since it wont be used. */
+ PropertyRNA *prop_con = RNA_struct_find_property(op->ptr, "constraint_axis");
+ if (prop_con && !RNA_property_is_set(op->ptr, prop_con)) {
+ if (STRPREFIX(prop_id, "constraint")) {
+ return false;
+ }
+ }
+ }
+
+ /* Proportional Editing. */
+ {
+ PropertyRNA *prop_pet = RNA_struct_find_property(op->ptr, "proportional");
+ if (prop_pet && (prop_pet != prop) &&
+ (RNA_property_enum_get(op->ptr, prop_pet) == PROP_EDIT_OFF))
+ {
+ if (STRPREFIX(prop_id, "proportional")) {
+ return false;
+ }
+ }
+ }
+
+ return true;
+}
+
void Transform_Properties(struct wmOperatorType *ot, int flags)
{
PropertyRNA *prop;
@@ -615,6 +645,7 @@ static void TRANSFORM_OT_translate(struct wmOperatorType *ot)
ot->modal = transform_modal;
ot->cancel = transform_cancel;
ot->poll = ED_operator_screenactive;
+ ot->poll_property = transform_poll_property;
RNA_def_float_vector_xyz(ot->srna, "value", 3, NULL, -FLT_MAX, FLT_MAX, "Vector", "", -FLT_MAX, FLT_MAX);
@@ -640,6 +671,7 @@ static void TRANSFORM_OT_resize(struct wmOperatorType *ot)
ot->modal = transform_modal;
ot->cancel = transform_cancel;
ot->poll = ED_operator_screenactive;
+ ot->poll_property = transform_poll_property;
RNA_def_float_vector(ot->srna, "value", 3, VecOne, -FLT_MAX, FLT_MAX, "Vector", "", -FLT_MAX, FLT_MAX);
@@ -673,6 +705,7 @@ static void TRANSFORM_OT_skin_resize(struct wmOperatorType *ot)
ot->modal = transform_modal;
ot->cancel = transform_cancel;
ot->poll = skin_resize_poll;
+ ot->poll_property = transform_poll_property;
RNA_def_float_vector(ot->srna, "value", 3, VecOne, -FLT_MAX, FLT_MAX, "Vector", "", -FLT_MAX, FLT_MAX);
@@ -695,6 +728,7 @@ static void TRANSFORM_OT_trackball(struct wmOperatorType *ot)
ot->modal = transform_modal;
ot->cancel = transform_cancel;
ot->poll = ED_operator_screenactive;
+ ot->poll_property = transform_poll_property;
/* Maybe we could use float_vector_xyz here too? */
RNA_def_float_rotation(ot->srna, "value", 2, NULL, -FLT_MAX, FLT_MAX, "Angle", "", -FLT_MAX, FLT_MAX);
@@ -718,6 +752,7 @@ static void TRANSFORM_OT_rotate(struct wmOperatorType *ot)
ot->modal = transform_modal;
ot->cancel = transform_cancel;
ot->poll = ED_operator_screenactive;
+ ot->poll_property = transform_poll_property;
RNA_def_float_rotation(ot->srna, "value", 0, NULL, -FLT_MAX, FLT_MAX, "Angle", "", -M_PI * 2, M_PI * 2);
@@ -744,6 +779,7 @@ static void TRANSFORM_OT_tilt(struct wmOperatorType *ot)
ot->modal = transform_modal;
ot->cancel = transform_cancel;
ot->poll = ED_operator_editcurve_3d;
+ ot->poll_property = transform_poll_property;
RNA_def_float_rotation(ot->srna, "value", 0, NULL, -FLT_MAX, FLT_MAX, "Angle", "", -M_PI * 2, M_PI * 2);
@@ -766,6 +802,7 @@ static void TRANSFORM_OT_bend(struct wmOperatorType *ot)
ot->modal = transform_modal;
ot->cancel = transform_cancel;
ot->poll = ED_operator_region_view3d_active;
+ ot->poll_property = transform_poll_property;
RNA_def_float_rotation(ot->srna, "value", 1, NULL, -FLT_MAX, FLT_MAX, "Angle", "", -M_PI * 2, M_PI * 2);
@@ -788,6 +825,7 @@ static void TRANSFORM_OT_shear(struct wmOperatorType *ot)
ot->modal = transform_modal;
ot->cancel = transform_cancel;
ot->poll = ED_operator_screenactive;
+ ot->poll_property = transform_poll_property;
RNA_def_float(ot->srna, "value", 0, -FLT_MAX, FLT_MAX, "Offset", "", -FLT_MAX, FLT_MAX);
@@ -811,6 +849,7 @@ static void TRANSFORM_OT_push_pull(struct wmOperatorType *ot)
ot->modal = transform_modal;
ot->cancel = transform_cancel;
ot->poll = ED_operator_screenactive;
+ ot->poll_property = transform_poll_property;
RNA_def_float(ot->srna, "value", 0, -FLT_MAX, FLT_MAX, "Distance", "", -FLT_MAX, FLT_MAX);
@@ -833,6 +872,7 @@ static void TRANSFORM_OT_shrink_fatten(struct wmOperatorType *ot)
ot->modal = transform_modal;
ot->cancel = transform_cancel;
ot->poll = ED_operator_editmesh;
+ ot->poll_property = transform_poll_property;
RNA_def_float(ot->srna, "value", 0, -FLT_MAX, FLT_MAX, "Offset", "", -FLT_MAX, FLT_MAX);
@@ -858,6 +898,7 @@ static void TRANSFORM_OT_tosphere(struct wmOperatorType *ot)
ot->modal = transform_modal;
ot->cancel = transform_cancel;
ot->poll = ED_operator_screenactive;
+ ot->poll_property = transform_poll_property;
RNA_def_float_factor(ot->srna, "value", 0, 0, 1, "Factor", "", 0, 1);
@@ -880,6 +921,7 @@ static void TRANSFORM_OT_mirror(struct wmOperatorType *ot)
ot->modal = transform_modal;
ot->cancel = transform_cancel;
ot->poll = ED_operator_screenactive;
+ ot->poll_property = transform_poll_property;
Transform_Properties(ot, P_CONSTRAINT | P_PROPORTIONAL | P_GPENCIL_EDIT | P_CENTER);
}
@@ -900,6 +942,7 @@ static void TRANSFORM_OT_edge_slide(struct wmOperatorType *ot)
ot->modal = transform_modal;
ot->cancel = transform_cancel;
ot->poll = ED_operator_editmesh_region_view3d;
+ ot->poll_property = transform_poll_property;
RNA_def_float_factor(ot->srna, "value", 0, -10.0f, 10.0f, "Factor", "", -1.0f, 1.0f);
@@ -932,6 +975,7 @@ static void TRANSFORM_OT_vert_slide(struct wmOperatorType *ot)
ot->modal = transform_modal;
ot->cancel = transform_cancel;
ot->poll = ED_operator_editmesh_region_view3d;
+ ot->poll_property = transform_poll_property;
RNA_def_float_factor(ot->srna, "value", 0, -10.0f, 10.0f, "Factor", "", -1.0f, 1.0f);
RNA_def_boolean(ot->srna, "use_even", false, "Even",
@@ -961,6 +1005,7 @@ static void TRANSFORM_OT_edge_crease(struct wmOperatorType *ot)
ot->modal = transform_modal;
ot->cancel = transform_cancel;
ot->poll = ED_operator_editmesh;
+ ot->poll_property = transform_poll_property;
RNA_def_float_factor(ot->srna, "value", 0, -1.0f, 1.0f, "Factor", "", -1.0f, 1.0f);
@@ -1050,6 +1095,7 @@ static void TRANSFORM_OT_transform(struct wmOperatorType *ot)
ot->modal = transform_modal;
ot->cancel = transform_cancel;
ot->poll = ED_operator_screenactive;
+ ot->poll_property = transform_poll_property;
prop = RNA_def_enum(ot->srna, "mode", rna_enum_transform_mode_types, TFM_TRANSLATION, "Mode", "");
RNA_def_property_flag(prop, PROP_HIDDEN);
diff --git a/source/blender/editors/transform/transform_snap.c b/source/blender/editors/transform/transform_snap.c
index b67fd22dbff..54253e36351 100644
--- a/source/blender/editors/transform/transform_snap.c
+++ b/source/blender/editors/transform/transform_snap.c
@@ -1462,7 +1462,7 @@ void snapSequenceBounds(TransInfo *t, const int mval[2])
float xmouse, ymouse;
int frame;
int mframe;
- TransSeq *ts = t->custom.type.data;
+ TransSeq *ts = TRANS_DATA_CONTAINER_FIRST_SINGLE(t)->custom.type.data;
/* reuse increment, strictly speaking could be another snap mode, but leave as is */
if (!(t->modifiers & MOD_SNAP_INVERT))
return;
diff --git a/source/blender/editors/transform/transform_snap_object.c b/source/blender/editors/transform/transform_snap_object.c
index e19320fa220..a6e857c4a60 100644
--- a/source/blender/editors/transform/transform_snap_object.c
+++ b/source/blender/editors/transform/transform_snap_object.c
@@ -111,6 +111,10 @@ typedef struct SnapObjectData_EditMesh {
SnapObjectData sd;
BVHTreeFromEditMesh *bvh_trees[3];
+ /* It's like a boundbox. It is tested first to avoid
+ * to create a bvhtree for all the edited objects. */
+ float min[3], max[3];
+
} SnapObjectData_EditMesh;
struct SnapObjectContext {
@@ -156,6 +160,39 @@ struct SnapObjectContext {
typedef void(*IterSnapObjsCallback)(SnapObjectContext *sctx, bool is_obedit, Object *ob, float obmat[4][4], void *data);
+static void min_max_from_bmesh(
+ BMesh *bm, float r_min[3], float r_max[3])
+{
+ BMIter iter;
+ BMVert *eve;
+
+ INIT_MINMAX(r_min, r_max);
+ BM_ITER_MESH(eve, &iter, bm, BM_VERTS_OF_MESH) {
+ minmax_v3v3_v3(r_min, r_max, eve->co);
+ }
+}
+
+static SnapObjectData_Mesh *snap_object_data_mesh_create(SnapObjectContext *sctx)
+{
+ SnapObjectData_Mesh *sod = BLI_memarena_calloc(sctx->cache.mem_arena, sizeof(*sod));
+ sod->sd.type = SNAP_MESH;
+ /* start assuming that it has each of these element types */
+ sod->has_looptris = true;
+ sod->has_loose_edge = true;
+ sod->has_loose_vert = true;
+
+ return sod;
+}
+
+static SnapObjectData_EditMesh *snap_object_data_editmesh_create(SnapObjectContext *sctx, BMesh *bm)
+{
+ SnapObjectData_EditMesh *sod = BLI_memarena_calloc(sctx->cache.mem_arena, sizeof(*sod));
+ sod->sd.type = SNAP_EDIT_MESH;
+ min_max_from_bmesh(bm, sod->min, sod->max);
+
+ return sod;
+}
+
/**
* Walks through all objects in the scene to create the list of objets to snap.
*
@@ -169,9 +206,9 @@ static void iter_snap_objects(
IterSnapObjsCallback sob_callback,
void *data)
{
- ViewLayer *view_layer = DEG_get_evaluated_view_layer(sctx->depsgraph);
- Object *obedit = params->use_object_edit_cage ? OBEDIT_FROM_VIEW_LAYER(view_layer) : NULL;
+ ViewLayer *view_layer = DEG_get_input_view_layer(sctx->depsgraph);
const eSnapSelect snap_select = params->snap_select;
+ const bool use_object_edit_cage = params->use_object_edit_cage;
Base *base_act = view_layer->basact;
for (Base *base = view_layer->object_bases.first; base != NULL; base = base->next) {
@@ -179,20 +216,17 @@ static void iter_snap_objects(
!((snap_select == SNAP_NOT_SELECTED && ((base->flag & BASE_SELECTED) || (base->flag_legacy & BA_WAS_SEL))) ||
(snap_select == SNAP_NOT_ACTIVE && base == base_act)))
{
- bool use_obedit;
- Object *obj = base->object;
- if (obj->transflag & OB_DUPLI) {
+ Object *obj_eval = DEG_get_evaluated_object(sctx->depsgraph, base->object);
+ if (obj_eval->transflag & OB_DUPLI) {
DupliObject *dupli_ob;
- ListBase *lb = object_duplilist(sctx->depsgraph, sctx->scene, obj);
+ ListBase *lb = object_duplilist(sctx->depsgraph, sctx->scene, obj_eval);
for (dupli_ob = lb->first; dupli_ob; dupli_ob = dupli_ob->next) {
- use_obedit = obedit && dupli_ob->ob->data == obedit->data;
- sob_callback(sctx, use_obedit, use_obedit ? obedit : dupli_ob->ob, dupli_ob->mat, data);
+ sob_callback(sctx, use_object_edit_cage, dupli_ob->ob, dupli_ob->mat, data);
}
free_object_duplilist(lb);
}
- use_obedit = obedit && obj->data == obedit->data;
- sob_callback(sctx, use_obedit, use_obedit ? obedit : obj, obj->obmat, data);
+ sob_callback(sctx, use_object_edit_cage, obj_eval, obj_eval->obmat, data);
}
}
}
@@ -372,13 +406,12 @@ static bool raycastMesh(
sod = *sod_p;
}
else {
- sod = *sod_p = BLI_memarena_calloc(sctx->cache.mem_arena, sizeof(*sod));
- sod->sd.type = SNAP_MESH;
+ sod = *sod_p = snap_object_data_mesh_create(sctx);
}
BVHTreeFromMesh *treedata = &sod->treedata;
- /* The tree is owned by the DM and may have been freed since we last used. */
+ /* The tree is owned by the Mesh and may have been freed since we last used. */
if (treedata->tree) {
BLI_assert(treedata->cached);
if (!bvhcache_has_tree(me->runtime.bvh_cache, treedata->tree)) {
@@ -502,14 +535,30 @@ static bool raycastEditMesh(
SnapObjectData_EditMesh *sod = NULL;
BVHTreeFromEditMesh *treedata = NULL;
+ Object *em_ob = em->ob;
+
+ BLI_assert(em_ob->data == BKE_object_get_pre_modified_mesh(ob));
void **sod_p;
- if (BLI_ghash_ensure_p(sctx->cache.object_map, ob, &sod_p)) {
+ /* Use `em->ob` as the key in ghash since the editmesh is used
+ * to create bvhtree and is the same for each linked object. */
+ if (BLI_ghash_ensure_p(sctx->cache.object_map, em_ob, &sod_p)) {
sod = *sod_p;
}
else {
- sod = *sod_p = BLI_memarena_calloc(sctx->cache.mem_arena, sizeof(*sod));
- sod->sd.type = SNAP_EDIT_MESH;
+ sod = *sod_p = snap_object_data_editmesh_create(sctx, em->bm);
+ }
+
+ {
+ float min[3], max[3];
+ mul_v3_m4v3(min, obmat, sod->min);
+ mul_v3_m4v3(max, obmat, sod->max);
+
+ if (!isect_ray_aabb_v3_simple(
+ ray_start, ray_dir, min, max, NULL, NULL))
+ {
+ return retval;
+ }
}
if (sod->bvh_trees[2] == NULL) {
@@ -517,7 +566,17 @@ static bool raycastEditMesh(
}
treedata = sod->bvh_trees[2];
+ BVHCache *em_bvh_cache = ((Mesh *)em_ob->data)->runtime.bvh_cache;
+
+ if (sctx->callbacks.edit_mesh.test_face_fn == NULL) {
+ /* The tree is owned by the Mesh and may have been freed since we last used! */
+ if (!bvhcache_has_tree(em_bvh_cache, treedata->tree)) {
+ free_bvhtree_from_editmesh(treedata);
+ }
+ }
+
if (treedata->tree == NULL) {
+ BVHCache **bvh_cache = NULL;
BLI_bitmap *elem_mask = NULL;
int looptri_num_active = -1;
@@ -527,7 +586,15 @@ static bool raycastEditMesh(
em->bm, elem_mask,
sctx->callbacks.edit_mesh.test_face_fn, sctx->callbacks.edit_mesh.user_data);
}
- bvhtree_from_editmesh_looptri_ex(treedata, em, elem_mask, looptri_num_active, 0.0f, 4, 6, NULL);
+ else {
+ /* Only cache if bvhtree is created without a mask.
+ * This helps keep a standardized bvhtree in cache. */
+ bvh_cache = &em_bvh_cache;
+ }
+
+ bvhtree_from_editmesh_looptri_ex(
+ treedata, em, elem_mask, looptri_num_active,
+ 0.0f, 4, 6, bvh_cache);
if (elem_mask) {
MEM_freeN(elem_mask);
@@ -669,7 +736,7 @@ static bool raycastObj(
switch (ob->type) {
case OB_MESH:
- if (use_obedit) {
+ if (use_obedit && BKE_object_is_in_editmode(ob)) {
BMEditMesh *em = BKE_editmesh_from_object(ob);
retval = raycastEditMesh(
sctx,
@@ -718,7 +785,7 @@ struct RaycastObjUserData {
bool ret;
};
-static void raycast_obj_cb(SnapObjectContext *sctx, bool is_obedit, Object *ob, float obmat[4][4], void *data)
+static void raycast_obj_cb(SnapObjectContext *sctx, bool use_obedit, Object *ob, float obmat[4][4], void *data)
{
struct RaycastObjUserData *dt = data;
@@ -726,7 +793,7 @@ static void raycast_obj_cb(SnapObjectContext *sctx, bool is_obedit, Object *ob,
sctx,
dt->ray_start, dt->ray_dir,
ob, obmat, dt->ob_index++,
- is_obedit, dt->use_occlusion_test,
+ use_obedit, dt->use_occlusion_test,
dt->ray_depth,
dt->r_loc, dt->r_no, dt->r_index,
dt->r_ob, dt->r_obmat,
@@ -1118,6 +1185,13 @@ static short snap_mesh_polygon(
};
SnapObjectData *sod = BLI_ghash_lookup(sctx->cache.object_map, ob);
+ if (sod == NULL) {
+ /* The object is in edit mode, and the key used
+ * was the object referenced in BMEditMesh */
+ BMEditMesh *em = BKE_editmesh_from_object(ob);
+ sod = BLI_ghash_lookup(sctx->cache.object_map, em->ob);
+ }
+
BLI_assert(sod != NULL);
if (sod->type == SNAP_MESH) {
@@ -1335,6 +1409,8 @@ static short snapArmature(
dist_squared_to_projected_aabb_precalc(
&neasrest_precalc, lpmat, snapdata->win_size, snapdata->mval);
+ use_obedit = use_obedit && BKE_object_is_in_editmode(ob);
+
if (use_obedit == false) {
/* Test BoundBox */
BoundBox *bb = BKE_armature_boundbox_get(ob);
@@ -1469,6 +1545,8 @@ static short snapCurve(
dist_squared_to_projected_aabb_precalc(
&neasrest_precalc, lpmat, snapdata->win_size, snapdata->mval);
+ use_obedit = use_obedit && BKE_object_is_in_editmode(ob);
+
if (use_obedit == false) {
/* Test BoundBox */
BoundBox *bb = BKE_curve_boundbox_get(ob);
@@ -1779,12 +1857,7 @@ static short snapMesh(
sod = *sod_p;
}
else {
- sod = *sod_p = BLI_memarena_calloc(sctx->cache.mem_arena, sizeof(*sod));
- sod->sd.type = SNAP_MESH;
- /* start assuming that it has each of these element types */
- sod->has_looptris = true;
- sod->has_loose_edge = true;
- sod->has_loose_vert = true;
+ sod = *sod_p = snap_object_data_mesh_create(sctx);
}
BVHTreeFromMesh *treedata, dummy_treedata;
@@ -1792,7 +1865,7 @@ static short snapMesh(
treedata = &sod->treedata;
bvhtree = sod->bvhtree;
- /* the tree is owned by the DM and may have been freed since we last used! */
+ /* The tree is owned by the Mesh and may have been freed since we last used! */
if ((sod->has_looptris && treedata->tree && !bvhcache_has_tree(me->runtime.bvh_cache, treedata->tree)) ||
(sod->has_loose_edge && bvhtree[0] && !bvhcache_has_tree(me->runtime.bvh_cache, bvhtree[0])) ||
(sod->has_loose_vert && bvhtree[1] && !bvhcache_has_tree(me->runtime.bvh_cache, bvhtree[1])))
@@ -1982,21 +2055,57 @@ static short snapEditMesh(
SnapObjectData_EditMesh *sod = NULL;
BVHTreeFromEditMesh *treedata_vert = NULL, *treedata_edge = NULL;
+ Object *em_ob = em->ob;
+
+ BLI_assert(em_ob->data == BKE_object_get_pre_modified_mesh(ob));
+ UNUSED_VARS_NDEBUG(ob);
void **sod_p;
- if (BLI_ghash_ensure_p(sctx->cache.object_map, ob, &sod_p)) {
+ /* Use `em->ob` as the key in ghash since the editmesh is used
+ * to create bvhtree and is the same for each linked object. */
+ if (BLI_ghash_ensure_p(sctx->cache.object_map, em_ob, &sod_p)) {
sod = *sod_p;
}
else {
- sod = *sod_p = BLI_memarena_calloc(sctx->cache.mem_arena, sizeof(*sod));
- sod->sd.type = SNAP_EDIT_MESH;
+ sod = *sod_p = snap_object_data_editmesh_create(sctx, em->bm);
+ }
+
+ float dist_px_sq = SQUARE(*dist_px);
+
+ {
+ float min[3], max[3];
+ mul_v3_m4v3(min, obmat, sod->min);
+ mul_v3_m4v3(max, obmat, sod->max);
+
+ /* In vertex and edges you need to get the pixel distance from ray to BoundBox, see: T46099, T46816 */
+ struct DistProjectedAABBPrecalc data_precalc;
+ dist_squared_to_projected_aabb_precalc(
+ &data_precalc, snapdata->pmat, snapdata->win_size, snapdata->mval);
+
+ bool dummy[3];
+ float bb_dist_px_sq = dist_squared_to_projected_aabb(
+ &data_precalc, min, max, dummy);
+
+ if (bb_dist_px_sq > dist_px_sq) {
+ return 0;
+ }
}
+ BVHCache *em_bvh_cache = ((Mesh *)em_ob->data)->runtime.bvh_cache;
+
if (snapdata->snap_to_flag & SCE_SNAP_MODE_VERTEX) {
if (sod->bvh_trees[0] == NULL) {
sod->bvh_trees[0] = BLI_memarena_calloc(sctx->cache.mem_arena, sizeof(**sod->bvh_trees));
}
treedata_vert = sod->bvh_trees[0];
+
+ if (sctx->callbacks.edit_mesh.test_vert_fn == NULL) {
+ /* The tree is owned by the Mesh and may have been freed since we last used! */
+ if (!bvhcache_has_tree(em_bvh_cache, treedata_vert->tree)) {
+ free_bvhtree_from_editmesh(treedata_vert);
+ }
+ }
+
if (treedata_vert->tree == NULL) {
BLI_bitmap *verts_mask = NULL;
int verts_num_active = -1;
@@ -2006,9 +2115,13 @@ static short snapEditMesh(
BM_VERTS_OF_MESH, em->bm, verts_mask,
(bool(*)(BMElem *, void *))sctx->callbacks.edit_mesh.test_vert_fn,
sctx->callbacks.edit_mesh.user_data);
+
+ bvhtree_from_editmesh_verts_ex(treedata_vert, em, verts_mask, verts_num_active, 0.0f, 2, 6);
+ MEM_freeN(verts_mask);
+ }
+ else {
+ bvhtree_from_editmesh_verts(treedata_vert, em, 0.0f, 2, 6, &em_bvh_cache);
}
- bvhtree_from_editmesh_verts_ex(treedata_vert, em, verts_mask, verts_num_active, 0.0f, 2, 6);
- MEM_SAFE_FREE(verts_mask);
}
}
@@ -2017,6 +2130,14 @@ static short snapEditMesh(
sod->bvh_trees[1] = BLI_memarena_calloc(sctx->cache.mem_arena, sizeof(**sod->bvh_trees));
}
treedata_edge = sod->bvh_trees[1];
+
+ if (sctx->callbacks.edit_mesh.test_edge_fn == NULL) {
+ /* The tree is owned by the Mesh and may have been freed since we last used! */
+ if (!bvhcache_has_tree(em_bvh_cache, treedata_edge->tree)) {
+ free_bvhtree_from_editmesh(treedata_edge);
+ }
+ }
+
if (treedata_edge->tree == NULL) {
BLI_bitmap *edges_mask = NULL;
int edges_num_active = -1;
@@ -2027,9 +2148,12 @@ static short snapEditMesh(
(bool(*)(BMElem *, void *))sctx->callbacks.edit_mesh.test_edge_fn,
sctx->callbacks.edit_mesh.user_data);
+ bvhtree_from_editmesh_edges_ex(treedata_edge, em, edges_mask, edges_num_active, 0.0f, 2, 6);
+ MEM_freeN(edges_mask);
+ }
+ else {
+ bvhtree_from_editmesh_edges(treedata_edge, em, 0.0f, 2, 6, &em_bvh_cache);
}
- bvhtree_from_editmesh_edges_ex(treedata_edge, em, edges_mask, edges_num_active, 0.0f, 2, 6);
- MEM_SAFE_FREE(edges_mask);
}
}
@@ -2043,7 +2167,7 @@ static short snapEditMesh(
BVHTreeNearest nearest = {
.index = -1,
- .dist_sq = SQUARE(*dist_px),
+ .dist_sq = dist_px_sq,
};
int last_index = nearest.index;
short elem = SCE_SNAP_MODE_VERTEX;
@@ -2119,7 +2243,7 @@ static short snapObject(
switch (ob->type) {
case OB_MESH:
- if (use_obedit) {
+ if (use_obedit && BKE_object_is_in_editmode(ob)) {
BMEditMesh *em = BKE_editmesh_from_object(ob);
retval = snapEditMesh(
sctx, snapdata, ob, em, obmat,
diff --git a/source/blender/editors/uvedit/uvedit_ops.c b/source/blender/editors/uvedit/uvedit_ops.c
index 51e2c1b6334..32bf32b03ab 100644
--- a/source/blender/editors/uvedit/uvedit_ops.c
+++ b/source/blender/editors/uvedit/uvedit_ops.c
@@ -80,6 +80,7 @@
#include "RNA_access.h"
#include "RNA_define.h"
+#include "RNA_enum_types.h"
#include "WM_api.h"
#include "WM_types.h"
@@ -4404,6 +4405,15 @@ void ED_keymap_uvedit(wmKeyConfig *keyconf)
RNA_string_set(kmi->ptr, "data_path", "tool_settings.use_uv_sculpt");
#endif
+ /* Select Element (Sync Select: on) */
+ ED_keymap_editmesh_elem_mode(keyconf, keymap);
+ /* Hack to prevent fall-through, when the button isn't visible. */
+ WM_keymap_add_item(keymap, "MESH_OT_select_mode", FOURKEY, KM_PRESS, 0, 0);
+ /* Select Element (Sync Select: off) */
+ WM_keymap_add_context_enum_set_items(
+ keymap, rna_enum_mesh_select_mode_uv_items, "tool_settings.uv_select_mode",
+ ONEKEY, KM_PRESS, 0, 0);
+
/* Mark edge seam */
WM_keymap_add_item(keymap, "UV_OT_mark_seam", EKEY, KM_PRESS, KM_CTRL, 0);
diff --git a/source/blender/gpu/GPU_extensions.h b/source/blender/gpu/GPU_extensions.h
index d36b0ea15be..f435be7fb34 100644
--- a/source/blender/gpu/GPU_extensions.h
+++ b/source/blender/gpu/GPU_extensions.h
@@ -42,6 +42,7 @@ bool GPU_full_non_power_of_two_support(void);
bool GPU_bicubic_bump_support(void);
int GPU_max_texture_size(void);
+int GPU_max_texture_layers(void);
int GPU_max_textures(void);
float GPU_max_texture_anisotropy(void);
int GPU_max_color_texture_samples(void);
diff --git a/source/blender/gpu/GPU_material.h b/source/blender/gpu/GPU_material.h
index b3e56c3640a..d8132e7c088 100644
--- a/source/blender/gpu/GPU_material.h
+++ b/source/blender/gpu/GPU_material.h
@@ -55,7 +55,6 @@ struct GPUNodeStack;
struct GPUMaterial;
struct GPUTexture;
struct GPUUniformBuffer;
-struct GPULamp;
struct PreviewImage;
struct World;
struct bNode;
diff --git a/source/blender/gpu/intern/gpu_extensions.c b/source/blender/gpu/intern/gpu_extensions.c
index dff6cfb74a8..43081154e89 100644
--- a/source/blender/gpu/intern/gpu_extensions.c
+++ b/source/blender/gpu/intern/gpu_extensions.c
@@ -66,6 +66,7 @@
static struct GPUGlobal {
GLint maxtexsize;
+ GLint maxtexlayers;
GLint maxcubemapsize;
GLint maxtextures;
GLint maxubosize;
@@ -96,6 +97,11 @@ int GPU_max_texture_size(void)
return GG.maxtexsize;
}
+int GPU_max_texture_layers(void)
+{
+ return GG.maxtexlayers;
+}
+
int GPU_max_textures(void)
{
return GG.maxtextures;
@@ -142,6 +148,7 @@ void gpu_extensions_init(void)
glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &GG.maxtextures);
glGetIntegerv(GL_MAX_TEXTURE_SIZE, &GG.maxtexsize);
+ glGetIntegerv(GL_MAX_ARRAY_TEXTURE_LAYERS, &GG.maxtexlayers);
glGetIntegerv(GL_MAX_CUBE_MAP_TEXTURE_SIZE, &GG.maxcubemapsize);
if (GLEW_EXT_texture_filter_anisotropic)
diff --git a/source/blender/gpu/intern/gpu_texture.c b/source/blender/gpu/intern/gpu_texture.c
index 5ac746ec9c1..a5dfb6a6b73 100644
--- a/source/blender/gpu/intern/gpu_texture.c
+++ b/source/blender/gpu/intern/gpu_texture.c
@@ -160,6 +160,8 @@ static int gpu_get_component_count(GPUTextureFormat format)
/* Definitely not complete, edit according to the gl specification. */
static void gpu_validate_data_format(GPUTextureFormat tex_format, GPUDataFormat data_format)
{
+ (void)data_format;
+
if (ELEM(tex_format,
GPU_DEPTH_COMPONENT24,
GPU_DEPTH_COMPONENT16,
@@ -432,6 +434,11 @@ static bool gpu_texture_try_alloc(
glTexImage2D(proxy, 0, internalformat, tex->w, tex->h, 0, data_format, data_type, NULL);
break;
case GL_PROXY_TEXTURE_2D_ARRAY:
+ /* HACK: Some driver wrongly check GL_PROXY_TEXTURE_2D_ARRAY as a GL_PROXY_TEXTURE_3D
+ * checking all dimensions against GPU_max_texture_layers (see T55888). */
+ return (tex->w > 0) && (tex->w <= GPU_max_texture_size()) &&
+ (tex->h > 0) && (tex->h <= GPU_max_texture_size()) &&
+ (tex->d > 0) && (tex->d <= GPU_max_texture_layers());
case GL_PROXY_TEXTURE_3D:
glTexImage3D(proxy, 0, internalformat, tex->w, tex->h, tex->d, 0, data_format, data_type, NULL);
break;
diff --git a/source/blender/makesdna/DNA_layer_types.h b/source/blender/makesdna/DNA_layer_types.h
index bfdd21807b8..e6b1bda7cf5 100644
--- a/source/blender/makesdna/DNA_layer_types.h
+++ b/source/blender/makesdna/DNA_layer_types.h
@@ -104,6 +104,8 @@ enum {
BASE_ENABLED_VIEWPORT = (1 << 6), /* Object is enabled in viewport. */
BASE_ENABLED_RENDER = (1 << 7), /* Object is enabled in final render */
BASE_ENABLED = (1 << 9), /* Object is enabled. */
+ BASE_HOLDOUT = (1 << 10), /* Object masked out from render */
+ BASE_INDIRECT_ONLY = (1 << 11), /* Object only contributes indirectly to render */
};
/* LayerCollection->flag */
@@ -113,6 +115,8 @@ enum {
/* LAYER_COLLECTION_DEPRECATED2 = (1 << 2), */
/* LAYER_COLLECTION_DEPRECATED3 = (1 << 3), */
LAYER_COLLECTION_EXCLUDE = (1 << 4),
+ LAYER_COLLECTION_HOLDOUT = (1 << 5),
+ LAYER_COLLECTION_INDIRECT_ONLY = (1 << 6),
};
/* Layer Collection->runtime_flag */
diff --git a/source/blender/makesdna/DNA_object_types.h b/source/blender/makesdna/DNA_object_types.h
index 999ebe0ccc3..edc87c492a6 100644
--- a/source/blender/makesdna/DNA_object_types.h
+++ b/source/blender/makesdna/DNA_object_types.h
@@ -283,7 +283,6 @@ typedef struct Object {
/* Runtime valuated curve-specific data, not stored in the file */
struct CurveCache *curve_cache;
- ListBase gpulamp; /* runtime, for glsl lamp display only */
ListBase pc_ids;
struct RigidBodyOb *rigidbody_object; /* settings for Bullet rigid body */
diff --git a/source/blender/makesdna/DNA_rigidbody_types.h b/source/blender/makesdna/DNA_rigidbody_types.h
index 693707b8b7a..a99d5b409be 100644
--- a/source/blender/makesdna/DNA_rigidbody_types.h
+++ b/source/blender/makesdna/DNA_rigidbody_types.h
@@ -220,7 +220,8 @@ typedef struct RigidBodyCon {
int flag; /* (eRigidBodyCon_Flag) */
float breaking_threshold; /* breaking impulse threshold */
- float pad;
+ char spring_type; /* spring implementation to use */
+ char pad[3];
/* limits */
/* translation limits */
@@ -290,9 +291,15 @@ typedef enum eRigidBodyCon_Type {
/* Simplified spring constraint with only once axis that's automatically placed between the connected bodies */
RBC_TYPE_SPRING,
/* dirves bodies by applying linear and angular forces */
- RBC_TYPE_MOTOR
+ RBC_TYPE_MOTOR,
} eRigidBodyCon_Type;
+/* Spring implementation type for RigidBodyOb */
+typedef enum eRigidBodyCon_SpringType {
+ RBC_SPRING_TYPE1 = 0, /* btGeneric6DofSpringConstraint */
+ RBC_SPRING_TYPE2, /* btGeneric6DofSpring2Constraint */
+} eRigidBodyCon_SpringType;
+
/* Flags for RigidBodyCon */
typedef enum eRigidBodyCon_Flag {
/* constraint influences rigid body motion */
diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h
index 16c8d8875c7..a4235a07ed5 100644
--- a/source/blender/makesdna/DNA_scene_types.h
+++ b/source/blender/makesdna/DNA_scene_types.h
@@ -2096,7 +2096,7 @@ enum {
SCE_EEVEE_VOLUMETRIC_ENABLED = (1 << 0),
SCE_EEVEE_VOLUMETRIC_LIGHTS = (1 << 1),
SCE_EEVEE_VOLUMETRIC_SHADOWS = (1 << 2),
- SCE_EEVEE_VOLUMETRIC_COLORED = (1 << 3),
+// SCE_EEVEE_VOLUMETRIC_COLORED = (1 << 3), /* Unused */
SCE_EEVEE_GTAO_ENABLED = (1 << 4),
SCE_EEVEE_GTAO_BENT_NORMALS = (1 << 5),
SCE_EEVEE_GTAO_BOUNCE = (1 << 6),
diff --git a/source/blender/makesdna/DNA_view3d_types.h b/source/blender/makesdna/DNA_view3d_types.h
index fedc604f120..bbbaf8bb957 100644
--- a/source/blender/makesdna/DNA_view3d_types.h
+++ b/source/blender/makesdna/DNA_view3d_types.h
@@ -142,7 +142,9 @@ typedef struct View3DShading {
short color_type;
short light;
- short pad[3];
+ short background_type;
+ short pad2[2];
+
char studio_light[256]; /* FILE_MAXFILE */
char matcap[256]; /* FILE_MAXFILE */
@@ -157,6 +159,10 @@ typedef struct View3DShading {
float cavity_valley_factor;
float cavity_ridge_factor;
+
+ float background_color[3];
+ int pad;
+
} View3DShading;
/* 3D Viewport Overlay setings */
@@ -349,7 +355,7 @@ typedef struct View3D {
/* View3d->flag3 (short) */
-#define V3D_SHOW_WORLD (1 << 0)
+#define V3D_SHOW_WORLD (1 << 0) /* LEGACY replaced by V3D_SHADING_BACKGROUND_WORLD */
/* View3DShading->light */
enum {
@@ -378,6 +384,13 @@ enum {
V3D_SHADING_TEXTURE_COLOR = 3,
};
+/* View3DShading->background_type */
+enum {
+ V3D_SHADING_BACKGROUND_THEME = 0,
+ V3D_SHADING_BACKGROUND_WORLD = 1,
+ V3D_SHADING_BACKGROUND_VIEWPORT = 2,
+};
+
/* View3DOverlay->flag */
enum {
V3D_OVERLAY_FACE_ORIENTATION = (1 << 0),
diff --git a/source/blender/makesrna/RNA_access.h b/source/blender/makesrna/RNA_access.h
index f66c80beeab..cb5e2e61f9a 100644
--- a/source/blender/makesrna/RNA_access.h
+++ b/source/blender/makesrna/RNA_access.h
@@ -800,7 +800,7 @@ bool RNA_struct_bl_idname_ok_or_report(struct ReportList *reports, const char *i
/* Property Information */
-const char *RNA_property_identifier(PropertyRNA *prop);
+const char *RNA_property_identifier(const PropertyRNA *prop);
const char *RNA_property_description(PropertyRNA *prop);
PropertyType RNA_property_type(PropertyRNA *prop);
diff --git a/source/blender/makesrna/RNA_enum_types.h b/source/blender/makesrna/RNA_enum_types.h
index bafb2bf5753..043375a066a 100644
--- a/source/blender/makesrna/RNA_enum_types.h
+++ b/source/blender/makesrna/RNA_enum_types.h
@@ -54,6 +54,7 @@ extern const EnumPropertyItem rna_enum_snap_element_items[];
extern const EnumPropertyItem rna_enum_snap_node_element_items[];
extern const EnumPropertyItem rna_enum_curve_fit_method_items[];
extern const EnumPropertyItem rna_enum_mesh_select_mode_items[];
+extern const EnumPropertyItem rna_enum_mesh_select_mode_uv_items[];
extern const EnumPropertyItem rna_enum_mesh_delimit_mode_items[];
extern const EnumPropertyItem rna_enum_space_graph_mode_items[];
extern const EnumPropertyItem rna_enum_space_type_items[];
diff --git a/source/blender/makesrna/intern/rna_access.c b/source/blender/makesrna/intern/rna_access.c
index 7228f4a4683..a0c34afa7ed 100644
--- a/source/blender/makesrna/intern/rna_access.c
+++ b/source/blender/makesrna/intern/rna_access.c
@@ -975,7 +975,7 @@ bool RNA_struct_bl_idname_ok_or_report(ReportList *reports, const char *identifi
/* Property Information */
-const char *RNA_property_identifier(PropertyRNA *prop)
+const char *RNA_property_identifier(const PropertyRNA *prop)
{
return rna_ensure_property_identifier(prop);
}
diff --git a/source/blender/makesrna/intern/rna_camera.c b/source/blender/makesrna/intern/rna_camera.c
index 146a8e2738d..8ca45e6dd2d 100644
--- a/source/blender/makesrna/intern/rna_camera.c
+++ b/source/blender/makesrna/intern/rna_camera.c
@@ -428,6 +428,7 @@ void RNA_def_camera(BlenderRNA *brna)
prop = RNA_def_property(srna, "passepartout_alpha", PROP_FLOAT, PROP_FACTOR);
RNA_def_property_float_sdna(prop, NULL, "passepartalpha");
+ RNA_def_property_float_default(prop, 0.5f);
RNA_def_property_ui_text(prop, "Passepartout Alpha", "Opacity (alpha) of the darkened overlay in Camera view");
RNA_def_property_update(prop, NC_CAMERA | ND_DRAW_RENDER_VIEWPORT, NULL);
@@ -454,6 +455,7 @@ void RNA_def_camera(BlenderRNA *brna)
prop = RNA_def_property(srna, "clip_start", PROP_FLOAT, PROP_DISTANCE);
RNA_def_property_float_sdna(prop, NULL, "clipsta");
+ RNA_def_property_float_default(prop, 0.1f);
RNA_def_property_range(prop, 1e-6f, FLT_MAX);
RNA_def_property_ui_range(prop, 0.001f, FLT_MAX, 10, 3);
RNA_def_property_ui_text(prop, "Clip Start", "Camera near clipping distance");
@@ -461,6 +463,7 @@ void RNA_def_camera(BlenderRNA *brna)
prop = RNA_def_property(srna, "clip_end", PROP_FLOAT, PROP_DISTANCE);
RNA_def_property_float_sdna(prop, NULL, "clipend");
+ RNA_def_property_float_default(prop, 1000.0f);
RNA_def_property_range(prop, 1e-6f, FLT_MAX);
RNA_def_property_ui_range(prop, 0.001f, FLT_MAX, 10, 3);
RNA_def_property_ui_text(prop, "Clip End", "Camera far clipping distance");
@@ -468,6 +471,7 @@ void RNA_def_camera(BlenderRNA *brna)
prop = RNA_def_property(srna, "lens", PROP_FLOAT, PROP_DISTANCE_CAMERA);
RNA_def_property_float_sdna(prop, NULL, "lens");
+ RNA_def_property_float_default(prop, 50.0f);
RNA_def_property_range(prop, 1.0f, FLT_MAX);
RNA_def_property_ui_range(prop, 1.0f, 5000.0f, 1, 2);
RNA_def_property_ui_text(prop, "Focal Length", "Perspective Camera lens value in millimeters");
@@ -475,6 +479,7 @@ void RNA_def_camera(BlenderRNA *brna)
prop = RNA_def_property(srna, "sensor_width", PROP_FLOAT, PROP_DISTANCE_CAMERA);
RNA_def_property_float_sdna(prop, NULL, "sensor_x");
+ RNA_def_property_float_default(prop, 36.0f);
RNA_def_property_range(prop, 1.0f, FLT_MAX);
RNA_def_property_ui_range(prop, 1.0f, 100.f, 1, 2);
RNA_def_property_ui_text(prop, "Sensor Width", "Horizontal size of the image sensor area in millimeters");
@@ -482,6 +487,7 @@ void RNA_def_camera(BlenderRNA *brna)
prop = RNA_def_property(srna, "sensor_height", PROP_FLOAT, PROP_DISTANCE_CAMERA);
RNA_def_property_float_sdna(prop, NULL, "sensor_y");
+ RNA_def_property_float_default(prop, 34.0f);
RNA_def_property_range(prop, 1.0f, FLT_MAX);
RNA_def_property_ui_range(prop, 1.0f, 100.f, 1, 2);
RNA_def_property_ui_text(prop, "Sensor Height", "Vertical size of the image sensor area in millimeters");
@@ -489,6 +495,7 @@ void RNA_def_camera(BlenderRNA *brna)
prop = RNA_def_property(srna, "ortho_scale", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "ortho_scale");
+ RNA_def_property_float_default(prop, 6.0f);
RNA_def_property_range(prop, FLT_MIN, FLT_MAX);
RNA_def_property_ui_range(prop, 0.001f, 10000.0f, 10, 3);
RNA_def_property_ui_text(prop, "Orthographic Scale", "Orthographic Camera scale (similar to zoom)");
@@ -496,6 +503,7 @@ void RNA_def_camera(BlenderRNA *brna)
prop = RNA_def_property(srna, "draw_size", PROP_FLOAT, PROP_DISTANCE);
RNA_def_property_float_sdna(prop, NULL, "drawsize");
+ RNA_def_property_float_default(prop, 1.0f);
RNA_def_property_range(prop, 0.01f, 1000.0f);
RNA_def_property_ui_range(prop, 0.01, 100, 1, 2);
RNA_def_property_ui_text(prop, "Draw Size", "Apparent size of the Camera object in the 3D View");
@@ -542,6 +550,7 @@ void RNA_def_camera(BlenderRNA *brna)
prop = RNA_def_property(srna, "show_passepartout", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", CAM_SHOWPASSEPARTOUT);
+ RNA_def_property_boolean_default(prop, true);
RNA_def_property_ui_text(prop, "Show Passepartout",
"Show a darkened overlay outside the image area in Camera view");
RNA_def_property_update(prop, NC_CAMERA | ND_DRAW_RENDER_VIEWPORT, NULL);
diff --git a/source/blender/makesrna/intern/rna_layer.c b/source/blender/makesrna/intern/rna_layer.c
index 7d770a99c0c..d425534fe53 100644
--- a/source/blender/makesrna/intern/rna_layer.c
+++ b/source/blender/makesrna/intern/rna_layer.c
@@ -230,6 +230,18 @@ static void rna_def_layer_collection(BlenderRNA *brna)
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
RNA_def_property_ui_text(prop, "Exclude", "Exclude collection from view layer");
RNA_def_property_update(prop, NC_SCENE | ND_LAYER, "rna_LayerCollection_use_update");
+
+ prop = RNA_def_property(srna, "holdout", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", LAYER_COLLECTION_HOLDOUT);
+ RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
+ RNA_def_property_ui_text(prop, "Holdout", "Mask out objects in collection from view layer");
+ RNA_def_property_update(prop, NC_SCENE | ND_LAYER, "rna_LayerCollection_use_update");
+
+ prop = RNA_def_property(srna, "indirect_only", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", LAYER_COLLECTION_INDIRECT_ONLY);
+ RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
+ RNA_def_property_ui_text(prop, "Indirect Only", "Objects in collection only contribute indirectly (through shadows and reflections) in the view layer");
+ RNA_def_property_update(prop, NC_SCENE | ND_LAYER, "rna_LayerCollection_use_update");
}
static void rna_def_layer_collections(BlenderRNA *brna, PropertyRNA *cprop)
diff --git a/source/blender/makesrna/intern/rna_object_api.c b/source/blender/makesrna/intern/rna_object_api.c
index 1a2b3854668..3adf9f790d9 100644
--- a/source/blender/makesrna/intern/rna_object_api.c
+++ b/source/blender/makesrna/intern/rna_object_api.c
@@ -128,11 +128,11 @@ static bool rna_Object_select_get(Object *ob, bContext *C, ReportList *reports)
Base *base = BKE_view_layer_base_find(view_layer, ob);
if (!base) {
- BKE_reportf(reports, RPT_ERROR, "Object '%s' not in Render Layer '%s'!", ob->id.name + 2, view_layer->name);
- return -1;
+ BKE_reportf(reports, RPT_ERROR, "Object '%s' not in View Layer '%s'!", ob->id.name + 2, view_layer->name);
+ return false;
}
- return ((base->flag & BASE_SELECTED) != 0) ? 1 : 0;
+ return ((base->flag & BASE_SELECTED) != 0);
}
static bool rna_Object_visible_get(Object *ob, bContext *C, ReportList *reports)
@@ -141,11 +141,35 @@ static bool rna_Object_visible_get(Object *ob, bContext *C, ReportList *reports)
Base *base = BKE_view_layer_base_find(view_layer, ob);
if (!base) {
- BKE_reportf(reports, RPT_ERROR, "Object '%s' not in Render Layer '%s'!", ob->id.name + 2, view_layer->name);
- return -1;
+ BKE_reportf(reports, RPT_ERROR, "Object '%s' not in View Layer '%s'!", ob->id.name + 2, view_layer->name);
+ return false;
+ }
+
+ return ((base->flag & BASE_VISIBLE) != 0);
+}
+
+static bool rna_Object_holdout_get(Object *ob, ReportList *reports, ViewLayer *view_layer)
+{
+ Base *base = BKE_view_layer_base_find(view_layer, ob);
+
+ if (!base) {
+ BKE_reportf(reports, RPT_ERROR, "Object '%s' not in View Layer '%s'!", ob->id.name + 2, view_layer->name);
+ return false;
}
- return ((base->flag & BASE_VISIBLE) != 0) ? 1 : 0;
+ return ((base->flag & BASE_HOLDOUT) != 0);
+}
+
+static bool rna_Object_indirect_only_get(Object *ob, ReportList *reports, ViewLayer *view_layer)
+{
+ Base *base = BKE_view_layer_base_find(view_layer, ob);
+
+ if (!base) {
+ BKE_reportf(reports, RPT_ERROR, "Object '%s' not in View Layer '%s'!", ob->id.name + 2, view_layer->name);
+ return false;
+ }
+
+ return ((base->flag & BASE_INDIRECT_ONLY) != 0);
}
/* Convert a given matrix from a space to another (using the object and/or a bone as reference). */
@@ -309,8 +333,10 @@ static void rna_Object_ray_cast(
/* Test BoundBox first (efficiency) */
BoundBox *bb = BKE_object_boundbox_get(ob);
float distmin;
- if (!bb || (isect_ray_aabb_v3_simple(origin, direction, bb->vec[0], bb->vec[6], &distmin, NULL) && distmin <= distance)) {
-
+ normalize_v3(direction); /* Needed for valid distance check from isect_ray_aabb_v3_simple() call. */
+ if (!bb ||
+ (isect_ray_aabb_v3_simple(origin, direction, bb->vec[0], bb->vec[6], &distmin, NULL) && distmin <= distance))
+ {
BVHTreeFromMesh treeData = {NULL};
/* no need to managing allocation or freeing of the BVH data. this is generated and freed as needed */
@@ -323,9 +349,6 @@ static void rna_Object_ray_cast(
hit.index = -1;
hit.dist = distance;
- normalize_v3(direction);
-
-
if (BLI_bvhtree_ray_cast(treeData.tree, origin, direction, 0.0f, &hit,
treeData.raycast_callback, &treeData) != -1)
{
@@ -470,31 +493,47 @@ void RNA_api_object(StructRNA *srna)
#endif
static EnumPropertyItem object_select_items[] = {
- {0, "SELECT", 0, "Select", "Select object from the active render layer"},
- {1, "DESELECT", 0, "Deselect", "Deselect object from the active render layer"},
- {2, "TOGGLE", 0, "Toggle", "Toggle object selection from the active render layer"},
+ {0, "SELECT", 0, "Select", "Select object from the active view layer"},
+ {1, "DESELECT", 0, "Deselect", "Deselect object from the active view layer"},
+ {2, "TOGGLE", 0, "Toggle", "Toggle object selection from the active view layer"},
{0, NULL, 0, NULL, NULL}
};
/* Special wrapper to access the base selection value */
func = RNA_def_function(srna, "select_set", "rna_Object_select_set");
- RNA_def_function_ui_description(func, "Select the object (for the active render layer)");
+ RNA_def_function_ui_description(func, "Select the object (for the active view layer)");
RNA_def_function_flag(func, FUNC_USE_CONTEXT | FUNC_USE_REPORTS);
parm = RNA_def_enum(func, "action", object_select_items, 0, "Action", "Select mode");
RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
func = RNA_def_function(srna, "select_get", "rna_Object_select_get");
- RNA_def_function_ui_description(func, "Get the object selection for the active render layer");
+ RNA_def_function_ui_description(func, "Get the object selection for the active view layer");
RNA_def_function_flag(func, FUNC_USE_CONTEXT | FUNC_USE_REPORTS);
parm = RNA_def_boolean(func, "result", 0, "", "Object selected");
RNA_def_function_return(func, parm);
func = RNA_def_function(srna, "visible_get", "rna_Object_visible_get");
- RNA_def_function_ui_description(func, "Get the object visibility for the active render layer");
+ RNA_def_function_ui_description(func, "Get the object visibility for the active view layer");
RNA_def_function_flag(func, FUNC_USE_CONTEXT | FUNC_USE_REPORTS);
parm = RNA_def_boolean(func, "result", 0, "", "Object visible");
RNA_def_function_return(func, parm);
+ func = RNA_def_function(srna, "holdout_get", "rna_Object_holdout_get");
+ RNA_def_function_ui_description(func, "Test if object is masked in the view layer");
+ RNA_def_function_flag(func, FUNC_USE_REPORTS);
+ parm = RNA_def_pointer(func, "view_layer", "ViewLayer", "", "");
+ RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
+ parm = RNA_def_boolean(func, "result", 0, "", "Object holdout");
+ RNA_def_function_return(func, parm);
+
+ func = RNA_def_function(srna, "indirect_only_get", "rna_Object_indirect_only_get");
+ RNA_def_function_ui_description(func, "Test if object is set to contribute only indirectly (through shadows and reflections) in the view layer");
+ RNA_def_function_flag(func, FUNC_USE_REPORTS);
+ parm = RNA_def_pointer(func, "view_layer", "ViewLayer", "", "");
+ RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
+ parm = RNA_def_boolean(func, "result", 0, "", "Object indirect only");
+ RNA_def_function_return(func, parm);
+
/* Matrix space conversion */
func = RNA_def_function(srna, "convert_space", "rna_Object_mat_convert_space");
RNA_def_function_ui_description(func, "Convert (transform) the given matrix from one space to another");
diff --git a/source/blender/makesrna/intern/rna_particle.c b/source/blender/makesrna/intern/rna_particle.c
index 4b8299b9245..979e5d433e7 100644
--- a/source/blender/makesrna/intern/rna_particle.c
+++ b/source/blender/makesrna/intern/rna_particle.c
@@ -1132,6 +1132,9 @@ static void rna_ParticleDupliWeight_active_index_set(struct PointerRNA *ptr, int
static void rna_ParticleDupliWeight_name_get(PointerRNA *ptr, char *str)
{
+ ParticleSettings *part = (ParticleSettings *)ptr->id.data;
+ psys_find_group_weights(part);
+
ParticleDupliWeight *dw = ptr->data;
if (dw->ob)
diff --git a/source/blender/makesrna/intern/rna_rigidbody.c b/source/blender/makesrna/intern/rna_rigidbody.c
index 592f8ee38c0..47075d0d4f7 100644
--- a/source/blender/makesrna/intern/rna_rigidbody.c
+++ b/source/blender/makesrna/intern/rna_rigidbody.c
@@ -76,6 +76,12 @@ const EnumPropertyItem rna_enum_rigidbody_constraint_type_items[] = {
{RBC_TYPE_MOTOR, "MOTOR", ICON_NONE, "Motor", "Drive rigid body around or along an axis"},
{0, NULL, 0, NULL, NULL}};
+/* bullet spring type */
+const EnumPropertyItem rna_enum_rigidbody_constraint_spring_type_items[] = {
+ {RBC_SPRING_TYPE1, "SPRING1", ICON_NONE, "Blender 2.7", "Spring implementation used in blender 2.7. Damping is capped at 1.0"},
+ {RBC_SPRING_TYPE2, "SPRING2", ICON_NONE, "Blender 2.8", "New implementation available since 2.8"},
+ {0, NULL, 0, NULL, NULL}};
+
#ifndef RNA_RUNTIME
/* mesh source for collision shape creation */
static const EnumPropertyItem rigidbody_mesh_source_items[] = {
@@ -375,6 +381,14 @@ static void rna_RigidBodyCon_type_set(PointerRNA *ptr, int value)
rbc->flag |= RBC_FLAG_NEEDS_VALIDATE;
}
+static void rna_RigidBodyCon_spring_type_set(PointerRNA *ptr, int value)
+{
+ RigidBodyCon *rbc = (RigidBodyCon *)ptr->data;
+
+ rbc->spring_type = value;
+ rbc->flag |= RBC_FLAG_NEEDS_VALIDATE;
+}
+
static void rna_RigidBodyCon_enabled_set(PointerRNA *ptr, bool value)
{
RigidBodyCon *rbc = (RigidBodyCon *)ptr->data;
@@ -467,6 +481,22 @@ static void rna_RigidBodyCon_num_solver_iterations_set(PointerRNA *ptr, int valu
#endif
}
+#ifdef WITH_BULLET
+static void rna_RigidBodyCon_do_set_spring_stiffness(RigidBodyCon *rbc, float value, int flag, int axis)
+{
+ if (rbc->physics_constraint && rbc->type == RBC_TYPE_6DOF_SPRING && (rbc->flag & flag)) {
+ switch (rbc->spring_type) {
+ case RBC_SPRING_TYPE1:
+ RB_constraint_set_stiffness_6dof_spring(rbc->physics_constraint, axis, value);
+ break;
+ case RBC_SPRING_TYPE2:
+ RB_constraint_set_stiffness_6dof_spring2(rbc->physics_constraint, axis, value);
+ break;
+ }
+ }
+}
+#endif
+
static void rna_RigidBodyCon_spring_stiffness_x_set(PointerRNA *ptr, float value)
{
RigidBodyCon *rbc = (RigidBodyCon *)ptr->data;
@@ -474,9 +504,7 @@ static void rna_RigidBodyCon_spring_stiffness_x_set(PointerRNA *ptr, float value
rbc->spring_stiffness_x = value;
#ifdef WITH_BULLET
- if (rbc->physics_constraint && rbc->type == RBC_TYPE_6DOF_SPRING && (rbc->flag & RBC_FLAG_USE_SPRING_X)) {
- RB_constraint_set_stiffness_6dof_spring(rbc->physics_constraint, RB_LIMIT_LIN_X, value);
- }
+ rna_RigidBodyCon_do_set_spring_stiffness(rbc, value, RBC_FLAG_USE_SPRING_X, RB_LIMIT_LIN_X);
#endif
}
@@ -487,9 +515,7 @@ static void rna_RigidBodyCon_spring_stiffness_y_set(PointerRNA *ptr, float value
rbc->spring_stiffness_y = value;
#ifdef WITH_BULLET
- if (rbc->physics_constraint && rbc->type == RBC_TYPE_6DOF_SPRING && (rbc->flag & RBC_FLAG_USE_SPRING_Y)) {
- RB_constraint_set_stiffness_6dof_spring(rbc->physics_constraint, RB_LIMIT_LIN_Y, value);
- }
+ rna_RigidBodyCon_do_set_spring_stiffness(rbc, value, RBC_FLAG_USE_SPRING_Y, RB_LIMIT_LIN_Y);
#endif
}
@@ -500,9 +526,7 @@ static void rna_RigidBodyCon_spring_stiffness_z_set(PointerRNA *ptr, float value
rbc->spring_stiffness_z = value;
#ifdef WITH_BULLET
- if (rbc->physics_constraint && rbc->type == RBC_TYPE_6DOF_SPRING && (rbc->flag & RBC_FLAG_USE_SPRING_Z)) {
- RB_constraint_set_stiffness_6dof_spring(rbc->physics_constraint, RB_LIMIT_LIN_Z, value);
- }
+ rna_RigidBodyCon_do_set_spring_stiffness(rbc, value, RBC_FLAG_USE_SPRING_Z, RB_LIMIT_LIN_Z);
#endif
}
@@ -513,9 +537,7 @@ static void rna_RigidBodyCon_spring_stiffness_ang_x_set(PointerRNA *ptr, float v
rbc->spring_stiffness_ang_x = value;
#ifdef WITH_BULLET
- if (rbc->physics_constraint && rbc->type == RBC_TYPE_6DOF_SPRING && (rbc->flag & RBC_FLAG_USE_SPRING_ANG_X)) {
- RB_constraint_set_stiffness_6dof_spring(rbc->physics_constraint, RB_LIMIT_ANG_X, value);
- }
+ rna_RigidBodyCon_do_set_spring_stiffness(rbc, value, RBC_FLAG_USE_SPRING_ANG_X, RB_LIMIT_ANG_X);
#endif
}
@@ -526,9 +548,7 @@ static void rna_RigidBodyCon_spring_stiffness_ang_y_set(PointerRNA *ptr, float v
rbc->spring_stiffness_ang_y = value;
#ifdef WITH_BULLET
- if (rbc->physics_constraint && rbc->type == RBC_TYPE_6DOF_SPRING && (rbc->flag & RBC_FLAG_USE_SPRING_ANG_Y)) {
- RB_constraint_set_stiffness_6dof_spring(rbc->physics_constraint, RB_LIMIT_ANG_Y, value);
- }
+ rna_RigidBodyCon_do_set_spring_stiffness(rbc, value, RBC_FLAG_USE_SPRING_ANG_Y, RB_LIMIT_ANG_Y);
#endif
}
@@ -539,12 +559,26 @@ static void rna_RigidBodyCon_spring_stiffness_ang_z_set(PointerRNA *ptr, float v
rbc->spring_stiffness_ang_z = value;
#ifdef WITH_BULLET
- if (rbc->physics_constraint && rbc->type == RBC_TYPE_6DOF_SPRING && (rbc->flag & RBC_FLAG_USE_SPRING_ANG_Z)) {
- RB_constraint_set_stiffness_6dof_spring(rbc->physics_constraint, RB_LIMIT_ANG_Z, value);
- }
+ rna_RigidBodyCon_do_set_spring_stiffness(rbc, value, RBC_FLAG_USE_SPRING_ANG_Z, RB_LIMIT_ANG_Z);
#endif
}
+#ifdef WITH_BULLET
+static void rna_RigidBodyCon_do_set_spring_damping(RigidBodyCon *rbc, float value, int flag, int axis)
+{
+ if (rbc->physics_constraint && rbc->type == RBC_TYPE_6DOF_SPRING && (rbc->flag & flag)) {
+ switch (rbc->spring_type) {
+ case RBC_SPRING_TYPE1:
+ RB_constraint_set_damping_6dof_spring(rbc->physics_constraint, axis, value);
+ break;
+ case RBC_SPRING_TYPE2:
+ RB_constraint_set_damping_6dof_spring2(rbc->physics_constraint, axis, value);
+ break;
+ }
+ }
+}
+#endif
+
static void rna_RigidBodyCon_spring_damping_x_set(PointerRNA *ptr, float value)
{
RigidBodyCon *rbc = (RigidBodyCon *)ptr->data;
@@ -552,9 +586,7 @@ static void rna_RigidBodyCon_spring_damping_x_set(PointerRNA *ptr, float value)
rbc->spring_damping_x = value;
#ifdef WITH_BULLET
- if (rbc->physics_constraint && rbc->type == RBC_TYPE_6DOF_SPRING && (rbc->flag & RBC_FLAG_USE_SPRING_X)) {
- RB_constraint_set_damping_6dof_spring(rbc->physics_constraint, RB_LIMIT_LIN_X, value);
- }
+ rna_RigidBodyCon_do_set_spring_damping(rbc, value, RBC_FLAG_USE_SPRING_X, RB_LIMIT_LIN_X);
#endif
}
@@ -564,9 +596,7 @@ static void rna_RigidBodyCon_spring_damping_y_set(PointerRNA *ptr, float value)
rbc->spring_damping_y = value;
#ifdef WITH_BULLET
- if (rbc->physics_constraint && rbc->type == RBC_TYPE_6DOF_SPRING && (rbc->flag & RBC_FLAG_USE_SPRING_Y)) {
- RB_constraint_set_damping_6dof_spring(rbc->physics_constraint, RB_LIMIT_LIN_Y, value);
- }
+ rna_RigidBodyCon_do_set_spring_damping(rbc, value, RBC_FLAG_USE_SPRING_Y, RB_LIMIT_LIN_Y);
#endif
}
@@ -576,9 +606,7 @@ static void rna_RigidBodyCon_spring_damping_z_set(PointerRNA *ptr, float value)
rbc->spring_damping_z = value;
#ifdef WITH_BULLET
- if (rbc->physics_constraint && rbc->type == RBC_TYPE_6DOF_SPRING && (rbc->flag & RBC_FLAG_USE_SPRING_Z)) {
- RB_constraint_set_damping_6dof_spring(rbc->physics_constraint, RB_LIMIT_LIN_Z, value);
- }
+ rna_RigidBodyCon_do_set_spring_damping(rbc, value, RBC_FLAG_USE_SPRING_Z, RB_LIMIT_LIN_Z);
#endif
}
@@ -589,9 +617,7 @@ static void rna_RigidBodyCon_spring_damping_ang_x_set(PointerRNA *ptr, float val
rbc->spring_damping_ang_x = value;
#ifdef WITH_BULLET
- if (rbc->physics_constraint && rbc->type == RBC_TYPE_6DOF_SPRING && (rbc->flag & RBC_FLAG_USE_SPRING_ANG_X)) {
- RB_constraint_set_damping_6dof_spring(rbc->physics_constraint, RB_LIMIT_ANG_X, value);
- }
+ rna_RigidBodyCon_do_set_spring_damping(rbc, value, RBC_FLAG_USE_SPRING_ANG_X, RB_LIMIT_ANG_X);
#endif
}
@@ -601,9 +627,7 @@ static void rna_RigidBodyCon_spring_damping_ang_y_set(PointerRNA *ptr, float val
rbc->spring_damping_ang_y = value;
#ifdef WITH_BULLET
- if (rbc->physics_constraint && rbc->type == RBC_TYPE_6DOF_SPRING && (rbc->flag & RBC_FLAG_USE_SPRING_ANG_Y)) {
- RB_constraint_set_damping_6dof_spring(rbc->physics_constraint, RB_LIMIT_ANG_Y, value);
- }
+ rna_RigidBodyCon_do_set_spring_damping(rbc, value, RBC_FLAG_USE_SPRING_ANG_Y, RB_LIMIT_ANG_Y);
#endif
}
@@ -613,9 +637,7 @@ static void rna_RigidBodyCon_spring_damping_ang_z_set(PointerRNA *ptr, float val
rbc->spring_damping_ang_z = value;
#ifdef WITH_BULLET
- if (rbc->physics_constraint && rbc->type == RBC_TYPE_6DOF_SPRING && (rbc->flag & RBC_FLAG_USE_SPRING_ANG_Z)) {
- RB_constraint_set_damping_6dof_spring(rbc->physics_constraint, RB_LIMIT_ANG_Z, value);
- }
+ rna_RigidBodyCon_do_set_spring_damping(rbc, value, RBC_FLAG_USE_SPRING_ANG_Z, RB_LIMIT_ANG_Z);
#endif
}
@@ -1031,6 +1053,14 @@ static void rna_def_rigidbody_constraint(BlenderRNA *brna)
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
RNA_def_property_update(prop, NC_OBJECT | ND_POINTCACHE, "rna_RigidBodyOb_reset");
+ prop = RNA_def_property(srna, "spring_type", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_sdna(prop, NULL, "spring_type");
+ RNA_def_property_enum_items(prop, rna_enum_rigidbody_constraint_spring_type_items);
+ RNA_def_property_enum_funcs(prop, NULL, "rna_RigidBodyCon_spring_type_set", NULL);
+ RNA_def_property_ui_text(prop, "Spring Type", "Which implementation of spring to use");
+ RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
+ RNA_def_property_update(prop, NC_OBJECT | ND_POINTCACHE, "rna_RigidBodyOb_reset");
+
prop = RNA_def_property(srna, "enabled", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", RBC_FLAG_ENABLED);
RNA_def_property_boolean_funcs(prop, NULL, "rna_RigidBodyCon_enabled_set");
diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c
index 339d3841b30..915018612a1 100644
--- a/source/blender/makesrna/intern/rna_scene.c
+++ b/source/blender/makesrna/intern/rna_scene.c
@@ -165,6 +165,14 @@ const EnumPropertyItem rna_enum_mesh_select_mode_items[] = {
{0, NULL, 0, NULL, NULL}
};
+const EnumPropertyItem rna_enum_mesh_select_mode_uv_items[] = {
+ {UV_SELECT_VERTEX, "VERTEX", ICON_UV_VERTEXSEL, "Vertex", "Vertex selection mode"},
+ {UV_SELECT_EDGE, "EDGE", ICON_UV_EDGESEL, "Edge", "Edge selection mode"},
+ {UV_SELECT_FACE, "FACE", ICON_UV_FACESEL, "Face", "Face selection mode"},
+ {UV_SELECT_ISLAND, "ISLAND", ICON_UV_ISLANDSEL, "Island", "Island selection mode"},
+ {0, NULL, 0, NULL, NULL}
+};
+
const EnumPropertyItem rna_enum_snap_element_items[] = {
{SCE_SNAP_MODE_INCREMENT, "INCREMENT", ICON_SNAP_INCREMENT, "Increment", "Snap to increments of grid"},
{SCE_SNAP_MODE_VERTEX, "VERTEX", ICON_SNAP_VERTEX, "Vertex", "Snap to vertices"},
@@ -2024,11 +2032,6 @@ static void rna_Stereo3dFormat_update(Main *bmain, Scene *UNUSED(scene), Pointer
}
}
-static bool rna_gpu_is_hq_supported_get(PointerRNA *UNUSED(ptr))
-{
- return true;
-}
-
static ViewLayer *rna_ViewLayer_new(
ID *id, Scene *UNUSED(sce), Main *bmain, const char *name)
{
@@ -2409,14 +2412,6 @@ static void rna_def_tool_settings(BlenderRNA *brna)
StructRNA *srna;
PropertyRNA *prop;
- static const EnumPropertyItem uv_select_mode_items[] = {
- {UV_SELECT_VERTEX, "VERTEX", ICON_UV_VERTEXSEL, "Vertex", "Vertex selection mode"},
- {UV_SELECT_EDGE, "EDGE", ICON_UV_EDGESEL, "Edge", "Edge selection mode"},
- {UV_SELECT_FACE, "FACE", ICON_UV_FACESEL, "Face", "Face selection mode"},
- {UV_SELECT_ISLAND, "ISLAND", ICON_UV_ISLANDSEL, "Island", "Island selection mode"},
- {0, NULL, 0, NULL, NULL}
- };
-
/* the construction of this enum is quite special - everything is stored as bitflags,
* with 1st position only for for on/off (and exposed as boolean), while others are mutually
* exclusive options but which will only have any effect when autokey is enabled
@@ -2811,7 +2806,7 @@ static void rna_def_tool_settings(BlenderRNA *brna)
/* UV */
prop = RNA_def_property(srna, "uv_select_mode", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "uv_selectmode");
- RNA_def_property_enum_items(prop, uv_select_mode_items);
+ RNA_def_property_enum_items(prop, rna_enum_mesh_select_mode_uv_items);
RNA_def_property_ui_text(prop, "UV Selection Mode", "UV selection and display mode");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_IMAGE, NULL);
@@ -4092,6 +4087,7 @@ static void rna_def_gpu_dof_fx(BlenderRNA *brna)
prop = RNA_def_property(srna, "fstop", PROP_FLOAT, PROP_NONE);
RNA_def_property_ui_text(prop, "F-stop", "F-stop for dof effect");
+ RNA_def_property_float_default(prop, 128.0f);
RNA_def_property_range(prop, 0.0f, FLT_MAX);
RNA_def_property_ui_range(prop, 0.1f, 128.0f, 10, 1);
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, "rna_GPUDOFSettings_update");
@@ -4110,21 +4106,10 @@ static void rna_def_gpu_dof_fx(BlenderRNA *brna)
prop = RNA_def_property(srna, "ratio", PROP_FLOAT, PROP_NONE);
RNA_def_property_ui_text(prop, "Ratio", "Distortion to simulate anamorphic lens bokeh");
+ RNA_def_property_float_default(prop, 1.0f);
RNA_def_property_range(prop, 0.0000001f, FLT_MAX);
RNA_def_property_ui_range(prop, 1.0f, 2.0f, 0.1, 3);
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL);
-
- prop = RNA_def_property(srna, "use_high_quality", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_sdna(prop, NULL, "high_quality", 1);
- RNA_def_property_ui_text(prop, "High Quality", "Use high quality depth of field");
- RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, "rna_GPUDOFSettings_update");
-
- /* NOTE: high quality is always supported */
- prop = RNA_def_property(srna, "is_hq_supported", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_funcs(prop, "rna_gpu_is_hq_supported_get", NULL);
- RNA_def_property_clear_flag(prop, PROP_EDITABLE);
- RNA_def_property_ui_text(prop, "High Quality", "Use high quality depth of field");
- RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL);
}
static void rna_def_gpu_ssao_fx(BlenderRNA *brna)
@@ -4255,6 +4240,7 @@ static void rna_def_scene_render_view(BlenderRNA *brna)
prop = RNA_def_property(srna, "use", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_negative_sdna(prop, NULL, "viewflag", SCE_VIEW_DISABLE);
+ RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
RNA_def_property_ui_text(prop, "Enabled", "Disable or enable the render view");
RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL);
}
@@ -4793,10 +4779,10 @@ static void rna_def_scene_render_data(BlenderRNA *brna)
};
static const EnumPropertyItem display_mode_items[] = {
- {R_OUTPUT_SCREEN, "SCREEN", 0, "Full Screen", "Images are rendered in full Screen"},
- {R_OUTPUT_AREA, "AREA", 0, "Image Editor", "Images are rendered in Image Editor"},
- {R_OUTPUT_WINDOW, "WINDOW", 0, "New Window", "Images are rendered in new Window"},
- {R_OUTPUT_NONE, "NONE", 0, "Keep UI", "Images are rendered without forcing UI changes"},
+ {R_OUTPUT_SCREEN, "SCREEN", 0, "Full Screen", "Images are rendered in a maximized Image Editor"},
+ {R_OUTPUT_AREA, "AREA", 0, "Image Editor", "Images are rendered in an Image Editor"},
+ {R_OUTPUT_WINDOW, "WINDOW", 0, "New Window", "Images are rendered in a new window"},
+ {R_OUTPUT_NONE, "NONE", 0, "Keep User Interface", "Images are rendered without changing the user interface"},
{0, NULL, 0, NULL, NULL}
};
@@ -4809,7 +4795,7 @@ static void rna_def_scene_render_data(BlenderRNA *brna)
};
static const EnumPropertyItem pixel_size_items[] = {
- {0, "AUTO", 0, "Automatic", "Automatic pixel size, depends on the UI scale"},
+ {0, "AUTO", 0, "Automatic", "Automatic pixel size, depends on the user interface scale"},
{1, "1", 0, "1x", "Render at full resolution"},
{2, "2", 0, "2x", "Render at 50% resolution"},
{4, "4", 0, "4x", "Render at 25% resolution"},
@@ -5411,7 +5397,8 @@ static void rna_def_scene_render_data(BlenderRNA *brna)
prop = RNA_def_property(srna, "use_single_layer", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "scemode", R_SINGLE_LAYER);
- RNA_def_property_ui_text(prop, "Render Single Layer", "Only render the active layer");
+ RNA_def_property_ui_text(prop, "Render Single Layer", "Only render the active layer. Only affects rendering from the interface, ignored for rendering from command line");
+ RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL);
/* views (stereoscopy et al) */
@@ -6015,12 +6002,6 @@ 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_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_STATIC);
- 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_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_STATIC);
-
/* Ambient Occlusion */
prop = RNA_def_property(srna, "use_gtao", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", SCE_EEVEE_GTAO_ENABLED);
diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c
index 6e45e52764e..1bdaa569604 100644
--- a/source/blender/makesrna/intern/rna_space.c
+++ b/source/blender/makesrna/intern/rna_space.c
@@ -2436,6 +2436,15 @@ static void rna_def_space_view3d_shading(BlenderRNA *brna)
StructRNA *srna;
PropertyRNA *prop;
+ static const EnumPropertyItem background_type_items[] = {
+ {V3D_SHADING_BACKGROUND_THEME, "THEME", 0, "Theme", "Use the theme for background color"},
+ {V3D_SHADING_BACKGROUND_WORLD, "WORLD", 0, "World", "Use the world for background color"},
+ {V3D_SHADING_BACKGROUND_VIEWPORT, "VIEWPORT", 0, "Viewport", "Use a custom color limited to this viewport only"},
+ {0, NULL, 0, NULL, NULL}
+ };
+ static const float default_background_color[] = {0.05f, 0.05f, 0.05f};
+
+
/* Note these settings are used for both 3D viewport and the OpenGL render
* engine in the scene, so can't assume to always be part of a screen. */
srna = RNA_def_struct(brna, "View3DShading", NULL);
@@ -2523,6 +2532,18 @@ static void rna_def_space_view3d_shading(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, "background_type", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_items(prop, background_type_items);
+ RNA_def_property_ui_text(prop, "Background", "Way to draw the background");
+ RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL);
+
+ prop = RNA_def_property(srna, "background_color", PROP_FLOAT, PROP_COLOR);
+ RNA_def_property_array(prop, 3);
+ RNA_def_property_float_array_default(prop, default_background_color);
+ RNA_def_property_ui_text(prop, "Background Color", "Color for custom background color");
+ 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, "show_shadows", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", V3D_SHADING_SHADOW);
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
@@ -2966,11 +2987,6 @@ static void rna_def_space_view3d(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Lock Camera to View", "Enable view navigation within the camera view");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL);
- prop = RNA_def_property(srna, "show_world", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_sdna(prop, NULL, "flag3", V3D_SHOW_WORLD);
- RNA_def_property_ui_text(prop, "World Background", "Display world colors in the background");
- RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL);
-
prop = RNA_def_property(srna, "use_occlude_geometry", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", V3D_ZBUF_SELECT);
RNA_def_property_ui_text(prop, "Occlude Geometry", "Limit selection to visible (clipped with depth buffer)");
diff --git a/source/blender/makesrna/intern/rna_world.c b/source/blender/makesrna/intern/rna_world.c
index f4dc07cf6c3..fe561cdef1c 100644
--- a/source/blender/makesrna/intern/rna_world.c
+++ b/source/blender/makesrna/intern/rna_world.c
@@ -199,6 +199,8 @@ void RNA_def_world(BlenderRNA *brna)
StructRNA *srna;
PropertyRNA *prop;
+ static float default_world_color[] = {0.05f, 0.05f, 0.05f};
+
srna = RNA_def_struct(brna, "World", "ID");
RNA_def_struct_ui_text(srna, "World",
"World data-block describing the environment and ambient lighting of a scene");
@@ -210,6 +212,7 @@ void RNA_def_world(BlenderRNA *brna)
prop = RNA_def_property(srna, "color", PROP_FLOAT, PROP_COLOR);
RNA_def_property_float_sdna(prop, NULL, "horr");
RNA_def_property_array(prop, 3);
+ RNA_def_property_float_array_default(prop, default_world_color);
RNA_def_property_ui_text(prop, "Color", "Color of the background");
/* RNA_def_property_update(prop, 0, "rna_World_update"); */
/* render-only uses this */
diff --git a/source/blender/python/mathutils/mathutils_Vector.c b/source/blender/python/mathutils/mathutils_Vector.c
index a06a63c8067..6a40f22d9df 100644
--- a/source/blender/python/mathutils/mathutils_Vector.c
+++ b/source/blender/python/mathutils/mathutils_Vector.c
@@ -1127,23 +1127,17 @@ PyDoc_STRVAR(Vector_project_doc,
static PyObject *Vector_project(VectorObject *self, PyObject *value)
{
const int size = self->size;
- float tvec[MAX_DIMENSIONS];
- float vec[MAX_DIMENSIONS];
+ float *tvec;
double dot = 0.0f, dot2 = 0.0f;
int x;
- if (mathutils_array_parse(tvec, size, size, value, "Vector.project(other), invalid 'other' arg") == -1)
+ if (BaseMath_ReadCallback(self) == -1)
return NULL;
- if (self->size > 4) {
- PyErr_SetString(PyExc_ValueError,
- "Vector must be 2D, 3D or 4D");
+ if (mathutils_array_parse_alloc(&tvec, size, value, "Vector.project(other), invalid 'other' arg") == -1) {
return NULL;
}
- if (BaseMath_ReadCallback(self) == -1)
- return NULL;
-
/* get dot products */
for (x = 0; x < size; x++) {
dot += (double)(self->vec[x] * tvec[x]);
@@ -1152,9 +1146,9 @@ static PyObject *Vector_project(VectorObject *self, PyObject *value)
/* projection */
dot /= dot2;
for (x = 0; x < size; x++) {
- vec[x] = (float)dot * tvec[x];
+ tvec[x] *= (float)dot;
}
- return Vector_CreatePyObject(vec, size, Py_TYPE(self));
+ return Vector_CreatePyObject_alloc(tvec, size, Py_TYPE(self));
}
PyDoc_STRVAR(Vector_lerp_doc,
diff --git a/source/blender/render/intern/include/render_result.h b/source/blender/render/intern/include/render_result.h
index 3096949b49f..ab7eee128f0 100644
--- a/source/blender/render/intern/include/render_result.h
+++ b/source/blender/render/intern/include/render_result.h
@@ -123,7 +123,7 @@ bool render_result_has_views(struct RenderResult *rr);
iter_ != NULL; \
iter_ = iter_->next, nr_++) \
{ \
- if ((re_)->r.scemode & R_SINGLE_LAYER) { \
+ if (!G.background && (re_)->r.scemode & R_SINGLE_LAYER) { \
if (nr_ != re->active_view_layer) { \
continue; \
} \
diff --git a/source/blender/windowmanager/WM_keymap.h b/source/blender/windowmanager/WM_keymap.h
index 547028c88f9..2e84140707d 100644
--- a/source/blender/windowmanager/WM_keymap.h
+++ b/source/blender/windowmanager/WM_keymap.h
@@ -70,6 +70,10 @@ wmKeyMapItem *WM_keymap_add_panel(struct wmKeyMap *keymap, const char *idname, i
wmKeyMapItem *WM_keymap_add_tool(struct wmKeyMap *keymap, const char *idname, int type,
int val, int modifier, int keymodifier);
+void WM_keymap_add_context_enum_set_items(
+ wmKeyMap *keymap, const struct EnumPropertyItem *items, const char *data_path,
+ int type_start, int val, int modifier, int keymodifier);
+
bool WM_keymap_remove_item(struct wmKeyMap *keymap, struct wmKeyMapItem *kmi);
int WM_keymap_item_to_string(wmKeyMapItem *kmi, const bool compact, char *result, const int result_len);
diff --git a/source/blender/windowmanager/WM_types.h b/source/blender/windowmanager/WM_types.h
index a5536dbd652..60dd9ad2e72 100644
--- a/source/blender/windowmanager/WM_types.h
+++ b/source/blender/windowmanager/WM_types.h
@@ -585,6 +585,12 @@ typedef struct wmOperatorType {
* that the operator might still fail to execute even if this return true */
bool (*poll)(struct bContext *) ATTR_WARN_UNUSED_RESULT;
+ /* Use to check of properties should be displayed in auto-generated UI.
+ * Use 'check' callback to enforce refreshing. */
+ bool (*poll_property)(
+ const struct bContext *C, struct wmOperator *op,
+ const PropertyRNA *prop) ATTR_WARN_UNUSED_RESULT;
+
/* optional panel for redo and repeat, autogenerated if not set */
void (*ui)(struct bContext *, struct wmOperator *);
diff --git a/source/blender/windowmanager/intern/wm.c b/source/blender/windowmanager/intern/wm.c
index f92cc511449..7247529d02d 100644
--- a/source/blender/windowmanager/intern/wm.c
+++ b/source/blender/windowmanager/intern/wm.c
@@ -223,65 +223,6 @@ void WM_operator_handlers_clear(wmWindowManager *wm, wmOperatorType *ot)
}
}
-/* ************ uiListType handling ************** */
-
-static GHash *uilisttypes_hash = NULL;
-
-uiListType *WM_uilisttype_find(const char *idname, bool quiet)
-{
- uiListType *ult;
-
- if (idname[0]) {
- ult = BLI_ghash_lookup(uilisttypes_hash, idname);
- if (ult) {
- return ult;
- }
- }
-
- if (!quiet) {
- printf("search for unknown uilisttype %s\n", idname);
- }
-
- return NULL;
-}
-
-bool WM_uilisttype_add(uiListType *ult)
-{
- BLI_ghash_insert(uilisttypes_hash, ult->idname, ult);
- return 1;
-}
-
-void WM_uilisttype_freelink(uiListType *ult)
-{
- bool ok;
-
- ok = BLI_ghash_remove(uilisttypes_hash, ult->idname, NULL, MEM_freeN);
-
- BLI_assert(ok);
- (void)ok;
-}
-
-/* called on initialize WM_init() */
-void WM_uilisttype_init(void)
-{
- uilisttypes_hash = BLI_ghash_str_new_ex("uilisttypes_hash gh", 16);
-}
-
-void WM_uilisttype_free(void)
-{
- GHashIterator gh_iter;
-
- GHASH_ITER (gh_iter, uilisttypes_hash) {
- uiListType *ult = BLI_ghashIterator_getValue(&gh_iter);
- if (ult->ext.free) {
- ult->ext.free(ult->ext.data);
- }
- }
-
- BLI_ghash_free(uilisttypes_hash, NULL, MEM_freeN);
- uilisttypes_hash = NULL;
-}
-
/* ****************************************** */
void WM_keymap_init(bContext *C)
diff --git a/source/blender/windowmanager/intern/wm_files.c b/source/blender/windowmanager/intern/wm_files.c
index c191255cd21..042bd8823c4 100644
--- a/source/blender/windowmanager/intern/wm_files.c
+++ b/source/blender/windowmanager/intern/wm_files.c
@@ -279,6 +279,10 @@ static void wm_window_match_replace_by_file_wm(
wm->initialized = 0;
wm->winactive = NULL;
+ /* Clearing drawable of before deleting any context
+ * to avoid clearing the wrong wm. */
+ wm_window_clear_drawable(oldwm);
+
/* only first wm in list has ghostwins */
for (wmWindow *win = wm->windows.first; win; win = win->next) {
for (wmWindow *oldwin = oldwm->windows.first; oldwin; oldwin = oldwin->next) {
@@ -488,13 +492,7 @@ static void wm_file_read_post(bContext *C, const bool is_startup_file, const boo
Main *bmain = CTX_data_main(C);
DEG_on_visible_update(bmain, true);
-
- if (!is_startup_file) {
- /* When starting up, the UI hasn't been fully initialised yet, and
- * this call can trigger icon updates, causing a segfault due to a
- * not-yet-initialised ghash for the icons. */
- wm_event_do_depsgraph(C);
- }
+ wm_event_do_depsgraph(C);
ED_editors_init(C);
diff --git a/source/blender/windowmanager/intern/wm_init_exit.c b/source/blender/windowmanager/intern/wm_init_exit.c
index c51d4c5534a..4b0d751a7ce 100644
--- a/source/blender/windowmanager/intern/wm_init_exit.c
+++ b/source/blender/windowmanager/intern/wm_init_exit.c
@@ -115,6 +115,7 @@
#include "ED_undo.h"
#include "UI_interface.h"
+#include "UI_resources.h"
#include "BLF_api.h"
#include "BLT_lang.h"
@@ -237,6 +238,11 @@ void WM_init(bContext *C, int argc, const char **argv)
BLF_init();
BLT_lang_init();
+ /* Init icons before reading .blend files for preview icons, which can
+ * get triggered by the depsgraph. This is also done in background mode
+ * for scripts that do background processing with preview icons. */
+ BKE_icons_init(BIFICONID_LAST);
+
/* reports cant be initialized before the wm,
* but keep before file reading, since that may report errors */
wm_init_reports(C);
@@ -259,13 +265,6 @@ void WM_init(bContext *C, int argc, const char **argv)
UI_init();
BKE_studiolight_init();
}
- else {
- /* Note: Currently only inits icons, which we now want in background mode too
- * (scripts could use those in background processing...).
- * In case we do more later, we may need to pass a 'background' flag.
- * Called from 'UI_init' above */
- BKE_icons_init(1);
- }
ED_spacemacros_init();
diff --git a/source/blender/windowmanager/intern/wm_keymap.c b/source/blender/windowmanager/intern/wm_keymap.c
index a95ccf36fdb..6815ff4413a 100644
--- a/source/blender/windowmanager/intern/wm_keymap.c
+++ b/source/blender/windowmanager/intern/wm_keymap.c
@@ -526,6 +526,25 @@ wmKeyMapItem *WM_keymap_add_tool(wmKeyMap *keymap, const char *idname, int type,
return kmi;
}
+/** Useful for mapping numbers to an enum. */
+void WM_keymap_add_context_enum_set_items(
+ wmKeyMap *keymap, const EnumPropertyItem *items, const char *data_path,
+ int type_start, int val, int modifier, int keymodifier)
+{
+ for (int i = 0, type_offset = 0; items[i].identifier; i++) {
+ if (items[i].identifier[0] == '\0') {
+ continue;
+ }
+ wmKeyMapItem *kmi = WM_keymap_add_item(
+ keymap, "WM_OT_context_set_enum",
+ type_start + type_offset, val, modifier, keymodifier);
+ RNA_string_set(kmi->ptr, "data_path", data_path);
+ RNA_string_set(kmi->ptr, "value", items[i].identifier);
+ type_offset += 1;
+ }
+}
+
+
bool WM_keymap_remove_item(wmKeyMap *keymap, wmKeyMapItem *kmi)
{
if (BLI_findindex(&keymap->items, kmi) != -1) {
diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c
index e757c7bee52..df869ba6b68 100644
--- a/source/blender/windowmanager/intern/wm_operators.c
+++ b/source/blender/windowmanager/intern/wm_operators.c
@@ -1043,15 +1043,17 @@ static uiBlock *wm_block_create_redo(bContext *C, ARegion *ar, void *arg_op)
if (op->type->flag & OPTYPE_MACRO) {
for (op = op->macro.first; op; op = op->next) {
- uiTemplateOperatorPropertyButs(C, layout, op, NULL, UI_BUT_LABEL_ALIGN_SPLIT_COLUMN,
- UI_TEMPLATE_OP_PROPS_SHOW_TITLE);
+ uiTemplateOperatorPropertyButs(
+ C, layout, op, UI_BUT_LABEL_ALIGN_SPLIT_COLUMN,
+ UI_TEMPLATE_OP_PROPS_SHOW_TITLE);
if (op->next)
uiItemS(layout);
}
}
else {
- uiTemplateOperatorPropertyButs(C, layout, op, NULL, UI_BUT_LABEL_ALIGN_SPLIT_COLUMN,
- UI_TEMPLATE_OP_PROPS_SHOW_TITLE);
+ uiTemplateOperatorPropertyButs(
+ C, layout, op, UI_BUT_LABEL_ALIGN_SPLIT_COLUMN,
+ UI_TEMPLATE_OP_PROPS_SHOW_TITLE);
}
UI_block_bounds_set_popup(block, 4, 0, 0);
@@ -1120,8 +1122,9 @@ static uiBlock *wm_block_dialog_create(bContext *C, ARegion *ar, void *userData)
layout = UI_block_layout(block, UI_LAYOUT_VERTICAL, UI_LAYOUT_PANEL, 0, 0, data->width, data->height, 0, style);
- uiTemplateOperatorPropertyButs(C, layout, op, NULL, UI_BUT_LABEL_ALIGN_SPLIT_COLUMN,
- UI_TEMPLATE_OP_PROPS_SHOW_TITLE);
+ uiTemplateOperatorPropertyButs(
+ C, layout, op, UI_BUT_LABEL_ALIGN_SPLIT_COLUMN,
+ UI_TEMPLATE_OP_PROPS_SHOW_TITLE);
/* clear so the OK button is left alone */
UI_block_func_set(block, NULL, NULL, NULL);
@@ -1160,7 +1163,7 @@ static uiBlock *wm_operator_ui_create(bContext *C, ARegion *ar, void *userData)
layout = UI_block_layout(block, UI_LAYOUT_VERTICAL, UI_LAYOUT_PANEL, 0, 0, data->width, data->height, 0, style);
/* since ui is defined the auto-layout args are not used */
- uiTemplateOperatorPropertyButs(C, layout, op, NULL, UI_BUT_LABEL_ALIGN_COLUMN, 0);
+ uiTemplateOperatorPropertyButs(C, layout, op, UI_BUT_LABEL_ALIGN_COLUMN, 0);
UI_block_func_set(block, NULL, NULL, NULL);
diff --git a/source/blender/windowmanager/intern/wm_window.c b/source/blender/windowmanager/intern/wm_window.c
index c1006db34ef..dd4013efdf2 100644
--- a/source/blender/windowmanager/intern/wm_window.c
+++ b/source/blender/windowmanager/intern/wm_window.c
@@ -123,7 +123,6 @@ static struct WMInitStruct {
/* ******** win open & close ************ */
static void wm_window_set_drawable(wmWindowManager *wm, wmWindow *win, bool activate);
-static void wm_window_clear_drawable(wmWindowManager *wm);
/* XXX this one should correctly check for apple top header...
* done for Cocoa : returns window contents (and not frame) max size*/
@@ -202,7 +201,6 @@ static void wm_ghostwindow_destroy(wmWindowManager *wm, wmWindow *win)
GHOST_DisposeWindow(g_system, win->ghostwin);
win->ghostwin = NULL;
win->gpuctx = NULL;
-
}
}
@@ -1103,7 +1101,7 @@ static void wm_window_set_drawable(wmWindowManager *wm, wmWindow *win, bool acti
immActivate();
}
-static void wm_window_clear_drawable(wmWindowManager *wm)
+void wm_window_clear_drawable(wmWindowManager *wm)
{
if (wm->windrawable) {
BLF_batch_reset();
@@ -2169,7 +2167,12 @@ ViewLayer *WM_window_get_active_view_layer(const wmWindow *win)
return view_layer;
}
- return BKE_view_layer_default_view(scene);
+ view_layer = BKE_view_layer_default_view(scene);
+ if (view_layer) {
+ WM_window_set_active_view_layer((wmWindow*)win, view_layer);
+ }
+
+ return view_layer;
}
void WM_window_set_active_view_layer(wmWindow *win, ViewLayer *view_layer)
diff --git a/source/blender/windowmanager/wm_window.h b/source/blender/windowmanager/wm_window.h
index 385d61217ad..4fd5d66fb43 100644
--- a/source/blender/windowmanager/wm_window.h
+++ b/source/blender/windowmanager/wm_window.h
@@ -57,6 +57,7 @@ void wm_window_ghostwindows_remove_invalid(bContext *C, wmWindowManager *wm);
void wm_window_process_events (const bContext *C);
void wm_window_process_events_nosleep(void);
+void wm_window_clear_drawable(wmWindowManager *wm);
void wm_window_make_drawable(wmWindowManager *wm, wmWindow *win);
void wm_window_reset_drawable(void);
diff --git a/source/creator/creator_args.c b/source/creator/creator_args.c
index da5dcf9ff8b..283585598bf 100644
--- a/source/creator/creator_args.c
+++ b/source/creator/creator_args.c
@@ -1448,6 +1448,16 @@ static int arg_handle_scene_set(int argc, const char **argv, void *data)
Scene *scene = BKE_scene_set_name(CTX_data_main(C), argv[1]);
if (scene) {
CTX_data_scene_set(C, scene);
+
+ /* Set the scene of the first window, see: T55991,
+ * otherwise scrips that run later won't get this scene back from the context. */
+ wmWindow *win = CTX_wm_window(C);
+ if (win == NULL) {
+ win = CTX_wm_manager(C)->windows.first;
+ }
+ if (win != NULL) {
+ WM_window_set_active_scene(CTX_data_main(C), C, win, scene);
+ }
}
return 1;
}