mirror of
				https://github.com/SoftFever/OrcaSlicer.git
				synced 2025-11-02 12:41:18 -07:00 
			
		
		
		
	
		
			
				
	
	
		
			171 lines
		
	
	
	
		
			6 KiB
		
	
	
	
		
			Perl
		
	
	
	
	
	
			
		
		
	
	
			171 lines
		
	
	
	
		
			6 KiB
		
	
	
	
		
			Perl
		
	
	
	
	
	
#!/usr/bin/perl
 | 
						||
# This script exports experimental G-code for wireframe printing
 | 
						||
# (inspired by the brilliant WirePrint concept)
 | 
						||
 | 
						||
use strict;
 | 
						||
use warnings;
 | 
						||
 | 
						||
BEGIN {
 | 
						||
    use FindBin;
 | 
						||
    use lib "$FindBin::Bin/../lib";
 | 
						||
}
 | 
						||
 | 
						||
use Getopt::Long qw(:config no_auto_abbrev);
 | 
						||
use Slic3r;
 | 
						||
use Slic3r::ExtrusionPath ':roles';
 | 
						||
use Slic3r::Geometry qw(scale unscale X Y PI);
 | 
						||
 | 
						||
my %opt = (
 | 
						||
    step_height         => 5,
 | 
						||
    nozzle_angle        => 30,
 | 
						||
    nozzle_width        => 10,
 | 
						||
    first_layer_height  => 0.3,
 | 
						||
);
 | 
						||
{
 | 
						||
    my %options = (
 | 
						||
        'help'                  => sub { usage() },
 | 
						||
        'output|o=s'            => \$opt{output_file},
 | 
						||
        'step-height|h=f'       => \$opt{step_height},
 | 
						||
        'nozzle-angle|a=f'      => \$opt{nozzle_angle},
 | 
						||
        'nozzle-width|w=f'      => \$opt{nozzle_width},
 | 
						||
        'first-layer-height=f'  => \$opt{first_layer_height},
 | 
						||
    );
 | 
						||
    GetOptions(%options) or usage(1);
 | 
						||
    $opt{output_file} or usage(1);
 | 
						||
    $ARGV[0] or usage(1);
 | 
						||
}
 | 
						||
 | 
						||
{
 | 
						||
    # load model
 | 
						||
    my $model = Slic3r::Model->read_from_file($ARGV[0]);
 | 
						||
    $model->center_instances_around_point(Slic3r::Pointf->new(100,100));
 | 
						||
    my $mesh = $model->mesh;
 | 
						||
    $mesh->translate(0, 0, -$mesh->bounding_box->z_min);
 | 
						||
    
 | 
						||
    # get slices
 | 
						||
    my @z = ();
 | 
						||
    my $z_max = $mesh->bounding_box->z_max;
 | 
						||
    for (my $z = $opt{first_layer_height}; $z <= $z_max; $z += $opt{step_height}) {
 | 
						||
        push @z, $z;
 | 
						||
    }
 | 
						||
    my @slices = @{$mesh->slice(\@z)};
 | 
						||
    
 | 
						||
    my $flow = Slic3r::Flow->new(
 | 
						||
        width           => 0.35,
 | 
						||
        height          => 0.35,
 | 
						||
        nozzle_diameter => 0.35,
 | 
						||
        bridge          => 1,
 | 
						||
    );
 | 
						||
    
 | 
						||
    my $config = Slic3r::Config::Print->new;
 | 
						||
    $config->set('gcode_comments', 1);
 | 
						||
    
 | 
						||
    open my $fh, '>', $opt{output_file};
 | 
						||
    my $gcodegen = Slic3r::GCode->new(
 | 
						||
        enable_loop_clipping => 0,  # better bonding
 | 
						||
    );
 | 
						||
    $gcodegen->apply_print_config($config);
 | 
						||
    $gcodegen->set_extruders([0]);
 | 
						||
    print $fh $gcodegen->set_extruder(0);
 | 
						||
    print $fh $gcodegen->writer->preamble;
 | 
						||
    
 | 
						||
    my $e = $gcodegen->writer->extruder->e_per_mm3 * $flow->mm3_per_mm;
 | 
						||
    
 | 
						||
    foreach my $layer_id (0..$#z) {
 | 
						||
        my $z = $z[$layer_id];
 | 
						||
        
 | 
						||
        foreach my $island (@{$slices[$layer_id]}) {
 | 
						||
            foreach my $polygon (@$island) {
 | 
						||
                if ($layer_id > 0) {
 | 
						||
                    # find the lower polygon that we want to connect to this one
 | 
						||
                    my $lower = $slices[$layer_id-1]->[0]->contour;  # 't was easy, wasn't it?
 | 
						||
                    my $lower_z = $z[$layer_id-1];
 | 
						||
                    
 | 
						||
                    {
 | 
						||
                        my @points = ();
 | 
						||
                        
 | 
						||
                        # keep all points with strong angles
 | 
						||
                        {
 | 
						||
                            my @pp = @$polygon;
 | 
						||
                            foreach my $i (0..$#pp) {
 | 
						||
                                push @points, $pp[$i-1] if abs($pp[$i-1]->ccw_angle($pp[$i-2], $pp[$i]) - PI) > PI/3;
 | 
						||
                            }
 | 
						||
                        }
 | 
						||
                        
 | 
						||
                        $polygon = Slic3r::Polygon->new(@points);
 | 
						||
                    }
 | 
						||
                    #$polygon = Slic3r::Polygon->new(@{$polygon->split_at_first_point->equally_spaced_points(scale $opt{nozzle_width})});
 | 
						||
                    
 | 
						||
                    # find vertical lines
 | 
						||
                    my @vertical = ();
 | 
						||
                    foreach my $point (@{$polygon}) {
 | 
						||
                        push @vertical, Slic3r::Line->new($point->projection_onto_polygon($lower), $point);
 | 
						||
                    }
 | 
						||
                    
 | 
						||
                    next if !@vertical;
 | 
						||
                
 | 
						||
                    my @points = ();
 | 
						||
                    foreach my $line (@vertical) {
 | 
						||
                        push @points, Slic3r::Pointf3->new(
 | 
						||
                            unscale($line->a->x),
 | 
						||
                            unscale($line->a->y),  #))
 | 
						||
                            $lower_z,
 | 
						||
                        );
 | 
						||
                        push @points, Slic3r::Pointf3->new(
 | 
						||
                            unscale($line->b->x),
 | 
						||
                            unscale($line->b->y),  #))
 | 
						||
                            $z,
 | 
						||
                        );
 | 
						||
                    }
 | 
						||
                
 | 
						||
                    # reappend first point as destination of the last diagonal segment
 | 
						||
                    push @points, Slic3r::Pointf3->new(
 | 
						||
                        unscale($vertical[0]->a->x),
 | 
						||
                        unscale($vertical[0]->a->y),  #))
 | 
						||
                        $lower_z,
 | 
						||
                    );
 | 
						||
                
 | 
						||
                    # move to the position of the first vertical line
 | 
						||
                    print $fh $gcodegen->writer->travel_to_xyz(shift @points);
 | 
						||
                
 | 
						||
                    # extrude segments
 | 
						||
                    foreach my $point (@points) {
 | 
						||
                        print $fh $gcodegen->writer->extrude_to_xyz($point, $e * $gcodegen->writer->get_position->distance_to($point));
 | 
						||
                    }
 | 
						||
                }
 | 
						||
            }
 | 
						||
            
 | 
						||
        print $fh $gcodegen->writer->travel_to_z($z);
 | 
						||
            foreach my $polygon (@$island) {
 | 
						||
                #my $polyline = $polygon->split_at_vertex(Slic3r::Point->new_scale(@{$gcodegen->writer->get_position}[0,1]));
 | 
						||
                my $polyline = $polygon->split_at_first_point;
 | 
						||
                print $fh $gcodegen->writer->travel_to_xy(Slic3r::Pointf->new_unscale(@{ $polyline->first_point }), "move to first contour point");
 | 
						||
                
 | 
						||
                foreach my $line (@{$polyline->lines}) {
 | 
						||
                    my $point = Slic3r::Pointf->new_unscale(@{ $line->b });
 | 
						||
                    print $fh $gcodegen->writer->extrude_to_xy($point, $e * unscale($line->length));
 | 
						||
                }
 | 
						||
            }
 | 
						||
        }
 | 
						||
    }
 | 
						||
    
 | 
						||
    close $fh;
 | 
						||
}
 | 
						||
 | 
						||
sub usage {
 | 
						||
    my ($exit_code) = @_;
 | 
						||
    
 | 
						||
    print <<"EOF";
 | 
						||
Usage: wireframe.pl [ OPTIONS ] file.stl
 | 
						||
 | 
						||
    --help              Output this usage screen and exit
 | 
						||
    --output, -o        Write to the specified file
 | 
						||
    --step-height, -h   Use the specified step height
 | 
						||
    --nozzle-angle, -a  Max nozzle angle
 | 
						||
    --nozzle-width, -w  External nozzle diameter
 | 
						||
    
 | 
						||
EOF
 | 
						||
    exit ($exit_code || 0);
 | 
						||
}
 | 
						||
 | 
						||
__END__
 |