diff --git a/src/libslic3r/SLA/SLASupportTree.cpp b/src/libslic3r/SLA/SLASupportTree.cpp index 7adaea1f4..d689324c0 100644 --- a/src/libslic3r/SLA/SLASupportTree.cpp +++ b/src/libslic3r/SLA/SLASupportTree.cpp @@ -924,6 +924,11 @@ bool SLASupportTree::generate(const PointSet &points, //... }; + // Debug: + for(int pn = 0; pn < points.rows(); ++pn) { + std::cout << "p " << pn << " " << points.row(pn) << std::endl; + } + auto filterfn = [] ( const SupportConfig& cfg, const PointSet& points, @@ -1511,7 +1516,7 @@ bool SLASupportTree::generate(const PointSet &points, auto progress = [&ctl, &pc, &pc_prev] () { static const std::array stepstr { - "", + "Starting", "Filtering", "Generate pinheads", "Classification", diff --git a/src/libslic3r/SLA/SLASupportTree.hpp b/src/libslic3r/SLA/SLASupportTree.hpp index f9691b19f..3a1c5ef68 100644 --- a/src/libslic3r/SLA/SLASupportTree.hpp +++ b/src/libslic3r/SLA/SLASupportTree.hpp @@ -74,13 +74,16 @@ struct Controller { /// An index-triangle structure for libIGL functions. Also serves as an /// alternative (raw) input format for the SLASupportTree struct EigenMesh3D { -// Eigen::MatrixXd V; -// Eigen::MatrixXi F; - Eigen::Matrix V; - Eigen::Matrix F; + Eigen::MatrixXd V; + Eigen::MatrixXi F; + + // igl crashes with the following data types: +// Eigen::Matrix V; +// Eigen::Matrix F; }; -using PointSet = Eigen::Matrix; //Eigen::MatrixXd; +//using PointSet = Eigen::Matrix; //Eigen::MatrixXd; +using PointSet = Eigen::MatrixXd; /* ************************************************************************** */ /* TODO: May not be needed: */ diff --git a/src/libslic3r/SLA/SLASupportTreeIGL.cpp b/src/libslic3r/SLA/SLASupportTreeIGL.cpp index 7de4d196d..c95dcef34 100644 --- a/src/libslic3r/SLA/SLASupportTreeIGL.cpp +++ b/src/libslic3r/SLA/SLASupportTreeIGL.cpp @@ -84,11 +84,11 @@ size_t SpatIndex::size() const } PointSet normals(const PointSet& points, const EigenMesh3D& mesh) { -// Eigen::VectorXd dists; -// Eigen::VectorXi I; #ifdef IGL_COMPATIBLE - Eigen::Matrix dists; - Eigen::Matrix I; + Eigen::VectorXd dists; + Eigen::VectorXi I; +// Eigen::Matrix dists; +// Eigen::Matrix I; PointSet C; igl::point_mesh_squared_distance( points, mesh.V, mesh.F, dists, I, C); diff --git a/src/libslic3r/SLAPrint.cpp b/src/libslic3r/SLAPrint.cpp index 73b423a3f..213c3a5c6 100644 --- a/src/libslic3r/SLAPrint.cpp +++ b/src/libslic3r/SLAPrint.cpp @@ -1,46 +1,212 @@ #include "SLAPrint.hpp" +#include "SLA/SLASupportTree.hpp" + +#include "I18N.hpp" + +//! macro used to mark string used at localization, +//! return same string +#define L(s) Slic3r::I18N::translate(s) namespace Slic3r { +class SLAPrintObject::SupportData { +public: + sla::EigenMesh3D emesh; // index-triangle representation + sla::PointSet support_points; // all the support points (manual/auto) + std::unique_ptr support_tree_ptr; // the supports + SlicedSupports slice_cache; // sliced supports +}; + +namespace { + +const std::array OBJ_STEP_LEVELS = +{ + 20, + 30, + 50, + 70, + 80, + 100 +}; + +const std::array OBJ_STEP_LABELS = +{ + L("Slicing model"), // slaposObjectSlice, + L("Generating islands"), // slaposSupportIslands, + L("Scanning model structure"), // slaposSupportPoints, + L("Generating support tree"), // slaposSupportTree, + L("Generating base pool"), // slaposBasePool, + L("Slicing supports") // slaposSliceSupports, +}; + +const std::array PRINT_STEP_LEVELS = +{ + 50, // slapsRasterize + 100, // slapsValidate +}; + +const std::array PRINT_STEP_LABELS = +{ + L("Rasterizing layers"), // slapsRasterize + L("Validating"), // slapsValidate +}; + +} + void SLAPrint::clear() { tbb::mutex::scoped_lock lock(this->cancel_mutex()); // The following call should stop background processing if it is running. this->invalidate_all_steps(); - for (SLAPrintObject *object : m_objects) - delete object; + + for (SLAPrintObject *object : m_objects) delete object; m_objects.clear(); } -SLAPrint::ApplyStatus SLAPrint::apply(const Model &model, const DynamicPrintConfig &config) +SLAPrint::ApplyStatus SLAPrint::apply(const Model &model, + const DynamicPrintConfig &config) { - if (m_objects.empty()) - return APPLY_STATUS_UNCHANGED; +// if (m_objects.empty()) +// return APPLY_STATUS_UNCHANGED; // Grab the lock for the Print / PrintObject milestones. tbb::mutex::scoped_lock lock(this->cancel_mutex()); + if(m_objects.empty() && model.objects.empty()) + return APPLY_STATUS_UNCHANGED; // Temporary quick fix, just invalidate everything. { - for (SLAPrintObject *print_object : m_objects) { + std::cout << "deleting object cache " << std::endl; + for (SLAPrintObject *print_object : m_objects) { print_object->invalidate_all_steps(); - delete print_object; + delete print_object; } m_objects.clear(); this->invalidate_all_steps(); - // Copy the model by value (deep copy), keep the Model / ModelObject / ModelInstance / ModelVolume IDs. + + // Copy the model by value (deep copy), + // keep the Model / ModelObject / ModelInstance / ModelVolume IDs. m_model.assign_copy(model); // Generate new SLAPrintObjects. - for (const ModelObject *model_object : m_model.objects) { + for (ModelObject *model_object : m_model.objects) { //TODO + m_objects.emplace_back(new SLAPrintObject(this, model_object)); } - } + } return APPLY_STATUS_INVALIDATED; } void SLAPrint::process() { + using namespace sla; + + std::cout << "SLA Processing triggered" << std::endl; + + // Assumption: at this point the print objects should be populated only with + // the model objects we have to process and the instances are also filtered + + auto slice_model = [](const SLAPrintObject&) { + + + }; + + auto support_points = [](const SLAPrintObject&) { + // for(SLAPrintObject *po : pobjects) { + // TODO: calculate automatic support points + // po->m_supportdata->slice_cache contains the slices at this point + //} + }; + + auto support_tree = [this](const SLAPrintObject& po) { + auto& emesh = po.m_supportdata->emesh; + auto& pts = po.m_supportdata->support_points; // nowhere filled yet + auto& supportd = *po.m_supportdata; + try { + SupportConfig scfg; // TODO fill or replace with po.m_config + + sla::Controller ctl; + ctl.statuscb = [this](unsigned st, const std::string& msg) { + unsigned stinit = OBJ_STEP_LEVELS[slaposSupportTree]; + double d = (OBJ_STEP_LEVELS[slaposBasePool] - stinit) / 100.0; + set_status(unsigned(stinit + st*d), msg); + }; + ctl.stopcondition = [this](){ return canceled(); }; + + supportd.support_tree_ptr.reset( + new SLASupportTree(pts, emesh, scfg, ctl)); + + } catch(sla::SLASupportsStoppedException&) { + // no need to rethrow + // throw_if_canceled(); + } + }; + + auto base_pool = [](const SLAPrintObject&) { + + }; + + auto slice_supports = [](const SLAPrintObject&) { + + }; + + auto rasterize = []() { + + }; + + using slaposFn = std::function; + + std::array objectsteps = { + slaposObjectSlice, + slaposSupportIslands, + slaposSupportPoints, + slaposSupportTree, + slaposBasePool, + slaposSliceSupports + }; + + std::array fullprogram = + { + slice_model, + [](const SLAPrintObject&){}, // slaposSupportIslands now empty + support_points, + support_tree, + base_pool, + slice_supports + }; + + for(SLAPrintObject * po : m_objects) { + for(size_t s = 0; s < fullprogram.size(); ++s) { + auto currentstep = objectsteps[s]; + + // Cancellation checking. Each step will check for cancellation + // on its own and return earlier gracefully. Just after it returns + // execution gets to this point and throws the canceled signal. + throw_if_canceled(); + + if(po->m_stepmask[s]) { + set_status(OBJ_STEP_LEVELS[currentstep], + OBJ_STEP_LABELS[currentstep]); + + po->set_started(currentstep); + fullprogram[s](*po); + po->set_done(currentstep); + } + } + } } +SLAPrintObject::SLAPrintObject(SLAPrint *print, ModelObject *model_object): + Inherited(print), + m_model_object(model_object), + m_supportdata(new SupportData()), + m_stepmask(slaposCount, true) +{ + m_supportdata->emesh = sla::to_eigenmesh(*m_model_object); + m_supportdata->support_points = sla::support_points(*m_model_object); + std::cout << "support points copied " << m_supportdata->support_points.rows() << std::endl; +} + +SLAPrintObject::~SLAPrintObject() {} + } // namespace Slic3r diff --git a/src/libslic3r/SLAPrint.hpp b/src/libslic3r/SLAPrint.hpp index 4a2c621ea..b5289c0f2 100644 --- a/src/libslic3r/SLAPrint.hpp +++ b/src/libslic3r/SLAPrint.hpp @@ -3,7 +3,6 @@ #include "PrintBase.hpp" #include "Point.hpp" -//#include "SLA/SLASupportTree.hpp" namespace Slic3r { @@ -25,21 +24,28 @@ enum SLAPrintObjectStep { class SLAPrint; -class SLAPrintObject : public PrintObjectBaseWithState +using _SLAPrintObjectBase = + PrintObjectBaseWithState; + +class SLAPrintObject : public _SLAPrintObjectBase { private: // Prevents erroneous use by other classes. - typedef PrintObjectBaseWithState Inherited; + using Inherited = _SLAPrintObjectBase; public: const ModelObject* model_object() const { return m_model_object; } ModelObject* model_object() { return m_model_object; } + // I refuse to grantee copying (Tamas) + SLAPrintObject(const SLAPrintObject&) = delete; + SLAPrintObject& operator=(const SLAPrintObject&) = delete; + protected: // to be called from SLAPrint only. friend class SLAPrint; SLAPrintObject(SLAPrint* print, ModelObject* model_object); - ~SLAPrintObject() {} + ~SLAPrintObject(); void config_apply(const ConfigBase &other, bool ignore_nonexistent = false) { this->m_config.apply(other, ignore_nonexistent); } void config_apply_only(const ConfigBase &other, const t_config_option_keys &keys, bool ignore_nonexistent = false) @@ -65,11 +71,11 @@ private: Transform3d m_trafo = Transform3d::Identity(); std::vector m_instances; -// sla::EigenMesh3D emesh; -// std::unique_ptr support_tree_ptr; -// SlicedSupports slice_cache; + // Which steps have to be performed. Implicitly: all + std::vector m_stepmask; - friend SLAPrint; + class SupportData; + std::unique_ptr m_supportdata; }; /** @@ -85,9 +91,6 @@ private: * triangle meshes or receiving the rendering canvas and drawing on that * directly. * - * TODO: This class uses the BackgroundProcess interface to create workers and - * manage input change events. An appropriate implementation can be derived - * from BackgroundSlicingProcess which is now working only with the FDM Print. */ class SLAPrint : public PrintBaseWithState { @@ -109,8 +112,7 @@ private: Model m_model; SLAPrinterConfig m_printer_config; SLAMaterialConfig m_material_config; - - std::vector m_objects; + std::vector m_objects; friend SLAPrintObject; };