#! /usr/bin/gawk -f # Last edited on 2004-10-27 14:45:48 by stolfi BEGIN { usage = ( ARGV[0] " -f color-conv.gawk\\\n" \ " [ -v offDir=DIR ] [ -v showStretched=BOOL ] \\\n" \ " [ -v gmr=N ] [ -v gmg=N ] [ -v gmb=N ] \\\n" \ " [-v logScale=BOOL] \\\n" \ " < file.parms > file.gvtop" \ ); # Reads a ".parms" file, turns the component colors into a geomview # model of a tetrahedron. If {showStretched} is true, shows the # stretched tetrahedron instead, and omits the RGB cube. The needed # auxiliary model "bola.off" is assumed to be in directory {offDir}. # The gamma and log-scale transforms are applied to the colors, as # requested. if (offDir == "") { offDir = "."; } if (showStretched == "") { showStretched = 1; } if (gmr == "") { gmr = 1.0; } if (gmg == "") { gmg = 1.0; } if (gmb == "") { gmb = 1.0; } if (logScale == "") { logScale = 0; } printf "{\n" printf " LIST\n" k = 0; split("", rt); split("", gt); split("", bt); # Layer colors split("", rm); split("", gm); split("", bm); # Stretch colors eps = 1.0/255.0; # Log scale threshhold stretched = 0; # True to plot the tetrahedron of stretched colors. map_given = 1; # For now; true if "-map" options present. } # Get rid of comments /[\#]/ { gsub(/[\#].*$/, "", $0); } # Should we check whether the -inGamma and -logScale options in the # ".parms" file are consistent with those given on the command line? # # /^ *[-]inGamma /{ # # Input gamma line # gmr = $2; gmg = $3; gmb = $4; # printf "using gamma = %6.4f %6.4f %6.4f\n", gmr, gmg, gmb > "/dev/stderr"; # next; # } # # /^ *[-]logScale /{ # # Log scale option # logScale = 1; # printf "using log scale\n" > "/dev/stderr"; # next; # } /^ *[-]stretched/ { stretched = showStretched; next; } /^ *[-]layer / { # Layer line icolor = 3; if ($(icolor) != "-color") { printf "bad layer line [%s]\n", $0 > "/dev/stderr"; exit 1; } # Get "-color" information: imap = icolor+1 + grab_color(icolor+1, rt, gt, bt, k); # Get "-map" information: if ((imap <= NF) && ($(imap) == "-map")) { iend = imap+1 + grab_color(imap+1, rm, gm, bm, k); } else { map_given = 0; } # Check format: if (NF != iend-1) { printf "bad layer NF [%s]\n", $0 > "/dev/stderr"; exit 1; } k++; next; } END { # Show tetrahedron edges if (k != 4) { printf "found %d layers - aborted\n", k > "/dev/stderr"; exit 1; } if (stretched && map_given) { show_tetrahedron(rm,gm,bm, 0.7,0.3,0.7); } else { show_tetrahedron(rt,gt,bt, 0.2,0.5,0.2); show_rgb_cube(); } printf "}\n"; # End of LIST printf "< %s/bola.off\n", offDir; } function grab_color(i,rv,gv,bv,k, r,g,b,nf,den) { # Parses fields {$(i)} through {$(i+2)} or {$(i+4)} as an RGB spec, # maps it though the current gamma and logscale options, # saves it in {rv[k],gv[k],bv[k]}. # Returns number of fields parsed if ($(i+3) == "/") { den = $(i+4) + 0.0; nf = 5; } else { den = 1.0; nf = 3; } if (i+nf-1 > NF) { printf "bad layer NF [%s]\n", $0 > "/dev/stderr"; exit 1; } r = gamma_in($(i+0)/den, gmr); g = gamma_in($(i+1)/den, gmg); b = gamma_in($(i+2)/den, gmb); if (logScale) { r = log_scale_in(r,eps); g = log_scale_in(g,eps); b = log_scale_in(b,eps); } rv[k] = r; gv[k] = g; bv[k] = b; return nf; } function show_color(r,g,b,size) { x = r - 0.5; y = g - 0.5; z = b - 0.5; radius = size/255.0; printf " { \n"; printf " appearance { material { ka 0.7 ambient %6.4f %6.4f %6.4f kd 0.3 diffuse %6.4f %6.4f %6.4f } }\n", r, g, b, r, g, b; printf " INST geom { : bola }\n"; printf " "; print_transform(x,y,z,radius); printf "\n"; printf " }\n"; } function print_transform(x,y,z,radius) { printf "transform {"; printf " %6.4f 0 0 0 ", radius; printf " 0 %6.4f 0 0 ", radius; printf " 0 0 %6.4f 0 ", radius; printf " %7.4f %7.4f %7.4f 1 ", x, y, z; printf "}"; } function show_tetrahedron(rv,gv,bv, re,ge,be, k) { for (k = 0; k < 4; k++) { show_color(rv[k],gv[k],bv[k], 5.0); } printf " {\n" set_edge_appearance(re,ge,be); printf " SKEL\n" printf " 4 6\n" for (k = 0; k < 4; k++) { printf " %7.4f %7.4f %7.4f\n", rv[k]-0.5, gv[k]-0.5, bv[k]-0.5; } 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 show_rgb_cube( rc,gc,bc) { for(rc = 0; rc <= 1; rc++) for(gc = 0; gc <= 1; gc++) for(bc = 0; bc <= 1; bc++) { show_color(rc,gc,bc, 3.0); } printf " {\n" set_edge_appearance(0.25, 0.25, 0.25); printf " SKEL\n" printf " 8 13\n" for(rc = 0; rc <= 1; rc++) for(gc = 0; gc <= 1; gc++) for(bc = 0; bc <= 1; bc++) { printf " %7.4f %7.4f %7.4f\n", rc-0.5, gc-0.5, bc-0.5; } 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 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 %6.4f %6.4f %6.4f \n", r, g, b; printf " }\n"; printf " }\n"; }