Thread-safe integration of ExtrusionPath::Collection

This commit is contained in:
Alessandro Ranellucci 2013-07-18 22:29:12 +02:00
parent c030e38908
commit 1b285f3f46
12 changed files with 81 additions and 104 deletions

View file

@ -114,6 +114,7 @@ sub thread_cleanup {
*Slic3r::ExPolygon::Collection::DESTROY = sub {}; *Slic3r::ExPolygon::Collection::DESTROY = sub {};
*Slic3r::ExtrusionLoop::DESTROY = sub {}; *Slic3r::ExtrusionLoop::DESTROY = sub {};
*Slic3r::ExtrusionPath::DESTROY = sub {}; *Slic3r::ExtrusionPath::DESTROY = sub {};
*Slic3r::ExtrusionPath::Collection::DESTROY = sub {};
*Slic3r::Line::DESTROY = sub {}; *Slic3r::Line::DESTROY = sub {};
*Slic3r::Point::DESTROY = sub {}; *Slic3r::Point::DESTROY = sub {};
*Slic3r::Polygon::DESTROY = sub {}; *Slic3r::Polygon::DESTROY = sub {};

View file

@ -42,12 +42,15 @@ sub cleanup {
my $self = shift; my $self = shift;
# split paths at angles that are too acute to be printed as they will cause blobs # split paths at angles that are too acute to be printed as they will cause blobs
@{$self->paths} = map $_->split_at_acute_angles, @{$self->paths}; my @paths = map $_->split_at_acute_angles, @$self;
$self->clear;
$self->append(@paths);
} }
sub detect_arcs { sub detect_arcs {
my $self = shift; my $self = shift;
@{$self->paths} = map $_->detect_arcs(@_), @{$self->paths};
return map $_->detect_arcs(@_), @$self;
} }
1; 1;

View file

@ -211,11 +211,7 @@ sub extrude_loop {
$extrusion_path->intersect_expolygons($self->_layer_overhangs); $extrusion_path->intersect_expolygons($self->_layer_overhangs);
# reapply the nearest point search for starting point # reapply the nearest point search for starting point
{ @paths = Slic3r::ExtrusionPath::Collection->new(@paths)->chained_path($start_at, 1);
my $collection = Slic3r::ExtrusionPath::Collection->new;
$collection->append(@paths);
@paths = $collection->chained_path($start_at, 1);
}
} else { } else {
push @paths, $extrusion_path; push @paths, $extrusion_path;
} }

View file

@ -29,19 +29,19 @@ has 'slices' => (is => 'rw', default => sub { Slic3r::Surface::Collection->new }
# collection of polygons or polylines representing thin walls contained # collection of polygons or polylines representing thin walls contained
# in the original geometry # in the original geometry
has 'thin_walls' => (is => 'rw', default => sub { [] }); has 'thin_walls' => (is => 'rw', default => sub { Slic3r::ExtrusionPath::Collection->new });
# collection of extrusion paths/loops filling gaps # collection of extrusion paths/loops filling gaps
has 'thin_fills' => (is => 'rw', default => sub { [] }); has 'thin_fills' => (is => 'rw', default => sub { Slic3r::ExtrusionPath::Collection->new });
# collection of surfaces for infill generation # collection of surfaces for infill generation
has 'fill_surfaces' => (is => 'rw', default => sub { Slic3r::Surface::Collection->new }); has 'fill_surfaces' => (is => 'rw', default => sub { Slic3r::Surface::Collection->new });
# ordered collection of extrusion paths/loops to build all perimeters # ordered collection of extrusion paths/loops to build all perimeters
has 'perimeters' => (is => 'rw', default => sub { [] }); has 'perimeters' => (is => 'rw', default => sub { Slic3r::ExtrusionPath::Collection->new });
# ordered collection of extrusion paths to fill surfaces # ordered collection of extrusion paths to fill surfaces
has 'fills' => (is => 'rw', default => sub { [] }); has 'fills' => (is => 'rw', default => sub { Slic3r::ExtrusionPath::Collection->new });
sub BUILD { sub BUILD {
my $self = shift; my $self = shift;
@ -100,13 +100,11 @@ sub make_surfaces {
1, 1,
); );
$self->thin_walls([]); $self->thin_walls->clear;
if (@$diff) { if (@$diff) {
my $area_threshold = $self->perimeter_flow->scaled_spacing ** 2; my $area_threshold = $self->perimeter_flow->scaled_spacing ** 2;
@$diff = grep $_->area > ($area_threshold), @$diff; @$diff = grep $_->area > ($area_threshold), @$diff;
$self->thin_walls->append(map $_->medial_axis($self->perimeter_flow->scaled_width), @$diff);
@{$self->thin_walls} = map $_->medial_axis($self->perimeter_flow->scaled_width), @$diff;
Slic3r::debugf " %d thin walls detected\n", scalar(@{$self->thin_walls}) if @{$self->thin_walls}; Slic3r::debugf " %d thin walls detected\n", scalar(@{$self->thin_walls}) if @{$self->thin_walls};
} }
} }
@ -156,9 +154,9 @@ sub make_perimeters {
my $infill_spacing = $self->solid_infill_flow->scaled_spacing; my $infill_spacing = $self->solid_infill_flow->scaled_spacing;
my $gap_area_threshold = $self->perimeter_flow->scaled_width ** 2; my $gap_area_threshold = $self->perimeter_flow->scaled_width ** 2;
$self->perimeters([]); $self->perimeters->clear;
$self->fill_surfaces->clear; $self->fill_surfaces->clear;
$self->thin_fills([]); $self->thin_fills->clear;
my @contours = (); # array of Polygons with ccw orientation my @contours = (); # array of Polygons with ccw orientation
my @holes = (); # array of Polygons with cw orientation my @holes = (); # array of Polygons with cw orientation
@ -278,7 +276,7 @@ sub make_perimeters {
|| ($self->layer->id == 0 && $Slic3r::Config->brim_width > 0); || ($self->layer->id == 0 && $Slic3r::Config->brim_width > 0);
# append perimeters # append perimeters
push @{ $self->perimeters }, @loops; $self->perimeters->append(@loops);
# add thin walls as perimeters # add thin walls as perimeters
push @{ $self->perimeters }, Slic3r::ExtrusionPath::Collection->new( push @{ $self->perimeters }, Slic3r::ExtrusionPath::Collection->new(
@ -333,11 +331,11 @@ sub _fill_gaps {
role => EXTR_ROLE_SOLIDFILL, role => EXTR_ROLE_SOLIDFILL,
flow_spacing => $flow->spacing, flow_spacing => $flow->spacing,
); );
push @{ $self->thin_fills }, map { $self->thin_fills->append(map {
$_->isa('Slic3r::Polygon') $_->isa('Slic3r::Polygon')
? Slic3r::ExtrusionLoop->new(polygon => $_, %path_args)->split_at_first_point # we should keep these as loops ? Slic3r::ExtrusionLoop->new(polygon => $_, %path_args)->split_at_first_point # we should keep these as loops
: Slic3r::ExtrusionPath->new(polyline => $_, %path_args), : Slic3r::ExtrusionPath->new(polyline => $_, %path_args),
} map $_->medial_axis($flow->scaled_width), @this_width; } map $_->medial_axis($flow->scaled_width), @this_width);
Slic3r::debugf " %d gaps filled with extrusion width = %s\n", scalar @this_width, $width Slic3r::debugf " %d gaps filled with extrusion width = %s\n", scalar @this_width, $width
if @{ $self->thin_fills }; if @{ $self->thin_fills };

View file

@ -395,33 +395,17 @@ sub export_gcode {
thread_cb => sub { thread_cb => sub {
my $q = shift; my $q = shift;
$Slic3r::Geometry::Clipper::clipper = Math::Clipper->new; $Slic3r::Geometry::Clipper::clipper = Math::Clipper->new;
my $fills = {};
while (defined (my $obj_layer = $q->dequeue)) { while (defined (my $obj_layer = $q->dequeue)) {
my ($obj_idx, $layer_id, $region_id) = @$obj_layer; my ($obj_idx, $layer_id, $region_id) = @$obj_layer;
my $object = $self->objects->[$obj_idx]; my $object = $self->objects->[$obj_idx];
$fills->{$obj_idx} ||= {}; my $layerm = $object->layers->[$layer_id]->regions->[$region_id];
$fills->{$obj_idx}{$layer_id} ||= {}; $layerm->fills->append( $object->fill_maker->make_fill($layerm) );
$fills->{$obj_idx}{$layer_id}{$region_id} = [
$object->fill_maker->make_fill($object->layers->[$layer_id]->regions->[$region_id]),
];
}
return $fills;
},
collect_cb => sub {
my $fills = shift;
foreach my $obj_idx (keys %$fills) {
my $object = $self->objects->[$obj_idx];
foreach my $layer_id (keys %{$fills->{$obj_idx}}) {
my $layer = $object->layers->[$layer_id];
foreach my $region_id (keys %{$fills->{$obj_idx}{$layer_id}}) {
$layer->regions->[$region_id]->fills($fills->{$obj_idx}{$layer_id}{$region_id});
}
}
} }
}, },
collect_cb => sub {},
no_threads_cb => sub { no_threads_cb => sub {
foreach my $layerm (map @{$_->regions}, map @{$_->layers}, @{$self->objects}) { foreach my $layerm (map @{$_->regions}, map @{$_->layers}, @{$self->objects}) {
$layerm->fills([ $layerm->layer->object->fill_maker->make_fill($layerm) ]); $layerm->fills->append($layerm->layer->object->fill_maker->make_fill($layerm));
} }
}, },
); );
@ -587,7 +571,7 @@ sub make_skirt {
my @layer_points = ( my @layer_points = (
(map @$_, map @$_, map @{$_->slices}, @layers), (map @$_, map @$_, map @{$_->slices}, @layers),
(map @$_, map @{$_->thin_walls}, map @{$_->regions}, @layers), (map @$_, map @{$_->thin_walls}, map @{$_->regions}, @layers),
(map @{$_->polyline}, map @{$_->support_fills->paths}, grep $_->support_fills, @layers), (map @{$_->polyline}, map @{$_->support_fills}, grep $_->support_fills, @layers),
); );
push @points, map move_points($_, @layer_points), @{$self->objects->[$obj_idx]->copies}; push @points, map move_points($_, @layer_points), @{$self->objects->[$obj_idx]->copies};
} }
@ -647,7 +631,7 @@ sub make_brim {
my @object_islands = ( my @object_islands = (
(map $_->contour, @{$layer0->slices}), (map $_->contour, @{$layer0->slices}),
(map { $_->isa('Slic3r::Polygon') ? $_ : $_->grow($grow_distance) } map @{$_->thin_walls}, @{$layer0->regions}), (map { $_->isa('Slic3r::Polygon') ? $_ : $_->grow($grow_distance) } map @{$_->thin_walls}, @{$layer0->regions}),
(map $_->polyline->grow($grow_distance), map @{$_->support_fills->paths}, grep $_->support_fills, $layer0), (map $_->polyline->grow($grow_distance), map @{$_->support_fills}, grep $_->support_fills, $layer0),
); );
foreach my $copy (@{$self->objects->[$obj_idx]->copies}) { foreach my $copy (@{$self->objects->[$obj_idx]->copies}) {
push @islands, map $_->clone->translate(@$copy), @object_islands; push @islands, map $_->clone->translate(@$copy), @object_islands;

View file

@ -315,31 +315,11 @@ sub make_perimeters {
thread_cb => sub { thread_cb => sub {
my $q = shift; my $q = shift;
$Slic3r::Geometry::Clipper::clipper = Math::Clipper->new; $Slic3r::Geometry::Clipper::clipper = Math::Clipper->new;
my $result = {};
while (defined (my $layer_id = $q->dequeue)) { while (defined (my $layer_id = $q->dequeue)) {
my $layer = $self->layers->[$layer_id]; $self->layers->[$layer_id]->make_perimeters;
$layer->make_perimeters;
$result->{$layer_id} ||= {};
foreach my $region_id (0 .. $#{$layer->regions}) {
my $layerm = $layer->regions->[$region_id];
$result->{$layer_id}{$region_id} = {
perimeters => $layerm->perimeters,
fill_surfaces => $layerm->fill_surfaces,
thin_fills => $layerm->thin_fills,
};
}
}
return $result;
},
collect_cb => sub {
my $result = shift;
foreach my $layer_id (keys %$result) {
foreach my $region_id (keys %{$result->{$layer_id}}) {
$self->layers->[$layer_id]->regions->[$region_id]->$_($result->{$layer_id}{$region_id}{$_})
for qw(perimeters fill_surfaces thin_fills);
}
} }
}, },
collect_cb => sub {},
no_threads_cb => sub { no_threads_cb => sub {
$_->make_perimeters for @{$self->layers}; $_->make_perimeters for @{$self->layers};
}, },
@ -988,9 +968,6 @@ sub generate_support_material {
}; };
return @paths; return @paths;
}; };
my %layer_paths = ();
my %layer_contact_paths = ();
my %layer_islands = ();
my $process_layer = sub { my $process_layer = sub {
my ($layer_id) = @_; my ($layer_id) = @_;
my $layer = $self->layers->[$layer_id]; my $layer = $self->layers->[$layer_id];
@ -1026,6 +1003,9 @@ sub generate_support_material {
} }
return ($paths, $contact_paths, $islands); return ($paths, $contact_paths, $islands);
}; };
my %layer_paths = ();
my %layer_contact_paths = ();
my %layer_islands = ();
Slic3r::parallelize( Slic3r::parallelize(
items => [ keys %layers ], items => [ keys %layers ],
thread_cb => sub { thread_cb => sub {
@ -1051,8 +1031,8 @@ sub generate_support_material {
$layer->support_islands($layer_islands{$layer_id}); $layer->support_islands($layer_islands{$layer_id});
$layer->support_fills(Slic3r::ExtrusionPath::Collection->new); $layer->support_fills(Slic3r::ExtrusionPath::Collection->new);
$layer->support_contact_fills(Slic3r::ExtrusionPath::Collection->new); $layer->support_contact_fills(Slic3r::ExtrusionPath::Collection->new);
push @{$layer->support_fills->paths}, @{$layer_paths{$layer_id}}; $layer->support_fills->append(@{$layer_paths{$layer_id}});
push @{$layer->support_contact_fills->paths}, @{$layer_contact_paths{$layer_id}}; $layer->support_contact_fills->append(@{$layer_contact_paths{$layer_id}});
} }
} }
} }

