mirror of
https://github.com/SoftFever/OrcaSlicer.git
synced 2025-07-08 07:27:41 -06:00
Ported filament shrinkage compensation for XY and independent Z from Prusa Slicer (fixing MMU painting, seam painting, support painting issues) (#6507)
* Ported filament shrinkage compensation from Prusa Slicer. Updated logic to be 100 = no shrinkage to be consistent with orca definitions * Code comments update * Merge branch 'main' into Filament-Shrinkage-compension---port-from-Prusa-slicer * Merge remote-tracking branch 'upstream/main' into Filament-Shrinkage-compension---port-from-Prusa-slicer * Merge branch 'main' into Filament-Shrinkage-compension---port-from-Prusa-slicer
This commit is contained in:
parent
d1e7bb2762
commit
0ba4181a06
17 changed files with 198 additions and 52 deletions
|
@ -640,6 +640,22 @@ Transform3d Transformation::get_matrix_no_scaling_factor() const
|
||||||
return copy.get_matrix();
|
return copy.get_matrix();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Orca: Implement prusa's filament shrink compensation approach
|
||||||
|
Transform3d Transformation::get_matrix_with_applied_shrinkage_compensation(const Vec3d &shrinkage_compensation) const {
|
||||||
|
const Transform3d shrinkage_trafo = Geometry::scale_transform(shrinkage_compensation);
|
||||||
|
const Vec3d trafo_offset = this->get_offset();
|
||||||
|
const Vec3d trafo_offset_xy = Vec3d(trafo_offset.x(), trafo_offset.y(), 0.);
|
||||||
|
|
||||||
|
Transformation copy(*this);
|
||||||
|
copy.set_offset(Axis::X, 0.);
|
||||||
|
copy.set_offset(Axis::Y, 0.);
|
||||||
|
|
||||||
|
Transform3d trafo_after_shrinkage = (shrinkage_trafo * copy.get_matrix());
|
||||||
|
trafo_after_shrinkage.translation() += trafo_offset_xy;
|
||||||
|
|
||||||
|
return trafo_after_shrinkage;
|
||||||
|
}
|
||||||
|
|
||||||
Transformation Transformation::operator * (const Transformation& other) const
|
Transformation Transformation::operator * (const Transformation& other) const
|
||||||
{
|
{
|
||||||
return Transformation(get_matrix() * other.get_matrix());
|
return Transformation(get_matrix() * other.get_matrix());
|
||||||
|
|
|
@ -466,6 +466,9 @@ public:
|
||||||
Transform3d get_matrix_no_offset() const;
|
Transform3d get_matrix_no_offset() const;
|
||||||
Transform3d get_matrix_no_scaling_factor() const;
|
Transform3d get_matrix_no_scaling_factor() const;
|
||||||
|
|
||||||
|
// Orca: Implement prusa's filament shrink compensation approach
|
||||||
|
Transform3d get_matrix_with_applied_shrinkage_compensation(const Vec3d &shrinkage_compensation) const;
|
||||||
|
|
||||||
void set_matrix(const Transform3d& transform) { m_matrix = transform; }
|
void set_matrix(const Transform3d& transform) { m_matrix = transform; }
|
||||||
|
|
||||||
Transformation operator * (const Transformation& other) const;
|
Transformation operator * (const Transformation& other) const;
|
||||||
|
|
|
@ -2779,6 +2779,24 @@ void ModelVolume::convert_from_meters()
|
||||||
this->source.is_converted_from_meters = true;
|
this->source.is_converted_from_meters = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Orca: Implement prusa's filament shrink compensation approach
|
||||||
|
// Returns 0-based indices of extruders painted by multi-material painting gizmo.
|
||||||
|
std::vector<size_t> ModelVolume::get_extruders_from_multi_material_painting() const {
|
||||||
|
if (!this->is_mm_painted())
|
||||||
|
return {};
|
||||||
|
|
||||||
|
assert(static_cast<size_t>(TriangleStateType::Extruder1) - 1 == 0);
|
||||||
|
const TriangleSelector::TriangleSplittingData &data = this->mmu_segmentation_facets.get_data();
|
||||||
|
|
||||||
|
std::vector<size_t> extruders;
|
||||||
|
for (size_t state_idx = static_cast<size_t>(EnforcerBlockerType::Extruder1); state_idx < data.used_states.size(); ++state_idx) {
|
||||||
|
if (data.used_states[state_idx])
|
||||||
|
extruders.emplace_back(state_idx - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return extruders;
|
||||||
|
}
|
||||||
|
|
||||||
void ModelInstance::transform_mesh(TriangleMesh* mesh, bool dont_translate) const
|
void ModelInstance::transform_mesh(TriangleMesh* mesh, bool dont_translate) const
|
||||||
{
|
{
|
||||||
mesh->transform(dont_translate ? get_matrix_no_offset() : get_matrix());
|
mesh->transform(dont_translate ? get_matrix_no_offset() : get_matrix());
|
||||||
|
|
|
@ -992,6 +992,10 @@ public:
|
||||||
bool is_seam_painted() const { return !this->seam_facets.empty(); }
|
bool is_seam_painted() const { return !this->seam_facets.empty(); }
|
||||||
bool is_mm_painted() const { return !this->mmu_segmentation_facets.empty(); }
|
bool is_mm_painted() const { return !this->mmu_segmentation_facets.empty(); }
|
||||||
|
|
||||||
|
// Orca: Implement prusa's filament shrink compensation approach
|
||||||
|
// Returns 0-based indices of extruders painted by multi-material painting gizmo.
|
||||||
|
std::vector<size_t> get_extruders_from_multi_material_painting() const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
friend class Print;
|
friend class Print;
|
||||||
friend class SLAPrint;
|
friend class SLAPrint;
|
||||||
|
|
|
@ -840,7 +840,7 @@ static std::vector<std::string> s_Preset_filament_options {
|
||||||
"filament_wipe_distance", "additional_cooling_fan_speed",
|
"filament_wipe_distance", "additional_cooling_fan_speed",
|
||||||
"nozzle_temperature_range_low", "nozzle_temperature_range_high",
|
"nozzle_temperature_range_low", "nozzle_temperature_range_high",
|
||||||
//SoftFever
|
//SoftFever
|
||||||
"enable_pressure_advance", "pressure_advance","adaptive_pressure_advance","adaptive_pressure_advance_model","adaptive_pressure_advance_overhangs", "adaptive_pressure_advance_bridges","chamber_temperature", "filament_shrink", "support_material_interface_fan_speed", "filament_notes" /*,"filament_seam_gap"*/,
|
"enable_pressure_advance", "pressure_advance","adaptive_pressure_advance","adaptive_pressure_advance_model","adaptive_pressure_advance_overhangs", "adaptive_pressure_advance_bridges","chamber_temperature", "filament_shrink","filament_shrinkage_compensation_z", "support_material_interface_fan_speed", "filament_notes" /*,"filament_seam_gap"*/,
|
||||||
"filament_loading_speed", "filament_loading_speed_start",
|
"filament_loading_speed", "filament_loading_speed_start",
|
||||||
"filament_unloading_speed", "filament_unloading_speed_start", "filament_toolchange_delay", "filament_cooling_moves", "filament_stamping_loading_speed", "filament_stamping_distance",
|
"filament_unloading_speed", "filament_unloading_speed_start", "filament_toolchange_delay", "filament_cooling_moves", "filament_stamping_loading_speed", "filament_stamping_distance",
|
||||||
"filament_cooling_initial_speed", "filament_cooling_final_speed", "filament_ramming_parameters",
|
"filament_cooling_initial_speed", "filament_cooling_final_speed", "filament_ramming_parameters",
|
||||||
|
|
|
@ -234,6 +234,7 @@ bool Print::invalidate_state_by_config_options(const ConfigOptionResolver & /* n
|
||||||
opt_key == "initial_layer_print_height"
|
opt_key == "initial_layer_print_height"
|
||||||
|| opt_key == "nozzle_diameter"
|
|| opt_key == "nozzle_diameter"
|
||||||
|| opt_key == "filament_shrink"
|
|| opt_key == "filament_shrink"
|
||||||
|
|| opt_key == "filament_shrinkage_compensation_z"
|
||||||
|| opt_key == "resolution"
|
|| opt_key == "resolution"
|
||||||
|| opt_key == "precise_z_height"
|
|| opt_key == "precise_z_height"
|
||||||
// Spiral Vase forces different kind of slicing than the normal model:
|
// Spiral Vase forces different kind of slicing than the normal model:
|
||||||
|
@ -1120,13 +1121,29 @@ StringObjectException Print::validate(StringObjectException *warning, Polygons*
|
||||||
const PrintObject &print_object = *m_objects[print_object_idx];
|
const PrintObject &print_object = *m_objects[print_object_idx];
|
||||||
//FIXME It is quite expensive to generate object layers just to get the print height!
|
//FIXME It is quite expensive to generate object layers just to get the print height!
|
||||||
if (auto layers = generate_object_layers(print_object.slicing_parameters(), layer_height_profile(print_object_idx), print_object.config().precise_z_height.value);
|
if (auto layers = generate_object_layers(print_object.slicing_parameters(), layer_height_profile(print_object_idx), print_object.config().precise_z_height.value);
|
||||||
! layers.empty() && layers.back() > this->config().printable_height + EPSILON) {
|
!layers.empty()) {
|
||||||
return
|
|
||||||
|
Vec3d test =this->shrinkage_compensation();
|
||||||
|
const double shrinkage_compensation_z = this->shrinkage_compensation().z();
|
||||||
|
|
||||||
|
if (shrinkage_compensation_z != 1. && layers.back() > (this->config().printable_height / shrinkage_compensation_z + EPSILON)) {
|
||||||
|
// The object exceeds the maximum build volume height because of shrinkage compensation.
|
||||||
|
return StringObjectException{
|
||||||
|
Slic3r::format(_u8L("While the object %1% itself fits the build volume, it exceeds the maximum build volume height because of material shrinkage compensation."), print_object.model_object()->name),
|
||||||
|
print_object.model_object(),
|
||||||
|
""
|
||||||
|
};
|
||||||
|
} else if (layers.back() > this->config().printable_height + EPSILON) {
|
||||||
// Test whether the last slicing plane is below or above the print volume.
|
// Test whether the last slicing plane is below or above the print volume.
|
||||||
{ 0.5 * (layers[layers.size() - 2] + layers.back()) > this->config().printable_height + EPSILON ?
|
return StringObjectException{
|
||||||
|
0.5 * (layers[layers.size() - 2] + layers.back()) > this->config().printable_height + EPSILON ?
|
||||||
Slic3r::format(_u8L("The object %1% exceeds the maximum build volume height."), print_object.model_object()->name) :
|
Slic3r::format(_u8L("The object %1% exceeds the maximum build volume height."), print_object.model_object()->name) :
|
||||||
Slic3r::format(_u8L("While the object %1% itself fits the build volume, its last layer exceeds the maximum build volume height."), print_object.model_object()->name) +
|
Slic3r::format(_u8L("While the object %1% itself fits the build volume, its last layer exceeds the maximum build volume height."), print_object.model_object()->name) +
|
||||||
" " + _u8L("You might want to reduce the size of your model or change current print settings and retry.") };
|
" " + _u8L("You might want to reduce the size of your model or change current print settings and retry."),
|
||||||
|
print_object.model_object(),
|
||||||
|
""
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1568,6 +1585,10 @@ StringObjectException Print::validate(StringObjectException *warning, Polygons*
|
||||||
BOOST_LOG_TRIVIAL(warning) << "Orca: validate motion ability failed: " << e.what() << std::endl;
|
BOOST_LOG_TRIVIAL(warning) << "Orca: validate motion ability failed: " << e.what() << std::endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (!this->has_same_shrinkage_compensations()){
|
||||||
|
warning->string = L("Filament shrinkage will not be used because filament shrinkage for the used filaments differs significantly.");
|
||||||
|
warning->opt_key = "";
|
||||||
|
}
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2949,6 +2970,44 @@ std::string PrintStatistics::finalize_output_path(const std::string &path_in) co
|
||||||
return final_path;
|
return final_path;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Orca: Implement prusa's filament shrink compensation approach
|
||||||
|
// Returns if all used filaments have same shrinkage compensations.
|
||||||
|
bool Print::has_same_shrinkage_compensations() const {
|
||||||
|
const std::vector<unsigned int> extruders = this->extruders();
|
||||||
|
if (extruders.empty())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
const double filament_shrinkage_compensation_xy = m_config.filament_shrink.get_at(extruders.front());
|
||||||
|
const double filament_shrinkage_compensation_z = m_config.filament_shrinkage_compensation_z.get_at(extruders.front());
|
||||||
|
|
||||||
|
for (unsigned int extruder : extruders) {
|
||||||
|
if (filament_shrinkage_compensation_xy != m_config.filament_shrink.get_at(extruder) ||
|
||||||
|
filament_shrinkage_compensation_z != m_config.filament_shrinkage_compensation_z.get_at(extruder)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Orca: Implement prusa's filament shrink compensation approach, but amended so 100% from the user is the equivalent to 0 in orca.
|
||||||
|
// Returns scaling for each axis representing shrinkage compensations in each axis.
|
||||||
|
Vec3d Print::shrinkage_compensation() const
|
||||||
|
{
|
||||||
|
if (!this->has_same_shrinkage_compensations())
|
||||||
|
return Vec3d::Ones();
|
||||||
|
|
||||||
|
const unsigned int first_extruder = this->extruders().front();
|
||||||
|
|
||||||
|
const double xy_shrinkage_percent = m_config.filament_shrink.get_at(first_extruder);
|
||||||
|
const double z_shrinkage_percent = m_config.filament_shrinkage_compensation_z.get_at(first_extruder);
|
||||||
|
|
||||||
|
const double xy_compensation = 100.0 / xy_shrinkage_percent;
|
||||||
|
const double z_compensation = 100.0 / z_shrinkage_percent;
|
||||||
|
|
||||||
|
return { xy_compensation, xy_compensation, z_compensation };
|
||||||
|
}
|
||||||
|
|
||||||
const std::string PrintStatistics::FilamentUsedG = "filament used [g]";
|
const std::string PrintStatistics::FilamentUsedG = "filament used [g]";
|
||||||
const std::string PrintStatistics::FilamentUsedGMask = "; filament used [g] =";
|
const std::string PrintStatistics::FilamentUsedGMask = "; filament used [g] =";
|
||||||
|
|
||||||
|
|
|
@ -401,7 +401,8 @@ public:
|
||||||
// The slicing parameters are dependent on various configuration values
|
// The slicing parameters are dependent on various configuration values
|
||||||
// (layer height, first layer height, raft settings, print nozzle diameter etc).
|
// (layer height, first layer height, raft settings, print nozzle diameter etc).
|
||||||
const SlicingParameters& slicing_parameters() const { return m_slicing_params; }
|
const SlicingParameters& slicing_parameters() const { return m_slicing_params; }
|
||||||
static SlicingParameters slicing_parameters(const DynamicPrintConfig &full_config, const ModelObject &model_object, float object_max_z);
|
// Orca: XYZ shrinkage compensation has introduced the const Vec3d &object_shrinkage_compensation parameter to the function below
|
||||||
|
static SlicingParameters slicing_parameters(const DynamicPrintConfig &full_config, const ModelObject &model_object, float object_max_z, const Vec3d &object_shrinkage_compensation);
|
||||||
|
|
||||||
size_t num_printing_regions() const throw() { return m_shared_regions->all_regions.size(); }
|
size_t num_printing_regions() const throw() { return m_shared_regions->all_regions.size(); }
|
||||||
const PrintRegion& printing_region(size_t idx) const throw() { return *m_shared_regions->all_regions[idx].get(); }
|
const PrintRegion& printing_region(size_t idx) const throw() { return *m_shared_regions->all_regions[idx].get(); }
|
||||||
|
@ -982,6 +983,12 @@ public:
|
||||||
return std::all_of(this->objects().begin(), this->objects().end(), [&](PrintObject* obj) { return obj->height() < scale_(this->config().nozzle_height.value); });
|
return std::all_of(this->objects().begin(), this->objects().end(), [&](PrintObject* obj) { return obj->height() < scale_(this->config().nozzle_height.value); });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Orca: Implement prusa's filament shrink compensation approach
|
||||||
|
// Returns if all used filaments have same shrinkage compensations.
|
||||||
|
bool has_same_shrinkage_compensations() const;
|
||||||
|
// Returns scaling for each axis representing shrinkage compensations in each axis.
|
||||||
|
Vec3d shrinkage_compensation() const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// Invalidates the step, and its depending steps in Print.
|
// Invalidates the step, and its depending steps in Print.
|
||||||
bool invalidate_step(PrintStep step);
|
bool invalidate_step(PrintStep step);
|
||||||
|
|
|
@ -131,7 +131,8 @@ struct PrintObjectTrafoAndInstances
|
||||||
};
|
};
|
||||||
|
|
||||||
// Generate a list of trafos and XY offsets for instances of a ModelObject
|
// Generate a list of trafos and XY offsets for instances of a ModelObject
|
||||||
static std::vector<PrintObjectTrafoAndInstances> print_objects_from_model_object(const ModelObject &model_object)
|
// Orca: Updated to include XYZ filament shrinkage compensation
|
||||||
|
static std::vector<PrintObjectTrafoAndInstances> print_objects_from_model_object(const ModelObject &model_object, const Vec3d &shrinkage_compensation)
|
||||||
{
|
{
|
||||||
std::set<PrintObjectTrafoAndInstances> trafos;
|
std::set<PrintObjectTrafoAndInstances> trafos;
|
||||||
PrintObjectTrafoAndInstances trafo;
|
PrintObjectTrafoAndInstances trafo;
|
||||||
|
@ -139,7 +140,10 @@ static std::vector<PrintObjectTrafoAndInstances> print_objects_from_model_object
|
||||||
int index = 0;
|
int index = 0;
|
||||||
for (ModelInstance *model_instance : model_object.instances) {
|
for (ModelInstance *model_instance : model_object.instances) {
|
||||||
if (model_instance->is_printable()) {
|
if (model_instance->is_printable()) {
|
||||||
trafo.trafo = model_instance->get_matrix();
|
// Orca: Updated with XYZ filament shrinkage compensation
|
||||||
|
Geometry::Transformation model_instance_transformation = model_instance->get_transformation();
|
||||||
|
trafo.trafo = model_instance_transformation.get_matrix_with_applied_shrinkage_compensation(shrinkage_compensation);
|
||||||
|
|
||||||
auto shift = Point::new_scale(trafo.trafo.data()[12], trafo.trafo.data()[13]);
|
auto shift = Point::new_scale(trafo.trafo.data()[12], trafo.trafo.data()[13]);
|
||||||
// Reset the XY axes of the transformation.
|
// Reset the XY axes of the transformation.
|
||||||
trafo.trafo.data()[12] = 0;
|
trafo.trafo.data()[12] = 0;
|
||||||
|
@ -1358,7 +1362,8 @@ Print::ApplyStatus Print::apply(const Model &model, DynamicPrintConfig new_full_
|
||||||
// Walk over all new model objects and check, whether there are matching PrintObjects.
|
// Walk over all new model objects and check, whether there are matching PrintObjects.
|
||||||
for (ModelObject *model_object : m_model.objects) {
|
for (ModelObject *model_object : m_model.objects) {
|
||||||
ModelObjectStatus &model_object_status = const_cast<ModelObjectStatus&>(model_object_status_db.reuse(*model_object));
|
ModelObjectStatus &model_object_status = const_cast<ModelObjectStatus&>(model_object_status_db.reuse(*model_object));
|
||||||
model_object_status.print_instances = print_objects_from_model_object(*model_object);
|
// Orca: Updated for XYZ filament shrink compensation
|
||||||
|
model_object_status.print_instances = print_objects_from_model_object(*model_object, this->shrinkage_compensation());
|
||||||
std::vector<const PrintObjectStatus*> old;
|
std::vector<const PrintObjectStatus*> old;
|
||||||
old.reserve(print_object_status_db.count(*model_object));
|
old.reserve(print_object_status_db.count(*model_object));
|
||||||
for (const PrintObjectStatus &print_object_status : print_object_status_db.get_range(*model_object))
|
for (const PrintObjectStatus &print_object_status : print_object_status_db.get_range(*model_object))
|
||||||
|
|
|
@ -1907,7 +1907,7 @@ void PrintConfigDef::init_fff_params()
|
||||||
def->set_default_value(new ConfigOptionFloats{ 0.4157 });
|
def->set_default_value(new ConfigOptionFloats{ 0.4157 });
|
||||||
|
|
||||||
def = this->add("filament_shrink", coPercents);
|
def = this->add("filament_shrink", coPercents);
|
||||||
def->label = L("Shrinkage");
|
def->label = L("Shrinkage (XY)");
|
||||||
// xgettext:no-c-format, no-boost-format
|
// xgettext:no-c-format, no-boost-format
|
||||||
def->tooltip = L("Enter the shrinkage percentage that the filament will get after cooling (94% if you measure 94mm instead of 100mm)."
|
def->tooltip = L("Enter the shrinkage percentage that the filament will get after cooling (94% if you measure 94mm instead of 100mm)."
|
||||||
" The part will be scaled in xy to compensate."
|
" The part will be scaled in xy to compensate."
|
||||||
|
@ -1919,6 +1919,16 @@ void PrintConfigDef::init_fff_params()
|
||||||
def->mode = comAdvanced;
|
def->mode = comAdvanced;
|
||||||
def->set_default_value(new ConfigOptionPercents{ 100 });
|
def->set_default_value(new ConfigOptionPercents{ 100 });
|
||||||
|
|
||||||
|
def = this->add("filament_shrinkage_compensation_z", coPercents);
|
||||||
|
def->label = L("Shrinkage (Z)");
|
||||||
|
def->tooltip = L("Enter the shrinkage percentage that the filament will get after cooling (94% if you measure 94mm instead of 100mm)."
|
||||||
|
" The part will be scaled in Z to compensate.");
|
||||||
|
def->sidetext = L("%");
|
||||||
|
def->ratio_over = "";
|
||||||
|
def->min = 10;
|
||||||
|
def->mode = comAdvanced;
|
||||||
|
def->set_default_value(new ConfigOptionPercents{ 100 });
|
||||||
|
|
||||||
def = this->add("filament_loading_speed", coFloats);
|
def = this->add("filament_loading_speed", coFloats);
|
||||||
def->label = L("Loading speed");
|
def->label = L("Loading speed");
|
||||||
def->tooltip = L("Speed used for loading the filament on the wipe tower.");
|
def->tooltip = L("Speed used for loading the filament on the wipe tower.");
|
||||||
|
|
|
@ -1274,6 +1274,7 @@ PRINT_CONFIG_CLASS_DERIVED_DEFINE(
|
||||||
((ConfigOptionBool, independent_support_layer_height))
|
((ConfigOptionBool, independent_support_layer_height))
|
||||||
// SoftFever
|
// SoftFever
|
||||||
((ConfigOptionPercents, filament_shrink))
|
((ConfigOptionPercents, filament_shrink))
|
||||||
|
((ConfigOptionPercents, filament_shrinkage_compensation_z))
|
||||||
((ConfigOptionBool, gcode_label_objects))
|
((ConfigOptionBool, gcode_label_objects))
|
||||||
((ConfigOptionBool, exclude_object))
|
((ConfigOptionBool, exclude_object))
|
||||||
((ConfigOptionBool, gcode_comments))
|
((ConfigOptionBool, gcode_comments))
|
||||||
|
|
|
@ -2966,12 +2966,15 @@ void PrintObject::generate_support_preview()
|
||||||
|
|
||||||
void PrintObject::update_slicing_parameters()
|
void PrintObject::update_slicing_parameters()
|
||||||
{
|
{
|
||||||
if (!m_slicing_params.valid)
|
// Orca: updated function call for XYZ shrinkage compensation
|
||||||
m_slicing_params = SlicingParameters::create_from_config(
|
if (!m_slicing_params.valid) {
|
||||||
this->print()->config(), m_config, this->model_object()->max_z(), this->object_extruders());
|
m_slicing_params = SlicingParameters::create_from_config(this->print()->config(), m_config, this->model_object()->max_z(),
|
||||||
|
this->object_extruders(), this->print()->shrinkage_compensation());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SlicingParameters PrintObject::slicing_parameters(const DynamicPrintConfig& full_config, const ModelObject& model_object, float object_max_z)
|
// Orca: XYZ shrinkage compensation has introduced the const Vec3d &object_shrinkage_compensation parameter to the function below
|
||||||
|
SlicingParameters PrintObject::slicing_parameters(const DynamicPrintConfig &full_config, const ModelObject &model_object, float object_max_z, const Vec3d &object_shrinkage_compensation)
|
||||||
{
|
{
|
||||||
PrintConfig print_config;
|
PrintConfig print_config;
|
||||||
PrintObjectConfig object_config;
|
PrintObjectConfig object_config;
|
||||||
|
@ -3006,7 +3009,7 @@ SlicingParameters PrintObject::slicing_parameters(const DynamicPrintConfig& full
|
||||||
|
|
||||||
if (object_max_z <= 0.f)
|
if (object_max_z <= 0.f)
|
||||||
object_max_z = (float)model_object.raw_bounding_box().size().z();
|
object_max_z = (float)model_object.raw_bounding_box().size().z();
|
||||||
return SlicingParameters::create_from_config(print_config, object_config, object_max_z, object_extruders);
|
return SlicingParameters::create_from_config(print_config, object_config, object_max_z, object_extruders, object_shrinkage_compensation);
|
||||||
}
|
}
|
||||||
|
|
||||||
// returns 0-based indices of extruders used to print the object (without brim, support and other helper extrusions)
|
// returns 0-based indices of extruders used to print the object (without brim, support and other helper extrusions)
|
||||||
|
@ -3049,7 +3052,7 @@ bool PrintObject::update_layer_height_profile(const ModelObject &model_object, c
|
||||||
// Must not be of even length.
|
// Must not be of even length.
|
||||||
((layer_height_profile.size() & 1) != 0 ||
|
((layer_height_profile.size() & 1) != 0 ||
|
||||||
// Last entry must be at the top of the object.
|
// Last entry must be at the top of the object.
|
||||||
std::abs(layer_height_profile[layer_height_profile.size() - 2] - slicing_parameters.object_print_z_max + slicing_parameters.object_print_z_min) > 1e-3))
|
std::abs(layer_height_profile[layer_height_profile.size() - 2] - slicing_parameters.object_print_z_uncompensated_max + slicing_parameters.object_print_z_min) > 1e-3))
|
||||||
layer_height_profile.clear();
|
layer_height_profile.clear();
|
||||||
|
|
||||||
if (layer_height_profile.empty() || layer_height_profile[1] != slicing_parameters.first_object_layer_height) {
|
if (layer_height_profile.empty() || layer_height_profile[1] != slicing_parameters.first_object_layer_height) {
|
||||||
|
|
|
@ -449,22 +449,6 @@ static std::vector<std::vector<ExPolygons>> slices_to_regions(
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// SoftFever: ported from SuperSlicer
|
|
||||||
// filament shrink
|
|
||||||
for (const std::unique_ptr<PrintRegion>& pr : print_object_regions.all_regions) {
|
|
||||||
if (pr.get()) {
|
|
||||||
std::vector<ExPolygons>& region_polys = slices_by_region[pr->print_object_region_id()];
|
|
||||||
const size_t extruder_id = pr->extruder(FlowRole::frPerimeter) - 1;
|
|
||||||
double scale = print_config.filament_shrink.values[extruder_id] * 0.01;
|
|
||||||
if (scale != 1) {
|
|
||||||
scale = 1 / scale;
|
|
||||||
for (ExPolygons& polys : region_polys)
|
|
||||||
for (ExPolygon& poly : polys)
|
|
||||||
poly.scale(scale);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return slices_by_region;
|
return slices_by_region;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -60,10 +60,11 @@ coordf_t Slicing::max_layer_height_from_nozzle(const DynamicPrintConfig &print_c
|
||||||
}
|
}
|
||||||
|
|
||||||
SlicingParameters SlicingParameters::create_from_config(
|
SlicingParameters SlicingParameters::create_from_config(
|
||||||
const PrintConfig &print_config,
|
const PrintConfig &print_config,
|
||||||
const PrintObjectConfig &object_config,
|
const PrintObjectConfig &object_config,
|
||||||
coordf_t object_height,
|
coordf_t object_height,
|
||||||
const std::vector<unsigned int> &object_extruders)
|
const std::vector<unsigned int> &object_extruders,
|
||||||
|
const Vec3d &object_shrinkage_compensation)
|
||||||
{
|
{
|
||||||
coordf_t initial_layer_print_height = (print_config.initial_layer_print_height.value <= 0) ?
|
coordf_t initial_layer_print_height = (print_config.initial_layer_print_height.value <= 0) ?
|
||||||
object_config.layer_height.value : print_config.initial_layer_print_height.value;
|
object_config.layer_height.value : print_config.initial_layer_print_height.value;
|
||||||
|
@ -81,7 +82,10 @@ SlicingParameters SlicingParameters::create_from_config(
|
||||||
params.first_print_layer_height = initial_layer_print_height;
|
params.first_print_layer_height = initial_layer_print_height;
|
||||||
params.first_object_layer_height = initial_layer_print_height;
|
params.first_object_layer_height = initial_layer_print_height;
|
||||||
params.object_print_z_min = 0.;
|
params.object_print_z_min = 0.;
|
||||||
params.object_print_z_max = object_height;
|
// Orca: XYZ filament compensation
|
||||||
|
params.object_print_z_max = object_height * object_shrinkage_compensation.z();
|
||||||
|
params.object_print_z_uncompensated_max = object_height;
|
||||||
|
params.object_shrinkage_compensation_z = object_shrinkage_compensation.z();
|
||||||
params.base_raft_layers = object_config.raft_layers.value;
|
params.base_raft_layers = object_config.raft_layers.value;
|
||||||
params.soluble_interface = soluble_interface;
|
params.soluble_interface = soluble_interface;
|
||||||
|
|
||||||
|
@ -153,6 +157,7 @@ SlicingParameters SlicingParameters::create_from_config(
|
||||||
coordf_t print_z = params.raft_contact_top_z + params.gap_raft_object;
|
coordf_t print_z = params.raft_contact_top_z + params.gap_raft_object;
|
||||||
params.object_print_z_min = print_z;
|
params.object_print_z_min = print_z;
|
||||||
params.object_print_z_max += print_z;
|
params.object_print_z_max += print_z;
|
||||||
|
params.object_print_z_uncompensated_max += print_z;
|
||||||
}
|
}
|
||||||
|
|
||||||
params.valid = true;
|
params.valid = true;
|
||||||
|
@ -225,10 +230,10 @@ std::vector<coordf_t> layer_height_profile_from_ranges(
|
||||||
lh_append(hi, height);
|
lh_append(hi, height);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (coordf_t z = last_z(); z < slicing_params.object_print_z_height()) {
|
if (coordf_t z = last_z(); z < slicing_params.object_print_z_uncompensated_height()) {
|
||||||
// Insert a step of normal layer height up to the object top.
|
// Insert a step of normal layer height up to the object top.
|
||||||
lh_append(z, slicing_params.layer_height);
|
lh_append(z, slicing_params.layer_height);
|
||||||
lh_append(slicing_params.object_print_z_height(), slicing_params.layer_height);
|
lh_append(slicing_params.object_print_z_uncompensated_height(), slicing_params.layer_height);
|
||||||
}
|
}
|
||||||
|
|
||||||
return layer_height_profile;
|
return layer_height_profile;
|
||||||
|
@ -450,12 +455,12 @@ void adjust_layer_height_profile(
|
||||||
std::pair<coordf_t, coordf_t> z_span_variable =
|
std::pair<coordf_t, coordf_t> z_span_variable =
|
||||||
std::pair<coordf_t, coordf_t>(
|
std::pair<coordf_t, coordf_t>(
|
||||||
slicing_params.first_object_layer_height_fixed() ? slicing_params.first_object_layer_height : 0.,
|
slicing_params.first_object_layer_height_fixed() ? slicing_params.first_object_layer_height : 0.,
|
||||||
slicing_params.object_print_z_height());
|
slicing_params.object_print_z_uncompensated_height());
|
||||||
if (z < z_span_variable.first || z > z_span_variable.second)
|
if (z < z_span_variable.first || z > z_span_variable.second)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
assert(layer_height_profile.size() >= 2);
|
assert(layer_height_profile.size() >= 2);
|
||||||
assert(std::abs(layer_height_profile[layer_height_profile.size() - 2] - slicing_params.object_print_z_height()) < EPSILON);
|
assert(std::abs(layer_height_profile[layer_height_profile.size() - 2] - slicing_params.object_print_z_uncompensated_height()) < EPSILON);
|
||||||
|
|
||||||
// 1) Get the current layer thickness at z.
|
// 1) Get the current layer thickness at z.
|
||||||
coordf_t current_layer_height = slicing_params.layer_height;
|
coordf_t current_layer_height = slicing_params.layer_height;
|
||||||
|
@ -616,7 +621,7 @@ void adjust_layer_height_profile(
|
||||||
assert(layer_height_profile.size() > 2);
|
assert(layer_height_profile.size() > 2);
|
||||||
assert(layer_height_profile.size() % 2 == 0);
|
assert(layer_height_profile.size() % 2 == 0);
|
||||||
assert(layer_height_profile[0] == 0.);
|
assert(layer_height_profile[0] == 0.);
|
||||||
assert(std::abs(layer_height_profile[layer_height_profile.size() - 2] - slicing_params.object_print_z_height()) < EPSILON);
|
assert(std::abs(layer_height_profile[layer_height_profile.size() - 2] - slicing_params.object_print_z_uncompensated_height()) < EPSILON);
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
for (size_t i = 2; i < layer_height_profile.size(); i += 2)
|
for (size_t i = 2; i < layer_height_profile.size(); i += 2)
|
||||||
assert(layer_height_profile[i - 2] <= layer_height_profile[i]);
|
assert(layer_height_profile[i - 2] <= layer_height_profile[i]);
|
||||||
|
@ -739,6 +744,8 @@ std::vector<coordf_t> generate_object_layers(
|
||||||
out.push_back(print_z);
|
out.push_back(print_z);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Orca: XYZ shrinkage compensation
|
||||||
|
const coordf_t shrinkage_compensation_z = slicing_params.object_shrinkage_compensation_z;
|
||||||
size_t idx_layer_height_profile = 0;
|
size_t idx_layer_height_profile = 0;
|
||||||
// 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
|
||||||
coordf_t slice_z = print_z + 0.5 * slicing_params.min_layer_height;
|
coordf_t slice_z = print_z + 0.5 * slicing_params.min_layer_height;
|
||||||
|
@ -747,17 +754,20 @@ std::vector<coordf_t> generate_object_layers(
|
||||||
if (idx_layer_height_profile < layer_height_profile.size()) {
|
if (idx_layer_height_profile < layer_height_profile.size()) {
|
||||||
size_t next = idx_layer_height_profile + 2;
|
size_t next = idx_layer_height_profile + 2;
|
||||||
for (;;) {
|
for (;;) {
|
||||||
if (next >= layer_height_profile.size() || slice_z < layer_height_profile[next])
|
// Orca: XYZ shrinkage compensation
|
||||||
|
if (next >= layer_height_profile.size() || slice_z < layer_height_profile[next] * shrinkage_compensation_z)
|
||||||
break;
|
break;
|
||||||
idx_layer_height_profile = next;
|
idx_layer_height_profile = next;
|
||||||
next += 2;
|
next += 2;
|
||||||
}
|
}
|
||||||
coordf_t z1 = layer_height_profile[idx_layer_height_profile];
|
// Orca: XYZ shrinkage compensation
|
||||||
coordf_t h1 = layer_height_profile[idx_layer_height_profile + 1];
|
const coordf_t z1 = layer_height_profile[idx_layer_height_profile] * shrinkage_compensation_z;
|
||||||
|
const coordf_t h1 = layer_height_profile[idx_layer_height_profile + 1];
|
||||||
height = h1;
|
height = h1;
|
||||||
if (next < layer_height_profile.size()) {
|
if (next < layer_height_profile.size()) {
|
||||||
coordf_t z2 = layer_height_profile[next];
|
// Orca: XYZ shrinkage compensation
|
||||||
coordf_t h2 = layer_height_profile[next + 1];
|
const coordf_t z2 = layer_height_profile[next] * shrinkage_compensation_z;
|
||||||
|
const coordf_t h2 = layer_height_profile[next + 1];
|
||||||
height = lerp(h1, h2, (slice_z - z1) / (z2 - z1));
|
height = lerp(h1, h2, (slice_z - z1) / (z2 - z1));
|
||||||
assert(height >= slicing_params.min_layer_height - EPSILON && height <= slicing_params.max_layer_height + EPSILON);
|
assert(height >= slicing_params.min_layer_height - EPSILON && height <= slicing_params.max_layer_height + EPSILON);
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,11 +28,13 @@ struct SlicingParameters
|
||||||
{
|
{
|
||||||
SlicingParameters() = default;
|
SlicingParameters() = default;
|
||||||
|
|
||||||
|
// Orca: XYZ filament compensation introduced object_shrinkage_compensation
|
||||||
static SlicingParameters create_from_config(
|
static SlicingParameters create_from_config(
|
||||||
const PrintConfig &print_config,
|
const PrintConfig &print_config,
|
||||||
const PrintObjectConfig &object_config,
|
const PrintObjectConfig &object_config,
|
||||||
coordf_t object_height,
|
coordf_t object_height,
|
||||||
const std::vector<unsigned int> &object_extruders);
|
const std::vector<unsigned int> &object_extruders,
|
||||||
|
const Vec3d &object_shrinkage_compensation);
|
||||||
|
|
||||||
// Has any raft layers?
|
// Has any raft layers?
|
||||||
bool has_raft() const { return raft_layers() > 0; }
|
bool has_raft() const { return raft_layers() > 0; }
|
||||||
|
@ -44,6 +46,10 @@ struct SlicingParameters
|
||||||
// Height of the object to be printed. This value does not contain the raft height.
|
// Height of the object to be printed. This value does not contain the raft height.
|
||||||
coordf_t object_print_z_height() const { return object_print_z_max - object_print_z_min; }
|
coordf_t object_print_z_height() const { return object_print_z_max - object_print_z_min; }
|
||||||
|
|
||||||
|
// Height of the object to be printed. This value does not contain the raft height.
|
||||||
|
// This value isn't scaled by shrinkage compensation in the Z-axis.
|
||||||
|
coordf_t object_print_z_uncompensated_height() const { return object_print_z_uncompensated_max - object_print_z_min; }
|
||||||
|
|
||||||
bool valid { false };
|
bool valid { false };
|
||||||
|
|
||||||
// Number of raft layers.
|
// Number of raft layers.
|
||||||
|
@ -95,7 +101,14 @@ struct SlicingParameters
|
||||||
coordf_t raft_contact_top_z { 0 };
|
coordf_t raft_contact_top_z { 0 };
|
||||||
// In case of a soluble interface, object_print_z_min == raft_contact_top_z, otherwise there is a gap between the raft and the 1st object layer.
|
// In case of a soluble interface, object_print_z_min == raft_contact_top_z, otherwise there is a gap between the raft and the 1st object layer.
|
||||||
coordf_t object_print_z_min { 0 };
|
coordf_t object_print_z_min { 0 };
|
||||||
|
// This value of maximum print Z is scaled by shrinkage compensation in the Z-axis.
|
||||||
coordf_t object_print_z_max { 0 };
|
coordf_t object_print_z_max { 0 };
|
||||||
|
|
||||||
|
// Orca: XYZ shrinkage compensation
|
||||||
|
// This value of maximum print Z isn't scaled by shrinkage compensation.
|
||||||
|
coordf_t object_print_z_uncompensated_max { 0 };
|
||||||
|
// Scaling factor for compensating shrinkage in Z-axis.
|
||||||
|
coordf_t object_shrinkage_compensation_z { 0 };
|
||||||
};
|
};
|
||||||
static_assert(IsTriviallyCopyable<SlicingParameters>::value, "SlicingParameters class is not POD (and it should be - see constructor).");
|
static_assert(IsTriviallyCopyable<SlicingParameters>::value, "SlicingParameters class is not POD (and it should be - see constructor).");
|
||||||
|
|
||||||
|
|
|
@ -666,8 +666,9 @@ void GLCanvas3D::LayersEditing::update_slicing_parameters()
|
||||||
{
|
{
|
||||||
if (m_slicing_parameters == nullptr) {
|
if (m_slicing_parameters == nullptr) {
|
||||||
m_slicing_parameters = new SlicingParameters();
|
m_slicing_parameters = new SlicingParameters();
|
||||||
*m_slicing_parameters = PrintObject::slicing_parameters(*m_config, *m_model_object, m_object_max_z);
|
*m_slicing_parameters = PrintObject::slicing_parameters(*m_config, *m_model_object, m_object_max_z, m_shrinkage_compensation);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
float GLCanvas3D::LayersEditing::thickness_bar_width(const GLCanvas3D & canvas)
|
float GLCanvas3D::LayersEditing::thickness_bar_width(const GLCanvas3D & canvas)
|
||||||
|
@ -1489,6 +1490,11 @@ void GLCanvas3D::set_config(const DynamicPrintConfig* config)
|
||||||
{
|
{
|
||||||
m_config = config;
|
m_config = config;
|
||||||
m_layers_editing.set_config(config);
|
m_layers_editing.set_config(config);
|
||||||
|
|
||||||
|
// Orca: Filament shrinkage compensation
|
||||||
|
const Print *print = fff_print();
|
||||||
|
if (print != nullptr)
|
||||||
|
m_layers_editing.set_shrinkage_compensation(fff_print()->shrinkage_compensation());
|
||||||
}
|
}
|
||||||
|
|
||||||
void GLCanvas3D::set_process(BackgroundSlicingProcess *process)
|
void GLCanvas3D::set_process(BackgroundSlicingProcess *process)
|
||||||
|
|
|
@ -217,6 +217,9 @@ class GLCanvas3D
|
||||||
|
|
||||||
static const float THICKNESS_BAR_WIDTH;
|
static const float THICKNESS_BAR_WIDTH;
|
||||||
|
|
||||||
|
// Orca: Shrinkage compensation
|
||||||
|
void set_shrinkage_compensation(const Vec3d &shrinkage_compensation) { m_shrinkage_compensation = shrinkage_compensation; };
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool m_enabled{ false };
|
bool m_enabled{ false };
|
||||||
unsigned int m_z_texture_id{ 0 };
|
unsigned int m_z_texture_id{ 0 };
|
||||||
|
@ -230,6 +233,9 @@ class GLCanvas3D
|
||||||
SlicingParameters* m_slicing_parameters{ nullptr };
|
SlicingParameters* m_slicing_parameters{ nullptr };
|
||||||
std::vector<double> m_layer_height_profile;
|
std::vector<double> m_layer_height_profile;
|
||||||
|
|
||||||
|
// Orca: Shrinkage compensation to apply when we need to use object_max_z with Z compensation.
|
||||||
|
Vec3d m_shrinkage_compensation{ Vec3d::Ones() };
|
||||||
|
|
||||||
mutable float m_adaptive_quality{ 0.5f };
|
mutable float m_adaptive_quality{ 0.5f };
|
||||||
mutable HeightProfileSmoothingParams m_smooth_params;
|
mutable HeightProfileSmoothingParams m_smooth_params;
|
||||||
|
|
||||||
|
|
|
@ -3245,6 +3245,7 @@ void TabFilament::build()
|
||||||
|
|
||||||
optgroup->append_single_option_line("filament_density");
|
optgroup->append_single_option_line("filament_density");
|
||||||
optgroup->append_single_option_line("filament_shrink");
|
optgroup->append_single_option_line("filament_shrink");
|
||||||
|
optgroup->append_single_option_line("filament_shrinkage_compensation_z");
|
||||||
optgroup->append_single_option_line("filament_cost");
|
optgroup->append_single_option_line("filament_cost");
|
||||||
//BBS
|
//BBS
|
||||||
optgroup->append_single_option_line("temperature_vitrification");
|
optgroup->append_single_option_line("temperature_vitrification");
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue