diff options
author | supermerill <merill@free.fr> | 2021-12-06 20:51:30 +0300 |
---|---|---|
committer | supermerill <merill@free.fr> | 2021-12-07 17:05:35 +0300 |
commit | 698be8f3de466dcf25ff8597fba1af6380beb587 (patch) | |
tree | 4b6d7cf2ca3d3f062dac8e46d6bcd0ef5737a3cd /src | |
parent | 3b2b5a43d523170db2b16ca7027b87b34a5b8832 (diff) |
Fix seam object for multiple instances with different rotations
supermerill/SuperSlicer#2015
Diffstat (limited to 'src')
-rw-r--r-- | src/libslic3r/GCode.cpp | 7 | ||||
-rw-r--r-- | src/libslic3r/GCode.hpp | 6 | ||||
-rw-r--r-- | src/libslic3r/GCode/SeamPlacer.cpp | 25 | ||||
-rw-r--r-- | src/libslic3r/GCode/SeamPlacer.hpp | 2 |
4 files changed, 26 insertions, 14 deletions
diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index acdc5d731..239c61f8b 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -2230,6 +2230,8 @@ void GCode::process_layer( assert(! layers.empty()); // Either printing all copies of all objects, or just a single copy of a single object. assert(single_object_instance_idx == size_t(-1) || layers.size() == 1); + if(single_object_instance_idx != size_t(-1)) + m_print_object_instance_id = static_cast<uint16_t>(single_object_instance_idx); if (layer_tools.extruders.empty()) // Nothing to extrude. @@ -2626,6 +2628,7 @@ void GCode::process_layer( for (InstanceToPrint &instance_to_print : instances_to_print) { m_config.apply(instance_to_print.print_object.config(), true); m_layer = layers[instance_to_print.layer_id].layer(); + m_print_object_instance_id = static_cast<uint16_t>(instance_to_print.instance_id); if (m_config.avoid_crossing_perimeters) m_avoid_crossing_perimeters.init_layer(*m_layer); //print object label to help the printer firmware know where it is (for removing the objects) @@ -3200,7 +3203,9 @@ void GCode::split_at_seam_pos(ExtrusionLoop& loop, std::unique_ptr<EdgeGrid::Gri Point seam = m_seam_placer.get_seam(*m_layer, seam_position, loop, last_pos, EXTRUDER_CONFIG_WITH_DEFAULT(nozzle_diameter, 0), (m_layer == NULL ? nullptr : m_layer->object()), - was_clockwise, edge_grid_ptr); + m_print_object_instance_id, + was_clockwise, + edge_grid_ptr); // Split the loop at the point with a minium penalty. if (!loop.split_at_vertex(seam)) // The point is not in the original loop. Insert it. diff --git a/src/libslic3r/GCode.hpp b/src/libslic3r/GCode.hpp index 8c2bc4242..7fab43e75 100644 --- a/src/libslic3r/GCode.hpp +++ b/src/libslic3r/GCode.hpp @@ -290,8 +290,8 @@ private: struct InstanceToPrint { - InstanceToPrint(ObjectByExtruder &object_by_extruder, size_t layer_id, const PrintObject &print_object, size_t instance_id) : - object_by_extruder(object_by_extruder), layer_id(layer_id), print_object(print_object), instance_id(instance_id) {} + InstanceToPrint(ObjectByExtruder& object_by_extruder, size_t layer_id, const PrintObject& print_object, size_t instance_id) : + object_by_extruder(object_by_extruder), layer_id(layer_id), print_object(print_object), instance_id(instance_id) {} // Repository ObjectByExtruder &object_by_extruder; @@ -362,6 +362,8 @@ private: // Current layer processed. Insequential printing mode, only a single copy will be printed. // In non-sequential mode, all its copies will be printed. const Layer* m_layer; + // idx of the current instance printed. (or the last one) + uint16_t m_print_object_instance_id = -1; // For crossing perimeter retraction detection (contain the layer & nozzle widdth used to construct it) // !!!! not thread-safe !!!! if threaded per layer, please store it in the thread. struct SliceOffsetted { diff --git a/src/libslic3r/GCode/SeamPlacer.cpp b/src/libslic3r/GCode/SeamPlacer.cpp index 00a8800d3..44e713d18 100644 --- a/src/libslic3r/GCode/SeamPlacer.cpp +++ b/src/libslic3r/GCode/SeamPlacer.cpp @@ -293,7 +293,8 @@ void SeamPlacer::init(const Print& print) Point SeamPlacer::get_seam(const Layer& layer, SeamPosition seam_position, const ExtrusionLoop& loop, Point last_pos, coordf_t nozzle_dmr, - const PrintObject* po, bool was_clockwise, const EdgeGrid::Grid* lower_layer_edge_grid) + const PrintObject* po, const uint16_t print_object_instance_idx, + bool was_clockwise, const EdgeGrid::Grid* lower_layer_edge_grid) { Polygon polygon = loop.polygon(); BoundingBox polygon_bb = polygon.bounding_box(); @@ -329,22 +330,25 @@ Point SeamPlacer::get_seam(const Layer& layer, SeamPosition seam_position, } bool has_seam_custom = false; - for (ModelVolume* v : po->model_object()->volumes) - if (v->is_seam_position()) { - has_seam_custom = true; - break; - } + if(print_object_instance_idx < po->instances().size()) + for (ModelVolume* v : po->model_object()->volumes) + if (v->is_seam_position()) { + has_seam_custom = true; + break; + } if (has_seam_custom) { // Look for all lambda-seam-modifiers below current z, choose the highest one ModelVolume* v_lambda_seam = nullptr; Vec3d lambda_pos; double lambda_dist; double lambda_radius; - for (ModelVolume* v : po->model_object()->volumes) + //get model_instance (like from po->model_object()->instances, but we don't have the index for that array) + const ModelInstance* model_instance = po->instances()[print_object_instance_idx].model_instance; + for (ModelVolume* v : po->model_object()->volumes) { if (v->is_seam_position()) { //xy in object coordinates, z in plater coordinates - Vec3d test_lambda_pos = po->model_object()->instances.front()->transform_vector(v->get_offset(), true); - Vec3d test_lambda_pos_plater = po->model_object()->instances.front()->transform_vector(v->get_offset(), false); + Vec3d test_lambda_pos = model_instance->transform_vector(v->get_offset(), true); + Point xy_lambda(scale_(test_lambda_pos.x()), scale_(test_lambda_pos.y())); Point nearest = polygon.point_projection(xy_lambda); Vec3d polygon_3dpoint{ unscaled(nearest.x()), unscaled(nearest.y()), (double)layer.print_z }; @@ -361,9 +365,10 @@ Point SeamPlacer::get_seam(const Layer& layer, SeamPosition seam_position, lambda_dist = test_lambda_dist; } } + } if (v_lambda_seam != nullptr) { - lambda_pos = po->model_object()->instances.front()->transform_vector(v_lambda_seam->get_offset(), true); + lambda_pos = model_instance->transform_vector(v_lambda_seam->get_offset(), true); // Found, get the center point and apply rotation and scaling of Model instance. Continues to spAligned if not found or Weight set to Zero. last_pos = Point::new_scale(lambda_pos.x(), lambda_pos.y()); // Weight is set by user and stored in the radius of the sphere diff --git a/src/libslic3r/GCode/SeamPlacer.hpp b/src/libslic3r/GCode/SeamPlacer.hpp index d7b1cf0a7..19b658562 100644 --- a/src/libslic3r/GCode/SeamPlacer.hpp +++ b/src/libslic3r/GCode/SeamPlacer.hpp @@ -43,7 +43,7 @@ public: Point get_seam(const Layer& layer, SeamPosition seam_position, const ExtrusionLoop& loop, Point last_pos, - coordf_t nozzle_diameter, const PrintObject* po, + coordf_t nozzle_diameter, const PrintObject* po, const uint16_t object_instance_idx, bool was_clockwise, const EdgeGrid::Grid* lower_layer_edge_grid); using TreeType = AABBTreeIndirect::Tree<2, coord_t>; |