fixed bug with base layers merging to single accumulator

This commit is contained in:
PavelMikus 2022-06-22 15:27:18 +02:00
parent eaffb14921
commit d5a584a2c2
2 changed files with 64 additions and 48 deletions

View File

@ -123,26 +123,23 @@ private:
Points support_points { }; Points support_points { };
Vec3f centroid_accumulator = Vec3f::Zero(); Vec3f centroid_accumulator = Vec3f::Zero();
float accumulated_volume { }; float accumulated_volume { };
float base_area { }; float accumulated_sticking_force { };
float base_height { };
public: public:
explicit StabilityAccumulator(float base_height) : StabilityAccumulator() = default;
base_height(base_height) {
}
void add_base_extrusion(const ExtrusionLine &line, float width, float print_z, float mm3_per_mm) { void add_base_extrusion(const ExtrusionLine &line, float sticking_force, float print_z, float mm3_per_mm) {
base_area += line.len * width; accumulated_sticking_force += sticking_force;
support_points.push_back(Point::new_scale(line.a)); support_points.push_back(Point::new_scale(line.a));
support_points.push_back(Point::new_scale(line.b)); support_points.push_back(Point::new_scale(line.b));
base_convex_hull.clear(); base_convex_hull.clear();
add_extrusion(line, print_z, mm3_per_mm); add_extrusion(line, print_z, mm3_per_mm);
} }
void add_support_point(const Point &position, float area) { void add_support_point(const Point &position, float sticking_force) {
support_points.push_back(position); support_points.push_back(position);
base_convex_hull.clear(); base_convex_hull.clear();
base_area += area; accumulated_sticking_force += sticking_force;
} }
void add_extrusion(const ExtrusionLine &line, float print_z, float mm3_per_mm) { void add_extrusion(const ExtrusionLine &line, float print_z, float mm3_per_mm) {
@ -156,12 +153,10 @@ public:
return centroid_accumulator / accumulated_volume; return centroid_accumulator / accumulated_volume;
} }
float get_base_area() const { float get_sticking_force() const {
return base_area; return accumulated_sticking_force;
}
float get_base_height() const {
return base_height;
} }
float get_accumulated_volume() const { float get_accumulated_volume() const {
return accumulated_volume; return accumulated_volume;
} }
@ -173,7 +168,7 @@ public:
return this->base_convex_hull; return this->base_convex_hull;
} }
const Points& get_support_points() { const Points& get_support_points() const {
return support_points; return support_points;
} }
@ -183,7 +178,7 @@ public:
base_convex_hull.clear(); base_convex_hull.clear();
this->centroid_accumulator += acc.centroid_accumulator; this->centroid_accumulator += acc.centroid_accumulator;
this->accumulated_volume += acc.accumulated_volume; this->accumulated_volume += acc.accumulated_volume;
this->base_area += acc.base_area; this->accumulated_sticking_force += acc.accumulated_sticking_force;
} }
}; };
@ -201,18 +196,18 @@ private:
} }
to_acc.add_from(from_acc); to_acc.add_from(from_acc);
mapping[from_id] = mapping[to_id]; mapping[from_id] = mapping[to_id];
from_acc = StabilityAccumulator { 0.0f }; from_acc = StabilityAccumulator { };
} }
public: public:
StabilityAccumulators() = default; StabilityAccumulators() = default;
int create_accumulator(float base_height) { int create_accumulator() {
size_t id = next_id; size_t id = next_id;
next_id++; next_id++;
mapping[id] = accumulators.size(); mapping[id] = accumulators.size();
accumulators.push_back(StabilityAccumulator { base_height }); accumulators.push_back(StabilityAccumulator { });
return id; return id;
} }
@ -231,7 +226,7 @@ public:
} }
to_acc.add_from(from_acc); to_acc.add_from(from_acc);
mapping[from_id] = mapping[to_id]; mapping[from_id] = mapping[to_id];
from_acc = StabilityAccumulator { 0.0f }; from_acc = StabilityAccumulator { };
} }
#ifdef DEBUG_FILES #ifdef DEBUG_FILES
@ -245,6 +240,18 @@ public:
size_t pseudornd = ((mapping[id] + 127) * 33331 + 6907) % 987; size_t pseudornd = ((mapping[id] + 127) * 33331 + 6907) % 987;
return value_to_rgbf(0.0f, float(987), float(pseudornd)); return value_to_rgbf(0.0f, float(987), float(pseudornd));
} }
void log_accumulators(){
for (size_t i = 0; i < accumulators.size(); ++i) {
const auto& acc = accumulators[i];
BOOST_LOG_TRIVIAL(debug)
<< "SSG: accumulator POS: " << i << "\n"
<< "SSG: get_accumulated_volume: " << acc.get_accumulated_volume() << "\n"
<< "SSG: get_sticking_force: " << acc.get_sticking_force() << "\n"
<< "SSG: support points count: " << acc.get_support_points().size() << "\n";
}
}
#endif #endif
}; };
@ -369,7 +376,7 @@ void check_extrusion_entity_stability(const ExtrusionEntity *entity,
} else { } else {
bridging_acc.add_distance(current_line.len); bridging_acc.add_distance(current_line.len);
if (current_stability_acc == NULL_ACC_ID) { if (current_stability_acc == NULL_ACC_ID) {
current_stability_acc = stability_accs.create_accumulator(print_z); current_stability_acc = stability_accs.create_accumulator();
} }
StabilityAccumulator &current_segment = stability_accs.access(current_stability_acc); StabilityAccumulator &current_segment = stability_accs.access(current_stability_acc);
current_line.stability_accumulator_id = current_stability_acc; current_line.stability_accumulator_id = current_stability_acc;
@ -379,7 +386,7 @@ void check_extrusion_entity_stability(const ExtrusionEntity *entity,
> params.bridge_distance > params.bridge_distance
/ (bridging_acc.max_curvature / (bridging_acc.max_curvature
* params.bridge_distance_decrease_by_curvature_factor / PI)) { * params.bridge_distance_decrease_by_curvature_factor / PI)) {
current_segment.add_support_point(current, 0.0f); // Do not count extrusion supports into the support area. They can be very densely placed, causing algorithm to overestimate stickiness. current_segment.add_support_point(current, 0.0f); // Do not count extrusion supports into the sticking force. They can be very densely placed, causing algorithm to overestimate stickiness.
issues.supports_nedded.emplace_back(to_vec3f(current), 1.0); issues.supports_nedded.emplace_back(to_vec3f(current), 1.0);
bridging_acc.reset(); bridging_acc.reset();
distance_from_last_support_point = 0.0f; distance_from_last_support_point = 0.0f;
@ -413,7 +420,8 @@ void check_layer_global_stability(StabilityAccumulators &stability_accs,
if (hull_lines.empty()) { if (hull_lines.empty()) {
if (acc->get_support_points().empty()) { if (acc->get_support_points().empty()) {
acc->add_support_point(Point::new_scale(checked_lines[accumulator.second[0]].a), acc->add_support_point(Point::new_scale(checked_lines[accumulator.second[0]].a),
params.support_points_interface_radius*params.support_points_interface_radius* float(PI) ); params.support_points_interface_radius * params.support_points_interface_radius * float(PI)
* params.support_adhesion);
issues.supports_nedded.emplace_back(to_3d(checked_lines[accumulator.second[0]].a, print_z), 1.0); issues.supports_nedded.emplace_back(to_3d(checked_lines[accumulator.second[0]].a, print_z), 1.0);
} }
hull_lines.push_back( { unscaled(acc->get_support_points()[0]).cast<float>(), hull_lines.push_back( { unscaled(acc->get_support_points()[0]).cast<float>(),
@ -423,8 +431,7 @@ void check_layer_global_stability(StabilityAccumulators &stability_accs,
LayerLinesDistancer hull_distancer(std::move(hull_lines)); LayerLinesDistancer hull_distancer(std::move(hull_lines));
float sticking_force = acc->get_base_area() float sticking_force = acc->get_sticking_force();
* (acc->get_base_height() == 0 ? params.base_adhesion : params.support_adhesion);
float mass = acc->get_accumulated_volume() * params.filament_density; float mass = acc->get_accumulated_volume() * params.filament_density;
float weight = mass * params.gravity_constant; float weight = mass * params.gravity_constant;
@ -435,7 +442,7 @@ void check_layer_global_stability(StabilityAccumulators &stability_accs,
Vec3f extruder_pressure_direction = to_3d(Vec2f(line.b - line.a), 0.0f).normalized(); Vec3f extruder_pressure_direction = to_3d(Vec2f(line.b - line.a), 0.0f).normalized();
Vec2f pivot_site_search = line.b + extruder_pressure_direction.head<2>() * 1000.0f; Vec2f pivot_site_search = line.b + extruder_pressure_direction.head<2>() * 1000.0f;
extruder_pressure_direction.z() = -0.1f; extruder_pressure_direction.z() = -0.3f;
extruder_pressure_direction.normalize(); extruder_pressure_direction.normalize();
size_t nearest_line_idx; size_t nearest_line_idx;
@ -448,7 +455,7 @@ void check_layer_global_stability(StabilityAccumulators &stability_accs,
float weight_arm = (pivot - centroid.head<2>()).norm(); float weight_arm = (pivot - centroid.head<2>()).norm();
float weight_torque = weight_arm * weight; float weight_torque = weight_arm * weight;
float bed_movement_arm = centroid.z() - acc->get_base_height(); float bed_movement_arm = centroid.z();
float bed_movement_force = params.max_acceleration * mass; float bed_movement_force = params.max_acceleration * mass;
float bed_movement_torque = bed_movement_force * bed_movement_arm; float bed_movement_torque = bed_movement_force * bed_movement_arm;
@ -460,13 +467,14 @@ void check_layer_global_stability(StabilityAccumulators &stability_accs,
if (total_torque > 0) { if (total_torque > 0) {
size_t _nearest_idx; size_t _nearest_idx;
Vec2f _nearest_pt; Vec2f _nearest_pt;
float area = params.support_points_interface_radius* params.support_points_interface_radius * float(PI); float area = params.support_points_interface_radius * params.support_points_interface_radius
* float(PI);
float dist_from_hull = hull_distancer.signed_distance_from_lines(line.b, _nearest_idx, _nearest_pt); float dist_from_hull = hull_distancer.signed_distance_from_lines(line.b, _nearest_idx, _nearest_pt);
if (dist_from_hull < params.support_points_interface_radius) { if (dist_from_hull < params.support_points_interface_radius) {
area = std::max(0.0f, dist_from_hull*params.support_points_interface_radius * float(PI)); area = std::max(0.0f, dist_from_hull * params.support_points_interface_radius * float(PI));
} }
float sticking_force = area * params.support_adhesion;
acc->add_support_point(Point::new_scale(line.b), area); acc->add_support_point(Point::new_scale(line.b), sticking_force);
issues.supports_nedded.emplace_back(to_3d(line.b, print_z), extruder_conflict_torque - sticking_torque); issues.supports_nedded.emplace_back(to_3d(line.b, print_z), extruder_conflict_torque - sticking_torque);
distance_from_last_support_point = 0.0f; distance_from_last_support_point = 0.0f;
} }
@ -513,7 +521,7 @@ Issues check_object_stability(const PrintObject *po, const Params &params) {
const float flow_width = get_flow_width(layer_region, perimeter->role()); const float flow_width = get_flow_width(layer_region, perimeter->role());
max_flow_width = std::max(flow_width, max_flow_width); max_flow_width = std::max(flow_width, max_flow_width);
const float mm3_per_mm = float(perimeter->min_mm3_per_mm()); const float mm3_per_mm = float(perimeter->min_mm3_per_mm());
int id = stability_accs.create_accumulator(base_print_z); int id = stability_accs.create_accumulator();
StabilityAccumulator &acc = stability_accs.access(id); StabilityAccumulator &acc = stability_accs.access(id);
Points points { }; Points points { };
perimeter->collect_points(points); perimeter->collect_points(points);
@ -522,7 +530,8 @@ Issues check_object_stability(const PrintObject *po, const Params &params) {
Vec2f next = unscaled(points[point_idx + 1]).cast<float>(); Vec2f next = unscaled(points[point_idx + 1]).cast<float>();
ExtrusionLine line { start, next }; ExtrusionLine line { start, next };
line.stability_accumulator_id = id; line.stability_accumulator_id = id;
acc.add_base_extrusion(line, flow_width, base_print_z, mm3_per_mm); float line_sticking_force = line.len * flow_width * params.base_adhesion;
acc.add_base_extrusion(line, line_sticking_force, base_print_z, mm3_per_mm);
checked_lines.push_back(line); checked_lines.push_back(line);
} }
if (perimeter->is_loop()) { if (perimeter->is_loop()) {
@ -530,7 +539,8 @@ Issues check_object_stability(const PrintObject *po, const Params &params) {
Vec2f next = unscaled(points[0]).cast<float>(); Vec2f next = unscaled(points[0]).cast<float>();
ExtrusionLine line { start, next }; ExtrusionLine line { start, next };
line.stability_accumulator_id = id; line.stability_accumulator_id = id;
acc.add_base_extrusion(line, flow_width, base_print_z, mm3_per_mm); float line_sticking_force = line.len * flow_width * params.base_adhesion;
acc.add_base_extrusion(line, line_sticking_force, base_print_z, mm3_per_mm);
checked_lines.push_back(line); checked_lines.push_back(line);
} }
} // perimeter } // perimeter
@ -540,7 +550,7 @@ Issues check_object_stability(const PrintObject *po, const Params &params) {
const float flow_width = get_flow_width(layer_region, fill->role()); const float flow_width = get_flow_width(layer_region, fill->role());
max_flow_width = std::max(flow_width, max_flow_width); max_flow_width = std::max(flow_width, max_flow_width);
const float mm3_per_mm = float(fill->min_mm3_per_mm()); const float mm3_per_mm = float(fill->min_mm3_per_mm());
int id = stability_accs.create_accumulator(base_print_z); int id = stability_accs.create_accumulator();
StabilityAccumulator &acc = stability_accs.access(id); StabilityAccumulator &acc = stability_accs.access(id);
Points points { }; Points points { };
fill->collect_points(points); fill->collect_points(points);
@ -549,27 +559,22 @@ Issues check_object_stability(const PrintObject *po, const Params &params) {
Vec2f next = unscaled(points[point_idx + 1]).cast<float>(); Vec2f next = unscaled(points[point_idx + 1]).cast<float>();
ExtrusionLine line { start, next }; ExtrusionLine line { start, next };
line.stability_accumulator_id = id; line.stability_accumulator_id = id;
acc.add_base_extrusion(line, flow_width, base_print_z, mm3_per_mm); float line_sticking_force = line.len * flow_width * params.base_adhesion;
acc.add_base_extrusion(line, line_sticking_force, base_print_z, mm3_per_mm);
checked_lines.push_back(line); checked_lines.push_back(line);
} }
} // fill } // fill
} // ex_entity } // ex_entity
} // region } // region
#ifdef DEBUG_FILES
for (const auto &line : checked_lines) {
Vec3f color = stability_accs.get_accumulator_color(line.stability_accumulator_id);
fprintf(debug_acc, "v %f %f %f %f %f %f\n", line.b[0],
line.b[1], base_print_z, color[0], color[1], color[2]);
}
#endif
//MERGE BASE LAYER STABILITY ACCS //MERGE BASE LAYER STABILITY ACCS
prev_layer_lines = LayerLinesDistancer { std::move(checked_lines) }; prev_layer_lines = LayerLinesDistancer { std::move(checked_lines) };
for (const ExtrusionLine &l : prev_layer_lines.get_lines()) { for (const ExtrusionLine &l : prev_layer_lines.get_lines()) {
size_t nearest_line_idx; size_t nearest_line_idx;
Vec2f nearest_pt; Vec2f nearest_pt;
float dist = prev_layer_lines.signed_distance_from_lines(l.a, nearest_line_idx, nearest_pt); Vec2f line_dir = (l.b - l.a).normalized();
Vec2f site_search_location = l.a + Vec2f(line_dir.y(), -line_dir.x()) * max_flow_width;
float dist = prev_layer_lines.signed_distance_from_lines(site_search_location, nearest_line_idx, nearest_pt);
if (std::abs(dist) < max_flow_width) { if (std::abs(dist) < max_flow_width) {
size_t other_line_acc_id = prev_layer_lines.get_line(nearest_line_idx).stability_accumulator_id; size_t other_line_acc_id = prev_layer_lines.get_line(nearest_line_idx).stability_accumulator_id;
size_t from_id = std::max(other_line_acc_id, l.stability_accumulator_id); size_t from_id = std::max(other_line_acc_id, l.stability_accumulator_id);
@ -578,6 +583,16 @@ Issues check_object_stability(const PrintObject *po, const Params &params) {
} }
} }
#ifdef DEBUG_FILES
for (const auto &line : prev_layer_lines.get_lines()) {
Vec3f color = stability_accs.get_accumulator_color(line.stability_accumulator_id);
fprintf(debug_acc, "v %f %f %f %f %f %f\n", line.b[0],
line.b[1], base_print_z, color[0], color[1], color[2]);
}
stability_accs.log_accumulators();
#endif
//CHECK STABILITY OF ALL LAYERS //CHECK STABILITY OF ALL LAYERS
for (size_t layer_idx = 1; layer_idx < po->layer_count(); ++layer_idx) { for (size_t layer_idx = 1; layer_idx < po->layer_count(); ++layer_idx) {
const Layer *layer = po->layers()[layer_idx]; const Layer *layer = po->layers()[layer_idx];
@ -656,6 +671,7 @@ Issues check_object_stability(const PrintObject *po, const Params &params) {
fprintf(debug_acc, "v %f %f %f %f %f %f\n", line.b[0], fprintf(debug_acc, "v %f %f %f %f %f %f\n", line.b[0],
line.b[1], print_z, color[0], color[1], color[2]); line.b[1], print_z, color[0], color[1], color[2]);
} }
stability_accs.log_accumulators();
#endif #endif
} }

View File

@ -10,7 +10,7 @@ namespace SupportSpotsGenerator {
struct Params { struct Params {
const float gravity_constant = 9806.65f; // mm/s^2; gravity acceleration on Earth's surface, algorithm assumes that printer is in upwards position. const float gravity_constant = 9806.65f; // mm/s^2; gravity acceleration on Earth's surface, algorithm assumes that printer is in upwards position.
float bridge_distance = 15.0f; //mm float bridge_distance = 10.0f; //mm
float bridge_distance_decrease_by_curvature_factor = 5.0f; // >0 REQUIRED; allowed bridge distance = bridge_distance / (this factor * (curvature / PI) ) float bridge_distance_decrease_by_curvature_factor = 5.0f; // >0 REQUIRED; allowed bridge distance = bridge_distance / (this factor * (curvature / PI) )
float min_distance_between_support_points = 0.5f; float min_distance_between_support_points = 0.5f;
@ -24,8 +24,8 @@ struct Params {
float max_acceleration = 1000.0f; // mm/s^2 ; max acceleration of object (bed) in XY float max_acceleration = 1000.0f; // mm/s^2 ; max acceleration of object (bed) in XY
float filament_density = 1.25f * 0.001f; // g/mm^3 ; Common filaments are very lightweight, so precise number is not that important float filament_density = 1.25f * 0.001f; // g/mm^3 ; Common filaments are very lightweight, so precise number is not that important
float tolerable_extruder_conflict_force = 50.0f * gravity_constant; // force that can occasionally push the model due to various factors (filament leaks, small curling, ... ); current value corresponds to weight of 50g float tolerable_extruder_conflict_force = 50.0f * gravity_constant; // force that can occasionally push the model due to various factors (filament leaks, small curling, ... ); current value corresponds to weight of X grams
float max_curled_conflict_extruder_force = 200.0f * gravity_constant; // for areas with possible high layered curled filaments, max force to account for; current value corresponds to weight of 200g float max_curled_conflict_extruder_force = 300.0f * gravity_constant; // for areas with possible high layered curled filaments, max force to account for;
}; };
struct SupportPoint { struct SupportPoint {