OrcaSlicer latest
OrcaSlicer
Loading...
Searching...
No Matches
Slic3r::orientation Namespace Reference

Classes

struct  CostItems
class  AutoOrienter
struct  OrientMesh
 Input/Output structure for the orient() function. The mesh field will not be modified during orientment. Instead, the translation and rotation fields will mark the needed transformation for the polygon to be in the orientd position. These can also be set to an initial offset and rotation. More...
struct  OrientParams

Typedefs

using OrientMeshs = std::vector<OrientMesh>

Functions

void _orient (OrientMeshs &meshs_, const OrientParams &params, std::function< void(unsigned, std::string)> progressfn, std::function< bool()> stopfn)
void orient (OrientMeshs &items, const OrientMeshs &excludes, const OrientParams &params={})
 Orients the input polygons.
void orient (ModelObject *obj)
void orient (ModelInstance *instance)
void orient_for_cooling (TriangleMesh &mesh, const FanDirection &fan_dir)

Variables

static const constexpr int UNORIENTD = -1
 A logical bed representing an object not being orientd. Either the orient has not yet successfully run on this OrientPolygon or it could not fit the object due to overly large size or invalid geometry.

Typedef Documentation

◆ OrientMeshs

Function Documentation

◆ _orient()

void Slic3r::orientation::_orient ( OrientMeshs & meshs_,
const OrientParams & params,
std::function< void(unsigned, std::string)> progressfn,
std::function< bool()> stopfn )
578{
579 if (!params.parallel)
580 {
581 for (size_t i = 0; i != meshs_.size(); ++i) {
582 auto& mesh_ = meshs_[i];
583 progressfn(i, mesh_.name);
584 //auto progressfn_i = [&](unsigned cnt) {progressfn(cnt, "Orienting " + mesh_.name); };
585 AutoOrienter orienter(&mesh_, params, /*progressfn_i*/{}, stopfn);
586 mesh_.orientation = orienter.process();
587 Geometry::rotation_from_two_vectors(mesh_.orientation, { 0,0,1 }, mesh_.axis, mesh_.angle, &mesh_.rotation_matrix);
588 BOOST_LOG_TRIVIAL(info) << std::fixed << std::setprecision(3) << "v,phi: " << mesh_.axis.transpose() << ", " << mesh_.angle;
589 //flush_logs();
590 }
591 }
592 else {
593 tbb::parallel_for(tbb::blocked_range<size_t>(0, meshs_.size()), [&meshs_, &params, progressfn, stopfn](const tbb::blocked_range<size_t>& range) {
594 for (size_t i = range.begin(); i != range.end(); ++i) {
595 auto& mesh_ = meshs_[i];
596 progressfn(i, mesh_.name);
597 AutoOrienter orienter(&mesh_, params, {}, stopfn);
598 mesh_.orientation = orienter.process();
599 Geometry::rotation_from_two_vectors(mesh_.orientation, { 0,0,1 }, mesh_.axis, mesh_.angle, &mesh_.rotation_matrix);
600 mesh_.euler_angles = Geometry::extract_euler_angles(mesh_.rotation_matrix);
601 // find cool direction
602 if (mesh_.has_cooling_fan)
603 {
604 mesh_.orientation_vertical = orienter.find_cooling_direction2(mesh_.euler_angles, orienter.areas_cooling, mesh_.mesh);
605 BOOST_LOG_TRIVIAL(info) << "cooling direction: " << mesh_.orientation_vertical.transpose() << "\n";
606 Geometry::rotation_from_two_vectors(mesh_.orientation_vertical, mesh_.cooling_direction, mesh_.axis_vertical, mesh_.angle_vertical, &mesh_.rotation_matrix_vertical);
607 }
608 BOOST_LOG_TRIVIAL(debug) << "rotation_from_two_vectors: " << mesh_.orientation << "; " << mesh_.axis << "; " << mesh_.angle << "; euler: " << mesh_.euler_angles.transpose();
609 }});
610 }
611}
Definition Orient.cpp:78
Vec3d process()
Definition Orient.cpp:135
void rotation_from_two_vectors(Vec3d from, Vec3d to, Vec3d &rotation_axis, double &phi, Matrix3d *rotation_matrix)
Definition Geometry.cpp:416
auto range(Cont &&cont)
Definition libslic3r.h:405
bool parallel
Allow parallel execution.
Definition Orient.hpp:96

