Skip to content

Commit

Permalink
Merge 713fd5b into c2aa7e7
Browse files Browse the repository at this point in the history
  • Loading branch information
Oekn5w authored Dec 22, 2019
2 parents c2aa7e7 + 713fd5b commit 47b8d2f
Show file tree
Hide file tree
Showing 2 changed files with 220 additions and 0 deletions.
1 change: 1 addition & 0 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -315,6 +315,7 @@ set(SLIC3R_TEST_SOURCES
${TESTDIR}/libslic3r/test_printobject.cpp
${TESTDIR}/libslic3r/test_skirt_brim.cpp
${TESTDIR}/libslic3r/test_test_data.cpp
${TESTDIR}/libslic3r/test_transformationmatrix.cpp
${TESTDIR}/libslic3r/test_trianglemesh.cpp
${TESTDIR}/libslic3r/test_extrusion_entity.cpp
${TESTDIR}/libslic3r/test_3mf.cpp
Expand Down
219 changes: 219 additions & 0 deletions src/test/libslic3r/test_transformationmatrix.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,219 @@
#include <catch.hpp>

#include <vector>

#include "libslic3r.h"
#include "TransformationMatrix.hpp"

#include "Log.hpp"

using namespace Slic3r;

bool check_elements(TransformationMatrix const & matrix,
double m00, double m01, double m02, double m03,
double m10, double m11, double m12, double m13,
double m20, double m21, double m22, double m23);
bool check_point(const Pointf3 & point, coordf_t x, coordf_t y, coordf_t z);
double degtorad(double value){ return PI / 180.0 * value; }

SCENARIO("TransformationMatrix: constructors, copytor, comparing, basic operations"){
GIVEN("a default constructed Matrix") {
auto trafo_default = TransformationMatrix();
THEN("comparing to the eye matrix") {
REQUIRE(check_elements(trafo_default,
1.0, 0.0, 0.0, 0.0,
0.0, 1.0, 0.0, 0.0,
0.0, 0.0, 1.0, 0.0));
}

WHEN("copied") {
auto trafo_eq_assigned = trafo_default;
THEN("comparing the second to the eye matrix") {
REQUIRE(check_elements(trafo_eq_assigned,
1.0, 0.0, 0.0, 0.0,
0.0, 1.0, 0.0, 0.0,
0.0, 0.0, 1.0, 0.0));
}
THEN("comparing them to each other")
{
REQUIRE(trafo_default == trafo_eq_assigned);
REQUIRE(!(trafo_default != trafo_eq_assigned));
}
trafo_eq_assigned.m00 = 2.0;
THEN("testing uniqueness") {
REQUIRE(trafo_default != trafo_eq_assigned);
}
}
}
GIVEN("a directly set matrix") {
THEN("set via constructor") {
auto trafo_set = TransformationMatrix(1,2,3,4,5,6,7,8,9,10,11,12);
REQUIRE(check_elements(trafo_set,
1,2,3,4,
5,6,7,8,
9,10,11,12));
}
THEN("set via vector") {
std::vector<double> elements;
elements.reserve(12);
elements.push_back(1);
elements.push_back(2);
elements.push_back(3);
elements.push_back(4);
elements.push_back(5);
elements.push_back(6);
elements.push_back(7);
elements.push_back(8);
elements.push_back(9);
elements.push_back(10);
elements.push_back(11);
elements.push_back(12);
auto trafo_vec = TransformationMatrix(elements);
REQUIRE(check_elements(trafo_vec,
1,2,3,4,
5,6,7,8,
9,10,11,12));
}
}
GIVEN("two separate matrices") {
auto mat1 = TransformationMatrix(1,2,3,4,5,6,7,8,9,10,11,12);
auto mat2 = TransformationMatrix(1,4,7,10,2,5,8,11,3,6,9,12);
THEN("static multiplication") {
auto mat3 = TransformationMatrix::multiply(mat1, mat2);
REQUIRE(check_elements(mat3,14,32,50,72,38,92,146,208,62,152,242,344));
mat3 = TransformationMatrix::multiply(mat2, mat1);
REQUIRE(check_elements(mat3,84,96,108,130,99,114,129,155,114,132,150,180));
}
THEN("direct multiplication") {
REQUIRE(check_elements(mat1.multiplyRight(mat2),14,32,50,72,38,92,146,208,62,152,242,344));
REQUIRE(check_elements(mat2.multiplyLeft(mat1),14,32,50,72,38,92,146,208,62,152,242,344));
}
}
GIVEN("a random transformation-ish matrix") {
auto mat = TransformationMatrix(
0.9004,-0.2369,-0.4847,12.9383,
-0.9311,0.531,-0.5026,7.7931,
-0.1225,0.5904,0.2576,-7.316);
THEN("computing the determinante") {
REQUIRE(std::abs(mat.determinante() - 0.5539) < 1.0e-3);
}
THEN("computing the inverse") {
REQUIRE(check_elements(mat.inverse(),
0.78273016,-0.40649736,0.67967289,-1.98683622,
0.54421957,0.31157368,1.63191055,2.46965668,
-0.87508846,-0.90741083,0.46498424,21.79552507));
}
}
}

SCENARIO("TransformationMatrix: application") {
GIVEN("two vectors to validate geometric transformations") {
auto vec1 = Pointf3(1,2,3);
auto vec2 = Pointf3(-4,3,-2);
THEN("testing general point transformation") {
auto mat = TransformationMatrix(1,2,3,4,5,6,7,8,9,10,11,12);
REQUIRE(check_point(mat.transform(vec1),18,46,74)); // default arg should be like a point
REQUIRE(check_point(mat.transform(vec1,1),18,46,74));
REQUIRE(check_point(mat.transform(vec1,0),14,38,62));
}
WHEN("testing scaling") {
THEN("testing universal scaling") {
auto mat = TransformationMatrix::mat_scale(3);
REQUIRE(check_point(mat.transform(vec1),3,6,9));
}
THEN("testing vector like scaling") {
auto mat = TransformationMatrix::mat_scale(2,3,4);
REQUIRE(check_point(mat.transform(vec1),2,6,12));
}
}
WHEN("testing mirroring") {
THEN("testing axis aligned mirroring") {
auto mat = TransformationMatrix::mat_mirror(Axis::X);
REQUIRE(check_point(mat.transform(vec1),-1,2,3));
mat = TransformationMatrix::mat_mirror(Axis::Y);
REQUIRE(check_point(mat.transform(vec1),1,-2,3));
mat = TransformationMatrix::mat_mirror(Axis::Z);
REQUIRE(check_point(mat.transform(vec1),1,2,-3));
}
THEN("testing arbituary axis mirroring") {
auto mat = TransformationMatrix::mat_mirror(vec2);
REQUIRE(check_point(mat.transform(vec1),-0.1034,2.8276,2.4483));
REQUIRE(std::abs(mat.determinante() + 1.0) < 1.0e-3);
}
}
WHEN("testing translation") {
THEN("testing xyz translation") {
auto mat = TransformationMatrix::mat_translation(4,2,5);
REQUIRE(check_point(mat.transform(vec1),5,4,8));
}
THEN("testing vector-defined translation") {
auto mat = TransformationMatrix::mat_translation(vec2);
REQUIRE(check_point(mat.transform(vec1),-3,5,1));
}
}
WHEN("testing rotation") {
THEN("testing axis aligned rotation") {
auto mat = TransformationMatrix::mat_rotation(degtorad(90), Axis::X);
REQUIRE(check_point(mat.transform(vec1),1,-3,2));
mat = TransformationMatrix::mat_rotation(degtorad(90), Axis::Y);
REQUIRE(check_point(mat.transform(vec1),3,2,-1));
mat = TransformationMatrix::mat_rotation(degtorad(90), Axis::Z);
REQUIRE(check_point(mat.transform(vec1),-2,1,3));
}
THEN("testing arbituary axis rotation") {
auto mat = TransformationMatrix::mat_rotation(degtorad(80), vec2);
REQUIRE(check_point(mat.transform(vec1),3.0069,1.8341,-1.2627));
REQUIRE(std::abs(mat.determinante() - 1.0) < 1.0e-3);
}
THEN("testing quaternion rotation") {
auto mat = TransformationMatrix::mat_rotation(-0.4775,0.3581,-0.2387,0.7660);
REQUIRE(check_point(mat.transform(vec1),3.0069,1.8341,-1.2627));
REQUIRE(std::abs(mat.determinante() - 1.0) < 1.0e-3);
}
THEN("testing vector to vector") {
auto mat = TransformationMatrix::mat_rotation(vec1,vec2);
REQUIRE(check_point(mat.transform(vec1),-2.7792,2.0844,-1.3896));
REQUIRE(std::abs(mat.determinante() - 1.0) < 1.0e-3);
mat = TransformationMatrix::mat_rotation(vec1,vec1.negative());
REQUIRE(check_point(mat.transform(vec1),-1,-2,-3)); // colinear, opposite direction
mat = TransformationMatrix::mat_rotation(vec1,vec1);
REQUIRE(check_elements(mat,
1.0, 0.0, 0.0, 0.0,
0.0, 1.0, 0.0, 0.0,
0.0, 0.0, 1.0, 0.0)); // colinear, same direction
}
}
}
}

bool check_elements(const TransformationMatrix & matrix,
double m00, double m01, double m02, double m03,
double m10, double m11, double m12, double m13,
double m20, double m21, double m22, double m23)
{
const double EPSILON = 1.0e-3;
bool equal = true;
equal &= std::abs(matrix.m00 - m00) < EPSILON;
equal &= std::abs(matrix.m01 - m01) < EPSILON;
equal &= std::abs(matrix.m02 - m02) < EPSILON;
equal &= std::abs(matrix.m03 - m03) < EPSILON;
equal &= std::abs(matrix.m10 - m10) < EPSILON;
equal &= std::abs(matrix.m11 - m11) < EPSILON;
equal &= std::abs(matrix.m12 - m12) < EPSILON;
equal &= std::abs(matrix.m13 - m13) < EPSILON;
equal &= std::abs(matrix.m20 - m20) < EPSILON;
equal &= std::abs(matrix.m21 - m21) < EPSILON;
equal &= std::abs(matrix.m22 - m22) < EPSILON;
equal &= std::abs(matrix.m23 - m23) < EPSILON;
return equal;
}

bool check_point(const Pointf3 & point, coordf_t x, coordf_t y, coordf_t z)
{
const coordf_t EPSILON = 1.0e-3;
bool equal = true;
equal &= std::abs(point.x - x) < EPSILON;
equal &= std::abs(point.y - y) < EPSILON;
equal &= std::abs(point.z - z) < EPSILON;
return equal;
}

0 comments on commit 47b8d2f

Please sign in to comment.