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
path: root/xs
diff options
context:
space:
mode:
authorbubnikv <bubnikv@gmail.com>2018-09-11 15:04:47 +0300
committerbubnikv <bubnikv@gmail.com>2018-09-11 15:04:47 +0300
commit41ce69f327a2fe3324dc47756b64a6fdb001cfa3 (patch)
treef2e4a00464c1c3aaee1e03cf1b1395c0f725e554 /xs
parent49697ed6aaa5155461be37be82f3b6bf58635a08 (diff)
Improved constness of the Print / PrintObject / Layer ...
Split the wipe tower and time statistics data into separate objects. Initial work in synchronizing the Model with the Print.
Diffstat (limited to 'xs')
-rw-r--r--xs/src/libslic3r/Fill/Fill.cpp14
-rw-r--r--xs/src/libslic3r/Flow.cpp24
-rw-r--r--xs/src/libslic3r/GCode.cpp272
-rw-r--r--xs/src/libslic3r/GCode/PrintExtents.cpp14
-rw-r--r--xs/src/libslic3r/GCode/ToolOrdering.cpp50
-rw-r--r--xs/src/libslic3r/GCode/WipeTowerPrusaMM.cpp26
-rw-r--r--xs/src/libslic3r/Layer.cpp52
-rw-r--r--xs/src/libslic3r/Layer.hpp145
-rw-r--r--xs/src/libslic3r/LayerRegion.cpp30
-rw-r--r--xs/src/libslic3r/PerimeterGenerator.cpp3
-rw-r--r--xs/src/libslic3r/PerimeterGenerator.hpp48
-rw-r--r--xs/src/libslic3r/PlaceholderParser.cpp16
-rw-r--r--xs/src/libslic3r/PlaceholderParser.hpp6
-rw-r--r--xs/src/libslic3r/Print.cpp401
-rw-r--r--xs/src/libslic3r/Print.hpp346
-rw-r--r--xs/src/libslic3r/PrintObject.cpp541
-rw-r--r--xs/src/libslic3r/PrintRegion.cpp32
-rw-r--r--xs/src/libslic3r/SupportMaterial.cpp130
-rw-r--r--xs/src/libslic3r/SupportMaterial.hpp2
-rw-r--r--xs/src/slic3r/GUI/3DScene.cpp64
-rw-r--r--xs/xsp/Print.xsp84
21 files changed, 1198 insertions, 1102 deletions
diff --git a/xs/src/libslic3r/Fill/Fill.cpp b/xs/src/libslic3r/Fill/Fill.cpp
index 5333fcfec..f1436c931 100644
--- a/xs/src/libslic3r/Fill/Fill.cpp
+++ b/xs/src/libslic3r/Fill/Fill.cpp
@@ -34,7 +34,7 @@ void make_fill(LayerRegion &layerm, ExtrusionEntityCollection &out)
{
// Slic3r::debugf "Filling layer %d:\n", $layerm->layer->id;
- double fill_density = layerm.region()->config.fill_density;
+ double fill_density = layerm.region()->config().fill_density;
Flow infill_flow = layerm.flow(frInfill);
Flow solid_infill_flow = layerm.flow(frSolidInfill);
Flow top_solid_infill_flow = layerm.flow(frTopSolidInfill);
@@ -69,7 +69,7 @@ void make_fill(LayerRegion &layerm, ExtrusionEntityCollection &out)
if (surface.is_solid() && (!surface.is_bridge() || layerm.layer()->id() == 0)) {
group_attrib[i].is_solid = true;
group_attrib[i].flow_width = (surface.surface_type == stTop) ? top_solid_infill_flow.width : solid_infill_flow.width;
- group_attrib[i].pattern = surface.is_external() ? layerm.region()->config.external_fill_pattern.value : ipRectilinear;
+ group_attrib[i].pattern = surface.is_external() ? layerm.region()->config().external_fill_pattern.value : ipRectilinear;
}
}
// Loop through solid groups, find compatible groups and append them to this one.
@@ -152,7 +152,7 @@ void make_fill(LayerRegion &layerm, ExtrusionEntityCollection &out)
for (const Surface &surface : surfaces) {
if (surface.surface_type == stInternalVoid)
continue;
- InfillPattern fill_pattern = layerm.region()->config.fill_pattern.value;
+ InfillPattern fill_pattern = layerm.region()->config().fill_pattern.value;
double density = fill_density;
FlowRole role = (surface.surface_type == stTop) ? frTopSolidInfill :
(surface.is_solid() ? frSolidInfill : frInfill);
@@ -161,7 +161,7 @@ void make_fill(LayerRegion &layerm, ExtrusionEntityCollection &out)
if (surface.is_solid()) {
density = 100.;
fill_pattern = (surface.is_external() && ! is_bridge) ?
- layerm.region()->config.external_fill_pattern.value :
+ layerm.region()->config().external_fill_pattern.value :
ipRectilinear;
} else if (density <= 0)
continue;
@@ -190,7 +190,7 @@ void make_fill(LayerRegion &layerm, ExtrusionEntityCollection &out)
// layer height
Flow internal_flow = layerm.region()->flow(
frInfill,
- layerm.layer()->object()->config.layer_height.value, // TODO: handle infill_every_layers?
+ layerm.layer()->object()->config().layer_height.value, // TODO: handle infill_every_layers?
false, // no bridge
false, // no first layer
-1, // auto width
@@ -205,7 +205,7 @@ void make_fill(LayerRegion &layerm, ExtrusionEntityCollection &out)
double link_max_length = 0.;
if (! is_bridge) {
#if 0
- link_max_length = layerm.region()->config.get_abs_value(surface.is_external() ? "external_fill_link_max_length" : "fill_link_max_length", flow.spacing());
+ link_max_length = layerm.region()->config().get_abs_value(surface.is_external() ? "external_fill_link_max_length" : "fill_link_max_length", flow.spacing());
// printf("flow spacing: %f, is_external: %d, link_max_length: %lf\n", flow.spacing(), int(surface.is_external()), link_max_length);
#else
if (density > 80.) // 80%
@@ -215,7 +215,7 @@ void make_fill(LayerRegion &layerm, ExtrusionEntityCollection &out)
f->layer_id = layerm.layer()->id();
f->z = layerm.layer()->print_z;
- f->angle = float(Geometry::deg2rad(layerm.region()->config.fill_angle.value));
+ f->angle = float(Geometry::deg2rad(layerm.region()->config().fill_angle.value));
// Maximum length of the perimeter segment linking two infill lines.
f->link_max_length = scale_(link_max_length);
// Used by the concentric infill pattern to clip the loops to create extrusion paths.
diff --git a/xs/src/libslic3r/Flow.cpp b/xs/src/libslic3r/Flow.cpp
index b60e26dcc..c33de8b6e 100644
--- a/xs/src/libslic3r/Flow.cpp
+++ b/xs/src/libslic3r/Flow.cpp
@@ -111,22 +111,22 @@ Flow support_material_flow(const PrintObject *object, float layer_height)
return Flow::new_from_config_width(
frSupportMaterial,
// The width parameter accepted by new_from_config_width is of type ConfigOptionFloatOrPercent, the Flow class takes care of the percent to value substitution.
- (object->config.support_material_extrusion_width.value > 0) ? object->config.support_material_extrusion_width : object->config.extrusion_width,
- // if object->config.support_material_extruder == 0 (which means to not trigger tool change, but use the current extruder instead), get_at will return the 0th component.
- float(object->print()->config.nozzle_diameter.get_at(object->config.support_material_extruder-1)),
- (layer_height > 0.f) ? layer_height : float(object->config.layer_height.value),
+ (object->config().support_material_extrusion_width.value > 0) ? object->config().support_material_extrusion_width : object->config().extrusion_width,
+ // if object->config().support_material_extruder == 0 (which means to not trigger tool change, but use the current extruder instead), get_at will return the 0th component.
+ float(object->print()->config().nozzle_diameter.get_at(object->config().support_material_extruder-1)),
+ (layer_height > 0.f) ? layer_height : float(object->config().layer_height.value),
false);
}
Flow support_material_1st_layer_flow(const PrintObject *object, float layer_height)
{
- const auto &width = (object->print()->config.first_layer_extrusion_width.value > 0) ? object->print()->config.first_layer_extrusion_width : object->config.support_material_extrusion_width;
+ const auto &width = (object->print()->config().first_layer_extrusion_width.value > 0) ? object->print()->config().first_layer_extrusion_width : object->config().support_material_extrusion_width;
return Flow::new_from_config_width(
frSupportMaterial,
// The width parameter accepted by new_from_config_width is of type ConfigOptionFloatOrPercent, the Flow class takes care of the percent to value substitution.
- (width.value > 0) ? width : object->config.extrusion_width,
- float(object->print()->config.nozzle_diameter.get_at(object->config.support_material_extruder-1)),
- (layer_height > 0.f) ? layer_height : float(object->config.first_layer_height.get_abs_value(object->config.layer_height.value)),
+ (width.value > 0) ? width : object->config().extrusion_width,
+ float(object->print()->config().nozzle_diameter.get_at(object->config().support_material_extruder-1)),
+ (layer_height > 0.f) ? layer_height : float(object->config().first_layer_height.get_abs_value(object->config().layer_height.value)),
false);
}
@@ -135,10 +135,10 @@ Flow support_material_interface_flow(const PrintObject *object, float layer_heig
return Flow::new_from_config_width(
frSupportMaterialInterface,
// The width parameter accepted by new_from_config_width is of type ConfigOptionFloatOrPercent, the Flow class takes care of the percent to value substitution.
- (object->config.support_material_extrusion_width > 0) ? object->config.support_material_extrusion_width : object->config.extrusion_width,
- // if object->config.support_material_interface_extruder == 0 (which means to not trigger tool change, but use the current extruder instead), get_at will return the 0th component.
- float(object->print()->config.nozzle_diameter.get_at(object->config.support_material_interface_extruder-1)),
- (layer_height > 0.f) ? layer_height : float(object->config.layer_height.value),
+ (object->config().support_material_extrusion_width > 0) ? object->config().support_material_extrusion_width : object->config().extrusion_width,
+ // if object->config().support_material_interface_extruder == 0 (which means to not trigger tool change, but use the current extruder instead), get_at will return the 0th component.
+ float(object->print()->config().nozzle_diameter.get_at(object->config().support_material_interface_extruder-1)),
+ (layer_height > 0.f) ? layer_height : float(object->config().layer_height.value),
false);
}
diff --git a/xs/src/libslic3r/GCode.cpp b/xs/src/libslic3r/GCode.cpp
index 9c6143fd6..e55404845 100644
--- a/xs/src/libslic3r/GCode.cpp
+++ b/xs/src/libslic3r/GCode.cpp
@@ -275,15 +275,15 @@ std::string WipeTowerIntegration::finalize(GCode &gcodegen)
std::vector<GCode::LayerToPrint> GCode::collect_layers_to_print(const PrintObject &object)
{
std::vector<GCode::LayerToPrint> layers_to_print;
- layers_to_print.reserve(object.layers.size() + object.support_layers.size());
+ layers_to_print.reserve(object.layers().size() + object.support_layers().size());
// Pair the object layers with the support layers by z.
size_t idx_object_layer = 0;
size_t idx_support_layer = 0;
- while (idx_object_layer < object.layers.size() || idx_support_layer < object.support_layers.size()) {
+ while (idx_object_layer < object.layers().size() || idx_support_layer < object.support_layers().size()) {
LayerToPrint layer_to_print;
- layer_to_print.object_layer = (idx_object_layer < object.layers.size()) ? object.layers[idx_object_layer ++] : nullptr;
- layer_to_print.support_layer = (idx_support_layer < object.support_layers.size()) ? object.support_layers[idx_support_layer ++] : nullptr;
+ layer_to_print.object_layer = (idx_object_layer < object.layers().size()) ? object.layers()[idx_object_layer ++] : nullptr;
+ layer_to_print.support_layer = (idx_support_layer < object.support_layers().size()) ? object.support_layers()[idx_support_layer ++] : nullptr;
if (layer_to_print.object_layer && layer_to_print.support_layer) {
if (layer_to_print.object_layer->print_z < layer_to_print.support_layer->print_z - EPSILON) {
layer_to_print.support_layer = nullptr;
@@ -309,10 +309,10 @@ std::vector<std::pair<coordf_t, std::vector<GCode::LayerToPrint>>> GCode::collec
size_t object_idx;
size_t layer_idx;
};
- std::vector<std::vector<LayerToPrint>> per_object(print.objects.size(), std::vector<LayerToPrint>());
+ std::vector<std::vector<LayerToPrint>> per_object(print.objects().size(), std::vector<LayerToPrint>());
std::vector<OrderingItem> ordering;
- for (size_t i = 0; i < print.objects.size(); ++ i) {
- per_object[i] = collect_layers_to_print(*print.objects[i]);
+ for (size_t i = 0; i < print.objects().size(); ++ i) {
+ per_object[i] = collect_layers_to_print(*print.objects()[i]);
OrderingItem ordering_item;
ordering_item.object_idx = i;
ordering.reserve(ordering.size() + per_object[i].size());
@@ -337,7 +337,7 @@ std::vector<std::pair<coordf_t, std::vector<GCode::LayerToPrint>>> GCode::collec
std::pair<coordf_t, std::vector<LayerToPrint>> merged;
// Assign an average print_z to the set of layers with nearly equal print_z.
merged.first = 0.5 * (ordering[i].print_z + ordering[j-1].print_z);
- merged.second.assign(print.objects.size(), LayerToPrint());
+ merged.second.assign(print.objects().size(), LayerToPrint());
for (; i < j; ++ i) {
const OrderingItem &oi = ordering[i];
assert(merged.second[oi.object_idx].layer() == nullptr);
@@ -366,7 +366,7 @@ void GCode::do_export(Print *print, const char *path, GCodePreviewData *preview_
throw std::runtime_error(std::string("G-code export to ") + path + " failed.\nCannot open the file for writing.\n");
try {
- this->m_placeholder_parser_failed_templates.clear();
+ m_placeholder_parser_failed_templates.clear();
this->_do_export(*print, file, preview_data);
fflush(file);
if (ferror(file)) {
@@ -382,10 +382,10 @@ void GCode::do_export(Print *print, const char *path, GCodePreviewData *preview_
throw;
}
fclose(file);
- if (! this->m_placeholder_parser_failed_templates.empty()) {
+ if (! m_placeholder_parser_failed_templates.empty()) {
// G-code export proceeded, but some of the PlaceholderParser substitutions failed.
std::string msg = std::string("G-code export to ") + path + " failed due to invalid custom G-code sections:\n\n";
- for (const std::string &name : this->m_placeholder_parser_failed_templates)
+ for (const std::string &name : m_placeholder_parser_failed_templates)
msg += std::string("\t") + name + "\n";
msg += "\nPlease inspect the file ";
msg += path_tmp + " for error messages enclosed between\n";
@@ -415,7 +415,7 @@ void GCode::_do_export(Print &print, FILE *file, GCodePreviewData *preview_data)
// resets time estimator
m_time_estimator.reset();
- m_time_estimator.set_dialect(print.config.gcode_flavor);
+ m_time_estimator.set_dialect(print.config().gcode_flavor);
// resets analyzer
m_analyzer.reset();
@@ -429,14 +429,14 @@ void GCode::_do_export(Print &print, FILE *file, GCodePreviewData *preview_data)
// How many times will be change_layer() called?
// change_layer() in turn increments the progress bar status.
m_layer_count = 0;
- if (print.config.complete_objects.value) {
+ if (print.config().complete_objects.value) {
// Add each of the object's layers separately.
- for (auto object : print.objects) {
+ for (auto object : print.objects()) {
std::vector<coordf_t> zs;
- zs.reserve(object->layers.size() + object->support_layers.size());
- for (auto layer : object->layers)
+ zs.reserve(object->layers().size() + object->support_layers().size());
+ for (auto layer : object->layers())
zs.push_back(layer->print_z);
- for (auto layer : object->support_layers)
+ for (auto layer : object->support_layers())
zs.push_back(layer->print_z);
std::sort(zs.begin(), zs.end());
m_layer_count += (unsigned int)(object->copies().size() * (std::unique(zs.begin(), zs.end()) - zs.begin()));
@@ -444,11 +444,11 @@ void GCode::_do_export(Print &print, FILE *file, GCodePreviewData *preview_data)
} else {
// Print all objects with the same print_z together.
std::vector<coordf_t> zs;
- for (auto object : print.objects) {
- zs.reserve(zs.size() + object->layers.size() + object->support_layers.size());
- for (auto layer : object->layers)
+ for (auto object : print.objects()) {
+ zs.reserve(zs.size() + object->layers().size() + object->support_layers().size());
+ for (auto layer : object->layers())
zs.push_back(layer->print_z);
- for (auto layer : object->support_layers)
+ for (auto layer : object->support_layers())
zs.push_back(layer->print_z);
}
std::sort(zs.begin(), zs.end());
@@ -457,33 +457,33 @@ void GCode::_do_export(Print &print, FILE *file, GCodePreviewData *preview_data)
print.throw_if_canceled();
m_enable_cooling_markers = true;
- this->apply_print_config(print.config);
+ this->apply_print_config(print.config());
this->set_extruders(print.extruders());
// Initialize autospeed.
{
// get the minimum cross-section used in the print
std::vector<double> mm3_per_mm;
- for (auto object : print.objects) {
- for (size_t region_id = 0; region_id < print.regions.size(); ++ region_id) {
- auto region = print.regions[region_id];
- for (auto layer : object->layers) {
- auto layerm = layer->regions[region_id];
- if (region->config.get_abs_value("perimeter_speed" ) == 0 ||
- region->config.get_abs_value("small_perimeter_speed" ) == 0 ||
- region->config.get_abs_value("external_perimeter_speed" ) == 0 ||
- region->config.get_abs_value("bridge_speed" ) == 0)
+ for (auto object : print.objects()) {
+ for (size_t region_id = 0; region_id < print.regions().size(); ++ region_id) {
+ auto region = print.regions()[region_id];
+ for (auto layer : object->layers()) {
+ auto layerm = layer->regions()[region_id];
+ if (region->config().get_abs_value("perimeter_speed" ) == 0 ||
+ region->config().get_abs_value("small_perimeter_speed" ) == 0 ||
+ region->config().get_abs_value("external_perimeter_speed" ) == 0 ||
+ region->config().get_abs_value("bridge_speed" ) == 0)
mm3_per_mm.push_back(layerm->perimeters.min_mm3_per_mm());
- if (region->config.get_abs_value("infill_speed" ) == 0 ||
- region->config.get_abs_value("solid_infill_speed" ) == 0 ||
- region->config.get_abs_value("top_solid_infill_speed" ) == 0 ||
- region->config.get_abs_value("bridge_speed" ) == 0)
+ if (region->config().get_abs_value("infill_speed" ) == 0 ||
+ region->config().get_abs_value("solid_infill_speed" ) == 0 ||
+ region->config().get_abs_value("top_solid_infill_speed" ) == 0 ||
+ region->config().get_abs_value("bridge_speed" ) == 0)
mm3_per_mm.push_back(layerm->fills.min_mm3_per_mm());
}
}
- if (object->config.get_abs_value("support_material_speed" ) == 0 ||
- object->config.get_abs_value("support_material_interface_speed" ) == 0)
- for (auto layer : object->support_layers)
+ if (object->config().get_abs_value("support_material_speed" ) == 0 ||
+ object->config().get_abs_value("support_material_interface_speed" ) == 0)
+ for (auto layer : object->support_layers())
mm3_per_mm.push_back(layer->support_fills.min_mm3_per_mm());
}
print.throw_if_canceled();
@@ -495,20 +495,20 @@ void GCode::_do_export(Print &print, FILE *file, GCodePreviewData *preview_data)
// volumetric speed as the volumetric speed produced by printing the
// smallest cross-section at the maximum speed: any larger cross-section
// will need slower feedrates.
- m_volumetric_speed = *std::min_element(mm3_per_mm.begin(), mm3_per_mm.end()) * print.config.max_print_speed.value;
+ m_volumetric_speed = *std::min_element(mm3_per_mm.begin(), mm3_per_mm.end()) * print.config().max_print_speed.value;
// limit such volumetric speed with max_volumetric_speed if set
- if (print.config.max_volumetric_speed.value > 0)
- m_volumetric_speed = std::min(m_volumetric_speed, print.config.max_volumetric_speed.value);
+ if (print.config().max_volumetric_speed.value > 0)
+ m_volumetric_speed = std::min(m_volumetric_speed, print.config().max_volumetric_speed.value);
}
}
print.throw_if_canceled();
m_cooling_buffer = make_unique<CoolingBuffer>(*this);
- if (print.config.spiral_vase.value)
- m_spiral_vase = make_unique<SpiralVase>(print.config);
- if (print.config.max_volumetric_extrusion_rate_slope_positive.value > 0 ||
- print.config.max_volumetric_extrusion_rate_slope_negative.value > 0)
- m_pressure_equalizer = make_unique<PressureEqualizer>(&print.config);
+ if (print.config().spiral_vase.value)
+ m_spiral_vase = make_unique<SpiralVase>(print.config());
+ if (print.config().max_volumetric_extrusion_rate_slope_positive.value > 0 ||
+ print.config().max_volumetric_extrusion_rate_slope_negative.value > 0)
+ m_pressure_equalizer = make_unique<PressureEqualizer>(&print.config());
m_enable_extrusion_role_markers = (bool)m_pressure_equalizer;
// Write information on the generator.
@@ -516,7 +516,7 @@ void GCode::_do_export(Print &print, FILE *file, GCodePreviewData *preview_data)
// Write notes (content of the Print Settings tab -> Notes)
{
std::list<std::string> lines;
- boost::split(lines, print.config.notes.value, boost::is_any_of("\n"), boost::token_compress_off);
+ boost::split(lines, print.config().notes.value, boost::is_any_of("\n"), boost::token_compress_off);
for (auto line : lines) {
// Remove the trailing '\r' from the '\r\n' sequence.
if (! line.empty() && line.back() == '\r')
@@ -529,11 +529,11 @@ void GCode::_do_export(Print &print, FILE *file, GCodePreviewData *preview_data)
print.throw_if_canceled();
// Write some terse information on the slicing parameters.
- const PrintObject *first_object = print.objects.front();
- const double layer_height = first_object->config.layer_height.value;
- const double first_layer_height = first_object->config.first_layer_height.get_abs_value(layer_height);
- for (size_t region_id = 0; region_id < print.regions.size(); ++ region_id) {
- auto region = print.regions[region_id];
+ const PrintObject *first_object = print.objects().front();
+ const double layer_height = first_object->config().layer_height.value;
+ const double first_layer_height = first_object->config().first_layer_height.get_abs_value(layer_height);
+ for (size_t region_id = 0; region_id < print.regions().size(); ++ region_id) {
+ auto region = print.regions()[region_id];
_write_format(file, "; external perimeters extrusion width = %.2fmm\n", region->flow(frExternalPerimeter, layer_height, false, false, -1., *first_object).width);
_write_format(file, "; perimeters extrusion width = %.2fmm\n", region->flow(frPerimeter, layer_height, false, false, -1., *first_object).width);
_write_format(file, "; infill extrusion width = %.2fmm\n", region->flow(frInfill, layer_height, false, false, -1., *first_object).width);
@@ -541,14 +541,14 @@ void GCode::_do_export(Print &print, FILE *file, GCodePreviewData *preview_data)
_write_format(file, "; top infill extrusion width = %.2fmm\n", region->flow(frTopSolidInfill, layer_height, false, false, -1., *first_object).width);
if (print.has_support_material())
_write_format(file, "; support material extrusion width = %.2fmm\n", support_material_flow(first_object).width);
- if (print.config.first_layer_extrusion_width.value > 0)
+ if (print.config().first_layer_extrusion_width.value > 0)
_write_format(file, "; first layer extrusion width = %.2fmm\n", region->flow(frPerimeter, first_layer_height, false, true, -1., *first_object).width);
_write_format(file, "\n");
}
print.throw_if_canceled();
// Prepare the helper object for replacing placeholders in custom G-code and output filename.
- m_placeholder_parser = print.placeholder_parser;
+ m_placeholder_parser = print.placeholder_parser();
m_placeholder_parser.update_timestamp();
// Get optimal tool ordering to minimize tool switches of a multi-exruder print.
@@ -558,19 +558,19 @@ void GCode::_do_export(Print &print, FILE *file, GCodePreviewData *preview_data)
unsigned int final_extruder_id = (unsigned int)-1;
size_t initial_print_object_id = 0;
bool has_wipe_tower = false;
- if (print.config.complete_objects.value) {
+ if (print.config().complete_objects.value) {
// Find the 1st printing object, find its tool ordering and the initial extruder ID.
- for (; initial_print_object_id < print.objects.size(); ++initial_print_object_id) {
- tool_ordering = ToolOrdering(*print.objects[initial_print_object_id], initial_extruder_id);
+ for (; initial_print_object_id < print.objects().size(); ++initial_print_object_id) {
+ tool_ordering = ToolOrdering(*print.objects()[initial_print_object_id], initial_extruder_id);
if ((initial_extruder_id = tool_ordering.first_extruder()) != (unsigned int)-1)
break;
}
} else {
// Find tool ordering for all the objects at once, and the initial extruder ID.
// If the tool ordering has been pre-calculated by Print class for wipe tower already, reuse it.
- tool_ordering = print.m_tool_ordering.empty() ?
+ tool_ordering = print.wipe_tower_data().tool_ordering.empty() ?
ToolOrdering(print, initial_extruder_id) :
- print.m_tool_ordering;
+ print.wipe_tower_data().tool_ordering;
initial_extruder_id = tool_ordering.first_extruder();
has_wipe_tower = print.has_wipe_tower() && tool_ordering.has_wipe_tower();
}
@@ -587,7 +587,7 @@ void GCode::_do_export(Print &print, FILE *file, GCodePreviewData *preview_data)
m_cooling_buffer->set_current_extruder(initial_extruder_id);
// Disable fan.
- if (! print.config.cooling.get_at(initial_extruder_id) || print.config.disable_fan_first_layers.get_at(initial_extruder_id))
+ if (! print.config().cooling.get_at(initial_extruder_id) || print.config().disable_fan_first_layers.get_at(initial_extruder_id))
_write(file, m_writer.set_fan(0, true));
// Let the start-up script prime the 1st printing tool.
@@ -598,7 +598,7 @@ void GCode::_do_export(Print &print, FILE *file, GCodePreviewData *preview_data)
m_placeholder_parser.set("current_object_idx", 0);
// For the start / end G-code to do the priming and final filament pull in case there is no wipe tower provided.
m_placeholder_parser.set("has_wipe_tower", has_wipe_tower);
- std::string start_gcode = this->placeholder_parser_process("start_gcode", print.config.start_gcode.value, initial_extruder_id);
+ std::string start_gcode = this->placeholder_parser_process("start_gcode", print.config().start_gcode.value, initial_extruder_id);
// Set bed temperature if the start G-code does not contain any bed temp control G-codes.
this->_print_first_layer_bed_temperature(file, print, start_gcode, initial_extruder_id, true);
@@ -616,16 +616,16 @@ void GCode::_do_export(Print &print, FILE *file, GCodePreviewData *preview_data)
// Write the custom start G-code
_writeln(file, start_gcode);
// Process filament-specific gcode in extruder order.
- if (print.config.single_extruder_multi_material) {
+ if (print.config().single_extruder_multi_material) {
if (has_wipe_tower) {
// Wipe tower will control the extruder switching, it will call the start_filament_gcode.
} else {
// Only initialize the initial extruder.
- _writeln(file, this->placeholder_parser_process("start_filament_gcode", print.config.start_filament_gcode.values[initial_extruder_id], initial_extruder_id));
+ _writeln(file, this->placeholder_parser_process("start_filament_gcode", print.config().start_filament_gcode.values[initial_extruder_id], initial_extruder_id));
}
} else {
- for (const std::string &start_gcode : print.config.start_filament_gcode.values)
- _writeln(file, this->placeholder_parser_process("start_gcode", start_gcode, (unsigned int)(&start_gcode - &print.config.start_filament_gcode.values.front())));
+ for (const std::string &start_gcode : print.config().start_filament_gcode.values)
+ _writeln(file, this->placeholder_parser_process("start_gcode", start_gcode, (unsigned int)(&start_gcode - &print.config().start_filament_gcode.values.front())));
}
this->_print_first_layer_extruder_temperatures(file, print, start_gcode, initial_extruder_id, true);
print.throw_if_canceled();
@@ -634,12 +634,12 @@ void GCode::_do_export(Print &print, FILE *file, GCodePreviewData *preview_data)
_write(file, this->preamble());
// Initialize a motion planner for object-to-object travel moves.
- if (print.config.avoid_crossing_perimeters.value) {
+ if (print.config().avoid_crossing_perimeters.value) {
// Collect outer contours of all objects over all layers.
// Discard objects only containing thin walls (offset would fail on an empty polygon).
Polygons islands;
- for (const PrintObject *object : print.objects)
- for (const Layer *layer : object->layers)
+ for (const PrintObject *object : print.objects())
+ for (const Layer *layer : object->layers())
for (const ExPolygon &expoly : layer->slices.expolygons)
for (const Point &copy : object->_shifted_copies) {
islands.emplace_back(expoly.contour);
@@ -651,16 +651,16 @@ void GCode::_do_export(Print &print, FILE *file, GCodePreviewData *preview_data)
}
// Calculate wiping points if needed
- if (print.config.ooze_prevention.value && ! print.config.single_extruder_multi_material) {
+ if (print.config().ooze_prevention.value && ! print.config().single_extruder_multi_material) {
Points skirt_points;
- for (const ExtrusionEntity *ee : print.skirt.entities)
+ for (const ExtrusionEntity *ee : print.skirt().entities)
for (const ExtrusionPath &path : dynamic_cast<const ExtrusionLoop*>(ee)->paths)
append(skirt_points, path.polyline.points);
if (! skirt_points.empty()) {
Polygon outer_skirt = Slic3r::Geometry::convex_hull(skirt_points);
Polygons skirts;
for (unsigned int extruder_id : print.extruders()) {
- const Pointf &extruder_offset = print.config.extruder_offset.get_at(extruder_id);
+ const Pointf &extruder_offset = print.config().extruder_offset.get_at(extruder_id);
Polygon s(outer_skirt);
s.translate(-scale_(extruder_offset.x), -scale_(extruder_offset.y));
skirts.emplace_back(std::move(s));
@@ -685,10 +685,10 @@ void GCode::_do_export(Print &print, FILE *file, GCodePreviewData *preview_data)
_write(file, this->set_extruder(initial_extruder_id));
// Do all objects for each layer.
- if (print.config.complete_objects.value) {
+ if (print.config().complete_objects.value) {
// Print objects from the smallest to the tallest to avoid collisions
// when moving onto next object starting point.
- std::vector<PrintObject*> objects(print.objects);
+ std::vector<PrintObject*> objects(print.objects());
std::sort(objects.begin(), objects.end(), [](const PrintObject* po1, const PrintObject* po2) { return po1->size.z < po2->size.z; });
size_t finished_objects = 0;
for (size_t object_id = initial_print_object_id; object_id < objects.size(); ++ object_id) {
@@ -722,7 +722,7 @@ void GCode::_do_export(Print &print, FILE *file, GCodePreviewData *preview_data)
// another one, set first layer temperatures. This happens before the Z move
// is triggered, so machine has more time to reach such temperatures.
m_placeholder_parser.set("current_object_idx", int(finished_objects));
- std::string between_objects_gcode = this->placeholder_parser_process("between_objects_gcode", print.config.between_objects_gcode.value, initial_extruder_id);
+ std::string between_objects_gcode = this->placeholder_parser_process("between_objects_gcode", print.config().between_objects_gcode.value, initial_extruder_id);
// Set first layer bed and extruder temperatures, don't wait for it to reach the temperature.
this->_print_first_layer_bed_temperature(file, print, between_objects_gcode, initial_extruder_id, false);
this->_print_first_layer_extruder_temperatures(file, print, between_objects_gcode, initial_extruder_id, false);
@@ -751,7 +751,7 @@ void GCode::_do_export(Print &print, FILE *file, GCodePreviewData *preview_data)
// Order objects using a nearest neighbor search.
std::vector<size_t> object_indices;
Points object_reference_points;
- for (PrintObject *object : print.objects)
+ for (PrintObject *object : print.objects())
object_reference_points.push_back(object->_shifted_copies.front());
Slic3r::Geometry::chained_path(object_reference_points, object_indices);
// Sort layers by Z.
@@ -759,13 +759,13 @@ void GCode::_do_export(Print &print, FILE *file, GCodePreviewData *preview_data)
std::vector<std::pair<coordf_t, std::vector<LayerToPrint>>> layers_to_print = collect_layers_to_print(print);
// Prusa Multi-Material wipe tower.
if (has_wipe_tower && ! layers_to_print.empty()) {
- m_wipe_tower.reset(new WipeTowerIntegration(print.config, *print.m_wipe_tower_priming.get(), print.m_wipe_tower_tool_changes, *print.m_wipe_tower_final_purge.get()));
+ m_wipe_tower.reset(new WipeTowerIntegration(print.config(), *print.wipe_tower_data().priming.get(), print.wipe_tower_data().tool_changes, *print.wipe_tower_data().final_purge.get()));
_write(file, m_writer.travel_to_z(first_layer_height + m_config.z_offset.value, "Move to the first layer height"));
_write(file, m_wipe_tower->prime(*this));
// Verify, whether the print overaps the priming extrusions.
BoundingBoxf bbox_print(get_print_extrusions_extents(print));
coordf_t twolayers_printz = ((layers_to_print.size() == 1) ? layers_to_print.front() : layers_to_print[1]).first + EPSILON;
- for (const PrintObject *print_object : print.objects)
+ for (const PrintObject *print_object : print.objects())
bbox_print.merge(get_print_object_extrusions_extents(*print_object, twolayers_printz));
bbox_print.merge(get_wipe_tower_extrusions_extents(print, twolayers_printz));
BoundingBoxf bbox_prime(get_wipe_tower_priming_extrusions_extents(print));
@@ -813,14 +813,14 @@ void GCode::_do_export(Print &print, FILE *file, GCodePreviewData *preview_data)
}
// Process filament-specific gcode in extruder order.
- if (print.config.single_extruder_multi_material) {
+ if (print.config().single_extruder_multi_material) {
// Process the end_filament_gcode for the active filament only.
- _writeln(file, this->placeholder_parser_process("end_filament_gcode", print.config.end_filament_gcode.get_at(m_writer.extruder()->id()), m_writer.extruder()->id()));
+ _writeln(file, this->placeholder_parser_process("end_filament_gcode", print.config().end_filament_gcode.get_at(m_writer.extruder()->id()), m_writer.extruder()->id()));
} else {
- for (const std::string &end_gcode : print.config.end_filament_gcode.values)
- _writeln(file, this->placeholder_parser_process("end_filament_gcode", end_gcode, (unsigned int)(&end_gcode - &print.config.end_filament_gcode.values.front())));
+ for (const std::string &end_gcode : print.config().end_filament_gcode.values)
+ _writeln(file, this->placeholder_parser_process("end_filament_gcode", end_gcode, (unsigned int)(&end_gcode - &print.config().end_filament_gcode.values.front())));
}
- _writeln(file, this->placeholder_parser_process("end_gcode", print.config.end_gcode, m_writer.extruder()->id()));
+ _writeln(file, this->placeholder_parser_process("end_gcode", print.config().end_gcode, m_writer.extruder()->id()));
_write(file, m_writer.update_progress(m_layer_count, m_layer_count, true)); // 100%
_write(file, m_writer.postamble());
print.throw_if_canceled();
@@ -829,31 +829,27 @@ void GCode::_do_export(Print &print, FILE *file, GCodePreviewData *preview_data)
m_time_estimator.calculate_time();
// Get filament stats.
- print.filament_stats.clear();
- print.total_used_filament = 0.;
- print.total_extruded_volume = 0.;
- print.total_weight = 0.;
- print.total_cost = 0.;
- print.estimated_print_time = m_time_estimator.get_time_hms();
+ print.m_print_statistics.clear();
+ print.m_print_statistics.estimated_print_time = m_time_estimator.get_time_hms();
for (const Extruder &extruder : m_writer.extruders()) {
double used_filament = extruder.used_filament();
double extruded_volume = extruder.extruded_volume();
double filament_weight = extruded_volume * extruder.filament_density() * 0.001;
double filament_cost = filament_weight * extruder.filament_cost() * 0.001;
- print.filament_stats.insert(std::pair<size_t,float>(extruder.id(), used_filament));
+ print.m_print_statistics.filament_stats.insert(std::pair<size_t,float>(extruder.id(), used_filament));
_write_format(file, "; filament used = %.1lfmm (%.1lfcm3)\n", used_filament, extruded_volume * 0.001);
if (filament_weight > 0.) {
- print.total_weight = print.total_weight + filament_weight;
+ print.m_print_statistics.total_weight = print.m_print_statistics.total_weight + filament_weight;
_write_format(file, "; filament used = %.1lf\n", filament_weight);
if (filament_cost > 0.) {
- print.total_cost = print.total_cost + filament_cost;
+ print.m_print_statistics.total_cost = print.m_print_statistics.total_cost + filament_cost;
_write_format(file, "; filament cost = %.1lf\n", filament_cost);
}
}
- print.total_used_filament = print.total_used_filament + used_filament;
- print.total_extruded_volume = print.total_extruded_volume + extruded_volume;
+ print.m_print_statistics.total_used_filament = print.m_print_statistics.total_used_filament + used_filament;
+ print.m_print_statistics.total_extruded_volume = print.m_print_statistics.total_extruded_volume + extruded_volume;
}
- _write_format(file, "; total filament cost = %.1lf\n", print.total_cost);
+ _write_format(file, "; total filament cost = %.1lf\n", print.m_print_statistics.total_cost);
_write_format(file, "; estimated printing time = %s\n", m_time_estimator.get_time_hms().c_str());
// Append full config.
@@ -879,7 +875,7 @@ std::string GCode::placeholder_parser_process(const std::string &name, const std
return m_placeholder_parser.process(templ, current_extruder_id, config_override);
} catch (std::runtime_error &err) {
// Collect the names of failed template substitutions for error reporting.
- this->m_placeholder_parser_failed_templates.insert(name);
+ m_placeholder_parser_failed_templates.insert(name);
// Insert the macro error message into the G-code.
return
std::string("\n!!!!! Failed to process the custom G-code template ") + name + "\n" +
@@ -949,7 +945,7 @@ static bool custom_gcode_sets_temperature(const std::string &gcode, const int mc
void GCode::_print_first_layer_bed_temperature(FILE *file, Print &print, const std::string &gcode, unsigned int first_printing_extruder_id, bool wait)
{
// Initial bed temperature based on the first extruder.
- int temp = print.config.first_layer_bed_temperature.get_at(first_printing_extruder_id);
+ int temp = print.config().first_layer_bed_temperature.get_at(first_printing_extruder_id);
// Is the bed temperature set by the provided custom G-code?
int temp_by_gcode = -1;
bool temp_set_by_gcode = custom_gcode_sets_temperature(gcode, 140, 190, temp_by_gcode);
@@ -972,23 +968,23 @@ void GCode::_print_first_layer_extruder_temperatures(FILE *file, Print &print, c
int temp_by_gcode = -1;
if (custom_gcode_sets_temperature(gcode, 104, 109, temp_by_gcode)) {
// Set the extruder temperature at m_writer, but throw away the generated G-code as it will be written with the custom G-code.
- int temp = print.config.first_layer_temperature.get_at(first_printing_extruder_id);
+ int temp = print.config().first_layer_temperature.get_at(first_printing_extruder_id);
if (temp_by_gcode >= 0 && temp_by_gcode < 1000)
temp = temp_by_gcode;
m_writer.set_temperature(temp_by_gcode, wait, first_printing_extruder_id);
} else {
// Custom G-code does not set the extruder temperature. Do it now.
- if (print.config.single_extruder_multi_material.value) {
+ if (print.config().single_extruder_multi_material.value) {
// Set temperature of the first printing extruder only.
- int temp = print.config.first_layer_temperature.get_at(first_printing_extruder_id);
+ int temp = print.config().first_layer_temperature.get_at(first_printing_extruder_id);
if (temp > 0)
_write(file, m_writer.set_temperature(temp, wait, first_printing_extruder_id));
} else {
// Set temperatures of all the printing extruders.
for (unsigned int tool_id : print.extruders()) {
- int temp = print.config.first_layer_temperature.get_at(tool_id);
- if (print.config.ooze_prevention.value)
- temp += print.config.standby_temperature_delta.value;
+ int temp = print.config().first_layer_temperature.get_at(tool_id);
+ if (print.config().ooze_prevention.value)
+ temp += print.config().standby_temperature_delta.value;
if (temp > 0)
_write(file, m_writer.set_temperature(temp, wait, tool_id));
}
@@ -1061,15 +1057,15 @@ void GCode::process_layer(
unsigned int first_extruder_id = layer_tools.extruders.front();
// Initialize config with the 1st object to be printed at this layer.
- m_config.apply(layer.object()->config, true);
+ m_config.apply(layer.object()->config(), true);
// Check whether it is possible to apply the spiral vase logic for this layer.
// Just a reminder: A spiral vase mode is allowed for a single object, single material print only.
if (m_spiral_vase && layers.size() == 1 && support_layer == nullptr) {
- bool enable = (layer.id() > 0 || print.config.brim_width.value == 0.) && (layer.id() >= print.config.skirt_height.value && ! print.has_infinite_skirt());
+ bool enable = (layer.id() > 0 || print.config().brim_width.value == 0.) && (layer.id() >= print.config().skirt_height.value && ! print.has_infinite_skirt());
if (enable) {
- for (const LayerRegion *layer_region : layer.regions)
- if (layer_region->region()->config.bottom_solid_layers.value > layer.id() ||
+ for (const LayerRegion *layer_region : layer.regions())
+ if (layer_region->region()->config().bottom_solid_layers.value > layer.id() ||
layer_region->perimeters.items_count() > 1 ||
layer_region->fills.items_count() > 0) {
enable = false;
@@ -1084,22 +1080,22 @@ void GCode::process_layer(
std::string gcode;
// Set new layer - this will change Z and force a retraction if retract_layer_change is enabled.
- if (! print.config.before_layer_gcode.value.empty()) {
+ if (! print.config().before_layer_gcode.value.empty()) {
DynamicConfig config;
config.set_key_value("layer_num", new ConfigOptionInt(m_layer_index + 1));
config.set_key_value("layer_z", new ConfigOptionFloat(print_z));
gcode += this->placeholder_parser_process("before_layer_gcode",
- print.config.before_layer_gcode.value, m_writer.extruder()->id(), &config)
+ print.config().before_layer_gcode.value, m_writer.extruder()->id(), &config)
+ "\n";
}
gcode += this->change_layer(print_z); // this will increase m_layer_index
m_layer = &layer;
- if (! print.config.layer_gcode.value.empty()) {
+ if (! print.config().layer_gcode.value.empty()) {
DynamicConfig config;
config.set_key_value("layer_num", new ConfigOptionInt(m_layer_index));
config.set_key_value("layer_z", new ConfigOptionFloat(print_z));
gcode += this->placeholder_parser_process("layer_gcode",
- print.config.layer_gcode.value, m_writer.extruder()->id(), &config)
+ print.config().layer_gcode.value, m_writer.extruder()->id(), &config)
+ "\n";
}
@@ -1107,14 +1103,14 @@ void GCode::process_layer(
// Transition from 1st to 2nd layer. Adjust nozzle temperatures as prescribed by the nozzle dependent
// first_layer_temperature vs. temperature settings.
for (const Extruder &extruder : m_writer.extruders()) {
- if (print.config.single_extruder_multi_material.value && extruder.id() != m_writer.extruder()->id())
+ if (print.config().single_extruder_multi_material.value && extruder.id() != m_writer.extruder()->id())
// In single extruder multi material mode, set the temperature for the current extruder only.
continue;
- int temperature = print.config.temperature.get_at(extruder.id());
- if (temperature > 0 && temperature != print.config.first_layer_temperature.get_at(extruder.id()))
+ int temperature = print.config().temperature.get_at(extruder.id());
+ if (temperature > 0 && temperature != print.config().first_layer_temperature.get_at(extruder.id()))
gcode += m_writer.set_temperature(temperature, false, extruder.id());
}
- gcode += m_writer.set_bed_temperature(print.config.bed_temperature.get_at(first_extruder_id));
+ gcode += m_writer.set_bed_temperature(print.config().bed_temperature.get_at(first_extruder_id));
// Mark the temperature transition from 1st to 2nd layer to be finished.
m_second_layer_things_done = true;
}
@@ -1122,9 +1118,9 @@ void GCode::process_layer(
// Extrude skirt at the print_z of the raft layers and normal object layers
// not at the print_z of the interlaced support material layers.
bool extrude_skirt =
- ! print.skirt.entities.empty() &&
+ ! print.skirt().entities.empty() &&
// Not enough skirt layers printed yet.
- (m_skirt_done.size() < print.config.skirt_height.value || print.has_infinite_skirt()) &&
+ (m_skirt_done.size() < print.config().skirt_height.value || print.has_infinite_skirt()) &&
// This print_z has not been extruded yet
(m_skirt_done.empty() ? 0. : m_skirt_done.back()) < print_z - EPSILON &&
// and this layer is the 1st layer, or it is an object layer, or it is a raft layer.
@@ -1146,7 +1142,7 @@ void GCode::process_layer(
extruder_ids.front() = first_extruder_id;
break;
}
- size_t n_loops = print.skirt.entities.size();
+ size_t n_loops = print.skirt().entities.size();
if (n_loops <= extruder_ids.size()) {
for (size_t i = 0; i < n_loops; ++i)
skirt_loops_per_extruder[extruder_ids[i]] = std::pair<size_t, size_t>(i, i + 1);
@@ -1165,7 +1161,7 @@ void GCode::process_layer(
}
} else
// Extrude all skirts with the current extruder.
- skirt_loops_per_extruder[first_extruder_id] = std::pair<size_t, size_t>(0, print.config.skirts.value);
+ skirt_loops_per_extruder[first_extruder_id] = std::pair<size_t, size_t>(0, print.config().skirts.value);
}
// Group extrusions by an extruder, then by an object, an island and a region.
@@ -1180,22 +1176,22 @@ void GCode::process_layer(
bool has_support = role == erMixed || role == erSupportMaterial;
bool has_interface = role == erMixed || role == erSupportMaterialInterface;
// Extruder ID of the support base. -1 if "don't care".
- unsigned int support_extruder = object.config.support_material_extruder.value - 1;
+ unsigned int support_extruder = object.config().support_material_extruder.value - 1;
// Shall the support be printed with the active extruder, preferably with non-soluble, to avoid tool changes?
- bool support_dontcare = object.config.support_material_extruder.value == 0;
+ bool support_dontcare = object.config().support_material_extruder.value == 0;
// Extruder ID of the support interface. -1 if "don't care".
- unsigned int interface_extruder = object.config.support_material_interface_extruder.value - 1;
+ unsigned int interface_extruder = object.config().support_material_interface_extruder.value - 1;
// Shall the support interface be printed with the active extruder, preferably with non-soluble, to avoid tool changes?
- bool interface_dontcare = object.config.support_material_interface_extruder.value == 0;
+ bool interface_dontcare = object.config().support_material_interface_extruder.value == 0;
if (support_dontcare || interface_dontcare) {
// Some support will be printed with "don't care" material, preferably non-soluble.
// Is the current extruder assigned a soluble filament?
unsigned int dontcare_extruder = first_extruder_id;
- if (print.config.filament_soluble.get_at(dontcare_extruder)) {
+ if (print.config().filament_soluble.get_at(dontcare_extruder)) {
// The last extruder printed on the previous layer extrudes soluble filament.
// Try to find a non-soluble extruder on the same layer.
for (unsigned int extruder_id : layer_tools.extruders)
- if (! print.config.filament_soluble.get_at(extruder_id)) {
+ if (! print.config().filament_soluble.get_at(extruder_id)) {
dontcare_extruder = extruder_id;
break;
}
@@ -1242,11 +1238,11 @@ void GCode::process_layer(
layer.slices.expolygons[i].contour.contains(point);
};
- for (size_t region_id = 0; region_id < print.regions.size(); ++ region_id) {
- const LayerRegion *layerm = layer.regions[region_id];
+ for (size_t region_id = 0; region_id < print.regions().size(); ++ region_id) {
+ const LayerRegion *layerm = layer.regions()[region_id];
if (layerm == nullptr)
continue;
- const PrintRegion &region = *print.regions[region_id];
+ const PrintRegion &region = *print.regions()[region_id];
// process perimeters
for (const ExtrusionEntity *ee : layerm->perimeters.entities) {
@@ -1258,7 +1254,7 @@ void GCode::process_layer(
// Init by_extruder item only if we actually use the extruder.
std::vector<ObjectByExtruder::Island> &islands = object_islands_by_extruder(
by_extruder,
- std::max<int>(region.config.perimeter_extruder.value - 1, 0),
+ std::max<int>(region.config().perimeter_extruder.value - 1, 0),
&layer_to_print - layers.data(),
layers.size(), n_slices+1);
for (size_t i = 0; i <= n_slices; ++ i)
@@ -1267,7 +1263,7 @@ void GCode::process_layer(
// perimeter_coll->first_point fits inside ith slice
point_inside_surface(i, perimeter_coll->first_point())) {
if (islands[i].by_region.empty())
- islands[i].by_region.assign(print.regions.size(), ObjectByExtruder::Island::Region());
+ islands[i].by_region.assign(print.regions().size(), ObjectByExtruder::Island::Region());
islands[i].by_region[region_id].perimeters.append(perimeter_coll->entities);
break;
}
@@ -1285,7 +1281,7 @@ void GCode::process_layer(
// This shouldn't happen but first_point() would fail.
continue;
// init by_extruder item only if we actually use the extruder
- int extruder_id = std::max<int>(0, (is_solid_infill(fill->entities.front()->role()) ? region.config.solid_infill_extruder : region.config.infill_extruder) - 1);
+ int extruder_id = std::max<int>(0, (is_solid_infill(fill->entities.front()->role()) ? region.config().solid_infill_extruder : region.config().infill_extruder) - 1);
// Init by_extruder item only if we actually use the extruder.
std::vector<ObjectByExtruder::Island> &islands = object_islands_by_extruder(
by_extruder,
@@ -1298,7 +1294,7 @@ void GCode::process_layer(
// fill->first_point fits inside ith slice
point_inside_surface(i, fill->first_point())) {
if (islands[i].by_region.empty())
- islands[i].by_region.assign(print.regions.size(), ObjectByExtruder::Island::Region());
+ islands[i].by_region.assign(print.regions().size(), ObjectByExtruder::Island::Region());
islands[i].by_region[region_id].infills.append(fill->entities);
break;
}
@@ -1324,7 +1320,7 @@ void GCode::process_layer(
Flow skirt_flow = print.skirt_flow();
for (size_t i = loops.first; i < loops.second; ++ i) {
// Adjust flow according to this layer's layer height.
- ExtrusionLoop loop = *dynamic_cast<const ExtrusionLoop*>(print.skirt.entities[i]);
+ ExtrusionLoop loop = *dynamic_cast<const ExtrusionLoop*>(print.skirt().entities[i]);
Flow layer_skirt_flow(skirt_flow);
layer_skirt_flow.height = (float)skirt_height;
double mm3_per_mm = layer_skirt_flow.mm3_per_mm();
@@ -1345,7 +1341,7 @@ void GCode::process_layer(
if (! m_brim_done) {
this->set_origin(0., 0.);
m_avoid_crossing_perimeters.use_external_mp = true;
- for (const ExtrusionEntity *ee : print.brim.entities)
+ for (const ExtrusionEntity *ee : print.brim().entities)
gcode += this->extrude_loop(*dynamic_cast<const ExtrusionLoop*>(ee), "brim", m_config.support_material_speed.value);
m_brim_done = true;
m_avoid_crossing_perimeters.use_external_mp = false;
@@ -1363,7 +1359,7 @@ void GCode::process_layer(
// This layer is empty for this particular object, it has neither object extrusions nor support extrusions at this print_z.
continue;
- m_config.apply(print_object->config, true);
+ m_config.apply(print_object->config(), true);
m_layer = layers[layer_id].layer();
if (m_config.avoid_crossing_perimeters)
m_avoid_crossing_perimeters.init_layer_mp(union_ex(m_layer->slices, true));
@@ -1389,7 +1385,7 @@ void GCode::process_layer(
m_layer = layers[layer_id].layer();
}
for (const ObjectByExtruder::Island &island : object_by_extruder.islands) {
- if (print.config.infill_first) {
+ if (print.config().infill_first) {
gcode += this->extrude_infill(print, island.by_region);
gcode += this->extrude_perimeters(print, island.by_region, lower_layer_edge_grids[layer_id]);
} else {
@@ -1430,7 +1426,7 @@ void GCode::apply_print_config(const PrintConfig &print_config)
void GCode::append_full_config(const Print& print, std::string& str)
{
- const StaticPrintConfig *configs[] = { &print.config, &print.default_object_config, &print.default_region_config };
+ const StaticPrintConfig *configs[] = { &print.config(), &print.default_object_config(), &print.default_region_config() };
for (size_t i = 0; i < sizeof(configs) / sizeof(configs[0]); ++i) {
const StaticPrintConfig *cfg = configs[i];
for (const std::string &key : cfg->keys())
@@ -2015,7 +2011,7 @@ std::string GCode::extrude_perimeters(const Print &print, const std::vector<Obje
{
std::string gcode;
for (const ObjectByExtruder::Island::Region &region : by_region) {
- m_config.apply(print.regions[&region - &by_region.front()]->config);
+ m_config.apply(print.regions()[&region - &by_region.front()]->config());
for (ExtrusionEntity *ee : region.perimeters.entities)
gcode += this->extrude_entity(*ee, "perimeter", -1., &lower_layer_edge_grid);
}
@@ -2027,7 +2023,7 @@ std::string GCode::extrude_infill(const Print &print, const std::vector<ObjectBy
{
std::string gcode;
for (const ObjectByExtruder::Island::Region &region : by_region) {
- m_config.apply(print.regions[&region - &by_region.front()]->config);
+ m_config.apply(print.regions()[&region - &by_region.front()]->config());
ExtrusionEntityCollection chained = region.infills.chained_path_from(m_last_pos, false);
for (ExtrusionEntity *fill : chained.entities) {
auto *eec = dynamic_cast<ExtrusionEntityCollection*>(fill);
diff --git a/xs/src/libslic3r/GCode/PrintExtents.cpp b/xs/src/libslic3r/GCode/PrintExtents.cpp
index 3c3f0f8d5..43352ee82 100644
--- a/xs/src/libslic3r/GCode/PrintExtents.cpp
+++ b/xs/src/libslic3r/GCode/PrintExtents.cpp
@@ -99,19 +99,19 @@ static BoundingBoxf extrusionentity_extents(const ExtrusionEntity *extrusion_ent
BoundingBoxf get_print_extrusions_extents(const Print &print)
{
- BoundingBoxf bbox(extrusionentity_extents(print.brim));
- bbox.merge(extrusionentity_extents(print.skirt));
+ BoundingBoxf bbox(extrusionentity_extents(print.brim()));
+ bbox.merge(extrusionentity_extents(print.skirt()));
return bbox;
}
BoundingBoxf get_print_object_extrusions_extents(const PrintObject &print_object, const coordf_t max_print_z)
{
BoundingBoxf bbox;
- for (const Layer *layer : print_object.layers) {
+ for (const Layer *layer : print_object.layers()) {
if (layer->print_z > max_print_z)
break;
BoundingBoxf bbox_this;
- for (const LayerRegion *layerm : layer->regions) {
+ for (const LayerRegion *layerm : layer->regions()) {
bbox_this.merge(extrusionentity_extents(layerm->perimeters));
for (const ExtrusionEntity *ee : layerm->fills.entities)
// fill represents infill extrusions of a single island.
@@ -135,7 +135,7 @@ BoundingBoxf get_print_object_extrusions_extents(const PrintObject &print_object
BoundingBoxf get_wipe_tower_extrusions_extents(const Print &print, const coordf_t max_print_z)
{
BoundingBoxf bbox;
- for (const std::vector<WipeTower::ToolChangeResult> &tool_changes : print.m_wipe_tower_tool_changes) {
+ for (const std::vector<WipeTower::ToolChangeResult> &tool_changes : print.wipe_tower_data().tool_changes) {
if (! tool_changes.empty() && tool_changes.front().print_z > max_print_z)
break;
for (const WipeTower::ToolChangeResult &tcr : tool_changes) {
@@ -161,8 +161,8 @@ BoundingBoxf get_wipe_tower_extrusions_extents(const Print &print, const coordf_
BoundingBoxf get_wipe_tower_priming_extrusions_extents(const Print &print)
{
BoundingBoxf bbox;
- if (print.m_wipe_tower_priming) {
- const WipeTower::ToolChangeResult &tcr = *print.m_wipe_tower_priming.get();
+ if (print.wipe_tower_data().priming != nullptr) {
+ const WipeTower::ToolChangeResult &tcr = *print.wipe_tower_data().priming;
for (size_t i = 1; i < tcr.extrusions.size(); ++ i) {
const WipeTower::Extrusion &e = tcr.extrusions[i];
if (e.width > 0) {
diff --git a/xs/src/libslic3r/GCode/ToolOrdering.cpp b/xs/src/libslic3r/GCode/ToolOrdering.cpp
index 271b75ef3..6e03d89c9 100644
--- a/xs/src/libslic3r/GCode/ToolOrdering.cpp
+++ b/xs/src/libslic3r/GCode/ToolOrdering.cpp
@@ -16,19 +16,19 @@
namespace Slic3r {
// For the use case when each object is printed separately
-// (print.config.complete_objects is true).
+// (print.config().complete_objects is true).
ToolOrdering::ToolOrdering(const PrintObject &object, unsigned int first_extruder, bool prime_multi_material)
{
- if (object.layers.empty())
+ if (object.layers().empty())
return;
// Initialize the print layers for just a single object.
{
std::vector<coordf_t> zs;
- zs.reserve(zs.size() + object.layers.size() + object.support_layers.size());
- for (auto layer : object.layers)
+ zs.reserve(zs.size() + object.layers().size() + object.support_layers().size());
+ for (auto layer : object.layers())
zs.emplace_back(layer->print_z);
- for (auto layer : object.support_layers)
+ for (auto layer : object.support_layers())
zs.emplace_back(layer->print_z);
this->initialize_layers(zs);
}
@@ -39,39 +39,39 @@ ToolOrdering::ToolOrdering(const PrintObject &object, unsigned int first_extrude
// Reorder the extruders to minimize tool switches.
this->reorder_extruders(first_extruder);
- this->fill_wipe_tower_partitions(object.print()->config, object.layers.front()->print_z - object.layers.front()->height);
+ this->fill_wipe_tower_partitions(object.print()->config(), object.layers().front()->print_z - object.layers().front()->height);
this->collect_extruder_statistics(prime_multi_material);
}
// For the use case when all objects are printed at once.
-// (print.config.complete_objects is false).
+// (print.config().complete_objects is false).
ToolOrdering::ToolOrdering(const Print &print, unsigned int first_extruder, bool prime_multi_material)
{
// Initialize the print layers for all objects and all layers.
coordf_t object_bottom_z = 0.;
{
std::vector<coordf_t> zs;
- for (auto object : print.objects) {
- zs.reserve(zs.size() + object->layers.size() + object->support_layers.size());
- for (auto layer : object->layers)
+ for (auto object : print.objects()) {
+ zs.reserve(zs.size() + object->layers().size() + object->support_layers().size());
+ for (auto layer : object->layers())
zs.emplace_back(layer->print_z);
- for (auto layer : object->support_layers)
+ for (auto layer : object->support_layers())
zs.emplace_back(layer->print_z);
- if (! object->layers.empty())
- object_bottom_z = object->layers.front()->print_z - object->layers.front()->height;
+ if (! object->layers().empty())
+ object_bottom_z = object->layers().front()->print_z - object->layers().front()->height;
}
this->initialize_layers(zs);
}
// Collect extruders reuqired to print the layers.
- for (auto object : print.objects)
+ for (auto object : print.objects())
this->collect_extruders(*object);
// Reorder the extruders to minimize tool switches.
this->reorder_extruders(first_extruder);
- this->fill_wipe_tower_partitions(print.config, object_bottom_z);
+ this->fill_wipe_tower_partitions(print.config(), object_bottom_z);
this->collect_extruder_statistics(prime_multi_material);
}
@@ -111,13 +111,13 @@ void ToolOrdering::initialize_layers(std::vector<coordf_t> &zs)
void ToolOrdering::collect_extruders(const PrintObject &object)
{
// Collect the support extruders.
- for (auto support_layer : object.support_layers) {
+ for (auto support_layer : object.support_layers()) {
LayerTools &layer_tools = this->tools_for_layer(support_layer->print_z);
ExtrusionRole role = support_layer->support_fills.role();
bool has_support = role == erMixed || role == erSupportMaterial;
bool has_interface = role == erMixed || role == erSupportMaterialInterface;
- unsigned int extruder_support = object.config.support_material_extruder.value;
- unsigned int extruder_interface = object.config.support_material_interface_extruder.value;
+ unsigned int extruder_support = object.config().support_material_extruder.value;
+ unsigned int extruder_interface = object.config().support_material_interface_extruder.value;
if (has_support)
layer_tools.extruders.push_back(extruder_support);
if (has_interface)
@@ -126,16 +126,16 @@ void ToolOrdering::collect_extruders(const PrintObject &object)
layer_tools.has_support = true;
}
// Collect the object extruders.
- for (auto layer : object.layers) {
+ for (auto layer : object.layers()) {
LayerTools &layer_tools = this->tools_for_layer(layer->print_z);
// What extruders are required to print this object layer?
- for (size_t region_id = 0; region_id < object.print()->regions.size(); ++ region_id) {
- const LayerRegion *layerm = (region_id < layer->regions.size()) ? layer->regions[region_id] : nullptr;
+ for (size_t region_id = 0; region_id < object.print()->regions().size(); ++ region_id) {
+ const LayerRegion *layerm = (region_id < layer->regions().size()) ? layer->regions()[region_id] : nullptr;
if (layerm == nullptr)
continue;
- const PrintRegion &region = *object.print()->regions[region_id];
+ const PrintRegion &region = *object.print()->regions()[region_id];
if (! layerm->perimeters.entities.empty()) {
- layer_tools.extruders.push_back(region.config.perimeter_extruder.value);
+ layer_tools.extruders.push_back(region.config().perimeter_extruder.value);
layer_tools.has_object = true;
}
bool has_infill = false;
@@ -150,9 +150,9 @@ void ToolOrdering::collect_extruders(const PrintObject &object)
has_infill = true;
}
if (has_solid_infill)
- layer_tools.extruders.push_back(region.config.solid_infill_extruder);
+ layer_tools.extruders.push_back(region.config().solid_infill_extruder);
if (has_infill)
- layer_tools.extruders.push_back(region.config.infill_extruder);
+ layer_tools.extruders.push_back(region.config().infill_extruder);
if (has_solid_infill || has_infill)
layer_tools.has_object = true;
}
diff --git a/xs/src/libslic3r/GCode/WipeTowerPrusaMM.cpp b/xs/src/libslic3r/GCode/WipeTowerPrusaMM.cpp
index 99c6c757f..069f975dd 100644
--- a/xs/src/libslic3r/GCode/WipeTowerPrusaMM.cpp
+++ b/xs/src/libslic3r/GCode/WipeTowerPrusaMM.cpp
@@ -396,8 +396,8 @@ WipeTower::ToolChangeResult WipeTowerPrusaMM::prime(
}
this->set_layer(first_layer_height, first_layer_height, tools.size(), true, false);
- this->m_num_layer_changes = 0;
- this->m_current_tool = tools.front();
+ m_num_layer_changes = 0;
+ m_current_tool = tools.front();
// The Prusa i3 MK2 has a working space of [0, -2.2] to [250, 210].
// Due to the XYZ calibration, this working space may shrink slightly from all directions,
@@ -439,9 +439,9 @@ WipeTower::ToolChangeResult WipeTowerPrusaMM::prime(
if (last_wipe_inside_wipe_tower) {
// Shrink the last wipe area to the area of the other purge areas,
// remember the last initial wipe width to be purged into the 1st layer of the wipe tower.
- this->m_initial_extra_wipe = std::max(0.f, wipe_area - (y_end + 0.5f * 0.85f * m_perimeter_width - cleaning_box.ld.y));
- cleaning_box.lu.y -= this->m_initial_extra_wipe;
- cleaning_box.ru.y -= this->m_initial_extra_wipe;
+ m_initial_extra_wipe = std::max(0.f, wipe_area - (y_end + 0.5f * 0.85f * m_perimeter_width - cleaning_box.ld.y));
+ cleaning_box.lu.y -= m_initial_extra_wipe;
+ cleaning_box.ru.y -= m_initial_extra_wipe;
}
toolchange_Wipe(writer, cleaning_box, false);
} else {
@@ -471,8 +471,8 @@ WipeTower::ToolChangeResult WipeTowerPrusaMM::prime(
m_idx_tool_change_in_layer = (unsigned int)(-1);
ToolChangeResult result;
- result.print_z = this->m_z_pos;
- result.layer_height = this->m_layer_height;
+ result.print_z = m_z_pos;
+ result.layer_height = m_layer_height;
result.gcode = writer.gcode();
result.elapsed_time = writer.elapsed_time();
result.extrusions = writer.extrusions();
@@ -612,8 +612,8 @@ WipeTower::ToolChangeResult WipeTowerPrusaMM::tool_change(unsigned int tool, boo
}
ToolChangeResult result;
- result.print_z = this->m_z_pos;
- result.layer_height = this->m_layer_height;
+ result.print_z = m_z_pos;
+ result.layer_height = m_layer_height;
result.gcode = writer.gcode();
result.elapsed_time = writer.elapsed_time();
result.extrusions = writer.extrusions();
@@ -718,8 +718,8 @@ WipeTower::ToolChangeResult WipeTowerPrusaMM::toolchange_Brim(Purpose purpose, b
}
ToolChangeResult result;
- result.print_z = this->m_z_pos;
- result.layer_height = this->m_layer_height;
+ result.print_z = m_z_pos;
+ result.layer_height = m_layer_height;
result.gcode = writer.gcode();
result.elapsed_time = writer.elapsed_time();
result.extrusions = writer.extrusions();
@@ -1040,8 +1040,8 @@ WipeTower::ToolChangeResult WipeTowerPrusaMM::finish_layer(Purpose purpose)
}
ToolChangeResult result;
- result.print_z = this->m_z_pos;
- result.layer_height = this->m_layer_height;
+ result.print_z = m_z_pos;
+ result.layer_height = m_layer_height;
result.gcode = writer.gcode();
result.elapsed_time = writer.elapsed_time();
result.extrusions = writer.extrusions();
diff --git a/xs/src/libslic3r/Layer.cpp b/xs/src/libslic3r/Layer.cpp
index 3dc2335d7..72ac371a2 100644
--- a/xs/src/libslic3r/Layer.cpp
+++ b/xs/src/libslic3r/Layer.cpp
@@ -12,24 +12,24 @@ namespace Slic3r {
Layer::~Layer()
{
this->lower_layer = this->upper_layer = nullptr;
- for (LayerRegion *region : this->regions)
+ for (LayerRegion *region : m_regions)
delete region;
- this->regions.clear();
+ m_regions.clear();
}
LayerRegion* Layer::add_region(PrintRegion* print_region)
{
- this->regions.emplace_back(new LayerRegion(this, print_region));
- return this->regions.back();
+ m_regions.emplace_back(new LayerRegion(this, print_region));
+ return m_regions.back();
}
// merge all regions' slices to get islands
void Layer::make_slices()
{
ExPolygons slices;
- if (this->regions.size() == 1) {
+ if (m_regions.size() == 1) {
// optimization: if we only have one region, take its slices
- slices = this->regions.front()->slices;
+ slices = m_regions.front()->slices;
} else {
Polygons slices_p;
FOREACH_LAYERREGION(this, layerm) {
@@ -58,10 +58,10 @@ void Layer::make_slices()
void Layer::merge_slices()
{
- if (this->regions.size() == 1) {
+ if (m_regions.size() == 1) {
// Optimization, also more robust. Don't merge classified pieces of layerm->slices,
// but use the non-split islands of a layer. For a single region print, these shall be equal.
- this->regions.front()->slices.set(this->slices.expolygons, stInternal);
+ m_regions.front()->slices.set(this->slices.expolygons, stInternal);
} else {
FOREACH_LAYERREGION(this, layerm) {
// without safety offset, artifacts are generated (GH #2494)
@@ -81,18 +81,18 @@ void Layer::make_perimeters()
std::set<size_t> done;
FOREACH_LAYERREGION(this, layerm) {
- size_t region_id = layerm - this->regions.begin();
+ size_t region_id = layerm - m_regions.begin();
if (done.find(region_id) != done.end()) continue;
BOOST_LOG_TRIVIAL(trace) << "Generating perimeters for layer " << this->id() << ", region " << region_id;
done.insert(region_id);
- const PrintRegionConfig &config = (*layerm)->region()->config;
+ const PrintRegionConfig &config = (*layerm)->region()->config();
// find compatible regions
LayerRegionPtrs layerms;
layerms.push_back(*layerm);
- for (LayerRegionPtrs::const_iterator it = layerm + 1; it != this->regions.end(); ++it) {
+ for (LayerRegionPtrs::const_iterator it = layerm + 1; it != m_regions.end(); ++it) {
LayerRegion* other_layerm = *it;
- const PrintRegionConfig &other_config = other_layerm->region()->config;
+ const PrintRegionConfig &other_config = other_layerm->region()->config();
if (config.perimeter_extruder == other_config.perimeter_extruder
&& config.perimeters == other_config.perimeters
@@ -104,7 +104,7 @@ void Layer::make_perimeters()
&& config.thin_walls == other_config.thin_walls
&& config.external_perimeters_first == other_config.external_perimeters_first) {
layerms.push_back(other_layerm);
- done.insert(it - this->regions.begin());
+ done.insert(it - m_regions.begin());
}
}
@@ -150,7 +150,7 @@ void Layer::make_fills()
#ifdef SLIC3R_DEBUG
printf("Making fills for layer " PRINTF_ZU "\n", this->id());
#endif
- for (LayerRegion *layerm : regions) {
+ for (LayerRegion *layerm : m_regions) {
layerm->fills.clear();
make_fill(*layerm, layerm->fills);
#ifndef NDEBUG
@@ -163,18 +163,18 @@ void Layer::make_fills()
void Layer::export_region_slices_to_svg(const char *path) const
{
BoundingBox bbox;
- for (LayerRegionPtrs::const_iterator region = this->regions.begin(); region != this->regions.end(); ++region)
- for (Surfaces::const_iterator surface = (*region)->slices.surfaces.begin(); surface != (*region)->slices.surfaces.end(); ++surface)
- bbox.merge(get_extents(surface->expolygon));
+ for (const auto *region : m_regions)
+ for (const auto &surface : region->slices.surfaces)
+ bbox.merge(get_extents(surface.expolygon));
Point legend_size = export_surface_type_legend_to_svg_box_size();
Point legend_pos(bbox.min.x, bbox.max.y);
bbox.merge(Point(std::max(bbox.min.x + legend_size.x, bbox.max.x), bbox.max.y + legend_size.y));
SVG svg(path, bbox);
const float transparency = 0.5f;
- for (LayerRegionPtrs::const_iterator region = this->regions.begin(); region != this->regions.end(); ++region)
- for (Surfaces::const_iterator surface = (*region)->slices.surfaces.begin(); surface != (*region)->slices.surfaces.end(); ++surface)
- svg.draw(surface->expolygon, surface_type_to_color_name(surface->surface_type), transparency);
+ for (const auto *region : m_regions)
+ for (const auto &surface : region->slices.surfaces)
+ svg.draw(surface.expolygon, surface_type_to_color_name(surface.surface_type), transparency);
export_surface_type_legend_to_svg(svg, legend_pos);
svg.Close();
}
@@ -189,18 +189,18 @@ void Layer::export_region_slices_to_svg_debug(const char *name) const
void Layer::export_region_fill_surfaces_to_svg(const char *path) const
{
BoundingBox bbox;
- for (LayerRegionPtrs::const_iterator region = this->regions.begin(); region != this->regions.end(); ++region)
- for (Surfaces::const_iterator surface = (*region)->fill_surfaces.surfaces.begin(); surface != (*region)->fill_surfaces.surfaces.end(); ++surface)
- bbox.merge(get_extents(surface->expolygon));
+ for (const auto *region : m_regions)
+ for (const auto &surface : region->slices.surfaces)
+ bbox.merge(get_extents(surface.expolygon));
Point legend_size = export_surface_type_legend_to_svg_box_size();
Point legend_pos(bbox.min.x, bbox.max.y);
bbox.merge(Point(std::max(bbox.min.x + legend_size.x, bbox.max.x), bbox.max.y + legend_size.y));
SVG svg(path, bbox);
const float transparency = 0.5f;
- for (LayerRegionPtrs::const_iterator region = this->regions.begin(); region != this->regions.end(); ++region)
- for (Surfaces::const_iterator surface = (*region)->fill_surfaces.surfaces.begin(); surface != (*region)->fill_surfaces.surfaces.end(); ++surface)
- svg.draw(surface->expolygon, surface_type_to_color_name(surface->surface_type), transparency);
+ for (const auto *region : m_regions)
+ for (const auto &surface : region->slices.surfaces)
+ svg.draw(surface.expolygon, surface_type_to_color_name(surface.surface_type), transparency);
export_surface_type_legend_to_svg(svg, legend_pos);
svg.Close();
}
diff --git a/xs/src/libslic3r/Layer.hpp b/xs/src/libslic3r/Layer.hpp
index f3b460443..8dbe850cc 100644
--- a/xs/src/libslic3r/Layer.hpp
+++ b/xs/src/libslic3r/Layer.hpp
@@ -15,95 +15,93 @@ class Layer;
class PrintRegion;
class PrintObject;
-// TODO: make stuff private
class LayerRegion
{
- friend class Layer;
-
public:
- Layer* layer() { return this->_layer; }
- const Layer* layer() const { return this->_layer; }
- PrintRegion* region() { return this->_region; }
- const PrintRegion* region() const { return this->_region; }
+ Layer* layer() { return m_layer; }
+ const Layer* layer() const { return m_layer; }
+ PrintRegion* region() { return m_region; }
+ const PrintRegion* region() const { return m_region; }
// collection of surfaces generated by slicing the original geometry
// divided by type top/bottom/internal
- SurfaceCollection slices;
+ SurfaceCollection slices;
// collection of extrusion paths/loops filling gaps
// These fills are generated by the perimeter generator.
// They are not printed on their own, but they are copied to this->fills during infill generation.
- ExtrusionEntityCollection thin_fills;
+ ExtrusionEntityCollection thin_fills;
// Unspecified fill polygons, used for overhang detection ("ensure vertical wall thickness feature")
// and for re-starting of infills.
- ExPolygons fill_expolygons;
+ ExPolygons fill_expolygons;
// collection of surfaces for infill generation
- SurfaceCollection fill_surfaces;
+ SurfaceCollection fill_surfaces;
// Collection of perimeter surfaces. This is a cached result of diff(slices, fill_surfaces).
// While not necessary, the memory consumption is meager and it speeds up calculation.
// The perimeter_surfaces keep the IDs of the slices (top/bottom/)
- SurfaceCollection perimeter_surfaces;
+ SurfaceCollection perimeter_surfaces;
// collection of expolygons representing the bridged areas (thus not
// needing support material)
- Polygons bridged;
+ Polygons bridged;
// collection of polylines representing the unsupported bridge edges
- PolylineCollection unsupported_bridge_edges;
+ PolylineCollection unsupported_bridge_edges;
// ordered collection of extrusion paths/loops to build all perimeters
// (this collection contains only ExtrusionEntityCollection objects)
- ExtrusionEntityCollection perimeters;
+ ExtrusionEntityCollection perimeters;
// ordered collection of extrusion paths to fill surfaces
// (this collection contains only ExtrusionEntityCollection objects)
- ExtrusionEntityCollection fills;
+ ExtrusionEntityCollection fills;
- Flow flow(FlowRole role, bool bridge = false, double width = -1) const;
- void slices_to_fill_surfaces_clipped();
- void prepare_fill_surfaces();
- void make_perimeters(const SurfaceCollection &slices, SurfaceCollection* fill_surfaces);
- void process_external_surfaces(const Layer* lower_layer);
+ Flow flow(FlowRole role, bool bridge = false, double width = -1) const;
+ void slices_to_fill_surfaces_clipped();
+ void prepare_fill_surfaces();
+ void make_perimeters(const SurfaceCollection &slices, SurfaceCollection* fill_surfaces);
+ void process_external_surfaces(const Layer* lower_layer);
double infill_area_threshold() const;
- void export_region_slices_to_svg(const char *path) const;
- void export_region_fill_surfaces_to_svg(const char *path) const;
+ void export_region_slices_to_svg(const char *path) const;
+ void export_region_fill_surfaces_to_svg(const char *path) const;
// Export to "out/LayerRegion-name-%d.svg" with an increasing index with every export.
- void export_region_slices_to_svg_debug(const char *name) const;
- void export_region_fill_surfaces_to_svg_debug(const char *name) const;
+ void export_region_slices_to_svg_debug(const char *name) const;
+ void export_region_fill_surfaces_to_svg_debug(const char *name) const;
// Is there any valid extrusion assigned to this LayerRegion?
- bool has_extrusions() const { return ! this->perimeters.entities.empty() || ! this->fills.entities.empty(); }
+ bool has_extrusions() const { return ! this->perimeters.entities.empty() || ! this->fills.entities.empty(); }
-private:
- Layer *_layer;
- PrintRegion *_region;
+protected:
+ friend class Layer;
- LayerRegion(Layer *layer, PrintRegion *region) : _layer(layer), _region(region) {}
+ LayerRegion(Layer *layer, PrintRegion *region) : m_layer(layer), m_region(region) {}
~LayerRegion() {}
+
+private:
+ Layer *m_layer;
+ PrintRegion *m_region;
};
typedef std::vector<LayerRegion*> LayerRegionPtrs;
-class Layer {
- friend class PrintObject;
-
+class Layer
+{
public:
- size_t id() const { return this->_id; }
- void set_id(size_t id) { this->_id = id; }
- PrintObject* object() { return this->_object; }
- const PrintObject* object() const { return this->_object; }
-
- Layer *upper_layer;
- Layer *lower_layer;
- LayerRegionPtrs regions;
- bool slicing_errors;
- coordf_t slice_z; // Z used for slicing in unscaled coordinates
- coordf_t print_z; // Z used for printing in unscaled coordinates
- coordf_t height; // layer height in unscaled coordinates
+ size_t id() const { return m_id; }
+ void set_id(size_t id) { m_id = id; }
+ PrintObject* object() { return m_object; }
+ const PrintObject* object() const { return m_object; }
+
+ Layer *upper_layer;
+ Layer *lower_layer;
+ bool slicing_errors;
+ coordf_t slice_z; // Z used for slicing in unscaled coordinates
+ coordf_t print_z; // Z used for printing in unscaled coordinates
+ coordf_t height; // layer height in unscaled coordinates
// collection of expolygons generated by slicing the original geometry;
// also known as 'islands' (all regions and surface types are merged here)
@@ -111,57 +109,64 @@ public:
// order will be recovered by the G-code generator.
ExPolygonCollection slices;
- size_t region_count() const { return this->regions.size(); }
- const LayerRegion* get_region(int idx) const { return this->regions.at(idx); }
- LayerRegion* get_region(int idx) { return this->regions.at(idx); }
- LayerRegion* add_region(PrintRegion* print_region);
+ size_t region_count() const { return m_regions.size(); }
+ const LayerRegion* get_region(int idx) const { return m_regions.at(idx); }
+ LayerRegion* get_region(int idx) { return m_regions[idx]; }
+ LayerRegion* add_region(PrintRegion* print_region);
+ const LayerRegionPtrs& regions() const { return m_regions; }
- void make_slices();
- void merge_slices();
+ void make_slices();
+ void merge_slices();
template <class T> bool any_internal_region_slice_contains(const T &item) const {
- for (const LayerRegion *layerm : this->regions) if (layerm->slices.any_internal_contains(item)) return true;
+ for (const LayerRegion *layerm : m_regions) if (layerm->slices.any_internal_contains(item)) return true;
return false;
}
template <class T> bool any_bottom_region_slice_contains(const T &item) const {
- for (const LayerRegion *layerm : this->regions) if (layerm->slices.any_bottom_contains(item)) return true;
+ for (const LayerRegion *layerm : m_regions) if (layerm->slices.any_bottom_contains(item)) return true;
return false;
}
- void make_perimeters();
- void make_fills();
+ void make_perimeters();
+ void make_fills();
- void export_region_slices_to_svg(const char *path) const;
- void export_region_fill_surfaces_to_svg(const char *path) const;
+ void export_region_slices_to_svg(const char *path) const;
+ void export_region_fill_surfaces_to_svg(const char *path) const;
// Export to "out/LayerRegion-name-%d.svg" with an increasing index with every export.
- void export_region_slices_to_svg_debug(const char *name) const;
- void export_region_fill_surfaces_to_svg_debug(const char *name) const;
+ void export_region_slices_to_svg_debug(const char *name) const;
+ void export_region_fill_surfaces_to_svg_debug(const char *name) const;
// Is there any valid extrusion assigned to this LayerRegion?
- virtual bool has_extrusions() const { for (auto layerm : this->regions) if (layerm->has_extrusions()) return true; return false; }
+ virtual bool has_extrusions() const { for (auto layerm : m_regions) if (layerm->has_extrusions()) return true; return false; }
protected:
- size_t _id; // sequential number of layer, 0-based
- PrintObject *_object;
+ friend class PrintObject;
Layer(size_t id, PrintObject *object, coordf_t height, coordf_t print_z, coordf_t slice_z) :
upper_layer(nullptr), lower_layer(nullptr), slicing_errors(false),
slice_z(slice_z), print_z(print_z), height(height),
- _id(id), _object(object) {}
+ m_id(id), m_object(object) {}
virtual ~Layer();
-};
-class SupportLayer : public Layer {
- friend class PrintObject;
+private:
+ // sequential number of layer, 0-based
+ size_t m_id;
+ PrintObject *m_object;
+ LayerRegionPtrs m_regions;
+};
+class SupportLayer : public Layer
+{
public:
// Polygons covered by the supports: base, interface and contact areas.
- ExPolygonCollection support_islands;
+ ExPolygonCollection support_islands;
// Extrusion paths for the support base and for the support interface and contacts.
- ExtrusionEntityCollection support_fills;
+ ExtrusionEntityCollection support_fills;
// Is there any valid extrusion assigned to this LayerRegion?
- virtual bool has_extrusions() const { return ! support_fills.empty(); }
+ virtual bool has_extrusions() const { return ! support_fills.empty(); }
+
+protected:
+ friend class PrintObject;
-//protected:
// The constructor has been made public to be able to insert additional support layers for the skirt or a wipe tower
// between the raft and the object first layer.
SupportLayer(size_t id, PrintObject *object, coordf_t height, coordf_t print_z, coordf_t slice_z) :
diff --git a/xs/src/libslic3r/LayerRegion.cpp b/xs/src/libslic3r/LayerRegion.cpp
index 68d1c5829..c576d7eec 100644
--- a/xs/src/libslic3r/LayerRegion.cpp
+++ b/xs/src/libslic3r/LayerRegion.cpp
@@ -18,13 +18,13 @@ namespace Slic3r {
Flow
LayerRegion::flow(FlowRole role, bool bridge, double width) const
{
- return this->_region->flow(
+ return m_region->flow(
role,
- this->_layer->height,
+ m_layer->height,
bridge,
- this->_layer->id() == 0,
+ m_layer->id() == 0,
width,
- *this->_layer->object()
+ *m_layer->object()
);
}
@@ -61,9 +61,9 @@ void LayerRegion::make_perimeters(const SurfaceCollection &slices, SurfaceCollec
&slices,
this->layer()->height,
this->flow(frPerimeter),
- &this->region()->config,
- &this->layer()->object()->config,
- &this->layer()->object()->print()->config,
+ &this->region()->config(),
+ &this->layer()->object()->config(),
+ &this->layer()->object()->print()->config(),
// output:
&this->perimeters,
@@ -116,7 +116,7 @@ void LayerRegion::process_external_surfaces(const Layer* lower_layer)
{
// bottom_polygons are used to trim inflated top surfaces.
fill_boundaries.reserve(number_polygons(surfaces));
- bool has_infill = this->region()->config.fill_density.value > 0.;
+ bool has_infill = this->region()->config().fill_density.value > 0.;
for (const Surface &surface : this->fill_surfaces.surfaces) {
if (surface.surface_type == stTop) {
// Collect the top surfaces, inflate them and trim them by the bottom surfaces.
@@ -259,9 +259,9 @@ void LayerRegion::process_external_surfaces(const Layer* lower_layer)
#ifdef SLIC3R_DEBUG
printf("Processing bridge at layer " PRINTF_ZU ":\n", this->layer()->id());
#endif
- if (bd.detect_angle(Geometry::deg2rad(this->region()->config.bridge_angle.value))) {
+ if (bd.detect_angle(Geometry::deg2rad(this->region()->config().bridge_angle.value))) {
bridges[idx_last].bridge_angle = bd.angle;
- if (this->layer()->object()->config.support_material) {
+ if (this->layer()->object()->config().support_material) {
polygons_append(this->bridged, bd.coverage());
this->unsupported_bridge_edges.append(bd.unsupported_edges());
}
@@ -351,13 +351,13 @@ void LayerRegion::prepare_fill_surfaces()
the only meaningful information returned by psPerimeters. */
// if no solid layers are requested, turn top/bottom surfaces to internal
- if (this->region()->config.top_solid_layers == 0) {
+ if (this->region()->config().top_solid_layers == 0) {
for (Surfaces::iterator surface = this->fill_surfaces.surfaces.begin(); surface != this->fill_surfaces.surfaces.end(); ++surface)
if (surface->surface_type == stTop)
- surface->surface_type = (this->layer()->object()->config.infill_only_where_needed) ?
+ surface->surface_type = (this->layer()->object()->config().infill_only_where_needed) ?
stInternalVoid : stInternal;
}
- if (this->region()->config.bottom_solid_layers == 0) {
+ if (this->region()->config().bottom_solid_layers == 0) {
for (Surfaces::iterator surface = this->fill_surfaces.surfaces.begin(); surface != this->fill_surfaces.surfaces.end(); ++surface) {
if (surface->surface_type == stBottom || surface->surface_type == stBottomBridge)
surface->surface_type = stInternal;
@@ -365,9 +365,9 @@ void LayerRegion::prepare_fill_surfaces()
}
// turn too small internal regions into solid regions according to the user setting
- if (this->region()->config.fill_density.value > 0) {
+ if (this->region()->config().fill_density.value > 0) {
// scaling an area requires two calls!
- double min_area = scale_(scale_(this->region()->config.solid_infill_below_area.value));
+ double min_area = scale_(scale_(this->region()->config().solid_infill_below_area.value));
for (Surfaces::iterator surface = this->fill_surfaces.surfaces.begin(); surface != this->fill_surfaces.surfaces.end(); ++surface) {
if (surface->surface_type == stInternal && surface->area() <= min_area)
surface->surface_type = stInternalSolid;
diff --git a/xs/src/libslic3r/PerimeterGenerator.cpp b/xs/src/libslic3r/PerimeterGenerator.cpp
index ea9c73fa4..176f28926 100644
--- a/xs/src/libslic3r/PerimeterGenerator.cpp
+++ b/xs/src/libslic3r/PerimeterGenerator.cpp
@@ -6,8 +6,7 @@
namespace Slic3r {
-void
-PerimeterGenerator::process()
+void PerimeterGenerator::process()
{
// other perimeters
this->_mm3_per_mm = this->perimeter_flow.mm3_per_mm();
diff --git a/xs/src/libslic3r/PerimeterGenerator.hpp b/xs/src/libslic3r/PerimeterGenerator.hpp
index 04557a2c0..dd1f9b0ec 100644
--- a/xs/src/libslic3r/PerimeterGenerator.hpp
+++ b/xs/src/libslic3r/PerimeterGenerator.hpp
@@ -38,30 +38,30 @@ typedef std::vector<PerimeterGeneratorLoop> PerimeterGeneratorLoops;
class PerimeterGenerator {
public:
// Inputs:
- const SurfaceCollection* slices;
- const ExPolygonCollection* lower_slices;
- double layer_height;
- int layer_id;
- Flow perimeter_flow;
- Flow ext_perimeter_flow;
- Flow overhang_flow;
- Flow solid_infill_flow;
- PrintRegionConfig* config;
- PrintObjectConfig* object_config;
- PrintConfig* print_config;
+ const SurfaceCollection *slices;
+ const ExPolygonCollection *lower_slices;
+ double layer_height;
+ int layer_id;
+ Flow perimeter_flow;
+ Flow ext_perimeter_flow;
+ Flow overhang_flow;
+ Flow solid_infill_flow;
+ const PrintRegionConfig *config;
+ const PrintObjectConfig *object_config;
+ const PrintConfig *print_config;
// Outputs:
- ExtrusionEntityCollection* loops;
- ExtrusionEntityCollection* gap_fill;
- SurfaceCollection* fill_surfaces;
+ ExtrusionEntityCollection *loops;
+ ExtrusionEntityCollection *gap_fill;
+ SurfaceCollection *fill_surfaces;
PerimeterGenerator(
// Input:
const SurfaceCollection* slices,
double layer_height,
Flow flow,
- PrintRegionConfig* config,
- PrintObjectConfig* object_config,
- PrintConfig* print_config,
+ const PrintRegionConfig* config,
+ const PrintObjectConfig* object_config,
+ const PrintConfig* print_config,
// Output:
// Loops with the external thin walls
ExtrusionEntityCollection* loops,
@@ -79,15 +79,13 @@ public:
void process();
private:
- double _ext_mm3_per_mm;
- double _mm3_per_mm;
- double _mm3_per_mm_overhang;
- Polygons _lower_slices_p;
+ double _ext_mm3_per_mm;
+ double _mm3_per_mm;
+ double _mm3_per_mm_overhang;
+ Polygons _lower_slices_p;
- ExtrusionEntityCollection _traverse_loops(const PerimeterGeneratorLoops &loops,
- ThickPolylines &thin_walls) const;
- ExtrusionEntityCollection _variable_width
- (const ThickPolylines &polylines, ExtrusionRole role, Flow flow) const;
+ ExtrusionEntityCollection _traverse_loops(const PerimeterGeneratorLoops &loops, ThickPolylines &thin_walls) const;
+ ExtrusionEntityCollection _variable_width(const ThickPolylines &polylines, ExtrusionRole role, Flow flow) const;
};
}
diff --git a/xs/src/libslic3r/PlaceholderParser.cpp b/xs/src/libslic3r/PlaceholderParser.cpp
index 62b516935..848e7fd2a 100644
--- a/xs/src/libslic3r/PlaceholderParser.cpp
+++ b/xs/src/libslic3r/PlaceholderParser.cpp
@@ -69,7 +69,7 @@ PlaceholderParser::PlaceholderParser()
this->update_timestamp();
}
-void PlaceholderParser::update_timestamp()
+void PlaceholderParser::update_timestamp(DynamicConfig &config)
{
time_t rawtime;
time(&rawtime);
@@ -84,14 +84,14 @@ void PlaceholderParser::update_timestamp()
ss << std::setw(2) << std::setfill('0') << timeinfo->tm_hour;
ss << std::setw(2) << std::setfill('0') << timeinfo->tm_min;
ss << std::setw(2) << std::setfill('0') << timeinfo->tm_sec;
- this->set("timestamp", ss.str());
+ config.set_key_value("timestamp", new ConfigOptionString(ss.str()));
}
- this->set("year", 1900 + timeinfo->tm_year);
- this->set("month", 1 + timeinfo->tm_mon);
- this->set("day", timeinfo->tm_mday);
- this->set("hour", timeinfo->tm_hour);
- this->set("minute", timeinfo->tm_min);
- this->set("second", timeinfo->tm_sec);
+ config.set_key_value("year", new ConfigOptionInt(1900 + timeinfo->tm_year));
+ config.set_key_value("month", new ConfigOptionInt(1 + timeinfo->tm_mon));
+ config.set_key_value("day", new ConfigOptionInt(timeinfo->tm_mday));
+ config.set_key_value("hour", new ConfigOptionInt(timeinfo->tm_hour));
+ config.set_key_value("minute", new ConfigOptionInt(timeinfo->tm_min));
+ config.set_key_value("second", new ConfigOptionInt(timeinfo->tm_sec));
}
// Scalar configuration values are stored into m_single,
diff --git a/xs/src/libslic3r/PlaceholderParser.hpp b/xs/src/libslic3r/PlaceholderParser.hpp
index 4e0aa9ee2..49d53ec9e 100644
--- a/xs/src/libslic3r/PlaceholderParser.hpp
+++ b/xs/src/libslic3r/PlaceholderParser.hpp
@@ -14,7 +14,6 @@ class PlaceholderParser
public:
PlaceholderParser();
- void update_timestamp();
void apply_config(const DynamicPrintConfig &config);
void apply_env_variables();
@@ -37,6 +36,11 @@ public:
// Throws std::runtime_error on syntax or runtime error.
static bool evaluate_boolean_expression(const std::string &templ, const DynamicConfig &config, const DynamicConfig *config_override = nullptr);
+ // Update timestamp, year, month, day, hour, minute, second variables at the provided config.
+ static void update_timestamp(DynamicConfig &config);
+ // Update timestamp, year, month, day, hour, minute, second variables at m_config.
+ void update_timestamp() { update_timestamp(m_config); }
+
private:
DynamicConfig m_config;
};
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;
diff --git a/xs/src/libslic3r/Print.hpp b/xs/src/libslic3r/Print.hpp
index 1162c9b0f..71711b31e 100644
--- a/xs/src/libslic3r/Print.hpp
+++ b/xs/src/libslic3r/Print.hpp
@@ -51,7 +51,7 @@ template <class StepType, size_t COUNT>
class PrintState
{
public:
- PrintState() { for (size_t i = 0; i < COUNT; ++ i) m_state[i] = INVALID; }
+ PrintState() { for (size_t i = 0; i < COUNT; ++ i) m_state[i].store(INVALID, std::memory_order_relaxed); }
enum State {
INVALID,
@@ -59,24 +59,58 @@ public:
DONE,
};
+ // With full memory barrier.
bool is_done(StepType step) const { return m_state[step] == DONE; }
- // set_started() will lock the provided mutex before setting the state.
+
+ // Set the step as started. Block on mutex while the Print / PrintObject / PrintRegion objects are being
+ // modified by the UI thread.
// This is necessary to block until the Print::apply_config() updates its state, which may
// influence the processing step being entered.
- void set_started(StepType step, tbb::mutex &mtx) { mtx.lock(); m_state[step] = STARTED; mtx.unlock(); }
- void set_done(StepType step) { m_state[step] = DONE; }
- bool invalidate(StepType step) {
- bool invalidated = m_state[step] != INVALID;
- m_state[step] = INVALID;
+ void set_started(StepType step, tbb::mutex &mtx) {
+ mtx.lock();
+ m_state[step].store(STARTED, std::memory_order_relaxed);
+ mtx.unlock();
+ }
+
+ // Set the step as done. Block on mutex while the Print / PrintObject / PrintRegion objects are being
+ // modified by the UI thread.
+ void set_done(StepType step, tbb::mutex &mtx) {
+ mtx.lock();
+ m_state[step].store(DONE, std::memory_order_relaxed);
+ mtx.unlock();
+ }
+
+ // Make the step invalid.
+ // The provided mutex should be locked at this point, guarding access to m_state.
+ // In case the step has already been entered or finished, cancel the background
+ // processing by calling the cancel callback.
+ template<typename CancelationCallback>
+ bool invalidate(StepType step, tbb::mutex &mtx, CancelationCallback &cancel) {
+ bool invalidated = m_state[step].load(std::memory_order_relaxed) != INVALID;
+ if (invalidated) {
+ mtx.unlock();
+ cancel();
+ mtx.lock();
+ }
return invalidated;
}
- bool invalidate_all() {
+
+ // Make all steps invalid.
+ // The provided mutex should be locked at this point, guarding access to m_state.
+ // In case any step has already been entered or finished, cancel the background
+ // processing by calling the cancel callback.
+ template<typename CancelationCallback>
+ bool invalidate_all(tbb::mutex &mtx, CancelationCallback &cancel) {
bool invalidated = false;
for (size_t i = 0; i < COUNT; ++ i)
- if (m_state[i] != INVALID) {
- invalidated = true;
- m_state[i] = INVALID;
- break;
+ if (m_state[i].load(std::memory_order_relaxed) != INVALID) {
+ if (! invalidated) {
+ mtx.unlock();
+ cancel();
+ mtx.lock();
+ invalidated = true;
+ }
+ m_state[i].store(INVALID, std::memory_order_relaxed);
}
return invalidated;
}
@@ -91,17 +125,24 @@ class PrintRegion
{
friend class Print;
+// Methods NOT modifying the PrintRegion's state:
public:
- PrintRegionConfig config;
+ const Print* print() const { return m_print; }
+ const PrintRegionConfig& config() const { return m_config; }
+ Flow flow(FlowRole role, double layer_height, bool bridge, bool first_layer, double width, const PrintObject &object) const;
+ coordf_t nozzle_dmr_avg(const PrintConfig &print_config) const;
- Print* print() { return this->_print; }
- Flow flow(FlowRole role, double layer_height, bool bridge, bool first_layer, double width, const PrintObject &object) const;
- coordf_t nozzle_dmr_avg(const PrintConfig &print_config) const;
+// Methods modifying the PrintRegion's state:
+public:
+ Print* print() { return m_print; }
+ void config_apply_only(const ConfigBase &other, const t_config_option_keys &keys, bool ignore_nonexistent = false) { this->m_config.apply_only(other, keys, ignore_nonexistent); }
private:
- Print* _print;
+ Print *m_print;
+ PrintRegionConfig m_config;
- PrintRegion(Print* print) : _print(print) {}
+ PrintRegion(Print* print) : m_print(print) {}
+ PrintRegion(Print* print, const PrintRegionConfig &config) : m_print(print), m_config(config) {}
~PrintRegion() {}
};
@@ -117,7 +158,6 @@ class PrintObject
public:
// vector of (vectors of volume ids), indexed by region_id
std::vector<std::vector<int>> region_volumes;
- PrintObjectConfig config;
t_layer_height_ranges layer_height_ranges;
// Profile of increasing z to a layer height, to be linearly interpolated when calculating the layers.
@@ -144,15 +184,17 @@ public:
// Slic3r::Point objects in scaled G-code coordinates in our coordinates
Points _shifted_copies;
- LayerPtrs layers;
- SupportLayerPtrs support_layers;
-
- Print* print() { return this->_print; }
- const Print* print() const { return this->_print; }
- ModelObject* model_object() { return this->_model_object; }
- const ModelObject* model_object() const { return this->_model_object; }
-
- const Points& copies() const { return this->_copies; }
+ Print* print() { return m_print; }
+ const Print* print() const { return m_print; }
+ ModelObject* model_object() { return m_model_object; }
+ const ModelObject* model_object() const { return m_model_object; }
+ const PrintObjectConfig& config() const { return m_config; }
+ void config_apply(const ConfigBase &other, bool ignore_nonexistent = false) { this->m_config.apply(other, ignore_nonexistent); }
+ void config_apply_only(const ConfigBase &other, const t_config_option_keys &keys, bool ignore_nonexistent = false) { this->m_config.apply_only(other, keys, ignore_nonexistent); }
+ const LayerPtrs& layers() const { return m_layers; }
+ const SupportLayerPtrs& support_layers() const { return m_support_layers; }
+
+ const Points& copies() const { return m_copies; }
bool add_copy(const Pointf &point);
bool delete_last_copy();
bool delete_all_copies() { return this->set_copies(Points()); }
@@ -171,24 +213,25 @@ public:
// this value is not supposed to be compared with Layer::id
// since they have different semantics.
size_t total_layer_count() const { return this->layer_count() + this->support_layer_count(); }
- size_t layer_count() const { return this->layers.size(); }
+ size_t layer_count() const { return m_layers.size(); }
void clear_layers();
- Layer* get_layer(int idx) { return this->layers.at(idx); }
- const Layer* get_layer(int idx) const { return this->layers.at(idx); }
+ Layer* get_layer(int idx) { return m_layers[idx]; }
+ const Layer* get_layer(int idx) const { return m_layers[idx]; }
// print_z: top of the layer; slice_z: center of the layer.
Layer* add_layer(int id, coordf_t height, coordf_t print_z, coordf_t slice_z);
- size_t support_layer_count() const { return this->support_layers.size(); }
+ size_t support_layer_count() const { return m_support_layers.size(); }
void clear_support_layers();
- SupportLayer* get_support_layer(int idx) { return this->support_layers.at(idx); }
+ SupportLayer* get_support_layer(int idx) { return m_support_layers[idx]; }
SupportLayer* add_support_layer(int id, coordf_t height, coordf_t print_z);
+ 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);
// methods for handling state
bool invalidate_state_by_config_options(const std::vector<t_config_option_key> &opt_keys);
bool invalidate_step(PrintObjectStep step);
- bool invalidate_all_steps() { return m_state.invalidate_all(); }
+ bool invalidate_all_steps();
bool is_step_done(PrintObjectStep step) const { return m_state.is_done(step); }
// To be used over the layer_height_profile of both the PrintObject and ModelObject
@@ -229,9 +272,14 @@ private:
void combine_infill();
void _generate_support_material();
- Print* _print;
- ModelObject* _model_object;
- Points _copies; // Slic3r::Point objects in scaled G-code coordinates
+ Print *m_print;
+ ModelObject *m_model_object;
+ PrintObjectConfig m_config;
+ // Slic3r::Point objects in scaled G-code coordinates
+ Points m_copies;
+
+ LayerPtrs m_layers;
+ SupportLayerPtrs m_support_layers;
PrintState<PrintObjectStep, posCount> m_state;
// Mutex used for synchronization of the worker thread with the UI thread:
@@ -245,9 +293,49 @@ private:
~PrintObject() {}
void set_started(PrintObjectStep step) { m_state.set_started(step, m_mutex); }
+ void set_done(PrintObjectStep step) { m_state.set_done(step, m_mutex); }
std::vector<ExPolygons> _slice_region(size_t region_id, const std::vector<float> &z, bool modifier);
};
+struct WipeTowerData
+{
+ // Following section will be consumed by the GCodeGenerator.
+ // Tool ordering of a non-sequential print has to be known to calculate the wipe tower.
+ // Cache it here, so it does not need to be recalculated during the G-code generation.
+ ToolOrdering tool_ordering;
+ // Cache of tool changes per print layer.
+ std::unique_ptr<WipeTower::ToolChangeResult> priming;
+ std::vector<std::vector<WipeTower::ToolChangeResult>> tool_changes;
+ std::unique_ptr<WipeTower::ToolChangeResult> final_purge;
+
+ void clear() {
+ tool_ordering.clear();
+ priming.reset(nullptr);
+ tool_changes.clear();
+ final_purge.reset(nullptr);
+ }
+};
+
+struct PrintStatistics
+{
+ PrintStatistics() { clear(); }
+ std::string estimated_print_time;
+ double total_used_filament;
+ double total_extruded_volume;
+ double total_cost;
+ double total_weight;
+ std::map<size_t, float> filament_stats;
+
+ void clear() {
+ estimated_print_time.clear();
+ total_used_filament = 0.;
+ total_extruded_volume = 0.;
+ total_weight = 0.;
+ total_cost = 0.;
+ filament_stats.clear();
+ }
+};
+
typedef std::vector<PrintObject*> PrintObjectPtrs;
typedef std::vector<PrintRegion*> PrintRegionPtrs;
@@ -255,110 +343,115 @@ typedef std::vector<PrintRegion*> PrintRegionPtrs;
class Print
{
public:
- PrintConfig config;
- PrintObjectConfig default_object_config;
- PrintRegionConfig default_region_config;
- PrintObjectPtrs objects;
- PrintRegionPtrs regions;
- PlaceholderParser placeholder_parser;
- std::string estimated_print_time;
- double total_used_filament, total_extruded_volume, total_cost, total_weight;
- std::map<size_t, float> filament_stats;
-
- // ordered collections of extrusion paths to build skirt loops and brim
- ExtrusionEntityCollection skirt, brim;
-
- Print() : total_used_filament(0), total_extruded_volume(0) { restart(); }
+ Print() { restart(); }
~Print() { clear_objects(); }
- // methods for handling objects
- void clear_objects();
- PrintObject* get_object(size_t idx) { return objects.at(idx); }
- const PrintObject* get_object(size_t idx) const { return objects.at(idx); }
-
- void delete_object(size_t idx);
- void reload_object(size_t idx);
- bool reload_model_instances();
+ // Methods, which change the state of Print / PrintObject / PrintRegion.
+ // The following methods are synchronized with process() and export_gcode(),
+ // so that process() and export_gcode() may be called from a background thread.
+ // In case the following methods need to modify data processed by process() or export_gcode(),
+ // a cancellation callback is executed to stop the background processing before the operation.
+ void clear_objects();
+ void delete_object(size_t idx);
+ void reload_object(size_t idx);
+ bool reload_model_instances();
+ void add_model_object(ModelObject* model_object, int idx = -1);
+ bool apply_config(DynamicPrintConfig config);
+ void process();
+ void export_gcode(const std::string &path_template, GCodePreviewData *preview_data);
- // methods for handling regions
- PrintRegion* get_region(size_t idx) { return regions.at(idx); }
- const PrintRegion* get_region(size_t idx) const { return regions.at(idx); }
- PrintRegion* add_region();
-
// methods for handling state
- bool invalidate_step(PrintStep step);
- bool invalidate_all_steps() { return m_state.invalidate_all(); }
- bool is_step_done(PrintStep step) const { return m_state.is_done(step); }
- bool is_step_done(PrintObjectStep step) const;
-
- void add_model_object(ModelObject* model_object, int idx = -1);
- bool apply_config(DynamicPrintConfig config);
- bool has_infinite_skirt() const;
- bool has_skirt() const;
+ bool is_step_done(PrintStep step) const { return m_state.is_done(step); }
+ bool is_step_done(PrintObjectStep step) const;
+
+ bool has_infinite_skirt() const;
+ bool has_skirt() const;
// Returns an empty string if valid, otherwise returns an error message.
- std::string validate() const;
- BoundingBox bounding_box() const;
- BoundingBox total_bounding_box() const;
- double skirt_first_layer_height() const;
- Flow brim_flow() const;
- Flow skirt_flow() const;
+ std::string validate() const;
+ BoundingBox bounding_box() const;
+ BoundingBox total_bounding_box() const;
+ double skirt_first_layer_height() const;
+ Flow brim_flow() const;
+ Flow skirt_flow() const;
std::vector<unsigned int> object_extruders() const;
std::vector<unsigned int> support_material_extruders() const;
std::vector<unsigned int> extruders() const;
- void _simplify_slices(double distance);
- double max_allowed_layer_height() const;
- bool has_support_material() const;
- void auto_assign_extruders(ModelObject* model_object) const;
+ double max_allowed_layer_height() const;
+ bool has_support_material() const;
+ // Make sure the background processing has no access to this model_object during this call!
+ void auto_assign_extruders(ModelObject* model_object) const;
+
+ const PrintConfig& config() const { return m_config; }
+ const PrintObjectConfig& default_object_config() const { return m_default_object_config; }
+ const PrintRegionConfig& default_region_config() const { return m_default_region_config; }
+ const PrintObjectPtrs& objects() const { return m_objects; }
+ const PrintRegionPtrs& regions() const { return m_regions; }
+ const PlaceholderParser& placeholder_parser() const { return m_placeholder_parser; }
+
+ const ExtrusionEntityCollection& skirt() const { return m_skirt; }
+ const ExtrusionEntityCollection& brim() const { return m_brim; }
- void process();
- void export_gcode(const std::string &path_template, GCodePreviewData *preview_data);
+ const PrintStatistics& print_statistics() const { return m_print_statistics; }
// Wipe tower support.
- bool has_wipe_tower() const;
- // Tool ordering of a non-sequential print has to be known to calculate the wipe tower.
- // Cache it here, so it does not need to be recalculated during the G-code generation.
- ToolOrdering m_tool_ordering;
- // Cache of tool changes per print layer.
- std::unique_ptr<WipeTower::ToolChangeResult> m_wipe_tower_priming;
- std::vector<std::vector<WipeTower::ToolChangeResult>> m_wipe_tower_tool_changes;
- std::unique_ptr<WipeTower::ToolChangeResult> m_wipe_tower_final_purge;
+ bool has_wipe_tower() const;
+ const WipeTowerData& wipe_tower_data() const { return m_wipe_tower_data; }
- std::string output_filename();
- std::string output_filepath(const std::string &path);
+ std::string output_filename() const;
+ std::string output_filepath(const std::string &path) const;
typedef std::function<void(int, const std::string&)> status_callback_type;
// Default status console print out in the form of percent => message.
- void set_status_default() { m_status_callback = nullptr; }
+ void set_status_default() { m_status_callback = nullptr; }
// No status output or callback whatsoever, useful mostly for automatic tests.
- void set_status_silent() { m_status_callback = [](int, const std::string&){}; }
+ void set_status_silent() { m_status_callback = [](int, const std::string&){}; }
// Register a custom status callback.
- void set_status_callback(status_callback_type cb) { m_status_callback = cb; }
+ void set_status_callback(status_callback_type cb) { m_status_callback = cb; }
// Calls a registered callback to update the status, or print out the default message.
- void set_status(int percent, const std::string &message) {
+ void set_status(int percent, const std::string &message) {
if (m_status_callback) m_status_callback(percent, message);
else printf("%d => %s\n", percent, message.c_str());
}
+
+ typedef std::function<void()> cancel_callback_type;
+ // Various methods will call this callback to stop the background processing (the Print::process() call)
+ // in case a successive change of the Print / PrintObject / PrintRegion instances changed
+ // the state of the finished or running calculations.
+ void set_cancel_callback(cancel_callback_type cancel_callback) { m_cancel_callback = cancel_callback; }
+ // Has the calculation been canceled?
+ bool canceled() const { return m_canceled; }
// Cancel the running computation. Stop execution of all the background threads.
- void cancel() { m_canceled = true; }
+ void cancel() { m_canceled = true; }
// Cancel the running computation. Stop execution of all the background threads.
- void restart() { m_canceled = false; }
- // Has the calculation been canceled?
- bool canceled() { return m_canceled; }
- void throw_if_canceled() { if (m_canceled) throw CanceledException(); }
+ void restart() { m_canceled = false; }
+
+ // Accessed by SupportMaterial
+ const PrintRegion* get_region(size_t idx) const { return m_regions[idx]; }
protected:
- void set_started(PrintStep step) { m_state.set_started(step, m_mutex); }
- void set_done(PrintStep step) { m_state.set_done(step); }
+ void set_started(PrintStep step) { m_state.set_started(step, m_mutex); }
+ void set_done(PrintStep step) { m_state.set_done(step, m_mutex); }
+ bool invalidate_step(PrintStep step);
+ bool invalidate_all_steps() { return m_state.invalidate_all(m_mutex, m_cancel_callback); }
+
+ // methods for handling regions
+ PrintRegion* get_region(size_t idx) { return m_regions[idx]; }
+ PrintRegion* add_region();
+ PrintRegion* add_region(const PrintRegionConfig &config);
private:
- bool invalidate_state_by_config_options(const std::vector<t_config_option_key> &opt_keys);
- PrintRegionConfig _region_config_from_model_volume(const ModelVolume &volume);
+ bool invalidate_state_by_config_options(const std::vector<t_config_option_key> &opt_keys);
+ PrintRegionConfig _region_config_from_model_volume(const ModelVolume &volume);
- void _make_skirt();
- void _make_brim();
- void _clear_wipe_tower();
- void _make_wipe_tower();
+ // If the background processing stop was requested, throw CanceledException.
+ // To be called by the worker thread and its sub-threads (mostly launched on the TBB thread pool) regularly.
+ void throw_if_canceled() { if (m_canceled) throw CanceledException(); }
+
+ void _make_skirt();
+ void _make_brim();
+ void _make_wipe_tower();
+ void _simplify_slices(double distance);
PrintState<PrintStep, psCount> m_state;
// Mutex used for synchronization of the worker thread with the UI thread:
@@ -370,15 +463,36 @@ private:
// Callback to be evoked regularly to update state of the UI thread.
status_callback_type m_status_callback;
+ // Callback to be evoked to stop the background processing before a state is updated.
+ cancel_callback_type m_cancel_callback = [](){};
+
+ PrintConfig m_config;
+ PrintObjectConfig m_default_object_config;
+ PrintRegionConfig m_default_region_config;
+ PrintObjectPtrs m_objects;
+ PrintRegionPtrs m_regions;
+ PlaceholderParser m_placeholder_parser;
+
+ // Ordered collections of extrusion paths to build skirt loops and brim.
+ ExtrusionEntityCollection m_skirt;
+ ExtrusionEntityCollection m_brim;
+
+ // Following section will be consumed by the GCodeGenerator.
+ WipeTowerData m_wipe_tower_data;
+
+ // Estimated print time, filament consumed.
+ PrintStatistics m_print_statistics;
+
// To allow GCode to set the Print's GCodeExport step status.
friend class GCode;
+ // Allow PrintObject to access m_mutex and m_cancel_callback.
+ friend class PrintObject;
};
#define FOREACH_BASE(type, container, iterator) for (type::const_iterator iterator = (container).begin(); iterator != (container).end(); ++iterator)
-#define FOREACH_REGION(print, region) FOREACH_BASE(PrintRegionPtrs, (print)->regions, region)
-#define FOREACH_OBJECT(print, object) FOREACH_BASE(PrintObjectPtrs, (print)->objects, object)
-#define FOREACH_LAYER(object, layer) FOREACH_BASE(LayerPtrs, (object)->layers, layer)
-#define FOREACH_LAYERREGION(layer, layerm) FOREACH_BASE(LayerRegionPtrs, (layer)->regions, layerm)
+#define FOREACH_OBJECT(print, object) FOREACH_BASE(PrintObjectPtrs, (print)->m_objects, object)
+#define FOREACH_LAYER(object, layer) FOREACH_BASE(LayerPtrs, (object)->m_layers, layer)
+#define FOREACH_LAYERREGION(layer, layerm) FOREACH_BASE(LayerRegionPtrs, (layer)->m_regions, layerm)
}
diff --git a/xs/src/libslic3r/PrintObject.cpp b/xs/src/libslic3r/PrintObject.cpp
index ff1e983fd..ba2521cd7 100644
--- a/xs/src/libslic3r/PrintObject.cpp
+++ b/xs/src/libslic3r/PrintObject.cpp
@@ -35,8 +35,8 @@ namespace Slic3r {
PrintObject::PrintObject(Print* print, ModelObject* model_object, const BoundingBoxf3 &modobj_bbox) :
typed_slices(false),
- _print(print),
- _model_object(model_object),
+ m_print(print),
+ m_model_object(model_object),
layer_height_profile_valid(false)
{
// Compute the translation to be applied to our meshes so that we work with smaller coordinates
@@ -60,21 +60,21 @@ PrintObject::PrintObject(Print* print, ModelObject* model_object, const Bounding
bool PrintObject::add_copy(const Pointf &point)
{
- Points points = this->_copies;
+ Points points = m_copies;
points.push_back(Point::new_scale(point.x, point.y));
return this->set_copies(points);
}
bool PrintObject::delete_last_copy()
{
- Points points = this->_copies;
+ Points points = m_copies;
points.pop_back();
return this->set_copies(points);
}
bool PrintObject::set_copies(const Points &points)
{
- this->_copies = points;
+ m_copies = points;
// order copies with a nearest neighbor search and translate them by _copies_shift
this->_shifted_copies.clear();
@@ -90,16 +90,16 @@ bool PrintObject::set_copies(const Points &points)
this->_shifted_copies.push_back(copy);
}
- bool invalidated = this->_print->invalidate_step(psSkirt);
- invalidated |= this->_print->invalidate_step(psBrim);
+ bool invalidated = m_print->invalidate_step(psSkirt);
+ invalidated |= m_print->invalidate_step(psBrim);
return invalidated;
}
bool PrintObject::reload_model_instances()
{
Points copies;
- copies.reserve(this->_model_object->instances.size());
- for (const ModelInstance *mi : this->_model_object->instances)
+ copies.reserve(m_model_object->instances.size());
+ for (const ModelInstance *mi : m_model_object->instances)
copies.emplace_back(Point::new_scale(mi->offset.x, mi->offset.y));
return this->set_copies(copies);
}
@@ -118,21 +118,21 @@ void PrintObject::slice()
if (m_state.is_done(posSlice))
return;
this->set_started(posSlice);
- this->_print->set_status(10, "Processing triangulated mesh");
+ m_print->set_status(10, "Processing triangulated mesh");
this->_slice();
- this->_print->throw_if_canceled();
+ m_print->throw_if_canceled();
// Fix the model.
//FIXME is this the right place to do? It is done repeateadly at the UI and now here at the backend.
std::string warning = this->_fix_slicing_errors();
- this->_print->throw_if_canceled();
+ m_print->throw_if_canceled();
if (! warning.empty())
BOOST_LOG_TRIVIAL(info) << warning;
// Simplify slices if required.
- if (this->_print->config.resolution)
- this->_simplify_slices(scale_(this->_print->config.resolution));
- if (this->layers.empty())
+ if (m_print->config().resolution)
+ this->_simplify_slices(scale_(this->print()->config().resolution));
+ if (m_layers.empty())
throw std::runtime_error("No layers were detected. You might want to repair your STL file(s) or check their size or thickness and retry.\n");
- m_state.set_done(posSlice);
+ this->set_done(posSlice);
}
// 1) Merges typed region slices into stInternal type.
@@ -147,17 +147,17 @@ void PrintObject::make_perimeters()
return;
this->set_started(posPerimeters);
- this->_print->set_status(20, "Generating perimeters");
+ m_print->set_status(20, "Generating perimeters");
BOOST_LOG_TRIVIAL(info) << "Generating perimeters...";
// merge slices if they were split into types
if (this->typed_slices) {
FOREACH_LAYER(this, layer_it) {
(*layer_it)->merge_slices();
- this->_print->throw_if_canceled();
+ m_print->throw_if_canceled();
}
this->typed_slices = false;
- m_state.invalidate(posPrepareInfill);
+// m_state.invalidate(posPrepareInfill);
}
// compare each layer to the one below, and mark those slices needing
@@ -167,24 +167,23 @@ void PrintObject::make_perimeters()
// but we don't generate any extra perimeter if fill density is zero, as they would be floating
// inside the object - infill_only_where_needed should be the method of choice for printing
// hollow objects
- FOREACH_REGION(this->_print, region_it) {
- size_t region_id = region_it - this->_print->regions.begin();
- const PrintRegion &region = **region_it;
+ for (size_t region_id = 0; region_id < m_print->regions().size(); ++ region_id) {
+ const PrintRegion &region = *m_print->regions()[region_id];
- if (!region.config.extra_perimeters
- || region.config.perimeters == 0
- || region.config.fill_density == 0
+ if (!region.config().extra_perimeters
+ || region.config().perimeters == 0
+ || region.config().fill_density == 0
|| this->layer_count() < 2)
continue;
BOOST_LOG_TRIVIAL(debug) << "Generating extra perimeters for region " << region_id << " in parallel - start";
tbb::parallel_for(
- tbb::blocked_range<size_t>(0, this->layers.size() - 1),
+ tbb::blocked_range<size_t>(0, m_layers.size() - 1),
[this, &region, region_id](const tbb::blocked_range<size_t>& range) {
for (size_t layer_idx = range.begin(); layer_idx < range.end(); ++ layer_idx) {
- this->_print->throw_if_canceled();
- LayerRegion &layerm = *this->layers[layer_idx]->regions[region_id];
- const LayerRegion &upper_layerm = *this->layers[layer_idx+1]->regions[region_id];
+ m_print->throw_if_canceled();
+ LayerRegion &layerm = *m_layers[layer_idx]->m_regions[region_id];
+ const LayerRegion &upper_layerm = *m_layers[layer_idx+1]->m_regions[region_id];
const Polygons upper_layerm_polygons = upper_layerm.slices;
// Filter upper layer polygons in intersection_ppl by their bounding boxes?
// my $upper_layerm_poly_bboxes= [ map $_->bounding_box, @{$upper_layerm_polygons} ];
@@ -198,7 +197,7 @@ void PrintObject::make_perimeters()
for (;;) {
// compute the total thickness of perimeters
const coord_t perimeters_thickness = ext_perimeter_width/2 + ext_perimeter_spacing/2
- + (region.config.perimeters-1 + slice.extra_perimeters) * perimeter_spacing;
+ + (region.config().perimeters-1 + slice.extra_perimeters) * perimeter_spacing;
// define a critical area where we don't want the upper slice to fall into
// (it should either lay over our perimeters or outside this area)
const coord_t critical_area_depth = coord_t(perimeter_spacing * 1.5);
@@ -231,21 +230,21 @@ void PrintObject::make_perimeters()
}
}
});
- this->_print->throw_if_canceled();
+ m_print->throw_if_canceled();
BOOST_LOG_TRIVIAL(debug) << "Generating extra perimeters for region " << region_id << " in parallel - end";
}
BOOST_LOG_TRIVIAL(debug) << "Generating perimeters in parallel - start";
tbb::parallel_for(
- tbb::blocked_range<size_t>(0, this->layers.size()),
+ tbb::blocked_range<size_t>(0, m_layers.size()),
[this](const tbb::blocked_range<size_t>& range) {
for (size_t layer_idx = range.begin(); layer_idx < range.end(); ++ layer_idx) {
- this->_print->throw_if_canceled();
- this->layers[layer_idx]->make_perimeters();
+ m_print->throw_if_canceled();
+ m_layers[layer_idx]->make_perimeters();
}
}
);
- this->_print->throw_if_canceled();
+ m_print->throw_if_canceled();
BOOST_LOG_TRIVIAL(debug) << "Generating perimeters in parallel - end";
/*
@@ -255,7 +254,7 @@ void PrintObject::make_perimeters()
###$self->_simplify_slices(&Slic3r::SCALED_RESOLUTION);
*/
- m_state.set_done(posPerimeters);
+ this->set_done(posPerimeters);
}
void PrintObject::prepare_infill()
@@ -264,23 +263,23 @@ void PrintObject::prepare_infill()
return;
this->set_started(posPrepareInfill);
- this->_print->set_status(30, "Preparing infill");
+ m_print->set_status(30, "Preparing infill");
// This will assign a type (top/bottom/internal) to $layerm->slices.
// Then the classifcation of $layerm->slices is transfered onto
// the $layerm->fill_surfaces by clipping $layerm->fill_surfaces
// by the cummulative area of the previous $layerm->fill_surfaces.
this->detect_surfaces_type();
- this->_print->throw_if_canceled();
+ m_print->throw_if_canceled();
// Decide what surfaces are to be filled.
// Here the S_TYPE_TOP / S_TYPE_BOTTOMBRIDGE / S_TYPE_BOTTOM infill is turned to just S_TYPE_INTERNAL if zero top / bottom infill layers are configured.
// Also tiny S_TYPE_INTERNAL surfaces are turned to S_TYPE_INTERNAL_SOLID.
BOOST_LOG_TRIVIAL(info) << "Preparing fill surfaces...";
- for (auto *layer : this->layers)
- for (auto *region : layer->regions) {
+ for (auto *layer : m_layers)
+ for (auto *region : layer->m_regions) {
region->prepare_fill_surfaces();
- this->_print->throw_if_canceled();
+ m_print->throw_if_canceled();
}
// this will detect bridges and reverse bridges
@@ -293,17 +292,17 @@ void PrintObject::prepare_infill()
// 4) Merge surfaces with the same style. This will mostly get rid of the overlaps.
//FIXME This does not likely merge surfaces, which are supported by a material with different colors, but same properties.
this->process_external_surfaces();
- this->_print->throw_if_canceled();
+ m_print->throw_if_canceled();
// Add solid fills to ensure the shell vertical thickness.
this->discover_vertical_shells();
- this->_print->throw_if_canceled();
+ m_print->throw_if_canceled();
// Debugging output.
#ifdef SLIC3R_DEBUG_SLICE_PROCESSING
- for (size_t region_id = 0; region_id < this->print()->regions.size(); ++ region_id) {
- for (const Layer *layer : this->layers) {
- LayerRegion *layerm = layer->regions[region_id];
+ for (size_t region_id = 0; region_id < this->print()->regions().size(); ++ region_id) {
+ for (const Layer *layer : m_layers) {
+ LayerRegion *layerm = layer->m_regions[region_id];
layerm->export_region_slices_to_svg_debug("6_discover_vertical_shells-final");
layerm->export_region_fill_surfaces_to_svg_debug("6_discover_vertical_shells-final");
} // for each layer
@@ -317,12 +316,12 @@ void PrintObject::prepare_infill()
// to close these surfaces reliably.
//FIXME Vojtech: Is this a good place to add supporting infills below sloping perimeters?
this->discover_horizontal_shells();
- this->_print->throw_if_canceled();
+ m_print->throw_if_canceled();
#ifdef SLIC3R_DEBUG_SLICE_PROCESSING
- for (size_t region_id = 0; region_id < this->print()->regions.size(); ++ region_id) {
- for (const Layer *layer : this->layers) {
- LayerRegion *layerm = layer->regions[region_id];
+ for (size_t region_id = 0; region_id < this->print()->regions().size(); ++ region_id) {
+ for (const Layer *layer : m_layers) {
+ LayerRegion *layerm = layer->m_regions[region_id];
layerm->export_region_slices_to_svg_debug("7_discover_horizontal_shells-final");
layerm->export_region_fill_surfaces_to_svg_debug("7_discover_horizontal_shells-final");
} // for each layer
@@ -336,12 +335,12 @@ void PrintObject::prepare_infill()
// Likely the sparse infill will not be anchored correctly, so it will not work as intended.
// Also one wishes the perimeters to be supported by a full infill.
this->clip_fill_surfaces();
- this->_print->throw_if_canceled();
+ m_print->throw_if_canceled();
#ifdef SLIC3R_DEBUG_SLICE_PROCESSING
- for (size_t region_id = 0; region_id < this->print()->regions.size(); ++ region_id) {
- for (const Layer *layer : this->layers) {
- LayerRegion *layerm = layer->regions[region_id];
+ for (size_t region_id = 0; region_id < this->print()->regions().size(); ++ region_id) {
+ for (const Layer *layer : m_layers) {
+ LayerRegion *layerm = layer->m_regions[region_id];
layerm->export_region_slices_to_svg_debug("8_clip_surfaces-final");
layerm->export_region_fill_surfaces_to_svg_debug("8_clip_surfaces-final");
} // for each layer
@@ -351,27 +350,27 @@ void PrintObject::prepare_infill()
// the following step needs to be done before combination because it may need
// to remove only half of the combined infill
this->bridge_over_infill();
- this->_print->throw_if_canceled();
+ m_print->throw_if_canceled();
// combine fill surfaces to honor the "infill every N layers" option
this->combine_infill();
- this->_print->throw_if_canceled();
+ m_print->throw_if_canceled();
#ifdef SLIC3R_DEBUG_SLICE_PROCESSING
- for (size_t region_id = 0; region_id < this->print()->regions.size(); ++ region_id) {
- for (const Layer *layer : this->layers) {
- LayerRegion *layerm = layer->regions[region_id];
+ for (size_t region_id = 0; region_id < this->print()->regions().size(); ++ region_id) {
+ for (const Layer *layer : m_layers) {
+ LayerRegion *layerm = layer->m_regions[region_id];
layerm->export_region_slices_to_svg_debug("9_prepare_infill-final");
layerm->export_region_fill_surfaces_to_svg_debug("9_prepare_infill-final");
} // for each layer
} // for each region
- for (const Layer *layer : this->layers) {
+ for (const Layer *layer : m_layers) {
layer->export_region_slices_to_svg_debug("9_prepare_infill-final");
layer->export_region_fill_surfaces_to_svg_debug("9_prepare_infill-final");
} // for each layer
#endif /* SLIC3R_DEBUG_SLICE_PROCESSING */
- m_state.set_done(posPrepareInfill);
+ this->set_done(posPrepareInfill);
}
void PrintObject::infill()
@@ -383,20 +382,20 @@ void PrintObject::infill()
this->set_started(posInfill);
BOOST_LOG_TRIVIAL(debug) << "Filling layers in parallel - start";
tbb::parallel_for(
- tbb::blocked_range<size_t>(0, this->layers.size()),
+ tbb::blocked_range<size_t>(0, m_layers.size()),
[this](const tbb::blocked_range<size_t>& range) {
for (size_t layer_idx = range.begin(); layer_idx < range.end(); ++ layer_idx) {
- this->_print->throw_if_canceled();
- this->layers[layer_idx]->make_fills();
+ m_print->throw_if_canceled();
+ m_layers[layer_idx]->make_fills();
}
}
);
- this->_print->throw_if_canceled();
+ m_print->throw_if_canceled();
BOOST_LOG_TRIVIAL(debug) << "Filling layers in parallel - end";
/* we could free memory now, but this would make this step not idempotent
### $_->fill_surfaces->clear for map @{$_->regions}, @{$object->layers};
*/
- m_state.set_done(posInfill);
+ this->set_done(posInfill);
}
}
@@ -405,39 +404,44 @@ void PrintObject::generate_support_material()
if (! m_state.is_done(posSupportMaterial)) {
this->set_started(posSupportMaterial);
this->clear_support_layers();
- if ((this->config.support_material || this->config.raft_layers > 0) && this->layers.size() > 1) {
- this->_print->set_status(85, "Generating support material");
+ if ((m_config.support_material || m_config.raft_layers > 0) && m_layers.size() > 1) {
+ m_print->set_status(85, "Generating support material");
this->_generate_support_material();
- this->_print->throw_if_canceled();
+ m_print->throw_if_canceled();
}
- m_state.set_done(posSupportMaterial);
+ this->set_done(posSupportMaterial);
}
}
void PrintObject::clear_layers()
{
- for (Layer *l : this->layers)
+ for (Layer *l : m_layers)
delete l;
- this->layers.clear();
+ m_layers.clear();
}
Layer* PrintObject::add_layer(int id, coordf_t height, coordf_t print_z, coordf_t slice_z)
{
- layers.push_back(new Layer(id, this, height, print_z, slice_z));
- return layers.back();
+ m_layers.emplace_back(new Layer(id, this, height, print_z, slice_z));
+ return m_layers.back();
}
void PrintObject::clear_support_layers()
{
- for (Layer *l : this->support_layers)
+ for (Layer *l : m_support_layers)
delete l;
- this->support_layers.clear();
+ m_support_layers.clear();
}
SupportLayer* PrintObject::add_support_layer(int id, coordf_t height, coordf_t print_z)
{
- support_layers.emplace_back(new SupportLayer(id, this, height, print_z, -1));
- return support_layers.back();
+ m_support_layers.emplace_back(new SupportLayer(id, this, height, print_z, -1));
+ return m_support_layers.back();
+}
+
+SupportLayerPtrs::const_iterator PrintObject::insert_support_layer(SupportLayerPtrs::const_iterator pos, int id, coordf_t height, coordf_t print_z, coordf_t slice_z)
+{
+ return m_support_layers.insert(pos, new SupportLayer(id, this, height, print_z, slice_z));
}
// Called by Print::apply_config().
@@ -545,8 +549,8 @@ bool PrintObject::invalidate_state_by_config_options(const std::vector<t_config_
// these options only affect G-code export, so nothing to invalidate
} else {
// for legacy, if we can't handle this option let's invalidate all steps
+ this->invalidate_all_steps();
this->reset_layer_height_profile();
- this->invalidate_all_steps();
invalidated = true;
}
}
@@ -559,37 +563,42 @@ bool PrintObject::invalidate_state_by_config_options(const std::vector<t_config_
bool PrintObject::invalidate_step(PrintObjectStep step)
{
- bool invalidated = m_state.invalidate(step);
+ bool invalidated = m_state.invalidate(step, m_print->m_mutex, m_print->m_cancel_callback);
// propagate to dependent steps
if (step == posPerimeters) {
invalidated |= this->invalidate_step(posPrepareInfill);
- invalidated |= this->_print->invalidate_step(psSkirt);
- invalidated |= this->_print->invalidate_step(psBrim);
+ invalidated |= m_print->invalidate_step(psSkirt);
+ invalidated |= m_print->invalidate_step(psBrim);
} else if (step == posPrepareInfill) {
invalidated |= this->invalidate_step(posInfill);
} else if (step == posInfill) {
- invalidated |= this->_print->invalidate_step(psSkirt);
- invalidated |= this->_print->invalidate_step(psBrim);
+ invalidated |= m_print->invalidate_step(psSkirt);
+ invalidated |= m_print->invalidate_step(psBrim);
} else if (step == posSlice) {
invalidated |= this->invalidate_step(posPerimeters);
invalidated |= this->invalidate_step(posSupportMaterial);
- invalidated |= this->_print->invalidate_step(psWipeTower);
+ invalidated |= m_print->invalidate_step(psWipeTower);
} else if (step == posSupportMaterial) {
- invalidated |= this->_print->invalidate_step(psSkirt);
- invalidated |= this->_print->invalidate_step(psBrim);
+ invalidated |= m_print->invalidate_step(psSkirt);
+ invalidated |= m_print->invalidate_step(psBrim);
}
// Wipe tower depends on the ordering of extruders, which in turn depends on everything.
- invalidated |= this->_print->invalidate_step(psWipeTower);
+ invalidated |= m_print->invalidate_step(psWipeTower);
return invalidated;
}
+bool PrintObject::invalidate_all_steps()
+{
+ return m_state.invalidate_all(m_print->m_mutex, m_print->m_cancel_callback);
+}
+
bool PrintObject::has_support_material() const
{
- return this->config.support_material
- || this->config.raft_layers > 0
- || this->config.support_material_enforce_layers > 0;
+ return m_config.support_material
+ || m_config.raft_layers > 0
+ || m_config.support_material_enforce_layers > 0;
}
// This function analyzes slices of a region (SurfaceCollection slices).
@@ -610,42 +619,42 @@ void PrintObject::detect_surfaces_type()
// are completely hidden inside a collective body of intersecting parts.
// This is useful if one of the parts is to be dissolved, or if it is transparent and the internal shells
// should be visible.
- bool interface_shells = this->config.interface_shells.value;
+ bool interface_shells = m_config.interface_shells.value;
- for (int idx_region = 0; idx_region < this->_print->regions.size(); ++ idx_region) {
+ for (int idx_region = 0; idx_region < m_print->m_regions.size(); ++ idx_region) {
BOOST_LOG_TRIVIAL(debug) << "Detecting solid surfaces for region " << idx_region << " in parallel - start";
#ifdef SLIC3R_DEBUG_SLICE_PROCESSING
- for (Layer *layer : this->layers)
- layer->regions[idx_region]->export_region_fill_surfaces_to_svg_debug("1_detect_surfaces_type-initial");
+ for (Layer *layer : m_layers)
+ layer->m_regions[idx_region]->export_region_fill_surfaces_to_svg_debug("1_detect_surfaces_type-initial");
#endif /* SLIC3R_DEBUG_SLICE_PROCESSING */
// If interface shells are allowed, the region->surfaces cannot be overwritten as they may be used by other threads.
// Cache the result of the following parallel_loop.
std::vector<Surfaces> surfaces_new;
if (interface_shells)
- surfaces_new.assign(this->layers.size(), Surfaces());
+ surfaces_new.assign(m_layers.size(), Surfaces());
tbb::parallel_for(
- tbb::blocked_range<size_t>(0, this->layers.size()),
+ tbb::blocked_range<size_t>(0, m_layers.size()),
[this, idx_region, interface_shells, &surfaces_new](const tbb::blocked_range<size_t>& range) {
// If we have raft layers, consider bottom layer as a bridge just like any other bottom surface lying on the void.
SurfaceType surface_type_bottom_1st =
- (this->config.raft_layers.value > 0 && this->config.support_material_contact_distance.value > 0) ?
+ (m_config.raft_layers.value > 0 && m_config.support_material_contact_distance.value > 0) ?
stBottomBridge : stBottom;
// If we have soluble support material, don't bridge. The overhang will be squished against a soluble layer separating
// the support from the print.
SurfaceType surface_type_bottom_other =
- (this->config.support_material.value && this->config.support_material_contact_distance.value == 0) ?
+ (m_config.support_material.value && m_config.support_material_contact_distance.value == 0) ?
stBottom : stBottomBridge;
for (size_t idx_layer = range.begin(); idx_layer < range.end(); ++ idx_layer) {
- this->_print->throw_if_canceled();
+ m_print->throw_if_canceled();
// BOOST_LOG_TRIVIAL(trace) << "Detecting solid surfaces for region " << idx_region << " and layer " << layer->print_z;
- Layer *layer = this->layers[idx_layer];
+ Layer *layer = m_layers[idx_layer];
LayerRegion *layerm = layer->get_region(idx_region);
// comparison happens against the *full* slices (considering all regions)
// unless internal shells are requested
- Layer *upper_layer = (idx_layer + 1 < this->layer_count()) ? this->layers[idx_layer + 1] : nullptr;
- Layer *lower_layer = (idx_layer > 0) ? this->layers[idx_layer - 1] : nullptr;
+ Layer *upper_layer = (idx_layer + 1 < this->layer_count()) ? m_layers[idx_layer + 1] : nullptr;
+ Layer *lower_layer = (idx_layer > 0) ? m_layers[idx_layer - 1] : nullptr;
// collapse very narrow parts (using the safety offset in the diff is not enough)
float offset = layerm->flow(frExternalPerimeter).scaled_width() / 10.f;
@@ -763,29 +772,29 @@ void PrintObject::detect_surfaces_type()
}
}
); // for each layer of a region
- this->_print->throw_if_canceled();
+ m_print->throw_if_canceled();
if (interface_shells) {
// Move surfaces_new to layerm->slices.surfaces
- for (size_t idx_layer = 0; idx_layer < this->layers.size(); ++ idx_layer)
- this->layers[idx_layer]->get_region(idx_region)->slices.surfaces = std::move(surfaces_new[idx_layer]);
+ for (size_t idx_layer = 0; idx_layer < m_layers.size(); ++ idx_layer)
+ m_layers[idx_layer]->get_region(idx_region)->slices.surfaces = std::move(surfaces_new[idx_layer]);
}
BOOST_LOG_TRIVIAL(debug) << "Detecting solid surfaces for region " << idx_region << " - clipping in parallel - start";
// Fill in layerm->fill_surfaces by trimming the layerm->slices by the cummulative layerm->fill_surfaces.
tbb::parallel_for(
- tbb::blocked_range<size_t>(0, this->layers.size()),
+ tbb::blocked_range<size_t>(0, m_layers.size()),
[this, idx_region, interface_shells, &surfaces_new](const tbb::blocked_range<size_t>& range) {
for (size_t idx_layer = range.begin(); idx_layer < range.end(); ++ idx_layer) {
- this->_print->throw_if_canceled();
- LayerRegion *layerm = this->layers[idx_layer]->get_region(idx_region);
+ m_print->throw_if_canceled();
+ LayerRegion *layerm = m_layers[idx_layer]->get_region(idx_region);
layerm->slices_to_fill_surfaces_clipped();
#ifdef SLIC3R_DEBUG_SLICE_PROCESSING
layerm->export_region_fill_surfaces_to_svg_debug("1_detect_surfaces_type-final");
#endif /* SLIC3R_DEBUG_SLICE_PROCESSING */
} // for each layer of a region
});
- this->_print->throw_if_canceled();
+ m_print->throw_if_canceled();
BOOST_LOG_TRIVIAL(debug) << "Detecting solid surfaces for region " << idx_region << " - clipping in parallel - end";
} // for each this->print->region_count
@@ -797,21 +806,21 @@ void PrintObject::process_external_surfaces()
{
BOOST_LOG_TRIVIAL(info) << "Processing external surfaces...";
- FOREACH_REGION(this->_print, region) {
- int region_id = int(region - this->_print->regions.begin());
+ for (size_t region_id = 0; region_id < m_print->regions().size(); ++ region_id) {
+ const PrintRegion &region = *m_print->regions()[region_id];
BOOST_LOG_TRIVIAL(debug) << "Processing external surfaces for region " << region_id << " in parallel - start";
tbb::parallel_for(
- tbb::blocked_range<size_t>(0, this->layers.size()),
+ tbb::blocked_range<size_t>(0, m_layers.size()),
[this, region_id](const tbb::blocked_range<size_t>& range) {
for (size_t layer_idx = range.begin(); layer_idx < range.end(); ++ layer_idx) {
- this->_print->throw_if_canceled();
- // BOOST_LOG_TRIVIAL(trace) << "Processing external surface, layer" << this->layers[layer_idx]->print_z;
- this->layers[layer_idx]->get_region(region_id)->process_external_surfaces((layer_idx == 0) ? NULL : this->layers[layer_idx - 1]);
+ m_print->throw_if_canceled();
+ // BOOST_LOG_TRIVIAL(trace) << "Processing external surface, layer" << m_layers[layer_idx]->print_z;
+ m_layers[layer_idx]->get_region(region_id)->process_external_surfaces((layer_idx == 0) ? NULL : m_layers[layer_idx - 1]);
}
}
);
- this->_print->throw_if_canceled();
+ m_print->throw_if_canceled();
BOOST_LOG_TRIVIAL(debug) << "Processing external surfaces for region " << region_id << " in parallel - end";
}
}
@@ -829,17 +838,17 @@ void PrintObject::discover_vertical_shells()
Polygons bottom_surfaces;
Polygons holes;
};
- std::vector<DiscoverVerticalShellsCacheEntry> cache_top_botom_regions(this->layers.size(), DiscoverVerticalShellsCacheEntry());
- bool top_bottom_surfaces_all_regions = this->_print->regions.size() > 1 && ! this->config.interface_shells.value;
+ std::vector<DiscoverVerticalShellsCacheEntry> cache_top_botom_regions(m_layers.size(), DiscoverVerticalShellsCacheEntry());
+ bool top_bottom_surfaces_all_regions = m_print->regions().size() > 1 && ! m_config.interface_shells.value;
if (top_bottom_surfaces_all_regions) {
// This is a multi-material print and interface_shells are disabled, meaning that the vertical shell thickness
// is calculated over all materials.
// Is the "ensure vertical wall thickness" applicable to any region?
bool has_extra_layers = false;
- for (size_t idx_region = 0; idx_region < this->_print->regions.size(); ++ idx_region) {
- const PrintRegion &region = *this->_print->get_region(idx_region);
- if (region.config.ensure_vertical_shell_thickness.value &&
- (region.config.top_solid_layers.value > 1 || region.config.bottom_solid_layers.value > 1)) {
+ for (size_t idx_region = 0; idx_region < m_print->regions().size(); ++ idx_region) {
+ const PrintRegion &region = *m_print->get_region(idx_region);
+ if (region.config().ensure_vertical_shell_thickness.value &&
+ (region.config().top_solid_layers.value > 1 || region.config().bottom_solid_layers.value > 1)) {
has_extra_layers = true;
}
}
@@ -848,15 +857,15 @@ void PrintObject::discover_vertical_shells()
return;
BOOST_LOG_TRIVIAL(debug) << "Discovering vertical shells in parallel - start : cache top / bottom";
//FIXME Improve the heuristics for a grain size.
- size_t grain_size = std::max(this->layers.size() / 16, size_t(1));
+ size_t grain_size = std::max(m_layers.size() / 16, size_t(1));
tbb::parallel_for(
- tbb::blocked_range<size_t>(0, this->layers.size(), grain_size),
+ tbb::blocked_range<size_t>(0, m_layers.size(), grain_size),
[this, &cache_top_botom_regions](const tbb::blocked_range<size_t>& range) {
const SurfaceType surfaces_bottom[2] = { stBottom, stBottomBridge };
- const size_t num_regions = this->_print->regions.size();
+ const size_t num_regions = m_print->regions().size();
for (size_t idx_layer = range.begin(); idx_layer < range.end(); ++ idx_layer) {
- this->_print->throw_if_canceled();
- const Layer &layer = *this->layers[idx_layer];
+ m_print->throw_if_canceled();
+ const Layer &layer = *m_layers[idx_layer];
DiscoverVerticalShellsCacheEntry &cache = cache_top_botom_regions[idx_layer];
// Simulate single set of perimeters over all merged regions.
float perimeter_offset = 0.f;
@@ -866,7 +875,7 @@ void PrintObject::discover_vertical_shells()
++ debug_idx;
#endif /* SLIC3R_DEBUG_SLICE_PROCESSING */
for (size_t idx_region = 0; idx_region < num_regions; ++ idx_region) {
- LayerRegion &layerm = *layer.regions[idx_region];
+ LayerRegion &layerm = *layer.m_regions[idx_region];
float min_perimeter_infill_spacing = float(layerm.flow(frSolidInfill).scaled_spacing()) * 1.05f;
// Top surfaces.
append(cache.top_surfaces, offset(to_expolygons(layerm.slices.filter_by_type(stTop)), min_perimeter_infill_spacing));
@@ -879,7 +888,7 @@ void PrintObject::discover_vertical_shells()
unsigned int perimeters = 0;
for (Surface &s : layerm.slices.surfaces)
perimeters = std::max<unsigned int>(perimeters, s.extra_perimeters);
- perimeters += layerm.region()->config.perimeters.value;
+ perimeters += layerm.region()->config().perimeters.value;
// Then calculate the infill offset.
if (perimeters > 0) {
Flow extflow = layerm.flow(frExternalPerimeter);
@@ -910,38 +919,38 @@ void PrintObject::discover_vertical_shells()
cache.holes = union_(cache.holes, false);
}
});
- this->_print->throw_if_canceled();
+ m_print->throw_if_canceled();
BOOST_LOG_TRIVIAL(debug) << "Discovering vertical shells in parallel - end : cache top / bottom";
}
- for (size_t idx_region = 0; idx_region < this->_print->regions.size(); ++ idx_region) {
+ for (size_t idx_region = 0; idx_region < m_print->regions().size(); ++ idx_region) {
PROFILE_BLOCK(discover_vertical_shells_region);
- const PrintRegion &region = *this->_print->get_region(idx_region);
- if (! region.config.ensure_vertical_shell_thickness.value)
+ const PrintRegion &region = *m_print->get_region(idx_region);
+ if (! region.config().ensure_vertical_shell_thickness.value)
// This region will be handled by discover_horizontal_shells().
continue;
- int n_extra_top_layers = std::max(0, region.config.top_solid_layers.value - 1);
- int n_extra_bottom_layers = std::max(0, region.config.bottom_solid_layers.value - 1);
+ int n_extra_top_layers = std::max(0, region.config().top_solid_layers.value - 1);
+ int n_extra_bottom_layers = std::max(0, region.config().bottom_solid_layers.value - 1);
if (n_extra_top_layers + n_extra_bottom_layers == 0)
// Zero or 1 layer, there is no additional vertical wall thickness enforced.
continue;
//FIXME Improve the heuristics for a grain size.
- size_t grain_size = std::max(this->layers.size() / 16, size_t(1));
+ size_t grain_size = std::max(m_layers.size() / 16, size_t(1));
if (! top_bottom_surfaces_all_regions) {
// This is either a single material print, or a multi-material print and interface_shells are enabled, meaning that the vertical shell thickness
// is calculated over a single material.
BOOST_LOG_TRIVIAL(debug) << "Discovering vertical shells for region " << idx_region << " in parallel - start : cache top / bottom";
tbb::parallel_for(
- tbb::blocked_range<size_t>(0, this->layers.size(), grain_size),
+ tbb::blocked_range<size_t>(0, m_layers.size(), grain_size),
[this, idx_region, &cache_top_botom_regions](const tbb::blocked_range<size_t>& range) {
const SurfaceType surfaces_bottom[2] = { stBottom, stBottomBridge };
for (size_t idx_layer = range.begin(); idx_layer < range.end(); ++ idx_layer) {
- this->_print->throw_if_canceled();
- Layer &layer = *this->layers[idx_layer];
- LayerRegion &layerm = *layer.regions[idx_region];
+ m_print->throw_if_canceled();
+ Layer &layer = *m_layers[idx_layer];
+ LayerRegion &layerm = *layer.m_regions[idx_region];
float min_perimeter_infill_spacing = float(layerm.flow(frSolidInfill).scaled_spacing()) * 1.05f;
// Top surfaces.
auto &cache = cache_top_botom_regions[idx_layer];
@@ -952,31 +961,31 @@ void PrintObject::discover_vertical_shells()
append(cache.bottom_surfaces, offset(to_expolygons(layerm.fill_surfaces.filter_by_types(surfaces_bottom, 2)), min_perimeter_infill_spacing));
// Holes over all regions. Only collect them once, they are valid for all idx_region iterations.
if (cache.holes.empty()) {
- for (size_t idx_region = 0; idx_region < layer.regions.size(); ++ idx_region)
- polygons_append(cache.holes, to_polygons(layer.regions[idx_region]->fill_expolygons));
+ for (size_t idx_region = 0; idx_region < layer.regions().size(); ++ idx_region)
+ polygons_append(cache.holes, to_polygons(layer.regions()[idx_region]->fill_expolygons));
}
}
});
- this->_print->throw_if_canceled();
+ m_print->throw_if_canceled();
BOOST_LOG_TRIVIAL(debug) << "Discovering vertical shells for region " << idx_region << " in parallel - end : cache top / bottom";
}
BOOST_LOG_TRIVIAL(debug) << "Discovering vertical shells for region " << idx_region << " in parallel - start : ensure vertical wall thickness";
tbb::parallel_for(
- tbb::blocked_range<size_t>(0, this->layers.size(), grain_size),
+ tbb::blocked_range<size_t>(0, m_layers.size(), grain_size),
[this, idx_region, n_extra_top_layers, n_extra_bottom_layers, &cache_top_botom_regions]
(const tbb::blocked_range<size_t>& range) {
// printf("discover_vertical_shells from %d to %d\n", range.begin(), range.end());
for (size_t idx_layer = range.begin(); idx_layer < range.end(); ++ idx_layer) {
PROFILE_BLOCK(discover_vertical_shells_region_layer);
- this->_print->throw_if_canceled();
+ m_print->throw_if_canceled();
#ifdef SLIC3R_DEBUG_SLICE_PROCESSING
static size_t debug_idx = 0;
++ debug_idx;
#endif /* SLIC3R_DEBUG_SLICE_PROCESSING */
- Layer *layer = this->layers[idx_layer];
- LayerRegion *layerm = layer->regions[idx_region];
+ Layer *layer = m_layers[idx_layer];
+ LayerRegion *layerm = layer->m_regions[idx_region];
#ifdef SLIC3R_DEBUG_SLICE_PROCESSING
layerm->export_region_slices_to_svg_debug("4_discover_vertical_shells-initial");
@@ -999,9 +1008,9 @@ void PrintObject::discover_vertical_shells()
{
Slic3r::SVG svg_cummulative(debug_out_path("discover_vertical_shells-perimeters-before-union-run%d.svg", debug_idx), this->bounding_box());
for (int n = (int)idx_layer - n_extra_bottom_layers; n <= (int)idx_layer + n_extra_top_layers; ++ n) {
- if (n < 0 || n >= (int)this->layers.size())
+ if (n < 0 || n >= (int)m_layers.size())
continue;
- ExPolygons &expolys = this->layers[n]->perimeter_expolygons;
+ ExPolygons &expolys = m_layers[n]->perimeter_expolygons;
for (size_t i = 0; i < expolys.size(); ++ i) {
Slic3r::SVG svg(debug_out_path("discover_vertical_shells-perimeters-before-union-run%d-layer%d-expoly%d.svg", debug_idx, n, i), get_extents(expolys[i]));
svg.draw(expolys[i]);
@@ -1019,8 +1028,8 @@ void PrintObject::discover_vertical_shells()
// Reset the top / bottom inflated regions caches of entries, which are out of the moving window.
bool hole_first = true;
for (int n = (int)idx_layer - n_extra_bottom_layers; n <= (int)idx_layer + n_extra_top_layers; ++ n)
- if (n >= 0 && n < (int)this->layers.size()) {
- Layer &neighbor_layer = *this->layers[n];
+ if (n >= 0 && n < (int)m_layers.size()) {
+ Layer &neighbor_layer = *m_layers[n];
const DiscoverVerticalShellsCacheEntry &cache = cache_top_botom_regions[n];
if (hole_first) {
hole_first = false;
@@ -1183,12 +1192,12 @@ void PrintObject::discover_vertical_shells()
layerm->fill_surfaces.append(new_internal_solid, stInternalSolid);
} // for each layer
});
- this->_print->throw_if_canceled();
+ m_print->throw_if_canceled();
BOOST_LOG_TRIVIAL(debug) << "Discovering vertical shells for region " << idx_region << " in parallel - end";
#ifdef SLIC3R_DEBUG_SLICE_PROCESSING
- for (size_t idx_layer = 0; idx_layer < this->layers.size(); ++idx_layer) {
- LayerRegion *layerm = this->layers[idx_layer]->get_region(idx_region);
+ for (size_t idx_layer = 0; idx_layer < m_layers.size(); ++idx_layer) {
+ LayerRegion *layerm = m_layers[idx_layer]->get_region(idx_region);
layerm->export_region_slices_to_svg_debug("4_discover_vertical_shells-final");
layerm->export_region_fill_surfaces_to_svg_debug("4_discover_vertical_shells-final");
}
@@ -1206,14 +1215,14 @@ void PrintObject::bridge_over_infill()
{
BOOST_LOG_TRIVIAL(info) << "Bridge over infill...";
- FOREACH_REGION(this->_print, region) {
- size_t region_id = region - this->_print->regions.begin();
+ for (size_t region_id = 0; region_id < m_print->regions().size(); ++ region_id) {
+ const PrintRegion &region = *m_print->regions()[region_id];
// skip bridging in case there are no voids
- if ((*region)->config.fill_density.value == 100) continue;
+ if (region.config().fill_density.value == 100) continue;
// get bridge flow
- Flow bridge_flow = (*region)->flow(
+ Flow bridge_flow = region.flow(
frSolidInfill,
-1, // layer height, not relevant for bridge flow
true, // bridge
@@ -1224,10 +1233,10 @@ void PrintObject::bridge_over_infill()
FOREACH_LAYER(this, layer_it) {
// skip first layer
- if (layer_it == this->layers.begin()) continue;
+ if (layer_it == m_layers.begin()) continue;
Layer* layer = *layer_it;
- LayerRegion* layerm = layer->regions[region_id];
+ LayerRegion* layerm = layer->m_regions[region_id];
// extract the stInternalSolid surfaces that might be transformed into bridges
Polygons internal_solid;
@@ -1242,8 +1251,8 @@ void PrintObject::bridge_over_infill()
// iterate through lower layers spanned by bridge_flow
double bottom_z = layer->print_z - bridge_flow.height;
- for (int i = int(layer_it - this->layers.begin()) - 1; i >= 0; --i) {
- const Layer* lower_layer = this->layers[i];
+ for (int i = int(layer_it - m_layers.begin()) - 1; i >= 0; --i) {
+ const Layer* lower_layer = m_layers[i];
// stop iterating if layer is lower than bottom_z
if (lower_layer->print_z < bottom_z) break;
@@ -1323,7 +1332,7 @@ void PrintObject::bridge_over_infill()
layerm->export_region_slices_to_svg_debug("7_bridge_over_infill");
layerm->export_region_fill_surfaces_to_svg_debug("7_bridge_over_infill");
#endif /* SLIC3R_DEBUG_SLICE_PROCESSING */
- this->_print->throw_if_canceled();
+ m_print->throw_if_canceled();
}
}
}
@@ -1331,7 +1340,7 @@ void PrintObject::bridge_over_infill()
SlicingParameters PrintObject::slicing_parameters() const
{
return SlicingParameters::create_from_config(
- this->print()->config, this->config,
+ this->print()->config(), m_config,
unscale(this->size.z), this->print()->object_extruders());
}
@@ -1422,39 +1431,39 @@ void PrintObject::_slice()
layer->lower_layer = prev;
}
// Make sure all layers contain layer region objects for all regions.
- for (size_t region_id = 0; region_id < this->print()->regions.size(); ++ region_id)
- layer->add_region(this->print()->regions[region_id]);
+ for (size_t region_id = 0; region_id < this->print()->regions().size(); ++ region_id)
+ layer->add_region(this->print()->regions()[region_id]);
prev = layer;
}
}
// Slice all non-modifier volumes.
- for (size_t region_id = 0; region_id < this->print()->regions.size(); ++ region_id) {
+ for (size_t region_id = 0; region_id < this->print()->regions().size(); ++ region_id) {
BOOST_LOG_TRIVIAL(debug) << "Slicing objects - region " << region_id;
std::vector<ExPolygons> expolygons_by_layer = this->_slice_region(region_id, slice_zs, false);
- this->_print->throw_if_canceled();
+ m_print->throw_if_canceled();
BOOST_LOG_TRIVIAL(debug) << "Slicing objects - append slices " << region_id << " start";
for (size_t layer_id = 0; layer_id < expolygons_by_layer.size(); ++ layer_id)
- this->layers[layer_id]->regions[region_id]->slices.append(std::move(expolygons_by_layer[layer_id]), stInternal);
- this->_print->throw_if_canceled();
+ m_layers[layer_id]->regions()[region_id]->slices.append(std::move(expolygons_by_layer[layer_id]), stInternal);
+ m_print->throw_if_canceled();
BOOST_LOG_TRIVIAL(debug) << "Slicing objects - append slices " << region_id << " end";
}
// Slice all modifier volumes.
- if (this->print()->regions.size() > 1) {
- for (size_t region_id = 0; region_id < this->print()->regions.size(); ++ region_id) {
+ if (this->print()->regions().size() > 1) {
+ for (size_t region_id = 0; region_id < this->print()->regions().size(); ++ region_id) {
BOOST_LOG_TRIVIAL(debug) << "Slicing modifier volumes - region " << region_id;
std::vector<ExPolygons> expolygons_by_layer = this->_slice_region(region_id, slice_zs, true);
- this->_print->throw_if_canceled();
+ m_print->throw_if_canceled();
// loop through the other regions and 'steal' the slices belonging to this one
BOOST_LOG_TRIVIAL(debug) << "Slicing modifier volumes - stealing " << region_id << " start";
- for (size_t other_region_id = 0; other_region_id < this->print()->regions.size(); ++ other_region_id) {
+ for (size_t other_region_id = 0; other_region_id < this->print()->regions().size(); ++ other_region_id) {
if (region_id == other_region_id)
continue;
for (size_t layer_id = 0; layer_id < expolygons_by_layer.size(); ++ layer_id) {
- Layer *layer = layers[layer_id];
- LayerRegion *layerm = layer->regions[region_id];
- LayerRegion *other_layerm = layer->regions[other_region_id];
+ Layer *layer = this->layers()[layer_id];
+ LayerRegion *layerm = layer->m_regions[region_id];
+ LayerRegion *other_layerm = layer->m_regions[other_region_id];
if (layerm == nullptr || other_layerm == nullptr)
continue;
Polygons other_slices = to_polygons(other_layerm->slices);
@@ -1467,59 +1476,59 @@ void PrintObject::_slice()
layerm->slices.append(std::move(my_parts), stInternal);
}
}
- this->_print->throw_if_canceled();
+ m_print->throw_if_canceled();
BOOST_LOG_TRIVIAL(debug) << "Slicing modifier volumes - stealing " << region_id << " end";
}
}
BOOST_LOG_TRIVIAL(debug) << "Slicing objects - removing top empty layers";
- while (! this->layers.empty()) {
- const Layer *layer = this->layers.back();
- for (size_t region_id = 0; region_id < this->print()->regions.size(); ++ region_id)
- if (layer->regions[region_id] != nullptr && ! layer->regions[region_id]->slices.empty())
+ while (! m_layers.empty()) {
+ const Layer *layer = m_layers.back();
+ for (size_t region_id = 0; region_id < this->print()->regions().size(); ++ region_id)
+ if (layer->m_regions[region_id] != nullptr && ! layer->m_regions[region_id]->slices.empty())
// Non empty layer.
goto end;
delete layer;
- this->layers.pop_back();
- if (! this->layers.empty())
- this->layers.back()->upper_layer = nullptr;
+ m_layers.pop_back();
+ if (! m_layers.empty())
+ m_layers.back()->upper_layer = nullptr;
}
- this->_print->throw_if_canceled();
+ m_print->throw_if_canceled();
end:
;
BOOST_LOG_TRIVIAL(debug) << "Slicing objects - make_slices in parallel - begin";
tbb::parallel_for(
- tbb::blocked_range<size_t>(0, this->layers.size()),
+ tbb::blocked_range<size_t>(0, m_layers.size()),
[this](const tbb::blocked_range<size_t>& range) {
for (size_t layer_id = range.begin(); layer_id < range.end(); ++ layer_id) {
- this->_print->throw_if_canceled();
- Layer *layer = this->layers[layer_id];
+ m_print->throw_if_canceled();
+ Layer *layer = m_layers[layer_id];
// Apply size compensation and perform clipping of multi-part objects.
- float delta = float(scale_(this->config.xy_size_compensation.value));
+ float delta = float(scale_(m_config.xy_size_compensation.value));
if (layer_id == 0)
- delta -= float(scale_(this->config.elefant_foot_compensation.value));
+ delta -= float(scale_(m_config.elefant_foot_compensation.value));
bool scale = delta != 0.f;
- bool clip = this->config.clip_multipart_objects.value || delta > 0.f;
- if (layer->regions.size() == 1) {
+ bool clip = m_config.clip_multipart_objects.value || delta > 0.f;
+ if (layer->m_regions.size() == 1) {
if (scale) {
// Single region, growing or shrinking.
- LayerRegion *layerm = layer->regions.front();
+ LayerRegion *layerm = layer->m_regions.front();
layerm->slices.set(offset_ex(to_expolygons(std::move(layerm->slices.surfaces)), delta), stInternal);
}
} else if (scale || clip) {
// Multiple regions, growing, shrinking or just clipping one region by the other.
// When clipping the regions, priority is given to the first regions.
Polygons processed;
- for (size_t region_id = 0; region_id < layer->regions.size(); ++ region_id) {
- LayerRegion *layerm = layer->regions[region_id];
+ for (size_t region_id = 0; region_id < layer->m_regions.size(); ++ region_id) {
+ LayerRegion *layerm = layer->m_regions[region_id];
ExPolygons slices = to_expolygons(std::move(layerm->slices.surfaces));
if (scale)
slices = offset_ex(slices, delta);
if (region_id > 0 && clip)
// Trim by the slices of already processed regions.
slices = diff_ex(to_polygons(std::move(slices)), processed);
- if (clip && region_id + 1 < layer->regions.size())
+ if (clip && region_id + 1 < layer->m_regions.size())
// Collect the already processed regions to trim the to be processed regions.
polygons_append(processed, slices);
layerm->slices.set(std::move(slices), stInternal);
@@ -1529,7 +1538,7 @@ end:
layer->make_slices();
}
});
- this->_print->throw_if_canceled();
+ m_print->throw_if_canceled();
BOOST_LOG_TRIVIAL(debug) << "Slicing objects - make_slices in parallel - end";
}
@@ -1546,7 +1555,7 @@ std::vector<ExPolygons> PrintObject::_slice_region(size_t region_id, const std::
ModelVolume *volume = this->model_object()->volumes[volume_id];
if (volume->modifier == modifier)
mesh.merge(volume->mesh);
- this->_print->throw_if_canceled();
+ m_print->throw_if_canceled();
}
if (mesh.stl.stats.number_of_facets > 0) {
// transform mesh
@@ -1561,7 +1570,7 @@ std::vector<ExPolygons> PrintObject::_slice_region(size_t region_id, const std::
auto callback = TriangleMeshSlicer::throw_on_cancel_callback_type([print](){print->throw_if_canceled();});
mslicer.init(&mesh, callback);
mslicer.slice(z, &layers, callback);
- this->_print->throw_if_canceled();
+ m_print->throw_if_canceled();
}
}
}
@@ -1573,9 +1582,9 @@ std::string PrintObject::_fix_slicing_errors()
// Collect layers with slicing errors.
// These layers will be fixed in parallel.
std::vector<size_t> buggy_layers;
- buggy_layers.reserve(this->layers.size());
- for (size_t idx_layer = 0; idx_layer < this->layers.size(); ++ idx_layer)
- if (this->layers[idx_layer]->slicing_errors)
+ buggy_layers.reserve(m_layers.size());
+ for (size_t idx_layer = 0; idx_layer < m_layers.size(); ++ idx_layer)
+ if (m_layers[idx_layer]->slicing_errors)
buggy_layers.push_back(idx_layer);
BOOST_LOG_TRIVIAL(debug) << "Slicing objects - fixing slicing errors in parallel - begin";
@@ -1583,25 +1592,25 @@ std::string PrintObject::_fix_slicing_errors()
tbb::blocked_range<size_t>(0, buggy_layers.size()),
[this, &buggy_layers](const tbb::blocked_range<size_t>& range) {
for (size_t buggy_layer_idx = range.begin(); buggy_layer_idx < range.end(); ++ buggy_layer_idx) {
- this->_print->throw_if_canceled();
+ m_print->throw_if_canceled();
size_t idx_layer = buggy_layers[buggy_layer_idx];
- Layer *layer = this->layers[idx_layer];
+ Layer *layer = m_layers[idx_layer];
assert(layer->slicing_errors);
// Try to repair the layer surfaces by merging all contours and all holes from neighbor layers.
// BOOST_LOG_TRIVIAL(trace) << "Attempting to repair layer" << idx_layer;
- for (size_t region_id = 0; region_id < layer->regions.size(); ++ region_id) {
- LayerRegion *layerm = layer->regions[region_id];
+ for (size_t region_id = 0; region_id < layer->m_regions.size(); ++ region_id) {
+ LayerRegion *layerm = layer->m_regions[region_id];
// Find the first valid layer below / above the current layer.
const Surfaces *upper_surfaces = nullptr;
const Surfaces *lower_surfaces = nullptr;
- for (size_t j = idx_layer + 1; j < this->layers.size(); ++ j)
- if (! this->layers[j]->slicing_errors) {
- upper_surfaces = &this->layers[j]->regions[region_id]->slices.surfaces;
+ for (size_t j = idx_layer + 1; j < m_layers.size(); ++ j)
+ if (! m_layers[j]->slicing_errors) {
+ upper_surfaces = &m_layers[j]->regions()[region_id]->slices.surfaces;
break;
}
for (int j = int(idx_layer) - 1; j >= 0; -- j)
- if (! this->layers[j]->slicing_errors) {
- lower_surfaces = &this->layers[j]->regions[region_id]->slices.surfaces;
+ if (! m_layers[j]->slicing_errors) {
+ lower_surfaces = &m_layers[j]->regions()[region_id]->slices.surfaces;
break;
}
// Collect outer contours and holes from the valid layers above & below.
@@ -1634,16 +1643,16 @@ std::string PrintObject::_fix_slicing_errors()
layer->make_slices();
}
});
- this->_print->throw_if_canceled();
+ m_print->throw_if_canceled();
BOOST_LOG_TRIVIAL(debug) << "Slicing objects - fixing slicing errors in parallel - end";
// remove empty layers from bottom
- while (! this->layers.empty() && this->layers.front()->slices.expolygons.empty()) {
- delete this->layers.front();
- this->layers.erase(this->layers.begin());
- this->layers.front()->lower_layer = nullptr;
- for (size_t i = 0; i < this->layers.size(); ++ i)
- this->layers[i]->set_id(this->layers[i]->id() - 1);
+ while (! m_layers.empty() && m_layers.front()->slices.expolygons.empty()) {
+ delete m_layers.front();
+ m_layers.erase(m_layers.begin());
+ m_layers.front()->lower_layer = nullptr;
+ for (size_t i = 0; i < m_layers.size(); ++ i)
+ m_layers[i]->set_id(m_layers[i]->id() - 1);
}
return buggy_layers.empty() ? "" :
@@ -1658,13 +1667,13 @@ void PrintObject::_simplify_slices(double distance)
{
BOOST_LOG_TRIVIAL(debug) << "Slicing objects - siplifying slices in parallel - begin";
tbb::parallel_for(
- tbb::blocked_range<size_t>(0, this->layers.size()),
+ tbb::blocked_range<size_t>(0, m_layers.size()),
[this, distance](const tbb::blocked_range<size_t>& range) {
for (size_t layer_idx = range.begin(); layer_idx < range.end(); ++ layer_idx) {
- this->_print->throw_if_canceled();
- Layer *layer = this->layers[layer_idx];
- for (size_t region_idx = 0; region_idx < layer->regions.size(); ++ region_idx)
- layer->regions[region_idx]->slices.simplify(distance);
+ m_print->throw_if_canceled();
+ Layer *layer = m_layers[layer_idx];
+ for (size_t region_idx = 0; region_idx < layer->m_regions.size(); ++ region_idx)
+ layer->m_regions[region_idx]->slices.simplify(distance);
layer->slices.simplify(distance);
}
});
@@ -1681,18 +1690,18 @@ void PrintObject::_simplify_slices(double distance)
// fill_surfaces but we only turn them into VOID surfaces, thus preserving the boundaries.
void PrintObject::clip_fill_surfaces()
{
- if (! this->config.infill_only_where_needed.value ||
- ! std::any_of(this->print()->regions.begin(), this->print()->regions.end(),
- [](const PrintRegion *region) { return region->config.fill_density > 0; }))
+ if (! m_config.infill_only_where_needed.value ||
+ ! std::any_of(this->print()->regions().begin(), this->print()->regions().end(),
+ [](const PrintRegion *region) { return region->config().fill_density > 0; }))
return;
// We only want infill under ceilings; this is almost like an
// internal support material.
// Proceed top-down, skipping the bottom layer.
Polygons upper_internal;
- for (int layer_id = int(this->layers.size()) - 1; layer_id > 0; -- layer_id) {
- Layer *layer = this->layers[layer_id];
- Layer *lower_layer = this->layers[layer_id - 1];
+ for (int layer_id = int(m_layers.size()) - 1; layer_id > 0; -- layer_id) {
+ Layer *layer = m_layers[layer_id];
+ Layer *lower_layer = m_layers[layer_id - 1];
// Detect things that we need to support.
// Cummulative slices.
Polygons slices;
@@ -1702,7 +1711,7 @@ void PrintObject::clip_fill_surfaces()
Polygons fill_surfaces;
// Solid surfaces to be supported.
Polygons overhangs;
- for (const LayerRegion *layerm : layer->regions)
+ for (const LayerRegion *layerm : layer->m_regions)
for (const Surface &surface : layerm->fill_surfaces.surfaces) {
Polygons polygons = to_polygons(surface.expolygon);
if (surface.is_solid())
@@ -1711,7 +1720,7 @@ void PrintObject::clip_fill_surfaces()
}
Polygons lower_layer_fill_surfaces;
Polygons lower_layer_internal_surfaces;
- for (const LayerRegion *layerm : lower_layer->regions)
+ for (const LayerRegion *layerm : lower_layer->m_regions)
for (const Surface &surface : layerm->fill_surfaces.surfaces) {
Polygons polygons = to_polygons(surface.expolygon);
if (surface.surface_type == stInternal || surface.surface_type == stInternalVoid)
@@ -1727,7 +1736,7 @@ void PrintObject::clip_fill_surfaces()
//FIXME Offset2 eats out from both sides, while the perimeters are create outside in.
//Should the pw not be half of the current value?
float pw = FLT_MAX;
- for (const LayerRegion *layerm : layer->regions)
+ for (const LayerRegion *layerm : layer->m_regions)
pw = std::min<float>(pw, layerm->flow(frPerimeter).scaled_width());
// Append such thick perimeters to the areas that need support
polygons_append(overhangs, offset2(perimeters, -pw, +pw));
@@ -1736,8 +1745,8 @@ void PrintObject::clip_fill_surfaces()
polygons_append(overhangs, std::move(upper_internal));
upper_internal = intersection(overhangs, lower_layer_internal_surfaces);
// Apply new internal infill to regions.
- for (LayerRegion *layerm : lower_layer->regions) {
- if (layerm->region()->config.fill_density.value == 0)
+ for (LayerRegion *layerm : lower_layer->m_regions) {
+ if (layerm->region()->config().fill_density.value == 0)
continue;
SurfaceType internal_surface_types[] = { stInternal, stInternalVoid };
Polygons internal;
@@ -1754,7 +1763,7 @@ void PrintObject::clip_fill_surfaces()
layerm->export_region_fill_surfaces_to_svg_debug("6_clip_fill_surfaces");
#endif
}
- this->_print->throw_if_canceled();
+ m_print->throw_if_canceled();
}
}
@@ -1762,11 +1771,11 @@ void PrintObject::discover_horizontal_shells()
{
BOOST_LOG_TRIVIAL(trace) << "discover_horizontal_shells()";
- for (size_t region_id = 0; region_id < this->print()->regions.size(); ++ region_id) {
- for (int i = 0; i < int(this->layers.size()); ++ i) {
- this->_print->throw_if_canceled();
- LayerRegion *layerm = this->layers[i]->regions[region_id];
- PrintRegionConfig &region_config = layerm->region()->config;
+ for (size_t region_id = 0; region_id < this->print()->regions().size(); ++ region_id) {
+ for (int i = 0; i < int(m_layers.size()); ++ i) {
+ m_print->throw_if_canceled();
+ LayerRegion *layerm = m_layers[i]->regions()[region_id];
+ const PrintRegionConfig &region_config = layerm->region()->config();
if (region_config.solid_infill_every_layers.value > 0 && region_config.fill_density.value > 0 &&
(i % region_config.solid_infill_every_layers) == 0) {
// Insert a solid internal layer. Mark stInternal surfaces as stInternalSolid or stInternalBridge.
@@ -1781,7 +1790,7 @@ void PrintObject::discover_horizontal_shells()
continue;
for (int idx_surface_type = 0; idx_surface_type < 3; ++ idx_surface_type) {
- this->_print->throw_if_canceled();
+ m_print->throw_if_canceled();
SurfaceType type = (idx_surface_type == 0) ? stTop : (idx_surface_type == 1) ? stBottom : stBottomBridge;
// Find slices of current type for current layer.
// Use slices instead of fill_surfaces, because they also include the perimeter area,
@@ -1810,11 +1819,11 @@ void PrintObject::discover_horizontal_shells()
size_t solid_layers = (type == stTop) ? region_config.top_solid_layers.value : region_config.bottom_solid_layers.value;
for (int n = (type == stTop) ? i-1 : i+1; std::abs(n - i) < solid_layers; (type == stTop) ? -- n : ++ n) {
- if (n < 0 || n >= int(this->layers.size()))
+ if (n < 0 || n >= int(m_layers.size()))
continue;
// Slic3r::debugf " looking for neighbors on layer %d...\n", $n;
// Reference to the lower layer of a TOP surface, or an upper layer of a BOTTOM surface.
- LayerRegion *neighbor_layerm = this->layers[n]->regions[region_id];
+ LayerRegion *neighbor_layerm = m_layers[n]->regions()[region_id];
// find intersection between neighbor and current layer's surfaces
// intersections have contours and holes
@@ -1936,9 +1945,9 @@ void PrintObject::discover_horizontal_shells()
} // for each region
#ifdef SLIC3R_DEBUG_SLICE_PROCESSING
- for (size_t region_id = 0; region_id < this->print()->regions.size(); ++ region_id) {
- for (const Layer *layer : this->layers) {
- const LayerRegion *layerm = layer->regions[region_id];
+ for (size_t region_id = 0; region_id < this->print()->regions().size(); ++ region_id) {
+ for (const Layer *layer : m_layers) {
+ const LayerRegion *layerm = layer->m_regions[region_id];
layerm->export_region_slices_to_svg_debug("5_discover_horizontal_shells");
layerm->export_region_fill_surfaces_to_svg_debug("5_discover_horizontal_shells");
} // for each layer
@@ -1952,24 +1961,24 @@ void PrintObject::discover_horizontal_shells()
void PrintObject::combine_infill()
{
// Work on each region separately.
- for (size_t region_id = 0; region_id < this->print()->regions.size(); ++ region_id) {
- const PrintRegion *region = this->print()->regions[region_id];
- const int every = region->config.infill_every_layers.value;
- if (every < 2 || region->config.fill_density == 0.)
+ for (size_t region_id = 0; region_id < this->print()->regions().size(); ++ region_id) {
+ const PrintRegion *region = this->print()->regions()[region_id];
+ const int every = region->config().infill_every_layers.value;
+ if (every < 2 || region->config().fill_density == 0.)
continue;
// Limit the number of combined layers to the maximum height allowed by this regions' nozzle.
//FIXME limit the layer height to max_layer_height
double nozzle_diameter = std::min(
- this->print()->config.nozzle_diameter.get_at(region->config.infill_extruder.value - 1),
- this->print()->config.nozzle_diameter.get_at(region->config.solid_infill_extruder.value - 1));
+ this->print()->config().nozzle_diameter.get_at(region->config().infill_extruder.value - 1),
+ this->print()->config().nozzle_diameter.get_at(region->config().solid_infill_extruder.value - 1));
// define the combinations
- std::vector<size_t> combine(this->layers.size(), 0);
+ std::vector<size_t> combine(m_layers.size(), 0);
{
double current_height = 0.;
size_t num_layers = 0;
- for (size_t layer_idx = 0; layer_idx < this->layers.size(); ++ layer_idx) {
- this->_print->throw_if_canceled();
- const Layer *layer = this->layers[layer_idx];
+ for (size_t layer_idx = 0; layer_idx < m_layers.size(); ++ layer_idx) {
+ m_print->throw_if_canceled();
+ const Layer *layer = m_layers[layer_idx];
if (layer->id() == 0)
// Skip first print layer (which may not be first layer in array because of raft).
continue;
@@ -1986,12 +1995,12 @@ void PrintObject::combine_infill()
}
// Append lower layers (if any) to uppermost layer.
- combine[this->layers.size() - 1] = num_layers;
+ combine[m_layers.size() - 1] = num_layers;
}
// loop through layers to which we have assigned layers to combine
- for (size_t layer_idx = 0; layer_idx < this->layers.size(); ++ layer_idx) {
- this->_print->throw_if_canceled();
+ for (size_t layer_idx = 0; layer_idx < m_layers.size(); ++ layer_idx) {
+ m_print->throw_if_canceled();
size_t num_layers = combine[layer_idx];
if (num_layers <= 1)
continue;
@@ -1999,7 +2008,7 @@ void PrintObject::combine_infill()
std::vector<LayerRegion*> layerms;
layerms.reserve(num_layers);
for (size_t i = layer_idx + 1 - num_layers; i <= layer_idx; ++ i)
- layerms.emplace_back(this->layers[i]->regions[region_id]);
+ layerms.emplace_back(m_layers[i]->regions()[region_id]);
// We need to perform a multi-layer intersection, so let's split it in pairs.
// Initialize the intersection with the candidates of the lowest layer.
ExPolygons intersection = to_expolygons(layerms.front()->fill_surfaces.filter_by_type(stInternal));
@@ -2028,10 +2037,10 @@ void PrintObject::combine_infill()
0.5f * layerms.back()->flow(frPerimeter).scaled_width() +
// Because fill areas for rectilinear and honeycomb are grown
// later to overlap perimeters, we need to counteract that too.
- ((region->config.fill_pattern == ipRectilinear ||
- region->config.fill_pattern == ipGrid ||
- region->config.fill_pattern == ipLine ||
- region->config.fill_pattern == ipHoneycomb) ? 1.5f : 0.5f) *
+ ((region->config().fill_pattern == ipRectilinear ||
+ region->config().fill_pattern == ipGrid ||
+ region->config().fill_pattern == ipLine ||
+ region->config().fill_pattern == ipHoneycomb) ? 1.5f : 0.5f) *
layerms.back()->flow(frSolidInfill).scaled_width();
for (ExPolygon &expoly : intersection)
polygons_append(intersection_with_clearance, offset(expoly, clearance_offset));
diff --git a/xs/src/libslic3r/PrintRegion.cpp b/xs/src/libslic3r/PrintRegion.cpp
index 2fcf69166..cdc8c532a 100644
--- a/xs/src/libslic3r/PrintRegion.cpp
+++ b/xs/src/libslic3r/PrintRegion.cpp
@@ -12,48 +12,48 @@ Flow PrintRegion::flow(FlowRole role, double layer_height, bool bridge, bool fir
} else {
// otherwise, get extrusion width from configuration
// (might be an absolute value, or a percent value, or zero for auto)
- if (first_layer && this->_print->config.first_layer_extrusion_width.value > 0) {
- config_width = this->_print->config.first_layer_extrusion_width;
+ if (first_layer && m_print->config().first_layer_extrusion_width.value > 0) {
+ config_width = m_print->config().first_layer_extrusion_width;
} else if (role == frExternalPerimeter) {
- config_width = this->config.external_perimeter_extrusion_width;
+ config_width = m_config.external_perimeter_extrusion_width;
} else if (role == frPerimeter) {
- config_width = this->config.perimeter_extrusion_width;
+ config_width = m_config.perimeter_extrusion_width;
} else if (role == frInfill) {
- config_width = this->config.infill_extrusion_width;
+ config_width = m_config.infill_extrusion_width;
} else if (role == frSolidInfill) {
- config_width = this->config.solid_infill_extrusion_width;
+ config_width = m_config.solid_infill_extrusion_width;
} else if (role == frTopSolidInfill) {
- config_width = this->config.top_infill_extrusion_width;
+ config_width = m_config.top_infill_extrusion_width;
} else {
CONFESS("Unknown role");
}
}
if (config_width.value == 0) {
- config_width = object.config.extrusion_width;
+ config_width = object.config().extrusion_width;
}
// get the configured nozzle_diameter for the extruder associated
// to the flow role requested
size_t extruder = 0; // 1-based
if (role == frPerimeter || role == frExternalPerimeter) {
- extruder = this->config.perimeter_extruder;
+ extruder = m_config.perimeter_extruder;
} else if (role == frInfill) {
- extruder = this->config.infill_extruder;
+ extruder = m_config.infill_extruder;
} else if (role == frSolidInfill || role == frTopSolidInfill) {
- extruder = this->config.solid_infill_extruder;
+ extruder = m_config.solid_infill_extruder;
} else {
CONFESS("Unknown role $role");
}
- double nozzle_diameter = this->_print->config.nozzle_diameter.get_at(extruder-1);
+ double nozzle_diameter = m_print->config().nozzle_diameter.get_at(extruder-1);
- return Flow::new_from_config_width(role, config_width, nozzle_diameter, layer_height, bridge ? (float)this->config.bridge_flow_ratio : 0.0);
+ return Flow::new_from_config_width(role, config_width, nozzle_diameter, layer_height, bridge ? (float)m_config.bridge_flow_ratio : 0.0);
}
coordf_t PrintRegion::nozzle_dmr_avg(const PrintConfig &print_config) const
{
- return (print_config.nozzle_diameter.get_at(this->config.perimeter_extruder.value - 1) +
- print_config.nozzle_diameter.get_at(this->config.infill_extruder.value - 1) +
- print_config.nozzle_diameter.get_at(this->config.solid_infill_extruder.value - 1)) / 3.;
+ return (print_config.nozzle_diameter.get_at(m_config.perimeter_extruder.value - 1) +
+ print_config.nozzle_diameter.get_at(m_config.infill_extruder.value - 1) +
+ print_config.nozzle_diameter.get_at(m_config.solid_infill_extruder.value - 1)) / 3.;
}
}
diff --git a/xs/src/libslic3r/SupportMaterial.cpp b/xs/src/libslic3r/SupportMaterial.cpp
index 0cecf0014..d18f9d710 100644
--- a/xs/src/libslic3r/SupportMaterial.cpp
+++ b/xs/src/libslic3r/SupportMaterial.cpp
@@ -142,8 +142,8 @@ void export_print_z_polygons_and_extrusions_to_svg(
PrintObjectSupportMaterial::PrintObjectSupportMaterial(const PrintObject *object, const SlicingParameters &slicing_params) :
m_object (object),
- m_print_config (&object->print()->config),
- m_object_config (&object->config),
+ m_print_config (&object->print()->config()),
+ m_object_config (&object->config()),
m_slicing_params (slicing_params),
m_first_layer_flow (support_material_1st_layer_flow(object, float(slicing_params.first_print_layer_height))),
m_support_material_flow (support_material_flow(object, float(slicing_params.layer_height))),
@@ -164,7 +164,7 @@ PrintObjectSupportMaterial::PrintObjectSupportMaterial(const PrintObject *object
coordf_t external_perimeter_width = 0.;
for (size_t region_id = 0; region_id < object->region_volumes.size(); ++ region_id) {
if (! object->region_volumes[region_id].empty()) {
- const PrintRegionConfig &config = object->print()->get_region(region_id)->config;
+ const PrintRegionConfig &config = object->print()->get_region(region_id)->config();
coordf_t width = config.external_perimeter_extrusion_width.get_abs_value(slicing_params.layer_height);
if (width <= 0.)
width = m_print_config->nozzle_diameter.get_at(config.perimeter_extruder-1);
@@ -226,7 +226,7 @@ void PrintObjectSupportMaterial::generate(PrintObject &object)
coordf_t max_object_layer_height = 0.;
for (size_t i = 0; i < object.layer_count(); ++ i)
- max_object_layer_height = std::max(max_object_layer_height, object.layers[i]->height);
+ max_object_layer_height = std::max(max_object_layer_height, object.layers()[i]->height);
// Layer instances will be allocated by std::deque and they will be kept until the end of this function call.
// The layers will be referenced by various LayersPtr (of type std::vector<Layer*>)
@@ -266,9 +266,9 @@ void PrintObjectSupportMaterial::generate(PrintObject &object)
layer_support_areas);
#ifdef SLIC3R_DEBUG
- for (size_t layer_id = 0; layer_id < object.layers.size(); ++ layer_id)
+ for (size_t layer_id = 0; layer_id < object.layers().size(); ++ layer_id)
Slic3r::SVG::export_expolygons(
- debug_out_path("support-areas-%d-%lf.svg", iRun, object.layers[layer_id]->print_z),
+ debug_out_path("support-areas-%d-%lf.svg", iRun, object.layers()[layer_id]->print_z),
union_ex(layer_support_areas[layer_id], false));
#endif /* SLIC3R_DEBUG */
@@ -354,7 +354,7 @@ void PrintObjectSupportMaterial::generate(PrintObject &object)
// Sort the layers lexicographically by a raising print_z and a decreasing height.
std::sort(layers_sorted.begin(), layers_sorted.end(), MyLayersPtrCompare());
int layer_id = 0;
- assert(object.support_layers.empty());
+ assert(object.support_layers().empty());
for (int i = 0; i < int(layers_sorted.size());) {
// Find the last layer with roughly the same print_z, find the minimum layer height of all.
// Due to the floating point inaccuracies, the print_z may not be the same even if in theory they should.
@@ -420,8 +420,8 @@ Polygons collect_region_slices_by_type(const Layer &layer, SurfaceType surface_t
{
// 1) Count the new polygons first.
size_t n_polygons_new = 0;
- for (LayerRegionPtrs::const_iterator it_region = layer.regions.begin(); it_region != layer.regions.end(); ++ it_region) {
- const LayerRegion &region = *(*it_region);
+ for (const LayerRegion* pregion : layer.regions()) {
+ const LayerRegion &region = *pregion;
const SurfaceCollection &slices = region.slices;
for (Surfaces::const_iterator it = slices.surfaces.begin(); it != slices.surfaces.end(); ++ it) {
const Surface &surface = *it;
@@ -433,8 +433,8 @@ Polygons collect_region_slices_by_type(const Layer &layer, SurfaceType surface_t
// 2) Collect the new polygons.
Polygons out;
out.reserve(n_polygons_new);
- for (LayerRegionPtrs::const_iterator it_region = layer.regions.begin(); it_region != layer.regions.end(); ++ it_region) {
- const LayerRegion &region = *(*it_region);
+ for (const LayerRegion *pregion : layer.regions()) {
+ const LayerRegion &region = *pregion;
const SurfaceCollection &slices = region.slices;
for (Surfaces::const_iterator it = slices.surfaces.begin(); it != slices.surfaces.end(); ++ it) {
const Surface &surface = *it;
@@ -658,9 +658,9 @@ PrintObjectSupportMaterial::MyLayersPtr PrintObjectSupportMaterial::top_contact_
std::vector<Polygons> buildplate_covered;
if (buildplate_only) {
BOOST_LOG_TRIVIAL(debug) << "PrintObjectSupportMaterial::top_contact_layers() - collecting regions covering the print bed.";
- buildplate_covered.assign(object.layers.size(), Polygons());
- for (size_t layer_id = 1; layer_id < object.layers.size(); ++ layer_id) {
- const Layer &lower_layer = *object.layers[layer_id-1];
+ buildplate_covered.assign(object.layers().size(), Polygons());
+ for (size_t layer_id = 1; layer_id < object.layers().size(); ++ layer_id) {
+ const Layer &lower_layer = *object.layers()[layer_id-1];
// Merge the new slices with the preceding slices.
// Apply the safety offset to the newly added polygons, so they will connect
// with the polygons collected before,
@@ -686,7 +686,7 @@ PrintObjectSupportMaterial::MyLayersPtr PrintObjectSupportMaterial::top_contact_
[this, &object, &buildplate_covered, threshold_rad, &layer_storage, &layer_storage_mutex, &contact_out](const tbb::blocked_range<size_t>& range) {
for (size_t layer_id = range.begin(); layer_id < range.end(); ++ layer_id)
{
- const Layer &layer = *object.layers[layer_id];
+ const Layer &layer = *object.layers()[layer_id];
// Detect overhangs and contact areas needed to support them.
// Collect overhangs and contacts of all regions of this layer supported by the layer immediately below.
@@ -703,13 +703,13 @@ PrintObjectSupportMaterial::MyLayersPtr PrintObjectSupportMaterial::top_contact_
contact_polygons = offset(overhang_polygons, scale_(SUPPORT_MATERIAL_MARGIN));
} else {
// Generate overhang / contact_polygons for non-raft layers.
- const Layer &lower_layer = *object.layers[layer_id-1];
- for (LayerRegion *layerm : layer.regions) {
+ const Layer &lower_layer = *object.layers()[layer_id-1];
+ for (LayerRegion *layerm : layer.regions()) {
// Extrusion width accounts for the roundings of the extrudates.
// It is the maximum widh of the extrudate.
float fw = float(layerm->flow(frExternalPerimeter).scaled_width());
float lower_layer_offset =
- (layer_id < this->m_object_config->support_material_enforce_layers.value) ?
+ (layer_id < m_object_config->support_material_enforce_layers.value) ?
// Enforce a full possible support, ignore the overhang angle.
0.f :
(threshold_rad > 0. ?
@@ -762,14 +762,14 @@ PrintObjectSupportMaterial::MyLayersPtr PrintObjectSupportMaterial::top_contact_
}
#endif /* SLIC3R_DEBUG */
- if (this->m_object_config->dont_support_bridges) {
+ if (m_object_config->dont_support_bridges) {
// compute the area of bridging perimeters
// Note: this is duplicate code from GCode.pm, we need to refactor
if (true) {
Polygons bridged_perimeters;
{
Flow bridge_flow = layerm->flow(frPerimeter, true);
- coordf_t nozzle_diameter = m_print_config->nozzle_diameter.get_at(layerm->region()->config.perimeter_extruder-1);
+ coordf_t nozzle_diameter = m_print_config->nozzle_diameter.get_at(layerm->region()->config().perimeter_extruder-1);
Polygons lower_grown_slices = offset(lower_layer_polygons, 0.5f*float(scale_(nozzle_diameter)), SUPPORT_SURFACES_OFFSET_PARAMETERS);
// Collect perimeters of this layer.
@@ -894,8 +894,8 @@ PrintObjectSupportMaterial::MyLayersPtr PrintObjectSupportMaterial::top_contact_
} else {
// Interface layer will be synchronized with the object.
assert(layer_id > 0);
- new_layer.height = object.layers[layer_id - 1]->height;
- new_layer.bottom_z = (layer_id == 1) ? m_slicing_params.object_print_z_min : object.layers[layer_id - 2]->print_z;
+ new_layer.height = object.layers()[layer_id - 1]->height;
+ new_layer.bottom_z = (layer_id == 1) ? m_slicing_params.object_print_z_min : object.layers()[layer_id - 2]->print_z;
}
} else {
// Contact layer will be printed with a normal flow, but
@@ -904,9 +904,9 @@ PrintObjectSupportMaterial::MyLayersPtr PrintObjectSupportMaterial::top_contact_
// In the future we may switch to a normal extrusion flow for the supported bridges.
// Get the average nozzle diameter used on this layer.
coordf_t nozzle_dmr = 0.;
- for (const LayerRegion *region : layer.regions)
+ for (const LayerRegion *region : layer.regions())
nozzle_dmr += region->region()->nozzle_dmr_avg(*m_print_config);
- nozzle_dmr /= coordf_t(layer.regions.size());
+ nozzle_dmr /= coordf_t(layer.regions().size());
new_layer.print_z = layer.print_z - nozzle_dmr - m_object_config->support_material_contact_distance;
new_layer.bottom_z = new_layer.print_z;
new_layer.height = 0.;
@@ -1048,10 +1048,10 @@ PrintObjectSupportMaterial::MyLayersPtr PrintObjectSupportMaterial::bottom_conta
// top shapes so this can be done here
layer_new.height = m_slicing_params.soluble_interface ?
// Align the interface layer with the object's layer height.
- object.layers[layer_id + 1]->height :
+ object.layers()[layer_id + 1]->height :
// Place a bridge flow interface layer over the top surface.
m_support_material_interface_flow.nozzle_diameter;
- layer_new.print_z = m_slicing_params.soluble_interface ? object.layers[layer_id + 1]->print_z :
+ layer_new.print_z = m_slicing_params.soluble_interface ? object.layers()[layer_id + 1]->print_z :
layer.print_z + layer_new.height + m_object_config->support_material_contact_distance.value;
layer_new.bottom_z = layer.print_z;
layer_new.idx_object_layer_below = layer_id;
@@ -1062,16 +1062,16 @@ PrintObjectSupportMaterial::MyLayersPtr PrintObjectSupportMaterial::bottom_conta
// Walk the top surfaces, snap the top of the new bottom surface to the closest top of the top surface,
// so there will be no support surfaces generated with thickness lower than m_support_layer_height_min.
for (size_t top_idx = size_t(std::max<int>(0, contact_idx));
- top_idx < top_contacts.size() && top_contacts[top_idx]->print_z < layer_new.print_z + this->m_support_layer_height_min;
+ top_idx < top_contacts.size() && top_contacts[top_idx]->print_z < layer_new.print_z + m_support_layer_height_min;
++ top_idx) {
- if (top_contacts[top_idx]->print_z > layer_new.print_z - this->m_support_layer_height_min) {
+ if (top_contacts[top_idx]->print_z > layer_new.print_z - m_support_layer_height_min) {
// A top layer has been found, which is close to the new bottom layer.
coordf_t diff = layer_new.print_z - top_contacts[top_idx]->print_z;
- assert(std::abs(diff) <= this->m_support_layer_height_min);
+ assert(std::abs(diff) <= m_support_layer_height_min);
if (diff > 0.) {
// The top contact layer is below this layer. Make the bridging layer thinner to align with the existing top layer.
assert(diff < layer_new.height + EPSILON);
- assert(layer_new.height - diff >= this->m_support_layer_height_min - EPSILON);
+ assert(layer_new.height - diff >= m_support_layer_height_min - EPSILON);
layer_new.print_z = top_contacts[top_idx]->print_z;
layer_new.height -= diff;
} else {
@@ -1093,7 +1093,7 @@ PrintObjectSupportMaterial::MyLayersPtr PrintObjectSupportMaterial::bottom_conta
// Trim the already created base layers above the current layer intersecting with the new bottom contacts layer.
touching = offset(touching, float(SCALED_EPSILON));
for (int layer_id_above = layer_id + 1; layer_id_above < int(object.total_layer_count()); ++ layer_id_above) {
- const Layer &layer_above = *object.layers[layer_id_above];
+ const Layer &layer_above = *object.layers()[layer_id_above];
if (layer_above.print_z > layer_new.print_z + EPSILON)
break;
if (! layer_support_areas[layer_id_above].empty()) {
@@ -1320,7 +1320,7 @@ PrintObjectSupportMaterial::MyLayersPtr PrintObjectSupportMaterial::raft_and_int
// Verify that the extremes are separated by m_support_layer_height_min.
for (size_t i = 1; i < extremes.size(); ++ i) {
assert(extremes[i]->extreme_z() - extremes[i-1]->extreme_z() == 0. ||
- extremes[i]->extreme_z() - extremes[i-1]->extreme_z() > this->m_support_layer_height_min - EPSILON);
+ extremes[i]->extreme_z() - extremes[i-1]->extreme_z() > m_support_layer_height_min - EPSILON);
assert(extremes[i]->extreme_z() - extremes[i-1]->extreme_z() > 0. ||
extremes[i]->layer_type == extremes[i-1]->layer_type ||
(extremes[i]->layer_type == sltBottomContact && extremes[i - 1]->layer_type == sltTopContact));
@@ -1344,7 +1344,7 @@ PrintObjectSupportMaterial::MyLayersPtr PrintObjectSupportMaterial::raft_and_int
// This is a bottom of a synchronized (or soluble) top contact layer, its height has been decided in this->top_contact_layers().
assert(extr2->layer_type == sltTopContact);
assert(extr2->bottom_z == m_slicing_params.first_print_layer_height);
- assert(extr2->print_z >= m_slicing_params.first_print_layer_height + this->m_support_layer_height_min - EPSILON);
+ assert(extr2->print_z >= m_slicing_params.first_print_layer_height + m_support_layer_height_min - EPSILON);
if (intermediate_layers.empty() || intermediate_layers.back()->print_z < m_slicing_params.first_print_layer_height) {
MyLayer &layer_new = layer_allocate(layer_storage, sltIntermediate);
layer_new.bottom_z = 0.;
@@ -1384,7 +1384,7 @@ PrintObjectSupportMaterial::MyLayersPtr PrintObjectSupportMaterial::raft_and_int
if (synchronize) {
// Emit support layers synchronized with the object layers.
// Find the first object layer, which has its print_z in this support Z range.
- while (idx_layer_object < object.layers.size() && object.layers[idx_layer_object]->print_z < extr1z + EPSILON)
+ while (idx_layer_object < object.layers().size() && object.layers()[idx_layer_object]->print_z < extr1z + EPSILON)
++ idx_layer_object;
if (idx_layer_object == 0 && extr1z == m_slicing_params.raft_interface_top_z) {
// Insert one base support layer below the object.
@@ -1395,11 +1395,11 @@ PrintObjectSupportMaterial::MyLayersPtr PrintObjectSupportMaterial::raft_and_int
intermediate_layers.push_back(&layer_new);
}
// Emit all intermediate support layers synchronized with object layers up to extr2z.
- for (; idx_layer_object < object.layers.size() && object.layers[idx_layer_object]->print_z < extr2z + EPSILON; ++ idx_layer_object) {
+ for (; idx_layer_object < object.layers().size() && object.layers()[idx_layer_object]->print_z < extr2z + EPSILON; ++ idx_layer_object) {
MyLayer &layer_new = layer_allocate(layer_storage, sltIntermediate);
- layer_new.print_z = object.layers[idx_layer_object]->print_z;
- layer_new.height = object.layers[idx_layer_object]->height;
- layer_new.bottom_z = (idx_layer_object > 0) ? object.layers[idx_layer_object - 1]->print_z : (layer_new.print_z - layer_new.height);
+ layer_new.print_z = object.layers()[idx_layer_object]->print_z;
+ layer_new.height = object.layers()[idx_layer_object]->height;
+ layer_new.bottom_z = (idx_layer_object > 0) ? object.layers()[idx_layer_object - 1]->print_z : (layer_new.print_z - layer_new.height);
assert(intermediate_layers.empty() || intermediate_layers.back()->print_z < layer_new.print_z + EPSILON);
intermediate_layers.push_back(&layer_new);
}
@@ -1409,10 +1409,10 @@ PrintObjectSupportMaterial::MyLayersPtr PrintObjectSupportMaterial::raft_and_int
assert(n_layers_extra > 0);
coordf_t step = dist / coordf_t(n_layers_extra);
if (extr1 != nullptr && extr1->layer_type == sltTopContact &&
- extr1->print_z + this->m_support_layer_height_min > extr1->bottom_z + step) {
+ extr1->print_z + m_support_layer_height_min > extr1->bottom_z + step) {
// The bottom extreme is a bottom of a top surface. Ensure that the gap
// between the 1st intermediate layer print_z and extr1->print_z is not too small.
- assert(extr1->bottom_z + this->m_support_layer_height_min < extr1->print_z + EPSILON);
+ assert(extr1->bottom_z + m_support_layer_height_min < extr1->print_z + EPSILON);
// Generate the first intermediate layer.
MyLayer &layer_new = layer_allocate(layer_storage, sltIntermediate);
layer_new.bottom_z = extr1->bottom_z;
@@ -1509,7 +1509,7 @@ void PrintObjectSupportMaterial::generate_base_layers(
Polygons polygons_new;
// Use the precomputed layer_support_areas.
- idx_object_layer_above = std::max(0, idx_lower_or_equal(object.layers, idx_object_layer_above,
+ idx_object_layer_above = std::max(0, idx_lower_or_equal(object.layers(), idx_object_layer_above,
[&layer_intermediate](const Layer *layer){ return layer->print_z <= layer_intermediate.print_z + EPSILON; }));
polygons_new = layer_support_areas[idx_object_layer_above];
@@ -1644,24 +1644,24 @@ void PrintObjectSupportMaterial::trim_support_layers_by_object(
// Find the overlapping object layers including the extra above / below gap.
coordf_t z_threshold = support_layer.print_z - support_layer.height - gap_extra_below + EPSILON;
idx_object_layer_overlapping = idx_higher_or_equal(
- object.layers, idx_object_layer_overlapping,
+ object.layers(), idx_object_layer_overlapping,
[z_threshold](const Layer *layer){ return layer->print_z >= z_threshold; });
// Collect all the object layers intersecting with this layer.
Polygons polygons_trimming;
size_t i = idx_object_layer_overlapping;
- for (; i < object.layers.size(); ++ i) {
- const Layer &object_layer = *object.layers[i];
+ for (; i < object.layers().size(); ++ i) {
+ const Layer &object_layer = *object.layers()[i];
if (object_layer.print_z - object_layer.height > support_layer.print_z + gap_extra_above - EPSILON)
break;
polygons_append(polygons_trimming, (Polygons)object_layer.slices);
}
- if (! this->m_slicing_params.soluble_interface) {
+ if (! m_slicing_params.soluble_interface) {
// Collect all bottom surfaces, which will be extruded with a bridging flow.
- for (; i < object.layers.size(); ++ i) {
- const Layer &object_layer = *object.layers[i];
+ for (; i < object.layers().size(); ++ i) {
+ const Layer &object_layer = *object.layers()[i];
bool some_region_overlaps = false;
- for (LayerRegion* region : object_layer.regions) {
- coordf_t nozzle_dmr = region->region()->nozzle_dmr_avg(*this->m_print_config);
+ for (LayerRegion* region : object_layer.regions()) {
+ coordf_t nozzle_dmr = region->region()->nozzle_dmr_avg(*m_print_config);
if (object_layer.print_z - nozzle_dmr > support_layer.print_z + gap_extra_above - EPSILON)
break;
some_region_overlaps = true;
@@ -1764,7 +1764,7 @@ PrintObjectSupportMaterial::MyLayersPtr PrintObjectSupportMaterial::generate_raf
// Expand the bases of the support columns in the 1st layer.
columns_base->polygons = diff(
offset(columns_base->polygons, inflate_factor_1st_layer),
- offset(m_object->layers.front()->slices.expolygons, scale_(m_gap_xy), SUPPORT_SURFACES_OFFSET_PARAMETERS));
+ offset(m_object->layers().front()->slices.expolygons, scale_(m_gap_xy), SUPPORT_SURFACES_OFFSET_PARAMETERS));
if (contacts != nullptr)
columns_base->polygons = diff(columns_base->polygons, interface_polygons);
}
@@ -1909,8 +1909,8 @@ struct MyLayerExtruded
else
*m_polygons_to_extrude = std::move(polygons);
}
- Polygons& polygons_to_extrude() { return (this->m_polygons_to_extrude == nullptr) ? layer->polygons : *this->m_polygons_to_extrude; }
- const Polygons& polygons_to_extrude() const { return (this->m_polygons_to_extrude == nullptr) ? layer->polygons : *this->m_polygons_to_extrude; }
+ Polygons& polygons_to_extrude() { return (m_polygons_to_extrude == nullptr) ? layer->polygons : *m_polygons_to_extrude; }
+ const Polygons& polygons_to_extrude() const { return (m_polygons_to_extrude == nullptr) ? layer->polygons : *m_polygons_to_extrude; }
bool could_merge(const MyLayerExtruded &other) const {
return ! this->empty() && ! other.empty() &&
@@ -1923,21 +1923,21 @@ struct MyLayerExtruded
assert(this->could_merge(other));
// 1) Merge the rest polygons to extrude, if there are any.
if (other.m_polygons_to_extrude != nullptr) {
- if (this->m_polygons_to_extrude == nullptr) {
+ if (m_polygons_to_extrude == nullptr) {
// This layer has no extrusions generated yet, if it has no m_polygons_to_extrude (its area to extrude was not reduced yet).
assert(this->extrusions.empty());
- this->m_polygons_to_extrude = new Polygons(this->layer->polygons);
+ m_polygons_to_extrude = new Polygons(this->layer->polygons);
}
- Slic3r::polygons_append(*this->m_polygons_to_extrude, std::move(*other.m_polygons_to_extrude));
- *this->m_polygons_to_extrude = union_(*this->m_polygons_to_extrude, true);
+ Slic3r::polygons_append(*m_polygons_to_extrude, std::move(*other.m_polygons_to_extrude));
+ *m_polygons_to_extrude = union_(*m_polygons_to_extrude, true);
delete other.m_polygons_to_extrude;
other.m_polygons_to_extrude = nullptr;
- } else if (this->m_polygons_to_extrude != nullptr) {
+ } else if (m_polygons_to_extrude != nullptr) {
assert(other.m_polygons_to_extrude == nullptr);
// The other layer has no extrusions generated yet, if it has no m_polygons_to_extrude (its area to extrude was not reduced yet).
assert(other.extrusions.empty());
- Slic3r::polygons_append(*this->m_polygons_to_extrude, other.layer->polygons);
- *this->m_polygons_to_extrude = union_(*this->m_polygons_to_extrude, true);
+ Slic3r::polygons_append(*m_polygons_to_extrude, other.layer->polygons);
+ *m_polygons_to_extrude = union_(*m_polygons_to_extrude, true);
}
// 2) Merge the extrusions.
this->extrusions.insert(this->extrusions.end(), other.extrusions.begin(), other.extrusions.end());
@@ -2535,7 +2535,7 @@ void PrintObjectSupportMaterial::generate_toolpaths(
for (size_t support_layer_id = range.begin(); support_layer_id < range.end(); ++ support_layer_id)
{
assert(support_layer_id < raft_layers.size());
- SupportLayer &support_layer = *object.support_layers[support_layer_id];
+ SupportLayer &support_layer = *object.support_layers()[support_layer_id];
assert(support_layer.support_fills.entities.empty());
MyLayer &raft_layer = *raft_layers[support_layer_id];
@@ -2631,9 +2631,9 @@ void PrintObjectSupportMaterial::generate_toolpaths(
MyLayerExtruded interface_layer;
std::vector<LayerCacheItem> overlaps;
};
- std::vector<LayerCache> layer_caches(object.support_layers.size(), LayerCache());
+ std::vector<LayerCache> layer_caches(object.support_layers().size(), LayerCache());
- tbb::parallel_for(tbb::blocked_range<size_t>(n_raft_layers, object.support_layers.size()),
+ tbb::parallel_for(tbb::blocked_range<size_t>(n_raft_layers, object.support_layers().size()),
[this, &object, &bottom_contacts, &top_contacts, &intermediate_layers, &interface_layers, &layer_caches, &loop_interface_processor,
infill_pattern, &bbox_object, support_density, interface_density, interface_angle, &angles, link_max_length_factor, with_sheath]
(const tbb::blocked_range<size_t>& range) {
@@ -2648,7 +2648,7 @@ void PrintObjectSupportMaterial::generate_toolpaths(
filler_support->set_bounding_box(bbox_object);
for (size_t support_layer_id = range.begin(); support_layer_id < range.end(); ++ support_layer_id)
{
- SupportLayer &support_layer = *object.support_layers[support_layer_id];
+ SupportLayer &support_layer = *object.support_layers()[support_layer_id];
LayerCache &layer_cache = layer_caches[support_layer_id];
// Find polygons with the same print_z.
@@ -2844,11 +2844,11 @@ void PrintObjectSupportMaterial::generate_toolpaths(
});
// Now modulate the support layer height in parallel.
- tbb::parallel_for(tbb::blocked_range<size_t>(n_raft_layers, object.support_layers.size()),
+ tbb::parallel_for(tbb::blocked_range<size_t>(n_raft_layers, object.support_layers().size()),
[this, &object, &layer_caches]
(const tbb::blocked_range<size_t>& range) {
for (size_t support_layer_id = range.begin(); support_layer_id < range.end(); ++ support_layer_id) {
- SupportLayer &support_layer = *object.support_layers[support_layer_id];
+ SupportLayer &support_layer = *object.support_layers()[support_layer_id];
LayerCache &layer_cache = layer_caches[support_layer_id];
for (LayerCacheItem &layer_cache_item : layer_cache.overlaps) {
modulate_extrusion_by_overlapping_layers(layer_cache_item.layer_extruded->extrusions, *layer_cache_item.layer_extruded->layer, layer_cache_item.overlapping);
diff --git a/xs/src/libslic3r/SupportMaterial.hpp b/xs/src/libslic3r/SupportMaterial.hpp
index 968763446..e20d7c69f 100644
--- a/xs/src/libslic3r/SupportMaterial.hpp
+++ b/xs/src/libslic3r/SupportMaterial.hpp
@@ -208,7 +208,7 @@ private:
// Produce the actual G-code.
void generate_toolpaths(
- const PrintObject &object,
+ const PrintObject &object,
const MyLayersPtr &raft_layers,
const MyLayersPtr &bottom_contacts,
const MyLayersPtr &top_contacts,
diff --git a/xs/src/slic3r/GUI/3DScene.cpp b/xs/src/slic3r/GUI/3DScene.cpp
index 03154c47e..356d27b96 100644
--- a/xs/src/slic3r/GUI/3DScene.cpp
+++ b/xs/src/slic3r/GUI/3DScene.cpp
@@ -1670,30 +1670,30 @@ void _3DScene::_load_print_toolpaths(
// The skirt and brim steps should be marked as done, so their paths are valid.
assert(print->is_step_done(psSkirt) && print->is_step_done(psBrim));
- if (!print->has_skirt() && print->config.brim_width.value == 0)
+ if (!print->has_skirt() && print->config().brim_width.value == 0)
return;
const float color[] = { 0.5f, 1.0f, 0.5f, 1.f }; // greenish
// number of skirt layers
size_t total_layer_count = 0;
- for (const PrintObject *print_object : print->objects)
+ for (const PrintObject *print_object : print->objects())
total_layer_count = std::max(total_layer_count, print_object->total_layer_count());
size_t skirt_height = print->has_infinite_skirt() ?
total_layer_count :
- std::min<size_t>(print->config.skirt_height.value, total_layer_count);
- if (skirt_height == 0 && print->config.brim_width.value > 0)
+ std::min<size_t>(print->config().skirt_height.value, total_layer_count);
+ if (skirt_height == 0 && print->config().brim_width.value > 0)
skirt_height = 1;
// get first skirt_height layers (maybe this should be moved to a PrintObject method?)
- const PrintObject *object0 = print->objects.front();
+ const PrintObject *object0 = print->objects().front();
std::vector<float> print_zs;
print_zs.reserve(skirt_height * 2);
- for (size_t i = 0; i < std::min(skirt_height, object0->layers.size()); ++ i)
- print_zs.push_back(float(object0->layers[i]->print_z));
+ for (size_t i = 0; i < std::min(skirt_height, object0->layers().size()); ++ i)
+ print_zs.push_back(float(object0->layers()[i]->print_z));
//FIXME why there are support layers?
- for (size_t i = 0; i < std::min(skirt_height, object0->support_layers.size()); ++ i)
- print_zs.push_back(float(object0->support_layers[i]->print_z));
+ for (size_t i = 0; i < std::min(skirt_height, object0->support_layers().size()); ++ i)
+ print_zs.push_back(float(object0->support_layers()[i]->print_z));
sort_remove_duplicates(print_zs);
if (print_zs.size() > skirt_height)
print_zs.erase(print_zs.begin() + skirt_height, print_zs.end());
@@ -1705,8 +1705,8 @@ void _3DScene::_load_print_toolpaths(
volume.offsets.push_back(volume.indexed_vertex_array.quad_indices.size());
volume.offsets.push_back(volume.indexed_vertex_array.triangle_indices.size());
if (i == 0)
- extrusionentity_to_verts(print->brim, print_zs[i], Point(0, 0), volume);
- extrusionentity_to_verts(print->skirt, print_zs[i], Point(0, 0), volume);
+ extrusionentity_to_verts(print->brim(), print_zs[i], Point(0, 0), volume);
+ extrusionentity_to_verts(print->skirt(), print_zs[i], Point(0, 0), volume);
}
volume.bounding_box = volume.indexed_vertex_array.bounding_box();
volume.indexed_vertex_array.finalize_geometry(use_VBOs);
@@ -1753,10 +1753,10 @@ void _3DScene::_load_print_object_toolpaths(
ctxt.shifted_copies = &print_object->_shifted_copies;
// order layers by print_z
- ctxt.layers.reserve(print_object->layers.size() + print_object->support_layers.size());
- for (const Layer *layer : print_object->layers)
+ ctxt.layers.reserve(print_object->layers().size() + print_object->support_layers().size());
+ for (const Layer *layer : print_object->layers())
ctxt.layers.push_back(layer);
- for (const Layer *layer : print_object->support_layers)
+ for (const Layer *layer : print_object->support_layers())
ctxt.layers.push_back(layer);
std::sort(ctxt.layers.begin(), ctxt.layers.end(), [](const Layer *l1, const Layer *l2) { return l1->print_z < l2->print_z; });
@@ -1803,10 +1803,10 @@ void _3DScene::_load_print_object_toolpaths(
}
}
for (const Point &copy: *ctxt.shifted_copies) {
- for (const LayerRegion *layerm : layer->regions) {
+ for (const LayerRegion *layerm : layer->regions()) {
if (ctxt.has_perimeters)
extrusionentity_to_verts(layerm->perimeters, float(layer->print_z), copy,
- *vols[ctxt.volume_idx(layerm->region()->config.perimeter_extruder.value, 0)]);
+ *vols[ctxt.volume_idx(layerm->region()->config().perimeter_extruder.value, 0)]);
if (ctxt.has_infill) {
for (const ExtrusionEntity *ee : layerm->fills.entities) {
// fill represents infill extrusions of a single island.
@@ -1815,8 +1815,8 @@ void _3DScene::_load_print_object_toolpaths(
extrusionentity_to_verts(*fill, float(layer->print_z), copy,
*vols[ctxt.volume_idx(
is_solid_infill(fill->entities.front()->role()) ?
- layerm->region()->config.solid_infill_extruder :
- layerm->region()->config.infill_extruder,
+ layerm->region()->config().solid_infill_extruder :
+ layerm->region()->config().infill_extruder,
1)]);
}
}
@@ -1828,8 +1828,8 @@ void _3DScene::_load_print_object_toolpaths(
extrusionentity_to_verts(extrusion_entity, float(layer->print_z), copy,
*vols[ctxt.volume_idx(
(extrusion_entity->role() == erSupportMaterial) ?
- support_layer->object()->config.support_material_extruder :
- support_layer->object()->config.support_material_interface_extruder,
+ support_layer->object()->config().support_material_extruder :
+ support_layer->object()->config().support_material_interface_extruder,
2)]);
}
}
@@ -1877,7 +1877,7 @@ void _3DScene::_load_wipe_tower_toolpaths(
const std::vector<std::string> &tool_colors_str,
bool use_VBOs)
{
- if (print->m_wipe_tower_tool_changes.empty())
+ if (print->wipe_tower_data().tool_changes.empty())
return;
std::vector<float> tool_colors = parse_colors(tool_colors_str);
@@ -1902,8 +1902,8 @@ void _3DScene::_load_wipe_tower_toolpaths(
const std::vector<WipeTower::ToolChangeResult>& tool_change(size_t idx) {
return priming.empty() ?
- ((idx == print->m_wipe_tower_tool_changes.size()) ? final : print->m_wipe_tower_tool_changes[idx]) :
- ((idx == 0) ? priming : (idx == print->m_wipe_tower_tool_changes.size() + 1) ? final : print->m_wipe_tower_tool_changes[idx - 1]);
+ ((idx == print->wipe_tower_data().tool_changes.size()) ? final : print->wipe_tower_data().tool_changes[idx]) :
+ ((idx == 0) ? priming : (idx == print->wipe_tower_data().tool_changes.size() + 1) ? final : print->wipe_tower_data().tool_changes[idx - 1]);
}
std::vector<WipeTower::ToolChangeResult> priming;
std::vector<WipeTower::ToolChangeResult> final;
@@ -1911,15 +1911,15 @@ void _3DScene::_load_wipe_tower_toolpaths(
ctxt.print = print;
ctxt.tool_colors = tool_colors.empty() ? nullptr : &tool_colors;
- if (print->m_wipe_tower_priming)
- ctxt.priming.emplace_back(*print->m_wipe_tower_priming.get());
- if (print->m_wipe_tower_final_purge)
- ctxt.final.emplace_back(*print->m_wipe_tower_final_purge.get());
+ if (print->wipe_tower_data().priming != nullptr)
+ ctxt.priming.emplace_back(*print->wipe_tower_data().priming);
+ if (print->wipe_tower_data().final_purge)
+ ctxt.final.emplace_back(*print->wipe_tower_data().final_purge);
BOOST_LOG_TRIVIAL(debug) << "Loading wipe tower toolpaths in parallel - start";
//FIXME Improve the heuristics for a grain size.
- size_t n_items = print->m_wipe_tower_tool_changes.size() + (ctxt.priming.empty() ? 0 : 1);
+ size_t n_items = print->wipe_tower_data().tool_changes.size() + (ctxt.priming.empty() ? 0 : 1);
size_t grain_size = std::max(n_items / 128, size_t(1));
tbb::spin_mutex new_volume_mutex;
auto new_volume = [volumes, &new_volume_mutex](const float *color) -> GLVolume* {
@@ -2554,13 +2554,13 @@ void _3DScene::_load_shells(const Print& print, GLVolumeCollection& volumes, boo
size_t initial_volumes_count = volumes.volumes.size();
s_gcode_preview_volume_index.first_volumes.emplace_back(GCodePreviewVolumeIndex::Shell, 0, (unsigned int)initial_volumes_count);
- if (print.objects.empty())
+ if (print.objects().empty())
// nothing to render, return
return;
// adds objects' volumes
unsigned int object_id = 0;
- for (PrintObject* obj : print.objects)
+ for (PrintObject* obj : print.objects())
{
ModelObject* model_obj = obj->model_object();
@@ -2579,8 +2579,8 @@ void _3DScene::_load_shells(const Print& print, GLVolumeCollection& volumes, boo
}
// adds wipe tower's volume
- coordf_t max_z = print.objects[0]->model_object()->get_model()->bounding_box().max.z;
- const PrintConfig& config = print.config;
+ coordf_t max_z = print.objects().front()->model_object()->get_model()->bounding_box().max.z;
+ const PrintConfig& config = print.config();
unsigned int extruders_count = config.nozzle_diameter.size();
if ((extruders_count > 1) && config.single_extruder_multi_material && config.wipe_tower && !config.complete_objects)
volumes.load_wipe_tower_preview(1000, config.wipe_tower_x, config.wipe_tower_y, config.wipe_tower_width, config.wipe_tower_per_color_wipe * (extruders_count - 1), max_z, use_VBOs);
diff --git a/xs/xsp/Print.xsp b/xs/xsp/Print.xsp
index 16e2d84aa..94c9d707d 100644
--- a/xs/xsp/Print.xsp
+++ b/xs/xsp/Print.xsp
@@ -31,7 +31,7 @@ _constant()
// owned by Print, no constructor/destructor
Ref<StaticPrintConfig> config()
- %code%{ RETVAL = &THIS->config; %};
+ %code%{ RETVAL = &THIS->config(); %};
Ref<Print> print();
Clone<Flow> flow(FlowRole role, double layer_height, bool bridge, bool first_layer, double width, PrintObject* object)
@@ -42,12 +42,12 @@ _constant()
// owned by Print, no constructor/destructor
int region_count()
- %code%{ RETVAL = THIS->print()->regions.size(); %};
+ %code%{ RETVAL = THIS->print()->regions().size(); %};
Ref<Print> print();
Ref<ModelObject> model_object();
Ref<StaticPrintConfig> config()
- %code%{ RETVAL = &THIS->config; %};
+ %code%{ RETVAL = &THIS->config(); %};
Points copies();
t_layer_height_ranges layer_height_ranges()
%code%{ RETVAL = THIS->layer_height_ranges; %};
@@ -95,32 +95,41 @@ _constant()
~Print();
Ref<StaticPrintConfig> config()
- %code%{ RETVAL = &THIS->config; %};
+ %code%{ RETVAL = &THIS->config(); %};
Ref<PlaceholderParser> placeholder_parser()
- %code%{ RETVAL = &THIS->placeholder_parser; %};
+ %code%{ RETVAL = &THIS->placeholder_parser(); %};
Ref<ExtrusionEntityCollection> skirt()
- %code%{ RETVAL = &THIS->skirt; %};
+ %code%{ RETVAL = const_cast<ExtrusionEntityCollection*>(&THIS->skirt()); %};
Ref<ExtrusionEntityCollection> brim()
- %code%{ RETVAL = &THIS->brim; %};
+ %code%{ RETVAL = const_cast<ExtrusionEntityCollection*>(&THIS->brim()); %};
std::string estimated_print_time()
- %code%{ RETVAL = THIS->estimated_print_time; %};
+ %code%{ RETVAL = THIS->print_statistics().estimated_print_time; %};
+ double total_used_filament()
+ %code%{ RETVAL = THIS->print_statistics().total_used_filament; %};
+ double total_extruded_volume()
+ %code%{ RETVAL = THIS->print_statistics().total_extruded_volume; %};
+ double total_weight()
+ %code%{ RETVAL = THIS->print_statistics().total_weight; %};
+ double total_cost()
+ %code%{ RETVAL = THIS->print_statistics().total_cost; %};
PrintObjectPtrs* objects()
- %code%{ RETVAL = &THIS->objects; %};
+ %code%{ RETVAL = const_cast<PrintObjectPtrs*>(&THIS->objects()); %};
void clear_objects();
- Ref<PrintObject> get_object(int idx);
+ Ref<PrintObject> get_object(int idx)
+ %code%{ RETVAL = THIS->objects()[idx]; %};
void delete_object(int idx);
void reload_object(int idx);
bool reload_model_instances();
size_t object_count()
- %code%{ RETVAL = THIS->objects.size(); %};
+ %code%{ RETVAL = THIS->objects().size(); %};
PrintRegionPtrs* regions()
- %code%{ RETVAL = &THIS->regions; %};
- Ref<PrintRegion> get_region(int idx);
- Ref<PrintRegion> add_region();
+ %code%{ RETVAL = const_cast<PrintRegionPtrs*>(&THIS->regions()); %};
+ Ref<PrintRegion> get_region(int idx)
+ %code%{ RETVAL = THIS->regions()[idx]; %};
size_t region_count()
- %code%{ RETVAL = THIS->regions.size(); %};
+ %code%{ RETVAL = THIS->regions().size(); %};
bool step_done(PrintStep step)
%code%{ RETVAL = THIS->is_step_done(step); %};
@@ -130,7 +139,7 @@ _constant()
SV* filament_stats()
%code%{
HV* hv = newHV();
- for (std::map<size_t,float>::const_iterator it = THIS->filament_stats.begin(); it != THIS->filament_stats.end(); ++it) {
+ for (std::map<size_t,float>::const_iterator it = THIS->print_statistics().filament_stats.begin(); it != THIS->print_statistics().filament_stats.end(); ++it) {
// stringify extruder_id
std::ostringstream ss;
ss << it->first;
@@ -194,47 +203,4 @@ _constant()
}
%};
-%{
-
-double
-Print::total_used_filament(...)
- CODE:
- if (items > 1) {
- THIS->total_used_filament = (double)SvNV(ST(1));
- }
- RETVAL = THIS->total_used_filament;
- OUTPUT:
- RETVAL
-
-double
-Print::total_extruded_volume(...)
- CODE:
- if (items > 1) {
- THIS->total_extruded_volume = (double)SvNV(ST(1));
- }
- RETVAL = THIS->total_extruded_volume;
- OUTPUT:
- RETVAL
-
-
-double
-Print::total_weight(...)
- CODE:
- if (items > 1) {
- THIS->total_weight = (double)SvNV(ST(1));
- }
- RETVAL = THIS->total_weight;
- OUTPUT:
- RETVAL
-
-double
-Print::total_cost(...)
- CODE:
- if (items > 1) {
- THIS->total_cost = (double)SvNV(ST(1));
- }
- RETVAL = THIS->total_cost;
- OUTPUT:
- RETVAL
-%}
};