bug fixes, raycasting to find good support spot
This commit is contained in:
parent
bef26fee2b
commit
8dc3956b64
@ -423,27 +423,29 @@ void PrintObject::find_supportable_issues()
|
||||
SupportableIssues::Issues issues = SupportableIssues::full_search(this);
|
||||
//TODO fix
|
||||
// if (!issues.supports_nedded.empty()) {
|
||||
auto obj_transform = this->trafo_centered();
|
||||
for (ModelVolume *model_volume : this->model_object()->volumes) {
|
||||
if (model_volume->type() == ModelVolumeType::MODEL_PART) {
|
||||
Transform3d model_transformation = model_volume->get_matrix();
|
||||
Transform3d inv_transform = (obj_transform * model_transformation).inverse();
|
||||
TriangleSelectorWrapper selector { model_volume->mesh() };
|
||||
auto obj_transform = this->trafo_centered();
|
||||
for (ModelVolume *model_volume : this->model_object()->volumes) {
|
||||
if (model_volume->type() == ModelVolumeType::MODEL_PART) {
|
||||
Transform3d model_transformation = model_volume->get_matrix();
|
||||
Transform3f inv_transform = (obj_transform * model_transformation).inverse().cast<float>();
|
||||
TriangleSelectorWrapper selector { model_volume->mesh() };
|
||||
|
||||
for (const SupportableIssues::SupportPoint &support_point : issues.supports_nedded) {
|
||||
selector.enforce_spot(Vec3f(inv_transform.cast<float>() * support_point.position), 0.5f);
|
||||
}
|
||||
|
||||
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
|
||||
for (const SupportableIssues::SupportPoint &support_point : issues.supports_nedded) {
|
||||
Vec3f point = Vec3f(inv_transform * support_point.position);
|
||||
Vec3f origin = Vec3f(
|
||||
inv_transform * Vec3f(support_point.position.x(), support_point.position.y(), 0.0f));
|
||||
selector.enforce_spot(point, origin, 0.5f);
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
// }
|
||||
}
|
||||
|
||||
|
@ -191,7 +191,7 @@ struct StabilityAccumulators {
|
||||
private:
|
||||
size_t next_id = 0;
|
||||
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) {
|
||||
StabilityAccumulator &from_acc = this->access(from_id);
|
||||
@ -211,13 +211,13 @@ public:
|
||||
int create_accumulator(float base_height) {
|
||||
size_t id = next_id;
|
||||
next_id++;
|
||||
mapping[id] = acccumulators.size();
|
||||
acccumulators.push_back(StabilityAccumulator { base_height });
|
||||
mapping[id] = accumulators.size();
|
||||
accumulators.push_back(StabilityAccumulator { base_height });
|
||||
return 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) {
|
||||
@ -235,24 +235,14 @@ public:
|
||||
}
|
||||
|
||||
#ifdef DEBUG_FILES
|
||||
Vec3f get_emerging_color(size_t id) {
|
||||
Vec3f get_accumulator_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 = ((id + 127) * 33331 + 6907) % 13;
|
||||
return value_to_rgbf(0.0f, 13.0f, 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));
|
||||
size_t pseudornd = ((mapping[id] + 127) * 33331 + 6907) % 987;
|
||||
return value_to_rgbf(0.0f, float(987), float(pseudornd));
|
||||
}
|
||||
#endif
|
||||
};
|
||||
@ -345,10 +335,12 @@ void check_extrusion_entity_stability(const ExtrusionEntity *entity,
|
||||
// -> it prevents extruding perimeter start and short loops into air.
|
||||
const float flow_width = get_flow_width(layer_region, entity->role());
|
||||
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) {
|
||||
ExtrusionLine ¤t_line = lines[line_idx];
|
||||
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 curr_angle = 0;
|
||||
@ -381,13 +373,15 @@ void check_extrusion_entity_stability(const ExtrusionEntity *entity,
|
||||
StabilityAccumulator ¤t_segment = stability_accs.access(current_stability_acc);
|
||||
current_line.stability_accumulator_id = current_stability_acc;
|
||||
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.
|
||||
> params.bridge_distance
|
||||
/ (1.0f + (bridging_acc.max_curvature
|
||||
* params.bridge_distance_decrease_by_curvature_factor / PI))) {
|
||||
current_segment.add_support_point(current, params.support_points_interface_area);
|
||||
if (distance_from_last_support_point > params.min_distance_between_support_points &&
|
||||
bridging_acc.distance // if unsupported distance is larger than bridge distance linearly decreased by curvature, enforce supports.
|
||||
> params.bridge_distance
|
||||
/ (1.0f + (bridging_acc.max_curvature
|
||||
* 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);
|
||||
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()
|
||||
* (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) {
|
||||
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();
|
||||
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;
|
||||
|
||||
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;
|
||||
|
||||
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;
|
||||
|
||||
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);
|
||||
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 ¶ms) {
|
||||
#ifdef DEBUG_FILES
|
||||
FILE *eacc = boost::nowide::fopen(debug_out_path("emerging_accumulators.obj").c_str(), "w");
|
||||
FILE *facc = boost::nowide::fopen(debug_out_path("final_accumulators.obj").c_str(), "w");
|
||||
FILE *debug_acc = boost::nowide::fopen(debug_out_path("accumulators.obj").c_str(), "w");
|
||||
#endif
|
||||
StabilityAccumulators stability_accs;
|
||||
LayerLinesDistancer prev_layer_lines { { } };
|
||||
@ -548,15 +545,11 @@ Issues check_object_stability(const PrintObject *po, const Params ¶ms) {
|
||||
|
||||
#ifdef DEBUG_FILES
|
||||
for (const auto &line : checked_lines) {
|
||||
Vec3f ecolor = stability_accs.get_emerging_color(line.stability_accumulator_id);
|
||||
fprintf(eacc, "v %f %f %f %f %f %f\n", line.b[0],
|
||||
line.b[1], base_print_z, ecolor[0], ecolor[1], ecolor[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]);
|
||||
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 DEBUG_FILES
|
||||
#endif
|
||||
|
||||
//MERGE BASE LAYER STABILITY ACCS
|
||||
prev_layer_lines = LayerLinesDistancer { std::move(checked_lines) };
|
||||
@ -564,7 +557,7 @@ Issues check_object_stability(const PrintObject *po, const Params ¶ms) {
|
||||
size_t nearest_line_idx;
|
||||
Vec2f 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 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);
|
||||
@ -646,20 +639,15 @@ Issues check_object_stability(const PrintObject *po, const Params ¶ms) {
|
||||
|
||||
#ifdef DEBUG_FILES
|
||||
for (const auto &line : prev_layer_lines.get_lines()) {
|
||||
Vec3f ecolor = stability_accs.get_emerging_color(line.stability_accumulator_id);
|
||||
fprintf(eacc, "v %f %f %f %f %f %f\n", line.b[0],
|
||||
line.b[1], print_z, ecolor[0], ecolor[1], ecolor[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]);
|
||||
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], print_z, color[0], color[1], color[2]);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef DEBUG_FILES
|
||||
fclose(eacc);
|
||||
fclose(facc);
|
||||
fclose(debug_acc);
|
||||
#endif
|
||||
|
||||
std::cout << " SUPP: " << issues.supports_nedded.size() << std::endl;
|
||||
|
@ -10,14 +10,18 @@ namespace SupportableIssues {
|
||||
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.
|
||||
|
||||
|
||||
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 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
|
||||
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_points_interface_area = 2.0f; // mm^2
|
||||
float support_adhesion = 3.0f * gravity_constant; // adhesion per mm^2 of support interface layer
|
||||
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 filament_density = 1.25f * 0.001f; // g/mm^3 ; Common filaments are very lightweight, so precise number is not that important
|
||||
|
||||
|
@ -10,22 +10,26 @@ TriangleSelectorWrapper::TriangleSelectorWrapper(const TriangleMesh &mesh) :
|
||||
|
||||
}
|
||||
|
||||
void TriangleSelectorWrapper::enforce_spot(const Vec3f &point, float radius) {
|
||||
size_t hit_face_index;
|
||||
Vec3f hit_point;
|
||||
auto dist = AABBTreeIndirect::squared_distance_to_indexed_triangle_set(mesh.its.vertices, mesh.its.indices,
|
||||
triangles_tree,
|
||||
point, hit_face_index, hit_point);
|
||||
if (dist < 0 || dist > radius * radius) {
|
||||
return;
|
||||
void TriangleSelectorWrapper::enforce_spot(const Vec3f &point, const Vec3f &origin, float radius) {
|
||||
std::vector<igl::Hit> hits;
|
||||
Vec3f dir = (point - origin).normalized();
|
||||
if (AABBTreeIndirect::intersect_ray_all_hits(mesh.its.vertices, mesh.its.indices, triangles_tree,
|
||||
Vec3d(origin.cast<double>()),
|
||||
Vec3d(dir.cast<double>()),
|
||||
hits)) {
|
||||
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);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -20,7 +20,7 @@ public:
|
||||
|
||||
TriangleSelectorWrapper(const TriangleMesh &mesh);
|
||||
|
||||
void enforce_spot(const Vec3f &point, float radius);
|
||||
void enforce_spot(const Vec3f &point, const Vec3f& origin, float radius);
|
||||
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user