Merge branch 'blender-v4.0-release'
This commit is contained in:
@@ -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) {
|
||||
|
||||
@@ -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()) {
|
||||
|
||||
Reference in New Issue
Block a user