OrcaSlicer latest
OrcaSlicer
Loading...
Searching...
No Matches
Slic3r::orientation::AutoOrienter Class Reference
Collaboration diagram for Slic3r::orientation::AutoOrienter:

Classes

struct  VecHash

Public Member Functions

 AutoOrienter (OrientMesh *orient_mesh_, const OrientParams &params_, std::function< void(unsigned)> progressind_, std::function< bool(void)> stopcond_)
 AutoOrienter (TriangleMesh *mesh_)
Vec3f quantize_vec3f (const Vec3f n1)
Vec3d process ()
void preprocess ()
void area_cumulation (const Eigen::MatrixXf &normals_, const Eigen::VectorXf &areas_, int num_directions=10)
void area_cumulation_accurate (std::vector< Vec3f > &normals_, const Eigen::MatrixXf &quantize_normals_, const Eigen::VectorXf &areas_, int num_directions=10)
void add_supplements ()
void remove_duplicates (double tol=0.0000001)
 remove duplicate orientations
void project_vertices (Vec3f orientation)
CostItems get_features (Vec3f orientation, bool min_volume=true)
float target_function (CostItems &costs, bool min_volume)
Vec3d find_cooling_direction2 (Vec3d euler_angles, const Eigen::VectorXf &areas_in, TriangleMesh &mesh)

Static Public Member Functions

static Eigen::VectorXi argsort (const Eigen::VectorXf &vec, std::string order="ascend")

Public Attributes

int face_count_hull
OrientMesh * orient_mesh = NULL
TriangleMesh * mesh
TriangleMesh mesh_convex_hull
Eigen::MatrixXf normals
Eigen::MatrixXf normals_quantize
Eigen::MatrixXf normals_hull
Eigen::MatrixXf normals_hull_quantize
Eigen::VectorXf areas
Eigen::VectorXf areas_hull
Eigen::VectorXf is_apperance
Eigen::MatrixXf z_projected
Eigen::VectorXf z_max
Eigen::VectorXf z_max_hull
Eigen::VectorXf z_median
Eigen::VectorXf z_mean
Eigen::VectorXf areas_cooling
std::vector< Vec3f > face_normals
std::vector< Vec3f > face_normals_hull
OrientParams params
bool has_cooling_fan = false
std::vector< Vec3f > orientations
std::function< void(unsigned)> progressind = { }

Detailed Description

Constructor & Destructor Documentation

◆ AutoOrienter() [1/2]

Slic3r::orientation::AutoOrienter::AutoOrienter ( OrientMesh * orient_mesh_,
const OrientParams & params_,
std::function< void(unsigned)> progressind_,
std::function< bool(void)> stopcond_ )
inline
105 {
106 orient_mesh = orient_mesh_;
107 mesh = &orient_mesh->mesh;
108 params = params_;
109 has_cooling_fan = orient_mesh->has_cooling_fan;
110 progressind = progressind_;
111 params.ASCENT = cos(PI - orient_mesh->overhang_angle * PI / 180); // use per-object overhang angle
112
113 // BOOST_LOG_TRIVIAL(info) << orient_mesh->name << ", angle=" << orient_mesh->overhang_angle << ", params.ASCENT=" << params.ASCENT;
114 // std::cout << orient_mesh->name << ", angle=" << orient_mesh->overhang_angle << ", params.ASCENT=" << params.ASCENT;
115
116 preprocess();
117 }
std::function< void(unsigned)> progressind
Definition Orient.cpp:98
OrientMesh * orient_mesh
Definition Orient.cpp:81
bool has_cooling_fan
Definition Orient.cpp:95
OrientParams params
Definition Orient.cpp:94
void preprocess()
Definition Orient.cpp:208
TriangleMesh * mesh
Definition Orient.cpp:82
static constexpr double PI
Definition libslic3r.h:81

References has_cooling_fan, mesh, orient_mesh, params, PI, preprocess(), and progressind.

Here is the call graph for this function:

◆ AutoOrienter() [2/2]

Slic3r::orientation::AutoOrienter::AutoOrienter ( TriangleMesh * mesh_)
inline
120 {
121 mesh = mesh_;
122 preprocess();
123 }

References mesh, and preprocess().

Here is the call graph for this function:

Member Function Documentation

◆ add_supplements()

