Merge branch 'master' into sender

This commit is contained in:
Alessandro Ranellucci 2015-11-05 11:04:01 +01:00
commit 9f9b5afedb
43 changed files with 267 additions and 242 deletions

View file

@ -346,7 +346,8 @@ sub get_option {
gui_flags => $optdef->{gui_flags}, gui_flags => $optdef->{gui_flags},
label => ($self->full_labels && defined $optdef->{full_label}) ? $optdef->{full_label} : $optdef->{label}, label => ($self->full_labels && defined $optdef->{full_label}) ? $optdef->{full_label} : $optdef->{label},
sidetext => $optdef->{sidetext}, sidetext => $optdef->{sidetext},
tooltip => $optdef->{tooltip} . " (default: " . $default_value . ")", # calling serialize() ensures we get a stringified value
tooltip => $optdef->{tooltip} . " (default: " . $self->config->serialize($opt_key) . ")",
multiline => $optdef->{multiline}, multiline => $optdef->{multiline},
width => $optdef->{width}, width => $optdef->{width},
min => $optdef->{min}, min => $optdef->{min},

View file

@ -227,7 +227,6 @@ sub new {
$self->object_list_changed; $self->object_list_changed;
EVT_BUTTON($self, $self->{btn_export_gcode}, sub { EVT_BUTTON($self, $self->{btn_export_gcode}, sub {
$self->export_gcode; $self->export_gcode;
Slic3r::thread_cleanup();
}); });
EVT_BUTTON($self, $self->{btn_print}, sub { EVT_BUTTON($self, $self->{btn_print}, sub {
$self->{print_file} = $self->export_gcode(Wx::StandardPaths::Get->GetTempDir()); $self->{print_file} = $self->export_gcode(Wx::StandardPaths::Get->GetTempDir());
@ -791,7 +790,7 @@ sub rotate {
$self->schedule_background_process; $self->schedule_background_process;
} }
sub flip { sub mirror {
my ($self, $axis) = @_; my ($self, $axis) = @_;
my ($obj_idx, $object) = $self->selected_object; my ($obj_idx, $object) = $self->selected_object;
@ -800,13 +799,13 @@ sub flip {
my $model_object = $self->{model}->objects->[$obj_idx]; my $model_object = $self->{model}->objects->[$obj_idx];
my $model_instance = $model_object->instances->[0]; my $model_instance = $model_object->instances->[0];
# apply Z rotation before flipping # apply Z rotation before mirroring
if ($model_instance->rotation != 0) { if ($model_instance->rotation != 0) {
$model_object->rotate($model_instance->rotation, Z); $model_object->rotate($model_instance->rotation, Z);
$_->set_rotation(0) for @{ $model_object->instances }; $_->set_rotation(0) for @{ $model_object->instances };
} }
$model_object->flip($axis); $model_object->mirror($axis);
$model_object->update_bounding_box; $model_object->update_bounding_box;
# realign object to Z = 0 # realign object to Z = 0
@ -1006,7 +1005,7 @@ sub start_background_process {
$self->{print}->process; $self->{print}->process;
}; };
if ($@) { if ($@) {
Slic3r::debugf "Discarding background process error: $@\n"; Slic3r::debugf "Background process error: $@\n";
Wx::PostEvent($self, Wx::PlThreadEvent->new(-1, $PROCESS_COMPLETED_EVENT, $@)); Wx::PostEvent($self, Wx::PlThreadEvent->new(-1, $PROCESS_COMPLETED_EVENT, $@));
} else { } else {
Wx::PostEvent($self, Wx::PlThreadEvent->new(-1, $PROCESS_COMPLETED_EVENT, undef)); Wx::PostEvent($self, Wx::PlThreadEvent->new(-1, $PROCESS_COMPLETED_EVENT, undef));
@ -1157,6 +1156,12 @@ sub on_process_completed {
$self->{process_thread}->detach if $self->{process_thread}; $self->{process_thread}->detach if $self->{process_thread};
$self->{process_thread} = undef; $self->{process_thread} = undef;
# if we're supposed to perform an explicit export let's display the error in a dialog
if ($error && $self->{export_gcode_output_file}) {
$self->{export_gcode_output_file} = undef;
Slic3r::GUI::show_error($self, $error);
}
return if $error; return if $error;
$self->{toolpaths2D}->reload_print if $self->{toolpaths2D}; $self->{toolpaths2D}->reload_print if $self->{toolpaths2D};
$self->{preview3D}->reload_print if $self->{preview3D}; $self->{preview3D}->reload_print if $self->{preview3D};
@ -1721,17 +1726,17 @@ sub object_menu {
$self->rotate(undef, Z); $self->rotate(undef, Z);
}); });
my $flipMenu = Wx::Menu->new; my $mirrorMenu = Wx::Menu->new;
my $flipMenuItem = $menu->AppendSubMenu($flipMenu, "Flip", 'Mirror the selected object'); my $mirrorMenuItem = $menu->AppendSubMenu($mirrorMenu, "Mirror", 'Mirror the selected object');
$frame->_set_menu_item_icon($flipMenuItem, 'shape_flip_horizontal.png'); $frame->_set_menu_item_icon($mirrorMenuItem, 'shape_flip_horizontal.png');
$frame->_append_menu_item($flipMenu, "Along X axis…", 'Mirror the selected object along the X axis', sub { $frame->_append_menu_item($mirrorMenu, "Along X axis…", 'Mirror the selected object along the X axis', sub {
$self->flip(X); $self->mirror(X);
}); });
$frame->_append_menu_item($flipMenu, "Along Y axis…", 'Mirror the selected object along the Y axis', sub { $frame->_append_menu_item($mirrorMenu, "Along Y axis…", 'Mirror the selected object along the Y axis', sub {
$self->flip(Y); $self->mirror(Y);
}); });
$frame->_append_menu_item($flipMenu, "Along Z axis…", 'Mirror the selected object along the Z axis', sub { $frame->_append_menu_item($mirrorMenu, "Along Z axis…", 'Mirror the selected object along the Z axis', sub {
$self->flip(Z); $self->mirror(Z);
}); });
my $scaleMenu = Wx::Menu->new; my $scaleMenu = Wx::Menu->new;

View file

@ -975,7 +975,7 @@ sub _update_description {
package Slic3r::GUI::Tab::Printer; package Slic3r::GUI::Tab::Printer;
use base 'Slic3r::GUI::Tab'; use base 'Slic3r::GUI::Tab';
use Wx qw(wxTheApp :sizer :button :bitmap :misc :id); use Wx qw(wxTheApp :sizer :button :bitmap :misc :id :icon :dialog);
use Wx::Event qw(EVT_BUTTON); use Wx::Event qw(EVT_BUTTON);
sub name { 'printer' } sub name { 'printer' }
@ -1360,6 +1360,22 @@ sub _update {
# some options only apply when not using firmware retraction # some options only apply when not using firmware retraction
$self->get_field($_, $i)->toggle($retraction && !$config->use_firmware_retraction) $self->get_field($_, $i)->toggle($retraction && !$config->use_firmware_retraction)
for qw(retract_speed retract_restart_extra wipe); for qw(retract_speed retract_restart_extra wipe);
if ($config->use_firmware_retraction && $config->get_at('wipe', $i)) {
my $dialog = Wx::MessageDialog->new($self,
"The Wipe option is not available when using the Firmware Retraction mode.\n"
. "\nShall I disable it in order to enable Firmware Retraction?",
'Firmware Retraction', wxICON_WARNING | wxYES | wxNO);
my $new_conf = Slic3r::Config->new;
if ($dialog->ShowModal() == wxID_YES) {
my $wipe = $config->wipe;
$wipe->[$i] = 0;
$new_conf->set("wipe", $wipe);
} else {
$new_conf->set("use_firmware_retraction", 0);
}
$self->load_config($new_conf);
}
$self->get_field('retract_length_toolchange', $i)->toggle($have_multiple_extruders); $self->get_field('retract_length_toolchange', $i)->toggle($have_multiple_extruders);

View file

@ -56,7 +56,7 @@ sub make_perimeters {
&& $config->perimeter_speed == $other_config->perimeter_speed && $config->perimeter_speed == $other_config->perimeter_speed
&& $config->gap_fill_speed == $other_config->gap_fill_speed && $config->gap_fill_speed == $other_config->gap_fill_speed
&& $config->overhangs == $other_config->overhangs && $config->overhangs == $other_config->overhangs
&& $config->perimeter_extrusion_width == $other_config->perimeter_extrusion_width && $config->serialize('perimeter_extrusion_width') eq $other_config->serialize('perimeter_extrusion_width')
&& $config->thin_walls == $other_config->thin_walls && $config->thin_walls == $other_config->thin_walls
&& $config->external_perimeters_first == $other_config->external_perimeters_first) { && $config->external_perimeters_first == $other_config->external_perimeters_first) {
push @layerms, $other_layerm; push @layerms, $other_layerm;

View file

@ -308,7 +308,7 @@ sub slice {
# remove empty layers from bottom # remove empty layers from bottom
while (@{$self->layers} && !@{$self->get_layer(0)->slices}) { while (@{$self->layers} && !@{$self->get_layer(0)->slices}) {
shift @{$self->layers}; $self->delete_layer(0);
for (my $i = 0; $i <= $#{$self->layers}; $i++) { for (my $i = 0; $i <= $#{$self->layers}; $i++) {
$self->get_layer($i)->set_id( $self->get_layer($i)->id-1 ); $self->get_layer($i)->set_id( $self->get_layer($i)->id-1 );
} }
@ -319,7 +319,7 @@ sub slice {
$self->_simplify_slices(scale($self->print->config->resolution)); $self->_simplify_slices(scale($self->print->config->resolution));
} }
die "No layers were detected. You might want to repair your STL file(s) or check their size and retry.\n" die "No layers were detected. You might want to repair your STL file(s) or check their size or thickness and retry.\n"
if !@{$self->layers}; if !@{$self->layers};
$self->set_typed_slices(0); $self->set_typed_slices(0);

View file

@ -69,7 +69,7 @@ stl_count_facets(stl_file *stl, char *file) {
long file_size; long file_size;
int header_num_facets; int header_num_facets;
int num_facets; int num_facets;
int i, j; int i;
size_t s; size_t s;
unsigned char chtest[128]; unsigned char chtest[128];
int num_lines = 1; int num_lines = 1;

View file

@ -542,8 +542,8 @@ bool SlopesEqual(const TEdge &e1, const TEdge &e2, bool UseFullInt64Range)
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
bool SlopesEqual(const IntPoint pt1, const IntPoint pt2, bool SlopesEqual(const IntPoint &pt1, const IntPoint &pt2,
const IntPoint pt3, bool UseFullInt64Range) const IntPoint &pt3, bool UseFullInt64Range)
{ {
#ifndef use_int32 #ifndef use_int32
if (UseFullInt64Range) if (UseFullInt64Range)
@ -554,8 +554,8 @@ bool SlopesEqual(const IntPoint pt1, const IntPoint pt2,
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
bool SlopesEqual(const IntPoint pt1, const IntPoint pt2, bool SlopesEqual(const IntPoint &pt1, const IntPoint &pt2,
const IntPoint pt3, const IntPoint pt4, bool UseFullInt64Range) const IntPoint &pt3, const IntPoint &pt4, bool UseFullInt64Range)
{ {
#ifndef use_int32 #ifndef use_int32
if (UseFullInt64Range) if (UseFullInt64Range)
@ -572,7 +572,7 @@ inline bool IsHorizontal(TEdge &e)
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
inline double GetDx(const IntPoint pt1, const IntPoint pt2) inline double GetDx(const IntPoint &pt1, const IntPoint &pt2)
{ {
return (pt1.Y == pt2.Y) ? return (pt1.Y == pt2.Y) ?
HORIZONTAL : (double)(pt2.X - pt1.X) / (pt2.Y - pt1.Y); HORIZONTAL : (double)(pt2.X - pt1.X) / (pt2.Y - pt1.Y);
@ -845,8 +845,8 @@ OutPt* GetBottomPt(OutPt *pp)
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
bool Pt2IsBetweenPt1AndPt3(const IntPoint pt1, bool Pt2IsBetweenPt1AndPt3(const IntPoint &pt1,
const IntPoint pt2, const IntPoint pt3) const IntPoint &pt2, const IntPoint &pt3)
{ {
if ((pt1 == pt3) || (pt1 == pt2) || (pt3 == pt2)) if ((pt1 == pt3) || (pt1 == pt2) || (pt3 == pt2))
return false; return false;
@ -1514,7 +1514,7 @@ void Clipper::DisposeOutRec(PolyOutList::size_type index)
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
void Clipper::SetWindingCount(TEdge &edge) void Clipper::SetWindingCount(TEdge &edge) const
{ {
TEdge *e = edge.PrevInAEL; TEdge *e = edge.PrevInAEL;
//find the edge of the same polytype that immediately preceeds 'edge' in AEL //find the edge of the same polytype that immediately preceeds 'edge' in AEL
@ -1814,7 +1814,7 @@ void Clipper::CopyAELToSEL()
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
void Clipper::AddJoin(OutPt *op1, OutPt *op2, const IntPoint OffPt) void Clipper::AddJoin(OutPt *op1, OutPt *op2, const IntPoint &OffPt)
{ {
Join* j = new Join; Join* j = new Join;
j->OutPt1 = op1; j->OutPt1 = op1;
@ -1840,7 +1840,7 @@ void Clipper::ClearGhostJoins()
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
void Clipper::AddGhostJoin(OutPt *op, const IntPoint OffPt) void Clipper::AddGhostJoin(OutPt *op, const IntPoint &OffPt)
{ {
Join* j = new Join; Join* j = new Join;
j->OutPt1 = op; j->OutPt1 = op;
@ -2180,7 +2180,7 @@ void Clipper::IntersectEdges(TEdge *e1, TEdge *e2, IntPoint &Pt)
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
void Clipper::SetHoleState(TEdge *e, OutRec *outrec) void Clipper::SetHoleState(TEdge *e, OutRec *outrec) const
{ {
bool IsHole = false; bool IsHole = false;
TEdge *e2 = e->PrevInAEL; TEdge *e2 = e->PrevInAEL;
@ -2238,7 +2238,7 @@ OutRec* Clipper::GetOutRec(int Idx)
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
void Clipper::AppendPolygon(TEdge *e1, TEdge *e2) void Clipper::AppendPolygon(TEdge *e1, TEdge *e2) const
{ {
//get the start and ends of both output polygons ... //get the start and ends of both output polygons ...
OutRec *outRec1 = m_PolyOuts[e1->OutIdx]; OutRec *outRec1 = m_PolyOuts[e1->OutIdx];
@ -2588,20 +2588,20 @@ void Clipper::ProcessHorizontal(TEdge *horzEdge)
MaximaList::const_iterator maxIt; MaximaList::const_iterator maxIt;
MaximaList::const_reverse_iterator maxRit; MaximaList::const_reverse_iterator maxRit;
if (m_Maxima.size() > 0) if (!m_Maxima.empty())
{ {
//get the first maxima in range (X) ... //get the first maxima in range (X) ...
if (dir == dLeftToRight) if (dir == dLeftToRight)
{ {
maxIt = m_Maxima.begin(); maxIt = m_Maxima.begin();
while (maxIt != m_Maxima.end() && *maxIt <= horzEdge->Bot.X) maxIt++; while (maxIt != m_Maxima.end() && *maxIt <= horzEdge->Bot.X) ++maxIt;
if (maxIt != m_Maxima.end() && *maxIt >= eLastHorz->Top.X) if (maxIt != m_Maxima.end() && *maxIt >= eLastHorz->Top.X)
maxIt = m_Maxima.end(); maxIt = m_Maxima.end();
} }
else else
{ {
maxRit = m_Maxima.rbegin(); maxRit = m_Maxima.rbegin();
while (maxRit != m_Maxima.rend() && *maxRit > horzEdge->Bot.X) maxRit++; while (maxRit != m_Maxima.rend() && *maxRit > horzEdge->Bot.X) ++maxRit;
if (maxRit != m_Maxima.rend() && *maxRit <= eLastHorz->Top.X) if (maxRit != m_Maxima.rend() && *maxRit <= eLastHorz->Top.X)
maxRit = m_Maxima.rend(); maxRit = m_Maxima.rend();
} }
@ -2620,7 +2620,7 @@ void Clipper::ProcessHorizontal(TEdge *horzEdge)
//this code block inserts extra coords into horizontal edges (in output //this code block inserts extra coords into horizontal edges (in output
//polygons) whereever maxima touch these horizontal edges. This helps //polygons) whereever maxima touch these horizontal edges. This helps
//'simplifying' polygons (ie if the Simplify property is set). //'simplifying' polygons (ie if the Simplify property is set).
if (m_Maxima.size() > 0) if (!m_Maxima.empty())
{ {
if (dir == dLeftToRight) if (dir == dLeftToRight)
{ {
@ -2628,7 +2628,7 @@ void Clipper::ProcessHorizontal(TEdge *horzEdge)
{ {
if (horzEdge->OutIdx >= 0 && !IsOpen) if (horzEdge->OutIdx >= 0 && !IsOpen)
AddOutPt(horzEdge, IntPoint(*maxIt, horzEdge->Bot.Y)); AddOutPt(horzEdge, IntPoint(*maxIt, horzEdge->Bot.Y));
maxIt++; ++maxIt;
} }
} }
else else
@ -2637,7 +2637,7 @@ void Clipper::ProcessHorizontal(TEdge *horzEdge)
{ {
if (horzEdge->OutIdx >= 0 && !IsOpen) if (horzEdge->OutIdx >= 0 && !IsOpen)
AddOutPt(horzEdge, IntPoint(*maxRit, horzEdge->Bot.Y)); AddOutPt(horzEdge, IntPoint(*maxRit, horzEdge->Bot.Y));
maxRit++; ++maxRit;
} }
} }
}; };
@ -3323,7 +3323,7 @@ OutPt* DupOutPt(OutPt* outPt, bool InsertAfter)
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
bool JoinHorz(OutPt* op1, OutPt* op1b, OutPt* op2, OutPt* op2b, bool JoinHorz(OutPt* op1, OutPt* op1b, OutPt* op2, OutPt* op2b,
const IntPoint Pt, bool DiscardLeft) const IntPoint &Pt, bool DiscardLeft)
{ {
Direction Dir1 = (op1->Pt.X > op1b->Pt.X ? dRightToLeft : dLeftToRight); Direction Dir1 = (op1->Pt.X > op1b->Pt.X ? dRightToLeft : dLeftToRight);
Direction Dir2 = (op2->Pt.X > op2b->Pt.X ? dRightToLeft : dLeftToRight); Direction Dir2 = (op2->Pt.X > op2b->Pt.X ? dRightToLeft : dLeftToRight);
@ -3576,7 +3576,7 @@ static OutRec* ParseFirstLeft(OutRec* FirstLeft)
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
void Clipper::FixupFirstLefts1(OutRec* OldOutRec, OutRec* NewOutRec) void Clipper::FixupFirstLefts1(OutRec* OldOutRec, OutRec* NewOutRec) const
{ {
//tests if NewOutRec contains the polygon before reassigning FirstLeft //tests if NewOutRec contains the polygon before reassigning FirstLeft
for (PolyOutList::size_type i = 0; i < m_PolyOuts.size(); ++i) for (PolyOutList::size_type i = 0; i < m_PolyOuts.size(); ++i)
@ -3593,7 +3593,7 @@ void Clipper::FixupFirstLefts1(OutRec* OldOutRec, OutRec* NewOutRec)
} }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
void Clipper::FixupFirstLefts2(OutRec* OldOutRec, OutRec* NewOutRec) void Clipper::FixupFirstLefts2(OutRec* OldOutRec, OutRec* NewOutRec) const
{ {
//reassigns FirstLeft WITHOUT testing if NewOutRec contains the polygon //reassigns FirstLeft WITHOUT testing if NewOutRec contains the polygon
for (PolyOutList::size_type i = 0; i < m_PolyOuts.size(); ++i) for (PolyOutList::size_type i = 0; i < m_PolyOuts.size(); ++i)
@ -4462,7 +4462,7 @@ void MinkowskiSum(const Path& pattern, const Path& path, Paths& solution, bool p
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
void TranslatePath(const Path& input, Path& output, const IntPoint delta) void TranslatePath(const Path& input, Path& output, const IntPoint& delta)
{ {
//precondition: input != output //precondition: input != output
output.resize(input.size()); output.resize(input.size());

View file

@ -224,7 +224,7 @@ public:
bool AddPaths(const Paths &ppg, PolyType PolyTyp, bool Closed); bool AddPaths(const Paths &ppg, PolyType PolyTyp, bool Closed);
virtual void Clear(); virtual void Clear();
IntRect GetBounds(); IntRect GetBounds();
bool PreserveCollinear() {return m_PreserveCollinear;}; bool PreserveCollinear() const {return m_PreserveCollinear;};
void PreserveCollinear(bool value) {m_PreserveCollinear = value;}; void PreserveCollinear(bool value) {m_PreserveCollinear = value;};
protected: protected:
void DisposeLocalMinimaList(); void DisposeLocalMinimaList();
@ -265,9 +265,9 @@ public:
PolyTree &polytree, PolyTree &polytree,
PolyFillType subjFillType, PolyFillType subjFillType,
PolyFillType clipFillType); PolyFillType clipFillType);
bool ReverseSolution() { return m_ReverseOutput; }; bool ReverseSolution() const { return m_ReverseOutput; };
void ReverseSolution(bool value) {m_ReverseOutput = value;}; void ReverseSolution(bool value) {m_ReverseOutput = value;};
bool StrictlySimple() {return m_StrictSimple;}; bool StrictlySimple() const {return m_StrictSimple;};
void StrictlySimple(bool value) {m_StrictSimple = value;}; void StrictlySimple(bool value) {m_StrictSimple = value;};
//set the callback function for z value filling on intersections (otherwise Z is 0) //set the callback function for z value filling on intersections (otherwise Z is 0)
#ifdef use_xyz #ifdef use_xyz
@ -297,7 +297,7 @@ private:
#ifdef use_xyz #ifdef use_xyz
ZFillCallback m_ZFill; //custom callback ZFillCallback m_ZFill; //custom callback
#endif #endif
void SetWindingCount(TEdge& edge); void SetWindingCount(TEdge& edge) const;
bool IsEvenOddFillType(const TEdge& edge) const; bool IsEvenOddFillType(const TEdge& edge) const;
bool IsEvenOddAltFillType(const TEdge& edge) const; bool IsEvenOddAltFillType(const TEdge& edge) const;
void InsertScanbeam(const cInt Y); void InsertScanbeam(const cInt Y);
@ -319,7 +319,7 @@ private:
void AddLocalMaxPoly(TEdge *e1, TEdge *e2, const IntPoint &pt); void AddLocalMaxPoly(TEdge *e1, TEdge *e2, const IntPoint &pt);
OutPt* AddLocalMinPoly(TEdge *e1, TEdge *e2, const IntPoint &pt); OutPt* AddLocalMinPoly(TEdge *e1, TEdge *e2, const IntPoint &pt);
OutRec* GetOutRec(int idx); OutRec* GetOutRec(int idx);
void AppendPolygon(TEdge *e1, TEdge *e2); void AppendPolygon(TEdge *e1, TEdge *e2) const;
void IntersectEdges(TEdge *e1, TEdge *e2, IntPoint &pt); void IntersectEdges(TEdge *e1, TEdge *e2, IntPoint &pt);
OutRec* CreateOutRec(); OutRec* CreateOutRec();
OutPt* AddOutPt(TEdge *e, const IntPoint &pt); OutPt* AddOutPt(TEdge *e, const IntPoint &pt);
@ -332,7 +332,7 @@ private:
void ProcessEdgesAtTopOfScanbeam(const cInt topY); void ProcessEdgesAtTopOfScanbeam(const cInt topY);
void BuildResult(Paths& polys); void BuildResult(Paths& polys);
void BuildResult2(PolyTree& polytree); void BuildResult2(PolyTree& polytree);
void SetHoleState(TEdge *e, OutRec *outrec); void SetHoleState(TEdge *e, OutRec *outrec) const;
void DisposeIntersectNodes(); void DisposeIntersectNodes();
bool FixupIntersectionOrder(); bool FixupIntersectionOrder();
void FixupOutPolygon(OutRec &outrec); void FixupOutPolygon(OutRec &outrec);
@ -340,15 +340,15 @@ private:
bool IsHole(TEdge *e); bool IsHole(TEdge *e);
bool FindOwnerFromSplitRecs(OutRec &outRec, OutRec *&currOrfl); bool FindOwnerFromSplitRecs(OutRec &outRec, OutRec *&currOrfl);
void FixHoleLinkage(OutRec &outrec); void FixHoleLinkage(OutRec &outrec);
void AddJoin(OutPt *op1, OutPt *op2, const IntPoint offPt); void AddJoin(OutPt *op1, OutPt *op2, const IntPoint &offPt);
void ClearJoins(); void ClearJoins();
void ClearGhostJoins(); void ClearGhostJoins();
void AddGhostJoin(OutPt *op, const IntPoint offPt); void AddGhostJoin(OutPt *op, const IntPoint &offPt);
bool JoinPoints(Join *j, OutRec* outRec1, OutRec* outRec2); bool JoinPoints(Join *j, OutRec* outRec1, OutRec* outRec2);
void JoinCommonEdges(); void JoinCommonEdges();
void DoSimplePolygons(); void DoSimplePolygons();
void FixupFirstLefts1(OutRec* OldOutRec, OutRec* NewOutRec); void FixupFirstLefts1(OutRec* OldOutRec, OutRec* NewOutRec) const;
void FixupFirstLefts2(OutRec* OldOutRec, OutRec* NewOutRec); void FixupFirstLefts2(OutRec* OldOutRec, OutRec* NewOutRec) const;
#ifdef use_xyz #ifdef use_xyz
void SetZ(IntPoint& pt, TEdge& e1, TEdge& e2); void SetZ(IntPoint& pt, TEdge& e1, TEdge& e2);
#endif #endif

View file

@ -30,7 +30,7 @@ class BridgeDirectionComparator {
BridgeDetector::BridgeDetector(const ExPolygon &_expolygon, const ExPolygonCollection &_lower_slices, BridgeDetector::BridgeDetector(const ExPolygon &_expolygon, const ExPolygonCollection &_lower_slices,
coord_t _extrusion_width) coord_t _extrusion_width)
: expolygon(_expolygon), lower_slices(_lower_slices), extrusion_width(_extrusion_width), : expolygon(_expolygon), lower_slices(_lower_slices), extrusion_width(_extrusion_width),
angle(-1), resolution(PI/36.0) resolution(PI/36.0), angle(-1)
{ {
/* outset our bridge by an arbitrary amout; we'll use this outer margin /* outset our bridge by an arbitrary amout; we'll use this outer margin
for detecting anchors */ for detecting anchors */
@ -293,8 +293,8 @@ BridgeDetector::unsupported_edges(double angle, Polylines* unsupported) const
TODO: angle tolerance should probably be based on segment length and flow width, TODO: angle tolerance should probably be based on segment length and flow width,
so that we build supports whenever there's a chance that at least one or two bridge so that we build supports whenever there's a chance that at least one or two bridge
extrusions would be anchored within such length (i.e. a slightly non-parallel bridging extrusions would be anchored within such length (i.e. a slightly non-parallel bridging
direction might still benefit from anchors if long enough) */ direction might still benefit from anchors if long enough)
double angle_tolerance = PI / 180.0 * 5.0; double angle_tolerance = PI / 180.0 * 5.0; */
for (Polylines::const_iterator polyline = _unsupported.begin(); polyline != _unsupported.end(); ++polyline) { for (Polylines::const_iterator polyline = _unsupported.begin(); polyline != _unsupported.end(); ++polyline) {
Lines lines = polyline->lines(); Lines lines = polyline->lines();
for (Lines::const_iterator line = lines.begin(); line != lines.end(); ++line) { for (Lines::const_iterator line = lines.begin(); line != lines.end(); ++line) {

View file

@ -685,7 +685,7 @@ SV*
polynode_children_2_perl(const ClipperLib::PolyNode& node) polynode_children_2_perl(const ClipperLib::PolyNode& node)
{ {
AV* av = newAV(); AV* av = newAV();
const unsigned int len = node.ChildCount(); const int len = node.ChildCount();
if (len > 0) av_extend(av, len-1); if (len > 0) av_extend(av, len-1);
for (int i = 0; i < len; ++i) { for (int i = 0; i < len; ++i) {
av_store(av, i, polynode2perl(*node.Childs[i])); av_store(av, i, polynode2perl(*node.Childs[i]));

View file

@ -8,7 +8,7 @@
namespace Slic3r { namespace Slic3r {
bool bool
ConfigBase::has(const t_config_option_key opt_key) { ConfigBase::has(const t_config_option_key &opt_key) {
return (this->option(opt_key, false) != NULL); return (this->option(opt_key, false) != NULL);
} }
@ -52,14 +52,14 @@ ConfigBase::diff(ConfigBase &other) {
} }
std::string std::string
ConfigBase::serialize(const t_config_option_key opt_key) { ConfigBase::serialize(const t_config_option_key &opt_key) {
ConfigOption* opt = this->option(opt_key); ConfigOption* opt = this->option(opt_key);
assert(opt != NULL); assert(opt != NULL);
return opt->serialize(); return opt->serialize();
} }
bool bool
ConfigBase::set_deserialize(const t_config_option_key opt_key, std::string str) { ConfigBase::set_deserialize(const t_config_option_key &opt_key, std::string str) {
if (this->def->count(opt_key) == 0) throw "Calling set_deserialize() on unknown option"; if (this->def->count(opt_key) == 0) throw "Calling set_deserialize() on unknown option";
ConfigOptionDef* optdef = &(*this->def)[opt_key]; ConfigOptionDef* optdef = &(*this->def)[opt_key];
if (!optdef->shortcut.empty()) { if (!optdef->shortcut.empty()) {
@ -75,7 +75,7 @@ ConfigBase::set_deserialize(const t_config_option_key opt_key, std::string str)
} }
double double
ConfigBase::get_abs_value(const t_config_option_key opt_key) { ConfigBase::get_abs_value(const t_config_option_key &opt_key) {
ConfigOption* opt = this->option(opt_key, false); ConfigOption* opt = this->option(opt_key, false);
if (ConfigOptionFloatOrPercent* optv = dynamic_cast<ConfigOptionFloatOrPercent*>(opt)) { if (ConfigOptionFloatOrPercent* optv = dynamic_cast<ConfigOptionFloatOrPercent*>(opt)) {
// get option definition // get option definition
@ -92,7 +92,7 @@ ConfigBase::get_abs_value(const t_config_option_key opt_key) {
} }
double double
ConfigBase::get_abs_value(const t_config_option_key opt_key, double ratio_over) { ConfigBase::get_abs_value(const t_config_option_key &opt_key, double ratio_over) {
// get stored option value // get stored option value
ConfigOptionFloatOrPercent* opt = dynamic_cast<ConfigOptionFloatOrPercent*>(this->option(opt_key)); ConfigOptionFloatOrPercent* opt = dynamic_cast<ConfigOptionFloatOrPercent*>(this->option(opt_key));
assert(opt != NULL); assert(opt != NULL);
@ -282,7 +282,7 @@ ConfigBase::set(t_config_option_key opt_key, SV* value) {
/* This method is implemented as a workaround for this typemap bug: /* This method is implemented as a workaround for this typemap bug:
https://rt.cpan.org/Public/Bug/Display.html?id=94110 */ https://rt.cpan.org/Public/Bug/Display.html?id=94110 */
bool bool
ConfigBase::set_deserialize(const t_config_option_key opt_key, SV* str) { ConfigBase::set_deserialize(const t_config_option_key &opt_key, SV* str) {
size_t len; size_t len;
const char * c = SvPV(str, len); const char * c = SvPV(str, len);
std::string value(c, len); std::string value(c, len);
@ -328,7 +328,7 @@ DynamicConfig::DynamicConfig (const DynamicConfig& other) {
} }
ConfigOption* ConfigOption*
DynamicConfig::option(const t_config_option_key opt_key, bool create) { DynamicConfig::option(const t_config_option_key &opt_key, bool create) {
if (this->options.count(opt_key) == 0) { if (this->options.count(opt_key) == 0) {
if (create) { if (create) {
ConfigOptionDef* optdef = &(*this->def)[opt_key]; ConfigOptionDef* optdef = &(*this->def)[opt_key];
@ -375,16 +375,16 @@ DynamicConfig::option(const t_config_option_key opt_key, bool create) {
template<class T> template<class T>
T* T*
DynamicConfig::opt(const t_config_option_key opt_key, bool create) { DynamicConfig::opt(const t_config_option_key &opt_key, bool create) {
return dynamic_cast<T*>(this->option(opt_key, create)); return dynamic_cast<T*>(this->option(opt_key, create));
} }
template ConfigOptionInt* DynamicConfig::opt<ConfigOptionInt>(const t_config_option_key opt_key, bool create); template ConfigOptionInt* DynamicConfig::opt<ConfigOptionInt>(const t_config_option_key &opt_key, bool create);
template ConfigOptionBool* DynamicConfig::opt<ConfigOptionBool>(const t_config_option_key opt_key, bool create); template ConfigOptionBool* DynamicConfig::opt<ConfigOptionBool>(const t_config_option_key &opt_key, bool create);
template ConfigOptionBools* DynamicConfig::opt<ConfigOptionBools>(const t_config_option_key opt_key, bool create); template ConfigOptionBools* DynamicConfig::opt<ConfigOptionBools>(const t_config_option_key &opt_key, bool create);
template ConfigOptionPercent* DynamicConfig::opt<ConfigOptionPercent>(const t_config_option_key opt_key, bool create); template ConfigOptionPercent* DynamicConfig::opt<ConfigOptionPercent>(const t_config_option_key &opt_key, bool create);
const ConfigOption* const ConfigOption*
DynamicConfig::option(const t_config_option_key opt_key) const { DynamicConfig::option(const t_config_option_key &opt_key) const {
return const_cast<DynamicConfig*>(this)->option(opt_key, false); return const_cast<DynamicConfig*>(this)->option(opt_key, false);
} }
@ -397,7 +397,7 @@ DynamicConfig::keys() const {
} }
void void
DynamicConfig::erase(const t_config_option_key opt_key) { DynamicConfig::erase(const t_config_option_key &opt_key) {
this->options.erase(opt_key); this->options.erase(opt_key);
} }
@ -412,7 +412,7 @@ StaticConfig::keys() const {
} }
const ConfigOption* const ConfigOption*
StaticConfig::option(const t_config_option_key opt_key) const StaticConfig::option(const t_config_option_key &opt_key) const
{ {
return const_cast<StaticConfig*>(this)->option(opt_key, false); return const_cast<StaticConfig*>(this)->option(opt_key, false);
} }

View file

@ -459,6 +459,7 @@ class ConfigOptionEnumGeneric : public ConfigOption
}; };
enum ConfigOptionType { enum ConfigOptionType {
coNone,
coFloat, coFloat,
coFloats, coFloats,
coInt, coInt,
@ -500,7 +501,8 @@ class ConfigOptionDef
std::vector<std::string> enum_labels; std::vector<std::string> enum_labels;
t_config_enum_values enum_keys_map; t_config_enum_values enum_keys_map;
ConfigOptionDef() : multiline(false), full_width(false), readonly(false), ConfigOptionDef() : type(coNone),
multiline(false), full_width(false), readonly(false),
height(-1), width(-1), min(INT_MIN), max(INT_MAX) {}; height(-1), width(-1), min(INT_MIN), max(INT_MAX) {};
}; };
@ -512,18 +514,18 @@ class ConfigBase
t_optiondef_map* def; t_optiondef_map* def;
ConfigBase() : def(NULL) {}; ConfigBase() : def(NULL) {};
bool has(const t_config_option_key opt_key); bool has(const t_config_option_key &opt_key);
virtual ConfigOption* option(const t_config_option_key opt_key, bool create = false) = 0; virtual ConfigOption* option(const t_config_option_key &opt_key, bool create = false) = 0;
virtual const ConfigOption* option(const t_config_option_key opt_key) const = 0; virtual const ConfigOption* option(const t_config_option_key &opt_key) const = 0;
virtual t_config_option_keys keys() const = 0; virtual t_config_option_keys keys() const = 0;
void apply(const ConfigBase &other, bool ignore_nonexistent = false); void apply(const ConfigBase &other, bool ignore_nonexistent = false);
bool equals(ConfigBase &other); bool equals(ConfigBase &other);
t_config_option_keys diff(ConfigBase &other); t_config_option_keys diff(ConfigBase &other);
std::string serialize(const t_config_option_key opt_key); std::string serialize(const t_config_option_key &opt_key);
bool set_deserialize(const t_config_option_key opt_key, std::string str); bool set_deserialize(const t_config_option_key &opt_key, std::string str);
void set_ifndef(t_config_option_key opt_key, SV* value, bool deserialize = false); void set_ifndef(t_config_option_key opt_key, SV* value, bool deserialize = false);
double get_abs_value(const t_config_option_key opt_key); double get_abs_value(const t_config_option_key &opt_key);
double get_abs_value(const t_config_option_key opt_key, double ratio_over); double get_abs_value(const t_config_option_key &opt_key, double ratio_over);
void setenv_(); void setenv_();
#ifdef SLIC3RXS #ifdef SLIC3RXS
@ -531,7 +533,7 @@ class ConfigBase
SV* get(t_config_option_key opt_key); SV* get(t_config_option_key opt_key);
SV* get_at(t_config_option_key opt_key, size_t i); SV* get_at(t_config_option_key opt_key, size_t i);
bool set(t_config_option_key opt_key, SV* value); bool set(t_config_option_key opt_key, SV* value);
bool set_deserialize(const t_config_option_key opt_key, SV* str); bool set_deserialize(const t_config_option_key &opt_key, SV* str);
#endif #endif
}; };
@ -543,11 +545,11 @@ class DynamicConfig : public ConfigBase
DynamicConfig& operator= (DynamicConfig other); DynamicConfig& operator= (DynamicConfig other);
void swap(DynamicConfig &other); void swap(DynamicConfig &other);
~DynamicConfig(); ~DynamicConfig();
template<class T> T* opt(const t_config_option_key opt_key, bool create = false); template<class T> T* opt(const t_config_option_key &opt_key, bool create = false);
ConfigOption* option(const t_config_option_key opt_key, bool create = false); ConfigOption* option(const t_config_option_key &opt_key, bool create = false);
const ConfigOption* option(const t_config_option_key opt_key) const; const ConfigOption* option(const t_config_option_key &opt_key) const;
t_config_option_keys keys() const; t_config_option_keys keys() const;
void erase(const t_config_option_key opt_key); void erase(const t_config_option_key &opt_key);
private: private:
typedef std::map<t_config_option_key,ConfigOption*> t_options_map; typedef std::map<t_config_option_key,ConfigOption*> t_options_map;
@ -558,8 +560,8 @@ class StaticConfig : public ConfigBase
{ {
public: public:
t_config_option_keys keys() const; t_config_option_keys keys() const;
virtual ConfigOption* option(const t_config_option_key opt_key, bool create = false) = 0; virtual ConfigOption* option(const t_config_option_key &opt_key, bool create = false) = 0;
const ConfigOption* option(const t_config_option_key opt_key) const; const ConfigOption* option(const t_config_option_key &opt_key) const;
#ifdef SLIC3RXS #ifdef SLIC3RXS
bool set(t_config_option_key opt_key, SV* value); bool set(t_config_option_key opt_key, SV* value);

View file

@ -375,31 +375,29 @@ ExPolygon::triangulate_p2t(Polygons* polygons) const
simplify_polygons(*this, &expp, true); simplify_polygons(*this, &expp, true);
for (ExPolygons::const_iterator ex = expp.begin(); ex != expp.end(); ++ex) { for (ExPolygons::const_iterator ex = expp.begin(); ex != expp.end(); ++ex) {
p2t::CDT* cdt;
// TODO: prevent duplicate points // TODO: prevent duplicate points
// contour // contour
{ std::vector<p2t::Point*> ContourPoints;
std::vector<p2t::Point*> points; for (Points::const_iterator point = ex->contour.points.begin(); point != ex->contour.points.end(); ++point) {
for (Points::const_iterator point = ex->contour.points.begin(); point != ex->contour.points.end(); ++point) { // We should delete each p2t::Point object
points.push_back(new p2t::Point(point->x, point->y)); ContourPoints.push_back(new p2t::Point(point->x, point->y));
}
cdt = new p2t::CDT(points);
} }
p2t::CDT cdt(ContourPoints);
// holes // holes
for (Polygons::const_iterator hole = ex->holes.begin(); hole != ex->holes.end(); ++hole) { for (Polygons::const_iterator hole = ex->holes.begin(); hole != ex->holes.end(); ++hole) {
std::vector<p2t::Point*> points; std::vector<p2t::Point*> points;
for (Points::const_iterator point = hole->points.begin(); point != hole->points.end(); ++point) { for (Points::const_iterator point = hole->points.begin(); point != hole->points.end(); ++point) {
// will be destructed in SweepContext::~SweepContext
points.push_back(new p2t::Point(point->x, point->y)); points.push_back(new p2t::Point(point->x, point->y));
} }
cdt->AddHole(points); cdt.AddHole(points);
} }
// perform triangulation // perform triangulation
cdt->Triangulate(); cdt.Triangulate();
std::vector<p2t::Triangle*> triangles = cdt->GetTriangles(); std::vector<p2t::Triangle*> triangles = cdt.GetTriangles();
for (std::vector<p2t::Triangle*>::const_iterator triangle = triangles.begin(); triangle != triangles.end(); ++triangle) { for (std::vector<p2t::Triangle*>::const_iterator triangle = triangles.begin(); triangle != triangles.end(); ++triangle) {
Polygon p; Polygon p;
@ -409,6 +407,10 @@ ExPolygon::triangulate_p2t(Polygons* polygons) const
} }
polygons->push_back(p); polygons->push_back(p);
} }
for(std::vector<p2t::Point*>::iterator it = ContourPoints.begin(); it != ContourPoints.end(); ++it) {
delete *it;
}
} }
} }

View file

@ -2,7 +2,7 @@
namespace Slic3r { namespace Slic3r {
Extruder::Extruder(int id, GCodeConfig *config) Extruder::Extruder(unsigned int id, GCodeConfig *config)
: id(id), : id(id),
config(config) config(config)
{ {

View file

@ -10,7 +10,7 @@ namespace Slic3r {
class Extruder class Extruder
{ {
public: public:
int id; unsigned int id;
double E; double E;
double absolute_E; double absolute_E;
double retracted; double retracted;
@ -18,7 +18,7 @@ class Extruder
double e_per_mm3; double e_per_mm3;
double retract_speed_mm_min; double retract_speed_mm_min;
Extruder(int id, GCodeConfig *config); Extruder(unsigned int id, GCodeConfig *config);
virtual ~Extruder() {} virtual ~Extruder() {}
void reset(); void reset();
double extrude(double dE); double extrude(double dE);

View file

@ -283,7 +283,7 @@ ExtrusionLoop::has_overhang_point(const Point &point) const
if (pos != -1) { if (pos != -1) {
// point belongs to this path // point belongs to this path
// we consider it overhang only if it's not an endpoint // we consider it overhang only if it's not an endpoint
return (path->is_bridge() && pos > 0 && pos != path->polyline.points.size()-1); return (path->is_bridge() && pos > 0 && pos != (int)(path->polyline.points.size())-1);
} }
} }
return false; return false;

View file

@ -6,7 +6,7 @@
namespace Slic3r { namespace Slic3r {
ExtrusionEntityCollection::ExtrusionEntityCollection(const ExtrusionEntityCollection& collection) ExtrusionEntityCollection::ExtrusionEntityCollection(const ExtrusionEntityCollection& collection)
: no_sort(collection.no_sort), orig_indices(collection.orig_indices) : orig_indices(collection.orig_indices), no_sort(collection.no_sort)
{ {
this->append(collection.entities); this->append(collection.entities);
} }

View file

@ -209,9 +209,9 @@ REGISTER_CLASS(Wipe, "GCode::Wipe");
#define EXTRUDER_CONFIG(OPT) this->config.OPT.get_at(this->writer.extruder()->id) #define EXTRUDER_CONFIG(OPT) this->config.OPT.get_at(this->writer.extruder()->id)
GCode::GCode() GCode::GCode()
: enable_loop_clipping(true), enable_cooling_markers(false), layer_count(0), : placeholder_parser(NULL), enable_loop_clipping(true), enable_cooling_markers(false), layer_count(0),
layer_index(-1), first_layer(false), elapsed_time(0), volumetric_speed(0), layer_index(-1), layer(NULL), first_layer(false), elapsed_time(0), volumetric_speed(0),
_last_pos_defined(false), layer(NULL), placeholder_parser(NULL) _last_pos_defined(false)
{ {
} }
@ -435,7 +435,6 @@ GCode::extrude(ExtrusionLoop loop, std::string description, double speed)
// make a little move inwards before leaving loop // make a little move inwards before leaving loop
if (paths.back().role == erExternalPerimeter && this->layer != NULL && this->config.perimeters > 1) { if (paths.back().role == erExternalPerimeter && this->layer != NULL && this->config.perimeters > 1) {
Polyline &last_path_polyline = paths.back().polyline;
// detect angle between last and first segment // detect angle between last and first segment
// the side depends on the original winding order of the polygon (left for contours, right for holes) // the side depends on the original winding order of the polygon (left for contours, right for holes)
Point a = paths.front().polyline.points[1]; // second point Point a = paths.front().polyline.points[1]; // second point
@ -576,7 +575,7 @@ GCode::_extrude(ExtrusionPath path, std::string description, double speed)
gcode += this->writer.set_speed(F); gcode += this->writer.set_speed(F);
double path_length = 0; double path_length = 0;
{ {
std::string comment = this->config.gcode_comments ? (" ; " + description) : ""; std::string comment = this->config.gcode_comments ? description : "";
Lines lines = path.polyline.lines(); Lines lines = path.polyline.lines();
for (Lines::const_iterator line = lines.begin(); line != lines.end(); ++line) { for (Lines::const_iterator line = lines.begin(); line != lines.end(); ++line) {
const double line_length = line->length() * SCALING_FACTOR; const double line_length = line->length() * SCALING_FACTOR;

View file

@ -67,7 +67,7 @@ GCodeWriter::preamble()
} }
std::string std::string
GCodeWriter::postamble() GCodeWriter::postamble() const
{ {
std::ostringstream gcode; std::ostringstream gcode;
if (FLAVOR_IS(gcfMachinekit)) if (FLAVOR_IS(gcfMachinekit))
@ -76,7 +76,7 @@ GCodeWriter::postamble()
} }
std::string std::string
GCodeWriter::set_temperature(unsigned int temperature, bool wait, int tool) GCodeWriter::set_temperature(unsigned int temperature, bool wait, int tool) const
{ {
if (wait && (FLAVOR_IS(gcfMakerWare) || FLAVOR_IS(gcfSailfish))) if (wait && (FLAVOR_IS(gcfMakerWare) || FLAVOR_IS(gcfSailfish)))
return ""; return "";
@ -84,7 +84,7 @@ GCodeWriter::set_temperature(unsigned int temperature, bool wait, int tool)
std::string code, comment; std::string code, comment;
if (wait && FLAVOR_IS_NOT(gcfTeacup)) { if (wait && FLAVOR_IS_NOT(gcfTeacup)) {
code = "M109"; code = "M109";
comment = "wait for temperature to be reached"; comment = "set temperature and wait for it to be reached";
} else { } else {
code = "M104"; code = "M104";
comment = "set temperature"; comment = "set temperature";
@ -110,7 +110,7 @@ GCodeWriter::set_temperature(unsigned int temperature, bool wait, int tool)
} }
std::string std::string
GCodeWriter::set_bed_temperature(unsigned int temperature, bool wait) GCodeWriter::set_bed_temperature(unsigned int temperature, bool wait) const
{ {
std::string code, comment; std::string code, comment;
if (wait && FLAVOR_IS_NOT(gcfTeacup)) { if (wait && FLAVOR_IS_NOT(gcfTeacup)) {
@ -119,10 +119,10 @@ GCodeWriter::set_bed_temperature(unsigned int temperature, bool wait)
} else { } else {
code = "M190"; code = "M190";
} }
comment = "set bed temperature"; comment = "set bed temperature and wait for it to be reached";
} else { } else {
code = "M140"; code = "M140";
comment = "wait for bed temperature to be reached"; comment = "set bed temperature";
} }
std::ostringstream gcode; std::ostringstream gcode;
@ -217,7 +217,7 @@ GCodeWriter::reset_e(bool force)
} }
std::string std::string
GCodeWriter::update_progress(unsigned int num, unsigned int tot, bool allow_100) GCodeWriter::update_progress(unsigned int num, unsigned int tot, bool allow_100) const
{ {
if (FLAVOR_IS_NOT(gcfMakerWare) && FLAVOR_IS_NOT(gcfSailfish)) if (FLAVOR_IS_NOT(gcfMakerWare) && FLAVOR_IS_NOT(gcfSailfish))
return ""; return "";
@ -273,7 +273,7 @@ GCodeWriter::toolchange(unsigned int extruder_id)
} }
std::string std::string
GCodeWriter::set_speed(double F, const std::string &comment) GCodeWriter::set_speed(double F, const std::string &comment) const
{ {
std::ostringstream gcode; std::ostringstream gcode;
gcode << "G1 F" << F; gcode << "G1 F" << F;

View file

@ -24,17 +24,17 @@ class GCodeWriter {
void apply_print_config(const PrintConfig &print_config); void apply_print_config(const PrintConfig &print_config);
void set_extruders(const std::vector<unsigned int> &extruder_ids); void set_extruders(const std::vector<unsigned int> &extruder_ids);
std::string preamble(); std::string preamble();
std::string postamble(); std::string postamble() const;
std::string set_temperature(unsigned int temperature, bool wait = false, int tool = -1); std::string set_temperature(unsigned int temperature, bool wait = false, int tool = -1) const;
std::string set_bed_temperature(unsigned int temperature, bool wait = false); std::string set_bed_temperature(unsigned int temperature, bool wait = false) const;
std::string set_fan(unsigned int speed, bool dont_save = false); std::string set_fan(unsigned int speed, bool dont_save = false);
std::string set_acceleration(unsigned int acceleration); std::string set_acceleration(unsigned int acceleration);
std::string reset_e(bool force = false); std::string reset_e(bool force = false);
std::string update_progress(unsigned int num, unsigned int tot, bool allow_100 = false); std::string update_progress(unsigned int num, unsigned int tot, bool allow_100 = false) const;
bool need_toolchange(unsigned int extruder_id) const; bool need_toolchange(unsigned int extruder_id) const;
std::string set_extruder(unsigned int extruder_id); std::string set_extruder(unsigned int extruder_id);
std::string toolchange(unsigned int extruder_id); std::string toolchange(unsigned int extruder_id);
std::string set_speed(double F, const std::string &comment = std::string()); std::string set_speed(double F, const std::string &comment = std::string()) const;
std::string travel_to_xy(const Pointf &point, const std::string &comment = std::string()); std::string travel_to_xy(const Pointf &point, const std::string &comment = std::string());
std::string travel_to_xyz(const Pointf3 &point, const std::string &comment = std::string()); std::string travel_to_xyz(const Pointf3 &point, const std::string &comment = std::string());
std::string travel_to_z(double z, const std::string &comment = std::string()); std::string travel_to_z(double z, const std::string &comment = std::string());

View file

@ -8,16 +8,16 @@ namespace Slic3r {
Layer::Layer(size_t id, PrintObject *object, coordf_t height, coordf_t print_z, Layer::Layer(size_t id, PrintObject *object, coordf_t height, coordf_t print_z,
coordf_t slice_z) coordf_t slice_z)
: _id(id), : upper_layer(NULL),
_object(object),
upper_layer(NULL),
lower_layer(NULL), lower_layer(NULL),
regions(), regions(),
slicing_errors(false), slicing_errors(false),
slice_z(slice_z), slice_z(slice_z),
print_z(print_z), print_z(print_z),
height(height), height(height),
slices() slices(),
_id(id),
_object(object)
{ {
} }
@ -61,7 +61,7 @@ Layer::object() const
size_t size_t
Layer::region_count() Layer::region_count() const
{ {
return this->regions.size(); return this->regions.size();
} }

View file

@ -93,7 +93,7 @@ class Layer {
ExPolygonCollection slices; ExPolygonCollection slices;
size_t region_count(); size_t region_count() const;
LayerRegion* get_region(int idx); LayerRegion* get_region(int idx);
LayerRegion* add_region(PrintRegion* print_region); LayerRegion* add_region(PrintRegion* print_region);

View file

@ -162,12 +162,10 @@ Model::has_objects_with_no_instances() const
bool bool
Model::add_default_instances() Model::add_default_instances()
{ {
bool added = false;
// apply a default position to all objects not having one // apply a default position to all objects not having one
for (ModelObjectPtrs::const_iterator o = this->objects.begin(); o != this->objects.end(); ++o) { for (ModelObjectPtrs::const_iterator o = this->objects.begin(); o != this->objects.end(); ++o) {
if ((*o)->instances.empty()) { if ((*o)->instances.empty()) {
(*o)->add_instance(); (*o)->add_instance();
added = true;
} }
} }
return true; return true;
@ -248,7 +246,7 @@ REGISTER_CLASS(Model, "Model");
ModelMaterial::ModelMaterial(Model *model) : model(model) {} ModelMaterial::ModelMaterial(Model *model) : model(model) {}
ModelMaterial::ModelMaterial(Model *model, const ModelMaterial &other) ModelMaterial::ModelMaterial(Model *model, const ModelMaterial &other)
: model(model), config(other.config), attributes(other.attributes) : attributes(other.attributes), config(other.config), model(model)
{} {}
void void
@ -268,8 +266,7 @@ ModelObject::ModelObject(Model *model)
{} {}
ModelObject::ModelObject(Model *model, const ModelObject &other, bool copy_volumes) ModelObject::ModelObject(Model *model, const ModelObject &other, bool copy_volumes)
: model(model), : name(other.name),
name(other.name),
input_file(other.input_file), input_file(other.input_file),
instances(), instances(),
volumes(), volumes(),
@ -277,7 +274,8 @@ ModelObject::ModelObject(Model *model, const ModelObject &other, bool copy_volum
layer_height_ranges(other.layer_height_ranges), layer_height_ranges(other.layer_height_ranges),
origin_translation(other.origin_translation), origin_translation(other.origin_translation),
_bounding_box(other._bounding_box), _bounding_box(other._bounding_box),
_bounding_box_valid(other._bounding_box_valid) _bounding_box_valid(other._bounding_box_valid),
model(model)
{ {
if (copy_volumes) { if (copy_volumes) {
this->volumes.reserve(other.volumes.size()); this->volumes.reserve(other.volumes.size());
@ -531,10 +529,10 @@ ModelObject::rotate(float angle, const Axis &axis)
} }
void void
ModelObject::flip(const Axis &axis) ModelObject::mirror(const Axis &axis)
{ {
for (ModelVolumePtrs::const_iterator v = this->volumes.begin(); v != this->volumes.end(); ++v) { for (ModelVolumePtrs::const_iterator v = this->volumes.begin(); v != this->volumes.end(); ++v) {
(*v)->mesh.flip(axis); (*v)->mesh.mirror(axis);
} }
this->origin_translation = Pointf3(0,0,0); this->origin_translation = Pointf3(0,0,0);
this->invalidate_bounding_box(); this->invalidate_bounding_box();
@ -647,12 +645,12 @@ REGISTER_CLASS(ModelObject, "Model::Object");
ModelVolume::ModelVolume(ModelObject* object, const TriangleMesh &mesh) ModelVolume::ModelVolume(ModelObject* object, const TriangleMesh &mesh)
: object(object), mesh(mesh), modifier(false) : mesh(mesh), modifier(false), object(object)
{} {}
ModelVolume::ModelVolume(ModelObject* object, const ModelVolume &other) ModelVolume::ModelVolume(ModelObject* object, const ModelVolume &other)
: object(object), name(other.name), mesh(other.mesh), config(other.config), : name(other.name), mesh(other.mesh), config(other.config),
modifier(other.modifier) modifier(other.modifier), object(object)
{ {
this->material_id(other.material_id()); this->material_id(other.material_id());
} }
@ -701,11 +699,11 @@ REGISTER_CLASS(ModelVolume, "Model::Volume");
ModelInstance::ModelInstance(ModelObject *object) ModelInstance::ModelInstance(ModelObject *object)
: object(object), rotation(0), scaling_factor(1) : rotation(0), scaling_factor(1), object(object)
{} {}
ModelInstance::ModelInstance(ModelObject *object, const ModelInstance &other) ModelInstance::ModelInstance(ModelObject *object, const ModelInstance &other)
: object(object), rotation(other.rotation), scaling_factor(other.scaling_factor), offset(other.offset) : rotation(other.rotation), scaling_factor(other.scaling_factor), offset(other.offset), object(object)
{} {}
void void

View file

@ -130,7 +130,7 @@ class ModelObject
void translate(coordf_t x, coordf_t y, coordf_t z); void translate(coordf_t x, coordf_t y, coordf_t z);
void scale(const Pointf3 &versor); void scale(const Pointf3 &versor);
void rotate(float angle, const Axis &axis); void rotate(float angle, const Axis &axis);
void flip(const Axis &axis); void mirror(const Axis &axis);
size_t materials_count() const; size_t materials_count() const;
size_t facets_count() const; size_t facets_count() const;
bool needed_repair() const; bool needed_repair() const;

View file

@ -73,7 +73,7 @@ MotionPlanner::initialize()
} }
ExPolygonCollection ExPolygonCollection
MotionPlanner::get_env(size_t island_idx) const MotionPlanner::get_env(int island_idx) const
{ {
if (island_idx == -1) { if (island_idx == -1) {
return ExPolygonCollection(this->outer); return ExPolygonCollection(this->outer);
@ -127,13 +127,12 @@ MotionPlanner::shortest_path(const Point &from, const Point &to)
// Now check whether points are inside the environment. // Now check whether points are inside the environment.
Point inner_from = from; Point inner_from = from;
Point inner_to = to; Point inner_to = to;
bool from_is_inside, to_is_inside;
if (!env.contains(from)) {
if (!(from_is_inside = env.contains(from))) {
// Find the closest inner point to start from. // Find the closest inner point to start from.
inner_from = this->nearest_env_point(env, from, to); inner_from = this->nearest_env_point(env, from, to);
} }
if (!(to_is_inside = env.contains(to))) { if (!env.contains(to)) {
// Find the closest inner point to start from. // Find the closest inner point to start from.
inner_to = this->nearest_env_point(env, to, inner_from); inner_to = this->nearest_env_point(env, to, inner_from);
} }
@ -362,7 +361,7 @@ MotionPlannerGraph::shortest_path(size_t from, size_t to)
const std::vector<neighbor> &neighbors = this->adjacency_list[u]; const std::vector<neighbor> &neighbors = this->adjacency_list[u];
for (std::vector<neighbor>::const_iterator neighbor_iter = neighbors.begin(); for (std::vector<neighbor>::const_iterator neighbor_iter = neighbors.begin();
neighbor_iter != neighbors.end(); neighbor_iter != neighbors.end();
neighbor_iter++) ++neighbor_iter)
{ {
// neighbor node is v // neighbor node is v
node_t v = neighbor_iter->target; node_t v = neighbor_iter->target;

View file

@ -33,7 +33,7 @@ class MotionPlanner
void initialize(); void initialize();
MotionPlannerGraph* init_graph(int island_idx); MotionPlannerGraph* init_graph(int island_idx);
ExPolygonCollection get_env(size_t island_idx) const; ExPolygonCollection get_env(int island_idx) const;
Point nearest_env_point(const ExPolygonCollection &env, const Point &from, const Point &to) const; Point nearest_env_point(const ExPolygonCollection &env, const Point &from, const Point &to) const;
}; };
@ -42,7 +42,7 @@ class MotionPlannerGraph
friend class MotionPlanner; friend class MotionPlanner;
private: private:
typedef size_t node_t; typedef int node_t;
typedef double weight_t; typedef double weight_t;
struct neighbor { struct neighbor {
node_t target; node_t target;

View file

@ -22,7 +22,7 @@ class PerimeterGeneratorLoop {
std::vector<PerimeterGeneratorLoop> children; std::vector<PerimeterGeneratorLoop> children;
PerimeterGeneratorLoop(Polygon polygon, unsigned short depth) PerimeterGeneratorLoop(Polygon polygon, unsigned short depth)
: polygon(polygon), depth(depth), is_contour(false) : polygon(polygon), is_contour(false), depth(depth)
{}; {};
bool is_external() const; bool is_external() const;
bool is_internal_contour() const; bool is_internal_contour() const;
@ -50,8 +50,8 @@ class PerimeterGenerator {
PrintConfig* print_config, ExtrusionEntityCollection* loops, PrintConfig* print_config, ExtrusionEntityCollection* loops,
ExtrusionEntityCollection* gap_fill, SurfaceCollection* fill_surfaces) ExtrusionEntityCollection* gap_fill, SurfaceCollection* fill_surfaces)
: slices(slices), lower_slices(NULL), layer_height(layer_height), : slices(slices), lower_slices(NULL), layer_height(layer_height),
perimeter_flow(flow), ext_perimeter_flow(flow), overhang_flow(flow), layer_id(-1), perimeter_flow(flow), ext_perimeter_flow(flow),
solid_infill_flow(flow), layer_id(-1), overhang_flow(flow), solid_infill_flow(flow),
config(config), object_config(object_config), print_config(print_config), config(config), object_config(object_config), print_config(print_config),
loops(loops), gap_fill(gap_fill), fill_surfaces(fill_surfaces), loops(loops), gap_fill(gap_fill), fill_surfaces(fill_surfaces),
_ext_mm3_per_mm(-1), _mm3_per_mm(-1), _mm3_per_mm_overhang(-1) _ext_mm3_per_mm(-1), _mm3_per_mm(-1), _mm3_per_mm_overhang(-1)

View file

@ -119,7 +119,7 @@ Polyline::equally_spaced_points(double distance) const
double take = segment_length - (len - distance); // how much we take of this segment double take = segment_length - (len - distance); // how much we take of this segment
Line segment(*(it-1), *it); Line segment(*(it-1), *it);
points.push_back(segment.point_at(take)); points.push_back(segment.point_at(take));
it--; --it;
len = -take; len = -take;
} }
return points; return points;

View file

@ -335,6 +335,7 @@ PrintConfigDef::build_def() {
Options["first_layer_extrusion_width"].type = coFloatOrPercent; Options["first_layer_extrusion_width"].type = coFloatOrPercent;
Options["first_layer_extrusion_width"].label = "First layer"; Options["first_layer_extrusion_width"].label = "First layer";
Options["first_layer_extrusion_width"].category = "Extrusion Width";
Options["first_layer_extrusion_width"].tooltip = "Set this to a non-zero value to set a manual extrusion width for first layer. You can use this to force fatter extrudates for better adhesion. If expressed as percentage (for example 120%) it will be computed over first layer height. If set to zero, it will use the Default Extrusion Width."; Options["first_layer_extrusion_width"].tooltip = "Set this to a non-zero value to set a manual extrusion width for first layer. You can use this to force fatter extrudates for better adhesion. If expressed as percentage (for example 120%) it will be computed over first layer height. If set to zero, it will use the Default Extrusion Width.";
Options["first_layer_extrusion_width"].sidetext = "mm or % (leave 0 for default)"; Options["first_layer_extrusion_width"].sidetext = "mm or % (leave 0 for default)";
Options["first_layer_extrusion_width"].cli = "first-layer-extrusion-width=s"; Options["first_layer_extrusion_width"].cli = "first-layer-extrusion-width=s";

View file

@ -150,7 +150,7 @@ class PrintObjectConfig : public virtual StaticPrintConfig
this->xy_size_compensation.value = 0; this->xy_size_compensation.value = 0;
}; };
ConfigOption* option(const t_config_option_key opt_key, bool create = false) { ConfigOption* option(const t_config_option_key &opt_key, bool create = false) {
OPT_PTR(dont_support_bridges); OPT_PTR(dont_support_bridges);
OPT_PTR(extrusion_width); OPT_PTR(extrusion_width);
OPT_PTR(first_layer_height); OPT_PTR(first_layer_height);
@ -260,7 +260,7 @@ class PrintRegionConfig : public virtual StaticPrintConfig
this->top_solid_layers.value = 3; this->top_solid_layers.value = 3;
}; };
ConfigOption* option(const t_config_option_key opt_key, bool create = false) { ConfigOption* option(const t_config_option_key &opt_key, bool create = false) {
OPT_PTR(bottom_solid_layers); OPT_PTR(bottom_solid_layers);
OPT_PTR(bridge_flow_ratio); OPT_PTR(bridge_flow_ratio);
OPT_PTR(bridge_speed); OPT_PTR(bridge_speed);
@ -359,7 +359,7 @@ class GCodeConfig : public virtual StaticPrintConfig
this->use_volumetric_e.value = false; this->use_volumetric_e.value = false;
}; };
ConfigOption* option(const t_config_option_key opt_key, bool create = false) { ConfigOption* option(const t_config_option_key &opt_key, bool create = false) {
OPT_PTR(before_layer_gcode); OPT_PTR(before_layer_gcode);
OPT_PTR(end_gcode); OPT_PTR(end_gcode);
OPT_PTR(extrusion_axis); OPT_PTR(extrusion_axis);
@ -518,7 +518,7 @@ class PrintConfig : public GCodeConfig
this->z_offset.value = 0; this->z_offset.value = 0;
}; };
ConfigOption* option(const t_config_option_key opt_key, bool create = false) { ConfigOption* option(const t_config_option_key &opt_key, bool create = false) {
OPT_PTR(avoid_crossing_perimeters); OPT_PTR(avoid_crossing_perimeters);
OPT_PTR(bed_shape); OPT_PTR(bed_shape);
OPT_PTR(bed_temperature); OPT_PTR(bed_temperature);
@ -593,7 +593,7 @@ class HostConfig : public virtual StaticPrintConfig
this->serial_speed.value = 250000; this->serial_speed.value = 250000;
}; };
ConfigOption* option(const t_config_option_key opt_key, bool create = false) { ConfigOption* option(const t_config_option_key &opt_key, bool create = false) {
OPT_PTR(octoprint_host); OPT_PTR(octoprint_host);
OPT_PTR(octoprint_apikey); OPT_PTR(octoprint_apikey);
OPT_PTR(serial_port); OPT_PTR(serial_port);
@ -607,7 +607,7 @@ class FullPrintConfig
: public PrintObjectConfig, public PrintRegionConfig, public PrintConfig, public HostConfig : public PrintObjectConfig, public PrintRegionConfig, public PrintConfig, public HostConfig
{ {
public: public:
ConfigOption* option(const t_config_option_key opt_key, bool create = false) { ConfigOption* option(const t_config_option_key &opt_key, bool create = false) {
ConfigOption* opt; ConfigOption* opt;
if ((opt = PrintObjectConfig::option(opt_key, create)) != NULL) return opt; if ((opt = PrintObjectConfig::option(opt_key, create)) != NULL) return opt;
if ((opt = PrintRegionConfig::option(opt_key, create)) != NULL) return opt; if ((opt = PrintRegionConfig::option(opt_key, create)) != NULL) return opt;

View file

@ -6,9 +6,9 @@
namespace Slic3r { namespace Slic3r {
PrintObject::PrintObject(Print* print, ModelObject* model_object, const BoundingBoxf3 &modobj_bbox) PrintObject::PrintObject(Print* print, ModelObject* model_object, const BoundingBoxf3 &modobj_bbox)
: _print(print), : typed_slices(false),
_model_object(model_object), _print(print),
typed_slices(false) _model_object(model_object)
{ {
// Compute the translation to be applied to our meshes so that we work with smaller coordinates // Compute the translation to be applied to our meshes so that we work with smaller coordinates
{ {

View file

@ -50,7 +50,7 @@ PrintRegion::flow(FlowRole role, double layer_height, bool bridge, bool first_la
// get the configured nozzle_diameter for the extruder associated // get the configured nozzle_diameter for the extruder associated
// to the flow role requested // to the flow role requested
size_t extruder; // 1-based size_t extruder = 0; // 1-based
if (role == frPerimeter || role == frExternalPerimeter) { if (role == frPerimeter || role == frExternalPerimeter) {
extruder = this->config.perimeter_extruder; extruder = this->config.perimeter_extruder;
} else if (role == frInfill) { } else if (role == frInfill) {

View file

@ -6,7 +6,7 @@
namespace Slic3r { namespace Slic3r {
SVG::SVG(const char* filename) SVG::SVG(const char* filename)
: arrows(true), filename(filename), fill("grey"), stroke("black") : arrows(true), fill("grey"), stroke("black"), filename(filename)
{ {
this->f = fopen(filename, "w"); this->f = fopen(filename, "w");
fprintf(this->f, fprintf(this->f,

View file

@ -100,7 +100,7 @@ TriangleMesh::repair() {
stl.stats.facets_w_3_bad_edge = (stl.stats.number_of_facets - stl.stats.connected_facets_1_edge); stl.stats.facets_w_3_bad_edge = (stl.stats.number_of_facets - stl.stats.connected_facets_1_edge);
// checking nearby // checking nearby
int last_edges_fixed = 0; //int last_edges_fixed = 0;
float tolerance = stl.stats.shortest_edge; float tolerance = stl.stats.shortest_edge;
float increment = stl.stats.bounding_diameter / 10000.0; float increment = stl.stats.bounding_diameter / 10000.0;
int iterations = 2; int iterations = 2;
@ -110,7 +110,7 @@ TriangleMesh::repair() {
//printf("Checking nearby. Tolerance= %f Iteration=%d of %d...", tolerance, i + 1, iterations); //printf("Checking nearby. Tolerance= %f Iteration=%d of %d...", tolerance, i + 1, iterations);
stl_check_facets_nearby(&stl, tolerance); stl_check_facets_nearby(&stl, tolerance);
//printf(" Fixed %d edges.\n", stl.stats.edges_fixed - last_edges_fixed); //printf(" Fixed %d edges.\n", stl.stats.edges_fixed - last_edges_fixed);
last_edges_fixed = stl.stats.edges_fixed; //last_edges_fixed = stl.stats.edges_fixed;
tolerance += increment; tolerance += increment;
} else { } else {
break; break;
@ -230,7 +230,7 @@ void TriangleMesh::rotate_z(float angle)
this->rotate(angle, Z); this->rotate(angle, Z);
} }
void TriangleMesh::flip(const Axis &axis) void TriangleMesh::mirror(const Axis &axis)
{ {
if (axis == X) { if (axis == X) {
stl_mirror_yz(&this->stl); stl_mirror_yz(&this->stl);
@ -242,19 +242,19 @@ void TriangleMesh::flip(const Axis &axis)
stl_invalidate_shared_vertices(&this->stl); stl_invalidate_shared_vertices(&this->stl);
} }
void TriangleMesh::flip_x() void TriangleMesh::mirror_x()
{ {
this->flip(X); this->mirror(X);
} }
void TriangleMesh::flip_y() void TriangleMesh::mirror_y()
{ {
this->flip(Y); this->mirror(Y);
} }
void TriangleMesh::flip_z() void TriangleMesh::mirror_z()
{ {
this->flip(Z); this->mirror(Z);
} }
void TriangleMesh::align_to_origin() void TriangleMesh::align_to_origin()
@ -316,7 +316,7 @@ TriangleMesh::split() const
stl_allocate(&mesh->stl); stl_allocate(&mesh->stl);
int first = 1; int first = 1;
for (std::deque<int>::const_iterator facet = facets.begin(); facet != facets.end(); facet++) { for (std::deque<int>::const_iterator facet = facets.begin(); facet != facets.end(); ++facet) {
mesh->stl.facet_start[facet - facets.begin()] = this->stl.facet_start[*facet]; mesh->stl.facet_start[facet - facets.begin()] = this->stl.facet_start[*facet];
stl_facet_stats(&mesh->stl, this->stl.facet_start[*facet], first); stl_facet_stats(&mesh->stl, this->stl.facet_start[*facet], first);
first = 0; first = 0;
@ -429,7 +429,7 @@ void TriangleMesh::ReadFromPerl(SV* vertices, SV* facets)
// read geometry // read geometry
AV* vertices_av = (AV*)SvRV(vertices); AV* vertices_av = (AV*)SvRV(vertices);
for (unsigned int i = 0; i < stl.stats.number_of_facets; i++) { for (int i = 0; i < stl.stats.number_of_facets; i++) {
AV* facet_av = (AV*)SvRV(*av_fetch(facets_av, i, 0)); AV* facet_av = (AV*)SvRV(*av_fetch(facets_av, i, 0));
stl_facet facet; stl_facet facet;
facet.normal.x = 0; facet.normal.x = 0;

View file

@ -36,10 +36,10 @@ class TriangleMesh
void rotate_x(float angle); void rotate_x(float angle);
void rotate_y(float angle); void rotate_y(float angle);
void rotate_z(float angle); void rotate_z(float angle);
void flip(const Axis &axis); void mirror(const Axis &axis);
void flip_x(); void mirror_x();
void flip_y(); void mirror_y();
void flip_z(); void mirror_z();
void align_to_origin(); void align_to_origin();
void rotate(double angle, Point* center); void rotate(double angle, Point* center);
TriangleMeshPtrs split() const; TriangleMeshPtrs split() const;

View file

@ -150,7 +150,7 @@ void Triangle::Legalize(Point& opoint, Point& npoint)
} }
} }
int Triangle::Index(const Point* p) int Triangle::Index(const Point* p) const
{ {
if (p == points_[0]) { if (p == points_[0]) {
return 0; return 0;
@ -163,7 +163,7 @@ int Triangle::Index(const Point* p)
return -1; return -1;
} }
int Triangle::EdgeIndex(const Point* p1, const Point* p2) int Triangle::EdgeIndex(const Point* p1, const Point* p2) const
{ {
if (points_[0] == p1) { if (points_[0] == p1) {
if (points_[1] == p2) { if (points_[1] == p2) {
@ -259,7 +259,7 @@ Triangle* Triangle::NeighborCCW(const Point& point)
return neighbors_[1]; return neighbors_[1];
} }
bool Triangle::GetConstrainedEdgeCCW(const Point& p) bool Triangle::GetConstrainedEdgeCCW(const Point& p) const
{ {
if (&p == points_[0]) { if (&p == points_[0]) {
return constrained_edge[2]; return constrained_edge[2];
@ -269,7 +269,7 @@ bool Triangle::GetConstrainedEdgeCCW(const Point& p)
return constrained_edge[1]; return constrained_edge[1];
} }
bool Triangle::GetConstrainedEdgeCW(const Point& p) bool Triangle::GetConstrainedEdgeCW(const Point& p) const
{ {
if (&p == points_[0]) { if (&p == points_[0]) {
return constrained_edge[1]; return constrained_edge[1];
@ -301,7 +301,7 @@ void Triangle::SetConstrainedEdgeCW(const Point& p, bool ce)
} }
} }
bool Triangle::GetDelunayEdgeCCW(const Point& p) bool Triangle::GetDelunayEdgeCCW(const Point& p) const
{ {
if (&p == points_[0]) { if (&p == points_[0]) {
return delaunay_edge[2]; return delaunay_edge[2];
@ -311,7 +311,7 @@ bool Triangle::GetDelunayEdgeCCW(const Point& p)
return delaunay_edge[1]; return delaunay_edge[1];
} }
bool Triangle::GetDelunayEdgeCW(const Point& p) bool Triangle::GetDelunayEdgeCW(const Point& p) const
{ {
if (&p == points_[0]) { if (&p == points_[0]) {
return delaunay_edge[1]; return delaunay_edge[1];

View file

@ -171,23 +171,23 @@ void MarkConstrainedEdge(int index);
void MarkConstrainedEdge(Edge& edge); void MarkConstrainedEdge(Edge& edge);
void MarkConstrainedEdge(Point* p, Point* q); void MarkConstrainedEdge(Point* p, Point* q);
int Index(const Point* p); int Index(const Point* p) const;
int EdgeIndex(const Point* p1, const Point* p2); int EdgeIndex(const Point* p1, const Point* p2) const;
Triangle* NeighborCW(const Point& point); Triangle* NeighborCW(const Point& point);
Triangle* NeighborCCW(const Point& point); Triangle* NeighborCCW(const Point& point);
bool GetConstrainedEdgeCCW(const Point& p); bool GetConstrainedEdgeCCW(const Point& p) const;
bool GetConstrainedEdgeCW(const Point& p); bool GetConstrainedEdgeCW(const Point& p) const;
void SetConstrainedEdgeCCW(const Point& p, bool ce); void SetConstrainedEdgeCCW(const Point& p, bool ce);
void SetConstrainedEdgeCW(const Point& p, bool ce); void SetConstrainedEdgeCW(const Point& p, bool ce);
bool GetDelunayEdgeCCW(const Point& p); bool GetDelunayEdgeCCW(const Point& p) const;
bool GetDelunayEdgeCW(const Point& p); bool GetDelunayEdgeCW(const Point& p) const;
void SetDelunayEdgeCCW(const Point& p, bool e); void SetDelunayEdgeCCW(const Point& p, bool e);
void SetDelunayEdgeCW(const Point& p, bool e); void SetDelunayEdgeCW(const Point& p, bool e);
bool Contains(const Point* p); bool Contains(const Point* p) const;
bool Contains(const Edge& e); bool Contains(const Edge& e) const;
bool Contains(const Point* p, const Point* q); bool Contains(const Point* p, const Point* q) const;
void Legalize(Point& point); void Legalize(Point& point);
void Legalize(Point& opoint, Point& npoint); void Legalize(Point& opoint, Point& npoint);
/** /**
@ -198,7 +198,7 @@ void ClearNeighbor(const Triangle *triangle);
void ClearNeighbors(); void ClearNeighbors();
void ClearDelunayEdges(); void ClearDelunayEdges();
inline bool IsInterior(); inline bool IsInterior() const;
inline void IsInterior(bool b); inline void IsInterior(bool b);
Triangle& NeighborAcross(const Point& opoint); Triangle& NeighborAcross(const Point& opoint);
@ -293,22 +293,22 @@ inline Triangle* Triangle::GetNeighbor(int index)
return neighbors_[index]; return neighbors_[index];
} }
inline bool Triangle::Contains(const Point* p) inline bool Triangle::Contains(const Point* p) const
{ {
return p == points_[0] || p == points_[1] || p == points_[2]; return p == points_[0] || p == points_[1] || p == points_[2];
} }
inline bool Triangle::Contains(const Edge& e) inline bool Triangle::Contains(const Edge& e) const
{ {
return Contains(e.p) && Contains(e.q); return Contains(e.p) && Contains(e.q);
} }
inline bool Triangle::Contains(const Point* p, const Point* q) inline bool Triangle::Contains(const Point* p, const Point* q) const
{ {
return Contains(p) && Contains(q); return Contains(p) && Contains(q);
} }
inline bool Triangle::IsInterior() inline bool Triangle::IsInterior() const
{ {
return interior_; return interior_;
} }

View file

@ -74,15 +74,17 @@ TPPLPoly::TPPLPoly(const TPPLPoly &src) {
} }
TPPLPoly& TPPLPoly::operator=(const TPPLPoly &src) { TPPLPoly& TPPLPoly::operator=(const TPPLPoly &src) {
Clear(); if(&src != this) {
hole = src.hole; Clear();
numpoints = src.numpoints; hole = src.hole;
points = new TPPLPoint[numpoints]; numpoints = src.numpoints;
memcpy(points, src.points, numpoints*sizeof(TPPLPoint)); points = new TPPLPoint[numpoints];
memcpy(points, src.points, numpoints*sizeof(TPPLPoint));
}
return *this; return *this;
} }
int TPPLPoly::GetOrientation() { int TPPLPoly::GetOrientation() const {
long i1,i2; long i1,i2;
tppl_float area = 0; tppl_float area = 0;
for(i1=0; i1<numpoints; i1++) { for(i1=0; i1<numpoints; i1++) {
@ -170,7 +172,7 @@ int TPPLPartition::Intersects(TPPLPoint &p11, TPPLPoint &p12, TPPLPoint &p21, TP
int TPPLPartition::RemoveHoles(list<TPPLPoly> *inpolys, list<TPPLPoly> *outpolys) { int TPPLPartition::RemoveHoles(list<TPPLPoly> *inpolys, list<TPPLPoly> *outpolys) {
list<TPPLPoly> polys; list<TPPLPoly> polys;
list<TPPLPoly>::iterator holeiter,polyiter,iter,iter2; list<TPPLPoly>::iterator holeiter,polyiter,iter,iter2;
long i,i2,holepointindex,polypointindex; long i,i2,holepointindex,polypointindex = 0;
TPPLPoint holepoint,polypoint,bestpolypoint; TPPLPoint holepoint,polypoint,bestpolypoint;
TPPLPoint linep1,linep2; TPPLPoint linep1,linep2;
TPPLPoint v1,v2; TPPLPoint v1,v2;
@ -181,14 +183,14 @@ int TPPLPartition::RemoveHoles(list<TPPLPoly> *inpolys, list<TPPLPoly> *outpolys
//check for trivial case (no holes) //check for trivial case (no holes)
hasholes = false; hasholes = false;
for(iter = inpolys->begin(); iter!=inpolys->end(); iter++) { for(iter = inpolys->begin(); iter!=inpolys->end(); ++iter) {
if(iter->IsHole()) { if(iter->IsHole()) {
hasholes = true; hasholes = true;
break; break;
} }
} }
if(!hasholes) { if(!hasholes) {
for(iter = inpolys->begin(); iter!=inpolys->end(); iter++) { for(iter = inpolys->begin(); iter!=inpolys->end(); ++iter) {
outpolys->push_back(*iter); outpolys->push_back(*iter);
} }
return 1; return 1;
@ -199,7 +201,7 @@ int TPPLPartition::RemoveHoles(list<TPPLPoly> *inpolys, list<TPPLPoly> *outpolys
while(1) { while(1) {
//find the hole point with the largest x //find the hole point with the largest x
hasholes = false; hasholes = false;
for(iter = polys.begin(); iter!=polys.end(); iter++) { for(iter = polys.begin(); iter!=polys.end(); ++iter) {
if(!iter->IsHole()) continue; if(!iter->IsHole()) continue;
if(!hasholes) { if(!hasholes) {
@ -219,7 +221,7 @@ int TPPLPartition::RemoveHoles(list<TPPLPoly> *inpolys, list<TPPLPoly> *outpolys
holepoint = holeiter->GetPoint(holepointindex); holepoint = holeiter->GetPoint(holepointindex);
pointfound = false; pointfound = false;
for(iter = polys.begin(); iter!=polys.end(); iter++) { for(iter = polys.begin(); iter!=polys.end(); ++iter) {
if(iter->IsHole()) continue; if(iter->IsHole()) continue;
for(i=0; i < iter->GetNumPoints(); i++) { for(i=0; i < iter->GetNumPoints(); i++) {
if(iter->GetPoint(i).x <= holepoint.x) continue; if(iter->GetPoint(i).x <= holepoint.x) continue;
@ -235,7 +237,7 @@ int TPPLPartition::RemoveHoles(list<TPPLPoly> *inpolys, list<TPPLPoly> *outpolys
if(v2.x > v1.x) continue; if(v2.x > v1.x) continue;
} }
pointvisible = true; pointvisible = true;
for(iter2 = polys.begin(); iter2!=polys.end(); iter2++) { for(iter2 = polys.begin(); iter2!=polys.end(); ++iter2) {
if(iter2->IsHole()) continue; if(iter2->IsHole()) continue;
for(i2=0; i2 < iter2->GetNumPoints(); i2++) { for(i2=0; i2 < iter2->GetNumPoints(); i2++) {
linep1 = iter2->GetPoint(i2); linep1 = iter2->GetPoint(i2);
@ -278,7 +280,7 @@ int TPPLPartition::RemoveHoles(list<TPPLPoly> *inpolys, list<TPPLPoly> *outpolys
polys.push_back(newpoly); polys.push_back(newpoly);
} }
for(iter = polys.begin(); iter!=polys.end(); iter++) { for(iter = polys.begin(); iter!=polys.end(); ++iter) {
outpolys->push_back(*iter); outpolys->push_back(*iter);
} }
@ -449,7 +451,7 @@ int TPPLPartition::Triangulate_EC(list<TPPLPoly> *inpolys, list<TPPLPoly> *trian
list<TPPLPoly>::iterator iter; list<TPPLPoly>::iterator iter;
if(!RemoveHoles(inpolys,&outpolys)) return 0; if(!RemoveHoles(inpolys,&outpolys)) return 0;
for(iter=outpolys.begin();iter!=outpolys.end();iter++) { for(iter=outpolys.begin();iter!=outpolys.end();++iter) {
if(!Triangulate_EC(&(*iter),triangles)) return 0; if(!Triangulate_EC(&(*iter),triangles)) return 0;
} }
return 1; return 1;
@ -484,7 +486,7 @@ int TPPLPartition::ConvexPartition_HM(TPPLPoly *poly, list<TPPLPoly> *parts) {
if(!Triangulate_EC(poly,&triangles)) return 0; if(!Triangulate_EC(poly,&triangles)) return 0;
for(iter1 = triangles.begin(); iter1 != triangles.end(); iter1++) { for(iter1 = triangles.begin(); iter1 != triangles.end(); ++iter1) {
poly1 = &(*iter1); poly1 = &(*iter1);
for(i11=0;i11<poly1->GetNumPoints();i11++) { for(i11=0;i11<poly1->GetNumPoints();i11++) {
d1 = poly1->GetPoint(i11); d1 = poly1->GetPoint(i11);
@ -492,7 +494,7 @@ int TPPLPartition::ConvexPartition_HM(TPPLPoly *poly, list<TPPLPoly> *parts) {
d2 = poly1->GetPoint(i12); d2 = poly1->GetPoint(i12);
isdiagonal = false; isdiagonal = false;
for(iter2 = iter1; iter2 != triangles.end(); iter2++) { for(iter2 = iter1; iter2 != triangles.end(); ++iter2) {
if(iter1 == iter2) continue; if(iter1 == iter2) continue;
poly2 = &(*iter2); poly2 = &(*iter2);
@ -548,7 +550,7 @@ int TPPLPartition::ConvexPartition_HM(TPPLPoly *poly, list<TPPLPoly> *parts) {
} }
} }
for(iter1 = triangles.begin(); iter1 != triangles.end(); iter1++) { for(iter1 = triangles.begin(); iter1 != triangles.end(); ++iter1) {
parts->push_back(*iter1); parts->push_back(*iter1);
} }
@ -560,7 +562,7 @@ int TPPLPartition::ConvexPartition_HM(list<TPPLPoly> *inpolys, list<TPPLPoly> *p
list<TPPLPoly>::iterator iter; list<TPPLPoly>::iterator iter;
if(!RemoveHoles(inpolys,&outpolys)) return 0; if(!RemoveHoles(inpolys,&outpolys)) return 0;
for(iter=outpolys.begin();iter!=outpolys.end();iter++) { for(iter=outpolys.begin();iter!=outpolys.end();++iter) {
if(!ConvexPartition_HM(&(*iter),parts)) return 0; if(!ConvexPartition_HM(&(*iter),parts)) return 0;
} }
return 1; return 1;
@ -740,7 +742,7 @@ void TPPLPartition::TypeA(long i, long j, long k, PartitionVertex *vertices, DPS
iter = pairs->end(); iter = pairs->end();
lastiter = pairs->end(); lastiter = pairs->end();
while(iter!=pairs->begin()) { while(iter!=pairs->begin()) {
iter--; --iter;
if(!IsReflex(vertices[iter->index2].p,vertices[j].p,vertices[k].p)) lastiter = iter; if(!IsReflex(vertices[iter->index2].p,vertices[j].p,vertices[k].p)) lastiter = iter;
else break; else break;
} }
@ -776,7 +778,7 @@ void TPPLPartition::TypeB(long i, long j, long k, PartitionVertex *vertices, DPS
while(iter!=pairs->end()) { while(iter!=pairs->end()) {
if(!IsReflex(vertices[i].p,vertices[j].p,vertices[iter->index1].p)) { if(!IsReflex(vertices[i].p,vertices[j].p,vertices[iter->index1].p)) {
lastiter = iter; lastiter = iter;
iter++; ++iter;
} }
else break; else break;
} }
@ -917,7 +919,7 @@ int TPPLPartition::ConvexPartition_OPT(TPPLPoly *poly, list<TPPLPoly> *parts) {
} }
if(!vertices[diagonal.index1].isConvex) { if(!vertices[diagonal.index1].isConvex) {
iter = pairs->end(); iter = pairs->end();
iter--; --iter;
j = iter->index2; j = iter->index2;
newdiagonal.index1 = j; newdiagonal.index1 = j;
newdiagonal.index2 = diagonal.index2; newdiagonal.index2 = diagonal.index2;
@ -931,7 +933,7 @@ int TPPLPartition::ConvexPartition_OPT(TPPLPoly *poly, list<TPPLPoly> *parts) {
break; break;
} }
iter2 = pairs2->end(); iter2 = pairs2->end();
iter2--; --iter2;
if(iter->index1 != iter2->index1) pairs2->pop_back(); if(iter->index1 != iter2->index1) pairs2->pop_back();
else break; else break;
} }
@ -1001,7 +1003,7 @@ int TPPLPartition::ConvexPartition_OPT(TPPLPoly *poly, list<TPPLPoly> *parts) {
pairs = &(dpstates[diagonal.index1][diagonal.index2].pairs); pairs = &(dpstates[diagonal.index1][diagonal.index2].pairs);
if(!vertices[diagonal.index1].isConvex) { if(!vertices[diagonal.index1].isConvex) {
iter = pairs->end(); iter = pairs->end();
iter--; --iter;
j = iter->index2; j = iter->index2;
if(iter->index1 != iter->index2) ijreal = false; if(iter->index1 != iter->index2) ijreal = false;
} else { } else {
@ -1032,7 +1034,7 @@ int TPPLPartition::ConvexPartition_OPT(TPPLPoly *poly, list<TPPLPoly> *parts) {
indices.sort(); indices.sort();
newpoly.Init((long)indices.size()); newpoly.Init((long)indices.size());
k=0; k=0;
for(iiter = indices.begin();iiter!=indices.end();iiter++) { for(iiter = indices.begin();iiter!=indices.end(); ++iiter) {
newpoly[k] = vertices[*iiter].p; newpoly[k] = vertices[*iiter].p;
k++; k++;
} }
@ -1064,7 +1066,7 @@ int TPPLPartition::MonotonePartition(list<TPPLPoly> *inpolys, list<TPPLPoly> *mo
bool error = false; bool error = false;
numvertices = 0; numvertices = 0;
for(iter = inpolys->begin(); iter != inpolys->end(); iter++) { for(iter = inpolys->begin(); iter != inpolys->end(); ++iter) {
numvertices += iter->GetNumPoints(); numvertices += iter->GetNumPoints();
} }
@ -1073,7 +1075,7 @@ int TPPLPartition::MonotonePartition(list<TPPLPoly> *inpolys, list<TPPLPoly> *mo
newnumvertices = numvertices; newnumvertices = numvertices;
polystartindex = 0; polystartindex = 0;
for(iter = inpolys->begin(); iter != inpolys->end(); iter++) { for(iter = inpolys->begin(); iter != inpolys->end(); ++iter) {
poly = &(*iter); poly = &(*iter);
polyendindex = polystartindex + poly->GetNumPoints()-1; polyendindex = polystartindex + poly->GetNumPoints()-1;
for(i=0;i<poly->GetNumPoints();i++) { for(i=0;i<poly->GetNumPoints();i++) {
@ -1174,7 +1176,7 @@ int TPPLPartition::MonotonePartition(list<TPPLPoly> *inpolys, list<TPPLPoly> *mo
error = true; error = true;
break; break;
} }
edgeIter--; --edgeIter;
//Insert the diagonal connecting vi to helper(ej) in D. //Insert the diagonal connecting vi to helper(ej) in D.
AddDiagonal(vertices,&newnumvertices,vindex,helpers[edgeIter->index]); AddDiagonal(vertices,&newnumvertices,vindex,helpers[edgeIter->index]);
vertextypes[newnumvertices-2] = vertextypes[vindex]; vertextypes[newnumvertices-2] = vertextypes[vindex];
@ -1220,7 +1222,7 @@ int TPPLPartition::MonotonePartition(list<TPPLPoly> *inpolys, list<TPPLPoly> *mo
error = true; error = true;
break; break;
} }
edgeIter--; --edgeIter;
//if helper(ej) is a merge vertex //if helper(ej) is a merge vertex
if(vertextypes[helpers[edgeIter->index]]==TPPL_VERTEXTYPE_MERGE) { if(vertextypes[helpers[edgeIter->index]]==TPPL_VERTEXTYPE_MERGE) {
//Insert the diagonal connecting vi to helper(e j) in D. //Insert the diagonal connecting vi to helper(e j) in D.
@ -1270,7 +1272,7 @@ int TPPLPartition::MonotonePartition(list<TPPLPoly> *inpolys, list<TPPLPoly> *mo
error = true; error = true;
break; break;
} }
edgeIter--; --edgeIter;
//if helper(ej) is a merge vertex //if helper(ej) is a merge vertex
if(vertextypes[helpers[edgeIter->index]]==TPPL_VERTEXTYPE_MERGE) { if(vertextypes[helpers[edgeIter->index]]==TPPL_VERTEXTYPE_MERGE) {
//Insert the diagonal connecting vi to helper(e j) in D. //Insert the diagonal connecting vi to helper(e j) in D.
@ -1373,7 +1375,7 @@ bool TPPLPartition::Below(TPPLPoint &p1, TPPLPoint &p2) {
} }
//sorts in the falling order of y values, if y is equal, x is used instead //sorts in the falling order of y values, if y is equal, x is used instead
bool TPPLPartition::VertexSorter::operator() (long index1, long index2) { bool TPPLPartition::VertexSorter::operator() (long index1, long index2) const {
if(vertices[index1].p.y > vertices[index2].p.y) return true; if(vertices[index1].p.y > vertices[index2].p.y) return true;
else if(vertices[index1].p.y == vertices[index2].p.y) { else if(vertices[index1].p.y == vertices[index2].p.y) {
if(vertices[index1].p.x > vertices[index2].p.x) return true; if(vertices[index1].p.x > vertices[index2].p.x) return true;
@ -1547,7 +1549,7 @@ int TPPLPartition::Triangulate_MONO(list<TPPLPoly> *inpolys, list<TPPLPoly> *tri
list<TPPLPoly>::iterator iter; list<TPPLPoly>::iterator iter;
if(!MonotonePartition(inpolys,&monotone)) return 0; if(!MonotonePartition(inpolys,&monotone)) return 0;
for(iter = monotone.begin(); iter!=monotone.end();iter++) { for(iter = monotone.begin(); iter!=monotone.end(); ++iter) {
if(!TriangulateMonotone(&(*iter),triangles)) return 0; if(!TriangulateMonotone(&(*iter),triangles)) return 0;
} }
return 1; return 1;

View file

@ -89,11 +89,11 @@ public:
TPPLPoly& operator=(const TPPLPoly &src); TPPLPoly& operator=(const TPPLPoly &src);
//getters and setters //getters and setters
long GetNumPoints() { long GetNumPoints() const {
return numpoints; return numpoints;
} }
bool IsHole() { bool IsHole() const {
return hole; return hole;
} }
@ -130,7 +130,7 @@ public:
// TPPL_CCW : polygon vertices are in counter-clockwise order // TPPL_CCW : polygon vertices are in counter-clockwise order
// TPPL_CW : polygon vertices are in clockwise order // TPPL_CW : polygon vertices are in clockwise order
// 0 : the polygon has no (measurable) area // 0 : the polygon has no (measurable) area
int GetOrientation(); int GetOrientation() const;
//sets the polygon orientation //sets the polygon orientation
//orientation can be //orientation can be
@ -162,7 +162,7 @@ protected:
MonotoneVertex *vertices; MonotoneVertex *vertices;
public: public:
VertexSorter(MonotoneVertex *v) : vertices(v) {} VertexSorter(MonotoneVertex *v) : vertices(v) {}
bool operator() (long index1, long index2); bool operator() (long index1, long index2) const;
}; };
struct Diagonal { struct Diagonal {

View file

@ -100,7 +100,7 @@ my $cube = {
my $slices = $m->slice([ 5, 10 ]); my $slices = $m->slice([ 5, 10 ]);
is $slices->[0][0]->area, $slices->[1][0]->area, 'slicing a top tangent plane includes its area'; is $slices->[0][0]->area, $slices->[1][0]->area, 'slicing a top tangent plane includes its area';
} }
$m->flip_z; $m->mirror_z;
{ {
# this second test also checks that performing a second slice on a mesh after # this second test also checks that performing a second slice on a mesh after
# a transformation works properly (shared_vertices is correctly invalidated); # a transformation works properly (shared_vertices is correctly invalidated);

View file

@ -6,7 +6,7 @@
%} %}
%name{Slic3r::Extruder} class Extruder { %name{Slic3r::Extruder} class Extruder {
Extruder(int id, GCodeConfig *config); Extruder(unsigned int id, GCodeConfig *config);
~Extruder(); ~Extruder();
void reset(); void reset();
double extrude(double dE); double extrude(double dE);
@ -16,7 +16,7 @@
double extruded_volume(); double extruded_volume();
double used_filament(); double used_filament();
int id() unsigned int id()
%code%{ RETVAL = THIS->id; %}; %code%{ RETVAL = THIS->id; %};
double E() double E()

View file

@ -183,7 +183,7 @@ ModelMaterial::attributes()
void scale_xyz(Pointf3* versor) void scale_xyz(Pointf3* versor)
%code{% THIS->scale(*versor); %}; %code{% THIS->scale(*versor); %};
void rotate(float angle, Axis axis); void rotate(float angle, Axis axis);
void flip(Axis axis); void mirror(Axis axis);
Model* cut(double z) Model* cut(double z)
%code%{ %code%{

View file

@ -23,9 +23,9 @@
void rotate_x(float angle); void rotate_x(float angle);
void rotate_y(float angle); void rotate_y(float angle);
void rotate_z(float angle); void rotate_z(float angle);
void flip_x(); void mirror_x();
void flip_y(); void mirror_y();
void flip_z(); void mirror_z();
void align_to_origin(); void align_to_origin();
void rotate(double angle, Point* center); void rotate(double angle, Point* center);
TriangleMeshPtrs split(); TriangleMeshPtrs split();