#define PROG_NAME "TriangToX3D" #define PROG_DESC "???" #define PROG_VERS "1.0" /* Last edited on 2024-12-21 11:39:08 by stolfi */ #define TriangToX3D_C_COPYRIGHT \ "" #define PROG_INFO \ "" \ " " /* This program contain procedures to write "3D topologies" (non exclusively triangulations) in X3D format (".poly"), an interactive wireframe viewer for X11. */ #include #include #include #include #include #include #include // #include #include #include /* [[!!! DOES THIS COMMENT FROM Octf.h APPLY HERE ??? */ /* A '@{chip->?}' is a group of four @places, consisting of two mutually dual wedges. */ TYPE double FourNodes_t = RECORD u, v, w, x: uint; } double Color = frgb_t; typedef struct Options_t { char *inFileTp; inFileSt3 : char *; char *outFile; bool_t silhouette; /* TRUE draws the silhouette walls */ bool_t all; /* TRUE draws even non-existing triangles */ bool_t colored; /* coloring the original walls with a defined palete */ uint ordernet; /* Order on the net for original walls of the map. */ } double double = double; VAR Color palette[5+1]; /* the palette colors for the original walls. */ fac : REF ARRAY OF Color; /* the wall colors to use */ bool_t Sign(d: double) /* Return TRUE iff the longreal value is positive, FALSE c.c. */ { assert(d!=0.0); if (d < 0.0){ return FALSE }else{ return TRUE; }; } /* END Sign */ Options_t *GetOptions(int argc, char **argv); int main(int argc, char **argv) { Options_t *o = GetOptions(argc, argv); char *topo_cmt = jsprintf("Created by %s on %s", PROG_NAME, Today()); /* Random_t coins = MakeRandomSource(4615); */ ??? tc = Triangulation.ReadToMa(o->inFileTp); ??? rc3 = Tridimensional.ReadState3D(o->inFileSt3); ??? top = tc.top; ??? c3 = rc3^; { WriteX3DFile(o->outFile, top, c3, o) return 0; } void WriteX3DFile(char *name, ElemTableRec_t *top, *c3: Tridimensional.Coords3D_t; Options_t op; ) <* FATAL Wr.Failure, Thread.Alerted, OSError.E); { ??? wr = FileWr.Open(name & ".poly"); { fprintf(wr, "# Created by TriangToX3D: " & name & ".poly\n"); WriteX3D(wr, top, c3, op); fclose(wr) } } /* END WriteX3DFile */ void WriteX3D(FILE *wr, *ElemTableRec_t *top; *c3: Tridimensional.Coords3D_t; Options_t op; ) double FindOriR3(q: FourNodes_t) /* For each tetrahedron with extremus nodes numbers u,v,w,x compute us its orientation in R^{3} through the 4x4 determinant: _ _ | c3[q.u][0] c3[q.u][1] c3[q.u][2] 1.0 | double B = | c3[q.v][0] c3[q.v][1] c3[q.v][2] 1.0 | | c3[q.w][0] c3[q.w][1] c3[q.w][2] 1.0 | | c3[q.x][0] c3[q.x][1] c3[q.x][2] 1.0 | - - */ { with ( double a = (r4_t){c3[q.u][0], c3[q.u][1], c3[q.u][2], 1.0}; double b = (r4_t){c3[q.v][0], c3[q.v][1], c3[q.v][2], 1.0}; double c = (r4_t){c3[q.w][0], c3[q.w][1], c3[q.w][2], 1.0}; double d = (r4_t){c3[q.x][0], c3[q.x][1], c3[q.x][2], 1.0} ){ return r4_det(a,b,c,d); } } FindOriR3; bool_t SilhouetteWalls(Place_t @p) /* Return TRUE iff the wall associated to the @place "a" is a silhouette wall, FALSE c.c. */ { ??? t = TetraNegPosNodes(a); ??? un = t[0]->num; ??? vn = t[1]->num; ??? wn = t[2]->num; ??? xn = t[3]->num; ??? yn = t[4]->num; with ( double t1 = FourNodes_t{un,vn,wn,xn}; double t2 = FourNodes_t{un,vn,wn,yn}; double d1 = FindOriR3(t1); double d2 = FindOriR3(t2) ){ if (((Sign(d1)) && (Sign(d2))) || (((NOT Sign(d1))) && ((NOT Sign(d2))))) { return TRUE; } else { return FALSE; } } } SilhouetteWalls; void WriteX3DCoord(double x) { fprintf(wr, Fmt.LongReal(x*1000.0, prec = 5)) } WriteX3DCoord; void WriteX3DColor(*cr: frgb_t) { fprintf(wr, Fmt.Int(ROUND(255.0*cr[0]))); fprintf(wr, " "); fprintf(wr, Fmt.Int(ROUND(255.0*cr[1]))); fprintf(wr, " "); fprintf(wr, Fmt.Int(ROUND(255.0*cr[2]))); } WriteX3DColor; void WriteX3DPoint(r3_t *p) { WriteX3DCoord(p[0]); fprintf(wr, " "); WriteX3DCoord(p[1]); fprintf(wr, " "); WriteX3DCoord(p[2]); } WriteX3DPoint; void WriteX3DWall( uint *n; *f: Triangulation.Wall; ) /* This procedure writes a n-gon wall */ REF uint_vec_t sc ; frgb_t color; { sc = NEW(REF uint_vec_t ,n); color = f.color; fprintf(wr, "# wall " & Fmt.Int(f->num) & "\n"); fprintf(wr, " "); WriteX3DColor(color); fprintf(wr, "# color \n\n"); ??? a = f.pa; { for (i = 0; i < n; i++) { sc[i] = OrgV(a)->num; fprintf(wr, " "); WriteX3DPoint(c3[sc[i]]); fprintf(wr, "\n"); a = NextE(a); }; } fprintf(wr,"\n"); fflush(wr); } WriteX3DWall; void WriteGhostTriang(u,v,w : r3_t; frgb_t color) /* This procedure writes a triangular ghost wall */ { fprintf(wr, "# ghost wall\n"); fprintf(wr, " "); WriteX3DColor(color); fprintf(wr, "# color \n\n"); fprintf(wr, " "); WriteX3DPoint(u); fprintf(wr, "\n"); fprintf(wr, " "); WriteX3DPoint(v); fprintf(wr, "\n"); fprintf(wr, " "); WriteX3DPoint(w); fprintf(wr, "\n\n"); fflush(wr); } WriteGhostTriang; void WriteInternalTriangle(f: Wall; bool_t colored; ordernet: uint) /* Writes the POV representation of an internal net for the "a.wall" (which is assumed to be a triangle). */ { ??? a = f.pa; Place_t b = NextE(a); Place_t c = NextE(b); Node_t un = OrgV(a)->num; Node_t vn = OrgV(b)->num; Node_t wn = OrgV(c)->num; ??? d0x = (c3[vn][0] - c3[un][0])/FLOAT(ordernet, double)); with( double d0y = (c3[vn][1] - c3[un][1])/FLOAT(ordernet, double); double d0z = (c3[vn][2] - c3[un][2])/FLOAT(ordernet, double); double d1x = (c3[wn][0] - c3[vn][0])/FLOAT(ordernet, double); double d1y = (c3[wn][1] - c3[vn][1])/FLOAT(ordernet, double); double d1z = (c3[wn][2] - c3[vn][2])/FLOAT(ordernet, double); double d2x = (c3[un][0] - c3[wn][0])/FLOAT(ordernet, double); double d2y = (c3[un][1] - c3[wn][1])/FLOAT(ordernet, double); double d2z = (c3[un][2] - c3[wn][2])/FLOAT(ordernet, double); fc == f.color ){ if (ordernet == 1) { /* nothing */ } else if (ordernet == 2){ for (j = 1; j < ordernet; j++) { ??? n0x = c3[vn][0] - FLOAT(j, double) * d0x); with( double n0y = c3[vn][1] - FLOAT(j, double) * d0y; double n0z = c3[vn][2] - FLOAT(j, double) * d0z; double n1x = c3[wn][0] - FLOAT(j, double) * d1x; double n1y = c3[wn][1] - FLOAT(j, double) * d1y; double n1z = c3[wn][2] - FLOAT(j, double) * d1z; double n2x = c3[un][0] - FLOAT(j, double) * d2x; double n2y = c3[un][1] - FLOAT(j, double) * d2y; double n2z = c3[un][2] - FLOAT(j, double) * d2z; n0 == (r3_t){n0x,n0y,n0z}, n1 == (r3_t){n1x,n1y,n1z}, n2 == (r3_t){n2x,n2y,n2z} ){ if (! colored) { WriteGhostTriang(n0,n1,n2,fc); } else { WriteGhostTriang(n0,n1,n2,fc); } } } } else if (ordernet == 3){ for (j = 1; j < 2; j++) { ??? n00x = c3[vn][0] - FLOAT(j, double) * d0x); with( double n00y = c3[vn][1] - FLOAT(j, double) * d0y; double n00z = c3[vn][2] - FLOAT(j, double) * d0z; n00 == (r3_t){n00x,n00y,n00z}, double n01x = c3[vn][0] - FLOAT(j+1, double) * d0x; double n01y = c3[vn][1] - FLOAT(j+1, double) * d0y; double n01z = c3[vn][2] - FLOAT(j+1, double) * d0z; n01 == (r3_t){n01x,n01y,n01z}, double n10x = c3[wn][0] - FLOAT(j, double) * d1x; double n10y = c3[wn][1] - FLOAT(j, double) * d1y; double n10z = c3[wn][2] - FLOAT(j, double) * d1z; n10 == (r3_t){n10x,n10y,n10z}, double n11x = c3[wn][0] - FLOAT(j+1, double) * d1x; double n11y = c3[wn][1] - FLOAT(j+1, double) * d1y; double n11z = c3[wn][2] - FLOAT(j+1, double) * d1z; n11 == (r3_t){n11x,n11y,n11z}, double n20x = c3[un][0] - FLOAT(j, double) * d2x; double n20y = c3[un][1] - FLOAT(j, double) * d2y; double n20z = c3[un][2] - FLOAT(j, double) * d2z; n20 == (r3_t){n20x,n20y,n20z}, double n21x = c3[un][0] - FLOAT(j+1, double) * d2x; double n21y = c3[un][1] - FLOAT(j+1, double) * d2y; double n21z = c3[un][2] - FLOAT(j+1, double) * d2z; n21 == (r3_t){n21x,n21y,n21z}, double i = Scale(1.0/FLOAT(6,double),Add(Add(Add(Add(Add(n00,n01),n10),n11),n20),n21)) ){ if (! colored) { WriteGhostTriang(n00,i,n11,fc); WriteGhostTriang(i,n21,n10,fc); WriteGhostTriang(n01,n20,i,fc); } else { WriteGhostTriang(n00,i,n11,fc); WriteGhostTriang(i,n21,n10,fc); WriteGhostTriang(n01,n20,i,fc); } } } } else { /* nothing */ } } } WriteInternalTriangle; { if (op.silhouette){ for (i = 0; i < top->wall.nel; i++) { ??? f = top->wall[i]; ??? a = f.pa; ??? der = Octf.DegreeOfEdge(a); { if ((SilhouetteWalls(a)) && (NOT f->exists)) { WriteX3DWall(der,f); } } } } if (op.colored) { /* computing the original number walls */ uint max = 0; { for (i = 0; i < top->wall.nel; i++) { ??? f = top->wall[i]; { if (f->exists) { max = MAX(max,f->root); } } }; fprintf(stderr,"The original number walls is " & Fmt.Int(max+1) & "\n"); fac = NEW(REF ARRAY OF Color,max+1); /* defining the palette colors with brightness aprox. 0.7 */ palette[0] = Color{1.00,0.50,1.00}; palette[1] = Color{0.00,1.00,1.00}; palette[2] = Color{0.80,0.80,0.00}; palette[3] = Color{1.00,0.60,0.60}; palette[4] = Color{0.25,1.00,0.25}; palette[5] = Color{0.70,0.70,1.00}; /* attribution of differents colors for each original wall */ for (j = 0; j <= (max); j++) { fac[j] = palette[j % 6]; } } } /* drawing the interior of the original walls as a net with the appropriate colors */ for (i = 0; i < top->wall.nel; i++) { ??? f = top->wall[i]; { if ((f->exists) || (op.all)) { ??? froot = f->root, der == Octf.DegreeOfEdge(f.pa); { if (op.colored){ f.color = fac[froot]; } WriteX3DWall(der,top->wall[i]); WriteInternalTriangle(top->wall[i],op.colored,op.ordernet); } } } } } /* END WriteX3D */ Options_t *GetOptions(int argc, char **argv) { Options_t *o = (Options_t *)malloc(sizeof(Options_t)); argparser_t *pp = argparser_new(stderr, argc, argv); argparser_set_help(pp, PROG_NAME " version " PROG_VERS ", usage:\n" PROG_HELP); argparser_set_info(pp, PROG_INFO); argparser_process_help_info_options(pp); { ¦TRY argparser_get_keyword(pp, "-inFileTp"); o->inFileTp = argparser_get_next(pp); argparser_get_keyword(pp, "-inFileSt3"); o->inFileSt3 = argparser_get_next(pp); if ((argparser_keyword_present(pp, "-outFile"))) { o->outFile = argparser_get_next(pp) } else { o->outFile = o->inFileTp } o->all = argparser_keyword_present(pp, "-all"); o->silhouette = argparser_keyword_present(pp, "-silhouette"); o->colored = argparser_keyword_present(pp, "-colored"); if ((argparser_keyword_present(pp, "-ordernet"))) { o->ordernet = argparser_get_next_int(pp, 1, 5); } argparser_finish(pp); ----------------------------------- #define _HELP \ fprintf(stderr, "Usage: TriangToX3D \\\n" \ " -inFileTp -inFileSt3 \\\n" \ " [-outFile ] [-all] [-silhouette] [-colored]\n"); END¦ } } return o; } /* END GetOptions */ /* end TriangToX3D */ /* Copyright © 2001 Universidade Estadual de Campinas (UNICAMP) */