mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-09-23 17:02:39 +00:00
Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a80d0b49f0 |
@@ -7015,6 +7015,12 @@ int CLI::run(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
sliced_info.sliced_plates.push_back(sliced_plate_info);
|
sliced_info.sliced_plates.push_back(sliced_plate_info);
|
||||||
|
} catch (const Slic3r::SlicingErrors &exs) {
|
||||||
|
const std::string message = print_fff ? print_fff->slicing_errors_message(exs) : std::string(exs.what());
|
||||||
|
BOOST_LOG_TRIVIAL(error) << "found slicing or export error for partplate " << index+1 << ": " << message;
|
||||||
|
boost::nowide::cerr << message << std::endl;
|
||||||
|
record_exit_reson(outfile_dir, CLI_SLICING_ERROR, index+1, message, sliced_info);
|
||||||
|
flush_and_exit(CLI_SLICING_ERROR);
|
||||||
} catch (const std::exception &ex) {
|
} catch (const std::exception &ex) {
|
||||||
BOOST_LOG_TRIVIAL(error) << "found slicing or export error for partplate "<<index+1 << std::endl;
|
BOOST_LOG_TRIVIAL(error) << "found slicing or export error for partplate "<<index+1 << std::endl;
|
||||||
boost::nowide::cerr << ex.what() << std::endl;
|
boost::nowide::cerr << ex.what() << std::endl;
|
||||||
|
|||||||
@@ -1704,6 +1704,25 @@ StringObjectException Print::check_multi_filament_valid(const Print& print)
|
|||||||
|
|
||||||
// Precondition: Print::validate() requires the Print::apply() to be called its invocation.
|
// Precondition: Print::validate() requires the Print::apply() to be called its invocation.
|
||||||
//BBS: refine seq-print validation logic
|
//BBS: refine seq-print validation logic
|
||||||
|
// The exception's own message is just "Errors"; the detail is in the per-object errors,
|
||||||
|
// whose object id is the PrintObject's.
|
||||||
|
std::string Print::slicing_errors_message(const SlicingErrors &errors) const
|
||||||
|
{
|
||||||
|
std::string message;
|
||||||
|
for (const SlicingError &error : errors.errors_) {
|
||||||
|
std::string object_name;
|
||||||
|
for (const PrintObject *object : m_objects)
|
||||||
|
if (object->id().id == error.objectId()) {
|
||||||
|
object_name = object->model_object()->name;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (!message.empty())
|
||||||
|
message += "\n";
|
||||||
|
message += object_name.empty() ? std::string(error.what()) : object_name + ": " + error.what();
|
||||||
|
}
|
||||||
|
return message;
|
||||||
|
}
|
||||||
|
|
||||||
StringObjectException Print::validate(std::vector<StringObjectException> *warnings, Polygons* collison_polygons, std::vector<std::pair<Polygon, float>>* height_polygons) const
|
StringObjectException Print::validate(std::vector<StringObjectException> *warnings, Polygons* collison_polygons, std::vector<std::pair<Polygon, float>>* height_polygons) const
|
||||||
{
|
{
|
||||||
auto add_warning = [warnings](StringObjectException w) {
|
auto add_warning = [warnings](StringObjectException w) {
|
||||||
|
|||||||
@@ -30,6 +30,8 @@
|
|||||||
|
|
||||||
namespace Slic3r {
|
namespace Slic3r {
|
||||||
|
|
||||||
|
class SlicingErrors;
|
||||||
|
|
||||||
class GCode;
|
class GCode;
|
||||||
class Layer;
|
class Layer;
|
||||||
class ModelObject;
|
class ModelObject;
|
||||||
@@ -967,6 +969,8 @@ public:
|
|||||||
|
|
||||||
// Returns an empty string if valid, otherwise returns an error message.
|
// Returns an empty string if valid, otherwise returns an error message.
|
||||||
StringObjectException validate(std::vector<StringObjectException> *warnings = nullptr, Polygons* collison_polygons = nullptr, std::vector<std::pair<Polygon, float>>* height_polygons = nullptr) const override;
|
StringObjectException validate(std::vector<StringObjectException> *warnings = nullptr, Polygons* collison_polygons = nullptr, std::vector<std::pair<Polygon, float>>* height_polygons = nullptr) const override;
|
||||||
|
// The per-object messages of a SlicingErrors, each prefixed with its object's name.
|
||||||
|
std::string slicing_errors_message(const SlicingErrors &errors) const;
|
||||||
double skirt_first_layer_height() const;
|
double skirt_first_layer_height() const;
|
||||||
Flow brim_flow() const;
|
Flow brim_flow() const;
|
||||||
Flow skirt_flow() const;
|
Flow skirt_flow() const;
|
||||||
|
|||||||
@@ -505,3 +505,29 @@ TEST_CASE("Sequential printing publishes the nozzle group result", "[Print][Mult
|
|||||||
CHECK(gcode.find("; SEQ-ND-OK") != std::string::npos);
|
CHECK(gcode.find("; SEQ-ND-OK") != std::string::npos);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_CASE("Slicing errors are reported per object with the object's name", "[Print]")
|
||||||
|
{
|
||||||
|
Print print;
|
||||||
|
Model model;
|
||||||
|
init_print({Slic3r::Test::cube(20.)}, print, model);
|
||||||
|
// Lift the cube off the bed: its first layer is empty, which G-code export reports per object.
|
||||||
|
ModelObject *object = model.objects.front();
|
||||||
|
object->name = "floating cube";
|
||||||
|
object->instances.front()->set_offset(object->instances.front()->get_offset() + Vec3d(0., 0., 2.));
|
||||||
|
print.apply(model, DynamicPrintConfig::full_print_config());
|
||||||
|
print.set_status_silent();
|
||||||
|
|
||||||
|
ScopedTemporaryFile temp(".gcode");
|
||||||
|
std::string message;
|
||||||
|
try {
|
||||||
|
print.process();
|
||||||
|
print.export_gcode(temp.string(), nullptr, nullptr);
|
||||||
|
FAIL("slicing did not report the empty first layer");
|
||||||
|
} catch (const SlicingErrors &errors) {
|
||||||
|
REQUIRE(errors.errors_.size() == 1);
|
||||||
|
message = print.slicing_errors_message(errors);
|
||||||
|
}
|
||||||
|
CHECK(message.rfind("floating cube: ", 0) == 0);
|
||||||
|
CHECK(message.find("empty first layer") != std::string::npos);
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user