Revision: 76402 http://sourceforge.net/p/brlcad/code/76402 Author: starseeker Date: 2020-07-22 01:27:01 +0000 (Wed, 22 Jul 2020) Log Message: ----------- Get as far as archer launching, although the tree and display are not working.
Modified Paths: -------------- brlcad/branches/gedplugins/src/libged/CMakeLists.txt brlcad/branches/gedplugins/src/libged/analyze/analyze.c brlcad/branches/gedplugins/src/libged/bot/CMakeLists.txt brlcad/branches/gedplugins/src/libged/bot/ged_bot.h brlcad/branches/gedplugins/src/libged/brep/CMakeLists.txt brlcad/branches/gedplugins/src/libged/check/CMakeLists.txt brlcad/branches/gedplugins/src/libged/comb/comb.c brlcad/branches/gedplugins/src/libged/draw/CMakeLists.txt brlcad/branches/gedplugins/src/libged/draw/draw.c brlcad/branches/gedplugins/src/libged/editit/editit.c brlcad/branches/gedplugins/src/libged/ged.c brlcad/branches/gedplugins/src/libged/ged_util.c brlcad/branches/gedplugins/src/libged/how/how.c brlcad/branches/gedplugins/src/libged/list/list.c brlcad/branches/gedplugins/src/libged/pnts_util.h brlcad/branches/gedplugins/src/libged/rt/rt.c brlcad/branches/gedplugins/src/libged/rtcheck/rtcheck.c brlcad/branches/gedplugins/src/libged/select/select.c brlcad/branches/gedplugins/src/libged/tops/tops.c brlcad/branches/gedplugins/src/libged/view/CMakeLists.txt brlcad/branches/gedplugins/src/libged/view/center.cpp Added Paths: ----------- brlcad/branches/gedplugins/src/libged/draw/loadview.c brlcad/branches/gedplugins/src/libged/draw/preview.c Removed Paths: ------------- brlcad/branches/gedplugins/src/libged/loadview/ brlcad/branches/gedplugins/src/libged/preview/ Modified: brlcad/branches/gedplugins/src/libged/CMakeLists.txt =================================================================== --- brlcad/branches/gedplugins/src/libged/CMakeLists.txt 2020-07-22 00:38:30 UTC (rev 76401) +++ brlcad/branches/gedplugins/src/libged/CMakeLists.txt 2020-07-22 01:27:01 UTC (rev 76402) @@ -64,6 +64,7 @@ get_solid_kp.c inside.c path.c + pnts_util.c polyclip.cpp qray.c rotate_about.c @@ -270,7 +271,6 @@ png/png.c png2fb/png2fb.c pnts/pnts.cpp - pnts_util.c prcolor/prcolor.c prefix/prefix.c preview/preview.c @@ -562,7 +562,6 @@ add_subdirectory(lc) add_subdirectory(lint) add_subdirectory(list) -add_subdirectory(loadview) add_subdirectory(lod) add_subdirectory(log) add_subdirectory(lookat) @@ -603,7 +602,6 @@ add_subdirectory(pnts) add_subdirectory(prcolor) add_subdirectory(prefix) -add_subdirectory(preview) add_subdirectory(process) add_subdirectory(protate) add_subdirectory(ps) Modified: brlcad/branches/gedplugins/src/libged/analyze/analyze.c =================================================================== --- brlcad/branches/gedplugins/src/libged/analyze/analyze.c 2020-07-22 00:38:30 UTC (rev 76401) +++ brlcad/branches/gedplugins/src/libged/analyze/analyze.c 2020-07-22 01:27:01 UTC (rev 76402) @@ -29,8 +29,6 @@ #include <string.h> #include <assert.h> - - #include "vmath.h" #include "bn.h" #include "bg/polygon.h" Modified: brlcad/branches/gedplugins/src/libged/bot/CMakeLists.txt =================================================================== --- brlcad/branches/gedplugins/src/libged/bot/CMakeLists.txt 2020-07-22 00:38:30 UTC (rev 76401) +++ brlcad/branches/gedplugins/src/libged/bot/CMakeLists.txt 2020-07-22 01:27:01 UTC (rev 76402) @@ -6,11 +6,30 @@ ${GED_INCLUDE_DIRS} ) +set(BOT_SRCS + bot_condense.c + bot.cpp + bot_decimate.c + bot_dump.c + bot_face_fuse.c + bot_face_sort.c + bot_flip.c + bot_fuse.c + bot_merge.c + bot_smooth.c + bot_split.c + bot_sync.c + bot_vertex_fuse.c + check.cpp + extrude.cpp + remesh.cpp + ) + add_definitions(-DGED_PLUGIN) -add_library(ged-bot SHARED bot.cpp) +add_library(ged-bot SHARED ${BOT_SRCS}) target_link_libraries(ged-bot libged libbu) set_property(TARGET ged-bot APPEND PROPERTY COMPILE_DEFINITIONS BRLCADBUILD HAVE_CONFIG_H) -VALIDATE_STYLE(ged-bot bot.cpp) +VALIDATE_STYLE(ged-bot ${BOT_SRCS}) PLUGIN_SETUP(ged-bot ged) # Local Variables: @@ -19,3 +38,4 @@ # indent-tabs-mode: t # End: # ex: shiftwidth=2 tabstop=8 + Modified: brlcad/branches/gedplugins/src/libged/bot/ged_bot.h =================================================================== --- brlcad/branches/gedplugins/src/libged/bot/ged_bot.h 2020-07-22 00:38:30 UTC (rev 76401) +++ brlcad/branches/gedplugins/src/libged/bot/ged_bot.h 2020-07-22 01:27:01 UTC (rev 76402) @@ -68,11 +68,11 @@ int _bot_cmd_msgs(void *bs, int argc, const char **argv, const char *us, const char *ps); -GED_EXPORT int _bot_cmd_extrude(void *bs, int argc, const char **argv); +GED_EXPORT extern int _bot_cmd_extrude(void *bs, int argc, const char **argv); -GED_EXPORT int _bot_cmd_check(void *bs, int argc, const char **argv); +GED_EXPORT extern int _bot_cmd_check(void *bs, int argc, const char **argv); -GED_EXPORT int _bot_cmd_remesh(void *bs, int argc, const char **argv); +GED_EXPORT extern int _bot_cmd_remesh(void *bs, int argc, const char **argv); __END_DECLS Modified: brlcad/branches/gedplugins/src/libged/brep/CMakeLists.txt =================================================================== --- brlcad/branches/gedplugins/src/libged/brep/CMakeLists.txt 2020-07-22 00:38:30 UTC (rev 76401) +++ brlcad/branches/gedplugins/src/libged/brep/CMakeLists.txt 2020-07-22 01:27:01 UTC (rev 76402) @@ -6,11 +6,23 @@ ${GED_INCLUDE_DIRS} ) +set(BREP_SRCS + brep.cpp + conversion.cpp + csg.cpp + info.cpp + intersect.cpp + pick.cpp + plot.cpp + tikz.cpp + valid.cpp + ) + add_definitions(-DGED_PLUGIN) -add_library(ged-brep SHARED brep.cpp) +add_library(ged-brep SHARED ${BREP_SRCS}) target_link_libraries(ged-brep libged libbu) set_property(TARGET ged-brep APPEND PROPERTY COMPILE_DEFINITIONS BRLCADBUILD HAVE_CONFIG_H) -VALIDATE_STYLE(ged-brep brep.cpp) +VALIDATE_STYLE(ged-brep ${BREP_SRCS}) PLUGIN_SETUP(ged-brep ged) # Local Variables: @@ -19,3 +31,4 @@ # indent-tabs-mode: t # End: # ex: shiftwidth=2 tabstop=8 + Modified: brlcad/branches/gedplugins/src/libged/check/CMakeLists.txt =================================================================== --- brlcad/branches/gedplugins/src/libged/check/CMakeLists.txt 2020-07-22 00:38:30 UTC (rev 76401) +++ brlcad/branches/gedplugins/src/libged/check/CMakeLists.txt 2020-07-22 01:27:01 UTC (rev 76402) @@ -6,11 +6,25 @@ ${GED_INCLUDE_DIRS} ) +set(CHECK_SRCS + check_adj_air.c + check.c + check_centroid.c + check_exp_air.c + check_gap.c + check_mass.c + check_moments.c + check_overlaps.c + check_surf_area.c + check_unconf_air.c + check_volume.c + ) + add_definitions(-DGED_PLUGIN) -add_library(ged-check SHARED check.c) +add_library(ged-check SHARED ${CHECK_SRCS}) target_link_libraries(ged-check libged libbu) set_property(TARGET ged-check APPEND PROPERTY COMPILE_DEFINITIONS BRLCADBUILD HAVE_CONFIG_H) -VALIDATE_STYLE(ged-check check.c) +VALIDATE_STYLE(ged-check ${CHECK_SRCS}) PLUGIN_SETUP(ged-check ged) # Local Variables: @@ -19,3 +33,4 @@ # indent-tabs-mode: t # End: # ex: shiftwidth=2 tabstop=8 + Modified: brlcad/branches/gedplugins/src/libged/comb/comb.c =================================================================== --- brlcad/branches/gedplugins/src/libged/comb/comb.c 2020-07-22 00:38:30 UTC (rev 76401) +++ brlcad/branches/gedplugins/src/libged/comb/comb.c 2020-07-22 01:27:01 UTC (rev 76402) @@ -772,204 +772,7 @@ } -/* - * Add an instance of object 'objp' to combination 'name'. - * If the combination does not exist, it is created. - * region_flag is 1 (region), or 0 (group). - * - * Preserves the GIFT semantics. - */ -struct directory * -_ged_combadd(struct ged *gedp, - struct directory *objp, - char *combname, - int region_flag, /* true if adding region */ - db_op_t relation, /* = UNION, SUBTRACT, INTERSECT */ - int ident, /* "Region ID" */ - int air /* Air code */) -{ - int ac = 1; - const char *av[2]; - av[0] = objp->d_namep; - av[1] = NULL; - - if (_ged_combadd2(gedp, combname, ac, av, region_flag, relation, ident, air, NULL, 1) == GED_ERROR) - return RT_DIR_NULL; - - /* Done changing stuff - update nref. */ - db_update_nref(gedp->ged_wdbp->dbip, &rt_uniresource); - - return db_lookup(gedp->ged_wdbp->dbip, combname, LOOKUP_QUIET); -} - - -/* - * Add an instance of object 'objp' to combination 'name'. - * If the combination does not exist, it is created. - * region_flag is 1 (region), or 0 (group). - * - * Preserves the GIFT semantics. - */ -int -_ged_combadd2(struct ged *gedp, - char *combname, - int argc, - const char *argv[], - int region_flag, /* true if adding region */ - db_op_t relation, /* = UNION, SUBTRACT, INTERSECT */ - int ident, /* "Region ID" */ - int air, /* Air code */ - matp_t m, /* Matrix */ - int validate /* 1 to check if new members exist, 0 to just add them */) -{ - struct directory *dp; - struct directory *objp; - struct rt_db_internal intern; - struct rt_comb_internal *comb; - union tree *tp; - struct rt_tree_array *tree_list; - size_t node_count; - size_t actual_count; - size_t curr_count; - int i; - - if (argc < 1) - return GED_ERROR; - - /* - * Check to see if we have to create a new combination - */ - if ((dp = db_lookup(gedp->ged_wdbp->dbip, combname, LOOKUP_QUIET)) == RT_DIR_NULL) { - int flags; - - if (region_flag) - flags = RT_DIR_REGION | RT_DIR_COMB; - else - flags = RT_DIR_COMB; - - RT_DB_INTERNAL_INIT(&intern); - intern.idb_major_type = DB5_MAJORTYPE_BRLCAD; - intern.idb_type = ID_COMBINATION; - intern.idb_meth = &OBJ[ID_COMBINATION]; - - GED_DB_DIRADD(gedp, dp, combname, -1, 0, flags, (void *)&intern.idb_type, 0); - - BU_ALLOC(comb, struct rt_comb_internal); - RT_COMB_INTERNAL_INIT(comb); - - intern.idb_ptr = (void *)comb; - - if (region_flag) { - comb->region_flag = 1; - comb->region_id = ident; - comb->aircode = air; - comb->los = gedp->ged_wdbp->wdb_los_default; - comb->GIFTmater = gedp->ged_wdbp->wdb_mat_default; - bu_vls_printf(gedp->ged_result_str, "Creating region with attrs: region_id=%d, ", ident); - if (air) - bu_vls_printf(gedp->ged_result_str, "air=%d, ", air); - bu_vls_printf(gedp->ged_result_str, "los=%d, material_id=%d\n", - gedp->ged_wdbp->wdb_los_default, - gedp->ged_wdbp->wdb_mat_default); - } else { - comb->region_flag = 0; - } - - goto addmembers; - } else if (!(dp->d_flags & RT_DIR_COMB)) { - bu_vls_printf(gedp->ged_result_str, "%s exists, but is not a combination\n", dp->d_namep); - return GED_ERROR; - } - - /* combination exists, add a new member */ - GED_DB_GET_INTERNAL(gedp, &intern, dp, (fastf_t *)NULL, &rt_uniresource, 0); - - comb = (struct rt_comb_internal *)intern.idb_ptr; - RT_CK_COMB(comb); - - if (region_flag && !comb->region_flag) { - bu_vls_printf(gedp->ged_result_str, "%s: not a region\n", dp->d_namep); - return GED_ERROR; - } - -addmembers: - 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_db_free_internal(&intern); - return GED_ERROR; - } - } - - /* make space for an extra leaf */ - curr_count = db_tree_nleaves(comb->tree); - node_count = curr_count + argc; - tree_list = (struct rt_tree_array *)bu_calloc(node_count, sizeof(struct rt_tree_array), "tree list"); - - /* flatten tree */ - if (comb->tree) { - actual_count = argc + (struct rt_tree_array *)db_flatten_tree(tree_list, comb->tree, OP_UNION, 1, &rt_uniresource) - tree_list; - BU_ASSERT(actual_count == node_count); - comb->tree = TREE_NULL; - } - - for (i = 0; i < argc; ++i) { - if (validate) { - if ((objp = db_lookup(gedp->ged_wdbp->dbip, argv[i], LOOKUP_NOISY)) == RT_DIR_NULL) { - bu_vls_printf(gedp->ged_result_str, "skip member %s\n", argv[i]); - continue; - } - } - - /* insert new member at end */ - switch (relation) { - case DB_OP_INTERSECT: - tree_list[curr_count].tl_op = OP_INTERSECT; - break; - case DB_OP_SUBTRACT: - tree_list[curr_count].tl_op = OP_SUBTRACT; - break; - default: - if (relation != DB_OP_UNION) { - bu_vls_printf(gedp->ged_result_str, "unrecognized relation (assume UNION)\n"); - } - tree_list[curr_count].tl_op = OP_UNION; - break; - } - - /* make new leaf node, and insert at end of list */ - BU_GET(tp, union tree); - RT_TREE_INIT(tp); - tree_list[curr_count].tl_tree = tp; - tp->tr_l.tl_op = OP_DB_LEAF; - tp->tr_l.tl_name = bu_strdup(argv[i]); - if (m) { - tp->tr_l.tl_mat = (matp_t)bu_malloc(sizeof(mat_t), "mat copy"); - MAT_COPY(tp->tr_l.tl_mat, m); - } else { - tp->tr_l.tl_mat = (matp_t)NULL; - } - - ++curr_count; - } - - /* rebuild the tree */ - comb->tree = (union tree *)db_mkgift_tree(tree_list, node_count, &rt_uniresource); - - /* and finally, write it out */ - GED_DB_PUT_INTERNAL(gedp, dp, &intern, &rt_uniresource, 0); - - bu_free((char *)tree_list, "combadd: tree_list"); - - /* Done changing stuff - update nref. */ - db_update_nref(gedp->ged_wdbp->dbip, &rt_uniresource); - - return GED_OK; -} - - #ifdef GED_PLUGIN #include "../include/plugin.h" struct ged_cmd_impl comb_cmd_impl = { Modified: brlcad/branches/gedplugins/src/libged/draw/CMakeLists.txt =================================================================== --- brlcad/branches/gedplugins/src/libged/draw/CMakeLists.txt 2020-07-22 00:38:30 UTC (rev 76401) +++ brlcad/branches/gedplugins/src/libged/draw/CMakeLists.txt 2020-07-22 01:27:01 UTC (rev 76402) @@ -6,11 +6,17 @@ ${GED_INCLUDE_DIRS} ) +set(DRAW_SRCS + draw.c + loadview.c + preview.c + ) + add_definitions(-DGED_PLUGIN) -add_library(ged-draw SHARED draw.c) +add_library(ged-draw SHARED ${DRAW_SRCS}) target_link_libraries(ged-draw libged libbu) set_property(TARGET ged-draw APPEND PROPERTY COMPILE_DEFINITIONS BRLCADBUILD HAVE_CONFIG_H) -VALIDATE_STYLE(ged-draw draw.c) +VALIDATE_STYLE(ged-draw ${DRAW_SRCS}) PLUGIN_SETUP(ged-draw ged) # Local Variables: Modified: brlcad/branches/gedplugins/src/libged/draw/draw.c =================================================================== --- brlcad/branches/gedplugins/src/libged/draw/draw.c 2020-07-22 00:38:30 UTC (rev 76401) +++ brlcad/branches/gedplugins/src/libged/draw/draw.c 2020-07-22 01:27:01 UTC (rev 76402) @@ -159,28 +159,6 @@ return curtree; } -/** - * Once the vlist has been created, perform the common tasks - * in handling the drawn solid. - * - * This routine must be prepared to run in parallel. - */ -void -_ged_drawH_part2(int dashflag, struct bu_list *vhead, const struct db_full_path *pathp, struct db_tree_state *tsp, struct _ged_client_data *dgcdp) -{ - - if (dgcdp->wireframe_color_override) { - unsigned char wcolor[3]; - - wcolor[0] = (unsigned char)dgcdp->wireframe_color[0]; - wcolor[1] = (unsigned char)dgcdp->wireframe_color[1]; - wcolor[2] = (unsigned char)dgcdp->wireframe_color[2]; - dl_add_path(dgcdp->gdlp, dashflag, dgcdp->transparency, dgcdp->dmode, dgcdp->hiddenLine, vhead, pathp, tsp, wcolor, dgcdp->gedp->ged_create_vlist_solid_callback, dgcdp->freesolid); - } else { - dl_add_path(dgcdp->gdlp, dashflag, dgcdp->transparency, dgcdp->dmode, dgcdp->hiddenLine, vhead, pathp, tsp, NULL, dgcdp->gedp->ged_create_vlist_solid_callback, dgcdp->freesolid); - } -} - static int get_path_and_state( struct db_tree_state *tsp, @@ -563,25 +541,6 @@ return curtree; } - -void -_ged_cvt_vlblock_to_solids(struct ged *gedp, struct bn_vlblock *vbp, const char *name, int copy) -{ - size_t i; - char shortname[32] = {0}; - char namebuf[64] = {0}; - - bu_strlcpy(shortname, name, sizeof(shortname)); - - for (i = 0; i < vbp->nused; i++) { - if (BU_LIST_IS_EMPTY(&(vbp->head[i]))) - continue; - snprintf(namebuf, 64, "%s%lx", shortname, vbp->rgb[i]); - invent_solid(gedp->ged_gdp->gd_headDisplay, gedp->ged_wdbp->dbip, gedp->ged_create_vlist_solid_callback, gedp->ged_free_vlist_callback, namebuf, &vbp->head[i], vbp->rgb[i], copy, 1.0, 0, gedp->freesolid, 0); - } -} - - /* * This routine is the drawable geometry object's analog of rt_gettrees(). * Add a set of tree hierarchies to the active set. @@ -1356,10 +1315,29 @@ }; const struct ged_cmd draw_cmd = { &draw_cmd_impl }; -const struct ged_cmd *draw_cmds[] = { &draw_cmd, NULL }; -static const struct ged_plugin pinfo = { draw_cmds, 1 }; +extern int ged_loadview_core(struct ged *gedp, int argc, const char *argv[]); +struct ged_cmd_impl loadview_cmd_impl = { + "loadview", + ged_loadview_core, + GED_CMD_DEFAULT +}; +const struct ged_cmd loadview_cmd = { &loadview_cmd_impl }; + +extern int ged_preview_core(struct ged *gedp, int argc, const char *argv[]); + +struct ged_cmd_impl preview_cmd_impl = { + "preview", + ged_preview_core, + GED_CMD_DEFAULT +}; +const struct ged_cmd preview_cmd = { &preview_cmd_impl }; + +const struct ged_cmd *draw_cmds[] = { &draw_cmd, &loadview_cmd, &preview_cmd, NULL }; + +static const struct ged_plugin pinfo = { draw_cmds, 3 }; + COMPILER_DLLEXPORT const struct ged_plugin *ged_plugin_info() { return &pinfo; Copied: brlcad/branches/gedplugins/src/libged/draw/loadview.c (from rev 76401, brlcad/branches/gedplugins/src/libged/loadview/loadview.c) =================================================================== --- brlcad/branches/gedplugins/src/libged/draw/loadview.c (rev 0) +++ brlcad/branches/gedplugins/src/libged/draw/loadview.c 2020-07-22 01:27:01 UTC (rev 76402) @@ -0,0 +1,414 @@ +/* L O A D V I E W . C + * BRL-CAD + * + * Copyright (c) 2008-2020 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 libged/loadview.c + * + * The loadview command. + * + */ + +#include "common.h" + +#include <stdlib.h> +#include <ctype.h> +#include <string.h> + +#include "../ged_private.h" + +/** + * 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", "quaternion", "set view direction from quaternion", + _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_end, 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_core(struct ged *gedp, int argc, const char *argv[]) +{ + int ret; + int failed = 0; + FILE *fp; + char buffer[512] = {0}; + + /* data pulled from script file */ + int perspective=-1; +#define MAX_DBNAME 2048 + char name[MAX_DBNAME] = {0}; + char *dbName = name; + char objects[10000] = {0}; + char *editArgv[3]; + static const char *usage = "filename"; + + GED_CHECK_DATABASE_OPEN(gedp, GED_ERROR); + GED_CHECK_VIEW(gedp, GED_ERROR); + GED_CHECK_ARGC_GT_0(gedp, argc, GED_ERROR); + + /* initialize result */ + bu_vls_trunc(gedp->ged_result_str, 0); + + /* must be wanting help */ + if (argc == 1) { + bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); + return GED_HELP; + } + + /* make sure the file exists */ + if (!bu_file_exists(argv[1], NULL)) { + bu_log("Error: File %s does not exist\n", argv[1]); + return GED_ERROR; + } + + /* open the file for reading */ + if ((fp = fopen(argv[1], "r")) == NULL) { + perror(argv[1]); + return GED_ERROR; + } + + _ged_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 */ + /* TODO: change to bu_fgets or bu_vls_fgets */ + while (!feof(fp)) { + memset(buffer, 0, 512); + ret = fscanf(fp, "%512s", buffer); + if (ret != 1) { + bu_log("Failed to read buffer\n"); + failed++; + } + + if (bu_strncmp(buffer, "-p", 2) == 0) { + char perspective_angle[128] = {0}; + const char *perspective_argv[2] = {"perspective", NULL}; + perspective_argv[1] = perspective_angle; + + /* we found perspective */ + + buffer[0] = ' '; + buffer[1] = ' '; + sscanf(buffer, "%d", &perspective); + /* bu_log("perspective=%d\n", perspective);*/ + snprintf(perspective_angle, sizeof(perspective_angle), "%d", perspective); + + ged_perspective(gedp, 2, (const char **)perspective_argv); + + } else if (bu_strncmp(buffer, "$*", 2) == 0) { + /* the next read is the file name, the objects come + * after that + */ + + memset(dbName, 0, MAX_DBNAME); + ret = fscanf(fp, "%2048s", dbName); /* MAX_DBNAME */ + if (ret != 1) { + bu_log("Failed to read database name\n"); + failed++; + } + + /* 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 the name was wrapped in quotes, remove them */ + if (dbName[0] == '\'' && *(dbName + strlen(dbName) - 1) == '\'') { + dbName++; + memset(dbName + strlen(dbName)-1, 0, 1); + } + + if (!bu_file_same(gedp->ged_wdbp->dbip->dbi_filename, dbName)) { + /* warn here if they are not the same file, otherwise, + * proceed as expected, and try to load the objects. + */ + bu_log("WARNING: view script seems to reference a different database\n([%s] != [%s])\n", dbName, gedp->ged_wdbp->dbip->dbi_filename); + } + + /* get rid of anything that may be displayed, since we + * will load objects that are listed in the script next. + * + * TODO: should only zap if the objects to be displayed + * all exist. + */ + (void)ged_zap(gedp, 1, NULL); + + /* now get the objects listed */ + ret = fscanf(fp, "%10000s", objects); + if (ret != 1) { + bu_log("Failed to read object names\n"); + failed++; + } + + /* bu_log("OBJECTS=%s\n", objects);*/ + while ((!feof(fp)) && (bu_strncmp(objects, "\\", 1) != 0)) { + + /* clean off the single quotes... */ + if (bu_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, (const char **)editArgv) != GED_OK) { + bu_vls_printf(gedp->ged_result_str, "Unable to load object: %s\n", objects); + } + + /* bu_log("objects=%s\n", objects);*/ + ret = fscanf(fp, "%10000s", objects); + if (ret != 1) { + bu_log("Failed to read object names\n"); + failed++; + } + } + + /* end iteration over reading in listed objects */ + } else if (bu_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); + failed++; + } + bu_free((void *)cmdBuffer, "loadview cmdBuffer"); + } + /* end iteration over rt commands */ + + } + /* end check for non-view values (dbname, etc.) */ + + } + /* end iteration over file until eof */ + fclose(fp); + + if (failed) + return GED_ERROR; + + return GED_OK; +} + + +int +_ged_cm_vsize(const int argc, const char **argv) +{ + if (argc < 2) + return -1; + /* for some reason, scale is supposed to be half of size... */ + _ged_current_gedp->ged_gvp->gv_size = atof(argv[1]); + _ged_current_gedp->ged_gvp->gv_scale = _ged_current_gedp->ged_gvp->gv_size * 0.5; + _ged_current_gedp->ged_gvp->gv_isize = 1.0 / _ged_current_gedp->ged_gvp->gv_size; + return 0; +} + + +int +_ged_cm_eyept(const int argc, const 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 view 'end' */ + return 0; +} + + +int +_ged_cm_lookat_pt(const int argc, const 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); + + /* + * At the moment bn_mat_lookat() will return NAN's if the + * direction vector is aligned with the Z axis. The following is a + * workaround. + */ + { + vect_t neg_Z_axis = VINIT_ZERO; + neg_Z_axis[Z] = -1.0; + bn_mat_fromto(_ged_viewrot, dir, neg_Z_axis, &_ged_current_gedp->ged_wdbp->wdb_tol); + } + + /* Final processing is deferred until view 'end', but eye_pt + * must have been specified before here (for now) + */ + return 0; +} + + +int +_ged_cm_vrot(const int argc, const char **argv) +{ + int i; + + if (argc < 17) + return -1; + for (i = 0; i < 16; i++) + _ged_viewrot[i] = atof(argv[i+1]); + /* Processing is deferred until view 'end' */ + return 0; +} + + +int +_ged_cm_orientation(const int argc, const char **argv) +{ + int i; + quat_t quat; + + if (argc < 4) + return -1; + + for (i = 0; i < 4; i++) + quat[i] = atof(argv[i+1]); + quat_quat2mat(_ged_viewrot, quat); + + return 0; +} + + +int +_ged_cm_set(const int UNUSED(argc), const char **UNUSED(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(const int argc, const char **argv) +{ + if (argc < 0 || argv == NULL) + return 1; + + return 0; +} + + +/** + * process the 'end' of a view. currently, requires an eye point be + * specified beforehand. + */ +int +_ged_cm_end(const int argc, const char **argv) +{ + struct bu_vls eye = BU_VLS_INIT_ZERO; + char *eye_argv[5] = {"eye", NULL, NULL, NULL, NULL}; + + if (argc < 0 || argv == NULL) + return 1; + + /* now we have to finish view calculations that are deferred until + * the end command runs. + */ + MAT_COPY(_ged_current_gedp->ged_gvp->gv_rotation, _ged_viewrot); + MAT_DELTAS_VEC_NEG(_ged_current_gedp->ged_gvp->gv_center, _ged_eye_model); + bview_update(_ged_current_gedp->ged_gvp); + + bu_vls_printf(&eye, "%lf %lf %lf", V3ARGS(_ged_eye_model)); + bu_argv_from_string(eye_argv+1, 4, bu_vls_addr(&eye)); + ged_eye(_ged_current_gedp, 4, (const char **)eye_argv); + bu_vls_free(&eye); + + return 0; +} + +/* + * Local Variables: + * mode: C + * tab-width: 8 + * indent-tabs-mode: t + * c-file-style: "stroustrup" + * End: + * ex: shiftwidth=4 tabstop=8 + */ Copied: brlcad/branches/gedplugins/src/libged/draw/preview.c (from rev 76401, brlcad/branches/gedplugins/src/libged/preview/preview.c) =================================================================== --- brlcad/branches/gedplugins/src/libged/draw/preview.c (rev 0) +++ brlcad/branches/gedplugins/src/libged/draw/preview.c 2020-07-22 01:27:01 UTC (rev 76402) @@ -0,0 +1,451 @@ +/* P R E V I E W . C + * BRL-CAD + * + * Copyright (c) 2008-2020 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 libged/preview.c + * + * The preview command. + * + */ + +#include "common.h" + +#include <stdlib.h> +#include <ctype.h> +#include <string.h> +#include <time.h> +#include "bsocket.h" + +#include "bu/cmd.h" +#include "bu/getopt.h" + +#include "../ged_private.h" + +static struct bn_vlblock *preview_vbp; +static double preview_delay; +static int preview_mode; +static int preview_desiredframe; +static int preview_finalframe; +static int preview_currentframe; +static int preview_tree_walk_needed; +static int draw_eye_path; +static char *image_name = NULL; + + +/* FIXME: this shouldn't exist as a static array and doesn't even seem + * to be necessary. gd_rt_cmd points into it as an argv, but the + * elements can probably be dup'd strings and released by the caller. + */ +#define MAXARGS 9000 +static char rt_cmd_storage[MAXARGS*9]; + + +int +ged_cm_anim(const int argc, const char **argv) +{ + + if (_ged_current_gedp->ged_wdbp->dbip == DBI_NULL) + return 0; + + if (db_parse_anim(_ged_current_gedp->ged_wdbp->dbip, argc, (const char **)argv) < 0) { + bu_vls_printf(_ged_current_gedp->ged_result_str, "cm_anim: %s %s failed\n", argv[1], argv[2]); + return -1; /* BAD */ + } + + preview_tree_walk_needed = 1; + + return 0; +} + + +int +ged_cm_clean(const int UNUSED(argc), const char **UNUSED(argv)) +{ + if (_ged_current_gedp->ged_wdbp->dbip == DBI_NULL) + return 0; + + /*f_zap(NULL, interp, 0, (char **)0);*/ + + /* Free animation structures */ + db_free_anim(_ged_current_gedp->ged_wdbp->dbip); + + preview_tree_walk_needed = 0; + return 0; +} + + +int +ged_cm_end(const int UNUSED(argc), const char **UNUSED(argv)) +{ + vect_t xlate; + vect_t new_cent; + vect_t xv, yv; /* view x, y */ + vect_t xm, ym; /* model x, y */ + struct bu_list *vhead = &preview_vbp->head[0]; + + /* Only display the frames the user is interested in */ + if (preview_currentframe < preview_desiredframe) return 0; + if (preview_finalframe && preview_currentframe > preview_finalframe) return 0; + + /* Record eye path as a polyline. Move, then draws */ + if (BU_LIST_IS_EMPTY(vhead)) { + RT_ADD_VLIST(vhead, _ged_eye_model, BN_VLIST_LINE_MOVE); + } else { + RT_ADD_VLIST(vhead, _ged_eye_model, BN_VLIST_LINE_DRAW); + } + + /* First step: put eye at view center (view 0, 0, 0) */ + MAT_COPY(_ged_current_gedp->ged_gvp->gv_rotation, _ged_viewrot); + MAT_DELTAS_VEC_NEG(_ged_current_gedp->ged_gvp->gv_center, _ged_eye_model); + bview_update(_ged_current_gedp->ged_gvp); + + /* + * Compute camera orientation notch to right (+X) and up (+Y) + * Done here, with eye in center of view. + */ + VSET(xv, 0.05, 0.0, 0.0); + VSET(yv, 0.0, 0.05, 0.0); + MAT4X3PNT(xm, _ged_current_gedp->ged_gvp->gv_view2model, xv); + MAT4X3PNT(ym, _ged_current_gedp->ged_gvp->gv_view2model, yv); + RT_ADD_VLIST(vhead, xm, BN_VLIST_LINE_DRAW); + RT_ADD_VLIST(vhead, _ged_eye_model, BN_VLIST_LINE_MOVE); + RT_ADD_VLIST(vhead, ym, BN_VLIST_LINE_DRAW); + RT_ADD_VLIST(vhead, _ged_eye_model, BN_VLIST_LINE_MOVE); + + /* Second step: put eye at view 0, 0, 1. + * For eye to be at 0, 0, 1, the old 0, 0, -1 needs to become 0, 0, 0. + */ + VSET(xlate, 0.0, 0.0, -1.0); /* correction factor */ + MAT4X3PNT(new_cent, _ged_current_gedp->ged_gvp->gv_view2model, xlate); + MAT_DELTAS_VEC_NEG(_ged_current_gedp->ged_gvp->gv_center, new_cent); + bview_update(_ged_current_gedp->ged_gvp); + + /* If new treewalk is needed, get new objects into view. */ + if (preview_tree_walk_needed) { + const char *av[2]; + + av[0] = "zap"; + av[1] = NULL; + + (void)ged_zap(_ged_current_gedp, 1, av); + _ged_drawtrees(_ged_current_gedp, _ged_current_gedp->ged_gdp->gd_rt_cmd_len, (const char **)&_ged_current_gedp->ged_gdp->gd_rt_cmd[1], preview_mode, (struct _ged_client_data *)0); + } + + if (_ged_current_gedp->ged_refresh_handler != GED_REFRESH_CALLBACK_PTR_NULL) + (*_ged_current_gedp->ged_refresh_handler)(_ged_current_gedp->ged_refresh_clientdata); + + if (preview_delay > 0) { + struct timeval tv; + fd_set readfds; + + FD_ZERO(&readfds); + FD_SET(fileno(stdin), &readfds); + tv.tv_sec = (long)preview_delay; + tv.tv_usec = (long)((preview_delay - tv.tv_sec) * 1000000); + select(fileno(stdin)+1, &readfds, (fd_set *)0, (fd_set *)0, &tv); + } + + return 0; +} + + +int +ged_cm_multiview(const int UNUSED(argc), const char **UNUSED(argv)) +{ + return -1; +} + + +int +ged_cm_start(const int argc, const char **argv) +{ + if (argc < 2) + return -1; + preview_currentframe = atoi(argv[1]); + preview_tree_walk_needed = 0; + + return 0; +} + + +int +ged_cm_tree(const int argc, const char **argv) +{ + int i = 1; + char *cp = rt_cmd_storage; + + for (i = 1; i < argc && i < MAXARGS; i++) { + bu_strlcpy(cp, argv[i], MAXARGS*9); + _ged_current_gedp->ged_gdp->gd_rt_cmd[i] = cp; + cp += strlen(cp) + 1; + } + _ged_current_gedp->ged_gdp->gd_rt_cmd[i] = (char *)0; + _ged_current_gedp->ged_gdp->gd_rt_cmd_len = i-1; + + preview_tree_walk_needed = 1; + + return 0; +} + + +struct command_tab ged_preview_cmdtab[] = { + {"start", "frame number", "start a new frame", + ged_cm_start, 2, 2}, + {"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}, + {"orientation", "quaternion", "set view direction from quaternion", + _ged_cm_orientation, 5, 5}, + {"viewrot", "4x4 matrix", "set view direction from matrix", + _ged_cm_vrot, 17, 17}, + {"end", "", "end of frame setup, begin raytrace", + ged_cm_end, 1, 1}, + {"multiview", "", "produce stock set of views", + ged_cm_multiview, 1, 1}, + {"anim", "path type args", "specify articulation animation", + ged_cm_anim, 4, 999}, + {"tree", "treetop(s)", "specify alternate list of tree tops", + ged_cm_tree, 1, 999}, + {"clean", "", "clean articulation from previous frame", + ged_cm_clean, 1, 1}, + {"set", "", "show or set parameters", + _ged_cm_set, 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}, + {(char *)0, (char *)0, (char *)0, + 0, 0, 0} /* END */ +}; + + +int +ged_loadframe(struct ged *gedp, FILE *fp) +{ + char *cmd; + + int end = 0; + while (!end && ((cmd = rt_read_cmd(fp)) != NULL)) { + /* Hack to prevent running framedone scripts prematurely */ + if (cmd[0] == '!') { + if (preview_currentframe < preview_desiredframe || + (preview_finalframe && preview_currentframe > preview_finalframe)) { + bu_free((void *)cmd, "preview ! cmd"); + continue; + } + } + + if (cmd[0] == 'e' && bu_strncmp(cmd, "end", 3) == 0) { + end = 1; + } + + if (rt_do_cmd((struct rt_i *)0, cmd, ged_preview_cmdtab) < 0) + bu_vls_printf(gedp->ged_result_str, "command failed: %s\n", cmd); + bu_free((void *)cmd, "preview cmd"); + } + + if (end) { + return GED_OK; /* possible more frames */ + } + return GED_ERROR; /* end of frames */ +} + + +/** + * Preview a new style RT animation script. + * Note that the RT command parser code is used, rather than the + * MGED command parser, because of the differences in format. + * The RT parser expects command handlers of the form "ged_cm_xxx()", + * and all communications are done via global variables. + * + * For the moment, the only preview mode is the normal one, + * moving the eyepoint as directed. + * However, as a bonus, the eye path is left behind as a vector plot. + */ +int +ged_preview_core(struct ged *gedp, int argc, const char *argv[]) +{ + static const char *usage = "[-v] [-e] [-o image_name.ext] [-d sec_delay] [-D start frame] [-K last frame] rt_script_file"; + + FILE *fp; + int c; + vect_t temp; + char **vp; + size_t args = 0; + struct bu_vls extension = BU_VLS_INIT_ZERO; + struct bu_vls name = BU_VLS_INIT_ZERO; + char *dot; + + GED_CHECK_DATABASE_OPEN(gedp, GED_ERROR); + GED_CHECK_DRAWABLE(gedp, GED_ERROR); + GED_CHECK_VIEW(gedp, GED_ERROR); + + /* initialize result */ + bu_vls_trunc(gedp->ged_result_str, 0); + + /* must be wanting help */ + if (argc == 1) { + bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); + return GED_HELP; + } + + if (argc < 2) { + bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); + return GED_ERROR; + } + + preview_delay = 0; /* Full speed, by default */ + preview_mode = 1; /* wireframe drawing */ + preview_desiredframe = 0; + preview_finalframe = 0; + draw_eye_path = 0; + _ged_current_gedp = gedp; + image_name = NULL; + + /* Parse options */ + bu_optind = 1; /* re-init bu_getopt() */ + while ((c=bu_getopt(argc, (char * const *)argv, "d:evD:K:o:")) != -1) { + switch (c) { + case 'd': + preview_delay = atof(bu_optarg); + break; + case 'D': + preview_desiredframe = atof(bu_optarg); + break; + case 'e': + draw_eye_path = 1; + break; + case 'K': + preview_finalframe = atof(bu_optarg); + break; + case 'o': + image_name = bu_optarg; + break; + case 'v': + preview_mode = 3; /* Like "ev" */ + break; + default: { + bu_vls_printf(gedp->ged_result_str, "option '%c' unknown\n", c); + bu_vls_printf(gedp->ged_result_str, " -d# inter-frame delay\n"); + bu_vls_printf(gedp->ged_result_str, " -e overlay plot of eye path\n"); + bu_vls_printf(gedp->ged_result_str, " -v polygon rendering (visual)\n"); + bu_vls_printf(gedp->ged_result_str, " -D# desired starting frame\n"); + bu_vls_printf(gedp->ged_result_str, " -K# final frame\n"); + bu_vls_printf(gedp->ged_result_str, " -o image_name.ext output frame to file typed by extension(defaults to PIX)\n"); + return GED_ERROR; + } + + break; + } + } + argc -= bu_optind-1; + argv += bu_optind-1; + + if ((fp = fopen(argv[1], "r")) == NULL) { + perror(argv[1]); + return GED_ERROR; + } + + args = argc + 2 + ged_who_argc(gedp); + gedp->ged_gdp->gd_rt_cmd = (char **)bu_calloc(args, sizeof(char *), "alloc gd_rt_cmd"); + vp = &gedp->ged_gdp->gd_rt_cmd[0]; + *vp++ = bu_strdup("tree"); + + /* Build list of top-level objects in view, in _ged_current_gedp->ged_gdp->gd_rt_cmd[] */ + _ged_current_gedp->ged_gdp->gd_rt_cmd_len = ged_who_argv(gedp, vp, (const char **)&_ged_current_gedp->ged_gdp->gd_rt_cmd[args]); + /* Print out the command we are about to run */ + vp = &_ged_current_gedp->ged_gdp->gd_rt_cmd[0]; + while ((vp != NULL) && (*vp)) + bu_vls_printf(gedp->ged_result_str, "%s ", *vp++); + + bu_vls_printf(gedp->ged_result_str, "\n"); + + preview_vbp = rt_vlblock_init(); + + bu_vls_printf(gedp->ged_result_str, "eyepoint at (0, 0, 1) viewspace\n"); + + + /* + * Initialize the view to the current one provided by the ged + * structure in case a view specification is never given. + */ + MAT_COPY(_ged_viewrot, gedp->ged_gvp->gv_rotation); + VSET(temp, 0.0, 0.0, 1.0); + MAT4X3PNT(_ged_eye_model, gedp->ged_gvp->gv_view2model, temp); + + if (image_name) { + /* parse file name and possible extension */ + if ((dot = strrchr(image_name, '.')) != (char *) NULL) { + bu_vls_strncpy(&name, image_name, dot - image_name); + bu_vls_strcpy(&extension, dot); + } else { + bu_vls_strcpy(&extension, ""); + bu_vls_strcpy(&name, image_name); + } + } + while (ged_loadframe(gedp, fp) == GED_OK) { + if (image_name) { + struct bu_vls fullname = BU_VLS_INIT_ZERO; + const char *screengrab_args[3]; + int screengrab_argc = 0; + + screengrab_args[screengrab_argc++] = "screengrab"; + + bu_vls_sprintf(&fullname, "%s%05d%s", bu_vls_addr(&name), + preview_currentframe, bu_vls_addr(&extension)); + screengrab_args[screengrab_argc++] = bu_vls_addr(&fullname); + + /* ged_png(gedp, screengrab_argc, screengrab_args); */ + ged_screen_grab(gedp, screengrab_argc, screengrab_args); + + bu_vls_free(&fullname); + } + } + + if (image_name) { + bu_vls_free(&name); + bu_vls_free(&extension); + } + + fclose(fp); + fp = NULL; + + if (draw_eye_path) + _ged_cvt_vlblock_to_solids(gedp, preview_vbp, "EYE_PATH", 0); + + if (preview_vbp) { + bn_vlblock_free(preview_vbp); + preview_vbp = (struct bn_vlblock *)NULL; + } + db_free_anim(gedp->ged_wdbp->dbip); /* Forget any anim commands */ + + return GED_OK; +} + +/* + * Local Variables: + * mode: C + * tab-width: 8 + * indent-tabs-mode: t + * c-file-style: "stroustrup" + * End: + * ex: shiftwidth=4 tabstop=8 + */ Modified: brlcad/branches/gedplugins/src/libged/editit/editit.c =================================================================== --- brlcad/branches/gedplugins/src/libged/editit/editit.c 2020-07-22 00:38:30 UTC (rev 76401) +++ brlcad/branches/gedplugins/src/libged/editit/editit.c 2020-07-22 01:27:01 UTC (rev 76402) @@ -41,221 +41,8 @@ #include "ged.h" #include "../ged_private.h" -#define WIN_EDITOR "\"c:/Program Files/Windows NT/Accessories/wordpad\"" -#define MAC_EDITOR "/Applications/TextEdit.app/Contents/MacOS/TextEdit" -#define EMACS_EDITOR "emacs" -#define NANO_EDITOR "nano" -#define VIM_EDITOR "vim" -#define VI_EDITOR "vi" int -_ged_editit(const char *editstring, const char *filename) -{ -#ifdef HAVE_UNISTD_H - int xpid = 0; - int status = 0; -#endif - int pid = 0; - char **avtmp = (char **)NULL; - const char *terminal = (char *)NULL; - const char *terminal_opt = (char *)NULL; - const char *editor = (char *)NULL; - const char *editor_opt = (char *)NULL; - const char *file = (const char *)filename; - -#if defined(SIGINT) && defined(SIGQUIT) - void (*s2)(); - void (*s3)(); -#endif - - if (!file) { - bu_log("INTERNAL ERROR: editit filename missing\n"); - return 0; - } - - char *editstring_cpy = NULL; - - /* convert the edit string into pieces suitable for arguments to execlp */ - - if (editstring != NULL) { - editstring_cpy = bu_strdup(editstring); - avtmp = (char **)bu_calloc(5, sizeof(char *), "ged_editit: editstring args"); - bu_argv_from_string(avtmp, 4, editstring_cpy); - - if (avtmp[0] && !BU_STR_EQUAL(avtmp[0], "(null)")) - terminal = avtmp[0]; - if (avtmp[1] && !BU_STR_EQUAL(avtmp[1], "(null)")) - terminal_opt = avtmp[1]; - if (avtmp[2] && !BU_STR_EQUAL(avtmp[2], "(null)")) - editor = avtmp[2]; - if (avtmp[3] && !BU_STR_EQUAL(avtmp[3], "(null)")) - editor_opt = avtmp[3]; - } else { - editor = getenv("EDITOR"); - - /* still unset? try windows */ - if (!editor || editor[0] == '\0') { - if (bu_file_exists(WIN_EDITOR, NULL)) { - editor = WIN_EDITOR; - } - } - - /* still unset? try mac os x */ - if (!editor || editor[0] == '\0') { - if (bu_file_exists(MAC_EDITOR, NULL)) { - editor = MAC_EDITOR; - } - } - - /* still unset? try emacs */ - if (!editor || editor[0] == '\0') { - editor = bu_which(EMACS_EDITOR); - } - - /* still unset? try nano */ - if (!editor || editor[0] == '\0') { - editor = bu_which(NANO_EDITOR); - } - - /* still unset? try vim */ - if (!editor || editor[0] == '\0') { - editor = bu_which(VIM_EDITOR); - } - - /* still unset? As a last resort, go with vi - - * vi is part of the POSIX standard, which is as - * close as we can get currently to an editor - * that should always be present: - * http://pubs.opengroup.org/onlinepubs/9699919799/utilities/vi.html */ - if (!editor || editor[0] == '\0') { - editor = bu_which(VI_EDITOR); - } - } - - if (!editor) { - bu_log("INTERNAL ERROR: editit editor missing\n"); - return 0; - } - - /* print a message to let the user know they need to quit their - * editor before the application will come back to life. - */ - { - int length; - struct bu_vls str = BU_VLS_INIT_ZERO; - struct bu_vls sep = BU_VLS_INIT_ZERO; - char *editor_basename; - - if (terminal && editor_opt) { - bu_log("Invoking [%s %s %s] via %s\n\n", editor, editor_opt, file, terminal); - } else if (terminal) { - bu_log("Invoking [%s %s] via %s\n\n", editor, file, terminal); - } else if (editor_opt) { - bu_log("Invoking [%s %s %s]\n\n", editor, editor_opt, file); - } else { - bu_log("Invoking [%s %s]\n\n", editor, file); - } - editor_basename = bu_path_basename(editor, NULL); - bu_vls_sprintf(&str, "\nNOTE: You must QUIT %s before %s will respond and continue.\n", editor_basename, bu_getprogname()); - for (length = bu_vls_strlen(&str) - 2; length > 0; length--) { - bu_vls_putc(&sep, '*'); - } - bu_log("%s%s%s\n\n", bu_vls_addr(&sep), bu_vls_addr(&str), bu_vls_addr(&sep)); - bu_vls_free(&str); - bu_vls_free(&sep); - bu_free(editor_basename, "editor_basename free"); - } - -#if defined(SIGINT) && defined(SIGQUIT) - s2 = signal(SIGINT, SIG_IGN); - s3 = signal(SIGQUIT, SIG_IGN); -#endif - -#ifdef HAVE_UNISTD_H - if ((pid = fork()) < 0) { - perror("fork"); - return 0; - } -#endif - - if (pid == 0) { - /* Don't call bu_log() here in the child! */ - -#if defined(SIGINT) && defined(SIGQUIT) - /* deja vu */ - (void)signal(SIGINT, SIG_DFL); - (void)signal(SIGQUIT, SIG_DFL); -#endif - - { - -#if defined(_WIN32) && !defined(__CYGWIN__) - char buffer[RT_MAXLINE + 1] = {0}; - STARTUPINFO si = {0}; - PROCESS_INFORMATION pi = {0}; - si.cb = sizeof(STARTUPINFO); - si.lpReserved = NULL; - si.lpReserved2 = NULL; - si.cbReserved2 = 0; - si.lpDesktop = NULL; - si.dwFlags = 0; - - snprintf(buffer, RT_MAXLINE, "%s %s", editor, file); - - CreateProcess(NULL, buffer, NULL, NULL, TRUE, NORMAL_PRIORITY_CLASS, NULL, NULL, &si, &pi); - WaitForSingleObject(pi.hProcess, INFINITE); - return 1; -#else - char *editor_basename = bu_path_basename(editor, NULL); - if (BU_STR_EQUAL(editor_basename, "TextEdit")) { - /* close stdout/stderr so we don't get blather from TextEdit about service registration failure */ - close(fileno(stdout)); - close(fileno(stderr)); - } - bu_free(editor_basename, "editor_basename free"); - - if (!terminal && !editor_opt) { - (void)execlp(editor, editor, file, NULL); - } else if (!terminal) { - (void)execlp(editor, editor, editor_opt, file, NULL); - } else if (terminal && !terminal_opt) { - (void)execlp(terminal, terminal, editor, file, NULL); - } else if (terminal && !editor_opt) { - (void)execlp(terminal, terminal, terminal_opt, editor, file, NULL); - } else { - (void)execlp(terminal, terminal, terminal_opt, editor, editor_opt, file, NULL); - } -#endif - /* should not reach */ - perror(editor); - bu_exit(1, NULL); - } - } - -#ifdef HAVE_UNISTD_H - /* wait for the editor to terminate */ - while ((xpid = wait(&status)) >= 0) { - if (xpid == pid) { - break; - } - } -#endif - -#if defined(SIGINT) && defined(SIGQUIT) - (void)signal(SIGINT, s2); - (void)signal(SIGQUIT, s3); -#endif - - if (editstring != NULL) { - bu_free((void *)avtmp, "ged_editit: avtmp"); - bu_free(editstring_cpy, "editstring copy"); - } - - return 1; -} - - -int ged_editit_core(struct ged *gedp, int argc, const char *argv[]) { int ret = 0; Modified: brlcad/branches/gedplugins/src/libged/ged.c =================================================================== --- brlcad/branches/gedplugins/src/libged/ged.c 2020-07-22 00:38:30 UTC (rev 76401) +++ brlcad/branches/gedplugins/src/libged/ged.c 2020-07-22 01:27:01 UTC (rev 76402) @@ -51,9 +51,10 @@ #include "./ged_private.h" #include "./qray.h" -/* TODO - * Ew. Make this go away... */ +/* TODO: Ew. Globals. Make this go away... */ struct ged *_ged_current_gedp; +vect_t _ged_eye_model; +mat_t _ged_viewrot; /* FIXME: this function should not exist. passing pointers as strings * indicates a failure in design and lazy coding. Modified: brlcad/branches/gedplugins/src/libged/ged_util.c =================================================================== --- brlcad/branches/gedplugins/src/libged/ged_util.c 2020-07-22 00:38:30 UTC (rev 76401) +++ brlcad/branches/gedplugins/src/libged/ged_util.c 2020-07-22 01:27:01 UTC (rev 76402) @@ -31,7 +31,16 @@ #include <stdlib.h> #include <string.h> +#ifdef HAVE_SYS_TYPES_H +# include <sys/types.h> +#endif + +#include "bio.h" +#include "bresource.h" + + #include "bu/app.h" +#include "bu/file.h" #include "bu/path.h" #include "bu/sort.h" #include "bu/str.h" @@ -928,8 +937,900 @@ return vp-start; } +void +_ged_do_list(struct ged *gedp, struct directory *dp, int verbose) +{ + int id; + struct rt_db_internal intern; + RT_CK_DBI(gedp->ged_wdbp->dbip); + + if (dp->d_major_type == DB5_MAJORTYPE_ATTRIBUTE_ONLY) { + /* this is the _GLOBAL object */ + struct bu_attribute_value_set avs; + struct bu_attribute_value_pair *avp; + + bu_vls_strcat(gedp->ged_result_str, dp->d_namep); + bu_vls_strcat(gedp->ged_result_str, ": global attributes object\n"); + bu_avs_init_empty(&avs); + if (db5_get_attributes(gedp->ged_wdbp->dbip, &avs, dp)) { + bu_vls_printf(gedp->ged_result_str, "Cannot get attributes for %s\n", dp->d_namep); + return; + } +/* !!! left off here*/ + for (BU_AVS_FOR(avp, &avs)) { + if (BU_STR_EQUAL(avp->name, "units")) { + double conv; + const char *str; + + conv = atof(avp->value); + bu_vls_strcat(gedp->ged_result_str, "\tunits: "); + if ((str=bu_units_string(conv)) == NULL) { + bu_vls_strcat(gedp->ged_result_str, "Unrecognized units\n"); + } else { + bu_vls_strcat(gedp->ged_result_str, str); + bu_vls_putc(gedp->ged_result_str, '\n'); + } + } else { + bu_vls_putc(gedp->ged_result_str, '\t'); + bu_vls_strcat(gedp->ged_result_str, avp->name); + bu_vls_strcat(gedp->ged_result_str, ": "); + bu_vls_strcat(gedp->ged_result_str, avp->value); + bu_vls_putc(gedp->ged_result_str, '\n'); + } + } + } else { + + if ((id = rt_db_get_internal(&intern, dp, gedp->ged_wdbp->dbip, + (fastf_t *)NULL, &rt_uniresource)) < 0) { + bu_vls_printf(gedp->ged_result_str, "rt_db_get_internal(%s) failure\n", dp->d_namep); + rt_db_free_internal(&intern); + return; + } + + bu_vls_printf(gedp->ged_result_str, "%s: ", dp->d_namep); + + if (!OBJ[id].ft_describe || + OBJ[id].ft_describe(gedp->ged_result_str, + &intern, + verbose, + gedp->ged_wdbp->dbip->dbi_base2local) < 0) + bu_vls_printf(gedp->ged_result_str, "%s: describe error\n", dp->d_namep); + rt_db_free_internal(&intern); + } +} + +/** + * Once the vlist has been created, perform the common tasks + * in handling the drawn solid. + * + * This routine must be prepared to run in parallel. + */ +void +_ged_drawH_part2(int dashflag, struct bu_list *vhead, const struct db_full_path *pathp, struct db_tree_state *tsp, struct _ged_client_data *dgcdp) +{ + + if (dgcdp->wireframe_color_override) { + unsigned char wcolor[3]; + + wcolor[0] = (unsigned char)dgcdp->wireframe_color[0]; + wcolor[1] = (unsigned char)dgcdp->wireframe_color[1]; + wcolor[2] = (unsigned char)dgcdp->wireframe_color[2]; + dl_add_path(dgcdp->gdlp, dashflag, dgcdp->transparency, dgcdp->dmode, dgcdp->hiddenLine, vhead, pathp, tsp, wcolor, dgcdp->gedp->ged_create_vlist_solid_callback, dgcdp->freesolid); + } else { + dl_add_path(dgcdp->gdlp, dashflag, dgcdp->transparency, dgcdp->dmode, dgcdp->hiddenLine, vhead, pathp, tsp, NULL, dgcdp->gedp->ged_create_vlist_solid_callback, dgcdp->freesolid); + } +} + +void +_ged_cvt_vlblock_to_solids(struct ged *gedp, struct bn_vlblock *vbp, const char *name, int copy) +{ + size_t i; + char shortname[32] = {0}; + char namebuf[64] = {0}; + + bu_strlcpy(shortname, name, sizeof(shortname)); + + for (i = 0; i < vbp->nused; i++) { + if (BU_LIST_IS_EMPTY(&(vbp->head[i]))) + continue; + snprintf(namebuf, 64, "%s%lx", shortname, vbp->rgb[i]); + invent_solid(gedp->ged_gdp->gd_headDisplay, gedp->ged_wdbp->dbip, gedp->ged_create_vlist_solid_callback, gedp->ged_free_vlist_callback, namebuf, &vbp->head[i], vbp->rgb[i], copy, 1.0, 0, gedp->freesolid, 0); + } +} + +#define WIN_EDITOR "\"c:/Program Files/Windows NT/Accessories/wordpad\"" +#define MAC_EDITOR "/Applications/TextEdit.app/Contents/MacOS/TextEdit" +#define EMACS_EDITOR "emacs" +#define NANO_EDITOR "nano" +#define VIM_EDITOR "vim" +#define VI_EDITOR "vi" + +int +_ged_editit(const char *editstring, const char *filename) +{ +#ifdef HAVE_UNISTD_H + int xpid = 0; + int status = 0; +#endif + int pid = 0; + char **avtmp = (char **)NULL; + const char *terminal = (char *)NULL; + const char *terminal_opt = (char *)NULL; + const char *editor = (char *)NULL; + const char *editor_opt = (char *)NULL; + const char *file = (const char *)filename; + +#if defined(SIGINT) && defined(SIGQUIT) + void (*s2)(); + void (*s3)(); +#endif + + if (!file) { + bu_log("INTERNAL ERROR: editit filename missing\n"); + return 0; + } + + char *editstring_cpy = NULL; + + /* convert the edit string into pieces suitable for arguments to execlp */ + + if (editstring != NULL) { + editstring_cpy = bu_strdup(editstring); + avtmp = (char **)bu_calloc(5, sizeof(char *), "ged_editit: editstring args"); + bu_argv_from_string(avtmp, 4, editstring_cpy); + + if (avtmp[0] && !BU_STR_EQUAL(avtmp[0], "(null)")) + terminal = avtmp[0]; + if (avtmp[1] && !BU_STR_EQUAL(avtmp[1], "(null)")) + terminal_opt = avtmp[1]; + if (avtmp[2] && !BU_STR_EQUAL(avtmp[2], "(null)")) + editor = avtmp[2]; + if (avtmp[3] && !BU_STR_EQUAL(avtmp[3], "(null)")) + editor_opt = avtmp[3]; + } else { + editor = getenv("EDITOR"); + + /* still unset? try windows */ + if (!editor || editor[0] == '\0') { + if (bu_file_exists(WIN_EDITOR, NULL)) { + editor = WIN_EDITOR; + } + } + + /* still unset? try mac os x */ + if (!editor || editor[0] == '\0') { + if (bu_file_exists(MAC_EDITOR, NULL)) { + editor = MAC_EDITOR; + } + } + + /* still unset? try emacs */ + if (!editor || editor[0] == '\0') { + editor = bu_which(EMACS_EDITOR); + } + + /* still unset? try nano */ + if (!editor || editor[0] == '\0') { + editor = bu_which(NANO_EDITOR); + } + + /* still unset? try vim */ + if (!editor || editor[0] == '\0') { + editor = bu_which(VIM_EDITOR); + } + + /* still unset? As a last resort, go with vi - + * vi is part of the POSIX standard, which is as + * close as we can get currently to an editor + * that should always be present: + * http://pubs.opengroup.org/onlinepubs/9699919799/utilities/vi.html */ + if (!editor || editor[0] == '\0') { + editor = bu_which(VI_EDITOR); + } + } + + if (!editor) { + bu_log("INTERNAL ERROR: editit editor missing\n"); + return 0; + } + + /* print a message to let the user know they need to quit their + * editor before the application will come back to life. + */ + { + int length; + struct bu_vls str = BU_VLS_INIT_ZERO; + struct bu_vls sep = BU_VLS_INIT_ZERO; + char *editor_basename; + + if (terminal && editor_opt) { + bu_log("Invoking [%s %s %s] via %s\n\n", editor, editor_opt, file, terminal); + } else if (terminal) { + bu_log("Invoking [%s %s] via %s\n\n", editor, file, terminal); + } else if (editor_opt) { + bu_log("Invoking [%s %s %s]\n\n", editor, editor_opt, file); + } else { + bu_log("Invoking [%s %s]\n\n", editor, file); + } + editor_basename = bu_path_basename(editor, NULL); + bu_vls_sprintf(&str, "\nNOTE: You must QUIT %s before %s will respond and continue.\n", editor_basename, bu_getprogname()); + for (length = bu_vls_strlen(&str) - 2; length > 0; length--) { + bu_vls_putc(&sep, '*'); + } + bu_log("%s%s%s\n\n", bu_vls_addr(&sep), bu_vls_addr(&str), bu_vls_addr(&sep)); + bu_vls_free(&str); + bu_vls_free(&sep); + bu_free(editor_basename, "editor_basename free"); + } + +#if defined(SIGINT) && defined(SIGQUIT) + s2 = signal(SIGINT, SIG_IGN); + s3 = signal(SIGQUIT, SIG_IGN); +#endif + +#ifdef HAVE_UNISTD_H + if ((pid = fork()) < 0) { + perror("fork"); + return 0; + } +#endif + + if (pid == 0) { + /* Don't call bu_log() here in the child! */ + +#if defined(SIGINT) && defined(SIGQUIT) + /* deja vu */ + (void)signal(SIGINT, SIG_DFL); + (void)signal(SIGQUIT, SIG_DFL); +#endif + + { + +#if defined(_WIN32) && !defined(__CYGWIN__) + char buffer[RT_MAXLINE + 1] = {0}; + STARTUPINFO si = {0}; + PROCESS_INFORMATION pi = {0}; + si.cb = sizeof(STARTUPINFO); + si.lpReserved = NULL; + si.lpReserved2 = NULL; + si.cbReserved2 = 0; + si.lpDesktop = NULL; + si.dwFlags = 0; + + snprintf(buffer, RT_MAXLINE, "%s %s", editor, file); + + CreateProcess(NULL, buffer, NULL, NULL, TRUE, NORMAL_PRIORITY_CLASS, NULL, NULL, &si, &pi); + WaitForSingleObject(pi.hProcess, INFINITE); + return 1; +#else + char *editor_basename = bu_path_basename(editor, NULL); + if (BU_STR_EQUAL(editor_basename, "TextEdit")) { + /* close stdout/stderr so we don't get blather from TextEdit about service registration failure */ + close(fileno(stdout)); + close(fileno(stderr)); + } + bu_free(editor_basename, "editor_basename free"); + + if (!terminal && !editor_opt) { + (void)execlp(editor, editor, file, NULL); + } else if (!terminal) { + (void)execlp(editor, editor, editor_opt, file, NULL); + } else if (terminal && !terminal_opt) { + (void)execlp(terminal, terminal, editor, file, NULL); + } else if (terminal && !editor_opt) { + (void)execlp(terminal, terminal, terminal_opt, editor, file, NULL); + } else { + (void)execlp(terminal, terminal, terminal_opt, editor, editor_opt, file, NULL); + } +#endif + /* should not reach */ + perror(editor); + bu_exit(1, NULL); + } + } + +#ifdef HAVE_UNISTD_H + /* wait for the editor to terminate */ + while ((xpid = wait(&status)) >= 0) { + if (xpid == pid) { + break; + } + } +#endif + +#if defined(SIGINT) && defined(SIGQUIT) + (void)signal(SIGINT, s2); + (void)signal(SIGQUIT, s3); +#endif + + if (editstring != NULL) { + bu_free((void *)avtmp, "ged_editit: avtmp"); + bu_free(editstring_cpy, "editstring copy"); + } + + return 1; +} + +void +_ged_rt_set_eye_model(struct ged *gedp, + vect_t eye_model) +{ + if (gedp->ged_gvp->gv_zclip || gedp->ged_gvp->gv_perspective > 0) { + vect_t temp; + + VSET(temp, 0.0, 0.0, 1.0); + MAT4X3PNT(eye_model, gedp->ged_gvp->gv_view2model, temp); + } else { + /* not doing zclipping, so back out of geometry */ + int i; + vect_t direction; + vect_t extremum[2]; + double t_in; + vect_t diag1; + vect_t diag2; + point_t ecenter; + + VSET(eye_model, -gedp->ged_gvp->gv_center[MDX], + -gedp->ged_gvp->gv_center[MDY], -gedp->ged_gvp->gv_center[MDZ]); + + for (i = 0; i < 3; ++i) { + extremum[0][i] = INFINITY; + extremum[1][i] = -INFINITY; + } + + (void)dl_bounding_sph(gedp->ged_gdp->gd_headDisplay, &(extremum[0]), &(extremum[1]), 1); + + VMOVEN(direction, gedp->ged_gvp->gv_rotation + 8, 3); + for (i = 0; i < 3; ++i) + if (NEAR_ZERO(direction[i], 1e-10)) + direction[i] = 0.0; + + VSUB2(diag1, extremum[1], extremum[0]); + VADD2(ecenter, extremum[1], extremum[0]); + VSCALE(ecenter, ecenter, 0.5); + VSUB2(diag2, ecenter, eye_model); + t_in = MAGNITUDE(diag1) + MAGNITUDE(diag2); + VJOIN1(eye_model, eye_model, t_in, direction); + } +} + +struct _ged_rt_client_data { + struct ged_subprocess *rrtp; + struct ged *gedp; +}; + +void +_ged_rt_output_handler(void *clientData, int UNUSED(mask)) +{ + struct _ged_rt_client_data *drcdp = (struct _ged_rt_client_data *)clientData; + struct ged_subprocess *run_rtp; + int count = 0; + int retcode = 0; + int read_failed = 0; + char line[RT_MAXLINE+1] = {0}; + + if (drcdp == (struct _ged_rt_client_data *)NULL || + drcdp->gedp == (struct ged *)NULL || + drcdp->rrtp == (struct ged_subprocess *)NULL) + return; + + run_rtp = drcdp->rrtp; + + /* Get data from rt */ + if (bu_process_read((char *)line, &count, run_rtp->p, BU_PROCESS_STDERR, RT_MAXLINE) <= 0) { + read_failed = 1; + } + + if (read_failed) { + int aborted; + + /* Done watching for output, undo subprocess I/O hooks. */ + if (drcdp->gedp->ged_delete_io_handler) { + (*drcdp->gedp->ged_delete_io_handler)(drcdp->gedp->ged_interp, run_rtp->chan, + run_rtp->p, BU_PROCESS_STDERR, (void *)drcdp, + _ged_rt_output_handler); + } + /* Either EOF has been sent or there was a read error. + * there is no need to block indefinitely */ + retcode = bu_process_wait(&aborted, run_rtp->p, 120); + + if (aborted) + bu_log("Raytrace aborted.\n"); + else if (retcode) + bu_log("Raytrace failed.\n"); + else + bu_log("Raytrace complete.\n"); + + if (drcdp->gedp->ged_gdp->gd_rtCmdNotify != (void (*)(int))0) + drcdp->gedp->ged_gdp->gd_rtCmdNotify(aborted); + + /* free run_rtp */ + BU_LIST_DEQUEUE(&run_rtp->l); + BU_PUT(run_rtp, struct ged_subprocess); + BU_PUT(drcdp, struct _ged_rt_client_data); + + return; + } + + /* for feelgoodedness */ + line[count] = '\0'; + + /* handle (i.e., probably log to stderr) the resulting line */ + if (drcdp->gedp->ged_output_handler != (void (*)(struct ged *, char *))0) + drcdp->gedp->ged_output_handler(drcdp->gedp, line); + else + bu_vls_printf(drcdp->gedp->ged_result_str, "%s", line); +} + +void +_ged_rt_write(struct ged *gedp, + FILE *fp, + vect_t eye_model, + int argc, + const char **argv) +{ + quat_t quat; + + /* Double-precision IEEE floating point only guarantees 15-17 + * digits of precision; single-precision only 6-9 significant + * decimal digits. Using a %.15e precision specifier makes our + * printed value dip into unreliable territory (1+15 digits). + * Looking through our history, %.14e seems to be safe as the + * value prior to printing quaternions was %.9e, although anything + * from 9->14 "should" be safe as it's above our calculation + * tolerance and above single-precision capability. + */ + fprintf(fp, "viewsize %.14e;\n", gedp->ged_gvp->gv_size); + quat_mat2quat(quat, gedp->ged_gvp->gv_rotation); + fprintf(fp, "orientation %.14e %.14e %.14e %.14e;\n", V4ARGS(quat)); + fprintf(fp, "eye_pt %.14e %.14e %.14e;\n", + eye_model[X], eye_model[Y], eye_model[Z]); + + fprintf(fp, "start 0; clean;\n"); + + /* If no objects were specified, activate all objects currently displayed. + * Otherwise, simply draw the specified objects. If the caller passed + * -1 in argc it means the objects are specified on the command line. + * (TODO - we shouldn't be doing that anywhere for this; long command + * strings make Windows unhappy. Once all the callers have been + * adjusted to pass the object lists for itemization via pipes below, + * remove the -1 case.) */ + if (argc >= 0) { + if (!argc) { + struct display_list *gdlp; + for (BU_LIST_FOR(gdlp, display_list, gedp->ged_gdp->gd_headDisplay)) { + if (((struct directory *)gdlp->dl_dp)->d_addr == RT_DIR_PHONY_ADDR) + continue; + fprintf(fp, "draw %s;\n", bu_vls_addr(&gdlp->dl_path)); + } + } else { + int i = 0; + while (i < argc) { + fprintf(fp, "draw %s;\n", argv[i++]); + } + } + + fprintf(fp, "prep;\n"); + } + + dl_bitwise_and_fullpath(gedp->ged_gdp->gd_headDisplay, ~RT_DIR_USED); + + dl_write_animate(gedp->ged_gdp->gd_headDisplay, fp); + + dl_bitwise_and_fullpath(gedp->ged_gdp->gd_headDisplay, ~RT_DIR_USED); + + fprintf(fp, "end;\n"); +} + +int +_ged_run_rt(struct ged *gedp, int cmd_len, const char **gd_rt_cmd, int argc, const char **argv) +{ + FILE *fp_in; + vect_t eye_model; + struct ged_subprocess *run_rtp; + struct _ged_rt_client_data *drcdp; + struct bu_process *p = NULL; + + bu_process_exec(&p, gd_rt_cmd[0], cmd_len, gd_rt_cmd, 0, 0); + fp_in = bu_process_open(p, BU_PROCESS_STDIN); + + if (bu_process_pid(p) == -1) { + bu_vls_printf(gedp->ged_result_str, "\nunable to successfully launch subprocess: "); + for (int i = 0; i < cmd_len; i++) { + bu_vls_printf(gedp->ged_result_str, "%s ", gd_rt_cmd[i]); + } + bu_vls_printf(gedp->ged_result_str, "\n"); + return GED_ERROR; + } + + _ged_rt_set_eye_model(gedp, eye_model); + _ged_rt_write(gedp, fp_in, eye_model, argc, argv); + + bu_process_close(p, BU_PROCESS_STDIN); + + BU_GET(run_rtp, struct ged_subprocess); + BU_LIST_INIT(&run_rtp->l); + BU_LIST_APPEND(&gedp->gd_headSubprocess.l, &run_rtp->l); + + run_rtp->p = p; + run_rtp->aborted = 0; + + BU_GET(drcdp, struct _ged_rt_client_data); + drcdp->gedp = gedp; + drcdp->rrtp = run_rtp; + + /* If we know how, set up hooks so the parent process knows to watch for output. */ + if (gedp->ged_create_io_handler) { + (*gedp->ged_create_io_handler)(&(run_rtp->chan), p, BU_PROCESS_STDERR, gedp->io_mode, (void *)drcdp, _ged_rt_output_handler); + } + return GED_OK; +} + +struct rt_object_selections * +ged_get_object_selections(struct ged *gedp, const char *object_name) +{ + struct rt_object_selections *obj_selections; + + obj_selections = (struct rt_object_selections *)bu_hash_get(gedp->ged_selections, (uint8_t *)object_name, strlen(object_name)); + + if (!obj_selections) { + BU_ALLOC(obj_selections, struct rt_object_selections); + obj_selections->sets = bu_hash_create(0); + (void)bu_hash_set(gedp->ged_selections, (uint8_t *)object_name, strlen(object_name), (void *)obj_selections); + } + + return obj_selections; +} + + +struct rt_selection_set * +ged_get_selection_set(struct ged *gedp, const char *object_name, const char *selection_name) +{ + struct rt_object_selections *obj_selections; + struct rt_selection_set *set; + + obj_selections = ged_get_object_selections(gedp, object_name); + set = (struct rt_selection_set *)bu_hash_get(obj_selections->sets, (uint8_t *)selection_name, strlen(selection_name)); + if (!set) { + BU_ALLOC(set, struct rt_selection_set); + BU_PTBL_INIT(&set->selections); + bu_hash_set(obj_selections->sets, (uint8_t *)selection_name, strlen(selection_name), (void *)set); + } + + return set; +} + /* + * Add an instance of object 'objp' to combination 'name'. + * If the combination does not exist, it is created. + * region_flag is 1 (region), or 0 (group). + * + * Preserves the GIFT semantics. + */ +struct directory * +_ged_combadd(struct ged *gedp, + struct directory *objp, + char *combname, + int region_flag, /* true if adding region */ + db_op_t relation, /* = UNION, SUBTRACT, INTERSECT */ + int ident, /* "Region ID" */ + int air /* Air code */) +{ + int ac = 1; + const char *av[2]; + + av[0] = objp->d_namep; + av[1] = NULL; + + if (_ged_combadd2(gedp, combname, ac, av, region_flag, relation, ident, air, NULL, 1) == GED_ERROR) + return RT_DIR_NULL; + + /* Done changing stuff - update nref. */ + db_update_nref(gedp->ged_wdbp->dbip, &rt_uniresource); + + return db_lookup(gedp->ged_wdbp->dbip, combname, LOOKUP_QUIET); +} + + +/* + * Add an instance of object 'objp' to combination 'name'. + * If the combination does not exist, it is created. + * region_flag is 1 (region), or 0 (group). + * + * Preserves the GIFT semantics. + */ +int +_ged_combadd2(struct ged *gedp, + char *combname, + int argc, + const char *argv[], + int region_flag, /* true if adding region */ + db_op_t relation, /* = UNION, SUBTRACT, INTERSECT */ + int ident, /* "Region ID" */ + int air, /* Air code */ + matp_t m, /* Matrix */ + int validate /* 1 to check if new members exist, 0 to just add them */) +{ + struct directory *dp; + struct directory *objp; + struct rt_db_internal intern; + struct rt_comb_internal *comb; + union tree *tp; + struct rt_tree_array *tree_list; + size_t node_count; + size_t actual_count; + size_t curr_count; + int i; + + if (argc < 1) + return GED_ERROR; + + /* + * Check to see if we have to create a new combination + */ + if ((dp = db_lookup(gedp->ged_wdbp->dbip, combname, LOOKUP_QUIET)) == RT_DIR_NULL) { + int flags; + + if (region_flag) + flags = RT_DIR_REGION | RT_DIR_COMB; + else + flags = RT_DIR_COMB; + + RT_DB_INTERNAL_INIT(&intern); + intern.idb_major_type = DB5_MAJORTYPE_BRLCAD; + intern.idb_type = ID_COMBINATION; + intern.idb_meth = &OBJ[ID_COMBINATION]; + + GED_DB_DIRADD(gedp, dp, combname, -1, 0, flags, (void *)&intern.idb_type, 0); + + BU_ALLOC(comb, struct rt_comb_internal); + RT_COMB_INTERNAL_INIT(comb); + + intern.idb_ptr = (void *)comb; + + if (region_flag) { + comb->region_flag = 1; + comb->region_id = ident; + comb->aircode = air; + comb->los = gedp->ged_wdbp->wdb_los_default; + comb->GIFTmater = gedp->ged_wdbp->wdb_mat_default; + bu_vls_printf(gedp->ged_result_str, "Creating region with attrs: region_id=%d, ", ident); + if (air) + bu_vls_printf(gedp->ged_result_str, "air=%d, ", air); + bu_vls_printf(gedp->ged_result_str, "los=%d, material_id=%d\n", + gedp->ged_wdbp->wdb_los_default, + gedp->ged_wdbp->wdb_mat_default); + } else { + comb->region_flag = 0; + } + + goto addmembers; + } else if (!(dp->d_flags & RT_DIR_COMB)) { + bu_vls_printf(gedp->ged_result_str, "%s exists, but is not a combination\n", dp->d_namep); + return GED_ERROR; + } + + /* combination exists, add a new member */ + GED_DB_GET_INTERNAL(gedp, &intern, dp, (fastf_t *)NULL, &rt_uniresource, 0); + + comb = (struct rt_comb_internal *)intern.idb_ptr; + RT_CK_COMB(comb); + + if (region_flag && !comb->region_flag) { + bu_vls_printf(gedp->ged_result_str, "%s: not a region\n", dp->d_namep); + return GED_ERROR; + } + +addmembers: + 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_db_free_internal(&intern); + return GED_ERROR; + } + } + + /* make space for an extra leaf */ + curr_count = db_tree_nleaves(comb->tree); + node_count = curr_count + argc; + tree_list = (struct rt_tree_array *)bu_calloc(node_count, sizeof(struct rt_tree_array), "tree list"); + + /* flatten tree */ + if (comb->tree) { + actual_count = argc + (struct rt_tree_array *)db_flatten_tree(tree_list, comb->tree, OP_UNION, 1, &rt_uniresource) - tree_list; + BU_ASSERT(actual_count == node_count); + comb->tree = TREE_NULL; + } + + for (i = 0; i < argc; ++i) { + if (validate) { + if ((objp = db_lookup(gedp->ged_wdbp->dbip, argv[i], LOOKUP_NOISY)) == RT_DIR_NULL) { + bu_vls_printf(gedp->ged_result_str, "skip member %s\n", argv[i]); + continue; + } + } + + /* insert new member at end */ + switch (relation) { + case DB_OP_INTERSECT: + tree_list[curr_count].tl_op = OP_INTERSECT; + break; + case DB_OP_SUBTRACT: + tree_list[curr_count].tl_op = OP_SUBTRACT; + break; + default: + if (relation != DB_OP_UNION) { + bu_vls_printf(gedp->ged_result_str, "unrecognized relation (assume UNION)\n"); + } + tree_list[curr_count].tl_op = OP_UNION; + break; + } + + /* make new leaf node, and insert at end of list */ + BU_GET(tp, union tree); + RT_TREE_INIT(tp); + tree_list[curr_count].tl_tree = tp; + tp->tr_l.tl_op = OP_DB_LEAF; + tp->tr_l.tl_name = bu_strdup(argv[i]); + if (m) { + tp->tr_l.tl_mat = (matp_t)bu_malloc(sizeof(mat_t), "mat copy"); + MAT_COPY(tp->tr_l.tl_mat, m); + } else { + tp->tr_l.tl_mat = (matp_t)NULL; + } + + ++curr_count; + } + + /* rebuild the tree */ + comb->tree = (union tree *)db_mkgift_tree(tree_list, node_count, &rt_uniresource); + + /* and finally, write it out */ + GED_DB_PUT_INTERNAL(gedp, dp, &intern, &rt_uniresource, 0); + + bu_free((char *)tree_list, "combadd: tree_list"); + + /* Done changing stuff - update nref. */ + db_update_nref(gedp->ged_wdbp->dbip, &rt_uniresource); + + return GED_OK; +} + +void +_ged_wait_status(struct bu_vls *logstr, + int status) +{ + int sig = status & 0x7f; + int core = status & 0x80; + int ret = status >> 8; + + if (status == 0) { + bu_vls_printf(logstr, "Normal exit\n"); + return; + } + + bu_vls_printf(logstr, "Abnormal exit x%x", status); + + if (core) + bu_vls_printf(logstr, ", core dumped"); + + if (sig) + bu_vls_printf(logstr, ", terminating signal = %d", sig); + else + bu_vls_printf(logstr, ", return (exit) code = %d", ret); +} + +struct directory ** +_ged_build_dpp(struct ged *gedp, + const char *path) { + struct directory *dp; + struct directory **dpp; + int i; + char *begin; + char *end; + char *newstr; + char *list; + int ac; + const char **av; + const char **av_orig = NULL; + struct bu_vls vls = BU_VLS_INIT_ZERO; + + /* + * First, build an array of the object's path components. + * We store the list in av_orig below. + */ + newstr = bu_strdup(path); + begin = newstr; + while ((end = strchr(begin, '/')) != NULL) { + *end = '\0'; + bu_vls_printf(&vls, "%s ", begin); + begin = end + 1; + } + bu_vls_printf(&vls, "%s ", begin); + free((void *)newstr); + + list = bu_vls_addr(&vls); + + if (bu_argv_from_tcl_list(list, &ac, &av_orig) != 0) { + bu_vls_printf(gedp->ged_result_str, "-1"); + bu_vls_free(&vls); + return (struct directory **)NULL; + } + + /* skip first element if empty */ + av = av_orig; + if (*av[0] == '\0') { + --ac; + ++av; + } + + /* ignore last element if empty */ + if (*av[ac-1] == '\0') + --ac; + + /* + * Next, we build an array of directory pointers that + * correspond to the object's path. + */ + dpp = (struct directory **)bu_calloc(ac+1, sizeof(struct directory *), "_ged_build_dpp: directory pointers"); + for (i = 0; i < ac; ++i) { + if ((dp = db_lookup(gedp->ged_wdbp->dbip, av[i], 0)) != RT_DIR_NULL) + dpp[i] = dp; + else { + /* object is not currently being displayed */ + bu_vls_printf(gedp->ged_result_str, "-1"); + + bu_free((void *)dpp, "_ged_build_dpp: directory pointers"); + bu_free((char *)av_orig, "free av_orig"); + bu_vls_free(&vls); + return (struct directory **)NULL; + } + } + + dpp[i] = RT_DIR_NULL; + + bu_free((char *)av_orig, "free av_orig"); + bu_vls_free(&vls); + return dpp; +} + +/* + * This routine walks through the directory entry list and mallocs enough + * space for pointers to hold: + * a) all of the entries if called with an argument of 0, or + * b) the number of entries specified by the argument if > 0. + */ +struct directory ** +_ged_dir_getspace(struct db_i *dbip, + int num_entries) +{ + struct directory *dp; + int i; + struct directory **dir_basep; + + if (num_entries < 0) { + bu_log("dir_getspace: was passed %d, used 0\n", + num_entries); + num_entries = 0; + } + if (num_entries == 0) { + /* Set num_entries to the number of entries */ + for (i = 0; i < RT_DBNHASH; i++) + for (dp = dbip->dbi_Head[i]; dp != RT_DIR_NULL; dp = dp->d_forw) + num_entries++; + } + + /* Allocate and cast num_entries worth of pointers */ + dir_basep = (struct directory **) bu_malloc((num_entries+1) * sizeof(struct directory *), + "dir_getspace *dir[]"); + return dir_basep; +} + + + +/* * Local Variables: * mode: C * tab-width: 8 Modified: brlcad/branches/gedplugins/src/libged/how/how.c =================================================================== --- brlcad/branches/gedplugins/src/libged/how/how.c 2020-07-22 00:38:30 UTC (rev 76401) +++ brlcad/branches/gedplugins/src/libged/how/how.c 2020-07-22 01:27:01 UTC (rev 76402) @@ -92,81 +92,7 @@ } -struct directory ** -_ged_build_dpp(struct ged *gedp, - const char *path) { - struct directory *dp; - struct directory **dpp; - int i; - char *begin; - char *end; - char *newstr; - char *list; - int ac; - const char **av; - const char **av_orig = NULL; - struct bu_vls vls = BU_VLS_INIT_ZERO; - /* - * First, build an array of the object's path components. - * We store the list in av_orig below. - */ - newstr = bu_strdup(path); - begin = newstr; - while ((end = strchr(begin, '/')) != NULL) { - *end = '\0'; - bu_vls_printf(&vls, "%s ", begin); - begin = end + 1; - } - bu_vls_printf(&vls, "%s ", begin); - free((void *)newstr); - - list = bu_vls_addr(&vls); - - if (bu_argv_from_tcl_list(list, &ac, &av_orig) != 0) { - bu_vls_printf(gedp->ged_result_str, "-1"); - bu_vls_free(&vls); - return (struct directory **)NULL; - } - - /* skip first element if empty */ - av = av_orig; - if (*av[0] == '\0') { - --ac; - ++av; - } - - /* ignore last element if empty */ - if (*av[ac-1] == '\0') - --ac; - - /* - * Next, we build an array of directory pointers that - * correspond to the object's path. - */ - dpp = (struct directory **)bu_calloc(ac+1, sizeof(struct directory *), "_ged_build_dpp: directory pointers"); - for (i = 0; i < ac; ++i) { - if ((dp = db_lookup(gedp->ged_wdbp->dbip, av[i], 0)) != RT_DIR_NULL) - dpp[i] = dp; - else { - /* object is not currently being displayed */ - bu_vls_printf(gedp->ged_result_str, "-1"); - - bu_free((void *)dpp, "_ged_build_dpp: directory pointers"); - bu_free((char *)av_orig, "free av_orig"); - bu_vls_free(&vls); - return (struct directory **)NULL; - } - } - - dpp[i] = RT_DIR_NULL; - - bu_free((char *)av_orig, "free av_orig"); - bu_vls_free(&vls); - return dpp; -} - - #ifdef GED_PLUGIN #include "../include/plugin.h" struct ged_cmd_impl how_cmd_impl = { Modified: brlcad/branches/gedplugins/src/libged/list/list.c =================================================================== --- brlcad/branches/gedplugins/src/libged/list/list.c 2020-07-22 00:38:30 UTC (rev 76401) +++ brlcad/branches/gedplugins/src/libged/list/list.c 2020-07-22 01:27:01 UTC (rev 76402) @@ -34,71 +34,6 @@ #include "../ged_private.h" - -void -_ged_do_list(struct ged *gedp, struct directory *dp, int verbose) -{ - int id; - struct rt_db_internal intern; - - RT_CK_DBI(gedp->ged_wdbp->dbip); - - if (dp->d_major_type == DB5_MAJORTYPE_ATTRIBUTE_ONLY) { - /* this is the _GLOBAL object */ - struct bu_attribute_value_set avs; - struct bu_attribute_value_pair *avp; - - bu_vls_strcat(gedp->ged_result_str, dp->d_namep); - bu_vls_strcat(gedp->ged_result_str, ": global attributes object\n"); - bu_avs_init_empty(&avs); - if (db5_get_attributes(gedp->ged_wdbp->dbip, &avs, dp)) { - bu_vls_printf(gedp->ged_result_str, "Cannot get attributes for %s\n", dp->d_namep); - return; - } -/* !!! left off here*/ - for (BU_AVS_FOR(avp, &avs)) { - if (BU_STR_EQUAL(avp->name, "units")) { - double conv; - const char *str; - - conv = atof(avp->value); - bu_vls_strcat(gedp->ged_result_str, "\tunits: "); - if ((str=bu_units_string(conv)) == NULL) { - bu_vls_strcat(gedp->ged_result_str, "Unrecognized units\n"); - } else { - bu_vls_strcat(gedp->ged_result_str, str); - bu_vls_putc(gedp->ged_result_str, '\n'); - } - } else { - bu_vls_putc(gedp->ged_result_str, '\t'); - bu_vls_strcat(gedp->ged_result_str, avp->name); - bu_vls_strcat(gedp->ged_result_str, ": "); - bu_vls_strcat(gedp->ged_result_str, avp->value); - bu_vls_putc(gedp->ged_result_str, '\n'); - } - } - } else { - - if ((id = rt_db_get_internal(&intern, dp, gedp->ged_wdbp->dbip, - (fastf_t *)NULL, &rt_uniresource)) < 0) { - bu_vls_printf(gedp->ged_result_str, "rt_db_get_internal(%s) failure\n", dp->d_namep); - rt_db_free_internal(&intern); - return; - } - - bu_vls_printf(gedp->ged_result_str, "%s: ", dp->d_namep); - - if (!OBJ[id].ft_describe || - OBJ[id].ft_describe(gedp->ged_result_str, - &intern, - verbose, - gedp->ged_wdbp->dbip->dbi_base2local) < 0) - bu_vls_printf(gedp->ged_result_str, "%s: describe error\n", dp->d_namep); - rt_db_free_internal(&intern); - } -} - - int ged_list_core(struct ged *gedp, int argc, const char *argv[]) { Modified: brlcad/branches/gedplugins/src/libged/pnts_util.h =================================================================== --- brlcad/branches/gedplugins/src/libged/pnts_util.h 2020-07-22 00:38:30 UTC (rev 76401) +++ brlcad/branches/gedplugins/src/libged/pnts_util.h 2020-07-22 01:27:01 UTC (rev 76402) @@ -22,6 +22,8 @@ * utility functionality for simple Point Set (pnts) primitive operations. * */ +#ifndef LIBGED_PNT_GED_PRIVATE_H +#define LIBGED_PNT_GED_PRIVATE_H #include "common.h" @@ -34,6 +36,8 @@ #include "ged/defines.h" #include "./ged_private.h" +__BEGIN_DECLS + GED_EXPORT extern const char *_ged_pnt_default_fmt_str(rt_pnt_type type); GED_EXPORT extern void _ged_pnt_v_set(void *point, rt_pnt_type type, char key, fastf_t val); @@ -56,6 +60,10 @@ GED_EXPORT extern void _ged_pnts_add(struct rt_pnts_internal *pnts, void *point); +__END_DECLS + +#endif //LIBGED_PNT_GED_PRIVATE_H + /* * Local Variables: * tab-width: 8 Modified: brlcad/branches/gedplugins/src/libged/rt/rt.c =================================================================== --- brlcad/branches/gedplugins/src/libged/rt/rt.c 2020-07-22 00:38:30 UTC (rev 76401) +++ brlcad/branches/gedplugins/src/libged/rt/rt.c 2020-07-22 01:27:01 UTC (rev 76402) @@ -39,226 +39,8 @@ #include "../ged_private.h" -struct _ged_rt_client_data { - struct ged_subprocess *rrtp; - struct ged *gedp; -}; - -void -_ged_rt_write(struct ged *gedp, - FILE *fp, - vect_t eye_model, - int argc, - const char **argv) -{ - quat_t quat; - - /* Double-precision IEEE floating point only guarantees 15-17 - * digits of precision; single-precision only 6-9 significant - * decimal digits. Using a %.15e precision specifier makes our - * printed value dip into unreliable territory (1+15 digits). - * Looking through our history, %.14e seems to be safe as the - * value prior to printing quaternions was %.9e, although anything - * from 9->14 "should" be safe as it's above our calculation - * tolerance and above single-precision capability. - */ - fprintf(fp, "viewsize %.14e;\n", gedp->ged_gvp->gv_size); - quat_mat2quat(quat, gedp->ged_gvp->gv_rotation); - fprintf(fp, "orientation %.14e %.14e %.14e %.14e;\n", V4ARGS(quat)); - fprintf(fp, "eye_pt %.14e %.14e %.14e;\n", - eye_model[X], eye_model[Y], eye_model[Z]); - - fprintf(fp, "start 0; clean;\n"); - - /* If no objects were specified, activate all objects currently displayed. - * Otherwise, simply draw the specified objects. If the caller passed - * -1 in argc it means the objects are specified on the command line. - * (TODO - we shouldn't be doing that anywhere for this; long command - * strings make Windows unhappy. Once all the callers have been - * adjusted to pass the object lists for itemization via pipes below, - * remove the -1 case.) */ - if (argc >= 0) { - if (!argc) { - struct display_list *gdlp; - for (BU_LIST_FOR(gdlp, display_list, gedp->ged_gdp->gd_headDisplay)) { - if (((struct directory *)gdlp->dl_dp)->d_addr == RT_DIR_PHONY_ADDR) - continue; - fprintf(fp, "draw %s;\n", bu_vls_addr(&gdlp->dl_path)); - } - } else { - int i = 0; - while (i < argc) { - fprintf(fp, "draw %s;\n", argv[i++]); - } - } - - fprintf(fp, "prep;\n"); - } - - dl_bitwise_and_fullpath(gedp->ged_gdp->gd_headDisplay, ~RT_DIR_USED); - - dl_write_animate(gedp->ged_gdp->gd_headDisplay, fp); - - dl_bitwise_and_fullpath(gedp->ged_gdp->gd_headDisplay, ~RT_DIR_USED); - - fprintf(fp, "end;\n"); -} - - -void -_ged_rt_set_eye_model(struct ged *gedp, - vect_t eye_model) -{ - if (gedp->ged_gvp->gv_zclip || gedp->ged_gvp->gv_perspective > 0) { - vect_t temp; - - VSET(temp, 0.0, 0.0, 1.0); - MAT4X3PNT(eye_model, gedp->ged_gvp->gv_view2model, temp); - } else { - /* not doing zclipping, so back out of geometry */ - int i; - vect_t direction; - vect_t extremum[2]; - double t_in; - vect_t diag1; - vect_t diag2; - point_t ecenter; - - VSET(eye_model, -gedp->ged_gvp->gv_center[MDX], - -gedp->ged_gvp->gv_center[MDY], -gedp->ged_gvp->gv_center[MDZ]); - - for (i = 0; i < 3; ++i) { - extremum[0][i] = INFINITY; - extremum[1][i] = -INFINITY; - } - - (void)dl_bounding_sph(gedp->ged_gdp->gd_headDisplay, &(extremum[0]), &(extremum[1]), 1); - - VMOVEN(direction, gedp->ged_gvp->gv_rotation + 8, 3); - for (i = 0; i < 3; ++i) - if (NEAR_ZERO(direction[i], 1e-10)) - direction[i] = 0.0; - - VSUB2(diag1, extremum[1], extremum[0]); - VADD2(ecenter, extremum[1], extremum[0]); - VSCALE(ecenter, ecenter, 0.5); - VSUB2(diag2, ecenter, eye_model); - t_in = MAGNITUDE(diag1) + MAGNITUDE(diag2); - VJOIN1(eye_model, eye_model, t_in, direction); - } -} - - -void -_ged_rt_output_handler(void *clientData, int UNUSED(mask)) -{ - struct _ged_rt_client_data *drcdp = (struct _ged_rt_client_data *)clientData; - struct ged_subprocess *run_rtp; - int count = 0; - int retcode = 0; - int read_failed = 0; - char line[RT_MAXLINE+1] = {0}; - - if (drcdp == (struct _ged_rt_client_data *)NULL || - drcdp->gedp == (struct ged *)NULL || - drcdp->rrtp == (struct ged_subprocess *)NULL) - return; - - run_rtp = drcdp->rrtp; - - /* Get data from rt */ - if (bu_process_read((char *)line, &count, run_rtp->p, BU_PROCESS_STDERR, RT_MAXLINE) <= 0) { - read_failed = 1; - } - - if (read_failed) { - int aborted; - - /* Done watching for output, undo subprocess I/O hooks. */ - if (drcdp->gedp->ged_delete_io_handler) { - (*drcdp->gedp->ged_delete_io_handler)(drcdp->gedp->ged_interp, run_rtp->chan, - run_rtp->p, BU_PROCESS_STDERR, (void *)drcdp, - _ged_rt_output_handler); - } - /* Either EOF has been sent or there was a read error. - * there is no need to block indefinitely */ - retcode = bu_process_wait(&aborted, run_rtp->p, 120); - - if (aborted) - bu_log("Raytrace aborted.\n"); - else if (retcode) - bu_log("Raytrace failed.\n"); - else - bu_log("Raytrace complete.\n"); - - if (drcdp->gedp->ged_gdp->gd_rtCmdNotify != (void (*)(int))0) - drcdp->gedp->ged_gdp->gd_rtCmdNotify(aborted); - - /* free run_rtp */ - BU_LIST_DEQUEUE(&run_rtp->l); - BU_PUT(run_rtp, struct ged_subprocess); - BU_PUT(drcdp, struct _ged_rt_client_data); - - return; - } - - /* for feelgoodedness */ - line[count] = '\0'; - - /* handle (i.e., probably log to stderr) the resulting line */ - if (drcdp->gedp->ged_output_handler != (void (*)(struct ged *, char *))0) - drcdp->gedp->ged_output_handler(drcdp->gedp, line); - else - bu_vls_printf(drcdp->gedp->ged_result_str, "%s", line); -} - int -_ged_run_rt(struct ged *gedp, int cmd_len, const char **gd_rt_cmd, int argc, const char **argv) -{ - FILE *fp_in; - vect_t eye_model; - struct ged_subprocess *run_rtp; - struct _ged_rt_client_data *drcdp; - struct bu_process *p = NULL; - - bu_process_exec(&p, gd_rt_cmd[0], cmd_len, gd_rt_cmd, 0, 0); - fp_in = bu_process_open(p, BU_PROCESS_STDIN); - - if (bu_process_pid(p) == -1) { - bu_vls_printf(gedp->ged_result_str, "\nunable to successfully launch subprocess: "); - for (int i = 0; i < cmd_len; i++) { - bu_vls_printf(gedp->ged_result_str, "%s ", gd_rt_cmd[i]); - } - bu_vls_printf(gedp->ged_result_str, "\n"); - return GED_ERROR; - } - - _ged_rt_set_eye_model(gedp, eye_model); - _ged_rt_write(gedp, fp_in, eye_model, argc, argv); - - bu_process_close(p, BU_PROCESS_STDIN); - - BU_GET(run_rtp, struct ged_subprocess); - BU_LIST_INIT(&run_rtp->l); - BU_LIST_APPEND(&gedp->gd_headSubprocess.l, &run_rtp->l); - - run_rtp->p = p; - run_rtp->aborted = 0; - - BU_GET(drcdp, struct _ged_rt_client_data); - drcdp->gedp = gedp; - drcdp->rrtp = run_rtp; - - /* If we know how, set up hooks so the parent process knows to watch for output. */ - if (gedp->ged_create_io_handler) { - (*gedp->ged_create_io_handler)(&(run_rtp->chan), p, BU_PROCESS_STDERR, gedp->io_mode, (void *)drcdp, _ged_rt_output_handler); - } - return GED_OK; -} - - -int ged_rt_core(struct ged *gedp, int argc, const char *argv[]) { char **vp; Modified: brlcad/branches/gedplugins/src/libged/rtcheck/rtcheck.c =================================================================== --- brlcad/branches/gedplugins/src/libged/rtcheck/rtcheck.c 2020-07-22 00:38:30 UTC (rev 76401) +++ brlcad/branches/gedplugins/src/libged/rtcheck/rtcheck.c 2020-07-22 01:27:01 UTC (rev 76402) @@ -50,30 +50,6 @@ int draw_read_failed; }; -void -_ged_wait_status(struct bu_vls *logstr, - int status) -{ - int sig = status & 0x7f; - int core = status & 0x80; - int ret = status >> 8; - - if (status == 0) { - bu_vls_printf(logstr, "Normal exit\n"); - return; - } - - bu_vls_printf(logstr, "Abnormal exit x%x", status); - - if (core) - bu_vls_printf(logstr, ", core dumped"); - - if (sig) - bu_vls_printf(logstr, ", terminating signal = %d", sig); - else - bu_vls_printf(logstr, ", return (exit) code = %d", ret); -} - static void rtcheck_output_handler(void *clientData, int mask); static void rtcheck_vector_handler(void *clientData, int mask); Modified: brlcad/branches/gedplugins/src/libged/select/select.c =================================================================== --- brlcad/branches/gedplugins/src/libged/select/select.c 2020-07-22 00:38:30 UTC (rev 76401) +++ brlcad/branches/gedplugins/src/libged/select/select.c 2020-07-22 01:27:01 UTC (rev 76402) @@ -274,39 +274,6 @@ } } -struct rt_object_selections * -ged_get_object_selections(struct ged *gedp, const char *object_name) -{ - struct rt_object_selections *obj_selections; - - obj_selections = (struct rt_object_selections *)bu_hash_get(gedp->ged_selections, (uint8_t *)object_name, strlen(object_name)); - - if (!obj_selections) { - BU_ALLOC(obj_selections, struct rt_object_selections); - obj_selections->sets = bu_hash_create(0); - (void)bu_hash_set(gedp->ged_selections, (uint8_t *)object_name, strlen(object_name), (void *)obj_selections); - } - - return obj_selections; -} - -struct rt_selection_set * -ged_get_selection_set(struct ged *gedp, const char *object_name, const char *selection_name) -{ - struct rt_object_selections *obj_selections; - struct rt_selection_set *set; - - obj_selections = ged_get_object_selections(gedp, object_name); - set = (struct rt_selection_set *)bu_hash_get(obj_selections->sets, (uint8_t *)selection_name, strlen(selection_name)); - if (!set) { - BU_ALLOC(set, struct rt_selection_set); - BU_PTBL_INIT(&set->selections); - bu_hash_set(obj_selections->sets, (uint8_t *)selection_name, strlen(selection_name), (void *)set); - } - - return set; -} - #ifdef GED_PLUGIN #include "../include/plugin.h" struct ged_cmd_impl select_cmd_impl = { Modified: brlcad/branches/gedplugins/src/libged/tops/tops.c =================================================================== --- brlcad/branches/gedplugins/src/libged/tops/tops.c 2020-07-22 00:38:30 UTC (rev 76401) +++ brlcad/branches/gedplugins/src/libged/tops/tops.c 2020-07-22 01:27:01 UTC (rev 76402) @@ -130,39 +130,7 @@ } -/* - * This routine walks through the directory entry list and mallocs enough - * space for pointers to hold: - * a) all of the entries if called with an argument of 0, or - * b) the number of entries specified by the argument if > 0. - */ -struct directory ** -_ged_dir_getspace(struct db_i *dbip, - int num_entries) -{ - struct directory *dp; - int i; - struct directory **dir_basep; - if (num_entries < 0) { - bu_log("dir_getspace: was passed %d, used 0\n", - num_entries); - num_entries = 0; - } - if (num_entries == 0) { - /* Set num_entries to the number of entries */ - for (i = 0; i < RT_DBNHASH; i++) - for (dp = dbip->dbi_Head[i]; dp != RT_DIR_NULL; dp = dp->d_forw) - num_entries++; - } - - /* Allocate and cast num_entries worth of pointers */ - dir_basep = (struct directory **) bu_malloc((num_entries+1) * sizeof(struct directory *), - "dir_getspace *dir[]"); - return dir_basep; -} - - #ifdef GED_PLUGIN #include "../include/plugin.h" struct ged_cmd_impl tops_cmd_impl = { Modified: brlcad/branches/gedplugins/src/libged/view/CMakeLists.txt =================================================================== --- brlcad/branches/gedplugins/src/libged/view/CMakeLists.txt 2020-07-22 00:38:30 UTC (rev 76401) +++ brlcad/branches/gedplugins/src/libged/view/CMakeLists.txt 2020-07-22 01:27:01 UTC (rev 76402) @@ -9,6 +9,7 @@ set(VIEW_SRCS aet.c #data_lines.c + center.cpp eye.c quat.c size.c Modified: brlcad/branches/gedplugins/src/libged/view/center.cpp =================================================================== --- brlcad/branches/gedplugins/src/libged/view/center.cpp 2020-07-22 00:38:30 UTC (rev 76401) +++ brlcad/branches/gedplugins/src/libged/view/center.cpp 2020-07-22 01:27:01 UTC (rev 76402) @@ -35,10 +35,10 @@ #include <string.h> #include "../ged_private.h" +#include "./ged_view.h" - int -ged_center(struct ged *gedp, int argc, const char *argv[]) +ged_center_core(struct ged *gedp, int argc, const char *argv[]) { point_t center; static const char *usage = "[-v] | [x y z]"; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. _______________________________________________ BRL-CAD Source Commits mailing list brlcad-commits@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/brlcad-commits