Ported Polygon->is_counter_clockwise() and rearranged code in .cpp files
This commit is contained in:
parent
bd3fb21cfd
commit
fe061b19ad
@ -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
177
xs/src/ClipperUtils.cpp
Normal 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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
@ -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);
|
||||
|
||||
// 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;
|
||||
}
|
||||
double miterLimit = 3);
|
||||
|
||||
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
98
xs/src/ExPolygon.cpp
Normal 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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -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
|
||||
|
29
xs/src/ExPolygonCollection.cpp
Normal file
29
xs/src/ExPolygonCollection.cpp
Normal 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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -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
|
||||
|
32
xs/src/ExtrusionEntity.cpp
Normal file
32
xs/src/ExtrusionEntity.cpp
Normal 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);
|
||||
}
|
||||
|
||||
}
|
@ -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
83
xs/src/Line.cpp
Normal 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);
|
||||
}
|
||||
|
||||
}
|
@ -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
82
xs/src/MultiPoint.cpp
Normal 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);
|
||||
}
|
||||
|
||||
}
|
@ -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
61
xs/src/Point.cpp
Normal 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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -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
55
xs/src/Polygon.cpp
Normal 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;
|
||||
}
|
||||
|
||||
}
|
@ -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
15
xs/src/Polyline.cpp
Normal 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;
|
||||
}
|
||||
|
||||
}
|
@ -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
|
||||
|
@ -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 {
|
||||
|
@ -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 {
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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__
|
||||
|
@ -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*
|
||||
|
@ -1,3 +1,4 @@
|
||||
%typemap{bool}{simple};
|
||||
%typemap{std::string};
|
||||
%typemap{std::vector<unsigned int>*};
|
||||
%typemap{SV*};
|
||||
|
Loading…
Reference in New Issue
Block a user