mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-10-04 22:31:02 +00:00
Compare commits
5
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
cca0f61c1b | ||
|
|
5efb3bef45 | ||
|
|
90ac58d3cd | ||
|
|
88346efceb | ||
|
|
5a95ba4bd5 |
@@ -196,7 +196,6 @@ src/slic3r/GUI/Tab.hpp
|
||||
src/slic3r/GUI/UnsavedChangesDialog.cpp
|
||||
src/slic3r/GUI/Auxiliary.cpp
|
||||
src/slic3r/GUI/UpdateDialogs.cpp
|
||||
src/slic3r/GUI/ObjColorDialog.cpp
|
||||
src/slic3r/GUI/SyncAmsInfoDialog.cpp
|
||||
src/slic3r/GUI/WipeTowerDialog.cpp
|
||||
src/slic3r/GUI/wxExtensions.cpp
|
||||
|
||||
@@ -37,6 +37,7 @@
|
||||
#include "libslic3r/TriangleSelector.hpp"
|
||||
#include <algorithm>
|
||||
#include "libslic3r/Format/bbs_3mf.hpp"
|
||||
#include "libslic3r/Format/AssembleList.hpp"
|
||||
#include <cstdlib>
|
||||
#include <stdlib.h>
|
||||
#include <stdexcept>
|
||||
@@ -141,6 +142,8 @@ using namespace nlohmann;
|
||||
#include "slic3r/GUI/GuiColor.hpp"
|
||||
#include <GLFW/glfw3.h>
|
||||
|
||||
namespace fs = boost::filesystem;
|
||||
|
||||
#ifdef __WXGTK__
|
||||
#if __has_include(<X11/Xlib.h>)
|
||||
#include <X11/Xlib.h>
|
||||
|
||||
@@ -58,6 +58,8 @@
|
||||
#include <set>
|
||||
#include <string>
|
||||
|
||||
namespace fs = boost::filesystem;
|
||||
|
||||
using namespace Slic3r;
|
||||
namespace po = boost::program_options;
|
||||
|
||||
|
||||
@@ -3,9 +3,16 @@
|
||||
#include <algorithm>
|
||||
|
||||
#include <boost/filesystem.hpp>
|
||||
#include <boost/filesystem/path.hpp>
|
||||
#include <boost/filesystem/operations.hpp>
|
||||
#include <boost/format.hpp>
|
||||
#include <boost/log/trivial.hpp>
|
||||
#include <boost/nowide/fstream.hpp>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <utility>
|
||||
#include <exception>
|
||||
|
||||
#include "nlohmann/json.hpp"
|
||||
|
||||
|
||||
@@ -29,18 +29,6 @@ struct ObjInfo {
|
||||
std::vector<ObjParser::ObjUseMtl> usemtls; // material spans, for texture import
|
||||
|
||||
};
|
||||
struct ObjDialogInOut
|
||||
{ // input:colors array
|
||||
std::vector<RGBA> input_colors;
|
||||
bool is_single_color{false};
|
||||
// colors array output:
|
||||
std::vector<unsigned char> filament_ids;
|
||||
unsigned char first_extruder_id;
|
||||
bool deal_vertex_color;
|
||||
Model * model{nullptr};
|
||||
std::string lost_material_name{""};
|
||||
};
|
||||
typedef std::function<void(ObjDialogInOut &in_out)> ObjImportColorFn;
|
||||
extern bool load_obj(const char *path, TriangleMesh *mesh, ObjInfo &vertex_colors, std::string &message, ObjParser::MtlData *out_mtl = nullptr);
|
||||
extern bool load_obj(const char *path, Model *model, ObjInfo &vertex_colors, std::string &message, const char *object_name = nullptr, ObjParser::MtlData *out_mtl = nullptr);
|
||||
|
||||
|
||||
@@ -60,6 +60,8 @@
|
||||
#include "BRepTools.hxx"
|
||||
#include <IMeshTools_Parameters.hxx>
|
||||
|
||||
namespace fs = boost::filesystem;
|
||||
|
||||
|
||||
namespace Slic3r {
|
||||
|
||||
|
||||
@@ -17,7 +17,6 @@
|
||||
#include <ostream>
|
||||
#include <vector>
|
||||
|
||||
namespace fs = boost::filesystem;
|
||||
|
||||
namespace Slic3r {
|
||||
|
||||
@@ -104,7 +103,7 @@ public:
|
||||
MESH_SUCCESS,
|
||||
MESH_ERROR
|
||||
};
|
||||
Step(fs::path path, ImportStepProgressFn stepFn = nullptr, StepIsUtf8Fn isUtf8Fn = nullptr);
|
||||
Step(boost::filesystem::path path, ImportStepProgressFn stepFn = nullptr, StepIsUtf8Fn isUtf8Fn = nullptr);
|
||||
Step(std::string path, ImportStepProgressFn stepFn = nullptr, StepIsUtf8Fn isUtf8Fn = nullptr);
|
||||
~Step();
|
||||
Step_Status load();
|
||||
|
||||
@@ -133,6 +133,8 @@ using namespace std::literals::string_view_literals;
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
namespace fs = boost::filesystem;
|
||||
|
||||
namespace Slic3r {
|
||||
|
||||
//! macro used to mark string used at localization,
|
||||
@@ -4412,11 +4414,6 @@ struct PrecomputedLayer
|
||||
};
|
||||
} // namespace
|
||||
|
||||
template<typename BoolsOption> static bool any_enabled(const BoolsOption &option)
|
||||
{
|
||||
return std::any_of(option.values.begin(), option.values.end(), [](unsigned char enabled) { return enabled != 0; });
|
||||
}
|
||||
|
||||
// Whether process_layer() prepares the overhang estimator for `layer`.
|
||||
template<typename OverhangSpeed>
|
||||
static bool prepares_overhang_estimator(const Layer &layer, bool overhang_fan, OverhangSpeed overhang_speed)
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
#include <cmath>
|
||||
#include <cctype>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
namespace Slic3r {
|
||||
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
#include "../ClipperUtils.hpp"
|
||||
#include "../Flow.hpp"
|
||||
#include "../Config.hpp"
|
||||
#include "libslic3r/ExtrusionEntityCollection.hpp"
|
||||
#include "libslic3r/Line.hpp"
|
||||
#include "libslic3r/ExPolygon.hpp"
|
||||
|
||||
@@ -22,6 +23,7 @@
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <functional>
|
||||
#include <limits>
|
||||
#include <memory>
|
||||
|
||||
@@ -321,8 +321,7 @@ Model Model::read_from_file(const std::string&
|
||||
Import3mfProgressFn proFn,
|
||||
ImportstlProgressFn stlFn,
|
||||
BBLProject * project,
|
||||
int plate_id,
|
||||
ObjImportColorFn objFn)
|
||||
int plate_id)
|
||||
{
|
||||
Model model;
|
||||
|
||||
|
||||
@@ -1756,8 +1756,7 @@ public:
|
||||
std::vector<Preset*>* project_presets = nullptr, bool* is_xxx = nullptr, Semver* file_version = nullptr, Import3mfProgressFn proFn = nullptr,
|
||||
ImportstlProgressFn stlFn = nullptr,
|
||||
BBLProject * project = nullptr,
|
||||
int plate_id = 0,
|
||||
ObjImportColorFn objFn = nullptr
|
||||
int plate_id = 0
|
||||
);
|
||||
// BBS
|
||||
static bool obj_import_vertex_color_deal(const std::vector<unsigned char> &vertex_filament_ids, const unsigned char &first_extruder_id, Model *model);
|
||||
|
||||
@@ -87,6 +87,8 @@
|
||||
#include "PlaceholderParser.hpp"
|
||||
#include "libslic3r/GCode/Thumbnails.hpp"
|
||||
|
||||
namespace fs = boost::filesystem;
|
||||
|
||||
using boost::property_tree::ptree;
|
||||
|
||||
namespace Slic3r {
|
||||
|
||||
@@ -473,8 +473,8 @@ public:
|
||||
|
||||
// Orca: Bundle metadata and cached preset names
|
||||
// std::map<std::string, BundleMetadata> m_bundles;
|
||||
fs::path dir_user_presets_local;
|
||||
fs::path dir_user_presets_subscribed;
|
||||
boost::filesystem::path dir_user_presets_local;
|
||||
boost::filesystem::path dir_user_presets_subscribed;
|
||||
PresetBundleMetadata bundles;
|
||||
|
||||
struct ObsoletePresets
|
||||
|
||||
@@ -102,6 +102,8 @@
|
||||
|
||||
#include <codecvt>
|
||||
|
||||
namespace fs = boost::filesystem;
|
||||
|
||||
using namespace nlohmann;
|
||||
|
||||
// Mark string for localization and translate.
|
||||
|
||||
@@ -789,6 +789,12 @@ class StaticPrintConfig;
|
||||
// Minimum object distance for arrangement, based on printer technology.
|
||||
double min_object_distance(const ConfigBase &cfg);
|
||||
|
||||
// Whether any value is set, a nil value included.
|
||||
template<bool NULLABLE> bool any_enabled(const ConfigOptionBoolsTempl<NULLABLE> &option)
|
||||
{
|
||||
return std::any_of(option.values.begin(), option.values.end(), [](unsigned char enabled) { return enabled != 0; });
|
||||
}
|
||||
|
||||
// One (extruder type x nozzle volume type) parameter variant a filament prints through, plus a
|
||||
// representative physical extruder observed using it. Ordering (and set-dedup identity) covers
|
||||
// the variant pair only, so the same variant reached through two extruders keeps one config slot.
|
||||
|
||||
@@ -1025,10 +1025,13 @@ void PrintObject::generate_support_material()
|
||||
void PrintObject::estimate_curled_extrusions()
|
||||
{
|
||||
if (this->set_started(posEstimateCurledExtrusions)) {
|
||||
if ( std::any_of(this->print()->m_print_regions.begin(), this->print()->m_print_regions.end(), [](const PrintRegion* region) {
|
||||
const auto& cfg = region->config().enable_overhang_speed.values;
|
||||
return std::any_of(cfg.begin(), cfg.end(), [](const unsigned char v) { return (bool) v; });
|
||||
})) {
|
||||
const auto any_region_enables = [this](ConfigOptionBoolsNullable PrintRegionConfig::*option) {
|
||||
return std::any_of(this->print()->m_print_regions.begin(), this->print()->m_print_regions.end(),
|
||||
[option](const PrintRegion* region) { return any_enabled(region->config().*option); });
|
||||
};
|
||||
// Only the slowdown for curled perimeters reads the curled lines, and they stay empty unless some region has overhang speed on.
|
||||
if (any_region_enables(&PrintRegionConfig::enable_overhang_speed) &&
|
||||
any_region_enables(&PrintRegionConfig::slowdown_for_curled_perimeters)) {
|
||||
|
||||
// Estimate curling of support material and add it to the malformaition lines of each layer
|
||||
float support_flow_width = support_material_flow(this, this->config().layer_height).width();
|
||||
@@ -1038,6 +1041,9 @@ void PrintObject::estimate_curled_extrusions()
|
||||
float(this->config().brim_width.getFloat())};
|
||||
SupportSpotsGenerator::estimate_malformations(this->layers(), params);
|
||||
m_print->throw_if_canceled();
|
||||
} else {
|
||||
for (Layer *layer : m_layers)
|
||||
layer->curled_lines.clear();
|
||||
}
|
||||
//this->set_done(posEstimateCurledExtrusions);
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
|
||||
#include "Types.hpp"
|
||||
|
||||
#include <array>
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
///|/
|
||||
#include "../include/Viewer.hpp"
|
||||
#include "ViewerImpl.hpp"
|
||||
#include <array>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include "../include/Types.hpp"
|
||||
|
||||
@@ -428,8 +428,6 @@ set(SLIC3R_GUI_SOURCES
|
||||
GUI/NotificationManager.hpp
|
||||
GUI/OAuthDialog.cpp
|
||||
GUI/OAuthDialog.hpp
|
||||
GUI/ObjColorDialog.cpp
|
||||
GUI/ObjColorDialog.hpp
|
||||
GUI/ObjectDataViewModel.cpp
|
||||
GUI/ObjectDataViewModel.hpp
|
||||
GUI/OG_CustomCtrl.cpp
|
||||
|
||||
@@ -65,6 +65,8 @@
|
||||
#include "MainFrame.hpp"
|
||||
#include "Widgets/Label.hpp"
|
||||
|
||||
namespace fs = boost::filesystem;
|
||||
|
||||
namespace Slic3r { namespace GUI {
|
||||
|
||||
wxDEFINE_EVENT(EVT_AUXILIARY_IMPORT, wxCommandEvent);
|
||||
|
||||
@@ -99,7 +99,7 @@ public:
|
||||
bool m_cover{false};
|
||||
wxStaticText* m_text_name {nullptr};
|
||||
::TextInput* m_input_name {nullptr};
|
||||
fs::path m_file_path;
|
||||
boost::filesystem::path m_file_path;
|
||||
wxString m_add_file;
|
||||
wxString m_file_name;
|
||||
wxString cover_text_left;
|
||||
@@ -116,7 +116,7 @@ public:
|
||||
ScalableBitmap m_bitmap_txt;
|
||||
|
||||
public:
|
||||
AuFile(wxWindow *parent, fs::path file_path, wxString file_name, AuxiliaryFolderType type, wxWindowID id = wxID_ANY, const wxPoint &pos = wxDefaultPosition, const wxSize &size = wxDefaultSize, long style = wxTAB_TRAVERSAL);
|
||||
AuFile(wxWindow *parent, boost::filesystem::path file_path, wxString file_name, AuxiliaryFolderType type, wxWindowID id = wxID_ANY, const wxPoint &pos = wxDefaultPosition, const wxSize &size = wxDefaultSize, long style = wxTAB_TRAVERSAL);
|
||||
void enter_rename_mode();
|
||||
void exit_rename_mode();
|
||||
void OnPaint(wxPaintEvent &evt);
|
||||
@@ -164,7 +164,7 @@ public:
|
||||
|
||||
void clear();
|
||||
void update_cover();
|
||||
void update(std::vector<fs::path> paths);
|
||||
void update(std::vector<boost::filesystem::path> paths);
|
||||
void msw_rescale();
|
||||
|
||||
public:
|
||||
@@ -240,7 +240,7 @@ public:
|
||||
bool Show(bool show);
|
||||
|
||||
// core logic
|
||||
std::map<std::string, std::vector<fs::path>> m_paths_list;
|
||||
std::map<std::string, std::vector<boost::filesystem::path>> m_paths_list;
|
||||
wxString m_root_dir;
|
||||
void init_auxiliary();
|
||||
void create_folder(wxString name = wxEmptyString);
|
||||
|
||||
@@ -21,6 +21,8 @@
|
||||
#include <wx/variant.h>
|
||||
#include <wx/types.h>
|
||||
|
||||
namespace fs = boost::filesystem;
|
||||
|
||||
const static std::array<wxString, 4> s_default_folders = {
|
||||
_L("Model Pictures"),
|
||||
_L("Bill of Materials"),
|
||||
|
||||
@@ -83,6 +83,8 @@
|
||||
#include "UnsavedChangesDialog.hpp"
|
||||
#include "MainFrame.hpp"
|
||||
|
||||
namespace fs = boost::filesystem;
|
||||
|
||||
#if defined(__linux__) && defined(__WXGTK3__)
|
||||
#define wxLinux_gtk3 true
|
||||
#else
|
||||
|
||||
@@ -276,8 +276,9 @@ void DailyTipsPanel::set_position(const ImVec2& pos)
|
||||
void DailyTipsPanel::set_size(const ImVec2& size)
|
||||
{
|
||||
m_width = size.x;
|
||||
m_height = size.y;
|
||||
m_content_height = m_height - m_footer_height;
|
||||
//Orca: Keep the requested content height so expanding a collapsed panel restores its full size.
|
||||
m_content_height = size.y - m_footer_height;
|
||||
m_height = m_can_expand && !m_is_expanded ? m_footer_height : size.y;
|
||||
}
|
||||
|
||||
void DailyTipsPanel::set_can_expand(bool can_expand)
|
||||
@@ -647,4 +648,4 @@ void DailyTipsWindow::on_change_color_mode(bool is_dark)
|
||||
m_panel->on_change_color_mode(is_dark);
|
||||
}
|
||||
|
||||
}}
|
||||
}}
|
||||
|
||||
@@ -108,6 +108,8 @@
|
||||
|
||||
#include "IPrinterAgent.hpp"
|
||||
|
||||
namespace fs = boost::filesystem;
|
||||
|
||||
#define CALI_DEBUG
|
||||
#define MINUTE_30 1800000 //ms
|
||||
#define TIME_OUT 5000 //ms
|
||||
|
||||
@@ -3,10 +3,15 @@
|
||||
|
||||
#include "3DScene.hpp"
|
||||
|
||||
#include <chrono>
|
||||
#include <array>
|
||||
#include <glad/gl.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstring>
|
||||
#include <ratio>
|
||||
#include <vector>
|
||||
#include <utility>
|
||||
|
||||
namespace Slic3r {
|
||||
namespace GUI {
|
||||
|
||||
@@ -28,6 +28,8 @@
|
||||
#include "libslic3r/Layer.hpp"
|
||||
#include "Widgets/ProgressDialog.hpp"
|
||||
#include "MsgDialog.hpp"
|
||||
#include <boost/container_hash/hash.hpp>
|
||||
#include "slic3r/GUI/MeshUtils.hpp"
|
||||
#include <string>
|
||||
#include "libvgcode/include/Types.hpp"
|
||||
#include <vector>
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
#include <cstdint>
|
||||
#include <float.h>
|
||||
#include <set>
|
||||
#include "slic3r/GUI/MeshUtils.hpp"
|
||||
#include <string>
|
||||
#include <unordered_set>
|
||||
#include <utility>
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include "libslic3r/Point.hpp"
|
||||
#include "slic3r/GUI/3DScene.hpp"
|
||||
#include <cstdlib>
|
||||
#include <imgui.h>
|
||||
#include <map>
|
||||
#include <cmath>
|
||||
#include "libslic3r/Geometry.hpp"
|
||||
|
||||
@@ -58,6 +58,8 @@
|
||||
#include "libslic3r/Print.hpp"
|
||||
#include "libslic3r/Utils.hpp"
|
||||
|
||||
namespace fs = boost::filesystem;
|
||||
|
||||
namespace Slic3r {
|
||||
|
||||
class AppConfig;
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
#include "slic3r/GUI/Gizmos/GLGizmoSVG.hpp"
|
||||
#include "slic3r/GUI/Gizmos/GLGizmoMeshBoolean.hpp"
|
||||
#include "slic3r/GUI/Gizmos/GLGizmoAssembly.hpp"
|
||||
#include <initializer_list>
|
||||
#include <wx/timer.h>
|
||||
#include <vector>
|
||||
#include <cstddef>
|
||||
|
||||
@@ -25,6 +25,8 @@
|
||||
#include <mutex>
|
||||
#include <ctime>
|
||||
|
||||
namespace fs = boost::filesystem;
|
||||
|
||||
static const char* HMS_PATH = "hms";
|
||||
static const char* HMS_LOCAL_IMG_PATH = "hms/local_image";
|
||||
|
||||
|
||||
@@ -35,6 +35,9 @@
|
||||
#include <boost/chrono/duration.hpp>
|
||||
#include "slic3r/GUI/DeviceCore/DevStorage.h"
|
||||
#include <wx/event.h>
|
||||
#include <boost/filesystem.hpp>
|
||||
|
||||
namespace fs = boost::filesystem;
|
||||
|
||||
namespace Slic3r {
|
||||
namespace GUI {
|
||||
|
||||
@@ -20,6 +20,9 @@
|
||||
#include <wx/event.h>
|
||||
#include <functional>
|
||||
#include <exception>
|
||||
#include <boost/filesystem.hpp>
|
||||
|
||||
namespace fs = boost::filesystem;
|
||||
|
||||
namespace Slic3r {
|
||||
namespace GUI {
|
||||
|
||||
@@ -11,6 +11,8 @@
|
||||
#include "libslic3r/Utils.hpp"
|
||||
#include <exception>
|
||||
|
||||
namespace fs = boost::filesystem;
|
||||
|
||||
namespace Slic3r {
|
||||
namespace GUI {
|
||||
|
||||
|
||||
@@ -2880,17 +2880,24 @@ void NotificationManager::update_slicing_notif_dailytips(bool need_change)
|
||||
// Slicing progress notification was not found - init it thru plater so correct cancel callback function is appended
|
||||
wxGetApp().plater()->init_notification_manager();
|
||||
}
|
||||
// Orca: Ensures the slicing-progress controller exists before applying the first slicing transition.
|
||||
void NotificationManager::set_slicing_progress_began()
|
||||
{
|
||||
for (std::unique_ptr<PopNotification> & notification : m_pop_notifications) {
|
||||
if (notification->get_type() == NotificationType::SlicingProgress) {
|
||||
SlicingProgressNotification* spn = dynamic_cast<SlicingProgressNotification*>(notification.get());
|
||||
spn->set_progress_state(SlicingProgressNotification::SlicingProgressState::SP_BEGAN);
|
||||
return;
|
||||
auto find_slicing_progress = [this]() -> SlicingProgressNotification* {
|
||||
for (std::unique_ptr<PopNotification>& notification : m_pop_notifications) {
|
||||
if (notification->get_type() == NotificationType::SlicingProgress)
|
||||
return dynamic_cast<SlicingProgressNotification*>(notification.get());
|
||||
}
|
||||
return nullptr;
|
||||
};
|
||||
|
||||
SlicingProgressNotification* notification = find_slicing_progress();
|
||||
if (notification == nullptr) {
|
||||
wxGetApp().plater()->init_notification_manager();
|
||||
notification = find_slicing_progress();
|
||||
}
|
||||
// Slicing progress notification was not found - init it thru plater so correct cancel callback function is appended
|
||||
wxGetApp().plater()->init_notification_manager();
|
||||
if (notification != nullptr)
|
||||
notification->set_progress_state(SlicingProgressNotification::SlicingProgressState::SP_BEGAN);
|
||||
}
|
||||
void NotificationManager::set_slicing_progress_percentage(const std::string& text, float percentage)
|
||||
{
|
||||
|
||||
@@ -1,971 +0,0 @@
|
||||
#include <algorithm>
|
||||
#include "libslic3r/TriangleSelector.hpp"
|
||||
#include "slic3r/GUI/Widgets/HyperLink.hpp"
|
||||
#include "slic3r/GUI/GUI_Utils.hpp"
|
||||
#include "libslic3r/Format/OBJ.hpp"
|
||||
#include <cstddef>
|
||||
#include "libslic3r/Color.hpp"
|
||||
#include "slic3r/GUI/GuiColor.hpp"
|
||||
#include "slic3r/GUI/Widgets/SpinInput.hpp"
|
||||
#include "slic3r/GUI/Plater.hpp"
|
||||
#include "slic3r/GUI/wxExtensions.hpp"
|
||||
#include <cmath>
|
||||
#include <cstdlib>
|
||||
#include <boost/log/trivial.hpp>
|
||||
#include "slic3r/GUI/PartPlate.hpp"
|
||||
#include "slic3r/GUI/Camera.hpp"
|
||||
#include <sstream>
|
||||
//#include "libslic3r/FlushVolCalc.hpp"
|
||||
#include "ObjColorDialog.hpp"
|
||||
#include "BitmapCache.hpp"
|
||||
#include "GUI.hpp"//for ICON_SIZE
|
||||
#include "I18N.hpp"
|
||||
#include "GUI_App.hpp"
|
||||
#include "MsgDialog.hpp"
|
||||
#include "Widgets/Button.hpp"
|
||||
#include "MainFrame.hpp"
|
||||
#include "libslic3r/Config.hpp"
|
||||
#include "BitmapComboBox.hpp"
|
||||
#include "Widgets/ComboBox.hpp"
|
||||
#include "Widgets/DialogButtons.hpp"
|
||||
#include <wx/colour.h>
|
||||
#include <wx/event.h>
|
||||
#include <wx/gdicmn.h>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <wx/dialog.h>
|
||||
#include <wx/panel.h>
|
||||
#include <wx/busycursor.h>
|
||||
#include <wx/arrstr.h>
|
||||
#include <wx/image.h>
|
||||
#include <wx/anybutton.h>
|
||||
#include <wx/scrolwin.h>
|
||||
#include <wx/sizer.h>
|
||||
#include <wx/string.h>
|
||||
#include <wx/textctrl.h>
|
||||
#include <wx/spinctrl.h>
|
||||
|
||||
#include "libslic3r/ObjColorUtils.hpp"
|
||||
#include "libslic3r/Model.hpp"
|
||||
using namespace Slic3r;
|
||||
using namespace Slic3r::GUI;
|
||||
|
||||
int objcolor_scale(const int val) { return val * Slic3r::GUI::wxGetApp().em_unit() / 10; }
|
||||
int OBJCOLOR_ITEM_WIDTH() { return objcolor_scale(30); }
|
||||
static const wxColour g_text_color = wxColour(107, 107, 107, 255);
|
||||
static const wxColour g_undefined_color_in_obj = wxColour(0, 255, 0, 255);
|
||||
const int HEADER_BORDER = 5;
|
||||
const int CONTENT_BORDER = 3;
|
||||
const int PANEL_WIDTH = 400;
|
||||
const int COLOR_LABEL_WIDTH = 180;
|
||||
const int IMAGE_SIZE_WIDTH = 300;
|
||||
#define MIN_OBJCOLOR_DIALOG_WIDTH FromDIP(400)
|
||||
#define FIX_SCROLL_HEIGTH FromDIP(400)
|
||||
#define BTN_SIZE wxSize(FromDIP(58), FromDIP(24))
|
||||
#define BTN_GAP FromDIP(15)
|
||||
#define FIX_SCROLL_IMAGE_WIDTH FromDIP(270)
|
||||
static void update_ui(wxWindow* window)
|
||||
{
|
||||
Slic3r::GUI::wxGetApp().UpdateDarkUI(window);
|
||||
}
|
||||
|
||||
static const char g_min_cluster_color = 1;
|
||||
static const char g_max_color = (int) EnforcerBlockerType::ExtruderMax;
|
||||
|
||||
wxBoxSizer* ObjColorDialog::create_btn_sizer(long flags,bool exist_error)
|
||||
{
|
||||
auto btn_sizer = new wxBoxSizer(wxHORIZONTAL);
|
||||
if (!exist_error) {
|
||||
btn_sizer->AddSpacer(FromDIP(25));
|
||||
auto *tips = new HyperLink(this, _L("Wiki Guide")); // ORCA
|
||||
tips->SetURL("https://www.orcaslicer.com/wiki/import_export#obj");
|
||||
btn_sizer->Add(tips, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL);
|
||||
}
|
||||
btn_sizer->AddStretchSpacer();
|
||||
|
||||
auto dlg_btns = new DialogButtons(this, {"OK", "Cancel"});
|
||||
m_button_list[wxOK] = dlg_btns->GetOK();
|
||||
m_button_list[wxCANCEL] = dlg_btns->GetCANCEL();
|
||||
|
||||
btn_sizer->Add(dlg_btns, 0, wxEXPAND);
|
||||
return btn_sizer;
|
||||
}
|
||||
|
||||
void ObjColorDialog::on_dpi_changed(const wxRect &suggested_rect)
|
||||
{
|
||||
m_panel_ObjColor->msw_rescale();
|
||||
this->Refresh();
|
||||
}
|
||||
void ObjColorDialog::update_layout() {
|
||||
m_main_sizer->Layout();
|
||||
SetSizerAndFit(m_main_sizer);
|
||||
}
|
||||
|
||||
bool ObjColorDialog::Show(bool show) {
|
||||
if (m_panel_ObjColor->do_show(show)) {
|
||||
return DPIDialog::Show(true);
|
||||
} else {
|
||||
return DPIDialog::Show(false);
|
||||
}
|
||||
};
|
||||
|
||||
ObjColorDialog::ObjColorDialog(wxWindow *parent, Slic3r::ObjDialogInOut &in_out, const std::vector<std::string> &extruder_colours, const bool semm)
|
||||
: DPIDialog(parent ? parent : static_cast<wxWindow *>(wxGetApp().mainframe),
|
||||
wxID_ANY,
|
||||
_(L("OBJ file import color")),
|
||||
wxDefaultPosition,
|
||||
wxDefaultSize,
|
||||
wxDEFAULT_DIALOG_STYLE /* | wxRESIZE_BORDER*/)
|
||||
{
|
||||
auto m_line_top = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxSize(-1, 1));
|
||||
m_line_top->SetBackgroundColour(wxColour(166, 169, 170));
|
||||
|
||||
this->SetBackgroundColour(*wxWHITE);
|
||||
this->SetMinSize(wxSize(MIN_OBJCOLOR_DIALOG_WIDTH, -1));
|
||||
|
||||
m_main_sizer = new wxBoxSizer(wxVERTICAL);
|
||||
m_main_sizer->Add(m_line_top, 0, wxEXPAND, 0);
|
||||
// set min sizer width according to extruders count
|
||||
auto sizer_width = (int) (2.8 * OBJCOLOR_ITEM_WIDTH());
|
||||
sizer_width = sizer_width > MIN_OBJCOLOR_DIALOG_WIDTH ? sizer_width : MIN_OBJCOLOR_DIALOG_WIDTH;
|
||||
m_main_sizer->SetMinSize(wxSize(sizer_width, -1));
|
||||
bool some_face_no_color = false;
|
||||
if (!in_out.deal_vertex_color) {
|
||||
auto temp0 = in_out.input_colors.size();
|
||||
auto temp1 = in_out.model->objects[0]->volumes[0]->mesh_ptr()->facets_count();
|
||||
some_face_no_color = temp0 < temp1;
|
||||
}
|
||||
bool ok = in_out.lost_material_name.empty() && !some_face_no_color;
|
||||
if (ok) {
|
||||
m_panel_ObjColor = new ObjColorPanel(this, in_out, extruder_colours, semm);
|
||||
m_panel_ObjColor->set_layout_callback([this]() { update_layout(); });
|
||||
m_main_sizer->Add(m_panel_ObjColor, 1, wxEXPAND | wxALL, 0);
|
||||
}
|
||||
else {
|
||||
wxBoxSizer * error_mtl_sizer = new wxBoxSizer(wxVERTICAL);
|
||||
|
||||
wxStaticText *error_mtl_title = new wxStaticText(this, wxID_ANY, _L("Some faces don't have color defined."));
|
||||
if (!in_out.lost_material_name.empty()) {
|
||||
error_mtl_title->SetLabel(_L("MTL file exist error, could not find the material:") + " " + in_out.lost_material_name + ".");
|
||||
}
|
||||
error_mtl_title->SetFont(Label::Head_12);
|
||||
error_mtl_sizer->Add(error_mtl_title, 0, wxALIGN_LEFT | wxBOTTOM | wxTOP, FromDIP(5));
|
||||
|
||||
wxStaticText *tip_title = new wxStaticText(this, wxID_ANY, _L("Please check OBJ or MTL file."));
|
||||
tip_title->SetFont(Label::Head_12);
|
||||
error_mtl_sizer->Add(tip_title, 0, wxALIGN_LEFT | wxBOTTOM | wxTOP, FromDIP(5));
|
||||
|
||||
m_main_sizer->Add(error_mtl_sizer, 1, wxEXPAND | wxLEFT, FromDIP(25));
|
||||
}
|
||||
|
||||
m_buttons_sizer = create_btn_sizer(wxOK | wxCANCEL, !ok);
|
||||
if (!ok) {
|
||||
m_button_list[wxCANCEL]->Hide();
|
||||
m_button_list[wxOK]->Enable(true);
|
||||
// ORCA no need to set colors again
|
||||
} else {
|
||||
m_button_list[wxOK]->Bind(wxEVT_UPDATE_UI, ([this](wxUpdateUIEvent &e) {
|
||||
if (m_panel_ObjColor->is_ok() == m_button_list[wxOK]->IsEnabled()) { return; }
|
||||
m_button_list[wxOK]->Enable(m_panel_ObjColor->is_ok());
|
||||
// ORCA no need to set colors again
|
||||
}));
|
||||
}
|
||||
m_main_sizer->Add(m_buttons_sizer, 0, wxBOTTOM | wxTOP | wxRIGHT | wxEXPAND, BTN_GAP);
|
||||
SetSizer(m_main_sizer);
|
||||
m_main_sizer->SetSizeHints(this);
|
||||
|
||||
if (this->FindWindowById(wxID_OK, this)) {
|
||||
this->FindWindowById(wxID_OK, this)->Bind(wxEVT_BUTTON, [this](wxCommandEvent&) {// if OK button is clicked..
|
||||
if (!m_panel_ObjColor) {
|
||||
EndModal(wxCANCEL);
|
||||
return;
|
||||
}
|
||||
m_panel_ObjColor->clear_instance_and_revert_offset();
|
||||
m_panel_ObjColor->send_new_filament_to_ui();
|
||||
EndModal(wxID_OK);
|
||||
}, wxID_OK);
|
||||
}
|
||||
if (this->FindWindowById(wxID_CANCEL, this)) {
|
||||
update_ui(static_cast<wxButton*>(this->FindWindowById(wxID_CANCEL, this)));
|
||||
this->FindWindowById(wxID_CANCEL, this)->Bind(wxEVT_BUTTON, [this](wxCommandEvent&) {
|
||||
if (m_panel_ObjColor) {
|
||||
m_panel_ObjColor->cancel_paint_color();
|
||||
}
|
||||
EndModal(wxCANCEL);
|
||||
});
|
||||
}
|
||||
this->Bind(wxEVT_CLOSE_WINDOW, [this](wxCloseEvent &e) {
|
||||
if (m_panel_ObjColor) {
|
||||
m_panel_ObjColor->cancel_paint_color();
|
||||
}
|
||||
EndModal(wxCANCEL);
|
||||
});
|
||||
|
||||
wxGetApp().UpdateDlgDarkUI(this);
|
||||
CenterOnParent();
|
||||
}
|
||||
|
||||
// This panel contains all control widgets for both simple and advanced mode (these reside in separate sizers)
|
||||
ObjColorPanel::ObjColorPanel(wxWindow *parent, Slic3r::ObjDialogInOut &in_out, const std::vector<std::string> &extruder_colours, const bool semm)
|
||||
: wxPanel(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize /*,wxBORDER_RAISED*/)
|
||||
, m_obj_in_out(in_out)
|
||||
, m_input_colors(in_out.input_colors)
|
||||
, m_filament_ids(in_out.filament_ids)
|
||||
, m_first_extruder_id(in_out.first_extruder_id)
|
||||
, m_semm(semm)
|
||||
{
|
||||
if (in_out.input_colors.size() == 0) { return; }
|
||||
for (const std::string& color : extruder_colours) {
|
||||
m_colours.push_back(wxColor(color));
|
||||
}
|
||||
//deal input_colors
|
||||
m_input_colors_size = in_out.input_colors.size();
|
||||
for (size_t i = 0; i < in_out.input_colors.size(); i++) {
|
||||
if (color_is_equal(in_out.input_colors[i], UNDEFINE_COLOR)) { // not define color range:0~1
|
||||
in_out.input_colors[i] = convert_to_rgba(m_colours[0]);
|
||||
}
|
||||
}
|
||||
if (in_out.is_single_color && in_out.input_colors.size() >= 1) {
|
||||
m_cluster_colors_from_algo.emplace_back(in_out.input_colors[0]);
|
||||
m_cluster_colours.emplace_back(convert_to_wxColour(in_out.input_colors[0]));
|
||||
m_cluster_labels_from_algo.reserve(m_input_colors_size);
|
||||
for (size_t i = 0; i < m_input_colors_size; i++) {
|
||||
m_cluster_labels_from_algo.emplace_back(0);
|
||||
}
|
||||
m_cluster_map_filaments.resize(m_cluster_colors_from_algo.size());
|
||||
m_new_add_colors.resize(m_cluster_map_filaments.size());
|
||||
m_color_num_recommend = m_color_cluster_num_by_algo = m_cluster_colors_from_algo.size();
|
||||
} else {//cluster deal
|
||||
deal_algo(-1);
|
||||
}
|
||||
//end first cluster
|
||||
//draw ui
|
||||
auto sizer_width = FromDIP(300);
|
||||
// Create two switched panels with their own sizers
|
||||
m_sizer_simple = new wxBoxSizer(wxVERTICAL);
|
||||
m_page_simple = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL);
|
||||
m_page_simple->SetSizer(m_sizer_simple);
|
||||
m_page_simple->SetBackgroundColour(*wxWHITE);
|
||||
|
||||
update_ui(m_page_simple);
|
||||
// BBS
|
||||
m_sizer_simple->AddSpacer(FromDIP(10));
|
||||
// BBS: for tunning flush volumes
|
||||
{
|
||||
//color cluster results
|
||||
wxBoxSizer * specify_cluster_sizer = new wxBoxSizer(wxHORIZONTAL);
|
||||
wxStaticText *specify_color_cluster_title = new wxStaticText(m_page_simple, wxID_ANY, _L("Specify number of colors:"));
|
||||
specify_color_cluster_title->SetFont(Label::Head_14);
|
||||
specify_cluster_sizer->Add(specify_color_cluster_title, 0, wxALIGN_CENTER | wxALL, FromDIP(5));
|
||||
|
||||
m_color_cluster_num_by_user_ebox = new SpinInput(m_page_simple, "", wxEmptyString, wxDefaultPosition, wxSize(FromDIP(60), -1), wxTE_PROCESS_ENTER);
|
||||
m_color_cluster_num_by_user_ebox->SetValue(std::to_string(m_color_cluster_num_by_algo).c_str());
|
||||
m_color_cluster_num_by_user_ebox->SetToolTip(_L("Enter or click the adjustment button to modify number again"));
|
||||
{//event
|
||||
auto on_apply_color_cluster_text_modify = [this](wxEvent &e) {
|
||||
int number = m_color_cluster_num_by_user_ebox->GetValue();
|
||||
if (number > m_color_num_recommend || number < g_min_cluster_color) {
|
||||
number = number < g_min_cluster_color ? g_min_cluster_color : m_color_num_recommend;
|
||||
auto str = wxString::Format(("%d"), number);
|
||||
m_color_cluster_num_by_user_ebox->SetValue(str);
|
||||
// m_color_cluster_num_by_user_ebox->SetInsertionPointEnd();
|
||||
}
|
||||
if (m_last_cluster_num != number) {
|
||||
wxBusyCursor busy;
|
||||
deal_algo(number, true);
|
||||
Layout();
|
||||
Refresh();
|
||||
Update();
|
||||
m_last_cluster_num = number;
|
||||
}
|
||||
};
|
||||
m_color_cluster_num_by_user_ebox->Bind(wxEVT_TEXT_ENTER, on_apply_color_cluster_text_modify);
|
||||
m_color_cluster_num_by_user_ebox->Bind(wxEVT_SPINCTRL, on_apply_color_cluster_text_modify);
|
||||
|
||||
m_color_cluster_num_by_user_ebox->Bind(wxEVT_CHAR, [](wxKeyEvent &e) {
|
||||
int keycode = e.GetKeyCode();
|
||||
wxString input_char = wxString::Format("%c", keycode);
|
||||
long value;
|
||||
if (!input_char.ToLong(&value))
|
||||
return;
|
||||
e.Skip();
|
||||
});
|
||||
}
|
||||
specify_cluster_sizer->AddSpacer(FromDIP(2));
|
||||
specify_cluster_sizer->Add(m_color_cluster_num_by_user_ebox, 0, wxALIGN_CENTER | wxALL, 0);
|
||||
specify_cluster_sizer->AddSpacer(FromDIP(15));
|
||||
wxStaticText *recommend_color_cluster_title = new wxStaticText(m_page_simple, wxID_ANY, "(" + std::to_string(m_color_num_recommend) + " " + _L("Recommended ") + ")");
|
||||
specify_cluster_sizer->Add(recommend_color_cluster_title, 0, wxALIGN_CENTER | wxALL, 0);
|
||||
|
||||
m_sizer_simple->Add(specify_cluster_sizer, 0, wxEXPAND | wxLEFT, FromDIP(20));
|
||||
{//add combox
|
||||
auto icon_sizer = new wxBoxSizer(wxHORIZONTAL);
|
||||
auto plater = wxGetApp().plater();
|
||||
{
|
||||
auto mo = m_obj_in_out.model->objects[0];
|
||||
mo->add_instance();
|
||||
auto mv = mo->volumes[0];
|
||||
m_thumbnail_offset = Slic3r::Vec3d::Zero();
|
||||
auto box = mo->bounding_box_exact();
|
||||
if (box.min.x() < 0 || box.min.y() < 0 || box.min.z() < 0) {
|
||||
m_thumbnail_offset = Slic3r::Vec3d(box.min.x() < 0 ? -box.min.x() : 0, box.min.y() < 0 ? -box.min.y() : 0, box.min.z() < 0 ? -box.min.z() : 0);
|
||||
mv->translate(m_thumbnail_offset);
|
||||
}
|
||||
}
|
||||
|
||||
wxStaticText *combox_title = new wxStaticText(m_page_simple, wxID_ANY, _L("view"));
|
||||
auto cur_combox = new ComboBox(m_page_simple, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(FromDIP(100), -1), 0, NULL, wxCB_READONLY);
|
||||
wxArrayString choices = get_all_camera_view_type();
|
||||
for (size_t i = 0; i < choices.size(); i++) { cur_combox->Append(choices[i]); }
|
||||
cur_combox->SetSelection(0);
|
||||
cur_combox->Bind(wxEVT_COMBOBOX, [this](auto &e) {
|
||||
set_view_angle_type(e.GetSelection());
|
||||
Layout();
|
||||
Fit();
|
||||
});
|
||||
// add image
|
||||
wxImage image(IMAGE_SIZE_WIDTH, IMAGE_SIZE_WIDTH);
|
||||
image.InitAlpha();
|
||||
for (unsigned int r = 0; r < IMAGE_SIZE_WIDTH; ++r) {
|
||||
for (unsigned int c = 0; c < IMAGE_SIZE_WIDTH; ++c) {
|
||||
image.SetRGB((int) c, (int) r, 0, 255, 0);
|
||||
image.SetAlpha((int) c, (int) r, 255);
|
||||
}
|
||||
}
|
||||
m_image_button = new wxButton(m_page_simple, wxID_ANY, {}, wxDefaultPosition, wxSize(FromDIP(IMAGE_SIZE_WIDTH), FromDIP(IMAGE_SIZE_WIDTH)),
|
||||
wxBORDER_NONE | wxBU_AUTODRAW);
|
||||
m_image_button->SetBitmap(image);
|
||||
m_image_button->SetCanFocus(false);
|
||||
#ifdef __WXGTK__
|
||||
RemoveButtonBorder(m_image_button);
|
||||
#endif
|
||||
icon_sizer->Add(m_image_button, 0, wxEXPAND | wxALL,
|
||||
FromDIP(0)); // wxEXPAND | wxALL
|
||||
cur_combox->Raise();//for mac
|
||||
|
||||
m_sizer_simple->Add(icon_sizer, FromDIP(0), wxALIGN_CENTER | wxALL, FromDIP(0));
|
||||
auto view_sizer = new wxBoxSizer(wxHORIZONTAL);
|
||||
view_sizer->Add(combox_title, 0, wxALIGN_CENTER | wxALL, FromDIP(5));
|
||||
view_sizer->Add(cur_combox , 0, wxALIGN_CENTER | wxALL, FromDIP(5));
|
||||
m_sizer_simple->Add(view_sizer, 0, wxALIGN_RIGHT | wxRIGHT, FromDIP(20));
|
||||
}
|
||||
wxBoxSizer * current_filaments_title_sizer = new wxBoxSizer(wxHORIZONTAL);
|
||||
wxStaticText *current_filaments_title = new wxStaticText(m_page_simple, wxID_ANY, _L("Current filament colors"));
|
||||
current_filaments_title->SetFont(Label::Head_14);
|
||||
current_filaments_title_sizer->Add(current_filaments_title, 0, wxALIGN_CENTER | wxALL, FromDIP(5));
|
||||
m_sizer_simple->Add(current_filaments_title_sizer, 0, wxEXPAND | wxLEFT, FromDIP(20));
|
||||
int current_filament_row = 1;
|
||||
int current_filament_col = 1;
|
||||
const int one_row_max = 16;
|
||||
if (m_colours.size() > 1) {
|
||||
current_filament_row = (m_colours.size() - 1) / one_row_max + 1;
|
||||
if (current_filament_row >= 2) {
|
||||
current_filament_col = one_row_max;
|
||||
} else {
|
||||
current_filament_col = m_colours.size();
|
||||
}
|
||||
}
|
||||
m_sizer_current_filaments = new wxBoxSizer(wxHORIZONTAL);
|
||||
wxGridSizer *current_filaments_sizer = new wxGridSizer(current_filament_row, current_filament_col, FromDIP(5), FromDIP(7)); //(int rows, int cols, int vgap, int hgap );
|
||||
for (size_t i = 0; i < m_colours.size(); i++) {
|
||||
auto extruder_icon_sizer = create_extruder_icon_and_rgba_sizer(m_page_simple, i, m_colours[i]);
|
||||
current_filaments_sizer->Add(extruder_icon_sizer, 0, wxALIGN_LEFT);
|
||||
}
|
||||
m_sizer_current_filaments->AddSpacer(FromDIP(1));
|
||||
m_sizer_current_filaments->Add(current_filaments_sizer, 0, wxEXPAND);
|
||||
m_sizer_current_filaments->AddStretchSpacer();
|
||||
m_sizer_simple->Add(m_sizer_current_filaments, 0, wxEXPAND | wxLEFT, FromDIP(25));
|
||||
//colors table title
|
||||
wxBoxSizer * matching_title_sizer = new wxBoxSizer(wxHORIZONTAL);
|
||||
matching_title_sizer->AddSpacer(FromDIP(25));
|
||||
wxStaticText *matching_title = new wxStaticText(m_page_simple, wxID_ANY, _L("Matching"));
|
||||
matching_title->SetFont(Label::Head_14);
|
||||
matching_title_sizer->Add(matching_title, 0, wxEXPAND , 0);
|
||||
m_sizer_simple->Add(matching_title_sizer, 0, wxEXPAND | wxTOP, FromDIP(15));// wxTop has FromDIP(10) margin
|
||||
//new color table
|
||||
m_scrolledWindow = new wxScrolledWindow(m_page_simple, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxVSCROLL);
|
||||
m_scrolledWindow->SetBackgroundColour(*wxWHITE);
|
||||
m_scrolledWindow->SetScrollRate(0, FromDIP(20));
|
||||
m_scrolledWindow->EnableScrolling(false, true);
|
||||
m_scrolledWindow->ShowScrollbars(wxScrollbarVisibility::wxSHOW_SB_NEVER, wxScrollbarVisibility::wxSHOW_SB_DEFAULT);
|
||||
draw_new_table();
|
||||
|
||||
m_sizer_simple->Add(m_scrolledWindow, 0, wxEXPAND | wxLEFT | wxRIGHT, FromDIP(15));
|
||||
//buttons
|
||||
wxBoxSizer *quick_set_sizer = new wxBoxSizer(wxHORIZONTAL);
|
||||
quick_set_sizer->AddSpacer(FromDIP(25));
|
||||
wxStaticText *quick_set_title = new wxStaticText(m_page_simple, wxID_ANY, _L("Quick set"));
|
||||
quick_set_title->SetFont(Label::Head_12);
|
||||
quick_set_sizer->Add(quick_set_title, 0, wxALIGN_CENTER | wxALL, 0);
|
||||
quick_set_sizer->AddSpacer(FromDIP(10));
|
||||
|
||||
auto calc_approximate_match_btn_sizer = create_approximate_match_btn_sizer(m_page_simple);
|
||||
auto calc_add_btn_sizer = create_add_btn_sizer(m_page_simple);
|
||||
auto calc_reset_btn_sizer = create_reset_btn_sizer(m_page_simple);
|
||||
quick_set_sizer->Add(calc_add_btn_sizer, 0, wxALIGN_CENTER | wxALL, 0);
|
||||
quick_set_sizer->AddSpacer(FromDIP(10));
|
||||
quick_set_sizer->Add(calc_approximate_match_btn_sizer, 0, wxALIGN_CENTER | wxALL, 0);
|
||||
quick_set_sizer->AddSpacer(FromDIP(10));
|
||||
quick_set_sizer->Add(calc_reset_btn_sizer, 0, wxALIGN_CENTER | wxALL, 0);
|
||||
quick_set_sizer->AddSpacer(FromDIP(10));
|
||||
m_sizer_simple->Add(quick_set_sizer, 0, wxEXPAND | wxTOP, FromDIP(10));
|
||||
|
||||
wxBoxSizer *warning_sizer = new wxBoxSizer(wxHORIZONTAL);
|
||||
m_warning_text = new wxStaticText(m_page_simple, wxID_ANY, "");
|
||||
m_warning_text->SetForegroundColour(wxColour(107, 107, 107, 100));
|
||||
warning_sizer->Add(m_warning_text, 0, wxALIGN_CENTER | wxALL, 0);
|
||||
m_sizer_simple->Add(warning_sizer, 0, wxEXPAND | wxLEFT, FromDIP(25));
|
||||
|
||||
m_sizer_simple->AddSpacer(15);
|
||||
}
|
||||
deal_default_strategy();
|
||||
deal_thumbnail();
|
||||
//page_simple//page_advanced
|
||||
m_sizer = new wxBoxSizer(wxVERTICAL);
|
||||
m_sizer->Add(m_page_simple, 0, wxEXPAND, 0);
|
||||
|
||||
m_sizer->SetSizeHints(this);
|
||||
SetSizer(m_sizer);
|
||||
this->Layout();
|
||||
}
|
||||
|
||||
ObjColorPanel::~ObjColorPanel() {
|
||||
}
|
||||
|
||||
void ObjColorPanel::msw_rescale()
|
||||
{
|
||||
for (unsigned int i = 0; i < m_extruder_icon_list.size(); ++i) {
|
||||
auto bitmap = *get_extruder_color_icon(m_colours[i].GetAsString(wxC2S_HTML_SYNTAX).ToStdString(), std::to_string(i + 1), FromDIP(16), FromDIP(16));
|
||||
m_extruder_icon_list[i]->SetBitmap(bitmap);
|
||||
}
|
||||
/* for (unsigned int i = 0; i < m_color_cluster_icon_list.size(); ++i) {
|
||||
auto bitmap = *get_extruder_color_icon(m_cluster_colours[i].GetAsString(wxC2S_HTML_SYNTAX).ToStdString(), std::to_string(i + 1), FromDIP(16), FromDIP(16));
|
||||
m_color_cluster_icon_list[i]->SetBitmap(bitmap);
|
||||
}*/
|
||||
}
|
||||
|
||||
bool ObjColorPanel::is_ok() {
|
||||
for (auto item : m_result_icon_list) {
|
||||
if (item->bitmap_combox->IsShown()) {
|
||||
auto selection = item->bitmap_combox->GetSelection();
|
||||
if (selection < 1) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void ObjColorPanel::send_new_filament_to_ui()
|
||||
{
|
||||
update_new_add_final_colors();
|
||||
if (m_is_add_filament) {
|
||||
for (auto c : m_new_add_final_colors) {
|
||||
/*auto evt = new ColorEvent(EVT_ADD_CUSTOM_FILAMENT, c);
|
||||
wxQueueEvent(wxGetApp().plater(), evt);*/
|
||||
wxGetApp().sidebar().add_custom_filament(c);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ObjColorPanel::cancel_paint_color() {
|
||||
m_filament_ids.clear();
|
||||
auto mo = m_obj_in_out.model->objects[0];
|
||||
mo->config.set("extruder", 1);
|
||||
clear_instance_and_revert_offset();
|
||||
auto mv = mo->volumes[0];
|
||||
mv->mmu_segmentation_facets.reset();
|
||||
mv->config.set("extruder", 1);
|
||||
m_first_extruder_id = 1;
|
||||
}
|
||||
|
||||
void ObjColorPanel::update_filament_ids()
|
||||
{
|
||||
//deal m_filament_ids
|
||||
m_filament_ids.clear();
|
||||
m_filament_ids.reserve(m_input_colors_size);
|
||||
for (size_t i = 0; i < m_input_colors_size; i++) {
|
||||
auto label = m_cluster_labels_from_algo[i];
|
||||
if (m_cluster_map_filaments[label] > 0) {
|
||||
m_filament_ids.emplace_back(m_cluster_map_filaments[label]);
|
||||
} else {
|
||||
m_filament_ids.emplace_back(1);//min filament_id is 1
|
||||
}
|
||||
}
|
||||
m_first_extruder_id = m_cluster_map_filaments[0];
|
||||
}
|
||||
|
||||
void ObjColorPanel::set_layout_callback(LayoutChanggeCallback callback) {
|
||||
m_layout_callback = callback;
|
||||
}
|
||||
|
||||
void ObjColorPanel::do_layout_callback() {
|
||||
if (m_layout_callback) {
|
||||
m_layout_callback();
|
||||
}
|
||||
}
|
||||
|
||||
wxBoxSizer *ObjColorPanel::create_approximate_match_btn_sizer(wxWindow *parent)
|
||||
{
|
||||
auto btn_sizer = new wxBoxSizer(wxHORIZONTAL);
|
||||
m_quick_approximate_match_btn = new Button(parent, _L("Color match"));
|
||||
m_quick_approximate_match_btn->SetToolTip(_L("Approximate color matching."));
|
||||
m_quick_approximate_match_btn->SetStyle(ButtonStyle::Regular, ButtonType::Window);
|
||||
m_quick_approximate_match_btn->SetFocus();
|
||||
btn_sizer->Add(m_quick_approximate_match_btn, 0, wxRIGHT | wxALIGN_CENTER_VERTICAL, 0);
|
||||
m_quick_approximate_match_btn->Bind(wxEVT_BUTTON, [this](wxCommandEvent &) {
|
||||
deal_approximate_match_btn();
|
||||
deal_thumbnail();
|
||||
});
|
||||
return btn_sizer;
|
||||
}
|
||||
|
||||
wxBoxSizer *ObjColorPanel::create_add_btn_sizer(wxWindow *parent)
|
||||
{
|
||||
auto btn_sizer = new wxBoxSizer(wxHORIZONTAL);
|
||||
m_quick_add_btn = new Button(parent, _L("Append"));
|
||||
m_quick_add_btn->SetToolTip(_L("Append to existing filaments"));
|
||||
auto cur_btn = m_quick_add_btn;
|
||||
cur_btn->SetStyle(ButtonStyle::Regular, ButtonType::Window);
|
||||
cur_btn->SetFocus();
|
||||
btn_sizer->Add(cur_btn, 0, wxRIGHT | wxALIGN_CENTER_VERTICAL, 0);
|
||||
cur_btn->Bind(wxEVT_BUTTON, [this](wxCommandEvent &) {
|
||||
deal_add_btn();
|
||||
deal_thumbnail();
|
||||
});
|
||||
m_quick_add_btn->Enable(m_semm); // only SEMM printer can add more colors
|
||||
return btn_sizer;
|
||||
}
|
||||
|
||||
wxBoxSizer *ObjColorPanel::create_reset_btn_sizer(wxWindow *parent)
|
||||
{
|
||||
auto btn_sizer = new wxBoxSizer(wxHORIZONTAL);
|
||||
m_quick_reset_btn = new Button(parent, _L("Reset"));
|
||||
m_quick_reset_btn->SetToolTip(_L("Reset mapped extruders."));
|
||||
auto cur_btn = m_quick_reset_btn;
|
||||
cur_btn->SetStyle(ButtonStyle::Regular, ButtonType::Window);
|
||||
cur_btn->SetFocus();
|
||||
btn_sizer->Add(cur_btn, 0, wxRIGHT | wxALIGN_CENTER_VERTICAL, 0);
|
||||
cur_btn->Bind(wxEVT_BUTTON, [this](wxCommandEvent &) {
|
||||
deal_reset_btn();
|
||||
deal_thumbnail();
|
||||
});
|
||||
return btn_sizer;
|
||||
}
|
||||
|
||||
wxBoxSizer *ObjColorPanel::create_extruder_icon_and_rgba_sizer(wxWindow *parent, int id, const wxColour &color)
|
||||
{
|
||||
auto icon_sizer = new wxBoxSizer(wxHORIZONTAL);
|
||||
wxButton *icon = new wxButton(parent, wxID_ANY, {}, wxDefaultPosition, FromDIP(wxSize(20,20)), wxBORDER_NONE | wxBU_AUTODRAW);
|
||||
icon->SetBitmap(*get_extruder_color_icon(color.GetAsString(wxC2S_HTML_SYNTAX).ToStdString(), std::to_string(id + 1), FromDIP(20), FromDIP(20)));
|
||||
icon->SetCanFocus(false);
|
||||
#ifdef __WXGTK__
|
||||
RemoveButtonBorder(icon);
|
||||
#endif
|
||||
m_extruder_icon_list.emplace_back(icon);
|
||||
icon_sizer->Add(icon, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL, 0); // wxALIGN_CENTER_VERTICAL | wxTOP | wxBOTTOM
|
||||
//icon_sizer->AddSpacer(FromDIP(5));
|
||||
return icon_sizer;
|
||||
}
|
||||
|
||||
std::string ObjColorPanel::get_color_str(const wxColour &color) {
|
||||
std::string str = ("R:" + std::to_string(color.Red()) +
|
||||
std::string(" G:") + std::to_string(color.Green()) +
|
||||
std::string(" B:") + std::to_string(color.Blue()) +
|
||||
std::string(" A:") + std::to_string(color.Alpha()));
|
||||
return str;
|
||||
}
|
||||
|
||||
ComboBox *ObjColorPanel::CreateEditorCtrl(wxWindow *parent, int id) // wxRect labelRect,, const wxVariant &value
|
||||
{
|
||||
std::vector<wxBitmap *> icons = get_extruder_color_icons();
|
||||
const double em = Slic3r::GUI::wxGetApp().em_unit();
|
||||
bool thin_icon = false;
|
||||
const int icon_width = lround((thin_icon ? 2 : 4.4) * em);
|
||||
const int icon_height = lround(2 * em);
|
||||
m_combox_icon_width = icon_width;
|
||||
m_combox_icon_height = icon_height;
|
||||
|
||||
icons.insert(icons.begin(), get_extruder_color_icon(g_undefined_color_in_obj.GetAsString(wxC2S_HTML_SYNTAX).ToStdString(), std::to_string(-1), icon_width, icon_height));
|
||||
if (icons.empty())
|
||||
return nullptr;
|
||||
|
||||
::ComboBox *c_editor = new ::ComboBox(parent, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0, nullptr,
|
||||
wxCB_READONLY | CB_NO_DROP_ICON | CB_NO_TEXT);
|
||||
c_editor->SetMinSize(wxSize(icon_width + FromDIP(8), -1)); // match size with bitmap
|
||||
c_editor->SetMaxSize(wxSize(icon_width + FromDIP(8), -1)); // match size with bitmap
|
||||
c_editor->GetDropDown().SetUseContentWidth(false);
|
||||
for (size_t i = 0; i < icons.size(); i++) {
|
||||
c_editor->Append(wxString::Format("%d", i), *icons[i]);
|
||||
if (i == 0) {
|
||||
c_editor->SetItemTooltip(i, g_undefined_color_in_obj.GetAsString(wxC2S_HTML_SYNTAX));
|
||||
} else {
|
||||
c_editor->SetItemTooltip(i, m_colours[i-1].GetAsString(wxC2S_HTML_SYNTAX));
|
||||
}
|
||||
}
|
||||
c_editor->SetSelection(0);
|
||||
c_editor->SetName(wxString::Format("%d", id));
|
||||
c_editor->Bind(wxEVT_COMBOBOX, [this](wxCommandEvent &evt) {
|
||||
auto *com_box = static_cast<ComboBox *>(evt.GetEventObject());
|
||||
int i = atoi(com_box->GetName().c_str());
|
||||
if (i < m_cluster_map_filaments.size()) {
|
||||
m_cluster_map_filaments[i] = com_box->GetSelection();
|
||||
m_new_add_colors[i] = com_box->GetItemTooltip(com_box->GetSelection());
|
||||
deal_thumbnail();
|
||||
}
|
||||
evt.StopPropagation();
|
||||
});
|
||||
return c_editor;
|
||||
}
|
||||
|
||||
void ObjColorPanel::deal_approximate_match_btn()
|
||||
{
|
||||
m_warning_text->SetLabelText("");
|
||||
if (m_result_icon_list.size() == 0) { return; }
|
||||
auto map_count = m_result_icon_list[0]->bitmap_combox->GetCount() -1;
|
||||
if (map_count < 1) { return; }
|
||||
for (size_t i = 0; i < m_cluster_colours.size(); i++) {
|
||||
auto c = m_cluster_colours[i];
|
||||
std::vector<ColorDistValue> color_dists;
|
||||
color_dists.resize(map_count);
|
||||
for (size_t j = 0; j < map_count; j++) {
|
||||
auto tip_color = m_result_icon_list[0]->bitmap_combox->GetItemTooltip(j+1);
|
||||
wxColour candidate_c(tip_color);
|
||||
color_dists[j].distance = calc_color_distance(c, candidate_c);
|
||||
color_dists[j].id = j + 1;
|
||||
}
|
||||
std::sort(color_dists.begin(), color_dists.end(), [](ColorDistValue &a, ColorDistValue& b) {
|
||||
return a.distance < b.distance;
|
||||
});
|
||||
auto new_index= color_dists[0].id;
|
||||
m_result_icon_list[i]->bitmap_combox->SetSelection(new_index);
|
||||
m_new_add_colors[i] = m_result_icon_list[i]->bitmap_combox->GetItemTooltip(new_index);
|
||||
m_cluster_map_filaments[i] = new_index;
|
||||
}
|
||||
}
|
||||
|
||||
void ObjColorPanel::show_sizer(wxSizer *sizer, bool show)
|
||||
{
|
||||
wxSizerItemList items = sizer->GetChildren();
|
||||
for (wxSizerItemList::iterator it = items.begin(); it != items.end(); ++it) {
|
||||
wxSizerItem *item = *it;
|
||||
if (wxWindow *window = item->GetWindow()) {
|
||||
window->Show(show);
|
||||
}
|
||||
if (wxSizer *son_sizer = item->GetSizer()) {
|
||||
show_sizer(son_sizer, show);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void ObjColorPanel::draw_new_table()
|
||||
{
|
||||
auto cluster_count = m_cluster_colours.size();
|
||||
auto col = 3;
|
||||
auto row = cluster_count / col;
|
||||
auto remainder = cluster_count % col;
|
||||
if (remainder > 0) {
|
||||
row++;
|
||||
}
|
||||
int old_row = 0;
|
||||
bool first_draw = false;
|
||||
if (m_new_grid_sizer) {
|
||||
old_row = m_new_grid_sizer->GetRows();
|
||||
m_new_grid_sizer->SetRows(row);
|
||||
}
|
||||
else {
|
||||
first_draw = true;
|
||||
m_new_grid_sizer = new wxGridSizer(row, 1, 1, 3); //(int rows, int cols, int vgap, int hgap );
|
||||
m_scrolledWindow->SetSizer(m_new_grid_sizer);
|
||||
}
|
||||
if (!first_draw) {
|
||||
for (size_t i = old_row; i < row; i++) { show_sizer(m_row_sizer_list[i], true); }
|
||||
for (size_t i = row; i < old_row; i++) { show_sizer(m_row_sizer_list[i], false); }
|
||||
for (size_t i = 0; i < cluster_count; i++) { show_sizer(m_row_col_boxsizer_list[i], true); }
|
||||
for (size_t i = cluster_count; i < m_color_num_recommend; i++) { show_sizer(m_row_col_boxsizer_list[i], false); }
|
||||
for (size_t ii = 0; ii < row; ii++) {
|
||||
for (size_t j = 0; j < col; j++) {
|
||||
auto id = ii * col + j;
|
||||
if (id >= cluster_count) {
|
||||
break;
|
||||
}
|
||||
auto color = m_cluster_colours[id];
|
||||
m_color_cluster_icon_list[id]->SetBitmap(*get_extruder_color_icon(color.GetAsString(wxC2S_HTML_SYNTAX).ToStdString(), "", FromDIP(16), FromDIP(16)));
|
||||
}
|
||||
}
|
||||
}
|
||||
else {//first draw
|
||||
for (size_t ii = 0; ii < row; ii++) {
|
||||
wxPanel *row_panel = new wxPanel(m_scrolledWindow);
|
||||
//row_panel->SetBackgroundColour(ii % 2 == 0 ? *wxWHITE : wxColour(238, 238, 238));
|
||||
auto row_sizer = new wxGridSizer(1, col, 1, 1);
|
||||
row_panel->SetSizer(row_sizer);
|
||||
|
||||
row_panel->SetMinSize(wxSize(FromDIP(PANEL_WIDTH), -1));
|
||||
row_panel->SetMaxSize(wxSize(FromDIP(PANEL_WIDTH), -1));
|
||||
for (size_t j = 0; j < col; j++) {
|
||||
auto id = ii * col + j;
|
||||
if (id >= cluster_count) {
|
||||
break;
|
||||
}
|
||||
auto cluster_color_icon_sizer = create_color_icon_map_rgba_sizer(row_panel, id, m_cluster_colours[id]);
|
||||
m_row_col_boxsizer_list.emplace_back(cluster_color_icon_sizer);
|
||||
row_sizer->Add(cluster_color_icon_sizer, 0, wxALIGN_CENTER | wxALIGN_CENTER_VERTICAL, 0);
|
||||
}
|
||||
m_row_sizer_list.emplace_back(row_sizer);
|
||||
m_new_grid_sizer->Add(row_panel, 0, wxALIGN_LEFT | wxALL, FromDIP(HEADER_BORDER));
|
||||
}
|
||||
}
|
||||
m_new_grid_sizer->Layout();
|
||||
auto height = m_new_grid_sizer->GetMinSize().GetY();
|
||||
if (row <= 4 || height < FromDIP(185)) {
|
||||
m_scrolledWindow->SetMinSize(wxSize(-1, height));
|
||||
} else {
|
||||
m_scrolledWindow->SetMinSize(wxSize(-1, FromDIP(185)));
|
||||
m_scrolledWindow->SetMaxSize(wxSize(-1, FromDIP(185)));
|
||||
}
|
||||
m_scrolledWindow->FitInside();
|
||||
if (!first_draw) {
|
||||
do_layout_callback();
|
||||
}
|
||||
}
|
||||
|
||||
void ObjColorPanel::update_new_add_final_colors()
|
||||
{
|
||||
m_new_add_final_colors = m_new_add_colors;
|
||||
if (!m_cluster_map_filaments.empty()) {
|
||||
m_max_filament_index = *std::max_element(m_cluster_map_filaments.begin(), m_cluster_map_filaments.end());
|
||||
} else {
|
||||
m_max_filament_index = 0;
|
||||
}
|
||||
|
||||
if (m_max_filament_index <= m_colours.size()) { // Fix 20240904
|
||||
m_new_add_final_colors.clear();
|
||||
}
|
||||
else {
|
||||
m_new_add_final_colors.resize(m_max_filament_index - m_colours.size());
|
||||
for (int ii = m_colours.size() ; ii < m_max_filament_index; ii++) {
|
||||
for (int j = 0; j < m_cluster_map_filaments.size(); j++) {
|
||||
if (m_cluster_map_filaments[j] == (ii+ 1) && j < m_new_add_colors.size()) {
|
||||
auto index = ii - m_colours.size();
|
||||
if (index < m_new_add_final_colors.size()) {
|
||||
m_new_add_final_colors[index] = m_new_add_colors[j];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (m_new_add_final_colors.size() > 0) {
|
||||
m_is_add_filament = true;
|
||||
}
|
||||
}
|
||||
|
||||
void ObjColorPanel::deal_algo(char cluster_number, bool redraw_ui)
|
||||
{
|
||||
if (m_last_cluster_number == cluster_number) {
|
||||
return;
|
||||
}
|
||||
wxBusyCursor cursor;
|
||||
m_last_cluster_number = cluster_number;
|
||||
obj_color_deal_algo(m_input_colors, m_cluster_colors_from_algo, m_cluster_labels_from_algo, cluster_number,g_max_color);
|
||||
|
||||
m_cluster_colours.clear();
|
||||
m_cluster_colours.reserve(m_cluster_colors_from_algo.size());
|
||||
for (size_t i = 0; i < m_cluster_colors_from_algo.size(); i++) {
|
||||
m_cluster_colours.emplace_back(convert_to_wxColour(m_cluster_colors_from_algo[i]));
|
||||
}
|
||||
if (m_cluster_colours.size() == 0) {
|
||||
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ",m_cluster_colours.size() = 0\n";
|
||||
return;
|
||||
}
|
||||
m_cluster_map_filaments.resize(m_cluster_colors_from_algo.size());
|
||||
m_new_add_colors.resize(m_cluster_map_filaments.size());
|
||||
m_color_cluster_num_by_algo = m_cluster_colors_from_algo.size();
|
||||
if (cluster_number == -1) {
|
||||
m_color_num_recommend = m_color_cluster_num_by_algo;
|
||||
}
|
||||
//redraw ui
|
||||
if (redraw_ui) {
|
||||
deal_reset_btn();
|
||||
draw_new_table();
|
||||
deal_default_strategy();
|
||||
deal_thumbnail();
|
||||
}
|
||||
}
|
||||
|
||||
void ObjColorPanel::deal_default_strategy()
|
||||
{
|
||||
bool is_exceed = deal_add_btn();
|
||||
if (!is_exceed) {
|
||||
deal_approximate_match_btn();
|
||||
}
|
||||
m_warning_text->SetLabelText(_L("Note") + ": " + _L("The color has been selected, you can choose OK \n to continue or manually adjust it."));
|
||||
}
|
||||
|
||||
void ObjColorPanel::deal_thumbnail() {
|
||||
update_filament_ids();
|
||||
// generate model volume
|
||||
if (m_obj_in_out.deal_vertex_color) {
|
||||
if (m_obj_in_out.filament_ids.size() > 0) {
|
||||
m_deal_thumbnail_flag = Model::obj_import_vertex_color_deal(m_obj_in_out.filament_ids, m_obj_in_out.first_extruder_id, m_obj_in_out.model);
|
||||
}
|
||||
} else {
|
||||
if (m_obj_in_out.filament_ids.size() > 0) {
|
||||
m_deal_thumbnail_flag = Model::obj_import_face_color_deal(m_obj_in_out.filament_ids, m_obj_in_out.first_extruder_id, m_obj_in_out.model);
|
||||
}
|
||||
}
|
||||
generate_thumbnail();
|
||||
}
|
||||
|
||||
void ObjColorPanel::generate_thumbnail()
|
||||
{
|
||||
if (m_deal_thumbnail_flag && m_obj_in_out.model->objects.size() == 1) {
|
||||
std::vector<Slic3r::ColorRGBA> colors = GUI::wxGetApp().plater()->get_extruders_colors();
|
||||
for (size_t i = 0; i < m_new_add_colors.size(); i++) {
|
||||
Slic3r::ColorRGBA temp_color;
|
||||
temp_color[0] = m_new_add_colors[i].Red() / 255.f;
|
||||
temp_color[1] = m_new_add_colors[i].Green() / 255.f;
|
||||
temp_color[2] = m_new_add_colors[i].Blue() / 255.f;
|
||||
temp_color[3] = m_new_add_colors[i].Alpha() / 255.f;
|
||||
colors.emplace_back(temp_color);
|
||||
}
|
||||
|
||||
auto mo = m_obj_in_out.model->objects[0];
|
||||
wxGetApp().plater()->update_obj_preview_thumbnail(mo, 0, 0, colors, (int) m_camera_view_angle_type);
|
||||
// get thumbnail image
|
||||
PartPlate *plate = wxGetApp().plater()->get_partplate_list().get_plate(0);
|
||||
auto & data = plate->obj_preview_thumbnail_data;
|
||||
if (data.is_valid()) {
|
||||
wxImage image(data.width, data.height);
|
||||
image.InitAlpha();
|
||||
for (unsigned int r = 0; r < data.height; ++r) {
|
||||
unsigned int rr = (data.height - 1 - r) * data.width;
|
||||
for (unsigned int c = 0; c < data.width; ++c) {
|
||||
unsigned char *px = (unsigned char *) data.pixels.data() + 4 * (rr + c);
|
||||
image.SetRGB((int) c, (int) r, px[0], px[1], px[2]);
|
||||
image.SetAlpha((int) c, (int) r, px[3]);
|
||||
}
|
||||
}
|
||||
image = image.Rescale(FromDIP(IMAGE_SIZE_WIDTH), FromDIP(IMAGE_SIZE_WIDTH));
|
||||
m_image_button->SetBitmap(image);
|
||||
}
|
||||
|
||||
}
|
||||
else {
|
||||
#ifdef _WIN32
|
||||
__debugbreak();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void ObjColorPanel::set_view_angle_type(int value)
|
||||
{
|
||||
if (value >= 0) {
|
||||
m_camera_view_angle_type = (Slic3r::GUI::Camera::ViewAngleType) value;
|
||||
generate_thumbnail();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void ObjColorPanel::clear_instance_and_revert_offset()
|
||||
{
|
||||
auto mo = m_obj_in_out.model->objects[0];
|
||||
mo->clear_instances();
|
||||
auto mv = mo->volumes[0];
|
||||
auto box = mo->bounding_box_exact();
|
||||
if (!m_thumbnail_offset.isApprox(Slic3r::Vec3d::Zero())) {
|
||||
mv->translate(-m_thumbnail_offset);
|
||||
}
|
||||
}
|
||||
|
||||
bool ObjColorPanel::do_show(bool show) {
|
||||
if (show) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool ObjColorPanel::deal_add_btn()
|
||||
{
|
||||
if (!m_semm) { return false; }// only SEMM printer can add more colors
|
||||
if (m_colours.size() > g_max_color) { return false; }
|
||||
deal_reset_btn();
|
||||
std::vector<wxBitmap *> new_icons;
|
||||
auto new_color_size = m_cluster_colors_from_algo.size();
|
||||
new_icons.reserve(new_color_size);
|
||||
m_new_add_colors.clear();
|
||||
m_new_add_colors.reserve(new_color_size);
|
||||
int new_index = m_colours.size() + 1;
|
||||
bool is_exceed = false;
|
||||
for (size_t i = 0; i < new_color_size; i++) {
|
||||
if (m_colours.size() + new_icons.size() >= g_max_color) {
|
||||
is_exceed = true;
|
||||
break;
|
||||
}
|
||||
wxColour cur_color = convert_to_wxColour(m_cluster_colors_from_algo[i]);
|
||||
m_new_add_colors.emplace_back(cur_color);
|
||||
new_icons.emplace_back(get_extruder_color_icon(cur_color.GetAsString(wxC2S_HTML_SYNTAX).ToStdString(),
|
||||
std::to_string(new_index), m_combox_icon_width, m_combox_icon_height));
|
||||
new_index++;
|
||||
}
|
||||
new_index = m_colours.size() + 1;
|
||||
for (size_t i = 0; i < m_result_icon_list.size(); i++) {
|
||||
auto item = m_result_icon_list[i];
|
||||
for (size_t k = 0; k < new_icons.size(); k++) {
|
||||
item->bitmap_combox->Append(wxString::Format("%d", item->bitmap_combox->GetCount()), *new_icons[k]);
|
||||
item->bitmap_combox->SetItemTooltip(item->bitmap_combox->GetCount() -1,m_new_add_colors[k].GetAsString(wxC2S_HTML_SYNTAX));
|
||||
}
|
||||
item->bitmap_combox->SetSelection(new_index);
|
||||
m_cluster_map_filaments[i] = new_index;
|
||||
new_index++;
|
||||
}
|
||||
if (is_exceed) {
|
||||
deal_approximate_match_btn();
|
||||
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ",Waring:The count of newly added and \n current extruders exceeds 32.";
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void ObjColorPanel::deal_reset_btn()
|
||||
{
|
||||
for (auto item : m_result_icon_list) {
|
||||
// delete redundant bitmap
|
||||
while (item->bitmap_combox->GetCount() > m_colours.size()+ 1) {
|
||||
item->bitmap_combox->DeleteOneItem(item->bitmap_combox->GetCount() - 1);
|
||||
}
|
||||
item->bitmap_combox->SetSelection(0);
|
||||
}
|
||||
for (int i = 0; i < m_new_add_colors.size(); i++) {
|
||||
m_new_add_colors[i] = g_undefined_color_in_obj;
|
||||
}
|
||||
m_warning_text->SetLabelText("");
|
||||
}
|
||||
|
||||
wxBoxSizer *ObjColorPanel::create_color_icon_map_rgba_sizer(wxWindow *parent, int id, const wxColour &color)
|
||||
{
|
||||
auto icon_sizer = new wxBoxSizer(wxHORIZONTAL);
|
||||
//icon_sizer->AddSpacer(FromDIP(40));
|
||||
wxButton *icon = new wxButton(parent, wxID_ANY, {}, wxDefaultPosition, FromDIP(wxSize(20,20)), wxBORDER_NONE | wxBU_AUTODRAW);
|
||||
icon->SetBitmap(*get_extruder_color_icon(color.GetAsString(wxC2S_HTML_SYNTAX).ToStdString(), "", FromDIP(20), FromDIP(20)));
|
||||
icon->SetCanFocus(false);
|
||||
#ifdef __WXGTK__
|
||||
RemoveButtonBorder(icon);
|
||||
#endif
|
||||
m_color_cluster_icon_list.emplace_back(icon);
|
||||
icon_sizer->Add(icon, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL, 0); // wxALIGN_CENTER_VERTICAL | wxTOP | wxBOTTOM
|
||||
icon_sizer->AddSpacer(FromDIP(10));
|
||||
|
||||
wxStaticText *map_text = new wxStaticText(parent, wxID_ANY, _L(u8"—> "));
|
||||
map_text->SetFont(Label::Head_12);
|
||||
icon_sizer->Add(map_text, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL, 0);
|
||||
|
||||
for (size_t i = m_result_icon_list.size(); i < id + 1; i++) {
|
||||
m_result_icon_list.emplace_back(new ButtonState());
|
||||
}
|
||||
m_result_icon_list[id]->bitmap_combox = CreateEditorCtrl(parent, id);
|
||||
icon_sizer->Add(m_result_icon_list[id]->bitmap_combox, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL, 0);
|
||||
return icon_sizer;
|
||||
}
|
||||
@@ -1,136 +0,0 @@
|
||||
#ifndef _OBJ_COLOR_DIALOG_H_
|
||||
#define _OBJ_COLOR_DIALOG_H_
|
||||
|
||||
#include "GUI_Utils.hpp"
|
||||
#include "Camera.hpp"
|
||||
#include "GuiColor.hpp"
|
||||
#include "libslic3r/Format/OBJ.hpp"
|
||||
#include <wx/panel.h>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <functional>
|
||||
#include <wx/colour.h>
|
||||
#include <wx/scrolwin.h>
|
||||
#include "libslic3r/Color.hpp"
|
||||
#include "libslic3r/Point.hpp"
|
||||
#include <unordered_map>
|
||||
#include <wx/sizer.h>
|
||||
#include <wx/spinctrl.h>
|
||||
#include <wx/stattext.h>
|
||||
#include <wx/textctrl.h>
|
||||
#include <wx/checkbox.h>
|
||||
#include <wx/msgdlg.h>
|
||||
#include "Widgets/SpinInput.hpp"
|
||||
class Button;
|
||||
class Label;
|
||||
class ComboBox;
|
||||
|
||||
class ObjColorPanel : public wxPanel
|
||||
{
|
||||
public:
|
||||
// BBS
|
||||
ObjColorPanel(wxWindow *parent, Slic3r::ObjDialogInOut &in_out, const std::vector<std::string> &extruder_colours, bool semm);
|
||||
~ObjColorPanel();
|
||||
void msw_rescale();
|
||||
bool is_ok();
|
||||
void send_new_filament_to_ui();
|
||||
void cancel_paint_color();
|
||||
void update_filament_ids();
|
||||
struct ButtonState
|
||||
{
|
||||
ComboBox* bitmap_combox{nullptr};
|
||||
bool is_map{false};//int id{0};
|
||||
};
|
||||
typedef std::function<void()> LayoutChanggeCallback;
|
||||
void set_layout_callback(LayoutChanggeCallback);
|
||||
void do_layout_callback();
|
||||
bool do_show(bool show);
|
||||
void clear_instance_and_revert_offset();
|
||||
|
||||
private:
|
||||
wxBoxSizer *create_approximate_match_btn_sizer(wxWindow *parent);
|
||||
wxBoxSizer *create_add_btn_sizer(wxWindow *parent);
|
||||
wxBoxSizer *create_reset_btn_sizer(wxWindow *parent);
|
||||
wxBoxSizer *create_extruder_icon_and_rgba_sizer(wxWindow *parent, int id, const wxColour& color);
|
||||
std::string get_color_str(const wxColour &color);
|
||||
wxBoxSizer *create_color_icon_map_rgba_sizer(wxWindow *parent, int id, const wxColour &color);//for display map
|
||||
ComboBox* CreateEditorCtrl(wxWindow *parent,int id);
|
||||
void draw_new_table();
|
||||
void update_new_add_final_colors();
|
||||
void show_sizer(wxSizer *sizer, bool show);
|
||||
void deal_approximate_match_btn();
|
||||
bool deal_add_btn();
|
||||
void deal_reset_btn();
|
||||
void deal_algo(char cluster_number,bool redraw_ui =false);
|
||||
void deal_default_strategy();
|
||||
void deal_thumbnail();
|
||||
void generate_thumbnail();
|
||||
void set_view_angle_type(int);
|
||||
private:
|
||||
//view ui
|
||||
Slic3r::ObjDialogInOut & m_obj_in_out;
|
||||
Slic3r::GUI::Camera::ViewAngleType m_camera_view_angle_type{Slic3r::GUI::Camera::ViewAngleType::Iso};
|
||||
wxPanel * m_page_simple = nullptr;
|
||||
wxBoxSizer * m_sizer = nullptr;
|
||||
wxBoxSizer * m_sizer_simple = nullptr;
|
||||
wxBoxSizer * m_sizer_current_filaments = nullptr;
|
||||
SpinInput * m_color_cluster_num_by_user_ebox{nullptr};
|
||||
wxStaticText * m_warning_text{nullptr};
|
||||
wxGridSizer * m_new_grid_sizer{nullptr};
|
||||
wxScrolledWindow * m_scrolledWindow{nullptr};
|
||||
Button * m_quick_approximate_match_btn{nullptr};
|
||||
Button * m_quick_add_btn{nullptr};
|
||||
Button * m_quick_reset_btn{nullptr};
|
||||
std::vector<wxButton*> m_extruder_icon_list;
|
||||
std::vector<wxButton*> m_color_cluster_icon_list;//need modeify
|
||||
std::vector<wxStaticText*> m_color_cluster_text_list;//need modeify
|
||||
std::vector<wxGridSizer*> m_row_sizer_list; // control show or not
|
||||
std::vector<wxBoxSizer *> m_row_col_boxsizer_list;
|
||||
std::vector<ButtonState*> m_result_icon_list;
|
||||
int m_last_cluster_num{-1};
|
||||
int m_combox_icon_width;
|
||||
int m_combox_icon_height;
|
||||
wxButton * m_image_button = nullptr;
|
||||
LayoutChanggeCallback m_layout_callback;
|
||||
//data
|
||||
char m_last_cluster_number{-2};
|
||||
std::vector<Slic3r::RGBA>& m_input_colors;
|
||||
int m_color_num_recommend{0};
|
||||
int m_color_cluster_num_by_algo{0};
|
||||
int m_input_colors_size{0};
|
||||
bool m_semm; // only SEMM printer can add more colors
|
||||
std::vector<wxColour> m_colours;//from project and show right
|
||||
std::vector<int> m_cluster_map_filaments;//show middle
|
||||
int m_max_filament_index = 0;
|
||||
std::vector<wxColour> m_cluster_colours;//from_algo and show left
|
||||
bool m_deal_thumbnail_flag{false};
|
||||
std::vector<wxColour> m_new_add_colors;
|
||||
std::vector<wxColour> m_new_add_final_colors;
|
||||
//algo result
|
||||
std::vector<Slic3r::RGBA> m_cluster_colors_from_algo;
|
||||
std::vector<int> m_cluster_labels_from_algo;
|
||||
//result
|
||||
bool m_is_add_filament{false};
|
||||
unsigned char& m_first_extruder_id;
|
||||
std::vector<unsigned char> &m_filament_ids;
|
||||
|
||||
Slic3r::Vec3d m_thumbnail_offset;
|
||||
};
|
||||
|
||||
class ObjColorDialog : public Slic3r::GUI::DPIDialog
|
||||
{
|
||||
public:
|
||||
ObjColorDialog(wxWindow *parent, Slic3r::ObjDialogInOut &in_out, const std::vector<std::string> &extruder_colours, bool semm);
|
||||
wxBoxSizer *create_btn_sizer(long flags, bool exist_error);
|
||||
void on_dpi_changed(const wxRect &suggested_rect) override;
|
||||
void update_layout();
|
||||
bool Show(bool show) override;
|
||||
|
||||
private:
|
||||
ObjColorPanel* m_panel_ObjColor = nullptr;
|
||||
wxBoxSizer * m_main_sizer = nullptr;
|
||||
wxBoxSizer * m_buttons_sizer = nullptr;
|
||||
std::unordered_map<int, Button *> m_button_list;
|
||||
};
|
||||
|
||||
#endif // _WIPE_TOWER_DIALOG_H_
|
||||
@@ -8,6 +8,7 @@
|
||||
|
||||
#include "libslic3r/Utils.hpp"
|
||||
#include "slic3r/GUI/GUI_Utils.hpp"
|
||||
#include "libslic3r/Preset.hpp"
|
||||
#include <wx/wx.h>
|
||||
#include <wx/gdicmn.h>
|
||||
#include <wx/toplevel.h>
|
||||
|
||||
@@ -62,6 +62,8 @@
|
||||
|
||||
#include "DeviceCore/DevManager.h"
|
||||
|
||||
namespace fs = boost::filesystem;
|
||||
|
||||
namespace Slic3r { namespace GUI {
|
||||
|
||||
extern wxString hide_passwd(wxString url, std::vector<wxString> const &passwords);
|
||||
|
||||
@@ -273,7 +273,6 @@
|
||||
#include "ColorDecomposeSupport.hpp"
|
||||
#include "FilamentBitmapUtils.hpp"
|
||||
#include "libslic3r/FilamentMixer.hpp"
|
||||
#include "ObjColorDialog.hpp"
|
||||
|
||||
#include "libslic3r/CustomGCode.hpp"
|
||||
#include "libslic3r/Platform.hpp"
|
||||
@@ -9775,16 +9774,6 @@ std::vector<size_t> Plater::priv::load_files(const std::vector<fs::path>& input_
|
||||
bool is_xxx;
|
||||
Semver file_version;
|
||||
|
||||
//ObjImportColorFn obj_color_fun=nullptr;
|
||||
auto obj_color_fun = [&path](ObjDialogInOut &in_out) {
|
||||
|
||||
if (!boost::iends_with(path.string(), ".obj")) { return; }
|
||||
const std::vector<std::string> extruder_colours = wxGetApp().plater()->get_extruder_colors_from_plater_config();
|
||||
ObjColorDialog color_dlg(nullptr, in_out, extruder_colours, Sidebar::should_show_SEMM_buttons());
|
||||
if (color_dlg.ShowModal() != wxID_OK) {
|
||||
in_out.filament_ids.clear();
|
||||
}
|
||||
};
|
||||
if (boost::iends_with(path.string(), ".stp") ||
|
||||
boost::iends_with(path.string(), ".step")) {
|
||||
double linear = string_to_double_decimal_point(wxGetApp().app_config->get("linear_deflection"));
|
||||
@@ -9851,7 +9840,7 @@ std::vector<size_t> Plater::priv::load_files(const std::vector<fs::path>& input_
|
||||
cont = dlg.Update(progress_percent, msg);
|
||||
cancel = !cont;
|
||||
},
|
||||
nullptr, 0, obj_color_fun);
|
||||
nullptr, 0);
|
||||
}
|
||||
|
||||
if (designer_model_id.empty() && boost::algorithm::iends_with(path.string(), ".stl")) {
|
||||
@@ -12143,14 +12132,6 @@ void Plater::priv::reload_from_disk()
|
||||
// load one file at a time
|
||||
for (size_t i = 0; i < input_paths.size(); ++i) {
|
||||
const auto& path = input_paths[i].string();
|
||||
auto obj_color_fun = [&path](ObjDialogInOut &in_out) {
|
||||
if (!boost::iends_with(path, ".obj")) { return; }
|
||||
const std::vector<std::string> extruder_colours = wxGetApp().plater()->get_extruder_colors_from_plater_config();
|
||||
ObjColorDialog color_dlg(nullptr, in_out, extruder_colours, Sidebar::should_show_SEMM_buttons());
|
||||
if (color_dlg.ShowModal() != wxID_OK) {
|
||||
in_out.filament_ids.clear();
|
||||
}
|
||||
};
|
||||
wxBusyCursor wait;
|
||||
wxBusyInfo info(_L("Reload from:") + " " + from_u8(path), q->get_current_canvas3D()->get_wxglcanvas());
|
||||
|
||||
@@ -12170,7 +12151,7 @@ void Plater::priv::reload_from_disk()
|
||||
bool is_split = wxGetApp().app_config->get_bool("is_split_compound");
|
||||
new_model = Model::read_from_step(path, LoadStrategy::AddDefaultInstances | LoadStrategy::LoadModel, nullptr, nullptr, nullptr, linear, angle, is_split);
|
||||
}else {
|
||||
new_model = Model::read_from_file(path, nullptr, nullptr, LoadStrategy::AddDefaultInstances | LoadStrategy::LoadModel, &plate_data, &project_presets, nullptr, nullptr, nullptr, nullptr, nullptr, 0, obj_color_fun);
|
||||
new_model = Model::read_from_file(path, nullptr, nullptr, LoadStrategy::AddDefaultInstances | LoadStrategy::LoadModel, &plate_data, &project_presets, nullptr, nullptr, nullptr, nullptr, nullptr, 0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -376,8 +376,8 @@ public:
|
||||
// BBS: check snapshot
|
||||
bool up_to_date(bool saved, bool backup);
|
||||
|
||||
bool open_3mf_file(const fs::path &file_path);
|
||||
int get_3mf_file_count(std::vector<fs::path> paths);
|
||||
bool open_3mf_file(const boost::filesystem::path &file_path);
|
||||
int get_3mf_file_count(std::vector<boost::filesystem::path> paths);
|
||||
void add_file();
|
||||
// Returns false when no object was added (e.g. the user cancelled the load dialog).
|
||||
bool add_model(bool imperial_units = false, std::string fname = "");
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include "libslic3r_version.h"
|
||||
|
||||
#include <boost/filesystem/path.hpp>
|
||||
#include <utility>
|
||||
#include <wx/panel.h>
|
||||
#include <wx/gdicmn.h>
|
||||
#include <memory>
|
||||
|
||||
@@ -21,6 +21,9 @@
|
||||
#include <wx/log.h>
|
||||
#include <wx/webview.h>
|
||||
#include <wx/utils.h>
|
||||
#include <boost/filesystem.hpp>
|
||||
|
||||
namespace fs = boost::filesystem;
|
||||
|
||||
|
||||
namespace Slic3r { namespace GUI {
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#include <boost/algorithm/string/case_conv.hpp>
|
||||
#include <boost/log/trivial.hpp>
|
||||
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include "slic3r/GUI/GUI.hpp"
|
||||
@@ -57,6 +58,8 @@
|
||||
#include "MainFrame.hpp"
|
||||
#include <slic3r/GUI/Widgets/WebView.hpp>
|
||||
|
||||
namespace fs = boost::filesystem;
|
||||
|
||||
namespace Slic3r { namespace GUI {
|
||||
|
||||
wxDEFINE_EVENT(EVT_PROJECT_RELOAD, wxCommandEvent);
|
||||
|
||||
@@ -70,6 +70,9 @@
|
||||
#include "DeviceCore/DevStorage.h"
|
||||
#include "../Utils/Http.hpp"
|
||||
#include "md4c/src/md4c-html.h"
|
||||
#include <boost/filesystem.hpp>
|
||||
|
||||
namespace fs = boost::filesystem;
|
||||
|
||||
namespace Slic3r { namespace GUI {
|
||||
|
||||
|
||||
@@ -21,12 +21,30 @@
|
||||
|
||||
#include "libslic3r/AppConfig.hpp"
|
||||
#include "libslic3r/libslic3r.h"
|
||||
#include "libslic3r_version.h"
|
||||
|
||||
#include <array>
|
||||
#include <glad/gl.h>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include "slic3r/GUI/FrameProfiler.hpp"
|
||||
#include "slic3r/GUI/GUI_Utils.hpp"
|
||||
#include "libslic3r/Point.hpp"
|
||||
#include "libslic3r/BoundingBox.hpp"
|
||||
#include <ratio>
|
||||
#include "libslic3r/Preset.hpp"
|
||||
#include <ios>
|
||||
#include <wx/clipbrd.h>
|
||||
#include <wx/gdicmn.h>
|
||||
#include <wx/colour.h>
|
||||
#include <wx/event.h>
|
||||
#include <wx/dcclient.h>
|
||||
#include <wx/dataobj.h>
|
||||
#include <wx/glcanvas.h>
|
||||
#include <wx/string.h>
|
||||
#include <wx/textctrl.h>
|
||||
#include <wx/timer.h>
|
||||
#include <wx/toplevel.h>
|
||||
#include <wx/utils.h>
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
@@ -120,6 +120,9 @@
|
||||
#include "Notebook.hpp"
|
||||
#include "BitmapCache.hpp"
|
||||
#include "BindDialog.hpp"
|
||||
#include <boost/filesystem.hpp>
|
||||
|
||||
namespace fs = boost::filesystem;
|
||||
|
||||
namespace Slic3r { namespace GUI {
|
||||
|
||||
|
||||
@@ -61,6 +61,9 @@
|
||||
|
||||
#include "DeviceCore/DevManager.h"
|
||||
#include "DeviceCore/DevStorage.h"
|
||||
#include <boost/filesystem.hpp>
|
||||
|
||||
namespace fs = boost::filesystem;
|
||||
|
||||
namespace Slic3r {
|
||||
namespace GUI {
|
||||
|
||||
@@ -77,6 +77,9 @@
|
||||
#include "DeviceCore/DevStorage.h"
|
||||
#include "libslic3r_version.h"
|
||||
#include "slic3r/Utils/FileTransferUtils.hpp"
|
||||
#include <boost/filesystem.hpp>
|
||||
|
||||
namespace fs = boost::filesystem;
|
||||
|
||||
|
||||
namespace Slic3r {
|
||||
|
||||
@@ -239,12 +239,15 @@ void NotificationManager::SlicingProgressNotification::render(GLCanvas3D& canvas
|
||||
const float gcodeviewer_height = wxGetApp().plater()->get_preview_canvas3D()->get_gcode_viewer().get_legend_height();
|
||||
//const float dailytips_panel_height = std::min(380.0f * scale, std::max(90.0f, (cnv_size.get_height() - gcodeviewer_height - progress_panel_height - dailytips_child_window_padding.y - initial_y - m_line_height * 4)));
|
||||
const float dailytips_panel_height = 125.0f * scale;
|
||||
const ImVec2 dailytips_size = ImVec2(dailytips_panel_width, dailytips_panel_height);
|
||||
//Orca: Update the child's effective height before positioning this parent window.
|
||||
m_dailytips_panel->set_size(dailytips_size);
|
||||
|
||||
float right_gap = right_margin + (move_from_overlay ? overlay_width + m_line_height * 5 : 0);
|
||||
m_window_pos = ImVec2((float)cnv_size.get_width() - right_gap - m_window_width, (float)cnv_size.get_height() - m_top_y);
|
||||
imgui.set_next_window_pos(m_window_pos.x, m_window_pos.y, ImGuiCond_Always, 0.0f, 0.0f);
|
||||
m_window_height = progress_panel_height + m_dailytips_panel->get_size().y + progress_child_window_padding.y + dailytips_child_window_padding.y + bottom_padding.y;
|
||||
m_top_y = initial_y + m_window_height;
|
||||
m_window_pos = ImVec2((float)cnv_size.get_width() - right_gap - m_window_width, (float)cnv_size.get_height() - m_top_y);
|
||||
imgui.set_next_window_pos(m_window_pos.x, m_window_pos.y, ImGuiCond_Always, 0.0f, 0.0f);
|
||||
ImGui::SetNextWindowSizeConstraints(ImVec2(m_window_width, m_window_height), ImVec2(m_window_width, m_window_height));
|
||||
|
||||
// name of window indentifies window - has to be unique string
|
||||
@@ -307,9 +310,7 @@ void NotificationManager::SlicingProgressNotification::render(GLCanvas3D& canvas
|
||||
|
||||
child_name = "##DailyTipsPanel" + std::to_string(parent_window->ID);
|
||||
ImVec2 dailytips_pos = ImGui::GetCursorScreenPos() + dailytips_child_window_padding;
|
||||
ImVec2 dailytips_size = ImVec2(dailytips_panel_width, dailytips_panel_height);
|
||||
m_dailytips_panel->set_position(dailytips_pos);
|
||||
m_dailytips_panel->set_size(dailytips_size);
|
||||
m_dailytips_panel->set_fade_opacity(m_current_fade_opacity);
|
||||
ImGui::SetNextWindowPos(dailytips_pos);
|
||||
if (ImGui::BeginChild(child_name.c_str(), ImVec2(dailytips_panel_width, dailytips_panel_height), false, child_window_flags)) {
|
||||
@@ -504,4 +505,4 @@ void NotificationManager::SlicingProgressNotification::render_progress_close_but
|
||||
}
|
||||
}
|
||||
|
||||
}}
|
||||
}}
|
||||
|
||||
@@ -78,6 +78,8 @@
|
||||
#include "DeviceCore/DevStorage.h"
|
||||
#include "FilamentBitmapUtils.hpp"
|
||||
|
||||
namespace fs = boost::filesystem;
|
||||
|
||||
using namespace Slic3r;
|
||||
using namespace Slic3r::GUI;
|
||||
|
||||
|
||||
@@ -79,6 +79,8 @@
|
||||
#include <libslic3r/Utils.hpp>
|
||||
#include "CreatePresetsDialog.hpp"
|
||||
|
||||
namespace fs = boost::filesystem;
|
||||
|
||||
using namespace nlohmann;
|
||||
|
||||
namespace Slic3r { namespace GUI {
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
#include <boost/property_tree/ptree.hpp>
|
||||
#include <boost/property_tree/json_parser.hpp>
|
||||
|
||||
#include <utility>
|
||||
#include <wx/event.h>
|
||||
#include <wx/panel.h>
|
||||
#include <wx/gdicmn.h>
|
||||
|
||||
@@ -52,6 +52,9 @@
|
||||
#include <wx/webview.h>
|
||||
#include <wx/string.h>
|
||||
#include <wx/timer.h>
|
||||
#include <boost/filesystem.hpp>
|
||||
|
||||
namespace fs = boost::filesystem;
|
||||
|
||||
namespace Slic3r { namespace GUI {
|
||||
|
||||
|
||||
@@ -34,6 +34,9 @@
|
||||
#include <wx/uri.h>
|
||||
#include <wx/filename.h>
|
||||
#include <wx/stdpaths.h>
|
||||
#include <boost/filesystem.hpp>
|
||||
|
||||
namespace fs = boost::filesystem;
|
||||
#if defined(__WIN32__) || defined(__WXMAC__)
|
||||
#include "wx/private/jsscriptwrapper.h"
|
||||
#endif
|
||||
|
||||
@@ -40,6 +40,9 @@
|
||||
#include "libslic3r/Config.hpp"
|
||||
#include "Widgets/Label.hpp"
|
||||
#include "MainFrame.hpp"
|
||||
#include <boost/filesystem.hpp>
|
||||
|
||||
namespace fs = boost::filesystem;
|
||||
|
||||
using namespace Slic3r;
|
||||
using namespace Slic3r::GUI;
|
||||
|
||||
@@ -58,6 +58,9 @@
|
||||
#include "slic3r/GUI/OpenGLManager.hpp"
|
||||
#include <utility>
|
||||
#include "slic3r/GUI/Jobs/PrintJob.hpp"
|
||||
#include <boost/filesystem.hpp>
|
||||
|
||||
namespace fs = boost::filesystem;
|
||||
|
||||
namespace Slic3r {
|
||||
namespace GUI {
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
#include "slic3r/GUI/WebPanel.hpp"
|
||||
#include <optional>
|
||||
#include "slic3r/plugin/PythonPluginInterface.hpp"
|
||||
#include "slic3r/GUI/LazyPage.hpp"
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
#include <wx/app.h>
|
||||
|
||||
@@ -25,6 +25,10 @@
|
||||
#include "libslic3r/PrintConfig.hpp"
|
||||
#include "libslic3r/Print.hpp"
|
||||
#include "libslic3r/Model.hpp"
|
||||
#include "libslic3r/Config.hpp"
|
||||
#include "libslic3r/Layer.hpp"
|
||||
#include "libslic3r/ExtrusionEntityCollection.hpp"
|
||||
#include "libslic3r/ExtrusionEntity.hpp"
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <vector>
|
||||
@@ -562,6 +566,12 @@ struct SlicedCage
|
||||
|
||||
using Walls = std::vector<std::vector<ProcessedPoint>>;
|
||||
|
||||
bool has_curled_lines(const PrintObject &object)
|
||||
{
|
||||
const auto layers = object.layers();
|
||||
return std::any_of(layers.begin(), layers.end(), [](const Layer *layer) { return !layer->curled_lines.empty(); });
|
||||
}
|
||||
|
||||
// Estimates every wall of `layer` against whatever layer `estimator` was last prepared with before it.
|
||||
Walls estimate_walls(ExtrusionQualityEstimator &estimator, const PrintObject *object, const Layer &layer)
|
||||
{
|
||||
@@ -703,6 +713,53 @@ TEST_CASE("Precomputed overhang data has the curled-line tree exactly when a reg
|
||||
CHECK((precomputed.front().lower_curled_lines != nullptr) == slowdown);
|
||||
}
|
||||
|
||||
TEST_CASE("Curled walls are estimated only when overhang speed and the slowdown for curled perimeters are both on", "[ExtrusionProcessor]")
|
||||
{
|
||||
const auto [overhang_speed, slowdown, estimated] = GENERATE(table<bool, bool, bool>({
|
||||
{true, true, true},
|
||||
{true, false, false},
|
||||
{false, true, false},
|
||||
}));
|
||||
DynamicPrintConfig config = caged_overhang_config("classic");
|
||||
config.set_deserialize_strict({{"enable_overhang_speed", overhang_speed ? "1" : "0"},
|
||||
{"slowdown_for_curled_perimeters", slowdown ? "1" : "0"}});
|
||||
const SlicedCage cage(config);
|
||||
|
||||
CHECK(has_curled_lines(*cage.object) == estimated);
|
||||
}
|
||||
|
||||
TEST_CASE("Curled walls are estimated when overhang speed and the slowdown for curled perimeters are on in different objects", "[ExtrusionProcessor]")
|
||||
{
|
||||
const std::vector<std::vector<ConfigBase::SetDeserializeItem>> overrides{
|
||||
{{"enable_overhang_speed", "1"}, {"slowdown_for_curled_perimeters", "0"}},
|
||||
{{"enable_overhang_speed", "0"}, {"slowdown_for_curled_perimeters", "1"}},
|
||||
};
|
||||
Print print;
|
||||
Model model;
|
||||
init_print(std::vector<TriangleMesh>{caged_overhang_mesh(), caged_overhang_mesh()}, print, model, caged_overhang_config("classic"),
|
||||
&overrides);
|
||||
print.process();
|
||||
|
||||
REQUIRE(print.objects().size() == 2);
|
||||
for (const PrintObject *object : print.objects())
|
||||
CHECK(has_curled_lines(*object));
|
||||
}
|
||||
|
||||
TEST_CASE("Curled walls from an earlier slice are dropped once overhang speed is off", "[ExtrusionProcessor]")
|
||||
{
|
||||
DynamicPrintConfig config = caged_overhang_config("classic");
|
||||
config.set_deserialize_strict("slowdown_for_curled_perimeters", "1");
|
||||
SlicedCage cage(config);
|
||||
const Layer *first_layer = cage.print.objects().front()->layers().front();
|
||||
REQUIRE(has_curled_lines(*cage.print.objects().front()));
|
||||
|
||||
config.set_deserialize_strict("enable_overhang_speed", "0");
|
||||
cage.print.apply(cage.model, config);
|
||||
cage.print.process();
|
||||
REQUIRE(cage.print.objects().front()->layers().front() == first_layer);
|
||||
CHECK_FALSE(has_curled_lines(*cage.print.objects().front()));
|
||||
}
|
||||
|
||||
TEST_CASE("Caged external overhangs are slowed when printed by object or through the pressure equalizer", "[ExtrusionProcessor]")
|
||||
{
|
||||
const auto [key, value] = GENERATE(table<const char *, const char *>({
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#include <catch2/catch_test_macros.hpp>
|
||||
#include <catch2/generators/catch_generators.hpp>
|
||||
|
||||
#include <catch2/catch_message.hpp>
|
||||
#include "libslic3r/BoundingBox.hpp"
|
||||
#include "libslic3r/Model.hpp"
|
||||
#include "libslic3r/ModelArrange.hpp"
|
||||
@@ -9,6 +10,8 @@
|
||||
|
||||
#include "test_helpers.hpp"
|
||||
|
||||
#include "libslic3r/TriangleMesh.hpp"
|
||||
#include "libslic3r/Point.hpp"
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
|
||||
@@ -2,15 +2,21 @@
|
||||
|
||||
#include <catch2/catch_test_macros.hpp>
|
||||
#include <catch2/generators/catch_generators.hpp>
|
||||
#include <catch2/matchers/catch_matchers.hpp>
|
||||
#include <catch2/matchers/catch_matchers_floating_point.hpp>
|
||||
#include "libslic3r/libslic3r.h"
|
||||
#include "libslic3r/GCode/GCodeProcessor.hpp"
|
||||
#include "libslic3r/Utils.hpp"
|
||||
|
||||
#include "test_utils.hpp"
|
||||
|
||||
#include <cstddef>
|
||||
#include <fstream>
|
||||
#include "libslic3r/PrintConfig.hpp"
|
||||
#include "libslic3r/Point.hpp"
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
using namespace Slic3r;
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#include <catch2/catch_all.hpp>
|
||||
|
||||
#include <catch2/catch_test_macros.hpp>
|
||||
#include <catch2/generators/catch_generators.hpp>
|
||||
#include "libslic3r/AppConfig.hpp"
|
||||
|
||||
using namespace Slic3r;
|
||||
|
||||
@@ -1,10 +1,16 @@
|
||||
#include <catch2/catch_all.hpp>
|
||||
|
||||
#include <catch2/matchers/catch_matchers_floating_point.hpp>
|
||||
#include <catch2/catch_test_macros.hpp>
|
||||
#include <catch2/matchers/catch_matchers.hpp>
|
||||
#include <catch2/generators/catch_generators.hpp>
|
||||
#include <catch2/catch_message.hpp>
|
||||
#include "libslic3r/Format/AssembleList.hpp"
|
||||
|
||||
#include "test_utils.hpp"
|
||||
|
||||
#include <boost/nowide/fstream.hpp>
|
||||
#include <cstddef>
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
#include <string>
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#include <numeric>
|
||||
#include <iostream>
|
||||
#include <boost/filesystem.hpp>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include <catch2/catch_test_macros.hpp>
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
#include <boost/filesystem.hpp>
|
||||
#include <boost/nowide/fstream.hpp>
|
||||
#include "libslic3r/Config.hpp"
|
||||
#include <initializer_list>
|
||||
#include <memory>
|
||||
#include <map>
|
||||
#include <iterator>
|
||||
@@ -29,6 +30,8 @@
|
||||
#include <vector>
|
||||
#include <utility>
|
||||
|
||||
namespace fs = boost::filesystem;
|
||||
|
||||
using namespace Slic3r;
|
||||
|
||||
SCENARIO("Generic config validation performs as expected.", "[Config]") {
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#include <catch2/generators/catch_generators.hpp>
|
||||
#include <catch2/matchers/catch_matchers_floating_point.hpp>
|
||||
|
||||
#include <catch2/matchers/catch_matchers.hpp>
|
||||
#include "libslic3r/Config.hpp"
|
||||
#include "libslic3r/GCodeReader.hpp"
|
||||
#include "libslic3r/PrintConfig.hpp"
|
||||
|
||||
@@ -5,6 +5,9 @@
|
||||
|
||||
#include <catch2/catch_test_macros.hpp>
|
||||
#include <catch2/generators/catch_generators.hpp>
|
||||
#include <catch2/catch_message.hpp>
|
||||
#include <catch2/matchers/catch_matchers.hpp>
|
||||
#include <catch2/matchers/catch_matchers_floating_point.hpp>
|
||||
#include "libslic3r/LocalesUtils.hpp"
|
||||
|
||||
#include <string>
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
#include "libslic3r/Config.hpp"
|
||||
#include "libslic3r/GCode/ToolOrderUtils.hpp"
|
||||
#include "libslic3r/PrintBase.hpp"
|
||||
#include <cstddef>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <set>
|
||||
|
||||
@@ -1,7 +1,13 @@
|
||||
#include <algorithm>
|
||||
#include <catch2/catch_all.hpp>
|
||||
|
||||
#include "libslic3r/Point.hpp"
|
||||
#include "libslic3r/Polygon.hpp"
|
||||
#include <tbb/global_control.h>
|
||||
#include <vector>
|
||||
#include <utility>
|
||||
|
||||
#include <catch2/catch_test_macros.hpp>
|
||||
#include "libslic3r/TriangleMesh.hpp"
|
||||
#include "libslic3r/TriangleMeshSlicer.hpp"
|
||||
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
#include <catch2/catch_all.hpp>
|
||||
|
||||
#include <catch2/matchers/catch_matchers_floating_point.hpp>
|
||||
#include <catch2/catch_test_macros.hpp>
|
||||
#include <catch2/matchers/catch_matchers.hpp>
|
||||
#include "slic3r/GUI/SceneBenchmark.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
Reference in New Issue
Block a user