From 3f6360ee8f083b840979ef1087620fae052ca918 Mon Sep 17 00:00:00 2001 From: Alessandro Ranellucci Date: Tue, 10 Jun 2014 16:01:57 +0200 Subject: [PATCH] Finish porting Print classes to XS --- lib/Slic3r/GCode.pm | 7 ++-- lib/Slic3r/GCode/PlaceholderParser.pm | 20 +++++------ lib/Slic3r/GUI/Plater.pm | 2 -- lib/Slic3r/Print.pm | 8 +++-- lib/Slic3r/Print/Object.pm | 4 ++- lib/Slic3r/Print/Region.pm | 6 ++-- xs/src/Print.cpp | 43 +++++++--------------- xs/src/Print.hpp | 51 ++++++++++----------------- xs/t/20_print.t | 18 ++++++++++ xs/xsp/Print.xsp | 6 ++-- 10 files changed, 78 insertions(+), 87 deletions(-) create mode 100644 xs/t/20_print.t diff --git a/lib/Slic3r/GCode.pm b/lib/Slic3r/GCode.pm index 520ececc1..2966000cd 100644 --- a/lib/Slic3r/GCode.pm +++ b/lib/Slic3r/GCode.pm @@ -169,10 +169,11 @@ sub extrude_loop { if ($self->config->seam_position eq 'nearest') { $loop->split_at_vertex($last_pos->nearest_point(\@candidates)); } elsif ($self->config->seam_position eq 'aligned') { - if (defined $self->layer && defined $self->_seam_position->{$self->layer->object}) { - $last_pos = $self->_seam_position->{$self->layer->object}; + my $obj_ptr = $self->layer->object->ptr; + if (defined $self->layer && defined $self->_seam_position->{$obj_ptr}) { + $last_pos = $self->_seam_position->{$obj_ptr}; } - my $point = $self->_seam_position->{$self->layer->object} = $last_pos->nearest_point(\@candidates); + my $point = $self->_seam_position->{$obj_ptr} = $last_pos->nearest_point(\@candidates); $loop->split_at_vertex($point); } } elsif ($self->config->seam_position eq 'random') { diff --git a/lib/Slic3r/GCode/PlaceholderParser.pm b/lib/Slic3r/GCode/PlaceholderParser.pm index f9b505208..d8df755f0 100644 --- a/lib/Slic3r/GCode/PlaceholderParser.pm +++ b/lib/Slic3r/GCode/PlaceholderParser.pm @@ -19,12 +19,12 @@ sub update_timestamp { my @lt = localtime; $lt[5] += 1900; $lt[4] += 1; $self->_single_set('timestamp', sprintf '%04d%02d%02d-%02d%02d%02d', @lt[5,4,3,2,1,0]); - $self->_single_set('year', $lt[5]); - $self->_single_set('month', $lt[4]); - $self->_single_set('day', $lt[3]); - $self->_single_set('hour', $lt[2]); - $self->_single_set('minute', $lt[1]); - $self->_single_set('second', $lt[0]); + $self->_single_set('year', "$lt[5]"); + $self->_single_set('month', "$lt[4]"); + $self->_single_set('day', "$lt[3]"); + $self->_single_set('hour', "$lt[2]"); + $self->_single_set('minute', "$lt[1]"); + $self->_single_set('second', "$lt[0]"); $self->_single_set('version', $Slic3r::VERSION); } @@ -42,11 +42,11 @@ sub apply_config { # TODO: this is a workaroud for XS string param handling # https://rt.cpan.org/Public/Bug/Display.html?id=94110 "$_" for @$value; - $self->_multiple_set("${opt_key}_" . $_, $value->[$_]) for 0..$#$value; - $self->_multiple_set($opt_key, $value->[0]); + $self->_multiple_set("${opt_key}_" . $_, $value->[$_]."") for 0..$#$value; + $self->_multiple_set($opt_key, $value->[0].""); if ($Slic3r::Config::Options->{$opt_key}{type} eq 'point') { - $self->_multiple_set("${opt_key}_X", $value->[0]); - $self->_multiple_set("${opt_key}_Y", $value->[1]); + $self->_multiple_set("${opt_key}_X", $value->[0].""); + $self->_multiple_set("${opt_key}_Y", $value->[1].""); } } } diff --git a/lib/Slic3r/GUI/Plater.pm b/lib/Slic3r/GUI/Plater.pm index 1961e70c7..4946d5a34 100644 --- a/lib/Slic3r/GUI/Plater.pm +++ b/lib/Slic3r/GUI/Plater.pm @@ -540,7 +540,6 @@ sub rotate { $model_object->update_bounding_box; # update print - $self->{print}->delete_object($obj_idx); $self->{print}->add_model_object($model_object, $obj_idx); $object->transform_thumbnail($self->{model}, $obj_idx); @@ -576,7 +575,6 @@ sub changescale { $model_object->update_bounding_box; # update print - $self->{print}->delete_object($obj_idx); $self->{print}->add_model_object($model_object, $obj_idx); $object->transform_thumbnail($self->{model}, $obj_idx); diff --git a/lib/Slic3r/Print.pm b/lib/Slic3r/Print.pm index bf9950174..59c21676d 100644 --- a/lib/Slic3r/Print.pm +++ b/lib/Slic3r/Print.pm @@ -1,4 +1,6 @@ package Slic3r::Print; +use strict; +use warnings; use File::Basename qw(basename fileparse); use File::Spec; @@ -16,7 +18,7 @@ our $status_cb; sub new { # TODO: port PlaceholderParser methods to C++, then its own constructor - # can call them and no need for this new() method at all + # can call them and no need for this new() method at all my ($class) = @_; my $self = $class->_new; $self->placeholder_parser->apply_env_variables; @@ -840,10 +842,10 @@ sub write_gcode { # TODO: only do this when M73 is enabled my $layer_count; if ($self->config->complete_objects) { - $layer_count = sum(map { $_->layer_count * @{$_->copies} } @{$self->objects}); + $layer_count = sum(map { $_->total_layer_count * @{$_->copies} } @{$self->objects}); } else { # if sequential printing is not enable, all copies of the same object share the same layer change command(s) - $layer_count = sum(map { $_->layer_count } @{$self->objects}); + $layer_count = sum(map { $_->total_layer_count } @{$self->objects}); } # set up our helper object diff --git a/lib/Slic3r/Print/Object.pm b/lib/Slic3r/Print/Object.pm index 99a7eb3ab..03aa86db1 100644 --- a/lib/Slic3r/Print/Object.pm +++ b/lib/Slic3r/Print/Object.pm @@ -1,4 +1,6 @@ package Slic3r::Print::Object; +use strict; +use warnings; use List::Util qw(min max sum first); use Slic3r::Flow ':roles'; @@ -54,7 +56,7 @@ sub _trigger_copies { # in unscaled coordinates sub add_copy { my ($self, $x, $y) = @_; - my @copies = $self->copies; + my @copies = @{$self->copies}; push @copies, Slic3r::Point->new_scale($x, $y); $self->set_copies(\@copies); $self->_trigger_copies; diff --git a/lib/Slic3r/Print/Region.pm b/lib/Slic3r/Print/Region.pm index 03532e25a..8a2330495 100644 --- a/lib/Slic3r/Print/Region.pm +++ b/lib/Slic3r/Print/Region.pm @@ -1,4 +1,6 @@ package Slic3r::Print::Region; +use strict; +use warnings; use Slic3r::Extruder ':roles'; use Slic3r::Flow ':roles'; @@ -47,14 +49,14 @@ sub flow { } else { die "Unknown role $role"; } - my $nozzle_diameter = $self->print_config->get_at('nozzle_diameter', $extruder-1); + my $nozzle_diameter = $self->print->config->get_at('nozzle_diameter', $extruder-1); return Slic3r::Flow->new_from_width( width => $config_width, role => $role, nozzle_diameter => $nozzle_diameter, layer_height => $layer_height, - bridge_flow_ratio => ($bridge ? $self->print_config->bridge_flow_ratio : 0), + bridge_flow_ratio => ($bridge ? $self->print->config->bridge_flow_ratio : 0), ); } diff --git a/xs/src/Print.cpp b/xs/src/Print.cpp index fef87387a..44513e49d 100644 --- a/xs/src/Print.cpp +++ b/xs/src/Print.cpp @@ -62,21 +62,14 @@ PrintRegion::print() return this->_print; } -PrintConfig & -PrintRegion::print_config() -{ - return this->_print->config; -} - #ifdef SLIC3RXS REGISTER_CLASS(PrintRegion, "Print::Region"); #endif -PrintObject::PrintObject(Print* print, int id, ModelObject* model_object, +PrintObject::PrintObject(Print* print, ModelObject* model_object, const BoundingBoxf3 &modobj_bbox) : _print(print), - _id(id), _model_object(model_object) { region_volumes.resize(this->_print->regions.size()); @@ -110,12 +103,6 @@ PrintObject::print() return this->_print; } -int -PrintObject::id() -{ - return this->_id; -} - ModelObject* PrintObject::model_object() { @@ -164,9 +151,8 @@ void PrintObject::delete_layer(int idx) { LayerPtrs::iterator i = this->layers.begin() + idx; - Layer* item = *i; + delete *i; this->layers.erase(i); - delete item; } size_t @@ -201,9 +187,8 @@ void PrintObject::delete_support_layer(int idx) { SupportLayerPtrs::iterator i = this->support_layers.begin() + idx; - SupportLayer* item = *i; + delete *i; this->support_layers.erase(i); - delete item; } @@ -237,7 +222,7 @@ Print::clear_objects() } PrintObject* -Print::get_object(int idx) +Print::get_object(size_t idx) { return objects.at(idx); } @@ -246,33 +231,30 @@ PrintObject* Print::add_object(ModelObject *model_object, const BoundingBoxf3 &modobj_bbox) { - PrintObject *object = new PrintObject(this, - this->objects.size(), model_object, modobj_bbox); + PrintObject *object = new PrintObject(this, model_object, modobj_bbox); objects.push_back(object); return object; } PrintObject* -Print::set_new_object(size_t idx, ModelObject *model_object, - const BoundingBoxf3 &modobj_bbox) +Print::set_new_object(size_t idx, ModelObject *model_object, const BoundingBoxf3 &modobj_bbox) { if (idx < 0 || idx >= this->objects.size()) throw "bad idx"; PrintObjectPtrs::iterator old_it = this->objects.begin() + idx; delete *old_it; - PrintObject *object = new PrintObject(this, idx, model_object, modobj_bbox); + PrintObject *object = new PrintObject(this, model_object, modobj_bbox); this->objects[idx] = object; return object; } void -Print::delete_object(int idx) +Print::delete_object(size_t idx) { PrintObjectPtrs::iterator i = this->objects.begin() + idx; - PrintObject* item = *i; + delete *i; this->objects.erase(i); - delete item; // TODO: purge unused regions @@ -288,7 +270,7 @@ Print::clear_regions() } PrintRegion* -Print::get_region(int idx) +Print::get_region(size_t idx) { return regions.at(idx); } @@ -302,12 +284,11 @@ Print::add_region() } void -Print::delete_region(int idx) +Print::delete_region(size_t idx) { PrintRegionPtrs::iterator i = this->regions.begin() + idx; - PrintRegion* item = *i; + delete *i; this->regions.erase(i); - delete item; } diff --git a/xs/src/Print.hpp b/xs/src/Print.hpp index 12dbc35c5..41a18c93b 100644 --- a/xs/src/Print.hpp +++ b/xs/src/Print.hpp @@ -36,8 +36,6 @@ class PrintState void invalidate_all(); }; -// TODO: make stuff private - // A PrintRegion object represents a group of volumes to print // sharing the same config (including the same assigned extruder(s)) class PrintRegion @@ -48,13 +46,12 @@ class PrintRegion PrintRegionConfig config; Print* print(); - PrintConfig &print_config(); private: Print* _print; PrintRegion(Print* print); - virtual ~PrintRegion(); + ~PrintRegion(); }; @@ -87,10 +84,8 @@ class PrintObject SupportLayerPtrs support_layers; // TODO: Fill* fill_maker => (is => 'lazy'); PrintState _state; - - + Print* print(); - int id(); ModelObject* model_object(); // adds region_id, too, if necessary @@ -99,27 +94,23 @@ class PrintObject size_t layer_count(); void clear_layers(); Layer* get_layer(int idx); - Layer* add_layer(int id, coordf_t height, coordf_t print_z, - coordf_t slice_z); + Layer* add_layer(int id, coordf_t height, coordf_t print_z, coordf_t slice_z); void delete_layer(int idx); size_t support_layer_count(); void clear_support_layers(); SupportLayer* get_support_layer(int idx); - SupportLayer* add_support_layer(int id, coordf_t height, coordf_t print_z, - coordf_t slice_z); + SupportLayer* add_support_layer(int id, coordf_t height, coordf_t print_z, coordf_t slice_z); void delete_support_layer(int idx); private: Print* _print; - int _id; ModelObject* _model_object; // TODO: call model_object->get_bounding_box() instead of accepting // parameter - PrintObject(Print* print, int id, ModelObject* model_object, - const BoundingBoxf3 &modobj_bbox); - virtual ~PrintObject(); + PrintObject(Print* print, ModelObject* model_object, const BoundingBoxf3 &modobj_bbox); + ~PrintObject(); }; typedef std::vector PrintObjectPtrs; @@ -135,33 +126,29 @@ class Print PrintRegionPtrs regions; PlaceholderParser placeholder_parser; // TODO: status_cb - double total_used_filament; - double total_extruded_volume; + double total_used_filament, total_extruded_volume; PrintState _state; - // ordered collection of extrusion paths to build skirt loops - ExtrusionEntityCollection skirt; - - // ordered collection of extrusion paths to build a brim - ExtrusionEntityCollection brim; + // ordered collections of extrusion paths to build skirt loops and brim + ExtrusionEntityCollection skirt, brim; Print(); - virtual ~Print(); - + ~Print(); + + // methods for handling objects void clear_objects(); - PrintObject* get_object(int idx); - PrintObject* add_object(ModelObject *model_object, - const BoundingBoxf3 &modobj_bbox); - PrintObject* set_new_object(size_t idx, ModelObject *model_object, - const BoundingBoxf3 &modobj_bbox); - void delete_object(int idx); + PrintObject* get_object(size_t idx); + PrintObject* add_object(ModelObject *model_object, const BoundingBoxf3 &modobj_bbox); + PrintObject* set_new_object(size_t idx, ModelObject *model_object, const BoundingBoxf3 &modobj_bbox); + void delete_object(size_t idx); - PrintRegion* get_region(int idx); + // methods for handling regions + PrintRegion* get_region(size_t idx); PrintRegion* add_region(); private: void clear_regions(); - void delete_region(int idx); + void delete_region(size_t idx); }; } diff --git a/xs/t/20_print.t b/xs/t/20_print.t new file mode 100644 index 000000000..d8e8699bf --- /dev/null +++ b/xs/t/20_print.t @@ -0,0 +1,18 @@ +#!/usr/bin/perl + +use strict; +use warnings; + +use Slic3r::XS; +use Test::More tests => 5; + +{ + my $print = Slic3r::Print->_new; + isa_ok $print, 'Slic3r::Print'; + isa_ok $print->config, 'Slic3r::Config::Print::Ref'; + isa_ok $print->default_object_config, 'Slic3r::Config::PrintObject::Ref'; + isa_ok $print->default_region_config, 'Slic3r::Config::PrintRegion::Ref'; + isa_ok $print->placeholder_parser, 'Slic3r::GCode::PlaceholderParser::Ref'; +} + +__END__ diff --git a/xs/xsp/Print.xsp b/xs/xsp/Print.xsp index cb8132108..d8319e794 100644 --- a/xs/xsp/Print.xsp +++ b/xs/xsp/Print.xsp @@ -48,8 +48,6 @@ _constant() Ref config() %code%{ RETVAL = &THIS->config; %}; Ref print(); - Ref print_config() - %code%{ RETVAL = &THIS->print_config(); %}; }; @@ -66,7 +64,6 @@ _constant() %code%{ RETVAL = THIS->print()->regions.size(); %}; Ref print(); - int id(); Ref model_object(); Ref config() %code%{ RETVAL = &THIS->config; %}; @@ -104,6 +101,9 @@ _constant() Ref add_support_layer(int id, coordf_t height, coordf_t print_z, coordf_t slice_z); void delete_support_layer(int idx); + + int ptr() + %code%{ RETVAL = (int)(intptr_t)THIS; %}; };