View file

@ -22,11 +22,10 @@ use Slic3r::Geometry qw(scaled_epsilon scale X Y);
[86948.77,175149.09], [119825.35,100585], [86948.77,175149.09], [119825.35,100585],
), role => EXTR_ROLE_FILL, flow_spacing => 0.5); ), role => EXTR_ROLE_FILL, flow_spacing => 0.5);
my $collection = Slic3r::ExtrusionPath::Collection->new(paths => [$path]); my @paths = $path->detect_arcs(30);
$collection->detect_arcs(30);
is scalar(@{$collection->paths}), 3, 'path collection now contains three paths'; is scalar(@paths), 3, 'path collection now contains three paths';
isa_ok $collection->paths->[1], 'Slic3r::ExtrusionPath::Arc', 'second one'; isa_ok $paths[1], 'Slic3r::ExtrusionPath::Arc', 'second one';
} }
#========================================================== #==========================================================
@ -50,30 +49,27 @@ use Slic3r::Geometry qw(scaled_epsilon scale X Y);
flow_spacing => 0.5, flow_spacing => 0.5,
); );
my $collection1 = Slic3r::ExtrusionPath::Collection->new(paths => [$path1]); my @paths1 = $path1->detect_arcs(10, scale 1);
my $collection2 = Slic3r::ExtrusionPath::Collection->new(paths => [$path2]); my @paths2 = $path2->detect_arcs(10, scale 1);
$collection1->detect_arcs(10, scale 1); is scalar(@paths1), 1, 'path collection now contains one path';
$collection2->detect_arcs(10, scale 1); is scalar(@paths2), 1, 'path collection now contains one path';
is scalar(@{$collection1->paths}), 1, 'path collection now contains one path'; isa_ok $paths1[0], 'Slic3r::ExtrusionPath::Arc', 'path';
is scalar(@{$collection2->paths}), 1, 'path collection now contains one path'; isa_ok $paths2[0], 'Slic3r::ExtrusionPath::Arc', 'path';
isa_ok $collection1->paths->[0], 'Slic3r::ExtrusionPath::Arc', 'path';
isa_ok $collection2->paths->[0], 'Slic3r::ExtrusionPath::Arc', 'path';
my $expected_length = scale 7.06858347057701; my $expected_length = scale 7.06858347057701;
ok abs($collection1->paths->[0]->length - $expected_length) < scaled_epsilon, 'cw oriented arc has correct length'; ok abs($paths1[0]->length - $expected_length) < scaled_epsilon, 'cw oriented arc has correct length';
ok abs($collection2->paths->[0]->length - $expected_length) < scaled_epsilon, 'ccw oriented arc has correct length'; ok abs($paths2[0]->length - $expected_length) < scaled_epsilon, 'ccw oriented arc has correct length';
is $collection1->paths->[0]->orientation, 'cw', 'cw orientation was correctly detected'; is $paths1[0]->orientation, 'cw', 'cw orientation was correctly detected';
is $collection2->paths->[0]->orientation, 'ccw', 'ccw orientation was correctly detected'; is $paths2[0]->orientation, 'ccw', 'ccw orientation was correctly detected';
is $collection1->paths->[0]->flow_spacing, $path1->flow_spacing, 'flow spacing was correctly preserved'; is $paths1[0]->flow_spacing, $path1->flow_spacing, 'flow spacing was correctly preserved';
my $center1 = [ map sprintf('%.0f', $_), @{ $collection1->paths->[0]->center } ]; my $center1 = [ map sprintf('%.0f', $_), @{ $paths1[0]->center } ];
ok abs($center1->[X] - scale 10) < scaled_epsilon && abs($center1->[Y] - scale 10) < scaled_epsilon, 'center was correctly detected'; ok abs($center1->[X] - scale 10) < scaled_epsilon && abs($center1->[Y] - scale 10) < scaled_epsilon, 'center was correctly detected';
my $center2 = [ map sprintf('%.0f', $_), @{ $collection2->paths->[0]->center } ]; my $center2 = [ map sprintf('%.0f', $_), @{ $paths2[0]->center } ];
ok abs($center2->[X] - scale 10) < scaled_epsilon && abs($center1->[Y] - scale 10) < scaled_epsilon, 'center was correctly detected'; ok abs($center2->[X] - scale 10) < scaled_epsilon && abs($center1->[Y] - scale 10) < scaled_epsilon, 'center was correctly detected';
} }

