Feature/misc fixes of toolchanger (#6396)

* Use more readable data types for storing triangle splitting information.

* fix build errors

* SPE-2063: Determine correctly which extruders are used when the object is painted by the multi-material painting gizmo.

During the serialization of TriangleSelector and also during reading serialized painting data from 3MF, we cache all used states in the painted triangle mesh.

Based on this information, we can quickly determine which extruders are used and which don't.

* Fixed an bug that filament list was not updated properly

---------

Co-authored-by: Lukáš Hejl <hejl.lukas@gmail.com>
This commit is contained in:
SoftFever 2024-08-09 21:11:17 +08:00 committed by GitHub
parent a4cfc14a7e
commit b8a9c22404
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 198 additions and 88 deletions

View file

@ -3293,7 +3293,7 @@ bool FacetsAnnotation::has_facets(const ModelVolume& mv, EnforcerBlockerType typ
bool FacetsAnnotation::set(const TriangleSelector& selector)
{
std::pair<std::vector<std::pair<int, int>>, std::vector<bool>> sel_map = selector.serialize();
TriangleSelector::TriangleSplittingData sel_map = selector.serialize();
if (sel_map != m_data) {
m_data = std::move(sel_map);
this->touch();
@ -3304,8 +3304,8 @@ bool FacetsAnnotation::set(const TriangleSelector& selector)
void FacetsAnnotation::reset()
{
m_data.first.clear();
m_data.second.clear();
m_data.triangles_to_split.clear();
m_data.bitstream.clear();
this->touch();
}
@ -3316,15 +3316,15 @@ std::string FacetsAnnotation::get_triangle_as_string(int triangle_idx) const
{
std::string out;
auto triangle_it = std::lower_bound(m_data.first.begin(), m_data.first.end(), triangle_idx, [](const std::pair<int, int> &l, const int r) { return l.first < r; });
if (triangle_it != m_data.first.end() && triangle_it->first == triangle_idx) {
int offset = triangle_it->second;
int end = ++ triangle_it == m_data.first.end() ? int(m_data.second.size()) : triangle_it->second;
auto triangle_it = std::lower_bound(m_data.triangles_to_split.begin(), m_data.triangles_to_split.end(), triangle_idx, [](const TriangleSelector::TriangleBitStreamMapping &l, const int r) { return l.triangle_idx < r; });
if (triangle_it != m_data.triangles_to_split.end() && triangle_it->triangle_idx == triangle_idx) {
int offset = triangle_it->bitstream_start_idx;
int end = ++ triangle_it == m_data.triangles_to_split.end() ? int(m_data.bitstream.size()) : triangle_it->bitstream_start_idx;
while (offset < end) {
int next_code = 0;
for (int i=3; i>=0; --i) {
next_code = next_code << 1;
next_code |= int(m_data.second[offset + i]);
next_code |= int(m_data.bitstream[offset + i]);
}
offset += 4;
@ -3341,9 +3341,10 @@ std::string FacetsAnnotation::get_triangle_as_string(int triangle_idx) const
void FacetsAnnotation::set_triangle_from_string(int triangle_id, const std::string& str)
{
assert(! str.empty());
assert(m_data.first.empty() || m_data.first.back().first < triangle_id);
m_data.first.emplace_back(triangle_id, int(m_data.second.size()));
assert(m_data.triangles_to_split.empty() || m_data.triangles_to_split.back().triangle_idx < triangle_id);
m_data.triangles_to_split.emplace_back(triangle_id, int(m_data.bitstream.size()));
const size_t bitstream_start_idx = m_data.bitstream.size();
for (auto it = str.crbegin(); it != str.crend(); ++it) {
const char ch = *it;
int dec = 0;
@ -3355,14 +3356,16 @@ void FacetsAnnotation::set_triangle_from_string(int triangle_id, const std::stri
assert(false);
// Convert to binary and append into code.
for (int i=0; i<4; ++i)
m_data.second.insert(m_data.second.end(), bool(dec & (1 << i)));
for (int i = 0; i < 4; ++i)
m_data.bitstream.insert(m_data.bitstream.end(), bool(dec & (1 << i)));
}
m_data.update_used_states(bitstream_start_idx);
}
bool FacetsAnnotation::equals(const FacetsAnnotation &other) const
{
const std::pair<std::vector<std::pair<int, int>>, std::vector<bool>>& data = other.get_data();
const auto& data = other.get_data();
return (m_data == data);
}