debug export svg info,

fixing problem with weird seam placement caused by disconnected scoring function
This commit is contained in:
PavelMikus 2022-03-04 14:13:17 +01:00
parent 962282c9ef
commit a92d5038bd
2 changed files with 128 additions and 70 deletions

View File

@ -26,12 +26,25 @@
#ifdef DEBUG_FILES
#include "Subdivide.hpp"
#include <boost/nowide/cstdio.hpp>
#include <SVG.hpp>
#endif
namespace Slic3r {
namespace SeamPlacerImpl {
Vec3f value_to_rgbf(float minimum, float maximum, float value) {
float ratio = 2.0f * (value - minimum) / (maximum - minimum);
float b = std::max(0.0f, (1.0f - ratio));
float r = std::max(0.0f, (ratio - 1.0f));
float g = 1.0f - b - r;
return Vec3f { r, g, b };
}
Vec3i value_rgbi(float minimum, float maximum, float value) {
return (value_to_rgbf(minimum, maximum, value) * 255).cast<int>();
}
//https://towardsdatascience.com/least-square-polynomial-fitting-using-c-eigen-package-c0673728bd01
// interpolates points in z (treats z coordinates as time) and returns coefficients for axis x and y
std::vector<Vec2f> polyfit(const std::vector<Vec3f> &points, const std::vector<float> &weights, size_t order) {
@ -350,7 +363,7 @@ struct GlobalModelInfo {
#ifdef DEBUG_FILES
void debug_export(const indexed_triangle_set &obj_mesh, const char *file_name) const {
indexed_triangle_set divided_mesh = subdivide(obj_mesh, SeamPlacer::considered_area_radius);
indexed_triangle_set divided_mesh = obj_mesh; // subdivide(obj_mesh, SeamPlacer::considered_area_radius);
Slic3r::CNumericLocalesSetter locales_setter;
{
FILE *fp = boost::nowide::fopen(file_name, "w");
@ -402,7 +415,6 @@ struct GlobalModelInfo {
}
}
#endif
}
;
@ -669,8 +681,10 @@ struct SeamComparator {
setup(setup) {
}
//TODO "bump function": e^[1 / ( (x-0.3)^2 +1 )] -1 << =^(((1)/((x-0.3)^(2)+1)))-1
float compute_angle_penalty(float ccw_angle) const {
if (ccw_angle >= 0) {
if (ccw_angle >= -0.4) {
return PI * PI - ccw_angle * ccw_angle;
} else {
return (PI * PI - ccw_angle * ccw_angle) * 0.7f;
@ -727,16 +741,56 @@ struct SeamComparator {
float get_weight(const SeamCandidate &a) const {
if (setup == SeamPosition::spRear) {
return a.position.y() + int(a.type) * 10000.0f;
return a.position.y();
}
//return negative, beacuse we want to minimize this value (sort of antiweight). normalization in alignment fixes that with respect to other points
return int(a.type) * 10000.0f
- (a.visibility + SeamPlacer::expected_hits_per_area) * compute_angle_penalty(a.local_ccw_angle);
//return negative, beacuse we want to minimize the absolute of this value (sort of antiweight). normalization in alignment fixes that with respect to other points
return -(a.visibility + SeamPlacer::expected_hits_per_area) * compute_angle_penalty(a.local_ccw_angle);
}
}
;
#ifdef DEBUG_FILES
void debug_export_points(const std::vector<std::vector<SeamPlacerImpl::SeamCandidate>> &object_perimter_points,
const BoundingBox &bounding_box, std::string object_name, const SeamComparator &comparator) {
for (size_t layer_idx = 0; layer_idx < object_perimter_points.size(); ++layer_idx) {
SVG angles_svg { object_name + "_angles_" + std::to_string(layer_idx) + ".svg", bounding_box };
float min_vis = 0;
float max_vis = min_vis;
float min_weight = std::numeric_limits<float>::min();
float max_weight = min_weight;
for (const SeamCandidate &point : object_perimter_points[layer_idx]) {
Vec3i color = value_rgbi(-PI, PI, point.local_ccw_angle);
std::string fill = "rgb(" + std::to_string(color.x()) + "," + std::to_string(color.y()) + ","
+ std::to_string(color.z()) + ")";
angles_svg.draw(scaled(Vec2f(point.position.head<2>())), fill);
min_vis = std::min(min_vis, point.visibility);
max_vis = std::max(max_vis, point.visibility);
min_weight = std::min(min_weight, comparator.get_weight(point));
max_weight = std::max(max_weight, comparator.get_weight(point));
}
SVG visibility_svg { object_name + "_visibility_" + std::to_string(layer_idx) + ".svg", bounding_box };
SVG weight_svg { object_name + "_weight_" + std::to_string(layer_idx) + ".svg", bounding_box };
for (const SeamCandidate &point : object_perimter_points[layer_idx]) {
Vec3i color = value_rgbi(min_vis, max_vis, point.visibility);
std::string visibility_fill = "rgb(" + std::to_string(color.x()) + "," + std::to_string(color.y()) + ","
+ std::to_string(color.z()) + ")";
visibility_svg.draw(scaled(Vec2f(point.position.head<2>())), visibility_fill);
Vec3i weight_color = value_rgbi(min_weight, max_weight, comparator.get_weight(point));
std::string weight_fill = "rgb(" + std::to_string(weight_color.x()) + "," + std::to_string(weight_color.y()) + ","
+ std::to_string(weight_color.z()) + ")";
weight_svg.draw(scaled(Vec2f(point.position.head<2>())), weight_fill);
}
}
}
#endif
} // namespace SeamPlacerImpl
// Parallel process and extract each perimeter polygon of the given print object.
@ -830,7 +884,8 @@ bool SeamPlacer::find_next_seam_in_layer(const PrintObject *po,
std::vector<std::pair<size_t, size_t>> &potential_string_seams) {
using namespace SeamPlacerImpl;
const SeamCandidate& last_point = m_perimeter_points_per_object[po][last_point_indexes.first][last_point_indexes.second];
const SeamCandidate &last_point =
m_perimeter_points_per_object[po][last_point_indexes.first][last_point_indexes.second];
Vec3f projected_position { last_point.position.x(), last_point.position.y(), float(
po->get_layer(layer_idx)->slice_z) };
@ -859,7 +914,8 @@ bool SeamPlacer::find_next_seam_in_layer(const PrintObject *po,
return true;
} else if ((closest_point.position - projected_position).norm()
< SeamPlacer::seam_align_tolerable_dist
&& comparator.is_first_not_much_worse(closest_point, next_layer_seam) && are_similar(last_point, closest_point)) {
&& comparator.is_first_not_much_worse(closest_point, next_layer_seam)
&& are_similar(last_point, closest_point)) {
//seam point is far, but if the close point is not much worse, do not count it as a skip and add it to potential_string_seams
potential_string_seams.emplace_back(layer_idx, closest_point_index);
last_point_indexes = std::pair<size_t, size_t> { layer_idx, closest_point_index };
@ -1131,6 +1187,8 @@ void SeamPlacer::init(const Print &print) {
BOOST_LOG_TRIVIAL(debug)
<< "SeamPlacer: align_seam_points : end";
}
debug_export_points(m_perimeter_points_per_object[po], po->bounding_box(), std::to_string(po->id().id), comparator);
}
}

View File

@ -101,11 +101,11 @@ public:
// area considered when computing number of rays and then gathering visiblity info from the hits
static constexpr float considered_area_radius = 3.0f;
// quadric error limit of quadric decimation function used on the mesh before raycasting
static constexpr float raycasting_decimation_target_error = 0.1f;
static constexpr float raycasting_decimation_target_error = 2.0f;
// cosine sampling power represents how prefered are forward directions when raycasting from given spot
// in this case, forward direction means towards the center of the mesh
static constexpr float cosine_hemisphere_sampling_power = 8.0f;
static constexpr float cosine_hemisphere_sampling_power = 5.0f;
// arm length used during angles computation
static constexpr float polygon_local_angles_arm_distance = 1.0f;