bug fixes, raycasting to find good support spot

This commit is contained in:
PavelMikus 2022-06-21 16:04:29 +02:00
parent bef26fee2b
commit 8dc3956b64
5 changed files with 80 additions and 82 deletions

View File

@ -423,27 +423,29 @@ void PrintObject::find_supportable_issues()
SupportableIssues::Issues issues = SupportableIssues::full_search(this); SupportableIssues::Issues issues = SupportableIssues::full_search(this);
//TODO fix //TODO fix
// if (!issues.supports_nedded.empty()) { // if (!issues.supports_nedded.empty()) {
auto obj_transform = this->trafo_centered(); auto obj_transform = this->trafo_centered();
for (ModelVolume *model_volume : this->model_object()->volumes) { for (ModelVolume *model_volume : this->model_object()->volumes) {
if (model_volume->type() == ModelVolumeType::MODEL_PART) { if (model_volume->type() == ModelVolumeType::MODEL_PART) {
Transform3d model_transformation = model_volume->get_matrix(); Transform3d model_transformation = model_volume->get_matrix();
Transform3d inv_transform = (obj_transform * model_transformation).inverse(); Transform3f inv_transform = (obj_transform * model_transformation).inverse().cast<float>();
TriangleSelectorWrapper selector { model_volume->mesh() }; TriangleSelectorWrapper selector { model_volume->mesh() };
for (const SupportableIssues::SupportPoint &support_point : issues.supports_nedded) { for (const SupportableIssues::SupportPoint &support_point : issues.supports_nedded) {
selector.enforce_spot(Vec3f(inv_transform.cast<float>() * support_point.position), 0.5f); Vec3f point = Vec3f(inv_transform * support_point.position);
} Vec3f origin = Vec3f(
inv_transform * Vec3f(support_point.position.x(), support_point.position.y(), 0.0f));
model_volume->supported_facets.set(selector.selector); selector.enforce_spot(point, origin, 0.5f);
#if 1
indexed_triangle_set copy = model_volume->mesh().its;
its_transform(copy, obj_transform * model_transformation);
its_write_obj(copy,
debug_out_path("model.obj").c_str());
#endif
} }
model_volume->supported_facets.set(selector.selector);
#if 1
indexed_triangle_set copy = model_volume->mesh().its;
its_transform(copy, obj_transform * model_transformation);
its_write_obj(copy,
debug_out_path("model.obj").c_str());
#endif
} }
}
// } // }
} }

View File

@ -191,7 +191,7 @@ struct StabilityAccumulators {
private: private:
size_t next_id = 0; size_t next_id = 0;
std::unordered_map<size_t, size_t> mapping; std::unordered_map<size_t, size_t> mapping;
std::vector<StabilityAccumulator> acccumulators; std::vector<StabilityAccumulator> accumulators;
void merge_to(size_t from_id, size_t to_id) { void merge_to(size_t from_id, size_t to_id) {
StabilityAccumulator &from_acc = this->access(from_id); StabilityAccumulator &from_acc = this->access(from_id);
@ -211,13 +211,13 @@ public:
int create_accumulator(float base_height) { int create_accumulator(float base_height) {
size_t id = next_id; size_t id = next_id;
next_id++; next_id++;
mapping[id] = acccumulators.size(); mapping[id] = accumulators.size();
acccumulators.push_back(StabilityAccumulator { base_height }); accumulators.push_back(StabilityAccumulator { base_height });
return id; return id;
} }
StabilityAccumulator& access(size_t id) { StabilityAccumulator& access(size_t id) {
return acccumulators[mapping[id]]; return accumulators[mapping[id]];
} }
void merge_accumulators(size_t from_id, size_t to_id) { void merge_accumulators(size_t from_id, size_t to_id) {
@ -235,24 +235,14 @@ public:
} }
#ifdef DEBUG_FILES #ifdef DEBUG_FILES
Vec3f get_emerging_color(size_t id) { Vec3f get_accumulator_color(size_t id) {
if (mapping.find(id) == mapping.end()) { if (mapping.find(id) == mapping.end()) {
std::cerr << " ERROR: uknown accumulator ID: " << id << std::endl; std::cerr << " ERROR: uknown accumulator ID: " << id << std::endl;
return Vec3f(1.0f, 1.0f, 1.0f); return Vec3f(1.0f, 1.0f, 1.0f);
} }
size_t pseudornd = ((id + 127) * 33331 + 6907) % 13; size_t pseudornd = ((mapping[id] + 127) * 33331 + 6907) % 987;
return value_to_rgbf(0.0f, 13.0f, float(pseudornd)); return value_to_rgbf(0.0f, float(987), float(pseudornd));
}
Vec3f get_final_color(size_t id) {
if (mapping.find(id) == mapping.end()) {
std::cerr << " ERROR: uknown accumulator ID: " << id << std::endl;
return Vec3f(1.0f, 1.0f, 1.0f);
}
size_t pseudornd = ((mapping[id] + 127) * 33331 + 6907) % 13;
return value_to_rgbf(0.0f, 13.0f, float(pseudornd));
} }
#endif #endif
}; };
@ -345,10 +335,12 @@ void check_extrusion_entity_stability(const ExtrusionEntity *entity,
// -> it prevents extruding perimeter start and short loops into air. // -> it prevents extruding perimeter start and short loops into air.
const float flow_width = get_flow_width(layer_region, entity->role()); const float flow_width = get_flow_width(layer_region, entity->role());
const float max_allowed_dist_from_prev_layer = flow_width; const float max_allowed_dist_from_prev_layer = flow_width;
float distance_from_last_support_point = params.min_distance_between_support_points * 2.0f;
for (size_t line_idx = 0; line_idx < lines.size(); ++line_idx) { for (size_t line_idx = 0; line_idx < lines.size(); ++line_idx) {
ExtrusionLine &current_line = lines[line_idx]; ExtrusionLine &current_line = lines[line_idx];
Point current = Point::new_scale(current_line.b); Point current = Point::new_scale(current_line.b);
distance_from_last_support_point += current_line.len;
float mm3_per_mm = float(entity->min_mm3_per_mm()); float mm3_per_mm = float(entity->min_mm3_per_mm());
float curr_angle = 0; float curr_angle = 0;
@ -381,13 +373,15 @@ void check_extrusion_entity_stability(const ExtrusionEntity *entity,
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;
current_segment.add_extrusion(current_line, print_z, mm3_per_mm); current_segment.add_extrusion(current_line, print_z, mm3_per_mm);
if (bridging_acc.distance // if unsupported distance is larger than bridge distance linearly decreased by curvature, enforce supports. if (distance_from_last_support_point > params.min_distance_between_support_points &&
> params.bridge_distance bridging_acc.distance // if unsupported distance is larger than bridge distance linearly decreased by curvature, enforce supports.
/ (1.0f + (bridging_acc.max_curvature > params.bridge_distance
* params.bridge_distance_decrease_by_curvature_factor / PI))) { / (1.0f + (bridging_acc.max_curvature
current_segment.add_support_point(current, params.support_points_interface_area); * params.bridge_distance_decrease_by_curvature_factor / PI))) {
current_segment.add_support_point(current, params.extrusion_support_points_area);
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;
} }
} }
} }
@ -430,10 +424,13 @@ void check_layer_global_stability(StabilityAccumulators &stability_accs,
float sticking_force = acc->get_base_area() float sticking_force = acc->get_base_area()
* (acc->get_base_height() == 0 ? params.base_adhesion : params.support_adhesion); * (acc->get_base_height() == 0 ? params.base_adhesion : params.support_adhesion);
float weight = acc->get_accumulated_volume() * params.filament_density * params.gravity_constant; float mass = acc->get_accumulated_volume() * params.filament_density;
float weight = mass * params.gravity_constant;
float distance_from_last_support_point = params.min_distance_between_support_points * 2.0f;
for (size_t line_idx : acc_lines.second) { for (size_t line_idx : acc_lines.second) {
const ExtrusionLine &line = checked_lines[line_idx]; const ExtrusionLine &line = checked_lines[line_idx];
distance_from_last_support_point += line.len;
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;
@ -457,7 +454,7 @@ void check_layer_global_stability(StabilityAccumulators &stability_accs,
std::cout << "weight_torque: " << weight_torque << std::endl; std::cout << "weight_torque: " << weight_torque << std::endl;
float bed_movement_arm = centroid.z() - acc->get_base_height(); float bed_movement_arm = centroid.z() - acc->get_base_height();
float bed_movement_force = params.max_acceleration * weight; 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;
std::cout << "bed_movement_arm: " << bed_movement_arm << std::endl; std::cout << "bed_movement_arm: " << bed_movement_arm << std::endl;
@ -475,8 +472,9 @@ void check_layer_global_stability(StabilityAccumulators &stability_accs,
std::cout << "total_torque: " << total_torque << " printz: " << print_z << std::endl; std::cout << "total_torque: " << total_torque << " printz: " << print_z << std::endl;
if (total_torque > 0) { if (total_torque > 0) {
acc->add_support_point(Point::new_scale(line.b), params.support_points_interface_area); acc->add_support_point(Point::new_scale(line.b), std::min(params.support_points_interface_area, (pivot - line.b).squaredNorm()));
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;
} }
} }
@ -485,8 +483,7 @@ void check_layer_global_stability(StabilityAccumulators &stability_accs,
Issues check_object_stability(const PrintObject *po, const Params &params) { Issues check_object_stability(const PrintObject *po, const Params &params) {
#ifdef DEBUG_FILES #ifdef DEBUG_FILES
FILE *eacc = boost::nowide::fopen(debug_out_path("emerging_accumulators.obj").c_str(), "w"); FILE *debug_acc = boost::nowide::fopen(debug_out_path("accumulators.obj").c_str(), "w");
FILE *facc = boost::nowide::fopen(debug_out_path("final_accumulators.obj").c_str(), "w");
#endif #endif
StabilityAccumulators stability_accs; StabilityAccumulators stability_accs;
LayerLinesDistancer prev_layer_lines { { } }; LayerLinesDistancer prev_layer_lines { { } };
@ -548,15 +545,11 @@ Issues check_object_stability(const PrintObject *po, const Params &params) {
#ifdef DEBUG_FILES #ifdef DEBUG_FILES
for (const auto &line : checked_lines) { for (const auto &line : checked_lines) {
Vec3f ecolor = stability_accs.get_emerging_color(line.stability_accumulator_id); Vec3f color = stability_accs.get_accumulator_color(line.stability_accumulator_id);
fprintf(eacc, "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], base_print_z, ecolor[0], ecolor[1], ecolor[2]); line.b[1], base_print_z, color[0], color[1], color[2]);
Vec3f fcolor = stability_accs.get_final_color(line.stability_accumulator_id);
fprintf(facc, "v %f %f %f %f %f %f\n", line.b[0],
line.b[1], base_print_z, fcolor[0], fcolor[1], fcolor[2]);
} }
#endif DEBUG_FILES #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) };
@ -564,7 +557,7 @@ Issues check_object_stability(const PrintObject *po, const Params &params) {
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); float dist = prev_layer_lines.signed_distance_from_lines(l.a, nearest_line_idx, nearest_pt);
if (std::abs(dist) < max_flow_width) { if (std::abs(dist) < max_flow_width*1.1f) {
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);
size_t to_id = std::min(other_line_acc_id, l.stability_accumulator_id); size_t to_id = std::min(other_line_acc_id, l.stability_accumulator_id);
@ -646,20 +639,15 @@ Issues check_object_stability(const PrintObject *po, const Params &params) {
#ifdef DEBUG_FILES #ifdef DEBUG_FILES
for (const auto &line : prev_layer_lines.get_lines()) { for (const auto &line : prev_layer_lines.get_lines()) {
Vec3f ecolor = stability_accs.get_emerging_color(line.stability_accumulator_id); Vec3f color = stability_accs.get_accumulator_color(line.stability_accumulator_id);
fprintf(eacc, "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, ecolor[0], ecolor[1], ecolor[2]); line.b[1], print_z, color[0], color[1], color[2]);
Vec3f fcolor = stability_accs.get_final_color(line.stability_accumulator_id);
fprintf(facc, "v %f %f %f %f %f %f\n", line.b[0],
line.b[1], print_z, fcolor[0], fcolor[1], fcolor[2]);
} }
#endif #endif
} }
#ifdef DEBUG_FILES #ifdef DEBUG_FILES
fclose(eacc); fclose(debug_acc);
fclose(facc);
#endif #endif
std::cout << " SUPP: " << issues.supports_nedded.size() << std::endl; std::cout << " SUPP: " << issues.supports_nedded.size() << std::endl;

View File

@ -10,14 +10,18 @@ namespace SupportableIssues {
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 = 10.0f; //mm float bridge_distance = 10.0f; //mm
float bridge_distance_decrease_by_curvature_factor = 5.0f; // allowed bridge distance = bridge_distance / ( 1 + this factor * (curvature / PI) ) float bridge_distance_decrease_by_curvature_factor = 5.0f; // allowed bridge distance = bridge_distance / ( 1 + this factor * (curvature / PI) )
float min_distance_between_support_points = 0.5f;
// Adhesion computation : from experiment, PLA holds about 3g per mm^2 of base area (with reserve); So it can withstand about 3*gravity_constant force per mm^2 // Adhesion computation : from experiment, PLA holds about 3g per mm^2 of base area (with reserve); So it can withstand about 3*gravity_constant force per mm^2
float base_adhesion = 3.0f * gravity_constant; // adhesion per mm^2 of first layer float base_adhesion = 3.0f * gravity_constant; // adhesion per mm^2 of first layer
float support_adhesion = 1.0f * gravity_constant; // adhesion per mm^2 of support interface layer float support_adhesion = 3.0f * gravity_constant; // adhesion per mm^2 of support interface layer
float support_points_interface_area = 2.0f; // mm^2 float support_points_interface_area = 5.0f; // mm^2
float extrusion_support_points_area = 0.5f; // much lower value, because these support points appear due to unsupported extrusion,
// not stability - they can be very densely placed, making the sticking estimation incorrect
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

View File

@ -10,22 +10,26 @@ TriangleSelectorWrapper::TriangleSelectorWrapper(const TriangleMesh &mesh) :
} }
void TriangleSelectorWrapper::enforce_spot(const Vec3f &point, float radius) { void TriangleSelectorWrapper::enforce_spot(const Vec3f &point, const Vec3f &origin, float radius) {
size_t hit_face_index; std::vector<igl::Hit> hits;
Vec3f hit_point; Vec3f dir = (point - origin).normalized();
auto dist = AABBTreeIndirect::squared_distance_to_indexed_triangle_set(mesh.its.vertices, mesh.its.indices, if (AABBTreeIndirect::intersect_ray_all_hits(mesh.its.vertices, mesh.its.indices, triangles_tree,
triangles_tree, Vec3d(origin.cast<double>()),
point, hit_face_index, hit_point); Vec3d(dir.cast<double>()),
if (dist < 0 || dist > radius * radius) { hits)) {
return; for (int hit_idx = hits.size() - 1; hit_idx >= 0; --hit_idx) {
const igl::Hit &hit = hits[hit_idx];
Vec3f pos = origin + dir * hit.t;
Vec3f face_normal = its_face_normal(mesh.its, hit.id);
if (point.z() + radius > pos.z() && face_normal.dot(dir) < 0) {
std::unique_ptr<TriangleSelector::Cursor> cursor = std::make_unique<TriangleSelector::Sphere>(
pos, origin, radius, Transform3d::Identity(), TriangleSelector::ClippingPlane { });
selector.select_patch(hit.id, std::move(cursor), EnforcerBlockerType::ENFORCER, Transform3d::Identity(),
true, 0.0f);
break;
}
}
} }
std::unique_ptr<TriangleSelector::Cursor> cursor = std::make_unique<TriangleSelector::Sphere>(hit_point, point,
radius, Transform3d::Identity(), TriangleSelector::ClippingPlane { });
selector.select_patch(hit_face_index, std::move(cursor), EnforcerBlockerType::ENFORCER, Transform3d::Identity(),
true,
0.0f);
} }
} }

View File

@ -20,7 +20,7 @@ public:
TriangleSelectorWrapper(const TriangleMesh &mesh); TriangleSelectorWrapper(const TriangleMesh &mesh);
void enforce_spot(const Vec3f &point, float radius); void enforce_spot(const Vec3f &point, const Vec3f& origin, float radius);
}; };