Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/blenlib/intern')
-rw-r--r--source/blender/blenlib/intern/bitmap.c20
-rw-r--r--source/blender/blenlib/intern/filereader_zstd.c5
-rw-r--r--source/blender/blenlib/intern/generic_virtual_array.cc114
-rw-r--r--source/blender/blenlib/intern/index_mask.cc5
-rw-r--r--source/blender/blenlib/intern/length_parameterize.cc150
-rw-r--r--source/blender/blenlib/intern/math_base_inline.c10
-rw-r--r--source/blender/blenlib/intern/math_matrix.c16
-rw-r--r--source/blender/blenlib/intern/math_rotation.c49
-rw-r--r--source/blender/blenlib/intern/math_rotation.cc13
-rw-r--r--source/blender/blenlib/intern/mesh_boolean.cc32
-rw-r--r--source/blender/blenlib/intern/rct.c4
-rw-r--r--source/blender/blenlib/intern/timeit.cc18
12 files changed, 294 insertions, 142 deletions
diff --git a/source/blender/blenlib/intern/bitmap.c b/source/blender/blenlib/intern/bitmap.c
index 7fcbc31c066..2cc2fbc3e2f 100644
--- a/source/blender/blenlib/intern/bitmap.c
+++ b/source/blender/blenlib/intern/bitmap.c
@@ -11,6 +11,7 @@
#include <string.h>
#include "BLI_bitmap.h"
+#include "BLI_math_bits.h"
#include "BLI_utildefines.h"
void BLI_bitmap_set_all(BLI_bitmap *bitmap, bool set, size_t bits)
@@ -46,3 +47,22 @@ void BLI_bitmap_or_all(BLI_bitmap *dst, const BLI_bitmap *src, size_t bits)
dst[i] |= src[i];
}
}
+
+int BLI_bitmap_find_first_unset(const BLI_bitmap *bitmap, const size_t bits)
+{
+ const size_t blocks_num = _BITMAP_NUM_BLOCKS(bits);
+ int result = -1;
+ /* Skip over completely set blocks. */
+ int index = 0;
+ while (index < blocks_num && bitmap[index] == ~0u) {
+ index++;
+ }
+ if (index < blocks_num) {
+ /* Found a partially used block: find the lowest unused bit. */
+ const uint m = ~bitmap[index];
+ BLI_assert(m != 0);
+ const uint bit_index = bitscan_forward_uint(m);
+ result = bit_index + (index << _BITMAP_POWER);
+ }
+ return result;
+}
diff --git a/source/blender/blenlib/intern/filereader_zstd.c b/source/blender/blenlib/intern/filereader_zstd.c
index 5f114f24fb0..aeb000e9754 100644
--- a/source/blender/blenlib/intern/filereader_zstd.c
+++ b/source/blender/blenlib/intern/filereader_zstd.c
@@ -281,7 +281,10 @@ static void zstd_close(FileReader *reader)
if (zstd->reader.seek) {
MEM_freeN(zstd->seek.uncompressed_ofs);
MEM_freeN(zstd->seek.compressed_ofs);
- MEM_freeN(zstd->seek.cached_content);
+ /* When an error has occurred this may be NULL, see: T99744. */
+ if (zstd->seek.cached_content) {
+ MEM_freeN(zstd->seek.cached_content);
+ }
}
else {
MEM_freeN((void *)zstd->in_buf.src);
diff --git a/source/blender/blenlib/intern/generic_virtual_array.cc b/source/blender/blenlib/intern/generic_virtual_array.cc
index 624af3c6ed1..f66b1e14fc6 100644
--- a/source/blender/blenlib/intern/generic_virtual_array.cc
+++ b/source/blender/blenlib/intern/generic_virtual_array.cc
@@ -284,11 +284,18 @@ template<int BufferSize> class GVArrayImpl_For_SmallTrivialSingleValue : public
/** \} */
/* -------------------------------------------------------------------- */
-/** \name #GVArray_GSpan
+/** \name #GVArraySpan
* \{ */
-GVArray_GSpan::GVArray_GSpan(GVArray varray) : GSpan(varray.type()), varray_(std::move(varray))
+GVArraySpan::GVArraySpan() = default;
+
+GVArraySpan::GVArraySpan(GVArray varray)
+ : GSpan(varray ? &varray.type() : nullptr), varray_(std::move(varray))
{
+ if (!varray_) {
+ return;
+ }
+
size_ = varray_.size();
const CommonVArrayInfo info = varray_.common_info();
if (info.type == CommonVArrayInfo::Type::Span) {
@@ -301,7 +308,27 @@ GVArray_GSpan::GVArray_GSpan(GVArray varray) : GSpan(varray.type()), varray_(std
}
}
-GVArray_GSpan::~GVArray_GSpan()
+GVArraySpan::GVArraySpan(GVArraySpan &&other)
+ : GSpan(other.type_ptr()), varray_(std::move(other.varray_)), owned_data_(other.owned_data_)
+{
+ if (!varray_) {
+ return;
+ }
+
+ size_ = varray_.size();
+ const CommonVArrayInfo info = varray_.common_info();
+ if (info.type == CommonVArrayInfo::Type::Span) {
+ data_ = info.data;
+ }
+ else {
+ data_ = owned_data_;
+ }
+ other.owned_data_ = nullptr;
+ other.data_ = nullptr;
+ other.size_ = 0;
+}
+
+GVArraySpan::~GVArraySpan()
{
if (owned_data_ != nullptr) {
type_->destruct_n(owned_data_, size_);
@@ -309,15 +336,30 @@ GVArray_GSpan::~GVArray_GSpan()
}
}
+GVArraySpan &GVArraySpan::operator=(GVArraySpan &&other)
+{
+ if (this == &other) {
+ return *this;
+ }
+ std::destroy_at(this);
+ new (this) GVArraySpan(std::move(other));
+ return *this;
+}
+
/** \} */
/* -------------------------------------------------------------------- */
-/** \name #GVMutableArray_GSpan
+/** \name #GMutableVArraySpan
* \{ */
-GVMutableArray_GSpan::GVMutableArray_GSpan(GVMutableArray varray, const bool copy_values_to_span)
- : GMutableSpan(varray.type()), varray_(std::move(varray))
+GMutableVArraySpan::GMutableVArraySpan() = default;
+
+GMutableVArraySpan::GMutableVArraySpan(GVMutableArray varray, const bool copy_values_to_span)
+ : GMutableSpan(varray ? &varray.type() : nullptr), varray_(std::move(varray))
{
+ if (!varray_) {
+ return;
+ }
size_ = varray_.size();
const CommonVArrayInfo info = varray_.common_info();
if (info.type == CommonVArrayInfo::Type::Span) {
@@ -335,11 +377,35 @@ GVMutableArray_GSpan::GVMutableArray_GSpan(GVMutableArray varray, const bool cop
}
}
-GVMutableArray_GSpan::~GVMutableArray_GSpan()
+GMutableVArraySpan::GMutableVArraySpan(GMutableVArraySpan &&other)
+ : GMutableSpan(other.type_ptr()),
+ varray_(std::move(other.varray_)),
+ owned_data_(other.owned_data_),
+ show_not_saved_warning_(other.show_not_saved_warning_)
{
- if (show_not_saved_warning_) {
- if (!save_has_been_called_) {
- std::cout << "Warning: Call `apply()` to make sure that changes persist in all cases.\n";
+ if (!varray_) {
+ return;
+ }
+ size_ = varray_.size();
+ const CommonVArrayInfo info = varray_.common_info();
+ if (info.type == CommonVArrayInfo::Type::Span) {
+ data_ = const_cast<void *>(info.data);
+ }
+ else {
+ data_ = owned_data_;
+ }
+ other.owned_data_ = nullptr;
+ other.data_ = nullptr;
+ other.size_ = 0;
+}
+
+GMutableVArraySpan::~GMutableVArraySpan()
+{
+ if (varray_) {
+ if (show_not_saved_warning_) {
+ if (!save_has_been_called_) {
+ std::cout << "Warning: Call `save()` to make sure that changes persist in all cases.\n";
+ }
}
}
if (owned_data_ != nullptr) {
@@ -348,7 +414,17 @@ GVMutableArray_GSpan::~GVMutableArray_GSpan()
}
}
-void GVMutableArray_GSpan::save()
+GMutableVArraySpan &GMutableVArraySpan::operator=(GMutableVArraySpan &&other)
+{
+ if (this == &other) {
+ return *this;
+ }
+ std::destroy_at(this);
+ new (this) GMutableVArraySpan(std::move(other));
+ return *this;
+}
+
+void GMutableVArraySpan::save()
{
save_has_been_called_ = true;
if (data_ != owned_data_) {
@@ -357,11 +433,16 @@ void GVMutableArray_GSpan::save()
varray_.set_all(owned_data_);
}
-void GVMutableArray_GSpan::disable_not_applied_warning()
+void GMutableVArraySpan::disable_not_applied_warning()
{
show_not_saved_warning_ = false;
}
+const GVMutableArray &GMutableVArraySpan::varray() const
+{
+ return varray_;
+}
+
/** \} */
/* -------------------------------------------------------------------- */
@@ -633,6 +714,15 @@ GVArray GVArray::ForEmpty(const CPPType &type)
GVArray GVArray::slice(IndexRange slice) const
{
+ const CommonVArrayInfo info = this->common_info();
+ if (info.type == CommonVArrayInfo::Type::Single) {
+ return GVArray::ForSingle(this->type(), slice.size(), info.data);
+ }
+ /* Need to check for ownership, because otherwise the referenced data can be destructed when
+ * #this is destructed. */
+ if (info.type == CommonVArrayInfo::Type::Span && !info.may_have_ownership) {
+ return GVArray::ForSpan(GSpan(this->type(), info.data, this->size()).slice(slice));
+ }
return GVArray::For<GVArrayImpl_For_SlicedGVArray>(*this, slice);
}
diff --git a/source/blender/blenlib/intern/index_mask.cc b/source/blender/blenlib/intern/index_mask.cc
index f3590e4a41c..e9af183d60d 100644
--- a/source/blender/blenlib/intern/index_mask.cc
+++ b/source/blender/blenlib/intern/index_mask.cc
@@ -142,6 +142,7 @@ IndexMask find_indices_based_on_predicate__merge(
int64_t result_mask_size = 0;
for (Vector<Vector<int64_t>> &local_sub_masks : sub_masks) {
for (Vector<int64_t> &sub_mask : local_sub_masks) {
+ BLI_assert(!sub_mask.is_empty());
all_vectors.append(&sub_mask);
result_mask_size += sub_mask.size();
}
@@ -232,7 +233,9 @@ IndexMask find_indices_from_virtual_array(const IndexMask indices_to_check,
}
}
});
- sub_masks.local().append(std::move(masked_indices));
+ if (!masked_indices.is_empty()) {
+ sub_masks.local().append(std::move(masked_indices));
+ }
});
return detail::find_indices_based_on_predicate__merge(indices_to_check, sub_masks, r_indices);
diff --git a/source/blender/blenlib/intern/length_parameterize.cc b/source/blender/blenlib/intern/length_parameterize.cc
index 7c0fc860b53..06cca281510 100644
--- a/source/blender/blenlib/intern/length_parameterize.cc
+++ b/source/blender/blenlib/intern/length_parameterize.cc
@@ -1,144 +1,58 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
#include "BLI_length_parameterize.hh"
+#include "BLI_task.hh"
namespace blender::length_parameterize {
-void create_uniform_samples(const Span<float> lengths,
- const bool cyclic,
- MutableSpan<int> indices,
- MutableSpan<float> factors)
+void sample_uniform(const Span<float> lengths,
+ const bool include_last_point,
+ MutableSpan<int> r_segment_indices,
+ MutableSpan<float> r_factors)
{
- const int count = indices.size();
+ const int count = r_segment_indices.size();
BLI_assert(count > 0);
BLI_assert(lengths.size() >= 1);
BLI_assert(std::is_sorted(lengths.begin(), lengths.end()));
- const int segments_num = lengths.size();
- const int points_num = cyclic ? segments_num : segments_num + 1;
- indices.first() = 0;
- factors.first() = 0.0f;
if (count == 1) {
+ r_segment_indices[0] = 0;
+ r_factors[0] = 0.0f;
return;
}
-
const float total_length = lengths.last();
- if (total_length == 0.0f) {
- indices.fill(0);
- factors.fill(0.0f);
- return;
- }
-
- const float step_length = total_length / (count - (cyclic ? 0 : 1));
- const float step_length_inv = 1.0f / step_length;
-
- int i_dst = 1;
- /* Store the length at the previous point in a variable so it can start out at zero
- * (the lengths array doesn't contain 0 for the first point). */
- float prev_length = 0.0f;
- for (const int i_src : IndexRange(points_num - 1)) {
- const float next_length = lengths[i_src];
- const float segment_length = next_length - prev_length;
- if (segment_length == 0.0f) {
- continue;
- }
- /* Add every sample that fits in this segment. */
- const float segment_length_inv = 1.0f / segment_length;
- const int segment_samples_num = std::ceil(next_length * step_length_inv - i_dst);
- indices.slice(i_dst, segment_samples_num).fill(i_src);
-
- for (const int i : factors.index_range().slice(i_dst, segment_samples_num)) {
- const float length_in_segment = step_length * i - prev_length;
- factors[i] = length_in_segment * segment_length_inv;
- }
-
- i_dst += segment_samples_num;
-
- prev_length = next_length;
- }
-
- /* Add the samples on the last cyclic segment if necessary, and also the samples
- * that weren't created in the previous loop due to floating point inaccuracy. */
- if (cyclic && lengths.size() > 1) {
- indices.drop_front(i_dst).fill(points_num - 1);
- const float segment_length = lengths.last() - lengths.last(1);
- if (segment_length == 0.0f) {
- return;
- }
- const float segment_length_inv = 1.0f / segment_length;
- for (const int i : indices.index_range().drop_front(i_dst)) {
- const float length_in_segment = step_length * i - prev_length;
- factors[i] = length_in_segment * segment_length_inv;
+ const float step_length = total_length / (count - include_last_point);
+ threading::parallel_for(IndexRange(count), 512, [&](const IndexRange range) {
+ SampleSegmentHint hint;
+ for (const int i : range) {
+ /* Use minimum to avoid issues with floating point accuracy. */
+ const float sample_length = std::min(total_length, i * step_length);
+ sample_at_length(lengths, sample_length, r_segment_indices[i], r_factors[i], &hint);
}
- }
- else {
- indices.drop_front(i_dst).fill(points_num - 2);
- factors.drop_front(i_dst).fill(1.0f);
- }
+ });
}
-void create_samples_from_sorted_lengths(const Span<float> lengths,
- const Span<float> sample_lengths,
- const bool cyclic,
- MutableSpan<int> indices,
- MutableSpan<float> factors)
+void sample_at_lengths(const Span<float> accumulated_segment_lengths,
+ const Span<float> sample_lengths,
+ MutableSpan<int> r_segment_indices,
+ MutableSpan<float> r_factors)
{
- BLI_assert(std::is_sorted(lengths.begin(), lengths.end()));
+ BLI_assert(
+ std::is_sorted(accumulated_segment_lengths.begin(), accumulated_segment_lengths.end()));
BLI_assert(std::is_sorted(sample_lengths.begin(), sample_lengths.end()));
- BLI_assert(indices.size() == sample_lengths.size());
- BLI_assert(indices.size() == factors.size());
- const int segments_num = lengths.size();
- const int points_num = cyclic ? segments_num : segments_num + 1;
- const float total_length = lengths.last();
- if (total_length == 0.0f) {
- indices.fill(0);
- factors.fill(0.0f);
- return;
- }
+ const int count = sample_lengths.size();
+ BLI_assert(count == r_segment_indices.size());
+ BLI_assert(count == r_factors.size());
- int i_dst = 0;
- /* Store the length at the previous point in a variable so it can start out at zero
- * (the lengths array doesn't contain 0 for the first point). */
- float prev_length = 0.0f;
- for (const int i_src : IndexRange(points_num - 1)) {
- const float next_length = lengths[i_src];
- const float segment_length = next_length - prev_length;
- if (segment_length == 0.0f) {
- continue;
- }
- /* Add every sample that fits in this segment. It's also necessary to check if the last sample
- * has been reached, since there is no upper bound on the number of samples in each segment. */
- const float segment_length_inv = 1.0f / segment_length;
- while (i_dst < sample_lengths.size() && sample_lengths[i_dst] < next_length) {
- const float length_in_segment = sample_lengths[i_dst] - prev_length;
- const float factor = length_in_segment * segment_length_inv;
- indices[i_dst] = i_src;
- factors[i_dst] = factor;
- i_dst++;
+ threading::parallel_for(IndexRange(count), 512, [&](const IndexRange range) {
+ SampleSegmentHint hint;
+ for (const int i : range) {
+ const float sample_length = sample_lengths[i];
+ sample_at_length(
+ accumulated_segment_lengths, sample_length, r_segment_indices[i], r_factors[i], &hint);
}
-
- prev_length = next_length;
- }
-
- /* Add the samples on the last cyclic segment if necessary, and also the samples
- * that weren't created in the previous loop due to floating point inaccuracy. */
- if (cyclic && lengths.size() > 1) {
- const float segment_length = lengths.last() - lengths.last(1);
- while (sample_lengths[i_dst] < total_length) {
- const float length_in_segment = sample_lengths[i_dst] - prev_length;
- const float factor = length_in_segment / segment_length;
- indices[i_dst] = points_num - 1;
- factors[i_dst] = factor;
- i_dst++;
- }
- indices.drop_front(i_dst).fill(points_num - 1);
- factors.drop_front(i_dst).fill(1.0f);
- }
- else {
- indices.drop_front(i_dst).fill(points_num - 2);
- factors.drop_front(i_dst).fill(1.0f);
- }
+ });
}
} // namespace blender::length_parameterize
diff --git a/source/blender/blenlib/intern/math_base_inline.c b/source/blender/blenlib/intern/math_base_inline.c
index cb7659a7059..fb71e84c23e 100644
--- a/source/blender/blenlib/intern/math_base_inline.c
+++ b/source/blender/blenlib/intern/math_base_inline.c
@@ -370,6 +370,11 @@ MINLINE uint divide_ceil_u(uint a, uint b)
return (a + b - 1) / b;
}
+MINLINE uint64_t divide_ceil_ul(uint64_t a, uint64_t b)
+{
+ return (a + b - 1) / b;
+}
+
/**
* Returns \a a if it is a multiple of \a b or the next multiple or \a b after \b a .
*/
@@ -378,6 +383,11 @@ MINLINE uint ceil_to_multiple_u(uint a, uint b)
return divide_ceil_u(a, b) * b;
}
+MINLINE uint64_t ceil_to_multiple_ul(uint64_t a, uint64_t b)
+{
+ return divide_ceil_ul(a, b) * b;
+}
+
MINLINE int mod_i(int i, int n)
{
return (i % n + n) % n;
diff --git a/source/blender/blenlib/intern/math_matrix.c b/source/blender/blenlib/intern/math_matrix.c
index ce9abc36cad..fcd017b3082 100644
--- a/source/blender/blenlib/intern/math_matrix.c
+++ b/source/blender/blenlib/intern/math_matrix.c
@@ -1116,6 +1116,22 @@ double determinant_m3_array_db(const double m[3][3])
m[2][0] * (m[0][1] * m[1][2] - m[0][2] * m[1][1]));
}
+bool invert_m2_m2(float m1[2][2], const float m2[2][2])
+{
+ adjoint_m2_m2(m1, m2);
+ float det = determinant_m2(m2[0][0], m2[1][0], m2[0][1], m2[1][1]);
+
+ bool success = (det != 0.0f);
+ if (success) {
+ m1[0][0] /= det;
+ m1[1][0] /= det;
+ m1[0][1] /= det;
+ m1[1][1] /= det;
+ }
+
+ return success;
+}
+
bool invert_m3_ex(float m[3][3], const float epsilon)
{
float tmp[3][3];
diff --git a/source/blender/blenlib/intern/math_rotation.c b/source/blender/blenlib/intern/math_rotation.c
index 92223bdf1d5..f0bfc7c21e1 100644
--- a/source/blender/blenlib/intern/math_rotation.c
+++ b/source/blender/blenlib/intern/math_rotation.c
@@ -915,6 +915,55 @@ float tri_to_quat(float q[4], const float a[3], const float b[3], const float c[
return len;
}
+void sin_cos_from_fraction(const int numerator, const int denominator, float *r_sin, float *r_cos)
+{
+ BLI_assert((numerator <= denominator) && (denominator > 0));
+ if ((denominator & 3) == 0) {
+ const int denominator_4 = denominator / 4;
+ if (numerator <= denominator_4) {
+ /* Fall through. */
+ }
+ else {
+ if (numerator <= denominator_4 * 2) {
+ const float phi = (float)(2.0 * M_PI) *
+ ((float)(numerator - denominator_4) / (float)denominator);
+ *r_sin = cosf(phi);
+ *r_cos = -sinf(phi);
+ }
+ else if (numerator <= denominator_4 * 3) {
+ const float phi = (float)(2.0 * M_PI) *
+ ((float)(numerator - (denominator_4 * 2)) / (float)denominator);
+ *r_sin = -sinf(phi);
+ *r_cos = -cosf(phi);
+ }
+ else {
+ const float phi = (float)(2.0 * M_PI) *
+ ((float)(numerator - (denominator_4 * 3)) / (float)denominator);
+ *r_cos = sinf(phi);
+ *r_sin = -cosf(phi);
+ }
+ return;
+ }
+ }
+ else if ((denominator & 1) == 0) {
+ const int denominator_2 = denominator / 2;
+ if (numerator <= denominator_2) {
+ /* Fall through. */
+ }
+ else {
+ const float phi = (float)(2.0 * M_PI) *
+ ((float)(numerator - denominator_2) / (float)denominator);
+ *r_sin = -sinf(phi);
+ *r_cos = -cosf(phi);
+ return;
+ }
+ }
+
+ const float phi = (float)(2.0 * M_PI) * ((float)numerator / (float)denominator);
+ *r_sin = sinf(phi);
+ *r_cos = cosf(phi);
+}
+
void print_qt(const char *str, const float q[4])
{
printf("%s: %.3f %.3f %.3f %.3f\n", str, q[0], q[1], q[2], q[3]);
diff --git a/source/blender/blenlib/intern/math_rotation.cc b/source/blender/blenlib/intern/math_rotation.cc
index 74300d55954..091e8af85d9 100644
--- a/source/blender/blenlib/intern/math_rotation.cc
+++ b/source/blender/blenlib/intern/math_rotation.cc
@@ -23,4 +23,17 @@ float3 rotate_direction_around_axis(const float3 &direction, const float3 &axis,
return axis_scaled + diff * std::cos(angle) + cross * std::sin(angle);
}
+float3 rotate_around_axis(const float3 &vector,
+ const float3 &center,
+ const float3 &axis,
+ const float angle)
+
+{
+ float3 result = vector - center;
+ float mat[3][3];
+ axis_angle_normalized_to_mat3(mat, axis, angle);
+ mul_m3_v3(mat, result);
+ return result + center;
+}
+
} // namespace blender::math
diff --git a/source/blender/blenlib/intern/mesh_boolean.cc b/source/blender/blenlib/intern/mesh_boolean.cc
index 700c126ca4c..d4586f95fe0 100644
--- a/source/blender/blenlib/intern/mesh_boolean.cc
+++ b/source/blender/blenlib/intern/mesh_boolean.cc
@@ -2966,6 +2966,11 @@ static std::ostream &operator<<(std::ostream &os, const FaceMergeState &fms)
* \a tris all have the same original face.
* Find the 2d edge/triangle topology for these triangles, but only the ones facing in the
* norm direction, and whether each edge is dissolvable or not.
+ * If we did the initial triangulation properly, and any Delaunay triangulations of interections
+ * properly, then each triangle edge should have at most one neighbor.
+ * However, there can be anonalies. For example, if an input face is self-intersecting, we fall
+ * back on the floating poing polyfill triangulation, which, after which all bets are off.
+ * Hence, try to be tolerant of such unexpected topology.
*/
static void init_face_merge_state(FaceMergeState *fms,
const Vector<int> &tris,
@@ -3053,16 +3058,35 @@ static void init_face_merge_state(FaceMergeState *fms,
std::cout << "me.v1 == mf.vert[i] so set edge[" << me_index << "].left_face = " << f
<< "\n";
}
- BLI_assert(me.left_face == -1);
- fms->edge[me_index].left_face = f;
+ if (me.left_face != -1) {
+ /* Unexpected in the normal case: this means more than one triangle shares this
+ * edge in the same orientation. But be tolerant of this case. By making this
+ * edge not dissolvable, we'll avoid future problems due to this non-manifold topology.
+ */
+ if (dbg_level > 1) {
+ std::cout << "me.left_face was already occupied, so triangulation wasn't good\n";
+ }
+ me.dissolvable = false;
+ }
+ else {
+ fms->edge[me_index].left_face = f;
+ }
}
else {
if (dbg_level > 1) {
std::cout << "me.v1 != mf.vert[i] so set edge[" << me_index << "].right_face = " << f
<< "\n";
}
- BLI_assert(me.right_face == -1);
- fms->edge[me_index].right_face = f;
+ if (me.right_face != -1) {
+ /* Unexpected, analogous to the me.left_face != -1 case above. */
+ if (dbg_level > 1) {
+ std::cout << "me.right_face was already occupied, so triangulation wasn't good\n";
+ }
+ me.dissolvable = false;
+ }
+ else {
+ fms->edge[me_index].right_face = f;
+ }
}
fms->face[f].edge.append(me_index);
}
diff --git a/source/blender/blenlib/intern/rct.c b/source/blender/blenlib/intern/rct.c
index 0bb606c288e..7248db5b718 100644
--- a/source/blender/blenlib/intern/rct.c
+++ b/source/blender/blenlib/intern/rct.c
@@ -265,7 +265,7 @@ bool BLI_rcti_isect_segment(const rcti *rect, const int s1[2], const int s2[2])
/* diagonal: [/] */
tvec1[0] = rect->xmin;
tvec1[1] = rect->ymin;
- tvec2[0] = rect->xmin;
+ tvec2[0] = rect->xmax;
tvec2[1] = rect->ymax;
if (isect_segments_i(s1, s2, tvec1, tvec2)) {
return true;
@@ -311,7 +311,7 @@ bool BLI_rctf_isect_segment(const rctf *rect, const float s1[2], const float s2[
/* diagonal: [/] */
tvec1[0] = rect->xmin;
tvec1[1] = rect->ymin;
- tvec2[0] = rect->xmin;
+ tvec2[0] = rect->xmax;
tvec2[1] = rect->ymax;
if (isect_segments_fl(s1, s2, tvec1, tvec2)) {
return true;
diff --git a/source/blender/blenlib/intern/timeit.cc b/source/blender/blenlib/intern/timeit.cc
index f11f9c4ad94..7a8cf8da038 100644
--- a/source/blender/blenlib/intern/timeit.cc
+++ b/source/blender/blenlib/intern/timeit.cc
@@ -3,19 +3,29 @@
#include "BLI_timeit.hh"
#include <algorithm>
+#include <iomanip>
namespace blender::timeit {
void print_duration(Nanoseconds duration)
{
- if (duration < std::chrono::microseconds(100)) {
+ using namespace std::chrono;
+ if (duration < microseconds(100)) {
std::cout << duration.count() << " ns";
}
- else if (duration < std::chrono::seconds(5)) {
- std::cout << duration.count() / 1.0e6 << " ms";
+ else if (duration < seconds(5)) {
+ std::cout << std::fixed << std::setprecision(1) << duration.count() / 1.0e6 << " ms";
+ }
+ else if (duration > seconds(90)) {
+ /* Long durations: print seconds, and also H:m:s */
+ const auto dur_hours = duration_cast<hours>(duration);
+ const auto dur_mins = duration_cast<minutes>(duration - dur_hours);
+ const auto dur_sec = duration_cast<seconds>(duration - dur_hours - dur_mins);
+ std::cout << std::fixed << std::setprecision(1) << duration.count() / 1.0e9 << " s ("
+ << dur_hours.count() << "H:" << dur_mins.count() << "m:" << dur_sec.count() << "s)";
}
else {
- std::cout << duration.count() / 1.0e9 << " s";
+ std::cout << std::fixed << std::setprecision(1) << duration.count() / 1.0e9 << " s";
}
}