void Slic3r::orientation::AutoOrienter::add_supplements ( )
inline
312 {
313 std::vector<Vec3f> vecs = { {0, 0, -1} ,{0.70710678, 0, -0.70710678},{0, 0.70710678, -0.70710678},
314 {-0.70710678, 0, -0.70710678},{0, -0.70710678, -0.70710678},
315 {1, 0, 0},{0.70710678, 0.70710678, 0},{0, 1, 0},{-0.70710678, 0.70710678, 0},
316 {-1, 0, 0},{-0.70710678, -0.70710678, 0},{0, -1, 0},{0.70710678, -0.70710678, 0},
317 {0.70710678, 0, 0.70710678},{0, 0.70710678, 0.70710678},
318 {-0.70710678, 0, 0.70710678},{0, -0.70710678, 0.70710678},{0, 0, 1} };
319 orientations.insert(orientations.end(), vecs.begin(), vecs.end());
320 }
std::vector< Vec3f > orientations
Definition Orient.cpp:97

References orientations.

Referenced by process().

Here is the caller graph for this function:

◆ area_cumulation()

void Slic3r::orientation::AutoOrienter::area_cumulation ( const Eigen::MatrixXf & normals_,
const Eigen::VectorXf & areas_,
int num_directions = 10 )
inline
257 {
258 std::unordered_map<stl_normal, float, VecHash> alignments;
259 // init to 0
260 for (size_t i = 0; i < areas_.size(); i++)
261 alignments.insert(std::pair(normals_.row(i), 0));
262 // cumulate areas
263 for (size_t i = 0; i < areas_.size(); i++)
264 {
265 alignments[normals_.row(i)] += areas_(i);
266 }
267
268 typedef std::pair<stl_normal, float> PAIR;
269 std::vector<PAIR> align_counts(alignments.begin(), alignments.end());
270 sort(align_counts.begin(), align_counts.end(), [](const PAIR& p1, const PAIR& p2) {return p1.second > p2.second; });
271
272 num_directions = std::min((size_t)num_directions, align_counts.size());
273 for (size_t i = 0; i < num_directions; i++)
274 {
275 orientations.push_back(align_counts[i].first);
276 //orientations.push_back(its_face_normals(mesh->its)[i]);
277 BOOST_LOG_TRIVIAL(debug) << align_counts[i].first.transpose() << ", area: " << align_counts[i].second;
278 }
279 }

References orientations.

◆ area_cumulation_accurate()

void Slic3r::orientation::AutoOrienter::area_cumulation_accurate ( std::vector< Vec3f > & normals_,
const Eigen::MatrixXf & quantize_normals_,
const Eigen::VectorXf & areas_,
int num_directions = 10 )
inline
282 {
283 std::unordered_map<stl_normal, std::pair<std::vector<float>, Vec3f>, VecHash> alignments_;
284 Vec3f n1 = { 0, 0, 0 };
285 std::vector<float> current_areas = {0, 0};
286 // init to 0
287 for (size_t i = 0; i < areas_.size(); i++) {
288 alignments_.insert(std::pair(quantize_normals_.row(i), std::pair(current_areas, n1)));
289 }
290 // cumulate areas
291 for (size_t i = 0; i < areas_.size(); i++)
292 {
293 alignments_[quantize_normals_.row(i)].first[1] += areas_(i);
294 if (areas_(i) > alignments_[quantize_normals_.row(i)].first[0]){
295 alignments_[quantize_normals_.row(i)].second = normals_[i];
296 alignments_[quantize_normals_.row(i)].first[0] = areas_(i);
297 }
298 }
299
300 typedef std::pair<stl_normal, std::pair<std::vector<float>, Vec3f>> PAIR;
301 std::vector<PAIR> align_counts(alignments_.begin(), alignments_.end());
302 sort(align_counts.begin(), align_counts.end(), [](const PAIR& p1, const PAIR& p2) {return p1.second.first[1] > p2.second.first[1]; });
303
304 num_directions = std::min((size_t)num_directions, align_counts.size());
305 for (size_t i = 0; i < num_directions; i++)
306 {
307 orientations.push_back(align_counts[i].second.second);
308 BOOST_LOG_TRIVIAL(debug) << align_counts[i].second.second.transpose() << ", area: " << align_counts[i].second.first[1];
309 }
310 }
Eigen::Matrix< float, 3, 1, Eigen::DontAlign > Vec3f
Definition Point.hpp:65

References orientations.

Referenced by process().

Here is the caller graph for this function:

◆ argsort()

