Merge remote-tracking branch 'remotes/origin/opengl_to_cpp'

This commit is contained in:
bubnikv 2018-06-19 16:08:53 +02:00
commit 5a56f08aad
49 changed files with 10551 additions and 3604 deletions

View file

@ -188,7 +188,15 @@ add_library(libslic3r_gui STATIC
${LIBDIR}/slic3r/GUI/3DScene.cpp
${LIBDIR}/slic3r/GUI/3DScene.hpp
${LIBDIR}/slic3r/GUI/GLShader.cpp
${LIBDIR}/slic3r/GUI/GLShader.hpp
${LIBDIR}/slic3r/GUI/GLShader.hpp
${LIBDIR}/slic3r/GUI/GLCanvas3D.hpp
${LIBDIR}/slic3r/GUI/GLCanvas3D.cpp
${LIBDIR}/slic3r/GUI/GLCanvas3DManager.hpp
${LIBDIR}/slic3r/GUI/GLCanvas3DManager.cpp
${LIBDIR}/slic3r/GUI/GLGizmo.hpp
${LIBDIR}/slic3r/GUI/GLGizmo.cpp
${LIBDIR}/slic3r/GUI/GLTexture.hpp
${LIBDIR}/slic3r/GUI/GLTexture.cpp
${LIBDIR}/slic3r/GUI/Preferences.cpp
${LIBDIR}/slic3r/GUI/Preferences.hpp
${LIBDIR}/slic3r/GUI/Preset.cpp
@ -566,13 +574,13 @@ if (SLIC3R_PRUSACONTROL)
set(wxWidgets_UseAlienWx 1)
if (wxWidgets_UseAlienWx)
set(AlienWx_DEBUG 1)
find_package(AlienWx REQUIRED COMPONENTS base core adv html)
find_package(AlienWx REQUIRED COMPONENTS base core adv html gl)
include_directories(${AlienWx_INCLUDE_DIRS})
#add_compile_options(${AlienWx_CXX_FLAGS})
add_definitions(${AlienWx_DEFINITIONS})
set(wxWidgets_LIBRARIES ${AlienWx_LIBRARIES})
else ()
find_package(wxWidgets REQUIRED COMPONENTS base core adv html)
find_package(wxWidgets REQUIRED COMPONENTS base core adv html gl)
include(${wxWidgets_USE_FILE})
endif ()
add_definitions(-DSLIC3R_GUI -DSLIC3R_PRUS)

View file

@ -12,6 +12,8 @@ our $VERSION = '0.01';
BEGIN {
if ($^O eq 'MSWin32') {
eval "use Wx";
eval "use Wx::GLCanvas";
eval "use Wx::GLContext";
eval "use Wx::Html";
eval "use Wx::Print"; # because of some Wx bug, thread creation fails if we don't have this (looks like Wx::Printout is hard-coded in some thread cleanup code)
}
@ -280,6 +282,7 @@ for my $class (qw(
Slic3r::Geometry::BoundingBox
Slic3r::Geometry::BoundingBoxf
Slic3r::Geometry::BoundingBoxf3
Slic3r::GUI::_3DScene::GLShader
Slic3r::GUI::_3DScene::GLVolume
Slic3r::GUI::Preset
Slic3r::GUI::PresetCollection

View file

@ -222,6 +222,14 @@ BoundingBox3Base<PointClass>::center() const
}
template Pointf3 BoundingBox3Base<Pointf3>::center() const;
template <class PointClass> coordf_t
BoundingBox3Base<PointClass>::max_size() const
{
PointClass s = size();
return std::max(s.x, std::max(s.y, s.z));
}
template coordf_t BoundingBox3Base<Pointf3>::max_size() const;
// Align a coordinate to a grid. The coordinate may be negative,
// the aligned value will never be bigger than the original one.
static inline coord_t _align_to_grid(const coord_t coord, const coord_t spacing) {

View file

@ -94,6 +94,7 @@ public:
void translate(const Pointf3 &pos) { this->translate(pos.x, pos.y, pos.z); }
void offset(coordf_t delta);
PointClass center() const;
coordf_t max_size() const;
bool contains(const PointClass &point) const {
return BoundingBoxBase<PointClass>::contains(point) && point.z >= this->min.z && point.z <= this->max.z;

View file

@ -603,7 +603,10 @@ void ModelObject::clear_instances()
// Returns the bounding box of the transformed instances.
// This bounding box is approximate and not snug.
const BoundingBoxf3& ModelObject::bounding_box()
//========================================================================================================
const BoundingBoxf3& ModelObject::bounding_box() const
//const BoundingBoxf3& ModelObject::bounding_box()
//========================================================================================================
{
if (! m_bounding_box_valid) {
BoundingBoxf3 raw_bbox;

View file

@ -103,7 +103,10 @@ public:
// Returns the bounding box of the transformed instances.
// This bounding box is approximate and not snug.
// This bounding box is being cached.
const BoundingBoxf3& bounding_box();
//========================================================================================================
const BoundingBoxf3& bounding_box() const;
// const BoundingBoxf3& bounding_box();
//========================================================================================================
void invalidate_bounding_box() { m_bounding_box_valid = false; }
// Returns a snug bounding box of the transformed instances.
// This bounding box is not being cached.
@ -145,8 +148,10 @@ private:
// Parent object, owning this ModelObject.
Model *m_model;
// Bounding box, cached.
BoundingBoxf3 m_bounding_box;
bool m_bounding_box_valid;
//========================================================================================================
mutable BoundingBoxf3 m_bounding_box;
mutable bool m_bounding_box_valid;
//========================================================================================================
};
// An object STL, or a modifier volume, over which a different set of parameters shall be applied.

View file

@ -238,6 +238,11 @@ inline coordf_t dot(const Pointf &v1, const Pointf &v2) { return v1.x * v2.x + v
inline coordf_t dot(const Pointf &v) { return v.x * v.x + v.y * v.y; }
inline double length(const Vectorf &v) { return sqrt(dot(v)); }
inline double l2(const Vectorf &v) { return dot(v); }
inline Vectorf normalize(const Vectorf& v)
{
coordf_t len = ::sqrt(sqr(v.x) + sqr(v.y));
return (len != 0.0) ? 1.0 / len * v : Vectorf(0.0, 0.0);
}
class Pointf3 : public Pointf
{

View file

@ -184,6 +184,8 @@ public:
void reset_layer_height_profile();
void adjust_layer_height_profile(coordf_t z, coordf_t layer_thickness_delta, coordf_t band_width, int action);
// Collect the slicing parameters, to be used by variable layer thickness algorithm,
// by the interactive layer height editor and by the printing process itself.
// The slicing parameters are dependent on various configuration values

View file

@ -4,6 +4,7 @@
#include "Geometry.hpp"
#include "SupportMaterial.hpp"
#include "Surface.hpp"
#include "Slicing.hpp"
#include <utility>
#include <boost/log/trivial.hpp>
@ -1961,4 +1962,12 @@ void PrintObject::reset_layer_height_profile()
this->model_object()->layer_height_profile_valid = false;
}
void PrintObject::adjust_layer_height_profile(coordf_t z, coordf_t layer_thickness_delta, coordf_t band_width, int action)
{
update_layer_height_profile(_model_object->layer_height_profile);
Slic3r::adjust_layer_height_profile(slicing_parameters(), _model_object->layer_height_profile, z, layer_thickness_delta, band_width, LayerHeightEditActionType(action));
_model_object->layer_height_profile_valid = true;
layer_height_profile_valid = false;
}
} // namespace Slic3r

View file

@ -91,10 +91,13 @@ public:
~PerlCallback() { this->deregister_callback(); }
void register_callback(void *sv);
void deregister_callback();
void call();
void call(int i);
void call(int i, int j);
// void call(const std::vector<int> &ints);
void call() const;
void call(int i) const;
void call(int i, int j) const;
void call(const std::vector<int>& ints) const;
void call(double d) const;
void call(double x, double y) const;
void call(bool b) const;
private:
void *m_callback;
};

View file

@ -184,7 +184,7 @@ void PerlCallback::deregister_callback()
}
}
void PerlCallback::call()
void PerlCallback::call() const
{
if (! m_callback)
return;
@ -198,7 +198,7 @@ void PerlCallback::call()
LEAVE;
}
void PerlCallback::call(int i)
void PerlCallback::call(int i) const
{
if (! m_callback)
return;
@ -213,7 +213,7 @@ void PerlCallback::call(int i)
LEAVE;
}
void PerlCallback::call(int i, int j)
void PerlCallback::call(int i, int j) const
{
if (! m_callback)
return;
@ -229,8 +229,7 @@ void PerlCallback::call(int i, int j)
LEAVE;
}
/*
void PerlCallback::call(const std::vector<int> &ints)
void PerlCallback::call(const std::vector<int>& ints) const
{
if (! m_callback)
return;
@ -238,16 +237,51 @@ void PerlCallback::call(const std::vector<int> &ints)
ENTER;
SAVETMPS;
PUSHMARK(SP);
AV* av = newAV();
for (int i : ints)
av_push(av, newSViv(i));
XPUSHs(av);
{
XPUSHs(sv_2mortal(newSViv(i)));
}
PUTBACK;
perl_call_sv(SvRV((SV*)m_callback), G_DISCARD);
FREETMPS;
LEAVE;
}
*/
void PerlCallback::call(double d) const
{
if (!m_callback)
return;
dSP;
ENTER;
SAVETMPS;
PUSHMARK(SP);
XPUSHs(sv_2mortal(newSVnv(d)));
PUTBACK;
perl_call_sv(SvRV((SV*)m_callback), G_DISCARD);
FREETMPS;
LEAVE;
}
void PerlCallback::call(double x, double y) const
{
if (!m_callback)
return;
dSP;
ENTER;
SAVETMPS;
PUSHMARK(SP);
XPUSHs(sv_2mortal(newSVnv(x)));
XPUSHs(sv_2mortal(newSVnv(y)));
PUTBACK;
perl_call_sv(SvRV((SV*)m_callback), G_DISCARD);
FREETMPS;
LEAVE;
}
void PerlCallback::call(bool b) const
{
call(b ? 1 : 0);
}
#ifdef WIN32
#ifndef NOMINMAX

File diff suppressed because it is too large Load diff

View file

@ -6,8 +6,10 @@
#include "../../libslic3r/Line.hpp"
#include "../../libslic3r/TriangleMesh.hpp"
#include "../../libslic3r/Utils.hpp"
#include "../../slic3r/GUI/GLCanvas3DManager.hpp"
class wxBitmap;
class wxWindow;
namespace Slic3r {
@ -17,6 +19,11 @@ class Model;
class ModelObject;
class GCodePreviewData;
class DynamicPrintConfig;
class ExtrusionPath;
class ExtrusionMultiPath;
class ExtrusionLoop;
class ExtrusionEntity;
class ExtrusionEntityCollection;
// A container for interleaved arrays of 3D vertices and normals,
// possibly indexed by triangles and / or quads.
@ -305,9 +312,9 @@ public:
// Boolean: Is mouse over this object?
bool hover;
// Wheter or not this volume has been generated from a modifier
bool is_modifier;
bool is_modifier;
// Wheter or not this volume has been generated from the wipe tower
bool is_wipe_tower;
bool is_wipe_tower;
// Interleaved triangles & normals with indexed triangles & quads.
GLIndexedVertexArray indexed_vertex_array;
@ -437,35 +444,6 @@ private:
class _3DScene
{
struct GCodePreviewVolumeIndex
{
enum EType
{
Extrusion,
Travel,
Retraction,
Unretraction,
Shell,
Num_Geometry_Types
};
struct FirstVolume
{
EType type;
unsigned int flag;
// Index of the first volume in a GLVolumeCollection.
unsigned int id;
FirstVolume(EType type, unsigned int flag, unsigned int id) : type(type), flag(flag), id(id) {}
};
std::vector<FirstVolume> first_volumes;
void reset() { first_volumes.clear(); }
};
static GCodePreviewVolumeIndex s_gcode_preview_volume_index;
class TextureBase
{
protected:
@ -525,12 +503,106 @@ class _3DScene
static LegendTexture s_legend_texture;
static WarningTexture s_warning_texture;
static GUI::GLCanvas3DManager s_canvas_mgr;
public:
static void _glew_init();
static void init_gl();
static std::string get_gl_info(bool format_as_html, bool extensions);
static bool use_VBOs();
static void load_gcode_preview(const Print* print, const GCodePreviewData* preview_data, GLVolumeCollection* volumes, const std::vector<std::string>& str_tool_colors, bool use_VBOs);
static bool add_canvas(wxGLCanvas* canvas);
static bool remove_canvas(wxGLCanvas* canvas);
static void remove_all_canvases();
static bool init(wxGLCanvas* canvas);
static void set_active(wxGLCanvas* canvas, bool active);
static unsigned int get_volumes_count(wxGLCanvas* canvas);
static void reset_volumes(wxGLCanvas* canvas);
static void deselect_volumes(wxGLCanvas* canvas);
static void select_volume(wxGLCanvas* canvas, unsigned int id);
static void update_volumes_selection(wxGLCanvas* canvas, const std::vector<int>& selections);
static bool check_volumes_outside_state(wxGLCanvas* canvas, const DynamicPrintConfig* config);
static bool move_volume_up(wxGLCanvas* canvas, unsigned int id);
static bool move_volume_down(wxGLCanvas* canvas, unsigned int id);
static void set_objects_selections(wxGLCanvas* canvas, const std::vector<int>& selections);
static void set_config(wxGLCanvas* canvas, DynamicPrintConfig* config);
static void set_print(wxGLCanvas* canvas, Print* print);
static void set_model(wxGLCanvas* canvas, Model* model);
static void set_bed_shape(wxGLCanvas* canvas, const Pointfs& shape);
static void set_auto_bed_shape(wxGLCanvas* canvas);
static BoundingBoxf3 get_volumes_bounding_box(wxGLCanvas* canvas);
static void set_axes_length(wxGLCanvas* canvas, float length);
static void set_cutting_plane(wxGLCanvas* canvas, float z, const ExPolygons& polygons);
static void set_color_by(wxGLCanvas* canvas, const std::string& value);
static void set_select_by(wxGLCanvas* canvas, const std::string& value);
static void set_drag_by(wxGLCanvas* canvas, const std::string& value);
static bool is_layers_editing_enabled(wxGLCanvas* canvas);
static bool is_layers_editing_allowed(wxGLCanvas* canvas);
static bool is_shader_enabled(wxGLCanvas* canvas);
static bool is_reload_delayed(wxGLCanvas* canvas);
static void enable_layers_editing(wxGLCanvas* canvas, bool enable);
static void enable_warning_texture(wxGLCanvas* canvas, bool enable);
static void enable_legend_texture(wxGLCanvas* canvas, bool enable);
static void enable_picking(wxGLCanvas* canvas, bool enable);
static void enable_moving(wxGLCanvas* canvas, bool enable);
static void enable_gizmos(wxGLCanvas* canvas, bool enable);
static void enable_shader(wxGLCanvas* canvas, bool enable);
static void enable_force_zoom_to_bed(wxGLCanvas* canvas, bool enable);
static void allow_multisample(wxGLCanvas* canvas, bool allow);
static void zoom_to_bed(wxGLCanvas* canvas);
static void zoom_to_volumes(wxGLCanvas* canvas);
static void select_view(wxGLCanvas* canvas, const std::string& direction);
static void set_viewport_from_scene(wxGLCanvas* canvas, wxGLCanvas* other);
static void update_volumes_colors_by_extruder(wxGLCanvas* canvas);
static void render(wxGLCanvas* canvas);
static std::vector<double> get_current_print_zs(wxGLCanvas* canvas, bool active_only);
static void set_toolpaths_range(wxGLCanvas* canvas, double low, double high);
static void register_on_viewport_changed_callback(wxGLCanvas* canvas, void* callback);
static void register_on_double_click_callback(wxGLCanvas* canvas, void* callback);
static void register_on_right_click_callback(wxGLCanvas* canvas, void* callback);
static void register_on_select_object_callback(wxGLCanvas* canvas, void* callback);
static void register_on_model_update_callback(wxGLCanvas* canvas, void* callback);
static void register_on_remove_object_callback(wxGLCanvas* canvas, void* callback);
static void register_on_arrange_callback(wxGLCanvas* canvas, void* callback);
static void register_on_rotate_object_left_callback(wxGLCanvas* canvas, void* callback);
static void register_on_rotate_object_right_callback(wxGLCanvas* canvas, void* callback);
static void register_on_scale_object_uniformly_callback(wxGLCanvas* canvas, void* callback);
static void register_on_increase_objects_callback(wxGLCanvas* canvas, void* callback);
static void register_on_decrease_objects_callback(wxGLCanvas* canvas, void* callback);
static void register_on_instance_moved_callback(wxGLCanvas* canvas, void* callback);
static void register_on_wipe_tower_moved_callback(wxGLCanvas* canvas, void* callback);
static void register_on_enable_action_buttons_callback(wxGLCanvas* canvas, void* callback);
static void register_on_gizmo_scale_uniformly_callback(wxGLCanvas* canvas, void* callback);
static std::vector<int> load_object(wxGLCanvas* canvas, const ModelObject* model_object, int obj_idx, std::vector<int> instance_idxs);
static std::vector<int> load_object(wxGLCanvas* canvas, const Model* model, int obj_idx);
static void reload_scene(wxGLCanvas* canvas, bool force);
static void load_print_toolpaths(wxGLCanvas* canvas);
static void load_print_object_toolpaths(wxGLCanvas* canvas, const PrintObject* print_object, const std::vector<std::string>& str_tool_colors);
static void load_wipe_tower_toolpaths(wxGLCanvas* canvas, const std::vector<std::string>& str_tool_colors);
static void load_gcode_preview(wxGLCanvas* canvas, const GCodePreviewData* preview_data, const std::vector<std::string>& str_tool_colors);
// generates the legend texture in dependence of the current shown view type
static void generate_legend_texture(const GCodePreviewData& preview_data, const std::vector<float>& tool_colors);
static unsigned int get_legend_texture_width();
static unsigned int get_legend_texture_height();
@ -545,42 +617,16 @@ public:
static void reset_warning_texture();
static unsigned int finalize_warning_texture();
static void _load_print_toolpaths(
const Print *print,
GLVolumeCollection *volumes,
const std::vector<std::string> &tool_colors,
bool use_VBOs);
static void _load_print_object_toolpaths(
const PrintObject *print_object,
GLVolumeCollection *volumes,
const std::vector<std::string> &tool_colors,
bool use_VBOs);
static void _load_wipe_tower_toolpaths(
const Print *print,
GLVolumeCollection *volumes,
const std::vector<std::string> &tool_colors_str,
bool use_VBOs);
private:
// generates gcode extrusion paths geometry
static void _load_gcode_extrusion_paths(const GCodePreviewData& preview_data, GLVolumeCollection& volumes, const std::vector<float>& tool_colors, bool use_VBOs);
// generates gcode travel paths geometry
static void _load_gcode_travel_paths(const GCodePreviewData& preview_data, GLVolumeCollection& volumes, const std::vector<float>& tool_colors, bool use_VBOs);
static bool _travel_paths_by_type(const GCodePreviewData& preview_data, GLVolumeCollection& volumes);
static bool _travel_paths_by_feedrate(const GCodePreviewData& preview_data, GLVolumeCollection& volumes);
static bool _travel_paths_by_tool(const GCodePreviewData& preview_data, GLVolumeCollection& volumes, const std::vector<float>& tool_colors);
// generates gcode retractions geometry
static void _load_gcode_retractions(const GCodePreviewData& preview_data, GLVolumeCollection& volumes, bool use_VBOs);
// generates gcode unretractions geometry
static void _load_gcode_unretractions(const GCodePreviewData& preview_data, GLVolumeCollection& volumes, bool use_VBOs);
// sets gcode geometry visibility according to user selection
static void _update_gcode_volumes_visibility(const GCodePreviewData& preview_data, GLVolumeCollection& volumes);
// generates the legend texture in dependence of the current shown view type
static void _generate_legend_texture(const GCodePreviewData& preview_data, const std::vector<float>& tool_colors);
// generates objects and wipe tower geometry
static void _load_shells(const Print& print, GLVolumeCollection& volumes, bool use_VBOs);
static void thick_lines_to_verts(const Lines& lines, const std::vector<double>& widths, const std::vector<double>& heights, bool closed, double top_z, GLVolume& volume);
static void thick_lines_to_verts(const Lines3& lines, const std::vector<double>& widths, const std::vector<double>& heights, bool closed, GLVolume& volume);
static void extrusionentity_to_verts(const ExtrusionPath& extrusion_path, float print_z, GLVolume& volume);
static void extrusionentity_to_verts(const ExtrusionPath& extrusion_path, float print_z, const Point& copy, GLVolume& volume);
static void extrusionentity_to_verts(const ExtrusionLoop& extrusion_loop, float print_z, const Point& copy, GLVolume& volume);
static void extrusionentity_to_verts(const ExtrusionMultiPath& extrusion_multi_path, float print_z, const Point& copy, GLVolume& volume);
static void extrusionentity_to_verts(const ExtrusionEntityCollection& extrusion_entity_collection, float print_z, const Point& copy, GLVolume& volume);
static void extrusionentity_to_verts(const ExtrusionEntity* extrusion_entity, float print_z, const Point& copy, GLVolume& volume);
static void polyline3_to_verts(const Polyline3& polyline, double width, double height, GLVolume& volume);
static void point3_to_verts(const Point3& point, double width, double height, GLVolume& volume);
};
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,639 @@
#ifndef slic3r_GLCanvas3D_hpp_
#define slic3r_GLCanvas3D_hpp_
#include "../../slic3r/GUI/3DScene.hpp"
#include "../../slic3r/GUI/GLTexture.hpp"
class wxTimer;
class wxSizeEvent;
class wxIdleEvent;
class wxKeyEvent;
class wxMouseEvent;
class wxTimerEvent;
class wxPaintEvent;
namespace Slic3r {
class GLShader;
class ExPolygon;
namespace GUI {
class GLGizmoBase;
class GeometryBuffer
{
std::vector<float> m_vertices;
std::vector<float> m_tex_coords;
public:
bool set_from_triangles(const Polygons& triangles, float z, bool generate_tex_coords);
bool set_from_lines(const Lines& lines, float z);
const float* get_vertices() const;
const float* get_tex_coords() const;
unsigned int get_vertices_count() const;
};
class Size
{
int m_width;
int m_height;
public:
Size();
Size(int width, int height);
int get_width() const;
void set_width(int width);
int get_height() const;
void set_height(int height);
};
class Rect
{
float m_left;
float m_top;
float m_right;
float m_bottom;
public:
Rect();
Rect(float left, float top, float right, float bottom);
float get_left() const;
void set_left(float left);
float get_top() const;
void set_top(float top);
float get_right() const;
void set_right(float right);
float get_bottom() const;
void set_bottom(float bottom);
};
class GLCanvas3D
{
struct GCodePreviewVolumeIndex
{
enum EType
{
Extrusion,
Travel,
Retraction,
Unretraction,
Shell,
Num_Geometry_Types
};
struct FirstVolume
{
EType type;
unsigned int flag;
// Index of the first volume in a GLVolumeCollection.
unsigned int id;
FirstVolume(EType type, unsigned int flag, unsigned int id) : type(type), flag(flag), id(id) {}
};
std::vector<FirstVolume> first_volumes;
void reset() { first_volumes.clear(); }
};
public:
struct Camera
{
enum EType : unsigned char
{
Unknown,
// Perspective,
Ortho,
Num_types
};
EType type;
float zoom;
float phi;
// float distance;
Pointf3 target;
private:
float m_theta;
public:
Camera();
std::string get_type_as_string() const;
float get_theta() const;
void set_theta(float theta);
};
class Bed
{
public:
enum EType : unsigned char
{
MK2,
MK3,
Custom,
Num_Types
};
private:
EType m_type;
Pointfs m_shape;
BoundingBoxf3 m_bounding_box;
Polygon m_polygon;
GeometryBuffer m_triangles;
GeometryBuffer m_gridlines;
mutable GLTexture m_top_texture;
mutable GLTexture m_bottom_texture;
public:
Bed();
bool is_prusa() const;
bool is_custom() const;
const Pointfs& get_shape() const;
void set_shape(const Pointfs& shape);
const BoundingBoxf3& get_bounding_box() const;
bool contains(const Point& point) const;
Point point_projection(const Point& point) const;
void render(float theta) const;
private:
void _calc_bounding_box();
void _calc_triangles(const ExPolygon& poly);
void _calc_gridlines(const ExPolygon& poly, const BoundingBox& bed_bbox);
EType _detect_type() const;
void _render_mk2(float theta) const;
void _render_mk3(float theta) const;
void _render_prusa(float theta) const;
void _render_custom() const;
static bool _are_equal(const Pointfs& bed_1, const Pointfs& bed_2);
};
struct Axes
{
Pointf3 origin;
float length;
Axes();
void render(bool depth_test) const;
};
class CuttingPlane
{
float m_z;
GeometryBuffer m_lines;
public:
CuttingPlane();
bool set(float z, const ExPolygons& polygons);
void render(const BoundingBoxf3& bb) const;
private:
void _render_plane(const BoundingBoxf3& bb) const;
void _render_contour() const;
};
class Shader
{
GLShader* m_shader;
public:
Shader();
~Shader();
bool init(const std::string& vertex_shader_filename, const std::string& fragment_shader_filename);
bool is_initialized() const;
bool start_using() const;
void stop_using() const;
void set_uniform(const std::string& name, float value) const;
const GLShader* get_shader() const;
private:
void _reset();
};
class LayersEditing
{
public:
enum EState : unsigned char
{
Unknown,
Editing,
Completed,
Num_States
};
private:
bool m_use_legacy_opengl;
bool m_enabled;
Shader m_shader;
unsigned int m_z_texture_id;
mutable GLTexture m_tooltip_texture;
mutable GLTexture m_reset_texture;
public:
EState state;
float band_width;
float strength;
int last_object_id;
float last_z;
unsigned int last_action;
LayersEditing();
~LayersEditing();
bool init(const std::string& vertex_shader_filename, const std::string& fragment_shader_filename);
bool is_allowed() const;
void set_use_legacy_opengl(bool use_legacy_opengl);
bool is_enabled() const;
void set_enabled(bool enabled);
unsigned int get_z_texture_id() const;
void render(const GLCanvas3D& canvas, const PrintObject& print_object, const GLVolume& volume) const;
int get_shader_program_id() const;
static float get_cursor_z_relative(const GLCanvas3D& canvas);
static bool bar_rect_contains(const GLCanvas3D& canvas, float x, float y);
static bool reset_rect_contains(const GLCanvas3D& canvas, float x, float y);
static Rect get_bar_rect_screen(const GLCanvas3D& canvas);
static Rect get_reset_rect_screen(const GLCanvas3D& canvas);
static Rect get_bar_rect_viewport(const GLCanvas3D& canvas);
static Rect get_reset_rect_viewport(const GLCanvas3D& canvas);
private:
bool _is_initialized() const;
void _render_tooltip_texture(const GLCanvas3D& canvas, const Rect& bar_rect, const Rect& reset_rect) const;
void _render_reset_texture(const Rect& reset_rect) const;
void _render_active_object_annotations(const GLCanvas3D& canvas, const GLVolume& volume, const PrintObject& print_object, const Rect& bar_rect) const;
void _render_profile(const PrintObject& print_object, const Rect& bar_rect) const;
};
struct Mouse
{
struct Drag
{
static const Point Invalid_2D_Point;
static const Pointf3 Invalid_3D_Point;
Point start_position_2D;
Pointf3 start_position_3D;
Vectorf3 volume_center_offset;
int volume_idx;
public:
Drag();
};
bool dragging;
Pointf position;
Drag drag;
Mouse();
void set_start_position_2D_as_invalid();
void set_start_position_3D_as_invalid();
bool is_start_position_2D_defined() const;
bool is_start_position_3D_defined() const;
};
class Gizmos
{
static const float OverlayOffsetX;
static const float OverlayGapY;
public:
enum EType : unsigned char
{
Undefined,
Scale,
Rotate,
Num_Types
};
private:
bool m_enabled;
typedef std::map<EType, GLGizmoBase*> GizmosMap;
GizmosMap m_gizmos;
EType m_current;
bool m_dragging;
public:
Gizmos();
~Gizmos();
bool init();
bool is_enabled() const;
void set_enabled(bool enable);
void update_hover_state(const GLCanvas3D& canvas, const Pointf& mouse_pos);
void update_on_off_state(const GLCanvas3D& canvas, const Pointf& mouse_pos);
void reset_all_states();
void set_hover_id(int id);
bool overlay_contains_mouse(const GLCanvas3D& canvas, const Pointf& mouse_pos) const;
bool grabber_contains_mouse() const;
void update(const Pointf& mouse_pos);
void update_data(float scale);
bool is_running() const;
bool is_dragging() const;
void start_dragging();
void stop_dragging();
float get_scale() const;
void render(const GLCanvas3D& canvas, const BoundingBoxf3& box) const;
void render_current_gizmo_for_picking_pass(const BoundingBoxf3& box) const;
private:
void _reset();
void _render_overlay(const GLCanvas3D& canvas) const;
void _render_current_gizmo(const BoundingBoxf3& box) const;
float _get_total_overlay_height() const;
GLGizmoBase* _get_current() const;
};
private:
wxGLCanvas* m_canvas;
wxGLContext* m_context;
wxTimer* m_timer;
Camera m_camera;
Bed m_bed;
Axes m_axes;
CuttingPlane m_cutting_plane;
LayersEditing m_layers_editing;
Shader m_shader;
Mouse m_mouse;
mutable Gizmos m_gizmos;
mutable GLVolumeCollection m_volumes;
DynamicPrintConfig* m_config;
Print* m_print;
Model* m_model;
bool m_dirty;
// the active member has been introduced to overcome a bug in wxWidgets method IsShownOnScreen() which always return true
// when a window is inside a wxNotebook
bool m_active;
bool m_initialized;
bool m_use_VBOs;
bool m_force_zoom_to_bed_enabled;
bool m_apply_zoom_to_volumes_filter;
mutable int m_hover_volume_id;
bool m_warning_texture_enabled;
bool m_legend_texture_enabled;
bool m_picking_enabled;
bool m_moving_enabled;
bool m_shader_enabled;
bool m_multisample_allowed;
std::string m_color_by;
std::string m_select_by;
std::string m_drag_by;
bool m_reload_delayed;
std::vector<std::vector<int>> m_objects_volumes_idxs;
std::vector<int> m_objects_selections;
GCodePreviewVolumeIndex m_gcode_preview_volume_index;
PerlCallback m_on_viewport_changed_callback;
PerlCallback m_on_double_click_callback;
PerlCallback m_on_right_click_callback;
PerlCallback m_on_select_object_callback;
PerlCallback m_on_model_update_callback;
PerlCallback m_on_remove_object_callback;
PerlCallback m_on_arrange_callback;
PerlCallback m_on_rotate_object_left_callback;
PerlCallback m_on_rotate_object_right_callback;
PerlCallback m_on_scale_object_uniformly_callback;
PerlCallback m_on_increase_objects_callback;
PerlCallback m_on_decrease_objects_callback;
PerlCallback m_on_instance_moved_callback;
PerlCallback m_on_wipe_tower_moved_callback;
PerlCallback m_on_enable_action_buttons_callback;
PerlCallback m_on_gizmo_scale_uniformly_callback;
public:
GLCanvas3D(wxGLCanvas* canvas, wxGLContext* context);
~GLCanvas3D();
bool init(bool useVBOs, bool use_legacy_opengl);
bool set_current();
void set_active(bool active);
unsigned int get_volumes_count() const;
void reset_volumes();
void deselect_volumes();
void select_volume(unsigned int id);
void update_volumes_selection(const std::vector<int>& selections);
bool check_volumes_outside_state(const DynamicPrintConfig* config) const;
bool move_volume_up(unsigned int id);
bool move_volume_down(unsigned int id);
void set_objects_selections(const std::vector<int>& selections);
void set_config(DynamicPrintConfig* config);
void set_print(Print* print);
void set_model(Model* model);
// 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();
void set_axes_length(float length);
void set_cutting_plane(float z, const ExPolygons& polygons);
void set_color_by(const std::string& value);
void set_select_by(const std::string& value);
void set_drag_by(const std::string& value);
float get_camera_zoom() const;
BoundingBoxf3 volumes_bounding_box() const;
bool is_layers_editing_enabled() const;
bool is_layers_editing_allowed() const;
bool is_shader_enabled() const;
bool is_reload_delayed() const;
void enable_layers_editing(bool enable);
void enable_warning_texture(bool enable);
void enable_legend_texture(bool enable);
void enable_picking(bool enable);
void enable_moving(bool enable);
void enable_gizmos(bool enable);
void enable_shader(bool enable);
void enable_force_zoom_to_bed(bool enable);
void allow_multisample(bool allow);
void zoom_to_bed();
void zoom_to_volumes();
void select_view(const std::string& direction);
void set_viewport_from_scene(const GLCanvas3D& other);
void update_volumes_colors_by_extruder();
void render();
std::vector<double> get_current_print_zs(bool active_only) const;
void set_toolpaths_range(double low, double high);
std::vector<int> load_object(const ModelObject& model_object, int obj_idx, std::vector<int> instance_idxs);
std::vector<int> load_object(const Model& model, int obj_idx);
void reload_scene(bool force);
// Create 3D thick extrusion lines for a skirt and brim.
// Adds a new Slic3r::GUI::3DScene::Volume to volumes.
void load_print_toolpaths();
// Create 3D thick extrusion lines for object forming extrusions.
// Adds a new Slic3r::GUI::3DScene::Volume to $self->volumes,
// one for perimeters, one for infill and one for supports.
void load_print_object_toolpaths(const PrintObject& print_object, const std::vector<std::string>& str_tool_colors);
// Create 3D thick extrusion lines for wipe tower extrusions
void load_wipe_tower_toolpaths(const std::vector<std::string>& str_tool_colors);
void load_gcode_preview(const GCodePreviewData& preview_data, const std::vector<std::string>& str_tool_colors);
void register_on_viewport_changed_callback(void* callback);
void register_on_double_click_callback(void* callback);
void register_on_right_click_callback(void* callback);
void register_on_select_object_callback(void* callback);
void register_on_model_update_callback(void* callback);
void register_on_remove_object_callback(void* callback);
void register_on_arrange_callback(void* callback);
void register_on_rotate_object_left_callback(void* callback);
void register_on_rotate_object_right_callback(void* callback);
void register_on_scale_object_uniformly_callback(void* callback);
void register_on_increase_objects_callback(void* callback);
void register_on_decrease_objects_callback(void* callback);
void register_on_instance_moved_callback(void* callback);
void register_on_wipe_tower_moved_callback(void* callback);
void register_on_enable_action_buttons_callback(void* callback);
void register_on_gizmo_scale_uniformly_callback(void* callback);
void bind_event_handlers();
void unbind_event_handlers();
void on_size(wxSizeEvent& evt);
void on_idle(wxIdleEvent& evt);
void on_char(wxKeyEvent& evt);
void on_mouse_wheel(wxMouseEvent& evt);
void on_timer(wxTimerEvent& evt);
void on_mouse(wxMouseEvent& evt);
void on_paint(wxPaintEvent& evt);
void on_key_down(wxKeyEvent& evt);
Size get_canvas_size() const;
Point get_local_mouse_position() const;
private:
bool _is_shown_on_screen() const;
void _force_zoom_to_bed();
void _resize(unsigned int w, unsigned int h);
BoundingBoxf3 _max_bounding_box() const;
BoundingBoxf3 _selected_volumes_bounding_box() const;
void _zoom_to_bounding_box(const BoundingBoxf3& bbox);
float _get_zoom_to_bounding_box_factor(const BoundingBoxf3& bbox) const;
void _deregister_callbacks();
void _mark_volumes_for_layer_height() const;
void _refresh_if_shown_on_screen();
void _camera_tranform() const;
void _picking_pass() const;
void _render_background() const;
void _render_bed(float theta) const;
void _render_axes(bool depth_test) const;
void _render_objects() const;
void _render_cutting_plane() const;
void _render_warning_texture() const;
void _render_legend_texture() const;
void _render_layer_editing_overlay() const;
void _render_volumes(bool fake_colors) const;
void _render_gizmo() const;
float _get_layers_editing_cursor_z_relative() const;
void _perform_layer_editing_action(wxMouseEvent* evt = nullptr);
// Convert the screen space coordinate to an object space coordinate.
// If the Z screen space coordinate is not provided, a depth buffer value is substituted.
Pointf3 _mouse_to_3d(const Point& mouse_pos, float* z = nullptr);
// Convert the screen space coordinate to world coordinate on the bed.
Pointf3 _mouse_to_bed_3d(const Point& mouse_pos);
void _start_timer();
void _stop_timer();
int _get_first_selected_object_id() const;
// generates gcode extrusion paths geometry
void _load_gcode_extrusion_paths(const GCodePreviewData& preview_data, const std::vector<float>& tool_colors);
// generates gcode travel paths geometry
void _load_gcode_travel_paths(const GCodePreviewData& preview_data, const std::vector<float>& tool_colors);
bool _travel_paths_by_type(const GCodePreviewData& preview_data);
bool _travel_paths_by_feedrate(const GCodePreviewData& preview_data);
bool _travel_paths_by_tool(const GCodePreviewData& preview_data, const std::vector<float>& tool_colors);
// generates gcode retractions geometry
void _load_gcode_retractions(const GCodePreviewData& preview_data);
// generates gcode unretractions geometry
void _load_gcode_unretractions(const GCodePreviewData& preview_data);
// generates objects and wipe tower geometry
void _load_shells();
// sets gcode geometry visibility according to user selection
void _update_gcode_volumes_visibility(const GCodePreviewData& preview_data);
void _on_move(const std::vector<int>& volume_idxs);
void _on_select(int volume_idx);
void _update_gizmos_data();
static std::vector<float> _parse_colors(const std::vector<std::string>& colors);
};
} // namespace GUI
} // namespace Slic3r
#endif // slic3r_GLCanvas3D_hpp_

View file

@ -0,0 +1,707 @@
#include "GLCanvas3DManager.hpp"
#include "../../slic3r/GUI/GUI.hpp"
#include "../../slic3r/GUI/AppConfig.hpp"
#include "../../slic3r/GUI/GLCanvas3D.hpp"
#include <GL/glew.h>
#include <boost/algorithm/string/split.hpp>
#include <boost/algorithm/string/classification.hpp>
#include <wx/glcanvas.h>
#include <wx/timer.h>
#include <vector>
#include <string>
#include <iostream>
namespace Slic3r {
namespace GUI {
GLCanvas3DManager::GLInfo::GLInfo()
: version("")
, glsl_version("")
, vendor("")
, renderer("")
{
}
bool GLCanvas3DManager::GLInfo::detect()
{
const char* data = (const char*)::glGetString(GL_VERSION);
if (data == nullptr)
return false;
version = data;
data = (const char*)::glGetString(GL_SHADING_LANGUAGE_VERSION);
if (data == nullptr)
return false;
glsl_version = data;
data = (const char*)::glGetString(GL_VENDOR);
if (data == nullptr)
return false;
vendor = data;
data = (const char*)::glGetString(GL_RENDERER);
if (data == nullptr)
return false;
renderer = data;
return true;
}
bool GLCanvas3DManager::GLInfo::is_version_greater_or_equal_to(unsigned int major, unsigned int minor) const
{
std::vector<std::string> tokens;
boost::split(tokens, version, boost::is_any_of(" "), boost::token_compress_on);
if (tokens.empty())
return false;
std::vector<std::string> numbers;
boost::split(numbers, tokens[0], boost::is_any_of("."), boost::token_compress_on);
unsigned int gl_major = 0;
unsigned int gl_minor = 0;
if (numbers.size() > 0)
gl_major = ::atoi(numbers[0].c_str());
if (numbers.size() > 1)
gl_minor = ::atoi(numbers[1].c_str());
if (gl_major < major)
return false;
else if (gl_major > major)
return true;
else
return gl_minor >= minor;
}
std::string GLCanvas3DManager::GLInfo::to_string(bool format_as_html, bool extensions) const
{
std::stringstream out;
std::string h2_start = format_as_html ? "<b>" : "";
std::string h2_end = format_as_html ? "</b>" : "";
std::string b_start = format_as_html ? "<b>" : "";
std::string b_end = format_as_html ? "</b>" : "";
std::string line_end = format_as_html ? "<br>" : "\n";
out << h2_start << "OpenGL installation" << h2_end << line_end;
out << b_start << "GL version: " << b_end << version << line_end;
out << b_start << "Vendor: " << b_end << vendor << line_end;
out << b_start << "Renderer: " << b_end << renderer << line_end;
out << b_start << "GLSL version: " << b_end << glsl_version << line_end;
if (extensions)
{
out << h2_start << "Installed extensions:" << h2_end << line_end;
std::vector<std::string> extensions_list;
GLint num_extensions;
::glGetIntegerv(GL_NUM_EXTENSIONS, &num_extensions);
for (GLint i = 0; i < num_extensions; ++i)
{
const char* e = (const char*)::glGetStringi(GL_EXTENSIONS, i);
extensions_list.push_back(e);
}
std::sort(extensions_list.begin(), extensions_list.end());
for (const std::string& ext : extensions_list)
{
out << ext << line_end;
}
}
return out.str();
}
GLCanvas3DManager::GLCanvas3DManager()
: m_context(nullptr)
, m_gl_initialized(false)
, m_use_legacy_opengl(false)
, m_use_VBOs(false)
{
}
GLCanvas3DManager::~GLCanvas3DManager()
{
if (m_context != nullptr)
delete m_context;
}
bool GLCanvas3DManager::add(wxGLCanvas* canvas)
{
if (canvas == nullptr)
return false;
if (_get_canvas(canvas) != m_canvases.end())
return false;
if (m_context == nullptr)
{
m_context = new wxGLContext(canvas);
if (m_context == nullptr)
return false;
}
GLCanvas3D* canvas3D = new GLCanvas3D(canvas, m_context);
if (canvas3D == nullptr)
return false;
canvas3D->bind_event_handlers();
m_canvases.insert(CanvasesMap::value_type(canvas, canvas3D));
return true;
}
bool GLCanvas3DManager::remove(wxGLCanvas* canvas)
{
CanvasesMap::iterator it = _get_canvas(canvas);
if (it == m_canvases.end())
return false;
it->second->unbind_event_handlers();
delete it->second;
m_canvases.erase(it);
return true;
}
void GLCanvas3DManager::remove_all()
{
for (CanvasesMap::value_type& item : m_canvases)
{
item.second->unbind_event_handlers();
delete item.second;
}
m_canvases.clear();
}
unsigned int GLCanvas3DManager::count() const
{
return (unsigned int)m_canvases.size();
}
void GLCanvas3DManager::init_gl()
{
if (!m_gl_initialized)
{
glewInit();
if (m_gl_info.detect())
{
const AppConfig* config = GUI::get_app_config();
m_use_legacy_opengl = (config == nullptr) || (config->get("use_legacy_opengl") == "1");
m_use_VBOs = !m_use_legacy_opengl && m_gl_info.is_version_greater_or_equal_to(2, 0);
m_gl_initialized = true;
}
else
throw std::runtime_error(std::string("Unable to initialize OpenGL driver\n"));
}
}
std::string GLCanvas3DManager::get_gl_info(bool format_as_html, bool extensions) const
{
return m_gl_info.to_string(format_as_html, extensions);
}
bool GLCanvas3DManager::use_VBOs() const
{
return m_use_VBOs;
}
bool GLCanvas3DManager::init(wxGLCanvas* canvas)
{
CanvasesMap::const_iterator it = _get_canvas(canvas);
if (it != m_canvases.end())
return (it->second != nullptr) ? _init(*it->second) : false;
else
return false;
}
void GLCanvas3DManager::set_active(wxGLCanvas* canvas, bool active)
{
CanvasesMap::iterator it = _get_canvas(canvas);
if (it != m_canvases.end())
it->second->set_active(active);
}
unsigned int GLCanvas3DManager::get_volumes_count(wxGLCanvas* canvas) const
{
CanvasesMap::const_iterator it = _get_canvas(canvas);
return (it != m_canvases.end()) ? it->second->get_volumes_count() : 0;
}
void GLCanvas3DManager::reset_volumes(wxGLCanvas* canvas)
{
CanvasesMap::iterator it = _get_canvas(canvas);
if (it != m_canvases.end())
it->second->reset_volumes();
}
void GLCanvas3DManager::deselect_volumes(wxGLCanvas* canvas)
{
CanvasesMap::iterator it = _get_canvas(canvas);
if (it != m_canvases.end())
it->second->deselect_volumes();
}
void GLCanvas3DManager::select_volume(wxGLCanvas* canvas, unsigned int id)
{
CanvasesMap::iterator it = _get_canvas(canvas);
if (it != m_canvases.end())
it->second->select_volume(id);
}
void GLCanvas3DManager::update_volumes_selection(wxGLCanvas* canvas, const std::vector<int>& selections)
{
CanvasesMap::iterator it = _get_canvas(canvas);
if (it != m_canvases.end())
it->second->update_volumes_selection(selections);
}
bool GLCanvas3DManager::check_volumes_outside_state(wxGLCanvas* canvas, const DynamicPrintConfig* config) const
{
CanvasesMap::const_iterator it = _get_canvas(canvas);
return (it != m_canvases.end()) ? it->second->check_volumes_outside_state(config) : false;
}
bool GLCanvas3DManager::move_volume_up(wxGLCanvas* canvas, unsigned int id)
{
CanvasesMap::const_iterator it = _get_canvas(canvas);
return (it != m_canvases.end()) ? it->second->move_volume_up(id) : false;
}
bool GLCanvas3DManager::move_volume_down(wxGLCanvas* canvas, unsigned int id)
{
CanvasesMap::const_iterator it = _get_canvas(canvas);
return (it != m_canvases.end()) ? it->second->move_volume_down(id) : false;
}
void GLCanvas3DManager::set_objects_selections(wxGLCanvas* canvas, const std::vector<int>& selections)
{
CanvasesMap::iterator it = _get_canvas(canvas);
if (it != m_canvases.end())
it->second->set_objects_selections(selections);
}
void GLCanvas3DManager::set_config(wxGLCanvas* canvas, DynamicPrintConfig* config)
{
CanvasesMap::iterator it = _get_canvas(canvas);
if (it != m_canvases.end())
it->second->set_config(config);
}
void GLCanvas3DManager::set_print(wxGLCanvas* canvas, Print* print)
{
CanvasesMap::iterator it = _get_canvas(canvas);
if (it != m_canvases.end())
it->second->set_print(print);
}
void GLCanvas3DManager::set_model(wxGLCanvas* canvas, Model* model)
{
CanvasesMap::iterator it = _get_canvas(canvas);
if (it != m_canvases.end())
it->second->set_model(model);
}
void GLCanvas3DManager::set_bed_shape(wxGLCanvas* canvas, const Pointfs& shape)
{
CanvasesMap::iterator it = _get_canvas(canvas);
if (it != m_canvases.end())
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();
}
BoundingBoxf3 GLCanvas3DManager::get_volumes_bounding_box(wxGLCanvas* canvas)
{
CanvasesMap::const_iterator it = _get_canvas(canvas);
return (it != m_canvases.end()) ? it->second->volumes_bounding_box() : BoundingBoxf3();
}
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);
if (it != m_canvases.end())
it->second->set_cutting_plane(z, polygons);
}
void GLCanvas3DManager::set_color_by(wxGLCanvas* canvas, const std::string& value)
{
CanvasesMap::iterator it = _get_canvas(canvas);
if (it != m_canvases.end())
it->second->set_color_by(value);
}
void GLCanvas3DManager::set_select_by(wxGLCanvas* canvas, const std::string& value)
{
CanvasesMap::iterator it = _get_canvas(canvas);
if (it != m_canvases.end())
it->second->set_select_by(value);
}
void GLCanvas3DManager::set_drag_by(wxGLCanvas* canvas, const std::string& value)
{
CanvasesMap::iterator it = _get_canvas(canvas);
if (it != m_canvases.end())
it->second->set_drag_by(value);
}
bool GLCanvas3DManager::is_layers_editing_enabled(wxGLCanvas* canvas) const
{
CanvasesMap::const_iterator it = _get_canvas(canvas);
return (it != m_canvases.end()) ? it->second->is_layers_editing_enabled() : false;
}
bool GLCanvas3DManager::is_layers_editing_allowed(wxGLCanvas* canvas) const
{
CanvasesMap::const_iterator it = _get_canvas(canvas);
return (it != m_canvases.end()) ? it->second->is_layers_editing_allowed() : false;
}
bool GLCanvas3DManager::is_shader_enabled(wxGLCanvas* canvas) const
{
CanvasesMap::const_iterator it = _get_canvas(canvas);
return (it != m_canvases.end()) ? it->second->is_shader_enabled() : false;
}
bool GLCanvas3DManager::is_reload_delayed(wxGLCanvas* canvas) const
{
CanvasesMap::const_iterator it = _get_canvas(canvas);
return (it != m_canvases.end()) ? it->second->is_reload_delayed() : false;
}
void GLCanvas3DManager::enable_layers_editing(wxGLCanvas* canvas, bool enable)
{
CanvasesMap::iterator it = _get_canvas(canvas);
if (it != m_canvases.end())
it->second->enable_layers_editing(enable);
}
void GLCanvas3DManager::enable_warning_texture(wxGLCanvas* canvas, bool enable)
{
CanvasesMap::iterator it = _get_canvas(canvas);
if (it != m_canvases.end())
it->second->enable_warning_texture(enable);
}
void GLCanvas3DManager::enable_legend_texture(wxGLCanvas* canvas, bool enable)
{
CanvasesMap::iterator it = _get_canvas(canvas);
if (it != m_canvases.end())
it->second->enable_legend_texture(enable);
}
void GLCanvas3DManager::enable_picking(wxGLCanvas* canvas, bool enable)
{
CanvasesMap::iterator it = _get_canvas(canvas);
if (it != m_canvases.end())
it->second->enable_picking(enable);
}
void GLCanvas3DManager::enable_moving(wxGLCanvas* canvas, bool enable)
{
CanvasesMap::iterator it = _get_canvas(canvas);
if (it != m_canvases.end())
it->second->enable_moving(enable);
}
void GLCanvas3DManager::enable_gizmos(wxGLCanvas* canvas, bool enable)
{
CanvasesMap::iterator it = _get_canvas(canvas);
if (it != m_canvases.end())
it->second->enable_gizmos(enable);
}
void GLCanvas3DManager::enable_shader(wxGLCanvas* canvas, bool enable)
{
CanvasesMap::iterator it = _get_canvas(canvas);
if (it != m_canvases.end())
it->second->enable_shader(enable);
}
void GLCanvas3DManager::enable_force_zoom_to_bed(wxGLCanvas* canvas, bool enable)
{
CanvasesMap::iterator it = _get_canvas(canvas);
if (it != m_canvases.end())
it->second->enable_force_zoom_to_bed(enable);
}
void GLCanvas3DManager::allow_multisample(wxGLCanvas* canvas, bool allow)
{
CanvasesMap::iterator it = _get_canvas(canvas);
if (it != m_canvases.end())
it->second->allow_multisample(allow);
}
void GLCanvas3DManager::zoom_to_bed(wxGLCanvas* canvas)
{
CanvasesMap::iterator it = _get_canvas(canvas);
if (it != m_canvases.end())
it->second->zoom_to_bed();
}
void GLCanvas3DManager::zoom_to_volumes(wxGLCanvas* canvas)
{
CanvasesMap::iterator it = _get_canvas(canvas);
if (it != m_canvases.end())
it->second->zoom_to_volumes();
}
void GLCanvas3DManager::select_view(wxGLCanvas* canvas, const std::string& direction)
{
CanvasesMap::iterator it = _get_canvas(canvas);
if (it != m_canvases.end())
it->second->select_view(direction);
}
void GLCanvas3DManager::set_viewport_from_scene(wxGLCanvas* canvas, wxGLCanvas* other)
{
CanvasesMap::iterator it = _get_canvas(canvas);
if (it != m_canvases.end())
{
CanvasesMap::iterator other_it = _get_canvas(other);
if (other_it != m_canvases.end())
it->second->set_viewport_from_scene(*other_it->second);
}
}
void GLCanvas3DManager::update_volumes_colors_by_extruder(wxGLCanvas* canvas)
{
CanvasesMap::const_iterator it = _get_canvas(canvas);
if (it != m_canvases.end())
it->second->update_volumes_colors_by_extruder();
}
void GLCanvas3DManager::render(wxGLCanvas* canvas) const
{
CanvasesMap::const_iterator it = _get_canvas(canvas);
if (it != m_canvases.end())
it->second->render();
}
std::vector<double> GLCanvas3DManager::get_current_print_zs(wxGLCanvas* canvas, bool active_only) const
{
CanvasesMap::const_iterator it = _get_canvas(canvas);
return (it != m_canvases.end()) ? it->second->get_current_print_zs(active_only) : std::vector<double>();
}
void GLCanvas3DManager::set_toolpaths_range(wxGLCanvas* canvas, double low, double high)
{
CanvasesMap::iterator it = _get_canvas(canvas);
if (it != m_canvases.end())
it->second->set_toolpaths_range(low, high);
}
std::vector<int> GLCanvas3DManager::load_object(wxGLCanvas* canvas, const ModelObject* model_object, int obj_idx, std::vector<int> instance_idxs)
{
if (model_object == nullptr)
return std::vector<int>();
CanvasesMap::const_iterator it = _get_canvas(canvas);
return (it != m_canvases.end()) ? it->second->load_object(*model_object, obj_idx, instance_idxs) : std::vector<int>();
}
std::vector<int> GLCanvas3DManager::load_object(wxGLCanvas* canvas, const Model* model, int obj_idx)
{
if (model == nullptr)
return std::vector<int>();
CanvasesMap::const_iterator it = _get_canvas(canvas);
return (it != m_canvases.end()) ? it->second->load_object(*model, obj_idx) : std::vector<int>();
}
void GLCanvas3DManager::reload_scene(wxGLCanvas* canvas, bool force)
{
CanvasesMap::iterator it = _get_canvas(canvas);
if (it != m_canvases.end())
it->second->reload_scene(force);
}
void GLCanvas3DManager::load_print_toolpaths(wxGLCanvas* canvas)
{
CanvasesMap::iterator it = _get_canvas(canvas);
if (it != m_canvases.end())
it->second->load_print_toolpaths();
}
void GLCanvas3DManager::load_print_object_toolpaths(wxGLCanvas* canvas, const PrintObject* print_object, const std::vector<std::string>& tool_colors)
{
if (print_object == nullptr)
return;
CanvasesMap::iterator it = _get_canvas(canvas);
if (it != m_canvases.end())
it->second->load_print_object_toolpaths(*print_object, tool_colors);
}
void GLCanvas3DManager::load_wipe_tower_toolpaths(wxGLCanvas* canvas, const std::vector<std::string>& str_tool_colors)
{
CanvasesMap::iterator it = _get_canvas(canvas);
if (it != m_canvases.end())
it->second->load_wipe_tower_toolpaths(str_tool_colors);
}
void GLCanvas3DManager::load_gcode_preview(wxGLCanvas* canvas, const GCodePreviewData* preview_data, const std::vector<std::string>& str_tool_colors)
{
if (preview_data == nullptr)
return;
CanvasesMap::iterator it = _get_canvas(canvas);
if (it != m_canvases.end())
it->second->load_gcode_preview(*preview_data, str_tool_colors);
}
void GLCanvas3DManager::register_on_viewport_changed_callback(wxGLCanvas* canvas, void* callback)
{
CanvasesMap::iterator it = _get_canvas(canvas);
if (it != m_canvases.end())
it->second->register_on_viewport_changed_callback(callback);
}
void GLCanvas3DManager::register_on_double_click_callback(wxGLCanvas* canvas, void* callback)
{
CanvasesMap::iterator it = _get_canvas(canvas);
if (it != m_canvases.end())
it->second->register_on_double_click_callback(callback);
}
void GLCanvas3DManager::register_on_right_click_callback(wxGLCanvas* canvas, void* callback)
{
CanvasesMap::iterator it = _get_canvas(canvas);
if (it != m_canvases.end())
it->second->register_on_right_click_callback(callback);
}
void GLCanvas3DManager::register_on_select_object_callback(wxGLCanvas* canvas, void* callback)
{
CanvasesMap::iterator it = _get_canvas(canvas);
if (it != m_canvases.end())
it->second->register_on_select_object_callback(callback);
}
void GLCanvas3DManager::register_on_model_update_callback(wxGLCanvas* canvas, void* callback)
{
CanvasesMap::iterator it = _get_canvas(canvas);
if (it != m_canvases.end())
it->second->register_on_model_update_callback(callback);
}
void GLCanvas3DManager::register_on_remove_object_callback(wxGLCanvas* canvas, void* callback)
{
CanvasesMap::iterator it = _get_canvas(canvas);
if (it != m_canvases.end())
it->second->register_on_remove_object_callback(callback);
}
void GLCanvas3DManager::register_on_arrange_callback(wxGLCanvas* canvas, void* callback)
{
CanvasesMap::iterator it = _get_canvas(canvas);
if (it != m_canvases.end())
it->second->register_on_arrange_callback(callback);
}
void GLCanvas3DManager::register_on_rotate_object_left_callback(wxGLCanvas* canvas, void* callback)
{
CanvasesMap::iterator it = _get_canvas(canvas);
if (it != m_canvases.end())
it->second->register_on_rotate_object_left_callback(callback);
}
void GLCanvas3DManager::register_on_rotate_object_right_callback(wxGLCanvas* canvas, void* callback)
{
CanvasesMap::iterator it = _get_canvas(canvas);
if (it != m_canvases.end())
it->second->register_on_rotate_object_right_callback(callback);
}
void GLCanvas3DManager::register_on_scale_object_uniformly_callback(wxGLCanvas* canvas, void* callback)
{
CanvasesMap::iterator it = _get_canvas(canvas);
if (it != m_canvases.end())
it->second->register_on_scale_object_uniformly_callback(callback);
}
void GLCanvas3DManager::register_on_increase_objects_callback(wxGLCanvas* canvas, void* callback)
{
CanvasesMap::iterator it = _get_canvas(canvas);
if (it != m_canvases.end())
it->second->register_on_increase_objects_callback(callback);
}
void GLCanvas3DManager::register_on_decrease_objects_callback(wxGLCanvas* canvas, void* callback)
{
CanvasesMap::iterator it = _get_canvas(canvas);
if (it != m_canvases.end())
it->second->register_on_decrease_objects_callback(callback);
}
void GLCanvas3DManager::register_on_instance_moved_callback(wxGLCanvas* canvas, void* callback)
{
CanvasesMap::iterator it = _get_canvas(canvas);
if (it != m_canvases.end())
it->second->register_on_instance_moved_callback(callback);
}
void GLCanvas3DManager::register_on_wipe_tower_moved_callback(wxGLCanvas* canvas, void* callback)
{
CanvasesMap::iterator it = _get_canvas(canvas);
if (it != m_canvases.end())
it->second->register_on_wipe_tower_moved_callback(callback);
}
void GLCanvas3DManager::register_on_enable_action_buttons_callback(wxGLCanvas* canvas, void* callback)
{
CanvasesMap::iterator it = _get_canvas(canvas);
if (it != m_canvases.end())
it->second->register_on_enable_action_buttons_callback(callback);
}
void GLCanvas3DManager::register_on_gizmo_scale_uniformly_callback(wxGLCanvas* canvas, void* callback)
{
CanvasesMap::iterator it = _get_canvas(canvas);
if (it != m_canvases.end())
it->second->register_on_gizmo_scale_uniformly_callback(callback);
}
GLCanvas3DManager::CanvasesMap::iterator GLCanvas3DManager::_get_canvas(wxGLCanvas* canvas)
{
return (canvas == nullptr) ? m_canvases.end() : m_canvases.find(canvas);
}
GLCanvas3DManager::CanvasesMap::const_iterator GLCanvas3DManager::_get_canvas(wxGLCanvas* canvas) const
{
return (canvas == nullptr) ? m_canvases.end() : m_canvases.find(canvas);
}
bool GLCanvas3DManager::_init(GLCanvas3D& canvas)
{
if (!m_gl_initialized)
init_gl();
return canvas.init(m_use_VBOs, m_use_legacy_opengl);
}
} // namespace GUI
} // namespace Slic3r

View file

@ -0,0 +1,167 @@
#ifndef slic3r_GLCanvas3DManager_hpp_
#define slic3r_GLCanvas3DManager_hpp_
#include "../../libslic3r/BoundingBox.hpp"
#include <map>
#include <vector>
class wxGLCanvas;
class wxGLContext;
namespace Slic3r {
class DynamicPrintConfig;
class Print;
class Model;
class ExPolygon;
typedef std::vector<ExPolygon> ExPolygons;
class ModelObject;
class PrintObject;
class GCodePreviewData;
namespace GUI {
class GLCanvas3D;
class GLCanvas3DManager
{
struct GLInfo
{
std::string version;
std::string glsl_version;
std::string vendor;
std::string renderer;
GLInfo();
bool detect();
bool is_version_greater_or_equal_to(unsigned int major, unsigned int minor) const;
std::string to_string(bool format_as_html, bool extensions) const;
};
typedef std::map<wxGLCanvas*, GLCanvas3D*> CanvasesMap;
wxGLContext* m_context;
CanvasesMap m_canvases;
GLInfo m_gl_info;
bool m_gl_initialized;
bool m_use_legacy_opengl;
bool m_use_VBOs;
public:
GLCanvas3DManager();
~GLCanvas3DManager();
bool add(wxGLCanvas* canvas);
bool remove(wxGLCanvas* canvas);
void remove_all();
unsigned int count() const;
void init_gl();
std::string get_gl_info(bool format_as_html, bool extensions) const;
bool use_VBOs() const;
bool layer_editing_allowed() const;
bool init(wxGLCanvas* canvas);
void set_active(wxGLCanvas* canvas, bool active);
unsigned int get_volumes_count(wxGLCanvas* canvas) const;
void reset_volumes(wxGLCanvas* canvas);
void deselect_volumes(wxGLCanvas* canvas);
void select_volume(wxGLCanvas* canvas, unsigned int id);
void update_volumes_selection(wxGLCanvas* canvas, const std::vector<int>& selections);
bool check_volumes_outside_state(wxGLCanvas* canvas, const DynamicPrintConfig* config) const;
bool move_volume_up(wxGLCanvas* canvas, unsigned int id);
bool move_volume_down(wxGLCanvas* canvas, unsigned int id);
void set_objects_selections(wxGLCanvas* canvas, const std::vector<int>& selections);
void set_config(wxGLCanvas* canvas, DynamicPrintConfig* config);
void set_print(wxGLCanvas* canvas, Print* print);
void set_model(wxGLCanvas* canvas, Model* model);
void set_bed_shape(wxGLCanvas* canvas, const Pointfs& shape);
void set_auto_bed_shape(wxGLCanvas* canvas);
BoundingBoxf3 get_volumes_bounding_box(wxGLCanvas* canvas);
void set_axes_length(wxGLCanvas* canvas, float length);
void set_cutting_plane(wxGLCanvas* canvas, float z, const ExPolygons& polygons);
void set_color_by(wxGLCanvas* canvas, const std::string& value);
void set_select_by(wxGLCanvas* canvas, const std::string& value);
void set_drag_by(wxGLCanvas* canvas, const std::string& value);
bool is_layers_editing_enabled(wxGLCanvas* canvas) const;
bool is_layers_editing_allowed(wxGLCanvas* canvas) const;
bool is_shader_enabled(wxGLCanvas* canvas) const;
bool is_reload_delayed(wxGLCanvas* canvas) const;
void enable_layers_editing(wxGLCanvas* canvas, bool enable);
void enable_warning_texture(wxGLCanvas* canvas, bool enable);
void enable_legend_texture(wxGLCanvas* canvas, bool enable);
void enable_picking(wxGLCanvas* canvas, bool enable);
void enable_moving(wxGLCanvas* canvas, bool enable);
void enable_gizmos(wxGLCanvas* canvas, bool enable);
void enable_shader(wxGLCanvas* canvas, bool enable);
void enable_force_zoom_to_bed(wxGLCanvas* canvas, bool enable);
void allow_multisample(wxGLCanvas* canvas, bool allow);
void zoom_to_bed(wxGLCanvas* canvas);
void zoom_to_volumes(wxGLCanvas* canvas);
void select_view(wxGLCanvas* canvas, const std::string& direction);
void set_viewport_from_scene(wxGLCanvas* canvas, wxGLCanvas* other);
void update_volumes_colors_by_extruder(wxGLCanvas* canvas);
void render(wxGLCanvas* canvas) const;
std::vector<double> get_current_print_zs(wxGLCanvas* canvas, bool active_only) const;
void set_toolpaths_range(wxGLCanvas* canvas, double low, double high);
std::vector<int> load_object(wxGLCanvas* canvas, const ModelObject* model_object, int obj_idx, std::vector<int> instance_idxs);
std::vector<int> load_object(wxGLCanvas* canvas, const Model* model, int obj_idx);
void reload_scene(wxGLCanvas* canvas, bool force);
void load_print_toolpaths(wxGLCanvas* canvas);
void load_print_object_toolpaths(wxGLCanvas* canvas, const PrintObject* print_object, const std::vector<std::string>& tool_colors);
void load_wipe_tower_toolpaths(wxGLCanvas* canvas, const std::vector<std::string>& str_tool_colors);
void load_gcode_preview(wxGLCanvas* canvas, const GCodePreviewData* preview_data, const std::vector<std::string>& str_tool_colors);
void register_on_viewport_changed_callback(wxGLCanvas* canvas, void* callback);
void register_on_double_click_callback(wxGLCanvas* canvas, void* callback);
void register_on_right_click_callback(wxGLCanvas* canvas, void* callback);
void register_on_select_object_callback(wxGLCanvas* canvas, void* callback);
void register_on_model_update_callback(wxGLCanvas* canvas, void* callback);
void register_on_remove_object_callback(wxGLCanvas* canvas, void* callback);
void register_on_arrange_callback(wxGLCanvas* canvas, void* callback);
void register_on_rotate_object_left_callback(wxGLCanvas* canvas, void* callback);
void register_on_rotate_object_right_callback(wxGLCanvas* canvas, void* callback);
void register_on_scale_object_uniformly_callback(wxGLCanvas* canvas, void* callback);
void register_on_increase_objects_callback(wxGLCanvas* canvas, void* callback);
void register_on_decrease_objects_callback(wxGLCanvas* canvas, void* callback);
void register_on_instance_moved_callback(wxGLCanvas* canvas, void* callback);
void register_on_wipe_tower_moved_callback(wxGLCanvas* canvas, void* callback);
void register_on_enable_action_buttons_callback(wxGLCanvas* canvas, void* callback);
void register_on_gizmo_scale_uniformly_callback(wxGLCanvas* canvas, void* callback);
private:
CanvasesMap::iterator _get_canvas(wxGLCanvas* canvas);
CanvasesMap::const_iterator _get_canvas(wxGLCanvas* canvas) const;
bool _init(GLCanvas3D& canvas);
};
} // namespace GUI
} // namespace Slic3r
#endif // slic3r_GLCanvas3DManager_hpp_

View file

@ -0,0 +1,454 @@
#include "GLGizmo.hpp"
#include "../../libslic3r/Utils.hpp"
#include "../../libslic3r/BoundingBox.hpp"
#include <GL/glew.h>
#include <iostream>
namespace Slic3r {
namespace GUI {
const float GLGizmoBase::Grabber::HalfSize = 2.0f;
const float GLGizmoBase::Grabber::HoverOffset = 0.5f;
const float GLGizmoBase::BaseColor[3] = { 1.0f, 1.0f, 1.0f };
const float GLGizmoBase::HighlightColor[3] = { 1.0f, 0.38f, 0.0f };
GLGizmoBase::Grabber::Grabber()
: center(Pointf(0.0, 0.0))
, angle_z(0.0f)
{
color[0] = 1.0f;
color[1] = 1.0f;
color[2] = 1.0f;
}
void GLGizmoBase::Grabber::render(bool hover) const
{
float min_x = -HalfSize;
float max_x = +HalfSize;
float min_y = -HalfSize;
float max_y = +HalfSize;
::glColor3f((GLfloat)color[0], (GLfloat)color[1], (GLfloat)color[2]);
float angle_z_in_deg = angle_z * 180.0f / (float)PI;
::glPushMatrix();
::glTranslatef((GLfloat)center.x, (GLfloat)center.y, 0.0f);
::glRotatef((GLfloat)angle_z_in_deg, 0.0f, 0.0f, 1.0f);
::glDisable(GL_CULL_FACE);
::glBegin(GL_TRIANGLES);
::glVertex3f((GLfloat)min_x, (GLfloat)min_y, 0.0f);
::glVertex3f((GLfloat)max_x, (GLfloat)min_y, 0.0f);
::glVertex3f((GLfloat)max_x, (GLfloat)max_y, 0.0f);
::glVertex3f((GLfloat)max_x, (GLfloat)max_y, 0.0f);
::glVertex3f((GLfloat)min_x, (GLfloat)max_y, 0.0f);
::glVertex3f((GLfloat)min_x, (GLfloat)min_y, 0.0f);
::glEnd();
::glEnable(GL_CULL_FACE);
if (hover)
{
min_x -= HoverOffset;
max_x += HoverOffset;
min_y -= HoverOffset;
max_y += HoverOffset;
::glBegin(GL_LINE_LOOP);
::glVertex3f((GLfloat)min_x, (GLfloat)min_y, 0.0f);
::glVertex3f((GLfloat)max_x, (GLfloat)min_y, 0.0f);
::glVertex3f((GLfloat)max_x, (GLfloat)max_y, 0.0f);
::glVertex3f((GLfloat)min_x, (GLfloat)max_y, 0.0f);
::glEnd();
}
::glPopMatrix();
}
GLGizmoBase::GLGizmoBase()
: m_state(Off)
, m_hover_id(-1)
{
}
GLGizmoBase::~GLGizmoBase()
{
}
bool GLGizmoBase::init()
{
return on_init();
}
GLGizmoBase::EState GLGizmoBase::get_state() const
{
return m_state;
}
void GLGizmoBase::set_state(GLGizmoBase::EState state)
{
m_state = state;
}
unsigned int GLGizmoBase::get_textures_id() const
{
return m_textures[m_state].get_id();
}
int GLGizmoBase::get_textures_size() const
{
return m_textures[Off].get_width();
}
int GLGizmoBase::get_hover_id() const
{
return m_hover_id;
}
void GLGizmoBase::set_hover_id(int id)
{
if (id < (int)m_grabbers.size())
m_hover_id = id;
}
void GLGizmoBase::start_dragging()
{
on_start_dragging();
}
void GLGizmoBase::update(const Pointf& mouse_pos)
{
if (m_hover_id != -1)
on_update(mouse_pos);
}
void GLGizmoBase::render(const BoundingBoxf3& box) const
{
on_render(box);
}
void GLGizmoBase::render_for_picking(const BoundingBoxf3& box) const
{
on_render_for_picking(box);
}
void GLGizmoBase::on_start_dragging()
{
}
void GLGizmoBase::render_grabbers() const
{
for (unsigned int i = 0; i < (unsigned int)m_grabbers.size(); ++i)
{
m_grabbers[i].render(m_hover_id == i);
}
}
const float GLGizmoRotate::Offset = 5.0f;
const unsigned int GLGizmoRotate::CircleResolution = 64;
const unsigned int GLGizmoRotate::AngleResolution = 64;
const unsigned int GLGizmoRotate::ScaleStepsCount = 60;
const float GLGizmoRotate::ScaleStepRad = 2.0f * (float)PI / GLGizmoRotate::ScaleStepsCount;
const unsigned int GLGizmoRotate::ScaleLongEvery = 5;
const float GLGizmoRotate::ScaleLongTooth = 2.0f;
const float GLGizmoRotate::ScaleShortTooth = 1.0f;
const unsigned int GLGizmoRotate::SnapRegionsCount = 8;
const float GLGizmoRotate::GrabberOffset = 5.0f;
GLGizmoRotate::GLGizmoRotate()
: GLGizmoBase()
, m_angle_z(0.0f)
, m_center(Pointf(0.0, 0.0))
, m_radius(0.0f)
{
}
bool GLGizmoRotate::on_init()
{
std::string path = resources_dir() + "/icons/overlay/";
std::string filename = path + "rotate_off.png";
if (!m_textures[Off].load_from_file(filename, false))
return false;
filename = path + "rotate_hover.png";
if (!m_textures[Hover].load_from_file(filename, false))
return false;
filename = path + "rotate_on.png";
if (!m_textures[On].load_from_file(filename, false))
return false;
m_grabbers.push_back(Grabber());
return true;
}
void GLGizmoRotate::on_update(const Pointf& mouse_pos)
{
Vectorf orig_dir(1.0, 0.0);
Vectorf new_dir = normalize(mouse_pos - m_center);
coordf_t theta = ::acos(clamp(-1.0, 1.0, dot(new_dir, orig_dir)));
if (cross(orig_dir, new_dir) < 0.0)
theta = 2.0 * (coordf_t)PI - theta;
if (length(m_center.vector_to(mouse_pos)) < 2.0 * (double)m_radius / 3.0)
{
coordf_t step = 2.0 * (coordf_t)PI / (coordf_t)SnapRegionsCount;
theta = step * (coordf_t)std::round(theta / step);
}
if (theta == 2.0 * (coordf_t)PI)
theta = 0.0;
m_angle_z = (float)theta;
}
void GLGizmoRotate::on_render(const BoundingBoxf3& box) const
{
::glDisable(GL_LIGHTING);
::glDisable(GL_DEPTH_TEST);
const Pointf3& size = box.size();
m_center = box.center();
m_radius = Offset + ::sqrt(sqr(0.5f * size.x) + sqr(0.5f * size.y));
::glLineWidth(2.0f);
::glColor3fv(BaseColor);
_render_circle();
_render_scale();
_render_snap_radii();
_render_reference_radius();
::glColor3fv(HighlightColor);
_render_angle_z();
_render_grabber();
}
void GLGizmoRotate::on_render_for_picking(const BoundingBoxf3& box) const
{
::glDisable(GL_LIGHTING);
::glDisable(GL_DEPTH_TEST);
m_grabbers[0].color[0] = 1.0f;
m_grabbers[0].color[1] = 1.0f;
m_grabbers[0].color[2] = 254.0f / 255.0f;
render_grabbers();
}
void GLGizmoRotate::_render_circle() const
{
::glBegin(GL_LINE_LOOP);
for (unsigned int i = 0; i < ScaleStepsCount; ++i)
{
float angle = (float)i * ScaleStepRad;
float x = m_center.x + ::cos(angle) * m_radius;
float y = m_center.y + ::sin(angle) * m_radius;
::glVertex3f((GLfloat)x, (GLfloat)y, 0.0f);
}
::glEnd();
}
void GLGizmoRotate::_render_scale() const
{
float out_radius_long = m_radius + ScaleLongTooth;
float out_radius_short = m_radius + ScaleShortTooth;
::glBegin(GL_LINES);
for (unsigned int i = 0; i < ScaleStepsCount; ++i)
{
float angle = (float)i * ScaleStepRad;
float cosa = ::cos(angle);
float sina = ::sin(angle);
float in_x = m_center.x + cosa * m_radius;
float in_y = m_center.y + sina * m_radius;
float out_x = (i % ScaleLongEvery == 0) ? m_center.x + cosa * out_radius_long : m_center.x + cosa * out_radius_short;
float out_y = (i % ScaleLongEvery == 0) ? m_center.y + sina * out_radius_long : m_center.y + sina * out_radius_short;
::glVertex3f((GLfloat)in_x, (GLfloat)in_y, 0.0f);
::glVertex3f((GLfloat)out_x, (GLfloat)out_y, 0.0f);
}
::glEnd();
}
void GLGizmoRotate::_render_snap_radii() const
{
float step = 2.0f * (float)PI / (float)SnapRegionsCount;
float in_radius = m_radius / 3.0f;
float out_radius = 2.0f * in_radius;
::glBegin(GL_LINES);
for (unsigned int i = 0; i < SnapRegionsCount; ++i)
{
float angle = (float)i * step;
float cosa = ::cos(angle);
float sina = ::sin(angle);
float in_x = m_center.x + cosa * in_radius;
float in_y = m_center.y + sina * in_radius;
float out_x = m_center.x + cosa * out_radius;
float out_y = m_center.y + sina * out_radius;
::glVertex3f((GLfloat)in_x, (GLfloat)in_y, 0.0f);
::glVertex3f((GLfloat)out_x, (GLfloat)out_y, 0.0f);
}
::glEnd();
}
void GLGizmoRotate::_render_reference_radius() const
{
::glBegin(GL_LINES);
::glVertex3f((GLfloat)m_center.x, (GLfloat)m_center.y, 0.0f);
::glVertex3f((GLfloat)m_center.x + m_radius + GrabberOffset, (GLfloat)m_center.y, 0.0f);
::glEnd();
}
void GLGizmoRotate::_render_angle_z() const
{
float step_angle = m_angle_z / AngleResolution;
float ex_radius = m_radius + GrabberOffset;
::glBegin(GL_LINE_STRIP);
for (unsigned int i = 0; i <= AngleResolution; ++i)
{
float angle = (float)i * step_angle;
float x = m_center.x + ::cos(angle) * ex_radius;
float y = m_center.y + ::sin(angle) * ex_radius;
::glVertex3f((GLfloat)x, (GLfloat)y, 0.0f);
}
::glEnd();
}
void GLGizmoRotate::_render_grabber() const
{
float grabber_radius = m_radius + GrabberOffset;
m_grabbers[0].center.x = m_center.x + ::cos(m_angle_z) * grabber_radius;
m_grabbers[0].center.y = m_center.y + ::sin(m_angle_z) * grabber_radius;
m_grabbers[0].angle_z = m_angle_z;
::glColor3fv(BaseColor);
::glBegin(GL_LINES);
::glVertex3f((GLfloat)m_center.x, (GLfloat)m_center.y, 0.0f);
::glVertex3f((GLfloat)m_grabbers[0].center.x, (GLfloat)m_grabbers[0].center.y, 0.0f);
::glEnd();
::memcpy((void*)m_grabbers[0].color, (const void*)HighlightColor, 3 * sizeof(float));
render_grabbers();
}
const float GLGizmoScale::Offset = 5.0f;
GLGizmoScale::GLGizmoScale()
: GLGizmoBase()
, m_scale(1.0f)
, m_starting_scale(1.0f)
{
}
float GLGizmoScale::get_scale() const
{
return m_scale;
}
void GLGizmoScale::set_scale(float scale)
{
m_starting_scale = scale;
}
bool GLGizmoScale::on_init()
{
std::string path = resources_dir() + "/icons/overlay/";
std::string filename = path + "scale_off.png";
if (!m_textures[Off].load_from_file(filename, false))
return false;
filename = path + "scale_hover.png";
if (!m_textures[Hover].load_from_file(filename, false))
return false;
filename = path + "scale_on.png";
if (!m_textures[On].load_from_file(filename, false))
return false;
for (unsigned int i = 0; i < 4; ++i)
{
m_grabbers.push_back(Grabber());
}
return true;
}
void GLGizmoScale::on_start_dragging()
{
if (m_hover_id != -1)
m_starting_drag_position = m_grabbers[m_hover_id].center;
}
void GLGizmoScale::on_update(const Pointf& mouse_pos)
{
Pointf center(0.5 * (m_grabbers[1].center.x + m_grabbers[0].center.x), 0.5 * (m_grabbers[3].center.y + m_grabbers[0].center.y));
coordf_t orig_len = length(m_starting_drag_position - center);
coordf_t new_len = length(mouse_pos - center);
coordf_t ratio = (orig_len != 0.0) ? new_len / orig_len : 1.0;
m_scale = m_starting_scale * (float)ratio;
}
void GLGizmoScale::on_render(const BoundingBoxf3& box) const
{
::glDisable(GL_LIGHTING);
::glDisable(GL_DEPTH_TEST);
coordf_t min_x = box.min.x - (coordf_t)Offset;
coordf_t max_x = box.max.x + (coordf_t)Offset;
coordf_t min_y = box.min.y - (coordf_t)Offset;
coordf_t max_y = box.max.y + (coordf_t)Offset;
m_grabbers[0].center.x = min_x;
m_grabbers[0].center.y = min_y;
m_grabbers[1].center.x = max_x;
m_grabbers[1].center.y = min_y;
m_grabbers[2].center.x = max_x;
m_grabbers[2].center.y = max_y;
m_grabbers[3].center.x = min_x;
m_grabbers[3].center.y = max_y;
::glLineWidth(2.0f);
::glColor3fv(BaseColor);
// draw outline
::glBegin(GL_LINE_LOOP);
for (unsigned int i = 0; i < 4; ++i)
{
::glVertex3f((GLfloat)m_grabbers[i].center.x, (GLfloat)m_grabbers[i].center.y, 0.0f);
}
::glEnd();
// draw grabbers
for (unsigned int i = 0; i < 4; ++i)
{
::memcpy((void*)m_grabbers[i].color, (const void*)HighlightColor, 3 * sizeof(float));
}
render_grabbers();
}
void GLGizmoScale::on_render_for_picking(const BoundingBoxf3& box) const
{
static const GLfloat INV_255 = 1.0f / 255.0f;
::glDisable(GL_LIGHTING);
::glDisable(GL_DEPTH_TEST);
for (unsigned int i = 0; i < 4; ++i)
{
m_grabbers[i].color[0] = 1.0f;
m_grabbers[i].color[1] = 1.0f;
m_grabbers[i].color[2] = (254.0f - (float)i) * INV_255;
}
render_grabbers();
}
} // namespace GUI
} // namespace Slic3r

View file

@ -0,0 +1,145 @@
#ifndef slic3r_GLGizmo_hpp_
#define slic3r_GLGizmo_hpp_
#include "../../slic3r/GUI/GLTexture.hpp"
#include "../../libslic3r/Point.hpp"
#include <vector>
namespace Slic3r {
class BoundingBoxf3;
class Pointf3;
namespace GUI {
class GLGizmoBase
{
protected:
static const float BaseColor[3];
static const float HighlightColor[3];
struct Grabber
{
static const float HalfSize;
static const float HoverOffset;
Pointf center;
float angle_z;
float color[3];
Grabber();
void render(bool hover) const;
};
public:
enum EState
{
Off,
Hover,
On,
Num_States
};
protected:
EState m_state;
// textures are assumed to be square and all with the same size in pixels, no internal check is done
GLTexture m_textures[Num_States];
int m_hover_id;
mutable std::vector<Grabber> m_grabbers;
public:
GLGizmoBase();
virtual ~GLGizmoBase();
bool init();
EState get_state() const;
void set_state(EState state);
unsigned int get_textures_id() const;
int get_textures_size() const;
int get_hover_id() const;
void set_hover_id(int id);
void start_dragging();
void update(const Pointf& mouse_pos);
void render(const BoundingBoxf3& box) const;
void render_for_picking(const BoundingBoxf3& box) const;
protected:
virtual bool on_init() = 0;
virtual void on_start_dragging();
virtual void on_update(const Pointf& mouse_pos) = 0;
virtual void on_render(const BoundingBoxf3& box) const = 0;
virtual void on_render_for_picking(const BoundingBoxf3& box) const = 0;
void render_grabbers() const;
};
class GLGizmoRotate : public GLGizmoBase
{
static const float Offset;
static const unsigned int CircleResolution;
static const unsigned int AngleResolution;
static const unsigned int ScaleStepsCount;
static const float ScaleStepRad;
static const unsigned int ScaleLongEvery;
static const float ScaleLongTooth;
static const float ScaleShortTooth;
static const unsigned int SnapRegionsCount;
static const float GrabberOffset;
float m_angle_z;
mutable Pointf m_center;
mutable float m_radius;
public:
GLGizmoRotate();
protected:
virtual bool on_init();
virtual void on_update(const Pointf& mouse_pos);
virtual void on_render(const BoundingBoxf3& box) const;
virtual void on_render_for_picking(const BoundingBoxf3& box) const;
private:
void _render_circle() const;
void _render_scale() const;
void _render_snap_radii() const;
void _render_reference_radius() const;
void _render_angle_z() const;
void _render_grabber() const;
};
class GLGizmoScale : public GLGizmoBase
{
static const float Offset;
float m_scale;
Pointf m_starting_drag_position;
float m_starting_scale;
public:
GLGizmoScale();
float get_scale() const;
void set_scale(float scale);
protected:
virtual bool on_init();
virtual void on_start_dragging();
virtual void on_update(const Pointf& mouse_pos);
virtual void on_render(const BoundingBoxf3& box) const;
virtual void on_render_for_picking(const BoundingBoxf3& box) const;
};
} // namespace GUI
} // namespace Slic3r
#endif // slic3r_GLGizmo_hpp_

View file

@ -2,6 +2,9 @@
#include "GLShader.hpp"
#include "../../libslic3r/Utils.hpp"
#include <boost/nowide/fstream.hpp>
#include <string>
#include <utility>
#include <assert.h>
@ -22,7 +25,7 @@ inline std::string gl_get_string_safe(GLenum param)
return std::string(value ? value : "N/A");
}
bool GLShader::load(const char *fragment_shader, const char *vertex_shader)
bool GLShader::load_from_text(const char *fragment_shader, const char *vertex_shader)
{
std::string gl_version = gl_get_string_safe(GL_VERSION);
int major = atoi(gl_version.c_str());
@ -123,6 +126,41 @@ bool GLShader::load(const char *fragment_shader, const char *vertex_shader)
return true;
}
bool GLShader::load_from_file(const char* fragment_shader_filename, const char* vertex_shader_filename)
{
const std::string& path = resources_dir() + "/shaders/";
boost::nowide::ifstream vs(path + std::string(vertex_shader_filename), boost::nowide::ifstream::binary);
if (!vs.good())
return false;
vs.seekg(0, vs.end);
int file_length = vs.tellg();
vs.seekg(0, vs.beg);
std::string vertex_shader(file_length, '\0');
vs.read(const_cast<char*>(vertex_shader.data()), file_length);
if (!vs.good())
return false;
vs.close();
boost::nowide::ifstream fs(path + std::string(fragment_shader_filename), boost::nowide::ifstream::binary);
if (!fs.good())
return false;
fs.seekg(0, fs.end);
file_length = fs.tellg();
fs.seekg(0, fs.beg);
std::string fragment_shader(file_length, '\0');
fs.read(const_cast<char*>(fragment_shader.data()), file_length);
if (!fs.good())
return false;
fs.close();
return load_from_text(fragment_shader.c_str(), vertex_shader.c_str());
}
void GLShader::release()
{
if (this->shader_program_id) {

View file

@ -16,7 +16,9 @@ public:
{}
~GLShader();
bool load(const char *fragment_shader, const char *vertex_shader);
bool load_from_text(const char *fragment_shader, const char *vertex_shader);
bool load_from_file(const char* fragment_shader_filename, const char* vertex_shader_filename);
void release();
int get_attrib_location(const char *name) const;

View file

@ -0,0 +1,185 @@
#include "GLTexture.hpp"
#include <GL/glew.h>
#include <wx/image.h>
#include <vector>
#include <algorithm>
namespace Slic3r {
namespace GUI {
GLTexture::GLTexture()
: m_id(0)
, m_width(0)
, m_height(0)
, m_source("")
{
}
GLTexture::~GLTexture()
{
reset();
}
bool GLTexture::load_from_file(const std::string& filename, bool generate_mipmaps)
{
reset();
// Load a PNG with an alpha channel.
wxImage image;
if (!image.LoadFile(filename, wxBITMAP_TYPE_PNG))
{
reset();
return false;
}
m_width = image.GetWidth();
m_height = image.GetHeight();
int n_pixels = m_width * m_height;
if (n_pixels <= 0)
{
reset();
return false;
}
// Get RGB & alpha raw data from wxImage, pack them into an array.
unsigned char* img_rgb = image.GetData();
if (img_rgb == nullptr)
{
reset();
return false;
}
unsigned char* img_alpha = image.GetAlpha();
std::vector<unsigned char> data(n_pixels * 4, 0);
for (int i = 0; i < n_pixels; ++i)
{
int data_id = i * 4;
int img_id = i * 3;
data[data_id + 0] = img_rgb[img_id + 0];
data[data_id + 1] = img_rgb[img_id + 1];
data[data_id + 2] = img_rgb[img_id + 2];
data[data_id + 3] = (img_alpha != nullptr) ? img_alpha[i] : 255;
}
// sends data to gpu
::glGenTextures(1, &m_id);
::glBindTexture(GL_TEXTURE_2D, m_id);
::glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, (GLsizei)m_width, (GLsizei)m_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, (const void*)data.data());
if (generate_mipmaps)
{
// we manually generate mipmaps because glGenerateMipmap() function is not reliable on all graphics cards
_generate_mipmaps(image);
::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
}
else
{
::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1);
}
::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
::glBindTexture(GL_TEXTURE_2D, 0);
m_source = filename;
return true;
}
void GLTexture::reset()
{
if (m_id != 0)
::glDeleteTextures(1, &m_id);
m_id = 0;
m_width = 0;
m_height = 0;
m_source = "";
}
unsigned int GLTexture::get_id() const
{
return m_id;
}
int GLTexture::get_width() const
{
return m_width;
}
int GLTexture::get_height() const
{
return m_height;
}
const std::string& GLTexture::get_source() const
{
return m_source;
}
void GLTexture::render_texture(unsigned int tex_id, float left, float right, float bottom, float top)
{
::glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
::glDisable(GL_LIGHTING);
::glEnable(GL_BLEND);
::glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
::glEnable(GL_TEXTURE_2D);
::glBindTexture(GL_TEXTURE_2D, (GLuint)tex_id);
::glBegin(GL_QUADS);
::glTexCoord2d(0.0f, 1.0f); ::glVertex3f(left, bottom, 0.0f);
::glTexCoord2d(1.0f, 1.0f); ::glVertex3f(right, bottom, 0.0f);
::glTexCoord2d(1.0f, 0.0f); ::glVertex3f(right, top, 0.0f);
::glTexCoord2d(0.0f, 0.0f); ::glVertex3f(left, top, 0.0f);
::glEnd();
::glBindTexture(GL_TEXTURE_2D, 0);
::glDisable(GL_TEXTURE_2D);
::glDisable(GL_BLEND);
::glEnable(GL_LIGHTING);
}
void GLTexture::_generate_mipmaps(wxImage& image)
{
int w = image.GetWidth();
int h = image.GetHeight();
GLint level = 0;
std::vector<unsigned char> data(w * h * 4, 0);
while ((w > 1) && (h > 1))
{
++level;
w = std::max(w / 2, 1);
h = std::max(h / 2, 1);
int n_pixels = w * h;
image = image.ResampleBicubic(w, h);
unsigned char* img_rgb = image.GetData();
unsigned char* img_alpha = image.GetAlpha();
data.resize(n_pixels * 4);
for (int i = 0; i < n_pixels; ++i)
{
int data_id = i * 4;
int img_id = i * 3;
data[data_id + 0] = img_rgb[img_id + 0];
data[data_id + 1] = img_rgb[img_id + 1];
data[data_id + 2] = img_rgb[img_id + 2];
data[data_id + 3] = (img_alpha != nullptr) ? img_alpha[i] : 255;
}
::glTexImage2D(GL_TEXTURE_2D, level, GL_RGBA8, (GLsizei)w, (GLsizei)h, 0, GL_RGBA, GL_UNSIGNED_BYTE, (const void*)data.data());
}
}
} // namespace GUI
} // namespace Slic3r

View file

@ -0,0 +1,41 @@
#ifndef slic3r_GLTexture_hpp_
#define slic3r_GLTexture_hpp_
#include <string>
class wxImage;
namespace Slic3r {
namespace GUI {
class GLTexture
{
private:
unsigned int m_id;
int m_width;
int m_height;
std::string m_source;
public:
GLTexture();
~GLTexture();
bool load_from_file(const std::string& filename, bool generate_mipmaps);
void reset();
unsigned int get_id() const;
int get_width() const;
int get_height() const;
const std::string& get_source() const;
static void render_texture(unsigned int tex_id, float left, float right, float bottom, float top);
private:
void _generate_mipmaps(wxImage& image);
};
} // namespace GUI
} // namespace Slic3r
#endif // slic3r_GLTexture_hpp_

View file

@ -8,7 +8,8 @@
GLShader();
~GLShader();
bool load(const char *fragment_shader, const char *vertex_shader);
bool load_from_text(const char *fragment_shader, const char *vertex_shader);
bool load_from_file(const char *fragment_shader, const char *vertex_shader);
void release();
int get_attrib_location(const char *name) const;
@ -92,9 +93,6 @@
int count()
%code{% RETVAL = THIS->volumes.size(); %};
std::vector<double> get_current_print_zs(bool active_only)
%code{% RETVAL = THIS->get_current_print_zs(active_only); %};
void set_range(double low, double high);
void render_VBOs() const;
@ -155,11 +153,457 @@ GLVolumeCollection::arrayref()
%package{Slic3r::GUI::_3DScene};
%{
std::string
get_gl_info(format_as_html, extensions)
bool format_as_html;
bool extensions;
CODE:
RETVAL = _3DScene::get_gl_info(format_as_html, extensions);
OUTPUT:
RETVAL
bool
use_VBOs()
CODE:
RETVAL = _3DScene::use_VBOs();
OUTPUT:
RETVAL
bool
add_canvas(canvas)
SV *canvas;
CODE:
RETVAL = _3DScene::add_canvas((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"));
OUTPUT:
RETVAL
bool
remove_canvas(canvas)
SV *canvas;
CODE:
RETVAL = _3DScene::remove_canvas((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"));
OUTPUT:
RETVAL
void
_glew_init()
remove_all_canvases()
CODE:
_3DScene::_glew_init();
_3DScene::remove_all_canvases();
void
set_active(canvas, active)
SV *canvas;
bool active;
CODE:
_3DScene::set_active((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"), active);
unsigned int
get_volumes_count(canvas)
SV *canvas;
CODE:
RETVAL = _3DScene::get_volumes_count((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"));
OUTPUT:
RETVAL
void
reset_volumes(canvas)
SV *canvas;
CODE:
_3DScene::reset_volumes((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"));
void
deselect_volumes(canvas)
SV *canvas;
CODE:
_3DScene::deselect_volumes((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"));
void
select_volume(canvas, id)
SV *canvas;
unsigned int id;
CODE:
_3DScene::select_volume((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"), id);
void
update_volumes_selection(canvas, selections)
SV *canvas;
std::vector<int> selections;
CODE:
_3DScene::update_volumes_selection((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"), selections);
bool
check_volumes_outside_state(canvas, config)
SV *canvas;
DynamicPrintConfig *config;
CODE:
RETVAL = _3DScene::check_volumes_outside_state((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"), config);
OUTPUT:
RETVAL
bool
move_volume_up(canvas, id)
SV *canvas;
unsigned int id;
CODE:
RETVAL = _3DScene::move_volume_up((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"), id);
OUTPUT:
RETVAL
bool
move_volume_down(canvas, id)
SV *canvas;
unsigned int id;
CODE:
RETVAL = _3DScene::move_volume_down((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"), id);
OUTPUT:
RETVAL
void
set_objects_selections(canvas, selections)
SV *canvas;
std::vector<int> selections;
CODE:
_3DScene::set_objects_selections((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"), selections);
void
set_config(canvas, config)
SV *canvas;
DynamicPrintConfig *config;
CODE:
_3DScene::set_config((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"), config);
void
set_print(canvas, print)
SV *canvas;
Print *print;
CODE:
_3DScene::set_print((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"), print);
void
set_model(canvas, model)
SV *canvas;
Model *model;
CODE:
_3DScene::set_model((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"), model);
void
set_bed_shape(canvas, shape)
SV *canvas;
Pointfs shape;
CODE:
_3DScene::set_bed_shape((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"), shape);
void
set_auto_bed_shape(canvas)
SV *canvas;
CODE:
_3DScene::set_auto_bed_shape((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"));
Clone<BoundingBoxf3>
get_volumes_bounding_box(canvas)
SV *canvas;
CODE:
RETVAL = _3DScene::get_volumes_bounding_box((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;
float z;
ExPolygons polygons;
CODE:
_3DScene::set_cutting_plane((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"), z, polygons);
void
set_color_by(canvas, value)
SV *canvas;
std::string value;
CODE:
_3DScene::set_color_by((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"), value);
void
set_select_by(canvas, value)
SV *canvas;
std::string value;
CODE:
_3DScene::set_select_by((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"), value);
void
set_drag_by(canvas, value)
SV *canvas;
std::string value;
CODE:
_3DScene::set_drag_by((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"), value);
bool
is_layers_editing_enabled(canvas)
SV *canvas;
CODE:
RETVAL = _3DScene::is_layers_editing_enabled((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"));
OUTPUT:
RETVAL
bool
is_layers_editing_allowed(canvas)
SV *canvas;
CODE:
RETVAL = _3DScene::is_layers_editing_allowed((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"));
OUTPUT:
RETVAL
bool
is_shader_enabled(canvas)
SV *canvas;
CODE:
RETVAL = _3DScene::is_shader_enabled((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"));
OUTPUT:
RETVAL
bool
is_reload_delayed(canvas)
SV *canvas;
CODE:
RETVAL = _3DScene::is_reload_delayed((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"));
OUTPUT:
RETVAL
void
enable_layers_editing(canvas, enable)
SV *canvas;
bool enable;
CODE:
_3DScene::enable_layers_editing((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"), enable);
void
enable_warning_texture(canvas, enable)
SV *canvas;
bool enable;
CODE:
_3DScene::enable_warning_texture((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"), enable);
void
enable_legend_texture(canvas, enable)
SV *canvas;
bool enable;
CODE:
_3DScene::enable_legend_texture((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"), enable);
void
enable_picking(canvas, enable)
SV *canvas;
bool enable;
CODE:
_3DScene::enable_picking((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"), enable);
void
enable_moving(canvas, enable)
SV *canvas;
bool enable;
CODE:
_3DScene::enable_moving((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"), enable);
void
enable_gizmos(canvas, enable)
SV *canvas;
bool enable;
CODE:
_3DScene::enable_gizmos((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"), enable);
void
enable_shader(canvas, enable)
SV *canvas;
bool enable;
CODE:
_3DScene::enable_shader((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"), enable);
void
enable_force_zoom_to_bed(canvas, enable)
SV *canvas;
bool enable;
CODE:
_3DScene::enable_force_zoom_to_bed((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"), enable);
void
allow_multisample(canvas, allow)
SV *canvas;
bool allow;
CODE:
_3DScene::allow_multisample((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"), allow);
void
zoom_to_bed(canvas)
SV *canvas;
CODE:
_3DScene::zoom_to_bed((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"));
void
zoom_to_volumes(canvas)
SV *canvas;
CODE:
_3DScene::zoom_to_volumes((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"));
void
select_view(canvas, direction)
SV *canvas;
std::string direction;
CODE:
_3DScene::select_view((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"), direction);
void
set_viewport_from_scene(canvas, other)
SV *canvas;
SV *other;
CODE:
_3DScene::set_viewport_from_scene((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"), (wxGLCanvas*)wxPli_sv_2_object(aTHX_ other, "Wx::GLCanvas"));
void
update_volumes_colors_by_extruder(canvas)
SV *canvas;
CODE:
_3DScene::update_volumes_colors_by_extruder((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"));
void
render(canvas)
SV *canvas;
CODE:
_3DScene::render((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"));
std::vector<double>
get_current_print_zs(canvas, active_only)
SV *canvas;
bool active_only;
CODE:
RETVAL = _3DScene::get_current_print_zs((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"), active_only);
OUTPUT:
RETVAL
void
set_toolpaths_range(canvas, low, high)
SV *canvas;
double low;
double high;
CODE:
_3DScene::set_toolpaths_range((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"), low, high);
void
register_on_viewport_changed_callback(canvas, callback)
SV *canvas;
SV *callback;
CODE:
_3DScene::register_on_viewport_changed_callback((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"), (void*)callback);
void
register_on_double_click_callback(canvas, callback)
SV *canvas;
SV *callback;
CODE:
_3DScene::register_on_double_click_callback((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"), (void*)callback);
void
register_on_right_click_callback(canvas, callback)
SV *canvas;
SV *callback;
CODE:
_3DScene::register_on_right_click_callback((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"), (void*)callback);
void
register_on_select_object_callback(canvas, callback)
SV *canvas;
SV *callback;
CODE:
_3DScene::register_on_select_object_callback((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"), (void*)callback);
void
register_on_model_update_callback(canvas, callback)
SV *canvas;
SV *callback;
CODE:
_3DScene::register_on_model_update_callback((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"), (void*)callback);
void
register_on_remove_object_callback(canvas, callback)
SV *canvas;
SV *callback;
CODE:
_3DScene::register_on_remove_object_callback((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"), (void*)callback);
void
register_on_arrange_callback(canvas, callback)
SV *canvas;
SV *callback;
CODE:
_3DScene::register_on_arrange_callback((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"), (void*)callback);
void
register_on_rotate_object_left_callback(canvas, callback)
SV *canvas;
SV *callback;
CODE:
_3DScene::register_on_rotate_object_left_callback((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"), (void*)callback);
void
register_on_rotate_object_right_callback(canvas, callback)
SV *canvas;
SV *callback;
CODE:
_3DScene::register_on_rotate_object_right_callback((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"), (void*)callback);
void
register_on_scale_object_uniformly_callback(canvas, callback)
SV *canvas;
SV *callback;
CODE:
_3DScene::register_on_scale_object_uniformly_callback((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"), (void*)callback);
void
register_on_increase_objects_callback(canvas, callback)
SV *canvas;
SV *callback;
CODE:
_3DScene::register_on_increase_objects_callback((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"), (void*)callback);
void
register_on_decrease_objects_callback(canvas, callback)
SV *canvas;
SV *callback;
CODE:
_3DScene::register_on_decrease_objects_callback((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"), (void*)callback);
void
register_on_instance_moved_callback(canvas, callback)
SV *canvas;
SV *callback;
CODE:
_3DScene::register_on_instance_moved_callback((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"), (void*)callback);
void
register_on_wipe_tower_moved_callback(canvas, callback)
SV *canvas;
SV *callback;
CODE:
_3DScene::register_on_wipe_tower_moved_callback((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"), (void*)callback);
void
register_on_enable_action_buttons_callback(canvas, callback)
SV *canvas;
SV *callback;
CODE:
_3DScene::register_on_enable_action_buttons_callback((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"), (void*)callback);
void
register_on_gizmo_scale_uniformly_callback(canvas, callback)
SV *canvas;
SV *callback;
CODE:
_3DScene::register_on_gizmo_scale_uniformly_callback((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"), (void*)callback);
unsigned int
finalize_legend_texture()
@ -218,41 +662,61 @@ reset_warning_texture()
CODE:
_3DScene::reset_warning_texture();
void
_load_print_toolpaths(print, volumes, tool_colors, use_VBOs)
Print *print;
GLVolumeCollection *volumes;
std::vector<std::string> tool_colors;
int use_VBOs;
std::vector<int>
load_model_object(canvas, model_object, obj_idx, instance_idxs)
SV *canvas;
ModelObject *model_object;
int obj_idx;
std::vector<int> instance_idxs;
CODE:
_3DScene::_load_print_toolpaths(print, volumes, tool_colors, use_VBOs != 0);
RETVAL = _3DScene::load_object((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"), model_object, obj_idx, instance_idxs);
OUTPUT:
RETVAL
void
_load_print_object_toolpaths(print_object, volumes, tool_colors, use_VBOs)
PrintObject *print_object;
GLVolumeCollection *volumes;
std::vector<std::string> tool_colors;
int use_VBOs;
std::vector<int>
load_model(canvas, model, obj_idx)
SV *canvas;
Model *model;
int obj_idx;
CODE:
_3DScene::_load_print_object_toolpaths(print_object, volumes, tool_colors, use_VBOs != 0);
RETVAL = _3DScene::load_object((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"), model, obj_idx);
OUTPUT:
RETVAL
void
_load_wipe_tower_toolpaths(print, volumes, tool_colors, use_VBOs)
Print *print;
GLVolumeCollection *volumes;
std::vector<std::string> tool_colors;
int use_VBOs;
reload_scene(canvas, force)
SV *canvas;
bool force;
CODE:
_3DScene::_load_wipe_tower_toolpaths(print, volumes, tool_colors, use_VBOs != 0);
_3DScene::reload_scene((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"), force);
void
load_print_toolpaths(canvas)
SV *canvas;
CODE:
_3DScene::load_print_toolpaths((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"));
void
load_gcode_preview(print, preview_data, volumes, str_tool_colors, use_VBOs)
Print *print;
load_print_object_toolpaths(canvas, print_object, tool_colors)
SV *canvas;
PrintObject *print_object;
std::vector<std::string> tool_colors;
CODE:
_3DScene::load_print_object_toolpaths((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"), print_object, tool_colors);
void
load_wipe_tower_toolpaths(canvas, tool_colors)
SV *canvas;
std::vector<std::string> tool_colors;
CODE:
_3DScene::load_wipe_tower_toolpaths((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"), tool_colors);
void
load_gcode_preview(canvas, preview_data, str_tool_colors)
SV *canvas;
GCodePreviewData *preview_data;
GLVolumeCollection *volumes;
std::vector<std::string> str_tool_colors;
int use_VBOs;
CODE:
_3DScene::load_gcode_preview(print, preview_data, volumes, str_tool_colors, use_VBOs != 0);
_3DScene::load_gcode_preview((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"), preview_data, str_tool_colors);
%}

View file

@ -52,6 +52,9 @@ _constant()
int region_count()
%code%{ RETVAL = THIS->print()->regions.size(); %};
int region_volumes_count()
%code%{ RETVAL = THIS->region_volumes.size(); %};
Ref<Print> print();
Ref<ModelObject> model_object();
Ref<StaticPrintConfig> config()
@ -119,15 +122,6 @@ _constant()
RETVAL.push_back(slicing_params.layer_height);
%};
void adjust_layer_height_profile(coordf_t z, coordf_t layer_thickness_delta, coordf_t band_width, int action)
%code%{
THIS->update_layer_height_profile(THIS->model_object()->layer_height_profile);
adjust_layer_height_profile(
THIS->slicing_parameters(), THIS->model_object()->layer_height_profile, z, layer_thickness_delta, band_width, LayerHeightEditActionType(action));
THIS->model_object()->layer_height_profile_valid = true;
THIS->layer_height_profile_valid = false;
%};
void reset_layer_height_profile();
int ptr()