diff options
Diffstat (limited to 'source/blender/blenkernel/intern')
43 files changed, 713 insertions, 560 deletions
diff --git a/source/blender/blenkernel/intern/DerivedMesh.cc b/source/blender/blenkernel/intern/DerivedMesh.cc index 933cddfdf1b..ba8cf8debe9 100644 --- a/source/blender/blenkernel/intern/DerivedMesh.cc +++ b/source/blender/blenkernel/intern/DerivedMesh.cc @@ -1976,7 +1976,7 @@ static void editbmesh_build_data(struct Depsgraph *depsgraph, BKE_sculpt_update_object_before_eval(obedit); } - BKE_editmesh_free_derivedmesh(em); + BKE_editmesh_free_derived_caches(em); Mesh *me_cage; Mesh *me_final; diff --git a/source/blender/blenkernel/intern/action.c b/source/blender/blenkernel/intern/action.c index 13ca5ecf23c..d55f023d209 100644 --- a/source/blender/blenkernel/intern/action.c +++ b/source/blender/blenkernel/intern/action.c @@ -497,9 +497,8 @@ void action_groups_add_channel(bAction *act, bActionGroup *agrp, FCurve *fcurve) } /* Reconstruct group channel pointers. - * Assumes that the channels are still in the proper order, i.e. that channels of the same group - * are adjacent in the act->channels list. It also assumes that the groups - * referred to by the FCurves are already in act->groups. + * Assumes that the groups referred to by the FCurves are already in act->groups. + * Reorders the main channel list to match group order. */ void BKE_action_groups_reconstruct(bAction *act) { @@ -514,23 +513,30 @@ void BKE_action_groups_reconstruct(bAction *act) BLI_listbase_clear(&group->channels); } - bActionGroup *grp; - bActionGroup *last_grp = NULL; - LISTBASE_FOREACH (FCurve *, fcurve, &act->curves) { - if (fcurve->grp == NULL) { - continue; - } + /* Sort the channels into the group lists, destroying the act->curves list. */ + ListBase ungrouped = {NULL, NULL}; - grp = fcurve->grp; - if (last_grp != grp) { - /* If this is the first time we see this group, this must be the first channel. */ - grp->channels.first = fcurve; + LISTBASE_FOREACH_MUTABLE (FCurve *, fcurve, &act->curves) { + if (fcurve->grp) { + BLI_assert(BLI_findindex(&act->groups, fcurve->grp) >= 0); + + BLI_addtail(&fcurve->grp->channels, fcurve); + } + else { + BLI_addtail(&ungrouped, fcurve); } + } + + /* Recombine into the main list. */ + BLI_listbase_clear(&act->curves); - /* This is the last channel, until it's overwritten by a later iteration. */ - grp->channels.last = fcurve; - last_grp = grp; + LISTBASE_FOREACH (bActionGroup *, group, &act->groups) { + /* Copy the list header to preserve the pointers in the group. */ + ListBase tmp = group->channels; + BLI_movelisttolist(&act->curves, &tmp); } + + BLI_movelisttolist(&act->curves, &ungrouped); } /* Remove the given channel from all groups */ diff --git a/source/blender/blenkernel/intern/action_test.cc b/source/blender/blenkernel/intern/action_test.cc new file mode 100644 index 00000000000..c02eca966ad --- /dev/null +++ b/source/blender/blenkernel/intern/action_test.cc @@ -0,0 +1,144 @@ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2021 Blender Foundation + * All rights reserved. + */ + +#include "BKE_action.h" + +#include "DNA_action_types.h" +#include "DNA_anim_types.h" + +#include "BLI_listbase.h" + +#include "testing/testing.h" + +namespace blender::bke::tests { + +TEST(action_groups, ReconstructGroupsWithReordering) +{ + /* Construct an Action with three groups. */ + bAction action = {{nullptr}}; + FCurve groupAcurve1 = {nullptr}; + FCurve groupAcurve2 = {nullptr}; + FCurve groupBcurve1 = {nullptr}; + FCurve groupBcurve2 = {nullptr}; + FCurve groupBcurve3 = {nullptr}; + /* Group C has no curves intentionally. */ + FCurve groupDcurve1 = {nullptr}; + FCurve groupDcurve2 = {nullptr}; + + groupAcurve1.rna_path = (char *)"groupAcurve1"; + groupAcurve2.rna_path = (char *)"groupAcurve2"; + groupBcurve1.rna_path = (char *)"groupBcurve1"; + groupBcurve2.rna_path = (char *)"groupBcurve2"; + groupDcurve1.rna_path = (char *)"groupDcurve1"; + groupBcurve3.rna_path = (char *)"groupBcurve3"; + groupDcurve2.rna_path = (char *)"groupDcurve2"; + + BLI_addtail(&action.curves, &groupAcurve1); + BLI_addtail(&action.curves, &groupAcurve2); + BLI_addtail(&action.curves, &groupBcurve1); + BLI_addtail(&action.curves, &groupBcurve2); + BLI_addtail(&action.curves, &groupDcurve1); + BLI_addtail(&action.curves, &groupBcurve3); /* <-- The error that should be corrected. */ + BLI_addtail(&action.curves, &groupDcurve2); + + /* Introduce another error type, by changing some `prev` pointers. */ + groupBcurve1.prev = nullptr; + groupBcurve3.prev = &groupBcurve2; + groupDcurve1.prev = &groupBcurve3; + + bActionGroup groupA = {nullptr}; + bActionGroup groupB = {nullptr}; + bActionGroup groupC = {nullptr}; + bActionGroup groupD = {nullptr}; + strcpy(groupA.name, "groupA"); + strcpy(groupB.name, "groupB"); + strcpy(groupC.name, "groupC"); + strcpy(groupD.name, "groupD"); + + BLI_addtail(&action.groups, &groupA); + BLI_addtail(&action.groups, &groupB); + BLI_addtail(&action.groups, &groupC); + BLI_addtail(&action.groups, &groupD); + + groupAcurve1.grp = &groupA; + groupAcurve2.grp = &groupA; + groupBcurve1.grp = &groupB; + groupBcurve2.grp = &groupB; + groupBcurve3.grp = &groupB; + groupDcurve1.grp = &groupD; + groupDcurve2.grp = &groupD; + + groupA.channels.first = &groupAcurve1; + groupA.channels.last = &groupAcurve2; + groupB.channels.first = &groupBcurve1; + groupB.channels.last = &groupBcurve3; /* The last channel in group B, after group C curve 1. */ + groupD.channels.first = &groupDcurve1; + groupD.channels.last = &groupDcurve2; + + EXPECT_EQ(groupA.channels.first, &groupAcurve1); + EXPECT_EQ(groupA.channels.last, &groupAcurve2); + EXPECT_EQ(groupB.channels.first, &groupBcurve1); + EXPECT_EQ(groupB.channels.last, &groupBcurve3); + EXPECT_EQ(groupC.channels.first, nullptr); + EXPECT_EQ(groupC.channels.last, nullptr); + EXPECT_EQ(groupD.channels.first, &groupDcurve1); + EXPECT_EQ(groupD.channels.last, &groupDcurve2); + + BKE_action_groups_reconstruct(&action); + + EXPECT_EQ(action.curves.first, &groupAcurve1); + EXPECT_EQ(action.curves.last, &groupDcurve2); + + EXPECT_EQ(groupA.prev, nullptr); + EXPECT_EQ(groupB.prev, &groupA); + EXPECT_EQ(groupC.prev, &groupB); + EXPECT_EQ(groupD.prev, &groupC); + + EXPECT_EQ(groupA.next, &groupB); + EXPECT_EQ(groupB.next, &groupC); + EXPECT_EQ(groupC.next, &groupD); + EXPECT_EQ(groupD.next, nullptr); + + EXPECT_EQ(groupA.channels.first, &groupAcurve1); + EXPECT_EQ(groupA.channels.last, &groupAcurve2); + EXPECT_EQ(groupB.channels.first, &groupBcurve1); + EXPECT_EQ(groupB.channels.last, &groupBcurve3); + EXPECT_EQ(groupC.channels.first, nullptr); + EXPECT_EQ(groupC.channels.last, nullptr); + EXPECT_EQ(groupD.channels.first, &groupDcurve1); + EXPECT_EQ(groupD.channels.last, &groupDcurve2); + + EXPECT_EQ(groupAcurve1.prev, nullptr); + EXPECT_EQ(groupAcurve2.prev, &groupAcurve1); + EXPECT_EQ(groupBcurve1.prev, &groupAcurve2); + EXPECT_EQ(groupBcurve2.prev, &groupBcurve1); + EXPECT_EQ(groupBcurve3.prev, &groupBcurve2); + EXPECT_EQ(groupDcurve1.prev, &groupBcurve3); + EXPECT_EQ(groupDcurve2.prev, &groupDcurve1); + + EXPECT_EQ(groupAcurve1.next, &groupAcurve2); + EXPECT_EQ(groupAcurve2.next, &groupBcurve1); + EXPECT_EQ(groupBcurve1.next, &groupBcurve2); + EXPECT_EQ(groupBcurve2.next, &groupBcurve3); + EXPECT_EQ(groupBcurve3.next, &groupDcurve1); + EXPECT_EQ(groupDcurve1.next, &groupDcurve2); + EXPECT_EQ(groupDcurve2.next, nullptr); +} + +} // namespace blender::bke::tests diff --git a/source/blender/blenkernel/intern/anim_data.c b/source/blender/blenkernel/intern/anim_data.c index 7e5313f0e4a..7e4ab754500 100644 --- a/source/blender/blenkernel/intern/anim_data.c +++ b/source/blender/blenkernel/intern/anim_data.c @@ -89,16 +89,16 @@ bool id_can_have_animdata(const ID *id) return id_type_can_have_animdata(GS(id->name)); } -/* Get AnimData from the given ID-block. In order for this to work, we assume that - * the AnimData pointer is stored immediately after the given ID-block in the struct, - * as per IdAdtTemplate. +/** + * Get #AnimData from the given ID-block. */ AnimData *BKE_animdata_from_id(ID *id) { - /* only some ID-blocks have this info for now, so we cast the - * types that do to be of type IdAdtTemplate, and extract the - * AnimData that way - */ + /* In order for this to work, we assume that the #AnimData pointer is stored + * immediately after the given ID-block in the struct, as per IdAdtTemplate. */ + + /* Only some ID-blocks have this info for now, so we cast the types that do + * to be of type IdAdtTemplate, and add the AnimData to it using the template. */ if (id_can_have_animdata(id)) { IdAdtTemplate *iat = (IdAdtTemplate *)id; return iat->adt; @@ -106,16 +106,16 @@ AnimData *BKE_animdata_from_id(ID *id) return NULL; } -/* Add AnimData to the given ID-block. In order for this to work, we assume that - * the AnimData pointer is stored immediately after the given ID-block in the struct, - * as per IdAdtTemplate. Also note that +/** + * Ensure #AnimData exists in the given ID-block (when supported). */ -AnimData *BKE_animdata_add_id(ID *id) +AnimData *BKE_animdata_ensure_id(ID *id) { - /* Only some ID-blocks have this info for now, so we cast the - * types that do to be of type IdAdtTemplate, and add the AnimData - * to it using the template - */ + /* In order for this to work, we assume that the #AnimData pointer is stored + * immediately after the given ID-block in the struct, as per IdAdtTemplate. */ + + /* Only some ID-blocks have this info for now, so we cast the types that do + * to be of type IdAdtTemplate, and add the AnimData to it using the template. */ if (id_can_have_animdata(id)) { IdAdtTemplate *iat = (IdAdtTemplate *)id; @@ -444,7 +444,7 @@ void BKE_animdata_merge_copy( return; } - // TODO: we must unset all "tweakmode" flags + /* TODO: we must unset all "tweak-mode" flags. */ if ((src->flag & ADT_NLA_EDIT_ON) || (dst->flag & ADT_NLA_EDIT_ON)) { CLOG_ERROR( &LOG, @@ -667,7 +667,7 @@ void BKE_animdata_transfer_by_basepath(Main *bmain, ID *srcID, ID *dstID, ListBa /* get animdata from src, and create for destination (if needed) */ srcAdt = BKE_animdata_from_id(srcID); - dstAdt = BKE_animdata_add_id(dstID); + dstAdt = BKE_animdata_ensure_id(dstID); if (ELEM(NULL, srcAdt, dstAdt)) { if (G.debug & G_DEBUG) { @@ -1590,10 +1590,10 @@ void BKE_animdata_blend_read_data(BlendDataReader *reader, AnimData *adt) /* relink active track/strip - even though strictly speaking this should only be used * if we're in 'tweaking mode', we need to be able to have this loaded back for - * undo, but also since users may not exit tweakmode before saving (T24535) + * undo, but also since users may not exit tweak-mode before saving (T24535). */ /* TODO: it's not really nice that anyone should be able to save the file in this - * state, but it's going to be too hard to enforce this single case... */ + * state, but it's going to be too hard to enforce this single case. */ BLO_read_data_address(reader, &adt->act_track); BLO_read_data_address(reader, &adt->actstrip); } diff --git a/source/blender/blenkernel/intern/appdir.c b/source/blender/blenkernel/intern/appdir.c index 579f671e2b0..ebff6015df1 100644 --- a/source/blender/blenkernel/intern/appdir.c +++ b/source/blender/blenkernel/intern/appdir.c @@ -191,8 +191,7 @@ bool BKE_appdir_folder_documents(char *dir) { dir[0] = '\0'; - const char *documents_path = (const char *)GHOST_getUserSpecialDir( - GHOST_kUserSpecialDirDocuments); + const char *documents_path = GHOST_getUserSpecialDir(GHOST_kUserSpecialDirDocuments); /* Usual case: Ghost gave us the documents path. We're done here. */ if (documents_path && BLI_is_dir(documents_path)) { @@ -462,7 +461,7 @@ static bool get_path_user_ex(char *targetpath, } user_path[0] = '\0'; - user_base_path = (const char *)GHOST_getUserDir(version, blender_version_decimal(version)); + user_base_path = GHOST_getUserDir(version, blender_version_decimal(version)); if (user_base_path) { BLI_strncpy(user_path, user_base_path, FILE_MAX); } @@ -522,7 +521,7 @@ static bool get_path_system_ex(char *targetpath, } system_path[0] = '\0'; - system_base_path = (const char *)GHOST_getSystemDir(version, blender_version_decimal(version)); + system_base_path = GHOST_getSystemDir(version, blender_version_decimal(version)); if (system_base_path) { BLI_strncpy(system_path, system_base_path, FILE_MAX); } diff --git a/source/blender/blenkernel/intern/armature.c b/source/blender/blenkernel/intern/armature.c index 22d6cfba893..b8ed519e8d1 100644 --- a/source/blender/blenkernel/intern/armature.c +++ b/source/blender/blenkernel/intern/armature.c @@ -2843,7 +2843,7 @@ void BKE_pose_where_is(struct Depsgraph *depsgraph, Scene *scene, Object *ob) * hopefully this is OK. */ BKE_pose_ensure(NULL, ob, arm, true); - ctime = BKE_scene_frame_get(scene); /* not accurate... */ + ctime = BKE_scene_ctime_get(scene); /* not accurate... */ /* In edit-mode or rest-position we read the data from the bones. */ if (arm->edbo || (arm->flag & ARM_RESTPOS)) { diff --git a/source/blender/blenkernel/intern/armature_deform.c b/source/blender/blenkernel/intern/armature_deform.c index 2552b5eefea..5e9259f05bb 100644 --- a/source/blender/blenkernel/intern/armature_deform.c +++ b/source/blender/blenkernel/intern/armature_deform.c @@ -47,6 +47,7 @@ #include "BKE_action.h" #include "BKE_armature.h" +#include "BKE_customdata.h" #include "BKE_deform.h" #include "BKE_editmesh.h" #include "BKE_lattice.h" diff --git a/source/blender/blenkernel/intern/armature_update.c b/source/blender/blenkernel/intern/armature_update.c index 0f8956a1a91..35ae2d2dbef 100644 --- a/source/blender/blenkernel/intern/armature_update.c +++ b/source/blender/blenkernel/intern/armature_update.c @@ -562,7 +562,7 @@ static void splineik_evaluate_bone( * spline dictates, while still maintaining roll control from the existing bone animation. */ mul_m3_m3m3(pose_mat, dmat, rmat); - /* Attempt to reduce shearing, though I doubt this'll really help too much now... */ + /* Attempt to reduce shearing, though I doubt this will really help too much now. */ normalize_m3(pose_mat); mul_m3_m3m3(base_pose_mat, dmat, base_pose_mat); @@ -828,7 +828,7 @@ void BKE_pose_eval_init_ik(struct Depsgraph *depsgraph, Scene *scene, Object *ob { DEG_debug_print_eval(depsgraph, __func__, object->id.name, object); BLI_assert(object->type == OB_ARMATURE); - const float ctime = BKE_scene_frame_get(scene); /* not accurate... */ + const float ctime = BKE_scene_ctime_get(scene); /* not accurate... */ bArmature *armature = (bArmature *)object->data; if (armature->flag & ARM_RESTPOS) { return; @@ -869,7 +869,7 @@ void BKE_pose_eval_bone(struct Depsgraph *depsgraph, Scene *scene, Object *objec else { if ((pchan->flag & POSE_DONE) == 0) { /* TODO(sergey): Use time source node for time. */ - float ctime = BKE_scene_frame_get(scene); /* not accurate... */ + float ctime = BKE_scene_ctime_get(scene); /* not accurate... */ BKE_pose_where_is_bone(depsgraph, scene, object, pchan, ctime, 1); } } @@ -897,7 +897,7 @@ void BKE_pose_constraints_evaluate(struct Depsgraph *depsgraph, } else { if ((pchan->flag & POSE_DONE) == 0) { - float ctime = BKE_scene_frame_get(scene); /* not accurate... */ + float ctime = BKE_scene_ctime_get(scene); /* not accurate... */ BKE_pose_where_is_bone(depsgraph, scene, object, pchan, ctime, 1); } } @@ -981,7 +981,7 @@ void BKE_pose_iktree_evaluate(struct Depsgraph *depsgraph, DEG_debug_print_eval_subdata( depsgraph, __func__, object->id.name, object, "rootchan", rootchan->name, rootchan); BLI_assert(object->type == OB_ARMATURE); - const float ctime = BKE_scene_frame_get(scene); /* not accurate... */ + const float ctime = BKE_scene_ctime_get(scene); /* not accurate... */ if (armature->flag & ARM_RESTPOS) { return; } @@ -1002,7 +1002,7 @@ void BKE_pose_splineik_evaluate(struct Depsgraph *depsgraph, DEG_debug_print_eval_subdata( depsgraph, __func__, object->id.name, object, "rootchan", rootchan->name, rootchan); BLI_assert(object->type == OB_ARMATURE); - const float ctime = BKE_scene_frame_get(scene); /* not accurate... */ + const float ctime = BKE_scene_ctime_get(scene); /* not accurate... */ if (armature->flag & ARM_RESTPOS) { return; } @@ -1031,7 +1031,7 @@ void BKE_pose_eval_cleanup(struct Depsgraph *depsgraph, Scene *scene, Object *ob bPose *pose = object->pose; BLI_assert(pose != NULL); UNUSED_VARS_NDEBUG(pose); - const float ctime = BKE_scene_frame_get(scene); /* not accurate... */ + const float ctime = BKE_scene_ctime_get(scene); /* not accurate... */ DEG_debug_print_eval(depsgraph, __func__, object->id.name, object); BLI_assert(object->type == OB_ARMATURE); /* Release the IK tree. */ diff --git a/source/blender/blenkernel/intern/blendfile.c b/source/blender/blenkernel/intern/blendfile.c index f31d8f5ade7..912cc66920e 100644 --- a/source/blender/blenkernel/intern/blendfile.c +++ b/source/blender/blenkernel/intern/blendfile.c @@ -128,7 +128,7 @@ static void setup_app_userdef(BlendFileData *bfd) } /** - * Context matching, handle no-ui case + * Context matching, handle no-UI case. * * \note this is called on Undo so any slow conversion functions here * should be avoided or check (mode != LOAD_UNDO). diff --git a/source/blender/blenkernel/intern/bvhutils.cc b/source/blender/blenkernel/intern/bvhutils.cc index 0284b20d98e..164f921c7ac 100644 --- a/source/blender/blenkernel/intern/bvhutils.cc +++ b/source/blender/blenkernel/intern/bvhutils.cc @@ -1290,9 +1290,9 @@ BVHTree *bvhtree_from_editmesh_looptri( } /** - * Builds a bvh tree where nodes are the looptri faces of the given dm + * Builds a BVH-tree where nodes are the looptri faces of the given mesh. * - * \note for editmesh this is currently a duplicate of bvhtree_from_mesh_faces_ex + * \note for edit-mesh this is currently a duplicate of #bvhtree_from_mesh_faces_ex */ BVHTree *bvhtree_from_mesh_looptri_ex(BVHTreeFromMesh *data, const struct MVert *vert, diff --git a/source/blender/blenkernel/intern/cachefile.c b/source/blender/blenkernel/intern/cachefile.c index 30e9ae39b67..eaba5d33a20 100644 --- a/source/blender/blenkernel/intern/cachefile.c +++ b/source/blender/blenkernel/intern/cachefile.c @@ -314,7 +314,7 @@ bool BKE_cachefile_filepath_get(const Main *bmain, if (cache_file->is_sequence && BLI_path_frame_get(r_filepath, &fframe, &frame_len)) { Scene *scene = DEG_get_evaluated_scene(depsgraph); - const float ctime = BKE_scene_frame_get(scene); + const float ctime = BKE_scene_ctime_get(scene); const float fps = (((double)scene->r.frs_sec) / (double)scene->r.frs_sec_base); const float frame = BKE_cachefile_time_offset(cache_file, ctime, fps); diff --git a/source/blender/blenkernel/intern/cloth.c b/source/blender/blenkernel/intern/cloth.c index 2bca3f5da76..8678a659c0a 100644 --- a/source/blender/blenkernel/intern/cloth.c +++ b/source/blender/blenkernel/intern/cloth.c @@ -597,7 +597,7 @@ static void cloth_to_object(Object *ob, ClothModifierData *clmd, float (*vertexC Cloth *cloth = clmd->clothObject; if (clmd->clothObject) { - /* inverse matrix is not uptodate... */ + /* Inverse matrix is not up to date. */ invert_m4_m4(ob->imat, ob->obmat); for (i = 0; i < cloth->mvert_num; i++) { diff --git a/source/blender/blenkernel/intern/collection.c b/source/blender/blenkernel/intern/collection.c index 39698bde622..cf32bc15962 100644 --- a/source/blender/blenkernel/intern/collection.c +++ b/source/blender/blenkernel/intern/collection.c @@ -888,7 +888,7 @@ Collection *BKE_collection_master_add() { /* Not an actual datablock, but owned by scene. */ Collection *master_collection = BKE_libblock_alloc( - NULL, ID_GR, "Master Collection", LIB_ID_CREATE_NO_MAIN); + NULL, ID_GR, BKE_SCENE_COLLECTION_NAME, LIB_ID_CREATE_NO_MAIN); master_collection->id.flag |= LIB_EMBEDDED_DATA; master_collection->flag |= COLLECTION_IS_MASTER; master_collection->color_tag = COLLECTION_COLOR_NONE; diff --git a/source/blender/blenkernel/intern/crazyspace.c b/source/blender/blenkernel/intern/crazyspace.c index 4e1ec9ba35e..26894495777 100644 --- a/source/blender/blenkernel/intern/crazyspace.c +++ b/source/blender/blenkernel/intern/crazyspace.c @@ -398,8 +398,7 @@ int BKE_sculpt_get_first_deform_matrices(struct Depsgraph *depsgraph, if (crazyspace_modifier_supports_deform_matrices(md)) { const ModifierTypeInfo *mti = BKE_modifier_get_info(md->type); if (defmats == NULL) { - /* NOTE: Evaluated object si re-set to its original undeformed - * state. */ + /* NOTE: Evaluated object is re-set to its original un-deformed state. */ Mesh *me = object_eval.data; me_eval = BKE_mesh_copy_for_eval(me, true); crazyspace_init_verts_and_matrices(me_eval, &defmats, &deformedVerts); diff --git a/source/blender/blenkernel/intern/dynamicpaint.c b/source/blender/blenkernel/intern/dynamicpaint.c index 8dac20f6fe9..52996e3bcc7 100644 --- a/source/blender/blenkernel/intern/dynamicpaint.c +++ b/source/blender/blenkernel/intern/dynamicpaint.c @@ -248,7 +248,7 @@ typedef struct PaintAdjData { int *n_target; /** Index to start reading n_target for each point. */ int *n_index; - /** Num of neighs for each point. */ + /** Number of neighbors for each point. */ int *n_num; /** Vertex adjacency flags. */ int *flags; @@ -3818,7 +3818,7 @@ static void dynamicPaint_brushMeshCalculateVelocity(Depsgraph *depsgraph, ob, true, SUBFRAME_RECURSION, - BKE_scene_frame_get(scene), + BKE_scene_ctime_get(scene), eModifierType_DynamicPaint); mesh_p = BKE_mesh_copy_for_eval(dynamicPaint_brush_mesh_get(brush), false); numOfVerts_p = mesh_p->totvert; @@ -3834,7 +3834,7 @@ static void dynamicPaint_brushMeshCalculateVelocity(Depsgraph *depsgraph, ob, true, SUBFRAME_RECURSION, - BKE_scene_frame_get(scene), + BKE_scene_ctime_get(scene), eModifierType_DynamicPaint); mesh_c = dynamicPaint_brush_mesh_get(brush); numOfVerts_c = mesh_c->totvert; @@ -3894,7 +3894,7 @@ static void dynamicPaint_brushObjectCalculateVelocity( ob, false, SUBFRAME_RECURSION, - BKE_scene_frame_get(scene), + BKE_scene_ctime_get(scene), eModifierType_DynamicPaint); copy_m4_m4(prev_obmat, ob->obmat); @@ -3906,7 +3906,7 @@ static void dynamicPaint_brushObjectCalculateVelocity( ob, false, SUBFRAME_RECURSION, - BKE_scene_frame_get(scene), + BKE_scene_ctime_get(scene), eModifierType_DynamicPaint); /* calculate speed */ @@ -6271,7 +6271,7 @@ static int dynamicPaint_doStep(Depsgraph *depsgraph, brushObj, true, SUBFRAME_RECURSION, - BKE_scene_frame_get(scene), + BKE_scene_ctime_get(scene), eModifierType_DynamicPaint); } @@ -6312,7 +6312,7 @@ static int dynamicPaint_doStep(Depsgraph *depsgraph, brushObj, true, SUBFRAME_RECURSION, - BKE_scene_frame_get(scene), + BKE_scene_ctime_get(scene), eModifierType_DynamicPaint); } diff --git a/source/blender/blenkernel/intern/editmesh.c b/source/blender/blenkernel/intern/editmesh.c index 2eb6b488da2..9cae74e4e9a 100644 --- a/source/blender/blenkernel/intern/editmesh.c +++ b/source/blender/blenkernel/intern/editmesh.c @@ -39,15 +39,14 @@ #include "BKE_mesh_wrapper.h" #include "BKE_object.h" -BMEditMesh *BKE_editmesh_create(BMesh *bm, const bool do_tessellate) +/** + * \note The caller is responsible for ensuring triangulation data, + * typically by calling #BKE_editmesh_looptri_calc. + */ +BMEditMesh *BKE_editmesh_create(BMesh *bm) { BMEditMesh *em = MEM_callocN(sizeof(BMEditMesh), __func__); - em->bm = bm; - if (do_tessellate) { - BKE_editmesh_looptri_calc(em); - } - return em; } @@ -209,7 +208,7 @@ void BKE_editmesh_looptri_and_normals_calc_with_partial(BMEditMesh *em, }); } -void BKE_editmesh_free_derivedmesh(BMEditMesh *em) +void BKE_editmesh_free_derived_caches(BMEditMesh *em) { if (em->mesh_eval_cage) { BKE_id_free(NULL, em->mesh_eval_cage); @@ -223,9 +222,9 @@ void BKE_editmesh_free_derivedmesh(BMEditMesh *em) } /* Does not free the #BMEditMesh struct itself. */ -void BKE_editmesh_free(BMEditMesh *em) +void BKE_editmesh_free_data(BMEditMesh *em) { - BKE_editmesh_free_derivedmesh(em); + BKE_editmesh_free_derived_caches(em); if (em->looptris) { MEM_freeN(em->looptris); diff --git a/source/blender/blenkernel/intern/editmesh_tangent.c b/source/blender/blenkernel/intern/editmesh_tangent.c index e5e639fa3f1..da4ea742656 100644 --- a/source/blender/blenkernel/intern/editmesh_tangent.c +++ b/source/blender/blenkernel/intern/editmesh_tangent.c @@ -25,6 +25,7 @@ #include "DNA_defs.h" #include "DNA_meshdata_types.h" +#include "BKE_customdata.h" #include "BKE_editmesh.h" #include "BKE_editmesh_tangent.h" #include "BKE_mesh.h" diff --git a/source/blender/blenkernel/intern/fluid.c b/source/blender/blenkernel/intern/fluid.c index 947417af55d..2b48683a3a8 100644 --- a/source/blender/blenkernel/intern/fluid.c +++ b/source/blender/blenkernel/intern/fluid.c @@ -1283,10 +1283,10 @@ static void compute_obstaclesemission(Scene *scene, # endif /* Update frame time, this is considering current subframe fraction * BLI_mutex_lock() called in manta_step(), so safe to update subframe here - * TODO(sebbas): Using BKE_scene_frame_get(scene) instead of new DEG_get_ctime(depsgraph) + * TODO(sebbas): Using BKE_scene_ctime_get(scene) instead of new DEG_get_ctime(depsgraph) * as subframes don't work with the latter yet. */ BKE_object_modifier_update_subframe( - depsgraph, scene, effecobj, true, 5, BKE_scene_frame_get(scene), eModifierType_Fluid); + depsgraph, scene, effecobj, true, 5, BKE_scene_ctime_get(scene), eModifierType_Fluid); if (subframes) { obstacles_from_mesh(effecobj, fds, fes, &bb_temp, subframe_dt); @@ -1616,7 +1616,7 @@ static void emit_from_particles(Object *flow_ob, } /* `DEG_get_ctime(depsgraph)` does not give sub-frame time. */ - state.time = BKE_scene_frame_get(scene); + state.time = BKE_scene_ctime_get(scene); if (psys_get_particle_state(&sim, p, &state, 0) == 0) { continue; @@ -2820,10 +2820,10 @@ static void compute_flowsemission(Scene *scene, # endif /* Update frame time, this is considering current subframe fraction * BLI_mutex_lock() called in manta_step(), so safe to update subframe here - * TODO(sebbas): Using BKE_scene_frame_get(scene) instead of new DEG_get_ctime(depsgraph) + * TODO(sebbas): Using BKE_scene_ctime_get(scene) instead of new DEG_get_ctime(depsgraph) * as subframes don't work with the latter yet. */ BKE_object_modifier_update_subframe( - depsgraph, scene, flowobj, true, 5, BKE_scene_frame_get(scene), eModifierType_Fluid); + depsgraph, scene, flowobj, true, 5, BKE_scene_ctime_get(scene), eModifierType_Fluid); /* Emission from particles. */ if (ffs->source == FLUID_FLOW_SOURCE_PARTICLES) { diff --git a/source/blender/blenkernel/intern/gpencil.c b/source/blender/blenkernel/intern/gpencil.c index 1a880b0c427..529096b8523 100644 --- a/source/blender/blenkernel/intern/gpencil.c +++ b/source/blender/blenkernel/intern/gpencil.c @@ -2703,19 +2703,57 @@ static bool gpencil_is_layer_mask(ViewLayer *view_layer, bGPdata *gpd, bGPDlayer } /* -------------------------------------------------------------------- */ -/** \name Iterators +/** \name Iterator * - * Iterate over all visible stroke of all visible layers inside a gpObject. - * Also take into account onion-skinning. + * Iterate over all visible stroke of all visible layers inside a grease pencil datablock. * \{ */ -void BKE_gpencil_visible_stroke_iter(ViewLayer *view_layer, - Object *ob, +void BKE_gpencil_visible_stroke_iter(bGPdata *gpd, gpIterCb layer_cb, gpIterCb stroke_cb, - void *thunk, - bool do_onion, - int cfra) + void *thunk) +{ + LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) { + + if (gpl->flag & GP_LAYER_HIDE) { + continue; + } + + /* If scale to 0 the layer must be invisible. */ + if (is_zero_v3(gpl->scale)) { + continue; + } + + bGPDframe *act_gpf = gpl->actframe; + if (layer_cb) { + layer_cb(gpl, act_gpf, NULL, thunk); + } + + if (act_gpf) { + LISTBASE_FOREACH (bGPDstroke *, gps, &act_gpf->strokes) { + if (gps->totpoints == 0) { + continue; + } + stroke_cb(gpl, act_gpf, gps, thunk); + } + } + } +} + +/* -------------------------------------------------------------------- */ +/** \name Advanced Iterator + * + * Iterate over all visible stroke of all visible layers inside a gpObject. + * Also take into account onion-skinning. + * \{ */ + +void BKE_gpencil_visible_stroke_advanced_iter(ViewLayer *view_layer, + Object *ob, + gpIterCb layer_cb, + gpIterCb stroke_cb, + void *thunk, + bool do_onion, + int cfra) { bGPdata *gpd = (bGPdata *)ob->data; const bool is_multiedit = ((GPENCIL_MULTIEDIT_SESSIONS_ON(gpd)) && (!GPENCIL_PLAY_ON(gpd))); diff --git a/source/blender/blenkernel/intern/ipo.c b/source/blender/blenkernel/intern/ipo.c index a1f82b1dcb6..8a70f065e40 100644 --- a/source/blender/blenkernel/intern/ipo.c +++ b/source/blender/blenkernel/intern/ipo.c @@ -2087,7 +2087,7 @@ void do_versions_ipos_to_animato(Main *bmain) /* check if object has any animation data */ if (ob->nlastrips.first) { /* Add AnimData block */ - BKE_animdata_add_id(id); + BKE_animdata_ensure_id(id); /* IPO first to take into any non-NLA'd Object Animation */ if (ob->ipo) { @@ -2109,7 +2109,7 @@ void do_versions_ipos_to_animato(Main *bmain) } else if ((ob->ipo) || (ob->action)) { /* Add AnimData block */ - AnimData *adt = BKE_animdata_add_id(id); + AnimData *adt = BKE_animdata_ensure_id(id); /* Action first - so that Action name get conserved */ if (ob->action) { @@ -2133,7 +2133,7 @@ void do_versions_ipos_to_animato(Main *bmain) /* check PoseChannels for constraints with local data */ if (ob->pose) { /* Verify if there's AnimData block */ - BKE_animdata_add_id(id); + BKE_animdata_ensure_id(id); for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) { for (con = pchan->constraints.first; con; con = con->next) { @@ -2159,7 +2159,7 @@ void do_versions_ipos_to_animato(Main *bmain) */ if (con->ipo) { /* Verify if there's AnimData block, just in case */ - BKE_animdata_add_id(id); + BKE_animdata_ensure_id(id); /* although this was the constraint's local IPO, we still need to provide con * so that drivers can be added properly... @@ -2176,7 +2176,7 @@ void do_versions_ipos_to_animato(Main *bmain) /* check constraint channels - we need to remove them anyway... */ if (ob->constraintChannels.first) { /* Verify if there's AnimData block */ - BKE_animdata_add_id(id); + BKE_animdata_ensure_id(id); for (conchan = ob->constraintChannels.first; conchan; conchan = conchann) { /* get pointer to next Constraint Channel */ @@ -2217,7 +2217,7 @@ void do_versions_ipos_to_animato(Main *bmain) */ if (key->ipo) { /* Add AnimData block */ - AnimData *adt = BKE_animdata_add_id(id); + AnimData *adt = BKE_animdata_ensure_id(id); /* Convert Shapekey data... */ ipo_to_animdata(bmain, id, key->ipo, NULL, NULL, NULL); @@ -2242,7 +2242,7 @@ void do_versions_ipos_to_animato(Main *bmain) /* we're only interested in the IPO */ if (ma->ipo) { /* Add AnimData block */ - AnimData *adt = BKE_animdata_add_id(id); + AnimData *adt = BKE_animdata_ensure_id(id); /* Convert Material data... */ ipo_to_animdata(bmain, id, ma->ipo, NULL, NULL, NULL); @@ -2267,7 +2267,7 @@ void do_versions_ipos_to_animato(Main *bmain) /* we're only interested in the IPO */ if (wo->ipo) { /* Add AnimData block */ - AnimData *adt = BKE_animdata_add_id(id); + AnimData *adt = BKE_animdata_ensure_id(id); /* Convert World data... */ ipo_to_animdata(bmain, id, wo->ipo, NULL, NULL, NULL); @@ -2288,7 +2288,7 @@ void do_versions_ipos_to_animato(Main *bmain) if (ed && ed->seqbasep) { Sequence *seq; - AnimData *adt = BKE_animdata_add_id(id); + AnimData *adt = BKE_animdata_ensure_id(id); SEQ_ALL_BEGIN (ed, seq) { IpoCurve *icu = (seq->ipo) ? seq->ipo->curve.first : NULL; @@ -2346,7 +2346,7 @@ void do_versions_ipos_to_animato(Main *bmain) /* we're only interested in the IPO */ if (te->ipo) { /* Add AnimData block */ - AnimData *adt = BKE_animdata_add_id(id); + AnimData *adt = BKE_animdata_ensure_id(id); /* Convert Texture data... */ ipo_to_animdata(bmain, id, te->ipo, NULL, NULL, NULL); @@ -2371,7 +2371,7 @@ void do_versions_ipos_to_animato(Main *bmain) /* we're only interested in the IPO */ if (ca->ipo) { /* Add AnimData block */ - AnimData *adt = BKE_animdata_add_id(id); + AnimData *adt = BKE_animdata_ensure_id(id); /* Convert Camera data... */ ipo_to_animdata(bmain, id, ca->ipo, NULL, NULL, NULL); @@ -2396,7 +2396,7 @@ void do_versions_ipos_to_animato(Main *bmain) /* we're only interested in the IPO */ if (la->ipo) { /* Add AnimData block */ - AnimData *adt = BKE_animdata_add_id(id); + AnimData *adt = BKE_animdata_ensure_id(id); /* Convert Light data... */ ipo_to_animdata(bmain, id, la->ipo, NULL, NULL, NULL); @@ -2421,7 +2421,7 @@ void do_versions_ipos_to_animato(Main *bmain) /* we're only interested in the IPO */ if (cu->ipo) { /* Add AnimData block */ - AnimData *adt = BKE_animdata_add_id(id); + AnimData *adt = BKE_animdata_ensure_id(id); /* Convert Curve data... */ ipo_to_animdata(bmain, id, cu->ipo, NULL, NULL, NULL); diff --git a/source/blender/blenkernel/intern/lattice_deform.c b/source/blender/blenkernel/intern/lattice_deform.c index 1856a08e198..f9437eeaffa 100644 --- a/source/blender/blenkernel/intern/lattice_deform.c +++ b/source/blender/blenkernel/intern/lattice_deform.c @@ -108,7 +108,7 @@ LatticeDeformData *BKE_lattice_deform_data_create(const Object *oblatt, const Ob invert_m4_m4(imat, latmat); } - /* Prefetch latice deform group weights. */ + /* Prefetch lattice deform group weights. */ int defgrp_index = -1; const MDeformVert *dvert = BKE_lattice_deform_verts_get(oblatt); if (lt->vgroup[0] && dvert) { diff --git a/source/blender/blenkernel/intern/layer_utils.c b/source/blender/blenkernel/intern/layer_utils.c index 10ab0a06dd0..48179e0c3bf 100644 --- a/source/blender/blenkernel/intern/layer_utils.c +++ b/source/blender/blenkernel/intern/layer_utils.c @@ -23,6 +23,7 @@ #include "BLI_array.h" #include "BKE_collection.h" +#include "BKE_customdata.h" #include "BKE_editmesh.h" #include "BKE_layer.h" diff --git a/source/blender/blenkernel/intern/lib_id.c b/source/blender/blenkernel/intern/lib_id.c index c00fba852ef..9d0349a7e89 100644 --- a/source/blender/blenkernel/intern/lib_id.c +++ b/source/blender/blenkernel/intern/lib_id.c @@ -1642,9 +1642,8 @@ static bool check_for_dupid(ListBase *lb, ID *id, char *name, ID **r_id_sorting_ * already. */ if (!is_orig_name_used) { - /* Don't bother updating prev_ static variables here, this case is not supposed to happen - * that often, and is not straight-forward here, so just ignore and reset them to default. - */ + /* Don't bother updating `prev_*` static variables here, this case is not supposed to happen + * that often, and is not straight-forward here, so just ignore and reset them to default. */ prev_id_type = ID_LINK_PLACEHOLDER; prev_final_base_name[0] = '\0'; prev_number = MIN_NUMBER - 1; @@ -1684,7 +1683,7 @@ static bool check_for_dupid(ListBase *lb, ID *id, char *name, ID **r_id_sorting_ continue; } - /* Update prev_ static variables, in case next call is for the same type of IDs and with the + /* Update `prev_*` static variables, in case next call is for the same type of IDs and with the * same initial base name, we can skip a lot of above process. */ prev_id_type = id_type; strcpy(prev_final_base_name, base_name); diff --git a/source/blender/blenkernel/intern/mesh_boolean_convert.cc b/source/blender/blenkernel/intern/mesh_boolean_convert.cc index 9bfb01a257c..798d9562150 100644 --- a/source/blender/blenkernel/intern/mesh_boolean_convert.cc +++ b/source/blender/blenkernel/intern/mesh_boolean_convert.cc @@ -38,6 +38,7 @@ #include "BLI_mesh_boolean.hh" #include "BLI_mesh_intersect.hh" #include "BLI_span.hh" +#include "BLI_task.hh" namespace blender::meshintersect { @@ -309,22 +310,38 @@ static IMesh meshes_to_imesh(Span<const Mesh *> meshes, clean_obmat(*obmats[mi]); r_info->to_target_transform[mi] = inv_target_mat * objn_mat; - /* Skip the matrix multiplication for each point when there is no transform for a mesh, - * for example when the first mesh is already in the target space. (Note the logic directly - * above, which uses an identity matrix with a null input transform). */ + Vector<Vert *> verts(me->totvert); + Span<MVert> mverts = Span(me->mvert, me->totvert); + + /* Allocate verts + * Skip the matrix multiplication for each point when there is no transform for a mesh, + * for example when the first mesh is already in the target space. (Note the logic + * directly above, which uses an identity matrix with a null input transform). */ if (obmats[mi] == nullptr) { - for (const MVert &vert : Span(me->mvert, me->totvert)) { - const float3 co = float3(vert.co); - r_info->mesh_to_imesh_vert[v] = arena.add_or_find_vert(mpq3(co.x, co.y, co.z), v); - ++v; - } + threading::parallel_for(mverts.index_range(), 2048, [&](IndexRange range) { + float3 co; + for (int i : range) { + co = float3(mverts[i].co); + mpq3 mco = mpq3(co.x, co.y, co.z); + double3 dco(mco[0].get_d(), mco[1].get_d(), mco[2].get_d()); + verts[i] = new Vert(mco, dco, NO_INDEX, i); + } + }); } else { - for (const MVert &vert : Span(me->mvert, me->totvert)) { - const float3 co = r_info->to_target_transform[mi] * float3(vert.co); - r_info->mesh_to_imesh_vert[v] = arena.add_or_find_vert(mpq3(co.x, co.y, co.z), v); - ++v; - } + threading::parallel_for(mverts.index_range(), 2048, [&](IndexRange range) { + float3 co; + for (int i : range) { + co = r_info->to_target_transform[mi] * float3(mverts[i].co); + mpq3 mco = mpq3(co.x, co.y, co.z); + double3 dco(mco[0].get_d(), mco[1].get_d(), mco[2].get_d()); + verts[i] = new Vert(mco, dco, NO_INDEX, i); + } + }); + } + for (int i : mverts.index_range()) { + r_info->mesh_to_imesh_vert[v] = arena.add_or_find_vert(verts[i]); + ++v; } for (const MPoly &poly : Span(me->mpoly, me->totpoly)) { diff --git a/source/blender/blenkernel/intern/mesh_evaluate.c b/source/blender/blenkernel/intern/mesh_evaluate.cc index 7290679bc07..91fd022a316 100644 --- a/source/blender/blenkernel/intern/mesh_evaluate.c +++ b/source/blender/blenkernel/intern/mesh_evaluate.cc @@ -23,7 +23,7 @@ * Functions to evaluate mesh data. */ -#include <limits.h> +#include <climits> #include "MEM_guardedalloc.h" @@ -200,7 +200,7 @@ float BKE_mesh_calc_poly_area(const MPoly *mpoly, const MLoop *loopstart, const } const MLoop *l_iter = loopstart; - float(*vertexcos)[3] = BLI_array_alloca(vertexcos, (size_t)mpoly->totloop); + float(*vertexcos)[3] = (float(*)[3])BLI_array_alloca(vertexcos, (size_t)mpoly->totloop); /* pack vertex cos into an array for area_poly_v3 */ for (int i = 0; i < mpoly->totloop; i++, l_iter++) { @@ -236,7 +236,7 @@ float BKE_mesh_calc_poly_uv_area(const MPoly *mpoly, const MLoopUV *uv_array) int i, l_iter = mpoly->loopstart; float area; - float(*vertexcos)[2] = BLI_array_alloca(vertexcos, (size_t)mpoly->totloop); + float(*vertexcos)[2] = (float(*)[2])BLI_array_alloca(vertexcos, (size_t)mpoly->totloop); /* pack vertex cos into an array for area_poly_v2 */ for (i = 0; i < mpoly->totloop; i++, l_iter++) { @@ -404,7 +404,7 @@ void BKE_mesh_poly_edgehash_insert(EdgeHash *ehash, const MPoly *mp, const MLoop ml = &ml_next[i - 1]; /* last loop */ while (i-- != 0) { - BLI_edgehash_reinsert(ehash, ml->v, ml_next->v, NULL); + BLI_edgehash_reinsert(ehash, ml->v, ml_next->v, nullptr); ml = ml_next; ml_next++; @@ -676,7 +676,7 @@ void BKE_mesh_calc_volume(const MVert *mverts, /** \} */ /* -------------------------------------------------------------------- */ -/** \name NGon Tessellation (NGon/Tessface Conversion) +/** \name NGon Tessellation (NGon to MFace Conversion) * \{ */ static void bm_corners_to_loops_ex(ID *id, @@ -692,9 +692,9 @@ static void bm_corners_to_loops_ex(ID *id, MFace *mf = mface + findex; for (int i = 0; i < numTex; i++) { - MTFace *texface = CustomData_get_n(fdata, CD_MTFACE, findex, i); + MTFace *texface = (MTFace *)CustomData_get_n(fdata, CD_MTFACE, findex, i); - MLoopUV *mloopuv = CustomData_get_n(ldata, CD_MLOOPUV, loopstart, i); + MLoopUV *mloopuv = (MLoopUV *)CustomData_get_n(ldata, CD_MLOOPUV, loopstart, i); copy_v2_v2(mloopuv->uv, texface->uv[0]); mloopuv++; copy_v2_v2(mloopuv->uv, texface->uv[1]); @@ -709,8 +709,8 @@ static void bm_corners_to_loops_ex(ID *id, } for (int i = 0; i < numCol; i++) { - MLoopCol *mloopcol = CustomData_get_n(ldata, CD_MLOOPCOL, loopstart, i); - MCol *mcol = CustomData_get_n(fdata, CD_MCOL, findex, i); + MLoopCol *mloopcol = (MLoopCol *)CustomData_get_n(ldata, CD_MLOOPCOL, loopstart, i); + MCol *mcol = (MCol *)CustomData_get_n(fdata, CD_MCOL, findex, i); MESH_MLOOPCOL_FROM_MCOL(mloopcol, &mcol[0]); mloopcol++; @@ -725,8 +725,8 @@ static void bm_corners_to_loops_ex(ID *id, } if (CustomData_has_layer(fdata, CD_TESSLOOPNORMAL)) { - float(*lnors)[3] = CustomData_get(ldata, loopstart, CD_NORMAL); - short(*tlnors)[3] = CustomData_get(fdata, findex, CD_TESSLOOPNORMAL); + float(*lnors)[3] = (float(*)[3])CustomData_get(ldata, loopstart, CD_NORMAL); + short(*tlnors)[3] = (short(*)[3])CustomData_get(fdata, findex, CD_TESSLOOPNORMAL); const int max = mf->v4 ? 4 : 3; for (int i = 0; i < max; i++, lnors++, tlnors++) { @@ -735,8 +735,8 @@ static void bm_corners_to_loops_ex(ID *id, } if (CustomData_has_layer(fdata, CD_MDISPS)) { - MDisps *ld = CustomData_get(ldata, loopstart, CD_MDISPS); - MDisps *fd = CustomData_get(fdata, findex, CD_MDISPS); + MDisps *ld = (MDisps *)CustomData_get(ldata, loopstart, CD_MDISPS); + MDisps *fd = (MDisps *)CustomData_get(fdata, findex, CD_MDISPS); float(*disps)[3] = fd->disps; int tot = mf->v4 ? 4 : 3; int corners; @@ -750,9 +750,9 @@ static void bm_corners_to_loops_ex(ID *id, corners = multires_mdisp_corners(fd); if (corners == 0) { - /* Empty MDisp layers appear in at least one of the sintel.blend files. + /* Empty #MDisp layers appear in at least one of the `sintel.blend` files. * Not sure why this happens, but it seems fine to just ignore them here. - * If (corners == 0) for a non-empty layer though, something went wrong. */ + * If `corners == 0` for a non-empty layer though, something went wrong. */ BLI_assert(fd->totdisp == 0); } else { @@ -767,7 +767,8 @@ static void bm_corners_to_loops_ex(ID *id, MEM_freeN(ld->disps); } - ld->disps = MEM_malloc_arrayN((size_t)side_sq, sizeof(float[3]), "converted loop mdisps"); + ld->disps = (float(*)[3])MEM_malloc_arrayN( + (size_t)side_sq, sizeof(float[3]), "converted loop mdisps"); if (fd->disps) { memcpy(ld->disps, disps, (size_t)side_sq * sizeof(float[3])); } @@ -801,15 +802,16 @@ void BKE_mesh_convert_mfaces_to_mpolys(Mesh *mesh) /** * The same as #BKE_mesh_convert_mfaces_to_mpolys - * but oriented to be used in #do_versions from readfile.c - * the difference is how active/render/clone/stencil indices are handled here + * but oriented to be used in #do_versions from `readfile.c` + * the difference is how active/render/clone/stencil indices are handled here. * - * normally thay're being set from pdata which totally makes sense for meshes which are already - * converted to bmesh structures, but when loading older files indices shall be updated in other - * way around, so newly added pdata and ldata would have this indices set based on fdata layer + * normally they're being set from `pdata` which totally makes sense for meshes which are already + * converted to #BMesh structures, but when loading older files indices shall be updated in other + * way around, so newly added `pdata` and `ldata` would have this indices set + * based on `fdata` layer. * * this is normally only needed when reading older files, - * in all other cases #BKE_mesh_convert_mfaces_to_mpolys shall be always used + * in all other cases #BKE_mesh_convert_mfaces_to_mpolys shall be always used. */ void BKE_mesh_do_versions_convert_mfaces_to_mpolys(Mesh *mesh) { @@ -864,7 +866,7 @@ void BKE_mesh_convert_mfaces_to_mpolys_ex(ID *id, CustomData_free(pdata, totpoly_i); totpoly = totface_i; - mpoly = MEM_calloc_arrayN((size_t)totpoly, sizeof(MPoly), "mpoly converted"); + mpoly = (MPoly *)MEM_calloc_arrayN((size_t)totpoly, sizeof(MPoly), "mpoly converted"); CustomData_add_layer(pdata, CD_MPOLY, CD_ASSIGN, mpoly, totpoly); numTex = CustomData_number_of_layers(fdata, CD_MTFACE); @@ -876,7 +878,7 @@ void BKE_mesh_convert_mfaces_to_mpolys_ex(ID *id, totloop += mf->v4 ? 4 : 3; } - mloop = MEM_calloc_arrayN((size_t)totloop, sizeof(MLoop), "mloop converted"); + mloop = (MLoop *)MEM_calloc_arrayN((size_t)totloop, sizeof(MLoop), "mloop converted"); CustomData_add_layer(ldata, CD_MLOOP, CD_ASSIGN, mloop, totloop); @@ -900,7 +902,7 @@ void BKE_mesh_convert_mfaces_to_mpolys_ex(ID *id, me->flag &= ~ME_FGON; } - polyindex = CustomData_get_layer(fdata, CD_ORIGINDEX); + polyindex = (int *)CustomData_get_layer(fdata, CD_ORIGINDEX); j = 0; /* current loop index */ ml = mloop; @@ -946,7 +948,7 @@ void BKE_mesh_convert_mfaces_to_mpolys_ex(ID *id, /* NOTE: we don't convert NGons at all, these are not even real ngons, * they have their own UV's, colors etc - its more an editing feature. */ - BLI_edgehash_free(eh, NULL); + BLI_edgehash_free(eh, nullptr); *r_totpoly = totpoly; *r_totloop = totloop; @@ -1050,8 +1052,8 @@ void BKE_mesh_polygon_flip_ex(MPoly *mpoly, void BKE_mesh_polygon_flip(MPoly *mpoly, MLoop *mloop, CustomData *ldata) { - MDisps *mdisp = CustomData_get_layer(ldata, CD_MDISPS); - BKE_mesh_polygon_flip_ex(mpoly, mloop, ldata, NULL, mdisp, true); + MDisps *mdisp = (MDisps *)CustomData_get_layer(ldata, CD_MDISPS); + BKE_mesh_polygon_flip_ex(mpoly, mloop, ldata, nullptr, mdisp, true); } /** @@ -1061,12 +1063,12 @@ void BKE_mesh_polygon_flip(MPoly *mpoly, MLoop *mloop, CustomData *ldata) */ void BKE_mesh_polygons_flip(MPoly *mpoly, MLoop *mloop, CustomData *ldata, int totpoly) { - MDisps *mdisp = CustomData_get_layer(ldata, CD_MDISPS); + MDisps *mdisp = (MDisps *)CustomData_get_layer(ldata, CD_MDISPS); MPoly *mp; int i; for (mp = mpoly, i = 0; i < totpoly; mp++, i++) { - BKE_mesh_polygon_flip_ex(mp, mloop, ldata, NULL, mdisp, true); + BKE_mesh_polygon_flip_ex(mp, mloop, ldata, nullptr, mdisp, true); } } @@ -1277,7 +1279,7 @@ void BKE_mesh_calc_relative_deform(const MPoly *mpoly, const MPoly *mp; int i; - int *vert_accum = MEM_calloc_arrayN((size_t)totvert, sizeof(*vert_accum), __func__); + int *vert_accum = (int *)MEM_calloc_arrayN((size_t)totvert, sizeof(*vert_accum), __func__); memset(vert_cos_new, '\0', sizeof(*vert_cos_new) * (size_t)totvert); diff --git a/source/blender/blenkernel/intern/mesh_mapping.c b/source/blender/blenkernel/intern/mesh_mapping.c index 9a3333fce6c..ca6c60557a6 100644 --- a/source/blender/blenkernel/intern/mesh_mapping.c +++ b/source/blender/blenkernel/intern/mesh_mapping.c @@ -998,7 +998,7 @@ void BKE_mesh_loop_islands_add(MeshIslandStore *island_store, } /* TODO: I'm not sure edge seam flag is enough to define UV islands? - * Maybe we should also consider UVmaps values + * Maybe we should also consider UV-maps values * themselves (i.e. different UV-edges for a same mesh-edge => boundary edge too?). * Would make things much more complex though, * and each UVMap would then need its own mesh mapping, not sure we want that at all! diff --git a/source/blender/blenkernel/intern/mesh_normals.c b/source/blender/blenkernel/intern/mesh_normals.cc index 89fd7f92d94..2fe132fc684 100644 --- a/source/blender/blenkernel/intern/mesh_normals.c +++ b/source/blender/blenkernel/intern/mesh_normals.cc @@ -25,7 +25,7 @@ * \see bmesh_mesh_normals.c for the equivalent #BMesh functionality. */ -#include <limits.h> +#include <climits> #include "CLG_log.h" @@ -90,15 +90,15 @@ void BKE_mesh_calc_normals_mapping_simple(struct Mesh *mesh) mesh->mpoly, mesh->totloop, mesh->totpoly, - NULL, + nullptr, mesh->mface, mesh->totface, - NULL, - NULL, + nullptr, + nullptr, only_face_normals); } -/* Calculate vertex and face normals, face normals are returned in *r_faceNors if non-NULL +/* Calculate vertex and face normals, face normals are returned in *r_faceNors if non-nullptr * and vertex normals are stored in actual mverts. */ void BKE_mesh_calc_normals_mapping(MVert *mverts, @@ -150,13 +150,13 @@ void BKE_mesh_calc_normals_mapping_ex(MVert *mverts, } /* if we are not calculating verts and no verts were passes then we have nothing to do */ - if ((only_face_normals == true) && (r_polyNors == NULL) && (r_faceNors == NULL)) { + if ((only_face_normals == true) && (r_polyNors == nullptr) && (r_faceNors == nullptr)) { CLOG_WARN(&LOG, "called with nothing to do"); return; } if (!pnors) { - pnors = MEM_calloc_arrayN((size_t)numPolys, sizeof(float[3]), __func__); + pnors = (float(*)[3])MEM_calloc_arrayN((size_t)numPolys, sizeof(float[3]), __func__); } /* NO NEED TO ALLOC YET */ /* if (!fnors) fnors = MEM_calloc_arrayN(numFaces, sizeof(float[3]), "face nors mesh.c"); */ @@ -165,7 +165,7 @@ void BKE_mesh_calc_normals_mapping_ex(MVert *mverts, /* vertex normals are optional, they require some extra calculations, * so make them optional */ BKE_mesh_calc_normals_poly( - mverts, NULL, numVerts, mloop, mpolys, numLoops, numPolys, pnors, false); + mverts, nullptr, numVerts, mloop, mpolys, numLoops, numPolys, pnors, false); } else { /* only calc poly normals */ @@ -177,7 +177,7 @@ void BKE_mesh_calc_normals_mapping_ex(MVert *mverts, if (origIndexFace && /* fnors == r_faceNors */ /* NO NEED TO ALLOC YET */ - fnors != NULL && + fnors != nullptr && numFaces) { const MFace *mf = mfaces; for (int i = 0; i < numFaces; i++, mf++, origIndexFace++) { @@ -196,23 +196,23 @@ void BKE_mesh_calc_normals_mapping_ex(MVert *mverts, } /* if (fnors != r_faceNors) MEM_freeN(fnors); */ /* NO NEED TO ALLOC YET */ - fnors = pnors = NULL; + fnors = pnors = nullptr; } -typedef struct MeshCalcNormalsData { +struct MeshCalcNormalsData { const MPoly *mpolys; const MLoop *mloop; MVert *mverts; float (*pnors)[3]; float (*lnors_weighted)[3]; float (*vnors)[3]; -} MeshCalcNormalsData; +}; static void mesh_calc_normals_poly_cb(void *__restrict userdata, const int pidx, const TaskParallelTLS *__restrict UNUSED(tls)) { - MeshCalcNormalsData *data = userdata; + MeshCalcNormalsData *data = (MeshCalcNormalsData *)userdata; const MPoly *mp = &data->mpolys[pidx]; BKE_mesh_calc_poly_normal(mp, data->mloop + mp->loopstart, data->mverts, data->pnors[pidx]); @@ -222,7 +222,7 @@ static void mesh_calc_normals_poly_prepare_cb(void *__restrict userdata, const int pidx, const TaskParallelTLS *__restrict UNUSED(tls)) { - MeshCalcNormalsData *data = userdata; + MeshCalcNormalsData *data = (MeshCalcNormalsData *)userdata; const MPoly *mp = &data->mpolys[pidx]; const MLoop *ml = &data->mloop[mp->loopstart]; const MVert *mverts = data->mverts; @@ -232,7 +232,7 @@ static void mesh_calc_normals_poly_prepare_cb(void *__restrict userdata, float(*lnors_weighted)[3] = data->lnors_weighted; const int nverts = mp->totloop; - float(*edgevecbuf)[3] = BLI_array_alloca(edgevecbuf, (size_t)nverts); + float(*edgevecbuf)[3] = (float(*)[3])BLI_array_alloca(edgevecbuf, (size_t)nverts); /* Polygon Normal and edge-vector */ /* inline version of #BKE_mesh_calc_poly_normal, also does edge-vectors */ @@ -285,7 +285,7 @@ static void mesh_calc_normals_poly_finalize_cb(void *__restrict userdata, const int vidx, const TaskParallelTLS *__restrict UNUSED(tls)) { - MeshCalcNormalsData *data = userdata; + MeshCalcNormalsData *data = (MeshCalcNormalsData *)userdata; MVert *mv = &data->mverts[vidx]; float *no = data->vnors[vidx]; @@ -315,42 +315,40 @@ void BKE_mesh_calc_normals_poly(MVert *mverts, settings.min_iter_per_thread = 1024; if (only_face_normals) { - BLI_assert((pnors != NULL) || (numPolys == 0)); - BLI_assert(r_vertnors == NULL); - - MeshCalcNormalsData data = { - .mpolys = mpolys, - .mloop = mloop, - .mverts = mverts, - .pnors = pnors, - }; + BLI_assert((pnors != nullptr) || (numPolys == 0)); + BLI_assert(r_vertnors == nullptr); + + MeshCalcNormalsData data; + data.mpolys = mpolys; + data.mloop = mloop; + data.mverts = mverts; + data.pnors = pnors; BLI_task_parallel_range(0, numPolys, &data, mesh_calc_normals_poly_cb, &settings); return; } float(*vnors)[3] = r_vertnors; - float(*lnors_weighted)[3] = MEM_malloc_arrayN( + float(*lnors_weighted)[3] = (float(*)[3])MEM_malloc_arrayN( (size_t)numLoops, sizeof(*lnors_weighted), __func__); bool free_vnors = false; /* first go through and calculate normals for all the polys */ - if (vnors == NULL) { - vnors = MEM_calloc_arrayN((size_t)numVerts, sizeof(*vnors), __func__); + if (vnors == nullptr) { + vnors = (float(*)[3])MEM_calloc_arrayN((size_t)numVerts, sizeof(*vnors), __func__); free_vnors = true; } else { memset(vnors, 0, sizeof(*vnors) * (size_t)numVerts); } - MeshCalcNormalsData data = { - .mpolys = mpolys, - .mloop = mloop, - .mverts = mverts, - .pnors = pnors, - .lnors_weighted = lnors_weighted, - .vnors = vnors, - }; + MeshCalcNormalsData data; + data.mpolys = mpolys; + data.mloop = mloop; + data.mverts = mverts; + data.pnors = pnors; + data.lnors_weighted = lnors_weighted; + data.vnors = vnors; /* Compute poly normals, and prepare weighted loop normals. */ BLI_task_parallel_range(0, numPolys, &data, mesh_calc_normals_poly_prepare_cb, &settings); @@ -400,19 +398,21 @@ void BKE_mesh_ensure_normals_for_display(Mesh *mesh) } } - float(*poly_nors)[3] = CustomData_get_layer(&mesh->pdata, CD_NORMAL); + float(*poly_nors)[3] = (float(*)[3])CustomData_get_layer(&mesh->pdata, CD_NORMAL); const bool do_vert_normals = (mesh->runtime.cd_dirty_vert & CD_MASK_NORMAL) != 0; - const bool do_poly_normals = (mesh->runtime.cd_dirty_poly & CD_MASK_NORMAL || poly_nors == NULL); + const bool do_poly_normals = (mesh->runtime.cd_dirty_poly & CD_MASK_NORMAL || + poly_nors == nullptr); if (do_vert_normals || do_poly_normals) { - const bool do_add_poly_nors_cddata = (poly_nors == NULL); + const bool do_add_poly_nors_cddata = (poly_nors == nullptr); if (do_add_poly_nors_cddata) { - poly_nors = MEM_malloc_arrayN((size_t)mesh->totpoly, sizeof(*poly_nors), __func__); + poly_nors = (float(*)[3])MEM_malloc_arrayN( + (size_t)mesh->totpoly, sizeof(*poly_nors), __func__); } /* calculate poly/vert normals */ BKE_mesh_calc_normals_poly(mesh->mvert, - NULL, + nullptr, mesh->totvert, mesh->mloop, mesh->mpoly, @@ -438,13 +438,13 @@ void BKE_mesh_calc_normals(Mesh *mesh) TIMEIT_START_AVERAGED(BKE_mesh_calc_normals); #endif BKE_mesh_calc_normals_poly(mesh->mvert, - NULL, + nullptr, mesh->totvert, mesh->mloop, mesh->mpoly, mesh->totloop, mesh->totpoly, - NULL, + nullptr, false); #ifdef DEBUG_TIME TIMEIT_END_AVERAGED(BKE_mesh_calc_normals); @@ -459,10 +459,10 @@ void BKE_mesh_calc_normals_looptri(MVert *mverts, int looptri_num, float (*r_tri_nors)[3]) { - float(*tnorms)[3] = MEM_calloc_arrayN((size_t)numVerts, sizeof(*tnorms), "tnorms"); - float(*fnors)[3] = (r_tri_nors) ? - r_tri_nors : - MEM_calloc_arrayN((size_t)looptri_num, sizeof(*fnors), "meshnormals"); + float(*tnorms)[3] = (float(*)[3])MEM_calloc_arrayN((size_t)numVerts, sizeof(*tnorms), "tnorms"); + float(*fnors)[3] = (r_tri_nors) ? r_tri_nors : + (float(*)[3])MEM_calloc_arrayN( + (size_t)looptri_num, sizeof(*fnors), "meshnormals"); if (!tnorms || !fnors) { goto cleanup; @@ -519,9 +519,10 @@ void BKE_lnor_spacearr_init(MLoopNorSpaceArray *lnors_spacearr, lnors_spacearr->mem = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE, __func__); } mem = lnors_spacearr->mem; - lnors_spacearr->lspacearr = BLI_memarena_calloc(mem, - sizeof(MLoopNorSpace *) * (size_t)numLoops); - lnors_spacearr->loops_pool = BLI_memarena_alloc(mem, sizeof(LinkNode) * (size_t)numLoops); + lnors_spacearr->lspacearr = (MLoopNorSpace **)BLI_memarena_calloc( + mem, sizeof(MLoopNorSpace *) * (size_t)numLoops); + lnors_spacearr->loops_pool = (LinkNode *)BLI_memarena_alloc( + mem, sizeof(LinkNode) * (size_t)numLoops); lnors_spacearr->num_spaces = 0; } @@ -532,9 +533,9 @@ void BKE_lnor_spacearr_init(MLoopNorSpaceArray *lnors_spacearr, void BKE_lnor_spacearr_clear(MLoopNorSpaceArray *lnors_spacearr) { lnors_spacearr->num_spaces = 0; - lnors_spacearr->lspacearr = NULL; - lnors_spacearr->loops_pool = NULL; - if (lnors_spacearr->mem != NULL) { + lnors_spacearr->lspacearr = nullptr; + lnors_spacearr->loops_pool = nullptr; + if (lnors_spacearr->mem != nullptr) { BLI_memarena_clear(lnors_spacearr->mem); } } @@ -542,16 +543,16 @@ void BKE_lnor_spacearr_clear(MLoopNorSpaceArray *lnors_spacearr) void BKE_lnor_spacearr_free(MLoopNorSpaceArray *lnors_spacearr) { lnors_spacearr->num_spaces = 0; - lnors_spacearr->lspacearr = NULL; - lnors_spacearr->loops_pool = NULL; + lnors_spacearr->lspacearr = nullptr; + lnors_spacearr->loops_pool = nullptr; BLI_memarena_free(lnors_spacearr->mem); - lnors_spacearr->mem = NULL; + lnors_spacearr->mem = nullptr; } MLoopNorSpace *BKE_lnor_space_create(MLoopNorSpaceArray *lnors_spacearr) { lnors_spacearr->num_spaces++; - return BLI_memarena_calloc(lnors_spacearr->mem, sizeof(MLoopNorSpace)); + return (MLoopNorSpace *)BLI_memarena_calloc(lnors_spacearr->mem, sizeof(MLoopNorSpace)); } /* This threshold is a bit touchy (usual float precision issue), this value seems OK. */ @@ -592,7 +593,7 @@ void BKE_lnor_space_define(MLoopNorSpace *lnor_space, float alpha = 0.0f; int nbr = 0; while (!BLI_stack_is_empty(edge_vectors)) { - const float *vec = BLI_stack_peek(edge_vectors); + const float *vec = (const float *)BLI_stack_peek(edge_vectors); alpha += saacosf(dot_v3v3(vec, lnor)); BLI_stack_discard(edge_vectors); nbr++; @@ -637,10 +638,10 @@ void BKE_lnor_space_define(MLoopNorSpace *lnor_space, /** * Add a new given loop to given lnor_space. * Depending on \a lnor_space->data_type, we expect \a bm_loop to be a pointer to BMLoop struct - * (in case of BMLOOP_PTR), or NULL (in case of LOOP_INDEX), loop index is then stored in pointer. - * If \a is_single is set, the BMLoop or loop index is directly stored in \a lnor_space->loops - * pointer (since there is only one loop in this fan), - * else it is added to the linked list of loops in the fan. + * (in case of BMLOOP_PTR), or nullptr (in case of LOOP_INDEX), loop index is then stored in + * pointer. If \a is_single is set, the BMLoop or loop index is directly stored in \a + * lnor_space->loops pointer (since there is only one loop in this fan), else it is added to the + * linked list of loops in the fan. */ void BKE_lnor_space_add_loop(MLoopNorSpaceArray *lnors_spacearr, MLoopNorSpace *lnor_space, @@ -648,17 +649,17 @@ void BKE_lnor_space_add_loop(MLoopNorSpaceArray *lnors_spacearr, void *bm_loop, const bool is_single) { - BLI_assert((lnors_spacearr->data_type == MLNOR_SPACEARR_LOOP_INDEX && bm_loop == NULL) || - (lnors_spacearr->data_type == MLNOR_SPACEARR_BMLOOP_PTR && bm_loop != NULL)); + BLI_assert((lnors_spacearr->data_type == MLNOR_SPACEARR_LOOP_INDEX && bm_loop == nullptr) || + (lnors_spacearr->data_type == MLNOR_SPACEARR_BMLOOP_PTR && bm_loop != nullptr)); lnors_spacearr->lspacearr[ml_index] = lnor_space; - if (bm_loop == NULL) { + if (bm_loop == nullptr) { bm_loop = POINTER_FROM_INT(ml_index); } if (is_single) { - BLI_assert(lnor_space->loops == NULL); + BLI_assert(lnor_space->loops == nullptr); lnor_space->flags |= MLNOR_SPACE_IS_SINGLE; - lnor_space->loops = bm_loop; + lnor_space->loops = (LinkNode *)bm_loop; } else { BLI_assert((lnor_space->flags & MLNOR_SPACE_IS_SINGLE) == 0); @@ -715,7 +716,8 @@ void BKE_lnor_space_custom_normal_to_data(MLoopNorSpace *lnor_space, const float custom_lnor[3], short r_clnor_data[2]) { - /* We use null vector as NOP custom normal (can be simpler than giving auto-computed `lnor`). */ + /* We use nullptr vector as NOP custom normal (can be simpler than giving auto-computed `lnor`). + */ if (is_zero_v3(custom_lnor) || compare_v3v3(lnor_space->vec_lnor, custom_lnor, 1e-4f)) { r_clnor_data[0] = r_clnor_data[1] = 0; return; @@ -765,7 +767,7 @@ void BKE_lnor_space_custom_normal_to_data(MLoopNorSpace *lnor_space, #define LOOP_SPLIT_TASK_BLOCK_SIZE 1024 -typedef struct LoopSplitTaskData { +struct LoopSplitTaskData { /* Specific to each instance (each task). */ /** We have to create those outside of tasks, since #MemArena is not thread-safe. */ @@ -784,9 +786,9 @@ typedef struct LoopSplitTaskData { BLI_Stack *edge_vectors; char pad_c; -} LoopSplitTaskData; +}; -typedef struct LoopSplitTaskDataCommon { +struct LoopSplitTaskDataCommon { /* Read/write. * Note we do not need to protect it, though, since two different tasks will *always* affect * different elements in the arrays. */ @@ -806,7 +808,7 @@ typedef struct LoopSplitTaskDataCommon { int numEdges; int numLoops; int numPolys; -} LoopSplitTaskDataCommon; +}; #define INDEX_UNSET INT_MIN #define INDEX_INVALID -1 @@ -827,13 +829,13 @@ static void mesh_edges_sharp_tag(LoopSplitTaskDataCommon *data, const int numEdges = data->numEdges; const int numPolys = data->numPolys; - float(*loopnors)[3] = data->loopnors; /* NOTE: loopnors may be NULL here. */ + float(*loopnors)[3] = data->loopnors; /* NOTE: loopnors may be nullptr here. */ const float(*polynors)[3] = data->polynors; int(*edge_to_loops)[2] = data->edge_to_loops; int *loop_to_poly = data->loop_to_poly; - BLI_bitmap *sharp_edges = do_sharp_edges_tag ? BLI_BITMAP_NEW(numEdges, __func__) : NULL; + BLI_bitmap *sharp_edges = do_sharp_edges_tag ? BLI_BITMAP_NEW(numEdges, __func__) : nullptr; const MPoly *mp; int mp_index; @@ -943,22 +945,22 @@ void BKE_edges_sharp_from_angle_set(const struct MVert *mverts, } /* Mapping edge -> loops. See BKE_mesh_normals_loop_split() for details. */ - int(*edge_to_loops)[2] = MEM_calloc_arrayN((size_t)numEdges, sizeof(*edge_to_loops), __func__); + int(*edge_to_loops)[2] = (int(*)[2])MEM_calloc_arrayN( + (size_t)numEdges, sizeof(*edge_to_loops), __func__); /* Simple mapping from a loop to its polygon index. */ - int *loop_to_poly = MEM_malloc_arrayN((size_t)numLoops, sizeof(*loop_to_poly), __func__); - - LoopSplitTaskDataCommon common_data = { - .mverts = mverts, - .medges = medges, - .mloops = mloops, - .mpolys = mpolys, - .edge_to_loops = edge_to_loops, - .loop_to_poly = loop_to_poly, - .polynors = polynors, - .numEdges = numEdges, - .numPolys = numPolys, - }; + int *loop_to_poly = (int *)MEM_malloc_arrayN((size_t)numLoops, sizeof(*loop_to_poly), __func__); + + LoopSplitTaskDataCommon common_data; + common_data.mverts = mverts; + common_data.medges = medges; + common_data.mloops = mloops; + common_data.mpolys = mpolys; + common_data.edge_to_loops = edge_to_loops; + common_data.loop_to_poly = loop_to_poly; + common_data.polynors = polynors; + common_data.numEdges = numEdges; + common_data.numPolys = numPolys; mesh_edges_sharp_tag(&common_data, true, split_angle, true); @@ -1065,10 +1067,10 @@ static void split_loop_nor_single_do(LoopSplitTaskDataCommon *common_data, LoopS sub_v3_v3v3(vec_prev, mv_3->co, mv_pivot->co); normalize_v3(vec_prev); - BKE_lnor_space_define(lnor_space, *lnor, vec_curr, vec_prev, NULL); + BKE_lnor_space_define(lnor_space, *lnor, vec_curr, vec_prev, nullptr); /* We know there is only one loop in this space, * no need to create a linklist in this case... */ - BKE_lnor_space_add_loop(lnors_spacearr, lnor_space, ml_curr_index, NULL, true); + BKE_lnor_space_add_loop(lnors_spacearr, lnor_space, ml_curr_index, nullptr, true); if (clnors_data) { BKE_lnor_space_custom_data_to_normal(lnor_space, clnors_data[ml_curr_index], *lnor); @@ -1125,7 +1127,7 @@ static void split_loop_nor_fan_do(LoopSplitTaskDataCommon *common_data, LoopSpli /* We validate clnors data on the fly - cheapest way to do! */ int clnors_avg[2] = {0, 0}; - short(*clnor_ref)[2] = NULL; + short(*clnor_ref)[2] = nullptr; int clnors_nbr = 0; bool clnors_invalid = false; @@ -1205,7 +1207,7 @@ static void split_loop_nor_fan_do(LoopSplitTaskDataCommon *common_data, LoopSpli if (lnors_spacearr) { /* Assign current lnor space to current 'vertex' loop. */ - BKE_lnor_space_add_loop(lnors_spacearr, lnor_space, mlfan_vert_index, NULL, false); + BKE_lnor_space_add_loop(lnors_spacearr, lnor_space, mlfan_vert_index, nullptr, false); if (me_curr != me_org) { /* We store here all edges-normalized vectors processed. */ BLI_stack_push(edge_vectors, vec_curr); @@ -1261,7 +1263,7 @@ static void split_loop_nor_fan_do(LoopSplitTaskDataCommon *common_data, LoopSpli if (G.debug & G_DEBUG) { printf("Invalid clnors in this fan!\n"); } - while ((clnor = BLI_SMALLSTACK_POP(clnors))) { + while ((clnor = (short *)BLI_SMALLSTACK_POP(clnors))) { // print_v2("org clnor", clnor); clnor[0] = (short)clnors_avg[0]; clnor[1] = (short)clnors_avg[1]; @@ -1280,7 +1282,7 @@ static void split_loop_nor_fan_do(LoopSplitTaskDataCommon *common_data, LoopSpli /* Copy back the final computed normal into all related loop-normals. */ float *nor; - while ((nor = BLI_SMALLSTACK_POP(normal))) { + while ((nor = (float *)BLI_SMALLSTACK_POP(normal))) { copy_v3_v3(nor, lnor); } } @@ -1295,7 +1297,7 @@ static void loop_split_worker_do(LoopSplitTaskDataCommon *common_data, { BLI_assert(data->ml_curr); if (data->e2l_prev) { - BLI_assert((edge_vectors == NULL) || BLI_stack_is_empty(edge_vectors)); + BLI_assert((edge_vectors == nullptr) || BLI_stack_is_empty(edge_vectors)); data->edge_vectors = edge_vectors; split_loop_nor_fan_do(common_data, data); } @@ -1307,21 +1309,21 @@ static void loop_split_worker_do(LoopSplitTaskDataCommon *common_data, static void loop_split_worker(TaskPool *__restrict pool, void *taskdata) { - LoopSplitTaskDataCommon *common_data = BLI_task_pool_user_data(pool); - LoopSplitTaskData *data = taskdata; + LoopSplitTaskDataCommon *common_data = (LoopSplitTaskDataCommon *)BLI_task_pool_user_data(pool); + LoopSplitTaskData *data = (LoopSplitTaskData *)taskdata; /* Temp edge vectors stack, only used when computing lnor spacearr. */ BLI_Stack *edge_vectors = common_data->lnors_spacearr ? BLI_stack_new(sizeof(float[3]), __func__) : - NULL; + nullptr; #ifdef DEBUG_TIME TIMEIT_START_AVERAGED(loop_split_worker); #endif for (int i = 0; i < LOOP_SPLIT_TASK_BLOCK_SIZE; i++, data++) { - /* A NULL ml_curr is used to tag ended data! */ - if (data->ml_curr == NULL) { + /* A nullptr ml_curr is used to tag ended data! */ + if (data->ml_curr == nullptr) { break; } @@ -1434,12 +1436,12 @@ static void loop_split_generator(TaskPool *pool, LoopSplitTaskDataCommon *common BLI_bitmap *skip_loops = BLI_BITMAP_NEW(numLoops, __func__); - LoopSplitTaskData *data_buff = NULL; + LoopSplitTaskData *data_buff = nullptr; int data_idx = 0; /* Temp edge vectors stack, only used when computing lnor spacearr * (and we are not multi-threading). */ - BLI_Stack *edge_vectors = NULL; + BLI_Stack *edge_vectors = nullptr; #ifdef DEBUG_TIME TIMEIT_START_AVERAGED(loop_split_generator); @@ -1508,7 +1510,7 @@ static void loop_split_generator(TaskPool *pool, LoopSplitTaskDataCommon *common if (pool) { if (data_idx == 0) { - data_buff = MEM_calloc_arrayN( + data_buff = (LoopSplitTaskData *)MEM_calloc_arrayN( LOOP_SPLIT_TASK_BLOCK_SIZE, sizeof(*data_buff), __func__); } data = &data_buff[data_idx]; @@ -1525,7 +1527,7 @@ static void loop_split_generator(TaskPool *pool, LoopSplitTaskDataCommon *common data->ml_curr_index = ml_curr_index; #if 0 /* Not needed for 'single' loop. */ data->ml_prev_index = ml_prev_index; - data->e2l_prev = NULL; /* Tag as 'single' task. */ + data->e2l_prev = nullptr; /* Tag as 'single' task. */ #endif data->mp_index = mp_index; if (lnors_spacearr) { @@ -1559,7 +1561,7 @@ static void loop_split_generator(TaskPool *pool, LoopSplitTaskDataCommon *common if (pool) { data_idx++; if (data_idx == LOOP_SPLIT_TASK_BLOCK_SIZE) { - BLI_task_pool_push(pool, loop_split_worker, data_buff, true, NULL); + BLI_task_pool_push(pool, loop_split_worker, data_buff, true, nullptr); data_idx = 0; } } @@ -1573,10 +1575,10 @@ static void loop_split_generator(TaskPool *pool, LoopSplitTaskDataCommon *common } } - /* Last block of data... Since it is calloc'ed and we use first NULL item as stopper, + /* Last block of data... Since it is calloc'ed and we use first nullptr item as stopper, * everything is fine. */ if (pool && data_idx) { - BLI_task_pool_push(pool, loop_split_worker, data_buff, true, NULL); + BLI_task_pool_push(pool, loop_split_worker, data_buff, true, nullptr); } if (edge_vectors) { @@ -1659,17 +1661,18 @@ void BKE_mesh_normals_loop_split(const MVert *mverts, * However, if needed, we can store the negated value of loop index instead of INDEX_INVALID * to retrieve the real value later in code). * Note also that loose edges always have both values set to 0! */ - int(*edge_to_loops)[2] = MEM_calloc_arrayN((size_t)numEdges, sizeof(*edge_to_loops), __func__); + int(*edge_to_loops)[2] = (int(*)[2])MEM_calloc_arrayN( + (size_t)numEdges, sizeof(*edge_to_loops), __func__); /* Simple mapping from a loop to its polygon index. */ - int *loop_to_poly = r_loop_to_poly ? - r_loop_to_poly : - MEM_malloc_arrayN((size_t)numLoops, sizeof(*loop_to_poly), __func__); + int *loop_to_poly = r_loop_to_poly ? r_loop_to_poly : + (int *)MEM_malloc_arrayN( + (size_t)numLoops, sizeof(*loop_to_poly), __func__); /* When using custom loop normals, disable the angle feature! */ - const bool check_angle = (split_angle < (float)M_PI) && (clnors_data == NULL); + const bool check_angle = (split_angle < (float)M_PI) && (clnors_data == nullptr); - MLoopNorSpaceArray _lnors_spacearr = {NULL}; + MLoopNorSpaceArray _lnors_spacearr = {nullptr}; #ifdef DEBUG_TIME TIMEIT_START_AVERAGED(BKE_mesh_normals_loop_split); @@ -1684,28 +1687,27 @@ void BKE_mesh_normals_loop_split(const MVert *mverts, } /* Init data common to all tasks. */ - LoopSplitTaskDataCommon common_data = { - .lnors_spacearr = r_lnors_spacearr, - .loopnors = r_loopnors, - .clnors_data = clnors_data, - .mverts = mverts, - .medges = medges, - .mloops = mloops, - .mpolys = mpolys, - .edge_to_loops = edge_to_loops, - .loop_to_poly = loop_to_poly, - .polynors = polynors, - .numEdges = numEdges, - .numLoops = numLoops, - .numPolys = numPolys, - }; + LoopSplitTaskDataCommon common_data; + common_data.lnors_spacearr = r_lnors_spacearr; + common_data.loopnors = r_loopnors; + common_data.clnors_data = clnors_data; + common_data.mverts = mverts; + common_data.medges = medges; + common_data.mloops = mloops; + common_data.mpolys = mpolys; + common_data.edge_to_loops = edge_to_loops; + common_data.loop_to_poly = loop_to_poly; + common_data.polynors = polynors; + common_data.numEdges = numEdges; + common_data.numLoops = numLoops; + common_data.numPolys = numPolys; /* This first loop check which edges are actually smooth, and compute edge vectors. */ mesh_edges_sharp_tag(&common_data, check_angle, split_angle, false); if (numLoops < LOOP_SPLIT_TASK_BLOCK_SIZE * 8) { /* Not enough loops to be worth the whole threading overhead... */ - loop_split_generator(NULL, &common_data); + loop_split_generator(nullptr, &common_data); } else { TaskPool *task_pool = BLI_task_pool_create(&common_data, TASK_PRIORITY_HIGH); @@ -1766,10 +1768,10 @@ static void mesh_normals_loop_custom_set(const MVert *mverts, * (and perhaps from some editing tools later?). * So better to keep some simplicity here, and just call BKE_mesh_normals_loop_split() twice! */ - MLoopNorSpaceArray lnors_spacearr = {NULL}; + MLoopNorSpaceArray lnors_spacearr = {nullptr}; BLI_bitmap *done_loops = BLI_BITMAP_NEW((size_t)numLoops, __func__); - float(*lnors)[3] = MEM_calloc_arrayN((size_t)numLoops, sizeof(*lnors), __func__); - int *loop_to_poly = MEM_malloc_arrayN((size_t)numLoops, sizeof(int), __func__); + float(*lnors)[3] = (float(*)[3])MEM_calloc_arrayN((size_t)numLoops, sizeof(*lnors), __func__); + int *loop_to_poly = (int *)MEM_malloc_arrayN((size_t)numLoops, sizeof(int), __func__); /* In this case we always consider split nors as ON, * and do not want to use angle to define smooth fans! */ const bool use_split_normals = true; @@ -1791,7 +1793,7 @@ static void mesh_normals_loop_custom_set(const MVert *mverts, use_split_normals, split_angle, &lnors_spacearr, - NULL, + nullptr, loop_to_poly); /* Set all given zero vectors to their default value. */ @@ -1823,12 +1825,12 @@ static void mesh_normals_loop_custom_set(const MVert *mverts, for (int i = 0; i < numLoops; i++) { if (!lnors_spacearr.lspacearr[i]) { /* This should not happen in theory, but in some rare case (probably ugly geometry) - * we can get some NULL loopspacearr at this point. :/ + * we can get some nullptr loopspacearr at this point. :/ * Maybe we should set those loops' edges as sharp? */ BLI_BITMAP_ENABLE(done_loops, i); if (G.debug & G_DEBUG) { - printf("WARNING! Getting invalid NULL loop space for loop %d!\n", i); + printf("WARNING! Getting invalid nullptr loop space for loop %d!\n", i); } continue; } @@ -1849,8 +1851,8 @@ static void mesh_normals_loop_custom_set(const MVert *mverts, } LinkNode *loops = lnors_spacearr.lspacearr[i]->loops; - MLoop *prev_ml = NULL; - const float *org_nor = NULL; + MLoop *prev_ml = nullptr; + const float *org_nor = nullptr; while (loops) { const int lidx = POINTER_AS_INT(loops->link); @@ -1916,7 +1918,7 @@ static void mesh_normals_loop_custom_set(const MVert *mverts, use_split_normals, split_angle, &lnors_spacearr, - NULL, + nullptr, loop_to_poly); } else { @@ -1929,7 +1931,8 @@ static void mesh_normals_loop_custom_set(const MVert *mverts, if (!lnors_spacearr.lspacearr[i]) { BLI_BITMAP_DISABLE(done_loops, i); if (G.debug & G_DEBUG) { - printf("WARNING! Still getting invalid NULL loop space in second loop for loop %d!\n", i); + printf("WARNING! Still getting invalid nullptr loop space in second loop for loop %d!\n", + i); } continue; } @@ -1970,7 +1973,7 @@ static void mesh_normals_loop_custom_set(const MVert *mverts, mul_v3_fl(avg_nor, 1.0f / (float)nbr_nors); BKE_lnor_space_custom_normal_to_data(lnors_spacearr.lspacearr[i], avg_nor, clnor_data_tmp); - while ((clnor_data = BLI_SMALLSTACK_POP(clnors_data))) { + while ((clnor_data = (short *)BLI_SMALLSTACK_POP(clnors_data))) { clnor_data[0] = clnor_data_tmp[0]; clnor_data[1] = clnor_data_tmp[1]; } @@ -2041,20 +2044,21 @@ static void mesh_set_custom_normals(Mesh *mesh, float (*r_custom_nors)[3], const short(*clnors)[2]; const int numloops = mesh->totloop; - clnors = CustomData_get_layer(&mesh->ldata, CD_CUSTOMLOOPNORMAL); - if (clnors != NULL) { + clnors = (short(*)[2])CustomData_get_layer(&mesh->ldata, CD_CUSTOMLOOPNORMAL); + if (clnors != nullptr) { memset(clnors, 0, sizeof(*clnors) * (size_t)numloops); } else { - clnors = CustomData_add_layer(&mesh->ldata, CD_CUSTOMLOOPNORMAL, CD_CALLOC, NULL, numloops); + clnors = (short(*)[2])CustomData_add_layer( + &mesh->ldata, CD_CUSTOMLOOPNORMAL, CD_CALLOC, nullptr, numloops); } - float(*polynors)[3] = CustomData_get_layer(&mesh->pdata, CD_NORMAL); + float(*polynors)[3] = (float(*)[3])CustomData_get_layer(&mesh->pdata, CD_NORMAL); bool free_polynors = false; - if (polynors == NULL) { - polynors = MEM_mallocN(sizeof(float[3]) * (size_t)mesh->totpoly, __func__); + if (polynors == nullptr) { + polynors = (float(*)[3])MEM_mallocN(sizeof(float[3]) * (size_t)mesh->totpoly, __func__); BKE_mesh_calc_normals_poly(mesh->mvert, - NULL, + nullptr, mesh->totvert, mesh->mloop, mesh->mpoly, @@ -2119,7 +2123,8 @@ void BKE_mesh_normals_loop_to_vertex(const int numVerts, const float (*clnors)[3], float (*r_vert_clnors)[3]) { - int *vert_loops_nbr = MEM_calloc_arrayN((size_t)numVerts, sizeof(*vert_loops_nbr), __func__); + int *vert_loops_nbr = (int *)MEM_calloc_arrayN( + (size_t)numVerts, sizeof(*vert_loops_nbr), __func__); copy_vn_fl((float *)r_vert_clnors, 3 * numVerts, 0.0f); diff --git a/source/blender/blenkernel/intern/nla.c b/source/blender/blenkernel/intern/nla.c index bf18765aa94..7e524da0f53 100644 --- a/source/blender/blenkernel/intern/nla.c +++ b/source/blender/blenkernel/intern/nla.c @@ -631,10 +631,10 @@ float BKE_nla_tweakedit_remap(AnimData *adt, float cframe, short mode) { NlaStrip *strip; - /* sanity checks - * - obviously we've got to have some starting data - * - when not in tweakmode, the active Action does not have any scaling applied :) - * - when in tweakmode, if the no-mapping flag is set, do not map + /* Sanity checks: + * - Obviously we've got to have some starting data. + * - When not in tweak-mode, the active Action does not have any scaling applied :) + * - When in tweak-mode, if the no-mapping flag is set, do not map. */ if ((adt == NULL) || (adt->flag & ADT_NLA_EDIT_ON) == 0 || (adt->flag & ADT_NLA_EDIT_NOMAP)) { return cframe; @@ -2089,9 +2089,8 @@ bool BKE_nla_tweakmode_enter(AnimData *adt) return false; } - /* if block is already in tweakmode, just leave, but we should report - * that this block is in tweakmode (as our returncode) - */ + /* If block is already in tweak-mode, just leave, but we should report + * that this block is in tweak-mode (as our returncode). */ if (adt->flag & ADT_NLA_EDIT_ON) { return true; } @@ -2111,8 +2110,8 @@ bool BKE_nla_tweakmode_enter(AnimData *adt) } } - /* There are situations where we may have multiple strips selected and we want to enter tweakmode - * on all of those at once. Usually in those cases, + /* There are situations where we may have multiple strips selected and we want to enter + * tweak-mode on all of those at once. Usually in those cases, * it will usually just be a single strip per AnimData. * In such cases, compromise and take the last selected track and/or last selected strip, T28468. */ @@ -2142,7 +2141,7 @@ bool BKE_nla_tweakmode_enter(AnimData *adt) if (ELEM(NULL, activeTrack, activeStrip, activeStrip->act)) { if (G.debug & G_DEBUG) { - printf("NLA tweakmode enter - neither active requirement found\n"); + printf("NLA tweak-mode enter - neither active requirement found\n"); printf("\tactiveTrack = %p, activeStrip = %p\n", (void *)activeTrack, (void *)activeStrip); } return false; @@ -2192,7 +2191,7 @@ bool BKE_nla_tweakmode_enter(AnimData *adt) return true; } -/* Exit tweakmode for this AnimData block */ +/* Exit tweak-mode for this AnimData block. */ void BKE_nla_tweakmode_exit(AnimData *adt) { NlaStrip *strip; diff --git a/source/blender/blenkernel/intern/node.cc b/source/blender/blenkernel/intern/node.cc index f6105bac1a8..e4c259ec9fc 100644 --- a/source/blender/blenkernel/intern/node.cc +++ b/source/blender/blenkernel/intern/node.cc @@ -69,7 +69,6 @@ #include "BKE_lib_query.h" #include "BKE_main.h" #include "BKE_node.h" -#include "BKE_node_ui_storage.hh" #include "BLI_ghash.h" #include "BLI_threads.h" @@ -220,10 +219,6 @@ static void ntree_copy_data(Main *UNUSED(bmain), ID *id_dst, const ID *id_src, c /* node tree will generate its own interface type */ ntree_dst->interface_type = nullptr; - - /* Don't copy error messages in the runtime struct. - * They should be filled during execution anyway. */ - ntree_dst->ui_storage = nullptr; } static void ntree_free_data(ID *id) @@ -277,8 +272,6 @@ static void ntree_free_data(ID *id) if (ntree->id.tag & LIB_TAG_LOCALIZED) { BKE_libblock_free_data(&ntree->id, true); } - - delete ntree->ui_storage; } static void library_foreach_node_socket(LibraryForeachIDData *data, bNodeSocket *sock) @@ -621,7 +614,6 @@ static void ntree_blend_write(BlendWriter *writer, ID *id, const void *id_addres ntree->interface_type = nullptr; ntree->progress = nullptr; ntree->execdata = nullptr; - ntree->ui_storage = nullptr; BLO_write_id_struct(writer, bNodeTree, id_address, &ntree->id); @@ -653,7 +645,6 @@ void ntreeBlendReadData(BlendDataReader *reader, bNodeTree *ntree) ntree->progress = nullptr; ntree->execdata = nullptr; - ntree->ui_storage = nullptr; BLO_read_data_address(reader, &ntree->adt); BKE_animdata_blend_read_data(reader, ntree->adt); @@ -1425,6 +1416,12 @@ GHashIterator *nodeSocketTypeGetIterator(void) return BLI_ghashIterator_new(nodesockettypes_hash); } +const char *nodeSocketTypeLabel(const bNodeSocketType *stype) +{ + /* Use socket type name as a fallback if label is undefined. */ + return stype->label[0] != '\0' ? stype->label : RNA_struct_ui_name(stype->ext_socket.srna); +} + struct bNodeSocket *nodeFindSocket(const bNode *node, eNodeSocketInOut in_out, const char *identifier) @@ -1585,13 +1582,15 @@ static void socket_id_user_decrement(bNodeSocket *sock) } } -void nodeModifySocketType( - bNodeTree *ntree, bNode *UNUSED(node), bNodeSocket *sock, int type, int subtype) +void nodeModifySocketType(bNodeTree *ntree, + bNode *UNUSED(node), + bNodeSocket *sock, + const char *idname) { - const char *idname = nodeStaticSocketType(type, subtype); + bNodeSocketType *socktype = nodeSocketTypeFind(idname); - if (!idname) { - CLOG_ERROR(&LOG, "static node socket type %d undefined", type); + if (!socktype) { + CLOG_ERROR(&LOG, "node socket type %s undefined", idname); return; } @@ -1601,9 +1600,21 @@ void nodeModifySocketType( sock->default_value = nullptr; } - sock->type = type; BLI_strncpy(sock->idname, idname, sizeof(sock->idname)); - node_socket_set_typeinfo(ntree, sock, nodeSocketTypeFind(idname)); + node_socket_set_typeinfo(ntree, sock, socktype); +} + +void nodeModifySocketTypeStatic( + bNodeTree *ntree, bNode *node, bNodeSocket *sock, int type, int subtype) +{ + const char *idname = nodeStaticSocketType(type, subtype); + + if (!idname) { + CLOG_ERROR(&LOG, "static node socket type %d undefined", type); + return; + } + + nodeModifySocketType(ntree, node, sock, idname); } bNodeSocket *nodeAddSocket(bNodeTree *ntree, @@ -1647,6 +1658,15 @@ bNodeSocket *nodeInsertSocket(bNodeTree *ntree, return sock; } +bool nodeIsStaticSocketType(const struct bNodeSocketType *stype) +{ + /* + * Cannot rely on type==SOCK_CUSTOM here, because type is 0 by default + * and can be changed on custom sockets. + */ + return RNA_struct_is_a(stype->ext_socket.srna, &RNA_NodeSocketStandard); +} + const char *nodeStaticSocketType(int type, int subtype) { switch (type) { @@ -1801,6 +1821,39 @@ const char *nodeStaticSocketInterfaceType(int type, int subtype) return nullptr; } +const char *nodeStaticSocketLabel(int type, int UNUSED(subtype)) +{ + switch (type) { + case SOCK_FLOAT: + return "Float"; + case SOCK_INT: + return "Integer"; + case SOCK_BOOLEAN: + return "Boolean"; + case SOCK_VECTOR: + return "Vector"; + case SOCK_RGBA: + return "Color"; + case SOCK_STRING: + return "String"; + case SOCK_SHADER: + return "Shader"; + case SOCK_OBJECT: + return "Object"; + case SOCK_IMAGE: + return "Image"; + case SOCK_GEOMETRY: + return "Geometry"; + case SOCK_COLLECTION: + return "Collection"; + case SOCK_TEXTURE: + return "Texture"; + case SOCK_MATERIAL: + return "Material"; + } + return nullptr; +} + bNodeSocket *nodeAddStaticSocket(bNodeTree *ntree, bNode *node, eNodeSocketInOut in_out, @@ -5044,27 +5097,29 @@ static void registerGeometryNodes() register_node_type_geo_attribute_mix(); register_node_type_geo_attribute_proximity(); register_node_type_geo_attribute_randomize(); + register_node_type_geo_attribute_remove(); register_node_type_geo_attribute_separate_xyz(); register_node_type_geo_attribute_transfer(); register_node_type_geo_attribute_vector_math(); register_node_type_geo_attribute_vector_rotate(); - register_node_type_geo_attribute_remove(); register_node_type_geo_boolean(); register_node_type_geo_bounding_box(); register_node_type_geo_collection_info(); register_node_type_geo_convex_hull(); + register_node_type_geo_curve_endpoints(); register_node_type_geo_curve_length(); register_node_type_geo_curve_primitive_bezier_segment(); register_node_type_geo_curve_primitive_circle(); register_node_type_geo_curve_primitive_line(); register_node_type_geo_curve_primitive_quadratic_bezier(); + register_node_type_geo_curve_primitive_quadrilateral(); register_node_type_geo_curve_primitive_spiral(); register_node_type_geo_curve_primitive_star(); - register_node_type_geo_curve_to_mesh(); - register_node_type_geo_curve_to_points(); register_node_type_geo_curve_resample(); register_node_type_geo_curve_reverse(); register_node_type_geo_curve_subdivide(); + register_node_type_geo_curve_to_mesh(); + register_node_type_geo_curve_to_points(); register_node_type_geo_delete_geometry(); register_node_type_geo_edge_split(); register_node_type_geo_input_material(); @@ -5080,6 +5135,7 @@ static void registerGeometryNodes() register_node_type_geo_mesh_primitive_ico_sphere(); register_node_type_geo_mesh_primitive_line(); register_node_type_geo_mesh_primitive_uv_sphere(); + register_node_type_geo_mesh_subdivide(); register_node_type_geo_mesh_to_curve(); register_node_type_geo_object_info(); register_node_type_geo_point_distribute(); @@ -5093,7 +5149,6 @@ static void registerGeometryNodes() register_node_type_geo_sample_texture(); register_node_type_geo_select_by_material(); register_node_type_geo_separate_components(); - register_node_type_geo_subdivide(); register_node_type_geo_subdivision_surface(); register_node_type_geo_switch(); register_node_type_geo_transform(); diff --git a/source/blender/blenkernel/intern/node_ui_storage.cc b/source/blender/blenkernel/intern/node_ui_storage.cc deleted file mode 100644 index e5e9f00c7c3..00000000000 --- a/source/blender/blenkernel/intern/node_ui_storage.cc +++ /dev/null @@ -1,169 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include "CLG_log.h" - -#include <mutex> - -#include "BLI_map.hh" -#include "BLI_string_ref.hh" -#include "BLI_vector.hh" - -#include "DNA_node_types.h" -#include "DNA_object_types.h" - -#include "BKE_context.h" -#include "BKE_node_ui_storage.hh" -#include "BKE_object.h" - -static CLG_LogRef LOG = {"bke.node_ui_storage"}; - -using blender::Map; -using blender::StringRef; -using blender::Vector; - -/* Use a global mutex because otherwise it would have to be stored directly in the - * bNodeTree struct in DNA. This could change if the node tree had a runtime struct. */ -static std::mutex global_ui_storage_mutex; - -static NodeTreeUIStorage &ui_storage_ensure(bNodeTree &ntree) -{ - /* As an optimization, only acquire a lock if the UI storage doesn't exist, - * because it only needs to be allocated once for every node tree. */ - if (ntree.ui_storage == nullptr) { - std::lock_guard<std::mutex> lock(global_ui_storage_mutex); - /* Check again-- another thread may have allocated the storage while this one waited. */ - if (ntree.ui_storage == nullptr) { - ntree.ui_storage = new NodeTreeUIStorage(); - } - } - return *ntree.ui_storage; -} - -const NodeUIStorage *BKE_node_tree_ui_storage_get_from_context(const bContext *C, - const bNodeTree &ntree, - const bNode &node) -{ - const NodeTreeUIStorage *ui_storage = ntree.ui_storage; - if (ui_storage == nullptr) { - return nullptr; - } - - const Object *active_object = CTX_data_active_object(C); - if (active_object == nullptr) { - return nullptr; - } - - const ModifierData *active_modifier = BKE_object_active_modifier(active_object); - if (active_modifier == nullptr) { - return nullptr; - } - - const NodeTreeEvaluationContext context(*active_object, *active_modifier); - const Map<std::string, NodeUIStorage> *storage = ui_storage->context_map.lookup_ptr(context); - if (storage == nullptr) { - return nullptr; - } - - return storage->lookup_ptr_as(StringRef(node.name)); -} - -/** - * Removes only the UI data associated with a particular evaluation context. The same node tree - * can be used for execution in multiple places, but the entire UI storage can't be removed when - * one execution starts, or all of the data associated with the node tree would be lost. - */ -void BKE_nodetree_ui_storage_free_for_context(bNodeTree &ntree, - const NodeTreeEvaluationContext &context) -{ - NodeTreeUIStorage *ui_storage = ntree.ui_storage; - if (ui_storage != nullptr) { - std::lock_guard<std::mutex> lock(ui_storage->mutex); - ui_storage->context_map.remove(context); - } -} - -static void node_error_message_log(bNodeTree &ntree, - const bNode &node, - const StringRef message, - const NodeWarningType type) -{ - switch (type) { - case NodeWarningType::Error: - CLOG_ERROR(&LOG, - "Node Tree: \"%s\", Node: \"%s\", %s", - ntree.id.name + 2, - node.name, - message.data()); - break; - case NodeWarningType::Warning: - CLOG_WARN(&LOG, - "Node Tree: \"%s\", Node: \"%s\", %s", - ntree.id.name + 2, - node.name, - message.data()); - break; - case NodeWarningType::Info: - CLOG_INFO(&LOG, - 2, - "Node Tree: \"%s\", Node: \"%s\", %s", - ntree.id.name + 2, - node.name, - message.data()); - break; - } -} - -static NodeUIStorage &node_ui_storage_ensure(NodeTreeUIStorage &locked_ui_storage, - const NodeTreeEvaluationContext &context, - const bNode &node) -{ - Map<std::string, NodeUIStorage> &node_tree_ui_storage = - locked_ui_storage.context_map.lookup_or_add_default(context); - NodeUIStorage &node_ui_storage = node_tree_ui_storage.lookup_or_add_default_as( - StringRef(node.name)); - return node_ui_storage; -} - -void BKE_nodetree_error_message_add(bNodeTree &ntree, - const NodeTreeEvaluationContext &context, - const bNode &node, - const NodeWarningType type, - std::string message) -{ - NodeTreeUIStorage &ui_storage = ui_storage_ensure(ntree); - std::lock_guard lock{ui_storage.mutex}; - - node_error_message_log(ntree, node, message, type); - - NodeUIStorage &node_ui_storage = node_ui_storage_ensure(ui_storage, context, node); - node_ui_storage.warnings.append({type, std::move(message)}); -} - -void BKE_nodetree_attribute_hint_add(bNodeTree &ntree, - const NodeTreeEvaluationContext &context, - const bNode &node, - const StringRef attribute_name, - const AttributeDomain domain, - const CustomDataType data_type) -{ - NodeTreeUIStorage &ui_storage = ui_storage_ensure(ntree); - std::lock_guard lock{ui_storage.mutex}; - - NodeUIStorage &node_ui_storage = node_ui_storage_ensure(ui_storage, context, node); - node_ui_storage.attribute_hints.add_as( - AvailableAttributeInfo{attribute_name, domain, data_type}); -} diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c index a13feafb70b..912b5e0a0dd 100644 --- a/source/blender/blenkernel/intern/object.c +++ b/source/blender/blenkernel/intern/object.c @@ -1753,10 +1753,6 @@ void BKE_object_free_derived_caches(Object *ob) BKE_geometry_set_free(ob->runtime.geometry_set_eval); ob->runtime.geometry_set_eval = NULL; } - if (ob->runtime.geometry_set_previews != NULL) { - BLI_ghash_free(ob->runtime.geometry_set_previews, NULL, (GHashValFreeFP)BKE_geometry_set_free); - ob->runtime.geometry_set_previews = NULL; - } } void BKE_object_free_caches(Object *object) @@ -1807,24 +1803,6 @@ void BKE_object_free_caches(Object *object) } } -/* Can be called from multiple threads. */ -void BKE_object_preview_geometry_set_add(Object *ob, - const uint64_t key, - struct GeometrySet *geometry_set) -{ - static ThreadMutex mutex = BLI_MUTEX_INITIALIZER; - BLI_mutex_lock(&mutex); - if (ob->runtime.geometry_set_previews == NULL) { - ob->runtime.geometry_set_previews = BLI_ghash_int_new(__func__); - } - BLI_ghash_reinsert(ob->runtime.geometry_set_previews, - POINTER_FROM_UINT(key), - geometry_set, - NULL, - (GHashValFreeFP)BKE_geometry_set_free); - BLI_mutex_unlock(&mutex); -} - /** * Actual check for internal data, not context or flags. */ @@ -2828,7 +2806,7 @@ void BKE_object_copy_proxy_drivers(Object *ob, Object *target) /* add new animdata block */ if (!ob->adt) { - ob->adt = BKE_animdata_add_id(&ob->id); + ob->adt = BKE_animdata_ensure_id(&ob->id); } /* make a copy of all the drivers (for now), then correct any links that need fixing */ @@ -4155,6 +4133,30 @@ bool BKE_object_minmax_dupli(Depsgraph *depsgraph, return ok; } +struct GPencilStrokePointIterData { + const float (*obmat)[4]; + + void (*point_func_cb)(const float co[3], void *user_data); + void *user_data; +}; + +static void foreach_display_point_gpencil_stroke_fn(bGPDlayer *UNUSED(layer), + bGPDframe *UNUSED(frame), + bGPDstroke *stroke, + void *thunk) +{ + struct GPencilStrokePointIterData *iter_data = thunk; + { + bGPDspoint *pt; + int i; + for (i = 0, pt = stroke->points; i < stroke->totpoints; i++, pt++) { + float co[3]; + mul_v3_m4v3(co, iter_data->obmat, &pt->x); + iter_data->point_func_cb(co, iter_data->user_data); + } + } +} + void BKE_object_foreach_display_point(Object *ob, const float obmat[4][4], void (*func_cb)(const float[3], void *), @@ -4172,6 +4174,13 @@ void BKE_object_foreach_display_point(Object *ob, func_cb(co, user_data); } } + else if (ob->type == OB_GPENCIL) { + struct GPencilStrokePointIterData iter_data = { + .obmat = obmat, .point_func_cb = func_cb, .user_data = user_data}; + + BKE_gpencil_visible_stroke_iter( + ob->data, NULL, foreach_display_point_gpencil_stroke_fn, &iter_data); + } else if (ob->runtime.curve_cache && ob->runtime.curve_cache->disp.first) { DispList *dl; diff --git a/source/blender/blenkernel/intern/object_update.c b/source/blender/blenkernel/intern/object_update.c index ab247ef5507..7cdea14e9bd 100644 --- a/source/blender/blenkernel/intern/object_update.c +++ b/source/blender/blenkernel/intern/object_update.c @@ -123,7 +123,7 @@ void BKE_object_eval_parent(Depsgraph *depsgraph, Object *ob) void BKE_object_eval_constraints(Depsgraph *depsgraph, Scene *scene, Object *ob) { bConstraintOb *cob; - float ctime = BKE_scene_frame_get(scene); + float ctime = BKE_scene_ctime_get(scene); DEG_debug_print_eval(depsgraph, __func__, ob->id.name, ob); @@ -388,12 +388,31 @@ void BKE_object_batch_cache_dirty_tag(Object *ob) BKE_object_data_batch_cache_dirty_tag(ob->data); } +void BKE_object_data_eval_batch_cache_dirty_tag(Depsgraph *depsgraph, ID *object_data) +{ + DEG_debug_print_eval(depsgraph, __func__, object_data->name, object_data); + BKE_object_data_batch_cache_dirty_tag(object_data); +} + +void BKE_object_data_eval_batch_cache_deform_tag(Depsgraph *depsgraph, ID *object_data) +{ + DEG_debug_print_eval(depsgraph, __func__, object_data->name, object_data); + switch (GS(object_data->name)) { + case ID_ME: + BKE_mesh_batch_cache_dirty_tag((Mesh *)object_data, BKE_MESH_BATCH_DIRTY_DEFORM); + break; + default: + /* Only mesh is currently supported. Fallback to dirty all for other datablocks types. */ + BKE_object_data_batch_cache_dirty_tag(object_data); + break; + } +} + void BKE_object_eval_uber_data(Depsgraph *depsgraph, Scene *scene, Object *ob) { DEG_debug_print_eval(depsgraph, __func__, ob->id.name, ob); BLI_assert(ob->type != OB_ARMATURE); BKE_object_handle_data_update(depsgraph, scene, ob); - BKE_object_batch_cache_dirty_tag(ob); } void BKE_object_eval_ptcache_reset(Depsgraph *depsgraph, Scene *scene, Object *object) diff --git a/source/blender/blenkernel/intern/particle.c b/source/blender/blenkernel/intern/particle.c index 7504fbeed19..db1fbb56125 100644 --- a/source/blender/blenkernel/intern/particle.c +++ b/source/blender/blenkernel/intern/particle.c @@ -3961,7 +3961,7 @@ static ModifierData *object_add_or_copy_particle_system( psys->totpart = 0; psys->flag = PSYS_CURRENT; if (scene != NULL) { - psys->cfra = BKE_scene_frame_to_ctime(scene, CFRA + 1); + psys->cfra = BKE_scene_frame_to_ctime(scene, scene->r.cfra + 1); } DEG_relations_tag_update(bmain); diff --git a/source/blender/blenkernel/intern/pbvh.c b/source/blender/blenkernel/intern/pbvh.c index 18b4c72932d..1f8f9ce63ac 100644 --- a/source/blender/blenkernel/intern/pbvh.c +++ b/source/blender/blenkernel/intern/pbvh.c @@ -2157,7 +2157,7 @@ static bool pbvh_faces_node_raycast(PBVH *pbvh, const float *co[3]; if (origco) { - /* intersect with backuped original coordinates */ + /* Intersect with backed up original coordinates. */ co[0] = origco[face_verts[0]]; co[1] = origco[face_verts[1]]; co[2] = origco[face_verts[2]]; diff --git a/source/blender/blenkernel/intern/pointcache.c b/source/blender/blenkernel/intern/pointcache.c index 90018e64f78..9ed5b0230e6 100644 --- a/source/blender/blenkernel/intern/pointcache.c +++ b/source/blender/blenkernel/intern/pointcache.c @@ -2807,8 +2807,8 @@ void BKE_ptcache_id_time( cache = pid->cache; if (timescale) { - time = BKE_scene_frame_get(scene); - nexttime = BKE_scene_frame_to_ctime(scene, CFRA + 1.0f); + time = BKE_scene_ctime_get(scene); + nexttime = BKE_scene_frame_to_ctime(scene, scene->r.cfra + 1); *timescale = MAX2(nexttime - time, 0.0f); } diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c index f8f4d52fcf2..cc5a8536a5a 100644 --- a/source/blender/blenkernel/intern/scene.c +++ b/source/blender/blenkernel/intern/scene.c @@ -2299,10 +2299,7 @@ Object *BKE_scene_camera_switch_find(Scene *scene) return NULL; } - const int cfra = ((scene->r.images == scene->r.framapto) ? - scene->r.cfra : - (int)(scene->r.cfra * - ((float)scene->r.framapto / (float)scene->r.images))); + const int ctime = (int)BKE_scene_ctime_get(scene); int frame = -(MAXFRAME + 1); int min_frame = MAXFRAME + 1; Object *camera = NULL; @@ -2310,11 +2307,11 @@ Object *BKE_scene_camera_switch_find(Scene *scene) LISTBASE_FOREACH (TimeMarker *, m, &scene->markers) { if (m->camera && (m->camera->restrictflag & OB_RESTRICT_RENDER) == 0) { - if ((m->frame <= cfra) && (m->frame > frame)) { + if ((m->frame <= ctime) && (m->frame > frame)) { camera = m->camera; frame = m->frame; - if (frame == cfra) { + if (frame == ctime) { break; } } @@ -2396,13 +2393,13 @@ const char *BKE_scene_find_last_marker_name(const Scene *scene, int frame) return best_marker ? best_marker->name : NULL; } -int BKE_scene_frame_snap_by_seconds(Scene *scene, double interval_in_seconds, int cfra) +int BKE_scene_frame_snap_by_seconds(Scene *scene, double interval_in_seconds, int frame) { const int fps = round_db_to_int(FPS * interval_in_seconds); - const int second_prev = cfra - mod_i(cfra, fps); + const int second_prev = frame - mod_i(frame, fps); const int second_next = second_prev + fps; - const int delta_prev = cfra - second_prev; - const int delta_next = second_next - cfra; + const int delta_prev = frame - second_prev; + const int delta_next = second_next - frame; return (delta_prev < delta_next) ? second_prev : second_next; } @@ -2444,16 +2441,17 @@ bool BKE_scene_validate_setscene(Main *bmain, Scene *sce) return true; } -/** - * This function is needed to cope with fractional frames, needed for motion blur & physics. - */ -float BKE_scene_frame_get(const Scene *scene) +/* Return fractional frame number taking into account subframes and time + * remapping. This the time value used by animation, modifiers and physics + * evaluation. */ +float BKE_scene_ctime_get(const Scene *scene) { return BKE_scene_frame_to_ctime(scene, scene->r.cfra); } -/* This function is used to obtain arbitrary fractional frames */ -float BKE_scene_frame_to_ctime(const Scene *scene, const float frame) +/* Convert integer frame number to fractional frame number taking into account + * subframes and time remapping. */ +float BKE_scene_frame_to_ctime(const Scene *scene, const int frame) { float ctime = frame; ctime += scene->r.subframe; @@ -2461,13 +2459,18 @@ float BKE_scene_frame_to_ctime(const Scene *scene, const float frame) return ctime; } -/** - * Sets the frame int/float components. - */ -void BKE_scene_frame_set(struct Scene *scene, double cfra) + +/* Get current fractional frame based on frame and subframe. */ +float BKE_scene_frame_get(const Scene *scene) +{ + return scene->r.cfra + scene->r.subframe; +} + +/* Set current frame and subframe based on a fractional frame. */ +void BKE_scene_frame_set(Scene *scene, float frame) { double intpart; - scene->r.subframe = modf(cfra, &intpart); + scene->r.subframe = modf((double)frame, &intpart); scene->r.cfra = (int)intpart; } @@ -2736,8 +2739,8 @@ void BKE_scene_graph_update_for_newframe_ex(Depsgraph *depsgraph, const bool cle * edits from callback are properly taken into account. Doing a time update on those would * lose any possible unkeyed changes made by the handler. */ if (pass == 0) { - const float ctime = BKE_scene_frame_get(scene); - DEG_evaluate_on_framechange(depsgraph, ctime); + const float frame = BKE_scene_frame_get(scene); + DEG_evaluate_on_framechange(depsgraph, frame); } else { DEG_evaluate_on_refresh(depsgraph); diff --git a/source/blender/blenkernel/intern/screen.c b/source/blender/blenkernel/intern/screen.c index a2809543b95..73658c3184e 100644 --- a/source/blender/blenkernel/intern/screen.c +++ b/source/blender/blenkernel/intern/screen.c @@ -1734,6 +1734,12 @@ static void direct_link_area(BlendDataReader *reader, ScrArea *area) sfile->runtime = NULL; BLO_read_data_address(reader, &sfile->params); BLO_read_data_address(reader, &sfile->asset_params); + if (sfile->params) { + sfile->params->rename_id = NULL; + } + if (sfile->asset_params) { + sfile->asset_params->base_params.rename_id = NULL; + } } else if (sl->spacetype == SPACE_ACTION) { SpaceAction *saction = (SpaceAction *)sl; diff --git a/source/blender/blenkernel/intern/softbody.c b/source/blender/blenkernel/intern/softbody.c index f978e5e8de4..e4e2ed94b41 100644 --- a/source/blender/blenkernel/intern/softbody.c +++ b/source/blender/blenkernel/intern/softbody.c @@ -3086,7 +3086,7 @@ static void softbody_to_object(Object *ob, float (*vertexCos)[3], int numVerts, if (sb->solverflags & SBSO_ESTIMATEIPO) { SB_estimate_transform(ob, sb->lcom, sb->lrot, sb->lscale); } - /* inverse matrix is not uptodate... */ + /* Inverse matrix is not up to date. */ invert_m4_m4(ob->imat, ob->obmat); for (a = 0; a < numVerts; a++, bp++) { diff --git a/source/blender/blenkernel/intern/spline_base.cc b/source/blender/blenkernel/intern/spline_base.cc index aa0d95d4d61..6234cdf87e2 100644 --- a/source/blender/blenkernel/intern/spline_base.cc +++ b/source/blender/blenkernel/intern/spline_base.cc @@ -512,6 +512,10 @@ void Spline::sample_with_index_factors(const GVArray &src, using T = decltype(dummy); const GVArray_Typed<T> src_typed = src.typed<T>(); MutableSpan<T> dst_typed = dst.typed<T>(); + if (src.size() == 1) { + dst_typed.fill(src_typed[0]); + return; + } blender::threading::parallel_for(dst_typed.index_range(), 1024, [&](IndexRange range) { for (const int i : range) { const LookupResult interp = this->lookup_data_from_index_factor(index_factors[i]); diff --git a/source/blender/blenkernel/intern/spline_nurbs.cc b/source/blender/blenkernel/intern/spline_nurbs.cc index 76d046337c0..ac6f1bd082c 100644 --- a/source/blender/blenkernel/intern/spline_nurbs.cc +++ b/source/blender/blenkernel/intern/spline_nurbs.cc @@ -346,7 +346,10 @@ Span<NURBSpline::BasisCache> NURBSpline::calculate_basis_cache() const const int size = this->size(); const int eval_size = this->evaluated_points_size(); - BLI_assert(this->evaluated_edges_size() > 0); + if (eval_size == 0) { + return {}; + } + basis_cache_.resize(eval_size); const int order = this->order(); diff --git a/source/blender/blenkernel/intern/studiolight.c b/source/blender/blenkernel/intern/studiolight.c index 4cc2d101b02..dc5162f201e 100644 --- a/source/blender/blenkernel/intern/studiolight.c +++ b/source/blender/blenkernel/intern/studiolight.c @@ -1352,7 +1352,7 @@ static void studiolight_irradiance_preview(uint *icon_buffer, StudioLight *sl) ITER_PIXELS_END; } -void BKE_studiolight_default(SolidLight lights[4], float light_ambient[4]) +void BKE_studiolight_default(SolidLight lights[4], float light_ambient[3]) { copy_v3_fl3(light_ambient, 0.0, 0.0, 0.0); diff --git a/source/blender/blenkernel/intern/tracking_region_tracker.c b/source/blender/blenkernel/intern/tracking_region_tracker.c index ef36acdc3d5..179def0a6f2 100644 --- a/source/blender/blenkernel/intern/tracking_region_tracker.c +++ b/source/blender/blenkernel/intern/tracking_region_tracker.c @@ -155,7 +155,7 @@ static ImBuf *tracking_context_get_keyframed_ibuf(MovieClip *clip, return tracking_context_get_frame_ibuf(clip, user, clip_flag, keyed_framenr); } -/* Get image buffer which si used as reference for track. */ +/* Get image buffer which is used as reference for track. */ static ImBuf *tracking_context_get_reference_ibuf(MovieClip *clip, MovieClipUser *user, int clip_flag, diff --git a/source/blender/blenkernel/intern/undo_system.c b/source/blender/blenkernel/intern/undo_system.c index fe2aa701c63..03bd9323f39 100644 --- a/source/blender/blenkernel/intern/undo_system.c +++ b/source/blender/blenkernel/intern/undo_system.c @@ -722,6 +722,24 @@ eUndoStepDir BKE_undosys_step_calc_direction(const UndoStack *ustack, } /** + * When reading undo steps for undo/redo, + * some extra checks are needed when so the correct undo step is decoded. + */ +static UndoStep *undosys_step_iter_first(UndoStep *us_reference, const eUndoStepDir undo_dir) +{ + if (us_reference->type->flags & UNDOTYPE_FLAG_DECODE_ACTIVE_STEP) { + /* Reading this step means an undo action reads undo twice. + * This should be avoided where possible, however some undo systems require it. + * + * Redo skips the current state as this represents the currently loaded state. */ + return (undo_dir == -1) ? us_reference : us_reference->next; + } + + /* Typical case, skip reading the current undo step. */ + return (undo_dir == -1) ? us_reference->prev : us_reference->next; +} + +/** * Undo/Redo until the given `us_target` step becomes the active (currently loaded) one. * * \note Unless `us_target` is a 'skipped' one and `use_skip` is true, `us_target` will become the @@ -786,15 +804,10 @@ bool BKE_undosys_step_load_data_ex(UndoStack *ustack, us_target->type->name, undo_dir); - /* Undo/Redo steps until we reach given target step (or beyond if it has to be skipped), from - * given reference step. - * - * NOTE: Unlike with redo case, where we can expect current active step to fully reflect current - * data status, in undo case we also do reload the active step. - * FIXME: this feels weak, and should probably not be actually needed? Or should also be done in - * redo case? */ + /* Undo/Redo steps until we reach given target step (or beyond if it has to be skipped), + * from given reference step. */ bool is_processing_extra_skipped_steps = false; - for (UndoStep *us_iter = (undo_dir == -1) ? us_reference : us_reference->next; us_iter != NULL; + for (UndoStep *us_iter = undosys_step_iter_first(us_reference, undo_dir); us_iter != NULL; us_iter = (undo_dir == -1) ? us_iter->prev : us_iter->next) { BLI_assert(us_iter != NULL); |