Eigen::VectorXi Slic3r::orientation::AutoOrienter::argsort ( const Eigen::VectorXf & vec,
std::string order = "ascend" )
inlinestatic
379 {
380 Eigen::VectorXi ind = Eigen::VectorXi::LinSpaced(vec.size(), 0, vec.size() - 1);//[0 1 2 3 ... N-1]
381 std::function<bool(int, int)> rule;
382 if (order == "ascend") {
383 rule = [vec](int i, int j)->bool {
384 return vec(i) < vec(j);
385 };
386 }
387 else {
388 rule = [vec](int i, int j)->bool {
389 return vec(i) > vec(j);
390 };
391 }
392 std::sort(ind.data(), ind.data() + ind.size(), rule);
393 return ind;
394
395 //sorted_vec.resize(vec.size());
396 //for (int i = 0; i < vec.size(); i++) {
397 // sorted_vec(i) = vec(ind(i));
398 //}
399 }

Referenced by get_features().

Here is the caller graph for this function:

◆ find_cooling_direction2()

Vec3d Slic3r::orientation::AutoOrienter::find_cooling_direction2 ( Vec3d euler_angles,
const Eigen::VectorXf & areas_in,
TriangleMesh & mesh )
inline
513 {
514 Vec3f machine_cool_dir = this->orient_mesh->cooling_direction.cast<float>();
515 const size_t num_faces = areas.rows();
516 Vec3f best_direction = { 0, 0, 0 };
517
518 // 1. Make a copy of input mesh, rotate and translate to the best orientation
519 TriangleMesh mesh_copy = TriangleMesh(mesh.its);
520 mesh_copy.rotate_x(euler_angles(0, 0));
521 mesh_copy.rotate_y(euler_angles(1, 0));
522 mesh_copy.rotate_z(euler_angles(2, 0));
523 auto bounding_box = mesh_copy.bounding_box();
524 Eigen::VectorXf translate_distance = bounding_box.min.array().cast<float>();
525 Vec3d mesh_center = mesh_copy.center();
526 mesh_copy.translate(-mesh_center(0), -mesh_center(1), -translate_distance(2));
527
528 // 2. sample cooling direction
529 const size_t sample_nums = 180;
530 std::vector<Vec3f> cool_dirs;
531 for (size_t i = 0; i < sample_nums; i++)
532 {
533 float angle_deg = i * (360.0 / sample_nums);
534 float angle_rad = angle_deg * (PI / 180.0);
535 cool_dirs.push_back(Vec3f{ std::cos(angle_rad), std::sin(angle_rad), 0});
536 }
537
538 // 3. accumulate the weighted projected overhang area, find the max weighted project area direction
539 std::vector<Vec3f> face_normals_copy = its_face_normals(mesh_copy.its);
540 float overhang_projected_max = 0.f;
541 float overhang_projected_origin = 0.f;
542 for (auto cool_dir : cool_dirs)
543 {
544 float overhang_projected_tmp = 0.f;
545 for (size_t i = 0; i < num_faces; i++)
546 {
547 float cool_dir_projection = face_normals_copy[i].dot(cool_dir);
548 if (areas_in[i] > 0 && cool_dir_projection > 0)
549 {
550 overhang_projected_tmp += areas_in[i] * cool_dir_projection;
551 }
552 }
553 if (overhang_projected_tmp > overhang_projected_max)
554 {
555 overhang_projected_max = overhang_projected_tmp;
556 best_direction = cool_dir;
557 }
558 if (cool_dir.dot(machine_cool_dir) > 0.999)
559 {
560 overhang_projected_origin = overhang_projected_tmp;
561 }
562 }
563
564 // The symmetric model has similar overhang projection at all angles, so Z-axis rotation is unnecessary.
565 if (std::abs(overhang_projected_origin - overhang_projected_max) < 1.0f)
566 {
567 best_direction = machine_cool_dir;
568 }
569 BOOST_LOG_TRIVIAL(info) << "best cooling dir = " << best_direction.transpose() << "\n";
570 return best_direction.cast<double>();
571 }
Eigen::VectorXf areas
Definition Orient.cpp:85
Eigen::Matrix< double, 3, 1, Eigen::DontAlign > Vec3d
Definition Point.hpp:68
BoundingBoxf3 bounding_box(const TriangleMesh &m)
Definition TriangleMesh.hpp:391
std::vector< Vec3f > its_face_normals(const indexed_triangle_set &its)
Definition TriangleMesh.cpp:1625

References areas, Slic3r::bounding_box(), Slic3r::TriangleMesh::bounding_box(), Slic3r::TriangleMesh::center(), Slic3r::orientation::OrientMesh::cooling_direction, Slic3r::TriangleMesh::its, Slic3r::its_face_normals(), mesh, PI, Slic3r::TriangleMesh::rotate_x(), Slic3r::TriangleMesh::rotate_y(), Slic3r::TriangleMesh::rotate_z(), and Slic3r::TriangleMesh::translate().

Here is the call graph for this function:

◆ get_features()

CostItems Slic3r::orientation::AutoOrienter::get_features ( Vec3f orientation,
bool min_volume = true )
inline
403 {
404 CostItems costs;
405 costs.area_total = mesh->bounding_box().area();
406 costs.radius = mesh->bounding_box().radius();
407 // volume
408 costs.volume = mesh->stats().volume > 0 ? mesh->stats().volume : its_volume(mesh->its);
409
410 float total_min_z = z_projected.minCoeff();
411 // filter bottom area
412 auto bottom_condition = (z_max.array() < total_min_z + this->params.FIRST_LAY_H - EPSILON).eval();
413 auto bottom_condition_hull = (z_max_hull.array() < total_min_z + this->params.FIRST_LAY_H - EPSILON).eval();
414 auto bottom_condition_2nd = (z_max.array() < total_min_z + this->params.FIRST_LAY_H / 2.f - EPSILON).eval();
415 //The first layer is sliced on half of the first layer height.
416 //The bottom area is measured by accumulating first layer area with the facets area below first layer height.
417 //By combining these two factors, we can avoid the wrong orientation of large planar faces while not influence the
418 //orientations of complex objects with small bottom areas.
419 costs.bottom = bottom_condition.select(areas, 0).sum()*0.5 + bottom_condition_2nd.select(areas, 0).sum();
420
421 // filter overhang
422 Eigen::VectorXf normal_projection(normals.rows(), 1);// = this->normals.dot(orientation);
423 for (size_t i = 0; i < normals.rows(); i++)
424 {
425 normal_projection(i) = normals.row(i).dot(orientation);
426 }
427 auto areas_appearance = areas.cwiseProduct((is_apperance * params.APPERANCE_FACE_SUPP + Eigen::VectorXf::Ones(is_apperance.rows(), is_apperance.cols()))).eval();
428 auto overhang_areas = ((normal_projection.array() < params.ASCENT) * (!bottom_condition_2nd)).select(areas_appearance, 0).eval();
429 Eigen::MatrixXf inner = normal_projection.array() - params.ASCENT;
430 inner = inner.cwiseMin(0).cwiseAbs();
431 if (min_volume)
432 {
433 Eigen::MatrixXf heights = z_mean.array() - total_min_z;
434 costs.overhang = (heights.array()* overhang_areas.array()*inner.array()).sum();
435 }
436 else {
437 costs.overhang = overhang_areas.array().cwiseAbs().sum();
438 }
439
440 {
441 // contour perimeter
442#if 1
443 // the simple way for contour is even better for faces of small bridges
444 costs.contour = 4 * sqrt(costs.bottom);
445#else
446 float contour = 0;
447 int face_count = mesh->facets_count();
448 auto its = mesh->its;
449 int contour_amout = 0;
450 for (size_t i = 0; i < face_count; i++)
451 {
452 if (bottom_condition(i)) {
453 Eigen::VectorXi index = argsort(z_projected.row(i));
454 stl_vertex line = its.get_vertex(i, index(0)) - its.get_vertex(i, index(1));
455 contour += line.norm();
456 contour_amout++;
457 }
458 }
459 costs.contour += contour + params.CONTOUR_AMOUNT * contour_amout;
460#endif
461 }
462
463 // bottom of convex hull
464 costs.bottom_hull = (bottom_condition_hull).select(areas_hull, 0).sum();
465
466 // low angle faces
467 auto normal_projection_abs = normal_projection.cwiseAbs().eval();
468 Eigen::MatrixXf laf_areas = ((normal_projection_abs.array() < params.LAF_MAX) * (normal_projection_abs.array() > params.LAF_MIN) * (z_max.array() > total_min_z + params.FIRST_LAY_H)).select(areas, 0);
469 costs.area_laf = laf_areas.sum();
470
471 if (has_cooling_fan)
472 {
473 // Angle range of overhang faces requiring cooling
474 float angle_thres_high = -0.6427f;
475 float angle_thres_low = -0.97f;
476 // compute the weighted overhang faces area
477 Eigen::VectorXf ones_f = Eigen::VectorXf::Ones(mesh->facets_count());
478 auto overhang_area_condition = (normal_projection.array() < angle_thres_high && normal_projection.array() > angle_thres_low).eval();
479 Eigen::VectorXf areas_ = (overhang_area_condition * !bottom_condition_2nd).select(areas, 0);
480 Eigen::VectorXf weighted_areas = areas_.cwiseProduct(ones_f - normal_projection);
481 costs.areas_cooling = weighted_areas;
482 }
483
484 // height to bottom_hull_area ratio
485 //float total_max_z = z_projected.maxCoeff();
486 //costs.height_to_bottom_hull_ratio = SQ(total_max_z) / (costs.bottom_hull + 1e-7);
487
488 return costs;
489 }
#define EPSILON
Definition ColorUtils.cpp:64
Eigen::VectorXf areas_hull
Definition Orient.cpp:85
Eigen::VectorXf is_apperance
Definition Orient.cpp:86
static Eigen::VectorXi argsort(const Eigen::VectorXf &vec, std::string order="ascend")
Definition Orient.cpp:378
Eigen::MatrixXf normals
Definition Orient.cpp:84
Eigen::VectorXf z_max
Definition Orient.cpp:88
Eigen::VectorXf z_mean
Definition Orient.cpp:90
Eigen::MatrixXf z_projected
Definition Orient.cpp:87
Eigen::VectorXf z_max_hull
Definition Orient.cpp:88
float its_volume(const indexed_triangle_set &its)
Definition TriangleMesh.cpp:1479
const Polygon & contour(const ExPolygon &p)
Definition AGGRaster.hpp:30

