Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/supermerill/SuperSlicer.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authortamasmeszaros <meszaros.q@gmail.com>2019-11-12 18:56:06 +0300
committertamasmeszaros <meszaros.q@gmail.com>2019-11-12 19:11:26 +0300
commit97811130a18e01ee8c4ae5e59f60918de53ee119 (patch)
treedef10104d5ec68a1d72386b21958a360a9a9bc94 /src/libslic3r/SLA
parent73ae73348434b110da1a09a83e9d152bb8afda8c (diff)
parent4e067c42f03bac019066849401fb42f70cacda87 (diff)
Merge branch 'tm_openvdb_integration' into lm_tm_hollowing
SLAPrintSteps parallel functions now fully adapted to sla::ccr
Diffstat (limited to 'src/libslic3r/SLA')
-rw-r--r--src/libslic3r/SLA/Common.cpp235
-rw-r--r--src/libslic3r/SLA/Hollowing.cpp26
-rw-r--r--src/libslic3r/SLA/Hollowing.hpp21
-rw-r--r--src/libslic3r/SLA/RasterWriter.cpp2
-rw-r--r--src/libslic3r/SLA/RasterWriter.hpp8
5 files changed, 157 insertions, 135 deletions
diff --git a/src/libslic3r/SLA/Common.cpp b/src/libslic3r/SLA/Common.cpp
index f85731603..caabdd755 100644
--- a/src/libslic3r/SLA/Common.cpp
+++ b/src/libslic3r/SLA/Common.cpp
@@ -1,11 +1,13 @@
#include <cmath>
#include <libslic3r/SLA/Common.hpp>
+#include <libslic3r/SLA/Concurrency.hpp>
#include <libslic3r/SLA/SupportTree.hpp>
#include <libslic3r/SLA/SpatIndex.hpp>
#include <libslic3r/SLA/EigenMesh3D.hpp>
#include <libslic3r/SLA/Contour3D.hpp>
#include <libslic3r/SLA/Clustering.hpp>
+
// Workaround: IGL signed_distance.h will define PI in the igl namespace.
#undef PI
@@ -351,128 +353,131 @@ PointSet normals(const PointSet& points,
std::function<void()> thr, // 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 {};
-
+
std::vector<unsigned> range = pt_indices;
- if(range.empty()) {
+ if (range.empty()) {
range.resize(size_t(points.rows()), 0);
std::iota(range.begin(), range.end(), 0);
}
-
- PointSet ret(range.size(), 3);
-
+
+ PointSet ret(range.size(), 3);
+
// for (size_t ridx = 0; ridx < range.size(); ++ridx)
- tbb::parallel_for(size_t(0), range.size(),
- [&ret, &range, &mesh, &points, thr, eps](size_t ridx)
- {
- thr();
- auto eidx = Eigen::Index(range[ridx]);
- int faceid = 0;
- Vec3d p;
-
- mesh.squared_distance(points.row(eidx), faceid, p);
-
- auto trindex = mesh.F().row(faceid);
-
- const Vec3d& p1 = mesh.V().row(trindex(0));
- const Vec3d& p2 = mesh.V().row(trindex(1));
- const Vec3d& p3 = mesh.V().row(trindex(2));
-
- // We should check if the point lies on an edge of the hosting triangle.
- // If it does then all the other triangles using the same two points
- // have to be searched and the final normal should be some kind of
- // aggregation of the participating triangle normals. We should also
- // consider the cases where the support point lies right on a vertex
- // of its triangle. The procedure is the same, get the neighbor
- // triangles and calculate an average normal.
-
- // mark the vertex indices of the edge. ia and ib marks and edge ic
- // will mark a single vertex.
- int ia = -1, ib = -1, ic = -1;
-
- if(std::abs(distance(p, p1)) < eps) {
- ic = trindex(0);
- }
- else if(std::abs(distance(p, p2)) < eps) {
- ic = trindex(1);
- }
- else if(std::abs(distance(p, p3)) < eps) {
- ic = trindex(2);
- }
- else if(point_on_edge(p, p1, p2, eps)) {
- ia = trindex(0); ib = trindex(1);
- }
- else if(point_on_edge(p, p2, p3, eps)) {
- ia = trindex(1); ib = trindex(2);
- }
- else if(point_on_edge(p, p1, p3, eps)) {
- ia = trindex(0); ib = trindex(2);
- }
-
- // vector for the neigboring triangles including the detected one.
- std::vector<Vec3i> neigh;
- if(ic >= 0) { // The point is right on a vertex of the triangle
- for(int n = 0; n < mesh.F().rows(); ++n) {
- thr();
- Vec3i ni = mesh.F().row(n);
- if((ni(X) == ic || ni(Y) == ic || ni(Z) == ic))
- neigh.emplace_back(ni);
- }
- }
- else if(ia >= 0 && ib >= 0) { // the point is on and edge
- // now get all the neigboring triangles
- for(int n = 0; n < mesh.F().rows(); ++n) {
- thr();
- Vec3i ni = mesh.F().row(n);
- if((ni(X) == ia || ni(Y) == ia || ni(Z) == ia) &&
- (ni(X) == ib || ni(Y) == ib || ni(Z) == ib))
- neigh.emplace_back(ni);
- }
- }
-
- // Calculate the normals for the neighboring triangles
- std::vector<Vec3d> neighnorms; neighnorms.reserve(neigh.size());
- for(const Vec3i& tri : neigh) {
- const Vec3d& pt1 = mesh.V().row(tri(0));
- const Vec3d& pt2 = mesh.V().row(tri(1));
- const Vec3d& pt3 = mesh.V().row(tri(2));
- Eigen::Vector3d U = pt2 - pt1;
- Eigen::Vector3d V = pt3 - pt1;
- neighnorms.emplace_back(U.cross(V).normalized());
- }
-
- // Throw out duplicates. They would cause trouble with summing. We will
- // use std::unique which works on sorted ranges. We will sort by the
- // coefficient-wise sum of the normals. It should force the same
- // elements to be consecutive.
- std::sort(neighnorms.begin(), neighnorms.end(),
- [](const Vec3d& v1, const Vec3d& v2){
- return v1.sum() < v2.sum();
- });
-
- auto lend = std::unique(neighnorms.begin(), neighnorms.end(),
- [](const Vec3d& n1, const Vec3d& n2) {
- // Compare normals for equivalence. This is controvers stuff.
- auto deq = [](double a, double b) { return std::abs(a-b) < 1e-3; };
- return deq(n1(X), n2(X)) && deq(n1(Y), n2(Y)) && deq(n1(Z), n2(Z));
- });
-
- if(!neighnorms.empty()) { // there were neighbors to count with
- // sum up the normals and then normalize the result again.
- // This unification seems to be enough.
- Vec3d sumnorm(0, 0, 0);
- sumnorm = std::accumulate(neighnorms.begin(), lend, sumnorm);
- sumnorm.normalize();
- ret.row(long(ridx)) = sumnorm;
- }
- else { // point lies safely within its triangle
- Eigen::Vector3d U = p2 - p1;
- Eigen::Vector3d V = p3 - p1;
- ret.row(long(ridx)) = U.cross(V).normalized();
- }
+ ccr::enumerate(
+ range.begin(), range.end(),
+ [&ret, &mesh, &points, thr, eps](unsigned el, size_t ridx) {
+ thr();
+ auto eidx = Eigen::Index(el);
+ int faceid = 0;
+ Vec3d p;
+
+ mesh.squared_distance(points.row(eidx), faceid, p);
+
+ auto trindex = mesh.F().row(faceid);
+
+ const Vec3d &p1 = mesh.V().row(trindex(0));
+ const Vec3d &p2 = mesh.V().row(trindex(1));
+ const Vec3d &p3 = mesh.V().row(trindex(2));
+
+ // We should check if the point lies on an edge of the hosting
+ // triangle. If it does then all the other triangles using the
+ // same two points have to be searched and the final normal should
+ // be some kind of aggregation of the participating triangle
+ // normals. We should also consider the cases where the support
+ // point lies right on a vertex of its triangle. The procedure is
+ // the same, get the neighbor triangles and calculate an average
+ // normal.
+
+ // mark the vertex indices of the edge. ia and ib marks and edge
+ // ic will mark a single vertex.
+ int ia = -1, ib = -1, ic = -1;
+
+ if (std::abs(distance(p, p1)) < eps) {
+ ic = trindex(0);
+ } else if (std::abs(distance(p, p2)) < eps) {
+ ic = trindex(1);
+ } else if (std::abs(distance(p, p3)) < eps) {
+ ic = trindex(2);
+ } else if (point_on_edge(p, p1, p2, eps)) {
+ ia = trindex(0);
+ ib = trindex(1);
+ } else if (point_on_edge(p, p2, p3, eps)) {
+ ia = trindex(1);
+ ib = trindex(2);
+ } else if (point_on_edge(p, p1, p3, eps)) {
+ ia = trindex(0);
+ ib = trindex(2);
+ }
+
+ // vector for the neigboring triangles including the detected one.
+ std::vector<Vec3i> neigh;
+ if (ic >= 0) { // The point is right on a vertex of the triangle
+ for (int n = 0; n < mesh.F().rows(); ++n) {
+ thr();
+ Vec3i ni = mesh.F().row(n);
+ if ((ni(X) == ic || ni(Y) == ic || ni(Z) == ic))
+ neigh.emplace_back(ni);
+ }
+ } else if (ia >= 0 && ib >= 0) { // the point is on and edge
+ // now get all the neigboring triangles
+ for (int n = 0; n < mesh.F().rows(); ++n) {
+ thr();
+ Vec3i ni = mesh.F().row(n);
+ if ((ni(X) == ia || ni(Y) == ia || ni(Z) == ia) &&
+ (ni(X) == ib || ni(Y) == ib || ni(Z) == ib))
+ neigh.emplace_back(ni);
+ }
+ }
+
+ // Calculate the normals for the neighboring triangles
+ std::vector<Vec3d> neighnorms;
+ neighnorms.reserve(neigh.size());
+ for (const Vec3i &tri : neigh) {
+ const Vec3d & pt1 = mesh.V().row(tri(0));
+ const Vec3d & pt2 = mesh.V().row(tri(1));
+ const Vec3d & pt3 = mesh.V().row(tri(2));
+ Eigen::Vector3d U = pt2 - pt1;
+ Eigen::Vector3d V = pt3 - pt1;
+ neighnorms.emplace_back(U.cross(V).normalized());
+ }
+
+ // Throw out duplicates. They would cause trouble with summing. We
+ // will use std::unique which works on sorted ranges. We will sort
+ // by the coefficient-wise sum of the normals. It should force the
+ // same elements to be consecutive.
+ std::sort(neighnorms.begin(), neighnorms.end(),
+ [](const Vec3d &v1, const Vec3d &v2) {
+ return v1.sum() < v2.sum();
});
-
+
+ auto lend = std::unique(neighnorms.begin(), neighnorms.end(),
+ [](const Vec3d &n1, const Vec3d &n2) {
+ // Compare normals for equivalence.
+ // This is controvers stuff.
+ auto deq = [](double a, double b) {
+ return std::abs(a - b) < 1e-3;
+ };
+ return deq(n1(X), n2(X)) &&
+ deq(n1(Y), n2(Y)) &&
+ deq(n1(Z), n2(Z));
+ });
+
+ if (!neighnorms.empty()) { // there were neighbors to count with
+ // sum up the normals and then normalize the result again.
+ // This unification seems to be enough.
+ Vec3d sumnorm(0, 0, 0);
+ sumnorm = std::accumulate(neighnorms.begin(), lend, sumnorm);
+ sumnorm.normalize();
+ ret.row(long(ridx)) = sumnorm;
+ } else { // point lies safely within its triangle
+ Eigen::Vector3d U = p2 - p1;
+ Eigen::Vector3d V = p3 - p1;
+ ret.row(long(ridx)) = U.cross(V).normalized();
+ }
+ });
+
return ret;
}
diff --git a/src/libslic3r/SLA/Hollowing.cpp b/src/libslic3r/SLA/Hollowing.cpp
index b224bc98c..c3763dbc9 100644
--- a/src/libslic3r/SLA/Hollowing.cpp
+++ b/src/libslic3r/SLA/Hollowing.cpp
@@ -1,5 +1,7 @@
#include <functional>
+#include <libslic3r/OpenVDBUtils.hpp>
+#include <libslic3r/TriangleMesh.hpp>
#include <libslic3r/SLA/Hollowing.hpp>
#include <libslic3r/SLA/Contour3D.hpp>
@@ -98,18 +100,30 @@ remove_cvref_t<Mesh> _generate_interior(Mesh &&mesh,
return omesh;
}
-TriangleMesh generate_interior(const TriangleMesh &mesh, const HollowingConfig &hc, const JobController &ctl)
+std::unique_ptr<TriangleMesh> generate_interior(const TriangleMesh & mesh,
+ const HollowingConfig &hc,
+ const JobController & ctl)
{
static const double MAX_OVERSAMPL = 7.;
- // I can't figure out how to increase the grid resolution through openvdb API
- // so the model will be scaled up before conversion and the result scaled
- // down. Voxels have a unit size. If I set voxelSize smaller, it scales
- // the whole geometry down, and doesn't increase the number of voxels.
+ // I can't figure out how to increase the grid resolution through openvdb
+ // API so the model will be scaled up before conversion and the result
+ // scaled down. Voxels have a unit size. If I set voxelSize smaller, it
+ // scales the whole geometry down, and doesn't increase the number of
+ // voxels.
//
// max 8x upscale, min is native voxel size
auto voxel_scale = (1.0 + MAX_OVERSAMPL * hc.quality);
- return _generate_interior(mesh, ctl, hc.min_thickness, voxel_scale, hc.closing_distance);
+ return std::make_unique<TriangleMesh>(
+ _generate_interior(mesh, ctl, hc.min_thickness, voxel_scale,
+ hc.closing_distance));
+}
+
+bool DrainHole::operator==(const DrainHole &sp) const
+{
+ return (m_pos == sp.m_pos) && (m_normal == sp.m_normal) &&
+ is_approx(m_radius, sp.m_radius) &&
+ is_approx(m_height, sp.m_height);
}
}} // namespace Slic3r::sla
diff --git a/src/libslic3r/SLA/Hollowing.hpp b/src/libslic3r/SLA/Hollowing.hpp
index 93a1f90fd..cb5c2bd15 100644
--- a/src/libslic3r/SLA/Hollowing.hpp
+++ b/src/libslic3r/SLA/Hollowing.hpp
@@ -1,10 +1,14 @@
#ifndef SLA_HOLLOWING_HPP
#define SLA_HOLLOWING_HPP
-#include <libslic3r/OpenVDBUtils.hpp>
+#include <memory>
+#include <libslic3r/SLA/Common.hpp>
#include <libslic3r/SLA/JobController.hpp>
namespace Slic3r {
+
+class TriangleMesh;
+
namespace sla {
struct HollowingConfig
@@ -33,24 +37,19 @@ struct DrainHole
, m_height(height)
{}
- bool operator==(const DrainHole &sp) const
- {
- return (m_pos == sp.m_pos) && (m_normal == sp.m_normal) &&
- is_approx(m_radius, sp.m_radius) &&
- is_approx(m_height, sp.m_height);
- }
+ bool operator==(const DrainHole &sp) const;
bool operator!=(const DrainHole &sp) const { return !(sp == (*this)); }
- template<class Archive> void serialize(Archive &ar)
+ template<class Archive> inline void serialize(Archive &ar)
{
ar(m_pos, m_normal, m_radius, m_height);
}
};
-TriangleMesh generate_interior(const TriangleMesh &mesh,
- const HollowingConfig & = {},
- const JobController &ctl = {});
+std::unique_ptr<TriangleMesh> generate_interior(const TriangleMesh &mesh,
+ const HollowingConfig & = {},
+ const JobController &ctl = {});
}
}
diff --git a/src/libslic3r/SLA/RasterWriter.cpp b/src/libslic3r/SLA/RasterWriter.cpp
index b3da0d2a5..0d55b769d 100644
--- a/src/libslic3r/SLA/RasterWriter.cpp
+++ b/src/libslic3r/SLA/RasterWriter.cpp
@@ -1,4 +1,6 @@
#include <libslic3r/SLA/RasterWriter.hpp>
+
+#include "libslic3r/PrintConfig.hpp"
#include <libslic3r/Zipper.hpp>
#include <libslic3r/Time.hpp>
diff --git a/src/libslic3r/SLA/RasterWriter.hpp b/src/libslic3r/SLA/RasterWriter.hpp
index a7792d55d..62ed44ca8 100644
--- a/src/libslic3r/SLA/RasterWriter.hpp
+++ b/src/libslic3r/SLA/RasterWriter.hpp
@@ -9,11 +9,13 @@
#include <map>
#include <array>
-#include "libslic3r/PrintConfig.hpp"
-
#include <libslic3r/SLA/Raster.hpp>
-namespace Slic3r { namespace sla {
+namespace Slic3r {
+
+class DynamicPrintConfig;
+
+namespace sla {
// API to write the zipped sla output layers and metadata.
// Implementation uses PNG raster output.