diff --git a/xs/lib/Slic3r/XS.pm b/xs/lib/Slic3r/XS.pm index 082bfb6f64..fb2649192a 100644 --- a/xs/lib/Slic3r/XS.pm +++ b/xs/lib/Slic3r/XS.pm @@ -60,6 +60,11 @@ sub new { return $self; } +package Slic3r::ExtrusionPath::Collection::Ref; +our @ISA = 'Slic3r::ExtrusionPath::Collection'; + +sub DESTROY {} + package Slic3r::ExtrusionLoop; use overload '@{}' => sub { $_[0]->arrayref }, @@ -87,6 +92,11 @@ sub clone { ); } +package Slic3r::ExtrusionLoop::Ref; +our @ISA = 'Slic3r::ExtrusionLoop'; + +sub DESTROY {} + package Slic3r::ExtrusionPath; use overload '@{}' => sub { $_[0]->arrayref }, @@ -114,6 +124,11 @@ sub clone { ); } +package Slic3r::ExtrusionPath::Ref; +our @ISA = 'Slic3r::ExtrusionPath'; + +sub DESTROY {} + package Slic3r::Surface; sub new { diff --git a/xs/src/ExtrusionEntityCollection.cpp b/xs/src/ExtrusionEntityCollection.cpp index 2b0df0eb20..c5bc809c91 100644 --- a/xs/src/ExtrusionEntityCollection.cpp +++ b/xs/src/ExtrusionEntityCollection.cpp @@ -5,7 +5,11 @@ namespace Slic3r { ExtrusionEntityCollection* ExtrusionEntityCollection::clone() const { - return new ExtrusionEntityCollection (*this); + ExtrusionEntityCollection* collection = new ExtrusionEntityCollection (*this); + for (ExtrusionEntitiesPtr::iterator it = collection->entities.begin(); it != collection->entities.end(); ++it) { + *it = (*it)->clone(); + } + return collection; } void @@ -43,7 +47,11 @@ ExtrusionEntityCollection::chained_path_from(Point* start_near, bool no_reverse) { if (this->no_sort) return new ExtrusionEntityCollection(*this); ExtrusionEntityCollection* retval = new ExtrusionEntityCollection; - ExtrusionEntitiesPtr my_paths = this->entities; + + ExtrusionEntitiesPtr my_paths; + for (ExtrusionEntitiesPtr::const_iterator it = this->entities.begin(); it != this->entities.end(); ++it) { + my_paths.push_back((*it)->clone()); + } Points endpoints; for (ExtrusionEntitiesPtr::iterator it = my_paths.begin(); it != my_paths.end(); ++it) { @@ -60,7 +68,6 @@ ExtrusionEntityCollection::chained_path_from(Point* start_near, bool no_reverse) int start_index = start_near->nearest_point_index(endpoints); int path_index = start_index/2; if (start_index % 2 && !no_reverse) { - my_paths.at(path_index) = my_paths.at(path_index)->clone(); // maybe we should clone them all when building my_paths? my_paths.at(path_index)->reverse(); } retval->entities.push_back(my_paths.at(path_index)); diff --git a/xs/xsp/ExtrusionEntityCollection.xsp b/xs/xsp/ExtrusionEntityCollection.xsp index c0e3f39b84..19c84914c2 100644 --- a/xs/xsp/ExtrusionEntityCollection.xsp +++ b/xs/xsp/ExtrusionEntityCollection.xsp @@ -7,7 +7,6 @@ %name{Slic3r::ExtrusionPath::Collection} class ExtrusionEntityCollection { %name{_new} ExtrusionEntityCollection(); - ~ExtrusionEntityCollection(); void clear() %code{% THIS->entities.clear(); %}; ExtrusionEntityCollection* chained_path(bool no_reverse) @@ -16,6 +15,14 @@ %code{% const char* CLASS = "Slic3r::ExtrusionPath::Collection"; RETVAL = THIS->chained_path_from(start_near, no_reverse); %}; %{ +void +ExtrusionEntityCollection::DESTROY() + CODE: + for (ExtrusionEntitiesPtr::iterator it = THIS->entities.begin(); it != THIS->entities.end(); ++it) { + delete *it; + } + delete THIS; + SV* ExtrusionEntityCollection::arrayref() CODE: @@ -24,13 +31,13 @@ ExtrusionEntityCollection::arrayref() int i = 0; for (ExtrusionEntitiesPtr::iterator it = THIS->entities.begin(); it != THIS->entities.end(); ++it) { SV* sv = newSV(0); - // return COPIES + // return our item by reference if (ExtrusionPath* path = dynamic_cast(*it)) { - sv_setref_pv( sv, "Slic3r::ExtrusionPath", new ExtrusionPath(*(ExtrusionPath*)*it) ); - } else if (ExtrusionLoop* path = dynamic_cast(*it)) { - sv_setref_pv( sv, "Slic3r::ExtrusionLoop", new ExtrusionLoop(*(ExtrusionLoop*)*it) ); + sv_setref_pv( sv, "Slic3r::ExtrusionPath::Ref", path ); + } else if (ExtrusionLoop* loop = dynamic_cast(*it)) { + sv_setref_pv( sv, "Slic3r::ExtrusionLoop::Ref", loop ); } else { - sv_setref_pv( sv, "Slic3r::ExtrusionPath::Collection", new ExtrusionEntityCollection(*(ExtrusionEntityCollection*)*it) ); + sv_setref_pv( sv, "Slic3r::ExtrusionPath::Collection::Ref", *it ); } av_store(av, i++, sv); }