/* // p2vrml.c // created by F.Mizutani 960409 // // pgv001 separate from original 960313 // pgv002 fast (using list) 960314 // pgv003 add axis, untialiasing 960314 // pgv004 change data format 960315 // pgv005 key support 960315 // pgv006 move eye 960318 // pgv007 frame auto fix 960322 // pgv008 double polygon 960322 // pgv009 mesh box 960326 // pgv010 move rate change 960326 // pgv011 polygon select 960327 // pgv012 wire and solid 960327 // pgv013 moleculer data support 960327 // pgv014 write image 960328 // pgv015 texture mapping 960328 give up // pgv016 wire color 960328 // pgv017 glass mode 960401 // pgv018 atomic wire 960401 // pgv019 glass, atomic model 960402 // pgv020 SGI modify 960403 // pgv021 atomic wire another 960403 // pgv022 back write 960404 // pgv023 cut plane, glass 960408 // pgv024 metaric wire 960408 // p2vrml vrml creator 960409 */ /* unix header file */ #include #include #include #include #include #include #include #define PCODE 10004 /* program code */ #define PMAX 32 /* parameters */ #define PGMAX 12 /* polygon count */ #define DLMAX 30 /* display list */ #define ATOMMAX 100 /* atomic number */ #define RATOM 0.4 /* Atom radius */ #define HATOM 0.6 /* H radius RATOM * HATOM */ #define WATOM 0.25 /* Atomic wire RATOM * WATOM */ #define ADIS 3.0 /* Atomic distance */ #define ADISH 2.9 /* Atomic distance */ /* 961018 H2O modify 3.0 -> 2.9 */ #define LATOM 0.5 #define MESHWIDTH 0.05 #define AXISWIDTH 0.01 #define AXISLENGTH 1.05 #define ARROWWIDTH 0.03 #define ARROWLENGTH 0.08 #define DIS 5.0 #define DIVM 0.1 #define DIVR 1.0 #define INIX -2.0 #define INIY 5.0 #define INIZ 1.2 #define EYEX 0.0 #define EYEY 0.0 #define EYEZ DIS #define PI 3.14159 #define PI2 1.57089 #define FALSE 0 #define TRUE !FALSE /* added by F.Mizutani */ int Drag = 0; int Scale = 0; int xpos = 0; int ypos = 0; int xsize = 500; int ysize = 500; float spin_x = 0.0; float spin_y = 0.0; float scalev = 0.5; double eyex = EYEX; double eyey = EYEY; double eyez = EYEZ; double cenx = 0.0; double ceny = 0.0; double cenz = 0.0; double dist = DIS; double divm = DIVM; int SOLID[PGMAX]; int WIRE = 0; int COLORID = 1; /* 0:RED 1:GREEN 2:BLUE 3:YELLOW */ int SHADE = 1; int AXIS = 1; int ALIAS = 1; int FOG = 1; int MESH = 0; int LMODE = 0; int BOND = 1; int GLASS = 0; int BACK = 0; int ROTATE = 0; int CLIP = 0; float xmax, ymax, zmax, datamax; float xmin, ymin, zmin, datamin; float wkx, wky, wkz, wkmax; typedef struct { float x[3]; float y[3]; float z[3]; float vx[3]; float vy[3]; float vz[3]; float vnx, vny, vnz; } PGD; typedef struct { long mn; float mw; float x; float y; float z; } MOL; PGD *pgd, *pgd2; int pgdct, pgdct2; int pgs; int molct; MOL *mol; int idsz, /* Mesh data size. */ idmx, /* Mesh size for x direction. */ idmy, /* Mesh size for y direction. */ idmz; /* Mesh size for z direction. */ long pl[PMAX]; float pf[PMAX]; int xbig, ybig, zbig; float mbgx, mbgy, mbgz; float mstx, msty, mstz; int pgv[PGMAX]; FILE *out; #ifdef DOS int sfg = FALSE; #else int sfg = TRUE; #endif void swapper(p, n) char *p; int n; { char d[4]; int i, j; for (j = 0; j < n; j++){ for (i = 0; i < 4; i++) d[3 -i] = p[i + 4 * j]; for (i = 0; i < 4; i++) p[i + 4 * j] = d[i]; } } void alloc() { if ((mol = (MOL *)malloc(molct * sizeof(MOL))) == NULL){ printf("ALLOC(): mol"); exit(1); } if ((pgd = (PGD *)malloc(pgdct * sizeof(PGD))) == NULL){ printf("ALLOC(): pgd"); exit(1); } if (pgs > 1){ if ((pgd2 = (PGD *)malloc(pgdct2 * sizeof(PGD))) == NULL){ printf("ALLOC(): pgd"); exit(1); } } } void MakeObject(sw) int sw; { int i, j, ct; PGD *p; if (sw == 0){ p = pgd; ct = pgdct; } if (sw == 1){ p = pgd2; ct = pgdct2; } fprintf(out, "DEF Polygon_%d Separator {\n", sw + 1); fprintf(out, " Material {\n"); if (sw == 0) fprintf(out, " diffuseColor 1.0 0.3 0.3\n"); else fprintf(out, " diffuseColor 0.3 1.0 0.3\n"); fprintf(out, " specularColor 0.2 0.2 0.2\n"); fprintf(out, " shininess 0.2\n"); fprintf(out, " transparency 0.5\n"); fprintf(out, " }\n"); fprintf(out, " Coordinate3 {\n"); fprintf(out, " point [\n"); printf("Output VRML polygon "); for (i = 0; i < ct; i++){ if (i % 100 == 0){ printf("[%d]", i); fflush(stdout); } for (j = 0; j < 3; j++){ fprintf(out, " %+5.3f %+5.3f %+5.3f",p[i].x[j],p[i].y[j],p[i].z[j]); if (i == ct - 1 && j == 2) fprintf(out, "\n"); else fprintf(out, ",\n"); } } fprintf(out, " ]\n"); fprintf(out, " }\n"); printf("\n"); fprintf(out, " IndexedFaceSet {\n"); fprintf(out, " coordIndex [\n"); for (i = 0; i < ct; i++){ fprintf(out, " %d, %d, %d, -1", i*3, i*3+1, i*3+2); if (i == ct - 1) fprintf(out, "\n"); else fprintf(out, ",\n"); } fprintf(out, " ]\n"); fprintf(out, " }\n"); fprintf(out, "}\n"); } void MolColor(sw) int sw; { fprintf(out, " Material {\n"); if (0); else if (sw == 1) fprintf(out, " diffuseColor 1.0 1.0 1.0\n"); else if (sw == 6) fprintf(out, " diffuseColor 0.2 0.2 1.0\n"); else if (sw == 7) fprintf(out, " diffuseColor 1.0 1.0 0.2\n"); else if (sw == 8) fprintf(out, " diffuseColor 1.0 0.2 0.2\n"); else fprintf(out, " diffuseColor 0.5 0.5 0.5\n"); fprintf(out, " }\n"); } void MakeBond() { int i, j, err; float d, d2, d2h, rw, rd, r; float xd, yd, zd, dd, lg, lg2; float xa, ya, za; int x, y, c, fg; unsigned long f; char buf[256]; d = ADIS; d2 = d * d; d2h = ADISH * ADISH; rd = 180.0 / PI; rw = RATOM * WATOM; lg2 = LATOM; fprintf(out, "DEF ATOM Separator {\n"); for (i = 0; i < molct; i++){ fprintf(out, " DEF ATOM_No%d_Mol%d Separator {\n", i+1, mol[i].mn); fprintf(out, " Translation { translation %+5.3f %+5.3f %+5.3f }\n", mol[i].x, mol[i].y, mol[i].z); MolColor(mol[i].mn); if (mol[i].mn == 1) r = RATOM * HATOM; else r = RATOM; fprintf(out, " Sphere { radius %+5.3f }\n", r); fprintf(out, " }\n"); } for (i = 0; i < molct; i++){ fprintf(out, " DEF ATOM_LINE_No%d Separator {\n", i+1); MolColor(1); for (j = i + 1; j < molct; j++){ xd = mol[j].x - mol[i].x; if (fabs(xd) > d) continue; yd = mol[j].y - mol[i].y; if (fabs(yd) > d) continue; zd = mol[j].z - mol[i].z; if (fabs(zd) > d) continue; dd = xd * xd + yd * yd + zd * zd; if (dd > d2) continue; if (mol[i].mn == 1 && mol[j].mn == 1 && dd > d2) continue; lg = sqrt(dd); printf("Line %d-%d Length=%+f\n", i, j, lg); xa = 0.0; ya = 0.0; za = 0.0; if (xd == 0.0){ if (yd == 0.0){ if (zd > 0.0) xa = PI2; else xa = -PI2; } else if (zd == 0.0){ if (yd > 0.0) ; else xa = PI; } else xa = (float)atan2((double)zd, (double)yd); } else if (yd == 0.0){ if (zd == 0.0){ if (xd > 0.0) za = -PI2; else za = PI2; } else { xa = PI2; za = (float)atan2((double)zd, (double)xd) - PI2; } } else if (zd == 0.0){ za = (float)atan2((double)yd, (double)xd) - PI2; } else { xa = (float)atan2((double)zd, (double)yd); za = (float)acos((double)(xd / lg)) - PI2; } fprintf(out, " DEF ATOM_LINE_No%d_No%d Separator {\n", i+1, j+1); fprintf(out, " Translation { translation %+5.3f %+5.3f %+5.3f }\n",mol[i].x,mol[i].y,mol[i].z); if (xa != 0.0) fprintf(out, " Rotation { rotation 1 0 0 %+5.3f }\n", xa); if (za != 0.0) fprintf(out, " Rotation { rotation 0 0 1 %+5.3f }\n", za); fprintf(out, " Translation { translation 0 %+5.3f 0 }\n", lg / 2.0); fprintf(out, " Cylinder {\n"); fprintf(out, " parts ALL\n"); fprintf(out, " radius %+5.3f\n", rw); fprintf(out, " height %+5.3f\n", lg); fprintf(out, " }\n"); fprintf(out, " }\n"); } fprintf(out, " }\n"); } fprintf(out, "}\n"); } void MakePolygon() { if (pgv[0] == 1) MakeObject(0); if (pgs > 1 && pgv[1] == 1) MakeObject(1); } void MakeParts() { /* MakeAxis();*/ MakeBond(); MakePolygon(); } Usage() { printf("USAGE: p2vrml filename\n"); /* fprintf(lg, " OPTIONS: -W Wireframe model\n"); fprintf(lg, " -S Flat shading\n"); fprintf(lg, " -A Not display axis\n"); fprintf(lg, " -U UntiAliasing\n"); fprintf(lg, " -F Fog off for wireframe\n"); fprintf(lg, " -Cx Color 0:RED 1:GREEN 2:BLUE 3:YELLOW\n"); fclose(lg);*/ exit(1); } /* // input argument // *argv[0] : program name // *argv[1] : input file name // *argv[2] : switches */ void main(argc, argv) int argc; char **argv; { int winx=800, winy=800; int i, j, k; long bg, ed; char filename[256]; char buf[256]; FILE *fp; printf("\n"); printf("P2VRML Copyright(C) 1996 CCIMS\n\n"); strcpy(filename, ""); for (i = 0; i < PGMAX; i++){ pgv[i] = 1; SOLID[i] = 1; } if (argc < 2) Usage(); for (i = 1; i < argc; i++){ if (argv[i][0] == '-' || argv[i][0] == '/'){ switch(toupper(argv[i][1])){ case 'W': for (i = 0; i < PGMAX; i++) SOLID[i] = 0; break; case 'S': SHADE = 0; break; case 'F': FOG = 0; break; case 'A': AXIS = 0; break; case 'U': ALIAS = 0; break; case 'C': if ('0' <= argv[i][2] && argv[i][2] <= '9') COLORID = argv[i][2] - '0'; break; case 'Q': if ('0' <= argv[i][2] && argv[i][2] <= '9') pgv[argv[i][2] - '1'] = 0; break; } } else if (strlen(filename) == 0) strcpy(filename, argv[i]); else Usage(); } if (strlen(filename) == 0) Usage(); if((fp = fopen(filename, "rb")) == NULL){ printf("MAIN(): fopen %s", filename); exit(1); } fread(pl, sizeof(long), PMAX, fp); if (sfg) swapper(pl, PMAX); if (pl[0] != PCODE){ printf("MAIN(): pcode %d", pl[0]); exit(1); } fread(pf, sizeof(float), PMAX, fp); if (sfg) swapper(pf, PMAX); pgs = pl[5]; molct = pl[7]; pgdct = pl[20]; if (pgs > 1) pgdct2 = pl[21]; if (pgdct == 0){ printf("MAIN(): No polygon"); exit(1); } alloc(); fread(mol, sizeof(MOL), molct, fp); if (sfg) swapper(mol, sizeof(MOL) / sizeof(long) * molct); printf("Moleculer count = %d\n", molct); for (i = 0; i < molct; i++) printf("%d: %d X=%+e Y=%+e Z=%+e\n",i+1,mol[i].mn,mol[i].x,mol[i].y,mol[i].z); fread(pgd, sizeof(PGD), pgdct, fp); if (sfg) swapper(pgd, sizeof(PGD) / 4 * pgdct); if (pgs > 1){ fread(pgd2, sizeof(PGD), pgdct2, fp); if (sfg) swapper(pgd2, sizeof(PGD) / 4 * pgdct2); } fclose(fp); idmx = pl[2]; idmy = pl[3]; idmz = pl[4]; xbig = idmx / 2; ybig = idmz / 2; zbig = idmz / 2; mbgx = pf[0]; mbgy = pf[1]; mbgz = pf[2]; mstx = pf[3]; msty = pf[4]; mstz = pf[5]; xmax = pf[6]; xmin = pf[7]; ymax = pf[8]; ymin = pf[9]; zmax = pf[10]; zmin = pf[11]; datamax = pf[12]; datamin = pf[13]; wkx = xmax - xmin; wky = ymax - ymin; wkz = zmax - zmin; wkmax = wkx; if(wky > wkmax) wkmax = wky; if(wkz > wkmax) wkmax = wkz; wkmax = (float)0.5 * (float)sqrt(2*wkmax*wkmax); /* printf("wkmax=%+f \n",wkmax);*/ dist = wkmax * 1.2; eyex = dist / INIX; eyey = dist / INIY; eyez = dist / INIZ; divm = dist / 50.0; strcpy(buf, filename); for (i = strlen(buf) - 1; i >= 0; i--){ if (buf[i] == '.') break; } if (i > 0){ buf[i] = 0x00; strcat(buf, ".wrl"); } else strcpy(buf, "pgv.wrl"); out = fopen(buf, "wt"); fprintf(out, "#VRML V1.0 ascii\n"); fprintf(out, "DEF Title Info {\n"); fprintf(out, " string \"MO display\"\n"); fprintf(out, "}\n"); fprintf(out, "DEF ViewerSpeed Info {\n"); fprintf(out, " string \"10\"\n"); fprintf(out, "}\n"); /* fprintf(out, "DirectionalLight {\n"); fprintf(out, " on TRUE\n"); fprintf(out, " intensity 1\n"); fprintf(out, " color 1 1 1\n"); fprintf(out, " direction -1 -1 -1\n"); fprintf(out, " location 100.0 100.0 100.0\n"); fprintf(out, "}\n"); fprintf(out, "DirectionalLight {\n"); fprintf(out, " on TRUE\n"); fprintf(out, " intensity 0.7\n"); fprintf(out, " color 1 1 1\n"); fprintf(out, " direction 1 1 1\n"); fprintf(out, " location -100.0 -100.0 -100.0\n"); fprintf(out, "}\n");*/ MakeParts(); }