mirror of
https://git.mirrors.martin98.com/https://github.com/slic3r/Slic3r.git
synced 2025-07-14 01:51:45 +08:00
fix merge
This commit is contained in:
parent
eff2c84ecc
commit
4e8a7b0e9e
@ -2196,16 +2196,16 @@ void GCode::process_layer(
|
||||
if (m_config.avoid_crossing_perimeters)
|
||||
m_avoid_crossing_perimeters.init_layer_mp(union_ex(m_layer->slices, true));
|
||||
|
||||
if (this->config().gcode_label_objects)
|
||||
gcode += std::string("; printing object ") + instance_to_print.print_object.model_object()->name
|
||||
+ " id:" + std::to_string(std::find(this->m_ordered_objects.begin(), this->m_ordered_objects.end(), &instance_to_print.print_object) - this->m_ordered_objects.begin())
|
||||
+ " copy " + std::to_string(instance_to_print.instance_id) + "\n";
|
||||
// When starting a new object, use the external motion planner for the first travel move.
|
||||
if (this->config().gcode_label_objects)
|
||||
gcode += std::string("; printing object ") + instance_to_print.print_object.model_object()->name
|
||||
+ " id:" + std::to_string(std::find(this->m_ordered_objects.begin(), this->m_ordered_objects.end(), &instance_to_print.print_object) - this->m_ordered_objects.begin())
|
||||
+ " copy " + std::to_string(instance_to_print.instance_id) + "\n";
|
||||
// When starting a new object, use the external motion planner for the first travel move.
|
||||
const Point &offset = instance_to_print.print_object.copies()[instance_to_print.instance_id];
|
||||
std::pair<const PrintObject*, Point> this_object_copy(&instance_to_print.print_object, offset);
|
||||
if (m_last_obj_copy != this_object_copy)
|
||||
m_avoid_crossing_perimeters.use_external_mp_once = true;
|
||||
m_last_obj_copy = this_object_copy;
|
||||
if (m_last_obj_copy != this_object_copy)
|
||||
m_avoid_crossing_perimeters.use_external_mp_once = true;
|
||||
m_last_obj_copy = this_object_copy;
|
||||
this->set_origin(unscale(offset));
|
||||
if (instance_to_print.object_by_extruder.support != nullptr && !print_wipe_extrusions) {
|
||||
m_layer = layers[instance_to_print.layer_id].support_layer;
|
||||
@ -2213,21 +2213,22 @@ void GCode::process_layer(
|
||||
// support_extrusion_role is erSupportMaterial, erSupportMaterialInterface or erMixed for all extrusion paths.
|
||||
instance_to_print.object_by_extruder.support->chained_path_from(m_last_pos, instance_to_print.object_by_extruder.support_extrusion_role));
|
||||
m_layer = layers[instance_to_print.layer_id].layer();
|
||||
}
|
||||
for (ObjectByExtruder::Island &island : instance_to_print.object_by_extruder.islands) {
|
||||
const auto& by_region_specific = is_anything_overridden ? island.by_region_per_copy(instance_to_print.instance_id, extruder_id, print_wipe_extrusions) : island.by_region;
|
||||
|
||||
gcode += this->extrude_infill(print, by_region_specific, true);
|
||||
gcode += this->extrude_perimeters(print, by_region_specific, lower_layer_edge_grids[instance_to_print.layer_id]);
|
||||
gcode += this->extrude_infill(print, by_region_specific, false);
|
||||
}
|
||||
if (this->config().gcode_label_objects)
|
||||
gcode += std::string("; stop printing object ") + instance_to_print.print_object.model_object()->name
|
||||
+ " id:" + std::to_string((std::find(this->m_ordered_objects.begin(), this->m_ordered_objects.end(), &instance_to_print.print_object) - this->m_ordered_objects.begin()))
|
||||
+ " copy " + std::to_string(instance_to_print.instance_id) + "\n";
|
||||
}
|
||||
for (ObjectByExtruder::Island &island : instance_to_print.object_by_extruder.islands) {
|
||||
const std::vector<GCode::ObjectByExtruder::Island::Region>& by_region_specific = is_anything_overridden ? island.by_region_per_copy(instance_to_print.instance_id, extruder_id, print_wipe_extrusions) : island.by_region;
|
||||
if (m_layer_index == 110)
|
||||
std::cout << "test point\n";
|
||||
gcode += this->extrude_infill(print, by_region_specific, true);
|
||||
gcode += this->extrude_perimeters(print, by_region_specific, lower_layer_edge_grids[instance_to_print.layer_id]);
|
||||
gcode += this->extrude_infill(print, by_region_specific, false);
|
||||
}
|
||||
if (this->config().gcode_label_objects)
|
||||
gcode += std::string("; stop printing object ") + instance_to_print.print_object.model_object()->name
|
||||
+ " id:" + std::to_string((std::find(this->m_ordered_objects.begin(), this->m_ordered_objects.end(), &instance_to_print.print_object) - this->m_ordered_objects.begin()))
|
||||
+ " copy " + std::to_string(instance_to_print.instance_id) + "\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Apply spiral vase post-processing if this layer contains suitable geometry
|
||||
// (we must feed all the G-code into the post-processor, including the first
|
||||
|
@ -353,6 +353,12 @@ Point circle_taubin_newton(const Points::const_iterator& input_begin, const Poin
|
||||
return Point::new_scale(center.x(), center.y());
|
||||
}
|
||||
|
||||
Vec2d
|
||||
circle_taubin_newton(const Pointfs& input, size_t cycles)
|
||||
{
|
||||
return circle_taubin_newton(input.cbegin(), input.cend(), cycles);
|
||||
}
|
||||
|
||||
/// Adapted from work in "Circular and Linear Regression: Fitting circles and lines by least squares", pg 126
|
||||
/// Returns a point corresponding to the center of a circle for which all of the points from input_begin to input_end
|
||||
/// lie on.
|
||||
|
@ -1388,9 +1388,9 @@ MedialAxis::simplify_polygon_frontier()
|
||||
{
|
||||
//it will remove every point in the surface contour that aren't on the bounds contour
|
||||
this->expolygon = this->surface;
|
||||
this->expolygon.contour.remove_colinear_points(SCALED_EPSILON);
|
||||
this->expolygon.contour.remove_collinear(SCALED_EPSILON);
|
||||
for (Polygon &hole : this->expolygon.holes)
|
||||
hole.remove_colinear_points(SCALED_EPSILON);
|
||||
hole.remove_collinear(SCALED_EPSILON);
|
||||
if (&this->surface != this->bounds) {
|
||||
bool need_intersect = false;
|
||||
for (size_t i = 0; i < this->expolygon.contour.points.size(); i++) {
|
||||
@ -1419,9 +1419,9 @@ MedialAxis::simplify_polygon_frontier()
|
||||
} else {
|
||||
//can't simplify that much, reuse the given one
|
||||
this->expolygon = this->surface;
|
||||
this->expolygon.contour.remove_colinear_points(SCALED_EPSILON);
|
||||
this->expolygon.contour.remove_collinear(SCALED_EPSILON);
|
||||
for (Polygon &hole : this->expolygon.holes)
|
||||
hole.remove_colinear_points(SCALED_EPSILON);
|
||||
hole.remove_collinear(SCALED_EPSILON);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,8 +1,10 @@
|
||||
#include "PerimeterGenerator.hpp"
|
||||
|
||||
#include "BridgeDetector.hpp"
|
||||
#include "ClipperUtils.hpp"
|
||||
#include "ExtrusionEntityCollection.hpp"
|
||||
#include "BridgeDetector.hpp"
|
||||
#include "Geometry.hpp"
|
||||
#include "ShortestPath.hpp"
|
||||
#include <cmath>
|
||||
#include <cassert>
|
||||
#include <vector>
|
||||
@ -702,14 +704,13 @@ ExtrusionEntityCollection PerimeterGenerator::_traverse_loops(
|
||||
// loops is an arrayref of ::Loop objects
|
||||
// turn each one into an ExtrusionLoop object
|
||||
ExtrusionEntityCollection coll;
|
||||
for (PerimeterGeneratorLoops::const_iterator loop = loops.begin();
|
||||
loop != loops.end(); ++loop) {
|
||||
bool is_external = loop->is_external();
|
||||
for (const PerimeterGeneratorLoop &loop : loops) {
|
||||
bool is_external = loop.is_external();
|
||||
|
||||
ExtrusionRole role;
|
||||
ExtrusionLoopRole loop_role;
|
||||
role = is_external ? erExternalPerimeter : erPerimeter;
|
||||
if (loop->is_internal_contour()) {
|
||||
if (loop.is_internal_contour()) {
|
||||
// Note that we set loop role to ContourInternalPerimeter
|
||||
// also when loop is both internal and external (i.e.
|
||||
// there's only one contour loop).
|
||||
@ -725,7 +726,7 @@ ExtrusionEntityCollection PerimeterGenerator::_traverse_loops(
|
||||
// get non-overhang paths by intersecting this loop with the grown lower slices
|
||||
extrusion_paths_append(
|
||||
paths,
|
||||
intersection_pl(loop->polygon, this->_lower_slices_p),
|
||||
intersection_pl(loop.polygon, this->_lower_slices_p),
|
||||
role,
|
||||
is_external ? this->_ext_mm3_per_mm : this->_mm3_per_mm,
|
||||
is_external ? this->ext_perimeter_flow.width : this->perimeter_flow.width,
|
||||
@ -736,20 +737,18 @@ ExtrusionEntityCollection PerimeterGenerator::_traverse_loops(
|
||||
// the loop centerline and original lower slices is >= half nozzle diameter
|
||||
extrusion_paths_append(
|
||||
paths,
|
||||
diff_pl(loop->polygon, this->_lower_slices_p),
|
||||
diff_pl(loop.polygon, this->_lower_slices_p),
|
||||
erOverhangPerimeter,
|
||||
this->_mm3_per_mm_overhang,
|
||||
this->overhang_flow.width,
|
||||
this->overhang_flow.height);
|
||||
|
||||
// reapply the nearest point search for starting point
|
||||
// We allow polyline reversal because Clipper may have randomly
|
||||
// reversed polylines during clipping.
|
||||
if (!paths.empty())
|
||||
paths = (ExtrusionPaths)ExtrusionEntityCollection(paths).chained_path_from(paths.front().first_point());
|
||||
// We allow polyline reversal because Clipper may have randomly reversed polylines during clipping.
|
||||
chain_and_reorder_extrusion_paths(paths, &paths.front().first_point());
|
||||
} else {
|
||||
ExtrusionPath path(role);
|
||||
path.polyline = loop->polygon.split_at_first_point();
|
||||
path.polyline = loop.polygon.split_at_first_point();
|
||||
path.mm3_per_mm = is_external ? this->_ext_mm3_per_mm : this->_mm3_per_mm;
|
||||
path.width = is_external ? this->ext_perimeter_flow.width : this->perimeter_flow.width;
|
||||
path.height = (float) this->layer_height;
|
||||
@ -761,48 +760,48 @@ ExtrusionEntityCollection PerimeterGenerator::_traverse_loops(
|
||||
|
||||
// append thin walls to the nearest-neighbor search (only for first iteration)
|
||||
if (!thin_walls.empty()) {
|
||||
ExtrusionEntityCollection tw = thin_variable_width
|
||||
(thin_walls, erExternalPerimeter, this->ext_perimeter_flow);
|
||||
|
||||
ExtrusionEntityCollection tw = thin_variable_width(thin_walls, erExternalPerimeter, this->ext_perimeter_flow);
|
||||
coll.append(tw.entities);
|
||||
thin_walls.clear();
|
||||
}
|
||||
|
||||
// sort entities into a new collection using a nearest-neighbor search,
|
||||
// preserving the original indices which are useful for detecting thin walls
|
||||
ExtrusionEntityCollection sorted_coll = coll.chained_path_from(coll.first_point());
|
||||
|
||||
// traverse children and build the final collection
|
||||
Point zero_point(0, 0);
|
||||
//result is [idx, needReverse] ?
|
||||
std::vector<std::pair<size_t, bool>> chain = chain_extrusion_entities(coll.entities, &zero_point);
|
||||
ExtrusionEntityCollection entities;
|
||||
for (std::vector<size_t>::const_iterator idx = sorted_coll.orig_indices.begin();
|
||||
idx != sorted_coll.orig_indices.end();
|
||||
++idx) {
|
||||
for (const std::pair<size_t, bool> &idx : chain) {
|
||||
|
||||
if (*idx >= loops.size()) {
|
||||
if (idx.first >= loops.size()) {
|
||||
// this is a thin wall
|
||||
// let's get it from the sorted collection as it might have been reversed
|
||||
size_t i = idx - sorted_coll.orig_indices.begin();
|
||||
entities.append(*sorted_coll.entities[i]);
|
||||
entities.entities.reserve(entities.entities.size() + 1);
|
||||
entities.entities.emplace_back(coll.entities[idx.first]);
|
||||
coll.entities[idx.first] = nullptr;
|
||||
if (idx.second)
|
||||
entities.entities.back()->reverse();
|
||||
//if thin extrusion is a loop, make it ccw like a normal contour.
|
||||
if (ExtrusionLoop* loop = dynamic_cast<ExtrusionLoop*>(entities.entities.back())) {
|
||||
loop->make_counter_clockwise();
|
||||
}
|
||||
} else {
|
||||
const PerimeterGeneratorLoop &loop = loops[*idx];
|
||||
ExtrusionLoop eloop = *dynamic_cast<ExtrusionLoop*>(coll.entities[*idx]);
|
||||
|
||||
const PerimeterGeneratorLoop &loop = loops[idx.first];
|
||||
assert(thin_walls.empty());
|
||||
ExtrusionEntityCollection children = this->_traverse_loops(loop.children, thin_walls);
|
||||
entities.entities.reserve(entities.entities.size() + children.entities.size() + 1);
|
||||
ExtrusionLoop *eloop = static_cast<ExtrusionLoop*>(coll.entities[idx.first]);
|
||||
coll.entities[idx.first] = nullptr;
|
||||
if (loop.is_contour) {
|
||||
if (loop.is_overhang && this->layer_id % 2 == 1)
|
||||
eloop.make_clockwise();
|
||||
eloop->make_clockwise();
|
||||
else
|
||||
eloop.make_counter_clockwise();
|
||||
entities.append(children.entities);
|
||||
entities.append(eloop);
|
||||
eloop->make_counter_clockwise();
|
||||
entities.append(std::move(children.entities));
|
||||
entities.append(*eloop);
|
||||
} else {
|
||||
eloop.make_clockwise();
|
||||
entities.append(eloop);
|
||||
entities.append(children.entities);
|
||||
eloop->make_clockwise();
|
||||
entities.append(*eloop);
|
||||
entities.append(std::move(children.entities));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -5,6 +5,8 @@
|
||||
|
||||
namespace Slic3r {
|
||||
|
||||
|
||||
|
||||
Lines Polygon::lines() const
|
||||
{
|
||||
return to_lines(*this);
|
||||
@ -261,7 +263,7 @@ BoundingBox get_extents(const Points &points)
|
||||
return BoundingBox(points);
|
||||
}
|
||||
|
||||
size_t Polygon::remove_colinear_points(coord_t max_offset){
|
||||
size_t Polygon::remove_collinear(coord_t max_offset){
|
||||
size_t nb_del = 0;
|
||||
if (points.size() < 3) return 0;
|
||||
|
||||
@ -429,10 +431,14 @@ bool remove_small(Polygons &polys, double min_area)
|
||||
return modified;
|
||||
}
|
||||
|
||||
void remove_collinear(Polygon &poly, coord_t max_offset)
|
||||
{
|
||||
poly.remove_collinear(max_offset);
|
||||
}
|
||||
void remove_collinear(Polygons &polys, coord_t max_offset)
|
||||
{
|
||||
for (Polygon &poly : polys)
|
||||
poly.remove_colinear_points(max_offset);
|
||||
poly.remove_collinear(max_offset);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -67,7 +67,7 @@ public:
|
||||
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);
|
||||
size_t remove_collinear(coord_t max_offset);
|
||||
};
|
||||
|
||||
inline bool operator==(const Polygon &lhs, const Polygon &rhs) { return lhs.points == rhs.points; }
|
||||
@ -94,8 +94,8 @@ extern bool remove_sticks(Polygons &polys);
|
||||
// Remove polygons with less than 3 edges.
|
||||
extern bool remove_degenerate(Polygons &polys);
|
||||
extern bool remove_small(Polygons &polys, double min_area);
|
||||
extern void remove_collinear(Polygon &poly);
|
||||
extern void remove_collinear(Polygons &polys);
|
||||
extern void remove_collinear(Polygon &poly, coord_t max_offset = SCALED_EPSILON);
|
||||
extern void remove_collinear(Polygons &polys, coord_t max_offset = SCALED_EPSILON);
|
||||
|
||||
// Append a vector of polygons at the end of another vector of polygons.
|
||||
inline void polygons_append(Polygons &dst, const Polygons &src) { dst.insert(dst.end(), src.begin(), src.end()); }
|
||||
|
@ -3205,10 +3205,25 @@ void PrintConfigDef::init_extruder_option_keys()
|
||||
{
|
||||
// ConfigOptionFloats, ConfigOptionPercents, ConfigOptionBools, ConfigOptionStrings
|
||||
m_extruder_option_keys = {
|
||||
"nozzle_diameter", "min_layer_height", "max_layer_height", "extruder_offset",
|
||||
"retract_length", "retract_lift", "retract_lift_above", "retract_lift_below", "retract_speed", "deretract_speed",
|
||||
"retract_before_wipe", "retract_restart_extra", "retract_before_travel", "wipe",
|
||||
"retract_layer_change", "retract_length_toolchange", "retract_restart_extra_toolchange", "extruder_colour",
|
||||
"nozzle_diameter",
|
||||
"min_layer_height",
|
||||
"max_layer_height",
|
||||
"extruder_offset",
|
||||
"retract_length",
|
||||
"retract_lift",
|
||||
"retract_lift_above",
|
||||
"retract_lift_below",
|
||||
"retract_lift_not_last_layer",
|
||||
"retract_speed",
|
||||
"deretract_speed",
|
||||
"retract_before_wipe",
|
||||
"retract_restart_extra",
|
||||
"retract_before_travel",
|
||||
"wipe",
|
||||
"retract_layer_change",
|
||||
"retract_length_toolchange",
|
||||
"retract_restart_extra_toolchange",
|
||||
"extruder_colour",
|
||||
"default_filament_profile"
|
||||
};
|
||||
|
||||
|
@ -37,7 +37,7 @@ Contour3D sphere(double rho, Portion portion, double fa) {
|
||||
if(sbegin == 0)
|
||||
vertices.emplace_back(Vec3d(0.0, 0.0, -rho + increment*sbegin*2.0*rho));
|
||||
|
||||
auto id = coord_t(vertices.size());
|
||||
int32_t id = int32_t(vertices.size());
|
||||
for (size_t i = 0; i < ring.size(); i++) {
|
||||
// Fixed scaling
|
||||
const double z = -rho + increment*rho*2.0 * (sbegin + 1.0);
|
||||
@ -48,8 +48,8 @@ Contour3D sphere(double rho, Portion portion, double fa) {
|
||||
|
||||
if (sbegin == 0)
|
||||
facets.emplace_back((i == 0) ?
|
||||
Vec3crd(coord_t(ring.size()), 0, 1) :
|
||||
Vec3crd(id - 1, 0, id));
|
||||
Vec3i32(int32_t(ring.size()), 0, 1) :
|
||||
Vec3i32(id - 1, 0, id));
|
||||
++id;
|
||||
}
|
||||
|
||||
@ -62,15 +62,15 @@ Contour3D sphere(double rho, Portion portion, double fa) {
|
||||
for (size_t i = 0; i < ring.size(); i++) {
|
||||
Vec2d b = Eigen::Rotation2Dd(ring[i]) * Eigen::Vector2d(0, r);
|
||||
vertices.emplace_back(Vec3d(b(0), b(1), z));
|
||||
auto id_ringsize = coord_t(id - int(ring.size()));
|
||||
int32_t id_ringsize = int32_t(id - int(ring.size()));
|
||||
if (i == 0) {
|
||||
// wrap around
|
||||
facets.emplace_back(Vec3crd(id - 1, id,
|
||||
id + coord_t(ring.size() - 1)));
|
||||
facets.emplace_back(Vec3crd(id - 1, id_ringsize, id));
|
||||
facets.emplace_back(Vec3i32(id - 1, id,
|
||||
id + int32_t(ring.size() - 1)));
|
||||
facets.emplace_back(Vec3i32(id - 1, id_ringsize, id));
|
||||
} else {
|
||||
facets.emplace_back(Vec3crd(id_ringsize - 1, id_ringsize, id));
|
||||
facets.emplace_back(Vec3crd(id - 1, id_ringsize - 1, id));
|
||||
facets.emplace_back(Vec3i32(id_ringsize - 1, id_ringsize, id));
|
||||
facets.emplace_back(Vec3i32(id - 1, id_ringsize - 1, id));
|
||||
}
|
||||
id++;
|
||||
}
|
||||
@ -81,13 +81,13 @@ Contour3D sphere(double rho, Portion portion, double fa) {
|
||||
if(send >= size_t(2*PI / angle)) {
|
||||
vertices.emplace_back(Vec3d(0.0, 0.0, -rho + increment*send*2.0*rho));
|
||||
for (size_t i = 0; i < ring.size(); i++) {
|
||||
auto id_ringsize = coord_t(id - int(ring.size()));
|
||||
int32_t id_ringsize = int32_t(id - int(ring.size()));
|
||||
if (i == 0) {
|
||||
// third vertex is on the other side of the ring.
|
||||
facets.emplace_back(Vec3crd(id - 1, id_ringsize, id));
|
||||
facets.emplace_back(Vec3i32(id - 1, id_ringsize, id));
|
||||
} else {
|
||||
auto ci = coord_t(id_ringsize + coord_t(i));
|
||||
facets.emplace_back(Vec3crd(ci - 1, ci, id));
|
||||
int32_t ci = int32_t(id_ringsize + int32_t(i));
|
||||
facets.emplace_back(Vec3i32(ci - 1, ci, id));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -204,21 +204,21 @@ Head::Head(double r_big_mm,
|
||||
mesh.merge(s1);
|
||||
mesh.merge(s2);
|
||||
|
||||
for(size_t idx1 = s1.points.size() - steps, idx2 = s1.points.size();
|
||||
for(int32_t idx1 = s1.points.size() - steps, idx2 = s1.points.size();
|
||||
idx1 < s1.points.size() - 1;
|
||||
idx1++, idx2++)
|
||||
{
|
||||
coord_t i1s1 = coord_t(idx1), i1s2 = coord_t(idx2);
|
||||
coord_t i2s1 = i1s1 + 1, i2s2 = i1s2 + 1;
|
||||
int32_t i1s1 = idx1, i1s2 = idx2;
|
||||
int32_t i2s1 = i1s1 + 1, i2s2 = i1s2 + 1;
|
||||
|
||||
mesh.indices.emplace_back((int32_t)i1s1, (int32_t)i2s1, (int32_t)i2s2);
|
||||
mesh.indices.emplace_back((int32_t)i1s1, (int32_t)i2s2, (int32_t)i1s2);
|
||||
mesh.indices.emplace_back(i1s1, i2s1, i2s2);
|
||||
mesh.indices.emplace_back(i1s1, i2s2, i1s2);
|
||||
}
|
||||
|
||||
auto i1s1 = coord_t(s1.points.size()) - coord_t(steps);
|
||||
auto i2s1 = coord_t(s1.points.size()) - 1;
|
||||
auto i1s2 = coord_t(s1.points.size());
|
||||
auto i2s2 = coord_t(s1.points.size()) + coord_t(steps) - 1;
|
||||
int32_t i1s1 = int32_t(s1.points.size()) - int32_t(steps);
|
||||
int32_t i2s1 = int32_t(s1.points.size()) - 1;
|
||||
int32_t i1s2 = int32_t(s1.points.size());
|
||||
int32_t i2s2 = int32_t(s1.points.size()) + int32_t(steps) - 1;
|
||||
|
||||
mesh.indices.emplace_back(i2s2, i2s1, i1s1);
|
||||
mesh.indices.emplace_back(i1s2, i2s2, i1s1);
|
||||
|
@ -1712,7 +1712,7 @@ void TriangleMeshSlicer::make_expolygons(const Polygons &loops, ExPolygons* slic
|
||||
Polygons filered_polys = loops;
|
||||
if (this->model_precision > 0){
|
||||
for (Polygon &hole : filered_polys){
|
||||
hole.remove_colinear_points(scale_(this->model_precision));
|
||||
hole.remove_collinear(scale_(this->model_precision));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -5552,7 +5552,7 @@ void GLCanvas3D::_load_print_object_toolpaths(const PrintObject& print_object, c
|
||||
bool at_least_one_has_correct_extruder = false;
|
||||
for (const LayerRegion* layerm : layer->regions())
|
||||
{
|
||||
if (layerm->slices.surfaces.empty())
|
||||
if (layerm->slices().surfaces.empty())
|
||||
continue;
|
||||
const PrintRegionConfig& cfg = layerm->region()->config();
|
||||
if (cfg.perimeter_extruder.value == m_selected_extruder ||
|
||||
|
@ -13,6 +13,7 @@
|
||||
#include "Gizmos/GLGizmosManager.hpp"
|
||||
#include "GUI_ObjectLayers.hpp"
|
||||
#include "MeshUtils.hpp"
|
||||
#include "../libslic3r/Slicing.hpp"
|
||||
|
||||
#include <float.h>
|
||||
|
||||
@ -81,7 +82,6 @@ template <size_t N> using Vec2dsEvent = ArrayEvent<Vec2d, N>;
|
||||
using Vec3dEvent = Event<Vec3d>;
|
||||
template <size_t N> using Vec3dsEvent = ArrayEvent<Vec3d, N>;
|
||||
|
||||
using HeightProfileSmoothEvent = Event<HeightProfileSmoothingParams>;
|
||||
|
||||
wxDECLARE_EVENT(EVT_GLCANVAS_INIT, SimpleEvent);
|
||||
wxDECLARE_EVENT(EVT_GLCANVAS_SCHEDULE_BACKGROUND_PROCESS, SimpleEvent);
|
||||
@ -107,6 +107,7 @@ wxDECLARE_EVENT(EVT_GLCANVAS_EDIT_COLOR_CHANGE, wxKeyEvent);
|
||||
wxDECLARE_EVENT(EVT_GLCANVAS_UNDO, SimpleEvent);
|
||||
wxDECLARE_EVENT(EVT_GLCANVAS_REDO, SimpleEvent);
|
||||
#if ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE
|
||||
using HeightProfileSmoothEvent = Event< Slic3r::HeightProfileSmoothingParams>;
|
||||
wxDECLARE_EVENT(EVT_GLCANVAS_RESET_LAYER_HEIGHT_PROFILE, SimpleEvent);
|
||||
wxDECLARE_EVENT(EVT_GLCANVAS_ADAPTIVE_LAYER_HEIGHT_PROFILE, Event<float>);
|
||||
wxDECLARE_EVENT(EVT_GLCANVAS_SMOOTH_LAYER_HEIGHT_PROFILE, HeightProfileSmoothEvent);
|
||||
|
@ -2465,11 +2465,11 @@ void TabPrinter::build_unregular_pages()
|
||||
optgroup = page->new_optgroup(_(L("Retraction")));
|
||||
optgroup->append_single_option_line("retract_length", extruder_idx);
|
||||
optgroup->append_single_option_line("retract_lift", extruder_idx);
|
||||
Line line = { _(L("Only lift Z")), "" };
|
||||
Line line = { _(L("Only lift Z")), "" };
|
||||
line.append_option(optgroup->get_option("retract_lift_above", extruder_idx));
|
||||
line.append_option(optgroup->get_option("retract_lift_below", extruder_idx));
|
||||
line.append_option(optgroup->get_option("retract_lift_not_last_layer", extruder_idx));
|
||||
optgroup->append_line(line);
|
||||
optgroup->append_line(line);
|
||||
|
||||
optgroup->append_single_option_line("retract_speed", extruder_idx);
|
||||
optgroup->append_single_option_line("deretract_speed", extruder_idx);
|
||||
|
@ -87,12 +87,12 @@ SCENARIO("ExtrusionEntityCollection: Polygon flattening") {
|
||||
}
|
||||
|
||||
SCENARIO("ExtrusionEntityCollection: no sort") {
|
||||
DynamicPrintConfig *config = Slic3r::DynamicPrintConfig::new_from_defaults();
|
||||
config->set_key_value("gcode_comments", new ConfigOptionBool(true));
|
||||
config->set_deserialize("skirts", "0");
|
||||
DynamicPrintConfig &config = Slic3r::DynamicPrintConfig::full_print_config();
|
||||
config.set_key_value("gcode_comments", new ConfigOptionBool(true));
|
||||
config.set_deserialize("skirts", "0");
|
||||
Model model{};
|
||||
Print print{};
|
||||
Slic3r::Test::init_print(print, { Slic3r::Test::TestMesh::cube_20x20x20}, model, config);
|
||||
Slic3r::Test::init_print(print, { Slic3r::Test::TestMesh::cube_20x20x20}, model, &config);
|
||||
|
||||
std::map<double, bool> layers_with_skirt;
|
||||
std::map<double, bool> layers_with_brim;
|
||||
@ -127,7 +127,7 @@ SCENARIO("ExtrusionEntityCollection: no sort") {
|
||||
Slic3r::Test::gcode(gcode_filepath, print);
|
||||
auto parser{ Slic3r::GCodeReader() };
|
||||
std::vector<float> extrude_x;
|
||||
parser.parse_file(gcode_filepath, [&extrude_x, &config](Slic3r::GCodeReader& self, const Slic3r::GCodeReader::GCodeLine& line)
|
||||
parser.parse_file(gcode_filepath, [&extrude_x](Slic3r::GCodeReader& self, const Slic3r::GCodeReader::GCodeLine& line)
|
||||
{
|
||||
if (line.comment() == " infill" || line.comment() == " perimeter" || line.comment() == " move to first infill point") {
|
||||
extrude_x.push_back(line.x());
|
||||
@ -148,7 +148,7 @@ SCENARIO("ExtrusionEntityCollection: no sort") {
|
||||
Slic3r::Test::gcode(gcode_filepath, print);
|
||||
auto parser{ Slic3r::GCodeReader() };
|
||||
std::vector<float> extrude_x;
|
||||
parser.parse_file(gcode_filepath, [&extrude_x, &config](Slic3r::GCodeReader& self, const Slic3r::GCodeReader::GCodeLine& line)
|
||||
parser.parse_file(gcode_filepath, [&extrude_x](Slic3r::GCodeReader& self, const Slic3r::GCodeReader::GCodeLine& line)
|
||||
{
|
||||
if (line.comment() == " infill" || line.comment() == " perimeter" || line.comment() == " move to first infill point") {
|
||||
extrude_x.push_back(line.x());
|
||||
|
@ -192,7 +192,7 @@ SCENARIO("Circle Fit, TaubinFit with Newton's method") {
|
||||
}
|
||||
GIVEN("A vector of Pointfs arranged in a half-circle with approximately the same distance R from some point") {
|
||||
Vec2d expected_center(-3, 9);
|
||||
Pointfs sample {Vec2d{6.0, 0}, Vec2d{5.1961524, 3}, Vec2d{3 ,5.1961524},
|
||||
Pointfs sample {Vec2d{6.0, 0}, Vec2d{5.1961524, 3}, Vec2d{3 ,5.1961524},
|
||||
Vec2d{0, 6.0},
|
||||
Vec2d{3, 5.1961524}, Vec2d{-5.1961524, 3}, Vec2d{-6.0, 0}};
|
||||
|
||||
@ -254,18 +254,18 @@ SCENARIO("Circle Fit, TaubinFit with Newton's method") {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
TEST_CASE("Chained path working correctly"){
|
||||
// if chained_path() works correctly, these points should be joined with no diagonal paths
|
||||
// (thus 26 units long)
|
||||
std::vector<Point> points = {Point{26,26},Point{52,26},Point{0,26},Point{26,52},Point{26,0},Point{0,52},Point{52,52},Point{52,0}};
|
||||
std::vector<Points::size_type> indices;
|
||||
Geometry::chained_path(points,indices);
|
||||
for(Points::size_type i = 0; i < indices.size()-1;i++){
|
||||
double dist = points.at(indices.at(i)).distance_to(points.at(indices.at(i+1)));
|
||||
REQUIRE(abs(dist-26) <= EPSILON);
|
||||
}
|
||||
}
|
||||
// A PU
|
||||
//TEST_CASE("Chained path working correctly"){
|
||||
// // if chained_path() works correctly, these points should be joined with no diagonal paths
|
||||
// // (thus 26 units long)
|
||||
// std::vector<Point> points = {Point{26,26},Point{52,26},Point{0,26},Point{26,52},Point{26,0},Point{0,52},Point{52,52},Point{52,0}};
|
||||
// std::vector<Points::size_type> indices;
|
||||
// Geometry::chained_path(points,indices);
|
||||
// for(Points::size_type i = 0; i < indices.size()-1;i++){
|
||||
// double dist = points.at(indices.at(i)).distance_to(points.at(indices.at(i+1)));
|
||||
// REQUIRE(abs(dist-26) <= EPSILON);
|
||||
// }
|
||||
//}
|
||||
|
||||
SCENARIO("Line distances"){
|
||||
GIVEN("A line"){
|
||||
|
@ -15,9 +15,9 @@ SCENARIO("Model construction") {
|
||||
TriangleMesh sample_mesh = make_cube(20,20,20);
|
||||
sample_mesh.repair();
|
||||
|
||||
DynamicPrintConfig *config = Slic3r::DynamicPrintConfig::new_from_defaults();
|
||||
DynamicPrintConfig &config = Slic3r::DynamicPrintConfig::full_print_config();
|
||||
Slic3r::Print print{};
|
||||
print.apply(model, *config);
|
||||
print.apply(model, config);
|
||||
//Slic3r::Test::init_print(print, { sample_mesh }, model, config);
|
||||
|
||||
WHEN("Model object is added") {
|
||||
@ -45,7 +45,7 @@ SCENARIO("Model construction") {
|
||||
model.center_instances_around_point(Slic3r::Vec2d(100,100));
|
||||
print.auto_assign_extruders(mo);
|
||||
//print.add_model_object(mo);
|
||||
print.apply(model, *config);
|
||||
print.apply(model, config);
|
||||
print.validate();
|
||||
THEN("Print works?") {
|
||||
std::string gcode_filepath{ "" };
|
||||
|
@ -265,8 +265,8 @@ TriangleMesh mesh(TestMesh m) {
|
||||
|
||||
|
||||
void init_print(Print& print, std::initializer_list<TestMesh> meshes, Slic3r::Model& model, DynamicPrintConfig* _config, bool comments) {
|
||||
DynamicPrintConfig* config {Slic3r::DynamicPrintConfig::new_from_defaults()};
|
||||
config->apply(*_config);
|
||||
DynamicPrintConfig &config = Slic3r::DynamicPrintConfig::full_print_config();
|
||||
config.apply(*_config);
|
||||
|
||||
//const std::string v {std::getenv("SLIC3R_TESTS_GCODE")};
|
||||
//auto tests_gcode {(v == "" ? ""s : std::string(v))};
|
||||
@ -291,15 +291,15 @@ void init_print(Print& print, std::initializer_list<TestMesh> meshes, Slic3r::Mo
|
||||
print.auto_assign_extruders(mo);
|
||||
//print.add_model_object(mo);
|
||||
}
|
||||
print.apply(model, *config);
|
||||
print.apply(model, config);
|
||||
|
||||
std::string err = print.validate();
|
||||
//std::cout << "validate result : " << err << ", mempty print? " << print.empty() << "\n";
|
||||
|
||||
}
|
||||
void init_print(Print& print, std::initializer_list<TriangleMesh> meshes, Slic3r::Model& model, DynamicPrintConfig* _config, bool comments) {
|
||||
DynamicPrintConfig* config {Slic3r::DynamicPrintConfig::new_from_defaults()};
|
||||
config->apply(*_config);
|
||||
DynamicPrintConfig &config = Slic3r::DynamicPrintConfig::full_print_config();
|
||||
config.apply(*_config);
|
||||
|
||||
//const std::string v {std::getenv("SLIC3R_TESTS_GCODE")};
|
||||
//std::string tests_gcode {(v == "" ? "" : v)};
|
||||
@ -319,7 +319,7 @@ void init_print(Print& print, std::initializer_list<TriangleMesh> meshes, Slic3r
|
||||
|
||||
model.arrange_objects(print.config().min_object_distance());
|
||||
model.center_instances_around_point(Slic3r::Vec2d(100,100));
|
||||
print.apply(model, *config);
|
||||
print.apply(model, config);
|
||||
for (ModelObject* mo : model.objects) {
|
||||
print.auto_assign_extruders(mo);
|
||||
}
|
||||
|
File diff suppressed because one or more lines are too long
@ -30,13 +30,13 @@ TEST_CASE("Fill: Pattern Path Length", "[Fill]") {
|
||||
std::unique_ptr<Slic3r::Fill> filler(Slic3r::Fill::new_from_type("rectilinear"));
|
||||
filler->angle = float(-(PI)/2.0);
|
||||
FillParams fill_params;
|
||||
filler->spacing = 5;
|
||||
fill_params.dont_adjust = true;
|
||||
//fill_params.endpoints_overlap = false;
|
||||
fill_params.density = float(filler->spacing / 50.0);
|
||||
fill_params.density = float(5 / 50.0);
|
||||
filler->init_spacing(5, fill_params);
|
||||
|
||||
auto test = [&filler, &fill_params] (const ExPolygon& poly) -> Slic3r::Polylines {
|
||||
Slic3r::Surface surface(stTop, poly);
|
||||
Slic3r::Surface surface(SurfaceType::stPosTop | SurfaceType::stDensSolid, poly);
|
||||
return filler->fill_surface(&surface, fill_params);
|
||||
};
|
||||
|
||||
@ -80,7 +80,7 @@ TEST_CASE("Fill: Pattern Path Length", "[Fill]") {
|
||||
|
||||
for (double angle : {-(PI/2.0), -(PI/4.0), -(PI), PI/2.0, PI}) {
|
||||
for (double spacing : {25.0, 5.0, 7.5, 8.5}) {
|
||||
fill_params.density = float(filler->spacing / spacing);
|
||||
fill_params.density = float(filler->get_spacing() / spacing);
|
||||
filler->angle = float(angle);
|
||||
ExPolygon e(test_square, test_hole);
|
||||
Slic3r::Polylines paths = test(e);
|
||||
@ -102,11 +102,11 @@ TEST_CASE("Fill: Pattern Path Length", "[Fill]") {
|
||||
SECTION("Regression: Missing infill segments in some rare circumstances") {
|
||||
filler->angle = float(PI/4.0);
|
||||
fill_params.dont_adjust = false;
|
||||
filler->spacing = 0.654498;
|
||||
//filler->endpoints_overlap = unscale(359974);
|
||||
fill_params.density = 1;
|
||||
filler->layer_id = 66;
|
||||
filler->z = 20.15;
|
||||
filler->init_spacing(0.654498, fill_params);
|
||||
|
||||
Slic3r::Points points {Point(25771516,14142125),Point(14142138,25771515),Point(2512749,14142131),Point(14142125,2512749)};
|
||||
Slic3r::Polylines paths = test(Slic3r::ExPolygon(points));
|
||||
@ -125,12 +125,12 @@ TEST_CASE("Fill: Pattern Path Length", "[Fill]") {
|
||||
filler->bounding_box = get_extents(expolygon.contour);
|
||||
filler->angle = 0;
|
||||
|
||||
Surface surface(stTop, expolygon);
|
||||
Surface surface(SurfaceType::stPosTop | SurfaceType::stDensSolid, expolygon);
|
||||
auto flow = Slic3r::Flow(0.69, 0.4, 0.50);
|
||||
|
||||
FillParams fill_params;
|
||||
fill_params.density = 1.0;
|
||||
filler->spacing = flow.spacing();
|
||||
filler->init_spacing(flow.spacing(), fill_params);
|
||||
|
||||
for (auto angle : { 0.0, 45.0}) {
|
||||
surface.expolygon.rotate(angle, Point(0,0));
|
||||
@ -436,13 +436,13 @@ bool test_if_solid_surface_filled(const ExPolygon& expolygon, double flow_spacin
|
||||
filler->angle = float(angle);
|
||||
|
||||
Flow flow(flow_spacing, 0.4, flow_spacing);
|
||||
filler->spacing = flow.spacing();
|
||||
|
||||
FillParams fill_params;
|
||||
fill_params.density = float(density);
|
||||
fill_params.dont_adjust = false;
|
||||
filler->init_spacing(flow.spacing(), fill_params);
|
||||
|
||||
Surface surface(stBottom, expolygon);
|
||||
Surface surface(SurfaceType::stDensSolid | SurfaceType::stPosBottom, expolygon);
|
||||
Slic3r::Polylines paths = filler->fill_surface(&surface, fill_params);
|
||||
|
||||
// check whether any part was left uncovered
|
||||
@ -450,7 +450,7 @@ bool test_if_solid_surface_filled(const ExPolygon& expolygon, double flow_spacin
|
||||
grown_paths.reserve(paths.size());
|
||||
|
||||
// figure out what is actually going on here re: data types
|
||||
float line_offset = float(scale_(filler->spacing / 2.0 + EPSILON));
|
||||
float line_offset = float(scale_(flow.spacing() / 2.0 + EPSILON));
|
||||
std::for_each(paths.begin(), paths.end(), [line_offset, &grown_paths] (const Slic3r::Polyline& p) {
|
||||
polygons_append(grown_paths, offset(p, line_offset));
|
||||
});
|
||||
|
@ -167,8 +167,8 @@ SCENARIO("Flow: Flow math for bridges", "[Flow]") {
|
||||
THEN("Bridge width is same as nozzle diameter") {
|
||||
REQUIRE(flow.width == Approx(nozzle_diameter));
|
||||
}
|
||||
THEN("Bridge spacing is same as nozzle diameter + BRIDGE_EXTRA_SPACING") {
|
||||
REQUIRE(flow.spacing() == Approx(nozzle_diameter + BRIDGE_EXTRA_SPACING));
|
||||
THEN("Bridge spacing is same as nozzle diameter + BRIDGE_EXTRA_SPACING_MULT * nozzle_diameter") {
|
||||
REQUIRE(flow.spacing() == Approx(nozzle_diameter + BRIDGE_EXTRA_SPACING_MULT * nozzle_diameter));
|
||||
}
|
||||
}
|
||||
WHEN("Flow role is frInfill") {
|
||||
@ -176,8 +176,8 @@ SCENARIO("Flow: Flow math for bridges", "[Flow]") {
|
||||
THEN("Bridge width is same as nozzle diameter") {
|
||||
REQUIRE(flow.width == Approx(nozzle_diameter));
|
||||
}
|
||||
THEN("Bridge spacing is same as nozzle diameter + BRIDGE_EXTRA_SPACING") {
|
||||
REQUIRE(flow.spacing() == Approx(nozzle_diameter + BRIDGE_EXTRA_SPACING));
|
||||
THEN("Bridge spacing is same as nozzle diameter + BRIDGE_EXTRA_SPACING_MULT * nozzle_diameter") {
|
||||
REQUIRE(flow.spacing() == Approx(nozzle_diameter + BRIDGE_EXTRA_SPACING_MULT * nozzle_diameter));
|
||||
}
|
||||
}
|
||||
WHEN("Flow role is frPerimeter") {
|
||||
@ -185,8 +185,8 @@ SCENARIO("Flow: Flow math for bridges", "[Flow]") {
|
||||
THEN("Bridge width is same as nozzle diameter") {
|
||||
REQUIRE(flow.width == Approx(nozzle_diameter));
|
||||
}
|
||||
THEN("Bridge spacing is same as nozzle diameter + BRIDGE_EXTRA_SPACING") {
|
||||
REQUIRE(flow.spacing() == Approx(nozzle_diameter + BRIDGE_EXTRA_SPACING));
|
||||
THEN("Bridge spacing is same as nozzle diameter + BRIDGE_EXTRA_SPACING_MULT * nozzle_diameter") {
|
||||
REQUIRE(flow.spacing() == Approx(nozzle_diameter + BRIDGE_EXTRA_SPACING_MULT * nozzle_diameter));
|
||||
}
|
||||
}
|
||||
WHEN("Flow role is frSupportMaterial") {
|
||||
@ -194,8 +194,8 @@ SCENARIO("Flow: Flow math for bridges", "[Flow]") {
|
||||
THEN("Bridge width is same as nozzle diameter") {
|
||||
REQUIRE(flow.width == Approx(nozzle_diameter));
|
||||
}
|
||||
THEN("Bridge spacing is same as nozzle diameter + BRIDGE_EXTRA_SPACING") {
|
||||
REQUIRE(flow.spacing() == Approx(nozzle_diameter + BRIDGE_EXTRA_SPACING));
|
||||
THEN("Bridge spacing is same as nozzle diameter + BRIDGE_EXTRA_SPACING_MULT * nozzle_diameter") {
|
||||
REQUIRE(flow.spacing() == Approx(nozzle_diameter + BRIDGE_EXTRA_SPACING_MULT * nozzle_diameter));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -66,7 +66,7 @@ SCENARIO("Print: Changing number of solid surfaces does not cause all surfaces t
|
||||
for (const LayerRegion *region : layer.regions()) {
|
||||
// for each region, iterate over the fill surfaces
|
||||
for (const Surface &surface : region->fill_surfaces.surfaces)
|
||||
CHECK(surface.is_solid());
|
||||
CHECK(surface.has_fill_solid());
|
||||
}
|
||||
};
|
||||
print.process();
|
||||
|
@ -19,7 +19,7 @@ using namespace std;
|
||||
SCENARIO( "TriangleMesh: Basic mesh statistics") {
|
||||
GIVEN( "A 20mm cube, built from constexpr std::array" ) {
|
||||
std::vector<Vec3d> vertices { Vec3d(20,20,0), Vec3d(20,0,0), Vec3d(0,0,0), Vec3d(0,20,0), Vec3d(20,20,20), Vec3d(0,20,20), Vec3d(0,0,20), Vec3d(20,0,20) };
|
||||
std::vector<Vec3crd> facets { Vec3crd(0,1,2), Vec3crd(0,2,3), Vec3crd(4,5,6), Vec3crd(4,6,7), Vec3crd(0,4,7), Vec3crd(0,7,1), Vec3crd(1,7,6), Vec3crd(1,6,2), Vec3crd(2,6,5), Vec3crd(2,5,3), Vec3crd(4,0,3), Vec3crd(4,3,5) };
|
||||
std::vector<Vec3i32> facets { Vec3i32(0,1,2), Vec3i32(0,2,3), Vec3i32(4,5,6), Vec3i32(4,6,7), Vec3i32(0,4,7), Vec3i32(0,7,1), Vec3i32(1,7,6), Vec3i32(1,6,2), Vec3i32(2,6,5), Vec3i32(2,5,3), Vec3i32(4,0,3), Vec3i32(4,3,5) };
|
||||
TriangleMesh cube(vertices, facets);
|
||||
cube.repair();
|
||||
|
||||
@ -69,7 +69,7 @@ SCENARIO( "TriangleMesh: Basic mesh statistics") {
|
||||
}
|
||||
GIVEN( "A 20mm cube with one corner on the origin") {
|
||||
const std::vector<Vec3d> vertices { Vec3d(20,20,0), Vec3d(20,0,0), Vec3d(0,0,0), Vec3d(0,20,0), Vec3d(20,20,20), Vec3d(0,20,20), Vec3d(0,0,20), Vec3d(20,0,20) };
|
||||
const std::vector<Vec3crd> facets { Vec3crd(0,1,2), Vec3crd(0,2,3), Vec3crd(4,5,6), Vec3crd(4,6,7), Vec3crd(0,4,7), Vec3crd(0,7,1), Vec3crd(1,7,6), Vec3crd(1,6,2), Vec3crd(2,6,5), Vec3crd(2,5,3), Vec3crd(4,0,3), Vec3crd(4,3,5) };
|
||||
const std::vector<Vec3i32> facets { Vec3i32(0,1,2), Vec3i32(0,2,3), Vec3i32(4,5,6), Vec3i32(4,6,7), Vec3i32(0,4,7), Vec3i32(0,7,1), Vec3i32(1,7,6), Vec3i32(1,6,2), Vec3i32(2,6,5), Vec3i32(2,5,3), Vec3i32(4,0,3), Vec3i32(4,3,5) };
|
||||
|
||||
TriangleMesh cube(vertices, facets);
|
||||
cube.repair();
|
||||
@ -122,7 +122,7 @@ SCENARIO( "TriangleMesh: Basic mesh statistics") {
|
||||
SCENARIO( "TriangleMesh: Transformation functions affect mesh as expected.") {
|
||||
GIVEN( "A 20mm cube with one corner on the origin") {
|
||||
const std::vector<Vec3d> vertices { Vec3d(20,20,0), Vec3d(20,0,0), Vec3d(0,0,0), Vec3d(0,20,0), Vec3d(20,20,20), Vec3d(0,20,20), Vec3d(0,0,20), Vec3d(20,0,20) };
|
||||
const std::vector<Vec3crd> facets { Vec3crd(0,1,2), Vec3crd(0,2,3), Vec3crd(4,5,6), Vec3crd(4,6,7), Vec3crd(0,4,7), Vec3crd(0,7,1), Vec3crd(1,7,6), Vec3crd(1,6,2), Vec3crd(2,6,5), Vec3crd(2,5,3), Vec3crd(4,0,3), Vec3crd(4,3,5) };
|
||||
const std::vector<Vec3i32> facets { Vec3i32(0,1,2), Vec3i32(0,2,3), Vec3i32(4,5,6), Vec3i32(4,6,7), Vec3i32(0,4,7), Vec3i32(0,7,1), Vec3i32(1,7,6), Vec3i32(1,6,2), Vec3i32(2,6,5), Vec3i32(2,5,3), Vec3i32(4,0,3), Vec3i32(4,3,5) };
|
||||
TriangleMesh cube(vertices, facets);
|
||||
cube.repair();
|
||||
|
||||
@ -185,7 +185,7 @@ SCENARIO( "TriangleMesh: Transformation functions affect mesh as expected.") {
|
||||
SCENARIO( "TriangleMesh: slice behavior.") {
|
||||
GIVEN( "A 20mm cube with one corner on the origin") {
|
||||
const std::vector<Vec3d> vertices { Vec3d(20,20,0), Vec3d(20,0,0), Vec3d(0,0,0), Vec3d(0,20,0), Vec3d(20,20,20), Vec3d(0,20,20), Vec3d(0,0,20), Vec3d(20,0,20) };
|
||||
const std::vector<Vec3crd> facets { Vec3crd(0,1,2), Vec3crd(0,2,3), Vec3crd(4,5,6), Vec3crd(4,6,7), Vec3crd(0,4,7), Vec3crd(0,7,1), Vec3crd(1,7,6), Vec3crd(1,6,2), Vec3crd(2,6,5), Vec3crd(2,5,3), Vec3crd(4,0,3), Vec3crd(4,3,5) };
|
||||
const std::vector<Vec3i32> facets { Vec3i32(0,1,2), Vec3i32(0,2,3), Vec3i32(4,5,6), Vec3i32(4,6,7), Vec3i32(0,4,7), Vec3i32(0,7,1), Vec3i32(1,7,6), Vec3i32(1,6,2), Vec3i32(2,6,5), Vec3i32(2,5,3), Vec3i32(4,0,3), Vec3i32(4,3,5) };
|
||||
TriangleMesh cube(vertices, facets);
|
||||
cube.repair();
|
||||
|
||||
@ -206,7 +206,7 @@ SCENARIO( "TriangleMesh: slice behavior.") {
|
||||
}
|
||||
GIVEN( "A STL with an irregular shape.") {
|
||||
const std::vector<Vec3d> vertices {Vec3d(0,0,0),Vec3d(0,0,20),Vec3d(0,5,0),Vec3d(0,5,20),Vec3d(50,0,0),Vec3d(50,0,20),Vec3d(15,5,0),Vec3d(35,5,0),Vec3d(15,20,0),Vec3d(50,5,0),Vec3d(35,20,0),Vec3d(15,5,10),Vec3d(50,5,20),Vec3d(35,5,10),Vec3d(35,20,10),Vec3d(15,20,10)};
|
||||
const std::vector<Vec3crd> facets {Vec3crd(0,1,2),Vec3crd(2,1,3),Vec3crd(1,0,4),Vec3crd(5,1,4),Vec3crd(0,2,4),Vec3crd(4,2,6),Vec3crd(7,6,8),Vec3crd(4,6,7),Vec3crd(9,4,7),Vec3crd(7,8,10),Vec3crd(2,3,6),Vec3crd(11,3,12),Vec3crd(7,12,9),Vec3crd(13,12,7),Vec3crd(6,3,11),Vec3crd(11,12,13),Vec3crd(3,1,5),Vec3crd(12,3,5),Vec3crd(5,4,9),Vec3crd(12,5,9),Vec3crd(13,7,10),Vec3crd(14,13,10),Vec3crd(8,15,10),Vec3crd(10,15,14),Vec3crd(6,11,8),Vec3crd(8,11,15),Vec3crd(15,11,13),Vec3crd(14,15,13)};
|
||||
const std::vector<Vec3i32> facets {Vec3i32(0,1,2),Vec3i32(2,1,3),Vec3i32(1,0,4),Vec3i32(5,1,4),Vec3i32(0,2,4),Vec3i32(4,2,6),Vec3i32(7,6,8),Vec3i32(4,6,7),Vec3i32(9,4,7),Vec3i32(7,8,10),Vec3i32(2,3,6),Vec3i32(11,3,12),Vec3i32(7,12,9),Vec3i32(13,12,7),Vec3i32(6,3,11),Vec3i32(11,12,13),Vec3i32(3,1,5),Vec3i32(12,3,5),Vec3i32(5,4,9),Vec3i32(12,5,9),Vec3i32(13,7,10),Vec3i32(14,13,10),Vec3i32(8,15,10),Vec3i32(10,15,14),Vec3i32(6,11,8),Vec3i32(8,11,15),Vec3i32(15,11,13),Vec3i32(14,15,13)};
|
||||
|
||||
TriangleMesh cube(vertices, facets);
|
||||
cube.repair();
|
||||
@ -296,7 +296,7 @@ SCENARIO( "make_xxx functions produce meshes.") {
|
||||
SCENARIO( "TriangleMesh: split functionality.") {
|
||||
GIVEN( "A 20mm cube with one corner on the origin") {
|
||||
const std::vector<Vec3d> vertices { Vec3d(20,20,0), Vec3d(20,0,0), Vec3d(0,0,0), Vec3d(0,20,0), Vec3d(20,20,20), Vec3d(0,20,20), Vec3d(0,0,20), Vec3d(20,0,20) };
|
||||
const std::vector<Vec3crd> facets { Vec3crd(0,1,2), Vec3crd(0,2,3), Vec3crd(4,5,6), Vec3crd(4,6,7), Vec3crd(0,4,7), Vec3crd(0,7,1), Vec3crd(1,7,6), Vec3crd(1,6,2), Vec3crd(2,6,5), Vec3crd(2,5,3), Vec3crd(4,0,3), Vec3crd(4,3,5) };
|
||||
const std::vector<Vec3i32> facets { Vec3i32(0,1,2), Vec3i32(0,2,3), Vec3i32(4,5,6), Vec3i32(4,6,7), Vec3i32(0,4,7), Vec3i32(0,7,1), Vec3i32(1,7,6), Vec3i32(1,6,2), Vec3i32(2,6,5), Vec3i32(2,5,3), Vec3i32(4,0,3), Vec3i32(4,3,5) };
|
||||
|
||||
TriangleMesh cube(vertices, facets);
|
||||
cube.repair();
|
||||
@ -310,7 +310,7 @@ SCENARIO( "TriangleMesh: split functionality.") {
|
||||
}
|
||||
GIVEN( "Two 20mm cubes, each with one corner on the origin, merged into a single TriangleMesh") {
|
||||
const std::vector<Vec3d> vertices { Vec3d(20,20,0), Vec3d(20,0,0), Vec3d(0,0,0), Vec3d(0,20,0), Vec3d(20,20,20), Vec3d(0,20,20), Vec3d(0,0,20), Vec3d(20,0,20) };
|
||||
const std::vector<Vec3crd> facets { Vec3crd(0,1,2), Vec3crd(0,2,3), Vec3crd(4,5,6), Vec3crd(4,6,7), Vec3crd(0,4,7), Vec3crd(0,7,1), Vec3crd(1,7,6), Vec3crd(1,6,2), Vec3crd(2,6,5), Vec3crd(2,5,3), Vec3crd(4,0,3), Vec3crd(4,3,5) };
|
||||
const std::vector<Vec3i32> facets { Vec3i32(0,1,2), Vec3i32(0,2,3), Vec3i32(4,5,6), Vec3i32(4,6,7), Vec3i32(0,4,7), Vec3i32(0,7,1), Vec3i32(1,7,6), Vec3i32(1,6,2), Vec3i32(2,6,5), Vec3i32(2,5,3), Vec3i32(4,0,3), Vec3i32(4,3,5) };
|
||||
|
||||
TriangleMesh cube(vertices, facets);
|
||||
cube.repair();
|
||||
@ -331,7 +331,7 @@ SCENARIO( "TriangleMesh: split functionality.") {
|
||||
SCENARIO( "TriangleMesh: Mesh merge functions") {
|
||||
GIVEN( "Two 20mm cubes, each with one corner on the origin") {
|
||||
const std::vector<Vec3d> vertices { Vec3d(20,20,0), Vec3d(20,0,0), Vec3d(0,0,0), Vec3d(0,20,0), Vec3d(20,20,20), Vec3d(0,20,20), Vec3d(0,0,20), Vec3d(20,0,20) };
|
||||
const std::vector<Vec3crd> facets { Vec3crd(0,1,2), Vec3crd(0,2,3), Vec3crd(4,5,6), Vec3crd(4,6,7), Vec3crd(0,4,7), Vec3crd(0,7,1), Vec3crd(1,7,6), Vec3crd(1,6,2), Vec3crd(2,6,5), Vec3crd(2,5,3), Vec3crd(4,0,3), Vec3crd(4,3,5) };
|
||||
const std::vector<Vec3i32> facets { Vec3i32(0,1,2), Vec3i32(0,2,3), Vec3i32(4,5,6), Vec3i32(4,6,7), Vec3i32(0,4,7), Vec3i32(0,7,1), Vec3i32(1,7,6), Vec3i32(1,6,2), Vec3i32(2,6,5), Vec3i32(2,5,3), Vec3i32(4,0,3), Vec3i32(4,3,5) };
|
||||
|
||||
TriangleMesh cube(vertices, facets);
|
||||
cube.repair();
|
||||
@ -351,7 +351,7 @@ SCENARIO( "TriangleMesh: Mesh merge functions") {
|
||||
SCENARIO( "TriangleMeshSlicer: Cut behavior.") {
|
||||
GIVEN( "A 20mm cube with one corner on the origin") {
|
||||
const std::vector<Vec3d> vertices { Vec3d(20,20,0), Vec3d(20,0,0), Vec3d(0,0,0), Vec3d(0,20,0), Vec3d(20,20,20), Vec3d(0,20,20), Vec3d(0,0,20), Vec3d(20,0,20) };
|
||||
const std::vector<Vec3crd> facets { Vec3crd(0,1,2), Vec3crd(0,2,3), Vec3crd(4,5,6), Vec3crd(4,6,7), Vec3crd(0,4,7), Vec3crd(0,7,1), Vec3crd(1,7,6), Vec3crd(1,6,2), Vec3crd(2,6,5), Vec3crd(2,5,3), Vec3crd(4,0,3), Vec3crd(4,3,5) };
|
||||
const std::vector<Vec3i32> facets { Vec3i32(0,1,2), Vec3i32(0,2,3), Vec3i32(4,5,6), Vec3i32(4,6,7), Vec3i32(0,4,7), Vec3i32(0,7,1), Vec3i32(1,7,6), Vec3i32(1,6,2), Vec3i32(2,6,5), Vec3i32(2,5,3), Vec3i32(4,0,3), Vec3i32(4,3,5) };
|
||||
|
||||
TriangleMesh cube(vertices, facets);
|
||||
cube.repair();
|
||||
|
@ -12,7 +12,7 @@ using namespace Slic3r;
|
||||
// #define TESTS_EXPORT_SVGS
|
||||
|
||||
SCENARIO("Constant offset", "[ClipperUtils]") {
|
||||
coord_t s = 1000000;
|
||||
int32_t s = 1000000;
|
||||
GIVEN("20mm box") {
|
||||
ExPolygon box20mm;
|
||||
box20mm.contour.points = { { 0, 0 }, { 20 * s, 0 }, { 20 * s, 20 * s}, { 0, 20 * s} };
|
||||
|
@ -505,12 +505,12 @@ SCENARIO("Elephant foot compensation", "[ElephantFoot]") {
|
||||
GIVEN("Rectangle with a narrow part sticking out") {
|
||||
// Rectangle
|
||||
ExPolygon expoly;
|
||||
coord_t scaled_w = coord_t(scale_(10));
|
||||
int32_t scaled_w = int32_t(scale_(10)); //should be coord_t but it's eaisier to create that way
|
||||
expoly.contour.points = { { 0, 0 }, { 0, scaled_w, }, { scaled_w, scaled_w }, { scaled_w, 0 } };
|
||||
// Narrow part
|
||||
ExPolygon expoly2;
|
||||
coord_t scaled_h = coord_t(scale_(0.8));
|
||||
expoly2.contour.points = { { scaled_w - coord_t(SCALED_EPSILON), scaled_w / 2 }, { scaled_w - coord_t(SCALED_EPSILON), scaled_w / 2 + scaled_h, },
|
||||
int32_t scaled_h = int32_t(scale_(0.8));
|
||||
expoly2.contour.points = { { scaled_w - int32_t(SCALED_EPSILON), scaled_w / 2 }, { scaled_w - int32_t(SCALED_EPSILON), scaled_w / 2 + scaled_h, },
|
||||
{ 2 * scaled_w, scaled_w / 2 + scaled_h }, { 2 * scaled_w, scaled_w / 2 } };
|
||||
// Rectangle with the narrow part.
|
||||
expoly = union_ex({ expoly, expoly2 }).front();
|
||||
|
@ -163,7 +163,7 @@ TEST_CASE("Offseting a line generates a polygon correctly", "[Geometry]"){
|
||||
SCENARIO("Circle Fit, TaubinFit with Newton's method", "[Geometry]") {
|
||||
GIVEN("A vector of Vec2ds arranged in a half-circle with approximately the same distance R from some point") {
|
||||
Vec2d expected_center(-6, 0);
|
||||
Vec2ds sample {Vec2d(6.0, 0), Vec2d(5.1961524, 3), Vec2d(3 ,5.1961524), Vec2d(0, 6.0), Vec2d(3, 5.1961524), Vec2d(-5.1961524, 3), Vec2d(-6.0, 0)};
|
||||
Pointfs sample {Vec2d(6.0, 0), Vec2d(5.1961524, 3), Vec2d(3 ,5.1961524), Vec2d(0, 6.0), Vec2d(3, 5.1961524), Vec2d(-5.1961524, 3), Vec2d(-6.0, 0)};
|
||||
std::transform(sample.begin(), sample.end(), sample.begin(), [expected_center] (const Vec2d& a) { return a + expected_center;});
|
||||
|
||||
WHEN("Circle fit is called on the entire array") {
|
||||
@ -190,7 +190,7 @@ SCENARIO("Circle Fit, TaubinFit with Newton's method", "[Geometry]") {
|
||||
}
|
||||
GIVEN("A vector of Vec2ds arranged in a half-circle with approximately the same distance R from some point") {
|
||||
Vec2d expected_center(-3, 9);
|
||||
Vec2ds sample {Vec2d(6.0, 0), Vec2d(5.1961524, 3), Vec2d(3 ,5.1961524),
|
||||
Pointfs sample {Vec2d(6.0, 0), Vec2d(5.1961524, 3), Vec2d(3 ,5.1961524),
|
||||
Vec2d(0, 6.0),
|
||||
Vec2d(3, 5.1961524), Vec2d(-5.1961524, 3), Vec2d(-6.0, 0)};
|
||||
|
||||
|
@ -215,7 +215,8 @@ void test_supports(const std::string & obj_filename,
|
||||
|
||||
REQUIRE_FALSE(mesh.empty());
|
||||
|
||||
TriangleMeshSlicer slicer{&mesh};
|
||||
TriangleMeshSlicer slicer{ CLOSING_RADIUS, 0.f };
|
||||
slicer.init(&mesh, []() {});
|
||||
|
||||
auto bb = mesh.bounding_box();
|
||||
double zmin = bb.min.z();
|
||||
@ -224,7 +225,7 @@ void test_supports(const std::string & obj_filename,
|
||||
auto layer_h = 0.05f;
|
||||
|
||||
out.slicegrid = grid(float(gnd), float(zmax), layer_h);
|
||||
slicer.slice(out.slicegrid , CLOSING_RADIUS, &out.model_slices, []{});
|
||||
slicer.slice(out.slicegrid, &out.model_slices, []{});
|
||||
|
||||
// Create the special index-triangle mesh with spatial indexing which
|
||||
// is the input of the support point and support mesh generators
|
||||
|
Loading…
x
Reference in New Issue
Block a user