diff --git a/src/libslic3r/SLAPrint.cpp b/src/libslic3r/SLAPrint.cpp index 73b423a3f..939b9ff34 100644 --- a/src/libslic3r/SLAPrint.cpp +++ b/src/libslic3r/SLAPrint.cpp @@ -1,18 +1,70 @@ #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; @@ -22,17 +74,20 @@ SLAPrint::ApplyStatus SLAPrint::apply(const Model &model, const DynamicPrintConf // Temporary quick fix, just invalidate everything. { - for (SLAPrintObject *print_object : m_objects) { + 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)); } } @@ -41,6 +96,112 @@ SLAPrint::ApplyStatus SLAPrint::apply(const Model &model, const DynamicPrintConf 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); +} + +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; };