diff options
author | Dilith Jayakody <dilithjay@gmail.com> | 2022-04-03 05:38:54 +0300 |
---|---|---|
committer | Dilith Jayakody <dilithjay@gmail.com> | 2022-04-03 05:38:54 +0300 |
commit | bb44667a2e8f9c91548a574443e750583918e996 (patch) | |
tree | 12347d0a95971a9b7cd7d11786ccc2f948b214c6 | |
parent | 2579367c93296eb2ab1da0b51dc107287dc09fd3 (diff) | |
parent | 79ff65d07bac0ecf0170542f86dc03a0228b53d5 (diff) |
Merge branch 'master' into soc-2021-curvessoc-2021-curves
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, ®ion->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, ®ion->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, ®ion->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, ®ion->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 = ®ion->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, ®ion->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, ®ion->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); } |