struct node { float x, y, z; /* location */ float nx, ny, nz; /* surface normals */ float s; /* scalar value */ }; typedef struct node Node; void ProcessCube( Node *, Node *, Node *, Node *, Node *, Node *, Node *, Node * ); int ProcessCubeEdge( Node *, Node *, int ); void ProcessCubeQuad( Node *, Node *, Node *, Node *, int, int, int, int ); void DrawCubeTriangles(); int FoundEdgeIntersection[12]; /* TRUE means edge has an S* intersection */ Node EdgeIntersection[12]; /* where cube edge intersection occured */ int FoundEdgeConnection[12][12]; /* TRUE means edges are connected */ . . . /* compute the normals: */ for( i=0; i <= NSTEPS; i++ ) { for( j=0; j <= NSTEPS; j++ ) { for( k=0; k <= NSTEPS; k++ ) { np = &Nodes[i][j][k]; if( i == 0 ) np->nx = ( Nodes[1][j][k].s - np->s ) / DX; else if( i == NSTEPS ) np->nx = ( np->s - Nodes[NSTEPS-1][j][k].s ) / DX; else np->nx = ( Nodes[i+1][j][k].s - Nodes[i-1][j][k].s ) / ( 2.*DX ); ????? Unitize( &np->nx ); } } } . . . void ProcessCube( Node *p0, Node *p1, Node *p2, Node *p3, Node *p4, Node *p5, Node *p6, Node *p7 ) { int i; /* counter */ int n; /* # edges intersected in this cube */ /* set all edge intersections to "no intersection": */ for( i = 0; i < 12; i++ ) FoundEdgeIntersection[i] = FALSE; /* produce all edge intersections and count them up: */ n = 0; n += ProcessCubeEdge( p0, p1, 0 ); n += ProcessCubeEdge( p1, p2, 1 ); n += ProcessCubeEdge( p2, p3, 2 ); n += ProcessCubeEdge( p3, p0, 3 ); n += ProcessCubeEdge( p4, p5, 4 ); n += ProcessCubeEdge( p5, p6, 5 ); n += ProcessCubeEdge( p6, p7, 6 ); n += ProcessCubeEdge( p7, p4, 7 ); n += ProcessCubeEdge( p0, p4, 8 ); n += ProcessCubeEdge( p1, p5, 9 ); n += ProcessCubeEdge( p2, p6, 10 ); n += ProcessCubeEdge( p3, p7, 11 ); /* get out if found no intersections: */ if( n == 0 ) return; /* process each quad's intersections into edges: */ ProcessCubeQuad( p0, p3, p7, p4, 3, 11, 7, 8 ); ProcessCubeQuad( p1, p2, p6, p5, 1, 10, 5, 9 ); ProcessCubeQuad( p0, p1, p5, p4, 0, 9, 4, 8 ); ProcessCubeQuad( p2, p3, p7, p6, 2, 11, 6, 10 ); ProcessCubeQuad( p0, p1, p2, p3, 0, 1, 2, 3 ); ProcessCubeQuad( p4, p5, p6, p7, 4, 5, 6, 7 ); /* process the cube's edges into triangles: */ DrawCubeTriangles(); } int ProcessCubeEdge( Node *pa, Node *pb, int edge ) { float num, den, tstar; /* parametric intersection */ ????? EdgeIntersection[edge].x = pa->x + tstar * ( pb->x - pa->x ); EdgeIntersection[edge].y = pa->y + tstar * ( pb->y - pa->y ); EdgeIntersection[edge].z = pa->z + tstar * ( pb->z - pa->z ); EdgeIntersection[edge].nx = pa->nx + tstar * ( pb->nx - pa->nx ); EdgeIntersection[edge].ny = pa->ny + tstar * ( pb->ny - pa->ny ); EdgeIntersection[edge].nz = pa->nz + tstar * ( pb->nz - pa->nz ); Unitize( &EdgeIntersection[edge].nx ); return 1; } void ProcessCubeQuad( Node *pa, Node *pb, Node *pc, Node *pd, int eab, int ebc, int ecd, int eda ) { int n; /* # of intersections */ int nfound; /* how many intersections found so far */ int e[4]; /* found intersections */ float smid; /* s at the quad midpoint */ /* count the number of intersections in this quad: */ nfound = 0; if( FoundEdgeIntersection[eab] ) { e[nfound] = eab; nfound++; } if( FoundEdgeIntersection[ebc] ) { e[nfound] = ebc; nfound++; } if( FoundEdgeIntersection[ecd] ) { e[nfound] = ecd; nfound++; } if( FoundEdgeIntersection[eda] ) { e[nfound] = eda; nfound++; } /* nfound is the number of intersections in this quad: */ switch( nfound ) { case 0: return; case 1: case 3: fprintf( stderr, "ProcessCubeQuad found %d intersections\n", n ); return; case 2: ????? break; case 4: ????? return; } } void DrawCubeTriangles() { int found; /* TRUE means found an edge pair to start with */ int ea, eb, ec; /* 3 edges of the triangle */ /* loop until all edges have been used up: */ for( ; ; ) { found = FALSE; for( ea = 0; ea < 12; ea++ ) { for( eb = 0; eb < 12; eb++ ) { if( FoundEdgeConnection[ea][eb] == TRUE ) { found = TRUE; break; } } if( found == TRUE ) break; /* short cut out */ } /* if found nothing, then all connections have been used:*/ if( found == FALSE ) break; /* have a connection from edge #ea to edge #eb: */ /* find an edge #ec connected to edge #eb: */ for( ec = 0; ec < 12; ec++ ) { if( ec == ea ) continue; if( FoundEdgeConnection[eb][ec] == TRUE ) break; } /* if didn't find a third edge, something is wrong: */ if( ec >= 12 ) { fprintf( stderr, "Could not find a 3rd edge in DrawCubeTriangles()\n" ); return; } /* draw the triangle from ea to eb to ec: */ ????? /* don't need connections between ea-eb and eb-ec anymore: */ FoundEdgeConnection[ea][eb] = FALSE; FoundEdgeConnection[eb][ea] = FALSE; FoundEdgeConnection[eb][ec] = FALSE; FoundEdgeConnection[ec][eb] = FALSE; /* *toggle* connection between ec and ea: */ /* if it was there before, we don't need it anymore: */ /* if it was not there, we have just invented it, */ /* and will need it again: */ FoundEdgeConnection[ec][ea] = ! FoundEdgeConnection[ec][ea]; FoundEdgeConnection[ea][ec] = ! FoundEdgeConnection[ea][ec]; } }