References Slic3r::orientation::CostItems::area_laf, Slic3r::orientation::CostItems::area_total, areas, Slic3r::orientation::CostItems::areas_cooling, areas_hull, argsort(), Slic3r::orientation::CostItems::bottom, Slic3r::orientation::CostItems::bottom_hull, Slic3r::contour(), Slic3r::orientation::CostItems::contour, EPSILON, Slic3r::orientation::OrientParams::FIRST_LAY_H, has_cooling_fan, is_apperance, Slic3r::its_volume(), mesh, normals, Slic3r::orientation::CostItems::overhang, params, Slic3r::orientation::CostItems::radius, Slic3r::orientation::CostItems::volume, z_max, z_max_hull, z_mean, and z_projected.

Referenced by process().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ preprocess()

void Slic3r::orientation::AutoOrienter::preprocess ( )
inline
209 {
210 int count_apperance = 0;
211 {
212 int face_count = mesh->facets_count();
213 auto its = mesh->its;
215 areas = Eigen::VectorXf::Zero(face_count);
216 is_apperance = Eigen::VectorXf::Zero(face_count);
217 normals = Eigen::MatrixXf::Zero(face_count, 3);
218 normals_quantize = Eigen::MatrixXf::Zero(face_count, 3);
219 for (size_t i = 0; i < face_count; i++)
220 {
221 float area = its.facet_area(i);
222 normals.row(i) = face_normals[i];
224 areas(i) = area;
225 is_apperance(i) = (its.get_property(i).type == EnumFaceTypes::eExteriorAppearance);
226 count_apperance += (is_apperance(i)==1);
227 }
228 }
229
230 if (orient_mesh)
231 BOOST_LOG_TRIVIAL(debug) <<orient_mesh->name<< ", count_apperance=" << count_apperance;
232
233 // get convex hull statistics
234 {
235 mesh_convex_hull = mesh->convex_hull_3d();
236 //mesh_convex_hull.write_binary("convex_hull_debug.stl");
237
238 int face_count = mesh_convex_hull.facets_count();
239 auto its = mesh_convex_hull.its;
240 face_count_hull = mesh_convex_hull.facets_count();
242 areas_hull = Eigen::VectorXf::Zero(face_count);
243 normals_hull = Eigen::MatrixXf::Zero(face_count_hull, 3);
244 normals_hull_quantize = Eigen::MatrixXf::Zero(face_count_hull, 3);
245 for (size_t i = 0; i < face_count; i++)
246 {
247 float area = its.facet_area(i);
248 //We cannot use quantized vector here, the accumulated error will result in bad orientations.
251 areas_hull(i) = area;
252 }
253 }
254 }
TriangleMesh mesh_convex_hull
Definition Orient.cpp:83
std::vector< Vec3f > face_normals_hull
Definition Orient.cpp:93
std::vector< Vec3f > face_normals
Definition Orient.cpp:92
Eigen::MatrixXf normals_hull_quantize
Definition Orient.cpp:84
Vec3f quantize_vec3f(const Vec3f n1)
Definition Orient.cpp:131
Eigen::MatrixXf normals_quantize
Definition Orient.cpp:84
Eigen::MatrixXf normals_hull
Definition Orient.cpp:84
int face_count_hull
Definition Orient.cpp:80
double area(const ExPolygon &poly)
Definition ExPolygon.hpp:511

