mirror of
https://git.mirrors.martin98.com/https://github.com/slic3r/Slic3r.git
synced 2025-07-31 15:42:01 +08:00
Merge remote-tracking branch 'samir/Samir55-support_porting' into test_merge_samir
# Conflicts: # src/CMakeLists.txt
This commit is contained in:
commit
575faf3231
@ -60,7 +60,7 @@ sub generate {
|
||||
$self->clip_with_shape($interface, $shape) if @$shape;
|
||||
|
||||
# Propagate contact layers and interface layers downwards to generate
|
||||
# the main support layers.
|
||||
# the main support layers.
|
||||
my ($base) = $self->generate_base_layers($support_z, $contact, $interface, $top);
|
||||
$self->clip_with_object($base, $support_z, $object);
|
||||
$self->clip_with_shape($base, $shape) if @$shape;
|
||||
@ -108,7 +108,7 @@ sub contact_area {
|
||||
|
||||
# determine contact areas
|
||||
my %contact = (); # contact_z => [ polygons ]
|
||||
my %overhang = (); # contact_z => [ polygons ] - this stores the actual overhang supported by each contact layer
|
||||
my %overhang = (); # contact_z => [ polygons ] - this stores the actual overhang supported by each contact layer
|
||||
for my $layer_id (0 .. $#{$object->layers}) {
|
||||
# note $layer_id might != $layer->id when raft_layers > 0
|
||||
# so $layer_id == 0 means first object layer
|
||||
@ -224,7 +224,7 @@ sub contact_area {
|
||||
|
||||
# Get all perimeters as polylines.
|
||||
# TODO: split_at_first_point() (called by as_polyline() for ExtrusionLoops)
|
||||
# could split a bridge mid-way
|
||||
# could split a bridge mid-way
|
||||
my @overhang_perimeters = map $_->as_polyline, @{$layerm->perimeters->flatten};
|
||||
|
||||
# Only consider the overhang parts of such perimeters,
|
||||
@ -374,7 +374,7 @@ sub object_top {
|
||||
# we considered)
|
||||
my $min_top = min(keys %top) // max(keys %$contact);
|
||||
# use <= instead of just < because otherwise we'd ignore any contact regions
|
||||
# having the same Z of top layers
|
||||
# having the same Z of top layers
|
||||
push @$projection, map @{$contact->{$_}}, grep { $_ > $layer->print_z && $_ <= $min_top } keys %$contact;
|
||||
|
||||
# now find whether any projection falls onto this top surface
|
||||
@ -511,7 +511,7 @@ sub generate_bottom_interface_layers {
|
||||
my $interface_layers = 0;
|
||||
|
||||
# loop through support layers until we find the one(s) right above the top
|
||||
# surface
|
||||
# surface
|
||||
foreach my $layer_id (0 .. $#$support_z) {
|
||||
my $z = $support_z->[$layer_id];
|
||||
next unless $z > $top_z;
|
||||
@ -581,7 +581,7 @@ sub generate_base_layers {
|
||||
|
||||
# This method removes object silhouette from support material
|
||||
# (it's used with interface and base only). It removes a bit more,
|
||||
# leaving a thin gap between object and support in the XY plane.
|
||||
# leaving a thin gap between object and support in the XY plane.
|
||||
sub clip_with_object {
|
||||
my ($self, $support, $support_z, $object) = @_;
|
||||
|
||||
@ -595,7 +595,7 @@ sub clip_with_object {
|
||||
|
||||
# $layer->slices contains the full shape of layer, thus including
|
||||
# perimeter's width. $support contains the full shape of support
|
||||
# material, thus including the width of its foremost extrusion.
|
||||
# material, thus including the width of its foremost extrusion.
|
||||
# We leave a gap equal to a full extrusion width.
|
||||
$support->{$i} = diff(
|
||||
$support->{$i},
|
||||
@ -825,7 +825,7 @@ sub generate_toolpaths {
|
||||
$base_flow = $self->first_layer_flow;
|
||||
|
||||
# use the proper spacing for first layer as we don't need to align
|
||||
# its pattern to the other layers
|
||||
# its pattern to the other layers
|
||||
$filler->set_min_spacing($base_flow->spacing);
|
||||
|
||||
# subtract brim so that it goes around the object fully (and support gets its own brim)
|
||||
|
@ -89,7 +89,7 @@ include_directories(${LIBDIR}/poly2tri/common)
|
||||
add_library(ZipArchive STATIC
|
||||
${LIBDIR}/Zip/ZipArchive.cpp
|
||||
)
|
||||
|
||||
target_compile_features(ZipArchive PUBLIC cxx_std_11)
|
||||
|
||||
add_library(libslic3r STATIC
|
||||
${LIBDIR}/libslic3r/BoundingBox.cpp
|
||||
@ -146,12 +146,11 @@ add_library(libslic3r STATIC
|
||||
${LIBDIR}/libslic3r/SurfaceCollection.cpp
|
||||
${LIBDIR}/libslic3r/SVG.cpp
|
||||
${LIBDIR}/libslic3r/TriangleMesh.cpp
|
||||
${LIBDIR}/libslic3r/SupportMaterial.cpp
|
||||
${LIBDIR}/libslic3r/utils.cpp
|
||||
)
|
||||
target_compile_features(libslic3r PUBLIC cxx_std_11)
|
||||
|
||||
|
||||
|
||||
add_library(BSpline STATIC
|
||||
${LIBDIR}/BSpline/BSpline.cpp
|
||||
)
|
||||
@ -172,6 +171,8 @@ add_library(expat STATIC
|
||||
${LIBDIR}/expat/xmlrole.c
|
||||
${LIBDIR}/expat/xmltok.c
|
||||
)
|
||||
target_compile_features(clipper PUBLIC cxx_std_11)
|
||||
|
||||
add_library(polypartition STATIC ${LIBDIR}/polypartition.cpp)
|
||||
add_library(poly2tri STATIC
|
||||
${LIBDIR}/poly2tri/common/shapes.cc
|
||||
@ -200,6 +201,7 @@ set(SLIC3R_TEST_SOURCES
|
||||
${TESTDIR}/test_data.cpp
|
||||
${TESTDIR}/libslic3r/test_trianglemesh.cpp
|
||||
${TESTDIR}/libslic3r/test_config.cpp
|
||||
${TESTDIR}/libslic3r/test_support_material.cpp
|
||||
)
|
||||
add_executable(slic3r slic3r.cpp)
|
||||
#set_target_properties(slic3r PROPERTIES LINK_SEARCH_START_STATIC 1)
|
||||
|
296
src/test/libslic3r/test_support_material.cpp
Normal file
296
src/test/libslic3r/test_support_material.cpp
Normal file
@ -0,0 +1,296 @@
|
||||
//#include <catch.hpp>
|
||||
#include <libslic3r/IO.hpp>
|
||||
#include <libslic3r/GCodeReader.hpp>
|
||||
#include "/home/ahmedsamir/Work/SamirSlic3r/Slic3r/build/external/Catch/include/catch.hpp"
|
||||
|
||||
#include "libslic3r.h"
|
||||
#include "TriangleMesh.hpp"
|
||||
#include "Model.hpp"
|
||||
#include "SupportMaterial.hpp"
|
||||
|
||||
using namespace std;
|
||||
using namespace Slic3r;
|
||||
|
||||
void test_1_checks(Print &print, bool &a, bool &b, bool &c, bool &d);
|
||||
bool test_6_checks(Print &print);
|
||||
|
||||
// Testing 0.1: supports material member functions.
|
||||
TEST_CASE("", "")
|
||||
{
|
||||
// Create a mesh & modelObject.
|
||||
TriangleMesh mesh = TriangleMesh::make_cube(20, 20, 20);
|
||||
|
||||
// Create modelObject.
|
||||
Model model = Model();
|
||||
ModelObject *object = model.add_object();
|
||||
object->add_volume(mesh);
|
||||
model.add_default_instances();
|
||||
|
||||
// Align to origin.
|
||||
model.align_instances_to_origin();
|
||||
|
||||
// Create Print.
|
||||
Print print = Print();
|
||||
vector<coordf_t> contact_z = {1.9};
|
||||
vector<coordf_t> top_z = {1.1};
|
||||
print.default_object_config.support_material = 1;
|
||||
print.default_object_config.set_deserialize("raft_layers", "3");
|
||||
print.add_model_object(model.objects[0]);
|
||||
print.objects.front()->_slice();
|
||||
|
||||
|
||||
SupportMaterial *support = print.objects.front()->_support_material();
|
||||
|
||||
support->generate(print.objects.front());
|
||||
REQUIRE(print.objects.front()->support_layer_count() == 3);
|
||||
|
||||
}
|
||||
|
||||
// Test 1.
|
||||
SCENARIO("SupportMaterial: support_layers_z and contact_distance")
|
||||
{
|
||||
GIVEN("A print object having one modelObject") {
|
||||
// Create a mesh & modelObject.
|
||||
TriangleMesh mesh = TriangleMesh::make_cube(20, 20, 20);
|
||||
|
||||
// Create modelObject.
|
||||
Model model = Model();
|
||||
ModelObject *object = model.add_object();
|
||||
object->add_volume(mesh);
|
||||
model.add_default_instances();
|
||||
|
||||
// Align to origin.
|
||||
model.align_instances_to_origin();
|
||||
// Create Print.
|
||||
Print print = Print();
|
||||
print.default_object_config.set_deserialize("support_material", "1");
|
||||
|
||||
WHEN("First layer height = 0.4") {
|
||||
print.default_object_config.set_deserialize("layer_height", "0.2");
|
||||
print.default_object_config.set_deserialize("first_layer_height", "0.4");
|
||||
|
||||
print.add_model_object(model.objects[0]);
|
||||
print.objects.front()->_slice();
|
||||
bool a, b, c, d;
|
||||
|
||||
test_1_checks(print, a, b, c, d);
|
||||
THEN("First layer height is honored") {
|
||||
REQUIRE(a == true);
|
||||
}
|
||||
THEN("No null or negative support layers") {
|
||||
REQUIRE(b == true);
|
||||
}
|
||||
THEN("No layers thicker than nozzle diameter") {
|
||||
REQUIRE(c == true);
|
||||
}
|
||||
THEN("Layers above top surfaces are spaced correctly") {
|
||||
REQUIRE(d == true);
|
||||
}
|
||||
}
|
||||
WHEN("Layer height = 0.2 and, first layer height = 0.3") {
|
||||
print.default_object_config.set_deserialize("layer_height", "0.2");
|
||||
print.default_object_config.set_deserialize("first_layer_height", "0.3");
|
||||
print.add_model_object(model.objects[0]);
|
||||
print.objects.front()->_slice();
|
||||
bool a, b, c, d;
|
||||
|
||||
test_1_checks(print, a, b, c, d);
|
||||
THEN("First layer height is honored") {
|
||||
REQUIRE(a == true);
|
||||
}
|
||||
THEN("No null or negative support layers") {
|
||||
REQUIRE(b == true);
|
||||
}
|
||||
THEN("No layers thicker than nozzle diameter") {
|
||||
REQUIRE(c == true);
|
||||
}
|
||||
THEN("Layers above top surfaces are spaced correctly") {
|
||||
REQUIRE(d == true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
WHEN("Layer height = nozzle_diameter[0]") {
|
||||
print.default_object_config.set_deserialize("layer_height", "0.2");
|
||||
print.default_object_config.set_deserialize("first_layer_height", "0.3");
|
||||
print.add_model_object(model.objects[0]);
|
||||
print.objects.front()->_slice();
|
||||
bool a, b, c, d;
|
||||
|
||||
test_1_checks(print, a, b, c, d);
|
||||
THEN("First layer height is honored") {
|
||||
REQUIRE(a == true);
|
||||
}
|
||||
THEN("No null or negative support layers") {
|
||||
REQUIRE(b == true);
|
||||
}
|
||||
THEN("No layers thicker than nozzle diameter") {
|
||||
REQUIRE(c == true);
|
||||
}
|
||||
THEN("Layers above top surfaces are spaced correctly") {
|
||||
REQUIRE(d == true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Test 8.
|
||||
TEST_CASE("SupportMaterial: forced support is generated", "")
|
||||
{
|
||||
// Create a mesh & modelObject.
|
||||
TriangleMesh mesh = TriangleMesh::make_cube(20, 20, 20);
|
||||
|
||||
Model model = Model();
|
||||
ModelObject *object = model.add_object();
|
||||
object->add_volume(mesh);
|
||||
model.add_default_instances();
|
||||
model.align_instances_to_origin();
|
||||
|
||||
Print print = Print();
|
||||
|
||||
vector<coordf_t> contact_z = {1.9};
|
||||
vector<coordf_t> top_z = {1.1};
|
||||
print.default_object_config.support_material_enforce_layers = 100;
|
||||
print.default_object_config.support_material = 0;
|
||||
print.default_object_config.layer_height = 0.2;
|
||||
print.default_object_config.set_deserialize("first_layer_height", "0.3");
|
||||
|
||||
print.add_model_object(model.objects[0]);
|
||||
print.objects.front()->_slice();
|
||||
|
||||
SupportMaterial *support = print.objects.front()->_support_material();
|
||||
auto support_z = support->support_layers_z(contact_z, top_z, print.default_object_config.layer_height);
|
||||
|
||||
bool check = true;
|
||||
for (size_t i = 1; i < support_z.size(); i++) {
|
||||
if (support_z[i] - support_z[i - 1] <= 0)
|
||||
check = false;
|
||||
}
|
||||
|
||||
REQUIRE(check == true);
|
||||
}
|
||||
|
||||
// Test 6.
|
||||
SCENARIO("SupportMaterial: Checking bridge speed")
|
||||
{
|
||||
GIVEN("Print object") {
|
||||
// Create a mesh & modelObject.
|
||||
TriangleMesh mesh = TriangleMesh::make_cube(20, 20, 20);
|
||||
|
||||
Model model = Model();
|
||||
ModelObject *object = model.add_object();
|
||||
object->add_volume(mesh);
|
||||
model.add_default_instances();
|
||||
model.align_instances_to_origin();
|
||||
|
||||
Print print = Print();
|
||||
print.config.brim_width = 0;
|
||||
print.config.skirts = 0;
|
||||
print.config.skirts = 0;
|
||||
print.default_object_config.support_material = 1;
|
||||
print.default_region_config.top_solid_layers = 0; // so that we don't have the internal bridge over infill.
|
||||
print.default_region_config.bridge_speed = 99;
|
||||
print.config.cooling = 0;
|
||||
print.config.set_deserialize("first_layer_speed", "100%");
|
||||
|
||||
WHEN("support_material_contact_distance = 0.2") {
|
||||
print.default_object_config.support_material_contact_distance = 0.2;
|
||||
print.add_model_object(model.objects[0]);
|
||||
|
||||
bool check = test_6_checks(print);
|
||||
REQUIRE(check == true); // bridge speed is used.
|
||||
}
|
||||
|
||||
WHEN("support_material_contact_distance = 0") {
|
||||
print.default_object_config.support_material_contact_distance = 0;
|
||||
print.add_model_object(model.objects[0]);
|
||||
|
||||
bool check = test_6_checks(print);
|
||||
REQUIRE(check == true); // bridge speed is not used.
|
||||
}
|
||||
|
||||
WHEN("support_material_contact_distance = 0.2 & raft_layers = 5") {
|
||||
print.default_object_config.support_material_contact_distance = 0.2;
|
||||
print.default_object_config.raft_layers = 5;
|
||||
print.add_model_object(model.objects[0]);
|
||||
|
||||
bool check = test_6_checks(print);
|
||||
REQUIRE(check == true); // bridge speed is used.
|
||||
}
|
||||
|
||||
WHEN("support_material_contact_distance = 0 & raft_layers = 5") {
|
||||
print.default_object_config.support_material_contact_distance = 0;
|
||||
print.default_object_config.raft_layers = 5;
|
||||
print.add_model_object(model.objects[0]);
|
||||
|
||||
bool check = test_6_checks(print);
|
||||
|
||||
REQUIRE(check == true); // bridge speed is not used.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void test_1_checks(Print &print, bool &a, bool &b, bool &c, bool &d)
|
||||
{
|
||||
vector<coordf_t> contact_z = {1.9};
|
||||
vector<coordf_t> top_z = {1.1};
|
||||
|
||||
SupportMaterial *support = print.objects.front()->_support_material();
|
||||
|
||||
vector<coordf_t>
|
||||
support_z = support->support_layers_z(contact_z, top_z, print.default_object_config.layer_height);
|
||||
|
||||
a = (support_z[0] == print.default_object_config.first_layer_height.value);
|
||||
|
||||
b = true;
|
||||
for (size_t i = 1; i < support_z.size(); ++i)
|
||||
if (support_z[i] - support_z[i - 1] <= 0) b = false;
|
||||
|
||||
|
||||
c = true;
|
||||
for (size_t i = 1; i < support_z.size(); ++i)
|
||||
if (support_z[i] - support_z[i - 1] > print.config.nozzle_diameter.get_at(0) + EPSILON)
|
||||
c = false;
|
||||
|
||||
coordf_t expected_top_spacing = support
|
||||
->contact_distance(print.default_object_config.layer_height,
|
||||
print.config.nozzle_diameter.get_at(0));
|
||||
|
||||
bool wrong_top_spacing = 0;
|
||||
for (coordf_t top_z_el : top_z) {
|
||||
// find layer index of this top surface.
|
||||
size_t layer_id = -1;
|
||||
for (size_t i = 0; i < support_z.size(); i++) {
|
||||
if (abs(support_z[i] - top_z_el) < EPSILON) {
|
||||
layer_id = i;
|
||||
i = static_cast<int>(support_z.size());
|
||||
}
|
||||
}
|
||||
|
||||
// check that first support layer above this top surface (or the next one) is spaced with nozzle diameter
|
||||
if (abs(support_z[layer_id + 1] - support_z[layer_id] - expected_top_spacing) > EPSILON
|
||||
&& abs(support_z[layer_id + 2] - support_z[layer_id] - expected_top_spacing) > EPSILON) {
|
||||
wrong_top_spacing = 1;
|
||||
}
|
||||
}
|
||||
d = !wrong_top_spacing;
|
||||
}
|
||||
|
||||
// TODO
|
||||
bool test_6_checks(Print &print)
|
||||
{
|
||||
bool has_bridge_speed = true;
|
||||
|
||||
// Pre-Processing.
|
||||
PrintObject *print_object = print.objects.front();
|
||||
print_object->_infill();
|
||||
SupportMaterial *support_material = print.objects.front()->_support_material();
|
||||
support_material->generate(print_object);
|
||||
// TODO but not needed in test 6 (make brims and make skirts).
|
||||
|
||||
// Exporting gcode.
|
||||
// TODO validation found in Simple.pm
|
||||
|
||||
|
||||
return has_bridge_speed;
|
||||
}
|
@ -15,6 +15,7 @@
|
||||
#include "PlaceholderParser.hpp"
|
||||
#include "SlicingAdaptive.hpp"
|
||||
#include "LayerHeightSpline.hpp"
|
||||
#include "SupportMaterial.hpp"
|
||||
|
||||
#include <exception>
|
||||
|
||||
@ -25,6 +26,7 @@ class InvalidObjectException : public std::exception {};
|
||||
class Print;
|
||||
class PrintObject;
|
||||
class ModelObject;
|
||||
class SupportMaterial;
|
||||
|
||||
// Print step IDs for keeping track of the print state.
|
||||
enum PrintStep {
|
||||
@ -132,6 +134,8 @@ class PrintObject
|
||||
Layer* add_layer(int id, coordf_t height, coordf_t print_z, coordf_t slice_z);
|
||||
void delete_layer(int idx);
|
||||
|
||||
SupportMaterial* _support_material();
|
||||
Flow _support_material_flow(FlowRole role = frSupportMaterial);
|
||||
size_t support_layer_count() const;
|
||||
void clear_support_layers();
|
||||
SupportLayer* get_support_layer(int idx) { return this->support_layers.at(idx); };
|
||||
@ -232,7 +236,6 @@ class Print
|
||||
void auto_assign_extruders(ModelObject* model_object) const;
|
||||
std::string output_filename();
|
||||
std::string output_filepath(const std::string &path);
|
||||
|
||||
private:
|
||||
void clear_regions();
|
||||
void delete_region(size_t idx);
|
||||
|
@ -1095,4 +1095,55 @@ PrintObject::_infill()
|
||||
this->state.set_done(posInfill);
|
||||
}
|
||||
|
||||
SupportMaterial *
|
||||
PrintObject::_support_material()
|
||||
{
|
||||
// TODO what does this line do //= FLOW_ROLE_SUPPORT_MATERIAL;
|
||||
Flow first_layer_flow = Flow::new_from_config_width(
|
||||
frSupportMaterial,
|
||||
print()->config
|
||||
.first_layer_extrusion_width, // check why this line is put || config.support_material_extrusion_width,
|
||||
static_cast<float>(print()->config.nozzle_diameter.get_at(static_cast<size_t>(
|
||||
config.support_material_extruder
|
||||
- 1))), // Check why this is put in perl "// $self->print->config->nozzle_diameter->[0]"
|
||||
static_cast<float>(config.get_abs_value("first_layer_height")),
|
||||
0 // No bridge flow ratio.
|
||||
);
|
||||
|
||||
return new SupportMaterial(
|
||||
&print()->config,
|
||||
&config,
|
||||
first_layer_flow,
|
||||
_support_material_flow(),
|
||||
_support_material_flow(frSupportMaterialInterface)
|
||||
);
|
||||
}
|
||||
|
||||
Flow
|
||||
PrintObject::_support_material_flow(FlowRole role)
|
||||
{
|
||||
// Create support flow.
|
||||
int extruder =
|
||||
(role == frSupportMaterial) ?
|
||||
config.support_material_extruder.value : config
|
||||
.support_material_interface_extruder.value;
|
||||
|
||||
auto width = config.support_material_extrusion_width; // || config.extrusion_width;
|
||||
|
||||
if (role == frSupportMaterialInterface)
|
||||
width = config.support_material_interface_extrusion_width; // || width;
|
||||
|
||||
// We use a bogus layer_height because we use the same flow for all
|
||||
// support material layers.
|
||||
Flow support_flow = Flow::new_from_config_width(
|
||||
role,
|
||||
width,
|
||||
static_cast<float>(print()->config.nozzle_diameter
|
||||
.get_at(static_cast<size_t>(extruder - 1))), // Check this line $self->print->config->nozzle_diameter->[0].
|
||||
static_cast<float>(config.layer_height.value),
|
||||
0
|
||||
);
|
||||
|
||||
return support_flow;
|
||||
}
|
||||
}
|
||||
|
1225
xs/src/libslic3r/SupportMaterial.cpp
Normal file
1225
xs/src/libslic3r/SupportMaterial.cpp
Normal file
File diff suppressed because it is too large
Load Diff
@ -1,11 +1,164 @@
|
||||
#ifndef slic3r_SupportMaterial_hpp_
|
||||
#define slic3r_SupportMaterial_hpp_
|
||||
|
||||
namespace Slic3r {
|
||||
#include <numeric>
|
||||
#include <vector>
|
||||
#include <iostream>
|
||||
#include <algorithm>
|
||||
#include "libslic3r.h"
|
||||
#include "PrintConfig.hpp"
|
||||
#include "Flow.hpp"
|
||||
#include "Layer.hpp"
|
||||
#include "Geometry.hpp"
|
||||
#include "Print.hpp"
|
||||
#include "ClipperUtils.hpp"
|
||||
#include "ExPolygon.hpp"
|
||||
#include "SVG.hpp"
|
||||
#include <libslic3r/Fill/Fill.hpp>
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace Slic3r
|
||||
{
|
||||
|
||||
// how much we extend support around the actual contact area
|
||||
constexpr coordf_t SUPPORT_MATERIAL_MARGIN = 1.5;
|
||||
|
||||
constexpr coordf_t MARGIN_STEP = SUPPORT_MATERIAL_MARGIN / 3;
|
||||
|
||||
constexpr coordf_t PILLAR_SIZE = 2.5;
|
||||
|
||||
constexpr coordf_t PILLAR_SPACING = 10;
|
||||
|
||||
/// Struct for carrying the toolpaths parameters needed for each thread.
|
||||
struct toolpaths_params
|
||||
{
|
||||
int contact_loops;
|
||||
coordf_t circle_radius;
|
||||
coordf_t circle_distance;
|
||||
Polygon circle;
|
||||
SupportMaterialPattern pattern;
|
||||
vector<int> angles;
|
||||
double interface_angle{};
|
||||
double interface_spacing{};
|
||||
float interface_density{};
|
||||
double support_spacing{};
|
||||
double support_density{};
|
||||
|
||||
toolpaths_params(int contact_loops = 0,
|
||||
coordf_t circle_radius = 0,
|
||||
coordf_t circle_distance = 0,
|
||||
const Polygon &circle = Polygon(),
|
||||
const SupportMaterialPattern &pattern = SupportMaterialPattern(),
|
||||
const vector<int> &angles = vector<int>())
|
||||
: contact_loops(contact_loops),
|
||||
circle_radius(circle_radius),
|
||||
circle_distance(circle_distance),
|
||||
circle(circle),
|
||||
pattern(pattern),
|
||||
angles(angles)
|
||||
{}
|
||||
};
|
||||
|
||||
class SupportMaterial
|
||||
{
|
||||
public:
|
||||
friend PrintObject;
|
||||
|
||||
PrintConfig *config; ///< The print config
|
||||
PrintObjectConfig *object_config; ///< The object print config.
|
||||
Flow flow; ///< The intermediate layers print flow.
|
||||
Flow first_layer_flow; ///< The first (base) layers print flow.
|
||||
Flow interface_flow; ///< The interface layers print flow.
|
||||
|
||||
/// Generate the extrusions paths for the support matterial generated for the given print object.
|
||||
void generate_toolpaths(PrintObject *object,
|
||||
map<coordf_t, Polygons> overhang,
|
||||
map<coordf_t, Polygons> contact,
|
||||
map<int, Polygons> interface,
|
||||
map<int, Polygons> base);
|
||||
|
||||
/// Generate support material for the given print object.
|
||||
void generate(PrintObject *object);
|
||||
|
||||
/// Generate the support layers slicing z coordinates.
|
||||
vector<coordf_t> support_layers_z(vector<coordf_t> contact_z,
|
||||
vector<coordf_t> top_z,
|
||||
coordf_t max_object_layer_height);
|
||||
|
||||
pair<map<coordf_t, Polygons>, map<coordf_t, Polygons>> contact_area(PrintObject *object);
|
||||
|
||||
map<coordf_t, Polygons> object_top(PrintObject *object, map<coordf_t, Polygons> *contact);
|
||||
|
||||
void generate_pillars_shape(const map<coordf_t, Polygons> &contact,
|
||||
const vector<coordf_t> &support_z,
|
||||
map<int, Polygons> &shape);
|
||||
|
||||
map<int, Polygons> generate_base_layers(vector<coordf_t> support_z,
|
||||
map<coordf_t, Polygons> contact,
|
||||
map<int, Polygons> interface,
|
||||
map<coordf_t, Polygons> top);
|
||||
|
||||
map<int, Polygons> generate_interface_layers(vector<coordf_t> support_z,
|
||||
map<coordf_t, Polygons> contact,
|
||||
map<coordf_t, Polygons> top);
|
||||
|
||||
void generate_bottom_interface_layers(const vector<coordf_t> &support_z,
|
||||
map<int, Polygons> &base,
|
||||
map<coordf_t, Polygons> &top,
|
||||
map<int, Polygons> &interface);
|
||||
|
||||
coordf_t contact_distance(coordf_t layer_height, coordf_t nozzle_diameter);
|
||||
|
||||
/// This method returns the indices of the layers overlapping with the given one.
|
||||
vector<int> overlapping_layers(int layer_idx, const vector<coordf_t> &support_z);
|
||||
|
||||
void clip_with_shape(map<int, Polygons> &support, map<int, Polygons> &shape);
|
||||
|
||||
// This method removes object silhouette from support material
|
||||
// (it's used with interface and base only). It removes a bit more,
|
||||
// leaving a thin gap between object and support in the XY plane.
|
||||
void clip_with_object(map<int, Polygons> &support, vector<coordf_t> support_z, PrintObject &object);
|
||||
|
||||
void process_layer(int layer_id, toolpaths_params params);
|
||||
|
||||
private:
|
||||
/// SupportMaterial is generated by PrintObject.
|
||||
SupportMaterial(PrintConfig *print_config,
|
||||
PrintObjectConfig *print_object_config,
|
||||
Flow flow,
|
||||
Flow first_layer_flow,
|
||||
Flow interface_flow)
|
||||
: config(print_config),
|
||||
object_config(print_object_config),
|
||||
flow(Flow(0, 0, 0)),
|
||||
first_layer_flow(Flow(0, 0, 0)),
|
||||
interface_flow(Flow(0, 0, 0)),
|
||||
object(nullptr)
|
||||
{}
|
||||
|
||||
// Get the maximum layer height given a print object.
|
||||
coordf_t get_max_layer_height(PrintObject *object);
|
||||
|
||||
// (Deprecated) use append_to instead
|
||||
void append_polygons(Polygons &dst, Polygons &src);
|
||||
|
||||
// Return polygon vector given a vector of surfaces.
|
||||
Polygons p(SurfacesPtr &surfaces);
|
||||
|
||||
vector<coordf_t> get_keys_sorted(map<coordf_t, Polygons> _map);
|
||||
|
||||
Polygon create_circle(coordf_t radius);
|
||||
|
||||
// Used during generate_toolpaths function.
|
||||
PrintObject *object;
|
||||
map<coordf_t, Polygons> overhang;
|
||||
map<coordf_t, Polygons> contact;
|
||||
map<int, Polygons> interface;
|
||||
map<int, Polygons> base;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
Loading…
x
Reference in New Issue
Block a user