# HG changeset patch # User John Tsiombikas # Date 1319574092 -10800 # Node ID 2c575855f70783a15bde3f147fee9f88e8d0c2b0 # Parent 52664d3451ad8dc382bdff0241948f5c594ba429 added simple example diff -r 52664d3451ad -r 2c575855f707 .hgignore --- a/.hgignore Tue Oct 25 13:30:03 2011 +0300 +++ b/.hgignore Tue Oct 25 23:21:32 2011 +0300 @@ -5,3 +5,4 @@ ^libmetasurf\.a$ ^metasurf\.dylib ^Makefile$ +\.png$ diff -r 52664d3451ad -r 2c575855f707 Makefile.in --- a/Makefile.in Tue Oct 25 13:30:03 2011 +0300 +++ b/Makefile.in Tue Oct 25 23:21:32 2011 +0300 @@ -52,6 +52,7 @@ cp src/$(hdr) $(PREFIX)/include/$(hdr) cp $(lib_so) $(PREFIX)/lib/$(lib_so) [ -n "$(soname)" ] \ + && rm -f $(PREFIX)/lib/$(soname) $(PREFIX)/lib/$(devlink) \ && ln -s $(PREFIX)/lib/$(lib_so) $(PREFIX)/lib/$(soname) \ && ln -s $(PREFIX)/lib/$(soname) $(PREFIX)/lib/$(devlink) \ || true diff -r 52664d3451ad -r 2c575855f707 examples/simple/Makefile --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/examples/simple/Makefile Tue Oct 25 23:21:32 2011 +0300 @@ -0,0 +1,20 @@ +src = $(wildcard *.c) +obj = $(src:.c=.o) +bin = simple + +CC = gcc +CFLAGS = -pedantic -Wall -g -I../../src +LDFLAGS = -L../.. -lmetasurf $(libgl) + +ifeq ($(shell uname -s), Darwin) + libgl = -framework OpenGL -framework GLUT +else + libgl = -lGL -lGLU -lglut +endif + +$(bin): $(obj) + $(CC) -o $@ $(obj) $(LDFLAGS) + +.PHONY: clean +clean: + rm -f $(obj) $(bin) diff -r 52664d3451ad -r 2c575855f707 examples/simple/simple.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/examples/simple/simple.c Tue Oct 25 23:21:32 2011 +0300 @@ -0,0 +1,103 @@ +#include + +#ifndef __APPLE__ +#include +#else +#include +#endif + +#include "metasurf.h" + +float eval(float x, float y, float z); +void disp(void); +void reshape(int x, int y); +void keyb(unsigned char key, int x, int y); + +struct metasurface *ms; + +int main(int argc, char **argv) +{ + float ldir[] = {-0.3, 0.3, 1, 0}; + + glutInitWindowSize(800, 600); + glutInit(&argc, argv); + glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH); + glutCreateWindow("metasurf example: simple"); + + glutDisplayFunc(disp); + glutReshapeFunc(reshape); + glutKeyboardFunc(keyb); + + glEnable(GL_DEPTH_TEST); + glEnable(GL_CULL_FACE); + + glEnable(GL_LIGHTING); + glEnable(GL_LIGHT0); + glLightfv(GL_LIGHT0, GL_POSITION, ldir); + + glEnable(GL_NORMALIZE); + + ms = msurf_create(); + /* consider anything below the threshold (0 by default) to be inside */ + msurf_inside(ms, MSURF_LESS); + /* set the evaluation callback */ + msurf_eval_func(ms, eval); + /* pass any vertices and normals generated directly to OpenGL */ + msurf_vertex_func(ms, glVertex3f); + msurf_normal_func(ms, glNormal3f); + /* slightly increase the bounds to avoid clipping the unit sphere */ + msurf_bounds(ms, -1.1, -1.1, -1.1, 1.1, 1.1, 1.1); + + glutMainLoop(); + return 0; +} + +/* the unit sphere is implicitly defined as the locus of points in R3 satisfying + * the equation: x^2 + y^2 + z^2 - 1 = 0 + */ +float eval(float x, float y, float z) +{ + return (x * x + y * y + z * z) - 1.0; +} + +void disp(void) +{ + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + glTranslatef(0, 0, -3); + + glBegin(GL_TRIANGLES); + msurf_polygonize(ms); + glEnd(); + + glutSwapBuffers(); +} + +void reshape(int x, int y) +{ + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + gluPerspective(45.0, (float)x / (float)y, 0.5, 500.0); +} + +void keyb(unsigned char key, int x, int y) +{ + switch(key) { + case 27: + exit(0); + + case 'w': + { + static int wire; + wire = !wire; + glPolygonMode(GL_FRONT_AND_BACK, wire ? GL_LINE : GL_FILL); + glutPostRedisplay(); + } + break; + + default: + break; + } +} diff -r 52664d3451ad -r 2c575855f707 src/metasurf.c --- a/src/metasurf.c Tue Oct 25 13:30:03 2011 +0300 +++ b/src/metasurf.c Tue Oct 25 23:21:32 2011 +0300 @@ -38,6 +38,9 @@ msurf_vertex_func_t vertex; msurf_normal_func_t normal; + float dx, dy, dz; + int flip; + vec3 vbuf[3]; int nverts; }; @@ -81,9 +84,28 @@ ms->res[0] = ms->res[1] = ms->res[2] = 40; ms->nverts = 0; + ms->dx = ms->dy = ms->dz = 0.001; + ms->flip = 0; + return 0; } +void msurf_inside(struct metasurface *ms, int inside) +{ + switch(inside) { + case MSURF_GREATER: + ms->flip = 0; + break; + + case MSURF_LESS: + ms->flip = 1; + break; + + default: + fprintf(stderr, "msurf_inside expects MSURF_GREATER or MSURF_LESS\n"); + } +} + void msurf_eval_func(struct metasurface *ms, msurf_eval_func_t func) { ms->eval = func; @@ -219,6 +241,10 @@ vec3 vert[12]; unsigned int code = mc_bitcode(val, ms->thres); + if(ms->flip) { + code = ~code & 0xff; + } + if(mc_edge_table[code] == 0) { return; } @@ -238,6 +264,21 @@ for(i=0; mc_tri_table[code][i] != -1; i+=3) { for(j=0; j<3; j++) { float *v = vert[mc_tri_table[code][i + j]]; + + if(ms->normal) { + float dfdx, dfdy, dfdz; + dfdx = ms->eval(v[0] - ms->dx, v[1], v[2]) - ms->eval(v[0] + ms->dx, v[1], v[2]); + dfdy = ms->eval(v[0], v[1] - ms->dy, v[2]) - ms->eval(v[0], v[1] + ms->dy, v[2]); + dfdz = ms->eval(v[0], v[1], v[2] - ms->dz) - ms->eval(v[0], v[1], v[2] + ms->dz); + + if(ms->flip) { + dfdx = -dfdx; + dfdy = -dfdy; + dfdz = -dfdz; + } + ms->normal(dfdx, dfdy, dfdz); + } + ms->vertex(v[0], v[1], v[2]); } } diff -r 52664d3451ad -r 2c575855f707 src/metasurf.h --- a/src/metasurf.h Tue Oct 25 13:30:03 2011 +0300 +++ b/src/metasurf.h Tue Oct 25 23:21:32 2011 +0300 @@ -19,6 +19,9 @@ #ifndef METASURF_H_ #define METASURF_H_ +#define MSURF_GREATER 1 +#define MSURF_LESS 0 + struct metasurface; typedef float (*msurf_eval_func_t)(float, float, float); @@ -32,6 +35,9 @@ struct metasurface *msurf_create(void); void msurf_free(struct metasurface *ms); +/* which is inside above or below the threshold */ +void msurf_inside(struct metasurface *ms, int inside); + /* set a scalar field evaluator function */ void msurf_eval_func(struct metasurface *ms, msurf_eval_func_t func);