// Bloomenthal.h: Bloomenthal's polygonizer // ////////////////////////////////////////////////////////////////////// #ifndef BLOOMENTHAL #define BLOOMENTHAL #include #include #include //#include #include "ImplicitFunction.h" #include "Mesh.h" /* * C code from the article * "An Implicit Surface Polygonizer" * by Jules Bloomenthal, jbloom@beauty.gmu.edu * in "Graphics Gems IV", Academic Press, 1994 */ /* implicit.c * an implicit surface polygonizer, translated from Mesa * applications should call polygonize() * * to compile a test program for ASCII output: * cc implicit.c -o implicit -lm * * to compile a test program for display on an SGI workstation: * cc -DSGIGFX implicit.c -o implicit -lgl_s -lm * * Authored by Jules Bloomenthal, Xerox PARC. * Copyright (c) Xerox Corporation, 1991. All rights reserved. * Permission is granted to reproduce, use and distribute this code for * any and all purposes, provided that this notice appears in all copies. */ #define TET 0 /* use tetrahedral decomposition */ #define NOTET 1 /* no tetrahedral decomposition */ #define RES 50 /* # converge iterations */ #define L 0 /* left direction: -x, -i */ #define R 1 /* right direction: +x, +i */ #define B 2 /* bottom direction: -y, -j */ #define T 3 /* top direction: +y, +j */ #define N 4 /* near direction: -z, -k */ #define F 5 /* far direction: +z, +k */ #define LBN 0 /* left bottom near corner */ #define LBF 1 /* left bottom far corner */ #define LTN 2 /* left top near corner */ #define LTF 3 /* left top far corner */ #define RBN 4 /* right bottom near corner */ #define RBF 5 /* right bottom far corner */ #define RTN 6 /* right top near corner */ #define RTF 7 /* right top far corner */ /* the LBN corner of cube (i, j, k), corresponds with location * (start.x+(i-.5)*size, start.y+(j-.5)*size, start.z+(k-.5)*size) */ #define RAND() ((rand()&32767)/32767.) /* random number between 0 and 1 */ #define HASHBIT (5) #define HASHSIZE (size_t)(1<<(3*HASHBIT)) /* hash table size (32768) */ #define MASK ((1<>(bit))&1) #define FLIP(i,bit) ((i)^1<<(bit)) /* flip the given bit of i */ #define LB 0 /* left bottom edge */ #define LT 1 /* left top edge */ #define LN 2 /* left near edge */ #define LF 3 /* left far edge */ #define RB 4 /* right bottom edge */ #define RT 5 /* right top edge */ #define RN 6 /* right near edge */ #define RF 7 /* right far edge */ #define BN 8 /* bottom near edge */ #define BF 9 /* bottom far edge */ #define TN 10 /* top near edge */ #define TF 11 /* top far edge */ //void *calloc(); //char *mycalloc(); #define TRIFILE "tri.tmp" #define VERFILE "ver.tmp" namespace polygonizer{ class Bloomenthal{ typedef struct point { /* a three-dimensional point */ double x, y, z; /* its coordinates */ } POINT1; typedef struct test1 { /* test the function for a signed value */ POINT1 p; /* location of test */ double value; /* function value at p */ int ok; /* if value is of correct sign */ } TEST1; typedef struct vertex { /* surface vertex */ POINT1 position;//, normal; /* position and surface normal */ } VERTEX; typedef struct vertices { /* list of vertices in polygonization */ int count, max; /* # vertices, max # allowed */ VERTEX *ptr; /* dynamically allocated */ } VERTICES; typedef struct corner { /* corner of a cube */ int i, j, k; /* (i, j, k) is index within lattice */ double x, y, z, value; /* location and function value */ } CORNER; typedef struct cube { /* partitioning cell (cube) */ int i, j, k; /* lattice location of cube */ CORNER *corners[8]; /* eight corners */ } CUBE; typedef struct cubes { /* linked list of cubes acting as stack */ CUBE cube; /* a single cube */ struct cubes *next; /* remaining elements */ } CUBES; typedef struct centerlist { /* list of cube locations */ int i, j, k; /* cube location */ struct centerlist *next; /* remaining elements */ } CENTERLIST; typedef struct cornerlist { /* list of corners */ int i, j, k; /* corner id */ double value; /* corner value */ struct cornerlist *next; /* remaining elements */ } CORNERLIST; typedef struct edgelist { /* list of edges */ int i1, j1, k1, i2, j2, k2; /* edge corner ids */ int vid; /* vertex id */ struct edgelist *next; /* remaining elements */ } EDGELIST; typedef struct intlist { /* list of integers */ int i; /* an integer */ struct intlist *next; /* remaining elements */ } INTLIST; typedef struct trilist { int i1, i2, i3; struct trilist *next; } TRILIST; typedef struct intlists { /* list of list of integers */ INTLIST *list; /* a list of integers */ struct intlists *next; /* remaining elements */ } INTLISTS; typedef struct process { /* parameters, function, storage */ //double (*function)(double x, double y, double z); /* implicit surface function */ //int (*triproc)(int i1, int i2, int i3, VERTICES vertices); /* triangle output function */ double size, delta; /* cube size, normal delta */ //int bounds; /* cube range within lattice */ float boundsX1, boundsX2; float boundsY1, boundsY2; float boundsZ1, boundsZ2; POINT1 start; /* start point on surface */ CUBES *cubes; /* active cubes */ VERTICES vertices; /* surface vertices */ CENTERLIST **centers; /* cube center hash table */ CORNERLIST **corners; /* corner value hash table */ EDGELIST **edges; /* edge and vertex id hash table */ } PROCESS; public: ImplicitFunction *func; //INTLISTS *cubetable[256]; int gntris; /* global needed by application */ VERTICES gvertices; /* global needed by application */ TRILIST *tris; FILE* tri_file; FILE* ver_file; float accuracy; public: double function(double x, double y, double z); void converge (POINT1 *p1, POINT1 *p2, double v, POINT1 *p); void vnormal (POINT1 *point, PROCESS *p, POINT1 *v); void addtovertices (VERTICES *vertices, VERTEX v); int vertid (CORNER *c1, CORNER *c2, PROCESS *p); int getedge (EDGELIST *table[], int i1, int j1, int k1, int i2, int j2, int k2); void setedge (EDGELIST *table[], int i1, int j1, int k1, int i2, int j2, int k2, int vid); int setcenter(CENTERLIST *table[], int i, int j, int k); char * mycalloc (int nitems, int nbytes); void makecubetable (); int otherface (int edge, int face); int nextcwedge (int edge, int face); int docube (CUBE* cube, PROCESS* p); int dotet (CUBE* cube, int c1, int c2, int c3, int c4, PROCESS* p); TEST1* find1(int sign1, PROCESS* p, double x, double y, double z); CORNER * setcorner1(PROCESS* p, int i, int j, int k); void testface (int i, int j, int k, CUBE* old, int face, int c1, int c2, int c3, int c4, PROCESS* p); char* polygonize (Mesh *mesh, double size, float bounds[6], double x, double y, double z, int mode); int triproc (int i1, int i2, int i3, VERTICES vertices); double blob (double x, double y, double z); double sphere (double x, double y, double z); double torus (double x, double y, double z); Bloomenthal(); virtual ~Bloomenthal(); }; } #endif