Просмотр исходного кода

Ported Slic3r::Polyline::Collection

Alessandro Ranellucci 11 лет назад
Родитель
Сommit
1cfdf7e955

+ 2 - 2
lib/Slic3r/Fill/Honeycomb.pm

@@ -96,9 +96,9 @@ sub fill_surface {
         
         # connect paths
         {
-            my $collection = Slic3r::Polyline::Collection->new(polylines => [@paths]);
+            my $collection = Slic3r::Polyline::Collection->new(@paths);
             @paths = ();
-            foreach my $path ($collection->chained_path) {
+            foreach my $path (@{$collection->chained_path(0)}) {
                 if (@paths) {
                     # distance between first point of this path and last point of last path
                     my $distance = $paths[-1]->last_point->distance_to($path->first_point);

+ 2 - 4
lib/Slic3r/Fill/Rectilinear.pm

@@ -66,9 +66,7 @@ sub fill_surface {
     # connect lines
     unless ($params{dont_connect}) {
         my ($expolygon_off) = @{$expolygon->offset_ex(scale $params{flow_spacing}/2)};
-        my $collection = Slic3r::Polyline::Collection->new(
-            polylines => [ @polylines ],
-        );
+        my $collection = Slic3r::Polyline::Collection->new(@polylines);
         @polylines = ();
         
         my $tolerance = 10 * scaled_epsilon;
@@ -80,7 +78,7 @@ sub fill_surface {
             }
             : sub { $_[X] <= $diagonal_distance && $_[Y] <= $diagonal_distance };
         
-        foreach my $polyline ($collection->chained_path) {
+        foreach my $polyline (@{$collection->chained_path(0)}) {
             if (@polylines) {
                 my $first_point = $polyline->first_point;
                 my $last_point = $polylines[-1]->last_point;

+ 0 - 34
lib/Slic3r/Polyline.pm

@@ -163,38 +163,4 @@ sub regular_points {
     return @points;
 }
 
-package Slic3r::Polyline::Collection;
-use Moo;
-
-has 'polylines' => (is => 'ro', default => sub { [] });
-
-# Note that our polylines will be reversed in place when necessary.
-sub chained_path {
-    my $self = shift;
-    my ($start_near, $no_reverse) = @_;
-    
-    my @my_paths = @{$self->polylines};
-    
-    my @paths = ();
-    my $start_at;
-    my $endpoints = $no_reverse
-        ? [ map { @$_[0,0] }  @my_paths ]
-        : [ map { @$_[0,-1] } @my_paths ];
-    while (@my_paths) {
-        # find nearest point
-        my $start_index = defined $start_near
-            ? $start_near->nearest_point_index($endpoints)
-            : 0;
-
-        my $path_index = int($start_index/2);
-        if ($start_index % 2 && !$no_reverse) { # index is end so reverse to make it the start
-            $my_paths[$path_index]->reverse;
-        }
-        push @paths, splice @my_paths, $path_index, 1;
-        splice @$endpoints, $path_index*2, 2;
-        $start_near = $paths[-1]->last_point;
-    }
-    return @paths;
-}
-
 1;

+ 6 - 6
t/fill.t

@@ -110,23 +110,23 @@ sub scale_points (@) { map [scale $_->[X], scale $_->[Y]], @_ }
 }
 
 {
-    my $collection = Slic3r::Polyline::Collection->new(polylines => [
+    my $collection = Slic3r::Polyline::Collection->new(
         Slic3r::Polyline->new([0,15], [0,18], [0,20]),
         Slic3r::Polyline->new([0,10], [0,8], [0,5]),
-    ]);
+    );
     is_deeply
-        [ map $_->[Y], map @$_, $collection->chained_path(Slic3r::Point->new(0,30), 0) ],
+        [ map $_->[Y], map @$_, @{$collection->chained_path(Slic3r::Point->new(0,30), 0)} ],
         [20, 18, 15, 10, 8, 5],
         'chained path';
 }
 
 {
-    my $collection = Slic3r::Polyline::Collection->new(polylines => [
+    my $collection = Slic3r::Polyline::Collection->new(
         Slic3r::Polyline->new([4,0], [10,0], [15,0]),
         Slic3r::Polyline->new([10,5], [15,5], [20,5]),
-    ]);
+    );
     is_deeply
-        [ map $_->[X], map @$_, $collection->chained_path(Slic3r::Point->new(30,0), 0) ],
+        [ map $_->[X], map @$_, @{$collection->chained_path(Slic3r::Point->new(30,0), 0)} ],
         [reverse 4, 10, 15, 10, 15, 20],
         'chained path';
 }

+ 5 - 0
xs/lib/Slic3r/XS.pm

@@ -27,6 +27,11 @@ use overload
     '@{}' => sub { $_[0]->arrayref },
     'fallback' => 1;
 
+package Slic3r::Polyline::Collection;
+use overload
+    '@{}' => sub { $_[0]->arrayref },
+    'fallback' => 1;
+
 package Slic3r::Polygon;
 use overload
     '@{}' => sub { $_[0]->arrayref },

+ 8 - 0
xs/src/Polyline.cpp

@@ -12,4 +12,12 @@ Polyline::lines()
     return lines;
 }
 
+SV*
+Polyline::to_SV_ref() const
+{
+    SV* sv = newSV(0);
+    sv_setref_pv( sv, "Slic3r::Polyline", new Polyline(*this) );
+    return sv;
+}
+
 }

+ 1 - 0
xs/src/Polyline.hpp

@@ -9,6 +9,7 @@ namespace Slic3r {
 class Polyline : public MultiPoint {
     public:
     Lines lines();
+    SV* to_SV_ref() const;
 };
 
 typedef std::vector<Polyline> Polylines;

+ 46 - 0
xs/src/PolylineCollection.cpp

@@ -0,0 +1,46 @@
+#include "PolylineCollection.hpp"
+
+namespace Slic3r {
+
+PolylineCollection*
+PolylineCollection::chained_path(bool no_reverse) const
+{
+    if (this->polylines.empty()) {
+        return new PolylineCollection ();
+    }
+    return this->chained_path_from(this->polylines.front().first_point(), no_reverse);
+}
+
+PolylineCollection*
+PolylineCollection::chained_path_from(const Point* start_near, bool no_reverse) const
+{
+    PolylineCollection* retval = new PolylineCollection;
+    Polylines my_paths = this->polylines;
+    
+    Points endpoints;
+    for (Polylines::const_iterator it = my_paths.begin(); it != my_paths.end(); ++it) {
+        endpoints.push_back(*(*it).first_point());
+        if (no_reverse) {
+            endpoints.push_back(*(*it).first_point());
+        } else {
+            endpoints.push_back(*(*it).last_point());
+        }
+    }
+    
+    while (!my_paths.empty()) {
+        // find nearest point
+        int start_index = start_near->nearest_point_index(endpoints);
+        int path_index = start_index/2;
+        if (start_index % 2 && !no_reverse) {
+            my_paths.at(path_index).reverse();
+        }
+        retval->polylines.push_back(my_paths.at(path_index));
+        my_paths.erase(my_paths.begin() + path_index);
+        endpoints.erase(endpoints.begin() + 2*path_index, endpoints.begin() + 2*path_index + 2);
+        start_near = retval->polylines.back().last_point();
+    }
+    
+    return retval;
+}
+
+}

+ 19 - 0
xs/src/PolylineCollection.hpp

@@ -0,0 +1,19 @@
+#ifndef slic3r_PolylineCollection_hpp_
+#define slic3r_PolylineCollection_hpp_
+
+#include <myinit.h>
+#include "Polyline.hpp"
+
+namespace Slic3r {
+
+class PolylineCollection
+{
+    public:
+    Polylines polylines;
+    PolylineCollection* chained_path(bool no_reverse) const;
+    PolylineCollection* chained_path_from(const Point* start_near, bool no_reverse) const;
+};
+
+}
+
+#endif

+ 35 - 0
xs/t/13_polylinecollection.t

@@ -0,0 +1,35 @@
+#!/usr/bin/perl
+
+use strict;
+use warnings;
+
+use Slic3r::XS;
+use Test::More tests => 3;
+
+{
+    my $collection = Slic3r::Polyline::Collection->new(
+        Slic3r::Polyline->new([0,15], [0,18], [0,20]),
+        Slic3r::Polyline->new([0,10], [0,8], [0,5]),
+    );
+    is_deeply
+        [ map $_->y, map @$_, @{$collection->chained_path_from(Slic3r::Point->new(0,30), 0)} ],
+        [20, 18, 15, 10, 8, 5],
+        'chained_path_from';
+    is_deeply
+        [ map $_->y, map @$_, @{$collection->chained_path(0)} ],
+        [15, 18, 20, 10, 8, 5],
+        'chained_path';
+}
+
+{
+    my $collection = Slic3r::Polyline::Collection->new(
+        Slic3r::Polyline->new([15,0], [10,0], [4,0]),
+        Slic3r::Polyline->new([10,5], [15,5], [20,5]),
+    );
+    is_deeply
+        [ map $_->x, map @$_, @{$collection->chained_path_from(Slic3r::Point->new(30,0), 0)} ],
+        [reverse 4, 10, 15, 10, 15, 20],
+        'chained_path_from';
+}
+
+__END__

Некоторые файлы не были показаны из-за большого количества измененных файлов