mirror of
https://github.com/SoftFever/OrcaSlicer.git
synced 2025-07-12 01:07:57 -06:00
Refactoring of adaptive cubic / support cubic:
1) Octree is built directly from the triangle mesh by checking overlap of a triangle with an octree cell. This shall produce a tighter octree with less dense cells. 2) The same method is used for both the adaptive / support cubic infill, where for the support cubic infill the non-overhang triangles are ignored. The AABB tree is no more used. 3) Optimized extraction of continuous infill lines in O(1) instead of O(n^2)
This commit is contained in:
parent
acdd5716bd
commit
37c5fe9923
16 changed files with 658 additions and 554 deletions
|
@ -1,3 +1,13 @@
|
|||
// Adaptive cubic infill was inspired by the work of @mboerwinkle
|
||||
// as implemented for Cura.
|
||||
// https://github.com/Ultimaker/CuraEngine/issues/381
|
||||
// https://github.com/Ultimaker/CuraEngine/pull/401
|
||||
//
|
||||
// Our implementation is more accurate (discretizes a bit less cubes than Cura's)
|
||||
// by splitting only such cubes which contain a triangle.
|
||||
// Our line extraction is time optimal instead of O(n^2) when connecting extracted lines,
|
||||
// and we also implemented adaptivity for supporting internal overhangs only.
|
||||
|
||||
#ifndef slic3r_FillAdaptive_hpp_
|
||||
#define slic3r_FillAdaptive_hpp_
|
||||
|
||||
|
@ -5,49 +15,39 @@
|
|||
|
||||
#include "FillBase.hpp"
|
||||
|
||||
struct indexed_triangle_set;
|
||||
|
||||
namespace Slic3r {
|
||||
|
||||
class PrintObject;
|
||||
class TriangleMesh;
|
||||
|
||||
namespace FillAdaptive_Internal
|
||||
{
|
||||
struct CubeProperties
|
||||
{
|
||||
double edge_length; // Lenght of edge of a cube
|
||||
double height; // Height of rotated cube (standing on the corner)
|
||||
double diagonal_length; // Length of diagonal of a cube a face
|
||||
double line_z_distance; // Defines maximal distance from a center of a cube on Z axis on which lines will be created
|
||||
double line_xy_distance;// Defines maximal distance from a center of a cube on X and Y axis on which lines will be created
|
||||
struct Octree;
|
||||
// To keep the definition of Octree opaque, we have to define a custom deleter.
|
||||
struct OctreeDeleter {
|
||||
void operator()(Octree *p);
|
||||
};
|
||||
using OctreePtr = std::unique_ptr<Octree, OctreeDeleter>;
|
||||
|
||||
struct Cube
|
||||
{
|
||||
Vec3d center;
|
||||
std::unique_ptr<Cube> children[8] = {};
|
||||
Cube(const Vec3d ¢er) : center(center) {}
|
||||
};
|
||||
// Calculate line spacing for
|
||||
// 1) adaptive cubic infill
|
||||
// 2) adaptive internal support cubic infill
|
||||
// Returns zero for a particular infill type if no such infill is to be generated.
|
||||
std::pair<double, double> adaptive_fill_line_spacing(const PrintObject &print_object);
|
||||
|
||||
struct Octree
|
||||
{
|
||||
std::unique_ptr<Cube> root_cube;
|
||||
Vec3d origin;
|
||||
std::vector<CubeProperties> cubes_properties;
|
||||
// Rotation of the octree to stand on one of its corners.
|
||||
Eigen::Quaterniond adaptive_fill_octree_transform_to_world();
|
||||
// Inverse roation of the above.
|
||||
Eigen::Quaterniond adaptive_fill_octree_transform_to_octree();
|
||||
|
||||
Octree(std::unique_ptr<Cube> rootCube, const Vec3d &origin, const std::vector<CubeProperties> &cubes_properties)
|
||||
: root_cube(std::move(rootCube)), origin(origin), cubes_properties(cubes_properties) {}
|
||||
|
||||
inline static int find_octant(const Vec3d &i_cube, const Vec3d ¤t)
|
||||
{
|
||||
return (i_cube.z() > current.z()) * 4 + (i_cube.y() > current.y()) * 2 + (i_cube.x() > current.x());
|
||||
}
|
||||
|
||||
static void propagate_point(
|
||||
Vec3d point,
|
||||
FillAdaptive_Internal::Cube *current_cube,
|
||||
int depth,
|
||||
const std::vector<FillAdaptive_Internal::CubeProperties> &cubes_properties);
|
||||
};
|
||||
FillAdaptive_Internal::OctreePtr build_octree(
|
||||
// Mesh is rotated to the coordinate system of the octree.
|
||||
const indexed_triangle_set &triangle_mesh,
|
||||
// Up vector of the mesh rotated to the coordinate system of the octree.
|
||||
const Vec3d &up_vector,
|
||||
coordf_t line_spacing,
|
||||
// If true, octree is densified below internal overhangs only.
|
||||
bool support_overhangs_only);
|
||||
}; // namespace FillAdaptive_Internal
|
||||
|
||||
//
|
||||
|
@ -70,70 +70,8 @@ protected:
|
|||
Polylines &polylines_out);
|
||||
|
||||
virtual bool no_sort() const { return true; }
|
||||
|
||||
void generate_infill_lines(
|
||||
FillAdaptive_Internal::Cube *cube,
|
||||
double z_position,
|
||||
const Vec3d & origin,
|
||||
const Transform3d & rotation_matrix,
|
||||
std::vector<Lines> & dir_lines_out,
|
||||
const std::vector<FillAdaptive_Internal::CubeProperties> &cubes_properties,
|
||||
int depth);
|
||||
|
||||
static void connect_lines(Lines &lines, Line new_line);
|
||||
|
||||
void generate_infill(const FillParams & params,
|
||||
unsigned int thickness_layers,
|
||||
const std::pair<float, Point> &direction,
|
||||
ExPolygon & expolygon,
|
||||
Polylines & polylines_out,
|
||||
FillAdaptive_Internal::Octree *octree);
|
||||
|
||||
public:
|
||||
static std::unique_ptr<FillAdaptive_Internal::Octree> build_octree(
|
||||
TriangleMesh &triangle_mesh,
|
||||
coordf_t line_spacing,
|
||||
const Vec3d & cube_center);
|
||||
|
||||
static void expand_cube(
|
||||
FillAdaptive_Internal::Cube *cube,
|
||||
const std::vector<FillAdaptive_Internal::CubeProperties> &cubes_properties,
|
||||
const AABBTreeIndirect::Tree3f &distance_tree,
|
||||
const TriangleMesh & triangle_mesh,
|
||||
int depth);
|
||||
};
|
||||
|
||||
class FillSupportCubic : public FillAdaptive
|
||||
{
|
||||
public:
|
||||
virtual ~FillSupportCubic() = default;
|
||||
|
||||
protected:
|
||||
virtual Fill* clone() const { return new FillSupportCubic(*this); };
|
||||
|
||||
virtual bool no_sort() const { return true; }
|
||||
|
||||
virtual void _fill_surface_single(
|
||||
const FillParams ¶ms,
|
||||
unsigned int thickness_layers,
|
||||
const std::pair<float, Point> &direction,
|
||||
ExPolygon &expolygon,
|
||||
Polylines &polylines_out);
|
||||
|
||||
public:
|
||||
static std::unique_ptr<FillAdaptive_Internal::Octree> build_octree(
|
||||
TriangleMesh & triangle_mesh,
|
||||
coordf_t line_spacing,
|
||||
const Vec3d & cube_center,
|
||||
const Transform3d &rotation_matrix);
|
||||
};
|
||||
|
||||
// Calculate line spacing for
|
||||
// 1) adaptive cubic infill
|
||||
// 2) adaptive internal support cubic infill
|
||||
// Returns zero for a particular infill type if no such infill is to be generated.
|
||||
std::pair<double, double> adaptive_fill_line_spacing(const PrintObject &print_object);
|
||||
|
||||
} // namespace Slic3r
|
||||
|
||||
#endif // slic3r_FillAdaptive_hpp_
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue