Some initial work for incremental slicing

master
Alessandro Ranellucci 2014-06-11 00:15:02 +02:00
parent 5c54acf9ac
commit d2ca4c1b13
9 changed files with 199 additions and 111 deletions

View File

@ -158,7 +158,6 @@ sub thread_cleanup {
*Slic3r::Polyline::DESTROY = sub {};
*Slic3r::Polyline::Collection::DESTROY = sub {};
*Slic3r::Print::DESTROY = sub {};
*Slic3r::Print::State::DESTROY = sub {};
*Slic3r::Print::Region::DESTROY = sub {};
*Slic3r::Surface::DESTROY = sub {};
*Slic3r::Surface::Collection::DESTROY = sub {};

View File

@ -13,7 +13,6 @@ use Slic3r::Geometry::Clipper qw(diff_ex union_ex union_pt intersection_ex inter
offset2 union union_pt_chained JT_ROUND JT_SQUARE);
use Slic3r::Print::State ':steps';
our $status_cb;
sub new {
@ -49,8 +48,8 @@ sub apply_config {
if (@$print_diff) {
$self->config->apply_dynamic($config);
# TODO: only invalidate changed steps
$self->_state->invalidate_all;
$self->invalidate_all_steps
if !$self->invalidate_state_by_config_options($print_diff);
}
# handle changes to object config defaults
@ -59,6 +58,7 @@ sub apply_config {
# we don't assume that $config contains a full ObjectConfig,
# so we base it on the current print-wise default
my $new = $self->default_object_config->clone;
$new->apply_dynamic($config);
# we override the new config with object-specific options
my $model_object_config = $object->model_object->config->clone;
@ -69,8 +69,8 @@ sub apply_config {
my $diff = $object->config->diff($new);
if (@$diff) {
$object->config->apply($new);
# TODO: only invalidate changed steps
$object->_state->invalidate_all;
$object->invalidate_all_steps
if !$object->invalidate_state_by_config_options($diff);
}
}
@ -188,8 +188,8 @@ sub add_model_object {
$o->config->apply($self->default_object_config);
$o->config->apply_dynamic($object_config);
$self->_state->invalidate(STEP_SKIRT);
$self->_state->invalidate(STEP_BRIM);
$self->invalidate_step(STEP_SKIRT);
$self->invalidate_step(STEP_BRIM);
}
sub reload_object {
@ -352,20 +352,20 @@ sub process {
my $print_step = sub {
my ($step, $cb) = @_;
if (!$self->_state->done($step)) {
$self->_state->set_started($step);
if (!$self->step_done($step)) {
$self->set_step_started($step);
$cb->();
$self->_state->set_done($step);
$self->set_step_done($step);
}
};
my $object_step = sub {
my ($step, $cb) = @_;
for my $obj_idx (0..($self->object_count - 1)) {
my $object = $self->objects->[$obj_idx];
if (!$object->_state->done($step)) {
$object->_state->set_started($step);
if (!$object->step_done($step)) {
$object->set_step_started($step);
$cb->($obj_idx);
$object->_state->set_done($step);
$object->set_step_done($step);
}
}
};
@ -1082,27 +1082,6 @@ sub expanded_output_filepath {
return $self->placeholder_parser->process($path, $extra);
}
sub invalidate_step {
my ($self, $step, $obj_idx) = @_;
# invalidate $step in the correct state object
if ($Slic3r::Print::State::print_step->{$step}) {
$self->_state->invalidate($step);
} else {
# object step
if (defined $obj_idx) {
$self->objects->[$obj_idx]->_state->invalidate($step);
} else {
$_->_state->invalidate($step) for @{$self->objects};
}
}
# recursively invalidate steps depending on $step
$self->invalidate_step($_)
for grep { grep { $_ == $step } @{$Slic3r::Print::State::prereqs{$_}} }
keys %Slic3r::Print::State::prereqs;
}
# This method assigns extruders to the volumes having a material
# but not having extruders set in the material config.
sub auto_assign_extruders {

View File

@ -49,8 +49,8 @@ sub _trigger_copies {
} @{$self->copies}[@{chained_path($self->copies)}]
]);
$self->print->_state->invalidate(STEP_SKIRT);
$self->print->_state->invalidate(STEP_BRIM);
$self->print->invalidate_step(STEP_SKIRT);
$self->print->invalidate_step(STEP_BRIM);
}
# in unscaled coordinates

View File

@ -8,21 +8,4 @@ our @EXPORT_OK = qw(STEP_INIT_EXTRUDERS STEP_SLICE STEP_PERIMETERS STEP_PREPAR
STEP_INFILL STEP_SUPPORTMATERIAL STEP_SKIRT STEP_BRIM);
our %EXPORT_TAGS = (steps => \@EXPORT_OK);
our %print_steps = map { $_ => 1 } (
STEP_INIT_EXTRUDERS,
STEP_SKIRT,
STEP_BRIM,
);
our %prereqs = (
STEP_INIT_EXTRUDERS => [],
STEP_SLICE => [],
STEP_PERIMETERS => [STEP_SLICE, STEP_INIT_EXTRUDERS],
STEP_PREPARE_INFILL => [STEP_PERIMETERS],
STEP_INFILL => [STEP_INFILL],
STEP_SUPPORTMATERIAL => [STEP_SLICE, STEP_INIT_EXTRUDERS],
STEP_SKIRT => [STEP_PERIMETERS, STEP_INFILL],
STEP_BRIM => [STEP_PERIMETERS, STEP_INFILL, STEP_SKIRT],
);
1;

View File

@ -3,52 +3,56 @@
namespace Slic3r {
template <class StepClass>
bool
PrintState::started(PrintStep step) const
PrintState<StepClass>::started(StepClass step) const
{
return this->_started.find(step) != this->_started.end();
}
template <class StepClass>
bool
PrintState::done(PrintStep step) const
PrintState<StepClass>::done(StepClass step) const
{
return this->_done.find(step) != this->_done.end();
}
template <class StepClass>
void
PrintState::set_started(PrintStep step)
PrintState<StepClass>::set_started(StepClass step)
{
this->_started.insert(step);
}
template <class StepClass>
void
PrintState::set_done(PrintStep step)
PrintState<StepClass>::set_done(StepClass step)
{
this->_done.insert(step);
}
template <class StepClass>
void
PrintState::invalidate(PrintStep step)
PrintState<StepClass>::invalidate(StepClass step)
{
this->_started.erase(step);
this->_done.erase(step);
}
template <class StepClass>
void
PrintState::invalidate_all()
PrintState<StepClass>::invalidate_all()
{
this->_started.clear();
this->_done.clear();
}
#ifdef SLIC3RXS
REGISTER_CLASS(PrintState, "Print::State");
#endif
template class PrintState<PrintStep>;
template class PrintState<PrintObjectStep>;
PrintRegion::PrintRegion(Print* print)
: config(), _print(print)
: _print(print)
{
}
@ -67,8 +71,7 @@ REGISTER_CLASS(PrintRegion, "Print::Region");
#endif
PrintObject::PrintObject(Print* print, ModelObject* model_object,
const BoundingBoxf3 &modobj_bbox)
PrintObject::PrintObject(Print* print, ModelObject* model_object, const BoundingBoxf3 &modobj_bbox)
: _print(print),
_model_object(model_object)
{
@ -139,8 +142,7 @@ PrintObject::get_layer(int idx)
}
Layer*
PrintObject::add_layer(int id, coordf_t height, coordf_t print_z,
coordf_t slice_z)
PrintObject::add_layer(int id, coordf_t height, coordf_t print_z, coordf_t slice_z)
{
Layer* layer = new Layer(id, this, height, print_z, slice_z);
layers.push_back(layer);
@ -191,6 +193,68 @@ PrintObject::delete_support_layer(int idx)
this->support_layers.erase(i);
}
bool
PrintObject::invalidate_state_by_config_options(const std::vector<t_config_option_key> &opt_keys)
{
std::set<PrintObjectStep> steps;
// this method only accepts PrintObjectConfig option keys
for (std::vector<t_config_option_key>::const_iterator opt_key = opt_keys.begin(); opt_key != opt_keys.end(); ++opt_key) {
if (*opt_key == "perimeters") {
steps.insert(posPerimeters);
} else if (*opt_key == "resolution"
|| *opt_key == "layer_height"
|| *opt_key == "first_layer_height"
|| *opt_key == "xy_size_compensation"
|| *opt_key == "raft_layers") {
steps.insert(posSlice);
} else if (*opt_key == "support_material"
|| *opt_key == "support_material_angle"
|| *opt_key == "support_material_extrusion_width"
|| *opt_key == "support_material_interface_layers"
|| *opt_key == "support_material_interface_spacing"
|| *opt_key == "support_material_interface_speed"
|| *opt_key == "support_material_pattern"
|| *opt_key == "support_material_spacing"
|| *opt_key == "support_material_threshold"
|| *opt_key == "dont_support_bridges") {
steps.insert(posSupportMaterial);
} else if (*opt_key == "interface_shells"
|| *opt_key == "infill_only_where_needed") {
steps.insert(posPrepareInfill);
} else {
// for legacy, if we can't handle this option let's signal the caller to invalidate all steps
return false;
}
}
for (std::set<PrintObjectStep>::const_iterator step = steps.begin(); step != steps.end(); ++step)
this->invalidate_step(*step);
return true;
}
void
PrintObject::invalidate_step(PrintObjectStep step)
{
this->state.invalidate(step);
// propagate to dependent steps
if (step == posPerimeters) {
this->invalidate_step(posPrepareInfill);
this->_print->invalidate_step(psSkirt);
this->_print->invalidate_step(psBrim);
} else if (step == posPrepareInfill) {
this->invalidate_step(posInfill);
} else if (step == posInfill) {
this->_print->invalidate_step(psSkirt);
this->_print->invalidate_step(psBrim);
} else if (step == posSlice) {
this->invalidate_step(posPerimeters);
this->invalidate_step(posSupportMaterial);
}
}
#ifdef SLIC3RXS
REGISTER_CLASS(PrintObject, "Print::Object");
@ -217,8 +281,8 @@ Print::clear_objects()
this->clear_regions();
this->_state.invalidate(psSkirt);
this->_state.invalidate(psBrim);
this->state.invalidate(psSkirt);
this->state.invalidate(psBrim);
}
PrintObject*
@ -239,7 +303,7 @@ Print::add_object(ModelObject *model_object,
PrintObject*
Print::set_new_object(size_t idx, ModelObject *model_object, const BoundingBoxf3 &modobj_bbox)
{
if (idx < 0 || idx >= this->objects.size()) throw "bad idx";
if (idx >= this->objects.size()) throw "bad idx";
PrintObjectPtrs::iterator old_it = this->objects.begin() + idx;
delete *old_it;
@ -258,8 +322,8 @@ Print::delete_object(size_t idx)
// TODO: purge unused regions
this->_state.invalidate(psSkirt);
this->_state.invalidate(psBrim);
this->state.invalidate(psSkirt);
this->state.invalidate(psBrim);
}
void
@ -291,6 +355,48 @@ Print::delete_region(size_t idx)
this->regions.erase(i);
}
bool
Print::invalidate_state_by_config_options(const std::vector<t_config_option_key> &opt_keys)
{
std::set<PrintStep> steps;
// this method only accepts PrintConfig option keys
for (std::vector<t_config_option_key>::const_iterator opt_key = opt_keys.begin(); opt_key != opt_keys.end(); ++opt_key) {
if (*opt_key == "skirts"
|| *opt_key == "skirt_height"
|| *opt_key == "skirt_distance"
|| *opt_key == "min_skirt_length") {
steps.insert(psSkirt);
} else if (*opt_key == "brim_width") {
steps.insert(psBrim);
} else {
// for legacy, if we can't handle this option let's signal the caller to invalidate all steps
return false;
}
}
for (std::set<PrintStep>::const_iterator step = steps.begin(); step != steps.end(); ++step)
this->invalidate_step(*step);
return true;
}
void
Print::invalidate_step(PrintStep step)
{
this->state.invalidate(step);
// propagate to dependent steps
if (step == psSkirt) {
this->invalidate_step(psBrim);
} else if (step == psInitExtruders) {
for (PrintObjectPtrs::iterator object = this->objects.begin(); object != this->objects.end(); ++object) {
(*object)->invalidate_step(posPerimeters);
(*object)->invalidate_step(posSupportMaterial);
}
}
}
#ifdef SLIC3RXS
REGISTER_CLASS(Print, "Print");

View File

@ -17,22 +17,25 @@ class ModelObject;
enum PrintStep {
psInitExtruders, psSlice, psPerimeters, prPrepareInfill,
psInfill, psSupportMaterial, psSkirt, psBrim,
psInitExtruders, psSkirt, psBrim,
};
enum PrintObjectStep {
posSlice, posPerimeters, posPrepareInfill,
posInfill, posSupportMaterial,
};
template <class StepType>
class PrintState
{
private:
std::set<PrintStep> _started;
std::set<PrintStep> _done;
std::set<StepType> _started, _done;
public:
bool started(PrintStep step) const;
bool done(PrintStep step) const;
void set_started(PrintStep step);
void set_done(PrintStep step);
void invalidate(PrintStep step);
bool started(StepType step) const;
bool done(StepType step) const;
void set_started(StepType step);
void set_done(StepType step);
void invalidate(StepType step);
void invalidate_all();
};
@ -83,7 +86,7 @@ class PrintObject
LayerPtrs layers;
SupportLayerPtrs support_layers;
// TODO: Fill* fill_maker => (is => 'lazy');
PrintState _state;
PrintState<PrintObjectStep> state;
Print* print();
ModelObject* model_object();
@ -102,7 +105,11 @@ class PrintObject
SupportLayer* get_support_layer(int idx);
SupportLayer* add_support_layer(int id, coordf_t height, coordf_t print_z, coordf_t slice_z);
void delete_support_layer(int idx);
// methods for handling state
bool invalidate_state_by_config_options(const std::vector<t_config_option_key> &opt_keys);
void invalidate_step(PrintObjectStep step);
private:
Print* _print;
ModelObject* _model_object;
@ -127,7 +134,7 @@ class Print
PlaceholderParser placeholder_parser;
// TODO: status_cb
double total_used_filament, total_extruded_volume;
PrintState _state;
PrintState<PrintStep> state;
// ordered collections of extrusion paths to build skirt loops and brim
ExtrusionEntityCollection skirt, brim;
@ -145,6 +152,10 @@ class Print
// methods for handling regions
PrintRegion* get_region(size_t idx);
PrintRegion* add_region();
// methods for handling state
bool invalidate_state_by_config_options(const std::vector<t_config_option_key> &opt_keys);
void invalidate_step(PrintStep step);
private:
void clear_regions();

View File

@ -6,20 +6,6 @@
#include "PlaceholderParser.hpp"
%}
%name{Slic3r::Print::State} class PrintState {
PrintState();
~PrintState();
bool started(PrintStep step) const;
bool done(PrintStep step) const;
void set_started(PrintStep step);
void set_done(PrintStep step);
void invalidate(PrintStep step);
void invalidate_all();
%{
%}
};
%package{Slic3r::Print::State};
%{
@ -27,11 +13,11 @@ IV
_constant()
ALIAS:
STEP_INIT_EXTRUDERS = psInitExtruders
STEP_SLICE = psSlice
STEP_PERIMETERS = psPerimeters
STEP_PREPARE_INFILL = prPrepareInfill
STEP_INFILL = psInfill
STEP_SUPPORTMATERIAL = psSupportMaterial
STEP_SLICE = posSlice
STEP_PERIMETERS = posPerimeters
STEP_PREPARE_INFILL = posPrepareInfill
STEP_INFILL = posInfill
STEP_SUPPORTMATERIAL = posSupportMaterial
STEP_SKIRT = psSkirt
STEP_BRIM = psBrim
PROTOTYPE:
@ -71,8 +57,6 @@ _constant()
%code%{ RETVAL = THIS->copies; %};
t_layer_height_ranges layer_height_ranges()
%code%{ RETVAL = THIS->layer_height_ranges; %};
Ref<PrintState> _state()
%code%{ RETVAL = &THIS->_state; %};
Ref<Point3> size()
%code%{ RETVAL = &THIS->size; %};
Ref<Point> _copies_shift()
@ -98,10 +82,20 @@ _constant()
size_t support_layer_count();
void clear_support_layers();
Ref<SupportLayer> get_support_layer(int idx);
Ref<SupportLayer> add_support_layer(int id, coordf_t height, coordf_t print_z,
coordf_t slice_z);
Ref<SupportLayer> add_support_layer(int id, coordf_t height, coordf_t print_z, coordf_t slice_z);
void delete_support_layer(int idx);
bool invalidate_state_by_config_options(std::vector<std::string> opt_keys);
void invalidate_step(PrintObjectStep step);
void invalidate_all_steps()
%code%{ THIS->state.invalidate_all(); %};
bool step_done(PrintObjectStep step)
%code%{ RETVAL = THIS->state.done(step); %};
void set_step_done(PrintObjectStep step)
%code%{ THIS->state.set_done(step); %};
void set_step_started(PrintObjectStep step)
%code%{ THIS->state.set_started(step); %};
int ptr()
%code%{ RETVAL = (int)(intptr_t)THIS; %};
};
@ -120,8 +114,6 @@ _constant()
Ref<PlaceholderParser> placeholder_parser()
%code%{ RETVAL = &THIS->placeholder_parser; %};
// TODO: status_cb
Ref<PrintState> _state()
%code%{ RETVAL = &THIS->_state; %};
Ref<ExtrusionEntityCollection> skirt()
%code%{ RETVAL = &THIS->skirt; %};
Ref<ExtrusionEntityCollection> brim()
@ -147,6 +139,17 @@ _constant()
Ref<PrintRegion> add_region();
size_t region_count()
%code%{ RETVAL = THIS->regions.size(); %};
bool invalidate_state_by_config_options(std::vector<std::string> opt_keys);
void invalidate_step(PrintStep step);
void invalidate_all_steps()
%code%{ THIS->state.invalidate_all(); %};
bool step_done(PrintStep step)
%code%{ RETVAL = THIS->state.done(step); %};
void set_step_done(PrintStep step)
%code%{ THIS->state.set_done(step); %};
void set_step_started(PrintStep step)
%code%{ THIS->state.set_started(step); %};
%{
double

View File

@ -153,6 +153,7 @@ ExtrusionLoopRole T_UV
ExtrusionRole T_UV
FlowRole T_UV
PrintStep T_UV
PrintObjectStep T_UV
SurfaceType T_UV
ClipperLib::JoinType T_UV
ClipperLib::PolyFillType T_UV

View File

@ -176,3 +176,9 @@
$CVar = (PrintStep)SvUV($PerlVar);
%};
};
%typemap{PrintObjectStep}{parsed}{
%cpp_type{PrintObjectStep};
%precall_code{%
$CVar = (PrintObjectStep)SvUV($PerlVar);
%};
};