View file

@ -71,11 +71,11 @@ sub scale_points (@) { map [scale $_->[X], scale $_->[Y]], @_ }
} }
{ {
my $collection = Slic3r::ExtrusionPath::Collection->new(paths => [ my $collection = Slic3r::ExtrusionPath::Collection->new(
map Slic3r::ExtrusionPath->new(polyline => $_, role => 0), map Slic3r::ExtrusionPath->new(polyline => $_, role => 0),
Slic3r::Polyline->new([0,15], [0,18], [0,20]), Slic3r::Polyline->new([0,15], [0,18], [0,20]),
Slic3r::Polyline->new([0,10], [0,8], [0,5]), Slic3r::Polyline->new([0,10], [0,8], [0,5]),
]); );
is_deeply is_deeply
[ map $_->[Y], map @{$_->polyline}, $collection->chained_path(Slic3r::Point->new(0,30)) ], [ map $_->[Y], map @{$_->polyline}, $collection->chained_path(Slic3r::Point->new(0,30)) ],
[20, 18, 15, 10, 8, 5], [20, 18, 15, 10, 8, 5],
@ -83,11 +83,11 @@ sub scale_points (@) { map [scale $_->[X], scale $_->[Y]], @_ }
} }
{ {
my $collection = Slic3r::ExtrusionPath::Collection->new(paths => [ my $collection = Slic3r::ExtrusionPath::Collection->new(
map Slic3r::ExtrusionPath->new(polyline => $_, role => 0), map Slic3r::ExtrusionPath->new(polyline => $_, role => 0),
Slic3r::Polyline->new([15,0], [10,0], [4,0]), Slic3r::Polyline->new([15,0], [10,0], [4,0]),
Slic3r::Polyline->new([10,5], [15,5], [20,5]), Slic3r::Polyline->new([10,5], [15,5], [20,5]),
]); );
is_deeply is_deeply
[ map $_->[X], map @{$_->polyline}, $collection->chained_path(Slic3r::Point->new(30,0)) ], [ map $_->[X], map @{$_->polyline}, $collection->chained_path(Slic3r::Point->new(30,0)) ],
[reverse 4, 10, 15, 10, 15, 20], [reverse 4, 10, 15, 10, 15, 20],

View file

@ -43,6 +43,14 @@ use overload
'@{}' => sub { $_[0]->arrayref }, '@{}' => sub { $_[0]->arrayref },
'fallback' => 1; 'fallback' => 1;
sub new {
my ($class, @paths) = @_;
my $self = $class->_new;
$self->append(@paths);
return $self;
}
package Slic3r::ExtrusionLoop; package Slic3r::ExtrusionLoop;
use overload use overload
'@{}' => sub { $_[0]->arrayref }, '@{}' => sub { $_[0]->arrayref },

View file

@ -6,7 +6,7 @@
namespace Slic3r { namespace Slic3r {
class ExtrusionEntityCollection class ExtrusionEntityCollection : public ExtrusionEntity
{ {
public: public:
ExtrusionEntitiesPtr entities; ExtrusionEntitiesPtr entities;

View file

@ -4,7 +4,7 @@ use strict;
use warnings; use warnings;
use Slic3r::XS; use Slic3r::XS;
use Test::More tests => 5; use Test::More tests => 8;
my $points = [ my $points = [
[100, 100], [100, 100],
@ -22,16 +22,23 @@ my $loop = Slic3r::ExtrusionLoop->new(
role => Slic3r::ExtrusionPath::EXTR_ROLE_FILL, role => Slic3r::ExtrusionPath::EXTR_ROLE_FILL,
); );
my $collection = Slic3r::ExtrusionPath::Collection->new; my $collection = Slic3r::ExtrusionPath::Collection->new($path);
isa_ok $collection, 'Slic3r::ExtrusionPath::Collection', 'collection object'; isa_ok $collection, 'Slic3r::ExtrusionPath::Collection', 'collection object with items in constructor';
$collection->append($collection);
is scalar(@$collection), 2, 'append ExtrusionPath::Collection';
$collection->append($path); $collection->append($path);
is scalar(@$collection), 1, 'append ExtrusionPath'; is scalar(@$collection), 3, 'append ExtrusionPath';
$collection->append($loop); $collection->append($loop);
is scalar(@$collection), 2, 'append ExtrusionLoop'; is scalar(@$collection), 4, 'append ExtrusionLoop';
isa_ok $collection->[1], 'Slic3r::ExtrusionPath::Collection', 'correct object returned for collection';
isa_ok $collection->[2], 'Slic3r::ExtrusionPath', 'correct object returned for path';
isa_ok $collection->[3], 'Slic3r::ExtrusionLoop', 'correct object returned for loop';
is scalar(@{$collection->[1]}), 1, 'appended collection was duplicated';
isa_ok $collection->[0], 'Slic3r::ExtrusionPath', 'correct object returned for path';
isa_ok $collection->[1], 'Slic3r::ExtrusionLoop', 'correct object returned for loop';
__END__ __END__

View file

@ -6,7 +6,7 @@
%} %}
%name{Slic3r::ExtrusionPath::Collection} class ExtrusionEntityCollection { %name{Slic3r::ExtrusionPath::Collection} class ExtrusionEntityCollection {
ExtrusionEntityCollection(); %name{_new} ExtrusionEntityCollection();
~ExtrusionEntityCollection(); ~ExtrusionEntityCollection();
void clear() void clear()
%code{% THIS->entities.clear(); %}; %code{% THIS->entities.clear(); %};
@ -23,8 +23,10 @@ ExtrusionEntityCollection::arrayref()
// return COPIES // return COPIES
if (ExtrusionPath* path = dynamic_cast<ExtrusionPath*>(*it)) { if (ExtrusionPath* path = dynamic_cast<ExtrusionPath*>(*it)) {
sv_setref_pv( sv, "Slic3r::ExtrusionPath", new ExtrusionPath(*(ExtrusionPath*)*it) ); sv_setref_pv( sv, "Slic3r::ExtrusionPath", new ExtrusionPath(*(ExtrusionPath*)*it) );
} else { } else if (ExtrusionLoop* path = dynamic_cast<ExtrusionLoop*>(*it)) {
sv_setref_pv( sv, "Slic3r::ExtrusionLoop", new ExtrusionLoop(*(ExtrusionLoop*)*it) ); sv_setref_pv( sv, "Slic3r::ExtrusionLoop", new ExtrusionLoop(*(ExtrusionLoop*)*it) );
} else {
sv_setref_pv( sv, "Slic3r::ExtrusionPath::Collection", new ExtrusionEntityCollection(*(ExtrusionEntityCollection*)*it) );
} }
av_store(av, i++, sv); av_store(av, i++, sv);
} }
@ -40,8 +42,10 @@ ExtrusionEntityCollection::append(...)
// append COPIES // append COPIES
if (ExtrusionPath* path = dynamic_cast<ExtrusionPath*>(entity)) { if (ExtrusionPath* path = dynamic_cast<ExtrusionPath*>(entity)) {
THIS->entities.push_back( new ExtrusionPath(*path) ); THIS->entities.push_back( new ExtrusionPath(*path) );
} else if (ExtrusionLoop* loop = dynamic_cast<ExtrusionLoop*>(entity)) {
THIS->entities.push_back( new ExtrusionLoop(*loop) );
} else { } else {
THIS->entities.push_back( new ExtrusionLoop(*(ExtrusionLoop*)entity) ); THIS->entities.push_back( new ExtrusionEntityCollection(*(ExtrusionEntityCollection*)entity) );
} }
} }