References Slic3r::area(), areas, areas_hull, face_count_hull, face_normals, face_normals_hull, is_apperance, Slic3r::its_face_normals(), mesh, mesh_convex_hull, normals, normals_hull, normals_hull_quantize, normals_quantize, orient_mesh, and quantize_vec3f().

Referenced by AutoOrienter(), and AutoOrienter().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ process()

Vec3d Slic3r::orientation::AutoOrienter::process ( )
inline
136 {
137 orientations = { { 0,0,-1 } }; // original orientation
138
140
142
144
145 if(progressind)
146 progressind(20);
147
149
150 if (progressind)
151 progressind(30);
152
153 std::unordered_map<Vec3f, CostItems, VecHash> results;
154 BOOST_LOG_TRIVIAL(info) << CostItems::field_names();
155 std::cout << CostItems::field_names() << std::endl;
156 for (int i = 0; i < orientations.size();i++) {
157 Vec3f orientation = -orientations[i];
158
159 project_vertices(orientation);
160
161 auto cost_items = get_features(orientation, params.min_volume);
162
163 float unprintability = target_function(cost_items, params.min_volume);
164
165 results[orientation] = cost_items;
166
167 BOOST_LOG_TRIVIAL(info) << std::fixed << std::setprecision(4) << "orientation:" << orientation.transpose() << ", cost:" << std::fixed << std::setprecision(4) << cost_items.field_values();
168 std::cout << std::fixed << std::setprecision(4) << "orientation:" << orientation.transpose() << ", cost:" << std::fixed << std::setprecision(4) << cost_items.field_values() << std::endl;
169 }
170 if (progressind)
171 progressind(60);
172
173 typedef std::pair<Vec3f, CostItems> PAIR;
174 std::vector<PAIR> results_vector(results.begin(), results.end());
175 sort(results_vector.begin(), results_vector.end(), [](const PAIR& p1, const PAIR& p2) {return p1.second.unprintability < p2.second.unprintability; });
176
177 if (progressind)
178 progressind(80);
179
180 //To avoid flipping, we need to verify if there are orientations with same unprintability.
181 Vec3f n1 = {0, 0, 1};
182 auto best_orientation = results_vector[0].first;
183 size_t best_index = 0;
184
185 for (int i = 1; i< results_vector.size()-1; i++) {
186 if (abs(results_vector[i].second.unprintability - results_vector[0].second.unprintability) < EPSILON && abs(results_vector[0].first.dot(n1)-1) > EPSILON) {
187 if (abs(results_vector[i].first.dot(n1)-1) < EPSILON*EPSILON) {
188 best_orientation = n1;
189 best_index = i;
190 break;
191 }
192 }
193 else {
194 break;
195 }
196
197 }
198
199 // cooling weights are per-orientation, so take them from the orientation actually chosen
200 areas_cooling = results_vector[best_index].second.areas_cooling;
201
202 BOOST_LOG_TRIVIAL(info) << std::fixed << std::setprecision(6) << "best:" << best_orientation.transpose() << ", costs:" << results_vector[0].second.field_values();
203 std::cout << std::fixed << std::setprecision(6) << "best:" << best_orientation.transpose() << ", costs:" << results_vector[0].second.field_values() << std::endl;
204
205 return best_orientation.cast<double>();
206 }
Eigen::VectorXf areas_cooling
Definition Orient.cpp:91
void project_vertices(Vec3f orientation)
Definition Orient.cpp:346
void area_cumulation_accurate(std::vector< Vec3f > &normals_, const Eigen::MatrixXf &quantize_normals_, const Eigen::VectorXf &areas_, int num_directions=10)
Definition Orient.cpp:281
void remove_duplicates(double tol=0.0000001)
remove duplicate orientations
Definition Orient.cpp:326
void add_supplements()
Definition Orient.cpp:311
CostItems get_features(Vec3f orientation, bool min_volume=true)
Definition Orient.cpp:402
float target_function(CostItems &costs, bool min_volume)
Definition Orient.cpp:491
static std::string field_names()
Definition Orient.cpp:63

References add_supplements(), area_cumulation_accurate(), areas, areas_cooling, areas_hull, EPSILON, face_normals, face_normals_hull, Slic3r::orientation::CostItems::field_names(), get_features(), normals_hull_quantize, normals_quantize, orientations, params, progressind, project_vertices(), remove_duplicates(), and target_function().

