Added ModelInstance::world_matrix() method and stl_transform using eigen transform
This commit is contained in:
parent
5f2afad95e
commit
15b1340514
@ -1141,13 +1141,12 @@ sub rotate {
|
|||||||
}
|
}
|
||||||
|
|
||||||
# Let's calculate vector of rotation axis (if we don't have it already)
|
# Let's calculate vector of rotation axis (if we don't have it already)
|
||||||
# The minus is there so that the direction is the same as was established
|
|
||||||
if (defined $axis) {
|
if (defined $axis) {
|
||||||
if ($axis == X) {
|
if ($axis == X) {
|
||||||
$axis_x = -1;
|
$axis_x = 1;
|
||||||
}
|
}
|
||||||
if ($axis == Y) {
|
if ($axis == Y) {
|
||||||
$axis_y = -1;
|
$axis_y = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -173,6 +173,7 @@ extern void stl_mirror_xy(stl_file *stl);
|
|||||||
extern void stl_mirror_yz(stl_file *stl);
|
extern void stl_mirror_yz(stl_file *stl);
|
||||||
extern void stl_mirror_xz(stl_file *stl);
|
extern void stl_mirror_xz(stl_file *stl);
|
||||||
extern void stl_transform(stl_file *stl, float *trafo3x4);
|
extern void stl_transform(stl_file *stl, float *trafo3x4);
|
||||||
|
extern void stl_transform(stl_file *stl, const Eigen::Transform<float, 3, Eigen::Affine, Eigen::DontAlign>& t);
|
||||||
extern void stl_open_merge(stl_file *stl, char *file);
|
extern void stl_open_merge(stl_file *stl, char *file);
|
||||||
extern void stl_invalidate_shared_vertices(stl_file *stl);
|
extern void stl_invalidate_shared_vertices(stl_file *stl);
|
||||||
extern void stl_generate_shared_vertices(stl_file *stl);
|
extern void stl_generate_shared_vertices(stl_file *stl);
|
||||||
|
@ -155,6 +155,47 @@ void stl_transform(stl_file *stl, float *trafo3x4) {
|
|||||||
calculate_normals(stl);
|
calculate_normals(stl);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void stl_transform(stl_file *stl, const Eigen::Transform<float, 3, Eigen::Affine, Eigen::DontAlign>& t)
|
||||||
|
{
|
||||||
|
if (stl->error)
|
||||||
|
return;
|
||||||
|
|
||||||
|
unsigned int vertices_count = 3 * (unsigned int)stl->stats.number_of_facets;
|
||||||
|
if (vertices_count == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
Eigen::MatrixXf src_vertices(3, vertices_count);
|
||||||
|
stl_facet* facet_ptr = stl->facet_start;
|
||||||
|
unsigned int v_id = 0;
|
||||||
|
while (facet_ptr < stl->facet_start + stl->stats.number_of_facets)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < 3; ++i)
|
||||||
|
{
|
||||||
|
::memcpy((void*)src_vertices.col(v_id).data(), (const void*)&facet_ptr->vertex[i], 3 * sizeof(float));
|
||||||
|
++v_id;
|
||||||
|
}
|
||||||
|
facet_ptr += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
Eigen::MatrixXf dst_vertices(3, vertices_count);
|
||||||
|
dst_vertices = t * src_vertices.colwise().homogeneous();
|
||||||
|
|
||||||
|
facet_ptr = stl->facet_start;
|
||||||
|
v_id = 0;
|
||||||
|
while (facet_ptr < stl->facet_start + stl->stats.number_of_facets)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < 3; ++i)
|
||||||
|
{
|
||||||
|
::memcpy((void*)&facet_ptr->vertex[i], (const void*)dst_vertices.col(v_id).data(), 3 * sizeof(float));
|
||||||
|
++v_id;
|
||||||
|
}
|
||||||
|
facet_ptr += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
stl_get_size(stl);
|
||||||
|
calculate_normals(stl);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
stl_rotate_x(stl_file *stl, float angle) {
|
stl_rotate_x(stl_file *stl, float angle) {
|
||||||
int i;
|
int i;
|
||||||
|
@ -672,20 +672,18 @@ void ModelObject::center_around_origin()
|
|||||||
|
|
||||||
// First align to origin on XYZ, then center it on XY.
|
// First align to origin on XYZ, then center it on XY.
|
||||||
Vec3d size = bb.size();
|
Vec3d size = bb.size();
|
||||||
size(2) = 0.;
|
size(2) = 0.0;
|
||||||
Vec3d shift3 = - bb.min - 0.5 * size;
|
Vec3d shift = -bb.min - 0.5 * size;
|
||||||
// Unaligned vector, for the Rotation2D to work on Visual Studio 2013.
|
|
||||||
Eigen::Vector2d shift2 = to_2d(shift3);
|
|
||||||
|
|
||||||
this->translate(shift3);
|
this->translate(shift);
|
||||||
this->origin_translation += shift3;
|
this->origin_translation += shift;
|
||||||
|
|
||||||
if (!this->instances.empty()) {
|
if (!this->instances.empty()) {
|
||||||
for (ModelInstance *i : this->instances) {
|
for (ModelInstance *i : this->instances) {
|
||||||
// apply rotation and scaling to vector as well before translating instance,
|
// apply rotation and scaling to vector as well before translating instance,
|
||||||
// in order to leave final position unaltered
|
// in order to leave final position unaltered
|
||||||
Eigen::Rotation2Dd rot(i->rotation);
|
Vec3d i_shift = i->world_matrix(true) * shift;
|
||||||
i->offset -= rot * shift2 * i->scaling_factor;
|
i->offset -= to_2d(i_shift);
|
||||||
}
|
}
|
||||||
this->invalidate_bounding_box();
|
this->invalidate_bounding_box();
|
||||||
}
|
}
|
||||||
@ -861,12 +859,7 @@ void ModelObject::check_instances_print_volume_state(const BoundingBoxf3& print_
|
|||||||
{
|
{
|
||||||
for (ModelInstance* inst : this->instances)
|
for (ModelInstance* inst : this->instances)
|
||||||
{
|
{
|
||||||
Transform3d m = Transform3d::Identity();
|
BoundingBoxf3 bb = vol->get_convex_hull().transformed_bounding_box(inst->world_matrix());
|
||||||
m.translate(Vec3d(inst->offset(0), inst->offset(1), 0.0));
|
|
||||||
m.rotate(Eigen::AngleAxisd(inst->rotation, Vec3d::UnitZ()));
|
|
||||||
m.scale(inst->scaling_factor);
|
|
||||||
|
|
||||||
BoundingBoxf3 bb = vol->get_convex_hull().transformed_bounding_box(m);
|
|
||||||
|
|
||||||
if (print_volume.contains(bb))
|
if (print_volume.contains(bb))
|
||||||
inst->print_volume_state = ModelInstance::PVS_Inside;
|
inst->print_volume_state = ModelInstance::PVS_Inside;
|
||||||
@ -995,26 +988,17 @@ size_t ModelVolume::split(unsigned int max_extruders)
|
|||||||
|
|
||||||
void ModelInstance::transform_mesh(TriangleMesh* mesh, bool dont_translate) const
|
void ModelInstance::transform_mesh(TriangleMesh* mesh, bool dont_translate) const
|
||||||
{
|
{
|
||||||
mesh->rotate_z(this->rotation); // rotate around mesh origin
|
mesh->transform(world_matrix(dont_translate).cast<float>());
|
||||||
mesh->scale(this->scaling_factor); // scale around mesh origin
|
|
||||||
if (!dont_translate)
|
|
||||||
mesh->translate(this->offset(0), this->offset(1), 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
BoundingBoxf3 ModelInstance::transform_mesh_bounding_box(const TriangleMesh* mesh, bool dont_translate) const
|
BoundingBoxf3 ModelInstance::transform_mesh_bounding_box(const TriangleMesh* mesh, bool dont_translate) const
|
||||||
{
|
{
|
||||||
// Rotate around mesh origin.
|
// Rotate around mesh origin.
|
||||||
double c = cos(this->rotation);
|
TriangleMesh copy(*mesh);
|
||||||
double s = sin(this->rotation);
|
copy.transform(world_matrix(dont_translate, false, true).cast<float>());
|
||||||
BoundingBoxf3 bbox;
|
BoundingBoxf3 bbox = copy.bounding_box();
|
||||||
for (int i = 0; i < mesh->stl.stats.number_of_facets; ++ i) {
|
|
||||||
const stl_facet &facet = mesh->stl.facet_start[i];
|
if (!empty(bbox)) {
|
||||||
for (int j = 0; j < 3; ++ j) {
|
|
||||||
const stl_vertex &v = facet.vertex[j];
|
|
||||||
bbox.merge(Vec3d(c * v(0) - s * v(1), s * v(0) + c * v(1), v(2)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (! empty(bbox)) {
|
|
||||||
// Scale the bounding box uniformly.
|
// Scale the bounding box uniformly.
|
||||||
if (std::abs(this->scaling_factor - 1.) > EPSILON) {
|
if (std::abs(this->scaling_factor - 1.) > EPSILON) {
|
||||||
bbox.min *= this->scaling_factor;
|
bbox.min *= this->scaling_factor;
|
||||||
@ -1031,13 +1015,7 @@ BoundingBoxf3 ModelInstance::transform_mesh_bounding_box(const TriangleMesh* mes
|
|||||||
|
|
||||||
BoundingBoxf3 ModelInstance::transform_bounding_box(const BoundingBoxf3 &bbox, bool dont_translate) const
|
BoundingBoxf3 ModelInstance::transform_bounding_box(const BoundingBoxf3 &bbox, bool dont_translate) const
|
||||||
{
|
{
|
||||||
Transform3d matrix = Transform3d::Identity();
|
return bbox.transformed(world_matrix(dont_translate));
|
||||||
if (!dont_translate)
|
|
||||||
matrix.translate(Vec3d(offset(0), offset(1), 0.0));
|
|
||||||
|
|
||||||
matrix.rotate(Eigen::AngleAxisd(rotation, Vec3d::UnitZ()));
|
|
||||||
matrix.scale(scaling_factor);
|
|
||||||
return bbox.transformed(matrix);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ModelInstance::transform_polygon(Polygon* polygon) const
|
void ModelInstance::transform_polygon(Polygon* polygon) const
|
||||||
@ -1046,4 +1024,20 @@ void ModelInstance::transform_polygon(Polygon* polygon) const
|
|||||||
polygon->scale(this->scaling_factor); // scale around polygon origin
|
polygon->scale(this->scaling_factor); // scale around polygon origin
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Transform3d ModelInstance::world_matrix(bool dont_translate, bool dont_rotate, bool dont_scale) const
|
||||||
|
{
|
||||||
|
Transform3d m = Transform3d::Identity();
|
||||||
|
|
||||||
|
if (!dont_translate)
|
||||||
|
m.translate(Vec3d(offset(0), offset(1), 0.0));
|
||||||
|
|
||||||
|
if (!dont_rotate)
|
||||||
|
m.rotate(Eigen::AngleAxisd(rotation, Vec3d::UnitZ()));
|
||||||
|
|
||||||
|
if (!dont_scale)
|
||||||
|
m.scale(scaling_factor);
|
||||||
|
|
||||||
|
return m;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -243,6 +243,8 @@ public:
|
|||||||
// To be called on an external polygon. It does not translate the polygon, only rotates and scales.
|
// To be called on an external polygon. It does not translate the polygon, only rotates and scales.
|
||||||
void transform_polygon(Polygon* polygon) const;
|
void transform_polygon(Polygon* polygon) const;
|
||||||
|
|
||||||
|
Transform3d world_matrix(bool dont_translate = false, bool dont_rotate = false, bool dont_scale = false) const;
|
||||||
|
|
||||||
bool is_printable() const { return print_volume_state == PVS_Inside; }
|
bool is_printable() const { return print_volume_state == PVS_Inside; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -264,7 +264,7 @@ void TriangleMesh::rotate(float angle, const Vec3d& axis)
|
|||||||
Vec3f axis_norm = axis.cast<float>().normalized();
|
Vec3f axis_norm = axis.cast<float>().normalized();
|
||||||
Transform3f m = Transform3f::Identity();
|
Transform3f m = Transform3f::Identity();
|
||||||
m.rotate(Eigen::AngleAxisf(angle, axis_norm));
|
m.rotate(Eigen::AngleAxisf(angle, axis_norm));
|
||||||
stl_transform(&stl, (float*)m.data());
|
stl_transform(&stl, m);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TriangleMesh::mirror(const Axis &axis)
|
void TriangleMesh::mirror(const Axis &axis)
|
||||||
@ -279,6 +279,11 @@ void TriangleMesh::mirror(const Axis &axis)
|
|||||||
stl_invalidate_shared_vertices(&this->stl);
|
stl_invalidate_shared_vertices(&this->stl);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TriangleMesh::transform(const Transform3f& t)
|
||||||
|
{
|
||||||
|
stl_transform(&stl, t);
|
||||||
|
}
|
||||||
|
|
||||||
void TriangleMesh::align_to_origin()
|
void TriangleMesh::align_to_origin()
|
||||||
{
|
{
|
||||||
this->translate(
|
this->translate(
|
||||||
@ -523,9 +528,9 @@ BoundingBoxf3 TriangleMesh::transformed_bounding_box(const Transform3d& t) const
|
|||||||
src_vertices(0, v_id) = (double)facet_ptr->vertex[i](0);
|
src_vertices(0, v_id) = (double)facet_ptr->vertex[i](0);
|
||||||
src_vertices(1, v_id) = (double)facet_ptr->vertex[i](1);
|
src_vertices(1, v_id) = (double)facet_ptr->vertex[i](1);
|
||||||
src_vertices(2, v_id) = (double)facet_ptr->vertex[i](2);
|
src_vertices(2, v_id) = (double)facet_ptr->vertex[i](2);
|
||||||
|
++v_id;
|
||||||
}
|
}
|
||||||
facet_ptr += 1;
|
facet_ptr += 1;
|
||||||
++v_id;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -48,6 +48,7 @@ public:
|
|||||||
void mirror_x() { this->mirror(X); }
|
void mirror_x() { this->mirror(X); }
|
||||||
void mirror_y() { this->mirror(Y); }
|
void mirror_y() { this->mirror(Y); }
|
||||||
void mirror_z() { this->mirror(Z); }
|
void mirror_z() { this->mirror(Z); }
|
||||||
|
void transform(const Transform3f& t);
|
||||||
void align_to_origin();
|
void align_to_origin();
|
||||||
void rotate(double angle, Point* center);
|
void rotate(double angle, Point* center);
|
||||||
TriangleMeshPtrs split() const;
|
TriangleMeshPtrs split() const;
|
||||||
|
@ -1051,6 +1051,8 @@ void GLGizmoFlatten::on_render(const BoundingBoxf3& box) const
|
|||||||
::glPopMatrix();
|
::glPopMatrix();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
::glDisable(GL_BLEND);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GLGizmoFlatten::on_render_for_picking(const BoundingBoxf3& box) const
|
void GLGizmoFlatten::on_render_for_picking(const BoundingBoxf3& box) const
|
||||||
@ -1278,9 +1280,7 @@ bool GLGizmoFlatten::is_plane_update_necessary() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
Vec3d GLGizmoFlatten::get_flattening_normal() const {
|
Vec3d GLGizmoFlatten::get_flattening_normal() const {
|
||||||
Transform3d m = Transform3d::Identity();
|
Vec3d normal = m_model_object->instances.front()->world_matrix().matrix().block(0, 0, 3, 3) * m_normal;
|
||||||
m.rotate(Eigen::AngleAxisd(-m_model_object->instances.front()->rotation, Vec3d::UnitZ()));
|
|
||||||
Vec3d normal = m * m_normal;
|
|
||||||
m_normal = Vec3d::Zero();
|
m_normal = Vec3d::Zero();
|
||||||
return normal;
|
return normal;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user