mirror of
https://git.mirrors.martin98.com/https://github.com/slic3r/Slic3r.git
synced 2025-08-17 11:05:53 +08:00
Fix seam object for multiple instances with different rotations
supermerill/SuperSlicer#2015
This commit is contained in:
parent
3b2b5a43d5
commit
698be8f3de
@ -2230,6 +2230,8 @@ void GCode::process_layer(
|
|||||||
assert(! layers.empty());
|
assert(! layers.empty());
|
||||||
// Either printing all copies of all objects, or just a single copy of a single object.
|
// 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);
|
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())
|
if (layer_tools.extruders.empty())
|
||||||
// Nothing to extrude.
|
// Nothing to extrude.
|
||||||
@ -2626,6 +2628,7 @@ void GCode::process_layer(
|
|||||||
for (InstanceToPrint &instance_to_print : instances_to_print) {
|
for (InstanceToPrint &instance_to_print : instances_to_print) {
|
||||||
m_config.apply(instance_to_print.print_object.config(), true);
|
m_config.apply(instance_to_print.print_object.config(), true);
|
||||||
m_layer = layers[instance_to_print.layer_id].layer();
|
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)
|
if (m_config.avoid_crossing_perimeters)
|
||||||
m_avoid_crossing_perimeters.init_layer(*m_layer);
|
m_avoid_crossing_perimeters.init_layer(*m_layer);
|
||||||
//print object label to help the printer firmware know where it is (for removing the objects)
|
//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,
|
Point seam = m_seam_placer.get_seam(*m_layer, seam_position, loop,
|
||||||
last_pos, EXTRUDER_CONFIG_WITH_DEFAULT(nozzle_diameter, 0),
|
last_pos, EXTRUDER_CONFIG_WITH_DEFAULT(nozzle_diameter, 0),
|
||||||
(m_layer == NULL ? nullptr : m_layer->object()),
|
(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.
|
// Split the loop at the point with a minium penalty.
|
||||||
if (!loop.split_at_vertex(seam))
|
if (!loop.split_at_vertex(seam))
|
||||||
// The point is not in the original loop. Insert it.
|
// The point is not in the original loop. Insert it.
|
||||||
|
@ -290,8 +290,8 @@ private:
|
|||||||
|
|
||||||
struct InstanceToPrint
|
struct InstanceToPrint
|
||||||
{
|
{
|
||||||
InstanceToPrint(ObjectByExtruder &object_by_extruder, size_t layer_id, const PrintObject &print_object, size_t 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) {}
|
object_by_extruder(object_by_extruder), layer_id(layer_id), print_object(print_object), instance_id(instance_id) {}
|
||||||
|
|
||||||
// Repository
|
// Repository
|
||||||
ObjectByExtruder &object_by_extruder;
|
ObjectByExtruder &object_by_extruder;
|
||||||
@ -362,6 +362,8 @@ private:
|
|||||||
// Current layer processed. Insequential printing mode, only a single copy will be printed.
|
// Current layer processed. Insequential printing mode, only a single copy will be printed.
|
||||||
// In non-sequential mode, all its copies will be printed.
|
// In non-sequential mode, all its copies will be printed.
|
||||||
const Layer* m_layer;
|
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)
|
// 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.
|
// !!!! not thread-safe !!!! if threaded per layer, please store it in the thread.
|
||||||
struct SliceOffsetted {
|
struct SliceOffsetted {
|
||||||
|
@ -293,7 +293,8 @@ void SeamPlacer::init(const Print& print)
|
|||||||
|
|
||||||
Point SeamPlacer::get_seam(const Layer& layer, SeamPosition seam_position,
|
Point SeamPlacer::get_seam(const Layer& layer, SeamPosition seam_position,
|
||||||
const ExtrusionLoop& loop, Point last_pos, coordf_t nozzle_dmr,
|
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();
|
Polygon polygon = loop.polygon();
|
||||||
BoundingBox polygon_bb = polygon.bounding_box();
|
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;
|
bool has_seam_custom = false;
|
||||||
for (ModelVolume* v : po->model_object()->volumes)
|
if(print_object_instance_idx < po->instances().size())
|
||||||
if (v->is_seam_position()) {
|
for (ModelVolume* v : po->model_object()->volumes)
|
||||||
has_seam_custom = true;
|
if (v->is_seam_position()) {
|
||||||
break;
|
has_seam_custom = true;
|
||||||
}
|
break;
|
||||||
|
}
|
||||||
if (has_seam_custom) {
|
if (has_seam_custom) {
|
||||||
// Look for all lambda-seam-modifiers below current z, choose the highest one
|
// Look for all lambda-seam-modifiers below current z, choose the highest one
|
||||||
ModelVolume* v_lambda_seam = nullptr;
|
ModelVolume* v_lambda_seam = nullptr;
|
||||||
Vec3d lambda_pos;
|
Vec3d lambda_pos;
|
||||||
double lambda_dist;
|
double lambda_dist;
|
||||||
double lambda_radius;
|
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()) {
|
if (v->is_seam_position()) {
|
||||||
//xy in object coordinates, z in plater coordinates
|
//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 = model_instance->transform_vector(v->get_offset(), true);
|
||||||
Vec3d test_lambda_pos_plater = po->model_object()->instances.front()->transform_vector(v->get_offset(), false);
|
|
||||||
Point xy_lambda(scale_(test_lambda_pos.x()), scale_(test_lambda_pos.y()));
|
Point xy_lambda(scale_(test_lambda_pos.x()), scale_(test_lambda_pos.y()));
|
||||||
Point nearest = polygon.point_projection(xy_lambda);
|
Point nearest = polygon.point_projection(xy_lambda);
|
||||||
Vec3d polygon_3dpoint{ unscaled(nearest.x()), unscaled(nearest.y()), (double)layer.print_z };
|
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;
|
lambda_dist = test_lambda_dist;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (v_lambda_seam != nullptr) {
|
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.
|
// 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());
|
last_pos = Point::new_scale(lambda_pos.x(), lambda_pos.y());
|
||||||
// Weight is set by user and stored in the radius of the sphere
|
// Weight is set by user and stored in the radius of the sphere
|
||||||
|
@ -43,7 +43,7 @@ public:
|
|||||||
|
|
||||||
Point get_seam(const Layer& layer, SeamPosition seam_position,
|
Point get_seam(const Layer& layer, SeamPosition seam_position,
|
||||||
const ExtrusionLoop& loop, Point last_pos,
|
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);
|
bool was_clockwise, const EdgeGrid::Grid* lower_layer_edge_grid);
|
||||||
|
|
||||||
using TreeType = AABBTreeIndirect::Tree<2, coord_t>;
|
using TreeType = AABBTreeIndirect::Tree<2, coord_t>;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user