/* * *************************************************************************** * Routine: SurfaceMesh_refine * * Author: Johan Hake ([email protected]) * * Purpose: Refine a surface mesh and recalculate the neighbors * *************************************************************************** */ void SurfaceMesh_refine(SurfaceMesh* surfmesh) { unsigned int local_num_edges = 0, total_num_edges = 0, edge_num = 0; unsigned int min_vertex_num, max_vertex_num, face_num; unsigned int k, m, n, nv; unsigned int a, b, c; unsigned int* num_edges; unsigned int* offsets; unsigned int* vertex2edge; unsigned int local_vertices[3], local_additional_vertices[3]; NPNT3* ngr; SurfaceMesh* surfmesh_refine; float ax, ay, az; float nx, ny, nz; // Check if neighborlist is created if (surfmesh->neighbor_list == NULL) SurfaceMesh_createNeighborlist(surfmesh); NPNT3** neighbor_list = surfmesh->neighbor_list; // Assign the number of vertices in the original mesh nv = surfmesh->num_vertices; // Create an array with the number of edges associated with each vertex num_edges = (unsigned int*)malloc(sizeof(unsigned int)*nv); // Create an array with the offsets into the vertex2edge array for each vertex offsets = (unsigned int*)malloc(sizeof(unsigned int)*nv); // Iterate over all vertices and collect edges for (n = 0; n < nv; n++){ offsets[n] = total_num_edges; local_num_edges = 0; ngr = neighbor_list[n]; while (ngr != NULL) { // If n is smaller than ngr->a we have an edge if (n < ngr->a){ total_num_edges++; local_num_edges++; } ngr = ngr->next; } num_edges[n] = local_num_edges; } // Create memory for the refined mesh surfmesh_refine = SurfaceMesh_ctor(nv + total_num_edges, surfmesh->num_faces*4); surfmesh_refine->num_vertices = nv; surfmesh_refine->num_faces = surfmesh->num_faces; // Copy the original mesh to the new mesh for (n = 0; n < nv; n++) { surfmesh_refine->vertex[n].x = surfmesh->vertex[n].x; surfmesh_refine->vertex[n].y = surfmesh->vertex[n].y; surfmesh_refine->vertex[n].z = surfmesh->vertex[n].z; } for (n = 0; n < surfmesh->num_faces; n++) { surfmesh_refine->face[n].a = surfmesh->face[n].a; surfmesh_refine->face[n].b = surfmesh->face[n].b; surfmesh_refine->face[n].c = surfmesh->face[n].c; } // Create the map from vertices to edges vertex2edge = (unsigned int*)malloc(sizeof(unsigned int)*total_num_edges); // Iterate over all vertices and split edges for (n = 0; n < nv; n++){ // Get the coordinates of vertex n nx = surfmesh_refine->vertex[n].x; ny = surfmesh_refine->vertex[n].y; nz = surfmesh_refine->vertex[n].z; ngr = neighbor_list[n]; while (ngr != NULL) { // If n is smaller than ngr->a we have an edge if (n < ngr->a){ // Add the value of the opposite vertex to the map vertex2edge[edge_num] = ngr->a; // Get the coordinates of vertex ngr->a ax = surfmesh_refine->vertex[ngr->a].x; ay = surfmesh_refine->vertex[ngr->a].y; az = surfmesh_refine->vertex[ngr->a].z; // Add the new vertex coordinates of the splitted edge surfmesh_refine->vertex[nv + edge_num].x = 0.5*(ax + nx); surfmesh_refine->vertex[nv + edge_num].y = 0.5*(ay + ny); surfmesh_refine->vertex[nv + edge_num].z = 0.5*(az + nz); // Increase the edge number edge_num++; } ngr = ngr->next; } } // A counter for adding new faces face_num = surfmesh_refine->num_faces; // Iterate over faces and add information of the refined face for (n = 0; n < surfmesh_refine->num_faces; n++) { local_vertices[0] = surfmesh_refine->face[n].a; local_vertices[1] = surfmesh_refine->face[n].b; local_vertices[2] = surfmesh_refine->face[n].c; // Iterate over the vertices and find the edges for (m = 0; m < 3; m++){ min_vertex_num = min(local_vertices[m], local_vertices[(m+1)%3]); max_vertex_num = max(local_vertices[m], local_vertices[(m+1)%3]); // Find the edge number that fit the pair of vertices for (k = 0; k < num_edges[min_vertex_num]; k++) if (vertex2edge[offsets[min_vertex_num] + k] == max_vertex_num) break; // The edge number represents the number of the added vertex plus the // number of original vertices local_additional_vertices[m] = nv + offsets[min_vertex_num] + k; } // Add information of the four new faces // First the mid face surfmesh_refine->face[n].a = local_additional_vertices[0]; surfmesh_refine->face[n].b = local_additional_vertices[1]; surfmesh_refine->face[n].c = local_additional_vertices[2]; // Then the three corner faces for (m = 0; m < 3; m++){ surfmesh_refine->face[face_num].a = local_vertices[m]; surfmesh_refine->face[face_num].b = local_additional_vertices[m]; surfmesh_refine->face[face_num].c = local_additional_vertices[(m+2)%3]; face_num++; } } // Release memory free(num_edges); free(offsets); free(vertex2edge); // Update number information surfmesh_refine->num_vertices += total_num_edges; surfmesh_refine->num_faces *= 4; // Release old data SurfaceMesh_releaseData(surfmesh); // Assign the refined mesh to the passed surfmesh->num_vertices = surfmesh_refine->num_vertices; surfmesh->num_faces = surfmesh_refine->num_faces; surfmesh->vertex = surfmesh_refine->vertex; surfmesh->face = surfmesh_refine->face; // Free memory of refined surface mesh struct free(surfmesh_refine); // Recreate the neigborlist SurfaceMesh_createNeighborlist(surfmesh); }
/* FIXME: Are we using the neighbor list at all? */ GemMesh* GemMesh_fromTetgen(tetgenio& tetio) { GemMesh *gem_mesh; unsigned int i, j, k; FILE *fout; long node_index; int *face_type, tetra_node[4]; float x,y,z; int cell_type, boundary_face=0; float dist; long a,b,c,d; float ax,ay,az; float bx,by,bz; float cx,cy,cz; float dx,dy,dz; int active, exterior_cell_type; long neighbor, neightype; long *map_w_o,*map_w_i,*map_w_t; Triface** tet_to_triface; int tet0, tet1, tet2; int *tetp; bool on_boundary[2]; int* vertex_markers; Triface* triface; // Check for higher order cells const bool higher_order = tetio.numberofcorners==10; // Initialization and memory allocation gem_mesh = GemMesh_ctor(tetio.numberofpoints, tetio.numberoftetrahedra, higher_order); tet_to_triface = new Triface*[tetio.numberoftetrahedra]; vertex_markers = new int[tetio.numberofpoints]; for (i = 0; i < tetio.numberoftetrahedra; i++) tet_to_triface[i] = NULL; for (i = 0; i < tetio.numberofpoints; i++) vertex_markers[i] = 0; // Using the markers from the trifaces to mark vertices beeing on the boundary SurfaceMesh* boundary = SurfaceMesh_ctor(0, tetio.numberoftrifaces); for (i = 0; i < tetio.numberoftrifaces; i++) { tetp = &tetio.adjtetlist[i*2]; on_boundary[0] = tetp[0] >= 0 && tetp[1] < 0; on_boundary[1] = tetp[1] >= 0 && tetp[0] < 0; // Iterate over the adjacent tets and register stored face information for (j=0; j<2; j++) { // If no tet continue if (tetp[j] < 0) continue; triface = new Triface; triface->next = NULL; triface->points[0] = tetio.trifacelist[i*3]-1; triface->points[1] = tetio.trifacelist[i*3+1]-1; triface->points[2] = tetio.trifacelist[i*3+2]-1; // If we are on a boundary face register it if (on_boundary[j]) { boundary->face[boundary_face].a = triface->points[0]; boundary->face[boundary_face].b = triface->points[1]; boundary->face[boundary_face].c = triface->points[2]; if (tetio.trifacemarkerlist != NULL) boundary->face[boundary_face].m = tetio.trifacemarkerlist[i]; else boundary->face[boundary_face].m = 1; boundary_face++; } if (tetio.trifacemarkerlist != NULL) triface->marker = tetio.trifacemarkerlist[i]; else triface->marker = 1; triface->next = tet_to_triface[tetp[j]-1]; tet_to_triface[tetp[j]-1] = triface; vertex_markers[triface->points[0]] = triface->marker; vertex_markers[triface->points[1]] = triface->marker; vertex_markers[triface->points[2]] = triface->marker; } } // Store the actuall number of boundary faces boundary->num_faces = boundary_face; // Generate facetype information face_type = new int[tetio.numberoftetrahedra*4]; for (i = 0; i < tetio.numberoftetrahedra; i++) { // Zero out all face types for (j = 0; j < 4; j++) face_type[i*4+j] = 0; // Check tetra orientation a = tetio.tetrahedronlist[i * tetio.numberofcorners + 0] - 1; b = tetio.tetrahedronlist[i * tetio.numberofcorners + 1] - 1; c = tetio.tetrahedronlist[i * tetio.numberofcorners + 2] - 1; d = tetio.tetrahedronlist[i * tetio.numberofcorners + 3] - 1; ax = tetio.pointlist[a * 3]; ay = tetio.pointlist[a * 3 + 1]; az = tetio.pointlist[a * 3 + 2]; bx = tetio.pointlist[b * 3]; by = tetio.pointlist[b * 3 + 1]; bz = tetio.pointlist[b * 3 + 2]; cx = tetio.pointlist[c * 3]; cy = tetio.pointlist[c * 3 + 1]; cz = tetio.pointlist[c * 3 + 2]; dx = tetio.pointlist[d * 3]; dy = tetio.pointlist[d * 3 + 1]; dz = tetio.pointlist[d * 3 + 2]; bx -= ax; by -= ay; bz -= az; cx -= ax; cy -= ay; cz -= az; dx -= ax; dy -= ay; dz -= az; ax = by*cz-bz*cy; ay = bz*cx-bx*cz; az = bx*cy-by*cx; if (ax*dx+ay*dy+az*dz < 0 && !higher_order) { tetio.tetrahedronlist[i * 4 + 1] = c; tetio.tetrahedronlist[i * 4 + 2] = b; k = tetio.neighborlist[i * 4 + 1]; tetio.neighborlist[i * 4 + 1] = tetio.neighborlist[i * 4 + 2]; tetio.neighborlist[i * 4 + 2] = k; } // Check if we have a marked face while (tet_to_triface[i] != NULL) { // If so find out which face is on the boundary if (same_face(b, c, d, tet_to_triface[i]->points)) { face_type[i*4] = tet_to_triface[i]->marker; triface = tet_to_triface[i]; tet_to_triface[i] = triface->next; delete triface; continue; } if (same_face(a, c, d, tet_to_triface[i]->points)) { face_type[i*4+1] = tet_to_triface[i]->marker; triface = tet_to_triface[i]; tet_to_triface[i] = triface->next; delete triface; continue; } if (same_face(a, b, d, tet_to_triface[i]->points)) { face_type[i*4+2] = tet_to_triface[i]->marker; triface = tet_to_triface[i]; tet_to_triface[i] = triface->next; delete triface; continue; } if (same_face(a, b, c, tet_to_triface[i]->points)) { face_type[i*4+3] = tet_to_triface[i]->marker; triface = tet_to_triface[i]; tet_to_triface[i] = triface->next; delete triface; continue; } } } // Start output mesh gem_mesh->num_vertices = tetio.numberofpoints; gem_mesh->num_cells = tetio.numberoftetrahedra; // Write all nodes to a GemMesh structure for (i = 0; i < tetio.numberofpoints; i++) { gem_mesh->vv[i].id = i; gem_mesh->vv[i].chrt = vertex_markers[i]; // This might be ambigious gem_mesh->vv[i].x = tetio.pointlist[i * 3]; gem_mesh->vv[i].y = tetio.pointlist[i * 3 + 1]; gem_mesh->vv[i].z = tetio.pointlist[i * 3 + 2]; } // Write all tets to a GemMesh structure for (i = 0; i < tetio.numberoftetrahedra; i++) { gem_mesh->ss[i].id = i; gem_mesh->ss[i].grp = 0; if (tetio.numberoftetrahedronattributes > 0) gem_mesh->ss[i].mat = (int)tetio.tetrahedronattributelist[i*tetio.numberoftetrahedronattributes]; else gem_mesh->ss[i].mat = 0; gem_mesh->ss[i].fa = face_type[4*i+0]; gem_mesh->ss[i].fb = face_type[4*i+1]; gem_mesh->ss[i].fc = face_type[4*i+2]; gem_mesh->ss[i].fd = face_type[4*i+3]; // NOTE: Index in tetrahedronlist starts from 1 gem_mesh->ss[i].na = tetio.tetrahedronlist[i*tetio.numberofcorners+0] - 1; gem_mesh->ss[i].nb = tetio.tetrahedronlist[i*tetio.numberofcorners+1] - 1; gem_mesh->ss[i].nc = tetio.tetrahedronlist[i*tetio.numberofcorners+2] - 1; gem_mesh->ss[i].nd = tetio.tetrahedronlist[i*tetio.numberofcorners+3] - 1; // Add higher order cell info if (higher_order) { gem_mesh->hs[i].a = tetio.tetrahedronlist[i*tetio.numberofcorners+4] - 1; gem_mesh->hs[i].b = tetio.tetrahedronlist[i*tetio.numberofcorners+5] - 1; gem_mesh->hs[i].c = tetio.tetrahedronlist[i*tetio.numberofcorners+6] - 1; gem_mesh->hs[i].d = tetio.tetrahedronlist[i*tetio.numberofcorners+7] - 1; gem_mesh->hs[i].e = tetio.tetrahedronlist[i*tetio.numberofcorners+8] - 1; gem_mesh->hs[i].f = tetio.tetrahedronlist[i*tetio.numberofcorners+9] - 1; } } // Store boundary gem_mesh->boundary = boundary; // Release memory delete[] face_type; delete[] tet_to_triface; delete[] vertex_markers; return gem_mesh; }
SurfaceMesh* SurfaceMesh_marchingCube(int xdim, int ydim, int zdim, float* dataset, float isovalue, float* intensity, float intensity_isovalue, SPNT **holelist) { int tempt_x, tempt_y, tempt_z; int i,j,k; int m,n,l; int number, ii, stack_size; float den1,den2,ratio; int v_num, t_num; FLTVECT *vertex; INT3VECT *triangle; int cellVerts[12]; unsigned char cellIndex; INT3VECT *mc_edge; unsigned char *mc_sign; SurfaceMesh *surfmesh; SPNT *hole_end, *hole_start; FLTVECT interior_seed; float max_density = -9999.0; bool use_intensity; // Check if we are using intensity values (neede for Lattice Data) use_intensity = intensity != NULL; // Initialize memory vertex = (FLTVECT*)malloc(sizeof(FLTVECT)*xdim*ydim*zdim); triangle = (INT3VECT*)malloc(sizeof(INT3VECT)*xdim*ydim*zdim); v_num = 0; t_num = 0; mc_edge = (INT3VECT*)malloc(sizeof(INT3VECT)*xdim*ydim*zdim); mc_sign = (unsigned char*)malloc(sizeof(unsigned char)*xdim*ydim*zdim); // preprocessing: removing small holes for (k=0; k<zdim; k++) for (j=0; j<ydim; j++) for (i=0; i<xdim; i++) { if (dataset[IndexVect(i,j,k)] > max_density) max_density = dataset[IndexVect(i,j,k)]; mc_sign[IndexVect(i,j,k)] = 0; } triangle[0].a = 0; triangle[0].b = 0; triangle[0].c = 0; mc_sign[0] = 1; stack_size = 1; while (stack_size > 0) { stack_size--; tempt_x = triangle[stack_size].a; tempt_y = triangle[stack_size].b; tempt_z = triangle[stack_size].c; for (k=max(tempt_z-1,0); k<=min(tempt_z+1,zdim-1); k++) for (j=max(tempt_y-1,0); j<=min(tempt_y+1,ydim-1); j++) for (i=max(tempt_x-1,0); i<=min(tempt_x+1,xdim-1); i++) { if (dataset[IndexVect(i,j,k)] < isovalue && mc_sign[IndexVect(i,j,k)] == 0) { mc_sign[IndexVect(i,j,k)] = 1; triangle[stack_size].a = i; triangle[stack_size].b = j; triangle[stack_size].c = k; stack_size++; } } } hole_start = NULL; hole_end = NULL; den1 = 0; for (l=0; l<zdim; l++) for (n=0; n<ydim; n++) for (m=0; m<xdim; m++) { if (dataset[IndexVect(m,n,l)] > den1) { den1 = dataset[IndexVect(m,n,l)]; interior_seed.x = (float)m; interior_seed.y = (float)n; interior_seed.z = (float)l; } if (dataset[IndexVect(m,n,l)] < isovalue && mc_sign[IndexVect(m,n,l)] == 0) { number = 1; triangle[0].a = m; triangle[0].b = n; triangle[0].c = l; mc_sign[0] = 1; stack_size = 1; while (stack_size > 0) { stack_size--; tempt_x = triangle[stack_size].a; tempt_y = triangle[stack_size].b; tempt_z = triangle[stack_size].c; for (k=max(tempt_z-1,0); k<=min(tempt_z+1,zdim-1); k++) for (j=max(tempt_y-1,0); j<=min(tempt_y+1,ydim-1); j++) for (i=max(tempt_x-1,0); i<=min(tempt_x+1,xdim-1); i++) { if (dataset[IndexVect(i,j,k)] < isovalue && mc_sign[IndexVect(i,j,k)] == 0) { mc_sign[IndexVect(i,j,k)] = 1; triangle[stack_size].a = i; triangle[stack_size].b = j; triangle[stack_size].c = k; stack_size++; number++; } } } printf("hole size: %d \n",number); if (number < MIN_VOLUME) { triangle[0].a = m; triangle[0].b = n; triangle[0].c = l; dataset[IndexVect(m,n,l)] = max_density; stack_size = 1; while (stack_size > 0) { stack_size--; tempt_x = triangle[stack_size].a; tempt_y = triangle[stack_size].b; tempt_z = triangle[stack_size].c; for (k=max(tempt_z-1,0); k<=min(tempt_z+1,zdim-1); k++) for (j=max(tempt_y-1,0); j<=min(tempt_y+1,ydim-1); j++) for (i=max(tempt_x-1,0); i<=min(tempt_x+1,xdim-1); i++) { if (dataset[IndexVect(i,j,k)] < isovalue) { dataset[IndexVect(i,j,k)] = max_density; triangle[stack_size].a = i; triangle[stack_size].b = j; triangle[stack_size].c = k; stack_size++; } } } } else { /* could be improved here ?????*/ if (hole_start == NULL) { hole_end = (SPNT*)malloc(sizeof(SPNT)); hole_start = hole_end; } else { hole_end->next = (SPNT*)malloc(sizeof(SPNT)); hole_end = hole_end->next; } hole_end->x = (float)m; hole_end->y = (float)n; hole_end->z = (float)l; } } } if (hole_end != NULL) hole_end->next = NULL; *holelist = hole_start; for (k=0; k<zdim; k++) for (j=0; j<ydim; j++) for (i=0; i<xdim; i++) { if (dataset[IndexVect(i,j,k)] > isovalue-0.0001 && dataset[IndexVect(i,j,k)] < isovalue+0.0001) dataset[IndexVect(i,j,k)] = isovalue+0.0001; mc_edge[IndexVect(i,j,k)].a = -1; mc_edge[IndexVect(i,j,k)].b = -1; mc_edge[IndexVect(i,j,k)].c = -1; if (dataset[IndexVect(i,j,k)] >= isovalue) mc_sign[IndexVect(i,j,k)] = 1; else mc_sign[IndexVect(i,j,k)] = 255; } for (tempt_z=0; tempt_z<zdim-1; tempt_z++) for (tempt_y=0; tempt_y<ydim-1; tempt_y++) for (tempt_x=0; tempt_x<xdim-1; tempt_x++) { for (ii = 0; ii < 12; ii++) cellVerts[ii] = -1; cellIndex = 0; if (mc_sign[IndexVect(tempt_x,tempt_y,tempt_z)] == 255) cellIndex |= 1; if (mc_sign[IndexVect(tempt_x,tempt_y+1,tempt_z)] == 255) cellIndex |= 2; if (mc_sign[IndexVect(tempt_x+1,tempt_y+1,tempt_z)] == 255) cellIndex |= 4; if (mc_sign[IndexVect(tempt_x+1,tempt_y,tempt_z)] == 255) cellIndex |= 8; if (mc_sign[IndexVect(tempt_x,tempt_y,tempt_z+1)] == 255) cellIndex |= 16; if (mc_sign[IndexVect(tempt_x,tempt_y+1,tempt_z+1)] == 255) cellIndex |= 32; if (mc_sign[IndexVect(tempt_x+1,tempt_y+1,tempt_z+1)] == 255) cellIndex |= 64; if (mc_sign[IndexVect(tempt_x+1,tempt_y,tempt_z+1)] == 255) cellIndex |= 128; if (edgeTable[cellIndex] & 1) { if (mc_edge[IndexVect(tempt_x, tempt_y, tempt_z)].b == -1) { if(use_intensity) { den1 = intensity[IndexVect(tempt_x, tempt_y, tempt_z)]; den2 = intensity[IndexVect(tempt_x, tempt_y+1, tempt_z)]; ratio = get_intensity_ratio(den1, den2, intensity_isovalue); } else { den1 = dataset[IndexVect(tempt_x, tempt_y, tempt_z)]; den2 = dataset[IndexVect(tempt_x, tempt_y+1, tempt_z)]; if (den1 != den2) ratio = (isovalue-den1)/(den2-den1); else ratio = 0; } vertex[v_num].x = (float)tempt_x; vertex[v_num].y = (float)tempt_y+ratio; vertex[v_num].z = (float)tempt_z; cellVerts[0] = v_num; mc_edge[IndexVect(tempt_x,tempt_y,tempt_z)].b = v_num; v_num++; } else cellVerts[0] = mc_edge[IndexVect(tempt_x, tempt_y, tempt_z)].b; } if (edgeTable[cellIndex] & 2) { if (mc_edge[IndexVect(tempt_x, tempt_y+1, tempt_z)].a == -1) { if(use_intensity) { den1 = intensity[IndexVect(tempt_x, tempt_y+1, tempt_z)]; den2 = intensity[IndexVect(tempt_x+1, tempt_y+1, tempt_z)]; ratio = get_intensity_ratio(den1, den2, intensity_isovalue); } else { den1 = dataset[IndexVect(tempt_x, tempt_y+1, tempt_z)]; den2 = dataset[IndexVect(tempt_x+1, tempt_y+1, tempt_z)]; if (den1 != den2) ratio = (isovalue-den1)/(den2-den1); else ratio = 0; } vertex[v_num].x = (float)tempt_x+ratio; vertex[v_num].y = (float)tempt_y+1; vertex[v_num].z = (float)tempt_z; cellVerts[1] = v_num; mc_edge[IndexVect(tempt_x, tempt_y+1, tempt_z)].a = v_num; v_num++; } else cellVerts[1] = mc_edge[IndexVect(tempt_x, tempt_y+1, tempt_z)].a; } if (edgeTable[cellIndex] & 4) { if (mc_edge[IndexVect(tempt_x+1,tempt_y,tempt_z)].b == -1) { if(use_intensity) { den1 = intensity[IndexVect(tempt_x+1, tempt_y, tempt_z)]; den2 = intensity[IndexVect(tempt_x+1, tempt_y+1, tempt_z)]; ratio = get_intensity_ratio(den1, den2, intensity_isovalue); } else { den1 = dataset[IndexVect(tempt_x+1, tempt_y, tempt_z)]; den2 = dataset[IndexVect(tempt_x+1, tempt_y+1, tempt_z)]; if (den1 != den2) ratio = (isovalue-den1)/(den2-den1); else ratio = 0; } vertex[v_num].x = (float)tempt_x+1; vertex[v_num].y = (float)tempt_y+ratio; vertex[v_num].z = (float)tempt_z; cellVerts[2] = v_num; mc_edge[IndexVect(tempt_x+1, tempt_y, tempt_z)].b = v_num; v_num++; } else cellVerts[2] = mc_edge[IndexVect(tempt_x+1, tempt_y, tempt_z)].b; } if (edgeTable[cellIndex] & 8) { if (mc_edge[IndexVect(tempt_x, tempt_y, tempt_z)].a == -1) { if(use_intensity) { den1 = intensity[IndexVect(tempt_x, tempt_y, tempt_z)]; den2 = intensity[IndexVect(tempt_x+1, tempt_y, tempt_z)]; ratio = get_intensity_ratio(den1, den2, intensity_isovalue); } else { den1 = dataset[IndexVect(tempt_x, tempt_y, tempt_z)]; den2 = dataset[IndexVect(tempt_x+1, tempt_y, tempt_z)]; if (den1 != den2) ratio = (isovalue-den1)/(den2-den1); else ratio = 0; } vertex[v_num].x = (float)tempt_x+ratio; vertex[v_num].y = (float)tempt_y; vertex[v_num].z = (float)tempt_z; cellVerts[3] = v_num; mc_edge[IndexVect(tempt_x, tempt_y, tempt_z)].a = v_num; v_num++; } else cellVerts[3] = mc_edge[IndexVect(tempt_x, tempt_y, tempt_z)].a; } if (edgeTable[cellIndex] & 16) { if (mc_edge[IndexVect(tempt_x,tempt_y,tempt_z+1)].b == -1) { if(use_intensity) { den1 = intensity[IndexVect(tempt_x, tempt_y, tempt_z+1)]; den2 = intensity[IndexVect(tempt_x, tempt_y+1, tempt_z+1)]; ratio = get_intensity_ratio(den1, den2, intensity_isovalue); } else { den1 = dataset[IndexVect(tempt_x, tempt_y, tempt_z+1)]; den2 = dataset[IndexVect(tempt_x, tempt_y+1, tempt_z+1)]; if (den1 != den2) ratio = (isovalue-den1)/(den2-den1); else ratio = 0; } vertex[v_num].x = (float)tempt_x; vertex[v_num].y = (float)tempt_y+ratio; vertex[v_num].z = (float)tempt_z+1; cellVerts[4] = v_num; mc_edge[IndexVect(tempt_x, tempt_y, tempt_z+1)].b = v_num; v_num++; } else cellVerts[4] = mc_edge[IndexVect(tempt_x, tempt_y, tempt_z+1)].b; } if (edgeTable[cellIndex] & 32) { if (mc_edge[IndexVect(tempt_x,tempt_y+1,tempt_z+1)].a == -1) { if(use_intensity) { den1 = intensity[IndexVect(tempt_x, tempt_y+1, tempt_z+1)]; den2 = intensity[IndexVect(tempt_x+1, tempt_y+1, tempt_z+1)]; ratio = get_intensity_ratio(den1, den2, intensity_isovalue); } else { den1 = dataset[IndexVect(tempt_x, tempt_y+1, tempt_z+1)]; den2 = dataset[IndexVect(tempt_x+1, tempt_y+1, tempt_z+1)]; if (den1 != den2) ratio = (isovalue-den1)/(den2-den1); else ratio = 0; } vertex[v_num].x = (float)tempt_x+ratio; vertex[v_num].y = (float)tempt_y+1; vertex[v_num].z = (float)tempt_z+1; cellVerts[5] = v_num; mc_edge[IndexVect(tempt_x, tempt_y+1, tempt_z+1)].a = v_num; v_num++; } else cellVerts[5] = mc_edge[IndexVect(tempt_x, tempt_y+1, tempt_z+1)].a; } if (edgeTable[cellIndex] & 64) { if (mc_edge[IndexVect(tempt_x+1, tempt_y, tempt_z+1)].b == -1) { if(use_intensity) { den1 = intensity[IndexVect(tempt_x+1, tempt_y, tempt_z+1)]; den2 = intensity[IndexVect(tempt_x+1, tempt_y+1, tempt_z+1)]; ratio = get_intensity_ratio(den1, den2, intensity_isovalue); } else { den1 = dataset[IndexVect(tempt_x+1, tempt_y, tempt_z+1)]; den2 = dataset[IndexVect(tempt_x+1, tempt_y+1, tempt_z+1)]; if (den1 != den2) ratio = (isovalue-den1)/(den2-den1); else ratio = 0; } vertex[v_num].x = (float)tempt_x+1; vertex[v_num].y = (float)tempt_y+ratio; vertex[v_num].z = (float)tempt_z+1; cellVerts[6] = v_num; mc_edge[IndexVect(tempt_x+1, tempt_y, tempt_z+1)].b = v_num; v_num++; } else cellVerts[6] = mc_edge[IndexVect(tempt_x+1, tempt_y, tempt_z+1)].b; } if (edgeTable[cellIndex] & 128) { if (mc_edge[IndexVect(tempt_x, tempt_y, tempt_z+1)].a == -1) { if(use_intensity) { den1 = intensity[IndexVect(tempt_x, tempt_y, tempt_z+1)]; den2 = intensity[IndexVect(tempt_x+1, tempt_y, tempt_z+1)]; ratio = get_intensity_ratio(den1, den2, intensity_isovalue); } else { den1 = dataset[IndexVect(tempt_x, tempt_y, tempt_z+1)]; den2 = dataset[IndexVect(tempt_x+1, tempt_y, tempt_z+1)]; if (den1 != den2) ratio = (isovalue-den1)/(den2-den1); else ratio = 0; } vertex[v_num].x = (float)tempt_x+ratio; vertex[v_num].y = (float)tempt_y; vertex[v_num].z = (float)tempt_z+1; cellVerts[7] = v_num; mc_edge[IndexVect(tempt_x, tempt_y, tempt_z+1)].a = v_num; v_num++; } else cellVerts[7] = mc_edge[IndexVect(tempt_x, tempt_y, tempt_z+1)].a; } if (edgeTable[cellIndex] & 256) { if (mc_edge[IndexVect(tempt_x, tempt_y, tempt_z)].c == -1) { if(use_intensity) { den1 = intensity[IndexVect(tempt_x, tempt_y, tempt_z)]; den2 = intensity[IndexVect(tempt_x, tempt_y, tempt_z+1)]; ratio = get_intensity_ratio(den1, den2, intensity_isovalue); } else { den1 = dataset[IndexVect(tempt_x, tempt_y, tempt_z)]; den2 = dataset[IndexVect(tempt_x, tempt_y, tempt_z+1)]; if (den1 != den2) ratio = (isovalue-den1)/(den2-den1); else ratio = 0; } vertex[v_num].x = (float)tempt_x; vertex[v_num].y = (float)tempt_y; vertex[v_num].z = (float)tempt_z+ratio; cellVerts[8] = v_num; mc_edge[IndexVect(tempt_x, tempt_y, tempt_z)].c = v_num; v_num++; } else cellVerts[8] = mc_edge[IndexVect(tempt_x,tempt_y,tempt_z)].c; } if (edgeTable[cellIndex] & 512) { if (mc_edge[IndexVect(tempt_x, tempt_y+1, tempt_z)].c == -1) { if(use_intensity) { den1 = intensity[IndexVect(tempt_x, tempt_y+1, tempt_z)]; den2 = intensity[IndexVect(tempt_x, tempt_y+1, tempt_z+1)]; ratio = get_intensity_ratio(den1, den2, intensity_isovalue); } else { den1 = dataset[IndexVect(tempt_x, tempt_y+1, tempt_z)]; den2 = dataset[IndexVect(tempt_x, tempt_y+1, tempt_z+1)]; if (den1 != den2) ratio = (isovalue-den1)/(den2-den1); else ratio = 0; } vertex[v_num].x = (float)tempt_x; vertex[v_num].y = (float)tempt_y+1; vertex[v_num].z = (float)tempt_z+ratio; cellVerts[9] = v_num; mc_edge[IndexVect(tempt_x, tempt_y+1, tempt_z)].c = v_num; v_num++; } else cellVerts[9] = mc_edge[IndexVect(tempt_x, tempt_y+1, tempt_z)].c; } if (edgeTable[cellIndex] & 1024) { if (mc_edge[IndexVect(tempt_x+1, tempt_y+1, tempt_z)].c == -1) { if(use_intensity) { den1 = intensity[IndexVect(tempt_x+1, tempt_y+1, tempt_z)]; den2 = intensity[IndexVect(tempt_x+1, tempt_y+1, tempt_z+1)]; ratio = get_intensity_ratio(den1, den2, intensity_isovalue); } else { den1 = dataset[IndexVect(tempt_x+1, tempt_y+1, tempt_z)]; den2 = dataset[IndexVect(tempt_x+1, tempt_y+1, tempt_z+1)]; if (den1 != den2) ratio = (isovalue-den1)/(den2-den1); else ratio = 0; } vertex[v_num].x = (float)tempt_x+1; vertex[v_num].y = (float)tempt_y+1; vertex[v_num].z = (float)tempt_z+ratio; cellVerts[10] = v_num; mc_edge[IndexVect(tempt_x+1, tempt_y+1, tempt_z)].c = v_num; v_num++; } else cellVerts[10] = mc_edge[IndexVect(tempt_x+1, tempt_y+1, tempt_z)].c; } if (edgeTable[cellIndex] & 2048) { if (mc_edge[IndexVect(tempt_x+1,tempt_y,tempt_z)].c == -1) { if(use_intensity) { den1 = intensity[IndexVect(tempt_x+1, tempt_y, tempt_z)]; den2 = intensity[IndexVect(tempt_x+1, tempt_y, tempt_z+1)]; ratio = get_intensity_ratio(den1, den2, intensity_isovalue); } else { den1 = dataset[IndexVect(tempt_x+1, tempt_y, tempt_z)]; den2 = dataset[IndexVect(tempt_x+1, tempt_y, tempt_z+1)]; if (den1 != den2) ratio = (isovalue-den1)/(den2-den1); else ratio = 0; } vertex[v_num].x = (float)tempt_x+1; vertex[v_num].y = (float)tempt_y; vertex[v_num].z = (float)tempt_z+ratio; cellVerts[11] = v_num; mc_edge[IndexVect(tempt_x+1, tempt_y, tempt_z)].c = v_num; v_num++; } else cellVerts[11] = mc_edge[IndexVect(tempt_x+1, tempt_y, tempt_z)].c; } ii = 0; while (triTable[cellIndex][ii] != -1) { triangle[t_num].a = cellVerts[triTable[cellIndex][ii++]]; triangle[t_num].b = cellVerts[triTable[cellIndex][ii++]]; triangle[t_num].c = cellVerts[triTable[cellIndex][ii++]]; t_num++; } } // Allocate memory surfmesh = SurfaceMesh_ctor(v_num, t_num); for (n = 0; n < surfmesh->nv; n++) { surfmesh->vertex[n].x = vertex[n].x; surfmesh->vertex[n].y = vertex[n].y; surfmesh->vertex[n].z = vertex[n].z; } for (n = 0; n < surfmesh->nf; n++) { surfmesh->face[n].a = triangle[n].a; surfmesh->face[n].b = triangle[n].b; surfmesh->face[n].c = triangle[n].c; } free(vertex); free(triangle); free(mc_edge); free(mc_sign); // Return created SurfaceMesh return surfmesh; }