Ported Polygon->is_counter_clockwise() and rearranged code in .cpp files

This commit is contained in:
Alessandro Ranellucci 2013-07-16 21:04:14 +02:00
parent bd3fb21cfd
commit fe061b19ad
27 changed files with 675 additions and 660 deletions

View File

@ -15,11 +15,6 @@ sub wkt {
return sprintf "POLYGON((%s))", join ',', map "$_->[0] $_->[1]", @$self;
}
sub is_counter_clockwise {
my $self = shift;
return Slic3r::Geometry::Clipper::is_counter_clockwise($self->pp);
}
sub make_counter_clockwise {
my $self = shift;
if (!$self->is_counter_clockwise) {

177
xs/src/ClipperUtils.cpp Normal file
View File

@ -0,0 +1,177 @@
#include "ClipperUtils.hpp"
namespace Slic3r {
void
ClipperPolygon_to_Slic3rPolygon(ClipperLib::Polygon &input, Slic3r::Polygon &output)
{
output.points.clear();
for (ClipperLib::Polygon::iterator pit = input.begin(); pit != input.end(); ++pit) {
output.points.push_back(Slic3r::Point( (*pit).X, (*pit).Y ));
}
}
//-----------------------------------------------------------
// legacy code from Clipper documentation
void AddOuterPolyNodeToExPolygons(ClipperLib::PolyNode& polynode, Slic3r::ExPolygons& expolygons)
{
size_t cnt = expolygons.size();
expolygons.resize(cnt + 1);
ClipperPolygon_to_Slic3rPolygon(polynode.Contour, expolygons[cnt].contour);
expolygons[cnt].holes.resize(polynode.ChildCount());
for (int i = 0; i < polynode.ChildCount(); ++i)
{
ClipperPolygon_to_Slic3rPolygon(polynode.Childs[i]->Contour, expolygons[cnt].holes[i]);
//Add outer polygons contained by (nested within) holes ...
for (int j = 0; j < polynode.Childs[i]->ChildCount(); ++j)
AddOuterPolyNodeToExPolygons(*polynode.Childs[i]->Childs[j], expolygons);
}
}
void PolyTreeToExPolygons(ClipperLib::PolyTree& polytree, Slic3r::ExPolygons& expolygons)
{
expolygons.clear();
for (int i = 0; i < polytree.ChildCount(); ++i)
AddOuterPolyNodeToExPolygons(*polytree.Childs[i], expolygons);
}
//-----------------------------------------------------------
void
Slic3rPolygon_to_ClipperPolygon(Slic3r::Polygon &input, ClipperLib::Polygon &output)
{
output.clear();
for (Slic3r::Points::iterator pit = input.points.begin(); pit != input.points.end(); ++pit) {
output.push_back(ClipperLib::IntPoint( (*pit).x, (*pit).y ));
}
}
void
Slic3rPolygons_to_ClipperPolygons(Slic3r::Polygons &input, ClipperLib::Polygons &output)
{
output.clear();
for (Slic3r::Polygons::iterator it = input.begin(); it != input.end(); ++it) {
ClipperLib::Polygon p;
Slic3rPolygon_to_ClipperPolygon(*it, p);
output.push_back(p);
}
}
void
ClipperPolygons_to_Slic3rExPolygons(ClipperLib::Polygons &input, Slic3r::ExPolygons &output)
{
// init Clipper
ClipperLib::Clipper clipper;
clipper.Clear();
// perform union
clipper.AddPolygons(input, ClipperLib::ptSubject);
ClipperLib::PolyTree* polytree = new ClipperLib::PolyTree();
clipper.Execute(ClipperLib::ctUnion, *polytree, ClipperLib::pftEvenOdd, ClipperLib::pftEvenOdd); // offset results work with both EvenOdd and NonZero
// write to ExPolygons object
output.clear();
PolyTreeToExPolygons(*polytree, output);
delete polytree;
}
void
scaleClipperPolygons(ClipperLib::Polygons &polygons, const double scale)
{
for (ClipperLib::Polygons::iterator it = polygons.begin(); it != polygons.end(); ++it) {
for (ClipperLib::Polygon::iterator pit = (*it).begin(); pit != (*it).end(); ++pit) {
(*pit).X *= scale;
(*pit).Y *= scale;
}
}
}
void
offset_ex(Slic3r::Polygons &polygons, Slic3r::ExPolygons &retval, const float delta,
double scale, ClipperLib::JoinType joinType, double miterLimit)
{
// read input
ClipperLib::Polygons* input = new ClipperLib::Polygons();
Slic3rPolygons_to_ClipperPolygons(polygons, *input);
// scale input
scaleClipperPolygons(*input, scale);
// perform offset
ClipperLib::Polygons* output = new ClipperLib::Polygons();
ClipperLib::OffsetPolygons(*input, *output, (delta*scale), joinType, miterLimit);
delete input;
// unscale output
scaleClipperPolygons(*output, 1/scale);
// convert into ExPolygons
ClipperPolygons_to_Slic3rExPolygons(*output, retval);
delete output;
}
void
offset2_ex(Slic3r::Polygons &polygons, Slic3r::ExPolygons &retval, const float delta1,
const float delta2, double scale, ClipperLib::JoinType joinType, double miterLimit)
{
// read input
ClipperLib::Polygons* input = new ClipperLib::Polygons();
Slic3rPolygons_to_ClipperPolygons(polygons, *input);
// scale input
scaleClipperPolygons(*input, scale);
// perform first offset
ClipperLib::Polygons* output1 = new ClipperLib::Polygons();
ClipperLib::OffsetPolygons(*input, *output1, (delta1*scale), joinType, miterLimit);
delete input;
// perform second offset
ClipperLib::Polygons* output2 = new ClipperLib::Polygons();
ClipperLib::OffsetPolygons(*output1, *output2, (delta2*scale), joinType, miterLimit);
delete output1;
// unscale output
scaleClipperPolygons(*output2, 1/scale);
// convert into ExPolygons
ClipperPolygons_to_Slic3rExPolygons(*output2, retval);
delete output2;
}
void
diff_ex(Slic3r::Polygons &subject, Slic3r::Polygons &clip, Slic3r::ExPolygons &retval, bool safety_offset)
{
// read input
ClipperLib::Polygons* input_subject = new ClipperLib::Polygons();
ClipperLib::Polygons* input_clip = new ClipperLib::Polygons();
Slic3rPolygons_to_ClipperPolygons(subject, *input_subject);
Slic3rPolygons_to_ClipperPolygons(clip, *input_clip);
// perform safety offset
if (safety_offset) {
// SafetyOffset(*input_clip);
}
// init Clipper
ClipperLib::Clipper clipper;
clipper.Clear();
// add polygons
clipper.AddPolygons(*input_subject, ClipperLib::ptSubject);
delete input_subject;
clipper.AddPolygons(*input_clip, ClipperLib::ptClip);
delete input_clip;
// perform operation
ClipperLib::PolyTree* polytree = new ClipperLib::PolyTree();
clipper.Execute(ClipperLib::ctDifference, *polytree, ClipperLib::pftNonZero, ClipperLib::pftNonZero);
// convert into ExPolygons
PolyTreeToExPolygons(*polytree, retval);
delete polytree;
}
}

View File

@ -1,190 +1,36 @@
#ifndef slic3r_ClipperUtils_hpp_
#define slic3r_ClipperUtils_hpp_
extern "C" {
#include "EXTERN.h"
#include "perl.h"
#include "XSUB.h"
#include "ppport.h"
}
#include <myinit.h>
#include "clipper.hpp"
#include "ExPolygon.hpp"
#include "Polygon.hpp"
namespace Slic3r {
void
ClipperPolygon_to_Slic3rPolygon(ClipperLib::Polygon &input, Slic3r::Polygon &output)
{
output.points.clear();
for (ClipperLib::Polygon::iterator pit = input.begin(); pit != input.end(); ++pit) {
output.points.push_back(Slic3r::Point( (*pit).X, (*pit).Y ));
}
}
void ClipperPolygon_to_Slic3rPolygon(ClipperLib::Polygon &input, Slic3r::Polygon &output);
//-----------------------------------------------------------
// legacy code from Clipper documentation
void AddOuterPolyNodeToExPolygons(ClipperLib::PolyNode& polynode, Slic3r::ExPolygons& expolygons)
{
size_t cnt = expolygons.size();
expolygons.resize(cnt + 1);
ClipperPolygon_to_Slic3rPolygon(polynode.Contour, expolygons[cnt].contour);
expolygons[cnt].holes.resize(polynode.ChildCount());
for (int i = 0; i < polynode.ChildCount(); ++i)
{
ClipperPolygon_to_Slic3rPolygon(polynode.Childs[i]->Contour, expolygons[cnt].holes[i]);
//Add outer polygons contained by (nested within) holes ...
for (int j = 0; j < polynode.Childs[i]->ChildCount(); ++j)
AddOuterPolyNodeToExPolygons(*polynode.Childs[i]->Childs[j], expolygons);
}
}
void PolyTreeToExPolygons(ClipperLib::PolyTree& polytree, Slic3r::ExPolygons& expolygons)
{
expolygons.clear();
for (int i = 0; i < polytree.ChildCount(); ++i)
AddOuterPolyNodeToExPolygons(*polytree.Childs[i], expolygons);
}
void AddOuterPolyNodeToExPolygons(ClipperLib::PolyNode& polynode, Slic3r::ExPolygons& expolygons);
void PolyTreeToExPolygons(ClipperLib::PolyTree& polytree, Slic3r::ExPolygons& expolygons);
//-----------------------------------------------------------
void
Slic3rPolygon_to_ClipperPolygon(Slic3r::Polygon &input, ClipperLib::Polygon &output)
{
output.clear();
for (Slic3r::Points::iterator pit = input.points.begin(); pit != input.points.end(); ++pit) {
output.push_back(ClipperLib::IntPoint( (*pit).x, (*pit).y ));
}
}
void Slic3rPolygon_to_ClipperPolygon(Slic3r::Polygon &input, ClipperLib::Polygon &output);
void Slic3rPolygons_to_ClipperPolygons(Slic3r::Polygons &input, ClipperLib::Polygons &output);
void ClipperPolygons_to_Slic3rExPolygons(ClipperLib::Polygons &input, Slic3r::ExPolygons &output);
void
Slic3rPolygons_to_ClipperPolygons(Slic3r::Polygons &input, ClipperLib::Polygons &output)
{
output.clear();
for (Slic3r::Polygons::iterator it = input.begin(); it != input.end(); ++it) {
ClipperLib::Polygon p;
Slic3rPolygon_to_ClipperPolygon(*it, p);
output.push_back(p);
}
}
void scaleClipperPolygons(ClipperLib::Polygons &polygons, const double scale);
void
ClipperPolygons_to_Slic3rExPolygons(ClipperLib::Polygons &input, Slic3r::ExPolygons &output)
{
// init Clipper
ClipperLib::Clipper clipper;
clipper.Clear();
// perform union
clipper.AddPolygons(input, ClipperLib::ptSubject);
ClipperLib::PolyTree* polytree = new ClipperLib::PolyTree();
clipper.Execute(ClipperLib::ctUnion, *polytree, ClipperLib::pftEvenOdd, ClipperLib::pftEvenOdd); // offset results work with both EvenOdd and NonZero
// write to ExPolygons object
output.clear();
PolyTreeToExPolygons(*polytree, output);
delete polytree;
}
void
scaleClipperPolygons(ClipperLib::Polygons &polygons, const double scale)
{
for (ClipperLib::Polygons::iterator it = polygons.begin(); it != polygons.end(); ++it) {
for (ClipperLib::Polygon::iterator pit = (*it).begin(); pit != (*it).end(); ++pit) {
(*pit).X *= scale;
(*pit).Y *= scale;
}
}
}
void
offset_ex(Slic3r::Polygons &polygons, Slic3r::ExPolygons &retval, const float delta,
void offset_ex(Slic3r::Polygons &polygons, Slic3r::ExPolygons &retval, const float delta,
double scale = 100000, ClipperLib::JoinType joinType = ClipperLib::jtMiter,
double miterLimit = 3)
{
// read input
ClipperLib::Polygons* input = new ClipperLib::Polygons();
Slic3rPolygons_to_ClipperPolygons(polygons, *input);
double miterLimit = 3);
// scale input
scaleClipperPolygons(*input, scale);
// perform offset
ClipperLib::Polygons* output = new ClipperLib::Polygons();
ClipperLib::OffsetPolygons(*input, *output, (delta*scale), joinType, miterLimit);
delete input;
// unscale output
scaleClipperPolygons(*output, 1/scale);
// convert into ExPolygons
ClipperPolygons_to_Slic3rExPolygons(*output, retval);
delete output;
}
void
offset2_ex(Slic3r::Polygons &polygons, Slic3r::ExPolygons &retval, const float delta1,
void offset2_ex(Slic3r::Polygons &polygons, Slic3r::ExPolygons &retval, const float delta1,
const float delta2, double scale = 100000, ClipperLib::JoinType joinType = ClipperLib::jtMiter,
double miterLimit = 3)
{
// read input
ClipperLib::Polygons* input = new ClipperLib::Polygons();
Slic3rPolygons_to_ClipperPolygons(polygons, *input);
// scale input
scaleClipperPolygons(*input, scale);
// perform first offset
ClipperLib::Polygons* output1 = new ClipperLib::Polygons();
ClipperLib::OffsetPolygons(*input, *output1, (delta1*scale), joinType, miterLimit);
delete input;
// perform second offset
ClipperLib::Polygons* output2 = new ClipperLib::Polygons();
ClipperLib::OffsetPolygons(*output1, *output2, (delta2*scale), joinType, miterLimit);
delete output1;
// unscale output
scaleClipperPolygons(*output2, 1/scale);
// convert into ExPolygons
ClipperPolygons_to_Slic3rExPolygons(*output2, retval);
delete output2;
}
void
diff_ex(Slic3r::Polygons &subject, Slic3r::Polygons &clip, Slic3r::ExPolygons &retval, bool safety_offset)
{
// read input
ClipperLib::Polygons* input_subject = new ClipperLib::Polygons();
ClipperLib::Polygons* input_clip = new ClipperLib::Polygons();
Slic3rPolygons_to_ClipperPolygons(subject, *input_subject);
Slic3rPolygons_to_ClipperPolygons(clip, *input_clip);
// perform safety offset
if (safety_offset) {
// SafetyOffset(*input_clip);
}
// init Clipper
ClipperLib::Clipper clipper;
clipper.Clear();
// add polygons
clipper.AddPolygons(*input_subject, ClipperLib::ptSubject);
delete input_subject;
clipper.AddPolygons(*input_clip, ClipperLib::ptClip);
delete input_clip;
// perform operation
ClipperLib::PolyTree* polytree = new ClipperLib::PolyTree();
clipper.Execute(ClipperLib::ctDifference, *polytree, ClipperLib::pftNonZero, ClipperLib::pftNonZero);
// convert into ExPolygons
PolyTreeToExPolygons(*polytree, retval);
delete polytree;
}
double miterLimit = 3);
void diff_ex(Slic3r::Polygons &subject, Slic3r::Polygons &clip, Slic3r::ExPolygons &retval, bool safety_offset);
}

98
xs/src/ExPolygon.cpp Normal file
View File

@ -0,0 +1,98 @@
#include "ExPolygon.hpp"
#include "Polygon.hpp"
namespace Slic3r {
void
ExPolygon::scale(double factor)
{
contour.scale(factor);
for (Polygons::iterator it = holes.begin(); it != holes.end(); ++it) {
(*it).scale(factor);
}
}
void
ExPolygon::translate(double x, double y)
{
contour.translate(x, y);
for (Polygons::iterator it = holes.begin(); it != holes.end(); ++it) {
(*it).translate(x, y);
}
}
void
ExPolygon::rotate(double angle, Point* center)
{
contour.rotate(angle, center);
for (Polygons::iterator it = holes.begin(); it != holes.end(); ++it) {
(*it).rotate(angle, center);
}
}
SV*
ExPolygon::to_SV() {
const unsigned int num_holes = this->holes.size();
AV* av = newAV();
av_extend(av, num_holes); // -1 +1
SV* sv = newSV(0);
sv_setref_pv( sv, "Slic3r::Polygon", new Polygon(this->contour) );
av_store(av, 0, sv);
for (unsigned int i = 0; i < num_holes; i++) {
sv = newSV(0);
sv_setref_pv( sv, "Slic3r::Polygon", new Polygon(this->holes[i]) );
av_store(av, i+1, sv);
}
return newRV_noinc((SV*)av);
}
SV*
ExPolygon::to_SV_ref() {
SV* sv = newSV(0);
sv_setref_pv( sv, "Slic3r::ExPolygon", new ExPolygon(*this) );
return sv;
}
SV*
ExPolygon::to_SV_pureperl()
{
const unsigned int num_holes = this->holes.size();
AV* av = newAV();
av_extend(av, num_holes); // -1 +1
av_store(av, 0, this->contour.to_SV_pureperl());
for (unsigned int i = 0; i < num_holes; i++) {
av_store(av, i+1, this->holes[i].to_SV_pureperl());
}
return newRV_noinc((SV*)av);
}
void
ExPolygon::from_SV(SV* expoly_sv)
{
AV* expoly_av = (AV*)SvRV(expoly_sv);
const unsigned int num_polygons = av_len(expoly_av)+1;
this->holes.resize(num_polygons-1);
SV** polygon_sv = av_fetch(expoly_av, 0, 0);
this->contour.from_SV(*polygon_sv);
for (unsigned int i = 0; i < num_polygons-1; i++) {
polygon_sv = av_fetch(expoly_av, i+1, 0);
this->holes[i].from_SV(*polygon_sv);
}
}
void
ExPolygon::from_SV_check(SV* expoly_sv)
{
if (sv_isobject(expoly_sv) && (SvTYPE(SvRV(expoly_sv)) == SVt_PVMG)) {
// a XS ExPolygon was supplied
*this = *(ExPolygon *)SvIV((SV*)SvRV( expoly_sv ));
} else {
// a Perl arrayref was supplied
this->from_SV(expoly_sv);
}
}
}

View File

@ -1,13 +1,6 @@
#ifndef slic3r_ExPolygon_hpp_
#define slic3r_ExPolygon_hpp_
extern "C" {
#include "EXTERN.h"
#include "perl.h"
#include "XSUB.h"
#include "ppport.h"
}
#include "Polygon.hpp"
#include <vector>
@ -31,98 +24,6 @@ class ExPolygon
typedef std::vector<ExPolygon> ExPolygons;
void
ExPolygon::scale(double factor)
{
contour.scale(factor);
for (Polygons::iterator it = holes.begin(); it != holes.end(); ++it) {
(*it).scale(factor);
}
}
void
ExPolygon::translate(double x, double y)
{
contour.translate(x, y);
for (Polygons::iterator it = holes.begin(); it != holes.end(); ++it) {
(*it).translate(x, y);
}
}
void
ExPolygon::rotate(double angle, Point* center)
{
contour.rotate(angle, center);
for (Polygons::iterator it = holes.begin(); it != holes.end(); ++it) {
(*it).rotate(angle, center);
}
}
SV*
ExPolygon::to_SV() {
const unsigned int num_holes = this->holes.size();
AV* av = newAV();
av_extend(av, num_holes); // -1 +1
SV* sv = newSV(0);
sv_setref_pv( sv, "Slic3r::Polygon", new Polygon(this->contour) );
av_store(av, 0, sv);
for (unsigned int i = 0; i < num_holes; i++) {
sv = newSV(0);
sv_setref_pv( sv, "Slic3r::Polygon", new Polygon(this->holes[i]) );
av_store(av, i+1, sv);
}
return newRV_noinc((SV*)av);
}
SV*
ExPolygon::to_SV_ref() {
SV* sv = newSV(0);
sv_setref_pv( sv, "Slic3r::ExPolygon", new ExPolygon(*this) );
return sv;
}
SV*
ExPolygon::to_SV_pureperl()
{
const unsigned int num_holes = this->holes.size();
AV* av = newAV();
av_extend(av, num_holes); // -1 +1
av_store(av, 0, this->contour.to_SV_pureperl());
for (unsigned int i = 0; i < num_holes; i++) {
av_store(av, i+1, this->holes[i].to_SV_pureperl());
}
return newRV_noinc((SV*)av);
}
void
ExPolygon::from_SV(SV* expoly_sv)
{
AV* expoly_av = (AV*)SvRV(expoly_sv);
const unsigned int num_polygons = av_len(expoly_av)+1;
this->holes.resize(num_polygons-1);
SV** polygon_sv = av_fetch(expoly_av, 0, 0);
this->contour.from_SV(*polygon_sv);
for (unsigned int i = 0; i < num_polygons-1; i++) {
polygon_sv = av_fetch(expoly_av, i+1, 0);
this->holes[i].from_SV(*polygon_sv);
}
}
void
ExPolygon::from_SV_check(SV* expoly_sv)
{
if (sv_isobject(expoly_sv) && (SvTYPE(SvRV(expoly_sv)) == SVt_PVMG)) {
// a XS ExPolygon was supplied
*this = *(ExPolygon *)SvIV((SV*)SvRV( expoly_sv ));
} else {
// a Perl arrayref was supplied
this->from_SV(expoly_sv);
}
}
}
#endif

View File

@ -0,0 +1,29 @@
#include "ExPolygonCollection.hpp"
namespace Slic3r {
void
ExPolygonCollection::scale(double factor)
{
for (ExPolygons::iterator it = expolygons.begin(); it != expolygons.end(); ++it) {
(*it).scale(factor);
}
}
void
ExPolygonCollection::translate(double x, double y)
{
for (ExPolygons::iterator it = expolygons.begin(); it != expolygons.end(); ++it) {
(*it).translate(x, y);
}
}
void
ExPolygonCollection::rotate(double angle, Point* center)
{
for (ExPolygons::iterator it = expolygons.begin(); it != expolygons.end(); ++it) {
(*it).rotate(angle, center);
}
}
}

View File

@ -1,13 +1,7 @@
#ifndef slic3r_ExPolygonCollection_hpp_
#define slic3r_ExPolygonCollection_hpp_
extern "C" {
#include "EXTERN.h"
#include "perl.h"
#include "XSUB.h"
#include "ppport.h"
}
#include <myinit.h>
#include "ExPolygon.hpp"
namespace Slic3r {
@ -22,30 +16,6 @@ class ExPolygonCollection
void rotate(double angle, Point* center);
};
void
ExPolygonCollection::scale(double factor)
{
for (ExPolygons::iterator it = expolygons.begin(); it != expolygons.end(); ++it) {
(*it).scale(factor);
}
}
void
ExPolygonCollection::translate(double x, double y)
{
for (ExPolygons::iterator it = expolygons.begin(); it != expolygons.end(); ++it) {
(*it).translate(x, y);
}
}
void
ExPolygonCollection::rotate(double angle, Point* center)
{
for (ExPolygons::iterator it = expolygons.begin(); it != expolygons.end(); ++it) {
(*it).rotate(angle, center);
}
}
}
#endif

View File

@ -0,0 +1,32 @@
#include "ExtrusionEntity.hpp"
namespace Slic3r {
void
ExtrusionPath::reverse()
{
this->polyline.reverse();
}
ExtrusionPath*
ExtrusionLoop::split_at_index(int index)
{
Polyline* poly = this->polygon.split_at_index(index);
ExtrusionPath* path = new ExtrusionPath();
path->polyline = *poly;
path->role = this->role;
path->height = this->height;
path->flow_spacing = this->flow_spacing;
delete poly;
return path;
}
ExtrusionPath*
ExtrusionLoop::split_at_first_point()
{
return this->split_at_index(0);
}
}

View File

@ -1,13 +1,7 @@
#ifndef slic3r_ExtrusionEntity_hpp_
#define slic3r_ExtrusionEntity_hpp_
extern "C" {
#include "EXTERN.h"
#include "perl.h"
#include "XSUB.h"
#include "ppport.h"
}
#include <myinit.h>
#include "Polygon.hpp"
#include "Polyline.hpp"
@ -51,33 +45,6 @@ class ExtrusionLoop : public ExtrusionEntity
ExtrusionPath* split_at_first_point();
};
void
ExtrusionPath::reverse()
{
this->polyline.reverse();
}
ExtrusionPath*
ExtrusionLoop::split_at_index(int index)
{
Polyline* poly = this->polygon.split_at_index(index);
ExtrusionPath* path = new ExtrusionPath();
path->polyline = *poly;
path->role = this->role;
path->height = this->height;
path->flow_spacing = this->flow_spacing;
delete poly;
return path;
}
ExtrusionPath*
ExtrusionLoop::split_at_first_point()
{
return this->split_at_index(0);
}
}
#endif

83
xs/src/Line.cpp Normal file
View File

@ -0,0 +1,83 @@
#include "Line.hpp"
#include <algorithm>
namespace Slic3r {
void
Line::scale(double factor)
{
this->a.scale(factor);
this->b.scale(factor);
}
void
Line::translate(double x, double y)
{
this->a.translate(x, y);
this->b.translate(x, y);
}
void
Line::rotate(double angle, Point* center)
{
this->a.rotate(angle, center);
this->b.rotate(angle, center);
}
void
Line::reverse()
{
std::swap(this->a, this->b);
}
void
Line::from_SV(SV* line_sv)
{
AV* line_av = (AV*)SvRV(line_sv);
this->a.from_SV_check(*av_fetch(line_av, 0, 0));
this->b.from_SV_check(*av_fetch(line_av, 1, 0));
}
void
Line::from_SV_check(SV* line_sv)
{
if (sv_isobject(line_sv) && (SvTYPE(SvRV(line_sv)) == SVt_PVMG)) {
*this = *(Line*)SvIV((SV*)SvRV( line_sv ));
} else {
this->from_SV(line_sv);
}
}
SV*
Line::to_SV() {
AV* av = newAV();
av_extend(av, 1);
SV* sv = newSV(0);
sv_setref_pv( sv, "Slic3r::Point", new Point(this->a) );
av_store(av, 0, sv);
sv = newSV(0);
sv_setref_pv( sv, "Slic3r::Point", new Point(this->b) );
av_store(av, 1, sv);
return newRV_noinc((SV*)av);
}
SV*
Line::to_SV_ref() {
SV* sv = newSV(0);
sv_setref_pv( sv, "Slic3r::Line", new Line(*this) );
return sv;
}
SV*
Line::to_SV_pureperl() {
AV* av = newAV();
av_extend(av, 1);
av_store(av, 0, this->a.to_SV_pureperl());
av_store(av, 1, this->b.to_SV_pureperl());
return newRV_noinc((SV*)av);
}
}

View File

@ -1,15 +1,8 @@
#ifndef slic3r_Line_hpp_
#define slic3r_Line_hpp_
extern "C" {
#include "EXTERN.h"
#include "perl.h"
#include "XSUB.h"
#include "ppport.h"
}
#include <myinit.h>
#include "Point.hpp"
#include <algorithm>
namespace Slic3r {
@ -33,83 +26,6 @@ class Line
typedef std::vector<Line> Lines;
void
Line::scale(double factor)
{
this->a.scale(factor);
this->b.scale(factor);
}
void
Line::translate(double x, double y)
{
this->a.translate(x, y);
this->b.translate(x, y);
}
void
Line::rotate(double angle, Point* center)
{
this->a.rotate(angle, center);
this->b.rotate(angle, center);
}
void
Line::reverse()
{
std::swap(this->a, this->b);
}
void
Line::from_SV(SV* line_sv)
{
AV* line_av = (AV*)SvRV(line_sv);
this->a.from_SV_check(*av_fetch(line_av, 0, 0));
this->b.from_SV_check(*av_fetch(line_av, 1, 0));
}
void
Line::from_SV_check(SV* line_sv)
{
if (sv_isobject(line_sv) && (SvTYPE(SvRV(line_sv)) == SVt_PVMG)) {
*this = *(Line*)SvIV((SV*)SvRV( line_sv ));
} else {
this->from_SV(line_sv);
}
}
SV*
Line::to_SV() {
AV* av = newAV();
av_extend(av, 1);
SV* sv = newSV(0);
sv_setref_pv( sv, "Slic3r::Point", new Point(this->a) );
av_store(av, 0, sv);
sv = newSV(0);
sv_setref_pv( sv, "Slic3r::Point", new Point(this->b) );
av_store(av, 1, sv);
return newRV_noinc((SV*)av);
}
SV*
Line::to_SV_ref() {
SV* sv = newSV(0);
sv_setref_pv( sv, "Slic3r::Line", new Line(*this) );
return sv;
}
SV*
Line::to_SV_pureperl() {
AV* av = newAV();
av_extend(av, 1);
av_store(av, 0, this->a.to_SV_pureperl());
av_store(av, 1, this->b.to_SV_pureperl());
return newRV_noinc((SV*)av);
}
}
#endif

