WIP: Moving ownership of PrintRegions to PrintObjects.
This commit is contained in:
parent
d21b9aa089
commit
714149dab2
@ -291,13 +291,13 @@ std::pair<double, double> adaptive_fill_line_spacing(const PrintObject &print_ob
|
|||||||
double extrusion_width;
|
double extrusion_width;
|
||||||
};
|
};
|
||||||
std::vector<RegionFillData> region_fill_data;
|
std::vector<RegionFillData> region_fill_data;
|
||||||
region_fill_data.reserve(print_object.print()->regions().size());
|
region_fill_data.reserve(print_object.num_printing_regions());
|
||||||
bool build_octree = false;
|
bool build_octree = false;
|
||||||
const std::vector<double> &nozzle_diameters = print_object.print()->config().nozzle_diameter.values;
|
const std::vector<double> &nozzle_diameters = print_object.print()->config().nozzle_diameter.values;
|
||||||
double max_nozzle_diameter = *std::max_element(nozzle_diameters.begin(), nozzle_diameters.end());
|
double max_nozzle_diameter = *std::max_element(nozzle_diameters.begin(), nozzle_diameters.end());
|
||||||
double default_infill_extrusion_width = Flow::auto_extrusion_width(FlowRole::frInfill, float(max_nozzle_diameter));
|
double default_infill_extrusion_width = Flow::auto_extrusion_width(FlowRole::frInfill, float(max_nozzle_diameter));
|
||||||
for (const PrintRegion *region : print_object.print()->regions()) {
|
for (size_t region_id = 0; region_id < print_object.num_printing_regions(); ++ region_id) {
|
||||||
const PrintRegionConfig &config = region->config();
|
const PrintRegionConfig &config = print_object.printing_region(region_id).config();
|
||||||
bool nonempty = config.fill_density > 0;
|
bool nonempty = config.fill_density > 0;
|
||||||
bool has_adaptive_infill = nonempty && config.fill_pattern == ipAdaptiveCubic;
|
bool has_adaptive_infill = nonempty && config.fill_pattern == ipAdaptiveCubic;
|
||||||
bool has_support_infill = nonempty && config.fill_pattern == ipSupportCubic;
|
bool has_support_infill = nonempty && config.fill_pattern == ipSupportCubic;
|
||||||
|
@ -796,19 +796,19 @@ namespace DoExport {
|
|||||||
// get the minimum cross-section used in the print
|
// get the minimum cross-section used in the print
|
||||||
std::vector<double> mm3_per_mm;
|
std::vector<double> mm3_per_mm;
|
||||||
for (auto object : print.objects()) {
|
for (auto object : print.objects()) {
|
||||||
for (size_t region_id = 0; region_id < object->region_volumes.size(); ++ region_id) {
|
for (size_t region_id = 0; region_id < object->num_printing_regions(); ++ region_id) {
|
||||||
const PrintRegion* region = print.regions()[region_id];
|
const PrintRegion ®ion = object->printing_region(region_id);
|
||||||
for (auto layer : object->layers()) {
|
for (auto layer : object->layers()) {
|
||||||
const LayerRegion* layerm = layer->regions()[region_id];
|
const LayerRegion* layerm = layer->regions()[region_id];
|
||||||
if (region->config().get_abs_value("perimeter_speed") == 0 ||
|
if (region.config().get_abs_value("perimeter_speed") == 0 ||
|
||||||
region->config().get_abs_value("small_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("external_perimeter_speed") == 0 ||
|
||||||
region->config().get_abs_value("bridge_speed") == 0)
|
region.config().get_abs_value("bridge_speed") == 0)
|
||||||
mm3_per_mm.push_back(layerm->perimeters.min_mm3_per_mm());
|
mm3_per_mm.push_back(layerm->perimeters.min_mm3_per_mm());
|
||||||
if (region->config().get_abs_value("infill_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("solid_infill_speed") == 0 ||
|
||||||
region->config().get_abs_value("top_solid_infill_speed") == 0 ||
|
region.config().get_abs_value("top_solid_infill_speed") == 0 ||
|
||||||
region->config().get_abs_value("bridge_speed") == 0)
|
region.config().get_abs_value("bridge_speed") == 0)
|
||||||
{
|
{
|
||||||
// Minimal volumetric flow should not be calculated over ironing extrusions.
|
// Minimal volumetric flow should not be calculated over ironing extrusions.
|
||||||
// Use following lambda instead of the built-it method.
|
// Use following lambda instead of the built-it method.
|
||||||
@ -1112,16 +1112,17 @@ void GCode::_do_export(Print& print, FILE* file, ThumbnailsGeneratorCallback thu
|
|||||||
const double layer_height = first_object->config().layer_height.value;
|
const double layer_height = first_object->config().layer_height.value;
|
||||||
assert(! print.config().first_layer_height.percent);
|
assert(! print.config().first_layer_height.percent);
|
||||||
const double first_layer_height = print.config().first_layer_height.value;
|
const double first_layer_height = print.config().first_layer_height.value;
|
||||||
for (const PrintRegion* region : print.regions()) {
|
for (size_t region_id = 0; region_id < print.num_print_regions(); ++ region_id) {
|
||||||
_write_format(file, "; external perimeters extrusion width = %.2fmm\n", region->flow(*first_object, frExternalPerimeter, layer_height).width());
|
const PrintRegion ®ion = *print.get_print_region(region_id);
|
||||||
_write_format(file, "; perimeters extrusion width = %.2fmm\n", region->flow(*first_object, frPerimeter, layer_height).width());
|
_write_format(file, "; external perimeters extrusion width = %.2fmm\n", region.flow(*first_object, frExternalPerimeter, layer_height).width());
|
||||||
_write_format(file, "; infill extrusion width = %.2fmm\n", region->flow(*first_object, frInfill, layer_height).width());
|
_write_format(file, "; perimeters extrusion width = %.2fmm\n", region.flow(*first_object, frPerimeter, layer_height).width());
|
||||||
_write_format(file, "; solid infill extrusion width = %.2fmm\n", region->flow(*first_object, frSolidInfill, layer_height).width());
|
_write_format(file, "; infill extrusion width = %.2fmm\n", region.flow(*first_object, frInfill, layer_height).width());
|
||||||
_write_format(file, "; top infill extrusion width = %.2fmm\n", region->flow(*first_object, frTopSolidInfill, layer_height).width());
|
_write_format(file, "; solid infill extrusion width = %.2fmm\n", region.flow(*first_object, frSolidInfill, layer_height).width());
|
||||||
|
_write_format(file, "; top infill extrusion width = %.2fmm\n", region.flow(*first_object, frTopSolidInfill, layer_height).width());
|
||||||
if (print.has_support_material())
|
if (print.has_support_material())
|
||||||
_write_format(file, "; support material extrusion width = %.2fmm\n", support_material_flow(first_object).width());
|
_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(*first_object, frPerimeter, first_layer_height, true).width());
|
_write_format(file, "; first layer extrusion width = %.2fmm\n", region.flow(*first_object, frPerimeter, first_layer_height, true).width());
|
||||||
_write_format(file, "\n");
|
_write_format(file, "\n");
|
||||||
}
|
}
|
||||||
print.throw_if_canceled();
|
print.throw_if_canceled();
|
||||||
@ -2109,7 +2110,7 @@ void GCode::process_layer(
|
|||||||
const LayerRegion *layerm = layer.regions()[region_id];
|
const LayerRegion *layerm = layer.regions()[region_id];
|
||||||
if (layerm == nullptr)
|
if (layerm == nullptr)
|
||||||
continue;
|
continue;
|
||||||
const PrintRegion ®ion = *print.regions()[region_id];
|
const PrintRegion ®ion = *layerm->region();
|
||||||
|
|
||||||
// Now we must process perimeters and infills and create islands of extrusions in by_region std::map.
|
// Now we must process perimeters and infills and create islands of extrusions in by_region std::map.
|
||||||
// It is also necessary to save which extrusions are part of MM wiping and which are not.
|
// It is also necessary to save which extrusions are part of MM wiping and which are not.
|
||||||
@ -2167,7 +2168,7 @@ void GCode::process_layer(
|
|||||||
// extrusions->first_point fits inside ith slice
|
// extrusions->first_point fits inside ith slice
|
||||||
point_inside_surface(island_idx, extrusions->first_point())) {
|
point_inside_surface(island_idx, extrusions->first_point())) {
|
||||||
if (islands[island_idx].by_region.empty())
|
if (islands[island_idx].by_region.empty())
|
||||||
islands[island_idx].by_region.assign(print.regions().size(), ObjectByExtruder::Island::Region());
|
islands[island_idx].by_region.assign(print.num_print_regions(), ObjectByExtruder::Island::Region());
|
||||||
islands[island_idx].by_region[region_id].append(entity_type, extrusions, entity_overrides);
|
islands[island_idx].by_region[region_id].append(entity_type, extrusions, entity_overrides);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -2570,7 +2571,7 @@ std::string GCode::extrude_perimeters(const Print &print, const std::vector<Obje
|
|||||||
std::string gcode;
|
std::string gcode;
|
||||||
for (const ObjectByExtruder::Island::Region ®ion : by_region)
|
for (const ObjectByExtruder::Island::Region ®ion : by_region)
|
||||||
if (! region.perimeters.empty()) {
|
if (! region.perimeters.empty()) {
|
||||||
m_config.apply(print.regions()[®ion - &by_region.front()]->config());
|
m_config.apply(print.get_print_region(®ion - &by_region.front())->config());
|
||||||
for (const ExtrusionEntity *ee : region.perimeters)
|
for (const ExtrusionEntity *ee : region.perimeters)
|
||||||
gcode += this->extrude_entity(*ee, "perimeter", -1., &lower_layer_edge_grid);
|
gcode += this->extrude_entity(*ee, "perimeter", -1., &lower_layer_edge_grid);
|
||||||
}
|
}
|
||||||
@ -2591,7 +2592,7 @@ std::string GCode::extrude_infill(const Print &print, const std::vector<ObjectBy
|
|||||||
if ((ee->role() == erIroning) == ironing)
|
if ((ee->role() == erIroning) == ironing)
|
||||||
extrusions.emplace_back(ee);
|
extrusions.emplace_back(ee);
|
||||||
if (! extrusions.empty()) {
|
if (! extrusions.empty()) {
|
||||||
m_config.apply(print.regions()[®ion - &by_region.front()]->config());
|
m_config.apply(print.get_print_region(®ion - &by_region.front())->config());
|
||||||
chain_and_reorder_extrusion_entities(extrusions, &m_last_pos);
|
chain_and_reorder_extrusion_entities(extrusions, &m_last_pos);
|
||||||
for (const ExtrusionEntity *fill : extrusions) {
|
for (const ExtrusionEntity *fill : extrusions) {
|
||||||
auto *eec = dynamic_cast<const ExtrusionEntityCollection*>(fill);
|
auto *eec = dynamic_cast<const ExtrusionEntityCollection*>(fill);
|
||||||
|
@ -223,11 +223,11 @@ void ToolOrdering::collect_extruders(const PrintObject &object, const std::vecto
|
|||||||
layer_tools.extruder_override = extruder_override;
|
layer_tools.extruder_override = extruder_override;
|
||||||
|
|
||||||
// What extruders are required to print this object layer?
|
// What extruders are required to print this object layer?
|
||||||
for (size_t region_id = 0; region_id < object.region_volumes.size(); ++ region_id) {
|
for (size_t region_id = 0; region_id < object.num_printing_regions(); ++ region_id) {
|
||||||
const LayerRegion *layerm = (region_id < layer->regions().size()) ? layer->regions()[region_id] : nullptr;
|
const LayerRegion *layerm = (region_id < layer->regions().size()) ? layer->regions()[region_id] : nullptr;
|
||||||
if (layerm == nullptr)
|
if (layerm == nullptr)
|
||||||
continue;
|
continue;
|
||||||
const PrintRegion ®ion = *object.print()->regions()[region_id];
|
const PrintRegion ®ion = *layerm->region();
|
||||||
|
|
||||||
if (! layerm->perimeters.entities.empty()) {
|
if (! layerm->perimeters.entities.empty()) {
|
||||||
bool something_nonoverriddable = true;
|
bool something_nonoverriddable = true;
|
||||||
@ -689,8 +689,8 @@ float WipingExtrusions::mark_wiping_extrusions(const Print& print, unsigned int
|
|||||||
// iterate through copies (aka PrintObject instances) first, so that we mark neighbouring infills to minimize travel moves
|
// iterate through copies (aka PrintObject instances) first, so that we mark neighbouring infills to minimize travel moves
|
||||||
for (unsigned int copy = 0; copy < num_of_copies; ++copy) {
|
for (unsigned int copy = 0; copy < num_of_copies; ++copy) {
|
||||||
|
|
||||||
for (size_t region_id = 0; region_id < object->region_volumes.size(); ++ region_id) {
|
for (size_t region_id = 0; region_id < object->num_printing_regions(); ++ region_id) {
|
||||||
const auto& region = *object->print()->regions()[region_id];
|
const PrintRegion ®ion = object->printing_region(region_id);
|
||||||
|
|
||||||
if (!region.config().wipe_into_infill && !object->config().wipe_into_objects)
|
if (!region.config().wipe_into_infill && !object->config().wipe_into_objects)
|
||||||
continue;
|
continue;
|
||||||
@ -762,8 +762,8 @@ void WipingExtrusions::ensure_perimeters_infills_order(const Print& print)
|
|||||||
size_t num_of_copies = object->instances().size();
|
size_t num_of_copies = object->instances().size();
|
||||||
|
|
||||||
for (size_t copy = 0; copy < num_of_copies; ++copy) { // iterate through copies first, so that we mark neighbouring infills to minimize travel moves
|
for (size_t copy = 0; copy < num_of_copies; ++copy) { // iterate through copies first, so that we mark neighbouring infills to minimize travel moves
|
||||||
for (size_t region_id = 0; region_id < object->region_volumes.size(); ++ region_id) {
|
for (size_t region_id = 0; region_id < object->num_printing_regions(); ++ region_id) {
|
||||||
const auto& region = *object->print()->regions()[region_id];
|
const auto& region = object->printing_region(region_id);
|
||||||
|
|
||||||
if (!region.config().wipe_into_infill && !object->config().wipe_into_objects)
|
if (!region.config().wipe_into_infill && !object->config().wipe_into_objects)
|
||||||
continue;
|
continue;
|
||||||
|
@ -39,22 +39,22 @@ void Print::clear()
|
|||||||
for (PrintObject *object : m_objects)
|
for (PrintObject *object : m_objects)
|
||||||
delete object;
|
delete object;
|
||||||
m_objects.clear();
|
m_objects.clear();
|
||||||
for (PrintRegion *region : m_regions)
|
for (PrintRegion *region : m_print_regions)
|
||||||
delete region;
|
delete region;
|
||||||
m_regions.clear();
|
m_print_regions.clear();
|
||||||
m_model.clear_objects();
|
m_model.clear_objects();
|
||||||
}
|
}
|
||||||
|
|
||||||
PrintRegion* Print::add_region()
|
PrintRegion* Print::add_print_region()
|
||||||
{
|
{
|
||||||
m_regions.emplace_back(new PrintRegion());
|
m_print_regions.emplace_back(new PrintRegion());
|
||||||
return m_regions.back();
|
return m_print_regions.back();
|
||||||
}
|
}
|
||||||
|
|
||||||
PrintRegion* Print::add_region(const PrintRegionConfig &config)
|
PrintRegion* Print::add_print_region(const PrintRegionConfig &config)
|
||||||
{
|
{
|
||||||
m_regions.emplace_back(new PrintRegion(config));
|
m_print_regions.emplace_back(new PrintRegion(config));
|
||||||
return m_regions.back();
|
return m_print_regions.back();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Called by Print::apply().
|
// Called by Print::apply().
|
||||||
@ -273,15 +273,10 @@ bool Print::is_step_done(PrintObjectStep step) const
|
|||||||
std::vector<unsigned int> Print::object_extruders() const
|
std::vector<unsigned int> Print::object_extruders() const
|
||||||
{
|
{
|
||||||
std::vector<unsigned int> extruders;
|
std::vector<unsigned int> extruders;
|
||||||
extruders.reserve(m_regions.size() * 3);
|
extruders.reserve(m_print_regions.size() * m_objects.size() * 3);
|
||||||
std::vector<unsigned char> region_used(m_regions.size(), false);
|
|
||||||
for (const PrintObject *object : m_objects)
|
for (const PrintObject *object : m_objects)
|
||||||
for (const std::vector<std::pair<t_layer_height_range, int>> &volumes_per_region : object->region_volumes)
|
for (const auto *region : object->all_regions())
|
||||||
if (! volumes_per_region.empty())
|
region->collect_object_printing_extruders(*this, extruders);
|
||||||
region_used[&volumes_per_region - &object->region_volumes.front()] = true;
|
|
||||||
for (size_t idx_region = 0; idx_region < m_regions.size(); ++ idx_region)
|
|
||||||
if (region_used[idx_region])
|
|
||||||
m_regions[idx_region]->collect_object_printing_extruders(*this, extruders);
|
|
||||||
sort_remove_duplicates(extruders);
|
sort_remove_duplicates(extruders);
|
||||||
return extruders;
|
return extruders;
|
||||||
}
|
}
|
||||||
@ -451,11 +446,7 @@ std::string Print::validate(std::string* warning) const
|
|||||||
return L("Only a single object may be printed at a time in Spiral Vase mode. "
|
return L("Only a single object may be printed at a time in Spiral Vase mode. "
|
||||||
"Either remove all but the last object, or enable sequential mode by \"complete_objects\".");
|
"Either remove all but the last object, or enable sequential mode by \"complete_objects\".");
|
||||||
assert(m_objects.size() == 1);
|
assert(m_objects.size() == 1);
|
||||||
size_t num_regions = 0;
|
if (m_objects.front()->all_regions().size() > 1)
|
||||||
for (const std::vector<std::pair<t_layer_height_range, int>> &volumes_per_region : m_objects.front()->region_volumes)
|
|
||||||
if (! volumes_per_region.empty())
|
|
||||||
++ num_regions;
|
|
||||||
if (num_regions > 1)
|
|
||||||
return L("The Spiral Vase option can only be used when printing single material objects.");
|
return L("The Spiral Vase option can only be used when printing single material objects.");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -670,8 +661,8 @@ std::string Print::validate(std::string* warning) const
|
|||||||
if ((object->has_support() || object->has_raft()) && ! validate_extrusion_width(object->config(), "support_material_extrusion_width", layer_height, err_msg))
|
if ((object->has_support() || object->has_raft()) && ! validate_extrusion_width(object->config(), "support_material_extrusion_width", layer_height, err_msg))
|
||||||
return err_msg;
|
return err_msg;
|
||||||
for (const char *opt_key : { "perimeter_extrusion_width", "external_perimeter_extrusion_width", "infill_extrusion_width", "solid_infill_extrusion_width", "top_infill_extrusion_width" })
|
for (const char *opt_key : { "perimeter_extrusion_width", "external_perimeter_extrusion_width", "infill_extrusion_width", "solid_infill_extrusion_width", "top_infill_extrusion_width" })
|
||||||
for (size_t i = 0; i < object->region_volumes.size(); ++ i)
|
for (const PrintRegion *region : object->all_regions())
|
||||||
if (! object->region_volumes[i].empty() && ! validate_extrusion_width(this->get_region(i)->config(), opt_key, layer_height, err_msg))
|
if (! validate_extrusion_width(region->config(), opt_key, layer_height, err_msg))
|
||||||
return err_msg;
|
return err_msg;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -746,7 +737,7 @@ Flow Print::brim_flow() const
|
|||||||
{
|
{
|
||||||
ConfigOptionFloatOrPercent width = m_config.first_layer_extrusion_width;
|
ConfigOptionFloatOrPercent width = m_config.first_layer_extrusion_width;
|
||||||
if (width.value == 0)
|
if (width.value == 0)
|
||||||
width = m_regions.front()->config().perimeter_extrusion_width;
|
width = m_print_regions.front()->config().perimeter_extrusion_width;
|
||||||
if (width.value == 0)
|
if (width.value == 0)
|
||||||
width = m_objects.front()->config().extrusion_width;
|
width = m_objects.front()->config().extrusion_width;
|
||||||
|
|
||||||
@ -758,7 +749,7 @@ Flow Print::brim_flow() const
|
|||||||
return Flow::new_from_config_width(
|
return Flow::new_from_config_width(
|
||||||
frPerimeter,
|
frPerimeter,
|
||||||
width,
|
width,
|
||||||
(float)m_config.nozzle_diameter.get_at(m_regions.front()->config().perimeter_extruder-1),
|
(float)m_config.nozzle_diameter.get_at(m_print_regions.front()->config().perimeter_extruder-1),
|
||||||
(float)this->skirt_first_layer_height());
|
(float)this->skirt_first_layer_height());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -766,7 +757,7 @@ Flow Print::skirt_flow() const
|
|||||||
{
|
{
|
||||||
ConfigOptionFloatOrPercent width = m_config.first_layer_extrusion_width;
|
ConfigOptionFloatOrPercent width = m_config.first_layer_extrusion_width;
|
||||||
if (width.value == 0)
|
if (width.value == 0)
|
||||||
width = m_regions.front()->config().perimeter_extrusion_width;
|
width = m_print_regions.front()->config().perimeter_extrusion_width;
|
||||||
if (width.value == 0)
|
if (width.value == 0)
|
||||||
width = m_objects.front()->config().extrusion_width;
|
width = m_objects.front()->config().extrusion_width;
|
||||||
|
|
||||||
|
@ -148,9 +148,6 @@ private: // Prevents erroneous use by other classes.
|
|||||||
typedef PrintObjectBaseWithState<Print, PrintObjectStep, posCount> Inherited;
|
typedef PrintObjectBaseWithState<Print, PrintObjectStep, posCount> Inherited;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// vector of (layer height ranges and vectors of volume ids), indexed by region_id
|
|
||||||
std::vector<std::vector<std::pair<t_layer_height_range, int>>> region_volumes;
|
|
||||||
|
|
||||||
// Size of an object: XYZ in scaled coordinates. The size might not be quite snug in XY plane.
|
// Size of an object: XYZ in scaled coordinates. The size might not be quite snug in XY plane.
|
||||||
const Vec3crd& size() const { return m_size; }
|
const Vec3crd& size() const { return m_size; }
|
||||||
const PrintObjectConfig& config() const { return m_config; }
|
const PrintObjectConfig& config() const { return m_config; }
|
||||||
@ -177,9 +174,9 @@ public:
|
|||||||
|
|
||||||
// adds region_id, too, if necessary
|
// adds region_id, too, if necessary
|
||||||
void add_region_volume(unsigned int region_id, int volume_id, const t_layer_height_range &layer_range) {
|
void add_region_volume(unsigned int region_id, int volume_id, const t_layer_height_range &layer_range) {
|
||||||
if (region_id >= region_volumes.size())
|
if (region_id >= m_region_volumes.size())
|
||||||
region_volumes.resize(region_id + 1);
|
m_region_volumes.resize(region_id + 1);
|
||||||
region_volumes[region_id].emplace_back(layer_range, volume_id);
|
m_region_volumes[region_id].emplace_back(layer_range, volume_id);
|
||||||
}
|
}
|
||||||
// This is the *total* layer count (including support layers)
|
// This is the *total* layer count (including support layers)
|
||||||
// this value is not supposed to be compared with Layer::id
|
// this value is not supposed to be compared with Layer::id
|
||||||
@ -219,6 +216,11 @@ public:
|
|||||||
const SlicingParameters& slicing_parameters() const { return m_slicing_params; }
|
const SlicingParameters& slicing_parameters() const { return m_slicing_params; }
|
||||||
static SlicingParameters slicing_parameters(const DynamicPrintConfig &full_config, const ModelObject &model_object, float object_max_z);
|
static SlicingParameters slicing_parameters(const DynamicPrintConfig &full_config, const ModelObject &model_object, float object_max_z);
|
||||||
|
|
||||||
|
size_t num_printing_regions() const throw() { return m_region_volumes.size(); }
|
||||||
|
const PrintRegion& printing_region(size_t idx) const throw();
|
||||||
|
//FIXME returing all possible regions before slicing, thus some of the regions may not be slicing at the end.
|
||||||
|
std::vector<const PrintRegion*> all_regions() const;
|
||||||
|
|
||||||
bool has_support() const { return m_config.support_material || m_config.support_material_enforce_layers > 0; }
|
bool has_support() const { return m_config.support_material || m_config.support_material_enforce_layers > 0; }
|
||||||
bool has_raft() const { return m_config.raft_layers > 0; }
|
bool has_raft() const { return m_config.raft_layers > 0; }
|
||||||
bool has_support_material() const { return this->has_support() || this->has_raft(); }
|
bool has_support_material() const { return this->has_support() || this->has_raft(); }
|
||||||
@ -293,6 +295,9 @@ private:
|
|||||||
// This is the adjustment of the the Object's coordinate system towards PrintObject's coordinate system.
|
// This is the adjustment of the the Object's coordinate system towards PrintObject's coordinate system.
|
||||||
Point m_center_offset;
|
Point m_center_offset;
|
||||||
|
|
||||||
|
// vector of (layer height ranges and vectors of volume ids), indexed by region_id
|
||||||
|
std::vector<std::vector<std::pair<t_layer_height_range, int>>> m_region_volumes;
|
||||||
|
|
||||||
SlicingParameters m_slicing_params;
|
SlicingParameters m_slicing_params;
|
||||||
LayerPtrs m_layers;
|
LayerPtrs m_layers;
|
||||||
SupportLayerPtrs m_support_layers;
|
SupportLayerPtrs m_support_layers;
|
||||||
@ -392,11 +397,13 @@ class ConstPrintObjectPtrsAdaptor : public ConstVectorOfPtrsAdaptor<PrintObject>
|
|||||||
};
|
};
|
||||||
|
|
||||||
typedef std::vector<PrintRegion*> PrintRegionPtrs;
|
typedef std::vector<PrintRegion*> PrintRegionPtrs;
|
||||||
|
/*
|
||||||
typedef std::vector<const PrintRegion*> ConstPrintRegionPtrs;
|
typedef std::vector<const PrintRegion*> ConstPrintRegionPtrs;
|
||||||
class ConstPrintRegionPtrsAdaptor : public ConstVectorOfPtrsAdaptor<PrintRegion> {
|
class ConstPrintRegionPtrsAdaptor : public ConstVectorOfPtrsAdaptor<PrintRegion> {
|
||||||
friend Print;
|
friend Print;
|
||||||
ConstPrintRegionPtrsAdaptor(const PrintRegionPtrs *data) : ConstVectorOfPtrsAdaptor<PrintRegion>(data) {}
|
ConstPrintRegionPtrsAdaptor(const PrintRegionPtrs *data) : ConstVectorOfPtrsAdaptor<PrintRegion>(data) {}
|
||||||
};
|
};
|
||||||
|
*/
|
||||||
|
|
||||||
// The complete print tray with possibly multiple objects.
|
// The complete print tray with possibly multiple objects.
|
||||||
class Print : public PrintBaseWithState<PrintStep, psCount>
|
class Print : public PrintBaseWithState<PrintStep, psCount>
|
||||||
@ -467,14 +474,14 @@ public:
|
|||||||
[object_id](const PrintObject *obj) { return obj->id() == object_id; });
|
[object_id](const PrintObject *obj) { return obj->id() == object_id; });
|
||||||
return (it == m_objects.end()) ? nullptr : *it;
|
return (it == m_objects.end()) ? nullptr : *it;
|
||||||
}
|
}
|
||||||
ConstPrintRegionPtrsAdaptor regions() const { return ConstPrintRegionPtrsAdaptor(&m_regions); }
|
// ConstPrintRegionPtrsAdaptor regions() const { return ConstPrintRegionPtrsAdaptor(&m_regions); }
|
||||||
// How many of PrintObject::copies() over all print objects are there?
|
// How many of PrintObject::copies() over all print objects are there?
|
||||||
// If zero, then the print is empty and the print shall not be executed.
|
// If zero, then the print is empty and the print shall not be executed.
|
||||||
unsigned int num_object_instances() const;
|
unsigned int num_object_instances() const;
|
||||||
|
|
||||||
// For Perl bindings.
|
// For Perl bindings.
|
||||||
PrintObjectPtrs& objects_mutable() { return m_objects; }
|
PrintObjectPtrs& objects_mutable() { return m_objects; }
|
||||||
PrintRegionPtrs& regions_mutable() { return m_regions; }
|
PrintRegionPtrs& print_regions_mutable() { return m_print_regions; }
|
||||||
|
|
||||||
const ExtrusionEntityCollection& skirt() const { return m_skirt; }
|
const ExtrusionEntityCollection& skirt() const { return m_skirt; }
|
||||||
const ExtrusionEntityCollection& brim() const { return m_brim; }
|
const ExtrusionEntityCollection& brim() const { return m_brim; }
|
||||||
@ -496,14 +503,15 @@ public:
|
|||||||
std::string output_filename(const std::string &filename_base = std::string()) const override;
|
std::string output_filename(const std::string &filename_base = std::string()) const override;
|
||||||
|
|
||||||
// Accessed by SupportMaterial
|
// Accessed by SupportMaterial
|
||||||
const PrintRegion* get_region(size_t idx) const { return m_regions[idx]; }
|
size_t num_print_regions() const throw() { return m_print_regions.size(); }
|
||||||
|
const PrintRegion* get_print_region(size_t idx) const { return m_print_regions[idx]; }
|
||||||
const ToolOrdering& get_tool_ordering() const { return m_wipe_tower_data.tool_ordering; } // #ys_FIXME just for testing
|
const ToolOrdering& get_tool_ordering() const { return m_wipe_tower_data.tool_ordering; } // #ys_FIXME just for testing
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// methods for handling regions
|
// methods for handling regions
|
||||||
PrintRegion* get_region(size_t idx) { return m_regions[idx]; }
|
PrintRegion* get_print_region(size_t idx) { return m_print_regions[idx]; }
|
||||||
PrintRegion* add_region();
|
PrintRegion* add_print_region();
|
||||||
PrintRegion* add_region(const PrintRegionConfig &config);
|
PrintRegion* add_print_region(const PrintRegionConfig &config);
|
||||||
|
|
||||||
// Invalidates the step, and its depending steps in Print.
|
// Invalidates the step, and its depending steps in Print.
|
||||||
bool invalidate_step(PrintStep step);
|
bool invalidate_step(PrintStep step);
|
||||||
@ -524,7 +532,7 @@ private:
|
|||||||
PrintObjectConfig m_default_object_config;
|
PrintObjectConfig m_default_object_config;
|
||||||
PrintRegionConfig m_default_region_config;
|
PrintRegionConfig m_default_region_config;
|
||||||
PrintObjectPtrs m_objects;
|
PrintObjectPtrs m_objects;
|
||||||
PrintRegionPtrs m_regions;
|
PrintRegionPtrs m_print_regions;
|
||||||
|
|
||||||
// Ordered collections of extrusion paths to build skirt loops and brim.
|
// Ordered collections of extrusion paths to build skirt loops and brim.
|
||||||
ExtrusionEntityCollection m_skirt;
|
ExtrusionEntityCollection m_skirt;
|
||||||
|
@ -383,9 +383,9 @@ Print::ApplyStatus Print::apply(const Model &model, DynamicPrintConfig new_full_
|
|||||||
delete object;
|
delete object;
|
||||||
}
|
}
|
||||||
m_objects.clear();
|
m_objects.clear();
|
||||||
for (PrintRegion *region : m_regions)
|
for (PrintRegion *region : m_print_regions)
|
||||||
delete region;
|
delete region;
|
||||||
m_regions.clear();
|
m_print_regions.clear();
|
||||||
m_model.assign_copy(model);
|
m_model.assign_copy(model);
|
||||||
for (const ModelObject *model_object : m_model.objects)
|
for (const ModelObject *model_object : m_model.objects)
|
||||||
model_object_status.emplace(model_object->id(), ModelObjectStatus::New);
|
model_object_status.emplace(model_object->id(), ModelObjectStatus::New);
|
||||||
@ -682,21 +682,21 @@ Print::ApplyStatus Print::apply(const Model &model, DynamicPrintConfig new_full_
|
|||||||
// 5) Synchronize configs of ModelVolumes, synchronize AMF / 3MF materials (and their configs), refresh PrintRegions.
|
// 5) Synchronize configs of ModelVolumes, synchronize AMF / 3MF materials (and their configs), refresh PrintRegions.
|
||||||
// Update reference counts of regions from the remaining PrintObjects and their volumes.
|
// Update reference counts of regions from the remaining PrintObjects and their volumes.
|
||||||
// Regions with zero references could and should be reused.
|
// Regions with zero references could and should be reused.
|
||||||
for (PrintRegion *region : m_regions)
|
for (PrintRegion *region : m_print_regions)
|
||||||
region->m_refcnt = 0;
|
region->m_refcnt = 0;
|
||||||
for (PrintObject *print_object : m_objects) {
|
for (PrintObject *print_object : m_objects) {
|
||||||
int idx_region = 0;
|
int idx_region = 0;
|
||||||
for (const auto &volumes : print_object->region_volumes) {
|
for (const auto &volumes : print_object->m_region_volumes) {
|
||||||
if (! volumes.empty())
|
if (! volumes.empty())
|
||||||
++ m_regions[idx_region]->m_refcnt;
|
++ m_print_regions[idx_region]->m_refcnt;
|
||||||
++ idx_region;
|
++ idx_region;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// All regions now have distinct settings.
|
// All regions now have distinct settings.
|
||||||
// Check whether applying the new region config defaults we'd get different regions.
|
// Check whether applying the new region config defaults we'd get different regions.
|
||||||
for (size_t region_id = 0; region_id < m_regions.size(); ++ region_id) {
|
for (size_t region_id = 0; region_id < m_print_regions.size(); ++ region_id) {
|
||||||
PrintRegion ®ion = *m_regions[region_id];
|
PrintRegion ®ion = *m_print_regions[region_id];
|
||||||
PrintRegionConfig this_region_config;
|
PrintRegionConfig this_region_config;
|
||||||
bool this_region_config_set = false;
|
bool this_region_config_set = false;
|
||||||
for (PrintObject *print_object : m_objects) {
|
for (PrintObject *print_object : m_objects) {
|
||||||
@ -707,8 +707,8 @@ Print::ApplyStatus Print::apply(const Model &model, DynamicPrintConfig new_full_
|
|||||||
assert(it_status->status != ModelObjectStatus::Deleted);
|
assert(it_status->status != ModelObjectStatus::Deleted);
|
||||||
layer_ranges = &it_status->layer_ranges;
|
layer_ranges = &it_status->layer_ranges;
|
||||||
}
|
}
|
||||||
if (region_id < print_object->region_volumes.size()) {
|
if (region_id < print_object->m_region_volumes.size()) {
|
||||||
for (const std::pair<t_layer_height_range, int> &volume_and_range : print_object->region_volumes[region_id]) {
|
for (const std::pair<t_layer_height_range, int> &volume_and_range : print_object->m_region_volumes[region_id]) {
|
||||||
const ModelVolume &volume = *print_object->model_object()->volumes[volume_and_range.second];
|
const ModelVolume &volume = *print_object->model_object()->volumes[volume_and_range.second];
|
||||||
const DynamicPrintConfig *layer_range_config = layer_ranges->config(volume_and_range.first);
|
const DynamicPrintConfig *layer_range_config = layer_ranges->config(volume_and_range.first);
|
||||||
if (this_region_config_set) {
|
if (this_region_config_set) {
|
||||||
@ -721,7 +721,7 @@ Print::ApplyStatus Print::apply(const Model &model, DynamicPrintConfig new_full_
|
|||||||
} else {
|
} else {
|
||||||
this_region_config = PrintObject::region_config_from_model_volume(m_default_region_config, layer_range_config, volume, num_extruders);
|
this_region_config = PrintObject::region_config_from_model_volume(m_default_region_config, layer_range_config, volume, num_extruders);
|
||||||
for (size_t i = 0; i < region_id; ++ i) {
|
for (size_t i = 0; i < region_id; ++ i) {
|
||||||
const PrintRegion ®ion_other = *m_regions[i];
|
const PrintRegion ®ion_other = *m_print_regions[i];
|
||||||
if (region_other.m_refcnt != 0 && region_other.config().equals(this_region_config))
|
if (region_other.m_refcnt != 0 && region_other.config().equals(this_region_config))
|
||||||
// Regions were merged. Reset this print_object.
|
// Regions were merged. Reset this print_object.
|
||||||
goto print_object_end;
|
goto print_object_end;
|
||||||
@ -735,19 +735,19 @@ Print::ApplyStatus Print::apply(const Model &model, DynamicPrintConfig new_full_
|
|||||||
update_apply_status(print_object->invalidate_all_steps());
|
update_apply_status(print_object->invalidate_all_steps());
|
||||||
// Decrease the references to regions from this volume.
|
// Decrease the references to regions from this volume.
|
||||||
int ireg = 0;
|
int ireg = 0;
|
||||||
for (const std::vector<std::pair<t_layer_height_range, int>> &volumes : print_object->region_volumes) {
|
for (const std::vector<std::pair<t_layer_height_range, int>> &volumes : print_object->m_region_volumes) {
|
||||||
if (! volumes.empty())
|
if (! volumes.empty())
|
||||||
-- m_regions[ireg]->m_refcnt;
|
-- m_print_regions[ireg]->m_refcnt;
|
||||||
++ ireg;
|
++ ireg;
|
||||||
}
|
}
|
||||||
print_object->region_volumes.clear();
|
print_object->m_region_volumes.clear();
|
||||||
}
|
}
|
||||||
if (this_region_config_set) {
|
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()) {
|
if (! diff.empty()) {
|
||||||
// Stop the background process before assigning new configuration to the regions.
|
// Stop the background process before assigning new configuration to the regions.
|
||||||
for (PrintObject *print_object : m_objects)
|
for (PrintObject *print_object : m_objects)
|
||||||
if (region_id < print_object->region_volumes.size() && ! print_object->region_volumes[region_id].empty())
|
if (region_id < print_object->m_region_volumes.size() && ! print_object->m_region_volumes[region_id].empty())
|
||||||
update_apply_status(print_object->invalidate_state_by_config_options(region.config(), this_region_config, diff));
|
update_apply_status(print_object->invalidate_state_by_config_options(region.config(), this_region_config, diff));
|
||||||
region.config_apply_only(this_region_config, diff, false);
|
region.config_apply_only(this_region_config, diff, false);
|
||||||
}
|
}
|
||||||
@ -769,7 +769,7 @@ Print::ApplyStatus Print::apply(const Model &model, DynamicPrintConfig new_full_
|
|||||||
regions_in_object.reserve(64);
|
regions_in_object.reserve(64);
|
||||||
for (size_t i = idx_print_object; i < m_objects.size() && m_objects[i]->model_object() == &model_object; ++ i) {
|
for (size_t i = idx_print_object; i < m_objects.size() && m_objects[i]->model_object() == &model_object; ++ i) {
|
||||||
PrintObject &print_object = *m_objects[i];
|
PrintObject &print_object = *m_objects[i];
|
||||||
bool fresh = print_object.region_volumes.empty();
|
bool fresh = print_object.m_region_volumes.empty();
|
||||||
unsigned int volume_id = 0;
|
unsigned int volume_id = 0;
|
||||||
unsigned int idx_region_in_object = 0;
|
unsigned int idx_region_in_object = 0;
|
||||||
for (const ModelVolume *volume : model_object.volumes) {
|
for (const ModelVolume *volume : model_object.volumes) {
|
||||||
@ -786,11 +786,11 @@ Print::ApplyStatus Print::apply(const Model &model, DynamicPrintConfig new_full_
|
|||||||
PrintRegionConfig config = PrintObject::region_config_from_model_volume(m_default_region_config, it_range->second, *volume, num_extruders);
|
PrintRegionConfig config = PrintObject::region_config_from_model_volume(m_default_region_config, it_range->second, *volume, num_extruders);
|
||||||
// Find an existing print region with the same config.
|
// Find an existing print region with the same config.
|
||||||
int idx_empty_slot = -1;
|
int idx_empty_slot = -1;
|
||||||
for (int i = 0; i < (int)m_regions.size(); ++ i) {
|
for (int i = 0; i < int(m_print_regions.size()); ++ i) {
|
||||||
if (m_regions[i]->m_refcnt == 0) {
|
if (m_print_regions[i]->m_refcnt == 0) {
|
||||||
if (idx_empty_slot == -1)
|
if (idx_empty_slot == -1)
|
||||||
idx_empty_slot = i;
|
idx_empty_slot = i;
|
||||||
} else if (config.equals(m_regions[i]->config())) {
|
} else if (config.equals(m_print_regions[i]->config())) {
|
||||||
region_id = i;
|
region_id = i;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -798,11 +798,11 @@ Print::ApplyStatus Print::apply(const Model &model, DynamicPrintConfig new_full_
|
|||||||
// If no region exists with the same config, create a new one.
|
// If no region exists with the same config, create a new one.
|
||||||
if (region_id == -1) {
|
if (region_id == -1) {
|
||||||
if (idx_empty_slot == -1) {
|
if (idx_empty_slot == -1) {
|
||||||
region_id = (int)m_regions.size();
|
region_id = int(m_print_regions.size());
|
||||||
this->add_region(config);
|
this->add_print_region(config);
|
||||||
} else {
|
} else {
|
||||||
region_id = idx_empty_slot;
|
region_id = idx_empty_slot;
|
||||||
m_regions[region_id]->set_config(std::move(config));
|
m_print_regions[region_id]->set_config(std::move(config));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
regions_in_object.emplace_back(region_id);
|
regions_in_object.emplace_back(region_id);
|
||||||
@ -810,8 +810,8 @@ Print::ApplyStatus Print::apply(const Model &model, DynamicPrintConfig new_full_
|
|||||||
region_id = regions_in_object[idx_region_in_object ++];
|
region_id = regions_in_object[idx_region_in_object ++];
|
||||||
// Assign volume to a region.
|
// Assign volume to a region.
|
||||||
if (fresh) {
|
if (fresh) {
|
||||||
if ((size_t)region_id >= print_object.region_volumes.size() || print_object.region_volumes[region_id].empty())
|
if ((size_t)region_id >= print_object.m_region_volumes.size() || print_object.m_region_volumes[region_id].empty())
|
||||||
++ m_regions[region_id]->m_refcnt;
|
++ m_print_regions[region_id]->m_refcnt;
|
||||||
print_object.add_region_volume(region_id, volume_id, it_range->first);
|
print_object.add_region_volume(region_id, volume_id, it_range->first);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -97,6 +97,21 @@ PrintBase::ApplyStatus PrintObject::set_instances(PrintInstances &&instances)
|
|||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const PrintRegion& PrintObject::printing_region(size_t idx) const throw()
|
||||||
|
{
|
||||||
|
return *m_print->get_print_region(idx);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<const PrintRegion*> PrintObject::all_regions() const
|
||||||
|
{
|
||||||
|
std::vector<const PrintRegion*> out;
|
||||||
|
out.reserve(m_region_volumes.size());
|
||||||
|
for (size_t i = 0; i < m_region_volumes.size(); ++ i)
|
||||||
|
if (! m_region_volumes[i].empty())
|
||||||
|
out.emplace_back(m_print->get_print_region(i));
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
// Called by make_perimeters()
|
// Called by make_perimeters()
|
||||||
// 1) Decides Z positions of the layers,
|
// 1) Decides Z positions of the layers,
|
||||||
// 2) Initializes layers and their regions
|
// 2) Initializes layers and their regions
|
||||||
@ -173,8 +188,8 @@ void PrintObject::make_perimeters()
|
|||||||
// but we don't generate any extra perimeter if fill density is zero, as they would be floating
|
// 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
|
// inside the object - infill_only_where_needed should be the method of choice for printing
|
||||||
// hollow objects
|
// hollow objects
|
||||||
for (size_t region_id = 0; region_id < this->region_volumes.size(); ++ region_id) {
|
for (size_t region_id = 0; region_id < this->num_printing_regions(); ++ region_id) {
|
||||||
const PrintRegion ®ion = *m_print->regions()[region_id];
|
const PrintRegion ®ion = this->printing_region(region_id);
|
||||||
if (! region.config().extra_perimeters || region.config().perimeters == 0 || region.config().fill_density == 0 || this->layer_count() < 2)
|
if (! region.config().extra_perimeters || region.config().perimeters == 0 || region.config().fill_density == 0 || this->layer_count() < 2)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
@ -294,7 +309,7 @@ void PrintObject::prepare_infill()
|
|||||||
|
|
||||||
// Debugging output.
|
// Debugging output.
|
||||||
#ifdef SLIC3R_DEBUG_SLICE_PROCESSING
|
#ifdef SLIC3R_DEBUG_SLICE_PROCESSING
|
||||||
for (size_t region_id = 0; region_id < this->region_volumes.size(); ++ region_id) {
|
for (size_t region_id = 0; region_id < this->num_printing_regions(); ++ region_id) {
|
||||||
for (const Layer *layer : m_layers) {
|
for (const Layer *layer : m_layers) {
|
||||||
LayerRegion *layerm = layer->m_regions[region_id];
|
LayerRegion *layerm = layer->m_regions[region_id];
|
||||||
layerm->export_region_slices_to_svg_debug("6_discover_vertical_shells-final");
|
layerm->export_region_slices_to_svg_debug("6_discover_vertical_shells-final");
|
||||||
@ -313,7 +328,7 @@ void PrintObject::prepare_infill()
|
|||||||
m_print->throw_if_canceled();
|
m_print->throw_if_canceled();
|
||||||
|
|
||||||
#ifdef SLIC3R_DEBUG_SLICE_PROCESSING
|
#ifdef SLIC3R_DEBUG_SLICE_PROCESSING
|
||||||
for (size_t region_id = 0; region_id < this->region_volumes.size(); ++ region_id) {
|
for (size_t region_id = 0; region_id < this->num_printing_regions(); ++ region_id) {
|
||||||
for (const Layer *layer : m_layers) {
|
for (const Layer *layer : m_layers) {
|
||||||
LayerRegion *layerm = layer->m_regions[region_id];
|
LayerRegion *layerm = layer->m_regions[region_id];
|
||||||
layerm->export_region_slices_to_svg_debug("7_discover_horizontal_shells-final");
|
layerm->export_region_slices_to_svg_debug("7_discover_horizontal_shells-final");
|
||||||
@ -332,7 +347,7 @@ void PrintObject::prepare_infill()
|
|||||||
m_print->throw_if_canceled();
|
m_print->throw_if_canceled();
|
||||||
|
|
||||||
#ifdef SLIC3R_DEBUG_SLICE_PROCESSING
|
#ifdef SLIC3R_DEBUG_SLICE_PROCESSING
|
||||||
for (size_t region_id = 0; region_id < this->region_volumes.size(); ++ region_id) {
|
for (size_t region_id = 0; region_id < this->num_printing_regions(); ++ region_id) {
|
||||||
for (const Layer *layer : m_layers) {
|
for (const Layer *layer : m_layers) {
|
||||||
LayerRegion *layerm = layer->m_regions[region_id];
|
LayerRegion *layerm = layer->m_regions[region_id];
|
||||||
layerm->export_region_slices_to_svg_debug("8_clip_surfaces-final");
|
layerm->export_region_slices_to_svg_debug("8_clip_surfaces-final");
|
||||||
@ -351,7 +366,7 @@ void PrintObject::prepare_infill()
|
|||||||
m_print->throw_if_canceled();
|
m_print->throw_if_canceled();
|
||||||
|
|
||||||
#ifdef SLIC3R_DEBUG_SLICE_PROCESSING
|
#ifdef SLIC3R_DEBUG_SLICE_PROCESSING
|
||||||
for (size_t region_id = 0; region_id < this->region_volumes.size(); ++ region_id) {
|
for (size_t region_id = 0; region_id < this->num_printing_regions(); ++ region_id) {
|
||||||
for (const Layer *layer : m_layers) {
|
for (const Layer *layer : m_layers) {
|
||||||
LayerRegion *layerm = layer->m_regions[region_id];
|
LayerRegion *layerm = layer->m_regions[region_id];
|
||||||
layerm->export_region_slices_to_svg_debug("9_prepare_infill-final");
|
layerm->export_region_slices_to_svg_debug("9_prepare_infill-final");
|
||||||
@ -736,19 +751,11 @@ bool PrintObject::invalidate_all_steps()
|
|||||||
// First call the "invalidate" functions, which may cancel background processing.
|
// First call the "invalidate" functions, which may cancel background processing.
|
||||||
bool result = Inherited::invalidate_all_steps() | m_print->invalidate_all_steps();
|
bool result = Inherited::invalidate_all_steps() | m_print->invalidate_all_steps();
|
||||||
// Then reset some of the depending values.
|
// Then reset some of the depending values.
|
||||||
this->m_slicing_params.valid = false;
|
m_slicing_params.valid = false;
|
||||||
this->region_volumes.clear();
|
m_region_volumes.clear();
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const PrintRegion* first_printing_region(const PrintObject &print_object)
|
|
||||||
{
|
|
||||||
for (size_t idx_region = 0; idx_region < print_object.region_volumes.size(); ++ idx_region)
|
|
||||||
if (!print_object.region_volumes.empty())
|
|
||||||
return print_object.print()->regions()[idx_region];
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
// This function analyzes slices of a region (SurfaceCollection slices).
|
// This function analyzes slices of a region (SurfaceCollection slices).
|
||||||
// Each region slice (instance of Surface) is analyzed, whether it is supported or whether it is the top surface.
|
// Each region slice (instance of Surface) is analyzed, whether it is supported or whether it is the top surface.
|
||||||
// Initially all slices are of type stInternal.
|
// Initially all slices are of type stInternal.
|
||||||
@ -769,9 +776,9 @@ void PrintObject::detect_surfaces_type()
|
|||||||
// should be visible.
|
// should be visible.
|
||||||
bool spiral_vase = this->print()->config().spiral_vase.value;
|
bool spiral_vase = this->print()->config().spiral_vase.value;
|
||||||
bool interface_shells = ! spiral_vase && m_config.interface_shells.value;
|
bool interface_shells = ! spiral_vase && m_config.interface_shells.value;
|
||||||
size_t num_layers = spiral_vase ? std::min(size_t(first_printing_region(*this)->config().bottom_solid_layers), m_layers.size()) : m_layers.size();
|
size_t num_layers = spiral_vase ? std::min(size_t(this->printing_region(0).config().bottom_solid_layers), m_layers.size()) : m_layers.size();
|
||||||
|
|
||||||
for (size_t idx_region = 0; idx_region < this->region_volumes.size(); ++ idx_region) {
|
for (size_t idx_region = 0; idx_region < this->num_printing_regions(); ++ idx_region) {
|
||||||
BOOST_LOG_TRIVIAL(debug) << "Detecting solid surfaces for region " << idx_region << " in parallel - start";
|
BOOST_LOG_TRIVIAL(debug) << "Detecting solid surfaces for region " << idx_region << " in parallel - start";
|
||||||
#ifdef SLIC3R_DEBUG_SLICE_PROCESSING
|
#ifdef SLIC3R_DEBUG_SLICE_PROCESSING
|
||||||
for (Layer *layer : m_layers)
|
for (Layer *layer : m_layers)
|
||||||
@ -966,8 +973,8 @@ void PrintObject::process_external_surfaces()
|
|||||||
// Is there any printing region, that has zero infill? If so, then we don't want the expansion to be performed over the complete voids, but only
|
// Is there any printing region, that has zero infill? If so, then we don't want the expansion to be performed over the complete voids, but only
|
||||||
// over voids, which are supported by the layer below.
|
// over voids, which are supported by the layer below.
|
||||||
bool has_voids = false;
|
bool has_voids = false;
|
||||||
for (size_t region_id = 0; region_id < this->region_volumes.size(); ++ region_id)
|
for (size_t region_id = 0; region_id < this->num_printing_regions(); ++ region_id)
|
||||||
if (! this->region_volumes.empty() && this->print()->regions()[region_id]->config().fill_density == 0) {
|
if (this->printing_region(region_id).config().fill_density == 0) {
|
||||||
has_voids = true;
|
has_voids = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -1016,7 +1023,7 @@ void PrintObject::process_external_surfaces()
|
|||||||
BOOST_LOG_TRIVIAL(debug) << "Collecting surfaces covered with extrusions in parallel - end";
|
BOOST_LOG_TRIVIAL(debug) << "Collecting surfaces covered with extrusions in parallel - end";
|
||||||
}
|
}
|
||||||
|
|
||||||
for (size_t region_id = 0; region_id < this->region_volumes.size(); ++region_id) {
|
for (size_t region_id = 0; region_id < this->num_printing_regions(); ++region_id) {
|
||||||
BOOST_LOG_TRIVIAL(debug) << "Processing external surfaces for region " << region_id << " in parallel - start";
|
BOOST_LOG_TRIVIAL(debug) << "Processing external surfaces for region " << region_id << " in parallel - start";
|
||||||
tbb::parallel_for(
|
tbb::parallel_for(
|
||||||
tbb::blocked_range<size_t>(0, m_layers.size()),
|
tbb::blocked_range<size_t>(0, m_layers.size()),
|
||||||
@ -1024,7 +1031,7 @@ void PrintObject::process_external_surfaces()
|
|||||||
for (size_t layer_idx = range.begin(); layer_idx < range.end(); ++ layer_idx) {
|
for (size_t layer_idx = range.begin(); layer_idx < range.end(); ++ layer_idx) {
|
||||||
m_print->throw_if_canceled();
|
m_print->throw_if_canceled();
|
||||||
// BOOST_LOG_TRIVIAL(trace) << "Processing external surface, layer" << m_layers[layer_idx]->print_z;
|
// BOOST_LOG_TRIVIAL(trace) << "Processing external surface, layer" << m_layers[layer_idx]->print_z;
|
||||||
m_layers[layer_idx]->get_region((int)region_id)->process_external_surfaces(
|
m_layers[layer_idx]->get_region(int(region_id))->process_external_surfaces(
|
||||||
(layer_idx == 0) ? nullptr : m_layers[layer_idx - 1],
|
(layer_idx == 0) ? nullptr : m_layers[layer_idx - 1],
|
||||||
(layer_idx == 0 || surfaces_covered.empty() || surfaces_covered[layer_idx - 1].empty()) ? nullptr : &surfaces_covered[layer_idx - 1]);
|
(layer_idx == 0 || surfaces_covered.empty() || surfaces_covered[layer_idx - 1].empty()) ? nullptr : &surfaces_covered[layer_idx - 1]);
|
||||||
}
|
}
|
||||||
@ -1049,7 +1056,7 @@ void PrintObject::discover_vertical_shells()
|
|||||||
Polygons holes;
|
Polygons holes;
|
||||||
};
|
};
|
||||||
bool spiral_vase = this->print()->config().spiral_vase.value;
|
bool spiral_vase = this->print()->config().spiral_vase.value;
|
||||||
size_t num_layers = spiral_vase ? std::min(size_t(first_printing_region(*this)->config().bottom_solid_layers), m_layers.size()) : m_layers.size();
|
size_t num_layers = spiral_vase ? std::min(size_t(this->printing_region(0).config().bottom_solid_layers), m_layers.size()) : m_layers.size();
|
||||||
coordf_t min_layer_height = this->slicing_parameters().min_layer_height;
|
coordf_t min_layer_height = this->slicing_parameters().min_layer_height;
|
||||||
// Does this region possibly produce more than 1 top or bottom layer?
|
// Does this region possibly produce more than 1 top or bottom layer?
|
||||||
auto has_extra_layers_fn = [min_layer_height](const PrintRegionConfig &config) {
|
auto has_extra_layers_fn = [min_layer_height](const PrintRegionConfig &config) {
|
||||||
@ -1064,14 +1071,14 @@ void PrintObject::discover_vertical_shells()
|
|||||||
num_extra_layers(config.bottom_solid_layers, config.bottom_solid_min_thickness) > 0;
|
num_extra_layers(config.bottom_solid_layers, config.bottom_solid_min_thickness) > 0;
|
||||||
};
|
};
|
||||||
std::vector<DiscoverVerticalShellsCacheEntry> cache_top_botom_regions(num_layers, DiscoverVerticalShellsCacheEntry());
|
std::vector<DiscoverVerticalShellsCacheEntry> cache_top_botom_regions(num_layers, DiscoverVerticalShellsCacheEntry());
|
||||||
bool top_bottom_surfaces_all_regions = this->region_volumes.size() > 1 && ! m_config.interface_shells.value;
|
bool top_bottom_surfaces_all_regions = this->num_printing_regions() > 1 && ! m_config.interface_shells.value;
|
||||||
if (top_bottom_surfaces_all_regions) {
|
if (top_bottom_surfaces_all_regions) {
|
||||||
// This is a multi-material print and interface_shells are disabled, meaning that the vertical shell thickness
|
// This is a multi-material print and interface_shells are disabled, meaning that the vertical shell thickness
|
||||||
// is calculated over all materials.
|
// is calculated over all materials.
|
||||||
// Is the "ensure vertical wall thickness" applicable to any region?
|
// Is the "ensure vertical wall thickness" applicable to any region?
|
||||||
bool has_extra_layers = false;
|
bool has_extra_layers = false;
|
||||||
for (size_t idx_region = 0; idx_region < this->region_volumes.size(); ++idx_region) {
|
for (size_t idx_region = 0; idx_region < this->num_printing_regions(); ++idx_region) {
|
||||||
const PrintRegionConfig &config = m_print->get_region(idx_region)->config();
|
const PrintRegionConfig &config = this->printing_region(idx_region).config();
|
||||||
if (config.ensure_vertical_shell_thickness.value && has_extra_layers_fn(config)) {
|
if (config.ensure_vertical_shell_thickness.value && has_extra_layers_fn(config)) {
|
||||||
has_extra_layers = true;
|
has_extra_layers = true;
|
||||||
break;
|
break;
|
||||||
@ -1087,7 +1094,7 @@ void PrintObject::discover_vertical_shells()
|
|||||||
tbb::blocked_range<size_t>(0, num_layers, grain_size),
|
tbb::blocked_range<size_t>(0, num_layers, grain_size),
|
||||||
[this, &cache_top_botom_regions](const tbb::blocked_range<size_t>& range) {
|
[this, &cache_top_botom_regions](const tbb::blocked_range<size_t>& range) {
|
||||||
const SurfaceType surfaces_bottom[2] = { stBottom, stBottomBridge };
|
const SurfaceType surfaces_bottom[2] = { stBottom, stBottomBridge };
|
||||||
const size_t num_regions = this->region_volumes.size();
|
const size_t num_regions = this->num_printing_regions();
|
||||||
for (size_t idx_layer = range.begin(); idx_layer < range.end(); ++ idx_layer) {
|
for (size_t idx_layer = range.begin(); idx_layer < range.end(); ++ idx_layer) {
|
||||||
m_print->throw_if_canceled();
|
m_print->throw_if_canceled();
|
||||||
const Layer &layer = *m_layers[idx_layer];
|
const Layer &layer = *m_layers[idx_layer];
|
||||||
@ -1148,10 +1155,10 @@ void PrintObject::discover_vertical_shells()
|
|||||||
BOOST_LOG_TRIVIAL(debug) << "Discovering vertical shells in parallel - end : cache top / bottom";
|
BOOST_LOG_TRIVIAL(debug) << "Discovering vertical shells in parallel - end : cache top / bottom";
|
||||||
}
|
}
|
||||||
|
|
||||||
for (size_t idx_region = 0; idx_region < this->region_volumes.size(); ++ idx_region) {
|
for (size_t idx_region = 0; idx_region < this->num_printing_regions(); ++ idx_region) {
|
||||||
PROFILE_BLOCK(discover_vertical_shells_region);
|
PROFILE_BLOCK(discover_vertical_shells_region);
|
||||||
|
|
||||||
const PrintRegion ®ion = *m_print->get_region(idx_region);
|
const PrintRegion ®ion = this->printing_region(idx_region);
|
||||||
if (! region.config().ensure_vertical_shell_thickness.value)
|
if (! region.config().ensure_vertical_shell_thickness.value)
|
||||||
// This region will be handled by discover_horizontal_shells().
|
// This region will be handled by discover_horizontal_shells().
|
||||||
continue;
|
continue;
|
||||||
@ -1445,8 +1452,8 @@ void PrintObject::bridge_over_infill()
|
|||||||
{
|
{
|
||||||
BOOST_LOG_TRIVIAL(info) << "Bridge over infill..." << log_memory_info();
|
BOOST_LOG_TRIVIAL(info) << "Bridge over infill..." << log_memory_info();
|
||||||
|
|
||||||
for (size_t region_id = 0; region_id < this->region_volumes.size(); ++ region_id) {
|
for (size_t region_id = 0; region_id < this->num_printing_regions(); ++ region_id) {
|
||||||
const PrintRegion ®ion = *m_print->regions()[region_id];
|
const PrintRegion ®ion = this->printing_region(region_id);
|
||||||
|
|
||||||
// skip bridging in case there are no voids
|
// skip bridging in case there are no voids
|
||||||
if (region.config().fill_density.value == 100)
|
if (region.config().fill_density.value == 100)
|
||||||
@ -1672,10 +1679,9 @@ SlicingParameters PrintObject::slicing_parameters(const DynamicPrintConfig& full
|
|||||||
std::vector<unsigned int> PrintObject::object_extruders() const
|
std::vector<unsigned int> PrintObject::object_extruders() const
|
||||||
{
|
{
|
||||||
std::vector<unsigned int> extruders;
|
std::vector<unsigned int> extruders;
|
||||||
extruders.reserve(this->region_volumes.size() * 3);
|
extruders.reserve(this->all_regions().size() * 3);
|
||||||
for (size_t idx_region = 0; idx_region < this->region_volumes.size(); ++ idx_region)
|
for (const PrintRegion *region : this->all_regions())
|
||||||
if (! this->region_volumes[idx_region].empty())
|
region->collect_object_printing_extruders(*this->print(), extruders);
|
||||||
m_print->get_region(idx_region)->collect_object_printing_extruders(*this->print(), extruders);
|
|
||||||
sort_remove_duplicates(extruders);
|
sort_remove_duplicates(extruders);
|
||||||
return extruders;
|
return extruders;
|
||||||
}
|
}
|
||||||
@ -1743,8 +1749,8 @@ void PrintObject::_slice(const std::vector<coordf_t> &layer_height_profile)
|
|||||||
layer->lower_layer = prev;
|
layer->lower_layer = prev;
|
||||||
}
|
}
|
||||||
// Make sure all layers contain layer region objects for all regions.
|
// Make sure all layers contain layer region objects for all regions.
|
||||||
for (size_t region_id = 0; region_id < this->region_volumes.size(); ++ region_id)
|
for (size_t region_id = 0; region_id < m_region_volumes.size(); ++ region_id)
|
||||||
layer->add_region(this->print()->get_region(region_id));
|
layer->add_region(this->print()->get_print_region(region_id));
|
||||||
prev = layer;
|
prev = layer;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1754,9 +1760,9 @@ void PrintObject::_slice(const std::vector<coordf_t> &layer_height_profile)
|
|||||||
bool has_z_ranges = false;
|
bool has_z_ranges = false;
|
||||||
size_t num_volumes = 0;
|
size_t num_volumes = 0;
|
||||||
size_t num_modifiers = 0;
|
size_t num_modifiers = 0;
|
||||||
for (int region_id = 0; region_id < (int)this->region_volumes.size(); ++ region_id) {
|
for (int region_id = 0; region_id < int(m_region_volumes.size()); ++ region_id) {
|
||||||
int last_volume_id = -1;
|
int last_volume_id = -1;
|
||||||
for (const std::pair<t_layer_height_range, int> &volume_and_range : this->region_volumes[region_id]) {
|
for (const std::pair<t_layer_height_range, int> &volume_and_range : m_region_volumes[region_id]) {
|
||||||
const int volume_id = volume_and_range.second;
|
const int volume_id = volume_and_range.second;
|
||||||
const ModelVolume *model_volume = this->model_object()->volumes[volume_id];
|
const ModelVolume *model_volume = this->model_object()->volumes[volume_id];
|
||||||
if (model_volume->is_model_part()) {
|
if (model_volume->is_model_part()) {
|
||||||
@ -1786,14 +1792,14 @@ void PrintObject::_slice(const std::vector<coordf_t> &layer_height_profile)
|
|||||||
if (! has_z_ranges && (! m_config.clip_multipart_objects.value || all_volumes_single_region >= 0)) {
|
if (! has_z_ranges && (! m_config.clip_multipart_objects.value || all_volumes_single_region >= 0)) {
|
||||||
// Cheap path: Slice regions without mutual clipping.
|
// Cheap path: Slice regions without mutual clipping.
|
||||||
// The cheap path is possible if no clipping is allowed or if slicing volumes of just a single region.
|
// The cheap path is possible if no clipping is allowed or if slicing volumes of just a single region.
|
||||||
for (size_t region_id = 0; region_id < this->region_volumes.size(); ++ region_id) {
|
for (size_t region_id = 0; region_id < m_region_volumes.size(); ++ region_id) {
|
||||||
BOOST_LOG_TRIVIAL(debug) << "Slicing objects - region " << region_id;
|
BOOST_LOG_TRIVIAL(debug) << "Slicing objects - region " << region_id;
|
||||||
// slicing in parallel
|
// slicing in parallel
|
||||||
size_t slicing_mode_normal_below_layer = 0;
|
size_t slicing_mode_normal_below_layer = 0;
|
||||||
if (spiral_vase) {
|
if (spiral_vase) {
|
||||||
// Slice the bottom layers with SlicingMode::Regular.
|
// Slice the bottom layers with SlicingMode::Regular.
|
||||||
// This needs to be in sync with LayerRegion::make_perimeters() spiral_vase!
|
// This needs to be in sync with LayerRegion::make_perimeters() spiral_vase!
|
||||||
const PrintRegionConfig &config = this->print()->regions()[region_id]->config();
|
const PrintRegionConfig &config = this->print()->get_print_region(region_id)->config();
|
||||||
slicing_mode_normal_below_layer = size_t(config.bottom_solid_layers.value);
|
slicing_mode_normal_below_layer = size_t(config.bottom_solid_layers.value);
|
||||||
for (; slicing_mode_normal_below_layer < slice_zs.size() && slice_zs[slicing_mode_normal_below_layer] < config.bottom_solid_min_thickness - EPSILON;
|
for (; slicing_mode_normal_below_layer < slice_zs.size() && slice_zs[slicing_mode_normal_below_layer] < config.bottom_solid_min_thickness - EPSILON;
|
||||||
++ slicing_mode_normal_below_layer);
|
++ slicing_mode_normal_below_layer);
|
||||||
@ -1819,8 +1825,8 @@ void PrintObject::_slice(const std::vector<coordf_t> &layer_height_profile)
|
|||||||
};
|
};
|
||||||
std::vector<SlicedVolume> sliced_volumes;
|
std::vector<SlicedVolume> sliced_volumes;
|
||||||
sliced_volumes.reserve(num_volumes);
|
sliced_volumes.reserve(num_volumes);
|
||||||
for (size_t region_id = 0; region_id < this->region_volumes.size(); ++ region_id) {
|
for (size_t region_id = 0; region_id < m_region_volumes.size(); ++ region_id) {
|
||||||
const std::vector<std::pair<t_layer_height_range, int>> &volumes_and_ranges = this->region_volumes[region_id];
|
const std::vector<std::pair<t_layer_height_range, int>> &volumes_and_ranges = m_region_volumes[region_id];
|
||||||
for (size_t i = 0; i < volumes_and_ranges.size(); ) {
|
for (size_t i = 0; i < volumes_and_ranges.size(); ) {
|
||||||
int volume_id = volumes_and_ranges[i].second;
|
int volume_id = volumes_and_ranges[i].second;
|
||||||
const ModelVolume *model_volume = this->model_object()->volumes[volume_id];
|
const ModelVolume *model_volume = this->model_object()->volumes[volume_id];
|
||||||
@ -1871,7 +1877,7 @@ void PrintObject::_slice(const std::vector<coordf_t> &layer_height_profile)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Collect and union volumes of a single region.
|
// Collect and union volumes of a single region.
|
||||||
for (int region_id = 0; region_id < (int)this->region_volumes.size(); ++ region_id) {
|
for (int region_id = 0; region_id < int(m_region_volumes.size()); ++ region_id) {
|
||||||
ExPolygons expolygons;
|
ExPolygons expolygons;
|
||||||
size_t num_volumes = 0;
|
size_t num_volumes = 0;
|
||||||
for (SlicedVolume &sliced_volume : sliced_volumes)
|
for (SlicedVolume &sliced_volume : sliced_volumes)
|
||||||
@ -1892,8 +1898,8 @@ void PrintObject::_slice(const std::vector<coordf_t> &layer_height_profile)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Slice all modifier volumes.
|
// Slice all modifier volumes.
|
||||||
if (this->region_volumes.size() > 1) {
|
if (m_region_volumes.size() > 1) {
|
||||||
for (size_t region_id = 0; region_id < this->region_volumes.size(); ++ region_id) {
|
for (size_t region_id = 0; region_id < m_region_volumes.size(); ++ region_id) {
|
||||||
BOOST_LOG_TRIVIAL(debug) << "Slicing modifier volumes - region " << region_id;
|
BOOST_LOG_TRIVIAL(debug) << "Slicing modifier volumes - region " << region_id;
|
||||||
// slicing in parallel
|
// slicing in parallel
|
||||||
std::vector<ExPolygons> expolygons_by_layer = this->slice_modifiers(region_id, slice_zs);
|
std::vector<ExPolygons> expolygons_by_layer = this->slice_modifiers(region_id, slice_zs);
|
||||||
@ -1906,7 +1912,7 @@ void PrintObject::_slice(const std::vector<coordf_t> &layer_height_profile)
|
|||||||
tbb::blocked_range<size_t>(0, m_layers.size()),
|
tbb::blocked_range<size_t>(0, m_layers.size()),
|
||||||
[this, &expolygons_by_layer, region_id](const tbb::blocked_range<size_t>& range) {
|
[this, &expolygons_by_layer, region_id](const tbb::blocked_range<size_t>& range) {
|
||||||
for (size_t layer_id = range.begin(); layer_id < range.end(); ++ layer_id) {
|
for (size_t layer_id = range.begin(); layer_id < range.end(); ++ layer_id) {
|
||||||
for (size_t other_region_id = 0; other_region_id < this->region_volumes.size(); ++ other_region_id) {
|
for (size_t other_region_id = 0; other_region_id < m_region_volumes.size(); ++ other_region_id) {
|
||||||
if (region_id == other_region_id)
|
if (region_id == other_region_id)
|
||||||
continue;
|
continue;
|
||||||
Layer *layer = m_layers[layer_id];
|
Layer *layer = m_layers[layer_id];
|
||||||
@ -2046,8 +2052,8 @@ end:
|
|||||||
std::vector<ExPolygons> PrintObject::slice_region(size_t region_id, const std::vector<float> &z, SlicingMode mode, size_t slicing_mode_normal_below_layer, SlicingMode mode_below) const
|
std::vector<ExPolygons> PrintObject::slice_region(size_t region_id, const std::vector<float> &z, SlicingMode mode, size_t slicing_mode_normal_below_layer, SlicingMode mode_below) const
|
||||||
{
|
{
|
||||||
std::vector<const ModelVolume*> volumes;
|
std::vector<const ModelVolume*> volumes;
|
||||||
if (region_id < this->region_volumes.size()) {
|
if (region_id < m_region_volumes.size()) {
|
||||||
for (const std::pair<t_layer_height_range, int> &volume_and_range : this->region_volumes[region_id]) {
|
for (const std::pair<t_layer_height_range, int> &volume_and_range : m_region_volumes[region_id]) {
|
||||||
const ModelVolume *volume = this->model_object()->volumes[volume_and_range.second];
|
const ModelVolume *volume = this->model_object()->volumes[volume_and_range.second];
|
||||||
if (volume->is_model_part())
|
if (volume->is_model_part())
|
||||||
volumes.emplace_back(volume);
|
volumes.emplace_back(volume);
|
||||||
@ -2060,10 +2066,10 @@ std::vector<ExPolygons> PrintObject::slice_region(size_t region_id, const std::v
|
|||||||
std::vector<ExPolygons> PrintObject::slice_modifiers(size_t region_id, const std::vector<float> &slice_zs) const
|
std::vector<ExPolygons> PrintObject::slice_modifiers(size_t region_id, const std::vector<float> &slice_zs) const
|
||||||
{
|
{
|
||||||
std::vector<ExPolygons> out;
|
std::vector<ExPolygons> out;
|
||||||
if (region_id < this->region_volumes.size())
|
if (region_id < m_region_volumes.size())
|
||||||
{
|
{
|
||||||
std::vector<std::vector<t_layer_height_range>> volume_ranges;
|
std::vector<std::vector<t_layer_height_range>> volume_ranges;
|
||||||
const std::vector<std::pair<t_layer_height_range, int>> &volumes_and_ranges = this->region_volumes[region_id];
|
const std::vector<std::pair<t_layer_height_range, int>> &volumes_and_ranges = m_region_volumes[region_id];
|
||||||
volume_ranges.reserve(volumes_and_ranges.size());
|
volume_ranges.reserve(volumes_and_ranges.size());
|
||||||
for (size_t i = 0; i < volumes_and_ranges.size(); ) {
|
for (size_t i = 0; i < volumes_and_ranges.size(); ) {
|
||||||
int volume_id = volumes_and_ranges[i].second;
|
int volume_id = volumes_and_ranges[i].second;
|
||||||
@ -2098,7 +2104,7 @@ std::vector<ExPolygons> PrintObject::slice_modifiers(size_t region_id, const std
|
|||||||
if (equal_ranges && volume_ranges.front().size() == 1 && volume_ranges.front().front() == t_layer_height_range(0, DBL_MAX)) {
|
if (equal_ranges && volume_ranges.front().size() == 1 && volume_ranges.front().front() == t_layer_height_range(0, DBL_MAX)) {
|
||||||
// No modifier in this region was split to layer spans.
|
// No modifier in this region was split to layer spans.
|
||||||
std::vector<const ModelVolume*> volumes;
|
std::vector<const ModelVolume*> volumes;
|
||||||
for (const std::pair<t_layer_height_range, int> &volume_and_range : this->region_volumes[region_id]) {
|
for (const std::pair<t_layer_height_range, int> &volume_and_range : m_region_volumes[region_id]) {
|
||||||
const ModelVolume *volume = this->model_object()->volumes[volume_and_range.second];
|
const ModelVolume *volume = this->model_object()->volumes[volume_and_range.second];
|
||||||
if (volume->is_modifier())
|
if (volume->is_modifier())
|
||||||
volumes.emplace_back(volume);
|
volumes.emplace_back(volume);
|
||||||
@ -2107,8 +2113,8 @@ std::vector<ExPolygons> PrintObject::slice_modifiers(size_t region_id, const std
|
|||||||
} else {
|
} else {
|
||||||
// Some modifier in this region was split to layer spans.
|
// Some modifier in this region was split to layer spans.
|
||||||
std::vector<char> merge;
|
std::vector<char> merge;
|
||||||
for (size_t region_id = 0; region_id < this->region_volumes.size(); ++ region_id) {
|
for (size_t region_id = 0; region_id < m_region_volumes.size(); ++ region_id) {
|
||||||
const std::vector<std::pair<t_layer_height_range, int>> &volumes_and_ranges = this->region_volumes[region_id];
|
const std::vector<std::pair<t_layer_height_range, int>> &volumes_and_ranges = m_region_volumes[region_id];
|
||||||
for (size_t i = 0; i < volumes_and_ranges.size(); ) {
|
for (size_t i = 0; i < volumes_and_ranges.size(); ) {
|
||||||
int volume_id = volumes_and_ranges[i].second;
|
int volume_id = volumes_and_ranges[i].second;
|
||||||
const ModelVolume *model_volume = this->model_object()->volumes[volume_id];
|
const ModelVolume *model_volume = this->model_object()->volumes[volume_id];
|
||||||
@ -2395,9 +2401,15 @@ void PrintObject::simplify_slices(double distance)
|
|||||||
// fill_surfaces but we only turn them into VOID surfaces, thus preserving the boundaries.
|
// fill_surfaces but we only turn them into VOID surfaces, thus preserving the boundaries.
|
||||||
void PrintObject::clip_fill_surfaces()
|
void PrintObject::clip_fill_surfaces()
|
||||||
{
|
{
|
||||||
if (! m_config.infill_only_where_needed.value ||
|
if (! m_config.infill_only_where_needed.value)
|
||||||
! std::any_of(this->print()->regions().begin(), this->print()->regions().end(),
|
return;
|
||||||
[](const PrintRegion *region) { return region->config().fill_density > 0; }))
|
bool has_infill = false;
|
||||||
|
for (size_t i = 0; i < this->num_printing_regions(); ++ i)
|
||||||
|
if (this->printing_region(i).config().fill_density > 0) {
|
||||||
|
has_infill = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (! has_infill)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// We only want infill under ceilings; this is almost like an
|
// We only want infill under ceilings; this is almost like an
|
||||||
@ -2475,7 +2487,7 @@ void PrintObject::discover_horizontal_shells()
|
|||||||
{
|
{
|
||||||
BOOST_LOG_TRIVIAL(trace) << "discover_horizontal_shells()";
|
BOOST_LOG_TRIVIAL(trace) << "discover_horizontal_shells()";
|
||||||
|
|
||||||
for (size_t region_id = 0; region_id < this->region_volumes.size(); ++ region_id) {
|
for (size_t region_id = 0; region_id < this->num_printing_regions(); ++ region_id) {
|
||||||
for (size_t i = 0; i < m_layers.size(); ++ i) {
|
for (size_t i = 0; i < m_layers.size(); ++ i) {
|
||||||
m_print->throw_if_canceled();
|
m_print->throw_if_canceled();
|
||||||
Layer *layer = m_layers[i];
|
Layer *layer = m_layers[i];
|
||||||
@ -2656,7 +2668,7 @@ void PrintObject::discover_horizontal_shells()
|
|||||||
} // for each region
|
} // for each region
|
||||||
|
|
||||||
#ifdef SLIC3R_DEBUG_SLICE_PROCESSING
|
#ifdef SLIC3R_DEBUG_SLICE_PROCESSING
|
||||||
for (size_t region_id = 0; region_id < this->region_volumes.size(); ++ region_id) {
|
for (size_t region_id = 0; region_id < this->num_printing_regions(); ++ region_id) {
|
||||||
for (const Layer *layer : m_layers) {
|
for (const Layer *layer : m_layers) {
|
||||||
const LayerRegion *layerm = layer->m_regions[region_id];
|
const LayerRegion *layerm = layer->m_regions[region_id];
|
||||||
layerm->export_region_slices_to_svg_debug("5_discover_horizontal_shells");
|
layerm->export_region_slices_to_svg_debug("5_discover_horizontal_shells");
|
||||||
@ -2672,16 +2684,16 @@ void PrintObject::discover_horizontal_shells()
|
|||||||
void PrintObject::combine_infill()
|
void PrintObject::combine_infill()
|
||||||
{
|
{
|
||||||
// Work on each region separately.
|
// Work on each region separately.
|
||||||
for (size_t region_id = 0; region_id < this->region_volumes.size(); ++ region_id) {
|
for (size_t region_id = 0; region_id < this->num_printing_regions(); ++ region_id) {
|
||||||
const PrintRegion *region = this->print()->regions()[region_id];
|
const PrintRegion ®ion = this->printing_region(region_id);
|
||||||
const size_t every = region->config().infill_every_layers.value;
|
const size_t every = region.config().infill_every_layers.value;
|
||||||
if (every < 2 || region->config().fill_density == 0.)
|
if (every < 2 || region.config().fill_density == 0.)
|
||||||
continue;
|
continue;
|
||||||
// Limit the number of combined layers to the maximum height allowed by this regions' nozzle.
|
// Limit the number of combined layers to the maximum height allowed by this regions' nozzle.
|
||||||
//FIXME limit the layer height to max_layer_height
|
//FIXME limit the layer height to max_layer_height
|
||||||
double nozzle_diameter = std::min(
|
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().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().solid_infill_extruder.value - 1));
|
||||||
// define the combinations
|
// define the combinations
|
||||||
std::vector<size_t> combine(m_layers.size(), 0);
|
std::vector<size_t> combine(m_layers.size(), 0);
|
||||||
{
|
{
|
||||||
@ -2745,11 +2757,11 @@ void PrintObject::combine_infill()
|
|||||||
0.5f * layerms.back()->flow(frPerimeter).scaled_width() +
|
0.5f * layerms.back()->flow(frPerimeter).scaled_width() +
|
||||||
// Because fill areas for rectilinear and honeycomb are grown
|
// Because fill areas for rectilinear and honeycomb are grown
|
||||||
// later to overlap perimeters, we need to counteract that too.
|
// later to overlap perimeters, we need to counteract that too.
|
||||||
((region->config().fill_pattern == ipRectilinear ||
|
((region.config().fill_pattern == ipRectilinear ||
|
||||||
region->config().fill_pattern == ipMonotonic ||
|
region.config().fill_pattern == ipMonotonic ||
|
||||||
region->config().fill_pattern == ipGrid ||
|
region.config().fill_pattern == ipGrid ||
|
||||||
region->config().fill_pattern == ipLine ||
|
region.config().fill_pattern == ipLine ||
|
||||||
region->config().fill_pattern == ipHoneycomb) ? 1.5f : 0.5f) *
|
region.config().fill_pattern == ipHoneycomb) ? 1.5f : 0.5f) *
|
||||||
layerms.back()->flow(frSolidInfill).scaled_width();
|
layerms.back()->flow(frSolidInfill).scaled_width();
|
||||||
for (ExPolygon &expoly : intersection)
|
for (ExPolygon &expoly : intersection)
|
||||||
polygons_append(intersection_with_clearance, offset(expoly, clearance_offset));
|
polygons_append(intersection_with_clearance, offset(expoly, clearance_offset));
|
||||||
|
@ -345,17 +345,14 @@ PrintObjectSupportMaterial::PrintObjectSupportMaterial(const PrintObject *object
|
|||||||
// Evaluate the XY gap between the object outer perimeters and the support structures.
|
// Evaluate the XY gap between the object outer perimeters and the support structures.
|
||||||
// Evaluate the XY gap between the object outer perimeters and the support structures.
|
// Evaluate the XY gap between the object outer perimeters and the support structures.
|
||||||
coordf_t external_perimeter_width = 0.;
|
coordf_t external_perimeter_width = 0.;
|
||||||
size_t num_nonempty_regions = 0;
|
|
||||||
coordf_t bridge_flow_ratio = 0;
|
coordf_t bridge_flow_ratio = 0;
|
||||||
for (size_t region_id = 0; region_id < object->region_volumes.size(); ++ region_id)
|
for (size_t region_id = 0; region_id < object->num_printing_regions(); ++ region_id) {
|
||||||
if (! object->region_volumes[region_id].empty()) {
|
const PrintRegion ®ion = object->printing_region(region_id);
|
||||||
++ num_nonempty_regions;
|
|
||||||
const PrintRegion ®ion = *object->print()->get_region(region_id);
|
|
||||||
external_perimeter_width = std::max(external_perimeter_width, coordf_t(region.flow(*object, frExternalPerimeter, slicing_params.layer_height).width()));
|
external_perimeter_width = std::max(external_perimeter_width, coordf_t(region.flow(*object, frExternalPerimeter, slicing_params.layer_height).width()));
|
||||||
bridge_flow_ratio += region.config().bridge_flow_ratio;
|
bridge_flow_ratio += region.config().bridge_flow_ratio;
|
||||||
}
|
}
|
||||||
m_support_params.gap_xy = m_object_config->support_material_xy_spacing.get_abs_value(external_perimeter_width);
|
m_support_params.gap_xy = m_object_config->support_material_xy_spacing.get_abs_value(external_perimeter_width);
|
||||||
bridge_flow_ratio /= num_nonempty_regions;
|
bridge_flow_ratio /= object->num_printing_regions();
|
||||||
|
|
||||||
m_support_params.support_material_bottom_interface_flow = m_slicing_params.soluble_interface || ! m_object_config->thick_bridges ?
|
m_support_params.support_material_bottom_interface_flow = m_slicing_params.soluble_interface || ! m_object_config->thick_bridges ?
|
||||||
m_support_params.support_material_interface_flow.with_flow_ratio(bridge_flow_ratio) :
|
m_support_params.support_material_interface_flow.with_flow_ratio(bridge_flow_ratio) :
|
||||||
|
@ -98,9 +98,9 @@ _constant()
|
|||||||
%code%{ RETVAL = THIS->objects().size(); %};
|
%code%{ RETVAL = THIS->objects().size(); %};
|
||||||
|
|
||||||
PrintRegionPtrs* regions()
|
PrintRegionPtrs* regions()
|
||||||
%code%{ RETVAL = const_cast<PrintRegionPtrs*>(&THIS->regions_mutable()); %};
|
%code%{ RETVAL = const_cast<PrintRegionPtrs*>(&THIS->print_regions_mutable()); %};
|
||||||
Ref<PrintRegion> get_region(int idx)
|
Ref<PrintRegion> get_region(int idx)
|
||||||
%code%{ RETVAL = THIS->regions_mutable()[idx]; %};
|
%code%{ RETVAL = THIS->print_regions_mutable()[idx]; %};
|
||||||
size_t region_count()
|
size_t region_count()
|
||||||
%code%{ RETVAL = THIS->regions().size(); %};
|
%code%{ RETVAL = THIS->regions().size(); %};
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user