diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 361074ea3..6f81384a1 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -187,6 +187,7 @@ IF(wxWidgets_FOUND) ${GUI_LIBDIR}/MainFrame.cpp ${GUI_LIBDIR}/Plater.cpp ${GUI_LIBDIR}/Plater/Plate2D.cpp + ${GUI_LIBDIR}/Plater/PlaterObject.cpp ${GUI_LIBDIR}/Settings.cpp ${GUI_LIBDIR}/misc_ui.cpp ) diff --git a/src/GUI/Plater.hpp b/src/GUI/Plater.hpp index c74f9d87f..58a25d0a1 100644 --- a/src/GUI/Plater.hpp +++ b/src/GUI/Plater.hpp @@ -14,7 +14,7 @@ #include "Print.hpp" #include "Config.hpp" -#include "Plater/Plater2DObject.hpp" +#include "Plater/PlaterObject.hpp" #include "Plater/Plate2D.hpp" #include "Settings.hpp" @@ -23,7 +23,7 @@ namespace Slic3r { namespace GUI { using UndoOperation = int; using obj_index = unsigned int; -class Plater2DObject; +class PlaterObject; class Plate2D; class Plater : public wxPanel @@ -44,7 +44,7 @@ private: bool processed {false}; - std::vector objects {}; + std::vector objects {}; std::stack undo {}; std::stack redo {}; diff --git a/src/GUI/Plater/Plate2D.cpp b/src/GUI/Plater/Plate2D.cpp index 2f747f2a2..11f863f93 100644 --- a/src/GUI/Plater/Plate2D.cpp +++ b/src/GUI/Plater/Plate2D.cpp @@ -12,7 +12,7 @@ namespace Slic3r { namespace GUI { -Plate2D::Plate2D(wxWindow* parent, const wxSize& size, std::vector& _objects, std::shared_ptr _model, std::shared_ptr _config, std::shared_ptr _settings) : +Plate2D::Plate2D(wxWindow* parent, const wxSize& size, std::vector& _objects, std::shared_ptr _model, std::shared_ptr _config, std::shared_ptr _settings) : wxPanel(parent, wxID_ANY, wxDefaultPosition, size, wxTAB_TRAVERSAL), objects(_objects), model(_model), config(_config), settings(_settings) { diff --git a/src/GUI/Plater/Plate2D.hpp b/src/GUI/Plater/Plate2D.hpp index 01eb01abe..8bab87b7a 100644 --- a/src/GUI/Plater/Plate2D.hpp +++ b/src/GUI/Plater/Plate2D.hpp @@ -11,7 +11,7 @@ #include "Plater.hpp" #include "ColorScheme.hpp" #include "Settings.hpp" -#include "Plater/Plater2DObject.hpp" +#include "Plater/PlaterObject.hpp" #include "misc_ui.hpp" #include "Log.hpp" @@ -31,12 +31,12 @@ enum class MoveDirection { class Plate2D : public wxPanel { public: - Plate2D(wxWindow* parent, const wxSize& size, std::vector& _objects, std::shared_ptr _model, std::shared_ptr _config, std::shared_ptr _settings); + Plate2D(wxWindow* parent, const wxSize& size, std::vector& _objects, std::shared_ptr _model, std::shared_ptr _config, std::shared_ptr _settings); // std::function<> on_select_object {}; private: - std::vector& objects; + std::vector& objects; std::shared_ptr model; std::shared_ptr config; std::shared_ptr settings; diff --git a/src/GUI/Plater/Plater2DObject.hpp b/src/GUI/Plater/Plater2DObject.hpp deleted file mode 100644 index 1bd5b97ba..000000000 --- a/src/GUI/Plater/Plater2DObject.hpp +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef PLATER2DOBJECT_HPP -#define PLATER2DOBJECT_HPP - -namespace Slic3r { namespace GUI { -// 2D Preview of an object -class Plater2DObject { -public: - std::string name {""}; - std::string identifier {""}; - bool selected {false}; - int selected_instance {-1}; -}; -} } // Namespace Slic3r::GUI -#endif diff --git a/src/GUI/Plater/PlaterObject.cpp b/src/GUI/Plater/PlaterObject.cpp new file mode 100644 index 000000000..39b6bca3b --- /dev/null +++ b/src/GUI/Plater/PlaterObject.cpp @@ -0,0 +1,50 @@ +#include "Plater/PlaterObject.hpp" + +#include "Geometry.hpp" +#include "ExPolygon.hpp" + +namespace Slic3r { namespace GUI { + +Slic3r::ExPolygonCollection& PlaterObject::make_thumbnail(const Slic3r::Model& model, int obj_index) { + + // make method idempotent + this->thumbnail.clear(); + + auto mesh {model.objects[obj_index]->raw_mesh()}; + auto model_instance {model.objects[obj_idx]->instances[0]}; + + // Apply any x/y rotations and scaling vector if this came from a 3MF object. + mesh.rotate_x(model_instance.x_rotation); + mesh.rotate_y(model_instance.y_rotation); + mesh.scale_xyz(model_instance.scaling_vector); + + if (mesh.facets_count <= 5000) { + auto area_threshold {Slic3r::Geometry::scale(1)}; + ExPolygons tmp {}; + std::copy_if(tmp.end(), mesh.horizontal_projection().begin(), mesh.horizontal_projection().end(), [=](const ExPolygon& p) { return p.area() >= area_threshold; } ); // return all polys bigger than the area + this->thumbnail.append(tmp); + this->thumbnail.simplify(0.5); + } else { + auto convex_hull {Slic3r::ExPolygon(mesh.convex_hull)}; + this->thumbnail.append(convex_hull); + } + + return this->thumbnail; +} +Slic3r::ExPolygonCollection& PlaterObject::transform_thumbnail(Slic3r::Model model, int obj_idx) { + if (this->thumbnail.expolygons.size() == 0) return this->thumbnail; + + const auto& model_object {model.objects[obj_idx] }; + const auto& model_instance {model_object.instances[0]}; + + // the order of these transformations MUST be the same everywhere, including + // in Slic3r::Print->add_model_object() + auto t {this->thumbnail}; + t.rotate(model_instance.rotation(), Slic3r::Point(0,0)); + t.scale(model_instance.scaling_factor()); + + this->transformed_thumbnail = t; + +} + +} } // Namespace Slic3r::GUI diff --git a/src/GUI/Plater/PlaterObject.hpp b/src/GUI/Plater/PlaterObject.hpp new file mode 100644 index 000000000..32709a30c --- /dev/null +++ b/src/GUI/Plater/PlaterObject.hpp @@ -0,0 +1,34 @@ +#ifndef PLATEROBJECT_HPP +#define PLATEROBJECT_HPP +#include +#ifndef WX_PRECOMP + #include +#endif + +#include "ExPolygonCollection.hpp" + +namespace Slic3r { namespace GUI { + +class PlaterObject { +public: + wxString name {L""}; + wxString identifier {L""}; + wxString input_file {L""}; + int input_file_obj_idx {-1}; + + + Slic3r::ExPolygonCollection thumbnail; + Slic3r::ExPolygonCollection transformed_thumbnail; + + // read only + std::vector instance_thumbnails; + + bool selected {false}; + int selected_instance {-1}; + + Slic3r::ExPolygonCollection& make_thumbnail(Slic3r::Model model, int obj_index); + Slic3r::ExPolygonCollection& transform_thumbnail(Slic3r::Model model, int obj_index); +}; + +}} // Namespace Slic3r::GUI +#endif