Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/prusa3d/PrusaSlicer.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'xs/src/libslic3r/Print.cpp')
-rw-r--r--xs/src/libslic3r/Print.cpp401
1 files changed, 203 insertions, 198 deletions
diff --git a/xs/src/libslic3r/Print.cpp b/xs/src/libslic3r/Print.cpp
index d67fe5884..e8a010a79 100644
--- a/xs/src/libslic3r/Print.cpp
+++ b/xs/src/libslic3r/Print.cpp
@@ -20,24 +20,27 @@ template class PrintState<PrintObjectStep, posCount>;
void Print::clear_objects()
{
- for (int i = int(this->objects.size())-1; i >= 0; --i)
+ tbb::mutex::scoped_lock lock(m_mutex);
+ for (int i = int(m_objects.size())-1; i >= 0; --i)
this->delete_object(i);
- for (PrintRegion *region : this->regions)
+ for (PrintRegion *region : m_regions)
delete region;
- this->regions.clear();
+ m_regions.clear();
}
void Print::delete_object(size_t idx)
{
+ tbb::mutex::scoped_lock lock(m_mutex);
// destroy object and remove it from our container
- delete this->objects[idx];
- this->objects.erase(this->objects.begin() + idx);
+ delete m_objects[idx];
+ m_objects.erase(m_objects.begin() + idx);
this->invalidate_all_steps();
// TODO: purge unused regions
}
void Print::reload_object(size_t /* idx */)
{
+ tbb::mutex::scoped_lock lock(m_mutex);
/* TODO: this method should check whether the per-object config and per-material configs
have changed in such a way that regions need to be rearranged or we can just apply
the diff and invalidate something. Same logic as apply_config()
@@ -46,8 +49,8 @@ void Print::reload_object(size_t /* idx */)
// collect all current model objects
ModelObjectPtrs model_objects;
- model_objects.reserve(this->objects.size());
- for (PrintObject *object : this->objects)
+ model_objects.reserve(m_objects.size());
+ for (PrintObject *object : m_objects)
model_objects.push_back(object->model_object());
// remove our print objects
this->clear_objects();
@@ -63,15 +66,21 @@ void Print::reload_object(size_t /* idx */)
bool Print::reload_model_instances()
{
bool invalidated = false;
- for (PrintObject *object : this->objects)
+ for (PrintObject *object : m_objects)
invalidated |= object->reload_model_instances();
return invalidated;
}
PrintRegion* Print::add_region()
{
- regions.push_back(new PrintRegion(this));
- return regions.back();
+ m_regions.emplace_back(new PrintRegion(this));
+ return m_regions.back();
+}
+
+PrintRegion* Print::add_region(const PrintRegionConfig &config)
+{
+ m_regions.emplace_back(new PrintRegion(this, config));
+ return m_regions.back();
}
// Called by Print::apply_config().
@@ -224,18 +233,18 @@ bool Print::invalidate_state_by_config_options(const std::vector<t_config_option
invalidated |= this->invalidate_step(step);
sort_remove_duplicates(osteps);
for (PrintObjectStep ostep : osteps)
- for (PrintObject *object : this->objects)
+ for (PrintObject *object : m_objects)
invalidated |= object->invalidate_step(ostep);
return invalidated;
}
bool Print::invalidate_step(PrintStep step)
{
- bool invalidated = m_state.invalidate(step);
+ bool invalidated = m_state.invalidate(step, m_mutex, m_cancel_callback);
// Propagate to dependent steps.
//FIXME Why should skirt invalidate brim? Shouldn't it be vice versa?
if (step == psSkirt)
- invalidated |= m_state.invalidate(psBrim);
+ invalidated |= m_state.invalidate(psBrim, m_mutex, m_cancel_callback);
return invalidated;
}
@@ -243,9 +252,9 @@ bool Print::invalidate_step(PrintStep step)
// and there's at least one object
bool Print::is_step_done(PrintObjectStep step) const
{
- if (this->objects.empty())
+ if (m_objects.empty())
return false;
- for (const PrintObject *object : this->objects)
+ for (const PrintObject *object : m_objects)
if (!object->m_state.is_done(step))
return false;
return true;
@@ -256,15 +265,15 @@ std::vector<unsigned int> Print::object_extruders() const
{
std::vector<unsigned int> extruders;
- for (PrintRegion* region : this->regions) {
+ for (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 || this->config.brim_width.value > 0)
- extruders.push_back(region->config.perimeter_extruder - 1);
- if (region->config.fill_density.value > 0)
- extruders.push_back(region->config.infill_extruder - 1);
- if (region->config.top_solid_layers.value > 0 || region->config.bottom_solid_layers.value > 0)
- extruders.push_back(region->config.solid_infill_extruder - 1);
+ if (region->config().perimeters.value > 0 || m_config.brim_width.value > 0)
+ extruders.push_back(region->config().perimeter_extruder - 1);
+ if (region->config().fill_density.value > 0)
+ extruders.push_back(region->config().infill_extruder - 1);
+ if (region->config().top_solid_layers.value > 0 || region->config().bottom_solid_layers.value > 0)
+ extruders.push_back(region->config().solid_infill_extruder - 1);
}
sort_remove_duplicates(extruders);
@@ -277,16 +286,16 @@ std::vector<unsigned int> Print::support_material_extruders() const
std::vector<unsigned int> extruders;
bool support_uses_current_extruder = false;
- for (PrintObject *object : this->objects) {
+ for (PrintObject *object : m_objects) {
if (object->has_support_material()) {
- if (object->config.support_material_extruder == 0)
+ if (object->config().support_material_extruder == 0)
support_uses_current_extruder = true;
else
- extruders.push_back(object->config.support_material_extruder - 1);
- if (object->config.support_material_interface_extruder == 0)
+ extruders.push_back(object->config().support_material_extruder - 1);
+ if (object->config().support_material_interface_extruder == 0)
support_uses_current_extruder = true;
else
- extruders.push_back(object->config.support_material_interface_extruder - 1);
+ extruders.push_back(object->config().support_material_interface_extruder - 1);
}
}
@@ -309,10 +318,10 @@ std::vector<unsigned int> Print::extruders() const
void Print::_simplify_slices(double distance)
{
- for (PrintObject *object : this->objects) {
- for (Layer *layer : object->layers) {
+ for (PrintObject *object : m_objects) {
+ for (Layer *layer : object->m_layers) {
layer->slices.simplify(distance);
- for (LayerRegion *layerm : layer->regions)
+ for (LayerRegion *layerm : layer->regions())
layerm->slices.simplify(distance);
}
}
@@ -322,7 +331,7 @@ double Print::max_allowed_layer_height() const
{
double nozzle_diameter_max = 0.;
for (unsigned int extruder_id : this->extruders())
- nozzle_diameter_max = std::max(nozzle_diameter_max, this->config.nozzle_diameter.get_at(extruder_id));
+ nozzle_diameter_max = std::max(nozzle_diameter_max, m_config.nozzle_diameter.get_at(extruder_id));
return nozzle_diameter_max;
}
@@ -333,10 +342,10 @@ void Print::add_model_object(ModelObject* model_object, int idx)
// Initialize a new print object and store it at the given position.
PrintObject *object = new PrintObject(this, model_object, model_object->raw_bounding_box());
if (idx != -1) {
- delete this->objects[idx];
- this->objects[idx] = object;
+ delete m_objects[idx];
+ m_objects[idx] = object;
} else
- this->objects.emplace_back(object);
+ m_objects.emplace_back(object);
// Invalidate all print steps.
this->invalidate_all_steps();
@@ -345,37 +354,42 @@ void Print::add_model_object(ModelObject* model_object, int idx)
PrintRegionConfig config = this->_region_config_from_model_volume(*model_object->volumes[volume_id]);
// Find an existing print region with the same config.
size_t region_id = size_t(-1);
- for (size_t i = 0; i < this->regions.size(); ++ i)
- if (config.equals(this->regions[i]->config)) {
+ for (size_t i = 0; i < m_regions.size(); ++ i)
+ if (config.equals(m_regions[i]->config())) {
region_id = i;
break;
}
// If no region exists with the same config, create a new one.
if (region_id == size_t(-1)) {
- region_id = this->regions.size();
- this->add_region()->config.apply(config);
+ region_id = this->regions().size();
+ this->add_region(config);
}
// Assign volume to a region.
object->add_region_volume(region_id, volume_id);
}
// Apply config to print object.
- object->config.apply(this->default_object_config);
- normalize_and_apply_config(object->config, model_object->config);
+ object->config_apply(this->default_object_config());
+ {
+ //normalize_and_apply_config(object->config(), model_object->config);
+ DynamicPrintConfig src_normalized(model_object->config);
+ src_normalized.normalize();
+ object->config_apply(src_normalized, true);
+ }
// update placeholders
{
// get the first input file name
std::string input_file;
std::vector<std::string> v_scale;
- for (const PrintObject *object : this->objects) {
+ for (const PrintObject *object : m_objects) {
const ModelObject &mobj = *object->model_object();
v_scale.push_back(boost::lexical_cast<std::string>(mobj.instances[0]->scaling_factor*100) + "%");
if (input_file.empty())
input_file = mobj.input_file;
}
- PlaceholderParser &pp = this->placeholder_parser;
+ PlaceholderParser &pp = m_placeholder_parser;
pp.set("scale", v_scale);
if (! input_file.empty()) {
// get basename with and without suffix
@@ -393,19 +407,19 @@ bool Print::apply_config(DynamicPrintConfig config)
config.normalize();
// apply variables to placeholder parser
- this->placeholder_parser.apply_config(config);
+ m_placeholder_parser.apply_config(config);
// handle changes to print config
- t_config_option_keys print_diff = this->config.diff(config);
- this->config.apply_only(config, print_diff, true);
+ t_config_option_keys print_diff = m_config.diff(config);
+ m_config.apply_only(config, print_diff, true);
bool invalidated = this->invalidate_state_by_config_options(print_diff);
// handle changes to object config defaults
- this->default_object_config.apply(config, true);
- for (PrintObject *object : this->objects) {
+ m_default_object_config.apply(config, true);
+ for (PrintObject *object : m_objects) {
// we don't assume that config contains a full ObjectConfig,
// so we base it on the current print-wise default
- PrintObjectConfig new_config = this->default_object_config;
+ PrintObjectConfig new_config = this->default_object_config();
// we override the new config with object-specific options
normalize_and_apply_config(new_config, object->model_object()->config);
// Force a refresh of a variable layer height profile at the PrintObject if it is not valid.
@@ -417,13 +431,13 @@ bool Print::apply_config(DynamicPrintConfig config)
invalidated = true;
}
// check whether the new config is different from the current one
- t_config_option_keys diff = object->config.diff(new_config);
- object->config.apply_only(new_config, diff, true);
+ t_config_option_keys diff = object->config().diff(new_config);
+ object->config_apply_only(new_config, diff, true);
invalidated |= object->invalidate_state_by_config_options(diff);
}
// handle changes to regions config defaults
- this->default_region_config.apply(config, true);
+ m_default_region_config.apply(config, true);
// All regions now have distinct settings.
// Check whether applying the new region config defaults we'd get different regions.
@@ -432,11 +446,11 @@ bool Print::apply_config(DynamicPrintConfig config)
// Collect the already visited region configs into other_region_configs,
// so one may check for duplicates.
std::vector<PrintRegionConfig> other_region_configs;
- for (size_t region_id = 0; region_id < this->regions.size(); ++ region_id) {
- PrintRegion &region = *this->regions[region_id];
+ for (size_t region_id = 0; region_id < m_regions.size(); ++ region_id) {
+ PrintRegion &region = *m_regions[region_id];
PrintRegionConfig this_region_config;
bool this_region_config_set = false;
- for (PrintObject *object : this->objects) {
+ for (PrintObject *object : m_objects) {
if (region_id < object->region_volumes.size()) {
for (int volume_id : object->region_volumes[region_id]) {
const ModelVolume &volume = *object->model_object()->volumes[volume_id];
@@ -466,10 +480,10 @@ bool Print::apply_config(DynamicPrintConfig config)
}
}
if (this_region_config_set) {
- t_config_option_keys diff = region.config.diff(this_region_config);
+ t_config_option_keys diff = region.config().diff(this_region_config);
if (! diff.empty()) {
- region.config.apply_only(this_region_config, diff);
- for (PrintObject *object : this->objects)
+ region.config_apply_only(this_region_config, diff, false);
+ for (PrintObject *object : m_objects)
if (region_id < object->region_volumes.size() && ! object->region_volumes[region_id].empty())
invalidated |= object->invalidate_state_by_config_options(diff);
}
@@ -484,8 +498,8 @@ exit_for_rearrange_regions:
// The current subdivision of regions does not make sense anymore.
// We need to remove all objects and re-add them.
ModelObjectPtrs model_objects;
- model_objects.reserve(this->objects.size());
- for (PrintObject *object : this->objects)
+ model_objects.reserve(m_objects.size());
+ for (PrintObject *object : m_objects)
model_objects.push_back(object->model_object());
this->clear_objects();
for (ModelObject *mo : model_objects)
@@ -494,7 +508,7 @@ exit_for_rearrange_regions:
}
// Always make sure that the layer_height_profiles are set, as they should not be modified from the worker threads.
- for (PrintObject *object : this->objects)
+ for (PrintObject *object : m_objects)
if (! object->layer_height_profile_valid)
object->update_layer_height_profile();
@@ -503,32 +517,32 @@ exit_for_rearrange_regions:
bool Print::has_infinite_skirt() const
{
- return (this->config.skirt_height == -1 && this->config.skirts > 0)
- || (this->config.ooze_prevention && this->extruders().size() > 1);
+ return (m_config.skirt_height == -1 && m_config.skirts > 0)
+ || (m_config.ooze_prevention && this->extruders().size() > 1);
}
bool Print::has_skirt() const
{
- return (this->config.skirt_height > 0 && this->config.skirts > 0)
+ return (m_config.skirt_height > 0 && m_config.skirts > 0)
|| this->has_infinite_skirt();
}
std::string Print::validate() const
{
- BoundingBox bed_box_2D = get_extents(Polygon::new_scale(config.bed_shape.values));
- BoundingBoxf3 print_volume(Pointf3(unscale(bed_box_2D.min.x), unscale(bed_box_2D.min.y), 0.0), Pointf3(unscale(bed_box_2D.max.x), unscale(bed_box_2D.max.y), config.max_print_height));
+ BoundingBox bed_box_2D = get_extents(Polygon::new_scale(m_config.bed_shape.values));
+ BoundingBoxf3 print_volume(Pointf3(unscale(bed_box_2D.min.x), unscale(bed_box_2D.min.y), 0.0), Pointf3(unscale(bed_box_2D.max.x), unscale(bed_box_2D.max.y), m_config.max_print_height));
// Allow the objects to protrude below the print bed, only the part of the object above the print bed will be sliced.
print_volume.min.z = -1e10;
- for (PrintObject *po : this->objects) {
+ for (PrintObject *po : m_objects) {
if (! print_volume.contains(po->model_object()->tight_bounding_box(false)))
return "Some objects are outside of the print volume.";
}
- if (this->config.complete_objects) {
+ if (m_config.complete_objects) {
// Check horizontal clearance.
{
Polygons convex_hulls_other;
- for (PrintObject *object : this->objects) {
+ for (PrintObject *object : m_objects) {
// Get convex hull of all meshes assigned to this print object.
Polygon convex_hull;
{
@@ -542,7 +556,7 @@ std::string Print::validate() const
// Apply the same transformations we apply to the actual meshes when slicing them.
object->model_object()->instances.front()->transform_polygon(&convex_hull);
// Grow convex hull with the clearance margin.
- convex_hull = offset(convex_hull, scale_(this->config.extruder_clearance_radius.value)/2, jtRound, scale_(0.1)).front();
+ convex_hull = offset(convex_hull, scale_(m_config.extruder_clearance_radius.value)/2, jtRound, scale_(0.1)).front();
// Now we check that no instance of convex_hull intersects any of the previously checked object instances.
for (const Point &copy : object->_shifted_copies) {
Polygon p = convex_hull;
@@ -556,47 +570,47 @@ std::string Print::validate() const
// Check vertical clearance.
{
std::vector<coord_t> object_height;
- for (const PrintObject *object : this->objects)
+ for (const PrintObject *object : m_objects)
object_height.insert(object_height.end(), object->copies().size(), object->size.z);
std::sort(object_height.begin(), object_height.end());
// Ignore the tallest *copy* (this is why we repeat height for all of them):
// it will be printed as last one so its height doesn't matter.
object_height.pop_back();
- if (! object_height.empty() && object_height.back() > scale_(this->config.extruder_clearance_height.value))
+ if (! object_height.empty() && object_height.back() > scale_(m_config.extruder_clearance_height.value))
return "Some objects are too tall and cannot be printed without extruder collisions.";
}
- } // end if (this->config.complete_objects)
+ } // end if (m_config.complete_objects)
- if (this->config.spiral_vase) {
+ if (m_config.spiral_vase) {
size_t total_copies_count = 0;
- for (const PrintObject *object : this->objects)
+ for (const PrintObject *object : m_objects)
total_copies_count += object->copies().size();
// #4043
- if (total_copies_count > 1 && ! this->config.complete_objects.value)
+ if (total_copies_count > 1 && ! m_config.complete_objects.value)
return "The Spiral Vase option can only be used when printing a single object.";
- if (this->regions.size() > 1)
+ if (m_regions.size() > 1)
return "The Spiral Vase option can only be used when printing single material objects.";
}
- if (this->has_wipe_tower() && ! this->objects.empty()) {
+ if (this->has_wipe_tower() && ! m_objects.empty()) {
#if 0
- for (auto dmr : this->config.nozzle_diameter.values)
+ for (auto dmr : m_config.nozzle_diameter.values)
if (std::abs(dmr - 0.4) > EPSILON)
return "The Wipe Tower is currently only supported for the 0.4mm nozzle diameter.";
#endif
- if (this->config.gcode_flavor != gcfRepRap && this->config.gcode_flavor != gcfMarlin)
+ if (m_config.gcode_flavor != gcfRepRap && m_config.gcode_flavor != gcfMarlin)
return "The Wipe Tower is currently only supported for the Marlin and RepRap/Sprinter G-code flavors.";
- if (! this->config.use_relative_e_distances)
+ if (! m_config.use_relative_e_distances)
return "The Wipe Tower is currently only supported with the relative extruder addressing (use_relative_e_distances=1).";
- SlicingParameters slicing_params0 = this->objects.front()->slicing_parameters();
- for (PrintObject *object : this->objects) {
+ SlicingParameters slicing_params0 = m_objects.front()->slicing_parameters();
+ for (PrintObject *object : m_objects) {
SlicingParameters slicing_params = object->slicing_parameters();
if (std::abs(slicing_params.first_print_layer_height - slicing_params0.first_print_layer_height) > EPSILON ||
std::abs(slicing_params.layer_height - slicing_params0.layer_height ) > EPSILON)
return "The Wipe Tower is only supported for multiple objects if they have equal layer heigths";
if (slicing_params.raft_layers() != slicing_params0.raft_layers())
return "The Wipe Tower is only supported for multiple objects if they are printed over an equal number of raft layers";
- if (object->config.support_material_contact_distance != this->objects.front()->config.support_material_contact_distance)
+ if (object->config().support_material_contact_distance != m_objects.front()->config().support_material_contact_distance)
return "The Wipe Tower is only supported for multiple objects if they are printed with the same support_material_contact_distance";
if (! equal_layering(slicing_params, slicing_params0))
return "The Wipe Tower is only supported for multiple objects if they are sliced equally.";
@@ -605,7 +619,7 @@ std::string Print::validate() const
object->layer_height_profile_valid = was_layer_height_profile_valid;
for (size_t i = 5; i < object->layer_height_profile.size(); i += 2)
if (object->layer_height_profile[i-1] > slicing_params.object_print_z_min + EPSILON &&
- std::abs(object->layer_height_profile[i] - object->config.layer_height) > EPSILON)
+ std::abs(object->layer_height_profile[i] - object->config().layer_height) > EPSILON)
return "The Wipe Tower is currently only supported with constant Z layer spacing. Layer editing is not allowed.";
}
}
@@ -618,12 +632,12 @@ std::string Print::validate() const
std::vector<double> nozzle_diameters;
for (unsigned int extruder_id : extruders)
- nozzle_diameters.push_back(this->config.nozzle_diameter.get_at(extruder_id));
+ nozzle_diameters.push_back(m_config.nozzle_diameter.get_at(extruder_id));
double min_nozzle_diameter = *std::min_element(nozzle_diameters.begin(), nozzle_diameters.end());
- for (PrintObject *object : this->objects) {
- if ((object->config.support_material_extruder == -1 || object->config.support_material_interface_extruder == -1) &&
- (object->config.raft_layers > 0 || object->config.support_material.value)) {
+ for (PrintObject *object : m_objects) {
+ if ((object->config().support_material_extruder == -1 || object->config().support_material_interface_extruder == -1) &&
+ (object->config().raft_layers > 0 || object->config().support_material.value)) {
// The object has some form of support and either support_material_extruder or support_material_interface_extruder
// will be printed with the current tool without a forced tool change. Play safe, assert that all object nozzles
// are of the same diameter.
@@ -634,16 +648,16 @@ std::string Print::validate() const
}
// validate first_layer_height
- double first_layer_height = object->config.get_abs_value("first_layer_height");
+ double first_layer_height = object->config().get_abs_value("first_layer_height");
double first_layer_min_nozzle_diameter;
- if (object->config.raft_layers > 0) {
+ if (object->config().raft_layers > 0) {
// if we have raft layers, only support material extruder is used on first layer
- size_t first_layer_extruder = object->config.raft_layers == 1
- ? object->config.support_material_interface_extruder-1
- : object->config.support_material_extruder-1;
+ size_t first_layer_extruder = object->config().raft_layers == 1
+ ? object->config().support_material_interface_extruder-1
+ : object->config().support_material_extruder-1;
first_layer_min_nozzle_diameter = (first_layer_extruder == size_t(-1)) ?
min_nozzle_diameter :
- this->config.nozzle_diameter.get_at(first_layer_extruder);
+ m_config.nozzle_diameter.get_at(first_layer_extruder);
} else {
// if we don't have raft layers, any nozzle diameter is potentially used in first layer
first_layer_min_nozzle_diameter = min_nozzle_diameter;
@@ -652,7 +666,7 @@ std::string Print::validate() const
return "First layer height can't be greater than nozzle diameter";
// validate layer_height
- if (object->config.layer_height.value > min_nozzle_diameter)
+ if (object->config().layer_height.value > min_nozzle_diameter)
return "Layer height can't be greater than nozzle diameter";
}
}
@@ -665,7 +679,7 @@ std::string Print::validate() const
BoundingBox Print::bounding_box() const
{
BoundingBox bb;
- for (const PrintObject *object : this->objects)
+ for (const PrintObject *object : m_objects)
for (Point copy : object->_shifted_copies) {
bb.merge(copy);
copy.translate(object->size);
@@ -683,7 +697,7 @@ BoundingBox Print::total_bounding_box() const
BoundingBox bb = this->bounding_box();
// we need to offset the objects bounding box by at least half the perimeters extrusion width
- Flow perimeter_flow = this->objects.front()->get_layer(0)->get_region(0)->flow(frPerimeter);
+ Flow perimeter_flow = m_objects.front()->get_layer(0)->get_region(0)->flow(frPerimeter);
double extra = perimeter_flow.width/2;
// consider support material
@@ -692,18 +706,18 @@ BoundingBox Print::total_bounding_box() const
}
// consider brim and skirt
- if (this->config.brim_width.value > 0) {
+ if (m_config.brim_width.value > 0) {
Flow brim_flow = this->brim_flow();
- extra = std::max(extra, this->config.brim_width.value + brim_flow.width/2);
+ extra = std::max(extra, m_config.brim_width.value + brim_flow.width/2);
}
if (this->has_skirt()) {
- int skirts = this->config.skirts.value;
+ int skirts = m_config.skirts.value;
if (skirts == 0 && this->has_infinite_skirt()) skirts = 1;
Flow skirt_flow = this->skirt_flow();
extra = std::max(
extra,
- this->config.brim_width.value
- + this->config.skirt_distance.value
+ m_config.brim_width.value
+ + m_config.skirt_distance.value
+ skirts * skirt_flow.spacing()
+ skirt_flow.width/2
);
@@ -717,17 +731,17 @@ BoundingBox Print::total_bounding_box() const
double Print::skirt_first_layer_height() const
{
- if (this->objects.empty()) CONFESS("skirt_first_layer_height() can't be called without PrintObjects");
- return this->objects.front()->config.get_abs_value("first_layer_height");
+ if (m_objects.empty()) CONFESS("skirt_first_layer_height() can't be called without PrintObjects");
+ return m_objects.front()->config().get_abs_value("first_layer_height");
}
Flow Print::brim_flow() const
{
- ConfigOptionFloatOrPercent width = this->config.first_layer_extrusion_width;
+ ConfigOptionFloatOrPercent width = m_config.first_layer_extrusion_width;
if (width.value == 0)
- width = this->regions.front()->config.perimeter_extrusion_width;
+ width = m_regions.front()->config().perimeter_extrusion_width;
if (width.value == 0)
- width = this->objects.front()->config.extrusion_width;
+ width = m_objects.front()->config().extrusion_width;
/* We currently use a random region's perimeter extruder.
While this works for most cases, we should probably consider all of the perimeter
@@ -737,7 +751,7 @@ Flow Print::brim_flow() const
return Flow::new_from_config_width(
frPerimeter,
width,
- this->config.nozzle_diameter.get_at(this->regions.front()->config.perimeter_extruder-1),
+ m_config.nozzle_diameter.get_at(m_regions.front()->config().perimeter_extruder-1),
this->skirt_first_layer_height(),
0
);
@@ -745,11 +759,11 @@ Flow Print::brim_flow() const
Flow Print::skirt_flow() const
{
- ConfigOptionFloatOrPercent width = this->config.first_layer_extrusion_width;
+ ConfigOptionFloatOrPercent width = m_config.first_layer_extrusion_width;
if (width.value == 0)
- width = this->regions.front()->config.perimeter_extrusion_width;
+ width = m_regions.front()->config().perimeter_extrusion_width;
if (width.value == 0)
- width = this->objects.front()->config.extrusion_width;
+ width = m_objects.front()->config().extrusion_width;
/* We currently use a random object's support material extruder.
While this works for most cases, we should probably consider all of the support material
@@ -759,7 +773,7 @@ Flow Print::skirt_flow() const
return Flow::new_from_config_width(
frPerimeter,
width,
- this->config.nozzle_diameter.get_at(this->objects.front()->config.support_material_extruder-1),
+ m_config.nozzle_diameter.get_at(m_objects.front()->config().support_material_extruder-1),
this->skirt_first_layer_height(),
0
);
@@ -767,7 +781,7 @@ Flow Print::skirt_flow() const
PrintRegionConfig Print::_region_config_from_model_volume(const ModelVolume &volume)
{
- PrintRegionConfig config = this->default_region_config;
+ PrintRegionConfig config = this->default_region_config();
normalize_and_apply_config(config, volume.get_object()->config);
normalize_and_apply_config(config, volume.config);
if (! volume.material_id().empty())
@@ -777,7 +791,7 @@ PrintRegionConfig Print::_region_config_from_model_volume(const ModelVolume &vol
bool Print::has_support_material() const
{
- for (const PrintObject *object : this->objects)
+ for (const PrintObject *object : m_objects)
if (object->has_support_material())
return true;
return false;
@@ -791,7 +805,7 @@ void Print::auto_assign_extruders(ModelObject* model_object) const
if (model_object->volumes.size() < 2)
return;
-// size_t extruders = this->config.nozzle_diameter.values.size();
+// size_t extruders = m_config.nozzle_diameter.values.size();
for (size_t volume_id = 0; volume_id < model_object->volumes.size(); ++ volume_id) {
ModelVolume *volume = model_object->volumes[volume_id];
//FIXME Vojtech: This assigns an extruder ID even to a modifier volume, if it has a material assigned.
@@ -804,44 +818,44 @@ void Print::auto_assign_extruders(ModelObject* model_object) const
void Print::process()
{
BOOST_LOG_TRIVIAL(info) << "Staring the slicing process.";
- for (PrintObject *obj : this->objects)
+ for (PrintObject *obj : m_objects)
obj->make_perimeters();
this->throw_if_canceled();
this->set_status(70, "Infilling layers");
- for (PrintObject *obj : this->objects)
+ for (PrintObject *obj : m_objects)
obj->infill();
this->throw_if_canceled();
- for (PrintObject *obj : this->objects)
+ for (PrintObject *obj : m_objects)
obj->generate_support_material();
this->throw_if_canceled();
if (! m_state.is_done(psSkirt)) {
this->set_started(psSkirt);
- this->skirt.clear();
+ m_skirt.clear();
if (this->has_skirt()) {
this->set_status(88, "Generating skirt");
this->_make_skirt();
}
- m_state.set_done(psSkirt);
+ this->set_done(psSkirt);
}
this->throw_if_canceled();
if (! m_state.is_done(psBrim)) {
this->set_started(psBrim);
- this->brim.clear();
- if (this->config.brim_width > 0) {
+ m_brim.clear();
+ if (m_config.brim_width > 0) {
this->set_status(88, "Generating brim");
this->_make_brim();
}
- m_state.set_done(psBrim);
+ this->set_done(psBrim);
}
this->throw_if_canceled();
if (! m_state.is_done(psWipeTower)) {
this->set_started(psWipeTower);
- this->_clear_wipe_tower();
+ m_wipe_tower_data.clear();
if (this->has_wipe_tower()) {
//this->set_status(95, "Generating wipe tower");
this->_make_wipe_tower();
}
- m_state.set_done(psWipeTower);
+ this->set_done(psWipeTower);
}
BOOST_LOG_TRIVIAL(info) << "Slicing process finished.";
}
@@ -883,20 +897,20 @@ void Print::_make_skirt()
// prepended to the first 'n' layers (with 'n' = skirt_height).
// $skirt_height_z in this case is the highest possible skirt height for safety.
coordf_t skirt_height_z = 0.;
- for (const PrintObject *object : this->objects) {
+ for (const PrintObject *object : m_objects) {
size_t skirt_layers = this->has_infinite_skirt() ?
object->layer_count() :
- std::min(size_t(this->config.skirt_height.value), object->layer_count());
- skirt_height_z = std::max(skirt_height_z, object->layers[skirt_layers-1]->print_z);
+ std::min(size_t(m_config.skirt_height.value), object->layer_count());
+ skirt_height_z = std::max(skirt_height_z, object->m_layers[skirt_layers-1]->print_z);
}
// Collect points from all layers contained in skirt height.
Points points;
- for (const PrintObject *object : this->objects) {
+ for (const PrintObject *object : m_objects) {
this->throw_if_canceled();
Points object_points;
// Get object layers up to skirt_height_z.
- for (const Layer *layer : object->layers) {
+ for (const Layer *layer : object->m_layers) {
if (layer->print_z > skirt_height_z)
break;
for (const ExPolygon &expoly : layer->slices.expolygons)
@@ -904,7 +918,7 @@ void Print::_make_skirt()
append(object_points, expoly.contour.points);
}
// Get support layers up to skirt_height_z.
- for (const SupportLayer *layer : object->support_layers) {
+ for (const SupportLayer *layer : object->support_layers()) {
if (layer->print_z > skirt_height_z)
break;
for (const ExtrusionEntity *extrusion_entity : layer->support_fills.entities)
@@ -942,18 +956,18 @@ void Print::_make_skirt()
extruders_e_per_mm.reserve(set_extruders.size());
for (auto &extruder_id : set_extruders) {
extruders.push_back(extruder_id);
- extruders_e_per_mm.push_back(Extruder((unsigned int)extruder_id, &this->config).e_per_mm(mm3_per_mm));
+ extruders_e_per_mm.push_back(Extruder((unsigned int)extruder_id, &m_config).e_per_mm(mm3_per_mm));
}
}
// Number of skirt loops per skirt layer.
- int n_skirts = this->config.skirts.value;
+ int n_skirts = m_config.skirts.value;
if (this->has_infinite_skirt() && n_skirts == 0)
n_skirts = 1;
// Initial offset of the brim inner edge from the object (possible with a support & raft).
// The skirt will touch the brim if the brim is extruded.
- coord_t distance = scale_(std::max(this->config.skirt_distance.value, this->config.brim_width.value));
+ coord_t distance = scale_(std::max(m_config.skirt_distance.value, m_config.brim_width.value));
// Draw outlines from outside to inside.
// Loop while we have less skirts than required or any extruder hasn't reached the min length if any.
std::vector<coordf_t> extruded_length(extruders.size(), 0.);
@@ -978,16 +992,16 @@ void Print::_make_skirt()
first_layer_height // this will be overridden at G-code export time
)));
eloop.paths.back().polyline = loop.split_at_first_point();
- this->skirt.append(eloop);
- if (this->config.min_skirt_length.value > 0) {
+ m_skirt.append(eloop);
+ if (m_config.min_skirt_length.value > 0) {
// The skirt length is limited. Sum the total amount of filament length extruded, in mm.
extruded_length[extruder_idx] += unscale(loop.length()) * extruders_e_per_mm[extruder_idx];
- if (extruded_length[extruder_idx] < this->config.min_skirt_length.value) {
+ if (extruded_length[extruder_idx] < m_config.min_skirt_length.value) {
// Not extruded enough yet with the current extruder. Add another loop.
if (i == 1)
++ i;
} else {
- assert(extruded_length[extruder_idx] >= this->config.min_skirt_length.value);
+ assert(extruded_length[extruder_idx] >= m_config.min_skirt_length.value);
// Enough extruded with the current extruder. Extrude with the next one,
// until the prescribed number of skirt loops is extruded.
if (extruder_idx + 1 < extruders.size())
@@ -998,7 +1012,7 @@ void Print::_make_skirt()
}
}
// Brims were generated inside out, reverse to print the outmost contour first.
- this->skirt.reverse();
+ m_skirt.reverse();
}
void Print::_make_brim()
@@ -1006,13 +1020,13 @@ void Print::_make_brim()
// Brim is only printed on first layer and uses perimeter extruder.
Flow flow = this->brim_flow();
Polygons islands;
- for (PrintObject *object : this->objects) {
+ for (PrintObject *object : m_objects) {
this->throw_if_canceled();
Polygons object_islands;
- for (ExPolygon &expoly : object->layers.front()->slices.expolygons)
+ for (ExPolygon &expoly : object->m_layers.front()->slices.expolygons)
object_islands.push_back(expoly.contour);
- if (! object->support_layers.empty())
- object->support_layers.front()->support_fills.polygons_covered_by_spacing(object_islands, float(SCALED_EPSILON));
+ if (! object->support_layers().empty())
+ object->support_layers().front()->support_fills.polygons_covered_by_spacing(object_islands, float(SCALED_EPSILON));
islands.reserve(islands.size() + object_islands.size() * object->_shifted_copies.size());
for (const Point &pt : object->_shifted_copies)
for (Polygon &poly : object_islands) {
@@ -1021,7 +1035,7 @@ void Print::_make_brim()
}
}
Polygons loops;
- size_t num_loops = size_t(floor(this->config.brim_width.value / flow.width));
+ size_t num_loops = size_t(floor(m_config.brim_width.value / flow.width));
for (size_t i = 0; i < num_loops; ++ i) {
this->throw_if_canceled();
islands = offset(islands, float(flow.scaled_spacing()), jtSquare);
@@ -1037,32 +1051,24 @@ void Print::_make_brim()
loops = union_pt_chained(loops, false);
std::reverse(loops.begin(), loops.end());
- extrusion_entities_append_loops(this->brim.entities, std::move(loops), erSkirt, float(flow.mm3_per_mm()), float(flow.width), float(this->skirt_first_layer_height()));
+ extrusion_entities_append_loops(m_brim.entities, std::move(loops), erSkirt, float(flow.mm3_per_mm()), float(flow.width), float(this->skirt_first_layer_height()));
}
// Wipe tower support.
bool Print::has_wipe_tower() const
{
return
- this->config.single_extruder_multi_material.value &&
- ! this->config.spiral_vase.value &&
- this->config.wipe_tower.value &&
- this->config.nozzle_diameter.values.size() > 1;
-}
-
-void Print::_clear_wipe_tower()
-{
- m_tool_ordering.clear();
- m_wipe_tower_priming.reset(nullptr);
- m_wipe_tower_tool_changes.clear();
- m_wipe_tower_final_purge.reset(nullptr);
+ m_config.single_extruder_multi_material.value &&
+ ! m_config.spiral_vase.value &&
+ m_config.wipe_tower.value &&
+ m_config.nozzle_diameter.values.size() > 1;
}
void Print::_make_wipe_tower()
{
// Let the ToolOrdering class know there will be initial priming extrusions at the start of the print.
- m_tool_ordering = ToolOrdering(*this, (unsigned int)-1, true);
- if (! m_tool_ordering.has_wipe_tower())
+ m_wipe_tower_data.tool_ordering = ToolOrdering(*this, (unsigned int)-1, true);
+ if (! m_wipe_tower_data.tool_ordering.has_wipe_tower())
// Don't generate any wipe tower.
return;
@@ -1072,33 +1078,31 @@ void Print::_make_wipe_tower()
// see https://github.com/prusa3d/Slic3r/issues/607
{
size_t idx_begin = size_t(-1);
- size_t idx_end = m_tool_ordering.layer_tools().size();
+ size_t idx_end = m_wipe_tower_data.tool_ordering.layer_tools().size();
// Find the first wipe tower layer, which does not have a counterpart in an object or a support layer.
for (size_t i = 0; i < idx_end; ++ i) {
- const ToolOrdering::LayerTools &lt = m_tool_ordering.layer_tools()[i];
+ const ToolOrdering::LayerTools &lt = m_wipe_tower_data.tool_ordering.layer_tools()[i];
if (lt.has_wipe_tower && ! lt.has_object && ! lt.has_support) {
idx_begin = i;
break;
}
}
if (idx_begin != size_t(-1)) {
- // Find the position in this->objects.first()->support_layers to insert these new support layers.
- double wipe_tower_new_layer_print_z_first = m_tool_ordering.layer_tools()[idx_begin].print_z;
- SupportLayerPtrs::iterator it_layer = this->objects.front()->support_layers.begin();
- SupportLayerPtrs::iterator it_end = this->objects.front()->support_layers.end();
+ // Find the position in m_objects.first()->support_layers to insert these new support layers.
+ double wipe_tower_new_layer_print_z_first = m_wipe_tower_data.tool_ordering.layer_tools()[idx_begin].print_z;
+ SupportLayerPtrs::const_iterator it_layer = m_objects.front()->support_layers().begin();
+ SupportLayerPtrs::const_iterator it_end = m_objects.front()->support_layers().end();
for (; it_layer != it_end && (*it_layer)->print_z - EPSILON < wipe_tower_new_layer_print_z_first; ++ it_layer);
// Find the stopper of the sequence of wipe tower layers, which do not have a counterpart in an object or a support layer.
for (size_t i = idx_begin; i < idx_end; ++ i) {
- ToolOrdering::LayerTools &lt = const_cast<ToolOrdering::LayerTools&>(m_tool_ordering.layer_tools()[i]);
+ ToolOrdering::LayerTools &lt = const_cast<ToolOrdering::LayerTools&>(m_wipe_tower_data.tool_ordering.layer_tools()[i]);
if (! (lt.has_wipe_tower && ! lt.has_object && ! lt.has_support))
break;
lt.has_support = true;
// Insert the new support layer.
- double height = lt.print_z - m_tool_ordering.layer_tools()[i-1].print_z;
+ double height = lt.print_z - m_wipe_tower_data.tool_ordering.layer_tools()[i-1].print_z;
//FIXME the support layer ID is set to -1, as Vojtech hopes it is not being used anyway.
- auto *new_layer = new SupportLayer(size_t(-1), this->objects.front(),
- height, lt.print_z, lt.print_z - 0.5 * height);
- it_layer = this->objects.front()->support_layers.insert(it_layer, new_layer);
+ it_layer = m_objects.front()->insert_support_layer(it_layer, size_t(-1), height, lt.print_z, lt.print_z - 0.5 * height);
++ it_layer;
}
}
@@ -1107,9 +1111,9 @@ void Print::_make_wipe_tower()
// Initialize the wipe tower.
WipeTowerPrusaMM wipe_tower(
- float(this->config.wipe_tower_x.value), float(this->config.wipe_tower_y.value),
- float(this->config.wipe_tower_width.value), float(this->config.wipe_tower_per_color_wipe.value),
- m_tool_ordering.first_extruder());
+ float(m_config.wipe_tower_x.value), float(m_config.wipe_tower_y.value),
+ float(m_config.wipe_tower_width.value), float(m_config.wipe_tower_per_color_wipe.value),
+ m_wipe_tower_data.tool_ordering.first_extruder());
//wipe_tower.set_retract();
//wipe_tower.set_zhop();
@@ -1118,29 +1122,29 @@ void Print::_make_wipe_tower()
for (size_t i = 0; i < 4; ++ i)
wipe_tower.set_extruder(
i,
- WipeTowerPrusaMM::parse_material(this->config.filament_type.get_at(i).c_str()),
- this->config.temperature.get_at(i),
- this->config.first_layer_temperature.get_at(i));
+ WipeTowerPrusaMM::parse_material(m_config.filament_type.get_at(i).c_str()),
+ m_config.temperature.get_at(i),
+ m_config.first_layer_temperature.get_at(i));
// When printing the first layer's wipe tower, the first extruder is expected to be active and primed.
- // Therefore the number of wipe sections at the wipe tower will be (m_tool_ordering.front().extruders-1) at the 1st layer.
+ // Therefore the number of wipe sections at the wipe tower will be (m_wipe_tower_data.tool_ordering.front().extruders-1) at the 1st layer.
// The following variable is true if the last priming section cannot be squeezed inside the wipe tower.
- bool last_priming_wipe_full = m_tool_ordering.front().extruders.size() > m_tool_ordering.front().wipe_tower_partitions;
+ bool last_priming_wipe_full = m_wipe_tower_data.tool_ordering.front().extruders.size() > m_wipe_tower_data.tool_ordering.front().wipe_tower_partitions;
- m_wipe_tower_priming = Slic3r::make_unique<WipeTower::ToolChangeResult>(
- wipe_tower.prime(this->skirt_first_layer_height(), m_tool_ordering.all_extruders(), ! last_priming_wipe_full, WipeTower::PURPOSE_EXTRUDE));
+ m_wipe_tower_data.priming = Slic3r::make_unique<WipeTower::ToolChangeResult>(
+ wipe_tower.prime(this->skirt_first_layer_height(), m_wipe_tower_data.tool_ordering.all_extruders(), ! last_priming_wipe_full, WipeTower::PURPOSE_EXTRUDE));
// Generate the wipe tower layers.
- m_wipe_tower_tool_changes.reserve(m_tool_ordering.layer_tools().size());
+ m_wipe_tower_data.tool_changes.reserve(m_wipe_tower_data.tool_ordering.layer_tools().size());
// Set current_extruder_id to the last extruder primed.
- unsigned int current_extruder_id = m_tool_ordering.all_extruders().back();
- for (const ToolOrdering::LayerTools &layer_tools : m_tool_ordering.layer_tools()) {
+ unsigned int current_extruder_id = m_wipe_tower_data.tool_ordering.all_extruders().back();
+ for (const ToolOrdering::LayerTools &layer_tools : m_wipe_tower_data.tool_ordering.layer_tools()) {
this->throw_if_canceled();
if (! layer_tools.has_wipe_tower)
// This is a support only layer, or the wipe tower does not reach to this height.
continue;
- bool first_layer = &layer_tools == &m_tool_ordering.front();
- bool last_layer = &layer_tools == &m_tool_ordering.back() || (&layer_tools + 1)->wipe_tower_partitions == 0;
+ bool first_layer = &layer_tools == &m_wipe_tower_data.tool_ordering.front();
+ bool last_layer = &layer_tools == &m_wipe_tower_data.tool_ordering.back() || (&layer_tools + 1)->wipe_tower_partitions == 0;
wipe_tower.set_layer(
float(layer_tools.print_z),
float(layer_tools.wipe_tower_layer_height),
@@ -1151,7 +1155,7 @@ void Print::_make_wipe_tower()
for (unsigned int extruder_id : layer_tools.extruders)
// Call the wipe_tower.tool_change() at the first layer for the initial extruder
// to extrude the wipe tower brim,
- if ((first_layer && extruder_id == m_tool_ordering.all_extruders().back()) ||
+ if ((first_layer && extruder_id == m_wipe_tower_data.tool_ordering.all_extruders().back()) ||
// or when an extruder shall be switched.
extruder_id != current_extruder_id) {
tool_changes.emplace_back(wipe_tower.tool_change(extruder_id, extruder_id == layer_tools.extruders.back(), WipeTower::PURPOSE_EXTRUDE));
@@ -1175,48 +1179,49 @@ void Print::_make_wipe_tower()
tool_changes.pop_back();
}
}
- m_wipe_tower_tool_changes.emplace_back(std::move(tool_changes));
+ m_wipe_tower_data.tool_changes.emplace_back(std::move(tool_changes));
if (last_layer)
break;
}
// Unload the current filament over the purge tower.
- coordf_t layer_height = this->objects.front()->config.layer_height.value;
- if (m_tool_ordering.back().wipe_tower_partitions > 0) {
+ coordf_t layer_height = m_objects.front()->config().layer_height.value;
+ if (m_wipe_tower_data.tool_ordering.back().wipe_tower_partitions > 0) {
// The wipe tower goes up to the last layer of the print.
if (wipe_tower.layer_finished()) {
// The wipe tower is printed to the top of the print and it has no space left for the final extruder purge.
// Lift Z to the next layer.
- wipe_tower.set_layer(float(m_tool_ordering.back().print_z + layer_height), float(layer_height), 0, false, true);
+ wipe_tower.set_layer(float(m_wipe_tower_data.tool_ordering.back().print_z + layer_height), float(layer_height), 0, false, true);
} else {
// There is yet enough space at this layer of the wipe tower for the final purge.
}
} else {
// The wipe tower does not reach the last print layer, perform the pruge at the last print layer.
- assert(m_tool_ordering.back().wipe_tower_partitions == 0);
- wipe_tower.set_layer(float(m_tool_ordering.back().print_z), float(layer_height), 0, false, true);
+ assert(m_wipe_tower_data.tool_ordering.back().wipe_tower_partitions == 0);
+ wipe_tower.set_layer(float(m_wipe_tower_data.tool_ordering.back().print_z), float(layer_height), 0, false, true);
}
- m_wipe_tower_final_purge = Slic3r::make_unique<WipeTower::ToolChangeResult>(
+ m_wipe_tower_data.final_purge = Slic3r::make_unique<WipeTower::ToolChangeResult>(
wipe_tower.tool_change((unsigned int)-1, false, WipeTower::PURPOSE_EXTRUDE));
}
-std::string Print::output_filename()
+std::string Print::output_filename() const
{
- this->placeholder_parser.update_timestamp();
+ DynamicConfig cfg_timestamp;
+ PlaceholderParser::update_timestamp(cfg_timestamp);
try {
- return this->placeholder_parser.process(this->config.output_filename_format.value, 0);
+ return this->placeholder_parser().process(m_config.output_filename_format.value, 0, &cfg_timestamp);
} catch (std::runtime_error &err) {
throw std::runtime_error(std::string("Failed processing of the output_filename_format template.\n") + err.what());
}
}
-std::string Print::output_filepath(const std::string &path)
+std::string Print::output_filepath(const std::string &path) const
{
// if we were supplied no path, generate an automatic one based on our first object's input file
if (path.empty()) {
// get the first input file name
std::string input_file;
- for (const PrintObject *object : this->objects) {
+ for (const PrintObject *object : m_objects) {
input_file = object->model_object()->input_file;
if (! input_file.empty())
break;