diff --git a/src/libslic3r/Format/3mf.cpp b/src/libslic3r/Format/3mf.cpp index abf01a11a8..6cf688b3fb 100644 --- a/src/libslic3r/Format/3mf.cpp +++ b/src/libslic3r/Format/3mf.cpp @@ -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(); diff --git a/src/libslic3r/Model.cpp b/src/libslic3r/Model.cpp index 2c8dc3b2b4..6d0a416275 100644 --- a/src/libslic3r/Model.cpp +++ b/src/libslic3r/Model.cpp @@ -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(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())); diff --git a/src/libslic3r/MultiMaterialSegmentation.cpp b/src/libslic3r/MultiMaterialSegmentation.cpp index add29c4e38..8e93d1cd6d 100644 --- a/src/libslic3r/MultiMaterialSegmentation.cpp +++ b/src/libslic3r/MultiMaterialSegmentation.cpp @@ -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 slice_model_volume_with_color(const ModelVolume &model_volume, const std::vector &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 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(TriangleStateType::NONE), static_cast(volume_extruder_id)); + } + } + } + + return color_polygons_per_layer; +} + std::vector> multi_material_segmentation_by_painting(const PrintObject &print_object, const std::function &throw_on_cancel_callback) { const size_t num_extruders = print_object.print()->config().nozzle_diameter.size(); @@ -1659,11 +1679,7 @@ std::vector> multi_material_segmentation_by_painting(con BOOST_LOG_TRIVIAL(debug) << "MM segmentation - Slicing painted triangles - Begin"; const std::vector 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 color_polygons_per_layer = slice_mesh(mesh_with_color, layer_zs, slicing_params); + std::vector color_polygons_per_layer = slice_model_volume_with_color(*mv, layer_zs, print_object); tbb::parallel_for(tbb::blocked_range(0, num_layers), [&color_polygons_per_layer, &color_polygons_lines_layers, &throw_on_cancel_callback](const tbb::blocked_range &range) { for (size_t layer_idx = range.begin(); layer_idx < range.end(); ++layer_idx) { diff --git a/src/libslic3r/PrintApply.cpp b/src/libslic3r/PrintApply.cpp index 6cce84d5cc..9a5ba3169f 100644 --- a/src/libslic3r/PrintApply.cpp +++ b/src/libslic3r/PrintApply.cpp @@ -1410,17 +1410,24 @@ Print::ApplyStatus Print::apply(const Model &model, DynamicPrintConfig new_full_ const std::vector &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(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(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) { diff --git a/src/libslic3r/TriangleSelector.cpp b/src/libslic3r/TriangleSelector.cpp index 3b951cf038..302ce06fe5 100644 --- a/src/libslic3r/TriangleSelector.cpp +++ b/src/libslic3r/TriangleSelector.cpp @@ -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(TriangleStateType::NONE)] = true; } // May be stored onto Undo / Redo stack, thus conserve memory.