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:
authorDilith Jayakody <dilithjay@gmail.com>2022-04-03 05:38:54 +0300
committerDilith Jayakody <dilithjay@gmail.com>2022-04-03 05:38:54 +0300
commitbb44667a2e8f9c91548a574443e750583918e996 (patch)
tree12347d0a95971a9b7cd7d11786ccc2f948b214c6
parent2579367c93296eb2ab1da0b51dc107287dc09fd3 (diff)
parent79ff65d07bac0ecf0170542f86dc03a0228b53d5 (diff)
Merge branch 'master' into soc-2021-curvessoc-2021-curves
-rw-r--r--intern/cycles/blender/addon/engine.py4
-rw-r--r--intern/cycles/blender/addon/ui.py43
-rw-r--r--intern/cycles/blender/light.cpp3
-rw-r--r--intern/cycles/blender/object.cpp3
-rw-r--r--intern/cycles/blender/shader.cpp2
-rw-r--r--intern/cycles/blender/sync.cpp14
-rw-r--r--intern/cycles/integrator/pass_accessor.cpp17
-rw-r--r--intern/cycles/integrator/pass_accessor.h1
-rw-r--r--intern/cycles/kernel/film/accumulate.h38
-rw-r--r--intern/cycles/kernel/geom/object.h20
-rw-r--r--intern/cycles/kernel/integrator/shade_background.h3
-rw-r--r--intern/cycles/kernel/integrator/shade_light.h2
-rw-r--r--intern/cycles/kernel/integrator/shade_surface.h9
-rw-r--r--intern/cycles/kernel/integrator/shade_volume.h9
-rw-r--r--intern/cycles/kernel/integrator/shadow_state_template.h2
-rw-r--r--intern/cycles/kernel/light/light.h5
-rw-r--r--intern/cycles/kernel/types.h13
-rw-r--r--intern/cycles/scene/background.cpp11
-rw-r--r--intern/cycles/scene/background.h2
-rw-r--r--intern/cycles/scene/film.cpp41
-rw-r--r--intern/cycles/scene/film.h2
-rw-r--r--intern/cycles/scene/light.cpp10
-rw-r--r--intern/cycles/scene/light.h2
-rw-r--r--intern/cycles/scene/object.cpp16
-rw-r--r--intern/cycles/scene/object.h5
-rw-r--r--intern/cycles/scene/pass.cpp18
-rw-r--r--intern/cycles/scene/pass.h8
-rw-r--r--intern/cycles/scene/scene.cpp5
-rw-r--r--intern/cycles/scene/scene.h3
-rw-r--r--intern/cycles/session/buffers.cpp6
-rw-r--r--intern/cycles/session/buffers.h4
-rw-r--r--release/scripts/startup/bl_ui/properties_view_layer.py28
-rw-r--r--source/blender/blenkernel/BKE_layer.h16
-rw-r--r--source/blender/blenkernel/intern/layer.c148
-rw-r--r--source/blender/blenkernel/intern/object.cc12
-rw-r--r--source/blender/blenkernel/intern/world.c12
-rw-r--r--source/blender/editors/include/UI_interface.h6
-rw-r--r--source/blender/editors/interface/CMakeLists.txt20
-rw-r--r--source/blender/editors/interface/interface_intern.h6
-rw-r--r--source/blender/editors/interface/interface_query.cc (renamed from source/blender/editors/interface/interface_query.c)99
-rw-r--r--source/blender/editors/interface/interface_region_color_picker.cc (renamed from source/blender/editors/interface/interface_region_color_picker.c)71
-rw-r--r--source/blender/editors/interface/interface_region_hud.cc (renamed from source/blender/editors/interface/interface_region_hud.c)64
-rw-r--r--source/blender/editors/interface/interface_region_menu_pie.cc (renamed from source/blender/editors/interface/interface_region_menu_pie.c)39
-rw-r--r--source/blender/editors/interface/interface_region_menu_popup.cc (renamed from source/blender/editors/interface/interface_region_menu_popup.c)81
-rw-r--r--source/blender/editors/interface/interface_region_popover.cc (renamed from source/blender/editors/interface/interface_region_popover.c)57
-rw-r--r--source/blender/editors/interface/interface_region_popup.cc (renamed from source/blender/editors/interface/interface_region_popup.c)44
-rw-r--r--source/blender/editors/interface/interface_regions.cc (renamed from source/blender/editors/interface/interface_regions.c)4
-rw-r--r--source/blender/editors/interface/interface_style.cc (renamed from source/blender/editors/interface/interface_style.c)50
-rw-r--r--source/blender/editors/interface/interface_utils.cc (renamed from source/blender/editors/interface/interface_utils.c)129
-rw-r--r--source/blender/editors/object/object_transform.cc4
-rw-r--r--source/blender/editors/render/render_intern.hh2
-rw-r--r--source/blender/editors/render/render_ops.cc2
-rw-r--r--source/blender/editors/render/render_shading.cc80
-rw-r--r--source/blender/makesdna/DNA_layer_types.h19
-rw-r--r--source/blender/makesdna/DNA_object_types.h5
-rw-r--r--source/blender/makesdna/DNA_world_types.h4
-rw-r--r--source/blender/makesrna/intern/rna_internal.h4
-rw-r--r--source/blender/makesrna/intern/rna_object.c24
-rw-r--r--source/blender/makesrna/intern/rna_scene.c104
-rw-r--r--source/blender/makesrna/intern/rna_world.c23
60 files changed, 1102 insertions, 376 deletions
diff --git a/intern/cycles/blender/addon/engine.py b/intern/cycles/blender/addon/engine.py
index 48dd26cc622..b7713dc7110 100644
--- a/intern/cycles/blender/addon/engine.py
+++ b/intern/cycles/blender/addon/engine.py
@@ -228,6 +228,10 @@ def list_render_passes(scene, srl):
else:
yield (aov.name, "RGB", 'COLOR')
+ # Light groups.
+ for lightgroup in srl.lightgroups:
+ yield ("Combined_%s" % lightgroup.name, "RGB", 'COLOR')
+
def register_passes(engine, scene, view_layer):
for name, channelids, channeltype in list_render_passes(scene, view_layer):
diff --git a/intern/cycles/blender/addon/ui.py b/intern/cycles/blender/addon/ui.py
index c86452e0a18..c97afa86fad 100644
--- a/intern/cycles/blender/addon/ui.py
+++ b/intern/cycles/blender/addon/ui.py
@@ -12,7 +12,7 @@ from bpy.types import Panel
from bl_ui.properties_grease_pencil_common import GreasePencilSimplifyPanel
from bl_ui.properties_render import draw_hair_settings
-from bl_ui.properties_view_layer import ViewLayerCryptomattePanel, ViewLayerAOVPanel
+from bl_ui.properties_view_layer import ViewLayerCryptomattePanel, ViewLayerAOVPanel, ViewLayerLightgroupsPanel
class CyclesPresetPanel(PresetPanel, Panel):
COMPAT_ENGINES = {'CYCLES'}
@@ -883,6 +883,12 @@ class CYCLES_RENDER_PT_passes_aov(CyclesButtonsPanel, ViewLayerAOVPanel):
bl_parent_id = "CYCLES_RENDER_PT_passes"
+class CYCLES_RENDER_PT_passes_lightgroups(CyclesButtonsPanel, ViewLayerLightgroupsPanel):
+ bl_label = "Light Groups"
+ bl_context = "view_layer"
+ bl_parent_id = "CYCLES_RENDER_PT_passes"
+
+
class CYCLES_PT_post_processing(CyclesButtonsPanel, Panel):
bl_label = "Post Processing"
bl_options = {'DEFAULT_CLOSED'}
@@ -1082,7 +1088,7 @@ class CYCLES_OBJECT_PT_shading(CyclesButtonsPanel, Panel):
return False
ob = context.object
- return ob and has_geometry_visibility(ob) and ob.type != 'LIGHT'
+ return ob and has_geometry_visibility(ob)
def draw(self, context):
pass
@@ -1093,6 +1099,10 @@ class CYCLES_OBJECT_PT_shading_shadow_terminator(CyclesButtonsPanel, Panel):
bl_parent_id = "CYCLES_OBJECT_PT_shading"
bl_context = "object"
+ @classmethod
+ def poll(cls, context):
+ return context.object.type != 'LIGHT'
+
def draw(self, context):
layout = self.layout
layout.use_property_split = True
@@ -1110,6 +1120,10 @@ class CYCLES_OBJECT_PT_shading_gi_approximation(CyclesButtonsPanel, Panel):
bl_parent_id = "CYCLES_OBJECT_PT_shading"
bl_context = "object"
+ @classmethod
+ def poll(cls, context):
+ return context.object.type != 'LIGHT'
+
def draw(self, context):
layout = self.layout
layout.use_property_split = True
@@ -1132,7 +1146,7 @@ class CYCLES_OBJECT_PT_shading_caustics(CyclesButtonsPanel, Panel):
@classmethod
def poll(cls, context):
- return CyclesButtonsPanel.poll(context) and not use_metal(context)
+ return CyclesButtonsPanel.poll(context) and not use_metal(context) and context.object.type != 'LIGHT'
def draw(self, context):
layout = self.layout
@@ -1147,6 +1161,23 @@ class CYCLES_OBJECT_PT_shading_caustics(CyclesButtonsPanel, Panel):
col.prop(cob, "is_caustics_receiver")
+class CYCLES_OBJECT_PT_lightgroup(CyclesButtonsPanel, Panel):
+ bl_label = "Light Group"
+ bl_parent_id = "CYCLES_OBJECT_PT_shading"
+ bl_context = "object"
+
+ def draw(self, context):
+ layout = self.layout
+ layout.use_property_split = True
+
+ ob = context.object
+
+ view_layer = context.view_layer
+
+ col = layout.column(align=True)
+ col.prop_search(ob, "lightgroup", view_layer, "lightgroups", text="Light Group")
+
+
class CYCLES_OBJECT_PT_visibility(CyclesButtonsPanel, Panel):
bl_label = "Visibility"
bl_context = "object"
@@ -1399,10 +1430,14 @@ class CYCLES_WORLD_PT_surface(CyclesButtonsPanel, Panel):
layout.use_property_split = True
world = context.world
+ view_layer = context.view_layer
if not panel_node_draw(layout, world, 'OUTPUT_WORLD', 'Surface'):
layout.prop(world, "color")
+ col = layout.column(align=True)
+ col.prop_search(world, "lightgroup", view_layer, "lightgroups", text="Light Group")
+
class CYCLES_WORLD_PT_volume(CyclesButtonsPanel, Panel):
bl_label = "Volume"
@@ -2209,6 +2244,7 @@ classes = (
CYCLES_RENDER_PT_passes_light,
CYCLES_RENDER_PT_passes_crypto,
CYCLES_RENDER_PT_passes_aov,
+ CYCLES_RENDER_PT_passes_lightgroups,
CYCLES_RENDER_PT_filter,
CYCLES_RENDER_PT_override,
CYCLES_PT_post_processing,
@@ -2220,6 +2256,7 @@ classes = (
CYCLES_OBJECT_PT_shading_shadow_terminator,
CYCLES_OBJECT_PT_shading_gi_approximation,
CYCLES_OBJECT_PT_shading_caustics,
+ CYCLES_OBJECT_PT_lightgroup,
CYCLES_OBJECT_PT_visibility,
CYCLES_OBJECT_PT_visibility_ray_visibility,
CYCLES_OBJECT_PT_visibility_culling,
diff --git a/intern/cycles/blender/light.cpp b/intern/cycles/blender/light.cpp
index 04799443ceb..5359fa13505 100644
--- a/intern/cycles/blender/light.cpp
+++ b/intern/cycles/blender/light.cpp
@@ -143,6 +143,9 @@ void BlenderSync::sync_light(BL::Object &b_parent,
light->set_use_scatter((visibility & PATH_RAY_VOLUME_SCATTER) != 0);
light->set_is_shadow_catcher(b_ob_info.real_object.is_shadow_catcher());
+ /* lightgroup */
+ light->set_lightgroup(ustring(b_ob_info.real_object.lightgroup()));
+
/* tag */
light->tag_update(scene);
}
diff --git a/intern/cycles/blender/object.cpp b/intern/cycles/blender/object.cpp
index 16a6b3454ed..d8f236e0641 100644
--- a/intern/cycles/blender/object.cpp
+++ b/intern/cycles/blender/object.cpp
@@ -343,6 +343,9 @@ Object *BlenderSync::sync_object(BL::Depsgraph &b_depsgraph,
object->set_random_id(hash_uint2(hash_string(object->name.c_str()), 0));
}
+ /* lightgroup */
+ object->set_lightgroup(ustring(b_ob.lightgroup()));
+
object->tag_update(scene);
}
diff --git a/intern/cycles/blender/shader.cpp b/intern/cycles/blender/shader.cpp
index 224cbea85f3..d3527567b96 100644
--- a/intern/cycles/blender/shader.cpp
+++ b/intern/cycles/blender/shader.cpp
@@ -1532,6 +1532,8 @@ void BlenderSync::sync_world(BL::Depsgraph &b_depsgraph, BL::SpaceView3D &b_v3d,
background->set_use_shader(view_layer.use_background_shader ||
viewport_parameters.use_custom_shader());
+ background->set_lightgroup(ustring(b_world ? b_world.lightgroup() : ""));
+
background->tag_update(scene);
}
diff --git a/intern/cycles/blender/sync.cpp b/intern/cycles/blender/sync.cpp
index 8af2ee7a435..bd6bfafedeb 100644
--- a/intern/cycles/blender/sync.cpp
+++ b/intern/cycles/blender/sync.cpp
@@ -745,6 +745,20 @@ void BlenderSync::sync_render_passes(BL::RenderLayer &b_rlay, BL::ViewLayer &b_v
}
}
+ /* Light Group passes. */
+ BL::ViewLayer::lightgroups_iterator b_lightgroup_iter;
+ for (b_view_layer.lightgroups.begin(b_lightgroup_iter);
+ b_lightgroup_iter != b_view_layer.lightgroups.end();
+ ++b_lightgroup_iter) {
+ BL::Lightgroup b_lightgroup(*b_lightgroup_iter);
+
+ string name = string_printf("Combined_%s", b_lightgroup.name().c_str());
+
+ b_engine.add_pass(name.c_str(), 3, "RGB", b_view_layer.name().c_str());
+ Pass *pass = pass_add(scene, PASS_COMBINED, name.c_str(), PassMode::NOISY);
+ pass->set_lightgroup(ustring(b_lightgroup.name()));
+ }
+
scene->film->set_pass_alpha_threshold(b_view_layer.pass_alpha_threshold());
}
diff --git a/intern/cycles/integrator/pass_accessor.cpp b/intern/cycles/integrator/pass_accessor.cpp
index 0be3cf6860b..05318b7545b 100644
--- a/intern/cycles/integrator/pass_accessor.cpp
+++ b/intern/cycles/integrator/pass_accessor.cpp
@@ -18,7 +18,11 @@ CCL_NAMESPACE_BEGIN
*/
PassAccessor::PassAccessInfo::PassAccessInfo(const BufferPass &pass)
- : type(pass.type), mode(pass.mode), include_albedo(pass.include_albedo), offset(pass.offset)
+ : type(pass.type),
+ mode(pass.mode),
+ include_albedo(pass.include_albedo),
+ is_lightgroup(!pass.lightgroup.empty()),
+ offset(pass.offset)
{
}
@@ -127,7 +131,8 @@ bool PassAccessor::get_render_tile_pixels(const RenderBuffers *render_buffers,
const PassType type = pass_access_info_.type;
const PassMode mode = pass_access_info_.mode;
- const PassInfo pass_info = Pass::get_info(type, pass_access_info_.include_albedo);
+ const PassInfo pass_info = Pass::get_info(
+ type, pass_access_info_.include_albedo, pass_access_info_.is_lightgroup);
int num_written_components = pass_info.num_components;
if (pass_info.num_components == 1) {
@@ -215,8 +220,8 @@ void PassAccessor::init_kernel_film_convert(KernelFilmConvert *kfilm_convert,
const Destination &destination) const
{
const PassMode mode = pass_access_info_.mode;
- const PassInfo &pass_info = Pass::get_info(pass_access_info_.type,
- pass_access_info_.include_albedo);
+ const PassInfo &pass_info = Pass::get_info(
+ pass_access_info_.type, pass_access_info_.include_albedo, pass_access_info_.is_lightgroup);
kfilm_convert->pass_offset = pass_access_info_.offset;
kfilm_convert->pass_stride = buffer_params.pass_stride;
@@ -279,8 +284,8 @@ bool PassAccessor::set_render_tile_pixels(RenderBuffers *render_buffers, const S
return false;
}
- const PassInfo pass_info = Pass::get_info(pass_access_info_.type,
- pass_access_info_.include_albedo);
+ const PassInfo pass_info = Pass::get_info(
+ pass_access_info_.type, pass_access_info_.include_albedo, pass_access_info_.is_lightgroup);
const BufferParams &buffer_params = render_buffers->params;
diff --git a/intern/cycles/integrator/pass_accessor.h b/intern/cycles/integrator/pass_accessor.h
index 7de1d03961b..683d3a35272 100644
--- a/intern/cycles/integrator/pass_accessor.h
+++ b/intern/cycles/integrator/pass_accessor.h
@@ -28,6 +28,7 @@ class PassAccessor {
PassType type = PASS_NONE;
PassMode mode = PassMode::NOISY;
bool include_albedo = false;
+ bool is_lightgroup = false;
int offset = -1;
/* For the shadow catcher matte pass: whether to approximate shadow catcher pass into its
diff --git a/intern/cycles/kernel/film/accumulate.h b/intern/cycles/kernel/film/accumulate.h
index d6a385a4bff..e10acfd7eb5 100644
--- a/intern/cycles/kernel/film/accumulate.h
+++ b/intern/cycles/kernel/film/accumulate.h
@@ -320,12 +320,13 @@ ccl_device_inline void kernel_accum_combined_transparent_pass(KernelGlobals kg,
}
/* Write background or emission to appropriate pass. */
-ccl_device_inline void kernel_accum_emission_or_background_pass(KernelGlobals kg,
- ConstIntegratorState state,
- float3 contribution,
- ccl_global float *ccl_restrict
- buffer,
- const int pass)
+ccl_device_inline void kernel_accum_emission_or_background_pass(
+ KernelGlobals kg,
+ ConstIntegratorState state,
+ float3 contribution,
+ ccl_global float *ccl_restrict buffer,
+ const int pass,
+ const int lightgroup = LIGHTGROUP_NONE)
{
if (!(kernel_data.film.light_pass_flag & PASS_ANY)) {
return;
@@ -347,6 +348,11 @@ ccl_device_inline void kernel_accum_emission_or_background_pass(KernelGlobals kg
}
# endif /* __DENOISING_FEATURES__ */
+ if (lightgroup != LIGHTGROUP_NONE && kernel_data.film.pass_lightgroup != PASS_UNUSED) {
+ kernel_write_pass_float3(buffer + kernel_data.film.pass_lightgroup + 3 * lightgroup,
+ contribution);
+ }
+
if (!(path_flag & PATH_RAY_ANY_PASS)) {
/* Directly visible, write to emission or background pass. */
pass_offset = pass;
@@ -449,6 +455,13 @@ ccl_device_inline void kernel_accum_light(KernelGlobals kg,
return;
}
+ /* Write lightgroup pass. LIGHTGROUP_NONE is ~0 so decode from unsigned to signed */
+ const int lightgroup = (int)(INTEGRATOR_STATE(state, shadow_path, lightgroup)) - 1;
+ if (lightgroup != LIGHTGROUP_NONE && kernel_data.film.pass_lightgroup != PASS_UNUSED) {
+ kernel_write_pass_float3(buffer + kernel_data.film.pass_lightgroup + 3 * lightgroup,
+ contribution);
+ }
+
if (kernel_data.kernel_features & KERNEL_FEATURE_LIGHT_PASSES) {
int pass_offset = PASS_UNUSED;
@@ -566,15 +579,20 @@ ccl_device_inline void kernel_accum_background(KernelGlobals kg,
kernel_accum_combined_transparent_pass(
kg, path_flag, sample, contribution, transparent, buffer);
}
- kernel_accum_emission_or_background_pass(
- kg, state, contribution, buffer, kernel_data.film.pass_background);
+ kernel_accum_emission_or_background_pass(kg,
+ state,
+ contribution,
+ buffer,
+ kernel_data.film.pass_background,
+ kernel_data.background.lightgroup);
}
/* Write emission to render buffer. */
ccl_device_inline void kernel_accum_emission(KernelGlobals kg,
ConstIntegratorState state,
const float3 L,
- ccl_global float *ccl_restrict render_buffer)
+ ccl_global float *ccl_restrict render_buffer,
+ const int lightgroup = LIGHTGROUP_NONE)
{
float3 contribution = L;
kernel_accum_clamp(kg, &contribution, INTEGRATOR_STATE(state, path, bounce) - 1);
@@ -585,7 +603,7 @@ ccl_device_inline void kernel_accum_emission(KernelGlobals kg,
kernel_accum_combined_pass(kg, path_flag, sample, contribution, buffer);
kernel_accum_emission_or_background_pass(
- kg, state, contribution, buffer, kernel_data.film.pass_emission);
+ kg, state, contribution, buffer, kernel_data.film.pass_emission, lightgroup);
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/geom/object.h b/intern/cycles/kernel/geom/object.h
index 86c57c84b47..3faab7fa905 100644
--- a/intern/cycles/kernel/geom/object.h
+++ b/intern/cycles/kernel/geom/object.h
@@ -283,6 +283,26 @@ ccl_device_inline float object_pass_id(KernelGlobals kg, int object)
return kernel_tex_fetch(__objects, object).pass_id;
}
+/* Lightgroup of lamp */
+
+ccl_device_inline int lamp_lightgroup(KernelGlobals kg, int lamp)
+{
+ if (lamp == LAMP_NONE)
+ return LIGHTGROUP_NONE;
+
+ return kernel_tex_fetch(__lights, lamp).lightgroup;
+}
+
+/* Lightgroup of object */
+
+ccl_device_inline int object_lightgroup(KernelGlobals kg, int object)
+{
+ if (object == OBJECT_NONE)
+ return LIGHTGROUP_NONE;
+
+ return kernel_tex_fetch(__objects, object).lightgroup;
+}
+
/* Per lamp random number for shader variation */
ccl_device_inline float lamp_random_number(KernelGlobals kg, int lamp)
diff --git a/intern/cycles/kernel/integrator/shade_background.h b/intern/cycles/kernel/integrator/shade_background.h
index 4fd41121466..62b3ce1c15c 100644
--- a/intern/cycles/kernel/integrator/shade_background.h
+++ b/intern/cycles/kernel/integrator/shade_background.h
@@ -186,7 +186,8 @@ ccl_device_inline void integrate_distant_lights(KernelGlobals kg,
/* Write to render buffer. */
const float3 throughput = INTEGRATOR_STATE(state, path, throughput);
- kernel_accum_emission(kg, state, throughput * light_eval, render_buffer);
+ kernel_accum_emission(
+ kg, state, throughput * light_eval, render_buffer, kernel_data.background.lightgroup);
}
}
}
diff --git a/intern/cycles/kernel/integrator/shade_light.h b/intern/cycles/kernel/integrator/shade_light.h
index 4a519a76ed0..be926c78439 100644
--- a/intern/cycles/kernel/integrator/shade_light.h
+++ b/intern/cycles/kernel/integrator/shade_light.h
@@ -78,7 +78,7 @@ ccl_device_inline void integrate_light(KernelGlobals kg,
/* Write to render buffer. */
const float3 throughput = INTEGRATOR_STATE(state, path, throughput);
- kernel_accum_emission(kg, state, throughput * light_eval, render_buffer);
+ kernel_accum_emission(kg, state, throughput * light_eval, render_buffer, ls.group);
}
ccl_device void integrator_shade_light(KernelGlobals kg,
diff --git a/intern/cycles/kernel/integrator/shade_surface.h b/intern/cycles/kernel/integrator/shade_surface.h
index c5dd9fe27f4..a9bf3b5b432 100644
--- a/intern/cycles/kernel/integrator/shade_surface.h
+++ b/intern/cycles/kernel/integrator/shade_surface.h
@@ -87,7 +87,8 @@ ccl_device_forceinline void integrate_surface_emission(KernelGlobals kg,
}
const float3 throughput = INTEGRATOR_STATE(state, path, throughput);
- kernel_accum_emission(kg, state, throughput * L, render_buffer);
+ kernel_accum_emission(
+ kg, state, throughput * L, render_buffer, object_lightgroup(kg, sd->object));
}
#endif /* __EMISSION__ */
@@ -258,6 +259,12 @@ ccl_device_forceinline void integrate_surface_direct_light(KernelGlobals kg,
if (kernel_data.kernel_features & KERNEL_FEATURE_SHADOW_PASS) {
INTEGRATOR_STATE_WRITE(shadow_state, shadow_path, unshadowed_throughput) = throughput;
}
+
+ /* Write Lightgroup, +1 as lightgroup is int but we need to encode into a uint8_t. */
+ INTEGRATOR_STATE_WRITE(
+ shadow_state, shadow_path, lightgroup) = (ls.type != LIGHT_BACKGROUND) ?
+ ls.group + 1 :
+ kernel_data.background.lightgroup + 1;
}
#endif
diff --git a/intern/cycles/kernel/integrator/shade_volume.h b/intern/cycles/kernel/integrator/shade_volume.h
index acda4b8e9d1..4a5015946aa 100644
--- a/intern/cycles/kernel/integrator/shade_volume.h
+++ b/intern/cycles/kernel/integrator/shade_volume.h
@@ -653,7 +653,8 @@ ccl_device_forceinline void volume_integrate_heterogeneous(
/* Write accumulated emission. */
if (!is_zero(accum_emission)) {
- kernel_accum_emission(kg, state, accum_emission, render_buffer);
+ kernel_accum_emission(
+ kg, state, accum_emission, render_buffer, object_lightgroup(kg, sd->object));
}
# ifdef __DENOISING_FEATURES__
@@ -833,6 +834,12 @@ ccl_device_forceinline void integrate_volume_direct_light(
INTEGRATOR_STATE_WRITE(shadow_state, shadow_path, unshadowed_throughput) = throughput;
}
+ /* Write Lightgroup, +1 as lightgroup is int but we need to encode into a uint8_t. */
+ INTEGRATOR_STATE_WRITE(
+ shadow_state, shadow_path, lightgroup) = (ls->type != LIGHT_BACKGROUND) ?
+ ls->group + 1 :
+ kernel_data.background.lightgroup + 1;
+
integrator_state_copy_volume_stack_to_shadow(kg, shadow_state, state);
}
# endif
diff --git a/intern/cycles/kernel/integrator/shadow_state_template.h b/intern/cycles/kernel/integrator/shadow_state_template.h
index 9308df53e46..eaee65ada40 100644
--- a/intern/cycles/kernel/integrator/shadow_state_template.h
+++ b/intern/cycles/kernel/integrator/shadow_state_template.h
@@ -38,6 +38,8 @@ KERNEL_STRUCT_MEMBER(shadow_path, packed_float3, pass_diffuse_weight, KERNEL_FEA
KERNEL_STRUCT_MEMBER(shadow_path, packed_float3, pass_glossy_weight, KERNEL_FEATURE_LIGHT_PASSES)
/* Number of intersections found by ray-tracing. */
KERNEL_STRUCT_MEMBER(shadow_path, uint16_t, num_hits, KERNEL_FEATURE_PATH_TRACING)
+/* Light group. */
+KERNEL_STRUCT_MEMBER(shadow_path, uint8_t, lightgroup, KERNEL_FEATURE_PATH_TRACING)
KERNEL_STRUCT_END(shadow_path)
/********************************** Shadow Ray *******************************/
diff --git a/intern/cycles/kernel/light/light.h b/intern/cycles/kernel/light/light.h
index fb637008ca4..1df1615ed99 100644
--- a/intern/cycles/kernel/light/light.h
+++ b/intern/cycles/kernel/light/light.h
@@ -23,6 +23,7 @@ typedef struct LightSample {
int prim; /* primitive id for triangle/curve lights */
int shader; /* shader id */
int lamp; /* lamp id */
+ int group; /* lightgroup */
LightType type; /* type of light */
} LightSample;
@@ -52,6 +53,7 @@ ccl_device_inline bool light_sample(KernelGlobals kg,
ls->lamp = lamp;
ls->u = randu;
ls->v = randv;
+ ls->group = lamp_lightgroup(kg, lamp);
if (in_volume_segment && (type == LIGHT_DISTANT || type == LIGHT_BACKGROUND)) {
/* Distant lights in a volume get a dummy sample, position will not actually
@@ -413,6 +415,7 @@ ccl_device bool light_sample_from_distant_ray(KernelGlobals kg,
ls->P = -ray_D;
ls->Ng = -ray_D;
ls->D = ray_D;
+ ls->group = lamp_lightgroup(kg, lamp);
/* compute pdf */
float invarea = klight->distant.invarea;
@@ -441,6 +444,7 @@ ccl_device bool light_sample_from_intersection(KernelGlobals kg,
ls->t = isect->t;
ls->P = ray_P + ray_D * ls->t;
ls->D = ray_D;
+ ls->group = lamp_lightgroup(kg, lamp);
if (type == LIGHT_SPOT) {
const float3 center = make_float3(klight->co[0], klight->co[1], klight->co[2]);
@@ -706,6 +710,7 @@ ccl_device_forceinline void triangle_light_sample(KernelGlobals kg,
ls->lamp = LAMP_NONE;
ls->shader |= SHADER_USE_MIS;
ls->type = LIGHT_TRIANGLE;
+ ls->group = object_lightgroup(kg, object);
float distance_to_plane = fabsf(dot(N0, V[0] - P) / dot(N0, N0));
diff --git a/intern/cycles/kernel/types.h b/intern/cycles/kernel/types.h
index 00b5b007e11..9d9daaa0dda 100644
--- a/intern/cycles/kernel/types.h
+++ b/intern/cycles/kernel/types.h
@@ -46,6 +46,7 @@ CCL_NAMESPACE_BEGIN
#define LAMP_NONE (~0)
#define ID_NONE (0.0f)
#define PASS_UNUSED (~0)
+#define LIGHTGROUP_NONE (~0)
#define INTEGRATOR_SHADOW_ISECT_SIZE_CPU 1024U
#define INTEGRATOR_SHADOW_ISECT_SIZE_GPU 4U
@@ -1108,6 +1109,7 @@ typedef struct KernelFilm {
int pass_aov_color;
int pass_aov_value;
+ int pass_lightgroup;
/* XYZ to rendering color space transform. float4 instead of float3 to
* ensure consistent padding/alignment across devices. */
@@ -1192,8 +1194,10 @@ typedef struct KernelBackground {
int use_mis;
+ int lightgroup;
+
/* Padding */
- int pad1, pad2, pad3;
+ int pad1, pad2;
} KernelBackground;
static_assert_align(KernelBackground, 16);
@@ -1372,9 +1376,12 @@ typedef struct KernelObject {
float ao_distance;
+ int lightgroup;
+
uint visibility;
int primitive_type;
- int pad[2];
+
+ int pad1;
} KernelObject;
static_assert_align(KernelObject, 16);
@@ -1427,7 +1434,7 @@ typedef struct KernelLight {
float random;
float strength[3];
int use_caustics;
- float pad1;
+ int lightgroup;
Transform tfm;
Transform itfm;
union {
diff --git a/intern/cycles/scene/background.cpp b/intern/cycles/scene/background.cpp
index 1c3a9f9358d..bffc8895bfd 100644
--- a/intern/cycles/scene/background.cpp
+++ b/intern/cycles/scene/background.cpp
@@ -32,6 +32,8 @@ NODE_DEFINE(Background)
SOCKET_NODE(shader, "Shader", Shader::get_node_type());
+ SOCKET_STRING(lightgroup, "Light Group", ustring());
+
return type;
}
@@ -101,6 +103,15 @@ void Background::device_update(Device *device, DeviceScene *dscene, Scene *scene
kbackground->surface_shader |= SHADER_EXCLUDE_CAMERA;
}
+ /* Light group. */
+ auto it = scene->lightgroups.find(lightgroup);
+ if (it != scene->lightgroups.end()) {
+ kbackground->lightgroup = it->second;
+ }
+ else {
+ kbackground->lightgroup = LIGHTGROUP_NONE;
+ }
+
clear_modified();
}
diff --git a/intern/cycles/scene/background.h b/intern/cycles/scene/background.h
index bbffce6e30a..50b4368d708 100644
--- a/intern/cycles/scene/background.h
+++ b/intern/cycles/scene/background.h
@@ -30,6 +30,8 @@ class Background : public Node {
NODE_SOCKET_API(float, volume_step_size)
+ NODE_SOCKET_API(ustring, lightgroup)
+
Background();
~Background();
diff --git a/intern/cycles/scene/film.cpp b/intern/cycles/scene/film.cpp
index e17c839d60b..c3b126544c4 100644
--- a/intern/cycles/scene/film.cpp
+++ b/intern/cycles/scene/film.cpp
@@ -175,6 +175,7 @@ void Film::device_update(Device *device, DeviceScene *dscene, Scene *scene)
kfilm->pass_volume_direct = PASS_UNUSED;
kfilm->pass_volume_indirect = PASS_UNUSED;
kfilm->pass_shadow = PASS_UNUSED;
+ kfilm->pass_lightgroup = PASS_UNUSED;
/* Mark passes as unused so that the kernel knows the pass is inaccessible. */
kfilm->pass_denoising_normal = PASS_UNUSED;
@@ -189,6 +190,7 @@ void Film::device_update(Device *device, DeviceScene *dscene, Scene *scene)
bool have_cryptomatte = false;
bool have_aov_color = false;
bool have_aov_value = false;
+ bool have_lightgroup = false;
for (size_t i = 0; i < scene->passes.size(); i++) {
const Pass *pass = scene->passes[i];
@@ -223,6 +225,15 @@ void Film::device_update(Device *device, DeviceScene *dscene, Scene *scene)
assert(pass->get_type() <= PASS_CATEGORY_BAKE_END);
}
+ if (pass->get_lightgroup() != ustring()) {
+ if (!have_lightgroup) {
+ kfilm->pass_lightgroup = kfilm->pass_stride;
+ have_lightgroup = true;
+ }
+ kfilm->pass_stride += pass->get_info().num_components;
+ continue;
+ }
+
switch (pass->get_type()) {
case PASS_COMBINED:
kfilm->pass_combined = kfilm->pass_stride;
@@ -414,6 +425,26 @@ int Film::get_aov_offset(Scene *scene, string name, bool &is_color)
return -1;
}
+bool Film::update_lightgroups(Scene *scene)
+{
+ map<ustring, int> lightgroups;
+ int i = 0;
+ foreach (const Pass *pass, scene->passes) {
+ ustring lightgroup = pass->get_lightgroup();
+ if (!lightgroup.empty()) {
+ if (!lightgroups.count(lightgroup)) {
+ lightgroups[lightgroup] = i++;
+ }
+ }
+ }
+ if (scene->lightgroups != lightgroups) {
+ scene->lightgroups = lightgroups;
+ return true;
+ }
+
+ return false;
+}
+
void Film::update_passes(Scene *scene, bool add_sample_count_pass)
{
const Background *background = scene->background;
@@ -580,11 +611,19 @@ void Film::remove_auto_passes(Scene *scene)
static bool compare_pass_order(const Pass *a, const Pass *b)
{
+ /* On the highest level, sort by number of components.
+ * Within passes of the same component count, sort so that all non-lightgroup passes come first.
+ * Within that group, sort by type. */
const int num_components_a = a->get_info().num_components;
const int num_components_b = b->get_info().num_components;
if (num_components_a == num_components_b) {
- return (a->get_type() < b->get_type());
+ const int is_lightgroup_a = !a->get_lightgroup().empty();
+ const int is_lightgroup_b = !b->get_lightgroup().empty();
+ if (is_lightgroup_a == is_lightgroup_b) {
+ return (a->get_type() < b->get_type());
+ }
+ return is_lightgroup_b;
}
return num_components_a > num_components_b;
diff --git a/intern/cycles/scene/film.h b/intern/cycles/scene/film.h
index 43597b0fc79..f1e3237eb9e 100644
--- a/intern/cycles/scene/film.h
+++ b/intern/cycles/scene/film.h
@@ -68,6 +68,8 @@ class Film : public Node {
int get_aov_offset(Scene *scene, string name, bool &is_color);
+ bool update_lightgroups(Scene *scene);
+
/* Update passes so that they contain all passes required for the configured functionality.
*
* If `add_sample_count_pass` is true then the SAMPLE_COUNT pass is ensured to be added. */
diff --git a/intern/cycles/scene/light.cpp b/intern/cycles/scene/light.cpp
index 85a7f37994c..5e311d3051f 100644
--- a/intern/cycles/scene/light.cpp
+++ b/intern/cycles/scene/light.cpp
@@ -134,6 +134,8 @@ NODE_DEFINE(Light)
SOCKET_NODE(shader, "Shader", Shader::get_node_type());
+ SOCKET_STRING(lightgroup, "Light Group", ustring());
+
return type;
}
@@ -902,6 +904,14 @@ void LightManager::device_update_points(Device *, DeviceScene *dscene, Scene *sc
klights[light_index].tfm = light->tfm;
klights[light_index].itfm = transform_inverse(light->tfm);
+ auto it = scene->lightgroups.find(light->lightgroup);
+ if (it != scene->lightgroups.end()) {
+ klights[light_index].lightgroup = it->second;
+ }
+ else {
+ klights[light_index].lightgroup = LIGHTGROUP_NONE;
+ }
+
light_index++;
}
diff --git a/intern/cycles/scene/light.h b/intern/cycles/scene/light.h
index 25190f6fb63..5b852f210fc 100644
--- a/intern/cycles/scene/light.h
+++ b/intern/cycles/scene/light.h
@@ -71,6 +71,8 @@ class Light : public Node {
NODE_SOCKET_API(int, max_bounces)
NODE_SOCKET_API(uint, random_id)
+ NODE_SOCKET_API(ustring, lightgroup)
+
void tag_update(Scene *scene);
/* Check whether the light has contribution the scene. */
diff --git a/intern/cycles/scene/object.cpp b/intern/cycles/scene/object.cpp
index 9b19169880a..55d89fc3673 100644
--- a/intern/cycles/scene/object.cpp
+++ b/intern/cycles/scene/object.cpp
@@ -98,6 +98,8 @@ NODE_DEFINE(Object)
SOCKET_FLOAT(ao_distance, "AO Distance", 0.0f);
+ SOCKET_STRING(lightgroup, "Light Group", ustring());
+
return type;
}
@@ -393,7 +395,8 @@ static float object_volume_density(const Transform &tfm, Geometry *geom)
void ObjectManager::device_update_object_transform(UpdateObjectTransformState *state,
Object *ob,
- bool update_all)
+ bool update_all,
+ const Scene *scene)
{
KernelObject &kobject = state->objects[ob->index];
Transform *object_motion_pass = state->object_motion_pass;
@@ -532,6 +535,15 @@ void ObjectManager::device_update_object_transform(UpdateObjectTransformState *s
if (geom->geometry_type == Geometry::HAIR) {
state->have_curves = true;
}
+
+ /* Light group. */
+ auto it = scene->lightgroups.find(ob->lightgroup);
+ if (it != scene->lightgroups.end()) {
+ kobject.lightgroup = it->second;
+ }
+ else {
+ kobject.lightgroup = LIGHTGROUP_NONE;
+ }
}
void ObjectManager::device_update_prim_offsets(Device *device, DeviceScene *dscene, Scene *scene)
@@ -618,7 +630,7 @@ void ObjectManager::device_update_transforms(DeviceScene *dscene, Scene *scene,
[&](const blocked_range<size_t> &r) {
for (size_t i = r.begin(); i != r.end(); i++) {
Object *ob = state.scene->objects[i];
- device_update_object_transform(&state, ob, update_all);
+ device_update_object_transform(&state, ob, update_all, scene);
}
});
diff --git a/intern/cycles/scene/object.h b/intern/cycles/scene/object.h
index 561ecd4e7e9..c41f1416180 100644
--- a/intern/cycles/scene/object.h
+++ b/intern/cycles/scene/object.h
@@ -66,6 +66,8 @@ class Object : public Node {
NODE_SOCKET_API(float, ao_distance)
+ NODE_SOCKET_API(ustring, lightgroup)
+
/* Set during device update. */
bool intersects_volume;
@@ -169,7 +171,8 @@ class ObjectManager {
protected:
void device_update_object_transform(UpdateObjectTransformState *state,
Object *ob,
- bool update_all);
+ bool update_all,
+ const Scene *scene);
void device_update_object_transform_task(UpdateObjectTransformState *state);
bool device_update_object_transform_pop_work(UpdateObjectTransformState *state,
int *start_index,
diff --git a/intern/cycles/scene/pass.cpp b/intern/cycles/scene/pass.cpp
index 41730cb189d..5f5b19e710d 100644
--- a/intern/cycles/scene/pass.cpp
+++ b/intern/cycles/scene/pass.cpp
@@ -124,6 +124,7 @@ NODE_DEFINE(Pass)
SOCKET_ENUM(mode, "Mode", *pass_mode_enum, static_cast<int>(PassMode::DENOISED));
SOCKET_STRING(name, "Name", ustring());
SOCKET_BOOLEAN(include_albedo, "Include Albedo", false);
+ SOCKET_STRING(lightgroup, "Light Group", ustring());
return type;
}
@@ -134,7 +135,7 @@ Pass::Pass() : Node(get_node_type()), is_auto_(false)
PassInfo Pass::get_info() const
{
- return get_info(type, include_albedo);
+ return get_info(type, include_albedo, !lightgroup.empty());
}
bool Pass::is_written() const
@@ -142,7 +143,7 @@ bool Pass::is_written() const
return get_info().is_written;
}
-PassInfo Pass::get_info(const PassType type, const bool include_albedo)
+PassInfo Pass::get_info(const PassType type, const bool include_albedo, const bool is_lightgroup)
{
PassInfo pass_info;
@@ -157,9 +158,9 @@ PassInfo Pass::get_info(const PassType type, const bool include_albedo)
pass_info.num_components = 0;
break;
case PASS_COMBINED:
- pass_info.num_components = 4;
+ pass_info.num_components = is_lightgroup ? 3 : 4;
pass_info.use_exposure = true;
- pass_info.support_denoise = true;
+ pass_info.support_denoise = !is_lightgroup;
break;
case PASS_DEPTH:
pass_info.num_components = 1;
@@ -369,13 +370,16 @@ const Pass *Pass::find(const vector<Pass *> &passes, const string &name)
return nullptr;
}
-const Pass *Pass::find(const vector<Pass *> &passes, PassType type, PassMode mode)
+const Pass *Pass::find(const vector<Pass *> &passes,
+ PassType type,
+ PassMode mode,
+ const ustring &lightgroup)
{
for (const Pass *pass : passes) {
- if (pass->get_type() != type || pass->get_mode() != mode) {
+ if (pass->get_type() != type || pass->get_mode() != mode ||
+ pass->get_lightgroup() != lightgroup) {
continue;
}
-
return pass;
}
diff --git a/intern/cycles/scene/pass.h b/intern/cycles/scene/pass.h
index c12df007b5d..e0689eba688 100644
--- a/intern/cycles/scene/pass.h
+++ b/intern/cycles/scene/pass.h
@@ -53,6 +53,7 @@ class Pass : public Node {
NODE_SOCKET_API(PassMode, mode)
NODE_SOCKET_API(ustring, name)
NODE_SOCKET_API(bool, include_albedo)
+ NODE_SOCKET_API(ustring, lightgroup)
Pass();
@@ -72,7 +73,9 @@ class Pass : public Node {
static const NodeEnum *get_type_enum();
static const NodeEnum *get_mode_enum();
- static PassInfo get_info(PassType type, const bool include_albedo = false);
+ static PassInfo get_info(PassType type,
+ const bool include_albedo = false,
+ const bool is_lightgroup = false);
static bool contains(const vector<Pass *> &passes, PassType type);
@@ -80,7 +83,8 @@ class Pass : public Node {
static const Pass *find(const vector<Pass *> &passes, const string &name);
static const Pass *find(const vector<Pass *> &passes,
PassType type,
- PassMode mode = PassMode::NOISY);
+ PassMode mode = PassMode::NOISY,
+ const ustring &lightgroup = ustring());
/* Returns PASS_UNUSED if there is no corresponding pass. */
static int get_offset(const vector<Pass *> &passes, const Pass *pass);
diff --git a/intern/cycles/scene/scene.cpp b/intern/cycles/scene/scene.cpp
index 359e2d8e2c3..b6b53004816 100644
--- a/intern/cycles/scene/scene.cpp
+++ b/intern/cycles/scene/scene.cpp
@@ -251,6 +251,11 @@ void Scene::device_update(Device *device_, Progress &progress)
* - Lookup tables are done a second time to handle film tables
*/
+ if (film->update_lightgroups(this)) {
+ light_manager->tag_update(this, ccl::LightManager::LIGHT_MODIFIED);
+ object_manager->tag_update(this, ccl::ObjectManager::OBJECT_MODIFIED);
+ }
+
progress.set_status("Updating Shaders");
shader_manager->device_update(device, &dscene, this, progress);
diff --git a/intern/cycles/scene/scene.h b/intern/cycles/scene/scene.h
index e1b36899302..9e3e8d61b80 100644
--- a/intern/cycles/scene/scene.h
+++ b/intern/cycles/scene/scene.h
@@ -197,6 +197,9 @@ class Scene : public NodeOwner {
/* Optional name. Is used for logging and reporting. */
string name;
+ /* Maps from Light group names to their pass ID. */
+ map<ustring, int> lightgroups;
+
/* data */
BVH *bvh;
Camera *camera;
diff --git a/intern/cycles/session/buffers.cpp b/intern/cycles/session/buffers.cpp
index f9893ed1e1c..3bbc205ca7a 100644
--- a/intern/cycles/session/buffers.cpp
+++ b/intern/cycles/session/buffers.cpp
@@ -49,6 +49,7 @@ NODE_DEFINE(BufferPass)
SOCKET_ENUM(mode, "Mode", *pass_mode_enum, static_cast<int>(PassMode::DENOISED));
SOCKET_STRING(name, "Name", ustring());
SOCKET_BOOLEAN(include_albedo, "Include Albedo", false);
+ SOCKET_STRING(lightgroup, "Light Group", ustring());
SOCKET_INT(offset, "Offset", -1);
@@ -64,13 +65,14 @@ BufferPass::BufferPass(const Pass *scene_pass)
type(scene_pass->get_type()),
mode(scene_pass->get_mode()),
name(scene_pass->get_name()),
- include_albedo(scene_pass->get_include_albedo())
+ include_albedo(scene_pass->get_include_albedo()),
+ lightgroup(scene_pass->get_lightgroup())
{
}
PassInfo BufferPass::get_info() const
{
- return Pass::get_info(type, include_albedo);
+ return Pass::get_info(type, include_albedo, !lightgroup.empty());
}
/* --------------------------------------------------------------------
diff --git a/intern/cycles/session/buffers.h b/intern/cycles/session/buffers.h
index 1c4ec81e427..a8278388a28 100644
--- a/intern/cycles/session/buffers.h
+++ b/intern/cycles/session/buffers.h
@@ -30,6 +30,7 @@ class BufferPass : public Node {
PassMode mode = PassMode::NOISY;
ustring name;
bool include_albedo = false;
+ ustring lightgroup;
int offset = -1;
@@ -49,7 +50,8 @@ class BufferPass : public Node {
inline bool operator==(const BufferPass &other) const
{
return type == other.type && mode == other.mode && name == other.name &&
- include_albedo == other.include_albedo && offset == other.offset;
+ include_albedo == other.include_albedo && lightgroup == other.lightgroup &&
+ offset == other.offset;
}
inline bool operator!=(const BufferPass &other) const
{
diff --git a/release/scripts/startup/bl_ui/properties_view_layer.py b/release/scripts/startup/bl_ui/properties_view_layer.py
index 4dee7b73faf..83e797583ad 100644
--- a/release/scripts/startup/bl_ui/properties_view_layer.py
+++ b/release/scripts/startup/bl_ui/properties_view_layer.py
@@ -187,6 +187,33 @@ class VIEWLAYER_PT_layer_passes_cryptomatte(ViewLayerCryptomattePanel, Panel):
COMPAT_ENGINES = {'BLENDER_EEVEE'}
+class ViewLayerLightgroupsPanel(ViewLayerButtonsPanel, Panel):
+ bl_label = "Light Groups"
+
+ def draw(self, context):
+ layout = self.layout
+
+ layout.use_property_split = True
+ layout.use_property_decorate = False
+
+ view_layer = context.view_layer
+
+ row = layout.row()
+ col = row.column()
+ col.template_list("UI_UL_list", "lightgroups", view_layer,
+ "lightgroups", view_layer, "active_lightgroup_index", rows=2)
+
+ col = row.column()
+ sub = col.column(align=True)
+ sub.operator("scene.view_layer_add_lightgroup", icon='ADD', text="")
+ sub.operator("scene.view_layer_remove_lightgroup", icon='REMOVE', text="")
+
+
+class VIEWLAYER_PT_layer_passes_lightgroups(ViewLayerLightgroupsPanel):
+ bl_parent_id = "VIEWLAYER_PT_layer_passes"
+ COMPAT_ENGINES = {'CYCLES'}
+
+
classes = (
VIEWLAYER_PT_layer,
VIEWLAYER_PT_layer_passes,
@@ -195,6 +222,7 @@ classes = (
VIEWLAYER_PT_eevee_layer_passes_effects,
VIEWLAYER_PT_layer_passes_cryptomatte,
VIEWLAYER_PT_layer_passes_aov,
+ VIEWLAYER_PT_layer_passes_lightgroups,
VIEWLAYER_UL_aov,
)
diff --git a/source/blender/blenkernel/BKE_layer.h b/source/blender/blenkernel/BKE_layer.h
index c877035830c..4a3917dafee 100644
--- a/source/blender/blenkernel/BKE_layer.h
+++ b/source/blender/blenkernel/BKE_layer.h
@@ -8,6 +8,7 @@
#include "BKE_collection.h"
+#include "DNA_layer_types.h"
#include "DNA_listBase.h"
#ifdef __cplusplus
@@ -581,6 +582,21 @@ bool BKE_view_layer_has_valid_aov(struct ViewLayer *view_layer);
struct ViewLayer *BKE_view_layer_find_with_aov(struct Scene *scene,
struct ViewLayerAOV *view_layer_aov);
+struct ViewLayerLightgroup *BKE_view_layer_add_lightgroup(struct ViewLayer *view_layer);
+void BKE_view_layer_remove_lightgroup(struct ViewLayer *view_layer,
+ struct ViewLayerLightgroup *lightgroup);
+void BKE_view_layer_set_active_lightgroup(struct ViewLayer *view_layer,
+ struct ViewLayerLightgroup *lightgroup);
+struct ViewLayer *BKE_view_layer_find_with_lightgroup(
+ struct Scene *scene, struct ViewLayerLightgroup *view_layer_lightgroup);
+void BKE_view_layer_rename_lightgroup(ViewLayer *view_layer,
+ ViewLayerLightgroup *lightgroup,
+ const char *name);
+
+void BKE_lightgroup_membership_get(struct LightgroupMembership *lgm, char *value);
+int BKE_lightgroup_membership_length(struct LightgroupMembership *lgm);
+void BKE_lightgroup_membership_set(struct LightgroupMembership **lgm, const char *value);
+
#ifdef __cplusplus
}
#endif
diff --git a/source/blender/blenkernel/intern/layer.c b/source/blender/blenkernel/intern/layer.c
index ccff4dbed03..c99bf885074 100644
--- a/source/blender/blenkernel/intern/layer.c
+++ b/source/blender/blenkernel/intern/layer.c
@@ -266,6 +266,8 @@ void BKE_view_layer_free_ex(ViewLayer *view_layer, const bool do_id_user)
BLI_freelistN(&view_layer->drawdata);
BLI_freelistN(&view_layer->aovs);
view_layer->active_aov = NULL;
+ BLI_freelistN(&view_layer->lightgroups);
+ view_layer->active_lightgroup = NULL;
MEM_SAFE_FREE(view_layer->stats);
@@ -428,6 +430,29 @@ static void layer_aov_copy_data(ViewLayer *view_layer_dst,
}
}
+static void layer_lightgroup_copy_data(ViewLayer *view_layer_dst,
+ const ViewLayer *view_layer_src,
+ ListBase *lightgroups_dst,
+ const ListBase *lightgroups_src)
+{
+ if (lightgroups_src != NULL) {
+ BLI_duplicatelist(lightgroups_dst, lightgroups_src);
+ }
+
+ ViewLayerLightgroup *lightgroup_dst = lightgroups_dst->first;
+ const ViewLayerLightgroup *lightgroup_src = lightgroups_src->first;
+
+ while (lightgroup_dst != NULL) {
+ BLI_assert(lightgroup_src);
+ if (lightgroup_src == view_layer_src->active_lightgroup) {
+ view_layer_dst->active_lightgroup = lightgroup_dst;
+ }
+
+ lightgroup_dst = lightgroup_dst->next;
+ lightgroup_src = lightgroup_src->next;
+ }
+}
+
static void layer_collections_copy_data(ViewLayer *view_layer_dst,
const ViewLayer *view_layer_src,
ListBase *layer_collections_dst,
@@ -496,6 +521,10 @@ void BKE_view_layer_copy_data(Scene *scene_dst,
layer_aov_copy_data(
view_layer_dst, view_layer_src, &view_layer_dst->aovs, &view_layer_src->aovs);
+ BLI_listbase_clear(&view_layer_dst->lightgroups);
+ layer_lightgroup_copy_data(
+ view_layer_dst, view_layer_src, &view_layer_dst->lightgroups, &view_layer_src->lightgroups);
+
if ((flag & LIB_ID_CREATE_NO_USER_REFCOUNT) == 0) {
id_us_plus((ID *)view_layer_dst->mat_override);
}
@@ -2256,6 +2285,9 @@ void BKE_view_layer_blend_write(BlendWriter *writer, ViewLayer *view_layer)
LISTBASE_FOREACH (ViewLayerAOV *, aov, &view_layer->aovs) {
BLO_write_struct(writer, ViewLayerAOV, aov);
}
+ LISTBASE_FOREACH (ViewLayerLightgroup *, lightgroup, &view_layer->lightgroups) {
+ BLO_write_struct(writer, ViewLayerLightgroup, lightgroup);
+ }
write_layer_collections(writer, &view_layer->layer_collections);
}
@@ -2294,6 +2326,9 @@ void BKE_view_layer_blend_read_data(BlendDataReader *reader, ViewLayer *view_lay
BLO_read_list(reader, &view_layer->aovs);
BLO_read_data_address(reader, &view_layer->active_aov);
+ BLO_read_list(reader, &view_layer->lightgroups);
+ BLO_read_data_address(reader, &view_layer->active_lightgroup);
+
BLI_listbase_clear(&view_layer->drawdata);
view_layer->object_bases_array = NULL;
view_layer->object_bases_hash = NULL;
@@ -2471,4 +2506,117 @@ ViewLayer *BKE_view_layer_find_with_aov(struct Scene *scene, struct ViewLayerAOV
return NULL;
}
+/* -------------------------------------------------------------------- */
+/** \name Light Groups
+ * \{ */
+
+static void viewlayer_lightgroup_make_name_unique(ViewLayer *view_layer,
+ ViewLayerLightgroup *lightgroup)
+{
+ /* Don't allow dots, it's incompatible with OpenEXR convention to store channels
+ * as "layer.pass.channel". */
+ BLI_str_replace_char(lightgroup->name, '.', '_');
+ BLI_uniquename(&view_layer->lightgroups,
+ lightgroup,
+ DATA_("Lightgroup"),
+ '_',
+ offsetof(ViewLayerLightgroup, name),
+ sizeof(lightgroup->name));
+}
+
+static void viewlayer_lightgroup_active_set(ViewLayer *view_layer, ViewLayerLightgroup *lightgroup)
+{
+ if (lightgroup != NULL) {
+ BLI_assert(BLI_findindex(&view_layer->lightgroups, lightgroup) != -1);
+ view_layer->active_lightgroup = lightgroup;
+ }
+ else {
+ view_layer->active_lightgroup = NULL;
+ }
+}
+
+struct ViewLayerLightgroup *BKE_view_layer_add_lightgroup(struct ViewLayer *view_layer)
+{
+ ViewLayerLightgroup *lightgroup;
+ lightgroup = MEM_callocN(sizeof(ViewLayerLightgroup), __func__);
+ BLI_strncpy(lightgroup->name, DATA_("Lightgroup"), sizeof(lightgroup->name));
+ BLI_addtail(&view_layer->lightgroups, lightgroup);
+ viewlayer_lightgroup_active_set(view_layer, lightgroup);
+ viewlayer_lightgroup_make_name_unique(view_layer, lightgroup);
+ return lightgroup;
+}
+
+void BKE_view_layer_remove_lightgroup(ViewLayer *view_layer, ViewLayerLightgroup *lightgroup)
+{
+ BLI_assert(BLI_findindex(&view_layer->lightgroups, lightgroup) != -1);
+ BLI_assert(lightgroup != NULL);
+ if (view_layer->active_lightgroup == lightgroup) {
+ if (lightgroup->next) {
+ viewlayer_lightgroup_active_set(view_layer, lightgroup->next);
+ }
+ else {
+ viewlayer_lightgroup_active_set(view_layer, lightgroup->prev);
+ }
+ }
+ BLI_freelinkN(&view_layer->lightgroups, lightgroup);
+}
+
+void BKE_view_layer_set_active_lightgroup(ViewLayer *view_layer, ViewLayerLightgroup *lightgroup)
+{
+ viewlayer_lightgroup_active_set(view_layer, lightgroup);
+}
+
+ViewLayer *BKE_view_layer_find_with_lightgroup(struct Scene *scene,
+ struct ViewLayerLightgroup *lightgroup)
+{
+ LISTBASE_FOREACH (ViewLayer *, view_layer, &scene->view_layers) {
+ if (BLI_findindex(&view_layer->lightgroups, lightgroup) != -1) {
+ return view_layer;
+ }
+ }
+ return NULL;
+}
+
+void BKE_view_layer_rename_lightgroup(ViewLayer *view_layer,
+ ViewLayerLightgroup *lightgroup,
+ const char *name)
+{
+ BLI_strncpy_utf8(lightgroup->name, name, sizeof(lightgroup->name));
+ viewlayer_lightgroup_make_name_unique(view_layer, lightgroup);
+}
+
+void BKE_lightgroup_membership_get(struct LightgroupMembership *lgm, char *name)
+{
+ if (lgm != NULL) {
+ BLI_strncpy(name, lgm->name, sizeof(lgm->name));
+ }
+ else {
+ name[0] = '\0';
+ }
+}
+
+int BKE_lightgroup_membership_length(struct LightgroupMembership *lgm)
+{
+ if (lgm != NULL) {
+ return strlen(lgm->name);
+ }
+ return 0;
+}
+
+void BKE_lightgroup_membership_set(struct LightgroupMembership **lgm, const char *name)
+{
+ if (name[0] != '\0') {
+ if (*lgm == NULL) {
+ *lgm = MEM_callocN(sizeof(LightgroupMembership), __func__);
+ }
+ BLI_strncpy((*lgm)->name, name, sizeof((*lgm)->name));
+ }
+ else {
+ if (*lgm != NULL) {
+ MEM_freeN(*lgm);
+ *lgm = NULL;
+ }
+ }
+}
+
/** \} */
diff --git a/source/blender/blenkernel/intern/object.cc b/source/blender/blenkernel/intern/object.cc
index c00a403d5e9..833e6f882f1 100644
--- a/source/blender/blenkernel/intern/object.cc
+++ b/source/blender/blenkernel/intern/object.cc
@@ -260,6 +260,10 @@ static void object_copy_data(Main *bmain, ID *id_dst, const ID *id_src, const in
else {
ob_dst->preview = nullptr;
}
+
+ if (ob_src->lightgroup) {
+ ob_dst->lightgroup = (LightgroupMembership *)MEM_dupallocN(ob_src->lightgroup);
+ }
}
static void object_free_data(ID *id)
@@ -310,6 +314,8 @@ static void object_free_data(ID *id)
}
BKE_previewimg_free(&ob->preview);
+
+ MEM_SAFE_FREE(ob->lightgroup);
}
static void library_foreach_modifiersForeachIDLink(void *user_data,
@@ -584,6 +590,10 @@ static void object_blend_write(BlendWriter *writer, ID *id, const void *id_addre
BLO_write_struct_list(writer, LinkData, &ob->pc_ids);
BKE_previewimg_blend_write(writer, ob->preview);
+
+ if (ob->lightgroup) {
+ BLO_write_struct(writer, LightgroupMembership, ob->lightgroup);
+ }
}
/* XXX deprecated - old animation system */
@@ -800,6 +810,8 @@ static void object_blend_read_data(BlendDataReader *reader, ID *id)
BLO_read_data_address(reader, &ob->preview);
BKE_previewimg_blend_read(reader, ob->preview);
+
+ BLO_read_data_address(reader, &ob->lightgroup);
}
/* XXX deprecated - old animation system */
diff --git a/source/blender/blenkernel/intern/world.c b/source/blender/blenkernel/intern/world.c
index ac8b18f3395..cc3ee06f539 100644
--- a/source/blender/blenkernel/intern/world.c
+++ b/source/blender/blenkernel/intern/world.c
@@ -59,6 +59,8 @@ static void world_free_data(ID *id)
BKE_icon_id_delete((struct ID *)wrld);
BKE_previewimg_free(&wrld->preview);
+
+ MEM_SAFE_FREE(wrld->lightgroup);
}
static void world_init_data(ID *id)
@@ -107,6 +109,10 @@ static void world_copy_data(Main *bmain, ID *id_dst, const ID *id_src, const int
else {
wrld_dst->preview = NULL;
}
+
+ if (wrld_src->lightgroup) {
+ wrld_dst->lightgroup = (LightgroupMembership *)MEM_dupallocN(wrld_src->lightgroup);
+ }
}
static void world_foreach_id(ID *id, LibraryForeachIDData *data)
@@ -142,6 +148,10 @@ static void world_blend_write(BlendWriter *writer, ID *id, const void *id_addres
}
BKE_previewimg_blend_write(writer, wrld->preview);
+
+ if (wrld->lightgroup) {
+ BLO_write_struct(writer, LightgroupMembership, wrld->lightgroup);
+ }
}
static void world_blend_read_data(BlendDataReader *reader, ID *id)
@@ -153,6 +163,8 @@ static void world_blend_read_data(BlendDataReader *reader, ID *id)
BLO_read_data_address(reader, &wrld->preview);
BKE_previewimg_blend_read(reader, wrld->preview);
BLI_listbase_clear(&wrld->gpumaterial);
+
+ BLO_read_data_address(reader, &wrld->lightgroup);
}
static void world_blend_read_lib(BlendLibReader *reader, ID *id)
diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h
index 74797f91046..a4508cb5b6d 100644
--- a/source/blender/editors/include/UI_interface.h
+++ b/source/blender/editors/include/UI_interface.h
@@ -634,7 +634,7 @@ uiPopupMenu *UI_popup_menu_begin_ex(struct bContext *C,
* Set the whole structure to work.
*/
void UI_popup_menu_end(struct bContext *C, struct uiPopupMenu *pup);
-bool UI_popup_menu_end_or_cancel(struct bContext *C, struct uiPopupMenu *head);
+bool UI_popup_menu_end_or_cancel(struct bContext *C, struct uiPopupMenu *pup);
struct uiLayout *UI_popup_menu_layout(uiPopupMenu *pup);
void UI_popup_menu_reports(struct bContext *C, struct ReportList *reports) ATTR_NONNULL();
@@ -1595,13 +1595,15 @@ typedef enum {
} eButLabelAlign;
/* Return info for uiDefAutoButsRNA */
-typedef enum {
+typedef enum eAutoPropButsReturn {
/* Returns when no buttons were added */
UI_PROP_BUTS_NONE_ADDED = 1 << 0,
/* Returned when any property failed the custom check callback (check_prop) */
UI_PROP_BUTS_ANY_FAILED_CHECK = 1 << 1,
} eAutoPropButsReturn;
+ENUM_OPERATORS(eAutoPropButsReturn, UI_PROP_BUTS_ANY_FAILED_CHECK);
+
uiBut *uiDefAutoButR(uiBlock *block,
struct PointerRNA *ptr,
struct PropertyRNA *prop,
diff --git a/source/blender/editors/interface/CMakeLists.txt b/source/blender/editors/interface/CMakeLists.txt
index 100be2c10c9..a1ee5c38838 100644
--- a/source/blender/editors/interface/CMakeLists.txt
+++ b/source/blender/editors/interface/CMakeLists.txt
@@ -46,17 +46,17 @@ set(SRC
interface_layout.c
interface_ops.c
interface_panel.c
- interface_query.c
- interface_region_color_picker.c
- interface_region_hud.c
- interface_region_menu_pie.c
- interface_region_menu_popup.c
- interface_region_popover.c
- interface_region_popup.c
+ interface_query.cc
+ interface_region_color_picker.cc
+ interface_region_hud.cc
+ interface_region_menu_pie.cc
+ interface_region_menu_popup.cc
+ interface_region_popover.cc
+ interface_region_popup.cc
interface_region_search.cc
interface_region_tooltip.c
- interface_regions.c
- interface_style.c
+ interface_regions.cc
+ interface_style.cc
interface_template_asset_view.cc
interface_template_attribute_search.cc
interface_template_list.cc
@@ -64,7 +64,7 @@ set(SRC
interface_template_search_operator.c
interface_templates.c
interface_undo.c
- interface_utils.c
+ interface_utils.cc
interface_view.cc
interface_widgets.c
resources.c
diff --git a/source/blender/editors/interface/interface_intern.h b/source/blender/editors/interface/interface_intern.h
index a7a2409ef17..e619b14fb69 100644
--- a/source/blender/editors/interface/interface_intern.h
+++ b/source/blender/editors/interface/interface_intern.h
@@ -214,8 +214,8 @@ struct uiBut {
BIFIconID icon;
/** Copied from the #uiBlock.emboss */
eUIEmbossType emboss;
- /** direction in a pie menu, used for collision detection (RadialDirection) */
- signed char pie_dir;
+ /** direction in a pie menu, used for collision detection. */
+ RadialDirection pie_dir;
/** could be made into a single flag */
bool changed;
/** so buttons can support unit systems which are not RNA */
@@ -954,7 +954,7 @@ void ui_pie_menu_level_create(uiBlock *block,
const EnumPropertyItem *items,
int totitem,
wmOperatorCallContext context,
- int flag);
+ wmOperatorCallContext flag);
/* interface_region_popup.c */
diff --git a/source/blender/editors/interface/interface_query.c b/source/blender/editors/interface/interface_query.cc
index 4703367671d..2767a184619 100644
--- a/source/blender/editors/interface/interface_query.c
+++ b/source/blender/editors/interface/interface_query.cc
@@ -61,7 +61,7 @@ bool ui_but_is_toggle(const uiBut *but)
bool ui_but_is_interactive(const uiBut *but, const bool labeledit)
{
/* NOTE: #UI_BTYPE_LABEL is included for highlights, this allows drags. */
- if ((but->type == UI_BTYPE_LABEL) && but->dragpoin == NULL) {
+ if ((but->type == UI_BTYPE_LABEL) && but->dragpoin == nullptr) {
return false;
}
if (ELEM(but->type, UI_BTYPE_ROUNDBOX, UI_BTYPE_SEPR, UI_BTYPE_SEPR_LINE, UI_BTYPE_LISTBOX)) {
@@ -119,12 +119,12 @@ bool ui_but_has_array_value(const uiBut *but)
PROP_COORDS));
}
-static wmOperatorType *g_ot_tool_set_by_id = NULL;
+static wmOperatorType *g_ot_tool_set_by_id = nullptr;
bool UI_but_is_tool(const uiBut *but)
{
/* very evil! */
- if (but->optype != NULL) {
- if (g_ot_tool_set_by_id == NULL) {
+ if (but->optype != nullptr) {
+ if (g_ot_tool_set_by_id == nullptr) {
g_ot_tool_set_by_id = WM_operatortype_find("WM_OT_tool_set_by_id", false);
}
if (but->optype == g_ot_tool_set_by_id) {
@@ -198,7 +198,7 @@ bool ui_but_contains_pt(const uiBut *but, float mx, float my)
bool ui_but_contains_rect(const uiBut *but, const rctf *rect)
{
- return BLI_rctf_isect(&but->rect, rect, NULL);
+ return BLI_rctf_isect(&but->rect, rect, nullptr);
}
bool ui_but_contains_point_px(const uiBut *but, const ARegion *region, const int xy[2])
@@ -260,7 +260,7 @@ static uiBut *ui_but_find(const ARegion *region,
}
}
- return NULL;
+ return nullptr;
}
uiBut *ui_but_find_mouse_over_ex(const ARegion *region,
@@ -269,10 +269,10 @@ uiBut *ui_but_find_mouse_over_ex(const ARegion *region,
const uiButFindPollFn find_poll,
const void *find_custom_data)
{
- uiBut *butover = NULL;
+ uiBut *butover = nullptr;
if (!ui_region_contains_point_px(region, xy)) {
- return NULL;
+ return nullptr;
}
LISTBASE_FOREACH (uiBlock *, block, &region->uiblocks) {
float mx = xy[0], my = xy[1];
@@ -310,20 +310,20 @@ uiBut *ui_but_find_mouse_over_ex(const ARegion *region,
uiBut *ui_but_find_mouse_over(const ARegion *region, const wmEvent *event)
{
- return ui_but_find_mouse_over_ex(region, event->xy, event->modifier & KM_CTRL, NULL, NULL);
+ return ui_but_find_mouse_over_ex(region, event->xy, event->modifier & KM_CTRL, nullptr, nullptr);
}
uiBut *ui_but_find_rect_over(const struct ARegion *region, const rcti *rect_px)
{
if (!ui_region_contains_rect_px(region, rect_px)) {
- return NULL;
+ return nullptr;
}
/* Currently no need to expose this at the moment. */
const bool labeledit = true;
rctf rect_px_fl;
BLI_rctf_rcti_copy(&rect_px_fl, rect_px);
- uiBut *butover = NULL;
+ uiBut *butover = nullptr;
LISTBASE_FOREACH (uiBlock *, block, &region->uiblocks) {
rctf rect_block;
@@ -343,7 +343,7 @@ uiBut *ui_but_find_rect_over(const struct ARegion *region, const rcti *rect_px)
/* CLIP_EVENTS prevents the event from reaching other blocks */
if (block->flag & UI_BLOCK_CLIP_EVENTS) {
/* check if mouse is inside block */
- if (BLI_rctf_isect(&block->rect, &rect_block, NULL)) {
+ if (BLI_rctf_isect(&block->rect, &rect_block, nullptr)) {
break;
}
}
@@ -354,7 +354,7 @@ uiBut *ui_but_find_rect_over(const struct ARegion *region, const rcti *rect_px)
uiBut *ui_list_find_mouse_over_ex(const ARegion *region, const int xy[2])
{
if (!ui_region_contains_point_px(region, xy)) {
- return NULL;
+ return nullptr;
}
LISTBASE_FOREACH (uiBlock *, block, &region->uiblocks) {
float mx = xy[0], my = xy[1];
@@ -366,14 +366,14 @@ uiBut *ui_list_find_mouse_over_ex(const ARegion *region, const int xy[2])
}
}
- return NULL;
+ return nullptr;
}
uiBut *ui_list_find_mouse_over(const ARegion *region, const wmEvent *event)
{
- if (event == NULL) {
+ if (event == nullptr) {
/* If there is no info about the mouse, just act as if there is nothing underneath it. */
- return NULL;
+ return nullptr;
}
return ui_list_find_mouse_over_ex(region, event->xy);
}
@@ -382,10 +382,10 @@ uiList *UI_list_find_mouse_over(const ARegion *region, const wmEvent *event)
{
uiBut *list_but = ui_list_find_mouse_over(region, event);
if (!list_but) {
- return NULL;
+ return nullptr;
}
- return list_but->custom_data;
+ return static_cast<uiList *>(list_but->custom_data);
}
static bool ui_list_contains_row(const uiBut *listbox_but, const uiBut *listrow_but)
@@ -398,7 +398,7 @@ static bool ui_list_contains_row(const uiBut *listbox_but, const uiBut *listrow_
static bool ui_but_is_listbox_with_row(const uiBut *but, const void *customdata)
{
- const uiBut *row_but = customdata;
+ const uiBut *row_but = static_cast<const uiBut *>(customdata);
return (but->type == UI_BTYPE_LISTBOX) && ui_list_contains_row(but, row_but);
}
@@ -414,7 +414,7 @@ static bool ui_but_is_listrow(const uiBut *but, const void *UNUSED(customdata))
uiBut *ui_list_row_find_mouse_over(const ARegion *region, const int xy[2])
{
- return ui_but_find_mouse_over_ex(region, xy, false, ui_but_is_listrow, NULL);
+ return ui_but_find_mouse_over_ex(region, xy, false, ui_but_is_listrow, nullptr);
}
struct ListRowFindIndexData {
@@ -424,19 +424,18 @@ struct ListRowFindIndexData {
static bool ui_but_is_listrow_at_index(const uiBut *but, const void *customdata)
{
- const struct ListRowFindIndexData *find_data = customdata;
+ const ListRowFindIndexData *find_data = static_cast<const ListRowFindIndexData *>(customdata);
- return ui_but_is_listrow(but, NULL) && ui_list_contains_row(find_data->listbox, but) &&
+ return ui_but_is_listrow(but, nullptr) && ui_list_contains_row(find_data->listbox, but) &&
(but->hardmax == find_data->index);
}
uiBut *ui_list_row_find_from_index(const ARegion *region, const int index, uiBut *listbox)
{
BLI_assert(listbox->type == UI_BTYPE_LISTBOX);
- struct ListRowFindIndexData data = {
- .index = index,
- .listbox = listbox,
- };
+ ListRowFindIndexData data = {};
+ data.index = index;
+ data.listbox = listbox;
return ui_but_find(region, ui_but_is_listrow_at_index, &data);
}
@@ -447,7 +446,7 @@ static bool ui_but_is_treerow(const uiBut *but, const void *UNUSED(customdata))
uiBut *ui_tree_row_find_mouse_over(const ARegion *region, const int xy[2])
{
- return ui_but_find_mouse_over_ex(region, xy, false, ui_but_is_treerow, NULL);
+ return ui_but_find_mouse_over_ex(region, xy, false, ui_but_is_treerow, nullptr);
}
static bool ui_but_is_active_treerow(const uiBut *but, const void *customdata)
@@ -462,7 +461,7 @@ static bool ui_but_is_active_treerow(const uiBut *but, const void *customdata)
uiBut *ui_tree_row_find_active(const ARegion *region)
{
- return ui_but_find(region, ui_but_is_active_treerow, NULL);
+ return ui_but_find(region, ui_but_is_active_treerow, nullptr);
}
/** \} */
@@ -479,7 +478,7 @@ uiBut *ui_but_prev(uiBut *but)
return but;
}
}
- return NULL;
+ return nullptr;
}
uiBut *ui_but_next(uiBut *but)
@@ -490,7 +489,7 @@ uiBut *ui_but_next(uiBut *but)
return but;
}
}
- return NULL;
+ return nullptr;
}
uiBut *ui_but_first(uiBlock *block)
@@ -500,21 +499,19 @@ uiBut *ui_but_first(uiBlock *block)
return but;
}
}
- return NULL;
+ return nullptr;
}
uiBut *ui_but_last(uiBlock *block)
{
- uiBut *but;
-
- but = block->buttons.last;
+ uiBut *but = static_cast<uiBut *>(block->buttons.last);
while (but) {
if (ui_but_is_editable(but)) {
return but;
}
but = but->prev;
}
- return NULL;
+ return nullptr;
}
bool ui_but_is_cursor_warp(const uiBut *but)
@@ -550,7 +547,7 @@ size_t ui_but_drawstr_len_without_sep_char(const uiBut *but)
{
if (but->flag & UI_BUT_HAS_SEP_CHAR) {
const char *str_sep = strrchr(but->drawstr, UI_SEP_CHAR);
- if (str_sep != NULL) {
+ if (str_sep != nullptr) {
return (str_sep - but->drawstr);
}
}
@@ -565,12 +562,12 @@ size_t ui_but_drawstr_without_sep_char(const uiBut *but, char *str, size_t str_m
size_t ui_but_tip_len_only_first_line(const uiBut *but)
{
- if (but->tip == NULL) {
+ if (but->tip == nullptr) {
return 0;
}
const char *str_sep = strchr(but->tip, '\n');
- if (str_sep != NULL) {
+ if (str_sep != nullptr) {
return (str_sep - but->tip);
}
return strlen(but->tip);
@@ -590,7 +587,7 @@ uiBut *ui_block_active_but_get(const uiBlock *block)
}
}
- return NULL;
+ return nullptr;
}
bool ui_block_is_menu(const uiBlock *block)
@@ -622,12 +619,12 @@ static const uiBut *ui_but_next_non_separator(const uiBut *but)
return but;
}
}
- return NULL;
+ return nullptr;
}
bool UI_block_is_empty_ex(const uiBlock *block, const bool skip_title)
{
- const uiBut *but = block->buttons.first;
+ const uiBut *but = static_cast<const uiBut *>(block->buttons.first);
if (skip_title) {
/* Skip the first label, since popups often have a title,
* we may want to consider the block empty in this case. */
@@ -636,7 +633,7 @@ bool UI_block_is_empty_ex(const uiBlock *block, const bool skip_title)
but = but->next;
}
}
- return (ui_but_next_non_separator(but) == NULL);
+ return (ui_but_next_non_separator(but) == nullptr);
}
bool UI_block_is_empty(const uiBlock *block)
@@ -647,7 +644,7 @@ bool UI_block_is_empty(const uiBlock *block)
bool UI_block_can_add_separator(const uiBlock *block)
{
if (ui_block_is_menu(block) && !ui_block_is_pie_menu(block)) {
- const uiBut *but = block->buttons.last;
+ const uiBut *but = static_cast<const uiBut *>(block->buttons.last);
return (but && !ELEM(but->type, UI_BTYPE_SEPR_LINE, UI_BTYPE_SEPR));
}
return true;
@@ -662,7 +659,7 @@ bool UI_block_can_add_separator(const uiBlock *block)
uiBlock *ui_block_find_mouse_over_ex(const ARegion *region, const int xy[2], bool only_clip)
{
if (!ui_region_contains_point_px(region, xy)) {
- return NULL;
+ return nullptr;
}
LISTBASE_FOREACH (uiBlock *, block, &region->uiblocks) {
if (only_clip) {
@@ -676,7 +673,7 @@ uiBlock *ui_block_find_mouse_over_ex(const ARegion *region, const int xy[2], boo
return block;
}
}
- return NULL;
+ return nullptr;
}
uiBlock *ui_block_find_mouse_over(const ARegion *region, const wmEvent *event, bool only_clip)
@@ -699,7 +696,7 @@ uiBut *ui_region_find_active_but(ARegion *region)
}
}
- return NULL;
+ return nullptr;
}
uiBut *ui_region_find_first_but_test_flag(ARegion *region, int flag_include, int flag_exclude)
@@ -712,7 +709,7 @@ uiBut *ui_region_find_first_but_test_flag(ARegion *region, int flag_include, int
}
}
- return NULL;
+ return nullptr;
}
/** \} */
@@ -752,7 +749,7 @@ bool ui_region_contains_rect_px(const ARegion *region, const rcti *rect_px)
{
rcti winrct;
ui_region_winrct_get_no_margin(region, &winrct);
- if (!BLI_rcti_isect(&winrct, rect_px, NULL)) {
+ if (!BLI_rcti_isect(&winrct, rect_px, nullptr)) {
return false;
}
@@ -761,7 +758,7 @@ bool ui_region_contains_rect_px(const ARegion *region, const rcti *rect_px)
const View2D *v2d = &region->v2d;
rcti rect_region;
ui_window_to_region_rcti(region, &rect_region, rect_px);
- if (!BLI_rcti_isect(&v2d->mask, &rect_region, NULL) ||
+ if (!BLI_rcti_isect(&v2d->mask, &rect_region, nullptr) ||
UI_view2d_rect_in_scrollers(region, &region->v2d, rect_px)) {
return false;
}
@@ -787,7 +784,7 @@ ARegion *ui_screen_region_find_mouse_over_ex(bScreen *screen, const int xy[2])
return region;
}
}
- return NULL;
+ return nullptr;
}
ARegion *ui_screen_region_find_mouse_over(bScreen *screen, const wmEvent *event)
@@ -803,7 +800,7 @@ ARegion *ui_screen_region_find_mouse_over(bScreen *screen, const wmEvent *event)
void ui_interface_tag_script_reload_queries(void)
{
- g_ot_tool_set_by_id = NULL;
+ g_ot_tool_set_by_id = nullptr;
}
/** \} */
diff --git a/source/blender/editors/interface/interface_region_color_picker.c b/source/blender/editors/interface/interface_region_color_picker.cc
index 9fb6f538191..ab0a6039cdc 100644
--- a/source/blender/editors/interface/interface_region_color_picker.c
+++ b/source/blender/editors/interface/interface_region_color_picker.cc
@@ -7,9 +7,9 @@
* Color Picker Region & Color Utils
*/
-#include <stdarg.h>
-#include <stdlib.h>
-#include <string.h>
+#include <cstdarg>
+#include <cstdlib>
+#include <cstring>
#include "MEM_guardedalloc.h"
@@ -168,7 +168,7 @@ static void ui_color_picker_update_hsv(ColorPicker *cpicker,
void ui_but_hsv_set(uiBut *but)
{
float rgb_perceptual[3];
- ColorPicker *cpicker = but->custom_data;
+ ColorPicker *cpicker = static_cast<ColorPicker *>(but->custom_data);
float *hsv_perceptual = cpicker->hsv_perceptual;
ui_color_picker_hsv_to_rgb(hsv_perceptual, rgb_perceptual);
@@ -255,7 +255,8 @@ static void ui_colorpicker_rgba_update_cb(bContext *UNUSED(C), void *bt1, void *
if (prop) {
RNA_property_float_get_array(&ptr, prop, rgb_scene_linear);
- ui_update_color_picker_buts_rgb(but, but->block, but->custom_data, rgb_scene_linear);
+ ui_update_color_picker_buts_rgb(
+ but, but->block, static_cast<ColorPicker *>(but->custom_data), rgb_scene_linear);
}
if (popup) {
@@ -268,7 +269,7 @@ static void ui_colorpicker_hsv_update_cb(bContext *UNUSED(C), void *bt1, void *U
uiBut *but = (uiBut *)bt1;
uiPopupBlockHandle *popup = but->block->handle;
float rgb_scene_linear[3];
- ColorPicker *cpicker = but->custom_data;
+ ColorPicker *cpicker = static_cast<ColorPicker *>(but->custom_data);
ui_color_picker_hsv_to_rgb(cpicker->hsv_scene_linear, rgb_scene_linear);
ui_update_color_picker_buts_rgb(but, but->block, cpicker, rgb_scene_linear);
@@ -282,7 +283,7 @@ static void ui_colorpicker_hex_rna_cb(bContext *UNUSED(C), void *bt1, void *hexc
{
uiBut *but = (uiBut *)bt1;
uiPopupBlockHandle *popup = but->block->handle;
- ColorPicker *cpicker = but->custom_data;
+ ColorPicker *cpicker = static_cast<ColorPicker *>(but->custom_data);
char *hexcol = (char *)hexcl;
float rgb[3];
@@ -307,7 +308,7 @@ static void ui_popup_close_cb(bContext *UNUSED(C), void *bt1, void *UNUSED(arg))
uiPopupBlockHandle *popup = but->block->handle;
if (popup) {
- ColorPicker *cpicker = but->custom_data;
+ ColorPicker *cpicker = static_cast<ColorPicker *>(but->custom_data);
BLI_assert(cpicker->is_init);
popup->menuretval = (equals_v3v3(cpicker->hsv_perceptual, cpicker->hsv_perceptual_init) ?
UI_RETURN_CANCEL :
@@ -315,7 +316,7 @@ static void ui_popup_close_cb(bContext *UNUSED(C), void *bt1, void *UNUSED(arg))
}
}
-static void ui_colorpicker_hide_reveal(uiBlock *block, enum ePickerType colormode)
+static void ui_colorpicker_hide_reveal(uiBlock *block, ePickerType colormode)
{
/* tag buttons */
LISTBASE_FOREACH (uiBut *, bt, &block->buttons) {
@@ -337,9 +338,9 @@ static void ui_colorpicker_hide_reveal(uiBlock *block, enum ePickerType colormod
static void ui_colorpicker_create_mode_cb(bContext *UNUSED(C), void *bt1, void *UNUSED(arg))
{
- uiBut *bt = bt1;
+ uiBut *bt = static_cast<uiBut *>(bt1);
const short colormode = ui_but_value_get(bt);
- ui_colorpicker_hide_reveal(bt->block, colormode);
+ ui_colorpicker_hide_reveal(bt->block, (ePickerType)colormode);
}
#define PICKER_H (7.5f * U.widget_unit)
@@ -374,7 +375,7 @@ static void ui_colorpicker_circle(uiBlock *block,
0.0,
0,
TIP_("Color"));
- UI_but_func_set(bt, ui_colorpicker_rgba_update_cb, bt, NULL);
+ UI_but_func_set(bt, ui_colorpicker_rgba_update_cb, bt, nullptr);
bt->custom_data = cpicker;
/* value */
@@ -396,7 +397,7 @@ static void ui_colorpicker_circle(uiBlock *block,
0,
"Lightness");
hsv_but->gradient_type = UI_GRAD_L_ALT;
- UI_but_func_set(&hsv_but->but, ui_colorpicker_rgba_update_cb, &hsv_but->but, NULL);
+ UI_but_func_set(&hsv_but->but, ui_colorpicker_rgba_update_cb, &hsv_but->but, nullptr);
}
else {
hsv_but = (uiButHSVCube *)uiDefButR_prop(block,
@@ -416,7 +417,7 @@ static void ui_colorpicker_circle(uiBlock *block,
0,
TIP_("Value"));
hsv_but->gradient_type = UI_GRAD_V_ALT;
- UI_but_func_set(&hsv_but->but, ui_colorpicker_rgba_update_cb, &hsv_but->but, NULL);
+ UI_but_func_set(&hsv_but->but, ui_colorpicker_rgba_update_cb, &hsv_but->but, nullptr);
}
hsv_but->but.custom_data = cpicker;
}
@@ -449,7 +450,7 @@ static void ui_colorpicker_square(uiBlock *block,
0,
TIP_("Color"));
hsv_but->gradient_type = type;
- UI_but_func_set(&hsv_but->but, ui_colorpicker_rgba_update_cb, &hsv_but->but, NULL);
+ UI_but_func_set(&hsv_but->but, ui_colorpicker_rgba_update_cb, &hsv_but->but, nullptr);
hsv_but->but.custom_data = cpicker;
/* value */
@@ -469,8 +470,8 @@ static void ui_colorpicker_square(uiBlock *block,
0,
0,
TIP_("Value"));
- hsv_but->gradient_type = type + 3;
- UI_but_func_set(&hsv_but->but, ui_colorpicker_rgba_update_cb, &hsv_but->but, NULL);
+ hsv_but->gradient_type = (eButGradientType)(type + 3);
+ UI_but_func_set(&hsv_but->but, ui_colorpicker_rgba_update_cb, &hsv_but->but, nullptr);
hsv_but->but.custom_data = cpicker;
}
@@ -547,7 +548,7 @@ static void ui_block_colorpicker(uiBlock *block,
"");
UI_but_flag_disable(bt, UI_BUT_UNDO);
UI_but_drawflag_disable(bt, UI_BUT_TEXT_LEFT);
- UI_but_func_set(bt, ui_colorpicker_create_mode_cb, bt, NULL);
+ UI_but_func_set(bt, ui_colorpicker_create_mode_cb, bt, nullptr);
bt->custom_data = cpicker;
bt = uiDefButC(block,
UI_BTYPE_ROW,
@@ -565,7 +566,7 @@ static void ui_block_colorpicker(uiBlock *block,
"");
UI_but_flag_disable(bt, UI_BUT_UNDO);
UI_but_drawflag_disable(bt, UI_BUT_TEXT_LEFT);
- UI_but_func_set(bt, ui_colorpicker_create_mode_cb, bt, NULL);
+ UI_but_func_set(bt, ui_colorpicker_create_mode_cb, bt, nullptr);
bt->custom_data = cpicker;
bt = uiDefButC(block,
UI_BTYPE_ROW,
@@ -583,7 +584,7 @@ static void ui_block_colorpicker(uiBlock *block,
"");
UI_but_flag_disable(bt, UI_BUT_UNDO);
UI_but_drawflag_disable(bt, UI_BUT_TEXT_LEFT);
- UI_but_func_set(bt, ui_colorpicker_create_mode_cb, bt, NULL);
+ UI_but_func_set(bt, ui_colorpicker_create_mode_cb, bt, nullptr);
bt->custom_data = cpicker;
UI_block_align_end(block);
@@ -598,10 +599,10 @@ static void ui_block_colorpicker(uiBlock *block,
yco,
UI_UNIT_X,
UI_UNIT_Y,
- NULL);
+ nullptr);
UI_but_flag_disable(bt, UI_BUT_UNDO);
UI_but_drawflag_disable(bt, UI_BUT_ICON_LEFT);
- UI_but_func_set(bt, ui_popup_close_cb, bt, NULL);
+ UI_but_func_set(bt, ui_popup_close_cb, bt, nullptr);
bt->custom_data = cpicker;
}
@@ -625,7 +626,7 @@ static void ui_block_colorpicker(uiBlock *block,
0,
3,
TIP_("Red"));
- UI_but_func_set(bt, ui_colorpicker_rgba_update_cb, bt, NULL);
+ UI_but_func_set(bt, ui_colorpicker_rgba_update_cb, bt, nullptr);
bt->custom_data = cpicker;
bt = uiDefButR_prop(block,
UI_BTYPE_NUM_SLIDER,
@@ -643,7 +644,7 @@ static void ui_block_colorpicker(uiBlock *block,
0,
3,
TIP_("Green"));
- UI_but_func_set(bt, ui_colorpicker_rgba_update_cb, bt, NULL);
+ UI_but_func_set(bt, ui_colorpicker_rgba_update_cb, bt, nullptr);
bt->custom_data = cpicker;
bt = uiDefButR_prop(block,
UI_BTYPE_NUM_SLIDER,
@@ -661,7 +662,7 @@ static void ui_block_colorpicker(uiBlock *block,
0,
3,
TIP_("Blue"));
- UI_but_func_set(bt, ui_colorpicker_rgba_update_cb, bt, NULL);
+ UI_but_func_set(bt, ui_colorpicker_rgba_update_cb, bt, nullptr);
bt->custom_data = cpicker;
/* Could use:
@@ -686,7 +687,7 @@ static void ui_block_colorpicker(uiBlock *block,
3,
TIP_("Hue"));
UI_but_flag_disable(bt, UI_BUT_UNDO);
- UI_but_func_set(bt, ui_colorpicker_hsv_update_cb, bt, NULL);
+ UI_but_func_set(bt, ui_colorpicker_hsv_update_cb, bt, nullptr);
bt->custom_data = cpicker;
bt = uiDefButF(block,
UI_BTYPE_NUM_SLIDER,
@@ -703,7 +704,7 @@ static void ui_block_colorpicker(uiBlock *block,
3,
TIP_("Saturation"));
UI_but_flag_disable(bt, UI_BUT_UNDO);
- UI_but_func_set(bt, ui_colorpicker_hsv_update_cb, bt, NULL);
+ UI_but_func_set(bt, ui_colorpicker_hsv_update_cb, bt, nullptr);
bt->custom_data = cpicker;
if (U.color_picker_type == USER_CP_CIRCLE_HSL) {
bt = uiDefButF(block,
@@ -740,7 +741,7 @@ static void ui_block_colorpicker(uiBlock *block,
UI_but_flag_disable(bt, UI_BUT_UNDO);
bt->hardmax = hardmax; /* not common but rgb may be over 1.0 */
- UI_but_func_set(bt, ui_colorpicker_hsv_update_cb, bt, NULL);
+ UI_but_func_set(bt, ui_colorpicker_hsv_update_cb, bt, nullptr);
bt->custom_data = cpicker;
UI_block_align_end(block);
@@ -762,7 +763,7 @@ static void ui_block_colorpicker(uiBlock *block,
0,
3,
TIP_("Alpha"));
- UI_but_func_set(bt, ui_colorpicker_rgba_update_cb, bt, NULL);
+ UI_but_func_set(bt, ui_colorpicker_rgba_update_cb, bt, nullptr);
bt->custom_data = cpicker;
}
else {
@@ -809,14 +810,14 @@ static void ui_block_colorpicker(uiBlock *block,
yco - UI_UNIT_Y,
butwidth,
UI_UNIT_Y,
- NULL,
+ nullptr,
0.0,
0.0,
0,
0,
"");
- ui_colorpicker_hide_reveal(block, colormode);
+ ui_colorpicker_hide_reveal(block, (ePickerType)colormode);
}
static int ui_colorpicker_small_wheel_cb(const bContext *UNUSED(C),
@@ -834,9 +835,9 @@ static int ui_colorpicker_small_wheel_cb(const bContext *UNUSED(C),
if (add != 0.0f) {
LISTBASE_FOREACH (uiBut *, but, &block->buttons) {
- if (but->type == UI_BTYPE_HSVCUBE && but->active == NULL) {
+ if (but->type == UI_BTYPE_HSVCUBE && but->active == nullptr) {
uiPopupBlockHandle *popup = block->handle;
- ColorPicker *cpicker = but->custom_data;
+ ColorPicker *cpicker = static_cast<ColorPicker *>(but->custom_data);
float *hsv_perceptual = cpicker->hsv_perceptual;
float rgb_perceptual[3];
@@ -865,7 +866,7 @@ static int ui_colorpicker_small_wheel_cb(const bContext *UNUSED(C),
uiBlock *ui_block_func_COLOR(bContext *C, uiPopupBlockHandle *handle, void *arg_but)
{
- uiBut *but = arg_but;
+ uiBut *but = static_cast<uiBut *>(arg_but);
uiBlock *block;
bool show_picker = true;
@@ -901,7 +902,7 @@ uiBlock *ui_block_func_COLOR(bContext *C, uiPopupBlockHandle *handle, void *arg_
ColorPicker *ui_block_colorpicker_create(struct uiBlock *block)
{
- ColorPicker *cpicker = MEM_callocN(sizeof(ColorPicker), "color_picker");
+ ColorPicker *cpicker = MEM_cnew<ColorPicker>(__func__);
BLI_addhead(&block->color_pickers.list, cpicker);
return cpicker;
diff --git a/source/blender/editors/interface/interface_region_hud.c b/source/blender/editors/interface/interface_region_hud.cc
index 4d72cd5382c..d6166694a4a 100644
--- a/source/blender/editors/interface/interface_region_hud.c
+++ b/source/blender/editors/interface/interface_region_hud.cc
@@ -7,7 +7,7 @@
* Floating Persistent Region
*/
-#include <string.h>
+#include <cstring>
#include "MEM_guardedalloc.h"
@@ -49,7 +49,7 @@ struct HudRegionData {
static bool last_redo_poll(const bContext *C, short region_type)
{
wmOperator *op = WM_operator_last_redo(C);
- if (op == NULL) {
+ if (op == nullptr) {
return false;
}
@@ -60,7 +60,8 @@ static bool last_redo_poll(const bContext *C, short region_type)
* wrong context.
*/
ScrArea *area = CTX_wm_area(C);
- ARegion *region_op = (region_type != -1) ? BKE_area_find_region_type(area, region_type) : NULL;
+ ARegion *region_op = (region_type != -1) ? BKE_area_find_region_type(area, region_type) :
+ nullptr;
ARegion *region_prev = CTX_wm_region(C);
CTX_wm_region_set((bContext *)C, region_op);
@@ -90,9 +91,9 @@ static bool hud_panel_operator_redo_poll(const bContext *C, PanelType *UNUSED(pt
{
ScrArea *area = CTX_wm_area(C);
ARegion *region = BKE_area_find_region_type(area, RGN_TYPE_HUD);
- if (region != NULL) {
- struct HudRegionData *hrd = region->regiondata;
- if (hrd != NULL) {
+ if (region != nullptr) {
+ HudRegionData *hrd = static_cast<HudRegionData *>(region->regiondata);
+ if (hrd != nullptr) {
return last_redo_poll(C, hrd->regionid);
}
}
@@ -108,7 +109,7 @@ static void hud_panel_operator_redo_draw_header(const bContext *C, Panel *panel)
static void hud_panel_operator_redo_draw(const bContext *C, Panel *panel)
{
wmOperator *op = WM_operator_last_redo(C);
- if (op == NULL) {
+ if (op == nullptr) {
return;
}
if (!WM_operator_check_ui_enabled(C, op->type->name)) {
@@ -120,9 +121,7 @@ static void hud_panel_operator_redo_draw(const bContext *C, Panel *panel)
static void hud_panels_register(ARegionType *art, int space_type, int region_type)
{
- PanelType *pt;
-
- pt = MEM_callocN(sizeof(PanelType), __func__);
+ PanelType *pt = MEM_cnew<PanelType>(__func__);
strcpy(pt->idname, "OPERATOR_PT_redo");
strcpy(pt->label, N_("Redo"));
strcpy(pt->translation_context, BLT_I18NCONTEXT_DEFAULT_BPYRNA);
@@ -155,8 +154,8 @@ static void hud_region_free(ARegion *region)
static void hud_region_layout(const bContext *C, ARegion *region)
{
- struct HudRegionData *hrd = region->regiondata;
- if (hrd == NULL || !last_redo_poll(C, hrd->regionid)) {
+ HudRegionData *hrd = static_cast<HudRegionData *>(region->regiondata);
+ if (hrd == nullptr || !last_redo_poll(C, hrd->regionid)) {
ED_region_tag_redraw(region);
hud_region_hide(region);
return;
@@ -205,19 +204,17 @@ static void hud_region_draw(const bContext *C, ARegion *region)
GPU_clear_color(0.0f, 0.0f, 0.0f, 0.0f);
if ((region->flag & RGN_FLAG_HIDDEN) == 0) {
- ui_draw_menu_back(NULL,
- NULL,
- &(rcti){
- .xmax = region->winx,
- .ymax = region->winy,
- });
+ rcti reset_rect = {};
+ reset_rect.xmax = region->winx;
+ reset_rect.ymax = region->winy;
+ ui_draw_menu_back(nullptr, nullptr, &reset_rect);
ED_region_panels_draw(C, region);
}
}
ARegionType *ED_area_type_hud(int space_type)
{
- ARegionType *art = MEM_callocN(sizeof(ARegionType), __func__);
+ ARegionType *art = MEM_cnew<ARegionType>(__func__);
art->regionid = RGN_TYPE_HUD;
art->keymapflag = ED_KEYMAP_UI | ED_KEYMAP_VIEW2D;
art->layout = hud_region_layout;
@@ -238,7 +235,7 @@ ARegionType *ED_area_type_hud(int space_type)
static ARegion *hud_region_add(ScrArea *area)
{
- ARegion *region = MEM_callocN(sizeof(ARegion), "area region");
+ ARegion *region = MEM_cnew<ARegion>(__func__);
ARegion *region_win = BKE_area_find_region_type(area, RGN_TYPE_WINDOW);
if (region_win) {
BLI_insertlinkbefore(&area->regionbase, region_win, region);
@@ -288,7 +285,7 @@ void ED_area_type_hud_ensure(bContext *C, ScrArea *area)
ED_area_type_hud_clear(wm, area);
ARegionType *art = BKE_regiontype_from_id(area->type, RGN_TYPE_HUD);
- if (art == NULL) {
+ if (art == nullptr) {
return;
}
@@ -301,9 +298,9 @@ void ED_area_type_hud_ensure(bContext *C, ScrArea *area)
}
bool init = false;
- const bool was_hidden = region == NULL || region->visible == false;
+ const bool was_hidden = region == nullptr || region->visible == false;
ARegion *region_op = CTX_wm_region(C);
- BLI_assert((region_op == NULL) || (region_op->regiontype != RGN_TYPE_HUD));
+ BLI_assert((region_op == nullptr) || (region_op->regiontype != RGN_TYPE_HUD));
if (!last_redo_poll(C, region_op ? region_op->regiontype : -1)) {
if (region) {
ED_region_tag_redraw(region);
@@ -312,7 +309,7 @@ void ED_area_type_hud_ensure(bContext *C, ScrArea *area)
return;
}
- if (region == NULL) {
+ if (region == nullptr) {
init = true;
region = hud_region_add(area);
region->type = art;
@@ -332,9 +329,9 @@ void ED_area_type_hud_ensure(bContext *C, ScrArea *area)
}
{
- struct HudRegionData *hrd = region->regiondata;
- if (hrd == NULL) {
- hrd = MEM_callocN(sizeof(*hrd), __func__);
+ HudRegionData *hrd = static_cast<HudRegionData *>(region->regiondata);
+ if (hrd == nullptr) {
+ hrd = MEM_cnew<HudRegionData>(__func__);
region->regiondata = hrd;
}
if (region_op) {
@@ -355,10 +352,10 @@ void ED_area_type_hud_ensure(bContext *C, ScrArea *area)
ED_region_tag_redraw(region);
/* Reset zoom level (not well supported). */
- region->v2d.cur = region->v2d.tot = (rctf){
- .xmax = region->winx,
- .ymax = region->winy,
- };
+ rctf reset_rect = {};
+ reset_rect.xmax = region->winx;
+ reset_rect.ymax = region->winy;
+ region->v2d.cur = region->v2d.tot = reset_rect;
region->v2d.minzoom = 1.0f;
region->v2d.maxzoom = 1.0f;
@@ -373,10 +370,7 @@ void ED_area_type_hud_ensure(bContext *C, ScrArea *area)
if (was_hidden) {
region->winx = region->v2d.winx;
region->winy = region->v2d.winy;
- region->v2d.cur = region->v2d.tot = (rctf){
- .xmax = region->winx,
- .ymax = region->winy,
- };
+ region->v2d.cur = region->v2d.tot = reset_rect;
}
CTX_wm_region_set((bContext *)C, region_prev);
}
diff --git a/source/blender/editors/interface/interface_region_menu_pie.c b/source/blender/editors/interface/interface_region_menu_pie.cc
index 74e128f3098..586aeef44fd 100644
--- a/source/blender/editors/interface/interface_region_menu_pie.c
+++ b/source/blender/editors/interface/interface_region_menu_pie.cc
@@ -7,9 +7,9 @@
* Pie Menu Region
*/
-#include <stdarg.h>
-#include <stdlib.h>
-#include <string.h>
+#include <cstdarg>
+#include <cstdlib>
+#include <cstring>
#include "MEM_guardedalloc.h"
@@ -51,7 +51,7 @@ struct uiPieMenu {
static uiBlock *ui_block_func_PIE(bContext *UNUSED(C), uiPopupBlockHandle *handle, void *arg_pie)
{
uiBlock *block;
- uiPieMenu *pie = arg_pie;
+ uiPieMenu *pie = static_cast<uiPieMenu *>(arg_pie);
int minwidth, width, height;
minwidth = UI_MENU_WIDTH_MIN;
@@ -89,14 +89,13 @@ static float ui_pie_menu_title_width(const char *name, int icon)
uiPieMenu *UI_pie_menu_begin(struct bContext *C, const char *title, int icon, const wmEvent *event)
{
const uiStyle *style = UI_style_get_dpi();
- uiPieMenu *pie;
short event_type;
wmWindow *win = CTX_wm_window(C);
- pie = MEM_callocN(sizeof(*pie), "pie menu");
+ uiPieMenu *pie = MEM_cnew<uiPieMenu>(__func__);
- pie->block_radial = UI_block_begin(C, NULL, __func__, UI_EMBOSS);
+ pie->block_radial = UI_block_begin(C, nullptr, __func__, UI_EMBOSS);
/* may be useful later to allow spawning pies
* from old positions */
/* pie->block_radial->flag |= UI_BLOCK_POPUP_MEMORY; */
@@ -153,7 +152,7 @@ uiPieMenu *UI_pie_menu_begin(struct bContext *C, const char *title, int icon, co
0,
w,
UI_UNIT_Y,
- NULL,
+ nullptr,
0.0,
0.0,
0,
@@ -170,7 +169,7 @@ uiPieMenu *UI_pie_menu_begin(struct bContext *C, const char *title, int icon, co
0,
w,
UI_UNIT_Y,
- NULL,
+ nullptr,
0.0,
0.0,
0,
@@ -191,7 +190,7 @@ void UI_pie_menu_end(bContext *C, uiPieMenu *pie)
wmWindow *window = CTX_wm_window(C);
uiPopupBlockHandle *menu;
- menu = ui_popup_block_create(C, NULL, NULL, NULL, ui_block_func_PIE, pie, NULL);
+ menu = ui_popup_block_create(C, nullptr, nullptr, nullptr, ui_block_func_PIE, pie, nullptr);
menu->popup = true;
menu->towardstime = PIL_check_seconds_timer();
@@ -212,7 +211,7 @@ int UI_pie_menu_invoke(struct bContext *C, const char *idname, const wmEvent *ev
uiLayout *layout;
MenuType *mt = WM_menutype_find(idname, true);
- if (mt == NULL) {
+ if (mt == nullptr) {
printf("%s: named menu \"%s\" not found\n", __func__, idname);
return OPERATOR_CANCELLED;
}
@@ -263,7 +262,7 @@ int UI_pie_menu_invoke_from_rna_enum(struct bContext *C,
uiPieMenu *pie;
uiLayout *layout;
- RNA_pointer_create(NULL, &RNA_Context, C, &ctx_ptr);
+ RNA_pointer_create(nullptr, &RNA_Context, C, &ctx_ptr);
if (!RNA_path_resolve(&ctx_ptr, path, &r_ptr, &r_prop)) {
return OPERATOR_CANCELLED;
@@ -280,7 +279,7 @@ int UI_pie_menu_invoke_from_rna_enum(struct bContext *C,
layout = UI_pie_menu_layout(pie);
layout = uiLayoutRadial(layout);
- uiItemFullR(layout, &r_ptr, r_prop, RNA_NO_INDEX, 0, UI_ITEM_R_EXPAND, NULL, 0);
+ uiItemFullR(layout, &r_ptr, r_prop, RNA_NO_INDEX, 0, UI_ITEM_R_EXPAND, nullptr, 0);
UI_pie_menu_end(C, pie);
@@ -304,7 +303,7 @@ int UI_pie_menu_invoke_from_rna_enum(struct bContext *C,
* - Julian (Feb 2016)
* \{ */
-typedef struct PieMenuLevelData {
+ struct PieMenuLevelData {
char title[UI_MAX_NAME_STR]; /* parent pie title, copied for level */
int icon; /* parent pie icon, copied for level */
int totitem; /* total count of *remaining* items */
@@ -314,7 +313,7 @@ typedef struct PieMenuLevelData {
const char *propname;
IDProperty *properties;
wmOperatorCallContext context, flag;
-} PieMenuLevelData;
+} ;
/**
* Invokes a new pie menu for a new level.
@@ -362,17 +361,17 @@ void ui_pie_menu_level_create(uiBlock *block,
const EnumPropertyItem *items,
int totitem,
wmOperatorCallContext context,
- int flag)
+ wmOperatorCallContext flag)
{
const int totitem_parent = PIE_MAX_ITEMS - 1;
const int totitem_remain = totitem - totitem_parent;
const size_t array_size = sizeof(EnumPropertyItem) * totitem_remain;
/* used as but->func_argN so freeing is handled elsewhere */
- EnumPropertyItem *remaining = MEM_mallocN(array_size + sizeof(EnumPropertyItem),
- "pie_level_item_array");
+ EnumPropertyItem *remaining = static_cast<EnumPropertyItem *>(
+ MEM_mallocN(array_size + sizeof(EnumPropertyItem), "pie_level_item_array"));
memcpy(remaining, items + totitem_parent, array_size);
- /* A NULL terminating sentinel element is required. */
+ /* A nullptr terminating sentinel element is required. */
memset(&remaining[totitem_remain], 0, sizeof(EnumPropertyItem));
/* yuk, static... issue is we can't reliably free this without doing dangerous changes */
@@ -395,7 +394,7 @@ void ui_pie_menu_level_create(uiBlock *block,
0,
UI_UNIT_X * 3,
UI_UNIT_Y,
- NULL,
+ nullptr,
0.0f,
0.0f,
0.0f,
diff --git a/source/blender/editors/interface/interface_region_menu_popup.c b/source/blender/editors/interface/interface_region_menu_popup.cc
index 7d8f4315710..e843a275d08 100644
--- a/source/blender/editors/interface/interface_region_menu_popup.c
+++ b/source/blender/editors/interface/interface_region_menu_popup.cc
@@ -7,9 +7,9 @@
* PopUp Menu Region
*/
-#include <stdarg.h>
-#include <stdlib.h>
-#include <string.h>
+#include <cstdarg>
+#include <cstdlib>
+#include <cstring>
#include "MEM_guardedalloc.h"
@@ -50,7 +50,7 @@ bool ui_but_menu_step_poll(const uiBut *but)
BLI_assert(but->type == UI_BTYPE_MENU);
/* currently only RNA buttons */
- return ((but->menu_step_func != NULL) ||
+ return ((but->menu_step_func != nullptr) ||
(but->rnaprop && RNA_property_type(but->rnaprop) == PROP_ENUM));
}
@@ -58,12 +58,16 @@ int ui_but_menu_step(uiBut *but, int direction)
{
if (ui_but_menu_step_poll(but)) {
if (but->menu_step_func) {
- return but->menu_step_func(but->block->evil_C, direction, but->poin);
+ return but->menu_step_func(
+ static_cast<bContext *>(but->block->evil_C), direction, but->poin);
}
const int curval = RNA_property_enum_get(&but->rnapoin, but->rnaprop);
- return RNA_property_enum_step(
- but->block->evil_C, &but->rnapoin, but->rnaprop, curval, direction);
+ return RNA_property_enum_step(static_cast<bContext *>(but->block->evil_C),
+ &but->rnapoin,
+ but->rnaprop,
+ curval,
+ direction);
}
printf("%s: cannot cycle button '%s'\n", __func__, but->str);
@@ -85,7 +89,7 @@ static uint ui_popup_string_hash(const char *str, const bool use_sep)
{
/* sometimes button contains hotkey, sometimes not, strip for proper compare */
int hash;
- const char *delimit = use_sep ? strrchr(str, UI_SEP_CHAR) : NULL;
+ const char *delimit = use_sep ? strrchr(str, UI_SEP_CHAR) : nullptr;
if (delimit) {
hash = BLI_ghashutil_strhash_n(str, delimit - str);
@@ -102,7 +106,7 @@ uint ui_popup_menu_hash(const char *str)
return BLI_ghashutil_strhash(str);
}
-/* but == NULL read, otherwise set */
+/* but == nullptr read, otherwise set */
static uiBut *ui_popup_menu_memory__internal(uiBlock *block, uiBut *but)
{
static uint mem[256];
@@ -114,13 +118,13 @@ static uiBut *ui_popup_menu_memory__internal(uiBlock *block, uiBut *but)
if (first) {
/* init */
memset(mem, -1, sizeof(mem));
- first = 0;
+ first = false;
}
if (but) {
/* set */
mem[hash_mod] = ui_popup_string_hash(but->str, but->flag & UI_BUT_HAS_SEP_CHAR);
- return NULL;
+ return nullptr;
}
/* get */
@@ -131,12 +135,12 @@ static uiBut *ui_popup_menu_memory__internal(uiBlock *block, uiBut *but)
}
}
- return NULL;
+ return nullptr;
}
uiBut *ui_popup_menu_memory_get(uiBlock *block)
{
- return ui_popup_menu_memory__internal(block, NULL);
+ return ui_popup_menu_memory__internal(block, nullptr);
}
void ui_popup_menu_memory_set(uiBlock *block, uiBut *but)
@@ -166,7 +170,7 @@ struct uiPopupMenu {
static uiBlock *ui_block_func_POPUP(bContext *C, uiPopupBlockHandle *handle, void *arg_pup)
{
uiBlock *block;
- uiPopupMenu *pup = arg_pup;
+ uiPopupMenu *pup = static_cast<uiPopupMenu *>(arg_pup);
int minwidth, width, height;
char direction;
bool flip;
@@ -174,7 +178,7 @@ static uiBlock *ui_block_func_POPUP(bContext *C, uiPopupBlockHandle *handle, voi
if (pup->menu_func) {
pup->block->handle = handle;
pup->menu_func(C, pup->layout, pup->menu_arg);
- pup->block->handle = NULL;
+ pup->block->handle = nullptr;
}
/* Find block minimum width. */
@@ -229,7 +233,7 @@ static uiBlock *ui_block_func_POPUP(bContext *C, uiPopupBlockHandle *handle, voi
if (pup->popup) {
int offset[2];
- uiBut *but_activate = NULL;
+ uiBut *but_activate = nullptr;
UI_block_flag_enable(block, UI_BLOCK_LOOP | UI_BLOCK_NUMSELECT);
UI_block_theme_style_set(block, UI_BLOCK_THEME_STYLE_POPUP);
UI_block_direction_set(block, direction);
@@ -309,10 +313,9 @@ uiPopupBlockHandle *ui_popup_menu_create(
wmWindow *window = CTX_wm_window(C);
const uiStyle *style = UI_style_get_dpi();
uiPopupBlockHandle *handle;
- uiPopupMenu *pup;
- pup = MEM_callocN(sizeof(uiPopupMenu), __func__);
- pup->block = UI_block_begin(C, NULL, __func__, UI_EMBOSS_PULLDOWN);
+ uiPopupMenu *pup = MEM_cnew<uiPopupMenu>(__func__);
+ pup->block = UI_block_begin(C, nullptr, __func__, UI_EMBOSS_PULLDOWN);
pup->block->flag |= UI_BLOCK_NUMSELECT; /* default menus to numselect */
pup->layout = UI_block_layout(
pup->block, UI_LAYOUT_VERTICAL, UI_LAYOUT_MENU, 0, 0, 200, 0, UI_MENU_PADDING, style);
@@ -348,7 +351,7 @@ uiPopupBlockHandle *ui_popup_menu_create(
pup->menu_func = menu_func;
pup->menu_arg = arg;
- handle = ui_popup_block_create(C, butregion, but, NULL, ui_block_func_POPUP, pup, NULL);
+ handle = ui_popup_block_create(C, butregion, but, nullptr, ui_block_func_POPUP, pup, nullptr);
if (!but) {
handle->popup = true;
@@ -374,10 +377,10 @@ uiPopupMenu *UI_popup_menu_begin_ex(bContext *C,
int icon)
{
const uiStyle *style = UI_style_get_dpi();
- uiPopupMenu *pup = MEM_callocN(sizeof(uiPopupMenu), "popup menu");
+ uiPopupMenu *pup = MEM_cnew<uiPopupMenu>(__func__);
uiBut *but;
- pup->block = UI_block_begin(C, NULL, block_name, UI_EMBOSS_PULLDOWN);
+ pup->block = UI_block_begin(C, nullptr, block_name, UI_EMBOSS_PULLDOWN);
pup->block->flag |= UI_BLOCK_POPUP_MEMORY | UI_BLOCK_IS_FLIP;
pup->block->puphash = ui_popup_menu_hash(title);
pup->layout = UI_block_layout(
@@ -389,7 +392,7 @@ uiPopupMenu *UI_popup_menu_begin_ex(bContext *C,
uiLayoutSetOperatorContext(pup->layout, WM_OP_EXEC_REGION_WIN);
/* create in advance so we can let buttons point to retval already */
- pup->block->handle = MEM_callocN(sizeof(uiPopupBlockHandle), "uiPopupBlockHandle");
+ pup->block->handle = MEM_cnew<uiPopupBlockHandle>(__func__);
/* create title button */
if (title[0]) {
@@ -406,7 +409,7 @@ uiPopupMenu *UI_popup_menu_begin_ex(bContext *C,
0,
200,
UI_UNIT_Y,
- NULL,
+ nullptr,
0.0,
0.0,
0,
@@ -415,7 +418,7 @@ uiPopupMenu *UI_popup_menu_begin_ex(bContext *C,
}
else {
but = uiDefBut(
- pup->block, UI_BTYPE_LABEL, 0, title, 0, 0, 200, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, "");
+ pup->block, UI_BTYPE_LABEL, 0, title, 0, 0, 200, UI_UNIT_Y, nullptr, 0.0, 0.0, 0, 0, "");
but->drawflag = UI_BUT_TEXT_LEFT;
}
@@ -440,8 +443,8 @@ void UI_popup_menu_end(bContext *C, uiPopupMenu *pup)
{
wmWindow *window = CTX_wm_window(C);
uiPopupBlockHandle *menu;
- uiBut *but = NULL;
- ARegion *butregion = NULL;
+ uiBut *but = nullptr;
+ ARegion *butregion = nullptr;
pup->popup = true;
pup->mx = window->eventstate->xy[0];
@@ -452,7 +455,7 @@ void UI_popup_menu_end(bContext *C, uiPopupMenu *pup)
butregion = pup->butregion;
}
- menu = ui_popup_block_create(C, butregion, but, NULL, ui_block_func_POPUP, pup, NULL);
+ menu = ui_popup_block_create(C, butregion, but, nullptr, ui_block_func_POPUP, pup, nullptr);
menu->popup = true;
UI_popup_handlers_add(C, &window->modalhandlers, menu, 0);
@@ -467,7 +470,7 @@ bool UI_popup_menu_end_or_cancel(bContext *C, uiPopupMenu *pup)
UI_popup_menu_end(C, pup);
return true;
}
- UI_block_layout_resolve(pup->block, NULL, NULL);
+ UI_block_layout_resolve(pup->block, nullptr, nullptr);
MEM_freeN(pup->block->handle);
UI_block_free(C, pup->block);
MEM_freeN(pup);
@@ -487,7 +490,7 @@ uiLayout *UI_popup_menu_layout(uiPopupMenu *pup)
void UI_popup_menu_reports(bContext *C, ReportList *reports)
{
- uiPopupMenu *pup = NULL;
+ uiPopupMenu *pup = nullptr;
uiLayout *layout;
if (!CTX_wm_window(C)) {
@@ -502,7 +505,7 @@ void UI_popup_menu_reports(bContext *C, ReportList *reports)
continue;
}
- if (pup == NULL) {
+ if (pup == nullptr) {
char title[UI_MAX_DRAW_STR];
BLI_snprintf(title, sizeof(title), "%s: %s", IFACE_("Report"), report->typestr);
/* popup_menu stuff does just what we need (but pass meaningful block name) */
@@ -540,7 +543,7 @@ int UI_popup_menu_invoke(bContext *C, const char *idname, ReportList *reports)
uiLayout *layout;
MenuType *mt = WM_menutype_find(idname, true);
- if (mt == NULL) {
+ if (mt == nullptr) {
BKE_reportf(reports, RPT_ERROR, "Menu \"%s\" not found", idname);
return OPERATOR_CANCELLED;
}
@@ -572,7 +575,7 @@ void UI_popup_block_invoke_ex(
wmWindow *window = CTX_wm_window(C);
uiPopupBlockHandle *handle;
- handle = ui_popup_block_create(C, NULL, NULL, func, NULL, arg, arg_free);
+ handle = ui_popup_block_create(C, nullptr, nullptr, func, nullptr, arg, arg_free);
handle->popup = true;
/* It can be useful to disable refresh (even though it will work)
@@ -580,7 +583,8 @@ void UI_popup_block_invoke_ex(
handle->can_refresh = can_refresh;
UI_popup_handlers_add(C, &window->modalhandlers, handle, 0);
- UI_block_active_only_flagged_buttons(C, handle->region, handle->region->uiblocks.first);
+ UI_block_active_only_flagged_buttons(
+ C, handle->region, static_cast<uiBlock *>(handle->region->uiblocks.first));
WM_event_add_mousemove(window);
}
@@ -599,7 +603,7 @@ void UI_popup_block_ex(bContext *C,
wmWindow *window = CTX_wm_window(C);
uiPopupBlockHandle *handle;
- handle = ui_popup_block_create(C, NULL, NULL, func, NULL, arg, NULL);
+ handle = ui_popup_block_create(C, nullptr, nullptr, func, nullptr, arg, nullptr);
handle->popup = true;
handle->retvalue = 1;
handle->can_refresh = true;
@@ -611,7 +615,8 @@ void UI_popup_block_ex(bContext *C,
// handle->opcontext = opcontext;
UI_popup_handlers_add(C, &window->modalhandlers, handle, 0);
- UI_block_active_only_flagged_buttons(C, handle->region, handle->region->uiblocks.first);
+ UI_block_active_only_flagged_buttons(
+ C, handle->region, static_cast<uiBlock *>(handle->region->uiblocks.first));
WM_event_add_mousemove(window);
}
@@ -621,7 +626,7 @@ void uiPupBlockOperator(bContext *C, uiBlockCreateFunc func, wmOperator *op, wmO
wmWindow *window = CTX_wm_window(C);
uiPopupBlockHandle *handle;
- handle = ui_popup_block_create(C, NULL, NULL, func, NULL, op, NULL);
+ handle = ui_popup_block_create(C, nullptr, nullptr, func, nullptr, op, nullptr);
handle->popup = 1;
handle->retvalue = 1;
handle->can_refresh = true;
@@ -638,7 +643,7 @@ void uiPupBlockOperator(bContext *C, uiBlockCreateFunc func, wmOperator *op, wmO
void UI_popup_block_close(bContext *C, wmWindow *win, uiBlock *block)
{
- /* if loading new .blend while popup is open, window will be NULL */
+ /* if loading new .blend while popup is open, window will be nullptr */
if (block->handle) {
if (win) {
const bScreen *screen = WM_window_get_active_screen(win);
diff --git a/source/blender/editors/interface/interface_region_popover.c b/source/blender/editors/interface/interface_region_popover.cc
index 7c7c9e887dd..2e10261a4f7 100644
--- a/source/blender/editors/interface/interface_region_popover.c
+++ b/source/blender/editors/interface/interface_region_popover.cc
@@ -80,7 +80,7 @@ static void ui_popover_create_block(bContext *C, uiPopover *pup, wmOperatorCallC
const uiStyle *style = UI_style_get_dpi();
- pup->block = UI_block_begin(C, NULL, __func__, UI_EMBOSS);
+ pup->block = UI_block_begin(C, nullptr, __func__, UI_EMBOSS);
UI_block_flag_enable(pup->block, UI_BLOCK_KEEP_OPEN | UI_BLOCK_POPOVER);
#ifdef USE_UI_POPOVER_ONCE
if (pup->is_once) {
@@ -104,7 +104,7 @@ static void ui_popover_create_block(bContext *C, uiPopover *pup, wmOperatorCallC
static uiBlock *ui_block_func_POPOVER(bContext *C, uiPopupBlockHandle *handle, void *arg_pup)
{
- uiPopover *pup = arg_pup;
+ uiPopover *pup = static_cast<uiPopover *>(arg_pup);
/* Create UI block and layout now if it wasn't done between begin/end. */
if (!pup->layout) {
@@ -113,10 +113,10 @@ static uiBlock *ui_block_func_POPOVER(bContext *C, uiPopupBlockHandle *handle, v
if (pup->menu_func) {
pup->block->handle = handle;
pup->menu_func(C, pup->layout, pup->menu_arg);
- pup->block->handle = NULL;
+ pup->block->handle = nullptr;
}
- pup->layout = NULL;
+ pup->layout = nullptr;
}
/* Setup and resolve UI layout for block. */
@@ -185,10 +185,10 @@ static uiBlock *ui_block_func_POPOVER(bContext *C, uiPopupBlockHandle *handle, v
block->minbounds = UI_MENU_WIDTH_MIN;
if (!handle->refresh) {
- uiBut *but = NULL;
- uiBut *but_first = NULL;
+ uiBut *but = nullptr;
+ uiBut *but_first = nullptr;
LISTBASE_FOREACH (uiBut *, but_iter, &block->buttons) {
- if ((but_first == NULL) && ui_but_is_editable(but_iter)) {
+ if ((but_first == nullptr) && ui_but_is_editable(but_iter)) {
but_first = but_iter;
}
if (but_iter->flag & (UI_SELECT | UI_SELECT_DRAW)) {
@@ -219,8 +219,8 @@ static uiBlock *ui_block_func_POPOVER(bContext *C, uiPopupBlockHandle *handle, v
static void ui_block_free_func_POPOVER(void *arg_pup)
{
- uiPopover *pup = arg_pup;
- if (pup->keymap != NULL) {
+ uiPopover *pup = static_cast<uiPopover *>(arg_pup);
+ if (pup->keymap != nullptr) {
wmWindow *window = pup->window;
WM_event_remove_keymap_handler(&window->modalhandlers, pup->keymap);
}
@@ -235,7 +235,7 @@ uiPopupBlockHandle *ui_popover_panel_create(
const PanelType *panel_type = (PanelType *)arg;
/* Create popover, buttons are created from callback. */
- uiPopover *pup = MEM_callocN(sizeof(uiPopover), __func__);
+ uiPopover *pup = MEM_cnew<uiPopover>(__func__);
pup->but = but;
/* FIXME: maybe one day we want non panel popovers? */
@@ -262,7 +262,7 @@ uiPopupBlockHandle *ui_popover_panel_create(
/* Create popup block. */
uiPopupBlockHandle *handle;
handle = ui_popup_block_create(
- C, butregion, but, NULL, ui_block_func_POPOVER, pup, ui_block_free_func_POPOVER);
+ C, butregion, but, nullptr, ui_block_func_POPOVER, pup, ui_block_free_func_POPOVER);
handle->can_refresh = true;
/* Add handlers. If attached to a button, the button will already
@@ -286,7 +286,7 @@ int UI_popover_panel_invoke(bContext *C, const char *idname, bool keep_open, Rep
{
uiLayout *layout;
PanelType *pt = WM_paneltype_find(idname, true);
- if (pt == NULL) {
+ if (pt == nullptr) {
BKE_reportf(reports, RPT_ERROR, "Panel \"%s\" not found", idname);
return OPERATOR_CANCELLED;
}
@@ -296,23 +296,23 @@ int UI_popover_panel_invoke(bContext *C, const char *idname, bool keep_open, Rep
return (OPERATOR_CANCELLED | OPERATOR_PASS_THROUGH);
}
- uiBlock *block = NULL;
+ uiBlock *block = nullptr;
if (keep_open) {
uiPopupBlockHandle *handle = ui_popover_panel_create(
- C, NULL, NULL, ui_item_paneltype_func, pt);
- uiPopover *pup = handle->popup_create_vars.arg;
+ C, nullptr, nullptr, ui_item_paneltype_func, pt);
+ uiPopover *pup = static_cast<uiPopover *>(handle->popup_create_vars.arg);
block = pup->block;
}
else {
uiPopover *pup = UI_popover_begin(C, U.widget_unit * pt->ui_units_x, false);
layout = UI_popover_layout(pup);
UI_paneltype_draw(C, pt, layout);
- UI_popover_end(C, pup, NULL);
+ UI_popover_end(C, pup, nullptr);
block = pup->block;
}
if (block) {
- uiPopupBlockHandle *handle = block->handle;
+ uiPopupBlockHandle *handle = static_cast<uiPopupBlockHandle *>(block->handle);
UI_block_active_only_flagged_buttons(C, handle->region, block);
}
return OPERATOR_INTERFACE;
@@ -326,20 +326,20 @@ int UI_popover_panel_invoke(bContext *C, const char *idname, bool keep_open, Rep
uiPopover *UI_popover_begin(bContext *C, int ui_menu_width, bool from_active_button)
{
- uiPopover *pup = MEM_callocN(sizeof(uiPopover), "popover menu");
+ uiPopover *pup = MEM_cnew<uiPopover>(__func__);
if (ui_menu_width == 0) {
ui_menu_width = U.widget_unit * UI_POPOVER_WIDTH_UNITS;
}
pup->ui_size_x = ui_menu_width;
- ARegion *butregion = NULL;
- uiBut *but = NULL;
+ ARegion *butregion = nullptr;
+ uiBut *but = nullptr;
if (from_active_button) {
butregion = CTX_wm_region(C);
but = UI_region_active_but_get(butregion);
- if (but == NULL) {
- butregion = NULL;
+ if (but == nullptr) {
+ butregion = nullptr;
}
}
@@ -350,14 +350,14 @@ uiPopover *UI_popover_begin(bContext *C, int ui_menu_width, bool from_active_but
ui_popover_create_block(C, pup, WM_OP_EXEC_REGION_WIN);
/* create in advance so we can let buttons point to retval already */
- pup->block->handle = MEM_callocN(sizeof(uiPopupBlockHandle), "uiPopupBlockHandle");
+ pup->block->handle = MEM_cnew<uiPopupBlockHandle>(__func__);
return pup;
}
static void popover_keymap_fn(wmKeyMap *UNUSED(keymap), wmKeyMapItem *UNUSED(kmi), void *user_data)
{
- uiPopover *pup = user_data;
+ uiPopover *pup = static_cast<uiPopover *>(user_data);
pup->block->handle->menuretval = UI_RETURN_OK;
}
@@ -376,8 +376,13 @@ void UI_popover_end(bContext *C, uiPopover *pup, wmKeyMap *keymap)
WM_event_set_keymap_handler_post_callback(pup->keymap_handler, popover_keymap_fn, pup);
}
- handle = ui_popup_block_create(
- C, pup->butregion, pup->but, NULL, ui_block_func_POPOVER, pup, ui_block_free_func_POPOVER);
+ handle = ui_popup_block_create(C,
+ pup->butregion,
+ pup->but,
+ nullptr,
+ ui_block_func_POPOVER,
+ pup,
+ ui_block_free_func_POPOVER);
/* Add handlers. */
UI_popup_handlers_add(C, &window->modalhandlers, handle, 0);
diff --git a/source/blender/editors/interface/interface_region_popup.c b/source/blender/editors/interface/interface_region_popup.cc
index 2f2556225b5..74c228e3338 100644
--- a/source/blender/editors/interface/interface_region_popup.c
+++ b/source/blender/editors/interface/interface_region_popup.cc
@@ -7,9 +7,9 @@
* PopUp Region (Generic)
*/
-#include <stdarg.h>
-#include <stdlib.h>
-#include <string.h>
+#include <cstdarg>
+#include <cstdlib>
+#include <cstring>
#include "MEM_guardedalloc.h"
@@ -120,7 +120,7 @@ static void ui_popup_block_position(wmWindow *window,
short dir1 = 0, dir2 = 0;
if (!handle->refresh) {
- bool left = 0, right = 0, top = 0, down = 0;
+ bool left = false, right = false, top = false, down = false;
const int win_x = WM_window_pixels_x(window);
const int win_y = WM_window_pixels_y(window);
@@ -131,24 +131,24 @@ static void ui_popup_block_position(wmWindow *window,
/* check if there's space at all */
if (butrct.xmin - max_size_x + center_x > 0.0f) {
- left = 1;
+ left = true;
}
if (butrct.xmax + max_size_x - center_x < win_x) {
- right = 1;
+ right = true;
}
if (butrct.ymin - max_size_y + center_y > 0.0f) {
- down = 1;
+ down = true;
}
if (butrct.ymax + max_size_y - center_y < win_y) {
- top = 1;
+ top = true;
}
if (top == 0 && down == 0) {
if (butrct.ymin - max_size_y < win_y - butrct.ymax - max_size_y) {
- top = 1;
+ top = true;
}
else {
- down = 1;
+ down = true;
}
}
@@ -335,7 +335,7 @@ static void ui_popup_block_position(wmWindow *window,
}
/* Keep a list of these, needed for pull-down menus. */
- uiSafetyRct *saferct = MEM_callocN(sizeof(uiSafetyRct), "uiSafetyRct");
+ uiSafetyRct *saferct = MEM_cnew<uiSafetyRct>(__func__);
saferct->parent = butrct;
saferct->safety = block->safety;
BLI_freelistN(&block->saferct);
@@ -520,7 +520,7 @@ static void ui_popup_block_remove(bContext *C, uiPopupBlockHandle *handle)
CTX_wm_window_set(C, win);
ui_region_temp_remove(C, screen, handle->region);
- /* Reset context (area and region were NULL'ed when changing context window). */
+ /* Reset context (area and region were nullptr'ed when changing context window). */
CTX_wm_window_set(C, ctx_win);
CTX_wm_area_set(C, ctx_area);
CTX_wm_region_set(C, ctx_region);
@@ -548,10 +548,10 @@ uiBlock *ui_popup_block_refresh(bContext *C,
const uiBlockHandleCreateFunc handle_create_func = handle->popup_create_vars.handle_create_func;
void *arg = handle->popup_create_vars.arg;
- uiBlock *block_old = region->uiblocks.first;
+ uiBlock *block_old = static_cast<uiBlock *>(region->uiblocks.first);
uiBlock *block;
- handle->refresh = (block_old != NULL);
+ handle->refresh = (block_old != nullptr);
BLI_assert(!handle->refresh || handle->can_refresh);
@@ -573,7 +573,7 @@ uiBlock *ui_popup_block_refresh(bContext *C,
/* ensure we don't use mouse coords here! */
#ifdef DEBUG
- window->eventstate = NULL;
+ window->eventstate = nullptr;
#endif
if (block->handle) {
@@ -588,7 +588,7 @@ uiBlock *ui_popup_block_refresh(bContext *C,
region->regiondata = handle;
/* set UI_BLOCK_NUMSELECT before UI_block_end() so we get alphanumeric keys assigned */
- if (but == NULL) {
+ if (but == nullptr) {
block->flag |= UI_BLOCK_POPUP;
}
@@ -596,7 +596,7 @@ uiBlock *ui_popup_block_refresh(bContext *C,
UI_block_theme_style_set(block, UI_BLOCK_THEME_STYLE_POPUP);
/* defer this until blocks are translated (below) */
- block->oldblock = NULL;
+ block->oldblock = nullptr;
if (!block->endblock) {
UI_block_end_ex(
@@ -610,9 +610,8 @@ uiBlock *ui_popup_block_refresh(bContext *C,
handle->direction = block->direction;
}
else {
- uiSafetyRct *saferct;
/* Keep a list of these, needed for pull-down menus. */
- saferct = MEM_callocN(sizeof(uiSafetyRct), "uiSafetyRct");
+ uiSafetyRct *saferct = MEM_cnew<uiSafetyRct>(__func__);
saferct->safety = block->safety;
BLI_addhead(&block->saferct, saferct);
}
@@ -760,7 +759,6 @@ uiPopupBlockHandle *ui_popup_block_create(bContext *C,
static ARegionType type;
ARegion *region;
uiBlock *block;
- uiPopupBlockHandle *handle;
/* disable tooltips from buttons below */
if (activebut) {
@@ -770,7 +768,7 @@ uiPopupBlockHandle *ui_popup_block_create(bContext *C,
WM_cursor_set(window, WM_CURSOR_DEFAULT);
/* create handle */
- handle = MEM_callocN(sizeof(uiPopupBlockHandle), "uiPopupBlockHandle");
+ uiPopupBlockHandle *handle = MEM_cnew<uiPopupBlockHandle>(__func__);
/* store context for operator */
handle->ctx_area = CTX_wm_area(C);
@@ -782,7 +780,7 @@ uiPopupBlockHandle *ui_popup_block_create(bContext *C,
handle->popup_create_vars.arg = arg;
handle->popup_create_vars.arg_free = arg_free;
handle->popup_create_vars.but = but;
- handle->popup_create_vars.butregion = but ? butregion : NULL;
+ handle->popup_create_vars.butregion = but ? butregion : nullptr;
copy_v2_v2_int(handle->popup_create_vars.event_xy, window->eventstate->xy);
/* don't allow by default, only if popup type explicitly supports it */
@@ -816,7 +814,7 @@ void ui_popup_block_free(bContext *C, uiPopupBlockHandle *handle)
/* If this popup is created from a popover which does NOT have keep-open flag set,
* then close the popover too. We could extend this to other popup types too. */
ARegion *region = handle->popup_create_vars.butregion;
- if (region != NULL) {
+ if (region != nullptr) {
LISTBASE_FOREACH (uiBlock *, block, &region->uiblocks) {
if (block->handle && (block->flag & UI_BLOCK_POPOVER) &&
(block->flag & UI_BLOCK_KEEP_OPEN) == 0) {
diff --git a/source/blender/editors/interface/interface_regions.c b/source/blender/editors/interface/interface_regions.cc
index ea6d293e52f..1a2c1f7919c 100644
--- a/source/blender/editors/interface/interface_regions.c
+++ b/source/blender/editors/interface/interface_regions.cc
@@ -25,7 +25,7 @@
ARegion *ui_region_temp_add(bScreen *screen)
{
- ARegion *region = MEM_callocN(sizeof(ARegion), __func__);
+ ARegion *region = MEM_cnew<ARegion>(__func__);
BLI_addtail(&screen->regionbase, region);
region->regiontype = RGN_TYPE_TEMPORARY;
@@ -45,6 +45,6 @@ void ui_region_temp_remove(bContext *C, bScreen *screen, ARegion *region)
}
ED_region_exit(C, region);
- BKE_area_region_free(NULL, region); /* NULL: no spacetype */
+ BKE_area_region_free(nullptr, region); /* nullptr: no spacetype */
BLI_freelinkN(&screen->regionbase, region);
}
diff --git a/source/blender/editors/interface/interface_style.c b/source/blender/editors/interface/interface_style.cc
index 76023f3033f..b4e97f8a396 100644
--- a/source/blender/editors/interface/interface_style.c
+++ b/source/blender/editors/interface/interface_style.cc
@@ -5,11 +5,11 @@
* \ingroup edinterface
*/
-#include <limits.h>
-#include <math.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
+#include <climits>
+#include <cmath>
+#include <cstdio>
+#include <cstdlib>
+#include <cstring>
#include "MEM_guardedalloc.h"
@@ -57,7 +57,7 @@
static uiStyle *ui_style_new(ListBase *styles, const char *name, short uifont_id)
{
- uiStyle *style = MEM_callocN(sizeof(uiStyle), "new style");
+ uiStyle *style = MEM_cnew<uiStyle>(__func__);
BLI_addtail(styles, style);
BLI_strncpy(style->name, name, MAX_STYLE_NAME);
@@ -108,14 +108,14 @@ static uiStyle *ui_style_new(ListBase *styles, const char *name, short uifont_id
static uiFont *uifont_to_blfont(int id)
{
- uiFont *font = U.uifonts.first;
+ uiFont *font = static_cast<uiFont *>(U.uifonts.first);
for (; font; font = font->next) {
if (font->uifont_id == id) {
return font;
}
}
- return U.uifonts.first;
+ return static_cast<uiFont *>(U.uifonts.first);
}
/* *************** draw ************************ */
@@ -198,7 +198,7 @@ void UI_fontstyle_draw(const uiFontStyle *fs,
const uchar col[4],
const struct uiFontStyleDraw_Params *fs_params)
{
- UI_fontstyle_draw_ex(fs, rect, str, str_len, col, fs_params, NULL, NULL, NULL);
+ UI_fontstyle_draw_ex(fs, rect, str, str_len, col, fs_params, nullptr, nullptr, nullptr);
}
void UI_fontstyle_draw_rotated(const uiFontStyle *fs,
@@ -284,17 +284,13 @@ void UI_fontstyle_draw_simple_backdrop(const uiFontStyle *fs,
const float decent = BLF_descender(fs->uifont_id);
const float margin = height / 4.0f;
+ rctf rect;
+ rect.xmin = x - margin;
+ rect.xmax = x + width + margin;
+ rect.ymin = (y + decent) - margin;
+ rect.ymax = (y + decent) + height + margin;
UI_draw_roundbox_corner_set(UI_CNR_ALL);
- UI_draw_roundbox_4fv(
- &(const rctf){
- .xmin = x - margin,
- .xmax = x + width + margin,
- .ymin = (y + decent) - margin,
- .ymax = (y + decent) + height + margin,
- },
- true,
- margin,
- col_bg);
+ UI_draw_roundbox_4fv(&rect, true, margin, col_bg);
}
BLF_position(fs->uifont_id, x, y, 0.0f);
@@ -307,12 +303,12 @@ void UI_fontstyle_draw_simple_backdrop(const uiFontStyle *fs,
const uiStyle *UI_style_get(void)
{
#if 0
- uiStyle *style = NULL;
+ uiStyle *style = nullptr;
/* offset is two struct uiStyle pointers */
style = BLI_findstring(&U.uistyles, "Unifont Style", sizeof(style) * 2);
- return (style != NULL) ? style : U.uistyles.first;
+ return (style != nullptr) ? style : U.uistyles.first;
#else
- return U.uistyles.first;
+ return static_cast<const uiStyle *>(U.uistyles.first);
#endif
}
@@ -378,7 +374,7 @@ int UI_fontstyle_height_max(const uiFontStyle *fs)
void uiStyleInit(void)
{
- const uiStyle *style = U.uistyles.first;
+ const uiStyle *style = static_cast<uiStyle *>(U.uistyles.first);
/* recover from uninitialized dpi */
if (U.dpi == 0) {
@@ -400,11 +396,11 @@ void uiStyleInit(void)
blf_mono_font_render = -1;
}
- uiFont *font_first = U.uifonts.first;
+ uiFont *font_first = static_cast<uiFont *>(U.uifonts.first);
/* default builtin */
- if (font_first == NULL) {
- font_first = MEM_callocN(sizeof(uiFont), "ui font");
+ if (font_first == nullptr) {
+ font_first = MEM_cnew<uiFont>(__func__);
BLI_addtail(&U.uifonts, font_first);
}
@@ -439,7 +435,7 @@ void uiStyleInit(void)
}
}
- if (style == NULL) {
+ if (style == nullptr) {
style = ui_style_new(&U.uistyles, "Default Style", UIFONT_DEFAULT);
}
diff --git a/source/blender/editors/interface/interface_utils.c b/source/blender/editors/interface/interface_utils.cc
index 728d42a9353..b796f07c24b 100644
--- a/source/blender/editors/interface/interface_utils.c
+++ b/source/blender/editors/interface/interface_utils.cc
@@ -5,17 +5,16 @@
* \ingroup edinterface
*/
-#include <ctype.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
+#include <cctype>
+#include <cstdio>
+#include <cstdlib>
+#include <cstring>
#include "DNA_object_types.h"
#include "DNA_screen_types.h"
#include "ED_screen.h"
-#include "BLI_alloca.h"
#include "BLI_listbase.h"
#include "BLI_math.h"
#include "BLI_string.h"
@@ -55,12 +54,12 @@ uiBut *uiDefAutoButR(uiBlock *block,
int width,
int height)
{
- uiBut *but = NULL;
+ uiBut *but = nullptr;
switch (RNA_property_type(prop)) {
case PROP_BOOLEAN: {
if (RNA_property_array_check(prop) && index == -1) {
- return NULL;
+ return nullptr;
}
if (icon && name && name[0] == '\0') {
@@ -79,7 +78,7 @@ uiBut *uiDefAutoButR(uiBlock *block,
0,
-1,
-1,
- NULL);
+ nullptr);
}
else if (icon) {
but = uiDefIconTextButR_prop(block,
@@ -98,7 +97,7 @@ uiBut *uiDefAutoButR(uiBlock *block,
0,
-1,
-1,
- NULL);
+ nullptr);
}
else {
but = uiDefButR_prop(block,
@@ -116,7 +115,7 @@ uiBut *uiDefAutoButR(uiBlock *block,
0,
-1,
-1,
- NULL);
+ nullptr);
}
break;
}
@@ -139,10 +138,10 @@ uiBut *uiDefAutoButR(uiBlock *block,
0,
0,
0,
- NULL);
+ nullptr);
}
else {
- return NULL;
+ return nullptr;
}
}
else if (RNA_property_subtype(prop) == PROP_PERCENTAGE ||
@@ -162,11 +161,25 @@ uiBut *uiDefAutoButR(uiBlock *block,
0,
-1,
-1,
- NULL);
+ nullptr);
}
else {
- but = uiDefButR_prop(
- block, UI_BTYPE_NUM, 0, name, x, y, width, height, ptr, prop, index, 0, 0, 0, 0, NULL);
+ but = uiDefButR_prop(block,
+ UI_BTYPE_NUM,
+ 0,
+ name,
+ x,
+ y,
+ width,
+ height,
+ ptr,
+ prop,
+ index,
+ 0,
+ 0,
+ 0,
+ 0,
+ nullptr);
}
if (RNA_property_flag(prop) & PROP_TEXTEDIT_UPDATE) {
@@ -191,14 +204,14 @@ uiBut *uiDefAutoButR(uiBlock *block,
0,
-1,
-1,
- NULL);
+ nullptr);
}
else if (icon) {
but = uiDefIconTextButR_prop(block,
UI_BTYPE_MENU,
0,
icon,
- NULL,
+ nullptr,
x,
y,
width,
@@ -210,7 +223,7 @@ uiBut *uiDefAutoButR(uiBlock *block,
0,
-1,
-1,
- NULL);
+ nullptr);
}
else {
but = uiDefButR_prop(block,
@@ -228,7 +241,7 @@ uiBut *uiDefAutoButR(uiBlock *block,
0,
-1,
-1,
- NULL);
+ nullptr);
}
break;
case PROP_STRING:
@@ -248,7 +261,7 @@ uiBut *uiDefAutoButR(uiBlock *block,
0,
-1,
-1,
- NULL);
+ nullptr);
}
else if (icon) {
but = uiDefIconTextButR_prop(block,
@@ -267,7 +280,7 @@ uiBut *uiDefAutoButR(uiBlock *block,
0,
-1,
-1,
- NULL);
+ nullptr);
}
else {
but = uiDefButR_prop(block,
@@ -285,7 +298,7 @@ uiBut *uiDefAutoButR(uiBlock *block,
0,
-1,
-1,
- NULL);
+ nullptr);
}
if (RNA_property_flag(prop) & PROP_TEXTEDIT_UPDATE) {
@@ -319,20 +332,21 @@ uiBut *uiDefAutoButR(uiBlock *block,
0,
-1,
-1,
- NULL);
- ui_but_add_search(but, ptr, prop, NULL, NULL);
+ nullptr);
+ ui_but_add_search(but, ptr, prop, nullptr, nullptr);
break;
}
case PROP_COLLECTION: {
char text[256];
BLI_snprintf(
text, sizeof(text), IFACE_("%d items"), RNA_property_collection_length(ptr, prop));
- but = uiDefBut(block, UI_BTYPE_LABEL, 0, text, x, y, width, height, NULL, 0, 0, 0, 0, NULL);
+ but = uiDefBut(
+ block, UI_BTYPE_LABEL, 0, text, x, y, width, height, nullptr, 0, 0, 0, 0, nullptr);
UI_but_flag_enable(but, UI_BUT_DISABLED);
break;
}
default:
- but = NULL;
+ but = nullptr;
break;
}
@@ -414,7 +428,7 @@ eAutoPropButsReturn uiDefAutoButsRNA(uiLayout *layout,
case UI_BUT_LABEL_ALIGN_NONE:
default:
col = layout;
- name = NULL; /* no smart label alignment, show default name with button */
+ name = nullptr; /* no smart label alignment, show default name with button */
break;
}
@@ -440,7 +454,7 @@ eAutoPropButsReturn uiDefAutoButsRNA(uiLayout *layout,
/* *** RNA collection search menu *** */
-typedef struct CollItemSearch {
+struct CollItemSearch {
struct CollItemSearch *next, *prev;
void *data;
char *name;
@@ -449,7 +463,7 @@ typedef struct CollItemSearch {
bool is_id;
int name_prefix_offset;
uint has_sep_char : 1;
-} CollItemSearch;
+};
static bool add_collection_search_item(CollItemSearch *cis,
const bool requires_exact_data_name,
@@ -462,10 +476,11 @@ static bool add_collection_search_item(CollItemSearch *cis,
* name prefix for showing the library status. */
int name_prefix_offset = cis->name_prefix_offset;
if (!has_id_icon && cis->is_id && !requires_exact_data_name) {
- cis->iconid = UI_icon_from_library(cis->data);
+ cis->iconid = UI_icon_from_library(static_cast<const ID *>(cis->data));
/* No need to re-allocate, string should be shorter than before (lib status prefix is
* removed). */
- BKE_id_full_name_ui_prefix_get(name_buf, cis->data, false, UI_SEP_CHAR, &name_prefix_offset);
+ BKE_id_full_name_ui_prefix_get(
+ name_buf, static_cast<const ID *>(cis->data), false, UI_SEP_CHAR, &name_prefix_offset);
BLI_assert(strlen(name_buf) <= MEM_allocN_len(cis->name));
strcpy(cis->name, name_buf);
}
@@ -478,15 +493,12 @@ static bool add_collection_search_item(CollItemSearch *cis,
name_prefix_offset);
}
-void ui_rna_collection_search_update_fn(const struct bContext *C,
- void *arg,
- const char *str,
- uiSearchItems *items,
- const bool is_first)
+void ui_rna_collection_search_update_fn(
+ const bContext *C, void *arg, const char *str, uiSearchItems *items, const bool is_first)
{
- uiRNACollectionSearch *data = arg;
+ uiRNACollectionSearch *data = static_cast<uiRNACollectionSearch *>(arg);
const int flag = RNA_property_flag(data->target_prop);
- ListBase *items_list = MEM_callocN(sizeof(ListBase), "items_list");
+ ListBase *items_list = MEM_cnew<ListBase>("items_list");
const bool is_ptr_target = (RNA_property_type(data->target_prop) == PROP_POINTER);
/* For non-pointer properties, UI code acts entirely based on the item's name. So the name has to
* match the RNA name exactly. So only for pointer properties, the name can be modified to add
@@ -497,7 +509,7 @@ void ui_rna_collection_search_update_fn(const struct bContext *C,
char *name;
bool has_id_icon = false;
- StringSearch *search = skip_filter ? NULL : BLI_string_search_new();
+ StringSearch *search = skip_filter ? nullptr : BLI_string_search_new();
/* build a temporary list of relevant items first */
int item_index = 0;
@@ -522,18 +534,17 @@ void ui_rna_collection_search_update_fn(const struct bContext *C,
const bool is_id = itemptr.type && RNA_struct_is_ID(itemptr.type);
if (is_id) {
- iconid = ui_id_icon_get(C, itemptr.data, false);
+ iconid = ui_id_icon_get(C, static_cast<ID *>(itemptr.data), false);
if (!ELEM(iconid, 0, ICON_BLANK1)) {
has_id_icon = true;
}
if (requires_exact_data_name) {
- name = RNA_struct_name_get_alloc(&itemptr, name_buf, sizeof(name_buf), NULL);
+ name = RNA_struct_name_get_alloc(&itemptr, name_buf, sizeof(name_buf), nullptr);
}
else {
- const ID *id = itemptr.data;
- BKE_id_full_name_ui_prefix_get(
- name_buf, itemptr.data, true, UI_SEP_CHAR, &name_prefix_offset);
+ const ID *id = static_cast<ID *>(itemptr.data);
+ BKE_id_full_name_ui_prefix_get(name_buf, id, true, UI_SEP_CHAR, &name_prefix_offset);
BLI_STATIC_ASSERT(sizeof(name_buf) >= MAX_ID_FULL_NAME_UI,
"Name string buffer should be big enough to hold full UI ID name");
name = name_buf;
@@ -541,11 +552,11 @@ void ui_rna_collection_search_update_fn(const struct bContext *C,
}
}
else {
- name = RNA_struct_name_get_alloc(&itemptr, name_buf, sizeof(name_buf), NULL);
+ name = RNA_struct_name_get_alloc(&itemptr, name_buf, sizeof(name_buf), nullptr);
}
if (name) {
- CollItemSearch *cis = MEM_callocN(sizeof(CollItemSearch), "CollectionItemSearch");
+ CollItemSearch *cis = MEM_cnew<CollItemSearch>(__func__);
cis->data = itemptr.data;
cis->name = BLI_strdup(name);
cis->index = item_index;
@@ -597,7 +608,7 @@ void ui_rna_collection_search_update_fn(const struct bContext *C,
int UI_icon_from_id(const ID *id)
{
- if (id == NULL) {
+ if (id == nullptr) {
return ICON_NONE;
}
@@ -608,7 +619,7 @@ int UI_icon_from_id(const ID *id)
if (ob->type == OB_EMPTY) {
return ICON_EMPTY_DATA;
}
- return UI_icon_from_id(ob->data);
+ return UI_icon_from_id(static_cast<const ID *>(ob->data));
}
/* otherwise get it through RNA, creating the pointer
@@ -761,7 +772,7 @@ bool UI_but_online_manual_id(const uiBut *but, char *r_str, size_t maxlength)
return false;
}
-bool UI_but_online_manual_id_from_active(const struct bContext *C, char *r_str, size_t maxlength)
+bool UI_but_online_manual_id_from_active(const bContext *C, char *r_str, size_t maxlength)
{
uiBut *but = UI_context_active_but_get(C);
@@ -861,7 +872,7 @@ void UI_but_ensure_in_view(const bContext *C, ARegion *region, const uiBut *but)
* Modal Button Store API.
*
* Store for modal operators & handlers to register button pointers
- * which are maintained while drawing or NULL when removed.
+ * which are maintained while drawing or nullptr when removed.
*
* This is needed since button pointers are continuously freed and re-allocated.
*
@@ -880,7 +891,7 @@ struct uiButStoreElem {
uiButStore *UI_butstore_create(uiBlock *block)
{
- uiButStore *bs_handle = MEM_callocN(sizeof(uiButStore), __func__);
+ uiButStore *bs_handle = MEM_cnew<uiButStore>(__func__);
bs_handle->block = block;
BLI_addtail(&block->butstore, bs_handle);
@@ -899,7 +910,7 @@ void UI_butstore_free(uiBlock *block, uiButStore *bs_handle)
* Ideally we would manage moving the 'uiButStore', keeping a correct state.
* All things considered this is the most straightforward fix - Campbell.
*/
- if (block != bs_handle->block && bs_handle->block != NULL) {
+ if (block != bs_handle->block && bs_handle->block != nullptr) {
block = bs_handle->block;
}
@@ -912,7 +923,7 @@ void UI_butstore_free(uiBlock *block, uiButStore *bs_handle)
bool UI_butstore_is_valid(uiButStore *bs)
{
- return (bs->block != NULL);
+ return (bs->block != nullptr);
}
bool UI_butstore_is_registered(uiBlock *block, uiBut *but)
@@ -930,7 +941,7 @@ bool UI_butstore_is_registered(uiBlock *block, uiBut *but)
void UI_butstore_register(uiButStore *bs_handle, uiBut **but_p)
{
- uiButStoreElem *bs_elem = MEM_callocN(sizeof(uiButStoreElem), __func__);
+ uiButStoreElem *bs_elem = MEM_cnew<uiButStoreElem>(__func__);
BLI_assert(*but_p);
bs_elem->but_p = but_p;
@@ -968,9 +979,9 @@ bool UI_butstore_register_update(uiBlock *block, uiBut *but_dst, const uiBut *bu
void UI_butstore_clear(uiBlock *block)
{
LISTBASE_FOREACH (uiButStore *, bs_handle, &block->butstore) {
- bs_handle->block = NULL;
+ bs_handle->block = nullptr;
LISTBASE_FOREACH (uiButStoreElem *, bs_elem, &bs_handle->items) {
- *bs_elem->but_p = NULL;
+ *bs_elem->but_p = nullptr;
}
}
}
@@ -984,14 +995,14 @@ void UI_butstore_update(uiBlock *block)
}
}
- if (LIKELY(block->butstore.first == NULL)) {
+ if (LIKELY(block->butstore.first == nullptr)) {
return;
}
/* warning, loop-in-loop, in practice we only store <10 buttons at a time,
* so this isn't going to be a problem, if that changes old-new mapping can be cached first */
LISTBASE_FOREACH (uiButStore *, bs_handle, &block->butstore) {
- BLI_assert(ELEM(bs_handle->block, NULL, block) ||
+ BLI_assert(ELEM(bs_handle->block, nullptr, block) ||
(block->oldblock && block->oldblock == bs_handle->block));
if (bs_handle->block == block->oldblock) {
@@ -1001,7 +1012,7 @@ void UI_butstore_update(uiBlock *block)
if (*bs_elem->but_p) {
uiBut *but_new = ui_but_find_new(block, *bs_elem->but_p);
- /* can be NULL if the buttons removed,
+ /* can be nullptr if the buttons removed,
* NOTE: we could allow passing in a callback when buttons are removed
* so the caller can cleanup */
*bs_elem->but_p = but_new;
diff --git a/source/blender/editors/object/object_transform.cc b/source/blender/editors/object/object_transform.cc
index 36d70eeef64..235ffb61738 100644
--- a/source/blender/editors/object/object_transform.cc
+++ b/source/blender/editors/object/object_transform.cc
@@ -1263,12 +1263,12 @@ static int object_origin_set_exec(bContext *C, wmOperator *op)
}
/* reset flags */
- for (int object_index = 0; object_index < objects.size(); object_index++) {
+ for (const int object_index : objects.index_range()) {
Object *ob = objects[object_index];
ob->flag &= ~OB_DONE;
/* move active first */
- if (ob == obact) {
+ if (ob == obact && objects.size() > 1) {
memmove(&objects[1], objects.data(), object_index * sizeof(Object *));
objects[0] = ob;
}
diff --git a/source/blender/editors/render/render_intern.hh b/source/blender/editors/render/render_intern.hh
index fc40fb06851..4135a0d97a9 100644
--- a/source/blender/editors/render/render_intern.hh
+++ b/source/blender/editors/render/render_intern.hh
@@ -33,6 +33,8 @@ void SCENE_OT_view_layer_add(struct wmOperatorType *ot);
void SCENE_OT_view_layer_remove(struct wmOperatorType *ot);
void SCENE_OT_view_layer_add_aov(struct wmOperatorType *ot);
void SCENE_OT_view_layer_remove_aov(struct wmOperatorType *ot);
+void SCENE_OT_view_layer_add_lightgroup(struct wmOperatorType *ot);
+void SCENE_OT_view_layer_remove_lightgroup(struct wmOperatorType *ot);
void SCENE_OT_light_cache_bake(struct wmOperatorType *ot);
void SCENE_OT_light_cache_free(struct wmOperatorType *ot);
diff --git a/source/blender/editors/render/render_ops.cc b/source/blender/editors/render/render_ops.cc
index 1583ce44ee5..f671b2f950d 100644
--- a/source/blender/editors/render/render_ops.cc
+++ b/source/blender/editors/render/render_ops.cc
@@ -39,6 +39,8 @@ void ED_operatortypes_render()
WM_operatortype_append(SCENE_OT_view_layer_remove);
WM_operatortype_append(SCENE_OT_view_layer_add_aov);
WM_operatortype_append(SCENE_OT_view_layer_remove_aov);
+ WM_operatortype_append(SCENE_OT_view_layer_add_lightgroup);
+ WM_operatortype_append(SCENE_OT_view_layer_remove_lightgroup);
WM_operatortype_append(SCENE_OT_render_view_add);
WM_operatortype_append(SCENE_OT_render_view_remove);
diff --git a/source/blender/editors/render/render_shading.cc b/source/blender/editors/render/render_shading.cc
index f48ac99fe75..07a07b462ef 100644
--- a/source/blender/editors/render/render_shading.cc
+++ b/source/blender/editors/render/render_shading.cc
@@ -1115,6 +1115,86 @@ void SCENE_OT_view_layer_remove_aov(wmOperatorType *ot)
/** \} */
/* -------------------------------------------------------------------- */
+/** \name View Layer Add Lightgroup Operator
+ * \{ */
+
+static int view_layer_add_lightgroup_exec(bContext *C, wmOperator *UNUSED(op))
+{
+ Scene *scene = CTX_data_scene(C);
+ ViewLayer *view_layer = CTX_data_view_layer(C);
+
+ BKE_view_layer_add_lightgroup(view_layer);
+
+ if (scene->nodetree) {
+ ntreeCompositUpdateRLayers(scene->nodetree);
+ }
+
+ DEG_id_tag_update(&scene->id, 0);
+ DEG_relations_tag_update(CTX_data_main(C));
+ WM_event_add_notifier(C, NC_SCENE | ND_LAYER, scene);
+
+ return OPERATOR_FINISHED;
+}
+
+void SCENE_OT_view_layer_add_lightgroup(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Add Lightgroup";
+ ot->idname = "SCENE_OT_view_layer_add_lightgroup";
+ ot->description = "Add a Light Group";
+
+ /* api callbacks */
+ ot->exec = view_layer_add_lightgroup_exec;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name View Layer Remove Lightgroup Operator
+ * \{ */
+
+static int view_layer_remove_lightgroup_exec(bContext *C, wmOperator *UNUSED(op))
+{
+ Scene *scene = CTX_data_scene(C);
+ ViewLayer *view_layer = CTX_data_view_layer(C);
+
+ if (view_layer->active_lightgroup == nullptr) {
+ return OPERATOR_FINISHED;
+ }
+
+ BKE_view_layer_remove_lightgroup(view_layer, view_layer->active_lightgroup);
+
+ if (scene->nodetree) {
+ ntreeCompositUpdateRLayers(scene->nodetree);
+ }
+
+ DEG_id_tag_update(&scene->id, 0);
+ DEG_relations_tag_update(CTX_data_main(C));
+ WM_event_add_notifier(C, NC_SCENE | ND_LAYER, scene);
+
+ return OPERATOR_FINISHED;
+}
+
+void SCENE_OT_view_layer_remove_lightgroup(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Remove Lightgroup";
+ ot->idname = "SCENE_OT_view_layer_remove_lightgroup";
+ ot->description = "Remove Active Lightgroup";
+
+ /* api callbacks */
+ ot->exec = view_layer_remove_lightgroup_exec;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
/** \name Light Cache Bake Operator
* \{ */
diff --git a/source/blender/makesdna/DNA_layer_types.h b/source/blender/makesdna/DNA_layer_types.h
index 7b6fe3773f8..d5f7e25bb80 100644
--- a/source/blender/makesdna/DNA_layer_types.h
+++ b/source/blender/makesdna/DNA_layer_types.h
@@ -124,6 +124,21 @@ typedef struct ViewLayerAOV {
* matches `eViewLayerAOVType` */
int type;
} ViewLayerAOV;
+
+/* Lightgroup Renderpass definition. */
+typedef struct ViewLayerLightgroup {
+ struct ViewLayerLightgroup *next, *prev;
+
+ /* Name of the Lightgroup */
+ char name[64];
+} ViewLayerLightgroup;
+
+/* Lightgroup membership information. */
+typedef struct LightgroupMembership {
+ /* Name of the Lightgroup */
+ char name[64];
+} LightgroupMembership;
+
typedef struct ViewLayer {
struct ViewLayer *next, *prev;
/** MAX_NAME. */
@@ -164,6 +179,10 @@ typedef struct ViewLayer {
ListBase aovs;
ViewLayerAOV *active_aov;
+ /* List containing the 'ViewLayerLightgroup`s */
+ ListBase lightgroups;
+ ViewLayerLightgroup *active_lightgroup;
+
/* Runtime data */
/** ViewLayerEngineData. */
ListBase drawdata;
diff --git a/source/blender/makesdna/DNA_object_types.h b/source/blender/makesdna/DNA_object_types.h
index 30f80110f6e..54627e711ff 100644
--- a/source/blender/makesdna/DNA_object_types.h
+++ b/source/blender/makesdna/DNA_object_types.h
@@ -31,6 +31,7 @@ struct Curve;
struct FluidsimSettings;
struct GeometrySet;
struct Ipo;
+struct LightgroupMembership;
struct Material;
struct Mesh;
struct Object;
@@ -434,8 +435,10 @@ typedef struct Object {
ObjectLineArt lineart;
+ /** Lightgroup membership information. */
+ struct LightgroupMembership *lightgroup;
+
/** Runtime evaluation data (keep last). */
- void *_pad9;
Object_Runtime runtime;
} Object;
diff --git a/source/blender/makesdna/DNA_world_types.h b/source/blender/makesdna/DNA_world_types.h
index 497b99eb04d..88f2e0c9407 100644
--- a/source/blender/makesdna/DNA_world_types.h
+++ b/source/blender/makesdna/DNA_world_types.h
@@ -16,6 +16,7 @@ extern "C" {
struct AnimData;
struct Ipo;
+struct LightgroupMembership;
struct bNodeTree;
#ifndef MAX_MTEX
@@ -70,6 +71,9 @@ typedef struct World {
/* nodes */
struct bNodeTree *nodetree;
+ /* Lightgroup membership information. */
+ struct LightgroupMembership *lightgroup;
+
/** Runtime. */
ListBase gpumaterial;
} World;
diff --git a/source/blender/makesrna/intern/rna_internal.h b/source/blender/makesrna/intern/rna_internal.h
index 84f083cb37a..0df0be07fee 100644
--- a/source/blender/makesrna/intern/rna_internal.h
+++ b/source/blender/makesrna/intern/rna_internal.h
@@ -355,6 +355,10 @@ void rna_ViewLayer_active_aov_index_range(
PointerRNA *ptr, int *min, int *max, int *softmin, int *softmax);
int rna_ViewLayer_active_aov_index_get(PointerRNA *ptr);
void rna_ViewLayer_active_aov_index_set(PointerRNA *ptr, int value);
+void rna_ViewLayer_active_lightgroup_index_range(
+ PointerRNA *ptr, int *min, int *max, int *softmin, int *softmax);
+int rna_ViewLayer_active_lightgroup_index_get(PointerRNA *ptr);
+void rna_ViewLayer_active_lightgroup_index_set(PointerRNA *ptr, int value);
/**
* Set `r_rna_path` with the base view-layer path.
* `rna_path_buffer_size` should be at least `sizeof(ViewLayer.name) * 3`.
diff --git a/source/blender/makesrna/intern/rna_object.c b/source/blender/makesrna/intern/rna_object.c
index e4495df36f1..f995ee3383e 100644
--- a/source/blender/makesrna/intern/rna_object.c
+++ b/source/blender/makesrna/intern/rna_object.c
@@ -2292,6 +2292,21 @@ static int rna_Object_mesh_symmetry_yz_editable(PointerRNA *ptr, const char **UN
return PROP_EDITABLE;
}
+void rna_Object_lightgroup_get(PointerRNA *ptr, char *value)
+{
+ BKE_lightgroup_membership_get(((Object *)ptr->owner_id)->lightgroup, value);
+}
+
+int rna_Object_lightgroup_length(PointerRNA *ptr)
+{
+ return BKE_lightgroup_membership_length(((Object *)ptr->owner_id)->lightgroup);
+}
+
+void rna_Object_lightgroup_set(PointerRNA *ptr, const char *value)
+{
+ BKE_lightgroup_membership_set(&((Object *)ptr->owner_id)->lightgroup, value);
+}
+
#else
static void rna_def_vertex_group(BlenderRNA *brna)
@@ -3775,6 +3790,15 @@ static void rna_def_object(BlenderRNA *brna)
RNA_def_property_editable_func(prop, "rna_Object_mesh_symmetry_yz_editable");
RNA_def_property_ui_text(prop, "Z", "Enable mesh symmetry in the Z axis");
+ /* Lightgroup Membership */
+ prop = RNA_def_property(srna, "lightgroup", PROP_STRING, PROP_NONE);
+ RNA_def_property_string_funcs(prop,
+ "rna_Object_lightgroup_get",
+ "rna_Object_lightgroup_length",
+ "rna_Object_lightgroup_set");
+ RNA_def_property_flag(prop, PROP_EDITABLE);
+ RNA_def_property_ui_text(prop, "Lightgroup", "Lightgroup that the object belongs to");
+
RNA_define_lib_overridable(false);
/* anim */
diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c
index 8d5d93e10ac..0960d246257 100644
--- a/source/blender/makesrna/intern/rna_scene.c
+++ b/source/blender/makesrna/intern/rna_scene.c
@@ -1767,6 +1767,10 @@ void rna_ViewLayer_pass_update(Main *bmain, Scene *activescene, PointerRNA *ptr)
ViewLayerAOV *aov = (ViewLayerAOV *)ptr->data;
view_layer = BKE_view_layer_find_with_aov(scene, aov);
}
+ else if (ptr->type == &RNA_Lightgroup) {
+ ViewLayerLightgroup *lightgroup = (ViewLayerLightgroup *)ptr->data;
+ view_layer = BKE_view_layer_find_with_lightgroup(scene, lightgroup);
+ }
if (view_layer) {
RenderEngineType *engine_type = RE_engines_find(scene->r.engine);
@@ -2447,6 +2451,49 @@ void rna_ViewLayer_active_aov_index_set(PointerRNA *ptr, int value)
view_layer->active_aov = aov;
}
+void rna_ViewLayer_active_lightgroup_index_range(
+ PointerRNA *ptr, int *min, int *max, int *UNUSED(softmin), int *UNUSED(softmax))
+{
+ ViewLayer *view_layer = (ViewLayer *)ptr->data;
+
+ *min = 0;
+ *max = max_ii(0, BLI_listbase_count(&view_layer->lightgroups) - 1);
+}
+
+int rna_ViewLayer_active_lightgroup_index_get(PointerRNA *ptr)
+{
+ ViewLayer *view_layer = (ViewLayer *)ptr->data;
+ return BLI_findindex(&view_layer->lightgroups, view_layer->active_lightgroup);
+}
+
+void rna_ViewLayer_active_lightgroup_index_set(PointerRNA *ptr, int value)
+{
+ ViewLayer *view_layer = (ViewLayer *)ptr->data;
+ ViewLayerLightgroup *lightgroup = BLI_findlink(&view_layer->lightgroups, value);
+ view_layer->active_lightgroup = lightgroup;
+}
+
+static void rna_ViewLayerLightgroup_name_get(PointerRNA *ptr, char *value)
+{
+ ViewLayerLightgroup *lightgroup = (ViewLayerLightgroup *)ptr->data;
+ BLI_strncpy(value, lightgroup->name, sizeof(lightgroup->name));
+}
+
+static int rna_ViewLayerLightgroup_name_length(PointerRNA *ptr)
+{
+ ViewLayerLightgroup *lightgroup = (ViewLayerLightgroup *)ptr->data;
+ return strlen(lightgroup->name);
+}
+
+static void rna_ViewLayerLightgroup_name_set(PointerRNA *ptr, const char *value)
+{
+ ViewLayerLightgroup *lightgroup = (ViewLayerLightgroup *)ptr->data;
+ Scene *scene = (Scene *)ptr->owner_id;
+ ViewLayer *view_layer = BKE_view_layer_find_with_lightgroup(scene, lightgroup);
+
+ BKE_view_layer_rename_lightgroup(view_layer, lightgroup, value);
+}
+
/* Fake value, used internally (not saved to DNA). */
# define V3D_ORIENT_DEFAULT -1
@@ -4156,6 +4203,43 @@ static void rna_def_view_layer_aov(BlenderRNA *brna)
RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, "rna_ViewLayer_pass_update");
}
+static void rna_def_view_layer_lightgroups(BlenderRNA *brna, PropertyRNA *cprop)
+{
+ StructRNA *srna;
+ /* PropertyRNA *prop; */
+
+ FunctionRNA *func;
+ PropertyRNA *parm;
+
+ RNA_def_property_srna(cprop, "Lightgroups");
+ srna = RNA_def_struct(brna, "Lightgroups", NULL);
+ RNA_def_struct_sdna(srna, "ViewLayer");
+ RNA_def_struct_ui_text(srna, "List of Lightgroups", "Collection of Lightgroups");
+
+ func = RNA_def_function(srna, "add", "BKE_view_layer_add_lightgroup");
+ parm = RNA_def_pointer(func, "lightgroup", "Lightgroup", "", "Newly created Lightgroup");
+ RNA_def_function_return(func, parm);
+}
+
+static void rna_def_view_layer_lightgroup(BlenderRNA *brna)
+{
+ StructRNA *srna;
+ PropertyRNA *prop;
+ srna = RNA_def_struct(brna, "Lightgroup", NULL);
+ RNA_def_struct_sdna(srna, "ViewLayerLightgroup");
+ RNA_def_struct_ui_text(srna, "Light Group", "");
+
+ prop = RNA_def_property(srna, "name", PROP_STRING, PROP_NONE);
+ RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
+ RNA_def_property_string_funcs(prop,
+ "rna_ViewLayerLightgroup_name_get",
+ "rna_ViewLayerLightgroup_name_length",
+ "rna_ViewLayerLightgroup_name_set");
+ RNA_def_property_ui_text(prop, "Name", "Name of the Lightgroup");
+ RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, "rna_ViewLayer_pass_update");
+ RNA_def_struct_name_property(srna, prop);
+}
+
void rna_def_view_layer_common(BlenderRNA *brna, StructRNA *srna, const bool scene)
{
PropertyRNA *prop;
@@ -4226,6 +4310,25 @@ void rna_def_view_layer_common(BlenderRNA *brna, StructRNA *srna, const bool sce
RNA_def_property_ui_text(prop, "Active AOV Index", "Index of active aov");
RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL);
+ prop = RNA_def_property(srna, "lightgroups", PROP_COLLECTION, PROP_NONE);
+ RNA_def_property_collection_sdna(prop, NULL, "lightgroups", NULL);
+ RNA_def_property_struct_type(prop, "Lightgroup");
+ RNA_def_property_ui_text(prop, "Light Groups", "");
+ rna_def_view_layer_lightgroups(brna, prop);
+
+ prop = RNA_def_property(srna, "active_lightgroup", PROP_POINTER, PROP_NONE);
+ RNA_def_property_struct_type(prop, "Lightgroup");
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+ RNA_def_property_ui_text(prop, "Light Groups", "Active Lightgroup");
+
+ prop = RNA_def_property(srna, "active_lightgroup_index", PROP_INT, PROP_UNSIGNED);
+ RNA_def_property_int_funcs(prop,
+ "rna_ViewLayer_active_lightgroup_index_get",
+ "rna_ViewLayer_active_lightgroup_index_set",
+ "rna_ViewLayer_active_lightgroup_index_range");
+ RNA_def_property_ui_text(prop, "Active Lightgroup Index", "Index of active lightgroup");
+ RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL);
+
prop = RNA_def_property(srna, "use_pass_cryptomatte_object", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "cryptomatte_flag", VIEW_LAYER_CRYPTOMATTE_OBJECT);
RNA_def_property_ui_text(
@@ -8088,6 +8191,7 @@ void RNA_def_scene(BlenderRNA *brna)
rna_def_scene_display(brna);
rna_def_scene_eevee(brna);
rna_def_view_layer_aov(brna);
+ rna_def_view_layer_lightgroup(brna);
rna_def_view_layer_eevee(brna);
rna_def_scene_gpencil(brna);
RNA_define_animate_sdna(true);
diff --git a/source/blender/makesrna/intern/rna_world.c b/source/blender/makesrna/intern/rna_world.c
index 04008665342..d1049eef2c7 100644
--- a/source/blender/makesrna/intern/rna_world.c
+++ b/source/blender/makesrna/intern/rna_world.c
@@ -22,6 +22,7 @@
# include "MEM_guardedalloc.h"
# include "BKE_context.h"
+# include "BKE_layer.h"
# include "BKE_main.h"
# include "BKE_texture.h"
@@ -84,6 +85,21 @@ static void rna_World_use_nodes_update(bContext *C, PointerRNA *ptr)
rna_World_draw_update(bmain, scene, ptr);
}
+void rna_World_lightgroup_get(PointerRNA *ptr, char *value)
+{
+ BKE_lightgroup_membership_get(((World *)ptr->owner_id)->lightgroup, value);
+}
+
+int rna_World_lightgroup_length(PointerRNA *ptr)
+{
+ return BKE_lightgroup_membership_length(((World *)ptr->owner_id)->lightgroup);
+}
+
+void rna_World_lightgroup_set(PointerRNA *ptr, const char *value)
+{
+ BKE_lightgroup_membership_set(&((World *)ptr->owner_id)->lightgroup, value);
+}
+
#else
static void rna_def_lighting(BlenderRNA *brna)
@@ -234,6 +250,13 @@ void RNA_def_world(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Use Nodes", "Use shader nodes to render the world");
RNA_def_property_update(prop, 0, "rna_World_use_nodes_update");
+ /* Lightgroup Membership */
+ prop = RNA_def_property(srna, "lightgroup", PROP_STRING, PROP_NONE);
+ RNA_def_property_string_funcs(
+ prop, "rna_World_lightgroup_get", "rna_World_lightgroup_length", "rna_World_lightgroup_set");
+ RNA_def_property_flag(prop, PROP_EDITABLE);
+ RNA_def_property_ui_text(prop, "Lightgroup", "Lightgroup that the world belongs to");
+
rna_def_lighting(brna);
rna_def_world_mist(brna);
}