diff options
author | Antonio Vazquez <blendergit@gmail.com> | 2022-06-21 20:09:54 +0300 |
---|---|---|
committer | Antonio Vazquez <blendergit@gmail.com> | 2022-06-21 20:09:54 +0300 |
commit | dd6d0aefcc56288bfe154fe06df56163d6961372 (patch) | |
tree | 7b74c26bcd48d0fbd844fd8b286c9a399813b203 /source/blender/blenkernel/intern | |
parent | c27a395d8cd8b58b3155cfdc26ae35198fbcdb14 (diff) | |
parent | 714001683888770f9d870ba73edd65f4c2757bda (diff) |
Merge branch 'master' into asset-greasepencilasset-greasepencil
Diffstat (limited to 'source/blender/blenkernel/intern')
-rw-r--r-- | source/blender/blenkernel/intern/constraint.c | 146 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/curves_geometry.cc | 1 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/effect.c | 2 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/fluid.c | 1 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/gpencil_modifier.c | 2 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/image.cc | 2 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/lib_override.cc | 58 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/mesh_boolean_convert.cc | 24 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/mesh_sample.cc | 172 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/mesh_tangent.c | 2 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/nla.c | 25 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/node.cc | 1 |
12 files changed, 339 insertions, 97 deletions
diff --git a/source/blender/blenkernel/intern/constraint.c b/source/blender/blenkernel/intern/constraint.c index 6ffb3299869..aa09541c043 100644 --- a/source/blender/blenkernel/intern/constraint.c +++ b/source/blender/blenkernel/intern/constraint.c @@ -949,30 +949,9 @@ static void default_get_tarmat_full_bbone(struct Depsgraph *UNUSED(depsgraph), } \ (void)0 -static void custom_space_id_looper(bConstraint *con, ConstraintIDFunc func, void *userdata) +static bool is_custom_space_needed(bConstraint *con) { - func(con, (ID **)&con->space_object, false, userdata); -} - -static int get_space_tar(bConstraint *con, ListBase *list) -{ - if (!con || !list || - (con->ownspace != CONSTRAINT_SPACE_CUSTOM && con->tarspace != CONSTRAINT_SPACE_CUSTOM)) { - return 0; - } - bConstraintTarget *ct; - SINGLETARGET_GET_TARS(con, con->space_object, con->space_subtarget, ct, list); - return 1; -} - -static void flush_space_tar(bConstraint *con, ListBase *list, bool no_copy) -{ - if (!con || !list || - (con->ownspace != CONSTRAINT_SPACE_CUSTOM && con->tarspace != CONSTRAINT_SPACE_CUSTOM)) { - return; - } - bConstraintTarget *ct = (bConstraintTarget *)list->last; - SINGLETARGET_FLUSH_TARS(con, con->space_object, con->space_subtarget, ct, list, no_copy); + return con->ownspace == CONSTRAINT_SPACE_CUSTOM || con->tarspace == CONSTRAINT_SPACE_CUSTOM; } /* --------- ChildOf Constraint ------------ */ @@ -1161,8 +1140,6 @@ static void trackto_id_looper(bConstraint *con, ConstraintIDFunc func, void *use /* target only */ func(con, (ID **)&data->tar, false, userdata); - - custom_space_id_looper(con, func, userdata); } static int trackto_get_tars(bConstraint *con, ListBase *list) @@ -1174,7 +1151,7 @@ static int trackto_get_tars(bConstraint *con, ListBase *list) /* standard target-getting macro for single-target constraints */ SINGLETARGET_GET_TARS(con, data->tar, data->subtarget, ct, list); - return 1 + get_space_tar(con, list); + return 1; } return 0; @@ -1188,7 +1165,6 @@ static void trackto_flush_tars(bConstraint *con, ListBase *list, bool no_copy) /* the following macro is used for all standard single-target constraints */ SINGLETARGET_FLUSH_TARS(con, data->tar, data->subtarget, ct, list, no_copy); - flush_space_tar(con, list, no_copy); } } @@ -1661,11 +1637,11 @@ static bConstraintTypeInfo CTI_LOCLIMIT = { "Limit Location", /* name */ "bLocLimitConstraint", /* struct name */ NULL, /* free data */ - custom_space_id_looper, /* id looper */ + NULL, /* id looper */ NULL, /* copy data */ NULL, /* new data */ - get_space_tar, /* get constraint targets */ - flush_space_tar, /* flush constraint targets */ + NULL, /* get constraint targets */ + NULL, /* flush constraint targets */ NULL, /* get target matrix */ loclimit_evaluate, /* evaluate */ }; @@ -1742,11 +1718,11 @@ static bConstraintTypeInfo CTI_ROTLIMIT = { "Limit Rotation", /* name */ "bRotLimitConstraint", /* struct name */ NULL, /* free data */ - custom_space_id_looper, /* id looper */ + NULL, /* id looper */ NULL, /* copy data */ NULL, /* new data */ - get_space_tar, /* get constraint targets */ - flush_space_tar, /* flush constraint targets */ + NULL, /* get constraint targets */ + NULL, /* flush constraint targets */ NULL, /* get target matrix */ rotlimit_evaluate, /* evaluate */ }; @@ -1809,11 +1785,11 @@ static bConstraintTypeInfo CTI_SIZELIMIT = { "Limit Scale", /* name */ "bSizeLimitConstraint", /* struct name */ NULL, /* free data */ - custom_space_id_looper, /* id looper */ + NULL, /* id looper */ NULL, /* copy data */ NULL, /* new data */ - get_space_tar, /* get constraint targets */ - flush_space_tar, /* flush constraint targets */ + NULL, /* get constraint targets */ + NULL, /* flush constraint targets */ NULL, /* get target matrix */ sizelimit_evaluate, /* evaluate */ }; @@ -1833,8 +1809,6 @@ static void loclike_id_looper(bConstraint *con, ConstraintIDFunc func, void *use /* target only */ func(con, (ID **)&data->tar, false, userdata); - - custom_space_id_looper(con, func, userdata); } static int loclike_get_tars(bConstraint *con, ListBase *list) @@ -1846,7 +1820,7 @@ static int loclike_get_tars(bConstraint *con, ListBase *list) /* standard target-getting macro for single-target constraints */ SINGLETARGET_GET_TARS(con, data->tar, data->subtarget, ct, list); - return 1 + get_space_tar(con, list); + return 1; } return 0; @@ -1860,7 +1834,6 @@ static void loclike_flush_tars(bConstraint *con, ListBase *list, bool no_copy) /* the following macro is used for all standard single-target constraints */ SINGLETARGET_FLUSH_TARS(con, data->tar, data->subtarget, ct, list, no_copy); - flush_space_tar(con, list, no_copy); } } @@ -1933,8 +1906,6 @@ static void rotlike_id_looper(bConstraint *con, ConstraintIDFunc func, void *use /* target only */ func(con, (ID **)&data->tar, false, userdata); - - custom_space_id_looper(con, func, userdata); } static int rotlike_get_tars(bConstraint *con, ListBase *list) @@ -1946,7 +1917,7 @@ static int rotlike_get_tars(bConstraint *con, ListBase *list) /* standard target-getting macro for single-target constraints */ SINGLETARGET_GET_TARS(con, data->tar, data->subtarget, ct, list); - return 1 + get_space_tar(con, list); + return 1; } return 0; @@ -1960,7 +1931,6 @@ static void rotlike_flush_tars(bConstraint *con, ListBase *list, bool no_copy) /* the following macro is used for all standard single-target constraints */ SINGLETARGET_FLUSH_TARS(con, data->tar, data->subtarget, ct, list, no_copy); - flush_space_tar(con, list, no_copy); } } @@ -2114,8 +2084,6 @@ static void sizelike_id_looper(bConstraint *con, ConstraintIDFunc func, void *us /* target only */ func(con, (ID **)&data->tar, false, userdata); - - custom_space_id_looper(con, func, userdata); } static int sizelike_get_tars(bConstraint *con, ListBase *list) @@ -2127,7 +2095,7 @@ static int sizelike_get_tars(bConstraint *con, ListBase *list) /* standard target-getting macro for single-target constraints */ SINGLETARGET_GET_TARS(con, data->tar, data->subtarget, ct, list); - return 1 + get_space_tar(con, list); + return 1; } return 0; @@ -2141,7 +2109,6 @@ static void sizelike_flush_tars(bConstraint *con, ListBase *list, bool no_copy) /* the following macro is used for all standard single-target constraints */ SINGLETARGET_FLUSH_TARS(con, data->tar, data->subtarget, ct, list, no_copy); - flush_space_tar(con, list, no_copy); } } @@ -2239,8 +2206,6 @@ static void translike_id_looper(bConstraint *con, ConstraintIDFunc func, void *u /* target only */ func(con, (ID **)&data->tar, false, userdata); - - custom_space_id_looper(con, func, userdata); } static int translike_get_tars(bConstraint *con, ListBase *list) @@ -2252,7 +2217,7 @@ static int translike_get_tars(bConstraint *con, ListBase *list) /* standard target-getting macro for single-target constraints */ SINGLETARGET_GET_TARS(con, data->tar, data->subtarget, ct, list); - return 1 + get_space_tar(con, list); + return 1; } return 0; @@ -2266,7 +2231,6 @@ static void translike_flush_tars(bConstraint *con, ListBase *list, bool no_copy) /* the following macro is used for all standard single-target constraints */ SINGLETARGET_FLUSH_TARS(con, data->tar, data->subtarget, ct, list, no_copy); - flush_space_tar(con, list, no_copy); } } @@ -2400,11 +2364,11 @@ static bConstraintTypeInfo CTI_SAMEVOL = { "Maintain Volume", /* name */ "bSameVolumeConstraint", /* struct name */ NULL, /* free data */ - custom_space_id_looper, /* id looper */ + NULL, /* id looper */ NULL, /* copy data */ samevolume_new_data, /* new data */ - get_space_tar, /* get constraint targets */ - flush_space_tar, /* flush constraint targets */ + NULL, /* get constraint targets */ + NULL, /* flush constraint targets */ NULL, /* get target matrix */ samevolume_evaluate, /* evaluate */ }; @@ -2810,8 +2774,6 @@ static void actcon_id_looper(bConstraint *con, ConstraintIDFunc func, void *user /* action */ func(con, (ID **)&data->act, true, userdata); - - custom_space_id_looper(con, func, userdata); } static int actcon_get_tars(bConstraint *con, ListBase *list) @@ -2823,7 +2785,7 @@ static int actcon_get_tars(bConstraint *con, ListBase *list) /* standard target-getting macro for single-target constraints */ SINGLETARGET_GET_TARS(con, data->tar, data->subtarget, ct, list); - return 1 + get_space_tar(con, list); + return 1; } return 0; @@ -2837,7 +2799,6 @@ static void actcon_flush_tars(bConstraint *con, ListBase *list, bool no_copy) /* the following macro is used for all standard single-target constraints */ SINGLETARGET_FLUSH_TARS(con, data->tar, data->subtarget, ct, list, no_copy); - flush_space_tar(con, list, no_copy); } } @@ -3338,8 +3299,6 @@ static void distlimit_id_looper(bConstraint *con, ConstraintIDFunc func, void *u /* target only */ func(con, (ID **)&data->tar, false, userdata); - - custom_space_id_looper(con, func, userdata); } static int distlimit_get_tars(bConstraint *con, ListBase *list) @@ -3351,7 +3310,7 @@ static int distlimit_get_tars(bConstraint *con, ListBase *list) /* standard target-getting macro for single-target constraints */ SINGLETARGET_GET_TARS(con, data->tar, data->subtarget, ct, list); - return 1 + get_space_tar(con, list); + return 1; } return 0; @@ -3365,7 +3324,6 @@ static void distlimit_flush_tars(bConstraint *con, ListBase *list, bool no_copy) /* the following macro is used for all standard single-target constraints */ SINGLETARGET_FLUSH_TARS(con, data->tar, data->subtarget, ct, list, no_copy); - flush_space_tar(con, list, no_copy); } } @@ -3694,8 +3652,6 @@ static void minmax_id_looper(bConstraint *con, ConstraintIDFunc func, void *user /* target only */ func(con, (ID **)&data->tar, false, userdata); - - custom_space_id_looper(con, func, userdata); } static int minmax_get_tars(bConstraint *con, ListBase *list) @@ -3707,7 +3663,7 @@ static int minmax_get_tars(bConstraint *con, ListBase *list) /* standard target-getting macro for single-target constraints */ SINGLETARGET_GET_TARS(con, data->tar, data->subtarget, ct, list); - return 1 + get_space_tar(con, list); + return 1; } return 0; @@ -3721,7 +3677,6 @@ static void minmax_flush_tars(bConstraint *con, ListBase *list, bool no_copy) /* the following macro is used for all standard single-target constraints */ SINGLETARGET_FLUSH_TARS(con, data->tar, data->subtarget, ct, list, no_copy); - flush_space_tar(con, list, no_copy); } } @@ -4019,8 +3974,6 @@ static void transform_id_looper(bConstraint *con, ConstraintIDFunc func, void *u /* target only */ func(con, (ID **)&data->tar, false, userdata); - - custom_space_id_looper(con, func, userdata); } static int transform_get_tars(bConstraint *con, ListBase *list) @@ -4032,7 +3985,7 @@ static int transform_get_tars(bConstraint *con, ListBase *list) /* standard target-getting macro for single-target constraints */ SINGLETARGET_GET_TARS(con, data->tar, data->subtarget, ct, list); - return 1 + get_space_tar(con, list); + return 1; } return 0; @@ -4046,7 +3999,6 @@ static void transform_flush_tars(bConstraint *con, ListBase *list, bool no_copy) /* the following macro is used for all standard single-target constraints */ SINGLETARGET_FLUSH_TARS(con, data->tar, data->subtarget, ct, list, no_copy); - flush_space_tar(con, list, no_copy); } } @@ -5582,6 +5534,19 @@ static void con_unlink_refs_cb(bConstraint *UNUSED(con), } } +/** Helper function to invoke the id_looper callback, including custom space. */ +static void con_invoke_id_looper(const bConstraintTypeInfo *cti, + bConstraint *con, + ConstraintIDFunc func, + void *userdata) +{ + if (cti->id_looper) { + cti->id_looper(con, func, userdata); + } + + func(con, (ID **)&con->space_object, false, userdata); +} + void BKE_constraint_free_data_ex(bConstraint *con, bool do_id_user) { if (con->data) { @@ -5594,8 +5559,8 @@ void BKE_constraint_free_data_ex(bConstraint *con, bool do_id_user) } /* unlink the referenced resources it uses */ - if (do_id_user && cti->id_looper) { - cti->id_looper(con, con_unlink_refs_cb, NULL); + if (do_id_user) { + con_invoke_id_looper(cti, con, con_unlink_refs_cb, NULL); } } @@ -5913,9 +5878,7 @@ void BKE_constraints_id_loop(ListBase *conlist, ConstraintIDFunc func, void *use const bConstraintTypeInfo *cti = BKE_constraint_typeinfo_get(con); if (cti) { - if (cti->id_looper) { - cti->id_looper(con, func, userdata); - } + con_invoke_id_looper(cti, con, func, userdata); } } } @@ -5967,16 +5930,14 @@ static void constraint_copy_data_ex(bConstraint *dst, } /* Fix usercounts for all referenced data that need it. */ - if (cti->id_looper && (flag & LIB_ID_CREATE_NO_USER_REFCOUNT) == 0) { - cti->id_looper(dst, con_fix_copied_refs_cb, NULL); + if ((flag & LIB_ID_CREATE_NO_USER_REFCOUNT) == 0) { + con_invoke_id_looper(cti, dst, con_fix_copied_refs_cb, NULL); } /* for proxies we don't want to make extern */ if (do_extern) { /* go over used ID-links for this constraint to ensure that they are valid for proxies */ - if (cti->id_looper) { - cti->id_looper(dst, con_extern_cb, NULL); - } + con_invoke_id_looper(cti, dst, con_extern_cb, NULL); } } } @@ -6208,6 +6169,15 @@ int BKE_constraint_targets_get(struct bConstraint *con, struct ListBase *r_targe count = cti->get_constraint_targets(con, r_targets); } + /* Add the custom target. */ + if (is_custom_space_needed(con)) { + bConstraintTarget *ct; + SINGLETARGET_GET_TARS(con, con->space_object, con->space_subtarget, ct, r_targets); + ct->space = CONSTRAINT_SPACE_WORLD; + ct->flag |= CONSTRAINT_TAR_CUSTOM_SPACE; + count++; + } + return count; } @@ -6219,6 +6189,20 @@ void BKE_constraint_targets_flush(struct bConstraint *con, struct ListBase *targ return; } + /* Remove the custom target. */ + bConstraintTarget *ct = (bConstraintTarget *)targets->last; + + if (ct && (ct->flag & CONSTRAINT_TAR_CUSTOM_SPACE)) { + BLI_assert(is_custom_space_needed(con)); + + if (!no_copy) { + con->space_object = ct->tar; + BLI_strncpy(con->space_subtarget, ct->subtarget, sizeof(con->space_subtarget)); + } + + BLI_freelinkN(targets, ct); + } + /* Release the constraint-specific targets. */ if (cti->flush_constraint_targets) { cti->flush_constraint_targets(con, targets, no_copy); diff --git a/source/blender/blenkernel/intern/curves_geometry.cc b/source/blender/blenkernel/intern/curves_geometry.cc index 1c3715aaf69..b58781ce806 100644 --- a/source/blender/blenkernel/intern/curves_geometry.cc +++ b/source/blender/blenkernel/intern/curves_geometry.cc @@ -1370,6 +1370,7 @@ void CurvesGeometry::remove_curves(const IndexMask curves_to_delete) } if (curves_to_delete.size() == this->curves_num()) { *this = {}; + return; } *this = copy_with_removed_curves(*this, curves_to_delete); } diff --git a/source/blender/blenkernel/intern/effect.c b/source/blender/blenkernel/intern/effect.c index f2915a97746..7722c2fa004 100644 --- a/source/blender/blenkernel/intern/effect.c +++ b/source/blender/blenkernel/intern/effect.c @@ -868,8 +868,6 @@ static void do_texture_effector(EffectorCache *eff, return; } - result[0].nor = result[1].nor = result[2].nor = result[3].nor = NULL; - strength = eff->pd->f_strength * efd->falloff; copy_v3_v3(tex_co, point->loc); diff --git a/source/blender/blenkernel/intern/fluid.c b/source/blender/blenkernel/intern/fluid.c index 06d32d5bfd4..5cd5a699dec 100644 --- a/source/blender/blenkernel/intern/fluid.c +++ b/source/blender/blenkernel/intern/fluid.c @@ -1942,7 +1942,6 @@ static void sample_mesh(FluidFlowSettings *ffs, tex_co[1] = tex_co[1] * 2.0f - 1.0f; tex_co[2] = ffs->texture_offset; } - texres.nor = NULL; BKE_texture_get_value(NULL, ffs->noise_texture, tex_co, &texres, false); emission_strength *= texres.tin; } diff --git a/source/blender/blenkernel/intern/gpencil_modifier.c b/source/blender/blenkernel/intern/gpencil_modifier.c index 5ef4d231807..0bf5418ea8f 100644 --- a/source/blender/blenkernel/intern/gpencil_modifier.c +++ b/source/blender/blenkernel/intern/gpencil_modifier.c @@ -678,7 +678,7 @@ static void copy_frame_to_eval_cb(bGPDlayer *gpl, static void gpencil_copy_visible_frames_to_eval(Depsgraph *depsgraph, Scene *scene, Object *ob) { - /* Remap layers'active frame with time modifiers applied. */ + /* Remap layers active frame with time modifiers applied. */ bGPdata *gpd_eval = ob->data; LISTBASE_FOREACH (bGPDlayer *, gpl_eval, &gpd_eval->layers) { bGPDframe *gpf_eval = gpl_eval->actframe; diff --git a/source/blender/blenkernel/intern/image.cc b/source/blender/blenkernel/intern/image.cc index b9bb536d173..0c1f01c3796 100644 --- a/source/blender/blenkernel/intern/image.cc +++ b/source/blender/blenkernel/intern/image.cc @@ -1730,7 +1730,7 @@ static void stampdata_from_template(StampData *stamp_data, stamp_data->file[0] = '\0'; } if (scene->r.stamp & R_STAMP_NOTE) { - SNPRINTF(stamp_data->note, "%s", stamp_data_template->note); + STRNCPY(stamp_data->note, stamp_data_template->note); } else { stamp_data->note[0] = '\0'; diff --git a/source/blender/blenkernel/intern/lib_override.cc b/source/blender/blenkernel/intern/lib_override.cc index 22012662180..0b91a1e2866 100644 --- a/source/blender/blenkernel/intern/lib_override.cc +++ b/source/blender/blenkernel/intern/lib_override.cc @@ -687,6 +687,51 @@ static void lib_override_group_tag_data_clear(LibOverrideGroupTagData *data) memset(data, 0, sizeof(*data)); } +static void lib_override_hierarchy_dependencies_recursive_tag_from(LibOverrideGroupTagData *data) +{ + Main *bmain = data->bmain; + ID *id = data->id_root; + const bool is_override = data->is_override; + + if ((*(uint *)&id->tag & data->tag) == 0) { + /* This ID is not tagged, no reason to proceed further to its parents. */ + return; + } + + MainIDRelationsEntry *entry = static_cast<MainIDRelationsEntry *>( + BLI_ghash_lookup(bmain->relations->relations_from_pointers, id)); + BLI_assert(entry != nullptr); + + if (entry->tags & MAINIDRELATIONS_ENTRY_TAGS_PROCESSED_FROM) { + /* This ID has already been processed. */ + return; + } + /* This way we won't process again that ID, should we encounter it again through another + * relationship hierarchy. */ + entry->tags |= MAINIDRELATIONS_ENTRY_TAGS_PROCESSED_FROM; + + for (MainIDRelationsEntryItem *from_id_entry = entry->from_ids; from_id_entry != nullptr; + from_id_entry = from_id_entry->next) { + if ((from_id_entry->usage_flag & IDWALK_CB_OVERRIDE_LIBRARY_NOT_OVERRIDABLE) != 0) { + /* Never consider non-overridable relationships ('from', 'parents', 'owner' etc. pointers) + * as actual dependencies. */ + continue; + } + /* We only consider IDs from the same library. */ + ID *from_id = from_id_entry->id_pointer.from; + if (from_id == nullptr || from_id->lib != id->lib || + (is_override && !ID_IS_OVERRIDE_LIBRARY(from_id))) { + /* IDs from different libraries, or non-override IDs in case we are processing overrides, + * are both barriers of dependency. */ + continue; + } + from_id->tag |= data->tag; + LibOverrideGroupTagData sub_data = *data; + sub_data.id_root = from_id; + lib_override_hierarchy_dependencies_recursive_tag_from(&sub_data); + } +} + /* Tag all IDs in dependency relationships within an override hierarchy/group. * * Requires existing `Main.relations`. @@ -703,13 +748,13 @@ static bool lib_override_hierarchy_dependencies_recursive_tag(LibOverrideGroupTa BLI_ghash_lookup(bmain->relations->relations_from_pointers, id)); BLI_assert(entry != nullptr); - if (entry->tags & MAINIDRELATIONS_ENTRY_TAGS_PROCESSED) { + if (entry->tags & MAINIDRELATIONS_ENTRY_TAGS_PROCESSED_TO) { /* This ID has already been processed. */ return (*(uint *)&id->tag & data->tag) != 0; } /* This way we won't process again that ID, should we encounter it again through another * relationship hierarchy. */ - entry->tags |= MAINIDRELATIONS_ENTRY_TAGS_PROCESSED; + entry->tags |= MAINIDRELATIONS_ENTRY_TAGS_PROCESSED_TO; for (MainIDRelationsEntryItem *to_id_entry = entry->to_ids; to_id_entry != nullptr; to_id_entry = to_id_entry->next) { @@ -733,6 +778,15 @@ static bool lib_override_hierarchy_dependencies_recursive_tag(LibOverrideGroupTa } } + /* If the current ID is/has been tagged for override above, then check its reversed dependencies + * (i.e. IDs that depend on the current one). + * + * This will cover e.g. the case where user override an armature, and would expect the mesh + * object deformed by that armature to also be overridden. */ + if ((*(uint *)&id->tag & data->tag) != 0) { + lib_override_hierarchy_dependencies_recursive_tag_from(data); + } + return (*(uint *)&id->tag & data->tag) != 0; } diff --git a/source/blender/blenkernel/intern/mesh_boolean_convert.cc b/source/blender/blenkernel/intern/mesh_boolean_convert.cc index 14bd6aa5b2f..a1ef2d2e6b5 100644 --- a/source/blender/blenkernel/intern/mesh_boolean_convert.cc +++ b/source/blender/blenkernel/intern/mesh_boolean_convert.cc @@ -791,7 +791,8 @@ Mesh *direct_mesh_boolean(Span<const Mesh *> meshes, Span<Array<short>> material_remaps, const bool use_self, const bool hole_tolerant, - const int boolean_mode) + const int boolean_mode, + Vector<int> *r_intersecting_edges) { #ifdef WITH_GMP BLI_assert(meshes.size() == transforms.size()); @@ -828,7 +829,23 @@ Mesh *direct_mesh_boolean(Span<const Mesh *> meshes, write_obj_mesh(m_out, "m_out"); } - return imesh_to_mesh(&m_out, mim); + Mesh *result = imesh_to_mesh(&m_out, mim); + + /* Store intersecting edge indices. */ + if (r_intersecting_edges != nullptr) { + for (int fi : m_out.face_index_range()) { + const Face &face = *m_out.face(fi); + const MPoly &poly = result->mpoly[fi]; + for (int corner_i : face.index_range()) { + if (face.is_intersect[corner_i]) { + int e_index = result->mloop[poly.loopstart + corner_i].e; + r_intersecting_edges->append(e_index); + } + } + } + } + + return result; #else // WITH_GMP UNUSED_VARS(meshes, transforms, @@ -836,7 +853,8 @@ Mesh *direct_mesh_boolean(Span<const Mesh *> meshes, target_transform, use_self, hole_tolerant, - boolean_mode); + boolean_mode, + r_intersecting_edges); return nullptr; #endif // WITH_GMP } diff --git a/source/blender/blenkernel/intern/mesh_sample.cc b/source/blender/blenkernel/intern/mesh_sample.cc index 7595c08a208..106c4c610ba 100644 --- a/source/blender/blenkernel/intern/mesh_sample.cc +++ b/source/blender/blenkernel/intern/mesh_sample.cc @@ -2,12 +2,15 @@ #include "BKE_attribute_access.hh" #include "BKE_attribute_math.hh" +#include "BKE_bvhutils.h" #include "BKE_mesh_runtime.h" #include "BKE_mesh_sample.hh" #include "DNA_mesh_types.h" #include "DNA_meshdata_types.h" +#include "BLI_rand.hh" + namespace blender::bke::mesh_surface_sample { template<typename T> @@ -259,4 +262,173 @@ void MeshAttributeInterpolator::sample_attribute(const ReadAttributeLookup &src_ } } +int sample_surface_points_spherical(RandomNumberGenerator &rng, + const Mesh &mesh, + const Span<int> looptri_indices_to_sample, + const float3 &sample_pos, + const float sample_radius, + const float approximate_density, + Vector<float3> &r_bary_coords, + Vector<int> &r_looptri_indices, + Vector<float3> &r_positions) +{ + const Span<MLoopTri> looptris{BKE_mesh_runtime_looptri_ensure(&mesh), + BKE_mesh_runtime_looptri_len(&mesh)}; + + const float sample_radius_sq = pow2f(sample_radius); + const float sample_plane_area = M_PI * sample_radius_sq; + /* Used for switching between two triangle sampling strategies. */ + const float area_threshold = sample_plane_area; + + const int old_num = r_bary_coords.size(); + + for (const int looptri_index : looptri_indices_to_sample) { + const MLoopTri &looptri = looptris[looptri_index]; + + const float3 &v0 = mesh.mvert[mesh.mloop[looptri.tri[0]].v].co; + const float3 &v1 = mesh.mvert[mesh.mloop[looptri.tri[1]].v].co; + const float3 &v2 = mesh.mvert[mesh.mloop[looptri.tri[2]].v].co; + + const float looptri_area = area_tri_v3(v0, v1, v2); + + if (looptri_area < area_threshold) { + /* The triangle is small compared to the sample radius. Sample by generating random + * barycentric coordinates. */ + const int amount = rng.round_probabilistic(approximate_density * looptri_area); + for ([[maybe_unused]] const int i : IndexRange(amount)) { + const float3 bary_coord = rng.get_barycentric_coordinates(); + const float3 point_pos = attribute_math::mix3(bary_coord, v0, v1, v2); + const float dist_to_sample_sq = math::distance_squared(point_pos, sample_pos); + if (dist_to_sample_sq > sample_radius_sq) { + continue; + } + + r_bary_coords.append(bary_coord); + r_looptri_indices.append(looptri_index); + r_positions.append(point_pos); + } + } + else { + /* The triangle is large compared to the sample radius. Sample by generating random points + * on the triangle plane within the sample radius. */ + float3 normal; + normal_tri_v3(normal, v0, v1, v2); + + float3 sample_pos_proj = sample_pos; + project_v3_plane(sample_pos_proj, normal, v0); + + const float proj_distance_sq = math::distance_squared(sample_pos_proj, sample_pos); + const float sample_radius_factor_sq = 1.0f - + std::min(1.0f, proj_distance_sq / sample_radius_sq); + const float radius_proj_sq = sample_radius_sq * sample_radius_factor_sq; + const float radius_proj = std::sqrt(radius_proj_sq); + const float circle_area = M_PI * radius_proj; + + const int amount = rng.round_probabilistic(approximate_density * circle_area); + + const float3 axis_1 = math::normalize(v1 - v0) * radius_proj; + const float3 axis_2 = math::normalize(math::cross(axis_1, math::cross(axis_1, v2 - v0))) * + radius_proj; + + for ([[maybe_unused]] const int i : IndexRange(amount)) { + const float r = std::sqrt(rng.get_float()); + const float angle = rng.get_float() * 2.0f * M_PI; + const float x = r * std::cos(angle); + const float y = r * std::sin(angle); + const float3 point_pos = sample_pos_proj + axis_1 * x + axis_2 * y; + if (!isect_point_tri_prism_v3(point_pos, v0, v1, v2)) { + /* Sampled point is not in the triangle. */ + continue; + } + + float3 bary_coord; + interp_weights_tri_v3(bary_coord, v0, v1, v2, point_pos); + + r_bary_coords.append(bary_coord); + r_looptri_indices.append(looptri_index); + r_positions.append(point_pos); + } + } + } + return r_bary_coords.size() - old_num; +} + +int sample_surface_points_projected( + RandomNumberGenerator &rng, + const Mesh &mesh, + BVHTreeFromMesh &mesh_bvhtree, + const float2 &sample_pos_re, + const float sample_radius_re, + const FunctionRef<void(const float2 &pos_re, float3 &r_start, float3 &r_end)> + region_position_to_ray, + const bool front_face_only, + const int tries_num, + const int max_points, + Vector<float3> &r_bary_coords, + Vector<int> &r_looptri_indices, + Vector<float3> &r_positions) +{ + const Span<MLoopTri> looptris{BKE_mesh_runtime_looptri_ensure(&mesh), + BKE_mesh_runtime_looptri_len(&mesh)}; + + int point_count = 0; + for ([[maybe_unused]] const int _ : IndexRange(tries_num)) { + if (point_count == max_points) { + break; + } + + const float r = sample_radius_re * std::sqrt(rng.get_float()); + const float angle = rng.get_float() * 2.0f * M_PI; + float3 ray_start, ray_end; + const float2 pos_re = sample_pos_re + r * float2(std::cos(angle), std::sin(angle)); + region_position_to_ray(pos_re, ray_start, ray_end); + const float3 ray_direction = math::normalize(ray_end - ray_start); + + BVHTreeRayHit ray_hit; + ray_hit.dist = FLT_MAX; + ray_hit.index = -1; + BLI_bvhtree_ray_cast(mesh_bvhtree.tree, + ray_start, + ray_direction, + 0.0f, + &ray_hit, + mesh_bvhtree.raycast_callback, + &mesh_bvhtree); + + if (ray_hit.index == -1) { + continue; + } + + if (front_face_only) { + const float3 normal = ray_hit.no; + if (math::dot(ray_direction, normal) >= 0.0f) { + continue; + } + } + + const int looptri_index = ray_hit.index; + const float3 pos = ray_hit.co; + + const float3 bary_coords = compute_bary_coord_in_triangle(mesh, looptris[looptri_index], pos); + + r_positions.append(pos); + r_bary_coords.append(bary_coords); + r_looptri_indices.append(looptri_index); + point_count++; + } + return point_count; +} + +float3 compute_bary_coord_in_triangle(const Mesh &mesh, + const MLoopTri &looptri, + const float3 &position) +{ + const float3 &v0 = mesh.mvert[mesh.mloop[looptri.tri[0]].v].co; + const float3 &v1 = mesh.mvert[mesh.mloop[looptri.tri[1]].v].co; + const float3 &v2 = mesh.mvert[mesh.mloop[looptri.tri[2]].v].co; + float3 bary_coords; + interp_weights_tri_v3(bary_coords, v0, v1, v2, position); + return bary_coords; +} + } // namespace blender::bke::mesh_surface_sample diff --git a/source/blender/blenkernel/intern/mesh_tangent.c b/source/blender/blenkernel/intern/mesh_tangent.c index c0b2b33c47c..a677a0d6ebb 100644 --- a/source/blender/blenkernel/intern/mesh_tangent.c +++ b/source/blender/blenkernel/intern/mesh_tangent.c @@ -167,7 +167,7 @@ void BKE_mesh_calc_loop_tangent_single(Mesh *mesh, if (!loopuvs) { BKE_reportf(reports, RPT_ERROR, - "Tangent space computation needs an UVMap, \"%s\" not found, aborting", + "Tangent space computation needs a UV Map, \"%s\" not found, aborting", uvmap); return; } diff --git a/source/blender/blenkernel/intern/nla.c b/source/blender/blenkernel/intern/nla.c index 8f54d71108a..10abb8f20df 100644 --- a/source/blender/blenkernel/intern/nla.c +++ b/source/blender/blenkernel/intern/nla.c @@ -252,12 +252,15 @@ static NlaStrip *find_active_strip_from_listbase(const NlaStrip *active_strip, const ListBase /* NlaStrip */ *strips_source, const ListBase /* NlaStrip */ *strips_dest) { + BLI_assert_msg(BLI_listbase_count(strips_source) == BLI_listbase_count(strips_dest), + "Expecting the same number of source and destination strips"); + NlaStrip *strip_dest = strips_dest->first; LISTBASE_FOREACH (const NlaStrip *, strip_source, strips_source) { if (strip_dest == NULL) { - /* The tracks are assumed to have an equal number of strips, but this is not the case when - * dragging multiple strips. The transform system merges the selected strips into one - * meta-strip, reducing the number of strips in `track_dest`. */ + /* The tracks are assumed to have an equal number of strips, but this is + * not the case. Not sure when this might happen, but it's better to not + * crash. */ break; } if (strip_source == active_strip) { @@ -282,7 +285,9 @@ static NlaStrip *find_active_strip_from_listbase(const NlaStrip *active_strip, return NULL; } -/* Set adt_dest->actstrip to the strip with the same index as adt_source->actstrip. */ +/* Set adt_dest->actstrip to the strip with the same index as + * adt_source->actstrip. Note that this always sets `adt_dest->actstrip`; sets + * to NULL when `adt_source->actstrip` cannot be found. */ static void update_active_strip(AnimData *adt_dest, NlaTrack *track_dest, const AnimData *adt_source, @@ -298,6 +303,12 @@ static void update_active_strip(AnimData *adt_dest, /* Set adt_dest->act_track to the track with the same index as adt_source->act_track. */ static void update_active_track(AnimData *adt_dest, const AnimData *adt_source) { + adt_dest->act_track = NULL; + adt_dest->actstrip = NULL; + if (adt_source->act_track == NULL && adt_source->actstrip == NULL) { + return; + } + BLI_assert(BLI_listbase_count(&adt_source->nla_tracks) == BLI_listbase_count(&adt_dest->nla_tracks)); @@ -306,7 +317,11 @@ static void update_active_track(AnimData *adt_dest, const AnimData *adt_source) if (track_source == adt_source->act_track) { adt_dest->act_track = track_dest; } - update_active_strip(adt_dest, track_dest, adt_source, track_source); + + /* Only search for the active strip if it hasn't been found yet. */ + if (adt_dest->actstrip == NULL && adt_source->actstrip != NULL) { + update_active_strip(adt_dest, track_dest, adt_source, track_source); + } track_dest = track_dest->next; } diff --git a/source/blender/blenkernel/intern/node.cc b/source/blender/blenkernel/intern/node.cc index 1ffc4a56a0e..e02d3b6486c 100644 --- a/source/blender/blenkernel/intern/node.cc +++ b/source/blender/blenkernel/intern/node.cc @@ -4836,6 +4836,7 @@ static void registerGeometryNodes() register_node_type_geo_translate_instances(); register_node_type_geo_triangulate(); register_node_type_geo_viewer(); + register_node_type_geo_volume_cube(); register_node_type_geo_volume_to_mesh(); } |