Пример #1
0
/* 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;
}
Пример #2
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;
}
Пример #3
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;
    }
}
Пример #4
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;
}
Пример #5
0
/*
 * 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;

}
Пример #6
0
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;
}