Perform additional checks before merging solid surfaces (i.e. take flow and fill pattern into account)
This commit is contained in:
parent
634ccb33ab
commit
3d483722c6
@ -64,8 +64,54 @@ sub make_fill {
|
|||||||
{
|
{
|
||||||
my @surfaces_with_bridge_angle = grep defined $_->bridge_angle, @{$layerm->fill_surfaces};
|
my @surfaces_with_bridge_angle = grep defined $_->bridge_angle, @{$layerm->fill_surfaces};
|
||||||
|
|
||||||
|
# group surfaces by distinct properties
|
||||||
|
my @groups = @{$layerm->fill_surfaces->group};
|
||||||
|
|
||||||
|
# merge compatible groups (we can generate continuous infill for them)
|
||||||
|
{
|
||||||
|
# cache flow widths and patterns used for all solid groups
|
||||||
|
# (we'll use them for comparing compatible groups)
|
||||||
|
my @is_solid = my @fw = my @pattern = ();
|
||||||
|
for (my $i = 0; $i <= $#groups; $i++) {
|
||||||
|
# we can only merge solid non-bridge surfaces, so discard
|
||||||
|
# non-solid surfaces
|
||||||
|
if ($groups[$i][0]->is_solid && (!$groups[$i][0]->is_bridge || $layerm->id == 0)) {
|
||||||
|
$is_solid[$i] = 1;
|
||||||
|
$fw[$i] = ($groups[$i][0]->surface_type == S_TYPE_TOP)
|
||||||
|
? $layerm->flow(FLOW_ROLE_TOP_SOLID_INFILL)->width
|
||||||
|
: $solid_infill_flow->width;
|
||||||
|
$pattern[$i] = $groups[$i][0]->is_external
|
||||||
|
? $layerm->config->solid_fill_pattern
|
||||||
|
: 'rectilinear';
|
||||||
|
} else {
|
||||||
|
$is_solid[$i] = 0;
|
||||||
|
$fw[$i] = 0;
|
||||||
|
$pattern[$i] = 'none';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# loop through solid groups
|
||||||
|
for (my $i = 0; $i <= $#groups; $i++) {
|
||||||
|
next if !$is_solid[$i];
|
||||||
|
|
||||||
|
# find compatible groups and append them to this one
|
||||||
|
for (my $j = $i+1; $j <= $#groups; $j++) {
|
||||||
|
next if !$is_solid[$j];
|
||||||
|
|
||||||
|
if ($fw[$i] == $fw[$j] && $pattern[$i] eq $pattern[$j]) {
|
||||||
|
# groups are compatible, merge them
|
||||||
|
push @{$groups[$i]}, @{$groups[$j]};
|
||||||
|
splice @groups, $j, 1;
|
||||||
|
splice @is_solid, $j, 1;
|
||||||
|
splice @fw, $j, 1;
|
||||||
|
splice @pattern, $j, 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
# give priority to bridges
|
# give priority to bridges
|
||||||
my @groups = sort { defined $a->[0]->bridge_angle ? -1 : 0 } @{$layerm->fill_surfaces->group(1)};
|
@groups = sort { defined $a->[0]->bridge_angle ? -1 : 0 } @groups;
|
||||||
|
|
||||||
foreach my $group (@groups) {
|
foreach my $group (@groups) {
|
||||||
my $union_p = union([ map $_->p, @$group ], 1);
|
my $union_p = union([ map $_->p, @$group ], 1);
|
||||||
|
@ -16,6 +16,13 @@ Surface::is_solid() const
|
|||||||
|| this->surface_type == stInternalSolid;
|
|| this->surface_type == stInternalSolid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
Surface::is_external() const
|
||||||
|
{
|
||||||
|
return this->surface_type == stTop
|
||||||
|
|| this->surface_type == stBottom;
|
||||||
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
Surface::is_bridge() const
|
Surface::is_bridge() const
|
||||||
{
|
{
|
||||||
|
@ -18,6 +18,7 @@ class Surface
|
|||||||
unsigned short extra_perimeters;
|
unsigned short extra_perimeters;
|
||||||
double area() const;
|
double area() const;
|
||||||
bool is_solid() const;
|
bool is_solid() const;
|
||||||
|
bool is_external() const;
|
||||||
bool is_bridge() const;
|
bool is_bridge() const;
|
||||||
|
|
||||||
#ifdef SLIC3RXS
|
#ifdef SLIC3RXS
|
||||||
|
@ -21,14 +21,14 @@ SurfaceCollection::simplify(double tolerance)
|
|||||||
|
|
||||||
/* group surfaces by common properties */
|
/* group surfaces by common properties */
|
||||||
void
|
void
|
||||||
SurfaceCollection::group(std::vector<SurfacesPtr> *retval, bool merge_solid)
|
SurfaceCollection::group(std::vector<SurfacesPtr> *retval)
|
||||||
{
|
{
|
||||||
for (Surfaces::iterator it = this->surfaces.begin(); it != this->surfaces.end(); ++it) {
|
for (Surfaces::iterator it = this->surfaces.begin(); it != this->surfaces.end(); ++it) {
|
||||||
// find a group with the same properties
|
// find a group with the same properties
|
||||||
SurfacesPtr* group = NULL;
|
SurfacesPtr* group = NULL;
|
||||||
for (std::vector<SurfacesPtr>::iterator git = retval->begin(); git != retval->end(); ++git) {
|
for (std::vector<SurfacesPtr>::iterator git = retval->begin(); git != retval->end(); ++git) {
|
||||||
Surface* gkey = git->front();
|
Surface* gkey = git->front();
|
||||||
if ((gkey->surface_type == it->surface_type || (merge_solid && gkey->is_solid() && it->is_solid()))
|
if ( gkey->surface_type == it->surface_type
|
||||||
&& gkey->thickness == it->thickness
|
&& gkey->thickness == it->thickness
|
||||||
&& gkey->thickness_layers == it->thickness_layers
|
&& gkey->thickness_layers == it->thickness_layers
|
||||||
&& gkey->bridge_angle == it->bridge_angle) {
|
&& gkey->bridge_angle == it->bridge_angle) {
|
||||||
|
@ -11,7 +11,7 @@ class SurfaceCollection
|
|||||||
public:
|
public:
|
||||||
Surfaces surfaces;
|
Surfaces surfaces;
|
||||||
void simplify(double tolerance);
|
void simplify(double tolerance);
|
||||||
void group(std::vector<SurfacesPtr> *retval, bool merge_solid = false);
|
void group(std::vector<SurfacesPtr> *retval);
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,7 @@ use strict;
|
|||||||
use warnings;
|
use warnings;
|
||||||
|
|
||||||
use Slic3r::XS;
|
use Slic3r::XS;
|
||||||
use Test::More tests => 16;
|
use Test::More tests => 15;
|
||||||
|
|
||||||
my $square = [ # ccw
|
my $square = [ # ccw
|
||||||
[100, 100],
|
[100, 100],
|
||||||
@ -71,7 +71,6 @@ is $surface->extra_perimeters, 2, 'extra_perimeters';
|
|||||||
);
|
);
|
||||||
my $collection = Slic3r::Surface::Collection->new(@surfaces);
|
my $collection = Slic3r::Surface::Collection->new(@surfaces);
|
||||||
is scalar(@{$collection->group}), 2, 'group() returns correct number of groups';
|
is scalar(@{$collection->group}), 2, 'group() returns correct number of groups';
|
||||||
is scalar(@{$collection->group(1)}), 1, 'group() returns correct number of solid groups';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
__END__
|
__END__
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
%code{% RETVAL = THIS->thickness_layers; %};
|
%code{% RETVAL = THIS->thickness_layers; %};
|
||||||
double area();
|
double area();
|
||||||
bool is_solid() const;
|
bool is_solid() const;
|
||||||
|
bool is_external() const;
|
||||||
bool is_bridge() const;
|
bool is_bridge() const;
|
||||||
%{
|
%{
|
||||||
|
|
||||||
|
@ -76,12 +76,11 @@ SurfaceCollection::set_surface_type(index, surface_type)
|
|||||||
THIS->surfaces[index].surface_type = surface_type;
|
THIS->surfaces[index].surface_type = surface_type;
|
||||||
|
|
||||||
SV*
|
SV*
|
||||||
SurfaceCollection::group(merge_solid = false)
|
SurfaceCollection::group()
|
||||||
bool merge_solid
|
|
||||||
CODE:
|
CODE:
|
||||||
// perform grouping
|
// perform grouping
|
||||||
std::vector<SurfacesPtr> groups;
|
std::vector<SurfacesPtr> groups;
|
||||||
THIS->group(&groups, merge_solid);
|
THIS->group(&groups);
|
||||||
|
|
||||||
// build return arrayref
|
// build return arrayref
|
||||||
AV* av = newAV();
|
AV* av = newAV();
|
||||||
|
Loading…
Reference in New Issue
Block a user