Referenced by Slic3r::orientation::_orient(), Slic3r::orientation::orient(), and Slic3r::orientation::orient().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ project_vertices()

void Slic3r::orientation::AutoOrienter::project_vertices ( Vec3f orientation)
inline
347 {
348 int face_count = mesh->facets_count();
349 auto its = mesh->its;
350 z_projected.resize(face_count, 3);
351 z_max.resize(face_count, 1);
352 z_median.resize(face_count, 1);
353 z_mean.resize(face_count, 1);
354 for (size_t i = 0; i < face_count; i++)
355 {
356 float z0 = its.get_vertex(i,0).dot(orientation);
357 float z1 = its.get_vertex(i,1).dot(orientation);
358 float z2 = its.get_vertex(i,2).dot(orientation);
359 z_projected(i, 0) = z0;
360 z_projected(i, 1) = z1;
361 z_projected(i, 2) = z2;
362 z_max(i) = MAX3(z0,z1,z2);
363 z_median(i) = MEDIAN3(z0,z1,z2);
364 z_mean(i) = (z0 + z1 + z2) / 3;
365 }
366
367 z_max_hull.resize(mesh_convex_hull.facets_count(), 1);
368 its = mesh_convex_hull.its;
369 for (size_t i = 0; i < z_max_hull.rows(); i++)
370 {
371 float z0 = its.get_vertex(i,0).dot(orientation);
372 float z1 = its.get_vertex(i,1).dot(orientation);
373 float z2 = its.get_vertex(i,2).dot(orientation);
374 z_max_hull(i) = MAX3(z0, z1, z2);
375 }
376 }
#define MAX3(a, b, c)
Definition Orient.cpp:37
#define MEDIAN3(a, b, c)
Definition Orient.cpp:40
Eigen::VectorXf z_median
Definition Orient.cpp:89

References MAX3, MEDIAN3, mesh, mesh_convex_hull, z_max, z_max_hull, z_mean, z_median, and z_projected.

Referenced by process().

Here is the caller graph for this function:

◆ quantize_vec3f()

Vec3f Slic3r::orientation::AutoOrienter::quantize_vec3f ( const Vec3f n1)
inline
131 {
132 return Vec3f(floor(n1(0) * 1000) / 1000, floor(n1(1) * 1000) / 1000, floor(n1(2) * 1000) / 1000);
133 }

Referenced by preprocess().

Here is the caller graph for this function:

◆ remove_duplicates()

void Slic3r::orientation::AutoOrienter::remove_duplicates ( double tol = 0.0000001)
inline

remove duplicate orientations

Parameters
toltolerance. default 0.01 =sin(0.57\degree)
327 {
328 for (auto it = orientations.begin()+1; it < orientations.end(); )
329 {
330 bool duplicate = false;
331 for (auto it_ok = orientations.begin(); it_ok < it; it_ok++)
332 {
333 if (it_ok->isApprox(*it, tol)) {
334 duplicate = true;
335 break;
336 }
337 }
338 const Vec3f all_zero = { 0,0,0 };
339 if (duplicate || it->isApprox(all_zero,tol))
340 it = orientations.erase(it);
341 else
342 it++;
343 }
344 }
void duplicate(Model &model, Slic3r::arrangement::ArrangePolygons &copies, VirtualBedFn vfn)
Definition ModelArrange.cpp:77

References Slic3r::duplicate(), and orientations.

Referenced by process().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ target_function()

float Slic3r::orientation::AutoOrienter::target_function ( CostItems & costs,
bool min_volume )
inline
492 {
493 float cost=0;
494 float bottom = costs.bottom;//std::min(costs.bottom, params.BOTTOM_MAX);
495 float bottom_hull = costs.bottom_hull;// std::min(costs.bottom_hull, params.BOTTOM_HULL_MAX);
496 if (min_volume)
497 {
498 float overhang = costs.overhang / 25;
499 cost = params.TAR_A * (overhang + params.TAR_B) + params.RELATIVE_F * (/*costs.volume/100*/overhang*params.TAR_C + params.TAR_D + params.TAR_LAF * costs.area_laf * params.use_low_angle_face) / (params.TAR_D + params.CONTOUR_F * costs.contour + params.BOTTOM_F * bottom + params.BOTTOM_HULL_F * bottom_hull + params.TAR_E * overhang + params.TAR_PROJ_AREA * costs.area_projected);
500 }
501 else {
502 float overhang = costs.overhang;
503 cost = params.RELATIVE_F * (costs.overhang * params.TAR_C + params.TAR_D + params.TAR_LAF * costs.area_laf * params.use_low_angle_face) / (params.TAR_D + params.CONTOUR_F * costs.contour + params.BOTTOM_F * bottom + params.BOTTOM_HULL_F * bottom_hull + params.TAR_PROJ_AREA * costs.area_projected);
504 }
505 cost += (costs.bottom < params.BOTTOM_MIN) * 100;// +(costs.height_to_bottom_hull_ratio > params.height_to_bottom_hull_ratio_MIN) * 110;
506
507 costs.unprintability = cost;
508
509 return cost;
510 }

References Slic3r::orientation::CostItems::area_laf, Slic3r::orientation::CostItems::area_projected, Slic3r::orientation::CostItems::bottom, Slic3r::orientation::CostItems::bottom_hull, Slic3r::orientation::CostItems::contour, Slic3r::orientation::CostItems::overhang, params, and Slic3r::orientation::CostItems::unprintability.

Referenced by process().

Here is the caller graph for this function:

Member Data Documentation

◆ areas

Eigen::VectorXf Slic3r::orientation::AutoOrienter::areas

◆ areas_cooling

Eigen::VectorXf Slic3r::orientation::AutoOrienter::areas_cooling

Referenced by process().

◆ areas_hull

Eigen::VectorXf Slic3r::orientation::AutoOrienter::areas_hull

Referenced by get_features(), preprocess(), and process().

◆ face_count_hull

int Slic3r::orientation::AutoOrienter::face_count_hull

Referenced by preprocess().

◆ face_normals

std::vector<Vec3f> Slic3r::orientation::AutoOrienter::face_normals

Referenced by preprocess(), and process().

◆ face_normals_hull

std::vector<Vec3f> Slic3r::orientation::AutoOrienter::face_normals_hull

Referenced by preprocess(), and process().

◆ has_cooling_fan

bool Slic3r::orientation::AutoOrienter::has_cooling_fan = false

Referenced by AutoOrienter(), and get_features().

◆ is_apperance

Eigen::VectorXf Slic3r::orientation::AutoOrienter::is_apperance

Referenced by get_features(), and preprocess().

◆ mesh

TriangleMesh* Slic3r::orientation::AutoOrienter::mesh

◆ mesh_convex_hull

TriangleMesh Slic3r::orientation::AutoOrienter::mesh_convex_hull

Referenced by preprocess(), and project_vertices().

◆ normals

Eigen::MatrixXf Slic3r::orientation::AutoOrienter::normals

Referenced by get_features(), and preprocess().

◆ normals_hull

Eigen::MatrixXf Slic3r::orientation::AutoOrienter::normals_hull

Referenced by preprocess().

◆ normals_hull_quantize

Eigen::MatrixXf Slic3r::orientation::AutoOrienter::normals_hull_quantize

Referenced by preprocess(), and process().

◆ normals_quantize

Eigen::MatrixXf Slic3r::orientation::AutoOrienter::normals_quantize

Referenced by preprocess(), and process().

◆ orient_mesh

OrientMesh* Slic3r::orientation::AutoOrienter::orient_mesh = NULL

Referenced by AutoOrienter(), and preprocess().

◆ orientations

std::vector< Vec3f> Slic3r::orientation::AutoOrienter::orientations

◆ params

OrientParams Slic3r::orientation::AutoOrienter::params

◆ progressind

std::function<void(unsigned)> Slic3r::orientation::AutoOrienter::progressind = { }
98{ }; // default empty indicator function

Referenced by AutoOrienter(), and process().

◆ z_max

Eigen::VectorXf Slic3r::orientation::AutoOrienter::z_max

Referenced by get_features(), and project_vertices().

◆ z_max_hull

Eigen::VectorXf Slic3r::orientation::AutoOrienter::z_max_hull

Referenced by get_features(), and project_vertices().

◆ z_mean

Eigen::VectorXf Slic3r::orientation::AutoOrienter::z_mean

Referenced by get_features(), and project_vertices().

◆ z_median

Eigen::VectorXf Slic3r::orientation::AutoOrienter::z_median

Referenced by project_vertices().

◆ z_projected

Eigen::MatrixXf Slic3r::orientation::AutoOrienter::z_projected

Referenced by get_features(), and project_vertices().


The documentation for this class was generated from the following file:
  • /home/runner/work/OrcaSlicer/OrcaSlicer/src/libslic3r/Orient.cpp