3DScene bed variables moved to c++

This commit is contained in:
Enrico Turri 2018-05-15 15:38:25 +02:00
parent 43784f3409
commit 2b4829a4b9
12 changed files with 425 additions and 167 deletions

View file

@ -1747,6 +1747,16 @@ void _3DScene::resize(wxGLCanvas* canvas, unsigned int w, unsigned int h)
s_canvas_mgr.resize(canvas, w, h);
}
bool _3DScene::is_dirty(wxGLCanvas* canvas)
{
return s_canvas_mgr.is_dirty(canvas);
}
void _3DScene::set_dirty(wxGLCanvas* canvas, bool dirty)
{
s_canvas_mgr.set_dirty(canvas, dirty);
}
bool _3DScene::is_shown_on_screen(wxGLCanvas* canvas)
{
return s_canvas_mgr.is_shown_on_screen(canvas);
@ -1767,6 +1777,11 @@ void _3DScene::set_bed_shape(wxGLCanvas* canvas, const Pointfs& shape)
return s_canvas_mgr.set_bed_shape(canvas, shape);
}
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);
@ -1793,16 +1808,6 @@ BoundingBoxf3 _3DScene::get_max_bounding_box(wxGLCanvas* canvas)
return s_canvas_mgr.get_max_bounding_box(canvas);
}
bool _3DScene::is_dirty(wxGLCanvas* canvas)
{
return s_canvas_mgr.is_dirty(canvas);
}
void _3DScene::set_dirty(wxGLCanvas* canvas, bool dirty)
{
s_canvas_mgr.set_dirty(canvas, dirty);
}
unsigned int _3DScene::get_camera_type(wxGLCanvas* canvas)
{
return s_canvas_mgr.get_camera_type(canvas);
@ -1883,6 +1888,11 @@ void _3DScene::select_view(wxGLCanvas* canvas, const std::string& direction)
s_canvas_mgr.select_view(canvas, direction);
}
void _3DScene::render(wxGLCanvas* canvas)
{
s_canvas_mgr.render(canvas);
}
void _3DScene::register_on_viewport_changed_callback(wxGLCanvas* canvas, void* callback)
{
s_canvas_mgr.register_on_viewport_changed_callback(canvas, callback);

View file

@ -544,12 +544,16 @@ public:
static void resize(wxGLCanvas* canvas, unsigned int w, unsigned int h);
static bool is_dirty(wxGLCanvas* canvas);
static void set_dirty(wxGLCanvas* canvas, bool dirty);
static bool is_shown_on_screen(wxGLCanvas* canvas);
static GLVolumeCollection* get_volumes(wxGLCanvas* canvas);
static void set_volumes(wxGLCanvas* canvas, GLVolumeCollection* volumes);
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);
@ -558,9 +562,6 @@ public:
static BoundingBoxf3 get_volumes_bounding_box(wxGLCanvas* canvas);
static BoundingBoxf3 get_max_bounding_box(wxGLCanvas* canvas);
static bool is_dirty(wxGLCanvas* canvas);
static void set_dirty(wxGLCanvas* canvas, bool dirty);
static unsigned int get_camera_type(wxGLCanvas* canvas);
static void set_camera_type(wxGLCanvas* canvas, unsigned int type);
static std::string get_camera_type_as_string(wxGLCanvas* canvas);
@ -584,6 +585,8 @@ public:
static void zoom_to_volumes(wxGLCanvas* canvas);
static void select_view(wxGLCanvas* canvas, const std::string& direction);
static void render(wxGLCanvas* canvas);
static void register_on_viewport_changed_callback(wxGLCanvas* canvas, void* callback);
// static void _glew_init();

View file

@ -1,6 +1,7 @@
#include "GLCanvas3D.hpp"
#include "../../slic3r/GUI/3DScene.hpp"
#include "../../libslic3r/ClipperUtils.hpp"
#include <wx/glcanvas.h>
@ -8,6 +9,7 @@
static const bool TURNTABLE_MODE = true;
static const float GIMBALL_LOCK_THETA_MAX = 180.0f;
static const float GROUND_Z = -0.02f;
// phi / theta angles to orient the camera.
static const float VIEW_DEFAULT[2] = { 45.0f, 45.0f };
@ -21,6 +23,65 @@ static const float VIEW_REAR[2] = { 180.0f, 90.0f };
namespace Slic3r {
namespace GUI {
bool GeometryBuffer::set_from_triangles(const Polygons& triangles, float z)
{
m_data.clear();
unsigned int size = 9 * (unsigned int)triangles.size();
if (size == 0)
return false;
m_data = std::vector<float>(size, 0.0f);
unsigned int coord = 0;
for (const Polygon& t : triangles)
{
for (unsigned int v = 0; v < 3; ++v)
{
const Point& p = t.points[v];
m_data[coord++] = (float)unscale(p.x);
m_data[coord++] = (float)unscale(p.y);
m_data[coord++] = z;
}
}
return true;
}
bool GeometryBuffer::set_from_lines(const Lines& lines, float z)
{
m_data.clear();
unsigned int size = 6 * (unsigned int)lines.size();
if (size == 0)
return false;
m_data = std::vector<float>(size, 0.0f);
unsigned int coord = 0;
for (const Line& l : lines)
{
m_data[coord++] = (float)unscale(l.a.x);
m_data[coord++] = (float)unscale(l.a.y);
m_data[coord++] = z;
m_data[coord++] = (float)unscale(l.b.x);
m_data[coord++] = (float)unscale(l.b.y);
m_data[coord++] = z;
}
return true;
}
const float* GeometryBuffer::get_data() const
{
return m_data.data();
}
unsigned int GeometryBuffer::get_data_size() const
{
return (unsigned int)m_data.size();
}
GLCanvas3D::Camera::Camera()
: m_type(CT_Ortho)
, m_zoom(1.0f)
@ -120,7 +181,23 @@ const Pointfs& GLCanvas3D::Bed::get_shape() const
void GLCanvas3D::Bed::set_shape(const Pointfs& shape)
{
m_shape = shape;
_calc_bounding_box();
ExPolygon poly;
for (const Pointf& p : m_shape)
{
poly.contour.append(Point(scale_(p.x), scale_(p.y)));
}
_calc_triangles(poly);
const BoundingBox& bed_bbox = poly.contour.bounding_box();
_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
@ -138,6 +215,43 @@ 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;
if (triangles_vcount > 0)
{
::glDisable(GL_DEPTH_TEST);
::glEnable(GL_BLEND);
::glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
::glEnableClientState(GL_VERTEX_ARRAY);
::glColor4f(0.8f, 0.6f, 0.5f, 0.4f);
::glNormal3d(0.0f, 0.0f, 1.0f);
::glVertexPointer(3, GL_FLOAT, 0, (GLvoid*)m_triangles.get_data());
::glDrawArrays(GL_TRIANGLES, 0, triangles_vcount);
// ::glDisableClientState(GL_VERTEX_ARRAY);
// we need depth test for grid, otherwise it would disappear when looking
// the object from below
glEnable(GL_DEPTH_TEST);
// draw grid
unsigned int gridlines_vcount = m_gridlines.get_data_size() / 3;
::glLineWidth(3.0f);
::glColor4f(0.2f, 0.2f, 0.2f, 0.4f);
// ::glEnableClientState(GL_VERTEX_ARRAY);
::glVertexPointer(3, GL_FLOAT, 0, (GLvoid*)m_gridlines.get_data());
::glDrawArrays(GL_LINES, 0, gridlines_vcount);
::glDisableClientState(GL_VERTEX_ARRAY);
::glDisable(GL_BLEND);
}
}
void GLCanvas3D::Bed::_calc_bounding_box()
{
m_bounding_box = BoundingBoxf3();
@ -147,6 +261,44 @@ void GLCanvas3D::Bed::_calc_bounding_box()
}
}
void GLCanvas3D::Bed::_calc_triangles(const ExPolygon& poly)
{
Polygons triangles;
poly.triangulate(&triangles);
if (!m_triangles.set_from_triangles(triangles, GROUND_Z))
printf("Unable to create bed triangles\n");
}
void GLCanvas3D::Bed::_calc_gridlines(const ExPolygon& poly, const BoundingBox& bed_bbox)
{
Polylines axes_lines;
for (coord_t x = bed_bbox.min.x; x <= bed_bbox.max.x; x += scale_(10.0))
{
Polyline line;
line.append(Point(x, bed_bbox.min.y));
line.append(Point(x, bed_bbox.max.y));
axes_lines.push_back(line);
}
for (coord_t y = bed_bbox.min.y; y <= bed_bbox.max.y; y += scale_(10.0))
{
Polyline line;
line.append(Point(bed_bbox.min.x, y));
line.append(Point(bed_bbox.max.x, y));
axes_lines.push_back(line);
}
// clip with a slightly grown expolygon because our lines lay on the contours and may get erroneously clipped
Lines gridlines = to_lines(intersection_pl(axes_lines, offset(poly, SCALED_EPSILON)));
// append bed contours
Lines contour_lines = to_lines(poly);
std::copy(contour_lines.begin(), contour_lines.end(), std::back_inserter(gridlines));
if (!m_gridlines.set_from_lines(gridlines, GROUND_Z))
printf("Unable to create bed grid lines\n");
}
GLCanvas3D::GLCanvas3D(wxGLCanvas* canvas, wxGLContext* context)
: m_canvas(canvas)
, m_context(context)
@ -167,6 +319,16 @@ void GLCanvas3D::set_current()
m_canvas->SetCurrent(*m_context);
}
bool GLCanvas3D::is_dirty() const
{
return m_dirty;
}
void GLCanvas3D::set_dirty(bool dirty)
{
m_dirty = dirty;
}
bool GLCanvas3D::is_shown_on_screen() const
{
return (m_canvas != nullptr) ? m_canvas->IsShownOnScreen() : false;
@ -254,6 +416,26 @@ void GLCanvas3D::set_bed_shape(const Pointfs& shape)
m_bed.set_shape(shape);
}
void GLCanvas3D::set_auto_bed_shape()
{
// draw a default square bed around object center
const BoundingBoxf3& bbox = volumes_bounding_box();
coordf_t max_size = bbox.max_size();
const Pointf3& center = bbox.center();
Pointfs bed_shape;
bed_shape.reserve(4);
bed_shape.emplace_back(center.x - max_size, center.y - max_size);
bed_shape.emplace_back(center.x + max_size, center.y - max_size);
bed_shape.emplace_back(center.x + max_size, center.y + max_size);
bed_shape.emplace_back(center.x - max_size, center.y + max_size);
set_bed_shape(bed_shape);
// Set the origin for painting of the coordinate system axes.
set_bed_origin(Pointf(center.x, center.y));
}
const Pointf& GLCanvas3D::get_bed_origin() const
{
return m_bed.get_origin();
@ -264,16 +446,6 @@ void GLCanvas3D::set_bed_origin(const Pointf& origin)
m_bed.set_origin(origin);
}
bool GLCanvas3D::is_dirty() const
{
return m_dirty;
}
void GLCanvas3D::set_dirty(bool dirty)
{
m_dirty = dirty;
}
GLCanvas3D::Camera::EType GLCanvas3D::get_camera_type() const
{
return m_camera.get_type();
@ -408,6 +580,11 @@ void GLCanvas3D::select_view(const std::string& direction)
}
}
void GLCanvas3D::render()
{
m_bed.render();
}
void GLCanvas3D::register_on_viewport_changed_callback(void* callback)
{
if (callback != nullptr)

View file

@ -12,9 +12,22 @@ class wxIdleEvent;
namespace Slic3r {
class GLVolumeCollection;
class ExPolygon;
namespace GUI {
class GeometryBuffer
{
std::vector<float> m_data;
public:
bool set_from_triangles(const Polygons& triangles, float z);
bool set_from_lines(const Lines& lines, float z);
const float* get_data() const;
unsigned int get_data_size() const;
};
class GLCanvas3D
{
public:
@ -65,6 +78,9 @@ public:
Pointfs m_shape;
BoundingBoxf3 m_bounding_box;
Pointf m_origin;
Polygon m_polygon;
GeometryBuffer m_triangles;
GeometryBuffer m_gridlines;
public:
const Pointfs& get_shape() const;
@ -75,8 +91,12 @@ public:
const Pointf& get_origin() const;
void set_origin(const Pointf& origin);
void render();
private:
void _calc_bounding_box();
void _calc_triangles(const ExPolygon& poly);
void _calc_gridlines(const ExPolygon& poly, const BoundingBox& bed_bbox);
};
private:
@ -98,6 +118,9 @@ public:
void set_current();
bool is_dirty() const;
void set_dirty(bool dirty);
bool is_shown_on_screen() const;
void resize(unsigned int w, unsigned int h);
@ -105,14 +128,17 @@ public:
GLVolumeCollection* get_volumes();
void set_volumes(GLVolumeCollection* volumes);
// Set the bed shape to a single closed 2D polygon(array of two element arrays),
// triangulate the bed and store the triangles into m_bed.m_triangles,
// fills the m_bed.m_grid_lines and sets m_bed.m_origin.
// Sets m_bed.m_polygon to limit the object placement.
void set_bed_shape(const Pointfs& shape);
// 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);
bool is_dirty() const;
void set_dirty(bool dirty);
Camera::EType get_camera_type() const;
void set_camera_type(Camera::EType type);
std::string get_camera_type_as_string() const;
@ -140,6 +166,8 @@ public:
void zoom_to_volumes();
void select_view(const std::string& direction);
void render();
void register_on_viewport_changed_callback(void* callback);
void on_size(wxSizeEvent& evt);

View file

@ -147,6 +147,19 @@ bool GLCanvas3DManager::layer_editing_allowed() const
return m_layer_editing.allowed;
}
bool GLCanvas3DManager::is_dirty(wxGLCanvas* canvas) const
{
CanvasesMap::const_iterator it = _get_canvas(canvas);
return (it != m_canvases.end()) ? it->second->is_dirty() : false;
}
void GLCanvas3DManager::set_dirty(wxGLCanvas* canvas, bool dirty)
{
CanvasesMap::iterator it = _get_canvas(canvas);
if (it != m_canvases.end())
it->second->set_dirty(dirty);
}
bool GLCanvas3DManager::is_shown_on_screen(wxGLCanvas* canvas) const
{
CanvasesMap::const_iterator it = _get_canvas(canvas);
@ -180,6 +193,13 @@ void GLCanvas3DManager::set_bed_shape(wxGLCanvas* canvas, const Pointfs& shape)
it->second->set_bed_shape(shape);
}
void GLCanvas3DManager::set_auto_bed_shape(wxGLCanvas* canvas)
{
CanvasesMap::iterator it = _get_canvas(canvas);
if (it != m_canvases.end())
it->second->set_auto_bed_shape();
}
Pointf GLCanvas3DManager::get_bed_origin(wxGLCanvas* canvas) const
{
CanvasesMap::const_iterator it = _get_canvas(canvas);
@ -211,19 +231,6 @@ BoundingBoxf3 GLCanvas3DManager::get_max_bounding_box(wxGLCanvas* canvas)
return (it != m_canvases.end()) ? it->second->max_bounding_box() : BoundingBoxf3();
}
bool GLCanvas3DManager::is_dirty(wxGLCanvas* canvas) const
{
CanvasesMap::const_iterator it = _get_canvas(canvas);
return (it != m_canvases.end()) ? it->second->is_dirty() : false;
}
void GLCanvas3DManager::set_dirty(wxGLCanvas* canvas, bool dirty)
{
CanvasesMap::iterator it = _get_canvas(canvas);
if (it != m_canvases.end())
it->second->set_dirty(dirty);
}
unsigned int GLCanvas3DManager::get_camera_type(wxGLCanvas* canvas) const
{
CanvasesMap::const_iterator it = _get_canvas(canvas);
@ -335,6 +342,13 @@ void GLCanvas3DManager::select_view(wxGLCanvas* canvas, const std::string& direc
it->second->select_view(direction);
}
void GLCanvas3DManager::render(wxGLCanvas* canvas)
{
CanvasesMap::iterator it = _get_canvas(canvas);
if (it != m_canvases.end())
it->second->render();
}
void GLCanvas3DManager::register_on_viewport_changed_callback(wxGLCanvas* canvas, void* callback)
{
CanvasesMap::iterator it = _get_canvas(canvas);

View file

@ -52,6 +52,9 @@ public:
bool use_VBOs() const;
bool layer_editing_allowed() const;
bool is_dirty(wxGLCanvas* canvas) const;
void set_dirty(wxGLCanvas* canvas, bool dirty);
bool is_shown_on_screen(wxGLCanvas* canvas) const;
void resize(wxGLCanvas* canvas, unsigned int w, unsigned int h);
@ -60,6 +63,7 @@ public:
void set_volumes(wxGLCanvas* canvas, GLVolumeCollection* volumes);
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);
@ -68,9 +72,6 @@ public:
BoundingBoxf3 get_volumes_bounding_box(wxGLCanvas* canvas);
BoundingBoxf3 get_max_bounding_box(wxGLCanvas* canvas);
bool is_dirty(wxGLCanvas* canvas) const;
void set_dirty(wxGLCanvas* canvas, bool dirty);
unsigned int get_camera_type(wxGLCanvas* canvas) const;
void set_camera_type(wxGLCanvas* canvas, unsigned int type);
std::string get_camera_type_as_string(wxGLCanvas* canvas) const;
@ -94,6 +95,8 @@ public:
void zoom_to_volumes(wxGLCanvas* canvas);
void select_view(wxGLCanvas* canvas, const std::string& direction);
void render(wxGLCanvas* canvas);
void register_on_viewport_changed_callback(wxGLCanvas* canvas, void* callback);
private: