diff --git a/src/libslic3r/SLA/SLABasePool.cpp b/src/libslic3r/SLA/SLABasePool.cpp index fe31ed57dc..91f8441606 100644 --- a/src/libslic3r/SLA/SLABasePool.cpp +++ b/src/libslic3r/SLA/SLABasePool.cpp @@ -425,6 +425,8 @@ void base_plate(const TriangleMesh &mesh, ExPolygons &output, float h) TriangleMesh upper, lower; slicer.cut(h, &upper, &lower); + + // TODO: this might be slow output = lower.horizontal_projection(); for(auto& o : output) o = o.simplify(0.1/SCALING_FACTOR).front(); diff --git a/src/libslic3r/SLA/SLASupportTree.cpp b/src/libslic3r/SLA/SLASupportTree.cpp index d689324c06..9bb590d303 100644 --- a/src/libslic3r/SLA/SLASupportTree.cpp +++ b/src/libslic3r/SLA/SLASupportTree.cpp @@ -168,9 +168,10 @@ Contour3D sphere(double rho, Portion portion = make_portion(0.0, 2.0*PI), return ret; } -Contour3D cylinder(double r, double h, size_t steps) { +Contour3D cylinder(double r, double h, size_t ssteps) { Contour3D ret; + auto steps = int(ssteps); auto& points = ret.points; auto& indices = ret.indices; points.reserve(2*steps); @@ -275,10 +276,10 @@ struct Head { mesh.indices.emplace_back(i1s1, i2s2, i1s2); } - auto i1s1 = coord_t(s1.points.size()) - steps; + auto i1s1 = coord_t(s1.points.size()) - coord_t(steps); auto i2s1 = coord_t(s1.points.size()) - 1; auto i1s2 = coord_t(s1.points.size()); - auto i2s2 = coord_t(s1.points.size()) + steps - 1; + auto i2s2 = coord_t(s1.points.size()) + coord_t(steps) - 1; mesh.indices.emplace_back(i2s2, i2s1, i1s1); mesh.indices.emplace_back(i1s2, i2s2, i1s1); @@ -368,13 +369,13 @@ struct Pillar { } indices.reserve(2*steps); - auto offs = steps; + int offs = int(steps); for(int i = 0; i < steps - 1; ++i) { indices.emplace_back(i, i + offs, offs + i + 1); indices.emplace_back(i, offs + i + 1, i + 1); } - auto last = steps - 1; + int last = int(steps) - 1; indices.emplace_back(0, last, offs); indices.emplace_back(last, offs + last, offs); } @@ -499,6 +500,27 @@ struct CompactBridge { } }; +// A wrapper struct around the base pool (pad) +struct Pad { +// Contour3D mesh; + TriangleMesh tmesh; + PoolConfig cfg; + double zlevel; + + Pad() {} + + Pad(const TriangleMesh& object_support_mesh, + double ground_level, + const PoolConfig& cfg) : zlevel(ground_level) + { + ExPolygons basep; + base_plate(object_support_mesh, basep); + create_base_pool(basep, tmesh, cfg); + tmesh.translate(0, 0, float(zlevel)); + std::cout << "pad ground level " << zlevel << std::endl; + } +}; + EigenMesh3D to_eigenmesh(const Contour3D& cntr) { EigenMesh3D emesh; @@ -564,7 +586,11 @@ EigenMesh3D to_eigenmesh(const TriangleMesh& tmesh) { } EigenMesh3D to_eigenmesh(const ModelObject& modelobj) { - return to_eigenmesh(modelobj.raw_mesh()); + auto&& rmesh = modelobj.raw_mesh(); + auto&& ret = to_eigenmesh(rmesh); + auto&& bb = rmesh.bounding_box(); + ret.ground_level = bb.min(Z); + return ret; } EigenMesh3D to_eigenmesh(const Model& model) { @@ -606,13 +632,12 @@ PointSet support_points(const Model& model) { return ret; } -PointSet support_points(const ModelObject& modelobject, std::size_t instance_id) +PointSet support_points(const ModelObject& modelobject) { PointSet ret(modelobject.sla_support_points.size(), 3); long i = 0; - ModelInstance *inst = modelobject.instances[instance_id]; for(const Vec3f& msource : modelobject.sla_support_points) { - ret.row(i++) = model_coord(*inst, msource); + ret.row(i++) = msource.cast(); } return ret; } @@ -643,12 +668,16 @@ class SLASupportTree::Impl { std::vector m_junctions; std::vector m_bridges; std::vector m_compact_bridges; + Pad m_pad; + mutable TriangleMesh meshcache; mutable bool meshcache_valid; + mutable double model_height = 0; // the full height of the model public: - float model_height = 0; // the full height of the model + double ground_level = 0; template Head& add_head(Args&&... args) { m_heads.emplace_back(std::forward(args)...); m_heads.back().id = long(m_heads.size() - 1); + meshcache_valid = false; return m_heads.back(); } @@ -661,6 +690,7 @@ public: head.pillar_id = pillar.id; pillar.start_junction_id = head.id; pillar.starts_from_head = true; + meshcache_valid = false; return m_pillars.back(); } @@ -669,6 +699,7 @@ public: Pillar& p = m_pillars[pillar_id]; assert(p.starts_from_head && p.start_junction_id > 0 && p.start_junction_id < m_heads.size() ); + meshcache_valid = false; return m_heads[p.start_junction_id]; } @@ -676,18 +707,21 @@ public: assert(headid >= 0 && headid < m_heads.size()); Head& h = m_heads[headid]; assert(h.pillar_id > 0 && h.pillar_id < m_pillars.size()); + meshcache_valid = false; return m_pillars[h.pillar_id]; } template const Junction& add_junction(Args&&... args) { m_junctions.emplace_back(std::forward(args)...); m_junctions.back().id = long(m_junctions.size() - 1); + meshcache_valid = false; return m_junctions.back(); } template const Bridge& add_bridge(Args&&... args) { m_bridges.emplace_back(std::forward(args)...); m_bridges.back().id = long(m_bridges.size() - 1); + meshcache_valid = false; return m_bridges.back(); } @@ -695,17 +729,64 @@ public: const CompactBridge& add_compact_bridge(Args&&...args) { m_compact_bridges.emplace_back(std::forward(args)...); m_compact_bridges.back().id = long(m_compact_bridges.size() - 1); + meshcache_valid = false; return m_compact_bridges.back(); } const std::vector& heads() const { return m_heads; } - Head& head(size_t idx) { return m_heads[idx]; } + Head& head(size_t idx) { meshcache_valid = false; return m_heads[idx]; } const std::vector& pillars() const { return m_pillars; } const std::vector& bridges() const { return m_bridges; } const std::vector& junctions() const { return m_junctions; } const std::vector& compact_bridges() const { return m_compact_bridges; } + + const Pad& create_pad(const TriangleMesh& object_supports, + const PoolConfig& cfg) { + m_pad = Pad(object_supports, ground_level, cfg); + return m_pad; + } + + const Pad& pad() const { return m_pad; } + + // WITHOUT THE PAD!!! + const TriangleMesh& merged_mesh() const { + if(meshcache_valid) return meshcache; + + meshcache = TriangleMesh(); + + for(auto& head : heads()) { + meshcache.merge(mesh(head.mesh)); + } + + for(auto& stick : pillars()) { + meshcache.merge(mesh(stick.mesh)); + meshcache.merge(mesh(stick.base)); + } + + for(auto& j : junctions()) { + meshcache.merge(mesh(j.mesh)); + } + + for(auto& cb : compact_bridges()) { + meshcache.merge(mesh(cb.mesh)); + } + + for(auto& bs : bridges()) { + meshcache.merge(mesh(bs.mesh)); + } + + BoundingBoxf3&& bb = meshcache.bounding_box(); + model_height = bb.max(Z); + + meshcache_valid = true; + } + + double full_height() const { + if(!meshcache_valid) merged_mesh(); + return model_height; + } }; template @@ -908,6 +989,7 @@ bool SLASupportTree::generate(const PointSet &points, using Result = SLASupportTree::Impl; Result& result = *m_impl; + result.ground_level = mesh.ground_level; enum Steps { BEGIN, @@ -925,9 +1007,9 @@ bool SLASupportTree::generate(const PointSet &points, }; // Debug: - for(int pn = 0; pn < points.rows(); ++pn) { - std::cout << "p " << pn << " " << points.row(pn) << std::endl; - } + // for(int pn = 0; pn < points.rows(); ++pn) { + // std::cout << "p " << pn << " " << points.row(pn) << std::endl; + // } auto filterfn = [] ( const SupportConfig& cfg, @@ -1119,8 +1201,8 @@ bool SLASupportTree::generate(const PointSet &points, const Head& phead = result.pillar_head(pillar.id); const Head& nextphead = result.pillar_head(nextpillar.id); - double d = 2*pillar.r; - const Vec3d& pp = pillar.endpoint.cwiseProduct(Vec3d{1, 1, 0}); +// double d = 2*pillar.r; +// const Vec3d& pp = pillar.endpoint.cwiseProduct(Vec3d{1, 1, 0}); Vec3d sj = phead.junction_point(); sj(Z) = std::min(sj(Z), nextphead.junction_point()(Z)); @@ -1176,10 +1258,13 @@ bool SLASupportTree::generate(const PointSet &points, const double hbr = cfg.head_back_radius_mm; const double pradius = cfg.pillar_radius_mm; const double maxbridgelen = cfg.max_bridge_length_mm; + const double gndlvl = emesh.ground_level - cfg.object_elevation_mm; ClusterEl cl_centroids; cl_centroids.reserve(gnd_clusters.size()); + std::cout << "gnd_clusters size: " << gnd_clusters.size() << std::endl; + SpatIndex pheadindex; // spatial index for the junctions for(auto cl : gnd_clusters) { // place all the centroid head positions into the index. We will @@ -1201,7 +1286,7 @@ bool SLASupportTree::generate(const PointSet &points, unsigned hid = gndidx[cl[cid]]; // Head index Head& h = result.head(hid); h.transform(); - Vec3d p = h.junction_point(); p(Z) = 0; + Vec3d p = h.junction_point(); p(Z) = gndlvl; pheadindex.insert(p, hid); } @@ -1218,7 +1303,7 @@ bool SLASupportTree::generate(const PointSet &points, auto& head = result.head(index_to_heads); Vec3d startpoint = head.junction_point(); - auto endpoint = startpoint; endpoint(Z) = 0; + auto endpoint = startpoint; endpoint(Z) = gndlvl; // Create the central pillar of the cluster with its base on the // ground @@ -1233,7 +1318,7 @@ bool SLASupportTree::generate(const PointSet &points, // is distributed more effectively on the pillar. auto search_nearest = - [&cfg, &result, &emesh, maxbridgelen] + [&cfg, &result, &emesh, maxbridgelen, gndlvl] (SpatIndex& spindex, const Vec3d& jsh) { long nearest_id = -1; @@ -1244,7 +1329,7 @@ bool SLASupportTree::generate(const PointSet &points, // (this may happen as the clustering is not perfect) // than we will bridge to this closer pillar - Vec3d qp(jsh(X), jsh(Y), 0); + Vec3d qp(jsh(X), jsh(Y), gndlvl); auto ne = spindex.nearest(qp, 1).front(); const Head& nearhead = result.heads()[ne.second]; @@ -1263,7 +1348,7 @@ bool SLASupportTree::generate(const PointSet &points, } double d = distance(jp, jn); - if(jn(Z) <= 0 || d > max_len) break; + if(jn(Z) <= gndlvl || d > max_len) break; double chkd = ray_mesh_intersect(jp, dirv(jp, jn), emesh); if(chkd >= d) nearest_id = ne.second; @@ -1278,7 +1363,7 @@ bool SLASupportTree::generate(const PointSet &points, sidehead.transform(); Vec3d jsh = sidehead.junction_point(); - Vec3d jp2d = {jsh(X), jsh(Y), 0}; +// Vec3d jp2d = {jsh(X), jsh(Y), gndlvl}; SpatIndex spindex = pheadindex; long nearest_id = search_nearest(spindex, jsh); @@ -1286,7 +1371,7 @@ bool SLASupportTree::generate(const PointSet &points, // to connect the sidehead to the ground if(nearest_id < 0) { // Could not find a pillar, create one - Vec3d jp = jsh; jp(Z) = 0; + Vec3d jp = jsh; jp(Z) = gndlvl; result.add_pillar(sidehead.id, jp, pradius). add_base(cfg.base_height_mm, cfg.base_radius_mm); @@ -1571,28 +1656,12 @@ bool SLASupportTree::generate(const PointSet &points, void SLASupportTree::merged_mesh(TriangleMesh &outmesh) const { - const SLASupportTree::Impl& stree = get(); + outmesh.merge(get().merged_mesh()); +} - for(auto& head : stree.heads()) { - outmesh.merge(mesh(head.mesh)); - } - - for(auto& stick : stree.pillars()) { - outmesh.merge(mesh(stick.mesh)); - outmesh.merge(mesh(stick.base)); - } - - for(auto& j : stree.junctions()) { - outmesh.merge(mesh(j.mesh)); - } - - for(auto& cb : stree.compact_bridges()) { - outmesh.merge(mesh(cb.mesh)); - } - - for(auto& bs : stree.bridges()) { - outmesh.merge(mesh(bs.mesh)); - } +void SLASupportTree::merged_mesh_with_pad(TriangleMesh &outmesh) const { + merged_mesh(outmesh); + outmesh.merge(get_pad()); } template void slice_part(const T& inp, @@ -1616,7 +1685,7 @@ SlicedSupports SLASupportTree::slice(float layerh, float init_layerh) const { if(init_layerh < 0) init_layerh = layerh; auto& stree = get(); - const float modelh = stree.model_height; + const float modelh = stree.full_height(); std::vector heights; heights.reserve(size_t(modelh/layerh) + 1); for(float h = init_layerh; h <= modelh; h += layerh) { @@ -1640,10 +1709,24 @@ SlicedSupports SLASupportTree::slice(float layerh, float init_layerh) const return {}; } -// Here we should implement the support editing -void SLASupportTree::mouse_event(const MouseEvent &) +const TriangleMesh &SLASupportTree::add_pad(double min_wall_thickness_mm, + double min_wall_height_mm, + double max_merge_distance_mm, + double edge_radius_mm) const { + TriangleMesh mm; + merged_mesh(mm); + PoolConfig pcfg; +// pcfg.min_wall_thickness_mm = min_wall_thickness_mm; +// pcfg.min_wall_height_mm = min_wall_height_mm; +// pcfg.max_merge_distance_mm = max_merge_distance_mm; +// pcfg.edge_radius_mm = edge_radius_mm; + return m_impl->create_pad(mm, pcfg).tmesh; +} +const TriangleMesh &SLASupportTree::get_pad() const +{ + return m_impl->pad().tmesh; } SLASupportTree::SLASupportTree(const Model& model, diff --git a/src/libslic3r/SLA/SLASupportTree.hpp b/src/libslic3r/SLA/SLASupportTree.hpp index 3a1c5ef689..9d32bcaf92 100644 --- a/src/libslic3r/SLA/SLASupportTree.hpp +++ b/src/libslic3r/SLA/SLASupportTree.hpp @@ -60,6 +60,10 @@ struct SupportConfig { // The max length of a bridge in mm double max_bridge_length_mm = 15.0; + + // The elevation in Z direction upwards. This is the space between the pad + // and the model object's bounding box bottom. + double object_elevation_mm = 0; }; /// A Control structure for the support calculation. Consists of the status @@ -76,6 +80,7 @@ struct Controller { struct EigenMesh3D { Eigen::MatrixXd V; Eigen::MatrixXi F; + double ground_level = 0; // igl crashes with the following data types: // Eigen::Matrix V; @@ -100,7 +105,7 @@ EigenMesh3D to_eigenmesh(const Model& model); EigenMesh3D to_eigenmesh(const ModelObject& model); PointSet support_points(const Model& model); -PointSet support_points(const ModelObject& modelobject, size_t instance_id = 0); +PointSet support_points(const ModelObject& modelobject); /* ************************************************************************** */ @@ -111,24 +116,10 @@ public: SLASupportsStoppedException(): std::runtime_error("") {} }; -/// A simple type carrying mouse event info. For support editing purposes -struct MouseEvent { - enum Buttons { - M_RIGHT, M_LEFT, M_MIDDLE - } button; - - enum Type { - ENGAGE, RELEASE, MOVE - } type; - - Vec3d coords; -}; - /// The class containing mesh data for the generated supports. class SLASupportTree { class Impl; std::unique_ptr m_impl; - std::function m_vcallback; Impl& get() { return *m_impl; } const Impl& get() const { return *m_impl; } @@ -160,20 +151,23 @@ public: ~SLASupportTree(); /// Get the whole mesh united into the output TriangleMesh + /// WITHOUT THE PAD void merged_mesh(TriangleMesh& outmesh) const; + void merged_mesh_with_pad(TriangleMesh&) const; + /// Get the sliced 2d layers of the support geometry. SlicedSupports slice(float layerh, float init_layerh = -1.0) const; - /// The function to call when mouse events should be propagated to the - /// supports for editing - void mouse_event(const MouseEvent&); + /// Adding the "pad" (base pool) under the supports + const TriangleMesh& add_pad(double min_wall_thickness_mm, + double min_wall_height_mm, + double max_merge_distance_mm, + double edge_radius_mm) const; + + /// Get the pad geometry + const TriangleMesh& get_pad() const; - /// The provided callback will be called if the supports change their shape - /// or need to be repainted - inline void on_supports_changed(std::function callback) { - m_vcallback = callback; - } }; } diff --git a/src/libslic3r/SLAPrint.cpp b/src/libslic3r/SLAPrint.cpp index 0a0b0ff5c6..6b6455e182 100644 --- a/src/libslic3r/SLAPrint.cpp +++ b/src/libslic3r/SLAPrint.cpp @@ -70,7 +70,7 @@ void SLAPrint::clear() } SLAPrint::ApplyStatus SLAPrint::apply(const Model &model, - const DynamicPrintConfig &config) + const DynamicPrintConfig &config_in) { // if (m_objects.empty()) // return APPLY_STATUS_UNCHANGED; @@ -80,6 +80,11 @@ SLAPrint::ApplyStatus SLAPrint::apply(const Model &model, if(m_objects.empty() && model.objects.empty()) return APPLY_STATUS_UNCHANGED; + // Temporary: just to have to correct layer height for the rasterization + DynamicPrintConfig config(config_in); + config.normalize(); + auto lh = config.opt("layer_height"); + // Temporary quick fix, just invalidate everything. { for (SLAPrintObject *print_object : m_objects) { @@ -95,6 +100,7 @@ SLAPrint::ApplyStatus SLAPrint::apply(const Model &model, // Generate new SLAPrintObjects. for (ModelObject *model_object : m_model.objects) { auto po = new SLAPrintObject(this, model_object); + po->m_config.layer_height.set(lh); m_objects.emplace_back(po); for (ModelInstance *oinst : model_object->instances) { Point tr = Point::new_scale(oinst->get_offset()(X), @@ -138,7 +144,17 @@ void SLAPrint::process() slicer.slice(heights, &layers, [](){}); }; - auto support_points = [](SLAPrintObject&) { + auto support_points = [](SLAPrintObject& po) { + ModelObject& mo = *po.m_model_object; + if(!mo.sla_support_points.empty()) { + po.m_supportdata.reset(new SLAPrintObject::SupportData()); + po.m_supportdata->emesh = sla::to_eigenmesh(mo); + po.m_supportdata->support_points = sla::support_points(mo); + + std::cout << "support points copied " + << po.m_supportdata->support_points.rows() << std::endl; + } + // for(SLAPrintObject *po : pobjects) { // TODO: calculate automatic support points // po->m_supportdata->slice_cache contains the slices at this point @@ -149,7 +165,6 @@ void SLAPrint::process() auto support_tree = [this](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 @@ -161,7 +176,7 @@ void SLAPrint::process() }; ctl.stopcondition = [this](){ return canceled(); }; - supportd.support_tree_ptr.reset( + po.m_supportdata->support_tree_ptr.reset( new SLASupportTree(pts, emesh, scfg, ctl)); } catch(sla::SLASupportsStoppedException&) { @@ -171,13 +186,32 @@ void SLAPrint::process() }; // This step generates the sla base pad - auto base_pool = [](SLAPrintObject&) { + auto base_pool = [](SLAPrintObject& po) { + // this step can only go after the support tree has been created + // and before the supports had been sliced. (or the slicing has to be + // repeated) + if(po.is_step_done(slaposSupportTree) && + po.m_supportdata && + po.m_supportdata->support_tree_ptr) + { + double wt = po.m_config.pad_wall_thickness.getFloat(); + double h = po.m_config.pad_wall_height.getFloat(); + double md = po.m_config.pad_max_merge_distance.getFloat(); + double er = po.m_config.pad_edge_radius.getFloat(); + po.m_supportdata->support_tree_ptr->add_pad(wt, h, md, er); + } }; - // Slicing the support geometries similarly to the model slicing procedure - auto slice_supports = [](SLAPrintObject&) { - + // Slicing the support geometries similarly to the model slicing procedure. + // If the pad had been added previously (see step "base_pool" than it will + // be part of the slices) + auto slice_supports = [ilh](SLAPrintObject& po) { + auto& sd = po.m_supportdata; + if(sd && sd->support_tree_ptr) { + auto lh = float(po.m_config.layer_height.getFloat()); + sd->support_slices = sd->support_tree_ptr->slice(lh, ilh); + } }; // Rasterizing the model objects, and their supports @@ -198,27 +232,47 @@ void SLAPrint::process() // For all print objects, go through its initial layers and place them // into the layers hash - long long initlyridx = static_cast(scale_(ilh)); +// long long initlyridx = static_cast(scale_(ilh)); for(SLAPrintObject *o : m_objects) { - auto& oslices = o->m_model_slices; - auto& firstlyr = oslices.front(); - auto& initlevel = levels[initlyridx]; - initlevel.emplace_back(firstlyr, o->m_instances); - - // now push the support slices as well - // TODO - double lh = o->m_config.layer_height.getFloat(); - size_t li = 1; - for(auto lit = std::next(oslices.begin()); - lit != oslices.end(); - ++lit) - { - double h = ilh + li++ * lh; + std::vector & oslices = o->m_model_slices; + for(int i = 0; i < oslices.size(); ++i) { + double h = ilh + i * lh; long long lyridx = static_cast(scale_(h)); - auto& lyrs = levels[lyridx]; - lyrs.emplace_back(*lit, o->m_instances); + auto& lyrs = levels[lyridx]; // this initializes a new record + lyrs.emplace_back(oslices[i], o->m_instances); } + + if(o->m_supportdata) { // deal with the support slices if present + auto& sslices = o->m_supportdata->support_slices; + + for(int i = 0; i < sslices.size(); ++i) { + double h = ilh + i * lh; + long long lyridx = static_cast(scale_(h)); + auto& lyrs = levels[lyridx]; + lyrs.emplace_back(sslices[i], o->m_instances); + } + } + +// auto& oslices = o->m_model_slices; +// auto& firstlyr = oslices.front(); +// auto& initlevel = levels[initlyridx]; +// initlevel.emplace_back(firstlyr, o->m_instances); + +// // now push the support slices as well +// // TODO + +// double lh = o->m_config.layer_height.getFloat(); +// size_t li = 1; +// for(auto lit = std::next(oslices.begin()); +// lit != oslices.end(); +// ++lit) +// { +// double h = ilh + li++ * lh; +// long long lyridx = static_cast(scale_(h)); +// auto& lyrs = levels[lyridx]; +// lyrs.emplace_back(*lit, o->m_instances); +// } } // collect all the keys @@ -244,10 +298,11 @@ void SLAPrint::process() // Allocate space for all the layers SLAPrinter& printer = *m_printer; - printer.layers(unsigned(levels.size())); + auto lvlcnt = unsigned(levels.size()); + printer.layers(lvlcnt); // procedure to process one height level. This will run in parallel - auto process_level = [&keys, &levels, &printer](unsigned level_id) { + auto lvlfn = [&keys, &levels, &printer](unsigned level_id) { LayerRefs& lrange = levels[keys[level_id]]; for(auto& lyrref : lrange) { // for all layers in the current level @@ -273,12 +328,10 @@ void SLAPrint::process() }; // Sequential version (for testing) - // for(unsigned l = 0; l < levels.size(); ++l) process_level(l); + // for(unsigned l = 0; l < lvlcnt; ++l) process_level(l); // Print all the layers in parallel - tbb::parallel_for(0, - levels.size(), - process_level); + tbb::parallel_for(0, lvlcnt, lvlfn); }; using slaposFn = std::function; @@ -333,6 +386,9 @@ void SLAPrint::process() slapsRasterize, slapsValidate }; + // TODO: enable rasterizing + m_stepmask[slapsRasterize] = false; + for(size_t s = 0; s < print_program.size(); ++s) { auto currentstep = printsteps[s]; @@ -352,33 +408,39 @@ void SLAPrint::process() set_status(100, L("Slicing done")); } -void SLAPrint::render_supports(SLASupportRenderer &renderer) -{ - std::cout << "Would show the SLA supports" << std::endl; -} - 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() {} TriangleMesh SLAPrintObject::support_mesh() const { - return make_cube(10., 10., 10.); + TriangleMesh trm; + + if(m_supportdata && m_supportdata->support_tree_ptr) + m_supportdata->support_tree_ptr->merged_mesh(trm); + + trm.repair(); + + std::cout << "support mesh united and returned" << std::endl; + return trm; +// return make_cube(10., 10., 10.); } TriangleMesh SLAPrintObject::pad_mesh() const { - return make_cube(10., 10., 10.); + if(!m_supportdata || !m_supportdata->support_tree_ptr) { + std::cout << "Empty pad mesh returned.." << std::endl; + return TriangleMesh(); + } + + // FIXME: pad mesh is empty here for some reason. + return m_supportdata->support_tree_ptr->get_pad(); } } // namespace Slic3r diff --git a/src/libslic3r/SLAPrint.hpp b/src/libslic3r/SLAPrint.hpp index 1d1bb3bb9e..a1e317abc9 100644 --- a/src/libslic3r/SLAPrint.hpp +++ b/src/libslic3r/SLAPrint.hpp @@ -98,33 +98,6 @@ using PrintObjects = std::vector; class TriangleMesh; -class SLASupportRenderer { -public: - - virtual ~SLASupportRenderer() {} - - enum Buttons { - LEFT, RIGHT, MIDDLE - }; - - enum MType { - ENGAGE, RELEASE, HOVER - }; - - struct MouseEvt { - Buttons button; MType type; - }; - - using ClickCb = std::function; - using Mesh = TriangleMesh; - - virtual void add_pillar(const Mesh&, ClickCb on_mouse_evt) = 0; - virtual void add_head(const Mesh&, ClickCb on_mouse_evt) = 0; - virtual void add_bridge(const Mesh&, ClickCb on_mouse_evt) = 0; - virtual void add_junction(const Mesh&, ClickCb on_mouse_evt) = 0; - virtual void add_pad(const Mesh&, ClickCb on_mouse_evt) = 0; -}; - /** * @brief This class is the high level FSM for the SLA printing process. * @@ -156,11 +129,8 @@ public: ApplyStatus apply(const Model &model, const DynamicPrintConfig &config) override; void process() override; - void render_supports(SLASupportRenderer& renderer); - template void export_raster(const std::string& fname) { if(m_printer) m_printer->save(fname); - std::cout << "Would export the SLA raster" << std::endl; } const PrintObjects& objects() const { return m_objects; } diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 3715843fb8..dcc02e56f1 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -1871,8 +1871,21 @@ void Plater::priv::on_process_completed(wxCommandEvent &evt) case ptSLA: // Update the SLAPrint from the current Model, so that the reload_scene() // pulls the correct data. - if (this->update_background_process() & UPDATE_BACKGROUND_PROCESS_RESTART) - this->schedule_background_process(); +// if (this->update_background_process() & UPDATE_BACKGROUND_PROCESS_RESTART) +// this->schedule_background_process(); + + { +// for(SLAPrintObject * po: sla_print.objects()) { +// TriangleMesh&& suppmesh = po->support_mesh(); +// if(suppmesh.facets_count() > 0) { +// ModelObject* mo = model.add_object(); +// for(const SLAPrintObject::Instance& inst : po->instances() ) { +// mo->add_instance(*(mo->instances[inst.instance_id.id])); +// mo->add_volume(suppmesh); +// } +// } +// } + } _3DScene::reload_scene(canvas3D, true); break; }