mirror of
https://github.com/SoftFever/OrcaSlicer.git
synced 2025-07-24 23:23:59 -06:00
Update support material code to use shared memory
This commit is contained in:
parent
c421feb633
commit
6adce9f66b
3 changed files with 36 additions and 57 deletions
|
@ -97,6 +97,7 @@ sub parallelize {
|
||||||
Slic3r::thread_cleanup();
|
Slic3r::thread_cleanup();
|
||||||
return $result;
|
return $result;
|
||||||
};
|
};
|
||||||
|
$params{collect_cb} ||= sub {};
|
||||||
|
|
||||||
@_ = ();
|
@_ = ();
|
||||||
foreach my $th (map threads->create($thread_cb), 1..$Config->threads) {
|
foreach my $th (map threads->create($thread_cb), 1..$Config->threads) {
|
||||||
|
@ -113,6 +114,11 @@ sub parallelize {
|
||||||
# inherited at the thread creation (thus shared) and those
|
# inherited at the thread creation (thus shared) and those
|
||||||
# that we are returning: destruction will be handled by the
|
# that we are returning: destruction will be handled by the
|
||||||
# main thread in both cases.
|
# main thread in both cases.
|
||||||
|
# reminder: do not destroy inherited objects in other threads,
|
||||||
|
# as the main thread will still try to destroy them when they
|
||||||
|
# go out of scope; in other words, if you're undef()'ing an
|
||||||
|
# object in a thread, make sure the main thread still holds a
|
||||||
|
# reference so that it won't be destroyed in thread.
|
||||||
sub thread_cleanup {
|
sub thread_cleanup {
|
||||||
# prevent destruction of shared objects
|
# prevent destruction of shared objects
|
||||||
no warnings 'redefine';
|
no warnings 'redefine';
|
||||||
|
|
|
@ -69,9 +69,9 @@ use Moo;
|
||||||
extends 'Slic3r::Layer';
|
extends 'Slic3r::Layer';
|
||||||
|
|
||||||
# ordered collection of extrusion paths to fill surfaces for support material
|
# ordered collection of extrusion paths to fill surfaces for support material
|
||||||
has 'support_islands' => (is => 'rw', default => sub { [] });
|
has 'support_islands' => (is => 'rw', default => sub { Slic3r::ExPolygon::Collection->new });
|
||||||
has 'support_fills' => (is => 'rw');
|
has 'support_fills' => (is => 'rw', default => sub { Slic3r::ExtrusionPath::Collection->new });
|
||||||
has 'support_interface_fills' => (is => 'rw');
|
has 'support_interface_fills' => (is => 'rw', default => sub { Slic3r::ExtrusionPath::Collection->new });
|
||||||
|
|
||||||
sub islands {
|
sub islands {
|
||||||
my $self = shift;
|
my $self = shift;
|
||||||
|
|
|
@ -1024,32 +1024,27 @@ sub generate_support_material {
|
||||||
|
|
||||||
my $process_layer = sub {
|
my $process_layer = sub {
|
||||||
my ($layer_id) = @_;
|
my ($layer_id) = @_;
|
||||||
|
my $layer = $self->support_layers->[$layer_id];
|
||||||
|
|
||||||
$contact{$support_layers[$layer_id]} ||= [];
|
my $overhang = $overhang{$support_layers[$layer_id]} || [];
|
||||||
$interface{$layer_id} ||= [];
|
my $contact = $contact{$support_layers[$layer_id]} || [];
|
||||||
$support{$layer_id} ||= [];
|
my $interface = $interface{$layer_id} || [];
|
||||||
|
my $support = $support{$layer_id} || [];
|
||||||
|
|
||||||
if (0) {
|
if (0) {
|
||||||
require "Slic3r/SVG.pm";
|
require "Slic3r/SVG.pm";
|
||||||
Slic3r::SVG::output("layer_" . $support_layers[$layer_id] . ".svg",
|
Slic3r::SVG::output("layer_" . $support_layers[$layer_id] . ".svg",
|
||||||
red_expolygons => union_ex($contact{$support_layers[$layer_id]}),
|
red_expolygons => union_ex($contact),
|
||||||
green_expolygons => union_ex($interface{$layer_id}),
|
green_expolygons => union_ex($interface),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
# islands
|
# islands
|
||||||
my $result = { contact => [], interface => [], support => [] };
|
$layer->support_islands->append(@{union_ex([ @$interface, @$support, @$contact ])});
|
||||||
$result->{islands} = union_ex([
|
|
||||||
map @$_,
|
|
||||||
$interface{$layer_id},
|
|
||||||
$support{$layer_id},
|
|
||||||
$contact{$support_layers[$layer_id]},
|
|
||||||
]);
|
|
||||||
|
|
||||||
# contact
|
# contact
|
||||||
my $contact_infill = [];
|
my $contact_infill = [];
|
||||||
if ((my $contact = $contact{$support_layers[$layer_id]}) && $contact_loops > 0) {
|
if ($contact && $contact_loops > 0) {
|
||||||
my $overhang = $overhang{$support_layers[$layer_id]};
|
|
||||||
$contact = [ grep $_->is_counter_clockwise, @$contact ];
|
$contact = [ grep $_->is_counter_clockwise, @$contact ];
|
||||||
|
|
||||||
# generate the outermost loop
|
# generate the outermost loop
|
||||||
|
@ -1090,26 +1085,26 @@ sub generate_support_material {
|
||||||
flow_spacing => $flow->spacing,
|
flow_spacing => $flow->spacing,
|
||||||
), @loops;
|
), @loops;
|
||||||
|
|
||||||
$result->{contact} = [ @loops ];
|
$layer->support_interface_fills->append(@loops);
|
||||||
}
|
}
|
||||||
|
|
||||||
# interface and contact infill
|
# interface and contact infill
|
||||||
if (@{$interface{$layer_id}} || @$contact_infill) {
|
if (@$interface || @$contact_infill) {
|
||||||
$fillers{interface}->angle($interface_angle);
|
$fillers{interface}->angle($interface_angle);
|
||||||
|
|
||||||
# steal some space from support
|
# steal some space from support
|
||||||
$interface{$layer_id} = intersection(
|
$interface = intersection(
|
||||||
offset([ map @$_, $interface{$layer_id}, $contact_infill ], scale 3),
|
offset([ @$interface, @$contact_infill ], scale 3),
|
||||||
[ map @$_, $interface{$layer_id}, $support{$layer_id}, $contact_infill ],
|
[ @$interface, @$support, @$contact_infill ],
|
||||||
1,
|
1,
|
||||||
);
|
);
|
||||||
$support{$layer_id} = diff(
|
$support{$layer_id} = diff(
|
||||||
$support{$layer_id},
|
$support,
|
||||||
$interface{$layer_id},
|
$interface,
|
||||||
);
|
);
|
||||||
|
|
||||||
my @paths = ();
|
my @paths = ();
|
||||||
foreach my $expolygon (@{union_ex($interface{$layer_id})}) {
|
foreach my $expolygon (@{union_ex($interface)}) {
|
||||||
my @p = $fillers{interface}->fill_surface(
|
my @p = $fillers{interface}->fill_surface(
|
||||||
Slic3r::Surface->new(expolygon => $expolygon, surface_type => S_TYPE_INTERNAL),
|
Slic3r::Surface->new(expolygon => $expolygon, surface_type => S_TYPE_INTERNAL),
|
||||||
density => $interface_density,
|
density => $interface_density,
|
||||||
|
@ -1125,18 +1120,18 @@ sub generate_support_material {
|
||||||
flow_spacing => $params->{flow_spacing},
|
flow_spacing => $params->{flow_spacing},
|
||||||
), @p;
|
), @p;
|
||||||
}
|
}
|
||||||
$result->{interface} = [ @paths ];
|
$layer->support_interface_fills->append(@paths);
|
||||||
}
|
}
|
||||||
|
|
||||||
# support or flange
|
# support or flange
|
||||||
if (@{$support{$layer_id}}) {
|
if (@$support) {
|
||||||
my $filler = $fillers{support};
|
my $filler = $fillers{support};
|
||||||
$filler->angle($angles[ ($layer_id) % @angles ]);
|
$filler->angle($angles[ ($layer_id) % @angles ]);
|
||||||
my $density = $support_density;
|
my $density = $support_density;
|
||||||
my $flow_spacing = $flow->spacing;
|
my $flow_spacing = $flow->spacing;
|
||||||
|
|
||||||
# TODO: use offset2_ex()
|
# TODO: use offset2_ex()
|
||||||
my $to_infill = union_ex($support{$layer_id}, 1);
|
my $to_infill = union_ex($support, 1);
|
||||||
my @paths = ();
|
my @paths = ();
|
||||||
|
|
||||||
# base flange
|
# base flange
|
||||||
|
@ -1176,52 +1171,30 @@ sub generate_support_material {
|
||||||
), @p;
|
), @p;
|
||||||
}
|
}
|
||||||
|
|
||||||
push @{$result->{support}}, @paths;
|
$layer->support_fills->append(@paths);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (0) {
|
if (0) {
|
||||||
require "Slic3r/SVG.pm";
|
require "Slic3r/SVG.pm";
|
||||||
Slic3r::SVG::output("islands_" . $support_layers[$layer_id] . ".svg",
|
Slic3r::SVG::output("islands_" . $support_layers[$layer_id] . ".svg",
|
||||||
red_expolygons => union_ex($contact{$support_layers[$layer_id]} || []),
|
red_expolygons => union_ex($contact),
|
||||||
green_expolygons => union_ex($interface{$layer_id} || []),
|
green_expolygons => union_ex($interface),
|
||||||
red_polylines => [ map $_->unpack->polyline, @{$result->{contact}} ],
|
green_polylines => [ map $_->unpack->polyline, @{$layer->support_contact_fills} ],
|
||||||
green_polylines => [ map $_->unpack->polyline, @{$result->{interface}} ],
|
polylines => [ map $_->unpack->polyline, @{$layer->support_fills} ],
|
||||||
polylines => [ map $_->unpack->polyline, @{$result->{support}} ],
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $result;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
my $apply = sub {
|
|
||||||
my ($layer_id, $result) = @_;
|
|
||||||
my $layer = $self->support_layers->[$layer_id];
|
|
||||||
|
|
||||||
my $interface_collection = Slic3r::ExtrusionPath::Collection->new(@{$result->{contact}}, @{$result->{interface}});
|
|
||||||
$layer->support_interface_fills($interface_collection) if @$interface_collection > 0;
|
|
||||||
|
|
||||||
my $support_collection = Slic3r::ExtrusionPath::Collection->new(@{$result->{support}});
|
|
||||||
$layer->support_fills($support_collection) if @$support_collection > 0;
|
|
||||||
|
|
||||||
# TODO: use a Slic3r::ExPolygon::Collection
|
|
||||||
$layer->support_islands($result->{islands});
|
|
||||||
};
|
|
||||||
Slic3r::parallelize(
|
Slic3r::parallelize(
|
||||||
items => [ 0 .. $#{$self->support_layers} ],
|
items => [ 0 .. $#{$self->support_layers} ],
|
||||||
thread_cb => sub {
|
thread_cb => sub {
|
||||||
my $q = shift;
|
my $q = shift;
|
||||||
my $result = {};
|
|
||||||
while (defined (my $layer_id = $q->dequeue)) {
|
while (defined (my $layer_id = $q->dequeue)) {
|
||||||
$result->{$layer_id} = $process_layer->($layer_id);
|
$process_layer->($layer_id);
|
||||||
}
|
}
|
||||||
return $result;
|
|
||||||
},
|
|
||||||
collect_cb => sub {
|
|
||||||
my $result = shift;
|
|
||||||
$apply->($_, $result->{$_}) for keys %$result;
|
|
||||||
},
|
},
|
||||||
no_threads_cb => sub {
|
no_threads_cb => sub {
|
||||||
$apply->($_, $process_layer->($_)) for 0 .. $#{$self->support_layers};
|
$process_layer->($_) for 0 .. $#{$self->support_layers};
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue