Merge branch 'master' of https://github.com/prusa3d/PrusaSlicer
This commit is contained in:
commit
659c24d3d8
3 changed files with 100 additions and 38 deletions
|
@ -3,12 +3,93 @@
|
||||||
#include "../Surface.hpp"
|
#include "../Surface.hpp"
|
||||||
#include "../Geometry.hpp"
|
#include "../Geometry.hpp"
|
||||||
#include "../AABBTreeIndirect.hpp"
|
#include "../AABBTreeIndirect.hpp"
|
||||||
|
#include "../Layer.hpp"
|
||||||
|
#include "../Print.hpp"
|
||||||
#include "../ShortestPath.hpp"
|
#include "../ShortestPath.hpp"
|
||||||
|
|
||||||
#include "FillAdaptive.hpp"
|
#include "FillAdaptive.hpp"
|
||||||
|
|
||||||
namespace Slic3r {
|
namespace Slic3r {
|
||||||
|
|
||||||
|
std::pair<double, double> adaptive_fill_line_spacing(const PrintObject &print_object)
|
||||||
|
{
|
||||||
|
// Output, spacing for icAdaptiveCubic and icSupportCubic
|
||||||
|
double adaptive_line_spacing = 0.;
|
||||||
|
double support_line_spacing = 0.;
|
||||||
|
|
||||||
|
enum class Tristate {
|
||||||
|
Yes,
|
||||||
|
No,
|
||||||
|
Maybe
|
||||||
|
};
|
||||||
|
struct RegionFillData {
|
||||||
|
Tristate has_adaptive_infill;
|
||||||
|
Tristate has_support_infill;
|
||||||
|
double density;
|
||||||
|
double extrusion_width;
|
||||||
|
};
|
||||||
|
std::vector<RegionFillData> region_fill_data;
|
||||||
|
region_fill_data.reserve(print_object.print()->regions().size());
|
||||||
|
bool build_octree = false;
|
||||||
|
for (const PrintRegion *region : print_object.print()->regions()) {
|
||||||
|
const PrintRegionConfig &config = region->config();
|
||||||
|
bool nonempty = config.fill_density > 0;
|
||||||
|
bool has_adaptive_infill = nonempty && config.fill_pattern == ipAdaptiveCubic;
|
||||||
|
bool has_support_infill = nonempty && false; // config.fill_pattern == icSupportCubic;
|
||||||
|
region_fill_data.push_back(RegionFillData({
|
||||||
|
has_adaptive_infill ? Tristate::Maybe : Tristate::No,
|
||||||
|
has_support_infill ? Tristate::Maybe : Tristate::No,
|
||||||
|
config.fill_density,
|
||||||
|
config.infill_extrusion_width
|
||||||
|
}));
|
||||||
|
build_octree |= has_adaptive_infill || has_support_infill;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (build_octree) {
|
||||||
|
// Compute the average of above parameters over all layers
|
||||||
|
for (const Layer *layer : print_object.layers())
|
||||||
|
for (size_t region_id = 0; region_id < layer->regions().size(); ++ region_id) {
|
||||||
|
RegionFillData &rd = region_fill_data[region_id];
|
||||||
|
if (rd.has_adaptive_infill == Tristate::Maybe && ! layer->regions()[region_id]->fill_surfaces.empty())
|
||||||
|
rd.has_adaptive_infill = Tristate::Yes;
|
||||||
|
if (rd.has_support_infill == Tristate::Maybe && ! layer->regions()[region_id]->fill_surfaces.empty())
|
||||||
|
rd.has_support_infill = Tristate::Yes;
|
||||||
|
}
|
||||||
|
|
||||||
|
double adaptive_fill_density = 0.;
|
||||||
|
double adaptive_infill_extrusion_width = 0.;
|
||||||
|
int adaptive_cnt = 0;
|
||||||
|
double support_fill_density = 0.;
|
||||||
|
double support_infill_extrusion_width = 0.;
|
||||||
|
int support_cnt = 0;
|
||||||
|
|
||||||
|
for (const RegionFillData &rd : region_fill_data) {
|
||||||
|
if (rd.has_adaptive_infill == Tristate::Yes) {
|
||||||
|
adaptive_fill_density += rd.density;
|
||||||
|
adaptive_infill_extrusion_width += rd.extrusion_width;
|
||||||
|
++ adaptive_cnt;
|
||||||
|
} else if (rd.has_support_infill == Tristate::Yes) {
|
||||||
|
support_fill_density += rd.density;
|
||||||
|
support_infill_extrusion_width += rd.extrusion_width;
|
||||||
|
++ support_cnt;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
auto to_line_spacing = [](int cnt, double density, double extrusion_width) {
|
||||||
|
if (cnt) {
|
||||||
|
density /= double(cnt);
|
||||||
|
extrusion_width /= double(cnt);
|
||||||
|
return extrusion_width / ((density / 100.0f) * 0.333333333f);
|
||||||
|
} else
|
||||||
|
return 0.;
|
||||||
|
};
|
||||||
|
adaptive_line_spacing = to_line_spacing(adaptive_cnt, adaptive_fill_density, adaptive_infill_extrusion_width);
|
||||||
|
support_line_spacing = to_line_spacing(support_cnt, support_fill_density, support_infill_extrusion_width);
|
||||||
|
}
|
||||||
|
|
||||||
|
return std::make_pair(adaptive_line_spacing, support_line_spacing);
|
||||||
|
}
|
||||||
|
|
||||||
void FillAdaptive::_fill_surface_single(
|
void FillAdaptive::_fill_surface_single(
|
||||||
const FillParams ¶ms,
|
const FillParams ¶ms,
|
||||||
unsigned int thickness_layers,
|
unsigned int thickness_layers,
|
||||||
|
@ -21,7 +102,7 @@ void FillAdaptive::_fill_surface_single(
|
||||||
this->generate_infill_lines(this->adapt_fill_octree->root_cube.get(),
|
this->generate_infill_lines(this->adapt_fill_octree->root_cube.get(),
|
||||||
this->z, this->adapt_fill_octree->origin,infill_lines_dir,
|
this->z, this->adapt_fill_octree->origin,infill_lines_dir,
|
||||||
this->adapt_fill_octree->cubes_properties,
|
this->adapt_fill_octree->cubes_properties,
|
||||||
this->adapt_fill_octree->cubes_properties.size() - 1);
|
int(this->adapt_fill_octree->cubes_properties.size()) - 1);
|
||||||
|
|
||||||
Polylines all_polylines;
|
Polylines all_polylines;
|
||||||
all_polylines.reserve(infill_lines_dir[0].size() * 3);
|
all_polylines.reserve(infill_lines_dir[0].size() * 3);
|
||||||
|
@ -131,16 +212,16 @@ void FillAdaptive::generate_infill_lines(
|
||||||
Point to(-from.x(), from.y());
|
Point to(-from.x(), from.y());
|
||||||
// Relative to cube center
|
// Relative to cube center
|
||||||
|
|
||||||
float rotation_angle = (2.0 * M_PI) / 3.0;
|
double rotation_angle = (2.0 * M_PI) / 3.0;
|
||||||
for (Lines &lines : dir_lines_out)
|
for (Lines &lines : dir_lines_out)
|
||||||
{
|
{
|
||||||
Vec3d offset = cube->center - origin;
|
Vec3d offset = cube->center - origin;
|
||||||
Point from_abs(from), to_abs(to);
|
Point from_abs(from), to_abs(to);
|
||||||
|
|
||||||
from_abs.x() += scale_(offset.x());
|
from_abs.x() += int(scale_(offset.x()));
|
||||||
from_abs.y() += scale_(offset.y());
|
from_abs.y() += int(scale_(offset.y()));
|
||||||
to_abs.x() += scale_(offset.x());
|
to_abs.x() += int(scale_(offset.x()));
|
||||||
to_abs.y() += scale_(offset.y());
|
to_abs.y() += int(scale_(offset.y()));
|
||||||
|
|
||||||
// lines.emplace_back(from_abs, to_abs);
|
// lines.emplace_back(from_abs, to_abs);
|
||||||
this->connect_lines(lines, Line(from_abs, to_abs));
|
this->connect_lines(lines, Line(from_abs, to_abs));
|
||||||
|
@ -161,7 +242,7 @@ void FillAdaptive::generate_infill_lines(
|
||||||
|
|
||||||
void FillAdaptive::connect_lines(Lines &lines, Line new_line)
|
void FillAdaptive::connect_lines(Lines &lines, Line new_line)
|
||||||
{
|
{
|
||||||
int eps = scale_(0.10);
|
auto eps = int(scale_(0.10));
|
||||||
for (size_t i = 0; i < lines.size(); ++i)
|
for (size_t i = 0; i < lines.size(); ++i)
|
||||||
{
|
{
|
||||||
if (std::abs(new_line.a.x() - lines[i].b.x()) < eps && std::abs(new_line.a.y() - lines[i].b.y()) < eps)
|
if (std::abs(new_line.a.x() - lines[i].b.x()) < eps && std::abs(new_line.a.y() - lines[i].b.y()) < eps)
|
||||||
|
@ -227,7 +308,7 @@ std::unique_ptr<FillAdaptive_Internal::Octree> FillAdaptive::build_octree(
|
||||||
triangle_mesh.its.vertices, triangle_mesh.its.indices);
|
triangle_mesh.its.vertices, triangle_mesh.its.indices);
|
||||||
auto octree = std::make_unique<Octree>(std::make_unique<Cube>(cube_center), cube_center, cubes_properties);
|
auto octree = std::make_unique<Octree>(std::make_unique<Cube>(cube_center), cube_center, cubes_properties);
|
||||||
|
|
||||||
FillAdaptive::expand_cube(octree->root_cube.get(), cubes_properties, rotation_matrix, aabbTree, triangle_mesh, cubes_properties.size() - 1);
|
FillAdaptive::expand_cube(octree->root_cube.get(), cubes_properties, rotation_matrix, aabbTree, triangle_mesh, int(cubes_properties.size()) - 1);
|
||||||
|
|
||||||
return octree;
|
return octree;
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,8 @@
|
||||||
|
|
||||||
namespace Slic3r {
|
namespace Slic3r {
|
||||||
|
|
||||||
|
class PrintObject;
|
||||||
|
|
||||||
namespace FillAdaptive_Internal
|
namespace FillAdaptive_Internal
|
||||||
{
|
{
|
||||||
struct CubeProperties
|
struct CubeProperties
|
||||||
|
@ -82,6 +84,12 @@ public:
|
||||||
int depth);
|
int depth);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 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
|
} // namespace Slic3r
|
||||||
|
|
||||||
#endif // slic3r_FillAdaptive_hpp_
|
#endif // slic3r_FillAdaptive_hpp_
|
||||||
|
|
|
@ -434,44 +434,17 @@ void PrintObject::generate_support_material()
|
||||||
|
|
||||||
std::unique_ptr<FillAdaptive_Internal::Octree> PrintObject::prepare_adaptive_infill_data()
|
std::unique_ptr<FillAdaptive_Internal::Octree> PrintObject::prepare_adaptive_infill_data()
|
||||||
{
|
{
|
||||||
float fill_density = 0;
|
auto [adaptive_line_spacing, support_line_spacing] = adaptive_fill_line_spacing(*this);
|
||||||
float infill_extrusion_width = 0;
|
if (adaptive_line_spacing == 0.)
|
||||||
|
|
||||||
// Compute the average of above parameters over all layers
|
|
||||||
for (size_t layer_idx = 0; layer_idx < this->m_layers.size(); ++layer_idx)
|
|
||||||
{
|
|
||||||
for (size_t region_id = 0; region_id < this->m_layers[layer_idx]->m_regions.size(); ++region_id)
|
|
||||||
{
|
|
||||||
LayerRegion *layerm = this->m_layers[layer_idx]->m_regions[region_id];
|
|
||||||
|
|
||||||
// Check if region_id is used for this layer
|
|
||||||
if(!layerm->fill_surfaces.surfaces.empty()) {
|
|
||||||
const PrintRegionConfig ®ion_config = layerm->region()->config();
|
|
||||||
|
|
||||||
fill_density += region_config.fill_density;
|
|
||||||
infill_extrusion_width += region_config.infill_extrusion_width;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fill_density /= this->m_layers.size();
|
|
||||||
infill_extrusion_width /= this->m_layers.size();
|
|
||||||
|
|
||||||
if(fill_density <= 0 || infill_extrusion_width <= 0)
|
|
||||||
{
|
|
||||||
return std::unique_ptr<FillAdaptive_Internal::Octree>{};
|
return std::unique_ptr<FillAdaptive_Internal::Octree>{};
|
||||||
}
|
|
||||||
|
|
||||||
coordf_t line_spacing = infill_extrusion_width / ((fill_density / 100.0f) * 0.333333333f);
|
|
||||||
|
|
||||||
TriangleMesh mesh = this->model_object()->raw_mesh();
|
TriangleMesh mesh = this->model_object()->raw_mesh();
|
||||||
mesh.transform(m_trafo, true);
|
mesh.transform(m_trafo, true);
|
||||||
// Apply XY shift
|
// Apply XY shift
|
||||||
mesh.translate(- unscale<float>(m_center_offset.x()), - unscale<float>(m_center_offset.y()), 0);
|
mesh.translate(- unscale<float>(m_center_offset.x()), - unscale<float>(m_center_offset.y()), 0);
|
||||||
|
|
||||||
// Center of the first cube in octree
|
// Center of the first cube in octree
|
||||||
Vec3d mesh_origin = mesh.bounding_box().center();
|
Vec3d mesh_origin = mesh.bounding_box().center();
|
||||||
return FillAdaptive::build_octree(mesh, line_spacing, mesh_origin);
|
return FillAdaptive::build_octree(mesh, adaptive_line_spacing, mesh_origin);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PrintObject::clear_layers()
|
void PrintObject::clear_layers()
|
||||||
|
|
Loading…
Reference in a new issue