#define PROG_NAME "make-sphere-normal-map" #define PROG_DESC "create the normal map of a sphere" #define PROG_VERS "1.0" /* Copyright © 2006 by the State University of Campinas (UNICAMP). */ /* See the copyright, authorship, and warranty notice at end of file. */ /* Last edited on 2006-05-02 11:09:46 by stolfi */ #define PROG_HELP \ PROG_NAME " \\\n" \ " -size {NX} {NY} \\\n" \ " -sphere \\\n" \ " " pst_geom_sphere_radius_HELP " \\\n" \ " [ " pst_geom_sphere_center_HELP " ] \\\n" \ " [ " pst_geom_sphere_stretch_HELP " ] \\\n" \ " [ -subsample {NSAMP} ] \\\n" \ " [ -noise {AMOUNT} ] \\\n" \ " " argparser_help_info_HELP " \\\n" \ " > {NORMALMAP}.fni" #define PROG_INFO \ "NAME\n" \ " " PROG_NAME " - " PROG_DESC ".\n" \ "\n" \ "SYNOPSIS\n" \ " " PROG_HELP "\n" \ "\n" \ "DESCRIPTION\n" \ " Writes to {stdout} the /normal map/ of a sphere --- that is, a" \ " three-channel float-valued image of a sphere, with {NX} columns" \ " and {NY} rows, where the value of each pixel is the outwards-pointing" \ " unit vector normal to the sphere's surface in that pixel." \ "\n" \ " The sphere is assumed to be viewed in parallel oblique projection," \ " so that its image is an ellipse. The center of the ellipse is at" \ " {(CTRX,CTRY)}. The ellipse has minor radius {RAD} and major radius" \ " {RAD+LEN}, where {LEN} is the length of the stretch vector" \ " {(STRX,STRY)}. The major radius is parallel to that vector.\n" \ "\n" \ " The normal vector for each pixel is obtained by averaging the" \ " slopes {dZ/dX} and {dZ/dY} at a grid of {NSAMP*NSAMP} points" \ " with each pixel, and then converting the average slopes to a" \ " normal vector.\n" \ "\n" \ " Although digital photographs use conical projection, the parallel" \ " oblique model is a first-order approximation that should be fairly" \ " accurate for a small sphere taken at typical camera geometries.\n" \ "\n" \ " All dimensions and coordinates are in pixels. The origin is" \ " assumed to be at the lower left corner of the image, with the" \ " Y axis pointing up. Note that row 0 in a FNI image file is the" \ " BOTTOM row of the image.\n" \ "\n" \ " The output file is in the FNI format. See" \ " {float_image.h} for details.\n" \ "\n" \ "OPTIONS\n" \ " -size {NX} {NY}\n" \ " Specifies the number of columns and the number of rows" \ " of the output image. Required.\n" \ pst_geom_sphere_center_INFO " Defaults to the image's center.\n" \ "\n" \ pst_geom_sphere_radius_INFO " This parameter is mandatory.\n" \ "\n" \ pst_geom_sphere_stretch_INFO " The default is \"stretch 0 0\", meaning" \ " a circular image of radius {RAD} (as in orthogonal projection).\n" \ "\n" \ " -subsample {NSAMP}\n" \ " Specifies a grid of {NSAMP*NSAMP} sampling points with each" \ " pixel for slope averaging. Defaults to \"-subsample 3\".\n" \ "\n" \ " -noise {AMOUNT}\n" \ " Randomly perturbs the direction of the normal vectors. In" \ " particular, {AMOUNT=0} means no perturbation, while {AMOUNT=1}" \ " means that the result is uniformly distributed on the unit sphere" \ " and independent of the true norm. For small values of {AMOUNT}," \ " the perturbation is (to first order) a tangential vector with" \ " zero mean and root-mean-square length {AMOUNT}. Defaults to" \ " no perturbation.\n" \ "\n" \ argparser_help_info_HELP_INFO "\n" \ "\n" \ "SEE ALSO\n" \ " virtual-gauge(1), normal-to-slope(1), slope-to-height(1)," \ " slope-to-norma(1), pnm-to-fni(1), fni-to-pnm(1).\n" \ "\n" \ "AUTHOR\n" \ " Created 2006-04-07 by Jorge Stolfi, Unicamp." #define _GNU_SOURCE #include #include #include #include #include #include #include #include #include #include #include #include #include typedef struct options_t { /* Output image dimensions: */ int NX; /* Number of columns in output image. */ int NY; /* Number of rows in output image. */ int subsample; /* Order of subsampling grid within each pixel. */ double noise; /* Root mean square length of perturbation vector. */ pst_geom_sphere_t *geo; /* Geometry of sphere's image (dimensions in pixels): */ } options_t; options_t *msn_parse_options(int argc, char **argv); /* Parses the command line options, returns them as an {options_t} record. */ int main(int argc, char** argv); int main(int argc, char** argv) { pst_normal_map_proc_t *nrmf = &pst_geom_sphere_compute_normal; /* Parse options from the command line: */ options_t *o = msn_parse_options(argc, argv); float_image_t *NRM = float_image_new(3, o->NX, o->NY); r3x3_t xym_to_uvm, uvw_to_xyz; pst_geom_sphere_view_matrices(o->geo, &xym_to_uvm, &uvw_to_xyz); pst_normal_map_from_proc(*nrmf, o->subsample, &xym_to_uvm, &uvw_to_xyz, NRM); float_image_write(stdout, NRM); return 0; } options_t *msn_parse_options(int argc, char **argv) { 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); options_t *o = (options_t *)notnull(malloc(sizeof(options_t)), "no mem"); /* Parse image size parameter: */ argparser_get_keyword(pp, "-size"); o->NX = argparser_get_next_int(pp, 1, float_image_max_size); o->NY = argparser_get_next_int(pp, 1, float_image_max_size); r2_t ctrdef = (r2_t){{ 0.5*(double)(o->NX), 0.5*(double)(o->NY) }}; o->geo = pst_geom_sphere_parse(pp, FALSE, &ctrdef, NULL, NULL, NULL, NULL); if (o->geo == NULL) { argparser_error(pp, "must specify the sphere's geometry"); } if (argparser_keyword_present(pp, "-subsample")) { o->subsample = argparser_get_next_int(pp, 1, 100); } else { o->subsample = 3; } if (argparser_keyword_present(pp, "-noise")) { o->noise = argparser_get_next_double(pp, 0.0, 1.0e+20); } else { o->noise = 0.0; } argparser_finish(pp); return o; } /* COPYRIGHT, AUTHORSHIP, AND WARRANTY NOTICE: ** ** Copyright © 2006 by the State University of Campinas (UNICAMP). ** ** Created on 08/apr/2006 by Jorge Stolfi, UNICAMP. ** ** Permission to use, copy, modify, and redistribute this software and ** its documentation for any purpose and without fee is hereby ** granted, provided that: (1) the copyright notice at the top of this ** file and this copyright, authorship, and warranty notice is retained ** in all derived source files and documentation; (2) no executable ** code derived from this file is published or distributed without the ** corresponding source code; and (3) these same rights are granted to ** any recipient of such code, under the same conditions. ** This software is provided "as is", WITHOUT ANY EXPLICIT OR IMPLICIT ** WARRANTIES, not even the implied warranties of merchantibility and ** fitness for a particular purpose. END OF NOTICE. */