2012-06-28 09:32:20 +00:00
|
|
|
|
|
|
|
|
#include <gtest/gtest.h>
|
|
|
|
|
#include <Unittests/unittests_common.hh>
|
2012-10-31 10:29:40 +00:00
|
|
|
#include <OpenMesh/Tools/Subdivider/Adaptive/Composite/CompositeT.hh>
|
|
|
|
|
#include <OpenMesh/Tools/Subdivider/Adaptive/Composite/RulesT.hh>
|
2012-06-28 09:32:20 +00:00
|
|
|
|
2013-09-20 14:21:08 +00:00
|
|
|
namespace {
|
|
|
|
|
|
2012-10-31 11:58:22 +00:00
|
|
|
class OpenMeshSubdividerAdaptive_Poly : public OpenMeshBasePoly {
|
2012-06-28 09:32:20 +00:00
|
|
|
|
|
|
|
|
protected:
|
|
|
|
|
|
|
|
|
|
// This function is called before each test is run
|
|
|
|
|
virtual void SetUp() {
|
2012-10-31 10:29:40 +00:00
|
|
|
|
2012-06-28 09:32:20 +00:00
|
|
|
// Do some initial stuff with the member data here...
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// This function is called after all tests are through
|
|
|
|
|
virtual void TearDown() {
|
|
|
|
|
|
|
|
|
|
// Do some final stuff with the member data here...
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Member already defined in OpenMeshBase
|
2012-10-31 10:29:40 +00:00
|
|
|
//Mesh mesh_;
|
2012-06-28 09:32:20 +00:00
|
|
|
};
|
|
|
|
|
|
2012-10-31 11:58:22 +00:00
|
|
|
class OpenMeshSubdividerAdaptive_Triangle : public OpenMeshBase {
|
2012-06-28 09:32:20 +00:00
|
|
|
|
|
|
|
|
protected:
|
|
|
|
|
|
|
|
|
|
// This function is called before each test is run
|
|
|
|
|
virtual void SetUp() {
|
|
|
|
|
|
|
|
|
|
// Do some initial stuff with the member data here...
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// This function is called after all tests are through
|
|
|
|
|
virtual void TearDown() {
|
|
|
|
|
|
|
|
|
|
// Do some final stuff with the member data here...
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Member already defined in OpenMeshBase
|
|
|
|
|
//Mesh mesh_;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* ====================================================================
|
|
|
|
|
* Define tests below
|
|
|
|
|
* ====================================================================
|
|
|
|
|
*/
|
|
|
|
|
|
2012-10-31 10:29:40 +00:00
|
|
|
struct MeshTraits : public OpenMesh::Subdivider::Adaptive::CompositeTraits {
|
|
|
|
|
typedef OpenMesh::Vec3f Point;
|
|
|
|
|
typedef OpenMesh::Vec3f Normal;
|
|
|
|
|
|
|
|
|
|
VertexAttributes(OpenMesh::Attributes::Status | OpenMesh::Attributes::Normal);
|
|
|
|
|
EdgeAttributes(OpenMesh::Attributes::Status);
|
|
|
|
|
FaceAttributes(OpenMesh::Attributes::Status | OpenMesh::Attributes::Normal);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
typedef OpenMesh::TriMesh_ArrayKernelT<MeshTraits> MyMesh;
|
2012-10-31 11:58:22 +00:00
|
|
|
typedef MyMesh::VertexHandle VHandle;
|
|
|
|
|
typedef MyMesh::FaceHandle FHandle;
|
2012-10-31 10:29:40 +00:00
|
|
|
|
2012-10-31 11:58:22 +00:00
|
|
|
TEST_F(OpenMeshSubdividerAdaptive_Triangle, AdaptiveCompositeRefineVertex) {
|
2012-10-31 10:29:40 +00:00
|
|
|
|
|
|
|
|
MyMesh mesh;
|
|
|
|
|
mesh.request_vertex_status();
|
|
|
|
|
mesh.request_edge_status();
|
|
|
|
|
mesh.request_face_status();
|
|
|
|
|
mesh.request_vertex_normals();
|
|
|
|
|
mesh.request_face_normals();
|
|
|
|
|
|
|
|
|
|
// Add some vertices
|
2012-10-31 11:58:22 +00:00
|
|
|
VHandle vhandle[9];
|
2012-10-31 10:29:40 +00:00
|
|
|
|
|
|
|
|
vhandle[0] = mesh.add_vertex(MyMesh::Point(0, 0, 0));
|
|
|
|
|
vhandle[1] = mesh.add_vertex(MyMesh::Point(0, 1, 0));
|
|
|
|
|
vhandle[2] = mesh.add_vertex(MyMesh::Point(0, 2, 0));
|
|
|
|
|
vhandle[3] = mesh.add_vertex(MyMesh::Point(1, 0, 0));
|
|
|
|
|
vhandle[4] = mesh.add_vertex(MyMesh::Point(1, 1, 0));
|
|
|
|
|
vhandle[5] = mesh.add_vertex(MyMesh::Point(1, 2, 0));
|
|
|
|
|
vhandle[6] = mesh.add_vertex(MyMesh::Point(2, 0, 0));
|
|
|
|
|
vhandle[7] = mesh.add_vertex(MyMesh::Point(2, 1, 0));
|
|
|
|
|
vhandle[8] = mesh.add_vertex(MyMesh::Point(2, 2, 0));
|
|
|
|
|
|
|
|
|
|
// Add eight faces
|
2012-10-31 11:58:22 +00:00
|
|
|
std::vector<VHandle> face_vhandles;
|
2012-10-31 10:29:40 +00:00
|
|
|
|
|
|
|
|
face_vhandles.push_back(vhandle[0]);
|
|
|
|
|
face_vhandles.push_back(vhandle[4]);
|
|
|
|
|
face_vhandles.push_back(vhandle[3]);
|
|
|
|
|
|
|
|
|
|
mesh.add_face(face_vhandles);
|
|
|
|
|
face_vhandles.clear();
|
|
|
|
|
|
|
|
|
|
face_vhandles.push_back(vhandle[0]);
|
|
|
|
|
face_vhandles.push_back(vhandle[1]);
|
|
|
|
|
face_vhandles.push_back(vhandle[4]);
|
|
|
|
|
|
|
|
|
|
mesh.add_face(face_vhandles);
|
|
|
|
|
face_vhandles.clear();
|
|
|
|
|
|
|
|
|
|
face_vhandles.push_back(vhandle[1]);
|
|
|
|
|
face_vhandles.push_back(vhandle[2]);
|
|
|
|
|
face_vhandles.push_back(vhandle[4]);
|
|
|
|
|
|
|
|
|
|
mesh.add_face(face_vhandles);
|
|
|
|
|
face_vhandles.clear();
|
|
|
|
|
|
|
|
|
|
face_vhandles.push_back(vhandle[2]);
|
|
|
|
|
face_vhandles.push_back(vhandle[5]);
|
|
|
|
|
face_vhandles.push_back(vhandle[4]);
|
|
|
|
|
|
|
|
|
|
mesh.add_face(face_vhandles);
|
|
|
|
|
face_vhandles.clear();
|
|
|
|
|
|
|
|
|
|
face_vhandles.push_back(vhandle[3]);
|
|
|
|
|
face_vhandles.push_back(vhandle[7]);
|
|
|
|
|
face_vhandles.push_back(vhandle[6]);
|
|
|
|
|
|
|
|
|
|
mesh.add_face(face_vhandles);
|
|
|
|
|
face_vhandles.clear();
|
|
|
|
|
|
|
|
|
|
face_vhandles.push_back(vhandle[3]);
|
|
|
|
|
face_vhandles.push_back(vhandle[4]);
|
|
|
|
|
face_vhandles.push_back(vhandle[7]);
|
|
|
|
|
|
|
|
|
|
mesh.add_face(face_vhandles);
|
|
|
|
|
face_vhandles.clear();
|
|
|
|
|
|
|
|
|
|
face_vhandles.push_back(vhandle[4]);
|
|
|
|
|
face_vhandles.push_back(vhandle[8]);
|
|
|
|
|
face_vhandles.push_back(vhandle[7]);
|
|
|
|
|
|
|
|
|
|
mesh.add_face(face_vhandles);
|
|
|
|
|
face_vhandles.clear();
|
|
|
|
|
|
|
|
|
|
face_vhandles.push_back(vhandle[4]);
|
|
|
|
|
face_vhandles.push_back(vhandle[5]);
|
|
|
|
|
face_vhandles.push_back(vhandle[8]);
|
|
|
|
|
|
2012-10-31 11:58:22 +00:00
|
|
|
mesh.add_face(face_vhandles);
|
2012-10-31 10:29:40 +00:00
|
|
|
|
|
|
|
|
//// Test setup:
|
|
|
|
|
//// 6 === 7 === 8
|
|
|
|
|
//// | / | / |
|
|
|
|
|
//// | / | / |
|
|
|
|
|
//// | / | / |
|
|
|
|
|
//// 3 === 4 === 5
|
|
|
|
|
//// | / | \ |
|
|
|
|
|
//// | / | \ |
|
|
|
|
|
//// | / | \ |
|
|
|
|
|
//// 0 === 1 === 2
|
|
|
|
|
|
|
|
|
|
// Initialize subdivider
|
|
|
|
|
OpenMesh::Subdivider::Adaptive::CompositeT<MyMesh> subdivider(mesh);
|
|
|
|
|
|
|
|
|
|
subdivider.add<OpenMesh::Subdivider::Adaptive::Tvv3<MyMesh> >();
|
|
|
|
|
subdivider.add<OpenMesh::Subdivider::Adaptive::VF<MyMesh> >();
|
|
|
|
|
subdivider.add<OpenMesh::Subdivider::Adaptive::FF<MyMesh> >();
|
|
|
|
|
subdivider.add<OpenMesh::Subdivider::Adaptive::FVc<MyMesh> >();
|
|
|
|
|
|
|
|
|
|
subdivider.initialize();
|
|
|
|
|
|
|
|
|
|
// Check setup
|
|
|
|
|
EXPECT_EQ(9u, mesh.n_vertices() ) << "Wrong number of vertices";
|
|
|
|
|
EXPECT_EQ(8u, mesh.n_faces() ) << "Wrong number of faces";
|
|
|
|
|
|
|
|
|
|
// execute adaptive composite subdivision
|
|
|
|
|
subdivider.refine(vhandle[4]);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Check setup
|
|
|
|
|
EXPECT_EQ(17u, mesh.n_vertices() ) << "Wrong number of vertices after subdivision with sqrt3";
|
|
|
|
|
EXPECT_EQ(24u, mesh.n_faces() ) << "Wrong number of faces after subdivision with sqrt3";
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
2012-10-31 11:58:22 +00:00
|
|
|
TEST_F(OpenMeshSubdividerAdaptive_Triangle, AdaptiveCompositeRefineFace) {
|
2012-10-31 10:29:40 +00:00
|
|
|
|
|
|
|
|
MyMesh mesh;
|
|
|
|
|
mesh.request_vertex_status();
|
|
|
|
|
mesh.request_edge_status();
|
|
|
|
|
mesh.request_face_status();
|
|
|
|
|
mesh.request_vertex_normals();
|
|
|
|
|
mesh.request_face_normals();
|
|
|
|
|
|
|
|
|
|
// Add some vertices
|
2012-10-31 11:58:22 +00:00
|
|
|
VHandle vhandle[9];
|
2012-10-31 10:29:40 +00:00
|
|
|
|
|
|
|
|
vhandle[0] = mesh.add_vertex(MyMesh::Point(0, 0, 0));
|
|
|
|
|
vhandle[1] = mesh.add_vertex(MyMesh::Point(0, 1, 0));
|
|
|
|
|
vhandle[2] = mesh.add_vertex(MyMesh::Point(0, 2, 0));
|
|
|
|
|
vhandle[3] = mesh.add_vertex(MyMesh::Point(1, 0, 0));
|
|
|
|
|
vhandle[4] = mesh.add_vertex(MyMesh::Point(1, 1, 0));
|
|
|
|
|
vhandle[5] = mesh.add_vertex(MyMesh::Point(1, 2, 0));
|
|
|
|
|
vhandle[6] = mesh.add_vertex(MyMesh::Point(2, 0, 0));
|
|
|
|
|
vhandle[7] = mesh.add_vertex(MyMesh::Point(2, 1, 0));
|
|
|
|
|
vhandle[8] = mesh.add_vertex(MyMesh::Point(2, 2, 0));
|
|
|
|
|
|
|
|
|
|
// Add eight faces
|
2012-10-31 11:58:22 +00:00
|
|
|
std::vector<VHandle> face_vhandles;
|
|
|
|
|
std::vector<FHandle> face_handles;
|
2012-10-31 10:29:40 +00:00
|
|
|
|
|
|
|
|
face_vhandles.push_back(vhandle[0]);
|
|
|
|
|
face_vhandles.push_back(vhandle[4]);
|
|
|
|
|
face_vhandles.push_back(vhandle[3]);
|
|
|
|
|
|
|
|
|
|
face_handles.push_back(mesh.add_face(face_vhandles));
|
|
|
|
|
face_vhandles.clear();
|
|
|
|
|
|
|
|
|
|
face_vhandles.push_back(vhandle[0]);
|
|
|
|
|
face_vhandles.push_back(vhandle[1]);
|
|
|
|
|
face_vhandles.push_back(vhandle[4]);
|
|
|
|
|
|
|
|
|
|
face_handles.push_back(mesh.add_face(face_vhandles));
|
|
|
|
|
face_vhandles.clear();
|
|
|
|
|
|
|
|
|
|
face_vhandles.push_back(vhandle[1]);
|
|
|
|
|
face_vhandles.push_back(vhandle[2]);
|
|
|
|
|
face_vhandles.push_back(vhandle[4]);
|
|
|
|
|
|
|
|
|
|
face_handles.push_back(mesh.add_face(face_vhandles));
|
|
|
|
|
face_vhandles.clear();
|
|
|
|
|
|
|
|
|
|
face_vhandles.push_back(vhandle[2]);
|
|
|
|
|
face_vhandles.push_back(vhandle[5]);
|
|
|
|
|
face_vhandles.push_back(vhandle[4]);
|
|
|
|
|
|
|
|
|
|
face_handles.push_back(mesh.add_face(face_vhandles));
|
|
|
|
|
face_vhandles.clear();
|
|
|
|
|
|
|
|
|
|
face_vhandles.push_back(vhandle[3]);
|
|
|
|
|
face_vhandles.push_back(vhandle[7]);
|
|
|
|
|
face_vhandles.push_back(vhandle[6]);
|
|
|
|
|
|
|
|
|
|
face_handles.push_back(mesh.add_face(face_vhandles));
|
|
|
|
|
face_vhandles.clear();
|
|
|
|
|
|
|
|
|
|
face_vhandles.push_back(vhandle[3]);
|
|
|
|
|
face_vhandles.push_back(vhandle[4]);
|
|
|
|
|
face_vhandles.push_back(vhandle[7]);
|
|
|
|
|
|
|
|
|
|
face_handles.push_back(mesh.add_face(face_vhandles));
|
|
|
|
|
face_vhandles.clear();
|
|
|
|
|
|
|
|
|
|
face_vhandles.push_back(vhandle[4]);
|
|
|
|
|
face_vhandles.push_back(vhandle[8]);
|
|
|
|
|
face_vhandles.push_back(vhandle[7]);
|
|
|
|
|
|
|
|
|
|
face_handles.push_back(mesh.add_face(face_vhandles));
|
|
|
|
|
face_vhandles.clear();
|
|
|
|
|
|
|
|
|
|
face_vhandles.push_back(vhandle[4]);
|
|
|
|
|
face_vhandles.push_back(vhandle[5]);
|
|
|
|
|
face_vhandles.push_back(vhandle[8]);
|
|
|
|
|
|
|
|
|
|
face_handles.push_back(mesh.add_face(face_vhandles));
|
|
|
|
|
|
|
|
|
|
//// Test setup:
|
|
|
|
|
//// 6 === 7 === 8
|
|
|
|
|
//// | / | / |
|
|
|
|
|
//// | / | / |
|
|
|
|
|
//// | / | / |
|
|
|
|
|
//// 3 === 4 === 5
|
|
|
|
|
//// | / | \ |
|
|
|
|
|
//// | / | \ |
|
|
|
|
|
//// | / | \ |
|
|
|
|
|
//// 0 === 1 === 2
|
|
|
|
|
|
|
|
|
|
// Initialize subdivider
|
|
|
|
|
OpenMesh::Subdivider::Adaptive::CompositeT<MyMesh> subdivider(mesh);
|
|
|
|
|
|
|
|
|
|
subdivider.add<OpenMesh::Subdivider::Adaptive::Tvv3<MyMesh> >();
|
|
|
|
|
subdivider.add<OpenMesh::Subdivider::Adaptive::VF<MyMesh> >();
|
|
|
|
|
subdivider.add<OpenMesh::Subdivider::Adaptive::FF<MyMesh> >();
|
|
|
|
|
subdivider.add<OpenMesh::Subdivider::Adaptive::FVc<MyMesh> >();
|
|
|
|
|
|
|
|
|
|
subdivider.initialize();
|
|
|
|
|
|
|
|
|
|
// Check setup
|
|
|
|
|
EXPECT_EQ(9u, mesh.n_vertices() ) << "Wrong number of vertices";
|
|
|
|
|
EXPECT_EQ(8u, mesh.n_faces() ) << "Wrong number of faces";
|
|
|
|
|
|
|
|
|
|
// execute adaptive composite subdivision
|
2012-10-31 11:58:22 +00:00
|
|
|
std::vector<FHandle>::iterator it, end;
|
2012-10-31 10:29:40 +00:00
|
|
|
it = face_handles.begin();
|
|
|
|
|
end = face_handles.end();
|
|
|
|
|
for (; it != end; ++it)
|
|
|
|
|
subdivider.refine(*it);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Check setup
|
|
|
|
|
EXPECT_EQ(245u, mesh.n_vertices() ) << "Wrong number of vertices after subdivision with sqrt3";
|
|
|
|
|
EXPECT_EQ(458u, mesh.n_faces() ) << "Wrong number of faces after subdivision with sqrt3";
|
|
|
|
|
|
|
|
|
|
}
|
2013-09-20 14:21:08 +00:00
|
|
|
}
|