XS interface completed, including new Line class

This commit is contained in:
Alessandro Ranellucci 2013-07-15 22:57:22 +02:00
parent 9af2a1c007
commit ab6b3d41a7
33 changed files with 435 additions and 257 deletions

View file

@ -19,7 +19,10 @@ class ExPolygon
Polygon contour;
Polygons holes;
bool in_collection;
SV* to_SV(bool pureperl = false, bool pureperl_children = false);
void from_SV(SV* poly_sv);
void from_SV_check(SV* poly_sv);
SV* to_SV();
SV* to_SV_pureperl();
void scale(double factor);
void translate(double x, double y);
void rotate(double angle, Point* center);
@ -55,48 +58,60 @@ ExPolygon::rotate(double angle, Point* center)
}
SV*
ExPolygon::to_SV(bool pureperl, bool pureperl_children)
{
if (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_children, pureperl_children));
for (unsigned int i = 0; i < num_holes; i++) {
av_store(av, i+1, this->holes[i].to_SV(pureperl_children, pureperl_children));
}
return sv_bless(newRV_noinc((SV*)av), gv_stashpv("Slic3r::ExPolygon", GV_ADD));
} else {
SV* sv = newSV(0);
sv_setref_pv( sv, "Slic3r::ExPolygon::XS", this );
return 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_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
perl2expolygon(SV* expoly_sv, ExPolygon& expoly)
ExPolygon::from_SV(SV* expoly_sv)
{
AV* expoly_av = (AV*)SvRV(expoly_sv);
const unsigned int num_polygons = av_len(expoly_av)+1;
expoly.holes.resize(num_polygons-1);
this->holes.resize(num_polygons-1);
SV** polygon_sv = av_fetch(expoly_av, 0, 0);
expoly.contour.from_SV(*polygon_sv);
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);
expoly.holes[i].from_SV(*polygon_sv);
this->holes[i].from_SV(*polygon_sv);
}
}
void
perl2expolygon_check(SV* expoly_sv, ExPolygon& expoly)
ExPolygon::from_SV_check(SV* expoly_sv)
{
if (sv_isobject(expoly_sv) && (SvTYPE(SvRV(expoly_sv)) == SVt_PVMG)) {
// a XS ExPolygon was supplied
expoly = *(ExPolygon *)SvIV((SV*)SvRV( expoly_sv ));
*this = *(ExPolygon *)SvIV((SV*)SvRV( expoly_sv ));
} else {
// a Perl arrayref was supplied
perl2expolygon(expoly_sv, expoly);
this->from_SV(expoly_sv);
}
}

107
xs/src/Line.hpp Normal file
View file

@ -0,0 +1,107 @@
#ifndef slic3r_Line_hpp_
#define slic3r_Line_hpp_
extern "C" {
#include "EXTERN.h"
#include "perl.h"
#include "XSUB.h"
#include "ppport.h"
}
#include "Point.hpp"
#include <algorithm>
namespace Slic3r {
class Line
{
public:
Point a;
Point b;
Line() {};
explicit Line(Point _a, Point _b): a(_a), b(_b) {};
void from_SV(SV* line_sv);
void from_SV_check(SV* line_sv);
SV* to_SV();
SV* to_SV_pureperl();
void scale(double factor);
void translate(double x, double y);
void rotate(double angle, Point* center);
void reverse();
};
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_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

110
xs/src/MultiPoint.hpp Normal file
View file

@ -0,0 +1,110 @@
#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>
namespace Slic3r {
class MultiPoint
{
public:
Points points;
void from_SV(SV* poly_sv);
void from_SV_check(SV* poly_sv);
SV* to_SV();
SV* to_SV_pureperl();
void scale(double factor);
void translate(double x, double y);
void rotate(double angle, Point* center);
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

View file

@ -19,7 +19,9 @@ class Point
long x;
long y;
explicit Point(long _x = 0, long _y = 0): x(_x), y(_y) {};
SV* to_SV(bool pureperl = false);
void from_SV(SV* point_sv);
void from_SV_check(SV* point_sv);
SV* to_SV_pureperl();
void scale(double factor);
void translate(double x, double y);
void rotate(double angle, Point* center);
@ -58,35 +60,29 @@ Point::coincides_with(Point* point)
}
SV*
Point::to_SV(bool pureperl) {
if (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);
} else {
SV* sv = newSV(0);
sv_setref_pv( sv, "Slic3r::Point", new Point(*this) );
return 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
perl2point(SV* point_sv, Point& point)
Point::from_SV(SV* point_sv)
{
AV* point_av = (AV*)SvRV(point_sv);
point.x = (unsigned long)SvIV(*av_fetch(point_av, 0, 0));
point.y = (unsigned long)SvIV(*av_fetch(point_av, 1, 0));
AV* point_av = (AV*)SvRV(point_sv);
this->x = (unsigned long)SvIV(*av_fetch(point_av, 0, 0));
this->y = (unsigned long)SvIV(*av_fetch(point_av, 1, 0));
}
void
perl2point_check(SV* point_sv, Point& point)
Point::from_SV_check(SV* point_sv)
{
if (sv_isobject(point_sv) && (SvTYPE(SvRV(point_sv)) == SVt_PVMG)) {
point = *(Point*)SvIV((SV*)SvRV( point_sv ));
*this = *(Point*)SvIV((SV*)SvRV( point_sv ));
} else {
perl2point(point_sv, point);
this->from_SV(point_sv);
}
}

View file

@ -13,12 +13,7 @@ extern "C" {
namespace Slic3r {
class Polygon : public Polyline {
protected:
char* perl_class() {
return (char*)"Slic3r::Polygon";
}
};
class Polygon : public MultiPoint {};
typedef std::vector<Polygon> Polygons;

View file

@ -8,94 +8,26 @@ extern "C" {
#include "ppport.h"
}
#include "Point.hpp"
#include <algorithm>
#include <string>
#include <vector>
#include "Line.hpp"
#include "MultiPoint.hpp"
namespace Slic3r {
class Polyline
{
class Polyline : public MultiPoint {
public:
Points points;
void from_SV(SV* poly_sv);
void from_SV_check(SV* poly_sv);
SV* to_SV(bool pureperl = false, bool pureperl_children = false);
void scale(double factor);
void translate(double x, double y);
void rotate(double angle, Point* center);
void reverse();
protected:
virtual char* perl_class() {
return (char*)"Slic3r::Polyline";
}
Lines lines();
};
typedef std::vector<Polyline> Polylines;
void
Polyline::scale(double factor)
Lines
Polyline::lines()
{
for (Points::iterator it = points.begin(); it != points.end(); ++it) {
(*it).scale(factor);
Lines lines;
for (int i = 0; i < this->points.size()-1; i++) {
lines.push_back(Line(this->points[i], this->points[i+1]));
}
}
void
Polyline::translate(double x, double y)
{
for (Points::iterator it = points.begin(); it != points.end(); ++it) {
(*it).translate(x, y);
}
}
void
Polyline::rotate(double angle, Point* center)
{
for (Points::iterator it = points.begin(); it != points.end(); ++it) {
(*it).rotate(angle, center);
}
}
void
Polyline::reverse()
{
std::reverse(this->points.begin(), this->points.end());
}
void
Polyline::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);
perl2point_check(*point_sv, this->points[i]);
}
}
void
Polyline::from_SV_check(SV* poly_sv)
{
if (sv_isobject(poly_sv) && (SvTYPE(SvRV(poly_sv)) == SVt_PVMG)) {
*this = *(Polyline*)SvIV((SV*)SvRV( poly_sv ));
} else {
this->from_SV(poly_sv);
}
}
SV*
Polyline::to_SV(bool pureperl, bool pureperl_children) {
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_children));
}
return sv_bless(newRV_noinc((SV*)av), gv_stashpv(this->perl_class(), GV_ADD));
return lines;
}
}