From 5fc8fdee112808b03baf651da17d4c826893336f Mon Sep 17 00:00:00 2001 From: Enrico Turri <enricoturri@seznam.cz> Date: Fri, 18 May 2018 13:02:47 +0200 Subject: [PATCH] 3DScene axes moved to c++ --- lib/Slic3r/GUI/3DScene.pm | 53 ++++++------- lib/Slic3r/GUI/Plater/ObjectCutDialog.pm | 4 + lib/Slic3r/GUI/Plater/ObjectPartsPanel.pm | 4 + xs/src/slic3r/GUI/3DScene.cpp | 37 ++++++--- xs/src/slic3r/GUI/3DScene.hpp | 10 ++- xs/src/slic3r/GUI/GLCanvas3D.cpp | 93 ++++++++++++++++++----- xs/src/slic3r/GUI/GLCanvas3D.hpp | 30 ++++++-- xs/src/slic3r/GUI/GLCanvas3DManager.cpp | 46 +++++++---- xs/src/slic3r/GUI/GLCanvas3DManager.hpp | 10 ++- xs/xsp/GUI_3DScene.xsp | 51 +++++++++---- 10 files changed, 244 insertions(+), 94 deletions(-) diff --git a/lib/Slic3r/GUI/3DScene.pm b/lib/Slic3r/GUI/3DScene.pm index e2fdcaaca..23b87d661 100644 --- a/lib/Slic3r/GUI/3DScene.pm +++ b/lib/Slic3r/GUI/3DScene.pm @@ -1551,35 +1551,36 @@ sub Render { my $volumes_bb = $self->volumes_bounding_box; - { - # draw axes - # disable depth testing so that axes are not covered by ground - glDisable(GL_DEPTH_TEST); #============================================================================================================================== - my $origin = Slic3r::GUI::_3DScene::get_bed_origin($self); + Slic3r::GUI::_3DScene::render_axes($self); + +# { +# # draw axes +# # disable depth testing so that axes are not covered by ground +# glDisable(GL_DEPTH_TEST); # my $origin = $self->origin; +# my $axis_len = $self->use_plain_shader ? 0.3 * max(@{ $self->bed_bounding_box->size }) : 2 * max(@{ $volumes_bb->size }); +# glLineWidth(2); +# glBegin(GL_LINES); +# # draw line for x axis +# glColor3f(1, 0, 0); +# glVertex3f(@$origin, $ground_z); +# glVertex3f($origin->x + $axis_len, $origin->y, $ground_z); #,, +# # draw line for y axis +# glColor3f(0, 1, 0); +# glVertex3f(@$origin, $ground_z); +# glVertex3f($origin->x, $origin->y + $axis_len, $ground_z); #++ +# glEnd(); +# # draw line for Z axis +# # (re-enable depth test so that axis is correctly shown when objects are behind it) +# glEnable(GL_DEPTH_TEST); +# glBegin(GL_LINES); +# glColor3f(0, 0, 1); +# glVertex3f(@$origin, $ground_z); +# glVertex3f(@$origin, $ground_z+$axis_len); +# glEnd(); +# } #============================================================================================================================== - my $axis_len = $self->use_plain_shader ? 0.3 * max(@{ $self->bed_bounding_box->size }) : 2 * max(@{ $volumes_bb->size }); - glLineWidth(2); - glBegin(GL_LINES); - # draw line for x axis - glColor3f(1, 0, 0); - glVertex3f(@$origin, $ground_z); - glVertex3f($origin->x + $axis_len, $origin->y, $ground_z); #,, - # draw line for y axis - glColor3f(0, 1, 0); - glVertex3f(@$origin, $ground_z); - glVertex3f($origin->x, $origin->y + $axis_len, $ground_z); #++ - glEnd(); - # draw line for Z axis - # (re-enable depth test so that axis is correctly shown when objects are behind it) - glEnable(GL_DEPTH_TEST); - glBegin(GL_LINES); - glColor3f(0, 0, 1); - glVertex3f(@$origin, $ground_z); - glVertex3f(@$origin, $ground_z+$axis_len); - glEnd(); - } glEnable(GL_LIGHTING); diff --git a/lib/Slic3r/GUI/Plater/ObjectCutDialog.pm b/lib/Slic3r/GUI/Plater/ObjectCutDialog.pm index 6d3234ff3..80ba4db50 100644 --- a/lib/Slic3r/GUI/Plater/ObjectCutDialog.pm +++ b/lib/Slic3r/GUI/Plater/ObjectCutDialog.pm @@ -9,6 +9,9 @@ use utf8; use Slic3r::Geometry qw(PI X); use Wx qw(wxTheApp :dialog :id :misc :sizer wxTAB_TRAVERSAL); use Wx::Event qw(EVT_CLOSE EVT_BUTTON); +#============================================================================================================================== +use List::Util qw(max); +#============================================================================================================================== use base 'Wx::Dialog'; sub new { @@ -115,6 +118,7 @@ sub new { $canvas->load_object($self->{model_object}, undef, undef, [0]); #============================================================================================================================== Slic3r::GUI::_3DScene::set_auto_bed_shape($canvas); + Slic3r::GUI::_3DScene::set_axes_length($canvas, 2.0 * max(@{ $canvas->volumes_bounding_box->size })); # $canvas->set_auto_bed_shape; #============================================================================================================================== $canvas->SetSize([500,500]); diff --git a/lib/Slic3r/GUI/Plater/ObjectPartsPanel.pm b/lib/Slic3r/GUI/Plater/ObjectPartsPanel.pm index ee1bf22d1..9320e6666 100644 --- a/lib/Slic3r/GUI/Plater/ObjectPartsPanel.pm +++ b/lib/Slic3r/GUI/Plater/ObjectPartsPanel.pm @@ -10,6 +10,9 @@ use File::Basename qw(basename); use Wx qw(:misc :sizer :treectrl :button :keycode wxTAB_TRAVERSAL wxSUNKEN_BORDER wxBITMAP_TYPE_PNG wxID_CANCEL wxMOD_CONTROL wxTheApp); use Wx::Event qw(EVT_BUTTON EVT_TREE_ITEM_COLLAPSING EVT_TREE_SEL_CHANGED EVT_TREE_KEY_DOWN EVT_KEY_DOWN); +#============================================================================================================================== +use List::Util qw(max); +#============================================================================================================================== use base 'Wx::Panel'; use constant ICON_OBJECT => 0; @@ -162,6 +165,7 @@ sub new { $canvas->load_object($self->{model_object}, undef, undef, [0]); #============================================================================================================================== Slic3r::GUI::_3DScene::set_auto_bed_shape($canvas); + Slic3r::GUI::_3DScene::set_axes_length($canvas, 2.0 * max(@{ $canvas->volumes_bounding_box->size })); # $canvas->set_auto_bed_shape; #============================================================================================================================== $canvas->SetSize([500,700]); diff --git a/xs/src/slic3r/GUI/3DScene.cpp b/xs/src/slic3r/GUI/3DScene.cpp index 9babd8bc6..02dfd18ae 100644 --- a/xs/src/slic3r/GUI/3DScene.cpp +++ b/xs/src/slic3r/GUI/3DScene.cpp @@ -1782,17 +1782,6 @@ void _3DScene::set_auto_bed_shape(wxGLCanvas* canvas) return s_canvas_mgr.set_auto_bed_shape(canvas); } -Pointf _3DScene::get_bed_origin(wxGLCanvas* canvas) -{ - return s_canvas_mgr.get_bed_origin(canvas); -} - -void _3DScene::set_bed_origin(wxGLCanvas* canvas, const Pointf* origin) -{ - if (origin != nullptr) - s_canvas_mgr.set_bed_origin(canvas, *origin); -} - BoundingBoxf3 _3DScene::get_bed_bounding_box(wxGLCanvas* canvas) { return s_canvas_mgr.get_bed_bounding_box(canvas); @@ -1808,6 +1797,27 @@ BoundingBoxf3 _3DScene::get_max_bounding_box(wxGLCanvas* canvas) return s_canvas_mgr.get_max_bounding_box(canvas); } +Pointf3 _3DScene::get_axes_origin(wxGLCanvas* canvas) +{ + return s_canvas_mgr.get_axes_origin(canvas); +} + +void _3DScene::set_axes_origin(wxGLCanvas* canvas, const Pointf3* origin) +{ + if (origin != nullptr) + s_canvas_mgr.set_axes_origin(canvas, *origin); +} + +float _3DScene::get_axes_length(wxGLCanvas* canvas) +{ + return s_canvas_mgr.get_axes_length(canvas); +} + +void _3DScene::set_axes_length(wxGLCanvas* canvas, float length) +{ + s_canvas_mgr.set_axes_length(canvas, length); +} + void _3DScene::set_cutting_plane(wxGLCanvas* canvas, float z, const ExPolygons& polygons) { return s_canvas_mgr.set_cutting_plane(canvas, z, polygons); @@ -1898,6 +1908,11 @@ void _3DScene::render_bed(wxGLCanvas* canvas) s_canvas_mgr.render_bed(canvas); } +void _3DScene::render_axes(wxGLCanvas* canvas) +{ + s_canvas_mgr.render_axes(canvas); +} + void _3DScene::render_cutting_plane(wxGLCanvas* canvas) { s_canvas_mgr.render_cutting_plane(canvas); diff --git a/xs/src/slic3r/GUI/3DScene.hpp b/xs/src/slic3r/GUI/3DScene.hpp index eb03a5313..2ae07d858 100644 --- a/xs/src/slic3r/GUI/3DScene.hpp +++ b/xs/src/slic3r/GUI/3DScene.hpp @@ -555,13 +555,16 @@ public: static void set_bed_shape(wxGLCanvas* canvas, const Pointfs& shape); static void set_auto_bed_shape(wxGLCanvas* canvas); - static Pointf get_bed_origin(wxGLCanvas* canvas); - static void set_bed_origin(wxGLCanvas* canvas, const Pointf* origin); - static BoundingBoxf3 get_bed_bounding_box(wxGLCanvas* canvas); static BoundingBoxf3 get_volumes_bounding_box(wxGLCanvas* canvas); static BoundingBoxf3 get_max_bounding_box(wxGLCanvas* canvas); + static Pointf3 get_axes_origin(wxGLCanvas* canvas); + static void set_axes_origin(wxGLCanvas* canvas, const Pointf3* origin); + + static float get_axes_length(wxGLCanvas* canvas); + static void set_axes_length(wxGLCanvas* canvas, float length); + static void set_cutting_plane(wxGLCanvas* canvas, float z, const ExPolygons& polygons); static unsigned int get_camera_type(wxGLCanvas* canvas); @@ -588,6 +591,7 @@ public: static void select_view(wxGLCanvas* canvas, const std::string& direction); static void render_bed(wxGLCanvas* canvas); + static void render_axes(wxGLCanvas* canvas); static void render_cutting_plane(wxGLCanvas* canvas); static void register_on_viewport_changed_callback(wxGLCanvas* canvas, void* callback); diff --git a/xs/src/slic3r/GUI/GLCanvas3D.cpp b/xs/src/slic3r/GUI/GLCanvas3D.cpp index 9631f7996..de875841c 100644 --- a/xs/src/slic3r/GUI/GLCanvas3D.cpp +++ b/xs/src/slic3r/GUI/GLCanvas3D.cpp @@ -196,8 +196,6 @@ void GLCanvas3D::Bed::set_shape(const Pointfs& shape) _calc_gridlines(poly, bed_bbox); m_polygon = offset_ex(poly.contour, bed_bbox.radius() * 1.7, jtRound, scale_(0.5))[0].contour; - - set_origin(Pointf(0.0, 0.0)); } const BoundingBoxf3& GLCanvas3D::Bed::get_bounding_box() const @@ -205,16 +203,6 @@ const BoundingBoxf3& GLCanvas3D::Bed::get_bounding_box() const return m_bounding_box; } -const Pointf& GLCanvas3D::Bed::get_origin() const -{ - return m_origin; -} - -void GLCanvas3D::Bed::set_origin(const Pointf& origin) -{ - m_origin = origin; -} - void GLCanvas3D::Bed::render() { unsigned int triangles_vcount = m_triangles.get_data_size() / 3; @@ -297,6 +285,56 @@ void GLCanvas3D::Bed::_calc_gridlines(const ExPolygon& poly, const BoundingBox& printf("Unable to create bed grid lines\n"); } +GLCanvas3D::Axes::Axes() + : m_length(0.0f) +{ +} + +const Pointf3& GLCanvas3D::Axes::get_origin() const +{ + return m_origin; +} + +void GLCanvas3D::Axes::set_origin(const Pointf3& origin) +{ + m_origin = origin; +} + +float GLCanvas3D::Axes::get_length() const +{ + return m_length; +} + +void GLCanvas3D::Axes::set_length(float length) +{ + m_length = length; +} + +void GLCanvas3D::Axes::render() +{ + // disable depth testing so that axes are not covered by ground + ::glDisable(GL_DEPTH_TEST); + ::glLineWidth(2.0f); + ::glBegin(GL_LINES); + // draw line for x axis + ::glColor3f(1.0f, 0.0f, 0.0f); + ::glVertex3f((float)m_origin.x, (float)m_origin.y, (float)m_origin.z); + ::glVertex3f((float)m_origin.x + m_length, (float)m_origin.y, (float)m_origin.z); + // draw line for y axis + ::glColor3f(0.0f, 1.0f, 0.0f); + ::glVertex3f((float)m_origin.x, (float)m_origin.y, (float)m_origin.z); + ::glVertex3f((float)m_origin.x, (float)m_origin.y + m_length, (float)m_origin.z); + ::glEnd(); + // draw line for Z axis + // (re-enable depth test so that axis is correctly shown when objects are behind it) + ::glEnable(GL_DEPTH_TEST); + ::glBegin(GL_LINES); + ::glColor3f(0.0f, 0.0f, 1.0f); + ::glVertex3f((float)m_origin.x, (float)m_origin.y, (float)m_origin.z); + ::glVertex3f((float)m_origin.x, (float)m_origin.y, (float)m_origin.z + m_length); + ::glEnd(); +} + GLCanvas3D::CuttingPlane::CuttingPlane() : m_z(-1.0f) { @@ -472,6 +510,10 @@ void GLCanvas3D::set_volumes(GLVolumeCollection* volumes) void GLCanvas3D::set_bed_shape(const Pointfs& shape) { m_bed.set_shape(shape); + + // Set the origin and size for painting of the coordinate system axes. + set_axes_origin(Pointf3(0.0, 0.0, (coordf_t)GROUND_Z)); + set_axes_length(0.3f * (float)bed_bounding_box().max_size()); } void GLCanvas3D::set_auto_bed_shape() @@ -491,17 +533,27 @@ void GLCanvas3D::set_auto_bed_shape() set_bed_shape(bed_shape); // Set the origin for painting of the coordinate system axes. - set_bed_origin(Pointf(center.x, center.y)); + set_axes_origin(Pointf3(center.x, center.y, (coordf_t)GROUND_Z)); } -const Pointf& GLCanvas3D::get_bed_origin() const +const Pointf3& GLCanvas3D::get_axes_origin() const { - return m_bed.get_origin(); + return m_axes.get_origin(); } -void GLCanvas3D::set_bed_origin(const Pointf& origin) +void GLCanvas3D::set_axes_origin(const Pointf3& origin) { - m_bed.set_origin(origin); + m_axes.set_origin(origin); +} + +float GLCanvas3D::get_axes_length() const +{ + return m_axes.get_length(); +} + +void GLCanvas3D::set_axes_length(float length) +{ + return m_axes.set_length(length); } void GLCanvas3D::set_cutting_plane(float z, const ExPolygons& polygons) @@ -645,9 +697,16 @@ void GLCanvas3D::select_view(const std::string& direction) void GLCanvas3D::render_bed() { + ::glDisable(GL_LIGHTING); m_bed.render(); } +void GLCanvas3D::render_axes() +{ + ::glDisable(GL_LIGHTING); + m_axes.render(); +} + void GLCanvas3D::render_cutting_plane() { m_cutting_plane.render_plane(volumes_bounding_box()); diff --git a/xs/src/slic3r/GUI/GLCanvas3D.hpp b/xs/src/slic3r/GUI/GLCanvas3D.hpp index a7e9dbfb0..201a840be 100644 --- a/xs/src/slic3r/GUI/GLCanvas3D.hpp +++ b/xs/src/slic3r/GUI/GLCanvas3D.hpp @@ -79,7 +79,6 @@ public: { Pointfs m_shape; BoundingBoxf3 m_bounding_box; - Pointf m_origin; Polygon m_polygon; GeometryBuffer m_triangles; GeometryBuffer m_gridlines; @@ -90,9 +89,6 @@ public: const BoundingBoxf3& get_bounding_box() const; - const Pointf& get_origin() const; - void set_origin(const Pointf& origin); - void render(); private: @@ -101,6 +97,23 @@ public: void _calc_gridlines(const ExPolygon& poly, const BoundingBox& bed_bbox); }; + class Axes + { + Pointf3 m_origin; + float m_length; + + public: + Axes(); + + const Pointf3& get_origin() const; + void set_origin(const Pointf3& origin); + + float get_length() const; + void set_length(float length); + + void render(); + }; + class CuttingPlane { float m_z; @@ -120,6 +133,7 @@ private: wxGLContext* m_context; Camera m_camera; Bed m_bed; + Axes m_axes; CuttingPlane m_cutting_plane; GLVolumeCollection* m_volumes; @@ -153,8 +167,11 @@ public: // Used by ObjectCutDialog and ObjectPartsPanel to generate a rectangular ground plane to support the scene objects. void set_auto_bed_shape(); - const Pointf& get_bed_origin() const; - void set_bed_origin(const Pointf& origin); + const Pointf3& get_axes_origin() const; + void set_axes_origin(const Pointf3& origin); + + float get_axes_length() const; + void set_axes_length(float length); void set_cutting_plane(float z, const ExPolygons& polygons); @@ -186,6 +203,7 @@ public: void select_view(const std::string& direction); void render_bed(); + void render_axes(); void render_cutting_plane(); void register_on_viewport_changed_callback(void* callback); diff --git a/xs/src/slic3r/GUI/GLCanvas3DManager.cpp b/xs/src/slic3r/GUI/GLCanvas3DManager.cpp index 911fb2f0e..48241dafb 100644 --- a/xs/src/slic3r/GUI/GLCanvas3DManager.cpp +++ b/xs/src/slic3r/GUI/GLCanvas3DManager.cpp @@ -201,19 +201,6 @@ void GLCanvas3DManager::set_auto_bed_shape(wxGLCanvas* canvas) it->second->set_auto_bed_shape(); } -Pointf GLCanvas3DManager::get_bed_origin(wxGLCanvas* canvas) const -{ - CanvasesMap::const_iterator it = _get_canvas(canvas); - return (it != m_canvases.end()) ? it->second->get_bed_origin() : Pointf(); -} - -void GLCanvas3DManager::set_bed_origin(wxGLCanvas* canvas, const Pointf& origin) -{ - CanvasesMap::iterator it = _get_canvas(canvas); - if (it != m_canvases.end()) - it->second->set_bed_origin(origin); -} - BoundingBoxf3 GLCanvas3DManager::get_bed_bounding_box(wxGLCanvas* canvas) { CanvasesMap::const_iterator it = _get_canvas(canvas); @@ -232,6 +219,32 @@ BoundingBoxf3 GLCanvas3DManager::get_max_bounding_box(wxGLCanvas* canvas) return (it != m_canvases.end()) ? it->second->max_bounding_box() : BoundingBoxf3(); } +Pointf3 GLCanvas3DManager::get_axes_origin(wxGLCanvas* canvas) const +{ + CanvasesMap::const_iterator it = _get_canvas(canvas); + return (it != m_canvases.end()) ? it->second->get_axes_origin() : Pointf3(); +} + +void GLCanvas3DManager::set_axes_origin(wxGLCanvas* canvas, const Pointf3& origin) +{ + CanvasesMap::iterator it = _get_canvas(canvas); + if (it != m_canvases.end()) + it->second->set_axes_origin(origin); +} + +float GLCanvas3DManager::get_axes_length(wxGLCanvas* canvas) const +{ + CanvasesMap::const_iterator it = _get_canvas(canvas); + return (it != m_canvases.end()) ? it->second->get_axes_length() : 0.0f; +} + +void GLCanvas3DManager::set_axes_length(wxGLCanvas* canvas, float length) +{ + CanvasesMap::iterator it = _get_canvas(canvas); + if (it != m_canvases.end()) + it->second->set_axes_length(length); +} + void GLCanvas3DManager::set_cutting_plane(wxGLCanvas* canvas, float z, const ExPolygons& polygons) { CanvasesMap::iterator it = _get_canvas(canvas); @@ -357,6 +370,13 @@ void GLCanvas3DManager::render_bed(wxGLCanvas* canvas) it->second->render_bed(); } +void GLCanvas3DManager::render_axes(wxGLCanvas* canvas) +{ + CanvasesMap::iterator it = _get_canvas(canvas); + if (it != m_canvases.end()) + it->second->render_axes(); +} + void GLCanvas3DManager::render_cutting_plane(wxGLCanvas* canvas) { CanvasesMap::iterator it = _get_canvas(canvas); diff --git a/xs/src/slic3r/GUI/GLCanvas3DManager.hpp b/xs/src/slic3r/GUI/GLCanvas3DManager.hpp index 4d8066597..4877618f0 100644 --- a/xs/src/slic3r/GUI/GLCanvas3DManager.hpp +++ b/xs/src/slic3r/GUI/GLCanvas3DManager.hpp @@ -65,13 +65,16 @@ public: void set_bed_shape(wxGLCanvas* canvas, const Pointfs& shape); void set_auto_bed_shape(wxGLCanvas* canvas); - Pointf get_bed_origin(wxGLCanvas* canvas) const; - void set_bed_origin(wxGLCanvas* canvas, const Pointf& origin); - BoundingBoxf3 get_bed_bounding_box(wxGLCanvas* canvas); BoundingBoxf3 get_volumes_bounding_box(wxGLCanvas* canvas); BoundingBoxf3 get_max_bounding_box(wxGLCanvas* canvas); + Pointf3 get_axes_origin(wxGLCanvas* canvas) const; + void set_axes_origin(wxGLCanvas* canvas, const Pointf3& origin); + + float get_axes_length(wxGLCanvas* canvas) const; + void set_axes_length(wxGLCanvas* canvas, float length); + void set_cutting_plane(wxGLCanvas* canvas, float z, const ExPolygons& polygons); unsigned int get_camera_type(wxGLCanvas* canvas) const; @@ -98,6 +101,7 @@ public: void select_view(wxGLCanvas* canvas, const std::string& direction); void render_bed(wxGLCanvas* canvas); + void render_axes(wxGLCanvas* canvas); void render_cutting_plane(wxGLCanvas* canvas); void register_on_viewport_changed_callback(wxGLCanvas* canvas, void* callback); diff --git a/xs/xsp/GUI_3DScene.xsp b/xs/xsp/GUI_3DScene.xsp index 2efe8f11b..55679ba16 100644 --- a/xs/xsp/GUI_3DScene.xsp +++ b/xs/xsp/GUI_3DScene.xsp @@ -221,21 +221,6 @@ set_auto_bed_shape(canvas) CODE: _3DScene::set_auto_bed_shape((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas")); -Clone<Pointf> -get_bed_origin(canvas) - SV *canvas; - CODE: - RETVAL = _3DScene::get_bed_origin((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas")); - OUTPUT: - RETVAL - -void -set_bed_origin(canvas, origin) - SV *canvas; - Pointf *origin - CODE: - _3DScene::set_bed_origin((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"), origin); - Clone<BoundingBoxf3> get_bed_bounding_box(canvas) SV *canvas; @@ -283,6 +268,36 @@ is_shown_on_screen(canvas) OUTPUT: RETVAL +Clone<Pointf3> +get_axes_origin(canvas) + SV *canvas; + CODE: + RETVAL = _3DScene::get_axes_origin((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas")); + OUTPUT: + RETVAL + +void +set_axes_origin(canvas, origin) + SV *canvas; + Pointf3 *origin; + CODE: + _3DScene::set_axes_origin((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"), origin); + +float +get_axes_length(canvas) + SV *canvas; + CODE: + RETVAL = _3DScene::get_axes_length((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas")); + OUTPUT: + RETVAL + +void +set_axes_length(canvas, length) + SV *canvas; + float length; + CODE: + _3DScene::set_axes_length((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"), length); + void set_cutting_plane(canvas, z, polygons) SV *canvas; @@ -414,6 +429,12 @@ render_bed(canvas) CODE: _3DScene::render_bed((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas")); +void +render_axes(canvas) + SV *canvas; + CODE: + _3DScene::render_axes((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas")); + void render_cutting_plane(canvas) SV *canvas;