mirror of
https://github.com/SoftFever/OrcaSlicer.git
synced 2025-10-25 17:51:10 -06:00
Merge remote-tracking branch 'origin/master' into ys_new_features
This commit is contained in:
commit
1525a864c5
24 changed files with 624 additions and 499 deletions
|
|
@ -54,10 +54,9 @@ void AppConfig::set_defaults()
|
|||
if (get("preset_update").empty())
|
||||
set("preset_update", "1");
|
||||
|
||||
// Use OpenGL 1.1 even if OpenGL 2.0 is available. This is mainly to support some buggy Intel HD Graphics drivers.
|
||||
// github.com/prusa3d/PrusaSlicer/issues/233
|
||||
if (get("use_legacy_opengl").empty())
|
||||
set("use_legacy_opengl", "0");
|
||||
// remove old 'use_legacy_opengl' parameter from this config, if present
|
||||
if (!get("use_legacy_opengl").empty())
|
||||
erase("", "use_legacy_opengl");
|
||||
|
||||
#if __APPLE__
|
||||
if (get("use_retina_opengl").empty())
|
||||
|
|
@ -73,8 +72,8 @@ void AppConfig::set_defaults()
|
|||
if (get("custom_toolbar_size").empty())
|
||||
set("custom_toolbar_size", "100");
|
||||
|
||||
if (get("camera_type").empty())
|
||||
set("camera_type", "1");
|
||||
if (get("use_perspective_camera").empty())
|
||||
set("use_perspective_camera", "1");
|
||||
|
||||
// Remove legacy window positions/sizes
|
||||
erase("", "main_frame_maximized");
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ Camera::Camera()
|
|||
: phi(45.0f)
|
||||
, requires_zoom_to_bed(false)
|
||||
, inverted_phi(false)
|
||||
, m_type(Ortho)
|
||||
, m_type(Perspective)
|
||||
, m_target(Vec3d::Zero())
|
||||
, m_theta(45.0f)
|
||||
, m_zoom(1.0)
|
||||
|
|
@ -61,20 +61,17 @@ void Camera::set_type(EType type)
|
|||
if (m_type != type)
|
||||
{
|
||||
m_type = type;
|
||||
|
||||
wxGetApp().app_config->set("camera_type", std::to_string(m_type));
|
||||
wxGetApp().app_config->set("use_perspective_camera", (m_type == Perspective) ? "1" : "0");
|
||||
wxGetApp().app_config->save();
|
||||
}
|
||||
}
|
||||
|
||||
void Camera::set_type(const std::string& type)
|
||||
{
|
||||
if (!type.empty() && (type != "1"))
|
||||
{
|
||||
unsigned char type_id = atoi(type.c_str());
|
||||
if (((unsigned char)Ortho < type_id) && (type_id < (unsigned char)Num_types))
|
||||
set_type((Camera::EType)type_id);
|
||||
}
|
||||
if (type == "1")
|
||||
set_type(Perspective);
|
||||
else
|
||||
set_type(Ortho);
|
||||
}
|
||||
|
||||
void Camera::select_next_type()
|
||||
|
|
|
|||
|
|
@ -49,6 +49,7 @@ public:
|
|||
EType get_type() const { return m_type; }
|
||||
std::string get_type_as_string() const;
|
||||
void set_type(EType type);
|
||||
// valid values for type: "0" -> ortho, "1" -> perspective
|
||||
void set_type(const std::string& type);
|
||||
void select_next_type();
|
||||
|
||||
|
|
|
|||
|
|
@ -198,8 +198,7 @@ void GLCanvas3D::Shader::_reset()
|
|||
#endif // !ENABLE_TEXTURES_FROM_SVG
|
||||
|
||||
GLCanvas3D::LayersEditing::LayersEditing()
|
||||
: m_use_legacy_opengl(false)
|
||||
, m_enabled(false)
|
||||
: m_enabled(false)
|
||||
, m_z_texture_id(0)
|
||||
, m_model_object(nullptr)
|
||||
, m_object_max_z(0.f)
|
||||
|
|
@ -274,12 +273,7 @@ void GLCanvas3D::LayersEditing::select_object(const Model &model, int object_id)
|
|||
|
||||
bool GLCanvas3D::LayersEditing::is_allowed() const
|
||||
{
|
||||
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)
|
||||
{
|
||||
m_use_legacy_opengl = use_legacy_opengl;
|
||||
return m_shader.is_initialized() && m_shader.get_shader()->shader_program_id > 0 && m_z_texture_id > 0;
|
||||
}
|
||||
|
||||
bool GLCanvas3D::LayersEditing::is_enabled() const
|
||||
|
|
@ -463,8 +457,10 @@ void GLCanvas3D::LayersEditing::_render_profile(const Rect& bar_rect) const
|
|||
{
|
||||
//FIXME show some kind of legend.
|
||||
|
||||
if (!m_slicing_parameters)
|
||||
return;
|
||||
|
||||
// Make the vertical bar a bit wider so the layer height curve does not touch the edge of the bar region.
|
||||
assert(m_slicing_parameters != nullptr);
|
||||
float scale_x = bar_rect.get_width() / (float)(1.12 * m_slicing_parameters->max_layer_height);
|
||||
float scale_y = bar_rect.get_height() / m_object_max_z;
|
||||
float x = bar_rect.get_left() + (float)m_slicing_parameters->layer_height * scale_x;
|
||||
|
|
@ -1253,7 +1249,7 @@ void GLCanvas3D::post_event(wxEvent &&event)
|
|||
wxPostEvent(m_canvas, event);
|
||||
}
|
||||
|
||||
bool GLCanvas3D::init(bool useVBOs, bool use_legacy_opengl)
|
||||
bool GLCanvas3D::init(bool useVBOs)
|
||||
{
|
||||
if (m_initialized)
|
||||
return true;
|
||||
|
|
@ -1311,7 +1307,6 @@ bool GLCanvas3D::init(bool useVBOs, bool use_legacy_opengl)
|
|||
return false;
|
||||
|
||||
m_use_VBOs = useVBOs;
|
||||
m_layers_editing.set_use_legacy_opengl(use_legacy_opengl);
|
||||
|
||||
// on linux the gl context is not valid until the canvas is not shown on screen
|
||||
// we defer the geometry finalization of volumes until the first call to render()
|
||||
|
|
@ -3317,6 +3312,9 @@ void GLCanvas3D::handle_layers_data_focus_event(const t_layer_height_range range
|
|||
|
||||
void GLCanvas3D::update_ui_from_settings()
|
||||
{
|
||||
m_camera.set_type(wxGetApp().app_config->get("use_perspective_camera"));
|
||||
m_dirty = true;
|
||||
|
||||
#if ENABLE_RETINA_GL
|
||||
const float orig_scaling = m_retina_helper->get_scale_factor();
|
||||
|
||||
|
|
@ -4527,17 +4525,12 @@ void GLCanvas3D::_load_print_object_toolpaths(const PrintObject& print_object, c
|
|||
bool color_by_tool() const { return tool_colors != nullptr; }
|
||||
size_t number_tools() const { return this->color_by_tool() ? tool_colors->size() / 4 : 0; }
|
||||
const float* color_tool(size_t tool) const { return tool_colors->data() + tool * 4; }
|
||||
int volume_idx(int extruder, int feature) const
|
||||
{
|
||||
return this->color_by_color_print() ? 0 : this->color_by_tool() ? std::min<int>(this->number_tools() - 1, std::max<int>(extruder - 1, 0)) : feature;
|
||||
}
|
||||
|
||||
// For coloring by a color_print(M600), return a parsed color.
|
||||
bool color_by_color_print() const { return color_print_values!=nullptr; }
|
||||
const float* color_print_by_layer_idx(const size_t layer_idx) const
|
||||
{
|
||||
const size_t color_print_color_idx_by_layer_idx(const size_t layer_idx) const {
|
||||
auto it = std::lower_bound(color_print_values->begin(), color_print_values->end(), layers[layer_idx]->print_z + EPSILON);
|
||||
return color_tool((it - color_print_values->begin()) % number_tools());
|
||||
return (it - color_print_values->begin()) % number_tools();
|
||||
}
|
||||
} ctxt;
|
||||
|
||||
|
|
@ -4570,7 +4563,7 @@ void GLCanvas3D::_load_print_object_toolpaths(const PrintObject& print_object, c
|
|||
BOOST_LOG_TRIVIAL(debug) << "Loading print object toolpaths in parallel - start";
|
||||
|
||||
//FIXME Improve the heuristics for a grain size.
|
||||
size_t grain_size = ctxt.color_by_color_print() ? size_t(1) : std::max(ctxt.layers.size() / 16, size_t(1));
|
||||
size_t grain_size = std::max(ctxt.layers.size() / 16, size_t(1));
|
||||
tbb::spin_mutex new_volume_mutex;
|
||||
auto new_volume = [this, &new_volume_mutex](const float *color) -> GLVolume* {
|
||||
auto *volume = new GLVolume(color);
|
||||
|
|
@ -4579,14 +4572,34 @@ void GLCanvas3D::_load_print_object_toolpaths(const PrintObject& print_object, c
|
|||
new_volume_mutex.unlock();
|
||||
return volume;
|
||||
};
|
||||
const size_t volumes_cnt_initial = m_volumes.volumes.size();
|
||||
std::vector<GLVolumeCollection> volumes_per_thread(ctxt.layers.size());
|
||||
const size_t volumes_cnt_initial = m_volumes.volumes.size();
|
||||
tbb::parallel_for(
|
||||
tbb::blocked_range<size_t>(0, ctxt.layers.size(), grain_size),
|
||||
[&ctxt, &new_volume](const tbb::blocked_range<size_t>& range) {
|
||||
GLVolumePtrs vols;
|
||||
if (ctxt.color_by_color_print())
|
||||
vols.emplace_back(new_volume(ctxt.color_print_by_layer_idx(range.begin())));
|
||||
GLVolumePtrs vols;
|
||||
std::vector<size_t> color_print_layer_to_glvolume;
|
||||
auto volume = [&ctxt, &vols, &color_print_layer_to_glvolume, &range](size_t layer_idx, int extruder, int feature) -> GLVolume& {
|
||||
return *vols[ctxt.color_by_color_print() ?
|
||||
color_print_layer_to_glvolume[layer_idx - range.begin()] :
|
||||
ctxt.color_by_tool() ?
|
||||
std::min<int>(ctxt.number_tools() - 1, std::max<int>(extruder - 1, 0)) :
|
||||
feature
|
||||
];
|
||||
};
|
||||
if (ctxt.color_by_color_print()) {
|
||||
// Create a map from the layer index to a GLVolume, which is initialized with the correct layer span color.
|
||||
std::vector<int> color_print_tool_to_glvolume(ctxt.number_tools(), -1);
|
||||
color_print_layer_to_glvolume.reserve(range.end() - range.begin());
|
||||
vols.reserve(ctxt.number_tools());
|
||||
for (size_t idx_layer = range.begin(); idx_layer < range.end(); ++ idx_layer) {
|
||||
int idx_tool = (int)ctxt.color_print_color_idx_by_layer_idx(idx_layer);
|
||||
if (color_print_tool_to_glvolume[idx_tool] == -1) {
|
||||
color_print_tool_to_glvolume[idx_tool] = (int)vols.size();
|
||||
vols.emplace_back(new_volume(ctxt.color_tool(idx_tool)));
|
||||
}
|
||||
color_print_layer_to_glvolume.emplace_back(color_print_tool_to_glvolume[idx_tool]);
|
||||
}
|
||||
}
|
||||
else if (ctxt.color_by_tool()) {
|
||||
for (size_t i = 0; i < ctxt.number_tools(); ++i)
|
||||
vols.emplace_back(new_volume(ctxt.color_tool(i)));
|
||||
|
|
@ -4594,33 +4607,31 @@ void GLCanvas3D::_load_print_object_toolpaths(const PrintObject& print_object, c
|
|||
else
|
||||
vols = { new_volume(ctxt.color_perimeters()), new_volume(ctxt.color_infill()), new_volume(ctxt.color_support()) };
|
||||
for (GLVolume *vol : vols)
|
||||
vol->indexed_vertex_array.reserve(ctxt.alloc_size_reserve());
|
||||
for (size_t idx_layer = range.begin(); idx_layer < range.end(); ++idx_layer) {
|
||||
vol->indexed_vertex_array.reserve(ctxt.alloc_size_reserve());
|
||||
for (size_t idx_layer = range.begin(); idx_layer < range.end(); ++ idx_layer) {
|
||||
const Layer *layer = ctxt.layers[idx_layer];
|
||||
for (size_t i = 0; i < vols.size(); ++i) {
|
||||
GLVolume &vol = *vols[i];
|
||||
if (vol.print_zs.empty() || vol.print_zs.back() != layer->print_z) {
|
||||
vol.print_zs.push_back(layer->print_z);
|
||||
vol.offsets.push_back(vol.indexed_vertex_array.quad_indices.size());
|
||||
vol.offsets.push_back(vol.indexed_vertex_array.triangle_indices.size());
|
||||
for (GLVolume *vol : vols)
|
||||
if (vol->print_zs.empty() || vol->print_zs.back() != layer->print_z) {
|
||||
vol->print_zs.push_back(layer->print_z);
|
||||
vol->offsets.push_back(vol->indexed_vertex_array.quad_indices.size());
|
||||
vol->offsets.push_back(vol->indexed_vertex_array.triangle_indices.size());
|
||||
}
|
||||
}
|
||||
for (const Point © : *ctxt.shifted_copies) {
|
||||
for (const LayerRegion *layerm : layer->regions()) {
|
||||
if (ctxt.has_perimeters)
|
||||
_3DScene::extrusionentity_to_verts(layerm->perimeters, float(layer->print_z), copy,
|
||||
*vols[ctxt.volume_idx(layerm->region()->config().perimeter_extruder.value, 0)]);
|
||||
volume(idx_layer, layerm->region()->config().perimeter_extruder.value, 0));
|
||||
if (ctxt.has_infill) {
|
||||
for (const ExtrusionEntity *ee : layerm->fills.entities) {
|
||||
// fill represents infill extrusions of a single island.
|
||||
const auto *fill = dynamic_cast<const ExtrusionEntityCollection*>(ee);
|
||||
if (!fill->entities.empty())
|
||||
if (! fill->entities.empty())
|
||||
_3DScene::extrusionentity_to_verts(*fill, float(layer->print_z), copy,
|
||||
*vols[ctxt.volume_idx(
|
||||
is_solid_infill(fill->entities.front()->role()) ?
|
||||
layerm->region()->config().solid_infill_extruder :
|
||||
layerm->region()->config().infill_extruder,
|
||||
1)]);
|
||||
volume(idx_layer,
|
||||
is_solid_infill(fill->entities.front()->role()) ?
|
||||
layerm->region()->config().solid_infill_extruder :
|
||||
layerm->region()->config().infill_extruder,
|
||||
1));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -4629,36 +4640,37 @@ void GLCanvas3D::_load_print_object_toolpaths(const PrintObject& print_object, c
|
|||
if (support_layer) {
|
||||
for (const ExtrusionEntity *extrusion_entity : support_layer->support_fills.entities)
|
||||
_3DScene::extrusionentity_to_verts(extrusion_entity, float(layer->print_z), copy,
|
||||
*vols[ctxt.volume_idx(
|
||||
(extrusion_entity->role() == erSupportMaterial) ?
|
||||
support_layer->object()->config().support_material_extruder :
|
||||
support_layer->object()->config().support_material_interface_extruder,
|
||||
2)]);
|
||||
volume(idx_layer,
|
||||
(extrusion_entity->role() == erSupportMaterial) ?
|
||||
support_layer->object()->config().support_material_extruder :
|
||||
support_layer->object()->config().support_material_interface_extruder,
|
||||
2));
|
||||
}
|
||||
}
|
||||
}
|
||||
for (size_t i = 0; i < vols.size(); ++i) {
|
||||
GLVolume &vol = *vols[i];
|
||||
if (vol.indexed_vertex_array.vertices_and_normals_interleaved.size() / 6 > ctxt.alloc_size_max()) {
|
||||
// Store the vertex arrays and restart their containers,
|
||||
vols[i] = new_volume(vol.color);
|
||||
GLVolume &vol_new = *vols[i];
|
||||
// Assign the large pre-allocated buffers to the new GLVolume.
|
||||
vol_new.indexed_vertex_array = std::move(vol.indexed_vertex_array);
|
||||
// Copy the content back to the old GLVolume.
|
||||
vol.indexed_vertex_array = vol_new.indexed_vertex_array;
|
||||
// Finalize a bounding box of the old GLVolume.
|
||||
vol.bounding_box = vol.indexed_vertex_array.bounding_box();
|
||||
// Clear the buffers, but keep them pre-allocated.
|
||||
vol_new.indexed_vertex_array.clear();
|
||||
// Just make sure that clear did not clear the reserved memory.
|
||||
vol_new.indexed_vertex_array.reserve(ctxt.alloc_size_reserve());
|
||||
}
|
||||
}
|
||||
// Ensure that no volume grows over the limits. If the volume is too large, allocate a new one.
|
||||
for (size_t i = 0; i < vols.size(); ++i) {
|
||||
GLVolume &vol = *vols[i];
|
||||
if (vol.indexed_vertex_array.vertices_and_normals_interleaved.size() / 6 > ctxt.alloc_size_max()) {
|
||||
// Store the vertex arrays and restart their containers,
|
||||
vols[i] = new_volume(vol.color);
|
||||
GLVolume &vol_new = *vols[i];
|
||||
// Assign the large pre-allocated buffers to the new GLVolume.
|
||||
vol_new.indexed_vertex_array = std::move(vol.indexed_vertex_array);
|
||||
// Copy the content back to the old GLVolume.
|
||||
vol.indexed_vertex_array = vol_new.indexed_vertex_array;
|
||||
// Finalize a bounding box of the old GLVolume.
|
||||
vol.bounding_box = vol.indexed_vertex_array.bounding_box();
|
||||
// Clear the buffers, but keep them pre-allocated.
|
||||
vol_new.indexed_vertex_array.clear();
|
||||
// Just make sure that clear did not clear the reserved memory.
|
||||
vol_new.indexed_vertex_array.reserve(ctxt.alloc_size_reserve());
|
||||
}
|
||||
}
|
||||
}
|
||||
for (GLVolume *vol : vols) {
|
||||
vol->bounding_box = vol->indexed_vertex_array.bounding_box();
|
||||
vol->indexed_vertex_array.shrink_to_fit();
|
||||
vol->bounding_box = vol->indexed_vertex_array.bounding_box();
|
||||
vol->indexed_vertex_array.shrink_to_fit();
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -198,7 +198,6 @@ class GLCanvas3D
|
|||
static const float THICKNESS_BAR_WIDTH;
|
||||
static const float THICKNESS_RESET_BUTTON_HEIGHT;
|
||||
|
||||
bool m_use_legacy_opengl;
|
||||
bool m_enabled;
|
||||
Shader m_shader;
|
||||
unsigned int m_z_texture_id;
|
||||
|
|
@ -251,7 +250,6 @@ class GLCanvas3D
|
|||
void select_object(const Model &model, int object_id);
|
||||
|
||||
bool is_allowed() const;
|
||||
void set_use_legacy_opengl(bool use_legacy_opengl);
|
||||
|
||||
bool is_enabled() const;
|
||||
void set_enabled(bool enabled);
|
||||
|
|
@ -493,7 +491,7 @@ public:
|
|||
wxGLCanvas* get_wxglcanvas() { return m_canvas; }
|
||||
const wxGLCanvas* get_wxglcanvas() const { return m_canvas; }
|
||||
|
||||
bool init(bool useVBOs, bool use_legacy_opengl);
|
||||
bool init(bool useVBOs);
|
||||
void post_event(wxEvent &&event);
|
||||
|
||||
void set_as_dirty();
|
||||
|
|
|
|||
|
|
@ -192,7 +192,6 @@ GLCanvas3DManager::GLInfo GLCanvas3DManager::s_gl_info;
|
|||
GLCanvas3DManager::GLCanvas3DManager()
|
||||
: m_context(nullptr)
|
||||
, m_gl_initialized(false)
|
||||
, m_use_legacy_opengl(false)
|
||||
, m_use_VBOs(false)
|
||||
{
|
||||
}
|
||||
|
|
@ -268,8 +267,7 @@ void GLCanvas3DManager::init_gl()
|
|||
{
|
||||
glewInit();
|
||||
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 && s_gl_info.is_version_greater_or_equal_to(2, 0);
|
||||
m_use_VBOs = s_gl_info.is_version_greater_or_equal_to(2, 0);
|
||||
m_gl_initialized = true;
|
||||
if (GLEW_EXT_texture_compression_s3tc)
|
||||
s_compressed_textures_supported = true;
|
||||
|
|
@ -325,16 +323,14 @@ bool GLCanvas3DManager::init(GLCanvas3D& canvas)
|
|||
if (!m_gl_initialized)
|
||||
init_gl();
|
||||
|
||||
return canvas.init(m_use_VBOs, m_use_legacy_opengl);
|
||||
return canvas.init(m_use_VBOs);
|
||||
}
|
||||
|
||||
void GLCanvas3DManager::detect_multisample(int* attribList)
|
||||
{
|
||||
int wxVersion = wxMAJOR_VERSION * 10000 + wxMINOR_VERSION * 100 + wxRELEASE_NUMBER;
|
||||
const AppConfig* app_config = GUI::get_app_config();
|
||||
bool enable_multisample = app_config != nullptr
|
||||
&& app_config->get("use_legacy_opengl") != "1"
|
||||
&& wxVersion >= 30003;
|
||||
bool enable_multisample = wxVersion >= 30003;
|
||||
|
||||
s_multisample = (enable_multisample && wxGLCanvas::IsDisplaySupported(attribList)) ? MS_Enabled : MS_Disabled;
|
||||
// Alternative method: it was working on previous version of wxWidgets but not with the latest, at least on Windows
|
||||
|
|
|
|||
|
|
@ -75,7 +75,6 @@ private:
|
|||
wxGLContext* m_context;
|
||||
static GLInfo s_gl_info;
|
||||
bool m_gl_initialized;
|
||||
bool m_use_legacy_opengl;
|
||||
bool m_use_VBOs;
|
||||
static EMultisampleState s_multisample;
|
||||
static bool s_compressed_textures_supported;
|
||||
|
|
|
|||
|
|
@ -68,7 +68,8 @@ namespace GUI {
|
|||
if (!is_dragging())
|
||||
return;
|
||||
|
||||
float zoom = (float)canvas.get_camera().get_zoom();
|
||||
const Camera& camera = canvas.get_camera();
|
||||
float zoom = (float)camera.get_zoom();
|
||||
float inv_zoom = (zoom != 0.0f) ? 1.0f / zoom : 0.0f;
|
||||
|
||||
Size cnv_size = canvas.get_canvas_size();
|
||||
|
|
@ -96,6 +97,11 @@ namespace GUI {
|
|||
|
||||
glsafe(::glPushMatrix());
|
||||
glsafe(::glLoadIdentity());
|
||||
// ensure that the rectangle is renderered inside the frustrum
|
||||
glsafe(::glTranslated(0.0, 0.0, -(camera.get_near_z() + 0.5)));
|
||||
// ensure that the overlay fits the frustrum near z plane
|
||||
double gui_scale = camera.get_gui_scale();
|
||||
glsafe(::glScaled(gui_scale, gui_scale, 1.0));
|
||||
|
||||
glsafe(::glPushAttrib(GL_ENABLE_BIT));
|
||||
glsafe(::glLineStipple(4, 0xAAAA));
|
||||
|
|
|
|||
|
|
@ -469,7 +469,7 @@ void ObjectList::update_extruder_in_config(const wxDataViewItem& item)
|
|||
if (!m_config || selection.empty())
|
||||
return;
|
||||
|
||||
const int extruder = selection.size() > 1 ? 0 : atoi(selection.c_str());
|
||||
const int extruder = /*selection.size() > 1 ? 0 : */atoi(selection.c_str());
|
||||
m_config->set_key_value("extruder", new ConfigOptionInt(extruder));
|
||||
|
||||
// update scene
|
||||
|
|
|
|||
|
|
@ -313,6 +313,12 @@ Preview::~Preview()
|
|||
}
|
||||
}
|
||||
|
||||
void Preview::set_as_dirty()
|
||||
{
|
||||
if (m_canvas != nullptr)
|
||||
m_canvas->set_as_dirty();
|
||||
}
|
||||
|
||||
void Preview::set_number_extruders(unsigned int number_extruders)
|
||||
{
|
||||
if (m_number_extruders != number_extruders)
|
||||
|
|
|
|||
|
|
@ -110,6 +110,8 @@ public:
|
|||
wxGLCanvas* get_wxglcanvas() { return m_canvas_widget; }
|
||||
GLCanvas3D* get_canvas3d() { return m_canvas; }
|
||||
|
||||
void set_as_dirty();
|
||||
|
||||
void set_number_extruders(unsigned int number_extruders);
|
||||
void set_canvas_as_dirty();
|
||||
void set_enabled(bool enabled);
|
||||
|
|
|
|||
|
|
@ -1273,6 +1273,7 @@ struct Plater::priv
|
|||
Preview *preview;
|
||||
|
||||
BackgroundSlicingProcess background_process;
|
||||
bool suppressed_backround_processing_update { false };
|
||||
|
||||
// A class to handle UI jobs like arranging and optimizing rotation.
|
||||
// These are not instant jobs, the user has to be informed about their
|
||||
|
|
@ -1707,7 +1708,11 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame)
|
|||
panels.push_back(preview);
|
||||
|
||||
this->background_process_timer.SetOwner(this->q, 0);
|
||||
this->q->Bind(wxEVT_TIMER, [this](wxTimerEvent &evt) { this->update_restart_background_process(false, false); });
|
||||
this->q->Bind(wxEVT_TIMER, [this](wxTimerEvent &evt)
|
||||
{
|
||||
if (!this->suppressed_backround_processing_update)
|
||||
this->update_restart_background_process(false, false);
|
||||
});
|
||||
|
||||
update();
|
||||
|
||||
|
|
@ -1787,7 +1792,7 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame)
|
|||
set_current_panel(view3D);
|
||||
|
||||
// updates camera type from .ini file
|
||||
camera.set_type(get_config("camera_type"));
|
||||
camera.set_type(get_config("use_perspective_camera"));
|
||||
}
|
||||
|
||||
void Plater::priv::update(bool force_full_scene_refresh)
|
||||
|
|
@ -1855,10 +1860,8 @@ void Plater::priv::update_ui_from_settings()
|
|||
// $self->{buttons_sizer}->Layout;
|
||||
// }
|
||||
|
||||
#if ENABLE_RETINA_GL
|
||||
view3D->get_canvas3d()->update_ui_from_settings();
|
||||
preview->get_canvas3d()->update_ui_from_settings();
|
||||
#endif
|
||||
}
|
||||
|
||||
ProgressStatusBar* Plater::priv::statusbar()
|
||||
|
|
@ -4196,9 +4199,25 @@ void Plater::changed_objects(const std::vector<size_t>& object_idxs)
|
|||
this->p->schedule_background_process();
|
||||
}
|
||||
|
||||
void Plater::schedule_background_process()
|
||||
void Plater::schedule_background_process(bool schedule/* = true*/)
|
||||
{
|
||||
this->p->schedule_background_process();
|
||||
if (schedule)
|
||||
this->p->schedule_background_process();
|
||||
|
||||
this->p->suppressed_backround_processing_update = false;
|
||||
}
|
||||
|
||||
bool Plater::is_background_process_running() const
|
||||
{
|
||||
return this->p->background_process_timer.IsRunning();
|
||||
}
|
||||
|
||||
void Plater::suppress_background_process(const bool stop_background_process)
|
||||
{
|
||||
if (stop_background_process)
|
||||
this->p->background_process_timer.Stop();
|
||||
|
||||
this->p->suppressed_backround_processing_update = true;
|
||||
}
|
||||
|
||||
void Plater::fix_through_netfabb(const int obj_idx, const int vol_idx/* = -1*/) { p->fix_through_netfabb(obj_idx, vol_idx); }
|
||||
|
|
@ -4274,4 +4293,15 @@ bool Plater::can_copy_to_clipboard() const
|
|||
return true;
|
||||
}
|
||||
|
||||
SuppressBackgroundProcessingUpdate::SuppressBackgroundProcessingUpdate() :
|
||||
m_was_running(wxGetApp().plater()->is_background_process_running())
|
||||
{
|
||||
wxGetApp().plater()->suppress_background_process(m_was_running);
|
||||
}
|
||||
|
||||
SuppressBackgroundProcessingUpdate::~SuppressBackgroundProcessingUpdate()
|
||||
{
|
||||
wxGetApp().plater()->schedule_background_process(m_was_running);
|
||||
}
|
||||
|
||||
}} // namespace Slic3r::GUI
|
||||
|
|
|
|||
|
|
@ -177,7 +177,9 @@ public:
|
|||
void reslice_SLA_supports(const ModelObject &object);
|
||||
void changed_object(int obj_idx);
|
||||
void changed_objects(const std::vector<size_t>& object_idxs);
|
||||
void schedule_background_process();
|
||||
void schedule_background_process(bool schedule = true);
|
||||
bool is_background_process_running() const;
|
||||
void suppress_background_process(const bool stop_background_process) ;
|
||||
void fix_through_netfabb(const int obj_idx, const int vol_idx = -1);
|
||||
void send_gcode();
|
||||
|
||||
|
|
@ -221,8 +223,18 @@ public:
|
|||
private:
|
||||
struct priv;
|
||||
std::unique_ptr<priv> p;
|
||||
|
||||
friend class SuppressBackgroundProcessingUpdate;
|
||||
};
|
||||
|
||||
class SuppressBackgroundProcessingUpdate
|
||||
{
|
||||
public:
|
||||
SuppressBackgroundProcessingUpdate();
|
||||
~SuppressBackgroundProcessingUpdate();
|
||||
private:
|
||||
bool m_was_running;
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ void PreferencesDialog::build()
|
|||
m_icon_size_sizer->ShowItems(boost::any_cast<bool>(value));
|
||||
this->layout();
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
// TODO
|
||||
// $optgroup->append_single_option_line(Slic3r::GUI::OptionsGroup::Option->new(
|
||||
|
|
@ -97,16 +97,6 @@ void PreferencesDialog::build()
|
|||
option = Option (def,"show_incompatible_presets");
|
||||
m_optgroup->append_single_option_line(option);
|
||||
|
||||
// TODO: remove?
|
||||
def.label = L("Use legacy OpenGL 1.1 rendering");
|
||||
def.type = coBool;
|
||||
def.tooltip = L("If you have rendering issues caused by a buggy OpenGL 2.0 driver, "
|
||||
"you may try to check this checkbox. This will disable the layer height "
|
||||
"editing and anti aliasing, so it is likely better to upgrade your graphics driver.");
|
||||
def.set_default_value(new ConfigOptionBool{ app_config->get("use_legacy_opengl") == "1" });
|
||||
option = Option (def,"use_legacy_opengl");
|
||||
m_optgroup->append_single_option_line(option);
|
||||
|
||||
#if __APPLE__
|
||||
def.label = L("Use Retina resolution for the 3D scene");
|
||||
def.type = coBool;
|
||||
|
|
@ -117,6 +107,13 @@ void PreferencesDialog::build()
|
|||
m_optgroup->append_single_option_line(option);
|
||||
#endif
|
||||
|
||||
def.label = L("Use perspective camera");
|
||||
def.type = coBool;
|
||||
def.tooltip = L("If enabled, use perspective camera. If not enabled, use orthographic camera.");
|
||||
def.set_default_value(new ConfigOptionBool{ app_config->get("use_perspective_camera") == "1" });
|
||||
option = Option(def, "use_perspective_camera");
|
||||
m_optgroup->append_single_option_line(option);
|
||||
|
||||
def.label = L("Use custom size for toolbar icons");
|
||||
def.type = coBool;
|
||||
def.tooltip = L("If enabled, you can change size of toolbar icons manually.");
|
||||
|
|
@ -143,8 +140,7 @@ void PreferencesDialog::build()
|
|||
|
||||
void PreferencesDialog::accept()
|
||||
{
|
||||
if (m_values.find("no_defaults") != m_values.end() ||
|
||||
m_values.find("use_legacy_opengl") != m_values.end()) {
|
||||
if (m_values.find("no_defaults") != m_values.end()) {
|
||||
warning_catcher(this, wxString::Format(_(L("You need to restart %s to make the changes effective.")), SLIC3R_APP_NAME));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2314,6 +2314,40 @@ void TabPrinter::build_unregular_pages()
|
|||
|
||||
auto optgroup = page->new_optgroup(_(L("Size")));
|
||||
optgroup->append_single_option_line("nozzle_diameter", extruder_idx);
|
||||
|
||||
optgroup->m_on_change = [this, extruder_idx](const t_config_option_key& opt_key, boost::any value)
|
||||
{
|
||||
if (m_extruders_count > 1 && opt_key.find_first_of("nozzle_diameter") != std::string::npos)
|
||||
{
|
||||
SuppressBackgroundProcessingUpdate sbpu;
|
||||
const double new_nd = boost::any_cast<double>(value);
|
||||
std::vector<double> nozzle_diameters = static_cast<const ConfigOptionFloats*>(m_config->option("nozzle_diameter"))->values;
|
||||
|
||||
// if value was changed
|
||||
if (fabs(nozzle_diameters[extruder_idx == 0 ? 1 : 0] - new_nd) > EPSILON)
|
||||
{
|
||||
const wxString msg_text = _(L("Do you want to change the diameter for all extruders?"));
|
||||
auto dialog = new wxMessageDialog(parent(), msg_text, _(L("Nozzle diameter")), wxICON_WARNING | wxYES_NO);
|
||||
|
||||
DynamicPrintConfig new_conf = *m_config;
|
||||
if (dialog->ShowModal() == wxID_YES) {
|
||||
for (size_t i = 0; i < nozzle_diameters.size(); i++) {
|
||||
if (i==extruder_idx)
|
||||
continue;
|
||||
nozzle_diameters[i] = new_nd;
|
||||
}
|
||||
}
|
||||
else
|
||||
nozzle_diameters[extruder_idx] = nozzle_diameters[extruder_idx == 0 ? 1 : 0];
|
||||
|
||||
new_conf.set_key_value("nozzle_diameter", new ConfigOptionFloats(nozzle_diameters));
|
||||
load_config(new_conf);
|
||||
}
|
||||
}
|
||||
|
||||
update_dirty();
|
||||
update();
|
||||
};
|
||||
|
||||
optgroup = page->new_optgroup(_(L("Layer height limits")));
|
||||
optgroup->append_single_option_line("min_layer_height", extruder_idx);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue