Browse Source

Added function MeshBuilder::subdivide().

Argument is function or functor which does interpolation between two
adjacent vertices.
vectorfields
Vladimír Vondruš 15 years ago
parent
commit
c56453cb37
  1. 41
      src/MeshBuilder.h
  2. 25
      src/Test/MeshBuilderTest.cpp
  3. 4
      src/Test/MeshBuilderTest.h

41
src/MeshBuilder.h

@ -169,6 +169,47 @@ template<class Vertex> class MeshBuilder {
_faces.insert(face); _faces.insert(face);
} }
/**
* @brief Subdivide mesh
* @param interpolator Functor or function pointer which interpolates
* two adjacent vertices: <tt>Vertex interpolator(Vertex a, Vertex
* b)</tt>
*
* Goes through all triangle faces and subdivides them in four new.
* Cleaning the mesh is up to user.
*/
template<class Interpolator> void subdivide(Interpolator interpolator) {
/* Copy of current faces */
std::set<Face*> f = faces();
/* Subdivide each face to four new */
for(typename std::set<Face*>::const_iterator face = f.begin(); face != f.end(); ++face) {
/* Interpolate each side */
Vertex* newVertices[3];
for(int i = 0; i != 3; ++i)
newVertices[i] = new Vertex(interpolator(*(*face)->vertices[i], *(*face)->vertices[(i+1)%3]));
/*
* Add three new faces (0, 1, 3) and update original (2)
*
* orig 0
* / \
* / 0 \
* / \
* new 0 ----- new 2
* / \ / \
* / 1 \ 2 / 3 \
* / \ / \
* orig 1 ----- new 1 ---- orig 2
*/
addFace(new Face((*face)->vertices[0], newVertices[0], newVertices[2]));
addFace(new Face(newVertices[0], (*face)->vertices[1], newVertices[1]));
addFace(new Face(newVertices[2], newVertices[1], (*face)->vertices[2]));
for(int i = 0; i != 3; ++i)
(*face)->vertices[i] = newVertices[i];
}
}
/** /**
* @brief Clean the mesh * @brief Clean the mesh
* *

25
src/Test/MeshBuilderTest.cpp

@ -150,4 +150,29 @@ void MeshBuilderTest::cleanMesh() {
QVERIFY(builder.faces() == faces); QVERIFY(builder.faces() == faces);
} }
void MeshBuilderTest::subdivide() {
MeshBuilder<int> builder;
int* v1 = new int(0);
int* v2 = new int(2);
int* v3 = new int(6);
int* v4 = new int(8);
MeshBuilder<int>::Face* f1 = new MeshBuilder<int>::Face(v1, v2, v3);
builder.addFace(f1);
MeshBuilder<int>::Face* f2 = new MeshBuilder<int>::Face(v2, v3, v4);
builder.addFace(f2);
builder.subdivide(interpolator);
QVERIFY(builder.vertices().size() == 10);
QVERIFY(builder.faces().size() == 8);
/* This also effectively checks the data, as the vertices should be exactly
0, 1, 2, .. 8 */
builder.cleanMesh();
QVERIFY(builder.vertices().size() == 9);
QVERIFY(builder.faces().size() == 8);
}
}} }}

4
src/Test/MeshBuilderTest.h

@ -27,6 +27,10 @@ class MeshBuilderTest: public QObject {
void addFace(); void addFace();
void removeFace(); void removeFace();
void cleanMesh(); void cleanMesh();
void subdivide();
private:
inline static int interpolator(int a, int b) { return (a+b)/2; }
}; };
}} }}

Loading…
Cancel
Save