mirror of
https://git.mirrors.martin98.com/https://github.com/slic3r/Slic3r.git
synced 2025-07-21 23:24:25 +08:00
remove colinear points
* this fix the issue that colinear points aren't anymore after the offset2 from slice_closing_radius. * this allow the XY hole compensation to apply correctly * up the max concave angle accepted to detect hole to grow by XY compensation from 0.06° to 6°.
This commit is contained in:
parent
b12f484b48
commit
3476579d44
@ -316,6 +316,35 @@ Point Polygon::point_projection(const Point &point) const
|
|||||||
return proj;
|
return proj;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size_t Polygon::remove_colinear_points(coord_t max_offset){
|
||||||
|
size_t nb_del = 0;
|
||||||
|
if (points.size() < 3) return 0;
|
||||||
|
|
||||||
|
coord_t min_dist = max_offset * max_offset;
|
||||||
|
while (points.size() > 2 && Line::distance_to_squared(points[0], points.back(), points[1]) < min_dist){
|
||||||
|
//colinear! delete!
|
||||||
|
points.erase(points.begin());
|
||||||
|
nb_del++;
|
||||||
|
}
|
||||||
|
for (size_t idx = 1; idx < points.size()-1; ) {
|
||||||
|
//if (Line(previous, points[idx + 1]).distance_to(points[idx]) < SCALED_EPSILON){
|
||||||
|
if (Line::distance_to_squared(points[idx], points[idx-1], points[idx + 1]) < min_dist){
|
||||||
|
//colinear! delete!
|
||||||
|
points.erase(points.begin() + idx);
|
||||||
|
nb_del++;
|
||||||
|
} else {
|
||||||
|
idx++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while (points.size() > 2 && Line::distance_to_squared(points.back(), points[points.size()-2], points.front()) < min_dist) {
|
||||||
|
//colinear! delete!
|
||||||
|
points.erase(points.end()-1);
|
||||||
|
nb_del++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return nb_del;
|
||||||
|
}
|
||||||
|
|
||||||
BoundingBox get_extents(const Polygon &poly)
|
BoundingBox get_extents(const Polygon &poly)
|
||||||
{
|
{
|
||||||
return poly.bounding_box();
|
return poly.bounding_box();
|
||||||
|
@ -59,6 +59,9 @@ public:
|
|||||||
Points convex_points(double angle = PI) const;
|
Points convex_points(double angle = PI) const;
|
||||||
// Projection of a point onto the polygon.
|
// Projection of a point onto the polygon.
|
||||||
Point point_projection(const Point &point) const;
|
Point point_projection(const Point &point) const;
|
||||||
|
/// remove points that are (almost) on an existing line from previous & next point.
|
||||||
|
/// return number of point removed
|
||||||
|
size_t remove_colinear_points(coord_t max_offset);
|
||||||
};
|
};
|
||||||
|
|
||||||
extern BoundingBox get_extents(const Polygon &poly);
|
extern BoundingBox get_extents(const Polygon &poly);
|
||||||
|
@ -1870,10 +1870,10 @@ void PrintConfigDef::init_fff_params()
|
|||||||
def = this->add("resolution", coFloat);
|
def = this->add("resolution", coFloat);
|
||||||
def->label = L("Resolution");
|
def->label = L("Resolution");
|
||||||
def->tooltip = L("Minimum detail resolution, used to simplify the input file for speeding up "
|
def->tooltip = L("Minimum detail resolution, used to simplify the input file for speeding up "
|
||||||
"the slicing job and reducing memory usage. High-resolution models often carry "
|
"the slicing job and reducing memory usage. High-resolution models often carry "
|
||||||
"more detail than printers can render. Set to zero to disable any simplification "
|
"more detail than printers can render. Set to zero to disable any simplification "
|
||||||
"and use full resolution from input. "
|
"and use full resolution from input. "
|
||||||
"\nNote: slic3r simplify the geometry with a treshold of 0.0125mm and has an internal resolution of 0.0001mm.");
|
"\nNote: slic3r simplify the geometry with a treshold of 0.0125mm and has an internal resolution of 0.0001mm.");
|
||||||
def->sidetext = L("mm");
|
def->sidetext = L("mm");
|
||||||
def->cli = "resolution=f";
|
def->cli = "resolution=f";
|
||||||
def->min = 0;
|
def->min = 0;
|
||||||
@ -2254,6 +2254,20 @@ void PrintConfigDef::init_fff_params()
|
|||||||
def->mode = comExpert;
|
def->mode = comExpert;
|
||||||
def->default_value = new ConfigOptionStrings { "; Filament gcode\n" };
|
def->default_value = new ConfigOptionStrings { "; Filament gcode\n" };
|
||||||
|
|
||||||
|
|
||||||
|
def = this->add("model_precision", coFloat);
|
||||||
|
def->label = L("Model rounding precision");
|
||||||
|
def->full_label = L("Model rounding precision");
|
||||||
|
def->category = L("Advanced");
|
||||||
|
def->tooltip = L("This is the rounding error of the input object."
|
||||||
|
" It's used to align points that should be in the same line."
|
||||||
|
" Put 0 to disable.");
|
||||||
|
def->sidetext = L("mm");
|
||||||
|
def->cli = "model-precision=f";
|
||||||
|
def->min = 0;
|
||||||
|
def->mode = comExpert;
|
||||||
|
def->default_value = new ConfigOptionFloat(0.0001);
|
||||||
|
|
||||||
def = this->add("single_extruder_multi_material", coBool);
|
def = this->add("single_extruder_multi_material", coBool);
|
||||||
def->label = L("Single Extruder Multi Material");
|
def->label = L("Single Extruder Multi Material");
|
||||||
def->tooltip = L("The printer multiplexes filaments into a single hot end.");
|
def->tooltip = L("The printer multiplexes filaments into a single hot end.");
|
||||||
|
@ -453,13 +453,14 @@ public:
|
|||||||
ConfigOptionBool clip_multipart_objects;
|
ConfigOptionBool clip_multipart_objects;
|
||||||
ConfigOptionBool dont_support_bridges;
|
ConfigOptionBool dont_support_bridges;
|
||||||
ConfigOptionFloat elefant_foot_compensation;
|
ConfigOptionFloat elefant_foot_compensation;
|
||||||
|
ConfigOptionBool exact_last_layer_height;
|
||||||
ConfigOptionFloatOrPercent extrusion_width;
|
ConfigOptionFloatOrPercent extrusion_width;
|
||||||
ConfigOptionFloatOrPercent first_layer_height;
|
ConfigOptionFloatOrPercent first_layer_height;
|
||||||
ConfigOptionBool infill_only_where_needed;
|
ConfigOptionBool infill_only_where_needed;
|
||||||
// Force the generation of solid shells between adjacent materials/volumes.
|
// Force the generation of solid shells between adjacent materials/volumes.
|
||||||
ConfigOptionBool interface_shells;
|
ConfigOptionBool interface_shells;
|
||||||
ConfigOptionFloat layer_height;
|
ConfigOptionFloat layer_height;
|
||||||
ConfigOptionBool exact_last_layer_height;
|
ConfigOptionFloat model_precision;
|
||||||
ConfigOptionInt raft_layers;
|
ConfigOptionInt raft_layers;
|
||||||
ConfigOptionEnum<SeamPosition> seam_position;
|
ConfigOptionEnum<SeamPosition> seam_position;
|
||||||
ConfigOptionBool seam_travel;
|
ConfigOptionBool seam_travel;
|
||||||
@ -505,12 +506,13 @@ protected:
|
|||||||
OPT_PTR(clip_multipart_objects);
|
OPT_PTR(clip_multipart_objects);
|
||||||
OPT_PTR(dont_support_bridges);
|
OPT_PTR(dont_support_bridges);
|
||||||
OPT_PTR(elefant_foot_compensation);
|
OPT_PTR(elefant_foot_compensation);
|
||||||
|
OPT_PTR(exact_last_layer_height);
|
||||||
OPT_PTR(extrusion_width);
|
OPT_PTR(extrusion_width);
|
||||||
OPT_PTR(first_layer_height);
|
OPT_PTR(first_layer_height);
|
||||||
OPT_PTR(infill_only_where_needed);
|
OPT_PTR(infill_only_where_needed);
|
||||||
OPT_PTR(interface_shells);
|
OPT_PTR(interface_shells);
|
||||||
OPT_PTR(layer_height);
|
OPT_PTR(layer_height);
|
||||||
OPT_PTR(exact_last_layer_height);
|
OPT_PTR(model_precision);
|
||||||
OPT_PTR(raft_layers);
|
OPT_PTR(raft_layers);
|
||||||
OPT_PTR(seam_position);
|
OPT_PTR(seam_position);
|
||||||
OPT_PTR(seam_travel);
|
OPT_PTR(seam_travel);
|
||||||
|
@ -813,7 +813,6 @@ void PrintObject::tag_under_bridge() {
|
|||||||
for (ExPolygon poly_inter : dense_polys) area_dense += poly_inter.area();
|
for (ExPolygon poly_inter : dense_polys) area_dense += poly_inter.area();
|
||||||
double area_sparse = 0;
|
double area_sparse = 0;
|
||||||
for (ExPolygon poly_inter : sparse_polys) area_sparse += poly_inter.area();
|
for (ExPolygon poly_inter : sparse_polys) area_sparse += poly_inter.area();
|
||||||
std::cout << "need to split? " << area_sparse << " > " << area_dense << " * " << COEFF_SPLIT << "\n";
|
|
||||||
if (area_sparse > area_dense * COEFF_SPLIT) {
|
if (area_sparse > area_dense * COEFF_SPLIT) {
|
||||||
//split
|
//split
|
||||||
dense_polys = union_ex(dense_polys);
|
dense_polys = union_ex(dense_polys);
|
||||||
@ -1913,27 +1912,27 @@ end:
|
|||||||
|
|
||||||
void PrintObject::_offsetHoles(float hole_delta, LayerRegion *layerm) {
|
void PrintObject::_offsetHoles(float hole_delta, LayerRegion *layerm) {
|
||||||
if (hole_delta != 0.f) {
|
if (hole_delta != 0.f) {
|
||||||
|
std::cout << "offset_hole z="<<layerm->layer()->id()<<"\n";
|
||||||
ExPolygons polys = to_expolygons(std::move(layerm->slices.surfaces));
|
ExPolygons polys = to_expolygons(std::move(layerm->slices.surfaces));
|
||||||
ExPolygons new_polys;
|
ExPolygons new_polys;
|
||||||
for (ExPolygon ex_poly : polys) {
|
for (const ExPolygon &ex_poly : polys) {
|
||||||
ExPolygon new_ex_poly(ex_poly);
|
ExPolygon new_ex_poly(ex_poly);
|
||||||
new_ex_poly.holes.clear();
|
new_ex_poly.holes.clear();
|
||||||
for (Polygon hole : ex_poly.holes) {
|
for (const Polygon &hole : ex_poly.holes) {
|
||||||
//check if convex to reduce it
|
//check if convex to reduce it
|
||||||
// check whether first point forms a convex angle
|
// check whether first point forms a convex angle
|
||||||
|
//note: we allow a deviation of 5.7° (0.01rad = 0.57°)
|
||||||
bool ok = true;
|
bool ok = true;
|
||||||
ok = (hole.points.front().ccw_angle(hole.points.back(), *(hole.points.begin() + 1)) <= PI + 0.001);
|
ok = (hole.points.front().ccw_angle(hole.points.back(), *(hole.points.begin() + 1)) <= PI + 0.1);
|
||||||
|
|
||||||
|
|
||||||
// check whether points 1..(n-1) form convex angles
|
// check whether points 1..(n-1) form convex angles
|
||||||
if (ok)
|
if (ok)
|
||||||
for (Points::const_iterator p = hole.points.begin() + 1; p != hole.points.end() - 1; ++p) {
|
for (Points::const_iterator p = hole.points.begin() + 1; p != hole.points.end() - 1; ++p) {
|
||||||
ok = (p->ccw_angle(*(p - 1), *(p + 1)) <= PI + 0.001);
|
ok = (p->ccw_angle(*(p - 1), *(p + 1)) <= PI + 0.1);
|
||||||
if (!ok) break;
|
if (!ok) break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// check whether last point forms a convex angle
|
// check whether last point forms a convex angle
|
||||||
ok &= (hole.points.back().ccw_angle(*(hole.points.end() - 2), hole.points.front()) <= PI + 0.001);
|
ok &= (hole.points.back().ccw_angle(*(hole.points.end() - 2), hole.points.front()) <= PI + 0.1);
|
||||||
|
|
||||||
if (ok) {
|
if (ok) {
|
||||||
for (Polygon newHole : offset(hole, -hole_delta)) {
|
for (Polygon newHole : offset(hole, -hole_delta)) {
|
||||||
@ -1941,8 +1940,9 @@ void PrintObject::_offsetHoles(float hole_delta, LayerRegion *layerm) {
|
|||||||
newHole.make_clockwise();
|
newHole.make_clockwise();
|
||||||
new_ex_poly.holes.push_back(newHole);
|
new_ex_poly.holes.push_back(newHole);
|
||||||
}
|
}
|
||||||
} else
|
} else {
|
||||||
new_ex_poly.holes.push_back(hole);
|
new_ex_poly.holes.push_back(hole);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
new_polys.push_back(new_ex_poly);
|
new_polys.push_back(new_ex_poly);
|
||||||
}
|
}
|
||||||
@ -2007,11 +2007,11 @@ std::vector<ExPolygons> PrintObject::_slice_volumes(const std::vector<float> &z,
|
|||||||
// apply XY shift
|
// apply XY shift
|
||||||
mesh.translate(- unscale<float>(m_copies_shift(0)), - unscale<float>(m_copies_shift(1)), 0);
|
mesh.translate(- unscale<float>(m_copies_shift(0)), - unscale<float>(m_copies_shift(1)), 0);
|
||||||
// perform actual slicing
|
// perform actual slicing
|
||||||
TriangleMeshSlicer mslicer;
|
TriangleMeshSlicer mslicer(float(m_config.slice_closing_radius.value), float(m_config.model_precision.value));
|
||||||
const Print *print = this->print();
|
const Print *print = this->print();
|
||||||
auto callback = TriangleMeshSlicer::throw_on_cancel_callback_type([print](){print->throw_if_canceled();});
|
auto callback = TriangleMeshSlicer::throw_on_cancel_callback_type([print](){print->throw_if_canceled();});
|
||||||
mslicer.init(&mesh, callback);
|
mslicer.init(&mesh, callback);
|
||||||
mslicer.slice(z, float(m_config.slice_closing_radius.value), &layers, callback);
|
mslicer.slice(z, &layers, callback);
|
||||||
m_print->throw_if_canceled();
|
m_print->throw_if_canceled();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -561,7 +561,7 @@ void base_plate(const TriangleMesh &mesh, ExPolygons &output, float h,
|
|||||||
heights.emplace_back(hi);
|
heights.emplace_back(hi);
|
||||||
|
|
||||||
std::vector<ExPolygons> out; out.reserve(size_t(std::ceil(h/layerh)));
|
std::vector<ExPolygons> out; out.reserve(size_t(std::ceil(h/layerh)));
|
||||||
slicer.slice(heights, 0.f, &out, thrfn);
|
slicer.slice(heights, &out, thrfn);
|
||||||
|
|
||||||
size_t count = 0; for(auto& o : out) count += o.size();
|
size_t count = 0; for(auto& o : out) count += o.size();
|
||||||
|
|
||||||
|
@ -2105,7 +2105,7 @@ SlicedSupports SLASupportTree::slice(float layerh, float init_layerh) const
|
|||||||
fullmesh.merge(get_pad());
|
fullmesh.merge(get_pad());
|
||||||
TriangleMeshSlicer slicer(&fullmesh);
|
TriangleMeshSlicer slicer(&fullmesh);
|
||||||
SlicedSupports ret;
|
SlicedSupports ret;
|
||||||
slicer.slice(heights, 0.f, &ret, get().ctl().cancelfn);
|
slicer.slice(heights, &ret, get().ctl().cancelfn);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -629,7 +629,8 @@ void SLAPrint::process()
|
|||||||
double lh = po.m_config.layer_height.getFloat();
|
double lh = po.m_config.layer_height.getFloat();
|
||||||
|
|
||||||
TriangleMesh mesh = po.transformed_mesh();
|
TriangleMesh mesh = po.transformed_mesh();
|
||||||
TriangleMeshSlicer slicer(&mesh);
|
TriangleMeshSlicer slicer(float(po.config().slice_closing_radius.value),0);
|
||||||
|
slicer.init(&mesh, [](){});
|
||||||
|
|
||||||
// The 1D grid heights
|
// The 1D grid heights
|
||||||
std::vector<float> heights = calculate_heights(mesh.bounding_box(),
|
std::vector<float> heights = calculate_heights(mesh.bounding_box(),
|
||||||
@ -637,7 +638,7 @@ void SLAPrint::process()
|
|||||||
ilh, float(lh));
|
ilh, float(lh));
|
||||||
|
|
||||||
auto& layers = po.m_model_slices; layers.clear();
|
auto& layers = po.m_model_slices; layers.clear();
|
||||||
slicer.slice(heights, float(po.config().slice_closing_radius.value), &layers, [this](){ throw_if_canceled(); });
|
slicer.slice(heights, &layers, [this](){ throw_if_canceled(); });
|
||||||
};
|
};
|
||||||
|
|
||||||
// In this step we check the slices, identify island and cover them with
|
// In this step we check the slices, identify island and cover them with
|
||||||
|
@ -852,7 +852,7 @@ void TriangleMeshSlicer::_slice_do(size_t facet_idx, std::vector<IntersectionLin
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TriangleMeshSlicer::slice(const std::vector<float> &z, const float closing_radius, std::vector<ExPolygons>* layers, throw_on_cancel_callback_type throw_on_cancel) const
|
void TriangleMeshSlicer::slice(const std::vector<float> &z, std::vector<ExPolygons>* layers, throw_on_cancel_callback_type throw_on_cancel) const
|
||||||
{
|
{
|
||||||
std::vector<Polygons> layers_p;
|
std::vector<Polygons> layers_p;
|
||||||
this->slice(z, &layers_p, throw_on_cancel);
|
this->slice(z, &layers_p, throw_on_cancel);
|
||||||
@ -861,13 +861,13 @@ void TriangleMeshSlicer::slice(const std::vector<float> &z, const float closing_
|
|||||||
layers->resize(z.size());
|
layers->resize(z.size());
|
||||||
tbb::parallel_for(
|
tbb::parallel_for(
|
||||||
tbb::blocked_range<size_t>(0, z.size()),
|
tbb::blocked_range<size_t>(0, z.size()),
|
||||||
[&layers_p, closing_radius, layers, throw_on_cancel, this](const tbb::blocked_range<size_t>& range) {
|
[&layers_p, layers, throw_on_cancel, this](const tbb::blocked_range<size_t>& range) {
|
||||||
for (size_t layer_id = range.begin(); layer_id < range.end(); ++ layer_id) {
|
for (size_t layer_id = range.begin(); layer_id < range.end(); ++ layer_id) {
|
||||||
#ifdef SLIC3R_TRIANGLEMESH_DEBUG
|
#ifdef SLIC3R_TRIANGLEMESH_DEBUG
|
||||||
printf("Layer " PRINTF_ZU " (slice_z = %.2f):\n", layer_id, z[layer_id]);
|
printf("Layer " PRINTF_ZU " (slice_z = %.2f):\n", layer_id, z[layer_id]);
|
||||||
#endif
|
#endif
|
||||||
throw_on_cancel();
|
throw_on_cancel();
|
||||||
this->make_expolygons(layers_p[layer_id], closing_radius, &(*layers)[layer_id]);
|
this->make_expolygons(layers_p[layer_id], &(*layers)[layer_id]);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
BOOST_LOG_TRIVIAL(debug) << "TriangleMeshSlicer::make_expolygons in parallel - end";
|
BOOST_LOG_TRIVIAL(debug) << "TriangleMeshSlicer::make_expolygons in parallel - end";
|
||||||
@ -1002,7 +1002,7 @@ TriangleMeshSlicer::FacetSliceType TriangleMeshSlicer::slice_facet(
|
|||||||
line_out->a_id = points[1].point_id;
|
line_out->a_id = points[1].point_id;
|
||||||
line_out->b_id = points[0].point_id;
|
line_out->b_id = points[0].point_id;
|
||||||
line_out->edge_a_id = points[1].edge_id;
|
line_out->edge_a_id = points[1].edge_id;
|
||||||
line_out->edge_b_id = points[0].edge_id;
|
line_out->edge_b_id = points[0].edge_id;
|
||||||
// Not a zero lenght edge.
|
// Not a zero lenght edge.
|
||||||
//FIXME slice_facet() may create zero length edges due to rounding of doubles into coord_t.
|
//FIXME slice_facet() may create zero length edges due to rounding of doubles into coord_t.
|
||||||
//assert(line_out->a != line_out->b);
|
//assert(line_out->a != line_out->b);
|
||||||
@ -1184,7 +1184,7 @@ static void chain_lines_by_triangle_connectivity(std::vector<IntersectionLine> &
|
|||||||
if (next_line == nullptr) {
|
if (next_line == nullptr) {
|
||||||
// Check whether we closed this loop.
|
// Check whether we closed this loop.
|
||||||
if ((first_line->edge_a_id != -1 && first_line->edge_a_id == last_line->edge_b_id) ||
|
if ((first_line->edge_a_id != -1 && first_line->edge_a_id == last_line->edge_b_id) ||
|
||||||
(first_line->a_id != -1 && first_line->a_id == last_line->b_id)) {
|
(first_line->a_id != -1 && first_line->a_id == last_line->b_id)) {
|
||||||
// The current loop is complete. Add it to the output.
|
// The current loop is complete. Add it to the output.
|
||||||
loops.emplace_back(std::move(loop_pts));
|
loops.emplace_back(std::move(loop_pts));
|
||||||
#ifdef SLIC3R_TRIANGLEMESH_DEBUG
|
#ifdef SLIC3R_TRIANGLEMESH_DEBUG
|
||||||
@ -1600,7 +1600,7 @@ void TriangleMeshSlicer::make_expolygons_simple(std::vector<IntersectionLine> &l
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void TriangleMeshSlicer::make_expolygons(const Polygons &loops, const float closing_radius, ExPolygons* slices) const
|
void TriangleMeshSlicer::make_expolygons(const Polygons &loops, ExPolygons* slices) const
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
Input loops are not suitable for evenodd nor nonzero fill types, as we might get
|
Input loops are not suitable for evenodd nor nonzero fill types, as we might get
|
||||||
@ -1651,11 +1651,19 @@ void TriangleMeshSlicer::make_expolygons(const Polygons &loops, const float clos
|
|||||||
// p_slices = diff(p_slices, *loop);
|
// p_slices = diff(p_slices, *loop);
|
||||||
//}
|
//}
|
||||||
|
|
||||||
|
//remove point in the same plane (have to do that before the safety offset to avoid workgin on a distored polygon)
|
||||||
|
Polygons filered_polys = loops;
|
||||||
|
if (this->model_precision > 0){
|
||||||
|
for (Polygon &hole : filered_polys){
|
||||||
|
hole.remove_colinear_points(scale_(this->model_precision));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Perform a safety offset to merge very close facets (TODO: find test case for this)
|
// Perform a safety offset to merge very close facets (TODO: find test case for this)
|
||||||
// 0.0499 comes from https://github.com/slic3r/Slic3r/issues/959
|
// 0.0499 comes from https://github.com/slic3r/Slic3r/issues/959
|
||||||
// double safety_offset = scale_(0.0499);
|
// double safety_offset = scale_(0.0499);
|
||||||
// 0.0001 is set to satisfy GH #520, #1029, #1364
|
// 0.0001 is set to satisfy GH #520, #1029, #1364
|
||||||
double safety_offset = scale_(closing_radius);
|
double safety_offset = scale_(this->closing_radius);
|
||||||
|
|
||||||
/* The following line is commented out because it can generate wrong polygons,
|
/* The following line is commented out because it can generate wrong polygons,
|
||||||
see for example issue #661 */
|
see for example issue #661 */
|
||||||
@ -1671,16 +1679,16 @@ void TriangleMeshSlicer::make_expolygons(const Polygons &loops, const float clos
|
|||||||
|
|
||||||
// append to the supplied collection
|
// append to the supplied collection
|
||||||
if (safety_offset > 0)
|
if (safety_offset > 0)
|
||||||
expolygons_append(*slices, offset2_ex(union_(loops, false), +safety_offset, -safety_offset));
|
expolygons_append(*slices, offset2_ex(union_(filered_polys, false), +safety_offset, -safety_offset));
|
||||||
else
|
else
|
||||||
expolygons_append(*slices, union_ex(loops, false));
|
expolygons_append(*slices, union_ex(filered_polys, false));
|
||||||
}
|
}
|
||||||
|
|
||||||
void TriangleMeshSlicer::make_expolygons(std::vector<IntersectionLine> &lines, const float closing_radius, ExPolygons* slices) const
|
void TriangleMeshSlicer::make_expolygons(std::vector<IntersectionLine> &lines, ExPolygons* slices) const
|
||||||
{
|
{
|
||||||
Polygons pp;
|
Polygons pp;
|
||||||
this->make_loops(lines, &pp);
|
this->make_loops(lines, &pp);
|
||||||
this->make_expolygons(pp, closing_radius, slices);
|
this->make_expolygons(pp, slices);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TriangleMeshSlicer::cut(float z, TriangleMesh* upper, TriangleMesh* lower) const
|
void TriangleMeshSlicer::cut(float z, TriangleMesh* upper, TriangleMesh* lower) const
|
||||||
|
@ -159,13 +159,16 @@ typedef std::vector<IntersectionLine*> IntersectionLinePtrs;
|
|||||||
class TriangleMeshSlicer
|
class TriangleMeshSlicer
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
float closing_radius;
|
||||||
|
float model_precision;
|
||||||
|
|
||||||
typedef std::function<void()> throw_on_cancel_callback_type;
|
typedef std::function<void()> throw_on_cancel_callback_type;
|
||||||
TriangleMeshSlicer() : mesh(nullptr) {}
|
TriangleMeshSlicer(float closing_radius, float model_precision) : mesh(nullptr), closing_radius(closing_radius), model_precision(model_precision) {}
|
||||||
// Not quite nice, but the constructor and init() methods require non-const mesh pointer to be able to call mesh->require_shared_vertices()
|
// Not quite nice, but the constructor and init() methods require non-const mesh pointer to be able to call mesh->require_shared_vertices()
|
||||||
TriangleMeshSlicer(TriangleMesh* mesh) { this->init(mesh, [](){}); }
|
TriangleMeshSlicer(TriangleMesh* mesh) { this->init(mesh, [](){}); }
|
||||||
void init(TriangleMesh *mesh, throw_on_cancel_callback_type throw_on_cancel);
|
void init(TriangleMesh *mesh, throw_on_cancel_callback_type throw_on_cancel);
|
||||||
void slice(const std::vector<float> &z, std::vector<Polygons>* layers, throw_on_cancel_callback_type throw_on_cancel) const;
|
void slice(const std::vector<float> &z, std::vector<Polygons>* layers, throw_on_cancel_callback_type throw_on_cancel) const;
|
||||||
void slice(const std::vector<float> &z, const float closing_radius, std::vector<ExPolygons>* layers, throw_on_cancel_callback_type throw_on_cancel) const;
|
void slice(const std::vector<float> &z, std::vector<ExPolygons>* layers, throw_on_cancel_callback_type throw_on_cancel) const;
|
||||||
enum FacetSliceType {
|
enum FacetSliceType {
|
||||||
NoSlice = 0,
|
NoSlice = 0,
|
||||||
Slicing = 1,
|
Slicing = 1,
|
||||||
@ -184,9 +187,9 @@ private:
|
|||||||
|
|
||||||
void _slice_do(size_t facet_idx, std::vector<IntersectionLines>* lines, boost::mutex* lines_mutex, const std::vector<float> &z) const;
|
void _slice_do(size_t facet_idx, std::vector<IntersectionLines>* lines, boost::mutex* lines_mutex, const std::vector<float> &z) const;
|
||||||
void make_loops(std::vector<IntersectionLine> &lines, Polygons* loops) const;
|
void make_loops(std::vector<IntersectionLine> &lines, Polygons* loops) const;
|
||||||
void make_expolygons(const Polygons &loops, const float closing_radius, ExPolygons* slices) const;
|
void make_expolygons(const Polygons &loops, ExPolygons* slices) const;
|
||||||
void make_expolygons_simple(std::vector<IntersectionLine> &lines, ExPolygons* slices) const;
|
void make_expolygons_simple(std::vector<IntersectionLine> &lines, ExPolygons* slices) const;
|
||||||
void make_expolygons(std::vector<IntersectionLine> &lines, const float closing_radius, ExPolygons* slices) const;
|
void make_expolygons(std::vector<IntersectionLine> &lines, ExPolygons* slices) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
TriangleMesh make_cube(double x, double y, double z);
|
TriangleMesh make_cube(double x, double y, double z);
|
||||||
|
@ -402,6 +402,7 @@ const std::vector<std::string>& Preset::print_options()
|
|||||||
, "first_layer_infill_speed"
|
, "first_layer_infill_speed"
|
||||||
, "thin_walls_min_width"
|
, "thin_walls_min_width"
|
||||||
, "thin_walls_overlap"
|
, "thin_walls_overlap"
|
||||||
|
, "model_precision"
|
||||||
};
|
};
|
||||||
return s_opts;
|
return s_opts;
|
||||||
}
|
}
|
||||||
|
@ -1179,6 +1179,7 @@ void TabPrint::build()
|
|||||||
optgroup = page->new_optgroup(_(L("Other")));
|
optgroup = page->new_optgroup(_(L("Other")));
|
||||||
optgroup->append_single_option_line("clip_multipart_objects");
|
optgroup->append_single_option_line("clip_multipart_objects");
|
||||||
optgroup->append_single_option_line("resolution");
|
optgroup->append_single_option_line("resolution");
|
||||||
|
optgroup->append_single_option_line("model_precision");
|
||||||
|
|
||||||
page = add_options_page(_(L("Output options")), "page_white_go.png");
|
page = add_options_page(_(L("Output options")), "page_white_go.png");
|
||||||
optgroup = page->new_optgroup(_(L("Sequential printing")));
|
optgroup = page->new_optgroup(_(L("Sequential printing")));
|
||||||
|
Loading…
x
Reference in New Issue
Block a user