Fix for erroneous support slicing.

Adding upper and lower closure for pillars and bridges.
This commit is contained in:
tamasmeszaros 2019-01-28 11:58:25 +01:00
parent 4a5cff3ee2
commit 61d59a7a2e
2 changed files with 55 additions and 5 deletions

View File

@ -5,8 +5,8 @@
#include <functional> #include <functional>
#include <numeric> #include <numeric>
#include "ExPolygon.hpp" #include <libslic3r/ExPolygon.hpp>
#include "TriangleMesh.hpp" #include <libslic3r/TriangleMesh.hpp>
namespace Slic3r { namespace Slic3r {
namespace sla { namespace sla {
@ -53,7 +53,7 @@ struct Contour3D {
void merge(const Contour3D& ctr) { void merge(const Contour3D& ctr) {
auto s3 = coord_t(points.size()); auto s3 = coord_t(points.size());
auto s = coord_t(indices.size()); auto s = indices.size();
points.insert(points.end(), ctr.points.begin(), ctr.points.end()); points.insert(points.end(), ctr.points.begin(), ctr.points.end());
indices.insert(indices.end(), ctr.indices.begin(), ctr.indices.end()); indices.insert(indices.end(), ctr.indices.begin(), ctr.indices.end());
@ -62,6 +62,17 @@ struct Contour3D {
auto& idx = indices[n]; x(idx) += s3; y(idx) += s3; z(idx) += s3; auto& idx = indices[n]; x(idx) += s3; y(idx) += s3; z(idx) += s3;
} }
} }
// Write the index triangle structure to OBJ file for debugging purposes.
void to_obj(std::ostream& stream) {
for(auto& p : points) {
stream << "v " << p.transpose() << "\n";
}
for(auto& f : indices) {
stream << "f " << (f + Vec3i(1, 1, 1)).transpose() << "\n";
}
}
}; };
//using PointSet = Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic, Eigen::DontAlign>; //Eigen::MatrixXd; //using PointSet = Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic, Eigen::DontAlign>; //Eigen::MatrixXd;

View File

@ -9,8 +9,8 @@
#include "SLASpatIndex.hpp" #include "SLASpatIndex.hpp"
#include "SLABasePool.hpp" #include "SLABasePool.hpp"
#include "ClipperUtils.hpp" #include <libslic3r/ClipperUtils.hpp>
#include "Model.hpp" #include <libslic3r/Model.hpp>
#include <boost/log/trivial.hpp> #include <boost/log/trivial.hpp>
@ -176,6 +176,7 @@ Contour3D cylinder(double r, double h, size_t ssteps) {
Vec3d jp = {0, 0, 0}; Vec3d jp = {0, 0, 0};
Vec3d endp = {0, 0, h}; Vec3d endp = {0, 0, h};
// Upper circle points
for(int i = 0; i < steps; ++i) { for(int i = 0; i < steps; ++i) {
double phi = i*a; double phi = i*a;
double ex = endp(X) + r*std::cos(phi); double ex = endp(X) + r*std::cos(phi);
@ -183,6 +184,7 @@ Contour3D cylinder(double r, double h, size_t ssteps) {
points.emplace_back(ex, ey, endp(Z)); points.emplace_back(ex, ey, endp(Z));
} }
// Lower circle points
for(int i = 0; i < steps; ++i) { for(int i = 0; i < steps; ++i) {
double phi = i*a; double phi = i*a;
double x = jp(X) + r*std::cos(phi); double x = jp(X) + r*std::cos(phi);
@ -190,6 +192,7 @@ Contour3D cylinder(double r, double h, size_t ssteps) {
points.emplace_back(x, y, jp(Z)); points.emplace_back(x, y, jp(Z));
} }
// Now create long triangles connecting upper and lower circles
indices.reserve(2*ssteps); indices.reserve(2*ssteps);
auto offs = steps; auto offs = steps;
for(int i = 0; i < steps - 1; ++i) { for(int i = 0; i < steps - 1; ++i) {
@ -197,10 +200,26 @@ Contour3D cylinder(double r, double h, size_t ssteps) {
indices.emplace_back(i, offs + i + 1, i + 1); indices.emplace_back(i, offs + i + 1, i + 1);
} }
// Last triangle connecting the first and last vertices
auto last = steps - 1; auto last = steps - 1;
indices.emplace_back(0, last, offs); indices.emplace_back(0, last, offs);
indices.emplace_back(last, offs + last, offs); indices.emplace_back(last, offs + last, offs);
// According to the slicing algorithms, we need to aid them with generating
// a watertight body. So we create a triangle fan for the upper and lower
// ending of the cylinder to close the geometry.
points.emplace_back(jp); size_t ci = points.size() - 1;
for(int i = 0; i < steps - 1; ++i)
indices.emplace_back(i + offs + 1, i + offs, ci);
indices.emplace_back(offs, steps + offs - 1, ci);
points.emplace_back(endp); ci = points.size() - 1;
for(int i = 0; i < steps - 1; ++i)
indices.emplace_back(ci, i, i + 1);
indices.emplace_back(steps - 1, 0, ci);
return ret; return ret;
} }
@ -352,6 +371,8 @@ struct Pillar {
r(radius), steps(st), endpoint(endp), starts_from_head(false) r(radius), steps(st), endpoint(endp), starts_from_head(false)
{ {
assert(steps > 0); assert(steps > 0);
assert(jp(Z) > endp(Z)); // Endpoint is below the starting point
int steps_1 = int(steps - 1); int steps_1 = int(steps - 1);
auto& points = mesh.points; auto& points = mesh.points;
@ -382,6 +403,22 @@ struct Pillar {
indices.emplace_back(0, steps_1, offs); indices.emplace_back(0, steps_1, offs);
indices.emplace_back(steps_1, offs + steps_1, offs); indices.emplace_back(steps_1, offs + steps_1, offs);
// According to the slicing algorithms, we need to aid them with
// generating a watertight body. So we create a triangle fan for the
// upper and lower ending of the cylinder to close the geometry.
points.emplace_back(jp); size_t ci = points.size() - 1;
int stepsi = int(steps);
for(int i = 0; i < stepsi - 1; ++i)
indices.emplace_back(ci, i, i + 1);
indices.emplace_back(stepsi - 1, 0, ci);
points.emplace_back(endp); ci = points.size() - 1;
for(int i = 0; i < stepsi - 1; ++i)
indices.emplace_back(i + offs + 1, i + offs, ci);
indices.emplace_back(offs, stepsi + offs - 1, ci);
} }
Pillar(const Junction& junc, const Vec3d& endp): Pillar(const Junction& junc, const Vec3d& endp):
@ -461,6 +498,8 @@ struct Bridge {
Vec3d dir = (j2 - j1).normalized(); Vec3d dir = (j2 - j1).normalized();
double d = distance(j2, j1); double d = distance(j2, j1);
assert(d > 0);
mesh = cylinder(r, d, steps); mesh = cylinder(r, d, steps);
auto quater = Quaternion::FromTwoVectors(Vec3d{0,0,1}, dir); auto quater = Quaternion::FromTwoVectors(Vec3d{0,0,1}, dir);