Refactored PrintObject::m_region_volumes for extensibility.
WIP for multi-material painting.
This commit is contained in:
parent
dd72016159
commit
feefbc575a
3 changed files with 67 additions and 44 deletions
|
@ -152,6 +152,34 @@ struct PrintInstance
|
|||
|
||||
typedef std::vector<PrintInstance> 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<ExtruderOverride> overrides;
|
||||
// List of ModelVolume indices and layer ranges of thereof.
|
||||
std::vector<VolumeWithZRange> volumes;
|
||||
// Is this region printing in any layer?
|
||||
// bool printing { false };
|
||||
};
|
||||
|
||||
class PrintObject : public PrintObjectBaseWithState<Print, PrintObjectStep, posCount>
|
||||
{
|
||||
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<std::unique_ptr<PrintRegion>> m_all_regions;
|
||||
std::vector<std::unique_ptr<PrintRegion>> m_all_regions;
|
||||
// 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;
|
||||
std::vector<PrintRegionVolumes> 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);
|
||||
|
||||
|
|
|
@ -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<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 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) {
|
||||
|
|
|
@ -1757,14 +1757,13 @@ void PrintObject::_slice(const std::vector<coordf_t> &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<t_layer_height_range, int> &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<coordf_t> &layer_height_profile)
|
|||
std::vector<SlicedVolume> sliced_volumes;
|
||||
sliced_volumes.reserve(num_volumes);
|
||||
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 = 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<t_layer_height_range> 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<ExPolygons> PrintObject::slice_region(size_t region_id, const std::v
|
|||
{
|
||||
std::vector<const ModelVolume*> volumes;
|
||||
if (region_id < m_region_volumes.size()) {
|
||||
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];
|
||||
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<ExPolygons> 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<ExPolygons> PrintObject::slice_modifiers(size_t region_id, const std::vector<float> &slice_zs) const
|
||||
{
|
||||
std::vector<ExPolygons> out;
|
||||
if (region_id < m_region_volumes.size())
|
||||
{
|
||||
std::vector<std::vector<t_layer_height_range>> volume_ranges;
|
||||
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());
|
||||
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<t_layer_height_range> 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<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)) {
|
||||
// No modifier in this region was split to layer spans.
|
||||
std::vector<const ModelVolume*> volumes;
|
||||
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];
|
||||
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<ExPolygons> PrintObject::slice_modifiers(size_t region_id, const std
|
|||
// Some modifier in this region was split to layer spans.
|
||||
std::vector<char> merge;
|
||||
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 = 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<t_layer_height_range> 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<ExPolygons> 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.
|
||||
|
|
Loading…
Reference in a new issue