Merge remote-tracking branch 'remotes/origin/master' into vb_print_regions

This commit is contained in:
Vojtech Bubnik 2021-05-31 14:05:53 +02:00
commit 033d9f3a5e
38 changed files with 1502 additions and 587 deletions

View file

@ -542,7 +542,7 @@ std::vector<GCode::LayerToPrint> GCode::collect_layers_to_print(const PrintObjec
if (has_extrusions && layer_to_print.print_z() > maximal_print_z + 2. * EPSILON) {
const_cast<Print*>(object.print())->active_step_add_warning(PrintStateBase::WarningLevel::CRITICAL,
_(L("Empty layers detected, the output would not be printable.")) + "\n\n" +
_(L("Empty layers detected. Make sure the object is printable.")) + "\n\n" +
_(L("Object name")) + ": " + object.model_object()->name + "\n" + _(L("Print z")) + ": " +
std::to_string(layers_to_print.back().print_z()) + "\n\n" + _(L("This is "
"usually caused by negligibly small extrusions or by a faulty model. Try to repair "

View file

@ -27,6 +27,7 @@ using Vec2crd = Eigen::Matrix<coord_t, 2, 1, Eigen::DontAlign>;
using Vec3crd = Eigen::Matrix<coord_t, 3, 1, Eigen::DontAlign>;
using Vec2i = Eigen::Matrix<int, 2, 1, Eigen::DontAlign>;
using Vec3i = Eigen::Matrix<int, 3, 1, Eigen::DontAlign>;
using Vec4i = Eigen::Matrix<int, 4, 1, Eigen::DontAlign>;
using Vec2i32 = Eigen::Matrix<int32_t, 2, 1, Eigen::DontAlign>;
using Vec2i64 = Eigen::Matrix<int64_t, 2, 1, Eigen::DontAlign>;
using Vec3i32 = Eigen::Matrix<int32_t, 3, 1, Eigen::DontAlign>;
@ -50,6 +51,8 @@ using Matrix2f = Eigen::Matrix<float, 2, 2, Eigen::DontAlign>;
using Matrix2d = Eigen::Matrix<double, 2, 2, Eigen::DontAlign>;
using Matrix3f = Eigen::Matrix<float, 3, 3, Eigen::DontAlign>;
using Matrix3d = Eigen::Matrix<double, 3, 3, Eigen::DontAlign>;
using Matrix4f = Eigen::Matrix<float, 4, 4, Eigen::DontAlign>;
using Matrix4d = Eigen::Matrix<double, 4, 4, Eigen::DontAlign>;
using Transform2f = Eigen::Transform<float, 2, Eigen::Affine, Eigen::DontAlign>;
using Transform2d = Eigen::Transform<double, 2, Eigen::Affine, Eigen::DontAlign>;

View file

@ -354,9 +354,19 @@ bool Print::has_brim() const
return std::any_of(m_objects.begin(), m_objects.end(), [](PrintObject *object) { return object->has_brim(); });
}
#if ENABLE_SEQUENTIAL_LIMITS
bool Print::sequential_print_horizontal_clearance_valid(const Print& print, Polygons* polygons)
#else
static inline bool sequential_print_horizontal_clearance_valid(const Print &print)
#endif // ENABLE_SEQUENTIAL_LIMITS
{
Polygons convex_hulls_other;
#if ENABLE_SEQUENTIAL_LIMITS
if (polygons != nullptr)
polygons->clear();
std::vector<size_t> intersecting_idxs;
#endif // ENABLE_SEQUENTIAL_LIMITS
std::map<ObjectID, Polygon> map_model_object_to_convex_hull;
for (const PrintObject *print_object : print.objects()) {
assert(! print_object->model_object()->instances.empty());
@ -378,7 +388,7 @@ static inline bool sequential_print_horizontal_clearance_valid(const Print &prin
// Shrink the extruder_clearance_radius a tiny bit, so that if the object arrangement algorithm placed the objects
// exactly by satisfying the extruder_clearance_radius, this test will not trigger collision.
float(scale_(0.5 * print.config().extruder_clearance_radius.value - EPSILON)),
jtRound, float(scale_(0.1))).front());
jtRound, scale_(0.1)).front());
#else
it_convex_hull = map_model_object_to_convex_hull.emplace_hint(it_convex_hull, model_object_id,
offset(print_object->model_object()->convex_hull_2d(
@ -391,21 +401,47 @@ static inline bool sequential_print_horizontal_clearance_valid(const Print &prin
}
// Make a copy, so it may be rotated for instances.
Polygon convex_hull0 = it_convex_hull->second;
double z_diff = Geometry::rotation_diff_z(model_instance0->get_rotation(), print_object->instances().front().model_instance->get_rotation());
const double z_diff = Geometry::rotation_diff_z(model_instance0->get_rotation(), print_object->instances().front().model_instance->get_rotation());
if (std::abs(z_diff) > EPSILON)
convex_hull0.rotate(z_diff);
// Now we check that no instance of convex_hull intersects any of the previously checked object instances.
for (const PrintInstance &instance : print_object->instances()) {
Polygon convex_hull = convex_hull0;
// instance.shift is a position of a centered object, while model object may not be centered.
// Conver the shift from the PrintObject's coordinates into ModelObject's coordinates by removing the centering offset.
// Convert the shift from the PrintObject's coordinates into ModelObject's coordinates by removing the centering offset.
convex_hull.translate(instance.shift - print_object->center_offset());
if (! intersection(convex_hulls_other, (Polygons)convex_hull).empty())
return false;
convex_hulls_other.emplace_back(std::move(convex_hull));
#if ENABLE_SEQUENTIAL_LIMITS
// if output needed, collect indices (inside convex_hulls_other) of intersecting hulls
for (size_t i = 0; i < convex_hulls_other.size(); ++i) {
if (!intersection((Polygons)convex_hulls_other[i], (Polygons)convex_hull).empty()) {
if (polygons == nullptr)
return false;
else {
intersecting_idxs.emplace_back(i);
intersecting_idxs.emplace_back(convex_hulls_other.size());
}
}
}
#else
if (!intersection(convex_hulls_other, (Polygons)convex_hull).empty())
return false;
#endif // ENABLE_SEQUENTIAL_LIMITS
convex_hulls_other.emplace_back(std::move(convex_hull));
}
}
return true;
#if ENABLE_SEQUENTIAL_LIMITS
if (!intersecting_idxs.empty()) {
// use collected indices (inside convex_hulls_other) to update output
std::sort(intersecting_idxs.begin(), intersecting_idxs.end());
intersecting_idxs.erase(std::unique(intersecting_idxs.begin(), intersecting_idxs.end()), intersecting_idxs.end());
for (size_t i : intersecting_idxs) {
polygons->emplace_back(std::move(convex_hulls_other[i]));
}
return false;
}
#endif // ENABLE_SEQUENTIAL_LIMITS
return true;
}
static inline bool sequential_print_vertical_clearance_valid(const Print &print)

View file

@ -584,6 +584,10 @@ public:
const PrintRegion& get_print_region(size_t idx) const { return *m_print_regions[idx]; }
const ToolOrdering& get_tool_ordering() const { return m_wipe_tower_data.tool_ordering; }
#if ENABLE_SEQUENTIAL_LIMITS
static bool sequential_print_horizontal_clearance_valid(const Print& print, Polygons* polygons = nullptr);
#endif // ENABLE_SEQUENTIAL_LIMITS
protected:
// Invalidates the step, and its depending steps in Print.
bool invalidate_step(PrintStep step);

View file

@ -1,4 +1,5 @@
#include <functional>
#include <optional>
#include <libslic3r/OpenVDBUtils.hpp>
#include <libslic3r/TriangleMesh.hpp>

View file

@ -2,6 +2,7 @@
#define SLASUPPORTTREEALGORITHM_H
#include <cstdint>
#include <optional>
#include <libslic3r/SLA/SupportTreeBuilder.hpp>
#include <libslic3r/SLA/Clustering.hpp>

View file

@ -66,6 +66,8 @@
// Enable to push object instances under the bed
#define ENABLE_ALLOW_NEGATIVE_Z (1 && ENABLE_2_4_0_ALPHA0)
#define DISABLE_ALLOW_NEGATIVE_Z_FOR_SLA (1 && ENABLE_ALLOW_NEGATIVE_Z)
// Enable visualization of objects clearance for sequential prints
#define ENABLE_SEQUENTIAL_LIMITS (1 && ENABLE_2_4_0_ALPHA0)
#endif // _prusaslicer_technologies_h_

View file

@ -1020,6 +1020,33 @@ TriangleMesh make_cylinder(double r, double h, double fa)
return mesh;
}
TriangleMesh make_cone(double r, double h, double fa)
{
Pointf3s vertices;
std::vector<Vec3i> facets;
vertices.reserve(3+size_t(2*PI/fa));
vertices.reserve(3+2*size_t(2*PI/fa));
vertices = { Vec3d::Zero(), Vec3d(0., 0., h) }; // base center and top vertex
size_t i = 0;
for (double angle=0; angle<2*PI; angle+=fa) {
vertices.emplace_back(r*std::cos(angle), r*std::sin(angle), 0.);
if (angle > 0.) {
facets.emplace_back(0, i+2, i+1);
facets.emplace_back(1, i+1, i+2);
}
++i;
}
facets.emplace_back(0, 2, i+1); // close the shape
facets.emplace_back(1, i+1, 2);
TriangleMesh mesh(std::move(vertices), std::move(facets));
mesh.repair();
return mesh;
}
// Generates mesh for a sphere centered about the origin, using the generated angle
// to determine the granularity.
// Default angle is 1 degree.

View file

@ -125,10 +125,8 @@ Polygon its_convex_hull_2d_above(const indexed_triangle_set &its, const Matrix3f
Polygon its_convex_hull_2d_above(const indexed_triangle_set &its, const Transform3f &t, const float z);
TriangleMesh make_cube(double x, double y, double z);
// Generate a TriangleMesh of a cylinder
TriangleMesh make_cylinder(double r, double h, double fa=(2*PI/360));
TriangleMesh make_cone(double r, double h, double fa=(2*PI/360));
TriangleMesh make_sphere(double rho, double fa=(2*PI/360));
}