References Slic3r::orientation::OrientParams::parallel, Slic3r::orientation::AutoOrienter::process(), Slic3r::range(), and Slic3r::Geometry::rotation_from_two_vectors().

Referenced by orient().

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

◆ orient() [1/3]

void Slic3r::orientation::orient ( ModelInstance * instance)
639{
640 auto m = instance->get_object()->mesh();
641 AutoOrienter orienter(&m);
642 Vec3d orientation = orienter.process();
643 Vec3d axis;
644 double angle;
645 Matrix3d rotation_matrix;
646 Geometry::rotation_from_two_vectors(orientation, { 0,0,1 }, axis, angle, &rotation_matrix);
647 instance->rotate(rotation_matrix);
648}
ModelObject * get_object() const
Definition Model.hpp:1445
void rotate(Matrix3d rotation_matrix)
Definition Model.hpp:1483
TriangleMesh mesh() const
Definition Model.cpp:1675
Definition Orient.cpp:47
Eigen::Matrix< double, 3, 1, Eigen::DontAlign > Vec3d
Definition Point.hpp:68
double angle(const Eigen::MatrixBase< Derived > &v1, const Eigen::MatrixBase< Derived2 > &v2)
Definition Point.hpp:138
Eigen::Matrix< double, 3, 3, Eigen::DontAlign > Matrix3d
Definition Point.hpp:86

References Slic3r::angle(), Slic3r::ModelInstance::get_object(), Slic3r::ModelObject::mesh(), Slic3r::orientation::AutoOrienter::process(), Slic3r::ModelInstance::rotate(), and Slic3r::Geometry::rotation_from_two_vectors().

Here is the call graph for this function:

◆ orient() [2/3]

void Slic3r::orientation::orient ( ModelObject * obj)
626{
627 auto m = obj->mesh();
628 AutoOrienter orienter(&m);
629 Vec3d orientation = orienter.process();
630 Vec3d axis;
631 double angle;
633
634 obj->rotate(angle, axis);
635 obj->ensure_on_bed();
636}
void ensure_on_bed(bool allow_negative_z=false)
Definition Model.cpp:1896
void rotate(double angle, Axis axis)
Definition Model.cpp:1958

References Slic3r::angle(), Slic3r::ModelObject::ensure_on_bed(), Slic3r::ModelObject::mesh(), Slic3r::orientation::AutoOrienter::process(), Slic3r::ModelObject::rotate(), and Slic3r::Geometry::rotation_from_two_vectors().

Here is the call graph for this function:

◆ orient() [3/3]

void Slic3r::orientation::orient ( OrientMeshs & items,
const OrientMeshs & excludes,
const OrientParams & params = {} )

Orients the input polygons.

Parameters
itemsInput vector of OrientMeshs. The transformation, rotation and bin_idx fields will be changed after the call finished and can be used to apply the result on the input polygon.
616{
617
618 auto &cfn = params.stopcondition;
619 auto &pri = params.progressind;
620
621 _orient(arrangables, params, pri, cfn);
622
623}
void _orient(OrientMeshs &meshs_, const OrientParams &params, std::function< void(unsigned, std::string)> progressfn, std::function< bool()> stopfn)
Definition Orient.cpp:574
std::function< bool(void)> stopcondition
A predicate returning true if abort is needed.
Definition Orient.hpp:103
std::function< void(unsigned, std::string)> progressind
Progress indicator callback called when an object gets packed. The unsigned argument is the number of...
Definition Orient.hpp:100

References _orient(), Slic3r::orientation::OrientParams::progressind, and Slic3r::orientation::OrientParams::stopcondition.

Referenced by Slic3r::GUI::OrientJob::process(), and Slic3r::CLI::run().

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

◆ orient_for_cooling()

void Slic3r::orientation::orient_for_cooling ( TriangleMesh & mesh,
const FanDirection & fan_dir )
651{
652 Vec3f best_direction{ 0, 0, 0 };
653 Vec3f machine_cool_dir{ 0, 0, 0 };
654
655 if (fan_dir == FanDirection::fdUndefine)
656 {
657 // no cooling fan, do not rotate along z axis
658 return;
659 }
660 else if (fan_dir == FanDirection::fdRight)
661 {
662 machine_cool_dir = { 1, 0, 0 }; // the cooling fan is on the right side.
663 }
664 else
665 {
666 // the cooling fan is on the left side or both side has cooling fans
667 machine_cool_dir = { -1, 0, 0 };
668 }
669
670 // 1. filter the overhang_areas
671 int nfaces = mesh.facets_count();
672 auto face_normals = its_face_normals(mesh.its);
673
674 Eigen::VectorXf normal_projection(nfaces, 1);
675 for (auto i = 0; i < nfaces; i++)
676 {
677 normal_projection(i) = face_normals[i].dot(Vec3f(0, 0, 1));
678 }
679 float angle_thres_high = -0.6427f;
680 float angle_thres_low = -0.97f;
681 // 2. compute the weighted overhang faces area
682 Eigen::VectorXf weighted_areas = Eigen::VectorXf::Zero(nfaces);
683 for (int i = 0; i < nfaces; i++)
684 {
685 if (normal_projection(i) < angle_thres_high && normal_projection(i) > angle_thres_low)
686 {
687 weighted_areas(i) = mesh.its.facet_area(i) * (1.0f - normal_projection(i));
688 }
689 }
690
691 const size_t sample_nums = 180;
692 std::vector<Vec3f> cool_dirs;
693 for (size_t i = 0; i < sample_nums; i++)
694 {
695 float angle_deg = i * (360.0 / sample_nums);
696 float angle_rad = angle_deg * (PI / 180.0);
697 cool_dirs.push_back(Vec3f{ std::cos(angle_rad), std::sin(angle_rad), 0 });
698 }
699
700 // 3. accumulate the weighted projected overhang area, find the max weighted project area direction
701 float overhang_projected_max = 0.f;
702 float overhang_projected_origin = 0.f;
703 for (auto cool_dir : cool_dirs)
704 {
705 float overhang_projected_tmp = 0.f;
706 for (size_t i = 0; i < nfaces; i++)
707 {
708 float cool_dir_projection = face_normals[i].dot(cool_dir);
709 if (weighted_areas[i] > 0 && cool_dir_projection > 0)
710 {
711 overhang_projected_tmp += weighted_areas[i] * cool_dir_projection;
712 }
713 }
714 if (overhang_projected_tmp > overhang_projected_max)
715 {
716 overhang_projected_max = overhang_projected_tmp;
717 best_direction = cool_dir;
718 }
719 if (cool_dir.dot(machine_cool_dir) > 0.999)
720 {
721 overhang_projected_origin = overhang_projected_tmp;
722 }
723 }
724
725 // The symmetric model has similar overhang projection at all angles, so Z-axis rotation is unnecessary.
726 if (std::abs(overhang_projected_origin - overhang_projected_max) < 1.0f)
727 {
728 return;
729 }
730
731 // rotate the mesh
732 Vec3d axis;
733 double angle;
734 Matrix3d rotation_matrix;
735 Geometry::rotation_from_two_vectors(best_direction.cast<double>(), machine_cool_dir.cast<double>(), axis, angle, &rotation_matrix);
736 mesh.rotate(angle, axis);
737}
indexed_triangle_set its
Definition TriangleMesh.hpp:164
void rotate(float angle, const Axis &axis)
Definition TriangleMesh.cpp:302
size_t facets_count() const
Definition TriangleMesh.hpp:145
static constexpr double PI
Definition libslic3r.h:81
Eigen::Matrix< float, 3, 1, Eigen::DontAlign > Vec3f
Definition Point.hpp:65
std::vector< Vec3f > its_face_normals(const indexed_triangle_set &its)
Definition TriangleMesh.cpp:1625
@ fdUndefine
Definition PrintConfig.hpp:532
@ fdRight
Definition PrintConfig.hpp:534

References Slic3r::angle(), Slic3r::TriangleMesh::facets_count(), Slic3r::fdRight, Slic3r::fdUndefine, Slic3r::TriangleMesh::its, Slic3r::its_face_normals(), orient_for_cooling(), PI, Slic3r::TriangleMesh::rotate(), and Slic3r::Geometry::rotation_from_two_vectors().

Referenced by Slic3r::GUI::ObjectList::load_shape_object(), and orient_for_cooling().

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

Variable Documentation

◆ UNORIENTD

const constexpr int Slic3r::orientation::UNORIENTD = -1
staticconstexpr

A logical bed representing an object not being orientd. Either the orient has not yet successfully run on this OrientPolygon or it could not fit the object due to overly large size or invalid geometry.