/* * $Id: nviz_init.c,v 1.20.2.2 2006/11/30 06:33:47 hamish Exp $ */ #include #include #include "tk.h" #include "interface.h" #include #include "coldefs.h" #include /* get from gislib: */ #include #include char startup_script[] = "toplevel .wait_ok\n\ label .wait_ok.wait -text \"Please wait...\" -fg red -bg black\n\ pack .wait_ok.wait -ipadx 20 -ipady 20 -expand 1 -fill both\n\ wm geometry .wait_ok \"+800+50\"\n\ wm geometry . \"+100+100\"\n\ wm title . \"NVIZ\"\n\ update\n\ grab .wait_ok.wait\n"; int script_mode=0; static int parse_command(Nv_data * data, Tcl_Interp * interp, /* Current interpreter. */ int argc, const char **argv) { struct Option *elev, *colr, *vct, *pnt, *vol; struct Option *panel_path, *script, *state; struct Flag *no_args, *script_kill, *demo, *verbose; struct GModule *module; char *arglist[3], *autoload; int i, aload = 1; /* * Flags and Options: * -q : quickstart, starts nvwish without querying for the usual maps * * path : panel path, adds the given directory to the path to * search for panels * * script : script file, after starting nviz immediately plays the * named script * * -k : script kill, if this flag is set, then Nviz will exit after completing * a script started from the command line * * -x : demo mode, the usual "please wait" messages are nuked. */ module = G_define_module(); module->keywords = _("visualization"); module->description = _("nviz - Visualization and animation tool for GRASS data"); elev = G_define_option(); elev->key = "elevation"; elev->type = TYPE_STRING; elev->required = NO; elev->multiple = YES; elev->gisprompt = "old,cell,Raster"; elev->description = _("Raster file(s) for Elevation"); colr = G_define_option(); colr->key = "color"; colr->type = TYPE_STRING; colr->required = NO; colr->multiple = YES; colr->gisprompt = "old,cell,Raster"; colr->description = _("Raster file(s) for Color"); vct = G_define_option(); vct->key = "vector"; vct->type = TYPE_STRING; vct->required = NO; vct->multiple = YES; vct->gisprompt = "old,vector,Vector"; vct->description = _("Vector lines/areas overlay file(s)"); pnt = G_define_option(); pnt->key = "points"; pnt->type = TYPE_STRING; pnt->required = NO; pnt->multiple = YES; pnt->gisprompt = "old,vector,Vector"; pnt->description = _("Vector points overlay file(s)"); vol = G_define_option(); vol->key = "volume"; vol->type = TYPE_STRING; vol->required = NO; vol->multiple = YES; vol->gisprompt = "old,grid3,3d raster"; vol->description = _("Name of existing 3dcell map"); no_args = G_define_flag(); no_args->key = 'q'; no_args->description = _("Quickstart - Do not load any data"); script_kill = G_define_flag(); script_kill->key = 'k'; script_kill->description = _("Script kill option"); demo = G_define_flag(); demo->key = 'x'; demo->description = _("Start in Demo mode"); verbose = G_define_flag(); verbose->key = 'v'; verbose->description = _("Output more comments (default=quiet)"); panel_path = G_define_option(); panel_path->key = "path"; panel_path->type = TYPE_STRING; panel_path->required = NO; panel_path->description = _("Set alternative panel path"); script = G_define_option(); script->key = "script"; script->type = TYPE_STRING; script->required = NO; script->description = _("Execute script file at startup"); state = G_define_option(); state->key = "state"; state->type = TYPE_STRING; state->required = NO; state->description = _("Load previosly saved state file"); /* BUG?: warning: passing arg 2 of `G_parser' from incompatible pointer type */ if (G_parser(argc, argv)) exit(EXIT_FAILURE); /* [?!]: Exit status is zero to avoid TCL complaints */ /* bug exists in at least GRASS 6.2.0, 6.2.1 */ if(vol->answer) G_warning(_("There is a bug in NVIZ's volume code! Work-around: " "Start with \"nviz -q\" and add the volume map manually from " "the Volume Panel.")); { float defs[MAX_ATTS]; defs[ATT_TOPO] = 0; defs[ATT_COLOR] = DEFAULT_SURF_COLOR; defs[ATT_MASK] = 0; defs[ATT_TRANSP] = 0; defs[ATT_SHINE] = 60; defs[ATT_EMIT] = 0; GS_set_att_defaults(defs, defs); } /* Put in the "please wait..." message unless we are in demo mode */ if ((strstr(argv[0], "nviz") != NULL) && (!demo->answer)) { if (Tcl_Eval(interp, startup_script) != TCL_OK) G_fatal_error("%s", interp->result); } if (verbose->answer) { fprintf(stderr, "\n"); fprintf(stderr, "\n"); fprintf(stderr, "Version: %s\n", GRASS_VERSION_STRING); fprintf(stderr, "\n"); fprintf(stderr, "Authors: Bill Brown, Terry Baker, Mark Astley, David Gerdes\n"); fprintf(stderr, "\tmodifications: Jaro Hofierka, Bob Covill\n"); fprintf(stderr, "\n"); fprintf(stderr, "\n"); fprintf(stderr, "Please cite one or more of the following references in publications\n"); fprintf(stderr, "where the results of this program were used:\n"); fprintf(stderr, "Brown, W.M., Astley, M., Baker, T., Mitasova, H. (1995).\n"); fprintf(stderr, "GRASS as an Integrated GIS and Visualization System for\n"); fprintf(stderr, "Spatio-Temporal Modeling, Proceedings of Auto Carto 12, Charlotte, N.C.\n"); fprintf(stderr, "\n"); fprintf(stderr, "Mitasova, H., W.M. Brown, J. Hofierka, 1994, Multidimensional\n"); fprintf(stderr, "dynamic cartography. Kartograficke listy, 2, p. 37-50.\n"); fprintf(stderr, "\n"); fprintf(stderr, "Mitas L., Brown W. M., Mitasova H., 1997, Role of dynamic\n"); fprintf(stderr, "cartography in simulations of landscape processes based on multi-variate\n"); fprintf(stderr, "fields. Computers and Geosciences, Vol. 23, No. 4, pp. 437-446\n"); fprintf(stderr, "\n"); fprintf(stderr, "http://www2.gis.uiuc.edu:2280/modviz/viz/nviz.html\n"); fprintf(stderr, "\n"); fprintf(stderr, "The papers are available at\n"); fprintf(stderr, "http://www2.gis.uiuc.edu:2280/modviz/\n"); } /* done verbose */ /* Look for quickstart flag */ if (no_args->answer) { elev->answers = colr->answers = vct->answers = pnt->answers = vol->answers = NULL; } /* Look for scriptkill flag */ if (script_kill->answer) { if (Tcl_VarEval(interp, "set NvizScriptKill 1 ", NULL) != TCL_OK) G_fatal_error("%s", interp->result); } /* See if an alternative panel path is specified */ if (panel_path->answer) { /* If so then set the variable NvizAltPath to the alternative path */ if (Tcl_VarEval(interp, "set NvizAltPath ", panel_path->answer, NULL) != TCL_OK) G_fatal_error("%s", interp->result); } /* Get State file from command line */ if (state->answer) { if (Tcl_VarEval(interp, "set NvizLoadState ", state->answer, NULL) != TCL_OK) G_fatal_error("%s", interp->result); } /* See if a script file was specified */ if (script->answer) { /* If so then set the variable NvizPlayScript to the file */ if (Tcl_VarEval(interp, "set NvizPlayScript ", script->answer, NULL) != TCL_OK) G_fatal_error("%s", interp->result); } #ifdef XSCRIPT AUTO_FILE = aut->answer; /* either file name or NULL */ Write_script = swrit->answer; #endif /* Consult the user's .grassrc file to see if we should * automatically set the colormap of loaded surfaces to be * the same as the raster used for topography. The appropriate * resource is: * Nviz_AutoSurfColors * If this resource isn't specified, it defaults to true. */ autoload = G__getenv("Nviz_AutoSurfColors"); if ((autoload != NULL) && (!strcmp(autoload, "false"))) aload = 0; /* Parse answeres from user */ /* Run check to make sure elev == colr */ if (elev->answers && colr->answers) { int ee=0, cc=0; for (i = 0; elev->answers[i]; i++) { ee = i; } for (i = 0; colr->answers[i]; i++) { cc = i; } if (ee != cc) G_fatal_error (_("Number of elevation files does not match number of colors files")); } if (elev->answers) { char tmp[30]; for (i = 0; elev->answers[i]; i++) { arglist[1] = "surf"; arglist[2] = elev->answers[i]; Nnew_map_obj_cmd(data, interp, 3, arglist); /* See if we should autoload the color file */ if (aload) { strncpy(tmp, interp->result, 29); if (colr->answers) { if (Tcl_VarEval(interp, tmp, " set_att color ", colr->answers[i], NULL) != TCL_OK) G_fatal_error("%s", interp->result); } else { if (Tcl_VarEval(interp, tmp, " set_att color ", elev->answers[i], NULL) != TCL_OK) G_fatal_error("%s", interp->result); } } } if (i > 1) set_default_wirecolors(data, i); } if (vct->answers) { if (!elev->answers && GS_num_surfs() == 0) { int i; int *surf_list; arglist[1] = "surf"; Nnew_map_obj_cmd(data, interp, 2, arglist); surf_list = GS_get_surf_list(&i); GS_set_att_const(surf_list[0], ATT_TRANSP, 255); } for (i = 0; vct->answers[i]; i++) { arglist[1] = "vect"; arglist[2] = vct->answers[i]; Nnew_map_obj_cmd(data, interp, 3, arglist); } } if (pnt->answers) { if (!elev->answers && GS_num_surfs() == 0) { int i; int *surf_list; arglist[1] = "surf"; Nnew_map_obj_cmd(data, interp, 2, arglist); surf_list = GS_get_surf_list(&i); GS_set_att_const(surf_list[0], ATT_TRANSP, 255); } for (i = 0; pnt->answers[i]; i++) { arglist[1] = "site"; arglist[2] = pnt->answers[i]; Nnew_map_obj_cmd(data, interp, 3, arglist); } } if (vol->answers) { for (i = 0; vol->answers[i]; i++) { arglist[1] = "vol"; arglist[2] = vol->answers[i]; Nnew_map_obj_cmd(data, interp, 3, arglist); } } return(TCL_OK); } /* * Ngetargs: gets command line args from tcl. Tcl stores argv[0] by * itself and the rest of the args as a single string so Ngetargs goes * through some string manipulation to put all the args back into a single array * so that G_parser can deal with them without getting sick. */ int Ngetargs(Tcl_Interp * interp, /* Current interpreter. */ const char ***args) { const char *argv0, *tmp; char *tmp2; const char *cmd; int argc; argv0 = Tcl_GetVar(interp, "argv0", TCL_LEAVE_ERR_MSG); tmp = Tcl_GetVar(interp, "argv", TCL_LEAVE_ERR_MSG); cmd = Tcl_GetNameOfExecutable(); if (strstr(argv0, "script_tools") != NULL || strstr(argv0, "script_play") != NULL || strstr(argv0, "script_get_line") != NULL || strstr(argv0, "script_file_tools") != NULL) { fprintf(stderr, "Entering script mode ...\n"); tmp2 = (char *)G_malloc ((strlen(cmd) + 2) * (sizeof(char))); sprintf(tmp2, "%s", cmd); script_mode = 1; } else if ( strstr(cmd, argv0) == NULL) { tmp2 = (char *)G_malloc ((strlen(cmd) + strlen(argv0) + strlen(tmp) + 4 ) * (sizeof(char))); sprintf(tmp2, "%s %s %s", cmd, argv0, tmp); } else { tmp2 = (char *)G_malloc ((strlen(argv0) + strlen(tmp) + 2) * (sizeof(char))); sprintf(tmp2, "%s %s", argv0, tmp); } if (TCL_ERROR == Tcl_SplitList(interp, tmp2, &argc, args)) exit(-1); return (argc); } int make_red_yellow_ramp(int *ramp, int num, int minval, int maxval) { int g, i, incr; incr = (maxval - minval) / (num - 1); for (i = 0; i < num; i++) { g = minval + incr * i; RGB_TO_INT(maxval, g, 0, ramp[i]); } return 0; } /* Sorts surfaces by mid elevation, lowest to highest. * Puts ordered id numbers in id_sort, leaving surfs unchanged. * Puts ordered indices of surfaces from id_orig in indices. */ int sort_surfs_mid(int *id_sort, int *indices, int num) { int i, j; float midvals[MAX_SURFS]; float tmp, max=0., tmin, tmax, tmid; int *surf_list; surf_list = GS_get_surf_list(&i); for (i = 0; i < num; i++) { GS_get_zextents(surf_list[i], &tmin, &tmax, &tmid); if (i == 0) max = tmax; else max = max < tmax ? tmax : max; midvals[i] = tmid; } for (i = 0; i < num; i++) { tmp = midvals[0]; indices[i] = 0; for (j = 0; j < num; j++) { if (midvals[j] < tmp) { tmp = midvals[j]; indices[i] = j; } } midvals[indices[i]] = max + 1; id_sort[i] = surf_list[indices[i]]; } return(TCL_OK); } int set_default_wirecolors(Nv_data * dc, int surfs) { #ifdef DO_GREYSCALE int *surf_list; int i, color, greyincr, greyval; greyincr = 200 / (surfs + 1); /* just use upper values */ surf_list = GS_get_surf_list(&i); for (i = 0; i < surfs; i++) { greyval = 55 + greyincr * (i + 1); RGB_TO_INT(greyval, greyval, greyval, color); GS_set_wire_color(surf_list[i], color); } G_free (surf_list); #else int i, ramp[MAX_SURFS]; int sortSurfs[MAX_SURFS], sorti[MAX_SURFS]; make_red_yellow_ramp(ramp, surfs, 30, 255); sort_surfs_mid(sortSurfs, sorti, surfs); for (i = 0; i < surfs; i++) { GS_set_wire_color(sortSurfs[i], ramp[i]); } #endif return 0; } int Ninit(Tcl_Interp * interp, Tk_Window w) { static Nv_data data; char nviz_script[] = "source [exec g.gisenv GISBASE]/etc/nviz2.2/scripts/nviz2.2_script\n"; /* compile in the home directory */ Tcl_SetVar(interp, "src_boot", getenv("GISBASE"), TCL_GLOBAL_ONLY); init_commands(interp, &data); Ninitdata(interp, &data); /*** ACS_MODIFY flythrough ONE LINE ******************************************/ togl_flythrough_init_tcl(interp, &data); /*** ACS_MODIFY pick ONE LINE ************************************************/ pick_init_tcl(interp, &data); /*** ACS_MODIFY site_attr ONE LINE ************************************************/ site_attr_init_tcl(interp, &data); /*** ACS_MODIFY site_highlight ONE LINE ************************************************/ site_highlight_init_tcl(interp, &data); if (!script_mode) Tcl_Eval(interp, nviz_script); /* source nviz_script to start main window */ return(TCL_OK); } void swap_togl(); int Ninitdata(Tcl_Interp * interp, /* Current interpreter. */ Nv_data * data) { const char **argv; int argc; argc = Ngetargs(interp, &argv); G_gisinit(argv[0]); GS_libinit(); GVL_libinit(); /* TODO */ GS_set_swap_func(swap_togl); data->NumCplanes = 0; data->CurCplane = 0; if (!script_mode) parse_command(data, interp, argc, argv); return(TCL_OK); }