mirror of
https://github.com/SoftFever/OrcaSlicer.git
synced 2025-10-23 08:41:11 -06:00
Merge remote-tracking branch 'remotes/origin/master' into fs_QuadricEdgeCollapse
This commit is contained in:
commit
ea5a90f08c
42 changed files with 468 additions and 142 deletions
|
@ -499,10 +499,10 @@ void Bed3D::render_model() const
|
|||
if (shader != nullptr) {
|
||||
shader->start_using();
|
||||
shader->set_uniform("emission_factor", 0.0);
|
||||
::glPushMatrix();
|
||||
::glTranslated(m_model_offset.x(), m_model_offset.y(), m_model_offset.z());
|
||||
glsafe(::glPushMatrix());
|
||||
glsafe(::glTranslated(m_model_offset.x(), m_model_offset.y(), m_model_offset.z()));
|
||||
model->render();
|
||||
::glPopMatrix();
|
||||
glsafe(::glPopMatrix());
|
||||
shader->stop_using();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -93,6 +93,7 @@ BonjourDialog::BonjourDialog(wxWindow *parent, Slic3r::PrinterTechnology tech)
|
|||
});
|
||||
|
||||
Bind(wxEVT_TIMER, &BonjourDialog::on_timer, this);
|
||||
GUI::wxGetApp().UpdateDlgDarkUI(this);
|
||||
}
|
||||
|
||||
BonjourDialog::~BonjourDialog()
|
||||
|
|
|
@ -335,3 +335,36 @@ bool BitmapChoiceRenderer::GetValueFromEditorCtrl(wxWindow* ctrl, wxVariant& val
|
|||
}
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// TextRenderer
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
bool TextRenderer::SetValue(const wxVariant& value)
|
||||
{
|
||||
m_value = value.GetString();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool TextRenderer::GetValue(wxVariant& value) const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool TextRenderer::Render(wxRect rect, wxDC* dc, int state)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
// workaround for Windows DarkMode : Don't respect to the state & wxDATAVIEW_CELL_SELECTED to avoid update of the text color
|
||||
RenderText(m_value, 0, rect, dc, state & wxDATAVIEW_CELL_SELECTED ? 0 : state);
|
||||
#else
|
||||
RenderText(m_value, 0, rect, dc, state);
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
wxSize TextRenderer::GetSize() const
|
||||
{
|
||||
return GetTextExtent(m_value);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -161,4 +161,29 @@ private:
|
|||
};
|
||||
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// TextRenderer
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
class TextRenderer : public wxDataViewCustomRenderer
|
||||
{
|
||||
public:
|
||||
TextRenderer(wxDataViewCellMode mode = wxDATAVIEW_CELL_INERT
|
||||
, int align = wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL
|
||||
) : wxDataViewCustomRenderer(wxT("string"), mode, align) {}
|
||||
|
||||
bool SetValue(const wxVariant& value) override;
|
||||
bool GetValue(wxVariant& value) const override;
|
||||
|
||||
virtual bool Render(wxRect cell, wxDC* dc, int state) override;
|
||||
virtual wxSize GetSize() const override;
|
||||
|
||||
bool HasEditorCtrl() const override { return false; }
|
||||
|
||||
private:
|
||||
wxString m_value;
|
||||
};
|
||||
|
||||
|
||||
#endif // slic3r_GUI_ExtraRenderers_hpp_
|
||||
|
|
|
@ -2379,8 +2379,12 @@ void GCodeViewer::render_toolpaths() const
|
|||
shader.set_uniform("uniform_color", color4);
|
||||
};
|
||||
|
||||
#if ENABLE_GCODE_VIEWER_STATISTICS
|
||||
auto render_as_points = [this, zoom, point_size, near_plane_height, set_uniform_color]
|
||||
#else
|
||||
auto render_as_points = [zoom, point_size, near_plane_height, set_uniform_color]
|
||||
(const TBuffer& buffer, unsigned int ibuffer_id, GLShaderProgram& shader) {
|
||||
#endif // ENABLE_GCODE_VIEWER_STATISTICS
|
||||
(const TBuffer& buffer, unsigned int ibuffer_id, GLShaderProgram& shader) {
|
||||
#if ENABLE_FIXED_SCREEN_SIZE_POINT_MARKERS
|
||||
shader.set_uniform("use_fixed_screen_size", 1);
|
||||
#else
|
||||
|
@ -2409,7 +2413,12 @@ void GCodeViewer::render_toolpaths() const
|
|||
glsafe(::glDisable(GL_VERTEX_PROGRAM_POINT_SIZE));
|
||||
};
|
||||
|
||||
auto render_as_lines = [light_intensity, set_uniform_color](const TBuffer& buffer, unsigned int ibuffer_id, GLShaderProgram& shader) {
|
||||
#if ENABLE_GCODE_VIEWER_STATISTICS
|
||||
auto render_as_lines = [this, light_intensity, set_uniform_color]
|
||||
#else
|
||||
auto render_as_lines = [light_intensity, set_uniform_color]
|
||||
#endif // ENABLE_GCODE_VIEWER_STATISTICS
|
||||
(const TBuffer& buffer, unsigned int ibuffer_id, GLShaderProgram& shader) {
|
||||
shader.set_uniform("light_intensity", light_intensity);
|
||||
for (const RenderPath& path : buffer.render_paths) {
|
||||
if (path.ibuffer_id == ibuffer_id) {
|
||||
|
@ -2422,7 +2431,12 @@ void GCodeViewer::render_toolpaths() const
|
|||
}
|
||||
};
|
||||
|
||||
auto render_as_triangles = [set_uniform_color](const TBuffer& buffer, unsigned int ibuffer_id, GLShaderProgram& shader) {
|
||||
#if ENABLE_GCODE_VIEWER_STATISTICS
|
||||
auto render_as_triangles = [this, set_uniform_color]
|
||||
#else
|
||||
auto render_as_triangles = [set_uniform_color]
|
||||
#endif // ENABLE_GCODE_VIEWER_STATISTICS
|
||||
(const TBuffer& buffer, unsigned int ibuffer_id, GLShaderProgram& shader) {
|
||||
for (const RenderPath& path : buffer.render_paths) {
|
||||
if (path.ibuffer_id == ibuffer_id) {
|
||||
set_uniform_color(path.color, shader);
|
||||
|
@ -2495,7 +2509,12 @@ void GCodeViewer::render_toolpaths() const
|
|||
}
|
||||
}
|
||||
|
||||
auto render_sequential_range_cap = [set_uniform_color](const SequentialRangeCap& cap) {
|
||||
#if ENABLE_GCODE_VIEWER_STATISTICS
|
||||
auto render_sequential_range_cap = [this, set_uniform_color]
|
||||
#else
|
||||
auto render_sequential_range_cap = [set_uniform_color]
|
||||
#endif // ENABLE_GCODE_VIEWER_STATISTICS
|
||||
(const SequentialRangeCap& cap) {
|
||||
GLShaderProgram* shader = wxGetApp().get_shader(cap.buffer->shader.c_str());
|
||||
if (shader != nullptr) {
|
||||
shader->start_using();
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
#include "libslic3r/libslic3r.h"
|
||||
#include "libslic3r/Platform.hpp"
|
||||
#include "GLShadersManager.hpp"
|
||||
#include "3DScene.hpp"
|
||||
#include "GUI_App.hpp"
|
||||
|
@ -43,9 +44,19 @@ std::pair<bool, std::string> GLShadersManager::init()
|
|||
// used to render extrusion and travel paths as lines in gcode preview
|
||||
valid &= append_shader("toolpaths_lines", { "toolpaths_lines.vs", "toolpaths_lines.fs" });
|
||||
// used to render objects in 3d editor
|
||||
valid &= append_shader("gouraud", { "gouraud.vs", "gouraud.fs" }
|
||||
// For Apple's on Arm CPU computed triangle normals inside fragment shader using dFdx and dFdy has the opposite direction.
|
||||
// Because of this, objects had darker colors inside the multi-material gizmo.
|
||||
// Based on https://stackoverflow.com/a/66206648, the similar behavior was also spotted on some other devices with Arm CPU.
|
||||
if (platform_flavor() == PlatformFlavor::OSXOnArm)
|
||||
valid &= append_shader("gouraud", { "gouraud.vs", "gouraud.fs" }, { "FLIP_TRIANGLE_NORMALS"sv
|
||||
#if ENABLE_ENVIRONMENT_MAP
|
||||
, { "ENABLE_ENVIRONMENT_MAP"sv }
|
||||
, "ENABLE_ENVIRONMENT_MAP"sv
|
||||
#endif
|
||||
});
|
||||
else
|
||||
valid &= append_shader("gouraud", { "gouraud.vs", "gouraud.fs" }
|
||||
#if ENABLE_ENVIRONMENT_MAP
|
||||
, { "ENABLE_ENVIRONMENT_MAP"sv }
|
||||
#endif
|
||||
);
|
||||
// used to render variable layers heights in 3d editor
|
||||
|
|
|
@ -428,6 +428,7 @@ wxString file_wildcards(FileType file_type, const std::string &custom_extension)
|
|||
/* FT_GCODE */ "G-code files (*.gcode, *.gco, *.g, *.ngc)|*.gcode;*.GCODE;*.gco;*.GCO;*.g;*.G;*.ngc;*.NGC",
|
||||
/* FT_MODEL */ "Known files (*.stl, *.obj, *.amf, *.xml, *.3mf, *.prusa)|*.stl;*.STL;*.obj;*.OBJ;*.amf;*.AMF;*.xml;*.XML;*.3mf;*.3MF;*.prusa;*.PRUSA",
|
||||
/* FT_PROJECT */ "Project files (*.3mf, *.amf)|*.3mf;*.3MF;*.amf;*.AMF",
|
||||
/* FT_GALLERY */ "Known files (*.stl, *.obj)|*.stl;*.STL;*.obj;*.OBJ",
|
||||
|
||||
/* FT_INI */ "INI files (*.ini)|*.ini;*.INI",
|
||||
/* FT_SVG */ "SVG files (*.svg)|*.svg;*.SVG",
|
||||
|
@ -662,7 +663,7 @@ void GUI_App::post_init()
|
|||
}
|
||||
|
||||
// show "Did you know" notification
|
||||
if (app_config->get("show_hints") == "1")
|
||||
if (app_config->get("show_hints") == "1" && ! is_gcode_viewer())
|
||||
plater_->get_notification_manager()->push_hint_notification();
|
||||
|
||||
// The extra CallAfter() is needed because of Mac, where this is the only way
|
||||
|
|
|
@ -59,6 +59,7 @@ enum FileType
|
|||
FT_GCODE,
|
||||
FT_MODEL,
|
||||
FT_PROJECT,
|
||||
FT_GALLERY,
|
||||
|
||||
FT_INI,
|
||||
FT_SVG,
|
||||
|
|
|
@ -433,7 +433,7 @@ wxMenu* MenuFactory::append_submenu_add_generic(wxMenu* menu, ModelVolumeType ty
|
|||
[type, item](wxCommandEvent&) { obj_list()->load_generic_subobject(item, type); }, "", menu);
|
||||
}
|
||||
|
||||
if (wxGetApp().get_mode() == comExpert) {
|
||||
if (wxGetApp().get_mode() >= comAdvanced) {
|
||||
sub_menu->AppendSeparator();
|
||||
append_menu_item(sub_menu, wxID_ANY, _L("Gallery"), "",
|
||||
[type](wxCommandEvent&) { obj_list()->load_subobject(type, true); }, "", menu);
|
||||
|
|
|
@ -2517,7 +2517,7 @@ wxDataViewItem ObjectList::add_settings_item(wxDataViewItem parent_item, const D
|
|||
}
|
||||
|
||||
|
||||
void ObjectList::update_info_items(size_t obj_idx)
|
||||
void ObjectList::update_info_items(size_t obj_idx, wxDataViewItemArray* selections/* = nullptr*/)
|
||||
{
|
||||
const ModelObject* model_object = (*m_objects)[obj_idx];
|
||||
wxDataViewItem item_obj = m_objects_model->GetItemById(obj_idx);
|
||||
|
@ -2565,9 +2565,21 @@ void ObjectList::update_info_items(size_t obj_idx)
|
|||
|
||||
}
|
||||
else if (shows && ! should_show) {
|
||||
Unselect(item);
|
||||
if (!selections)
|
||||
Unselect(item);
|
||||
m_objects_model->Delete(item);
|
||||
Select(item_obj);
|
||||
if (selections) {
|
||||
if (selections->Index(item) != wxNOT_FOUND) {
|
||||
// If info item was deleted from the list,
|
||||
// it's need to be deleted from selection array, if it was there
|
||||
selections->Remove(item);
|
||||
// Select item_obj, if info_item doesn't exist for item anymore, but was selected
|
||||
if (selections->Index(item_obj) == wxNOT_FOUND)
|
||||
selections->Add(item_obj);
|
||||
}
|
||||
}
|
||||
else
|
||||
Select(item_obj);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3760,7 +3772,7 @@ void ObjectList::update_object_list_by_printer_technology()
|
|||
|
||||
for (auto& object_item : object_items) {
|
||||
// update custom supports info
|
||||
update_info_items(m_objects_model->GetObjectIdByItem(object_item));
|
||||
update_info_items(m_objects_model->GetObjectIdByItem(object_item), &sel);
|
||||
|
||||
// Update Settings Item for object
|
||||
update_settings_item_and_selection(object_item, sel);
|
||||
|
|
|
@ -350,7 +350,7 @@ public:
|
|||
void update_and_show_object_settings_item();
|
||||
void update_settings_item_and_selection(wxDataViewItem item, wxDataViewItemArray& selections);
|
||||
void update_object_list_by_printer_technology();
|
||||
void update_info_items(size_t obj_idx);
|
||||
void update_info_items(size_t obj_idx, wxDataViewItemArray* selections = nullptr);
|
||||
|
||||
void instances_to_separated_object(const int obj_idx, const std::set<int>& inst_idx);
|
||||
void instances_to_separated_objects(const int obj_idx);
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
#include "libslic3r/AppConfig.hpp"
|
||||
#include "libslic3r/Model.hpp"
|
||||
#include "libslic3r/GCode/ThumbnailData.hpp"
|
||||
#include "libslic3r/Format/OBJ.hpp"
|
||||
#include "../Utils/MacDarkMode.hpp"
|
||||
|
||||
namespace Slic3r {
|
||||
|
@ -205,7 +206,11 @@ static void add_lock(wxImage& image)
|
|||
|
||||
static void add_default_image(wxImageList* img_list, bool is_system)
|
||||
{
|
||||
wxBitmap bmp = create_scaled_bitmap("cog", nullptr, IMG_PX_CNT, true);
|
||||
int sz = IMG_PX_CNT;
|
||||
#ifdef __APPLE__
|
||||
sz /= mac_max_scaling_factor();
|
||||
#endif
|
||||
wxBitmap bmp = create_scaled_bitmap("cog", nullptr, sz, true);
|
||||
|
||||
if (is_system) {
|
||||
wxImage image = bmp.ConvertToImage();
|
||||
|
@ -232,10 +237,11 @@ static std::string get_dir_path(bool sys_dir)
|
|||
#endif
|
||||
}
|
||||
|
||||
static void generate_thumbnail_from_stl(const std::string& filename)
|
||||
static void generate_thumbnail_from_model(const std::string& filename)
|
||||
{
|
||||
if (!boost::algorithm::iends_with(filename, ".stl")) {
|
||||
BOOST_LOG_TRIVIAL(error) << "Found invalid file type in generate_thumbnail_from_stl() [" << filename << "]";
|
||||
if (!boost::algorithm::iends_with(filename, ".stl") &&
|
||||
!boost::algorithm::iends_with(filename, ".obj")) {
|
||||
BOOST_LOG_TRIVIAL(error) << "Found invalid file type in generate_thumbnail_from_model() [" << filename << "]";
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -244,7 +250,7 @@ static void generate_thumbnail_from_stl(const std::string& filename)
|
|||
model = Model::read_from_file(filename);
|
||||
}
|
||||
catch (std::exception&) {
|
||||
BOOST_LOG_TRIVIAL(error) << "Error loading model from " << filename << " in generate_thumbnail_from_stl()";
|
||||
BOOST_LOG_TRIVIAL(error) << "Error loading model from " << filename << " in generate_thumbnail_from_model()";
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -294,25 +300,28 @@ static void generate_thumbnail_from_stl(const std::string& filename)
|
|||
void GalleryDialog::load_label_icon_list()
|
||||
{
|
||||
// load names from files
|
||||
auto add_files_from_gallery = [](std::vector<Item>& items, bool sys_dir, std::string& dir_path)
|
||||
auto add_files_from_gallery = [](std::vector<Item>& items, bool is_sys_dir, std::string& dir_path)
|
||||
{
|
||||
fs::path dir = get_dir(sys_dir);
|
||||
fs::path dir = get_dir(is_sys_dir);
|
||||
if (!fs::exists(dir))
|
||||
return;
|
||||
|
||||
dir_path = get_dir_path(sys_dir);
|
||||
dir_path = get_dir_path(is_sys_dir);
|
||||
|
||||
std::vector<std::string> sorted_names;
|
||||
for (auto& dir_entry : fs::directory_iterator(dir))
|
||||
if (TriangleMesh mesh; is_stl_file(dir_entry) && mesh.ReadSTLFile(dir_entry.path().string().c_str()))
|
||||
sorted_names.push_back(dir_entry.path().stem().string());
|
||||
for (auto& dir_entry : fs::directory_iterator(dir)) {
|
||||
TriangleMesh mesh;
|
||||
if ((is_gallery_file(dir_entry, ".stl") && mesh.ReadSTLFile(dir_entry.path().string().c_str())) ||
|
||||
(is_gallery_file(dir_entry, ".obj") && load_obj(dir_entry.path().string().c_str(), &mesh) ) )
|
||||
sorted_names.push_back(dir_entry.path().filename().string());
|
||||
}
|
||||
|
||||
// sort the filename case insensitive
|
||||
std::sort(sorted_names.begin(), sorted_names.end(), [](const std::string& a, const std::string& b)
|
||||
{ return boost::algorithm::to_lower_copy(a) < boost::algorithm::to_lower_copy(b); });
|
||||
|
||||
for (const std::string& name : sorted_names)
|
||||
items.push_back(Item{ name, sys_dir });
|
||||
items.push_back(Item{ name, is_sys_dir });
|
||||
};
|
||||
|
||||
wxBusyCursor busy;
|
||||
|
@ -330,10 +339,24 @@ void GalleryDialog::load_label_icon_list()
|
|||
std::string ext = ".png";
|
||||
|
||||
for (const auto& item : list_items) {
|
||||
std::string img_name = (item.is_system ? m_sys_dir_path : m_cust_dir_path) + item.name + ext;
|
||||
std::string stl_name = (item.is_system ? m_sys_dir_path : m_cust_dir_path) + item.name + ".stl";
|
||||
if (!fs::exists(img_name))
|
||||
generate_thumbnail_from_stl(stl_name);
|
||||
fs::path model_path = fs::path((item.is_system ? m_sys_dir_path : m_cust_dir_path) + item.name);
|
||||
std::string model_name = model_path.string();
|
||||
model_path.replace_extension("png");
|
||||
std::string img_name = model_path.string();
|
||||
|
||||
#if 0 // use "1" just in DEBUG mode to the generation of the thumbnails for the sistem shapes
|
||||
bool can_generate_thumbnail = true;
|
||||
#else
|
||||
bool can_generate_thumbnail = !item.is_system;
|
||||
#endif //DEBUG
|
||||
if (!fs::exists(img_name)) {
|
||||
if (can_generate_thumbnail)
|
||||
generate_thumbnail_from_model(model_name);
|
||||
else {
|
||||
add_default_image(m_image_list, item.is_system);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
wxImage image;
|
||||
if (!image.CanRead(from_u8(img_name)) ||
|
||||
|
@ -363,15 +386,15 @@ void GalleryDialog::load_label_icon_list()
|
|||
void GalleryDialog::get_input_files(wxArrayString& input_files)
|
||||
{
|
||||
for (const Item& item : m_selected_items)
|
||||
input_files.Add(from_u8(get_dir_path(item.is_system) + item.name + ".stl"));
|
||||
input_files.Add(from_u8(get_dir_path(item.is_system) + item.name));
|
||||
}
|
||||
|
||||
void GalleryDialog::add_custom_shapes(wxEvent& event)
|
||||
{
|
||||
wxArrayString input_files;
|
||||
wxFileDialog dialog(this, _L("Choose one or more files (STL):"),
|
||||
wxFileDialog dialog(this, _L("Choose one or more files (STL, OBJ):"),
|
||||
from_u8(wxGetApp().app_config->get_last_dir()), "",
|
||||
file_wildcards(FT_STL), wxFD_OPEN | wxFD_MULTIPLE | wxFD_FILE_MUST_EXIST);
|
||||
file_wildcards(FT_GALLERY), wxFD_OPEN | wxFD_MULTIPLE | wxFD_FILE_MUST_EXIST);
|
||||
|
||||
if (dialog.ShowModal() == wxID_OK)
|
||||
dialog.GetPaths(input_files);
|
||||
|
@ -398,8 +421,10 @@ void GalleryDialog::del_custom_shapes(wxEvent& event)
|
|||
};
|
||||
|
||||
for (const Item& item : m_selected_items) {
|
||||
remove_file(item.name + ".stl");
|
||||
remove_file(item.name + ".png");
|
||||
remove_file(item.name);
|
||||
fs::path path = fs::path(item.name);
|
||||
path.replace_extension("png");
|
||||
remove_file(path.string());
|
||||
}
|
||||
|
||||
update();
|
||||
|
@ -490,26 +515,32 @@ bool GalleryDialog::load_files(const wxArrayString& input_files)
|
|||
return false;
|
||||
}
|
||||
|
||||
// Iterate through the source directory
|
||||
// Iterate through the input files
|
||||
for (size_t i = 0; i < input_files.size(); ++i) {
|
||||
std::string input_file = into_u8(input_files.Item(i));
|
||||
|
||||
if (TriangleMesh mesh; !mesh.ReadSTLFile(input_file.c_str())) {
|
||||
TriangleMesh mesh;
|
||||
if (is_gallery_file(input_file, ".stl") && !mesh.ReadSTLFile(input_file.c_str())) {
|
||||
show_warning(format_wxstr(_L("Loading of the \"%1%\""), input_file), "STL");
|
||||
continue;
|
||||
}
|
||||
|
||||
if (is_gallery_file(input_file, ".obj") && !load_obj(input_file.c_str(), &mesh)) {
|
||||
show_warning(format_wxstr(_L("Loading of the \"%1%\""), input_file), "OBJ");
|
||||
continue;
|
||||
}
|
||||
|
||||
try {
|
||||
fs::path current = fs::path(input_file);
|
||||
if (!fs::exists(dest_dir / current.filename()))
|
||||
fs::copy_file(current, dest_dir / current.filename());
|
||||
else {
|
||||
std::string filename = current.stem().string();
|
||||
std::string filename = current.filename().string();
|
||||
|
||||
int file_idx = 0;
|
||||
for (auto& dir_entry : fs::directory_iterator(dest_dir))
|
||||
if (is_stl_file(dir_entry)) {
|
||||
std::string name = dir_entry.path().stem().string();
|
||||
if (is_gallery_file(dir_entry, ".stl") || is_gallery_file(dir_entry, ".obj")) {
|
||||
std::string name = dir_entry.path().filename().string();
|
||||
if (filename == name) {
|
||||
if (file_idx == 0)
|
||||
file_idx++;
|
||||
|
@ -524,7 +555,7 @@ bool GalleryDialog::load_files(const wxArrayString& input_files)
|
|||
file_idx = cur_idx+1;
|
||||
}
|
||||
if (file_idx > 0) {
|
||||
filename += " (" + std::to_string(file_idx) + ").stl";
|
||||
filename += " (" + std::to_string(file_idx) + ")." + (is_gallery_file(input_file, ".stl") ? "stl" : "obj");
|
||||
fs::copy_file(current, dest_dir / filename);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -359,10 +359,10 @@ void ObjectClipper::render_cut() const
|
|||
clipper->set_plane(*m_clp);
|
||||
clipper->set_transformation(trafo);
|
||||
|
||||
::glPushMatrix();
|
||||
::glColor3f(1.0f, 0.37f, 0.0f);
|
||||
glsafe(::glPushMatrix());
|
||||
glsafe(::glColor3f(1.0f, 0.37f, 0.0f));
|
||||
clipper->render_cut();
|
||||
::glPopMatrix();
|
||||
glsafe(::glPopMatrix());
|
||||
|
||||
++clipper_id;
|
||||
}
|
||||
|
@ -472,10 +472,10 @@ void SupportsClipper::render_cut() const
|
|||
m_clipper->set_plane(*ocl->get_clipping_plane());
|
||||
m_clipper->set_transformation(supports_trafo);
|
||||
|
||||
::glPushMatrix();
|
||||
::glColor3f(1.0f, 0.f, 0.37f);
|
||||
glsafe(::glPushMatrix());
|
||||
glsafe(::glColor3f(1.0f, 0.f, 0.37f));
|
||||
m_clipper->render_cut();
|
||||
::glPopMatrix();
|
||||
glsafe(::glPopMatrix());
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -434,6 +434,12 @@ void PhysicalPrinterDialog::build_printhost_settings(ConfigOptionsGroup* m_optgr
|
|||
e.Skip();
|
||||
temp->GetToolTip()->Enable(true);
|
||||
#endif // __WXGTK__
|
||||
// Remove all leading and trailing spaces from the input
|
||||
std::string trimed_str, str = trimed_str = temp->GetValue().ToStdString();
|
||||
boost::trim(trimed_str);
|
||||
if (trimed_str != str)
|
||||
temp->SetValue(trimed_str);
|
||||
|
||||
TextCtrl* field = dynamic_cast<TextCtrl*>(printhost_field);
|
||||
if (field)
|
||||
field->propagate_value();
|
||||
|
|
|
@ -2389,8 +2389,8 @@ std::vector<size_t> Plater::priv::load_files(const std::vector<fs::path>& input_
|
|||
//wxMessageDialog msg_dlg(q, _L(
|
||||
MessageDialog msg_dlg(q, _L(
|
||||
"This file contains several objects positioned at multiple heights.\n"
|
||||
"Instead of considering them as multiple objects, should I consider\n"
|
||||
"this file as a single object having multiple parts?") + "\n",
|
||||
"Instead of considering them as multiple objects, should \n"
|
||||
"should the file be loaded as a single object having multiple parts?") + "\n",
|
||||
_L("Multi-part object detected"), wxICON_WARNING | wxYES | wxNO);
|
||||
if (msg_dlg.ShowModal() == wxID_YES) {
|
||||
model.convert_multipart_object(nozzle_dmrs->values.size());
|
||||
|
@ -3212,9 +3212,10 @@ void Plater::priv::replace_with_stl()
|
|||
new_volume->set_material_id(old_volume->material_id());
|
||||
new_volume->set_transformation(old_volume->get_transformation());
|
||||
new_volume->translate(new_volume->get_transformation().get_matrix(true) * (new_volume->source.mesh_offset - old_volume->source.mesh_offset));
|
||||
assert(! old_volume->source.is_converted_from_inches || ! old_volume->source.is_converted_from_meters);
|
||||
if (old_volume->source.is_converted_from_inches)
|
||||
new_volume->convert_from_imperial_units();
|
||||
if (old_volume->source.is_converted_from_meters)
|
||||
else if (old_volume->source.is_converted_from_meters)
|
||||
new_volume->convert_from_meters();
|
||||
new_volume->supported_facets.assign(old_volume->supported_facets);
|
||||
new_volume->seam_facets.assign(old_volume->seam_facets);
|
||||
|
@ -3420,13 +3421,11 @@ void Plater::priv::reload_from_disk()
|
|||
new_volume->set_material_id(old_volume->material_id());
|
||||
new_volume->set_transformation(old_volume->get_transformation());
|
||||
new_volume->translate(new_volume->get_transformation().get_matrix(true) * (new_volume->source.mesh_offset - old_volume->source.mesh_offset));
|
||||
assert(! old_volume->source.is_converted_from_inches || ! old_volume->source.is_converted_from_meters);
|
||||
if (old_volume->source.is_converted_from_inches)
|
||||
new_volume->convert_from_imperial_units();
|
||||
if (old_volume->source.is_converted_from_meters)
|
||||
else if (old_volume->source.is_converted_from_meters)
|
||||
new_volume->convert_from_meters();
|
||||
new_volume->supported_facets.assign(old_volume->supported_facets);
|
||||
new_volume->seam_facets.assign(old_volume->seam_facets);
|
||||
new_volume->mmu_segmentation_facets.assign(old_volume->mmu_segmentation_facets);
|
||||
std::swap(old_model_object->volumes[sel_v.volume_idx], old_model_object->volumes.back());
|
||||
old_model_object->delete_volume(old_model_object->volumes.size() - 1);
|
||||
if (!sinking)
|
||||
|
@ -5223,7 +5222,7 @@ void Plater::convert_unit(ConversionType conv_type)
|
|||
void Plater::toggle_layers_editing(bool enable)
|
||||
{
|
||||
if (canvas3D()->is_layers_editing_enabled() != enable)
|
||||
wxPostEvent(canvas3D()->get_wxglcanvas(), SimpleEvent(EVT_GLTOOLBAR_LAYERSEDITING));
|
||||
canvas3D()->force_main_toolbar_left_action(canvas3D()->get_main_toolbar_item_id("layersediting"));
|
||||
}
|
||||
|
||||
void Plater::cut(size_t obj_idx, size_t instance_idx, coordf_t z, ModelObjectCutAttributes attributes)
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
#include "MainFrame.hpp"
|
||||
#include "libslic3r/AppConfig.hpp"
|
||||
#include "NotificationManager.hpp"
|
||||
#include "ExtraRenderers.hpp"
|
||||
|
||||
namespace fs = boost::filesystem;
|
||||
|
||||
|
@ -214,14 +215,25 @@ PrintHostQueueDialog::PrintHostQueueDialog(wxWindow *parent)
|
|||
}
|
||||
|
||||
job_list = new wxDataViewListCtrl(this, wxID_ANY);
|
||||
|
||||
// MSW DarkMode: workaround for the selected item in the list
|
||||
auto append_text_column = [this](const wxString& label, int width, wxAlignment align = wxALIGN_LEFT,
|
||||
int flags = wxDATAVIEW_COL_RESIZABLE | wxDATAVIEW_COL_SORTABLE) {
|
||||
#ifdef _WIN32
|
||||
job_list->AppendColumn(new wxDataViewColumn(label, new TextRenderer(), job_list->GetColumnCount(), width, align, flags));
|
||||
#else
|
||||
job_list->AppendTextColumn(label, wxDATAVIEW_CELL_INERT, width, align, flags);
|
||||
#endif
|
||||
};
|
||||
|
||||
// Note: Keep these in sync with Column
|
||||
job_list->AppendTextColumn(_L("ID"), wxDATAVIEW_CELL_INERT, widths[0], wxALIGN_LEFT, wxDATAVIEW_COL_RESIZABLE | wxDATAVIEW_COL_SORTABLE);
|
||||
job_list->AppendProgressColumn(_L("Progress"), wxDATAVIEW_CELL_INERT, widths[1], wxALIGN_LEFT, wxDATAVIEW_COL_RESIZABLE | wxDATAVIEW_COL_SORTABLE);
|
||||
job_list->AppendTextColumn(_L("Status"), wxDATAVIEW_CELL_INERT, widths[2], wxALIGN_LEFT, wxDATAVIEW_COL_RESIZABLE | wxDATAVIEW_COL_SORTABLE);
|
||||
job_list->AppendTextColumn(_L("Host"), wxDATAVIEW_CELL_INERT, widths[3], wxALIGN_LEFT, wxDATAVIEW_COL_RESIZABLE | wxDATAVIEW_COL_SORTABLE);
|
||||
job_list->AppendTextColumn(_CTX_utf8(L_CONTEXT("Size", "OfFile"), "OfFile"), wxDATAVIEW_CELL_INERT, widths[4], wxALIGN_LEFT, wxDATAVIEW_COL_RESIZABLE | wxDATAVIEW_COL_SORTABLE);
|
||||
job_list->AppendTextColumn(_L("Filename"), wxDATAVIEW_CELL_INERT, widths[5], wxALIGN_LEFT, wxDATAVIEW_COL_RESIZABLE | wxDATAVIEW_COL_SORTABLE);
|
||||
job_list->AppendTextColumn(_L("Error Message"), wxDATAVIEW_CELL_INERT, -1, wxALIGN_CENTER, wxDATAVIEW_COL_HIDDEN);
|
||||
append_text_column(_L("ID"), widths[0]);
|
||||
job_list->AppendProgressColumn(_L("Progress"), wxDATAVIEW_CELL_INERT, widths[1], wxALIGN_LEFT, wxDATAVIEW_COL_RESIZABLE | wxDATAVIEW_COL_SORTABLE);
|
||||
append_text_column(_L("Status"),widths[2]);
|
||||
append_text_column(_L("Host"), widths[3]);
|
||||
append_text_column(_CTX_utf8(L_CONTEXT("Size", "OfFile"), "OfFile"), widths[4]);
|
||||
append_text_column(_L("Filename"), widths[5]);
|
||||
append_text_column(_L("Error Message"), -1, wxALIGN_CENTER, wxDATAVIEW_COL_HIDDEN);
|
||||
|
||||
auto *btnsizer = new wxBoxSizer(wxHORIZONTAL);
|
||||
btn_cancel = new wxButton(this, wxID_DELETE, _L("Cancel selected"));
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue