Browse Source

Some more work on wireframe

Alessandro Ranellucci 10 years ago
parent
commit
7253dc699a

+ 1 - 1
lib/Slic3r/GCode.pm

@@ -344,7 +344,7 @@ sub travel_to {
     if ($travel->length < scale $self->config->get_at('retract_before_travel', $self->writer->extruder->id)
     if ($travel->length < scale $self->config->get_at('retract_before_travel', $self->writer->extruder->id)
         || ($self->config->only_retract_when_crossing_perimeters
         || ($self->config->only_retract_when_crossing_perimeters
             && $self->config->fill_density > 0
             && $self->config->fill_density > 0
-            && $self->layer->any_internal_region_slice_contains_line($travel))
+            && defined($self->layer) && $self->layer->any_internal_region_slice_contains_line($travel))
         || (defined $role && $role == EXTR_ROLE_SUPPORTMATERIAL && $self->layer->support_islands->contains_line($travel))
         || (defined $role && $role == EXTR_ROLE_SUPPORTMATERIAL && $self->layer->support_islands->contains_line($travel))
         ) {
         ) {
         # Just perform a straight travel move without any retraction.
         # Just perform a straight travel move without any retraction.

+ 90 - 35
utils/wireframe.pl

@@ -11,14 +11,15 @@ BEGIN {
 }
 }
 
 
 use Getopt::Long qw(:config no_auto_abbrev);
 use Getopt::Long qw(:config no_auto_abbrev);
-use PDF::API2;
 use Slic3r;
 use Slic3r;
 use Slic3r::ExtrusionPath ':roles';
 use Slic3r::ExtrusionPath ':roles';
-use Slic3r::Geometry qw(scale unscale X Y);
+use Slic3r::Geometry qw(scale unscale X Y PI);
 
 
 my %opt = (
 my %opt = (
-    step_height => 10,
-    first_layer_height => 0.3,
+    step_height         => 5,
+    nozzle_angle        => 30,
+    nozzle_width        => 10,
+    first_layer_height  => 0.3,
 );
 );
 {
 {
     my %options = (
     my %options = (
@@ -30,13 +31,15 @@ my %opt = (
         'first-layer-height=f'  => \$opt{first_layer_height},
         'first-layer-height=f'  => \$opt{first_layer_height},
     );
     );
     GetOptions(%options) or usage(1);
     GetOptions(%options) or usage(1);
-    $opt{output_file} or usage(1);ì
+    $opt{output_file} or usage(1);
     $ARGV[0] or usage(1);
     $ARGV[0] or usage(1);
 }
 }
 
 
 {
 {
     # load model
     # load model
     my $model = Slic3r::Model->read_from_file($ARGV[0]);
     my $model = Slic3r::Model->read_from_file($ARGV[0]);
+    $model->add_default_instances;
+    $model->center_instances_around_point(Slic3r::Pointf->new(100,100));
     my $mesh = $model->mesh;
     my $mesh = $model->mesh;
     $mesh->translate(0, 0, -$mesh->bounding_box->z_min);
     $mesh->translate(0, 0, -$mesh->bounding_box->z_min);
     
     
@@ -46,6 +49,7 @@ my %opt = (
     for (my $z = $opt{first_layer_height}; $z <= $z_max; $z += $opt{step_height}) {
     for (my $z = $opt{first_layer_height}; $z <= $z_max; $z += $opt{step_height}) {
         push @z, $z;
         push @z, $z;
     }
     }
+    my @slices = @{$mesh->slice(\@z)};
     
     
     my $flow = Slic3r::Flow->new(
     my $flow = Slic3r::Flow->new(
         width           => 0.35,
         width           => 0.35,
@@ -54,45 +58,96 @@ my %opt = (
         bridge          => 1,
         bridge          => 1,
     );
     );
     
     
-    my $section;
-    
-    # build a square section
-    {
-        my $dist = 2 * $opt{step_height};  # horizontal step
-        my $side_modules = 3;
-        my @points = (
-            [0,0],
-            (map [$_*$dist, 0], 1..$side_modules),
-            (map [$side_modules*$dist, $_*$dist], 1..$side_modules),
-            (map [($_-1)*$dist, $side_modules*$dist], reverse 1..$side_modules),
-            (map [0, ($_-1)*$dist], reverse 1..$side_modules),
-        );
-        pop @points;  # prevent coinciding endpoints
-        $section = Slic3r::Polygon->new_scale(@points);
-    }
-    my $section_loop = Slic3r::ExtrusionLoop->new_from_paths(
-        Slic3r::ExtrusionPath->new(
-            polyline        => $section->split_at_first_point,
-            role            => EXTR_ROLE_BRIDGE,
-            mm3_per_mm      => $flow->mm3_per_mm,
-            width           => $flow->width,
-            height          => $flow->height,
-        )
-    );
-    
-    my $vertical_steps = 3;
+    my $config = Slic3r::Config::Print->new;
+    $config->set('gcode_comments', 1);
     
     
     open my $fh, '>', $opt{output_file};
     open my $fh, '>', $opt{output_file};
     my $gcodegen = Slic3r::GCode->new(
     my $gcodegen = Slic3r::GCode->new(
         enable_loop_clipping => 0,  # better bonding
         enable_loop_clipping => 0,  # better bonding
     );
     );
+    $gcodegen->apply_print_config($config);
     $gcodegen->set_extruders([0]);
     $gcodegen->set_extruders([0]);
     print $fh $gcodegen->set_extruder(0);
     print $fh $gcodegen->set_extruder(0);
     print $fh $gcodegen->writer->preamble;
     print $fh $gcodegen->writer->preamble;
     
     
-    foreach my $z (map $_*$opt{step_height}, 0..($vertical_steps-1)) {
-        print $fh $gcodegen->writer->travel_to_z($z + $flow->height);
-        print $fh $gcodegen->extrude_loop($section_loop, "contour");
+    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;
     close $fh;

+ 6 - 0
xs/src/libslic3r/GCodeWriter.cpp

@@ -491,6 +491,12 @@ GCodeWriter::unlift()
     return gcode;
     return gcode;
 }
 }
 
 
+Pointf3
+GCodeWriter::get_position() const
+{
+    return this->_pos;
+}
+
 #ifdef SLIC3RXS
 #ifdef SLIC3RXS
 REGISTER_CLASS(GCodeWriter, "GCode::Writer");
 REGISTER_CLASS(GCodeWriter, "GCode::Writer");
 #endif
 #endif

+ 1 - 0
xs/src/libslic3r/GCodeWriter.hpp

@@ -45,6 +45,7 @@ class GCodeWriter {
     std::string unretract();
     std::string unretract();
     std::string lift();
     std::string lift();
     std::string unlift();
     std::string unlift();
+    Pointf3 get_position() const;
     
     
     private:
     private:
     std::string _extrusion_axis;
     std::string _extrusion_axis;

+ 6 - 1
xs/src/libslic3r/Point.cpp

@@ -161,10 +161,15 @@ Point::ccw(const Line &line) const
 }
 }
 
 
 // returns the CCW angle between this-p1 and this-p2
 // returns the CCW angle between this-p1 and this-p2
+// i.e. this assumes a CCW rotation from p1 to p2 around this
 double
 double
 Point::ccw_angle(const Point &p1, const Point &p2) const
 Point::ccw_angle(const Point &p1, const Point &p2) const
 {
 {
-    return Line(*this, p1).orientation() - Line(*this, p2).orientation();
+    double angle = atan2(p1.x - this->x, p1.y - this->y)
+                 - atan2(p2.x - this->x, p2.y - this->y);
+    
+    // we only want to return only positive angles
+    return angle <= 0 ? angle + 2*PI : angle;
 }
 }
 
 
 Point
 Point

+ 1 - 0
xs/xsp/GCodeWriter.xsp

@@ -44,6 +44,7 @@
     std::string unretract();
     std::string unretract();
     std::string lift();
     std::string lift();
     std::string unlift();
     std::string unlift();
+    Clone<Pointf3> get_position() const;
 %{
 %{
 
 
 SV*
 SV*

+ 2 - 0
xs/xsp/Point.xsp

@@ -31,6 +31,8 @@
         %code{% RETVAL = THIS->distance_to(*line); %};
         %code{% RETVAL = THIS->distance_to(*line); %};
     double ccw(Point* p1, Point* p2)
     double ccw(Point* p1, Point* p2)
         %code{% RETVAL = THIS->ccw(*p1, *p2); %};
         %code{% RETVAL = THIS->ccw(*p1, *p2); %};
+    double ccw_angle(Point* p1, Point* p2)
+        %code{% RETVAL = THIS->ccw_angle(*p1, *p2); %};
     Clone<Point> projection_onto_polygon(Polygon* polygon)
     Clone<Point> projection_onto_polygon(Polygon* polygon)
         %code{% RETVAL = new Point(THIS->projection_onto(*polygon)); %};
         %code{% RETVAL = new Point(THIS->projection_onto(*polygon)); %};
     Clone<Point> projection_onto_polyline(Polyline* polyline)
     Clone<Point> projection_onto_polyline(Polyline* polyline)