mirror of
https://github.com/Dark98/SliceBeam.git
synced 2026-07-06 08:39:05 +00:00
Auto-orientation
This commit is contained in:
@@ -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) {
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user