ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE -> Refactoring of SlicingAdaptive to account for volumes' transformation
This commit is contained in:
parent
b77ba32bb2
commit
0001ce3dab
5 changed files with 104 additions and 41 deletions
|
@ -224,24 +224,38 @@ std::vector<coordf_t> layer_height_profile_from_ranges(
|
||||||
|
|
||||||
// Based on the work of @platsch
|
// Based on the work of @platsch
|
||||||
// Fill layer_height_profile by heights ensuring a prescribed maximum cusp height.
|
// Fill layer_height_profile by heights ensuring a prescribed maximum cusp height.
|
||||||
|
#if ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE
|
||||||
|
std::vector<coordf_t> layer_height_profile_adaptive(
|
||||||
|
const SlicingParameters& slicing_params,
|
||||||
|
const ModelObject& object)
|
||||||
|
#else
|
||||||
std::vector<coordf_t> layer_height_profile_adaptive(
|
std::vector<coordf_t> layer_height_profile_adaptive(
|
||||||
const SlicingParameters &slicing_params,
|
const SlicingParameters &slicing_params,
|
||||||
const t_layer_config_ranges & /* layer_config_ranges */,
|
const t_layer_config_ranges & /* layer_config_ranges */,
|
||||||
const ModelVolumePtrs &volumes)
|
const ModelVolumePtrs &volumes)
|
||||||
|
#endif // ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE
|
||||||
{
|
{
|
||||||
|
#if ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE
|
||||||
// 1) Initialize the SlicingAdaptive class with the object meshes.
|
// 1) Initialize the SlicingAdaptive class with the object meshes.
|
||||||
SlicingAdaptive as;
|
SlicingAdaptive as;
|
||||||
as.set_slicing_parameters(slicing_params);
|
as.set_slicing_parameters(slicing_params);
|
||||||
for (const ModelVolume *volume : volumes)
|
as.set_object(object);
|
||||||
|
#else
|
||||||
|
// 1) Initialize the SlicingAdaptive class with the object meshes.
|
||||||
|
SlicingAdaptive as;
|
||||||
|
as.set_slicing_parameters(slicing_params);
|
||||||
|
for (const ModelVolume* volume : volumes)
|
||||||
if (volume->is_model_part())
|
if (volume->is_model_part())
|
||||||
as.add_mesh(&volume->mesh());
|
as.add_mesh(&volume->mesh());
|
||||||
|
#endif // ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE
|
||||||
|
|
||||||
as.prepare();
|
as.prepare();
|
||||||
|
|
||||||
// 2) Generate layers using the algorithm of @platsch
|
// 2) Generate layers using the algorithm of @platsch
|
||||||
// loop until we have at least one layer and the max slice_z reaches the object height
|
// loop until we have at least one layer and the max slice_z reaches the object height
|
||||||
//FIXME make it configurable
|
//FIXME make it configurable
|
||||||
// Cusp value: A maximum allowed distance from a corner of a rectangular extrusion to a chrodal line, in mm.
|
// Cusp value: A maximum allowed distance from a corner of a rectangular extrusion to a chrodal line, in mm.
|
||||||
const coordf_t cusp_value = 0.2; // $self->config->get_value('cusp_value');
|
const double cusp_value = 0.2; // $self->config->get_value('cusp_value');
|
||||||
|
|
||||||
std::vector<coordf_t> layer_height_profile;
|
std::vector<coordf_t> layer_height_profile;
|
||||||
layer_height_profile.push_back(0.);
|
layer_height_profile.push_back(0.);
|
||||||
|
@ -250,14 +264,14 @@ std::vector<coordf_t> layer_height_profile_adaptive(
|
||||||
layer_height_profile.push_back(slicing_params.first_object_layer_height);
|
layer_height_profile.push_back(slicing_params.first_object_layer_height);
|
||||||
layer_height_profile.push_back(slicing_params.first_object_layer_height);
|
layer_height_profile.push_back(slicing_params.first_object_layer_height);
|
||||||
}
|
}
|
||||||
coordf_t slice_z = slicing_params.first_object_layer_height;
|
double slice_z = slicing_params.first_object_layer_height;
|
||||||
coordf_t height = slicing_params.first_object_layer_height;
|
double height = slicing_params.first_object_layer_height;
|
||||||
int current_facet = 0;
|
int current_facet = 0;
|
||||||
while ((slice_z - height) <= slicing_params.object_print_z_height()) {
|
while ((slice_z - height) <= slicing_params.object_print_z_height()) {
|
||||||
height = 999;
|
height = 999;
|
||||||
// Slic3r::debugf "\n Slice layer: %d\n", $id;
|
// Slic3r::debugf "\n Slice layer: %d\n", $id;
|
||||||
// determine next layer height
|
// determine next layer height
|
||||||
coordf_t cusp_height = as.cusp_height(slice_z, cusp_value, current_facet);
|
double cusp_height = as.cusp_height((float)slice_z, (float)cusp_value, current_facet);
|
||||||
// check for horizontal features and object size
|
// check for horizontal features and object size
|
||||||
/*
|
/*
|
||||||
if($self->config->get_value('match_horizontal_surfaces')) {
|
if($self->config->get_value('match_horizontal_surfaces')) {
|
||||||
|
|
|
@ -18,8 +18,12 @@ namespace Slic3r
|
||||||
|
|
||||||
class PrintConfig;
|
class PrintConfig;
|
||||||
class PrintObjectConfig;
|
class PrintObjectConfig;
|
||||||
|
#if ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE
|
||||||
|
class ModelObject;
|
||||||
|
#else
|
||||||
class ModelVolume;
|
class ModelVolume;
|
||||||
typedef std::vector<ModelVolume*> ModelVolumePtrs;
|
typedef std::vector<ModelVolume*> ModelVolumePtrs;
|
||||||
|
#endif // ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE
|
||||||
|
|
||||||
// Parameters to guide object slicing and support generation.
|
// Parameters to guide object slicing and support generation.
|
||||||
// The slicing parameters account for a raft and whether the 1st object layer is printed with a normal or a bridging flow
|
// The slicing parameters account for a raft and whether the 1st object layer is printed with a normal or a bridging flow
|
||||||
|
@ -138,11 +142,16 @@ extern std::vector<coordf_t> layer_height_profile_from_ranges(
|
||||||
const SlicingParameters &slicing_params,
|
const SlicingParameters &slicing_params,
|
||||||
const t_layer_config_ranges &layer_config_ranges);
|
const t_layer_config_ranges &layer_config_ranges);
|
||||||
|
|
||||||
|
#if ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE
|
||||||
|
extern std::vector<coordf_t> layer_height_profile_adaptive(
|
||||||
|
const SlicingParameters& slicing_params,
|
||||||
|
const ModelObject& object);
|
||||||
|
#else
|
||||||
extern std::vector<coordf_t> layer_height_profile_adaptive(
|
extern std::vector<coordf_t> layer_height_profile_adaptive(
|
||||||
const SlicingParameters &slicing_params,
|
const SlicingParameters &slicing_params,
|
||||||
const t_layer_config_ranges &layer_config_ranges,
|
const t_layer_config_ranges &layer_config_ranges,
|
||||||
const ModelVolumePtrs &volumes);
|
const ModelVolumePtrs &volumes);
|
||||||
|
#endif // ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE
|
||||||
|
|
||||||
enum LayerHeightEditActionType : unsigned int {
|
enum LayerHeightEditActionType : unsigned int {
|
||||||
LAYER_HEIGHT_EDIT_ACTION_INCREASE = 0,
|
LAYER_HEIGHT_EDIT_ACTION_INCREASE = 0,
|
||||||
|
|
|
@ -1,16 +1,22 @@
|
||||||
#include "libslic3r.h"
|
#include "libslic3r.h"
|
||||||
|
#if ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE
|
||||||
|
#include "Model.hpp"
|
||||||
|
#else
|
||||||
#include "TriangleMesh.hpp"
|
#include "TriangleMesh.hpp"
|
||||||
|
#endif // ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE
|
||||||
#include "SlicingAdaptive.hpp"
|
#include "SlicingAdaptive.hpp"
|
||||||
|
|
||||||
namespace Slic3r
|
namespace Slic3r
|
||||||
{
|
{
|
||||||
|
|
||||||
|
#if !ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE
|
||||||
void SlicingAdaptive::clear()
|
void SlicingAdaptive::clear()
|
||||||
{
|
{
|
||||||
m_meshes.clear();
|
m_meshes.clear();
|
||||||
m_faces.clear();
|
m_faces.clear();
|
||||||
m_face_normal_z.clear();
|
m_face_normal_z.clear();
|
||||||
}
|
}
|
||||||
|
#endif // !ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE
|
||||||
|
|
||||||
std::pair<float, float> face_z_span(const stl_facet *f)
|
std::pair<float, float> face_z_span(const stl_facet *f)
|
||||||
{
|
{
|
||||||
|
@ -21,21 +27,38 @@ std::pair<float, float> face_z_span(const stl_facet *f)
|
||||||
|
|
||||||
void SlicingAdaptive::prepare()
|
void SlicingAdaptive::prepare()
|
||||||
{
|
{
|
||||||
// 1) Collect faces of all meshes.
|
#if ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE
|
||||||
int nfaces_total = 0;
|
if (m_object == nullptr)
|
||||||
for (std::vector<const TriangleMesh*>::const_iterator it_mesh = m_meshes.begin(); it_mesh != m_meshes.end(); ++ it_mesh)
|
return;
|
||||||
|
|
||||||
|
m_faces.clear();
|
||||||
|
m_face_normal_z.clear();
|
||||||
|
|
||||||
|
m_mesh = m_object->raw_mesh();
|
||||||
|
const ModelInstance* first_instance = m_object->instances.front();
|
||||||
|
m_mesh.transform(first_instance->get_matrix(), first_instance->is_left_handed());
|
||||||
|
|
||||||
|
// 1) Collect faces from mesh.
|
||||||
|
m_faces.reserve(m_mesh.stl.stats.number_of_facets);
|
||||||
|
for (const stl_facet& face : m_mesh.stl.facet_start)
|
||||||
|
m_faces.emplace_back(&face);
|
||||||
|
#else
|
||||||
|
// 1) Collect faces of all meshes.
|
||||||
|
int nfaces_total = 0;
|
||||||
|
for (std::vector<const TriangleMesh*>::const_iterator it_mesh = m_meshes.begin(); it_mesh != m_meshes.end(); ++ it_mesh)
|
||||||
nfaces_total += (*it_mesh)->stl.stats.number_of_facets;
|
nfaces_total += (*it_mesh)->stl.stats.number_of_facets;
|
||||||
m_faces.reserve(nfaces_total);
|
m_faces.reserve(nfaces_total);
|
||||||
for (std::vector<const TriangleMesh*>::const_iterator it_mesh = m_meshes.begin(); it_mesh != m_meshes.end(); ++ it_mesh)
|
for (std::vector<const TriangleMesh*>::const_iterator it_mesh = m_meshes.begin(); it_mesh != m_meshes.end(); ++ it_mesh)
|
||||||
for (const stl_facet &face : (*it_mesh)->stl.facet_start)
|
for (const stl_facet& face : (*it_mesh)->stl.facet_start)
|
||||||
m_faces.emplace_back(&face);
|
m_faces.emplace_back(&face);
|
||||||
|
#endif // ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE
|
||||||
|
|
||||||
// 2) Sort faces lexicographically by their Z span.
|
// 2) Sort faces lexicographically by their Z span.
|
||||||
std::sort(m_faces.begin(), m_faces.end(), [](const stl_facet *f1, const stl_facet *f2) {
|
std::sort(m_faces.begin(), m_faces.end(), [](const stl_facet *f1, const stl_facet *f2) {
|
||||||
std::pair<float, float> span1 = face_z_span(f1);
|
std::pair<float, float> span1 = face_z_span(f1);
|
||||||
std::pair<float, float> span2 = face_z_span(f2);
|
std::pair<float, float> span2 = face_z_span(f2);
|
||||||
return span1 < span2;
|
return span1 < span2;
|
||||||
});
|
});
|
||||||
|
|
||||||
// 3) Generate Z components of the facet normals.
|
// 3) Generate Z components of the facet normals.
|
||||||
m_face_normal_z.assign(m_faces.size(), 0.f);
|
m_face_normal_z.assign(m_faces.size(), 0.f);
|
||||||
|
@ -45,14 +68,14 @@ void SlicingAdaptive::prepare()
|
||||||
|
|
||||||
float SlicingAdaptive::cusp_height(float z, float cusp_value, int ¤t_facet)
|
float SlicingAdaptive::cusp_height(float z, float cusp_value, int ¤t_facet)
|
||||||
{
|
{
|
||||||
float height = m_slicing_params.max_layer_height;
|
float height = (float)m_slicing_params.max_layer_height;
|
||||||
bool first_hit = false;
|
bool first_hit = false;
|
||||||
|
|
||||||
// find all facets intersecting the slice-layer
|
// find all facets intersecting the slice-layer
|
||||||
int ordered_id = current_facet;
|
int ordered_id = current_facet;
|
||||||
for (; ordered_id < int(m_faces.size()); ++ ordered_id) {
|
for (; ordered_id < int(m_faces.size()); ++ ordered_id) {
|
||||||
std::pair<float, float> zspan = face_z_span(m_faces[ordered_id]);
|
std::pair<float, float> zspan = face_z_span(m_faces[ordered_id]);
|
||||||
// facet's minimum is higher than slice_z -> end loop
|
// facet's minimum is higher than slice_z -> end loop
|
||||||
if (zspan.first >= z)
|
if (zspan.first >= z)
|
||||||
break;
|
break;
|
||||||
// facet's maximum is higher than slice_z -> store the first event for next cusp_height call to begin at this point
|
// facet's maximum is higher than slice_z -> store the first event for next cusp_height call to begin at this point
|
||||||
|
@ -77,8 +100,8 @@ float SlicingAdaptive::cusp_height(float z, float cusp_value, int ¤t_facet
|
||||||
// check for sloped facets inside the determined layer and correct height if necessary
|
// check for sloped facets inside the determined layer and correct height if necessary
|
||||||
if (height > m_slicing_params.min_layer_height) {
|
if (height > m_slicing_params.min_layer_height) {
|
||||||
for (; ordered_id < int(m_faces.size()); ++ ordered_id) {
|
for (; ordered_id < int(m_faces.size()); ++ ordered_id) {
|
||||||
std::pair<float, float> zspan = face_z_span(m_faces[ordered_id]);
|
std::pair<float, float> zspan = face_z_span(m_faces[ordered_id]);
|
||||||
// facet's minimum is higher than slice_z + height -> end loop
|
// facet's minimum is higher than slice_z + height -> end loop
|
||||||
if (zspan.first >= z + height)
|
if (zspan.first >= z + height)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -122,19 +145,18 @@ float SlicingAdaptive::cusp_height(float z, float cusp_value, int ¤t_facet
|
||||||
float SlicingAdaptive::horizontal_facet_distance(float z)
|
float SlicingAdaptive::horizontal_facet_distance(float z)
|
||||||
{
|
{
|
||||||
for (size_t i = 0; i < m_faces.size(); ++ i) {
|
for (size_t i = 0; i < m_faces.size(); ++ i) {
|
||||||
std::pair<float, float> zspan = face_z_span(m_faces[i]);
|
std::pair<float, float> zspan = face_z_span(m_faces[i]);
|
||||||
// facet's minimum is higher than max forward distance -> end loop
|
// facet's minimum is higher than max forward distance -> end loop
|
||||||
if (zspan.first > z + m_slicing_params.max_layer_height)
|
if (zspan.first > z + m_slicing_params.max_layer_height)
|
||||||
break;
|
break;
|
||||||
// min_z == max_z -> horizontal facet
|
// min_z == max_z -> horizontal facet
|
||||||
if (zspan.first > z && zspan.first == zspan.second)
|
if ((zspan.first > z) && (zspan.first == zspan.second))
|
||||||
return zspan.first - z;
|
return zspan.first - z;
|
||||||
}
|
}
|
||||||
|
|
||||||
// objects maximum?
|
// objects maximum?
|
||||||
return (z + m_slicing_params.max_layer_height > m_slicing_params.object_print_z_height()) ?
|
return (z + (float)m_slicing_params.max_layer_height > (float)m_slicing_params.object_print_z_height()) ?
|
||||||
std::max<float>(m_slicing_params.object_print_z_height() - z, 0.f) :
|
std::max((float)m_slicing_params.object_print_z_height() - z, 0.f) : (float)m_slicing_params.max_layer_height;
|
||||||
m_slicing_params.max_layer_height;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}; // namespace Slic3r
|
}; // namespace Slic3r
|
||||||
|
|
|
@ -5,29 +5,47 @@
|
||||||
|
|
||||||
#include "Slicing.hpp"
|
#include "Slicing.hpp"
|
||||||
#include "admesh/stl.h"
|
#include "admesh/stl.h"
|
||||||
|
#if ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE
|
||||||
|
#include "TriangleMesh.hpp"
|
||||||
|
#endif // ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE
|
||||||
|
|
||||||
namespace Slic3r
|
namespace Slic3r
|
||||||
{
|
{
|
||||||
|
|
||||||
|
#if ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE
|
||||||
|
class ModelVolume;
|
||||||
|
#else
|
||||||
class TriangleMesh;
|
class TriangleMesh;
|
||||||
|
#endif // ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE
|
||||||
|
|
||||||
class SlicingAdaptive
|
class SlicingAdaptive
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
void clear();
|
#if !ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE
|
||||||
void set_slicing_parameters(SlicingParameters params) { m_slicing_params = params; }
|
void clear();
|
||||||
void add_mesh(const TriangleMesh *mesh) { m_meshes.push_back(mesh); }
|
#endif // !ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE
|
||||||
void prepare();
|
void set_slicing_parameters(SlicingParameters params) { m_slicing_params = params; }
|
||||||
|
#if ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE
|
||||||
|
void set_object(const ModelObject& object) { m_object = &object; }
|
||||||
|
#else
|
||||||
|
void add_mesh(const TriangleMesh* mesh) { m_meshes.push_back(mesh); }
|
||||||
|
#endif // ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE
|
||||||
|
void prepare();
|
||||||
float cusp_height(float z, float cusp_value, int ¤t_facet);
|
float cusp_height(float z, float cusp_value, int ¤t_facet);
|
||||||
float horizontal_facet_distance(float z);
|
float horizontal_facet_distance(float z);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
SlicingParameters m_slicing_params;
|
SlicingParameters m_slicing_params;
|
||||||
|
|
||||||
std::vector<const TriangleMesh*> m_meshes;
|
#if ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE
|
||||||
// Collected faces of all meshes, sorted by raising Z of the bottom most face.
|
const ModelObject* m_object;
|
||||||
|
TriangleMesh m_mesh;
|
||||||
|
#else
|
||||||
|
std::vector<const TriangleMesh*> m_meshes;
|
||||||
|
#endif // ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE
|
||||||
|
// Collected faces of all meshes, sorted by raising Z of the bottom most face.
|
||||||
std::vector<const stl_facet*> m_faces;
|
std::vector<const stl_facet*> m_faces;
|
||||||
// Z component of face normals, normalized.
|
// Z component of face normals, normalized.
|
||||||
std::vector<float> m_face_normal_z;
|
std::vector<float> m_face_normal_z;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -266,13 +266,13 @@ void GLCanvas3D::LayersEditing::render_overlay(const GLCanvas3D& canvas) const
|
||||||
imgui.text(_(L("Increase/decrease edit area")));
|
imgui.text(_(L("Increase/decrease edit area")));
|
||||||
|
|
||||||
ImGui::Separator();
|
ImGui::Separator();
|
||||||
if (imgui.button(_(L("Reset"))))
|
|
||||||
wxPostEvent((wxEvtHandler*)canvas.get_wxglcanvas(), SimpleEvent(EVT_GLCANVAS_RESET_LAYER_HEIGHT_PROFILE));
|
|
||||||
|
|
||||||
ImGui::SameLine();
|
|
||||||
if (imgui.button(_(L("Adaptive"))))
|
if (imgui.button(_(L("Adaptive"))))
|
||||||
wxPostEvent((wxEvtHandler*)canvas.get_wxglcanvas(), SimpleEvent(EVT_GLCANVAS_ADAPTIVE_LAYER_HEIGHT_PROFILE));
|
wxPostEvent((wxEvtHandler*)canvas.get_wxglcanvas(), SimpleEvent(EVT_GLCANVAS_ADAPTIVE_LAYER_HEIGHT_PROFILE));
|
||||||
|
|
||||||
|
ImGui::SameLine();
|
||||||
|
if (imgui.button(_(L("Reset"))))
|
||||||
|
wxPostEvent((wxEvtHandler*)canvas.get_wxglcanvas(), SimpleEvent(EVT_GLCANVAS_RESET_LAYER_HEIGHT_PROFILE));
|
||||||
|
|
||||||
imgui.end();
|
imgui.end();
|
||||||
|
|
||||||
ImGui::PopStyleVar();
|
ImGui::PopStyleVar();
|
||||||
|
@ -577,8 +577,8 @@ void GLCanvas3D::LayersEditing::reset_layer_height_profile(GLCanvas3D& canvas)
|
||||||
#if ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE
|
#if ENABLE_ADAPTIVE_LAYER_HEIGHT_PROFILE
|
||||||
void GLCanvas3D::LayersEditing::adaptive_layer_height_profile(GLCanvas3D& canvas)
|
void GLCanvas3D::LayersEditing::adaptive_layer_height_profile(GLCanvas3D& canvas)
|
||||||
{
|
{
|
||||||
const_cast<ModelObject*>(m_model_object)->layer_height_profile.clear();
|
m_layer_height_profile = layer_height_profile_adaptive(*m_slicing_parameters, *m_model_object);
|
||||||
m_layer_height_profile = layer_height_profile_adaptive(*m_slicing_parameters, m_model_object->layer_config_ranges, m_model_object->volumes);
|
const_cast<ModelObject*>(m_model_object)->layer_height_profile = m_layer_height_profile;
|
||||||
m_layers_texture.valid = false;
|
m_layers_texture.valid = false;
|
||||||
canvas.post_event(SimpleEvent(EVT_GLCANVAS_SCHEDULE_BACKGROUND_PROCESS));
|
canvas.post_event(SimpleEvent(EVT_GLCANVAS_SCHEDULE_BACKGROUND_PROCESS));
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue