mirror of
https://git.mirrors.martin98.com/https://github.com/prusa3d/PrusaSlicer.git
synced 2025-05-25 15:47:25 +08:00
Fixed conflicts after merge with master
This commit is contained in:
commit
5aadfe3d1c
@ -316,8 +316,8 @@ std::string ExtrusionEntity::role_to_string(ExtrusionRole role)
|
|||||||
case erOverhangPerimeter : return L("Overhang perimeter");
|
case erOverhangPerimeter : return L("Overhang perimeter");
|
||||||
case erInternalInfill : return L("Internal infill");
|
case erInternalInfill : return L("Internal infill");
|
||||||
case erSolidInfill : return L("Solid infill");
|
case erSolidInfill : return L("Solid infill");
|
||||||
case erIroning : return L("Ironing");
|
|
||||||
case erTopSolidInfill : return L("Top solid infill");
|
case erTopSolidInfill : return L("Top solid infill");
|
||||||
|
case erIroning : return L("Ironing");
|
||||||
case erBridgeInfill : return L("Bridge infill");
|
case erBridgeInfill : return L("Bridge infill");
|
||||||
case erGapFill : return L("Gap fill");
|
case erGapFill : return L("Gap fill");
|
||||||
case erSkirt : return L("Skirt");
|
case erSkirt : return L("Skirt");
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
#include "../GCode.hpp"
|
#include "../GCode.hpp"
|
||||||
#include "../Geometry.hpp"
|
#include "../Geometry.hpp"
|
||||||
#include "../GCode/ThumbnailData.hpp"
|
#include "../GCode/ThumbnailData.hpp"
|
||||||
|
#include "../Time.hpp"
|
||||||
|
|
||||||
#include "../I18N.hpp"
|
#include "../I18N.hpp"
|
||||||
|
|
||||||
@ -1991,7 +1992,7 @@ namespace Slic3r {
|
|||||||
bool _add_content_types_file_to_archive(mz_zip_archive& archive);
|
bool _add_content_types_file_to_archive(mz_zip_archive& archive);
|
||||||
bool _add_thumbnail_file_to_archive(mz_zip_archive& archive, const ThumbnailData& thumbnail_data);
|
bool _add_thumbnail_file_to_archive(mz_zip_archive& archive, const ThumbnailData& thumbnail_data);
|
||||||
bool _add_relationships_file_to_archive(mz_zip_archive& archive);
|
bool _add_relationships_file_to_archive(mz_zip_archive& archive);
|
||||||
bool _add_model_file_to_archive(mz_zip_archive& archive, const Model& model, IdToObjectDataMap &objects_data);
|
bool _add_model_file_to_archive(const std::string& filename, mz_zip_archive& archive, const Model& model, IdToObjectDataMap& objects_data);
|
||||||
bool _add_object_to_model_stream(std::stringstream& stream, unsigned int& object_id, ModelObject& object, BuildItemsList& build_items, VolumeToOffsetsMap& volumes_offsets);
|
bool _add_object_to_model_stream(std::stringstream& stream, unsigned int& object_id, ModelObject& object, BuildItemsList& build_items, VolumeToOffsetsMap& volumes_offsets);
|
||||||
bool _add_mesh_to_object_stream(std::stringstream& stream, ModelObject& object, VolumeToOffsetsMap& volumes_offsets);
|
bool _add_mesh_to_object_stream(std::stringstream& stream, ModelObject& object, VolumeToOffsetsMap& volumes_offsets);
|
||||||
bool _add_build_to_model_stream(std::stringstream& stream, const BuildItemsList& build_items);
|
bool _add_build_to_model_stream(std::stringstream& stream, const BuildItemsList& build_items);
|
||||||
@ -2054,7 +2055,7 @@ namespace Slic3r {
|
|||||||
// Adds model file ("3D/3dmodel.model").
|
// Adds model file ("3D/3dmodel.model").
|
||||||
// This is the one and only file that contains all the geometry (vertices and triangles) of all ModelVolumes.
|
// This is the one and only file that contains all the geometry (vertices and triangles) of all ModelVolumes.
|
||||||
IdToObjectDataMap objects_data;
|
IdToObjectDataMap objects_data;
|
||||||
if (!_add_model_file_to_archive(archive, model, objects_data))
|
if (!_add_model_file_to_archive(filename, archive, model, objects_data))
|
||||||
{
|
{
|
||||||
close_zip_writer(&archive);
|
close_zip_writer(&archive);
|
||||||
boost::filesystem::remove(filename);
|
boost::filesystem::remove(filename);
|
||||||
@ -2203,7 +2204,7 @@ namespace Slic3r {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool _3MF_Exporter::_add_model_file_to_archive(mz_zip_archive& archive, const Model& model, IdToObjectDataMap &objects_data)
|
bool _3MF_Exporter::_add_model_file_to_archive(const std::string& filename, mz_zip_archive& archive, const Model& model, IdToObjectDataMap& objects_data)
|
||||||
{
|
{
|
||||||
std::stringstream stream;
|
std::stringstream stream;
|
||||||
// https://en.cppreference.com/w/cpp/types/numeric_limits/max_digits10
|
// https://en.cppreference.com/w/cpp/types/numeric_limits/max_digits10
|
||||||
@ -2214,6 +2215,19 @@ namespace Slic3r {
|
|||||||
stream << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
|
stream << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
|
||||||
stream << "<" << MODEL_TAG << " unit=\"millimeter\" xml:lang=\"en-US\" xmlns=\"http://schemas.microsoft.com/3dmanufacturing/core/2015/02\" xmlns:slic3rpe=\"http://schemas.slic3r.org/3mf/2017/06\">\n";
|
stream << "<" << MODEL_TAG << " unit=\"millimeter\" xml:lang=\"en-US\" xmlns=\"http://schemas.microsoft.com/3dmanufacturing/core/2015/02\" xmlns:slic3rpe=\"http://schemas.slic3r.org/3mf/2017/06\">\n";
|
||||||
stream << " <" << METADATA_TAG << " name=\"" << SLIC3RPE_3MF_VERSION << "\">" << VERSION_3MF << "</" << METADATA_TAG << ">\n";
|
stream << " <" << METADATA_TAG << " name=\"" << SLIC3RPE_3MF_VERSION << "\">" << VERSION_3MF << "</" << METADATA_TAG << ">\n";
|
||||||
|
std::string name = boost::filesystem::path(filename).stem().string();
|
||||||
|
stream << " <" << METADATA_TAG << " name=\"Title\">" << name << "</" << METADATA_TAG << ">\n";
|
||||||
|
stream << " <" << METADATA_TAG << " name=\"Designer\">" << "</" << METADATA_TAG << ">\n";
|
||||||
|
stream << " <" << METADATA_TAG << " name=\"Description\">" << name << "</" << METADATA_TAG << ">\n";
|
||||||
|
stream << " <" << METADATA_TAG << " name=\"Copyright\">" << "</" << METADATA_TAG << ">\n";
|
||||||
|
stream << " <" << METADATA_TAG << " name=\"LicenseTerms\">" << "</" << METADATA_TAG << ">\n";
|
||||||
|
stream << " <" << METADATA_TAG << " name=\"Rating\">" << "</" << METADATA_TAG << ">\n";
|
||||||
|
std::string date = Slic3r::Utils::utc_timestamp(Slic3r::Utils::get_current_time_utc());
|
||||||
|
// keep only the date part of the string
|
||||||
|
date = date.substr(0, 10);
|
||||||
|
stream << " <" << METADATA_TAG << " name=\"CreationDate\">" << date << "</" << METADATA_TAG << ">\n";
|
||||||
|
stream << " <" << METADATA_TAG << " name=\"ModificationDate\">" << date << "</" << METADATA_TAG << ">\n";
|
||||||
|
stream << " <" << METADATA_TAG << " name=\"Application\">" << SLIC3R_APP_KEY << "-" << SLIC3R_VERSION << "</" << METADATA_TAG << ">\n";
|
||||||
stream << " <" << RESOURCES_TAG << ">\n";
|
stream << " <" << RESOURCES_TAG << ">\n";
|
||||||
|
|
||||||
// Instance transformations, indexed by the 3MF object ID (which is a linear serialization of all instances of all ModelObjects).
|
// Instance transformations, indexed by the 3MF object ID (which is a linear serialization of all instances of all ModelObjects).
|
||||||
|
@ -579,142 +579,262 @@ namespace Slic3r {
|
|||||||
|
|
||||||
#define EXTRUDER_CONFIG(OPT) m_config.OPT.get_at(m_writer.extruder()->id())
|
#define EXTRUDER_CONFIG(OPT) m_config.OPT.get_at(m_writer.extruder()->id())
|
||||||
|
|
||||||
// Collect pairs of object_layer + support_layer sorted by print_z.
|
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
||||||
// object_layer & support_layer are considered to be on the same print_z, if they are not further than EPSILON.
|
// Collect pairs of object_layer + support_layer sorted by print_z.
|
||||||
std::vector<GCode::LayerToPrint> GCode::collect_layers_to_print(const PrintObject& object)
|
// object_layer & support_layer are considered to be on the same print_z, if they are not further than EPSILON.
|
||||||
{
|
std::vector<GCode::LayerToPrint> GCode::collect_layers_to_print(const PrintObject& object)
|
||||||
std::vector<GCode::LayerToPrint> layers_to_print;
|
{
|
||||||
layers_to_print.reserve(object.layers().size() + object.support_layers().size());
|
std::vector<GCode::LayerToPrint> layers_to_print;
|
||||||
|
layers_to_print.reserve(object.layers().size() + object.support_layers().size());
|
||||||
|
|
||||||
// Calculate a minimum support layer height as a minimum over all extruders, but not smaller than 10um.
|
// Calculate a minimum support layer height as a minimum over all extruders, but not smaller than 10um.
|
||||||
// This is the same logic as in support generator.
|
// This is the same logic as in support generator.
|
||||||
//FIXME should we use the printing extruders instead?
|
//FIXME should we use the printing extruders instead?
|
||||||
double gap_over_supports = object.config().support_material_contact_distance;
|
double gap_over_supports = object.config().support_material_contact_distance;
|
||||||
// FIXME should we test object.config().support_material_synchronize_layers ? Currently the support layers are synchronized with object layers iff soluble supports.
|
// FIXME should we test object.config().support_material_synchronize_layers ? Currently the support layers are synchronized with object layers iff soluble supports.
|
||||||
assert(!object.config().support_material || gap_over_supports != 0. || object.config().support_material_synchronize_layers);
|
assert(!object.config().support_material || gap_over_supports != 0. || object.config().support_material_synchronize_layers);
|
||||||
if (gap_over_supports != 0.) {
|
if (gap_over_supports != 0.) {
|
||||||
gap_over_supports = std::max(0., gap_over_supports);
|
gap_over_supports = std::max(0., gap_over_supports);
|
||||||
// Not a soluble support,
|
// Not a soluble support,
|
||||||
double support_layer_height_min = 1000000.;
|
double support_layer_height_min = 1000000.;
|
||||||
for (auto lh : object.print()->config().min_layer_height.values)
|
for (auto lh : object.print()->config().min_layer_height.values)
|
||||||
support_layer_height_min = std::min(support_layer_height_min, std::max(0.01, lh));
|
support_layer_height_min = std::min(support_layer_height_min, std::max(0.01, lh));
|
||||||
gap_over_supports += support_layer_height_min;
|
gap_over_supports += support_layer_height_min;
|
||||||
}
|
|
||||||
|
|
||||||
// Pair the object layers with the support layers by z.
|
|
||||||
size_t idx_object_layer = 0;
|
|
||||||
size_t idx_support_layer = 0;
|
|
||||||
const LayerToPrint* last_extrusion_layer = nullptr;
|
|
||||||
while (idx_object_layer < object.layers().size() || idx_support_layer < object.support_layers().size()) {
|
|
||||||
LayerToPrint layer_to_print;
|
|
||||||
layer_to_print.object_layer = (idx_object_layer < object.layers().size()) ? object.layers()[idx_object_layer++] : nullptr;
|
|
||||||
layer_to_print.support_layer = (idx_support_layer < object.support_layers().size()) ? object.support_layers()[idx_support_layer++] : nullptr;
|
|
||||||
if (layer_to_print.object_layer && layer_to_print.support_layer) {
|
|
||||||
if (layer_to_print.object_layer->print_z < layer_to_print.support_layer->print_z - EPSILON) {
|
|
||||||
layer_to_print.support_layer = nullptr;
|
|
||||||
--idx_support_layer;
|
|
||||||
}
|
|
||||||
else if (layer_to_print.support_layer->print_z < layer_to_print.object_layer->print_z - EPSILON) {
|
|
||||||
layer_to_print.object_layer = nullptr;
|
|
||||||
--idx_object_layer;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
layers_to_print.emplace_back(layer_to_print);
|
|
||||||
|
|
||||||
// Check that there are extrusions on the very first layer.
|
|
||||||
if (layers_to_print.size() == 1u) {
|
|
||||||
if ((layer_to_print.object_layer && !layer_to_print.object_layer->has_extrusions())
|
|
||||||
|| (layer_to_print.support_layer && !layer_to_print.support_layer->has_extrusions()))
|
|
||||||
throw std::runtime_error(_(L("There is an object with no extrusions on the first layer.")));
|
|
||||||
}
|
|
||||||
|
|
||||||
// In case there are extrusions on this layer, check there is a layer to lay it on.
|
|
||||||
if ((layer_to_print.object_layer && layer_to_print.object_layer->has_extrusions())
|
|
||||||
// Allow empty support layers, as the support generator may produce no extrusions for non-empty support regions.
|
|
||||||
|| (layer_to_print.support_layer /* && layer_to_print.support_layer->has_extrusions() */)) {
|
|
||||||
double support_contact_z = (last_extrusion_layer && last_extrusion_layer->support_layer)
|
|
||||||
? gap_over_supports
|
|
||||||
: 0.;
|
|
||||||
double maximal_print_z = (last_extrusion_layer ? last_extrusion_layer->print_z() : 0.)
|
|
||||||
+ layer_to_print.layer()->height
|
|
||||||
+ support_contact_z;
|
|
||||||
// Negative support_contact_z is not taken into account, it can result in false positives in cases
|
|
||||||
// where previous layer has object extrusions too (https://github.com/prusa3d/PrusaSlicer/issues/2752)
|
|
||||||
|
|
||||||
// Only check this layer in case it has some extrusions.
|
|
||||||
bool has_extrusions = (layer_to_print.object_layer && layer_to_print.object_layer->has_extrusions())
|
|
||||||
|| (layer_to_print.support_layer && layer_to_print.support_layer->has_extrusions());
|
|
||||||
|
|
||||||
if (has_extrusions && layer_to_print.print_z() > maximal_print_z + 2. * EPSILON) {
|
|
||||||
const_cast<Print*>(object.print())->active_step_add_warning(PrintStateBase::WarningLevel::CRITICAL,
|
|
||||||
_(L("Empty layers detected, the output would not be printable.")) + "\n\n" +
|
|
||||||
_(L("Object name")) + ": " + object.model_object()->name + "\n" + _(L("Print z")) + ": " +
|
|
||||||
std::to_string(layers_to_print.back().print_z()) + "\n\n" + _(L("This is "
|
|
||||||
"usually caused by negligibly small extrusions or by a faulty model. Try to repair "
|
|
||||||
"the model or change its orientation on the bed.")));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Remember last layer with extrusions.
|
|
||||||
if (has_extrusions)
|
|
||||||
last_extrusion_layer = &layers_to_print.back();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return layers_to_print;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Prepare for non-sequential printing of multiple objects: Support resp. object layers with nearly identical print_z
|
// Pair the object layers with the support layers by z.
|
||||||
// will be printed for all objects at once.
|
size_t idx_object_layer = 0;
|
||||||
// Return a list of <print_z, per object LayerToPrint> items.
|
size_t idx_support_layer = 0;
|
||||||
std::vector<std::pair<coordf_t, std::vector<GCode::LayerToPrint>>> GCode::collect_layers_to_print(const Print& print)
|
const LayerToPrint* last_extrusion_layer = nullptr;
|
||||||
{
|
while (idx_object_layer < object.layers().size() || idx_support_layer < object.support_layers().size()) {
|
||||||
struct OrderingItem {
|
LayerToPrint layer_to_print;
|
||||||
coordf_t print_z;
|
layer_to_print.object_layer = (idx_object_layer < object.layers().size()) ? object.layers()[idx_object_layer++] : nullptr;
|
||||||
size_t object_idx;
|
layer_to_print.support_layer = (idx_support_layer < object.support_layers().size()) ? object.support_layers()[idx_support_layer++] : nullptr;
|
||||||
size_t layer_idx;
|
if (layer_to_print.object_layer && layer_to_print.support_layer) {
|
||||||
};
|
if (layer_to_print.object_layer->print_z < layer_to_print.support_layer->print_z - EPSILON) {
|
||||||
|
layer_to_print.support_layer = nullptr;
|
||||||
std::vector<std::vector<LayerToPrint>> per_object(print.objects().size(), std::vector<LayerToPrint>());
|
--idx_support_layer;
|
||||||
std::vector<OrderingItem> ordering;
|
}
|
||||||
for (size_t i = 0; i < print.objects().size(); ++i) {
|
else if (layer_to_print.support_layer->print_z < layer_to_print.object_layer->print_z - EPSILON) {
|
||||||
per_object[i] = collect_layers_to_print(*print.objects()[i]);
|
layer_to_print.object_layer = nullptr;
|
||||||
OrderingItem ordering_item;
|
--idx_object_layer;
|
||||||
ordering_item.object_idx = i;
|
|
||||||
ordering.reserve(ordering.size() + per_object[i].size());
|
|
||||||
const LayerToPrint& front = per_object[i].front();
|
|
||||||
for (const LayerToPrint& ltp : per_object[i]) {
|
|
||||||
ordering_item.print_z = ltp.print_z();
|
|
||||||
ordering_item.layer_idx = <p - &front;
|
|
||||||
ordering.emplace_back(ordering_item);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::sort(ordering.begin(), ordering.end(), [](const OrderingItem& oi1, const OrderingItem& oi2) { return oi1.print_z < oi2.print_z; });
|
layers_to_print.emplace_back(layer_to_print);
|
||||||
|
|
||||||
std::vector<std::pair<coordf_t, std::vector<LayerToPrint>>> layers_to_print;
|
bool has_extrusions = (layer_to_print.object_layer && layer_to_print.object_layer->has_extrusions())
|
||||||
// Merge numerically very close Z values.
|
|| (layer_to_print.support_layer && layer_to_print.support_layer->has_extrusions());
|
||||||
for (size_t i = 0; i < ordering.size();) {
|
|
||||||
// Find the last layer with roughly the same print_z.
|
// Check that there are extrusions on the very first layer.
|
||||||
size_t j = i + 1;
|
if (layers_to_print.size() == 1u) {
|
||||||
coordf_t zmax = ordering[i].print_z + EPSILON;
|
if (!has_extrusions)
|
||||||
for (; j < ordering.size() && ordering[j].print_z <= zmax; ++j);
|
throw std::runtime_error(_(L("There is an object with no extrusions on the first layer.")));
|
||||||
// Merge into layers_to_print.
|
|
||||||
std::pair<coordf_t, std::vector<LayerToPrint>> merged;
|
|
||||||
// Assign an average print_z to the set of layers with nearly equal print_z.
|
|
||||||
merged.first = 0.5 * (ordering[i].print_z + ordering[j - 1].print_z);
|
|
||||||
merged.second.assign(print.objects().size(), LayerToPrint());
|
|
||||||
for (; i < j; ++i) {
|
|
||||||
const OrderingItem& oi = ordering[i];
|
|
||||||
assert(merged.second[oi.object_idx].layer() == nullptr);
|
|
||||||
merged.second[oi.object_idx] = std::move(per_object[oi.object_idx][oi.layer_idx]);
|
|
||||||
}
|
|
||||||
layers_to_print.emplace_back(std::move(merged));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return layers_to_print;
|
// In case there are extrusions on this layer, check there is a layer to lay it on.
|
||||||
|
if ((layer_to_print.object_layer && layer_to_print.object_layer->has_extrusions())
|
||||||
|
// Allow empty support layers, as the support generator may produce no extrusions for non-empty support regions.
|
||||||
|
|| (layer_to_print.support_layer /* && layer_to_print.support_layer->has_extrusions() */)) {
|
||||||
|
double support_contact_z = (last_extrusion_layer && last_extrusion_layer->support_layer)
|
||||||
|
? gap_over_supports
|
||||||
|
: 0.;
|
||||||
|
double maximal_print_z = (last_extrusion_layer ? last_extrusion_layer->print_z() : 0.)
|
||||||
|
+ layer_to_print.layer()->height
|
||||||
|
+ support_contact_z;
|
||||||
|
// Negative support_contact_z is not taken into account, it can result in false positives in cases
|
||||||
|
// where previous layer has object extrusions too (https://github.com/prusa3d/PrusaSlicer/issues/2752)
|
||||||
|
|
||||||
|
if (has_extrusions && layer_to_print.print_z() > maximal_print_z + 2. * EPSILON) {
|
||||||
|
const_cast<Print*>(object.print())->active_step_add_warning(PrintStateBase::WarningLevel::CRITICAL,
|
||||||
|
_(L("Empty layers detected, the output would not be printable.")) + "\n\n" +
|
||||||
|
_(L("Object name")) + ": " + object.model_object()->name + "\n" + _(L("Print z")) + ": " +
|
||||||
|
std::to_string(layers_to_print.back().print_z()) + "\n\n" + _(L("This is "
|
||||||
|
"usually caused by negligibly small extrusions or by a faulty model. Try to repair "
|
||||||
|
"the model or change its orientation on the bed.")));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remember last layer with extrusions.
|
||||||
|
if (has_extrusions)
|
||||||
|
last_extrusion_layer = &layers_to_print.back();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return layers_to_print;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// // Collect pairs of object_layer + support_layer sorted by print_z.
|
||||||
|
// // object_layer & support_layer are considered to be on the same print_z, if they are not further than EPSILON.
|
||||||
|
// std::vector<GCode::LayerToPrint> GCode::collect_layers_to_print(const PrintObject& object)
|
||||||
|
// {
|
||||||
|
// std::vector<GCode::LayerToPrint> layers_to_print;
|
||||||
|
// layers_to_print.reserve(object.layers().size() + object.support_layers().size());
|
||||||
|
//
|
||||||
|
// // Calculate a minimum support layer height as a minimum over all extruders, but not smaller than 10um.
|
||||||
|
// // This is the same logic as in support generator.
|
||||||
|
// //FIXME should we use the printing extruders instead?
|
||||||
|
// double gap_over_supports = object.config().support_material_contact_distance;
|
||||||
|
// // FIXME should we test object.config().support_material_synchronize_layers ? Currently the support layers are synchronized with object layers iff soluble supports.
|
||||||
|
// assert(!object.config().support_material || gap_over_supports != 0. || object.config().support_material_synchronize_layers);
|
||||||
|
// if (gap_over_supports != 0.) {
|
||||||
|
// gap_over_supports = std::max(0., gap_over_supports);
|
||||||
|
// // Not a soluble support,
|
||||||
|
// double support_layer_height_min = 1000000.;
|
||||||
|
// for (auto lh : object.print()->config().min_layer_height.values)
|
||||||
|
// support_layer_height_min = std::min(support_layer_height_min, std::max(0.01, lh));
|
||||||
|
// gap_over_supports += support_layer_height_min;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// // Pair the object layers with the support layers by z.
|
||||||
|
// size_t idx_object_layer = 0;
|
||||||
|
// size_t idx_support_layer = 0;
|
||||||
|
// const LayerToPrint* last_extrusion_layer = nullptr;
|
||||||
|
// while (idx_object_layer < object.layers().size() || idx_support_layer < object.support_layers().size()) {
|
||||||
|
// LayerToPrint layer_to_print;
|
||||||
|
// layer_to_print.object_layer = (idx_object_layer < object.layers().size()) ? object.layers()[idx_object_layer++] : nullptr;
|
||||||
|
// layer_to_print.support_layer = (idx_support_layer < object.support_layers().size()) ? object.support_layers()[idx_support_layer++] : nullptr;
|
||||||
|
// if (layer_to_print.object_layer && layer_to_print.support_layer) {
|
||||||
|
// if (layer_to_print.object_layer->print_z < layer_to_print.support_layer->print_z - EPSILON) {
|
||||||
|
// layer_to_print.support_layer = nullptr;
|
||||||
|
// --idx_support_layer;
|
||||||
|
// }
|
||||||
|
// else if (layer_to_print.support_layer->print_z < layer_to_print.object_layer->print_z - EPSILON) {
|
||||||
|
// layer_to_print.object_layer = nullptr;
|
||||||
|
// --idx_object_layer;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
//<<<<<<< HEAD
|
||||||
|
// layers_to_print.emplace_back(layer_to_print);
|
||||||
|
//
|
||||||
|
// // Check that there are extrusions on the very first layer.
|
||||||
|
// if (layers_to_print.size() == 1u) {
|
||||||
|
// if ((layer_to_print.object_layer && !layer_to_print.object_layer->has_extrusions())
|
||||||
|
// || (layer_to_print.support_layer && !layer_to_print.support_layer->has_extrusions()))
|
||||||
|
// throw std::runtime_error(_(L("There is an object with no extrusions on the first layer.")));
|
||||||
|
//=======
|
||||||
|
// layers_to_print.emplace_back(layer_to_print);
|
||||||
|
//
|
||||||
|
// bool has_extrusions = (layer_to_print.object_layer && layer_to_print.object_layer->has_extrusions())
|
||||||
|
// || (layer_to_print.support_layer && layer_to_print.support_layer->has_extrusions());
|
||||||
|
//
|
||||||
|
// // Check that there are extrusions on the very first layer.
|
||||||
|
// if (layers_to_print.size() == 1u) {
|
||||||
|
// if (! has_extrusions)
|
||||||
|
// throw std::runtime_error(_(L("There is an object with no extrusions on the first layer.")));
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// // In case there are extrusions on this layer, check there is a layer to lay it on.
|
||||||
|
// if ((layer_to_print.object_layer && layer_to_print.object_layer->has_extrusions())
|
||||||
|
// // Allow empty support layers, as the support generator may produce no extrusions for non-empty support regions.
|
||||||
|
// || (layer_to_print.support_layer /* && layer_to_print.support_layer->has_extrusions() */)) {
|
||||||
|
// double support_contact_z = (last_extrusion_layer && last_extrusion_layer->support_layer)
|
||||||
|
// ? gap_over_supports
|
||||||
|
// : 0.;
|
||||||
|
// double maximal_print_z = (last_extrusion_layer ? last_extrusion_layer->print_z() : 0.)
|
||||||
|
// + layer_to_print.layer()->height
|
||||||
|
// + support_contact_z;
|
||||||
|
// // Negative support_contact_z is not taken into account, it can result in false positives in cases
|
||||||
|
// // where previous layer has object extrusions too (https://github.com/prusa3d/PrusaSlicer/issues/2752)
|
||||||
|
//
|
||||||
|
// if (has_extrusions && layer_to_print.print_z() > maximal_print_z + 2. * EPSILON) {
|
||||||
|
// const_cast<Print*>(object.print())->active_step_add_warning(PrintStateBase::WarningLevel::CRITICAL,
|
||||||
|
// _(L("Empty layers detected, the output would not be printable.")) + "\n\n" +
|
||||||
|
// _(L("Object name")) + ": " + object.model_object()->name + "\n" + _(L("Print z")) + ": " +
|
||||||
|
// std::to_string(layers_to_print.back().print_z()) + "\n\n" + _(L("This is "
|
||||||
|
// "usually caused by negligibly small extrusions or by a faulty model. Try to repair "
|
||||||
|
// "the model or change its orientation on the bed.")));
|
||||||
|
//>>>>>>> b587289c141022323753fa1810552964de0b1356
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// // In case there are extrusions on this layer, check there is a layer to lay it on.
|
||||||
|
// if ((layer_to_print.object_layer && layer_to_print.object_layer->has_extrusions())
|
||||||
|
// // Allow empty support layers, as the support generator may produce no extrusions for non-empty support regions.
|
||||||
|
// || (layer_to_print.support_layer /* && layer_to_print.support_layer->has_extrusions() */)) {
|
||||||
|
// double support_contact_z = (last_extrusion_layer && last_extrusion_layer->support_layer)
|
||||||
|
// ? gap_over_supports
|
||||||
|
// : 0.;
|
||||||
|
// double maximal_print_z = (last_extrusion_layer ? last_extrusion_layer->print_z() : 0.)
|
||||||
|
// + layer_to_print.layer()->height
|
||||||
|
// + support_contact_z;
|
||||||
|
// // Negative support_contact_z is not taken into account, it can result in false positives in cases
|
||||||
|
// // where previous layer has object extrusions too (https://github.com/prusa3d/PrusaSlicer/issues/2752)
|
||||||
|
//
|
||||||
|
// // Only check this layer in case it has some extrusions.
|
||||||
|
// bool has_extrusions = (layer_to_print.object_layer && layer_to_print.object_layer->has_extrusions())
|
||||||
|
// || (layer_to_print.support_layer && layer_to_print.support_layer->has_extrusions());
|
||||||
|
//
|
||||||
|
// if (has_extrusions && layer_to_print.print_z() > maximal_print_z + 2. * EPSILON) {
|
||||||
|
// const_cast<Print*>(object.print())->active_step_add_warning(PrintStateBase::WarningLevel::CRITICAL,
|
||||||
|
// _(L("Empty layers detected, the output would not be printable.")) + "\n\n" +
|
||||||
|
// _(L("Object name")) + ": " + object.model_object()->name + "\n" + _(L("Print z")) + ": " +
|
||||||
|
// std::to_string(layers_to_print.back().print_z()) + "\n\n" + _(L("This is "
|
||||||
|
// "usually caused by negligibly small extrusions or by a faulty model. Try to repair "
|
||||||
|
// "the model or change its orientation on the bed.")));
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// // Remember last layer with extrusions.
|
||||||
|
// if (has_extrusions)
|
||||||
|
// last_extrusion_layer = &layers_to_print.back();
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// return layers_to_print;
|
||||||
|
// }
|
||||||
|
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
||||||
|
|
||||||
|
// Prepare for non-sequential printing of multiple objects: Support resp. object layers with nearly identical print_z
|
||||||
|
// will be printed for all objects at once.
|
||||||
|
// Return a list of <print_z, per object LayerToPrint> items.
|
||||||
|
std::vector<std::pair<coordf_t, std::vector<GCode::LayerToPrint>>> GCode::collect_layers_to_print(const Print& print)
|
||||||
|
{
|
||||||
|
struct OrderingItem {
|
||||||
|
coordf_t print_z;
|
||||||
|
size_t object_idx;
|
||||||
|
size_t layer_idx;
|
||||||
|
};
|
||||||
|
|
||||||
|
std::vector<std::vector<LayerToPrint>> per_object(print.objects().size(), std::vector<LayerToPrint>());
|
||||||
|
std::vector<OrderingItem> ordering;
|
||||||
|
for (size_t i = 0; i < print.objects().size(); ++i) {
|
||||||
|
per_object[i] = collect_layers_to_print(*print.objects()[i]);
|
||||||
|
OrderingItem ordering_item;
|
||||||
|
ordering_item.object_idx = i;
|
||||||
|
ordering.reserve(ordering.size() + per_object[i].size());
|
||||||
|
const LayerToPrint& front = per_object[i].front();
|
||||||
|
for (const LayerToPrint& ltp : per_object[i]) {
|
||||||
|
ordering_item.print_z = ltp.print_z();
|
||||||
|
ordering_item.layer_idx = <p - &front;
|
||||||
|
ordering.emplace_back(ordering_item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::sort(ordering.begin(), ordering.end(), [](const OrderingItem& oi1, const OrderingItem& oi2) { return oi1.print_z < oi2.print_z; });
|
||||||
|
|
||||||
|
std::vector<std::pair<coordf_t, std::vector<LayerToPrint>>> layers_to_print;
|
||||||
|
// Merge numerically very close Z values.
|
||||||
|
for (size_t i = 0; i < ordering.size();) {
|
||||||
|
// Find the last layer with roughly the same print_z.
|
||||||
|
size_t j = i + 1;
|
||||||
|
coordf_t zmax = ordering[i].print_z + EPSILON;
|
||||||
|
for (; j < ordering.size() && ordering[j].print_z <= zmax; ++j);
|
||||||
|
// Merge into layers_to_print.
|
||||||
|
std::pair<coordf_t, std::vector<LayerToPrint>> merged;
|
||||||
|
// Assign an average print_z to the set of layers with nearly equal print_z.
|
||||||
|
merged.first = 0.5 * (ordering[i].print_z + ordering[j - 1].print_z);
|
||||||
|
merged.second.assign(print.objects().size(), LayerToPrint());
|
||||||
|
for (; i < j; ++i) {
|
||||||
|
const OrderingItem& oi = ordering[i];
|
||||||
|
assert(merged.second[oi.object_idx].layer() == nullptr);
|
||||||
|
merged.second[oi.object_idx] = std::move(per_object[oi.object_idx][oi.layer_idx]);
|
||||||
|
}
|
||||||
|
layers_to_print.emplace_back(std::move(merged));
|
||||||
|
}
|
||||||
|
|
||||||
|
return layers_to_print;
|
||||||
|
}
|
||||||
|
|
||||||
#if ENABLE_GCODE_VIEWER
|
#if ENABLE_GCODE_VIEWER
|
||||||
void GCode::do_export(Print* print, const char* path, GCodeProcessor::Result* result, ThumbnailsGeneratorCallback thumbnail_cb)
|
void GCode::do_export(Print* print, const char* path, GCodeProcessor::Result* result, ThumbnailsGeneratorCallback thumbnail_cb)
|
||||||
#else
|
#else
|
||||||
|
@ -1122,7 +1122,7 @@ void PrintConfigDef::init_fff_params()
|
|||||||
|
|
||||||
def = this->add("ironing_spacing", coFloat);
|
def = this->add("ironing_spacing", coFloat);
|
||||||
def->label = L("Spacing between ironing passes");
|
def->label = L("Spacing between ironing passes");
|
||||||
def->tooltip = L("Distance between ironing lins");
|
def->tooltip = L("Distance between ironing lines");
|
||||||
def->sidetext = L("mm");
|
def->sidetext = L("mm");
|
||||||
def->min = 0;
|
def->min = 0;
|
||||||
def->mode = comExpert;
|
def->mode = comExpert;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user