/* * File: main.cpp * Author: jcoelho * * A simple test that refines all triangles inside a circle using the differents * triangulation in order to illustrate the sintaxe of the refinement lib. * * To test the generation of differents triangulation, just comment or uncomment * the call function from line 158. */ #include #include #include #include #include #include #include "CornerTable.h" #include "CornerTableAdaptiveRefinement.h" using namespace std; /** * Create a mesh of an hexagon. * @return - corner table with the mesh. */ CornerTable* createNewMesh( ) { //Allocate the geometry vector. double *coordinates = new double[2 * 7]; //Allocate the triangulation vector. CornerType *triangleMesh = new CornerType[3 * 6]; //Central vertex. double centerX = 0.0, centerY = 0.0; //Radius of the hexagon. double radius = 10.0; //Set the coordinates of the central vertex. coordinates[0] = centerX; coordinates[1] = centerY; //Set the first point in x-axe direction. coordinates[2] = centerX + radius; coordinates[3] = centerY; for (unsigned int i = 1; i < 6; i++) { //Compute the angle. double angle = i * M_PI / 3.0; //Set the new vertex coordinates. coordinates[2 * ( i + 1 ) + 0] = radius * cos( angle ); coordinates[2 * ( i + 1 ) + 1] = radius * sin( angle ); //Set new triangle. triangleMesh[3 * ( i - 1 ) + 0] = 0; triangleMesh[3 * ( i - 1 ) + 1] = i; triangleMesh[3 * ( i - 1 ) + 2] = i + 1; } //Set last triangle. triangleMesh[3 * 5 + 0] = 0; triangleMesh[3 * 5 + 1] = 6; triangleMesh[3 * 5 + 2] = 1; //Allocate the corner table. CornerTable *surface = new CornerTable( triangleMesh, coordinates, 6, 7, 2 ); //Free memory. delete []triangleMesh; delete []coordinates; return surface; } /** * Callback to compute the coordinates of the new vertices. In this case, the * callback set new coordinates in the middle point of the edge. * @param surface - current surface represented in the corner table data * structure. * @param corner - corner opposite to the edge. * @param attributes - vector to be set with the new coordinates. */ static void computeNewVertex( const CornerTable* surface, const CornerType corner, double* attributes ) { //Get the index of the vertices on edge. const CornerType p1 = surface->cornerToVertexIndex( surface->cornerNext( corner ) ); const CornerType p2 = surface->cornerToVertexIndex( surface->cornerPrevious( corner ) ); //Get the geometry vector. const double* G = surface->getAttributes( ); //Get the number of coordinates by vector. unsigned int n = surface->getNumberAttributesByVertex( ); //Compute the middle point and set on vector. for (unsigned int i = 0; i < n; i++) { attributes[i] = ( G[n * p1 + i] + G[n * p2 + i] ) / 2.0; } } /** * Refine the top and the bottom of the hexagon with different refinement levels * as constraints. * @param refinement - object to perform the refinement. * @param r - distance from the center to include triangles. */ void refinementExample( CornerTableAdaptiveRefinement* refinement, double r = 2 ) { //Get the surface representation. CornerTable* surface = refinement->getSurface( ); //A set of selected triangles to be refined. std::set selectedTriangles; //Get the number of triangles on current mesh. CornerType numberTriangles = surface->getNumTriangles( ); //Select triangles to be refined. for (CornerType t = 0; t < numberTriangles; t++) { //Get the vertices index of the triangle. CornerType v1 = surface->getTriangleList( )[3 * t + 0]; CornerType v2 = surface->getTriangleList( )[3 * t + 1]; CornerType v3 = surface->getTriangleList( )[3 * t + 2]; //Get the (x,y) coordinates of each vertex. double x1 = surface->getAttributes( )[2 * v1 + 0]; double y1 = surface->getAttributes( )[2 * v1 + 1]; double x2 = surface->getAttributes( )[2 * v2 + 0]; double y2 = surface->getAttributes( )[2 * v2 + 1]; double x3 = surface->getAttributes( )[2 * v3 + 0]; double y3 = surface->getAttributes( )[2 * v3 + 1]; //If at least one vertice is in circle, include the triangle. if (x1 * x1 + y1 * y1 < r * r || x2 * x2 + y2 * y2 < r * r || x3 * x3 + y3 * y3 < r * r) { selectedTriangles.insert( t ); } } //Comment and uncomment the follow call functions to test different //triangulation. //Refine the triangle mesh without undo mechanism, the ARTMe triangulation and //the default callback. //refinement->meshAdaptiveRefinement( selectedTriangles ); //Refine the triangle mesh with undo mechanism, the ARTMe triangulation and //our callback. The radius is set as 0 because it is used just in the //incremental refinement. refinement->meshAdaptiveRefinement( selectedTriangles, true, CornerTableAdaptiveRefinement::ARTMe, 0, computeNewVertex ); //Refine the triangle mesh with undo mechanism, the REDGREEN triangulation and //our callback. The radius is set as 0 because it is used just in the //incremental refinement. //refinement->meshAdaptiveRefinement( selectedTriangles, true, // CornerTableAdaptiveRefinement::REDGREEN, // 0, computeNewVertex ); //Refine the triangle mesh with undo mechanism, the INCREMENTAL triangulation. //refinement->meshAdaptiveRefinement( selectedTriangles, true, // CornerTableAdaptiveRefinement::INCREMENTAL, // 3, computeNewVertex ); } /* * */ int main( int argc, char** argv ) { //Get the surface. CornerTable* surface = createNewMesh( ); //Create the refinement object. CornerTableAdaptiveRefinement* refinement = new CornerTableAdaptiveRefinement( surface ); //Write the original mesh. refinement->writeMeshOFFFIle( "original.off" ); double r = 2; LevelType maxLevel = 6; for (LevelType l = 0; l < maxLevel; l++) { refinementExample( refinement, r ); } //Write the resulting mesh. refinement->writeMeshOFFFIle( "refined.off" ); //Perform all undo steps. while (!refinement->undoIsEmpty( )) { refinement->makeUndo( ); } //Write the resulting mesh after all undo steps. refinement->writeMeshOFFFIle( "originalCopy.off" ); //Perform all redo steps. while (!refinement->redoIsEmpty( )) { refinement->makeRedo( ); } //Write the resulting mesh after all redo steps. refinement->writeMeshOFFFIle( "refinedCopy.off" ); //Free memory. delete refinement; delete surface; return 0; }