mirror of
https://github.com/SoftFever/OrcaSlicer.git
synced 2025-08-04 04:24:04 -06:00
Merge branch 'master' of https://github.com/prusa3d/Slic3r
This commit is contained in:
commit
7a30dd250a
38 changed files with 784 additions and 711 deletions
|
@ -386,58 +386,6 @@ void GLVolume::render() const
|
|||
::glPopMatrix();
|
||||
}
|
||||
|
||||
void GLVolume::render_using_layer_height() const
|
||||
{
|
||||
if (!is_active)
|
||||
return;
|
||||
|
||||
GLint current_program_id;
|
||||
glGetIntegerv(GL_CURRENT_PROGRAM, ¤t_program_id);
|
||||
|
||||
if ((layer_height_texture_data.shader_id > 0) && (layer_height_texture_data.shader_id != current_program_id))
|
||||
glUseProgram(layer_height_texture_data.shader_id);
|
||||
|
||||
GLint z_to_texture_row_id = (layer_height_texture_data.shader_id > 0) ? glGetUniformLocation(layer_height_texture_data.shader_id, "z_to_texture_row") : -1;
|
||||
GLint z_texture_row_to_normalized_id = (layer_height_texture_data.shader_id > 0) ? glGetUniformLocation(layer_height_texture_data.shader_id, "z_texture_row_to_normalized") : -1;
|
||||
GLint z_cursor_id = (layer_height_texture_data.shader_id > 0) ? glGetUniformLocation(layer_height_texture_data.shader_id, "z_cursor") : -1;
|
||||
GLint z_cursor_band_width_id = (layer_height_texture_data.shader_id > 0) ? glGetUniformLocation(layer_height_texture_data.shader_id, "z_cursor_band_width") : -1;
|
||||
GLint world_matrix_id = (layer_height_texture_data.shader_id > 0) ? glGetUniformLocation(layer_height_texture_data.shader_id, "volume_world_matrix") : -1;
|
||||
|
||||
if (z_to_texture_row_id >= 0)
|
||||
glUniform1f(z_to_texture_row_id, (GLfloat)layer_height_texture_z_to_row_id());
|
||||
|
||||
if (z_texture_row_to_normalized_id >= 0)
|
||||
glUniform1f(z_texture_row_to_normalized_id, (GLfloat)(1.0f / layer_height_texture_height()));
|
||||
|
||||
if (z_cursor_id >= 0)
|
||||
glUniform1f(z_cursor_id, (GLfloat)(layer_height_texture_data.print_object->model_object()->bounding_box().max(2) * layer_height_texture_data.z_cursor_relative));
|
||||
|
||||
if (z_cursor_band_width_id >= 0)
|
||||
glUniform1f(z_cursor_band_width_id, (GLfloat)layer_height_texture_data.edit_band_width);
|
||||
|
||||
if (world_matrix_id >= 0)
|
||||
::glUniformMatrix4fv(world_matrix_id, 1, GL_FALSE, (const GLfloat*)world_matrix().cast<float>().data());
|
||||
|
||||
GLsizei w = (GLsizei)layer_height_texture_width();
|
||||
GLsizei h = (GLsizei)layer_height_texture_height();
|
||||
GLsizei half_w = w / 2;
|
||||
GLsizei half_h = h / 2;
|
||||
|
||||
::glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
||||
glBindTexture(GL_TEXTURE_2D, layer_height_texture_data.texture_id);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
|
||||
glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA, half_w, half_h, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, layer_height_texture_data_ptr_level0());
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 1, 0, 0, half_w, half_h, GL_RGBA, GL_UNSIGNED_BYTE, layer_height_texture_data_ptr_level1());
|
||||
|
||||
render();
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
|
||||
if ((current_program_id > 0) && (layer_height_texture_data.shader_id != current_program_id))
|
||||
glUseProgram(current_program_id);
|
||||
}
|
||||
|
||||
void GLVolume::render_VBOs(int color_id, int detection_id, int worldmatrix_id) const
|
||||
{
|
||||
if (!is_active)
|
||||
|
@ -446,16 +394,6 @@ void GLVolume::render_VBOs(int color_id, int detection_id, int worldmatrix_id) c
|
|||
if (!indexed_vertex_array.vertices_and_normals_interleaved_VBO_id)
|
||||
return;
|
||||
|
||||
if (layer_height_texture_data.can_use())
|
||||
{
|
||||
::glDisableClientState(GL_VERTEX_ARRAY);
|
||||
::glDisableClientState(GL_NORMAL_ARRAY);
|
||||
render_using_layer_height();
|
||||
::glEnableClientState(GL_VERTEX_ARRAY);
|
||||
::glEnableClientState(GL_NORMAL_ARRAY);
|
||||
return;
|
||||
}
|
||||
|
||||
GLsizei n_triangles = GLsizei(std::min(indexed_vertex_array.triangle_indices_size, tverts_range.second - tverts_range.first));
|
||||
GLsizei n_quads = GLsizei(std::min(indexed_vertex_array.quad_indices_size, qverts_range.second - qverts_range.first));
|
||||
if (n_triangles + n_quads == 0)
|
||||
|
@ -558,44 +496,6 @@ void GLVolume::render_legacy() const
|
|||
::glPopMatrix();
|
||||
}
|
||||
|
||||
double GLVolume::layer_height_texture_z_to_row_id() const
|
||||
{
|
||||
return (this->layer_height_texture.get() == nullptr) ? 0.0 : double(this->layer_height_texture->cells - 1) / (double(this->layer_height_texture->width) * this->layer_height_texture_data.print_object->model_object()->bounding_box().max(2));
|
||||
}
|
||||
|
||||
void GLVolume::generate_layer_height_texture(const PrintObject *print_object, bool force)
|
||||
{
|
||||
LayersTexture *tex = this->layer_height_texture.get();
|
||||
if (tex == nullptr)
|
||||
// No layer_height_texture is assigned to this GLVolume, therefore the layer height texture cannot be filled.
|
||||
return;
|
||||
|
||||
// Always try to update the layer height profile.
|
||||
bool update = print_object->update_layer_height_profile(const_cast<ModelObject*>(print_object->model_object())->layer_height_profile) || force;
|
||||
// Update if the layer height profile was changed, or when the texture is not valid.
|
||||
if (! update && ! tex->data.empty() && tex->cells > 0)
|
||||
// Texture is valid, don't update.
|
||||
return;
|
||||
|
||||
if (tex->data.empty()) {
|
||||
tex->width = 1024;
|
||||
tex->height = 1024;
|
||||
tex->levels = 2;
|
||||
tex->data.assign(tex->width * tex->height * 5, 0);
|
||||
}
|
||||
|
||||
SlicingParameters slicing_params = print_object->slicing_parameters();
|
||||
bool level_of_detail_2nd_level = true;
|
||||
tex->cells = Slic3r::generate_layer_height_texture(
|
||||
slicing_params,
|
||||
Slic3r::generate_object_layers(slicing_params, print_object->model_object()->layer_height_profile),
|
||||
tex->data.data(), tex->height, tex->width, level_of_detail_2nd_level);
|
||||
}
|
||||
|
||||
// 512x512 bitmaps are supported everywhere, but that may not be sufficent for super large print volumes.
|
||||
#define LAYER_HEIGHT_TEXTURE_WIDTH 1024
|
||||
#define LAYER_HEIGHT_TEXTURE_HEIGHT 1024
|
||||
|
||||
std::vector<int> GLVolumeCollection::load_object(
|
||||
const ModelObject *model_object,
|
||||
int obj_idx,
|
||||
|
@ -603,19 +503,15 @@ std::vector<int> GLVolumeCollection::load_object(
|
|||
const std::string &color_by,
|
||||
bool use_VBOs)
|
||||
{
|
||||
// Object will share a single common layer height texture between all printable volumes.
|
||||
std::shared_ptr<LayersTexture> layer_height_texture = std::make_shared<LayersTexture>();
|
||||
std::vector<int> volumes_idx;
|
||||
for (int volume_idx = 0; volume_idx < int(model_object->volumes.size()); ++ volume_idx)
|
||||
for (int instance_idx : instance_idxs)
|
||||
volumes_idx.emplace_back(this->GLVolumeCollection::load_object_volume(model_object, layer_height_texture, obj_idx, volume_idx, instance_idx, color_by, use_VBOs));
|
||||
volumes_idx.emplace_back(this->GLVolumeCollection::load_object_volume(model_object, obj_idx, volume_idx, instance_idx, color_by, use_VBOs));
|
||||
return volumes_idx;
|
||||
}
|
||||
|
||||
int GLVolumeCollection::load_object_volume(
|
||||
const ModelObject *model_object,
|
||||
// Layer height texture is shared between all printable volumes of a single ModelObject.
|
||||
std::shared_ptr<LayersTexture> &layer_height_texture,
|
||||
int obj_idx,
|
||||
int volume_idx,
|
||||
int instance_idx,
|
||||
|
@ -666,7 +562,6 @@ int GLVolumeCollection::load_object_volume(
|
|||
v.set_convex_hull(&model_volume->get_convex_hull(), false);
|
||||
if (extruder_id != -1)
|
||||
v.extruder_id = extruder_id;
|
||||
v.layer_height_texture = layer_height_texture;
|
||||
}
|
||||
v.is_modifier = ! model_volume->is_model_part();
|
||||
v.shader_outside_printer_detection_enabled = model_volume->is_model_part();
|
||||
|
@ -696,7 +591,6 @@ void GLVolumeCollection::load_object_auxiliary(
|
|||
mesh.transform(mesh_trafo_inv);
|
||||
// Convex hull is required for out of print bed detection.
|
||||
TriangleMesh convex_hull = mesh.convex_hull_3d();
|
||||
convex_hull.transform(mesh_trafo_inv);
|
||||
for (const std::pair<size_t, size_t> &instance_idx : instances) {
|
||||
const ModelInstance &model_instance = *print_object->model_object()->instances[instance_idx.first];
|
||||
const SLAPrintObject::Instance &print_instance = print_object->instances()[instance_idx.second];
|
||||
|
@ -796,17 +690,19 @@ int GLVolumeCollection::load_wipe_tower_preview(
|
|||
#if ENABLE_IMPROVED_TRANSPARENT_VOLUMES_RENDERING
|
||||
typedef std::pair<GLVolume*, double> GLVolumeWithZ;
|
||||
typedef std::vector<GLVolumeWithZ> GLVolumesWithZList;
|
||||
GLVolumesWithZList volumes_to_render(const GLVolumePtrs& volumes, GLVolumeCollection::ERenderType type)
|
||||
static GLVolumesWithZList volumes_to_render(const GLVolumePtrs& volumes, GLVolumeCollection::ERenderType type, std::function<bool(const GLVolume&)> filter_func)
|
||||
{
|
||||
GLVolumesWithZList list;
|
||||
list.reserve(volumes.size());
|
||||
|
||||
for (GLVolume* volume : volumes)
|
||||
{
|
||||
bool is_transparent = (volume->render_color[3] < 1.0f);
|
||||
if (((type == GLVolumeCollection::Opaque) && !is_transparent) ||
|
||||
((type == GLVolumeCollection::Transparent) && is_transparent) ||
|
||||
(type == GLVolumeCollection::All))
|
||||
list.push_back(std::make_pair(volume, 0.0));
|
||||
if ((((type == GLVolumeCollection::Opaque) && !is_transparent) ||
|
||||
((type == GLVolumeCollection::Transparent) && is_transparent) ||
|
||||
(type == GLVolumeCollection::All)) &&
|
||||
(! filter_func || filter_func(*volume)))
|
||||
list.emplace_back(std::make_pair(volume, 0.0));
|
||||
}
|
||||
|
||||
if ((type == GLVolumeCollection::Transparent) && (list.size() > 1))
|
||||
|
@ -827,7 +723,7 @@ GLVolumesWithZList volumes_to_render(const GLVolumePtrs& volumes, GLVolumeCollec
|
|||
return list;
|
||||
}
|
||||
|
||||
void GLVolumeCollection::render_VBOs(GLVolumeCollection::ERenderType type, bool disable_cullface) const
|
||||
void GLVolumeCollection::render_VBOs(GLVolumeCollection::ERenderType type, bool disable_cullface, std::function<bool(const GLVolume&)> filter_func) const
|
||||
#else
|
||||
void GLVolumeCollection::render_VBOs() const
|
||||
#endif // ENABLE_IMPROVED_TRANSPARENT_VOLUMES_RENDERING
|
||||
|
@ -863,26 +759,17 @@ void GLVolumeCollection::render_VBOs() const
|
|||
::glUniform2fv(z_range_id, 1, (const GLfloat*)z_range);
|
||||
|
||||
#if ENABLE_IMPROVED_TRANSPARENT_VOLUMES_RENDERING
|
||||
GLVolumesWithZList to_render = volumes_to_render(this->volumes, type);
|
||||
for (GLVolumeWithZ& volume : to_render)
|
||||
{
|
||||
if (volume.first->layer_height_texture_data.can_use())
|
||||
volume.first->generate_layer_height_texture(volume.first->layer_height_texture_data.print_object, false);
|
||||
else
|
||||
volume.first->set_render_color();
|
||||
|
||||
GLVolumesWithZList to_render = volumes_to_render(this->volumes, type, filter_func);
|
||||
for (GLVolumeWithZ& volume : to_render) {
|
||||
volume.first->set_render_color();
|
||||
volume.first->render_VBOs(color_id, print_box_detection_id, print_box_worldmatrix_id);
|
||||
}
|
||||
#else
|
||||
for (GLVolume *volume : this->volumes)
|
||||
{
|
||||
if (volume->layer_height_texture_data.can_use())
|
||||
volume->generate_layer_height_texture(volume->layer_height_texture_data.print_object, false);
|
||||
else
|
||||
if (! filter_func || filter_func(*volume)) {
|
||||
volume->set_render_color();
|
||||
|
||||
volume->render_VBOs(color_id, print_box_detection_id, print_box_worldmatrix_id);
|
||||
}
|
||||
volume->render_VBOs(color_id, print_box_detection_id, print_box_worldmatrix_id);
|
||||
}
|
||||
#endif // ENABLE_IMPROVED_TRANSPARENT_VOLUMES_RENDERING
|
||||
|
||||
::glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
|
@ -918,7 +805,7 @@ void GLVolumeCollection::render_legacy() const
|
|||
glEnableClientState(GL_NORMAL_ARRAY);
|
||||
|
||||
#if ENABLE_IMPROVED_TRANSPARENT_VOLUMES_RENDERING
|
||||
GLVolumesWithZList to_render = volumes_to_render(this->volumes, type);
|
||||
GLVolumesWithZList to_render = volumes_to_render(this->volumes, type, std::function<bool(const GLVolume&)>());
|
||||
for (GLVolumeWithZ& volume : to_render)
|
||||
{
|
||||
volume.first->set_render_color();
|
||||
|
|
|
@ -9,6 +9,8 @@
|
|||
#include "libslic3r/Model.hpp"
|
||||
#include "slic3r/GUI/GLCanvas3DManager.hpp"
|
||||
|
||||
#include <functional>
|
||||
|
||||
namespace Slic3r {
|
||||
|
||||
class Print;
|
||||
|
@ -199,50 +201,7 @@ private:
|
|||
}
|
||||
};
|
||||
|
||||
class LayersTexture
|
||||
{
|
||||
public:
|
||||
LayersTexture() : width(0), height(0), levels(0), cells(0) {}
|
||||
|
||||
// Texture data
|
||||
std::vector<char> data;
|
||||
// Width of the texture, top level.
|
||||
size_t width;
|
||||
// Height of the texture, top level.
|
||||
size_t height;
|
||||
// For how many levels of detail is the data allocated?
|
||||
size_t levels;
|
||||
// Number of texture cells allocated for the height texture.
|
||||
size_t cells;
|
||||
};
|
||||
|
||||
class GLVolume {
|
||||
struct LayerHeightTextureData
|
||||
{
|
||||
// ID of the layer height texture
|
||||
unsigned int texture_id;
|
||||
// ID of the shader used to render with the layer height texture
|
||||
unsigned int shader_id;
|
||||
// The print object to update when generating the layer height texture
|
||||
const PrintObject* print_object;
|
||||
|
||||
float z_cursor_relative;
|
||||
float edit_band_width;
|
||||
|
||||
LayerHeightTextureData() { reset(); }
|
||||
|
||||
void reset()
|
||||
{
|
||||
texture_id = 0;
|
||||
shader_id = 0;
|
||||
print_object = nullptr;
|
||||
z_cursor_relative = 0.0f;
|
||||
edit_band_width = 0.0f;
|
||||
}
|
||||
|
||||
bool can_use() const { return (texture_id > 0) && (shader_id > 0) && (print_object != nullptr); }
|
||||
};
|
||||
|
||||
public:
|
||||
static const float SELECTED_COLOR[4];
|
||||
static const float HOVER_COLOR[4];
|
||||
|
@ -406,7 +365,7 @@ public:
|
|||
int volume_idx() const { return this->composite_id.volume_id; }
|
||||
int instance_idx() const { return this->composite_id.instance_id; }
|
||||
|
||||
Transform3d world_matrix() const;
|
||||
Transform3d world_matrix() const;
|
||||
|
||||
const BoundingBoxf3& transformed_bounding_box() const;
|
||||
const BoundingBoxf3& transformed_convex_hull_bounding_box() const;
|
||||
|
@ -416,49 +375,13 @@ public:
|
|||
|
||||
void set_range(coordf_t low, coordf_t high);
|
||||
void render() const;
|
||||
void render_using_layer_height() const;
|
||||
void render_VBOs(int color_id, int detection_id, int worldmatrix_id) const;
|
||||
void render_legacy() const;
|
||||
|
||||
void finalize_geometry(bool use_VBOs) { this->indexed_vertex_array.finalize_geometry(use_VBOs); }
|
||||
void release_geometry() { this->indexed_vertex_array.release_geometry(); }
|
||||
|
||||
/************************************************ Layer height texture ****************************************************/
|
||||
std::shared_ptr<LayersTexture> layer_height_texture;
|
||||
// Data to render this volume using the layer height texture
|
||||
LayerHeightTextureData layer_height_texture_data;
|
||||
|
||||
bool has_layer_height_texture() const
|
||||
{ return this->layer_height_texture.get() != nullptr; }
|
||||
size_t layer_height_texture_width() const
|
||||
{ return (this->layer_height_texture.get() == nullptr) ? 0 : this->layer_height_texture->width; }
|
||||
size_t layer_height_texture_height() const
|
||||
{ return (this->layer_height_texture.get() == nullptr) ? 0 : this->layer_height_texture->height; }
|
||||
size_t layer_height_texture_cells() const
|
||||
{ return (this->layer_height_texture.get() == nullptr) ? 0 : this->layer_height_texture->cells; }
|
||||
void* layer_height_texture_data_ptr_level0() const {
|
||||
return (layer_height_texture.get() == nullptr) ? 0 :
|
||||
(void*)layer_height_texture->data.data();
|
||||
}
|
||||
void* layer_height_texture_data_ptr_level1() const {
|
||||
return (layer_height_texture.get() == nullptr) ? 0 :
|
||||
(void*)(layer_height_texture->data.data() + layer_height_texture->width * layer_height_texture->height * 4);
|
||||
}
|
||||
double layer_height_texture_z_to_row_id() const;
|
||||
void generate_layer_height_texture(const PrintObject *print_object, bool force);
|
||||
|
||||
void set_layer_height_texture_data(unsigned int texture_id, unsigned int shader_id, const PrintObject* print_object, float z_cursor_relative, float edit_band_width)
|
||||
{
|
||||
layer_height_texture_data.texture_id = texture_id;
|
||||
layer_height_texture_data.shader_id = shader_id;
|
||||
layer_height_texture_data.print_object = print_object;
|
||||
layer_height_texture_data.z_cursor_relative = z_cursor_relative;
|
||||
layer_height_texture_data.edit_band_width = edit_band_width;
|
||||
}
|
||||
|
||||
void reset_layer_height_texture_data() { layer_height_texture_data.reset(); }
|
||||
|
||||
void set_bounding_boxes_as_dirty() { m_transformed_bounding_box_dirty = true; m_transformed_convex_hull_bounding_box_dirty = true; }
|
||||
void set_bounding_boxes_as_dirty() { m_transformed_bounding_box_dirty = true; m_transformed_convex_hull_bounding_box_dirty = true; }
|
||||
};
|
||||
|
||||
typedef std::vector<GLVolume*> GLVolumePtrs;
|
||||
|
@ -498,7 +421,6 @@ public:
|
|||
|
||||
int load_object_volume(
|
||||
const ModelObject *model_object,
|
||||
std::shared_ptr<LayersTexture> &layer_height_texture,
|
||||
int obj_idx,
|
||||
int volume_idx,
|
||||
int instance_idx,
|
||||
|
@ -521,7 +443,7 @@ public:
|
|||
|
||||
// Render the volumes by OpenGL.
|
||||
#if ENABLE_IMPROVED_TRANSPARENT_VOLUMES_RENDERING
|
||||
void render_VBOs(ERenderType type, bool disable_cullface) const;
|
||||
void render_VBOs(ERenderType type, bool disable_cullface, std::function<bool(const GLVolume&)> filter_func = std::function<bool(const GLVolume&)>()) const;
|
||||
void render_legacy(ERenderType type, bool disable_cullface) const;
|
||||
#else
|
||||
void render_VBOs() const;
|
||||
|
|
|
@ -819,12 +819,16 @@ GLCanvas3D::LayersEditing::LayersEditing()
|
|||
: m_use_legacy_opengl(false)
|
||||
, m_enabled(false)
|
||||
, m_z_texture_id(0)
|
||||
, m_model_object(nullptr)
|
||||
, m_object_max_z(0.f)
|
||||
, m_slicing_parameters(new SlicingParameters)
|
||||
, m_layer_height_profile_modified(false)
|
||||
, state(Unknown)
|
||||
, band_width(2.0f)
|
||||
, strength(0.005f)
|
||||
, last_object_id(-1)
|
||||
, last_z(0.0f)
|
||||
, last_action(0)
|
||||
, last_action(LAYER_HEIGHT_EDIT_ACTION_INCREASE)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -835,6 +839,7 @@ GLCanvas3D::LayersEditing::~LayersEditing()
|
|||
::glDeleteTextures(1, &m_z_texture_id);
|
||||
m_z_texture_id = 0;
|
||||
}
|
||||
delete m_slicing_parameters;
|
||||
}
|
||||
|
||||
bool GLCanvas3D::LayersEditing::init(const std::string& vertex_shader_filename, const std::string& fragment_shader_filename)
|
||||
|
@ -854,9 +859,20 @@ bool GLCanvas3D::LayersEditing::init(const std::string& vertex_shader_filename,
|
|||
return true;
|
||||
}
|
||||
|
||||
void GLCanvas3D::LayersEditing::select_object(const Model &model, int object_id)
|
||||
{
|
||||
m_model_object = (object_id >= 0) ? model.objects[object_id] : nullptr;
|
||||
m_object_max_z = (m_model_object == nullptr) ? 0.f : m_model_object->bounding_box().max.z();
|
||||
if (m_model_object == nullptr || this->last_object_id != object_id) {
|
||||
m_layer_height_profile.clear();
|
||||
m_layer_height_profile_modified = false;
|
||||
}
|
||||
this->last_object_id = object_id;
|
||||
}
|
||||
|
||||
bool GLCanvas3D::LayersEditing::is_allowed() const
|
||||
{
|
||||
return !m_use_legacy_opengl && m_shader.is_initialized();
|
||||
return !m_use_legacy_opengl && m_shader.is_initialized() && m_shader.get_shader()->shader_program_id > 0 && m_z_texture_id > 0;
|
||||
}
|
||||
|
||||
void GLCanvas3D::LayersEditing::set_use_legacy_opengl(bool use_legacy_opengl)
|
||||
|
@ -874,12 +890,7 @@ void GLCanvas3D::LayersEditing::set_enabled(bool enabled)
|
|||
m_enabled = is_allowed() && enabled;
|
||||
}
|
||||
|
||||
unsigned int GLCanvas3D::LayersEditing::get_z_texture_id() const
|
||||
{
|
||||
return m_z_texture_id;
|
||||
}
|
||||
|
||||
void GLCanvas3D::LayersEditing::render(const GLCanvas3D& canvas, const PrintObject& print_object, const GLVolume& volume) const
|
||||
void GLCanvas3D::LayersEditing::render_overlay(const GLCanvas3D& canvas) const
|
||||
{
|
||||
if (!m_enabled)
|
||||
return;
|
||||
|
@ -896,8 +907,8 @@ void GLCanvas3D::LayersEditing::render(const GLCanvas3D& canvas, const PrintObje
|
|||
|
||||
_render_tooltip_texture(canvas, bar_rect, reset_rect);
|
||||
_render_reset_texture(reset_rect);
|
||||
_render_active_object_annotations(canvas, volume, print_object, bar_rect);
|
||||
_render_profile(print_object, bar_rect);
|
||||
_render_active_object_annotations(canvas, bar_rect);
|
||||
_render_profile(bar_rect);
|
||||
|
||||
// Revert the matrices.
|
||||
::glPopMatrix();
|
||||
|
@ -905,12 +916,6 @@ void GLCanvas3D::LayersEditing::render(const GLCanvas3D& canvas, const PrintObje
|
|||
::glEnable(GL_DEPTH_TEST);
|
||||
}
|
||||
|
||||
int GLCanvas3D::LayersEditing::get_shader_program_id() const
|
||||
{
|
||||
const GLShader* shader = m_shader.get_shader();
|
||||
return (shader != nullptr) ? shader->shader_program_id : -1;
|
||||
}
|
||||
|
||||
float GLCanvas3D::LayersEditing::get_cursor_z_relative(const GLCanvas3D& canvas)
|
||||
{
|
||||
const Point& mouse_pos = canvas.get_local_mouse_position();
|
||||
|
@ -1023,21 +1028,19 @@ void GLCanvas3D::LayersEditing::_render_reset_texture(const Rect& reset_rect) co
|
|||
GLTexture::render_texture(m_reset_texture.get_id(), reset_rect.get_left(), reset_rect.get_right(), reset_rect.get_bottom(), reset_rect.get_top());
|
||||
}
|
||||
|
||||
void GLCanvas3D::LayersEditing::_render_active_object_annotations(const GLCanvas3D& canvas, const GLVolume& volume, const PrintObject& print_object, const Rect& bar_rect) const
|
||||
void GLCanvas3D::LayersEditing::_render_active_object_annotations(const GLCanvas3D& canvas, const Rect& bar_rect) const
|
||||
{
|
||||
float max_z = print_object.model_object()->bounding_box().max(2);
|
||||
|
||||
m_shader.start_using();
|
||||
|
||||
m_shader.set_uniform("z_to_texture_row", (float)volume.layer_height_texture_z_to_row_id());
|
||||
m_shader.set_uniform("z_texture_row_to_normalized", 1.0f / (float)volume.layer_height_texture_height());
|
||||
m_shader.set_uniform("z_cursor", max_z * get_cursor_z_relative(canvas));
|
||||
m_shader.set_uniform("z_to_texture_row", float(m_layers_texture.cells - 1) / (float(m_layers_texture.width) * m_object_max_z));
|
||||
m_shader.set_uniform("z_texture_row_to_normalized", 1.0f / (float)m_layers_texture.height);
|
||||
m_shader.set_uniform("z_cursor", m_object_max_z * this->get_cursor_z_relative(canvas));
|
||||
m_shader.set_uniform("z_cursor_band_width", band_width);
|
||||
// The shader requires the original model coordinates when rendering to the texture, so we pass it the unit matrix
|
||||
m_shader.set_uniform("volume_world_matrix", UNIT_MATRIX);
|
||||
|
||||
GLsizei w = (GLsizei)volume.layer_height_texture_width();
|
||||
GLsizei h = (GLsizei)volume.layer_height_texture_height();
|
||||
GLsizei w = (GLsizei)m_layers_texture.width;
|
||||
GLsizei h = (GLsizei)m_layers_texture.height;
|
||||
GLsizei half_w = w / 2;
|
||||
GLsizei half_h = h / 2;
|
||||
|
||||
|
@ -1045,8 +1048,8 @@ void GLCanvas3D::LayersEditing::_render_active_object_annotations(const GLCanvas
|
|||
::glBindTexture(GL_TEXTURE_2D, m_z_texture_id);
|
||||
::glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
|
||||
::glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA, half_w, half_h, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
|
||||
::glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, volume.layer_height_texture_data_ptr_level0());
|
||||
::glTexSubImage2D(GL_TEXTURE_2D, 1, 0, 0, half_w, half_h, GL_RGBA, GL_UNSIGNED_BYTE, volume.layer_height_texture_data_ptr_level1());
|
||||
::glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, m_layers_texture.data.data());
|
||||
::glTexSubImage2D(GL_TEXTURE_2D, 1, 0, 0, half_w, half_h, GL_RGBA, GL_UNSIGNED_BYTE, m_layers_texture.data.data() + m_layers_texture.width * m_layers_texture.height * 4);
|
||||
|
||||
// Render the color bar
|
||||
float l = bar_rect.get_left();
|
||||
|
@ -1057,25 +1060,24 @@ void GLCanvas3D::LayersEditing::_render_active_object_annotations(const GLCanvas
|
|||
::glBegin(GL_QUADS);
|
||||
::glVertex3f(l, b, 0.0f);
|
||||
::glVertex3f(r, b, 0.0f);
|
||||
::glVertex3f(r, t, max_z);
|
||||
::glVertex3f(l, t, max_z);
|
||||
::glVertex3f(r, t, m_object_max_z);
|
||||
::glVertex3f(l, t, m_object_max_z);
|
||||
::glEnd();
|
||||
::glBindTexture(GL_TEXTURE_2D, 0);
|
||||
|
||||
m_shader.stop_using();
|
||||
}
|
||||
|
||||
void GLCanvas3D::LayersEditing::_render_profile(const PrintObject& print_object, const Rect& bar_rect) const
|
||||
void GLCanvas3D::LayersEditing::_render_profile(const Rect& bar_rect) const
|
||||
{
|
||||
// FIXME show some kind of legend.
|
||||
//FIXME show some kind of legend.
|
||||
|
||||
// Get a maximum layer height value.
|
||||
// FIXME This is a duplicate code of Slicing.cpp.
|
||||
//FIXME This is a duplicate code of Slicing.cpp.
|
||||
double layer_height_max = DBL_MAX;
|
||||
const PrintConfig& print_config = print_object.print()->config();
|
||||
const std::vector<double>& nozzle_diameters = dynamic_cast<const ConfigOptionFloats*>(print_config.option("nozzle_diameter"))->values;
|
||||
const std::vector<double>& layer_heights_min = dynamic_cast<const ConfigOptionFloats*>(print_config.option("min_layer_height"))->values;
|
||||
const std::vector<double>& layer_heights_max = dynamic_cast<const ConfigOptionFloats*>(print_config.option("max_layer_height"))->values;
|
||||
const std::vector<double>& nozzle_diameters = dynamic_cast<const ConfigOptionFloats*>(m_config->option("nozzle_diameter"))->values;
|
||||
const std::vector<double>& layer_heights_min = dynamic_cast<const ConfigOptionFloats*>(m_config->option("min_layer_height"))->values;
|
||||
const std::vector<double>& layer_heights_max = dynamic_cast<const ConfigOptionFloats*>(m_config->option("max_layer_height"))->values;
|
||||
for (unsigned int i = 0; i < (unsigned int)nozzle_diameters.size(); ++i)
|
||||
{
|
||||
double lh_min = (layer_heights_min[i] == 0.0) ? 0.07 : std::max(0.01, layer_heights_min[i]);
|
||||
|
@ -1086,15 +1088,19 @@ void GLCanvas3D::LayersEditing::_render_profile(const PrintObject& print_object,
|
|||
// Make the vertical bar a bit wider so the layer height curve does not touch the edge of the bar region.
|
||||
layer_height_max *= 1.12;
|
||||
|
||||
double max_z = unscale<double>(print_object.size(2));
|
||||
double layer_height = dynamic_cast<const ConfigOptionFloat*>(print_object.config().option("layer_height"))->value;
|
||||
// Get global layer height.
|
||||
double layer_height = dynamic_cast<const ConfigOptionFloat*>(m_config->option("layer_height"))->value;
|
||||
// Override the global layer height with object's layer height if set.
|
||||
const ConfigOption *opt_object_layer_height = m_model_object->config.option("layer_height");
|
||||
if (opt_object_layer_height != nullptr)
|
||||
layer_height = dynamic_cast<const ConfigOptionFloat*>(opt_object_layer_height)->value;
|
||||
float l = bar_rect.get_left();
|
||||
float w = bar_rect.get_right() - l;
|
||||
float b = bar_rect.get_bottom();
|
||||
float t = bar_rect.get_top();
|
||||
float h = t - b;
|
||||
float scale_x = w / (float)layer_height_max;
|
||||
float scale_y = h / (float)max_z;
|
||||
float scale_y = h / m_object_max_z;
|
||||
float x = l + (float)layer_height * scale_x;
|
||||
|
||||
// Baseline
|
||||
|
@ -1105,19 +1111,129 @@ void GLCanvas3D::LayersEditing::_render_profile(const PrintObject& print_object,
|
|||
::glEnd();
|
||||
|
||||
// Curve
|
||||
const ModelObject* model_object = print_object.model_object();
|
||||
if (model_object->layer_height_profile_valid)
|
||||
{
|
||||
const std::vector<double>& profile = model_object->layer_height_profile;
|
||||
::glColor3f(0.0f, 0.0f, 1.0f);
|
||||
::glBegin(GL_LINE_STRIP);
|
||||
for (unsigned int i = 0; i < m_layer_height_profile.size(); i += 2)
|
||||
::glVertex2f(l + (float)m_layer_height_profile[i + 1] * scale_x, b + (float)m_layer_height_profile[i] * scale_y);
|
||||
::glEnd();
|
||||
}
|
||||
|
||||
::glColor3f(0.0f, 0.0f, 1.0f);
|
||||
::glBegin(GL_LINE_STRIP);
|
||||
for (unsigned int i = 0; i < profile.size(); i += 2)
|
||||
{
|
||||
::glVertex2f(l + (float)profile[i + 1] * scale_x, b + (float)profile[i] * scale_y);
|
||||
void GLCanvas3D::LayersEditing::render_volumes(const GLCanvas3D& canvas, const GLVolumeCollection &volumes) const
|
||||
{
|
||||
assert(this->is_allowed());
|
||||
assert(this->last_object_id != -1);
|
||||
GLint shader_id = m_shader.get_shader()->shader_program_id;
|
||||
assert(shader_id > 0);
|
||||
|
||||
GLint current_program_id;
|
||||
glGetIntegerv(GL_CURRENT_PROGRAM, ¤t_program_id);
|
||||
if (shader_id > 0 && shader_id != current_program_id)
|
||||
// The layer editing shader is not yet active. Activate it.
|
||||
glUseProgram(shader_id);
|
||||
else
|
||||
// The layer editing shader was already active.
|
||||
current_program_id = -1;
|
||||
|
||||
GLint z_to_texture_row_id = glGetUniformLocation(shader_id, "z_to_texture_row");
|
||||
GLint z_texture_row_to_normalized_id = glGetUniformLocation(shader_id, "z_texture_row_to_normalized");
|
||||
GLint z_cursor_id = glGetUniformLocation(shader_id, "z_cursor");
|
||||
GLint z_cursor_band_width_id = glGetUniformLocation(shader_id, "z_cursor_band_width");
|
||||
GLint world_matrix_id = glGetUniformLocation(shader_id, "volume_world_matrix");
|
||||
|
||||
if (z_to_texture_row_id != -1 && z_texture_row_to_normalized_id != -1 && z_cursor_id != -1 && z_cursor_band_width_id != -1 && world_matrix_id != -1)
|
||||
{
|
||||
const_cast<LayersEditing*>(this)->generate_layer_height_texture();
|
||||
|
||||
// Uniforms were resolved, go ahead using the layer editing shader.
|
||||
glUniform1f(z_to_texture_row_id, GLfloat(m_layers_texture.cells - 1) / (GLfloat(m_layers_texture.width) * GLfloat(m_object_max_z)));
|
||||
glUniform1f(z_texture_row_to_normalized_id, GLfloat(1.0f / m_layers_texture.height));
|
||||
glUniform1f(z_cursor_id, GLfloat(m_object_max_z) * GLfloat(this->get_cursor_z_relative(canvas)));
|
||||
glUniform1f(z_cursor_band_width_id, GLfloat(this->band_width));
|
||||
// Initialize the layer height texture mapping.
|
||||
GLsizei w = (GLsizei)m_layers_texture.width;
|
||||
GLsizei h = (GLsizei)m_layers_texture.height;
|
||||
GLsizei half_w = w / 2;
|
||||
GLsizei half_h = h / 2;
|
||||
::glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
||||
glBindTexture(GL_TEXTURE_2D, m_z_texture_id);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
|
||||
glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA, half_w, half_h, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, m_layers_texture.data.data());
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 1, 0, 0, half_w, half_h, GL_RGBA, GL_UNSIGNED_BYTE, m_layers_texture.data.data() + m_layers_texture.width * m_layers_texture.height * 4);
|
||||
for (const GLVolume *glvolume : volumes.volumes) {
|
||||
// Render the object using the layer editing shader and texture.
|
||||
if (! glvolume->is_active || glvolume->composite_id.object_id != this->last_object_id || glvolume->is_modifier)
|
||||
continue;
|
||||
::glUniformMatrix4fv(world_matrix_id, 1, GL_FALSE, (const GLfloat*)glvolume->world_matrix().cast<float>().data());
|
||||
glvolume->render();
|
||||
}
|
||||
::glEnd();
|
||||
// Revert back to the previous shader.
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
if (current_program_id > 0)
|
||||
glUseProgram(current_program_id);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Something went wrong. Just render the object.
|
||||
assert(false);
|
||||
for (const GLVolume *glvolume : volumes.volumes) {
|
||||
// Render the object using the layer editing shader and texture.
|
||||
if (!glvolume->is_active || glvolume->composite_id.object_id != this->last_object_id || glvolume->is_modifier)
|
||||
continue;
|
||||
::glUniformMatrix4fv(world_matrix_id, 1, GL_FALSE, (const GLfloat*)glvolume->world_matrix().cast<float>().data());
|
||||
glvolume->render();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GLCanvas3D::LayersEditing::adjust_layer_height_profile()
|
||||
{
|
||||
*m_slicing_parameters = PrintObject::slicing_parameters(*m_config, *m_model_object);
|
||||
PrintObject::update_layer_height_profile(*m_model_object, *m_slicing_parameters, m_layer_height_profile);
|
||||
Slic3r::adjust_layer_height_profile(*m_slicing_parameters, m_layer_height_profile, this->last_z, this->strength, this->band_width, this->last_action);
|
||||
m_layer_height_profile_modified = true;
|
||||
m_layers_texture.valid = false;
|
||||
}
|
||||
|
||||
void GLCanvas3D::LayersEditing::generate_layer_height_texture()
|
||||
{
|
||||
// Always try to update the layer height profile.
|
||||
bool update = ! m_layers_texture.valid;
|
||||
*m_slicing_parameters = PrintObject::slicing_parameters(*m_config, *m_model_object);
|
||||
if (PrintObject::update_layer_height_profile(*m_model_object, *m_slicing_parameters, m_layer_height_profile)) {
|
||||
// Initialized to the default value.
|
||||
m_layer_height_profile_modified = false;
|
||||
update = true;
|
||||
}
|
||||
// Update if the layer height profile was changed, or when the texture is not valid.
|
||||
if (! update && ! m_layers_texture.data.empty() && m_layers_texture.cells > 0)
|
||||
// Texture is valid, don't update.
|
||||
return;
|
||||
|
||||
if (m_layers_texture.data.empty()) {
|
||||
m_layers_texture.width = 1024;
|
||||
m_layers_texture.height = 1024;
|
||||
m_layers_texture.levels = 2;
|
||||
m_layers_texture.data.assign(m_layers_texture.width * m_layers_texture.height * 5, 0);
|
||||
}
|
||||
|
||||
bool level_of_detail_2nd_level = true;
|
||||
m_layers_texture.cells = Slic3r::generate_layer_height_texture(
|
||||
*m_slicing_parameters,
|
||||
Slic3r::generate_object_layers(*m_slicing_parameters, m_layer_height_profile),
|
||||
m_layers_texture.data.data(), m_layers_texture.height, m_layers_texture.width, level_of_detail_2nd_level);
|
||||
m_layers_texture.valid = true;
|
||||
}
|
||||
|
||||
void GLCanvas3D::LayersEditing::accept_changes(GLCanvas3D& canvas)
|
||||
{
|
||||
if (last_object_id >= 0) {
|
||||
if (m_layer_height_profile_modified) {
|
||||
const_cast<ModelObject*>(m_model_object)->layer_height_profile = m_layer_height_profile;
|
||||
canvas.post_event(SimpleEvent(EVT_GLCANVAS_SCHEDULE_BACKGROUND_PROCESS));
|
||||
}
|
||||
}
|
||||
m_layer_height_profile_modified = false;
|
||||
}
|
||||
|
||||
const Point GLCanvas3D::Mouse::Drag::Invalid_2D_Point(INT_MAX, INT_MAX);
|
||||
|
@ -1668,11 +1784,14 @@ void GLCanvas3D::Selection::flattening_rotate(const Vec3d& normal)
|
|||
|
||||
for (unsigned int i : m_list)
|
||||
{
|
||||
Transform3d wst = m_cache.volumes_data[i].get_instance_scale_matrix() * m_cache.volumes_data[i].get_volume_scale_matrix();
|
||||
Transform3d wst = m_cache.volumes_data[i].get_instance_scale_matrix();
|
||||
Vec3d scaling_factor = Vec3d(1./wst(0,0), 1./wst(1,1), 1./wst(2,2));
|
||||
|
||||
Vec3d rotation = Geometry::extract_euler_angles(m_cache.volumes_data[i].get_instance_rotation_matrix() * m_cache.volumes_data[i].get_volume_rotation_matrix());
|
||||
Vec3d transformed_normal = Geometry::assemble_transform(Vec3d::Zero(), rotation, scaling_factor) * normal;
|
||||
Transform3d wmt = m_cache.volumes_data[i].get_instance_mirror_matrix();
|
||||
Vec3d mirror(wmt(0,0), wmt(1,1), wmt(2,2));
|
||||
|
||||
Vec3d rotation = Geometry::extract_euler_angles(m_cache.volumes_data[i].get_instance_rotation_matrix());
|
||||
Vec3d transformed_normal = Geometry::assemble_transform(Vec3d::Zero(), rotation, scaling_factor, mirror) * normal;
|
||||
transformed_normal.normalize();
|
||||
|
||||
Vec3d axis = transformed_normal(2) > 0.999f ? Vec3d(1., 0., 0.) : Vec3d(transformed_normal.cross(Vec3d(0., 0., -1.)));
|
||||
|
@ -2800,13 +2919,13 @@ std::string GLCanvas3D::Gizmos::update_hover_state(const GLCanvas3D& canvas, con
|
|||
|
||||
float icon_size = (float)it->second->get_textures_size() * OverlayIconsScale;
|
||||
|
||||
bool inside = (OverlayBorder <= (float)mouse_pos(0)) && ((float)mouse_pos(0) <= OverlayBorder + icon_size) && (top_y <= (float)mouse_pos(1)) && ((float)mouse_pos(1) <= top_y + icon_size);
|
||||
if (inside)
|
||||
name = it->second->get_name();
|
||||
|
||||
if (it->second->is_activable(selection) && (it->second->get_state() != GLGizmoBase::On))
|
||||
{
|
||||
bool inside = (OverlayBorder <= (float)mouse_pos(0)) && ((float)mouse_pos(0) <= OverlayBorder + icon_size) && (top_y <= (float)mouse_pos(1)) && ((float)mouse_pos(1) <= top_y + icon_size);
|
||||
it->second->set_state(inside ? GLGizmoBase::Hover : GLGizmoBase::Off);
|
||||
if (inside)
|
||||
name = it->second->get_name();
|
||||
}
|
||||
|
||||
top_y += (icon_size + OverlayGapY);
|
||||
}
|
||||
|
||||
|
@ -3689,7 +3808,6 @@ wxDEFINE_EVENT(EVT_GLCANVAS_SCHEDULE_BACKGROUND_PROCESS, SimpleEvent);
|
|||
wxDEFINE_EVENT(EVT_GLCANVAS_OBJECT_SELECT, SimpleEvent);
|
||||
wxDEFINE_EVENT(EVT_GLCANVAS_VIEWPORT_CHANGED, SimpleEvent);
|
||||
wxDEFINE_EVENT(EVT_GLCANVAS_RIGHT_CLICK, Vec2dEvent);
|
||||
wxDEFINE_EVENT(EVT_GLCANVAS_MODEL_UPDATE, SimpleEvent);
|
||||
wxDEFINE_EVENT(EVT_GLCANVAS_REMOVE_OBJECT, SimpleEvent);
|
||||
wxDEFINE_EVENT(EVT_GLCANVAS_ARRANGE, SimpleEvent);
|
||||
wxDEFINE_EVENT(EVT_GLCANVAS_QUESTION_MARK, SimpleEvent);
|
||||
|
@ -3718,7 +3836,11 @@ GLCanvas3D::GLCanvas3D(wxGLCanvas* canvas)
|
|||
, m_dirty(true)
|
||||
, m_initialized(false)
|
||||
, m_use_VBOs(false)
|
||||
#if ENABLE_REWORKED_BED_SHAPE_CHANGE
|
||||
, m_requires_zoom_to_bed(false)
|
||||
#else
|
||||
, m_force_zoom_to_bed_enabled(false)
|
||||
#endif // ENABLE_REWORKED_BED_SHAPE_CHANGE
|
||||
, m_apply_zoom_to_volumes_filter(false)
|
||||
, m_hover_volume_id(-1)
|
||||
, m_toolbar_action_running(false)
|
||||
|
@ -3912,9 +4034,10 @@ int GLCanvas3D::check_volumes_outside_state() const
|
|||
return (int)state;
|
||||
}
|
||||
|
||||
void GLCanvas3D::set_config(DynamicPrintConfig* config)
|
||||
void GLCanvas3D::set_config(const DynamicPrintConfig* config)
|
||||
{
|
||||
m_config = config;
|
||||
m_layers_editing.set_config(config);
|
||||
}
|
||||
|
||||
void GLCanvas3D::set_process(BackgroundSlicingProcess *process)
|
||||
|
@ -3937,7 +4060,11 @@ void GLCanvas3D::set_bed_shape(const Pointfs& shape)
|
|||
set_bed_axes_length(0.1 * m_bed.get_bounding_box().max_size());
|
||||
|
||||
if (new_shape)
|
||||
#if ENABLE_REWORKED_BED_SHAPE_CHANGE
|
||||
m_requires_zoom_to_bed = true;
|
||||
#else
|
||||
zoom_to_bed();
|
||||
#endif // ENABLE_REWORKED_BED_SHAPE_CHANGE
|
||||
|
||||
m_dirty = true;
|
||||
}
|
||||
|
@ -4032,10 +4159,12 @@ void GLCanvas3D::enable_toolbar(bool enable)
|
|||
m_toolbar.set_enabled(enable);
|
||||
}
|
||||
|
||||
#if !ENABLE_REWORKED_BED_SHAPE_CHANGE
|
||||
void GLCanvas3D::enable_force_zoom_to_bed(bool enable)
|
||||
{
|
||||
m_force_zoom_to_bed_enabled = enable;
|
||||
}
|
||||
#endif // !ENABLE_REWORKED_BED_SHAPE_CHANGE
|
||||
|
||||
void GLCanvas3D::enable_dynamic_background(bool enable)
|
||||
{
|
||||
|
@ -4116,6 +4245,9 @@ void GLCanvas3D::set_viewport_from_scene(const GLCanvas3D& other)
|
|||
m_camera.set_scene_box(other.m_camera.get_scene_box(), *this);
|
||||
m_camera.set_target(other.m_camera.get_target(), *this);
|
||||
m_camera.zoom = other.m_camera.zoom;
|
||||
#if ENABLE_REWORKED_BED_SHAPE_CHANGE
|
||||
m_requires_zoom_to_bed = false;
|
||||
#endif // ENABLE_REWORKED_BED_SHAPE_CHANGE
|
||||
m_dirty = true;
|
||||
}
|
||||
|
||||
|
@ -4168,8 +4300,18 @@ void GLCanvas3D::render()
|
|||
#endif // ENABLE_USE_UNIQUE_GLCONTEXT
|
||||
return;
|
||||
|
||||
#if ENABLE_REWORKED_BED_SHAPE_CHANGE
|
||||
if (m_requires_zoom_to_bed)
|
||||
{
|
||||
zoom_to_bed();
|
||||
const Size& cnv_size = get_canvas_size();
|
||||
_resize((unsigned int)cnv_size.get_width(), (unsigned int)cnv_size.get_height());
|
||||
m_requires_zoom_to_bed = false;
|
||||
}
|
||||
#else
|
||||
if (m_force_zoom_to_bed_enabled)
|
||||
_force_zoom_to_bed();
|
||||
#endif // ENABLE_REWORKED_BED_SHAPE_CHANGE
|
||||
|
||||
_camera_tranform();
|
||||
|
||||
|
@ -4239,7 +4381,8 @@ void GLCanvas3D::render()
|
|||
_resize_toolbars();
|
||||
_render_toolbar();
|
||||
_render_view_toolbar();
|
||||
_render_layer_editing_overlay();
|
||||
if (m_layers_editing.last_object_id >= 0)
|
||||
m_layers_editing.render_overlay(*this);
|
||||
|
||||
#if ENABLE_IMGUI
|
||||
wxGetApp().imgui()->render();
|
||||
|
@ -4479,8 +4622,6 @@ void GLCanvas3D::reload_scene(bool refresh_immediately, bool force_full_scene_re
|
|||
m_volumes.volumes = std::move(glvolumes_new);
|
||||
for (unsigned int obj_idx = 0; obj_idx < (unsigned int)m_model->objects.size(); ++ obj_idx) {
|
||||
const ModelObject &model_object = *m_model->objects[obj_idx];
|
||||
// Object will share a single common layer height texture between all printable volumes.
|
||||
std::shared_ptr<LayersTexture> layer_height_texture;
|
||||
for (int volume_idx = 0; volume_idx < (int)model_object.volumes.size(); ++ volume_idx) {
|
||||
const ModelVolume &model_volume = *model_object.volumes[volume_idx];
|
||||
for (int instance_idx = 0; instance_idx < (int)model_object.instances.size(); ++ instance_idx) {
|
||||
|
@ -4490,33 +4631,7 @@ void GLCanvas3D::reload_scene(bool refresh_immediately, bool force_full_scene_re
|
|||
assert(it != model_volume_state.end() && it->geometry_id == key.geometry_id);
|
||||
if (it->new_geometry()) {
|
||||
// New volume.
|
||||
if (model_volume.is_model_part() && ! layer_height_texture) {
|
||||
// New object part needs to have the layer height texture assigned, which is shared with the other volumes of the same part.
|
||||
// Search for the layer height texture in the other volumes.
|
||||
for (int iv = volume_idx; iv < (int)model_object.volumes.size(); ++ iv) {
|
||||
const ModelVolume &mv = *model_object.volumes[iv];
|
||||
if (mv.is_model_part())
|
||||
for (int ii = instance_idx; ii < (int)model_object.instances.size(); ++ ii) {
|
||||
const ModelInstance &mi = *model_object.instances[ii];
|
||||
ModelVolumeState key(mv.id(), mi.id());
|
||||
auto it = std::lower_bound(model_volume_state.begin(), model_volume_state.end(), key, model_volume_state_lower);
|
||||
assert(it != model_volume_state.end() && it->geometry_id == key.geometry_id);
|
||||
if (! it->new_geometry()) {
|
||||
// Found an old printable GLVolume (existing before this function was called).
|
||||
assert(m_volumes.volumes[it->volume_idx]->geometry_id == key.geometry_id);
|
||||
// Reuse the layer height texture.
|
||||
const GLVolume *volume = m_volumes.volumes[it->volume_idx];
|
||||
assert(volume->layer_height_texture);
|
||||
layer_height_texture = volume->layer_height_texture;
|
||||
goto iv_end;
|
||||
}
|
||||
}
|
||||
}
|
||||
iv_end:
|
||||
if (! layer_height_texture)
|
||||
layer_height_texture = std::make_shared<LayersTexture>();
|
||||
}
|
||||
m_volumes.load_object_volume(&model_object, layer_height_texture, obj_idx, volume_idx, instance_idx, m_color_by, m_use_VBOs && m_initialized);
|
||||
m_volumes.load_object_volume(&model_object, obj_idx, volume_idx, instance_idx, m_color_by, m_use_VBOs && m_initialized);
|
||||
m_volumes.volumes.back()->geometry_id = key.geometry_id;
|
||||
} else {
|
||||
// Recycling an old GLVolume.
|
||||
|
@ -4524,11 +4639,6 @@ void GLCanvas3D::reload_scene(bool refresh_immediately, bool force_full_scene_re
|
|||
assert(existing_volume.geometry_id == key.geometry_id);
|
||||
// Update the Object/Volume/Instance indices into the current Model.
|
||||
existing_volume.composite_id = it->composite_id;
|
||||
if (model_volume.is_model_part() && ! layer_height_texture) {
|
||||
assert(existing_volume.layer_height_texture);
|
||||
// cache its layer height texture
|
||||
layer_height_texture = existing_volume.layer_height_texture;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -4922,10 +5032,8 @@ void GLCanvas3D::on_mouse_wheel(wxMouseEvent& evt)
|
|||
|
||||
void GLCanvas3D::on_timer(wxTimerEvent& evt)
|
||||
{
|
||||
if (m_layers_editing.state != LayersEditing::Editing)
|
||||
return;
|
||||
|
||||
_perform_layer_editing_action();
|
||||
if (m_layers_editing.state == LayersEditing::Editing)
|
||||
_perform_layer_editing_action();
|
||||
}
|
||||
|
||||
void GLCanvas3D::on_mouse(wxMouseEvent& evt)
|
||||
|
@ -4944,7 +5052,7 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt)
|
|||
|
||||
int selected_object_idx = m_selection.get_object_idx();
|
||||
int layer_editing_object_idx = is_layers_editing_enabled() ? selected_object_idx : -1;
|
||||
m_layers_editing.last_object_id = layer_editing_object_idx;
|
||||
m_layers_editing.select_object(*m_model, layer_editing_object_idx);
|
||||
bool gizmos_overlay_contains_mouse = m_gizmos.overlay_contains_mouse(*this, m_mouse.position);
|
||||
int toolbar_contains_mouse = m_toolbar.contains_mouse(m_mouse.position, *this);
|
||||
int view_toolbar_contains_mouse = (m_view_toolbar != nullptr) ? m_view_toolbar->contains_mouse(m_mouse.position, *this) : -1;
|
||||
|
@ -5009,10 +5117,8 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt)
|
|||
{
|
||||
if (evt.LeftDown())
|
||||
{
|
||||
// A volume is selected and the mouse is inside the reset button.
|
||||
// The PrintObject::adjust_layer_height_profile() call adjusts the profile of its associated ModelObject, it does not modify the profile of the PrintObject itself,
|
||||
// therefore it is safe to call it while the background processing is running.
|
||||
const_cast<PrintObject*>(this->fff_print()->get_object(layer_editing_object_idx))->reset_layer_height_profile();
|
||||
// A volume is selected and the mouse is inside the reset button. Reset the ModelObject's layer height profile.
|
||||
m_model->objects[layer_editing_object_idx]->layer_height_profile.clear();
|
||||
// Index 2 means no editing, just wait for mouse up event.
|
||||
m_layers_editing.state = LayersEditing::Completed;
|
||||
|
||||
|
@ -5273,9 +5379,7 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt)
|
|||
{
|
||||
m_layers_editing.state = LayersEditing::Unknown;
|
||||
_stop_timer();
|
||||
|
||||
if (layer_editing_object_idx != -1)
|
||||
post_event(SimpleEvent(EVT_GLCANVAS_MODEL_UPDATE));
|
||||
m_layers_editing.accept_changes(*this);
|
||||
}
|
||||
else if ((m_mouse.drag.move_volume_idx != -1) && m_mouse.dragging)
|
||||
{
|
||||
|
@ -5365,9 +5469,8 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt)
|
|||
std::string tooltip = "";
|
||||
|
||||
// updates gizmos overlay
|
||||
if (!m_selection.is_empty())
|
||||
tooltip = m_gizmos.update_hover_state(*this, m_mouse.position, m_selection);
|
||||
else
|
||||
tooltip = m_gizmos.update_hover_state(*this, m_mouse.position, m_selection);
|
||||
if (m_selection.is_empty())
|
||||
m_gizmos.reset_all_states();
|
||||
|
||||
// updates toolbar overlay
|
||||
|
@ -5452,7 +5555,9 @@ void GLCanvas3D::set_tooltip(const std::string& tooltip) const
|
|||
wxToolTip* t = m_canvas->GetToolTip();
|
||||
if (t != nullptr)
|
||||
{
|
||||
if (t->GetTip() != tooltip)
|
||||
if (tooltip.empty())
|
||||
m_canvas->UnsetToolTip();
|
||||
else
|
||||
t->SetTip(tooltip);
|
||||
}
|
||||
else
|
||||
|
@ -5737,11 +5842,13 @@ bool GLCanvas3D::_is_shown_on_screen() const
|
|||
return (m_canvas != nullptr) ? m_canvas->IsShownOnScreen() : false;
|
||||
}
|
||||
|
||||
#if !ENABLE_REWORKED_BED_SHAPE_CHANGE
|
||||
void GLCanvas3D::_force_zoom_to_bed()
|
||||
{
|
||||
zoom_to_bed();
|
||||
m_force_zoom_to_bed_enabled = false;
|
||||
}
|
||||
#endif // !ENABLE_REWORKED_BED_SHAPE_CHANGE
|
||||
|
||||
bool GLCanvas3D::_init_toolbar()
|
||||
{
|
||||
|
@ -5783,7 +5890,7 @@ bool GLCanvas3D::_init_toolbar()
|
|||
GLToolbarItem::Data item;
|
||||
|
||||
item.name = "add";
|
||||
item.tooltip = GUI::L_str("Add...");
|
||||
item.tooltip = GUI::L_str("Add... [Ctrl+I]");
|
||||
item.sprite_id = 0;
|
||||
item.is_toggable = false;
|
||||
item.action_event = EVT_GLTOOLBAR_ADD;
|
||||
|
@ -5791,7 +5898,7 @@ bool GLCanvas3D::_init_toolbar()
|
|||
return false;
|
||||
|
||||
item.name = "delete";
|
||||
item.tooltip = GUI::L_str("Delete");
|
||||
item.tooltip = GUI::L_str("Delete [Del]");
|
||||
item.sprite_id = 1;
|
||||
item.is_toggable = false;
|
||||
item.action_event = EVT_GLTOOLBAR_DELETE;
|
||||
|
@ -5799,7 +5906,7 @@ bool GLCanvas3D::_init_toolbar()
|
|||
return false;
|
||||
|
||||
item.name = "deleteall";
|
||||
item.tooltip = GUI::L_str("Delete all");
|
||||
item.tooltip = GUI::L_str("Delete all [Ctrl+Del]");
|
||||
item.sprite_id = 2;
|
||||
item.is_toggable = false;
|
||||
item.action_event = EVT_GLTOOLBAR_DELETE_ALL;
|
||||
|
@ -5807,7 +5914,7 @@ bool GLCanvas3D::_init_toolbar()
|
|||
return false;
|
||||
|
||||
item.name = "arrange";
|
||||
item.tooltip = GUI::L_str("Arrange");
|
||||
item.tooltip = GUI::L_str("Arrange [A]");
|
||||
item.sprite_id = 3;
|
||||
item.is_toggable = false;
|
||||
item.action_event = EVT_GLTOOLBAR_ARRANGE;
|
||||
|
@ -5818,7 +5925,7 @@ bool GLCanvas3D::_init_toolbar()
|
|||
return false;
|
||||
|
||||
item.name = "more";
|
||||
item.tooltip = GUI::L_str("Add instance");
|
||||
item.tooltip = GUI::L_str("Add instance [+]");
|
||||
item.sprite_id = 4;
|
||||
item.is_toggable = false;
|
||||
item.action_event = EVT_GLTOOLBAR_MORE;
|
||||
|
@ -5826,7 +5933,7 @@ bool GLCanvas3D::_init_toolbar()
|
|||
return false;
|
||||
|
||||
item.name = "fewer";
|
||||
item.tooltip = GUI::L_str("Remove instance");
|
||||
item.tooltip = GUI::L_str("Remove instance [-]");
|
||||
item.sprite_id = 5;
|
||||
item.is_toggable = false;
|
||||
item.action_event = EVT_GLTOOLBAR_FEWER;
|
||||
|
@ -5973,7 +6080,11 @@ void GLCanvas3D::_zoom_to_bounding_box(const BoundingBoxf3& bbox)
|
|||
|
||||
viewport_changed();
|
||||
|
||||
#if ENABLE_REWORKED_BED_SHAPE_CHANGE
|
||||
m_dirty = true;
|
||||
#else
|
||||
_refresh_if_shown_on_screen();
|
||||
#endif // ENABLE_REWORKED_BED_SHAPE_CHANGE
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -6044,28 +6155,6 @@ float GLCanvas3D::_get_zoom_to_bounding_box_factor(const BoundingBoxf3& bbox) co
|
|||
return (float)std::min((double)cnv_size.get_width() / max_x, (double)cnv_size.get_height() / max_y);
|
||||
}
|
||||
|
||||
void GLCanvas3D::_mark_volumes_for_layer_height() const
|
||||
{
|
||||
const Print *print = (m_process == nullptr) ? nullptr : m_process->fff_print();
|
||||
if (print == nullptr)
|
||||
return;
|
||||
|
||||
for (GLVolume* vol : m_volumes.volumes)
|
||||
{
|
||||
int object_id = vol->object_idx();
|
||||
int shader_id = m_layers_editing.get_shader_program_id();
|
||||
|
||||
if (is_layers_editing_enabled() && (shader_id != -1) && vol->selected &&
|
||||
vol->has_layer_height_texture() && (object_id < (int)print->objects().size()))
|
||||
{
|
||||
vol->set_layer_height_texture_data(m_layers_editing.get_z_texture_id(), shader_id,
|
||||
print->get_object(object_id), _get_layers_editing_cursor_z_relative(), m_layers_editing.band_width);
|
||||
}
|
||||
else
|
||||
vol->reset_layer_height_texture_data();
|
||||
}
|
||||
}
|
||||
|
||||
void GLCanvas3D::_refresh_if_shown_on_screen()
|
||||
{
|
||||
if (_is_shown_on_screen())
|
||||
|
@ -6075,11 +6164,15 @@ void GLCanvas3D::_refresh_if_shown_on_screen()
|
|||
|
||||
// Because of performance problems on macOS, where PaintEvents are not delivered
|
||||
// frequently enough, we call render() here directly when we can.
|
||||
#if ENABLE_REWORKED_BED_SHAPE_CHANGE
|
||||
render();
|
||||
#else
|
||||
// We can't do that when m_force_zoom_to_bed_enabled == true, because then render()
|
||||
// ends up calling back here via _force_zoom_to_bed(), causing a stack overflow.
|
||||
if (m_canvas != nullptr) {
|
||||
m_force_zoom_to_bed_enabled ? m_canvas->Refresh() : render();
|
||||
}
|
||||
#endif // ENABLE_REWORKED_BED_SHAPE_CHANGE
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -6207,7 +6300,8 @@ void GLCanvas3D::_render_objects() const
|
|||
{
|
||||
if (m_picking_enabled)
|
||||
{
|
||||
_mark_volumes_for_layer_height();
|
||||
// Update the layer editing selection to the first object selected, update the current object maximum Z.
|
||||
const_cast<LayersEditing&>(m_layers_editing).select_object(*m_model, this->is_layers_editing_enabled() ? m_selection.get_object_idx() : -1);
|
||||
|
||||
if (m_config != nullptr)
|
||||
{
|
||||
|
@ -6228,8 +6322,18 @@ void GLCanvas3D::_render_objects() const
|
|||
|
||||
m_shader.start_using();
|
||||
#if ENABLE_IMPROVED_TRANSPARENT_VOLUMES_RENDERING
|
||||
// do not cull backfaces to show broken geometry, if any
|
||||
m_volumes.render_VBOs(GLVolumeCollection::Opaque, m_picking_enabled);
|
||||
if (m_picking_enabled && m_layers_editing.is_enabled() && m_layers_editing.last_object_id != -1) {
|
||||
int object_id = m_layers_editing.last_object_id;
|
||||
m_volumes.render_VBOs(GLVolumeCollection::Opaque, false, [object_id](const GLVolume &volume) {
|
||||
// Which volume to paint without the layer height profile shader?
|
||||
return volume.is_active && (volume.is_modifier || volume.composite_id.object_id != object_id);
|
||||
});
|
||||
// Let LayersEditing handle rendering of the active object using the layer height profile shader.
|
||||
m_layers_editing.render_volumes(*this, this->m_volumes);
|
||||
} else {
|
||||
// do not cull backfaces to show broken geometry, if any
|
||||
m_volumes.render_VBOs(GLVolumeCollection::Opaque, m_picking_enabled);
|
||||
}
|
||||
m_volumes.render_VBOs(GLVolumeCollection::Transparent, false);
|
||||
#else
|
||||
m_volumes.render_VBOs();
|
||||
|
@ -6310,39 +6414,6 @@ void GLCanvas3D::_render_legend_texture() const
|
|||
m_legend_texture.render(*this);
|
||||
}
|
||||
|
||||
void GLCanvas3D::_render_layer_editing_overlay() const
|
||||
{
|
||||
const Print *print = this->fff_print();
|
||||
if ((print == nullptr) || print->objects().empty())
|
||||
return;
|
||||
|
||||
GLVolume* volume = nullptr;
|
||||
|
||||
for (GLVolume* vol : m_volumes.volumes)
|
||||
{
|
||||
if ((vol != nullptr) && vol->selected && vol->has_layer_height_texture())
|
||||
{
|
||||
volume = vol;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (volume == nullptr)
|
||||
return;
|
||||
|
||||
// If the active object was not allocated at the Print, go away.This should only be a momentary case between an object addition / deletion
|
||||
// and an update by Platter::async_apply_config.
|
||||
int object_idx = volume->object_idx();
|
||||
if ((int)print->objects().size() <= object_idx)
|
||||
return;
|
||||
|
||||
const PrintObject* print_object = print->get_object(object_idx);
|
||||
if (print_object == nullptr)
|
||||
return;
|
||||
|
||||
m_layers_editing.render(*this, *print_object, *volume);
|
||||
}
|
||||
|
||||
void GLCanvas3D::_render_volumes(bool fake_colors) const
|
||||
{
|
||||
static const GLfloat INV_255 = 1.0f / 255.0f;
|
||||
|
@ -6742,55 +6813,24 @@ void GLCanvas3D::_update_gizmos_data()
|
|||
}
|
||||
}
|
||||
|
||||
float GLCanvas3D::_get_layers_editing_cursor_z_relative() const
|
||||
{
|
||||
return m_layers_editing.get_cursor_z_relative(*this);
|
||||
}
|
||||
|
||||
void GLCanvas3D::_perform_layer_editing_action(wxMouseEvent* evt)
|
||||
{
|
||||
int object_idx_selected = m_layers_editing.last_object_id;
|
||||
if (object_idx_selected == -1)
|
||||
return;
|
||||
|
||||
const Print *print = this->fff_print();
|
||||
if (print == nullptr)
|
||||
return;
|
||||
|
||||
const PrintObject* selected_obj = print->get_object(object_idx_selected);
|
||||
if (selected_obj == nullptr)
|
||||
return;
|
||||
|
||||
// A volume is selected. Test, whether hovering over a layer thickness bar.
|
||||
if (evt != nullptr)
|
||||
{
|
||||
const Rect& rect = LayersEditing::get_bar_rect_screen(*this);
|
||||
float b = rect.get_bottom();
|
||||
m_layers_editing.last_z = unscale<double>(selected_obj->size(2)) * (b - evt->GetY() - 1.0f) / (b - rect.get_top());
|
||||
m_layers_editing.last_action = evt->ShiftDown() ? (evt->RightIsDown() ? 3 : 2) : (evt->RightIsDown() ? 0 : 1);
|
||||
m_layers_editing.last_z = m_layers_editing.object_max_z() * (b - evt->GetY() - 1.0f) / (b - rect.get_top());
|
||||
m_layers_editing.last_action =
|
||||
evt->ShiftDown() ? (evt->RightIsDown() ? LAYER_HEIGHT_EDIT_ACTION_SMOOTH : LAYER_HEIGHT_EDIT_ACTION_REDUCE) :
|
||||
(evt->RightIsDown() ? LAYER_HEIGHT_EDIT_ACTION_INCREASE : LAYER_HEIGHT_EDIT_ACTION_DECREASE);
|
||||
}
|
||||
|
||||
// Mark the volume as modified, so Print will pick its layer height profile ? Where to mark it ?
|
||||
// Start a timer to refresh the print ? schedule_background_process() ?
|
||||
// The PrintObject::adjust_layer_height_profile() call adjusts the profile of its associated ModelObject, it does not modify the profile of the PrintObject itself,
|
||||
// therefore it is safe to call it while the background processing is running.
|
||||
const_cast<PrintObject*>(selected_obj)->adjust_layer_height_profile(m_layers_editing.last_z, m_layers_editing.strength, m_layers_editing.band_width, m_layers_editing.last_action);
|
||||
|
||||
// searches the id of the first volume of the selected object
|
||||
int volume_idx = 0;
|
||||
for (int i = 0; i < object_idx_selected; ++i)
|
||||
{
|
||||
const PrintObject* obj = print->get_object(i);
|
||||
if (obj != nullptr)
|
||||
{
|
||||
for (int j = 0; j < (int)obj->region_volumes.size(); ++j)
|
||||
{
|
||||
volume_idx += (int)obj->region_volumes[j].size();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m_volumes.volumes[volume_idx]->generate_layer_height_texture(selected_obj, 1);
|
||||
m_layers_editing.adjust_layer_height_profile();
|
||||
_refresh_if_shown_on_screen();
|
||||
|
||||
// Automatic action on mouse down with the same coordinate.
|
||||
|
|
|
@ -29,6 +29,8 @@ class GLShader;
|
|||
class ExPolygon;
|
||||
class BackgroundSlicingProcess;
|
||||
class GCodePreviewData;
|
||||
struct SlicingParameters;
|
||||
enum LayerHeightEditActionType : unsigned int;
|
||||
|
||||
namespace GUI {
|
||||
|
||||
|
@ -101,7 +103,6 @@ wxDECLARE_EVENT(EVT_GLCANVAS_INIT, SimpleEvent);
|
|||
wxDECLARE_EVENT(EVT_GLCANVAS_SCHEDULE_BACKGROUND_PROCESS, SimpleEvent);
|
||||
wxDECLARE_EVENT(EVT_GLCANVAS_VIEWPORT_CHANGED, SimpleEvent);
|
||||
wxDECLARE_EVENT(EVT_GLCANVAS_RIGHT_CLICK, Vec2dEvent);
|
||||
wxDECLARE_EVENT(EVT_GLCANVAS_MODEL_UPDATE, SimpleEvent);
|
||||
wxDECLARE_EVENT(EVT_GLCANVAS_REMOVE_OBJECT, SimpleEvent);
|
||||
wxDECLARE_EVENT(EVT_GLCANVAS_ARRANGE, SimpleEvent);
|
||||
wxDECLARE_EVENT(EVT_GLCANVAS_QUESTION_MARK, SimpleEvent);
|
||||
|
@ -293,12 +294,42 @@ class GLCanvas3D
|
|||
};
|
||||
|
||||
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;
|
||||
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;
|
||||
// Not owned by LayersEditing.
|
||||
const DynamicPrintConfig *m_config;
|
||||
// ModelObject for the currently selected object (Model::objects[last_object_id]).
|
||||
const ModelObject *m_model_object;
|
||||
// Maximum z of the currently selected object (Model::objects[last_object_id]).
|
||||
float m_object_max_z;
|
||||
// Owned by LayersEditing.
|
||||
SlicingParameters *m_slicing_parameters;
|
||||
std::vector<coordf_t> m_layer_height_profile;
|
||||
bool m_layer_height_profile_modified;
|
||||
|
||||
class LayersTexture
|
||||
{
|
||||
public:
|
||||
LayersTexture() : width(0), height(0), levels(0), cells(0), valid(false) {}
|
||||
|
||||
// Texture data
|
||||
std::vector<char> data;
|
||||
// Width of the texture, top level.
|
||||
size_t width;
|
||||
// Height of the texture, top level.
|
||||
size_t height;
|
||||
// For how many levels of detail is the data allocated?
|
||||
size_t levels;
|
||||
// Number of texture cells allocated for the height texture.
|
||||
size_t cells;
|
||||
// Does it need to be refreshed?
|
||||
bool valid;
|
||||
};
|
||||
LayersTexture m_layers_texture;
|
||||
|
||||
public:
|
||||
EState state;
|
||||
|
@ -306,12 +337,14 @@ class GLCanvas3D
|
|||
float strength;
|
||||
int last_object_id;
|
||||
float last_z;
|
||||
unsigned int last_action;
|
||||
LayerHeightEditActionType last_action;
|
||||
|
||||
LayersEditing();
|
||||
~LayersEditing();
|
||||
|
||||
bool init(const std::string& vertex_shader_filename, const std::string& fragment_shader_filename);
|
||||
void set_config(const DynamicPrintConfig* config) { m_config = config; }
|
||||
void select_object(const Model &model, int object_id);
|
||||
|
||||
bool is_allowed() const;
|
||||
void set_use_legacy_opengl(bool use_legacy_opengl);
|
||||
|
@ -319,11 +352,12 @@ class GLCanvas3D
|
|||
bool is_enabled() const;
|
||||
void set_enabled(bool enabled);
|
||||
|
||||
unsigned int get_z_texture_id() const;
|
||||
void render_overlay(const GLCanvas3D& canvas) const;
|
||||
void render_volumes(const GLCanvas3D& canvas, const GLVolumeCollection& volumes) const;
|
||||
|
||||
void render(const GLCanvas3D& canvas, const PrintObject& print_object, const GLVolume& volume) const;
|
||||
|
||||
int get_shader_program_id() const;
|
||||
void generate_layer_height_texture();
|
||||
void adjust_layer_height_profile();
|
||||
void accept_changes(GLCanvas3D& canvas);
|
||||
|
||||
static float get_cursor_z_relative(const GLCanvas3D& canvas);
|
||||
static bool bar_rect_contains(const GLCanvas3D& canvas, float x, float y);
|
||||
|
@ -333,12 +367,14 @@ class GLCanvas3D
|
|||
static Rect get_bar_rect_viewport(const GLCanvas3D& canvas);
|
||||
static Rect get_reset_rect_viewport(const GLCanvas3D& canvas);
|
||||
|
||||
float object_max_z() const { return m_object_max_z; }
|
||||
|
||||
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;
|
||||
void _render_active_object_annotations(const GLCanvas3D& canvas, const Rect& bar_rect) const;
|
||||
void _render_profile(const Rect& bar_rect) const;
|
||||
};
|
||||
|
||||
struct Mouse
|
||||
|
@ -821,7 +857,7 @@ private:
|
|||
|
||||
mutable GLVolumeCollection m_volumes;
|
||||
Selection m_selection;
|
||||
DynamicPrintConfig* m_config;
|
||||
const DynamicPrintConfig* m_config;
|
||||
Model* m_model;
|
||||
BackgroundSlicingProcess *m_process;
|
||||
|
||||
|
@ -829,7 +865,11 @@ private:
|
|||
bool m_dirty;
|
||||
bool m_initialized;
|
||||
bool m_use_VBOs;
|
||||
#if ENABLE_REWORKED_BED_SHAPE_CHANGE
|
||||
bool m_requires_zoom_to_bed;
|
||||
#else
|
||||
bool m_force_zoom_to_bed_enabled;
|
||||
#endif // ENABLE_REWORKED_BED_SHAPE_CHANGE
|
||||
bool m_apply_zoom_to_volumes_filter;
|
||||
mutable int m_hover_volume_id;
|
||||
bool m_toolbar_action_running;
|
||||
|
@ -877,7 +917,7 @@ public:
|
|||
void reset_volumes();
|
||||
int check_volumes_outside_state() const;
|
||||
|
||||
void set_config(DynamicPrintConfig* config);
|
||||
void set_config(const DynamicPrintConfig* config);
|
||||
void set_process(BackgroundSlicingProcess* process);
|
||||
void set_model(Model* model);
|
||||
|
||||
|
@ -920,7 +960,9 @@ public:
|
|||
void enable_moving(bool enable);
|
||||
void enable_gizmos(bool enable);
|
||||
void enable_toolbar(bool enable);
|
||||
#if !ENABLE_REWORKED_BED_SHAPE_CHANGE
|
||||
void enable_force_zoom_to_bed(bool enable);
|
||||
#endif // !ENABLE_REWORKED_BED_SHAPE_CHANGE
|
||||
void enable_dynamic_background(bool enable);
|
||||
void allow_multisample(bool allow);
|
||||
|
||||
|
@ -1001,7 +1043,9 @@ public:
|
|||
|
||||
private:
|
||||
bool _is_shown_on_screen() const;
|
||||
#if !ENABLE_REWORKED_BED_SHAPE_CHANGE
|
||||
void _force_zoom_to_bed();
|
||||
#endif // !ENABLE_REWORKED_BED_SHAPE_CHANGE
|
||||
|
||||
bool _init_toolbar();
|
||||
|
||||
|
@ -1015,7 +1059,6 @@ private:
|
|||
void _zoom_to_bounding_box(const BoundingBoxf3& bbox);
|
||||
float _get_zoom_to_bounding_box_factor(const BoundingBoxf3& bbox) const;
|
||||
|
||||
void _mark_volumes_for_layer_height() const;
|
||||
void _refresh_if_shown_on_screen();
|
||||
|
||||
void _camera_tranform() const;
|
||||
|
@ -1030,7 +1073,6 @@ private:
|
|||
#endif // ENABLE_RENDER_SELECTION_CENTER
|
||||
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_current_gizmo() const;
|
||||
void _render_gizmos_overlay() const;
|
||||
|
@ -1047,7 +1089,6 @@ private:
|
|||
void _update_volumes_hover_state() const;
|
||||
void _update_gizmos_data();
|
||||
|
||||
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.
|
||||
|
|
|
@ -748,7 +748,7 @@ bool GLGizmoRotate3D::on_init()
|
|||
|
||||
std::string GLGizmoRotate3D::on_get_name() const
|
||||
{
|
||||
return L("Rotate");
|
||||
return L("Rotate [R]");
|
||||
}
|
||||
|
||||
void GLGizmoRotate3D::on_start_dragging(const GLCanvas3D::Selection& selection)
|
||||
|
@ -838,7 +838,7 @@ bool GLGizmoScale3D::on_init()
|
|||
|
||||
std::string GLGizmoScale3D::on_get_name() const
|
||||
{
|
||||
return L("Scale");
|
||||
return L("Scale [S]");
|
||||
}
|
||||
|
||||
void GLGizmoScale3D::on_start_dragging(const GLCanvas3D::Selection& selection)
|
||||
|
@ -1197,7 +1197,7 @@ bool GLGizmoMove3D::on_init()
|
|||
|
||||
std::string GLGizmoMove3D::on_get_name() const
|
||||
{
|
||||
return L("Move");
|
||||
return L("Move [M]");
|
||||
}
|
||||
|
||||
void GLGizmoMove3D::on_start_dragging(const GLCanvas3D::Selection& selection)
|
||||
|
@ -1427,7 +1427,7 @@ bool GLGizmoFlatten::on_init()
|
|||
|
||||
std::string GLGizmoFlatten::on_get_name() const
|
||||
{
|
||||
return L("Place on face");
|
||||
return L("Place on face [F]");
|
||||
}
|
||||
|
||||
bool GLGizmoFlatten::on_is_activable(const GLCanvas3D::Selection& selection) const
|
||||
|
@ -1526,10 +1526,9 @@ void GLGizmoFlatten::update_planes()
|
|||
vol_ch.transform(vol->get_matrix());
|
||||
ch.merge(vol_ch);
|
||||
}
|
||||
|
||||
ch = ch.convex_hull_3d();
|
||||
m_planes.clear();
|
||||
const Transform3d& inst_matrix = m_model_object->instances.front()->get_matrix();
|
||||
const Transform3d& inst_matrix = m_model_object->instances.front()->get_matrix(true);
|
||||
|
||||
// Following constants are used for discarding too small polygons.
|
||||
const float minimal_area = 5.f; // in square mm (world coordinates)
|
||||
|
@ -1559,7 +1558,7 @@ void GLGizmoFlatten::update_planes()
|
|||
while (facet_queue_cnt > 0) {
|
||||
int facet_idx = facet_queue[-- facet_queue_cnt];
|
||||
const stl_normal& this_normal = ch.stl.facet_start[facet_idx].normal;
|
||||
if (this_normal.isApprox(*normal_ptr)) {
|
||||
if (std::abs(this_normal(0) - (*normal_ptr)(0)) < 0.001 && std::abs(this_normal(1) - (*normal_ptr)(1)) < 0.001 && std::abs(this_normal(2) - (*normal_ptr)(2)) < 0.001) {
|
||||
stl_vertex* first_vertex = ch.stl.facet_start[facet_idx].vertex;
|
||||
for (int j=0; j<3; ++j)
|
||||
m_planes.back().vertices.emplace_back((double)first_vertex[j](0), (double)first_vertex[j](1), (double)first_vertex[j](2));
|
||||
|
@ -1696,10 +1695,6 @@ void GLGizmoFlatten::update_planes()
|
|||
|
||||
// Transform back to 3D (and also back to mesh coordinates)
|
||||
polygon = transform(polygon, inst_matrix.inverse() * m.inverse());
|
||||
|
||||
// make sure the points are in correct order:
|
||||
if ( ((inst_matrix.inverse() * m.inverse()) * Vec3d(0., 0., 1.)).dot(normal) > 0.)
|
||||
std::reverse(polygon.begin(),polygon.end());
|
||||
}
|
||||
|
||||
// We'll sort the planes by area and only keep the 254 largest ones (because of the picking pass limitations):
|
||||
|
@ -1714,6 +1709,7 @@ void GLGizmoFlatten::update_planes()
|
|||
m_volumes_types.push_back(vol->type());
|
||||
}
|
||||
m_first_instance_scale = m_model_object->instances.front()->get_scaling_factor();
|
||||
m_first_instance_mirror = m_model_object->instances.front()->get_mirror();
|
||||
}
|
||||
|
||||
|
||||
|
@ -1726,7 +1722,8 @@ bool GLGizmoFlatten::is_plane_update_necessary() const
|
|||
return true;
|
||||
|
||||
// We want to recalculate when the scale changes - some planes could (dis)appear.
|
||||
if (! m_model_object->instances.front()->get_scaling_factor().isApprox(m_first_instance_scale))
|
||||
if (! m_model_object->instances.front()->get_scaling_factor().isApprox(m_first_instance_scale)
|
||||
|| ! m_model_object->instances.front()->get_mirror().isApprox(m_first_instance_mirror))
|
||||
return true;
|
||||
|
||||
for (unsigned int i=0; i < m_model_object->volumes.size(); ++i)
|
||||
|
@ -2240,9 +2237,8 @@ bool GLGizmoSlaSupports::on_is_selectable() const
|
|||
}
|
||||
|
||||
std::string GLGizmoSlaSupports::on_get_name() const
|
||||
|
||||
{
|
||||
return L("SLA Support Points");
|
||||
return L("SLA Support Points [L]");
|
||||
}
|
||||
|
||||
|
||||
|
@ -2353,7 +2349,7 @@ bool GLGizmoCut::on_init()
|
|||
|
||||
std::string GLGizmoCut::on_get_name() const
|
||||
{
|
||||
return L("Cut");
|
||||
return L("Cut [C]");
|
||||
}
|
||||
|
||||
void GLGizmoCut::on_set_state()
|
||||
|
@ -2467,11 +2463,13 @@ void GLGizmoCut::on_render_input_window(float x, float y, const GLCanvas3D::Sele
|
|||
m_imgui->checkbox(_(L("Keep lower part")), m_keep_lower);
|
||||
m_imgui->checkbox(_(L("Rotate lower part upwards")), m_rotate_lower);
|
||||
|
||||
m_imgui->disabled_begin(!m_keep_upper && !m_keep_lower);
|
||||
const bool cut_clicked = m_imgui->button(_(L("Perform cut")));
|
||||
m_imgui->disabled_end();
|
||||
|
||||
m_imgui->end();
|
||||
|
||||
if (cut_clicked) {
|
||||
if (cut_clicked && (m_keep_upper || m_keep_lower)) {
|
||||
perform_cut(selection);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -405,6 +405,7 @@ private:
|
|||
std::vector<Transform3d> m_volumes_matrices;
|
||||
std::vector<ModelVolume::Type> m_volumes_types;
|
||||
Vec3d m_first_instance_scale;
|
||||
Vec3d m_first_instance_mirror;
|
||||
|
||||
std::vector<PlaneData> m_planes;
|
||||
mutable Vec3d m_starting_center;
|
||||
|
|
|
@ -530,6 +530,8 @@ std::string GLToolbar::update_hover_state_horizontal(const Vec2d& mouse_pos, GLC
|
|||
|
||||
GLToolbarItem::EState state = item->get_state();
|
||||
bool inside = (left <= (float)scaled_mouse_pos(0)) && ((float)scaled_mouse_pos(0) <= right) && (bottom <= (float)scaled_mouse_pos(1)) && ((float)scaled_mouse_pos(1) <= top);
|
||||
if (inside)
|
||||
tooltip = item->get_tooltip();
|
||||
|
||||
switch (state)
|
||||
{
|
||||
|
@ -545,9 +547,7 @@ std::string GLToolbar::update_hover_state_horizontal(const Vec2d& mouse_pos, GLC
|
|||
}
|
||||
case GLToolbarItem::Hover:
|
||||
{
|
||||
if (inside)
|
||||
tooltip = item->get_tooltip();
|
||||
else
|
||||
if (!inside)
|
||||
{
|
||||
item->set_state(GLToolbarItem::Normal);
|
||||
parent.set_as_dirty();
|
||||
|
@ -567,9 +567,7 @@ std::string GLToolbar::update_hover_state_horizontal(const Vec2d& mouse_pos, GLC
|
|||
}
|
||||
case GLToolbarItem::HoverPressed:
|
||||
{
|
||||
if (inside)
|
||||
tooltip = item->get_tooltip();
|
||||
else
|
||||
if (!inside)
|
||||
{
|
||||
item->set_state(GLToolbarItem::Pressed);
|
||||
parent.set_as_dirty();
|
||||
|
@ -623,6 +621,8 @@ std::string GLToolbar::update_hover_state_vertical(const Vec2d& mouse_pos, GLCan
|
|||
|
||||
GLToolbarItem::EState state = item->get_state();
|
||||
bool inside = (left <= (float)scaled_mouse_pos(0)) && ((float)scaled_mouse_pos(0) <= right) && (bottom <= (float)scaled_mouse_pos(1)) && ((float)scaled_mouse_pos(1) <= top);
|
||||
if (inside)
|
||||
tooltip = item->get_tooltip();
|
||||
|
||||
switch (state)
|
||||
{
|
||||
|
@ -638,9 +638,7 @@ std::string GLToolbar::update_hover_state_vertical(const Vec2d& mouse_pos, GLCan
|
|||
}
|
||||
case GLToolbarItem::Hover:
|
||||
{
|
||||
if (inside)
|
||||
tooltip = item->get_tooltip();
|
||||
else
|
||||
if (!inside)
|
||||
{
|
||||
item->set_state(GLToolbarItem::Normal);
|
||||
parent.set_as_dirty();
|
||||
|
@ -660,9 +658,7 @@ std::string GLToolbar::update_hover_state_vertical(const Vec2d& mouse_pos, GLCan
|
|||
}
|
||||
case GLToolbarItem::HoverPressed:
|
||||
{
|
||||
if (inside)
|
||||
tooltip = item->get_tooltip();
|
||||
else
|
||||
if (!inside)
|
||||
{
|
||||
item->set_state(GLToolbarItem::Pressed);
|
||||
parent.set_as_dirty();
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
namespace Slic3r {
|
||||
namespace GUI {
|
||||
|
||||
View3D::View3D(wxWindow* parent, Model* model, DynamicPrintConfig* config, BackgroundSlicingProcess* process)
|
||||
View3D::View3D(wxWindow* parent, Model* model, DynamicPrintConfig* config, BackgroundSlicingProcess* process)
|
||||
: m_canvas_widget(nullptr)
|
||||
, m_canvas(nullptr)
|
||||
#if !ENABLE_IMGUI
|
||||
|
@ -69,7 +69,9 @@ bool View3D::init(wxWindow* parent, Model* model, DynamicPrintConfig* config, Ba
|
|||
m_canvas->set_config(config);
|
||||
m_canvas->enable_gizmos(true);
|
||||
m_canvas->enable_toolbar(true);
|
||||
#if !ENABLE_REWORKED_BED_SHAPE_CHANGE
|
||||
m_canvas->enable_force_zoom_to_bed(true);
|
||||
#endif // !ENABLE_REWORKED_BED_SHAPE_CHANGE
|
||||
|
||||
#if !ENABLE_IMGUI
|
||||
m_gizmo_widget = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxDefaultSize);
|
||||
|
@ -107,7 +109,9 @@ void View3D::set_bed_shape(const Pointfs& shape)
|
|||
if (m_canvas != nullptr)
|
||||
{
|
||||
m_canvas->set_bed_shape(shape);
|
||||
#if !ENABLE_REWORKED_BED_SHAPE_CHANGE
|
||||
m_canvas->zoom_to_bed();
|
||||
#endif // !ENABLE_REWORKED_BED_SHAPE_CHANGE
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -12,6 +12,8 @@
|
|||
|
||||
#include <GL/glew.h>
|
||||
|
||||
#include <imgui/imgui_internal.h>
|
||||
|
||||
#include "libslic3r/libslic3r.h"
|
||||
#include "libslic3r/Utils.hpp"
|
||||
#include "GUI.hpp"
|
||||
|
@ -23,6 +25,7 @@ namespace GUI {
|
|||
ImGuiWrapper::ImGuiWrapper()
|
||||
: m_font_texture(0)
|
||||
, m_mouse_buttons(0)
|
||||
, m_disabled(false)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -154,6 +157,26 @@ void ImGuiWrapper::text(const wxString &label)
|
|||
ImGui::Text(label_utf8.c_str(), NULL);
|
||||
}
|
||||
|
||||
void ImGuiWrapper::disabled_begin(bool disabled)
|
||||
{
|
||||
wxCHECK_RET(!m_disabled, "ImGUI: Unbalanced disabled_begin() call");
|
||||
|
||||
if (disabled) {
|
||||
ImGui::PushItemFlag(ImGuiItemFlags_Disabled, true);
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_Alpha, ImGui::GetStyle().Alpha * 0.5f);
|
||||
m_disabled = true;
|
||||
}
|
||||
}
|
||||
|
||||
void ImGuiWrapper::disabled_end()
|
||||
{
|
||||
if (m_disabled) {
|
||||
ImGui::PopItemFlag();
|
||||
ImGui::PopStyleVar();
|
||||
m_disabled = false;
|
||||
}
|
||||
}
|
||||
|
||||
bool ImGuiWrapper::want_mouse() const
|
||||
{
|
||||
return ImGui::GetIO().WantCaptureMouse;
|
||||
|
|
|
@ -21,8 +21,8 @@ class ImGuiWrapper
|
|||
|
||||
FontsMap m_fonts;
|
||||
unsigned m_font_texture;
|
||||
|
||||
unsigned m_mouse_buttons;
|
||||
bool m_disabled;
|
||||
|
||||
public:
|
||||
ImGuiWrapper();
|
||||
|
@ -50,6 +50,9 @@ public:
|
|||
bool checkbox(const wxString &label, bool &value);
|
||||
void text(const wxString &label);
|
||||
|
||||
void disabled_begin(bool disabled);
|
||||
void disabled_end();
|
||||
|
||||
bool want_mouse() const;
|
||||
bool want_keyboard() const;
|
||||
bool want_text_input() const;
|
||||
|
|
|
@ -120,8 +120,7 @@ void KBShortcutsDialog::fill_shortcuts()
|
|||
main_shortcuts.push_back(Shortcut("+" ,L("Add Instance to selected object ")));
|
||||
main_shortcuts.push_back(Shortcut("-" ,L("Remove Instance from selected object")));
|
||||
main_shortcuts.push_back(Shortcut("?" ,L("Show keyboard shortcuts list")));
|
||||
main_shortcuts.push_back(Shortcut("PgUp/PgDn" ,L("Switch between 3D and Preview")));
|
||||
main_shortcuts.push_back(Shortcut("Shift+LeftMouse" ,L("Select multiple object/Move multiple object")));
|
||||
main_shortcuts.push_back(Shortcut("Shift+LeftMouse", L("Select multiple object/Move multiple object")));
|
||||
|
||||
m_full_shortcuts.emplace(_(L("Main Shortcuts")), main_shortcuts);
|
||||
|
||||
|
|
|
@ -159,6 +159,7 @@ void MainFrame::create_preset_tabs()
|
|||
add_created_tab(new TabSLAPrint(m_tabpanel));
|
||||
add_created_tab(new TabSLAMaterial(m_tabpanel));
|
||||
add_created_tab(new TabPrinter(m_tabpanel));
|
||||
GUI::wxGetApp().load_current_presets();
|
||||
}
|
||||
|
||||
void MainFrame::add_created_tab(Tab* panel)
|
||||
|
|
|
@ -1088,7 +1088,10 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame)
|
|||
"brim_width", "variable_layer_height", "serial_port", "serial_speed", "host_type", "print_host",
|
||||
"printhost_apikey", "printhost_cafile", "nozzle_diameter", "single_extruder_multi_material",
|
||||
"wipe_tower", "wipe_tower_x", "wipe_tower_y", "wipe_tower_width", "wipe_tower_rotation_angle",
|
||||
"extruder_colour", "filament_colour", "max_print_height", "printer_model", "printer_technology"
|
||||
"extruder_colour", "filament_colour", "max_print_height", "printer_model", "printer_technology",
|
||||
// The following three layer height config values are passed here for View3D::m_canvas to receive
|
||||
// layer height updates for the layer height.
|
||||
"min_layer_height", "max_layer_height", "layer_height", "first_layer_height"
|
||||
}))
|
||||
, sidebar(new Sidebar(q))
|
||||
, delayed_scene_refresh(false)
|
||||
|
@ -1125,9 +1128,11 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame)
|
|||
this->background_process_timer.SetOwner(this->q, 0);
|
||||
this->q->Bind(wxEVT_TIMER, [this](wxTimerEvent &evt) { this->update_restart_background_process(false, false); });
|
||||
|
||||
#if !ENABLE_REWORKED_BED_SHAPE_CHANGE
|
||||
auto *bed_shape = config->opt<ConfigOptionPoints>("bed_shape");
|
||||
view3D->set_bed_shape(bed_shape->values);
|
||||
preview->set_bed_shape(bed_shape->values);
|
||||
#endif // !ENABLE_REWORKED_BED_SHAPE_CHANGE
|
||||
|
||||
update();
|
||||
|
||||
|
@ -1155,7 +1160,6 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame)
|
|||
view3D_canvas->Bind(EVT_GLCANVAS_OBJECT_SELECT, &priv::on_object_select, this);
|
||||
view3D_canvas->Bind(EVT_GLCANVAS_VIEWPORT_CHANGED, &priv::on_viewport_changed, this);
|
||||
view3D_canvas->Bind(EVT_GLCANVAS_RIGHT_CLICK, &priv::on_right_click, this);
|
||||
view3D_canvas->Bind(EVT_GLCANVAS_MODEL_UPDATE, [this](SimpleEvent&) { this->schedule_background_process(); });
|
||||
view3D_canvas->Bind(EVT_GLCANVAS_REMOVE_OBJECT, [q](SimpleEvent&) { q->remove_selected(); });
|
||||
view3D_canvas->Bind(EVT_GLCANVAS_ARRANGE, [this](SimpleEvent&) { arrange(); });
|
||||
view3D_canvas->Bind(EVT_GLCANVAS_QUESTION_MARK, [this](SimpleEvent&) { wxGetApp().keyboard_shortcuts(); });
|
||||
|
@ -2033,7 +2037,7 @@ void Plater::priv::reload_from_disk()
|
|||
}
|
||||
}
|
||||
|
||||
// XXX: Restore more: layer_height_ranges, layer_height_profile, layer_height_profile_valid (?)
|
||||
// XXX: Restore more: layer_height_ranges, layer_height_profile (?)
|
||||
}
|
||||
|
||||
remove(obj_orig_idx);
|
||||
|
@ -2064,7 +2068,7 @@ void Plater::priv::fix_through_netfabb(const int obj_idx)
|
|||
o->volumes[i]->config.apply(model_object->volumes[i]->config);
|
||||
}
|
||||
}
|
||||
// FIXME restore volumes and their configs, layer_height_ranges, layer_height_profile, layer_height_profile_valid,
|
||||
// FIXME restore volumes and their configs, layer_height_ranges, layer_height_profile
|
||||
}
|
||||
|
||||
remove(obj_idx);
|
||||
|
@ -2490,7 +2494,7 @@ void Plater::priv::init_view_toolbar()
|
|||
GLToolbarItem::Data item;
|
||||
|
||||
item.name = "3D";
|
||||
item.tooltip = GUI::L_str("3D editor view");
|
||||
item.tooltip = GUI::L_str("3D editor view [Ctrl+5]");
|
||||
item.sprite_id = 0;
|
||||
item.action_event = EVT_GLVIEWTOOLBAR_3D;
|
||||
item.is_toggable = false;
|
||||
|
@ -2498,7 +2502,7 @@ void Plater::priv::init_view_toolbar()
|
|||
return;
|
||||
|
||||
item.name = "Preview";
|
||||
item.tooltip = GUI::L_str("Preview");
|
||||
item.tooltip = GUI::L_str("Preview [Ctrl+6]");
|
||||
item.sprite_id = 1;
|
||||
item.action_event = EVT_GLVIEWTOOLBAR_PREVIEW;
|
||||
item.is_toggable = false;
|
||||
|
@ -2765,6 +2769,10 @@ void Plater::cut(size_t obj_idx, size_t instance_idx, coordf_t z, bool keep_uppe
|
|||
|
||||
wxCHECK_RET(instance_idx < object->instances.size(), "instance_idx out of bounds");
|
||||
|
||||
if (!keep_upper && !keep_lower) {
|
||||
return;
|
||||
}
|
||||
|
||||
const auto new_objects = object->cut(instance_idx, z, keep_upper, keep_lower, rotate_lower);
|
||||
|
||||
remove(obj_idx);
|
||||
|
@ -2965,7 +2973,7 @@ void Plater::on_config_change(const DynamicPrintConfig &config)
|
|||
p->config->set_key_value(opt_key, config.option(opt_key)->clone());
|
||||
if (opt_key == "printer_technology")
|
||||
this->set_printer_technology(config.opt_enum<PrinterTechnology>(opt_key));
|
||||
else if (opt_key == "bed_shape") {
|
||||
else if (opt_key == "bed_shape") {
|
||||
if (p->view3D) p->view3D->set_bed_shape(p->config->option<ConfigOptionPoints>(opt_key)->values);
|
||||
if (p->preview) p->preview->set_bed_shape(p->config->option<ConfigOptionPoints>(opt_key)->values);
|
||||
update_scheduled = true;
|
||||
|
@ -2990,12 +2998,14 @@ void Plater::on_config_change(const DynamicPrintConfig &config)
|
|||
p->preview->set_number_extruders(p->config->option<ConfigOptionStrings>(opt_key)->values.size());
|
||||
} else if(opt_key == "max_print_height") {
|
||||
update_scheduled = true;
|
||||
} else if(opt_key == "printer_model") {
|
||||
}
|
||||
else if (opt_key == "printer_model") {
|
||||
// update to force bed selection(for texturing)
|
||||
if (p->view3D) p->view3D->set_bed_shape(p->config->option<ConfigOptionPoints>("bed_shape")->values);
|
||||
if (p->preview) p->preview->set_bed_shape(p->config->option<ConfigOptionPoints>("bed_shape")->values);
|
||||
update_scheduled = true;
|
||||
} else if (opt_key == "host_type" && this->p->printer_technology == ptSLA) {
|
||||
}
|
||||
else if (opt_key == "host_type" && this->p->printer_technology == ptSLA) {
|
||||
p->config->option<ConfigOptionEnum<PrintHostType>>(opt_key)->value = htSL1;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#include "libslic3r/GCodeSender.hpp"
|
||||
// #include "libslic3r/GCodeSender.hpp"
|
||||
#include "Tab.hpp"
|
||||
#include "PresetBundle.hpp"
|
||||
#include "PresetHints.hpp"
|
||||
|
@ -245,9 +245,6 @@ void Tab::create_preset_tab()
|
|||
// Initialize the DynamicPrintConfig by default keys/values.
|
||||
build();
|
||||
rebuild_page_tree();
|
||||
// update();
|
||||
// Load the currently selected preset into the GUI, update the preset selection box.
|
||||
load_current_preset();
|
||||
}
|
||||
|
||||
void Tab::load_initial_data()
|
||||
|
|
|
@ -288,7 +288,7 @@ bool PrusaCollapsiblePaneMSW::Create(wxWindow *parent, wxWindowID id, const wxSt
|
|||
{
|
||||
if (!wxControl::Create(parent, id, pos, size, style, val, name))
|
||||
return false;
|
||||
m_pStaticLine = NULL;
|
||||
// m_pStaticLine = NULL;
|
||||
m_strLabel = label;
|
||||
|
||||
// sizer containing the expand button and possibly a static line
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue