mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-07-29 05:42:33 +00:00
Fix skirt and brim handling for duplicated objects (instances) (#14683)
This commit is contained in:
@@ -399,6 +399,26 @@ std::string slice_two_cubes_apart(double gap, std::initializer_list<Slic3r::Conf
|
||||
return gcode(print);
|
||||
}
|
||||
|
||||
void place_two_cube_instances_apart(double gap, std::initializer_list<Slic3r::ConfigBase::SetDeserializeItem> config_items,
|
||||
Print &print, Model &model)
|
||||
{
|
||||
DynamicPrintConfig config = DynamicPrintConfig::full_print_config();
|
||||
config.set_deserialize_strict(config_items);
|
||||
config.set_key_value("gcode_comments", new ConfigOptionBool(true));
|
||||
|
||||
ModelObject *object = model.add_object();
|
||||
object->name += "object.stl";
|
||||
object->add_volume(cube(20));
|
||||
object->add_instance()->set_offset(Vec3d(80, 80, 0));
|
||||
object->add_instance()->set_offset(Vec3d(80 + 20 + gap, 80, 0));
|
||||
object->ensure_on_bed();
|
||||
print.auto_assign_extruders(object);
|
||||
|
||||
print.apply(model, config);
|
||||
print.validate();
|
||||
print.set_status_silent();
|
||||
}
|
||||
|
||||
std::set<double> layers_with_role(const std::string &gcode, const std::string &role)
|
||||
{
|
||||
std::set<double> layers;
|
||||
|
||||
@@ -108,6 +108,10 @@ void place_two_cubes_apart(double gap, std::initializer_list<Slic3r::ConfigBase:
|
||||
// Slice two 20mm cubes `gap` mm apart (not auto-arranged) and return the G-code.
|
||||
std::string slice_two_cubes_apart(double gap, std::initializer_list<Slic3r::ConfigBase::SetDeserializeItem> config_items);
|
||||
|
||||
// Place two instances of one 20mm cube `gap` mm apart edge-to-edge.
|
||||
void place_two_cube_instances_apart(double gap, std::initializer_list<Slic3r::ConfigBase::SetDeserializeItem> config_items,
|
||||
Slic3r::Print &print, Slic3r::Model &model);
|
||||
|
||||
// Distinct layer Z heights carrying an extrusion of the given `role` (e.g. "skirt").
|
||||
std::set<double> layers_with_role(const std::string &gcode, const std::string &role);
|
||||
|
||||
|
||||
@@ -86,6 +86,27 @@ TEST_CASE("Per-object skirts group when objects are close", "[SkirtBrim]")
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("Per-object skirt is generated per instance", "[SkirtBrim]")
|
||||
{
|
||||
Print print;
|
||||
Model model;
|
||||
place_two_cube_instances_apart(60, {
|
||||
{ "skirt_type", "perobject" },
|
||||
{ "skirt_height", 1 },
|
||||
{ "skirt_distance", 2 },
|
||||
{ "skirt_loops", 1 },
|
||||
{ "brim_type", "no_brim" },
|
||||
}, print, model);
|
||||
print.process();
|
||||
|
||||
REQUIRE(print.skirt_brim_groups().size() == 2);
|
||||
REQUIRE(print.skirt().items_count() == 2);
|
||||
for (const Print::SkirtBrimGroup &group : print.skirt_brim_groups()) {
|
||||
REQUIRE(group.instances.size() == 1);
|
||||
REQUIRE(group.instances.front().object_id == print.get_object(0)->id());
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("Combine brims merges touching brims", "[SkirtBrim]")
|
||||
{
|
||||
auto [gap, combine, expected_brims] = GENERATE(table<double, int, int>({
|
||||
@@ -112,6 +133,45 @@ TEST_CASE("Combine brims merges touching brims", "[SkirtBrim]")
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("Object brims are generated per instance", "[SkirtBrim]")
|
||||
{
|
||||
Print print;
|
||||
Model model;
|
||||
place_two_cube_instances_apart(60, {
|
||||
{ "skirt_loops", 0 },
|
||||
{ "brim_type", "outer_only" },
|
||||
{ "brim_width", 5 },
|
||||
{ "combine_brims", 0 },
|
||||
}, print, model);
|
||||
print.process();
|
||||
|
||||
REQUIRE(print.skirt_brim_groups().size() == 1);
|
||||
REQUIRE(print.skirt_brim_groups().front().brims.size() == 2);
|
||||
for (const Print::SkirtBrimGroup::Brim &brim : print.skirt_brim_groups().front().brims) {
|
||||
REQUIRE(brim.instances.size() == 1);
|
||||
REQUIRE(brim.instances.front().object_id == print.get_object(0)->id());
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("Combine brims merges neighboring object instances", "[SkirtBrim]")
|
||||
{
|
||||
Print print;
|
||||
Model model;
|
||||
place_two_cube_instances_apart(5, {
|
||||
{ "skirt_loops", 0 },
|
||||
{ "brim_type", "outer_only" },
|
||||
{ "brim_width", 5 },
|
||||
{ "combine_brims", 1 },
|
||||
}, print, model);
|
||||
print.process();
|
||||
|
||||
REQUIRE(print.skirt_brim_groups().size() == 1);
|
||||
REQUIRE(print.skirt_brim_groups().front().brims.size() == 1);
|
||||
REQUIRE(print.skirt_brim_groups().front().brims.front().instances.size() == 2);
|
||||
const std::vector<std::string> expected{ "brim", "perimeter" };
|
||||
CHECK(role_sequence(gcode(print), { "brim", "perimeter" }) == expected);
|
||||
}
|
||||
|
||||
// Each object's skirt and brim come right before that object, not all skirts then all brims first.
|
||||
TEST_CASE("By-layer per-object skirt and brim precede each object", "[SkirtBrim]")
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user