C++ supports sketched, but not finalized yet. Slic3r is still using
the old Perl supports, but this time with the C++ fillers.
This commit is contained in:
parent
8f40d9b34e
commit
7d7f093120
@ -250,6 +250,7 @@ sub thread_cleanup {
|
||||
*Slic3r::Print::Region::DESTROY = sub {};
|
||||
*Slic3r::Surface::DESTROY = sub {};
|
||||
*Slic3r::Surface::Collection::DESTROY = sub {};
|
||||
*Slic3r::Print::SupportMaterial2::DESTROY = sub {};
|
||||
*Slic3r::TriangleMesh::DESTROY = sub {};
|
||||
return undef; # this prevents a "Scalars leaked" warning
|
||||
}
|
||||
|
@ -288,6 +288,8 @@ sub export {
|
||||
my @obj_idx = @{chained_path([ map Slic3r::Point->new(@{$_->_shifted_copies->[0]}), @{$self->objects} ])};
|
||||
|
||||
# sort layers by Z
|
||||
# All extrusion moves with the same top layer height are extruded uninterrupted,
|
||||
# object extrusion moves are performed first, then the support.
|
||||
my %layers = (); # print_z => [ [layers], [layers], [layers] ] by obj_idx
|
||||
foreach my $obj_idx (0 .. ($self->print->object_count - 1)) {
|
||||
my $object = $self->objects->[$obj_idx];
|
||||
|
@ -70,14 +70,16 @@ sub slice {
|
||||
|
||||
# add raft layers
|
||||
if ($self->config->raft_layers > 0) {
|
||||
# Reserve object layers for the raft. Last layer of the raft is the contact layer.
|
||||
$id += $self->config->raft_layers;
|
||||
|
||||
# raise first object layer Z by the thickness of the raft itself
|
||||
# plus the extra distance required by the support material logic
|
||||
# Raise first object layer Z by the thickness of the raft itself
|
||||
# plus the extra distance required by the support material logic.
|
||||
#FIXME The last raft layer is the contact layer, which shall be printed with a bridging flow for ease of separation. Currently it is not the case.
|
||||
my $first_layer_height = $self->config->get_value('first_layer_height');
|
||||
$print_z += $first_layer_height;
|
||||
|
||||
# use a large height
|
||||
# Use as large as possible layer height for the intermediate raft layers.
|
||||
my $support_material_layer_height;
|
||||
{
|
||||
my @nozzle_diameters = (
|
||||
@ -90,6 +92,7 @@ sub slice {
|
||||
$print_z += $support_material_layer_height * ($self->config->raft_layers - 1);
|
||||
|
||||
# compute the average of all nozzles used for printing the object
|
||||
#FIXME It is expected, that the 1st layer of the object is printed with a bridging flow over a full raft. Shall it not be vice versa?
|
||||
my $nozzle_diameter;
|
||||
{
|
||||
my @nozzle_diameters = (
|
||||
@ -664,6 +667,8 @@ sub _support_material {
|
||||
bridge_flow_ratio => 0,
|
||||
);
|
||||
|
||||
if (1) {
|
||||
# Old supports, Perl implementation.
|
||||
return Slic3r::Print::SupportMaterial->new(
|
||||
print_config => $self->print->config,
|
||||
object_config => $self->config,
|
||||
@ -671,6 +676,17 @@ sub _support_material {
|
||||
flow => $self->support_material_flow,
|
||||
interface_flow => $self->support_material_flow(FLOW_ROLE_SUPPORT_MATERIAL_INTERFACE),
|
||||
);
|
||||
} else {
|
||||
# New supports, C++ implementation.
|
||||
return Slic3r::Print::SupportMaterial2->new(
|
||||
print_config => $self->print->config,
|
||||
object_config => $self->config,
|
||||
first_layer_flow => $first_layer_flow,
|
||||
flow => $self->support_material_flow,
|
||||
interface_flow => $self->support_material_flow(FLOW_ROLE_SUPPORT_MATERIAL_INTERFACE),
|
||||
soluble_interface => ($self->config->support_material_contact_distance == 0),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
# This function analyzes slices of a region (SurfaceCollection slices).
|
||||
|
@ -8,7 +8,7 @@ use Slic3r::ExtrusionPath ':roles';
|
||||
use Slic3r::Flow ':roles';
|
||||
use Slic3r::Geometry qw(epsilon scale scaled_epsilon PI rad2deg deg2rad convex_hull);
|
||||
use Slic3r::Geometry::Clipper qw(offset diff union union_ex intersection offset_ex offset2
|
||||
intersection_pl offset2_ex diff_pl);
|
||||
intersection_pl offset2_ex diff_pl CLIPPER_OFFSET_SCALE JT_MITER JT_ROUND);
|
||||
use Slic3r::Surface ':types';
|
||||
|
||||
has 'print_config' => (is => 'rw', required => 1);
|
||||
@ -59,7 +59,7 @@ sub generate {
|
||||
}
|
||||
|
||||
# Propagate contact layers downwards to generate interface layers
|
||||
my ($interface) = $self->generate_interface_layers($support_z, $contact, $top);
|
||||
my ($interface) = $self->generate_top_interface_layers($support_z, $contact, $top);
|
||||
$self->clip_with_object($interface, $support_z, $object);
|
||||
$self->clip_with_shape($interface, $shape) if @$shape;
|
||||
|
||||
@ -146,10 +146,14 @@ sub contact_area {
|
||||
# footprint for the raft
|
||||
# we only consider contours and discard holes to get a more continuous raft
|
||||
push @overhang, map $_->clone, map $_->contour, @{$layer->slices};
|
||||
# Extend by SUPPORT_MATERIAL_MARGIN, which is 1.5mm
|
||||
# MARGIN is the C++ Slic3r::SUPPORT_MATERIAL_MARGIN constant.
|
||||
push @contact, @{offset(\@overhang, scale +MARGIN)};
|
||||
} else {
|
||||
my $lower_layer = $object->get_layer($layer_id-1);
|
||||
foreach my $layerm (@{$layer->regions}) {
|
||||
# Extrusion width accounts for the roundings of the extrudates.
|
||||
# It is the maximum widh of the extrudate.
|
||||
my $fw = $layerm->flow(FLOW_ROLE_EXTERNAL_PERIMETER)->scaled_width;
|
||||
my $diff;
|
||||
|
||||
@ -161,6 +165,7 @@ sub contact_area {
|
||||
? scale $lower_layer->height * ((cos $threshold_rad) / (sin $threshold_rad))
|
||||
: 0;
|
||||
|
||||
# Shrinking the supported layer by layer_height/atan(threshold_rad).
|
||||
$diff = diff(
|
||||
offset([ map $_->p, @{$layerm->slices} ], -$d),
|
||||
[ map @$_, @{$lower_layer->slices} ],
|
||||
@ -175,9 +180,12 @@ sub contact_area {
|
||||
[ map @$_, @{$lower_layer->slices} ],
|
||||
) if $d > $fw/2;
|
||||
} else {
|
||||
# Automatic overhang detection.
|
||||
$diff = diff(
|
||||
[ map $_->p, @{$layerm->slices} ],
|
||||
offset([ map @$_, @{$lower_layer->slices} ], +$fw*2),
|
||||
offset([ map @$_, @{$lower_layer->slices} ],
|
||||
#FIXME Vojtech: Why 2x extrusion width? Isn't this too much? Should it not be /2?
|
||||
+$fw/2),
|
||||
);
|
||||
|
||||
# collapse very tiny spots
|
||||
@ -288,8 +296,13 @@ sub contact_area {
|
||||
}
|
||||
for ($fw/2, map {scale MARGIN_STEP} 1..(MARGIN / MARGIN_STEP)) {
|
||||
$diff = diff(
|
||||
offset($diff, $_),
|
||||
$slices_margin,
|
||||
offset(
|
||||
$diff,
|
||||
$_,
|
||||
CLIPPER_OFFSET_SCALE,
|
||||
JT_ROUND,
|
||||
scale(0.05)*CLIPPER_OFFSET_SCALE),
|
||||
$slices_margin
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -308,7 +321,9 @@ sub contact_area {
|
||||
|
||||
my $contact_z = $layer->print_z - $self->contact_distance($layer->height, $nozzle_diameter);
|
||||
|
||||
# ignore this contact area if it's too low
|
||||
# Ignore this contact area if it's too low.
|
||||
#FIXME Better to control the thickness of the interface layer printed, but that would
|
||||
# require having attributes (extrusion width / height, bridge flow etc) per island.
|
||||
next if $contact_z < $self->object_config->get_value('first_layer_height') - epsilon;
|
||||
|
||||
$contact{$contact_z} = [ @contact ];
|
||||
@ -336,6 +351,7 @@ sub object_top {
|
||||
my %top = (); # print_z => [ expolygons ]
|
||||
return \%top if ($self->object_config->support_material_buildplate_only);
|
||||
|
||||
# Sum of unsupported contact areas above the current $layer->print_z.
|
||||
my $projection = [];
|
||||
foreach my $layer (reverse @{$object->layers}) {
|
||||
if (my @top = map @{$_->slices->filter_by_type(S_TYPE_TOP)}, @{$layer->regions}) {
|
||||
@ -348,7 +364,8 @@ sub object_top {
|
||||
# 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
|
||||
# Now find whether any projection of the contact surfaces above $layer->print_z not yet supported by any top surfaces above $layer->z falls onto this top surface.
|
||||
# $touching are the contact surfaces supported exclusively by this @top surfaaces.
|
||||
my $touching = intersection($projection, [ map $_->p, @top ]);
|
||||
if (@$touching) {
|
||||
# grow top surfaces so that interface and support generation are generated
|
||||
@ -382,7 +399,10 @@ sub support_layers_z {
|
||||
# initialize known, fixed, support layers
|
||||
my @z = sort { $a <=> $b }
|
||||
@$contact_z,
|
||||
@$top_z, # TODO: why we have this?
|
||||
# TODO: why we have this?
|
||||
# Vojtech: To detect the bottom interface layers by finding a Z value in the $top_z.
|
||||
@$top_z,
|
||||
# Top surfaces of the bottom interface layers.
|
||||
(map $_ + $contact_distance, @$top_z);
|
||||
|
||||
# enforce first layer height
|
||||
@ -407,10 +427,15 @@ sub support_layers_z {
|
||||
for (my $i = $#z; $i >= $self->object_config->raft_layers; $i--) {
|
||||
my $target_height = $support_material_height;
|
||||
if ($i > 0 && $top{ $z[$i-1] }) {
|
||||
# Bridge flow?
|
||||
#FIXME We want to enforce not only the bridge flow height, but also the interface gap!
|
||||
# This will introduce an additional layer if the gap is set to an extreme value!
|
||||
$target_height = $nozzle_diameter;
|
||||
}
|
||||
|
||||
# enforce first layer height
|
||||
#FIXME better to split the layers regularly, than to bite a constant height one at a time,
|
||||
# and then be left with a very thin layer at the end.
|
||||
if (($i == 0 && $z[$i] > $target_height + $first_layer_height)
|
||||
|| ($z[$i] - $z[$i-1] > $target_height + Slic3r::Geometry::epsilon)) {
|
||||
splice @z, $i, 0, ($z[$i] - $target_height);
|
||||
@ -427,9 +452,12 @@ sub support_layers_z {
|
||||
return \@z;
|
||||
}
|
||||
|
||||
sub generate_interface_layers {
|
||||
sub generate_top_interface_layers {
|
||||
my ($self, $support_z, $contact, $top) = @_;
|
||||
|
||||
# If no interface layers are allowed, don't generate top interface layers.
|
||||
return if $self->object_config->support_material_interface_layers == 0;
|
||||
|
||||
# let's now generate interface layers below contact areas
|
||||
my %interface = (); # layer_id => [ polygons ]
|
||||
my $interface_layers_num = $self->object_config->support_material_interface_layers;
|
||||
@ -519,6 +547,7 @@ sub generate_base_layers {
|
||||
# let's now generate support layers under interface layers
|
||||
my $base = {}; # layer_id => [ polygons ]
|
||||
{
|
||||
my $fillet_radius_scaled = scale($self->object_config->support_material_spacing);
|
||||
for my $i (reverse 0 .. $#$support_z-1) {
|
||||
my $z = $support_z->[$i];
|
||||
my @overlapping_layers = $self->overlapping_layers($i, $support_z);
|
||||
@ -531,19 +560,36 @@ sub generate_base_layers {
|
||||
@upper_contact = @{ $contact->{$support_z->[$i+1]} || [] };
|
||||
}
|
||||
|
||||
my $trim_polygons = [
|
||||
(map @$_, map $top->{$_}, grep exists $top->{$_}, @overlapping_z), # top slices on this layer
|
||||
(map @$_, map $interface->{$_}, grep exists $interface->{$_}, @overlapping_layers), # interface regions on this layer
|
||||
(map @$_, map $contact->{$_}, grep exists $contact->{$_}, @overlapping_z), # contact regions on this layer
|
||||
];
|
||||
|
||||
$base->{$i} = diff(
|
||||
[
|
||||
@{ $base->{$i+1} || [] }, # support regions on upper layer
|
||||
@{ $interface->{$i+1} || [] }, # interface regions on upper layer
|
||||
@upper_contact, # contact regions on upper layer
|
||||
],
|
||||
[
|
||||
(map @$_, map $top->{$_}, grep exists $top->{$_}, @overlapping_z), # top slices on this layer
|
||||
(map @$_, map $interface->{$_}, grep exists $interface->{$_}, @overlapping_layers), # interface regions on this layer
|
||||
(map @$_, map $contact->{$_}, grep exists $contact->{$_}, @overlapping_z), # contact regions on this layer
|
||||
],
|
||||
1,
|
||||
$trim_polygons,
|
||||
1, # safety offset to merge the touching source polygons
|
||||
);
|
||||
|
||||
if (0) {
|
||||
# Fillet the base polygons and trim them again with the top, interface and contact layers.
|
||||
$base->{$i} = diff(
|
||||
offset2(
|
||||
$base->{$i},
|
||||
$fillet_radius_scaled,
|
||||
-$fillet_radius_scaled,
|
||||
# Use a geometric offsetting for filleting.
|
||||
CLIPPER_OFFSET_SCALE,
|
||||
JT_ROUND,
|
||||
0.2*$fillet_radius_scaled*CLIPPER_OFFSET_SCALE),
|
||||
$trim_polygons,
|
||||
0); # don't apply the safety offset.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -602,8 +648,8 @@ sub generate_toolpaths {
|
||||
}
|
||||
|
||||
my %fillers = (
|
||||
interface => $object->fill_maker->filler('rectilinear'),
|
||||
support => $object->fill_maker->filler($pattern),
|
||||
interface => $object->fill_maker2->filler('rectilinear'),
|
||||
support => $object->fill_maker2->filler($pattern),
|
||||
);
|
||||
|
||||
my $interface_angle = $self->object_config->support_material_angle + 90;
|
||||
@ -635,7 +681,8 @@ sub generate_toolpaths {
|
||||
|
||||
if (0) {
|
||||
require "Slic3r/SVG.pm";
|
||||
Slic3r::SVG::output("layer_" . $z . ".svg",
|
||||
Slic3r::SVG::output("out\\layer_" . $z . ".svg",
|
||||
blue_expolygons => union_ex($base),
|
||||
red_expolygons => union_ex($contact),
|
||||
green_expolygons => union_ex($interface),
|
||||
);
|
||||
@ -718,8 +765,8 @@ sub generate_toolpaths {
|
||||
|
||||
# interface and contact infill
|
||||
if (@$interface || @$contact_infill) {
|
||||
$fillers{interface}->angle($interface_angle);
|
||||
$fillers{interface}->spacing($_interface_flow->spacing);
|
||||
$fillers{interface}->set_angle($interface_angle);
|
||||
$fillers{interface}->set_spacing($_interface_flow->spacing);
|
||||
|
||||
# find centerline of the external loop
|
||||
$interface = offset2($interface, +scaled_epsilon, -(scaled_epsilon + $_interface_flow->scaled_width/2));
|
||||
@ -745,7 +792,7 @@ sub generate_toolpaths {
|
||||
|
||||
my @paths = ();
|
||||
foreach my $expolygon (@{union_ex($interface)}) {
|
||||
my @p = $fillers{interface}->fill_surface(
|
||||
my $polylines = $fillers{interface}->fill_surface(
|
||||
Slic3r::Surface->new(expolygon => $expolygon, surface_type => S_TYPE_INTERNAL),
|
||||
density => $interface_density,
|
||||
layer_height => $layer->height,
|
||||
@ -759,7 +806,7 @@ sub generate_toolpaths {
|
||||
mm3_per_mm => $mm3_per_mm,
|
||||
width => $_interface_flow->width,
|
||||
height => $layer->height,
|
||||
), @p;
|
||||
), @$polylines,
|
||||
}
|
||||
|
||||
$layer->support_interface_fills->append(@paths);
|
||||
@ -768,11 +815,11 @@ sub generate_toolpaths {
|
||||
# support or flange
|
||||
if (@$base) {
|
||||
my $filler = $fillers{support};
|
||||
$filler->angle($angles[ ($layer_id) % @angles ]);
|
||||
$filler->set_angle($angles[ ($layer_id) % @angles ]);
|
||||
|
||||
# We don't use $base_flow->spacing because we need a constant spacing
|
||||
# value that guarantees that all layers are correctly aligned.
|
||||
$filler->spacing($flow->spacing);
|
||||
$filler->set_spacing($flow->spacing);
|
||||
|
||||
my $density = $support_density;
|
||||
my $base_flow = $_flow;
|
||||
@ -780,18 +827,27 @@ sub generate_toolpaths {
|
||||
# find centerline of the external loop/extrusions
|
||||
my $to_infill = offset2_ex($base, +scaled_epsilon, -(scaled_epsilon + $_flow->scaled_width/2));
|
||||
|
||||
if (0) {
|
||||
require "Slic3r/SVG.pm";
|
||||
Slic3r::SVG::output("out\\to_infill_base" . $z . ".svg",
|
||||
red_expolygons => union_ex($contact),
|
||||
green_expolygons => union_ex($interface),
|
||||
blue_expolygons => $to_infill,
|
||||
);
|
||||
}
|
||||
|
||||
my @paths = ();
|
||||
|
||||
# base flange
|
||||
if ($layer_id == 0) {
|
||||
$filler = $fillers{interface};
|
||||
$filler->angle($self->object_config->support_material_angle + 90);
|
||||
$filler->set_angle($self->object_config->support_material_angle + 90);
|
||||
$density = 0.5;
|
||||
$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
|
||||
$filler->spacing($base_flow->spacing);
|
||||
$filler->set_spacing($base_flow->spacing);
|
||||
} elsif ($with_sheath) {
|
||||
# draw a perimeter all around support infill
|
||||
# TODO: use brim ordering algorithm
|
||||
@ -808,9 +864,8 @@ sub generate_toolpaths {
|
||||
$to_infill = offset_ex([ map @$_, @$to_infill ], -$_flow->scaled_spacing);
|
||||
}
|
||||
|
||||
my $mm3_per_mm = $base_flow->mm3_per_mm;
|
||||
foreach my $expolygon (@$to_infill) {
|
||||
my @p = $filler->fill_surface(
|
||||
my $polylines = $filler->fill_surface(
|
||||
Slic3r::Surface->new(expolygon => $expolygon, surface_type => S_TYPE_INTERNAL),
|
||||
density => $density,
|
||||
layer_height => $layer->height,
|
||||
@ -820,10 +875,10 @@ sub generate_toolpaths {
|
||||
push @paths, map Slic3r::ExtrusionPath->new(
|
||||
polyline => Slic3r::Polyline->new(@$_),
|
||||
role => EXTR_ROLE_SUPPORTMATERIAL,
|
||||
mm3_per_mm => $mm3_per_mm,
|
||||
mm3_per_mm => $base_flow->mm3_per_mm,
|
||||
width => $base_flow->width,
|
||||
height => $layer->height,
|
||||
), @p;
|
||||
), @$polylines;
|
||||
}
|
||||
|
||||
$layer->support_fills->append(@paths);
|
||||
@ -864,8 +919,11 @@ sub generate_pillars_shape {
|
||||
my $pillar_size = scale PILLAR_SIZE;
|
||||
my $pillar_spacing = scale PILLAR_SPACING;
|
||||
|
||||
# A regular grid of pillars, filling the 2D bounding box.
|
||||
# arrayref of polygons
|
||||
my $grid; # arrayref of polygons
|
||||
{
|
||||
# Rectangle with a side of 2.5x2.5mm.
|
||||
my $pillar = Slic3r::Polygon->new(
|
||||
[0,0],
|
||||
[$pillar_size, 0],
|
||||
@ -873,7 +931,9 @@ sub generate_pillars_shape {
|
||||
[0, $pillar_size],
|
||||
);
|
||||
|
||||
# A regular grid of pillars, filling the 2D bounding box.
|
||||
my @pillars = ();
|
||||
# 2D bounding box of the projection of all contact polygons.
|
||||
my $bb = Slic3r::Geometry::BoundingBox->new_from_points([ map @$_, map @$_, values %$contact ]);
|
||||
for (my $x = $bb->x_min; $x <= $bb->x_max-$pillar_size; $x += $pillar_spacing) {
|
||||
for (my $y = $bb->y_min; $y <= $bb->y_max-$pillar_size; $y += $pillar_spacing) {
|
||||
|
@ -88,6 +88,7 @@ src/libslic3r/PrintConfig.cpp
|
||||
src/libslic3r/PrintConfig.hpp
|
||||
src/libslic3r/PrintObject.cpp
|
||||
src/libslic3r/PrintRegion.cpp
|
||||
src/libslic3r/SupportMaterial.cpp
|
||||
src/libslic3r/SupportMaterial.hpp
|
||||
src/libslic3r/Surface.cpp
|
||||
src/libslic3r/Surface.hpp
|
||||
|
@ -229,6 +229,21 @@ sub new {
|
||||
return $self;
|
||||
}
|
||||
|
||||
package Slic3r::Print::SupportMaterial2;
|
||||
|
||||
sub new {
|
||||
my ($class, %args) = @_;
|
||||
|
||||
return $class->_new(
|
||||
$args{print_config}, # required
|
||||
$args{object_config}, # required
|
||||
$args{first_layer_flow}, # required
|
||||
$args{flow}, # required
|
||||
$args{interface_flow}, # required
|
||||
$args{soluble_interface} // 0
|
||||
);
|
||||
}
|
||||
|
||||
package Slic3r::GUI::_3DScene::GLVertexArray;
|
||||
sub CLONE_SKIP { 1 }
|
||||
|
||||
@ -283,6 +298,7 @@ for my $class (qw(
|
||||
Slic3r::Print::State
|
||||
Slic3r::Surface
|
||||
Slic3r::Surface::Collection
|
||||
Slic3r::Print::SupportMaterial2
|
||||
Slic3r::TriangleMesh
|
||||
))
|
||||
{
|
||||
|
@ -14,13 +14,6 @@
|
||||
|
||||
namespace Slic3r {
|
||||
|
||||
Fill* Fill::new_from_type(const std::string &type)
|
||||
{
|
||||
static t_config_enum_values enum_keys_map = ConfigOptionEnum<InfillPattern>::get_enum_values();
|
||||
t_config_enum_values::const_iterator it = enum_keys_map.find(type);
|
||||
return (it == enum_keys_map.end()) ? NULL : new_from_type(InfillPattern(it->second));
|
||||
}
|
||||
|
||||
Fill* Fill::new_from_type(const InfillPattern type)
|
||||
{
|
||||
switch (type) {
|
||||
@ -39,6 +32,13 @@ Fill* Fill::new_from_type(const InfillPattern type)
|
||||
}
|
||||
}
|
||||
|
||||
Fill* Fill::new_from_type(const std::string &type)
|
||||
{
|
||||
static t_config_enum_values enum_keys_map = ConfigOptionEnum<InfillPattern>::get_enum_values();
|
||||
t_config_enum_values::const_iterator it = enum_keys_map.find(type);
|
||||
return (it == enum_keys_map.end()) ? NULL : new_from_type(InfillPattern(it->second));
|
||||
}
|
||||
|
||||
Polylines Fill::fill_surface(const Surface *surface, const FillParams ¶ms)
|
||||
{
|
||||
// Perform offset.
|
||||
|
@ -7,6 +7,7 @@
|
||||
|
||||
#include "../libslic3r.h"
|
||||
#include "../BoundingBox.hpp"
|
||||
#include "../PrintConfig.hpp"
|
||||
|
||||
namespace Slic3r {
|
||||
|
||||
@ -52,6 +53,7 @@ public:
|
||||
public:
|
||||
virtual ~Fill() {}
|
||||
|
||||
static Fill* Fill::new_from_type(const InfillPattern type);
|
||||
static Fill* new_from_type(const std::string &type);
|
||||
|
||||
void set_bounding_box(const Slic3r::BoundingBox &bbox) { bounding_box = bbox; }
|
||||
|
@ -77,10 +77,11 @@ Flow::mm3_per_mm() const {
|
||||
}
|
||||
|
||||
/* This static method returns bridge width for a given nozzle diameter. */
|
||||
float
|
||||
Flow::_bridge_width(float nozzle_diameter, float bridge_flow_ratio) {
|
||||
if (bridge_flow_ratio == 1) return nozzle_diameter; // optimization to avoid sqrt()
|
||||
return sqrt(bridge_flow_ratio * (nozzle_diameter*nozzle_diameter));
|
||||
float Flow::_bridge_width(float nozzle_diameter, float bridge_flow_ratio) {
|
||||
return (bridge_flow_ratio == 1.) ?
|
||||
// optimization to avoid sqrt()
|
||||
nozzle_diameter :
|
||||
sqrt(bridge_flow_ratio) * nozzle_diameter;
|
||||
}
|
||||
|
||||
/* This static method returns a sane extrusion width default. */
|
||||
|
@ -26,7 +26,8 @@ class LayerRegion
|
||||
|
||||
public:
|
||||
Layer* layer();
|
||||
PrintRegion* region();
|
||||
PrintRegion* region() { return this->_region; }
|
||||
const PrintRegion* region() const { return this->_region; }
|
||||
|
||||
// collection of surfaces generated by slicing the original geometry
|
||||
// divided by type top/bottom/internal
|
||||
|
@ -28,12 +28,6 @@ LayerRegion::layer()
|
||||
return this->_layer;
|
||||
}
|
||||
|
||||
PrintRegion*
|
||||
LayerRegion::region()
|
||||
{
|
||||
return this->_region;
|
||||
}
|
||||
|
||||
Flow
|
||||
LayerRegion::flow(FlowRole role, bool bridge, double width) const
|
||||
{
|
||||
|
@ -120,7 +120,9 @@ public:
|
||||
size_t total_layer_count() const;
|
||||
size_t layer_count() const;
|
||||
void clear_layers();
|
||||
Layer* get_layer(int idx);
|
||||
Layer* get_layer(int idx) { return this->layers.at(idx); }
|
||||
const Layer* get_layer(int idx) const { return this->layers.at(idx); }
|
||||
|
||||
// print_z: top of the layer; slice_z: center of the layer.
|
||||
Layer* add_layer(int id, coordf_t height, coordf_t print_z, coordf_t slice_z);
|
||||
void delete_layer(int idx);
|
||||
|
@ -149,12 +149,6 @@ PrintObject::clear_layers()
|
||||
this->delete_layer(i);
|
||||
}
|
||||
|
||||
Layer*
|
||||
PrintObject::get_layer(int idx)
|
||||
{
|
||||
return this->layers.at(idx);
|
||||
}
|
||||
|
||||
Layer*
|
||||
PrintObject::add_layer(int id, coordf_t height, coordf_t print_z, coordf_t slice_z)
|
||||
{
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -3,6 +3,8 @@
|
||||
|
||||
namespace Slic3r {
|
||||
|
||||
class PrintObject;
|
||||
|
||||
// how much we extend support around the actual contact area
|
||||
#define SUPPORT_MATERIAL_MARGIN 1.5
|
||||
|
||||
@ -43,7 +45,7 @@ public:
|
||||
}
|
||||
|
||||
bool operator==(const MyLayer &layer2) const {
|
||||
return print_z == layer2.printz && height == layer2.height && bridging == layer2.bridging;
|
||||
return print_z == layer2.print_z && height == layer2.height && bridging == layer2.bridging;
|
||||
}
|
||||
|
||||
bool operator<(const MyLayer &layer2) const {
|
||||
@ -90,50 +92,59 @@ public:
|
||||
// top or bottom extreme
|
||||
bool is_top;
|
||||
|
||||
coordf_t z() const { return is_top ? layer->print_z : layer->print_z - height; }
|
||||
coordf_t z() const { return is_top ? layer->print_z : layer->print_z - layer->height; }
|
||||
|
||||
bool operator<(const LayerExtreme &other) const { return z() < other.z(); }
|
||||
}
|
||||
};
|
||||
|
||||
struct LayerPrintZ_Hash {
|
||||
static size_t operator(const MyLayer &layer) {
|
||||
return std::hash<double>(layer.print_z)^std::hash<double>(layer.height)^size_t(layer.bridging);
|
||||
size_t operator()(const MyLayer &layer) const {
|
||||
return std::hash<double>()(layer.print_z)^std::hash<double>()(layer.height)^size_t(layer.bridging);
|
||||
}
|
||||
};
|
||||
|
||||
typedef std::set<MyLayer, LayerPrintZ_Hash> MyLayersSet;
|
||||
typedef std::vector<Layer*> MyLayersPtr;
|
||||
typedef std::deque<Layer> MyLayersDeque;
|
||||
typedef std::deque<Layer> MyLayerStorage;
|
||||
typedef std::vector<MyLayer*> MyLayersPtr;
|
||||
typedef std::deque<MyLayer> MyLayerStorage;
|
||||
|
||||
public:
|
||||
PrintSupportMaterial() :
|
||||
m_object(NULL),
|
||||
m_print_config(NULL),
|
||||
m_object_config(NULL),
|
||||
m_soluble_interface(false),
|
||||
PrintSupportMaterial(
|
||||
const PrintConfig *print_config,
|
||||
const PrintObjectConfig *object_config,
|
||||
const Flow &flow,
|
||||
const Flow &first_layer_flow,
|
||||
const Flow &interface_flow,
|
||||
bool soluble_interface) :
|
||||
m_print_config(print_config),
|
||||
m_object_config(object_config),
|
||||
m_flow(flow),
|
||||
m_first_layer_flow(first_layer_flow),
|
||||
m_interface_flow(interface_flow),
|
||||
m_soluble_interface(soluble_interface),
|
||||
m_support_layer_height_max(0.),
|
||||
m_support_interface_layer_height_max(0.)
|
||||
{}
|
||||
|
||||
void setup(
|
||||
const PrintConfig *print_config;
|
||||
const ObjectConfig *object_config;
|
||||
Flow flow;
|
||||
Flow first_layer_flow;
|
||||
Flow interface_flow;
|
||||
bool soluble_interface)
|
||||
{
|
||||
this->m_object = object;
|
||||
this->m_print_config = print_config;
|
||||
this->m_object_config = object_config;
|
||||
this->m_flow = flow;
|
||||
this->m_first_layer_flow = first_layer_flow;
|
||||
this->m_interface_flow = interface_flow;
|
||||
this->m_soluble_interface = soluble_interface;
|
||||
}
|
||||
PrintSupportMaterial(
|
||||
PrintConfig *print_config,
|
||||
PrintObjectConfig *object_config,
|
||||
Flow *flow,
|
||||
Flow *first_layer_flow,
|
||||
Flow *interface_flow,
|
||||
bool soluble_interface) :
|
||||
m_print_config(print_config),
|
||||
m_object_config(object_config),
|
||||
m_flow(*flow),
|
||||
m_first_layer_flow(*first_layer_flow),
|
||||
m_interface_flow(*interface_flow),
|
||||
m_soluble_interface(soluble_interface),
|
||||
m_support_layer_height_max(0.),
|
||||
m_support_interface_layer_height_max(0.)
|
||||
{}
|
||||
|
||||
void generate(const PrintObject *object);
|
||||
// Generate support material for the object.
|
||||
// New support layers will be added to the object,
|
||||
// with extrusion paths and islands filled in for each support layer.
|
||||
void generate(PrintObject &object);
|
||||
|
||||
private:
|
||||
// Generate top contact layers supporting overhangs.
|
||||
@ -146,26 +157,29 @@ private:
|
||||
// otherwise set the layer height to a bridging flow of a support interface nozzle.
|
||||
MyLayersPtr bottom_contact_layers(const PrintObject &object, const MyLayersPtr &top_contacts, MyLayerStorage &layer_storage) const;
|
||||
|
||||
// Trim the top_contacts layers with the bottom_contacts layers if they overlap, so there would not be enough vertical space for both of them.
|
||||
void trim_top_contacts_by_bottom_contacts(const PrintObject &object, const MyLayersPtr &bottom_contacts, MyLayersPtr &top_contacts) const;
|
||||
|
||||
// Generate raft layers and the intermediate support layers between the bottom contact and top contact surfaces.
|
||||
MyLayersPtr raft_and_intermediate_support_layers(
|
||||
const PrintObject &object,
|
||||
const MyLayersPtr &bottom_contacts,
|
||||
const MyLayersPtr &top_contacts,
|
||||
MyLayerStorage &layer_storage,
|
||||
const coordf_t max_object_layer_height);
|
||||
const coordf_t max_object_layer_height) const;
|
||||
|
||||
void generate_base_layers(
|
||||
const PrintObject &object,
|
||||
const MyLayersPtr &bottom_contacts,
|
||||
const MyLayersPtr &top_contacts,
|
||||
MyLayersPtr &intermediate_layers);
|
||||
MyLayersPtr &intermediate_layers) const;
|
||||
|
||||
MyLayersPtr generate_interface_layers(
|
||||
const PrintObject &object,
|
||||
const MyLayersPtr &bottom_contacts,
|
||||
const MyLayersPtr &top_contacts,
|
||||
MyLayersPtr &intermediate_layers,
|
||||
MyLayerStorage &layer_storage);
|
||||
MyLayerStorage &layer_storage) const;
|
||||
|
||||
/*
|
||||
void generate_pillars_shape();
|
||||
@ -178,10 +192,10 @@ private:
|
||||
const MyLayersPtr &bottom_contacts,
|
||||
const MyLayersPtr &top_contacts,
|
||||
const MyLayersPtr &intermediate_layers,
|
||||
const MyLayersPtr &interface_layers);
|
||||
const MyLayersPtr &interface_layers) const;
|
||||
|
||||
const PrintConfig *m_print_config;
|
||||
const ObjectConfig *m_object_config;
|
||||
const PrintObjectConfig *m_object_config;
|
||||
Flow m_flow;
|
||||
Flow m_first_layer_flow;
|
||||
Flow m_interface_flow;
|
||||
@ -189,6 +203,9 @@ private:
|
||||
|
||||
coordf_t m_support_layer_height_max;
|
||||
coordf_t m_support_interface_layer_height_max;
|
||||
bool m_synchronize_support_layers_with_object;
|
||||
};
|
||||
|
||||
#endif
|
||||
} // namespace Slic3r
|
||||
|
||||
#endif /* slic3r_SupportMaterial_hpp_ */
|
||||
|
@ -56,6 +56,7 @@ REGISTER_CLASS(PrintConfig, "Config::Print");
|
||||
REGISTER_CLASS(FullPrintConfig, "Config::Full");
|
||||
REGISTER_CLASS(Surface, "Surface");
|
||||
REGISTER_CLASS(SurfaceCollection, "Surface::Collection");
|
||||
REGISTER_CLASS(PrintSupportMaterial, "Print::SupportMaterial2");
|
||||
REGISTER_CLASS(TriangleMesh, "TriangleMesh");
|
||||
REGISTER_CLASS(GLVertexArray, "GUI::_3DScene::GLVertexArray");
|
||||
|
||||
|
@ -1,7 +1,23 @@
|
||||
%module{Slic3r::XS};
|
||||
|
||||
%{
|
||||
#include <xsinit.h>
|
||||
#include "libslic3r/SupportMaterial.hpp"
|
||||
%}
|
||||
|
||||
%name{Slic3r::Print::SupportMaterial2} class PrintSupportMaterial {
|
||||
%name{_new} PrintSupportMaterial(
|
||||
PrintConfig *print_config,
|
||||
PrintObjectConfig *object_config,
|
||||
Flow *flow,
|
||||
Flow *first_layer_flow,
|
||||
Flow *interface_flow,
|
||||
bool soluble_interface);
|
||||
~PrintSupportMaterial();
|
||||
|
||||
void generate(PrintObject *object)
|
||||
%code{% THIS->generate(*object); %};
|
||||
};
|
||||
|
||||
%package{Slic3r::Print::SupportMaterial};
|
||||
%{
|
||||
|
@ -221,6 +221,10 @@ PerimeterGenerator* O_OBJECT_SLIC3R
|
||||
Ref<PerimeterGenerator> O_OBJECT_SLIC3R_T
|
||||
Clone<PerimeterGenerator> O_OBJECT_SLIC3R_T
|
||||
|
||||
PrintSupportMaterial* O_OBJECT_SLIC3R
|
||||
Ref<PrintSupportMaterial> O_OBJECT_SLIC3R_T
|
||||
Clone<PrintSupportMaterial> O_OBJECT_SLIC3R_T
|
||||
|
||||
GLVertexArray* O_OBJECT_SLIC3R
|
||||
|
||||
Axis T_UV
|
||||
|
@ -141,6 +141,10 @@
|
||||
%typemap{SupportLayer*};
|
||||
%typemap{Ref<SupportLayer>}{simple};
|
||||
|
||||
%typemap{PrintSupportMaterial*};
|
||||
%typemap{Ref<PrintSupportMaterial>}{simple};
|
||||
%typemap{Clone<PrintSupportMaterial>}{simple};
|
||||
|
||||
%typemap{PlaceholderParser*};
|
||||
%typemap{Ref<PlaceholderParser>}{simple};
|
||||
%typemap{Clone<PlaceholderParser>}{simple};
|
||||
|
Loading…
Reference in New Issue
Block a user