mirror of
https://git.mirrors.martin98.com/https://github.com/prusa3d/PrusaSlicer.git
synced 2025-07-31 13:52:01 +08:00
SPE-1841: Replace default extruder with volume extruder for multi-material segmentation.
Previously, the default extruder wasn't handled inside multi-material segmentation, but this could confuse users, especially for multi-volume objects. Because with multi-volume, it could happen that in the place where two volumes were touching, there could be a change in the used extruder.
This commit is contained in:
parent
3edec09a2e
commit
84e9da9c6c
@ -2588,12 +2588,10 @@ namespace Slic3r {
|
||||
assert(index < geometry.custom_supports.size());
|
||||
assert(index < geometry.custom_seam.size());
|
||||
assert(index < geometry.mm_segmentation.size());
|
||||
if (! geometry.custom_supports[index].empty())
|
||||
volume->supported_facets.set_triangle_from_string(i, geometry.custom_supports[index]);
|
||||
if (! geometry.custom_seam[index].empty())
|
||||
volume->seam_facets.set_triangle_from_string(i, geometry.custom_seam[index]);
|
||||
if (! geometry.mm_segmentation[index].empty())
|
||||
volume->mm_segmentation_facets.set_triangle_from_string(i, geometry.mm_segmentation[index]);
|
||||
|
||||
volume->supported_facets.set_triangle_from_string(i, geometry.custom_supports[index]);
|
||||
volume->seam_facets.set_triangle_from_string(i, geometry.custom_seam[index]);
|
||||
volume->mm_segmentation_facets.set_triangle_from_string(i, geometry.mm_segmentation[index]);
|
||||
}
|
||||
volume->supported_facets.shrink_to_fit();
|
||||
volume->seam_facets.shrink_to_fit();
|
||||
|
@ -2122,9 +2122,15 @@ std::string FacetsAnnotation::get_triangle_as_string(int triangle_idx) const
|
||||
|
||||
// Recover triangle splitting & state from string of hexadecimal values previously
|
||||
// generated by get_triangle_as_string. Used to load from 3MF.
|
||||
void FacetsAnnotation::set_triangle_from_string(int triangle_id, const std::string& str)
|
||||
void FacetsAnnotation::set_triangle_from_string(int triangle_id, const std::string &str)
|
||||
{
|
||||
assert(! str.empty());
|
||||
if (str.empty()) {
|
||||
// The triangle isn't painted, so it means that it will use the default extruder.
|
||||
m_data.used_states[static_cast<int>(TriangleStateType::NONE)] = true;
|
||||
return;
|
||||
}
|
||||
|
||||
assert(!str.empty());
|
||||
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()));
|
||||
|
||||
|
@ -1611,6 +1611,26 @@ static indexed_triangle_set_with_color extract_mesh_with_color(const ModelVolume
|
||||
return volume.mm_segmentation_facets.get_all_facets_strict_with_colors(volume);
|
||||
}
|
||||
|
||||
static std::vector<ColorPolygons> slice_model_volume_with_color(const ModelVolume &model_volume, const std::vector<float> &layer_zs, const PrintObject &print_object)
|
||||
{
|
||||
const indexed_triangle_set_with_color mesh_with_color = extract_mesh_with_color(model_volume);
|
||||
const Transform3d trafo = print_object.trafo_centered() * model_volume.get_matrix();
|
||||
const MeshSlicingParams slicing_params{trafo};
|
||||
|
||||
std::vector<ColorPolygons> color_polygons_per_layer = slice_mesh(mesh_with_color, layer_zs, slicing_params);
|
||||
|
||||
// Replace default painted color (TriangleStateType::NONE) with volume extruder.
|
||||
if (const int volume_extruder_id = model_volume.extruder_id(); volume_extruder_id > 0 && model_volume.is_mm_painted()) {
|
||||
for (ColorPolygons &color_polygons : color_polygons_per_layer) {
|
||||
for (ColorPolygon &color_polygon : color_polygons) {
|
||||
std::replace(color_polygon.colors.begin(), color_polygon.colors.end(), static_cast<uint8_t>(TriangleStateType::NONE), static_cast<uint8_t>(volume_extruder_id));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return color_polygons_per_layer;
|
||||
}
|
||||
|
||||
std::vector<std::vector<ExPolygons>> multi_material_segmentation_by_painting(const PrintObject &print_object, const std::function<void()> &throw_on_cancel_callback)
|
||||
{
|
||||
const size_t num_extruders = print_object.print()->config().nozzle_diameter.size();
|
||||
@ -1659,11 +1679,7 @@ std::vector<std::vector<ExPolygons>> multi_material_segmentation_by_painting(con
|
||||
BOOST_LOG_TRIVIAL(debug) << "MM segmentation - Slicing painted triangles - Begin";
|
||||
const std::vector<float> layer_zs = get_print_object_layers_zs(layers);
|
||||
for (const ModelVolume *mv : print_object.model_object()->volumes) {
|
||||
const indexed_triangle_set_with_color mesh_with_color = extract_mesh_with_color(*mv);
|
||||
const Transform3d trafo = print_object.trafo_centered() * mv->get_matrix();
|
||||
const MeshSlicingParams slicing_params{trafo};
|
||||
|
||||
std::vector<ColorPolygons> color_polygons_per_layer = slice_mesh(mesh_with_color, layer_zs, slicing_params);
|
||||
std::vector<ColorPolygons> color_polygons_per_layer = slice_model_volume_with_color(*mv, layer_zs, print_object);
|
||||
|
||||
tbb::parallel_for(tbb::blocked_range<size_t>(0, num_layers), [&color_polygons_per_layer, &color_polygons_lines_layers, &throw_on_cancel_callback](const tbb::blocked_range<size_t> &range) {
|
||||
for (size_t layer_idx = range.begin(); layer_idx < range.end(); ++layer_idx) {
|
||||
|
@ -1410,17 +1410,24 @@ Print::ApplyStatus Print::apply(const Model &model, DynamicPrintConfig new_full_
|
||||
const std::vector<bool> &volume_used_facet_states = volume->mm_segmentation_facets.get_data().used_states;
|
||||
|
||||
assert(volume_used_facet_states.size() == used_facet_states.size());
|
||||
for (size_t state_idx = 0; state_idx < std::min(volume_used_facet_states.size(), used_facet_states.size()); ++state_idx) {
|
||||
for (size_t state_idx = 1; state_idx < std::min(volume_used_facet_states.size(), used_facet_states.size()); ++state_idx) {
|
||||
used_facet_states[state_idx] |= volume_used_facet_states[state_idx];
|
||||
}
|
||||
|
||||
// When the default facet state (TriangleStateType::NONE) is used, then we mark the volume extruder also as the used extruder.
|
||||
const bool used_volume_extruder = !volume_used_facet_states.empty() && volume_used_facet_states[static_cast<size_t>(TriangleStateType::NONE)];
|
||||
if (const int volume_extruder_id = volume->extruder_id(); used_volume_extruder && volume_extruder_id >= 0) {
|
||||
used_facet_states[volume_extruder_id] |= true;
|
||||
}
|
||||
} else if (const int volume_extruder_id = volume->extruder_id(); volume_extruder_id >= 0) {
|
||||
used_facet_states[volume_extruder_id] |= true;
|
||||
}
|
||||
}
|
||||
|
||||
for (size_t state_idx = static_cast<size_t>(TriangleStateType::Extruder1); state_idx < used_facet_states.size(); ++state_idx) {
|
||||
if (used_facet_states[state_idx])
|
||||
if (used_facet_states[state_idx]) {
|
||||
painting_extruders.emplace_back(state_idx);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (model_object_status.print_object_regions_status == ModelObjectStatus::PrintObjectRegionsStatus::Valid) {
|
||||
|
@ -1658,6 +1658,9 @@ TriangleSelector::TriangleSplittingData TriangleSelector::serialize() const {
|
||||
out.data.triangles_to_split.emplace_back(i, int(out.data.bitstream.size()));
|
||||
// out the triangle bits.
|
||||
out.serialize(i);
|
||||
} else if (!tr.is_split()) {
|
||||
assert(tr.get_state() == TriangleStateType::NONE);
|
||||
out.data.used_states[static_cast<int>(TriangleStateType::NONE)] = true;
|
||||
}
|
||||
|
||||
// May be stored onto Undo / Redo stack, thus conserve memory.
|
||||
|
Loading…
x
Reference in New Issue
Block a user