diff options
author | Ray Molenkamp <github@lazydodo.com> | 2022-11-10 22:03:13 +0300 |
---|---|---|
committer | Ray Molenkamp <github@lazydodo.com> | 2022-11-10 22:03:13 +0300 |
commit | 140a83e2023041fed7e48028faf0f1d3e3faf0fc (patch) | |
tree | f7633b780dc6c3897f0879392fd564feee668b58 | |
parent | 24bd098dbaf8d26511cb416badb8489d1fcfe00b (diff) | |
parent | 366796bbbe71c246ad436da07a721f2a8deafe5c (diff) |
Merge remote-tracking branch 'origin/master' into tmp-vfx-platform-2023
47 files changed, 672 insertions, 486 deletions
diff --git a/intern/cycles/blender/addon/engine.py b/intern/cycles/blender/addon/engine.py index 83dc6332f47..4ac078ed8a5 100644 --- a/intern/cycles/blender/addon/engine.py +++ b/intern/cycles/blender/addon/engine.py @@ -155,6 +155,7 @@ def with_osl(): import _cycles return _cycles.with_osl + def osl_version(): import _cycles return _cycles.osl_version diff --git a/intern/cycles/blender/addon/operators.py b/intern/cycles/blender/addon/operators.py index ab474cda0ab..3680d11359e 100644 --- a/intern/cycles/blender/addon/operators.py +++ b/intern/cycles/blender/addon/operators.py @@ -114,7 +114,7 @@ class CYCLES_OT_denoise_animation(Operator): class CYCLES_OT_merge_images(Operator): - "Combine OpenEXR multilayer images rendered with different sample " \ + "Combine OpenEXR multi-layer images rendered with different sample " \ "ranges into one image with reduced noise" bl_idname = "cycles.merge_images" bl_label = "Merge Images" diff --git a/intern/cycles/blender/addon/ui.py b/intern/cycles/blender/addon/ui.py index 11fa2bc62fb..10a37688f45 100644 --- a/intern/cycles/blender/addon/ui.py +++ b/intern/cycles/blender/addon/ui.py @@ -2305,7 +2305,10 @@ def draw_device(self, context): col.prop(cscene, "device") from . import engine - if engine.with_osl() and (use_cpu(context) or (use_optix(context) and (engine.osl_version()[1] >= 13 or engine.osl_version()[0] > 1))): + if engine.with_osl() and ( + use_cpu(context) or + (use_optix(context) and (engine.osl_version()[1] >= 13 or engine.osl_version()[0] > 1)) + ): col.prop(cscene, "shading_system") diff --git a/intern/cycles/kernel/osl/services.cpp b/intern/cycles/kernel/osl/services.cpp index 454b75ea4d9..3fd098de4bb 100644 --- a/intern/cycles/kernel/osl/services.cpp +++ b/intern/cycles/kernel/osl/services.cpp @@ -1176,9 +1176,10 @@ TextureSystem::TextureHandle *OSLRenderServices::get_texture_handle(ustring file return (TextureSystem::TextureHandle *)it->second.get(); } else { - if (it != textures.end() && it->second->type == OSLTextureHandle::SVM && it->second->svm_slots[0].w == -1) { - return reinterpret_cast<TextureSystem::TextureHandle *>( - static_cast<uintptr_t>(it->second->svm_slots[0].y + 1)); + if (it != textures.end() && it->second->type == OSLTextureHandle::SVM && + it->second->svm_slots[0].w == -1) { + return reinterpret_cast<TextureSystem::TextureHandle *>( + static_cast<uintptr_t>(it->second->svm_slots[0].y + 1)); } return NULL; diff --git a/intern/cycles/scene/osl.cpp b/intern/cycles/scene/osl.cpp index 3ea406b6935..4dc5fb4edf7 100644 --- a/intern/cycles/scene/osl.cpp +++ b/intern/cycles/scene/osl.cpp @@ -641,6 +641,8 @@ string OSLCompiler::id(ShaderNode *node) { /* assign layer unique name based on pointer address + bump mode */ stringstream stream; + stream.imbue(std::locale("C")); /* Ensure that no grouping characters (e.g. commas with en_US + locale) are added to the pointer string */ stream << "node_" << node->type->name << "_" << node; return stream.str(); @@ -1132,12 +1134,12 @@ OSL::ShaderGroupRef OSLCompiler::compile_type(Shader *shader, ShaderGraph *graph { current_type = type; - string name = shader->name.string(); - /* Replace invalid characters. */ - for (size_t i; (i = name.find_first_of(" .,:;+-*/#")) != string::npos;) - name.replace(i, 1, "_"); + /* Use name hash to identify shader group to avoid issues with non-alphanumeric characters */ + stringstream name; + name.imbue(std::locale("C")); + name << "shader_" << shader->name.hash(); - OSL::ShaderGroupRef group = ss->ShaderGroupBegin(name); + OSL::ShaderGroupRef group = ss->ShaderGroupBegin(name.str()); ShaderNode *output = graph->output(); ShaderNodeSet dependencies; diff --git a/intern/cycles/session/merge.h b/intern/cycles/session/merge.h index 702ca5c3eb8..d8a4f04a27b 100644 --- a/intern/cycles/session/merge.h +++ b/intern/cycles/session/merge.h @@ -9,7 +9,7 @@ CCL_NAMESPACE_BEGIN -/* Merge OpenEXR multilayer renders. */ +/* Merge OpenEXR multi-layer renders. */ class ImageMerger { public: diff --git a/intern/ghost/intern/GHOST_SystemWayland.cpp b/intern/ghost/intern/GHOST_SystemWayland.cpp index a2028de6f53..528aa6e1884 100644 --- a/intern/ghost/intern/GHOST_SystemWayland.cpp +++ b/intern/ghost/intern/GHOST_SystemWayland.cpp @@ -1157,6 +1157,18 @@ static void gwl_registry_entry_update_all(GWL_Display *display, const int interf /** \name Private Utility Functions * \{ */ +static void ghost_wl_display_report_error(struct wl_display *display) +{ + int ecode = wl_display_get_error(display); + GHOST_ASSERT(ecode, "Error not set!"); + if ((ecode == EPIPE || ecode == ECONNRESET)) { + fprintf(stderr, "The Wayland connection broke. Did the Wayland compositor die?\n"); + } + else { + fprintf(stderr, "The Wayland connection experienced a fatal error: %s\n", strerror(ecode)); + } +} + /** * Callback for WAYLAND to run when there is an error. * @@ -4985,6 +4997,42 @@ static const struct wl_registry_listener registry_listener = { /** \} */ /* -------------------------------------------------------------------- */ +/** \name Listener (Display), #wl_display_listener + * \{ */ + +static CLG_LogRef LOG_WL_DISPLAY = {"ghost.wl.handle.display"}; +#define LOG (&LOG_WL_DISPLAY) + +static void display_handle_error( + void *data, struct wl_display *wl_display, void *object_id, uint32_t code, const char *message) +{ + GWL_Display *display = static_cast<GWL_Display *>(data); + GHOST_ASSERT(display->wl_display == wl_display, "Invalid internal state"); + (void)display; + + /* NOTE: code is #wl_display_error, there isn't a convenient way to convert to an ID. */ + CLOG_INFO(LOG, 2, "error (code=%u, object_id=%p, message=%s)", code, object_id, message); +} + +static void display_handle_delete_id(void *data, struct wl_display *wl_display, uint32_t id) +{ + GWL_Display *display = static_cast<GWL_Display *>(data); + GHOST_ASSERT(display->wl_display == wl_display, "Invalid internal state"); + (void)display; + + CLOG_INFO(LOG, 2, "delete_id (id=%u)", id); +} + +static const struct wl_display_listener display_listener = { + display_handle_error, + display_handle_delete_id, +}; + +#undef LOG + +/** \} */ + +/* -------------------------------------------------------------------- */ /** \name GHOST Implementation * * WAYLAND specific implementation of the #GHOST_System interface. @@ -5006,6 +5054,8 @@ GHOST_SystemWayland::GHOST_SystemWayland(bool background) /* This may be removed later if decorations are required, needed as part of registration. */ display_->xdg_decor = new GWL_XDG_Decor_System; + wl_display_add_listener(display_->wl_display, &display_listener, display_); + /* Register interfaces. */ { display_->registry_skip_update_all = true; @@ -5114,10 +5164,14 @@ bool GHOST_SystemWayland::processEvents(bool waitForEvent) #endif /* WITH_INPUT_NDOF */ if (waitForEvent) { - wl_display_dispatch(display_->wl_display); + if (wl_display_dispatch(display_->wl_display) == -1) { + ghost_wl_display_report_error(display_->wl_display); + } } else { - wl_display_roundtrip(display_->wl_display); + if (wl_display_roundtrip(display_->wl_display) == -1) { + ghost_wl_display_report_error(display_->wl_display); + } } if (getEventManager()->getNumEvents() > 0) { diff --git a/intern/ghost/intern/GHOST_WindowWayland.cpp b/intern/ghost/intern/GHOST_WindowWayland.cpp index ad94a02b514..9d62c69edef 100644 --- a/intern/ghost/intern/GHOST_WindowWayland.cpp +++ b/intern/ghost/intern/GHOST_WindowWayland.cpp @@ -219,7 +219,7 @@ static void xdg_toplevel_handle_close(void *data, xdg_toplevel * /*xdg_toplevel* static_cast<GWL_Window *>(data)->ghost_window->close(); } -static const xdg_toplevel_listener toplevel_listener = { +static const xdg_toplevel_listener xdg_toplevel_listener = { xdg_toplevel_handle_configure, xdg_toplevel_handle_close, }; @@ -322,7 +322,7 @@ static void xdg_toplevel_decoration_handle_configure( static_cast<GWL_Window *>(data)->xdg_decor->mode = (zxdg_toplevel_decoration_v1_mode)mode; } -static const zxdg_toplevel_decoration_v1_listener toplevel_decoration_v1_listener = { +static const zxdg_toplevel_decoration_v1_listener xdg_toplevel_decoration_v1_listener = { xdg_toplevel_decoration_handle_configure, }; @@ -418,7 +418,7 @@ static void surface_handle_leave(void *data, } } -static struct wl_surface_listener wl_surface_listener = { +static const struct wl_surface_listener wl_surface_listener = { surface_handle_enter, surface_handle_leave, }; @@ -483,7 +483,7 @@ GHOST_WindowWayland::GHOST_WindowWayland(GHOST_SystemWayland *system, wl_surface_set_buffer_scale(window_->wl_surface, window_->scale); - wl_surface_add_listener(window_->wl_surface, &wl_surface_listener, this); + wl_surface_add_listener(window_->wl_surface, &wl_surface_listener, window_); window_->egl_window = wl_egl_window_create( window_->wl_surface, int(window_->size[0]), int(window_->size[1])); @@ -537,13 +537,13 @@ GHOST_WindowWayland::GHOST_WindowWayland(GHOST_SystemWayland *system, decor.toplevel_decor = zxdg_decoration_manager_v1_get_toplevel_decoration( system_->xdg_decor_manager(), decor.toplevel); zxdg_toplevel_decoration_v1_add_listener( - decor.toplevel_decor, &toplevel_decoration_v1_listener, window_); + decor.toplevel_decor, &xdg_toplevel_decoration_v1_listener, window_); zxdg_toplevel_decoration_v1_set_mode(decor.toplevel_decor, ZXDG_TOPLEVEL_DECORATION_V1_MODE_SERVER_SIDE); } xdg_surface_add_listener(decor.surface, &xdg_surface_listener, window_); - xdg_toplevel_add_listener(decor.toplevel, &toplevel_listener, window_); + xdg_toplevel_add_listener(decor.toplevel, &xdg_toplevel_listener, window_); if (parentWindow && is_dialog) { WGL_XDG_Decor_Window &decor_parent = diff --git a/intern/wayland_dynload/extern/wayland_dynload_client.h b/intern/wayland_dynload/extern/wayland_dynload_client.h index d80ef5c9f0c..bf1e2f89c18 100644 --- a/intern/wayland_dynload/extern/wayland_dynload_client.h +++ b/intern/wayland_dynload/extern/wayland_dynload_client.h @@ -16,6 +16,7 @@ WAYLAND_DYNLOAD_FN(wl_display_disconnect) WAYLAND_DYNLOAD_FN(wl_display_dispatch) WAYLAND_DYNLOAD_FN(wl_display_roundtrip) WAYLAND_DYNLOAD_FN(wl_display_flush) +WAYLAND_DYNLOAD_FN(wl_display_get_error) WAYLAND_DYNLOAD_FN(wl_log_set_handler_client) WAYLAND_DYNLOAD_FN(wl_proxy_add_listener) WAYLAND_DYNLOAD_FN(wl_proxy_destroy) @@ -68,6 +69,7 @@ struct WaylandDynload_Client { int WL_DYN_FN(wl_display_dispatch)(struct wl_display *display); int WL_DYN_FN(wl_display_roundtrip)(struct wl_display *display); int WL_DYN_FN(wl_display_flush)(struct wl_display *display); + int WL_DYN_FN(wl_display_get_error)(struct wl_display *display); void WL_DYN_FN(wl_log_set_handler_client)(wl_log_func_t); int WL_DYN_FN(wl_proxy_add_listener)(struct wl_proxy *proxy, void (**implementation)(void), @@ -103,6 +105,7 @@ struct WaylandDynload_Client { # define wl_display_dispatch(...) (*wayland_dynload_client.wl_display_dispatch)(__VA_ARGS__) # define wl_display_roundtrip(...) (*wayland_dynload_client.wl_display_roundtrip)(__VA_ARGS__) # define wl_display_flush(...) (*wayland_dynload_client.wl_display_flush)(__VA_ARGS__) +# define wl_display_get_error(...) (*wayland_dynload_client.wl_display_get_error)(__VA_ARGS__) # define wl_log_set_handler_client(...) \ (*wayland_dynload_client.wl_log_set_handler_client)(__VA_ARGS__) # define wl_proxy_add_listener(...) \ diff --git a/release/scripts/startup/bl_ui/space_nla.py b/release/scripts/startup/bl_ui/space_nla.py index a1c7e5c54de..b43434d9988 100644 --- a/release/scripts/startup/bl_ui/space_nla.py +++ b/release/scripts/startup/bl_ui/space_nla.py @@ -310,6 +310,11 @@ class NLA_MT_context_menu(Menu): layout.separator() + layout.operator("nla.meta_add") + layout.operator("nla.meta_remove") + + layout.separator() + layout.operator("nla.swap") layout.separator() diff --git a/release/scripts/startup/bl_ui/space_view3d.py b/release/scripts/startup/bl_ui/space_view3d.py index 947f9056df7..7e0f41f7c86 100644 --- a/release/scripts/startup/bl_ui/space_view3d.py +++ b/release/scripts/startup/bl_ui/space_view3d.py @@ -3212,11 +3212,11 @@ class VIEW3D_MT_sculpt(Menu): props.action = 'SHOW' props.area = 'ALL' - props = layout.operator("paint.hide_show", text="Show Bounding Box") + props = layout.operator("paint.hide_show", text="Box Show") props.action = 'SHOW' props.area = 'INSIDE' - props = layout.operator("paint.hide_show", text="Hide Bounding Box") + props = layout.operator("paint.hide_show", text="Box Hide") props.action = 'HIDE' props.area = 'INSIDE' diff --git a/release/scripts/startup/bl_ui/space_view3d_toolbar.py b/release/scripts/startup/bl_ui/space_view3d_toolbar.py index 111fb0d8bae..8ebc385a8ee 100644 --- a/release/scripts/startup/bl_ui/space_view3d_toolbar.py +++ b/release/scripts/startup/bl_ui/space_view3d_toolbar.py @@ -1020,6 +1020,7 @@ class VIEW3D_PT_sculpt_symmetry(Panel, View3DPaintPanel): layout.prop(sculpt, "symmetrize_direction") layout.operator("sculpt.symmetrize") + layout.prop(WindowManager.operator_properties_last("sculpt.symmetrize"), "merge_tolerance") class VIEW3D_PT_sculpt_symmetry_for_topbar(Panel): diff --git a/source/blender/blenkernel/BKE_curves_utils.hh b/source/blender/blenkernel/BKE_curves_utils.hh index c8ca24b756a..1e06cb2d4c7 100644 --- a/source/blender/blenkernel/BKE_curves_utils.hh +++ b/source/blender/blenkernel/BKE_curves_utils.hh @@ -69,11 +69,11 @@ struct CurvePoint : public CurveSegment { /** * Cyclical index range. Allows iteration over a plain 'IndexRange' interval on form [start, end) * while also supporting treating the underlying array as a cyclic array where the last index is - * followed by the first nidex in the 'cyclical' range. The cyclical index range can then be + * followed by the first index in the 'cyclical' range. The cyclical index range can then be * considered a combination of the intervals separated by the last index of the underlying array, * namely [start, range_size) and [0, end) where start/end is the indices iterated between and * range_size is the size of the underlying array. To cycle the underlying array the interval - * [0, range_size) can be iterated over an arbitrary amount of times inbetween. + * [0, range_size) can be iterated over an arbitrary amount of times in between. */ class IndexRangeCyclic { /* Index to the start and end of the iterated range. diff --git a/source/blender/blenkernel/BKE_fcurve.h b/source/blender/blenkernel/BKE_fcurve.h index cbdf37e14bd..b4de24e3b64 100644 --- a/source/blender/blenkernel/BKE_fcurve.h +++ b/source/blender/blenkernel/BKE_fcurve.h @@ -167,7 +167,7 @@ void set_active_fmodifier(ListBase *modifiers, struct FModifier *fcm); * \param mtype: Type of modifier (if 0, doesn't matter). * \param acttype: Type of action to perform (if -1, doesn't matter). */ -bool list_has_suitable_fmodifier(ListBase *modifiers, int mtype, short acttype); +bool list_has_suitable_fmodifier(const ListBase *modifiers, int mtype, short acttype); typedef struct FModifiersStackStorage { uint modifier_count; @@ -369,12 +369,12 @@ int BKE_fcurve_pathcache_find_array(struct FCurvePathCache *fcache, * Calculate the extents of F-Curve's keyframes. */ bool BKE_fcurve_calc_range( - struct FCurve *fcu, float *min, float *max, bool do_sel_only, bool do_min_length); + const struct FCurve *fcu, float *min, float *max, bool do_sel_only, bool do_min_length); /** * Calculate the extents of F-Curve's data. */ -bool BKE_fcurve_calc_bounds(struct FCurve *fcu, +bool BKE_fcurve_calc_bounds(const struct FCurve *fcu, float *xmin, float *xmax, float *ymin, @@ -421,14 +421,14 @@ void BKE_fcurve_keyframe_move_value_with_handles(struct BezTriple *keyframe, flo * Usability of keyframes refers to whether they should be displayed, * and also whether they will have any influence on the final result. */ -bool BKE_fcurve_are_keyframes_usable(struct FCurve *fcu); +bool BKE_fcurve_are_keyframes_usable(const struct FCurve *fcu); /** * Can keyframes be added to F-Curve? * Keyframes can only be added if they are already visible. */ -bool BKE_fcurve_is_keyframable(struct FCurve *fcu); -bool BKE_fcurve_is_protected(struct FCurve *fcu); +bool BKE_fcurve_is_keyframable(const struct FCurve *fcu); +bool BKE_fcurve_is_protected(const struct FCurve *fcu); /** * Are any of the keyframe control points selected on the F-Curve? @@ -439,7 +439,7 @@ bool BKE_fcurve_has_selected_control_points(const struct FCurve *fcu); * Checks if the F-Curve has a Cycles modifier with simple settings * that warrant transition smoothing. */ -bool BKE_fcurve_is_cyclic(struct FCurve *fcu); +bool BKE_fcurve_is_cyclic(const struct FCurve *fcu); /* Type of infinite cycle for a curve. */ typedef enum eFCU_Cycle_Type { @@ -453,7 +453,7 @@ typedef enum eFCU_Cycle_Type { /** * Checks if the F-Curve has a Cycles modifier, and returns the type of the cycle behavior. */ -eFCU_Cycle_Type BKE_fcurve_get_cycle_type(struct FCurve *fcu); +eFCU_Cycle_Type BKE_fcurve_get_cycle_type(const struct FCurve *fcu); /** * Recompute bezier handles of all three given BezTriples, so that `bezt` can be inserted between @@ -544,7 +544,7 @@ float evaluate_fcurve_driver(struct PathResolvedRNA *anim_rna, /** * Checks if the curve has valid keys, drivers or modifiers that produce an actual curve. */ -bool BKE_fcurve_is_empty(struct FCurve *fcu); +bool BKE_fcurve_is_empty(const struct FCurve *fcu); /** * Calculate the value of the given F-Curve at the given frame, * and store it's value in #FCurve.curval. diff --git a/source/blender/blenkernel/BKE_paint.h b/source/blender/blenkernel/BKE_paint.h index 9fc4aa5307d..434255b2d9c 100644 --- a/source/blender/blenkernel/BKE_paint.h +++ b/source/blender/blenkernel/BKE_paint.h @@ -119,6 +119,7 @@ typedef enum ePaintSymmetryAreas { PAINT_SYMM_AREA_Y = (1 << 1), PAINT_SYMM_AREA_Z = (1 << 2), } ePaintSymmetryAreas; +ENUM_OPERATORS(ePaintSymmetryAreas, PAINT_SYMM_AREA_Z); #define PAINT_SYMM_AREAS 8 diff --git a/source/blender/blenkernel/BKE_pbvh.h b/source/blender/blenkernel/BKE_pbvh.h index b375d69b61c..4badd1bc269 100644 --- a/source/blender/blenkernel/BKE_pbvh.h +++ b/source/blender/blenkernel/BKE_pbvh.h @@ -416,6 +416,8 @@ typedef enum { PBVH_Subdivide = 1, PBVH_Collapse = 2, } PBVHTopologyUpdateMode; +ENUM_OPERATORS(PBVHTopologyUpdateMode, PBVH_Collapse); + /** * Collapse short edges, subdivide long edges. */ diff --git a/source/blender/blenkernel/intern/fcurve.c b/source/blender/blenkernel/intern/fcurve.c index d248faaab00..aa99a5f605a 100644 --- a/source/blender/blenkernel/intern/fcurve.c +++ b/source/blender/blenkernel/intern/fcurve.c @@ -571,7 +571,7 @@ int BKE_fcurve_bezt_binarysearch_index(const BezTriple array[], /* ...................................... */ /* Helper for calc_fcurve_* functions -> find first and last BezTriple to be used. */ -static short get_fcurve_end_keyframes(FCurve *fcu, +static short get_fcurve_end_keyframes(const FCurve *fcu, BezTriple **first, BezTriple **last, const bool do_sel_only) @@ -621,7 +621,7 @@ static short get_fcurve_end_keyframes(FCurve *fcu, return found; } -bool BKE_fcurve_calc_bounds(FCurve *fcu, +bool BKE_fcurve_calc_bounds(const FCurve *fcu, float *xmin, float *xmax, float *ymin, @@ -752,7 +752,7 @@ bool BKE_fcurve_calc_bounds(FCurve *fcu, } bool BKE_fcurve_calc_range( - FCurve *fcu, float *start, float *end, const bool do_sel_only, const bool do_min_length) + const FCurve *fcu, float *start, float *end, const bool do_sel_only, const bool do_min_length) { float min = 999999999.0f, max = -999999999.0f; bool foundvert = false; @@ -900,7 +900,7 @@ void BKE_fcurve_keyframe_move_value_with_handles(struct BezTriple *keyframe, con /** \name Status Checks * \{ */ -bool BKE_fcurve_are_keyframes_usable(FCurve *fcu) +bool BKE_fcurve_are_keyframes_usable(const FCurve *fcu) { /* F-Curve must exist. */ if (fcu == NULL) { @@ -960,7 +960,7 @@ bool BKE_fcurve_are_keyframes_usable(FCurve *fcu) return true; } -bool BKE_fcurve_is_protected(FCurve *fcu) +bool BKE_fcurve_is_protected(const FCurve *fcu) { return ((fcu->flag & FCURVE_PROTECTED) || ((fcu->grp) && (fcu->grp->flag & AGRP_PROTECTED))); } @@ -977,7 +977,7 @@ bool BKE_fcurve_has_selected_control_points(const FCurve *fcu) return false; } -bool BKE_fcurve_is_keyframable(FCurve *fcu) +bool BKE_fcurve_is_keyframable(const FCurve *fcu) { /* F-Curve's keyframes must be "usable" (i.e. visible + have an effect on final result) */ if (BKE_fcurve_are_keyframes_usable(fcu) == 0) { @@ -1168,7 +1168,7 @@ void fcurve_samples_to_keyframes(FCurve *fcu, const int start, const int end) * that the handles are correct. */ -eFCU_Cycle_Type BKE_fcurve_get_cycle_type(FCurve *fcu) +eFCU_Cycle_Type BKE_fcurve_get_cycle_type(const FCurve *fcu) { FModifier *fcm = fcu->modifiers.first; @@ -1201,7 +1201,7 @@ eFCU_Cycle_Type BKE_fcurve_get_cycle_type(FCurve *fcu) return FCU_CYCLE_NONE; } -bool BKE_fcurve_is_cyclic(FCurve *fcu) +bool BKE_fcurve_is_cyclic(const FCurve *fcu) { return BKE_fcurve_get_cycle_type(fcu) != FCU_CYCLE_NONE; } @@ -2207,7 +2207,7 @@ float evaluate_fcurve_driver(PathResolvedRNA *anim_rna, return evaluate_fcurve_ex(fcu, evaltime, cvalue); } -bool BKE_fcurve_is_empty(FCurve *fcu) +bool BKE_fcurve_is_empty(const FCurve *fcu) { return (fcu->totvert == 0) && (fcu->driver == NULL) && !list_has_suitable_fmodifier(&fcu->modifiers, 0, FMI_TYPE_GENERATE_CURVE); diff --git a/source/blender/blenkernel/intern/fmodifier.c b/source/blender/blenkernel/intern/fmodifier.c index 551bab75d4b..46dc01edbff 100644 --- a/source/blender/blenkernel/intern/fmodifier.c +++ b/source/blender/blenkernel/intern/fmodifier.c @@ -1283,7 +1283,7 @@ void set_active_fmodifier(ListBase *modifiers, FModifier *fcm) } } -bool list_has_suitable_fmodifier(ListBase *modifiers, int mtype, short acttype) +bool list_has_suitable_fmodifier(const ListBase *modifiers, int mtype, short acttype) { FModifier *fcm; diff --git a/source/blender/blenkernel/intern/pbvh_bmesh.c b/source/blender/blenkernel/intern/pbvh_bmesh.c index 3b0f35263d3..d03f12b98bd 100644 --- a/source/blender/blenkernel/intern/pbvh_bmesh.c +++ b/source/blender/blenkernel/intern/pbvh_bmesh.c @@ -1527,8 +1527,8 @@ bool pbvh_bmesh_node_raycast(PBVHNode *node, float location[3] = {0.0f}; madd_v3_v3v3fl(location, ray_start, ray_normal, *depth); for (int j = 0; j < 3; j++) { - if (len_squared_v3v3(location, cos[j]) < - len_squared_v3v3(location, nearest_vertex_co)) { + if (j == 0 || len_squared_v3v3(location, cos[j]) < + len_squared_v3v3(location, nearest_vertex_co)) { copy_v3_v3(nearest_vertex_co, cos[j]); r_active_vertex->i = (intptr_t)node->bm_orvert[node->bm_ortri[i][j]]; } @@ -1559,8 +1559,8 @@ bool pbvh_bmesh_node_raycast(PBVHNode *node, float location[3] = {0.0f}; madd_v3_v3v3fl(location, ray_start, ray_normal, *depth); for (int j = 0; j < 3; j++) { - if (len_squared_v3v3(location, v_tri[j]->co) < - len_squared_v3v3(location, nearest_vertex_co)) { + if (j == 0 || len_squared_v3v3(location, v_tri[j]->co) < + len_squared_v3v3(location, nearest_vertex_co)) { copy_v3_v3(nearest_vertex_co, v_tri[j]->co); r_active_vertex->i = (intptr_t)v_tri[j]; } diff --git a/source/blender/blenloader/intern/versioning_260.c b/source/blender/blenloader/intern/versioning_260.c index cdb63bd8075..47a1f7f7241 100644 --- a/source/blender/blenloader/intern/versioning_260.c +++ b/source/blender/blenloader/intern/versioning_260.c @@ -280,10 +280,9 @@ static void do_versions_nodetree_multi_file_output_format_2_62_1(Scene *sce, bNo BLI_strncpy(filename, old_image->name, sizeof(filename)); } - /* if z buffer is saved, change the image type to multilayer exr. - * XXX this is slightly messy, Z buffer was ignored before for anything but EXR and IRIS ... - * I'm just assuming here that IRIZ means IRIS with z buffer ... - */ + /* If Z buffer is saved, change the image type to multi-layer EXR. + * XXX: this is slightly messy, Z buffer was ignored before for anything but EXR and IRIS ... + * I'm just assuming here that IRIZ means IRIS with z buffer. */ if (old_data && ELEM(old_data->im_format.imtype, R_IMF_IMTYPE_IRIZ, R_IMF_IMTYPE_OPENEXR)) { char sockpath[FILE_MAX]; @@ -393,9 +392,8 @@ static void do_versions_nodetree_file_output_layers_2_64_5(bNodeTree *ntree) for (sock = node->inputs.first; sock; sock = sock->next) { NodeImageMultiFileSocket *input = sock->storage; - /* multilayer names are stored as separate strings now, - * used the path string before, so copy it over. - */ + /* Multi-layer names are stored as separate strings now, + * used the path string before, so copy it over. */ BLI_strncpy(input->layer, input->path, sizeof(input->layer)); /* paths/layer names also have to be unique now, initial check */ diff --git a/source/blender/compositor/nodes/COM_OutputFileNode.cc b/source/blender/compositor/nodes/COM_OutputFileNode.cc index fc4270cc222..50989f73986 100644 --- a/source/blender/compositor/nodes/COM_OutputFileNode.cc +++ b/source/blender/compositor/nodes/COM_OutputFileNode.cc @@ -65,7 +65,7 @@ void OutputFileNode::convert_to_operations(NodeConverter &converter, if (storage->format.imtype == R_IMF_IMTYPE_MULTILAYER) { const bool use_half_float = (storage->format.depth == R_IMF_CHAN_DEPTH_16); - /* single output operation for the multilayer file */ + /* Single output operation for the multi-layer file. */ OutputOpenExrMultiLayerOperation *output_operation; if (is_multiview && storage->format.views_format == R_IMF_VIEWS_MULTIVIEW) { diff --git a/source/blender/compositor/operations/COM_MovieDistortionOperation.cc b/source/blender/compositor/operations/COM_MovieDistortionOperation.cc index b89a48f2a39..353f3da14d7 100644 --- a/source/blender/compositor/operations/COM_MovieDistortionOperation.cc +++ b/source/blender/compositor/operations/COM_MovieDistortionOperation.cc @@ -78,34 +78,41 @@ void MovieDistortionOperation::execute_pixel_sampled(float output[4], float y, PixelSampler /*sampler*/) { - if (distortion_ != nullptr) { - /* float overscan = 0.0f; */ - const float pixel_aspect = pixel_aspect_; - const float w = float(this->get_width()) /* / (1 + overscan) */; - const float h = float(this->get_height()) /* / (1 + overscan) */; - const float aspx = w / float(calibration_width_); - const float aspy = h / float(calibration_height_); - float in[2]; - float out[2]; - - in[0] = (x /* - 0.5 * overscan * w */) / aspx; - in[1] = (y /* - 0.5 * overscan * h */) / aspy / pixel_aspect; + const int width = this->get_width(); + const int height = this->get_height(); + if (distortion_ == nullptr || width == 0 || height == 0) { + /* When there is no precomputed distortion pass-through the coordinate as-is to the input + * samples. + * If the frame size is zero do the same and bypass any math. In theory it is probably more + * correct to zero the output but it is easier and safe to let the input to do so than to deal + * with possible different number of channels here. */ + input_operation_->read_sampled(output, x, y, PixelSampler::Bilinear); + return; + } - if (apply_) { - BKE_tracking_distortion_undistort_v2(distortion_, in, out); - } - else { - BKE_tracking_distortion_distort_v2(distortion_, in, out); - } + /* float overscan = 0.0f; */ + const float w = float(width) /* / (1 + overscan) */; + const float h = float(height) /* / (1 + overscan) */; + const float pixel_aspect = pixel_aspect_; + const float aspx = w / float(calibration_width_); + const float aspy = h / float(calibration_height_); + float in[2]; + float out[2]; - float u = out[0] * aspx /* + 0.5 * overscan * w */, - v = (out[1] * aspy /* + 0.5 * overscan * h */) * pixel_aspect; + in[0] = (x /* - 0.5 * overscan * w */) / aspx; + in[1] = (y /* - 0.5 * overscan * h */) / aspy / pixel_aspect; - input_operation_->read_sampled(output, u, v, PixelSampler::Bilinear); + if (apply_) { + BKE_tracking_distortion_undistort_v2(distortion_, in, out); } else { - input_operation_->read_sampled(output, x, y, PixelSampler::Bilinear); + BKE_tracking_distortion_distort_v2(distortion_, in, out); } + + float u = out[0] * aspx /* + 0.5 * overscan * w */, + v = (out[1] * aspy /* + 0.5 * overscan * h */) * pixel_aspect; + + input_operation_->read_sampled(output, u, v, PixelSampler::Bilinear); } bool MovieDistortionOperation::determine_depending_area_of_interest( diff --git a/source/blender/compositor/operations/COM_OutputFileMultiViewOperation.h b/source/blender/compositor/operations/COM_OutputFileMultiViewOperation.h index e36999e5cf1..70773c1a559 100644 --- a/source/blender/compositor/operations/COM_OutputFileMultiViewOperation.h +++ b/source/blender/compositor/operations/COM_OutputFileMultiViewOperation.h @@ -31,7 +31,7 @@ class OutputOpenExrSingleLayerMultiViewOperation : public OutputSingleLayerOpera void deinit_execution() override; }; -/* Writes inputs into OpenEXR multilayer channels. */ +/** Writes inputs into OpenEXR multi-layer channels. */ class OutputOpenExrMultiLayerMultiViewOperation : public OutputOpenExrMultiLayerOperation { private: public: diff --git a/source/blender/compositor/operations/COM_OutputFileOperation.h b/source/blender/compositor/operations/COM_OutputFileOperation.h index df1d68838d9..716bede8035 100644 --- a/source/blender/compositor/operations/COM_OutputFileOperation.h +++ b/source/blender/compositor/operations/COM_OutputFileOperation.h @@ -71,7 +71,7 @@ struct OutputOpenExrLayer { SocketReader *image_input; }; -/* Writes inputs into OpenEXR multilayer channels. */ +/* Writes inputs into OpenEXR multi-layer channels. */ class OutputOpenExrMultiLayerOperation : public MultiThreadedOperation { protected: const Scene *scene_; diff --git a/source/blender/compositor/realtime_compositor/COM_scheduler.hh b/source/blender/compositor/realtime_compositor/COM_scheduler.hh index 4f778b32145..9f3bc14ae17 100644 --- a/source/blender/compositor/realtime_compositor/COM_scheduler.hh +++ b/source/blender/compositor/realtime_compositor/COM_scheduler.hh @@ -16,6 +16,6 @@ using Schedule = VectorSet<DNode>; /* Computes the execution schedule of the node tree. This is essentially a post-order depth first * traversal of the node tree from the output node to the leaf input nodes, with informed order of * traversal of dependencies based on a heuristic estimation of the number of needed buffers. */ -Schedule compute_schedule(DerivedNodeTree &tree); +Schedule compute_schedule(const DerivedNodeTree &tree); } // namespace blender::realtime_compositor diff --git a/source/blender/compositor/realtime_compositor/intern/scheduler.cc b/source/blender/compositor/realtime_compositor/intern/scheduler.cc index ac5cc55a73f..0d3cce7af39 100644 --- a/source/blender/compositor/realtime_compositor/intern/scheduler.cc +++ b/source/blender/compositor/realtime_compositor/intern/scheduler.cc @@ -8,6 +8,7 @@ #include "NOD_derived_node_tree.hh" +#include "BKE_node.h" #include "BKE_node_runtime.hh" #include "COM_scheduler.hh" @@ -17,36 +18,103 @@ namespace blender::realtime_compositor { using namespace nodes::derived_node_tree_types; -/* Compute the output node whose result should be computed. The output node is the node marked as - * NODE_DO_OUTPUT. If multiple types of output nodes are marked, then the preference will be - * CMP_NODE_COMPOSITE > CMP_NODE_VIEWER > CMP_NODE_SPLITVIEWER. If no output node exists, a null - * node will be returned. */ -static DNode compute_output_node(DerivedNodeTree &tree) +/* Find the active context from the given context and its descendants contexts. The active context + * is the one whose node instance key matches the active_viewer_key stored in the root node tree. + * The instance key of each context is computed by calling BKE_node_instance_key given the key of + * the parent as well as the group node making the context. */ +static const DTreeContext *find_active_context_recursive(const DTreeContext *context, + bNodeInstanceKey key) { - const bNodeTree &root_tree = tree.root_context().btree(); + /* The instance key of the given context matches the active viewer instance key, so this is the + * active context, return it. */ + if (key.value == context->derived_tree().root_context().btree().active_viewer_key.value) { + return context; + } + + /* For each of the group nodes, compute their instance key and contexts and call this function + * recursively. */ + for (const bNode *group_node : context->btree().group_nodes()) { + const bNodeInstanceKey child_key = BKE_node_instance_key(key, &context->btree(), group_node); + const DTreeContext *child_context = context->child_context(*group_node); + const DTreeContext *found_context = find_active_context_recursive(child_context, child_key); + + /* If the found context is null, that means neither the child context nor one of its descendant + * contexts is active. */ + if (!found_context) { + continue; + } + + /* Otherwise, we have found our active context, return it. */ + return found_context; + } + + /* Neither the given context nor one of its descendant contexts is active, so return null. */ + return nullptr; +} + +/* Find the active context for the given node tree. The active context represents the node tree + * currently being edited. In most cases, that would be the top level node tree itself, but in the + * case where the user is editing the node tree of a node group, the active context would be a + * representation of the node tree of that node group. Note that the context also stores the group + * node that the user selected to edit the node tree, so the context fully represents a particular + * instance of the node group. */ +static const DTreeContext *find_active_context(const DerivedNodeTree &tree) +{ + /* The root context has an instance key of NODE_INSTANCE_KEY_BASE by definition. */ + return find_active_context_recursive(&tree.root_context(), NODE_INSTANCE_KEY_BASE); +} + +/* Return the output node which is marked as NODE_DO_OUTPUT. If multiple types of output nodes are + * marked, then the preference will be CMP_NODE_COMPOSITE > CMP_NODE_VIEWER > CMP_NODE_SPLITVIEWER. + * If no output node exists, a null node will be returned. */ +static DNode find_output_in_context(const DTreeContext *context) +{ + const bNodeTree &tree = context->btree(); - for (const bNode *node : root_tree.nodes_by_type("CompositorNodeComposite")) { + for (const bNode *node : tree.nodes_by_type("CompositorNodeComposite")) { if (node->flag & NODE_DO_OUTPUT) { - return DNode(&tree.root_context(), node); + return DNode(context, node); } } - for (const bNode *node : root_tree.nodes_by_type("CompositorNodeViewer")) { + for (const bNode *node : tree.nodes_by_type("CompositorNodeViewer")) { if (node->flag & NODE_DO_OUTPUT) { - return DNode(&tree.root_context(), node); + return DNode(context, node); } } - for (const bNode *node : root_tree.nodes_by_type("CompositorNodeSplitViewer")) { + for (const bNode *node : tree.nodes_by_type("CompositorNodeSplitViewer")) { if (node->flag & NODE_DO_OUTPUT) { - return DNode(&tree.root_context(), node); + return DNode(context, node); } } - /* No output node found, return a null node. */ return DNode(); } +/* Compute the output node whose result should be computed. This node is the output node that + * satisfies the requirements in the find_output_in_context function. First, the active context is + * searched for an output node, if non was found, the root context is search. For more information + * on what contexts mean here, see the find_active_context function. */ +static DNode compute_output_node(const DerivedNodeTree &tree) +{ + const DTreeContext *active_context = find_active_context(tree); + + const DNode node = find_output_in_context(active_context); + if (node) { + return node; + } + + /* If the active context is the root one and no output node was found, we consider this node tree + * to have no output node, even if one of the non-active descendants have an output node. */ + if (active_context->is_root()) { + return DNode(); + } + + /* The active context doesn't have an output node, search in the root context as a fallback. */ + return find_output_in_context(&tree.root_context()); +} + /* A type representing a mapping that associates each node with a heuristic estimation of the * number of intermediate buffers needed to compute it and all of its dependencies. See the * compute_number_of_needed_buffers function for more information. */ @@ -225,7 +293,7 @@ static NeededBuffers compute_number_of_needed_buffers(DNode output_node) * doesn't always guarantee an optimal evaluation order, as the optimal evaluation order is very * difficult to compute, however, this method works well in most cases. Moreover it assumes that * all buffers will have roughly the same size, which may not always be the case. */ -Schedule compute_schedule(DerivedNodeTree &tree) +Schedule compute_schedule(const DerivedNodeTree &tree) { Schedule schedule; diff --git a/source/blender/depsgraph/intern/depsgraph_build.cc b/source/blender/depsgraph/intern/depsgraph_build.cc index 6da290d6c4e..9eeb074bbaa 100644 --- a/source/blender/depsgraph/intern/depsgraph_build.cc +++ b/source/blender/depsgraph/intern/depsgraph_build.cc @@ -138,9 +138,14 @@ void DEG_add_node_tree_output_relation(DepsNodeHandle *node_handle, { deg::OperationKey ntree_output_key( &node_tree->id, deg::NodeType::NTREE_OUTPUT, deg::OperationCode::NTREE_OUTPUT); + deg::OperationKey ntree_preprocess_key(&node_tree->id, + deg::NodeType::NTREE_GEOMETRY_PREPROCESS, + deg::OperationCode::NTREE_GEOMETRY_PREPROCESS); deg::DepsNodeHandle *deg_node_handle = get_node_handle(node_handle); deg_node_handle->builder->add_node_handle_relation( ntree_output_key, deg_node_handle, description); + deg_node_handle->builder->add_node_handle_relation( + ntree_preprocess_key, deg_node_handle, description, deg::RELATION_FLAG_NO_FLUSH); } void DEG_add_object_cache_relation(DepsNodeHandle *node_handle, diff --git a/source/blender/draw/engines/eevee_next/eevee_camera.cc b/source/blender/draw/engines/eevee_next/eevee_camera.cc index ad22219f0ae..4331db4bc4c 100644 --- a/source/blender/draw/engines/eevee_next/eevee_camera.cc +++ b/source/blender/draw/engines/eevee_next/eevee_camera.cc @@ -32,7 +32,7 @@ void Camera::init() CameraData &data = data_; - if (camera_eval) { + if (camera_eval && camera_eval->type == OB_CAMERA) { const ::Camera *cam = reinterpret_cast<const ::Camera *>(camera_eval->data); switch (cam->type) { default: @@ -112,7 +112,7 @@ void Camera::sync() data.uv_bias = float2(0.0f); } - if (camera_eval) { + if (camera_eval && camera_eval->type == OB_CAMERA) { const ::Camera *cam = reinterpret_cast<const ::Camera *>(camera_eval->data); data.clip_near = cam->clip_start; data.clip_far = cam->clip_end; diff --git a/source/blender/draw/engines/eevee_next/eevee_depth_of_field.cc b/source/blender/draw/engines/eevee_next/eevee_depth_of_field.cc index e4c4f6f3f6f..8672cce80b6 100644 --- a/source/blender/draw/engines/eevee_next/eevee_depth_of_field.cc +++ b/source/blender/draw/engines/eevee_next/eevee_depth_of_field.cc @@ -44,7 +44,7 @@ void DepthOfField::init() { const SceneEEVEE &sce_eevee = inst_.scene->eevee; const Object *camera_object_eval = inst_.camera_eval_object; - const ::Camera *camera = (camera_object_eval) ? + const ::Camera *camera = (camera_object_eval && camera_object_eval->type == OB_CAMERA) ? reinterpret_cast<const ::Camera *>(camera_object_eval->data) : nullptr; if (camera == nullptr) { @@ -70,7 +70,7 @@ void DepthOfField::sync() { const Camera &camera = inst_.camera; const Object *camera_object_eval = inst_.camera_eval_object; - const ::Camera *camera_data = (camera_object_eval) ? + const ::Camera *camera_data = (camera_object_eval && camera_object_eval->type == OB_CAMERA) ? reinterpret_cast<const ::Camera *>(camera_object_eval->data) : nullptr; diff --git a/source/blender/editors/include/ED_sculpt.h b/source/blender/editors/include/ED_sculpt.h index 1c1ce41ef7a..bc4e3b88586 100644 --- a/source/blender/editors/include/ED_sculpt.h +++ b/source/blender/editors/include/ED_sculpt.h @@ -22,7 +22,7 @@ struct wmMsgSubscribeValue; struct wmRegionMessageSubscribeParams; struct wmOperator; -/* sculpt.c */ +/* sculpt.cc */ void ED_operatortypes_sculpt(void); void ED_sculpt_redraw_planes_get(float planes[4][4], struct ARegion *region, struct Object *ob); diff --git a/source/blender/editors/sculpt_paint/CMakeLists.txt b/source/blender/editors/sculpt_paint/CMakeLists.txt index 2709ac3fd91..b29fc0e9e7d 100644 --- a/source/blender/editors/sculpt_paint/CMakeLists.txt +++ b/source/blender/editors/sculpt_paint/CMakeLists.txt @@ -60,7 +60,7 @@ set(SRC paint_vertex_proj.c paint_vertex_weight_ops.c paint_vertex_weight_utils.c - sculpt.c + sculpt.cc sculpt_automasking.cc sculpt_boundary.c sculpt_brush_types.c diff --git a/source/blender/editors/sculpt_paint/paint_vertex.cc b/source/blender/editors/sculpt_paint/paint_vertex.cc index 8e790ac435e..8758d3fa83f 100644 --- a/source/blender/editors/sculpt_paint/paint_vertex.cc +++ b/source/blender/editors/sculpt_paint/paint_vertex.cc @@ -1162,7 +1162,7 @@ static void do_weight_paint_vertex( } } -/* Toggle operator for turning vertex paint mode on or off (copied from sculpt.c) */ +/* Toggle operator for turning vertex paint mode on or off (copied from sculpt.cc) */ static void vertex_paint_init_session(Depsgraph *depsgraph, Scene *scene, Object *ob, @@ -2388,7 +2388,7 @@ static void wpaint_do_paint(bContext *C, WeightPaintInfo *wpi, Mesh *me, Brush *brush, - const char symm, + const ePaintSymmetryFlags symm, const int axis, const int i, const float angle) @@ -2415,7 +2415,7 @@ static void wpaint_do_radial_symmetry(bContext *C, WeightPaintInfo *wpi, Mesh *me, Brush *brush, - const char symm, + const ePaintSymmetryFlags symm, const int axis) { for (int i = 1; i < wp->radial_symm[axis - 'X']; i++) { @@ -2424,7 +2424,7 @@ static void wpaint_do_radial_symmetry(bContext *C, } } -/* near duplicate of: sculpt.c's, +/* near duplicate of: sculpt.cc's, * 'do_symmetrical_brush_actions' and 'vpaint_do_symmetrical_brush_actions'. */ static void wpaint_do_symmetrical_brush_actions( bContext *C, Object *ob, VPaint *wp, Sculpt *sd, WPaintData *wpd, WeightPaintInfo *wpi) @@ -2437,11 +2437,11 @@ static void wpaint_do_symmetrical_brush_actions( int i = 0; /* initial stroke */ - cache->mirror_symmetry_pass = 0; - wpaint_do_paint(C, ob, wp, sd, wpd, wpi, me, brush, 0, 'X', 0, 0); - wpaint_do_radial_symmetry(C, ob, wp, sd, wpd, wpi, me, brush, 0, 'X'); - wpaint_do_radial_symmetry(C, ob, wp, sd, wpd, wpi, me, brush, 0, 'Y'); - wpaint_do_radial_symmetry(C, ob, wp, sd, wpd, wpi, me, brush, 0, 'Z'); + cache->mirror_symmetry_pass = ePaintSymmetryFlags(0); + wpaint_do_paint(C, ob, wp, sd, wpd, wpi, me, brush, ePaintSymmetryFlags(0), 'X', 0, 0); + wpaint_do_radial_symmetry(C, ob, wp, sd, wpd, wpi, me, brush, ePaintSymmetryFlags(0), 'X'); + wpaint_do_radial_symmetry(C, ob, wp, sd, wpd, wpi, me, brush, ePaintSymmetryFlags(0), 'Y'); + wpaint_do_radial_symmetry(C, ob, wp, sd, wpd, wpi, me, brush, ePaintSymmetryFlags(0), 'Z'); cache->symmetry = symm; @@ -2456,21 +2456,22 @@ static void wpaint_do_symmetrical_brush_actions( * X; 2 is Y; 3 is XY; 4 is Z; 5 is XZ; 6 is YZ; 7 is XYZ */ for (i = 1; i <= symm; i++) { if (symm & i && (symm != 5 || i != 3) && (symm != 6 || !ELEM(i, 3, 5))) { - cache->mirror_symmetry_pass = i; + const ePaintSymmetryFlags symm = ePaintSymmetryFlags(i); + cache->mirror_symmetry_pass = symm; cache->radial_symmetry_pass = 0; - SCULPT_cache_calc_brushdata_symm(cache, i, 0, 0); + SCULPT_cache_calc_brushdata_symm(cache, symm, 0, 0); if (i & (1 << 0)) { - wpaint_do_paint(C, ob, wp, sd, wpd, wpi, me, brush, i, 'X', 0, 0); - wpaint_do_radial_symmetry(C, ob, wp, sd, wpd, wpi, me, brush, i, 'X'); + wpaint_do_paint(C, ob, wp, sd, wpd, wpi, me, brush, symm, 'X', 0, 0); + wpaint_do_radial_symmetry(C, ob, wp, sd, wpd, wpi, me, brush, symm, 'X'); } if (i & (1 << 1)) { - wpaint_do_paint(C, ob, wp, sd, wpd, wpi, me, brush, i, 'Y', 0, 0); - wpaint_do_radial_symmetry(C, ob, wp, sd, wpd, wpi, me, brush, i, 'Y'); + wpaint_do_paint(C, ob, wp, sd, wpd, wpi, me, brush, symm, 'Y', 0, 0); + wpaint_do_radial_symmetry(C, ob, wp, sd, wpd, wpi, me, brush, symm, 'Y'); } if (i & (1 << 2)) { - wpaint_do_paint(C, ob, wp, sd, wpd, wpi, me, brush, i, 'Z', 0, 0); - wpaint_do_radial_symmetry(C, ob, wp, sd, wpd, wpi, me, brush, i, 'Z'); + wpaint_do_paint(C, ob, wp, sd, wpd, wpi, me, brush, symm, 'Z', 0, 0); + wpaint_do_radial_symmetry(C, ob, wp, sd, wpd, wpi, me, brush, symm, 'Z'); } } } @@ -3738,7 +3739,7 @@ static void vpaint_do_paint(bContext *C, Object *ob, Mesh *me, Brush *brush, - const char symm, + const ePaintSymmetryFlags symm, const int axis, const int i, const float angle) @@ -3769,7 +3770,7 @@ static void vpaint_do_radial_symmetry(bContext *C, Object *ob, Mesh *me, Brush *brush, - const char symm, + const ePaintSymmetryFlags symm, const int axis) { for (int i = 1; i < vp->radial_symm[axis - 'X']; i++) { @@ -3778,7 +3779,7 @@ static void vpaint_do_radial_symmetry(bContext *C, } } -/* near duplicate of: sculpt.c's, +/* near duplicate of: sculpt.cc's, * 'do_symmetrical_brush_actions' and 'wpaint_do_symmetrical_brush_actions'. */ template<typename Color, typename Traits, eAttrDomain domain> static void vpaint_do_symmetrical_brush_actions( @@ -3792,11 +3793,15 @@ static void vpaint_do_symmetrical_brush_actions( int i = 0; /* initial stroke */ - cache->mirror_symmetry_pass = 0; - vpaint_do_paint<Color, Traits, domain>(C, sd, vp, vpd, ob, me, brush, i, 'X', 0, 0); - vpaint_do_radial_symmetry<Color, Traits, domain>(C, sd, vp, vpd, ob, me, brush, i, 'X'); - vpaint_do_radial_symmetry<Color, Traits, domain>(C, sd, vp, vpd, ob, me, brush, i, 'Y'); - vpaint_do_radial_symmetry<Color, Traits, domain>(C, sd, vp, vpd, ob, me, brush, i, 'Z'); + const ePaintSymmetryFlags initial_symm = ePaintSymmetryFlags(0); + cache->mirror_symmetry_pass = ePaintSymmetryFlags(0); + vpaint_do_paint<Color, Traits, domain>(C, sd, vp, vpd, ob, me, brush, initial_symm, 'X', 0, 0); + vpaint_do_radial_symmetry<Color, Traits, domain>( + C, sd, vp, vpd, ob, me, brush, initial_symm, 'X'); + vpaint_do_radial_symmetry<Color, Traits, domain>( + C, sd, vp, vpd, ob, me, brush, initial_symm, 'Y'); + vpaint_do_radial_symmetry<Color, Traits, domain>( + C, sd, vp, vpd, ob, me, brush, initial_symm, 'Z'); cache->symmetry = symm; @@ -3804,21 +3809,28 @@ static void vpaint_do_symmetrical_brush_actions( * X; 2 is Y; 3 is XY; 4 is Z; 5 is XZ; 6 is YZ; 7 is XYZ */ for (i = 1; i <= symm; i++) { if (symm & i && (symm != 5 || i != 3) && (symm != 6 || !ELEM(i, 3, 5))) { - cache->mirror_symmetry_pass = i; + const ePaintSymmetryFlags symm_pass = ePaintSymmetryFlags(i); + cache->mirror_symmetry_pass = symm_pass; cache->radial_symmetry_pass = 0; - SCULPT_cache_calc_brushdata_symm(cache, i, 0, 0); + SCULPT_cache_calc_brushdata_symm(cache, symm_pass, 0, 0); if (i & (1 << 0)) { - vpaint_do_paint<Color, Traits, domain>(C, sd, vp, vpd, ob, me, brush, i, 'X', 0, 0); - vpaint_do_radial_symmetry<Color, Traits, domain>(C, sd, vp, vpd, ob, me, brush, i, 'X'); + vpaint_do_paint<Color, Traits, domain>( + C, sd, vp, vpd, ob, me, brush, symm_pass, 'X', 0, 0); + vpaint_do_radial_symmetry<Color, Traits, domain>( + C, sd, vp, vpd, ob, me, brush, symm_pass, 'X'); } if (i & (1 << 1)) { - vpaint_do_paint<Color, Traits, domain>(C, sd, vp, vpd, ob, me, brush, i, 'Y', 0, 0); - vpaint_do_radial_symmetry<Color, Traits, domain>(C, sd, vp, vpd, ob, me, brush, i, 'Y'); + vpaint_do_paint<Color, Traits, domain>( + C, sd, vp, vpd, ob, me, brush, symm_pass, 'Y', 0, 0); + vpaint_do_radial_symmetry<Color, Traits, domain>( + C, sd, vp, vpd, ob, me, brush, symm_pass, 'Y'); } if (i & (1 << 2)) { - vpaint_do_paint<Color, Traits, domain>(C, sd, vp, vpd, ob, me, brush, i, 'Z', 0, 0); - vpaint_do_radial_symmetry<Color, Traits, domain>(C, sd, vp, vpd, ob, me, brush, i, 'Z'); + vpaint_do_paint<Color, Traits, domain>( + C, sd, vp, vpd, ob, me, brush, symm_pass, 'Z', 0, 0); + vpaint_do_radial_symmetry<Color, Traits, domain>( + C, sd, vp, vpd, ob, me, brush, symm_pass, 'Z'); } } } diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.cc index 3477285814e..684fcdbff9e 100644 --- a/source/blender/editors/sculpt_paint/sculpt.c +++ b/source/blender/editors/sculpt_paint/sculpt.cc @@ -6,6 +6,10 @@ * Implements the Sculpt Mode tools. */ +#include <cmath> +#include <cstdlib> +#include <cstring> + #include "MEM_guardedalloc.h" #include "BLI_blenlib.h" @@ -65,10 +69,6 @@ #include "bmesh.h" -#include <math.h> -#include <stdlib.h> -#include <string.h> - /* -------------------------------------------------------------------- */ /** \name Sculpt PBVH Abstraction API * @@ -121,7 +121,7 @@ const float *SCULPT_vertex_co_get(SculptSession *ss, PBVHVertRef vertex) return CCG_elem_co(key, CCG_elem_offset(key, elem, vertex_index)); } } - return NULL; + return nullptr; } bool SCULPT_has_loop_colors(const Object *ob) @@ -209,9 +209,10 @@ void SCULPT_vertex_limit_surface_get(SculptSession *ss, PBVHVertRef vertex, floa const int grid_index = vertex.i / key->grid_area; const int vertex_index = vertex.i - grid_index * key->grid_area; - SubdivCCGCoord coord = {.grid_index = grid_index, - .x = vertex_index % key->grid_size, - .y = vertex_index / key->grid_size}; + SubdivCCGCoord coord{}; + coord.grid_index = grid_index; + coord.x = vertex_index % key->grid_size; + coord.y = vertex_index / key->grid_size; BKE_subdiv_ccg_eval_limit_point(ss->subdiv_ccg, &coord, r_co); break; } @@ -280,9 +281,9 @@ MVert *SCULPT_mesh_deformed_mverts_get(SculptSession *ss) return ss->mvert; case PBVH_BMESH: case PBVH_GRIDS: - return NULL; + return nullptr; } - return NULL; + return nullptr; } float *SCULPT_brush_deform_target_vertex_co_get(SculptSession *ss, @@ -351,7 +352,7 @@ bool SCULPT_vertex_visible_get(SculptSession *ss, PBVHVertRef vertex) switch (BKE_pbvh_type(ss->pbvh)) { case PBVH_FACES: { const bool *hide_vert = BKE_pbvh_get_vert_hide(ss->pbvh); - return hide_vert == NULL || !hide_vert[vertex.i]; + return hide_vert == nullptr || !hide_vert[vertex.i]; } case PBVH_BMESH: return !BM_elem_flag_test((BMVert *)vertex.i, BM_ELEM_HIDDEN); @@ -370,8 +371,8 @@ bool SCULPT_vertex_visible_get(SculptSession *ss, PBVHVertRef vertex) void SCULPT_face_set_visibility_set(SculptSession *ss, int face_set, bool visible) { - BLI_assert(ss->face_sets != NULL); - BLI_assert(ss->hide_poly != NULL); + BLI_assert(ss->face_sets != nullptr); + BLI_assert(ss->hide_poly != nullptr); switch (BKE_pbvh_type(ss->pbvh)) { case PBVH_FACES: case PBVH_GRIDS: @@ -389,8 +390,8 @@ void SCULPT_face_set_visibility_set(SculptSession *ss, int face_set, bool visibl void SCULPT_face_visibility_all_invert(SculptSession *ss) { - BLI_assert(ss->face_sets != NULL); - BLI_assert(ss->hide_poly != NULL); + BLI_assert(ss->face_sets != nullptr); + BLI_assert(ss->hide_poly != nullptr); switch (BKE_pbvh_type(ss->pbvh)) { case PBVH_FACES: case PBVH_GRIDS: @@ -415,7 +416,7 @@ void SCULPT_face_visibility_all_set(SculptSession *ss, bool visible) switch (BKE_pbvh_type(ss->pbvh)) { case PBVH_FACES: case PBVH_GRIDS: - BLI_assert(ss->hide_poly != NULL); + BLI_assert(ss->hide_poly != nullptr); memset(ss->hide_poly, !visible, sizeof(bool) * ss->totfaces); break; case PBVH_BMESH: { @@ -509,7 +510,7 @@ void SCULPT_vertex_face_set_set(SculptSession *ss, PBVHVertRef vertex, int face_ { switch (BKE_pbvh_type(ss->pbvh)) { case PBVH_FACES: { - BLI_assert(ss->face_sets != NULL); + BLI_assert(ss->face_sets != nullptr); const MeshElemMap *vert_map = &ss->pmap[vertex.i]; for (int j = 0; j < vert_map->count; j++) { const int poly_index = vert_map->indices[j]; @@ -524,7 +525,7 @@ void SCULPT_vertex_face_set_set(SculptSession *ss, PBVHVertRef vertex, int face_ case PBVH_BMESH: break; case PBVH_GRIDS: { - BLI_assert(ss->face_sets != NULL); + BLI_assert(ss->face_sets != nullptr); const CCGKey *key = BKE_pbvh_get_grid_key(ss->pbvh); const int grid_index = vertex.i / key->grid_area; const int face_index = BKE_subdiv_ccg_grid_to_face_index(ss->subdiv_ccg, grid_index); @@ -715,9 +716,10 @@ bool SCULPT_vertex_has_unique_face_set(SculptSession *ss, PBVHVertRef vertex) const CCGKey *key = BKE_pbvh_get_grid_key(ss->pbvh); const int grid_index = vertex.i / key->grid_area; const int vertex_index = vertex.i - grid_index * key->grid_area; - const SubdivCCGCoord coord = {.grid_index = grid_index, - .x = vertex_index % key->grid_size, - .y = vertex_index / key->grid_size}; + SubdivCCGCoord coord{}; + coord.grid_index = grid_index; + coord.x = vertex_index % key->grid_size; + coord.y = vertex_index / key->grid_size; int v1, v2; const SubdivCCGAdjacencyType adjacency = BKE_subdiv_ccg_coarse_mesh_adjacency_info_get( ss->subdiv_ccg, &coord, ss->mloop, ss->mpoly, &v1, &v2); @@ -775,21 +777,23 @@ static void sculpt_vertex_neighbor_add(SculptVertexNeighborIter *iter, iter->capacity += SCULPT_VERTEX_NEIGHBOR_FIXED_CAPACITY; if (iter->neighbors == iter->neighbors_fixed) { - iter->neighbors = MEM_mallocN(iter->capacity * sizeof(PBVHVertRef), "neighbor array"); + iter->neighbors = static_cast<PBVHVertRef *>( + MEM_mallocN(iter->capacity * sizeof(PBVHVertRef), "neighbor array")); memcpy(iter->neighbors, iter->neighbors_fixed, sizeof(PBVHVertRef) * iter->size); } else { - iter->neighbors = MEM_reallocN_id( - iter->neighbors, iter->capacity * sizeof(PBVHVertRef), "neighbor array"); + iter->neighbors = static_cast<PBVHVertRef *>(MEM_reallocN_id( + iter->neighbors, iter->capacity * sizeof(PBVHVertRef), "neighbor array")); } if (iter->neighbor_indices == iter->neighbor_indices_fixed) { - iter->neighbor_indices = MEM_mallocN(iter->capacity * sizeof(int), "neighbor array"); + iter->neighbor_indices = static_cast<int *>( + MEM_mallocN(iter->capacity * sizeof(int), "neighbor array")); memcpy(iter->neighbor_indices, iter->neighbor_indices_fixed, sizeof(int) * iter->size); } else { - iter->neighbor_indices = MEM_reallocN_id( - iter->neighbor_indices, iter->capacity * sizeof(int), "neighbor array"); + iter->neighbor_indices = static_cast<int *>( + MEM_reallocN_id(iter->neighbor_indices, iter->capacity * sizeof(int), "neighbor array")); } } @@ -849,7 +853,7 @@ static void sculpt_vertex_neighbors_get_faces(SculptSession *ss, } if (ss->fake_neighbors.use_fake_neighbors) { - BLI_assert(ss->fake_neighbors.fake_neighbor_index != NULL); + BLI_assert(ss->fake_neighbors.fake_neighbor_index != nullptr); if (ss->fake_neighbors.fake_neighbor_index[vertex.i] != FAKE_NEIGHBOR_NONE) { sculpt_vertex_neighbor_add( iter, @@ -871,9 +875,10 @@ static void sculpt_vertex_neighbors_get_grids(SculptSession *ss, const int grid_index = vertex.i / key->grid_area; const int vertex_index = vertex.i - grid_index * key->grid_area; - SubdivCCGCoord coord = {.grid_index = grid_index, - .x = vertex_index % key->grid_size, - .y = vertex_index / key->grid_size}; + SubdivCCGCoord coord{}; + coord.grid_index = grid_index; + coord.x = vertex_index % key->grid_size; + coord.y = vertex_index / key->grid_size; SubdivCCGNeighbors neighbors; BKE_subdiv_ccg_neighbor_coords_get(ss->subdiv_ccg, &coord, include_duplicates, &neighbors); @@ -892,7 +897,7 @@ static void sculpt_vertex_neighbors_get_grids(SculptSession *ss, } if (ss->fake_neighbors.use_fake_neighbors) { - BLI_assert(ss->fake_neighbors.fake_neighbor_index != NULL); + BLI_assert(ss->fake_neighbors.fake_neighbor_index != nullptr); if (ss->fake_neighbors.fake_neighbor_index[vertex.i] != FAKE_NEIGHBOR_NONE) { int v = ss->fake_neighbors.fake_neighbor_index[vertex.i]; sculpt_vertex_neighbor_add(iter, BKE_pbvh_make_vref(v), v); @@ -946,9 +951,10 @@ bool SCULPT_vertex_is_boundary(const SculptSession *ss, const PBVHVertRef vertex const CCGKey *key = BKE_pbvh_get_grid_key(ss->pbvh); const int grid_index = vertex.i / key->grid_area; const int vertex_index = vertex.i - grid_index * key->grid_area; - const SubdivCCGCoord coord = {.grid_index = grid_index, - .x = vertex_index % key->grid_size, - .y = vertex_index / key->grid_size}; + SubdivCCGCoord coord{}; + coord.grid_index = grid_index; + coord.x = vertex_index % key->grid_size; + coord.y = vertex_index / key->grid_size; int v1, v2; const SubdivCCGAdjacencyType adjacency = BKE_subdiv_ccg_coarse_mesh_adjacency_info_get( ss->subdiv_ccg, &coord, ss->mloop, ss->mpoly, &v1, &v2); @@ -1005,18 +1011,18 @@ bool SCULPT_check_vertex_pivot_symmetry(const float vco[3], const float pco[3], return is_in_symmetry_area; } -typedef struct NearestVertexTLSData { +struct NearestVertexTLSData { PBVHVertRef nearest_vertex; float nearest_vertex_distance_squared; -} NearestVertexTLSData; +}; static void do_nearest_vertex_get_task_cb(void *__restrict userdata, const int n, const TaskParallelTLS *__restrict tls) { - SculptThreadedTaskData *data = userdata; + SculptThreadedTaskData *data = static_cast<SculptThreadedTaskData *>(userdata); SculptSession *ss = data->ob->sculpt; - NearestVertexTLSData *nvtd = tls->userdata_chunk; + NearestVertexTLSData *nvtd = static_cast<NearestVertexTLSData *>(tls->userdata_chunk); PBVHVertexIter vd; BKE_pbvh_vertex_iter_begin (ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) { @@ -1030,12 +1036,12 @@ static void do_nearest_vertex_get_task_cb(void *__restrict userdata, BKE_pbvh_vertex_iter_end; } -static void nearest_vertex_get_reduce(const void *__restrict UNUSED(userdata), +static void nearest_vertex_get_reduce(const void *__restrict /*userdata*/, void *__restrict chunk_join, void *__restrict chunk) { - NearestVertexTLSData *join = chunk_join; - NearestVertexTLSData *nvtd = chunk; + NearestVertexTLSData *join = static_cast<NearestVertexTLSData *>(chunk_join); + NearestVertexTLSData *nvtd = static_cast<NearestVertexTLSData *>(chunk); if (join->nearest_vertex.i == PBVH_REF_NONE) { join->nearest_vertex = nvtd->nearest_vertex; join->nearest_vertex_distance_squared = nvtd->nearest_vertex_distance_squared; @@ -1050,26 +1056,24 @@ PBVHVertRef SCULPT_nearest_vertex_get( Sculpt *sd, Object *ob, const float co[3], float max_distance, bool use_original) { SculptSession *ss = ob->sculpt; - PBVHNode **nodes = NULL; + PBVHNode **nodes = nullptr; int totnode; - SculptSearchSphereData data = { - .ss = ss, - .sd = sd, - .radius_squared = max_distance * max_distance, - .original = use_original, - .center = co, - }; + SculptSearchSphereData data{}; + data.sd = sd; + data.radius_squared = max_distance * max_distance; + data.original = use_original; + data.center = co; + BKE_pbvh_search_gather(ss->pbvh, SCULPT_search_sphere_cb, &data, &nodes, &totnode); if (totnode == 0) { return BKE_pbvh_make_vref(PBVH_REF_NONE); } - SculptThreadedTaskData task_data = { - .sd = sd, - .ob = ob, - .nodes = nodes, - .max_distance_squared = max_distance * max_distance, - }; + SculptThreadedTaskData task_data{}; + task_data.sd = sd; + task_data.ob = ob; + task_data.nodes = nodes; + task_data.max_distance_squared = max_distance * max_distance; copy_v3_v3(task_data.nearest_vertex_search_co, co); NearestVertexTLSData nvtd; @@ -1103,7 +1107,7 @@ bool SCULPT_is_vertex_inside_brush_radius_symm(const float vertex[3], continue; } float location[3]; - flip_v3_v3(location, br_co, (char)i); + flip_v3_v3(location, br_co, ePaintSymmetryFlags(i)); if (len_squared_v3v3(location, vertex) < radius * radius) { return true; } @@ -1176,7 +1180,7 @@ void SCULPT_floodfill_add_initial_with_symmetry(Sculpt *sd, else if (radius > 0.0f) { float radius_squared = (radius == FLT_MAX) ? FLT_MAX : radius * radius; float location[3]; - flip_v3_v3(location, SCULPT_vertex_co_get(ss, vertex), i); + flip_v3_v3(location, SCULPT_vertex_co_get(ss, vertex), ePaintSymmetryFlags(i)); v = SCULPT_nearest_vertex_get(sd, ob, location, radius_squared, false); } @@ -1203,7 +1207,7 @@ void SCULPT_floodfill_add_active( } else if (radius > 0.0f) { float location[3]; - flip_v3_v3(location, SCULPT_active_vertex_co_get(ss), i); + flip_v3_v3(location, SCULPT_active_vertex_co_get(ss), ePaintSymmetryFlags(i)); v = SCULPT_nearest_vertex_get(sd, ob, location, radius, false); } @@ -1253,7 +1257,7 @@ void SCULPT_floodfill_free(SculptFloodFill *flood) { MEM_SAFE_FREE(flood->visited_verts); BLI_gsqueue_free(flood->queue); - flood->queue = NULL; + flood->queue = nullptr; } /** \} */ @@ -1302,7 +1306,7 @@ static bool sculpt_tool_is_proxy_used(const char sculpt_tool) static bool sculpt_brush_use_topology_rake(const SculptSession *ss, const Brush *brush) { return SCULPT_TOOL_HAS_TOPOLOGY_RAKE(brush->sculpt_tool) && - (brush->topology_rake_factor > 0.0f) && (ss->bm != NULL); + (brush->topology_rake_factor > 0.0f) && (ss->bm != nullptr); } /** @@ -1340,11 +1344,11 @@ static bool sculpt_brush_needs_rake_rotation(const Brush *brush) /** \name Sculpt Init/Update * \{ */ -typedef enum StrokeFlags { +enum StrokeFlags { CLIP_X = 1, CLIP_Y = 2, CLIP_Z = 4, -} StrokeFlags; +}; void SCULPT_orig_vert_data_unode_init(SculptOrigVertData *data, Object *ob, SculptUndoNode *unode) { @@ -1399,7 +1403,7 @@ void SCULPT_orig_vert_data_update(SculptOrigVertData *orig_data, PBVHVertexIter } } -static void sculpt_rake_data_update(struct SculptRakeData *srd, const float co[3]) +static void sculpt_rake_data_update(SculptRakeData *srd, const float co[3]) { float rake_dist = len_v3v3(srd->follow_co, co); if (rake_dist > srd->follow_dist) { @@ -1434,9 +1438,9 @@ bool SCULPT_stroke_is_dynamic_topology(const SculptSession *ss, const Brush *bru static void paint_mesh_restore_co_task_cb(void *__restrict userdata, const int n, - const TaskParallelTLS *__restrict UNUSED(tls)) + const TaskParallelTLS *__restrict /*tls*/) { - SculptThreadedTaskData *data = userdata; + SculptThreadedTaskData *data = static_cast<SculptThreadedTaskData *>(userdata); SculptSession *ss = data->ob->sculpt; SculptUndoNode *unode; @@ -1518,19 +1522,18 @@ static void paint_mesh_restore_co(Sculpt *sd, Object *ob) PBVHNode **nodes; int totnode; - BKE_pbvh_search_gather(ss->pbvh, NULL, NULL, &nodes, &totnode); + BKE_pbvh_search_gather(ss->pbvh, nullptr, nullptr, &nodes, &totnode); /** * Disable multi-threading when dynamic-topology is enabled. Otherwise, * new entries might be inserted by #SCULPT_undo_push_node() into the #GHash * used internally by #BM_log_original_vert_co() by a different thread. See T33787. */ - SculptThreadedTaskData data = { - .sd = sd, - .ob = ob, - .brush = brush, - .nodes = nodes, - }; + SculptThreadedTaskData data{}; + data.sd = sd; + data.ob = ob; + data.brush = brush; + data.nodes = nodes; TaskParallelSettings settings; BKE_pbvh_parallel_range_settings(&settings, true && !ss->bm, totnode); @@ -1624,7 +1627,7 @@ void SCULPT_brush_test_init(SculptSession *ss, SculptBrushTest *test) } else { copy_v3_v3(test->location, ss->cursor_location); - test->mirror_symmetry_pass = 0; + test->mirror_symmetry_pass = ePaintSymmetryFlags(0); test->radial_symmetry_pass = 0; unit_m4(test->symm_rot_mat_inv); } @@ -1640,7 +1643,7 @@ void SCULPT_brush_test_init(SculptSession *ss, SculptBrushTest *test) test->clip_rv3d = rv3d; } else { - test->clip_rv3d = NULL; + test->clip_rv3d = nullptr; } } @@ -1837,7 +1840,10 @@ static bool sculpt_brush_test_cyl(SculptBrushTest *test, /* ===== Sculpting ===== */ -static float calc_overlap(StrokeCache *cache, const char symm, const char axis, const float angle) +static float calc_overlap(StrokeCache *cache, + const ePaintSymmetryFlags symm, + const char axis, + const float angle) { float mirror[3]; float distsq; @@ -1860,7 +1866,7 @@ static float calc_overlap(StrokeCache *cache, const char symm, const char axis, static float calc_radial_symmetry_feather(Sculpt *sd, StrokeCache *cache, - const char symm, + const ePaintSymmetryFlags symm, const char axis) { float overlap = 0.0f; @@ -1887,11 +1893,11 @@ static float calc_symmetry_feather(Sculpt *sd, StrokeCache *cache) continue; } - overlap += calc_overlap(cache, i, 0, 0); + overlap += calc_overlap(cache, ePaintSymmetryFlags(i), 0, 0); - overlap += calc_radial_symmetry_feather(sd, cache, i, 'X'); - overlap += calc_radial_symmetry_feather(sd, cache, i, 'Y'); - overlap += calc_radial_symmetry_feather(sd, cache, i, 'Z'); + overlap += calc_radial_symmetry_feather(sd, cache, ePaintSymmetryFlags(i), 'X'); + overlap += calc_radial_symmetry_feather(sd, cache, ePaintSymmetryFlags(i), 'Y'); + overlap += calc_radial_symmetry_feather(sd, cache, ePaintSymmetryFlags(i), 'Z'); } return 1.0f / overlap; } @@ -1912,26 +1918,26 @@ static float calc_symmetry_feather(Sculpt *sd, StrokeCache *cache) * \note These are all _very_ similar, when changing one, check others. * \{ */ -typedef struct AreaNormalCenterTLSData { +struct AreaNormalCenterTLSData { /* 0 = towards view, 1 = flipped */ float area_cos[2][3]; float area_nos[2][3]; int count_no[2]; int count_co[2]; -} AreaNormalCenterTLSData; +}; static void calc_area_normal_and_center_task_cb(void *__restrict userdata, const int n, const TaskParallelTLS *__restrict tls) { - SculptThreadedTaskData *data = userdata; + SculptThreadedTaskData *data = static_cast<SculptThreadedTaskData *>(userdata); SculptSession *ss = data->ob->sculpt; - AreaNormalCenterTLSData *anctd = tls->userdata_chunk; + AreaNormalCenterTLSData *anctd = static_cast<AreaNormalCenterTLSData *>(tls->userdata_chunk); const bool use_area_nos = data->use_area_nos; const bool use_area_cos = data->use_area_cos; PBVHVertexIter vd; - SculptUndoNode *unode = NULL; + SculptUndoNode *unode = nullptr; bool use_original = false; bool normal_test_r, area_test_r; @@ -1982,7 +1988,8 @@ static void calc_area_normal_and_center_task_cb(void *__restrict userdata, int(*orco_tris)[3]; int orco_tris_num; - BKE_pbvh_node_get_bm_orco_data(data->nodes[n], &orco_tris, &orco_tris_num, &orco_coords, NULL); + BKE_pbvh_node_get_bm_orco_data( + data->nodes[n], &orco_tris, &orco_tris_num, &orco_coords, nullptr); for (int i = 0; i < orco_tris_num; i++) { const float *co_tri[3] = { @@ -2109,12 +2116,12 @@ static void calc_area_normal_and_center_task_cb(void *__restrict userdata, } } -static void calc_area_normal_and_center_reduce(const void *__restrict UNUSED(userdata), +static void calc_area_normal_and_center_reduce(const void *__restrict /*userdata*/, void *__restrict chunk_join, void *__restrict chunk) { - AreaNormalCenterTLSData *join = chunk_join; - AreaNormalCenterTLSData *anctd = chunk; + AreaNormalCenterTLSData *join = static_cast<AreaNormalCenterTLSData *>(chunk_join); + AreaNormalCenterTLSData *anctd = static_cast<AreaNormalCenterTLSData *>(chunk); /* For flatten center. */ add_v3_v3(join->area_cos[0], anctd->area_cos[0]); @@ -2137,16 +2144,15 @@ void SCULPT_calc_area_center( const bool has_bm_orco = ss->bm && SCULPT_stroke_is_dynamic_topology(ss, brush); int n; - /* Intentionally set 'sd' to NULL since we share logic with vertex paint. */ - SculptThreadedTaskData data = { - .sd = NULL, - .ob = ob, - .brush = brush, - .nodes = nodes, - .totnode = totnode, - .has_bm_orco = has_bm_orco, - .use_area_cos = true, - }; + /* Intentionally set 'sd' to nullptr since we share logic with vertex paint. */ + SculptThreadedTaskData data{}; + data.sd = nullptr; + data.ob = ob; + data.brush = brush; + data.nodes = nodes; + data.totnode = totnode; + data.has_bm_orco = has_bm_orco; + data.use_area_cos = true; AreaNormalCenterTLSData anctd = {{{0}}}; @@ -2195,17 +2201,16 @@ bool SCULPT_pbvh_calc_area_normal(const Brush *brush, SculptSession *ss = ob->sculpt; const bool has_bm_orco = ss->bm && SCULPT_stroke_is_dynamic_topology(ss, brush); - /* Intentionally set 'sd' to NULL since this is used for vertex paint too. */ - SculptThreadedTaskData data = { - .sd = NULL, - .ob = ob, - .brush = brush, - .nodes = nodes, - .totnode = totnode, - .has_bm_orco = has_bm_orco, - .use_area_nos = true, - .any_vertex_sampled = false, - }; + /* Intentionally set 'sd' to nullptr since this is used for vertex paint too. */ + SculptThreadedTaskData data{}; + data.sd = nullptr; + data.ob = ob; + data.brush = brush; + data.nodes = nodes; + data.totnode = totnode; + data.has_bm_orco = has_bm_orco; + data.use_area_nos = true; + data.any_vertex_sampled = false; AreaNormalCenterTLSData anctd = {{{0}}}; @@ -2234,17 +2239,16 @@ void SCULPT_calc_area_normal_and_center( const bool has_bm_orco = ss->bm && SCULPT_stroke_is_dynamic_topology(ss, brush); int n; - /* Intentionally set 'sd' to NULL since this is used for vertex paint too. */ - SculptThreadedTaskData data = { - .sd = NULL, - .ob = ob, - .brush = brush, - .nodes = nodes, - .totnode = totnode, - .has_bm_orco = has_bm_orco, - .use_area_cos = true, - .use_area_nos = true, - }; + /* Intentionally set 'sd' to nullptr since this is used for vertex paint too. */ + SculptThreadedTaskData data{}; + data.sd = nullptr; + data.ob = ob; + data.brush = brush; + data.nodes = nodes; + data.totnode = totnode; + data.has_bm_orco = has_bm_orco; + data.use_area_cos = true; + data.use_area_nos = true; AreaNormalCenterTLSData anctd = {{{0}}}; @@ -2298,7 +2302,7 @@ static float brush_strength(const Sculpt *sd, const StrokeCache *cache, const float feather, const UnifiedPaintSettings *ups, - const PaintModeSettings *UNUSED(paint_mode_settings)) + const PaintModeSettings * /*paint_mode_settings*/) { const Scene *scene = cache->vc->scene; const Brush *brush = BKE_paint_brush((Paint *)&sd->paint); @@ -2545,7 +2549,7 @@ float SCULPT_brush_strength_factor(SculptSession *ss, bool SCULPT_search_sphere_cb(PBVHNode *node, void *data_v) { - SculptSearchSphereData *data = data_v; + SculptSearchSphereData *data = static_cast<SculptSearchSphereData *>(data_v); const float *center; float nearest[3]; if (data->center) { @@ -2591,7 +2595,7 @@ bool SCULPT_search_sphere_cb(PBVHNode *node, void *data_v) bool SCULPT_search_circle_cb(PBVHNode *node, void *data_v) { - SculptSearchCircleData *data = data_v; + SculptSearchCircleData *data = static_cast<SculptSearchCircleData *>(data_v); float bb_min[3], bb_max[3]; if (data->ignore_fully_ineffective) { @@ -2653,15 +2657,14 @@ static PBVHNode **sculpt_pbvh_gather_cursor_update(Object *ob, int *r_totnode) { SculptSession *ss = ob->sculpt; - PBVHNode **nodes = NULL; - SculptSearchSphereData data = { - .ss = ss, - .sd = sd, - .radius_squared = ss->cursor_radius, - .original = use_original, - .ignore_fully_ineffective = false, - .center = NULL, - }; + PBVHNode **nodes = nullptr; + SculptSearchSphereData data{}; + data.ss = ss; + data.sd = sd; + data.radius_squared = ss->cursor_radius; + data.original = use_original; + data.ignore_fully_ineffective = false; + data.center = nullptr; BKE_pbvh_search_gather(ss->pbvh, SCULPT_search_sphere_cb, &data, &nodes, r_totnode); return nodes; } @@ -2674,34 +2677,32 @@ static PBVHNode **sculpt_pbvh_gather_generic(Object *ob, int *r_totnode) { SculptSession *ss = ob->sculpt; - PBVHNode **nodes = NULL; + PBVHNode **nodes = nullptr; /* Build a list of all nodes that are potentially within the cursor or brush's area of influence. */ if (brush->falloff_shape == PAINT_FALLOFF_SHAPE_SPHERE) { - SculptSearchSphereData data = { - .ss = ss, - .sd = sd, - .radius_squared = square_f(ss->cache->radius * radius_scale), - .original = use_original, - .ignore_fully_ineffective = brush->sculpt_tool != SCULPT_TOOL_MASK, - .center = NULL, - }; + SculptSearchSphereData data{}; + data.ss = ss; + data.sd = sd; + data.radius_squared = square_f(ss->cache->radius * radius_scale); + data.original = use_original; + data.ignore_fully_ineffective = brush->sculpt_tool != SCULPT_TOOL_MASK; + data.center = nullptr; BKE_pbvh_search_gather(ss->pbvh, SCULPT_search_sphere_cb, &data, &nodes, r_totnode); } else { - struct DistRayAABB_Precalc dist_ray_to_aabb_precalc; + DistRayAABB_Precalc dist_ray_to_aabb_precalc; dist_squared_ray_to_aabb_v3_precalc( &dist_ray_to_aabb_precalc, ss->cache->location, ss->cache->view_normal); - SculptSearchCircleData data = { - .ss = ss, - .sd = sd, - .radius_squared = ss->cache ? square_f(ss->cache->radius * radius_scale) : - ss->cursor_radius, - .original = use_original, - .dist_ray_to_aabb_precalc = &dist_ray_to_aabb_precalc, - .ignore_fully_ineffective = brush->sculpt_tool != SCULPT_TOOL_MASK, - }; + SculptSearchCircleData data{}; + data.ss = ss; + data.sd = sd; + data.radius_squared = ss->cache ? square_f(ss->cache->radius * radius_scale) : + ss->cursor_radius; + data.original = use_original; + data.dist_ray_to_aabb_precalc = &dist_ray_to_aabb_precalc; + data.ignore_fully_ineffective = brush->sculpt_tool != SCULPT_TOOL_MASK; BKE_pbvh_search_gather(ss->pbvh, SCULPT_search_circle_cb, &data, &nodes, r_totnode); } return nodes; @@ -2899,7 +2900,7 @@ static void sculpt_pbvh_update_pixels(PaintModeSettings *paint_mode_settings, /** \name Generic Brush Plane & Symmetry Utilities * \{ */ -typedef struct { +struct SculptRaycastData { SculptSession *ss; const float *ray_start; const float *ray_normal; @@ -2912,21 +2913,21 @@ typedef struct { int active_face_grid_index; - struct IsectRayPrecalc isect_precalc; -} SculptRaycastData; + IsectRayPrecalc isect_precalc; +}; -typedef struct { +struct SculptFindNearestToRayData { SculptSession *ss; const float *ray_start, *ray_normal; bool hit; float depth; float dist_sq_to_ray; bool original; -} SculptFindNearestToRayData; +}; ePaintSymmetryAreas SCULPT_get_vertex_symm_area(const float co[3]) { - ePaintSymmetryAreas symm_area = PAINT_SYMM_AREA_DEFAULT; + ePaintSymmetryAreas symm_area = ePaintSymmetryAreas(PAINT_SYMM_AREA_DEFAULT); if (co[0] < 0.0f) { symm_area |= PAINT_SYMM_AREA_X; } @@ -2945,7 +2946,7 @@ void SCULPT_flip_v3_by_symm_area(float v[3], const float pivot[3]) { for (int i = 0; i < 3; i++) { - ePaintSymmetryFlags symm_it = 1 << i; + ePaintSymmetryFlags symm_it = ePaintSymmetryFlags(1 << i); if (!(symm & symm_it)) { continue; } @@ -2964,7 +2965,7 @@ void SCULPT_flip_quat_by_symm_area(float quat[4], const float pivot[3]) { for (int i = 0; i < 3; i++) { - ePaintSymmetryFlags symm_it = 1 << i; + ePaintSymmetryFlags symm_it = ePaintSymmetryFlags(1 << i); if (!(symm & symm_it)) { continue; } @@ -3101,7 +3102,7 @@ static void do_gravity_task_cb_ex(void *__restrict userdata, const int n, const TaskParallelTLS *__restrict tls) { - SculptThreadedTaskData *data = userdata; + SculptThreadedTaskData *data = static_cast<SculptThreadedTaskData *>(userdata); SculptSession *ss = data->ob->sculpt; const Brush *brush = data->brush; float *offset = data->offset; @@ -3129,7 +3130,7 @@ static void do_gravity_task_cb_ex(void *__restrict userdata, vd.mask ? *vd.mask : 0.0f, vd.vertex, thread_id, - NULL); + nullptr); mul_v3_v3fl(proxy[vd.i], offset, fade); @@ -3155,13 +3156,12 @@ static void do_gravity(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode, fl mul_v3_fl(offset, bstrength); /* Threaded loop over nodes. */ - SculptThreadedTaskData data = { - .sd = sd, - .ob = ob, - .brush = brush, - .nodes = nodes, - .offset = offset, - }; + SculptThreadedTaskData data{}; + data.sd = sd; + data.ob = ob; + data.brush = brush; + data.nodes = nodes; + data.offset = offset; TaskParallelSettings settings; BKE_pbvh_parallel_range_settings(&settings, true, totnode); @@ -3177,10 +3177,9 @@ static void do_gravity(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode, fl void SCULPT_vertcos_to_key(Object *ob, KeyBlock *kb, const float (*vertCos)[3]) { Mesh *me = (Mesh *)ob->data; - float(*ofs)[3] = NULL; + float(*ofs)[3] = nullptr; int a; const int kb_act_idx = ob->shapenr - 1; - KeyBlock *currkey; /* For relative keys editing of base should update other keys. */ if (BKE_keyblock_is_basis(me->key, kb_act_idx)) { @@ -3192,7 +3191,7 @@ void SCULPT_vertcos_to_key(Object *ob, KeyBlock *kb, const float (*vertCos)[3]) } /* Apply offsets on other keys. */ - for (currkey = me->key->block.first; currkey; currkey = currkey->next) { + LISTBASE_FOREACH (KeyBlock *, currkey, &me->key->block) { if ((currkey != kb) && (currkey->relative == kb_act_idx)) { BKE_keyblock_update_from_offset(ob, currkey, ofs); } @@ -3221,8 +3220,8 @@ void SCULPT_vertcos_to_key(Object *ob, KeyBlock *kb, const float (*vertCos)[3]) static void sculpt_topology_update(Sculpt *sd, Object *ob, Brush *brush, - UnifiedPaintSettings *UNUSED(ups), - PaintModeSettings *UNUSED(paint_mode_settings)) + UnifiedPaintSettings * /*ups*/, + PaintModeSettings * /*paint_mode_settings*/) { SculptSession *ss = ob->sculpt; @@ -3244,7 +3243,7 @@ static void sculpt_topology_update(Sculpt *sd, MEM_SAFE_FREE(ss->vertex_info.boundary); MEM_SAFE_FREE(ss->vertex_info.connected_component); - PBVHTopologyUpdateMode mode = 0; + PBVHTopologyUpdateMode mode = PBVHTopologyUpdateMode(0); float location[3]; if (!(sd->flags & SCULPT_DYNTOPO_DETAIL_MANUAL)) { @@ -3289,9 +3288,9 @@ static void sculpt_topology_update(Sculpt *sd, static void do_brush_action_task_cb(void *__restrict userdata, const int n, - const TaskParallelTLS *__restrict UNUSED(tls)) + const TaskParallelTLS *__restrict /*tls*/) { - SculptThreadedTaskData *data = userdata; + SculptThreadedTaskData *data = static_cast<SculptThreadedTaskData *>(userdata); SculptSession *ss = data->ob->sculpt; bool need_coords = ss->cache->supports_gravity; @@ -3347,7 +3346,7 @@ static void do_brush_action(Sculpt *sd, if (SCULPT_tool_needs_all_pbvh_nodes(brush)) { /* These brushes need to update all nodes as they are not constrained by the brush radius */ - BKE_pbvh_search_gather(ss->pbvh, NULL, NULL, &nodes, &totnode); + BKE_pbvh_search_gather(ss->pbvh, nullptr, nullptr, &nodes, &totnode); } else if (brush->sculpt_tool == SCULPT_TOOL_CLOTH) { nodes = SCULPT_cloth_brush_affected_nodes_gather(ss, brush, &totnode); @@ -3385,7 +3384,7 @@ static void do_brush_action(Sculpt *sd, /* TODO(pablodp606): This check should be done in the undo code and not here, but the rest of * the sculpt code is not checking for unsupported undo types that may return a null node. */ if (BKE_pbvh_type(ss->pbvh) != PBVH_BMESH) { - SCULPT_undo_push_node(ob, NULL, SCULPT_UNDO_FACE_SETS); + SCULPT_undo_push_node(ob, nullptr, SCULPT_UNDO_FACE_SETS); } if (ss->cache->invert) { @@ -3412,9 +3411,9 @@ static void do_brush_action(Sculpt *sd, /* Initialize surface smooth cache. */ if ((brush->sculpt_tool == SCULPT_TOOL_SMOOTH) && (brush->smooth_deform_type == BRUSH_SMOOTH_DEFORM_SURFACE)) { - BLI_assert(ss->cache->surface_smooth_laplacian_disp == NULL); - ss->cache->surface_smooth_laplacian_disp = MEM_callocN( - sizeof(float[3]) * SCULPT_vertex_count_get(ss), "HC smooth laplacian b"); + BLI_assert(ss->cache->surface_smooth_laplacian_disp == nullptr); + ss->cache->surface_smooth_laplacian_disp = static_cast<float(*)[3]>( + MEM_callocN(sizeof(float[3]) * SCULPT_vertex_count_get(ss), "HC smooth laplacian b")); } } } @@ -3426,12 +3425,11 @@ static void do_brush_action(Sculpt *sd, float location[3]; if (!use_pixels) { - SculptThreadedTaskData task_data = { - .sd = sd, - .ob = ob, - .brush = brush, - .nodes = nodes, - }; + SculptThreadedTaskData task_data{}; + task_data.sd = sd; + task_data.ob = ob; + task_data.brush = brush; + task_data.nodes = nodes; TaskParallelSettings settings; BKE_pbvh_parallel_range_settings(&settings, true, totnode); @@ -3627,7 +3625,7 @@ static void do_brush_action(Sculpt *sd, static void sculpt_flush_pbvhvert_deform(Object *ob, PBVHVertexIter *vd) { SculptSession *ss = ob->sculpt; - Mesh *me = ob->data; + Mesh *me = static_cast<Mesh *>(ob->data); float disp[3], newco[3]; int index = vd->vert_indices[vd->i]; @@ -3646,9 +3644,9 @@ static void sculpt_flush_pbvhvert_deform(Object *ob, PBVHVertexIter *vd) static void sculpt_combine_proxies_task_cb(void *__restrict userdata, const int n, - const TaskParallelTLS *__restrict UNUSED(tls)) + const TaskParallelTLS *__restrict /*tls*/) { - SculptThreadedTaskData *data = userdata; + SculptThreadedTaskData *data = static_cast<SculptThreadedTaskData *>(userdata); SculptSession *ss = data->ob->sculpt; Sculpt *sd = data->sd; Object *ob = data->ob; @@ -3657,7 +3655,7 @@ static void sculpt_combine_proxies_task_cb(void *__restrict userdata, PBVHVertexIter vd; PBVHProxyNode *proxies; int proxy_count; - float(*orco)[3] = NULL; + float(*orco)[3] = nullptr; if (use_orco && !ss->bm) { orco = SCULPT_undo_push_node(data->ob, data->nodes[n], SCULPT_UNDO_COORDS)->co; @@ -3718,13 +3716,12 @@ static void sculpt_combine_proxies(Sculpt *sd, Object *ob) BKE_pbvh_gather_proxies(ss->pbvh, &nodes, &totnode); - SculptThreadedTaskData data = { - .sd = sd, - .ob = ob, - .brush = brush, - .nodes = nodes, - .use_proxies_orco = use_orco, - }; + SculptThreadedTaskData data{}; + data.sd = sd; + data.ob = ob; + data.brush = brush; + data.nodes = nodes; + data.use_proxies_orco = use_orco; TaskParallelSettings settings; BKE_pbvh_parallel_range_settings(&settings, true, totnode); @@ -3739,12 +3736,11 @@ void SCULPT_combine_transform_proxies(Sculpt *sd, Object *ob) int totnode; BKE_pbvh_gather_proxies(ss->pbvh, &nodes, &totnode); - SculptThreadedTaskData data = { - .sd = sd, - .ob = ob, - .nodes = nodes, - .use_proxies_orco = false, - }; + SculptThreadedTaskData data{}; + data.sd = sd; + data.ob = ob; + data.nodes = nodes; + data.use_proxies_orco = false; TaskParallelSettings settings; BKE_pbvh_parallel_range_settings(&settings, true, totnode); @@ -3783,9 +3779,9 @@ static void sculpt_update_keyblock(Object *ob) static void SCULPT_flush_stroke_deform_task_cb(void *__restrict userdata, const int n, - const TaskParallelTLS *__restrict UNUSED(tls)) + const TaskParallelTLS *__restrict /*tls*/) { - SculptThreadedTaskData *data = userdata; + SculptThreadedTaskData *data = static_cast<SculptThreadedTaskData *>(userdata); SculptSession *ss = data->ob->sculpt; Object *ob = data->ob; float(*vertCos)[3] = data->vertCos; @@ -3817,25 +3813,25 @@ void SCULPT_flush_stroke_deform(Sculpt *sd, Object *ob, bool is_proxy_used) int totnode; Mesh *me = (Mesh *)ob->data; PBVHNode **nodes; - float(*vertCos)[3] = NULL; + float(*vertCos)[3] = nullptr; if (ss->shapekey_active) { - vertCos = MEM_mallocN(sizeof(*vertCos) * me->totvert, "flushStrokeDeofrm keyVerts"); + vertCos = static_cast<float(*)[3]>( + MEM_mallocN(sizeof(*vertCos) * me->totvert, "flushStrokeDeofrm keyVerts")); /* Mesh could have isolated verts which wouldn't be in BVH, to deal with this we copy old * coordinates over new ones and then update coordinates for all vertices from BVH. */ memcpy(vertCos, ss->orig_cos, sizeof(*vertCos) * me->totvert); } - BKE_pbvh_search_gather(ss->pbvh, NULL, NULL, &nodes, &totnode); + BKE_pbvh_search_gather(ss->pbvh, nullptr, nullptr, &nodes, &totnode); - SculptThreadedTaskData data = { - .sd = sd, - .ob = ob, - .brush = brush, - .nodes = nodes, - .vertCos = vertCos, - }; + SculptThreadedTaskData data{}; + data.sd = sd; + data.ob = ob; + data.brush = brush; + data.nodes = nodes; + data.vertCos = vertCos; TaskParallelSettings settings; BKE_pbvh_parallel_range_settings(&settings, true, totnode); @@ -3854,7 +3850,7 @@ void SCULPT_flush_stroke_deform(Sculpt *sd, Object *ob, bool is_proxy_used) } void SCULPT_cache_calc_brushdata_symm(StrokeCache *cache, - const char symm, + const ePaintSymmetryFlags symm, const char axis, const float angle) { @@ -3904,11 +3900,11 @@ void SCULPT_cache_calc_brushdata_symm(StrokeCache *cache, } } -typedef void (*BrushActionFunc)(Sculpt *sd, - Object *ob, - Brush *brush, - UnifiedPaintSettings *ups, - PaintModeSettings *paint_mode_settings); +using BrushActionFunc = void (*)(Sculpt *sd, + Object *ob, + Brush *brush, + UnifiedPaintSettings *ups, + PaintModeSettings *paint_mode_settings); static void do_tiled(Sculpt *sd, Object *ob, @@ -3980,9 +3976,9 @@ static void do_radial_symmetry(Sculpt *sd, UnifiedPaintSettings *ups, PaintModeSettings *paint_mode_settings, BrushActionFunc action, - const char symm, + const ePaintSymmetryFlags symm, const int axis, - const float UNUSED(feather)) + const float /*feather*/) { SculptSession *ss = ob->sculpt; @@ -4031,15 +4027,16 @@ static void do_symmetrical_brush_actions(Sculpt *sd, if (!SCULPT_is_symmetry_iteration_valid(i, symm)) { continue; } - cache->mirror_symmetry_pass = i; + const ePaintSymmetryFlags symm = ePaintSymmetryFlags(i); + cache->mirror_symmetry_pass = symm; cache->radial_symmetry_pass = 0; - SCULPT_cache_calc_brushdata_symm(cache, i, 0, 0); + SCULPT_cache_calc_brushdata_symm(cache, symm, 0, 0); do_tiled(sd, ob, brush, ups, paint_mode_settings, action); - do_radial_symmetry(sd, ob, brush, ups, paint_mode_settings, action, i, 'X', feather); - do_radial_symmetry(sd, ob, brush, ups, paint_mode_settings, action, i, 'Y', feather); - do_radial_symmetry(sd, ob, brush, ups, paint_mode_settings, action, i, 'Z', feather); + do_radial_symmetry(sd, ob, brush, ups, paint_mode_settings, action, symm, 'X', feather); + do_radial_symmetry(sd, ob, brush, ups, paint_mode_settings, action, symm, 'Y', feather); + do_radial_symmetry(sd, ob, brush, ups, paint_mode_settings, action, symm, 'Z', feather); } } @@ -4172,11 +4169,9 @@ void SCULPT_cache_free(StrokeCache *cache) /* Initialize mirror modifier clipping. */ static void sculpt_init_mirror_clipping(Object *ob, SculptSession *ss) { - ModifierData *md; - unit_m4(ss->cache->clip_mirror_mtx); - for (md = ob->modifiers.first; md; md = md->next) { + LISTBASE_FOREACH (ModifierData *, md, &ob->modifiers) { if (!(md->type == eModifierType_Mirror && (md->mode & eModifierMode_Realtime))) { continue; } @@ -4272,11 +4267,12 @@ static void smooth_brush_toggle_off(const bContext *C, Paint *paint, StrokeCache static void sculpt_update_cache_invariants( bContext *C, Sculpt *sd, SculptSession *ss, wmOperator *op, const float mval[2]) { - StrokeCache *cache = MEM_callocN(sizeof(StrokeCache), "stroke cache"); + StrokeCache *cache = static_cast<StrokeCache *>( + MEM_callocN(sizeof(StrokeCache), "stroke cache")); ToolSettings *tool_settings = CTX_data_tool_settings(C); UnifiedPaintSettings *ups = &tool_settings->unified_paint_settings; Brush *brush = BKE_paint_brush(&sd->paint); - ViewContext *vc = paint_stroke_view_context(op->customdata); + ViewContext *vc = paint_stroke_view_context(static_cast<PaintStroke *>(op->customdata)); Object *ob = CTX_data_active_object(C); float mat[3][3]; float viewDir[3] = {0.0f, 0.0f, 1.0f}; @@ -4830,8 +4826,8 @@ static void sculpt_raycast_cb(PBVHNode *node, void *data_v, float *tmin) if (BKE_pbvh_node_get_tmin(node) >= *tmin) { return; } - SculptRaycastData *srd = data_v; - float(*origco)[3] = NULL; + SculptRaycastData *srd = static_cast<SculptRaycastData *>(data_v); + float(*origco)[3] = nullptr; bool use_origco = false; if (srd->original && srd->ss->cache) { @@ -4841,7 +4837,7 @@ static void sculpt_raycast_cb(PBVHNode *node, void *data_v, float *tmin) else { /* Intersect with coordinates from before we started stroke. */ SculptUndoNode *unode = SCULPT_undo_get_node(node, SCULPT_UNDO_COORDS); - origco = (unode) ? unode->co : NULL; + origco = (unode) ? unode->co : nullptr; use_origco = origco ? true : false; } } @@ -4867,8 +4863,8 @@ static void sculpt_find_nearest_to_ray_cb(PBVHNode *node, void *data_v, float *t if (BKE_pbvh_node_get_tmin(node) >= *tmin) { return; } - SculptFindNearestToRayData *srd = data_v; - float(*origco)[3] = NULL; + SculptFindNearestToRayData *srd = static_cast<SculptFindNearestToRayData *>(data_v); + float(*origco)[3] = nullptr; bool use_origco = false; if (srd->original && srd->ss->cache) { @@ -4878,7 +4874,7 @@ static void sculpt_find_nearest_to_ray_cb(PBVHNode *node, void *data_v, float *t else { /* Intersect with coordinates from before we started stroke. */ SculptUndoNode *unode = SCULPT_undo_get_node(node, SCULPT_UNDO_COORDS); - origco = (unode) ? unode->co : NULL; + origco = (unode) ? unode->co : nullptr; use_origco = origco ? true : false; } } @@ -4906,7 +4902,7 @@ float SCULPT_raycast_init(ViewContext *vc, float obimat[4][4]; float dist; Object *ob = vc->obact; - RegionView3D *rv3d = vc->region->regiondata; + RegionView3D *rv3d = static_cast<RegionView3D *>(vc->region->regiondata); View3D *v3d = vc->v3d; /* TODO: what if the segment is totally clipped? (return == 0). */ @@ -4967,15 +4963,15 @@ bool SCULPT_cursor_geometry_info_update(bContext *C, depth = SCULPT_raycast_init(&vc, mval, ray_start, ray_end, ray_normal, original); SCULPT_stroke_modifiers_check(C, ob, brush); - SculptRaycastData srd = { - .original = original, - .ss = ob->sculpt, - .hit = false, - .ray_start = ray_start, - .ray_normal = ray_normal, - .depth = depth, - .face_normal = face_normal, - }; + SculptRaycastData srd{}; + srd.original = original; + srd.ss = ob->sculpt; + srd.hit = false; + srd.ray_start = ray_start; + srd.ray_normal = ray_normal; + srd.depth = depth; + srd.face_normal = face_normal; + isect_ray_tri_watertight_v3_precalc(&srd.isect_precalc, ray_normal); BKE_pbvh_raycast(ss->pbvh, sculpt_raycast_cb, &srd, ray_start, ray_normal, srd.original); @@ -5123,15 +5119,15 @@ bool SCULPT_stroke_get_location(bContext *C, return hit; } - SculptFindNearestToRayData srd = { - .original = original, - .ss = ob->sculpt, - .hit = false, - .ray_start = ray_start, - .ray_normal = ray_normal, - .depth = FLT_MAX, - .dist_sq_to_ray = FLT_MAX, - }; + SculptFindNearestToRayData srd{}; + srd.original = original; + srd.ss = ob->sculpt; + srd.hit = false; + srd.ray_start = ray_start; + srd.ray_normal = ray_normal; + srd.depth = FLT_MAX; + srd.dist_sq_to_ray = FLT_MAX; + BKE_pbvh_find_nearest_to_ray( ss->pbvh, sculpt_find_nearest_to_ray_cb, &srd, ray_start, ray_normal, srd.original); if (srd.hit) { @@ -5155,7 +5151,7 @@ static void sculpt_brush_init_tex(Sculpt *sd, SculptSession *ss) ntreeTexBeginExecTree(mtex->tex->nodetree); } - if (ss->tex_pool == NULL) { + if (ss->tex_pool == nullptr) { ss->tex_pool = BKE_image_pool_new(); } } @@ -5256,7 +5252,7 @@ void SCULPT_flush_update_step(bContext *C, SculptUpdateType update_flags) rv3d->rflag |= RV3D_PAINTING; } - if (mmd != NULL) { + if (mmd != nullptr) { multires_mark_as_modified(depsgraph, ob, MULTIRES_COORDS_MODIFIED); } @@ -5317,7 +5313,7 @@ void SCULPT_flush_update_done(const bContext *C, Object *ob, SculptUpdateType up wmWindowManager *wm = CTX_wm_manager(C); RegionView3D *current_rv3d = CTX_wm_region_view3d(C); SculptSession *ss = ob->sculpt; - Mesh *mesh = ob->data; + Mesh *mesh = static_cast<Mesh *>(ob->data); /* Always needed for linked duplicates. */ bool need_tag = (ID_REAL_USERS(&mesh->id) > 1); @@ -5329,7 +5325,7 @@ void SCULPT_flush_update_done(const bContext *C, Object *ob, SculptUpdateType up LISTBASE_FOREACH (wmWindow *, win, &wm->windows) { bScreen *screen = WM_window_get_active_screen(win); LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) { - SpaceLink *sl = area->spacedata.first; + SpaceLink *sl = static_cast<SpaceLink *>(area->spacedata.first); if (sl->spacetype != SPACE_VIEW3D) { continue; } @@ -5339,7 +5335,7 @@ void SCULPT_flush_update_done(const bContext *C, Object *ob, SculptUpdateType up * current viewport was deactivated. */ LISTBASE_FOREACH (ARegion *, region, &area->regionbase) { if (region->regiontype == RGN_TYPE_WINDOW) { - RegionView3D *rv3d = region->regiondata; + RegionView3D *rv3d = static_cast<RegionView3D *>(region->regiondata); if (rv3d != current_rv3d) { need_tag |= !BKE_sculptsession_use_pbvh_draw(ob, rv3d); } @@ -5351,7 +5347,7 @@ void SCULPT_flush_update_done(const bContext *C, Object *ob, SculptUpdateType up if (update_flags & SCULPT_UPDATE_IMAGE) { LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) { - SpaceLink *sl = area->spacedata.first; + SpaceLink *sl = static_cast<SpaceLink *>(area->spacedata.first); if (sl->spacetype != SPACE_IMAGE) { continue; } @@ -5397,7 +5393,7 @@ void SCULPT_flush_update_done(const bContext *C, Object *ob, SculptUpdateType up /* Returns whether the mouse/stylus is over the mesh (1) * or over the background (0). */ -static bool over_mesh(bContext *C, struct wmOperator *UNUSED(op), const float mval[2]) +static bool over_mesh(bContext *C, wmOperator * /*op*/, const float mval[2]) { float co_dummy[3]; return SCULPT_stroke_get_location(C, co_dummy, mval, false); @@ -5453,13 +5449,13 @@ bool SCULPT_handles_colors_report(SculptSession *ss, ReportList *reports) return false; } -static bool sculpt_stroke_test_start(bContext *C, struct wmOperator *op, const float mval[2]) +static bool sculpt_stroke_test_start(bContext *C, wmOperator *op, const float mval[2]) { /* Don't start the stroke until `mval` goes over the mesh. * NOTE: `mval` will only be null when re-executing the saved stroke. * We have exception for 'exec' strokes since they may not set `mval`, * only 'location', see: T52195. */ - if (((op->flag & OP_IS_INVOKE) == 0) || (mval == NULL) || over_mesh(C, op, mval)) { + if (((op->flag & OP_IS_INVOKE) == 0) || (mval == nullptr) || over_mesh(C, op, mval)) { Object *ob = CTX_data_active_object(C); SculptSession *ss = ob->sculpt; Sculpt *sd = CTX_data_tool_settings(C)->sculpt; @@ -5494,8 +5490,8 @@ static bool sculpt_stroke_test_start(bContext *C, struct wmOperator *op, const f } static void sculpt_stroke_update_step(bContext *C, - wmOperator *UNUSED(op), - struct PaintStroke *stroke, + wmOperator * /*op*/, + PaintStroke *stroke, PointerRNA *itemptr) { UnifiedPaintSettings *ups = &CTX_data_tool_settings(C)->unified_paint_settings; @@ -5582,7 +5578,7 @@ static void sculpt_brush_exit_tex(Sculpt *sd) } } -static void sculpt_stroke_done(const bContext *C, struct PaintStroke *UNUSED(stroke)) +static void sculpt_stroke_done(const bContext *C, PaintStroke * /*stroke*/) { Object *ob = CTX_data_active_object(C); SculptSession *ss = ob->sculpt; @@ -5614,7 +5610,7 @@ static void sculpt_stroke_done(const bContext *C, struct PaintStroke *UNUSED(str BKE_pbvh_node_color_buffer_free(ss->pbvh); SCULPT_cache_free(ss->cache); - ss->cache = NULL; + ss->cache = nullptr; sculpt_stroke_undo_end(C, brush); @@ -5640,7 +5636,7 @@ static void sculpt_stroke_done(const bContext *C, struct PaintStroke *UNUSED(str static int sculpt_brush_stroke_invoke(bContext *C, wmOperator *op, const wmEvent *event) { - struct PaintStroke *stroke; + PaintStroke *stroke; int ignore_background_click; int retval; Object *ob = CTX_data_active_object(C); @@ -5682,7 +5678,7 @@ static int sculpt_brush_stroke_invoke(bContext *C, wmOperator *op, const wmEvent SCULPT_stroke_get_location, sculpt_stroke_test_start, sculpt_stroke_update_step, - NULL, + nullptr, sculpt_stroke_done, event->type); @@ -5690,15 +5686,15 @@ static int sculpt_brush_stroke_invoke(bContext *C, wmOperator *op, const wmEvent /* For tablet rotation. */ ignore_background_click = RNA_boolean_get(op->ptr, "ignore_background_click"); - - if (ignore_background_click && !over_mesh(C, op, (const float[2]){UNPACK2(event->mval)})) { - paint_stroke_free(C, op, op->customdata); + const float mval[2] = {float(event->mval[0]), float(event->mval[1])}; + if (ignore_background_click && !over_mesh(C, op, mval)) { + paint_stroke_free(C, op, static_cast<PaintStroke *>(op->customdata)); return OPERATOR_PASS_THROUGH; } retval = op->type->modal(C, op, event); if (ELEM(retval, OPERATOR_FINISHED, OPERATOR_CANCELLED)) { - paint_stroke_free(C, op, op->customdata); + paint_stroke_free(C, op, static_cast<PaintStroke *>(op->customdata)); return retval; } /* Add modal handler. */ @@ -5719,12 +5715,12 @@ static int sculpt_brush_stroke_exec(bContext *C, wmOperator *op) SCULPT_stroke_get_location, sculpt_stroke_test_start, sculpt_stroke_update_step, - NULL, + nullptr, sculpt_stroke_done, 0); /* Frees op->customdata. */ - paint_stroke_exec(C, op, op->customdata); + paint_stroke_exec(C, op, static_cast<PaintStroke *>(op->customdata)); return OPERATOR_FINISHED; } @@ -5742,11 +5738,11 @@ static void sculpt_brush_stroke_cancel(bContext *C, wmOperator *op) paint_mesh_restore_co(sd, ob); } - paint_stroke_cancel(C, op, op->customdata); + paint_stroke_cancel(C, op, static_cast<PaintStroke *>(op->customdata)); if (ss->cache) { SCULPT_cache_free(ss->cache); - ss->cache = NULL; + ss->cache = nullptr; } sculpt_brush_exit_tex(sd); @@ -5754,9 +5750,9 @@ static void sculpt_brush_stroke_cancel(bContext *C, wmOperator *op) static int sculpt_brush_stroke_modal(bContext *C, wmOperator *op, const wmEvent *event) { - bool started = op->customdata && paint_stroke_started((struct PaintStroke *)op->customdata); + bool started = op->customdata && paint_stroke_started((PaintStroke *)op->customdata); - int retval = paint_stroke_modal(C, op, event, (struct PaintStroke **)&op->customdata); + int retval = paint_stroke_modal(C, op, event, (PaintStroke **)&op->customdata); if (!started && ELEM(retval, OPERATOR_FINISHED, OPERATOR_CANCELLED)) { /* Did the stroke never start? If so push a blank sculpt undo @@ -5779,7 +5775,7 @@ static int sculpt_brush_stroke_modal(bContext *C, wmOperator *op, const wmEvent return retval; } -static void sculpt_redo_empty_ui(bContext *UNUSED(C), wmOperator *UNUSED(op)) +static void sculpt_redo_empty_ui(bContext * /*C*/, wmOperator * /*op*/) { } @@ -5850,8 +5846,8 @@ static int SCULPT_vertex_get_connected_component(SculptSession *ss, PBVHVertRef static void SCULPT_fake_neighbor_init(SculptSession *ss, const float max_dist) { const int totvert = SCULPT_vertex_count_get(ss); - ss->fake_neighbors.fake_neighbor_index = MEM_malloc_arrayN( - totvert, sizeof(int), "fake neighbor"); + ss->fake_neighbors.fake_neighbor_index = static_cast<int *>( + MEM_malloc_arrayN(totvert, sizeof(int), "fake neighbor")); for (int i = 0; i < totvert; i++) { ss->fake_neighbors.fake_neighbor_index[i] = FAKE_NEIGHBOR_NONE; } @@ -5875,19 +5871,20 @@ static void sculpt_pose_fake_neighbors_free(SculptSession *ss) MEM_SAFE_FREE(ss->fake_neighbors.fake_neighbor_index); } -typedef struct NearestVertexFakeNeighborTLSData { +struct NearestVertexFakeNeighborTLSData { PBVHVertRef nearest_vertex; float nearest_vertex_distance_squared; int current_topology_id; -} NearestVertexFakeNeighborTLSData; +}; static void do_fake_neighbor_search_task_cb(void *__restrict userdata, const int n, const TaskParallelTLS *__restrict tls) { - SculptThreadedTaskData *data = userdata; + SculptThreadedTaskData *data = static_cast<SculptThreadedTaskData *>(userdata); SculptSession *ss = data->ob->sculpt; - NearestVertexFakeNeighborTLSData *nvtd = tls->userdata_chunk; + NearestVertexFakeNeighborTLSData *nvtd = static_cast<NearestVertexFakeNeighborTLSData *>( + tls->userdata_chunk); PBVHVertexIter vd; BKE_pbvh_vertex_iter_begin (ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) { @@ -5905,12 +5902,13 @@ static void do_fake_neighbor_search_task_cb(void *__restrict userdata, BKE_pbvh_vertex_iter_end; } -static void fake_neighbor_search_reduce(const void *__restrict UNUSED(userdata), +static void fake_neighbor_search_reduce(const void *__restrict /*userdata*/, void *__restrict chunk_join, void *__restrict chunk) { - NearestVertexFakeNeighborTLSData *join = chunk_join; - NearestVertexFakeNeighborTLSData *nvtd = chunk; + NearestVertexFakeNeighborTLSData *join = static_cast<NearestVertexFakeNeighborTLSData *>( + chunk_join); + NearestVertexFakeNeighborTLSData *nvtd = static_cast<NearestVertexFakeNeighborTLSData *>(chunk); if (join->nearest_vertex.i == PBVH_REF_NONE) { join->nearest_vertex = nvtd->nearest_vertex; join->nearest_vertex_distance_squared = nvtd->nearest_vertex_distance_squared; @@ -5927,27 +5925,26 @@ static PBVHVertRef SCULPT_fake_neighbor_search(Sculpt *sd, float max_distance) { SculptSession *ss = ob->sculpt; - PBVHNode **nodes = NULL; + PBVHNode **nodes = nullptr; int totnode; - SculptSearchSphereData data = { - .ss = ss, - .sd = sd, - .radius_squared = max_distance * max_distance, - .original = false, - .center = SCULPT_vertex_co_get(ss, vertex), - }; + SculptSearchSphereData data{}; + data.ss = ss; + data.sd = sd; + data.radius_squared = max_distance * max_distance; + data.original = false; + data.center = SCULPT_vertex_co_get(ss, vertex); + BKE_pbvh_search_gather(ss->pbvh, SCULPT_search_sphere_cb, &data, &nodes, &totnode); if (totnode == 0) { return BKE_pbvh_make_vref(PBVH_REF_NONE); } - SculptThreadedTaskData task_data = { - .sd = sd, - .ob = ob, - .nodes = nodes, - .max_distance_squared = max_distance * max_distance, - }; + SculptThreadedTaskData task_data{}; + task_data.sd = sd; + task_data.ob = ob; + task_data.nodes = nodes; + task_data.max_distance_squared = max_distance * max_distance; copy_v3_v3(task_data.nearest_vertex_search_co, SCULPT_vertex_co_get(ss, vertex)); @@ -5968,17 +5965,14 @@ static PBVHVertRef SCULPT_fake_neighbor_search(Sculpt *sd, return nvtd.nearest_vertex; } -typedef struct SculptTopologyIDFloodFillData { +struct SculptTopologyIDFloodFillData { int next_id; -} SculptTopologyIDFloodFillData; +}; -static bool SCULPT_connected_components_floodfill_cb(SculptSession *ss, - PBVHVertRef from_v, - PBVHVertRef to_v, - bool UNUSED(is_duplicate), - void *userdata) +static bool SCULPT_connected_components_floodfill_cb( + SculptSession *ss, PBVHVertRef from_v, PBVHVertRef to_v, bool /*is_duplicate*/, void *userdata) { - SculptTopologyIDFloodFillData *data = userdata; + SculptTopologyIDFloodFillData *data = static_cast<SculptTopologyIDFloodFillData *>(userdata); int from_v_i = BKE_pbvh_vertex_to_index(ss->pbvh, from_v); int to_v_i = BKE_pbvh_vertex_to_index(ss->pbvh, to_v); @@ -6000,7 +5994,8 @@ void SCULPT_connected_components_ensure(Object *ob) } const int totvert = SCULPT_vertex_count_get(ss); - ss->vertex_info.connected_component = MEM_malloc_arrayN(totvert, sizeof(int), "topology ID"); + ss->vertex_info.connected_component = static_cast<int *>( + MEM_malloc_arrayN(totvert, sizeof(int), "topology ID")); for (int i = 0; i < totvert; i++) { ss->vertex_info.connected_component[i] = SCULPT_TOPOLOGY_ID_NONE; @@ -6036,8 +6031,8 @@ void SCULPT_boundary_info_ensure(Object *object) const MLoop *loops = BKE_mesh_loops(base_mesh); ss->vertex_info.boundary = BLI_BITMAP_NEW(base_mesh->totvert, "Boundary info"); - int *adjacent_faces_edge_count = MEM_calloc_arrayN( - base_mesh->totedge, sizeof(int), "Adjacent face edge count"); + int *adjacent_faces_edge_count = static_cast<int *>( + MEM_calloc_arrayN(base_mesh->totedge, sizeof(int), "Adjacent face edge count")); for (int p = 0; p < base_mesh->totpoly; p++) { const MPoly *poly = &polys[p]; @@ -6091,14 +6086,14 @@ void SCULPT_fake_neighbors_ensure(Sculpt *sd, Object *ob, const float max_dist) void SCULPT_fake_neighbors_enable(Object *ob) { SculptSession *ss = ob->sculpt; - BLI_assert(ss->fake_neighbors.fake_neighbor_index != NULL); + BLI_assert(ss->fake_neighbors.fake_neighbor_index != nullptr); ss->fake_neighbors.use_fake_neighbors = true; } void SCULPT_fake_neighbors_disable(Object *ob) { SculptSession *ss = ob->sculpt; - BLI_assert(ss->fake_neighbors.fake_neighbor_index != NULL); + BLI_assert(ss->fake_neighbors.fake_neighbor_index != nullptr); ss->fake_neighbors.use_fake_neighbors = false; } @@ -6109,7 +6104,7 @@ void SCULPT_fake_neighbors_free(Object *ob) } void SCULPT_automasking_node_begin(Object *ob, - const SculptSession *UNUSED(ss), + const SculptSession * /*ss*/, AutomaskingCache *automasking, AutomaskingNodeData *automask_data, PBVHNode *node) @@ -6131,7 +6126,7 @@ void SCULPT_automasking_node_begin(Object *ob, } } -void SCULPT_automasking_node_update(SculptSession *UNUSED(ss), +void SCULPT_automasking_node_update(SculptSession * /*ss*/, AutomaskingNodeData *automask_data, PBVHVertexIter *vd) { @@ -6177,7 +6172,7 @@ void SCULPT_stroke_id_next(Object *ob) /* Manually wrap in int32 space to avoid tripping up undefined behavior * sanitizers. */ - ob->sculpt->stroke_id = (uchar)(((int)ob->sculpt->stroke_id + 1) & 255); + ob->sculpt->stroke_id = uchar((int(ob->sculpt->stroke_id) + 1) & 255); } void SCULPT_stroke_id_ensure(Object *ob) diff --git a/source/blender/editors/sculpt_paint/sculpt_intern.h b/source/blender/editors/sculpt_paint/sculpt_intern.h index bf47b64d176..852b3c2719a 100644 --- a/source/blender/editors/sculpt_paint/sculpt_intern.h +++ b/source/blender/editors/sculpt_paint/sculpt_intern.h @@ -341,7 +341,7 @@ typedef struct SculptBrushTest { float radius; float location[3]; float dist; - int mirror_symmetry_pass; + ePaintSymmetryFlags mirror_symmetry_pass; int radial_symmetry_pass; float symm_rot_mat_inv[4][4]; @@ -556,7 +556,8 @@ typedef struct StrokeCache { /* Symmetry index between 0 and 7 bit combo 0 is Brush only; * 1 is X mirror; 2 is Y mirror; 3 is XY; 4 is Z; 5 is XZ; 6 is YZ; 7 is XYZ */ int symmetry; - int mirror_symmetry_pass; /* The symmetry pass we are currently on between 0 and 7. */ + ePaintSymmetryFlags + mirror_symmetry_pass; /* The symmetry pass we are currently on between 0 and 7. */ float true_view_normal[3]; float view_normal[3]; @@ -1526,7 +1527,10 @@ bool SCULPT_pbvh_calc_area_normal(const struct Brush *brush, * Flip all the edit-data across the axis/axes specified by \a symm. * Used to calculate multiple modifications to the mesh when symmetry is enabled. */ -void SCULPT_cache_calc_brushdata_symm(StrokeCache *cache, char symm, char axis, float angle); +void SCULPT_cache_calc_brushdata_symm(StrokeCache *cache, + ePaintSymmetryFlags symm, + char axis, + float angle); void SCULPT_cache_free(StrokeCache *cache); /* -------------------------------------------------------------------- */ diff --git a/source/blender/editors/sculpt_paint/sculpt_ops.c b/source/blender/editors/sculpt_paint/sculpt_ops.c index 8affb0e9d53..0e7873bc652 100644 --- a/source/blender/editors/sculpt_paint/sculpt_ops.c +++ b/source/blender/editors/sculpt_paint/sculpt_ops.c @@ -246,15 +246,17 @@ static void SCULPT_OT_symmetrize(wmOperatorType *ot) ot->exec = sculpt_symmetrize_exec; ot->poll = sculpt_no_multires_poll; - RNA_def_float(ot->srna, - "merge_tolerance", - 0.001f, - 0.0f, - FLT_MAX, - "Merge Distance", - "Distance within which symmetrical vertices are merged", - 0.0f, - 1.0f); + PropertyRNA *prop = RNA_def_float(ot->srna, + "merge_tolerance", + 0.0005f, + 0.0f, + FLT_MAX, + "Merge Distance", + "Distance within which symmetrical vertices are merged", + 0.0f, + 1.0f); + + RNA_def_property_ui_range(prop, 0.0, FLT_MAX, 0.001, 5); } /**** Toggle operator for turning sculpt mode on or off ****/ @@ -1202,7 +1204,7 @@ static void SCULPT_OT_mask_from_cavity(wmOperatorType *ot) RNA_def_boolean(ot->srna, "use_automask_settings", false, - "Use Automask Settings", + "Automask Settings", "Use default settings from Options panel in sculpt mode"); RNA_def_float(ot->srna, @@ -1210,7 +1212,7 @@ static void SCULPT_OT_mask_from_cavity(wmOperatorType *ot) 0.5f, 0.0f, 5.0f, - "Cavity Factor", + "Factor", "The contrast of the cavity mask", 0.0f, 1.0f); @@ -1219,11 +1221,11 @@ static void SCULPT_OT_mask_from_cavity(wmOperatorType *ot) 2, 0, 25, - "Cavity Blur", + "Blur", "The number of times the cavity mask is blurred", 0, 25); - RNA_def_boolean(ot->srna, "use_curve", false, "Use Curve", ""); + RNA_def_boolean(ot->srna, "use_curve", false, "Custom Curve", ""); RNA_def_boolean(ot->srna, "invert", false, "Cavity (Inverted)", ""); } diff --git a/source/blender/editors/space_node/space_node.cc b/source/blender/editors/space_node/space_node.cc index ce0273eec81..c993fa57d76 100644 --- a/source/blender/editors/space_node/space_node.cc +++ b/source/blender/editors/space_node/space_node.cc @@ -5,6 +5,7 @@ * \ingroup spnode */ +#include "DNA_ID.h" #include "DNA_gpencil_types.h" #include "DNA_light_types.h" #include "DNA_material_types.h" @@ -28,6 +29,8 @@ #include "UI_resources.h" #include "UI_view2d.h" +#include "DEG_depsgraph.h" + #include "BLO_read_write.h" #include "RNA_access.h" @@ -191,6 +194,13 @@ void ED_node_set_active_viewer_key(SpaceNode *snode) { bNodeTreePath *path = (bNodeTreePath *)snode->treepath.last; if (snode->nodetree && path) { + /* A change in active viewer may result in the change of the output node used by the + * compositor, so we need to get notified about such changes. */ + if (snode->nodetree->active_viewer_key.value != path->parent_key.value) { + DEG_id_tag_update(&snode->nodetree->id, ID_RECALC_NTREE_OUTPUT); + WM_main_add_notifier(NC_NODE, nullptr); + } + snode->nodetree->active_viewer_key = path->parent_key; } } diff --git a/source/blender/editors/space_text/text_ops.c b/source/blender/editors/space_text/text_ops.c index f0196bf8e00..0ddd06ead62 100644 --- a/source/blender/editors/space_text/text_ops.c +++ b/source/blender/editors/space_text/text_ops.c @@ -3487,10 +3487,10 @@ static int text_insert_invoke(bContext *C, wmOperator *op, const wmEvent *event) /* NOTE: the "text" property is always set from key-map, * so we can't use #RNA_struct_property_is_set, check the length instead. */ if (!RNA_string_length(op->ptr, "text")) { - /* if alt/ctrl/super are pressed pass through except for utf8 character event + /* If Alt/Control/Super are pressed pass through except for utf8 character event * (when input method are used for utf8 inputs, the user may assign key event - * including alt/ctrl/super like ctrl+m to commit utf8 string. in such case, - * the modifiers in the utf8 character event make no sense.) */ + * including Alt/Control/Super like Control-M to commit utf8 string. + * In such case, the modifiers in the utf8 character event make no sense). */ if ((event->modifier & (KM_CTRL | KM_OSKEY)) && !event->utf8_buf[0]) { return OPERATOR_PASS_THROUGH; } diff --git a/source/blender/geometry/intern/trim_curves.cc b/source/blender/geometry/intern/trim_curves.cc index 192c47b0d43..1aff07f2b4e 100644 --- a/source/blender/geometry/intern/trim_curves.cc +++ b/source/blender/geometry/intern/trim_curves.cc @@ -895,7 +895,7 @@ bke::CurvesGeometry trim_curves(const bke::CurvesGeometry &src_curves, } } - /* Compute destiation curves. */ + /* Compute destination curves. */ compute_curve_trim_parameters(src_curves, selection, starts, diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpenciloutline.c b/source/blender/gpencil_modifiers/intern/MOD_gpenciloutline.c index 455d8b0b528..dff8d14564a 100644 --- a/source/blender/gpencil_modifiers/intern/MOD_gpenciloutline.c +++ b/source/blender/gpencil_modifiers/intern/MOD_gpenciloutline.c @@ -287,7 +287,7 @@ static void updateDepsgraph(GpencilModifierData *md, DEG_add_object_relation(ctx->node, ctx->object, DEG_OB_COMP_TRANSFORM, "Outline Modifier"); } -static void panel_draw(const bContext *UNUSED(C), Panel *panel) +static void panel_draw(const bContext *C, Panel *panel) { uiLayout *layout = panel->layout; @@ -302,6 +302,11 @@ static void panel_draw(const bContext *UNUSED(C), Panel *panel) uiItemR(layout, ptr, "outline_material", 0, NULL, ICON_NONE); uiItemR(layout, ptr, "object", 0, NULL, ICON_NONE); + Scene *scene = CTX_data_scene(C); + if (scene->camera == NULL) { + uiItemL(layout, IFACE_("Outline requires an active camera"), ICON_ERROR); + } + gpencil_modifier_panel_end(layout, ptr); } diff --git a/source/blender/gpu/intern/gpu_node_graph.h b/source/blender/gpu/intern/gpu_node_graph.h index de0a0687b13..2f617713749 100644 --- a/source/blender/gpu/intern/gpu_node_graph.h +++ b/source/blender/gpu/intern/gpu_node_graph.h @@ -66,7 +66,7 @@ typedef enum { GPU_NODE_TAG_COMPOSITOR = (1 << 6), } eGPUNodeTag; -ENUM_OPERATORS(eGPUNodeTag, GPU_NODE_TAG_FUNCTION) +ENUM_OPERATORS(eGPUNodeTag, GPU_NODE_TAG_COMPOSITOR) struct GPUNode { struct GPUNode *next, *prev; diff --git a/source/blender/imbuf/intern/jp2.c b/source/blender/imbuf/intern/jp2.c index f3d6d19cb8d..4320f870d64 100644 --- a/source/blender/imbuf/intern/jp2.c +++ b/source/blender/imbuf/intern/jp2.c @@ -125,7 +125,7 @@ struct BufInfo { static void opj_read_from_buffer_free(void *UNUSED(p_user_data)) { - /* nop */ + /* NOP. */ } static OPJ_SIZE_T opj_read_from_buffer(void *p_buffer, OPJ_SIZE_T p_nb_bytes, void *p_user_data) diff --git a/source/blender/imbuf/intern/openexr/openexr_api.cpp b/source/blender/imbuf/intern/openexr/openexr_api.cpp index d4a89c9e1c9..d2bdb5041c5 100644 --- a/source/blender/imbuf/intern/openexr/openexr_api.cpp +++ b/source/blender/imbuf/intern/openexr/openexr_api.cpp @@ -811,7 +811,7 @@ static void imb_exr_get_views(MultiPartInputFile &file, StringVector &views) } } -/* Multilayer Blender files have the view name in all the passes (even the default view one) */ +/* Multi-layer Blender files have the view name in all the passes (even the default view one). */ static void imb_exr_insert_view_name(char *name_full, const char *passname, const char *viewname) { BLI_assert(!ELEM(name_full, passname, viewname)); diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h index 8d02b274c65..274b2094ee7 100644 --- a/source/blender/makesdna/DNA_scene_types.h +++ b/source/blender/makesdna/DNA_scene_types.h @@ -2302,6 +2302,7 @@ typedef enum ePaintSymmetryFlags { PAINT_TILE_Y = (1 << 5), PAINT_TILE_Z = (1 << 6), } ePaintSymmetryFlags; +ENUM_OPERATORS(ePaintSymmetryFlags, PAINT_TILE_Z); #define PAINT_SYMM_AXIS_ALL (PAINT_SYMM_X | PAINT_SYMM_Y | PAINT_SYMM_Z) diff --git a/source/blender/sequencer/intern/effects.c b/source/blender/sequencer/intern/effects.c index 6dd75031f3b..3e3fe85ed39 100644 --- a/source/blender/sequencer/intern/effects.c +++ b/source/blender/sequencer/intern/effects.c @@ -709,8 +709,8 @@ static void do_gammacross_effect_float( rt[2] = gammaCorrect(mfac * invGammaCorrect(rt1[2]) + fac * invGammaCorrect(rt2[2])); rt[3] = gammaCorrect(mfac * invGammaCorrect(rt1[3]) + fac * invGammaCorrect(rt2[3])); rt1 += 4; - rt2+=4; - rt+=4; + rt2 += 4; + rt += 4; } } } diff --git a/tests/python/CMakeLists.txt b/tests/python/CMakeLists.txt index 51da4c24538..e5a9151ec3e 100644 --- a/tests/python/CMakeLists.txt +++ b/tests/python/CMakeLists.txt @@ -639,7 +639,7 @@ endif() # SVG Import if(True) - set(_svg_render_tests path) + set(_svg_render_tests complex path) foreach(render_test ${_svg_render_tests}) add_python_test( diff --git a/tests/python/bl_io_curve_svg_test.py b/tests/python/bl_io_curve_svg_test.py index 092dfa5497a..f36036a5b52 100644 --- a/tests/python/bl_io_curve_svg_test.py +++ b/tests/python/bl_io_curve_svg_test.py @@ -50,7 +50,10 @@ def main(): from modules import render_report report = render_report.Report('IO Curve SVG', output_dir, idiff) report.set_pixelated(True) - print(test_dir) + + test_dir_name = Path(test_dir).name + if test_dir_name == 'complex': + report.set_fail_percent(0.01) ok = report.run(test_dir, blender, get_arguments, batch=True) diff --git a/tests/python/modules/render_report.py b/tests/python/modules/render_report.py index 15d46d6d127..5dcb73b65cc 100755 --- a/tests/python/modules/render_report.py +++ b/tests/python/modules/render_report.py @@ -166,6 +166,9 @@ class Report: def set_fail_threshold(self, threshold): self.fail_threshold = threshold + def set_fail_percent(self, percent): + self.fail_percent = percent + def set_reference_dir(self, reference_dir): self.reference_dir = reference_dir |