diff --git a/xs/src/ExPolygon.cpp b/xs/src/ExPolygon.cpp index 3f83a24d7..c9002344f 100644 --- a/xs/src/ExPolygon.cpp +++ b/xs/src/ExPolygon.cpp @@ -51,7 +51,7 @@ ExPolygon::is_valid() const } SV* -ExPolygon::to_SV() { +ExPolygon::to_AV() { const unsigned int num_holes = this->holes.size(); AV* av = newAV(); av_extend(av, num_holes); // -1 +1 diff --git a/xs/src/ExPolygon.hpp b/xs/src/ExPolygon.hpp index a51280051..31b1c3042 100644 --- a/xs/src/ExPolygon.hpp +++ b/xs/src/ExPolygon.hpp @@ -13,7 +13,7 @@ class ExPolygon Polygons holes; void from_SV(SV* poly_sv); void from_SV_check(SV* poly_sv); - SV* to_SV(); + SV* to_AV(); SV* to_SV_ref(); SV* to_SV_clone_ref() const; SV* to_SV_pureperl() const; diff --git a/xs/src/Line.cpp b/xs/src/Line.cpp index c2450d28b..05775c759 100644 --- a/xs/src/Line.cpp +++ b/xs/src/Line.cpp @@ -61,7 +61,7 @@ Line::from_SV_check(SV* line_sv) } SV* -Line::to_SV() { +Line::to_AV() { AV* av = newAV(); av_extend(av, 1); diff --git a/xs/src/Line.hpp b/xs/src/Line.hpp index 32897641a..7015f7c8f 100644 --- a/xs/src/Line.hpp +++ b/xs/src/Line.hpp @@ -15,7 +15,7 @@ class 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_AV(); SV* to_SV_ref(); SV* to_SV_clone_ref() const; SV* to_SV_pureperl() const; diff --git a/xs/src/MultiPoint.cpp b/xs/src/MultiPoint.cpp index 1290a614e..aad03386c 100644 --- a/xs/src/MultiPoint.cpp +++ b/xs/src/MultiPoint.cpp @@ -62,7 +62,7 @@ MultiPoint::from_SV_check(SV* poly_sv) } SV* -MultiPoint::to_SV() { +MultiPoint::to_AV() { const unsigned int num_points = this->points.size(); AV* av = newAV(); av_extend(av, num_points-1); diff --git a/xs/src/MultiPoint.hpp b/xs/src/MultiPoint.hpp index 39c3db4a0..85fc5bada 100644 --- a/xs/src/MultiPoint.hpp +++ b/xs/src/MultiPoint.hpp @@ -13,7 +13,7 @@ class MultiPoint Points points; void from_SV(SV* poly_sv); void from_SV_check(SV* poly_sv); - SV* to_SV(); + SV* to_AV(); SV* to_SV_pureperl() const; void scale(double factor); void translate(double x, double y); diff --git a/xs/src/TriangleMesh.cpp b/xs/src/TriangleMesh.cpp index 3ebab04de..2c5c7a52d 100644 --- a/xs/src/TriangleMesh.cpp +++ b/xs/src/TriangleMesh.cpp @@ -16,6 +16,13 @@ TriangleMesh::~TriangleMesh() { stl_close(&stl); } +SV* +TriangleMesh::to_SV() { + SV* sv = newSV(0); + sv_setref_pv( sv, "Slic3r::TriangleMesh::XS", (void*)this ); + return sv; +} + void TriangleMesh::ReadSTLFile(char* input_file) { stl_open(&stl, input_file); @@ -471,10 +478,10 @@ TriangleMesh::slice(const std::vector &z) return layers; } -std::vector +TriangleMeshPtrs TriangleMesh::split() const { - std::vector meshes; + TriangleMeshPtrs meshes; std::set seen_facets; // loop while we have remaining facets @@ -483,7 +490,8 @@ TriangleMesh::split() const std::queue facet_queue; std::deque facets; for (int facet_idx = 0; facet_idx < this->stl.stats.number_of_facets; facet_idx++) { - if (seen_facets.find(facet_idx) != seen_facets.end()) { + if (seen_facets.find(facet_idx) == seen_facets.end()) { + // if facet was not seen put it into queue and start searching facet_queue.push(facet_idx); break; } @@ -493,7 +501,7 @@ TriangleMesh::split() const while (!facet_queue.empty()) { int facet_idx = facet_queue.front(); facet_queue.pop(); - if (seen_facets.find(facet_idx) == seen_facets.end()) continue; + if (seen_facets.find(facet_idx) != seen_facets.end()) continue; facets.push_back(facet_idx); for (int j = 0; j <= 2; j++) { facet_queue.push(this->stl.neighbors_start[facet_idx].neighbor[j]); @@ -501,8 +509,8 @@ TriangleMesh::split() const seen_facets.insert(facet_idx); } - meshes.resize(meshes.size()+1); - TriangleMesh* mesh = &(meshes.back()); + TriangleMesh* mesh = new TriangleMesh; + meshes.push_back(mesh); stl_initialize(&mesh->stl); mesh->stl.stats.type = inmemory; mesh->stl.stats.number_of_facets = facets.size(); diff --git a/xs/src/TriangleMesh.hpp b/xs/src/TriangleMesh.hpp index a3f112052..2506160f1 100644 --- a/xs/src/TriangleMesh.hpp +++ b/xs/src/TriangleMesh.hpp @@ -9,11 +9,15 @@ namespace Slic3r { +class TriangleMesh; +typedef std::vector TriangleMeshPtrs; + class TriangleMesh { public: TriangleMesh(); ~TriangleMesh(); + SV* to_SV(); void ReadSTLFile(char* input_file); void ReadFromPerl(SV* vertices, SV* facets); void Repair(); @@ -23,7 +27,7 @@ class TriangleMesh void align_to_origin(); void rotate(double angle, Point* center); std::vector* slice(const std::vector &z); - std::vector split() const; + TriangleMeshPtrs split() const; stl_file stl; }; diff --git a/xs/t/01_trianglemesh.t b/xs/t/01_trianglemesh.t index 32d189826..d8b5cb5e8 100644 --- a/xs/t/01_trianglemesh.t +++ b/xs/t/01_trianglemesh.t @@ -4,7 +4,7 @@ use strict; use warnings; use Slic3r::XS; -use Test::More tests => 43; +use Test::More tests => 45; is Slic3r::TriangleMesh::XS::hello_world(), 'Hello world!', 'hello world'; @@ -42,6 +42,10 @@ my $cube = { $m->rotate(45, Slic3r::Point->new(20,20)); ok abs($m->size->[0] - sqrt(2)*40) < 1E-4, 'rotate'; + + my $result = $m->split; + is scalar(@$result), 1, 'split'; + isa_ok $result->[0], 'Slic3r::TriangleMesh::XS', 'split'; } { diff --git a/xs/xsp/ExPolygon.xsp b/xs/xsp/ExPolygon.xsp index f650e0e81..28876e232 100644 --- a/xs/xsp/ExPolygon.xsp +++ b/xs/xsp/ExPolygon.xsp @@ -10,7 +10,7 @@ ExPolygon* clone() %code{% const char* CLASS = "Slic3r::ExPolygon"; RETVAL = new ExPolygon(*THIS); %}; SV* arrayref() - %code{% RETVAL = THIS->to_SV(); %}; + %code{% RETVAL = THIS->to_AV(); %}; SV* pp() %code{% RETVAL = THIS->to_SV_pureperl(); %}; Polygon* contour() diff --git a/xs/xsp/ExtrusionLoop.xsp b/xs/xsp/ExtrusionLoop.xsp index 984b8d5d6..230443b60 100644 --- a/xs/xsp/ExtrusionLoop.xsp +++ b/xs/xsp/ExtrusionLoop.xsp @@ -8,7 +8,7 @@ %name{Slic3r::ExtrusionLoop} class ExtrusionLoop { ~ExtrusionLoop(); SV* arrayref() - %code{% RETVAL = THIS->polygon.to_SV(); %}; + %code{% RETVAL = THIS->polygon.to_AV(); %}; SV* pp() %code{% RETVAL = THIS->polygon.to_SV_pureperl(); %}; void reverse() diff --git a/xs/xsp/ExtrusionPath.xsp b/xs/xsp/ExtrusionPath.xsp index ae5f16e12..34c845707 100644 --- a/xs/xsp/ExtrusionPath.xsp +++ b/xs/xsp/ExtrusionPath.xsp @@ -8,7 +8,7 @@ %name{Slic3r::ExtrusionPath} class ExtrusionPath { ~ExtrusionPath(); SV* arrayref() - %code{% RETVAL = THIS->polyline.to_SV(); %}; + %code{% RETVAL = THIS->polyline.to_AV(); %}; SV* pp() %code{% RETVAL = THIS->polyline.to_SV_pureperl(); %}; void pop_back() diff --git a/xs/xsp/Line.xsp b/xs/xsp/Line.xsp index cde39fd81..d3a3ce37c 100644 --- a/xs/xsp/Line.xsp +++ b/xs/xsp/Line.xsp @@ -10,7 +10,7 @@ Line* clone() %code{% const char* CLASS = "Slic3r::Line"; RETVAL = new Line(*THIS); %}; SV* arrayref() - %code{% RETVAL = THIS->to_SV(); %}; + %code{% RETVAL = THIS->to_AV(); %}; SV* pp() %code{% RETVAL = THIS->to_SV_pureperl(); %}; Point* a() diff --git a/xs/xsp/Polygon.xsp b/xs/xsp/Polygon.xsp index 8339382ef..58c3d0883 100644 --- a/xs/xsp/Polygon.xsp +++ b/xs/xsp/Polygon.xsp @@ -10,7 +10,7 @@ Polygon* clone() %code{% const char* CLASS = "Slic3r::Polygon"; RETVAL = new Polygon(*THIS); %}; SV* arrayref() - %code{% RETVAL = THIS->to_SV(); %}; + %code{% RETVAL = THIS->to_AV(); %}; SV* pp() %code{% RETVAL = THIS->to_SV_pureperl(); %}; void scale(double factor); diff --git a/xs/xsp/Polyline.xsp b/xs/xsp/Polyline.xsp index 5d6ac400b..15ee0c5ff 100644 --- a/xs/xsp/Polyline.xsp +++ b/xs/xsp/Polyline.xsp @@ -10,7 +10,7 @@ Polyline* clone() %code{% const char* CLASS = "Slic3r::Polyline"; RETVAL = new Polyline(*THIS); %}; SV* arrayref() - %code{% RETVAL = THIS->to_SV(); %}; + %code{% RETVAL = THIS->to_AV(); %}; SV* pp() %code{% RETVAL = THIS->to_SV_pureperl(); %}; void scale(double factor); diff --git a/xs/xsp/TriangleMesh.xsp b/xs/xsp/TriangleMesh.xsp index 97f66bfae..e97da15dc 100644 --- a/xs/xsp/TriangleMesh.xsp +++ b/xs/xsp/TriangleMesh.xsp @@ -16,6 +16,7 @@ void translate(float x, float y, float z); void align_to_origin(); void rotate(double angle, Point* center); + TriangleMeshPtrs split(); %{ SV* diff --git a/xs/xsp/my.map b/xs/xsp/my.map index e7735f7d9..e0a4cb9d6 100644 --- a/xs/xsp/my.map +++ b/xs/xsp/my.map @@ -18,13 +18,22 @@ SurfaceType T_UV ClipperLib::JoinType T_UV ClipperLib::PolyFillType T_UV +# we return these types whenever we want the items to be cloned Points T_ARRAYREF Lines T_ARRAYREF Polygons T_ARRAYREF ExPolygons T_ARRAYREF +# we return these types whenever we want the items to be returned +# by reference and marked ::Ref because they're contained in another +# Perl object Polygons* T_ARRAYREF_PTR +# we return these types whenever we want the items to be returned +# by reference and not marked ::Ref because they're newly allocated +# and not referenced by any Perl object +TriangleMeshPtrs T_PTR_ARRAYREF + INPUT T_ARRAYREF @@ -52,7 +61,7 @@ T_ARRAYREF av_extend(av, $var.size()-1); int i = 0; for (${type}::const_iterator it = $var.begin(); it != $var.end(); ++it) { - av_store(av, i++, (*it).to_SV_clone_ref()); + av_store(av, i++, it->to_SV_clone_ref()); } $var.clear(); @@ -63,5 +72,15 @@ T_ARRAYREF_PTR av_extend(av, $var->size()-1); int i = 0; for (${ my $t = $type; $t =~ s/\*$//; \$t }::iterator it = $var->begin(); it != $var->end(); ++it) { - av_store(av, i++, (*it).to_SV_ref()); + av_store(av, i++, it->to_SV_ref()); + } + +T_PTR_ARRAYREF + AV* av = newAV(); + $arg = newRV_noinc((SV*)av); + sv_2mortal($arg); + av_extend(av, $var.size()-1); + int i = 0; + for (${type}::iterator it = $var.begin(); it != $var.end(); ++it) { + av_store(av, i++, (*it)->to_SV()); } diff --git a/xs/xsp/typemap.xspt b/xs/xsp/typemap.xspt index ee1da30e0..9a1e79314 100644 --- a/xs/xsp/typemap.xspt +++ b/xs/xsp/typemap.xspt @@ -16,7 +16,7 @@ %typemap{Polygons}; %typemap{ExPolygons}; %typemap{Polygons*}; -%typemap{Lines*}; +%typemap{TriangleMeshPtrs}; %typemap{SurfaceType}{parsed}{ %cpp_type{SurfaceType};