mirror of
https://github.com/SoftFever/OrcaSlicer.git
synced 2025-07-11 16:57:53 -06:00
Many major issues solved. Performance may be degraded.
This commit is contained in:
parent
17a1f829cd
commit
7c839b8469
4 changed files with 29 additions and 40 deletions
|
@ -510,7 +510,6 @@ struct CompactBridge {
|
||||||
|
|
||||||
// A wrapper struct around the base pool (pad)
|
// A wrapper struct around the base pool (pad)
|
||||||
struct Pad {
|
struct Pad {
|
||||||
// Contour3D mesh;
|
|
||||||
TriangleMesh tmesh;
|
TriangleMesh tmesh;
|
||||||
PoolConfig cfg;
|
PoolConfig cfg;
|
||||||
double zlevel = 0;
|
double zlevel = 0;
|
||||||
|
@ -588,7 +587,7 @@ double pinhead_mesh_intersect(const Vec3d& s,
|
||||||
double r_back,
|
double r_back,
|
||||||
double width,
|
double width,
|
||||||
const EigenMesh3D& m,
|
const EigenMesh3D& m,
|
||||||
unsigned samples = 8,
|
unsigned samples = 4,
|
||||||
double safety_distance = 0.05)
|
double safety_distance = 0.05)
|
||||||
{
|
{
|
||||||
// method based on:
|
// method based on:
|
||||||
|
@ -603,6 +602,7 @@ double pinhead_mesh_intersect(const Vec3d& s,
|
||||||
// inner surface of the mesh.
|
// inner surface of the mesh.
|
||||||
Vec3d v = dir; // Our direction (axis)
|
Vec3d v = dir; // Our direction (axis)
|
||||||
Vec3d c = s + width * dir;
|
Vec3d c = s + width * dir;
|
||||||
|
const double& sd = safety_distance;
|
||||||
|
|
||||||
// Two vectors that will be perpendicular to each other and to the axis.
|
// Two vectors that will be perpendicular to each other and to the axis.
|
||||||
// Values for a(X) and a(Y) are now arbitrary, a(Z) is just a placeholder.
|
// Values for a(X) and a(Y) are now arbitrary, a(Z) is just a placeholder.
|
||||||
|
@ -626,10 +626,10 @@ double pinhead_mesh_intersect(const Vec3d& s,
|
||||||
double cosphi = std::cos(phi);
|
double cosphi = std::cos(phi);
|
||||||
|
|
||||||
// Let's have a safety coefficient for the radiuses.
|
// Let's have a safety coefficient for the radiuses.
|
||||||
double rpscos = (safety_distance + r_pin) * cosphi;
|
double rpscos = (sd + r_pin) * cosphi;
|
||||||
double rpssin = (safety_distance + r_pin) * sinphi;
|
double rpssin = (sd + r_pin) * sinphi;
|
||||||
double rpbcos = (safety_distance + r_back) * cosphi;
|
double rpbcos = (sd + r_back) * cosphi;
|
||||||
double rpbsin = (safety_distance + r_back) * sinphi;
|
double rpbsin = (sd + r_back) * sinphi;
|
||||||
|
|
||||||
// Point on the circle on the pin sphere
|
// Point on the circle on the pin sphere
|
||||||
Vec3d ps(s(X) + rpscos * a(X) + rpssin * b(X),
|
Vec3d ps(s(X) + rpscos * a(X) + rpssin * b(X),
|
||||||
|
@ -639,17 +639,15 @@ double pinhead_mesh_intersect(const Vec3d& s,
|
||||||
// Point ps is not on mesh but can be inside or outside as well. This
|
// Point ps is not on mesh but can be inside or outside as well. This
|
||||||
// would cause many problems with ray-casting. So we query the closest
|
// would cause many problems with ray-casting. So we query the closest
|
||||||
// point on the mesh to this.
|
// point on the mesh to this.
|
||||||
auto result = m.signed_distance(ps);
|
auto psq = m.signed_distance(ps);
|
||||||
|
|
||||||
// This is the point on the circle on the back sphere
|
// This is the point on the circle on the back sphere
|
||||||
Vec3d p(c(X) + rpbcos * a(X) + rpbsin * b(X),
|
Vec3d p(c(X) + rpbcos * a(X) + rpbsin * b(X),
|
||||||
c(Y) + rpbcos * a(Y) + rpbsin * b(Y),
|
c(Y) + rpbcos * a(Y) + rpbsin * b(Y),
|
||||||
c(Z) + rpbcos * a(Z) + rpbsin * b(Z));
|
c(Z) + rpbcos * a(Z) + rpbsin * b(Z));
|
||||||
|
|
||||||
if(!m.inside(p)) {
|
Vec3d n = (p - psq.point_on_mesh()).normalized();
|
||||||
Vec3d n = (p - result.point_on_mesh() + 0.01 * dir).normalized();
|
phi = m.query_ray_hit(psq.point_on_mesh() + sd*n, n);
|
||||||
phi = m.query_ray_hit(result.point_on_mesh(), n);
|
|
||||||
} else phi = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
auto mit = std::min_element(phis.begin(), phis.end());
|
auto mit = std::min_element(phis.begin(), phis.end());
|
||||||
|
@ -661,11 +659,12 @@ double bridge_mesh_intersect(const Vec3d& s,
|
||||||
const Vec3d& dir,
|
const Vec3d& dir,
|
||||||
double r,
|
double r,
|
||||||
const EigenMesh3D& m,
|
const EigenMesh3D& m,
|
||||||
unsigned samples = 8,
|
unsigned samples = 4,
|
||||||
double safety_distance = 0.05)
|
double safety_distance = 0.05)
|
||||||
{
|
{
|
||||||
// helper vector calculations
|
// helper vector calculations
|
||||||
Vec3d a(0, 1, 0), b;
|
Vec3d a(0, 1, 0), b;
|
||||||
|
const double& sd = safety_distance;
|
||||||
|
|
||||||
a(Z) = -(dir(X)*a(X) + dir(Y)*a(Y)) / dir(Z);
|
a(Z) = -(dir(X)*a(X) + dir(Y)*a(Y)) / dir(Z);
|
||||||
b = a.cross(dir);
|
b = a.cross(dir);
|
||||||
|
@ -679,8 +678,8 @@ double bridge_mesh_intersect(const Vec3d& s,
|
||||||
double cosphi = std::cos(phi);
|
double cosphi = std::cos(phi);
|
||||||
|
|
||||||
// Let's have a safety coefficient for the radiuses.
|
// Let's have a safety coefficient for the radiuses.
|
||||||
double rcos = (safety_distance + r) * cosphi;
|
double rcos = (sd + r) * cosphi;
|
||||||
double rsin = (safety_distance + r) * sinphi;
|
double rsin = (sd + r) * sinphi;
|
||||||
|
|
||||||
// Point on the circle on the pin sphere
|
// Point on the circle on the pin sphere
|
||||||
Vec3d p (s(X) + rcos * a(X) + rsin * b(X),
|
Vec3d p (s(X) + rcos * a(X) + rsin * b(X),
|
||||||
|
@ -689,7 +688,9 @@ double bridge_mesh_intersect(const Vec3d& s,
|
||||||
|
|
||||||
auto result = m.signed_distance(p);
|
auto result = m.signed_distance(p);
|
||||||
|
|
||||||
phi = m.query_ray_hit(result.point_on_mesh() + 0.05*dir, dir);
|
Vec3d sp = result.value() < 0 ? result.point_on_mesh() : p;
|
||||||
|
|
||||||
|
phi = m.query_ray_hit(sp + sd*dir, dir);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto mit = std::min_element(phis.begin(), phis.end());
|
auto mit = std::min_element(phis.begin(), phis.end());
|
||||||
|
@ -1560,6 +1561,8 @@ bool SLASupportTree::generate(const PointSet &points,
|
||||||
}
|
}
|
||||||
|
|
||||||
double d = distance(jp, jn);
|
double d = distance(jp, jn);
|
||||||
|
|
||||||
|
if(jn(Z) <= gndlvl + 2*cfg.head_width_mm || d > max_len)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
double chkd = bridge_mesh_intersect(jp, dirv(jp, jn),
|
double chkd = bridge_mesh_intersect(jp, dirv(jp, jn),
|
||||||
|
@ -1784,16 +1787,15 @@ bool SLASupportTree::generate(const PointSet &points,
|
||||||
// We will sink the pins into the model surface for a distance of 1/3 of
|
// We will sink the pins into the model surface for a distance of 1/3 of
|
||||||
// the pin radius
|
// the pin radius
|
||||||
for(int i = 0; i < headless_pts.rows(); i++) { tifcl();
|
for(int i = 0; i < headless_pts.rows(); i++) { tifcl();
|
||||||
Vec3d sp = headless_pts.row(i);
|
Vec3d sph = headless_pts.row(i); // Exact support position
|
||||||
|
Vec3d n = headless_norm.row(i); // mesh outward normal
|
||||||
Vec3d n = headless_norm.row(i);
|
Vec3d sp = sph - n * HWIDTH_MM; // stick head start point
|
||||||
sp = sp - n * HWIDTH_MM;
|
|
||||||
|
|
||||||
Vec3d dir = {0, 0, -1};
|
Vec3d dir = {0, 0, -1};
|
||||||
Vec3d sj = sp + R * n;
|
Vec3d sj = sp + R * n; // stick start point
|
||||||
|
|
||||||
// This is only for checking
|
// This is only for checking
|
||||||
double idist = bridge_mesh_intersect(sj, dir, R, emesh);
|
double idist = bridge_mesh_intersect(sph, dir, R, emesh);
|
||||||
double dist = ray_mesh_intersect(sj, dir, emesh);
|
double dist = ray_mesh_intersect(sj, dir, emesh);
|
||||||
|
|
||||||
if(std::isinf(idist) || std::isnan(idist) || idist < 2*R ||
|
if(std::isinf(idist) || std::isnan(idist) || idist < 2*R ||
|
||||||
|
|
|
@ -114,14 +114,12 @@ class EigenMesh3D {
|
||||||
std::unique_ptr<AABBImpl> m_aabb;
|
std::unique_ptr<AABBImpl> m_aabb;
|
||||||
public:
|
public:
|
||||||
|
|
||||||
EigenMesh3D();
|
|
||||||
EigenMesh3D(const TriangleMesh&);
|
EigenMesh3D(const TriangleMesh&);
|
||||||
|
|
||||||
~EigenMesh3D();
|
|
||||||
|
|
||||||
EigenMesh3D(const EigenMesh3D& other);
|
EigenMesh3D(const EigenMesh3D& other);
|
||||||
EigenMesh3D& operator=(const EigenMesh3D&);
|
EigenMesh3D& operator=(const EigenMesh3D&);
|
||||||
|
|
||||||
|
~EigenMesh3D();
|
||||||
|
|
||||||
inline double ground_level() const { return m_ground_level; }
|
inline double ground_level() const { return m_ground_level; }
|
||||||
|
|
||||||
inline const Eigen::MatrixXd& V() const { return m_V; }
|
inline const Eigen::MatrixXd& V() const { return m_V; }
|
||||||
|
|
|
@ -98,8 +98,6 @@ public:
|
||||||
igl::WindingNumberAABB<Vec3d, Eigen::MatrixXd, Eigen::MatrixXi> windtree;
|
igl::WindingNumberAABB<Vec3d, Eigen::MatrixXd, Eigen::MatrixXi> windtree;
|
||||||
};
|
};
|
||||||
|
|
||||||
EigenMesh3D::EigenMesh3D(): m_aabb(new AABBImpl()) {}
|
|
||||||
|
|
||||||
EigenMesh3D::EigenMesh3D(const TriangleMesh& tmesh): m_aabb(new AABBImpl()) {
|
EigenMesh3D::EigenMesh3D(const TriangleMesh& tmesh): m_aabb(new AABBImpl()) {
|
||||||
static const double dEPS = 1e-6;
|
static const double dEPS = 1e-6;
|
||||||
|
|
||||||
|
@ -138,9 +136,7 @@ EigenMesh3D::EigenMesh3D(const TriangleMesh& tmesh): m_aabb(new AABBImpl()) {
|
||||||
|
|
||||||
// Build the AABB accelaration tree
|
// Build the AABB accelaration tree
|
||||||
m_aabb->init(m_V, m_F);
|
m_aabb->init(m_V, m_F);
|
||||||
|
|
||||||
m_aabb->windtree.set_mesh(m_V, m_F);
|
m_aabb->windtree.set_mesh(m_V, m_F);
|
||||||
m_aabb->windtree.init();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
EigenMesh3D::~EigenMesh3D() {}
|
EigenMesh3D::~EigenMesh3D() {}
|
||||||
|
@ -207,15 +203,6 @@ PointSet normals(const PointSet& points, const EigenMesh3D& mesh,
|
||||||
Eigen::VectorXi I;
|
Eigen::VectorXi I;
|
||||||
PointSet C;
|
PointSet C;
|
||||||
|
|
||||||
// We need to remove duplicate vertices and have a true index triangle
|
|
||||||
// structure
|
|
||||||
/*
|
|
||||||
EigenMesh3D mesh;
|
|
||||||
Eigen::VectorXi SVI, SVJ;
|
|
||||||
static const double dEPS = 1e-6;
|
|
||||||
igl::remove_duplicate_vertices(emesh.V, emesh.F, dEPS,
|
|
||||||
mesh.V, SVI, SVJ, mesh.F);*/
|
|
||||||
|
|
||||||
igl::point_mesh_squared_distance( points, mesh.V(), mesh.F(), dists, I, C);
|
igl::point_mesh_squared_distance( points, mesh.V(), mesh.F(), dists, I, C);
|
||||||
|
|
||||||
PointSet ret(I.rows(), 3);
|
PointSet ret(I.rows(), 3);
|
||||||
|
|
|
@ -29,6 +29,8 @@ public:
|
||||||
SupportTreePtr support_tree_ptr; // the supports
|
SupportTreePtr support_tree_ptr; // the supports
|
||||||
SlicedSupports support_slices; // sliced supports
|
SlicedSupports support_slices; // sliced supports
|
||||||
std::vector<LevelID> level_ids;
|
std::vector<LevelID> level_ids;
|
||||||
|
|
||||||
|
inline SupportData(const TriangleMesh& trmesh): emesh(trmesh) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
@ -503,8 +505,8 @@ void SLAPrint::process()
|
||||||
// support points. Then we sprinkle the rest of the mesh.
|
// support points. Then we sprinkle the rest of the mesh.
|
||||||
auto support_points = [this, ilh](SLAPrintObject& po) {
|
auto support_points = [this, ilh](SLAPrintObject& po) {
|
||||||
const ModelObject& mo = *po.m_model_object;
|
const ModelObject& mo = *po.m_model_object;
|
||||||
po.m_supportdata.reset(new SLAPrintObject::SupportData());
|
po.m_supportdata.reset(
|
||||||
po.m_supportdata->emesh = EigenMesh3D(po.transformed_mesh());
|
new SLAPrintObject::SupportData(po.transformed_mesh()) );
|
||||||
|
|
||||||
// If supports are disabled, we can skip the model scan.
|
// If supports are disabled, we can skip the model scan.
|
||||||
if(!po.m_config.supports_enable.getBool()) return;
|
if(!po.m_config.supports_enable.getBool()) return;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue