Ported some methods to XS
This commit is contained in:
parent
1813a309a7
commit
380dd8adfc
13 changed files with 176 additions and 93 deletions
|
@ -135,7 +135,7 @@ sub process_layer {
|
|||
}
|
||||
|
||||
# tweak region ordering to save toolchanges
|
||||
my @region_ids = 0 .. ($self->print->regions_count-1);
|
||||
my @region_ids = 0 .. ($self->print->region_count-1);
|
||||
if ($self->gcodegen->multiple_extruders) {
|
||||
my $last_extruder = $self->gcodegen->extruder;
|
||||
my $best_region_id = first { $self->print->regions->[$_]->config->perimeter_extruder-1 eq $last_extruder } @region_ids;
|
||||
|
|
|
@ -135,7 +135,7 @@ sub set_z {
|
|||
my $interlaced = (defined first { $_->config->support_material } @{$print->objects})
|
||||
|| (defined first { $_->config->infill_every_layers > 1 } @{$print->regions});
|
||||
|
||||
my $max_layer_height = $print->max_layer_height;
|
||||
my $max_layer_height = $print->max_allowed_layer_height;
|
||||
|
||||
my @layers = ();
|
||||
foreach my $object (@{$print->objects}) {
|
||||
|
|
|
@ -39,24 +39,6 @@ sub regions {
|
|||
return [ map $self->get_region($_), 0..($self->region_count-1) ];
|
||||
}
|
||||
|
||||
# merge all regions' slices to get islands
|
||||
sub make_slices {
|
||||
my $self = shift;
|
||||
|
||||
my $slices;
|
||||
if (@{$self->regions} == 1) {
|
||||
$slices = [ map $_->expolygon->clone, @{$self->regions->[0]->slices} ];
|
||||
} else {
|
||||
$slices = union_ex([ map $_->p, map @{$_->slices}, @{$self->regions} ]);
|
||||
}
|
||||
|
||||
# sort slices
|
||||
$slices = [ @$slices[@{chained_path([ map $_->contour->first_point, @$slices ])}] ];
|
||||
|
||||
$self->slices->clear;
|
||||
$self->slices->append(@$slices);
|
||||
}
|
||||
|
||||
sub merge_slices {
|
||||
my ($self) = @_;
|
||||
$_->merge_slices for @{$self->regions};
|
||||
|
|
|
@ -148,13 +148,6 @@ sub apply_config {
|
|||
return $invalidated;
|
||||
}
|
||||
|
||||
sub has_support_material {
|
||||
my $self = shift;
|
||||
return (first { $_->config->support_material } @{$self->objects})
|
||||
|| (first { $_->config->raft_layers > 0 } @{$self->objects})
|
||||
|| (first { $_->config->support_material_enforce_layers > 0 } @{$self->objects});
|
||||
}
|
||||
|
||||
# caller is responsible for supplying models whose objects don't collide
|
||||
# and have explicit instance positions
|
||||
sub add_model_object {
|
||||
|
@ -311,43 +304,6 @@ sub validate {
|
|||
}
|
||||
}
|
||||
|
||||
# 0-based indices of used extruders
|
||||
sub extruders {
|
||||
my ($self) = @_;
|
||||
|
||||
# initialize all extruder(s) we need
|
||||
my @used_extruders = ();
|
||||
foreach my $region (@{$self->regions}) {
|
||||
push @used_extruders,
|
||||
map $region->config->get("${_}_extruder")-1,
|
||||
qw(perimeter infill);
|
||||
}
|
||||
foreach my $object (@{$self->objects}) {
|
||||
push @used_extruders,
|
||||
map $object->config->get("${_}_extruder")-1,
|
||||
qw(support_material support_material_interface);
|
||||
}
|
||||
|
||||
my %h = map { $_ => 1 } @used_extruders;
|
||||
return [ sort keys %h ];
|
||||
}
|
||||
|
||||
sub init_extruders {
|
||||
my $self = shift;
|
||||
|
||||
return if $self->step_done(STEP_INIT_EXTRUDERS);
|
||||
$self->set_step_started(STEP_INIT_EXTRUDERS);
|
||||
|
||||
# enforce tall skirt if using ooze_prevention
|
||||
# FIXME: this is not idempotent (i.e. switching ooze_prevention off will not revert skirt settings)
|
||||
if ($self->config->ooze_prevention && @{$self->extruders} > 1) {
|
||||
$self->config->set('skirt_height', -1);
|
||||
$self->config->set('skirts', 1) if $self->config->skirts == 0;
|
||||
}
|
||||
|
||||
$self->set_step_done(STEP_INIT_EXTRUDERS);
|
||||
}
|
||||
|
||||
# this value is not supposed to be compared with $layer->id
|
||||
# since they have different semantics
|
||||
sub total_layer_count {
|
||||
|
@ -355,16 +311,6 @@ sub total_layer_count {
|
|||
return max(map $_->total_layer_count, @{$self->objects});
|
||||
}
|
||||
|
||||
sub regions_count {
|
||||
my $self = shift;
|
||||
return scalar @{$self->regions};
|
||||
}
|
||||
|
||||
sub max_layer_height {
|
||||
my ($self) = @_;
|
||||
return max(@{$self->config->nozzle_diameter});
|
||||
}
|
||||
|
||||
# the bounding box of objects placed in copies position
|
||||
# (without taking skirt/brim/support material into account)
|
||||
sub bounding_box {
|
||||
|
@ -410,16 +356,6 @@ sub size {
|
|||
return $self->bounding_box->size;
|
||||
}
|
||||
|
||||
sub _simplify_slices {
|
||||
my $self = shift;
|
||||
my ($distance) = @_;
|
||||
|
||||
foreach my $layer (map @{$_->layers}, @{$self->objects}) {
|
||||
$layer->slices->simplify($distance);
|
||||
$_->slices->simplify($distance) for @{$layer->regions};
|
||||
}
|
||||
}
|
||||
|
||||
sub process {
|
||||
my ($self) = @_;
|
||||
|
||||
|
|
|
@ -173,7 +173,7 @@ sub slice {
|
|||
}
|
||||
|
||||
# make sure all layers contain layer region objects for all regions
|
||||
my $regions_count = $self->print->regions_count;
|
||||
my $regions_count = $self->print->region_count;
|
||||
foreach my $layer (@{ $self->layers }) {
|
||||
$layer->region($_) for 0 .. ($regions_count-1);
|
||||
}
|
||||
|
@ -427,7 +427,7 @@ sub make_perimeters {
|
|||
# but we don't generate any extra perimeter if fill density is zero, as they would be floating
|
||||
# inside the object - infill_only_where_needed should be the method of choice for printing
|
||||
# hollow objects
|
||||
for my $region_id (0 .. ($self->print->regions_count-1)) {
|
||||
for my $region_id (0 .. ($self->print->region_count-1)) {
|
||||
my $region = $self->print->regions->[$region_id];
|
||||
my $region_perimeters = $region->config->perimeters;
|
||||
|
||||
|
@ -555,7 +555,7 @@ sub infill {
|
|||
threads => $self->print->config->threads,
|
||||
items => sub {
|
||||
my @items = (); # [layer_id, region_id]
|
||||
for my $region_id (0 .. ($self->print->regions_count-1)) {
|
||||
for my $region_id (0 .. ($self->print->region_count-1)) {
|
||||
push @items, map [$_, $region_id], 0..($self->layer_count - 1);
|
||||
}
|
||||
@items;
|
||||
|
@ -627,7 +627,7 @@ sub detect_surfaces_type {
|
|||
my $self = shift;
|
||||
Slic3r::debugf "Detecting solid surfaces...\n";
|
||||
|
||||
for my $region_id (0 .. ($self->print->regions_count-1)) {
|
||||
for my $region_id (0 .. ($self->print->region_count-1)) {
|
||||
for my $i (0 .. ($self->layer_count - 1)) {
|
||||
my $layerm = $self->get_layer($i)->regions->[$region_id];
|
||||
|
||||
|
@ -885,7 +885,7 @@ sub bridge_over_infill {
|
|||
sub process_external_surfaces {
|
||||
my ($self) = @_;
|
||||
|
||||
for my $region_id (0 .. ($self->print->regions_count-1)) {
|
||||
for my $region_id (0 .. ($self->print->region_count-1)) {
|
||||
$self->get_layer(0)->regions->[$region_id]->process_external_surfaces(undef);
|
||||
for my $i (1 .. ($self->layer_count - 1)) {
|
||||
$self->get_layer($i)->regions->[$region_id]->process_external_surfaces($self->get_layer($i-1));
|
||||
|
@ -898,7 +898,7 @@ sub discover_horizontal_shells {
|
|||
|
||||
Slic3r::debugf "==> DISCOVERING HORIZONTAL SHELLS\n";
|
||||
|
||||
for my $region_id (0 .. ($self->print->regions_count-1)) {
|
||||
for my $region_id (0 .. ($self->print->region_count-1)) {
|
||||
for (my $i = 0; $i < $self->layer_count; $i++) {
|
||||
my $layerm = $self->get_layer($i)->regions->[$region_id];
|
||||
|
||||
|
@ -1048,7 +1048,7 @@ sub combine_infill {
|
|||
|
||||
my @layer_heights = map $_->height, @{$self->layers};
|
||||
|
||||
for my $region_id (0 .. ($self->print->regions_count-1)) {
|
||||
for my $region_id (0 .. ($self->print->region_count-1)) {
|
||||
my $region = $self->print->regions->[$region_id];
|
||||
my $every = $region->config->infill_every_layers;
|
||||
|
||||
|
|
|
@ -1,4 +1,7 @@
|
|||
#include "Layer.hpp"
|
||||
#include "ClipperUtils.hpp"
|
||||
#include "Geometry.hpp"
|
||||
#include "Print.hpp"
|
||||
|
||||
|
||||
namespace Slic3r {
|
||||
|
@ -108,6 +111,42 @@ Layer::delete_region(int idx)
|
|||
delete item;
|
||||
}
|
||||
|
||||
// merge all regions' slices to get islands
|
||||
void
|
||||
Layer::make_slices()
|
||||
{
|
||||
ExPolygons slices;
|
||||
if (this->regions.size() == 1) {
|
||||
// optimization: if we only have one region, take its slices
|
||||
slices = this->regions.front()->slices;
|
||||
} else {
|
||||
Polygons slices_p;
|
||||
FOREACH_LAYERREGION(this, layerm) {
|
||||
Polygons region_slices_p = (*layerm)->slices;
|
||||
slices_p.insert(slices_p.end(), region_slices_p.begin(), region_slices_p.end());
|
||||
}
|
||||
union_(slices_p, slices);
|
||||
}
|
||||
|
||||
this->slices.expolygons.clear();
|
||||
this->slices.expolygons.reserve(slices.size());
|
||||
|
||||
// prepare ordering points
|
||||
Points ordering_points;
|
||||
ordering_points.reserve(slices.size());
|
||||
for (ExPolygons::const_iterator ex = slices.begin(); ex != slices.end(); ++ex)
|
||||
ordering_points.push_back(ex->contour.first_point());
|
||||
|
||||
// sort slices
|
||||
std::vector<Points::size_type> order;
|
||||
Slic3r::Geometry::chained_path(ordering_points, order);
|
||||
|
||||
// populate slices vector
|
||||
for (std::vector<Points::size_type>::const_iterator it = order.begin(); it != order.end(); ++it) {
|
||||
this->slices.expolygons.push_back(slices[*it]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#ifdef SLIC3RXS
|
||||
REGISTER_CLASS(Layer, "Layer");
|
||||
|
|
|
@ -84,6 +84,8 @@ class Layer {
|
|||
size_t region_count();
|
||||
LayerRegion* get_region(int idx);
|
||||
LayerRegion* add_region(PrintRegion* print_region);
|
||||
|
||||
void make_slices();
|
||||
|
||||
protected:
|
||||
int _id; // sequential number of layer, 0-based
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#include "Print.hpp"
|
||||
#include "BoundingBox.hpp"
|
||||
#include <algorithm>
|
||||
|
||||
namespace Slic3r {
|
||||
|
||||
|
@ -511,7 +512,7 @@ Print::invalidate_step(PrintStep step)
|
|||
if (step == psSkirt) {
|
||||
this->invalidate_step(psBrim);
|
||||
} else if (step == psInitExtruders) {
|
||||
for (PrintObjectPtrs::iterator object = this->objects.begin(); object != this->objects.end(); ++object) {
|
||||
FOREACH_OBJECT(this, object) {
|
||||
(*object)->invalidate_step(posPerimeters);
|
||||
(*object)->invalidate_step(posSupportMaterial);
|
||||
}
|
||||
|
@ -533,6 +534,77 @@ Print::invalidate_all_steps()
|
|||
return invalidated;
|
||||
}
|
||||
|
||||
// returns 0-based indices of used extruders
|
||||
std::set<size_t>
|
||||
Print::extruders() const
|
||||
{
|
||||
std::set<size_t> extruders;
|
||||
|
||||
FOREACH_REGION(this, region) {
|
||||
extruders.insert((*region)->config.perimeter_extruder - 1);
|
||||
extruders.insert((*region)->config.infill_extruder - 1);
|
||||
}
|
||||
FOREACH_OBJECT(this, object) {
|
||||
extruders.insert((*object)->config.support_material_extruder - 1);
|
||||
extruders.insert((*object)->config.support_material_interface_extruder - 1);
|
||||
}
|
||||
|
||||
return extruders;
|
||||
}
|
||||
|
||||
void
|
||||
Print::_simplify_slices(double distance)
|
||||
{
|
||||
FOREACH_OBJECT(this, object) {
|
||||
FOREACH_LAYER(*object, layer) {
|
||||
(*layer)->slices.simplify(distance);
|
||||
FOREACH_LAYERREGION(*layer, layerm) {
|
||||
(*layerm)->slices.simplify(distance);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
double
|
||||
Print::max_allowed_layer_height() const
|
||||
{
|
||||
std::vector<double> nozzle_diameter;
|
||||
|
||||
std::set<size_t> extruders = this->extruders();
|
||||
for (std::set<size_t>::const_iterator e = extruders.begin(); e != extruders.end(); ++e) {
|
||||
nozzle_diameter.push_back(this->config.nozzle_diameter.get_at(*e));
|
||||
}
|
||||
|
||||
return *std::max_element(nozzle_diameter.begin(), nozzle_diameter.end());
|
||||
}
|
||||
|
||||
void
|
||||
Print::init_extruders()
|
||||
{
|
||||
if (this->state.is_done(psInitExtruders)) return;
|
||||
this->state.set_done(psInitExtruders);
|
||||
|
||||
// enforce tall skirt if using ooze_prevention
|
||||
// FIXME: this is not idempotent (i.e. switching ooze_prevention off will not revert skirt settings)
|
||||
if (this->config.ooze_prevention && this->extruders().size() > 1) {
|
||||
this->config.skirt_height.value = -1;
|
||||
if (this->config.skirts == 0) this->config.skirts.value = 1;
|
||||
}
|
||||
|
||||
this->state.set_done(psInitExtruders);
|
||||
}
|
||||
|
||||
bool
|
||||
Print::has_support_material() const
|
||||
{
|
||||
FOREACH_OBJECT(this, object) {
|
||||
PrintObjectConfig &config = (*object)->config;
|
||||
if (config.support_material || config.raft_layers > 0 || config.support_material_enforce_layers > 0)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
#ifdef SLIC3RXS
|
||||
REGISTER_CLASS(Print, "Print");
|
||||
|
|
|
@ -160,12 +160,25 @@ class Print
|
|||
bool invalidate_state_by_config_options(const std::vector<t_config_option_key> &opt_keys);
|
||||
bool invalidate_step(PrintStep step);
|
||||
bool invalidate_all_steps();
|
||||
|
||||
|
||||
void init_extruders();
|
||||
|
||||
std::set<size_t> extruders() const;
|
||||
void _simplify_slices(double distance);
|
||||
double max_allowed_layer_height() const;
|
||||
bool has_support_material() const;
|
||||
|
||||
private:
|
||||
void clear_regions();
|
||||
void delete_region(size_t idx);
|
||||
};
|
||||
|
||||
#define FOREACH_BASE(type, container, iterator) for (type::const_iterator iterator = (container).begin(); iterator != (container).end(); ++iterator)
|
||||
#define FOREACH_REGION(print, region) FOREACH_BASE(PrintRegionPtrs, (print)->regions, region)
|
||||
#define FOREACH_OBJECT(print, object) FOREACH_BASE(PrintObjectPtrs, (print)->objects, object)
|
||||
#define FOREACH_LAYER(object, layer) FOREACH_BASE(LayerPtrs, (object)->layers, layer)
|
||||
#define FOREACH_LAYERREGION(layer, layerm) FOREACH_BASE(LayerRegionPtrs, (layer)->regions, layerm)
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -3,6 +3,26 @@
|
|||
|
||||
namespace Slic3r {
|
||||
|
||||
SurfaceCollection::operator Polygons() const
|
||||
{
|
||||
Polygons polygons;
|
||||
for (Surfaces::const_iterator surface = this->surfaces.begin(); surface != this->surfaces.end(); ++surface) {
|
||||
Polygons surface_p = surface->expolygon;
|
||||
polygons.insert(polygons.end(), surface_p.begin(), surface_p.end());
|
||||
}
|
||||
return polygons;
|
||||
}
|
||||
|
||||
SurfaceCollection::operator ExPolygons() const
|
||||
{
|
||||
ExPolygons expp;
|
||||
expp.reserve(this->surfaces.size());
|
||||
for (Surfaces::const_iterator surface = this->surfaces.begin(); surface != this->surfaces.end(); ++surface) {
|
||||
expp.push_back(surface->expolygon);
|
||||
}
|
||||
return expp;
|
||||
}
|
||||
|
||||
void
|
||||
SurfaceCollection::simplify(double tolerance)
|
||||
{
|
||||
|
|
|
@ -10,6 +10,9 @@ class SurfaceCollection
|
|||
{
|
||||
public:
|
||||
Surfaces surfaces;
|
||||
|
||||
operator Polygons() const;
|
||||
operator ExPolygons() const;
|
||||
void simplify(double tolerance);
|
||||
void group(std::vector<SurfacesPtr> *retval);
|
||||
};
|
||||
|
|
|
@ -60,6 +60,8 @@
|
|||
|
||||
int ptr()
|
||||
%code%{ RETVAL = (int)(intptr_t)THIS; %};
|
||||
|
||||
void make_slices();
|
||||
};
|
||||
|
||||
%name{Slic3r::Layer::Support} class SupportLayer {
|
||||
|
|
|
@ -153,6 +153,20 @@ _constant()
|
|||
%code%{ THIS->state.set_done(step); %};
|
||||
void set_step_started(PrintStep step)
|
||||
%code%{ THIS->state.set_started(step); %};
|
||||
|
||||
std::vector<int> extruders()
|
||||
%code%{
|
||||
std::set<size_t> extruders = THIS->extruders();
|
||||
RETVAL.reserve(extruders.size());
|
||||
for (std::set<size_t>::const_iterator e = extruders.begin(); e != extruders.end(); ++e) {
|
||||
RETVAL.push_back(*e);
|
||||
}
|
||||
%};
|
||||
void _simplify_slices(double distance);
|
||||
double max_allowed_layer_height() const;
|
||||
bool has_support_material() const;
|
||||
|
||||
void init_extruders();
|
||||
%{
|
||||
|
||||
double
|
||||
|
|
Loading…
Reference in a new issue