82
xs/src/MultiPoint.cpp Normal file
View File

@ -0,0 +1,82 @@
#include "MultiPoint.hpp"
namespace Slic3r {
void
MultiPoint::scale(double factor)
{
for (Points::iterator it = points.begin(); it != points.end(); ++it) {
(*it).scale(factor);
}
}
void
MultiPoint::translate(double x, double y)
{
for (Points::iterator it = points.begin(); it != points.end(); ++it) {
(*it).translate(x, y);
}
}
void
MultiPoint::rotate(double angle, Point* center)
{
for (Points::iterator it = points.begin(); it != points.end(); ++it) {
(*it).rotate(angle, center);
}
}
void
MultiPoint::reverse()
{
std::reverse(this->points.begin(), this->points.end());
}
void
MultiPoint::from_SV(SV* poly_sv)
{
AV* poly_av = (AV*)SvRV(poly_sv);
const unsigned int num_points = av_len(poly_av)+1;
this->points.resize(num_points);
for (unsigned int i = 0; i < num_points; i++) {
SV** point_sv = av_fetch(poly_av, i, 0);
this->points[i].from_SV_check(*point_sv);
}
}
void
MultiPoint::from_SV_check(SV* poly_sv)
{
if (sv_isobject(poly_sv) && (SvTYPE(SvRV(poly_sv)) == SVt_PVMG)) {
*this = *(MultiPoint*)SvIV((SV*)SvRV( poly_sv ));
} else {
this->from_SV(poly_sv);
}
}
SV*
MultiPoint::to_SV() {
const unsigned int num_points = this->points.size();
AV* av = newAV();
av_extend(av, num_points-1);
for (unsigned int i = 0; i < num_points; i++) {
SV* sv = newSV(0);
sv_setref_pv( sv, "Slic3r::Point", new Point(this->points[i]) );
av_store(av, i, sv);
}
return newRV_noinc((SV*)av);
}
SV*
MultiPoint::to_SV_pureperl() {
const unsigned int num_points = this->points.size();
AV* av = newAV();
av_extend(av, num_points-1);
for (unsigned int i = 0; i < num_points; i++) {
av_store(av, i, this->points[i].to_SV_pureperl());
}
return newRV_noinc((SV*)av);
}
}

