Fixed a crash in the multi-material segmentation when projected lines are outside of the BoundingBox used for EdgeGrid.
This commit is contained in:
parent
f577350f1f
commit
da3a0c6332
3 changed files with 55 additions and 4 deletions
|
@ -4,6 +4,7 @@
|
|||
#include "Fill/Fill.hpp"
|
||||
#include "ShortestPath.hpp"
|
||||
#include "SVG.hpp"
|
||||
#include "BoundingBox.hpp"
|
||||
|
||||
#include <boost/log/trivial.hpp>
|
||||
|
||||
|
@ -258,4 +259,26 @@ void Layer::export_region_fill_surfaces_to_svg_debug(const char *name) const
|
|||
this->export_region_fill_surfaces_to_svg(debug_out_path("Layer-fill_surfaces-%s-%d.svg", name, idx ++).c_str());
|
||||
}
|
||||
|
||||
BoundingBox get_extents(const LayerRegion &layer_region)
|
||||
{
|
||||
BoundingBox bbox;
|
||||
if (!layer_region.slices.surfaces.empty()) {
|
||||
bbox = get_extents(layer_region.slices.surfaces.front());
|
||||
for (auto it = layer_region.slices.surfaces.cbegin() + 1; it != layer_region.slices.surfaces.cend(); ++it)
|
||||
bbox.merge(get_extents(*it));
|
||||
}
|
||||
return bbox;
|
||||
}
|
||||
|
||||
BoundingBox get_extents(const LayerRegionPtrs &layer_regions)
|
||||
{
|
||||
BoundingBox bbox;
|
||||
if (!layer_regions.empty()) {
|
||||
bbox = get_extents(*layer_regions.front());
|
||||
for (auto it = layer_regions.begin() + 1; it != layer_regions.end(); ++it)
|
||||
bbox.merge(get_extents(**it));
|
||||
}
|
||||
return bbox;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -211,6 +211,9 @@ inline std::vector<float> zs_from_layers(const LayerContainer &layers)
|
|||
return zs;
|
||||
}
|
||||
|
||||
extern BoundingBox get_extents(const LayerRegion &layer_region);
|
||||
extern BoundingBox get_extents(const LayerRegionPtrs &layer_regions);
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -42,6 +42,7 @@ struct segment_traits<Slic3r::ColoredLine> {
|
|||
|
||||
//#define MMU_SEGMENTATION_DEBUG_GRAPH
|
||||
//#define MMU_SEGMENTATION_DEBUG_REGIONS
|
||||
//#define MMU_SEGMENTATION_DEBUG_INPUT
|
||||
|
||||
namespace Slic3r {
|
||||
|
||||
|
@ -1699,6 +1700,22 @@ static void export_graph_to_svg(const std::string &path, const MMU_Graph &graph,
|
|||
}
|
||||
#endif // MMU_SEGMENTATION_DEBUG_GRAPH
|
||||
|
||||
#ifdef MMU_SEGMENTATION_DEBUG_INPUT
|
||||
void export_processed_input_expolygons_to_svg(const std::string &path, const LayerRegionPtrs ®ions, const ExPolygons &processed_input_expolygons)
|
||||
{
|
||||
coordf_t stroke_width = scale_(0.05);
|
||||
BoundingBox bbox = get_extents(regions);
|
||||
bbox.merge(get_extents(processed_input_expolygons));
|
||||
bbox.offset(scale_(1.));
|
||||
::Slic3r::SVG svg(path.c_str(), bbox);
|
||||
|
||||
for (LayerRegion *region : regions)
|
||||
svg.draw_outline(region->slices.surfaces, "blue", "cyan", stroke_width);
|
||||
|
||||
svg.draw_outline(processed_input_expolygons, "red", "pink", stroke_width);
|
||||
}
|
||||
#endif // MMU_SEGMENTATION_DEBUG_INPUT
|
||||
|
||||
std::vector<std::vector<std::pair<ExPolygon, size_t>>> multi_material_segmentation_by_painting(const PrintObject &print_object, const std::function<void()> &throw_on_cancel_callback)
|
||||
{
|
||||
std::vector<std::vector<std::pair<ExPolygon, size_t>>> segmented_regions(print_object.layers().size());
|
||||
|
@ -1732,13 +1749,21 @@ std::vector<std::vector<std::pair<ExPolygon, size_t>>> multi_material_segmentati
|
|||
// This consequently leads to issues with the extraction of colored segments by function extract_colored_segments.
|
||||
// Calling expolygons_simplify fixed these issues.
|
||||
input_expolygons[layer_idx] = smooth_outward(expolygons_simplify(offset_ex(ex_polygons, -10.f * float(SCALED_EPSILON)), 5 * SCALED_EPSILON), 10 * coord_t(SCALED_EPSILON));
|
||||
|
||||
#ifdef MMU_SEGMENTATION_DEBUG_INPUT
|
||||
{
|
||||
static int iRun = 0;
|
||||
export_processed_input_expolygons_to_svg(debug_out_path("mm-input-%d-%d.svg", layer_idx, iRun++), layers[layer_idx]->regions(), input_expolygons[layer_idx]);
|
||||
}
|
||||
#endif // MMU_SEGMENTATION_DEBUG_INPUT
|
||||
}
|
||||
}); // end of parallel_for
|
||||
BOOST_LOG_TRIVIAL(debug) << "MMU segmentation - slices preparation in parallel - end";
|
||||
|
||||
for (size_t layer_idx = 0; layer_idx < layers.size(); ++layer_idx) {
|
||||
throw_on_cancel_callback();
|
||||
BoundingBox bbox(get_extents(input_expolygons[layer_idx]));
|
||||
BoundingBox bbox(get_extents(layers[layer_idx]->regions()));
|
||||
bbox.merge(get_extents(input_expolygons[layer_idx]));
|
||||
// Projected triangles may slightly exceed the input polygons.
|
||||
bbox.offset(20 * SCALED_EPSILON);
|
||||
edge_grids[layer_idx].set_bbox(bbox);
|
||||
|
@ -1748,7 +1773,7 @@ std::vector<std::vector<std::pair<ExPolygon, size_t>>> multi_material_segmentati
|
|||
BOOST_LOG_TRIVIAL(debug) << "MMU segmentation - projection of painted triangles - begin";
|
||||
for (const ModelVolume *mv : print_object.model_object()->volumes) {
|
||||
const size_t num_extruders = print_object.print()->config().nozzle_diameter.size() + 1;
|
||||
tbb::parallel_for(tbb::blocked_range<size_t>(1, num_extruders), [&mv, &print_object, &edge_grids, &painted_lines, &painted_lines_mutex, &throw_on_cancel_callback](const tbb::blocked_range<size_t> &range) {
|
||||
tbb::parallel_for(tbb::blocked_range<size_t>(1, num_extruders), [&mv, &print_object, &edge_grids, &painted_lines, &painted_lines_mutex, &input_expolygons, &throw_on_cancel_callback](const tbb::blocked_range<size_t> &range) {
|
||||
for (size_t extruder_idx = range.begin(); extruder_idx < range.end(); ++extruder_idx) {
|
||||
throw_on_cancel_callback();
|
||||
const indexed_triangle_set custom_facets = mv->mmu_segmentation_facets.get_facets(*mv, EnforcerBlockerType(extruder_idx));
|
||||
|
@ -1756,7 +1781,7 @@ std::vector<std::vector<std::pair<ExPolygon, size_t>>> multi_material_segmentati
|
|||
continue;
|
||||
|
||||
const Transform3f tr = print_object.trafo().cast<float>() * mv->get_matrix().cast<float>();
|
||||
tbb::parallel_for(tbb::blocked_range<size_t>(0, custom_facets.indices.size()), [&tr, &custom_facets, &print_object, &edge_grids, &painted_lines, &painted_lines_mutex, &extruder_idx](const tbb::blocked_range<size_t> &range) {
|
||||
tbb::parallel_for(tbb::blocked_range<size_t>(0, custom_facets.indices.size()), [&tr, &custom_facets, &print_object, &edge_grids, &input_expolygons, &painted_lines, &painted_lines_mutex, &extruder_idx](const tbb::blocked_range<size_t> &range) {
|
||||
for (size_t facet_idx = range.begin(); facet_idx < range.end(); ++facet_idx) {
|
||||
float min_z = std::numeric_limits<float>::max();
|
||||
float max_z = std::numeric_limits<float>::lowest();
|
||||
|
@ -1781,7 +1806,7 @@ std::vector<std::vector<std::pair<ExPolygon, size_t>>> multi_material_segmentati
|
|||
for (auto layer_it = first_layer; layer_it != (last_layer + 1); ++layer_it) {
|
||||
const Layer *layer = *layer_it;
|
||||
size_t layer_idx = layer_it - print_object.layers().begin();
|
||||
if (facet[0].z() > layer->slice_z || layer->slice_z > facet[2].z())
|
||||
if (input_expolygons[layer_idx].empty() || facet[0].z() > layer->slice_z || layer->slice_z > facet[2].z())
|
||||
continue;
|
||||
|
||||
// https://kandepet.com/3d-printing-slicing-3d-objects/
|
||||
|
|
Loading…
Reference in a new issue