[brlcad-commits] SF.net SVN: brlcad:[32395] brlcad/trunk/src/libged
Open Source Solid Modeling CAD
Brought to you by:
brlcad
From: <bo...@us...> - 2008-08-11 19:14:51
|
Revision: 32395 http://brlcad.svn.sourceforge.net/brlcad/?rev=32395&view=rev Author: bob1961 Date: 2008-08-11 19:14:44 +0000 (Mon, 11 Aug 2008) Log Message: ----------- Added the following commands to libged and libtclcad: idents, regions, solids, loadview, saveview and solids_on_ray. Added Paths: ----------- brlcad/trunk/src/libged/loadview.c brlcad/trunk/src/libged/saveview.c brlcad/trunk/src/libged/solids_on_ray.c brlcad/trunk/src/libged/tables.c Added: brlcad/trunk/src/libged/loadview.c =================================================================== --- brlcad/trunk/src/libged/loadview.c (rev 0) +++ brlcad/trunk/src/libged/loadview.c 2008-08-11 19:14:44 UTC (rev 32395) @@ -0,0 +1,375 @@ +/* L O A D V I E W . C + * BRL-CAD + * + * Copyright (c) 2008 United States Government as represented by + * the U.S. Army Research Laboratory. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * version 2.1 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this file; see the file named COPYING for more + * information. + */ +/** @file loadview.c + * + * The loadview command. + * + */ + +#include "common.h" + +#include <stdlib.h> +#include <ctype.h> +#include <string.h> + +#include "ged_private.h" + +int ged_cm_vsize(int argc, char **argv); +int ged_cm_eyept(int argc, char **argv); +int ged_cm_lookat_pt(int argc, char **argv); +int ged_cm_vrot(int argc, char **argv); +int ged_cm_orientation(int argc, char **argv); +int ged_cm_set(int argc, char **argv); +int ged_cm_null(int argc, char **argv); + + +static vect_t ged_eye_model; +static mat_t ged_viewrot; +static struct ged *current_gedp; + +/** + * here we define a minimal table of commands that are supported by the + * loadview command. unsupported commands are those that have no bearing on + * view restoration. + */ +struct command_tab ged_loadview_cmdtab[] = { + {"viewsize", "size in mm", "set view size", + ged_cm_vsize, 2, 2}, + {"eye_pt", "xyz of eye", "set eye point", + ged_cm_eyept, 4, 4}, + {"lookat_pt", "x y z [yflip]", "set eye look direction, in X-Y plane", + ged_cm_lookat_pt, 4, 5}, + {"viewrot", "4x4 matrix", "set view direction from matrix", + ged_cm_vrot, 17, 17}, + {"orientation", "quaturnion", "set view direction from quaturnion", + ged_cm_orientation, 5, 5}, + {"set", "", "show or set parameters", + ged_cm_set, 1, 999}, + + /* begin unsupported commands (for view loading) */ + + {"start", "frame number", "start a new frame", + ged_cm_null, 2, 2}, + {"clean", "", "clean articulation from previous frame", + ged_cm_null, 1, 1}, + {"end", "", "end of frame setup, begin raytrace", + ged_cm_null, 1, 1}, + + /* not output, by default in saveview */ + + {"multiview", "", "produce stock set of views", + ged_cm_null, 1, 1}, + {"anim", "path type args", "specify articulation animation", + ged_cm_null, 4, 999}, + {"tree", "treetop(s)", "specify alternate list of tree tops", + ged_cm_null, 1, 999}, + {"ae", "azim elev", "specify view as azim and elev, in degrees", + ged_cm_null, 3, 3}, + {"opt", "-flags", "set flags, like on command line", + ged_cm_null, 2, 999}, + + /* this is a quick hack used for quietly parsing the EOF delimiter in the + * script files. + */ + {"EOF", "", "End of file delimiter", + ged_cm_null, 1, 1}, + + /* XXX support for the ae command is not included, though it probably should */ + {(char *)0, (char *)0, (char *)0, + 0, 0, 0 /* END */} +}; + +int +ged_loadview(struct ged *gedp, int argc, const char *argv[]) +{ + register FILE *fp; + char buffer[512] = {0}; + + /* data pulled from script file */ + int perspective=-1; +#define MAX_DBNAME 2048 + char dbName[MAX_DBNAME] = {0}; + char objects[10000] = {0}; + char *editArgv[3]; + int prevPerspective; + static const char *usage = "filename"; + + GED_CHECK_DATABASE_OPEN(gedp, BRLCAD_ERROR); + GED_CHECK_VIEW(gedp, BRLCAD_ERROR); + + /* initialize result */ + bu_vls_trunc(&gedp->ged_result_str, 0); + gedp->ged_result = GED_RESULT_NULL; + gedp->ged_result_flags = 0; + + /* must be wanting help */ + if (argc == 1) { + gedp->ged_result_flags |= GED_RESULT_FLAGS_HELP_BIT; + bu_vls_printf(&gedp->ged_result_str, "Usage: %s %s", argv[0], usage); + return BRLCAD_OK; + } + + if (argc < 2) { + bu_vls_printf(&gedp->ged_result_str, "Usage: %s %s", argv[0], usage); + return BRLCAD_ERROR; + } + + /* make sure the file exists */ + if (!bu_file_exists(argv[1])) { + bu_log("Error: File %s does not exist\n", argv[1]); + return BRLCAD_ERROR; + } + + /* open the file for reading */ + if ((fp = fopen( argv[1], "r")) == NULL) { + perror(argv[1]); + return BRLCAD_ERROR; + } + + prevPerspective = gedp->ged_gvp->gv_perspective; + current_gedp = gedp; + + /* turn perspective mode off, by default. A "-p" option in the + * view script will turn it back on. + */ + gedp->ged_gvp->gv_perspective = 0; + + /* iterate over the contents of the raytrace script */ + while (!feof(fp)) { + memset(buffer, 0, 512); + fscanf(fp, "%512s", buffer); + + if (strncmp(buffer, "-p", 2)==0) { + /* we found perspective */ + + buffer[0]=' '; + buffer[1]=' '; + sscanf(buffer, "%d", &perspective); + /* bu_log("perspective=%d\n", perspective);*/ + gedp->ged_gvp->gv_perspective = perspective; + + } else if (strncmp(buffer, "$*", 2)==0) { + /* the next read is the file name, the objects come + * after that + */ + + memset(dbName, 0, MAX_DBNAME); + fscanf(fp, "%2048s", dbName); /* MAX_DBNAME */ + + /* if the last character is a line termination, + * remove it (it should always be unless the user + * modifies the file) + */ + if ( *(dbName + strlen(dbName) - 1)=='\\' ) { + memset(dbName+strlen(dbName)-1, 0, 1); + } + /* bu_log("dbName=%s\n", dbName); */ + + if (!bu_same_file(gedp->ged_wdbp->dbip->dbi_filename, dbName)) { + /* stop here if they are not the same file, + * otherwise, we may proceed as expected, and load + * the objects. + */ + bu_vls_printf(&gedp->ged_result_str, "View script references a different database\nCannot load the view without closing the current database\n(i.e. run \"opendb %s\")\n", dbName); + + /* restore state before leaving */ + gedp->ged_gvp->gv_perspective = prevPerspective; + + return BRLCAD_ERROR; + } + + /* get rid of anything that may be displayed, since we + * will load objects that are listed in the script next. + */ + (void)ged_zap(gedp, 1, NULL); + + /* now get the objects listed */ + fscanf(fp, "%10000s", objects); + /* bu_log("OBJECTS=%s\n", objects);*/ + while ((!feof(fp)) && (strncmp(objects, "\\", 1)!=0)) { + + /* clean off the single quotes... */ + if (strncmp(objects, "'", 1)==0) { + objects[0]=' '; + memset(objects+strlen(objects)-1, ' ', 1); + sscanf(objects, "%10000s", objects); + } + + editArgv[0] = "draw"; + editArgv[1] = objects; + editArgv[2] = (char *)NULL; + if (ged_draw(gedp, 2, editArgv) != BRLCAD_OK) { + bu_vls_printf(&gedp->ged_result_str, "Unable to load object: %s\n", objects); + } + + /* bu_log("objects=%s\n", objects);*/ + fscanf(fp, "%10000s", objects); + } + + /* end iteration over reading in listed objects */ + } else if (strncmp(buffer, "<<EOF", 5)==0) { + char *cmdBuffer = NULL; + /* we are almost done .. read in the view commands */ + + while ( (cmdBuffer = rt_read_cmd( fp )) != NULL ) { + /* even unsupported commands should return successfully as + * they should be calling ged_cm_null() + */ + if ( rt_do_cmd( (struct rt_i *)0, cmdBuffer, ged_loadview_cmdtab ) < 0 ) { + bu_vls_printf(&gedp->ged_result_str, "command failed: %s\n", cmdBuffer); + } + bu_free( (genptr_t)cmdBuffer, "loadview cmdBuffer" ); + } + /* end iteration over rt commands */ + + } + /* end check for non-view values (dbname, etc) */ + + } + /* end iteration over file until eof */ + fclose(fp); + + /* now we have to finish the eye point calculations that usually get + * postponed until the end command runs. Since we are at the "end" + * of a commands section, we may finish the computations. + */ + /* First step: put eye at view center (view 0, 0, 0) */ + MAT_COPY(gedp->ged_gvp->gv_rotation, ged_viewrot); + MAT_DELTAS_VEC_NEG(gedp->ged_gvp->gv_center, ged_eye_model); + ged_view_update(gedp->ged_gvp); + + return BRLCAD_OK; +} + + +int +ged_cm_vsize(int argc, char **argv) +{ + if ( argc < 2 ) + return(-1); + /* for some reason, scale is supposed to be half of size... */ + current_gedp->ged_gvp->gv_size = atof(argv[1]); + current_gedp->ged_gvp->gv_scale = current_gedp->ged_gvp->gv_size * 0.5; + current_gedp->ged_gvp->gv_isize = 1.0 / current_gedp->ged_gvp->gv_size; + return(0); +} + + +int +ged_cm_eyept(int argc, char **argv) +{ + if ( argc < 4 ) + return(-1); + ged_eye_model[X] = atof(argv[1]); + ged_eye_model[Y] = atof(argv[2]); + ged_eye_model[Z] = atof(argv[3]); + /* Processing is deferred until ged_cm_end() */ + return(0); +} + + +int +ged_cm_lookat_pt(int argc, char **argv) +{ + point_t pt; + vect_t dir; + + if ( argc < 4 ) + return(-1); + pt[X] = atof(argv[1]); + pt[Y] = atof(argv[2]); + pt[Z] = atof(argv[3]); + + VSUB2( dir, pt, ged_eye_model ); + VUNITIZE( dir ); + +#if 1 + /* + At the moment bn_mat_lookat will return NAN's if the direction vector + is aligned with the Z axis. The following is a temporary workaround. + */ + { + vect_t neg_Z_axis; + + VSET(neg_Z_axis, 0.0, 0.0, -1.0); + bn_mat_fromto( ged_viewrot, dir, neg_Z_axis); + } +#else + bn_mat_lookat( ged_viewrot, dir, yflip ); +#endif + + /* Final processing is deferred until ged_cm_end(), but eye_pt + * must have been specified before here (for now) + */ + return(0); +} + + +int +ged_cm_vrot(int argc, char **argv) +{ + register int i; + + if ( argc < 17 ) + return(-1); + for ( i=0; i<16; i++ ) + ged_viewrot[i] = atof(argv[i+1]); + /* Processing is deferred until ged_cm_end() */ + return(0); +} + +int +ged_cm_orientation(int argc, char **argv) +{ + register int i; + quat_t quat; + + for ( i=0; i<4; i++ ) + quat[i] = atof( argv[i+1] ); + quat_quat2mat( ged_viewrot, quat ); + return(0); +} + +int +ged_cm_set(int argc, char **argv) +{ + return(-1); +} + +/** + * any commands that are not supported or implemented may call this null + * routine to avoid rt_do_cmd() "command not found" error reporting + */ +int +ged_cm_null(int argc, char **argv) +{ + return(0); +} + + +/* + * Local Variables: + * tab-width: 8 + * mode: C + * indent-tabs-mode: t + * c-file-style: "stroustrup" + * End: + * ex: shiftwidth=4 tabstop=8 + */ Property changes on: brlcad/trunk/src/libged/loadview.c ___________________________________________________________________ Added: svn:executable + * Added: svn:mime-type + text/plain Added: svn:eol-style + native Added: brlcad/trunk/src/libged/saveview.c =================================================================== --- brlcad/trunk/src/libged/saveview.c (rev 0) +++ brlcad/trunk/src/libged/saveview.c 2008-08-11 19:14:44 UTC (rev 32395) @@ -0,0 +1,220 @@ +/* S A V E V I E W . C + * BRL-CAD + * + * Copyright (c) 2008 United States Government as represented by + * the U.S. Army Research Laboratory. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * version 2.1 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this file; see the file named COPYING for more + * information. + */ +/** @file saveview.c + * + * The saveview command. + * + */ + +#include "common.h" + +#include <stdlib.h> +#include <ctype.h> +#include <string.h> + +#include "bio.h" +#include "solid.h" +#include "ged_private.h" + +static char *ged_basename_without_suffix(register const char *p1, register const char *suff); + + +int +ged_saveview(struct ged *gedp, int argc, const char *argv[]) +{ + register struct solid *sp; + register int i; + register FILE *fp; + char *base; + int c; + char rtcmd[255] = {'r', 't', 0}; + char outlog[255] = {0}; + char outpix[255] = {0}; + char inputg[255] = {0}; + static const char *usage = "[-e] [-i] [-l] [-o] filename [args]"; + + GED_CHECK_DATABASE_OPEN(gedp, BRLCAD_ERROR); + GED_CHECK_VIEW(gedp, BRLCAD_ERROR); + + /* initialize result */ + bu_vls_trunc(&gedp->ged_result_str, 0); + gedp->ged_result = GED_RESULT_NULL; + gedp->ged_result_flags = 0; + + /* must be wanting help */ + if (argc == 1) { + gedp->ged_result_flags |= GED_RESULT_FLAGS_HELP_BIT; + bu_vls_printf(&gedp->ged_result_str, "Usage: %s %s", argv[0], usage); + return BRLCAD_OK; + } + + if (argc < 2) { + bu_vls_printf(&gedp->ged_result_str, "Usage: %s %s", argv[0], usage); + return BRLCAD_ERROR; + } + + bu_optind = 1; + while ((c = bu_getopt(argc, (char * const *)argv, "e:i:l:o:")) != EOF) { + switch (c) { + case 'e': + snprintf(rtcmd, 255, "%s", bu_optarg); + break; + case 'l': + snprintf(outlog, 255, "%s", bu_optarg); + break; + case 'o': + snprintf(outpix, 255, "%s", bu_optarg); + break; + case 'i': + snprintf(inputg, 255, "%s", bu_optarg); + break; + default: { + bu_vls_printf(&gedp->ged_result_str, "Option '%c' unknown\n", c); + bu_vls_printf(&gedp->ged_result_str, "help saveview"); + return BRLCAD_ERROR; + } + } + } + argc -= bu_optind-1; + argv += bu_optind-1; + + if (argc < 2) { + bu_vls_printf(&gedp->ged_result_str, "Usage: %s %s", argv[0], usage); + return BRLCAD_ERROR; + } + + if ( (fp = fopen( argv[1], "a")) == NULL ) { + perror(argv[1]); + return BRLCAD_ERROR; + } + (void)bu_fchmod(fp, 0755); /* executable */ + + if (!gedp->ged_wdbp->dbip->dbi_filename) { + bu_log("Error: geometry file is not specified\n"); + return BRLCAD_ERROR; + } + + if (!bu_file_exists(gedp->ged_wdbp->dbip->dbi_filename)) { + bu_log("Error: %s does not exist\n", gedp->ged_wdbp->dbip->dbi_filename); + return BRLCAD_ERROR; + } + + base = ged_basename_without_suffix( argv[1], ".sh" ); + if (outpix[0] == '\0') { + snprintf(outpix, 255, "%s.pix", base); + } + if (outlog[0] == '\0') { + snprintf(outlog, 255, "%s.log", base); + } + + /* Do not specify -v option to rt; batch jobs must print everything. -Mike */ + (void)fprintf(fp, "#!/bin/sh\n%s -M ", rtcmd); + if ( gedp->ged_gvp->gv_perspective > 0 ) + (void)fprintf(fp, "-p%g ", gedp->ged_gvp->gv_perspective); + for ( i=2; i < argc; i++ ) + (void)fprintf(fp, "%s ", argv[i]); + + if (strncmp(rtcmd,"nirt",4) != 0) + (void)fprintf(fp, "\\\n -o %s\\\n $*\\\n", outpix); + + if (inputg[0] == '\0') { + snprintf(inputg, 255, "%s", gedp->ged_wdbp->dbip->dbi_filename); + } + (void)fprintf(fp, " %s\\\n ", inputg); + + /* Find all unique top-level entries. + * Mark ones already done with s_wflag == UP + */ + FOR_ALL_SOLIDS(sp, &gedp->ged_gdp->gd_headSolid) + sp->s_wflag = DOWN; + FOR_ALL_SOLIDS(sp, &gedp->ged_gdp->gd_headSolid) { + register struct solid *forw; /* XXX */ + struct directory *dp = FIRST_SOLID(sp); + + if ( sp->s_wflag == UP ) + continue; + if (dp->d_addr == RT_DIR_PHONY_ADDR) continue; + (void)fprintf(fp, "'%s' ", dp->d_namep); + sp->s_wflag = UP; + for (BU_LIST_PFOR(forw, sp, solid, &gedp->ged_gdp->gd_headSolid)) { + if ( FIRST_SOLID(forw) == dp ) + forw->s_wflag = UP; + } + } + (void)fprintf(fp, "\\\n 2>> %s\\\n", outlog); + (void)fprintf(fp, " <<EOF\n"); + + { + vect_t eye_model; + + ged_rt_set_eye_model(gedp, eye_model); + ged_rt_write(gedp, fp, eye_model); + } + + (void)fprintf(fp, "\nEOF\n"); + (void)fclose( fp ); + + FOR_ALL_SOLIDS(sp, &gedp->ged_gdp->gd_headSolid) + sp->s_wflag = DOWN; + + return BRLCAD_OK; +} + +/** + * Return basename of path, removing leading slashes and trailing suffix. + */ +static char * +ged_basename_without_suffix(register const char *p1, register const char *suff) +{ + register char *p2, *p3; + static char buf[128]; + + /* find the basename */ + p2 = (char *)p1; + while (*p1) { + if (*p1++ == '/') + p2 = (char *)p1; + } + + /* find the end of suffix */ + for (p3=(char *)suff; *p3; p3++) + ; + + /* early out */ + while (p1>p2 && p3>suff) { + if (*--p3 != *--p1) + return(p2); + } + + /* stash and return filename, sans suffix */ + bu_strlcpy( buf, p2, p1-p2+1 ); + return(buf); +} + + +/* + * Local Variables: + * tab-width: 8 + * mode: C + * indent-tabs-mode: t + * c-file-style: "stroustrup" + * End: + * ex: shiftwidth=4 tabstop=8 + */ Property changes on: brlcad/trunk/src/libged/saveview.c ___________________________________________________________________ Added: svn:executable + * Added: svn:mime-type + text/plain Added: svn:eol-style + native Added: brlcad/trunk/src/libged/solids_on_ray.c =================================================================== --- brlcad/trunk/src/libged/solids_on_ray.c (rev 0) +++ brlcad/trunk/src/libged/solids_on_ray.c 2008-08-11 19:14:44 UTC (rev 32395) @@ -0,0 +1,316 @@ +/* S O L I D S _ O N _ R A Y . C + * BRL-CAD + * + * Copyright (c) 2008 United States Government as represented by + * the U.S. Army Research Laboratory. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * version 2.1 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this file; see the file named COPYING for more + * information. + */ +/** @file skel.c + * + * The skel command. + * + */ + +#include "common.h" + +#include <stdlib.h> +#include <ctype.h> +#include <string.h> + +#include "bio.h" +#include "bu.h" +#include "bn.h" +#include "cmd.h" +#include "solid.h" +#include "ged_private.h" + +static char **ged_skewer_solids(struct ged *gedp, int argc, const char **argv, fastf_t *ray_orig, fastf_t *ray_dir, int full_path); + +static char *rt_cmd_vec[MAXARGS]; +static int rt_cmd_vec_len; + +int +ged_solids_on_ray(struct ged *gedp, int argc, const char *argv[]) +{ + char **snames; + int h = 0; + int v = 0; + int i; /* Dummy loop index */ + double t; + double t_in; + point_t ray_orig; + vect_t ray_dir; + point_t extremum[2]; + vect_t unit_H, unit_V; + static const char *usage = "[h v]"; + + GED_CHECK_DATABASE_OPEN(gedp, BRLCAD_ERROR); + GED_CHECK_READ_ONLY(gedp, BRLCAD_ERROR); + GED_CHECK_DRAWABLE(gedp, BRLCAD_ERROR); + GED_CHECK_VIEW(gedp, BRLCAD_ERROR); + + /* initialize result */ + bu_vls_trunc(&gedp->ged_result_str, 0); + gedp->ged_result = GED_RESULT_NULL; + gedp->ged_result_flags = 0; + + /* must be wanting help */ + if (argc == 1) { + gedp->ged_result_flags |= GED_RESULT_FLAGS_HELP_BIT; + bu_vls_printf(&gedp->ged_result_str, "Usage: %s %s", argv[0], usage); + return BRLCAD_OK; + } + + if (argc != 1 && argc != 3) { + bu_vls_printf(&gedp->ged_result_str, "Usage: %s %s", argv[0], usage); + return BRLCAD_ERROR; + } + + if (argc == 3 && + (sscanf(argv[1], "%d", &h) != 1 || + sscanf(argv[2], "%d", &v) != 1)) { + bu_vls_printf(&gedp->ged_result_str, "Usage: %s %s", argv[0], usage); + return BRLCAD_ERROR; + } + + if ((int)GED_VMIN > h || h > (int)GED_VMAX || (int)GED_VMIN > v || v > (int)GED_VMAX) { + bu_vls_printf(&gedp->ged_result_str, "Screen coordinates out of range\nMust be between +/-2048"); + return BRLCAD_ERROR; + } + + VSET(ray_orig, -gedp->ged_gvp->gv_center[MDX], + -gedp->ged_gvp->gv_center[MDY], -gedp->ged_gvp->gv_center[MDZ]); + /* + * Compute bounding box of all objects displayed. + * Borrowed from size_reset() in chgview.c + */ + for (i = 0; i < 3; ++i) + { + extremum[0][i] = INFINITY; + extremum[1][i] = -INFINITY; + } +#if 0 + FOR_ALL_SOLIDS (sp, &gedp->ged_gdp->gd_headSolid) + { + minus[X] = sp->s_center[X] - sp->s_size; + minus[Y] = sp->s_center[Y] - sp->s_size; + minus[Z] = sp->s_center[Z] - sp->s_size; + VMIN(extremum[0], minus); + plus[X] = sp->s_center[X] + sp->s_size; + plus[Y] = sp->s_center[Y] + sp->s_size; + plus[Z] = sp->s_center[Z] + sp->s_size; + VMAX(extremum[1], plus); + } +#endif + VMOVEN(ray_dir, gedp->ged_gvp->gv_rotation + 8, 3); + VSCALE(ray_dir, ray_dir, -1.0); + for (i = 0; i < 3; ++i) + if (NEAR_ZERO(ray_dir[i], 1e-10)) + ray_dir[i] = 0.0; + if ((ray_orig[X] >= extremum[0][X]) && + (ray_orig[X] <= extremum[1][X]) && + (ray_orig[Y] >= extremum[0][Y]) && + (ray_orig[Y] <= extremum[1][Y]) && + (ray_orig[Z] >= extremum[0][Z]) && + (ray_orig[Z] <= extremum[1][Z])) + { + t_in = -INFINITY; + for (i = 0; i < 6; ++i) { + if (ray_dir[i%3] == 0) + continue; + t = (extremum[i/3][i%3] - ray_orig[i%3]) / + ray_dir[i%3]; + if ((t < 0) && (t > t_in)) + t_in = t; + } + VJOIN1(ray_orig, ray_orig, t_in, ray_dir); + } + + VMOVEN(unit_H, gedp->ged_gvp->gv_model2view, 3); + VMOVEN(unit_V, gedp->ged_gvp->gv_model2view + 4, 3); + VJOIN1(ray_orig, ray_orig, h * gedp->ged_gvp->gv_scale * INV_GED_V, unit_H); + VJOIN1(ray_orig, ray_orig, v * gedp->ged_gvp->gv_scale * INV_GED_V, unit_V); + + /* + * Build a list of all the top-level objects currently displayed + */ + rt_cmd_vec_len = ged_build_tops(gedp, (struct solid *)&gedp->ged_gdp->gd_headSolid, &rt_cmd_vec[0], &rt_cmd_vec[MAXARGS]); + +#if 0 + start_catching_output(&gedp->ged_result_str); +#endif + snames = ged_skewer_solids(gedp, rt_cmd_vec_len, (const char **)rt_cmd_vec, ray_orig, ray_dir, 1); +#if 0 + stop_catching_output(&gedp->ged_result_str); +#endif + + if (snames == 0) { + bu_vls_printf(&gedp->ged_result_str, "Error executing ged_skewer_solids: "); + return (BRLCAD_ERROR); + } + + for (i = 0; snames[i] != 0; ++i) + bu_vls_printf(&gedp->ged_result_str, " %s", snames[i]); + + bu_free((genptr_t) snames, "solid names"); + + return BRLCAD_OK; +} + + +/* + * G E D _ N O _ O P + * + * Null event handler for use by rt_shootray(). + * + * Does nothing. Returns 1. + */ +static int +ged_no_op(struct application *ap, struct partition *ph, struct region *r1, struct region *r2, struct partition *hp) +{ + return (1); +} + +/* + * R P T _ H I T S _ M I K E + * + * Each partition represents a segment, i.e. a single solid. + * Boolean operations have not been performed. + * The partition list is sorted by ascending inhit distance. + * This code does not attempt to eliminate duplicate segs, + * e.g. from piercing the torus twice. + */ +static int +ged_rpt_hits_mike(struct application *ap, struct partition *PartHeadp, struct seg *segp) +{ + register struct partition *pp; + int len; + char **list; + int i; + + len = rt_partition_len(PartHeadp) + 2; + list = (char **)bu_calloc( len, sizeof(char *), "hit list[]"); + + i = 0; + for (pp = PartHeadp->pt_forw; pp != PartHeadp; pp = pp->pt_forw) { + RT_CK_PT(pp); + list[i++] = db_path_to_string(&(pp->pt_inseg->seg_stp->st_path)); + } + list[i++] = NULL; + if (i > len) bu_exit(EXIT_FAILURE, "rpt_hits_mike: array overflow\n"); + + ap->a_uptr = (genptr_t)list; + return len; +} + +/* + * R P T _ M I S S + * + * Miss handler for use by rt_shootray(). + * + * Stuffs the address of a null string in ap->a_uptr and returns 0. + */ + +static int +ged_rpt_miss(struct application *ap) +{ + ap->a_uptr = NULL; + + return (0); +} + +/* + * G E D _ S K E W E R _ S O L I D S + * + * Fire a ray at some geometry and obtain a list of + * the solids encountered, sorted by first intersection. + * + * The function has five parameters: the model and objects at which + * to fire (in an argc/argv pair) the origination point and direction + * for the ray, and a result-format specifier. So long as it could + * find the objects in the model, skewer_solids() returns a null- + * terminated array of solid names. Otherwise, it returns 0. If + * full_path is nonzero, then the entire path for each solid is + * recorded. Otherwise, only the basename is recorded. + * + * N.B. - It is the caller's responsibility to free the array + * of solid names. + */ +static char ** +ged_skewer_solids (struct ged *gedp, int argc, const char **argv, fastf_t *ray_orig, fastf_t *ray_dir, int full_path) +{ + struct application ap; + struct rt_i *rtip; + struct bu_list sol_list; + + if (argc <= 0) { + bu_vls_printf(&gedp->ged_result_str, "skewer_solids argc<=0\n"); + return ((char **) 0); + } + + /* .inmem rt_gettrees .rt -i -u [who] */ + rtip = rt_new_rti( gedp->ged_wdbp->dbip ); + rtip->useair = 1; + rtip->rti_dont_instance = 1; /* full paths to solids, too. */ + if (rt_gettrees(rtip, argc, argv, 1) == -1) { + bu_vls_printf(&gedp->ged_result_str, "rt_gettrees() failed\n"); + rt_clean(rtip); + bu_free((genptr_t)rtip, "struct rt_i"); + return ((char **) 0); + } + + /* .rt prep 1 */ + rtip->rti_hasty_prep = 1; + rt_prep(rtip); + + BU_LIST_INIT(&sol_list); + + /* + * Initialize the application + */ + RT_APPLICATION_INIT(&ap); + ap.a_magic = RT_AP_MAGIC; + ap.a_ray.magic = RT_RAY_MAGIC; + ap.a_hit = ged_rpt_hits_mike; + ap.a_miss = ged_rpt_miss; + ap.a_resource = RESOURCE_NULL; + ap.a_overlap = ged_no_op; + ap.a_onehit = 0; + ap.a_user = 1; /* Requests full paths to solids, not just basenames */ + ap.a_rt_i = rtip; + ap.a_zero1 = ap.a_zero2 = 0; + ap.a_purpose = "skewer_solids()"; + ap.a_no_booleans = 1; /* full paths, no booleans */ + VMOVE(ap.a_ray.r_pt, ray_orig); + VMOVE(ap.a_ray.r_dir, ray_dir); + + (void) rt_shootray(&ap); + + rt_clean(rtip); + bu_free((genptr_t)rtip, "struct rt_i"); + + return ((char **) ap.a_uptr); +} + + +/* + * Local Variables: + * tab-width: 8 + * mode: C + * indent-tabs-mode: t + * c-file-style: "stroustrup" + * End: + * ex: shiftwidth=4 tabstop=8 + */ Property changes on: brlcad/trunk/src/libged/solids_on_ray.c ___________________________________________________________________ Added: svn:executable + * Added: svn:mime-type + text/plain Added: svn:eol-style + native Added: brlcad/trunk/src/libged/tables.c =================================================================== --- brlcad/trunk/src/libged/tables.c (rev 0) +++ brlcad/trunk/src/libged/tables.c 2008-08-11 19:14:44 UTC (rev 32395) @@ -0,0 +1,466 @@ +/* T A B L E S . C + * BRL-CAD + * + * Copyright (c) 2008 United States Government as represented by + * the U.S. Army Research Laboratory. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * version 2.1 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this file; see the file named COPYING for more + * information. + */ +/** @file tables.c + * + * The tables command. + * + */ + +#include "common.h" + +#include <stdlib.h> +#ifdef HAVE_SYS_TYPES_H +# include <sys/types.h> +#endif +#ifdef HAVE_PWD_H +# include <pwd.h> +#endif +#include <ctype.h> +#include <string.h> + +#include "bio.h" +#include "ged_private.h" + +/* structure to distinguish new solids from existing (old) solids */ +struct identt { + int i_index; + char i_name[NAMESIZE+1]; + mat_t i_mat; +}; + +#define ABORTED -99 +#define OLDSOLID 0 +#define NEWSOLID 1 +#define SOL_TABLE 1 +#define REG_TABLE 2 +#define ID_TABLE 3 + +static struct identt identt, idbuf; +static int idfd; +static int rd_idfd; +static int numreg; +static int numsol; +static FILE *tabptr; + +static int ged_check(register char *a, register char *b); +static int ged_sol_number(matp_t matrix, char *name, int *old); +static void ged_new_tables(struct ged *gedp, struct directory *dp, struct bu_ptbl *cur_path, fastf_t *old_mat, int flag); + +int +ged_tables(struct ged *gedp, int argc, const char *argv[]) +{ + static const char sortcmd[] = "sort -n +1 -2 -o /tmp/ord_id "; + static const char catcmd[] = "cat /tmp/ord_id >> "; + struct bu_vls tmp_vls; + struct bu_vls cmd; + struct bu_ptbl cur_path; + int flag; + int status; + char *timep; + time_t now; + int i; + static const char *usage = "file object(s)"; + + GED_CHECK_DATABASE_OPEN(gedp, BRLCAD_ERROR); + + /* initialize result */ + bu_vls_trunc(&gedp->ged_result_str, 0); + gedp->ged_result = GED_RESULT_NULL; + gedp->ged_result_flags = 0; + + /* must be wanting help */ + if (argc == 1) { + gedp->ged_result_flags |= GED_RESULT_FLAGS_HELP_BIT; + bu_vls_printf(&gedp->ged_result_str, "Usage: %s %s", argv[0], usage); + return BRLCAD_OK; + } + + if (argc < 3) { + bu_vls_printf(&gedp->ged_result_str, "Usage: %s %s", argv[0], usage); + return BRLCAD_ERROR; + } + + + bu_vls_init(&tmp_vls); + bu_vls_init( &cmd ); + bu_ptbl_init( &cur_path, 8, "f_tables: cur_path" ); + numreg = 0; + numsol = 0; + +#if 0 + if ( setjmp( jmp_env ) == 0 ) { + /* allow interupts */ + (void)signal( SIGINT, sig3); + } else { + bu_vls_free( &cmd ); + bu_vls_free(&tmp_vls); + bu_ptbl_free( &cur_path ); + return BRLCAD_OK; + } +#endif + status = BRLCAD_OK; + + /* find out which ascii table is desired */ + if ( strcmp(argv[0], "solids") == 0 ) { + /* complete summary - down to solids/paremeters */ + flag = SOL_TABLE; + } else if ( strcmp(argv[0], "regions") == 0 ) { + /* summary down to solids as members of regions */ + flag = REG_TABLE; + } else if ( strcmp(argv[0], "idents") == 0 ) { + /* summary down to regions */ + flag = ID_TABLE; + } else { + /* should never reach here */ + bu_vls_printf(&gedp->ged_result_str, "%s: input error\n", argv[0]); + status = BRLCAD_ERROR; + goto end; + } + + /* open the file */ + if ((tabptr=fopen(argv[1], "w+")) == NULL) { + bu_vls_printf(&gedp->ged_result_str, "%s: Can't open %s\n", argv[0], argv[1]); + status = BRLCAD_ERROR; + goto end; + } + + if ( flag == SOL_TABLE || flag == REG_TABLE ) { + /* temp file for discrimination of solids */ + if ( (idfd = creat("/tmp/mged_discr", 0600)) < 0 ) { + perror( "/tmp/mged_discr" ); + status = BRLCAD_ERROR; + goto end; + } + rd_idfd = open( "/tmp/mged_discr", 2 ); + } + + (void)time( &now ); + timep = ctime( &now ); + timep[24] = '\0'; + (void)fprintf(tabptr, "1 -8 Summary Table {%s} (written: %s)\n", argv[0], timep); + (void)fprintf(tabptr, "2 -7 file name : %s\n", gedp->ged_wdbp->dbip->dbi_filename); + (void)fprintf(tabptr, "3 -6 \n"); + (void)fprintf(tabptr, "4 -5 \n"); +#ifndef _WIN32 + (void)fprintf(tabptr, "5 -4 user : %s\n", getpwuid(getuid())->pw_gecos); +#else + { + char uname[256]; + DWORD dwNumBytes = 256; + if (GetUserName(uname, &dwNumBytes)) + (void)fprintf(tabptr, "5 -4 user : %s\n", uname); + else + (void)fprintf(tabptr, "5 -4 user : UNKNOWN\n"); + } +#endif + (void)fprintf(tabptr, "6 -3 target title : %s\n", gedp->ged_wdbp->dbip->dbi_title); + (void)fprintf(tabptr, "7 -2 target units : %s\n", + bu_units_string(gedp->ged_wdbp->dbip->dbi_local2base) ); + (void)fprintf(tabptr, "8 -1 objects :"); + for (i=2; i<argc; i++) { + if ( (i%8) == 0 ) + (void)fprintf(tabptr, "\n "); + (void)fprintf(tabptr, " %s", argv[i]); + } + (void)fprintf(tabptr, "\n\n"); + + /* make the tables */ + for ( i=2; i<argc; i++ ) { + struct directory *dp; + + bu_ptbl_reset( &cur_path ); + if ( (dp = db_lookup(gedp->ged_wdbp->dbip, argv[i], LOOKUP_NOISY)) != DIR_NULL ) + ged_new_tables(gedp, dp, &cur_path, (fastf_t *)bn_mat_identity, flag); + else + bu_vls_printf(&gedp->ged_result_str, "%s: skip this object\n"); + } + + bu_vls_printf(&gedp->ged_result_str, "Summary written in: %s\n", argv[1]); + + if ( flag == SOL_TABLE || flag == REG_TABLE ) { + (void)unlink( "/tmp/mged_discr\0" ); + (void)fprintf(tabptr, "\n\nNumber Primitives = %d Number Regions = %d\n", + numsol, numreg); + + bu_vls_printf(&gedp->ged_result_str, "Processed %d Primitives and %d Regions\n", + numsol, numreg); + + (void)fclose( tabptr ); + } else { + (void)fprintf(tabptr, "* 9999999\n* 9999999\n* 9999999\n* 9999999\n* 9999999\n"); + (void)fclose( tabptr ); + + bu_vls_printf(&gedp->ged_result_str, "Processed %d Regions\n", numreg); + + /* make ordered idents */ + bu_vls_strcpy(&cmd, sortcmd); + bu_vls_strcat(&cmd, argv[1]); + bu_vls_printf(&gedp->ged_result_str, "%S\n", &cmd); + (void)system( bu_vls_addr(&cmd) ); + + bu_vls_trunc( &cmd, 0 ); + bu_vls_strcpy( &cmd, catcmd ); + bu_vls_strcat( &cmd, argv[1] ); + bu_vls_printf(&gedp->ged_result_str, "%S\n", &cmd); + (void)system( bu_vls_addr(&cmd) ); + + (void)unlink( "/tmp/ord_id\0" ); + } + + end: + bu_vls_free( &cmd ); + bu_vls_free(&tmp_vls); + bu_ptbl_free( &cur_path ); +#if 0 + (void)signal( SIGINT, SIG_IGN ); +#endif + return status; +} + +static int +ged_check(register char *a, register char *b) +{ + + register int c= sizeof( struct identt ); + + while ( c-- ) if ( *a++ != *b++ ) return( 0 ); /* no match */ + return( 1 ); /* match */ + +} + +static int +ged_sol_number(matp_t matrix, char *name, int *old) +{ + int i; + struct identt idbuf1, idbuf2; + int readval; + + memset(&idbuf1, 0, sizeof( struct identt )); + bu_strlcpy(idbuf1.i_name, name, sizeof(idbuf1.i_name)); + MAT_COPY(idbuf1.i_mat, matrix); + + for ( i=0; i<numsol; i++ ) { + (void)lseek(rd_idfd, i*(long)sizeof identt, 0); + readval = read(rd_idfd, &idbuf2, sizeof identt); + + if (readval < 0) { + perror("READ ERROR"); + } + + idbuf1.i_index = i + 1; + + if (ged_check( (char *)&idbuf1, (char *)&idbuf2 ) == 1) { + *old = 1; + return( idbuf2.i_index ); + } + } + numsol++; + idbuf1.i_index = numsol; + + (void)lseek(idfd, (off_t)0L, 2); + (void)write(idfd, &idbuf1, sizeof identt); + + *old = 0; + return( idbuf1.i_index ); +} + +static void +ged_new_tables(struct ged *gedp, struct directory *dp, struct bu_ptbl *cur_path, fastf_t *old_mat, int flag) +{ + struct rt_db_internal intern; + struct rt_comb_internal *comb; + struct rt_tree_array *tree_list; + int node_count; + int actual_count; + int i, k; + + RT_CK_DIR( dp ); + BU_CK_PTBL( cur_path ); + + if ( !(dp->d_flags & DIR_COMB) ) + return; + + if ( rt_db_get_internal( &intern, dp, gedp->ged_wdbp->dbip, (fastf_t *)NULL, &rt_uniresource ) < 0 ) { + bu_vls_printf(&gedp->ged_result_str, "Database read error, aborting\n"); + return; + } + + comb = (struct rt_comb_internal *)intern.idb_ptr; + RT_CK_COMB( comb ); + + if ( comb->tree && db_ck_v4gift_tree( comb->tree ) < 0 ) { + db_non_union_push( comb->tree, &rt_uniresource ); + if ( db_ck_v4gift_tree( comb->tree ) < 0 ) { + bu_vls_printf(&gedp->ged_result_str, "Cannot flatten tree for editing\n"); + rt_comb_ifree( &intern, &rt_uniresource ); + return; + } + } + + if (!comb->tree) { + /* empty combination */ + rt_comb_ifree( &intern, &rt_uniresource ); + return; + } + + node_count = db_tree_nleaves( comb->tree ); + tree_list = (struct rt_tree_array *)bu_calloc( node_count, + sizeof( struct rt_tree_array ), "tree list" ); + + /* flatten tree */ + actual_count = (struct rt_tree_array *)db_flatten_tree( tree_list, + comb->tree, OP_UNION, 0, &rt_uniresource ) - tree_list; + BU_ASSERT_LONG( actual_count, ==, node_count ); + + if ( dp->d_flags & DIR_REGION ) { + numreg++; + (void)fprintf( tabptr, " %-4d %4d %4d %4d %4d ", + numreg, comb->region_id, comb->aircode, comb->GIFTmater, + comb->los ); + for ( k=0; k<BU_PTBL_END( cur_path ); k++ ) { + struct directory *path_dp; + + path_dp = (struct directory *)BU_PTBL_GET( cur_path, k ); + RT_CK_DIR( path_dp ); + (void)fprintf( tabptr, "/%s", path_dp->d_namep ); + } + (void)fprintf( tabptr, "/%s:\n", dp->d_namep ); + + if ( flag == ID_TABLE ) + goto out; + + for ( i=0; i<actual_count; i++ ) { + char op; + int nsoltemp=0; + struct rt_db_internal sol_intern; + struct directory *sol_dp; + mat_t temp_mat; + struct bu_vls tmp_vls; + int old; + + switch ( tree_list[i].tl_op ) { + case OP_UNION: + op = 'u'; + break; + case OP_SUBTRACT: + op = '-'; + break; + case OP_INTERSECT: + op = '+'; + break; + default: + bu_log( "unrecognized operation in region %s\n", dp->d_namep ); + op = '?'; + break; + } + + if ( (sol_dp=db_lookup( gedp->ged_wdbp->dbip, tree_list[i].tl_tree->tr_l.tl_name, LOOKUP_QUIET )) != DIR_NULL ) { + if ( sol_dp->d_flags & DIR_COMB ) { + (void)fprintf(tabptr, " RG %c %s\n", + op, sol_dp->d_namep); + continue; + } else if ( !(sol_dp->d_flags & DIR_SOLID) ) { + (void)fprintf( tabptr, " ?? %c %s\n", + op, sol_dp->d_namep); + continue; + } else { + if ( tree_list[i].tl_tree->tr_l.tl_mat ) { + bn_mat_mul( temp_mat, old_mat, + tree_list[i].tl_tree->tr_l.tl_mat ); + } else { + MAT_COPY( temp_mat, old_mat ); + } + if ( rt_db_get_internal( &sol_intern, sol_dp, gedp->ged_wdbp->dbip, temp_mat, &rt_uniresource ) < 0 ) { + bu_log( "Could not import %s\n", tree_list[i].tl_tree->tr_l.tl_name ); + nsoltemp = 0; + } + nsoltemp = ged_sol_number( temp_mat, tree_list[i].tl_tree->tr_l.tl_name, &old ); + (void)fprintf(tabptr, " %c [%d] ", op, nsoltemp ); + } + } else { + nsoltemp = ged_sol_number( old_mat, tree_list[i].tl_tree->tr_l.tl_name, &old ); + (void)fprintf(tabptr, " %c [%d] ", op, nsoltemp ); + continue; + } + + if ( flag == REG_TABLE || old ) { + (void) fprintf( tabptr, "%s\n", tree_list[i].tl_tree->tr_l.tl_name ); + continue; + } else + (void) fprintf( tabptr, "%s: ", tree_list[i].tl_tree->tr_l.tl_name ); + + if ( !old && (sol_dp->d_flags & DIR_SOLID) ) { + /* if we get here, we must be looking for a solid table */ + bu_vls_init_if_uninit( &tmp_vls ); + if ( rt_functab[sol_intern.idb_type].ft_describe( &tmp_vls, &sol_intern, 1, gedp->ged_wdbp->dbip->dbi_base2local, &rt_uniresource, gedp->ged_wdbp->dbip ) < 0 ) { + bu_vls_printf(&gedp->ged_result_str, "%s describe error\n", tree_list[i].tl_tree->tr_l.tl_name); + } + fprintf( tabptr, "%s", bu_vls_addr(&tmp_vls)); + bu_vls_free( &tmp_vls ); + } + if ( nsoltemp && (sol_dp->d_flags & DIR_SOLID) ) + rt_db_free_internal( &sol_intern, &rt_uniresource ); + } + } else if ( dp->d_flags & DIR_COMB ) { + int cur_length; + + bu_ptbl_ins( cur_path, (long *)dp ); + cur_length = BU_PTBL_END( cur_path ); + + for ( i=0; i<actual_count; i++ ) { + struct directory *nextdp; + mat_t new_mat; + + nextdp = db_lookup( gedp->ged_wdbp->dbip, tree_list[i].tl_tree->tr_l.tl_name, LOOKUP_NOISY ); + if ( nextdp == DIR_NULL ) { + bu_vls_printf(&gedp->ged_result_str, "\tskipping this object\n"); + continue; + } + + /* recurse */ + if ( tree_list[i].tl_tree->tr_l.tl_mat ) { + bn_mat_mul( new_mat, old_mat, tree_list[i].tl_tree->tr_l.tl_mat ); + } else { + MAT_COPY( new_mat, old_mat ); + } + ged_new_tables(gedp, nextdp, cur_path, new_mat, flag); + bu_ptbl_trunc(cur_path, cur_length); + } + } else { + bu_vls_printf(&gedp->ged_result_str, "Illegal flags for %s skipping\n", dp->d_namep); + return; + } + + out: + bu_free( (char *)tree_list, "new_tables: tree_list" ); + rt_comb_ifree( &intern, &rt_uniresource ); + return; +} + + +/* + * Local Variables: + * tab-width: 8 + * mode: C + * indent-tabs-mode: t + * c-file-style: "stroustrup" + * End: + * ex: shiftwidth=4 tabstop=8 + */ Property changes on: brlcad/trunk/src/libged/tables.c ___________________________________________________________________ Added: svn:executable + * Added: svn:mime-type + text/plain Added: svn:eol-style + native This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |