diff --git a/src/libslic3r/Print.hpp b/src/libslic3r/Print.hpp index 25fd0dfc3b..b4241c91ec 100644 --- a/src/libslic3r/Print.hpp +++ b/src/libslic3r/Print.hpp @@ -152,6 +152,34 @@ struct PrintInstance typedef std::vector PrintInstances; +// Region and its volumes (printing volumes or modifier volumes) +struct PrintRegionVolumes +{ + // Single volume + Z range assigned to a region. + struct VolumeWithZRange { + // Z range to slice this ModelVolume over. + t_layer_height_range layer_height_range; + // Index of a ModelVolume inside its parent ModelObject. + int volume_idx; + }; + + // Overriding one region with some other extruder, producing another region. + // The region is owned by PrintObject::m_all_regions. + struct ExtruderOverride { + unsigned int extruder; +// const PrintRegion *region; + }; + + // The region is owned by PrintObject::m_all_regions. +// const PrintRegion *region; + // Possible overrides of the default region extruder. + std::vector overrides; + // List of ModelVolume indices and layer ranges of thereof. + std::vector volumes; + // Is this region printing in any layer? +// bool printing { false }; +}; + class PrintObject : public PrintObjectBaseWithState { private: // Prevents erroneous use by other classes. @@ -186,7 +214,7 @@ public: void add_region_volume(unsigned int region_id, int volume_id, const t_layer_height_range &layer_range) { if (region_id >= m_region_volumes.size()) m_region_volumes.resize(region_id + 1); - m_region_volumes[region_id].emplace_back(layer_range, volume_id); + m_region_volumes[region_id].volumes.push_back({ layer_range, volume_id }); } // This is the *total* layer count (including support layers) // this value is not supposed to be compared with Layer::id @@ -305,9 +333,9 @@ private: // This is the adjustment of the the Object's coordinate system towards PrintObject's coordinate system. Point m_center_offset; - std::vector> m_all_regions; + std::vector> m_all_regions; // vector of (layer height ranges and vectors of volume ids), indexed by region_id - std::vector>> m_region_volumes; + std::vector m_region_volumes; SlicingParameters m_slicing_params; LayerPtrs m_layers; @@ -513,15 +541,11 @@ public: std::string output_filename(const std::string &filename_base = std::string()) const override; - // Accessed by SupportMaterial 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; } protected: - // methods for handling regions - PrintRegion& get_print_region(size_t idx) { return *m_print_regions[idx]; } - // Invalidates the step, and its depending steps in Print. bool invalidate_step(PrintStep step); diff --git a/src/libslic3r/PrintApply.cpp b/src/libslic3r/PrintApply.cpp index 3679080e62..f0e262fdcd 100644 --- a/src/libslic3r/PrintApply.cpp +++ b/src/libslic3r/PrintApply.cpp @@ -694,9 +694,9 @@ Print::ApplyStatus Print::apply(const Model &model, DynamicPrintConfig new_full_ PrintRegion ®ion = *print_object->m_all_regions[region_id]; PrintRegionConfig region_config; bool region_config_set = false; - for (const std::pair &volume_and_range : print_object->m_region_volumes[region_id]) { - const ModelVolume &volume = *print_object->model_object()->volumes[volume_and_range.second]; - const DynamicPrintConfig *layer_range_config = layer_ranges->config(volume_and_range.first); + for (const PrintRegionVolumes::VolumeWithZRange &volume_w_zrange : print_object->m_region_volumes[region_id].volumes) { + const ModelVolume &volume = *print_object->model_object()->volumes[volume_w_zrange.volume_idx]; + const DynamicPrintConfig *layer_range_config = layer_ranges->config(volume_w_zrange.layer_height_range); PrintRegionConfig this_region_config = PrintObject::region_config_from_model_volume(m_default_region_config, layer_range_config, volume, num_extruders); if (region_config_set) { if (this_region_config != region_config) { diff --git a/src/libslic3r/PrintObject.cpp b/src/libslic3r/PrintObject.cpp index 33e961dbef..8fefd4beb8 100644 --- a/src/libslic3r/PrintObject.cpp +++ b/src/libslic3r/PrintObject.cpp @@ -1757,14 +1757,13 @@ void PrintObject::_slice(const std::vector &layer_height_profile) size_t num_modifiers = 0; for (int region_id = 0; region_id < int(m_region_volumes.size()); ++ region_id) { int last_volume_id = -1; - for (const std::pair &volume_and_range : m_region_volumes[region_id]) { - const int volume_id = volume_and_range.second; - const ModelVolume *model_volume = this->model_object()->volumes[volume_id]; + for (const PrintRegionVolumes::VolumeWithZRange &volume_w_zrange : m_region_volumes[region_id].volumes) { + const ModelVolume *model_volume = this->model_object()->volumes[volume_w_zrange.volume_idx]; if (model_volume->is_model_part()) { - if (last_volume_id == volume_id) { + if (last_volume_id == volume_w_zrange.volume_idx) { has_z_ranges = true; } else { - last_volume_id = volume_id; + last_volume_id = volume_w_zrange.volume_idx; if (all_volumes_single_region == -2) // first model volume met all_volumes_single_region = region_id; @@ -1821,21 +1820,21 @@ void PrintObject::_slice(const std::vector &layer_height_profile) std::vector sliced_volumes; sliced_volumes.reserve(num_volumes); for (size_t region_id = 0; region_id < m_region_volumes.size(); ++ region_id) { - const std::vector> &volumes_and_ranges = m_region_volumes[region_id]; - for (size_t i = 0; i < volumes_and_ranges.size(); ) { - int volume_id = volumes_and_ranges[i].second; + const PrintRegionVolumes &volumes_and_ranges = m_region_volumes[region_id]; + for (size_t i = 0; i < volumes_and_ranges.volumes.size(); ) { + int volume_id = volumes_and_ranges.volumes[i].volume_idx; const ModelVolume *model_volume = this->model_object()->volumes[volume_id]; if (model_volume->is_model_part()) { BOOST_LOG_TRIVIAL(debug) << "Slicing objects - volume " << volume_id; // Find the ranges of this volume. Ranges in volumes_and_ranges must not overlap for a single volume. std::vector ranges; - ranges.emplace_back(volumes_and_ranges[i].first); + ranges.emplace_back(volumes_and_ranges.volumes[i].layer_height_range); size_t j = i + 1; - for (; j < volumes_and_ranges.size() && volume_id == volumes_and_ranges[j].second; ++ j) - if (! ranges.empty() && std::abs(ranges.back().second - volumes_and_ranges[j].first.first) < EPSILON) - ranges.back().second = volumes_and_ranges[j].first.second; + for (; j < volumes_and_ranges.volumes.size() && volume_id == volumes_and_ranges.volumes[j].volume_idx; ++ j) + if (! ranges.empty() && std::abs(ranges.back().second - volumes_and_ranges.volumes[j].layer_height_range.first) < EPSILON) + ranges.back().second = volumes_and_ranges.volumes[j].layer_height_range.second; else - ranges.emplace_back(volumes_and_ranges[j].first); + ranges.emplace_back(volumes_and_ranges.volumes[j].layer_height_range); // slicing in parallel sliced_volumes.emplace_back(volume_id, (int)region_id, this->slice_volume(slice_zs, ranges, slicing_mode, *model_volume)); i = j; @@ -2048,8 +2047,8 @@ std::vector PrintObject::slice_region(size_t region_id, const std::v { std::vector volumes; if (region_id < m_region_volumes.size()) { - for (const std::pair &volume_and_range : m_region_volumes[region_id]) { - const ModelVolume *volume = this->model_object()->volumes[volume_and_range.second]; + for (const PrintRegionVolumes::VolumeWithZRange &volume_w_zrange : m_region_volumes[region_id].volumes) { + const ModelVolume *volume = this->model_object()->volumes[volume_w_zrange.volume_idx]; if (volume->is_model_part()) volumes.emplace_back(volume); } @@ -2057,27 +2056,27 @@ std::vector PrintObject::slice_region(size_t region_id, const std::v return this->slice_volumes(z, mode, slicing_mode_normal_below_layer, mode_below, volumes); } -// Z ranges are not applicable to modifier meshes, therefore a single volume will be found in volume_and_range at most once. +// Z ranges are not applicable to modifier meshes, therefore a single volume will be found in volume_w_zrange at most once. std::vector PrintObject::slice_modifiers(size_t region_id, const std::vector &slice_zs) const { std::vector out; if (region_id < m_region_volumes.size()) { std::vector> volume_ranges; - const std::vector> &volumes_and_ranges = m_region_volumes[region_id]; - volume_ranges.reserve(volumes_and_ranges.size()); - for (size_t i = 0; i < volumes_and_ranges.size(); ) { - int volume_id = volumes_and_ranges[i].second; + const PrintRegionVolumes &volumes_and_ranges = m_region_volumes[region_id]; + volume_ranges.reserve(volumes_and_ranges.volumes.size()); + for (size_t i = 0; i < volumes_and_ranges.volumes.size(); ) { + int volume_id = volumes_and_ranges.volumes[i].volume_idx; const ModelVolume *model_volume = this->model_object()->volumes[volume_id]; if (model_volume->is_modifier()) { std::vector ranges; - ranges.emplace_back(volumes_and_ranges[i].first); + ranges.emplace_back(volumes_and_ranges.volumes[i].layer_height_range); size_t j = i + 1; - for (; j < volumes_and_ranges.size() && volume_id == volumes_and_ranges[j].second; ++ j) { - if (! ranges.empty() && std::abs(ranges.back().second - volumes_and_ranges[j].first.first) < EPSILON) - ranges.back().second = volumes_and_ranges[j].first.second; + for (; j < volumes_and_ranges.volumes.size() && volume_id == volumes_and_ranges.volumes[j].volume_idx; ++ j) { + if (! ranges.empty() && std::abs(ranges.back().second - volumes_and_ranges.volumes[j].layer_height_range.first) < EPSILON) + ranges.back().second = volumes_and_ranges.volumes[j].layer_height_range.second; else - ranges.emplace_back(volumes_and_ranges[j].first); + ranges.emplace_back(volumes_and_ranges.volumes[j].layer_height_range); } volume_ranges.emplace_back(std::move(ranges)); i = j; @@ -2099,8 +2098,8 @@ std::vector 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)) { // No modifier in this region was split to layer spans. std::vector volumes; - for (const std::pair &volume_and_range : m_region_volumes[region_id]) { - const ModelVolume *volume = this->model_object()->volumes[volume_and_range.second]; + for (const PrintRegionVolumes::VolumeWithZRange &volume_w_zrange : m_region_volumes[region_id].volumes) { + const ModelVolume *volume = this->model_object()->volumes[volume_w_zrange.volume_idx]; if (volume->is_modifier()) volumes.emplace_back(volume); } @@ -2109,18 +2108,18 @@ std::vector PrintObject::slice_modifiers(size_t region_id, const std // Some modifier in this region was split to layer spans. std::vector merge; for (size_t region_id = 0; region_id < m_region_volumes.size(); ++ region_id) { - const std::vector> &volumes_and_ranges = m_region_volumes[region_id]; - for (size_t i = 0; i < volumes_and_ranges.size(); ) { - int volume_id = volumes_and_ranges[i].second; + const PrintRegionVolumes &volumes_and_ranges = m_region_volumes[region_id]; + for (size_t i = 0; i < volumes_and_ranges.volumes.size(); ) { + int volume_id = volumes_and_ranges.volumes[i].volume_idx; const ModelVolume *model_volume = this->model_object()->volumes[volume_id]; if (model_volume->is_modifier()) { BOOST_LOG_TRIVIAL(debug) << "Slicing modifiers - volume " << volume_id; // Find the ranges of this volume. Ranges in volumes_and_ranges must not overlap for a single volume. std::vector ranges; - ranges.emplace_back(volumes_and_ranges[i].first); + ranges.emplace_back(volumes_and_ranges.volumes[i].layer_height_range); size_t j = i + 1; - for (; j < volumes_and_ranges.size() && volume_id == volumes_and_ranges[j].second; ++ j) - ranges.emplace_back(volumes_and_ranges[j].first); + for (; j < volumes_and_ranges.volumes.size() && volume_id == volumes_and_ranges.volumes[j].volume_idx; ++ j) + ranges.emplace_back(volumes_and_ranges.volumes[j].layer_height_range); // slicing in parallel std::vector this_slices = this->slice_volume(slice_zs, ranges, SlicingMode::Regular, *model_volume); // Variable this_slices could be empty if no value of slice_zs is within any of the ranges of this volume.