diff --git a/src/libslic3r/Format/STEP.cpp b/src/libslic3r/Format/STEP.cpp index a637cdd3ca..38c507bacd 100644 --- a/src/libslic3r/Format/STEP.cpp +++ b/src/libslic3r/Format/STEP.cpp @@ -33,6 +33,8 @@ #include "TopExp_Explorer.hxx" #include "TopExp_Explorer.hxx" #include "BRep_Tool.hxx" +#include "BRepTools.hxx" +#include namespace Slic3r { @@ -163,13 +165,6 @@ int StepPreProcessor::preNum(const unsigned char byte) { return num; } -struct NamedSolid { - NamedSolid(const TopoDS_Shape& s, - const std::string& n) : solid{s}, name{n} {} - const TopoDS_Shape solid; - const std::string name; -}; - static void getNamedSolids(const TopLoc_Location& location, const std::string& prefix, unsigned int& id, const Handle(XCAFDoc_ShapeTool) shapeTool, const TDF_Label label, std::vector& namedSolids) { @@ -206,7 +201,7 @@ static void getNamedSolids(const TopLoc_Location& location, const std::string& p i++; const TopoDS_Shape& currentShape = explorer.Current(); namedSolids.emplace_back(TopoDS::Solid(currentShape), fullName + "-SOLID-" + std::to_string(i)); - } + } break; case TopAbs_SOLID: namedSolids.emplace_back(TopoDS::Solid(transform.Shape()), fullName); @@ -324,7 +319,7 @@ bool load_step(const char *path, Model *model, bool& is_cancel, } // BBS: copy triangles const TopAbs_Orientation anOrientation = anExpSF.Current().Orientation(); - Standard_Integer anId[3]; + Standard_Integer anId[3] = {}; for (Standard_Integer aTriIter = 1; aTriIter <= aTriangulation->NbTriangles(); ++aTriIter) { Poly_Triangle aTri = aTriangulation->Triangle(aTriIter); @@ -403,4 +398,104 @@ bool load_step(const char *path, Model *model, bool& is_cancel, return true; } +Step::Step(fs::path path, ImportStepProgressFn stepFn, StepIsUtf8Fn isUtf8Fn): + m_stepFn(stepFn), + m_utf8Fn(isUtf8Fn) +{ + m_path = path.string(); + m_app->NewDocument(TCollection_ExtendedString("BinXCAF"), m_doc); +} + +Step::Step(std::string path, ImportStepProgressFn stepFn, StepIsUtf8Fn isUtf8Fn) : + m_path(path), + m_stepFn(stepFn), + m_utf8Fn(isUtf8Fn) +{ + m_app->NewDocument(TCollection_ExtendedString("BinXCAF"), m_doc); +} + +bool Step::load() +{ + if (!StepPreProcessor::isUtf8File(m_path.c_str()) && m_utf8Fn) { + m_utf8Fn(false); + return false; + } + + STEPCAFControl_Reader reader; + reader.SetNameMode(true); + IFSelect_ReturnStatus stat = reader.ReadFile(m_path.c_str()); + if (stat != IFSelect_RetDone || !reader.Transfer(m_doc)) { + m_app->Close(m_doc); + return false; + } + m_shape_tool = XCAFDoc_DocumentTool::ShapeTool(m_doc->Main()); + TDF_LabelSequence topLevelShapes; + m_shape_tool->GetFreeShapes(topLevelShapes); + unsigned int id{ 1 }; + Standard_Integer topShapeLength = topLevelShapes.Length() + 1; + for (Standard_Integer iLabel = 1; iLabel < topShapeLength; ++iLabel) { + getNamedSolids(TopLoc_Location{}, "", id, m_shape_tool, topLevelShapes.Value(iLabel), m_name_solids); + } + + return true; +} + +void Step::clean_mesh_data() +{ + for (const auto& name_solid : m_name_solids) { + BRepTools::Clean(name_solid.solid); + } +} + +unsigned int Step::get_triangle_num(double linear_defletion, double angle_defletion) +{ + unsigned int tri_num = 0; + Handle(StepProgressIncdicator) progress = new StepProgressIncdicator(m_stop_mesh); + clean_mesh_data(); + IMeshTools_Parameters param; + param.Deflection = linear_defletion; + param.Angle = angle_defletion; + param.InParallel = true; + for (int i = 0; i < m_name_solids.size(); ++i) { + BRepMesh_IncrementalMesh mesh(m_name_solids[i].solid, param, progress->Start()); + for (TopExp_Explorer anExpSF(m_name_solids[i].solid, TopAbs_FACE); anExpSF.More(); anExpSF.Next()) { + TopLoc_Location aLoc; + Handle(Poly_Triangulation) aTriangulation = BRep_Tool::Triangulation(TopoDS::Face(anExpSF.Current()), aLoc); + if (!aTriangulation.IsNull()) { + tri_num += aTriangulation->NbTriangles(); + } + } + if (m_stop_mesh.load()) { + return 0; + } + } + return tri_num; +} + +unsigned int Step::get_triangle_num_tbb(double linear_defletion, double angle_defletion) +{ + unsigned int tri_num = 0; + clean_mesh_data(); + tbb::parallel_for(tbb::blocked_range(0, m_name_solids.size()), + [&](const tbb::blocked_range& range) { + for (size_t i = range.begin(); i < range.end(); i++) { + unsigned int solids_tri_num = 0; + BRepMesh_IncrementalMesh mesh(m_name_solids[i].solid, linear_defletion, false, angle_defletion, true); + for (TopExp_Explorer anExpSF(m_name_solids[i].solid, TopAbs_FACE); anExpSF.More(); anExpSF.Next()) { + TopLoc_Location aLoc; + Handle(Poly_Triangulation) aTriangulation = BRep_Tool::Triangulation(TopoDS::Face(anExpSF.Current()), aLoc); + if (!aTriangulation.IsNull()) { + solids_tri_num += aTriangulation->NbTriangles(); + } + } + m_name_solids[i].tri_face_cout = solids_tri_num; + } + + }); + for (int i = 0; i < m_name_solids.size(); ++i) { + tri_num += m_name_solids[i].tri_face_cout; + } + return tri_num; +} + }; // namespace Slic3r diff --git a/src/libslic3r/Format/STEP.hpp b/src/libslic3r/Format/STEP.hpp index 64e52aa9be..40c8669b86 100644 --- a/src/libslic3r/Format/STEP.hpp +++ b/src/libslic3r/Format/STEP.hpp @@ -1,5 +1,14 @@ #ifndef slic3r_Format_STEP_hpp_ #define slic3r_Format_STEP_hpp_ +#include "XCAFDoc_DocumentTool.hxx" +#include "XCAFApp_Application.hxx" +#include "XCAFDoc_ShapeTool.hxx" +#include +#include +#include +#include + +namespace fs = boost::filesystem; namespace Slic3r { @@ -16,6 +25,16 @@ const int LOAD_STEP_STAGE_UNIT_NUM = 5; typedef std::function ImportStepProgressFn; typedef std::function StepIsUtf8Fn; +struct NamedSolid +{ + NamedSolid(const TopoDS_Shape& s, + const std::string& n) : solid{ s }, name{ n } { + } + const TopoDS_Shape solid; + const std::string name; + int tri_face_cout = 0; +}; + //BBS: Load an step file into a provided model. extern bool load_step(const char *path, Model *model, bool& is_cancel, @@ -50,6 +69,41 @@ private: EncodedType m_encode_type = EncodedType::UTF8; }; +class StepProgressIncdicator : public Message_ProgressIndicator +{ +public: + StepProgressIncdicator(std::atomic& stop_flag) : should_stop(stop_flag){} + + Standard_Boolean UserBreak() override { return should_stop.load(); } + + void Show(const Message_ProgressScope&, const Standard_Boolean) override { + std::cout << "Progress: " << GetPosition() << "%" << std::endl; + } +private: + std::atomic& should_stop; +}; + +class Step +{ +public: + Step(fs::path path, ImportStepProgressFn stepFn = nullptr, StepIsUtf8Fn isUtf8Fn = nullptr); + Step(std::string path, ImportStepProgressFn stepFn = nullptr, StepIsUtf8Fn isUtf8Fn = nullptr); + bool load(); + unsigned int get_triangle_num(double linear_defletion, double angle_defletion); + unsigned int get_triangle_num_tbb(double linear_defletion, double angle_defletion); + void clean_mesh_data(); + + std::atomic m_stop_mesh; +private: + std::string m_path; + ImportStepProgressFn m_stepFn; + StepIsUtf8Fn m_utf8Fn; + Handle(XCAFApp_Application) m_app = XCAFApp_Application::GetApplication(); + Handle(TDocStd_Document) m_doc; + Handle(XCAFDoc_ShapeTool) m_shape_tool; + std::vector m_name_solids; +}; + }; // namespace Slic3r #endif /* slic3r_Format_STEP_hpp_ */ diff --git a/src/libslic3r/Model.cpp b/src/libslic3r/Model.cpp index 79c424ff79..066eaeda98 100644 --- a/src/libslic3r/Model.cpp +++ b/src/libslic3r/Model.cpp @@ -188,7 +188,7 @@ Model Model::read_from_file(const std::string& input_file, DynamicPrintConfig* c BBLProject * project, int plate_id, ObjImportColorFn objFn, - std::function step_mesh_fn) + std::function step_mesh_fn) { Model model; @@ -216,15 +216,15 @@ Model Model::read_from_file(const std::string& input_file, DynamicPrintConfig* c boost::algorithm::iends_with(input_file, ".step")) { double linear_defletion = 0.003; double angle_defletion = 0.5; + Step step_file(input_file); + step_file.load(); if (step_mesh_fn) { - if (step_mesh_fn(linear_defletion, angle_defletion) == -1) { - result = false; - goto end; + if (step_mesh_fn(step_file, linear_defletion, angle_defletion) == -1) { + Model empty_model; + return empty_model; } } result = load_step(input_file.c_str(), &model, is_cb_cancel, linear_defletion, angle_defletion, stepFn, stepIsUtf8Fn); - end: - BOOST_LOG_TRIVIAL(info) << "Cancel step mesh dialog"; } else if (boost::algorithm::iends_with(input_file, ".stl")) result = load_stl(input_file.c_str(), &model, nullptr, stlFn); else if (boost::algorithm::iends_with(input_file, ".oltp")) diff --git a/src/libslic3r/Model.hpp b/src/libslic3r/Model.hpp index b243bca945..9170b2e40d 100644 --- a/src/libslic3r/Model.hpp +++ b/src/libslic3r/Model.hpp @@ -1544,7 +1544,7 @@ public: BBLProject * project = nullptr, int plate_id = 0, ObjImportColorFn objFn = nullptr, - std::function step_mesh_fn = nullptr + std::function step_mesh_fn = nullptr ); // BBS static bool obj_import_vertex_color_deal(const std::vector &vertex_filament_ids, const unsigned char &first_extruder_id, Model *model); diff --git a/src/slic3r/GUI/CameraUtils.cpp b/src/slic3r/GUI/CameraUtils.cpp index fb8e84fb8a..a14e99c9c5 100644 --- a/src/slic3r/GUI/CameraUtils.cpp +++ b/src/slic3r/GUI/CameraUtils.cpp @@ -38,7 +38,7 @@ Points CameraUtils::project(const Camera & camera, return result; } -Point CameraUtils::project(const Camera &camera, const Vec3d &point) +Slic3r::Point CameraUtils::project(const Camera &camera, const Vec3d &point) { // IMPROVE: do it faster when you need it (inspire in project multi point) return project(camera, std::vector{point}).front(); diff --git a/src/slic3r/GUI/CameraUtils.hpp b/src/slic3r/GUI/CameraUtils.hpp index c3e938ec42..6e953bf6ee 100644 --- a/src/slic3r/GUI/CameraUtils.hpp +++ b/src/slic3r/GUI/CameraUtils.hpp @@ -25,7 +25,7 @@ public: /// projected points by camera into coordinate of camera. /// x(from left to right), y(from top to bottom) static Points project(const Camera& camera, const std::vector &points); - static Point project(const Camera& camera, const Vec3d &point); + static Slic3r::Point project(const Camera& camera, const Vec3d &point); /// /// Create hull around GLVolume in 2d space of camera diff --git a/src/slic3r/GUI/Gizmos/GLGizmoBrimEars.hpp b/src/slic3r/GUI/Gizmos/GLGizmoBrimEars.hpp index e316861dbd..0d6480abd7 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoBrimEars.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoBrimEars.hpp @@ -174,6 +174,8 @@ protected: void find_single(); }; +wxDECLARE_EVENT(wxEVT_THREAD_DONE, wxCommandEvent); + } // namespace GUI } // namespace Slic3r diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 50fa2bd084..a5ec5bed3a 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -4156,17 +4156,17 @@ std::vector Plater::priv::load_files(const std::vector& input_ filament_ids.clear(); } }; - auto step_mesh = [this, &path, &is_user_cancel](double& linear_value, double& angle_value)-> int { + auto step_mesh = [this, &path, &is_user_cancel](Slic3r::Step& file, double& linear_value, double& angle_value)-> int { if (boost::iends_with(path.string(), ".step") || boost::iends_with(path.string(), ".stp")){ - StepMeshDialog mesh_dlg(nullptr, path); + StepMeshDialog mesh_dlg(nullptr, file); if (mesh_dlg.ShowModal() == wxID_OK) { linear_value = mesh_dlg.get_linear_defletion(); angle_value = mesh_dlg.get_angle_defletion(); return 1; } } - is_user_cancel = false; + is_user_cancel = true; return -1; }; model = Slic3r::Model:: read_from_file( diff --git a/src/slic3r/GUI/StepMeshDialog.cpp b/src/slic3r/GUI/StepMeshDialog.cpp index 60d2acde1a..85989accf9 100644 --- a/src/slic3r/GUI/StepMeshDialog.cpp +++ b/src/slic3r/GUI/StepMeshDialog.cpp @@ -1,11 +1,15 @@ #include "StepMeshDialog.hpp" -#include "BBLStatusBar.hpp" -#include "I18N.hpp" -#include "GUI_App.hpp" -#include "Widgets/Button.hpp" -#include "MainFrame.hpp" + +#include +#include #include #include +#include "GUI_App.hpp" +#include "I18N.hpp" +#include "MainFrame.hpp" +#include "Widgets/Button.hpp" +#include "Widgets/TextInput.hpp" +#include using namespace Slic3r; using namespace Slic3r::GUI; @@ -14,7 +18,7 @@ static int _scale(const int val) { return val * Slic3r::GUI::wxGetApp().em_unit( static int _ITEM_WIDTH() { return _scale(30); } #define MIN_DIALOG_WIDTH FromDIP(400) #define SLIDER_WIDTH FromDIP(150) -#define TEXT_CTRL_WIDTH FromDIP(40) +#define TEXT_CTRL_WIDTH FromDIP(50) #define BUTTON_SIZE wxSize(FromDIP(58), FromDIP(24)) #define BUTTON_BORDER FromDIP(int(400 - 58 * 2) / 8) #define SLIDER_SCALE(val) ((val) / 0.001) @@ -23,18 +27,28 @@ static int _ITEM_WIDTH() { return _scale(30); } #define SLIDER_UNSCALE_10(val) ((val) * 0.01) #define LEFT_RIGHT_PADING FromDIP(20) +wxDEFINE_EVENT(wxEVT_THREAD_DONE, wxCommandEvent); + void StepMeshDialog::on_dpi_changed(const wxRect& suggested_rect) { }; bool StepMeshDialog:: validate_number_range(const wxString& value, double min, double max) { - double num; - if (!value.ToDouble(&num)) { + double num = 0.0; + if (value.IsEmpty()) { return false; } + try { + if (!value.ToDouble(&num)) { + return false; + } + } catch (...) { + return false; + } + return (num >= min && num <= max); } -StepMeshDialog::StepMeshDialog(wxWindow* parent, fs::path file) +StepMeshDialog::StepMeshDialog(wxWindow* parent, Slic3r::Step& file) : DPIDialog(parent ? parent : static_cast(wxGetApp().mainframe), wxID_ANY, _(L("Step file import parameters")), @@ -42,6 +56,8 @@ StepMeshDialog::StepMeshDialog(wxWindow* parent, fs::path file) wxDefaultSize, wxDEFAULT_DIALOG_STYLE /* | wxRESIZE_BORDER*/), m_file(file) { + Bind(wxEVT_THREAD_DONE, &StepMeshDialog::on_task_done, this); + std::string icon_path = (boost::format("%1%/images/BambuStudioTitle.ico") % Slic3r::resources_dir()).str(); SetIcon(wxIcon(Slic3r::encode_path(icon_path.c_str()), wxBITMAP_TYPE_ICO)); @@ -64,34 +80,28 @@ StepMeshDialog::StepMeshDialog(wxWindow* parent, fs::path file) wxSize(SLIDER_WIDTH, -1), wxSL_HORIZONTAL); linear_sizer->Add(linear_slider, 0, wxALIGN_RIGHT | wxLEFT, FromDIP(5)); - wxTextValidator valid_number(wxFILTER_NUMERIC); - wxTextCtrl* linear_textctrl = new wxTextCtrl(this, wxID_ANY, - m_linear_last, - wxDefaultPosition, wxSize(TEXT_CTRL_WIDTH, -1), - 0, valid_number); - linear_sizer->Add(linear_textctrl, 0, wxALIGN_RIGHT | wxLEFT, FromDIP(5)); - // textctrl loss focus - linear_textctrl->Bind(wxEVT_KILL_FOCUS, ([this, linear_textctrl](wxFocusEvent& e) { - wxString value = linear_textctrl->GetValue(); - if(!validate_number_range(value, 0.001, 0.1)) { - linear_textctrl->SetValue(m_linear_last); + + auto linear_input = new ::TextInput(this, m_linear_last, wxEmptyString, wxEmptyString, wxDefaultPosition, wxSize(TEXT_CTRL_WIDTH, -1)); + linear_input->GetTextCtrl()->SetFont(Label::Body_12); + linear_input->GetTextCtrl()->SetValidator(wxTextValidator(wxFILTER_NUMERIC)); + linear_sizer->Add(linear_input, 0, wxALIGN_RIGHT | wxLEFT, FromDIP(5)); + linear_input->Bind(wxEVT_KILL_FOCUS, ([this, linear_input](wxFocusEvent& e) { + wxString value = linear_input->GetTextCtrl()->GetValue(); + if (validate_number_range(value, 0.001, 0.1)) { + m_linear_last = value; + update_mesh_number_text(); + } else { + MessageDialog msg_dlg(nullptr, _L("Please input a valid value (0.001 < angle deflection < 0.1)"), wxEmptyString, wxICON_WARNING | wxOK); + msg_dlg.ShowModal(); + linear_input->GetTextCtrl()->SetValue(m_linear_last); } - m_linear_last = value; - update_mesh_number_text(); e.Skip(); })); - // slider bind textctrl - linear_slider->Bind(wxEVT_SLIDER, ([this, linear_slider, linear_textctrl](wxCommandEvent& e) { - double slider_value = SLIDER_UNSCALE(linear_slider->GetValue()); - linear_textctrl->SetValue(wxString::Format("%.3f", slider_value)); - m_linear_last = wxString::Format("%.3f", slider_value); - update_mesh_number_text(); - })); // textctrl bind slider - linear_textctrl->Bind(wxEVT_TEXT, ([this, linear_textctrl, linear_slider](wxCommandEvent& e) { + linear_input->Bind(wxEVT_TEXT, ([this, linear_slider, linear_input](wxCommandEvent& e) { double slider_value_long; int slider_value; - wxString value = linear_textctrl->GetValue(); + wxString value = linear_input->GetTextCtrl()->GetValue(); if (value.ToDouble(&slider_value_long)) { slider_value = SLIDER_SCALE(slider_value_long); if (slider_value >= linear_slider->GetMin() && slider_value <= linear_slider->GetMax()) { @@ -99,6 +109,15 @@ StepMeshDialog::StepMeshDialog(wxWindow* parent, fs::path file) } } })); + linear_slider->Bind(wxEVT_SLIDER, ([this, linear_slider, linear_input](wxCommandEvent& e) { + double slider_value = SLIDER_UNSCALE(linear_slider->GetValue()); + linear_input->GetTextCtrl()->SetValue(wxString::Format("%.3f", slider_value)); + m_linear_last = wxString::Format("%.3f", slider_value); + })); + linear_slider->Bind(wxEVT_LEFT_UP, ([this](wxMouseEvent& e) { + update_mesh_number_text(); + e.Skip(); + })); bSizer->Add(linear_sizer, 1, wxEXPAND | wxLEFT | wxRIGHT | wxTOP, LEFT_RIGHT_PADING); @@ -114,33 +133,28 @@ StepMeshDialog::StepMeshDialog(wxWindow* parent, fs::path file) wxSize(SLIDER_WIDTH, -1), wxSL_HORIZONTAL); angle_sizer->Add(angle_slider, 0, wxALIGN_RIGHT | wxLEFT, FromDIP(5)); - wxTextCtrl* angle_textctrl = new wxTextCtrl(this, wxID_ANY, - m_angle_last, - wxDefaultPosition, wxSize(TEXT_CTRL_WIDTH, -1), - 0, valid_number); - angle_sizer->Add(angle_textctrl, 0, wxALIGN_RIGHT | wxLEFT, FromDIP(5)); - // textctrl loss focus - angle_textctrl->Bind(wxEVT_KILL_FOCUS, ([this, angle_textctrl](wxFocusEvent& e) { - wxString value = angle_textctrl->GetValue(); - if (!validate_number_range(value, 0.01, 1)) { - angle_textctrl->SetValue(m_angle_last); + + auto angle_input = new::TextInput(this, m_angle_last, wxEmptyString, wxEmptyString, wxDefaultPosition, wxSize(TEXT_CTRL_WIDTH, -1)); + angle_input->GetTextCtrl()->SetFont(Label::Body_12); + angle_input->GetTextCtrl()->SetValidator(wxTextValidator(wxFILTER_NUMERIC)); + angle_sizer->Add(angle_input, 0, wxALIGN_RIGHT | wxLEFT, FromDIP(5)); + angle_input->Bind(wxEVT_KILL_FOCUS, ([this, angle_input](wxFocusEvent& e) { + wxString value = angle_input->GetTextCtrl()->GetValue(); + if (validate_number_range(value, 0.01, 1)) { + m_angle_last = value; + update_mesh_number_text(); + } else { + MessageDialog msg_dlg(nullptr, _L("Please input a valid value (0.01 < angle deflection < 1.0)"), wxEmptyString, wxICON_WARNING | wxOK); + msg_dlg.ShowModal(); + angle_input->GetTextCtrl()->SetValue(m_angle_last); } - m_angle_last = value; - update_mesh_number_text(); e.Skip(); })); - // slider bind textctrl - angle_slider->Bind(wxEVT_SLIDER, ([this, angle_slider, angle_textctrl](wxCommandEvent& e) { - double slider_value = SLIDER_UNSCALE_10(angle_slider->GetValue()); - angle_textctrl->SetValue(wxString::Format("%.2f", slider_value)); - m_angle_last = wxString::Format("%.2f", slider_value); - update_mesh_number_text(); - })); // textctrl bind slider - linear_textctrl->Bind(wxEVT_TEXT, ([this, angle_slider, angle_textctrl](wxCommandEvent& e) { + angle_input->Bind(wxEVT_TEXT, ([this, angle_slider, angle_input](wxCommandEvent& e) { double slider_value_long; int slider_value; - wxString value = angle_textctrl->GetValue(); + wxString value = angle_input->GetTextCtrl()->GetValue(); if (value.ToDouble(&slider_value_long)) { slider_value = SLIDER_SCALE_10(slider_value_long); if (slider_value >= angle_slider->GetMin() && slider_value <= angle_slider->GetMax()) { @@ -149,11 +163,25 @@ StepMeshDialog::StepMeshDialog(wxWindow* parent, fs::path file) } })); + angle_slider->Bind(wxEVT_SLIDER, ([this, angle_slider, angle_input](wxCommandEvent& e) { + double slider_value = SLIDER_UNSCALE_10(angle_slider->GetValue()); + angle_input->GetTextCtrl()->SetValue(wxString::Format("%.2f", slider_value)); + m_angle_last = wxString::Format("%.2f", slider_value); + })); + angle_slider->Bind(wxEVT_LEFT_UP, ([this](wxMouseEvent& e) { + update_mesh_number_text(); + e.Skip(); + })); + bSizer->Add(angle_sizer, 1, wxEXPAND | wxLEFT | wxRIGHT, LEFT_RIGHT_PADING); - - mesh_face_number_text = new wxStaticText(this, wxID_ANY, _L("Number of generated surfaces: 0")); - bSizer->Add(mesh_face_number_text, 1, wxEXPAND | wxLEFT | wxRIGHT, LEFT_RIGHT_PADING); + wxBoxSizer* mesh_face_number_sizer = new wxBoxSizer(wxHORIZONTAL); + wxStaticText* mesh_face_number_title = new wxStaticText(this, wxID_ANY, _L("Number of triangular facets: ")); + mesh_face_number_text = new wxStaticText(this, wxID_ANY, _L("0")); + mesh_face_number_text->SetMinSize(wxSize(FromDIP(150), -1)); + mesh_face_number_sizer->Add(mesh_face_number_title, 0, wxALIGN_LEFT); + mesh_face_number_sizer->Add(mesh_face_number_text, 0, wxALIGN_LEFT); + bSizer->Add(mesh_face_number_sizer, 1, wxEXPAND | wxLEFT | wxRIGHT, LEFT_RIGHT_PADING); wxBoxSizer* bSizer_button = new wxBoxSizer(wxHORIZONTAL); bSizer_button->SetMinSize(wxSize(FromDIP(100), -1)); @@ -170,7 +198,14 @@ StepMeshDialog::StepMeshDialog(wxWindow* parent, fs::path file) m_button_ok->SetCornerRadius(FromDIP(12)); bSizer_button->Add(m_button_ok, 0, wxALIGN_RIGHT, BUTTON_BORDER); - m_button_ok->Bind(wxEVT_LEFT_DOWN, [this](wxMouseEvent& e) { EndModal(wxID_OK); }); + m_button_ok->Bind(wxEVT_LEFT_DOWN, [this, angle_input, linear_input](wxMouseEvent& e) { + stop_task(); + if (validate_number_range(angle_input->GetTextCtrl()->GetValue(), 0.01, 1) && + validate_number_range(linear_input->GetTextCtrl()->GetValue(), 0.001, 0.1)) { + EndModal(wxID_OK); + } + SetFocusIgnoringChildren(); + }); StateColor btn_bg_white(std::pair(wxColour(206, 206, 206), StateColor::Pressed), std::pair(wxColour(238, 238, 238), StateColor::Hovered), std::pair(*wxWHITE, StateColor::Normal)); @@ -184,7 +219,10 @@ StepMeshDialog::StepMeshDialog(wxWindow* parent, fs::path file) m_button_cancel->SetCornerRadius(FromDIP(12)); bSizer_button->Add(m_button_cancel, 0, wxALIGN_RIGHT | wxLEFT, BUTTON_BORDER); - m_button_cancel->Bind(wxEVT_LEFT_DOWN, [this](wxMouseEvent& e) { EndModal(wxID_CANCEL); }); + m_button_cancel->Bind(wxEVT_LEFT_DOWN, [this](wxMouseEvent& e) { + stop_task(); + EndModal(wxID_CANCEL); + }); bSizer->Add(bSizer_button, 0, wxALIGN_RIGHT | wxRIGHT| wxBOTTOM, LEFT_RIGHT_PADING); @@ -193,24 +231,57 @@ StepMeshDialog::StepMeshDialog(wxWindow* parent, fs::path file) this->Layout(); bSizer->Fit(this); - this->Bind(wxEVT_CLOSE_WINDOW, [this](wxCloseEvent& e) { }); + this->Bind(wxEVT_LEFT_DOWN, [this](auto& e) { + SetFocusIgnoringChildren(); + }); + mesh_face_number_text->Bind(wxEVT_LEFT_DOWN, [this](auto& e) { + SetFocusIgnoringChildren(); + }); + + this->Bind(wxEVT_CLOSE_WINDOW, [this](wxCloseEvent& e) { + stop_task(); + EndModal(wxID_CANCEL); + }); wxGetApp().UpdateDlgDarkUI(this); } -long StepMeshDialog::get_mesh_number() +void StepMeshDialog::on_task_done(wxCommandEvent& event) { - Model model; - long number = 0; - const std::string file_path = m_file.string(); - bool is_cb_cancel = false; - bool result = load_step(file_path.c_str(), &model, is_cb_cancel, get_linear_defletion(), get_angle_defletion(), nullptr, nullptr, number); - return number; + wxString text = event.GetString(); + mesh_face_number_text->SetLabel(text); + if (task.valid()) { + task.get(); + } +} + +void StepMeshDialog::stop_task() +{ + if (task.valid()) { + m_file.m_stop_mesh.store(true); + unsigned int test = task.get(); + m_file.m_stop_mesh.store(false); + std::cout << test << std::endl; + } + } void StepMeshDialog::update_mesh_number_text() { - long number = get_mesh_number(); - wxString newText = wxString::Format("Number of generated surfaces: %d", number); + if (m_last_linear == get_linear_defletion() && m_last_angle == get_angle_defletion()) + return; + wxString newText = wxString::Format(_L("Calculating, please wait...")); mesh_face_number_text->SetLabel(newText); + + stop_task(); + task = std::async(std::launch::async, [&] { + unsigned int number = m_file.get_triangle_num(get_linear_defletion(), get_angle_defletion()); + if (number != 0) { + wxString number_text = wxString::Format("%d", number); + wxCommandEvent event(wxEVT_THREAD_DONE); + event.SetString(number_text); + wxPostEvent(this, event); + } + return number; + }); } \ No newline at end of file diff --git a/src/slic3r/GUI/StepMeshDialog.hpp b/src/slic3r/GUI/StepMeshDialog.hpp index 24754cd138..48bff2adc3 100644 --- a/src/slic3r/GUI/StepMeshDialog.hpp +++ b/src/slic3r/GUI/StepMeshDialog.hpp @@ -1,15 +1,16 @@ #ifndef _STEP_MESH_DIALOG_H_ #define _STEP_MESH_DIALOG_H_ +#include #include "GUI_Utils.hpp" -#include -#include +#include "libslic3r/Format/STEP.hpp" +#include "Widgets/Button.hpp" class Button; -namespace fs = boost::filesystem; + class StepMeshDialog : public Slic3r::GUI::DPIDialog { public: - StepMeshDialog(wxWindow* parent, fs::path file); + StepMeshDialog(wxWindow* parent, Slic3r::Step& file); void on_dpi_changed(const wxRect& suggested_rect) override; inline double get_linear_defletion() { double value; @@ -27,16 +28,20 @@ public: return 0.5; } } - long get_mesh_number(); private: - fs::path m_file; + Slic3r::Step& m_file; Button* m_button_ok = nullptr; Button* m_button_cancel = nullptr; wxString m_linear_last = wxString::Format("%.3f", 0.003); wxString m_angle_last = wxString::Format("%.2f", 0.5); wxStaticText* mesh_face_number_text; + double m_last_linear; + double m_last_angle; + std::future task; bool validate_number_range(const wxString& value, double min, double max); void update_mesh_number_text(); + void on_task_done(wxCommandEvent& event); + void stop_task(); }; #endif // _STEP_MESH_DIALOG_H_ \ No newline at end of file diff --git a/src/slic3r/pchheader.hpp b/src/slic3r/pchheader.hpp index 1413839185..7519cbb399 100644 --- a/src/slic3r/pchheader.hpp +++ b/src/slic3r/pchheader.hpp @@ -6,6 +6,11 @@ #define NOMINMAX #endif #include + #include +#endif + +#ifdef __APPLE__ + #include #endif #include