mirror of
https://git.mirrors.martin98.com/https://github.com/prusa3d/PrusaSlicer.git
synced 2025-08-14 01:15:53 +08:00
UNFINISHED!
refactoring of algorithm to bottom up propagation of support islands Added CentroidAccumulators for balance issues checking
This commit is contained in:
parent
f0bdf2760c
commit
d9bd1080da
@ -429,8 +429,8 @@ void PrintObject::find_supportable_issues()
|
|||||||
Transform3d inv_transform = (obj_transform * model_transformation).inverse();
|
Transform3d inv_transform = (obj_transform * model_transformation).inverse();
|
||||||
TriangleSelectorWrapper selector { model_volume->mesh() };
|
TriangleSelectorWrapper selector { model_volume->mesh() };
|
||||||
|
|
||||||
for (const Vec3f &support_point : issues.supports_nedded) {
|
for (const SupportableIssues::SupportPoint &support_point : issues.supports_nedded) {
|
||||||
selector.enforce_spot(Vec3f(inv_transform.cast<float>() * support_point), 0.3f);
|
selector.enforce_spot(Vec3f(inv_transform.cast<float>() * support_point.position), 0.3f);
|
||||||
}
|
}
|
||||||
|
|
||||||
model_volume->supported_facets.set(selector.selector);
|
model_volume->supported_facets.set(selector.selector);
|
||||||
|
@ -5,10 +5,12 @@
|
|||||||
#include "tbb/parallel_reduce.h"
|
#include "tbb/parallel_reduce.h"
|
||||||
#include <boost/log/trivial.hpp>
|
#include <boost/log/trivial.hpp>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
#include <unordered_set>
|
||||||
#include <stack>
|
#include <stack>
|
||||||
|
|
||||||
#include "libslic3r/Layer.hpp"
|
#include "libslic3r/Layer.hpp"
|
||||||
#include "libslic3r/ClipperUtils.hpp"
|
#include "libslic3r/ClipperUtils.hpp"
|
||||||
|
#include "Geometry/ConvexHull.hpp"
|
||||||
#include "PolygonPointTest.hpp"
|
#include "PolygonPointTest.hpp"
|
||||||
|
|
||||||
#define DEBUG_FILES
|
#define DEBUG_FILES
|
||||||
@ -31,9 +33,68 @@ bool Issues::empty() const {
|
|||||||
return supports_nedded.empty() && curling_up.empty();
|
return supports_nedded.empty() && curling_up.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SupportPoint::SupportPoint(const Vec3f &position, float weight) :
|
||||||
|
position(position), weight(weight) {
|
||||||
|
}
|
||||||
|
|
||||||
|
SupportPoint::SupportPoint(const Vec3f &position) :
|
||||||
|
position(position), weight(0.0f) {
|
||||||
|
}
|
||||||
|
|
||||||
|
CurledFilament::CurledFilament(const Vec3f &position, float estimated_height) :
|
||||||
|
position(position), estimated_height(estimated_height) {
|
||||||
|
}
|
||||||
|
|
||||||
|
CurledFilament::CurledFilament(const Vec3f &position) :
|
||||||
|
position(position), estimated_height(0.0f) {
|
||||||
|
}
|
||||||
|
|
||||||
struct Cell {
|
struct Cell {
|
||||||
float weight;
|
float weight;
|
||||||
int island_id;
|
float curled_height;
|
||||||
|
int island_id = std::numeric_limits<int>::max();
|
||||||
|
};
|
||||||
|
|
||||||
|
struct CentroidAccumulator {
|
||||||
|
//TODO add base height
|
||||||
|
|
||||||
|
Polygon convex_hull;
|
||||||
|
Points points;
|
||||||
|
Vec3d accumulated_value;
|
||||||
|
float accumulated_weight;
|
||||||
|
|
||||||
|
void calculate_base_hull() {
|
||||||
|
convex_hull = Geometry::convex_hull(points);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct CentroidAccumulators {
|
||||||
|
std::unordered_map<int, size_t> mapping;
|
||||||
|
std::vector<CentroidAccumulator> acccumulators;
|
||||||
|
|
||||||
|
explicit CentroidAccumulators(int count) {
|
||||||
|
acccumulators.resize(count);
|
||||||
|
for (int index = 0; index < count; ++index) {
|
||||||
|
mapping[index - 1] = index;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CentroidAccumulator& access(int id) {
|
||||||
|
return acccumulators[mapping[id]];
|
||||||
|
}
|
||||||
|
|
||||||
|
void merge_to(int from_id, int to_id) {
|
||||||
|
if (from_id == to_id) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
CentroidAccumulator &from_acc = this->access(from_id);
|
||||||
|
CentroidAccumulator &to_acc = this->access(to_id);
|
||||||
|
to_acc.accumulated_value += from_acc.accumulated_value;
|
||||||
|
to_acc.accumulated_weight += from_acc.accumulated_weight;
|
||||||
|
to_acc.points.insert(to_acc.points.end(), from_acc.points.begin(), from_acc.points.end());
|
||||||
|
to_acc.calculate_base_hull();
|
||||||
|
mapping[from_id] = mapping[to_id];
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct WeightDistributionMatrix {
|
struct WeightDistributionMatrix {
|
||||||
@ -75,11 +136,17 @@ struct WeightDistributionMatrix {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Vec3i to_global_cell_coords(const Point &p, float print_z) const {
|
Vec3i to_global_cell_coords(const Point &p, float print_z) const {
|
||||||
Vec3i position = Vec3crd { p.x(), p.y(), int(scale_(print_z)) };
|
Vec3crd position = Vec3crd { p.x(), p.y(), int(scale_(print_z)) };
|
||||||
Vec3i cell_coords = (position - this->global_origin).cwiseQuotient(this->cell_size);
|
Vec3i cell_coords = (position - this->global_origin).cwiseQuotient(this->cell_size);
|
||||||
return cell_coords;
|
return cell_coords;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Vec3i to_global_cell_coords(const Vec3f &position) const {
|
||||||
|
Vec3crd scaled_position = scaled(position);
|
||||||
|
Vec3i cell_coords = (scaled_position - this->global_origin).cwiseQuotient(this->cell_size);
|
||||||
|
return cell_coords;
|
||||||
|
}
|
||||||
|
|
||||||
Vec3i to_local_cell_coords(const Point &p, float print_z) const {
|
Vec3i to_local_cell_coords(const Point &p, float print_z) const {
|
||||||
Vec3i cell_coords = this->to_global_cell_coords(p, print_z);
|
Vec3i cell_coords = this->to_global_cell_coords(p, print_z);
|
||||||
return this->to_local_cell_coords(cell_coords);
|
return this->to_local_cell_coords(cell_coords);
|
||||||
@ -107,6 +174,10 @@ struct WeightDistributionMatrix {
|
|||||||
return cells[this->to_cell_index(to_local_cell_coords(p, print_z))];
|
return cells[this->to_cell_index(to_local_cell_coords(p, print_z))];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Cell& access_cell(const Vec3f &unscaled_position) {
|
||||||
|
return cells[this->to_cell_index(this->to_local_cell_coords(this->to_global_cell_coords(unscaled_position)))];
|
||||||
|
}
|
||||||
|
|
||||||
Cell& access_cell(const Vec3i &local_cell_coords) {
|
Cell& access_cell(const Vec3i &local_cell_coords) {
|
||||||
return cells[this->to_cell_index(local_cell_coords)];
|
return cells[this->to_cell_index(local_cell_coords)];
|
||||||
}
|
}
|
||||||
@ -115,7 +186,7 @@ struct WeightDistributionMatrix {
|
|||||||
return cells[this->to_cell_index(local_cell_coords)];
|
return cells[this->to_cell_index(local_cell_coords)];
|
||||||
}
|
}
|
||||||
|
|
||||||
void ditribute_edge_weight(const Point &p1, const Point &p2, float print_z, coordf_t width) {
|
void distribute_edge_weight(const Point &p1, const Point &p2, float print_z, float unscaled_width) {
|
||||||
Vec2d dir = (p2 - p1).cast<double>();
|
Vec2d dir = (p2 - p1).cast<double>();
|
||||||
double length = dir.norm();
|
double length = dir.norm();
|
||||||
if (length < 0.01) {
|
if (length < 0.01) {
|
||||||
@ -130,17 +201,7 @@ struct WeightDistributionMatrix {
|
|||||||
double current_dist_payload = next_len - distributed_length;
|
double current_dist_payload = next_len - distributed_length;
|
||||||
|
|
||||||
Point location = p1 + ((next_len / length) * dir).cast<coord_t>();
|
Point location = p1 + ((next_len / length) * dir).cast<coord_t>();
|
||||||
double payload = current_dist_payload * width;
|
float payload = unscale<float>(current_dist_payload) * unscaled_width;
|
||||||
|
|
||||||
Vec3i local_index = this->to_local_cell_coords(location, print_z);
|
|
||||||
|
|
||||||
if (this->to_cell_index(local_index) >= this->cells.size() || this->to_cell_index(local_index) < 0) {
|
|
||||||
std::cout << "loc: " << local_index.x() << " " << local_index.y() << " " << local_index.z()
|
|
||||||
<< " globals: " << this->global_cell_count.x() << " "
|
|
||||||
<< this->global_cell_count.y() << " " << this->local_z_cell_count <<
|
|
||||||
"+" << this->local_z_cell_count << std::endl;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this->access_cell(location, print_z).weight += payload;
|
this->access_cell(location, print_z).weight += payload;
|
||||||
|
|
||||||
distributed_length = next_len;
|
distributed_length = next_len;
|
||||||
@ -164,42 +225,97 @@ struct WeightDistributionMatrix {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void distribute_top_down() {
|
void analyze(Issues &issues) {
|
||||||
|
CentroidAccumulators accumulators(issues.supports_nedded.size() + 1);
|
||||||
|
|
||||||
|
|
||||||
|
//TODO split base support points by connectivity!!
|
||||||
|
for (int x = 0; x < global_cell_count.x(); ++x) {
|
||||||
|
for (int y = 0; y < global_cell_count.y(); ++y) {
|
||||||
|
Cell &cell = this->access_cell(Vec3i(x, y, 0));
|
||||||
|
if (cell.weight > 0) {
|
||||||
|
cell.island_id = -1;
|
||||||
|
Vec3crd cell_center = this->get_cell_center(Vec3i(x, y, local_z_index_offset));
|
||||||
|
CentroidAccumulator &acc = accumulators.access(-1);
|
||||||
|
acc.points.push_back(Point(cell_center.head<2>()));
|
||||||
|
acc.accumulated_value += cell_center.cast<double>() * cell.weight;
|
||||||
|
acc.accumulated_weight += cell.weight;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::sort(issues.supports_nedded.begin(), issues.supports_nedded.end(),
|
||||||
|
[](const SupportPoint &left, const SupportPoint &right) {
|
||||||
|
return left.position.z() < right.position.z();
|
||||||
|
});
|
||||||
|
for (int index = 0; index < int(issues.supports_nedded.size()); ++index) {
|
||||||
|
Vec3i local_coords = this->to_local_cell_coords(
|
||||||
|
this->to_global_cell_coords(issues.supports_nedded[index].position));
|
||||||
|
this->access_cell(local_coords).island_id = index;
|
||||||
|
accumulators.access(index).points.push_back(
|
||||||
|
Point(scaled(Vec2f(issues.supports_nedded[index].position.head<2>()))));
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const CurledFilament &curling : issues.curling_up) {
|
||||||
|
this->access_cell(curling.position).curled_height += curling.estimated_height;
|
||||||
|
}
|
||||||
|
|
||||||
const auto validate_xy_coords = [&](const Vec2i &local_coords) {
|
const auto validate_xy_coords = [&](const Vec2i &local_coords) {
|
||||||
return local_coords.x() >= 0 && local_coords.y() >= 0 &&
|
return local_coords.x() >= 0 && local_coords.y() >= 0 &&
|
||||||
local_coords.x() < this->global_cell_count.x() && local_coords.y() < this->global_cell_count.y();
|
local_coords.x() < this->global_cell_count.x() && local_coords.y() < this->global_cell_count.y();
|
||||||
};
|
};
|
||||||
|
|
||||||
Vec2i valid_coords[9];
|
std::unordered_set<int> modified_acc_ids;
|
||||||
|
modified_acc_ids.reserve(issues.supports_nedded.size() + 1);
|
||||||
|
for (int z = 1; z < local_z_cell_count; ++z) {
|
||||||
|
modified_acc_ids.clear();
|
||||||
|
|
||||||
|
for (int x = 0; x < global_cell_count.x(); ++x) {
|
||||||
|
for (int y = 0; y < global_cell_count.y(); ++y) {
|
||||||
|
|
||||||
for (int x = 0; x < global_cell_count.x(); ++x) {
|
|
||||||
for (int y = 0; y < global_cell_count.y(); ++y) {
|
|
||||||
for (int z = local_z_cell_count - 1; z > local_z_index_offset; --z) {
|
|
||||||
Cell ¤t = this->access_cell(Vec3i(x, y, z));
|
Cell ¤t = this->access_cell(Vec3i(x, y, z));
|
||||||
size_t valid_coords_count = 0;
|
//first determine island id
|
||||||
if (current.weight > 0) {
|
if (current.island_id == std::numeric_limits<int>::max()) {
|
||||||
for (int y_offset = -1; y_offset <= 1; ++y_offset) {
|
for (int y_offset = -1; y_offset <= 1; ++y_offset) {
|
||||||
for (int x_offset = -1; x_offset <= 1; ++x_offset) {
|
for (int x_offset = -1; x_offset <= 1; ++x_offset) {
|
||||||
Vec2i xy_coords { x + x_offset, y + y_offset };
|
Vec2i xy_coords { x + x_offset, y + y_offset };
|
||||||
if (validate_xy_coords(xy_coords)
|
if (validate_xy_coords(xy_coords)) {
|
||||||
&&
|
Cell &under = this->access_cell(Vec3i(x, y, z - 1));
|
||||||
this->access_cell(Vec3i(xy_coords.x(), xy_coords.y(), z - 1)).weight != 0) {
|
int island_id = std::min(under.island_id, current.island_id);
|
||||||
valid_coords[valid_coords_count] = xy_coords;
|
int merging_id = std::max(under.island_id, current.island_id);
|
||||||
valid_coords_count++;
|
if (merging_id != std::numeric_limits<int>::max()
|
||||||
|
&& island_id != merging_id) {
|
||||||
|
accumulators.merge_to(merging_id, island_id);
|
||||||
|
}
|
||||||
|
if (island_id != std::numeric_limits<int>::max()) {
|
||||||
|
current.island_id = island_id;
|
||||||
|
modified_acc_ids.insert(current.island_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
current.curled_height += under.curled_height
|
||||||
|
/ (2 + std::abs(x_offset) + std::abs(y_offset));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
float distribution = current.weight / valid_coords_count;
|
|
||||||
for (size_t index = 0; index < valid_coords_count; ++index) {
|
|
||||||
this->access_cell(Vec3i(valid_coords[index].x(), valid_coords[index].y(), z - 1)).weight +=
|
|
||||||
distribution;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (valid_coords_count > 0) {
|
|
||||||
current.weight = 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Propagate to accumulators. TODO what to do if no supporter is found?
|
||||||
|
if (current.island_id != std::numeric_limits<int>::max()) {
|
||||||
|
CentroidAccumulator &acc = accumulators.access(current.island_id);
|
||||||
|
acc.accumulated_value += current.weight * this->get_cell_center(
|
||||||
|
this->to_global_cell_coords(Vec3i(x, y, z))).cast<double>();
|
||||||
|
acc.accumulated_weight += current.weight;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// check stability of modified centroid accumulators
|
||||||
|
for (int acc_index : modified_acc_ids) {
|
||||||
|
CentroidAccumulator &acc = accumulators.access(acc_index);
|
||||||
|
Vec3d centroid = acc.accumulated_value / acc.accumulated_weight;
|
||||||
|
|
||||||
|
if (!acc.convex_hull.contains(Point(centroid.head<2>().cast<coord_t>()))) {
|
||||||
|
//TODO :]
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -232,7 +348,8 @@ struct WeightDistributionMatrix {
|
|||||||
for (int x = 0; x < global_cell_count.x(); ++x) {
|
for (int x = 0; x < global_cell_count.x(); ++x) {
|
||||||
for (int y = 0; y < global_cell_count.y(); ++y) {
|
for (int y = 0; y < global_cell_count.y(); ++y) {
|
||||||
for (int z = 0; z < local_z_cell_count; ++z) {
|
for (int z = 0; z < local_z_cell_count; ++z) {
|
||||||
Vec3f center = unscale(get_cell_center(to_global_cell_coords(Vec3i { x, y, z }))).cast<float>();
|
Vec3f center = unscale(get_cell_center(to_global_cell_coords(Vec3i { x, y, z }))).cast<
|
||||||
|
float>();
|
||||||
const Cell &cell = access_cell(Vec3i(x, y, z));
|
const Cell &cell = access_cell(Vec3i(x, y, z));
|
||||||
if (cell.weight != 0) {
|
if (cell.weight != 0) {
|
||||||
fprintf(fp, "v %f %f %f %f %f %f\n",
|
fprintf(fp, "v %f %f %f %f %f %f\n",
|
||||||
@ -262,7 +379,8 @@ struct WeightDistributionMatrix {
|
|||||||
int local_z_cell_count { };
|
int local_z_cell_count { };
|
||||||
std::vector<Cell> cells { };
|
std::vector<Cell> cells { };
|
||||||
|
|
||||||
};
|
}
|
||||||
|
;
|
||||||
|
|
||||||
namespace Impl {
|
namespace Impl {
|
||||||
|
|
||||||
@ -280,7 +398,8 @@ void debug_export(Issues issues, std::string file_name) {
|
|||||||
|
|
||||||
for (size_t i = 0; i < issues.supports_nedded.size(); ++i) {
|
for (size_t i = 0; i < issues.supports_nedded.size(); ++i) {
|
||||||
fprintf(fp, "v %f %f %f %f %f %f\n",
|
fprintf(fp, "v %f %f %f %f %f %f\n",
|
||||||
issues.supports_nedded[i](0), issues.supports_nedded[i](1), issues.supports_nedded[i](2),
|
issues.supports_nedded[i].position(0), issues.supports_nedded[i].position(1),
|
||||||
|
issues.supports_nedded[i].position(2),
|
||||||
1.0, 0.0, 0.0
|
1.0, 0.0, 0.0
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -297,7 +416,8 @@ void debug_export(Issues issues, std::string file_name) {
|
|||||||
|
|
||||||
for (size_t i = 0; i < issues.curling_up.size(); ++i) {
|
for (size_t i = 0; i < issues.curling_up.size(); ++i) {
|
||||||
fprintf(fp, "v %f %f %f %f %f %f\n",
|
fprintf(fp, "v %f %f %f %f %f %f\n",
|
||||||
issues.curling_up[i](0), issues.curling_up[i](1), issues.curling_up[i](2),
|
issues.curling_up[i].position(0), issues.curling_up[i].position(1),
|
||||||
|
issues.curling_up[i].position(2),
|
||||||
0.0, 1.0, 0.0
|
0.0, 1.0, 0.0
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -310,7 +430,8 @@ void debug_export(Issues issues, std::string file_name) {
|
|||||||
EdgeGridWrapper compute_layer_edge_grid(const Layer *layer) {
|
EdgeGridWrapper compute_layer_edge_grid(const Layer *layer) {
|
||||||
float min_region_flow_width { 1.0f };
|
float min_region_flow_width { 1.0f };
|
||||||
for (const auto *region : layer->regions()) {
|
for (const auto *region : layer->regions()) {
|
||||||
min_region_flow_width = std::min(min_region_flow_width, region->flow(FlowRole::frExternalPerimeter).width());
|
min_region_flow_width = std::min(min_region_flow_width,
|
||||||
|
region->flow(FlowRole::frExternalPerimeter).width());
|
||||||
}
|
}
|
||||||
std::vector<Points> lines;
|
std::vector<Points> lines;
|
||||||
for (const LayerRegion *layer_region : layer->regions()) {
|
for (const LayerRegion *layer_region : layer->regions()) {
|
||||||
@ -390,7 +511,8 @@ Issues check_extrusion_entity_stability(const ExtrusionEntity *entity,
|
|||||||
if (entity->is_collection()) {
|
if (entity->is_collection()) {
|
||||||
for (const auto *e : static_cast<const ExtrusionEntityCollection*>(entity)->entities) {
|
for (const auto *e : static_cast<const ExtrusionEntityCollection*>(entity)->entities) {
|
||||||
issues.add(
|
issues.add(
|
||||||
check_extrusion_entity_stability(e, print_z, layer_region, supported_grid, weight_matrix, params));
|
check_extrusion_entity_stability(e, print_z, layer_region, supported_grid, weight_matrix,
|
||||||
|
params));
|
||||||
}
|
}
|
||||||
} else { //single extrusion path, with possible varying parameters
|
} else { //single extrusion path, with possible varying parameters
|
||||||
//prepare stack of points on the extrusion path. If there are long segments, additional points might be pushed onto the stack during the algorithm.
|
//prepare stack of points on the extrusion path. If there are long segments, additional points might be pushed onto the stack during the algorithm.
|
||||||
@ -419,15 +541,14 @@ Issues check_extrusion_entity_stability(const ExtrusionEntity *entity,
|
|||||||
while (!points.empty()) {
|
while (!points.empty()) {
|
||||||
Point point = points.top();
|
Point point = points.top();
|
||||||
points.pop();
|
points.pop();
|
||||||
Vec2f tmp = unscale(point).cast<float>();
|
Vec3f fpoint = to_vec3f(point);
|
||||||
Vec3f fpoint = Vec3f(tmp.x(), tmp.y(), print_z);
|
|
||||||
float edge_len = (fpoint - prev_fpoint).norm();
|
float edge_len = (fpoint - prev_fpoint).norm();
|
||||||
|
|
||||||
weight_matrix.ditribute_edge_weight(prev_point, point, print_z, flow_width);
|
weight_matrix.distribute_edge_weight(prev_point, point, print_z, unscale<float>(flow_width));
|
||||||
|
|
||||||
coordf_t dist_from_prev_layer { 0 };
|
coordf_t dist_from_prev_layer { 0 };
|
||||||
if (!supported_grid.signed_distance(point, flow_width, dist_from_prev_layer)) { // dist from prev layer not found, assume empty layer
|
if (!supported_grid.signed_distance(point, flow_width, dist_from_prev_layer)) { // dist from prev layer not found, assume empty layer
|
||||||
issues.supports_nedded.push_back(fpoint);
|
issues.supports_nedded.push_back(SupportPoint(fpoint));
|
||||||
supports_acc.reset();
|
supports_acc.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -451,7 +572,7 @@ Issues check_extrusion_entity_stability(const ExtrusionEntity *entity,
|
|||||||
/ (1.0f
|
/ (1.0f
|
||||||
+ (supports_acc.max_curvature
|
+ (supports_acc.max_curvature
|
||||||
* params.bridge_distance_decrease_by_curvature_factor / PI))) {
|
* params.bridge_distance_decrease_by_curvature_factor / PI))) {
|
||||||
issues.supports_nedded.push_back(fpoint);
|
issues.supports_nedded.push_back(SupportPoint(fpoint));
|
||||||
supports_acc.reset();
|
supports_acc.reset();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -462,7 +583,7 @@ Issues check_extrusion_entity_stability(const ExtrusionEntity *entity,
|
|||||||
if (dist_from_prev_layer > 0.0f) { //extrusion point is unsupported or poorly supported
|
if (dist_from_prev_layer > 0.0f) { //extrusion point is unsupported or poorly supported
|
||||||
curling_acc.add_distance(edge_len);
|
curling_acc.add_distance(edge_len);
|
||||||
if (curling_acc.max_curvature / (PI * curling_acc.distance) > params.limit_curvature) {
|
if (curling_acc.max_curvature / (PI * curling_acc.distance) > params.limit_curvature) {
|
||||||
issues.curling_up.push_back(fpoint);
|
issues.curling_up.push_back(CurledFilament(fpoint, layer_region->layer()->height));
|
||||||
curling_acc.reset();
|
curling_acc.reset();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -512,7 +633,8 @@ Issues check_layer_stability(const PrintObject *po, size_t layer_idx, bool full_
|
|||||||
} // 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) {
|
||||||
if (fill->role() == ExtrusionRole::erGapFill || fill->role() == ExtrusionRole::erBridgeInfill) {
|
if (fill->role() == ExtrusionRole::erGapFill
|
||||||
|
|| fill->role() == ExtrusionRole::erBridgeInfill) {
|
||||||
issues.add(check_extrusion_entity_stability(fill,
|
issues.add(check_extrusion_entity_stability(fill,
|
||||||
layer->print_z, layer_region,
|
layer->print_z, layer_region,
|
||||||
supported_grid, weight_matrix, params));
|
supported_grid, weight_matrix, params));
|
||||||
@ -577,7 +699,8 @@ std::vector<size_t> quick_search(const PrintObject *po, const Params ¶ms) {
|
|||||||
return problematic_layers;
|
return problematic_layers;
|
||||||
}
|
}
|
||||||
|
|
||||||
Issues full_search(const PrintObject *po, const Params ¶ms) {
|
Issues
|
||||||
|
full_search(const PrintObject *po, const Params ¶ms) {
|
||||||
using namespace Impl;
|
using namespace Impl;
|
||||||
|
|
||||||
WeightDistributionMatrix matrix { };
|
WeightDistributionMatrix matrix { };
|
||||||
@ -609,7 +732,7 @@ Issues full_search(const PrintObject *po, const Params ¶ms) {
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
matrix.distribute_top_down();
|
matrix.analyze(found_issues);
|
||||||
|
|
||||||
matrix.debug_export("weight");
|
matrix.debug_export("weight");
|
||||||
|
|
||||||
|
@ -16,9 +16,23 @@ struct Params {
|
|||||||
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) )
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct SupportPoint {
|
||||||
|
SupportPoint(const Vec3f &position, float weight);
|
||||||
|
explicit SupportPoint(const Vec3f &position);
|
||||||
|
Vec3f position;
|
||||||
|
float weight;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct CurledFilament {
|
||||||
|
CurledFilament(const Vec3f &position, float estimated_height);
|
||||||
|
explicit CurledFilament(const Vec3f &position);
|
||||||
|
Vec3f position;
|
||||||
|
float estimated_height;
|
||||||
|
};
|
||||||
|
|
||||||
struct Issues {
|
struct Issues {
|
||||||
std::vector<Vec3f> supports_nedded;
|
std::vector<SupportPoint> supports_nedded;
|
||||||
std::vector<Vec3f> curling_up;
|
std::vector<CurledFilament> curling_up;
|
||||||
|
|
||||||
void add(const Issues &layer_issues);
|
void add(const Issues &layer_issues);
|
||||||
bool empty() const;
|
bool empty() const;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user