Merge branch 'blender-v4.0-release'

This commit is contained in:
Jacques Lucke
2023-10-02 18:20:24 +02:00
2 changed files with 34 additions and 6 deletions

View File

@@ -568,6 +568,9 @@ static Mesh *modifier_modify_mesh_and_geometry_set(ModifierData *md,
}
mesh_output = mesh_component.release();
}
/* Need to ensure that non-mesh data is also owned by the geometry set. Otherwise it might be
* freed while there is still a reference to it in the geometry. */
geometry_set.ensure_owns_direct_data();
/* Return an empty mesh instead of null. */
if (mesh_output == nullptr) {

View File

@@ -235,8 +235,29 @@ static bool match_word_initials(StringRef query,
static int get_best_word_index_that_startswith(StringRef query,
Span<StringRef> words,
Span<float> word_weights,
Span<int> word_match_map)
Span<int> word_match_map,
Span<StringRef> remaining_query_words)
{
/* If there is another word in the remaining full query that contains the current word, we have
* to pick the shortest word. If we pick a longer one, it can happen that the other query word
* does not have a match anymore. This can lead to a situation where a query does not match
* itself anymore.
*
* E.g. the full query `T > Test` wouldn't match itself anymore if `Test` has a higher weight.
* That's because the `T` would be matched with the `Test`, but then `Test` can't match `Test
* anymore because that's taken up already.
*
* If we don't have to pick the shortest match for correctness, pick the one with the largest
* weight instead.
*/
bool use_shortest_match = false;
for (const StringRef other_word : remaining_query_words) {
if (other_word.startswith(query)) {
use_shortest_match = true;
break;
}
}
int best_word_size = INT32_MAX;
int best_word_index = -1;
int best_word_weight = 0.0f;
@@ -247,7 +268,7 @@ static int get_best_word_index_that_startswith(StringRef query,
StringRef word = words[i];
const float word_weight = word_weights[i];
if (word.startswith(query)) {
if (word.size() < best_word_size ||
if ((use_shortest_match && word.size() < best_word_size) ||
(word.size() == best_word_size && word_weight > best_word_weight))
{
best_word_index = i;
@@ -298,7 +319,11 @@ static std::optional<float> score_query_against_words(Span<StringRef> query_word
{
/* Check if any result word begins with the query word. */
const int word_index = get_best_word_index_that_startswith(
query_word, result_words, result_word_weights, word_match_map);
query_word,
result_words,
result_word_weights,
word_match_map,
query_words.drop_front(query_word_index + 1));
if (word_index >= 0) {
total_match_score += 10 * result_word_weights[word_index];
word_match_map[word_index] = query_word_index;
@@ -466,8 +491,8 @@ Vector<void *> StringSearchBase::query_impl(const StringRef query) const
}
}
Vector<int> found_scores;
for (const int score : result_indices_by_score.keys()) {
Vector<float> found_scores;
for (const float score : result_indices_by_score.keys()) {
found_scores.append(score);
}
std::sort(found_scores.begin(), found_scores.end(), std::greater<>());
@@ -475,7 +500,7 @@ Vector<void *> StringSearchBase::query_impl(const StringRef query) const
/* Add results to output vector in correct order. First come the results with the best match
* score. Results with the same score are in the order they have been added to the search. */
Vector<int> sorted_result_indices;
for (const int score : found_scores) {
for (const float score : found_scores) {
MutableSpan<int> indices = result_indices_by_score.lookup(score);
if (score == found_scores[0]) {
if (!query.is_empty()) {