From 19c5fa054562c03eaf91a93d531783b4eab58b82 Mon Sep 17 00:00:00 2001 From: Joseph Lenox Date: Mon, 9 Jul 2018 23:27:21 -0500 Subject: [PATCH] Added more tests for center(), and cut(). Added functions to access functionality (used to be in Perl interface). --- src/test/libslic3r/test_trianglemesh.cpp | 72 +++++++++++++++++++++++- xs/src/libslic3r/TriangleMesh.cpp | 30 ++++++++++ xs/src/libslic3r/TriangleMesh.hpp | 13 +++++ 3 files changed, 114 insertions(+), 1 deletion(-) diff --git a/src/test/libslic3r/test_trianglemesh.cpp b/src/test/libslic3r/test_trianglemesh.cpp index 72d0d0b55..259a73acc 100644 --- a/src/test/libslic3r/test_trianglemesh.cpp +++ b/src/test/libslic3r/test_trianglemesh.cpp @@ -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); + } + } + } + +} diff --git a/xs/src/libslic3r/TriangleMesh.cpp b/xs/src/libslic3r/TriangleMesh.cpp index cae3e40c1..a337eeb72 100644 --- a/xs/src/libslic3r/TriangleMesh.cpp +++ b/xs/src/libslic3r/TriangleMesh.cpp @@ -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(vec.x), + static_cast(vec.y), + static_cast(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(this).cut(z, upper, lower); + break; + case Y: + TriangleMeshSlicer(this).cut(z, upper, lower); + break; + case Z: + TriangleMeshSlicer(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 diff --git a/xs/src/libslic3r/TriangleMesh.hpp b/xs/src/libslic3r/TriangleMesh.hpp index b930888e0..dd937fba5 100644 --- a/xs/src/libslic3r/TriangleMesh.hpp +++ b/xs/src/libslic3r/TriangleMesh.hpp @@ -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);