FIX: prevent slicing with adaptive layer height and organic support
Variable layer height is not supported with Organic supports. This is picked from Prusa. Thanks. jira: STUDIO-5614, STUDIO-5615 Change-Id: Iea462ecf8dd56e2a5a25cbe071519c29a2a763d3 (cherry picked from commit 708c5f0f7a00a30f9fe414b3dabe007ebdc48ca6)
This commit is contained in:
parent
1cea12e130
commit
f2b938ebc6
|
@ -410,6 +410,10 @@ public:
|
|||
bool is_seam_painted() const;
|
||||
// Checks if any of object volume is painted using the multi-material painting gizmo.
|
||||
bool is_mm_painted() const;
|
||||
// This object may have a varying layer height by painting or by a table.
|
||||
// Even if true is returned, the layer height profile may be "flat" with no difference to default layering.
|
||||
bool has_custom_layering() const
|
||||
{ return ! this->layer_config_ranges.empty() || ! this->layer_height_profile.empty(); }
|
||||
|
||||
ModelInstance* add_instance();
|
||||
ModelInstance* add_instance(const ModelInstance &instance);
|
||||
|
|
|
@ -1032,6 +1032,32 @@ StringObjectException Print::validate(StringObjectException *warning, Polygons*
|
|||
return {L("The spiral vase mode does not work when an object contains more than one materials."), nullptr, "spiral_mode"};
|
||||
}
|
||||
|
||||
// Cache of layer height profiles for checking:
|
||||
// 1) Whether all layers are synchronized if printing with wipe tower and / or unsynchronized supports.
|
||||
// 2) Whether layer height is constant for Organic supports.
|
||||
// 3) Whether build volume Z is not violated.
|
||||
std::vector<std::vector<coordf_t>> layer_height_profiles;
|
||||
auto layer_height_profile = [this, &layer_height_profiles](const size_t print_object_idx) -> const std::vector<coordf_t>& {
|
||||
const PrintObject &print_object = *m_objects[print_object_idx];
|
||||
if (layer_height_profiles.empty())
|
||||
layer_height_profiles.assign(m_objects.size(), std::vector<coordf_t>());
|
||||
std::vector<coordf_t> &profile = layer_height_profiles[print_object_idx];
|
||||
if (profile.empty())
|
||||
PrintObject::update_layer_height_profile(*print_object.model_object(), print_object.slicing_parameters(), profile);
|
||||
return profile;
|
||||
};
|
||||
|
||||
|
||||
// Custom layering is not allowed for tree supports as of now.
|
||||
for (size_t print_object_idx = 0; print_object_idx < m_objects.size(); ++ print_object_idx)
|
||||
if (const PrintObject &print_object = *m_objects[print_object_idx];
|
||||
print_object.has_support_material() && is_tree(print_object.config().support_type.value) && print_object.config().support_style.value == smsTreeOrganic &&
|
||||
print_object.model_object()->has_custom_layering()) {
|
||||
if (const std::vector<coordf_t> &layers = layer_height_profile(print_object_idx); ! layers.empty())
|
||||
if (! check_object_layers_fixed(print_object.slicing_parameters(), layers))
|
||||
return { L("Variable layer height is not supported with Organic supports.") };
|
||||
}
|
||||
|
||||
if (this->has_wipe_tower() && ! m_objects.empty()) {
|
||||
// Make sure all extruders use same diameter filament and have the same nozzle diameter
|
||||
// EPSILON comparison is used for nozzles and 10 % tolerance is used for filaments
|
||||
|
@ -1079,19 +1105,12 @@ StringObjectException Print::validate(StringObjectException *warning, Polygons*
|
|||
#endif
|
||||
|
||||
if (m_objects.size() > 1) {
|
||||
bool has_custom_layering = false;
|
||||
std::vector<std::vector<coordf_t>> layer_height_profiles;
|
||||
for (const PrintObject *object : m_objects) {
|
||||
has_custom_layering = ! object->model_object()->layer_config_ranges.empty() || ! object->model_object()->layer_height_profile.empty();
|
||||
if (has_custom_layering) {
|
||||
layer_height_profiles.assign(m_objects.size(), std::vector<coordf_t>());
|
||||
break;
|
||||
}
|
||||
}
|
||||
// Some of the objects has variable layer height applied by painting or by a table.
|
||||
bool has_custom_layering = std::any_of(m_objects.begin(), m_objects.end(),
|
||||
[](const PrintObject* object) { return object->model_object()->has_custom_layering(); });
|
||||
|
||||
const SlicingParameters &slicing_params0 = m_objects.front()->slicing_parameters();
|
||||
size_t tallest_object_idx = 0;
|
||||
if (has_custom_layering)
|
||||
PrintObject::update_layer_height_profile(*m_objects.front()->model_object(), slicing_params0, layer_height_profiles.front());
|
||||
for (size_t i = 1; i < m_objects.size(); ++ i) {
|
||||
const PrintObject *object = m_objects[i];
|
||||
const SlicingParameters &slicing_params = object->slicing_parameters();
|
||||
|
@ -1109,8 +1128,9 @@ StringObjectException Print::validate(StringObjectException *warning, Polygons*
|
|||
if (!equal_layering(slicing_params, slicing_params0))
|
||||
return { L("The prime tower requires that all objects are sliced with the same layer heights."), object };
|
||||
if (has_custom_layering) {
|
||||
PrintObject::update_layer_height_profile(*object->model_object(), slicing_params, layer_height_profiles[i]);
|
||||
if (*(layer_height_profiles[i].end()-2) > *(layer_height_profiles[tallest_object_idx].end()-2))
|
||||
auto &lh = layer_height_profile(i);
|
||||
auto &lh_tallest = layer_height_profile(tallest_object_idx);
|
||||
if (*(lh.end()-2) > *(lh_tallest.end()-2))
|
||||
tallest_object_idx = i;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -685,6 +685,40 @@ std::vector<coordf_t> generate_object_layers(
|
|||
return out;
|
||||
}
|
||||
|
||||
// Check whether the layer height profile describes a fixed layer height profile.
|
||||
bool check_object_layers_fixed(
|
||||
const SlicingParameters &slicing_params,
|
||||
const std::vector<coordf_t> &layer_height_profile)
|
||||
{
|
||||
assert(layer_height_profile.size() >= 4);
|
||||
assert(layer_height_profile.size() % 2 == 0);
|
||||
assert(layer_height_profile[0] == 0);
|
||||
|
||||
if (layer_height_profile.size() != 4 && layer_height_profile.size() != 8)
|
||||
return false;
|
||||
|
||||
bool fixed_step1 = is_approx(layer_height_profile[1], layer_height_profile[3]);
|
||||
bool fixed_step2 = layer_height_profile.size() == 4 ||
|
||||
(layer_height_profile[2] == layer_height_profile[4] && is_approx(layer_height_profile[5], layer_height_profile[7]));
|
||||
|
||||
if (! fixed_step1 || ! fixed_step2)
|
||||
return false;
|
||||
|
||||
if (layer_height_profile[2] < 0.5 * slicing_params.first_object_layer_height + EPSILON ||
|
||||
! is_approx(layer_height_profile[3], slicing_params.first_object_layer_height))
|
||||
return false;
|
||||
|
||||
double z_max = layer_height_profile[layer_height_profile.size() - 2];
|
||||
double z_2nd = slicing_params.first_object_layer_height + 0.5 * slicing_params.layer_height;
|
||||
if (z_2nd > z_max)
|
||||
return true;
|
||||
if (z_2nd < *(layer_height_profile.end() - 4) + EPSILON ||
|
||||
! is_approx(layer_height_profile.back(), slicing_params.layer_height))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int generate_layer_height_texture(
|
||||
const SlicingParameters &slicing_params,
|
||||
const std::vector<coordf_t> &layers,
|
||||
|
|
|
@ -175,6 +175,10 @@ extern std::vector<coordf_t> generate_object_layers(
|
|||
const SlicingParameters &slicing_params,
|
||||
const std::vector<coordf_t> &layer_height_profile);
|
||||
|
||||
// Check whether the layer height profile describes a fixed layer height profile.
|
||||
bool check_object_layers_fixed(
|
||||
const SlicingParameters &slicing_params,
|
||||
const std::vector<coordf_t> &layer_height_profile);
|
||||
// Produce a 1D texture packed into a 2D texture describing in the RGBA format
|
||||
// the planned object layers.
|
||||
// Returns number of cells used by the texture of the 0th LOD level.
|
||||
|
|
Loading…
Reference in New Issue