Auto-orientation

This commit is contained in:
utkabobr
2025-03-02 22:05:22 +03:00
parent 540f8f6c7c
commit 7f9b1b908a
12 changed files with 499 additions and 17 deletions
+67 -7
View File
@@ -5,6 +5,7 @@
#include <boost/geometry/index/rtree.hpp>
#include <tbb/parallel_for.h>
#include "bbl_utils.hpp"
#include "libslic3r/AABBMesh.hpp"
#if defined(_MSC_VER) && defined(__clang__)
#define BOOST_NO_CXX17_HDR_STRING_VIEW
@@ -196,7 +197,61 @@ namespace Slic3r {
return best_orientation.cast<double>();
}
#define BBOX_OFFSET 2.0
void preprocess() {
float m_sample_interval = 0.5;
AABBMesh indexed_mesh(mesh->its, true);
BoundingBoxf3 bbox = mesh->bounding_box();
bbox.offset(BBOX_OFFSET);
std::vector<FaceProperty> properties(mesh->its.indices.size());
std::unordered_set<size_t> hit_face_indices;
// x-axis rays
for (double y = bbox.min.y(); y < bbox.max.y(); y += m_sample_interval) {
for (double z = bbox.min.z(); z < bbox.max.z(); z += m_sample_interval) {
auto hit_result = indexed_mesh.query_ray_hit({ bbox.min.x(), y, z }, { 1.0, 0.0, 0.0 });
if (hit_result.is_hit())
hit_face_indices.insert(hit_result.face());
hit_result = indexed_mesh.query_ray_hit({ bbox.max.x(), y, z }, { -1.0, 0.0, 0.0 });
if (hit_result.is_hit())
hit_face_indices.insert(hit_result.face());
}
}
// y-axis rays
for (double x = bbox.min.x(); x < bbox.max.x(); x += m_sample_interval) {
for (double z = bbox.min.z(); z < bbox.max.z(); z += m_sample_interval) {
auto hit_result = indexed_mesh.query_ray_hit({ x, bbox.min.y(), z }, { 0.0, 1.0, 0.0 });
if (hit_result.is_hit())
hit_face_indices.insert(hit_result.face());
hit_result = indexed_mesh.query_ray_hit({ x, bbox.max.y(), z }, { 0.0, -1.0, 0.0 });
if (hit_result.is_hit())
hit_face_indices.insert(hit_result.face());
}
}
// z-axis rays
for (double x = bbox.min.x(); x < bbox.max.x(); x += m_sample_interval) {
for (double y = bbox.min.y(); y < bbox.max.y(); y += m_sample_interval) {
auto hit_result = indexed_mesh.query_ray_hit({ x, y, bbox.min.z() }, { 0.0, 0.0, 1.0 });
if (hit_result.is_hit())
hit_face_indices.insert(hit_result.face());
hit_result = indexed_mesh.query_ray_hit({ x, y, bbox.max.z() }, { 0.0, 0.0, -1.0 });
if (hit_result.is_hit())
hit_face_indices.insert(hit_result.face());
}
}
for (size_t facet_idx : hit_face_indices) {
uint32_t vol_facet_idx = facet_idx;
properties[vol_facet_idx].type = EnumFaceTypes::eExteriorAppearance;
}
int count_apperance = 0;
{
int face_count = mesh->facets_count();
@@ -211,7 +266,7 @@ namespace Slic3r {
normals.row(i) = face_normals[i];
normals_quantize.row(i) = quantize_vec3f(face_normals[i]);
areas(i) = area;
// TODO: Fix this // is_apperance(i) = (its.get_property(i).type == EnumFaceTypes::eExteriorAppearance);
is_apperance(i) = (properties[i].type == EnumFaceTypes::eExteriorAppearance);
count_apperance += (is_apperance(i) == 1);
}
}
@@ -585,12 +640,17 @@ namespace Slic3r {
auto m = obj->mesh();
AutoOrienter orienter(&m);
Vec3d orientation = orienter.process();
Vec3d axis;
double angle;
Geometry::rotation_from_two_vectors(orientation, {0, 0, 1}, axis, angle, nullptr);
obj->rotate(angle, axis);
obj->ensure_on_bed();
orientation *= -1;
ModelVolumePtrs ptrs = obj->volumes;
for (int i = 0, c = ptrs.size(); i < c; i++) {
auto vol = ptrs[i];
const Geometry::Transformation& old_transform = vol->get_transformation();
const Vec3d tnormal = orientation;
const Transform3d rotation_matrix = Transform3d(Eigen::Quaterniond().setFromTwoVectors(tnormal, -Vec3d::UnitZ()));
vol->set_transformation(old_transform.get_offset_matrix() * rotation_matrix * old_transform.get_matrix_no_offset());
}
obj->invalidate_bounding_box();
obj->ensure_on_bed(false);
}
void orient(ModelInstance *instance) {
+49
View File
@@ -11,6 +11,55 @@ typedef enum {
eMaxNumFaceTypes
}EnumFaceTypes;
struct FaceProperty
{ // triangle face property
EnumFaceTypes type;
double area;
// stl_normal normal;
std::string to_string() const
{
std::string str;
// skip normal type facet to improve performance
if (type > eNormal && type < eMaxNumFaceTypes) {
str += std::to_string(type);
if (area != 0.f)
str += " " + std::to_string(area);
}
return str;
}
void from_string(const std::string& str)
{
std::string val_str, area_str;
do {
if (str.empty())
break;
this->type = (EnumFaceTypes)std::atoi(str.c_str());
if (this->type <= eNormal || this->type >= eMaxNumFaceTypes)
break;
size_t type_end_pos = str.find(" ");
if (type_end_pos == std::string::npos) {
this->area = 0.f;
return;
}
area_str = str.substr(type_end_pos + 1);
if (!area_str.empty())
this->area = std::atof(area_str.c_str());
else
this->area = 0.f;
return;
} while (0);
this->type = eNormal;
this->area = 0.f;
}
};
namespace Slic3r {
namespace Geometry {
void rotation_from_two_vectors(Vec3d& from, Vec3d to, Vec3d& rotation_axis, double& phi, Matrix3d* rotation_matrix) {
@@ -12,6 +12,7 @@
#include "libslic3r/Arrange.hpp"
#include "libslic3r/AABBMesh.hpp"
#include "libslic3r/Geometry/ConvexHull.hpp"
#include "bbl/Orient.hpp"
#include "Viewer.hpp"
#include "GLModel.hpp"
@@ -810,6 +811,12 @@ extern "C" {
return arr;
}
JNIEXPORT void JNICALL Java_ru_ytkab0bp_slicebeam_slic3r_Native_model_1auto_1orient(JNIEnv* env, jclass, jlong ptr, jint i) {
ModelRef* model = (ModelRef*) (intptr_t) ptr;
ModelObject* obj = model->model.objects[i];
orientation::orient(obj);
}
JNIEXPORT jlong JNICALL Java_ru_ytkab0bp_slicebeam_slic3r_Native_model_1slice(JNIEnv* env, jclass, jlong ptr, jstring configPath, jstring path, jobject listener) {
try {
ModelRef* model = (ModelRef*) (intptr_t) ptr;