Adaptive infill: Reshuffled the namespaces.
This commit is contained in:
parent
7c7f5ebdda
commit
7e756b20e6
@ -318,7 +318,7 @@ void export_group_fills_to_svg(const char *path, const std::vector<SurfaceFill>
|
||||
#endif
|
||||
|
||||
// friend to Layer
|
||||
void Layer::make_fills(FillAdaptive_Internal::Octree* adaptive_fill_octree, FillAdaptive_Internal::Octree* support_fill_octree)
|
||||
void Layer::make_fills(FillAdaptive::Octree* adaptive_fill_octree, FillAdaptive::Octree* support_fill_octree)
|
||||
{
|
||||
for (LayerRegion *layerm : m_regions)
|
||||
layerm->fills.clear();
|
||||
|
@ -19,6 +19,7 @@
|
||||
#include <boost/pool/object_pool.hpp>
|
||||
|
||||
namespace Slic3r {
|
||||
namespace FillAdaptive {
|
||||
|
||||
// Derived from https://github.com/juj/MathGeoLib/blob/master/src/Geometry/Triangle.cpp
|
||||
// The AABB-Triangle test implementation is based on the pseudo-code in
|
||||
@ -165,48 +166,45 @@ static constexpr std::array<std::array<int, 8>, 3> child_traversal_order {
|
||||
std::array<int, 8>{ 1, 5, 0, 4, 3, 7, 2, 6 },
|
||||
};
|
||||
|
||||
namespace FillAdaptive_Internal
|
||||
struct Cube
|
||||
{
|
||||
struct Cube
|
||||
{
|
||||
Vec3d center;
|
||||
Vec3d center;
|
||||
#ifndef NDEBUG
|
||||
Vec3d center_octree;
|
||||
Vec3d center_octree;
|
||||
#endif // NDEBUG
|
||||
std::array<Cube*, 8> children {}; // initialized to nullptrs
|
||||
Cube(const Vec3d ¢er) : center(center) {}
|
||||
};
|
||||
std::array<Cube*, 8> children {}; // initialized to nullptrs
|
||||
Cube(const Vec3d ¢er) : center(center) {}
|
||||
};
|
||||
|
||||
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 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
|
||||
{
|
||||
// Octree will allocate its Cubes from the pool. The pool only supports deletion of the complete pool,
|
||||
// perfect for building up our octree.
|
||||
boost::object_pool<Cube> pool;
|
||||
Cube* root_cube { nullptr };
|
||||
Vec3d origin;
|
||||
std::vector<CubeProperties> cubes_properties;
|
||||
struct Octree
|
||||
{
|
||||
// Octree will allocate its Cubes from the pool. The pool only supports deletion of the complete pool,
|
||||
// perfect for building up our octree.
|
||||
boost::object_pool<Cube> pool;
|
||||
Cube* root_cube { nullptr };
|
||||
Vec3d origin;
|
||||
std::vector<CubeProperties> cubes_properties;
|
||||
|
||||
Octree(const Vec3d &origin, const std::vector<CubeProperties> &cubes_properties)
|
||||
: root_cube(pool.construct(origin)), origin(origin), cubes_properties(cubes_properties) {}
|
||||
Octree(const Vec3d &origin, const std::vector<CubeProperties> &cubes_properties)
|
||||
: root_cube(pool.construct(origin)), origin(origin), cubes_properties(cubes_properties) {}
|
||||
|
||||
void insert_triangle(const Vec3d &a, const Vec3d &b, const Vec3d &c, Cube *current_cube, const BoundingBoxf3 ¤t_bbox, int depth);
|
||||
};
|
||||
void insert_triangle(const Vec3d &a, const Vec3d &b, const Vec3d &c, Cube *current_cube, const BoundingBoxf3 ¤t_bbox, int depth);
|
||||
};
|
||||
|
||||
void OctreeDeleter::operator()(Octree *p) {
|
||||
delete p;
|
||||
}
|
||||
}; // namespace FillAdaptive_Internal
|
||||
void OctreeDeleter::operator()(Octree *p) {
|
||||
delete p;
|
||||
}
|
||||
|
||||
std::pair<double, double> FillAdaptive_Internal::adaptive_fill_line_spacing(const PrintObject &print_object)
|
||||
std::pair<double, double> FillAdaptive::adaptive_fill_line_spacing(const PrintObject &print_object)
|
||||
{
|
||||
// Output, spacing for icAdaptiveCubic and icSupportCubic
|
||||
double adaptive_line_spacing = 0.;
|
||||
@ -296,7 +294,7 @@ struct FillContext
|
||||
-(2.0 * M_PI) / 3.0
|
||||
};
|
||||
|
||||
FillContext(const FillAdaptive_Internal::Octree &octree, double z_position, int direction_idx) :
|
||||
FillContext(const Octree &octree, double z_position, int direction_idx) :
|
||||
origin_world(octree.origin),
|
||||
cubes_properties(octree.cubes_properties),
|
||||
z_position(z_position),
|
||||
@ -312,31 +310,31 @@ struct FillContext
|
||||
Vec2d rotate(const Vec2d& v) { return Vec2d(this->cos_a * v.x() - this->sin_a * v.y(), this->sin_a * v.x() + this->cos_a * v.y()); }
|
||||
|
||||
// Center of the root cube in the Octree coordinate system.
|
||||
const Vec3d origin_world;
|
||||
const std::vector<FillAdaptive_Internal::CubeProperties> &cubes_properties;
|
||||
const Vec3d origin_world;
|
||||
const std::vector<CubeProperties> &cubes_properties;
|
||||
// Top of the current layer.
|
||||
const double z_position;
|
||||
const double z_position;
|
||||
// Order of traversal for this line direction.
|
||||
const std::array<int, 8> traversal_order;
|
||||
const std::array<int, 8> traversal_order;
|
||||
// Rotation of the generated line for this line direction.
|
||||
const double cos_a;
|
||||
const double sin_a;
|
||||
const double cos_a;
|
||||
const double sin_a;
|
||||
|
||||
// Linearized tree spanning a single Octree wall, used to connect lines spanning
|
||||
// neighboring Octree cells. Unused lines have the Line::a::x set to infinity.
|
||||
std::vector<Line> temp_lines;
|
||||
std::vector<Line> temp_lines;
|
||||
// Final output
|
||||
std::vector<Line> output_lines;
|
||||
std::vector<Line> output_lines;
|
||||
};
|
||||
|
||||
static constexpr double octree_rot[3] = { 5.0 * M_PI / 4.0, Geometry::deg2rad(215.264), M_PI / 6.0 };
|
||||
|
||||
Eigen::Quaterniond FillAdaptive_Internal::adaptive_fill_octree_transform_to_world()
|
||||
Eigen::Quaterniond transform_to_world()
|
||||
{
|
||||
return Eigen::AngleAxisd(octree_rot[2], Vec3d::UnitZ()) * Eigen::AngleAxisd(octree_rot[1], Vec3d::UnitY()) * Eigen::AngleAxisd(octree_rot[0], Vec3d::UnitX());
|
||||
}
|
||||
|
||||
Eigen::Quaterniond FillAdaptive_Internal::adaptive_fill_octree_transform_to_octree()
|
||||
Eigen::Quaterniond transform_to_octree()
|
||||
{
|
||||
return Eigen::AngleAxisd(- octree_rot[0], Vec3d::UnitX()) * Eigen::AngleAxisd(- octree_rot[1], Vec3d::UnitY()) * Eigen::AngleAxisd(- octree_rot[2], Vec3d::UnitZ());
|
||||
}
|
||||
@ -345,14 +343,14 @@ Eigen::Quaterniond FillAdaptive_Internal::adaptive_fill_octree_transform_to_octr
|
||||
// Verify that the traversal order of the octree children matches the line direction,
|
||||
// therefore the infill line may get extended with O(1) time & space complexity.
|
||||
static bool verify_traversal_order(
|
||||
FillContext &context,
|
||||
const FillAdaptive_Internal::Cube *cube,
|
||||
int depth,
|
||||
const Vec2d &line_from,
|
||||
const Vec2d &line_to)
|
||||
FillContext &context,
|
||||
const Cube *cube,
|
||||
int depth,
|
||||
const Vec2d &line_from,
|
||||
const Vec2d &line_to)
|
||||
{
|
||||
std::array<Vec3d, 8> c;
|
||||
Eigen::Quaterniond to_world = FillAdaptive_Internal::adaptive_fill_octree_transform_to_world();
|
||||
Eigen::Quaterniond to_world = transform_to_world();
|
||||
for (int i = 0; i < 8; ++i) {
|
||||
int j = context.traversal_order[i];
|
||||
Vec3d cntr = to_world * (cube->center_octree + (child_centers[j] * (context.cubes_properties[depth].edge_length / 4.)));
|
||||
@ -379,15 +377,15 @@ static bool verify_traversal_order(
|
||||
#endif // NDEBUG
|
||||
|
||||
static void generate_infill_lines_recursive(
|
||||
FillContext &context,
|
||||
const FillAdaptive_Internal::Cube *cube,
|
||||
FillContext &context,
|
||||
const Cube *cube,
|
||||
// Address of this wall in the octree, used to address context.temp_lines.
|
||||
int address,
|
||||
int depth)
|
||||
int address,
|
||||
int depth)
|
||||
{
|
||||
assert(cube != nullptr);
|
||||
|
||||
const std::vector<FillAdaptive_Internal::CubeProperties> &cubes_properties = context.cubes_properties;
|
||||
const std::vector<CubeProperties> &cubes_properties = context.cubes_properties;
|
||||
const double z_diff = context.z_position - cube->center.z();
|
||||
const double z_diff_abs = std::abs(z_diff);
|
||||
|
||||
@ -427,7 +425,7 @@ static void generate_infill_lines_recursive(
|
||||
-- depth;
|
||||
size_t i = 0;
|
||||
for (const int child_idx : context.traversal_order) {
|
||||
const FillAdaptive_Internal::Cube *child = cube->children[child_idx];
|
||||
const Cube *child = cube->children[child_idx];
|
||||
if (child != nullptr)
|
||||
generate_infill_lines_recursive(context, child, address, depth);
|
||||
if (++ i == 4)
|
||||
@ -486,7 +484,7 @@ static void export_infill_lines_to_svg(const ExPolygon &expoly, const Polylines
|
||||
}
|
||||
#endif /* ADAPTIVE_CUBIC_INFILL_DEBUG_OUTPUT */
|
||||
|
||||
void FillAdaptive::_fill_surface_single(
|
||||
void Filler::_fill_surface_single(
|
||||
const FillParams & params,
|
||||
unsigned int thickness_layers,
|
||||
const std::pair<float, Point> &direction,
|
||||
@ -547,7 +545,7 @@ void FillAdaptive::_fill_surface_single(
|
||||
|
||||
if (!boundary_polylines.empty()) {
|
||||
boundary_polylines = chain_polylines(boundary_polylines);
|
||||
FillAdaptive::connect_infill(std::move(boundary_polylines), expolygon, polylines_out, this->spacing, params);
|
||||
connect_infill(std::move(boundary_polylines), expolygon, polylines_out, this->spacing, params);
|
||||
}
|
||||
|
||||
append(polylines_out, std::move(non_boundary_polylines));
|
||||
@ -571,14 +569,14 @@ static double bbox_max_radius(const BoundingBoxf3 &bbox, const Vec3d ¢er)
|
||||
return sqrt(r2max);
|
||||
}
|
||||
|
||||
static std::vector<FillAdaptive_Internal::CubeProperties> make_cubes_properties(double max_cube_edge_length, double line_spacing)
|
||||
static std::vector<CubeProperties> make_cubes_properties(double max_cube_edge_length, double line_spacing)
|
||||
{
|
||||
max_cube_edge_length += EPSILON;
|
||||
|
||||
std::vector<FillAdaptive_Internal::CubeProperties> cubes_properties;
|
||||
std::vector<CubeProperties> cubes_properties;
|
||||
for (double edge_length = line_spacing * 2.;; edge_length *= 2.)
|
||||
{
|
||||
FillAdaptive_Internal::CubeProperties props{};
|
||||
CubeProperties props{};
|
||||
props.edge_length = edge_length;
|
||||
props.height = edge_length * sqrt(3);
|
||||
props.diagonal_length = edge_length * sqrt(2);
|
||||
@ -598,7 +596,7 @@ static inline bool is_overhang_triangle(const Vec3d &a, const Vec3d &b, const Ve
|
||||
return n.dot(up) > 0.707 * n.norm();
|
||||
}
|
||||
|
||||
static void transform_center(FillAdaptive_Internal::Cube *current_cube, const Eigen::Matrix3d &rot)
|
||||
static void transform_center(Cube *current_cube, const Eigen::Matrix3d &rot)
|
||||
{
|
||||
#ifndef NDEBUG
|
||||
current_cube->center_octree = current_cube->center;
|
||||
@ -609,7 +607,7 @@ static void transform_center(FillAdaptive_Internal::Cube *current_cube, const Ei
|
||||
transform_center(child, rot);
|
||||
}
|
||||
|
||||
FillAdaptive_Internal::OctreePtr FillAdaptive_Internal::build_octree(const indexed_triangle_set &triangle_mesh, const Vec3d &up_vector, coordf_t line_spacing, bool support_overhangs_only)
|
||||
OctreePtr build_octree(const indexed_triangle_set &triangle_mesh, coordf_t line_spacing, bool support_overhangs_only)
|
||||
{
|
||||
assert(line_spacing > 0);
|
||||
assert(! std::isnan(line_spacing));
|
||||
@ -620,6 +618,7 @@ FillAdaptive_Internal::OctreePtr FillAdaptive_Internal::build_octree(const index
|
||||
auto octree = OctreePtr(new Octree(cube_center, cubes_properties));
|
||||
|
||||
if (cubes_properties.size() > 1) {
|
||||
auto up_vector = support_overhangs_only ? transform_to_octree() * Vec3d(0., 0., 1.) : Vec3d();
|
||||
for (auto &tri : triangle_mesh.indices) {
|
||||
auto a = triangle_mesh.vertices[tri[0]].cast<double>();
|
||||
auto b = triangle_mesh.vertices[tri[1]].cast<double>();
|
||||
@ -636,7 +635,7 @@ FillAdaptive_Internal::OctreePtr FillAdaptive_Internal::build_octree(const index
|
||||
}
|
||||
{
|
||||
// Transform the octree to world coordinates to reduce computation when extracting infill lines.
|
||||
auto rot = adaptive_fill_octree_transform_to_world().toRotationMatrix();
|
||||
auto rot = transform_to_world().toRotationMatrix();
|
||||
transform_center(octree->root_cube, rot);
|
||||
octree->origin = rot * octree->origin;
|
||||
}
|
||||
@ -645,7 +644,7 @@ FillAdaptive_Internal::OctreePtr FillAdaptive_Internal::build_octree(const index
|
||||
return octree;
|
||||
}
|
||||
|
||||
void FillAdaptive_Internal::Octree::insert_triangle(const Vec3d &a, const Vec3d &b, const Vec3d &c, Cube *current_cube, const BoundingBoxf3 ¤t_bbox, int depth)
|
||||
void Octree::insert_triangle(const Vec3d &a, const Vec3d &b, const Vec3d &c, Cube *current_cube, const BoundingBoxf3 ¤t_bbox, int depth)
|
||||
{
|
||||
assert(current_cube);
|
||||
assert(depth > 0);
|
||||
@ -673,4 +672,5 @@ void FillAdaptive_Internal::Octree::insert_triangle(const Vec3d &a, const Vec3d
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace FillAdaptive
|
||||
} // namespace Slic3r
|
||||
|
@ -11,8 +11,6 @@
|
||||
#ifndef slic3r_FillAdaptive_hpp_
|
||||
#define slic3r_FillAdaptive_hpp_
|
||||
|
||||
#include "../AABBTreeIndirect.hpp"
|
||||
|
||||
#include "FillBase.hpp"
|
||||
|
||||
struct indexed_triangle_set;
|
||||
@ -20,58 +18,55 @@ struct indexed_triangle_set;
|
||||
namespace Slic3r {
|
||||
|
||||
class PrintObject;
|
||||
namespace FillAdaptive_Internal
|
||||
|
||||
namespace FillAdaptive
|
||||
{
|
||||
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>;
|
||||
|
||||
// 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;
|
||||
// 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>;
|
||||
|
||||
// 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();
|
||||
// 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);
|
||||
|
||||
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
|
||||
// Rotation of the octree to stand on one of its corners.
|
||||
Eigen::Quaterniond transform_to_world();
|
||||
// Inverse roation of the above.
|
||||
Eigen::Quaterniond transform_to_octree();
|
||||
|
||||
FillAdaptive::OctreePtr build_octree(
|
||||
// Mesh is rotated to the coordinate system of the octree.
|
||||
const indexed_triangle_set &triangle_mesh,
|
||||
coordf_t line_spacing,
|
||||
// If true, octree is densified below internal overhangs only.
|
||||
bool support_overhangs_only);
|
||||
|
||||
//
|
||||
// Some of the algorithms used by class FillAdaptive were inspired by
|
||||
// Cura Engine's class SubDivCube
|
||||
// https://github.com/Ultimaker/CuraEngine/blob/master/src/infill/SubDivCube.h
|
||||
//
|
||||
class FillAdaptive : public Fill
|
||||
class Filler : public Slic3r::Fill
|
||||
{
|
||||
public:
|
||||
virtual ~FillAdaptive() {}
|
||||
virtual ~Filler() {}
|
||||
|
||||
protected:
|
||||
virtual Fill* clone() const { return new FillAdaptive(*this); };
|
||||
virtual Fill* clone() const { return new Filler(*this); };
|
||||
virtual void _fill_surface_single(
|
||||
const FillParams ¶ms,
|
||||
unsigned int thickness_layers,
|
||||
const std::pair<float, Point> &direction,
|
||||
ExPolygon &expolygon,
|
||||
Polylines &polylines_out);
|
||||
|
||||
virtual bool no_sort() const { return true; }
|
||||
};
|
||||
|
||||
}; // namespace FillAdaptive
|
||||
} // namespace Slic3r
|
||||
|
||||
#endif // slic3r_FillAdaptive_hpp_
|
||||
|
@ -38,8 +38,8 @@ Fill* Fill::new_from_type(const InfillPattern type)
|
||||
case ipArchimedeanChords: return new FillArchimedeanChords();
|
||||
case ipHilbertCurve: return new FillHilbertCurve();
|
||||
case ipOctagramSpiral: return new FillOctagramSpiral();
|
||||
case ipAdaptiveCubic: return new FillAdaptive();
|
||||
case ipSupportCubic: return new FillAdaptive();
|
||||
case ipAdaptiveCubic: return new FillAdaptive::Filler();
|
||||
case ipSupportCubic: return new FillAdaptive::Filler();
|
||||
default: throw Slic3r::InvalidArgument("unknown type");
|
||||
}
|
||||
}
|
||||
|
@ -20,7 +20,7 @@ class ExPolygon;
|
||||
class Surface;
|
||||
enum InfillPattern : int;
|
||||
|
||||
namespace FillAdaptive_Internal {
|
||||
namespace FillAdaptive {
|
||||
struct Octree;
|
||||
};
|
||||
|
||||
@ -76,7 +76,7 @@ public:
|
||||
BoundingBox bounding_box;
|
||||
|
||||
// Octree builds on mesh for usage in the adaptive cubic infill
|
||||
FillAdaptive_Internal::Octree* adapt_fill_octree = nullptr;
|
||||
FillAdaptive::Octree* adapt_fill_octree = nullptr;
|
||||
|
||||
public:
|
||||
virtual ~Fill() {}
|
||||
|
@ -13,7 +13,7 @@ class Layer;
|
||||
class PrintRegion;
|
||||
class PrintObject;
|
||||
|
||||
namespace FillAdaptive_Internal {
|
||||
namespace FillAdaptive {
|
||||
struct Octree;
|
||||
};
|
||||
|
||||
@ -139,7 +139,7 @@ public:
|
||||
}
|
||||
void make_perimeters();
|
||||
void make_fills() { this->make_fills(nullptr, nullptr); };
|
||||
void make_fills(FillAdaptive_Internal::Octree* adaptive_fill_octree, FillAdaptive_Internal::Octree* support_fill_octree);
|
||||
void make_fills(FillAdaptive::Octree* adaptive_fill_octree, FillAdaptive::Octree* support_fill_octree);
|
||||
void make_ironing();
|
||||
|
||||
void export_region_slices_to_svg(const char *path) const;
|
||||
|
@ -30,7 +30,7 @@ enum class SlicingMode : uint32_t;
|
||||
class Layer;
|
||||
class SupportLayer;
|
||||
|
||||
namespace FillAdaptive_Internal {
|
||||
namespace FillAdaptive {
|
||||
struct Octree;
|
||||
struct OctreeDeleter;
|
||||
using OctreePtr = std::unique_ptr<Octree, OctreeDeleter>;
|
||||
@ -241,7 +241,7 @@ private:
|
||||
void discover_horizontal_shells();
|
||||
void combine_infill();
|
||||
void _generate_support_material();
|
||||
std::pair<FillAdaptive_Internal::OctreePtr, FillAdaptive_Internal::OctreePtr> prepare_adaptive_infill_data();
|
||||
std::pair<FillAdaptive::OctreePtr, FillAdaptive::OctreePtr> prepare_adaptive_infill_data();
|
||||
|
||||
// XYZ in scaled coordinates
|
||||
Vec3crd m_size;
|
||||
|
@ -434,27 +434,22 @@ void PrintObject::generate_support_material()
|
||||
}
|
||||
}
|
||||
|
||||
std::pair<FillAdaptive_Internal::OctreePtr, FillAdaptive_Internal::OctreePtr> PrintObject::prepare_adaptive_infill_data()
|
||||
std::pair<FillAdaptive::OctreePtr, FillAdaptive::OctreePtr> PrintObject::prepare_adaptive_infill_data()
|
||||
{
|
||||
using namespace FillAdaptive_Internal;
|
||||
using namespace FillAdaptive;
|
||||
|
||||
auto [adaptive_line_spacing, support_line_spacing] = adaptive_fill_line_spacing(*this);
|
||||
if (adaptive_line_spacing == 0. && support_line_spacing == 0.)
|
||||
return std::make_pair(OctreePtr(), OctreePtr());
|
||||
|
||||
indexed_triangle_set mesh = this->model_object()->raw_indexed_triangle_set();
|
||||
Vec3d up;
|
||||
{
|
||||
auto m = adaptive_fill_octree_transform_to_octree().toRotationMatrix();
|
||||
up = m * Vec3d(0., 0., 1.);
|
||||
// Rotate mesh and build octree on it with axis-aligned (standart base) cubes
|
||||
Transform3d m2 = m_trafo;
|
||||
m2.translate(Vec3d(- unscale<float>(m_center_offset.x()), - unscale<float>(m_center_offset.y()), 0));
|
||||
its_transform(mesh, m * m2, true);
|
||||
}
|
||||
// Rotate mesh and build octree on it with axis-aligned (standart base) cubes.
|
||||
Transform3d m = m_trafo;
|
||||
m.translate(Vec3d(- unscale<float>(m_center_offset.x()), - unscale<float>(m_center_offset.y()), 0));
|
||||
its_transform(mesh, transform_to_octree().toRotationMatrix() * m, true);
|
||||
return std::make_pair(
|
||||
adaptive_line_spacing ? build_octree(mesh, up, adaptive_line_spacing, false) : OctreePtr(),
|
||||
support_line_spacing ? build_octree(mesh, up, support_line_spacing, true) : OctreePtr());
|
||||
adaptive_line_spacing ? build_octree(mesh, adaptive_line_spacing, false) : OctreePtr(),
|
||||
support_line_spacing ? build_octree(mesh, support_line_spacing, true) : OctreePtr());
|
||||
}
|
||||
|
||||
void PrintObject::clear_layers()
|
||||
|
Loading…
Reference in New Issue
Block a user