mirror of
https://git.mirrors.martin98.com/https://github.com/slic3r/Slic3r.git
synced 2025-08-05 16:20:49 +08:00
Creation of Trafo Class
This commit is contained in:
parent
56175357be
commit
dde72b12ef
332
xs/src/libslic3r/TransformationMatrix.cpp
Normal file
332
xs/src/libslic3r/TransformationMatrix.cpp
Normal file
@ -0,0 +1,332 @@
|
||||
//#define Testumgebung
|
||||
//#include <iostream>
|
||||
//enum Axis { X = 0, Y, Z };
|
||||
//
|
||||
//void CONFESS(std::string content) {};
|
||||
//
|
||||
//
|
||||
#include "TransformationMatrix.hpp"
|
||||
#include <cmath>
|
||||
#include <math.h>
|
||||
|
||||
#ifdef SLIC3R_DEBUG
|
||||
#include "SVG.hpp"
|
||||
#endif
|
||||
|
||||
namespace Slic3r {
|
||||
|
||||
TransformationMatrix::TransformationMatrix()
|
||||
{
|
||||
*this = mat_eye();
|
||||
}
|
||||
|
||||
TransformationMatrix::TransformationMatrix(float m11, float m12, float m13, float m14, float m21, float m22, float m23, float m24, float m31, float m32, float m33, float m34)
|
||||
{
|
||||
this->m11 = m11; this->m12 = m12; this->m13 = m13; this->m14 = m14;
|
||||
this->m21 = m21; this->m22 = m22; this->m23 = m23; this->m21 = m24;
|
||||
this->m31 = m31; this->m32 = m32; this->m33 = m33; this->m34 = m34;
|
||||
}
|
||||
#ifndef Testumgebung
|
||||
TransformationMatrix::TransformationMatrix(std::vector<float> &entries_row_maj)
|
||||
{
|
||||
if (entries_row_maj.size() != 12)
|
||||
{
|
||||
*this = mat_eye();
|
||||
CONFESS("Invalid number of entries when initalizing TransformationMatrix. Vector length must be 12.");
|
||||
return;
|
||||
}
|
||||
m11 = entries_row_maj[0]; m12 = entries_row_maj[1]; m13 = entries_row_maj[2]; m14 = entries_row_maj[3];
|
||||
m21 = entries_row_maj[4]; m22 = entries_row_maj[5]; m23 = entries_row_maj[6]; m24 = entries_row_maj[7];
|
||||
m31 = entries_row_maj[8]; m32 = entries_row_maj[9]; m33 = entries_row_maj[10]; m34 = entries_row_maj[11];
|
||||
}
|
||||
#endif
|
||||
TransformationMatrix::TransformationMatrix(const TransformationMatrix &other)
|
||||
{
|
||||
this->m11 = other.m11; this->m12 = other.m12; this->m13 = other.m13; this->m14 = other.m14;
|
||||
this->m11 = other.m11; this->m22 = other.m22; this->m23 = other.m23; this->m24 = other.m24;
|
||||
this->m31 = other.m31; this->m32 = other.m32; this->m33 = other.m33; this->m34 = other.m34;
|
||||
}
|
||||
|
||||
TransformationMatrix& TransformationMatrix::operator= (TransformationMatrix other)
|
||||
{
|
||||
this->swap(other);
|
||||
return *this;
|
||||
}
|
||||
|
||||
void
|
||||
TransformationMatrix::swap(TransformationMatrix &other)
|
||||
{
|
||||
std::swap(this->m11, other.m11); std::swap(this->m12, other.m12);
|
||||
std::swap(this->m13, other.m13); std::swap(this->m14, other.m14);
|
||||
std::swap(this->m21, other.m21); std::swap(this->m22, other.m22);
|
||||
std::swap(this->m23, other.m23); std::swap(this->m24, other.m24);
|
||||
std::swap(this->m31, other.m31); std::swap(this->m32, other.m32);
|
||||
std::swap(this->m33, other.m33); std::swap(this->m34, other.m34);
|
||||
}
|
||||
|
||||
float* TransformationMatrix::matrix3x4f()
|
||||
{
|
||||
float mat[12];
|
||||
mat[0] = this->m11; mat[1] = this->m12; mat[2] = this->m13; mat[3] = this->m14;
|
||||
mat[4] = this->m21; mat[5] = this->m22; mat[6] = this->m23; mat[7] = this->m24;
|
||||
mat[8] = this->m31; mat[9] = this->m32; mat[10] = this->m33; mat[11] = this->m34;
|
||||
return mat;
|
||||
}
|
||||
|
||||
float TransformationMatrix::determinante()
|
||||
{
|
||||
// translation elements don't influence the determinante
|
||||
// because of the 0s on the other side of main diagonal
|
||||
return m11*(m22*m33 - m23*m32) - m12*(m21*m33 - m23*m31) + m13*(m21*m32 - m31*m22);
|
||||
}
|
||||
|
||||
bool TransformationMatrix::inverse(TransformationMatrix* inverse)
|
||||
{
|
||||
// from http://mathworld.wolfram.com/MatrixInverse.html
|
||||
// and https://math.stackexchange.com/questions/152462/inverse-of-transformation-matrix
|
||||
TransformationMatrix mat;
|
||||
float det = this->determinante();
|
||||
if (abs(det) < 1e-9)
|
||||
return false;
|
||||
float fac = 1.0f / det;
|
||||
|
||||
mat.m11 = fac*(this->m22*this->m33 - this->m23*this->m32);
|
||||
mat.m12 = fac*(this->m13*this->m32 - this->m12*this->m33);
|
||||
mat.m13 = fac*(this->m12*this->m23 - this->m13*this->m22);
|
||||
mat.m21 = fac*(this->m23*this->m31 - this->m21*this->m33);
|
||||
mat.m22 = fac*(this->m11*this->m33 - this->m13*this->m31);
|
||||
mat.m23 = fac*(this->m13*this->m21 - this->m11*this->m23);
|
||||
mat.m31 = fac*(this->m21*this->m32 - this->m22*this->m31);
|
||||
mat.m32 = fac*(this->m12*this->m31 - this->m11*this->m32);
|
||||
mat.m33 = fac*(this->m11*this->m22 - this->m12*this->m21);
|
||||
|
||||
mat.m14 = -(mat.m11*this->m14 + mat.m12*this->m24 + mat.m13*this->m34);
|
||||
mat.m24 = -(mat.m21*this->m14 + mat.m22*this->m24 + mat.m23*this->m34);
|
||||
mat.m34 = -(mat.m31*this->m14 + mat.m32*this->m24 + mat.m33*this->m34);
|
||||
|
||||
inverse = &mat;
|
||||
return true;
|
||||
}
|
||||
|
||||
void TransformationMatrix::translate(float x, float y, float z)
|
||||
{
|
||||
TransformationMatrix mat = mat_translation(x, y, z);
|
||||
this->multiplyLeft(mat);
|
||||
}
|
||||
|
||||
void TransformationMatrix::scale(float factor)
|
||||
{
|
||||
this->scale(factor, factor, factor);
|
||||
}
|
||||
|
||||
void TransformationMatrix::scale(float x, float y, float z)
|
||||
{
|
||||
TransformationMatrix mat = mat_scale(x, y, z);
|
||||
this->multiplyLeft(mat);
|
||||
}
|
||||
|
||||
void TransformationMatrix::mirror(const Axis &axis)
|
||||
{
|
||||
TransformationMatrix mat = mat_mirror(axis);
|
||||
this->multiplyLeft(mat);
|
||||
}
|
||||
|
||||
void TransformationMatrix::mirror(const Pointf3 & normal)
|
||||
{
|
||||
TransformationMatrix mat = mat_mirror(normal);
|
||||
this->multiplyLeft(mat);
|
||||
}
|
||||
|
||||
void TransformationMatrix::rotate(float angle_rad, const Axis & axis)
|
||||
{
|
||||
TransformationMatrix mat = mat_rotation(angle_rad, axis);
|
||||
this->multiplyLeft(mat);
|
||||
}
|
||||
|
||||
void TransformationMatrix::rotate(float angle_rad, const Pointf3 & axis)
|
||||
{
|
||||
TransformationMatrix mat = mat_rotation(angle_rad, axis);
|
||||
this->multiplyLeft(mat);
|
||||
}
|
||||
|
||||
void TransformationMatrix::rotate(float q1, float q2, float q3, float q4)
|
||||
{
|
||||
TransformationMatrix mat = mat_rotation(q1, q2, q3, q4);
|
||||
this->multiplyLeft(mat);
|
||||
}
|
||||
|
||||
void TransformationMatrix::multiplyLeft(TransformationMatrix &left)
|
||||
{
|
||||
*this = multiply(left, *this);
|
||||
}
|
||||
|
||||
void TransformationMatrix::multiplyRight(TransformationMatrix &right)
|
||||
{
|
||||
*this = multiply(*this, right);
|
||||
}
|
||||
|
||||
TransformationMatrix TransformationMatrix::multiply(const TransformationMatrix &left, const TransformationMatrix &right)
|
||||
{
|
||||
TransformationMatrix trafo;
|
||||
|
||||
trafo.m11 = left.m11*right.m11 + left.m12*right.m21 + left.m13 + right.m31;
|
||||
trafo.m12 = left.m11*right.m12 + left.m12*right.m22 + left.m13 + right.m32;
|
||||
trafo.m13 = left.m11*right.m13 + left.m12*right.m23 + left.m13 + right.m33;
|
||||
trafo.m14 = left.m11*right.m14 + left.m12*right.m24 + left.m13 + right.m34 + left.m14;
|
||||
|
||||
trafo.m21 = left.m21*right.m11 + left.m22*right.m21 + left.m23 + right.m31;
|
||||
trafo.m22 = left.m21*right.m12 + left.m22*right.m22 + left.m23 + right.m32;
|
||||
trafo.m23 = left.m21*right.m13 + left.m22*right.m23 + left.m23 + right.m33;
|
||||
trafo.m24 = left.m21*right.m14 + left.m22*right.m24 + left.m23 + right.m34 + left.m24;
|
||||
|
||||
trafo.m31 = left.m31*right.m11 + left.m32*right.m21 + left.m33 + right.m31;
|
||||
trafo.m32 = left.m31*right.m12 + left.m32*right.m22 + left.m33 + right.m32;
|
||||
trafo.m33 = left.m31*right.m13 + left.m32*right.m23 + left.m33 + right.m33;
|
||||
trafo.m34 = left.m31*right.m14 + left.m32*right.m24 + left.m33 + right.m34 + left.m34;
|
||||
|
||||
return trafo;
|
||||
}
|
||||
|
||||
TransformationMatrix TransformationMatrix::mat_eye()
|
||||
{
|
||||
return TransformationMatrix(
|
||||
1.0f, 0.0f, 0.0f, 0.0f,
|
||||
0.0f, 1.0f, 0.0f, 0.0f,
|
||||
0.0f, 0.0f, 1.0f, 0.0f);
|
||||
}
|
||||
|
||||
TransformationMatrix TransformationMatrix::mat_translation(float x, float y, float z)
|
||||
{
|
||||
return TransformationMatrix(
|
||||
1.0f, 0.0f, 0.0f, x,
|
||||
0.0f, 1.0f, 0.0f, y,
|
||||
0.0f, 0.0f, 1.0f, z);
|
||||
}
|
||||
|
||||
TransformationMatrix TransformationMatrix::mat_scale(float x, float y, float z)
|
||||
{
|
||||
return TransformationMatrix(
|
||||
x, 0.0f, 0.0f, 0.0f,
|
||||
0.0f, y, 0.0f, 0.0f,
|
||||
0.0f, 0.0f, z, 0.0f);
|
||||
}
|
||||
|
||||
TransformationMatrix TransformationMatrix::mat_scale(float scale)
|
||||
{
|
||||
return TransformationMatrix::mat_scale(scale, scale, scale);
|
||||
}
|
||||
|
||||
TransformationMatrix TransformationMatrix::mat_rotation(float angle_rad, const Axis &axis)
|
||||
{
|
||||
float s = sin(angle_rad);
|
||||
float c = cos(angle_rad);
|
||||
TransformationMatrix mat; // For RVO
|
||||
switch (axis)
|
||||
{
|
||||
case X:
|
||||
mat = TransformationMatrix(
|
||||
1.0f, 0.0f, 0.0f, 0.0f,
|
||||
0.0f, c, s, 0.0f,
|
||||
0.0f, -s, c, 0.0f);
|
||||
break;
|
||||
case Y:
|
||||
mat = TransformationMatrix(
|
||||
c, 0.0f, -s, 0.0f,
|
||||
0.0f, 1.0f, 0.0f, 0.0f,
|
||||
s, 0.0f, c, 0.0f);
|
||||
break;
|
||||
case Z:
|
||||
mat = TransformationMatrix(
|
||||
c, s, 0.0f, 0.0f,
|
||||
-s, c, 0.0f, 0.0f,
|
||||
0.0f, 0.0f, 1.0f, 0.0f);
|
||||
break;
|
||||
default:
|
||||
CONFESS("Invalid Axis supplied to TransformationMatrix::mat_rotation");
|
||||
mat = TransformationMatrix();
|
||||
break;
|
||||
}
|
||||
return mat;
|
||||
}
|
||||
|
||||
TransformationMatrix TransformationMatrix::mat_rotation(float q1, float q2, float q3, float q4)
|
||||
{
|
||||
float factor = q1*q1 + q2*q2 + q3*q3 + q4*q4;
|
||||
if (abs(factor - 1.0f) > 1e-9)
|
||||
{
|
||||
factor = 1.0f / sqrtf(factor);
|
||||
q1 *= factor;
|
||||
q2 *= factor;
|
||||
q3 *= factor;
|
||||
q4 *= factor;
|
||||
}
|
||||
// https://en.wikipedia.org/wiki/Quaternions_and_spatial_rotation#Quaternion-derived_rotation_matrix
|
||||
return TransformationMatrix(
|
||||
1 - 2 * (q2*q2 + q3*q3), 2 * (q1*q2 - q3*q4), 2 * (q1*q3 + q2*q4), 0.0f,
|
||||
2 * (q1*q2 + q3*q4), 1 - 2 * (q1*q1 + q3*q3), 2 * (q2*q3 - q1*q4), 0.0f,
|
||||
2 * (q1*q3 - q2*q4), 2 * (q2*q3 + q1*q4), 1 - 2 * (q1*q1 + q2*q2), 0.0f);
|
||||
}
|
||||
|
||||
TransformationMatrix TransformationMatrix::mat_rotation(float angle_rad, const Pointf3 &axis)
|
||||
{
|
||||
float s, factor, q1, q2, q3, q4;
|
||||
s = sin(angle_rad);
|
||||
TransformationMatrix mat; // For RVO
|
||||
factor = axis.x*axis.x + axis.y*axis.y + axis.z*axis.z;
|
||||
factor = 1.0f / sqrtf(factor);
|
||||
q1 = s*factor*axis.x;
|
||||
q2 = s*factor*axis.y;
|
||||
q3 = s*factor*axis.z;
|
||||
q4 = cos(angle_rad);
|
||||
return mat_rotation(q1, q2, q3, q4);
|
||||
}
|
||||
|
||||
TransformationMatrix TransformationMatrix::mat_mirror(const Axis &axis)
|
||||
{
|
||||
TransformationMatrix mat; // For RVO
|
||||
switch (axis)
|
||||
{
|
||||
case X:
|
||||
mat = TransformationMatrix(
|
||||
-1.0f, 0.0f, 0.0f, 0.0f,
|
||||
0.0f, 1.0f, 0.0f, 0.0f,
|
||||
0.0f, 0.0f, 1.0f, 0.0f);
|
||||
break;
|
||||
case Y:
|
||||
mat = TransformationMatrix(
|
||||
1.0f, 0.0f, 0.0f, 0.0f,
|
||||
0.0f, -1.0f, 0.0f, 0.0f,
|
||||
0.0f, 0.0f, 1.0f, 0.0f);
|
||||
break;
|
||||
case Z:
|
||||
mat = TransformationMatrix(
|
||||
1.0f, 0.0f, 0.0f, 0.0f,
|
||||
0.0f, 1.0f, 0.0f, 0.0f,
|
||||
0.0f, 0.0f, -1.0f, 0.0f);
|
||||
break;
|
||||
default:
|
||||
CONFESS("Invalid Axis supplied to TransformationMatrix::mat_mirror");
|
||||
mat = TransformationMatrix();
|
||||
break;
|
||||
}
|
||||
return mat;
|
||||
}
|
||||
|
||||
TransformationMatrix TransformationMatrix::mat_mirror(const Pointf3 &normal)
|
||||
{
|
||||
// Kovács, E. Rotation about arbitrary axis and reflection through an arbitrary plane, Annales Mathematicae
|
||||
// et Informaticae, Vol 40 (2012) pp 175-186
|
||||
// http://ami.ektf.hu/uploads/papers/finalpdf/AMI_40_from175to186.pdf
|
||||
float factor, c1, c2, c3;
|
||||
factor = normal.x*normal.x + normal.y*normal.y + normal.z*normal.z;
|
||||
factor = 1.0f / sqrtf(factor);
|
||||
c1 = factor*normal.x;
|
||||
c2 = factor*normal.y;
|
||||
c3 = factor*normal.z;
|
||||
return TransformationMatrix(
|
||||
1 - 2 * c1*c1, -2 * c2*c1, -2 * c3*c1, 0.0f,
|
||||
-2 * c2*c1, 1 - 2 * c2*c2, -2 * c2*c3, 0.0f,
|
||||
-2 * c1*c3, -2 * c2*c3, 1 - 2 * c3*c3, 0.0f);
|
||||
}
|
||||
|
||||
}
|
98
xs/src/libslic3r/TransformationMatrix.hpp
Normal file
98
xs/src/libslic3r/TransformationMatrix.hpp
Normal file
@ -0,0 +1,98 @@
|
||||
#ifndef slic3r_TriangleMatrix_hpp_
|
||||
#define slic3r_TriangleMatrix_hpp_
|
||||
|
||||
#ifndef Testumgebung
|
||||
#include "libslic3r.h"
|
||||
#include "Point.hpp"
|
||||
#endif
|
||||
|
||||
namespace Slic3r {
|
||||
|
||||
class TransformationMatrix
|
||||
{
|
||||
public:
|
||||
TransformationMatrix();
|
||||
#ifndef Testumgebung
|
||||
TransformationMatrix(std::vector<float> &entries);
|
||||
#endif
|
||||
TransformationMatrix(float m11, float m12, float m13, float m14, float m21, float m22, float m23, float m24, float m31, float m32, float m33, float m34);
|
||||
TransformationMatrix(const TransformationMatrix &other);
|
||||
TransformationMatrix& operator= (TransformationMatrix other);
|
||||
void swap(TransformationMatrix &other);
|
||||
|
||||
/// matrix entries
|
||||
float m11, m12, m13, m14, m21, m22, m23, m24, m31, m32, m33, m34;
|
||||
|
||||
/// Return the row-major form of the represented transformation matrix
|
||||
float* matrix3x4f();
|
||||
|
||||
/// Return the determinante of the matrix
|
||||
float determinante();
|
||||
|
||||
/// Returns the inverse of the matrix
|
||||
bool inverse(TransformationMatrix * inverse);
|
||||
|
||||
/// Perform Translation
|
||||
void translate(float x, float y, float z);
|
||||
|
||||
/// Perform uniform scale
|
||||
void scale(float factor);
|
||||
|
||||
/// Perform per-axis scale
|
||||
void scale(float x, float y, float z);
|
||||
|
||||
/// Perform mirroring along given axis
|
||||
void mirror(const Axis &axis);
|
||||
|
||||
/// Perform mirroring along given axis
|
||||
void mirror(const Pointf3 &normal);
|
||||
|
||||
/// Perform rotation around given axis
|
||||
void rotate(float angle_rad, const Axis &axis);
|
||||
|
||||
/// Perform rotation around arbitrary axis
|
||||
void rotate(float angle_rad, const Pointf3 &axis);
|
||||
|
||||
/// Perform rotation defined by unit quaternion
|
||||
void rotate(float q1, float q2, float q3, float q4);
|
||||
|
||||
/// Multiplies the Parameter-Matrix from the left (this=left*this)
|
||||
void multiplyLeft(TransformationMatrix &left);
|
||||
|
||||
/// Multiplies the Parameter-Matrix from the right (this=this*right)
|
||||
void multiplyRight(TransformationMatrix &right);
|
||||
|
||||
/// Generate an eye matrix.
|
||||
static TransformationMatrix mat_eye();
|
||||
|
||||
/// Generate a per axis scaling matrix
|
||||
static TransformationMatrix mat_scale(float x, float y, float z);
|
||||
|
||||
/// Generate a uniform scaling matrix
|
||||
static TransformationMatrix mat_scale(float scale);
|
||||
|
||||
/// Generate a reflection matrix by coordinate axis
|
||||
static TransformationMatrix mat_mirror(const Axis &axis);
|
||||
|
||||
/// Generate a reflection matrix by arbitrary vector
|
||||
static TransformationMatrix mat_mirror(const Pointf3 &normal);
|
||||
|
||||
/// Generate a translation matrix
|
||||
static TransformationMatrix mat_translation(float x, float y, float z);
|
||||
|
||||
/// Generate a rotation matrix around coodinate axis
|
||||
static TransformationMatrix mat_rotation(float angle_rad, const Axis &axis);
|
||||
|
||||
/// Generate a rotation matrix defined by unit quaternion q1*i + q2*j + q3*k + q4
|
||||
static TransformationMatrix mat_rotation(float q1, float q2, float q3, float q4);
|
||||
|
||||
/// Generate a rotation matrix around arbitrary axis
|
||||
static TransformationMatrix mat_rotation(float angle_rad, const Pointf3 &axis);
|
||||
|
||||
/// Performs a matrix multiplication
|
||||
static TransformationMatrix multiply(const TransformationMatrix &left, const TransformationMatrix &right);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
141
xs/t/02_transformationmatrix.t
Normal file
141
xs/t/02_transformationmatrix.t
Normal file
@ -0,0 +1,141 @@
|
||||
#!/usr/bin/perl
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use Slic3r::XS;
|
||||
use Test::More tests => 49;
|
||||
|
||||
use constant Z => 2;
|
||||
|
||||
is Slic3r::TriangleMesh::hello_world(), 'Hello world!',
|
||||
'hello world';
|
||||
|
||||
my $cube = {
|
||||
vertices => [ [20,20,0], [20,0,0], [0,0,0], [0,20,0], [20,20,20], [0,20,20], [0,0,20], [20,0,20] ],
|
||||
facets => [ [0,1,2], [0,2,3], [4,5,6], [4,6,7], [0,4,7], [0,7,1], [1,7,6], [1,6,2], [2,6,5], [2,5,3], [4,0,3], [4,3,5] ],
|
||||
};
|
||||
|
||||
{
|
||||
my $m = Slic3r::TriangleMesh->new;
|
||||
$m->ReadFromPerl($cube->{vertices}, $cube->{facets});
|
||||
$m->repair;
|
||||
my ($vertices, $facets) = ($m->vertices, $m->facets);
|
||||
|
||||
is_deeply $vertices, $cube->{vertices}, 'vertices arrayref roundtrip';
|
||||
is_deeply $facets, $cube->{facets}, 'facets arrayref roundtrip';
|
||||
is scalar(@{$m->normals}), scalar(@$facets), 'normals returns the right number of items';
|
||||
|
||||
{
|
||||
my $m2 = $m->clone;
|
||||
is_deeply $m2->vertices, $cube->{vertices}, 'cloned vertices arrayref roundtrip';
|
||||
is_deeply $m2->facets, $cube->{facets}, 'cloned facets arrayref roundtrip';
|
||||
$m2->scale(3); # check that it does not affect $m
|
||||
}
|
||||
|
||||
{
|
||||
my $stats = $m->stats;
|
||||
is $stats->{number_of_facets}, scalar(@{ $cube->{facets} }), 'stats.number_of_facets';
|
||||
ok abs($stats->{volume} - 20*20*20) < 1E-2, 'stats.volume';
|
||||
}
|
||||
|
||||
$m->scale(2);
|
||||
ok abs($m->stats->{volume} - 40*40*40) < 1E-2, 'scale';
|
||||
|
||||
$m->scale_xyz(Slic3r::Pointf3->new(2,1,1));
|
||||
ok abs($m->stats->{volume} - 2*40*40*40) < 1E-2, 'scale_xyz';
|
||||
|
||||
$m->translate(5,10,0);
|
||||
is_deeply $m->vertices->[0], [85,50,0], 'translate';
|
||||
|
||||
$m->align_to_origin;
|
||||
is_deeply $m->vertices->[2], [0,0,0], 'align_to_origin';
|
||||
|
||||
is_deeply $m->size, [80,40,40], 'size';
|
||||
|
||||
$m->scale_xyz(Slic3r::Pointf3->new(0.5,1,1));
|
||||
$m->rotate(45, Slic3r::Point->new(20,20));
|
||||
ok abs($m->size->[0] - sqrt(2)*40) < 1E-4, 'rotate';
|
||||
|
||||
{
|
||||
my $meshes = $m->split;
|
||||
is scalar(@$meshes), 1, 'split';
|
||||
isa_ok $meshes->[0], 'Slic3r::TriangleMesh', 'split';
|
||||
is_deeply $m->bb3, $meshes->[0]->bb3, 'split populates stats';
|
||||
}
|
||||
|
||||
my $m2 = Slic3r::TriangleMesh->new;
|
||||
$m2->ReadFromPerl($cube->{vertices}, $cube->{facets});
|
||||
$m2->repair;
|
||||
$m->merge($m2);
|
||||
$m->repair;
|
||||
is $m->stats->{number_of_facets}, 2 * $m2->stats->{number_of_facets}, 'merge';
|
||||
|
||||
{
|
||||
my $meshes = $m->split;
|
||||
is scalar(@$meshes), 2, 'split';
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
my $m = Slic3r::TriangleMesh->new;
|
||||
$m->ReadFromPerl($cube->{vertices}, $cube->{facets});
|
||||
$m->repair;
|
||||
my @z = (0,2,4,8,6,8,10,12,14,16,18,20);
|
||||
my $result = $m->slice(\@z);
|
||||
my $SCALING_FACTOR = 0.000001;
|
||||
for my $i (0..$#z) {
|
||||
is scalar(@{$result->[$i]}), 1, "number of returned polygons per layer (z = " . $z[$i] . ")";
|
||||
is $result->[$i][0]->area, 20*20/($SCALING_FACTOR**2), 'size of returned polygon';
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
my $m = Slic3r::TriangleMesh->new;
|
||||
$m->ReadFromPerl(
|
||||
[ [0,0,0],[0,0,20],[0,5,0],[0,5,20],[50,0,0],[50,0,20],[15,5,0],[35,5,0],[15,20,0],[50,5,0],[35,20,0],[15,5,10],[50,5,20],[35,5,10],[35,20,10],[15,20,10] ],
|
||||
[ [0,1,2],[2,1,3],[1,0,4],[5,1,4],[0,2,4],[4,2,6],[7,6,8],[4,6,7],[9,4,7],[7,8,10],[2,3,6],[11,3,12],[7,12,9],[13,12,7],[6,3,11],[11,12,13],[3,1,5],[12,3,5],[5,4,9],[12,5,9],[13,7,10],[14,13,10],[8,15,10],[10,15,14],[6,11,8],[8,11,15],[15,11,13],[14,15,13] ],
|
||||
);
|
||||
$m->repair;
|
||||
{
|
||||
# at Z = 10 we have a top horizontal surface
|
||||
my $slices = $m->slice([ 5, 10 ]);
|
||||
is $slices->[0][0]->area, $slices->[1][0]->area, 'slicing a top tangent plane includes its area';
|
||||
}
|
||||
$m->mirror_z;
|
||||
{
|
||||
# this second test also checks that performing a second slice on a mesh after
|
||||
# a transformation works properly (shared_vertices is correctly invalidated);
|
||||
# at Z = -10 we have a bottom horizontal surface
|
||||
my $slices = $m->slice([ -5, -10 ]);
|
||||
is $slices->[0][0]->area, $slices->[1][0]->area, 'slicing a bottom tangent plane includes its area';
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
my $m = Slic3r::TriangleMesh->new;
|
||||
$m->ReadFromPerl($cube->{vertices}, $cube->{facets});
|
||||
$m->repair;
|
||||
{
|
||||
my $upper = Slic3r::TriangleMesh->new;
|
||||
my $lower = Slic3r::TriangleMesh->new;
|
||||
$m->cut(Z, 0, $upper, $lower);
|
||||
$upper->repair; $lower->repair;
|
||||
is $upper->facets_count, 12, 'upper mesh has all facets except those belonging to the slicing plane';
|
||||
is $lower->facets_count, 0, 'lower mesh has no facets';
|
||||
}
|
||||
{
|
||||
my $upper = Slic3r::TriangleMesh->new;
|
||||
my $lower = Slic3r::TriangleMesh->new;
|
||||
$m->cut(Z, 10, $upper, $lower);
|
||||
#$upper->repair; $lower->repair;
|
||||
# we expect:
|
||||
# 2 facets on external horizontal surfaces
|
||||
# 3 facets on each side = 12 facets
|
||||
# 6 facets on the triangulated side (8 vertices)
|
||||
is $upper->facets_count, 2+12+6, 'upper mesh has the expected number of facets';
|
||||
is $lower->facets_count, 2+12+6, 'lower mesh has the expected number of facets';
|
||||
}
|
||||
}
|
||||
|
||||
__END__
|
65
xs/xsp/TransformationMatrix.xsp
Normal file
65
xs/xsp/TransformationMatrix.xsp
Normal file
@ -0,0 +1,65 @@
|
||||
%module{Slic3r::XS};
|
||||
|
||||
%{
|
||||
#include <xsinit.h>
|
||||
#include "libslic3r/TransformationMatrix.hpp"
|
||||
%}
|
||||
|
||||
%name{Slic3r::TransformationMatrix} class TransformationMatrix {
|
||||
TransformationMatrix();
|
||||
~TransformationMatrix();
|
||||
Clone<TransformationMatrix> clone()
|
||||
%code{% RETVAL = THIS; %};
|
||||
|
||||
float m11;
|
||||
%code%{ RETVAL = THIS->m11; %}
|
||||
void set_m11(float value)
|
||||
%code%{ THIS->m11 = value; %}
|
||||
float m12;
|
||||
%code%{ RETVAL = THIS->m12; %}
|
||||
void set_m12(float value)
|
||||
%code%{ THIS->m12 = value; %}
|
||||
float m13;
|
||||
%code%{ RETVAL = THIS->m13; %}
|
||||
void set_m13(float value)
|
||||
%code%{ THIS->m13 = value; %}
|
||||
float m14;
|
||||
%code%{ RETVAL = THIS->m14; %}
|
||||
void set_m14(float value)
|
||||
%code%{ THIS->m14 = value; %}
|
||||
|
||||
float m21;
|
||||
%code%{ RETVAL = THIS->m21; %}
|
||||
void set_m21(float value)
|
||||
%code%{ THIS->m21 = value; %}
|
||||
float m22;
|
||||
%code%{ RETVAL = THIS->m22; %}
|
||||
void set_m22(float value)
|
||||
%code%{ THIS->m22 = value; %}
|
||||
float m23;
|
||||
%code%{ RETVAL = THIS->m23; %}
|
||||
void set_m23(float value)
|
||||
%code%{ THIS->m23 = value; %}
|
||||
float m24;
|
||||
%code%{ RETVAL = THIS->m24; %}
|
||||
void set_m24(float value)
|
||||
%code%{ THIS->m24 = value; %}
|
||||
|
||||
float m31;
|
||||
%code%{ RETVAL = THIS->m31; %}
|
||||
void set_m31(float value)
|
||||
%code%{ THIS->m31 = value; %}
|
||||
float m32;
|
||||
%code%{ RETVAL = THIS->m32; %}
|
||||
void set_m32(float value)
|
||||
%code%{ THIS->m32 = value; %}
|
||||
float m33;
|
||||
%code%{ RETVAL = THIS->m33; %}
|
||||
void set_m33(float value)
|
||||
%code%{ THIS->m33 = value; %}
|
||||
float m34;
|
||||
%code%{ RETVAL = THIS->m34; %}
|
||||
void set_m34(float value)
|
||||
%code%{ THIS->m34 = value; %}
|
||||
|
||||
};
|
Loading…
x
Reference in New Issue
Block a user