mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-07-28 21:32:11 +00:00
bugfix in progress
This commit is contained in:
@@ -30,6 +30,14 @@ namespace Slic3r {
|
|||||||
|
|
||||||
using namespace Slic3r::Feature::FuzzySkin;
|
using namespace Slic3r::Feature::FuzzySkin;
|
||||||
|
|
||||||
|
static bool is_gap_fill_allowed_for_surface(const PrintObjectConfig* config, const SurfaceType surface_type)
|
||||||
|
{
|
||||||
|
if (config == nullptr || config->gap_fill_target.value == gftNowhere)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return surface_type != stInternalSolid || config->gap_fill_target.value == gftEverywhere;
|
||||||
|
}
|
||||||
|
|
||||||
static void append_collapsed_infill_gap_fill(const ExPolygons &areas,
|
static void append_collapsed_infill_gap_fill(const ExPolygons &areas,
|
||||||
const Flow &flow,
|
const Flow &flow,
|
||||||
const double simplify_resolution,
|
const double simplify_resolution,
|
||||||
@@ -1706,7 +1714,7 @@ void PerimeterGenerator::process_classic()
|
|||||||
not_filled_exp,
|
not_filled_exp,
|
||||||
float(-inset - min_perimeter_infill_spacing / 2.),
|
float(-inset - min_perimeter_infill_spacing / 2.),
|
||||||
float(min_perimeter_infill_spacing / 2.));
|
float(min_perimeter_infill_spacing / 2.));
|
||||||
if (infill_exp.empty() && has_gap_fill) {
|
if (infill_exp.empty() && has_gap_fill && is_gap_fill_allowed_for_surface(object_config, surface.surface_type)) {
|
||||||
ExPolygons gap_fill_source = not_filled_exp.empty() ? collapsed_gap_fill_source : not_filled_exp;
|
ExPolygons gap_fill_source = not_filled_exp.empty() ? collapsed_gap_fill_source : not_filled_exp;
|
||||||
if (gap_fill_source.empty())
|
if (gap_fill_source.empty())
|
||||||
gap_fill_source = ExPolygons { surface.expolygon };
|
gap_fill_source = ExPolygons { surface.expolygon };
|
||||||
@@ -2581,7 +2589,8 @@ void PerimeterGenerator::process_arachne()
|
|||||||
not_filled_exp,
|
not_filled_exp,
|
||||||
float(-min_perimeter_infill_spacing / 2.),
|
float(-min_perimeter_infill_spacing / 2.),
|
||||||
float(inset + min_perimeter_infill_spacing / 2.));
|
float(inset + min_perimeter_infill_spacing / 2.));
|
||||||
if (infill_exp.empty() && this->config->gap_infill_speed.value > 0) {
|
if (infill_exp.empty() && this->config->gap_infill_speed.value > 0 &&
|
||||||
|
is_gap_fill_allowed_for_surface(object_config, surface.surface_type)) {
|
||||||
ExPolygons gap_fill_source = not_filled_exp.empty() ? collapsed_gap_fill_source : not_filled_exp;
|
ExPolygons gap_fill_source = not_filled_exp.empty() ? collapsed_gap_fill_source : not_filled_exp;
|
||||||
if (gap_fill_source.empty())
|
if (gap_fill_source.empty())
|
||||||
gap_fill_source = ExPolygons { surface.expolygon };
|
gap_fill_source = ExPolygons { surface.expolygon };
|
||||||
|
|||||||
@@ -1,7 +1,119 @@
|
|||||||
#include "VariableWidth.hpp"
|
#include "VariableWidth.hpp"
|
||||||
|
|
||||||
|
#include "BoundingBox.hpp"
|
||||||
|
|
||||||
namespace Slic3r {
|
namespace Slic3r {
|
||||||
|
|
||||||
|
static Points closed_loop_points(const ThickPolyline& thick_polyline)
|
||||||
|
{
|
||||||
|
Points points = thick_polyline.points;
|
||||||
|
if (points.size() > 1 && points.front() == points.back())
|
||||||
|
points.pop_back();
|
||||||
|
return points;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool points_match_cyclic(const Points& lhs, const Points& rhs, const coord_t point_tolerance, const bool reversed)
|
||||||
|
{
|
||||||
|
if (lhs.size() != rhs.size() || lhs.empty())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
const double tolerance_sq = double(point_tolerance) * double(point_tolerance);
|
||||||
|
for (size_t start = 0; start < rhs.size(); ++start) {
|
||||||
|
if ((lhs.front() - rhs[start]).cast<double>().squaredNorm() > tolerance_sq)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
bool matches = true;
|
||||||
|
for (size_t i = 0; i < lhs.size(); ++i) {
|
||||||
|
const size_t rhs_idx = reversed ? (start + rhs.size() - i) % rhs.size() : (start + i) % rhs.size();
|
||||||
|
if ((lhs[i] - rhs[rhs_idx]).cast<double>().squaredNorm() > tolerance_sq) {
|
||||||
|
matches = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (matches)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool are_near_duplicate_closed_gap_fill_loops(const ThickPolyline& lhs, const ThickPolyline& rhs)
|
||||||
|
{
|
||||||
|
if (!lhs.is_closed() || !rhs.is_closed())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
const Points lhs_points = closed_loop_points(lhs);
|
||||||
|
const Points rhs_points = closed_loop_points(rhs);
|
||||||
|
if (lhs_points.size() < 3 || lhs_points.size() != rhs_points.size())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
const coord_t bbox_tolerance = scale_(0.05);
|
||||||
|
const coord_t point_tolerance = scale_(0.05);
|
||||||
|
const double length_tolerance = double(scale_(0.20));
|
||||||
|
|
||||||
|
const BoundingBox lhs_bbox(lhs_points);
|
||||||
|
const BoundingBox rhs_bbox(rhs_points);
|
||||||
|
if (!lhs_bbox.defined || !rhs_bbox.defined)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (std::abs(lhs_bbox.min.x() - rhs_bbox.min.x()) > bbox_tolerance ||
|
||||||
|
std::abs(lhs_bbox.min.y() - rhs_bbox.min.y()) > bbox_tolerance ||
|
||||||
|
std::abs(lhs_bbox.max.x() - rhs_bbox.max.x()) > bbox_tolerance ||
|
||||||
|
std::abs(lhs_bbox.max.y() - rhs_bbox.max.y()) > bbox_tolerance)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (std::abs(length(lhs_points) - length(rhs_points)) > length_tolerance)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
const double area_tolerance = double(scale_(0.05)) * std::max(length(lhs_points), length(rhs_points));
|
||||||
|
if (std::abs(std::abs(area(lhs_points)) - std::abs(area(rhs_points))) > area_tolerance)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return points_match_cyclic(lhs_points, rhs_points, point_tolerance, false) ||
|
||||||
|
points_match_cyclic(lhs_points, rhs_points, point_tolerance, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
static ExtrusionPaths closed_gap_fill_loop_to_extrusion_paths(const ThickPolyline& thick_polyline, ExtrusionRole role, const Flow& flow)
|
||||||
|
{
|
||||||
|
ExtrusionPaths paths;
|
||||||
|
if (!thick_polyline.is_closed())
|
||||||
|
return paths;
|
||||||
|
|
||||||
|
ThickLines lines = thick_polyline.thicklines();
|
||||||
|
if (lines.empty())
|
||||||
|
return paths;
|
||||||
|
|
||||||
|
double total_length = 0.0;
|
||||||
|
double weighted_width_sum = 0.0;
|
||||||
|
for (const ThickLine& line : lines) {
|
||||||
|
const coordf_t line_len = line.length();
|
||||||
|
if (line_len < SCALED_EPSILON)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
total_length += line_len;
|
||||||
|
weighted_width_sum += line_len * 0.5 * (line.a_width + line.b_width);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (total_length <= SCALED_EPSILON)
|
||||||
|
return paths;
|
||||||
|
|
||||||
|
ExtrusionPath path(role);
|
||||||
|
path.polyline.points = thick_polyline.points;
|
||||||
|
if (!path.polyline.is_valid())
|
||||||
|
return paths;
|
||||||
|
|
||||||
|
const double average_width = weighted_width_sum / total_length;
|
||||||
|
const Flow new_flow = (role == erOverhangPerimeter && flow.bridge()) ?
|
||||||
|
flow :
|
||||||
|
flow.with_width(unscale<float>(average_width) + flow.height() * float(1. - 0.25 * PI));
|
||||||
|
path.mm3_per_mm = new_flow.mm3_per_mm();
|
||||||
|
path.width = new_flow.width();
|
||||||
|
path.height = new_flow.height();
|
||||||
|
paths.emplace_back(std::move(path));
|
||||||
|
return paths;
|
||||||
|
}
|
||||||
|
|
||||||
ExtrusionMultiPath thick_polyline_to_multi_path(const ThickPolyline& thick_polyline, ExtrusionRole role, const Flow& flow, const float tolerance, const float merge_tolerance)
|
ExtrusionMultiPath thick_polyline_to_multi_path(const ThickPolyline& thick_polyline, ExtrusionRole role, const Flow& flow, const float tolerance, const float merge_tolerance)
|
||||||
{
|
{
|
||||||
ExtrusionMultiPath multi_path;
|
ExtrusionMultiPath multi_path;
|
||||||
@@ -219,8 +331,33 @@ void variable_width(const ThickPolylines& polylines, ExtrusionRole role, const F
|
|||||||
// variable extrusion within a single move; this value shall only affect the amount
|
// variable extrusion within a single move; this value shall only affect the amount
|
||||||
// of segments, and any pruning shall be performed before we apply this tolerance.
|
// of segments, and any pruning shall be performed before we apply this tolerance.
|
||||||
const float tolerance = float(scale_(0.05));
|
const float tolerance = float(scale_(0.05));
|
||||||
for (const ThickPolyline& p : polylines) {
|
const ThickPolylines* source_polylines = &polylines;
|
||||||
ExtrusionPaths paths = thick_polyline_to_extrusion_paths_2(p, role, flow, tolerance);
|
ThickPolylines deduplicated_gap_fill_loops;
|
||||||
|
|
||||||
|
if (role == erGapFill && polylines.size() > 1) {
|
||||||
|
deduplicated_gap_fill_loops.reserve(polylines.size());
|
||||||
|
for (const ThickPolyline& polyline : polylines) {
|
||||||
|
bool is_duplicate = false;
|
||||||
|
for (const ThickPolyline& kept : deduplicated_gap_fill_loops) {
|
||||||
|
if (are_near_duplicate_closed_gap_fill_loops(polyline, kept)) {
|
||||||
|
is_duplicate = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!is_duplicate)
|
||||||
|
deduplicated_gap_fill_loops.emplace_back(polyline);
|
||||||
|
}
|
||||||
|
|
||||||
|
source_polylines = &deduplicated_gap_fill_loops;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const ThickPolyline& p : *source_polylines) {
|
||||||
|
ExtrusionPaths paths;
|
||||||
|
if (role == erGapFill && p.is_closed())
|
||||||
|
paths = closed_gap_fill_loop_to_extrusion_paths(p, role, flow);
|
||||||
|
if (paths.empty())
|
||||||
|
paths = thick_polyline_to_extrusion_paths_2(p, role, flow, tolerance);
|
||||||
// Append paths to collection.
|
// Append paths to collection.
|
||||||
if (!paths.empty()) {
|
if (!paths.empty()) {
|
||||||
if (paths.front().first_point() == paths.back().last_point())
|
if (paths.front().first_point() == paths.back().last_point())
|
||||||
|
|||||||
Reference in New Issue
Block a user