Added more tests for center(), and cut(). Added functions to access functionality (used to be in Perl interface).

This commit is contained in:
Joseph Lenox 2018-07-09 23:27:21 -05:00 committed by Joseph Lenox
parent 21946dc1a1
commit 19c5fa0545
3 changed files with 114 additions and 1 deletions

View File

@ -45,6 +45,14 @@ SCENARIO( "TriangleMesh: Basic mesh statistics") {
THEN( "Number of normals is equal to the number of facets.") {
REQUIRE(cube.normals().size() == facets.size());
}
THEN( "center() returns the center of the object.") {
REQUIRE(cube.center() == Pointf3(10.0,10.0,10.0));
}
THEN( "Size of cube is (20,20,20)") {
REQUIRE(cube.size() == Pointf3(20,20,20));
}
}
}
@ -81,12 +89,33 @@ SCENARIO( "TriangleMesh: Transformation functions affect mesh as expected.") {
}
}
WHEN( "The scaled cube is rotated 45 degrees.") {
WHEN( "The cube is rotated 45 degrees.") {
cube.rotate(45.0, Slic3r::Point(20,20));
THEN( "The X component of the size is sqrt(2)*20") {
REQUIRE(abs(cube.size().x - sqrt(2.0)*20) < 1e-2);
}
}
WHEN( "The cube is translated (5, 10, 0) units with a Pointf3 ") {
cube.translate(Pointf3(5.0, 10.0, 0.0));
THEN( "The first vertex is located at 25, 30, 0") {
REQUIRE(cube.vertices().at(0) == Pointf3(25.0, 30.0, 0.0));
}
}
WHEN( "The cube is translated (5, 10, 0) units with 3 doubles") {
cube.translate(5.0, 10.0, 0.0);
THEN( "The first vertex is located at 25, 30, 0") {
REQUIRE(cube.vertices().at(0) == Pointf3(25.0, 30.0, 0.0));
}
}
WHEN( "The cube is translated (5, 10, 0) units and then aligned to origin") {
cube.translate(5.0, 10.0, 0.0);
cube.align_to_origin();
THEN( "The third vertex is located at 0,0,0") {
REQUIRE(cube.vertices().at(2) == Pointf3(0.0, 0.0, 0.0));
}
}
}
}
@ -94,6 +123,47 @@ SCENARIO( "TriangleMesh: split functionality.", "[!mayfail]") {
REQUIRE(false); // TODO
}
SCENARIO( "TriangleMesh: slice behavior.", "[!mayfail]") {
REQUIRE(false); // TODO
}
SCENARIO( "make_xxx functions produce meshes.", "[!mayfail]") {
REQUIRE(false); // TODO
}
SCENARIO( "TriangleMesh: Mesh merge functions", "[!mayfail]") {
REQUIRE(false); // TODO
}
SCENARIO( "TriangleMeshSlicer: Cut behavior.") {
GIVEN( "A 20mm cube with one corner on the origin") {
const Pointf3s vertices { Pointf3(20,20,0), Pointf3(20,0,0), Pointf3(0,0,0), Pointf3(0,20,0), Pointf3(20,20,20), Pointf3(0,20,20), Pointf3(0,0,20), Pointf3(20,0,20) };
const Point3s facets { Point3(0,1,2), Point3(0,2,3), Point3(4,5,6), Point3(4,6,7), Point3(0,4,7), Point3(0,7,1), Point3(1,7,6), Point3(1,6,2), Point3(2,6,5), Point3(2,5,3), Point3(4,0,3), Point3(4,3,5) };
auto cube {TriangleMesh(vertices, facets)};
cube.repair();
WHEN( "Object is cut at the bottom") {
TriangleMesh upper {};
TriangleMesh lower {};
cube.cut(Z, 0, &upper, &lower);
THEN("Upper mesh has all facets except those belonging to the slicing plane.") {
REQUIRE(upper.facets_count() == 12);
}
THEN("Lower mesh has no facets.") {
REQUIRE(lower.facets_count() == 0);
}
}
WHEN( "Object is cut at the center") {
TriangleMesh upper {};
TriangleMesh lower {};
cube.cut(Z, 10, &upper, &lower);
THEN("Upper mesh has 2 external horizontal facets, 3 facets on each side, and 6 facets on the triangulated side (2 + 12 + 6).") {
REQUIRE(upper.facets_count() == 2+12+6);
}
THEN("Lower mesh has 2 external horizontal facets, 3 facets on each side, and 6 facets on the triangulated side (2 + 12 + 6).") {
REQUIRE(lower.facets_count() == 2+12+6);
}
}
}
}

View File

@ -332,6 +332,14 @@ void TriangleMesh::translate(float x, float y, float z)
stl_invalidate_shared_vertices(&this->stl);
}
void TriangleMesh::translate(Pointf3 vec) {
this->translate(
static_cast<float>(vec.x),
static_cast<float>(vec.y),
static_cast<float>(vec.z)
);
}
void TriangleMesh::rotate(float angle, const Axis &axis)
{
// admesh uses degrees
@ -419,6 +427,11 @@ void TriangleMesh::rotate(double angle, const Point& center)
this->translate(+center.x, +center.y, 0);
}
Pointf3
TriangleMesh::center() const {
return this->bounding_box().center();
}
TriangleMeshPtrs
TriangleMesh::split() const
{
@ -534,6 +547,23 @@ TriangleMesh::merge(const TriangleMesh &mesh)
stl_get_size(&this->stl);
}
void TriangleMesh::cut(Axis axis, double z, TriangleMesh* upper, TriangleMesh* lower)
{
switch(axis) {
case X:
TriangleMeshSlicer<X>(this).cut(z, upper, lower);
break;
case Y:
TriangleMeshSlicer<Y>(this).cut(z, upper, lower);
break;
case Z:
TriangleMeshSlicer<Z>(this).cut(z, upper, lower);
break;
default:
Slic3r::Log::error("TriangleMesh", "Invalid Axis supplied to cut()");
}
}
/* this will return scaled ExPolygons */
ExPolygons
TriangleMesh::horizontal_projection() const

View File

@ -36,7 +36,14 @@ class TriangleMesh
void WriteOBJFile(const std::string &output_file);
void scale(float factor);
void scale(const Pointf3 &versor);
/// Translate the mesh to a new location.
void translate(float x, float y, float z);
/// Translate the mesh to a new location.
void translate(Pointf3 vec);
void rotate(float angle, const Axis &axis);
void rotate_x(float angle);
void rotate_y(float angle);
@ -76,6 +83,12 @@ class TriangleMesh
/// Return the size of the mesh in coordinates.
Pointf3 size() const;
/// Return the center of the related bounding box.
Pointf3 center() const;
/// Perform a cut of the mesh and put the output in upper and lower
void cut(Axis axis, double z, TriangleMesh* upper, TriangleMesh* lower);
/// Generate a mesh representing a cube with dimensions (x, y, z), with one corner at (0,0,0).
static TriangleMesh make_cube(double x, double y, double z);