1) New methods PrintObject::num_regions() and ::has_region() to make
the code more readable and to highlight where PrintObject::region_volumes are actually set and consumed. 2) Replaced Slic3r::clamp() with std::clamp(). They differ in the order of their parameters, thus hopefully no new bugs were introduced. 3) Some refactoring of MultiMaterialSegmentation for efficiency.
This commit is contained in:
parent
4f950343c8
commit
38bb7d2950
19 changed files with 139 additions and 161 deletions
|
@ -1039,7 +1039,7 @@ ClipperLib::Path mittered_offset_path_scaled(const Points &contour, const std::v
|
|||
Vec2d nnext = perp(ptnext - pt).normalized();
|
||||
|
||||
double delta = deltas[i];
|
||||
double sin_a = clamp(-1., 1., cross2(nprev, nnext));
|
||||
double sin_a = std::clamp(cross2(nprev, nnext), -1., 1.);
|
||||
double convex = sin_a * delta;
|
||||
if (convex <= - sin_min_parallel) {
|
||||
// Concave corner.
|
||||
|
|
|
@ -270,7 +270,7 @@ std::vector<float> contour_distance2(const EdgeGrid::Grid &grid, const size_t id
|
|||
const Vec2d v = (segment.second - segment.first).cast<double>();
|
||||
const Vec2d va = (this->point - segment.first).cast<double>();
|
||||
const double l2 = v.squaredNorm(); // avoid a sqrt
|
||||
const double t = (l2 == 0.0) ? 0. : clamp(0., 1., va.dot(v) / l2);
|
||||
const double t = (l2 == 0.0) ? 0. : std::clamp(va.dot(v) / l2, 0., 1.);
|
||||
// Closest point from this->point to the segment.
|
||||
const Vec2d foot = segment.first.cast<double>() + t * v;
|
||||
const Vec2d bisector = foot - this->point.cast<double>();
|
||||
|
|
|
@ -550,10 +550,10 @@ void gcode_paint_layer(
|
|||
boost::geometry::expand(bboxLine, rect[2]);
|
||||
boost::geometry::expand(bboxLine, rect[3]);
|
||||
B2i bboxLinei(
|
||||
V2i(clamp(0, nc-1, int(floor(bboxLine.min_corner().x()))),
|
||||
clamp(0, nr-1, int(floor(bboxLine.min_corner().y())))),
|
||||
V2i(clamp(0, nc-1, int(ceil (bboxLine.max_corner().x()))),
|
||||
clamp(0, nr-1, int(ceil (bboxLine.max_corner().y())))));
|
||||
V2i(std::clamp(int(floor(bboxLine.min_corner().x())), 0, nc-1),
|
||||
std::clamp(int(floor(bboxLine.min_corner().y())), 0, nr-1)),
|
||||
V2i(std::clamp(int(ceil(bboxLine.max_corner().x())), 0, nc-1),
|
||||
std::clamp(int(ceil(bboxLine.max_corner().y())), 0, nr-1)));
|
||||
// printf("bboxLinei %d,%d %d,%d\n", bboxLinei.min_corner().x(), bboxLinei.min_corner().y(), bboxLinei.max_corner().x(), bboxLinei.max_corner().y());
|
||||
#ifdef _DEBUG
|
||||
float area = polyArea(rect, 4);
|
||||
|
@ -597,10 +597,10 @@ void gcode_paint_bitmap(
|
|||
boost::geometry::expand(bboxLine, rect[2]);
|
||||
boost::geometry::expand(bboxLine, rect[3]);
|
||||
B2i bboxLinei(
|
||||
V2i(clamp(0, nc-1, int(floor(bboxLine.min_corner().x()))),
|
||||
clamp(0, nr-1, int(floor(bboxLine.min_corner().y())))),
|
||||
V2i(clamp(0, nc-1, int(ceil (bboxLine.max_corner().x()))),
|
||||
clamp(0, nr-1, int(ceil (bboxLine.max_corner().y())))));
|
||||
V2i(std::clamp(int(floor(bboxLine.min_corner().x())), 0, nc-1),
|
||||
std::clamp(int(floor(bboxLine.min_corner().y())), 0, nr-1)),
|
||||
V2i(std::clamp(int(ceil(bboxLine.max_corner().x())), 0, nc-1),
|
||||
std::clamp(int(ceil(bboxLine.max_corner().y())), 0, nr-1)));
|
||||
// printf("bboxLinei %d,%d %d,%d\n", bboxLinei.min_corner().x(), bboxLinei.min_corner().y(), bboxLinei.max_corner().x(), bboxLinei.max_corner().y());
|
||||
for (int j = bboxLinei.min_corner().y(); j + 1 < bboxLinei.max_corner().y(); ++ j) {
|
||||
for (int i = bboxLinei.min_corner().x(); i + 1 < bboxLinei.max_corner().x(); ++i) {
|
||||
|
@ -664,10 +664,10 @@ void gcode_spread_points(
|
|||
const float height_target = it->height;
|
||||
B2f bbox(center - V2f(radius, radius), center + V2f(radius, radius));
|
||||
B2i bboxi(
|
||||
V2i(clamp(0, nc-1, int(floor(bbox.min_corner().x()))),
|
||||
clamp(0, nr-1, int(floor(bbox.min_corner().y())))),
|
||||
V2i(clamp(0, nc-1, int(ceil (bbox.max_corner().x()))),
|
||||
clamp(0, nr-1, int(ceil (bbox.max_corner().y())))));
|
||||
V2i(std::clamp(int(floor(bbox.min_corner().x())), 0, nc-1),
|
||||
std::clamp(int(floor(bbox.min_corner().y())), 0, nr-1)),
|
||||
V2i(std::clamp(int(ceil(bbox.max_corner().x())), 0, nc-1),
|
||||
std::clamp(int(ceil(bbox.max_corner().y())), 0, nr-1)));
|
||||
/*
|
||||
// Fill in the spans, at which the circle intersects the rows.
|
||||
int row_first = bboxi.min_corner().y();
|
||||
|
@ -758,7 +758,7 @@ void gcode_spread_points(
|
|||
area_circle_total += area;
|
||||
if (cell.area < area)
|
||||
cell.area = area;
|
||||
cell.fraction_covered = clamp(0.f, 1.f, (cell.area > 0) ? (area / cell.area) : 0);
|
||||
cell.fraction_covered = std::clamp((cell.area > 0) ? (area / cell.area) : 0, 0.f, 1.f);
|
||||
if (cell.fraction_covered == 0) {
|
||||
-- n_cells;
|
||||
continue;
|
||||
|
@ -1018,7 +1018,7 @@ void ExtrusionSimulator::evaluate_accumulator(ExtrusionSimulationType simulation
|
|||
float p = mask[r][c];
|
||||
#endif
|
||||
int idx = int(floor(p * float(pimpl->color_gradient.size()) + 0.5f));
|
||||
V3uc clr = pimpl->color_gradient[clamp(0, int(pimpl->color_gradient.size()-1), idx)];
|
||||
V3uc clr = pimpl->color_gradient[std::clamp(idx, 0, int(pimpl->color_gradient.size()-1))];
|
||||
*ptr ++ = clr.get<0>();
|
||||
*ptr ++ = clr.get<1>();
|
||||
*ptr ++ = clr.get<2>();
|
||||
|
|
|
@ -55,8 +55,8 @@ static std::vector<coordf_t> perpendPoints(const coordf_t offset, const size_t b
|
|||
static inline void trim(Pointfs &pts, coordf_t minX, coordf_t minY, coordf_t maxX, coordf_t maxY)
|
||||
{
|
||||
for (Vec2d &pt : pts) {
|
||||
pt(0) = clamp(minX, maxX, pt(0));
|
||||
pt(1) = clamp(minY, maxY, pt(1));
|
||||
pt.x() = std::clamp(pt.x(), minX, maxX);
|
||||
pt.y() = std::clamp(pt.y(), minY, maxY);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -53,7 +53,7 @@ static inline Polyline make_wave(
|
|||
polyline.points.reserve(points.size());
|
||||
for (auto& point : points) {
|
||||
point(1) += offset;
|
||||
point(1) = clamp(0., height, double(point(1)));
|
||||
point(1) = std::clamp(double(point.y()), 0., height);
|
||||
if (vertical)
|
||||
std::swap(point(0), point(1));
|
||||
polyline.points.emplace_back((point * scaleFactor).cast<coord_t>());
|
||||
|
|
|
@ -796,7 +796,7 @@ namespace DoExport {
|
|||
// get the minimum cross-section used in the print
|
||||
std::vector<double> mm3_per_mm;
|
||||
for (auto object : print.objects()) {
|
||||
for (size_t region_id = 0; region_id < object->region_volumes.size(); ++ region_id) {
|
||||
for (size_t region_id = 0; region_id < object->num_regions(); ++ region_id) {
|
||||
const PrintRegion* region = print.regions()[region_id];
|
||||
for (auto layer : object->layers()) {
|
||||
const LayerRegion* layerm = layer->regions()[region_id];
|
||||
|
|
|
@ -620,7 +620,7 @@ static std::vector<float> contour_distance(const EdgeGrid::Grid &grid,
|
|||
const Vec2d v = (segment.second - segment.first).cast<double>();
|
||||
const Vec2d va = (this->point - segment.first).cast<double>();
|
||||
const double l2 = v.squaredNorm(); // avoid a sqrt
|
||||
const double t = (l2 == 0.0) ? 0. : clamp(0., 1., va.dot(v) / l2);
|
||||
const double t = (l2 == 0.0) ? 0. : std::clamp(va.dot(v) / l2, 0., 1.);
|
||||
// Closest point from this->point to the segment.
|
||||
const Vec2d foot = segment.first.cast<double>() + t * v;
|
||||
const Vec2d bisector = foot - this->point.cast<double>();
|
||||
|
|
|
@ -722,8 +722,8 @@ std::string CoolingBuffer::apply_layer_cooldown(
|
|||
if (int(layer_id) >= disable_fan_first_layers && int(layer_id) + 1 < full_fan_speed_layer) {
|
||||
// Ramp up the fan speed from disable_fan_first_layers to full_fan_speed_layer.
|
||||
float factor = float(int(layer_id + 1) - disable_fan_first_layers) / float(full_fan_speed_layer - disable_fan_first_layers);
|
||||
fan_speed_new = clamp(0, 255, int(float(fan_speed_new ) * factor + 0.5f));
|
||||
bridge_fan_speed = clamp(0, 255, int(float(bridge_fan_speed) * factor + 0.5f));
|
||||
fan_speed_new = std::clamp(int(float(fan_speed_new) * factor + 0.5f), 0, 255);
|
||||
bridge_fan_speed = std::clamp(int(float(bridge_fan_speed) * factor + 0.5f), 0, 255);
|
||||
}
|
||||
#undef EXTRUDER_CONFIG
|
||||
bridge_fan_control = bridge_fan_speed > fan_speed_new;
|
||||
|
|
|
@ -223,7 +223,7 @@ void ToolOrdering::collect_extruders(const PrintObject &object, const std::vecto
|
|||
layer_tools.extruder_override = extruder_override;
|
||||
|
||||
// What extruders are required to print this object layer?
|
||||
for (size_t region_id = 0; region_id < object.region_volumes.size(); ++ region_id) {
|
||||
for (size_t region_id = 0; region_id < object.num_regions(); ++ region_id) {
|
||||
const LayerRegion *layerm = (region_id < layer->regions().size()) ? layer->regions()[region_id] : nullptr;
|
||||
if (layerm == nullptr)
|
||||
continue;
|
||||
|
@ -689,7 +689,7 @@ float WipingExtrusions::mark_wiping_extrusions(const Print& print, unsigned int
|
|||
// iterate through copies (aka PrintObject instances) first, so that we mark neighbouring infills to minimize travel moves
|
||||
for (unsigned int copy = 0; copy < num_of_copies; ++copy) {
|
||||
|
||||
for (size_t region_id = 0; region_id < object->region_volumes.size(); ++ region_id) {
|
||||
for (size_t region_id = 0; region_id < object->num_regions(); ++ region_id) {
|
||||
const auto& region = *object->print()->regions()[region_id];
|
||||
|
||||
if (!region.config().wipe_into_infill && !object->config().wipe_into_objects)
|
||||
|
@ -762,7 +762,7 @@ void WipingExtrusions::ensure_perimeters_infills_order(const Print& print)
|
|||
size_t num_of_copies = object->instances().size();
|
||||
|
||||
for (size_t copy = 0; copy < num_of_copies; ++copy) { // iterate through copies first, so that we mark neighbouring infills to minimize travel moves
|
||||
for (size_t region_id = 0; region_id < object->region_volumes.size(); ++ region_id) {
|
||||
for (size_t region_id = 0; region_id < object->num_regions(); ++ region_id) {
|
||||
const auto& region = *object->print()->regions()[region_id];
|
||||
|
||||
if (!region.config().wipe_into_infill && !object->config().wipe_into_objects)
|
||||
|
|
|
@ -63,8 +63,8 @@ static bool project_line_on_line(const Line &projection_l, const Line &projected
|
|||
assert(t1 <= 1.);
|
||||
assert(t2 <= 1.);
|
||||
|
||||
Point p1 = (projection_l.a.cast<double>() + t1 * v1).cast<coord_t>();
|
||||
Point p2 = (projection_l.a.cast<double>() + t2 * v1).cast<coord_t>();
|
||||
Point p1 = projection_l.a + (t1 * v1).cast<coord_t>();
|
||||
Point p2 = projection_l.a + (t2 * v1).cast<coord_t>();
|
||||
*new_projected = Line(p1, p2);
|
||||
return true;
|
||||
}
|
||||
|
@ -74,7 +74,7 @@ struct PaintedLine
|
|||
size_t contour_idx;
|
||||
size_t line_idx;
|
||||
Line projected_line;
|
||||
int color = 1;
|
||||
int color;
|
||||
};
|
||||
|
||||
struct PaintedLineVisitor
|
||||
|
@ -89,35 +89,31 @@ struct PaintedLineVisitor
|
|||
bool operator()(coord_t iy, coord_t ix)
|
||||
{
|
||||
// Called with a row and column of the grid cell, which is intersected by a line.
|
||||
auto cell_data_range = grid.cell_data_range(iy, ix);
|
||||
auto cell_data_range = grid.cell_data_range(iy, ix);
|
||||
const Vec2d v1 = line_to_test.vector().cast<double>();
|
||||
for (auto it_contour_and_segment = cell_data_range.first; it_contour_and_segment != cell_data_range.second; ++it_contour_and_segment) {
|
||||
Line grid_line = grid.line(*it_contour_and_segment);
|
||||
|
||||
const Vec2d v1 = (line_to_test.b - line_to_test.a).cast<double>().normalized();
|
||||
const Vec2d v2 = (grid_line.b - grid_line.a).cast<double>().normalized();
|
||||
double angle = ::acos(clamp(-1.0, 1.0, v1.dot(v2)));
|
||||
double angle_deg = Geometry::rad2deg(angle);
|
||||
Line grid_line = grid.line(*it_contour_and_segment);
|
||||
const Vec2d v2 = grid_line.vector().cast<double>();
|
||||
// When lines have too different length, it is necessary to normalize them
|
||||
if ((angle_deg >= 0 && angle_deg <= 30) || (angle_deg >= 150)) {
|
||||
Line line_to_test_projected;
|
||||
project_line_on_line(grid_line, line_to_test, &line_to_test_projected);
|
||||
|
||||
if (Slic3r::sqr(v1.dot(v2)) > cos_threshold2 * v1.squaredNorm() * v2.squaredNorm()) {
|
||||
// The two vectors are nearly collinear (their mutual angle is lower than 30 degrees)
|
||||
if (painted_lines_set.find(*it_contour_and_segment) == painted_lines_set.end()) {
|
||||
if (Line(grid_line.a, line_to_test_projected.a).length() > Line(grid_line.a, line_to_test_projected.b).length()) {
|
||||
line_to_test_projected.reverse();
|
||||
}
|
||||
|
||||
double dist_1 = grid_line.distance_to(line_to_test.a);
|
||||
double dist_2 = grid_line.distance_to(line_to_test.b);
|
||||
double dist_3 = line_to_test.distance_to(grid_line.a);
|
||||
double dist_4 = line_to_test.distance_to(grid_line.b);
|
||||
double total_dist = std::min(std::min(dist_1, dist_2), std::min(dist_3, dist_4));
|
||||
|
||||
if (total_dist > 50 * SCALED_EPSILON)
|
||||
continue;
|
||||
if (total_dist < 50 * SCALED_EPSILON) {
|
||||
Line line_to_test_projected;
|
||||
project_line_on_line(grid_line, line_to_test, &line_to_test_projected);
|
||||
|
||||
painted_lines.push_back({it_contour_and_segment->first, it_contour_and_segment->second, line_to_test_projected, this->color});
|
||||
painted_lines_set.insert(*it_contour_and_segment);
|
||||
if (Line(grid_line.a, line_to_test_projected.a).length() > Line(grid_line.a, line_to_test_projected.b).length()) {
|
||||
line_to_test_projected.reverse();
|
||||
}
|
||||
painted_lines.push_back({it_contour_and_segment->first, it_contour_and_segment->second, line_to_test_projected, this->color});
|
||||
painted_lines_set.insert(*it_contour_and_segment);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -130,13 +126,15 @@ struct PaintedLineVisitor
|
|||
Line line_to_test;
|
||||
std::unordered_set<std::pair<size_t, size_t>, boost::hash<std::pair<size_t, size_t>>> painted_lines_set;
|
||||
int color = -1;
|
||||
|
||||
static inline const double cos_threshold2 = Slic3r::sqr(cos(M_PI * 30. / 180.));
|
||||
};
|
||||
|
||||
static std::vector<ColoredLine> to_colored_lines(const Polygon &polygon, int color)
|
||||
{
|
||||
std::vector<ColoredLine> lines;
|
||||
lines.reserve(polygon.points.size());
|
||||
if (polygon.points.size() > 2) {
|
||||
lines.reserve(polygon.points.size());
|
||||
for (auto it = polygon.points.begin(); it != polygon.points.end() - 1; ++it)
|
||||
lines.push_back({Line(*it, *(it + 1)), color});
|
||||
lines.push_back({Line(polygon.points.back(), polygon.points.front()), color});
|
||||
|
@ -146,10 +144,11 @@ static std::vector<ColoredLine> to_colored_lines(const Polygon &polygon, int col
|
|||
|
||||
static Polygon colored_points_to_polygon(const std::vector<ColoredLine> &lines)
|
||||
{
|
||||
Points out;
|
||||
Polygon out;
|
||||
out.points.reserve(lines.size());
|
||||
for (const ColoredLine &l : lines)
|
||||
out.emplace_back(l.line.a);
|
||||
return Polygon(out);
|
||||
out.points.emplace_back(l.line.a);
|
||||
return out;
|
||||
}
|
||||
|
||||
static Polygons colored_points_to_polygon(const std::vector<std::vector<ColoredLine>> &lines)
|
||||
|
@ -160,7 +159,8 @@ static Polygons colored_points_to_polygon(const std::vector<std::vector<ColoredL
|
|||
return out;
|
||||
}
|
||||
|
||||
inline std::vector<ColoredLine> to_lines(const std::vector<std::vector<ColoredLine>> &c_lines)
|
||||
// Flatten the vector of vectors into a vector.
|
||||
static inline std::vector<ColoredLine> to_lines(const std::vector<std::vector<ColoredLine>> &c_lines)
|
||||
{
|
||||
size_t n_lines = 0;
|
||||
for (const auto &c_line : c_lines)
|
||||
|
@ -173,8 +173,7 @@ inline std::vector<ColoredLine> to_lines(const std::vector<std::vector<ColoredLi
|
|||
}
|
||||
|
||||
// Double vertex equal to a coord_t point after conversion to double.
|
||||
template<typename VertexType>
|
||||
inline bool vertex_equal_to_point(const VertexType &vertex, const Point &ipt)
|
||||
static bool vertex_equal_to_point(const Voronoi::VD::vertex_type &vertex, const Point &ipt)
|
||||
{
|
||||
// Convert ipt to doubles, force the 80bit FPU temporary to 64bit and then compare.
|
||||
// This should work with any settings of math compiler switches and the C++ compiler
|
||||
|
@ -186,7 +185,7 @@ inline bool vertex_equal_to_point(const VertexType &vertex, const Point &ipt)
|
|||
ulp_cmp(vertex.y(), double(ipt.y()), ULPS) == ulp_cmp_type::EQUAL;
|
||||
}
|
||||
|
||||
bool vertex_equal_to_point(const Voronoi::VD::vertex_type *vertex, const Point &ipt) {
|
||||
static inline bool vertex_equal_to_point(const Voronoi::VD::vertex_type *vertex, const Point &ipt) {
|
||||
return vertex_equal_to_point(*vertex, ipt);
|
||||
}
|
||||
|
||||
|
@ -967,7 +966,7 @@ static std::vector<std::pair<Polygon, size_t>> extract_colored_segments(MMU_Grap
|
|||
Vec2d process_line_vec_n = (process_line.a - process_line.b).cast<double>().normalized();
|
||||
Vec2d neighbour_line_vec_n = (graph.nodes[arc.to_idx].point - graph.nodes[arc.from_idx].point).cast<double>().normalized();
|
||||
|
||||
double angle = ::acos(clamp(-1.0, 1.0, neighbour_line_vec_n.dot(process_line_vec_n)));
|
||||
double angle = ::acos(std::clamp(neighbour_line_vec_n.dot(process_line_vec_n), -1.0, 1.0));
|
||||
if (Slic3r::cross2(neighbour_line_vec_n, process_line_vec_n) < 0.0)
|
||||
angle = 2.0 * (double) PI - angle;
|
||||
|
||||
|
@ -1050,7 +1049,7 @@ static inline double compute_edge_length(MMU_Graph &graph, size_t start_idx, MMU
|
|||
Vec2d second_line_vec = (second_line.b - second_line.a).cast<double>();
|
||||
Vec2d first_line_vec_n = first_line_vec.normalized();
|
||||
Vec2d second_line_vec_n = second_line_vec.normalized();
|
||||
double angle = ::acos(clamp(-1.0, 1.0, first_line_vec_n.dot(second_line_vec_n)));
|
||||
double angle = ::acos(std::clamp(first_line_vec_n.dot(second_line_vec_n), -1.0, 1.0));
|
||||
if (Slic3r::cross2(first_line_vec_n, second_line_vec_n) < 0.0)
|
||||
angle = 2.0 * (double) PI - angle;
|
||||
|
||||
|
@ -1276,9 +1275,9 @@ static inline std::vector<std::vector<ExPolygons>> mmu_segmentation_top_and_bott
|
|||
|
||||
for (size_t layer_idx = 0; layer_idx < print_object.layers().size(); ++layer_idx) {
|
||||
BOOST_LOG_TRIVIAL(debug) << "MMU segmentation of bottom layer: " << layer_idx;
|
||||
float extrusion_width = scale_(get_extrusion_width(layer_idx));
|
||||
int bottom_solid_layers = get_bottom_solid_layers(layer_idx);
|
||||
ExPolygons bottom_expolygon = bottom_layers[layer_idx];
|
||||
float extrusion_width = scale_(get_extrusion_width(layer_idx));
|
||||
int bottom_solid_layers = get_bottom_solid_layers(layer_idx);
|
||||
const ExPolygons &bottom_expolygon = bottom_layers[layer_idx];
|
||||
if (bottom_expolygon.empty())
|
||||
continue;
|
||||
|
||||
|
@ -1301,8 +1300,7 @@ static inline std::vector<std::vector<ExPolygons>> mmu_segmentation_top_and_bott
|
|||
|
||||
ExPolygons offset_e = offset_ex(layer_slices_trimmed, offset_value);
|
||||
ExPolygons intersection_poly_2 = intersection_ex(triangles_by_color_bottom[color_idx][layer_idx], offset_e);
|
||||
triangles_by_color_bottom[color_idx][last_idx].insert(triangles_by_color_bottom[color_idx][last_idx].end(), intersection_poly_2.begin(),
|
||||
intersection_poly_2.end());
|
||||
append(triangles_by_color_bottom[color_idx][last_idx], std::move(intersection_poly_2));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1312,13 +1310,10 @@ static inline std::vector<std::vector<ExPolygons>> mmu_segmentation_top_and_bott
|
|||
triangles_by_color_merged.assign(3, std::vector<ExPolygons>(layers.size()));
|
||||
for (size_t layer_idx = 0; layer_idx < layers.size(); ++layer_idx) {
|
||||
for (size_t color_idx = 0; color_idx < triangles_by_color_merged.size(); ++color_idx) {
|
||||
triangles_by_color_merged[color_idx][layer_idx].insert(triangles_by_color_merged[color_idx][layer_idx].end(),
|
||||
triangles_by_color_bottom[color_idx][layer_idx].begin(),
|
||||
triangles_by_color_bottom[color_idx][layer_idx].end());
|
||||
triangles_by_color_merged[color_idx][layer_idx].insert(triangles_by_color_merged[color_idx][layer_idx].end(),
|
||||
triangles_by_color_top[color_idx][layer_idx].begin(),
|
||||
triangles_by_color_top[color_idx][layer_idx].end());
|
||||
triangles_by_color_merged[color_idx][layer_idx] = union_ex(triangles_by_color_merged[color_idx][layer_idx]);
|
||||
auto &self = triangles_by_color_merged[color_idx][layer_idx];
|
||||
append(self, std::move(triangles_by_color_bottom[color_idx][layer_idx]));
|
||||
append(self, std::move(triangles_by_color_top[color_idx][layer_idx]));
|
||||
self = union_ex(self);
|
||||
}
|
||||
|
||||
// Cut all colors for cases when two colors are overlapping
|
||||
|
@ -1332,7 +1327,7 @@ static inline std::vector<std::vector<ExPolygons>> mmu_segmentation_top_and_bott
|
|||
}
|
||||
|
||||
static std::vector<std::vector<std::pair<ExPolygon, size_t>>> merge_segmented_layers(
|
||||
const std::vector<std::vector<std::pair<ExPolygon, size_t>>> &segmented_regions, const std::vector<std::vector<ExPolygons>> &top_and_bottom_layers)
|
||||
const std::vector<std::vector<std::pair<ExPolygon, size_t>>> &segmented_regions, std::vector<std::vector<ExPolygons>> &&top_and_bottom_layers)
|
||||
{
|
||||
std::vector<std::vector<std::pair<ExPolygon, size_t>>> segmented_regions_merged(segmented_regions.size());
|
||||
|
||||
|
@ -1344,14 +1339,12 @@ static std::vector<std::vector<std::pair<ExPolygon, size_t>>> merge_segmented_la
|
|||
for (const std::vector<ExPolygons> &top_and_bottom_layer : top_and_bottom_layers)
|
||||
cut_colored_expoly = diff_ex(cut_colored_expoly, top_and_bottom_layer[layer_idx]);
|
||||
for (ExPolygon &ex_poly : cut_colored_expoly)
|
||||
segmented_regions_merged[layer_idx].emplace_back(ex_poly, colored_expoly.second);
|
||||
|
||||
segmented_regions_merged[layer_idx].emplace_back(std::move(ex_poly), colored_expoly.second);
|
||||
}
|
||||
|
||||
for (size_t color_idx = 0; color_idx < top_and_bottom_layers.size(); ++color_idx) {
|
||||
ExPolygons top_and_bottom_expoly = top_and_bottom_layers[color_idx][layer_idx];
|
||||
for (const ExPolygon &expoly : top_and_bottom_expoly) { segmented_regions_merged[layer_idx].emplace_back(expoly, color_idx); }
|
||||
}
|
||||
for (size_t color_idx = 0; color_idx < top_and_bottom_layers.size(); ++color_idx)
|
||||
for (ExPolygon &expoly : top_and_bottom_layers[color_idx][layer_idx])
|
||||
segmented_regions_merged[layer_idx].emplace_back(std::move(expoly), color_idx);
|
||||
}
|
||||
}); // end of parallel_for
|
||||
|
||||
|
@ -1385,7 +1378,6 @@ std::vector<std::vector<std::pair<ExPolygon, size_t>>> multi_material_segmentati
|
|||
float max_z = std::numeric_limits<float>::lowest();
|
||||
|
||||
std::array<Vec3f, 3> facet;
|
||||
Points projected_facet(3);
|
||||
for (int p_idx = 0; p_idx < 3; ++p_idx) {
|
||||
facet[p_idx] = tr * custom_facets.vertices[custom_facets.indices[facet_idx](p_idx)];
|
||||
max_z = std::max(max_z, facet[p_idx].z());
|
||||
|
@ -1395,13 +1387,6 @@ std::vector<std::vector<std::pair<ExPolygon, size_t>>> multi_material_segmentati
|
|||
// Sort the vertices by z-axis for simplification of projected_facet on slices
|
||||
std::sort(facet.begin(), facet.end(), [](const Vec3f &p1, const Vec3f &p2) { return p1.z() < p2.z(); });
|
||||
|
||||
for (int p_idx = 0; p_idx < 3; ++p_idx) {
|
||||
projected_facet[p_idx] = Point(scale_(facet[p_idx].x()), scale_(facet[p_idx].y()));
|
||||
projected_facet[p_idx] = projected_facet[p_idx] - print_object.center_offset();
|
||||
}
|
||||
|
||||
ExPolygon triangle = ExPolygon(projected_facet);
|
||||
|
||||
// Find lowest slice not below the triangle.
|
||||
auto first_layer = std::upper_bound(print_object.layers().begin(), print_object.layers().end(), float(min_z - EPSILON),
|
||||
[](float z, const Layer *l1) { return z < l1->slice_z; });
|
||||
|
@ -1443,8 +1428,7 @@ std::vector<std::vector<std::pair<ExPolygon, size_t>>> multi_material_segmentati
|
|||
visitor.color = params.second;
|
||||
edge_grids[layer_idx].visit_cells_intersecting_line(line_start, line_end, visitor);
|
||||
|
||||
if (!painted_line_tmp.empty())
|
||||
painted_lines[layer_idx].insert(painted_lines[layer_idx].end(), painted_line_tmp.begin(), painted_line_tmp.end());
|
||||
append(painted_lines[layer_idx], std::move(painted_line_tmp));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1454,7 +1438,7 @@ std::vector<std::vector<std::pair<ExPolygon, size_t>>> multi_material_segmentati
|
|||
for (size_t layer_idx = range.begin(); layer_idx < range.end(); ++layer_idx) {
|
||||
// for(size_t layer_idx = 0; layer_idx < print_object.layers().size(); ++layer_idx) {
|
||||
BOOST_LOG_TRIVIAL(debug) << "MMU segmentation of layer: " << layer_idx;
|
||||
auto comp = [&edge_grids, &layer_idx](const PaintedLine &first, const PaintedLine &second) {
|
||||
auto comp = [&edge_grids, layer_idx](const PaintedLine &first, const PaintedLine &second) {
|
||||
Point first_start_p = *(edge_grids[layer_idx].contours()[first.contour_idx].begin() + first.line_idx);
|
||||
|
||||
return first.contour_idx < second.contour_idx ||
|
||||
|
@ -1469,11 +1453,8 @@ std::vector<std::vector<std::pair<ExPolygon, size_t>>> multi_material_segmentati
|
|||
|
||||
if (!painted_lines_single.empty()) {
|
||||
Polygons original_polygons;
|
||||
for (const Slic3r::EdgeGrid::Contour &contour : edge_grids[layer_idx].contours()) {
|
||||
Points points;
|
||||
for (const Point &point : contour) points.emplace_back(point);
|
||||
original_polygons.emplace_back(points);
|
||||
}
|
||||
for (const Slic3r::EdgeGrid::Contour &contour : edge_grids[layer_idx].contours())
|
||||
original_polygons.emplace_back(Points(contour.begin(), contour.end()));
|
||||
|
||||
std::vector<std::vector<ColoredLine>> color_poly = colorize_polygons(original_polygons, painted_lines_single);
|
||||
MMU_Graph graph = build_graph(layer_idx, color_poly);
|
||||
|
@ -1491,7 +1472,7 @@ std::vector<std::vector<std::pair<ExPolygon, size_t>>> multi_material_segmentati
|
|||
|
||||
// return segmented_regions;
|
||||
std::vector<std::vector<ExPolygons>> top_and_bottom_layers = mmu_segmentation_top_and_bottom_layers(print_object);
|
||||
std::vector<std::vector<std::pair<ExPolygon, size_t>>> segmented_regions_merged = merge_segmented_layers(segmented_regions, top_and_bottom_layers);
|
||||
std::vector<std::vector<std::pair<ExPolygon, size_t>>> segmented_regions_merged = merge_segmented_layers(segmented_regions, std::move(top_and_bottom_layers));
|
||||
return segmented_regions_merged;
|
||||
}
|
||||
|
||||
|
|
|
@ -1066,7 +1066,7 @@ Print::ApplyStatus Print::apply(const Model &model, DynamicPrintConfig new_full_
|
|||
assert(it_status->status != ModelObjectStatus::Deleted);
|
||||
layer_ranges = &it_status->layer_ranges;
|
||||
}
|
||||
if (region_id < print_object->region_volumes.size()) {
|
||||
if (region_id < print_object->num_regions()) {
|
||||
for (const std::pair<t_layer_height_range, int> &volume_and_range : print_object->region_volumes[region_id]) {
|
||||
const ModelVolume &volume = *print_object->model_object()->volumes[volume_and_range.second];
|
||||
const DynamicPrintConfig *layer_range_config = layer_ranges->config(volume_and_range.first);
|
||||
|
@ -1106,7 +1106,7 @@ Print::ApplyStatus Print::apply(const Model &model, DynamicPrintConfig new_full_
|
|||
if (! diff.empty()) {
|
||||
// Stop the background process before assigning new configuration to the regions.
|
||||
for (PrintObject *print_object : m_objects)
|
||||
if (region_id < print_object->region_volumes.size() && ! print_object->region_volumes[region_id].empty())
|
||||
if (print_object->has_region(region_id))
|
||||
update_apply_status(print_object->invalidate_state_by_config_options(region.config(), this_region_config, diff));
|
||||
region.config_apply_only(this_region_config, diff, false);
|
||||
}
|
||||
|
@ -1169,7 +1169,7 @@ Print::ApplyStatus Print::apply(const Model &model, DynamicPrintConfig new_full_
|
|||
region_id = regions_in_object[idx_region_in_object ++];
|
||||
// Assign volume to a region.
|
||||
if (fresh) {
|
||||
if ((size_t)region_id >= print_object.region_volumes.size() || print_object.region_volumes[region_id].empty())
|
||||
if (! print_object.has_region(size_t(region_id)))
|
||||
++ m_regions[region_id]->m_refcnt;
|
||||
print_object.add_region_volume(region_id, volume_id, it_range->first);
|
||||
}
|
||||
|
@ -1506,7 +1506,7 @@ std::string Print::validate(std::string* warning) const
|
|||
if ((object->has_support() || object->has_raft()) && ! validate_extrusion_width(object->config(), "support_material_extrusion_width", layer_height, err_msg))
|
||||
return err_msg;
|
||||
for (const char *opt_key : { "perimeter_extrusion_width", "external_perimeter_extrusion_width", "infill_extrusion_width", "solid_infill_extrusion_width", "top_infill_extrusion_width" })
|
||||
for (size_t i = 0; i < object->region_volumes.size(); ++ i)
|
||||
for (size_t i = 0; i < object->num_regions(); ++ i)
|
||||
if (! object->region_volumes[i].empty() && ! validate_extrusion_width(this->get_region(i)->config(), opt_key, layer_height, err_msg))
|
||||
return err_msg;
|
||||
}
|
||||
|
|
|
@ -177,6 +177,8 @@ public:
|
|||
|
||||
bool has_brim() const { return this->config().brim_type != btNoBrim && this->config().brim_width.value > 0.; }
|
||||
|
||||
size_t num_regions() const { return this->region_volumes.size(); }
|
||||
bool has_region(size_t i) const { return i < this->region_volumes.size() && ! this->region_volumes[i].empty(); }
|
||||
|
||||
// adds region_id, too, if necessary
|
||||
void add_region_volume(unsigned int region_id, int volume_id, const t_layer_height_range &layer_range) {
|
||||
|
@ -471,6 +473,7 @@ public:
|
|||
return (it == m_objects.end()) ? nullptr : *it;
|
||||
}
|
||||
ConstPrintRegionPtrsAdaptor regions() const { return ConstPrintRegionPtrsAdaptor(&m_regions); }
|
||||
size_t num_regions() const { return m_regions.size(); }
|
||||
// How many of PrintObject::copies() over all print objects are there?
|
||||
// If zero, then the print is empty and the print shall not be executed.
|
||||
unsigned int num_object_instances() const;
|
||||
|
|
|
@ -174,7 +174,7 @@ void PrintObject::make_perimeters()
|
|||
// but we don't generate any extra perimeter if fill density is zero, as they would be floating
|
||||
// inside the object - infill_only_where_needed should be the method of choice for printing
|
||||
// hollow objects
|
||||
for (size_t region_id = 0; region_id < this->region_volumes.size(); ++ region_id) {
|
||||
for (size_t region_id = 0; region_id < this->num_regions(); ++ region_id) {
|
||||
const PrintRegion ®ion = *m_print->regions()[region_id];
|
||||
if (! region.config().extra_perimeters || region.config().perimeters == 0 || region.config().fill_density == 0 || this->layer_count() < 2)
|
||||
continue;
|
||||
|
@ -295,7 +295,7 @@ void PrintObject::prepare_infill()
|
|||
|
||||
// Debugging output.
|
||||
#ifdef SLIC3R_DEBUG_SLICE_PROCESSING
|
||||
for (size_t region_id = 0; region_id < this->region_volumes.size(); ++ region_id) {
|
||||
for (size_t region_id = 0; region_id < this->num_regions(); ++ region_id) {
|
||||
for (const Layer *layer : m_layers) {
|
||||
LayerRegion *layerm = layer->m_regions[region_id];
|
||||
layerm->export_region_slices_to_svg_debug("6_discover_vertical_shells-final");
|
||||
|
@ -314,7 +314,7 @@ void PrintObject::prepare_infill()
|
|||
m_print->throw_if_canceled();
|
||||
|
||||
#ifdef SLIC3R_DEBUG_SLICE_PROCESSING
|
||||
for (size_t region_id = 0; region_id < this->region_volumes.size(); ++ region_id) {
|
||||
for (size_t region_id = 0; region_id < this->num_regions(); ++ region_id) {
|
||||
for (const Layer *layer : m_layers) {
|
||||
LayerRegion *layerm = layer->m_regions[region_id];
|
||||
layerm->export_region_slices_to_svg_debug("7_discover_horizontal_shells-final");
|
||||
|
@ -333,7 +333,7 @@ void PrintObject::prepare_infill()
|
|||
m_print->throw_if_canceled();
|
||||
|
||||
#ifdef SLIC3R_DEBUG_SLICE_PROCESSING
|
||||
for (size_t region_id = 0; region_id < this->region_volumes.size(); ++ region_id) {
|
||||
for (size_t region_id = 0; region_id < this->num_regions(); ++ region_id) {
|
||||
for (const Layer *layer : m_layers) {
|
||||
LayerRegion *layerm = layer->m_regions[region_id];
|
||||
layerm->export_region_slices_to_svg_debug("8_clip_surfaces-final");
|
||||
|
@ -352,7 +352,7 @@ void PrintObject::prepare_infill()
|
|||
m_print->throw_if_canceled();
|
||||
|
||||
#ifdef SLIC3R_DEBUG_SLICE_PROCESSING
|
||||
for (size_t region_id = 0; region_id < this->region_volumes.size(); ++ region_id) {
|
||||
for (size_t region_id = 0; region_id < this->num_regions(); ++ region_id) {
|
||||
for (const Layer *layer : m_layers) {
|
||||
LayerRegion *layerm = layer->m_regions[region_id];
|
||||
layerm->export_region_slices_to_svg_debug("9_prepare_infill-final");
|
||||
|
@ -744,7 +744,7 @@ bool PrintObject::invalidate_all_steps()
|
|||
|
||||
static const PrintRegion* first_printing_region(const PrintObject &print_object)
|
||||
{
|
||||
for (size_t idx_region = 0; idx_region < print_object.region_volumes.size(); ++ idx_region)
|
||||
for (size_t idx_region = 0; idx_region < print_object.num_regions(); ++ idx_region)
|
||||
if (!print_object.region_volumes.empty())
|
||||
return print_object.print()->regions()[idx_region];
|
||||
return nullptr;
|
||||
|
@ -772,7 +772,7 @@ void PrintObject::detect_surfaces_type()
|
|||
bool interface_shells = ! spiral_vase && m_config.interface_shells.value;
|
||||
size_t num_layers = spiral_vase ? std::min(size_t(first_printing_region(*this)->config().bottom_solid_layers), m_layers.size()) : m_layers.size();
|
||||
|
||||
for (size_t idx_region = 0; idx_region < this->region_volumes.size(); ++ idx_region) {
|
||||
for (size_t idx_region = 0; idx_region < this->num_regions(); ++ idx_region) {
|
||||
BOOST_LOG_TRIVIAL(debug) << "Detecting solid surfaces for region " << idx_region << " in parallel - start";
|
||||
#ifdef SLIC3R_DEBUG_SLICE_PROCESSING
|
||||
for (Layer *layer : m_layers)
|
||||
|
@ -971,7 +971,7 @@ void PrintObject::process_external_surfaces()
|
|||
// Is there any printing region, that has zero infill? If so, then we don't want the expansion to be performed over the complete voids, but only
|
||||
// over voids, which are supported by the layer below.
|
||||
bool has_voids = false;
|
||||
for (size_t region_id = 0; region_id < this->region_volumes.size(); ++ region_id)
|
||||
for (size_t region_id = 0; region_id < this->num_regions(); ++ region_id)
|
||||
if (! this->region_volumes.empty() && this->print()->regions()[region_id]->config().fill_density == 0) {
|
||||
has_voids = true;
|
||||
break;
|
||||
|
@ -1021,7 +1021,7 @@ void PrintObject::process_external_surfaces()
|
|||
BOOST_LOG_TRIVIAL(debug) << "Collecting surfaces covered with extrusions in parallel - end";
|
||||
}
|
||||
|
||||
for (size_t region_id = 0; region_id < this->region_volumes.size(); ++region_id) {
|
||||
for (size_t region_id = 0; region_id < this->num_regions(); ++region_id) {
|
||||
BOOST_LOG_TRIVIAL(debug) << "Processing external surfaces for region " << region_id << " in parallel - start";
|
||||
tbb::parallel_for(
|
||||
tbb::blocked_range<size_t>(0, m_layers.size()),
|
||||
|
@ -1069,13 +1069,13 @@ void PrintObject::discover_vertical_shells()
|
|||
num_extra_layers(config.bottom_solid_layers, config.bottom_solid_min_thickness) > 0;
|
||||
};
|
||||
std::vector<DiscoverVerticalShellsCacheEntry> cache_top_botom_regions(num_layers, DiscoverVerticalShellsCacheEntry());
|
||||
bool top_bottom_surfaces_all_regions = this->region_volumes.size() > 1 && ! m_config.interface_shells.value;
|
||||
bool top_bottom_surfaces_all_regions = this->num_regions() > 1 && ! m_config.interface_shells.value;
|
||||
if (top_bottom_surfaces_all_regions) {
|
||||
// This is a multi-material print and interface_shells are disabled, meaning that the vertical shell thickness
|
||||
// is calculated over all materials.
|
||||
// Is the "ensure vertical wall thickness" applicable to any region?
|
||||
bool has_extra_layers = false;
|
||||
for (size_t idx_region = 0; idx_region < this->region_volumes.size(); ++idx_region) {
|
||||
for (size_t idx_region = 0; idx_region < this->num_regions(); ++idx_region) {
|
||||
const PrintRegionConfig &config = m_print->get_region(idx_region)->config();
|
||||
if (config.ensure_vertical_shell_thickness.value && has_extra_layers_fn(config)) {
|
||||
has_extra_layers = true;
|
||||
|
@ -1092,7 +1092,7 @@ void PrintObject::discover_vertical_shells()
|
|||
tbb::blocked_range<size_t>(0, num_layers, grain_size),
|
||||
[this, &cache_top_botom_regions](const tbb::blocked_range<size_t>& range) {
|
||||
const SurfaceType surfaces_bottom[2] = { stBottom, stBottomBridge };
|
||||
const size_t num_regions = this->region_volumes.size();
|
||||
const size_t num_regions = this->num_regions();
|
||||
for (size_t idx_layer = range.begin(); idx_layer < range.end(); ++ idx_layer) {
|
||||
m_print->throw_if_canceled();
|
||||
const Layer &layer = *m_layers[idx_layer];
|
||||
|
@ -1153,7 +1153,7 @@ void PrintObject::discover_vertical_shells()
|
|||
BOOST_LOG_TRIVIAL(debug) << "Discovering vertical shells in parallel - end : cache top / bottom";
|
||||
}
|
||||
|
||||
for (size_t idx_region = 0; idx_region < this->region_volumes.size(); ++ idx_region) {
|
||||
for (size_t idx_region = 0; idx_region < this->num_regions(); ++ idx_region) {
|
||||
PROFILE_BLOCK(discover_vertical_shells_region);
|
||||
|
||||
const PrintRegion ®ion = *m_print->get_region(idx_region);
|
||||
|
@ -1458,7 +1458,7 @@ void PrintObject::bridge_over_infill()
|
|||
{
|
||||
BOOST_LOG_TRIVIAL(info) << "Bridge over infill..." << log_memory_info();
|
||||
|
||||
for (size_t region_id = 0; region_id < this->region_volumes.size(); ++ region_id) {
|
||||
for (size_t region_id = 0; region_id < this->num_regions(); ++ region_id) {
|
||||
const PrintRegion ®ion = *m_print->regions()[region_id];
|
||||
|
||||
// skip bridging in case there are no voids
|
||||
|
@ -1685,9 +1685,9 @@ SlicingParameters PrintObject::slicing_parameters(const DynamicPrintConfig& full
|
|||
std::vector<unsigned int> PrintObject::object_extruders() const
|
||||
{
|
||||
std::vector<unsigned int> extruders;
|
||||
extruders.reserve(this->region_volumes.size() * 3);
|
||||
for (size_t idx_region = 0; idx_region < this->region_volumes.size(); ++ idx_region)
|
||||
if (! this->region_volumes[idx_region].empty())
|
||||
extruders.reserve(this->num_regions() * 3);
|
||||
for (size_t idx_region = 0; idx_region < this->num_regions(); ++ idx_region)
|
||||
if (this->has_region(idx_region))
|
||||
m_print->get_region(idx_region)->collect_object_printing_extruders(extruders);
|
||||
sort_remove_duplicates(extruders);
|
||||
return extruders;
|
||||
|
@ -1756,7 +1756,7 @@ void PrintObject::_slice(const std::vector<coordf_t> &layer_height_profile)
|
|||
layer->lower_layer = prev;
|
||||
}
|
||||
// Make sure all layers contain layer region objects for all regions.
|
||||
for (size_t region_id = 0; region_id < this->region_volumes.size(); ++ region_id)
|
||||
for (size_t region_id = 0; region_id < this->num_regions(); ++ region_id)
|
||||
layer->add_region(this->print()->get_region(region_id));
|
||||
prev = layer;
|
||||
}
|
||||
|
@ -1767,7 +1767,7 @@ void PrintObject::_slice(const std::vector<coordf_t> &layer_height_profile)
|
|||
bool has_z_ranges = false;
|
||||
size_t num_volumes = 0;
|
||||
size_t num_modifiers = 0;
|
||||
for (int region_id = 0; region_id < (int)this->region_volumes.size(); ++ region_id) {
|
||||
for (int region_id = 0; region_id < (int)this->num_regions(); ++ region_id) {
|
||||
int last_volume_id = -1;
|
||||
for (const std::pair<t_layer_height_range, int> &volume_and_range : this->region_volumes[region_id]) {
|
||||
const int volume_id = volume_and_range.second;
|
||||
|
@ -1799,7 +1799,7 @@ void PrintObject::_slice(const std::vector<coordf_t> &layer_height_profile)
|
|||
if (! has_z_ranges && (! m_config.clip_multipart_objects.value || all_volumes_single_region >= 0)) {
|
||||
// Cheap path: Slice regions without mutual clipping.
|
||||
// The cheap path is possible if no clipping is allowed or if slicing volumes of just a single region.
|
||||
for (size_t region_id = 0; region_id < this->region_volumes.size(); ++ region_id) {
|
||||
for (size_t region_id = 0; region_id < this->num_regions(); ++ region_id) {
|
||||
BOOST_LOG_TRIVIAL(debug) << "Slicing objects - region " << region_id;
|
||||
// slicing in parallel
|
||||
size_t slicing_mode_normal_below_layer = 0;
|
||||
|
@ -1832,7 +1832,7 @@ void PrintObject::_slice(const std::vector<coordf_t> &layer_height_profile)
|
|||
};
|
||||
std::vector<SlicedVolume> sliced_volumes;
|
||||
sliced_volumes.reserve(num_volumes);
|
||||
for (size_t region_id = 0; region_id < this->region_volumes.size(); ++ region_id) {
|
||||
for (size_t region_id = 0; region_id < this->num_regions(); ++ region_id) {
|
||||
const std::vector<std::pair<t_layer_height_range, int>> &volumes_and_ranges = this->region_volumes[region_id];
|
||||
for (size_t i = 0; i < volumes_and_ranges.size(); ) {
|
||||
int volume_id = volumes_and_ranges[i].second;
|
||||
|
@ -1884,7 +1884,7 @@ void PrintObject::_slice(const std::vector<coordf_t> &layer_height_profile)
|
|||
}
|
||||
}
|
||||
// Collect and union volumes of a single region.
|
||||
for (int region_id = 0; region_id < (int)this->region_volumes.size(); ++ region_id) {
|
||||
for (int region_id = 0; region_id < (int)this->num_regions(); ++ region_id) {
|
||||
ExPolygons expolygons;
|
||||
size_t num_volumes = 0;
|
||||
for (SlicedVolume &sliced_volume : sliced_volumes)
|
||||
|
@ -1915,7 +1915,7 @@ void PrintObject::_slice(const std::vector<coordf_t> &layer_height_profile)
|
|||
this->m_layers[layer_idx]->lslices = union_ex(ex_polygons);
|
||||
}
|
||||
|
||||
size_t region_count_before_change = this->region_volumes.size();
|
||||
size_t region_count_before_change = this->num_regions();
|
||||
std::vector<std::vector<std::pair<ExPolygon, size_t>>> segmented_regions = multi_material_segmentation_by_painting(*this);
|
||||
// Skip region with default extruder
|
||||
for (size_t region_idx = 1; region_idx < 3; ++region_idx) {
|
||||
|
@ -1944,15 +1944,15 @@ void PrintObject::_slice(const std::vector<coordf_t> &layer_height_profile)
|
|||
for (size_t i_layer = 0; i_layer < m_layers.size(); i_layer += 1) {
|
||||
Layer *layer = m_layers[i_layer];
|
||||
// Make sure all layers contain layer region objects for all regions.
|
||||
for (size_t region_id = region_count_before_change; region_id < this->region_volumes.size(); ++ region_id)
|
||||
for (size_t region_id = region_count_before_change; region_id < this->num_regions(); ++ region_id)
|
||||
layer->add_region(this->print()->get_region(region_id));
|
||||
}
|
||||
|
||||
// --------------------MMU_SEGMENTATION_END----------------------
|
||||
|
||||
// Slice all modifier volumes.
|
||||
if (this->region_volumes.size() > 1) {
|
||||
for (size_t region_id = 0; region_id < this->region_volumes.size(); ++ region_id) {
|
||||
if (this->num_regions() > 1) {
|
||||
for (size_t region_id = 0; region_id < this->num_regions(); ++ region_id) {
|
||||
BOOST_LOG_TRIVIAL(debug) << "Slicing modifier volumes - region " << region_id;
|
||||
// slicing in parallel
|
||||
std::vector<ExPolygons> expolygons_by_layer = this->slice_modifiers(region_id, slice_zs);
|
||||
|
@ -1965,7 +1965,7 @@ void PrintObject::_slice(const std::vector<coordf_t> &layer_height_profile)
|
|||
tbb::blocked_range<size_t>(0, m_layers.size()),
|
||||
[this, &expolygons_by_layer, region_id](const tbb::blocked_range<size_t>& range) {
|
||||
for (size_t layer_id = range.begin(); layer_id < range.end(); ++ layer_id) {
|
||||
for (size_t other_region_id = 0; other_region_id < this->region_volumes.size(); ++ other_region_id) {
|
||||
for (size_t other_region_id = 0; other_region_id < this->num_regions(); ++ other_region_id) {
|
||||
if (region_id == other_region_id)
|
||||
continue;
|
||||
Layer *layer = m_layers[layer_id];
|
||||
|
@ -2106,7 +2106,7 @@ end:
|
|||
std::vector<ExPolygons> PrintObject::slice_region(size_t region_id, const std::vector<float> &z, SlicingMode mode, size_t slicing_mode_normal_below_layer, SlicingMode mode_below) const
|
||||
{
|
||||
std::vector<const ModelVolume*> volumes;
|
||||
if (region_id < this->region_volumes.size()) {
|
||||
if (region_id < this->num_regions()) {
|
||||
for (const std::pair<t_layer_height_range, int> &volume_and_range : this->region_volumes[region_id]) {
|
||||
const ModelVolume *volume = this->model_object()->volumes[volume_and_range.second];
|
||||
if (volume->is_model_part())
|
||||
|
@ -2120,7 +2120,7 @@ std::vector<ExPolygons> PrintObject::slice_region(size_t region_id, const std::v
|
|||
std::vector<ExPolygons> PrintObject::slice_modifiers(size_t region_id, const std::vector<float> &slice_zs) const
|
||||
{
|
||||
std::vector<ExPolygons> out;
|
||||
if (region_id < this->region_volumes.size())
|
||||
if (region_id < this->num_regions())
|
||||
{
|
||||
std::vector<std::vector<t_layer_height_range>> volume_ranges;
|
||||
const std::vector<std::pair<t_layer_height_range, int>> &volumes_and_ranges = this->region_volumes[region_id];
|
||||
|
@ -2174,7 +2174,7 @@ std::vector<ExPolygons> PrintObject::slice_modifiers(size_t region_id, const std
|
|||
} else {
|
||||
// Some modifier in this region was split to layer spans.
|
||||
std::vector<char> merge;
|
||||
for (size_t region_id = 0; region_id < this->region_volumes.size(); ++ region_id) {
|
||||
for (size_t region_id = 0; region_id < this->num_regions(); ++ region_id) {
|
||||
const std::vector<std::pair<t_layer_height_range, int>> &volumes_and_ranges = this->region_volumes[region_id];
|
||||
for (size_t i = 0; i < volumes_and_ranges.size(); ) {
|
||||
int volume_id = volumes_and_ranges[i].second;
|
||||
|
@ -2544,7 +2544,7 @@ void PrintObject::discover_horizontal_shells()
|
|||
{
|
||||
BOOST_LOG_TRIVIAL(trace) << "discover_horizontal_shells()";
|
||||
|
||||
for (size_t region_id = 0; region_id < this->region_volumes.size(); ++ region_id) {
|
||||
for (size_t region_id = 0; region_id < this->num_regions(); ++ region_id) {
|
||||
for (size_t i = 0; i < m_layers.size(); ++ i) {
|
||||
m_print->throw_if_canceled();
|
||||
Layer *layer = m_layers[i];
|
||||
|
@ -2730,7 +2730,7 @@ void PrintObject::discover_horizontal_shells()
|
|||
} // for each region
|
||||
|
||||
#ifdef SLIC3R_DEBUG_SLICE_PROCESSING
|
||||
for (size_t region_id = 0; region_id < this->region_volumes.size(); ++ region_id) {
|
||||
for (size_t region_id = 0; region_id < this->num_regions(); ++ region_id) {
|
||||
for (const Layer *layer : m_layers) {
|
||||
const LayerRegion *layerm = layer->m_regions[region_id];
|
||||
layerm->export_region_slices_to_svg_debug("5_discover_horizontal_shells");
|
||||
|
@ -2746,7 +2746,7 @@ void PrintObject::discover_horizontal_shells()
|
|||
void PrintObject::combine_infill()
|
||||
{
|
||||
// Work on each region separately.
|
||||
for (size_t region_id = 0; region_id < this->region_volumes.size(); ++ region_id) {
|
||||
for (size_t region_id = 0; region_id < this->num_regions(); ++ region_id) {
|
||||
const PrintRegion *region = this->print()->regions()[region_id];
|
||||
const size_t every = region->config().infill_every_layers.value;
|
||||
if (every < 2 || region->config().fill_density == 0.)
|
||||
|
|
|
@ -298,7 +298,7 @@ std::vector<double> layer_height_profile_adaptive(const SlicingParameters& slici
|
|||
if (z_gap > 0.0)
|
||||
{
|
||||
layer_height_profile.push_back(slicing_params.object_print_z_height());
|
||||
layer_height_profile.push_back(clamp(slicing_params.min_layer_height, slicing_params.max_layer_height, z_gap));
|
||||
layer_height_profile.push_back(std::clamp(z_gap, slicing_params.min_layer_height, slicing_params.max_layer_height));
|
||||
}
|
||||
|
||||
return layer_height_profile;
|
||||
|
@ -376,7 +376,7 @@ std::vector<double> smooth_height_profile(const std::vector<double>& profile, co
|
|||
}
|
||||
}
|
||||
|
||||
height = clamp(slicing_params.min_layer_height, slicing_params.max_layer_height, (weight_total != 0.0) ? height /= weight_total : hi);
|
||||
height = std::clamp((weight_total != 0.0) ? height /= weight_total : hi, slicing_params.min_layer_height, slicing_params.max_layer_height);
|
||||
if (smoothing_params.keep_min)
|
||||
height = std::min(height, hi);
|
||||
}
|
||||
|
@ -502,7 +502,7 @@ void adjust_layer_height_profile(
|
|||
assert(false);
|
||||
break;
|
||||
}
|
||||
height = clamp(slicing_params.min_layer_height, slicing_params.max_layer_height, height);
|
||||
height = std::clamp(height, slicing_params.min_layer_height, slicing_params.max_layer_height);
|
||||
if (zz == z_span_variable.second) {
|
||||
// This is the last point of the profile.
|
||||
if (profile_new[profile_new.size() - 2] + EPSILON > zz) {
|
||||
|
@ -670,11 +670,11 @@ int generate_layer_height_texture(
|
|||
assert(mid <= slicing_params.object_print_z_height());
|
||||
coordf_t h = hi - lo;
|
||||
hi = std::min(hi, slicing_params.object_print_z_height());
|
||||
int cell_first = clamp(0, ncells-1, int(ceil(lo * z_to_cell)));
|
||||
int cell_last = clamp(0, ncells-1, int(floor(hi * z_to_cell)));
|
||||
int cell_first = std::clamp(int(ceil(lo * z_to_cell)), 0, ncells-1);
|
||||
int cell_last = std::clamp(int(floor(hi * z_to_cell)), 0, ncells-1);
|
||||
for (int cell = cell_first; cell <= cell_last; ++ cell) {
|
||||
coordf_t idxf = (0.5 * hscale + (h - slicing_params.layer_height)) * coordf_t(palette_raw.size()-1) / hscale;
|
||||
int idx1 = clamp(0, int(palette_raw.size() - 1), int(floor(idxf)));
|
||||
int idx1 = std::clamp(int(floor(idxf)), 0, int(palette_raw.size() - 1));
|
||||
int idx2 = std::min(int(palette_raw.size() - 1), idx1 + 1);
|
||||
coordf_t t = idxf - coordf_t(idx1);
|
||||
const Vec3crd &color1 = palette_raw[idx1];
|
||||
|
@ -693,9 +693,9 @@ int generate_layer_height_texture(
|
|||
assert(row >= 0 && row < rows);
|
||||
assert(col >= 0 && col < cols);
|
||||
unsigned char *ptr = (unsigned char*)data + (row * cols + col) * 4;
|
||||
ptr[0] = (unsigned char)clamp<int>(0, 255, int(floor(color(0) + 0.5)));
|
||||
ptr[1] = (unsigned char)clamp<int>(0, 255, int(floor(color(1) + 0.5)));
|
||||
ptr[2] = (unsigned char)clamp<int>(0, 255, int(floor(color(2) + 0.5)));
|
||||
ptr[0] = (unsigned char)std::clamp(int(floor(color(0) + 0.5)), 0, 255);
|
||||
ptr[1] = (unsigned char)std::clamp(int(floor(color(1) + 0.5)), 0, 255);
|
||||
ptr[2] = (unsigned char)std::clamp(int(floor(color(2) + 0.5)), 0, 255);
|
||||
ptr[3] = 255;
|
||||
if (col == 0 && row > 0) {
|
||||
// Duplicate the first value in a row as a last value of the preceding row.
|
||||
|
@ -706,11 +706,11 @@ int generate_layer_height_texture(
|
|||
}
|
||||
}
|
||||
if (level_of_detail_2nd_level) {
|
||||
cell_first = clamp(0, ncells1-1, int(ceil(lo * z_to_cell1)));
|
||||
cell_last = clamp(0, ncells1-1, int(floor(hi * z_to_cell1)));
|
||||
cell_first = std::clamp(int(ceil(lo * z_to_cell1)), 0, ncells1-1);
|
||||
cell_last = std::clamp(int(floor(hi * z_to_cell1)), 0, ncells1-1);
|
||||
for (int cell = cell_first; cell <= cell_last; ++ cell) {
|
||||
coordf_t idxf = (0.5 * hscale + (h - slicing_params.layer_height)) * coordf_t(palette_raw.size()-1) / hscale;
|
||||
int idx1 = clamp(0, int(palette_raw.size() - 1), int(floor(idxf)));
|
||||
int idx1 = std::clamp(int(floor(idxf)), 0, int(palette_raw.size() - 1));
|
||||
int idx2 = std::min(int(palette_raw.size() - 1), idx1 + 1);
|
||||
coordf_t t = idxf - coordf_t(idx1);
|
||||
const Vec3crd &color1 = palette_raw[idx1];
|
||||
|
@ -725,9 +725,9 @@ int generate_layer_height_texture(
|
|||
assert(row >= 0 && row < rows/2);
|
||||
assert(col >= 0 && col < cols/2);
|
||||
unsigned char *ptr = data1 + (row * cols1 + col) * 4;
|
||||
ptr[0] = (unsigned char)clamp<int>(0, 255, int(floor(color(0) + 0.5)));
|
||||
ptr[1] = (unsigned char)clamp<int>(0, 255, int(floor(color(1) + 0.5)));
|
||||
ptr[2] = (unsigned char)clamp<int>(0, 255, int(floor(color(2) + 0.5)));
|
||||
ptr[0] = (unsigned char)std::clamp(int(floor(color(0) + 0.5)), 0, 255);
|
||||
ptr[1] = (unsigned char)std::clamp(int(floor(color(1) + 0.5)), 0, 255);
|
||||
ptr[2] = (unsigned char)std::clamp(int(floor(color(2) + 0.5)), 0, 255);
|
||||
ptr[3] = 255;
|
||||
if (col == 0 && row > 0) {
|
||||
// Duplicate the first value in a row as a last value of the preceding row.
|
||||
|
|
|
@ -347,8 +347,8 @@ PrintObjectSupportMaterial::PrintObjectSupportMaterial(const PrintObject *object
|
|||
coordf_t external_perimeter_width = 0.;
|
||||
size_t num_nonempty_regions = 0;
|
||||
coordf_t bridge_flow_ratio = 0;
|
||||
for (size_t region_id = 0; region_id < object->region_volumes.size(); ++ region_id)
|
||||
if (! object->region_volumes[region_id].empty()) {
|
||||
for (size_t region_id = 0; region_id < object->num_regions(); ++ region_id)
|
||||
if (object->has_region(region_id)) {
|
||||
++ num_nonempty_regions;
|
||||
const PrintRegion ®ion = *object->print()->get_region(region_id);
|
||||
external_perimeter_width = std::max(external_perimeter_width, coordf_t(region.flow(*object, frExternalPerimeter, slicing_params.layer_height).width()));
|
||||
|
|
|
@ -41,7 +41,7 @@ namespace detail {
|
|||
// Degenerate to a single closest point.
|
||||
t = - b / (2. * a);
|
||||
assert(t >= - EPSILON && t <= 1. + EPSILON);
|
||||
return Slic3r::clamp(0., 1., t);
|
||||
return std::clamp(t, 0., 1.);
|
||||
} else {
|
||||
u = sqrt(u);
|
||||
out.first = 2;
|
||||
|
@ -1142,7 +1142,7 @@ std::vector<Vec2d> edge_offset_contour_intersections(
|
|||
#endif // NDEBUG
|
||||
if (! bisector || (dmin != dmax && offset_distance >= dmin)) {
|
||||
double t = (offset_distance - dmin) / (dmax - dmin);
|
||||
t = clamp(0., 1., t);
|
||||
t = std::clamp(t, 0., 1.);
|
||||
if (d1 < d0) {
|
||||
out[edge_idx2] = Slic3r::lerp(vertex_point(v1), vertex_point(v0), t);
|
||||
// mark visited
|
||||
|
|
|
@ -239,26 +239,20 @@ template<typename T> inline bool one_of(const T& v, const std::initializer_list<
|
|||
{ return contains(il, v); }
|
||||
|
||||
template<typename T>
|
||||
static inline T sqr(T x)
|
||||
constexpr inline T sqr(T x)
|
||||
{
|
||||
return x * x;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
static inline T clamp(const T low, const T high, const T value)
|
||||
{
|
||||
return std::max(low, std::min(high, value));
|
||||
}
|
||||
|
||||
template <typename T, typename Number>
|
||||
static inline T lerp(const T& a, const T& b, Number t)
|
||||
constexpr inline T lerp(const T& a, const T& b, Number t)
|
||||
{
|
||||
assert((t >= Number(-EPSILON)) && (t <= Number(1) + Number(EPSILON)));
|
||||
return (Number(1) - t) * a + t * b;
|
||||
}
|
||||
|
||||
template <typename Number>
|
||||
static inline bool is_approx(Number value, Number test_value)
|
||||
constexpr inline bool is_approx(Number value, Number test_value)
|
||||
{
|
||||
return std::fabs(double(value) - double(test_value)) < double(EPSILON);
|
||||
}
|
||||
|
|
|
@ -271,7 +271,7 @@ void GLCanvas3D::LayersEditing::render_overlay(const GLCanvas3D& canvas) const
|
|||
ImGui::SameLine();
|
||||
float widget_align = ImGui::GetCursorPosX();
|
||||
ImGui::PushItemWidth(imgui.get_style_scaling() * 120.0f);
|
||||
m_adaptive_quality = clamp(0.0f, 1.f, m_adaptive_quality);
|
||||
m_adaptive_quality = std::clamp(m_adaptive_quality, 0.0f, 1.f);
|
||||
ImGui::SliderFloat("", &m_adaptive_quality, 0.0f, 1.f, "%.2f");
|
||||
|
||||
ImGui::Separator();
|
||||
|
|
|
@ -110,7 +110,7 @@ void GLGizmoRotate::on_update(const UpdateData& data)
|
|||
Vec2d orig_dir = Vec2d::UnitX();
|
||||
Vec2d new_dir = mouse_pos.normalized();
|
||||
|
||||
double theta = ::acos(clamp(-1.0, 1.0, new_dir.dot(orig_dir)));
|
||||
double theta = ::acos(std::clamp(new_dir.dot(orig_dir), -1.0, 1.0));
|
||||
if (cross2(orig_dir, new_dir) < 0.0)
|
||||
theta = 2.0 * (double)PI - theta;
|
||||
|
||||
|
|
Loading…
Reference in a new issue