Incorporate individual support point radius.
This commit is contained in:
parent
61f8e4f6f7
commit
43f03b8032
5 changed files with 462 additions and 451 deletions
|
@ -2,6 +2,7 @@
|
||||||
#define SLACOMMON_HPP
|
#define SLACOMMON_HPP
|
||||||
|
|
||||||
#include <Eigen/Geometry>
|
#include <Eigen/Geometry>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
// #define SLIC3R_SLA_NEEDS_WINDTREE
|
// #define SLIC3R_SLA_NEEDS_WINDTREE
|
||||||
|
|
||||||
|
@ -36,7 +37,6 @@ struct SupportPoint {
|
||||||
bool operator!=(const SupportPoint& sp) const { return !(sp == (*this)); }
|
bool operator!=(const SupportPoint& sp) const { return !(sp == (*this)); }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/// An index-triangle structure for libIGL functions. Also serves as an
|
/// An index-triangle structure for libIGL functions. Also serves as an
|
||||||
/// alternative (raw) input format for the SLASupportTree
|
/// alternative (raw) input format for the SLASupportTree
|
||||||
/*struct EigenMesh3D {
|
/*struct EigenMesh3D {
|
||||||
|
@ -125,6 +125,8 @@ public:
|
||||||
|
|
||||||
bool inside(const Vec3d& p) const;
|
bool inside(const Vec3d& p) const;
|
||||||
#endif /* SLIC3R_SLA_NEEDS_WINDTREE */
|
#endif /* SLIC3R_SLA_NEEDS_WINDTREE */
|
||||||
|
|
||||||
|
double squared_distance(const Vec3d& p, int& i, Vec3d& c) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -134,4 +136,4 @@ public:
|
||||||
} // namespace Slic3r
|
} // namespace Slic3r
|
||||||
|
|
||||||
|
|
||||||
#endif // SLASUPPORTTREE_HPP
|
#endif // SLASUPPORTTREE_HPP
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -74,7 +74,7 @@ struct SupportConfig {
|
||||||
double base_height_mm = 1.0;
|
double base_height_mm = 1.0;
|
||||||
|
|
||||||
// The default angle for connecting support sticks and junctions.
|
// The default angle for connecting support sticks and junctions.
|
||||||
double tilt = M_PI/4;
|
double head_slope = M_PI/4;
|
||||||
|
|
||||||
// The max length of a bridge in mm
|
// The max length of a bridge in mm
|
||||||
double max_bridge_length_mm = 15.0;
|
double max_bridge_length_mm = 15.0;
|
||||||
|
@ -116,18 +116,11 @@ using PointSet = Eigen::MatrixXd;
|
||||||
//EigenMesh3D to_eigenmesh(const ModelObject& model);
|
//EigenMesh3D to_eigenmesh(const ModelObject& model);
|
||||||
|
|
||||||
// Simple conversion of 'vector of points' to an Eigen matrix
|
// Simple conversion of 'vector of points' to an Eigen matrix
|
||||||
PointSet to_point_set(const std::vector<sla::SupportPoint>&);
|
//PointSet to_point_set(const std::vector<sla::SupportPoint>&);
|
||||||
|
|
||||||
|
|
||||||
/* ************************************************************************** */
|
/* ************************************************************************** */
|
||||||
|
|
||||||
/// Just a wrapper to the runtime error to be recognizable in try blocks
|
|
||||||
class SLASupportsStoppedException: public std::runtime_error {
|
|
||||||
public:
|
|
||||||
using std::runtime_error::runtime_error;
|
|
||||||
SLASupportsStoppedException();
|
|
||||||
};
|
|
||||||
|
|
||||||
/// The class containing mesh data for the generated supports.
|
/// The class containing mesh data for the generated supports.
|
||||||
class SLASupportTree {
|
class SLASupportTree {
|
||||||
class Impl;
|
class Impl;
|
||||||
|
@ -141,7 +134,12 @@ class SLASupportTree {
|
||||||
const Controller&);
|
const Controller&);
|
||||||
|
|
||||||
/// Generate the 3D supports for a model intended for SLA print.
|
/// Generate the 3D supports for a model intended for SLA print.
|
||||||
bool generate(const PointSet& pts,
|
bool generate(const std::vector<SupportPoint>& pts,
|
||||||
|
const EigenMesh3D& mesh,
|
||||||
|
const SupportConfig& cfg = {},
|
||||||
|
const Controller& ctl = {});
|
||||||
|
|
||||||
|
bool _generate(const std::vector<SupportPoint>& pts,
|
||||||
const EigenMesh3D& mesh,
|
const EigenMesh3D& mesh,
|
||||||
const SupportConfig& cfg = {},
|
const SupportConfig& cfg = {},
|
||||||
const Controller& ctl = {});
|
const Controller& ctl = {});
|
||||||
|
@ -149,7 +147,7 @@ public:
|
||||||
|
|
||||||
SLASupportTree();
|
SLASupportTree();
|
||||||
|
|
||||||
SLASupportTree(const PointSet& pts,
|
SLASupportTree(const std::vector<SupportPoint>& pts,
|
||||||
const EigenMesh3D& em,
|
const EigenMesh3D& em,
|
||||||
const SupportConfig& cfg = {},
|
const SupportConfig& cfg = {},
|
||||||
const Controller& ctl = {});
|
const Controller& ctl = {});
|
||||||
|
|
|
@ -17,6 +17,8 @@
|
||||||
#include <igl/remove_duplicate_vertices.h>
|
#include <igl/remove_duplicate_vertices.h>
|
||||||
#include <igl/signed_distance.h>
|
#include <igl/signed_distance.h>
|
||||||
|
|
||||||
|
#include <tbb/parallel_for.h>
|
||||||
|
|
||||||
#include "SLASpatIndex.hpp"
|
#include "SLASpatIndex.hpp"
|
||||||
#include "ClipperUtils.hpp"
|
#include "ClipperUtils.hpp"
|
||||||
|
|
||||||
|
@ -186,6 +188,15 @@ bool EigenMesh3D::inside(const Vec3d &p) const {
|
||||||
}
|
}
|
||||||
#endif /* SLIC3R_SLA_NEEDS_WINDTREE */
|
#endif /* SLIC3R_SLA_NEEDS_WINDTREE */
|
||||||
|
|
||||||
|
double EigenMesh3D::squared_distance(const Vec3d &p, int& i, Vec3d& c) const {
|
||||||
|
double sqdst = 0;
|
||||||
|
Eigen::Matrix<double, 1, 3> pp = p;
|
||||||
|
Eigen::Matrix<double, 1, 3> cc;
|
||||||
|
sqdst = m_aabb->squared_distance(m_V, m_F, pp, i, cc);
|
||||||
|
c = cc;
|
||||||
|
return sqdst;
|
||||||
|
}
|
||||||
|
|
||||||
/* ****************************************************************************
|
/* ****************************************************************************
|
||||||
* Misc functions
|
* Misc functions
|
||||||
* ****************************************************************************/
|
* ****************************************************************************/
|
||||||
|
@ -208,21 +219,40 @@ template<class Vec> double distance(const Vec& pp1, const Vec& pp2) {
|
||||||
PointSet normals(const PointSet& points,
|
PointSet normals(const PointSet& points,
|
||||||
const EigenMesh3D& mesh,
|
const EigenMesh3D& mesh,
|
||||||
double eps,
|
double eps,
|
||||||
std::function<void()> throw_on_cancel)
|
std::function<void()> throw_on_cancel,
|
||||||
|
const std::vector<unsigned>& pt_indices = {})
|
||||||
{
|
{
|
||||||
if(points.rows() == 0 || mesh.V().rows() == 0 || mesh.F().rows() == 0)
|
if(points.rows() == 0 || mesh.V().rows() == 0 || mesh.F().rows() == 0)
|
||||||
return {};
|
return {};
|
||||||
|
|
||||||
Eigen::VectorXd dists;
|
std::vector<unsigned> range = pt_indices;
|
||||||
Eigen::VectorXi I;
|
if(range.empty()) {
|
||||||
PointSet C;
|
range.resize(size_t(points.rows()), 0);
|
||||||
|
std::iota(range.begin(), range.end(), 0);
|
||||||
|
}
|
||||||
|
|
||||||
igl::point_mesh_squared_distance( points, mesh.V(), mesh.F(), dists, I, C);
|
std::vector<double> dists(range.size());
|
||||||
|
std::vector<int> I(range.size());
|
||||||
|
PointSet C(Eigen::Index(range.size()), 3);
|
||||||
|
|
||||||
PointSet ret(I.rows(), 3);
|
tbb::parallel_for(size_t(0), range.size(),
|
||||||
for(int i = 0; i < I.rows(); i++) {
|
[&range, &mesh, &points, &dists, &I, &C](size_t idx)
|
||||||
|
{
|
||||||
|
auto eidx = Eigen::Index(range[idx]);
|
||||||
|
int i = 0;
|
||||||
|
Vec3d c;
|
||||||
|
dists[idx] = mesh.squared_distance(points.row(eidx), i, c);
|
||||||
|
C.row(eidx) = c;
|
||||||
|
I[range[idx]] = i;
|
||||||
|
});
|
||||||
|
|
||||||
|
// igl::point_mesh_squared_distance( points, mesh.V(), mesh.F(), dists, I, C);
|
||||||
|
|
||||||
|
|
||||||
|
PointSet ret(I.size(), 3);
|
||||||
|
for(unsigned i = 0; i < I.size(); i++) {
|
||||||
throw_on_cancel();
|
throw_on_cancel();
|
||||||
auto idx = I(i);
|
auto idx = I[i];
|
||||||
auto trindex = mesh.F().row(idx);
|
auto trindex = mesh.F().row(idx);
|
||||||
|
|
||||||
const Vec3d& p1 = mesh.V().row(trindex(0));
|
const Vec3d& p1 = mesh.V().row(trindex(0));
|
||||||
|
@ -332,7 +362,7 @@ PointSet normals(const PointSet& points,
|
||||||
ClusteredPoints cluster(
|
ClusteredPoints cluster(
|
||||||
const sla::PointSet& points,
|
const sla::PointSet& points,
|
||||||
std::function<bool(const SpatElement&, const SpatElement&)> pred,
|
std::function<bool(const SpatElement&, const SpatElement&)> pred,
|
||||||
unsigned max_points = 0)
|
unsigned max_points = 0, const std::vector<unsigned>& indices = {})
|
||||||
{
|
{
|
||||||
|
|
||||||
namespace bgi = boost::geometry::index;
|
namespace bgi = boost::geometry::index;
|
||||||
|
@ -342,8 +372,12 @@ ClusteredPoints cluster(
|
||||||
Index3D sindex;
|
Index3D sindex;
|
||||||
|
|
||||||
// Build the index
|
// Build the index
|
||||||
for(unsigned idx = 0; idx < points.rows(); idx++)
|
if(indices.empty())
|
||||||
sindex.insert( std::make_pair(points.row(idx), idx));
|
for(unsigned idx = 0; idx < points.rows(); idx++)
|
||||||
|
sindex.insert( std::make_pair(points.row(idx), idx));
|
||||||
|
else
|
||||||
|
for(unsigned idx : indices)
|
||||||
|
sindex.insert( std::make_pair(points.row(idx), idx));
|
||||||
|
|
||||||
using Elems = std::vector<SpatElement>;
|
using Elems = std::vector<SpatElement>;
|
||||||
|
|
||||||
|
|
|
@ -521,7 +521,7 @@ sla::SupportConfig make_support_cfg(const SLAPrintObjectConfig& c) {
|
||||||
scfg.head_penetration_mm = c.support_head_penetration.getFloat();
|
scfg.head_penetration_mm = c.support_head_penetration.getFloat();
|
||||||
scfg.head_width_mm = c.support_head_width.getFloat();
|
scfg.head_width_mm = c.support_head_width.getFloat();
|
||||||
scfg.object_elevation_mm = c.support_object_elevation.getFloat();
|
scfg.object_elevation_mm = c.support_object_elevation.getFloat();
|
||||||
scfg.tilt = c.support_critical_angle.getFloat() * PI / 180.0 ;
|
scfg.head_slope = c.support_critical_angle.getFloat() * PI / 180.0 ;
|
||||||
scfg.max_bridge_length_mm = c.support_max_bridge_length.getFloat();
|
scfg.max_bridge_length_mm = c.support_max_bridge_length.getFloat();
|
||||||
scfg.headless_pillar_radius_mm = 0.375*c.support_pillar_diameter.getFloat();
|
scfg.headless_pillar_radius_mm = 0.375*c.support_pillar_diameter.getFloat();
|
||||||
switch(c.support_pillar_connection_mode.getInt()) {
|
switch(c.support_pillar_connection_mode.getInt()) {
|
||||||
|
@ -684,54 +684,52 @@ void SLAPrint::process()
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
sla::SupportConfig scfg = make_support_cfg(po.m_config);
|
||||||
sla::SupportConfig scfg = make_support_cfg(po.m_config);
|
sla::Controller ctl;
|
||||||
sla::Controller ctl;
|
|
||||||
|
|
||||||
// some magic to scale the status values coming from the support
|
// some magic to scale the status values coming from the support
|
||||||
// tree creation into the whole print process
|
// tree creation into the whole print process
|
||||||
auto stfirst = OBJ_STEP_LEVELS.begin();
|
auto stfirst = OBJ_STEP_LEVELS.begin();
|
||||||
auto stthis = stfirst + slaposSupportTree;
|
auto stthis = stfirst + slaposSupportTree;
|
||||||
// we need to add up the status portions until this operation
|
// we need to add up the status portions until this operation
|
||||||
int init = std::accumulate(stfirst, stthis, 0);
|
int init = std::accumulate(stfirst, stthis, 0);
|
||||||
init = int(init * ostepd); // scale the init portion
|
init = int(init * ostepd); // scale the init portion
|
||||||
|
|
||||||
// scaling for the sub operations
|
// scaling for the sub operations
|
||||||
double d = *stthis / (objcount * 100.0);
|
double d = *stthis / (objcount * 100.0);
|
||||||
|
|
||||||
ctl.statuscb = [this, init, d](unsigned st, const std::string& msg)
|
ctl.statuscb = [this, init, d](unsigned st, const std::string& msg)
|
||||||
{
|
{
|
||||||
//FIXME this status line scaling does not seem to be correct.
|
//FIXME this status line scaling does not seem to be correct.
|
||||||
// How does it account for an increasing object index?
|
// How does it account for an increasing object index?
|
||||||
report_status(*this, int(init + st*d), msg);
|
report_status(*this, int(init + st*d), msg);
|
||||||
};
|
};
|
||||||
|
|
||||||
ctl.stopcondition = [this](){ return canceled(); };
|
ctl.stopcondition = [this](){ return canceled(); };
|
||||||
ctl.cancelfn = [this]() { throw_if_canceled(); };
|
ctl.cancelfn = [this]() { throw_if_canceled(); };
|
||||||
|
|
||||||
po.m_supportdata->support_tree_ptr.reset(
|
po.m_supportdata->support_tree_ptr.reset(
|
||||||
new SLASupportTree(sla::to_point_set(po.m_supportdata->support_points),
|
new SLASupportTree(po.m_supportdata->support_points,
|
||||||
po.m_supportdata->emesh, scfg, ctl));
|
po.m_supportdata->emesh, scfg, ctl));
|
||||||
|
|
||||||
// Create the unified mesh
|
throw_if_canceled();
|
||||||
auto rc = SlicingStatus::RELOAD_SCENE;
|
|
||||||
|
|
||||||
// This is to prevent "Done." being displayed during merged_mesh()
|
// Create the unified mesh
|
||||||
report_status(*this, -1, L("Visualizing supports"));
|
auto rc = SlicingStatus::RELOAD_SCENE;
|
||||||
po.m_supportdata->support_tree_ptr->merged_mesh();
|
|
||||||
|
|
||||||
BOOST_LOG_TRIVIAL(debug) << "Processed support point count "
|
// This is to prevent "Done." being displayed during merged_mesh()
|
||||||
<< po.m_supportdata->support_points.size();
|
report_status(*this, -1, L("Visualizing supports"));
|
||||||
|
po.m_supportdata->support_tree_ptr->merged_mesh();
|
||||||
|
|
||||||
// Check the mesh for later troubleshooting.
|
BOOST_LOG_TRIVIAL(debug) << "Processed support point count "
|
||||||
if(po.support_mesh().empty())
|
<< po.m_supportdata->support_points.size();
|
||||||
BOOST_LOG_TRIVIAL(warning) << "Support mesh is empty";
|
|
||||||
|
// Check the mesh for later troubleshooting.
|
||||||
|
if(po.support_mesh().empty())
|
||||||
|
BOOST_LOG_TRIVIAL(warning) << "Support mesh is empty";
|
||||||
|
|
||||||
|
report_status(*this, -1, L("Visualizing supports"), rc);
|
||||||
|
|
||||||
report_status(*this, -1, L("Visualizing supports"), rc);
|
|
||||||
} catch(sla::SLASupportsStoppedException&) {
|
|
||||||
// no need to rethrow
|
|
||||||
// throw_if_canceled();
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// This step generates the sla base pad
|
// This step generates the sla base pad
|
||||||
|
|
Loading…
Reference in a new issue