mirror of
https://github.com/SoftFever/OrcaSlicer.git
synced 2025-10-23 16:51:21 -06:00
WIP Restoration of the layer editing.
This commit is contained in:
parent
3e28905621
commit
d64b55d27d
17 changed files with 398 additions and 569 deletions
|
|
@ -582,10 +582,7 @@ namespace Slic3r {
|
|||
|
||||
IdToLayerHeightsProfileMap::iterator obj_layer_heights_profile = m_layer_heights_profiles.find(object.first);
|
||||
if (obj_layer_heights_profile != m_layer_heights_profiles.end())
|
||||
{
|
||||
object.second->layer_height_profile = obj_layer_heights_profile->second;
|
||||
object.second->layer_height_profile_valid = true;
|
||||
}
|
||||
|
||||
IdToSlaSupportPointsMap::iterator obj_sla_support_points = m_sla_support_points.find(object.first);
|
||||
if (obj_sla_support_points != m_sla_support_points.end() && !obj_sla_support_points->second.empty())
|
||||
|
|
@ -1926,7 +1923,7 @@ namespace Slic3r {
|
|||
for (const ModelObject* object : model.objects)
|
||||
{
|
||||
++count;
|
||||
std::vector<double> layer_height_profile = object->layer_height_profile_valid ? object->layer_height_profile : std::vector<double>();
|
||||
const std::vector<double> &layer_height_profile = object->layer_height_profile;
|
||||
if ((layer_height_profile.size() >= 4) && ((layer_height_profile.size() % 2) == 0))
|
||||
{
|
||||
sprintf(buffer, "object_id=%d|", count);
|
||||
|
|
|
|||
|
|
@ -578,7 +578,6 @@ void AMFParserContext::endElement(const char * /* name */)
|
|||
break;
|
||||
p = end + 1;
|
||||
}
|
||||
m_object->layer_height_profile_valid = true;
|
||||
}
|
||||
else if (m_path.size() == 3 && m_path[1] == NODE_TYPE_OBJECT && m_object && strcmp(opt_key, "sla_support_points") == 0) {
|
||||
// Parse object's layer height profile, a semicolon separated list of floats.
|
||||
|
|
@ -885,7 +884,7 @@ bool store_amf(const char *path, Model *model, const DynamicPrintConfig *config)
|
|||
stream << " <metadata type=\"slic3r." << key << "\">" << object->config.serialize(key) << "</metadata>\n";
|
||||
if (!object->name.empty())
|
||||
stream << " <metadata type=\"name\">" << xml_escape(object->name) << "</metadata>\n";
|
||||
std::vector<double> layer_height_profile = object->layer_height_profile_valid ? object->layer_height_profile : std::vector<double>();
|
||||
const std::vector<double> &layer_height_profile = object->layer_height_profile;
|
||||
if (layer_height_profile.size() >= 4 && (layer_height_profile.size() % 2) == 0) {
|
||||
// Store the layer height profile as a single semicolon separated list.
|
||||
stream << " <metadata type=\"slic3r.layer_height_profile\">";
|
||||
|
|
|
|||
|
|
@ -570,7 +570,6 @@ ModelObject& ModelObject::assign_copy(const ModelObject &rhs)
|
|||
this->sla_support_points = rhs.sla_support_points;
|
||||
this->layer_height_ranges = rhs.layer_height_ranges;
|
||||
this->layer_height_profile = rhs.layer_height_profile;
|
||||
this->layer_height_profile_valid = rhs.layer_height_profile_valid;
|
||||
this->origin_translation = rhs.origin_translation;
|
||||
m_bounding_box = rhs.m_bounding_box;
|
||||
m_bounding_box_valid = rhs.m_bounding_box_valid;
|
||||
|
|
@ -602,7 +601,6 @@ ModelObject& ModelObject::assign_copy(ModelObject &&rhs)
|
|||
this->sla_support_points = std::move(rhs.sla_support_points);
|
||||
this->layer_height_ranges = std::move(rhs.layer_height_ranges);
|
||||
this->layer_height_profile = std::move(rhs.layer_height_profile);
|
||||
this->layer_height_profile_valid = std::move(rhs.layer_height_profile_valid);
|
||||
this->origin_translation = std::move(rhs.origin_translation);
|
||||
m_bounding_box = std::move(rhs.m_bounding_box);
|
||||
m_bounding_box_valid = std::move(rhs.m_bounding_box_valid);
|
||||
|
|
|
|||
|
|
@ -170,12 +170,8 @@ public:
|
|||
// Variation of a layer thickness for spans of Z coordinates.
|
||||
t_layer_height_ranges layer_height_ranges;
|
||||
// Profile of increasing z to a layer height, to be linearly interpolated when calculating the layers.
|
||||
// The pairs of <z, layer_height> are packed into a 1D array to simplify handling by the Perl XS.
|
||||
// The pairs of <z, layer_height> are packed into a 1D array.
|
||||
std::vector<coordf_t> layer_height_profile;
|
||||
// layer_height_profile is initialized when the layer editing mode is entered.
|
||||
// Only if the user really modified the layer height, layer_height_profile_valid is set
|
||||
// and used subsequently by the PrintObject.
|
||||
bool layer_height_profile_valid;
|
||||
|
||||
// This vector holds position of selected support points for SLA. The data are
|
||||
// saved in mesh coordinates to allow using them for several instances.
|
||||
|
|
@ -261,7 +257,7 @@ protected:
|
|||
void set_model(Model *model) { m_model = model; }
|
||||
|
||||
private:
|
||||
ModelObject(Model *model) : layer_height_profile_valid(false), m_model(model), origin_translation(Vec3d::Zero()), m_bounding_box_valid(false) {}
|
||||
ModelObject(Model *model) : m_model(model), origin_translation(Vec3d::Zero()), m_bounding_box_valid(false) {}
|
||||
~ModelObject();
|
||||
|
||||
/* To be able to return an object from own copy / clone methods. Hopefully the compiler will do the "Copy elision" */
|
||||
|
|
|
|||
|
|
@ -287,18 +287,8 @@ std::vector<unsigned int> Print::object_extruders() const
|
|||
{
|
||||
std::vector<unsigned int> extruders;
|
||||
extruders.reserve(m_regions.size() * 3);
|
||||
|
||||
for (const PrintRegion *region : m_regions) {
|
||||
// these checks reflect the same logic used in the GUI for enabling/disabling
|
||||
// extruder selection fields
|
||||
if (region->config().perimeters.value > 0 || m_config.brim_width.value > 0)
|
||||
extruders.emplace_back(region->config().perimeter_extruder - 1);
|
||||
if (region->config().fill_density.value > 0)
|
||||
extruders.emplace_back(region->config().infill_extruder - 1);
|
||||
if (region->config().top_solid_layers.value > 0 || region->config().bottom_solid_layers.value > 0)
|
||||
extruders.emplace_back(region->config().solid_infill_extruder - 1);
|
||||
}
|
||||
|
||||
for (const PrintRegion *region : m_regions)
|
||||
region->collect_object_printing_extruders(extruders);
|
||||
sort_remove_duplicates(extruders);
|
||||
return extruders;
|
||||
}
|
||||
|
|
@ -366,37 +356,6 @@ double Print::max_allowed_layer_height() const
|
|||
return nozzle_diameter_max;
|
||||
}
|
||||
|
||||
static void clamp_exturder_to_default(ConfigOptionInt &opt, size_t num_extruders)
|
||||
{
|
||||
if (opt.value > (int)num_extruders)
|
||||
// assign the default extruder
|
||||
opt.value = 1;
|
||||
}
|
||||
|
||||
static PrintObjectConfig object_config_from_model(const PrintObjectConfig &default_object_config, const ModelObject &object, size_t num_extruders)
|
||||
{
|
||||
PrintObjectConfig config = default_object_config;
|
||||
normalize_and_apply_config(config, object.config);
|
||||
// Clamp invalid extruders to the default extruder (with index 1).
|
||||
clamp_exturder_to_default(config.support_material_extruder, num_extruders);
|
||||
clamp_exturder_to_default(config.support_material_interface_extruder, num_extruders);
|
||||
return config;
|
||||
}
|
||||
|
||||
static PrintRegionConfig region_config_from_model_volume(const PrintRegionConfig &default_region_config, const ModelVolume &volume, size_t num_extruders)
|
||||
{
|
||||
PrintRegionConfig config = default_region_config;
|
||||
normalize_and_apply_config(config, volume.get_object()->config);
|
||||
normalize_and_apply_config(config, volume.config);
|
||||
if (! volume.material_id().empty())
|
||||
normalize_and_apply_config(config, volume.material()->config);
|
||||
// Clamp invalid extruders to the default extruder (with index 1).
|
||||
clamp_exturder_to_default(config.infill_extruder, num_extruders);
|
||||
clamp_exturder_to_default(config.perimeter_extruder, num_extruders);
|
||||
clamp_exturder_to_default(config.solid_infill_extruder, num_extruders);
|
||||
return config;
|
||||
}
|
||||
|
||||
// Caller is responsible for supplying models whose objects don't collide
|
||||
// and have explicit instance positions.
|
||||
void Print::add_model_object(ModelObject* model_object, int idx)
|
||||
|
|
@ -433,7 +392,7 @@ void Print::add_model_object(ModelObject* model_object, int idx)
|
|||
if (! volume->is_model_part() && ! volume->is_modifier())
|
||||
continue;
|
||||
// Get the config applied to this volume.
|
||||
PrintRegionConfig config = region_config_from_model_volume(m_default_region_config, *volume, 99999);
|
||||
PrintRegionConfig config = PrintObject::region_config_from_model_volume(m_default_region_config, *volume, 99999);
|
||||
// Find an existing print region with the same config.
|
||||
size_t region_id = size_t(-1);
|
||||
for (size_t i = 0; i < m_regions.size(); ++ i)
|
||||
|
|
@ -514,12 +473,12 @@ bool Print::apply_config(DynamicPrintConfig config)
|
|||
// If the new config for this volume differs from the other
|
||||
// volume configs currently associated to this region, it means
|
||||
// the region subdivision does not make sense anymore.
|
||||
if (! this_region_config.equals(region_config_from_model_volume(m_default_region_config, volume, 99999))) {
|
||||
if (! this_region_config.equals(PrintObject::region_config_from_model_volume(m_default_region_config, volume, 99999))) {
|
||||
rearrange_regions = true;
|
||||
goto exit_for_rearrange_regions;
|
||||
}
|
||||
} else {
|
||||
this_region_config = region_config_from_model_volume(m_default_region_config, volume, 99999);
|
||||
this_region_config = PrintObject::region_config_from_model_volume(m_default_region_config, volume, 99999);
|
||||
this_region_config_set = true;
|
||||
}
|
||||
for (const PrintRegionConfig &cfg : other_region_configs) {
|
||||
|
|
@ -563,10 +522,6 @@ exit_for_rearrange_regions:
|
|||
invalidated = true;
|
||||
}
|
||||
|
||||
// Always make sure that the layer_height_profiles are set, as they should not be modified from the worker threads.
|
||||
for (PrintObject *object : m_objects)
|
||||
object->update_layer_height_profile();
|
||||
|
||||
return invalidated;
|
||||
}
|
||||
|
||||
|
|
@ -888,8 +843,7 @@ Print::ApplyStatus Print::apply(const Model &model, const DynamicPrintConfig &co
|
|||
if (model_parts_differ || modifiers_differ ||
|
||||
model_object.origin_translation != model_object_new.origin_translation ||
|
||||
model_object.layer_height_ranges != model_object_new.layer_height_ranges ||
|
||||
model_object.layer_height_profile != model_object_new.layer_height_profile ||
|
||||
model_object.layer_height_profile_valid != model_object_new.layer_height_profile_valid) {
|
||||
model_object.layer_height_profile != model_object_new.layer_height_profile) {
|
||||
// The very first step (the slicing step) is invalidated. One may freely remove all associated PrintObjects.
|
||||
auto range = print_object_status.equal_range(PrintObjectStatus(model_object.id()));
|
||||
for (auto it = range.first; it != range.second; ++ it) {
|
||||
|
|
@ -915,7 +869,7 @@ Print::ApplyStatus Print::apply(const Model &model, const DynamicPrintConfig &co
|
|||
if (object_config_changed)
|
||||
model_object.config = model_object_new.config;
|
||||
if (! object_diff.empty() || object_config_changed) {
|
||||
PrintObjectConfig new_config = object_config_from_model(m_default_object_config, model_object, num_extruders);
|
||||
PrintObjectConfig new_config = PrintObject::object_config_from_model_object(m_default_object_config, model_object, num_extruders);
|
||||
auto range = print_object_status.equal_range(PrintObjectStatus(model_object.id()));
|
||||
for (auto it = range.first; it != range.second; ++ it) {
|
||||
t_config_option_keys diff = it->print_object->config().diff(new_config);
|
||||
|
|
@ -957,7 +911,7 @@ Print::ApplyStatus Print::apply(const Model &model, const DynamicPrintConfig &co
|
|||
old.emplace_back(&(*it));
|
||||
}
|
||||
// Generate a list of trafos and XY offsets for instances of a ModelObject
|
||||
PrintObjectConfig config = object_config_from_model(m_default_object_config, *model_object, num_extruders);
|
||||
PrintObjectConfig config = PrintObject::object_config_from_model_object(m_default_object_config, *model_object, num_extruders);
|
||||
std::vector<PrintInstances> new_print_instances = print_objects_from_model_object(*model_object);
|
||||
if (old.empty()) {
|
||||
// Simple case, just generate new instances.
|
||||
|
|
@ -1048,11 +1002,11 @@ Print::ApplyStatus Print::apply(const Model &model, const DynamicPrintConfig &co
|
|||
// If the new config for this volume differs from the other
|
||||
// volume configs currently associated to this region, it means
|
||||
// the region subdivision does not make sense anymore.
|
||||
if (! this_region_config.equals(region_config_from_model_volume(m_default_region_config, volume, num_extruders)))
|
||||
if (! this_region_config.equals(PrintObject::region_config_from_model_volume(m_default_region_config, volume, num_extruders)))
|
||||
// Regions were split. Reset this print_object.
|
||||
goto print_object_end;
|
||||
} else {
|
||||
this_region_config = region_config_from_model_volume(m_default_region_config, volume, num_extruders);
|
||||
this_region_config = PrintObject::region_config_from_model_volume(m_default_region_config, volume, num_extruders);
|
||||
for (size_t i = 0; i < region_id; ++i) {
|
||||
const PrintRegion ®ion_other = *m_regions[i];
|
||||
if (region_other.m_refcnt != 0 && region_other.config().equals(this_region_config))
|
||||
|
|
@ -1103,7 +1057,7 @@ Print::ApplyStatus Print::apply(const Model &model, const DynamicPrintConfig &co
|
|||
int region_id = -1;
|
||||
if (&print_object == &print_object0) {
|
||||
// Get the config applied to this volume.
|
||||
PrintRegionConfig config = region_config_from_model_volume(m_default_region_config, *volume, num_extruders);
|
||||
PrintRegionConfig config = PrintObject::region_config_from_model_volume(m_default_region_config, *volume, num_extruders);
|
||||
// Find an existing print region with the same config.
|
||||
int idx_empty_slot = -1;
|
||||
for (int i = 0; i < (int)m_regions.size(); ++ i) {
|
||||
|
|
@ -1139,13 +1093,6 @@ Print::ApplyStatus Print::apply(const Model &model, const DynamicPrintConfig &co
|
|||
}
|
||||
}
|
||||
|
||||
// Always make sure that the layer_height_profiles are set, as they should not be modified from the worker threads.
|
||||
for (PrintObject *object : m_objects)
|
||||
if (! object->layer_height_profile_valid)
|
||||
// No need to call the next line as the step should already be invalidated above.
|
||||
// update_apply_status(object->invalidate_step(posSlice));
|
||||
object->update_layer_height_profile();
|
||||
|
||||
//FIXME there may be a race condition with the G-code export running at the background thread.
|
||||
this->update_object_placeholders();
|
||||
|
||||
|
|
|
|||
|
|
@ -45,6 +45,10 @@ public:
|
|||
// Average diameter of nozzles participating on extruding this region.
|
||||
coordf_t bridging_height_avg(const PrintConfig &print_config) const;
|
||||
|
||||
// Collect extruder indices used to print this region's object.
|
||||
void collect_object_printing_extruders(std::vector<unsigned int> &object_extruders) const;
|
||||
static void collect_object_printing_extruders(const PrintConfig &print_config, const PrintRegionConfig ®ion_config, std::vector<unsigned int> &object_extruders);
|
||||
|
||||
// Methods modifying the PrintRegion's state:
|
||||
public:
|
||||
Print* print() { return m_print; }
|
||||
|
|
@ -80,14 +84,8 @@ public:
|
|||
std::vector<std::vector<int>> region_volumes;
|
||||
|
||||
// Profile of increasing z to a layer height, to be linearly interpolated when calculating the layers.
|
||||
// The pairs of <z, layer_height> are packed into a 1D array to simplify handling by the Perl XS.
|
||||
// layer_height_profile must not be set by the background thread.
|
||||
// The pairs of <z, layer_height> are packed into a 1D array.
|
||||
std::vector<coordf_t> layer_height_profile;
|
||||
// There is a layer_height_profile at both PrintObject and ModelObject. The layer_height_profile at the ModelObject
|
||||
// is used for interactive editing and for loading / storing into a project file (AMF file as of today).
|
||||
// This flag indicates that the layer_height_profile at the UI has been updated, therefore the backend needs to get it.
|
||||
// This flag is necessary as we cannot safely clear the layer_height_profile if the background calculation is running.
|
||||
bool layer_height_profile_valid;
|
||||
|
||||
// this is set to true when LayerRegion->slices is split in top/internal/bottom
|
||||
// so that next call to make_perimeters() performs a union() before computing loops
|
||||
|
|
@ -129,23 +127,19 @@ public:
|
|||
SupportLayerPtrs::const_iterator insert_support_layer(SupportLayerPtrs::const_iterator pos, int id, coordf_t height, coordf_t print_z, coordf_t slice_z);
|
||||
void delete_support_layer(int idx);
|
||||
|
||||
// To be used over the layer_height_profile of both the PrintObject and ModelObject
|
||||
// to initialize the height profile with the height ranges.
|
||||
bool update_layer_height_profile(std::vector<coordf_t> &layer_height_profile) const;
|
||||
|
||||
// Process layer_height_ranges, the raft layers and first layer thickness into layer_height_profile.
|
||||
// The layer_height_profile may be later modified interactively by the user to refine layers at sloping surfaces.
|
||||
bool update_layer_height_profile();
|
||||
|
||||
void reset_layer_height_profile();
|
||||
|
||||
void adjust_layer_height_profile(coordf_t z, coordf_t layer_thickness_delta, coordf_t band_width, int action);
|
||||
// Initialize the layer_height_profile from the model_object's layer_height_profile, from model_object's layer height table, or from slicing parameters.
|
||||
// Returns true, if the layer_height_profile was changed.
|
||||
static bool update_layer_height_profile(const ModelObject &model_object, const SlicingParameters &slicing_parameters, std::vector<coordf_t> &layer_height_profile);
|
||||
|
||||
// Collect the slicing parameters, to be used by variable layer thickness algorithm,
|
||||
// by the interactive layer height editor and by the printing process itself.
|
||||
// The slicing parameters are dependent on various configuration values
|
||||
// (layer height, first layer height, raft settings, print nozzle diameter etc).
|
||||
SlicingParameters slicing_parameters() const;
|
||||
SlicingParameters slicing_parameters() const;
|
||||
static SlicingParameters slicing_parameters(const DynamicPrintConfig &full_config, const ModelObject &model_object);
|
||||
|
||||
// returns 0-based indices of extruders used to print the object (without brim, support and other helper extrusions)
|
||||
std::vector<unsigned int> object_extruders() const;
|
||||
|
||||
// Called when slicing to SVG (see Print.pm sub export_svg), and used by perimeters.t
|
||||
void slice();
|
||||
|
|
@ -172,6 +166,9 @@ protected:
|
|||
// Invalidate steps based on a set of parameters changed.
|
||||
bool invalidate_state_by_config_options(const std::vector<t_config_option_key> &opt_keys);
|
||||
|
||||
static PrintObjectConfig object_config_from_model_object(const PrintObjectConfig &default_object_config, const ModelObject &object, size_t num_extruders);
|
||||
static PrintRegionConfig region_config_from_model_volume(const PrintRegionConfig &default_region_config, const ModelVolume &volume, size_t num_extruders);
|
||||
|
||||
private:
|
||||
void make_perimeters();
|
||||
void prepare_infill();
|
||||
|
|
|
|||
|
|
@ -38,8 +38,7 @@ namespace Slic3r {
|
|||
PrintObject::PrintObject(Print* print, ModelObject* model_object, bool add_instances) :
|
||||
PrintObjectBaseWithState(print, model_object),
|
||||
typed_slices(false),
|
||||
size(Vec3crd::Zero()),
|
||||
layer_height_profile_valid(false)
|
||||
size(Vec3crd::Zero())
|
||||
{
|
||||
// Compute the translation to be applied to our meshes so that we work with smaller coordinates
|
||||
{
|
||||
|
|
@ -106,6 +105,8 @@ void PrintObject::slice()
|
|||
if (! this->set_started(posSlice))
|
||||
return;
|
||||
m_print->set_status(10, "Processing triangulated mesh");
|
||||
this->update_layer_height_profile(*this->model_object(), this->slicing_parameters(), this->layer_height_profile);
|
||||
m_print->throw_if_canceled();
|
||||
this->_slice();
|
||||
m_print->throw_if_canceled();
|
||||
// Fix the model.
|
||||
|
|
@ -455,7 +456,6 @@ bool PrintObject::invalidate_state_by_config_options(const std::vector<t_config_
|
|||
|| opt_key == "first_layer_height"
|
||||
|| opt_key == "raft_layers") {
|
||||
steps.emplace_back(posSlice);
|
||||
this->reset_layer_height_profile();
|
||||
}
|
||||
else if (
|
||||
opt_key == "clip_multipart_objects"
|
||||
|
|
@ -542,7 +542,6 @@ bool PrintObject::invalidate_state_by_config_options(const std::vector<t_config_
|
|||
} else {
|
||||
// for legacy, if we can't handle this option let's invalidate all steps
|
||||
this->invalidate_all_steps();
|
||||
this->reset_layer_height_profile();
|
||||
invalidated = true;
|
||||
}
|
||||
}
|
||||
|
|
@ -1329,55 +1328,107 @@ void PrintObject::bridge_over_infill()
|
|||
}
|
||||
}
|
||||
|
||||
static void clamp_exturder_to_default(ConfigOptionInt &opt, size_t num_extruders)
|
||||
{
|
||||
if (opt.value > (int)num_extruders)
|
||||
// assign the default extruder
|
||||
opt.value = 1;
|
||||
}
|
||||
|
||||
PrintObjectConfig PrintObject::object_config_from_model_object(const PrintObjectConfig &default_object_config, const ModelObject &object, size_t num_extruders)
|
||||
{
|
||||
PrintObjectConfig config = default_object_config;
|
||||
normalize_and_apply_config(config, object.config);
|
||||
// Clamp invalid extruders to the default extruder (with index 1).
|
||||
clamp_exturder_to_default(config.support_material_extruder, num_extruders);
|
||||
clamp_exturder_to_default(config.support_material_interface_extruder, num_extruders);
|
||||
return config;
|
||||
}
|
||||
|
||||
PrintRegionConfig PrintObject::region_config_from_model_volume(const PrintRegionConfig &default_region_config, const ModelVolume &volume, size_t num_extruders)
|
||||
{
|
||||
PrintRegionConfig config = default_region_config;
|
||||
normalize_and_apply_config(config, volume.get_object()->config);
|
||||
normalize_and_apply_config(config, volume.config);
|
||||
if (! volume.material_id().empty())
|
||||
normalize_and_apply_config(config, volume.material()->config);
|
||||
// Clamp invalid extruders to the default extruder (with index 1).
|
||||
clamp_exturder_to_default(config.infill_extruder, num_extruders);
|
||||
clamp_exturder_to_default(config.perimeter_extruder, num_extruders);
|
||||
clamp_exturder_to_default(config.solid_infill_extruder, num_extruders);
|
||||
return config;
|
||||
}
|
||||
|
||||
SlicingParameters PrintObject::slicing_parameters() const
|
||||
{
|
||||
return SlicingParameters::create_from_config(
|
||||
this->print()->config(), m_config,
|
||||
unscale<double>(this->size(2)), this->print()->object_extruders());
|
||||
unscale<double>(this->size(2)), this->object_extruders());
|
||||
}
|
||||
|
||||
bool PrintObject::update_layer_height_profile(std::vector<coordf_t> &layer_height_profile) const
|
||||
SlicingParameters PrintObject::slicing_parameters(const DynamicPrintConfig &full_config, const ModelObject &model_object)
|
||||
{
|
||||
PrintConfig print_config;
|
||||
PrintObjectConfig object_config;
|
||||
PrintRegionConfig default_region_config;
|
||||
print_config .apply(full_config, true);
|
||||
object_config.apply(full_config, true);
|
||||
default_region_config.apply(full_config, true);
|
||||
size_t num_extruders = print_config.nozzle_diameter.size();
|
||||
object_config = object_config_from_model_object(object_config, model_object, num_extruders);
|
||||
|
||||
std::vector<unsigned int> object_extruders;
|
||||
for (const ModelVolume *model_volume : model_object.volumes)
|
||||
if (model_volume->is_model_part())
|
||||
PrintRegion::collect_object_printing_extruders(
|
||||
print_config,
|
||||
region_config_from_model_volume(default_region_config, *model_volume, num_extruders),
|
||||
object_extruders);
|
||||
sort_remove_duplicates(object_extruders);
|
||||
|
||||
return SlicingParameters::create_from_config(print_config, object_config, model_object.bounding_box().max.z(), object_extruders);
|
||||
}
|
||||
|
||||
// returns 0-based indices of extruders used to print the object (without brim, support and other helper extrusions)
|
||||
std::vector<unsigned int> PrintObject::object_extruders() const
|
||||
{
|
||||
std::vector<unsigned int> extruders;
|
||||
extruders.reserve(this->region_volumes.size() * 3);
|
||||
for (size_t idx_region = 0; idx_region < this->region_volumes.size(); ++ idx_region)
|
||||
if (! this->region_volumes[idx_region].empty())
|
||||
m_print->get_region(idx_region)->collect_object_printing_extruders(extruders);
|
||||
sort_remove_duplicates(extruders);
|
||||
return extruders;
|
||||
}
|
||||
|
||||
bool PrintObject::update_layer_height_profile(const ModelObject &model_object, const SlicingParameters &slicing_parameters, std::vector<coordf_t> &layer_height_profile)
|
||||
{
|
||||
bool updated = false;
|
||||
|
||||
// If the layer height profile is not set, try to use the one stored at the ModelObject.
|
||||
if (layer_height_profile.empty()) {
|
||||
layer_height_profile = this->model_object()->layer_height_profile;
|
||||
layer_height_profile = model_object.layer_height_profile;
|
||||
updated = true;
|
||||
}
|
||||
|
||||
// Verify the layer_height_profile.
|
||||
SlicingParameters slicing_params = this->slicing_parameters();
|
||||
if (! layer_height_profile.empty() &&
|
||||
// Must not be of even length.
|
||||
((layer_height_profile.size() & 1) != 0 ||
|
||||
// Last entry must be at the top of the object.
|
||||
std::abs(layer_height_profile[layer_height_profile.size() - 2] - slicing_params.object_print_z_height()) > 1e-3))
|
||||
std::abs(layer_height_profile[layer_height_profile.size() - 2] - slicing_parameters.object_print_z_height()) > 1e-3))
|
||||
layer_height_profile.clear();
|
||||
|
||||
if (layer_height_profile.empty()) {
|
||||
if (0)
|
||||
// if (this->layer_height_profile.empty())
|
||||
layer_height_profile = layer_height_profile_adaptive(slicing_params, this->model_object()->layer_height_ranges, this->model_object()->volumes);
|
||||
layer_height_profile = layer_height_profile_adaptive(slicing_parameters, model_object.layer_height_ranges, model_object.volumes);
|
||||
else
|
||||
layer_height_profile = layer_height_profile_from_ranges(slicing_params, this->model_object()->layer_height_ranges);
|
||||
layer_height_profile = layer_height_profile_from_ranges(slicing_parameters, model_object.layer_height_ranges);
|
||||
updated = true;
|
||||
}
|
||||
return updated;
|
||||
}
|
||||
|
||||
// This must be called from the main thread as it modifies the layer_height_profile.
|
||||
bool PrintObject::update_layer_height_profile()
|
||||
{
|
||||
// If the layer height profile has been marked as invalid for some reason (modified at the UI level
|
||||
// or invalidated due to the slicing parameters), clear it now.
|
||||
if (! this->layer_height_profile_valid) {
|
||||
this->layer_height_profile.clear();
|
||||
this->layer_height_profile_valid = true;
|
||||
}
|
||||
return this->update_layer_height_profile(this->layer_height_profile);
|
||||
}
|
||||
|
||||
// 1) Decides Z positions of the layers,
|
||||
// 2) Initializes layers and their regions
|
||||
// 3) Slices the object meshes
|
||||
|
|
@ -2198,22 +2249,4 @@ void PrintObject::_generate_support_material()
|
|||
support_material.generate(*this);
|
||||
}
|
||||
|
||||
void PrintObject::reset_layer_height_profile()
|
||||
{
|
||||
// Reset the layer_heigth_profile.
|
||||
this->layer_height_profile.clear();
|
||||
this->layer_height_profile_valid = false;
|
||||
// Reset the source layer_height_profile if it exists at the ModelObject.
|
||||
this->model_object()->layer_height_profile.clear();
|
||||
this->model_object()->layer_height_profile_valid = false;
|
||||
}
|
||||
|
||||
void PrintObject::adjust_layer_height_profile(coordf_t z, coordf_t layer_thickness_delta, coordf_t band_width, int action)
|
||||
{
|
||||
update_layer_height_profile(m_model_object->layer_height_profile);
|
||||
Slic3r::adjust_layer_height_profile(slicing_parameters(), m_model_object->layer_height_profile, z, layer_thickness_delta, band_width, LayerHeightEditActionType(action));
|
||||
m_model_object->layer_height_profile_valid = true;
|
||||
layer_height_profile_valid = false;
|
||||
}
|
||||
|
||||
} // namespace Slic3r
|
||||
|
|
|
|||
|
|
@ -61,4 +61,20 @@ coordf_t PrintRegion::bridging_height_avg(const PrintConfig &print_config) const
|
|||
return this->nozzle_dmr_avg(print_config) * sqrt(m_config.bridge_flow_ratio.value);
|
||||
}
|
||||
|
||||
void PrintRegion::collect_object_printing_extruders(const PrintConfig &print_config, const PrintRegionConfig ®ion_config, std::vector<unsigned int> &object_extruders)
|
||||
{
|
||||
// These checks reflect the same logic used in the GUI for enabling/disabling extruder selection fields.
|
||||
if (region_config.perimeters.value > 0 || print_config.brim_width.value > 0)
|
||||
object_extruders.emplace_back(region_config.perimeter_extruder - 1);
|
||||
if (region_config.fill_density.value > 0)
|
||||
object_extruders.emplace_back(region_config.infill_extruder - 1);
|
||||
if (region_config.top_solid_layers.value > 0 || region_config.bottom_solid_layers.value > 0)
|
||||
object_extruders.emplace_back(region_config.solid_infill_extruder - 1);
|
||||
}
|
||||
|
||||
void PrintRegion::collect_object_printing_extruders(std::vector<unsigned int> &object_extruders) const
|
||||
{
|
||||
collect_object_printing_extruders(print()->config(), this->config(), object_extruders);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -131,7 +131,7 @@ extern std::vector<coordf_t> layer_height_profile_adaptive(
|
|||
const ModelVolumePtrs &volumes);
|
||||
|
||||
|
||||
enum LayerHeightEditActionType {
|
||||
enum LayerHeightEditActionType : unsigned int {
|
||||
LAYER_HEIGHT_EDIT_ACTION_INCREASE = 0,
|
||||
LAYER_HEIGHT_EDIT_ACTION_DECREASE = 1,
|
||||
LAYER_HEIGHT_EDIT_ACTION_REDUCE = 2,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue