Browse Source

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

Alessandro Ranellucci 11 years ago
parent
commit
fe061b19ad

+ 0 - 5
lib/Slic3r/Polygon.pm

@@ -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 - 0
xs/src/ClipperUtils.cpp

@@ -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;
+}
+
+
+
+}

+ 15 - 169
xs/src/ClipperUtils.hpp

@@ -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
-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 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
-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 scaleClipperPolygons(ClipperLib::Polygons &polygons, const double 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 - 0
xs/src/ExPolygon.cpp

@@ -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);
+    }
+}
+
+}

+ 0 - 99
xs/src/ExPolygon.hpp

@@ -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 - 0
xs/src/ExPolygonCollection.cpp

@@ -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 - 31
xs/src/ExPolygonCollection.hpp

@@ -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 - 0
xs/src/ExtrusionEntity.cpp

@@ -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 - 34
xs/src/ExtrusionEntity.hpp

@@ -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 - 0
xs/src/Line.cpp

@@ -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);
+}
+
+}

Some files were not shown because too many files changed in this diff