#! /usr/bin/gawk -f # Last edited on 2025-08-25 17:49:39 by stolfi BEGIN { # Reads a list of simple object specs. Turns it into a geomview model. # A simple object can be a point, a tetrahedron, or a box (a # hexahedron with quadrangular faces). See the description of # the input format in {view_point_cloud.sh}. # # Ignores blank lines and '#'-comments. usage = ( ARGV[0] " < ${data_file} > ${geom_file}" ); npoints = 0; nsegs = 0; ntetras = 0; nboxes = 0; in_seg = 0; # True while parsing line segment endpoints. in_tetra = 0; # True while parsing tetrahedron corners. in_box = 0; # True while parsing box corners. write_preamble(); } # // { printf "ยป %s\n", $0 > "/dev/stderr"; } # Ignore blanks and '#'-comments: // { gsub(/[#].*$/, "", $0); } /^[ \011\015]*$/{ next; } /^ *-[a-zA-Z]/ { if (in_seg) { data_error(("incomplete line segment"));} if (in_tetra) { data_error(("incomplete tetrahedron"));} if (in_box) { data_error(("incomplete box")); } } /^ *-point/ { # Data line if ((NF != 5) && (NF != 8)) { data_error(("bad NF " NF "")); } npoints++; x = $2; y = $3; z = $4; s = $5; if (NF == 5) { R = 1.0; G = 0.9; B = 0.2 } else { R = $6; G = $7; B = $8 } output_point(x,y,z,s,R,G,B); next; } /^ *-segment/ { if (NF != 4) { data_error(("bad NF " NF "")); } nsegs++; begin_grab_vertices() in_seg = 1; next; } /^ *-tetra/ { if (NF != 4) { data_error(("bad NF " NF "")); } ntetras++; begin_grab_vertices() in_tetra = 1; next; } /^ *-box/ { if (NF != 4) { data_error(("bad NF " NF "")); } nboxes++; begin_grab_vertices() in_box = 1; next; } function begin_grab_vertices() { R_e = $2; G_e = $3; B_e = $4; split("", x_v); split("", y_v); split("", z_v); split("", s_v); split("", R_v); split("", G_v); split("", B_v); nv = 0; } /^ *[-+]?[0-9]/ { if (in_seg || in_tetra || in_box) { if ((NF != 4) && (NF != 7)) { data_error(("bad NF")); } x = $1+0; y = $2+0; z = $3+0; s = $4+0; if (NF == 4) { R = R_e; G = G_e; B = B_e; } else { R = $5+0; G = $6+0; B = $7+0; } save_vertex(x,y,z, s, R,G,B); if (in_seg && (nv == 2)) { output_line_segment(x_v,y_v,z_v, s_v, R_v,G_v,B_v, R_e,G_e,B_e); in_seg = 0; } else if (in_tetra && (nv == 4)) { output_tetrahedron(x_v,y_v,z_v, s_v, R_v,G_v,B_v, R_e,G_e,B_e); in_tetra = 0; } else if (in_box && (nv == 8)) { output_box(x_v,y_v,z_v, s_v, R_v,G_v,B_v, R_e,G_e,B_e); in_box = 0; } } else { data_error(("spurious coords line")); } next; } // { data_error(("invalid format")); } END { write_postamble(); } function save_vertex(x,y,z, s, R,G,B) { x_v[nv] = x; y_v[nv] = y; z_v[nv] = z; s_v[nv] = s; R_v[nv] = R; G_v[nv] = G; B_v[nv] = B; nv++; } function output_point(x,y,z,s,R,G,B) { printf " { \n"; printf " appearance { material { diffuse %5.3f %5.3f %5.3f } }\n", R, G, B; printf " SPHERE %7.5f %7.4f %7.4f %7.4f\n", s, x, y, z; printf " }\n"; } function print_transform(x,y,z,s) { printf "transform {"; printf " %6.4f 0 0 0 ", s; printf " 0 %6.4f 0 0 ", s; printf " 0 0 %6.4f 0 ", s; printf " %7.4f %7.4f %7.4f 1 ", x, y, z; printf "}"; } function write_preamble() { # write_def_bola(); # write_def_pingo(); # ??? printf "{\n" printf " LIST\n" printf " { appearance {\n" printf " lighting { ambient 1 1 1 }\n" printf " material { ka 0.7 kd 0.3 ks 0.0 }\n" printf " }\n" } function write_def_bola() { printf "{ define\n" printf " bola = \n" printf " SPHERE\n" printf " 1.0\n" printf " 0.0 0.0 0.0\n" printf "}\n" } function write_def_pingo() { printf "{\n" printf " define pingo\n" printf " appearance\n" printf " { material { ka 0.7 kd 0.3 diffuse 1.0 1.0 1.0 ks 0.0 }\n" printf " lighting { ambient 1.0 1.0 1.0 }\n" printf " }\n" printf " =\n" printf " OFF\n" printf " 8 6 12\n" printf " -0.5 -0.5 -0.5\n" printf " -0.5 -0.5 0.5\n" printf " -0.5 0.5 -0.5\n" printf " -0.5 0.5 0.5\n" printf " 0.5 -0.5 -0.5\n" printf " 0.5 -0.5 0.5\n" printf " 0.5 0.5 -0.5\n" printf " 0.5 0.5 0.5\n" printf " 4 0 1 3 2\n" printf " 4 4 5 7 6\n" printf " 4 0 1 5 4\n" printf " 4 2 3 7 6\n" printf " 4 0 2 6 4\n" printf " 4 1 3 7 5\n" printf "}\n" } function output_line_segment(x_v,y_v,z_v, s_v, R_v,G_v,B_v, R_e,G_e,B_e, iv) { if (nv != 2) { prog_error(("line {nv}")); } for (iv = 0; iv < nv; iv++) { output_point(x_v[iv],y_v[iv],z_v[iv], s_v[iv], R_v[iv],G_v[iv],B_v[iv]); } printf " {\n" set_edge_appearance(R_e,G_e,B_e); printf " SKEL\n" printf " 2 1\n" for (iv = 0; iv < nv; iv++) { printf " %7.4f %7.4f %7.4f\n", x_v[iv],y_v[iv],z_v[iv]; } printf " 2 0 1\n"; printf " }\n"; } function output_tetrahedron(x_v,y_v,z_v, s_v, R_v,G_v,B_v, R_e,G_e,B_e, iv) { if (nv != 4) { prog_error(("tetra {nv}")); } for (iv = 0; iv < nv; iv++) { output_point(x_v[iv],y_v[iv],z_v[iv], s_v[iv], R_v[iv],G_v[iv],B_v[iv]); } printf " {\n" set_edge_appearance(R_e,G_e,B_e); printf " SKEL\n" printf " 4 6\n" for (iv = 0; iv < nv; iv++) { printf " %7.4f %7.4f %7.4f\n", x_v[iv],y_v[iv],z_v[iv]; } printf " 2 0 1\n"; printf " 2 0 2\n"; printf " 2 0 3\n"; printf " 2 1 2\n"; printf " 2 1 3\n"; printf " 2 2 3\n"; printf " }\n"; } function output_box(x_v,y_v,z_v, s_v, R_v,G_v,B_v, R_e,G_e,B_e, iv) { if (nv != 8) { prog_error(("box {nv}")); } for (iv = 0; iv < nv; iv++) { output_point(x_v[iv],y_v[iv],z_v[iv], s_v[iv], R_v[iv],G_v[iv],B_v[iv]); } printf " {\n" set_edge_appearance(R_e,G_e,B_e); printf " SKEL\n" printf " 8 13\n" for (iv = 0; iv < nv; iv++) { printf " %7.4f %7.4f %7.4f\n", x_v[iv],y_v[iv],z_v[iv]; } printf " 2 0 1\n"; printf " 2 2 3\n"; printf " 2 4 5\n"; printf " 2 6 7\n"; printf " 2 0 2\n"; printf " 2 1 3\n"; printf " 2 4 6\n"; printf " 2 5 7\n"; printf " 2 0 4\n"; printf " 2 1 5\n"; printf " 2 2 6\n"; printf " 2 3 7\n"; printf " 2 0 7\n"; printf " }\n"; } function write_postamble() { printf " }\n"; printf "}\n"; } function set_edge_appearance(R,G,B) { printf " appearance {\n"; printf " material {\n"; printf " ka 0.5 ambient 0.5 1.0 1.0\n"; printf " kd 0.5 diffuse 0.5 1.0 1.0\n"; printf " ks 0.0\n"; printf " edgecolor %5.3f %5.3f %5.3f \n", R, G, B; printf " }\n"; printf " }\n"; } function data_error(msg) { printf "%s:%d: ** %s\n", FILENAME, FNR, msg > "/dev/stderr"; printf " [[%s]]\n", $0 > "/dev/stderr"; exit(1) } function prog_error(msg) { printf "** PROG ERREOR: %s\n", msg > "/dev/stderr"; exit(1) }