Ported point_along_segment(), Polyline::length(), Polyline::clip_end() to XS
This commit is contained in:
parent
26a18a2a52
commit
29b83517cb
@ -264,8 +264,7 @@ sub extrude_loop {
|
|||||||
# the rotation of the second segment so we might cross the object boundary
|
# the rotation of the second segment so we might cross the object boundary
|
||||||
my $first_segment = Slic3r::Line->new(@{$extrusion_path->polyline}[0,1]);
|
my $first_segment = Slic3r::Line->new(@{$extrusion_path->polyline}[0,1]);
|
||||||
my $distance = min(scale $extrusion_path->flow_spacing, $first_segment->length);
|
my $distance = min(scale $extrusion_path->flow_spacing, $first_segment->length);
|
||||||
my $point = Slic3r::Geometry::point_along_segment(@$first_segment, $distance);
|
my $point = $first_segment->point_at($distance);
|
||||||
$point = Slic3r::Point->new(@$point);
|
|
||||||
$point->rotate($angle, $extrusion_path->first_point);
|
$point->rotate($angle, $extrusion_path->first_point);
|
||||||
|
|
||||||
# generate the travel move
|
# generate the travel move
|
||||||
@ -474,8 +473,8 @@ sub retract {
|
|||||||
my $wipe_path;
|
my $wipe_path;
|
||||||
if ($self->extruder->wipe && $self->wipe_path) {
|
if ($self->extruder->wipe && $self->wipe_path) {
|
||||||
my @points = @{$self->wipe_path};
|
my @points = @{$self->wipe_path};
|
||||||
$wipe_path = Slic3r::Polyline->new($self->last_pos, @{$self->wipe_path}[1..$#{$self->wipe_path}])
|
$wipe_path = Slic3r::Polyline->new($self->last_pos, @{$self->wipe_path}[1..$#{$self->wipe_path}]);
|
||||||
->clip_start($self->extruder->scaled_wipe_distance);
|
$wipe_path->clip_end($wipe_path->length - $self->extruder->scaled_wipe_distance);
|
||||||
}
|
}
|
||||||
|
|
||||||
# prepare moves
|
# prepare moves
|
||||||
|
@ -35,11 +35,6 @@ sub simplify {
|
|||||||
return __PACKAGE__->new(@$simplified);
|
return __PACKAGE__->new(@$simplified);
|
||||||
}
|
}
|
||||||
|
|
||||||
sub length {
|
|
||||||
my $self = shift;
|
|
||||||
return Boost::Geometry::Utils::linestring_length($self->pp);
|
|
||||||
}
|
|
||||||
|
|
||||||
sub grow {
|
sub grow {
|
||||||
my $self = shift;
|
my $self = shift;
|
||||||
my ($distance, $scale, $joinType, $miterLimit) = @_;
|
my ($distance, $scale, $joinType, $miterLimit) = @_;
|
||||||
@ -85,53 +80,6 @@ sub align_to_origin {
|
|||||||
return $self->translate(-$bb->x_min, -$bb->y_min);
|
return $self->translate(-$bb->x_min, -$bb->y_min);
|
||||||
}
|
}
|
||||||
|
|
||||||
# removes the given distance from the end of the polyline
|
|
||||||
sub clip_end {
|
|
||||||
my $self = shift;
|
|
||||||
my ($distance) = @_;
|
|
||||||
|
|
||||||
while ($distance > 0) {
|
|
||||||
my $last_point = $self->last_point->clone;
|
|
||||||
$self->pop_back;
|
|
||||||
last if @$self == 0;
|
|
||||||
|
|
||||||
my $last_segment_length = $last_point->distance_to($self->last_point);
|
|
||||||
if ($last_segment_length <= $distance) {
|
|
||||||
$distance -= $last_segment_length;
|
|
||||||
next;
|
|
||||||
}
|
|
||||||
|
|
||||||
my $new_point = Slic3r::Geometry::point_along_segment($last_point, $self->last_point, $distance);
|
|
||||||
$self->append($new_point);
|
|
||||||
$distance = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
# only keeps the given distance at the beginning of the polyline
|
|
||||||
sub clip_start {
|
|
||||||
my $self = shift;
|
|
||||||
my ($distance) = @_;
|
|
||||||
|
|
||||||
my @my_points = @$self;
|
|
||||||
my $points = [ $my_points[0]->clone ];
|
|
||||||
|
|
||||||
for (my $i = 1; $distance > 0 && $i <= $#my_points; $i++) {
|
|
||||||
my $point = $my_points[$i];
|
|
||||||
my $segment_length = $point->distance_to($my_points[$i-1]);
|
|
||||||
if ($segment_length <= $distance) {
|
|
||||||
$distance -= $segment_length;
|
|
||||||
push @$points, $point;
|
|
||||||
next;
|
|
||||||
}
|
|
||||||
|
|
||||||
my $new_point = Slic3r::Geometry::point_along_segment($my_points[$i-1], $point, $distance);
|
|
||||||
push @$points, Slic3r::Point->new(@$new_point);
|
|
||||||
$distance = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return __PACKAGE__->new(@$points);
|
|
||||||
}
|
|
||||||
|
|
||||||
# this method returns a collection of points picked on the polygon contour
|
# this method returns a collection of points picked on the polygon contour
|
||||||
# so that they are evenly spaced according to the input distance
|
# so that they are evenly spaced according to the input distance
|
||||||
# (find a better name!)
|
# (find a better name!)
|
||||||
|
@ -42,6 +42,18 @@ Line::midpoint() const
|
|||||||
return new Point ((this->a.x + this->b.x) / 2.0, (this->a.y + this->b.y) / 2.0);
|
return new Point ((this->a.x + this->b.x) / 2.0, (this->a.y + this->b.y) / 2.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Point*
|
||||||
|
Line::point_at(double distance) const
|
||||||
|
{
|
||||||
|
double len = this->length();
|
||||||
|
Point* p = new Point(this->a);
|
||||||
|
if (this->a.x != this->b.x)
|
||||||
|
p->x = this->a.x + (this->b.x - this->a.x) * distance / len;
|
||||||
|
if (this->a.y != this->b.y)
|
||||||
|
p->y = this->a.y + (this->b.y - this->a.y) * distance / len;
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef SLIC3RXS
|
#ifdef SLIC3RXS
|
||||||
void
|
void
|
||||||
Line::from_SV(SV* line_sv)
|
Line::from_SV(SV* line_sv)
|
||||||
|
@ -19,6 +19,7 @@ class Line
|
|||||||
void reverse();
|
void reverse();
|
||||||
double length() const;
|
double length() const;
|
||||||
Point* midpoint() const;
|
Point* midpoint() const;
|
||||||
|
Point* point_at(double distance) const;
|
||||||
|
|
||||||
#ifdef SLIC3RXS
|
#ifdef SLIC3RXS
|
||||||
void from_SV(SV* line_sv);
|
void from_SV(SV* line_sv);
|
||||||
|
@ -38,6 +38,17 @@ MultiPoint::first_point() const
|
|||||||
return new Point(this->points.front());
|
return new Point(this->points.front());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
double
|
||||||
|
MultiPoint::length() const
|
||||||
|
{
|
||||||
|
Lines lines = this->lines();
|
||||||
|
double len = 0;
|
||||||
|
for (Lines::iterator it = lines.begin(); it != lines.end(); ++it) {
|
||||||
|
len += it->length();
|
||||||
|
}
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef SLIC3RXS
|
#ifdef SLIC3RXS
|
||||||
void
|
void
|
||||||
MultiPoint::from_SV(SV* poly_sv)
|
MultiPoint::from_SV(SV* poly_sv)
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
#ifndef slic3r_MultiPoint_hpp_
|
#ifndef slic3r_MultiPoint_hpp_
|
||||||
#define slic3r_MultiPoint_hpp_
|
#define slic3r_MultiPoint_hpp_
|
||||||
|
|
||||||
|
#include "Line.hpp"
|
||||||
#include "Point.hpp"
|
#include "Point.hpp"
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
@ -17,6 +18,8 @@ class MultiPoint
|
|||||||
void reverse();
|
void reverse();
|
||||||
Point* first_point() const;
|
Point* first_point() const;
|
||||||
virtual Point* last_point() const = 0;
|
virtual Point* last_point() const = 0;
|
||||||
|
virtual Lines lines() const = 0;
|
||||||
|
double length() const;
|
||||||
|
|
||||||
#ifdef SLIC3RXS
|
#ifdef SLIC3RXS
|
||||||
void from_SV(SV* poly_sv);
|
void from_SV(SV* poly_sv);
|
||||||
|
@ -19,6 +19,27 @@ Polyline::lines() const
|
|||||||
return lines;
|
return lines;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// removes the given distance from the end of the polyline
|
||||||
|
void
|
||||||
|
Polyline::clip_end(double distance)
|
||||||
|
{
|
||||||
|
while (distance > 0) {
|
||||||
|
Point last_point = *this->last_point();
|
||||||
|
this->points.pop_back();
|
||||||
|
if (this->points.empty()) break;
|
||||||
|
|
||||||
|
double last_segment_length = last_point.distance_to(this->last_point());
|
||||||
|
if (last_segment_length <= distance) {
|
||||||
|
distance -= last_segment_length;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
Line segment(last_point, *this->last_point());
|
||||||
|
this->points.push_back(*segment.point_at(distance));
|
||||||
|
distance = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef SLIC3RXS
|
#ifdef SLIC3RXS
|
||||||
SV*
|
SV*
|
||||||
Polyline::to_SV_ref()
|
Polyline::to_SV_ref()
|
||||||
|
@ -10,6 +10,7 @@ class Polyline : public MultiPoint {
|
|||||||
public:
|
public:
|
||||||
Point* last_point() const;
|
Point* last_point() const;
|
||||||
Lines lines() const;
|
Lines lines() const;
|
||||||
|
void clip_end(double distance);
|
||||||
|
|
||||||
#ifdef SLIC3RXS
|
#ifdef SLIC3RXS
|
||||||
SV* to_SV_ref();
|
SV* to_SV_ref();
|
||||||
|
@ -4,7 +4,7 @@ use strict;
|
|||||||
use warnings;
|
use warnings;
|
||||||
|
|
||||||
use Slic3r::XS;
|
use Slic3r::XS;
|
||||||
use Test::More tests => 5;
|
use Test::More tests => 6;
|
||||||
|
|
||||||
my $points = [
|
my $points = [
|
||||||
[100, 100],
|
[100, 100],
|
||||||
@ -28,4 +28,10 @@ is_deeply [ map $_->pp, @$lines ], [
|
|||||||
$polyline->append_polyline($polyline->clone);
|
$polyline->append_polyline($polyline->clone);
|
||||||
is_deeply $polyline->pp, [ @$points, @$points ], 'append_polyline';
|
is_deeply $polyline->pp, [ @$points, @$points ], 'append_polyline';
|
||||||
|
|
||||||
|
{
|
||||||
|
my $len = $polyline->length;
|
||||||
|
$polyline->clip_end($len/3);
|
||||||
|
ok abs($polyline->length - ($len-($len/3))) < 1, 'clip_end';
|
||||||
|
}
|
||||||
|
|
||||||
__END__
|
__END__
|
||||||
|
@ -23,6 +23,8 @@
|
|||||||
double length();
|
double length();
|
||||||
Point* midpoint()
|
Point* midpoint()
|
||||||
%code{% const char* CLASS = "Slic3r::Point"; RETVAL = THIS->midpoint(); %};
|
%code{% const char* CLASS = "Slic3r::Point"; RETVAL = THIS->midpoint(); %};
|
||||||
|
Point* point_at(double distance)
|
||||||
|
%code{% const char* CLASS = "Slic3r::Point"; RETVAL = THIS->point_at(distance); %};
|
||||||
%{
|
%{
|
||||||
|
|
||||||
Line*
|
Line*
|
||||||
|
@ -23,6 +23,7 @@
|
|||||||
%code{% const char* CLASS = "Slic3r::Polyline"; RETVAL = THIS->split_at_index(index); %};
|
%code{% const char* CLASS = "Slic3r::Polyline"; RETVAL = THIS->split_at_index(index); %};
|
||||||
Polyline* split_at_first_point()
|
Polyline* split_at_first_point()
|
||||||
%code{% const char* CLASS = "Slic3r::Polyline"; RETVAL = THIS->split_at_first_point(); %};
|
%code{% const char* CLASS = "Slic3r::Polyline"; RETVAL = THIS->split_at_first_point(); %};
|
||||||
|
double length();
|
||||||
double area();
|
double area();
|
||||||
bool is_counter_clockwise();
|
bool is_counter_clockwise();
|
||||||
bool is_clockwise();
|
bool is_clockwise();
|
||||||
|
@ -23,6 +23,8 @@
|
|||||||
%code{% const char* CLASS = "Slic3r::Point"; RETVAL = THIS->first_point(); %};
|
%code{% const char* CLASS = "Slic3r::Point"; RETVAL = THIS->first_point(); %};
|
||||||
Point* last_point()
|
Point* last_point()
|
||||||
%code{% const char* CLASS = "Slic3r::Point"; RETVAL = THIS->last_point(); %};
|
%code{% const char* CLASS = "Slic3r::Point"; RETVAL = THIS->last_point(); %};
|
||||||
|
double length();
|
||||||
|
void clip_end(double distance);
|
||||||
%{
|
%{
|
||||||
|
|
||||||
Polyline*
|
Polyline*
|
||||||
|
Loading…
Reference in New Issue
Block a user