View File

@ -1,13 +1,6 @@
#ifndef slic3r_MultiPoint_hpp_
#define slic3r_MultiPoint_hpp_
extern "C" {
#include "EXTERN.h"
#include "perl.h"
#include "XSUB.h"
#include "ppport.h"
}
#include "Point.hpp"
#include <algorithm>
#include <vector>
@ -28,83 +21,6 @@ class MultiPoint
void reverse();
};
void
MultiPoint::scale(double factor)
{
for (Points::iterator it = points.begin(); it != points.end(); ++it) {
(*it).scale(factor);
}
}
void
MultiPoint::translate(double x, double y)
{
for (Points::iterator it = points.begin(); it != points.end(); ++it) {
(*it).translate(x, y);
}
}
void
MultiPoint::rotate(double angle, Point* center)
{
for (Points::iterator it = points.begin(); it != points.end(); ++it) {
(*it).rotate(angle, center);
}
}
void
MultiPoint::reverse()
{
std::reverse(this->points.begin(), this->points.end());
}
void
MultiPoint::from_SV(SV* poly_sv)
{
AV* poly_av = (AV*)SvRV(poly_sv);
const unsigned int num_points = av_len(poly_av)+1;
this->points.resize(num_points);
for (unsigned int i = 0; i < num_points; i++) {
SV** point_sv = av_fetch(poly_av, i, 0);
this->points[i].from_SV_check(*point_sv);
}
}
void
MultiPoint::from_SV_check(SV* poly_sv)
{
if (sv_isobject(poly_sv) && (SvTYPE(SvRV(poly_sv)) == SVt_PVMG)) {
*this = *(MultiPoint*)SvIV((SV*)SvRV( poly_sv ));
} else {
this->from_SV(poly_sv);
}
}
SV*
MultiPoint::to_SV() {
const unsigned int num_points = this->points.size();
AV* av = newAV();
av_extend(av, num_points-1);
for (unsigned int i = 0; i < num_points; i++) {
SV* sv = newSV(0);
sv_setref_pv( sv, "Slic3r::Point", new Point(this->points[i]) );
av_store(av, i, sv);
}
return newRV_noinc((SV*)av);
}
SV*
MultiPoint::to_SV_pureperl() {
const unsigned int num_points = this->points.size();
AV* av = newAV();
av_extend(av, num_points-1);
for (unsigned int i = 0; i < num_points; i++) {
av_store(av, i, this->points[i].to_SV_pureperl());
}
return newRV_noinc((SV*)av);
}
}
#endif

