diff options
author | Jacques Lucke <jacques@blender.org> | 2021-11-15 15:21:15 +0300 |
---|---|---|
committer | Jacques Lucke <jacques@blender.org> | 2021-11-15 15:21:15 +0300 |
commit | a9ac8b44d5aea5d56eb132d3ff1ed3934478ea9c (patch) | |
tree | 1b52fdbcfd23e54d4cadf4f54d4a48a0b1451ee4 /source/blender | |
parent | 36bf158e5c184e048d59d3da202c8e1a5a109140 (diff) | |
parent | c2c65cc4bf9467c180387ae791bd4fe3e7fbba8c (diff) |
Merge branch 'master' into node-tree-update-refactor
Diffstat (limited to 'source/blender')
125 files changed, 1474 insertions, 987 deletions
diff --git a/source/blender/blenfont/BLF_api.h b/source/blender/blenfont/BLF_api.h index 217a4d5d918..fa8e764139d 100644 --- a/source/blender/blenfont/BLF_api.h +++ b/source/blender/blenfont/BLF_api.h @@ -65,7 +65,7 @@ void BLF_metrics_attach(int fontid, unsigned char *mem, int mem_size); void BLF_aspect(int fontid, float x, float y, float z); void BLF_position(int fontid, float x, float y, float z); -void BLF_size(int fontid, int size, int dpi); +void BLF_size(int fontid, float size, int dpi); /* goal: small but useful color API */ void BLF_color4ubv(int fontid, const unsigned char rgba[4]); diff --git a/source/blender/blenfont/intern/blf.c b/source/blender/blenfont/intern/blf.c index 34ddb6f22d2..d6773916abd 100644 --- a/source/blender/blenfont/intern/blf.c +++ b/source/blender/blenfont/intern/blf.c @@ -363,7 +363,7 @@ void BLF_position(int fontid, float x, float y, float z) } } -void BLF_size(int fontid, int size, int dpi) +void BLF_size(int fontid, float size, int dpi) { FontBLF *font = blf_get(fontid); @@ -910,7 +910,7 @@ void BLF_state_print(int fontid) if (font) { printf("fontid %d %p\n", fontid, (void *)font); printf(" name: '%s'\n", font->name); - printf(" size: %u\n", font->size); + printf(" size: %f\n", font->size); printf(" dpi: %u\n", font->dpi); printf(" pos: %.6f %.6f %.6f\n", UNPACK3(font->pos)); printf(" aspect: (%d) %.6f %.6f %.6f\n", diff --git a/source/blender/blenfont/intern/blf_font.c b/source/blender/blenfont/intern/blf_font.c index d536a0b8486..959faca2f46 100644 --- a/source/blender/blenfont/intern/blf_font.c +++ b/source/blender/blenfont/intern/blf_font.c @@ -1350,19 +1350,24 @@ void blf_font_free(FontBLF *font) /** \name Font Configure * \{ */ -void blf_font_size(FontBLF *font, unsigned int size, unsigned int dpi) +void blf_font_size(FontBLF *font, float size, unsigned int dpi) { blf_glyph_cache_acquire(font); + /* FreeType uses fixed-point integers in 64ths. */ + FT_F26Dot6 ft_size = lroundf(size * 64.0f); + /* Adjust our size to be on even 64ths. */ + size = (float)ft_size / 64.0f; + GlyphCacheBLF *gc = blf_glyph_cache_find(font, size, dpi); if (gc && (font->size == size && font->dpi == dpi)) { /* Optimization: do not call FT_Set_Char_Size if size did not change. */ } else { - const FT_Error err = FT_Set_Char_Size(font->face, 0, ((FT_F26Dot6)(size)) * 64, dpi, dpi); + const FT_Error err = FT_Set_Char_Size(font->face, 0, ft_size, dpi, dpi); if (err) { /* FIXME: here we can go through the fixed size and choice a close one */ - printf("The current font don't support the size, %u and dpi, %u\n", size, dpi); + printf("The current font don't support the size, %f and dpi, %u\n", size, dpi); } else { font->size = size; diff --git a/source/blender/blenfont/intern/blf_glyph.c b/source/blender/blenfont/intern/blf_glyph.c index a9d00151e99..5f14ef433e9 100644 --- a/source/blender/blenfont/intern/blf_glyph.c +++ b/source/blender/blenfont/intern/blf_glyph.c @@ -76,7 +76,7 @@ static FT_Fixed to_16dot16(double val) /** * Find a glyph cache that matches a size, DPI & styles. */ -GlyphCacheBLF *blf_glyph_cache_find(FontBLF *font, unsigned int size, unsigned int dpi) +GlyphCacheBLF *blf_glyph_cache_find(FontBLF *font, float size, unsigned int dpi) { GlyphCacheBLF *gc = (GlyphCacheBLF *)font->cache.first; while (gc) { diff --git a/source/blender/blenfont/intern/blf_internal.h b/source/blender/blenfont/intern/blf_internal.h index a715d5df692..cec20995dc6 100644 --- a/source/blender/blenfont/intern/blf_internal.h +++ b/source/blender/blenfont/intern/blf_internal.h @@ -52,7 +52,7 @@ struct FontBLF *blf_font_new(const char *name, const char *filename); struct FontBLF *blf_font_new_from_mem(const char *name, const unsigned char *mem, int mem_size); void blf_font_attach_from_mem(struct FontBLF *font, const unsigned char *mem, int mem_size); -void blf_font_size(struct FontBLF *font, unsigned int size, unsigned int dpi); +void blf_font_size(struct FontBLF *font, float size, unsigned int dpi); void blf_font_draw(struct FontBLF *font, const char *str, size_t str_len, @@ -130,9 +130,7 @@ int blf_font_count_missing_chars(struct FontBLF *font, void blf_font_free(struct FontBLF *font); -struct GlyphCacheBLF *blf_glyph_cache_find(struct FontBLF *font, - unsigned int size, - unsigned int dpi); +struct GlyphCacheBLF *blf_glyph_cache_find(struct FontBLF *font, float size, unsigned int dpi); struct GlyphCacheBLF *blf_glyph_cache_new(struct FontBLF *font); struct GlyphCacheBLF *blf_glyph_cache_acquire(struct FontBLF *font); void blf_glyph_cache_release(struct FontBLF *font); diff --git a/source/blender/blenfont/intern/blf_internal_types.h b/source/blender/blenfont/intern/blf_internal_types.h index aae666fa182..46156edbb1f 100644 --- a/source/blender/blenfont/intern/blf_internal_types.h +++ b/source/blender/blenfont/intern/blf_internal_types.h @@ -65,7 +65,7 @@ typedef struct GlyphCacheBLF { struct GlyphCacheBLF *prev; /* font size. */ - unsigned int size; + float size; /* and dpi. */ unsigned int dpi; @@ -205,7 +205,7 @@ typedef struct FontBLF { unsigned int dpi; /* font size. */ - unsigned int size; + float size; /* Column width when printing monospaced. */ int fixed_width; diff --git a/source/blender/blenfont/intern/blf_thumbs.c b/source/blender/blenfont/intern/blf_thumbs.c index 12a83f7634e..bbdb26a61b6 100644 --- a/source/blender/blenfont/intern/blf_thumbs.c +++ b/source/blender/blenfont/intern/blf_thumbs.c @@ -95,7 +95,7 @@ void BLF_thumb_preview(const char *filename, const size_t draw_str_i18n_len = strlen(draw_str_i18n); int draw_str_i18n_nbr = 0; - blf_font_size(font, (unsigned int)MAX2(font_size_min, font_size_curr), dpi); + blf_font_size(font, (float)MAX2(font_size_min, font_size_curr), dpi); gc = blf_glyph_cache_find(font, font->size, font->dpi); /* There will be no matching glyph cache if blf_font_size() failed to set font size. */ if (!gc) { diff --git a/source/blender/blenkernel/BKE_action.h b/source/blender/blenkernel/BKE_action.h index 9f69c5e3976..763e540fdd9 100644 --- a/source/blender/blenkernel/BKE_action.h +++ b/source/blender/blenkernel/BKE_action.h @@ -125,6 +125,17 @@ struct bActionGroup *BKE_action_group_find_name(struct bAction *act, const char /* Clear all 'temp' flags on all groups */ void action_groups_clear_tempflags(struct bAction *act); +/** + * Return whether the action has one unique point in time keyed. + * + * This is mostly for the pose library, which will have different behavior depending on whether an + * Action corresponds to a "pose" (one keyframe) or "animation snippet" (multiple keyframes). + * + * \return `false` when there is no keyframe at all or keys on different points in time, `true` + * when exactly one point in time is keyed. + */ +bool BKE_action_has_single_frame(const struct bAction *act); + /* Pose API ----------------- */ void BKE_pose_channel_free(struct bPoseChannel *pchan); diff --git a/source/blender/blenkernel/BKE_blender_copybuffer.h b/source/blender/blenkernel/BKE_blender_copybuffer.h index 1dd6d495276..4dd7145e66d 100644 --- a/source/blender/blenkernel/BKE_blender_copybuffer.h +++ b/source/blender/blenkernel/BKE_blender_copybuffer.h @@ -31,16 +31,18 @@ struct ReportList; struct bContext; /* copybuffer (wrapper for BKE_blendfile_write_partial) */ -void BKE_copybuffer_begin(struct Main *bmain_src); -void BKE_copybuffer_tag_ID(struct ID *id); -bool BKE_copybuffer_save(struct Main *bmain_src, const char *filename, struct ReportList *reports); +void BKE_copybuffer_copy_begin(struct Main *bmain_src); +void BKE_copybuffer_copy_tag_ID(struct ID *id); +bool BKE_copybuffer_copy_end(struct Main *bmain_src, + const char *filename, + struct ReportList *reports); bool BKE_copybuffer_read(struct Main *bmain_dst, const char *libname, struct ReportList *reports, const uint64_t id_types_mask); int BKE_copybuffer_paste(struct bContext *C, const char *libname, - const short flag, + const int flag, struct ReportList *reports, const uint64_t id_types_mask); diff --git a/source/blender/blenkernel/BKE_global.h b/source/blender/blenkernel/BKE_global.h index 1e3fe61552a..4f1da0a972f 100644 --- a/source/blender/blenkernel/BKE_global.h +++ b/source/blender/blenkernel/BKE_global.h @@ -45,7 +45,6 @@ typedef struct Global { /** When set: `G_MAIN->name` contains valid relative base path. */ bool relbase_valid; - bool file_loaded; bool save_over; /** Strings of recent opened files. */ diff --git a/source/blender/blenkernel/BKE_lib_id.h b/source/blender/blenkernel/BKE_lib_id.h index b38125b791d..4faf6d94df8 100644 --- a/source/blender/blenkernel/BKE_lib_id.h +++ b/source/blender/blenkernel/BKE_lib_id.h @@ -134,8 +134,10 @@ enum { LIB_ID_COPY_SHAPEKEY = 1 << 26, /** EXCEPTION! Specific deep-copy of node trees used e.g. for rendering purposes. */ LIB_ID_COPY_NODETREE_LOCALIZE = 1 << 27, - /** EXCEPTION! Specific handling of RB objects regarding collections differs depending whether we - duplicate scene/collections, or objects. */ + /** + * EXCEPTION! Specific handling of RB objects regarding collections differs depending whether we + * duplicate scene/collections, or objects. + */ LIB_ID_COPY_RIGID_BODY_NO_COLLECTION_HANDLING = 1 << 28, /* *** Helper 'defines' gathering most common flag sets. *** */ diff --git a/source/blender/blenkernel/BKE_spline.hh b/source/blender/blenkernel/BKE_spline.hh index 8509b730709..1d34768b1a2 100644 --- a/source/blender/blenkernel/BKE_spline.hh +++ b/source/blender/blenkernel/BKE_spline.hh @@ -306,11 +306,23 @@ class BezierSpline final : public Spline { blender::Span<HandleType> handle_types_left() const; blender::MutableSpan<HandleType> handle_types_left(); blender::Span<blender::float3> handle_positions_left() const; - blender::MutableSpan<blender::float3> handle_positions_left(); + /** + * Get writable access to the handle position. + * + * \param write_only: pass true for an uninitialized spline, this prevents accessing + * uninitialized memory while auto-generating handles. + */ + blender::MutableSpan<blender::float3> handle_positions_left(bool write_only = false); blender::Span<HandleType> handle_types_right() const; blender::MutableSpan<HandleType> handle_types_right(); blender::Span<blender::float3> handle_positions_right() const; - blender::MutableSpan<blender::float3> handle_positions_right(); + /** + * Get writable access to the handle position. + * + * \param write_only: pass true for an uninitialized spline, this prevents accessing + * uninitialized memory while auto-generating handles. + */ + blender::MutableSpan<blender::float3> handle_positions_right(bool write_only = false); void ensure_auto_handles() const; void translate(const blender::float3 &translation) override; diff --git a/source/blender/blenkernel/intern/action.c b/source/blender/blenkernel/intern/action.c index cae72ddf68c..2cc1cba99cd 100644 --- a/source/blender/blenkernel/intern/action.c +++ b/source/blender/blenkernel/intern/action.c @@ -51,6 +51,7 @@ #include "BKE_anim_visualization.h" #include "BKE_animsys.h" #include "BKE_armature.h" +#include "BKE_asset.h" #include "BKE_constraint.h" #include "BKE_deform.h" #include "BKE_fcurve.h" @@ -286,6 +287,30 @@ static void action_blend_read_expand(BlendExpander *expander, ID *id) } } +static IDProperty *action_asset_type_property(const bAction *action) +{ + const bool is_single_frame = !BKE_action_has_single_frame(action); + + IDPropertyTemplate idprop = {0}; + idprop.i = is_single_frame; + + IDProperty *property = IDP_New(IDP_INT, &idprop, "is_single_frame"); + return property; +} + +static void action_asset_pre_save(void *asset_ptr, struct AssetMetaData *asset_data) +{ + bAction *action = (bAction *)asset_ptr; + BLI_assert(GS(action->id.name) == ID_AC); + + IDProperty *action_type = action_asset_type_property(action); + BKE_asset_metadata_idprop_ensure(asset_data, action_type); +} + +AssetTypeInfo AssetType_AC = { + /* pre_save_fn */ action_asset_pre_save, +}; + IDTypeInfo IDType_ID_AC = { .id_code = ID_AC, .id_filter = FILTER_ID_AC, @@ -312,6 +337,8 @@ IDTypeInfo IDType_ID_AC = { .blend_read_undo_preserve = NULL, .lib_override_apply_post = NULL, + + .asset_type_info = &AssetType_AC, }; /* ***************** Library data level operations on action ************** */ @@ -1418,6 +1445,47 @@ bool action_has_motion(const bAction *act) return false; } +bool BKE_action_has_single_frame(const struct bAction *act) +{ + if (act == NULL || BLI_listbase_is_empty(&act->curves)) { + return false; + } + + bool found_key = false; + float found_key_frame = 0.0f; + + LISTBASE_FOREACH (FCurve *, fcu, &act->curves) { + switch (fcu->totvert) { + case 0: + /* No keys, so impossible to come to a conclusion on this curve alone. */ + continue; + case 1: + /* Single key, which is the complex case, so handle below. */ + break; + default: + /* Multiple keys, so there is animation. */ + return false; + } + + const float this_key_frame = fcu->bezt != NULL ? fcu->bezt[0].vec[1][0] : fcu->fpt[0].vec[0]; + if (!found_key) { + found_key = true; + found_key_frame = this_key_frame; + continue; + } + + /* The graph editor rounds to 1/1000th of a frame, so it's not necessary to be really precise + * with these comparisons. */ + if (!compare_ff(found_key_frame, this_key_frame, 0.001f)) { + /* This key differs from the already-found key, so this Action represents animation. */ + return false; + } + } + + /* There is only a single frame if we found at least one key. */ + return found_key; +} + /* Calculate the extents of given action */ void calc_action_range(const bAction *act, float *start, float *end, short incl_modifiers) { diff --git a/source/blender/blenkernel/intern/action_test.cc b/source/blender/blenkernel/intern/action_test.cc index c02eca966ad..c0d9a4c6055 100644 --- a/source/blender/blenkernel/intern/action_test.cc +++ b/source/blender/blenkernel/intern/action_test.cc @@ -24,6 +24,8 @@ #include "BLI_listbase.h" +#include "MEM_guardedalloc.h" + #include "testing/testing.h" namespace blender::bke::tests { @@ -141,4 +143,97 @@ TEST(action_groups, ReconstructGroupsWithReordering) EXPECT_EQ(groupDcurve2.next, nullptr); } +namespace { + +/* Allocate fcu->bezt, and also return a unique_ptr to it for easily freeing the memory. */ +std::unique_ptr<BezTriple[]> allocate_keyframes(FCurve *fcu, const size_t num_keyframes) +{ + auto bezt_uptr = std::make_unique<BezTriple[]>(num_keyframes); + fcu->bezt = bezt_uptr.get(); + return bezt_uptr; +} + +/* Append keyframe, assumes that fcu->bezt is allocated and has enough space. */ +void add_keyframe(FCurve *fcu, float x, float y) +{ + /* The insert_keyframe functions are in the editors, so we cannot link to those here. */ + BezTriple the_keyframe; + memset(&the_keyframe, 0, sizeof(the_keyframe)); + + /* Copied from insert_vert_fcurve() in keyframing.c. */ + the_keyframe.vec[0][0] = x - 1.0f; + the_keyframe.vec[0][1] = y; + the_keyframe.vec[1][0] = x; + the_keyframe.vec[1][1] = y; + the_keyframe.vec[2][0] = x + 1.0f; + the_keyframe.vec[2][1] = y; + + memcpy(&fcu->bezt[fcu->totvert], &the_keyframe, sizeof(the_keyframe)); + fcu->totvert++; +} + +} // namespace + +TEST(action_assets, BKE_action_has_single_frame) +{ + /* NULL action. */ + EXPECT_FALSE(BKE_action_has_single_frame(nullptr)) << "NULL Action cannot have a single frame."; + + /* No FCurves. */ + { + const bAction empty = {nullptr}; + EXPECT_FALSE(BKE_action_has_single_frame(&empty)) + << "Action without FCurves cannot have a single frame."; + } + + /* One curve with one key. */ + { + FCurve fcu = {nullptr}; + std::unique_ptr<BezTriple[]> bezt = allocate_keyframes(&fcu, 1); + add_keyframe(&fcu, 1.0f, 2.0f); + + bAction action = {nullptr}; + BLI_addtail(&action.curves, &fcu); + + EXPECT_TRUE(BKE_action_has_single_frame(&action)) + << "Action with one FCurve and one key should have single frame."; + } + + /* Two curves with one key each. */ + { + FCurve fcu1 = {nullptr}; + FCurve fcu2 = {nullptr}; + std::unique_ptr<BezTriple[]> bezt1 = allocate_keyframes(&fcu1, 1); + std::unique_ptr<BezTriple[]> bezt2 = allocate_keyframes(&fcu2, 1); + add_keyframe(&fcu1, 1.0f, 327.0f); + add_keyframe(&fcu2, 1.0f, 47.0f); /* Same X-coordinate as the other one. */ + + bAction action = {nullptr}; + BLI_addtail(&action.curves, &fcu1); + BLI_addtail(&action.curves, &fcu2); + + EXPECT_TRUE(BKE_action_has_single_frame(&action)) + << "Two FCurves with keys on the same frame should have single frame."; + + /* Modify the 2nd curve so it's keyed on a different frame. */ + fcu2.bezt[0].vec[1][0] = 2.0f; + EXPECT_FALSE(BKE_action_has_single_frame(&action)) + << "Two FCurves with keys on different frames should have animation."; + } + + /* One curve with two keys. */ + { + FCurve fcu = {nullptr}; + std::unique_ptr<BezTriple[]> bezt = allocate_keyframes(&fcu, 2); + add_keyframe(&fcu, 1.0f, 2.0f); + add_keyframe(&fcu, 2.0f, 2.5f); + + bAction action = {nullptr}; + BLI_addtail(&action.curves, &fcu); + + EXPECT_FALSE(BKE_action_has_single_frame(&action)) + << "Action with one FCurve and two keys must have animation."; + } +} + } // namespace blender::bke::tests diff --git a/source/blender/blenkernel/intern/blender_copybuffer.c b/source/blender/blenkernel/intern/blender_copybuffer.c index 9c9f898afef..f8b943d3479 100644 --- a/source/blender/blenkernel/intern/blender_copybuffer.c +++ b/source/blender/blenkernel/intern/blender_copybuffer.c @@ -57,20 +57,26 @@ /** \name Copy/Paste `.blend`, partial saves. * \{ */ -void BKE_copybuffer_begin(Main *bmain_src) +/** Initialize a copy operation. */ +void BKE_copybuffer_copy_begin(Main *bmain_src) { BKE_blendfile_write_partial_begin(bmain_src); } -void BKE_copybuffer_tag_ID(ID *id) +/** Mark an ID to be copied. Should only be called after a call to #BKE_copybuffer_copy_begin. */ +void BKE_copybuffer_copy_tag_ID(ID *id) { BKE_blendfile_write_partial_tag_ID(id, true); } /** - * \return Success. + * Finalize a copy operation into given .blend file 'buffer'. + * + * \param filename: Full path to the .blend file used as copy/paste buffer. + * + * \return true on success, false otherwise. */ -bool BKE_copybuffer_save(Main *bmain_src, const char *filename, ReportList *reports) +bool BKE_copybuffer_copy_end(Main *bmain_src, const char *filename, ReportList *reports) { const int write_flags = 0; const eBLO_WritePathRemap remap_mode = BLO_WRITE_PATH_REMAP_RELATIVE; @@ -82,6 +88,16 @@ bool BKE_copybuffer_save(Main *bmain_src, const char *filename, ReportList *repo return retval; } +/** + * Paste datablocks from the given .blend file 'buffer' (i.e. append them). + * + * Unlike #BKE_copybuffer_paste, it does not perform any instantiation of collections/objects/etc. + * + * \param libname: Full path to the .blend file used as copy/paste buffer. + * \param id_types_mask: Only directly link IDs of those types from the given .blend file buffer. + * + * \return true on success, false otherwise. + */ bool BKE_copybuffer_read(Main *bmain_dst, const char *libname, ReportList *reports, @@ -116,12 +132,22 @@ bool BKE_copybuffer_read(Main *bmain_dst, } /** - * \return Number of IDs directly pasted from the buffer - * (does not includes indirectly pulled out ones). + * Paste datablocks from the given .blend file 'buffer' (i.e. append them). + * + * Similar to #BKE_copybuffer_read, but also handles instantiation of collections/objects/etc. + * + * \param libname: Full path to the .blend file used as copy/paste buffer. + * \param flag: A combination of #eBLOLibLinkFlags and ##eFileSel_Params_Flag to control + * link/append behavior. + * \note: Ignores #FILE_LINK flag, since it always appends IDs. + * \param id_types_mask: Only directly link IDs of those types from the given .blend file buffer. + * + * \return Number of IDs directly pasted from the buffer (does not includes indirectly linked + * ones). */ int BKE_copybuffer_paste(bContext *C, const char *libname, - const short flag, + const int flag, ReportList *reports, const uint64_t id_types_mask) { diff --git a/source/blender/blenkernel/intern/curve_eval.cc b/source/blender/blenkernel/intern/curve_eval.cc index bb745d5b20d..ff0478f2543 100644 --- a/source/blender/blenkernel/intern/curve_eval.cc +++ b/source/blender/blenkernel/intern/curve_eval.cc @@ -225,8 +225,8 @@ static SplinePtr spline_from_dna_bezier(const Nurb &nurb) Span<const BezTriple> src_points{nurb.bezt, nurb.pntsu}; spline->resize(src_points.size()); MutableSpan<float3> positions = spline->positions(); - MutableSpan<float3> handle_positions_left = spline->handle_positions_left(); - MutableSpan<float3> handle_positions_right = spline->handle_positions_right(); + MutableSpan<float3> handle_positions_left = spline->handle_positions_left(true); + MutableSpan<float3> handle_positions_right = spline->handle_positions_right(true); MutableSpan<BezierSpline::HandleType> handle_types_left = spline->handle_types_left(); MutableSpan<BezierSpline::HandleType> handle_types_right = spline->handle_types_right(); MutableSpan<float> radii = spline->radii(); diff --git a/source/blender/blenkernel/intern/fcurve_driver.c b/source/blender/blenkernel/intern/fcurve_driver.c index 6e03f362160..3ac64dbf84b 100644 --- a/source/blender/blenkernel/intern/fcurve_driver.c +++ b/source/blender/blenkernel/intern/fcurve_driver.c @@ -422,7 +422,7 @@ static float dvar_eval_locDiff(ChannelDriver *driver, DriverVar *dvar) } } else { - /* Convert to worldspace. */ + /* Convert to world-space. */ copy_v3_v3(tmp_loc, pchan->pose_head); mul_m4_v3(ob->obmat, tmp_loc); } diff --git a/source/blender/blenkernel/intern/image_gen.c b/source/blender/blenkernel/intern/image_gen.c index 943909cc90f..bef14b6ad70 100644 --- a/source/blender/blenkernel/intern/image_gen.c +++ b/source/blender/blenkernel/intern/image_gen.c @@ -369,7 +369,7 @@ static void checker_board_text( char text[3] = {'A', '1', '\0'}; const int mono = blf_mono_font_render; - BLF_size(mono, 54, 72); /* hard coded size! */ + BLF_size(mono, 54.0f, 72); /* hard coded size! */ /* OCIO_TODO: using NULL as display will assume using sRGB display * this is correct since currently generated images are assumed to be in sRGB space, diff --git a/source/blender/blenkernel/intern/mesh_mirror.c b/source/blender/blenkernel/intern/mesh_mirror.c index b20d81e7b9c..6df13e71e72 100644 --- a/source/blender/blenkernel/intern/mesh_mirror.c +++ b/source/blender/blenkernel/intern/mesh_mirror.c @@ -260,10 +260,16 @@ Mesh *BKE_mesh_mirror_apply_mirror_on_axis_for_modifier(MirrorModifierData *mmd, mul_m4_v3(mtx, mv->co); if (do_vtargetmap) { - /* compare location of the original and mirrored vertex, to see if they - * should be mapped for merging */ + /* Compare location of the original and mirrored vertex, + * to see if they should be mapped for merging. + * + * Always merge from the copied into the original vertices so it's possible to + * generate a 1:1 mapping by scanning vertices from the beginning of the array + * as is done in #BKE_editmesh_vert_coords_when_deformed. Without this, + * the coordinates returned will sometimes point to the copied vertex locations, see: T91444. + */ if (UNLIKELY(len_squared_v3v3(mv_prev->co, mv->co) < tolerance_sq)) { - *vtmap_a = maxVerts + i; + *vtmap_b = i; tot_vtargetmap++; /* average location */ @@ -271,10 +277,11 @@ Mesh *BKE_mesh_mirror_apply_mirror_on_axis_for_modifier(MirrorModifierData *mmd, copy_v3_v3(mv_prev->co, mv->co); } else { - *vtmap_a = -1; + *vtmap_b = -1; } - *vtmap_b = -1; /* fill here to avoid 2x loops */ + /* Fill here to avoid 2x loops. */ + *vtmap_a = -1; vtmap_a++; vtmap_b++; diff --git a/source/blender/blenkernel/intern/mesh_runtime.c b/source/blender/blenkernel/intern/mesh_runtime.c index ce89c723a61..7b1d5140421 100644 --- a/source/blender/blenkernel/intern/mesh_runtime.c +++ b/source/blender/blenkernel/intern/mesh_runtime.c @@ -113,7 +113,7 @@ void BKE_mesh_runtime_reset_on_copy(Mesh *mesh, const int UNUSED(flag)) /** * \brief This function clears runtime cache of the given mesh. - * + * * Call this function to recalculate runtime data when used. */ void BKE_mesh_runtime_clear_cache(Mesh *mesh) diff --git a/source/blender/blenkernel/intern/node.cc b/source/blender/blenkernel/intern/node.cc index f8e23da5222..468a597e242 100644 --- a/source/blender/blenkernel/intern/node.cc +++ b/source/blender/blenkernel/intern/node.cc @@ -1541,7 +1541,7 @@ static bNodeSocket *make_socket(bNodeTree *ntree, } /* make the identifier unique */ BLI_uniquename_cb( - unique_identifier_check, lb, "socket", '.', auto_identifier, sizeof(auto_identifier)); + unique_identifier_check, lb, "socket", '_', auto_identifier, sizeof(auto_identifier)); bNodeSocket *sock = (bNodeSocket *)MEM_callocN(sizeof(bNodeSocket), "sock"); sock->in_out = in_out; @@ -4776,6 +4776,9 @@ static OutputFieldDependency find_group_output_dependencies( /* Propagate search further to the left. */ for (const InputSocketRef *origin_input_socket : gather_input_socket_dependencies(field_dependency, origin_node)) { + if (!origin_input_socket->is_available()) { + continue; + } if (!field_state_by_socket_id[origin_input_socket->id()].is_single) { if (handled_sockets.add(origin_input_socket)) { sockets_to_check.push(origin_input_socket); @@ -4824,6 +4827,9 @@ static void propagate_data_requirements_from_right_to_left( const Vector<const InputSocketRef *> connected_inputs = gather_input_socket_dependencies( field_dependency, *node); for (const InputSocketRef *input_socket : connected_inputs) { + if (!input_socket->is_available()) { + continue; + } if (inferencing_interface.inputs[input_socket->index()] == InputSocketFieldType::Implicit) { if (!input_socket->is_logically_linked()) { diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c index 04106e6f42a..a0bd3abbc1a 100644 --- a/source/blender/blenkernel/intern/scene.c +++ b/source/blender/blenkernel/intern/scene.c @@ -1071,7 +1071,7 @@ static void link_recurs_seq(BlendDataReader *reader, ListBase *lb) /* Sanity check. */ if (!SEQ_valid_strip_channel(seq)) { BLI_freelinkN(lb, seq); - BLO_read_data_reports(reader)->count.vse_strips_skipped++; + BLO_read_data_reports(reader)->count.sequence_strips_skipped++; } else if (seq->seqbase.first) { link_recurs_seq(reader, &seq->seqbase); diff --git a/source/blender/blenkernel/intern/spline_bezier.cc b/source/blender/blenkernel/intern/spline_bezier.cc index e760bf3495e..166fe0f5464 100644 --- a/source/blender/blenkernel/intern/spline_bezier.cc +++ b/source/blender/blenkernel/intern/spline_bezier.cc @@ -142,11 +142,14 @@ Span<float3> BezierSpline::handle_positions_left() const this->ensure_auto_handles(); return handle_positions_left_; } -MutableSpan<float3> BezierSpline::handle_positions_left() +MutableSpan<float3> BezierSpline::handle_positions_left(const bool write_only) { - this->ensure_auto_handles(); + if (!write_only) { + this->ensure_auto_handles(); + } return handle_positions_left_; } + Span<BezierSpline::HandleType> BezierSpline::handle_types_right() const { return handle_types_right_; @@ -160,9 +163,11 @@ Span<float3> BezierSpline::handle_positions_right() const this->ensure_auto_handles(); return handle_positions_right_; } -MutableSpan<float3> BezierSpline::handle_positions_right() +MutableSpan<float3> BezierSpline::handle_positions_right(const bool write_only) { - this->ensure_auto_handles(); + if (!write_only) { + this->ensure_auto_handles(); + } return handle_positions_right_; } diff --git a/source/blender/blenlib/intern/string.c b/source/blender/blenlib/intern/string.c index e8be674b6c1..62c8625378d 100644 --- a/source/blender/blenlib/intern/string.c +++ b/source/blender/blenlib/intern/string.c @@ -1346,9 +1346,8 @@ void BLI_str_format_byte_unit(char dst[15], long long int bytes, const bool base } /** - * Format a attribute domain to a up to 6 places (plus '\0' terminator) string using long number - * names abbreviations. This function is designed to produce a compact representation of large - * numbers. + * Format a count to up to 6 places (plus '\0' terminator) string using long number + * names abbreviations. Used to produce a compact representation of large numbers. * * 1 -> 1 * 15 -> 15 @@ -1362,8 +1361,7 @@ void BLI_str_format_byte_unit(char dst[15], long long int bytes, const bool base * 1000000000 -> 1B * ... * - * Dimension of 7 is the maximum length of the resulting string - * A combination with 7 places would be -15.5K\0 + * Length of 7 is the maximum of the resulting string, for example, `-15.5K\0`. */ void BLI_str_format_attribute_domain_size(char dst[7], int number_to_format) { diff --git a/source/blender/blenloader/BLO_readfile.h b/source/blender/blenloader/BLO_readfile.h index 5a919ae3605..22182edd070 100644 --- a/source/blender/blenloader/BLO_readfile.h +++ b/source/blender/blenloader/BLO_readfile.h @@ -124,7 +124,7 @@ typedef struct BlendFileReadReport { /* Number of proxies that failed to convert to library overrides. */ int proxies_to_lib_overrides_failures; /* Number of sequencer strips that were not read because were in non-supported channels. */ - int vse_strips_skipped; + int sequence_strips_skipped; } count; /* Number of libraries which had overrides that needed to be resynced, and a single linked list diff --git a/source/blender/blenloader/intern/versioning_300.c b/source/blender/blenloader/intern/versioning_300.c index 3c6fed9b759..e25d90ea90b 100644 --- a/source/blender/blenloader/intern/versioning_300.c +++ b/source/blender/blenloader/intern/versioning_300.c @@ -1273,6 +1273,18 @@ static void version_geometry_nodes_set_position_node_offset(bNodeTree *ntree) } } +static void version_node_tree_socket_id_delim(bNodeTree *ntree) +{ + LISTBASE_FOREACH (bNode *, node, &ntree->nodes) { + LISTBASE_FOREACH (bNodeSocket *, socket, &node->inputs) { + version_node_socket_id_delim(socket); + } + LISTBASE_FOREACH (bNodeSocket *, socket, &node->outputs) { + version_node_socket_id_delim(socket); + } + } +} + /* NOLINTNEXTLINE: readability-function-size */ void blo_do_versions_300(FileData *fd, Library *UNUSED(lib), Main *bmain) { @@ -2160,5 +2172,12 @@ void blo_do_versions_300(FileData *fd, Library *UNUSED(lib), Main *bmain) */ { /* Keep this block, even when empty. */ + + FOREACH_NODETREE_BEGIN (bmain, ntree, id) { + if (ntree->type != NTREE_CUSTOM) { + version_node_tree_socket_id_delim(ntree); + } + } + FOREACH_NODETREE_END; } } diff --git a/source/blender/blenloader/intern/versioning_common.cc b/source/blender/blenloader/intern/versioning_common.cc index 61119b80fdd..af765be619f 100644 --- a/source/blender/blenloader/intern/versioning_common.cc +++ b/source/blender/blenloader/intern/versioning_common.cc @@ -27,6 +27,7 @@ #include "BLI_listbase.h" #include "BLI_string.h" +#include "BLI_string_ref.hh" #include "BKE_animsys.h" #include "BKE_lib_id.h" @@ -37,6 +38,8 @@ #include "versioning_common.h" +using blender::StringRef; + ARegion *do_versions_add_region_if_not_found(ListBase *regionbase, int region_type, const char *name, @@ -101,6 +104,30 @@ static void change_node_socket_name(ListBase *sockets, const char *old_name, con } } +/** + * Convert `SocketName.001` unique name format to `SocketName_001`. Previously both were used. + */ +void version_node_socket_id_delim(bNodeSocket *socket) +{ + StringRef name = socket->name; + StringRef id = socket->identifier; + + if (!id.startswith(name)) { + /* We only need to affect the case where the identifier starts with the name. */ + return; + } + + StringRef id_number = id.drop_known_prefix(name); + if (id_number.is_empty()) { + /* The name was already unique, and didn't need numbers at the end for the id. */ + return; + } + + if (id_number.startswith(".")) { + socket->identifier[name.size()] = '_'; + } +} + void version_node_socket_name(bNodeTree *ntree, const int node_type, const char *old_name, diff --git a/source/blender/blenloader/intern/versioning_common.h b/source/blender/blenloader/intern/versioning_common.h index ed1cafdca33..7f179800ddd 100644 --- a/source/blender/blenloader/intern/versioning_common.h +++ b/source/blender/blenloader/intern/versioning_common.h @@ -62,6 +62,8 @@ void version_node_socket_index_animdata( void version_node_id(struct bNodeTree *ntree, const int node_type, const char *new_name); +void version_node_socket_id_delim(bNodeSocket *socket); + #ifdef __cplusplus } #endif diff --git a/source/blender/bmesh/intern/bmesh_mesh_normals.c b/source/blender/bmesh/intern/bmesh_mesh_normals.c index 16ce9703568..8119d9eb57d 100644 --- a/source/blender/bmesh/intern/bmesh_mesh_normals.c +++ b/source/blender/bmesh/intern/bmesh_mesh_normals.c @@ -2264,7 +2264,6 @@ bool BM_custom_loop_normals_to_vector_layer(BMesh *bm) } BM_lnorspace_update(bm); - BM_mesh_elem_index_ensure(bm, BM_LOOP); /* Create a loop normal layer. */ if (!CustomData_has_layer(&bm->ldata, CD_NORMAL)) { @@ -2276,14 +2275,15 @@ bool BM_custom_loop_normals_to_vector_layer(BMesh *bm) const int cd_custom_normal_offset = CustomData_get_offset(&bm->ldata, CD_CUSTOMLOOPNORMAL); const int cd_normal_offset = CustomData_get_offset(&bm->ldata, CD_NORMAL); + int l_index = 0; BM_ITER_MESH (f, &fiter, bm, BM_FACES_OF_MESH) { BM_ITER_ELEM (l, &liter, f, BM_LOOPS_OF_FACE) { - const int l_index = BM_elem_index_get(l); const short *clnors_data = BM_ELEM_CD_GET_VOID_P(l, cd_custom_normal_offset); float *normal = BM_ELEM_CD_GET_VOID_P(l, cd_normal_offset); BKE_lnor_space_custom_data_to_normal( bm->lnor_spacearr->lspacearr[l_index], clnors_data, normal); + l_index += 1; } } diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_attributes.cc b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_attributes.cc index 9edefe32fbc..8a5a8134ca7 100644 --- a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_attributes.cc +++ b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_attributes.cc @@ -172,6 +172,18 @@ static void init_vbo_for_attribute(const MeshRenderData *mr, GPUVertFormat format = {0}; GPU_vertformat_deinterleave(&format); GPU_vertformat_attr_add(&format, attr_name, comp_type, comp_size, fetch_mode); + + /* Ensure Sculpt Vertex Colors are properly aliased. */ + if (request.cd_type == CD_PROP_COLOR && request.domain == ATTR_DOMAIN_POINT) { + CustomData *cd_vdata = get_custom_data_for_domain(mr, ATTR_DOMAIN_POINT); + if (request.layer_index == CustomData_get_render_layer(cd_vdata, CD_PROP_COLOR)) { + GPU_vertformat_alias_add(&format, "c"); + } + if (request.layer_index == CustomData_get_active_layer(cd_vdata, CD_PROP_COLOR)) { + GPU_vertformat_alias_add(&format, "ac"); + } + } + GPU_vertbuf_init_with_format(vbo, &format); GPU_vertbuf_data_alloc(vbo, static_cast<uint32_t>(mr->loop_len)); } diff --git a/source/blender/editors/animation/anim_motion_paths.c b/source/blender/editors/animation/anim_motion_paths.c index 0d812198d04..335034fef6e 100644 --- a/source/blender/editors/animation/anim_motion_paths.c +++ b/source/blender/editors/animation/anim_motion_paths.c @@ -176,11 +176,11 @@ static void motionpaths_calc_bake_targets(ListBase *targets, int cframe) copy_v3_v3(mpv->co, pchan_eval->pose_tail); } - /* result must be in worldspace */ + /* Result must be in world-space. */ mul_m4_v3(ob_eval->obmat, mpv->co); } else { - /* worldspace object location */ + /* World-space object location. */ copy_v3_v3(mpv->co, ob_eval->obmat[3]); } diff --git a/source/blender/editors/armature/pose_transform.c b/source/blender/editors/armature/pose_transform.c index 279f79ac44b..70d6fa93104 100644 --- a/source/blender/editors/armature/pose_transform.c +++ b/source/blender/editors/armature/pose_transform.c @@ -797,13 +797,13 @@ static int pose_copy_exec(bContext *C, wmOperator *op) BLI_addtail(&temp_bmain->objects, &ob_copy); BLI_addtail(&temp_bmain->armatures, &arm_copy); /* begin copy buffer on a temp bmain. */ - BKE_copybuffer_begin(temp_bmain); + BKE_copybuffer_copy_begin(temp_bmain); /* Store the whole object to the copy buffer because pose can't be * existing on its own. */ - BKE_copybuffer_tag_ID(&ob_copy.id); + BKE_copybuffer_copy_tag_ID(&ob_copy.id); BLI_join_dirfile(str, sizeof(str), BKE_tempdir_base(), "copybuffer_pose.blend"); - BKE_copybuffer_save(temp_bmain, str, op->reports); + BKE_copybuffer_copy_end(temp_bmain, str, op->reports); /* We clear the lists so no datablocks gets freed, * This is required because objects in temp bmain shares same pointers * as the real ones. diff --git a/source/blender/editors/curve/editcurve.c b/source/blender/editors/curve/editcurve.c index 46bf1f6c9b5..3b05975d22d 100644 --- a/source/blender/editors/curve/editcurve.c +++ b/source/blender/editors/curve/editcurve.c @@ -4909,7 +4909,9 @@ bool ED_curve_editnurb_select_pick( /** \name Spin Operator * \{ */ -/* 'cent' is in object space and 'dvec' in worldspace. +/** + * \param axis: is in world-space. + * \param cent: is in object-space. */ bool ed_editnurb_spin( float viewmat[4][4], View3D *v3d, Object *obedit, const float axis[3], const float cent[3]) diff --git a/source/blender/editors/curve/editcurve_paint.c b/source/blender/editors/curve/editcurve_paint.c index 26906b0ddcd..784f67ac4f1 100644 --- a/source/blender/editors/curve/editcurve_paint.c +++ b/source/blender/editors/curve/editcurve_paint.c @@ -102,7 +102,7 @@ struct CurveDrawData { /* offset projection by this value */ bool use_offset; - float offset[3]; /* worldspace */ + float offset[3]; /* world-space */ float surface_offset; bool use_surface_offset_absolute; } project; diff --git a/source/blender/editors/include/ED_view3d.h b/source/blender/editors/include/ED_view3d.h index 38f607dddcb..008ad5b3203 100644 --- a/source/blender/editors/include/ED_view3d.h +++ b/source/blender/editors/include/ED_view3d.h @@ -588,8 +588,6 @@ float ED_view3d_radius_to_dist(const struct View3D *v3d, const bool use_aspect, const float radius); -void imm_drawcircball(const float cent[3], float rad, const float tmat[4][4], unsigned int pos); - /* Back-buffer select and draw support. */ void ED_view3d_backbuf_depth_validate(struct ViewContext *vc); int ED_view3d_backbuf_sample_size_clamp(struct ARegion *region, const float dist); @@ -840,6 +838,7 @@ void ED_view3d_gizmo_mesh_preselect_get_active(struct bContext *C, struct wmGizmo *gz, struct Base **r_base, struct BMElem **r_ele); +void ED_view3d_gizmo_mesh_preselect_clear(struct wmGizmo *gz); /* space_view3d.c */ void ED_view3d_buttons_region_layout_ex(const struct bContext *C, diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h index 207318de981..a244e77fcea 100644 --- a/source/blender/editors/include/UI_interface.h +++ b/source/blender/editors/include/UI_interface.h @@ -245,10 +245,10 @@ enum { }; /* Default font size for normal text. */ -#define UI_DEFAULT_TEXT_POINTS 11 +#define UI_DEFAULT_TEXT_POINTS 11.0f /* Larger size used for title text. */ -#define UI_DEFAULT_TITLE_POINTS 11 +#define UI_DEFAULT_TITLE_POINTS 11.0f #define UI_PANEL_WIDTH 340 #define UI_COMPACT_PANEL_WIDTH 160 diff --git a/source/blender/editors/interface/CMakeLists.txt b/source/blender/editors/interface/CMakeLists.txt index 84172c7efce..2a8f40b2631 100644 --- a/source/blender/editors/interface/CMakeLists.txt +++ b/source/blender/editors/interface/CMakeLists.txt @@ -66,7 +66,7 @@ set(SRC interface_region_menu_popup.c interface_region_popover.c interface_region_popup.c - interface_region_search.c + interface_region_search.cc interface_region_tooltip.c interface_regions.c interface_style.c diff --git a/source/blender/editors/interface/interface.c b/source/blender/editors/interface/interface.c index 82ea218baba..67ad4731b18 100644 --- a/source/blender/editors/interface/interface.c +++ b/source/blender/editors/interface/interface.c @@ -1993,23 +1993,9 @@ void UI_block_end(const bContext *C, uiBlock *block) /* ************** BLOCK DRAWING FUNCTION ************* */ -void ui_fontscale(short *points, float aspect) +void ui_fontscale(float *points, float aspect) { - if (aspect < 0.9f || aspect > 1.1f) { - float pointsf = *points; - - /* For some reason scaling fonts goes too fast compared to widget size. */ - /* XXX(ton): not true anymore? */ - // aspect = sqrt(aspect); - pointsf /= aspect; - - if (aspect > 1.0f) { - *points = ceilf(pointsf); - } - else { - *points = floorf(pointsf); - } - } + *points /= aspect; } /* Project button or block (but==NULL) to pixels in region-space. */ @@ -2022,6 +2008,13 @@ static void ui_but_to_pixelrect(rcti *rect, const ARegion *region, uiBlock *bloc BLI_rcti_translate(rect, -region->winrct.xmin, -region->winrct.ymin); } +static bool ui_but_pixelrect_in_view(const ARegion *region, const rcti *rect) +{ + rcti rect_winspace = *rect; + BLI_rcti_translate(&rect_winspace, region->winrct.xmin, region->winrct.ymin); + return BLI_rcti_isect(®ion->winrct, &rect_winspace, NULL); +} + /* uses local copy of style, to scale things down, and allow widgets to change stuff */ void UI_block_draw(const bContext *C, uiBlock *block) { @@ -2095,14 +2088,20 @@ void UI_block_draw(const bContext *C, uiBlock *block) /* widgets */ LISTBASE_FOREACH (uiBut *, but, &block->buttons) { - if (!(but->flag & (UI_HIDDEN | UI_SCROLLED))) { - ui_but_to_pixelrect(&rect, region, block, but); + if (but->flag & (UI_HIDDEN | UI_SCROLLED)) { + continue; + } - /* XXX: figure out why invalid coordinates happen when closing render window */ - /* and material preview is redrawn in main window (temp fix for bug T23848) */ - if (rect.xmin < rect.xmax && rect.ymin < rect.ymax) { - ui_draw_but(C, region, &style, but, &rect); - } + ui_but_to_pixelrect(&rect, region, block, but); + /* Optimization: Don't draw buttons that are not visible (outside view bounds). */ + if (!ui_but_pixelrect_in_view(region, &rect)) { + continue; + } + + /* XXX: figure out why invalid coordinates happen when closing render window */ + /* and material preview is redrawn in main window (temp fix for bug T23848) */ + if (rect.xmin < rect.xmax && rect.ymin < rect.ymax) { + ui_draw_but(C, region, &style, but, &rect); } } diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c index 35e1526d079..244d5b51ffd 100644 --- a/source/blender/editors/interface/interface_handlers.c +++ b/source/blender/editors/interface/interface_handlers.c @@ -397,8 +397,8 @@ typedef struct uiHandleButtonData { float vec[3], origvec[3]; ColorBand *coba; - /* Tool-tip. */ - uint tooltip_force : 1; + /* True when alt is held and the preference for displaying tooltips should be ignored. */ + bool tooltip_force; /* auto open */ bool used_mouse; diff --git a/source/blender/editors/interface/interface_icons_event.c b/source/blender/editors/interface/interface_icons_event.c index 3962ff6a702..577db6a0338 100644 --- a/source/blender/editors/interface/interface_icons_event.c +++ b/source/blender/editors/interface/interface_icons_event.c @@ -77,7 +77,7 @@ static void icon_draw_rect_input_text(const rctf *rect, const float color[4], const char *str, - int font_size) + float font_size) { BLF_batch_draw_flush(); const int font_id = BLF_default(); @@ -97,7 +97,7 @@ static void icon_draw_rect_input_symbol(const rctf *rect, const float color[4], BLF_batch_draw_flush(); const int font_id = blf_mono_font; BLF_color4fv(font_id, color); - BLF_size(font_id, 19 * U.pixelsize, U.dpi); + BLF_size(font_id, 19.0f * U.pixelsize, U.dpi); const float x = rect->xmin + (2.0f * U.pixelsize); const float y = rect->ymin + (1.0f * U.pixelsize); BLF_position(font_id, x, y, 0.0f); @@ -152,12 +152,12 @@ void icon_draw_rect_input(float x, if ((event_type >= EVT_AKEY) && (event_type <= EVT_ZKEY)) { const char str[2] = {'A' + (event_type - EVT_AKEY), '\0'}; - icon_draw_rect_input_text(&rect, color, str, 13); + icon_draw_rect_input_text(&rect, color, str, 13.0f); } else if ((event_type >= EVT_F1KEY) && (event_type <= EVT_F12KEY)) { char str[4]; SNPRINTF(str, "F%d", 1 + (event_type - EVT_F1KEY)); - icon_draw_rect_input_text(&rect, color, str, event_type > EVT_F9KEY ? 8 : 10); + icon_draw_rect_input_text(&rect, color, str, event_type > EVT_F9KEY ? 8.0f : 10.0f); } else if (event_type == EVT_LEFTSHIFTKEY) { icon_draw_rect_input_symbol(&rect, color, (const char[]){0xe2, 0x87, 0xa7, 0x0}); @@ -167,7 +167,7 @@ void icon_draw_rect_input(float x, icon_draw_rect_input_symbol(&rect, color, (const char[]){0xe2, 0x8c, 0x83, 0x0}); } else { - icon_draw_rect_input_text(&rect, color, "Ctrl", 9); + icon_draw_rect_input_text(&rect, color, "Ctrl", 9.0f); } } else if (event_type == EVT_LEFTALTKEY) { @@ -175,7 +175,7 @@ void icon_draw_rect_input(float x, icon_draw_rect_input_symbol(&rect, color, (const char[]){0xe2, 0x8c, 0xa5, 0x0}); } else { - icon_draw_rect_input_text(&rect, color, "Alt", 10); + icon_draw_rect_input_text(&rect, color, "Alt", 10.0f); } } else if (event_type == EVT_OSKEY) { @@ -186,20 +186,20 @@ void icon_draw_rect_input(float x, icon_draw_rect_input_symbol(&rect, color, (const char[]){0xe2, 0x9d, 0x96, 0x0}); } else { - icon_draw_rect_input_text(&rect, color, "OS", 10); + icon_draw_rect_input_text(&rect, color, "OS", 10.0f); } } else if (event_type == EVT_DELKEY) { - icon_draw_rect_input_text(&rect, color, "Del", 9); + icon_draw_rect_input_text(&rect, color, "Del", 9.0f); } else if (event_type == EVT_TABKEY) { icon_draw_rect_input_symbol(&rect, color, (const char[]){0xe2, 0xad, 0xbe, 0x0}); } else if (event_type == EVT_HOMEKEY) { - icon_draw_rect_input_text(&rect, color, "Home", 6); + icon_draw_rect_input_text(&rect, color, "Home", 6.0f); } else if (event_type == EVT_ENDKEY) { - icon_draw_rect_input_text(&rect, color, "End", 8); + icon_draw_rect_input_text(&rect, color, "End", 8.0f); } else if (event_type == EVT_RETKEY) { icon_draw_rect_input_symbol(&rect, color, (const char[]){0xe2, 0x8f, 0x8e, 0x0}); @@ -209,14 +209,14 @@ void icon_draw_rect_input(float x, icon_draw_rect_input_symbol(&rect, color, (const char[]){0xe2, 0x8e, 0x8b, 0x0}); } else { - icon_draw_rect_input_text(&rect, color, "Esc", 8); + icon_draw_rect_input_text(&rect, color, "Esc", 8.0f); } } else if (event_type == EVT_PAGEUPKEY) { - icon_draw_rect_input_text(&rect, color, (const char[]){'P', 0xe2, 0x86, 0x91, 0x0}, 8); + icon_draw_rect_input_text(&rect, color, (const char[]){'P', 0xe2, 0x86, 0x91, 0x0}, 8.0f); } else if (event_type == EVT_PAGEDOWNKEY) { - icon_draw_rect_input_text(&rect, color, (const char[]){'P', 0xe2, 0x86, 0x93, 0x0}, 8); + icon_draw_rect_input_text(&rect, color, (const char[]){'P', 0xe2, 0x86, 0x93, 0x0}, 8.0f); } else if (event_type == EVT_LEFTARROWKEY) { icon_draw_rect_input_symbol(&rect, color, (const char[]){0xe2, 0x86, 0x90, 0x0}); diff --git a/source/blender/editors/interface/interface_intern.h b/source/blender/editors/interface/interface_intern.h index c7c6a88de01..8c33e2d1cc9 100644 --- a/source/blender/editors/interface/interface_intern.h +++ b/source/blender/editors/interface/interface_intern.h @@ -609,7 +609,7 @@ typedef struct uiSafetyRct { /* interface.c */ -void ui_fontscale(short *points, float aspect); +void ui_fontscale(float *points, float aspect); extern void ui_block_to_region_fl(const struct ARegion *region, uiBlock *block, diff --git a/source/blender/editors/interface/interface_panel.c b/source/blender/editors/interface/interface_panel.c index 072362492d8..6acbaf03476 100644 --- a/source/blender/editors/interface/interface_panel.c +++ b/source/blender/editors/interface/interface_panel.c @@ -1348,7 +1348,7 @@ void UI_panel_category_draw_all(ARegion *region, const char *category_id_active) const uiStyle *style = UI_style_get(); const uiFontStyle *fstyle = &style->widget; const int fontid = fstyle->uifont_id; - short fstyle_points = fstyle->points; + float fstyle_points = fstyle->points; const float aspect = ((uiBlock *)region->uiblocks.first)->aspect; const float zoom = 1.0f / aspect; const int px = U.pixelsize; diff --git a/source/blender/editors/interface/interface_region_search.c b/source/blender/editors/interface/interface_region_search.cc index b8a19d06be1..eaf1ed3693b 100644 --- a/source/blender/editors/interface/interface_region_search.c +++ b/source/blender/editors/interface/interface_region_search.cc @@ -23,9 +23,9 @@ * Search Box Region & Interaction */ -#include <stdarg.h> -#include <stdlib.h> -#include <string.h> +#include <cstdarg> +#include <cstdlib> +#include <cstring> #include "DNA_ID.h" #include "MEM_guardedalloc.h" @@ -84,7 +84,7 @@ struct uiSearchItems { void *active; }; -typedef struct uiSearchboxData { +struct uiSearchboxData { rcti bbox; uiFontStyle fstyle; uiSearchItems items; @@ -102,7 +102,7 @@ typedef struct uiSearchboxData { * Used so we can show leading text to menu items less prominently (not related to 'use_sep'). */ const char *sep_string; -} uiSearchboxData; +}; #define SEARCH_ITEMS 10 @@ -166,9 +166,9 @@ bool UI_search_item_add(uiSearchItems *items, if (name_prefix_offset != 0) { /* Lazy initialize, as this isn't used often. */ - if (items->name_prefix_offsets == NULL) { - items->name_prefix_offsets = MEM_callocN( - items->maxitem * sizeof(*items->name_prefix_offsets), "search name prefix offsets"); + if (items->name_prefix_offsets == nullptr) { + items->name_prefix_offsets = (uint8_t *)MEM_callocN( + items->maxitem * sizeof(*items->name_prefix_offsets), __func__); } items->name_prefix_offsets[items->totitem] = name_prefix_offset; } @@ -198,7 +198,7 @@ int UI_searchbox_size_x(void) int UI_search_items_find_index(uiSearchItems *items, const char *name) { - if (items->name_prefix_offsets != NULL) { + if (items->name_prefix_offsets != nullptr) { for (int i = 0; i < items->totitem; i++) { if (STREQ(name, items->names[i] + items->name_prefix_offsets[i])) { return i; @@ -218,7 +218,7 @@ int UI_search_items_find_index(uiSearchItems *items, const char *name) /* region is the search box itself */ static void ui_searchbox_select(bContext *C, ARegion *region, uiBut *but, int step) { - uiSearchboxData *data = region->regiondata; + uiSearchboxData *data = static_cast<uiSearchboxData *>(region->regiondata); /* apply step */ data->active += step; @@ -285,14 +285,14 @@ static void ui_searchbox_butrect(rcti *r_rect, uiSearchboxData *data, int itemnr int ui_searchbox_find_index(ARegion *region, const char *name) { - uiSearchboxData *data = region->regiondata; + uiSearchboxData *data = static_cast<uiSearchboxData *>(region->regiondata); return UI_search_items_find_index(&data->items, name); } /* x and y in screen-coords. */ bool ui_searchbox_inside(ARegion *region, const int xy[2]) { - uiSearchboxData *data = region->regiondata; + uiSearchboxData *data = static_cast<uiSearchboxData *>(region->regiondata); return BLI_rcti_isect_pt(&data->bbox, xy[0] - region->winrct.xmin, xy[1] - region->winrct.ymin); } @@ -300,12 +300,12 @@ bool ui_searchbox_inside(ARegion *region, const int xy[2]) /* string validated to be of correct length (but->hardmax) */ bool ui_searchbox_apply(uiBut *but, ARegion *region) { - uiSearchboxData *data = region->regiondata; + uiSearchboxData *data = static_cast<uiSearchboxData *>(region->regiondata); uiButSearch *search_but = (uiButSearch *)but; BLI_assert(but->type == UI_BTYPE_SEARCH_MENU); - search_but->item_active = NULL; + search_but->item_active = nullptr; if (data->active != -1) { const char *name = data->items.names[data->active] + @@ -314,7 +314,7 @@ bool ui_searchbox_apply(uiBut *but, ARegion *region) data->items.name_prefix_offsets[data->active] : 0); - const char *name_sep = data->use_shortcut_sep ? strrchr(name, UI_SEP_CHAR) : NULL; + const char *name_sep = data->use_shortcut_sep ? strrchr(name, UI_SEP_CHAR) : nullptr; /* Search button with dynamic string properties may have their own method of applying * the search results, so only copy the result if there is a proper space for it. */ @@ -356,7 +356,7 @@ static struct ARegion *wm_searchbox_tooltip_init(struct bContext *C, } ARegion *searchbox_region = UI_region_searchbox_region_get(region); - uiSearchboxData *data = searchbox_region->regiondata; + uiSearchboxData *data = static_cast<uiSearchboxData *>(searchbox_region->regiondata); BLI_assert(data->items.pointers[data->active] == search_but->item_active); @@ -367,13 +367,13 @@ static struct ARegion *wm_searchbox_tooltip_init(struct bContext *C, C, region, &rect, search_but->arg, search_but->item_active); } } - return NULL; + return nullptr; } bool ui_searchbox_event( bContext *C, ARegion *region, uiBut *but, ARegion *butregion, const wmEvent *event) { - uiSearchboxData *data = region->regiondata; + uiSearchboxData *data = static_cast<uiSearchboxData *>(region->regiondata); uiButSearch *search_but = (uiButSearch *)but; int type = event->type, val = event->val; bool handled = false; @@ -481,7 +481,7 @@ static void ui_searchbox_update_fn(bContext *C, void ui_searchbox_update(bContext *C, ARegion *region, uiBut *but, const bool reset) { uiButSearch *search_but = (uiButSearch *)but; - uiSearchboxData *data = region->regiondata; + uiSearchboxData *data = static_cast<uiSearchboxData *>(region->regiondata); BLI_assert(but->type == UI_BTYPE_SEARCH_MENU); @@ -499,7 +499,7 @@ void ui_searchbox_update(bContext *C, ARegion *region, uiBut *but, const bool re if (search_but->items_update_fn && search_but->item_active) { data->items.active = search_but->item_active; ui_searchbox_update_fn(C, search_but, but->editstr, &data->items); - data->items.active = NULL; + data->items.active = nullptr; /* found active item, calculate real offset by centering it */ if (data->items.totitem) { @@ -538,7 +538,7 @@ void ui_searchbox_update(bContext *C, ARegion *region, uiBut *but, const bool re /* Never include the prefix in the button. */ (data->items.name_prefix_offsets ? data->items.name_prefix_offsets[a] : 0); - const char *name_sep = data->use_shortcut_sep ? strrchr(name, UI_SEP_CHAR) : NULL; + const char *name_sep = data->use_shortcut_sep ? strrchr(name, UI_SEP_CHAR) : nullptr; if (STREQLEN(but->editstr, name, name_sep ? (name_sep - name) : data->items.maxstrlen)) { data->active = a; break; @@ -558,7 +558,7 @@ void ui_searchbox_update(bContext *C, ARegion *region, uiBut *but, const bool re int ui_searchbox_autocomplete(bContext *C, ARegion *region, uiBut *but, char *str) { uiButSearch *search_but = (uiButSearch *)but; - uiSearchboxData *data = region->regiondata; + uiSearchboxData *data = static_cast<uiSearchboxData *>(region->regiondata); int match = AUTOCOMPLETE_NO_MATCH; BLI_assert(but->type == UI_BTYPE_SEARCH_MENU); @@ -569,7 +569,7 @@ int ui_searchbox_autocomplete(bContext *C, ARegion *region, uiBut *but, char *st ui_searchbox_update_fn(C, search_but, but->editstr, &data->items); match = UI_autocomplete_end(data->items.autocpl, str); - data->items.autocpl = NULL; + data->items.autocpl = nullptr; } return match; @@ -577,7 +577,7 @@ int ui_searchbox_autocomplete(bContext *C, ARegion *region, uiBut *but, char *st static void ui_searchbox_region_draw_fn(const bContext *C, ARegion *region) { - uiSearchboxData *data = region->regiondata; + uiSearchboxData *data = static_cast<uiSearchboxData *>(region->regiondata); /* pixel space */ wmOrtho2_region_pixelspace(region); @@ -630,7 +630,7 @@ static void ui_searchbox_region_draw_fn(const bContext *C, ARegion *region) const int state = ((a == data->active) ? UI_ACTIVE : 0) | data->items.states[a]; char *name = data->items.names[a]; int icon = data->items.icons[a]; - char *name_sep_test = NULL; + char *name_sep_test = nullptr; uiMenuItemSeparatorType separator_type = UI_MENU_ITEM_SEPARATOR_NONE; if (data->use_shortcut_sep) { @@ -652,15 +652,15 @@ static void ui_searchbox_region_draw_fn(const bContext *C, ARegion *region) } /* Simple menu item. */ - ui_draw_menu_item(&data->fstyle, &rect, name, icon, state, separator_type, NULL); + ui_draw_menu_item(&data->fstyle, &rect, name, icon, state, separator_type, nullptr); } else { /* Split menu item, faded text before the separator. */ - char *name_sep = NULL; + char *name_sep = nullptr; do { name_sep = name_sep_test; name_sep_test = strstr(name_sep + search_sep_len, data->sep_string); - } while (name_sep_test != NULL); + } while (name_sep_test != nullptr); name_sep += search_sep_len; const char name_sep_prev = *name_sep; @@ -683,7 +683,7 @@ static void ui_searchbox_region_draw_fn(const bContext *C, ARegion *region) } /* The previous menu item draws the active selection. */ - ui_draw_menu_item(&data->fstyle, &rect, name_sep, icon, state, separator_type, NULL); + ui_draw_menu_item(&data->fstyle, &rect, name_sep, icon, state, separator_type, nullptr); } } /* indicate more */ @@ -705,7 +705,7 @@ static void ui_searchbox_region_draw_fn(const bContext *C, ARegion *region) static void ui_searchbox_region_free_fn(ARegion *region) { - uiSearchboxData *data = region->regiondata; + uiSearchboxData *data = static_cast<uiSearchboxData *>(region->regiondata); /* free search data */ for (int a = 0; a < data->items.maxitem; a++) { @@ -716,12 +716,12 @@ static void ui_searchbox_region_free_fn(ARegion *region) MEM_freeN(data->items.icons); MEM_freeN(data->items.states); - if (data->items.name_prefix_offsets != NULL) { + if (data->items.name_prefix_offsets != nullptr) { MEM_freeN(data->items.name_prefix_offsets); } MEM_freeN(data); - region->regiondata = NULL; + region->regiondata = nullptr; } static ARegion *ui_searchbox_create_generic_ex(bContext *C, @@ -746,7 +746,7 @@ static ARegion *ui_searchbox_create_generic_ex(bContext *C, region->type = &type; /* create searchbox data */ - uiSearchboxData *data = MEM_callocN(sizeof(uiSearchboxData), "uiSearchboxData"); + uiSearchboxData *data = (uiSearchboxData *)MEM_callocN(sizeof(uiSearchboxData), __func__); /* set font, get bb */ data->fstyle = style->widget; /* copy struct */ @@ -767,7 +767,7 @@ static ARegion *ui_searchbox_create_generic_ex(bContext *C, data->prv_cols = but->a2; } - if (but->optype != NULL || use_shortcut_sep) { + if (but->optype != nullptr || use_shortcut_sep) { data->use_shortcut_sep = true; } data->sep_string = search_but->item_sep_string; @@ -881,13 +881,13 @@ static ARegion *ui_searchbox_create_generic_ex(bContext *C, /* In case the button's string is dynamic, make sure there are buffers available. */ data->items.maxstrlen = but->hardmax == 0 ? UI_MAX_NAME_STR : but->hardmax; data->items.totitem = 0; - data->items.names = MEM_callocN(data->items.maxitem * sizeof(void *), "search names"); - data->items.pointers = MEM_callocN(data->items.maxitem * sizeof(void *), "search pointers"); - data->items.icons = MEM_callocN(data->items.maxitem * sizeof(int), "search icons"); - data->items.states = MEM_callocN(data->items.maxitem * sizeof(int), "search flags"); - data->items.name_prefix_offsets = NULL; /* Lazy initialized as needed. */ + data->items.names = (char **)MEM_callocN(data->items.maxitem * sizeof(void *), __func__); + data->items.pointers = (void **)MEM_callocN(data->items.maxitem * sizeof(void *), __func__); + data->items.icons = (int *)MEM_callocN(data->items.maxitem * sizeof(int), __func__); + data->items.states = (int *)MEM_callocN(data->items.maxitem * sizeof(int), __func__); + data->items.name_prefix_offsets = nullptr; /* Lazy initialized as needed. */ for (int i = 0; i < data->items.maxitem; i++) { - data->items.names[i] = MEM_callocN(data->items.maxstrlen + 1, "search pointers"); + data->items.names[i] = (char *)MEM_callocN(data->items.maxstrlen + 1, __func__); } return region; @@ -924,7 +924,7 @@ static void str_tolower_titlecaps_ascii(char *str, const size_t len) static void ui_searchbox_region_draw_cb__operator(const bContext *UNUSED(C), ARegion *region) { - uiSearchboxData *data = region->regiondata; + uiSearchboxData *data = static_cast<uiSearchboxData *>(region->regiondata); /* pixel space */ wmOrtho2_region_pixelspace(region); @@ -952,10 +952,10 @@ static void ui_searchbox_region_draw_cb__operator(const bContext *UNUSED(C), ARe { const int state = ((a == data->active) ? UI_ACTIVE : 0) | data->items.states[a]; - wmOperatorType *ot = data->items.pointers[a]; + wmOperatorType *ot = static_cast<wmOperatorType *>(data->items.pointers[a]); char text_pre[128]; - char *text_pre_p = strstr(ot->idname, "_OT_"); - if (text_pre_p == NULL) { + const char *text_pre_p = strstr(ot->idname, "_OT_"); + if (text_pre_p == nullptr) { text_pre[0] = '\0'; } else { @@ -975,7 +975,7 @@ static void ui_searchbox_region_draw_cb__operator(const bContext *UNUSED(C), ARe data->items.icons[a], state, UI_MENU_ITEM_SEPARATOR_NONE, - NULL); + nullptr); ui_draw_menu_item(&data->fstyle, &rect_post, data->items.names[a], @@ -983,7 +983,7 @@ static void ui_searchbox_region_draw_cb__operator(const bContext *UNUSED(C), ARe state, data->use_shortcut_sep ? UI_MENU_ITEM_SEPARATOR_SHORTCUT : UI_MENU_ITEM_SEPARATOR_NONE, - NULL); + nullptr); } } /* indicate more */ @@ -1044,17 +1044,17 @@ void ui_but_search_refresh(uiButSearch *search_but) return; } - uiSearchItems *items = MEM_callocN(sizeof(uiSearchItems), "search items"); + uiSearchItems *items = (uiSearchItems *)MEM_callocN(sizeof(uiSearchItems), __func__); /* setup search struct */ items->maxitem = 10; items->maxstrlen = 256; - items->names = MEM_callocN(items->maxitem * sizeof(void *), "search names"); + items->names = (char **)MEM_callocN(items->maxitem * sizeof(void *), __func__); for (int i = 0; i < items->maxitem; i++) { - items->names[i] = MEM_callocN(but->hardmax + 1, "search names"); + items->names[i] = (char *)MEM_callocN(but->hardmax + 1, __func__); } - ui_searchbox_update_fn(but->block->evil_C, search_but, but->drawstr, items); + ui_searchbox_update_fn((bContext *)but->block->evil_C, search_but, but->drawstr, items); if (!search_but->results_are_suggestions) { /* Only red-alert when we are sure of it, this can miss cases when >10 matches. */ diff --git a/source/blender/editors/interface/interface_regions_intern.h b/source/blender/editors/interface/interface_regions_intern.h index 0cb1fee9a92..ce938852520 100644 --- a/source/blender/editors/interface/interface_regions_intern.h +++ b/source/blender/editors/interface/interface_regions_intern.h @@ -22,9 +22,17 @@ #pragma once +#ifdef __cplusplus +extern "C" { +#endif + /* interface_region_menu_popup.c */ uint ui_popup_menu_hash(const char *str); /* interface_regions_intern.h */ ARegion *ui_region_temp_add(bScreen *screen); void ui_region_temp_remove(struct bContext *C, bScreen *screen, ARegion *region); + +#ifdef __cplusplus +} +#endif diff --git a/source/blender/editors/interface/interface_style.c b/source/blender/editors/interface/interface_style.c index 4c640851999..8bb1e477506 100644 --- a/source/blender/editors/interface/interface_style.c +++ b/source/blender/editors/interface/interface_style.c @@ -483,9 +483,9 @@ void uiStyleInit(void) * Yes, this build the glyph cache and create * the texture. */ - BLF_size(font->blf_id, 11 * U.pixelsize, U.dpi); - BLF_size(font->blf_id, 12 * U.pixelsize, U.dpi); - BLF_size(font->blf_id, 14 * U.pixelsize, U.dpi); + BLF_size(font->blf_id, 11.0f * U.pixelsize, U.dpi); + BLF_size(font->blf_id, 12.0f * U.pixelsize, U.dpi); + BLF_size(font->blf_id, 14.0f * U.pixelsize, U.dpi); } } @@ -510,7 +510,7 @@ void uiStyleInit(void) blf_mono_font = BLF_load_mono_default(unique); } - BLF_size(blf_mono_font, 12 * U.pixelsize, 72); + BLF_size(blf_mono_font, 12.0f * U.pixelsize, 72); /* Set default flags based on UI preferences (not render fonts) */ { @@ -555,7 +555,7 @@ void uiStyleInit(void) blf_mono_font_render = BLF_load_mono_default(unique); } - BLF_size(blf_mono_font_render, 12 * U.pixelsize, 72); + BLF_size(blf_mono_font_render, 12.0f * U.pixelsize, 72); } void UI_fontstyle_set(const uiFontStyle *fs) diff --git a/source/blender/editors/interface/resources.c b/source/blender/editors/interface/resources.c index aece2e58f1e..d960f5e6b1d 100644 --- a/source/blender/editors/interface/resources.c +++ b/source/blender/editors/interface/resources.c @@ -1340,7 +1340,8 @@ void UI_GetThemeColorBlendShade4fv(int colorid1, int colorid2, float fac, int of CLAMP(g, 0, 255); b = offset + floorf((1.0f - fac) * cp1[2] + fac * cp2[2]); CLAMP(b, 0, 255); - a = offset + floorf((1.0f - fac) * cp1[3] + fac * cp2[3]); + + a = floorf((1.0f - fac) * cp1[3] + fac * cp2[3]); /* No shading offset. */ CLAMP(a, 0, 255); col[0] = ((float)r) / 255.0f; diff --git a/source/blender/editors/mesh/editmesh_extrude.c b/source/blender/editors/mesh/editmesh_extrude.c index e4cd48d95bb..912399c25b3 100644 --- a/source/blender/editors/mesh/editmesh_extrude.c +++ b/source/blender/editors/mesh/editmesh_extrude.c @@ -821,8 +821,8 @@ static int edbm_dupli_extrude_cursor_invoke(bContext *C, wmOperator *op, const w float view_vec[3], cross[3]; /* convert the 2D normal into 3D */ - mul_mat3_m4_v3(vc.rv3d->viewinv, nor); /* worldspace */ - mul_mat3_m4_v3(vc.obedit->imat, nor); /* local space */ + mul_mat3_m4_v3(vc.rv3d->viewinv, nor); /* World-space. */ + mul_mat3_m4_v3(vc.obedit->imat, nor); /* Local-space. */ /* correct the normal to be aligned on the view plane */ mul_v3_mat3_m4v3(view_vec, vc.obedit->imat, vc.rv3d->viewinv[2]); diff --git a/source/blender/editors/mesh/editmesh_extrude_spin.c b/source/blender/editors/mesh/editmesh_extrude_spin.c index 2146207308c..d7eaf58653f 100644 --- a/source/blender/editors/mesh/editmesh_extrude_spin.c +++ b/source/blender/editors/mesh/editmesh_extrude_spin.c @@ -80,7 +80,7 @@ static int edbm_spin_exec(bContext *C, wmOperator *op) BMesh *bm = em->bm; BMOperator spinop; - /* keep the values in worldspace since we're passing the obmat */ + /* Keep the values in world-space since we're passing the `obmat`. */ if (!EDBM_op_init(em, &spinop, op, diff --git a/source/blender/editors/mesh/editmesh_knife.c b/source/blender/editors/mesh/editmesh_knife.c index b712cfc24ed..cd04f40dedf 100644 --- a/source/blender/editors/mesh/editmesh_knife.c +++ b/source/blender/editors/mesh/editmesh_knife.c @@ -491,7 +491,7 @@ static void knifetool_draw_visible_distances(const KnifeTool_OpData *kcd) float numstr_size[2]; float posit[2]; const float bg_margin = 4.0f * U.dpi_fac; - const int font_size = 14.0f * U.pixelsize; + const float font_size = 14.0f * U.pixelsize; const int distance_precision = 4; /* Calculate distance and convert to string. */ @@ -561,7 +561,7 @@ static void knifetool_draw_angle(const KnifeTool_OpData *kcd, const float arc_size = 64.0f * U.dpi_fac; const float bg_margin = 4.0f * U.dpi_fac; const float cap_size = 4.0f * U.dpi_fac; - const int font_size = 14 * U.pixelsize; + const float font_size = 14.0f * U.pixelsize; const int angle_precision = 3; /* Angle arc in 3d space. */ diff --git a/source/blender/editors/physics/particle_edit.c b/source/blender/editors/physics/particle_edit.c index 97f3b96cd18..fc80767be9e 100644 --- a/source/blender/editors/physics/particle_edit.c +++ b/source/blender/editors/physics/particle_edit.c @@ -3903,8 +3903,8 @@ static void brush_puff(PEData *data, int point_index, float mouse_distance) copy_v3_v3(co, key->co); mul_m4_v3(mat, co); - /* use 'kco' as the object space version of worldspace 'co', - * ob->imat is set before calling */ + /* Use `kco` as the object space version of world-space `co`, + * `ob->imat` is set before calling. */ mul_v3_m4v3(kco, data->ob->imat, co); point_index = BLI_kdtree_3d_find_nearest(edit->emitter_field, kco, NULL); @@ -3993,15 +3993,15 @@ static void brush_puff(PEData *data, int point_index, float mouse_distance) copy_v3_v3(oco, key->co); mul_m4_v3(mat, oco); - /* use 'kco' as the object space version of worldspace 'co', - * ob->imat is set before calling */ + /* Use `kco` as the object space version of world-space `co`, + * `ob->imat` is set before calling. */ mul_v3_m4v3(kco, data->ob->imat, oco); point_index = BLI_kdtree_3d_find_nearest(edit->emitter_field, kco, NULL); if (point_index != -1) { copy_v3_v3(onor, &edit->emitter_cosnos[point_index * 6 + 3]); - mul_mat3_m4_v3(data->ob->obmat, onor); /* normal into worldspace */ - mul_mat3_m4_v3(imat, onor); /* worldspace into particle space */ + mul_mat3_m4_v3(data->ob->obmat, onor); /* Normal into world-space. */ + mul_mat3_m4_v3(imat, onor); /* World-space into particle-space. */ normalize_v3(onor); } else { diff --git a/source/blender/editors/sculpt_paint/paint_image_proj.c b/source/blender/editors/sculpt_paint/paint_image_proj.c index 84b9fbdea49..96a0beb6426 100644 --- a/source/blender/editors/sculpt_paint/paint_image_proj.c +++ b/source/blender/editors/sculpt_paint/paint_image_proj.c @@ -3125,7 +3125,8 @@ static void project_paint_face_init(const ProjPaintState *ps, uv, v1coSS, v2coSS, v3coSS, uv1co, uv2co, uv3co, pixelScreenCo, w); } - /* a pity we need to get the worldspace pixel location here */ + /* A pity we need to get the world-space pixel location here + * because it is a relatively expensive operation. */ if (do_clip || do_3d_mapping) { interp_v3_v3v3v3(wco, ps->mvert_eval[lt_vtri[0]].co, @@ -3208,7 +3209,10 @@ static void project_paint_face_init(const ProjPaintState *ps, else { /* we have a seam - deal with it! */ - /* inset face coords. NOTE!!! ScreenSace for ortho, Worldspace in perspective view */ + /* Inset face coords. + * - screen-space in orthographic view. + * - world-space in perspective view. + */ float insetCos[3][3]; /* Vertex screen-space coords. */ @@ -3373,8 +3377,8 @@ static void project_paint_face_init(const ProjPaintState *ps, if ((ps->do_occlude == false) || !project_bucket_point_occluded( ps, bucketFaceNodes, tri_index, pixel_on_edge)) { - /* a pity we need to get the worldspace - * pixel location here */ + /* A pity we need to get the world-space pixel location here + * because it is a relatively expensive operation. */ if (do_clip || do_3d_mapping) { interp_v3_v3v3v3(wco, vCo[0], vCo[1], vCo[2], w); diff --git a/source/blender/editors/sculpt_paint/sculpt_intern.h b/source/blender/editors/sculpt_paint/sculpt_intern.h index 696c3332a2b..16df1efd969 100644 --- a/source/blender/editors/sculpt_paint/sculpt_intern.h +++ b/source/blender/editors/sculpt_paint/sculpt_intern.h @@ -366,10 +366,12 @@ float *SCULPT_boundary_automasking_init(Object *ob, /* Geodesic distances. */ -/* Returns an array indexed by vertex index containing the geodesic distance to the closest vertex -in the initial vertex set. The caller is responsible for freeing the array. -Geodesic distances will only work when used with PBVH_FACES, for other types of PBVH it will -fallback to euclidean distances to one of the initial vertices in the set. */ +/** + * Returns an array indexed by vertex index containing the geodesic distance to the closest vertex + * in the initial vertex set. The caller is responsible for freeing the array. + * Geodesic distances will only work when used with PBVH_FACES, for other types of PBVH it will + * fallback to euclidean distances to one of the initial vertices in the set. + */ float *SCULPT_geodesic_distances_create(struct Object *ob, struct GSet *initial_vertices, const float limit_radius); diff --git a/source/blender/editors/space_file/filelist.c b/source/blender/editors/space_file/filelist.c index a73fa2b9740..5d1a202e5ca 100644 --- a/source/blender/editors/space_file/filelist.c +++ b/source/blender/editors/space_file/filelist.c @@ -914,6 +914,9 @@ static void prepare_filter_asset_library(const FileList *filelist, FileListFilte if (!filter->asset_catalog_filter) { return; } + BLI_assert_msg(filelist->asset_library, + "prepare_filter_asset_library() should only be called when the file browser is " + "in asset browser mode"); file_ensure_updated_catalog_filter_data(filter->asset_catalog_filter, filelist->asset_library); } @@ -1876,11 +1879,13 @@ void filelist_settype(FileList *filelist, short type) case FILE_MAIN: filelist->check_dir_fn = filelist_checkdir_main; filelist->read_job_fn = filelist_readjob_main; + filelist->prepare_filter_fn = NULL; filelist->filter_fn = is_filtered_main; break; case FILE_LOADLIB: filelist->check_dir_fn = filelist_checkdir_lib; filelist->read_job_fn = filelist_readjob_lib; + filelist->prepare_filter_fn = NULL; filelist->filter_fn = is_filtered_lib; break; case FILE_ASSET_LIBRARY: @@ -1900,6 +1905,7 @@ void filelist_settype(FileList *filelist, short type) default: filelist->check_dir_fn = filelist_checkdir_dir; filelist->read_job_fn = filelist_readjob_dir; + filelist->prepare_filter_fn = NULL; filelist->filter_fn = is_filtered_file; break; } diff --git a/source/blender/editors/space_image/image_draw.c b/source/blender/editors/space_image/image_draw.c index 22a43ea3794..d76b1842c94 100644 --- a/source/blender/editors/space_image/image_draw.c +++ b/source/blender/editors/space_image/image_draw.c @@ -185,7 +185,7 @@ void ED_image_draw_info(Scene *scene, GPU_blend(GPU_BLEND_NONE); - BLF_size(blf_mono_font, 11 * U.pixelsize, U.dpi); + BLF_size(blf_mono_font, 11.0f * U.pixelsize, U.dpi); BLF_color3ub(blf_mono_font, 255, 255, 255); SNPRINTF(str, "X:%-4d Y:%-4d |", x, y); diff --git a/source/blender/editors/space_info/info_stats.cc b/source/blender/editors/space_info/info_stats.cc index 62f40ae625d..19c98fb4d17 100644 --- a/source/blender/editors/space_info/info_stats.cc +++ b/source/blender/editors/space_info/info_stats.cc @@ -175,7 +175,7 @@ static void stats_object(Object *ob, if (stats_mesheval(me_eval, is_selected, stats)) { break; } - ATTR_FALLTHROUGH; /* Fallthrough to displist. */ + ATTR_FALLTHROUGH; /* Fall-through to displist. */ } case OB_MBALL: { int totv = 0, totf = 0, tottri = 0; diff --git a/source/blender/editors/space_node/CMakeLists.txt b/source/blender/editors/space_node/CMakeLists.txt index 677032d42bf..444ab6c827e 100644 --- a/source/blender/editors/space_node/CMakeLists.txt +++ b/source/blender/editors/space_node/CMakeLists.txt @@ -45,17 +45,17 @@ set(SRC node_draw.cc node_edit.cc node_geometry_attribute_search.cc - node_gizmo.c + node_gizmo.cc node_group.cc - node_ops.c + node_ops.cc node_relationships.cc node_select.cc node_templates.cc node_toolbar.cc node_view.cc - space_node.c + space_node.cc - node_intern.h + node_intern.hh ) set(LIB diff --git a/source/blender/editors/space_node/drawnode.cc b/source/blender/editors/space_node/drawnode.cc index 705fd391a6b..0226c7ba61e 100644 --- a/source/blender/editors/space_node/drawnode.cc +++ b/source/blender/editors/space_node/drawnode.cc @@ -77,7 +77,7 @@ #include "NOD_node_declaration.hh" #include "NOD_shader.h" #include "NOD_texture.h" -#include "node_intern.h" /* own include */ +#include "node_intern.hh" /* own include */ /* Default flags for uiItemR(). Name is kept short since this is used a lot in this file. */ #define DEFAULT_FLAGS UI_ITEM_R_SPLIT_EMPTY_NAME @@ -342,7 +342,7 @@ static void node_draw_frame_label(bNodeTree *ntree, bNode *node, const float asp /* XXX font id is crap design */ const int fontid = UI_style_get()->widgetlabel.uifont_id; NodeFrame *data = (NodeFrame *)node->storage; - const int font_size = data->label_size / aspect; + const float font_size = data->label_size / aspect; char label[MAX_NAME]; nodeLabel(ntree, node, label, sizeof(label)); @@ -350,7 +350,7 @@ static void node_draw_frame_label(bNodeTree *ntree, bNode *node, const float asp BLF_enable(fontid, BLF_ASPECT); BLF_aspect(fontid, aspect, aspect, 1.0f); /* clamp otherwise it can suck up a LOT of memory */ - BLF_size(fontid, MIN2(24, font_size), U.dpi); + BLF_size(fontid, MIN2(24.0f, font_size), U.dpi); /* title color */ int color_id = node_get_colorid(node); diff --git a/source/blender/editors/space_node/node_add.cc b/source/blender/editors/space_node/node_add.cc index 522b0d63ba1..ae59cf7e365 100644 --- a/source/blender/editors/space_node/node_add.cc +++ b/source/blender/editors/space_node/node_add.cc @@ -57,7 +57,7 @@ #include "UI_view2d.h" -#include "node_intern.h" /* own include */ +#include "node_intern.hh" /* own include */ /* -------------------------------------------------------------------- */ /** \name Utilities diff --git a/source/blender/editors/space_node/node_context_path.cc b/source/blender/editors/space_node/node_context_path.cc index a0ff7f3ce25..2f3855fd654 100644 --- a/source/blender/editors/space_node/node_context_path.cc +++ b/source/blender/editors/space_node/node_context_path.cc @@ -43,7 +43,7 @@ #include "UI_interface.hh" -#include "node_intern.h" +#include "node_intern.hh" struct Mesh; struct Curve; diff --git a/source/blender/editors/space_node/node_draw.cc b/source/blender/editors/space_node/node_draw.cc index 5fdf816339b..b2c16280c58 100644 --- a/source/blender/editors/space_node/node_draw.cc +++ b/source/blender/editors/space_node/node_draw.cc @@ -85,7 +85,7 @@ #include "FN_field_cpp_type.hh" -#include "node_intern.h" /* own include */ +#include "node_intern.hh" /* own include */ #ifdef WITH_COMPOSITOR # include "COM_compositor.h" diff --git a/source/blender/editors/space_node/node_edit.cc b/source/blender/editors/space_node/node_edit.cc index a30f8f02ab1..7c112524ca4 100644 --- a/source/blender/editors/space_node/node_edit.cc +++ b/source/blender/editors/space_node/node_edit.cc @@ -80,7 +80,7 @@ #include "NOD_geometry.h" #include "NOD_shader.h" #include "NOD_texture.h" -#include "node_intern.h" /* own include */ +#include "node_intern.hh" /* own include */ #define USE_ESC_COMPO diff --git a/source/blender/editors/space_node/node_geometry_attribute_search.cc b/source/blender/editors/space_node/node_geometry_attribute_search.cc index d0ccbb03107..79ba9b8d2d9 100644 --- a/source/blender/editors/space_node/node_geometry_attribute_search.cc +++ b/source/blender/editors/space_node/node_geometry_attribute_search.cc @@ -33,6 +33,7 @@ #include "RNA_access.h" #include "RNA_enum_types.h" +#include "ED_screen.h" #include "ED_undo.h" #include "BLT_translation.h" @@ -43,7 +44,7 @@ #include "NOD_geometry_nodes_eval_log.hh" -#include "node_intern.h" +#include "node_intern.hh" using blender::IndexRange; using blender::Map; @@ -64,6 +65,10 @@ BLI_STATIC_ASSERT(std::is_trivially_destructible_v<AttributeSearchData>, ""); static void attribute_search_update_fn( const bContext *C, void *arg, const char *str, uiSearchItems *items, const bool is_first) { + if (ED_screen_animation_playing(CTX_wm_manager(C))) { + return; + } + AttributeSearchData *data = static_cast<AttributeSearchData *>(arg); SpaceNode *snode = CTX_wm_space_node(C); @@ -79,6 +84,9 @@ static void attribute_search_update_fn( static void attribute_search_exec_fn(bContext *C, void *data_v, void *item_v) { + if (ED_screen_animation_playing(CTX_wm_manager(C))) { + return; + } if (item_v == nullptr) { return; } diff --git a/source/blender/editors/space_node/node_gizmo.c b/source/blender/editors/space_node/node_gizmo.cc index e1deca54890..717f4d2f4f9 100644 --- a/source/blender/editors/space_node/node_gizmo.c +++ b/source/blender/editors/space_node/node_gizmo.cc @@ -18,7 +18,7 @@ * \ingroup spnode */ -#include <math.h> +#include <cmath> #include "BLI_math_matrix.h" #include "BLI_math_vector.h" @@ -41,7 +41,7 @@ #include "WM_api.h" #include "WM_types.h" -#include "node_intern.h" +#include "node_intern.hh" /* -------------------------------------------------------------------- */ /** \name Local Utilities @@ -80,9 +80,9 @@ static void gizmo_node_backdrop_prop_matrix_get(const wmGizmo *UNUSED(gz), wmGizmoProperty *gz_prop, void *value_p) { - float(*matrix)[4] = value_p; + float(*matrix)[4] = (float(*)[4])value_p; BLI_assert(gz_prop->type->array_length == 16); - const SpaceNode *snode = gz_prop->custom_func.user_data; + const SpaceNode *snode = (const SpaceNode *)gz_prop->custom_func.user_data; matrix[0][0] = snode->zoom; matrix[1][1] = snode->zoom; matrix[3][0] = snode->xof; @@ -93,9 +93,9 @@ static void gizmo_node_backdrop_prop_matrix_set(const wmGizmo *UNUSED(gz), wmGizmoProperty *gz_prop, const void *value_p) { - const float(*matrix)[4] = value_p; + const float(*matrix)[4] = (const float(*)[4])value_p; BLI_assert(gz_prop->type->array_length == 16); - SpaceNode *snode = gz_prop->custom_func.user_data; + SpaceNode *snode = (SpaceNode *)gz_prop->custom_func.user_data; snode->zoom = matrix[0][0]; snode->xof = matrix[3][0]; snode->yof = matrix[3][1]; @@ -122,9 +122,9 @@ static bool WIDGETGROUP_node_transform_poll(const bContext *C, wmGizmoGroupType static void WIDGETGROUP_node_transform_setup(const bContext *UNUSED(C), wmGizmoGroup *gzgroup) { - wmGizmoWrapper *wwrapper = MEM_mallocN(sizeof(wmGizmoWrapper), __func__); + wmGizmoWrapper *wwrapper = (wmGizmoWrapper *)MEM_mallocN(sizeof(wmGizmoWrapper), __func__); - wwrapper->gizmo = WM_gizmo_new("GIZMO_GT_cage_2d", gzgroup, NULL); + wwrapper->gizmo = WM_gizmo_new("GIZMO_GT_cage_2d", gzgroup, nullptr); RNA_enum_set(wwrapper->gizmo->ptr, "transform", @@ -139,11 +139,11 @@ static void WIDGETGROUP_node_transform_refresh(const bContext *C, wmGizmoGroup * wmGizmo *cage = ((wmGizmoWrapper *)gzgroup->customdata)->gizmo; const ARegion *region = CTX_wm_region(C); /* center is always at the origin */ - const float origin[3] = {region->winx / 2, region->winy / 2}; + const float origin[3] = {float(region->winx / 2), float(region->winy / 2), 0.0f}; void *lock; Image *ima = BKE_image_ensure_viewer(bmain, IMA_TYPE_COMPOSITE, "Viewer Node"); - ImBuf *ibuf = BKE_image_acquire_ibuf(ima, NULL, &lock); + ImBuf *ibuf = BKE_image_acquire_ibuf(ima, nullptr, &lock); if (ibuf) { const float dims[2] = { @@ -164,14 +164,12 @@ static void WIDGETGROUP_node_transform_refresh(const bContext *C, wmGizmoGroup * WM_gizmo_target_property_def_rna(cage, "scale", &nodeptr, "backdrop_zoom", -1); #endif - WM_gizmo_target_property_def_func(cage, - "matrix", - &(const struct wmGizmoPropertyFnParams){ - .value_get_fn = gizmo_node_backdrop_prop_matrix_get, - .value_set_fn = gizmo_node_backdrop_prop_matrix_set, - .range_get_fn = NULL, - .user_data = snode, - }); + wmGizmoPropertyFnParams params{}; + params.value_get_fn = gizmo_node_backdrop_prop_matrix_get; + params.value_set_fn = gizmo_node_backdrop_prop_matrix_set; + params.range_get_fn = nullptr; + params.user_data = snode; + WM_gizmo_target_property_def_func(cage, "matrix", ¶ms); } else { WM_gizmo_set_flag(cage, WM_GIZMO_HIDDEN, true); @@ -262,12 +260,12 @@ static void gizmo_node_crop_prop_matrix_get(const wmGizmo *gz, wmGizmoProperty *gz_prop, void *value_p) { - float(*matrix)[4] = value_p; + float(*matrix)[4] = (float(*)[4])value_p; BLI_assert(gz_prop->type->array_length == 16); - struct NodeCropWidgetGroup *crop_group = gz->parent_gzgroup->customdata; + NodeCropWidgetGroup *crop_group = (NodeCropWidgetGroup *)gz->parent_gzgroup->customdata; const float *dims = crop_group->state.dims; - const bNode *node = gz_prop->custom_func.user_data; - const NodeTwoXYs *nxy = node->storage; + const bNode *node = (const bNode *)gz_prop->custom_func.user_data; + const NodeTwoXYs *nxy = (const NodeTwoXYs *)node->storage; bool is_relative = (bool)node->custom2; rctf rct; two_xy_to_rect(nxy, &rct, dims, is_relative); @@ -281,12 +279,12 @@ static void gizmo_node_crop_prop_matrix_set(const wmGizmo *gz, wmGizmoProperty *gz_prop, const void *value_p) { - const float(*matrix)[4] = value_p; + const float(*matrix)[4] = (const float(*)[4])value_p; BLI_assert(gz_prop->type->array_length == 16); - struct NodeCropWidgetGroup *crop_group = gz->parent_gzgroup->customdata; + NodeCropWidgetGroup *crop_group = (NodeCropWidgetGroup *)gz->parent_gzgroup->customdata; const float *dims = crop_group->state.dims; - bNode *node = gz_prop->custom_func.user_data; - NodeTwoXYs *nxy = node->storage; + bNode *node = (bNode *)gz_prop->custom_func.user_data; + NodeTwoXYs *nxy = (NodeTwoXYs *)node->storage; bool is_relative = (bool)node->custom2; rctf rct; two_xy_to_rect(nxy, &rct, dims, is_relative); @@ -294,15 +292,8 @@ static void gizmo_node_crop_prop_matrix_set(const wmGizmo *gz, const bool ny = rct.ymin > rct.ymax; BLI_rctf_resize(&rct, fabsf(matrix[0][0]), fabsf(matrix[1][1])); BLI_rctf_recenter(&rct, (matrix[3][0] / dims[0]) + 0.5f, (matrix[3][1] / dims[1]) + 0.5f); - BLI_rctf_isect( - &(rctf){ - .xmin = 0, - .ymin = 0, - .xmax = 1, - .ymax = 1, - }, - &rct, - &rct); + const rctf rct_isect{0, 0, 1, 1}; + BLI_rctf_isect(&rct_isect, &rct, &rct); if (nx) { SWAP(float, rct.xmin, rct.xmax); } @@ -337,10 +328,10 @@ static bool WIDGETGROUP_node_crop_poll(const bContext *C, wmGizmoGroupType *UNUS static void WIDGETGROUP_node_crop_setup(const bContext *UNUSED(C), wmGizmoGroup *gzgroup) { - struct NodeCropWidgetGroup *crop_group = MEM_mallocN(sizeof(struct NodeCropWidgetGroup), - __func__); + struct NodeCropWidgetGroup *crop_group = (NodeCropWidgetGroup *)MEM_mallocN( + sizeof(struct NodeCropWidgetGroup), __func__); - crop_group->border = WM_gizmo_new("GIZMO_GT_cage_2d", gzgroup, NULL); + crop_group->border = WM_gizmo_new("GIZMO_GT_cage_2d", gzgroup, nullptr); RNA_enum_set(crop_group->border->ptr, "transform", @@ -352,7 +343,7 @@ static void WIDGETGROUP_node_crop_setup(const bContext *UNUSED(C), wmGizmoGroup static void WIDGETGROUP_node_crop_draw_prepare(const bContext *C, wmGizmoGroup *gzgroup) { ARegion *region = CTX_wm_region(C); - wmGizmo *gz = gzgroup->gizmos.first; + wmGizmo *gz = (wmGizmo *)gzgroup->gizmos.first; SpaceNode *snode = CTX_wm_space_node(C); @@ -362,12 +353,12 @@ static void WIDGETGROUP_node_crop_draw_prepare(const bContext *C, wmGizmoGroup * static void WIDGETGROUP_node_crop_refresh(const bContext *C, wmGizmoGroup *gzgroup) { Main *bmain = CTX_data_main(C); - struct NodeCropWidgetGroup *crop_group = gzgroup->customdata; + NodeCropWidgetGroup *crop_group = (NodeCropWidgetGroup *)gzgroup->customdata; wmGizmo *gz = crop_group->border; void *lock; Image *ima = BKE_image_ensure_viewer(bmain, IMA_TYPE_COMPOSITE, "Viewer Node"); - ImBuf *ibuf = BKE_image_acquire_ibuf(ima, NULL, &lock); + ImBuf *ibuf = BKE_image_acquire_ibuf(ima, nullptr, &lock); if (ibuf) { crop_group->state.dims[0] = (ibuf->x > 0) ? ibuf->x : 64.0f; @@ -385,14 +376,12 @@ static void WIDGETGROUP_node_crop_refresh(const bContext *C, wmGizmoGroup *gzgro crop_group->update_data.prop = RNA_struct_find_property(&crop_group->update_data.ptr, "relative"); - WM_gizmo_target_property_def_func(gz, - "matrix", - &(const struct wmGizmoPropertyFnParams){ - .value_get_fn = gizmo_node_crop_prop_matrix_get, - .value_set_fn = gizmo_node_crop_prop_matrix_set, - .range_get_fn = NULL, - .user_data = node, - }); + wmGizmoPropertyFnParams params{}; + params.value_get_fn = gizmo_node_crop_prop_matrix_get; + params.value_set_fn = gizmo_node_crop_prop_matrix_set; + params.range_get_fn = nullptr; + params.user_data = snode; + WM_gizmo_target_property_def_func(gz, "matrix", ¶ms); } else { WM_gizmo_set_flag(gz, WM_GIZMO_HIDDEN, true); @@ -450,10 +439,10 @@ static bool WIDGETGROUP_node_sbeam_poll(const bContext *C, wmGizmoGroupType *UNU static void WIDGETGROUP_node_sbeam_setup(const bContext *UNUSED(C), wmGizmoGroup *gzgroup) { - struct NodeSunBeamsWidgetGroup *sbeam_group = MEM_mallocN(sizeof(struct NodeSunBeamsWidgetGroup), - __func__); + NodeSunBeamsWidgetGroup *sbeam_group = (NodeSunBeamsWidgetGroup *)MEM_mallocN( + sizeof(NodeSunBeamsWidgetGroup), __func__); - sbeam_group->gizmo = WM_gizmo_new("GIZMO_GT_move_3d", gzgroup, NULL); + sbeam_group->gizmo = WM_gizmo_new("GIZMO_GT_move_3d", gzgroup, nullptr); wmGizmo *gz = sbeam_group->gizmo; RNA_enum_set(gz->ptr, "draw_style", ED_GIZMO_MOVE_STYLE_CROSS_2D); @@ -465,9 +454,9 @@ static void WIDGETGROUP_node_sbeam_setup(const bContext *UNUSED(C), wmGizmoGroup static void WIDGETGROUP_node_sbeam_draw_prepare(const bContext *C, wmGizmoGroup *gzgroup) { - struct NodeSunBeamsWidgetGroup *sbeam_group = gzgroup->customdata; + NodeSunBeamsWidgetGroup *sbeam_group = (NodeSunBeamsWidgetGroup *)gzgroup->customdata; ARegion *region = CTX_wm_region(C); - wmGizmo *gz = gzgroup->gizmos.first; + wmGizmo *gz = (wmGizmo *)gzgroup->gizmos.first; SpaceNode *snode = CTX_wm_space_node(C); @@ -478,12 +467,12 @@ static void WIDGETGROUP_node_sbeam_draw_prepare(const bContext *C, wmGizmoGroup static void WIDGETGROUP_node_sbeam_refresh(const bContext *C, wmGizmoGroup *gzgroup) { Main *bmain = CTX_data_main(C); - struct NodeSunBeamsWidgetGroup *sbeam_group = gzgroup->customdata; + NodeSunBeamsWidgetGroup *sbeam_group = (NodeSunBeamsWidgetGroup *)gzgroup->customdata; wmGizmo *gz = sbeam_group->gizmo; void *lock; Image *ima = BKE_image_ensure_viewer(bmain, IMA_TYPE_COMPOSITE, "Viewer Node"); - ImBuf *ibuf = BKE_image_acquire_ibuf(ima, NULL, &lock); + ImBuf *ibuf = BKE_image_acquire_ibuf(ima, nullptr, &lock); if (ibuf) { sbeam_group->state.dims[0] = (ibuf->x > 0) ? ibuf->x : 64.0f; @@ -555,12 +544,12 @@ static bool WIDGETGROUP_node_corner_pin_poll(const bContext *C, wmGizmoGroupType static void WIDGETGROUP_node_corner_pin_setup(const bContext *UNUSED(C), wmGizmoGroup *gzgroup) { - struct NodeCornerPinWidgetGroup *cpin_group = MEM_mallocN( - sizeof(struct NodeCornerPinWidgetGroup), __func__); + NodeCornerPinWidgetGroup *cpin_group = (NodeCornerPinWidgetGroup *)MEM_mallocN( + sizeof(NodeCornerPinWidgetGroup), __func__); const wmGizmoType *gzt_move_3d = WM_gizmotype_find("GIZMO_GT_move_3d", false); for (int i = 0; i < 4; i++) { - cpin_group->gizmos[i] = WM_gizmo_new_ptr(gzt_move_3d, gzgroup, NULL); + cpin_group->gizmos[i] = WM_gizmo_new_ptr(gzt_move_3d, gzgroup, nullptr); wmGizmo *gz = cpin_group->gizmos[i]; RNA_enum_set(gz->ptr, "draw_style", ED_GIZMO_MOVE_STYLE_CROSS_2D); @@ -573,7 +562,7 @@ static void WIDGETGROUP_node_corner_pin_setup(const bContext *UNUSED(C), wmGizmo static void WIDGETGROUP_node_corner_pin_draw_prepare(const bContext *C, wmGizmoGroup *gzgroup) { - struct NodeCornerPinWidgetGroup *cpin_group = gzgroup->customdata; + NodeCornerPinWidgetGroup *cpin_group = (NodeCornerPinWidgetGroup *)gzgroup->customdata; ARegion *region = CTX_wm_region(C); SpaceNode *snode = CTX_wm_space_node(C); @@ -591,11 +580,11 @@ static void WIDGETGROUP_node_corner_pin_draw_prepare(const bContext *C, wmGizmoG static void WIDGETGROUP_node_corner_pin_refresh(const bContext *C, wmGizmoGroup *gzgroup) { Main *bmain = CTX_data_main(C); - struct NodeCornerPinWidgetGroup *cpin_group = gzgroup->customdata; + NodeCornerPinWidgetGroup *cpin_group = (NodeCornerPinWidgetGroup *)gzgroup->customdata; void *lock; Image *ima = BKE_image_ensure_viewer(bmain, IMA_TYPE_COMPOSITE, "Viewer Node"); - ImBuf *ibuf = BKE_image_acquire_ibuf(ima, NULL, &lock); + ImBuf *ibuf = BKE_image_acquire_ibuf(ima, nullptr, &lock); if (ibuf) { cpin_group->state.dims[0] = (ibuf->x > 0) ? ibuf->x : 64.0f; @@ -606,7 +595,7 @@ static void WIDGETGROUP_node_corner_pin_refresh(const bContext *C, wmGizmoGroup /* need to set property here for undo. TODO: would prefer to do this in _init. */ int i = 0; - for (bNodeSocket *sock = node->inputs.first; sock && i < 4; sock = sock->next) { + for (bNodeSocket *sock = (bNodeSocket *)node->inputs.first; sock && i < 4; sock = sock->next) { if (sock->type == SOCK_VECTOR) { wmGizmo *gz = cpin_group->gizmos[i++]; diff --git a/source/blender/editors/space_node/node_group.cc b/source/blender/editors/space_node/node_group.cc index 73e7f612e5e..125c2ba8249 100644 --- a/source/blender/editors/space_node/node_group.cc +++ b/source/blender/editors/space_node/node_group.cc @@ -59,7 +59,7 @@ #include "NOD_common.h" #include "NOD_socket.h" -#include "node_intern.h" /* own include */ +#include "node_intern.hh" /* own include */ /* -------------------------------------------------------------------- */ /** \name Local Utilities diff --git a/source/blender/editors/space_node/node_intern.h b/source/blender/editors/space_node/node_intern.hh index 383fe5afdf9..cb2980b7db5 100644 --- a/source/blender/editors/space_node/node_intern.h +++ b/source/blender/editors/space_node/node_intern.hh @@ -26,6 +26,10 @@ #include "BKE_node.h" #include "UI_interface.h" #include "UI_view2d.h" + +#include "BLI_vector.hh" +#include "UI_interface.hh" + #include <stddef.h> /* for size_t */ /* internal exports only */ @@ -43,10 +47,6 @@ struct wmGizmoGroupType; struct wmKeyConfig; struct wmWindow; -#ifdef __cplusplus -extern "C" { -#endif - /* temp data to pass on to modal */ typedef struct bNodeLinkDrag { struct bNodeLinkDrag *next, *prev; @@ -342,14 +342,6 @@ extern const char *node_context_dir[]; #define NODE_RESIZE_MARGIN (0.20f * U.widget_unit) #define NODE_LINK_RESOL 12 -#ifdef __cplusplus -} -#endif - -#ifdef __cplusplus -# include "BLI_vector.hh" -# include "UI_interface.hh" namespace blender::ed::space_node { Vector<ui::ContextPathItem> context_path_for_space_node(const bContext &C); } -#endif diff --git a/source/blender/editors/space_node/node_ops.c b/source/blender/editors/space_node/node_ops.cc index 0c54da65e9c..4c08f4d7b47 100644 --- a/source/blender/editors/space_node/node_ops.c +++ b/source/blender/editors/space_node/node_ops.cc @@ -33,9 +33,9 @@ #include "WM_api.h" #include "WM_types.h" -#include "node_intern.h" /* own include */ +#include "node_intern.hh" /* own include */ -void node_operatortypes(void) +void node_operatortypes() { WM_operatortype_append(NODE_OT_select); WM_operatortype_append(NODE_OT_select_all); diff --git a/source/blender/editors/space_node/node_relationships.cc b/source/blender/editors/space_node/node_relationships.cc index 1bc68ddf468..623615f112d 100644 --- a/source/blender/editors/space_node/node_relationships.cc +++ b/source/blender/editors/space_node/node_relationships.cc @@ -61,7 +61,7 @@ #include "NOD_node_declaration.hh" #include "NOD_node_tree_ref.hh" -#include "node_intern.h" /* own include */ +#include "node_intern.hh" /* own include */ using namespace blender::nodes::node_tree_ref_types; @@ -2349,8 +2349,8 @@ static void node_link_insert_offset_ntree(NodeInsertOfsData *iofsd, /* NODE_TEST will be used later, so disable for all nodes */ ntreeNodeFlagSet(ntree, NODE_TEST, false); - /* insert->totr isn't updated yet, - * so totr_insert is used to get the correct worldspace coords */ + /* `insert->totr` isn't updated yet, + * so `totr_insert` is used to get the correct world-space coords. */ rctf totr_insert; node_to_updated_rect(insert, &totr_insert); diff --git a/source/blender/editors/space_node/node_select.cc b/source/blender/editors/space_node/node_select.cc index 29b8372d043..3c7b404547b 100644 --- a/source/blender/editors/space_node/node_select.cc +++ b/source/blender/editors/space_node/node_select.cc @@ -61,7 +61,7 @@ #include "MEM_guardedalloc.h" -#include "node_intern.h" /* own include */ +#include "node_intern.hh" /* own include */ /** * Function to detect if there is a visible view3d that uses workbench in texture mode. diff --git a/source/blender/editors/space_node/node_templates.cc b/source/blender/editors/space_node/node_templates.cc index 84a3c842779..a060bbefa5c 100644 --- a/source/blender/editors/space_node/node_templates.cc +++ b/source/blender/editors/space_node/node_templates.cc @@ -49,7 +49,7 @@ #include "UI_interface.h" #include "ED_node.h" /* own include */ -#include "node_intern.h" +#include "node_intern.hh" #include "ED_undo.h" diff --git a/source/blender/editors/space_node/node_toolbar.cc b/source/blender/editors/space_node/node_toolbar.cc index 2e7d6ab6cd5..c32dcbef91b 100644 --- a/source/blender/editors/space_node/node_toolbar.cc +++ b/source/blender/editors/space_node/node_toolbar.cc @@ -30,7 +30,7 @@ #include "WM_api.h" -#include "node_intern.h" /* own include */ +#include "node_intern.hh" /* own include */ /* ******************* node toolbar registration ************** */ diff --git a/source/blender/editors/space_node/node_view.cc b/source/blender/editors/space_node/node_view.cc index 762b4b36a39..36b84bec7eb 100644 --- a/source/blender/editors/space_node/node_view.cc +++ b/source/blender/editors/space_node/node_view.cc @@ -54,7 +54,7 @@ #include "IMB_imbuf.h" #include "IMB_imbuf_types.h" -#include "node_intern.h" /* own include */ +#include "node_intern.hh" /* own include */ using blender::StringRef; diff --git a/source/blender/editors/space_node/space_node.c b/source/blender/editors/space_node/space_node.cc index 0b5d7cdda82..a94deb97f42 100644 --- a/source/blender/editors/space_node/space_node.c +++ b/source/blender/editors/space_node/space_node.cc @@ -52,21 +52,19 @@ #include "WM_api.h" #include "WM_types.h" -#include "node_intern.h" /* own include */ +#include "node_intern.hh" /* own include */ /* ******************** tree path ********************* */ void ED_node_tree_start(SpaceNode *snode, bNodeTree *ntree, ID *id, ID *from) { - bNodeTreePath *path, *path_next; - for (path = snode->treepath.first; path; path = path_next) { - path_next = path->next; + LISTBASE_FOREACH_MUTABLE (bNodeTreePath *, path, &snode->treepath) { MEM_freeN(path); } BLI_listbase_clear(&snode->treepath); if (ntree) { - path = MEM_callocN(sizeof(bNodeTreePath), "node tree path"); + bNodeTreePath *path = (bNodeTreePath *)MEM_callocN(sizeof(bNodeTreePath), "node tree path"); path->nodetree = ntree; path->parent_key = NODE_INSTANCE_KEY_BASE; @@ -94,13 +92,13 @@ void ED_node_tree_start(SpaceNode *snode, bNodeTree *ntree, ID *id, ID *from) ED_node_set_active_viewer_key(snode); - WM_main_add_notifier(NC_SCENE | ND_NODES, NULL); + WM_main_add_notifier(NC_SCENE | ND_NODES, nullptr); } void ED_node_tree_push(SpaceNode *snode, bNodeTree *ntree, bNode *gnode) { - bNodeTreePath *path = MEM_callocN(sizeof(bNodeTreePath), "node tree path"); - bNodeTreePath *prev_path = snode->treepath.last; + bNodeTreePath *path = (bNodeTreePath *)MEM_callocN(sizeof(bNodeTreePath), "node tree path"); + bNodeTreePath *prev_path = (bNodeTreePath *)snode->treepath.last; path->nodetree = ntree; if (gnode) { if (prev_path) { @@ -129,12 +127,12 @@ void ED_node_tree_push(SpaceNode *snode, bNodeTree *ntree, bNode *gnode) ED_node_set_active_viewer_key(snode); - WM_main_add_notifier(NC_SCENE | ND_NODES, NULL); + WM_main_add_notifier(NC_SCENE | ND_NODES, nullptr); } void ED_node_tree_pop(SpaceNode *snode) { - bNodeTreePath *path = snode->treepath.last; + bNodeTreePath *path = (bNodeTreePath *)snode->treepath.last; /* don't remove root */ if (path == snode->treepath.first) { @@ -145,13 +143,13 @@ void ED_node_tree_pop(SpaceNode *snode) MEM_freeN(path); /* update current tree */ - path = snode->treepath.last; + path = (bNodeTreePath *)snode->treepath.last; snode->edittree = path->nodetree; ED_node_set_active_viewer_key(snode); /* listener updates the View2D center from edittree */ - WM_main_add_notifier(NC_SCENE | ND_NODES, NULL); + WM_main_add_notifier(NC_SCENE | ND_NODES, nullptr); } int ED_node_tree_depth(SpaceNode *snode) @@ -163,12 +161,12 @@ bNodeTree *ED_node_tree_get(SpaceNode *snode, int level) { bNodeTreePath *path; int i; - for (path = snode->treepath.last, i = 0; path; path = path->prev, i++) { + for (path = (bNodeTreePath *)snode->treepath.last, i = 0; path; path = path->prev, i++) { if (i == level) { return path->nodetree; } } - return NULL; + return nullptr; } int ED_node_tree_path_length(SpaceNode *snode) @@ -203,7 +201,7 @@ void ED_node_tree_path_get(SpaceNode *snode, char *value) void ED_node_set_active_viewer_key(SpaceNode *snode) { - bNodeTreePath *path = snode->treepath.last; + bNodeTreePath *path = (bNodeTreePath *)snode->treepath.last; if (snode->nodetree && path) { snode->nodetree->active_viewer_key = path->parent_key; } @@ -211,7 +209,7 @@ void ED_node_set_active_viewer_key(SpaceNode *snode) void space_node_group_offset(SpaceNode *snode, float *x, float *y) { - bNodeTreePath *path = snode->treepath.last; + bNodeTreePath *path = (bNodeTreePath *)snode->treepath.last; if (path && path->prev) { float dcenter[2]; @@ -228,10 +226,7 @@ void space_node_group_offset(SpaceNode *snode, float *x, float *y) static SpaceLink *node_create(const ScrArea *UNUSED(area), const Scene *UNUSED(scene)) { - ARegion *region; - SpaceNode *snode; - - snode = MEM_callocN(sizeof(SpaceNode), "initnode"); + SpaceNode *snode = (SpaceNode *)MEM_callocN(sizeof(SpaceNode), "initnode"); snode->spacetype = SPACE_NODE; snode->flag = SNODE_SHOW_GPENCIL | SNODE_USE_ALPHA; @@ -249,21 +244,21 @@ static SpaceLink *node_create(const ScrArea *UNUSED(area), const Scene *UNUSED(s NODE_TREE_TYPES_END; /* header */ - region = MEM_callocN(sizeof(ARegion), "header for node"); + ARegion *region = (ARegion *)MEM_callocN(sizeof(ARegion), "header for node"); BLI_addtail(&snode->regionbase, region); region->regiontype = RGN_TYPE_HEADER; region->alignment = (U.uiflag & USER_HEADER_BOTTOM) ? RGN_ALIGN_BOTTOM : RGN_ALIGN_TOP; /* buttons/list view */ - region = MEM_callocN(sizeof(ARegion), "buttons for node"); + region = (ARegion *)MEM_callocN(sizeof(ARegion), "buttons for node"); BLI_addtail(&snode->regionbase, region); region->regiontype = RGN_TYPE_UI; region->alignment = RGN_ALIGN_RIGHT; /* toolbar */ - region = MEM_callocN(sizeof(ARegion), "node tools"); + region = (ARegion *)MEM_callocN(sizeof(ARegion), "node tools"); BLI_addtail(&snode->regionbase, region); region->regiontype = RGN_TYPE_TOOLS; @@ -272,7 +267,7 @@ static SpaceLink *node_create(const ScrArea *UNUSED(area), const Scene *UNUSED(s region->flag = RGN_FLAG_HIDDEN; /* main region */ - region = MEM_callocN(sizeof(ARegion), "main region for node"); + region = (ARegion *)MEM_callocN(sizeof(ARegion), "main region for node"); BLI_addtail(&snode->regionbase, region); region->regiontype = RGN_TYPE_WINDOW; @@ -316,8 +311,8 @@ static void node_init(struct wmWindowManager *UNUSED(wm), ScrArea *area) { SpaceNode *snode = (SpaceNode *)area->spacedata.first; - if (snode->runtime == NULL) { - snode->runtime = MEM_callocN(sizeof(SpaceNode_Runtime), __func__); + if (snode->runtime == nullptr) { + snode->runtime = (SpaceNode_Runtime *)MEM_callocN(sizeof(SpaceNode_Runtime), __func__); } } @@ -327,7 +322,7 @@ static void node_area_listener(const wmSpaceTypeListenerParams *params) wmNotifier *wmn = params->notifier; /* NOTE: #ED_area_tag_refresh will re-execute compositor. */ - SpaceNode *snode = area->spacedata.first; + SpaceNode *snode = (SpaceNode *)area->spacedata.first; /* shaderfrom is only used for new shading nodes, otherwise all shaders are from objects */ short shader_type = snode->shaderfrom; @@ -337,7 +332,7 @@ static void node_area_listener(const wmSpaceTypeListenerParams *params) switch (wmn->data) { case ND_NODES: { ARegion *region = BKE_area_find_region_type(area, RGN_TYPE_WINDOW); - bNodeTreePath *path = snode->treepath.last; + bNodeTreePath *path = (bNodeTreePath *)snode->treepath.last; /* shift view to node tree center */ if (region && path) { UI_view2d_center_set(®ion->v2d, path->view_center[0], path->view_center[1]); @@ -379,7 +374,7 @@ static void node_area_listener(const wmSpaceTypeListenerParams *params) ED_area_tag_refresh(area); } else if (wmn->action == NA_ADDED && snode->edittree) { - nodeSetActiveID(snode->edittree, ID_MA, wmn->reference); + nodeSetActiveID(snode->edittree, ID_MA, (ID *)wmn->reference); } } break; @@ -404,7 +399,7 @@ static void node_area_listener(const wmSpaceTypeListenerParams *params) else if (ED_node_is_geometry(snode)) { /* Rather strict check: only redraw when the reference matches the current editor's ID. */ if (wmn->data == ND_MODIFIER) { - if (wmn->reference == snode->id || snode->id == NULL) { + if (wmn->reference == snode->id || snode->id == nullptr) { ED_area_tag_refresh(area); } } @@ -447,7 +442,7 @@ static void node_area_listener(const wmSpaceTypeListenerParams *params) /* note that nodeUpdateID is already called by BKE_image_signal() on all * scenes so really this is just to know if the images is used in the compo else * painting on images could become very slow when the compositor is open. */ - if (nodeUpdateID(snode->nodetree, wmn->reference)) { + if (nodeUpdateID(snode->nodetree, (ID *)wmn->reference)) { ED_area_tag_refresh(area); } } @@ -457,7 +452,7 @@ static void node_area_listener(const wmSpaceTypeListenerParams *params) case NC_MOVIECLIP: if (wmn->action == NA_EDITED) { if (ED_node_is_compositor(snode)) { - if (nodeUpdateID(snode->nodetree, wmn->reference)) { + if (nodeUpdateID(snode->nodetree, (ID *)wmn->reference)) { ED_area_tag_refresh(area); } } @@ -485,7 +480,7 @@ static void node_area_listener(const wmSpaceTypeListenerParams *params) static void node_area_refresh(const struct bContext *C, ScrArea *area) { /* default now: refresh node is starting preview */ - SpaceNode *snode = area->spacedata.first; + SpaceNode *snode = (SpaceNode *)area->spacedata.first; snode_set_context(C); @@ -494,19 +489,19 @@ static void node_area_refresh(const struct bContext *C, ScrArea *area) if (GS(snode->id->name) == ID_MA) { Material *ma = (Material *)snode->id; if (ma->use_nodes) { - ED_preview_shader_job(C, area, snode->id, NULL, NULL, 100, 100, PR_NODE_RENDER); + ED_preview_shader_job(C, area, snode->id, nullptr, nullptr, 100, 100, PR_NODE_RENDER); } } else if (GS(snode->id->name) == ID_LA) { Light *la = (Light *)snode->id; if (la->use_nodes) { - ED_preview_shader_job(C, area, snode->id, NULL, NULL, 100, 100, PR_NODE_RENDER); + ED_preview_shader_job(C, area, snode->id, nullptr, nullptr, 100, 100, PR_NODE_RENDER); } } else if (GS(snode->id->name) == ID_WO) { World *wo = (World *)snode->id; if (wo->use_nodes) { - ED_preview_shader_job(C, area, snode->id, NULL, NULL, 100, 100, PR_NODE_RENDER); + ED_preview_shader_job(C, area, snode->id, nullptr, nullptr, 100, 100, PR_NODE_RENDER); } } } @@ -516,7 +511,7 @@ static void node_area_refresh(const struct bContext *C, ScrArea *area) /* recalc is set on 3d view changes for auto compo */ if (snode->runtime->recalc) { snode->runtime->recalc = false; - node_render_changed_exec((struct bContext *)C, NULL); + node_render_changed_exec((struct bContext *)C, nullptr); } else { ED_node_composite_job(C, snode->nodetree, scene); @@ -526,7 +521,7 @@ static void node_area_refresh(const struct bContext *C, ScrArea *area) else if (snode->nodetree->type == NTREE_TEXTURE) { Tex *tex = (Tex *)snode->id; if (tex->use_nodes) { - ED_preview_shader_job(C, area, snode->id, NULL, NULL, 100, 100, PR_NODE_RENDER); + ED_preview_shader_job(C, area, snode->id, nullptr, nullptr, 100, 100, PR_NODE_RENDER); } } } @@ -535,12 +530,12 @@ static void node_area_refresh(const struct bContext *C, ScrArea *area) static SpaceLink *node_duplicate(SpaceLink *sl) { SpaceNode *snode = (SpaceNode *)sl; - SpaceNode *snoden = MEM_dupallocN(snode); + SpaceNode *snoden = (SpaceNode *)MEM_dupallocN(snode); BLI_duplicatelist(&snoden->treepath, &snode->treepath); - if (snode->runtime != NULL) { - snoden->runtime = MEM_dupallocN(snode->runtime); + if (snode->runtime != nullptr) { + snoden->runtime = (SpaceNode_Runtime *)MEM_dupallocN(snode->runtime); BLI_listbase_clear(&snoden->runtime->linkdrag); } @@ -596,7 +591,7 @@ void ED_node_cursor_location_set(SpaceNode *snode, const float value[2]) static void node_cursor(wmWindow *win, ScrArea *area, ARegion *region) { - SpaceNode *snode = area->spacedata.first; + SpaceNode *snode = (SpaceNode *)area->spacedata.first; /* convert mouse coordinates to v2d space */ UI_view2d_region_to_view(®ion->v2d, @@ -710,7 +705,7 @@ static void node_id_path_drop_copy(wmDrag *drag, wmDropBox *drop) } /* this region dropbox definition */ -static void node_dropboxes(void) +static void node_dropboxes() { ListBase *lb = WM_dropboxmap_find("Node Editor", SPACE_NODE, RGN_TYPE_WINDOW); @@ -719,37 +714,37 @@ static void node_dropboxes(void) node_object_drop_poll, node_id_drop_copy, WM_drag_free_imported_drag_ID, - NULL); + nullptr); WM_dropbox_add(lb, "NODE_OT_add_collection", node_collection_drop_poll, node_id_drop_copy, WM_drag_free_imported_drag_ID, - NULL); + nullptr); WM_dropbox_add(lb, "NODE_OT_add_texture", node_texture_drop_poll, node_id_drop_copy, WM_drag_free_imported_drag_ID, - NULL); + nullptr); WM_dropbox_add(lb, "NODE_OT_add_group", node_group_drop_poll, node_group_drop_copy, WM_drag_free_imported_drag_ID, - NULL); + nullptr); WM_dropbox_add(lb, "NODE_OT_add_file", node_ima_drop_poll, node_id_path_drop_copy, WM_drag_free_imported_drag_ID, - NULL); + nullptr); WM_dropbox_add(lb, "NODE_OT_add_mask", node_mask_drop_poll, node_id_drop_copy, WM_drag_free_imported_drag_ID, - NULL); + nullptr); } /* ************* end drop *********** */ @@ -843,7 +838,7 @@ static void node_region_listener(const wmRegionListenerParams *params) } const char *node_context_dir[] = { - "selected_nodes", "active_node", "light", "material", "world", NULL}; + "selected_nodes", "active_node", "light", "material", "world", nullptr}; static int /*eContextResult*/ node_context(const bContext *C, const char *member, bContextDataResult *result) @@ -855,10 +850,8 @@ static int /*eContextResult*/ node_context(const bContext *C, return CTX_RESULT_OK; } if (CTX_data_equals(member, "selected_nodes")) { - bNode *node; - if (snode->edittree) { - for (node = snode->edittree->nodes.last; node; node = node->prev) { + LISTBASE_FOREACH_BACKWARD (bNode *, node, &snode->edittree->nodes) { if (node->flag & NODE_SELECT) { CTX_data_list_add(result, &snode->edittree->id, &RNA_Node, node); } @@ -907,11 +900,11 @@ static int /*eContextResult*/ node_context(const bContext *C, return CTX_RESULT_MEMBER_NOT_FOUND; } -static void node_widgets(void) +static void node_widgets() { - /* create the widgetmap for the area here */ - wmGizmoMapType *gzmap_type = WM_gizmomaptype_ensure( - &(const struct wmGizmoMapType_Params){SPACE_NODE, RGN_TYPE_WINDOW}); + /* Create the widget-map for the area here. */ + wmGizmoMapType_Params params{SPACE_NODE, RGN_TYPE_WINDOW}; + wmGizmoMapType *gzmap_type = WM_gizmomaptype_ensure(¶ms); WM_gizmogrouptype_append_and_link(gzmap_type, NODE_GGT_backdrop_transform); WM_gizmogrouptype_append_and_link(gzmap_type, NODE_GGT_backdrop_crop); WM_gizmogrouptype_append_and_link(gzmap_type, NODE_GGT_backdrop_sun_beams); @@ -928,15 +921,15 @@ static void node_id_remap(ScrArea *UNUSED(area), SpaceLink *slink, ID *old_id, I */ BLI_freelistN(&snode->treepath); - /* XXX Untested in case new_id != NULL... */ + /* XXX Untested in case new_id != nullptr... */ snode->id = new_id; - snode->from = NULL; - snode->nodetree = NULL; - snode->edittree = NULL; + snode->from = nullptr; + snode->nodetree = nullptr; + snode->edittree = nullptr; } else if (GS(old_id->name) == ID_OB) { if (snode->from == old_id) { - if (new_id == NULL) { + if (new_id == nullptr) { snode->flag &= ~SNODE_PIN; } snode->from = new_id; @@ -952,7 +945,7 @@ static void node_id_remap(ScrArea *UNUSED(area), SpaceLink *slink, ID *old_id, I else if (GS(old_id->name) == ID_NT) { bNodeTreePath *path, *path_next; - for (path = snode->treepath.first; path; path = path->next) { + for (path = (bNodeTreePath *)snode->treepath.first; path; path = path->next) { if ((ID *)path->nodetree == old_id) { path->nodetree = (bNodeTree *)new_id; id_us_ensure_real(new_id); @@ -961,7 +954,7 @@ static void node_id_remap(ScrArea *UNUSED(area), SpaceLink *slink, ID *old_id, I /* first nodetree in path is same as snode->nodetree */ snode->nodetree = path->nodetree; } - if (path->nodetree == NULL) { + if (path->nodetree == nullptr) { break; } } @@ -977,24 +970,24 @@ static void node_id_remap(ScrArea *UNUSED(area), SpaceLink *slink, ID *old_id, I /* edittree is just the last in the path, * set this directly since the path may have been shortened above */ if (snode->treepath.last) { - path = snode->treepath.last; + path = (bNodeTreePath *)snode->treepath.last; snode->edittree = path->nodetree; } else { - snode->edittree = NULL; + snode->edittree = nullptr; } } } static int node_space_subtype_get(ScrArea *area) { - SpaceNode *snode = area->spacedata.first; + SpaceNode *snode = (SpaceNode *)area->spacedata.first; return rna_node_tree_idname_to_enum(snode->tree_idname); } static void node_space_subtype_set(ScrArea *area, int value) { - SpaceNode *snode = area->spacedata.first; + SpaceNode *snode = (SpaceNode *)area->spacedata.first; ED_node_set_tree_type(snode, rna_node_tree_type_from_enum(value)); } @@ -1011,7 +1004,7 @@ static void node_space_subtype_item_extend(bContext *C, EnumPropertyItem **item, /* only called once, from space/spacetypes.c */ void ED_spacetype_node(void) { - SpaceType *st = MEM_callocN(sizeof(SpaceType), "spacetype node"); + SpaceType *st = (SpaceType *)MEM_callocN(sizeof(SpaceType), "spacetype node"); ARegionType *art; st->spaceid = SPACE_NODE; @@ -1034,7 +1027,7 @@ void ED_spacetype_node(void) st->space_subtype_set = node_space_subtype_set; /* regions: main window */ - art = MEM_callocN(sizeof(ARegionType), "spacetype node region"); + art = (ARegionType *)MEM_callocN(sizeof(ARegionType), "spacetype node region"); art->regionid = RGN_TYPE_WINDOW; art->init = node_main_region_init; art->draw = node_main_region_draw; @@ -1048,7 +1041,7 @@ void ED_spacetype_node(void) BLI_addhead(&st->regiontypes, art); /* regions: header */ - art = MEM_callocN(sizeof(ARegionType), "spacetype node region"); + art = (ARegionType *)MEM_callocN(sizeof(ARegionType), "spacetype node region"); art->regionid = RGN_TYPE_HEADER; art->prefsizey = HEADERY; art->keymapflag = ED_KEYMAP_UI | ED_KEYMAP_VIEW2D | ED_KEYMAP_FRAMES | ED_KEYMAP_HEADER; @@ -1059,7 +1052,7 @@ void ED_spacetype_node(void) BLI_addhead(&st->regiontypes, art); /* regions: listview/buttons */ - art = MEM_callocN(sizeof(ARegionType), "spacetype node region"); + art = (ARegionType *)MEM_callocN(sizeof(ARegionType), "spacetype node region"); art->regionid = RGN_TYPE_UI; art->prefsizex = UI_SIDEBAR_PANEL_WIDTH; art->keymapflag = ED_KEYMAP_UI | ED_KEYMAP_FRAMES; @@ -1070,7 +1063,7 @@ void ED_spacetype_node(void) BLI_addhead(&st->regiontypes, art); /* regions: toolbar */ - art = MEM_callocN(sizeof(ARegionType), "spacetype view3d tools region"); + art = (ARegionType *)MEM_callocN(sizeof(ARegionType), "spacetype view3d tools region"); art->regionid = RGN_TYPE_TOOLS; art->prefsizex = 58; /* XXX */ art->prefsizey = 50; /* XXX */ diff --git a/source/blender/editors/space_outliner/outliner_edit.c b/source/blender/editors/space_outliner/outliner_edit.c index 738db28a2b6..e449e4a609b 100644 --- a/source/blender/editors/space_outliner/outliner_edit.c +++ b/source/blender/editors/space_outliner/outliner_edit.c @@ -763,7 +763,7 @@ static int outliner_id_copy_tag(SpaceOutliner *space_outliner, ListBase *tree) if (tselem->flag & TSE_SELECTED && ELEM(tselem->type, TSE_SOME_ID, TSE_LAYER_COLLECTION)) { ID *id = tselem->id; if (!(id->tag & LIB_TAG_DOIT)) { - BKE_copybuffer_tag_ID(tselem->id); + BKE_copybuffer_copy_tag_ID(tselem->id); num_ids++; } } @@ -781,7 +781,7 @@ static int outliner_id_copy_exec(bContext *C, wmOperator *op) SpaceOutliner *space_outliner = CTX_wm_space_outliner(C); char str[FILE_MAX]; - BKE_copybuffer_begin(bmain); + BKE_copybuffer_copy_begin(bmain); const int num_ids = outliner_id_copy_tag(space_outliner, &space_outliner->tree); if (num_ids == 0) { @@ -790,7 +790,7 @@ static int outliner_id_copy_exec(bContext *C, wmOperator *op) } BLI_join_dirfile(str, sizeof(str), BKE_tempdir_base(), "copybuffer.blend"); - BKE_copybuffer_save(bmain, str, op->reports); + BKE_copybuffer_copy_end(bmain, str, op->reports); BKE_reportf(op->reports, RPT_INFO, "Copied %d selected data-block(s)", num_ids); diff --git a/source/blender/editors/space_text/text_draw.c b/source/blender/editors/space_text/text_draw.c index b541b65d676..f8d16e396d4 100644 --- a/source/blender/editors/space_text/text_draw.c +++ b/source/blender/editors/space_text/text_draw.c @@ -70,7 +70,7 @@ static void text_draw_context_init(const SpaceText *st, TextDrawContext *tdc) static void text_font_begin(const TextDrawContext *tdc) { - BLF_size(tdc->font_id, tdc->lheight_px, 72); + BLF_size(tdc->font_id, (float)tdc->lheight_px, 72); } static void text_font_end(const TextDrawContext *UNUSED(tdc)) diff --git a/source/blender/editors/space_text/text_ops.c b/source/blender/editors/space_text/text_ops.c index 458a1be0308..3c0ffa29bbd 100644 --- a/source/blender/editors/space_text/text_ops.c +++ b/source/blender/editors/space_text/text_ops.c @@ -86,6 +86,30 @@ static void test_line_start(char c, bool *r_last_state) } /** + * This function receives a character and returns its closing pair if it exists. + * \param character: Character to find the closing pair. + * \return The closing pair of the character if it exists. + */ +static char text_closing_character_pair_get(const char character) +{ + + switch (character) { + case '(': + return ')'; + case '[': + return ']'; + case '{': + return '}'; + case '"': + return '"'; + case '\'': + return '\''; + default: + return 0; + } +} + +/** * This function converts the indentation tabs from a buffer to spaces. * \param in_buf: A pointer to a cstring. * \param tab_size: The size, in spaces, of the tab character. @@ -2403,7 +2427,17 @@ static int text_delete_exec(bContext *C, wmOperator *op) } } } - + if (U.text_flag & USER_TEXT_EDIT_AUTO_CLOSE) { + const char *curr = text->curl->line + text->curc; + if (*curr != '\0') { + const char *prev = BLI_str_find_prev_char_utf8(curr, text->curl->line); + if ((curr != prev) && /* When back-spacing from the start of the line. */ + (*curr == text_closing_character_pair_get(*prev))) { + txt_move_right(text, false); + txt_backspace_char(text); + } + } + } txt_backspace_char(text); } else if (type == DEL_NEXT_WORD) { @@ -3443,6 +3477,12 @@ static int text_insert_exec(bContext *C, wmOperator *op) while (str[i]) { code = BLI_str_utf8_as_unicode_step(str, str_len, &i); done |= txt_add_char(text, code); + if (U.text_flag & USER_TEXT_EDIT_AUTO_CLOSE) { + if (text_closing_character_pair_get(code)) { + done |= txt_add_char(text, text_closing_character_pair_get(code)); + txt_move_left(text, false); + } + } } } diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c index 6b9da431510..48f39f835c5 100644 --- a/source/blender/editors/space_view3d/drawobject.c +++ b/source/blender/editors/space_view3d/drawobject.c @@ -48,58 +48,6 @@ #include "view3d_intern.h" /* bad level include */ -/* OpenGL Circle Drawing - Tables for Optimized Drawing Speed */ -/* 32 values of sin function (still same result!) */ -#define CIRCLE_RESOL 32 - -static const float sinval[CIRCLE_RESOL] = { - 0.00000000, 0.20129852, 0.39435585, 0.57126821, 0.72479278, 0.84864425, 0.93775213, - 0.98846832, 0.99871650, 0.96807711, 0.89780453, 0.79077573, 0.65137248, 0.48530196, - 0.29936312, 0.10116832, -0.10116832, -0.29936312, -0.48530196, -0.65137248, -0.79077573, - -0.89780453, -0.96807711, -0.99871650, -0.98846832, -0.93775213, -0.84864425, -0.72479278, - -0.57126821, -0.39435585, -0.20129852, 0.00000000, -}; - -/* 32 values of cos function (still same result!) */ -static const float cosval[CIRCLE_RESOL] = { - 1.00000000, 0.97952994, 0.91895781, 0.82076344, 0.68896691, 0.52896401, 0.34730525, - 0.15142777, -0.05064916, -0.25065253, -0.44039415, -0.61210598, -0.75875812, -0.87434661, - -0.95413925, -0.99486932, -0.99486932, -0.95413925, -0.87434661, -0.75875812, -0.61210598, - -0.44039415, -0.25065253, -0.05064916, 0.15142777, 0.34730525, 0.52896401, 0.68896691, - 0.82076344, 0.91895781, 0.97952994, 1.00000000, -}; - -static void circball_array_fill(const float verts[CIRCLE_RESOL][3], - const float cent[3], - float rad, - const float tmat[4][4]) -{ - float vx[3], vy[3]; - float *viter = (float *)verts; - - mul_v3_v3fl(vx, tmat[0], rad); - mul_v3_v3fl(vy, tmat[1], rad); - - for (uint a = 0; a < CIRCLE_RESOL; a++, viter += 3) { - viter[0] = cent[0] + sinval[a] * vx[0] + cosval[a] * vy[0]; - viter[1] = cent[1] + sinval[a] * vx[1] + cosval[a] * vy[1]; - viter[2] = cent[2] + sinval[a] * vx[2] + cosval[a] * vy[2]; - } -} - -void imm_drawcircball(const float cent[3], float rad, const float tmat[4][4], uint pos) -{ - float verts[CIRCLE_RESOL][3]; - - circball_array_fill(verts, cent, rad, tmat); - - immBegin(GPU_PRIM_LINE_LOOP, CIRCLE_RESOL); - for (int i = 0; i < CIRCLE_RESOL; i++) { - immVertex3fv(pos, verts[i]); - } - immEnd(); -} - #ifdef VIEW3D_CAMERA_BORDER_HACK uchar view3d_camera_border_hack_col[3]; bool view3d_camera_border_hack_test = false; diff --git a/source/blender/editors/space_view3d/view3d_cursor_snap.c b/source/blender/editors/space_view3d/view3d_cursor_snap.c index bb387adb82e..ac80a70011a 100644 --- a/source/blender/editors/space_view3d/view3d_cursor_snap.c +++ b/source/blender/editors/space_view3d/view3d_cursor_snap.c @@ -95,9 +95,7 @@ typedef struct SnapCursorDataIntern { static SnapCursorDataIntern g_data_intern = { .state_default = {.prevpoint = NULL, - .snap_elem_force = (SCE_SNAP_MODE_VERTEX | SCE_SNAP_MODE_EDGE | - SCE_SNAP_MODE_FACE | SCE_SNAP_MODE_EDGE_PERPENDICULAR | - SCE_SNAP_MODE_EDGE_MIDPOINT), + .snap_elem_force = SCE_SNAP_MODE_GEOM, .plane_axis = 2, .color_point = {255, 255, 255, 255}, .color_line = {255, 255, 255, 128}, @@ -759,7 +757,7 @@ static void v3d_cursor_snap_update(V3DSnapCursorState *state, /** \name Callbacks * \{ */ -static bool v3d_cursor_snap_pool_fn(bContext *C) +static bool v3d_cursor_snap_poll_fn(bContext *C) { if (G.moving) { return false; @@ -898,7 +896,7 @@ static void v3d_cursor_snap_activate(void) } struct wmPaintCursor *pc = WM_paint_cursor_activate( - SPACE_VIEW3D, RGN_TYPE_WINDOW, v3d_cursor_snap_pool_fn, v3d_cursor_snap_draw_fn, NULL); + SPACE_VIEW3D, RGN_TYPE_WINDOW, v3d_cursor_snap_poll_fn, v3d_cursor_snap_draw_fn, NULL); data_intern->handle = pc; } } diff --git a/source/blender/editors/space_view3d/view3d_gizmo_preselect_type.c b/source/blender/editors/space_view3d/view3d_gizmo_preselect_type.c index 07c3b6bd1d8..513fdbecc74 100644 --- a/source/blender/editors/space_view3d/view3d_gizmo_preselect_type.c +++ b/source/blender/editors/space_view3d/view3d_gizmo_preselect_type.c @@ -29,9 +29,11 @@ #include "BLI_math.h" #include "DNA_mesh_types.h" +#include "DNA_view3d_types.h" #include "BKE_context.h" #include "BKE_editmesh.h" +#include "BKE_global.h" #include "BKE_layer.h" #include "DEG_depsgraph.h" @@ -51,6 +53,39 @@ #include "ED_view3d.h" /* -------------------------------------------------------------------- */ +/** \name Shared Internal API + * \{ */ + +/** + * Check if drawing should be performed, clear the pre-selection in the case it's disabled. + * Without this, the gizmo would be visible while transforming. See T92954. + * + * NOTE(@campbellbarton): This is a workaround for the gizmo system, since typically poll + * would be used for this purpose. The problem with using poll is once the gizmo is visible again + * is there is a visible flicker showing the previous location before cursor motion causes the + * pre selection to be updated. While this is only a glitch, it's distracting. + * The gizmo system it's self could support this use case by tracking which gizmos draw and ensure + * gizmos always run #wmGizmoType.test_select before drawing, however pre-selection is already + * outside the scope of what gizmos are meant to be used for, so keep this workaround localized + * to this gizmo type unless this seems worth supporting for more typical use-cases. + * + * Longer term it may be better to use #wmPaintCursor instead of gizmos (as snapping preview does). + */ +static bool gizmo_preselect_poll_for_draw(const bContext *C, wmGizmo *gz) +{ + if (G.moving == false) { + RegionView3D *rv3d = CTX_wm_region_view3d(C); + if (!(rv3d && (rv3d->rflag & RV3D_NAVIGATING))) { + return true; + } + } + ED_view3d_gizmo_mesh_preselect_clear(gz); + return false; +} + +/** \} */ + +/* -------------------------------------------------------------------- */ /** \name Mesh Element (Vert/Edge/Face) Pre-Select Gizmo API * \{ */ @@ -65,8 +100,12 @@ typedef struct MeshElemGizmo3D { struct EditMesh_PreSelElem *psel; } MeshElemGizmo3D; -static void gizmo_preselect_elem_draw(const bContext *UNUSED(C), wmGizmo *gz) +static void gizmo_preselect_elem_draw(const bContext *C, wmGizmo *gz) { + if (!gizmo_preselect_poll_for_draw(C, gz)) { + return; + } + MeshElemGizmo3D *gz_ele = (MeshElemGizmo3D *)gz; if (gz_ele->base_index != -1) { Object *ob = gz_ele->bases[gz_ele->base_index]->object; @@ -292,8 +331,12 @@ typedef struct MeshEdgeRingGizmo3D { struct EditMesh_PreSelEdgeRing *psel; } MeshEdgeRingGizmo3D; -static void gizmo_preselect_edgering_draw(const bContext *UNUSED(C), wmGizmo *gz) +static void gizmo_preselect_edgering_draw(const bContext *C, wmGizmo *gz) { + if (!gizmo_preselect_poll_for_draw(C, gz)) { + return; + } + MeshEdgeRingGizmo3D *gz_ring = (MeshEdgeRingGizmo3D *)gz; if (gz_ring->base_index != -1) { Object *ob = gz_ring->bases[gz_ring->base_index]->object; @@ -504,4 +547,33 @@ void ED_view3d_gizmo_mesh_preselect_get_active(bContext *C, } } } + +void ED_view3d_gizmo_mesh_preselect_clear(wmGizmo *gz) +{ + if (STREQ(gz->type->idname, "GIZMO_GT_mesh_preselect_elem_3d")) { + MeshElemGizmo3D *gz_ele = (MeshElemGizmo3D *)gz; + gz_ele->base_index = -1; + gz_ele->vert_index = -1; + gz_ele->edge_index = -1; + gz_ele->face_index = -1; + } + else if (STREQ(gz->type->idname, "GIZMO_GT_mesh_preselect_edgering_3d")) { + MeshEdgeRingGizmo3D *gz_ele = (MeshEdgeRingGizmo3D *)gz; + gz_ele->base_index = -1; + gz_ele->edge_index = -1; + } + else { + BLI_assert_unreachable(); + } + + const char *prop_ids[] = {"object_index", "vert_index", "edge_index", "face_index"}; + for (int i = 0; i < ARRAY_SIZE(prop_ids); i++) { + PropertyRNA *prop = RNA_struct_find_property(gz->ptr, prop_ids[i]); + if (prop == NULL) { + continue; + } + RNA_property_int_set(gz->ptr, prop, -1); + } +} + /** \} */ diff --git a/source/blender/editors/space_view3d/view3d_gizmo_ruler.c b/source/blender/editors/space_view3d/view3d_gizmo_ruler.c index 34e3b808b50..1082483dcd7 100644 --- a/source/blender/editors/space_view3d/view3d_gizmo_ruler.c +++ b/source/blender/editors/space_view3d/view3d_gizmo_ruler.c @@ -115,8 +115,10 @@ enum { CONSTRAIN_AXIS_Z = 2, }; -/* Constraining modes. - Off / Scene orientation / Global (or Local if Scene orientation is Global) */ +/** + * Constraining modes. + * Off / Scene orientation / Global (or Local if Scene orientation is Global). + */ enum { CONSTRAIN_MODE_OFF = 0, CONSTRAIN_MODE_1 = 1, @@ -163,7 +165,7 @@ typedef struct RulerInfo { typedef struct RulerItem { wmGizmo gz; - /* worldspace coords, middle being optional */ + /** World-space coords, middle being optional. */ float co[3][3]; int flag; @@ -643,7 +645,7 @@ static void gizmo_ruler_draw(const bContext *C, wmGizmo *gz) GPU_line_width(1.0f); BLF_enable(blf_mono_font, BLF_ROTATION); - BLF_size(blf_mono_font, 14 * U.pixelsize, U.dpi); + BLF_size(blf_mono_font, 14.0f * U.pixelsize, U.dpi); BLF_rotation(blf_mono_font, 0.0f); UI_GetThemeColor3ubv(TH_TEXT, color_text); diff --git a/source/blender/editors/space_view3d/view3d_ops.c b/source/blender/editors/space_view3d/view3d_ops.c index eb8c043319c..823aa3b6643 100644 --- a/source/blender/editors/space_view3d/view3d_ops.c +++ b/source/blender/editors/space_view3d/view3d_ops.c @@ -63,19 +63,19 @@ static int view3d_copybuffer_exec(bContext *C, wmOperator *op) char str[FILE_MAX]; int num_copied = 0; - BKE_copybuffer_begin(bmain); + BKE_copybuffer_copy_begin(bmain); /* context, selection, could be generalized */ CTX_DATA_BEGIN (C, Object *, ob, selected_objects) { if ((ob->id.tag & LIB_TAG_DOIT) == 0) { - BKE_copybuffer_tag_ID(&ob->id); + BKE_copybuffer_copy_tag_ID(&ob->id); num_copied++; } } CTX_DATA_END; BLI_join_dirfile(str, sizeof(str), BKE_tempdir_base(), "copybuffer.blend"); - BKE_copybuffer_save(bmain, str, op->reports); + BKE_copybuffer_copy_end(bmain, str, op->reports); BKE_reportf(op->reports, RPT_INFO, "Copied %d selected object(s)", num_copied); diff --git a/source/blender/editors/space_view3d/view3d_placement.c b/source/blender/editors/space_view3d/view3d_placement.c index cecd1765a17..8c1cab6bf14 100644 --- a/source/blender/editors/space_view3d/view3d_placement.c +++ b/source/blender/editors/space_view3d/view3d_placement.c @@ -45,10 +45,6 @@ #include "view3d_intern.h" -#define SNAP_MODE_GEOM \ - (SCE_SNAP_MODE_VERTEX | SCE_SNAP_MODE_EDGE | SCE_SNAP_MODE_FACE | \ - SCE_SNAP_MODE_EDGE_PERPENDICULAR | SCE_SNAP_MODE_EDGE_MIDPOINT) - static const char *view3d_gzgt_placement_id = "VIEW3D_GGT_placement"; /** @@ -1308,7 +1304,7 @@ static int idp_rna_snap_target_get_fn(struct PointerRNA *UNUSED(ptr), } /* Make sure you keep a consistent #snap_mode. */ - snap_state->snap_elem_force = SNAP_MODE_GEOM; + snap_state->snap_elem_force = SCE_SNAP_MODE_GEOM; return PLACE_SNAP_TO_GEOMETRY; } @@ -1319,7 +1315,7 @@ static void idp_rna_snap_target_set_fn(struct PointerRNA *UNUSED(ptr), short snap_mode = 0; /* #toolsettings->snap_mode. */ const enum ePlace_SnapTo snap_to = value; if (snap_to == PLACE_SNAP_TO_GEOMETRY) { - snap_mode = SNAP_MODE_GEOM; + snap_mode = SCE_SNAP_MODE_GEOM; } V3DSnapCursorState *snap_state = ED_view3d_cursor_snap_state_get(); diff --git a/source/blender/editors/space_view3d/view3d_view.c b/source/blender/editors/space_view3d/view3d_view.c index 46a664f10fa..6f0ce6c9326 100644 --- a/source/blender/editors/space_view3d/view3d_view.c +++ b/source/blender/editors/space_view3d/view3d_view.c @@ -1731,9 +1731,9 @@ void ED_view3d_xr_shading_update(wmWindowManager *wm, const View3D *v3d, const S View3DShading *xr_shading = &wm->xr.session_settings.shading; /* Flags that shouldn't be overridden by the 3D View shading. */ int flag_copy = 0; - if (v3d->shading.type != - OB_SOLID) { /* Don't set V3D_SHADING_WORLD_ORIENTATION for solid shading since it results - in distorted lighting when the view matrix has a scale factor. */ + if (v3d->shading.type != OB_SOLID) { + /* Don't set V3D_SHADING_WORLD_ORIENTATION for solid shading since it results in distorted + * lighting when the view matrix has a scale factor. */ flag_copy |= V3D_SHADING_WORLD_ORIENTATION; } diff --git a/source/blender/editors/transform/transform.h b/source/blender/editors/transform/transform.h index 3076b3e207f..d78cd13f8b8 100644 --- a/source/blender/editors/transform/transform.h +++ b/source/blender/editors/transform/transform.h @@ -317,9 +317,9 @@ typedef struct TransSnap { /* Snapped Element Type (currently for objects only). */ char snapElem; /** snapping from this point (in global-space). */ - float snapPoint[3]; - /** to this point (in global-space). */ float snapTarget[3]; + /** to this point (in global-space). */ + float snapPoint[3]; float snapTargetGrid[3]; float snapNormal[3]; char snapNodeBorder; @@ -621,6 +621,12 @@ typedef struct TransInfo { O_SET, } orient_curr; + /** + * All values from `TransInfo.orient[].type` converted into a flag + * to allow quickly checking which orientation types are used. + */ + int orient_type_mask; + short prop_mode; /** Value taken as input, either through mouse coordinates or entered as a parameter. */ @@ -713,7 +719,8 @@ struct wmKeyMap *transform_modal_keymap(struct wmKeyConfig *keyconf); /* transform_gizmo.c */ #define GIZMO_AXIS_LINE_WIDTH 2.0f -bool gimbal_axis(struct Object *ob, float gmat[3][3]); +bool gimbal_axis_pose(struct Object *ob, const struct bPoseChannel *pchan, float gmat[3][3]); +bool gimbal_axis_object(struct Object *ob, float gmat[3][3]); void drawDial3d(const TransInfo *t); /** \} */ diff --git a/source/blender/editors/transform/transform_constraints.c b/source/blender/editors/transform/transform_constraints.c index 23ba335476c..a24491119c6 100644 --- a/source/blender/editors/transform/transform_constraints.c +++ b/source/blender/editors/transform/transform_constraints.c @@ -384,6 +384,29 @@ static void planeProjection(const TransInfo *t, const float in[3], float out[3]) add_v3_v3v3(out, in, vec); } +static short transform_orientation_or_default(const TransInfo *t) +{ + short orientation = t->orient[t->orient_curr].type; + if (orientation == V3D_ORIENT_CUSTOM_MATRIX) { + /* Use the real value of the "orient_type". */ + orientation = t->orient[O_DEFAULT].type; + } + return orientation; +} + +static const float (*transform_object_axismtx_get(const TransInfo *t, + const TransDataContainer *UNUSED(tc), + const TransData *td))[3] +{ + if (transform_orientation_or_default(t) == V3D_ORIENT_GIMBAL) { + BLI_assert(t->orient_type_mask & (1 << V3D_ORIENT_GIMBAL)); + if (t->options & (CTX_POSE_BONE | CTX_OBJECT)) { + return td->ext->axismtx_gimbal; + } + } + return td->axismtx; +} + /** * Generic callback for constant spatial constraints applied to linear motion * @@ -489,7 +512,8 @@ static void applyObjectConstraintVec(const TransInfo *t, copy_v3_v3(out, in); if (t->con.mode & CON_APPLY) { mul_m3_v3(t->spacemtx_inv, out); - mul_m3_v3(td->axismtx, out); + const float(*axismtx)[3] = transform_object_axismtx_get(t, tc, td); + mul_m3_v3(axismtx, out); if (t->flag & T_EDIT) { mul_m3_v3(tc->mat3_unit, out); } @@ -535,7 +559,8 @@ static void applyObjectConstraintSize(const TransInfo *t, float tmat[3][3]; float imat[3][3]; - invert_m3_m3(imat, td->axismtx); + const float(*axismtx)[3] = transform_object_axismtx_get(t, tc, td); + invert_m3_m3(imat, axismtx); if (!(t->con.mode & CON_AXIS0)) { r_smat[0][0] = 1.0f; @@ -551,7 +576,7 @@ static void applyObjectConstraintSize(const TransInfo *t, if (t->flag & T_EDIT) { mul_m3_m3m3(r_smat, tc->mat3_unit, r_smat); } - mul_m3_m3m3(r_smat, td->axismtx, tmat); + mul_m3_m3m3(r_smat, axismtx, tmat); } } @@ -647,7 +672,7 @@ static void applyObjectConstraintRot(const TransInfo *t, axismtx = tmp_axismtx; } else { - axismtx = td->axismtx; + axismtx = transform_object_axismtx_get(t, tc, td); } constraints_rotation_impl(t, axismtx, r_axis, r_angle); @@ -712,17 +737,13 @@ void setLocalConstraint(TransInfo *t, int mode, const char text[]) void setUserConstraint(TransInfo *t, int mode, const char ftext[]) { char text[256]; - short orientation = t->orient[t->orient_curr].type; - if (orientation == V3D_ORIENT_CUSTOM_MATRIX) { - /* Use the real value of the "orient_type". */ - orientation = t->orient[0].type; - } - + const short orientation = transform_orientation_or_default(t); const char *spacename = transform_orientations_spacename_get(t, orientation); BLI_snprintf(text, sizeof(text), ftext, spacename); switch (orientation) { case V3D_ORIENT_LOCAL: + case V3D_ORIENT_GIMBAL: setLocalConstraint(t, mode, text); break; case V3D_ORIENT_NORMAL: @@ -734,7 +755,6 @@ void setUserConstraint(TransInfo *t, int mode, const char ftext[]) case V3D_ORIENT_GLOBAL: case V3D_ORIENT_VIEW: case V3D_ORIENT_CURSOR: - case V3D_ORIENT_GIMBAL: case V3D_ORIENT_CUSTOM_MATRIX: case V3D_ORIENT_CUSTOM: default: { @@ -905,7 +925,7 @@ static void drawObjectConstraint(TransInfo *t) TransData *td = tc->data; for (int i = 0; i < tc->data_len; i++, td++) { float co[3]; - float(*axismtx)[3]; + const float(*axismtx)[3]; if (t->flag & T_PROP_EDIT) { /* we're sorted, so skip the rest */ @@ -937,13 +957,14 @@ static void drawObjectConstraint(TransInfo *t) mul_m3_m3m3(tmp_axismtx, tc->mat3_unit, td->axismtx); axismtx = tmp_axismtx; } - else if (t->options & CTX_POSE_BONE) { - mul_v3_m4v3(co, tc->mat, td->center); - axismtx = td->axismtx; - } else { - copy_v3_v3(co, td->center); - axismtx = td->axismtx; + if (t->options & CTX_POSE_BONE) { + mul_v3_m4v3(co, tc->mat, td->center); + } + else { + copy_v3_v3(co, td->center); + } + axismtx = transform_object_axismtx_get(t, tc, td); } if (t->con.mode & CON_AXIS0) { diff --git a/source/blender/editors/transform/transform_convert_action.c b/source/blender/editors/transform/transform_convert_action.c index a6658ae00a3..24d84bc2de8 100644 --- a/source/blender/editors/transform/transform_convert_action.c +++ b/source/blender/editors/transform/transform_convert_action.c @@ -159,8 +159,11 @@ static void TimeToTransData( copy_v2_v2(td2d->ih2, td2d->h2); /* Setup #TransData. */ - td->loc = time; /* Usually #td2d->loc is used here. But this is for when the original location is - not float[3]. */ + + /* Usually #td2d->loc is used here. + * But this is for when the original location is not float[3]. */ + td->loc = time; + copy_v3_v3(td->iloc, td->loc); td->val = time; td->ival = *(time); diff --git a/source/blender/editors/transform/transform_convert_armature.c b/source/blender/editors/transform/transform_convert_armature.c index 1bbbbc6294e..88790e9645c 100644 --- a/source/blender/editors/transform/transform_convert_armature.c +++ b/source/blender/editors/transform/transform_convert_armature.c @@ -662,6 +662,12 @@ static void add_pose_transdata(TransInfo *t, bPoseChannel *pchan, Object *ob, Tr mul_m3_m3m3(td->axismtx, omat, pmat); normalize_m3(td->axismtx); + if (t->orient_type_mask & (1 << V3D_ORIENT_GIMBAL)) { + if (!gimbal_axis_pose(ob, pchan, td->ext->axismtx_gimbal)) { + copy_m3_m3(td->ext->axismtx_gimbal, td->axismtx); + } + } + if (t->mode == TFM_BONE_ENVELOPE_DIST) { td->loc = NULL; td->val = &bone->dist; diff --git a/source/blender/editors/transform/transform_convert_object.c b/source/blender/editors/transform/transform_convert_object.c index 7e4e0892420..4a8ebf3fc6e 100644 --- a/source/blender/editors/transform/transform_convert_object.c +++ b/source/blender/editors/transform/transform_convert_object.c @@ -181,6 +181,11 @@ static void ObjectToTransData(TransInfo *t, TransData *td, Object *ob) /* axismtx has the real orientation */ transform_orientations_create_from_axis(td->axismtx, UNPACK3(ob->obmat)); + if (t->orient_type_mask & (1 << V3D_ORIENT_GIMBAL)) { + if (!gimbal_axis_object(ob, td->ext->axismtx_gimbal)) { + copy_m3_m3(td->ext->axismtx_gimbal, td->axismtx); + } + } td->con = ob->constraints.first; diff --git a/source/blender/editors/transform/transform_data.h b/source/blender/editors/transform/transform_data.h index 15e40ec466b..6cfceedb389 100644 --- a/source/blender/editors/transform/transform_data.h +++ b/source/blender/editors/transform/transform_data.h @@ -85,6 +85,8 @@ typedef struct TransDataExtension { float isize[3]; /** Object matrix. */ float obmat[4][4]; + /** Use for #V3D_ORIENT_GIMBAL orientation. */ + float axismtx_gimbal[3][3]; /** Use instead of #TransData.smtx, * It is the same but without the #Bone.bone_mat, see #TD_PBONE_LOCAL_MTX_C. */ float l_smtx[3][3]; diff --git a/source/blender/editors/transform/transform_generics.c b/source/blender/editors/transform/transform_generics.c index 8effb82173b..7ff95ebeeae 100644 --- a/source/blender/editors/transform/transform_generics.c +++ b/source/blender/editors/transform/transform_generics.c @@ -512,6 +512,15 @@ void initTransInfo(bContext *C, TransInfo *t, wmOperator *op, const wmEvent *eve } } + t->orient_type_mask = 0; + for (int i = 0; i < 3; i++) { + const int type = t->orient[i].type; + if (type < V3D_ORIENT_CUSTOM_MATRIX) { + BLI_assert(type < 32); + t->orient_type_mask |= (1 << type); + } + } + transform_orientations_current_set(t, (t->con.mode & CON_APPLY) ? 2 : 0); } diff --git a/source/blender/editors/transform/transform_gizmo_3d.c b/source/blender/editors/transform/transform_gizmo_3d.c index e79fdc4890a..6a2353d403f 100644 --- a/source/blender/editors/transform/transform_gizmo_3d.c +++ b/source/blender/editors/transform/transform_gizmo_3d.c @@ -515,7 +515,7 @@ static void protectflag_to_drawflags_pchan(RegionView3D *rv3d, { /* Protect-flags apply to local space in pose mode, so only let them influence axis * visibility if we show the global orientation, otherwise it's confusing. */ - if (orientation_index == V3D_ORIENT_LOCAL) { + if (ELEM(orientation_index, V3D_ORIENT_LOCAL, V3D_ORIENT_GIMBAL)) { protectflag_to_drawflags(pchan->protectflag, &rv3d->twdrawflag); } } @@ -564,72 +564,63 @@ static bool test_rotmode_euler(short rotmode) return (ELEM(rotmode, ROT_MODE_AXISANGLE, ROT_MODE_QUAT)) ? 0 : 1; } -/** - * Return false when no gimbal for selection. - */ -bool gimbal_axis(Object *ob, float gmat[3][3]) +bool gimbal_axis_pose(Object *ob, const bPoseChannel *pchan, float gmat[3][3]) { - if (ob->mode & OB_MODE_POSE) { - bPoseChannel *pchan = BKE_pose_channel_active(ob); - - if (pchan) { - float mat[3][3], tmat[3][3], obmat[3][3]; - if (test_rotmode_euler(pchan->rotmode)) { - eulO_to_gimbal_axis(mat, pchan->eul, pchan->rotmode); - } - else if (pchan->rotmode == ROT_MODE_AXISANGLE) { - axis_angle_to_gimbal_axis(mat, pchan->rotAxis, pchan->rotAngle); - } - else { /* quat */ - return 0; - } - - /* apply bone transformation */ - mul_m3_m3m3(tmat, pchan->bone->bone_mat, mat); + float mat[3][3], tmat[3][3], obmat[3][3]; + if (test_rotmode_euler(pchan->rotmode)) { + eulO_to_gimbal_axis(mat, pchan->eul, pchan->rotmode); + } + else if (pchan->rotmode == ROT_MODE_AXISANGLE) { + axis_angle_to_gimbal_axis(mat, pchan->rotAxis, pchan->rotAngle); + } + else { /* quat */ + return 0; + } - if (pchan->parent) { - float parent_mat[3][3]; + /* apply bone transformation */ + mul_m3_m3m3(tmat, pchan->bone->bone_mat, mat); - copy_m3_m4(parent_mat, - (pchan->bone->flag & BONE_HINGE) ? pchan->parent->bone->arm_mat : - pchan->parent->pose_mat); - mul_m3_m3m3(mat, parent_mat, tmat); + if (pchan->parent) { + float parent_mat[3][3]; - /* needed if object transformation isn't identity */ - copy_m3_m4(obmat, ob->obmat); - mul_m3_m3m3(gmat, obmat, mat); - } - else { - /* needed if object transformation isn't identity */ - copy_m3_m4(obmat, ob->obmat); - mul_m3_m3m3(gmat, obmat, tmat); - } + copy_m3_m4(parent_mat, + (pchan->bone->flag & BONE_HINGE) ? pchan->parent->bone->arm_mat : + pchan->parent->pose_mat); + mul_m3_m3m3(mat, parent_mat, tmat); - normalize_m3(gmat); - return 1; - } + /* needed if object transformation isn't identity */ + copy_m3_m4(obmat, ob->obmat); + mul_m3_m3m3(gmat, obmat, mat); } else { - if (test_rotmode_euler(ob->rotmode)) { - eulO_to_gimbal_axis(gmat, ob->rot, ob->rotmode); - } - else if (ob->rotmode == ROT_MODE_AXISANGLE) { - axis_angle_to_gimbal_axis(gmat, ob->rotAxis, ob->rotAngle); - } - else { /* quat */ - return 0; - } + /* needed if object transformation isn't identity */ + copy_m3_m4(obmat, ob->obmat); + mul_m3_m3m3(gmat, obmat, tmat); + } - if (ob->parent) { - float parent_mat[3][3]; - copy_m3_m4(parent_mat, ob->parent->obmat); - normalize_m3(parent_mat); - mul_m3_m3m3(gmat, parent_mat, gmat); - } - return 1; + normalize_m3(gmat); + return true; +} + +bool gimbal_axis_object(Object *ob, float gmat[3][3]) +{ + if (test_rotmode_euler(ob->rotmode)) { + eulO_to_gimbal_axis(gmat, ob->rot, ob->rotmode); + } + else if (ob->rotmode == ROT_MODE_AXISANGLE) { + axis_angle_to_gimbal_axis(gmat, ob->rotAxis, ob->rotAngle); + } + else { /* quat */ + return 0; } - return 0; + if (ob->parent) { + float parent_mat[3][3]; + copy_m3_m4(parent_mat, ob->parent->obmat); + normalize_m3(parent_mat); + mul_m3_m3m3(gmat, parent_mat, gmat); + } + return 1; } /* centroid, boundbox, of selection */ @@ -1071,9 +1062,13 @@ int ED_transform_calc_gizmo_stats(const bContext *C, } } - /* Protect-flags apply to world space in object mode, so only let them influence axis - * visibility if we show the global orientation, otherwise it's confusing. */ if (orient_index == V3D_ORIENT_GLOBAL) { + /* Protect-flags apply to world space in object mode, + * so only let them influence axis visibility if we show the global orientation, + * otherwise it's confusing. */ + protectflag_to_drawflags(base->object->protectflag & OB_LOCK_LOC, &rv3d->twdrawflag); + } + else if (ELEM(orient_index, V3D_ORIENT_LOCAL, V3D_ORIENT_GIMBAL)) { protectflag_to_drawflags(base->object->protectflag, &rv3d->twdrawflag); } totsel++; diff --git a/source/blender/editors/transform/transform_orientations.c b/source/blender/editors/transform/transform_orientations.c index a1ed66c96a3..61bbe722d71 100644 --- a/source/blender/editors/transform/transform_orientations.c +++ b/source/blender/editors/transform/transform_orientations.c @@ -524,8 +524,19 @@ short ED_transform_calc_orientation_from_type_ex(const Scene *scene, { switch (orientation_index) { case V3D_ORIENT_GIMBAL: { - if (ob && gimbal_axis(ob, r_mat)) { - break; + + if (ob) { + if (ob->mode & OB_MODE_POSE) { + const bPoseChannel *pchan = BKE_pose_channel_active(ob); + if (pchan && gimbal_axis_pose(ob, pchan, r_mat)) { + break; + } + } + else { + if (gimbal_axis_object(ob, r_mat)) { + break; + } + } } /* If not gimbal, fall through to normal. */ ATTR_FALLTHROUGH; diff --git a/source/blender/editors/transform/transform_snap.c b/source/blender/editors/transform/transform_snap.c index 7f27d5fb180..71f26ef0594 100644 --- a/source/blender/editors/transform/transform_snap.c +++ b/source/blender/editors/transform/transform_snap.c @@ -200,7 +200,7 @@ void drawSnapping(const struct bContext *C, TransInfo *t) if (t->spacetype == SPACE_VIEW3D) { bool draw_target = (t->tsnap.status & TARGET_INIT) && - (t->scene->toolsettings->snap_mode & SCE_SNAP_MODE_EDGE_PERPENDICULAR); + (t->tsnap.mode & SCE_SNAP_MODE_EDGE_PERPENDICULAR); if (draw_target || validSnap(t)) { const float *loc_cur = NULL; @@ -483,7 +483,7 @@ void applySnapping(TransInfo *t, float *vec) } if (t->tsnap.project && t->tsnap.mode == SCE_SNAP_MODE_FACE) { - /* The snap has already been resolved for each transdata. */ + /* A similar snap will be applied to each transdata in `applyProject`. */ return; } @@ -574,70 +574,61 @@ static bool bm_face_is_snap_target(BMFace *f, void *UNUSED(user_data)) return true; } -static void initSnappingMode(TransInfo *t) +static short snap_mode_from_scene(TransInfo *t) { ToolSettings *ts = t->settings; - /* All obedit types will match. */ - const int obedit_type = t->obedit_type; - ViewLayer *view_layer = t->view_layer; - Base *base_act = view_layer->basact; + short r_snap_mode = SCE_SNAP_MODE_INCREMENT; if (t->spacetype == SPACE_NODE) { - /* force project off when not supported */ - t->tsnap.project = 0; - - t->tsnap.mode = ts->snap_node_mode; + r_snap_mode = ts->snap_node_mode; } else if (t->spacetype == SPACE_IMAGE) { - /* force project off when not supported */ - t->tsnap.project = 0; - - t->tsnap.mode = ts->snap_uv_mode; - if ((t->tsnap.mode & SCE_SNAP_MODE_INCREMENT) && (ts->snap_uv_flag & SCE_SNAP_ABS_GRID) && + r_snap_mode = ts->snap_uv_mode; + if ((r_snap_mode & SCE_SNAP_MODE_INCREMENT) && (ts->snap_uv_flag & SCE_SNAP_ABS_GRID) && (t->mode == TFM_TRANSLATION)) { - t->tsnap.mode &= ~SCE_SNAP_MODE_INCREMENT; - t->tsnap.mode |= SCE_SNAP_MODE_GRID; + r_snap_mode &= ~SCE_SNAP_MODE_INCREMENT; + r_snap_mode |= SCE_SNAP_MODE_GRID; } } else if (t->spacetype == SPACE_SEQ) { - t->tsnap.mode = SEQ_tool_settings_snap_mode_get(t->scene); + r_snap_mode = SEQ_tool_settings_snap_mode_get(t->scene); } else if (ELEM(t->spacetype, SPACE_VIEW3D, SPACE_IMAGE) && !(t->options & CTX_CAMERA)) { - /* force project off when not supported */ - if ((ts->snap_mode & SCE_SNAP_MODE_FACE) == 0) { - t->tsnap.project = 0; - } - - t->tsnap.mode = ts->snap_mode; - if ((t->tsnap.mode & SCE_SNAP_MODE_INCREMENT) && (ts->snap_flag & SCE_SNAP_ABS_GRID) && - (t->mode == TFM_TRANSLATION)) { - /* Special case in which snap to increments is transformed to snap to grid. */ - t->tsnap.mode &= ~SCE_SNAP_MODE_INCREMENT; - t->tsnap.mode |= SCE_SNAP_MODE_GRID; + /* All obedit types will match. */ + const int obedit_type = t->obedit_type; + if ((t->options & (CTX_GPENCIL_STROKES | CTX_CURSOR | CTX_OBMODE_XFORM_OBDATA)) || + ELEM(obedit_type, OB_MESH, OB_ARMATURE, OB_CURVE, OB_LATTICE, OB_MBALL, -1)) { + r_snap_mode = ts->snap_mode; + if ((r_snap_mode & SCE_SNAP_MODE_INCREMENT) && (ts->snap_flag & SCE_SNAP_ABS_GRID) && + (t->mode == TFM_TRANSLATION)) { + /* Special case in which snap to increments is transformed to snap to grid. */ + r_snap_mode &= ~SCE_SNAP_MODE_INCREMENT; + r_snap_mode |= SCE_SNAP_MODE_GRID; + } } } else if (ELEM(t->spacetype, SPACE_ACTION, SPACE_NLA)) { /* No incremental snapping. */ - t->tsnap.mode = 0; - } - else { - /* Fallback. */ - t->tsnap.mode = SCE_SNAP_MODE_INCREMENT; + r_snap_mode = 0; } - if (ELEM(t->spacetype, SPACE_VIEW3D, SPACE_IMAGE) && !(t->options & CTX_CAMERA)) { - /* Only 3D view or UV. */ - /* Not with camera selected in camera view. */ + return r_snap_mode; +} - setSnappingCallback(t); +static short snap_select_type_get(TransInfo *t) +{ + short r_snap_select = SNAP_ALL; + ViewLayer *view_layer = t->view_layer; + Base *base_act = view_layer->basact; + if (ELEM(t->spacetype, SPACE_VIEW3D, SPACE_IMAGE) && !(t->options & CTX_CAMERA)) { + const int obedit_type = t->obedit_type; if (t->options & (CTX_GPENCIL_STROKES | CTX_CURSOR | CTX_OBMODE_XFORM_OBDATA)) { /* In "Edit Strokes" mode, * snap tool can perform snap to selected or active objects (see T49632) * TODO: perform self snap in gpencil_strokes. * * When we're moving the origins, allow snapping onto our own geometry (see T69132). */ - t->tsnap.modeSelect = SNAP_ALL; } else if ((obedit_type != -1) && ELEM(obedit_type, OB_MESH, OB_ARMATURE, OB_CURVE, OB_LATTICE, OB_MBALL)) { @@ -646,29 +637,44 @@ static void initSnappingMode(TransInfo *t) if ((obedit_type == OB_MESH) && (t->flag & T_PROP_EDIT)) { /* Exclude editmesh if using proportional edit */ - t->tsnap.modeSelect = SNAP_NOT_ACTIVE; + r_snap_select = SNAP_NOT_ACTIVE; } - else { - t->tsnap.modeSelect = t->tsnap.snap_self ? SNAP_ALL : SNAP_NOT_ACTIVE; + else if (!t->tsnap.snap_self) { + r_snap_select = SNAP_NOT_ACTIVE; } } else if ((obedit_type == -1) && base_act && base_act->object && (base_act->object->mode & OB_MODE_PARTICLE_EDIT)) { /* Particles edit mode. */ - t->tsnap.modeSelect = SNAP_ALL; } else if (obedit_type == -1) { /* Object mode */ - t->tsnap.modeSelect = SNAP_NOT_SELECTED; - } - else { - /* Increment if snap is not possible */ - t->tsnap.mode = SCE_SNAP_MODE_INCREMENT; + r_snap_select = SNAP_NOT_SELECTED; } } else if (ELEM(t->spacetype, SPACE_NODE, SPACE_SEQ)) { - setSnappingCallback(t); - t->tsnap.modeSelect = SNAP_NOT_SELECTED; + r_snap_select = SNAP_NOT_SELECTED; + } + + return r_snap_select; +} + +static void initSnappingMode(TransInfo *t) +{ + ToolSettings *ts = t->settings; + t->tsnap.mode = snap_mode_from_scene(t); + t->tsnap.modeSelect = snap_select_type_get(t); + + if ((t->spacetype != SPACE_VIEW3D) || !(ts->snap_mode & SCE_SNAP_MODE_FACE)) { + /* Force project off when not supported. */ + t->tsnap.project = 0; + } + + if (ELEM(t->spacetype, SPACE_VIEW3D, SPACE_IMAGE, SPACE_NODE, SPACE_SEQ)) { + /* Not with camera selected in camera view. */ + if (!(t->options & CTX_CAMERA)) { + setSnappingCallback(t); + } } if (t->spacetype == SPACE_VIEW3D) { @@ -918,8 +924,7 @@ static void snap_calc_view3d_fn(TransInfo *t, float *UNUSED(vec)) mval[0] = t->mval[0]; mval[1] = t->mval[1]; - if (t->tsnap.mode & (SCE_SNAP_MODE_VERTEX | SCE_SNAP_MODE_EDGE | SCE_SNAP_MODE_FACE | - SCE_SNAP_MODE_EDGE_MIDPOINT | SCE_SNAP_MODE_EDGE_PERPENDICULAR)) { + if (t->tsnap.mode & SCE_SNAP_MODE_GEOM) { zero_v3(no); /* objects won't set this */ snap_elem = snapObjectsTransform(t, mval, &dist_px, loc, no); found = snap_elem != 0; @@ -1249,7 +1254,7 @@ short snapObjectsTransform( t->depsgraph, t->region, t->view, - t->settings->snap_mode, + t->tsnap.mode, &(const struct SnapObjectParams){ .snap_select = t->tsnap.modeSelect, .edit_mode_type = (t->flag & T_EDIT) != 0 ? SNAP_GEOM_EDIT : SNAP_GEOM_FINAL, diff --git a/source/blender/editors/transform/transform_snap_object.c b/source/blender/editors/transform/transform_snap_object.c index 3254d56d795..4b981e763f1 100644 --- a/source/blender/editors/transform/transform_snap_object.c +++ b/source/blender/editors/transform/transform_snap_object.c @@ -125,6 +125,8 @@ struct SnapObjectContext { const ARegion *region; const View3D *v3d; + const struct SnapObjectParams *params; + float mval[2]; float pmat[4][4]; /* perspective matrix */ float win_size[2]; /* win x and y */ @@ -444,8 +446,6 @@ static SnapObjectData *snap_object_data_editmesh_get(SnapObjectContext *sctx, typedef void (*IterSnapObjsCallback)(SnapObjectContext *sctx, Object *ob_eval, float obmat[4][4], - eSnapEditType edit_mode_type, - bool use_backface_culling, bool is_object_active, void *data); @@ -453,20 +453,16 @@ typedef void (*IterSnapObjsCallback)(SnapObjectContext *sctx, * Walks through all objects in the scene to create the list of objects to snap. */ static void iter_snap_objects(SnapObjectContext *sctx, - const struct SnapObjectParams *params, IterSnapObjsCallback sob_callback, void *data) { ViewLayer *view_layer = DEG_get_input_view_layer(sctx->runtime.depsgraph); - const eSnapSelect snap_select = params->snap_select; - const eSnapEditType edit_mode_type = params->edit_mode_type; - const bool use_backface_culling = params->use_backface_culling; + const eSnapSelect snap_select = sctx->runtime.params->snap_select; Base *base_act = view_layer->basact; if (snap_select == SNAP_ONLY_ACTIVE) { Object *obj_eval = DEG_get_evaluated_object(sctx->runtime.depsgraph, base_act->object); - sob_callback( - sctx, obj_eval, obj_eval->obmat, edit_mode_type, use_backface_culling, true, data); + sob_callback(sctx, obj_eval, obj_eval->obmat, true, data); return; } @@ -475,7 +471,7 @@ static void iter_snap_objects(SnapObjectContext *sctx, continue; } - if (base->flag_legacy & BA_TRANSFORM_LOCKED_IN_PLACE) { + if ((snap_select == SNAP_ALL) || (base->flag_legacy & BA_TRANSFORM_LOCKED_IN_PLACE)) { /* pass */ } else if (base->flag_legacy & BA_SNAP_FIX_DEPS_FIASCO) { @@ -483,13 +479,13 @@ static void iter_snap_objects(SnapObjectContext *sctx, } const bool is_object_active = (base == base_act); - if (snap_select == SNAP_NOT_SELECTED) { - if ((base->flag & BASE_SELECTED) || (base->flag_legacy & BA_WAS_SEL)) { + if (snap_select == SNAP_NOT_ACTIVE) { + if (is_object_active) { continue; } } - else if (snap_select == SNAP_NOT_ACTIVE) { - if (is_object_active) { + else if (snap_select == SNAP_NOT_SELECTED) { + if ((base->flag & BASE_SELECTED) || (base->flag_legacy & BA_WAS_SEL)) { continue; } } @@ -504,24 +500,12 @@ static void iter_snap_objects(SnapObjectContext *sctx, ListBase *lb = object_duplilist(sctx->runtime.depsgraph, sctx->scene, obj_eval); for (DupliObject *dupli_ob = lb->first; dupli_ob; dupli_ob = dupli_ob->next) { BLI_assert(DEG_is_evaluated_object(dupli_ob->ob)); - sob_callback(sctx, - dupli_ob->ob, - dupli_ob->mat, - edit_mode_type, - use_backface_culling, - is_object_active, - data); + sob_callback(sctx, dupli_ob->ob, dupli_ob->mat, is_object_active, data); } free_object_duplilist(lb); } - sob_callback(sctx, - obj_eval, - obj_eval->obmat, - edit_mode_type, - use_backface_culling, - is_object_active, - data); + sob_callback(sctx, obj_eval, obj_eval->obmat, is_object_active, data); } } @@ -597,15 +581,15 @@ static void raycast_all_cb(void *userdata, int index, const BVHTreeRay *ray, BVH struct RayCastAll_Data *data = userdata; data->raycast_callback(data->bvhdata, index, ray, hit); if (hit->index != -1) { - /* get all values in worldspace */ + /* Get all values in world-space. */ float location[3], normal[3]; float depth; - /* worldspace location */ + /* World-space location. */ mul_v3_m4v3(location, (float(*)[4])data->obmat, hit->co); depth = (hit->dist + data->len_diff) / data->local_scale; - /* worldspace normal */ + /* World-space normal. */ copy_v3_v3(normal, hit->no); mul_m3_v3((float(*)[3])data->timat, normal); normalize_v3(normal); @@ -688,7 +672,6 @@ static bool raycastMesh(SnapObjectContext *sctx, const float obmat[4][4], const uint ob_index, bool use_hide, - bool use_backface_culling, /* read/write args */ float *ray_depth, /* return args */ @@ -790,8 +773,9 @@ static bool raycastMesh(SnapObjectContext *sctx, ray_normal_local, 0.0f, &hit, - use_backface_culling ? mesh_looptri_raycast_backface_culling_cb : - treedata->raycast_callback, + sctx->runtime.params->use_backface_culling ? + mesh_looptri_raycast_backface_culling_cb : + treedata->raycast_callback, treedata) != -1) { hit.dist += len_diff; hit.dist /= local_scale; @@ -799,7 +783,7 @@ static bool raycastMesh(SnapObjectContext *sctx, *ray_depth = hit.dist; copy_v3_v3(r_loc, hit.co); - /* back to worldspace */ + /* Back to world-space. */ mul_m4_v3(obmat, r_loc); if (r_no) { @@ -827,7 +811,6 @@ static bool raycastEditMesh(SnapObjectContext *sctx, BMEditMesh *em, const float obmat[4][4], const uint ob_index, - bool use_backface_culling, /* read/write args */ float *ray_depth, /* return args */ @@ -960,8 +943,9 @@ static bool raycastEditMesh(SnapObjectContext *sctx, ray_normal_local, 0.0f, &hit, - use_backface_culling ? editmesh_looptri_raycast_backface_culling_cb : - treedata->raycast_callback, + sctx->runtime.params->use_backface_culling ? + editmesh_looptri_raycast_backface_culling_cb : + treedata->raycast_callback, treedata) != -1) { hit.dist += len_diff; hit.dist /= local_scale; @@ -969,7 +953,7 @@ static bool raycastEditMesh(SnapObjectContext *sctx, *ray_depth = hit.dist; copy_v3_v3(r_loc, hit.co); - /* back to worldspace */ + /* Back to world-space. */ mul_m4_v3(obmat, r_loc); if (r_no) { @@ -1014,13 +998,8 @@ struct RaycastObjUserData { * * \note Duplicate args here are documented at #snapObjectsRay */ -static void raycast_obj_fn(SnapObjectContext *sctx, - Object *ob_eval, - float obmat[4][4], - eSnapEditType edit_mode_type, - bool use_backface_culling, - bool is_object_active, - void *data) +static void raycast_obj_fn( + SnapObjectContext *sctx, Object *ob_eval, float obmat[4][4], bool is_object_active, void *data) { struct RaycastObjUserData *dt = data; const uint ob_index = dt->ob_index++; @@ -1039,6 +1018,7 @@ static void raycast_obj_fn(SnapObjectContext *sctx, switch (ob_eval->type) { case OB_MESH: { + const eSnapEditType edit_mode_type = sctx->runtime.params->edit_mode_type; bool use_hide = false; Mesh *me_eval = mesh_for_snap(ob_eval, edit_mode_type, &use_hide); if (me_eval == NULL) { @@ -1051,7 +1031,6 @@ static void raycast_obj_fn(SnapObjectContext *sctx, em_orig, obmat, ob_index, - use_backface_culling, ray_depth, dt->r_loc, dt->r_no, @@ -1067,7 +1046,6 @@ static void raycast_obj_fn(SnapObjectContext *sctx, obmat, ob_index, use_hide, - use_backface_culling, ray_depth, dt->r_loc, dt->r_no, @@ -1089,7 +1067,6 @@ static void raycast_obj_fn(SnapObjectContext *sctx, obmat, ob_index, false, - use_backface_culling, ray_depth, dt->r_loc, dt->r_no, @@ -1119,7 +1096,6 @@ static void raycast_obj_fn(SnapObjectContext *sctx, * Walks through all objects in the scene to find the `hit` on object surface. * * \param sctx: Snap context to store data. - * \param params: Snapping behavior. * * Read/Write Args * --------------- @@ -1139,9 +1115,6 @@ static void raycast_obj_fn(SnapObjectContext *sctx, * \param r_hit_list: List of #SnapObjectHitDepth (caller must free). */ static bool raycastObjects(SnapObjectContext *sctx, - Depsgraph *depsgraph, - const View3D *v3d, - const struct SnapObjectParams *params, const float ray_start[3], const float ray_dir[3], /* read/write args */ @@ -1156,6 +1129,8 @@ static bool raycastObjects(SnapObjectContext *sctx, float r_obmat[4][4], ListBase *r_hit_list) { + const struct SnapObjectParams *params = sctx->runtime.params; + const View3D *v3d = sctx->runtime.v3d; if (params->use_occlusion_test && v3d && XRAY_FLAG_ENABLED(v3d)) { /* General testing of occlusion geometry is disabled if the snap is not intended for the edit * cage. */ @@ -1164,9 +1139,6 @@ static bool raycastObjects(SnapObjectContext *sctx, } } - sctx->runtime.depsgraph = depsgraph; - sctx->runtime.v3d = v3d; - struct RaycastObjUserData data = { .ray_start = ray_start, .ray_dir = ray_dir, @@ -1182,7 +1154,7 @@ static bool raycastObjects(SnapObjectContext *sctx, .ret = false, }; - iter_snap_objects(sctx, params, raycast_obj_fn, &data); + iter_snap_objects(sctx, raycast_obj_fn, &data); return data.ret; } @@ -1561,7 +1533,6 @@ static void cb_snap_tri_verts(void *userdata, static short snap_mesh_polygon(SnapObjectContext *sctx, Object *ob_eval, const float obmat[4][4], - bool use_backface_culling, /* read/write args */ float *dist_px, /* return args */ @@ -1593,8 +1564,10 @@ static short snap_mesh_polygon(SnapObjectContext *sctx, BLI_assert(sod != NULL); Nearest2dUserData nearest2d; - nearest2d_data_init( - sod, sctx->runtime.view_proj == VIEW_PROJ_PERSP, use_backface_culling, &nearest2d); + nearest2d_data_init(sod, + sctx->runtime.view_proj == VIEW_PROJ_PERSP, + sctx->runtime.params->use_backface_culling, + &nearest2d); if (sod->type == SNAP_MESH) { BVHTreeFromMesh *treedata = &sod->treedata_mesh; @@ -1688,7 +1661,6 @@ static short snap_mesh_edge_verts_mixed(SnapObjectContext *sctx, const float obmat[4][4], float original_dist_px, const float prev_co[3], - bool use_backface_culling, /* read/write args */ float *dist_px, /* return args */ @@ -1706,8 +1678,10 @@ static short snap_mesh_edge_verts_mixed(SnapObjectContext *sctx, BLI_assert(sod != NULL); Nearest2dUserData nearest2d; - nearest2d_data_init( - sod, sctx->runtime.view_proj == VIEW_PROJ_PERSP, use_backface_culling, &nearest2d); + nearest2d_data_init(sod, + sctx->runtime.view_proj == VIEW_PROJ_PERSP, + sctx->runtime.params->use_backface_culling, + &nearest2d); int vindex[2]; nearest2d.get_edge_verts_index(*r_index, nearest2d.userdata, vindex); @@ -1875,74 +1849,38 @@ static short snapArmature(SnapObjectContext *sctx, mul_v4_m4v4(clip_planes_local[i], tobmat, sctx->runtime.clip_plane[i]); } + const eSnapSelect snap_select = sctx->runtime.params->snap_select; bool is_persp = sctx->runtime.view_proj == VIEW_PROJ_PERSP; bArmature *arm = ob_eval->data; if (arm->edbo) { LISTBASE_FOREACH (EditBone *, eBone, arm->edbo) { if (eBone->layer & arm->layer) { - /* skip hidden or moving (selected) bones */ - if ((eBone->flag & (BONE_HIDDEN_A | BONE_ROOTSEL | BONE_TIPSEL)) == 0) { - bool has_vert_snap = false; - - if (sctx->runtime.snap_to_flag & SCE_SNAP_MODE_VERTEX) { - has_vert_snap = test_projected_vert_dist(&neasrest_precalc, - clip_planes_local, - sctx->runtime.clip_plane_len, - is_persp, - eBone->head, - &dist_px_sq, - r_loc); - has_vert_snap |= test_projected_vert_dist(&neasrest_precalc, - clip_planes_local, - sctx->runtime.clip_plane_len, - is_persp, - eBone->tail, - &dist_px_sq, - r_loc); - - if (has_vert_snap) { - retval = SCE_SNAP_MODE_VERTEX; - } - } - if (!has_vert_snap && sctx->runtime.snap_to_flag & SCE_SNAP_MODE_EDGE) { - if (test_projected_edge_dist(&neasrest_precalc, - clip_planes_local, - sctx->runtime.clip_plane_len, - is_persp, - eBone->head, - eBone->tail, - &dist_px_sq, - r_loc)) { - retval = SCE_SNAP_MODE_EDGE; - } - } + if (eBone->flag & BONE_HIDDEN_A) { + /* Skip hidden bones. */ + continue; + } + + const bool is_selected = (eBone->flag & (BONE_ROOTSEL | BONE_TIPSEL)) != 0; + if (is_selected && snap_select == SNAP_NOT_SELECTED) { + continue; } - } - } - } - else if (ob_eval->pose && ob_eval->pose->chanbase.first) { - LISTBASE_FOREACH (bPoseChannel *, pchan, &ob_eval->pose->chanbase) { - Bone *bone = pchan->bone; - /* skip hidden bones */ - if (bone && !(bone->flag & (BONE_HIDDEN_P | BONE_HIDDEN_PG))) { bool has_vert_snap = false; - const float *head_vec = pchan->pose_head; - const float *tail_vec = pchan->pose_tail; if (sctx->runtime.snap_to_flag & SCE_SNAP_MODE_VERTEX) { has_vert_snap = test_projected_vert_dist(&neasrest_precalc, clip_planes_local, sctx->runtime.clip_plane_len, is_persp, - head_vec, + eBone->head, &dist_px_sq, r_loc); has_vert_snap |= test_projected_vert_dist(&neasrest_precalc, clip_planes_local, sctx->runtime.clip_plane_len, is_persp, - tail_vec, + eBone->tail, + &dist_px_sq, r_loc); @@ -1955,8 +1893,8 @@ static short snapArmature(SnapObjectContext *sctx, clip_planes_local, sctx->runtime.clip_plane_len, is_persp, - head_vec, - tail_vec, + eBone->head, + eBone->tail, &dist_px_sq, r_loc)) { retval = SCE_SNAP_MODE_EDGE; @@ -1965,6 +1903,51 @@ static short snapArmature(SnapObjectContext *sctx, } } } + else if (ob_eval->pose && ob_eval->pose->chanbase.first) { + LISTBASE_FOREACH (bPoseChannel *, pchan, &ob_eval->pose->chanbase) { + Bone *bone = pchan->bone; + /* skip hidden bones */ + if (!bone || (bone->flag & (BONE_HIDDEN_P | BONE_HIDDEN_PG))) { + continue; + } + bool has_vert_snap = false; + const float *head_vec = pchan->pose_head; + const float *tail_vec = pchan->pose_tail; + + if (sctx->runtime.snap_to_flag & SCE_SNAP_MODE_VERTEX) { + has_vert_snap = test_projected_vert_dist(&neasrest_precalc, + clip_planes_local, + sctx->runtime.clip_plane_len, + is_persp, + head_vec, + &dist_px_sq, + r_loc); + has_vert_snap |= test_projected_vert_dist(&neasrest_precalc, + clip_planes_local, + sctx->runtime.clip_plane_len, + is_persp, + tail_vec, + &dist_px_sq, + r_loc); + + if (has_vert_snap) { + retval = SCE_SNAP_MODE_VERTEX; + } + } + if (!has_vert_snap && sctx->runtime.snap_to_flag & SCE_SNAP_MODE_EDGE) { + if (test_projected_edge_dist(&neasrest_precalc, + clip_planes_local, + sctx->runtime.clip_plane_len, + is_persp, + head_vec, + tail_vec, + &dist_px_sq, + r_loc)) { + retval = SCE_SNAP_MODE_EDGE; + } + } + } + } if (retval) { *dist_px = sqrtf(dist_px_sq); @@ -1982,7 +1965,6 @@ static short snapArmature(SnapObjectContext *sctx, static short snapCurve(SnapObjectContext *sctx, Object *ob_eval, const float obmat[4][4], - bool use_obedit, /* read/write args */ float *dist_px, /* return args */ @@ -2007,7 +1989,7 @@ static short snapCurve(SnapObjectContext *sctx, dist_squared_to_projected_aabb_precalc( &neasrest_precalc, lpmat, sctx->runtime.win_size, sctx->runtime.mval); - use_obedit = use_obedit && BKE_object_is_in_editmode(ob_eval); + const bool use_obedit = BKE_object_is_in_editmode(ob_eval); if (use_obedit == false) { /* Test BoundBox */ @@ -2040,14 +2022,20 @@ static short snapCurve(SnapObjectContext *sctx, } bool is_persp = sctx->runtime.view_proj == VIEW_PROJ_PERSP; + bool skip_selected = sctx->runtime.params->snap_select == SNAP_NOT_SELECTED; for (Nurb *nu = (use_obedit ? cu->editnurb->nurbs.first : cu->nurb.first); nu; nu = nu->next) { for (int u = 0; u < nu->pntsu; u++) { if (sctx->runtime.snap_to_flag & SCE_SNAP_MODE_VERTEX) { if (use_obedit) { if (nu->bezt) { - /* don't snap to selected (moving) or hidden */ - if (nu->bezt[u].f2 & SELECT || nu->bezt[u].hide != 0) { + if (nu->bezt[u].hide) { + /* Skip hidden. */ + continue; + } + + bool is_selected = (nu->bezt[u].f2 & SELECT) != 0; + if (is_selected && skip_selected) { continue; } has_snap |= test_projected_vert_dist(&neasrest_precalc, @@ -2059,8 +2047,9 @@ static short snapCurve(SnapObjectContext *sctx, r_loc); /* Don't snap if handle is selected (moving), * or if it is aligning to a moving handle. */ - if (!(nu->bezt[u].f1 & SELECT) && - !(nu->bezt[u].h1 & HD_ALIGN && nu->bezt[u].f3 & SELECT)) { + is_selected = (!(nu->bezt[u].f1 & SELECT) && + !(nu->bezt[u].h1 & HD_ALIGN && nu->bezt[u].f3 & SELECT)) != 0; + if (!(is_selected && skip_selected)) { has_snap |= test_projected_vert_dist(&neasrest_precalc, clip_planes_local, clip_plane_len, @@ -2069,8 +2058,10 @@ static short snapCurve(SnapObjectContext *sctx, &dist_px_sq, r_loc); } - if (!(nu->bezt[u].f3 & SELECT) && - !(nu->bezt[u].h2 & HD_ALIGN && nu->bezt[u].f1 & SELECT)) { + + is_selected = (!(nu->bezt[u].f3 & SELECT) && + !(nu->bezt[u].h2 & HD_ALIGN && nu->bezt[u].f1 & SELECT)) != 0; + if (!(is_selected && skip_selected)) { has_snap |= test_projected_vert_dist(&neasrest_precalc, clip_planes_local, clip_plane_len, @@ -2081,10 +2072,16 @@ static short snapCurve(SnapObjectContext *sctx, } } else { - /* don't snap to selected (moving) or hidden */ - if (nu->bp[u].f1 & SELECT || nu->bp[u].hide != 0) { + if (nu->bp[u].hide) { + /* Skip hidden. */ continue; } + + bool is_selected = (nu->bp[u].f1 & SELECT) != 0; + if (is_selected && skip_selected) { + continue; + } + has_snap |= test_projected_vert_dist(&neasrest_precalc, clip_planes_local, clip_plane_len, @@ -2291,7 +2288,6 @@ static short snapMesh(SnapObjectContext *sctx, Mesh *me_eval, const float obmat[4][4], bool use_hide, - bool use_backface_culling, /* read/write args */ float *dist_px, /* return args */ @@ -2362,8 +2358,10 @@ static short snapMesh(SnapObjectContext *sctx, } Nearest2dUserData nearest2d; - nearest2d_data_init( - sod, sctx->runtime.view_proj == VIEW_PROJ_PERSP, use_backface_culling, &nearest2d); + nearest2d_data_init(sod, + sctx->runtime.view_proj == VIEW_PROJ_PERSP, + sctx->runtime.params->use_backface_culling, + &nearest2d); BVHTreeNearest nearest = { .index = -1, @@ -2481,7 +2479,6 @@ static short snapEditMesh(SnapObjectContext *sctx, Object *ob_eval, BMEditMesh *em, const float obmat[4][4], - bool use_backface_culling, /* read/write args */ float *dist_px, /* return args */ @@ -2582,8 +2579,10 @@ static short snapEditMesh(SnapObjectContext *sctx, } Nearest2dUserData nearest2d; - nearest2d_data_init( - sod, sctx->runtime.view_proj == VIEW_PROJ_PERSP, use_backface_culling, &nearest2d); + nearest2d_data_init(sod, + sctx->runtime.view_proj == VIEW_PROJ_PERSP, + sctx->runtime.params->use_backface_culling, + &nearest2d); BVHTreeNearest nearest = { .index = -1, @@ -2678,8 +2677,6 @@ struct SnapObjUserData { static void snap_obj_fn(SnapObjectContext *sctx, Object *ob_eval, float obmat[4][4], - eSnapEditType edit_mode_type, - bool use_backface_culling, bool UNUSED(is_object_active), void *data) { @@ -2688,20 +2685,14 @@ static void snap_obj_fn(SnapObjectContext *sctx, switch (ob_eval->type) { case OB_MESH: { + const eSnapEditType edit_mode_type = sctx->runtime.params->edit_mode_type; bool use_hide; Mesh *me_eval = mesh_for_snap(ob_eval, edit_mode_type, &use_hide); if (me_eval == NULL) { /* Operators only update the editmesh looptris of the original mesh. */ BMEditMesh *em_orig = BKE_editmesh_from_object(DEG_get_original_object(ob_eval)); - retval = snapEditMesh(sctx, - ob_eval, - em_orig, - obmat, - use_backface_culling, - dt->dist_px, - dt->r_loc, - dt->r_no, - dt->r_index); + retval = snapEditMesh( + sctx, ob_eval, em_orig, obmat, dt->dist_px, dt->r_loc, dt->r_no, dt->r_index); break; } if (ob_eval->dt == OB_BOUNDBOX) { @@ -2709,45 +2700,22 @@ static void snap_obj_fn(SnapObjectContext *sctx, return; } - retval = snapMesh(sctx, - ob_eval, - me_eval, - obmat, - use_hide, - use_backface_culling, - dt->dist_px, - dt->r_loc, - dt->r_no, - dt->r_index); + retval = snapMesh( + sctx, ob_eval, me_eval, obmat, use_hide, dt->dist_px, dt->r_loc, dt->r_no, dt->r_index); break; } case OB_ARMATURE: retval = snapArmature(sctx, ob_eval, obmat, dt->dist_px, dt->r_loc, dt->r_no, dt->r_index); break; case OB_CURVE: - retval = snapCurve(sctx, - ob_eval, - obmat, - edit_mode_type == SNAP_GEOM_EDIT, - dt->dist_px, - dt->r_loc, - dt->r_no, - dt->r_index); + retval = snapCurve(sctx, ob_eval, obmat, dt->dist_px, dt->r_loc, dt->r_no, dt->r_index); break; /* Use ATTR_FALLTHROUGH if we want to snap to the generated mesh. */ case OB_SURF: case OB_FONT: { Mesh *mesh_eval = BKE_object_get_evaluated_mesh(ob_eval); if (mesh_eval) { - retval |= snapMesh(sctx, - ob_eval, - mesh_eval, - obmat, - false, - use_backface_culling, - dt->dist_px, - dt->r_loc, - dt->r_no, - dt->r_index); + retval |= snapMesh( + sctx, ob_eval, mesh_eval, obmat, false, dt->dist_px, dt->r_loc, dt->r_no, dt->r_index); } break; } @@ -2780,8 +2748,6 @@ static void snap_obj_fn(SnapObjectContext *sctx, * Walks through all objects in the scene to find the closest snap element ray. * * \param sctx: Snap context to store data. - * \param snapdata: struct generated in `get_snapdata`. - * \param params: Parameters for control snap behavior. * * Read/Write Args * --------------- @@ -2799,7 +2765,6 @@ static void snap_obj_fn(SnapObjectContext *sctx, * \param r_obmat: Object matrix (may not be #Object.obmat with dupli-instances). */ static short snapObjectsRay(SnapObjectContext *sctx, - const struct SnapObjectParams *params, /* read/write args */ /* Parameters below cannot be const, because they are assigned to a * non-const variable (readability-non-const-parameter). */ @@ -2821,7 +2786,7 @@ static short snapObjectsRay(SnapObjectContext *sctx, .ret = 0, }; - iter_snap_objects(sctx, params, snap_obj_fn, &data); + iter_snap_objects(sctx, snap_obj_fn, &data); return data.ret; } @@ -2892,19 +2857,12 @@ bool ED_transform_snap_object_project_ray_ex(SnapObjectContext *sctx, Object **r_ob, float r_obmat[4][4]) { - return raycastObjects(sctx, - depsgraph, - v3d, - params, - ray_start, - ray_normal, - ray_depth, - r_loc, - r_no, - r_index, - r_ob, - r_obmat, - NULL); + sctx->runtime.params = params; + sctx->runtime.depsgraph = depsgraph; + sctx->runtime.v3d = v3d; + + return raycastObjects( + sctx, ray_start, ray_normal, ray_depth, r_loc, r_no, r_index, r_ob, r_obmat, NULL); } /** @@ -2924,6 +2882,10 @@ bool ED_transform_snap_object_project_ray_all(SnapObjectContext *sctx, bool sort, ListBase *r_hit_list) { + sctx->runtime.params = params; + sctx->runtime.depsgraph = depsgraph; + sctx->runtime.v3d = v3d; + if (ray_depth == -1.0f) { ray_depth = BVH_RAYCAST_DIST_MAX; } @@ -2932,19 +2894,8 @@ bool ED_transform_snap_object_project_ray_all(SnapObjectContext *sctx, float ray_depth_prev = ray_depth; #endif - bool retval = raycastObjects(sctx, - depsgraph, - v3d, - params, - ray_start, - ray_normal, - &ray_depth, - NULL, - NULL, - NULL, - NULL, - NULL, - r_hit_list); + bool retval = raycastObjects( + sctx, ray_start, ray_normal, &ray_depth, NULL, NULL, NULL, NULL, NULL, r_hit_list); /* meant to be readonly for 'all' hits, ensure it is */ #ifdef DEBUG @@ -3031,6 +2982,11 @@ static short transform_snap_context_project_view3d_mixed_impl( float r_obmat[4][4], float r_face_nor[3]) { + sctx->runtime.params = params; + sctx->runtime.depsgraph = depsgraph; + sctx->runtime.region = region; + sctx->runtime.v3d = v3d; + BLI_assert((snap_to_flag & (SCE_SNAP_MODE_VERTEX | SCE_SNAP_MODE_EDGE | SCE_SNAP_MODE_FACE | SCE_SNAP_MODE_EDGE_MIDPOINT | SCE_SNAP_MODE_EDGE_PERPENDICULAR)) != 0); @@ -3050,10 +3006,6 @@ static short transform_snap_context_project_view3d_mixed_impl( bool use_occlusion_test = params->use_occlusion_test && !XRAY_ENABLED(v3d); - sctx->runtime.depsgraph = depsgraph; - sctx->runtime.region = region; - sctx->runtime.v3d = v3d; - if (snap_to_flag & SCE_SNAP_MODE_FACE || use_occlusion_test) { float ray_start[3], ray_normal[3]; if (!ED_view3d_win_to_ray_clipped_ex( @@ -3063,19 +3015,9 @@ static short transform_snap_context_project_view3d_mixed_impl( float dummy_ray_depth = BVH_RAYCAST_DIST_MAX; - has_hit = raycastObjects(sctx, - depsgraph, - v3d, - params, - ray_start, - ray_normal, - &dummy_ray_depth, - loc, - no, - &index, - &ob_eval, - obmat, - NULL); + has_hit = raycastObjects( + sctx, ray_start, ray_normal, &dummy_ray_depth, loc, no, &index, &ob_eval, obmat, NULL); + if (has_hit) { if (r_face_nor) { copy_v3_v3(r_face_nor, no); @@ -3144,8 +3086,7 @@ static short transform_snap_context_project_view3d_mixed_impl( new_clipplane[3] += 0.01f; /* Try to snap only to the polygon. */ - elem_test = snap_mesh_polygon( - sctx, ob_eval, obmat, params->use_backface_culling, &dist_px_tmp, loc, no, &index); + elem_test = snap_mesh_polygon(sctx, ob_eval, obmat, &dist_px_tmp, loc, no, &index); if (elem_test) { elem = elem_test; } @@ -3159,7 +3100,7 @@ static short transform_snap_context_project_view3d_mixed_impl( sctx->runtime.has_occlusion_plane = true; } - elem_test = snapObjectsRay(sctx, params, &dist_px_tmp, loc, no, &index, &ob_eval, obmat); + elem_test = snapObjectsRay(sctx, &dist_px_tmp, loc, no, &index, &ob_eval, obmat); if (elem_test) { elem = elem_test; } @@ -3168,16 +3109,8 @@ static short transform_snap_context_project_view3d_mixed_impl( (snap_to_flag & (SCE_SNAP_MODE_VERTEX | SCE_SNAP_MODE_EDGE_MIDPOINT | SCE_SNAP_MODE_EDGE_PERPENDICULAR))) { sctx->runtime.snap_to_flag = snap_to_flag; - elem = snap_mesh_edge_verts_mixed(sctx, - ob_eval, - obmat, - *dist_px, - prev_co, - params->use_backface_culling, - &dist_px_tmp, - loc, - no, - &index); + elem = snap_mesh_edge_verts_mixed( + sctx, ob_eval, obmat, *dist_px, prev_co, &dist_px_tmp, loc, no, &index); } if (elem & snap_to_flag) { diff --git a/source/blender/gpu/GPU_immediate_util.h b/source/blender/gpu/GPU_immediate_util.h index 0d3d39839b2..047c3d3da00 100644 --- a/source/blender/gpu/GPU_immediate_util.h +++ b/source/blender/gpu/GPU_immediate_util.h @@ -92,6 +92,7 @@ void imm_draw_cylinder_wire_3d( void imm_draw_cylinder_fill_3d( uint pos, float base, float top, float height, int slices, int stacks); +void imm_drawcircball(const float cent[3], float rad, const float tmat[4][4], uint pos); #ifdef __cplusplus } #endif diff --git a/source/blender/gpu/intern/gpu_immediate_util.c b/source/blender/gpu/intern/gpu_immediate_util.c index 032974db8d1..df18b89bd67 100644 --- a/source/blender/gpu/intern/gpu_immediate_util.c +++ b/source/blender/gpu/intern/gpu_immediate_util.c @@ -602,3 +602,55 @@ void imm_draw_cylinder_fill_3d( } immEnd(); } + +/* Circle Drawing - Tables for Optimized Drawing Speed */ +#define CIRCLE_RESOL 32 + +static void circball_array_fill(const float verts[CIRCLE_RESOL][3], + const float cent[3], + float rad, + const float tmat[4][4]) +{ + /* 32 values of sin function (still same result!) */ + const float sinval[CIRCLE_RESOL] = { + 0.00000000, 0.20129852, 0.39435585, 0.57126821, 0.72479278, 0.84864425, 0.93775213, + 0.98846832, 0.99871650, 0.96807711, 0.89780453, 0.79077573, 0.65137248, 0.48530196, + 0.29936312, 0.10116832, -0.10116832, -0.29936312, -0.48530196, -0.65137248, -0.79077573, + -0.89780453, -0.96807711, -0.99871650, -0.98846832, -0.93775213, -0.84864425, -0.72479278, + -0.57126821, -0.39435585, -0.20129852, 0.00000000, + }; + + /* 32 values of cos function (still same result!) */ + const float cosval[CIRCLE_RESOL] = { + 1.00000000, 0.97952994, 0.91895781, 0.82076344, 0.68896691, 0.52896401, 0.34730525, + 0.15142777, -0.05064916, -0.25065253, -0.44039415, -0.61210598, -0.75875812, -0.87434661, + -0.95413925, -0.99486932, -0.99486932, -0.95413925, -0.87434661, -0.75875812, -0.61210598, + -0.44039415, -0.25065253, -0.05064916, 0.15142777, 0.34730525, 0.52896401, 0.68896691, + 0.82076344, 0.91895781, 0.97952994, 1.00000000, + }; + + float vx[3], vy[3]; + float *viter = (float *)verts; + + mul_v3_v3fl(vx, tmat[0], rad); + mul_v3_v3fl(vy, tmat[1], rad); + + for (uint a = 0; a < CIRCLE_RESOL; a++, viter += 3) { + viter[0] = cent[0] + sinval[a] * vx[0] + cosval[a] * vy[0]; + viter[1] = cent[1] + sinval[a] * vx[1] + cosval[a] * vy[1]; + viter[2] = cent[2] + sinval[a] * vx[2] + cosval[a] * vy[2]; + } +} + +void imm_drawcircball(const float cent[3], float rad, const float tmat[4][4], uint pos) +{ + float verts[CIRCLE_RESOL][3]; + + circball_array_fill(verts, cent, rad, tmat); + + immBegin(GPU_PRIM_LINE_LOOP, CIRCLE_RESOL); + for (int i = 0; i < CIRCLE_RESOL; i++) { + immVertex3fv(pos, verts[i]); + } + immEnd(); +} diff --git a/source/blender/imbuf/intern/moviecache.c b/source/blender/imbuf/intern/moviecache.c index 1bc0a4e628d..8923ba98e08 100644 --- a/source/blender/imbuf/intern/moviecache.c +++ b/source/blender/imbuf/intern/moviecache.c @@ -122,11 +122,11 @@ static void moviecache_valfree(void *val) PRINT("%s: cache '%s' free item %p buffer %p\n", __func__, cache->name, item, item->ibuf); - BLI_mutex_lock(&limitor_lock); if (item->c_handle) { + BLI_mutex_lock(&limitor_lock); MEM_CacheLimiter_unmanage(item->c_handle); + BLI_mutex_unlock(&limitor_lock); } - BLI_mutex_unlock(&limitor_lock); if (item->ibuf) { IMB_freeImBuf(item->ibuf); diff --git a/source/blender/makesdna/DNA_constraint_types.h b/source/blender/makesdna/DNA_constraint_types.h index 6dc2d00252f..d587bd8082b 100644 --- a/source/blender/makesdna/DNA_constraint_types.h +++ b/source/blender/makesdna/DNA_constraint_types.h @@ -728,7 +728,7 @@ typedef enum eBConstraint_Flags { /* bConstraint->ownspace/tarspace */ typedef enum eBConstraint_SpaceTypes { - /** Default for all - worldspace. */ + /** Default for all - world-space. */ CONSTRAINT_SPACE_WORLD = 0, /** For all - custom space. */ CONSTRAINT_SPACE_CUSTOM = 5, diff --git a/source/blender/makesdna/DNA_node_types.h b/source/blender/makesdna/DNA_node_types.h index cd333789177..a0d88bd0289 100644 --- a/source/blender/makesdna/DNA_node_types.h +++ b/source/blender/makesdna/DNA_node_types.h @@ -305,7 +305,7 @@ typedef struct bNode { char _pad1[4]; - /** Entire boundbox (worldspace). */ + /** Entire boundbox (world-space). */ rctf totr; /** Optional buttons area. */ rctf butr; diff --git a/source/blender/makesdna/DNA_object_types.h b/source/blender/makesdna/DNA_object_types.h index e94541fdc7f..57c8ef200ae 100644 --- a/source/blender/makesdna/DNA_object_types.h +++ b/source/blender/makesdna/DNA_object_types.h @@ -311,7 +311,7 @@ typedef struct Object { float rotAxis[3], drotAxis[3]; /** Axis angle rotation - angle part. */ float rotAngle, drotAngle; - /** Final worldspace matrix with constraints & animsys applied. */ + /** Final world-space matrix with constraints & animsys applied. */ float obmat[4][4]; /** Inverse result of parent, so that object doesn't 'stick' to parent. */ float parentinv[4][4]; diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h index eeff5473d16..634e97f782f 100644 --- a/source/blender/makesdna/DNA_scene_types.h +++ b/source/blender/makesdna/DNA_scene_types.h @@ -2066,6 +2066,9 @@ enum { #define SCE_SNAP_MODE_VOLUME (1 << 3) #define SCE_SNAP_MODE_EDGE_MIDPOINT (1 << 4) #define SCE_SNAP_MODE_EDGE_PERPENDICULAR (1 << 5) +#define SCE_SNAP_MODE_GEOM \ + (SCE_SNAP_MODE_VERTEX | SCE_SNAP_MODE_EDGE | SCE_SNAP_MODE_FACE | \ + SCE_SNAP_MODE_EDGE_PERPENDICULAR | SCE_SNAP_MODE_EDGE_MIDPOINT) /** #SequencerToolSettings.snap_mode */ #define SEQ_SNAP_TO_STRIPS (1 << 0) diff --git a/source/blender/makesdna/DNA_screen_types.h b/source/blender/makesdna/DNA_screen_types.h index 86fd6b9744a..03110f6e1be 100644 --- a/source/blender/makesdna/DNA_screen_types.h +++ b/source/blender/makesdna/DNA_screen_types.h @@ -667,7 +667,7 @@ typedef enum eRegion_Type { RGN_TYPE_FOOTER = 11, RGN_TYPE_TOOL_HEADER = 12, /* Region type used exclusively by internal code and add-ons to register draw callbacks to the XR - context (surface, mirror view). Does not represent any real region. */ + * context (surface, mirror view). Does not represent any real region. */ RGN_TYPE_XR = 13, #define RGN_TYPE_LEN (RGN_TYPE_XR + 1) diff --git a/source/blender/makesdna/DNA_sequence_types.h b/source/blender/makesdna/DNA_sequence_types.h index fc23d3c69a3..9e6cf907444 100644 --- a/source/blender/makesdna/DNA_sequence_types.h +++ b/source/blender/makesdna/DNA_sequence_types.h @@ -378,7 +378,7 @@ typedef struct TextVars { char text[512]; struct VFont *text_font; int text_blf_id; - int text_size; + float text_size; float color[4], shadow_color[4], box_color[4]; float loc[2]; float wrap_width; diff --git a/source/blender/makesdna/DNA_space_types.h b/source/blender/makesdna/DNA_space_types.h index 671cc182d7e..3bd7df0043a 100644 --- a/source/blender/makesdna/DNA_space_types.h +++ b/source/blender/makesdna/DNA_space_types.h @@ -64,7 +64,7 @@ struct wmTimer; /* Defined in `buttons_intern.h`. */ typedef struct SpaceProperties_Runtime SpaceProperties_Runtime; -/* Defined in `node_intern.h`. */ +/* Defined in `node_intern.hh`. */ typedef struct SpaceNode_Runtime SpaceNode_Runtime; /* Defined in `file_intern.h`. */ diff --git a/source/blender/makesdna/DNA_texture_types.h b/source/blender/makesdna/DNA_texture_types.h index ee33e8666ec..2c3cd8eab77 100644 --- a/source/blender/makesdna/DNA_texture_types.h +++ b/source/blender/makesdna/DNA_texture_types.h @@ -128,9 +128,9 @@ typedef struct PointDensity { struct Object *object; /** `index + 1` in ob.particlesystem, non-ID pointer not allowed */ int psys; - /** cache points in worldspace, object space, ... ? */ + /** cache points in world-space, object space, ... ? */ short psys_cache_space; - /** cache points in worldspace, object space, ... ? */ + /** cache points in world-space, object space, ... ? */ short ob_cache_space; /** vertex attribute layer for color source, MAX_CUSTOMDATA_LAYER_NAME */ char vertex_attribute_name[64]; diff --git a/source/blender/makesdna/DNA_userdef_types.h b/source/blender/makesdna/DNA_userdef_types.h index f80fcb9ae78..aad84482f07 100644 --- a/source/blender/makesdna/DNA_userdef_types.h +++ b/source/blender/makesdna/DNA_userdef_types.h @@ -69,8 +69,9 @@ typedef struct uiFont { typedef struct uiFontStyle { /** Saved in file, 0 is default. */ short uifont_id; + char _pad1[2]; /** Actual size depends on 'global' dpi. */ - short points; + float points; /** Style hint. */ short italic, bold; /** Value is amount of pixels blur. */ @@ -82,6 +83,7 @@ typedef struct uiFontStyle { float shadowalpha; /** 1 value, typically white or black anyway. */ float shadowcolor; + char _pad2[4]; } uiFontStyle; /* this is fed to the layout engine and widget code */ @@ -938,7 +940,8 @@ typedef struct UserDef { short sequencer_proxy_setup; /* eUserpref_SeqProxySetup */ float collection_instance_empty_size; - char _pad10[2]; + char text_flag; + char _pad10[1]; char file_preview_type; /* eUserpref_File_Preview_Type */ char statusbar_flag; /* eUserpref_StatusBar_Flag */ @@ -1263,6 +1266,14 @@ typedef enum eDupli_ID_Flags { } eDupli_ID_Flags; /** + * Text Editor options + * #UserDef.text_flag + */ +typedef enum eTextEdit_Flags { + USER_TEXT_EDIT_AUTO_CLOSE = (1 << 0), +} eTextEdit_Flags; + +/** * Text draw options * #UserDef.text_render */ diff --git a/source/blender/makesdna/DNA_view3d_types.h b/source/blender/makesdna/DNA_view3d_types.h index 9b5ed133feb..3fd2f1208dd 100644 --- a/source/blender/makesdna/DNA_view3d_types.h +++ b/source/blender/makesdna/DNA_view3d_types.h @@ -64,8 +64,10 @@ typedef struct RegionView3D { /** User defined clipping planes. */ float clip[6][4]; - /** Clip in object space, - * means we can test for clipping in editmode without first going into worldspace. */ + /** + * Clip in object space, + * means we can test for clipping in edit-mode without first going into world-space. + */ float clip_local[6][4]; struct BoundBox *clipbb; @@ -94,8 +96,8 @@ typedef struct RegionView3D { /** Runtime only. */ float pixsize; /** - * View center & orbit pivot, negative of worldspace location, - * also matches -viewinv[3][0:3] in ortho mode. + * View center & orbit pivot, negative of world-space location, + * also matches `-viewinv[3][0:3]` in orthographic mode. */ float ofs[3]; /** Viewport zoom on the camera frame, see BKE_screen_view3d_zoom_to_fac. */ diff --git a/source/blender/makesrna/intern/rna_animviz.c b/source/blender/makesrna/intern/rna_animviz.c index b205b3d7139..1511921cef0 100644 --- a/source/blender/makesrna/intern/rna_animviz.c +++ b/source/blender/makesrna/intern/rna_animviz.c @@ -117,7 +117,7 @@ static void rna_def_animviz_motion_path(BlenderRNA *brna) srna = RNA_def_struct(brna, "MotionPath", NULL); RNA_def_struct_sdna(srna, "bMotionPath"); RNA_def_struct_ui_text( - srna, "Motion Path", "Cache of the worldspace positions of an element over a frame range"); + srna, "Motion Path", "Cache of the world-space positions of an element over a frame range"); /* Collections */ prop = RNA_def_property(srna, "points", PROP_COLLECTION, PROP_NONE); diff --git a/source/blender/makesrna/intern/rna_depsgraph.c b/source/blender/makesrna/intern/rna_depsgraph.c index 85071e8cd19..58565fecf4d 100644 --- a/source/blender/makesrna/intern/rna_depsgraph.c +++ b/source/blender/makesrna/intern/rna_depsgraph.c @@ -207,8 +207,10 @@ static bool rna_DepsgraphUpdate_is_updated_transform_get(PointerRNA *ptr) static bool rna_DepsgraphUpdate_is_updated_shading_get(PointerRNA *ptr) { + /* Assume any animated parameters can affect shading, we don't have fine + * grained enough updates to distinguish this. */ ID *id = ptr->data; - return ((id->recalc & ID_RECALC_SHADING) != 0); + return ((id->recalc & (ID_RECALC_SHADING | ID_RECALC_ANIMATION)) != 0); } static bool rna_DepsgraphUpdate_is_updated_geometry_get(PointerRNA *ptr) diff --git a/source/blender/makesrna/intern/rna_sequencer.c b/source/blender/makesrna/intern/rna_sequencer.c index cc302c4dd89..21a7131c46f 100644 --- a/source/blender/makesrna/intern/rna_sequencer.c +++ b/source/blender/makesrna/intern/rna_sequencer.c @@ -2979,11 +2979,11 @@ static void rna_def_text(StructRNA *srna) RNA_def_property_pointer_funcs(prop, NULL, "rna_Sequence_text_font_set", NULL, NULL); RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_invalidate_raw_update"); - prop = RNA_def_property(srna, "font_size", PROP_INT, PROP_UNSIGNED); - RNA_def_property_int_sdna(prop, NULL, "text_size"); + prop = RNA_def_property(srna, "font_size", PROP_FLOAT, PROP_UNSIGNED); + RNA_def_property_float_sdna(prop, NULL, "text_size"); RNA_def_property_ui_text(prop, "Size", "Size of the text"); RNA_def_property_range(prop, 0.0, 2000); - RNA_def_property_ui_range(prop, 0.0f, 2000, 1, -1); + RNA_def_property_ui_range(prop, 0.0f, 2000, 10.f, 1); RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_invalidate_raw_update"); prop = RNA_def_property(srna, "color", PROP_FLOAT, PROP_COLOR_GAMMA); diff --git a/source/blender/makesrna/intern/rna_userdef.c b/source/blender/makesrna/intern/rna_userdef.c index 92f7b7d7682..9ce1fca164c 100644 --- a/source/blender/makesrna/intern/rna_userdef.c +++ b/source/blender/makesrna/intern/rna_userdef.c @@ -1136,10 +1136,11 @@ static void rna_def_userdef_theme_ui_font_style(BlenderRNA *brna) RNA_def_struct_clear_flag(srna, STRUCT_UNDO); RNA_def_struct_ui_text(srna, "Font Style", "Theme settings for Font"); - prop = RNA_def_property(srna, "points", PROP_INT, PROP_NONE); - RNA_def_property_range(prop, 6, 24); + prop = RNA_def_property(srna, "points", PROP_FLOAT, PROP_UNSIGNED); + RNA_def_property_range(prop, 6.0f, 32.0f); + RNA_def_property_ui_range(prop, 8.0f, 20.0f, 10.0f, 1); RNA_def_property_ui_text(prop, "Points", "Font size in points"); - RNA_def_property_update(prop, 0, "rna_userdef_theme_text_style_update"); + RNA_def_property_update(prop, 0, "rna_userdef_dpi_update"); prop = RNA_def_property(srna, "shadow", PROP_INT, PROP_PIXEL); RNA_def_property_range(prop, 0, 5); @@ -5024,6 +5025,14 @@ static void rna_def_userdef_edit(BlenderRNA *brna) "Collection Instance Empty Size", "Display size of the empty when new collection instances are created"); + /* Text Editor */ + + prop = RNA_def_property(srna, "use_text_edit_auto_close", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "text_flag", USER_TEXT_EDIT_AUTO_CLOSE); + RNA_def_property_ui_text( + prop, "Auto Close", "Auto close relevant characters inside the text editor"); + RNA_def_property_update(prop, NC_SPACE | ND_SPACE_TEXT, NULL); + /* Undo */ prop = RNA_def_property(srna, "undo_steps", PROP_INT, PROP_NONE); diff --git a/source/blender/modifiers/intern/MOD_meshdeform.c b/source/blender/modifiers/intern/MOD_meshdeform.c index c997cd7377f..cb043643dd9 100644 --- a/source/blender/modifiers/intern/MOD_meshdeform.c +++ b/source/blender/modifiers/intern/MOD_meshdeform.c @@ -426,7 +426,7 @@ static void meshdeformModifier_do(ModifierData *md, bindcagecos = (float(*)[3])mmd->bindcagecos; for (a = 0; a < totcagevert; a++) { - /* get cage vertex in world space with binding transform */ + /* Get cage vertex in world-space with binding transform. */ float co[3]; mul_v3_m4v3(co, mmd->bindmat, dco[a]); /* compute difference with world space bind coord */ diff --git a/source/blender/modifiers/intern/MOD_nodes.cc b/source/blender/modifiers/intern/MOD_nodes.cc index 218493a53cf..fb9dbc0ad0a 100644 --- a/source/blender/modifiers/intern/MOD_nodes.cc +++ b/source/blender/modifiers/intern/MOD_nodes.cc @@ -89,6 +89,7 @@ #include "MOD_ui_common.h" #include "ED_object.h" +#include "ED_screen.h" #include "ED_spreadsheet.h" #include "ED_undo.h" @@ -1026,17 +1027,22 @@ static void check_property_socket_sync(const Object *ob, ModifierData *md) { NodesModifierData *nmd = reinterpret_cast<NodesModifierData *>(md); - int i = 0; + int geometry_socket_count = 0; + + int i; LISTBASE_FOREACH_INDEX (const bNodeSocket *, socket, &nmd->node_group->inputs, i) { /* The first socket is the special geometry socket for the modifier object. */ - if (i == 0 && socket->type == SOCK_GEOMETRY) { - continue; + if (i == 0) { + if (socket->type == SOCK_GEOMETRY) { + continue; + } + BKE_modifier_set_error(ob, md, "The first node group input must be a geometry"); } IDProperty *property = IDP_GetPropertyFromGroup(nmd->settings.properties, socket->identifier); if (property == nullptr) { if (socket->type == SOCK_GEOMETRY) { - BKE_modifier_set_error(ob, md, "Node group can only have one geometry input"); + geometry_socket_count++; } else { BKE_modifier_set_error(ob, md, "Missing property for input socket \"%s\"", socket->name); @@ -1051,15 +1057,8 @@ static void check_property_socket_sync(const Object *ob, ModifierData *md) } } - bool has_geometry_output = false; - LISTBASE_FOREACH (const bNodeSocket *, socket, &nmd->node_group->outputs) { - if (socket->type == SOCK_GEOMETRY) { - has_geometry_output = true; - } - } - - if (!has_geometry_output) { - BKE_modifier_set_error(ob, md, "Node group must have a geometry output"); + if (geometry_socket_count > 1) { + BKE_modifier_set_error(ob, md, "Node group can only have one geometry input"); } } @@ -1079,6 +1078,7 @@ static void modifyGeometry(ModifierData *md, if (tree.has_link_cycles()) { BKE_modifier_set_error(ctx->object, md, "Node group has cycles"); + geometry_set.clear(); return; } @@ -1086,17 +1086,23 @@ static void modifyGeometry(ModifierData *md, Span<const NodeRef *> input_nodes = root_tree_ref.nodes_by_type("NodeGroupInput"); Span<const NodeRef *> output_nodes = root_tree_ref.nodes_by_type("NodeGroupOutput"); if (output_nodes.size() != 1) { + BKE_modifier_set_error(ctx->object, md, "Node group must have a single output node"); + geometry_set.clear(); return; } const NodeRef &output_node = *output_nodes[0]; Span<const InputSocketRef *> group_outputs = output_node.inputs().drop_back(1); if (group_outputs.is_empty()) { + BKE_modifier_set_error(ctx->object, md, "Node group must have an output socket"); + geometry_set.clear(); return; } const InputSocketRef *first_output_socket = group_outputs[0]; if (first_output_socket->idname() != "NodeSocketGeometry") { + BKE_modifier_set_error(ctx->object, md, "Node group's first output must be a geometry"); + geometry_set.clear(); return; } @@ -1133,8 +1139,17 @@ struct AttributeSearchData { /* This class must not have a destructor, since it is used by buttons and freed with #MEM_freeN. */ BLI_STATIC_ASSERT(std::is_trivially_destructible_v<AttributeSearchData>, ""); -static NodesModifierData *get_modifier_data(Main &bmain, const AttributeSearchData &data) +static NodesModifierData *get_modifier_data(Main &bmain, + const wmWindowManager &wm, + const AttributeSearchData &data) { + if (ED_screen_animation_playing(&wm)) { + /* Work around an issue where the attribute search exec function has stale pointers when data + * is reallocated when evaluating the node tree, causing a crash. This would be solved by + * allowing the UI search data to own arbitrary memory rather than just referencing it. */ + return nullptr; + } + const Object *object = (Object *)BKE_libblock_find_session_uuid( &bmain, ID_OB, data.object_session_uid); if (object == nullptr) { @@ -1152,7 +1167,7 @@ static void attribute_search_update_fn( const bContext *C, void *arg, const char *str, uiSearchItems *items, const bool is_first) { AttributeSearchData &data = *static_cast<AttributeSearchData *>(arg); - const NodesModifierData *nmd = get_modifier_data(*CTX_data_main(C), data); + const NodesModifierData *nmd = get_modifier_data(*CTX_data_main(C), *CTX_wm_manager(C), data); if (nmd == nullptr) { return; } @@ -1186,7 +1201,7 @@ static void attribute_search_exec_fn(bContext *C, void *data_v, void *item_v) } AttributeSearchData &data = *static_cast<AttributeSearchData *>(data_v); const GeometryAttributeInfo &item = *static_cast<const GeometryAttributeInfo *>(item_v); - const NodesModifierData *nmd = get_modifier_data(*CTX_data_main(C), data); + const NodesModifierData *nmd = get_modifier_data(*CTX_data_main(C), *CTX_wm_manager(C), data); if (nmd == nullptr) { return; } diff --git a/source/blender/modifiers/intern/MOD_uvproject.c b/source/blender/modifiers/intern/MOD_uvproject.c index 2c28e9710ef..238952fde00 100644 --- a/source/blender/modifiers/intern/MOD_uvproject.c +++ b/source/blender/modifiers/intern/MOD_uvproject.c @@ -192,7 +192,7 @@ static Mesh *uvprojectModifier_do(UVProjectModifierData *umd, mul_m4_m4m4(projectors[i].projmat, offsetmat, tmpmat); - /* calculate worldspace projector normal (for best projector test) */ + /* Calculate world-space projector normal (for best projector test). */ projectors[i].normal[0] = 0; projectors[i].normal[1] = 0; projectors[i].normal[2] = 1; @@ -208,7 +208,7 @@ static Mesh *uvprojectModifier_do(UVProjectModifierData *umd, coords = BKE_mesh_vert_coords_alloc(mesh, &numVerts); - /* convert coords to world space */ + /* Convert coords to world-space. */ for (i = 0, co = coords; i < numVerts; i++, co++) { mul_m4_v3(ob->obmat, *co); } diff --git a/source/blender/nodes/geometry/nodes/node_geo_curve_handle_type_selection.cc b/source/blender/nodes/geometry/nodes/node_geo_curve_handle_type_selection.cc index 165f5da5f71..e48c72b68d9 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_curve_handle_type_selection.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_curve_handle_type_selection.cc @@ -158,11 +158,8 @@ void register_node_type_geo_curve_handle_type_selection() { static bNodeType ntype; - geo_node_type_base(&ntype, - GEO_NODE_CURVE_HANDLE_TYPE_SELECTION, - "Handle Type Selection", - NODE_CLASS_GEOMETRY, - 0); + geo_node_type_base( + &ntype, GEO_NODE_CURVE_HANDLE_TYPE_SELECTION, "Handle Type Selection", NODE_CLASS_INPUT, 0); ntype.declare = blender::nodes::geo_node_curve_handle_type_selection_declare; ntype.geometry_node_execute = blender::nodes::geo_node_curve_handle_type_selection_exec; node_type_init(&ntype, blender::nodes::geo_node_curve_handle_type_selection_init); diff --git a/source/blender/nodes/geometry/nodes/node_geo_curve_primitive_star.cc b/source/blender/nodes/geometry/nodes/node_geo_curve_primitive_star.cc index 7f682b198b3..9004681c246 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_curve_primitive_star.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_curve_primitive_star.cc @@ -42,6 +42,9 @@ static void geo_node_curve_primitive_star_declare(NodeDeclarationBuilder &b) .subtype(PROP_ANGLE) .description(N_("The counterclockwise rotation of the inner set of points")); b.add_output<decl::Geometry>(N_("Curve")); + b.add_output<decl::Bool>(N_("Outer Points")) + .field_source() + .description(N_("An attribute field with a selection of the outer points")); } static std::unique_ptr<CurveEval> create_star_curve(const float inner_radius, @@ -66,9 +69,22 @@ static std::unique_ptr<CurveEval> create_star_curve(const float inner_radius, spline->attributes.reallocate(spline->size()); curve->add_spline(std::move(spline)); curve->attributes.reallocate(curve->splines().size()); + return curve; } +static void create_selection_output(CurveComponent &component, + StrongAnonymousAttributeID &r_attribute) +{ + OutputAttribute_Typed<bool> attribute = component.attribute_try_get_for_output_only<bool>( + r_attribute.get(), ATTR_DOMAIN_POINT); + MutableSpan<bool> selection = attribute.as_span(); + for (int i : selection.index_range()) { + selection[i] = i % 2 == 0; + } + attribute.save(); +} + static void geo_node_curve_primitive_star_exec(GeoNodeExecParams params) { std::unique_ptr<CurveEval> curve = create_star_curve( @@ -76,9 +92,17 @@ static void geo_node_curve_primitive_star_exec(GeoNodeExecParams params) std::max(params.extract_input<float>("Outer Radius"), 0.0f), params.extract_input<float>("Twist"), std::max(params.extract_input<int>("Points"), 3)); - params.set_output("Curve", GeometrySet::create_with_curve(curve.release())); -} + GeometrySet output = GeometrySet::create_with_curve(curve.release()); + if (params.output_is_required("Outer Points")) { + StrongAnonymousAttributeID attribute_output("Outer Points"); + create_selection_output(output.get_component_for_write<CurveComponent>(), attribute_output); + params.set_output("Outer Points", + AnonymousAttributeFieldInput::Create<bool>( + std::move(attribute_output), params.attribute_producer_name())); + } + params.set_output("Curve", std::move(output)); +} } // namespace blender::nodes void register_node_type_geo_curve_primitive_star() diff --git a/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_cylinder.cc b/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_cylinder.cc index 51ecff72e68..49fcb063a91 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_cylinder.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_cylinder.cc @@ -56,8 +56,8 @@ static void geo_node_mesh_primitive_cylinder_declare(NodeDeclarationBuilder &b) .description(N_("The height of the cylinder")); b.add_output<decl::Geometry>(N_("Mesh")); b.add_output<decl::Bool>(N_("Top")).field_source(); - b.add_output<decl::Bool>(N_("Bottom")).field_source(); b.add_output<decl::Bool>(N_("Side")).field_source(); + b.add_output<decl::Bool>(N_("Bottom")).field_source(); } static void geo_node_mesh_primitive_cylinder_layout(uiLayout *layout, diff --git a/source/blender/nodes/geometry/nodes/node_geo_set_curve_handles.cc b/source/blender/nodes/geometry/nodes/node_geo_set_curve_handles.cc index b64aa266330..30b445da58c 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_set_curve_handles.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_set_curve_handles.cc @@ -28,6 +28,7 @@ static void geo_node_set_curve_handles_declare(NodeDeclarationBuilder &b) b.add_input<decl::Geometry>(N_("Curve")).supported_type(GEO_COMPONENT_TYPE_CURVE); b.add_input<decl::Bool>(N_("Selection")).default_value(true).hide_value().supports_field(); b.add_input<decl::Vector>(N_("Position")).implicit_field(); + b.add_input<decl::Vector>(N_("Offset")).default_value(float3(0.0f, 0.0f, 0.0f)).supports_field(); b.add_output<decl::Geometry>(N_("Curve")); } @@ -50,7 +51,8 @@ static void geo_node_set_curve_handles_init(bNodeTree *UNUSED(tree), bNode *node static void set_position_in_component(const GeometryNodeCurveHandleMode mode, GeometryComponent &component, const Field<bool> &selection_field, - const Field<float3> &position_field) + const Field<float3> &position_field, + const Field<float3> &offset_field) { GeometryComponentFieldContext field_context{component, ATTR_DOMAIN_POINT}; const int domain_size = component.attribute_domain_size(ATTR_DOMAIN_POINT); @@ -111,11 +113,22 @@ static void set_position_in_component(const GeometryNodeCurveHandleMode mode, } } - OutputAttribute_Typed<float3> positions = component.attribute_try_get_for_output_only<float3>( - side, ATTR_DOMAIN_POINT); fn::FieldEvaluator position_evaluator{field_context, &selection}; - position_evaluator.add_with_destination(position_field, positions.varray()); + position_evaluator.add(position_field); + position_evaluator.add(offset_field); position_evaluator.evaluate(); + + const VArray<float3> &positions_input = position_evaluator.get_evaluated<float3>(0); + const VArray<float3> &offsets_input = position_evaluator.get_evaluated<float3>(1); + + OutputAttribute_Typed<float3> positions = component.attribute_try_get_for_output<float3>( + side, ATTR_DOMAIN_POINT, {0, 0, 0}); + MutableSpan<float3> position_mutable = positions.as_span(); + + for (int i : selection) { + position_mutable[i] = positions_input[i] + offsets_input[i]; + } + positions.save(); } @@ -128,6 +141,7 @@ static void geo_node_set_curve_handles_exec(GeoNodeExecParams params) GeometrySet geometry_set = params.extract_input<GeometrySet>("Curve"); Field<bool> selection_field = params.extract_input<Field<bool>>("Selection"); Field<float3> position_field = params.extract_input<Field<float3>>("Position"); + Field<float3> offset_field = params.extract_input<Field<float3>>("Offset"); bool has_bezier = false; geometry_set.modify_geometry_sets([&](GeometrySet &geometry_set) { @@ -137,7 +151,8 @@ static void geo_node_set_curve_handles_exec(GeoNodeExecParams params) set_position_in_component(mode, geometry_set.get_component_for_write<CurveComponent>(), selection_field, - position_field); + position_field, + offset_field); } }); if (!has_bezier) { diff --git a/source/blender/nodes/geometry/nodes/node_geo_transfer_attribute.cc b/source/blender/nodes/geometry/nodes/node_geo_transfer_attribute.cc index a889678537f..9754b3f81a0 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_transfer_attribute.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_transfer_attribute.cc @@ -42,7 +42,8 @@ static void geo_node_transfer_attribute_declare(NodeDeclarationBuilder &b) { b.add_input<decl::Geometry>(N_("Target")) .only_realized_data() - .supported_type({GEO_COMPONENT_TYPE_MESH, GEO_COMPONENT_TYPE_POINT_CLOUD}); + .supported_type( + {GEO_COMPONENT_TYPE_MESH, GEO_COMPONENT_TYPE_POINT_CLOUD, GEO_COMPONENT_TYPE_CURVE}); b.add_input<decl::Vector>(N_("Attribute")).hide_value().supports_field(); b.add_input<decl::Float>(N_("Attribute"), "Attribute_001").hide_value().supports_field(); @@ -305,7 +306,7 @@ void copy_with_indices(const VArray<T> &src, template<typename T> void copy_with_indices_clamped(const VArray<T> &src, const IndexMask mask, - const Span<int> indices, + const VArray<int> &indices, const MutableSpan<T> dst) { if (src.is_empty()) { @@ -587,18 +588,11 @@ class NearestTransferFunction : public fn::MultiFunction { } }; -static const GeometryComponent *find_best_match_component(const GeometrySet &geometry, - const GeometryComponentType type, - const AttributeDomain domain) +static const GeometryComponent *find_target_component(const GeometrySet &geometry, + const AttributeDomain domain) { - /* Prefer transferring from the same component type, if it exists. */ - if (component_is_available(geometry, type, domain)) { - return geometry.get_component_for_read(type); - } - - /* If there is no component of the same type, choose the other component based on a consistent - * order, rather than some more complicated heuristic. This is the same order visible in the - * spreadsheet and used in the ray-cast node. */ + /* Choose the other component based on a consistent order, rather than some more complicated + * heuristic. This is the same order visible in the spreadsheet and used in the ray-cast node. */ static const Array<GeometryComponentType> supported_types = { GEO_COMPONENT_TYPE_MESH, GEO_COMPONENT_TYPE_POINT_CLOUD, GEO_COMPONENT_TYPE_CURVE}; for (const GeometryComponentType src_type : supported_types) { @@ -611,76 +605,71 @@ static const GeometryComponent *find_best_match_component(const GeometrySet &geo } /** - * Use a #FieldInput because it's necessary to know the field context in order to choose the - * corresponding component type from the input geometry, and only a #FieldInput receives the - * evaluation context to provide its data. - * * The index-based transfer theoretically does not need realized data when there is only one * instance geometry set in the target. A future optimization could be removing that limitation * internally. */ -class IndexTransferFieldInput : public FieldInput { +class IndexTransferFunction : public fn::MultiFunction { GeometrySet src_geometry_; GField src_field_; - Field<int> index_field_; AttributeDomain domain_; + fn::MFSignature signature_; + + std::optional<GeometryComponentFieldContext> geometry_context_; + std::unique_ptr<FieldEvaluator> evaluator_; + const GVArray *src_data_ = nullptr; + public: - IndexTransferFieldInput(GeometrySet geometry, - GField src_field, - Field<int> index_field, - const AttributeDomain domain) - : FieldInput(src_field.cpp_type(), "Attribute Transfer node"), - src_geometry_(std::move(geometry)), - src_field_(std::move(src_field)), - index_field_(std::move(index_field)), - domain_(domain) + IndexTransferFunction(GeometrySet geometry, GField src_field, const AttributeDomain domain) + : src_geometry_(std::move(geometry)), src_field_(std::move(src_field)), domain_(domain) { src_geometry_.ensure_owns_direct_data(); - category_ = Category::Generated; + + signature_ = this->create_signature(); + this->set_signature(&signature_); + + this->evaluate_field(); } - const GVArray *get_varray_for_context(const FieldContext &context, - const IndexMask mask, - ResourceScope &scope) const final + fn::MFSignature create_signature() { - const GeometryComponentFieldContext *geometry_context = - dynamic_cast<const GeometryComponentFieldContext *>(&context); - if (geometry_context == nullptr) { - return nullptr; - } - - FieldEvaluator index_evaluator{*geometry_context, &mask}; - index_evaluator.add(index_field_); - index_evaluator.evaluate(); - const VArray<int> &index_varray = index_evaluator.get_evaluated<int>(0); - /* The index virtual array is expected to be a span, since transferring the same index for - * every element is not very useful. */ - VArray_Span<int> indices{index_varray}; + fn::MFSignatureBuilder signature{"Attribute Transfer Index"}; + signature.single_input<int>("Index"); + signature.single_output("Attribute", src_field_.cpp_type()); + return signature.build(); + } - const GeometryComponent *component = find_best_match_component( - src_geometry_, geometry_context->geometry_component().type(), domain_); + void evaluate_field() + { + const GeometryComponent *component = find_target_component(src_geometry_, domain_); if (component == nullptr) { - return nullptr; + return; } + const int domain_size = component->attribute_domain_size(domain_); + geometry_context_.emplace(GeometryComponentFieldContext(*component, domain_)); + evaluator_ = std::make_unique<FieldEvaluator>(*geometry_context_, domain_size); + evaluator_->add(src_field_); + evaluator_->evaluate(); + src_data_ = &evaluator_->get_evaluated(0); + } - GeometryComponentFieldContext target_context{*component, domain_}; - /* A potential improvement is to only copy the necessary values - * based on the indices retrieved from the index input field. */ - FieldEvaluator target_evaluator{target_context, component->attribute_domain_size(domain_)}; - target_evaluator.add(src_field_); - target_evaluator.evaluate(); - const GVArray &src_data = target_evaluator.get_evaluated(0); + void call(IndexMask mask, fn::MFParams params, fn::MFContext UNUSED(context)) const override + { + const VArray<int> &indices = params.readonly_single_input<int>(0, "Index"); + GMutableSpan dst = params.uninitialized_single_output(1, "Attribute"); - GArray dst(src_field_.cpp_type(), mask.min_array_size()); + const CPPType &type = dst.type(); + if (src_data_ == nullptr) { + type.fill_construct_indices(type.default_value(), dst.data(), mask); + return; + } - attribute_math::convert_to_static_type(src_data.type(), [&](auto dummy) { + attribute_math::convert_to_static_type(type, [&](auto dummy) { using T = decltype(dummy); - GVArray_Typed<T> src{src_data}; - copy_with_indices_clamped(*src, mask, indices, dst.as_mutable_span().typed<T>()); + GVArray_Typed<T> src{*src_data_}; + copy_with_indices_clamped(*src, mask, indices, dst.typed<T>()); }); - - return &scope.construct<fn::GVArray_For_GArray>(std::move(dst)); } }; @@ -781,6 +770,8 @@ static void geo_node_transfer_attribute_exec(GeoNodeExecParams params) } case GEO_NODE_ATTRIBUTE_TRANSFER_NEAREST: { if (geometry.has_curve() && !geometry.has_mesh() && !geometry.has_pointcloud()) { + params.error_message_add(NodeWarningType::Error, + TIP_("The target geometry must contain a mesh or a point cloud")); return return_default(); } auto fn = std::make_unique<NearestTransferFunction>( @@ -792,9 +783,11 @@ static void geo_node_transfer_attribute_exec(GeoNodeExecParams params) } case GEO_NODE_ATTRIBUTE_TRANSFER_INDEX: { Field<int> indices = params.extract_input<Field<int>>("Index"); - std::shared_ptr<FieldInput> input = std::make_shared<IndexTransferFieldInput>( - std::move(geometry), std::move(field), std::move(indices), domain); - output_field = GField(std::move(input)); + auto fn = std::make_unique<IndexTransferFunction>( + std::move(geometry), std::move(field), domain); + auto op = std::make_shared<FieldOperation>( + FieldOperation(std::move(fn), {std::move(indices)})); + output_field = GField(std::move(op)); break; } } diff --git a/source/blender/python/generic/blf_py_api.c b/source/blender/python/generic/blf_py_api.c index 9e725730d40..a49c943df94 100644 --- a/source/blender/python/generic/blf_py_api.c +++ b/source/blender/python/generic/blf_py_api.c @@ -70,14 +70,15 @@ PyDoc_STRVAR(py_blf_size_doc, "font use 0.\n" " :type fontid: int\n" " :arg size: Point size of the font.\n" - " :type size: int\n" + " :type size: float\n" " :arg dpi: dots per inch value to use for drawing.\n" " :type dpi: int\n"); static PyObject *py_blf_size(PyObject *UNUSED(self), PyObject *args) { - int fontid, size, dpi; + int fontid, dpi; + float size; - if (!PyArg_ParseTuple(args, "iii:blf.size", &fontid, &size, &dpi)) { + if (!PyArg_ParseTuple(args, "ifi:blf.size", &fontid, &size, &dpi)) { return NULL; } diff --git a/source/blender/python/intern/bpy_library_load.c b/source/blender/python/intern/bpy_library_load.c index d9a357c5e2e..059d692a9ba 100644 --- a/source/blender/python/intern/bpy_library_load.c +++ b/source/blender/python/intern/bpy_library_load.c @@ -67,7 +67,9 @@ typedef struct { char abspath[FILE_MAX]; /* absolute path */ BlendHandle *blo_handle; /* Referenced by `blo_handle`, so stored here to keep alive for long enough. */ + ReportList reports; BlendFileReadReport bf_reports; + int flag; PyObject *dict; /* Borrowed reference to the `bmain`, taken from the RNA instance of #RNA_BlendDataLibraries. @@ -256,16 +258,17 @@ static PyObject *bpy_lib_enter(BPy_Library *self) PyObject *ret; BPy_Library *self_from; PyObject *from_dict = _PyDict_NewPresized(INDEX_ID_MAX); - ReportList reports; + ReportList *reports = &self->reports; + BlendFileReadReport *bf_reports = &self->bf_reports; - BKE_reports_init(&reports, RPT_STORE); - BlendFileReadReport bf_reports = {.reports = &reports}; + BKE_reports_init(reports, RPT_STORE); + memset(bf_reports, 0, sizeof(*bf_reports)); + bf_reports->reports = reports; - self->bf_reports = bf_reports; - self->blo_handle = BLO_blendhandle_from_file(self->abspath, &self->bf_reports); + self->blo_handle = BLO_blendhandle_from_file(self->abspath, bf_reports); if (self->blo_handle == NULL) { - if (BPy_reports_to_error(&reports, PyExc_IOError, true) != -1) { + if (BPy_reports_to_error(reports, PyExc_IOError, true) != -1) { PyErr_Format(PyExc_IOError, "load: %s failed to open blend file", self->abspath); } return NULL; @@ -301,7 +304,7 @@ static PyObject *bpy_lib_enter(BPy_Library *self) PyTuple_SET_ITEMS(ret, (PyObject *)self_from, (PyObject *)self); Py_INCREF(self); - BKE_reports_clear(&reports); + BKE_reports_clear(reports); return ret; } diff --git a/source/blender/sequencer/intern/effects.c b/source/blender/sequencer/intern/effects.c index b9ee23a9186..37d1f6832bb 100644 --- a/source/blender/sequencer/intern/effects.c +++ b/source/blender/sequencer/intern/effects.c @@ -3741,7 +3741,7 @@ static void init_text_effect(Sequence *seq) data = seq->effectdata = MEM_callocN(sizeof(TextVars), "textvars"); data->text_font = NULL; data->text_blf_id = -1; - data->text_size = 60; + data->text_size = 60.0f; copy_v4_fl(data->color, 1.0f); data->shadow_color[3] = 0.7f; @@ -3842,7 +3842,7 @@ static int num_inputs_text(void) static int early_out_text(Sequence *seq, float UNUSED(facf0), float UNUSED(facf1)) { TextVars *data = seq->effectdata; - if (data->text[0] == 0 || data->text_size < 1 || + if (data->text[0] == 0 || data->text_size < 1.0f || ((data->color[3] == 0.0f) && (data->shadow_color[3] == 0.0f || (data->flag & SEQ_TEXT_SHADOW) == 0))) { return EARLY_USE_INPUT_1; diff --git a/source/blender/windowmanager/gizmo/WM_gizmo_types.h b/source/blender/windowmanager/gizmo/WM_gizmo_types.h index ceaec94e70b..8bf82a41c91 100644 --- a/source/blender/windowmanager/gizmo/WM_gizmo_types.h +++ b/source/blender/windowmanager/gizmo/WM_gizmo_types.h @@ -29,6 +29,7 @@ #pragma once #include "BLI_compiler_attrs.h" +#include "BLI_utildefines.h" struct wmGizmo; struct wmGizmoGroup; @@ -163,6 +164,8 @@ typedef enum eWM_GizmoFlagGroupTypeFlag { WM_GIZMOGROUPTYPE_VR_REDRAWS = (1 << 10), } eWM_GizmoFlagGroupTypeFlag; +ENUM_OPERATORS(eWM_GizmoFlagGroupTypeFlag, WM_GIZMOGROUPTYPE_VR_REDRAWS); + /** * #wmGizmoGroup.init_flag */ diff --git a/source/blender/windowmanager/intern/wm_files.c b/source/blender/windowmanager/intern/wm_files.c index 0074ecc392d..a301b17227d 100644 --- a/source/blender/windowmanager/intern/wm_files.c +++ b/source/blender/windowmanager/intern/wm_files.c @@ -887,11 +887,11 @@ static void file_read_reports_finalize(BlendFileReadReport *bf_reports) bf_reports->count.linked_proxies); } - if (bf_reports->count.vse_strips_skipped != 0) { + if (bf_reports->count.sequence_strips_skipped != 0) { BKE_reportf(bf_reports->reports, RPT_ERROR, "%d sequence strips were not read because they were in a channel larger than %d", - bf_reports->count.vse_strips_skipped, + bf_reports->count.sequence_strips_skipped, MAXSEQ); } @@ -1558,15 +1558,16 @@ static void wm_history_file_update(void) * Screen-shot the active window. * \{ */ -static ImBuf *blend_file_thumb_from_screenshot(bContext *C, BlendThumbnail **thumb_pt) +static ImBuf *blend_file_thumb_from_screenshot(bContext *C, BlendThumbnail **r_thumb) { - if (*thumb_pt) { - /* We are given a valid thumbnail data, so just generate image from it. */ - return BKE_main_thumbnail_to_imbuf(NULL, *thumb_pt); + *r_thumb = NULL; + + wmWindow *win = CTX_wm_window(C); + if (G.background || (win == NULL)) { + return NULL; } /* The window to capture should be a main window (without parent). */ - wmWindow *win = CTX_wm_window(C); while (win && win->parent) { win = win->parent; } @@ -1595,7 +1596,7 @@ static ImBuf *blend_file_thumb_from_screenshot(bContext *C, BlendThumbnail **thu BlendThumbnail *thumb = BKE_main_thumbnail_from_imbuf(NULL, thumb_ibuf); IMB_freeImBuf(thumb_ibuf); - *thumb_pt = thumb; + *r_thumb = thumb; } /* Must be freed by caller. */ @@ -1614,8 +1615,15 @@ static ImBuf *blend_file_thumb_from_screenshot(bContext *C, BlendThumbnail **thu static ImBuf *blend_file_thumb_from_camera(const bContext *C, Scene *scene, bScreen *screen, - BlendThumbnail **thumb_pt) + BlendThumbnail **r_thumb) { + *r_thumb = NULL; + + /* Scene can be NULL if running a script at startup and calling the save operator. */ + if (G.background || scene == NULL) { + return NULL; + } + /* will be scaled down, but gives some nice oversampling */ ImBuf *ibuf; BlendThumbnail *thumb; @@ -1629,17 +1637,6 @@ static ImBuf *blend_file_thumb_from_camera(const bContext *C, ARegion *region = NULL; View3D *v3d = NULL; - /* In case we are given a valid thumbnail data, just generate image from it. */ - if (*thumb_pt) { - thumb = *thumb_pt; - return BKE_main_thumbnail_to_imbuf(NULL, thumb); - } - - /* scene can be NULL if running a script at startup and calling the save operator */ - if (G.background || scene == NULL) { - return NULL; - } - if (screen != NULL) { area = BKE_screen_find_big_area(screen, SPACE_VIEW3D, 0); if (area) { @@ -1713,13 +1710,13 @@ static ImBuf *blend_file_thumb_from_camera(const bContext *C, IMB_scaleImBuf(ibuf, PREVIEW_RENDER_LARGE_HEIGHT, PREVIEW_RENDER_LARGE_HEIGHT); } else { - /* '*thumb_pt' needs to stay NULL to prevent a bad thumbnail from being handled */ + /* '*r_thumb' needs to stay NULL to prevent a bad thumbnail from being handled. */ CLOG_WARN(&LOG, "failed to create thumbnail: %s", err_out); thumb = NULL; } /* must be freed by caller */ - *thumb_pt = thumb; + *r_thumb = thumb; return ibuf; } @@ -1752,7 +1749,7 @@ static bool wm_file_write(bContext *C, Main *bmain = CTX_data_main(C); int len; int ok = false; - BlendThumbnail *thumb, *main_thumb; + BlendThumbnail *thumb = NULL, *main_thumb = NULL; ImBuf *ibuf_thumb = NULL; len = strlen(filepath); @@ -1802,33 +1799,42 @@ static bool wm_file_write(bContext *C, /* don't forget not to return without! */ WM_cursor_wait(true); - /* blend file thumbnail */ - /* Save before exit_editmode, otherwise derivedmeshes for shared data corrupt T27765. */ - /* Main now can store a '.blend' thumbnail, useful for background mode - * or thumbnail customization. */ - main_thumb = thumb = bmain->blen_thumb; - if (BLI_thread_is_main() && U.file_preview_type != USER_FILE_PREVIEW_NONE) { - - int file_preview_type = U.file_preview_type; - - if (file_preview_type == USER_FILE_PREVIEW_AUTO) { - Scene *scene = CTX_data_scene(C); - bool do_render = (scene != NULL && scene->camera != NULL && - (BKE_screen_find_big_area(CTX_wm_screen(C), SPACE_VIEW3D, 0) != NULL)); - file_preview_type = do_render ? USER_FILE_PREVIEW_CAMERA : USER_FILE_PREVIEW_SCREENSHOT; - } - - switch (file_preview_type) { - case USER_FILE_PREVIEW_SCREENSHOT: { - ibuf_thumb = blend_file_thumb_from_screenshot(C, &thumb); - break; + if (U.file_preview_type != USER_FILE_PREVIEW_NONE) { + /* Blend file thumbnail. + * + * - Save before exiting edit-mode, otherwise evaluated-mesh for shared data gets corrupted. + * See T27765. + * - Main can store a '.blend' thumbnail, + * useful for background-mode or thumbnail customization. + */ + main_thumb = thumb = bmain->blen_thumb; + if (thumb != NULL) { + /* In case we are given a valid thumbnail data, just generate image from it. */ + ibuf_thumb = BKE_main_thumbnail_to_imbuf(NULL, thumb); + } + else if (BLI_thread_is_main()) { + int file_preview_type = U.file_preview_type; + + if (file_preview_type == USER_FILE_PREVIEW_AUTO) { + Scene *scene = CTX_data_scene(C); + bool do_render = (scene != NULL && scene->camera != NULL && + (BKE_screen_find_big_area(CTX_wm_screen(C), SPACE_VIEW3D, 0) != NULL)); + file_preview_type = do_render ? USER_FILE_PREVIEW_CAMERA : USER_FILE_PREVIEW_SCREENSHOT; } - case USER_FILE_PREVIEW_CAMERA: { - ibuf_thumb = blend_file_thumb_from_camera(C, CTX_data_scene(C), CTX_wm_screen(C), &thumb); - break; + + switch (file_preview_type) { + case USER_FILE_PREVIEW_SCREENSHOT: { + ibuf_thumb = blend_file_thumb_from_screenshot(C, &thumb); + break; + } + case USER_FILE_PREVIEW_CAMERA: { + ibuf_thumb = blend_file_thumb_from_camera( + C, CTX_data_scene(C), CTX_wm_screen(C), &thumb); + break; + } + default: + BLI_assert_unreachable(); } - default: - BLI_assert_unreachable(); } } diff --git a/source/blender/windowmanager/intern/wm_playanim.c b/source/blender/windowmanager/intern/wm_playanim.c index a41fa94e8c2..640fef82085 100644 --- a/source/blender/windowmanager/intern/wm_playanim.c +++ b/source/blender/windowmanager/intern/wm_playanim.c @@ -1570,7 +1570,7 @@ static char *wm_main_playanim_intern(int argc, const char **argv) /* initialize the font */ BLF_init(); ps.fontid = BLF_load_mono_default(false); - BLF_size(ps.fontid, 11, 72); + BLF_size(ps.fontid, 11.0f, 72); ps.ibufx = ibuf->x; ps.ibufy = ibuf->y; diff --git a/source/blender/windowmanager/xr/intern/wm_xr_operators.c b/source/blender/windowmanager/xr/intern/wm_xr_operators.c index 112312bab7b..f3470edf2f7 100644 --- a/source/blender/windowmanager/xr/intern/wm_xr_operators.c +++ b/source/blender/windowmanager/xr/intern/wm_xr_operators.c @@ -432,10 +432,10 @@ static bool wm_xr_navigation_grab_can_do_bimanual(const wmXrActionData *actionda const XrGrabData *data) { /* Returns true if: 1) Bimanual interaction is currently occurring (i.e. inputs on both - controllers are pressed) and 2) bimanual interaction occurred on the last update. This second - part is needed to avoid "jumpy" navigation changes when transitioning from one-handed to - two-handed interaction (see #wm_xr_grab_compute/compute_bimanual() for how navigation deltas - are calculated). */ + * controllers are pressed) and 2) bimanual interaction occurred on the last update. This second + * part is needed to avoid "jumpy" navigation changes when transitioning from one-handed to + * two-handed interaction (see #wm_xr_grab_compute/compute_bimanual() for how navigation deltas + * are calculated). */ return (actiondata->bimanual && data->bimanual_prev); } @@ -545,7 +545,7 @@ static int wm_xr_navigation_grab_modal(bContext *C, wmOperator *op, const wmEven /* Check if navigation is locked. */ if (!wm_xr_navigation_grab_is_locked(data, do_bimanual)) { /* Prevent unwanted snapping (i.e. "jumpy" navigation changes when transitioning from - two-handed to one-handed interaction) at the end of a bimanual interaction. */ + * two-handed to one-handed interaction) at the end of a bimanual interaction. */ if (!wm_xr_navigation_grab_is_bimanual_ending(actiondata, data)) { wm_xr_navigation_grab_apply(xr, actiondata, data, do_bimanual); } @@ -554,9 +554,9 @@ static int wm_xr_navigation_grab_modal(bContext *C, wmOperator *op, const wmEven wm_xr_navigation_grab_bimanual_state_update(actiondata, data); /* Note: KM_PRESS and KM_RELEASE are the only two values supported by XR events during event - dispatching (see #wm_xr_session_action_states_interpret()). For modal XR operators, modal - handling starts when an input is "pressed" (action state exceeds the action threshold) and - ends when the input is "released" (state falls below the threshold). */ + * dispatching (see #wm_xr_session_action_states_interpret()). For modal XR operators, modal + * handling starts when an input is "pressed" (action state exceeds the action threshold) and + * ends when the input is "released" (state falls below the threshold). */ switch (event->val) { case KM_PRESS: return OPERATOR_RUNNING_MODAL; |