Make sure texture mapping zone sparse IDs are recognized in libslic3r internals
This commit is contained in:
@@ -136,6 +136,8 @@ unsigned int LayerTools::resolve_filament_id(unsigned int filament_id_1based) co
|
||||
num_physical_filaments > 0 &&
|
||||
texture_mapping_manager->is_texture_mapping_zone_id(filament_id_1based))
|
||||
return texture_mapping_manager->resolve_zone_component(filament_id_1based, num_physical_filaments, layer_index);
|
||||
if (num_physical_filaments > 0 && filament_id_1based > num_physical_filaments)
|
||||
return 1;
|
||||
return filament_id_1based;
|
||||
}
|
||||
|
||||
@@ -582,10 +584,14 @@ std::vector<unsigned int> ToolOrdering::generate_first_layer_tool_order(const Pr
|
||||
|
||||
for (auto layerm : target_layer->regions()) {
|
||||
const int raw_extruder_id = layerm->region().config().option("wall_filament")->getInt();
|
||||
const unsigned int resolved_extruder_id = raw_extruder_id <= 0 ? 0 :
|
||||
print.texture_mapping_manager().resolve_zone_component(unsigned(raw_extruder_id), print.config().filament_colour.size(), int(target_layer->id()));
|
||||
if (resolved_extruder_id == 0 || resolved_extruder_id > print.config().filament_colour.size())
|
||||
unsigned int resolved_extruder_id = raw_extruder_id <= 0 ? 0 :
|
||||
print.texture_mapping_manager().resolve_zone_component(unsigned(raw_extruder_id),
|
||||
print.config().filament_colour.size(),
|
||||
int(target_layer->id()));
|
||||
if (resolved_extruder_id == 0)
|
||||
continue;
|
||||
if (resolved_extruder_id > print.config().filament_colour.size())
|
||||
resolved_extruder_id = 1;
|
||||
int extruder_id = int(resolved_extruder_id);
|
||||
|
||||
for (auto expoly : layerm->raw_slices) {
|
||||
@@ -651,10 +657,14 @@ std::vector<unsigned int> ToolOrdering::generate_first_layer_tool_order(const Pr
|
||||
|
||||
for (auto layerm : target_layer->regions()) {
|
||||
const int raw_extruder_id = layerm->region().config().option("wall_filament")->getInt();
|
||||
const unsigned int resolved_extruder_id = raw_extruder_id <= 0 ? 0 :
|
||||
object.print()->texture_mapping_manager().resolve_zone_component(unsigned(raw_extruder_id), object.print()->config().filament_colour.size(), int(target_layer->id()));
|
||||
if (resolved_extruder_id == 0 || resolved_extruder_id > object.print()->config().filament_colour.size())
|
||||
unsigned int resolved_extruder_id = raw_extruder_id <= 0 ? 0 :
|
||||
object.print()->texture_mapping_manager().resolve_zone_component(unsigned(raw_extruder_id),
|
||||
object.print()->config().filament_colour.size(),
|
||||
int(target_layer->id()));
|
||||
if (resolved_extruder_id == 0)
|
||||
continue;
|
||||
if (resolved_extruder_id > object.print()->config().filament_colour.size())
|
||||
resolved_extruder_id = 1;
|
||||
int extruder_id = int(resolved_extruder_id);
|
||||
for (auto expoly : layerm->raw_slices) {
|
||||
const double nozzle_diameter = object.print()->config().nozzle_diameter.get_at(0);
|
||||
|
||||
@@ -92,7 +92,8 @@ static void append_used_physical_extruders_for_filament_id(const TextureMappingM
|
||||
return;
|
||||
}
|
||||
|
||||
append_physical(unsigned(filament_id));
|
||||
const unsigned int physical_id = unsigned(filament_id);
|
||||
append_physical(physical_id <= num_physical ? physical_id : 1);
|
||||
}
|
||||
|
||||
static std::array<float, 3> prime_tower_parse_hex_color_for_print(const std::string &hex)
|
||||
|
||||
@@ -1254,7 +1254,8 @@ static void append_used_filament_from_config_id(const TextureMappingManager
|
||||
return;
|
||||
}
|
||||
|
||||
append_physical(unsigned(filament_id));
|
||||
const unsigned int physical_id = unsigned(filament_id);
|
||||
append_physical(physical_id <= num_physical_extruders ? physical_id : 1);
|
||||
}
|
||||
|
||||
static void append_model_used_filaments_for_normalization(const Model &model,
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
#include "Surface.hpp"
|
||||
#include "Slicing.hpp"
|
||||
#include "Tesselate.hpp"
|
||||
#include "TextureMapping.hpp"
|
||||
#include "TriangleMeshSlicer.hpp"
|
||||
#include "Utils.hpp"
|
||||
#include "Fill/FillAdaptive.hpp"
|
||||
@@ -22,6 +23,7 @@
|
||||
#include "format.hpp"
|
||||
#include "AABBTreeLines.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
#include <float.h>
|
||||
#include <oneapi/tbb/blocked_range.h>
|
||||
#include <oneapi/tbb/concurrent_vector.h>
|
||||
@@ -289,6 +291,68 @@ void PrintObject::_transform_hole_to_polyholes()
|
||||
}
|
||||
}
|
||||
|
||||
static std::vector<unsigned int> physical_extruders_for_filament_id(const TextureMappingManager &texture_mgr,
|
||||
int filament_id,
|
||||
size_t num_physical,
|
||||
const std::vector<std::string> &filament_colours)
|
||||
{
|
||||
std::vector<unsigned int> out;
|
||||
if (filament_id <= 0 || num_physical == 0)
|
||||
return out;
|
||||
|
||||
auto append_physical = [num_physical, &out](unsigned int physical_id) {
|
||||
if (physical_id >= 1 && physical_id <= num_physical)
|
||||
out.emplace_back(physical_id - 1);
|
||||
};
|
||||
|
||||
const TextureMappingZone *zone = texture_mgr.zone_from_id(unsigned(filament_id));
|
||||
if (zone != nullptr) {
|
||||
if (!zone->enabled || zone->deleted)
|
||||
return out;
|
||||
|
||||
std::vector<std::string> colors = filament_colours;
|
||||
colors.resize(num_physical, "#FFFFFF");
|
||||
std::vector<unsigned int> component_ids = zone->is_image_texture() ?
|
||||
TextureMappingManager::effective_texture_component_ids(*zone, num_physical, colors) :
|
||||
TextureMappingManager::selected_component_ids(*zone, num_physical);
|
||||
|
||||
for (unsigned int component_id : component_ids)
|
||||
append_physical(component_id);
|
||||
|
||||
if (out.empty())
|
||||
append_physical(texture_mgr.resolve_zone_component(unsigned(filament_id), num_physical, 0));
|
||||
} else {
|
||||
const unsigned int physical_id = unsigned(filament_id);
|
||||
append_physical(physical_id <= num_physical ? physical_id : 1);
|
||||
}
|
||||
|
||||
sort_remove_duplicates(out);
|
||||
return out;
|
||||
}
|
||||
|
||||
template<typename Set>
|
||||
static bool contains_any_physical_extruder(const Set &set, const std::vector<unsigned int> &extruders)
|
||||
{
|
||||
return std::any_of(extruders.begin(), extruders.end(), [&set](unsigned int extruder) {
|
||||
return set.count(int(extruder)) > 0;
|
||||
});
|
||||
}
|
||||
|
||||
template<typename Set>
|
||||
static bool contains_missing_physical_extruder(const Set &set, const std::vector<unsigned int> &extruders)
|
||||
{
|
||||
return std::any_of(extruders.begin(), extruders.end(), [&set](unsigned int extruder) {
|
||||
return set.count(int(extruder)) == 0;
|
||||
});
|
||||
}
|
||||
|
||||
template<typename Set>
|
||||
static void insert_physical_extruders(Set &set, const std::vector<unsigned int> &extruders)
|
||||
{
|
||||
for (unsigned int extruder : extruders)
|
||||
set.insert(int(extruder));
|
||||
}
|
||||
|
||||
std::vector<std::set<int>> PrintObject::detect_extruder_geometric_unprintables() const
|
||||
{
|
||||
int extruder_size = m_print->config().nozzle_diameter.size();
|
||||
@@ -296,6 +360,12 @@ std::vector<std::set<int>> PrintObject::detect_extruder_geometric_unprintables()
|
||||
return std::vector<std::set<int>>(1, std::set<int>());
|
||||
|
||||
std::vector<std::set<int>> geometric_unprintables(extruder_size); // the container to return
|
||||
const size_t num_physical_filaments = m_print->config().filament_colour.size();
|
||||
const TextureMappingManager &texture_mgr = m_print->texture_mapping_manager();
|
||||
const std::vector<std::string> filament_colours = m_print->config().filament_colour.values;
|
||||
auto resolve_physical_extruders = [&texture_mgr, num_physical_filaments, &filament_colours](int filament_id) {
|
||||
return physical_extruders_for_filament_id(texture_mgr, filament_id, num_physical_filaments, filament_colours);
|
||||
};
|
||||
|
||||
std::vector<double> printable_height_per_extruder = m_print->config().extruder_printable_height.values;
|
||||
assert(printable_height_per_extruder.size() == extruder_size);
|
||||
@@ -309,18 +379,18 @@ std::vector<std::set<int>> PrintObject::detect_extruder_geometric_unprintables()
|
||||
continue;
|
||||
for (auto layerm : layer->regions()) {
|
||||
auto region = layerm->region();
|
||||
int wall_filament = region.config().wall_filament;
|
||||
int solid_infill_filament = region.config().solid_infill_filament;
|
||||
int sparse_infill_filament = region.config().sparse_infill_filament;
|
||||
const std::vector<unsigned int> wall_filaments = resolve_physical_extruders(region.config().wall_filament);
|
||||
const std::vector<unsigned int> solid_infill_filaments =
|
||||
resolve_physical_extruders(region.config().solid_infill_filament);
|
||||
const std::vector<unsigned int> sparse_infill_filaments =
|
||||
resolve_physical_extruders(region.config().sparse_infill_filament);
|
||||
|
||||
if (!layerm->fills.entities.empty()) {
|
||||
if (solid_infill_filament > 0)
|
||||
geometric_unprintables[extruder_id].insert(solid_infill_filament - 1);
|
||||
if (sparse_infill_filament > 0)
|
||||
geometric_unprintables[extruder_id].insert(sparse_infill_filament - 1);
|
||||
insert_physical_extruders(geometric_unprintables[extruder_id], solid_infill_filaments);
|
||||
insert_physical_extruders(geometric_unprintables[extruder_id], sparse_infill_filaments);
|
||||
}
|
||||
if (!layerm->perimeters.entities.empty() && wall_filament > 0)
|
||||
geometric_unprintables[extruder_id].insert(wall_filament - 1);
|
||||
if (!layerm->perimeters.entities.empty())
|
||||
insert_physical_extruders(geometric_unprintables[extruder_id], wall_filaments);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -340,26 +410,33 @@ std::vector<std::set<int>> PrintObject::detect_extruder_geometric_unprintables()
|
||||
|
||||
// check unprintbale filaments caused by printable area limit
|
||||
tbb::parallel_for(tbb::blocked_range<int>(0, m_layers.size()),
|
||||
[this, &tbb_geometric_unprintables, &unprintable_area_in_obj_coord, &unprintable_area_bbox](const tbb::blocked_range<int>& range) {
|
||||
[this,
|
||||
&tbb_geometric_unprintables,
|
||||
&unprintable_area_in_obj_coord,
|
||||
&unprintable_area_bbox,
|
||||
&resolve_physical_extruders](const tbb::blocked_range<int>& range) {
|
||||
for (int j = range.begin(); j < range.end(); ++j) {
|
||||
auto layer = m_layers[j];
|
||||
for (auto layerm : layer->regions()) {
|
||||
const auto& region = layerm->region();
|
||||
int wall_filament = region.config().wall_filament;
|
||||
int solid_infill_filament = region.config().solid_infill_filament;
|
||||
int sparse_infill_filament = region.config().sparse_infill_filament;
|
||||
const std::vector<unsigned int> wall_filaments = resolve_physical_extruders(region.config().wall_filament);
|
||||
const std::vector<unsigned int> solid_infill_filaments =
|
||||
resolve_physical_extruders(region.config().solid_infill_filament);
|
||||
const std::vector<unsigned int> sparse_infill_filaments =
|
||||
resolve_physical_extruders(region.config().sparse_infill_filament);
|
||||
std::optional<ExPolygons> fill_expolys;
|
||||
BoundingBox fill_bbox;
|
||||
std::optional<ExPolygons> wall_expolys;
|
||||
BoundingBox wall_bbox;
|
||||
|
||||
for (size_t idx = 0; idx < unprintable_area_in_obj_coord.size(); ++idx) {
|
||||
bool do_infill_filament_detect = (solid_infill_filament > 0 && tbb_geometric_unprintables[idx].count(solid_infill_filament - 1) == 0) ||
|
||||
(sparse_infill_filament > 0 && tbb_geometric_unprintables[idx].count(sparse_infill_filament-1) == 0);
|
||||
bool do_infill_filament_detect =
|
||||
contains_missing_physical_extruder(tbb_geometric_unprintables[idx], solid_infill_filaments) ||
|
||||
contains_missing_physical_extruder(tbb_geometric_unprintables[idx], sparse_infill_filaments);
|
||||
|
||||
bool infill_unprintable = !layerm->fills.entities.empty() &&
|
||||
((solid_infill_filament > 0 && tbb_geometric_unprintables[idx].count(solid_infill_filament - 1) > 0) ||
|
||||
(sparse_infill_filament > 0 && tbb_geometric_unprintables[idx].count(sparse_infill_filament - 1) > 0));
|
||||
(contains_any_physical_extruder(tbb_geometric_unprintables[idx], solid_infill_filaments) ||
|
||||
contains_any_physical_extruder(tbb_geometric_unprintables[idx], sparse_infill_filaments));
|
||||
|
||||
if (!layerm->fills.entities.empty() && do_infill_filament_detect) {
|
||||
if (!fill_expolys) {
|
||||
@@ -368,19 +445,17 @@ std::vector<std::set<int>> PrintObject::detect_extruder_geometric_unprintables()
|
||||
}
|
||||
if (fill_bbox.overlap(unprintable_area_bbox[idx]) &&
|
||||
!intersection(*fill_expolys, unprintable_area_in_obj_coord[idx]).empty()) {
|
||||
if (solid_infill_filament > 0)
|
||||
tbb_geometric_unprintables[idx].insert(solid_infill_filament - 1);
|
||||
if (sparse_infill_filament > 0)
|
||||
tbb_geometric_unprintables[idx].insert(sparse_infill_filament - 1);
|
||||
insert_physical_extruders(tbb_geometric_unprintables[idx], solid_infill_filaments);
|
||||
insert_physical_extruders(tbb_geometric_unprintables[idx], sparse_infill_filaments);
|
||||
infill_unprintable = true;
|
||||
}
|
||||
}
|
||||
|
||||
bool do_wall_filament_detect = wall_filament > 0 && tbb_geometric_unprintables[idx].count(wall_filament - 1) == 0;
|
||||
bool do_wall_filament_detect = contains_missing_physical_extruder(tbb_geometric_unprintables[idx], wall_filaments);
|
||||
if (!layerm->perimeters.entities.empty() && do_wall_filament_detect) {
|
||||
// if infill is unprintable, no need to check wall since wall contour surrounds infill contour
|
||||
if (infill_unprintable) {
|
||||
tbb_geometric_unprintables[idx].insert(wall_filament - 1);
|
||||
insert_physical_extruders(tbb_geometric_unprintables[idx], wall_filaments);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -395,7 +470,7 @@ std::vector<std::set<int>> PrintObject::detect_extruder_geometric_unprintables()
|
||||
|
||||
if (wall_bbox.overlap(unprintable_area_bbox[idx]) &&
|
||||
!intersection(*wall_expolys, unprintable_area_in_obj_coord[idx]).empty()) {
|
||||
tbb_geometric_unprintables[idx].insert(wall_filament - 1);
|
||||
insert_physical_extruders(tbb_geometric_unprintables[idx], wall_filaments);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3477,11 +3552,16 @@ std::vector<unsigned int> PrintObject::object_extruders() const
|
||||
region.collect_object_printing_extruders(*this->print(), extruders);
|
||||
|
||||
const ModelObject* mo = this->model_object();
|
||||
const size_t num_physical = this->print()->config().filament_colour.size();
|
||||
for (const ModelVolume* mv : mo->volumes) {
|
||||
std::vector<int> volume_extruders = mv->get_extruders();
|
||||
for (int extruder : volume_extruders) {
|
||||
assert(extruder > 0);
|
||||
extruders.push_back(extruder - 1);
|
||||
append(extruders,
|
||||
physical_extruders_for_filament_id(this->print()->texture_mapping_manager(),
|
||||
extruder,
|
||||
num_physical,
|
||||
this->print()->config().filament_colour.values));
|
||||
}
|
||||
}
|
||||
sort_remove_duplicates(extruders);
|
||||
|
||||
@@ -63,7 +63,8 @@ static void append_used_physical_extruders_for_filament_id(const Print
|
||||
return;
|
||||
}
|
||||
|
||||
append_physical(unsigned(filament_id));
|
||||
const unsigned int physical_id = unsigned(filament_id);
|
||||
append_physical(physical_id <= num_physical ? physical_id : 1);
|
||||
}
|
||||
|
||||
// 1-based extruder identifier for this region and role.
|
||||
@@ -153,9 +154,15 @@ void PrintRegion::collect_object_printing_extruders(const Print &print, std::vec
|
||||
#ifndef NDEBUG
|
||||
// BBS
|
||||
auto num_extruders = int(print.config().filament_diameter.size());
|
||||
assert(this->config().wall_filament <= num_extruders || print.texture_mapping_manager().is_texture_mapping_zone_id(this->config().wall_filament));
|
||||
assert(this->config().sparse_infill_filament <= num_extruders || print.texture_mapping_manager().is_texture_mapping_zone_id(this->config().sparse_infill_filament));
|
||||
assert(this->config().solid_infill_filament <= num_extruders || print.texture_mapping_manager().is_texture_mapping_zone_id(this->config().solid_infill_filament));
|
||||
auto can_resolve_filament_id = [num_extruders, &print](int filament_id) {
|
||||
return filament_id >= 0 &&
|
||||
(filament_id <= num_extruders ||
|
||||
print.texture_mapping_manager().is_texture_mapping_zone_id(unsigned(filament_id)) ||
|
||||
num_extruders > 0);
|
||||
};
|
||||
assert(can_resolve_filament_id(this->config().wall_filament));
|
||||
assert(can_resolve_filament_id(this->config().sparse_infill_filament));
|
||||
assert(can_resolve_filament_id(this->config().solid_infill_filament));
|
||||
#endif
|
||||
if (this->config().wall_loops.value > 0 || print.has_brim())
|
||||
append_used_physical_extruders_for_filament_id(print, this->config().wall_filament.value, object_extruders);
|
||||
|
||||
Reference in New Issue
Block a user