61
xs/src/Point.cpp Normal file
View File

@ -0,0 +1,61 @@
#include "Point.hpp"
namespace Slic3r {
void
Point::scale(double factor)
{
this->x *= factor;
this->y *= factor;
}
void
Point::translate(double x, double y)
{
this->x += x;
this->y += y;
}
void
Point::rotate(double angle, Point* center)
{
double cur_x = (double)this->x;
double cur_y = (double)this->y;
this->x = (long)( (double)center->x + cos(angle) * (cur_x - (double)center->x) - sin(angle) * (cur_y - (double)center->y) );
this->y = (long)( (double)center->y + cos(angle) * (cur_y - (double)center->y) + sin(angle) * (cur_x - (double)center->x) );
}
bool
Point::coincides_with(Point* point)
{
return this->x == point->x && this->y == point->y;
}
SV*
Point::to_SV_pureperl() {
AV* av = newAV();
av_fill(av, 1);
av_store(av, 0, newSViv(this->x));
av_store(av, 1, newSViv(this->y));
return newRV_noinc((SV*)av);
}
void
Point::from_SV(SV* point_sv)
{
AV* point_av = (AV*)SvRV(point_sv);
this->x = (long)SvIV(*av_fetch(point_av, 0, 0));
this->y = (long)SvIV(*av_fetch(point_av, 1, 0));
}
void
Point::from_SV_check(SV* point_sv)
{
if (sv_isobject(point_sv) && (SvTYPE(SvRV(point_sv)) == SVt_PVMG)) {
*this = *(Point*)SvIV((SV*)SvRV( point_sv ));
} else {
this->from_SV(point_sv);
}
}
}

View File

@ -1,13 +1,7 @@
#ifndef slic3r_Point_hpp_
#define slic3r_Point_hpp_
extern "C" {
#include "EXTERN.h"
#include "perl.h"
#include "XSUB.h"
#include "ppport.h"
}
#include <myinit.h>
#include <vector>
#include <math.h>
@ -30,62 +24,6 @@ class Point
typedef std::vector<Point> Points;
void
Point::scale(double factor)
{
this->x *= factor;
this->y *= factor;
}
void
Point::translate(double x, double y)
{
this->x += x;
this->y += y;
}
void
Point::rotate(double angle, Point* center)
{
double cur_x = (double)this->x;
double cur_y = (double)this->y;
this->x = (long)( (double)center->x + cos(angle) * (cur_x - (double)center->x) - sin(angle) * (cur_y - (double)center->y) );
this->y = (long)( (double)center->y + cos(angle) * (cur_y - (double)center->y) + sin(angle) * (cur_x - (double)center->x) );
}
bool
Point::coincides_with(Point* point)
{
return this->x == point->x && this->y == point->y;
}
SV*
Point::to_SV_pureperl() {
AV* av = newAV();
av_fill(av, 1);
av_store(av, 0, newSViv(this->x));
av_store(av, 1, newSViv(this->y));
return newRV_noinc((SV*)av);
}
void
Point::from_SV(SV* point_sv)
{
AV* point_av = (AV*)SvRV(point_sv);
this->x = (long)SvIV(*av_fetch(point_av, 0, 0));
this->y = (long)SvIV(*av_fetch(point_av, 1, 0));
}
void
Point::from_SV_check(SV* point_sv)
{
if (sv_isobject(point_sv) && (SvTYPE(SvRV(point_sv)) == SVt_PVMG)) {
*this = *(Point*)SvIV((SV*)SvRV( point_sv ));
} else {
this->from_SV(point_sv);
}
}
}
#endif

55
xs/src/Polygon.cpp Normal file
View File

@ -0,0 +1,55 @@
#include <myinit.h>
#include "ClipperUtils.hpp"
#include "Polygon.hpp"
#include "Polyline.hpp"
namespace Slic3r {
SV*
Polygon::to_SV_ref() {
SV* sv = newSV(0);
sv_setref_pv( sv, "Slic3r::Polygon", new Polygon(*this) );
return sv;
}
Lines
Polygon::lines()
{
Lines lines;
for (int i = 0; i < this->points.size()-1; i++) {
lines.push_back(Line(this->points[i], this->points[i+1]));
}
lines.push_back(Line(this->points.back(), this->points.front()));
return lines;
}
Polyline*
Polygon::split_at_index(int index)
{
Polyline* poly = new Polyline;
for (int i = index; i < this->points.size(); i++) {
poly->points.push_back( this->points[i] );
}
for (int i = 0; i <= index; i++) {
poly->points.push_back( this->points[i] );
}
return poly;
}
Polyline*
Polygon::split_at_first_point()
{
return this->split_at_index(0);
}
bool
Polygon::is_counter_clockwise()
{
ClipperLib::Polygon* p = new ClipperLib::Polygon();
Slic3rPolygon_to_ClipperPolygon(*this, *p);
bool orientation = ClipperLib::Orientation(*p);
delete p;
return orientation;
}
}

View File

@ -1,14 +1,10 @@
#ifndef slic3r_Polygon_hpp_
#define slic3r_Polygon_hpp_
extern "C" {
#include "EXTERN.h"
#include "perl.h"
#include "XSUB.h"
#include "ppport.h"
}
#include <myinit.h>
#include <vector>
#include "Line.hpp"
#include "MultiPoint.hpp"
#include "Polyline.hpp"
namespace Slic3r {
@ -19,47 +15,11 @@ class Polygon : public MultiPoint {
Lines lines();
Polyline* split_at_index(int index);
Polyline* split_at_first_point();
bool is_counter_clockwise();
};
typedef std::vector<Polygon> Polygons;
SV*
Polygon::to_SV_ref() {
SV* sv = newSV(0);
sv_setref_pv( sv, "Slic3r::Polygon", new Polygon(*this) );
return sv;
}
Lines
Polygon::lines()
{
Lines lines;
for (int i = 0; i < this->points.size()-1; i++) {
lines.push_back(Line(this->points[i], this->points[i+1]));
}
lines.push_back(Line(this->points.back(), this->points.front()));
return lines;
}
Polyline*
Polygon::split_at_index(int index)
{
Polyline* poly = new Polyline;
for (int i = index; i < this->points.size(); i++) {
poly->points.push_back( this->points[i] );
}
for (int i = 0; i <= index; i++) {
poly->points.push_back( this->points[i] );
}
return poly;
}
Polyline*
Polygon::split_at_first_point()
{
return this->split_at_index(0);
}
}
#endif

15
xs/src/Polyline.cpp Normal file
View File

@ -0,0 +1,15 @@
#include "Polyline.hpp"
namespace Slic3r {
Lines
Polyline::lines()
{
Lines lines;
for (int i = 0; i < this->points.size()-1; i++) {
lines.push_back(Line(this->points[i], this->points[i+1]));
}
return lines;
}
}

View File

@ -1,13 +1,6 @@
#ifndef slic3r_Polyline_hpp_
#define slic3r_Polyline_hpp_
extern "C" {
#include "EXTERN.h"
#include "perl.h"
#include "XSUB.h"
#include "ppport.h"
}
#include "Line.hpp"
#include "MultiPoint.hpp"
@ -20,16 +13,6 @@ class Polyline : public MultiPoint {
typedef std::vector<Polyline> Polylines;
Lines
Polyline::lines()
{
Lines lines;
for (int i = 0; i < this->points.size()-1; i++) {
lines.push_back(Line(this->points[i], this->points[i+1]));
}
return lines;
}
}
#endif

View File

@ -1,13 +1,6 @@
#ifndef slic3r_Surface_hpp_
#define slic3r_Surface_hpp_
extern "C" {
#include "EXTERN.h"
#include "perl.h"
#include "XSUB.h"
#include "ppport.h"
}
#include "ExPolygon.hpp"
namespace Slic3r {

View File

@ -1,13 +1,6 @@
#ifndef slic3r_SurfaceCollection_hpp_
#define slic3r_SurfaceCollection_hpp_
extern "C" {
#include "EXTERN.h"
#include "perl.h"
#include "XSUB.h"
#include "ppport.h"
}
#include "Surface.hpp"
namespace Slic3r {

View File

@ -1,15 +1,9 @@
#ifndef slic3r_TriangleMesh_hpp_
#define slic3r_TriangleMesh_hpp_
#include <myinit.h>
#include <admesh/stl.h>
extern "C" {
#include "EXTERN.h"
#include "perl.h"
#include "XSUB.h"
#include "ppport.h"
}
namespace Slic3r {
class TriangleMesh

View File

@ -1,13 +1,6 @@
#ifndef slic3r_ZTable_hpp_
#define slic3r_ZTable_hpp_
extern "C" {
#include "EXTERN.h"
#include "perl.h"
#include "XSUB.h"
#include "ppport.h"
}
namespace Slic3r {
class ZTable

View File

@ -1,6 +1,15 @@
#ifndef _myinit_h_
#define _myinit_h_
extern "C" {
#include "EXTERN.h"
#include "perl.h"
#include "XSUB.h"
#include "ppport.h"
#undef do_open
#undef do_close
}
namespace Slic3r {}
using namespace Slic3r;

View File

@ -4,7 +4,7 @@ use strict;
use warnings;
use Slic3r::XS;
use Test::More tests => 6;
use Test::More tests => 8;
my $square = [ # ccw
[100, 100],
@ -30,4 +30,11 @@ is_deeply [ map $_->pp, @$lines ], [
is_deeply $polygon->split_at_first_point->pp, [ @$square[0,1,2,3,0] ], 'split_at_first_point';
is_deeply $polygon->split_at_index(2)->pp, [ @$square[2,3,0,1,2] ], 'split_at_index';
ok $polygon->is_counter_clockwise, 'is_counter_clockwise';
{
my $clone = $polygon->clone;
$clone->reverse;
ok !$clone->is_counter_clockwise, 'is_counter_clockwise';
}
__END__

View File

@ -21,6 +21,7 @@
%code{% const char* CLASS = "Slic3r::Polyline"; RETVAL = THIS->split_at_index(index); %};
Polyline* split_at_first_point()
%code{% const char* CLASS = "Slic3r::Polyline"; RETVAL = THIS->split_at_first_point(); %};
bool is_counter_clockwise();
%{
Polygon*

View File

@ -1,3 +1,4 @@
%typemap{bool}{simple};
%typemap{std::string};
%typemap{std::vector<unsigned int>*};
%typemap{SV*};