/* Main */ int main(int argc, char* argv[]) { int nnF = 200000, nnV = 200000, nnT = 1100000; int nF = 0, nV = 0, nT = 0; int *face = 0, *facematerial = 0, *facedup = 0, *facematdup = 0; int *tetra = 0, *tetramaterial = 0; double *vertex = 0; int i, nFdup, r, j, medge, msurf, m, k, p; int nVVert, nLine, nSurface; int *LineD, *LineP; double *LineT; int *SurfL, *SurfI; double *SurfT; double *VVert; int *expCrv; int nE = 0, nnE = 100000, *edge, *edgematerial; int va, vb, vc, vd, ve, vf, vg, vh; int vc1a, vc1b, vc2a, vc2b, vc3a, vc3b; int arc1a, arc1b, arc2a, arc2b, arc3a, arc3b; int eab, ebc, ecd, eda, eef, efg, egh, ehe, eae, ebf, ecg, edh; int ntfix = 0, nvfix = 0; int izero = 0; // allocate memory for mesh ctructures vertex = (double*)malloc(sizeof(double) * 3 * nnV); face = (int*) malloc(sizeof(int) * 3 * nnF); facedup = (int*) malloc(sizeof(int) * 3 * nnF); facematerial = (int*) malloc(sizeof(int) * nnF); facematdup = (int*) malloc(sizeof(int) * nnF); tetra = (int*) malloc(sizeof(int) * 4 * nnT); tetramaterial = (int*) malloc(sizeof(int) * nnT); edge = (int*) malloc(sizeof(int) * 2 * nnE); edgematerial = (int*) malloc(sizeof(int) * nnE); // allocate memory for boundary representation structure VVert = (double*)malloc(sizeof(double) * 3*100); nVVert = 0; LineD = (int*) malloc(sizeof(int) * 3*100); LineP = (int*) malloc(sizeof(int) * 2*2*100); LineT = (double*)malloc(sizeof(double) * 2*2*100); nLine = 0; SurfL = (int*) malloc(sizeof(int) * 5*100); SurfI = (int*) malloc(sizeof(int) * 2*2*100); SurfT = (double*)malloc(sizeof(double) * 4*100); nSurface = 0; expCrv = (int*) malloc(sizeof(int) * 100); memset(expCrv, 0, sizeof(int) * 100); /***/ #define ADD_VERTEX(X, Y, Z) (VVert[3*nVVert+0] = X, VVert[3*nVVert+1] = Y, VVert[3*nVVert+2] = Z, ++nVVert) #define EDGE(V1, V2, N, ...) add_edge(LineD, LineP, LineT, &nLine, &medge, V1, V2, N, __VA_ARGS__) #define SURF(P, C1, C2, D, U1, U2, V1, V2, N, ...) add_surf(SurfL, SurfT, SurfI, &nSurface, &msurf, P, C1, C2, D, U1, U2, V1, V2, N, __VA_ARGS__) /***/ vc1a = ADD_VERTEX( R1, 0, 0); vc1b = ADD_VERTEX(-R1, 0, 0); vc2a = ADD_VERTEX( R2, 0, 0); vc2b = ADD_VERTEX(-R2, 0, 0); vc3a = ADD_VERTEX( R3, 0, 0); vc3b = ADD_VERTEX(-R3, 0, 0); va = ADD_VERTEX(-Db, -Db, 0); vb = ADD_VERTEX(-Db, Db, 0); vc = ADD_VERTEX( Db, Db, 0); vd = ADD_VERTEX( Db, -Db, 0); ve = ADD_VERTEX(-Db, -Db, -Db); vf = ADD_VERTEX(-Db, Db, -Db); vg = ADD_VERTEX( Db, Db, -Db); vh = ADD_VERTEX( Db, -Db, -Db); medge = 0; /* EDGE(v1, v2, nSurf, [iSurf, iLine, t_0, t1,] ...); */ arc1a = EDGE(vc1a, vc1b, 1, 1, 1, 0.0, M_PI); arc1b = EDGE(vc1b, vc1a, 1, 1, 1, M_PI, 2.0*M_PI); arc2a = EDGE(vc2a, vc2b, 1, 1, 2, M_PI, 0.0); arc2b = EDGE(vc2b, vc2a, 1, 1, 2, 2.0*M_PI, M_PI); arc3a = EDGE(vc3a, vc3b, 1, 1, 3, 0.0, M_PI); arc3b = EDGE(vc3b, vc3a, 1, 1, 3, M_PI, 2.0*M_PI); expCrv[arc1a-1] = 1, expCrv[arc1b-1] = 1; expCrv[arc2a-1] = 1, expCrv[arc2b-1] = 1; expCrv[arc3a-1] = 1, expCrv[arc3b-1] = 1; eab = EDGE(va, vb, 1, 0, 0, 0.0, 0.0); ebc = EDGE(vb, vc, 1, 0, 0, 0.0, 0.0); ecd = EDGE(vc, vd, 1, 0, 0, 0.0, 0.0); eda = EDGE(vd, va, 1, 0, 0, 0.0, 0.0); eef = EDGE(ve, vf, 1, 0, 0, 0.0, 0.0); efg = EDGE(vf, vg, 1, 0, 0, 0.0, 0.0); egh = EDGE(vg, vh, 1, 0, 0, 0.0, 0.0); ehe = EDGE(vh, ve, 1, 0, 0, 0.0, 0.0); eae = EDGE(va, ve, 1, 0, 0, 0.0, 0.0); ebf = EDGE(vb, vf, 1, 0, 0, 0.0, 0.0); ecg = EDGE(vc, vg, 1, 0, 0, 0.0, 0.0); edh = EDGE(vd, vh, 1, 0, 0, 0.0, 0.0); msurf = 0; /* SURF(iSurf, color1, color2, direction, u0, u1, v0, v1, n, [edge, edge_dir,] ...); */ SURF(1, 2, 11, 0, -Db, Db, -Db, Db, 2, arc1a, 0, arc1b, 0); SURF(1, 1, 0, 0, -Db, Db, -Db, Db, 4, arc2a, 1, arc2b, 1, arc1a, 1, arc1b, 1); SURF(1, 2, 12, 0, -Db, Db, -Db, Db, 4, arc3a, 0, arc3b, 0, arc2a, 0, arc2b, 0); SURF(0, 1, 0, 0, 0.0, 0.0, 0.0, 0.0, 6, arc3a, 1, arc3b, 1, eab, 1, ebc, 1, ecd, 1, eda, 1); SURF(0, 1, 0, 0, 0.0, 0.0, 0.0, 0.0, 4, eef, 0, efg, 0, egh, 0, ehe, 0); SURF(0, 1, 0, 0, 0.0, 0.0, 0.0, 0.0, 4, eab, 0, ebf, 0, eef, 1, eae, 1); SURF(0, 1, 0, 0, 0.0, 0.0, 0.0, 0.0, 4, ebc, 0, ecg, 0, efg, 1, ebf, 1); SURF(0, 1, 0, 0, 0.0, 0.0, 0.0, 0.0, 4, ecd, 0, edh, 0, egh, 1, ecg, 1); SURF(0, 1, 0, 0, 0.0, 0.0, 0.0, 0.0, 4, eda, 0, eae, 0, ehe, 1, edh, 1); tria_dump_front = 0; tria_debug_front = 0; region_dump_face = 0; printf("\n * Generating surface mesh\n"); i = ani3d_surface_edges_boundary_(&nVVert, VVert, &nLine, LineD, LineP, LineT, &nSurface, SurfL, SurfI, SurfT, NULL, surface_param, line_param, NULL/*periodic*/, fsize, expCrv, &nV, vertex, &nF, face, facematerial, &nE, edge, edgematerial, &nnV, &nnF, &nnE ); free(VVert), free(LineD), free(LineP), free(LineT), free(SurfL), free(SurfI), free(SurfT); printf("INFO: nV = %d, nE = %d, nF = %d, nT = %d\n", nV, nE, nF, nT); /* Generate skin mesh */ printf("\n * Generating skin mesh\n"); nFdup = 0; addlayer(electrodesize, &nV, vertex-3, nE, edge, edgematerial, &nF, face, facematerial, &nT, tetra, tetramaterial, &nFdup, facedup, facematdup, nnV, nnF, nnT); fix_vertices(&nV, vertex-3, nF, face, nT, tetra, nFdup, facedup, nE, edge); printf("INFO: nV = %d, nF = %d, nT = %d\n", nV, nF, nT); // It could be usefull to dump the triangulation of the surface in case we want to check // that boundary representation is correct and represents the desired region if (0) { write_mesh_gmv("surf.gmv", nV, vertex, nF, face, facematerial, nT, tetra, tetramaterial); // for GMV write_front ("surf.smv", nV, vertex, nF, face, facematerial); // for smv // return 0; // do not mesh the volume, just exit write_mesh_gmv("dups.gmv", nV, vertex, nFdup, facedup, facematdup, nT, tetra, tetramaterial); // for GMV write_front ("dups.smv", nV, vertex, nFdup, facedup, facematdup); // for smv } // We will copy the front, so that it could be used in output in future. ntfix = nT; nvfix = nV; for (i=0; i<nF; i++) { facedup[3*nFdup+0] = face[3*i+0]; facedup[3*nFdup+1] = face[3*i+1]; facedup[3*nFdup+2] = face[3*i+2]; facematdup[nFdup] = facematerial[i]; nFdup++; } // Generate 3D mesh using our own size function fsize() printf("\n * Generating volume mesh\n"); r = mesh_3d_aft_func_(&nV, vertex, &nF, face, facematerial, &nT, tetra, tetramaterial, &nnV, &nnF, &nnT, fsize); printf("\nINFO: nV = %d, nF = %d, nT = %d\n", nV, nF, nT); if (r) { write_mesh_gmv("fail.gmv", nV, vertex, nF, face, facematerial, nT, tetra, tetramaterial); } else { /* Check that 3D mesh corresponds with surface mesh */ /*printf("Checking topology: "), fflush(stdout);*/ if (0 && check_mesh_topology_(&nV, vertex, &nFdup, facedup, &nT, tetra)) printf("FAILED!\n"); else { /*printf("ok.\n");*/ if (0) { write_mesh ("bfix.out", nV, vertex, nFdup, facedup, facematdup, nT, tetra, tetramaterial); write_mesh_gmv_qual("bfix.gmv", nV, vertex, nFdup, facedup, facematdup, nT, tetra, tetramaterial); } for (i=0; i<nT; i++) tetramaterial[i] = (tetramaterial[i]==1) ? 2 : tetramaterial[i]; keepskin(&nFdup, facedup, facematdup); /* Improve mesh quality */ printf("\n * Smoothing volume mesh\n"); fixshape(&nV, vertex, &nT, tetra, tetramaterial, &nFdup, facedup, facematdup, 0, ntfix, nFdup, nnV, nnT, nnF); keepskin(&nFdup, facedup, facematdup); // Write output files write_mesh_gmv_qual("mesh.gmv", nV, vertex, nFdup, facedup, facematdup, nT, tetra, tetramaterial); /*write_mesh ("mesh.out", nV, vertex, nFdup, facedup, facematdup, nT, tetra, tetramaterial);*/ saveMani(&nV, &nFdup, &nT, vertex, facedup, tetra, facematdup, tetramaterial, &izero, &izero, &izero, NULL, NULL, NULL, &izero, NULL, NULL, "mesh.ani"); } } free(vertex); free(face); free(facedup); free(facematerial); free(facematdup); free(tetra); free(tetramaterial); return 0; }
int main(int argc, char* argv[]) { int nnF = 1000000, nnV = 1000000, nnT = 1000000; int nF = 0, nV = 0, nT = 0; int nnS = 1000, nnE = 1000; int *face = 0, *facematerial = 0, *facedup = 0, *facematdup = 0; int *tetra = 0, *tetramaterial = 0; double *vertex = 0; int i, nFdup, r, m; int nVVert, nLine, nSurface; int *LineD, *LineP; double *LineT; int *SurfL, *SurfI; double *SurfT; double *VVert; (void) argc, (void) argv; // allocate memory for mesh ctructures vertex = (double*)malloc(sizeof(double) * 3 * nnV); face = (int*) malloc(sizeof(int) * 3 * nnF); facedup = (int*) malloc(sizeof(int) * 3 * nnF); facematerial = (int*) malloc(sizeof(int) * nnF); facematdup = (int*) malloc(sizeof(int) * nnF); tetra = (int*) malloc(sizeof(int) * 4 * nnT); tetramaterial = (int*) malloc(sizeof(int) * nnT); // allocate memory for boundary representation structure VVert = (double*)malloc(sizeof(double) * 3*nnV); nVVert = 0; LineD = (int*) malloc(sizeof(int) * 3*nnE); LineP = (int*) malloc(sizeof(int) * 2*2*nnE); LineT = (double*)malloc(sizeof(double) * 2*2*nnE); nLine = 0; SurfL = (int*) malloc(sizeof(int) * 5*nnS); SurfI = (int*) malloc(sizeof(int) * 2*2*nnE); SurfT = (double*)malloc(sizeof(double) * 4*nnS); nSurface = 0; // First we will define coords of the main points. // Main points are the end points of each curve. // They are also known as V-points or V-vertices // We will define 8 vertices of the box // and two points on equator of the sphere // Here is an example how we can add point with coords(x,y,z): /* VVert[3*nVVert+0] = x; VVert[3*nVVert+1] = y; VVert[3*nVVert+2] = z; nVVert++; */ // To simplify our program we can use the following macros: #define ADD_VERTEX(X, Y, Z); {\ VVert[3*nVVert+0] = X;\ VVert[3*nVVert+1] = Y;\ VVert[3*nVVert+2] = Z;\ nVVert++;\ } // 8 vertices of the box ADD_VERTEX(CX - L, CY - L, CZ - L); // 1 ADD_VERTEX(CX + L, CY - L, CZ - L); // 2 ADD_VERTEX(CX + L, CY + L, CZ - L); // 3 ADD_VERTEX(CX - L, CY + L, CZ - L); // 4 ADD_VERTEX(CX - L, CY - L, CZ + L); // 5 ADD_VERTEX(CX + L, CY - L, CZ + L); // 6 ADD_VERTEX(CX + L, CY + L, CZ + L); // 7 ADD_VERTEX(CX - L, CY + L, CZ + L); // 8 // If the vertex is the end of parametrized curve it coords will be forcly recalculated // So for such points we can just say nVVert++; // But in this example we will still fill the coords for clarity/ ADD_VERTEX(CX - R, CY, CZ); // 9 | In fact coords of these points will be recalculated ADD_VERTEX(CX + R, CY, CZ); // 10 | using parametrization of the curves m = 0; // Now we will define our curves // For each curve we should define indices of start point and end point // We also should define number of parametrized surfaces this curve belongs to. // For each such surface we define the F_i and V_j, so curve is parametrized as // u -> (u,v) = (u,V_j(u)) -> (x,y,z) = F_i(u,v) // Pairs (i,j) are stored in separate array in successive order // If curve is a segment, it still needs one pair of (i,j)=(0,0) // For each pair (i,j) we also define the value of parameter u for start and end points, // they are stored in third array // Here is an example how we can add curve: /* LineD[3*nLine+0] = v1; LineD[3*nLine+1] = v2; // indices of start and end points LineD[3*nLine+2] = 2; // this curve belongs to two surfaces // first one have parametrization function number 1 (F_1) // and in this surface curve could be parametrized by V_5(u), where u are from -1.0 to 1.0 LineP[2*m+0] = 1; LineP[2*m+1] = 5; LineT[2*m+0] = -1.0; LineT[2*m+1] = 1.0; m++; // first surface have parametrization function number 2 (F_2) // and in this surface curve could be parametrized by V_9(u), where u are from 0.0 to 2.0 LineP[2*m+0] = 2; LineP[2*m+1] = 9; LineT[2*m+0] = 0.0; LineT[2*m+1] = 2.0; m++; nLine++; */ // To simplify our program we can use the following macros for segments: #define ADD_SEGMENT(V1, V2); {\ LineD[3*nLine+0] = V1; LineD[3*nLine+1] = V2;\ LineD[3*nLine+2] = 1;\ LineP[2*m+0] = 0; LineP[2*m+1] = 0; LineT[2*m+0] = 0.0; LineT[2*m+1] = 0.0; m++;\ nLine++;\ } // 12 edges of the box ADD_SEGMENT(1, 2); // 1 ADD_SEGMENT(2, 3); // 2 ADD_SEGMENT(3, 4); // 3 ADD_SEGMENT(4, 1); // 4 ADD_SEGMENT(5, 6); // 5 ADD_SEGMENT(6, 7); // 6 ADD_SEGMENT(7, 8); // 7 ADD_SEGMENT(8, 5); // 8 ADD_SEGMENT(1, 5); // 9 ADD_SEGMENT(2, 6); // 10 ADD_SEGMENT(3, 7); // 11 ADD_SEGMENT(4, 8); // 12 // First arc on equator from point 9 to point 10 LineD[3*nLine+0] = 9; LineD[3*nLine+1] = 10; // This arc belongs to two surfaces (halfs of the sphere) LineD[3*nLine+2] = 2; // On both halfs of the sphere this arc is parametrized by the same (u,v) // We will use V_1 for both surfaces, u in [-1.0, 1.0] LineP[2*m+0] = 1; LineP[2*m+1] = 1; LineT[2*m+0] = -1.0; LineT[2*m+1] = 1.0; m++; LineP[2*m+0] = 2; LineP[2*m+1] = 1; LineT[2*m+0] = -1.0; LineT[2*m+1] = 1.0; m++; nLine++; // 13 // Second arc on equator from point 10 to point 9 LineD[3*nLine+0] = 10; LineD[3*nLine+1] = 9; // This arc also belongs to two surfaces (halfs of the sphere) LineD[3*nLine+2] = 2; // On both halfs of the sphere this arc is parametrized by the same (u,v) // We will use V_2 for both surfaces, u in [1.0, -1.0] LineP[2*m+0] = 1; LineP[2*m+1] = 2; LineT[2*m+0] = 1.0; LineT[2*m+1] = -1.0; m++; LineP[2*m+0] = 2; LineP[2*m+1] = 2; LineT[2*m+0] = 1.0; LineT[2*m+1] = -1.0; m++; nLine++; // 14 m = 0; // Now we will define surfaces // For each surface we define 5 integer numbers (SurfL): // 1st: number of boundary curves // 2nd: number of parametrization function // 3rd: color of the face // 4th: 0 if the face is boundary face, or the second color of the face if it is used to split volume // 5th: 0 if orientation of the face corresponds with parametrization, 1 if it should be inverted, 0 for flat faces // For each surface we alse define minimax values of (u,v) parametrization (SurfT) // u_min, u_max, v_min, v_max // For each boundary curve we define a pair of integers (SurfI): // 1st: index of curve // 2nd: orientation, 0 for normal, 1 for reversed // Here is an example how we can add surface: /* SurfL[5*nSurface+0] = 2; // surface is bounded by two curves SurfL[5*nSurface+1] = 1; // surface is parametrized by F_1 SurfL[5*nSurface+2] = 1; // the color of face is 1 SurfL[5*nSurface+3] = 0; // the face is boundary SurfL[5*nSurface+4] = 0; // orientation of the face corresponds with parametrization // minimax values of parametrs SurfT[4*nSurface+0] = -1.0; SurfT[4*nSurface+1] = -1.0; SurfT[4*nSurface+2] = 1.0; SurfT[4*nSurface+3] = 1.0; // first curve is curve number c1, orientation is normal SurfI[2*m+0] = c1; SurfI[2*m+1] = 0; m++; // second curve is curve number c2, orientation is reversed SurfI[2*m+0] = c2; SurfI[2*m+1] = 1; m++; nSurface++; */ // In common case to invert orientation of the face one should invert the 5th parameter in SurfL // and invert orientation of all boundary curves // To simplify our program we can use the following macros for flat quadrilaterals: // Here for each curve (V,I) is for index of the curve V and orientation I #define ADD_QUADRILATERAL(V1,I1, V2,I2, V3,I3, V4,I4); {\ SurfL[5*nSurface+0] = 4;\ SurfL[5*nSurface+1] = 0;\ SurfL[5*nSurface+2] = 1;\ SurfL[5*nSurface+3] = 0;\ SurfL[5*nSurface+4] = 0;\ SurfT[4*nSurface+0] = 0.0; SurfT[4*nSurface+1] = 0.0; SurfT[4*nSurface+2] = 0.0; SurfT[4*nSurface+3] = 0.0;\ SurfI[2*m+0] = V1; SurfI[2*m+1] = I1; m++;\ SurfI[2*m+0] = V2; SurfI[2*m+1] = I2; m++;\ SurfI[2*m+0] = V3; SurfI[2*m+1] = I3; m++;\ SurfI[2*m+0] = V4; SurfI[2*m+1] = I4; m++;\ nSurface++;\ } // 6 faces of the box ADD_QUADRILATERAL( 4,1, 3,1, 2,1, 1,1); // 1 ADD_QUADRILATERAL( 5,0, 6,0, 7,0, 8,0); // 2 ADD_QUADRILATERAL( 1,0, 10,0, 5,1, 9,1); // 3 ADD_QUADRILATERAL( 2,0, 11,0, 6,1, 10,1); // 4 ADD_QUADRILATERAL( 3,0, 12,0, 7,1, 11,1); // 5 ADD_QUADRILATERAL( 4,0, 9,0, 8,1, 12,1); // 6 // top half of the sphere, parametrized by F_1 SurfL[5*nSurface+0] = 2; SurfL[5*nSurface+1] = 1; SurfL[5*nSurface+2] = 1; SurfL[5*nSurface+3] = 0; SurfL[5*nSurface+4] = 1; SurfT[4*nSurface+0] = -1.0; SurfT[4*nSurface+1] = 1.0; SurfT[4*nSurface+2] = -1.0; SurfT[4*nSurface+3] = 1.0; SurfI[2*m+0] = 13; SurfI[2*m+1] = 0; m++; SurfI[2*m+0] = 14; SurfI[2*m+1] = 0; m++; nSurface++; // 7 // bottom half of the sphere, parametrized by F_2 SurfL[5*nSurface+0] = 2; SurfL[5*nSurface+1] = 2; SurfL[5*nSurface+2] = 1; SurfL[5*nSurface+3] = 0; SurfL[5*nSurface+4] = 0; SurfT[4*nSurface+0] = -1.0; SurfT[4*nSurface+1] = 1.0; SurfT[4*nSurface+2] = -1.0; SurfT[4*nSurface+3] = 1.0; SurfI[2*m+0] = 13; SurfI[2*m+1] = 1; m++; SurfI[2*m+0] = 14; SurfI[2*m+1] = 1; m++; nSurface++; // 8 // Note the difference of orientations of last two surfaces // When creating new boundary representations it could be usefull to check // the boundary of each surface // tria_dump_front = 1; // enable dumping of initial front for each surface // If triangulation of surface fails, it could be usefull to check the process // of the triangulation // tria_debug_front = 1; // enable dumping front on each step. Will generate a lot of files // fronts will be droped in files frt_gmv.{num} for gmv // and frt_smv.{num} for smv or manual reference // {num} is 000, 001, 002, ... // region_dump_face = 1; // Setting up our boundary parametrization functions // First one is for (x,y,z)=F_i(u,v) and second one is for v=V_j(u) set_param_functions(surface_param, v_u_param); // Now we are ready to create the surface mesh // Setting up our own size function. set_surface_size_function(fsize); // Making surface mesh i = surface_boundary_(&nVVert, VVert, &nLine, LineD, LineP, LineT, &nSurface, SurfL, SurfI, SurfT, &nV, vertex, &nF, face, facematerial, &nnV, &nnF); free(VVert), free(LineD), free(LineP), free(LineT), free(SurfL), free(SurfI), free(SurfT); printf("\nINFO: nV = %d, nF = %d, nT = %d\n", nV, nF, nT); // It could be usefull to dump the triangulation of the surface in case we want to check // that boundary representation is correct and represents the desired region if (0) { write_mesh_gmv("surf.gmv", nV, vertex, nF, face, facematerial, 0, 0, 0); // for GMV write_front ("surf.smv", nV, vertex, nF, face, facematerial); // for smv // return 0; // do not mesh the volume, just exit } // We will copy the front, so that it could be used in output in future. nFdup = nF; memcpy(facedup, face, sizeof(int)*3*nF); memcpy(facematdup, facematerial, sizeof(int)*nF); // Generate 3D mesh using our own size function fsize() r = mesh_3d_aft_func_(&nV, vertex, &nF, face, facematerial, &nT, tetra, tetramaterial, &nnV, &nnF, &nnT, fsize); printf("\nINFO: nV = %d, nF = %d, nT = %d\n", nV, nF, nT); if (r) { write_mesh_gmv("fail.gmv", nV, vertex, nF, face, facematerial, nT, tetra, tetramaterial); } else { // Checking that 3D mesh corresponds with surface mesh printf("Cheking topology: "); fflush(stdout); if (check_mesh_topology_(&nV, vertex, &nFdup, facedup, &nT, tetra)) printf("FAILED!\n"); else printf("ok.\n"); // Write output files write_mesh_gmv("mesh.gmv", nV, vertex, nFdup, facedup, facematdup, nT, tetra, tetramaterial); write_mesh ("mesh.out", nV, vertex, nFdup, facedup, facematdup, nT, tetra, tetramaterial); } return 0; }
/* * Compute vertices for the 3-D box. * This function must be called AFTER the dtx->Nr,dtx->Nc,Nl variables have * been initialized. * Input: prop - code for box proportions: * 1 = scale box according to lat, lons. * 2 = scale according to ax, ay, az. * ax, ay, az - aspect ratio numbers used if prop==3. */ static void make_square_box( Display_Context dtx ) { dtx->NumBoxVerts = 0; dtx->TickMarks = 0; /* bottom rectangle */ ADD_VERTEX( dtx->Xmin, dtx->Ymax, dtx->Zmin ); ADD_VERTEX( dtx->Xmax, dtx->Ymax, dtx->Zmin ); ADD_VERTEX( dtx->Xmax, dtx->Ymin, dtx->Zmin ); ADD_VERTEX( dtx->Xmin, dtx->Ymin, dtx->Zmin ); ADD_VERTEX( dtx->Xmin, dtx->Ymax, dtx->Zmin ); END_OF_LINE; /* top rectangle */ ADD_VERTEX( dtx->Xmin, dtx->Ymax, dtx->Zmax ); ADD_VERTEX( dtx->Xmax, dtx->Ymax, dtx->Zmax ); ADD_VERTEX( dtx->Xmax, dtx->Ymin, dtx->Zmax ); ADD_VERTEX( dtx->Xmin, dtx->Ymin, dtx->Zmax ); ADD_VERTEX( dtx->Xmin, dtx->Ymax, dtx->Zmax ); END_OF_LINE; /* top-to-bottom lines */ ADD_VERTEX( dtx->Xmax, dtx->Ymax, dtx->Zmax ); ADD_VERTEX( dtx->Xmax, dtx->Ymax, dtx->Zmin ); END_OF_LINE; ADD_VERTEX( dtx->Xmax, dtx->Ymin, dtx->Zmax ); ADD_VERTEX( dtx->Xmax, dtx->Ymin, dtx->Zmin ); END_OF_LINE; ADD_VERTEX( dtx->Xmin, dtx->Ymin, dtx->Zmax ); ADD_VERTEX( dtx->Xmin, dtx->Ymin, dtx->Zmin ); END_OF_LINE; ADD_VERTEX( dtx->Xmin, dtx->Ymax, dtx->Zmax ); ADD_VERTEX( dtx->Xmin, dtx->Ymax, dtx->Zmin ); END_OF_LINE; /* arrow */ ADD_VERTEX( 0.025, dtx->Ymax+0.05, dtx->Zmin ); ADD_VERTEX( 0.0, dtx->Ymax+0.1, dtx->Zmin ); ADD_VERTEX( -0.025, dtx->Ymax+0.05, dtx->Zmin ); END_OF_LINE; ADD_VERTEX( 0.0, dtx->Ymax, dtx->Zmin ); ADD_VERTEX( 0.0, dtx->Ymax+0.1, dtx->Zmin ); END_OF_LINE; /* N */ ADD_VERTEX( -0.025, dtx->Ymax+0.15, dtx->Zmin ); ADD_VERTEX( -0.025, dtx->Ymax+0.25, dtx->Zmin ); ADD_VERTEX( 0.025, dtx->Ymax+0.15, dtx->Zmin ); ADD_VERTEX( 0.025, dtx->Ymax+0.25, dtx->Zmin ); END_OF_LINE; if (dtx->Projection==PROJ_GENERIC || dtx->Projection==PROJ_LINEAR /* ZLB */ || dtx->Projection==PROJ_GENERIC_NONEQUAL) { /* East tick mark */ ADD_VERTEX( dtx->Xmax, dtx->Ymin, dtx->Zmin ); ADD_VERTEX( dtx->Xmax, dtx->Ymin-0.05, dtx->Zmin-0.05); END_OF_LINE; /* West */ ADD_VERTEX( dtx->Xmin, dtx->Ymin, dtx->Zmin ); ADD_VERTEX( dtx->Xmin, dtx->Ymin-0.05, dtx->Zmin-0.05 ); END_OF_LINE; /* North */ ADD_VERTEX( dtx->Xmin, dtx->Ymax, dtx->Zmin ); ADD_VERTEX( dtx->Xmin-0.05, dtx->Ymax, dtx->Zmin-0.05 ); END_OF_LINE; /* South */ ADD_VERTEX( dtx->Xmin, dtx->Ymin, dtx->Zmin ); ADD_VERTEX( dtx->Xmin-0.05, dtx->Ymin, dtx->Zmin-0.05 ); END_OF_LINE; /* Top */ ADD_VERTEX( dtx->Xmin, dtx->Ymin, dtx->Zmax ); ADD_VERTEX( dtx->Xmin-0.05, dtx->Ymin-0.05, dtx->Zmax ); END_OF_LINE; /* Bottom */ ADD_VERTEX( dtx->Xmin, dtx->Ymin, dtx->Zmin ); ADD_VERTEX( dtx->Xmin-0.05, dtx->Ymin-0.05, dtx->Zmin ); END_OF_LINE; dtx->TickMarks = 1; } else { dtx->TickMarks = 0; } }
static void make_sphere_box( Display_Context dtx ) { int i; float lat, lon, hgt; float x, y, z; float row, col, lev; int r, c, l; dtx->NumBoxVerts = 0; dtx->TickMarks = 0; /* Axis */ lat = 90.0; lon = 0.0; hgt = 0.0; geo_to_xyzPRIME( dtx, 0, 0, 1, &lat, &lon, &hgt, &x, &y, &z ); ADD_VERTEX( x, y, z ); lat = -90.0; geo_to_xyzPRIME( dtx, 0, 0, 1, &lat, &lon, &hgt, &x, &y, &z ); ADD_VERTEX( x, y, z ); END_OF_LINE; /* Equator */ lat = 0.0; hgt = 0.0; for (i=0; i<=360; i+=10) { lon = (float) i; geo_to_xyzPRIME( dtx, 0, 0, 1, &lat, &lon, &hgt, &x, &y, &z ); ADD_VERTEX( x, y, z ); } END_OF_LINE; /* curved edges */ for (i=0; i<4; i++) { switch (i) { case 0: /* bottom south edge */ r = dtx->Nr-1; l = 0; break; case 1: /* top south edge */ r = dtx->Nr-1; l = dtx->MaxNl-1; break; case 2: /* top north edge */ r = 0; l = dtx->MaxNl-1; break; case 3: /* bottom north edge */ r = 0; l = 0; break; } for (c=0; c<dtx->Nc; c++) { row = (float) r; col = (float) c; lev = (float) l; gridPRIME_to_xyzPRIME( dtx, 0, 0, 1, &row, &col, &lev, &x, &y, &z ); ADD_VERTEX( x, y, z ); } END_OF_LINE; } for (i=0; i<4; i++) { switch (i) { case 0: /* bottom west edge */ c = 0; l = 0; break; case 1: /* top west edge */ c = 0; l = dtx->MaxNl-1; break; case 2: /* top east edge */ c = dtx->Nc-1; l = dtx->MaxNl-1; break; case 3: /* bottom east edge */ c = dtx->Nc-1; l = 0; break; } for (r=0; r<dtx->Nr; r++) { row = (float) r; col = (float) c; lev = (float) l; gridPRIME_to_xyzPRIME( dtx, 0, 0, 1, &row, &col, &lev, &x, &y, &z ); ADD_VERTEX( x, y, z ); } END_OF_LINE; } /* south-west vertical edge */ row = dtx->Nr-1; col = 0; lev = 0; gridPRIME_to_xyzPRIME( dtx, 0, 0, 1, &row, &col, &lev, &x, &y, &z ); ADD_VERTEX( x, y, z ); lev = dtx->MaxNl-1; gridPRIME_to_xyzPRIME( dtx, 0, 0, 1, &row, &col, &lev, &x, &y, &z ); ADD_VERTEX( x, y, z ); END_OF_LINE; /* north-west vertical edge */ row = 0; col = 0; lev = 0; gridPRIME_to_xyzPRIME( dtx, 0, 0, 1, &row, &col, &lev, &x, &y, &z ); ADD_VERTEX( x, y, z ); lev = dtx->MaxNl-1; gridPRIME_to_xyzPRIME( dtx, 0, 0, 1, &row, &col, &lev, &x, &y, &z ); ADD_VERTEX( x, y, z ); END_OF_LINE; /* north-east vertical edge */ row = 0; col = dtx->Nc-1; lev = 0; gridPRIME_to_xyzPRIME( dtx, 0, 0, 1, &row, &col, &lev, &x, &y, &z ); ADD_VERTEX( x, y, z ); lev = dtx->MaxNl-1; gridPRIME_to_xyzPRIME( dtx, 0, 0, 1, &row, &col, &lev, &x, &y, &z ); ADD_VERTEX( x, y, z ); END_OF_LINE; /* south-east vertical edge */ row = dtx->Nr-1; col = dtx->Nc-1; lev = 0; gridPRIME_to_xyzPRIME( dtx, 0, 0, 1, &row, &col, &lev, &x, &y, &z ); ADD_VERTEX( x, y, z ); lev = dtx->MaxNl-1; gridPRIME_to_xyzPRIME( dtx, 0, 0, 1, &row, &col, &lev, &x, &y, &z ); ADD_VERTEX( x, y, z ); END_OF_LINE; }
/* * Make the box used to bound a cylindrical projection. */ static void make_cylinder_box( Display_Context dtx ) { float row, col, lev; int r, c, l; float x, y, z; int i; dtx->NumBoxVerts = 0; dtx->TickMarks = 0; /* curved edges */ for (i=0; i<4; i++) { switch (i) { case 0: /* bottom south edge */ r = dtx->Nr-1; l = 0; break; case 1: /* top south edge */ r = dtx->Nr-1; l = dtx->MaxNl-1; break; case 2: /* top north edge */ r = 0; l = dtx->MaxNl-1; break; case 3: /* bottom north edge */ r = 0; l = 0; break; } for (c=0; c<dtx->Nc; c++) { row = (float) r; col = (float) c; lev = (float) l; gridPRIME_to_xyzPRIME( dtx, 0, 0, 1, &row, &col, &lev, &x, &y, &z ); /*grid_to_xyz( dtx, 0, dtx->MaxNlVar, 1, &row, &col, &lev, &x, &y, &z ); */ ADD_VERTEX( x, y, z ); } END_OF_LINE; } /* top east edge */ row = 0; col = dtx->Nc-1; lev = dtx->MaxNl-1; gridPRIME_to_xyzPRIME( dtx, 0, 0, 1, &row, &col, &lev, &x, &y, &z ); /*grid_to_xyz( dtx, 0, dtx->MaxNlVar, 1, &row, &col, &lev, &x, &y, &z ); */ ADD_VERTEX( x, y, z ); row = dtx->Nr-1; gridPRIME_to_xyzPRIME( dtx, 0, 0, 1, &row, &col, &lev, &x, &y, &z ); /*grid_to_xyz( dtx, 0, dtx->MaxNlVar, 1, &row, &col, &lev, &x, &y, &z ); */ ADD_VERTEX( x, y, z ); END_OF_LINE; /* bottom east edge */ row = 0; col = dtx->Nc-1; lev = 0; gridPRIME_to_xyzPRIME( dtx, 0, 0, 1, &row, &col, &lev, &x, &y, &z ); ADD_VERTEX( x, y, z ); row = dtx->Nr-1; gridPRIME_to_xyzPRIME( dtx, 0, 0, 1, &row, &col, &lev, &x, &y, &z ); ADD_VERTEX( x, y, z ); END_OF_LINE; /* top west edge */ row = 0; col = 0; lev = dtx->MaxNl-1; gridPRIME_to_xyzPRIME( dtx, 0, 0, 1, &row, &col, &lev, &x, &y, &z ); ADD_VERTEX( x, y, z ); row = dtx->Nr-1; gridPRIME_to_xyzPRIME( dtx, 0, 0, 1, &row, &col, &lev, &x, &y, &z ); ADD_VERTEX( x, y, z ); END_OF_LINE; /* bottom west edge */ row = 0; col = 0; lev = 0; gridPRIME_to_xyzPRIME( dtx, 0, 0, 1, &row, &col, &lev, &x, &y, &z ); ADD_VERTEX( x, y, z ); row = dtx->Nr-1; gridPRIME_to_xyzPRIME( dtx, 0, 0, 1, &row, &col, &lev, &x, &y, &z ); ADD_VERTEX( x, y, z ); END_OF_LINE; /* south-west vertical edge */ row = dtx->Nr-1; col = 0; lev = 0; gridPRIME_to_xyzPRIME( dtx, 0, 0, 1, &row, &col, &lev, &x, &y, &z ); ADD_VERTEX( x, y, z ); lev = dtx->MaxNl-1; gridPRIME_to_xyzPRIME( dtx, 0, 0, 1, &row, &col, &lev, &x, &y, &z ); ADD_VERTEX( x, y, z ); END_OF_LINE; /* north-west vertical edge */ row = 0; col = 0; lev = 0; gridPRIME_to_xyzPRIME( dtx, 0, 0, 1, &row, &col, &lev, &x, &y, &z ); ADD_VERTEX( x, y, z ); lev = dtx->MaxNl-1; gridPRIME_to_xyzPRIME( dtx, 0, 0, 1, &row, &col, &lev, &x, &y, &z ); ADD_VERTEX( x, y, z ); END_OF_LINE; /* north-east vertical edge */ row = 0; col = dtx->Nc-1; lev = 0; gridPRIME_to_xyzPRIME( dtx, 0, 0, 1, &row, &col, &lev, &x, &y, &z ); ADD_VERTEX( x, y, z ); lev = dtx->MaxNl-1; gridPRIME_to_xyzPRIME( dtx, 0, 0, 1, &row, &col, &lev, &x, &y, &z ); ADD_VERTEX( x, y, z ); END_OF_LINE; /* south-east vertical edge */ row = dtx->Nr-1; col = dtx->Nc-1; lev = 0; gridPRIME_to_xyzPRIME( dtx, 0, 0, 1, &row, &col, &lev, &x, &y, &z ); ADD_VERTEX( x, y, z ); lev = dtx->MaxNl-1; gridPRIME_to_xyzPRIME( dtx, 0, 0, 1, &row, &col, &lev, &x, &y, &z ); ADD_VERTEX( x, y, z ); END_OF_LINE; }
fz_error * pdf_loadtype5shade(fz_shade *shade, pdf_xref *xref, fz_obj *shading, fz_obj *ref) { fz_error *error; fz_stream *stream; fz_obj *obj; int bpcoord; int bpcomp; int vpr, vpc; int ncomp; float x0, x1, y0, y1; float c0[FZ_MAXCOLORS]; float c1[FZ_MAXCOLORS]; int i, n, j; int p, q; unsigned int t; float *x, *y, *c[FZ_MAXCOLORS]; error = nil; ncomp = shade->cs->n; bpcoord = fz_toint(fz_dictgets(shading, "BitsPerCoordinate")); bpcomp = fz_toint(fz_dictgets(shading, "BitsPerComponent")); vpr = fz_toint(fz_dictgets(shading, "VerticesPerRow")); if (vpr < 2) { error = fz_throw("VerticesPerRow must be greater than or equal to 2"); goto cleanup; } obj = fz_dictgets(shading, "Decode"); if (fz_isarray(obj)) { pdf_logshade("decode array\n"); x0 = fz_toreal(fz_arrayget(obj, 0)); x1 = fz_toreal(fz_arrayget(obj, 1)); y0 = fz_toreal(fz_arrayget(obj, 2)); y1 = fz_toreal(fz_arrayget(obj, 3)); for (i=0; i < fz_arraylen(obj) / 2; ++i) { c0[i] = fz_toreal(fz_arrayget(obj, i*2+4)); c1[i] = fz_toreal(fz_arrayget(obj, i*2+5)); } } else { error = fz_throw("syntaxerror: No Decode key in Type 4 Shade"); goto cleanup; } obj = fz_dictgets(shading, "Function"); if (obj) { ncomp = 1; pdf_loadshadefunction(shade, xref, shading, c0[0], c1[0]); shade->usefunction = 1; } else shade->usefunction = 0; n = 2 + shade->cs->n; j = 0; #define BIGNUM 1024 x = fz_malloc(sizeof(float) * vpr * BIGNUM); y = fz_malloc(sizeof(float) * vpr * BIGNUM); for (i = 0; i < ncomp; ++i) { c[i] = fz_malloc(sizeof(float) * vpr * BIGNUM); } q = 0; error = pdf_openstream(&stream, xref, fz_tonum(ref), fz_togen(ref)); if (error) goto cleanup; while (fz_peekbyte(stream) != EOF) { for (p = 0; p < vpr; ++p) { int idx; idx = q * vpr + p; t = getdata(stream, bpcoord); x[idx] = x0 + (t * (x1 - x0) / ((float)pow(2, bpcoord) - 1)); t = getdata(stream, bpcoord); y[idx] = y0 + (t * (y1 - y0) / ((float)pow(2, bpcoord) - 1)); for (i=0; i < ncomp; ++i) { t = getdata(stream, bpcomp); c[i][idx] = c0[i] + (t * (c1[i] - c0[i]) / (float)(pow(2, bpcomp) - 1)); } } q++; } fz_dropstream(stream); #define ADD_VERTEX(idx) \ {\ int z;\ shade->mesh[j++] = x[idx];\ shade->mesh[j++] = y[idx];\ for (z = 0; z < shade->cs->n; ++z) {\ shade->mesh[j++] = c[z][idx];\ }\ }\ vpc = q; shade->meshcap = 0; shade->mesh = fz_malloc(sizeof(float) * 1024); if (!shade) { error = fz_outofmem; goto cleanup; } j = 0; for (p = 0; p < vpr-1; ++p) { for (q = 0; q < vpc-1; ++q) { ADD_VERTEX(q * vpr + p); ADD_VERTEX(q * vpr + p + 1); ADD_VERTEX((q + 1) * vpr + p + 1); ADD_VERTEX(q * vpr + p); ADD_VERTEX((q + 1) * vpr + p + 1); ADD_VERTEX((q + 1) * vpr + p); } } shade->meshlen = j / n / 3; fz_free(x); fz_free(y); for (i = 0; i < ncomp; ++i) { fz_free(c[i]); } cleanup: return nil; }