use Polyline instead of Points, so that there are no duplicate points
This commit is contained in:
parent
52a7703447
commit
8a1a31992a
2 changed files with 58 additions and 59 deletions
|
@ -1,5 +1,6 @@
|
||||||
#include "SupportSpotsGenerator.hpp"
|
#include "SupportSpotsGenerator.hpp"
|
||||||
|
|
||||||
|
#include "ExtrusionEntity.hpp"
|
||||||
#include "tbb/parallel_for.h"
|
#include "tbb/parallel_for.h"
|
||||||
#include "tbb/blocked_range.h"
|
#include "tbb/blocked_range.h"
|
||||||
#include "tbb/blocked_range2d.h"
|
#include "tbb/blocked_range2d.h"
|
||||||
|
@ -346,6 +347,41 @@ float gauss(float value, float mean_x_coord, float mean_value, float falloff_spe
|
||||||
return mean_value * (std::exp(exponent) - 1.0f) / (std::exp(1.0f) - 1.0f);
|
return mean_value * (std::exp(exponent) - 1.0f) / (std::exp(1.0f) - 1.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void push_lines(const ExtrusionEntity *e, std::vector<ExtrusionLine>& destination)
|
||||||
|
{
|
||||||
|
assert(!e->is_collection());
|
||||||
|
Polyline pl = e->as_polyline();
|
||||||
|
for (int point_idx = 0; point_idx < int(pl.points.size() - 1); ++point_idx) {
|
||||||
|
Vec2f start = unscaled(pl.points[point_idx]).cast<float>();
|
||||||
|
Vec2f next = unscaled(pl.points[point_idx + 1]).cast<float>();
|
||||||
|
ExtrusionLine line{start, next, e};
|
||||||
|
destination.push_back(line);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<ExtrusionLine> to_short_lines(const ExtrusionEntity *e, float length_limit)
|
||||||
|
{
|
||||||
|
assert(!e->is_collection());
|
||||||
|
Polyline pl = e->as_polyline();
|
||||||
|
std::vector<ExtrusionLine> lines;
|
||||||
|
lines.reserve(pl.points.size() * 1.5f);
|
||||||
|
for (int point_idx = 0; point_idx < int(pl.points.size() - 1); ++point_idx) {
|
||||||
|
Vec2f start = unscaled(pl.points[point_idx]).cast<float>();
|
||||||
|
Vec2f next = unscaled(pl.points[point_idx + 1]).cast<float>();
|
||||||
|
Vec2f v = next - start; // vector from next to current
|
||||||
|
float dist_to_next = v.norm();
|
||||||
|
v.normalize();
|
||||||
|
int lines_count = int(std::ceil(dist_to_next / length_limit));
|
||||||
|
float step_size = dist_to_next / lines_count;
|
||||||
|
for (int i = 0; i < lines_count; ++i) {
|
||||||
|
Vec2f a(start + v * (i * step_size));
|
||||||
|
Vec2f b(start + v * ((i + 1) * step_size));
|
||||||
|
lines.emplace_back(a, b, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return lines;
|
||||||
|
}
|
||||||
|
|
||||||
void check_extrusion_entity_stability(const ExtrusionEntity *entity,
|
void check_extrusion_entity_stability(const ExtrusionEntity *entity,
|
||||||
std::vector<ExtrusionLine> &checked_lines_out,
|
std::vector<ExtrusionLine> &checked_lines_out,
|
||||||
float layer_z,
|
float layer_z,
|
||||||
|
@ -371,23 +407,8 @@ void check_extrusion_entity_stability(const ExtrusionEntity *entity,
|
||||||
|
|
||||||
Points points { };
|
Points points { };
|
||||||
entity->collect_points(points);
|
entity->collect_points(points);
|
||||||
std::vector<ExtrusionLine> lines;
|
std::vector<ExtrusionLine> lines = to_short_lines(entity, params.bridge_distance);
|
||||||
lines.reserve(points.size() * 1.5f);
|
if (lines.empty()) return;
|
||||||
lines.emplace_back(unscaled(points[0]).cast<float>(), unscaled(points[0]).cast<float>(), entity);
|
|
||||||
for (int point_idx = 0; point_idx < int(points.size() - 1); ++point_idx) {
|
|
||||||
Vec2f start = unscaled(points[point_idx]).cast<float>();
|
|
||||||
Vec2f next = unscaled(points[point_idx + 1]).cast<float>();
|
|
||||||
Vec2f v = next - start; // vector from next to current
|
|
||||||
float dist_to_next = v.norm();
|
|
||||||
v.normalize();
|
|
||||||
int lines_count = int(std::ceil(dist_to_next / params.bridge_distance));
|
|
||||||
float step_size = dist_to_next / lines_count;
|
|
||||||
for (int i = 0; i < lines_count; ++i) {
|
|
||||||
Vec2f a(start + v * (i * step_size));
|
|
||||||
Vec2f b(start + v * ((i + 1) * step_size));
|
|
||||||
lines.emplace_back(a, b, entity);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (entity->total_volume() < params.supportable_volume_threshold) {
|
if (entity->total_volume() < params.supportable_volume_threshold) {
|
||||||
checked_lines_out.insert(checked_lines_out.end(), lines.begin(), lines.end());
|
checked_lines_out.insert(checked_lines_out.end(), lines.begin(), lines.end());
|
||||||
|
@ -440,11 +461,9 @@ void check_extrusion_entity_stability(const ExtrusionEntity *entity,
|
||||||
}
|
}
|
||||||
if (dist_from_prev_layer > min_malformation_dist && dist_from_prev_layer < max_malformation_dist) {
|
if (dist_from_prev_layer > min_malformation_dist && dist_from_prev_layer < max_malformation_dist) {
|
||||||
malformation_acc.add_distance(current_line.len);
|
malformation_acc.add_distance(current_line.len);
|
||||||
current_line.malformation += layer_region->layer()->height
|
current_line.malformation += layer_region->layer()->height *
|
||||||
* (0.5f
|
(0.5f + 1.5f * (malformation_acc.max_curvature / PI) *
|
||||||
+
|
gauss(malformation_acc.distance, 5.0f, 1.0f, 0.2f));
|
||||||
1.5f * (malformation_acc.max_curvature / PI)
|
|
||||||
* gauss(malformation_acc.distance, 5.0f, 1.0f, 0.2f));
|
|
||||||
} else {
|
} else {
|
||||||
malformation_acc.reset();
|
malformation_acc.reset();
|
||||||
}
|
}
|
||||||
|
@ -1049,18 +1068,20 @@ Issues check_global_stability(SupportGridFilter supports_presence_grid,
|
||||||
auto force = part.is_stable_while_extruding(weakest_conn, line, support_point, layer_z, params);
|
auto force = part.is_stable_while_extruding(weakest_conn, line, support_point, layer_z, params);
|
||||||
if (force > 0) {
|
if (force > 0) {
|
||||||
if (!supports_presence_grid.position_taken(support_point)) {
|
if (!supports_presence_grid.position_taken(support_point)) {
|
||||||
float area = params.support_points_interface_radius * params.support_points_interface_radius
|
float area = std::min(float(unscaled(line.origin_entity->length())),
|
||||||
* float(PI);
|
params.support_points_interface_radius * params.support_points_interface_radius
|
||||||
|
* float(PI));
|
||||||
|
float altered_area = area * params.get_support_spots_adhesion_strength() / params.get_bed_adhesion_yield_strength();
|
||||||
part.add_support_point(support_point, area);
|
part.add_support_point(support_point, area);
|
||||||
issues.support_points.emplace_back(support_point, force,
|
issues.support_points.emplace_back(support_point, force,
|
||||||
to_3d(Vec2f(line.b - line.a).normalized(), 0.0f));
|
to_3d(Vec2f(line.b - line.a).normalized(), 0.0f));
|
||||||
supports_presence_grid.take_position(support_point);
|
supports_presence_grid.take_position(support_point);
|
||||||
|
|
||||||
weakest_conn.area += area;
|
weakest_conn.area += altered_area;
|
||||||
weakest_conn.centroid_accumulator += support_point * area;
|
weakest_conn.centroid_accumulator += support_point * altered_area;
|
||||||
weakest_conn.second_moment_of_area_accumulator += area
|
weakest_conn.second_moment_of_area_accumulator += altered_area
|
||||||
* support_point.head<2>().cwiseProduct(support_point.head<2>());
|
* support_point.head<2>().cwiseProduct(support_point.head<2>());
|
||||||
weakest_conn.second_moment_of_area_covariance_accumulator += area * support_point.x()
|
weakest_conn.second_moment_of_area_covariance_accumulator += altered_area * support_point.x()
|
||||||
* support_point.y();
|
* support_point.y();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1090,32 +1111,12 @@ std::tuple<Issues, std::vector<LayerIslands>> check_extrusions_and_build_graph(c
|
||||||
for (const LayerRegion *layer_region : layer->regions()) {
|
for (const LayerRegion *layer_region : layer->regions()) {
|
||||||
for (const ExtrusionEntity *ex_entity : layer_region->perimeters.entities) {
|
for (const ExtrusionEntity *ex_entity : layer_region->perimeters.entities) {
|
||||||
for (const ExtrusionEntity *perimeter : static_cast<const ExtrusionEntityCollection*>(ex_entity)->entities) {
|
for (const ExtrusionEntity *perimeter : static_cast<const ExtrusionEntityCollection*>(ex_entity)->entities) {
|
||||||
Points points { };
|
push_lines(perimeter, layer_lines);
|
||||||
perimeter->collect_points(points);
|
|
||||||
for (int point_idx = 0; point_idx < int(points.size() - 1); ++point_idx) {
|
|
||||||
Vec2f start = unscaled(points[point_idx]).cast<float>();
|
|
||||||
Vec2f next = unscaled(points[point_idx + 1]).cast<float>();
|
|
||||||
ExtrusionLine line { start, next, perimeter };
|
|
||||||
layer_lines.push_back(line);
|
|
||||||
}
|
|
||||||
if (perimeter->is_loop()) {
|
|
||||||
Vec2f start = unscaled(points[points.size() - 1]).cast<float>();
|
|
||||||
Vec2f next = unscaled(points[0]).cast<float>();
|
|
||||||
ExtrusionLine line { start, next, perimeter };
|
|
||||||
layer_lines.push_back(line);
|
|
||||||
}
|
|
||||||
} // perimeter
|
} // perimeter
|
||||||
} // ex_entity
|
} // ex_entity
|
||||||
for (const ExtrusionEntity *ex_entity : layer_region->fills.entities) {
|
for (const ExtrusionEntity *ex_entity : layer_region->fills.entities) {
|
||||||
for (const ExtrusionEntity *fill : static_cast<const ExtrusionEntityCollection*>(ex_entity)->entities) {
|
for (const ExtrusionEntity *fill : static_cast<const ExtrusionEntityCollection*>(ex_entity)->entities) {
|
||||||
Points points { };
|
push_lines(fill, layer_lines);
|
||||||
fill->collect_points(points);
|
|
||||||
for (int point_idx = 0; point_idx < int(points.size() - 1); ++point_idx) {
|
|
||||||
Vec2f start = unscaled(points[point_idx]).cast<float>();
|
|
||||||
Vec2f next = unscaled(points[point_idx + 1]).cast<float>();
|
|
||||||
ExtrusionLine line { start, next, fill };
|
|
||||||
layer_lines.push_back(line);
|
|
||||||
}
|
|
||||||
} // fill
|
} // fill
|
||||||
} // ex_entity
|
} // ex_entity
|
||||||
} // region
|
} // region
|
||||||
|
@ -1165,14 +1166,7 @@ std::tuple<Issues, std::vector<LayerIslands>> check_extrusions_and_build_graph(c
|
||||||
check_extrusion_entity_stability(fill, layer_lines, layer->slice_z, layer_region,
|
check_extrusion_entity_stability(fill, layer_lines, layer->slice_z, layer_region,
|
||||||
external_lines, issues, params);
|
external_lines, issues, params);
|
||||||
} else {
|
} else {
|
||||||
Points points { };
|
push_lines(fill, layer_lines);
|
||||||
fill->collect_points(points);
|
|
||||||
for (int point_idx = 0; point_idx < int(points.size() - 1); ++point_idx) {
|
|
||||||
Vec2f start = unscaled(points[point_idx]).cast<float>();
|
|
||||||
Vec2f next = unscaled(points[point_idx + 1]).cast<float>();
|
|
||||||
ExtrusionLine line { start, next, fill };
|
|
||||||
layer_lines.push_back(line);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} // fill
|
} // fill
|
||||||
} // ex_entity
|
} // ex_entity
|
||||||
|
|
|
@ -30,7 +30,7 @@ struct Params {
|
||||||
const std::pair<float,float> malformation_angle_span_deg = std::pair<float, float> { 45.0f, 80.0f };
|
const std::pair<float,float> malformation_angle_span_deg = std::pair<float, float> { 45.0f, 80.0f };
|
||||||
|
|
||||||
const float min_distance_between_support_points = 3.0f; //mm
|
const float min_distance_between_support_points = 3.0f; //mm
|
||||||
const float support_points_interface_radius = 1.5f; // mm
|
const float support_points_interface_radius = 2.0f; // mm
|
||||||
|
|
||||||
// NOTE: Currently disabled, does not work correctly due to inability of the algorithm to correctly detect islands at each layer
|
// NOTE: Currently disabled, does not work correctly due to inability of the algorithm to correctly detect islands at each layer
|
||||||
const float supportable_volume_threshold = 0.0f; // mm^3
|
const float supportable_volume_threshold = 0.0f; // mm^3
|
||||||
|
@ -53,6 +53,11 @@ struct Params {
|
||||||
return 0.018f * 1e6f;
|
return 0.018f * 1e6f;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//just return PLA adhesion value as value for supports
|
||||||
|
float get_support_spots_adhesion_strength() const {
|
||||||
|
return 0.018f * 1e6f;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct SupportPoint {
|
struct SupportPoint {
|
||||||
|
|
Loading…
Add table
Reference in a new issue