Main Page | Modules | Class Hierarchy | Alphabetical List | Class List | File List | Class Members | Related Pages

A Simple Example

This example creates a planar surface (i.e. a rectangle) and the adaptation function of the tesselation is based on a target resolution level "l" and a vertical threshold "t", so that the mesh will have resolution "l-1" below "t" and "l+1" above "t".

class Plane : public virtual Surface { public: double* pts; int* fcs; int np, nf; int target_level; double ythresh; Plane() { double mpts[] = { 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 1, 0, }; int mfcs[] = { 0, 3, 1, 3, 0, 2, }; target_level = 4; ythresh = 0.0; np = 4; nf = 2; pts = new double[np*3]; fcs = new int[nf*3]; for (int i = 0; i < np*3; i++) pts[i] = mpts[i]; for (int i = 0; i < nf*3; i++) fcs[i] = mfcs[i]; } ~Plane() { delete[] pts; delete[] fcs; } void Plane::base_mesh(int *pnp, int **pfcs, int *pnf) { *pnp = np; *pfcs = fcs; *pnf = nf; } void Plane::sample(int k, Vertex* v) { int i = k * 3; Vector3 p(pts[i], pts[i+1], pts[i+2]); Pvert* pv = Pvert::cast(v); pv->a = Point(p); } void Plane::sample(Edge* e, Vertex* v) { Pvert* v0 = Pvert::cast(e->org()); Pvert* v1 = Pvert::cast(e->dst()); Vector3 p = 0.5 * (v0->a.g + v1->a.g); Pvert *pv = Pvert::cast(v); pv->a = Point(p); } void Plane::sample(Face *f, Vertex* v) { Pvert* v0 = Pvert::cast(f->vertex(0)); Pvert* v1 = Pvert::cast(f->vertex(1)); Pvert* v2 = Pvert::cast(f->vertex(2)); Vector3 p = (v0->a.g + v1->a.g + v2->a.g) / 3.0; Pvert *pv = Pvert::cast(v); pv->a = Point(p); } float Plane::elenght(Edge* e) { Pvert* v0 = Pvert::cast(e->org()); Pvert* v1 = Pvert::cast(e->dst()); Vector3 p = (v1->a.g - v0->a.g); return norm(p); } float Plane::ref_rank(Edge *e) { Pvert* v0 = Pvert::cast(e->org()); Pvert* v1 = Pvert::cast(e->dst()); Vector3 p = (v0->a.g + v0->a.g) * 0.5; if (p[Y] < ythresh) return (e->level() < target_level + 1)? 1 : -1; else return (e->level() < target_level - 1)? 1 : -1; } float Plane::simpl_rank(Vertex *w) { Pvert* v = Pvert::cast(w); if (v->a.g[Y] < ythresh) return (v->level()-1 > target_level + 1)? 1 : -1; else return (v->level()-1 > target_level - 1)? 1 : -1; } Vertex* new_vertex(void) { return new Pvert(); } void del_vertex(Vertex *v) { delete(Pvert::cast(v)); } };

The geometric attributes are defined by the classes Point and Pvert.

struct Point { Vector3 g; // 3D position Point() {} Point(Vector3 pos) : g(pos) {} Point(double x, double y, double z) { g[X]=x; g[Y]=y; g[Z]=z; } }; class Pvert : public Vertex { public: Point a; Pvert(void) : Vertex(), a(0,0,0) {}; static Pvert* cast(Vertex* v) { return static_cast<Pvert *>(v); } };

The planar surface is used to instantiate an adaptive mesh, defined as global objects.

Plane p2; Mesh m(&p2);

The application is based on GLUT and uses the "-/=" keys to change the target resolution level, the ",/." keys to move the threshold.

void change_level(int i) { p2.target_level += i; if (p2.target_level < 2) p2.target_level = 2; glutPostRedisplay(); } void change_thresh(double d) { p2.ythresh += d; glutPostRedisplay(); } void adapt_and_display_mesh() { m.adapt_refine(0); m.adapt_simplify(0); display_mesh(m); } void display(void) { glClear (GL_COLOR_BUFFER_BIT); adapt_and_display_mesh(); glutSwapBuffers(); } void keyboard(unsigned char key, int x, int y) { switch(key) { case 27: exit(0); case '-': change_level(-1); break; case '=': change_level(1); break; case ',': change_thresh(-0.1); break; case '.': change_thresh(0.1); break; default: break; } } int main(int argc, char** argv) { int wsize = 512; glutInit(&argc, argv); glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB); glutInitWindowSize (wsize, wsize); glutCreateWindow ("levels"); initgl(); glutDisplayFunc(display); glutKeyboardFunc(keyboard); glutMainLoop(); return 0; }

The display is done with OpenGL.

void draw_tri(double x0, double y0, double z0, double x1, double y1, double z1, double x2, double y2, double z2) { glColor3f (0.0, 0.0, 0.0); glBegin(GL_LINE_LOOP); glVertex3d(x0, y0, z0); glVertex3d(x1, y1, z1); glVertex3d(x2, y2, z2); glEnd(); } void display_mesh(Mesh &s) { for (FaceIter f = s.faces_begin(); f != s.faces_end(); f++) { Pvert *v0 = Pvert::cast((*f)->vertex(0)); Pvert *v1 = Pvert::cast((*f)->vertex(1)); Pvert *v2 = Pvert::cast((*f)->vertex(2)); draw_tri(v0->a.g[X], v0->a.g[Y], v0->a.g[Z], v1->a.g[X], v1->a.g[Y], v1->a.g[Z], v2->a.g[X], v2->a.g[Y], v2->a.g[Z]); } } void initgl(void) { glClearColor (1.0, 1.0, 1.0, 1.0); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(0.0, 1.0, 0.0, 1.0, -1.0, 1.0); }

Generated on Mon Oct 11 19:32:26 2004 for A48 by doxygen 1.3.7