00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039 #ifndef lint
00040 static const char RCSid[] = "@(#)$Header: /cvsroot/brlcad/brlcad/src/librt/wdb_obj.c,v 14.37 2006/09/16 02:04:26 lbutler Exp $ (ARL)";
00041 #endif
00042
00043 #include "common.h"
00044
00045 #include <stdlib.h>
00046 #include <ctype.h>
00047 #ifdef HAVE_STRING_H
00048 # include <string.h>
00049 #else
00050 # include <strings.h>
00051 #endif
00052 #include <math.h>
00053 #if defined(HAVE_FCNTL_H)
00054 # include <fcntl.h>
00055 #endif
00056 #if defined(HAVE_ERRNO_H)
00057 # include <errno.h>
00058 #else
00059 # if defined(HAVE_SYS_ERRNO_H)
00060 # include <sys/errno.h>
00061 # endif
00062 #endif
00063 #if defined(HAVE_UNISTD_H)
00064 # include <unistd.h>
00065 #endif
00066
00067 #include "tcl.h"
00068 #include "machine.h"
00069 #include "cmd.h"
00070 #include "vmath.h"
00071 #include "bn.h"
00072 #include "db.h"
00073 #include "mater.h"
00074 #include "rtgeom.h"
00075 #include "raytrace.h"
00076 #include "wdb.h"
00077
00078 #include "./debug.h"
00079
00080
00081
00082
00083
00084
00085 #define USE_RT_COMB_IFREE 0
00086
00087
00088 extern void rt_insert_color( struct mater *newp );
00089
00090 #define WDB_TCL_READ_ERR { \
00091 Tcl_AppendResult(interp, "Database read error, aborting.\n", (char *)NULL); \
00092 }
00093
00094 #define WDB_TCL_READ_ERR_return { \
00095 WDB_TCL_READ_ERR; \
00096 return TCL_ERROR; }
00097
00098 #define WDB_TCL_WRITE_ERR { \
00099 Tcl_AppendResult(interp, "Database write error, aborting.\n", (char *)NULL); \
00100 WDB_TCL_ERROR_RECOVERY_SUGGESTION; }
00101
00102 #define WDB_TCL_WRITE_ERR_return { \
00103 WDB_TCL_WRITE_ERR; \
00104 return TCL_ERROR; }
00105
00106 #define WDB_TCL_ALLOC_ERR { \
00107 Tcl_AppendResult(interp, "\
00108 An error has occured while adding a new object to the database.\n", (char *)NULL); \
00109 WDB_TCL_ERROR_RECOVERY_SUGGESTION; }
00110
00111 #define WDB_TCL_ALLOC_ERR_return { \
00112 WDB_TCL_ALLOC_ERR; \
00113 return TCL_ERROR; }
00114
00115 #define WDB_TCL_DELETE_ERR(_name){ \
00116 Tcl_AppendResult(interp, "An error has occurred while deleting '", _name,\
00117 "' from the database.\n", (char *)NULL);\
00118 WDB_TCL_ERROR_RECOVERY_SUGGESTION; }
00119
00120 #define WDB_TCL_DELETE_ERR_return(_name){ \
00121 WDB_TCL_DELETE_ERR(_name); \
00122 return TCL_ERROR; }
00123
00124
00125 #define WDB_TCL_ERROR_RECOVERY_SUGGESTION\
00126 Tcl_AppendResult(interp, "\
00127 The in-memory table of contents may not match the status of the on-disk\n\
00128 database. The on-disk database should still be intact. For safety,\n\
00129 you should exit now, and resolve the I/O problem, before continuing.\n", (char *)NULL)
00130
00131 #define WDB_READ_ERR { \
00132 bu_log("Database read error, aborting\n"); }
00133
00134 #define WDB_READ_ERR_return { \
00135 WDB_READ_ERR; \
00136 return; }
00137
00138 #define WDB_WRITE_ERR { \
00139 bu_log("Database write error, aborting.\n"); \
00140 WDB_ERROR_RECOVERY_SUGGESTION; }
00141
00142 #define WDB_WRITE_ERR_return { \
00143 WDB_WRITE_ERR; \
00144 return; }
00145
00146
00147 #define WDB_ALLOC_ERR { \
00148 bu_log("\nAn error has occured while adding a new object to the database.\n"); \
00149 WDB_ERROR_RECOVERY_SUGGESTION; }
00150
00151 #define WDB_ALLOC_ERR_return { \
00152 WDB_ALLOC_ERR; \
00153 return; }
00154
00155
00156 #define WDB_ERROR_RECOVERY_SUGGESTION\
00157 bu_log(WDB_ERROR_RECOVERY_MESSAGE)
00158
00159 #define WDB_ERROR_RECOVERY_MESSAGE "\
00160 The in-memory table of contents may not match the status of the on-disk\n\
00161 database. The on-disk database should still be intact. For safety,\n\
00162 you should exit now, and resolve the I/O problem, before continuing.\n"
00163
00164 #define WDB_TCL_CHECK_READ_ONLY \
00165 if (wdbp->dbip->dbi_read_only) {\
00166 Tcl_AppendResult(interp, "Sorry, this database is READ-ONLY\n", (char *)NULL); \
00167 return TCL_ERROR; \
00168 }
00169
00170 #define WDB_MAX_LEVELS 12
00171 #define WDB_CPEVAL 0
00172 #define WDB_LISTPATH 1
00173 #define WDB_LISTEVAL 2
00174 #define WDB_EVAL_ONLY 3
00175
00176 struct wdb_trace_data {
00177 Tcl_Interp *wtd_interp;
00178 struct db_i *wtd_dbip;
00179 struct directory *wtd_path[WDB_MAX_LEVELS];
00180 struct directory *wtd_obj[WDB_MAX_LEVELS];
00181 mat_t wtd_xform;
00182 int wtd_objpos;
00183 int wtd_prflag;
00184 int wtd_flag;
00185 };
00186
00187 struct wdb_killtree_data {
00188 Tcl_Interp *interp;
00189 int notify;
00190 };
00191
00192
00193 extern int rt_tcl_rt(ClientData clientData, Tcl_Interp *interp, int argc, const char **argv);
00194 extern int rt_tcl_import_from_path(Tcl_Interp *interp, struct rt_db_internal *ip, const char *path, struct rt_wdb *wdb);
00195 extern void rt_generic_make(const struct rt_functab *ftp, struct rt_db_internal *intern, double diameter);
00196
00197
00198 extern int wdb_comb_std_tcl(ClientData clientData, Tcl_Interp *interp, int argc, char **argv);
00199
00200
00201 extern int rt_bot_sort_faces( struct rt_bot_internal *bot, int tris_per_piece );
00202 extern int rt_bot_decimate( struct rt_bot_internal *bot, fastf_t max_chord_error, fastf_t max_normal_error, fastf_t min_edge_length );
00203
00204
00205 HIDDEN int db5_scan(struct db_i *dbip, void (*handler) (struct db_i *, const struct db5_raw_internal *, long int, genptr_t), genptr_t client_data);
00206
00207 int wdb_init_obj(Tcl_Interp *interp, struct rt_wdb *wdbp, const char *oname);
00208 int wdb_get_tcl(ClientData clientData, Tcl_Interp *interp, int argc, char **argv);
00209 int wdb_get_type_tcl(ClientData clientData, Tcl_Interp *interp, int argc, char **argv);
00210 int wdb_attr_tcl(ClientData clientData, Tcl_Interp *interp, int argc, char **argv);
00211 int wdb_pathsum_cmd(struct rt_wdb *wdbp, Tcl_Interp *interp, int argc, char **argv);
00212
00213 static int wdb_open_tcl(ClientData clientData, Tcl_Interp *interp, int argc, const char **argv);
00214 #if 0
00215 static int wdb_close_tcl();
00216 #endif
00217 static int wdb_decode_dbip(Tcl_Interp *interp, const char *dbip_string, struct db_i **dbipp);
00218 struct db_i *wdb_prep_dbip(Tcl_Interp *interp, const char *filename);
00219
00220 static int wdb_cmd(ClientData clientData, Tcl_Interp *interp, int argc, char **argv);
00221 static int wdb_match_tcl(ClientData clientData, Tcl_Interp *interp, int argc, char **argv);
00222 static int wdb_put_tcl(ClientData clientData, Tcl_Interp *interp, int argc, char **argv);
00223 static int wdb_adjust_tcl(ClientData clientData, Tcl_Interp *interp, int argc, char **argv);
00224 static int wdb_form_tcl(ClientData clientData, Tcl_Interp *interp, int argc, char **argv);
00225 static int wdb_tops_tcl(ClientData clientData, Tcl_Interp *interp, int argc, char **argv);
00226 static int wdb_rt_gettrees_tcl(ClientData clientData, Tcl_Interp *interp, int argc, char **argv);
00227 static int wdb_shells_tcl(ClientData clientData, Tcl_Interp *interp, int argc, char **argv);
00228 static int wdb_dump_tcl(ClientData clientData, Tcl_Interp *interp, int argc, char **argv);
00229 static int wdb_dbip_tcl(ClientData clientData, Tcl_Interp *interp, int argc, char **argv);
00230 static int wdb_ls_tcl(ClientData clientData, Tcl_Interp *interp, int argc, char **argv);
00231 static int wdb_list_tcl(ClientData clientData, Tcl_Interp *interp, int argc, char **argv);
00232 static int wdb_pathsum_tcl(ClientData clientData, Tcl_Interp *interp, int argc, char **argv);
00233 static int wdb_expand_tcl(ClientData clientData, Tcl_Interp *interp, int argc, char **argv);
00234 static int wdb_kill_tcl(ClientData clientData, Tcl_Interp *interp, int argc, char **argv);
00235 static int wdb_killall_tcl(ClientData clientData, Tcl_Interp *interp, int argc, char **argv);
00236 static int wdb_killtree_tcl(ClientData clientData, Tcl_Interp *interp, int argc, char **argv);
00237 static void wdb_killtree_callback(struct db_i *dbip, register struct directory *dp, genptr_t ptr);
00238 static int wdb_copy_tcl(ClientData clientData, Tcl_Interp *interp, int argc, char **argv);
00239 static int wdb_move_tcl(ClientData clientData, Tcl_Interp *interp, int argc, char **argv);
00240 static int wdb_move_all_tcl(ClientData clientData, Tcl_Interp *interp, int argc, char **argv);
00241 static int wdb_concat_tcl(ClientData clientData, Tcl_Interp *interp, int argc, char **argv);
00242 static int wdb_copyeval_tcl(ClientData clientData, Tcl_Interp *interp, int argc, char **argv);
00243 static int wdb_dup_tcl(ClientData clientData, Tcl_Interp *interp, int argc, char **argv);
00244 static int wdb_group_tcl(ClientData clientData, Tcl_Interp *interp, int argc, char **argv);
00245 static int wdb_remove_tcl(ClientData clientData, Tcl_Interp *interp, int argc, char **argv);
00246 static int wdb_region_tcl(ClientData clientData, Tcl_Interp *interp, int argc, char **argv);
00247 static int wdb_comb_tcl(ClientData clientData, Tcl_Interp *interp, int argc, char **argv);
00248 static int wdb_facetize_tcl(ClientData clientData, Tcl_Interp *interp, int argc, char **argv);
00249 static int wdb_find_tcl(ClientData clientData, Tcl_Interp *interp, int argc, char **argv);
00250 static int wdb_which_tcl(ClientData clientData, Tcl_Interp *interp, int argc, char **argv);
00251 static int wdb_title_tcl(ClientData clientData, Tcl_Interp *interp, int argc, char **argv);
00252 static int wdb_track_tcl(ClientData clientData, Tcl_Interp *interp, int argc, char **argv);
00253 static int wdb_tree_tcl(ClientData clientData, Tcl_Interp *interp, int argc, char **argv);
00254 static int wdb_color_tcl(ClientData clientData, Tcl_Interp *interp, int argc, char **argv);
00255 static int wdb_prcolor_tcl(ClientData clientData, Tcl_Interp *interp, int argc, char **argv);
00256 static int wdb_tol_tcl(ClientData clientData, Tcl_Interp *interp, int argc, char **argv);
00257 static int wdb_push_tcl(ClientData clientData, Tcl_Interp *interp, int argc, char **argv);
00258 static int wdb_whatid_tcl(ClientData clientData, Tcl_Interp *interp, int argc, char **argv);
00259 static int wdb_keep_tcl(ClientData clientData, Tcl_Interp *interp, int argc, char **argv);
00260 static int wdb_cat_tcl(ClientData clientData, Tcl_Interp *interp, int argc, char **argv);
00261 static int wdb_instance_tcl(ClientData clientData, Tcl_Interp *interp, int argc, char **argv);
00262 static int wdb_observer_tcl(ClientData clientData, Tcl_Interp *interp, int argc, char **argv);
00263 static int wdb_reopen_tcl(ClientData clientData, Tcl_Interp *interp, int argc, char **argv);
00264 static int wdb_make_bb_tcl(ClientData clientData, Tcl_Interp *interp, int argc, char **argv);
00265 static int wdb_make_name_tcl(ClientData clientData, Tcl_Interp *interp, int argc, char **argv);
00266 static int wdb_units_tcl(ClientData clientData, Tcl_Interp *interp, int argc, char **argv);
00267 static int wdb_hide_tcl(ClientData clientData, Tcl_Interp *interp, int argc, char **argv);
00268 static int wdb_unhide_tcl(ClientData clientData, Tcl_Interp *interp, int argc, char **argv);
00269 static int wdb_xpush_tcl(ClientData clientData, Tcl_Interp *interp, int argc, char **argv);
00270 static int wdb_smooth_bot_tcl(ClientData clientData, Tcl_Interp *interp, int argc, char **argv);
00271 static int wdb_showmats_tcl(ClientData clientData, Tcl_Interp *interp, int argc, char **argv);
00272 static int wdb_nmg_collapse_tcl(ClientData clientData, Tcl_Interp *interp, int argc, char **argv);
00273 static int wdb_nmg_simplify_tcl(ClientData clientData, Tcl_Interp *interp, int argc, char **argv);
00274 static int wdb_summary_tcl(ClientData clientData, Tcl_Interp *interp, int argc, char **argv);
00275 static int wdb_pathlist_tcl(ClientData clientData, Tcl_Interp *interp, int argc, char **argv);
00276 static int wdb_lt_tcl(ClientData clientData, Tcl_Interp *interp, int argc, char **argv);
00277 static int wdb_version_tcl(ClientData clientData, Tcl_Interp *interp, int argc, char **argv);
00278 static int wdb_binary_tcl(ClientData clientData, Tcl_Interp *interp, int argc, char **argv);
00279 static int wdb_bot_face_sort_tcl(ClientData clientData, Tcl_Interp *interp, int argc, char **argv);
00280 static int wdb_bot_decimate_tcl(ClientData clientData, Tcl_Interp *interp, int argc, char **argv);
00281 static int wdb_move_arb_edge_tcl(ClientData clientData, Tcl_Interp *interp, int argc, char **argv);
00282 static int wdb_move_arb_face_tcl(ClientData clientData, Tcl_Interp *interp, int argc, char **argv);
00283 static int wdb_rotate_arb_face_tcl(ClientData clientData, Tcl_Interp *interp, int argc, char **argv);
00284 static int wdb_rmap_tcl(ClientData clientData, Tcl_Interp *interp, int argc, char **argv);
00285 static int wdb_importFg4Section_tcl(ClientData clientData, Tcl_Interp *interp, int argc, char **argv);
00286 static int wdb_orotate_tcl(ClientData clientData, Tcl_Interp *interp, int argc, char **argv);
00287 static int wdb_oscale_tcl(ClientData clientData, Tcl_Interp *interp, int argc, char **argv);
00288 static int wdb_otranslate_tcl(ClientData clientData, Tcl_Interp *interp, int argc, char **argv);
00289 static int wdb_ocenter_tcl(ClientData clientData, Tcl_Interp *interp, int argc, char **argv);
00290
00291 void wdb_deleteProc(ClientData clientData);
00292 static void wdb_deleteProc_rt(ClientData clientData);
00293
00294 static void wdb_do_trace(struct db_i *dbip, struct rt_comb_internal *comb, union tree *comb_leaf, genptr_t user_ptr1, genptr_t user_ptr2, genptr_t user_ptr3);
00295 static void wdb_trace(register struct directory *dp, int pathpos, const fastf_t *old_xlate, struct wdb_trace_data *wtdp);
00296
00297 int wdb_cmpdirname(const genptr_t a, const genptr_t b);
00298 void wdb_vls_col_item(struct bu_vls *str, register char *cp, int *ccp, int *clp);
00299 void wdb_vls_col_eol(struct bu_vls *str, int *ccp, int *clp);
00300 void wdb_vls_col_pr4v(struct bu_vls *vls, struct directory **list_of_names, int num_in_list, int no_decorate);
00301 void wdb_vls_long_dpp(struct bu_vls *vls, struct directory **list_of_names, int num_in_list, int aflag, int cflag, int rflag, int sflag);
00302 void wdb_vls_line_dpp(struct bu_vls *vls, struct directory **list_of_names, int num_in_list, int aflag, int cflag, int rflag, int sflag);
00303 void wdb_do_list(struct db_i *dbip, Tcl_Interp *interp, struct bu_vls *outstrp, register struct directory *dp, int verbose);
00304 struct directory ** wdb_getspace(struct db_i *dbip, register int num_entries);
00305 struct directory *wdb_combadd(Tcl_Interp *interp, struct db_i *dbip, register struct directory *objp, char *combname, int region_flag, int relation, int ident, int air, struct rt_wdb *wdbp);
00306 void wdb_identitize(struct directory *dp, struct db_i *dbip, Tcl_Interp *interp);
00307 static void wdb_dir_summary(struct db_i *dbip, Tcl_Interp *interp, int flag);
00308 static struct directory ** wdb_dir_getspace(struct db_i *dbip, register int num_entries);
00309 static union tree *wdb_pathlist_leaf_func(struct db_tree_state *tsp, struct db_full_path *pathp, struct rt_db_internal *ip, genptr_t client_data);
00310 HIDDEN union tree *facetize_region_end(struct db_tree_state *tsp, struct db_full_path *pathp, union tree *curtree, genptr_t client_data);
00311 static int pathListNoLeaf = 0;
00312
00313
00314 static struct bu_cmdtab wdb_cmds[] = {
00315 {"adjust", wdb_adjust_tcl},
00316 {"attr", wdb_attr_tcl},
00317 {"binary", wdb_binary_tcl},
00318 {"bot_face_sort", wdb_bot_face_sort_tcl},
00319 {"bot_decimate", wdb_bot_decimate_tcl},
00320 {"c", wdb_comb_std_tcl},
00321 {"cat", wdb_cat_tcl},
00322 #if 0
00323 {"close", wdb_close_tcl},
00324 #endif
00325 {"color", wdb_color_tcl},
00326 {"comb", wdb_comb_tcl},
00327 {"concat", wdb_concat_tcl},
00328 {"copyeval", wdb_copyeval_tcl},
00329 {"cp", wdb_copy_tcl},
00330 {"dbip", wdb_dbip_tcl},
00331 {"dump", wdb_dump_tcl},
00332 {"dup", wdb_dup_tcl},
00333 {"expand", wdb_expand_tcl},
00334 {"facetize", wdb_facetize_tcl},
00335 {"find", wdb_find_tcl},
00336 {"form", wdb_form_tcl},
00337 {"g", wdb_group_tcl},
00338 {"get", wdb_get_tcl},
00339 {"get_type", wdb_get_type_tcl},
00340 {"hide", wdb_hide_tcl},
00341 {"i", wdb_instance_tcl},
00342 {"importFg4Section", wdb_importFg4Section_tcl},
00343 {"keep", wdb_keep_tcl},
00344 {"kill", wdb_kill_tcl},
00345 {"killall", wdb_killall_tcl},
00346 {"killtree", wdb_killtree_tcl},
00347 {"l", wdb_list_tcl},
00348 {"listeval", wdb_pathsum_tcl},
00349 {"ls", wdb_ls_tcl},
00350 {"lt", wdb_lt_tcl},
00351 {"make_bb", wdb_make_bb_tcl},
00352 {"make_name", wdb_make_name_tcl},
00353 {"match", wdb_match_tcl},
00354 {"move_arb_edge", wdb_move_arb_edge_tcl},
00355 {"move_arb_face", wdb_move_arb_face_tcl},
00356 {"mv", wdb_move_tcl},
00357 {"mvall", wdb_move_all_tcl},
00358 {"nmg_collapse",wdb_nmg_collapse_tcl},
00359 {"nmg_simplify",wdb_nmg_simplify_tcl},
00360 {"observer", wdb_observer_tcl},
00361 {"ocenter", wdb_ocenter_tcl},
00362 {"orotate", wdb_orotate_tcl},
00363 {"oscale", wdb_oscale_tcl},
00364 {"otranslate", wdb_otranslate_tcl},
00365 {"open", wdb_reopen_tcl},
00366 {"pathlist", wdb_pathlist_tcl},
00367 {"paths", wdb_pathsum_tcl},
00368 {"prcolor", wdb_prcolor_tcl},
00369 {"push", wdb_push_tcl},
00370 {"put", wdb_put_tcl},
00371 {"r", wdb_region_tcl},
00372 {"rm", wdb_remove_tcl},
00373 {"rmap", wdb_rmap_tcl},
00374 {"rotate_arb_face", wdb_rotate_arb_face_tcl},
00375 {"rt_gettrees", wdb_rt_gettrees_tcl},
00376 {"shells", wdb_shells_tcl},
00377 {"showmats", wdb_showmats_tcl},
00378 {"smooth_bot", wdb_smooth_bot_tcl},
00379 {"summary", wdb_summary_tcl},
00380 {"title", wdb_title_tcl},
00381 {"tol", wdb_tol_tcl},
00382 {"tops", wdb_tops_tcl},
00383 {"track", wdb_track_tcl},
00384 {"tree", wdb_tree_tcl},
00385 {"unhide", wdb_unhide_tcl},
00386 {"units", wdb_units_tcl},
00387 {"version", wdb_version_tcl},
00388 {"whatid", wdb_whatid_tcl},
00389 {"whichair", wdb_which_tcl},
00390 {"whichid", wdb_which_tcl},
00391 {"xpush", wdb_xpush_tcl},
00392 #if 0
00393
00394 {"comb_color", wdb_comb_color_tcl},
00395 {"copymat", wdb_copymat_tcl},
00396 {"getmat", wdb_getmat_tcl},
00397 {"putmat", wdb_putmat_tcl},
00398 {"which_shader", wdb_which_shader_tcl},
00399 {"rcodes", wdb_rcodes_tcl},
00400 {"wcodes", wdb_wcodes_tcl},
00401 {"rmater", wdb_rmater_tcl},
00402 {"wmater", wdb_wmater_tcl},
00403 {"analyze", wdb_analyze_tcl},
00404 {"inside", wdb_inside_tcl},
00405 #endif
00406 {(char *)NULL, (int (*)())0 }
00407 };
00408
00409 int
00410 Wdb_Init(Tcl_Interp *interp)
00411 {
00412 (void)Tcl_CreateCommand(interp, (const char *)"wdb_open", wdb_open_tcl,
00413 (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL);
00414
00415 return TCL_OK;
00416 }
00417
00418
00419
00420
00421
00422
00423
00424
00425
00426
00427 static int
00428 wdb_cmd(ClientData clientData, Tcl_Interp *interp, int argc, char **argv)
00429 {
00430 return bu_cmd(clientData, interp, argc, argv, wdb_cmds, 1);
00431 }
00432
00433
00434
00435
00436 void
00437 wdb_deleteProc(ClientData clientData)
00438 {
00439 struct rt_wdb *wdbp = (struct rt_wdb *)clientData;
00440
00441
00442 bu_observer_free(&wdbp->wdb_observers);
00443
00444
00445 dgo_impending_wdb_close(wdbp, wdbp->wdb_interp);
00446
00447 RT_CK_WDB(wdbp);
00448 BU_LIST_DEQUEUE(&wdbp->l);
00449 bu_vls_free(&wdbp->wdb_name);
00450 wdb_close(wdbp);
00451 }
00452
00453
00454
00455
00456
00457 int
00458 wdb_create_cmd(Tcl_Interp *interp,
00459 struct rt_wdb *wdbp,
00460 const char *oname)
00461 {
00462 if (wdbp == RT_WDB_NULL) {
00463 Tcl_AppendResult(interp, "wdb_init_cmd ", oname, " failed", NULL);
00464 return TCL_ERROR;
00465 }
00466
00467
00468
00469 (void)Tcl_CreateCommand(interp, oname, (Tcl_CmdProc *)wdb_cmd,
00470 (ClientData)wdbp, wdb_deleteProc);
00471
00472
00473 Tcl_AppendResult(interp, oname, (char *)NULL);
00474
00475 return TCL_OK;
00476 }
00477
00478
00479
00480
00481
00482 int
00483 wdb_init_obj(Tcl_Interp *interp,
00484 struct rt_wdb *wdbp,
00485 const char *oname)
00486 {
00487 if (wdbp == RT_WDB_NULL) {
00488 Tcl_AppendResult(interp, "wdb_open ", oname, " failed (wdb_init_obj)", NULL);
00489 return TCL_ERROR;
00490 }
00491
00492
00493 bu_vls_init(&wdbp->wdb_name);
00494 bu_vls_strcpy(&wdbp->wdb_name, oname);
00495
00496 #if 0
00497
00498
00499 wdbp->wdb_ttol.magic = RT_TESS_TOL_MAGIC;
00500 wdbp->wdb_ttol.abs = 0.0;
00501 wdbp->wdb_ttol.rel = 0.01;
00502 wdbp->wdb_ttol.norm = 0.0;
00503
00504 wdbp->wdb_tol.magic = BN_TOL_MAGIC;
00505 wdbp->wdb_tol.dist = 0.005;
00506 wdbp->wdb_tol.dist_sq = wdbp->wdb_tol.dist * wdbp->wdb_tol.dist;
00507 wdbp->wdb_tol.perp = 1e-6;
00508 wdbp->wdb_tol.para = 1 - wdbp->wdb_tol.perp;
00509 #endif
00510
00511
00512 wdbp->wdb_initial_tree_state = rt_initial_tree_state;
00513 wdbp->wdb_initial_tree_state.ts_ttol = &wdbp->wdb_ttol;
00514 wdbp->wdb_initial_tree_state.ts_tol = &wdbp->wdb_tol;
00515
00516
00517 wdbp->wdb_item_default = 1000;
00518 wdbp->wdb_air_default = 0;
00519 wdbp->wdb_mat_default = 1;
00520 wdbp->wdb_los_default = 100;
00521
00522
00523 wdbp->wdb_resp = &rt_uniresource;
00524
00525 BU_LIST_INIT(&wdbp->wdb_observers.l);
00526 wdbp->wdb_interp = interp;
00527
00528
00529 BU_LIST_APPEND(&rt_g.rtg_headwdb.l,&wdbp->l);
00530
00531 return TCL_OK;
00532 }
00533
00534
00535
00536
00537
00538
00539
00540
00541
00542
00543
00544
00545
00546
00547
00548
00549
00550
00551
00552
00553
00554
00555
00556
00557 static int
00558 wdb_open_tcl(ClientData clientData,
00559 Tcl_Interp *interp,
00560 int argc,
00561 const char **argv)
00562 {
00563 struct rt_wdb *wdbp;
00564 int ret;
00565
00566 if (argc == 1) {
00567
00568 for (BU_LIST_FOR(wdbp, rt_wdb, &rt_g.rtg_headwdb.l))
00569 Tcl_AppendResult(interp, bu_vls_addr(&wdbp->wdb_name), " ", (char *)NULL);
00570
00571 return TCL_OK;
00572 }
00573
00574 if (argc < 3 || 4 < argc) {
00575 #if 0
00576 bu_vls_init(&vls);
00577 bu_vls_printf(&vls, "helplib wdb_open");
00578 Tcl_Eval(interp, bu_vls_addr(&vls));
00579 bu_vls_free(&vls);
00580 return TCL_ERROR;
00581 #else
00582 Tcl_AppendResult(interp, "\
00583 Usage: wdb_open\n\
00584 wdb_open newprocname file filename\n\
00585 wdb_open newprocname disk $dbip\n\
00586 wdb_open newprocname disk_append $dbip\n\
00587 wdb_open newprocname inmem $dbip\n\
00588 wdb_open newprocname inmem_append $dbip\n\
00589 wdb_open newprocname db filename\n\
00590 wdb_open newprocname filename\n",
00591 NULL);
00592 return TCL_ERROR;
00593 #endif
00594 }
00595
00596
00597 (void)Tcl_DeleteCommand(interp, argv[1]);
00598
00599 if (argc == 3 || strcmp(argv[2], "db") == 0) {
00600 struct db_i *dbip;
00601 int i;
00602
00603 if (argc == 3)
00604 i = 2;
00605 else
00606 i = 3;
00607
00608 if ((dbip = wdb_prep_dbip(interp, argv[i])) == DBI_NULL)
00609 return TCL_ERROR;
00610 RT_CK_DBI_TCL(interp,dbip);
00611
00612 wdbp = wdb_dbopen(dbip, RT_WDB_TYPE_DB_DISK);
00613 } else if (strcmp(argv[2], "file") == 0) {
00614 wdbp = wdb_fopen( argv[3] );
00615 } else {
00616 struct db_i *dbip;
00617
00618 if (wdb_decode_dbip(interp, argv[3], &dbip) != TCL_OK)
00619 return TCL_ERROR;
00620
00621 if (strcmp( argv[2], "disk" ) == 0)
00622 wdbp = wdb_dbopen(dbip, RT_WDB_TYPE_DB_DISK);
00623 else if (strcmp(argv[2], "disk_append") == 0)
00624 wdbp = wdb_dbopen(dbip, RT_WDB_TYPE_DB_DISK_APPEND_ONLY);
00625 else if (strcmp( argv[2], "inmem" ) == 0)
00626 wdbp = wdb_dbopen(dbip, RT_WDB_TYPE_DB_INMEM);
00627 else if (strcmp( argv[2], "inmem_append" ) == 0)
00628 wdbp = wdb_dbopen(dbip, RT_WDB_TYPE_DB_INMEM_APPEND_ONLY);
00629 else {
00630 Tcl_AppendResult(interp, "wdb_open ", argv[2],
00631 " target type not recognized", NULL);
00632 return TCL_ERROR;
00633 }
00634 }
00635
00636 if ((ret = wdb_init_obj(interp, wdbp, argv[1])) != TCL_OK)
00637 return ret;
00638
00639 return wdb_create_cmd(interp, wdbp, argv[1]);
00640 }
00641
00642 int
00643 wdb_decode_dbip(Tcl_Interp *interp, const char *dbip_string, struct db_i **dbipp)
00644 {
00645
00646 *dbipp = (struct db_i *)atol(dbip_string);
00647
00648
00649 RT_CK_DBI_TCL(interp,*dbipp);
00650
00651 return TCL_OK;
00652 }
00653
00654
00655
00656
00657 struct db_i *
00658 wdb_prep_dbip(Tcl_Interp *interp, const char *filename)
00659 {
00660 struct db_i *dbip;
00661
00662
00663 if (((dbip = db_open(filename, "r+w")) == DBI_NULL) &&
00664 ((dbip = db_open(filename, "r" )) == DBI_NULL)) {
00665
00666 #if defined(HAVE_ACCESS)
00667
00668
00669
00670 if (access(filename, R_OK|W_OK) != 0 && errno != ENOENT) {
00671 perror(filename);
00672 return DBI_NULL;
00673 }
00674 #endif
00675
00676
00677 if ((dbip = db_create(filename, 5)) == DBI_NULL) {
00678 Tcl_AppendResult(interp,
00679 "wdb_open: failed to create ", filename,
00680 (char *)NULL);
00681 if (dbip == DBI_NULL)
00682 Tcl_AppendResult(interp,
00683 "opendb: no database is currently opened!", \
00684 (char *)NULL);
00685
00686 return DBI_NULL;
00687 }
00688 } else
00689
00690 db_dirbuild(dbip);
00691
00692
00693 return dbip;
00694 }
00695
00696
00697 #if 0
00698 int
00699 wdb_close_cmd(struct rt_wdb *wdbp,
00700 Tcl_Interp *interp,
00701 int argc,
00702 char **argv)
00703 {
00704 struct bu_vls vls;
00705
00706 if (argc != 1) {
00707 bu_vls_init(&vls);
00708 bu_vls_printf(&vls, "helplib wdb_close");
00709 Tcl_Eval(interp, bu_vls_addr(&vls));
00710 bu_vls_free(&vls);
00711 return TCL_ERROR;
00712 }
00713
00714
00715
00716
00717
00718
00719 Tcl_DeleteCommand(interp, bu_vls_addr(&wdbp->wdb_name));
00720
00721 return TCL_OK;
00722 }
00723
00724
00725
00726
00727
00728
00729
00730 static int
00731 wdb_close_tcl(ClientData clientData,
00732 Tcl_Interp *interp,
00733 int argc,
00734 char **argv)
00735 {
00736 struct rt_wdb *wdbp = (struct rt_wdb *)clientData;
00737
00738 return wdb_close_cmd(wdbp, interp, argc-1, argv+1);
00739 }
00740 #endif
00741
00742 int
00743 wdb_reopen_cmd(struct rt_wdb *wdbp,
00744 Tcl_Interp *interp,
00745 int argc,
00746 char **argv)
00747 {
00748 struct db_i *dbip;
00749 struct bu_vls vls;
00750
00751
00752 if (argc == 1) {
00753 Tcl_AppendResult(interp, wdbp->dbip->dbi_filename, (char *)NULL);
00754 return TCL_OK;
00755 }
00756
00757
00758 if (argc == 2) {
00759 if ((dbip = wdb_prep_dbip(interp, argv[1])) == DBI_NULL) {
00760 return TCL_ERROR;
00761 }
00762
00763
00764
00765 dgo_zapall(wdbp, interp);
00766
00767
00768 db_close(wdbp->dbip);
00769
00770 wdbp->dbip = dbip;
00771
00772 Tcl_AppendResult(interp, wdbp->dbip->dbi_filename, (char *)NULL);
00773 return TCL_OK;
00774 }
00775
00776 bu_vls_init(&vls);
00777 bu_vls_printf(&vls, "helplib_alias wdb_reopen %s", argv[0]);
00778 Tcl_Eval(interp, bu_vls_addr(&vls));
00779 bu_vls_free(&vls);
00780 return TCL_ERROR;
00781 }
00782
00783
00784
00785
00786
00787
00788 static int
00789 wdb_reopen_tcl(ClientData clientData,
00790 Tcl_Interp *interp,
00791 int argc,
00792 char **argv)
00793 {
00794 struct rt_wdb *wdbp = (struct rt_wdb *)clientData;
00795
00796 return wdb_reopen_cmd(wdbp, interp, argc-1, argv+1);
00797 }
00798
00799 int
00800 wdb_match_cmd(struct rt_wdb *wdbp,
00801 Tcl_Interp *interp,
00802 int argc,
00803 char **argv)
00804 {
00805 struct bu_vls matches;
00806
00807 RT_CK_WDB_TCL(interp,wdbp);
00808
00809
00810
00811 if (wdbp->dbip == 0) {
00812 Tcl_AppendResult( interp, "this database does not support lookup operations" );
00813 return TCL_ERROR;
00814 }
00815
00816 bu_vls_init(&matches);
00817 for (++argv; *argv != NULL; ++argv) {
00818 if (db_regexp_match_all(&matches, wdbp->dbip, *argv) > 0)
00819 bu_vls_strcat(&matches, " ");
00820 }
00821 bu_vls_trimspace(&matches);
00822 Tcl_AppendResult(interp, bu_vls_addr(&matches), (char *)NULL);
00823 bu_vls_free(&matches);
00824 return TCL_OK;
00825 }
00826
00827
00828
00829
00830
00831
00832
00833
00834
00835
00836 static int
00837 wdb_match_tcl(ClientData clientData,
00838 Tcl_Interp *interp,
00839 int argc,
00840 char **argv)
00841 {
00842 struct rt_wdb *wdbp = (struct rt_wdb *)clientData;
00843
00844 return wdb_match_cmd(wdbp, interp, argc-1, argv+1);
00845 }
00846
00847 int
00848 wdb_get_cmd(struct rt_wdb *wdbp,
00849 Tcl_Interp *interp,
00850 int argc,
00851 char **argv)
00852 {
00853 int status;
00854 struct rt_db_internal intern;
00855
00856 if (argc < 2 || argc > 3) {
00857 struct bu_vls vls;
00858
00859 bu_vls_init(&vls);
00860 bu_vls_printf(&vls, "helplib_alias wdb_get %s", argv[0]);
00861 Tcl_Eval(interp, bu_vls_addr(&vls));
00862 bu_vls_free(&vls);
00863 return TCL_ERROR;
00864 }
00865
00866
00867
00868 if (wdbp->dbip == 0) {
00869 Tcl_AppendResult(interp,
00870 "db does not support lookup operations",
00871 (char *)NULL);
00872 return TCL_ERROR;
00873 }
00874
00875 if (rt_tcl_import_from_path(interp, &intern, argv[1], wdbp) == TCL_ERROR)
00876 return TCL_ERROR;
00877
00878 status = intern.idb_meth->ft_tclget(interp, &intern, argv[2]);
00879 rt_db_free_internal(&intern, &rt_uniresource);
00880 return status;
00881 }
00882
00883
00884
00885
00886
00887
00888
00889
00890
00891
00892
00893
00894
00895
00896 int
00897 wdb_get_tcl(ClientData clientData,
00898 Tcl_Interp *interp,
00899 int argc,
00900 char **argv)
00901 {
00902 struct rt_wdb *wdbp = (struct rt_wdb *)clientData;
00903
00904 return wdb_get_cmd(wdbp, interp, argc-1, argv+1);
00905 }
00906
00907 int
00908 wdb_get_type_cmd(struct rt_wdb *wdbp,
00909 Tcl_Interp *interp,
00910 int argc,
00911 char **argv)
00912 {
00913 struct rt_db_internal intern;
00914 int type;
00915
00916 if (argc != 2) {
00917 struct bu_vls vls;
00918
00919 bu_vls_init(&vls);
00920 bu_vls_printf(&vls, "helplib_alias wdb_get_type %s", argv[0]);
00921 Tcl_Eval(interp, bu_vls_addr(&vls));
00922 bu_vls_free(&vls);
00923
00924 return TCL_ERROR;
00925 }
00926
00927 if (wdbp->dbip == 0) {
00928 Tcl_AppendResult(interp,
00929 "db does not support lookup operations",
00930 (char *)NULL);
00931 return TCL_ERROR;
00932 }
00933
00934 if (rt_tcl_import_from_path(interp, &intern, argv[1], wdbp) == TCL_ERROR)
00935 return TCL_ERROR;
00936
00937 if (intern.idb_major_type != DB5_MAJORTYPE_BRLCAD) {
00938 Tcl_AppendResult(interp, "unknown", (char *)NULL);
00939 rt_db_free_internal(&intern, &rt_uniresource);
00940
00941 return TCL_OK;
00942 }
00943
00944 switch (intern.idb_minor_type) {
00945 case DB5_MINORTYPE_BRLCAD_TOR:
00946 Tcl_AppendResult(interp, "tor", (char *)NULL);
00947 break;
00948 case DB5_MINORTYPE_BRLCAD_TGC:
00949 Tcl_AppendResult(interp, "tgc", (char *)NULL);
00950 break;
00951 case DB5_MINORTYPE_BRLCAD_ELL:
00952 Tcl_AppendResult(interp, "ell", (char *)NULL);
00953 break;
00954 case DB5_MINORTYPE_BRLCAD_ARB8:
00955 type = rt_arb_std_type(&intern, &wdbp->wdb_tol);
00956
00957 switch (type) {
00958 case 4:
00959 Tcl_AppendResult(interp, "arb4", (char *)NULL);
00960 break;
00961 case 5:
00962 Tcl_AppendResult(interp, "arb5", (char *)NULL);
00963 break;
00964 case 6:
00965 Tcl_AppendResult(interp, "arb6", (char *)NULL);
00966 break;
00967 case 7:
00968 Tcl_AppendResult(interp, "arb7", (char *)NULL);
00969 break;
00970 case 8:
00971 Tcl_AppendResult(interp, "arb8", (char *)NULL);
00972 break;
00973 default:
00974 Tcl_AppendResult(interp, "invalid", (char *)NULL);
00975 break;
00976 }
00977
00978 break;
00979 case DB5_MINORTYPE_BRLCAD_ARS:
00980 Tcl_AppendResult(interp, "ars", (char *)NULL);
00981 break;
00982 case DB5_MINORTYPE_BRLCAD_HALF:
00983 Tcl_AppendResult(interp, "half", (char *)NULL);
00984 break;
00985 case DB5_MINORTYPE_BRLCAD_REC:
00986 Tcl_AppendResult(interp, "rec", (char *)NULL);
00987 break;
00988 case DB5_MINORTYPE_BRLCAD_POLY:
00989 Tcl_AppendResult(interp, "poly", (char *)NULL);
00990 break;
00991 case DB5_MINORTYPE_BRLCAD_BSPLINE:
00992 Tcl_AppendResult(interp, "spline", (char *)NULL);
00993 break;
00994 case DB5_MINORTYPE_BRLCAD_SPH:
00995 Tcl_AppendResult(interp, "sph", (char *)NULL);
00996 break;
00997 case DB5_MINORTYPE_BRLCAD_NMG:
00998 Tcl_AppendResult(interp, "nmg", (char *)NULL);
00999 break;
01000 case DB5_MINORTYPE_BRLCAD_EBM:
01001 Tcl_AppendResult(interp, "ebm", (char *)NULL);
01002 break;
01003 case DB5_MINORTYPE_BRLCAD_VOL:
01004 Tcl_AppendResult(interp, "vol", (char *)NULL);
01005 break;
01006 case DB5_MINORTYPE_BRLCAD_ARBN:
01007 Tcl_AppendResult(interp, "arbn", (char *)NULL);
01008 break;
01009 case DB5_MINORTYPE_BRLCAD_PIPE:
01010 Tcl_AppendResult(interp, "pipe", (char *)NULL);
01011 break;
01012 case DB5_MINORTYPE_BRLCAD_PARTICLE:
01013 Tcl_AppendResult(interp, "part", (char *)NULL);
01014 break;
01015 case DB5_MINORTYPE_BRLCAD_RPC:
01016 Tcl_AppendResult(interp, "rpc", (char *)NULL);
01017 break;
01018 case DB5_MINORTYPE_BRLCAD_RHC:
01019 Tcl_AppendResult(interp, "rhc", (char *)NULL);
01020 break;
01021 case DB5_MINORTYPE_BRLCAD_EPA:
01022 Tcl_AppendResult(interp, "epa", (char *)NULL);
01023 break;
01024 case DB5_MINORTYPE_BRLCAD_EHY:
01025 Tcl_AppendResult(interp, "ehy", (char *)NULL);
01026 break;
01027 case DB5_MINORTYPE_BRLCAD_ETO:
01028 Tcl_AppendResult(interp, "eto", (char *)NULL);
01029 break;
01030 case DB5_MINORTYPE_BRLCAD_GRIP:
01031 Tcl_AppendResult(interp, "grip", (char *)NULL);
01032 break;
01033 case DB5_MINORTYPE_BRLCAD_JOINT:
01034 Tcl_AppendResult(interp, "joint", (char *)NULL);
01035 break;
01036 case DB5_MINORTYPE_BRLCAD_HF:
01037 Tcl_AppendResult(interp, "hf", (char *)NULL);
01038 break;
01039 case DB5_MINORTYPE_BRLCAD_DSP:
01040 Tcl_AppendResult(interp, "dsp", (char *)NULL);
01041 break;
01042 case DB5_MINORTYPE_BRLCAD_SKETCH:
01043 Tcl_AppendResult(interp, "sketch", (char *)NULL);
01044 break;
01045 case DB5_MINORTYPE_BRLCAD_EXTRUDE:
01046 Tcl_AppendResult(interp, "extrude", (char *)NULL);
01047 break;
01048 case DB5_MINORTYPE_BRLCAD_SUBMODEL:
01049 Tcl_AppendResult(interp, "submodel", (char *)NULL);
01050 break;
01051 case DB5_MINORTYPE_BRLCAD_CLINE:
01052 Tcl_AppendResult(interp, "cline", (char *)NULL);
01053 break;
01054 case DB5_MINORTYPE_BRLCAD_BOT:
01055 Tcl_AppendResult(interp, "bot", (char *)NULL);
01056 break;
01057 case DB5_MINORTYPE_BRLCAD_COMBINATION:
01058 Tcl_AppendResult(interp, "comb", (char *)NULL);
01059 break;
01060 default:
01061 Tcl_AppendResult(interp, "other", (char *)NULL);
01062 break;
01063 }
01064
01065 rt_db_free_internal(&intern, &rt_uniresource);
01066 return TCL_OK;
01067 }
01068
01069 int
01070 wdb_get_type_tcl(ClientData clientData,
01071 Tcl_Interp *interp,
01072 int argc,
01073 char **argv)
01074 {
01075 struct rt_wdb *wdbp = (struct rt_wdb *)clientData;
01076
01077 return wdb_get_type_cmd(wdbp, interp, argc-1, argv+1);
01078 }
01079
01080 int
01081 wdb_put_cmd(struct rt_wdb *wdbp,
01082 Tcl_Interp *interp,
01083 int argc,
01084 char **argv)
01085 {
01086 struct rt_db_internal intern;
01087 register const struct rt_functab *ftp;
01088 int i;
01089 char *name;
01090 char type[16];
01091
01092 if (argc < 3) {
01093 struct bu_vls vls;
01094
01095 bu_vls_init(&vls);
01096 bu_vls_printf(&vls, "helplib_alias wdb_put %s", argv[0]);
01097 Tcl_Eval(interp, bu_vls_addr(&vls));
01098 bu_vls_free(&vls);
01099 return TCL_ERROR;
01100 }
01101
01102 name = argv[1];
01103
01104
01105
01106
01107
01108 if (wdbp->dbip && db_lookup(wdbp->dbip, argv[1], LOOKUP_QUIET) != DIR_NULL ) {
01109 Tcl_AppendResult(interp, argv[1], " already exists",
01110 (char *)NULL);
01111 return TCL_ERROR;
01112 }
01113
01114 RT_INIT_DB_INTERNAL(&intern);
01115
01116 for (i = 0; argv[2][i] != 0 && i < 16; i++) {
01117 type[i] = isupper(argv[2][i]) ? tolower(argv[2][i]) :
01118 argv[2][i];
01119 }
01120 type[i] = 0;
01121
01122 ftp = rt_get_functab_by_label(type);
01123 if (ftp == NULL) {
01124 Tcl_AppendResult(interp, type,
01125 " is an unknown object type.",
01126 (char *)NULL);
01127 return TCL_ERROR;
01128 }
01129
01130 RT_CK_FUNCTAB(ftp);
01131
01132 if (ftp->ft_make) {
01133 if (ftp->ft_make == rt_nul_make) {
01134 Tcl_AppendResult(interp, "wdb_put_internal(", argv[1],
01135 ") cannot put a ", type, (char *)NULL);
01136
01137 return TCL_ERROR;
01138 }
01139 ftp->ft_make(ftp, &intern, 0.0);
01140 } else {
01141 rt_generic_make(ftp, &intern, 0.0);
01142 }
01143
01144 if (ftp->ft_tcladjust(interp, &intern, argc-3, argv+3, &rt_uniresource) == TCL_ERROR) {
01145 rt_db_free_internal(&intern, &rt_uniresource);
01146 return TCL_ERROR;
01147 }
01148
01149 if (wdb_put_internal(wdbp, name, &intern, 1.0) < 0) {
01150 Tcl_AppendResult(interp, "wdb_put_internal(", argv[1],
01151 ") failure", (char *)NULL);
01152 rt_db_free_internal(&intern, &rt_uniresource);
01153 return TCL_ERROR;
01154 }
01155
01156 rt_db_free_internal( &intern, &rt_uniresource );
01157 return TCL_OK;
01158 }
01159
01160
01161
01162
01163
01164
01165
01166
01167 static int
01168 wdb_put_tcl(ClientData clientData,
01169 Tcl_Interp *interp,
01170 int argc,
01171 char **argv)
01172 {
01173 struct rt_wdb *wdbp = (struct rt_wdb *)clientData;
01174
01175 return wdb_put_cmd(wdbp, interp, argc-1, argv+1);
01176 }
01177
01178 int
01179 wdb_adjust_cmd(struct rt_wdb *wdbp,
01180 Tcl_Interp *interp,
01181 int argc,
01182 char **argv)
01183 {
01184 register struct directory *dp;
01185 int status;
01186 char *name;
01187 struct rt_db_internal intern;
01188
01189 if (argc < 4) {
01190 struct bu_vls vls;
01191
01192 bu_vls_init(&vls);
01193 bu_vls_printf(&vls, "helplib_alias wdb_adjust %s", argv[0]);
01194 Tcl_Eval(interp, bu_vls_addr(&vls));
01195 bu_vls_free(&vls);
01196 return TCL_ERROR;
01197 }
01198 name = argv[1];
01199
01200
01201 RT_CK_DBI_TCL(interp,wdbp->dbip);
01202
01203 dp = db_lookup(wdbp->dbip, name, LOOKUP_QUIET);
01204 if (dp == DIR_NULL) {
01205 Tcl_AppendResult(interp, name, ": not found",
01206 (char *)NULL );
01207 return TCL_ERROR;
01208 }
01209
01210 status = rt_db_get_internal(&intern, dp, wdbp->dbip, (matp_t)NULL, &rt_uniresource);
01211 if (status < 0) {
01212 Tcl_AppendResult(interp, "rt_db_get_internal(", name,
01213 ") failure", (char *)NULL );
01214 return TCL_ERROR;
01215 }
01216 RT_CK_DB_INTERNAL(&intern);
01217
01218
01219 RT_CK_FUNCTAB(intern.idb_meth);
01220
01221 status = intern.idb_meth->ft_tcladjust(interp, &intern, argc-2, argv+2, &rt_uniresource);
01222 if( status == TCL_OK && wdb_put_internal(wdbp, name, &intern, 1.0) < 0) {
01223 Tcl_AppendResult(interp, "wdb_export(", name,
01224 ") failure", (char *)NULL);
01225 rt_db_free_internal(&intern, &rt_uniresource);
01226 return TCL_ERROR;
01227 }
01228
01229
01230 bu_observer_notify(interp, &wdbp->wdb_observers, bu_vls_addr(&wdbp->wdb_name));
01231
01232 return status;
01233 }
01234
01235
01236
01237
01238
01239
01240
01241
01242
01243
01244
01245
01246
01247
01248
01249
01250 static int
01251 wdb_adjust_tcl(ClientData clientData,
01252 Tcl_Interp *interp,
01253 int argc,
01254 char **argv)
01255 {
01256 struct rt_wdb *wdbp = (struct rt_wdb *)clientData;
01257
01258 return wdb_adjust_cmd(wdbp, interp, argc-1, argv+1);
01259 }
01260
01261 int
01262 wdb_form_cmd(struct rt_wdb *wdbp,
01263 Tcl_Interp *interp,
01264 int argc,
01265 char **argv)
01266 {
01267 const struct rt_functab *ftp;
01268
01269 if (argc != 2) {
01270 struct bu_vls vls;
01271
01272 bu_vls_init(&vls);
01273 bu_vls_printf(&vls, "helplib_alias wdb_form %s", argv[0]);
01274 Tcl_Eval(interp, bu_vls_addr(&vls));
01275 bu_vls_free(&vls);
01276 return TCL_ERROR;
01277 }
01278
01279 if ((ftp = rt_get_functab_by_label(argv[1])) == NULL) {
01280 Tcl_AppendResult(interp, "There is no geometric object type \"",
01281 argv[1], "\".", (char *)NULL);
01282 return TCL_ERROR;
01283 }
01284 return ftp->ft_tclform(ftp, interp);
01285 }
01286
01287
01288
01289
01290 static int
01291 wdb_form_tcl(ClientData clientData,
01292 Tcl_Interp *interp,
01293 int argc,
01294 char **argv)
01295 {
01296 struct rt_wdb *wdbp = (struct rt_wdb *)clientData;
01297
01298 return wdb_form_cmd(wdbp, interp, argc-1, argv+1);
01299 }
01300
01301 int
01302 wdb_tops_cmd(struct rt_wdb *wdbp,
01303 Tcl_Interp *interp,
01304 int argc,
01305 char **argv)
01306 {
01307 register struct directory *dp;
01308 register int i;
01309 struct directory **dirp;
01310 struct directory **dirp0 = (struct directory **)NULL;
01311 struct bu_vls vls;
01312 int c;
01313 #ifdef NEW_TOPS_BEHAVIOR
01314 int aflag = 0;
01315 int hflag = 0;
01316 int pflag = 0;
01317 #else
01318 int gflag = 0;
01319 int uflag = 0;
01320 #endif
01321 int no_decorate = 0;
01322
01323 RT_CK_WDB_TCL(interp, wdbp);
01324 RT_CK_DBI_TCL(interp, wdbp->dbip);
01325
01326
01327 bu_optind = 1;
01328 #ifdef NEW_TOPS_BEHAVIOR
01329 while ((c = bu_getopt(argc, argv, "ahnp")) != EOF) {
01330 switch (c) {
01331 case 'a':
01332 aflag = 1;
01333 break;
01334 case 'h':
01335 hflag = 1;
01336 break;
01337 case 'n':
01338 no_decorate = 1;
01339 break;
01340 case 'p':
01341 pflag = 1;
01342 break;
01343 default:
01344 break;
01345 }
01346 }
01347 #else
01348 while ((c = bu_getopt(argc, argv, "gun")) != EOF) {
01349 switch (c) {
01350 case 'g':
01351 gflag = 1;
01352 break;
01353 case 'u':
01354 uflag = 1;
01355 break;
01356 case 'n':
01357 no_decorate = 1;
01358 break;
01359 default:
01360 break;
01361 }
01362 }
01363 #endif
01364
01365 argc -= (bu_optind - 1);
01366 argv += (bu_optind - 1);
01367
01368
01369
01370 db_update_nref(wdbp->dbip, &rt_uniresource);
01371
01372
01373
01374
01375 dirp = wdb_dir_getspace(wdbp->dbip, 0);
01376 dirp0 = dirp;
01377
01378 if (wdbp->dbip->dbi_version < 5) {
01379 for (i = 0; i < RT_DBNHASH; i++)
01380 for (dp = wdbp->dbip->dbi_Head[i];
01381 dp != DIR_NULL;
01382 dp = dp->d_forw) {
01383 if (dp->d_nref == 0)
01384 *dirp++ = dp;
01385 }
01386 } else {
01387 for (i = 0; i < RT_DBNHASH; i++)
01388 for (dp = wdbp->dbip->dbi_Head[i];
01389 dp != DIR_NULL;
01390 dp = dp->d_forw) {
01391 #ifdef NEW_TOPS_BEHAVIOR
01392 if (dp->d_nref == 0 &&
01393 (aflag ||
01394 (hflag && (dp->d_flags & DIR_HIDDEN)) ||
01395 (pflag && dp->d_addr == RT_DIR_PHONY_ADDR) ||
01396 (!aflag && !hflag && !pflag &&
01397 !(dp->d_flags & DIR_HIDDEN) &&
01398 (dp->d_addr != RT_DIR_PHONY_ADDR))))
01399 *dirp++ = dp;
01400 #else
01401 if (dp->d_nref == 0 &&
01402 ((!gflag || (gflag && dp->d_major_type == DB5_MAJORTYPE_BRLCAD)) &&
01403 (!uflag || (uflag && !(dp->d_flags & DIR_HIDDEN)))))
01404 *dirp++ = dp;
01405 #endif
01406 }
01407 }
01408
01409 bu_vls_init(&vls);
01410 wdb_vls_col_pr4v(&vls, dirp0, (int)(dirp - dirp0), no_decorate);
01411 Tcl_AppendResult(interp, bu_vls_addr(&vls), (char *)0);
01412 bu_vls_free(&vls);
01413 bu_free((genptr_t)dirp0, "wdb_tops_cmd: wdb_dir_getspace");
01414
01415 return TCL_OK;
01416 }
01417
01418
01419
01420
01421
01422
01423 static int
01424 wdb_tops_tcl(ClientData clientData,
01425 Tcl_Interp *interp,
01426 int argc,
01427 char **argv)
01428 {
01429 struct rt_wdb *wdbp = (struct rt_wdb *)clientData;
01430
01431 return wdb_tops_cmd(wdbp, interp, argc-1, argv+1);
01432 }
01433
01434
01435
01436
01437
01438
01439 static void
01440 wdb_deleteProc_rt(ClientData clientData)
01441 {
01442 struct application *ap = (struct application *)clientData;
01443 struct rt_i *rtip;
01444
01445 RT_AP_CHECK(ap);
01446 rtip = ap->a_rt_i;
01447 RT_CK_RTI(rtip);
01448
01449 rt_free_rti(rtip);
01450 ap->a_rt_i = (struct rt_i *)NULL;
01451
01452 bu_free( (genptr_t)ap, "struct application" );
01453 }
01454
01455 int
01456 wdb_rt_gettrees_cmd(struct rt_wdb *wdbp,
01457 Tcl_Interp *interp,
01458 int argc,
01459 char **argv)
01460 {
01461 struct rt_i *rtip;
01462 struct application *ap;
01463 struct resource *resp;
01464 char *newprocname;
01465
01466 RT_CK_WDB_TCL(interp, wdbp);
01467 RT_CK_DBI_TCL(interp, wdbp->dbip);
01468
01469 if (argc < 3) {
01470 struct bu_vls vls;
01471
01472 bu_vls_init(&vls);
01473 bu_vls_printf(&vls, "helplib_alias wdb_rt_gettrees %s", argv[0]);
01474 Tcl_Eval(interp, bu_vls_addr(&vls));
01475 bu_vls_free(&vls);
01476 return TCL_ERROR;
01477 }
01478
01479 rtip = rt_new_rti(wdbp->dbip);
01480 newprocname = argv[1];
01481
01482
01483 (void)Tcl_DeleteCommand(interp, newprocname);
01484
01485 while (argv[2][0] == '-') {
01486 if (strcmp( argv[2], "-i") == 0) {
01487 rtip->rti_dont_instance = 1;
01488 argc--;
01489 argv++;
01490 continue;
01491 }
01492 if (strcmp(argv[2], "-u") == 0) {
01493 rtip->useair = 1;
01494 argc--;
01495 argv++;
01496 continue;
01497 }
01498 break;
01499 }
01500
01501 if (rt_gettrees(rtip, argc-2, (const char **)&argv[2], 1) < 0) {
01502 Tcl_AppendResult(interp,
01503 "rt_gettrees() returned error", (char *)NULL);
01504 rt_free_rti(rtip);
01505 return TCL_ERROR;
01506 }
01507
01508
01509 rtip->rti_hasty_prep = 1;
01510
01511
01512
01513
01514
01515
01516
01517
01518
01519
01520 BU_GETSTRUCT(resp, resource);
01521 rt_init_resource(resp, 0, rtip);
01522 BU_ASSERT_PTR( BU_PTBL_GET(&rtip->rti_resources, 0), !=, NULL );
01523
01524 ap = (struct application *)bu_malloc(sizeof(struct application), "wdb_rt_gettrees_cmd: ap");
01525 RT_APPLICATION_INIT(ap);
01526 ap->a_magic = RT_AP_MAGIC;
01527 ap->a_resource = resp;
01528 ap->a_rt_i = rtip;
01529 ap->a_purpose = "Conquest!";
01530
01531 rt_ck(rtip);
01532
01533
01534
01535 (void)Tcl_CreateCommand(interp, newprocname, rt_tcl_rt,
01536 (ClientData)ap, wdb_deleteProc_rt);
01537
01538
01539 Tcl_AppendResult(interp, newprocname, (char *)NULL);
01540
01541 return TCL_OK;
01542 }
01543
01544
01545
01546
01547
01548
01549
01550
01551
01552
01553
01554
01555 static int
01556 wdb_rt_gettrees_tcl(ClientData clientData,
01557 Tcl_Interp *interp,
01558 int argc,
01559 char **argv)
01560 {
01561 struct rt_wdb *wdbp = (struct rt_wdb *)clientData;
01562
01563 return wdb_rt_gettrees_cmd(wdbp, interp, argc-1, argv+1);
01564 }
01565
01566 struct showmats_data {
01567 Tcl_Interp *smd_interp;
01568 int smd_count;
01569 char *smd_child;
01570 mat_t smd_mat;
01571 };
01572
01573 static void
01574 Do_showmats(struct db_i *dbip,
01575 struct rt_comb_internal *comb,
01576 union tree *comb_leaf,
01577 genptr_t user_ptr1,
01578 genptr_t user_ptr2,
01579 genptr_t user_ptr3)
01580 {
01581 struct showmats_data *smdp;
01582
01583 RT_CK_DBI(dbip);
01584 RT_CK_TREE(comb_leaf);
01585
01586 smdp = (struct showmats_data *)user_ptr1;
01587
01588 if (strcmp(comb_leaf->tr_l.tl_name, smdp->smd_child))
01589 return;
01590
01591 smdp->smd_count++;
01592 if (smdp->smd_count > 1) {
01593 struct bu_vls vls;
01594
01595 bu_vls_init(&vls);
01596 bu_vls_printf(&vls, "\n\tOccurrence #%d:\n", smdp->smd_count);
01597 Tcl_AppendResult(smdp->smd_interp, bu_vls_addr(&vls), (char *)NULL);
01598 bu_vls_free(&vls);
01599 }
01600
01601 bn_tcl_mat_print(smdp->smd_interp, "", comb_leaf->tr_l.tl_mat);
01602 if (smdp->smd_count == 1) {
01603 mat_t tmp_mat;
01604 if (comb_leaf->tr_l.tl_mat) {
01605 bn_mat_mul(tmp_mat, smdp->smd_mat, comb_leaf->tr_l.tl_mat);
01606 MAT_COPY(smdp->smd_mat, tmp_mat);
01607 }
01608 }
01609 }
01610
01611 int
01612 wdb_showmats_cmd(struct rt_wdb *wdbp,
01613 Tcl_Interp *interp,
01614 int argc,
01615 char **argv)
01616 {
01617 struct showmats_data sm_data;
01618 char *parent;
01619 struct directory *dp;
01620 int max_count=1;
01621
01622 if (argc != 2) {
01623 struct bu_vls vls;
01624
01625 bu_vls_init(&vls);
01626 bu_vls_printf(&vls, "helplib_alias wdb_showmats %s", argv[0]);
01627 Tcl_Eval(interp, bu_vls_addr(&vls));
01628 bu_vls_free(&vls);
01629 return TCL_ERROR;
01630 }
01631
01632 sm_data.smd_interp = interp;
01633 MAT_IDN(sm_data.smd_mat);
01634
01635 parent = strtok(argv[1], "/");
01636 while ((sm_data.smd_child = strtok((char *)NULL, "/")) != NULL) {
01637 struct rt_db_internal intern;
01638 struct rt_comb_internal *comb;
01639
01640 if ((dp = db_lookup(wdbp->dbip, parent, LOOKUP_NOISY)) == DIR_NULL)
01641 return TCL_ERROR;
01642
01643 Tcl_AppendResult(interp, parent, "\n", (char *)NULL);
01644
01645 if (!(dp->d_flags & DIR_COMB)) {
01646 Tcl_AppendResult(interp, "\tThis is not a combination\n", (char *)NULL);
01647 break;
01648 }
01649
01650 if (rt_db_get_internal(&intern, dp, wdbp->dbip, (fastf_t *)NULL, &rt_uniresource) < 0)
01651 WDB_TCL_READ_ERR_return;
01652 comb = (struct rt_comb_internal *)intern.idb_ptr;
01653
01654 sm_data.smd_count = 0;
01655
01656 if (comb->tree)
01657 db_tree_funcleaf(wdbp->dbip, comb, comb->tree, Do_showmats,
01658 (genptr_t)&sm_data, (genptr_t)NULL, (genptr_t)NULL);
01659 #if USE_RT_COMB_IFREE
01660 rt_comb_ifree(&intern, &rt_uniresource);
01661 #else
01662 rt_db_free_internal(&intern, &rt_uniresource);
01663 #endif
01664
01665 if (!sm_data.smd_count) {
01666 Tcl_AppendResult(interp, sm_data.smd_child, " is not a member of ",
01667 parent, "\n", (char *)NULL);
01668 return TCL_ERROR;
01669 }
01670 if (sm_data.smd_count > max_count)
01671 max_count = sm_data.smd_count;
01672
01673 parent = sm_data.smd_child;
01674 }
01675 Tcl_AppendResult(interp, parent, "\n", (char *)NULL);
01676
01677 if (max_count > 1)
01678 Tcl_AppendResult(interp, "\nAccumulated matrix (using first occurrence of each object):\n", (char *)NULL);
01679 else
01680 Tcl_AppendResult(interp, "\nAccumulated matrix:\n", (char *)NULL);
01681
01682 bn_tcl_mat_print(interp, "", sm_data.smd_mat);
01683
01684 return TCL_OK;
01685 }
01686
01687 static int
01688 wdb_showmats_tcl(ClientData clientData,
01689 Tcl_Interp *interp,
01690 int argc,
01691 char **argv)
01692 {
01693 struct rt_wdb *wdbp = (struct rt_wdb *)clientData;
01694
01695 return wdb_showmats_cmd(wdbp, interp, argc-1, argv+1);
01696 }
01697
01698 int
01699 wdb_shells_cmd(struct rt_wdb *wdbp,
01700 Tcl_Interp *interp,
01701 int argc,
01702 char **argv)
01703 {
01704 struct directory *old_dp,*new_dp;
01705 struct rt_db_internal old_intern,new_intern;
01706 struct model *m_tmp,*m;
01707 struct nmgregion *r_tmp,*r;
01708 struct shell *s_tmp,*s;
01709 int shell_count=0;
01710 struct bu_vls shell_name;
01711 long **trans_tbl;
01712
01713 WDB_TCL_CHECK_READ_ONLY;
01714
01715 if (argc != 2) {
01716 struct bu_vls vls;
01717
01718 bu_vls_init(&vls);
01719 bu_vls_printf(&vls, "helplib_alias wdb_shells %s", argv[0]);
01720 Tcl_Eval(interp, bu_vls_addr(&vls));
01721 bu_vls_free(&vls);
01722 return TCL_ERROR;
01723 }
01724
01725 if ((old_dp = db_lookup(wdbp->dbip, argv[1], LOOKUP_NOISY)) == DIR_NULL)
01726 return TCL_ERROR;
01727
01728 if (rt_db_get_internal(&old_intern, old_dp, wdbp->dbip, bn_mat_identity, &rt_uniresource) < 0) {
01729 Tcl_AppendResult(interp, "rt_db_get_internal() error\n", (char *)NULL);
01730 return TCL_ERROR;
01731 }
01732
01733 if (old_intern.idb_type != ID_NMG) {
01734 Tcl_AppendResult(interp, "Object is not an NMG!!!\n", (char *)NULL);
01735 return TCL_ERROR;
01736 }
01737
01738 m = (struct model *)old_intern.idb_ptr;
01739 NMG_CK_MODEL(m);
01740
01741 bu_vls_init(&shell_name);
01742 for (BU_LIST_FOR(r, nmgregion, &m->r_hd)) {
01743 for (BU_LIST_FOR(s, shell, &r->s_hd)) {
01744 s_tmp = nmg_dup_shell(s, &trans_tbl, &wdbp->wdb_tol);
01745 bu_free((genptr_t)trans_tbl, "trans_tbl");
01746
01747 m_tmp = nmg_mmr();
01748 r_tmp = BU_LIST_FIRST(nmgregion, &m_tmp->r_hd);
01749
01750 BU_LIST_DEQUEUE(&s_tmp->l);
01751 BU_LIST_APPEND(&r_tmp->s_hd, &s_tmp->l);
01752 s_tmp->r_p = r_tmp;
01753 nmg_m_reindex(m_tmp, 0);
01754 nmg_m_reindex(m, 0);
01755
01756 bu_vls_printf(&shell_name, "shell.%d", shell_count);
01757 while (db_lookup(wdbp->dbip, bu_vls_addr( &shell_name), 0) != DIR_NULL) {
01758 bu_vls_trunc(&shell_name, 0);
01759 shell_count++;
01760 bu_vls_printf(&shell_name, "shell.%d", shell_count);
01761 }
01762
01763
01764 RT_INIT_DB_INTERNAL(&new_intern);
01765 new_intern.idb_major_type = DB5_MAJORTYPE_BRLCAD;
01766 new_intern.idb_type = ID_NMG;
01767 new_intern.idb_meth = &rt_functab[ID_NMG];
01768 new_intern.idb_ptr = (genptr_t)m_tmp;
01769
01770 if ((new_dp=db_diradd(wdbp->dbip, bu_vls_addr(&shell_name), -1, 0,
01771 DIR_SOLID, (genptr_t)&new_intern.idb_type)) == DIR_NULL) {
01772 WDB_TCL_ALLOC_ERR_return;
01773 }
01774
01775
01776 nmg_rebound(m_tmp, &wdbp->wdb_tol);
01777
01778
01779 if (rt_db_put_internal(new_dp, wdbp->dbip, &new_intern, &rt_uniresource) < 0) {
01780
01781 nmg_km(m_tmp);
01782 Tcl_AppendResult(interp, "rt_db_put_internal() failure\n", (char *)NULL);
01783 return TCL_ERROR;
01784 }
01785
01786 new_intern.idb_ptr = (genptr_t)NULL;
01787 }
01788 }
01789 bu_vls_free(&shell_name);
01790
01791 return TCL_OK;
01792 }
01793
01794 static int
01795 wdb_shells_tcl(ClientData clientData,
01796 Tcl_Interp *interp,
01797 int argc,
01798 char **argv)
01799 {
01800 struct rt_wdb *wdbp = (struct rt_wdb *)clientData;
01801
01802 return wdb_shells_cmd(wdbp, interp, argc-1, argv+1);
01803 }
01804
01805 int
01806 wdb_dump_cmd(struct rt_wdb *wdbp,
01807 Tcl_Interp *interp,
01808 int argc,
01809 char **argv)
01810 {
01811 struct rt_wdb *op;
01812 int ret;
01813
01814 RT_CK_WDB_TCL(interp, wdbp);
01815 RT_CK_DBI_TCL(interp, wdbp->dbip);
01816
01817 if (argc != 2) {
01818 struct bu_vls vls;
01819
01820 bu_vls_init(&vls);
01821 bu_vls_printf(&vls, "helplib_alias wdb_dump %s", argv[0]);
01822 Tcl_Eval(interp, bu_vls_addr(&vls));
01823 bu_vls_free(&vls);
01824 return TCL_ERROR;
01825 }
01826
01827 if ((op = wdb_fopen(argv[1])) == RT_WDB_NULL) {
01828 Tcl_AppendResult(interp, "dump: ", argv[1],
01829 ": cannot create", (char *)NULL);
01830 return TCL_ERROR;
01831 }
01832
01833 ret = db_dump(op, wdbp->dbip);
01834 wdb_close(op);
01835
01836 if (ret < 0) {
01837 Tcl_AppendResult(interp, "dump ", argv[1],
01838 ": db_dump() error", (char *)NULL);
01839 return TCL_ERROR;
01840 }
01841
01842 return TCL_OK;
01843 }
01844
01845
01846
01847
01848
01849
01850
01851
01852
01853 static int
01854 wdb_dump_tcl(ClientData clientData,
01855 Tcl_Interp *interp,
01856 int argc,
01857 char **argv)
01858 {
01859 struct rt_wdb *wdbp = (struct rt_wdb *)clientData;
01860
01861 return wdb_dump_cmd(wdbp, interp, argc-1, argv+1);
01862 }
01863
01864 int
01865 wdb_dbip_cmd(struct rt_wdb *wdbp,
01866 Tcl_Interp *interp,
01867 int argc,
01868 char **argv)
01869 {
01870 struct bu_vls vls;
01871
01872 bu_vls_init(&vls);
01873
01874 if (argc != 1) {
01875 bu_vls_printf(&vls, "helplib_alias wdb_dbip %s", argv[0]);
01876 Tcl_Eval(interp, bu_vls_addr(&vls));
01877 bu_vls_free(&vls);
01878 return TCL_ERROR;
01879 }
01880
01881 bu_vls_printf(&vls, "%lu", (unsigned long)wdbp->dbip);
01882 Tcl_AppendResult(interp, bu_vls_addr(&vls), (char *)NULL);
01883 bu_vls_free(&vls);
01884 return TCL_OK;
01885 }
01886
01887
01888
01889
01890
01891
01892
01893
01894 static int
01895 wdb_dbip_tcl(ClientData clientData,
01896 Tcl_Interp *interp,
01897 int argc,
01898 char **argv)
01899 {
01900 struct rt_wdb *wdbp = (struct rt_wdb *)clientData;
01901
01902 return wdb_dbip_cmd(wdbp, interp, argc-1, argv+1);
01903 }
01904
01905 int
01906 wdb_ls_cmd(struct rt_wdb *wdbp,
01907 Tcl_Interp *interp,
01908 int argc,
01909 char **argv)
01910 {
01911 struct bu_vls vls;
01912 register struct directory *dp;
01913 register int i;
01914 int c;
01915 int aflag = 0;
01916 int cflag = 0;
01917 int rflag = 0;
01918 int sflag = 0;
01919 int lflag = 0;
01920 int attr_flag = 0;
01921 int or_flag = 0;
01922
01923
01924 struct directory **dirp;
01925 struct directory **dirp0 = (struct directory **)NULL;
01926
01927 bu_vls_init(&vls);
01928
01929 if (argc < 1 || MAXARGS < argc) {
01930 bu_vls_printf(&vls, "helplib_alias wdb_ls %s", argv[0]);
01931 Tcl_Eval(interp, bu_vls_addr(&vls));
01932 bu_vls_free(&vls);
01933 return TCL_ERROR;
01934 }
01935
01936 bu_optind = 1;
01937 while ((c = bu_getopt(argc, argv, "acrslpAo")) != EOF) {
01938 switch (c) {
01939 case 'A':
01940 attr_flag = 1;
01941 break;
01942 case 'o':
01943 or_flag = 1;
01944 break;
01945 case 'a':
01946 aflag = 1;
01947 break;
01948 case 'c':
01949 cflag = 1;
01950 break;
01951 case 'r':
01952 rflag = 1;
01953 break;
01954 case 's':
01955 case 'p':
01956 sflag = 1;
01957 break;
01958 case 'l':
01959 lflag = 1;
01960 break;
01961 default:
01962 bu_vls_printf(&vls, "Unrecognized option - %c", c);
01963 Tcl_AppendResult(interp, bu_vls_addr(&vls), (char *)NULL);
01964 bu_vls_free(&vls);
01965 return TCL_ERROR;
01966 }
01967 }
01968 argc -= (bu_optind - 1);
01969 argv += (bu_optind - 1);
01970
01971
01972 if( attr_flag ) {
01973
01974 struct bu_ptbl *tbl;
01975 struct bu_attribute_value_set avs;
01976 int dir_flags;
01977 int op;
01978
01979 if( argc < 3 || argc%2 != 1 ) {
01980
01981 bu_vls_printf(&vls, "helplib_alias wdb_ls %s", argv[0]);
01982 Tcl_Eval(interp, bu_vls_addr(&vls));
01983 bu_vls_free(&vls);
01984 return TCL_ERROR;
01985 }
01986
01987 if( or_flag ) {
01988 op = 2;
01989 } else {
01990 op = 1;
01991 }
01992
01993 dir_flags = 0;
01994 if( aflag ) dir_flags = -1;
01995 if( cflag ) dir_flags = DIR_COMB;
01996 if( sflag ) dir_flags = DIR_SOLID;
01997 if( rflag ) dir_flags = DIR_REGION;
01998 if( !dir_flags ) dir_flags = -1 ^ DIR_HIDDEN;
01999
02000 bu_avs_init( &avs, argc-1, "wdb_ls_cmd avs" );
02001 for (i = 1; i < argc; i += 2) {
02002 if( or_flag ) {
02003 bu_avs_add_nonunique( &avs, argv[i], argv[i+1] );
02004 } else {
02005 bu_avs_add( &avs, argv[i], argv[i+1] );
02006 }
02007 }
02008 tbl = db_lookup_by_attr( wdbp->dbip, dir_flags, &avs, op );
02009 bu_avs_free( &avs );
02010 dirp = wdb_getspace(wdbp->dbip, BU_PTBL_LEN( tbl ));
02011 dirp0 = dirp;
02012 for( i=0 ; i<BU_PTBL_LEN( tbl ) ; i++ ) {
02013 *dirp++ = (struct directory *)BU_PTBL_GET( tbl, i );
02014 }
02015 bu_ptbl_free( tbl );
02016 bu_free( (char *)tbl, "wdb_ls_cmd ptbl" );
02017 } else if (argc > 1) {
02018
02019 dirp = wdb_getspace(wdbp->dbip, argc-1);
02020 dirp0 = dirp;
02021
02022
02023
02024 for (i = 1; i < argc; i++) {
02025 if ((dp = db_lookup(wdbp->dbip, argv[i], LOOKUP_NOISY)) == DIR_NULL)
02026 continue;
02027 *dirp++ = dp;
02028 }
02029 } else {
02030
02031 dirp = wdb_getspace(wdbp->dbip, 0);
02032 dirp0 = dirp;
02033
02034
02035
02036
02037 for (i = 0; i < RT_DBNHASH; i++)
02038 for (dp = wdbp->dbip->dbi_Head[i]; dp != DIR_NULL; dp = dp->d_forw) {
02039 if( !aflag && (dp->d_flags & DIR_HIDDEN) )
02040 continue;
02041 *dirp++ = dp;
02042 }
02043 }
02044
02045 if (lflag)
02046 wdb_vls_long_dpp(&vls, dirp0, (int)(dirp - dirp0),
02047 aflag, cflag, rflag, sflag);
02048 else if (aflag || cflag || rflag || sflag)
02049 wdb_vls_line_dpp(&vls, dirp0, (int)(dirp - dirp0),
02050 aflag, cflag, rflag, sflag);
02051 else
02052 wdb_vls_col_pr4v(&vls, dirp0, (int)(dirp - dirp0), 0);
02053
02054 Tcl_AppendResult(interp, bu_vls_addr(&vls), (char *)NULL);
02055 bu_vls_free(&vls);
02056 bu_free((genptr_t)dirp0, "wdb_getspace dp[]");
02057
02058 return TCL_OK;
02059 }
02060
02061
02062
02063
02064
02065
02066
02067
02068 static int
02069 wdb_ls_tcl(ClientData clientData,
02070 Tcl_Interp *interp,
02071 int argc,
02072 char **argv)
02073 {
02074 struct rt_wdb *wdbp = (struct rt_wdb *)clientData;
02075
02076 return wdb_ls_cmd(wdbp, interp, argc-1, argv+1);
02077 }
02078
02079 int
02080 wdb_list_cmd(struct rt_wdb *wdbp,
02081 Tcl_Interp *interp,
02082 int argc,
02083 char **argv)
02084 {
02085 register struct directory *dp;
02086 register int arg;
02087 struct bu_vls str;
02088 int id;
02089 int recurse = 0;
02090 char *listeval = "listeval";
02091 struct rt_db_internal intern;
02092
02093 if (argc < 2 || MAXARGS < argc) {
02094 struct bu_vls vls;
02095
02096 bu_vls_init(&vls);
02097 bu_vls_printf(&vls, "helplib_alias wdb_list %s", argv[0]);
02098 Tcl_Eval(interp, bu_vls_addr(&vls));
02099 bu_vls_free(&vls);
02100 return TCL_ERROR;
02101 }
02102
02103 if (argc > 1 && strcmp(argv[1], "-r") == 0) {
02104 recurse = 1;
02105
02106
02107 --argc;
02108 ++argv;
02109 }
02110
02111
02112 --argc;
02113 ++argv;
02114
02115 bu_vls_init(&str);
02116
02117 for (arg = 0; arg < argc; arg++) {
02118 if (recurse) {
02119 char *tmp_argv[3];
02120
02121 tmp_argv[0] = listeval;
02122 tmp_argv[1] = argv[arg];
02123 tmp_argv[2] = (char *)NULL;
02124
02125 wdb_pathsum_cmd(wdbp, interp, 2, tmp_argv);
02126 } else if (strchr(argv[arg], '/')) {
02127 struct db_tree_state ts;
02128 struct db_full_path path;
02129
02130 db_full_path_init( &path );
02131 ts = wdbp->wdb_initial_tree_state;
02132 ts.ts_dbip = wdbp->dbip;
02133 ts.ts_resp = &rt_uniresource;
02134 MAT_IDN(ts.ts_mat);
02135
02136 if (db_follow_path_for_state(&ts, &path, argv[arg], 1))
02137 continue;
02138
02139 dp = DB_FULL_PATH_CUR_DIR( &path );
02140
02141 if ((id = rt_db_get_internal(&intern, dp, wdbp->dbip, ts.ts_mat, &rt_uniresource)) < 0) {
02142 Tcl_AppendResult(interp, "rt_db_get_internal(", dp->d_namep,
02143 ") failure", (char *)NULL );
02144 continue;
02145 }
02146
02147 db_free_full_path( &path );
02148
02149 bu_vls_printf( &str, "%s: ", argv[arg] );
02150
02151 if (rt_functab[id].ft_describe(&str, &intern, 99, wdbp->dbip->dbi_base2local, &rt_uniresource, wdbp->dbip) < 0)
02152 Tcl_AppendResult(interp, dp->d_namep, ": describe error", (char *)NULL);
02153
02154 rt_db_free_internal(&intern, &rt_uniresource);
02155 } else {
02156 if ((dp = db_lookup(wdbp->dbip, argv[arg], LOOKUP_NOISY)) == DIR_NULL)
02157 continue;
02158
02159 wdb_do_list(wdbp->dbip, interp, &str, dp, 99);
02160 }
02161 }
02162
02163 Tcl_AppendResult(interp, bu_vls_addr(&str), (char *)NULL);
02164 bu_vls_free(&str);
02165
02166 return TCL_OK;
02167 }
02168
02169
02170
02171
02172
02173
02174
02175
02176 static int
02177 wdb_list_tcl(ClientData clientData, Tcl_Interp *interp, int argc, char **argv)
02178 {
02179 struct rt_wdb *wdbp = (struct rt_wdb *)clientData;
02180
02181 return wdb_list_cmd(wdbp, interp, argc-1, argv+1);
02182 }
02183
02184 static void
02185 wdb_do_trace(struct db_i *dbip,
02186 struct rt_comb_internal *comb,
02187 union tree *comb_leaf,
02188 genptr_t user_ptr1,
02189 genptr_t user_ptr2,
02190 genptr_t user_ptr3)
02191 {
02192 int *pathpos;
02193 matp_t old_xlate;
02194 mat_t new_xlate;
02195 struct directory *nextdp;
02196 struct wdb_trace_data *wtdp;
02197
02198 RT_CK_DBI(dbip);
02199 RT_CK_TREE(comb_leaf);
02200
02201 if ((nextdp = db_lookup(dbip, comb_leaf->tr_l.tl_name, LOOKUP_NOISY)) == DIR_NULL)
02202 return;
02203
02204 pathpos = (int *)user_ptr1;
02205 old_xlate = (matp_t)user_ptr2;
02206 wtdp = (struct wdb_trace_data *)user_ptr3;
02207
02208
02209
02210
02211
02212
02213
02214
02215
02216 #if 0
02217
02218 if (comb_leaf->tr_l.tl_mat) {
02219 bn_mat_mul(new_xlate, old_xlate, comb_leaf->tr_l.tl_mat);
02220 } else {
02221 MAT_COPY(new_xlate, old_xlate);
02222 }
02223 #else
02224 if (wtdp->wtd_flag != WDB_EVAL_ONLY ||
02225 (*pathpos)+1 < wtdp->wtd_objpos) {
02226 if (comb_leaf->tr_l.tl_mat) {
02227 bn_mat_mul(new_xlate, old_xlate, comb_leaf->tr_l.tl_mat);
02228 } else {
02229 MAT_COPY(new_xlate, old_xlate);
02230 }
02231 } else {
02232 MAT_COPY(new_xlate, old_xlate);
02233 }
02234 #endif
02235
02236 wdb_trace(nextdp, (*pathpos)+1, new_xlate, wtdp);
02237 }
02238
02239 static void
02240 wdb_trace(register struct directory *dp,
02241 int pathpos,
02242 const mat_t old_xlate,
02243 struct wdb_trace_data *wtdp)
02244 {
02245 struct rt_db_internal intern;
02246 struct rt_comb_internal *comb;
02247 int i;
02248 int id;
02249 struct bu_vls str;
02250
02251 #if 0
02252 if (dbip == DBI_NULL)
02253 return;
02254 #endif
02255
02256 bu_vls_init(&str);
02257
02258 if (pathpos >= WDB_MAX_LEVELS) {
02259 struct bu_vls tmp_vls;
02260
02261 bu_vls_init(&tmp_vls);
02262 bu_vls_printf(&tmp_vls, "nesting exceeds %d levels\n", WDB_MAX_LEVELS);
02263 Tcl_AppendResult(wtdp->wtd_interp, bu_vls_addr(&tmp_vls), (char *)NULL);
02264 bu_vls_free(&tmp_vls);
02265
02266 for (i=0; i<WDB_MAX_LEVELS; i++)
02267 Tcl_AppendResult(wtdp->wtd_interp, "/", wtdp->wtd_path[i]->d_namep, (char *)NULL);
02268
02269 Tcl_AppendResult(wtdp->wtd_interp, "\n", (char *)NULL);
02270 return;
02271 }
02272
02273 if (dp->d_flags & DIR_COMB) {
02274 if (rt_db_get_internal(&intern, dp, wtdp->wtd_dbip, (fastf_t *)NULL, &rt_uniresource) < 0)
02275 WDB_READ_ERR_return;
02276
02277 wtdp->wtd_path[pathpos] = dp;
02278 comb = (struct rt_comb_internal *)intern.idb_ptr;
02279 if (comb->tree)
02280 db_tree_funcleaf(wtdp->wtd_dbip, comb, comb->tree, wdb_do_trace,
02281 (genptr_t)&pathpos, (genptr_t)old_xlate, (genptr_t)wtdp);
02282 #if USE_RT_COMB_IFREE
02283 rt_comb_ifree(&intern, &rt_uniresource);
02284 #else
02285 rt_db_free_internal(&intern, &rt_uniresource);
02286 #endif
02287 return;
02288 }
02289
02290
02291
02292
02293 wtdp->wtd_path[pathpos] = dp;
02294
02295
02296 if( wtdp->wtd_flag == WDB_CPEVAL ) {
02297 for (i=0; i<=pathpos; i++) {
02298 if (wtdp->wtd_path[i]->d_addr != wtdp->wtd_obj[i]->d_addr) {
02299
02300 return;
02301 }
02302 }
02303 } else {
02304 for (i=0; i<wtdp->wtd_objpos; i++) {
02305 if (wtdp->wtd_path[i]->d_addr != wtdp->wtd_obj[i]->d_addr) {
02306
02307 return;
02308 }
02309 }
02310 }
02311
02312
02313 MAT_COPY(wtdp->wtd_xform, old_xlate);
02314 wtdp->wtd_prflag = 1;
02315
02316 if (wtdp->wtd_flag == WDB_CPEVAL ||
02317 wtdp->wtd_flag == WDB_EVAL_ONLY)
02318 return;
02319
02320
02321 for (i=0; i<pathpos; i++)
02322 Tcl_AppendResult(wtdp->wtd_interp, "/", wtdp->wtd_path[i]->d_namep, (char *)NULL);
02323
02324 if (wtdp->wtd_flag == WDB_LISTPATH) {
02325 bu_vls_printf( &str, "/%s:\n", dp->d_namep );
02326 Tcl_AppendResult(wtdp->wtd_interp, bu_vls_addr(&str), (char *)NULL);
02327 bu_vls_free(&str);
02328 return;
02329 }
02330
02331
02332 Tcl_AppendResult(wtdp->wtd_interp, "/", (char *)NULL);
02333 if ((id=rt_db_get_internal(&intern, dp, wtdp->wtd_dbip, wtdp->wtd_xform, &rt_uniresource)) < 0) {
02334 Tcl_AppendResult(wtdp->wtd_interp, "rt_db_get_internal(", dp->d_namep,
02335 ") failure", (char *)NULL );
02336 return;
02337 }
02338 bu_vls_printf(&str, "%s:\n", dp->d_namep);
02339 if (rt_functab[id].ft_describe(&str, &intern, 1, wtdp->wtd_dbip->dbi_base2local, &rt_uniresource, wtdp->wtd_dbip) < 0)
02340 Tcl_AppendResult(wtdp->wtd_interp, dp->d_namep, ": describe error\n", (char *)NULL);
02341 rt_db_free_internal(&intern, &rt_uniresource);
02342 Tcl_AppendResult(wtdp->wtd_interp, bu_vls_addr(&str), (char *)NULL);
02343 bu_vls_free(&str);
02344 }
02345
02346 int
02347 wdb_pathsum_cmd(struct rt_wdb *wdbp,
02348 Tcl_Interp *interp,
02349 int argc,
02350 char **argv)
02351 {
02352 int i, pos_in;
02353 struct wdb_trace_data wtd;
02354
02355 if (argc < 2 || MAXARGS < argc) {
02356 struct bu_vls vls;
02357
02358 bu_vls_init(&vls);
02359 bu_vls_printf(&vls, "helplib_alias %s%s %s", "wdb_", argv[0], argv[0]);
02360 Tcl_Eval(interp, bu_vls_addr(&vls));
02361 bu_vls_free(&vls);
02362 return TCL_ERROR;
02363 }
02364
02365
02366
02367
02368
02369
02370
02371 wtd.wtd_interp = interp;
02372 wtd.wtd_dbip = wdbp->dbip;
02373 wtd.wtd_flag = WDB_CPEVAL;
02374 wtd.wtd_prflag = 0;
02375
02376 pos_in = 1;
02377
02378
02379 if (strcmp(argv[0], "paths") == 0) {
02380
02381 wtd.wtd_flag = WDB_LISTPATH;
02382 }
02383 if (strcmp(argv[0], "listeval") == 0) {
02384
02385 wtd.wtd_flag = WDB_LISTEVAL;
02386 }
02387
02388 if (argc == 2 && strchr(argv[1], '/')) {
02389 char *tok;
02390 wtd.wtd_objpos = 0;
02391
02392 tok = strtok(argv[1], "/");
02393 while (tok) {
02394 if ((wtd.wtd_obj[wtd.wtd_objpos++] = db_lookup(wdbp->dbip, tok, LOOKUP_NOISY)) == DIR_NULL)
02395 return TCL_ERROR;
02396 tok = strtok((char *)NULL, "/");
02397 }
02398 } else {
02399 wtd.wtd_objpos = argc-1;
02400
02401
02402 for (i=0; i<wtd.wtd_objpos; i++) {
02403 if ((wtd.wtd_obj[i] = db_lookup(wdbp->dbip, argv[pos_in+i], LOOKUP_NOISY)) == DIR_NULL)
02404 return TCL_ERROR;
02405 }
02406 }
02407
02408 MAT_IDN(wtd.wtd_xform);
02409
02410 wdb_trace(wtd.wtd_obj[0], 0, bn_mat_identity, &wtd);
02411
02412 if (wtd.wtd_prflag == 0) {
02413
02414 Tcl_AppendResult(interp, "PATH: ", (char *)NULL);
02415 for (i=0; i<wtd.wtd_objpos; i++)
02416 Tcl_AppendResult(interp, "/", wtd.wtd_obj[i]->d_namep, (char *)NULL);
02417
02418 Tcl_AppendResult(interp, " NOT FOUND\n", (char *)NULL);
02419 }
02420
02421 return TCL_OK;
02422 }
02423
02424
02425
02426
02427
02428
02429
02430
02431
02432
02433
02434
02435
02436
02437
02438
02439
02440 static int
02441 wdb_pathsum_tcl(ClientData clientData,
02442 Tcl_Interp *interp,
02443 int argc,
02444 char **argv)
02445 {
02446 struct rt_wdb *wdbp = (struct rt_wdb *)clientData;
02447
02448 return wdb_pathsum_cmd(wdbp, interp, argc-1, argv+1);
02449 }
02450
02451
02452 static void
02453 wdb_scrape_escapes_AppendResult(Tcl_Interp *interp,
02454 char *str)
02455 {
02456 char buf[2];
02457 buf[1] = '\0';
02458
02459 while (*str) {
02460 buf[0] = *str;
02461 if (*str != '\\') {
02462 Tcl_AppendResult(interp, buf, NULL);
02463 } else if (*(str+1) == '\\') {
02464 Tcl_AppendResult(interp, buf, NULL);
02465 ++str;
02466 }
02467 if (*str == '\0')
02468 break;
02469 ++str;
02470 }
02471 }
02472
02473 int
02474 wdb_expand_cmd(struct rt_wdb *wdbp,
02475 Tcl_Interp *interp,
02476 int argc,
02477 char **argv)
02478 {
02479 register char *pattern;
02480 register struct directory *dp;
02481 register int i, whicharg;
02482 int regexp, nummatch, thismatch, backslashed;
02483
02484 if (argc < 1 || MAXARGS < argc) {
02485 struct bu_vls vls;
02486
02487 bu_vls_init(&vls);
02488 bu_vls_printf(&vls, "helplib_alias wdb_expand %s", argv[0]);
02489 Tcl_Eval(interp, bu_vls_addr(&vls));
02490 bu_vls_free(&vls);
02491 return TCL_ERROR;
02492 }
02493
02494 nummatch = 0;
02495 backslashed = 0;
02496 for (whicharg = 1; whicharg < argc; whicharg++) {
02497
02498 pattern = argv[whicharg];
02499 regexp = 0;
02500 do {
02501 if ((*pattern == '*' || *pattern == '?' || *pattern == '[') &&
02502 !backslashed) {
02503 regexp = 1;
02504 break;
02505 }
02506 if (*pattern == '\\' && !backslashed)
02507 backslashed = 1;
02508 else
02509 backslashed = 0;
02510 } while (*pattern++);
02511
02512
02513 if (regexp == 0) {
02514 if (nummatch > 0)
02515 Tcl_AppendResult(interp, " ", NULL);
02516 wdb_scrape_escapes_AppendResult(interp, argv[whicharg]);
02517 ++nummatch;
02518 continue;
02519 }
02520
02521
02522
02523
02524
02525
02526
02527
02528 pattern = argv[whicharg];
02529 thismatch = 0;
02530 for (i = 0; i < RT_DBNHASH; i++) {
02531 for (dp = wdbp->dbip->dbi_Head[i]; dp != DIR_NULL; dp = dp->d_forw) {
02532 if (!db_regexp_match(pattern, dp->d_namep))
02533 continue;
02534
02535 if (nummatch == 0)
02536 Tcl_AppendResult(interp, dp->d_namep, NULL);
02537 else
02538 Tcl_AppendResult(interp, " ", dp->d_namep, NULL);
02539 ++nummatch;
02540 ++thismatch;
02541 }
02542 }
02543 if (thismatch == 0) {
02544 if (nummatch > 0)
02545 Tcl_AppendResult(interp, " ", NULL);
02546 wdb_scrape_escapes_AppendResult(interp, argv[whicharg]);
02547 }
02548 }
02549
02550 return TCL_OK;
02551 }
02552
02553
02554
02555
02556
02557
02558
02559
02560 static int
02561 wdb_expand_tcl(ClientData clientData, Tcl_Interp *interp, int argc, char **argv)
02562 {
02563 struct rt_wdb *wdbp = (struct rt_wdb *)clientData;
02564
02565 return wdb_expand_cmd(wdbp, interp, argc-1, argv+1);
02566 }
02567
02568 int
02569 wdb_kill_cmd(struct rt_wdb *wdbp,
02570 Tcl_Interp *interp,
02571 int argc,
02572 char **argv)
02573 {
02574 register struct directory *dp;
02575 register int i;
02576 int is_phony;
02577 int verbose = LOOKUP_NOISY;
02578
02579 WDB_TCL_CHECK_READ_ONLY;
02580
02581 if (argc < 2 || MAXARGS < argc) {
02582 struct bu_vls vls;
02583
02584 bu_vls_init(&vls);
02585 bu_vls_printf(&vls, "helplib_alias wdb_kill %s", argv[0]);
02586 if (interp) {
02587 Tcl_Eval(interp, bu_vls_addr(&vls));
02588 }
02589 bu_vls_free(&vls);
02590 return TCL_ERROR;
02591 }
02592
02593
02594 if (argc > 1 && strcmp(argv[1], "-f") == 0) {
02595 verbose = LOOKUP_QUIET;
02596 argc--;
02597 argv++;
02598 }
02599
02600 for (i = 1; i < argc; i++) {
02601 if ((dp = db_lookup(wdbp->dbip, argv[i], verbose)) != DIR_NULL) {
02602 is_phony = (dp->d_addr == RT_DIR_PHONY_ADDR);
02603
02604
02605 if (is_phony)
02606 continue;
02607
02608
02609 if (i == argc-1)
02610 dgo_eraseobjall_callback(wdbp->dbip, interp, dp, 1 );
02611 else
02612 dgo_eraseobjall_callback(wdbp->dbip, interp, dp, 0);
02613
02614 if (db_delete(wdbp->dbip, dp) < 0 ||
02615 db_dirdelete(wdbp->dbip, dp) < 0) {
02616
02617 Tcl_AppendResult(interp,
02618 "an error occurred while deleting ",
02619 argv[i], (char *)NULL);
02620 return TCL_ERROR;
02621 }
02622 }
02623 }
02624
02625 return TCL_OK;
02626 }
02627
02628
02629
02630
02631
02632 static int
02633 wdb_kill_tcl(ClientData clientData,
02634 Tcl_Interp *interp,
02635 int argc,
02636 char **argv)
02637 {
02638 struct rt_wdb *wdbp = (struct rt_wdb *)clientData;
02639
02640 return wdb_kill_cmd(wdbp, interp, argc-1, argv+1);
02641 }
02642
02643 int
02644 wdb_killall_cmd(struct rt_wdb *wdbp,
02645 Tcl_Interp *interp,
02646 int argc,
02647 char **argv)
02648 {
02649 register int i,k;
02650 register struct directory *dp;
02651 struct rt_db_internal intern;
02652 struct rt_comb_internal *comb;
02653 int ret;
02654
02655 WDB_TCL_CHECK_READ_ONLY;
02656
02657 if (argc < 2 || MAXARGS < argc) {
02658 struct bu_vls vls;
02659
02660 bu_vls_init(&vls);
02661 bu_vls_printf(&vls, "helplib_alias wdb_killall %s", argv[0]);
02662 Tcl_Eval(interp, bu_vls_addr(&vls));
02663 bu_vls_free(&vls);
02664 return TCL_ERROR;
02665 }
02666
02667 ret = TCL_OK;
02668
02669
02670 for (i = 0; i < RT_DBNHASH; i++) {
02671 for (dp = wdbp->dbip->dbi_Head[i]; dp != DIR_NULL; dp = dp->d_forw) {
02672 if (!(dp->d_flags & DIR_COMB))
02673 continue;
02674
02675 if (rt_db_get_internal(&intern, dp, wdbp->dbip, (fastf_t *)NULL, &rt_uniresource) < 0) {
02676 Tcl_AppendResult(interp, "rt_db_get_internal(", dp->d_namep,
02677 ") failure", (char *)NULL );
02678 ret = TCL_ERROR;
02679 continue;
02680 }
02681 comb = (struct rt_comb_internal *)intern.idb_ptr;
02682 RT_CK_COMB(comb);
02683
02684 for (k=1; k<argc; k++) {
02685 int code;
02686
02687 code = db_tree_del_dbleaf(&(comb->tree), argv[k], &rt_uniresource);
02688 if (code == -1)
02689 continue;
02690 if (code == -2)
02691 continue;
02692 if (code < 0) {
02693 Tcl_AppendResult(interp, " ERROR_deleting ",
02694 dp->d_namep, "/", argv[k],
02695 "\n", (char *)NULL);
02696 ret = TCL_ERROR;
02697 } else {
02698 Tcl_AppendResult(interp, "deleted ",
02699 dp->d_namep, "/", argv[k],
02700 "\n", (char *)NULL);
02701 }
02702 }
02703
02704 if (rt_db_put_internal(dp, wdbp->dbip, &intern, &rt_uniresource) < 0) {
02705 Tcl_AppendResult(interp,
02706 "ERROR: Unable to write new combination into database.\n",
02707 (char *)NULL);
02708 ret = TCL_ERROR;
02709 continue;
02710 }
02711 }
02712 }
02713
02714 if (ret != TCL_OK) {
02715 Tcl_AppendResult(interp,
02716 "KILL skipped because of earlier errors.\n",
02717 (char *)NULL);
02718 return ret;
02719 }
02720
02721
02722
02723 argv[0] = "kill";
02724 return wdb_kill_cmd(wdbp, interp, argc, argv);
02725 }
02726
02727
02728
02729
02730
02731
02732
02733 static int
02734 wdb_killall_tcl(ClientData clientData,
02735 Tcl_Interp *interp,
02736 int argc,
02737 char **argv)
02738 {
02739 struct rt_wdb *wdbp = (struct rt_wdb *)clientData;
02740
02741 return wdb_killall_cmd(wdbp, interp, argc-1, argv+1);
02742 }
02743
02744 int
02745 wdb_killtree_cmd(struct rt_wdb *wdbp,
02746 Tcl_Interp *interp,
02747 int argc,
02748 char **argv)
02749 {
02750 register struct directory *dp;
02751 register int i;
02752 struct wdb_killtree_data ktd;
02753
02754 WDB_TCL_CHECK_READ_ONLY;
02755
02756 if (argc < 2 || MAXARGS < argc) {
02757 struct bu_vls vls;
02758
02759 bu_vls_init(&vls);
02760 bu_vls_printf(&vls, "helplib_alias wdb_killtree %s", argv[0]);
02761 Tcl_Eval(interp, bu_vls_addr(&vls));
02762 bu_vls_free(&vls);
02763 return TCL_ERROR;
02764 }
02765
02766 ktd.interp = interp;
02767 ktd.notify = 0;
02768
02769 for (i=1; i<argc; i++) {
02770 if ((dp = db_lookup(wdbp->dbip, argv[i], LOOKUP_NOISY)) == DIR_NULL)
02771 continue;
02772
02773
02774 if (dp->d_addr == RT_DIR_PHONY_ADDR)
02775 continue;
02776 #if 0
02777 if (i == argc-1)
02778 ktd.notify = 1;
02779 #endif
02780
02781 db_functree(wdbp->dbip, dp,
02782 wdb_killtree_callback, wdb_killtree_callback,
02783 wdbp->wdb_resp, (genptr_t)&ktd);
02784 }
02785
02786 dgo_notifyWdb(wdbp, interp);
02787
02788 return TCL_OK;
02789 }
02790
02791
02792
02793
02794
02795
02796
02797 static int
02798 wdb_killtree_tcl(ClientData clientData,
02799 Tcl_Interp *interp,
02800 int argc,
02801 char **argv)
02802 {
02803 struct rt_wdb *wdbp = (struct rt_wdb *)clientData;
02804
02805 return wdb_killtree_cmd(wdbp, interp, argc-1, argv+1);
02806 }
02807
02808
02809
02810
02811 static void
02812 wdb_killtree_callback(struct db_i *dbip,
02813 register struct directory *dp,
02814 genptr_t ptr) {
02815 struct wdb_killtree_data *ktdp = (struct wdb_killtree_data *)ptr;
02816 Tcl_Interp *interp = ktdp->interp;
02817
02818 if (dbip == DBI_NULL)
02819 return;
02820
02821 Tcl_AppendResult(interp, "KILL ", (dp->d_flags & DIR_COMB) ? "COMB" : "Solid",
02822 ": ", dp->d_namep, "\n", (char *)NULL);
02823
02824
02825 dgo_eraseobjall_callback(dbip, interp, dp, ktdp->notify);
02826
02827 if (db_delete(dbip, dp) < 0 || db_dirdelete(dbip, dp) < 0) {
02828 Tcl_AppendResult(interp,
02829 "an error occurred while deleting ",
02830 dp->d_namep, "\n", (char *)NULL);
02831 }
02832 }
02833
02834 int
02835 wdb_copy_cmd(struct rt_wdb *wdbp,
02836 Tcl_Interp *interp,
02837 int argc,
02838 char **argv)
02839 {
02840 register struct directory *proto;
02841 register struct directory *dp;
02842 struct bu_external external;
02843
02844 WDB_TCL_CHECK_READ_ONLY;
02845
02846 if (argc != 3) {
02847 struct bu_vls vls;
02848
02849 bu_vls_init(&vls);
02850 bu_vls_printf(&vls, "helplib_alias wdb_copy %s", argv[0]);
02851 Tcl_Eval(interp, bu_vls_addr(&vls));
02852 bu_vls_free(&vls);
02853 return TCL_ERROR;
02854 }
02855
02856 if ((proto = db_lookup(wdbp->dbip, argv[1], LOOKUP_NOISY)) == DIR_NULL)
02857 return TCL_ERROR;
02858
02859 if (db_lookup(wdbp->dbip, argv[2], LOOKUP_QUIET) != DIR_NULL) {
02860 Tcl_AppendResult(interp, argv[2], ": already exists", (char *)NULL);
02861 return TCL_ERROR;
02862 }
02863
02864 if (db_get_external(&external , proto , wdbp->dbip)) {
02865 Tcl_AppendResult(interp, "Database read error, aborting", (char *)NULL);
02866 return TCL_ERROR;
02867 }
02868
02869 if ((dp=db_diradd(wdbp->dbip, argv[2], -1, 0, proto->d_flags, (genptr_t)&proto->d_minor_type)) == DIR_NULL ) {
02870 Tcl_AppendResult(interp,
02871 "An error has occured while adding a new object to the database.",
02872 (char *)NULL);
02873 return TCL_ERROR;
02874 }
02875
02876 if (db_put_external(&external, dp, wdbp->dbip) < 0) {
02877 bu_free_external(&external);
02878 Tcl_AppendResult(interp, "Database write error, aborting", (char *)NULL);
02879 return TCL_ERROR;
02880 }
02881 bu_free_external(&external);
02882
02883 return TCL_OK;
02884 }
02885
02886
02887
02888
02889
02890 static int
02891 wdb_copy_tcl(ClientData clientData,
02892 Tcl_Interp *interp,
02893 int argc,
02894 char **argv)
02895 {
02896 struct rt_wdb *wdbp = (struct rt_wdb *)clientData;
02897
02898 return wdb_copy_cmd(wdbp, interp, argc-1, argv+1);
02899 }
02900
02901 int
02902 wdb_move_cmd(struct rt_wdb *wdbp,
02903 Tcl_Interp *interp,
02904 int argc,
02905 char **argv)
02906 {
02907 register struct directory *dp;
02908 struct rt_db_internal intern;
02909
02910 WDB_TCL_CHECK_READ_ONLY;
02911
02912 if (argc != 3) {
02913 struct bu_vls vls;
02914
02915 bu_vls_init(&vls);
02916 bu_vls_printf(&vls, "helplib_alias wdb_move %s", argv[0]);
02917 Tcl_Eval(interp, bu_vls_addr(&vls));
02918 bu_vls_free(&vls);
02919 return TCL_ERROR;
02920 }
02921
02922 if ((dp = db_lookup(wdbp->dbip, argv[1], LOOKUP_NOISY)) == DIR_NULL)
02923 return TCL_ERROR;
02924
02925 if (db_lookup(wdbp->dbip, argv[2], LOOKUP_QUIET) != DIR_NULL) {
02926 Tcl_AppendResult(interp, argv[2], ": already exists", (char *)NULL);
02927 return TCL_ERROR;
02928 }
02929
02930 if (rt_db_get_internal(&intern, dp, wdbp->dbip, (fastf_t *)NULL, &rt_uniresource) < 0) {
02931 Tcl_AppendResult(interp, "Database read error, aborting", (char *)NULL);
02932 return TCL_ERROR;
02933 }
02934
02935
02936 if (db_rename(wdbp->dbip, dp, argv[2]) < 0) {
02937 rt_db_free_internal(&intern, &rt_uniresource);
02938 Tcl_AppendResult(interp, "error in db_rename to ", argv[2],
02939 ", aborting", (char *)NULL);
02940 return TCL_ERROR;
02941 }
02942
02943
02944 if (rt_db_put_internal(dp, wdbp->dbip, &intern, &rt_uniresource) < 0) {
02945 Tcl_AppendResult(interp, "Database write error, aborting", (char *)NULL);
02946 return TCL_ERROR;
02947 }
02948
02949 return TCL_OK;
02950 }
02951
02952
02953
02954
02955
02956
02957
02958 static int
02959 wdb_move_tcl(ClientData clientData,
02960 Tcl_Interp *interp,
02961 int argc,
02962 char **argv)
02963 {
02964 struct rt_wdb *wdbp = (struct rt_wdb *)clientData;
02965
02966 return wdb_move_cmd(wdbp, interp, argc-1, argv+1);
02967 }
02968
02969
02970
02971
02972 int
02973 wdb_move_all_cmd(struct rt_wdb *wdbp,
02974 Tcl_Interp *interp,
02975 int argc,
02976 char **argv)
02977 {
02978 register int i;
02979 register struct directory *dp;
02980 struct rt_db_internal intern;
02981 struct rt_comb_internal *comb;
02982 struct bu_ptbl stack;
02983
02984 WDB_TCL_CHECK_READ_ONLY;
02985
02986 if (argc != 3) {
02987 struct bu_vls vls;
02988
02989 bu_vls_init(&vls);
02990 bu_vls_printf(&vls, "helplib_alias wdb_moveall %s", argv[0]);
02991 Tcl_Eval(interp, bu_vls_addr(&vls));
02992 bu_vls_free(&vls);
02993 return TCL_ERROR;
02994 }
02995
02996 if (wdbp->dbip->dbi_version < 5 && (int)strlen(argv[2]) > NAMESIZE) {
02997 struct bu_vls tmp_vls;
02998
02999 bu_vls_init(&tmp_vls);
03000 bu_vls_printf(&tmp_vls, "ERROR: name length limited to %d characters in v4 databases\n", NAMESIZE);
03001 Tcl_AppendResult(interp, bu_vls_addr(&tmp_vls), (char *)NULL);
03002 bu_vls_free(&tmp_vls);
03003 return TCL_ERROR;
03004 }
03005
03006
03007
03008
03009 if ((dp = db_lookup(wdbp->dbip, argv[1], LOOKUP_NOISY )) == DIR_NULL)
03010 return TCL_ERROR;
03011
03012 if (db_lookup(wdbp->dbip, argv[2], LOOKUP_QUIET) != DIR_NULL) {
03013 Tcl_AppendResult(interp, argv[2], ": already exists", (char *)NULL);
03014 return TCL_ERROR;
03015 }
03016
03017
03018
03019
03020
03021
03022
03023
03024 if (dp->d_major_type == DB5_MAJORTYPE_BRLCAD && \
03025 dp->d_minor_type == DB5_MINORTYPE_BRLCAD_SKETCH) {
03026
03027 struct directory *dirp;
03028
03029 for (i = 0; i < RT_DBNHASH; i++) {
03030 for (dirp = wdbp->dbip->dbi_Head[i]; dirp != DIR_NULL; dirp = dirp->d_forw) {
03031
03032 if (dirp->d_major_type == DB5_MAJORTYPE_BRLCAD && \
03033 dirp->d_minor_type == DB5_MINORTYPE_BRLCAD_EXTRUDE) {
03034 struct rt_extrude_internal *extrude;
03035
03036 if (rt_db_get_internal(&intern, dirp, wdbp->dbip, (fastf_t *)NULL, &rt_uniresource) < 0) {
03037 bu_log("Can't get extrude %s?\n", dirp->d_namep);
03038 continue;
03039 }
03040 extrude = (struct rt_extrude_internal *)intern.idb_ptr;
03041 RT_EXTRUDE_CK_MAGIC(extrude);
03042
03043 if (! strcmp(extrude->sketch_name, argv[1]) ) {
03044 bu_free(extrude->sketch_name, "sketch name");
03045 extrude->sketch_name = bu_strdup(argv[2]);
03046
03047 if (rt_db_put_internal(dirp, wdbp->dbip, &intern, &rt_uniresource) < 0) {
03048 bu_log("oops\n");
03049 }
03050 }
03051 }
03052 }
03053 }
03054 }
03055
03056
03057 if (db_rename(wdbp->dbip, dp, argv[2]) < 0) {
03058 Tcl_AppendResult(interp, "error in rename to ", argv[2],
03059 ", aborting", (char *)NULL);
03060 return TCL_ERROR;
03061 }
03062
03063
03064 if (rt_db_get_internal(&intern, dp, wdbp->dbip, (fastf_t *)NULL, &rt_uniresource) < 0) {
03065 Tcl_AppendResult(interp, "Database read error, aborting", (char *)NULL);
03066 return TCL_ERROR;
03067 }
03068
03069 if (rt_db_put_internal(dp, wdbp->dbip, &intern, &rt_uniresource) < 0) {
03070 Tcl_AppendResult(interp, "Database write error, aborting", (char *)NULL);
03071 return TCL_ERROR;
03072 }
03073
03074 bu_ptbl_init(&stack, 64, "combination stack for wdb_mvall_cmd");
03075
03076
03077
03078 for (i = 0; i < RT_DBNHASH; i++) {
03079 for (dp = wdbp->dbip->dbi_Head[i]; dp != DIR_NULL; dp = dp->d_forw) {
03080 union tree *comb_leaf;
03081 int done=0;
03082 int changed=0;
03083
03084
03085
03086 if (!(dp->d_flags & DIR_COMB))
03087 continue;
03088
03089 if (rt_db_get_internal(&intern, dp, wdbp->dbip, (fastf_t *)NULL, &rt_uniresource) < 0)
03090 continue;
03091 comb = (struct rt_comb_internal *)intern.idb_ptr;
03092
03093 bu_ptbl_reset(&stack);
03094
03095 comb_leaf = comb->tree;
03096 if (comb_leaf) {
03097 while (!done) {
03098 while(comb_leaf->tr_op != OP_DB_LEAF) {
03099 bu_ptbl_ins(&stack, (long *)comb_leaf);
03100 comb_leaf = comb_leaf->tr_b.tb_left;
03101 }
03102
03103 if (!strcmp(comb_leaf->tr_l.tl_name, argv[1])) {
03104 bu_free(comb_leaf->tr_l.tl_name, "comb_leaf->tr_l.tl_name");
03105 comb_leaf->tr_l.tl_name = bu_strdup(argv[2]);
03106 changed = 1;
03107 }
03108
03109 if (BU_PTBL_END(&stack) < 1) {
03110 done = 1;
03111 break;
03112 }
03113 comb_leaf = (union tree *)BU_PTBL_GET(&stack, BU_PTBL_END(&stack)-1);
03114 if (comb_leaf->tr_op != OP_DB_LEAF) {
03115 bu_ptbl_rm( &stack, (long *)comb_leaf );
03116 comb_leaf = comb_leaf->tr_b.tb_right;
03117 }
03118 }
03119 }
03120
03121 if (changed) {
03122 if (rt_db_put_internal(dp, wdbp->dbip, &intern, &rt_uniresource)) {
03123 bu_ptbl_free( &stack );
03124 rt_db_free_internal( &intern, &rt_uniresource );
03125 Tcl_AppendResult(interp,
03126 "Database write error, aborting",
03127 (char *)NULL);
03128 return TCL_ERROR;
03129 }
03130 }
03131 else
03132 rt_db_free_internal(&intern, &rt_uniresource);
03133 }
03134 }
03135
03136 bu_ptbl_free(&stack);
03137 return TCL_OK;
03138 }
03139
03140
03141
03142
03143
03144
03145
03146 static int
03147 wdb_move_all_tcl(ClientData clientData, Tcl_Interp *interp, int argc, char **argv)
03148 {
03149 struct rt_wdb *wdbp = (struct rt_wdb *)clientData;
03150
03151 return wdb_move_all_cmd(wdbp, interp, argc-1, argv+1);
03152 }
03153
03154 struct concat_data {
03155 int unique_mode;
03156 struct db_i *old_dbip;
03157 struct db_i *new_dbip;
03158 struct bu_vls prestr;
03159 };
03160
03161 #define ADD_PREFIX 1
03162 #define ADD_SUFFIX 2
03163 #define OLD_PREFIX 3
03164 #define V4_MAXNAME 16
03165
03166 static char *
03167 get_new_name(
03168 const char *name,
03169 struct db_i *dbip,
03170 Tcl_HashTable *name_tbl,
03171 Tcl_HashTable *used_names_tbl,
03172 struct concat_data *cc_data )
03173 {
03174 int new=0;
03175 Tcl_HashEntry *ptr;
03176 struct bu_vls new_name;
03177 int num=0;
03178 char *aname;
03179 char *ret_name;
03180
03181 ptr = Tcl_CreateHashEntry( name_tbl, name, &new );
03182
03183 if( !new ) {
03184 return( (char *)Tcl_GetHashValue( ptr ) );
03185 }
03186
03187
03188 bu_vls_init( &new_name );
03189 if( cc_data->unique_mode != OLD_PREFIX ) {
03190 bu_vls_strcpy( &new_name, name );
03191 aname = bu_vls_addr( &new_name );
03192 while( db_lookup( dbip, aname, LOOKUP_QUIET ) != DIR_NULL ||
03193 Tcl_FindHashEntry( used_names_tbl, aname ) != NULL ) {
03194 bu_vls_trunc( &new_name, 0 );
03195 num++;
03196 if( cc_data->unique_mode == ADD_PREFIX ) {
03197 bu_vls_printf( &new_name, "%d_", num);
03198 }
03199 bu_vls_strcat( &new_name, name );
03200 if( cc_data->unique_mode == ADD_SUFFIX ) {
03201 bu_vls_printf( &new_name, "_%d", num );
03202 }
03203 aname = bu_vls_addr( &new_name );
03204 }
03205 } else {
03206 bu_vls_vlscat( &new_name, &cc_data->prestr );
03207 bu_vls_strcat( &new_name, name );
03208 if( cc_data->old_dbip->dbi_version < 5 ) {
03209 bu_vls_trunc( &new_name, V4_MAXNAME );
03210 }
03211 }
03212
03213
03214
03215 ret_name = bu_vls_strgrab( &new_name );
03216 Tcl_SetHashValue( ptr, (ClientData)ret_name );
03217 (void)Tcl_CreateHashEntry( used_names_tbl, ret_name, &new );
03218
03219 return( ret_name );
03220 }
03221
03222 static void
03223 adjust_names(
03224 Tcl_Interp *interp,
03225 union tree *trp,
03226 struct db_i *dbip,
03227 Tcl_HashTable *name_tbl,
03228 Tcl_HashTable *used_names_tbl,
03229 struct concat_data *cc_data )
03230 {
03231 char *new_name;
03232
03233 switch( trp->tr_op ) {
03234 case OP_DB_LEAF:
03235 new_name = get_new_name( trp->tr_l.tl_name, dbip,
03236 name_tbl, used_names_tbl, cc_data );
03237 if( new_name ) {
03238 bu_free( trp->tr_l.tl_name, "leaf name" );
03239 trp->tr_l.tl_name = bu_strdup( new_name );
03240 }
03241 break;
03242 case OP_UNION:
03243 case OP_INTERSECT:
03244 case OP_SUBTRACT:
03245 case OP_XOR:
03246 adjust_names( interp, trp->tr_b.tb_left, dbip,
03247 name_tbl, used_names_tbl, cc_data );
03248 adjust_names( interp, trp->tr_b.tb_right, dbip,
03249 name_tbl, used_names_tbl, cc_data );
03250 break;
03251 case OP_NOT:
03252 case OP_GUARD:
03253 case OP_XNOP:
03254 adjust_names( interp, trp->tr_b.tb_left, dbip,
03255 name_tbl, used_names_tbl, cc_data );
03256 break;
03257 }
03258 }
03259
03260 static int
03261 copy_object(
03262 Tcl_Interp *interp,
03263 struct directory *input_dp,
03264 struct db_i *input_dbip,
03265 struct db_i *curr_dbip,
03266 Tcl_HashTable *name_tbl,
03267 Tcl_HashTable *used_names_tbl,
03268 struct concat_data *cc_data )
03269 {
03270 struct rt_db_internal ip;
03271 struct rt_extrude_internal *extr;
03272 struct rt_dsp_internal *dsp;
03273 struct rt_comb_internal *comb;
03274 struct directory *new_dp;
03275 char *new_name;
03276
03277 if( rt_db_get_internal( &ip, input_dp, input_dbip, NULL, &rt_uniresource) < 0 ) {
03278 Tcl_AppendResult(interp, "Failed to get internal form of object (", input_dp->d_namep,
03279 ") - aborting!!!\n", (char *)NULL );
03280 return TCL_ERROR;
03281 }
03282
03283 if( ip.idb_major_type == DB5_MAJORTYPE_BRLCAD ) {
03284
03285 switch( ip.idb_minor_type ) {
03286 case DB5_MINORTYPE_BRLCAD_COMBINATION:
03287 comb = (struct rt_comb_internal *)ip.idb_ptr;
03288 RT_CK_COMB_TCL( interp, comb );
03289 adjust_names( interp, comb->tree, curr_dbip, name_tbl, used_names_tbl, cc_data );
03290 break;
03291 case DB5_MINORTYPE_BRLCAD_EXTRUDE:
03292 extr = (struct rt_extrude_internal *)ip.idb_ptr;
03293 RT_EXTRUDE_CK_MAGIC( extr );
03294
03295 new_name = get_new_name( extr->sketch_name, curr_dbip, name_tbl, used_names_tbl, cc_data );
03296 if( new_name ) {
03297 bu_free( extr->sketch_name, "sketch name" );
03298 extr->sketch_name = bu_strdup( new_name );
03299 }
03300 break;
03301 case DB5_MINORTYPE_BRLCAD_DSP:
03302 dsp = (struct rt_dsp_internal *)ip.idb_ptr;
03303 RT_DSP_CK_MAGIC( dsp );
03304
03305 if( dsp->dsp_datasrc == RT_DSP_SRC_OBJ ) {
03306
03307 new_name = get_new_name( bu_vls_addr( &dsp->dsp_name ), curr_dbip,
03308 name_tbl, used_names_tbl, cc_data );
03309 if( new_name ) {
03310 bu_vls_free( &dsp->dsp_name );
03311 bu_vls_strcpy( &dsp->dsp_name, new_name );
03312 }
03313 }
03314 break;
03315 }
03316 }
03317
03318 new_name = get_new_name(input_dp->d_namep, curr_dbip, name_tbl, used_names_tbl , cc_data );
03319 if( !new_name ) {
03320 new_name = input_dp->d_namep;
03321 }
03322 if( (new_dp = db_diradd( curr_dbip, new_name, -1L, 0, input_dp->d_flags,
03323 (genptr_t)&input_dp->d_minor_type ) ) == DIR_NULL ) {
03324 Tcl_AppendResult(interp, "Failed to add new object name (", new_name,
03325 ") to directory - aborting!!\n", (char *)NULL );
03326 return TCL_ERROR;
03327 }
03328
03329 if( rt_db_put_internal( new_dp, curr_dbip, &ip, &rt_uniresource ) < 0 ) {
03330 Tcl_AppendResult(interp, "Failed to write new object (", new_name,
03331 ") to database - aborting!!\n", (char *)NULL );
03332 return TCL_ERROR;
03333 }
03334
03335 return TCL_OK;
03336 }
03337
03338 int
03339 wdb_concat_cmd(struct rt_wdb *wdbp,
03340 Tcl_Interp *interp,
03341 int argc,
03342 char **argv)
03343 {
03344 struct db_i *newdbp;
03345 int bad = 0;
03346 int file_index;
03347 struct directory *dp;
03348 Tcl_HashTable name_tbl;
03349 Tcl_HashTable used_names_tbl;
03350 Tcl_HashEntry *ptr;
03351 Tcl_HashSearch search;
03352 struct concat_data cc_data;
03353
03354 WDB_TCL_CHECK_READ_ONLY;
03355
03356 if (argc != 3 ) {
03357 struct bu_vls vls;
03358
03359 bu_vls_init(&vls);
03360 bu_vls_printf(&vls, "helplib_alias wdb_concat %s", argv[0]);
03361 Tcl_Eval(interp, bu_vls_addr(&vls));
03362 bu_vls_free(&vls);
03363 return TCL_ERROR;
03364 }
03365
03366 bu_vls_init( &cc_data.prestr );
03367
03368 if( argv[1][0] == '-' ) {
03369
03370 file_index = 2;
03371
03372 if( argv[1][1] == 'p' ) {
03373 cc_data.unique_mode = ADD_PREFIX;
03374 } else if( argv[1][1] == 's' ) {
03375 cc_data.unique_mode = ADD_SUFFIX;
03376 } else {
03377 struct bu_vls vls;
03378
03379 bu_vls_init(&vls);
03380 bu_vls_printf(&vls, "helplib_alias wdb_concat %s", argv[0]);
03381 Tcl_Eval(interp, bu_vls_addr(&vls));
03382 bu_vls_free(&vls);
03383 return TCL_ERROR;
03384 }
03385 } else {
03386 file_index = 1;
03387 cc_data.unique_mode = OLD_PREFIX;
03388
03389 if (strcmp(argv[2], "/") != 0) {
03390 (void)bu_vls_strcpy(&cc_data.prestr, argv[2]);
03391 }
03392
03393 if( wdbp->dbip->dbi_version < 5 ) {
03394 if ( bu_vls_strlen(&cc_data.prestr) > 12) {
03395 bu_vls_trunc( &cc_data.prestr, 12 );
03396 }
03397 }
03398 }
03399
03400
03401 if ((newdbp = db_open(argv[file_index], "r")) == DBI_NULL) {
03402 perror(argv[file_index]);
03403 Tcl_AppendResult(interp, "concat: Can't open ",
03404 argv[file_index], (char *)NULL);
03405 return TCL_ERROR;
03406 }
03407
03408 if( newdbp->dbi_version > 4 && wdbp->dbip->dbi_version < 5 ) {
03409 Tcl_AppendResult(interp, "concat: databases are incompatible, convert ",
03410 wdbp->dbip->dbi_filename, " to version 5 first",
03411 (char *)NULL );
03412 return TCL_ERROR;
03413 }
03414
03415 db_dirbuild( newdbp );
03416
03417 cc_data.new_dbip = newdbp;
03418 cc_data.old_dbip = wdbp->dbip;
03419
03420
03421 Tcl_InitHashTable( &name_tbl, TCL_STRING_KEYS );
03422 Tcl_InitHashTable( &used_names_tbl, TCL_STRING_KEYS );
03423 FOR_ALL_DIRECTORY_START( dp, newdbp )
03424 if( dp->d_major_type == DB5_MAJORTYPE_ATTRIBUTE_ONLY ) {
03425
03426 continue;
03427 }
03428
03429 copy_object( interp, dp, newdbp, wdbp->dbip, &name_tbl,
03430 &used_names_tbl, &cc_data );
03431 FOR_ALL_DIRECTORY_END;
03432
03433 bu_vls_free( &cc_data.prestr );
03434 rt_mempurge(&(newdbp->dbi_freep));
03435
03436
03437 db_close(newdbp);
03438
03439 db_sync(wdbp->dbip);
03440
03441
03442 ptr = Tcl_FirstHashEntry( &name_tbl, &search );
03443 while( ptr ) {
03444 bu_free( (char *)Tcl_GetHashValue( ptr ), "new name" );
03445 ptr = Tcl_NextHashEntry( &search );
03446 }
03447 Tcl_DeleteHashTable( &name_tbl );
03448 Tcl_DeleteHashTable( &used_names_tbl );
03449
03450 return bad ? TCL_ERROR : TCL_OK;
03451 }
03452
03453
03454
03455
03456
03457
03458
03459 static int
03460 wdb_concat_tcl(ClientData clientData,
03461 Tcl_Interp *interp,
03462 int argc,
03463 char **argv)
03464 {
03465 struct rt_wdb *wdbp = (struct rt_wdb *)clientData;
03466
03467 return wdb_concat_cmd(wdbp, interp, argc-1, argv+1);
03468 }
03469
03470 int
03471 wdb_copyeval_cmd(struct rt_wdb *wdbp,
03472 Tcl_Interp *interp,
03473 int argc,
03474 char **argv)
03475 {
03476 struct directory *dp;
03477 struct rt_db_internal internal, new_int;
03478 mat_t start_mat;
03479 int id;
03480 int i;
03481 int endpos;
03482 struct wdb_trace_data wtd;
03483
03484 WDB_TCL_CHECK_READ_ONLY;
03485
03486 if (argc < 3 || 27 < argc) {
03487 struct bu_vls vls;
03488
03489 bu_vls_init(&vls);
03490 bu_vls_printf(&vls, "helplib_alias wdb_copyeval %s", argv[0]);
03491 Tcl_Eval(interp, bu_vls_addr(&vls));
03492 bu_vls_free(&vls);
03493 return TCL_ERROR;
03494 }
03495
03496
03497 wtd.wtd_interp = interp;
03498 wtd.wtd_dbip = wdbp->dbip;
03499 wtd.wtd_flag = WDB_CPEVAL;
03500 wtd.wtd_prflag = 0;
03501
03502
03503 if (db_lookup(wdbp->dbip, argv[1], LOOKUP_QUIET) != DIR_NULL) {
03504 Tcl_AppendResult(interp, argv[1], ": already exists\n", (char *)NULL);
03505 return TCL_ERROR;
03506 }
03507
03508 MAT_IDN(start_mat);
03509
03510
03511 if (argc == 3 && strchr(argv[2], '/')) {
03512 char *tok;
03513
03514 endpos = 0;
03515
03516 tok = strtok(argv[2], "/");
03517 while (tok) {
03518 if ((wtd.wtd_obj[endpos++] = db_lookup(wdbp->dbip, tok, LOOKUP_NOISY)) == DIR_NULL)
03519 return TCL_ERROR;
03520 tok = strtok((char *)NULL, "/");
03521 }
03522 } else {
03523 for (i=2; i<argc; i++) {
03524 if ((wtd.wtd_obj[i-2] = db_lookup(wdbp->dbip, argv[i], LOOKUP_NOISY)) == DIR_NULL)
03525 return TCL_ERROR;
03526 }
03527 endpos = argc - 2;
03528 }
03529
03530 wtd.wtd_objpos = endpos - 1;
03531
03532
03533 if ((id = rt_db_get_internal(&internal, wtd.wtd_obj[endpos - 1], wdbp->dbip, bn_mat_identity, &rt_uniresource)) < 0) {
03534 Tcl_AppendResult(interp, "import failure on ",
03535 argv[argc-1], "\n", (char *)NULL);
03536 return TCL_ERROR;
03537 }
03538
03539 if (id >= ID_COMBINATION) {
03540 rt_db_free_internal(&internal, &rt_uniresource);
03541 Tcl_AppendResult(interp, "final component on path must be a solid!!!\n", (char *)NULL );
03542 return TCL_ERROR;
03543 }
03544
03545 wdb_trace(wtd.wtd_obj[0], 0, start_mat, &wtd);
03546
03547 if (wtd.wtd_prflag == 0) {
03548 Tcl_AppendResult(interp, "PATH: ", (char *)NULL);
03549
03550 for (i=0; i<wtd.wtd_objpos; i++)
03551 Tcl_AppendResult(interp, "/", wtd.wtd_obj[i]->d_namep, (char *)NULL);
03552
03553 Tcl_AppendResult(interp, " NOT FOUND\n", (char *)NULL);
03554 rt_db_free_internal(&internal, &rt_uniresource);
03555 return TCL_ERROR;
03556 }
03557
03558
03559
03560
03561
03562 RT_INIT_DB_INTERNAL(&new_int);
03563 if (rt_generic_xform(&new_int, wtd.wtd_xform,
03564 &internal, 0, wdbp->dbip, &rt_uniresource)) {
03565 rt_db_free_internal(&internal, &rt_uniresource);
03566 Tcl_AppendResult(interp, "wdb_copyeval_cmd: rt_generic_xform failed\n", (char *)NULL);
03567 return TCL_ERROR;
03568 }
03569
03570 if ((dp=db_diradd(wdbp->dbip, argv[1], -1L, 0,
03571 wtd.wtd_obj[endpos-1]->d_flags,
03572 (genptr_t)&new_int.idb_type)) == DIR_NULL) {
03573 rt_db_free_internal(&internal, &rt_uniresource);
03574 rt_db_free_internal(&new_int, &rt_uniresource);
03575 WDB_TCL_ALLOC_ERR_return;
03576 }
03577
03578 if (rt_db_put_internal(dp, wdbp->dbip, &new_int, &rt_uniresource) < 0) {
03579 rt_db_free_internal(&internal, &rt_uniresource);
03580 rt_db_free_internal(&new_int, &rt_uniresource);
03581 WDB_TCL_WRITE_ERR_return;
03582 }
03583 rt_db_free_internal(&internal, &rt_uniresource);
03584 rt_db_free_internal(&new_int, &rt_uniresource);
03585
03586 return TCL_OK;
03587 }
03588
03589
03590
03591
03592
03593
03594
03595 static int
03596 wdb_copyeval_tcl(ClientData clientData,
03597 Tcl_Interp *interp,
03598 int argc,
03599 char **argv)
03600 {
03601 struct rt_wdb *wdbp = (struct rt_wdb *)clientData;
03602
03603 return wdb_copyeval_cmd(wdbp, interp, argc-1, argv+1);
03604 }
03605
03606 BU_EXTERN(int wdb_dir_check, ( struct
03607 db_i *input_dbip, const char *name, long laddr, int len, int flags,
03608 genptr_t ptr));
03609
03610 struct dir_check_stuff {
03611 struct db_i *main_dbip;
03612 struct rt_wdb *wdbp;
03613 struct directory **dup_dirp;
03614 };
03615
03616 BU_EXTERN(void wdb_dir_check5, ( struct db_i *input_dbip, const struct db5_raw_internal *rip, long addr, genptr_t ptr));
03617
03618 void
03619 wdb_dir_check5(register struct db_i *input_dbip,
03620 const struct db5_raw_internal *rip,
03621 long addr,
03622 genptr_t ptr)
03623 {
03624 char *name;
03625 struct directory *dupdp;
03626 struct bu_vls local;
03627 struct dir_check_stuff *dcsp = (struct dir_check_stuff *)ptr;
03628
03629 if (dcsp->main_dbip == DBI_NULL)
03630 return;
03631
03632 RT_CK_DBI(input_dbip);
03633 RT_CK_RIP( rip );
03634
03635 if( rip->h_dli == DB5HDR_HFLAGS_DLI_HEADER_OBJECT ) return;
03636 if( rip->h_dli == DB5HDR_HFLAGS_DLI_FREE_STORAGE ) return;
03637
03638 name = (char *)rip->name.ext_buf;
03639
03640 if( name == (char *)NULL ) return;
03641
03642
03643 if( rip->major_type == DB5_MAJORTYPE_ATTRIBUTE_ONLY &&
03644 rip->minor_type == 0 )
03645 return;
03646
03647
03648 bu_vls_init( &local );
03649 if( dcsp->main_dbip->dbi_version < 5 ) {
03650 if (dcsp->wdbp->wdb_ncharadd > 0) {
03651 bu_vls_strncpy( &local, bu_vls_addr( &dcsp->wdbp->wdb_prestr ), dcsp->wdbp->wdb_ncharadd );
03652 bu_vls_strcat( &local, name );
03653 } else {
03654 bu_vls_strncpy( &local, name, V4_MAXNAME );
03655 }
03656 bu_vls_trunc( &local, V4_MAXNAME );
03657 } else {
03658 if (dcsp->wdbp->wdb_ncharadd > 0) {
03659 (void)bu_vls_vlscat( &local, &dcsp->wdbp->wdb_prestr );
03660 (void)bu_vls_strcat( &local, name );
03661 } else {
03662 (void)bu_vls_strcat( &local, name );
03663 }
03664 }
03665
03666
03667 if ((dupdp = db_lookup(dcsp->main_dbip, bu_vls_addr( &local ), LOOKUP_QUIET)) != DIR_NULL) {
03668
03669 dcsp->wdbp->wdb_num_dups++;
03670 *dcsp->dup_dirp++ = dupdp;
03671 }
03672 return;
03673 }
03674
03675
03676
03677
03678
03679
03680 int
03681 wdb_dir_check(register struct db_i *input_dbip, register const char *name, long int laddr, int len, int flags, genptr_t ptr)
03682 {
03683 struct directory *dupdp;
03684 struct bu_vls local;
03685 struct dir_check_stuff *dcsp = (struct dir_check_stuff *)ptr;
03686
03687 if (dcsp->main_dbip == DBI_NULL)
03688 return 0;
03689
03690 RT_CK_DBI(input_dbip);
03691
03692
03693 bu_vls_init( &local );
03694 if( dcsp->main_dbip->dbi_version < 5 ) {
03695 if (dcsp->wdbp->wdb_ncharadd > 0) {
03696 bu_vls_strncpy( &local, bu_vls_addr( &dcsp->wdbp->wdb_prestr ), dcsp->wdbp->wdb_ncharadd );
03697 bu_vls_strcat( &local, name );
03698 } else {
03699 bu_vls_strncpy( &local, name, V4_MAXNAME );
03700 }
03701 bu_vls_trunc( &local, V4_MAXNAME );
03702 } else {
03703 if (dcsp->wdbp->wdb_ncharadd > 0) {
03704 bu_vls_vlscat( &local, &dcsp->wdbp->wdb_prestr );
03705 bu_vls_strcat( &local, name );
03706 } else {
03707 bu_vls_strcat( &local, name );
03708 }
03709 }
03710
03711
03712 if ((dupdp = db_lookup(dcsp->main_dbip, bu_vls_addr( &local ), LOOKUP_QUIET)) != DIR_NULL) {
03713
03714 dcsp->wdbp->wdb_num_dups++;
03715 *dcsp->dup_dirp++ = dupdp;
03716 }
03717 bu_vls_free( &local );
03718 return 0;
03719 }
03720
03721 int
03722 wdb_dup_cmd(struct rt_wdb *wdbp,
03723 Tcl_Interp *interp,
03724 int argc,
03725 char **argv)
03726 {
03727 struct db_i *newdbp = DBI_NULL;
03728 struct directory **dirp0 = (struct directory **)NULL;
03729 struct bu_vls vls;
03730 struct dir_check_stuff dcs;
03731
03732 if (argc < 2 || 3 < argc) {
03733 struct bu_vls vls;
03734
03735 bu_vls_init(&vls);
03736 bu_vls_printf(&vls, "helplib_alias wdb_dup %s", argv[0]);
03737 Tcl_Eval(interp, bu_vls_addr(&vls));
03738 bu_vls_free(&vls);
03739 return TCL_ERROR;
03740 }
03741
03742 bu_vls_trunc( &wdbp->wdb_prestr, 0 );
03743 if (argc == 3)
03744 (void)bu_vls_strcpy(&wdbp->wdb_prestr, argv[2]);
03745
03746 wdbp->wdb_num_dups = 0;
03747 if( wdbp->dbip->dbi_version < 5 ) {
03748 if ((wdbp->wdb_ncharadd = bu_vls_strlen(&wdbp->wdb_prestr)) > 12) {
03749 wdbp->wdb_ncharadd = 12;
03750 bu_vls_trunc( &wdbp->wdb_prestr, 12 );
03751 }
03752 } else {
03753 wdbp->wdb_ncharadd = bu_vls_strlen(&wdbp->wdb_prestr);
03754 }
03755
03756
03757 if ((newdbp = db_open(argv[1], "r")) == DBI_NULL) {
03758 perror(argv[1]);
03759 Tcl_AppendResult(interp, "dup: Can't open ", argv[1], (char *)NULL);
03760 return TCL_ERROR;
03761 }
03762
03763 Tcl_AppendResult(interp, "\n*** Comparing ",
03764 wdbp->dbip->dbi_filename,
03765 " with ", argv[1], " for duplicate names\n", (char *)NULL);
03766 if (wdbp->wdb_ncharadd) {
03767 Tcl_AppendResult(interp, " For comparison, all names in ",
03768 argv[1], " were prefixed with: ",
03769 bu_vls_addr( &wdbp->wdb_prestr ), "\n", (char *)NULL);
03770 }
03771
03772
03773 if ((dirp0 = wdb_getspace(wdbp->dbip, 0)) == (struct directory **) 0) {
03774 Tcl_AppendResult(interp, "f_dup: unable to get memory\n", (char *)NULL);
03775 db_close( newdbp );
03776 return TCL_ERROR;
03777 }
03778
03779
03780 dcs.main_dbip = wdbp->dbip;
03781 dcs.wdbp = wdbp;
03782 dcs.dup_dirp = dirp0;
03783 if( newdbp->dbi_version < 5 ) {
03784 if (db_scan(newdbp, wdb_dir_check, 0, (genptr_t)&dcs) < 0) {
03785 Tcl_AppendResult(interp, "dup: db_scan failure", (char *)NULL);
03786 bu_free((genptr_t)dirp0, "wdb_getspace array");
03787 db_close(newdbp);
03788 return TCL_ERROR;
03789 }
03790 } else {
03791 if( db5_scan( newdbp, wdb_dir_check5, (genptr_t)&dcs) < 0) {
03792 Tcl_AppendResult(interp, "dup: db_scan failure", (char *)NULL);
03793 bu_free((genptr_t)dirp0, "wdb_getspace array");
03794 db_close(newdbp);
03795 return TCL_ERROR;
03796 }
03797 }
03798 rt_mempurge( &(newdbp->dbi_freep) );
03799
03800 bu_vls_init(&vls);
03801 wdb_vls_col_pr4v(&vls, dirp0, (int)(dcs.dup_dirp - dirp0), 0);
03802 bu_vls_printf(&vls, "\n ----- %d duplicate names found -----", wdbp->wdb_num_dups);
03803 Tcl_AppendResult(interp, bu_vls_addr(&vls), (char *)NULL);
03804 bu_vls_free(&vls);
03805 bu_free((genptr_t)dirp0, "wdb_getspace array");
03806 db_close(newdbp);
03807
03808 return TCL_OK;
03809 }
03810
03811
03812
03813
03814
03815 static int
03816 wdb_dup_tcl(ClientData clientData, Tcl_Interp *interp, int argc, char **argv)
03817 {
03818 struct rt_wdb *wdbp = (struct rt_wdb *)clientData;
03819
03820 return wdb_dup_cmd(wdbp, interp, argc-1, argv+1);
03821 }
03822
03823 int
03824 wdb_group_cmd(struct rt_wdb *wdbp,
03825 Tcl_Interp *interp,
03826 int argc,
03827 char **argv)
03828 {
03829 register struct directory *dp;
03830 register int i;
03831
03832 WDB_TCL_CHECK_READ_ONLY;
03833
03834 if (argc < 3 || MAXARGS < argc) {
03835 struct bu_vls vls;
03836
03837 bu_vls_init(&vls);
03838 bu_vls_printf(&vls, "helplib_alias wdb_group %s", argv[0]);
03839 Tcl_Eval(interp, bu_vls_addr(&vls));
03840 bu_vls_free(&vls);
03841 return TCL_ERROR;
03842 }
03843
03844
03845 for (i = 2; i < argc; i++) {
03846 if ((dp = db_lookup(wdbp->dbip, argv[i], LOOKUP_NOISY)) != DIR_NULL) {
03847 if (wdb_combadd(interp, wdbp->dbip, dp, argv[1], 0,
03848 WMOP_UNION, 0, 0, wdbp) == DIR_NULL)
03849 return TCL_ERROR;
03850 } else
03851 Tcl_AppendResult(interp, "skip member ", argv[i], "\n", (char *)NULL);
03852 }
03853 return TCL_OK;
03854 }
03855
03856
03857
03858
03859
03860 static int
03861 wdb_group_tcl(ClientData clientData,
03862 Tcl_Interp *interp,
03863 int argc,
03864 char **argv)
03865 {
03866 struct rt_wdb *wdbp = (struct rt_wdb *)clientData;
03867
03868 return wdb_group_cmd(wdbp, interp, argc-1, argv+1);
03869 }
03870
03871 int
03872 wdb_remove_cmd(struct rt_wdb *wdbp,
03873 Tcl_Interp *interp,
03874 int argc,
03875 char **argv)
03876 {
03877 register struct directory *dp;
03878 register int i;
03879 int num_deleted;
03880 struct rt_db_internal intern;
03881 struct rt_comb_internal *comb;
03882 int ret;
03883
03884 WDB_TCL_CHECK_READ_ONLY;
03885
03886 if (argc < 3 || MAXARGS < argc) {
03887 struct bu_vls vls;
03888
03889 bu_vls_init(&vls);
03890 bu_vls_printf(&vls, "helplib_alias wdb_remove %s", argv[0]);
03891 Tcl_Eval(interp, bu_vls_addr(&vls));
03892 bu_vls_free(&vls);
03893 return TCL_ERROR;
03894 }
03895
03896 if ((dp = db_lookup(wdbp->dbip, argv[1], LOOKUP_NOISY)) == DIR_NULL)
03897 return TCL_ERROR;
03898
03899 if ((dp->d_flags & DIR_COMB) == 0) {
03900 Tcl_AppendResult(interp, "rm: ", dp->d_namep,
03901 " is not a combination", (char *)NULL );
03902 return TCL_ERROR;
03903 }
03904
03905 if (rt_db_get_internal(&intern, dp, wdbp->dbip, (fastf_t *)NULL, &rt_uniresource) < 0) {
03906 Tcl_AppendResult(interp, "Database read error, aborting", (char *)NULL);
03907 return TCL_ERROR;
03908 }
03909
03910 comb = (struct rt_comb_internal *)intern.idb_ptr;
03911 RT_CK_COMB(comb);
03912
03913
03914 num_deleted = 0;
03915 ret = TCL_OK;
03916 for (i = 2; i < argc; i++) {
03917 if (db_tree_del_dbleaf( &(comb->tree), argv[i], &rt_uniresource ) < 0) {
03918 Tcl_AppendResult(interp, " ERROR_deleting ",
03919 dp->d_namep, "/", argv[i],
03920 "\n", (char *)NULL);
03921 ret = TCL_ERROR;
03922 } else {
03923 Tcl_AppendResult(interp, "deleted ",
03924 dp->d_namep, "/", argv[i],
03925 "\n", (char *)NULL);
03926 num_deleted++;
03927 }
03928 }
03929
03930 if (rt_db_put_internal(dp, wdbp->dbip, &intern, &rt_uniresource) < 0) {
03931 Tcl_AppendResult(interp, "Database write error, aborting", (char *)NULL);
03932 return TCL_ERROR;
03933 }
03934
03935 return ret;
03936 }
03937
03938
03939
03940
03941
03942
03943
03944 static int
03945 wdb_remove_tcl(ClientData clientData, Tcl_Interp *interp, int argc, char **argv)
03946 {
03947 struct rt_wdb *wdbp = (struct rt_wdb *)clientData;
03948
03949 return wdb_remove_cmd(wdbp, interp, argc-1, argv+1);
03950 }
03951
03952 int
03953 wdb_region_cmd(struct rt_wdb *wdbp,
03954 Tcl_Interp *interp,
03955 int argc,
03956 char **argv)
03957 {
03958 register struct directory *dp;
03959 int i;
03960 int ident, air;
03961 char oper;
03962
03963 WDB_TCL_CHECK_READ_ONLY;
03964
03965 if (argc < 4 || MAXARGS < argc) {
03966 struct bu_vls vls;
03967
03968 bu_vls_init(&vls);
03969 bu_vls_printf(&vls, "helplib_alias wdb_region %s", argv[0]);
03970 Tcl_Eval(interp, bu_vls_addr(&vls));
03971 bu_vls_free(&vls);
03972 return TCL_ERROR;
03973 }
03974
03975 ident = wdbp->wdb_item_default;
03976 air = wdbp->wdb_air_default;
03977
03978
03979 if (argc & 01) {
03980 Tcl_AppendResult(interp, "error in number of args!", (char *)NULL);
03981 return TCL_ERROR;
03982 }
03983
03984 if (db_lookup(wdbp->dbip, argv[1], LOOKUP_QUIET) == DIR_NULL) {
03985
03986 if (wdbp->wdb_item_default) {
03987 struct bu_vls tmp_vls;
03988
03989 wdbp->wdb_item_default++;
03990 bu_vls_init(&tmp_vls);
03991 bu_vls_printf(&tmp_vls, "Defaulting item number to %d\n",
03992 wdbp->wdb_item_default);
03993 Tcl_AppendResult(interp, bu_vls_addr(&tmp_vls), (char *)NULL);
03994 bu_vls_free(&tmp_vls);
03995 }
03996 }
03997
03998
03999 for (i = 2; i < argc; i += 2) {
04000 if (argv[i][1] != '\0') {
04001 Tcl_AppendResult(interp, "bad operation: ", argv[i],
04002 " skip member: ", argv[i+1], "\n", (char *)NULL);
04003 continue;
04004 }
04005 oper = argv[i][0];
04006 if ((dp = db_lookup(wdbp->dbip, argv[i+1], LOOKUP_NOISY )) == DIR_NULL) {
04007 Tcl_AppendResult(interp, "skipping ", argv[i+1], "\n", (char *)NULL);
04008 continue;
04009 }
04010
04011 if (oper != WMOP_UNION && oper != WMOP_SUBTRACT && oper != WMOP_INTERSECT) {
04012 struct bu_vls tmp_vls;
04013
04014 bu_vls_init(&tmp_vls);
04015 bu_vls_printf(&tmp_vls, "bad operation: %c skip member: %s\n",
04016 oper, dp->d_namep );
04017 Tcl_AppendResult(interp, bu_vls_addr(&tmp_vls), (char *)NULL);
04018 bu_vls_free(&tmp_vls);
04019 continue;
04020 }
04021
04022
04023 if (dp->d_flags & DIR_REGION) {
04024 Tcl_AppendResult(interp, "Note: ", dp->d_namep,
04025 " is a region\n", (char *)NULL);
04026 }
04027
04028 if (wdb_combadd(interp, wdbp->dbip, dp,
04029 argv[1], 1, oper, ident, air, wdbp) == DIR_NULL) {
04030 Tcl_AppendResult(interp, "error in combadd", (char *)NULL);
04031 return TCL_ERROR;
04032 }
04033 }
04034
04035 if (db_lookup(wdbp->dbip, argv[1], LOOKUP_QUIET) == DIR_NULL) {
04036
04037 if (wdbp->wdb_item_default > 1)
04038 wdbp->wdb_item_default--;
04039 return TCL_ERROR;
04040 }
04041
04042 return TCL_OK;
04043 }
04044
04045
04046
04047
04048
04049 static int
04050 wdb_region_tcl(ClientData clientData, Tcl_Interp *interp, int argc, char **argv)
04051 {
04052 struct rt_wdb *wdbp = (struct rt_wdb *)clientData;
04053
04054 return wdb_region_cmd(wdbp, interp, argc-1, argv+1);
04055 }
04056
04057 int
04058 wdb_comb_cmd(struct rt_wdb *wdbp,
04059 Tcl_Interp *interp,
04060 int argc,
04061 char **argv)
04062 {
04063 register struct directory *dp;
04064 char *comb_name;
04065 register int i;
04066 char oper;
04067
04068 WDB_TCL_CHECK_READ_ONLY;
04069
04070 if (argc < 4 || MAXARGS < argc) {
04071 struct bu_vls vls;
04072
04073 bu_vls_init(&vls);
04074 bu_vls_printf(&vls, "helplib_alias wdb_comb %s", argv[0]);
04075 Tcl_Eval(interp, bu_vls_addr(&vls));
04076 bu_vls_free(&vls);
04077 return TCL_ERROR;
04078 }
04079
04080
04081 if (argc & 01) {
04082 Tcl_AppendResult(interp, "error in number of args!", (char *)NULL);
04083 return TCL_ERROR;
04084 }
04085
04086
04087 comb_name = argv[1];
04088 if ((dp=db_lookup(wdbp->dbip, comb_name, LOOKUP_QUIET)) != DIR_NULL) {
04089 if (!(dp->d_flags & DIR_COMB)) {
04090 Tcl_AppendResult(interp,
04091 "ERROR: ", comb_name,
04092 " is not a combination", (char *)0 );
04093 return TCL_ERROR;
04094 }
04095 }
04096
04097
04098 for (i = 2; i < argc; i += 2) {
04099 if (argv[i][1] != '\0') {
04100 Tcl_AppendResult(interp, "bad operation: ", argv[i],
04101 " skip member: ", argv[i+1], "\n", (char *)NULL);
04102 continue;
04103 }
04104 oper = argv[i][0];
04105 if ((dp = db_lookup(wdbp->dbip, argv[i+1], LOOKUP_NOISY)) == DIR_NULL) {
04106 Tcl_AppendResult(interp, "skipping ", argv[i+1], "\n", (char *)NULL);
04107 continue;
04108 }
04109
04110 if (oper != WMOP_UNION && oper != WMOP_SUBTRACT && oper != WMOP_INTERSECT) {
04111 struct bu_vls tmp_vls;
04112
04113 bu_vls_init(&tmp_vls);
04114 bu_vls_printf(&tmp_vls, "bad operation: %c skip member: %s\n",
04115 oper, dp->d_namep);
04116 Tcl_AppendResult(interp, bu_vls_addr(&tmp_vls), (char *)NULL);
04117 continue;
04118 }
04119
04120 if (wdb_combadd(interp, wdbp->dbip, dp, comb_name, 0, oper, 0, 0, wdbp) == DIR_NULL) {
04121 Tcl_AppendResult(interp, "error in combadd", (char *)NULL);
04122 return TCL_ERROR;
04123 }
04124 }
04125
04126 if (db_lookup(wdbp->dbip, comb_name, LOOKUP_QUIET) == DIR_NULL) {
04127 Tcl_AppendResult(interp, "Error: ", comb_name,
04128 " not created", (char *)NULL);
04129 return TCL_ERROR;
04130 }
04131
04132 return TCL_OK;
04133 }
04134
04135
04136
04137
04138
04139
04140
04141
04142 static int
04143 wdb_comb_tcl(ClientData clientData, Tcl_Interp *interp, int argc, char **argv)
04144 {
04145 struct rt_wdb *wdbp = (struct rt_wdb *)clientData;
04146
04147 return wdb_comb_cmd(wdbp, interp, argc-1, argv+1);
04148 }
04149
04150 static void
04151 wdb_find_ref(struct db_i *dbip,
04152 struct rt_comb_internal *comb,
04153 union tree *comb_leaf,
04154 genptr_t object,
04155 genptr_t comb_name_ptr,
04156 genptr_t user_ptr3)
04157 {
04158 char *obj_name;
04159 char *comb_name;
04160 Tcl_Interp *interp = (Tcl_Interp *)user_ptr3;
04161
04162 RT_CK_TREE(comb_leaf);
04163
04164 obj_name = (char *)object;
04165 if (strcmp(comb_leaf->tr_l.tl_name, obj_name))
04166 return;
04167
04168 comb_name = (char *)comb_name_ptr;
04169
04170 Tcl_AppendElement(interp, comb_name);
04171 }
04172
04173 HIDDEN union tree *
04174 facetize_region_end( tsp, pathp, curtree, client_data )
04175 register struct db_tree_state *tsp;
04176 struct db_full_path *pathp;
04177 union tree *curtree;
04178 genptr_t client_data;
04179 {
04180 struct bu_list vhead;
04181 union tree **facetize_tree;
04182
04183 facetize_tree = (union tree **)client_data;
04184 BU_LIST_INIT( &vhead );
04185
04186 if( curtree->tr_op == OP_NOP ) return curtree;
04187
04188 if( *facetize_tree ) {
04189 union tree *tr;
04190 tr = (union tree *)bu_calloc(1, sizeof(union tree), "union tree");
04191 tr->magic = RT_TREE_MAGIC;
04192 tr->tr_op = OP_UNION;
04193 tr->tr_b.tb_regionp = REGION_NULL;
04194 tr->tr_b.tb_left = *facetize_tree;
04195 tr->tr_b.tb_right = curtree;
04196 *facetize_tree = tr;
04197 } else {
04198 *facetize_tree = curtree;
04199 }
04200
04201
04202 return( TREE_NULL );
04203 }
04204
04205 int
04206 wdb_facetize_cmd(struct rt_wdb *wdbp,
04207 Tcl_Interp *interp,
04208 int argc,
04209 char **argv)
04210 {
04211 int i;
04212 register int c;
04213 int triangulate;
04214 char *newname;
04215 struct rt_db_internal intern;
04216 struct directory *dp;
04217 int failed;
04218 int nmg_use_tnurbs = 0;
04219 int make_bot;
04220 struct db_tree_state init_state;
04221 struct db_i *dbip;
04222 union tree *facetize_tree;
04223 struct model *nmg_model;
04224
04225 if(argc < 3){
04226 Tcl_AppendResult(interp,
04227 "Usage: ",
04228 argv[0],
04229 " new_object old_object [old_object2 old_object3 ...]\n",
04230 (char *)NULL );
04231 return TCL_ERROR;
04232 }
04233
04234 dbip = wdbp->dbip;
04235 RT_CHECK_DBI(dbip);
04236
04237 db_init_db_tree_state( &init_state, dbip, wdbp->wdb_resp );
04238
04239
04240 init_state.ts_ttol = &wdbp->wdb_ttol;
04241 init_state.ts_tol = &wdbp->wdb_tol;
04242
04243
04244 triangulate = 0;
04245 make_bot = 1;
04246
04247
04248 bu_optind = 1;
04249 while( (c=bu_getopt(argc,argv,"ntT")) != EOF ) {
04250 switch(c) {
04251 case 'n':
04252 make_bot = 0;
04253 break;
04254 case 'T':
04255 triangulate = 1;
04256 break;
04257 case 't':
04258 nmg_use_tnurbs = 1;
04259 break;
04260 default:
04261 {
04262 struct bu_vls tmp_vls;
04263
04264 bu_vls_init(&tmp_vls);
04265 bu_vls_printf(&tmp_vls, "option '%c' unknown\n", c);
04266 Tcl_AppendResult(interp, bu_vls_addr(&tmp_vls),
04267 "Usage: facetize [-ntT] object(s)\n",
04268 "\t-n make NMG primitives rather than BOT's\n",
04269 "\t-t Perform CSG-to-tNURBS conversion\n",
04270 "\t-T enable triangulator\n", (char *)NULL);
04271 bu_vls_free(&tmp_vls);
04272 }
04273 break;
04274 }
04275 }
04276 argc -= bu_optind;
04277 argv += bu_optind;
04278 if( argc < 0 ){
04279 Tcl_AppendResult(interp, "facetize: missing argument\n", (char *)NULL);
04280 return TCL_ERROR;
04281 }
04282
04283 newname = argv[0];
04284 argv++;
04285 argc--;
04286 if( argc < 0 ){
04287 Tcl_AppendResult(interp, "facetize: missing argument\n", (char *)NULL);
04288 return TCL_ERROR;
04289 }
04290
04291 if( db_lookup( dbip, newname, LOOKUP_QUIET ) != DIR_NULL ) {
04292 Tcl_AppendResult(interp, "error: solid '", newname,
04293 "' already exists, aborting\n", (char *)NULL);
04294 return TCL_ERROR;
04295 }
04296
04297 {
04298 struct bu_vls tmp_vls;
04299
04300 bu_vls_init(&tmp_vls);
04301 bu_vls_printf(&tmp_vls,
04302 "facetize: tessellating primitives with tolerances a=%g, r=%g, n=%g\n",
04303 wdbp->wdb_ttol.abs, wdbp->wdb_ttol.rel, wdbp->wdb_ttol.norm );
04304 Tcl_AppendResult(interp, bu_vls_addr(&tmp_vls), (char *)NULL);
04305 bu_vls_free(&tmp_vls);
04306 }
04307 facetize_tree = (union tree *)0;
04308 nmg_model = nmg_mm();
04309 init_state.ts_m = &nmg_model;
04310
04311 i = db_walk_tree( dbip, argc, (const char **)argv,
04312 1,
04313 &init_state,
04314 0,
04315 facetize_region_end,
04316 nmg_use_tnurbs ?
04317 nmg_booltree_leaf_tnurb :
04318 nmg_booltree_leaf_tess,
04319 (genptr_t)&facetize_tree
04320 );
04321
04322
04323 if( i < 0 ) {
04324 Tcl_AppendResult(interp, "facetize: error in db_walk_tree()\n", (char *)NULL);
04325
04326 nmg_km( nmg_model );
04327 return TCL_ERROR;
04328 }
04329
04330 if( facetize_tree )
04331 {
04332
04333 Tcl_AppendResult(interp, "facetize: evaluating boolean expressions\n", (char *)NULL);
04334
04335 if( BU_SETJUMP )
04336 {
04337 BU_UNSETJUMP;
04338 Tcl_AppendResult(interp, "WARNING: facetization failed!!!\n", (char *)NULL );
04339 if( facetize_tree )
04340 db_free_tree( facetize_tree, &rt_uniresource );
04341 facetize_tree = (union tree *)NULL;
04342 nmg_km( nmg_model );
04343 nmg_model = (struct model *)NULL;
04344 return TCL_ERROR;
04345 }
04346
04347 failed = nmg_boolean( facetize_tree, nmg_model, &wdbp->wdb_tol, &rt_uniresource );
04348 BU_UNSETJUMP;
04349 }
04350 else
04351 failed = 1;
04352
04353 if( failed ) {
04354 Tcl_AppendResult(interp, "facetize: no resulting region, aborting\n", (char *)NULL);
04355 if( facetize_tree )
04356 db_free_tree( facetize_tree, &rt_uniresource );
04357 facetize_tree = (union tree *)NULL;
04358 nmg_km( nmg_model );
04359 nmg_model = (struct model *)NULL;
04360 return TCL_ERROR;
04361 }
04362
04363 NMG_CK_REGION( facetize_tree->tr_d.td_r );
04364 Tcl_AppendResult(interp, "facetize: ", facetize_tree->tr_d.td_name,
04365 "\n", (char *)NULL);
04366
04367
04368 if( triangulate && !make_bot )
04369 {
04370 Tcl_AppendResult(interp, "facetize: triangulating resulting object\n", (char *)NULL);
04371 if( BU_SETJUMP )
04372 {
04373 BU_UNSETJUMP;
04374 Tcl_AppendResult(interp, "WARNING: triangulation failed!!!\n", (char *)NULL );
04375 if( facetize_tree )
04376 db_free_tree( facetize_tree, &rt_uniresource );
04377 facetize_tree = (union tree *)NULL;
04378 nmg_km( nmg_model );
04379 nmg_model = (struct model *)NULL;
04380 return TCL_ERROR;
04381 }
04382 nmg_triangulate_model( nmg_model , &wdbp->wdb_tol );
04383 BU_UNSETJUMP;
04384 }
04385
04386 if( make_bot )
04387 {
04388 struct rt_bot_internal *bot;
04389 struct nmgregion *r;
04390 struct shell *s;
04391
04392 Tcl_AppendResult(interp, "facetize: converting to BOT format\n", (char *)NULL);
04393
04394 r = BU_LIST_FIRST( nmgregion, &nmg_model->r_hd );
04395 s = BU_LIST_FIRST( shell, &r->s_hd );
04396 bot = (struct rt_bot_internal *)nmg_bot( s, &wdbp->wdb_tol );
04397 nmg_km( nmg_model );
04398 nmg_model = (struct model *)NULL;
04399
04400
04401 RT_INIT_DB_INTERNAL(&intern);
04402 intern.idb_major_type = DB5_MAJORTYPE_BRLCAD;
04403 intern.idb_type = ID_BOT;
04404 intern.idb_meth = &rt_functab[ID_BOT];
04405 intern.idb_ptr = (genptr_t) bot;
04406 }
04407 else
04408 {
04409
04410 Tcl_AppendResult(interp, "facetize: converting NMG to database format\n", (char *)NULL);
04411
04412
04413 RT_INIT_DB_INTERNAL(&intern);
04414 intern.idb_major_type = DB5_MAJORTYPE_BRLCAD;
04415 intern.idb_type = ID_NMG;
04416 intern.idb_meth = &rt_functab[ID_NMG];
04417 intern.idb_ptr = (genptr_t)nmg_model;
04418 nmg_model = (struct model *)NULL;
04419 }
04420
04421 if( (dp=db_diradd( dbip, newname, -1L, 0, DIR_SOLID, (genptr_t)&intern.idb_type)) == DIR_NULL )
04422 {
04423 Tcl_AppendResult(interp, "Cannot add ", newname, " to directory\n", (char *)NULL );
04424 return TCL_ERROR;
04425 }
04426
04427 if( rt_db_put_internal( dp, dbip, &intern, &rt_uniresource ) < 0 )
04428 {
04429 Tcl_AppendResult(interp, "Failed to write ", newname, " to database\n", (char *)NULL );
04430 rt_db_free_internal( &intern, &rt_uniresource );
04431 return TCL_ERROR;
04432 }
04433
04434 facetize_tree->tr_d.td_r = (struct nmgregion *)NULL;
04435
04436
04437 db_free_tree( facetize_tree, &rt_uniresource );
04438 facetize_tree = (union tree *)NULL;
04439
04440 return TCL_OK;
04441 }
04442
04443 int
04444 wdb_find_cmd(struct rt_wdb *wdbp,
04445 Tcl_Interp *interp,
04446 int argc,
04447 char **argv)
04448 {
04449 register int i,k;
04450 register struct directory *dp;
04451 struct rt_db_internal intern;
04452 register struct rt_comb_internal *comb=(struct rt_comb_internal *)NULL;
04453 struct bu_vls vls;
04454 int c;
04455 int aflag = 0;
04456
04457 if (argc < 2 || MAXARGS < argc) {
04458 bu_vls_init(&vls);
04459 bu_vls_printf(&vls, "helplib_alias wdb_find %s", argv[0]);
04460 Tcl_Eval(interp, bu_vls_addr(&vls));
04461 bu_vls_free(&vls);
04462 return TCL_ERROR;
04463 }
04464
04465 bu_optind = 1;
04466 while ((c = bu_getopt(argc, argv, "a")) != EOF) {
04467 switch (c) {
04468 case 'a':
04469 aflag = 1;
04470 break;
04471 default:
04472 bu_vls_init(&vls);
04473 bu_vls_printf(&vls, "Unrecognized option - %c", c);
04474 Tcl_AppendResult(interp, bu_vls_addr(&vls), (char *)NULL);
04475 bu_vls_free(&vls);
04476 return TCL_ERROR;
04477 }
04478 }
04479 argc -= (bu_optind - 1);
04480 argv += (bu_optind - 1);
04481
04482
04483 for (i = 0; i < RT_DBNHASH; i++) {
04484 for (dp = wdbp->dbip->dbi_Head[i]; dp != DIR_NULL; dp = dp->d_forw) {
04485 if (!(dp->d_flags & DIR_COMB) ||
04486 (!aflag && (dp->d_flags & DIR_HIDDEN)))
04487 continue;
04488
04489 if (rt_db_get_internal(&intern,
04490 dp,
04491 wdbp->dbip,
04492 (fastf_t *)NULL,
04493 &rt_uniresource) < 0) {
04494 Tcl_AppendResult(interp, "Database read error, aborting", (char *)NULL);
04495 return TCL_ERROR;
04496 }
04497
04498 comb = (struct rt_comb_internal *)intern.idb_ptr;
04499 for (k=1; k<argc; k++)
04500 db_tree_funcleaf(wdbp->dbip,
04501 comb,
04502 comb->tree,
04503 wdb_find_ref,
04504 (genptr_t)argv[k],
04505 (genptr_t)dp->d_namep,
04506 (genptr_t)interp);
04507
04508 rt_db_free_internal(&intern, &rt_uniresource);
04509 }
04510 }
04511
04512 return TCL_OK;
04513 }
04514
04515 static int
04516 wdb_facetize_tcl(ClientData clientData, Tcl_Interp *interp, int argc, char **argv)
04517 {
04518 struct rt_wdb *wdbp = (struct rt_wdb *)clientData;
04519
04520 return wdb_facetize_cmd(wdbp, interp, argc-1, argv+1);
04521 }
04522
04523
04524
04525
04526
04527
04528 static int
04529 wdb_find_tcl(ClientData clientData, Tcl_Interp *interp, int argc, char **argv)
04530 {
04531 struct rt_wdb *wdbp = (struct rt_wdb *)clientData;
04532
04533 return wdb_find_cmd(wdbp, interp, argc-1, argv+1);
04534 }
04535
04536 struct wdb_id_names {
04537 struct bu_list l;
04538 struct bu_vls name;
04539 };
04540
04541 struct wdb_id_to_names {
04542 struct bu_list l;
04543 int id;
04544 struct wdb_id_names headName;
04545 };
04546
04547 int
04548 wdb_rmap_cmd(struct rt_wdb *wdbp,
04549 Tcl_Interp *interp,
04550 int argc,
04551 char **argv)
04552 {
04553 register int i;
04554 register struct directory *dp;
04555 struct rt_db_internal intern;
04556 struct rt_comb_internal *comb;
04557 struct wdb_id_to_names headIdName;
04558 struct wdb_id_to_names *itnp;
04559 struct wdb_id_names *inp;
04560 Tcl_DString ds;
04561
04562
04563 if (argc != 1) {
04564 struct bu_vls vls;
04565
04566 bu_vls_init(&vls);
04567 bu_vls_printf(&vls, "helplib_alias wdb_rmap %s", argv[0]);
04568 Tcl_Eval(interp, bu_vls_addr(&vls));
04569 bu_vls_free(&vls);
04570 return TCL_ERROR;
04571 }
04572
04573 Tcl_DStringInit(&ds);
04574
04575 if (wdbp->dbip->dbi_version < 5) {
04576 Tcl_DStringAppend(&ds, argv[0], -1);
04577 Tcl_DStringAppend(&ds, " is not available prior to dbversion 5\n", -1);
04578 Tcl_DStringResult(interp, &ds);
04579 return TCL_ERROR;
04580 }
04581
04582 BU_LIST_INIT(&headIdName.l);
04583
04584
04585 for (i = 0; i < RT_DBNHASH; i++) {
04586 for (dp = wdbp->dbip->dbi_Head[i]; dp != DIR_NULL; dp = dp->d_forw) {
04587 int found = 0;
04588
04589 if (!(dp->d_flags & DIR_REGION) ||
04590 (dp->d_flags & DIR_HIDDEN))
04591 continue;
04592
04593 if (rt_db_get_internal(&intern,
04594 dp,
04595 wdbp->dbip,
04596 (fastf_t *)NULL,
04597 &rt_uniresource) < 0) {
04598 Tcl_DStringAppend(&ds, "Database read error, aborting", -1);
04599 Tcl_DStringResult(interp, &ds);
04600 return TCL_ERROR;
04601 }
04602
04603 comb = (struct rt_comb_internal *)intern.idb_ptr;
04604
04605 for (BU_LIST_FOR(itnp,wdb_id_to_names,&headIdName.l)) {
04606 if ((comb->region_id == itnp->id) ||
04607 (comb->aircode != 0 && -comb->aircode == itnp->id)) {
04608
04609 BU_GETSTRUCT(inp,wdb_id_names);
04610 bu_vls_init(&inp->name);
04611 bu_vls_strcpy(&inp->name, dp->d_namep);
04612 BU_LIST_INSERT(&itnp->headName.l,&inp->l);
04613 found = 1;
04614 break;
04615 }
04616 }
04617
04618 if (!found) {
04619
04620 BU_GETSTRUCT(itnp,wdb_id_to_names);
04621 if (0 < comb->region_id)
04622 itnp->id = comb->region_id;
04623 else
04624 itnp->id = -comb->aircode;
04625 BU_LIST_INSERT(&headIdName.l,&itnp->l);
04626 BU_LIST_INIT(&itnp->headName.l);
04627
04628
04629 BU_GETSTRUCT(inp,wdb_id_names);
04630 bu_vls_init(&inp->name);
04631 bu_vls_strcpy(&inp->name, dp->d_namep);
04632 BU_LIST_INSERT(&itnp->headName.l,&inp->l);
04633 }
04634
04635 #if USE_RT_COMB_IFREE
04636 rt_comb_ifree(&intern, &rt_uniresource);
04637 #else
04638 rt_db_free_internal(&intern, &rt_uniresource);
04639 #endif
04640 }
04641 }
04642
04643
04644 while (BU_LIST_WHILE(itnp,wdb_id_to_names,&headIdName.l)) {
04645 char buf[32];
04646
04647
04648 sprintf(buf, "%d", itnp->id);
04649 Tcl_DStringAppendElement(&ds, buf);
04650
04651
04652 Tcl_DStringStartSublist(&ds);
04653 while (BU_LIST_WHILE(inp,wdb_id_names,&itnp->headName.l)) {
04654
04655 Tcl_DStringAppendElement(&ds, bu_vls_addr(&inp->name));
04656
04657 BU_LIST_DEQUEUE(&inp->l);
04658 bu_vls_free(&inp->name);
04659 bu_free((genptr_t)inp, "rmap: inp");
04660 }
04661 Tcl_DStringEndSublist(&ds);
04662
04663 BU_LIST_DEQUEUE(&itnp->l);
04664 bu_free((genptr_t)itnp, "rmap: itnp");
04665 }
04666
04667 Tcl_DStringResult(interp, &ds);
04668 return TCL_OK;
04669 }
04670
04671
04672
04673
04674
04675 static int
04676 wdb_rmap_tcl(ClientData clientData, Tcl_Interp *interp, int argc, char **argv)
04677 {
04678 struct rt_wdb *wdbp = (struct rt_wdb *)clientData;
04679
04680 return wdb_rmap_cmd(wdbp, interp, argc-1, argv+1);
04681 }
04682
04683 int
04684 wdb_which_cmd(struct rt_wdb *wdbp,
04685 Tcl_Interp *interp,
04686 int argc,
04687 char **argv)
04688 {
04689 register int i,j;
04690 register struct directory *dp;
04691 struct rt_db_internal intern;
04692 struct rt_comb_internal *comb;
04693 struct wdb_id_to_names headIdName;
04694 struct wdb_id_to_names *itnp;
04695 struct wdb_id_names *inp;
04696 int isAir;
04697 int sflag;
04698
04699
04700 if (argc < 2 || MAXARGS < argc) {
04701 struct bu_vls vls;
04702
04703 bu_vls_init(&vls);
04704 bu_vls_printf(&vls, "helplib_alias wdb_%s %s", argv[0], argv[0]);
04705 Tcl_Eval(interp, bu_vls_addr(&vls));
04706 bu_vls_free(&vls);
04707 return TCL_ERROR;
04708 }
04709
04710 if (!strcmp(argv[0], "whichair"))
04711 isAir = 1;
04712 else
04713 isAir = 0;
04714
04715 if (strcmp(argv[1], "-s") == 0) {
04716 --argc;
04717 ++argv;
04718
04719 if (argc < 2) {
04720 struct bu_vls vls;
04721
04722 bu_vls_init(&vls);
04723 bu_vls_printf(&vls, "helplib_alias wdb_%s %s", argv[-1], argv[-1]);
04724 Tcl_Eval(interp, bu_vls_addr(&vls));
04725 bu_vls_free(&vls);
04726 return TCL_ERROR;
04727 }
04728
04729 sflag = 1;
04730 } else {
04731 sflag = 0;
04732 }
04733
04734 BU_LIST_INIT(&headIdName.l);
04735
04736
04737 for (j=1; j<argc; j++) {
04738 int n;
04739 int start, end;
04740 int range;
04741 int k;
04742
04743 n = sscanf(argv[j], "%d%*[:-]%d", &start, &end);
04744 switch (n) {
04745 case 1:
04746 for (BU_LIST_FOR(itnp,wdb_id_to_names,&headIdName.l))
04747 if (itnp->id == start)
04748 break;
04749
04750
04751 if (BU_LIST_IS_HEAD(itnp,&headIdName.l)) {
04752 BU_GETSTRUCT(itnp,wdb_id_to_names);
04753 itnp->id = start;
04754 BU_LIST_INSERT(&headIdName.l,&itnp->l);
04755 BU_LIST_INIT(&itnp->headName.l);
04756 }
04757
04758 break;
04759 case 2:
04760 if (start < end)
04761 range = end - start + 1;
04762 else if (end < start) {
04763 range = start - end + 1;
04764 start = end;
04765 } else
04766 range = 1;
04767
04768 for (k = 0; k < range; ++k) {
04769 int id = start + k;
04770
04771 for (BU_LIST_FOR(itnp,wdb_id_to_names,&headIdName.l))
04772 if (itnp->id == id)
04773 break;
04774
04775
04776 if (BU_LIST_IS_HEAD(itnp,&headIdName.l)) {
04777 BU_GETSTRUCT(itnp,wdb_id_to_names);
04778 itnp->id = id;
04779 BU_LIST_INSERT(&headIdName.l,&itnp->l);
04780 BU_LIST_INIT(&itnp->headName.l);
04781 }
04782 }
04783
04784 break;
04785 }
04786 }
04787
04788
04789 for (i = 0; i < RT_DBNHASH; i++) {
04790 for (dp = wdbp->dbip->dbi_Head[i]; dp != DIR_NULL; dp = dp->d_forw) {
04791 if (!(dp->d_flags & DIR_REGION))
04792 continue;
04793
04794 if (rt_db_get_internal( &intern, dp, wdbp->dbip, (fastf_t *)NULL, &rt_uniresource ) < 0) {
04795 Tcl_AppendResult(interp, "Database read error, aborting", (char *)NULL);
04796 return TCL_ERROR;
04797 }
04798 comb = (struct rt_comb_internal *)intern.idb_ptr;
04799
04800 for (BU_LIST_FOR(itnp,wdb_id_to_names,&headIdName.l)) {
04801 if ((!isAir && comb->region_id == itnp->id) ||
04802 (isAir && comb->aircode == itnp->id)) {
04803
04804 BU_GETSTRUCT(inp,wdb_id_names);
04805 bu_vls_init(&inp->name);
04806 bu_vls_strcpy(&inp->name, dp->d_namep);
04807 BU_LIST_INSERT(&itnp->headName.l,&inp->l);
04808 break;
04809 }
04810 }
04811
04812 #if USE_RT_COMB_IFREE
04813 rt_comb_ifree( &intern, &rt_uniresource );
04814 #else
04815 rt_db_free_internal(&intern, &rt_uniresource);
04816 #endif
04817 }
04818 }
04819
04820
04821 while (BU_LIST_WHILE(itnp,wdb_id_to_names,&headIdName.l)) {
04822 if (!sflag) {
04823 struct bu_vls vls;
04824
04825 bu_vls_init(&vls);
04826 bu_vls_printf(&vls, "Region[s] with %s %d:\n",
04827 isAir ? "air code" : "ident", itnp->id);
04828 Tcl_AppendResult(interp, bu_vls_addr(&vls), (char *)NULL);
04829 bu_vls_free(&vls);
04830 }
04831
04832 while (BU_LIST_WHILE(inp,wdb_id_names,&itnp->headName.l)) {
04833 if (sflag)
04834 Tcl_AppendElement(interp, bu_vls_addr(&inp->name));
04835 else
04836 Tcl_AppendResult(interp, " ", bu_vls_addr(&inp->name),
04837 "\n", (char *)NULL);
04838
04839 BU_LIST_DEQUEUE(&inp->l);
04840 bu_vls_free(&inp->name);
04841 bu_free((genptr_t)inp, "which: inp");
04842 }
04843
04844 BU_LIST_DEQUEUE(&itnp->l);
04845 bu_free((genptr_t)itnp, "which: itnp");
04846 }
04847
04848 return TCL_OK;
04849 }
04850
04851
04852
04853
04854
04855 static int
04856 wdb_which_tcl(ClientData clientData, Tcl_Interp *interp, int argc, char **argv)
04857 {
04858 struct rt_wdb *wdbp = (struct rt_wdb *)clientData;
04859
04860 return wdb_which_cmd(wdbp, interp, argc-1, argv+1);
04861 }
04862
04863 int
04864 wdb_title_cmd(struct rt_wdb *wdbp,
04865 Tcl_Interp *interp,
04866 int argc,
04867 char **argv)
04868 {
04869 struct bu_vls title;
04870 int bad = 0;
04871
04872 RT_CK_WDB(wdbp);
04873 RT_CK_DBI(wdbp->dbip);
04874
04875 if (argc < 1 || MAXARGS < argc) {
04876 struct bu_vls vls;
04877
04878 bu_vls_init(&vls);
04879 bu_vls_printf(&vls, "helplib_alias wdb_title %s", argv[0]);
04880 Tcl_Eval(interp, bu_vls_addr(&vls));
04881 bu_vls_free(&vls);
04882 return TCL_ERROR;
04883 }
04884
04885
04886 if (argc == 1) {
04887 Tcl_AppendResult(interp, wdbp->dbip->dbi_title, (char *)NULL);
04888 return TCL_OK;
04889 }
04890
04891 WDB_TCL_CHECK_READ_ONLY;
04892
04893
04894 bu_vls_init(&title);
04895 bu_vls_from_argv(&title, argc-1, (const char **)argv+1);
04896
04897 if (db_update_ident(wdbp->dbip, bu_vls_addr(&title), wdbp->dbip->dbi_base2local) < 0) {
04898 Tcl_AppendResult(interp, "Error: unable to change database title");
04899 bad = 1;
04900 }
04901
04902 bu_vls_free(&title);
04903 return bad ? TCL_ERROR : TCL_OK;
04904 }
04905
04906
04907
04908
04909
04910
04911
04912 static int
04913 wdb_title_tcl(ClientData clientData,
04914 Tcl_Interp *interp,
04915 int argc,
04916 char **argv)
04917 {
04918 struct rt_wdb *wdbp = (struct rt_wdb *)clientData;
04919
04920 return wdb_title_cmd(wdbp, interp, argc-1, argv+1);
04921 }
04922
04923 static int
04924 wdb_list_children(struct rt_wdb *wdbp,
04925 Tcl_Interp *interp,
04926 register struct directory *dp)
04927 {
04928 register int i;
04929 struct rt_db_internal intern;
04930 struct rt_comb_internal *comb;
04931
04932 if (!(dp->d_flags & DIR_COMB))
04933 return TCL_OK;
04934
04935 if (rt_db_get_internal(&intern, dp, wdbp->dbip, (fastf_t *)NULL, &rt_uniresource) < 0) {
04936 Tcl_AppendResult(interp, "Database read error, aborting", (char *)NULL);
04937 return TCL_ERROR;
04938 }
04939 comb = (struct rt_comb_internal *)intern.idb_ptr;
04940
04941 if (comb->tree) {
04942 struct bu_vls vls;
04943 int node_count;
04944 int actual_count;
04945 struct rt_tree_array *rt_tree_array;
04946
04947 if (comb->tree && db_ck_v4gift_tree(comb->tree) < 0) {
04948 db_non_union_push(comb->tree, &rt_uniresource);
04949 if (db_ck_v4gift_tree(comb->tree) < 0) {
04950 Tcl_AppendResult(interp, "Cannot flatten tree for listing", (char *)NULL);
04951 return TCL_ERROR;
04952 }
04953 }
04954 node_count = db_tree_nleaves(comb->tree);
04955 if (node_count > 0) {
04956 rt_tree_array = (struct rt_tree_array *)bu_calloc( node_count,
04957 sizeof( struct rt_tree_array ), "tree list" );
04958 actual_count = (struct rt_tree_array *)db_flatten_tree(
04959 rt_tree_array, comb->tree, OP_UNION,
04960 1, &rt_uniresource ) - rt_tree_array;
04961 BU_ASSERT_PTR( actual_count, ==, node_count );
04962 comb->tree = TREE_NULL;
04963 } else {
04964 actual_count = 0;
04965 rt_tree_array = NULL;
04966 }
04967
04968 bu_vls_init(&vls);
04969 for (i=0 ; i<actual_count ; i++) {
04970 char op;
04971
04972 switch (rt_tree_array[i].tl_op) {
04973 case OP_UNION:
04974 op = 'u';
04975 break;
04976 case OP_INTERSECT:
04977 op = '+';
04978 break;
04979 case OP_SUBTRACT:
04980 op = '-';
04981 break;
04982 default:
04983 op = '?';
04984 break;
04985 }
04986
04987 bu_vls_printf(&vls, "{%c %s} ", op, rt_tree_array[i].tl_tree->tr_l.tl_name);
04988 db_free_tree( rt_tree_array[i].tl_tree, &rt_uniresource );
04989 }
04990 Tcl_AppendResult(interp, bu_vls_addr(&vls), (char *)0);
04991 bu_vls_free(&vls);
04992
04993 if (rt_tree_array)
04994 bu_free((char *)rt_tree_array, "printnode: rt_tree_array");
04995 }
04996 rt_db_free_internal(&intern, &rt_uniresource);
04997
04998 return TCL_OK;
04999 }
05000
05001 int
05002 wdb_lt_cmd(struct rt_wdb *wdbp,
05003 Tcl_Interp *interp,
05004 int argc,
05005 char **argv)
05006 {
05007 register struct directory *dp;
05008 struct bu_vls vls;
05009
05010 if (argc != 2)
05011 goto bad;
05012
05013 if ((dp = db_lookup(wdbp->dbip, argv[1], LOOKUP_NOISY)) == DIR_NULL)
05014 goto bad;
05015
05016 return wdb_list_children(wdbp, interp, dp);
05017
05018 bad:
05019 bu_vls_init(&vls);
05020 bu_vls_printf(&vls, "helplib_alias wdb_lt %s", argv[0]);
05021 Tcl_Eval(interp, bu_vls_addr(&vls));
05022 bu_vls_free(&vls);
05023 return TCL_ERROR;
05024 }
05025
05026
05027
05028
05029
05030 static int
05031 wdb_lt_tcl(ClientData clientData,
05032 Tcl_Interp *interp,
05033 int argc,
05034 char **argv)
05035 {
05036 struct rt_wdb *wdbp = (struct rt_wdb *)clientData;
05037
05038 return wdb_lt_cmd(wdbp, interp, argc-1, argv+1);
05039 }
05040
05041 int
05042 wdb_version_cmd(struct rt_wdb *wdbp,
05043 Tcl_Interp *interp,
05044 int argc,
05045 char **argv)
05046 {
05047 struct bu_vls vls;
05048
05049 bu_vls_init(&vls);
05050
05051 if (argc != 1) {
05052 bu_vls_printf(&vls, "helplib_alias wdb_version %s", argv[0]);
05053 Tcl_Eval(interp, bu_vls_addr(&vls));
05054 bu_vls_free(&vls);
05055 return TCL_ERROR;
05056 }
05057
05058 bu_vls_printf(&vls, "%d", wdbp->dbip->dbi_version);
05059 Tcl_AppendResult(interp, bu_vls_addr(&vls), (char *)0);
05060 bu_vls_free(&vls);
05061
05062 return TCL_OK;
05063 }
05064
05065
05066
05067
05068
05069 static int
05070 wdb_version_tcl(ClientData clientData,
05071 Tcl_Interp *interp,
05072 int argc,
05073 char **argv)
05074 {
05075 struct rt_wdb *wdbp = (struct rt_wdb *)clientData;
05076
05077 return wdb_version_cmd(wdbp, interp, argc-1, argv+1);
05078 }
05079
05080
05081
05082
05083
05084
05085 static void
05086 wdb_print_node(struct rt_wdb *wdbp,
05087 Tcl_Interp *interp,
05088 register struct directory *dp,
05089 int pathpos,
05090 int indentSize,
05091 char prefix,
05092 int cflag)
05093 {
05094 register int i;
05095 register struct directory *nextdp;
05096 struct rt_db_internal intern;
05097 struct rt_comb_internal *comb;
05098
05099 if (cflag && !(dp->d_flags & DIR_COMB))
05100 return;
05101
05102 for (i=0; i<pathpos; i++)
05103 if( indentSize < 0 ) {
05104 Tcl_AppendResult(interp, "\t", (char *)NULL);
05105 } else {
05106 int j;
05107 for( j=0 ; j<indentSize ; j++ ) {
05108 Tcl_AppendResult(interp, " ", (char *)NULL);
05109 }
05110 }
05111
05112 if (prefix) {
05113 struct bu_vls tmp_vls;
05114
05115 bu_vls_init(&tmp_vls);
05116 bu_vls_printf(&tmp_vls, "%c ", prefix);
05117 Tcl_AppendResult(interp, bu_vls_addr(&tmp_vls), (char *)NULL);
05118 bu_vls_free(&tmp_vls);
05119 }
05120
05121 Tcl_AppendResult(interp, dp->d_namep, (char *)NULL);
05122
05123 if(dp->d_flags & DIR_COMB)
05124 Tcl_AppendResult(interp, "/", (char *)NULL);
05125 if(dp->d_flags & DIR_REGION)
05126 Tcl_AppendResult(interp, "R", (char *)NULL);
05127
05128 Tcl_AppendResult(interp, "\n", (char *)NULL);
05129
05130 if(!(dp->d_flags & DIR_COMB))
05131 return;
05132
05133
05134
05135
05136
05137
05138 if (rt_db_get_internal(&intern, dp, wdbp->dbip, (fastf_t *)NULL, &rt_uniresource) < 0) {
05139 Tcl_AppendResult(interp, "Database read error, aborting", (char *)NULL);
05140 return;
05141 }
05142 comb = (struct rt_comb_internal *)intern.idb_ptr;
05143
05144 if (comb->tree) {
05145 int node_count;
05146 int actual_count;
05147 struct rt_tree_array *rt_tree_array;
05148
05149 if (comb->tree && db_ck_v4gift_tree(comb->tree) < 0) {
05150 db_non_union_push(comb->tree, &rt_uniresource);
05151 if (db_ck_v4gift_tree(comb->tree) < 0) {
05152 Tcl_AppendResult(interp, "Cannot flatten tree for listing", (char *)NULL);
05153 return;
05154 }
05155 }
05156 node_count = db_tree_nleaves(comb->tree);
05157 if (node_count > 0) {
05158 rt_tree_array = (struct rt_tree_array *)bu_calloc( node_count,
05159 sizeof( struct rt_tree_array ), "tree list" );
05160 actual_count = (struct rt_tree_array *)db_flatten_tree(
05161 rt_tree_array, comb->tree, OP_UNION,
05162 1, &rt_uniresource ) - rt_tree_array;
05163 BU_ASSERT_PTR( actual_count, ==, node_count );
05164 comb->tree = TREE_NULL;
05165 } else {
05166 actual_count = 0;
05167 rt_tree_array = NULL;
05168 }
05169
05170 for (i=0 ; i<actual_count ; i++) {
05171 char op;
05172
05173 switch (rt_tree_array[i].tl_op) {
05174 case OP_UNION:
05175 op = 'u';
05176 break;
05177 case OP_INTERSECT:
05178 op = '+';
05179 break;
05180 case OP_SUBTRACT:
05181 op = '-';
05182 break;
05183 default:
05184 op = '?';
05185 break;
05186 }
05187
05188 if ((nextdp = db_lookup(wdbp->dbip, rt_tree_array[i].tl_tree->tr_l.tl_name, LOOKUP_NOISY)) == DIR_NULL) {
05189 int j;
05190 struct bu_vls tmp_vls;
05191
05192 for (j=0; j<pathpos+1; j++)
05193 Tcl_AppendResult(interp, "\t", (char *)NULL);
05194
05195 bu_vls_init(&tmp_vls);
05196 bu_vls_printf(&tmp_vls, "%c ", op);
05197 Tcl_AppendResult(interp, bu_vls_addr(&tmp_vls), (char *)NULL);
05198 bu_vls_free(&tmp_vls);
05199
05200 Tcl_AppendResult(interp, rt_tree_array[i].tl_tree->tr_l.tl_name, "\n", (char *)NULL);
05201 } else
05202 wdb_print_node(wdbp, interp, nextdp, pathpos+1, indentSize, op, cflag);
05203 db_free_tree( rt_tree_array[i].tl_tree, &rt_uniresource );
05204 }
05205 if(rt_tree_array) bu_free((char *)rt_tree_array, "printnode: rt_tree_array");
05206 }
05207 rt_db_free_internal(&intern, &rt_uniresource);
05208 }
05209
05210
05211
05212
05213
05214 static int
05215 wdb_track_tcl(ClientData clientData,
05216 Tcl_Interp *interp,
05217 int argc,
05218 char **argv) {
05219 struct rt_wdb *wdbp = (struct rt_wdb *)clientData;
05220
05221 return wdb_track_cmd(wdbp, interp, argc-1, argv+1);
05222 }
05223
05224 int
05225 wdb_tree_cmd(struct rt_wdb *wdbp,
05226 Tcl_Interp *interp,
05227 int argc,
05228 char **argv)
05229 {
05230 register struct directory *dp;
05231 register int j;
05232 int cflag = 0;
05233 int indentSize = -1;
05234 int c;
05235 struct bu_vls vls;
05236 FILE *fdout = NULL;
05237
05238 if (argc < 2 || MAXARGS < argc) {
05239
05240 bu_vls_init(&vls);
05241 bu_vls_printf(&vls, "helplib_alias wdb_tree %s", argv[0]);
05242 Tcl_Eval(interp, bu_vls_addr(&vls));
05243 bu_vls_free(&vls);
05244 return TCL_ERROR;
05245 }
05246
05247
05248 bu_optind = 1;
05249 while ((c=bu_getopt(argc, argv, "i:o:c")) != EOF) {
05250 switch (c) {
05251 case 'i':
05252 indentSize = atoi(bu_optarg);
05253 break;
05254 case 'c':
05255 cflag = 1;
05256 break;
05257 case 'o':
05258 if( (fdout = fopen( bu_optarg, "w+" )) == NULL ) {
05259 Tcl_SetErrno( errno );
05260 Tcl_AppendResult( interp, "Failed to open output file, ",
05261 strerror( errno ), (char *)NULL );
05262 return TCL_ERROR;
05263 }
05264 break;
05265 case '?':
05266 default:
05267 bu_vls_init(&vls);
05268 bu_vls_printf(&vls, "helplib_alias wdb_tree %s", argv[0]);
05269 Tcl_Eval(interp, bu_vls_addr(&vls));
05270 bu_vls_free(&vls);
05271 return TCL_ERROR;
05272 break;
05273 }
05274 }
05275
05276 argc -= (bu_optind - 1);
05277 argv += (bu_optind - 1);
05278
05279 for (j = 1; j < argc; j++) {
05280 if (j > 1)
05281 Tcl_AppendResult(interp, "\n", (char *)NULL);
05282 if ((dp = db_lookup(wdbp->dbip, argv[j], LOOKUP_NOISY)) == DIR_NULL)
05283 continue;
05284 wdb_print_node(wdbp, interp, dp, 0, indentSize, 0, cflag);
05285 }
05286
05287 if( fdout != NULL ) {
05288 fprintf( fdout, "%s", Tcl_GetStringResult( interp ) );
05289 Tcl_ResetResult( interp );
05290 fclose( fdout );
05291 }
05292
05293 return TCL_OK;
05294 }
05295
05296
05297
05298
05299
05300 static int
05301 wdb_tree_tcl(ClientData clientData, Tcl_Interp *interp, int argc, char **argv)
05302 {
05303 struct rt_wdb *wdbp = (struct rt_wdb *)clientData;
05304
05305 return wdb_tree_cmd(wdbp, interp, argc-1, argv+1);
05306 }
05307
05308
05309
05310
05311
05312
05313
05314 static void
05315 wdb_color_putrec(register struct mater *mp,
05316 Tcl_Interp *interp,
05317 struct db_i *dbip)
05318 {
05319 struct directory dir;
05320 union record rec;
05321
05322
05323
05324 rec.md.md_id = ID_MATERIAL;
05325 rec.md.md_low = mp->mt_low;
05326 rec.md.md_hi = mp->mt_high;
05327 rec.md.md_r = mp->mt_r;
05328 rec.md.md_g = mp->mt_g;
05329 rec.md.md_b = mp->mt_b;
05330
05331
05332 RT_DIR_SET_NAMEP( &dir, "color_putrec" );
05333 dir.d_magic = RT_DIR_MAGIC;
05334 dir.d_flags = 0;
05335
05336 if (mp->mt_daddr == MATER_NO_ADDR) {
05337
05338 if (db_alloc(dbip, &dir, 1) < 0) {
05339 Tcl_AppendResult(interp,
05340 "Database alloc error, aborting",
05341 (char *)NULL);
05342 return;
05343 }
05344 mp->mt_daddr = dir.d_addr;
05345 } else {
05346 dir.d_addr = mp->mt_daddr;
05347 dir.d_len = 1;
05348 }
05349
05350 if (db_put(dbip, &dir, &rec, 0, 1) < 0) {
05351 Tcl_AppendResult(interp,
05352 "Database write error, aborting",
05353 (char *)NULL);
05354 return;
05355 }
05356 }
05357
05358
05359
05360
05361
05362
05363 static void
05364 wdb_color_zaprec(register struct mater *mp,
05365 Tcl_Interp *interp,
05366 struct db_i *dbip)
05367 {
05368 struct directory dir;
05369
05370
05371 if (mp->mt_daddr == MATER_NO_ADDR)
05372 return;
05373
05374 dir.d_magic = RT_DIR_MAGIC;
05375 RT_DIR_SET_NAMEP( &dir, "color_zaprec" );
05376 dir.d_len = 1;
05377 dir.d_addr = mp->mt_daddr;
05378 dir.d_flags = 0;
05379
05380 if (db_delete(dbip, &dir) < 0) {
05381 Tcl_AppendResult(interp,
05382 "Database delete error, aborting",
05383 (char *)NULL);
05384 return;
05385 }
05386 mp->mt_daddr = MATER_NO_ADDR;
05387 }
05388
05389 int
05390 wdb_color_cmd(struct rt_wdb *wdbp,
05391 Tcl_Interp *interp,
05392 int argc,
05393 char **argv)
05394 {
05395 register struct mater *newp,*next_mater;
05396
05397 WDB_TCL_CHECK_READ_ONLY;
05398
05399 if (argc != 6) {
05400 struct bu_vls vls;
05401
05402 bu_vls_init(&vls);
05403 bu_vls_printf(&vls, "helplib_alias wdb_color %s", argv[0]);
05404 Tcl_Eval(interp, bu_vls_addr(&vls));
05405 bu_vls_free(&vls);
05406 return TCL_ERROR;
05407 }
05408
05409 if (wdbp->dbip->dbi_version < 5) {
05410
05411 newp = rt_material_head;
05412 while (newp != MATER_NULL) {
05413 next_mater = newp->mt_forw;
05414 wdb_color_zaprec(newp, interp, wdbp->dbip);
05415 newp = next_mater;
05416 }
05417
05418
05419 BU_GETSTRUCT(newp, mater);
05420 newp->mt_low = atoi(argv[1]);
05421 newp->mt_high = atoi(argv[2]);
05422 newp->mt_r = atoi(argv[3]);
05423 newp->mt_g = atoi(argv[4]);
05424 newp->mt_b = atoi(argv[5]);
05425 newp->mt_daddr = MATER_NO_ADDR;
05426
05427
05428 rt_insert_color(newp);
05429
05430
05431 newp = rt_material_head;
05432 while (newp != MATER_NULL) {
05433 next_mater = newp->mt_forw;
05434 wdb_color_putrec(newp, interp, wdbp->dbip);
05435 newp = next_mater;
05436 }
05437 } else {
05438 struct bu_vls colors;
05439
05440
05441 BU_GETSTRUCT(newp, mater);
05442 newp->mt_low = atoi(argv[1]);
05443 newp->mt_high = atoi(argv[2]);
05444 newp->mt_r = atoi(argv[3]);
05445 newp->mt_g = atoi(argv[4]);
05446 newp->mt_b = atoi(argv[5]);
05447 newp->mt_daddr = MATER_NO_ADDR;
05448
05449
05450 rt_insert_color(newp);
05451
05452
05453
05454
05455
05456 newp = rt_material_head;
05457 bu_vls_init(&colors);
05458 while (newp != MATER_NULL) {
05459 next_mater = newp->mt_forw;
05460 bu_vls_printf(&colors, "{%d %d %d %d %d} ", newp->mt_low, newp->mt_high,
05461 newp->mt_r, newp->mt_g, newp->mt_b);
05462 newp = next_mater;
05463 }
05464
05465 db5_update_attribute("_GLOBAL", "regionid_colortable", bu_vls_addr(&colors), wdbp->dbip);
05466 bu_vls_free(&colors);
05467 }
05468
05469 return TCL_OK;
05470 }
05471
05472
05473
05474
05475
05476 static int
05477 wdb_color_tcl(ClientData clientData,
05478 Tcl_Interp *interp,
05479 int argc,
05480 char **argv)
05481 {
05482 struct rt_wdb *wdbp = (struct rt_wdb *)clientData;
05483
05484 return wdb_color_cmd(wdbp, interp, argc-1, argv+1);
05485 }
05486
05487 static void
05488 wdb_pr_mater(register struct mater *mp,
05489 Tcl_Interp *interp,
05490 int *ccp,
05491 int *clp)
05492 {
05493 char buf[128];
05494 struct bu_vls vls;
05495
05496 bu_vls_init(&vls);
05497
05498 (void)sprintf(buf, "%5d..%d", mp->mt_low, mp->mt_high );
05499 wdb_vls_col_item(&vls, buf, ccp, clp);
05500 (void)sprintf( buf, "%3d,%3d,%3d", mp->mt_r, mp->mt_g, mp->mt_b);
05501 wdb_vls_col_item(&vls, buf, ccp, clp);
05502 wdb_vls_col_eol(&vls, ccp, clp);
05503
05504 Tcl_AppendResult(interp, bu_vls_addr(&vls), (char *)NULL);
05505 bu_vls_free(&vls);
05506 }
05507
05508 int
05509 wdb_prcolor_cmd(struct rt_wdb *wdbp,
05510 Tcl_Interp *interp,
05511 int argc,
05512 char **argv)
05513 {
05514 register struct mater *mp;
05515 int col_count = 0;
05516 int col_len = 0;
05517
05518 if (argc != 1) {
05519 struct bu_vls vls;
05520
05521 bu_vls_init(&vls);
05522 bu_vls_printf(&vls, "helplib_alias wdb_prcolor %s", argv[0]);
05523 Tcl_Eval(interp, bu_vls_addr(&vls));
05524 bu_vls_free(&vls);
05525 return TCL_ERROR;
05526 }
05527
05528 if (rt_material_head == MATER_NULL) {
05529 Tcl_AppendResult(interp, "none", (char *)NULL);
05530 return TCL_OK;
05531 }
05532
05533 for (mp = rt_material_head; mp != MATER_NULL; mp = mp->mt_forw)
05534 wdb_pr_mater(mp, interp, &col_count, &col_len);
05535
05536 return TCL_OK;
05537 }
05538
05539
05540
05541
05542
05543 static int
05544 wdb_prcolor_tcl(ClientData clientData, Tcl_Interp *interp, int argc, char **argv)
05545 {
05546 struct rt_wdb *wdbp = (struct rt_wdb *)clientData;
05547
05548 return wdb_prcolor_cmd(wdbp, interp, argc-1, argv+1);
05549 }
05550
05551 int
05552 wdb_tol_cmd(struct rt_wdb *wdbp,
05553 Tcl_Interp *interp,
05554 int argc,
05555 char **argv)
05556 {
05557 struct bu_vls vls;
05558 double f;
05559
05560 if (argc < 1 || 3 < argc){
05561 bu_vls_init(&vls);
05562 bu_vls_printf(&vls, "helplib_alias wdb_tol %s", argv[0]);
05563 Tcl_Eval(interp, bu_vls_addr(&vls));
05564 bu_vls_free(&vls);
05565 return TCL_ERROR;
05566 }
05567
05568
05569 if (argc == 1) {
05570 Tcl_AppendResult(interp, "Current tolerance settings are:\n", (char *)NULL);
05571 Tcl_AppendResult(interp, "Tesselation tolerances:\n", (char *)NULL );
05572
05573 if (wdbp->wdb_ttol.abs > 0.0) {
05574 bu_vls_init(&vls);
05575 bu_vls_printf(&vls, "\tabs %g mm\n", wdbp->wdb_ttol.abs);
05576 Tcl_AppendResult(interp, bu_vls_addr(&vls), (char *)NULL);
05577 bu_vls_free(&vls);
05578 } else {
05579 Tcl_AppendResult(interp, "\tabs None\n", (char *)NULL);
05580 }
05581
05582 if (wdbp->wdb_ttol.rel > 0.0) {
05583 bu_vls_init(&vls);
05584 bu_vls_printf(&vls, "\trel %g (%g%%)\n",
05585 wdbp->wdb_ttol.rel, wdbp->wdb_ttol.rel * 100.0 );
05586 Tcl_AppendResult(interp, bu_vls_addr(&vls), (char *)NULL);
05587 bu_vls_free(&vls);
05588 } else {
05589 Tcl_AppendResult(interp, "\trel None\n", (char *)NULL);
05590 }
05591
05592 if (wdbp->wdb_ttol.norm > 0.0) {
05593 int deg, min;
05594 double sec;
05595
05596 bu_vls_init(&vls);
05597 sec = wdbp->wdb_ttol.norm * bn_radtodeg;
05598 deg = (int)(sec);
05599 sec = (sec - (double)deg) * 60;
05600 min = (int)(sec);
05601 sec = (sec - (double)min) * 60;
05602
05603 bu_vls_printf(&vls, "\tnorm %g degrees (%d deg %d min %g sec)\n",
05604 wdbp->wdb_ttol.norm * bn_radtodeg, deg, min, sec);
05605 Tcl_AppendResult(interp, bu_vls_addr(&vls), (char *)NULL);
05606 bu_vls_free(&vls);
05607 } else {
05608 Tcl_AppendResult(interp, "\tnorm None\n", (char *)NULL);
05609 }
05610
05611 bu_vls_init(&vls);
05612 bu_vls_printf(&vls,"Calculational tolerances:\n");
05613 bu_vls_printf(&vls,
05614 "\tdistance = %g mm\n\tperpendicularity = %g (cosine of %g degrees)",
05615 wdbp->wdb_tol.dist, wdbp->wdb_tol.perp,
05616 acos(wdbp->wdb_tol.perp)*bn_radtodeg);
05617 Tcl_AppendResult(interp, bu_vls_addr(&vls), (char *)NULL);
05618 bu_vls_free(&vls);
05619
05620 return TCL_OK;
05621 }
05622
05623
05624 if (argc == 2) {
05625 int status = TCL_OK;
05626
05627 bu_vls_init(&vls);
05628
05629 switch (argv[1][0]) {
05630 case 'a':
05631 if (wdbp->wdb_ttol.abs > 0.0)
05632 bu_vls_printf(&vls, "%g", wdbp->wdb_ttol.abs);
05633 else
05634 bu_vls_printf(&vls, "None");
05635 break;
05636 case 'r':
05637 if (wdbp->wdb_ttol.rel > 0.0)
05638 bu_vls_printf(&vls, "%g", wdbp->wdb_ttol.rel);
05639 else
05640 bu_vls_printf(&vls, "None");
05641 break;
05642 case 'n':
05643 if (wdbp->wdb_ttol.norm > 0.0)
05644 bu_vls_printf(&vls, "%g", wdbp->wdb_ttol.norm);
05645 else
05646 bu_vls_printf(&vls, "None");
05647 break;
05648 case 'd':
05649 bu_vls_printf(&vls, "%g", wdbp->wdb_tol.dist);
05650 break;
05651 case 'p':
05652 bu_vls_printf(&vls, "%g", wdbp->wdb_tol.perp);
05653 break;
05654 default:
05655 bu_vls_printf(&vls, "unrecognized tolerance type - %s", argv[1]);
05656 status = TCL_ERROR;
05657 break;
05658 }
05659
05660 Tcl_AppendResult(interp, bu_vls_addr(&vls), (char *)NULL);
05661 bu_vls_free(&vls);
05662 return status;
05663 }
05664
05665
05666 if (sscanf(argv[2], "%lf", &f) != 1) {
05667 bu_vls_init(&vls);
05668 bu_vls_printf(&vls, "bad tolerance - %s", argv[2]);
05669 Tcl_AppendResult(interp, bu_vls_addr(&vls), (char *)NULL);
05670 bu_vls_free(&vls);
05671
05672 return TCL_ERROR;
05673 }
05674
05675
05676 if (f < 0.0) {
05677 Tcl_AppendResult(interp, "negative tolerance clamped to 0.0\n", (char *)NULL);
05678 f = 0.0;
05679 }
05680
05681 switch (argv[1][0]) {
05682 case 'a':
05683
05684 if (f < wdbp->wdb_tol.dist) {
05685 bu_vls_init(&vls);
05686 bu_vls_printf(&vls, "absolute tolerance cannot be less than distance tolerance, clamped to %f\n", wdbp->wdb_tol.dist);
05687 Tcl_AppendResult(interp, bu_vls_addr(&vls), (char *)NULL);
05688 }
05689 wdbp->wdb_ttol.abs = f;
05690 break;
05691 case 'r':
05692 if (f >= 1.0) {
05693 Tcl_AppendResult(interp,
05694 "relative tolerance must be between 0 and 1, not changed\n",
05695 (char *)NULL);
05696 return TCL_ERROR;
05697 }
05698
05699 wdbp->wdb_ttol.rel = f;
05700 break;
05701 case 'n':
05702
05703 if (f > 90.0) {
05704 Tcl_AppendResult(interp,
05705 "Normal tolerance must be less than 90.0 degrees\n",
05706 (char *)NULL);
05707 return TCL_ERROR;
05708 }
05709
05710 wdbp->wdb_ttol.norm = f * bn_degtorad;
05711 break;
05712 case 'd':
05713
05714 wdbp->wdb_tol.dist = f;
05715 wdbp->wdb_tol.dist_sq = wdbp->wdb_tol.dist * wdbp->wdb_tol.dist;
05716 break;
05717 case 'p':
05718
05719 if (f > 1.0) {
05720 Tcl_AppendResult(interp,
05721 "Calculational perpendicular tolerance must be from 0 to 1\n",
05722 (char *)NULL);
05723 return TCL_ERROR;
05724 }
05725 wdbp->wdb_tol.perp = f;
05726 wdbp->wdb_tol.para = 1.0 - f;
05727 break;
05728 default:
05729 bu_vls_init(&vls);
05730 bu_vls_printf(&vls, "unrecognized tolerance type - %s", argv[1]);
05731 Tcl_AppendResult(interp, bu_vls_addr(&vls), (char *)NULL);
05732 bu_vls_free(&vls);
05733
05734 return TCL_ERROR;
05735 }
05736
05737 return TCL_OK;
05738 }
05739
05740
05741
05742
05743
05744
05745
05746
05747
05748
05749
05750
05751 static int
05752 wdb_tol_tcl(ClientData clientData,
05753 Tcl_Interp *interp,
05754 int argc,
05755 char **argv)
05756 {
05757 struct rt_wdb *wdbp = (struct rt_wdb *)clientData;
05758
05759 return wdb_tol_cmd(wdbp, interp, argc-1, argv+1);
05760 }
05761
05762
05763 struct wdb_push_id {
05764 long magic;
05765 struct wdb_push_id *forw, *back;
05766 struct directory *pi_dir;
05767 mat_t pi_mat;
05768 };
05769
05770 #define WDB_MAGIC_PUSH_ID 0x50495323
05771 #define FOR_ALL_WDB_PUSH_SOLIDS(_p,_phead) \
05772 for(_p=_phead.forw; _p!=&_phead; _p=_p->forw)
05773 struct wdb_push_data {
05774 Tcl_Interp *interp;
05775 struct wdb_push_id pi_head;
05776 int push_error;
05777 };
05778
05779
05780
05781
05782
05783
05784
05785
05786
05787
05788
05789 static union tree *
05790 wdb_push_leaf(struct db_tree_state *tsp,
05791 struct db_full_path *pathp,
05792 struct rt_db_internal *ip,
05793 genptr_t client_data)
05794 {
05795 union tree *curtree;
05796 struct directory *dp;
05797 register struct wdb_push_id *pip;
05798 struct wdb_push_data *wpdp = (struct wdb_push_data *)client_data;
05799
05800 RT_CK_TESS_TOL(tsp->ts_ttol);
05801 BN_CK_TOL(tsp->ts_tol);
05802 RT_CK_RESOURCE(tsp->ts_resp);
05803
05804 dp = pathp->fp_names[pathp->fp_len-1];
05805
05806 if (RT_G_DEBUG&DEBUG_TREEWALK) {
05807 char *sofar = db_path_to_string(pathp);
05808
05809 Tcl_AppendResult(wpdp->interp, "wdb_push_leaf(",
05810 ip->idb_meth->ft_name,
05811 ") path='", sofar, "'\n", (char *)NULL);
05812 bu_free((genptr_t)sofar, "path string");
05813 }
05814
05815
05816
05817
05818
05819
05820
05821
05822
05823
05824 bu_semaphore_acquire(RT_SEM_WORKER);
05825 FOR_ALL_WDB_PUSH_SOLIDS(pip,wpdp->pi_head) {
05826 if (pip->pi_dir == dp ) {
05827 if (!bn_mat_is_equal(pip->pi_mat,
05828 tsp->ts_mat, tsp->ts_tol)) {
05829 char *sofar = db_path_to_string(pathp);
05830
05831 Tcl_AppendResult(wpdp->interp, "wdb_push_leaf: matrix mismatch between '", sofar,
05832 "' and prior reference.\n", (char *)NULL);
05833 bu_free((genptr_t)sofar, "path string");
05834 wpdp->push_error = 1;
05835 }
05836
05837 bu_semaphore_release(RT_SEM_WORKER);
05838 RT_GET_TREE(curtree, tsp->ts_resp);
05839 curtree->magic = RT_TREE_MAGIC;
05840 curtree->tr_op = OP_NOP;
05841 return curtree;
05842 }
05843 }
05844
05845
05846
05847 pip = (struct wdb_push_id *) bu_malloc(sizeof(struct wdb_push_id), "Push ident");
05848 pip->magic = WDB_MAGIC_PUSH_ID;
05849 pip->pi_dir = dp;
05850 MAT_COPY(pip->pi_mat, tsp->ts_mat);
05851 pip->back = wpdp->pi_head.back;
05852 wpdp->pi_head.back = pip;
05853 pip->forw = &wpdp->pi_head;
05854 pip->back->forw = pip;
05855 bu_semaphore_release(RT_SEM_WORKER);
05856 RT_GET_TREE( curtree, tsp->ts_resp );
05857 curtree->magic = RT_TREE_MAGIC;
05858 curtree->tr_op = OP_NOP;
05859 return curtree;
05860 }
05861
05862
05863
05864 static union tree *
05865 wdb_push_region_end(register struct db_tree_state *tsp,
05866 struct db_full_path *pathp,
05867 union tree *curtree,
05868 genptr_t client_data)
05869 {
05870 return curtree;
05871 }
05872
05873 int
05874 wdb_push_cmd(struct rt_wdb *wdbp,
05875 Tcl_Interp *interp,
05876 int argc,
05877 char **argv)
05878 {
05879 struct wdb_push_data *wpdp;
05880 struct wdb_push_id *pip;
05881 struct rt_db_internal es_int;
05882 int i;
05883 int ncpu;
05884 int c;
05885 int old_debug;
05886 int push_error;
05887 extern int bu_optind;
05888 extern char *bu_optarg;
05889
05890 WDB_TCL_CHECK_READ_ONLY;
05891
05892 if (argc < 2 || MAXARGS < argc) {
05893 struct bu_vls vls;
05894
05895 bu_vls_init(&vls);
05896 bu_vls_printf(&vls, "helplib_alias wdb_push %s", argv[0]);
05897 Tcl_Eval(interp, bu_vls_addr(&vls));
05898 bu_vls_free(&vls);
05899 return TCL_ERROR;
05900 }
05901
05902 RT_CHECK_DBI(wdbp->dbip);
05903
05904 BU_GETSTRUCT(wpdp,wdb_push_data);
05905 wpdp->interp = interp;
05906 wpdp->push_error = 0;
05907 wpdp->pi_head.magic = WDB_MAGIC_PUSH_ID;
05908 wpdp->pi_head.forw = wpdp->pi_head.back = &wpdp->pi_head;
05909 wpdp->pi_head.pi_dir = (struct directory *) 0;
05910
05911 old_debug = RT_G_DEBUG;
05912
05913
05914 ncpu = 1;
05915
05916
05917 bu_optind = 1;
05918 while ((c=bu_getopt(argc, argv, "P:d")) != EOF) {
05919 switch (c) {
05920 case 'P':
05921 ncpu = atoi(bu_optarg);
05922 if (ncpu<1) ncpu = 1;
05923 break;
05924 case 'd':
05925 rt_g.debug |= DEBUG_TREEWALK;
05926 break;
05927 case '?':
05928 default:
05929 Tcl_AppendResult(interp, "push: usage push [-P processors] [-d] root [root2 ...]\n", (char *)NULL);
05930 break;
05931 }
05932 }
05933
05934 argc -= bu_optind;
05935 argv += bu_optind;
05936
05937
05938
05939
05940
05941
05942
05943 i = db_walk_tree(wdbp->dbip, argc, (const char **)argv,
05944 ncpu,
05945 &wdbp->wdb_initial_tree_state,
05946 0,
05947 wdb_push_region_end,
05948 wdb_push_leaf, (genptr_t)wpdp);
05949
05950
05951
05952
05953
05954 if (i < 0 || wpdp->push_error) {
05955 while (wpdp->pi_head.forw != &wpdp->pi_head) {
05956 pip = wpdp->pi_head.forw;
05957 pip->forw->back = pip->back;
05958 pip->back->forw = pip->forw;
05959 bu_free((genptr_t)pip, "Push ident");
05960 }
05961 rt_g.debug = old_debug;
05962 bu_free((genptr_t)wpdp, "wdb_push_tcl: wpdp");
05963 Tcl_AppendResult(interp,
05964 "push:\tdb_walk_tree failed or there was a solid moving\n\tin two or more directions",
05965 (char *)NULL);
05966 return TCL_ERROR;
05967 }
05968
05969
05970
05971
05972 FOR_ALL_WDB_PUSH_SOLIDS(pip,wpdp->pi_head) {
05973 if (rt_db_get_internal(&es_int, pip->pi_dir, wdbp->dbip, pip->pi_mat, &rt_uniresource) < 0) {
05974 Tcl_AppendResult(interp, "f_push: Read error fetching '",
05975 pip->pi_dir->d_namep, "'\n", (char *)NULL);
05976 wpdp->push_error = -1;
05977 continue;
05978 }
05979 RT_CK_DB_INTERNAL(&es_int);
05980
05981 if (rt_db_put_internal(pip->pi_dir, wdbp->dbip, &es_int, &rt_uniresource) < 0) {
05982 Tcl_AppendResult(interp, "push(", pip->pi_dir->d_namep,
05983 "): solid export failure\n", (char *)NULL);
05984 }
05985 rt_db_free_internal(&es_int, &rt_uniresource);
05986 }
05987
05988
05989
05990
05991
05992
05993
05994
05995
05996
05997
05998 while (argc > 0) {
05999 struct directory *db;
06000 db = db_lookup(wdbp->dbip, *argv++, 0);
06001 if (db)
06002 wdb_identitize(db, wdbp->dbip, interp);
06003 --argc;
06004 }
06005
06006
06007
06008
06009 while (wpdp->pi_head.forw != &wpdp->pi_head) {
06010 pip = wpdp->pi_head.forw;
06011 pip->forw->back = pip->back;
06012 pip->back->forw = pip->forw;
06013 bu_free((genptr_t)pip, "Push ident");
06014 }
06015
06016 rt_g.debug = old_debug;
06017 push_error = wpdp->push_error;
06018 bu_free((genptr_t)wpdp, "wdb_push_tcl: wpdp");
06019
06020 return push_error ? TCL_ERROR : TCL_OK;
06021 }
06022
06023
06024
06025
06026
06027
06028
06029
06030
06031
06032
06033
06034 static int
06035 wdb_push_tcl(ClientData clientData,
06036 Tcl_Interp *interp,
06037 int argc,
06038 char **argv)
06039 {
06040 struct rt_wdb *wdbp = (struct rt_wdb *)clientData;
06041
06042 return wdb_push_cmd(wdbp, interp, argc-1, argv+1);
06043 }
06044
06045 static void
06046 increment_uses(struct db_i *db_ip,
06047 struct directory *dp,
06048 genptr_t ptr)
06049 {
06050 RT_CK_DIR(dp);
06051
06052 dp->d_uses++;
06053 }
06054
06055 static void
06056 increment_nrefs(struct db_i *db_ip,
06057 struct directory *dp,
06058 genptr_t ptr)
06059 {
06060 RT_CK_DIR(dp);
06061
06062 dp->d_nref++;
06063 }
06064
06065 struct object_use
06066 {
06067 struct bu_list l;
06068 struct directory *dp;
06069 mat_t xform;
06070 int used;
06071 };
06072
06073 static void
06074 Free_uses( struct db_i *dbip )
06075 {
06076 int i;
06077
06078 for (i=0 ; i<RT_DBNHASH ; i++) {
06079 struct directory *dp;
06080 struct object_use *use;
06081
06082 for (dp=dbip->dbi_Head[i]; dp!=DIR_NULL; dp=dp->d_forw) {
06083 if (!(dp->d_flags & (DIR_SOLID | DIR_COMB)))
06084 continue;
06085
06086 while (BU_LIST_NON_EMPTY(&dp->d_use_hd)) {
06087 use = BU_LIST_FIRST(object_use, &dp->d_use_hd);
06088 if( !use->used ) {
06089 if( use->dp->d_un.file_offset >= 0 ) {
06090
06091 db_delete( dbip, use->dp );
06092 }
06093 db_dirdelete(dbip, use->dp);
06094 }
06095 BU_LIST_DEQUEUE(&use->l);
06096 bu_free((genptr_t)use, "Free_uses: use");
06097 }
06098
06099 }
06100 }
06101
06102 }
06103
06104 static void
06105 Make_new_name(struct db_i *dbip,
06106 struct directory *dp,
06107 genptr_t ptr)
06108 {
06109 struct object_use *use;
06110 int use_no;
06111 int digits;
06112 int suffix_start;
06113 int name_length;
06114 int j;
06115 char format_v4[25], format_v5[25];
06116 struct bu_vls name_v5;
06117 char name_v4[NAMESIZE];
06118 char *name;
06119
06120
06121 if (dp->d_uses < 2 && dp->d_uses == dp->d_nref)
06122 return;
06123
06124
06125 if (BU_LIST_NON_EMPTY(&dp->d_use_hd))
06126 return;
06127
06128 digits = log10((double)dp->d_uses) + 2.0;
06129 sprintf(format_v5, "%%s_%%0%dd", digits);
06130 sprintf(format_v4, "_%%0%dd", digits);
06131
06132 name_length = strlen(dp->d_namep);
06133 if (name_length + digits + 1 > NAMESIZE - 1)
06134 suffix_start = NAMESIZE - digits - 2;
06135 else
06136 suffix_start = name_length;
06137
06138 if (dbip->dbi_version >= 5)
06139 bu_vls_init(&name_v5);
06140 j = 0;
06141 for (use_no=0 ; use_no<dp->d_uses ; use_no++) {
06142 j++;
06143 use = (struct object_use *)bu_malloc( sizeof( struct object_use ), "Make_new_name: use" );
06144
06145
06146 MAT_ZERO(use->xform);
06147 use->used = 0;
06148 if (dbip->dbi_version < 5) {
06149 NAMEMOVE(dp->d_namep, name_v4);
06150 name_v4[NAMESIZE-1] = '\0';
06151 }
06152
06153
06154
06155
06156
06157 if (use_no == dp->d_uses-1 && dp->d_uses == dp->d_nref)
06158 use->dp = dp;
06159 else {
06160 if (dbip->dbi_version < 5) {
06161 sprintf(&name_v4[suffix_start], format_v4, j);
06162 name = name_v4;
06163 } else {
06164 bu_vls_trunc(&name_v5, 0);
06165 bu_vls_printf(&name_v5, format_v5, dp->d_namep, j);
06166 name = bu_vls_addr(&name_v5);
06167 }
06168
06169
06170 while (db_lookup( dbip, name, 0 ) != DIR_NULL) {
06171 j++;
06172 if (dbip->dbi_version < 5) {
06173 sprintf(&name_v4[suffix_start], format_v4, j);
06174 name = name_v4;
06175 } else {
06176 bu_vls_trunc(&name_v5, 0);
06177 bu_vls_printf(&name_v5, format_v5, dp->d_namep, j);
06178 name = bu_vls_addr(&name_v5);
06179 }
06180 }
06181
06182
06183 if ((use->dp = db_diradd(dbip, name, -1, 0, dp->d_flags,
06184 (genptr_t)&dp->d_minor_type)) == DIR_NULL) {
06185 WDB_ALLOC_ERR_return;
06186 }
06187 }
06188
06189
06190 BU_LIST_INSERT(&dp->d_use_hd, &use->l);
06191 }
06192
06193 if (dbip->dbi_version >= 5)
06194 bu_vls_free(&name_v5);
06195 }
06196
06197 static struct directory *
06198 Copy_solid(struct db_i *dbip,
06199 struct directory *dp,
06200 mat_t xform,
06201 Tcl_Interp *interp,
06202 struct rt_wdb *wdbp)
06203 {
06204 struct directory *found;
06205 struct rt_db_internal sol_int;
06206 struct object_use *use;
06207
06208 RT_CK_DIR(dp);
06209
06210 if (!(dp->d_flags & DIR_SOLID)) {
06211 Tcl_AppendResult(interp, "Copy_solid: ", dp->d_namep,
06212 " is not a solid!!!!\n", (char *)NULL);
06213 return (DIR_NULL);
06214 }
06215
06216
06217 if (bn_mat_is_identity(xform)) {
06218
06219 for (BU_LIST_FOR(use, object_use, &dp->d_use_hd)) {
06220 if (use->dp == dp && use->used == 0) {
06221 use->used = 1;
06222 return (dp);
06223 }
06224 }
06225 }
06226
06227
06228 for (BU_LIST_FOR(use, object_use, &dp->d_use_hd)) {
06229 if (bn_mat_is_equal(xform, use->xform, &wdbp->wdb_tol)) {
06230
06231 use->used = 1;
06232 return(use->dp);
06233 }
06234 }
06235
06236
06237 found = DIR_NULL;
06238 for (BU_LIST_FOR(use, object_use, &dp->d_use_hd)) {
06239 if (use->used)
06240 continue;
06241
06242 found = use->dp;
06243 use->used = 1;
06244 MAT_COPY(use->xform, xform);
06245 break;
06246 }
06247
06248 if (found == DIR_NULL && dp->d_nref == 1 && dp->d_uses == 1) {
06249
06250 found = dp;
06251 }
06252
06253 if (found == DIR_NULL) {
06254 Tcl_AppendResult(interp, "Ran out of uses for solid ",
06255 dp->d_namep, "\n", (char *)NULL);
06256 return (DIR_NULL);
06257 }
06258
06259 if (rt_db_get_internal(&sol_int, dp, dbip, xform, &rt_uniresource) < 0) {
06260 Tcl_AppendResult(interp, "Cannot import solid ",
06261 dp->d_namep, "\n", (char *)NULL);
06262 return (DIR_NULL);
06263 }
06264
06265 RT_CK_DB_INTERNAL(&sol_int);
06266 if (rt_db_put_internal(found, dbip, &sol_int, &rt_uniresource) < 0) {
06267 Tcl_AppendResult(interp, "Cannot write copy solid (", found->d_namep,
06268 ") to database\n", (char *)NULL);
06269 return (DIR_NULL);
06270 }
06271
06272 return (found);
06273 }
06274
06275 static struct directory *Copy_object(struct db_i *dbip, struct directory *dp, fastf_t *xform, Tcl_Interp *interp, struct rt_wdb *wdbp);
06276
06277 HIDDEN void
06278 Do_copy_membs(struct db_i *dbip,
06279 struct rt_comb_internal *comb,
06280 union tree *comb_leaf,
06281 genptr_t user_ptr1,
06282 genptr_t user_ptr2,
06283 genptr_t user_ptr3)
06284 {
06285 struct directory *dp;
06286 struct directory *dp_new;
06287 mat_t new_xform;
06288 matp_t xform;
06289 Tcl_Interp *interp;
06290 struct rt_wdb *wdbp;
06291
06292 RT_CK_DBI(dbip);
06293 RT_CK_TREE(comb_leaf);
06294
06295 if ((dp=db_lookup(dbip, comb_leaf->tr_l.tl_name, LOOKUP_QUIET)) == DIR_NULL)
06296 return;
06297
06298 xform = (matp_t)user_ptr1;
06299 interp = (Tcl_Interp *)user_ptr2;
06300 wdbp = (struct rt_wdb *)user_ptr3;
06301
06302
06303 if (comb_leaf->tr_l.tl_mat) {
06304 bn_mat_mul(new_xform, xform, comb_leaf->tr_l.tl_mat);
06305 } else {
06306 MAT_COPY(new_xform, xform);
06307 }
06308
06309
06310 if ((dp_new=Copy_object(dbip, dp, new_xform, interp, wdbp)) == DIR_NULL) {
06311 Tcl_AppendResult(interp, "Failed to copy object ",
06312 dp->d_namep, "\n", (char *)NULL);
06313 return;
06314 }
06315
06316
06317 bu_free(comb_leaf->tr_l.tl_name, "comb_leaf->tr_l.tl_name");
06318 comb_leaf->tr_l.tl_name = bu_strdup(dp_new->d_namep);
06319
06320
06321 if (!comb_leaf->tr_l.tl_mat) {
06322 comb_leaf->tr_l.tl_mat = (matp_t)bu_malloc(sizeof(mat_t), "tl_mat");
06323 }
06324 MAT_IDN(comb_leaf->tr_l.tl_mat);
06325 }
06326
06327 static struct directory *
06328 Copy_comb(struct db_i *dbip,
06329 struct directory *dp,
06330 mat_t xform,
06331 Tcl_Interp *interp,
06332 struct rt_wdb *wdbp)
06333 {
06334 struct object_use *use;
06335 struct directory *found;
06336 struct rt_db_internal intern;
06337 struct rt_comb_internal *comb;
06338
06339 RT_CK_DIR(dp);
06340
06341
06342 for (BU_LIST_FOR(use, object_use, &dp->d_use_hd)) {
06343 if (bn_mat_is_equal(xform, use->xform, &wdbp->wdb_tol)) {
06344
06345 use->used = 1;
06346 return (use->dp);
06347 }
06348 }
06349
06350
06351 if (rt_db_get_internal(&intern, dp, dbip, (fastf_t *)NULL, &rt_uniresource) < 0)
06352 return (dp);
06353 comb = (struct rt_comb_internal *)intern.idb_ptr;
06354
06355
06356 if (comb->tree)
06357 db_tree_funcleaf(dbip, comb, comb->tree, Do_copy_membs,
06358 (genptr_t)xform, (genptr_t)interp, (genptr_t)wdbp);
06359
06360
06361 found = DIR_NULL;
06362 for (BU_LIST_FOR(use, object_use, &dp->d_use_hd)) {
06363
06364 if (use->used)
06365 continue;
06366 found = use->dp;
06367 use->used = 1;
06368 MAT_COPY(use->xform, xform);
06369 break;
06370 }
06371
06372 if (found == DIR_NULL && dp->d_nref == 1 && dp->d_uses == 1) {
06373
06374 found = dp;
06375 }
06376
06377 if (found == DIR_NULL) {
06378 Tcl_AppendResult(interp, "Ran out of uses for combination ",
06379 dp->d_namep, "\n", (char *)NULL);
06380 return (DIR_NULL);
06381 }
06382
06383 if (rt_db_put_internal(found, dbip, &intern, &rt_uniresource) < 0) {
06384 Tcl_AppendResult(interp, "rt_db_put_internal failed for ", dp->d_namep,
06385 "\n", (char *)NULL);
06386 #if USE_RT_COMB_IFREE
06387 rt_comb_ifree(&intern, &rt_uniresource);
06388 #else
06389 rt_db_free_internal(&intern, &rt_uniresource);
06390 #endif
06391 return(DIR_NULL);
06392 }
06393
06394 return(found);
06395 }
06396
06397 static struct directory *
06398 Copy_object(struct db_i *dbip,
06399 struct directory *dp,
06400 mat_t xform,
06401 Tcl_Interp *interp,
06402 struct rt_wdb *wdbp)
06403 {
06404 RT_CK_DIR(dp);
06405
06406 if (dp->d_flags & DIR_SOLID)
06407 return (Copy_solid(dbip, dp, xform, interp, wdbp));
06408 else
06409 return (Copy_comb(dbip, dp, xform, interp, wdbp));
06410 }
06411
06412 HIDDEN void
06413 Do_ref_incr(struct db_i *dbip,
06414 struct rt_comb_internal *comb,
06415 union tree *comb_leaf,
06416 genptr_t user_ptr1,
06417 genptr_t user_ptr2,
06418 genptr_t user_ptr3)
06419 {
06420 struct directory *dp;
06421
06422 RT_CK_DBI(dbip);
06423 RT_CK_TREE(comb_leaf);
06424
06425 if ((dp = db_lookup(dbip, comb_leaf->tr_l.tl_name, LOOKUP_QUIET)) == DIR_NULL)
06426 return;
06427
06428 dp->d_nref++;
06429 }
06430
06431 int
06432 wdb_xpush_cmd(struct rt_wdb *wdbp,
06433 Tcl_Interp *interp,
06434 int argc,
06435 char **argv)
06436 {
06437 struct directory *old_dp;
06438 struct rt_db_internal intern;
06439 struct rt_comb_internal *comb;
06440 struct bu_ptbl tops;
06441 mat_t xform;
06442 int i;
06443
06444 WDB_TCL_CHECK_READ_ONLY;
06445
06446 if (argc != 2) {
06447 struct bu_vls vls;
06448
06449 bu_vls_init(&vls);
06450 bu_vls_printf(&vls, "helplib_alias wdb_xpush %s", argv[0]);
06451 Tcl_Eval(interp, bu_vls_addr(&vls));
06452 bu_vls_free(&vls);
06453 return TCL_ERROR;
06454 }
06455
06456
06457 if ((old_dp = db_lookup(wdbp->dbip, argv[1], LOOKUP_NOISY)) == DIR_NULL)
06458 return TCL_ERROR;
06459
06460
06461 for (i=0 ; i<RT_DBNHASH ; i++) {
06462 struct directory *dp;
06463
06464 for (dp=wdbp->dbip->dbi_Head[i]; dp!=DIR_NULL; dp=dp->d_forw) {
06465 if (!(dp->d_flags & (DIR_SOLID | DIR_COMB)))
06466 continue;
06467
06468 dp->d_uses = 0;
06469 dp->d_nref = 0;
06470 }
06471 }
06472
06473
06474 db_functree(wdbp->dbip, old_dp, increment_uses, increment_uses, &rt_uniresource, NULL);
06475
06476
06477 for (i=0 ; i<RT_DBNHASH ; i++) {
06478 struct directory *dp;
06479
06480 for (dp=wdbp->dbip->dbi_Head[i] ; dp!=DIR_NULL ; dp=dp->d_forw) {
06481 struct rt_db_internal intern;
06482 struct rt_comb_internal *comb;
06483
06484 if (dp->d_flags & DIR_SOLID)
06485 continue;
06486
06487 if (!(dp->d_flags & (DIR_SOLID | DIR_COMB)))
06488 continue;
06489
06490 if (rt_db_get_internal(&intern, dp, wdbp->dbip, (fastf_t *)NULL, &rt_uniresource) < 0)
06491 WDB_TCL_READ_ERR_return;
06492 comb = (struct rt_comb_internal *)intern.idb_ptr;
06493 if (comb->tree)
06494 db_tree_funcleaf(wdbp->dbip, comb, comb->tree, Do_ref_incr,
06495 (genptr_t )NULL, (genptr_t )NULL, (genptr_t )NULL);
06496 #if USE_RT_COMB_IFREE
06497 rt_comb_ifree(&intern, &rt_uniresource);
06498 #else
06499 rt_db_free_internal(&intern, &rt_uniresource);
06500 #endif
06501 }
06502 }
06503
06504
06505 bu_ptbl_init(&tops, 0, "tops for xpush");
06506 for (i=0; i<RT_DBNHASH; i++) {
06507 struct directory *dp;
06508
06509 for (dp=wdbp->dbip->dbi_Head[i]; dp!=DIR_NULL; dp=dp->d_forw) {
06510 if (dp->d_flags & DIR_SOLID)
06511 continue;
06512
06513 if (!(dp->d_flags & (DIR_SOLID | DIR_COMB )))
06514 continue;
06515
06516 if (dp->d_nref == 0)
06517 bu_ptbl(&tops, BU_PTBL_INS, (long *)dp);
06518 }
06519 }
06520
06521
06522 for (i=0 ; i<RT_DBNHASH ; i++) {
06523 struct directory *dp;
06524
06525 for (dp=wdbp->dbip->dbi_Head[i]; dp!=DIR_NULL; dp=dp->d_forw) {
06526 if (!(dp->d_flags & (DIR_SOLID | DIR_COMB)))
06527 continue;
06528
06529 dp->d_nref = 0;
06530 }
06531 }
06532
06533
06534 for (i=0; i<BU_PTBL_END(&tops); i++) {
06535 struct directory *dp;
06536
06537 dp = (struct directory *)BU_PTBL_GET(&tops, i);
06538 db_functree(wdbp->dbip, dp, increment_nrefs, increment_nrefs, &rt_uniresource, NULL);
06539 }
06540
06541
06542 bu_ptbl(&tops, BU_PTBL_FREE, (long *)NULL);
06543
06544
06545 db_functree(wdbp->dbip, old_dp, Make_new_name, Make_new_name, &rt_uniresource, NULL);
06546
06547 MAT_IDN(xform);
06548
06549
06550 if (rt_db_get_internal(&intern, old_dp, wdbp->dbip, (fastf_t *)NULL, &rt_uniresource) < 0) {
06551 bu_log("ERROR: cannot load %s feom the database!!!\n", old_dp->d_namep);
06552 bu_log("\tNothing has been changed!!\n");
06553 Free_uses( wdbp->dbip );
06554 return TCL_ERROR;
06555 }
06556
06557 comb = (struct rt_comb_internal *)intern.idb_ptr;
06558 if (!comb->tree) {
06559 Free_uses( wdbp->dbip );
06560 return TCL_OK;
06561 }
06562
06563 db_tree_funcleaf(wdbp->dbip, comb, comb->tree, Do_copy_membs,
06564 (genptr_t)xform, (genptr_t)interp, (genptr_t)wdbp);
06565
06566 if (rt_db_put_internal(old_dp, wdbp->dbip, &intern, &rt_uniresource) < 0) {
06567 Tcl_AppendResult(interp, "rt_db_put_internal failed for ", old_dp->d_namep,
06568 "\n", (char *)NULL);
06569 #if USE_RT_COMB_IFREE
06570 rt_comb_ifree(&intern, &rt_uniresource);
06571 #else
06572 rt_db_free_internal(&intern, &rt_uniresource);
06573 #endif
06574 Free_uses( wdbp->dbip );
06575 return TCL_ERROR;
06576 }
06577
06578
06579 Free_uses( wdbp->dbip );
06580 return TCL_OK;
06581 }
06582
06583 static int
06584 wdb_xpush_tcl(ClientData clientData,
06585 Tcl_Interp *interp,
06586 int argc,
06587 char **argv)
06588 {
06589 struct rt_wdb *wdbp = (struct rt_wdb *)clientData;
06590
06591 return wdb_xpush_cmd(wdbp, interp, argc-1, argv+1);
06592 }
06593
06594 int
06595 wdb_whatid_cmd(struct rt_wdb *wdbp,
06596 Tcl_Interp *interp,
06597 int argc,
06598 char **argv)
06599 {
06600 struct directory *dp;
06601 struct rt_db_internal intern;
06602 struct rt_comb_internal *comb;
06603 struct bu_vls vls;
06604
06605 if (argc != 2) {
06606 bu_vls_init(&vls);
06607 bu_vls_printf(&vls, "helplib_alias wdb_whatid %s", argv[0]);
06608 Tcl_Eval(interp, bu_vls_addr(&vls));
06609 bu_vls_free(&vls);
06610 return TCL_ERROR;
06611 }
06612
06613 if ((dp=db_lookup(wdbp->dbip, argv[1], LOOKUP_NOISY )) == DIR_NULL )
06614 return TCL_ERROR;
06615
06616 if (!(dp->d_flags & DIR_REGION)) {
06617 Tcl_AppendResult(interp, argv[1], " is not a region", (char *)NULL );
06618 return TCL_ERROR;
06619 }
06620
06621 if (rt_db_get_internal(&intern, dp, wdbp->dbip, (fastf_t *)NULL, &rt_uniresource) < 0)
06622 return TCL_ERROR;
06623 comb = (struct rt_comb_internal *)intern.idb_ptr;
06624
06625 bu_vls_init(&vls);
06626 bu_vls_printf(&vls, "%d", comb->region_id);
06627 #if USE_RT_COMB_IFREE
06628 rt_comb_ifree(&intern, &rt_uniresource);
06629 #else
06630 rt_db_free_internal(&intern, &rt_uniresource);
06631 #endif
06632 Tcl_AppendResult(interp, bu_vls_addr(&vls), (char *)NULL);
06633 bu_vls_free(&vls);
06634
06635 return TCL_OK;
06636 }
06637
06638
06639
06640
06641
06642 static int
06643 wdb_whatid_tcl(ClientData clientData,
06644 Tcl_Interp *interp,
06645 int argc,
06646 char **argv)
06647 {
06648 struct rt_wdb *wdbp = (struct rt_wdb *)clientData;
06649
06650 return wdb_whatid_cmd(wdbp, interp, argc-1, argv+1);
06651 }
06652
06653 struct wdb_node_data {
06654 FILE *fp;
06655 Tcl_Interp *interp;
06656 };
06657
06658
06659
06660
06661
06662
06663
06664 void
06665 wdb_node_write(struct db_i *dbip,
06666 register struct directory *dp,
06667 genptr_t ptr)
06668 {
06669 struct rt_wdb *keepfp = (struct rt_wdb *)ptr;
06670 struct rt_db_internal intern;
06671
06672 RT_CK_WDB(keepfp);
06673
06674 if (dp->d_nref++ > 0)
06675 return;
06676
06677 if (rt_db_get_internal(&intern, dp, dbip, NULL, &rt_uniresource) < 0)
06678 WDB_READ_ERR_return;
06679
06680
06681 if( dp->d_major_type == DB5_MAJORTYPE_BRLCAD && dp->d_minor_type == DB5_MINORTYPE_BRLCAD_EXTRUDE ) {
06682 struct rt_extrude_internal *extr;
06683 struct directory *dp2;
06684
06685 extr = (struct rt_extrude_internal *)intern.idb_ptr;
06686 RT_EXTRUDE_CK_MAGIC( extr );
06687
06688 if( (dp2 = db_lookup( dbip, extr->sketch_name, LOOKUP_QUIET )) != DIR_NULL ) {
06689 wdb_node_write( dbip, dp2, ptr );
06690 }
06691 } else if ( dp->d_major_type == DB5_MAJORTYPE_BRLCAD && dp->d_minor_type == DB5_MINORTYPE_BRLCAD_DSP ) {
06692 struct rt_dsp_internal *dsp;
06693 struct directory *dp2;
06694
06695
06696 dsp = (struct rt_dsp_internal *)intern.idb_ptr;
06697 RT_DSP_CK_MAGIC( dsp );
06698
06699 if( dsp->dsp_datasrc == RT_DSP_SRC_OBJ ) {
06700
06701 if( (dp2 = db_lookup( dbip, bu_vls_addr(&dsp->dsp_name), LOOKUP_QUIET )) != DIR_NULL ) {
06702 wdb_node_write( dbip, dp2, ptr );
06703 }
06704 }
06705 }
06706
06707 if (wdb_put_internal(keepfp, dp->d_namep, &intern, 1.0) < 0)
06708 WDB_WRITE_ERR_return;
06709 }
06710
06711 int
06712 wdb_keep_cmd(struct rt_wdb *wdbp,
06713 Tcl_Interp *interp,
06714 int argc,
06715 char **argv)
06716 {
06717 struct rt_wdb *keepfp;
06718 register struct directory *dp;
06719 struct bu_vls title;
06720 register int i;
06721 struct db_i *new_dbip;
06722
06723 if (argc < 3 || MAXARGS < argc) {
06724 struct bu_vls vls;
06725
06726 bu_vls_init(&vls);
06727 bu_vls_printf(&vls, "helplib_alias wdb_keep %s", argv[0]);
06728 Tcl_Eval(interp, bu_vls_addr(&vls));
06729 bu_vls_free(&vls);
06730 return TCL_ERROR;
06731 }
06732
06733
06734 for (i = 0; i < RT_DBNHASH; i++) {
06735 for (dp = wdbp->dbip->dbi_Head[i]; dp != DIR_NULL; dp = dp->d_forw)
06736 dp->d_nref = 0;
06737 }
06738
06739
06740
06741 new_dbip = db_open(argv[1], "w");
06742
06743
06744 if (new_dbip != DBI_NULL) {
06745 if (new_dbip->dbi_version != wdbp->dbip->dbi_version) {
06746 Tcl_AppendResult(interp,
06747 "keep: File format mismatch between '",
06748 argv[1], "' and '",
06749 wdbp->dbip->dbi_filename, "'\n",
06750 (char *)NULL);
06751 return TCL_ERROR;
06752 }
06753
06754 if ((keepfp = wdb_dbopen(new_dbip, RT_WDB_TYPE_DB_DISK)) == NULL) {
06755 Tcl_AppendResult(interp, "keep: Error opening '", argv[1],
06756 "'\n", (char *)NULL);
06757 return TCL_ERROR;
06758 } else {
06759 Tcl_AppendResult(interp, "keep: appending to '", argv[1],
06760 "'\n", (char *)NULL);
06761
06762
06763 db_dirbuild(new_dbip);
06764 }
06765 } else {
06766
06767 keepfp = wdb_fopen_v(argv[1], wdbp->dbip->dbi_version);
06768
06769 if (keepfp == NULL) {
06770 perror(argv[1]);
06771 return TCL_ERROR;
06772 }
06773 }
06774
06775
06776 bu_vls_init(&title);
06777 if (strncmp(wdbp->dbip->dbi_title, "Parts of: ", 10) != 0) {
06778 bu_vls_strcat(&title, "Parts of: ");
06779 }
06780 bu_vls_strcat(&title, wdbp->dbip->dbi_title);
06781
06782 if (db_update_ident(keepfp->dbip, bu_vls_addr(&title), wdbp->dbip->dbi_local2base) < 0) {
06783 perror("fwrite");
06784 Tcl_AppendResult(interp, "db_update_ident() failed\n", (char *)NULL);
06785 wdb_close(keepfp);
06786 bu_vls_free(&title);
06787 return TCL_ERROR;
06788 }
06789 bu_vls_free(&title);
06790
06791 for (i = 2; i < argc; i++) {
06792 if ((dp = db_lookup(wdbp->dbip, argv[i], LOOKUP_NOISY)) == DIR_NULL)
06793 continue;
06794 db_functree(wdbp->dbip, dp, wdb_node_write, wdb_node_write, &rt_uniresource, (genptr_t)keepfp);
06795 }
06796
06797 wdb_close(keepfp);
06798 return TCL_OK;
06799 }
06800
06801
06802
06803
06804
06805 static int
06806 wdb_keep_tcl(ClientData clientData,
06807 Tcl_Interp *interp,
06808 int argc,
06809 char **argv)
06810 {
06811 struct rt_wdb *wdbp = (struct rt_wdb *)clientData;
06812
06813 return wdb_keep_cmd(wdbp, interp, argc-1, argv+1);
06814 }
06815
06816 int
06817 wdb_cat_cmd(struct rt_wdb *wdbp,
06818 Tcl_Interp *interp,
06819 int argc,
06820 char **argv)
06821 {
06822 register struct directory *dp;
06823 register int arg;
06824 struct bu_vls str;
06825
06826 if (argc < 2 || MAXARGS < argc) {
06827 struct bu_vls vls;
06828
06829 bu_vls_init(&vls);
06830 bu_vls_printf(&vls, "helplib_alias wdb_cat %s", argv[0]);
06831 Tcl_Eval(interp, bu_vls_addr(&vls));
06832 bu_vls_free(&vls);
06833 return TCL_ERROR;
06834 }
06835
06836 bu_vls_init(&str);
06837 for (arg = 1; arg < argc; arg++) {
06838 if ((dp = db_lookup(wdbp->dbip, argv[arg], LOOKUP_NOISY)) == DIR_NULL)
06839 continue;
06840
06841 bu_vls_trunc(&str, 0);
06842 wdb_do_list(wdbp->dbip, interp, &str, dp, 0);
06843 Tcl_AppendResult(interp, bu_vls_addr(&str), "\n", (char *)NULL);
06844 }
06845 bu_vls_free(&str);
06846
06847 return TCL_OK;
06848 }
06849
06850
06851
06852
06853
06854 static int
06855 wdb_cat_tcl(ClientData clientData,
06856 Tcl_Interp *interp,
06857 int argc,
06858 char **argv)
06859 {
06860 struct rt_wdb *wdbp = (struct rt_wdb *)clientData;
06861
06862 return wdb_cat_cmd(wdbp, interp, argc-1, argv+1);
06863 }
06864
06865 int
06866 wdb_instance_cmd(struct rt_wdb *wdbp,
06867 Tcl_Interp *interp,
06868 int argc,
06869 char **argv)
06870 {
06871 register struct directory *dp;
06872 char oper;
06873
06874 WDB_TCL_CHECK_READ_ONLY;
06875
06876 if (argc < 3 || 4 < argc) {
06877 struct bu_vls vls;
06878
06879 bu_vls_init(&vls);
06880 bu_vls_printf(&vls, "helplib_alias wdb_instance %s", argv[0]);
06881 Tcl_Eval(interp, bu_vls_addr(&vls));
06882 bu_vls_free(&vls);
06883 return TCL_ERROR;
06884 }
06885
06886 if ((dp = db_lookup(wdbp->dbip, argv[1], LOOKUP_NOISY)) == DIR_NULL)
06887 return TCL_ERROR;
06888
06889 oper = WMOP_UNION;
06890 if (argc == 4)
06891 oper = argv[3][0];
06892
06893 if (oper != WMOP_UNION &&
06894 oper != WMOP_SUBTRACT &&
06895 oper != WMOP_INTERSECT) {
06896 struct bu_vls tmp_vls;
06897
06898 bu_vls_init(&tmp_vls);
06899 bu_vls_printf(&tmp_vls, "bad operation: %c\n", oper);
06900 Tcl_AppendResult(interp, bu_vls_addr(&tmp_vls), (char *)NULL);
06901 bu_vls_free(&tmp_vls);
06902 return TCL_ERROR;
06903 }
06904
06905 if (wdb_combadd(interp, wdbp->dbip, dp, argv[2], 0, oper, 0, 0, wdbp) == DIR_NULL)
06906 return TCL_ERROR;
06907
06908 return TCL_OK;
06909 }
06910
06911
06912
06913
06914
06915
06916
06917 static int
06918 wdb_instance_tcl(ClientData clientData,
06919 Tcl_Interp *interp,
06920 int argc,
06921 char **argv)
06922 {
06923 struct rt_wdb *wdbp = (struct rt_wdb *)clientData;
06924
06925 return wdb_instance_cmd(wdbp, interp, argc-1, argv+1);
06926 }
06927
06928 int
06929 wdb_observer_cmd(struct rt_wdb *wdbp,
06930 Tcl_Interp *interp,
06931 int argc,
06932 char **argv)
06933 {
06934 if (argc < 2) {
06935 struct bu_vls vls;
06936
06937
06938 bu_vls_init(&vls);
06939 bu_vls_printf(&vls, "helplib_alias wdb_observer %s", argv[0]);
06940 Tcl_Eval(interp, bu_vls_addr(&vls));
06941 bu_vls_free(&vls);
06942 return TCL_ERROR;
06943 }
06944
06945 return bu_cmd((ClientData)&wdbp->wdb_observers,
06946 interp, argc - 1, argv + 1, bu_observer_cmds, 0);
06947 }
06948
06949
06950
06951
06952
06953
06954
06955
06956 static int
06957 wdb_observer_tcl(ClientData clientData,
06958 Tcl_Interp *interp,
06959 int argc,
06960 char **argv)
06961 {
06962 struct rt_wdb *wdbp = (struct rt_wdb *)clientData;
06963
06964 return wdb_observer_cmd(wdbp, interp, argc-1, argv+1);
06965 }
06966
06967 int
06968 wdb_get_objpath_mat(struct rt_wdb *wdbp,
06969 Tcl_Interp *interp,
06970 int argc,
06971 char **argv,
06972 struct wdb_trace_data *wtdp)
06973 {
06974 int i, pos_in;
06975
06976
06977
06978
06979
06980
06981
06982 wtdp->wtd_interp = interp;
06983 wtdp->wtd_dbip = wdbp->dbip;
06984 wtdp->wtd_flag = WDB_EVAL_ONLY;
06985 wtdp->wtd_prflag = 0;
06986
06987 pos_in = 0;
06988
06989 if (argc == 1 && strchr(argv[0], '/')) {
06990 char *tok;
06991 char *av0;
06992 wtdp->wtd_objpos = 0;
06993
06994 av0 = strdup(argv[0]);
06995 tok = strtok(av0, "/");
06996 while (tok) {
06997 if ((wtdp->wtd_obj[wtdp->wtd_objpos++] =
06998 db_lookup(wdbp->dbip, tok, LOOKUP_NOISY)) == DIR_NULL) {
06999 Tcl_AppendResult(interp,
07000 "wdb_get_objpath_mat: Failed to find ",
07001 tok,
07002 "\n",
07003 (char *)0);
07004 free(av0);
07005 return TCL_ERROR;
07006 }
07007
07008 tok = strtok((char *)0, "/");
07009 }
07010
07011 free(av0);
07012 } else {
07013 wtdp->wtd_objpos = argc;
07014
07015
07016 for (i=0; i<wtdp->wtd_objpos; i++) {
07017 if ((wtdp->wtd_obj[i] =
07018 db_lookup(wdbp->dbip, argv[pos_in+i], LOOKUP_NOISY)) == DIR_NULL) {
07019 Tcl_AppendResult(interp,
07020 "wdb_get_objpath_mat: Failed to find ",
07021 argv[pos_in+i],
07022 "\n",
07023 (char *)0);
07024 return TCL_ERROR;
07025 }
07026 }
07027 }
07028
07029 MAT_IDN(wtdp->wtd_xform);
07030 wdb_trace(wtdp->wtd_obj[0], 0, bn_mat_identity, wtdp);
07031
07032 return TCL_OK;
07033 }
07034
07035
07036
07037
07038 int
07039 wdb_get_obj_bounds2(struct rt_wdb *wdbp,
07040 Tcl_Interp *interp,
07041 int argc,
07042 char **argv,
07043 struct wdb_trace_data *wtdp,
07044 point_t rpp_min,
07045 point_t rpp_max)
07046 {
07047 register struct directory *dp;
07048 struct rt_db_internal intern;
07049 struct rt_i *rtip;
07050 struct soltab *stp;
07051 mat_t imat;
07052
07053
07054 VSETALL(rpp_min, MAX_FASTF);
07055 VREVERSE(rpp_max, rpp_min);
07056
07057 if (wdb_get_objpath_mat(wdbp, interp, argc, argv, wtdp) == TCL_ERROR)
07058 return TCL_ERROR;
07059
07060 dp = wtdp->wtd_obj[wtdp->wtd_objpos-1];
07061 if (rt_db_get_internal(&intern,
07062 dp,
07063 wdbp->dbip,
07064 wtdp->wtd_xform,
07065 &rt_uniresource) < 0) {
07066 Tcl_AppendResult(interp,
07067 "rt_db_get_internal(",
07068 dp->d_namep,
07069 ") failure",
07070 (char *)0);
07071 return TCL_ERROR;
07072 }
07073
07074
07075 if ((rtip=rt_new_rti(wdbp->dbip)) == RTI_NULL) {
07076 Tcl_AppendResult(interp,
07077 "rt_new_rti failure for ",
07078 wdbp->dbip->dbi_filename,
07079 "\n",
07080 (char *)0);
07081 return TCL_ERROR;
07082 }
07083
07084 BU_GETSTRUCT(stp, soltab);
07085 stp->l.magic = RT_SOLTAB_MAGIC;
07086 stp->l2.magic = RT_SOLTAB2_MAGIC;
07087 stp->st_dp = dp;
07088 MAT_IDN(imat);
07089 stp->st_matp = imat;
07090
07091
07092 VMOVE(stp->st_min, rpp_min);
07093 VMOVE(stp->st_max, rpp_max);
07094 intern.idb_meth->ft_prep(stp, &intern, rtip);
07095 VMOVE(rpp_min, stp->st_min);
07096 VMOVE(rpp_max, stp->st_max);
07097
07098 rt_free_rti(rtip);
07099 rt_db_free_internal(&intern, &rt_uniresource);
07100 bu_free( (char *)stp, "struct soltab" );
07101
07102 return TCL_OK;
07103 }
07104
07105
07106 int
07107 wdb_get_obj_bounds(struct rt_wdb *wdbp,
07108 Tcl_Interp *interp,
07109 int argc,
07110 char **argv,
07111 int use_air,
07112 point_t rpp_min,
07113 point_t rpp_max)
07114 {
07115 register int i;
07116 struct rt_i *rtip;
07117 struct db_full_path path;
07118 struct region *regp;
07119
07120
07121 if ((rtip=rt_new_rti(wdbp->dbip)) == RTI_NULL) {
07122 Tcl_AppendResult(interp, "rt_new_rti failure for ", wdbp->dbip->dbi_filename,
07123 "\n", (char *)NULL);
07124 return TCL_ERROR;
07125 }
07126
07127 rtip->useair = use_air;
07128
07129
07130 for (i = 0; i < argc; i++) {
07131 int gottree;
07132
07133
07134 db_full_path_init(&path);
07135 if (db_string_to_path(&path, rtip->rti_dbip, argv[i])) {
07136 Tcl_AppendResult(interp, "db_string_to_path failed for ",
07137 argv[i], "\n", (char *)NULL );
07138 rt_free_rti(rtip);
07139 return TCL_ERROR;
07140 }
07141
07142
07143 gottree = 0;
07144 for (BU_LIST_FOR(regp, region, &(rtip->HeadRegion))) {
07145 struct db_full_path tmp_path;
07146
07147 db_full_path_init(&tmp_path);
07148 if (db_string_to_path(&tmp_path, rtip->rti_dbip, regp->reg_name)) {
07149 Tcl_AppendResult(interp, "db_string_to_path failed for ",
07150 regp->reg_name, "\n", (char *)NULL);
07151 rt_free_rti(rtip);
07152 return TCL_ERROR;
07153 }
07154 if (path.fp_names[0] == tmp_path.fp_names[0])
07155 gottree = 1;
07156 db_free_full_path(&tmp_path);
07157 if (gottree)
07158 break;
07159 }
07160
07161
07162 if (!gottree && rt_gettree(rtip, path.fp_names[0]->d_namep)) {
07163 Tcl_AppendResult(interp, "rt_gettree failed for ",
07164 argv[i], "\n", (char *)NULL );
07165 rt_free_rti(rtip);
07166 return TCL_ERROR;
07167 }
07168 db_free_full_path(&path);
07169 }
07170
07171
07172 rt_prep(rtip);
07173
07174
07175 VSETALL(rpp_min, MAX_FASTF);
07176 VREVERSE(rpp_max, rpp_min);
07177 for (i = 0; i < argc; i++) {
07178 vect_t reg_min, reg_max;
07179 struct region *regp;
07180 const char *reg_name;
07181
07182
07183 for (BU_LIST_FOR(regp, region, &(rtip->HeadRegion))) {
07184 reg_name = regp->reg_name;
07185 if (*argv[i] != '/' && *reg_name == '/')
07186 reg_name++;
07187
07188 if (!strcmp( reg_name, argv[i]))
07189 goto found;
07190 }
07191 goto not_found;
07192
07193 found:
07194 if (regp != REGION_NULL) {
07195
07196 if (rt_bound_tree(regp->reg_treetop, reg_min, reg_max)) {
07197 Tcl_AppendResult(interp, "rt_bound_tree failed for ",
07198 regp->reg_name, "\n", (char *)NULL);
07199 rt_free_rti(rtip);
07200 return TCL_ERROR;
07201 }
07202 VMINMAX(rpp_min, rpp_max, reg_min);
07203 VMINMAX(rpp_min, rpp_max, reg_max);
07204 } else {
07205 int name_len;
07206 not_found:
07207
07208
07209
07210
07211 name_len = strlen( argv[i] );
07212 for (BU_LIST_FOR( regp, region, &(rtip->HeadRegion))) {
07213 reg_name = regp->reg_name;
07214 if (*argv[i] != '/' && *reg_name == '/')
07215 reg_name++;
07216
07217 if (strncmp(argv[i], reg_name, name_len))
07218 continue;
07219
07220
07221 if (rt_bound_tree(regp->reg_treetop, reg_min, reg_max)) {
07222 Tcl_AppendResult(interp, "rt_bound_tree failed for ",
07223 regp->reg_name, "\n", (char *)NULL);
07224 rt_free_rti(rtip);
07225 return TCL_ERROR;
07226 }
07227 VMINMAX(rpp_min, rpp_max, reg_min);
07228 VMINMAX(rpp_min, rpp_max, reg_max);
07229 }
07230 }
07231 }
07232
07233 rt_free_rti(rtip);
07234
07235 return TCL_OK;
07236 }
07237
07238 int
07239 wdb_make_bb_cmd(struct rt_wdb *wdbp,
07240 Tcl_Interp *interp,
07241 int argc,
07242 char **argv)
07243 {
07244 register int i;
07245 point_t rpp_min,rpp_max;
07246 struct directory *dp;
07247 struct rt_arb_internal *arb;
07248 struct rt_db_internal new_intern;
07249 char *new_name;
07250 int use_air = 0;
07251
07252 WDB_TCL_CHECK_READ_ONLY;
07253
07254 if (argc < 3 || MAXARGS < argc) {
07255 struct bu_vls vls;
07256
07257 bu_vls_init(&vls);
07258 bu_vls_printf(&vls, "helplib_alias wdb_make_bb %s", argv[0]);
07259 Tcl_Eval(interp, bu_vls_addr(&vls));
07260 bu_vls_free(&vls);
07261 return TCL_ERROR;
07262 }
07263
07264 i = 1;
07265
07266
07267 if ( ! strcmp(argv[i], "-u") ) {
07268 use_air = 1;
07269 i++;
07270 }
07271
07272
07273 if (strchr(argv[i], '/')) {
07274 Tcl_AppendResult(interp, "Do not use '/' in solid names: ", argv[i], "\n", (char *)NULL);
07275 return TCL_ERROR;
07276 }
07277
07278 new_name = argv[i++];
07279 if (db_lookup(wdbp->dbip, new_name, LOOKUP_QUIET) != DIR_NULL) {
07280 Tcl_AppendResult(interp, new_name, " already exists\n", (char *)NULL);
07281 return TCL_ERROR;
07282 }
07283
07284 if (wdb_get_obj_bounds(wdbp, interp, argc-2, argv+2, use_air, rpp_min, rpp_max) == TCL_ERROR)
07285 return TCL_ERROR;
07286
07287
07288 arb = (struct rt_arb_internal *)bu_malloc(sizeof(struct rt_arb_internal), "arb");
07289 VMOVE(arb->pt[0], rpp_min);
07290 VSET(arb->pt[1], rpp_min[X], rpp_min[Y], rpp_max[Z]);
07291 VSET(arb->pt[2], rpp_min[X], rpp_max[Y], rpp_max[Z]);
07292 VSET(arb->pt[3], rpp_min[X], rpp_max[Y], rpp_min[Z]);
07293 VSET(arb->pt[4], rpp_max[X], rpp_min[Y], rpp_min[Z]);
07294 VSET(arb->pt[5], rpp_max[X], rpp_min[Y], rpp_max[Z]);
07295 VMOVE(arb->pt[6], rpp_max);
07296 VSET(arb->pt[7], rpp_max[X], rpp_max[Y], rpp_min[Z]);
07297 arb->magic = RT_ARB_INTERNAL_MAGIC;
07298
07299
07300 RT_INIT_DB_INTERNAL(&new_intern);
07301 new_intern.idb_major_type = DB5_MAJORTYPE_BRLCAD;
07302 new_intern.idb_type = ID_ARB8;
07303 new_intern.idb_meth = &rt_functab[ID_ARB8];
07304 new_intern.idb_ptr = (genptr_t)arb;
07305
07306 if ((dp=db_diradd( wdbp->dbip, new_name, -1L, 0, DIR_SOLID, (genptr_t)&new_intern.idb_type)) == DIR_NULL) {
07307 Tcl_AppendResult(interp, "Cannot add ", new_name, " to directory\n", (char *)NULL);
07308 return TCL_ERROR;
07309 }
07310
07311 if (rt_db_put_internal(dp, wdbp->dbip, &new_intern, wdbp->wdb_resp) < 0) {
07312 rt_db_free_internal(&new_intern, wdbp->wdb_resp);
07313 Tcl_AppendResult(interp, "Database write error, aborting.\n", (char *)NULL);
07314 return TCL_ERROR;
07315 }
07316
07317 return TCL_OK;
07318 }
07319
07320
07321
07322
07323
07324
07325
07326
07327 static int
07328 wdb_make_bb_tcl(ClientData clientData,
07329 Tcl_Interp *interp,
07330 int argc,
07331 char **argv)
07332 {
07333 struct rt_wdb *wdbp = (struct rt_wdb *)clientData;
07334
07335 return wdb_make_bb_cmd(wdbp, interp, argc-1, argv+1);
07336 }
07337
07338 int
07339 wdb_make_name_cmd(struct rt_wdb *wdbp,
07340 Tcl_Interp *interp,
07341 int argc,
07342 char **argv)
07343 {
07344 struct bu_vls obj_name;
07345 char *cp, *tp;
07346 static int i = 0;
07347 int len;
07348
07349 switch (argc) {
07350 case 2:
07351 if (strcmp(argv[1], "-s") != 0)
07352 break;
07353 else {
07354 i = 0;
07355 return TCL_OK;
07356 }
07357 case 3:
07358 {
07359 int new_i;
07360
07361 if ((strcmp(argv[1], "-s") == 0)
07362 && (sscanf(argv[2], "%d", &new_i) == 1)) {
07363 i = new_i;
07364 return TCL_OK;
07365 }
07366 }
07367 default:
07368 {
07369 struct bu_vls vls;
07370
07371 bu_vls_init(&vls);
07372 bu_vls_printf(&vls, "helplib_alias wdb_make_name %s", argv[0]);
07373 Tcl_Eval(interp, bu_vls_addr(&vls));
07374 bu_vls_free(&vls);
07375 return TCL_ERROR;
07376 }
07377 }
07378
07379 bu_vls_init(&obj_name);
07380 for (cp = argv[1], len = 0; *cp != '\0'; ++cp, ++len) {
07381 if (*cp == '@') {
07382 if (*(cp + 1) == '@')
07383 ++cp;
07384 else
07385 break;
07386 }
07387 bu_vls_putc(&obj_name, *cp);
07388 }
07389 bu_vls_putc(&obj_name, '\0');
07390 tp = (*cp == '\0') ? "" : cp + 1;
07391
07392 do {
07393 bu_vls_trunc(&obj_name, len);
07394 bu_vls_printf(&obj_name, "%d", i++);
07395 bu_vls_strcat(&obj_name, tp);
07396 }
07397 while (db_lookup(wdbp->dbip, bu_vls_addr(&obj_name), LOOKUP_QUIET) != DIR_NULL);
07398 Tcl_AppendResult(interp, bu_vls_addr(&obj_name), (char *) NULL);
07399 bu_vls_free(&obj_name);
07400 return TCL_OK;
07401 }
07402
07403
07404
07405
07406
07407
07408
07409
07410
07411
07412 static int
07413 wdb_make_name_tcl(ClientData clientData,
07414 Tcl_Interp *interp,
07415 int argc,
07416 char **argv)
07417
07418 {
07419 struct rt_wdb *wdbp = (struct rt_wdb *)clientData;
07420
07421 return wdb_make_name_cmd(wdbp, interp, argc-1, argv+1);
07422 }
07423
07424 int
07425 wdb_units_cmd(struct rt_wdb *wdbp,
07426 Tcl_Interp *interp,
07427 int argc,
07428 char **argv)
07429 {
07430 double loc2mm;
07431 struct bu_vls vls;
07432 const char *str;
07433 int sflag = 0;
07434
07435 bu_vls_init(&vls);
07436 if (argc < 1 || 2 < argc) {
07437 bu_vls_printf(&vls, "helplib_alias wdb_units %s", argv[0]);
07438 Tcl_Eval(interp, bu_vls_addr(&vls));
07439 bu_vls_free(&vls);
07440 return TCL_ERROR;
07441 }
07442
07443 if (argc == 2 && strcmp(argv[1], "-s") == 0) {
07444 --argc;
07445 ++argv;
07446
07447 sflag = 1;
07448 }
07449
07450 if (argc < 2) {
07451 str = bu_units_string(wdbp->dbip->dbi_local2base);
07452 if (!str) str = "Unknown_unit";
07453
07454 if (sflag)
07455 bu_vls_printf(&vls, "%s", str);
07456 else
07457 bu_vls_printf(&vls, "You are editing in '%s'. 1 %s = %g mm \n",
07458 str, str, wdbp->dbip->dbi_local2base );
07459
07460 Tcl_AppendResult(interp, bu_vls_addr(&vls), (char *)NULL);
07461 bu_vls_free(&vls);
07462 return TCL_OK;
07463 }
07464
07465
07466 if ((loc2mm = bu_mm_value(argv[1]) ) <= 0) {
07467 Tcl_AppendResult(interp, argv[1], ": unrecognized unit\n",
07468 "valid units: <um|mm|cm|m|km|in|ft|yd|mi>\n", (char *)NULL);
07469 bu_vls_free(&vls);
07470 return TCL_ERROR;
07471 }
07472
07473 if (db_update_ident(wdbp->dbip, wdbp->dbip->dbi_title, loc2mm) < 0) {
07474 Tcl_AppendResult(interp,
07475 "Warning: unable to stash working units into database\n",
07476 (char *)NULL);
07477 }
07478
07479 wdbp->dbip->dbi_local2base = loc2mm;
07480 wdbp->dbip->dbi_base2local = 1.0 / loc2mm;
07481
07482 str = bu_units_string(wdbp->dbip->dbi_local2base);
07483 if (!str) str = "Unknown_unit";
07484 bu_vls_printf(&vls, "You are now editing in '%s'. 1 %s = %g mm \n",
07485 str, str, wdbp->dbip->dbi_local2base );
07486 Tcl_AppendResult(interp, bu_vls_addr(&vls), (char *)NULL);
07487 bu_vls_free(&vls);
07488
07489 return TCL_OK;
07490 }
07491
07492
07493
07494
07495
07496
07497
07498 static int
07499 wdb_units_tcl(ClientData clientData,
07500 Tcl_Interp *interp,
07501 int argc,
07502 char **argv)
07503 {
07504 struct rt_wdb *wdbp = (struct rt_wdb *)clientData;
07505
07506 return wdb_units_cmd(wdbp, interp, argc-1, argv+1);
07507 }
07508
07509 int
07510 wdb_hide_cmd(struct rt_wdb *wdbp,
07511 Tcl_Interp *interp,
07512 int argc,
07513 char **argv)
07514 {
07515 struct directory *dp;
07516 struct db_i *dbip;
07517 struct bu_external ext;
07518 struct bu_external tmp;
07519 struct db5_raw_internal raw;
07520 int i;
07521
07522 WDB_TCL_CHECK_READ_ONLY;
07523
07524 if( argc < 2 ) {
07525 struct bu_vls vls;
07526
07527 bu_vls_init( &vls );
07528 bu_vls_printf(&vls, "helplib_alias wdb_hide %s", argv[0]);
07529 Tcl_Eval(interp, bu_vls_addr(&vls));
07530 bu_vls_free(&vls);
07531 return TCL_ERROR;
07532 }
07533
07534 RT_CK_WDB( wdbp );
07535
07536 dbip = wdbp->dbip;
07537
07538 RT_CK_DBI( dbip );
07539 if( dbip->dbi_version < 5 ) {
07540 Tcl_AppendResult(interp,
07541 "Database was created with a previous release of BRL-CAD.\nSelect \"Tools->Upgrade Database...\" to enable support for this feature.",
07542 (char *)NULL );
07543 return TCL_ERROR;
07544 }
07545
07546 for( i=1 ; i<argc ; i++ ) {
07547 if( (dp = db_lookup( dbip, argv[i], LOOKUP_NOISY )) == DIR_NULL ) {
07548 continue;
07549 }
07550
07551 RT_CK_DIR( dp );
07552
07553 if( dp->d_major_type == DB5_MAJORTYPE_BRLCAD ) {
07554 int no_hide=0;
07555
07556
07557 if( isatty(fileno(stdin)) && isatty(fileno(stdout))) {
07558 char line[80];
07559
07560
07561 #if 0
07562
07563 while( 1 ) {
07564 bu_log( "Hiding BRL-CAD geometry (%s) is generaly a bad idea.\n", dp->d_namep );
07565 bu_log( "This may cause unexpected problems with other commands.\n" );
07566 bu_log( "Are you sure you want to do this?? (y/n)\n" );
07567 (void)fgets( line, sizeof( line ), stdin );
07568 if( line[0] == 'y' || line[0] == 'Y' ) break;
07569 if( line[0] == 'n' || line[0] == 'N' ) {
07570 no_hide = 1;
07571 break;
07572 }
07573 }
07574 #endif
07575 } else if( Tcl_GetVar2Ex( interp, "tk_version", NULL, TCL_GLOBAL_ONLY ) ) {
07576 #if 0
07577 struct bu_vls vls;
07578
07579
07580
07581
07582
07583
07584 bu_vls_init( &vls );
07585 bu_vls_printf( &vls, "Hiding BRL-CAD geometry (%s) is generaly a bad idea.\n", dp->d_namep );
07586 bu_vls_strcat( &vls, "This may cause unexpected problems with other commands.\n" );
07587 bu_vls_strcat( &vls, "Are you sure you want to do this??" );
07588 (void)Tcl_ResetResult( interp );
07589 if( Tcl_VarEval( interp, "tk_messageBox -type yesno ",
07590 "-title Warning -icon question -message {",
07591 bu_vls_addr( &vls ), "}",
07592 (char *)NULL ) != TCL_OK ) {
07593 bu_log( "Unable to post question!!!\n" );
07594 } else {
07595 const char *result;
07596
07597 result = Tcl_GetStringResult( interp );
07598 if( !strcmp( result, "no" ) ) {
07599 no_hide = 1;
07600 }
07601 (void)Tcl_ResetResult( interp );
07602 }
07603 #endif
07604 }
07605 if( no_hide )
07606 continue;
07607 }
07608
07609 BU_INIT_EXTERNAL(&ext);
07610
07611 if( db_get_external( &ext, dp, dbip ) < 0 ) {
07612 Tcl_AppendResult(interp, "db_get_external failed for ",
07613 dp->d_namep, " \n", (char *)NULL );
07614 continue;
07615 }
07616
07617 if (db5_get_raw_internal_ptr(&raw, ext.ext_buf) == NULL) {
07618 Tcl_AppendResult(interp, "db5_get_raw_internal_ptr() failed for ",
07619 dp->d_namep, " \n", (char *)NULL );
07620 bu_free_external( &ext );
07621 continue;
07622 }
07623
07624 raw.h_name_hidden = (unsigned char)(0x1);
07625
07626 BU_INIT_EXTERNAL( &tmp );
07627 db5_export_object3( &tmp, DB5HDR_HFLAGS_DLI_APPLICATION_DATA_OBJECT,
07628 dp->d_namep,
07629 raw.h_name_hidden,
07630 &raw.attributes,
07631 &raw.body,
07632 raw.major_type, raw.minor_type,
07633 raw.a_zzz, raw.b_zzz );
07634 bu_free_external( &ext );
07635
07636 if( db_put_external( &tmp, dp, dbip ) ) {
07637 Tcl_AppendResult(interp, "db_put_external() failed for ",
07638 dp->d_namep, " \n", (char *)NULL );
07639 bu_free_external( &tmp );
07640 continue;
07641 }
07642 bu_free_external( &tmp );
07643 dp->d_flags |= DIR_HIDDEN;
07644 }
07645
07646 return TCL_OK;
07647 }
07648
07649 static int
07650 wdb_hide_tcl(ClientData clientData,
07651 Tcl_Interp *interp,
07652 int argc,
07653 char **argv)
07654 {
07655 struct rt_wdb *wdbp = (struct rt_wdb *)clientData;
07656
07657 return wdb_hide_cmd(wdbp, interp, argc-1, argv+1);
07658 }
07659
07660 int
07661 wdb_unhide_cmd(struct rt_wdb *wdbp,
07662 Tcl_Interp *interp,
07663 int argc,
07664 char **argv)
07665 {
07666 struct directory *dp;
07667 struct db_i *dbip;
07668 struct bu_external ext;
07669 struct bu_external tmp;
07670 struct db5_raw_internal raw;
07671 int i;
07672
07673 WDB_TCL_CHECK_READ_ONLY;
07674
07675 if( argc < 2 ) {
07676 struct bu_vls vls;
07677
07678 bu_vls_init( &vls );
07679 bu_vls_printf(&vls, "helplib_alias wdb_unhide %s", argv[0]);
07680 Tcl_Eval(interp, bu_vls_addr(&vls));
07681 bu_vls_free(&vls);
07682 return TCL_ERROR;
07683 }
07684
07685 RT_CK_WDB( wdbp );
07686
07687 dbip = wdbp->dbip;
07688
07689 RT_CK_DBI( dbip );
07690 if( dbip->dbi_version < 5 ) {
07691 Tcl_AppendResult(interp,
07692 "Database was created with a previous release of BRL-CAD.\nSelect \"Tools->Upgrade Database...\" to enable support for this feature.",
07693 (char *)NULL );
07694 return TCL_ERROR;
07695 }
07696
07697 for( i=1 ; i<argc ; i++ ) {
07698 if( (dp = db_lookup( dbip, argv[i], LOOKUP_NOISY )) == DIR_NULL ) {
07699 continue;
07700 }
07701
07702 RT_CK_DIR( dp );
07703
07704 BU_INIT_EXTERNAL(&ext);
07705
07706 if( db_get_external( &ext, dp, dbip ) < 0 ) {
07707 Tcl_AppendResult(interp, "db_get_external failed for ",
07708 dp->d_namep, " \n", (char *)NULL );
07709 continue;
07710 }
07711
07712 if (db5_get_raw_internal_ptr(&raw, ext.ext_buf) == NULL) {
07713 Tcl_AppendResult(interp, "db5_get_raw_internal_ptr() failed for ",
07714 dp->d_namep, " \n", (char *)NULL );
07715 bu_free_external( &ext );
07716 continue;
07717 }
07718
07719 raw.h_name_hidden = (unsigned char)(0x0);
07720
07721 BU_INIT_EXTERNAL( &tmp );
07722 db5_export_object3( &tmp, DB5HDR_HFLAGS_DLI_APPLICATION_DATA_OBJECT,
07723 dp->d_namep,
07724 raw.h_name_hidden,
07725 &raw.attributes,
07726 &raw.body,
07727 raw.major_type, raw.minor_type,
07728 raw.a_zzz, raw.b_zzz );
07729 bu_free_external( &ext );
07730
07731 if( db_put_external( &tmp, dp, dbip ) ) {
07732 Tcl_AppendResult(interp, "db_put_external() failed for ",
07733 dp->d_namep, " \n", (char *)NULL );
07734 bu_free_external( &tmp );
07735 continue;
07736 }
07737 bu_free_external( &tmp );
07738 dp->d_flags &= (~DIR_HIDDEN);
07739 }
07740
07741 return TCL_OK;
07742 }
07743
07744 static int
07745 wdb_unhide_tcl(ClientData clientData,
07746 Tcl_Interp *interp,
07747 int argc,
07748 char **argv)
07749 {
07750 struct rt_wdb *wdbp = (struct rt_wdb *)clientData;
07751
07752 return wdb_unhide_cmd(wdbp, interp, argc-1, argv+1);
07753 }
07754
07755
07756
07757
07758
07759
07760
07761
07762
07763
07764
07765
07766
07767
07768
07769
07770
07771
07772
07773
07774
07775
07776
07777
07778 int
07779 wdb_attr_cmd(struct rt_wdb *wdbp,
07780 Tcl_Interp *interp,
07781 int argc,
07782 char **argv)
07783 {
07784 int i;
07785 struct directory *dp;
07786 struct bu_attribute_value_set avs;
07787 struct bu_attribute_value_pair *avpp;
07788
07789
07790 if( wdbp->dbip->dbi_version < 5 ) {
07791 Tcl_AppendResult(interp, "Attributes are not available for this database format.\nPlease upgrade your database format using \"dbupgrade\" to enable attributes.", (char *)NULL );
07792 return TCL_ERROR;
07793 }
07794
07795 if (argc < 3 ) {
07796 struct bu_vls vls;
07797
07798 bu_vls_init(&vls);
07799 bu_vls_printf(&vls, "helplib_alias wdb_attr %s", argv[0]);
07800 Tcl_Eval(interp, bu_vls_addr(&vls));
07801 bu_vls_free(&vls);
07802 return TCL_ERROR;
07803 }
07804
07805
07806
07807 if (wdbp->dbip == 0) {
07808 Tcl_AppendResult(interp,
07809 "db does not support lookup operations",
07810 (char *)NULL);
07811 return TCL_ERROR;
07812 }
07813
07814 if( (dp=db_lookup( wdbp->dbip, argv[2], LOOKUP_QUIET)) == DIR_NULL ) {
07815 Tcl_AppendResult(interp,
07816 argv[2],
07817 " does not exist\n",
07818 (char *)NULL );
07819 return TCL_ERROR;
07820 }
07821
07822 bu_avs_init_empty(&avs);
07823 if( db5_get_attributes( wdbp->dbip, &avs, dp ) ) {
07824 Tcl_AppendResult(interp,
07825 "Cannot get attributes for object ", dp->d_namep, "\n", (char *)NULL );
07826 return TCL_ERROR;
07827 }
07828
07829 if( strcmp( argv[1], "get" ) == 0 ) {
07830 if( argc == 3 ) {
07831
07832 avpp = avs.avp;
07833 for( i=0 ; i < avs.count ; i++, avpp++ ) {
07834 Tcl_AppendResult(interp, avpp->name, " {",
07835 avpp->value, "} ", (char *)NULL );
07836 }
07837 } else {
07838 const char *val;
07839 int do_separators=argc-4;
07840
07841 for( i=3 ; i<argc ; i++ ) {
07842 val = bu_avs_get( &avs, argv[i] );
07843 if( !val ) {
07844 Tcl_ResetResult( interp );
07845 Tcl_AppendResult(interp, "Object ",
07846 dp->d_namep, " does not have a ",
07847 argv[i], " attribute\n",
07848 (char *)NULL );
07849 bu_avs_free( &avs );
07850 return TCL_ERROR;
07851 }
07852 if( do_separators ) {
07853 Tcl_AppendResult(interp,
07854 "{",
07855 val,
07856 "} ",
07857 (char *)NULL );
07858 } else {
07859 Tcl_AppendResult(interp, val,
07860 (char *)NULL );
07861 }
07862 }
07863 }
07864
07865 bu_avs_free( &avs );
07866 return TCL_OK;
07867
07868 } else if( strcmp( argv[1], "set" ) == 0 ) {
07869
07870 if( (argc - 3) % 2 ) {
07871 Tcl_AppendResult(interp,
07872 "Error: attribute names and values must be in pairs!!!\n",
07873 (char *)NULL );
07874 bu_avs_free( &avs );
07875 return TCL_ERROR;
07876 }
07877
07878 i = 3;
07879 while( i < argc ) {
07880 (void)bu_avs_add( &avs, argv[i], argv[i+1] );
07881 i += 2;
07882 }
07883 if( db5_update_attributes( dp, &avs, wdbp->dbip ) ) {
07884 Tcl_AppendResult(interp,
07885 "Error: failed to update attributes\n",
07886 (char *)NULL );
07887 bu_avs_free( &avs );
07888 return TCL_ERROR;
07889 }
07890
07891
07892 return TCL_OK;
07893 } else if( strcmp( argv[1], "rm" ) == 0 ) {
07894 i = 3;
07895 while( i < argc ) {
07896 (void)bu_avs_remove( &avs, argv[i] );
07897 i++;
07898 }
07899 if( db5_replace_attributes( dp, &avs, wdbp->dbip ) ) {
07900 Tcl_AppendResult(interp,
07901 "Error: failed to update attributes\n",
07902 (char *)NULL );
07903 bu_avs_free( &avs );
07904 return TCL_ERROR;
07905 }
07906
07907
07908 return TCL_OK;
07909 } else if( strcmp( argv[1], "append" ) == 0 ) {
07910 if( (argc-3)%2 ) {
07911 Tcl_AppendResult(interp,
07912 "Error: attribute names and values must be in pairs!!!\n",
07913 (char *)NULL );
07914 bu_avs_free( &avs );
07915 return TCL_ERROR;
07916 }
07917 i = 3;
07918 while( i < argc ) {
07919 const char *old_val;
07920
07921 old_val = bu_avs_get( &avs, argv[i] );
07922 if( !old_val ) {
07923 (void)bu_avs_add( &avs, argv[i], argv[i+1] );
07924 } else {
07925 struct bu_vls vls;
07926
07927 bu_vls_init( &vls );
07928 bu_vls_strcat( &vls, old_val );
07929 bu_vls_strcat( &vls, argv[i+1] );
07930 bu_avs_add_vls( &avs, argv[i], &vls );
07931 bu_vls_free( &vls );
07932 }
07933
07934 i += 2;
07935 }
07936 if( db5_replace_attributes( dp, &avs, wdbp->dbip ) ) {
07937 Tcl_AppendResult(interp,
07938 "Error: failed to update attributes\n",
07939 (char *)NULL );
07940 bu_avs_free( &avs );
07941 return TCL_ERROR;
07942 }
07943
07944
07945 return TCL_OK;
07946 } else if( strcmp( argv[1], "show" ) == 0 ) {
07947 struct bu_vls vls;
07948 int max_attr_name_len=0;
07949 int tabs1=0;
07950
07951
07952 bu_vls_init( &vls );
07953 if( dp->d_flags & DIR_COMB ) {
07954 if( dp->d_flags & DIR_REGION ) {
07955 bu_vls_printf( &vls, "%s region:\n", argv[2] );
07956 } else {
07957 bu_vls_printf( &vls, "%s combination:\n", argv[2] );
07958 }
07959 } else if( dp->d_flags & DIR_SOLID ) {
07960 bu_vls_printf( &vls, "%s %s:\n", argv[2],
07961 rt_functab[dp->d_minor_type].ft_label );
07962 } else {
07963 switch( dp->d_major_type ) {
07964 case DB5_MAJORTYPE_ATTRIBUTE_ONLY:
07965 bu_vls_printf( &vls, "%s global:\n", argv[2] );
07966 break;
07967 case DB5_MAJORTYPE_BINARY_EXPM:
07968 bu_vls_printf( &vls, "%s binary(expm):\n", argv[2] );
07969 break;
07970 case DB5_MAJORTYPE_BINARY_MIME:
07971 bu_vls_printf( &vls, "%s binary(mime):\n", argv[2] );
07972 break;
07973 case DB5_MAJORTYPE_BINARY_UNIF:
07974 bu_vls_printf( &vls, "%s %s:\n", argv[2],
07975 binu_types[dp->d_minor_type] );
07976 break;
07977 }
07978 }
07979 if( argc == 3 ) {
07980
07981 avpp = avs.avp;
07982 for( i=0 ; i < avs.count ; i++, avpp++ ) {
07983 int len;
07984
07985 len = strlen( avpp->name );
07986 if( len > max_attr_name_len ) {
07987 max_attr_name_len = len;
07988 }
07989 }
07990 tabs1 = 2 + max_attr_name_len/8;
07991 avpp = avs.avp;
07992 for( i=0 ; i < avs.count ; i++, avpp++ ) {
07993 const char *c;
07994 int tabs2;
07995 int k;
07996 int len;
07997
07998 bu_vls_printf( &vls, "\t%s", avpp->name );
07999 len = strlen( avpp->name );
08000 tabs2 = tabs1 - 1 - len/8;
08001 for( k=0 ; k<tabs2 ; k++ ) {
08002 bu_vls_putc( &vls, '\t' );
08003 }
08004 c = avpp->value;
08005 while( *c ) {
08006 bu_vls_putc( &vls, *c );
08007 if( *c == '\n' ) {
08008 for( k=0 ; k<tabs1 ; k++ ) {
08009 bu_vls_putc( &vls, '\t' );
08010 }
08011 }
08012 c++;
08013 }
08014 bu_vls_putc( &vls, '\n' );
08015 }
08016 } else {
08017 const char *val;
08018 int len;
08019
08020
08021 for( i=0 ; i<argc ; i++ ) {
08022 len = strlen( argv[i] );
08023 if( len > max_attr_name_len ) {
08024 max_attr_name_len = len;
08025 }
08026 }
08027 tabs1 = 2 + max_attr_name_len/8;
08028 for( i=3 ; i<argc ; i++ ) {
08029 int tabs2;
08030 int k;
08031 const char *c;
08032
08033 val = bu_avs_get( &avs, argv[i] );
08034 if( !val ) {
08035 Tcl_ResetResult( interp );
08036 Tcl_AppendResult(interp, "Object ",
08037 dp->d_namep, " does not have a ",
08038 argv[i], " attribute\n",
08039 (char *)NULL );
08040 bu_avs_free( &avs );
08041 return TCL_ERROR;
08042 }
08043 bu_vls_printf( &vls, "\t%s", argv[i] );
08044 len = strlen( val );
08045 tabs2 = tabs1 - 1 - len/8;
08046 for( k=0 ; k<tabs2 ; k++ ) {
08047 bu_vls_putc( &vls, '\t' );
08048 }
08049 c = val;
08050 while( *c ) {
08051 bu_vls_putc( &vls, *c );
08052 if( *c == '\n' ) {
08053 for( k=0 ; k<tabs1 ; k++ ) {
08054 bu_vls_putc( &vls, '\t' );
08055 }
08056 }
08057 c++;
08058 }
08059 bu_vls_putc( &vls, '\n' );
08060 }
08061 }
08062 Tcl_AppendResult(interp, bu_vls_addr( &vls ), (char *)NULL );
08063 bu_vls_free( &vls );
08064 return TCL_OK;
08065 } else {
08066 struct bu_vls vls;
08067
08068 Tcl_AppendResult(interp,
08069 "ERROR: unrecognized attr subcommand ",
08070 argv[1], "\n",
08071 (char *)NULL );
08072 bu_vls_init(&vls);
08073 bu_vls_printf(&vls, "helplib_alias wdb_attr %s", argv[0]);
08074 Tcl_Eval(interp, bu_vls_addr(&vls));
08075 bu_vls_free(&vls);
08076 return TCL_ERROR;
08077 }
08078
08079 }
08080
08081 int
08082 wdb_attr_tcl(ClientData clientData,
08083 Tcl_Interp *interp,
08084 int argc,
08085 char **argv)
08086 {
08087 struct rt_wdb *wdbp = (struct rt_wdb *)clientData;
08088
08089 return wdb_attr_cmd(wdbp, interp, argc-1, argv+1);
08090 }
08091
08092 int
08093 wdb_nmg_simplify_cmd(struct rt_wdb *wdbp,
08094 Tcl_Interp *interp,
08095 int argc,
08096 char **argv)
08097 {
08098 struct directory *dp;
08099 struct rt_db_internal nmg_intern;
08100 struct rt_db_internal new_intern;
08101 struct model *m;
08102 struct nmgregion *r;
08103 struct shell *s;
08104 int do_all=1;
08105 int do_arb=0;
08106 int do_tgc=0;
08107 int do_poly=0;
08108 char *new_name;
08109 char *nmg_name;
08110 int success = 0;
08111 int shell_count=0;
08112
08113 WDB_TCL_CHECK_READ_ONLY;
08114
08115 if (argc < 3 || 4 < argc) {
08116 struct bu_vls vls;
08117
08118 bu_vls_init(&vls);
08119 bu_vls_printf(&vls, "helplib_alias wdb_nmg_simplify %s", argv[0]);
08120 Tcl_Eval(interp, bu_vls_addr(&vls));
08121 bu_vls_free(&vls);
08122 return TCL_ERROR;
08123 }
08124
08125 RT_INIT_DB_INTERNAL(&new_intern);
08126
08127 if (argc == 4) {
08128 do_all = 0;
08129 if (!strncmp(argv[1], "arb", 3))
08130 do_arb = 1;
08131 else if (!strncmp(argv[1], "tgc", 3))
08132 do_tgc = 1;
08133 else if (!strncmp(argv[1], "poly", 4))
08134 do_poly = 1;
08135 else {
08136 struct bu_vls vls;
08137
08138 bu_vls_init(&vls);
08139 bu_vls_printf(&vls, "helplib_alias wdb_nmg_simplify %s", argv[0]);
08140 Tcl_Eval(interp, bu_vls_addr(&vls));
08141 bu_vls_free(&vls);
08142 return TCL_ERROR;
08143 }
08144
08145 new_name = argv[2];
08146 nmg_name = argv[3];
08147 } else {
08148 new_name = argv[1];
08149 nmg_name = argv[2];
08150 }
08151
08152 if (db_lookup(wdbp->dbip, new_name, LOOKUP_QUIET) != DIR_NULL) {
08153 Tcl_AppendResult(interp, new_name, " already exists\n", (char *)NULL);
08154 return TCL_ERROR;
08155 }
08156
08157 if ((dp=db_lookup(wdbp->dbip, nmg_name, LOOKUP_QUIET)) == DIR_NULL) {
08158 Tcl_AppendResult(interp, nmg_name, " does not exist\n", (char *)NULL);
08159 return TCL_ERROR;
08160 }
08161
08162 if (rt_db_get_internal(&nmg_intern, dp, wdbp->dbip, bn_mat_identity, &rt_uniresource) < 0) {
08163 Tcl_AppendResult(interp, "rt_db_get_internal() error\n", (char *)NULL);
08164 return TCL_ERROR;
08165 }
08166
08167 if (nmg_intern.idb_type != ID_NMG) {
08168 Tcl_AppendResult(interp, nmg_name, " is not an NMG solid\n", (char *)NULL);
08169 rt_db_free_internal(&nmg_intern, &rt_uniresource);
08170 return TCL_ERROR;
08171 }
08172
08173 m = (struct model *)nmg_intern.idb_ptr;
08174 NMG_CK_MODEL(m);
08175
08176
08177 for (BU_LIST_FOR(r, nmgregion, &m->r_hd)) {
08178 for (BU_LIST_FOR(s, shell, &r->s_hd))
08179 shell_count++;
08180 }
08181
08182 if ((do_arb || do_all) && shell_count == 1) {
08183 struct rt_arb_internal *arb_int;
08184
08185 BU_GETSTRUCT( arb_int, rt_arb_internal );
08186
08187 if (nmg_to_arb(m, arb_int)) {
08188 new_intern.idb_ptr = (genptr_t)(arb_int);
08189 new_intern.idb_major_type = DB5_MAJORTYPE_BRLCAD;
08190 new_intern.idb_type = ID_ARB8;
08191 new_intern.idb_meth = &rt_functab[ID_ARB8];
08192 success = 1;
08193 } else if (do_arb) {
08194
08195
08196 r = BU_LIST_FIRST( nmgregion, &m->r_hd );
08197 s = BU_LIST_FIRST( shell, &r->s_hd );
08198 nmg_shell_coplanar_face_merge( s, &wdbp->wdb_tol, 1 );
08199 if (!nmg_kill_cracks(s)) {
08200 (void) nmg_model_edge_fuse( m, &wdbp->wdb_tol );
08201 (void) nmg_model_edge_g_fuse( m, &wdbp->wdb_tol );
08202 (void) nmg_unbreak_region_edges( &r->l.magic );
08203 if (nmg_to_arb(m, arb_int)) {
08204 new_intern.idb_ptr = (genptr_t)(arb_int);
08205 new_intern.idb_major_type = DB5_MAJORTYPE_BRLCAD;
08206 new_intern.idb_type = ID_ARB8;
08207 new_intern.idb_meth = &rt_functab[ID_ARB8];
08208 success = 1;
08209 }
08210 }
08211 if (!success) {
08212 rt_db_free_internal( &nmg_intern, &rt_uniresource );
08213 Tcl_AppendResult(interp, "Failed to construct an ARB equivalent to ",
08214 nmg_name, "\n", (char *)NULL);
08215 return TCL_OK;
08216 }
08217 }
08218 }
08219
08220 if ((do_tgc || do_all) && !success && shell_count == 1) {
08221 struct rt_tgc_internal *tgc_int;
08222
08223 BU_GETSTRUCT( tgc_int, rt_tgc_internal );
08224
08225 if (nmg_to_tgc(m, tgc_int, &wdbp->wdb_tol)) {
08226 new_intern.idb_ptr = (genptr_t)(tgc_int);
08227 new_intern.idb_major_type = DB5_MAJORTYPE_BRLCAD;
08228 new_intern.idb_type = ID_TGC;
08229 new_intern.idb_meth = &rt_functab[ID_TGC];
08230 success = 1;
08231 } else if (do_tgc) {
08232 rt_db_free_internal( &nmg_intern, &rt_uniresource );
08233 Tcl_AppendResult(interp, "Failed to construct a TGC equivalent to ",
08234 nmg_name, "\n", (char *)NULL);
08235 return TCL_OK;
08236 }
08237 }
08238
08239
08240 if ((do_arb || do_all) && !success && shell_count == 1) {
08241 struct rt_arb_internal *arb_int;
08242
08243 BU_GETSTRUCT( arb_int, rt_arb_internal );
08244
08245 r = BU_LIST_FIRST( nmgregion, &m->r_hd );
08246 s = BU_LIST_FIRST( shell, &r->s_hd );
08247 nmg_shell_coplanar_face_merge( s, &wdbp->wdb_tol, 1 );
08248 if (!nmg_kill_cracks(s)) {
08249 (void) nmg_model_edge_fuse( m, &wdbp->wdb_tol );
08250 (void) nmg_model_edge_g_fuse( m, &wdbp->wdb_tol );
08251 (void) nmg_unbreak_region_edges( &r->l.magic );
08252 if (nmg_to_arb(m, arb_int )) {
08253 new_intern.idb_ptr = (genptr_t)(arb_int);
08254 new_intern.idb_major_type = DB5_MAJORTYPE_BRLCAD;
08255 new_intern.idb_type = ID_ARB8;
08256 new_intern.idb_meth = &rt_functab[ID_ARB8];
08257 success = 1;
08258 }
08259 else if (do_arb) {
08260 rt_db_free_internal( &nmg_intern, &rt_uniresource );
08261 Tcl_AppendResult(interp, "Failed to construct an ARB equivalent to ",
08262 nmg_name, "\n", (char *)NULL);
08263 return TCL_OK;
08264 }
08265 }
08266 }
08267
08268 if ((do_poly || do_all) && !success) {
08269 struct rt_pg_internal *poly_int;
08270
08271 poly_int = (struct rt_pg_internal *)bu_malloc( sizeof( struct rt_pg_internal ), "f_nmg_simplify: poly_int" );
08272
08273 if (nmg_to_poly( m, poly_int, &wdbp->wdb_tol)) {
08274 new_intern.idb_ptr = (genptr_t)(poly_int);
08275 new_intern.idb_major_type = DB5_MAJORTYPE_BRLCAD;
08276 new_intern.idb_type = ID_POLY;
08277 new_intern.idb_meth = &rt_functab[ID_POLY];
08278 success = 1;
08279 }
08280 else if (do_poly) {
08281 rt_db_free_internal( &nmg_intern, &rt_uniresource );
08282 Tcl_AppendResult(interp, nmg_name, " is not a closed surface, cannot make a polysolid\n", (char *)NULL);
08283 return TCL_OK;
08284 }
08285 }
08286
08287 if (success) {
08288 r = BU_LIST_FIRST( nmgregion, &m->r_hd );
08289 s = BU_LIST_FIRST( shell, &r->s_hd );
08290
08291 if (BU_LIST_NON_EMPTY( &s->lu_hd))
08292 Tcl_AppendResult(interp, "wire loops in ", nmg_name,
08293 " have been ignored in conversion\n", (char *)NULL);
08294
08295 if (BU_LIST_NON_EMPTY(&s->eu_hd))
08296 Tcl_AppendResult(interp, "wire edges in ", nmg_name,
08297 " have been ignored in conversion\n", (char *)NULL);
08298
08299 if (s->vu_p)
08300 Tcl_AppendResult(interp, "Single vertexuse in shell of ", nmg_name,
08301 " has been ignored in conversion\n", (char *)NULL);
08302
08303 rt_db_free_internal( &nmg_intern, &rt_uniresource );
08304
08305 if ((dp=db_diradd(wdbp->dbip, new_name, -1L, 0, DIR_SOLID, (genptr_t)&new_intern.idb_type)) == DIR_NULL) {
08306 Tcl_AppendResult(interp, "Cannot add ", new_name, " to directory\n", (char *)NULL );
08307 return TCL_ERROR;
08308 }
08309
08310 if (rt_db_put_internal(dp, wdbp->dbip, &new_intern, &rt_uniresource) < 0) {
08311 rt_db_free_internal( &new_intern, &rt_uniresource );
08312 WDB_TCL_WRITE_ERR_return;
08313 }
08314 return TCL_OK;
08315 }
08316
08317 Tcl_AppendResult(interp, "simplification to ", argv[1],
08318 " is not yet supported\n", (char *)NULL);
08319 return TCL_ERROR;
08320 }
08321
08322
08323
08324
08325
08326 static int
08327 wdb_nmg_simplify_tcl(ClientData clientData,
08328 Tcl_Interp *interp,
08329 int argc,
08330 char **argv)
08331 {
08332 struct rt_wdb *wdbp = (struct rt_wdb *)clientData;
08333
08334 return wdb_nmg_simplify_cmd(wdbp, interp, argc-1, argv+1);
08335 }
08336
08337 int
08338 wdb_nmg_collapse_cmd(struct rt_wdb *wdbp,
08339 Tcl_Interp *interp,
08340 int argc,
08341 char **argv)
08342 {
08343 char *new_name;
08344 struct model *m;
08345 struct rt_db_internal intern;
08346 struct directory *dp;
08347 long count;
08348 char count_str[32];
08349 fastf_t tol_coll;
08350 fastf_t min_angle;
08351
08352 WDB_TCL_CHECK_READ_ONLY;
08353
08354 if (argc < 4) {
08355 struct bu_vls vls;
08356
08357 bu_vls_init(&vls);
08358 bu_vls_printf(&vls, "helplib_alias wdb_nmg_collapse %s", argv[0]);
08359 Tcl_Eval(interp, bu_vls_addr(&vls));
08360 bu_vls_free(&vls);
08361 return TCL_ERROR;
08362 }
08363
08364 if (strchr(argv[2], '/')) {
08365 Tcl_AppendResult(interp, "Do not use '/' in solid names: ", argv[2], "\n", (char *)NULL);
08366 return TCL_ERROR;
08367 }
08368
08369 new_name = argv[2];
08370
08371 if (db_lookup(wdbp->dbip, new_name, LOOKUP_QUIET) != DIR_NULL) {
08372 Tcl_AppendResult(interp, new_name, " already exists\n", (char *)NULL);
08373 return TCL_ERROR;
08374 }
08375
08376 if ((dp=db_lookup(wdbp->dbip, argv[1], LOOKUP_NOISY)) == DIR_NULL)
08377 return TCL_ERROR;
08378
08379 if (dp->d_flags & DIR_COMB) {
08380 Tcl_AppendResult(interp, argv[1], " is a combination, only NMG primitives are allowed here\n", (char *)NULL );
08381 return TCL_ERROR;
08382 }
08383
08384 if (rt_db_get_internal(&intern, dp, wdbp->dbip, (matp_t)NULL, &rt_uniresource) < 0) {
08385 Tcl_AppendResult(interp, "Failed to get internal form of ", argv[1], "!!!!\n", (char *)NULL);
08386 return TCL_ERROR;
08387 }
08388
08389 if (intern.idb_type != ID_NMG) {
08390 Tcl_AppendResult(interp, argv[1], " is not an NMG solid!!!!\n", (char *)NULL);
08391 rt_db_free_internal(&intern, &rt_uniresource);
08392 return TCL_ERROR;
08393 }
08394
08395 tol_coll = atof(argv[3]) * wdbp->dbip->dbi_local2base;
08396 if (tol_coll <= 0.0) {
08397 Tcl_AppendResult(interp, "tolerance distance too small\n", (char *)NULL);
08398 return TCL_ERROR;
08399 }
08400
08401 if (argc == 5) {
08402 min_angle = atof(argv[4]);
08403 if (min_angle < 0.0) {
08404 Tcl_AppendResult(interp, "Minimum angle cannot be less than zero\n", (char *)NULL);
08405 return TCL_ERROR;
08406 }
08407 } else
08408 min_angle = 0.0;
08409
08410 m = (struct model *)intern.idb_ptr;
08411 NMG_CK_MODEL(m);
08412
08413
08414 nmg_triangulate_model(m, &wdbp->wdb_tol);
08415
08416 count = nmg_edge_collapse(m, &wdbp->wdb_tol, tol_coll, min_angle);
08417
08418 if ((dp=db_diradd(wdbp->dbip, new_name, -1L, 0, DIR_SOLID, (genptr_t)&intern.idb_type)) == DIR_NULL) {
08419 Tcl_AppendResult(interp, "Cannot add ", new_name, " to directory\n", (char *)NULL);
08420 rt_db_free_internal(&intern, &rt_uniresource);
08421 return TCL_ERROR;
08422 }
08423
08424 if (rt_db_put_internal(dp, wdbp->dbip, &intern, &rt_uniresource) < 0) {
08425 rt_db_free_internal(&intern, &rt_uniresource);
08426 WDB_TCL_WRITE_ERR_return;
08427 }
08428
08429 rt_db_free_internal(&intern, &rt_uniresource);
08430
08431 sprintf(count_str, "%ld", count);
08432 Tcl_AppendResult(interp, count_str, " edges collapsed\n", (char *)NULL);
08433
08434 return TCL_OK;
08435 }
08436
08437
08438
08439
08440
08441 static int
08442 wdb_nmg_collapse_tcl(ClientData clientData,
08443 Tcl_Interp *interp,
08444 int argc,
08445 char **argv)
08446 {
08447 struct rt_wdb *wdbp = (struct rt_wdb *)clientData;
08448
08449 return wdb_nmg_collapse_cmd(wdbp, interp, argc-1, argv+1);
08450 }
08451
08452 int
08453 wdb_summary_cmd(struct rt_wdb *wdbp,
08454 Tcl_Interp *interp,
08455 int argc,
08456 char **argv)
08457 {
08458 register char *cp;
08459 int flags = 0;
08460 int bad = 0;
08461
08462 if (argc < 1 || 2 < argc) {
08463 struct bu_vls vls;
08464
08465 bu_vls_init(&vls);
08466 bu_vls_printf(&vls, "helplib_alias wdb_summary %s", argv[0]);
08467 Tcl_Eval(interp, bu_vls_addr(&vls));
08468 bu_vls_free(&vls);
08469 return TCL_ERROR;
08470 }
08471
08472 if (argc <= 1) {
08473 wdb_dir_summary(wdbp->dbip, interp, 0);
08474 return TCL_OK;
08475 }
08476
08477 cp = argv[1];
08478 while (*cp) switch(*cp++) {
08479 case 'p':
08480 flags |= DIR_SOLID;
08481 break;
08482 case 'r':
08483 flags |= DIR_REGION;
08484 break;
08485 case 'g':
08486 flags |= DIR_COMB;
08487 break;
08488 default:
08489 Tcl_AppendResult(interp, "summary: P R or G are only valid parmaters\n",
08490 (char *)NULL);
08491 bad = 1;
08492 break;
08493 }
08494
08495 wdb_dir_summary(wdbp->dbip, interp, flags);
08496 return bad ? TCL_ERROR : TCL_OK;
08497 }
08498
08499
08500
08501
08502
08503 static int
08504 wdb_summary_tcl(ClientData clientData,
08505 Tcl_Interp *interp,
08506 int argc,
08507 char **argv)
08508 {
08509 struct rt_wdb *wdbp = (struct rt_wdb *)clientData;
08510
08511 return wdb_summary_cmd(wdbp, interp, argc-1, argv+1);
08512 }
08513
08514 int
08515 wdb_pathlist_cmd(struct rt_wdb *wdbp,
08516 Tcl_Interp *interp,
08517 int argc,
08518 char **argv)
08519 {
08520 if (argc < 2 || 3 < argc) {
08521 struct bu_vls vls;
08522
08523 bu_vls_init(&vls);
08524 bu_vls_printf(&vls, "helplib_alias wdb_pathlist %s", argv[0]);
08525 Tcl_Eval(interp, bu_vls_addr(&vls));
08526 bu_vls_free(&vls);
08527 return TCL_ERROR;
08528 }
08529
08530 pathListNoLeaf = 0;
08531
08532 if (argc == 3) {
08533 if (!strcmp(argv[1], "-noleaf"))
08534 pathListNoLeaf = 1;
08535
08536 ++argv;
08537 --argc;
08538 }
08539
08540 if (db_walk_tree(wdbp->dbip, argc-1, (const char **)argv+1, 1,
08541 &wdbp->wdb_initial_tree_state,
08542 0, 0, wdb_pathlist_leaf_func, (genptr_t)interp) < 0) {
08543 Tcl_AppendResult(interp, "wdb_pathlist: db_walk_tree() error", (char *)NULL);
08544 return TCL_ERROR;
08545 }
08546
08547 return TCL_OK;
08548 }
08549
08550
08551
08552
08553
08554 static int
08555 wdb_pathlist_tcl(ClientData clientData,
08556 Tcl_Interp *interp,
08557 int argc,
08558 char **argv)
08559 {
08560 struct rt_wdb *wdbp = (struct rt_wdb *)clientData;
08561
08562 return wdb_pathlist_cmd(wdbp, interp, argc-1, argv+1);
08563 }
08564
08565 int
08566 wdb_smooth_bot_cmd(struct rt_wdb *wdbp,
08567 Tcl_Interp *interp,
08568 int argc,
08569 char **argv)
08570 {
08571 char *new_bot_name, *old_bot_name;
08572 struct directory *dp_old, *dp_new;
08573 struct rt_bot_internal *old_bot;
08574 struct rt_db_internal intern;
08575 fastf_t tolerance_angle=180.0;
08576 int arg_index=1;
08577 int id;
08578
08579
08580 if( wdbp->dbip->dbi_version < 5 ) {
08581 Tcl_AppendResult(interp, "This is an older database version.\n",
08582 "It does not support BOT surface normals.\n",
08583 "Use \"dbupgrade\" to upgrade this database to the current version.\n",
08584 (char *)NULL );
08585 return TCL_ERROR;
08586 }
08587
08588 if( argc < 3 ) {
08589 struct bu_vls vls;
08590
08591 bu_vls_init(&vls);
08592 bu_vls_printf(&vls, "helplib_alias wdb_smooth_bot %s", argv[0]);
08593 Tcl_Eval(interp, bu_vls_addr(&vls));
08594 bu_vls_free(&vls);
08595 return TCL_ERROR;
08596 }
08597
08598 while( *argv[arg_index] == '-' ) {
08599
08600 if( !strcmp( argv[arg_index], "-t" ) ) {
08601 arg_index++;
08602 tolerance_angle = atof( argv[arg_index] );
08603 } else {
08604 struct bu_vls vls;
08605
08606 bu_vls_init(&vls);
08607 bu_vls_printf(&vls, "helplib_alias wdb_smooth_bot %s", argv[0]);
08608 Tcl_Eval(interp, bu_vls_addr(&vls));
08609 bu_vls_free(&vls);
08610 return TCL_ERROR;
08611 }
08612 arg_index++;
08613 }
08614
08615 if( arg_index >= argc ) {
08616 struct bu_vls vls;
08617
08618 bu_vls_init(&vls);
08619 bu_vls_printf(&vls, "helplib_alias wdb_smooth_bot %s", argv[0]);
08620 Tcl_Eval(interp, bu_vls_addr(&vls));
08621 bu_vls_free(&vls);
08622 return TCL_ERROR;
08623 }
08624
08625 new_bot_name = argv[arg_index++];
08626 old_bot_name = argv[arg_index];
08627
08628 if( (dp_old=db_lookup( wdbp->dbip, old_bot_name, LOOKUP_QUIET ) ) == DIR_NULL ) {
08629 Tcl_AppendResult(interp, old_bot_name, " does not exist!!\n", (char *)NULL );
08630 return TCL_ERROR;
08631 }
08632
08633 if( strcmp( old_bot_name, new_bot_name ) ) {
08634
08635 if( (dp_new=db_lookup( wdbp->dbip, new_bot_name, LOOKUP_QUIET ) ) != DIR_NULL ) {
08636 Tcl_AppendResult(interp, new_bot_name, " already exists!!\n", (char *)NULL );
08637 return TCL_ERROR;
08638 }
08639 } else {
08640 dp_new = dp_old;
08641 }
08642
08643 if( (id=rt_db_get_internal( &intern, dp_old, wdbp->dbip, NULL, wdbp->wdb_resp ) ) < 0 ) {
08644 Tcl_AppendResult(interp, "Failed to get internal form of ", old_bot_name, "\n", (char *)NULL );
08645 return TCL_ERROR;
08646 }
08647
08648 if( id != ID_BOT ) {
08649 Tcl_AppendResult(interp, old_bot_name, " is not a BOT primitive\n", (char *)NULL );
08650 rt_db_free_internal( &intern, wdbp->wdb_resp );
08651 return TCL_ERROR;
08652 }
08653
08654 old_bot = (struct rt_bot_internal *)intern.idb_ptr;
08655 RT_BOT_CK_MAGIC( old_bot );
08656
08657 if( rt_smooth_bot( old_bot, old_bot_name, wdbp->dbip, tolerance_angle*M_PI/180.0 ) ) {
08658 Tcl_AppendResult(interp, "Failed to smooth ", old_bot_name, "\n", (char *)NULL );
08659 rt_db_free_internal( &intern, wdbp->wdb_resp );
08660 return TCL_ERROR;
08661 }
08662
08663 if( dp_new == DIR_NULL ) {
08664 if( (dp_new=db_diradd( wdbp->dbip, new_bot_name, -1L, 0, DIR_SOLID,
08665 (genptr_t)&intern.idb_type)) == DIR_NULL ) {
08666 rt_db_free_internal(&intern, wdbp->wdb_resp);
08667 Tcl_AppendResult(interp, "Cannot add ", new_bot_name, " to directory\n", (char *)NULL);
08668 return TCL_ERROR;
08669 }
08670 }
08671
08672 if( rt_db_put_internal( dp_new, wdbp->dbip, &intern, wdbp->wdb_resp ) < 0 ) {
08673 rt_db_free_internal(&intern, wdbp->wdb_resp);
08674 Tcl_AppendResult(interp, "Database write error, aborting.\n", (char *)NULL);
08675 return TCL_ERROR;
08676 }
08677
08678 rt_db_free_internal( &intern, wdbp->wdb_resp );
08679
08680 return TCL_OK;
08681 }
08682
08683 static int
08684 wdb_smooth_bot_tcl(ClientData clientData,
08685 Tcl_Interp *interp,
08686 int argc,
08687 char **argv)
08688 {
08689 struct rt_wdb *wdbp = (struct rt_wdb *)clientData;
08690
08691 return wdb_smooth_bot_cmd(wdbp, interp, argc-1, argv+1);
08692 }
08693
08694 int
08695 wdb_binary_cmd(struct rt_wdb *wdbp,
08696 Tcl_Interp *interp,
08697 int argc,
08698 char **argv)
08699 {
08700 int c;
08701 struct bu_vls vls;
08702 unsigned int minor_type=0;
08703 char *obj_name;
08704 char *file_name;
08705 int input_mode=0;
08706 int output_mode=0;
08707 struct rt_binunif_internal *bip;
08708 struct rt_db_internal intern;
08709 struct directory *dp;
08710 char *cname;
08711
08712
08713 if( wdbp->dbip->dbi_version < 5 ) {
08714 Tcl_AppendResult(interp, "This is an older database version.\n",
08715 "It does not support binary objects.\n",
08716 "Use \"dbupgrade\" to upgrade this database to the current version.\n",
08717 (char *)NULL );
08718 return TCL_ERROR;
08719 }
08720
08721 bu_optind = 1;
08722 bu_opterr = 0;
08723 while ((c=bu_getopt(argc, argv, "iou:")) != EOF) {
08724 switch (c) {
08725 case 'i':
08726 input_mode = 1;
08727 break;
08728 case 'o':
08729 output_mode = 1;
08730 break;
08731 default:
08732 bu_vls_init( &vls );
08733 bu_vls_printf(&vls, "Unrecognized option - %c", c);
08734 Tcl_AppendResult(interp, bu_vls_addr(&vls), (char *)NULL);
08735 bu_vls_free(&vls);
08736 return TCL_ERROR;
08737
08738 }
08739 }
08740
08741 cname = argv[0];
08742
08743 if( input_mode + output_mode != 1 ) {
08744 bu_vls_init(&vls);
08745 bu_vls_printf(&vls, "helplib_alias wdb_binary %s", cname);
08746 Tcl_Eval(interp, bu_vls_addr(&vls));
08747 bu_vls_free(&vls);
08748 return TCL_ERROR;
08749 }
08750
08751 argc -= bu_optind;
08752 argv += bu_optind;
08753
08754 if ( (input_mode && argc != 4) || (output_mode && argc != 2) ) {
08755 bu_vls_init(&vls);
08756 bu_vls_printf(&vls, "helplib_alias wdb_binary %s", cname);
08757 Tcl_Eval(interp, bu_vls_addr(&vls));
08758 bu_vls_free(&vls);
08759 return TCL_ERROR;
08760 }
08761
08762
08763 if( input_mode ) {
08764 if (argv[0][0] == 'u') {
08765
08766 if (argv[1][1] != '\0') {
08767 bu_vls_init(&vls);
08768 bu_vls_printf(&vls, "Unrecognized minor type: %s", argv[1]);
08769 Tcl_AppendResult(interp, bu_vls_addr(&vls), (char *)NULL);
08770 bu_vls_free(&vls);
08771 return TCL_ERROR;
08772 }
08773
08774 switch ((int)argv[1][0]) {
08775 case 'f':
08776 minor_type = DB5_MINORTYPE_BINU_FLOAT;
08777 break;
08778 case 'd':
08779 minor_type = DB5_MINORTYPE_BINU_DOUBLE;
08780 break;
08781 case 'c':
08782 minor_type = DB5_MINORTYPE_BINU_8BITINT;
08783 break;
08784 case 's':
08785 minor_type = DB5_MINORTYPE_BINU_16BITINT;
08786 break;
08787 case 'i':
08788 minor_type = DB5_MINORTYPE_BINU_32BITINT;
08789 break;
08790 case 'l':
08791 minor_type = DB5_MINORTYPE_BINU_64BITINT;
08792 break;
08793 case 'C':
08794 minor_type = DB5_MINORTYPE_BINU_8BITINT_U;
08795 break;
08796 case 'S':
08797 minor_type = DB5_MINORTYPE_BINU_16BITINT_U;
08798 break;
08799 case 'I':
08800 minor_type = DB5_MINORTYPE_BINU_32BITINT_U;
08801 break;
08802 case 'L':
08803 minor_type = DB5_MINORTYPE_BINU_64BITINT_U;
08804 break;
08805 default:
08806 bu_vls_init(&vls);
08807 bu_vls_printf(&vls, "Unrecognized minor type: %s", argv[1]);
08808 Tcl_AppendResult(interp, bu_vls_addr(&vls), (char *)NULL);
08809 bu_vls_free(&vls);
08810 return TCL_ERROR;
08811 }
08812 } else {
08813 bu_vls_init(&vls);
08814 bu_vls_printf(&vls, "Unrecognized major type: %s", argv[0]);
08815 Tcl_AppendResult(interp, bu_vls_addr(&vls), (char *)NULL);
08816 bu_vls_free(&vls);
08817 return TCL_ERROR;
08818 }
08819
08820
08821 argc -= 2;
08822 argv += 2;
08823
08824 if( minor_type == 0 ) {
08825 bu_vls_init(&vls);
08826 bu_vls_printf(&vls, "helplib_alias wdb_binary %s", cname);
08827 Tcl_Eval(interp, bu_vls_addr(&vls));
08828 bu_vls_free(&vls);
08829 return TCL_ERROR;
08830 }
08831
08832 obj_name = *argv;
08833 if( db_lookup( wdbp->dbip, obj_name, LOOKUP_QUIET ) != DIR_NULL ) {
08834 bu_vls_init( &vls );
08835 bu_vls_printf( &vls, "Object %s already exists", obj_name );
08836 Tcl_AppendResult(interp, bu_vls_addr(&vls), (char *)NULL);
08837 bu_vls_free( &vls );
08838 return TCL_ERROR;
08839 }
08840
08841 argc--;
08842 argv++;
08843
08844 file_name = *argv;
08845
08846
08847 if( rt_mk_binunif( wdbp, obj_name, file_name, minor_type, -1 ) ) {
08848 Tcl_AppendResult(interp, "Error creating ", obj_name,
08849 (char *)NULL );
08850 return TCL_ERROR;
08851 }
08852
08853 return TCL_OK;
08854
08855 } else if( output_mode ) {
08856 FILE *fd;
08857
08858 file_name = *argv;
08859
08860 argc--;
08861 argv++;
08862
08863 obj_name = *argv;
08864
08865 if( (dp=db_lookup(wdbp->dbip, obj_name, LOOKUP_NOISY )) == DIR_NULL ) {
08866 return TCL_ERROR;
08867 }
08868 if( !( dp->d_major_type & DB5_MAJORTYPE_BINARY_MASK) ) {
08869 Tcl_AppendResult(interp, obj_name, " is not a binary object", (char *)NULL );
08870 return TCL_ERROR;
08871 }
08872
08873 if( dp->d_major_type != DB5_MAJORTYPE_BINARY_UNIF ) {
08874 Tcl_AppendResult(interp, "source must be a uniform binary object",
08875 (char *)NULL );
08876 return TCL_ERROR;
08877 }
08878
08879 #if defined(_WIN32) && !defined(__CYGWIN__)
08880 if( (fd=fopen( file_name, "w+b")) == NULL ) {
08881 #else
08882 if( (fd=fopen( file_name, "w+")) == NULL ) {
08883 #endif
08884 Tcl_AppendResult(interp, "Error: cannot open file ", file_name,
08885 " for writing", (char *)NULL );
08886 return TCL_ERROR;
08887 }
08888
08889 if( rt_db_get_internal( &intern, dp, wdbp->dbip, NULL,
08890 &rt_uniresource ) < 0 ) {
08891 Tcl_AppendResult(interp, "Error reading ", dp->d_namep,
08892 " from database", (char *)NULL );
08893 fclose( fd );
08894 return TCL_ERROR;
08895 }
08896
08897 RT_CK_DB_INTERNAL( &intern );
08898
08899 bip = (struct rt_binunif_internal *)intern.idb_ptr;
08900 if( bip->count < 1 ) {
08901 Tcl_AppendResult(interp, obj_name, " has no contents", (char *)NULL );
08902 fclose( fd );
08903 rt_db_free_internal( &intern, &rt_uniresource );
08904 return TCL_ERROR;
08905 }
08906
08907 if( fwrite( bip->u.int8, bip->count * db5_type_sizeof_h_binu( bip->type ),
08908 1, fd) != 1 ) {
08909 Tcl_AppendResult(interp, "Error writing contents to file",
08910 (char *)NULL );
08911 fclose( fd );
08912 rt_db_free_internal( &intern, &rt_uniresource );
08913 return TCL_ERROR;
08914 }
08915
08916 fclose( fd );
08917 rt_db_free_internal( &intern, &rt_uniresource );
08918 return TCL_OK;
08919 } else {
08920 bu_vls_init(&vls);
08921 bu_vls_printf(&vls, "helplib_alias wdb_binary %s", cname);
08922 Tcl_Eval(interp, bu_vls_addr(&vls));
08923 bu_vls_free(&vls);
08924 return TCL_ERROR;
08925 }
08926
08927
08928
08929 }
08930
08931
08932
08933
08934
08935 static int
08936 wdb_binary_tcl(ClientData clientData,
08937 Tcl_Interp *interp,
08938 int argc,
08939 char **argv)
08940 {
08941 struct rt_wdb *wdbp = (struct rt_wdb *)clientData;
08942
08943 return wdb_binary_cmd(wdbp, interp, argc-1, argv+1);
08944 }
08945
08946 int wdb_bot_face_sort_cmd(struct rt_wdb *wdbp,
08947 Tcl_Interp *interp,
08948 int argc,
08949 char **argv)
08950 {
08951 int i;
08952 int tris_per_piece=0;
08953 struct bu_vls vls;
08954 int warnings=0;
08955
08956 if( argc < 3 ) {
08957 bu_vls_init(&vls);
08958 bu_vls_printf(&vls, "helplib_alias wdb_bot_face_sort %s", argv[0]);
08959 Tcl_Eval(interp, bu_vls_addr(&vls));
08960 bu_vls_free(&vls);
08961 return TCL_ERROR;
08962 }
08963
08964 tris_per_piece = atoi( argv[1] );
08965 if( tris_per_piece < 1 ) {
08966 Tcl_AppendResult(interp, "Illegal value for triangle per piece (",
08967 argv[1],
08968 ")\n",
08969 (char *)NULL );
08970 bu_vls_init(&vls);
08971 bu_vls_printf(&vls, "helplib_alias wdb_bot_face_sort %s", argv[0]);
08972 Tcl_Eval(interp, bu_vls_addr(&vls));
08973 bu_vls_free(&vls);
08974 return TCL_ERROR;
08975 }
08976
08977 bu_vls_init( &vls );
08978 for( i=2 ; i<argc ; i++ ) {
08979 struct directory *dp;
08980 struct rt_db_internal intern;
08981 struct rt_bot_internal *bot;
08982 int id;
08983
08984 if( (dp=db_lookup( wdbp->dbip, argv[i], LOOKUP_NOISY ) ) == DIR_NULL ) {
08985 continue;
08986 }
08987
08988 if( (id=rt_db_get_internal( &intern, dp, wdbp->dbip, bn_mat_identity, wdbp->wdb_resp )) < 0 ) {
08989 bu_vls_printf( &vls,
08990 "Failed to get internal form of %s, not sorting this one\n",
08991 dp->d_namep );
08992 warnings++;
08993 continue;
08994 }
08995
08996 if( id != ID_BOT ) {
08997 rt_db_free_internal( &intern, wdbp->wdb_resp );
08998 bu_vls_printf( &vls,
08999 "%s is not a BOT primitive, skipped\n",
09000 dp->d_namep );
09001 warnings++;
09002 continue;
09003 }
09004
09005 bot = (struct rt_bot_internal *)intern.idb_ptr;
09006 RT_BOT_CK_MAGIC( bot );
09007
09008 bu_log( "processing %s (%d triangles)\n", dp->d_namep, bot->num_faces );
09009 while( Tcl_DoOneEvent( TCL_DONT_WAIT | TCL_FILE_EVENTS ) );
09010 if( rt_bot_sort_faces( bot, tris_per_piece ) ) {
09011 rt_db_free_internal( &intern, wdbp->wdb_resp );
09012 bu_vls_printf( &vls,
09013 "Face sort failed for %s, this BOT not sorted\n",
09014 dp->d_namep );
09015 warnings++;
09016 continue;
09017 }
09018
09019 if( rt_db_put_internal( dp, wdbp->dbip, &intern, wdbp->wdb_resp ) ) {
09020 if( warnings ) {
09021 Tcl_AppendResult(interp, bu_vls_addr( &vls ),
09022 (char *)NULL );
09023 }
09024 Tcl_AppendResult(interp, "Failed to write sorted BOT (",
09025 dp->d_namep,
09026 ") to database!!! (This is very bad)\n" );
09027 rt_db_free_internal( &intern, wdbp->wdb_resp );
09028 bu_vls_free( &vls );
09029 return( TCL_ERROR );
09030 }
09031 }
09032
09033 if( warnings ) {
09034 Tcl_AppendResult(interp, bu_vls_addr( &vls ), (char *)NULL );
09035 }
09036 bu_vls_free( &vls );
09037 return( TCL_OK );
09038 }
09039
09040
09041
09042
09043
09044 static int
09045 wdb_bot_face_sort_tcl(ClientData clientData,
09046 Tcl_Interp *interp,
09047 int argc,
09048 char **argv)
09049 {
09050 struct rt_wdb *wdbp = (struct rt_wdb *)clientData;
09051
09052 return wdb_bot_face_sort_cmd(wdbp, interp, argc-1, argv+1);
09053 }
09054
09055
09056
09057
09058
09059
09060 static int
09061 wdb_importFg4Section_tcl(ClientData clientData,
09062 Tcl_Interp *interp,
09063 int argc,
09064 char **argv)
09065 {
09066 struct rt_wdb *wdbp = (struct rt_wdb *)clientData;
09067
09068 return wdb_importFg4Section_cmd(wdbp, interp, argc-1, argv+1);
09069 }
09070
09071 #if 0
09072
09073 int
09074 wdb__cmd(struct rt_wdb *wdbp,
09075 Tcl_Interp *interp,
09076 int argc,
09077 char **argv)
09078 {
09079 }
09080
09081
09082
09083
09084
09085 static int
09086 wdb__tcl(ClientData clientData,
09087 Tcl_Interp *interp,
09088 int argc,
09089 char **argv)
09090 {
09091 struct rt_wdb *wdbp = (struct rt_wdb *)clientData;
09092
09093 return wdb__cmd(wdbp, interp, argc-1, argv+1);
09094 }
09095 #endif
09096
09097
09098
09099
09100
09101
09102
09103
09104
09105
09106 int
09107 wdb_cmpdirname(const genptr_t a,
09108 const genptr_t b)
09109 {
09110 register struct directory **dp1, **dp2;
09111
09112 dp1 = (struct directory **)a;
09113 dp2 = (struct directory **)b;
09114 return( strcmp( (*dp1)->d_namep, (*dp2)->d_namep));
09115 }
09116
09117 #define RT_TERMINAL_WIDTH 80
09118 #define RT_COLUMNS ((RT_TERMINAL_WIDTH + V4_MAXNAME - 1) / V4_MAXNAME)
09119
09120
09121
09122
09123 void
09124 wdb_vls_col_item(struct bu_vls *str,
09125 register char *cp,
09126 int *ccp,
09127 int *clp)
09128 {
09129
09130 if (*ccp >= RT_COLUMNS || (*clp+V4_MAXNAME-1) >= RT_TERMINAL_WIDTH) {
09131
09132 bu_vls_putc(str, '\n');
09133 *ccp = 0;
09134 } else if (*ccp != 0) {
09135
09136 do {
09137 bu_vls_putc(str, ' ');
09138 ++*clp;
09139 } while ((*clp % V4_MAXNAME) != 0);
09140 }
09141
09142 *clp = 0;
09143 while (*cp != '\0') {
09144 bu_vls_putc(str, *cp);
09145 ++cp;
09146 ++*clp;
09147 }
09148 ++*ccp;
09149 }
09150
09151
09152
09153 void
09154 wdb_vls_col_eol(struct bu_vls *str,
09155 int *ccp,
09156 int *clp)
09157 {
09158 if (*ccp != 0)
09159 bu_vls_putc(str, '\n');
09160 *ccp = 0;
09161 *clp = 0;
09162 }
09163
09164
09165
09166
09167
09168
09169
09170
09171 void
09172 wdb_vls_col_pr4v(struct bu_vls *vls,
09173 struct directory **list_of_names,
09174 int num_in_list,
09175 int no_decorate)
09176 {
09177 #if 0
09178 int lines, i, j, namelen, this_one;
09179
09180 qsort((genptr_t)list_of_names,
09181 (unsigned)num_in_list, (unsigned)sizeof(struct directory *),
09182 (int (*)())wdb_cmpdirname);
09183
09184
09185
09186
09187
09188 lines = (num_in_list + 3) / 4;
09189 for (i=0; i < lines; i++) {
09190 for (j=0; j < 4; j++) {
09191 this_one = j * lines + i;
09192
09193 bu_vls_printf(vls, "%.16s", list_of_names[this_one]->d_namep);
09194 namelen = strlen(list_of_names[this_one]->d_namep);
09195 if (namelen > 16)
09196 namelen = 16;
09197
09198
09199
09200
09201
09202
09203
09204 if (list_of_names[this_one]->d_flags & DIR_COMB) {
09205 bu_vls_putc(vls, '/');
09206 namelen++;
09207 }
09208 if (list_of_names[this_one]->d_flags & DIR_REGION) {
09209 bu_vls_putc(vls, 'R');
09210 namelen++;
09211 }
09212
09213
09214
09215
09216
09217 if (this_one + lines >= num_in_list) {
09218 bu_vls_putc(vls, '\n');
09219 break;
09220 } else {
09221
09222
09223
09224
09225 while (namelen++ < 20)
09226 bu_vls_putc(vls, ' ');
09227 }
09228 }
09229 }
09230 #else
09231 int lines, i, j, k, namelen, this_one;
09232 int maxnamelen;
09233 int cwidth;
09234 int numcol;
09235
09236 qsort((genptr_t)list_of_names,
09237 (unsigned)num_in_list, (unsigned)sizeof(struct directory *),
09238 (int (*)())wdb_cmpdirname);
09239
09240
09241
09242
09243
09244
09245
09246 maxnamelen = 0;
09247 for (k=0; k < num_in_list; k++) {
09248 namelen = strlen(list_of_names[k]->d_namep);
09249 if (namelen > maxnamelen)
09250 maxnamelen = namelen;
09251 }
09252
09253 if (maxnamelen <= 16)
09254 maxnamelen = 16;
09255 cwidth = maxnamelen + 4;
09256
09257 if (cwidth > 80)
09258 cwidth = 80;
09259 numcol = RT_TERMINAL_WIDTH / cwidth;
09260
09261
09262
09263
09264
09265 lines = (num_in_list + (numcol - 1)) / numcol;
09266 for (i=0; i < lines; i++) {
09267 for (j=0; j < numcol; j++) {
09268 this_one = j * lines + i;
09269 bu_vls_printf(vls, "%s", list_of_names[this_one]->d_namep);
09270 namelen = strlen( list_of_names[this_one]->d_namep);
09271
09272
09273
09274
09275
09276
09277
09278
09279 if ( !no_decorate && list_of_names[this_one]->d_flags & DIR_COMB) {
09280 bu_vls_putc(vls, '/');
09281 namelen++;
09282 }
09283
09284 if ( !no_decorate && list_of_names[this_one]->d_flags & DIR_REGION) {
09285 bu_vls_putc(vls, 'R');
09286 namelen++;
09287 }
09288
09289
09290
09291
09292
09293
09294 if (this_one + lines >= num_in_list) {
09295 bu_vls_putc(vls, '\n');
09296 break;
09297 } else {
09298
09299
09300
09301
09302 while( namelen++ < cwidth)
09303 bu_vls_putc(vls, ' ');
09304 }
09305 }
09306 }
09307 #endif
09308 }
09309
09310 void
09311 wdb_vls_long_dpp(struct bu_vls *vls,
09312 struct directory **list_of_names,
09313 int num_in_list,
09314 int aflag,
09315 int cflag,
09316 int rflag,
09317 int sflag)
09318 {
09319 int i;
09320 int isComb=0, isRegion=0;
09321 int isSolid=0;
09322 const char *type=NULL;
09323 int max_nam_len = 0;
09324 int max_type_len = 0;
09325 struct directory *dp;
09326
09327 qsort((genptr_t)list_of_names,
09328 (unsigned)num_in_list, (unsigned)sizeof(struct directory *),
09329 (int (*)())wdb_cmpdirname);
09330
09331 for (i=0 ; i < num_in_list ; i++) {
09332 int len;
09333
09334 dp = list_of_names[i];
09335 len = strlen(dp->d_namep);
09336 if (len > max_nam_len)
09337 max_nam_len = len;
09338
09339 if (dp->d_flags & DIR_REGION)
09340 len = 6;
09341 else if (dp->d_flags & DIR_COMB)
09342 len = 4;
09343 else if( dp->d_flags & DIR_SOLID )
09344 len = strlen(rt_functab[dp->d_minor_type].ft_label);
09345 else {
09346 switch(list_of_names[i]->d_major_type) {
09347 case DB5_MAJORTYPE_ATTRIBUTE_ONLY:
09348 len = 6;
09349 break;
09350 case DB5_MAJORTYPE_BINARY_MIME:
09351 len = strlen( "binary (mime)" );
09352 break;
09353 case DB5_MAJORTYPE_BINARY_UNIF:
09354 len = strlen( binu_types[list_of_names[i]->d_minor_type] );
09355 break;
09356 case DB5_MAJORTYPE_BINARY_EXPM:
09357 len = strlen( "binary(expm)" );
09358 break;
09359 }
09360 }
09361
09362 if (len > max_type_len)
09363 max_type_len = len;
09364 }
09365
09366
09367
09368
09369 for (i=0; i < num_in_list; ++i) {
09370 if (list_of_names[i]->d_flags & DIR_COMB) {
09371 isComb = 1;
09372 isSolid = 0;
09373 type = "comb";
09374
09375 if (list_of_names[i]->d_flags & DIR_REGION) {
09376 isRegion = 1;
09377 type = "region";
09378 } else
09379 isRegion = 0;
09380 } else if( list_of_names[i]->d_flags & DIR_SOLID ) {
09381 isComb = isRegion = 0;
09382 isSolid = 1;
09383 type = rt_functab[list_of_names[i]->d_minor_type].ft_label;
09384 } else {
09385 switch(list_of_names[i]->d_major_type) {
09386 case DB5_MAJORTYPE_ATTRIBUTE_ONLY:
09387 isSolid = 0;
09388 type = "global";
09389 break;
09390 case DB5_MAJORTYPE_BINARY_EXPM:
09391 isSolid = 0;
09392 isRegion = 0;
09393 type = "binary(expm)";
09394 break;
09395 case DB5_MAJORTYPE_BINARY_MIME:
09396 isSolid = 0;
09397 isRegion = 0;
09398 type = "binary(mime)";
09399 break;
09400 case DB5_MAJORTYPE_BINARY_UNIF:
09401 isSolid = 0;
09402 isRegion = 0;
09403 type = binu_types[list_of_names[i]->d_minor_type];
09404 break;
09405 }
09406 }
09407
09408
09409 dp = list_of_names[i];
09410 if (aflag ||
09411 (!cflag && !rflag && !sflag) ||
09412 (cflag && isComb) ||
09413 (rflag && isRegion) ||
09414 (sflag && isSolid)) {
09415 bu_vls_printf(vls, "%s", dp->d_namep );
09416 bu_vls_spaces(vls, max_nam_len - strlen( dp->d_namep ) );
09417 bu_vls_printf(vls, " %s", type );
09418 bu_vls_spaces(vls, max_type_len - strlen( type ) );
09419 bu_vls_printf(vls, " %2d %2d %ld\n",
09420 dp->d_major_type, dp->d_minor_type, (long)(dp->d_len));
09421 }
09422 }
09423 }
09424
09425
09426
09427
09428
09429
09430
09431
09432 void
09433 wdb_vls_line_dpp(struct bu_vls *vls,
09434 struct directory **list_of_names,
09435 int num_in_list,
09436 int aflag,
09437 int cflag,
09438 int rflag,
09439 int sflag)
09440 {
09441 int i;
09442 int isComb, isRegion;
09443 int isSolid;
09444
09445 qsort( (genptr_t)list_of_names,
09446 (unsigned)num_in_list, (unsigned)sizeof(struct directory *),
09447 (int (*)())wdb_cmpdirname);
09448
09449
09450
09451
09452 for (i=0; i < num_in_list; ++i) {
09453 if (list_of_names[i]->d_flags & DIR_COMB) {
09454 isComb = 1;
09455 isSolid = 0;
09456
09457 if (list_of_names[i]->d_flags & DIR_REGION)
09458 isRegion = 1;
09459 else
09460 isRegion = 0;
09461 } else {
09462 isComb = isRegion = 0;
09463 isSolid = 1;
09464 }
09465
09466
09467 if (aflag ||
09468 (!cflag && !rflag && !sflag) ||
09469 (cflag && isComb) ||
09470 (rflag && isRegion) ||
09471 (sflag && isSolid)) {
09472 bu_vls_printf(vls, "%s ", list_of_names[i]->d_namep);
09473 }
09474 }
09475 }
09476
09477
09478
09479
09480
09481
09482
09483
09484
09485
09486 struct directory **
09487 wdb_getspace(struct db_i *dbip,
09488 register int num_entries)
09489 {
09490 register struct directory **dir_basep;
09491
09492 if (num_entries < 0) {
09493 bu_log("wdb_getspace: was passed %d, used 0\n",
09494 num_entries);
09495 num_entries = 0;
09496 }
09497
09498 if (num_entries == 0) num_entries = db_get_directory_size(dbip);
09499
09500
09501 dir_basep = (struct directory **) bu_malloc((num_entries+1) * sizeof(struct directory *),
09502 "wdb_getspace *dir[]" );
09503 return(dir_basep);
09504 }
09505
09506
09507
09508
09509 void
09510 wdb_do_list(struct db_i *dbip,
09511 Tcl_Interp *interp,
09512 struct bu_vls *outstrp,
09513 register struct directory *dp,
09514 int verbose)
09515 {
09516 int id;
09517 struct rt_db_internal intern;
09518
09519 RT_CK_DBI(dbip);
09520
09521 if( dp->d_major_type == DB5_MAJORTYPE_ATTRIBUTE_ONLY ) {
09522
09523 struct bu_attribute_value_set avs;
09524 struct bu_attribute_value_pair *avp;
09525
09526 bu_vls_strcat( outstrp, dp->d_namep );
09527 bu_vls_strcat( outstrp, ": global attributes object\n" );
09528 bu_avs_init_empty(&avs);
09529 if( db5_get_attributes( dbip, &avs, dp ) ) {
09530 Tcl_AppendResult(interp, "Cannot get attributes for ", dp->d_namep,
09531 "\n", (char *)NULL );
09532 return;
09533 }
09534 for( BU_AVS_FOR( avp, &avs ) ) {
09535 if( !strcmp( avp->name, "units" ) ) {
09536 double conv;
09537 const char *str;
09538
09539 conv = atof( avp->value );
09540 bu_vls_strcat( outstrp, "\tunits: " );
09541 if( (str=bu_units_string( conv ) ) == NULL ) {
09542 bu_vls_strcat( outstrp, "Unrecognized units\n" );
09543 } else {
09544 bu_vls_strcat( outstrp, str );
09545 bu_vls_putc( outstrp, '\n' );
09546 }
09547 } else {
09548 bu_vls_putc( outstrp, '\t' );
09549 bu_vls_strcat( outstrp, avp->name );
09550 bu_vls_strcat( outstrp, ": " );
09551 bu_vls_strcat( outstrp, avp->value );
09552 bu_vls_putc( outstrp, '\n' );
09553 }
09554 }
09555 } else {
09556
09557 if ((id = rt_db_get_internal(&intern, dp, dbip,
09558 (fastf_t *)NULL, &rt_uniresource)) < 0) {
09559 Tcl_AppendResult(interp, "rt_db_get_internal(", dp->d_namep,
09560 ") failure\n", (char *)NULL);
09561 return;
09562 }
09563
09564 bu_vls_printf(outstrp, "%s: ", dp->d_namep);
09565
09566 if (rt_functab[id].ft_describe(outstrp, &intern,
09567 verbose, dbip->dbi_base2local, &rt_uniresource, dbip) < 0)
09568 Tcl_AppendResult(interp, dp->d_namep, ": describe error\n", (char *)NULL);
09569 rt_db_free_internal(&intern, &rt_uniresource);
09570 }
09571 }
09572
09573
09574
09575
09576
09577
09578
09579
09580
09581
09582 struct directory *
09583 wdb_combadd(Tcl_Interp *interp,
09584 struct db_i *dbip,
09585 register struct directory *objp,
09586 char *combname,
09587 int region_flag,
09588 int relation,
09589 int ident,
09590 int air,
09591 struct rt_wdb *wdbp)
09592 {
09593 register struct directory *dp;
09594 struct rt_db_internal intern;
09595 struct rt_comb_internal *comb;
09596 union tree *tp;
09597 struct rt_tree_array *tree_list;
09598 int node_count;
09599 int actual_count;
09600
09601
09602
09603
09604 if ((dp = db_lookup(dbip, combname, LOOKUP_QUIET)) == DIR_NULL) {
09605 int flags;
09606
09607 if (region_flag)
09608 flags = DIR_REGION | DIR_COMB;
09609 else
09610 flags = DIR_COMB;
09611
09612 RT_INIT_DB_INTERNAL(&intern);
09613 intern.idb_major_type = DB5_MAJORTYPE_BRLCAD;
09614 intern.idb_type = ID_COMBINATION;
09615 intern.idb_meth = &rt_functab[ID_COMBINATION];
09616
09617
09618 if ((dp = db_diradd(dbip, combname, -1, 0, flags, (genptr_t)&intern.idb_type)) == DIR_NULL) {
09619 Tcl_AppendResult(interp, "An error has occured while adding '",
09620 combname, "' to the database.\n", (char *)NULL);
09621 return DIR_NULL;
09622 }
09623
09624 BU_GETSTRUCT(comb, rt_comb_internal);
09625 intern.idb_ptr = (genptr_t)comb;
09626 comb->magic = RT_COMB_MAGIC;
09627 bu_vls_init(&comb->shader);
09628 bu_vls_init(&comb->material);
09629 comb->region_id = 0;
09630 comb->tree = TREE_NULL;
09631
09632 if (region_flag) {
09633 struct bu_vls tmp_vls;
09634
09635 comb->region_flag = 1;
09636 comb->region_id = ident;
09637 comb->aircode = air;
09638 comb->los = wdbp->wdb_los_default;
09639 comb->GIFTmater = wdbp->wdb_mat_default;
09640 bu_vls_init(&tmp_vls);
09641 bu_vls_printf(&tmp_vls,
09642 "Creating region id=%d, air=%d, GIFTmaterial=%d, los=%d\n",
09643 ident, air,
09644 wdbp->wdb_mat_default,
09645 wdbp->wdb_los_default);
09646 Tcl_AppendResult(interp, bu_vls_addr(&tmp_vls), (char *)NULL);
09647 bu_vls_free(&tmp_vls);
09648 } else {
09649 comb->region_flag = 0;
09650 }
09651 RT_GET_TREE( tp, &rt_uniresource );
09652 tp->magic = RT_TREE_MAGIC;
09653 tp->tr_l.tl_op = OP_DB_LEAF;
09654 tp->tr_l.tl_name = bu_strdup( objp->d_namep );
09655 tp->tr_l.tl_mat = (matp_t)NULL;
09656 comb->tree = tp;
09657
09658 if (rt_db_put_internal(dp, dbip, &intern, &rt_uniresource) < 0) {
09659 Tcl_AppendResult(interp, "Failed to write ", dp->d_namep, (char *)NULL );
09660 return DIR_NULL;
09661 }
09662 return dp;
09663 } else if (!(dp->d_flags & DIR_COMB)) {
09664 Tcl_AppendResult(interp, combname, " exists, but is not a combination\n", (char *)NULL);
09665 return DIR_NULL;
09666 }
09667
09668
09669 if (rt_db_get_internal(&intern, dp, dbip, (fastf_t *)NULL, &rt_uniresource) < 0) {
09670 Tcl_AppendResult(interp, "read error, aborting\n", (char *)NULL);
09671 return DIR_NULL;
09672 }
09673
09674 comb = (struct rt_comb_internal *)intern.idb_ptr;
09675 RT_CK_COMB(comb);
09676
09677 if (region_flag && !comb->region_flag) {
09678 Tcl_AppendResult(interp, combname, ": not a region\n", (char *)NULL);
09679 return DIR_NULL;
09680 }
09681
09682 if (comb->tree && db_ck_v4gift_tree(comb->tree) < 0) {
09683 db_non_union_push(comb->tree, &rt_uniresource);
09684 if (db_ck_v4gift_tree(comb->tree) < 0) {
09685 Tcl_AppendResult(interp, "Cannot flatten tree for editing\n", (char *)NULL);
09686 rt_db_free_internal(&intern, &rt_uniresource);
09687 return DIR_NULL;
09688 }
09689 }
09690
09691
09692 node_count = db_tree_nleaves( comb->tree ) + 1;
09693 tree_list = (struct rt_tree_array *)bu_calloc( node_count,
09694 sizeof( struct rt_tree_array ), "tree list" );
09695
09696
09697 if (comb->tree) {
09698 actual_count = 1 + (struct rt_tree_array *)db_flatten_tree(
09699 tree_list, comb->tree, OP_UNION, 1, &rt_uniresource )
09700 - tree_list;
09701 BU_ASSERT_LONG( actual_count, ==, node_count );
09702 comb->tree = TREE_NULL;
09703 }
09704
09705
09706 switch (relation) {
09707 case '+':
09708 tree_list[node_count - 1].tl_op = OP_INTERSECT;
09709 break;
09710 case '-':
09711 tree_list[node_count - 1].tl_op = OP_SUBTRACT;
09712 break;
09713 default:
09714 Tcl_AppendResult(interp, "unrecognized relation (assume UNION)\n",
09715 (char *)NULL );
09716 case 'u':
09717 tree_list[node_count - 1].tl_op = OP_UNION;
09718 break;
09719 }
09720
09721
09722 RT_GET_TREE( tp, &rt_uniresource );
09723 tree_list[node_count-1].tl_tree = tp;
09724 tp->tr_l.magic = RT_TREE_MAGIC;
09725 tp->tr_l.tl_op = OP_DB_LEAF;
09726 tp->tr_l.tl_name = bu_strdup( objp->d_namep );
09727 tp->tr_l.tl_mat = (matp_t)NULL;
09728
09729
09730 comb->tree = (union tree *)db_mkgift_tree( tree_list, node_count, &rt_uniresource );
09731
09732
09733 if (rt_db_put_internal(dp, dbip, &intern, &rt_uniresource) < 0) {
09734 Tcl_AppendResult(interp, "Failed to write ", dp->d_namep, (char *)NULL);
09735 return DIR_NULL;
09736 }
09737
09738 bu_free((char *)tree_list, "combadd: tree_list");
09739
09740 return (dp);
09741 }
09742
09743 static void
09744 wdb_do_identitize(struct db_i *dbip,
09745 struct rt_comb_internal *comb,
09746 union tree *comb_leaf,
09747 genptr_t user_ptr1,
09748 genptr_t user_ptr2,
09749 genptr_t user_ptr3)
09750 {
09751 struct directory *dp;
09752 Tcl_Interp *interp = (Tcl_Interp *)user_ptr1;
09753
09754 RT_CK_DBI(dbip);
09755 RT_CK_TREE(comb_leaf);
09756
09757 if (!comb_leaf->tr_l.tl_mat) {
09758 comb_leaf->tr_l.tl_mat = (matp_t)bu_malloc(sizeof(mat_t), "tl_mat");
09759 }
09760 MAT_IDN(comb_leaf->tr_l.tl_mat);
09761 if ((dp = db_lookup(dbip, comb_leaf->tr_l.tl_name, LOOKUP_NOISY)) == DIR_NULL)
09762 return;
09763
09764 wdb_identitize(dp, dbip, interp);
09765 }
09766
09767
09768
09769
09770
09771
09772
09773 void
09774 wdb_identitize(struct directory *dp,
09775 struct db_i *dbip,
09776 Tcl_Interp *interp)
09777 {
09778 struct rt_db_internal intern;
09779 struct rt_comb_internal *comb;
09780
09781 if (dp->d_flags & DIR_SOLID)
09782 return;
09783 if (rt_db_get_internal(&intern, dp, dbip, (fastf_t *)NULL, &rt_uniresource) < 0) {
09784 Tcl_AppendResult(interp, "Database read error, aborting\n", (char *)NULL);
09785 return;
09786 }
09787 comb = (struct rt_comb_internal *)intern.idb_ptr;
09788 if (comb->tree) {
09789 db_tree_funcleaf(dbip, comb, comb->tree, wdb_do_identitize,
09790 (genptr_t)interp, (genptr_t)NULL, (genptr_t)NULL);
09791 if (rt_db_put_internal(dp, dbip, &intern, &rt_uniresource) < 0) {
09792 Tcl_AppendResult(interp, "Cannot write modified combination (", dp->d_namep,
09793 ") to database\n", (char *)NULL );
09794 return;
09795 }
09796 }
09797 }
09798
09799
09800
09801
09802
09803
09804
09805
09806 static void
09807 wdb_dir_summary(struct db_i *dbip,
09808 Tcl_Interp *interp,
09809 int flag)
09810 {
09811 register struct directory *dp;
09812 register int i;
09813 static int sol, comb, reg;
09814 struct directory **dirp;
09815 struct directory **dirp0 = (struct directory **)NULL;
09816 struct bu_vls vls;
09817
09818 bu_vls_init(&vls);
09819
09820 sol = comb = reg = 0;
09821 for (i = 0; i < RT_DBNHASH; i++) {
09822 for (dp = dbip->dbi_Head[i]; dp != DIR_NULL; dp = dp->d_forw) {
09823 if (dp->d_flags & DIR_SOLID)
09824 sol++;
09825 if (dp->d_flags & DIR_COMB) {
09826 if (dp->d_flags & DIR_REGION)
09827 reg++;
09828 else
09829 comb++;
09830 }
09831 }
09832 }
09833
09834 bu_vls_printf(&vls, "Summary:\n");
09835 bu_vls_printf(&vls, " %5d primitives\n", sol);
09836 bu_vls_printf(&vls, " %5d region; %d non-region combinations\n", reg, comb);
09837 bu_vls_printf(&vls, " %5d total objects\n\n", sol+reg+comb );
09838
09839 if (flag == 0) {
09840 Tcl_AppendResult(interp, bu_vls_addr(&vls), (char *)NULL);
09841 bu_vls_free(&vls);
09842 return;
09843 }
09844
09845
09846
09847
09848 dirp = wdb_dir_getspace(dbip, 0);
09849 dirp0 = dirp;
09850
09851
09852
09853
09854 for (i = 0; i < RT_DBNHASH; i++)
09855 for(dp = dbip->dbi_Head[i]; dp != DIR_NULL; dp = dp->d_forw)
09856 if (dp->d_flags & flag)
09857 *dirp++ = dp;
09858
09859 wdb_vls_col_pr4v(&vls, dirp0, (int)(dirp - dirp0), 0);
09860 Tcl_AppendResult(interp, bu_vls_addr(&vls), (char *)NULL);
09861 bu_vls_free(&vls);
09862 bu_free((genptr_t)dirp0, "dir_getspace");
09863 }
09864
09865
09866
09867
09868
09869
09870
09871
09872
09873 static struct directory **
09874 wdb_dir_getspace(struct db_i *dbip,
09875 register int num_entries)
09876 {
09877 register struct directory *dp;
09878 register int i;
09879 register struct directory **dir_basep;
09880
09881 if (num_entries < 0) {
09882 bu_log( "dir_getspace: was passed %d, used 0\n",
09883 num_entries);
09884 num_entries = 0;
09885 }
09886 if (num_entries == 0) {
09887
09888 for (i = 0; i < RT_DBNHASH; i++)
09889 for(dp = dbip->dbi_Head[i]; dp != DIR_NULL; dp = dp->d_forw)
09890 num_entries++;
09891 }
09892
09893
09894 dir_basep = (struct directory **) bu_malloc((num_entries+1) * sizeof(struct directory *),
09895 "dir_getspace *dir[]");
09896 return dir_basep;
09897 }
09898
09899
09900
09901
09902 static union tree *
09903 wdb_pathlist_leaf_func(struct db_tree_state *tsp,
09904 struct db_full_path *pathp,
09905 struct rt_db_internal *ip,
09906 genptr_t client_data)
09907 {
09908 Tcl_Interp *interp = (Tcl_Interp *)client_data;
09909 char *str;
09910
09911 RT_CK_FULL_PATH(pathp);
09912 RT_CK_DB_INTERNAL(ip);
09913
09914 if (pathListNoLeaf) {
09915 --pathp->fp_len;
09916 str = db_path_to_string(pathp);
09917 ++pathp->fp_len;
09918 } else
09919 str = db_path_to_string(pathp);
09920
09921 Tcl_AppendElement(interp, str);
09922
09923 bu_free((genptr_t)str, "path string");
09924 return TREE_NULL;
09925 }
09926
09927
09928
09929
09930
09931 int
09932 wdb_bot_decimate_cmd(struct rt_wdb *wdbp,
09933 Tcl_Interp *interp,
09934 int argc,
09935 char **argv)
09936 {
09937 int c;
09938 struct rt_db_internal intern;
09939 struct rt_bot_internal *bot;
09940 struct directory *dp;
09941 fastf_t max_chord_error=-1.0;
09942 fastf_t max_normal_error=-1.0;
09943 fastf_t min_edge_length=-1.0;
09944
09945 if( argc < 5 || argc > 9 ) {
09946 struct bu_vls vls;
09947
09948 bu_vls_init(&vls);
09949 bu_vls_printf(&vls, "helplib_alias wdb_bot_decimate %s", argv[0]);
09950 Tcl_Eval(interp, bu_vls_addr(&vls));
09951 bu_vls_free(&vls);
09952 return TCL_ERROR;
09953 }
09954
09955
09956 bu_optind = 1;
09957 bu_opterr = 0;
09958 while( (c=bu_getopt(argc,argv,"c:n:e:")) != EOF ) {
09959 switch(c) {
09960 case 'c':
09961 max_chord_error = atof( bu_optarg );
09962 if( max_chord_error < 0.0 ) {
09963 Tcl_AppendResult(interp,
09964 "Maximum chord error cannot be less than zero",
09965 (char *)NULL );
09966 return TCL_ERROR;
09967 }
09968 break;
09969 case 'n':
09970 max_normal_error = atof( bu_optarg );
09971 if( max_normal_error < 0.0 ) {
09972 Tcl_AppendResult(interp,
09973 "Maximum normal error cannot be less than zero",
09974 (char *)NULL );
09975 return TCL_ERROR;
09976 }
09977 break;
09978 case 'e':
09979 min_edge_length = atof( bu_optarg );
09980 if( min_edge_length < 0.0 ) {
09981 Tcl_AppendResult(interp,
09982 "minumum edge length cannot be less than zero",
09983 (char *)NULL );
09984 return TCL_ERROR;
09985 }
09986 break;
09987 default:
09988 {
09989 struct bu_vls vls;
09990
09991 bu_vls_init(&vls);
09992 bu_vls_printf(&vls, "helplib_alias wdb_bot_decimate %s",
09993 argv[0]);
09994 Tcl_Eval(interp, bu_vls_addr(&vls));
09995 bu_vls_free(&vls);
09996 return TCL_ERROR;
09997 }
09998 }
09999 }
10000
10001 argc -= bu_optind;
10002 argv += bu_optind;
10003
10004
10005 if( (dp=db_lookup( wdbp->dbip, argv[0], LOOKUP_QUIET ) ) != DIR_NULL ) {
10006 Tcl_AppendResult(interp, argv[0], " already exists!!\n", (char *)NULL );
10007 return TCL_ERROR;
10008 }
10009
10010
10011 if( (dp=db_lookup( wdbp->dbip, argv[1], LOOKUP_QUIET ) ) == DIR_NULL ) {
10012 Tcl_AppendResult(interp, argv[1], " Does not exist\n", (char *)NULL );
10013 return TCL_ERROR;
10014 }
10015
10016
10017 RT_INIT_DB_INTERNAL( &intern );
10018 if( rt_db_get_internal( &intern, dp, wdbp->dbip, NULL, wdbp->wdb_resp ) < 0 ) {
10019 Tcl_AppendResult(interp, "Failed to get internal form of ", argv[1],
10020 "\n", (char *)NULL );
10021 return TCL_ERROR;
10022 }
10023
10024
10025 if( intern.idb_major_type != DB5_MAJORTYPE_BRLCAD ||
10026 intern.idb_minor_type != DB5_MINORTYPE_BRLCAD_BOT ) {
10027 Tcl_AppendResult(interp, argv[1], " is not a BOT solid\n", (char *)NULL );
10028 rt_db_free_internal( &intern, wdbp->wdb_resp );
10029 return TCL_ERROR;
10030 }
10031
10032 bot = (struct rt_bot_internal *)intern.idb_ptr;
10033
10034 RT_BOT_CK_MAGIC( bot );
10035
10036
10037 max_chord_error = max_chord_error * wdbp->dbip->dbi_local2base;
10038 min_edge_length = min_edge_length * wdbp->dbip->dbi_local2base;
10039
10040
10041 if( rt_bot_decimate( bot, max_chord_error, max_normal_error, min_edge_length) < 0 ) {
10042 Tcl_AppendResult(interp, "Decimation Error\n", (char *)NULL );
10043 rt_db_free_internal( &intern, wdbp->wdb_resp );
10044 return TCL_ERROR;
10045 }
10046
10047
10048 if( wdb_put_internal( wdbp, argv[0], &intern, 1.0 ) < 0 ) {
10049 Tcl_AppendResult(interp, "Failed to write decimated BOT back to database\n", (char *)NULL );
10050 return TCL_ERROR;
10051 }
10052
10053 return TCL_OK;
10054 }
10055
10056
10057
10058
10059
10060 static int
10061 wdb_bot_decimate_tcl(ClientData clientData,
10062 Tcl_Interp *interp,
10063 int argc,
10064 char **argv)
10065 {
10066 struct rt_wdb *wdbp = (struct rt_wdb *)clientData;
10067
10068 return wdb_bot_decimate_cmd(wdbp, interp, argc-1, argv+1);
10069 }
10070
10071
10072 int
10073 wdb_move_arb_edge_cmd(struct rt_wdb *wdbp,
10074 Tcl_Interp *interp,
10075 int argc,
10076 char **argv)
10077 {
10078 struct rt_db_internal intern;
10079 struct rt_arb_internal *arb;
10080 fastf_t planes[7][4];
10081 int arb_type;
10082 int edge;
10083 int bad_edge_id = 0;
10084 point_t pt;
10085
10086 if (argc != 4) {
10087 struct bu_vls vls;
10088
10089 bu_vls_init(&vls);
10090 bu_vls_printf(&vls, "helplib_alias wdb_move_arb_edge %s", argv[0]);
10091 Tcl_Eval(interp, bu_vls_addr(&vls));
10092 bu_vls_free(&vls);
10093
10094 return TCL_ERROR;
10095 }
10096
10097 if (wdbp->dbip == 0) {
10098 Tcl_AppendResult(interp,
10099 "db does not support lookup operations",
10100 (char *)NULL);
10101 return TCL_ERROR;
10102 }
10103
10104 if (rt_tcl_import_from_path(interp, &intern, argv[1], wdbp) == TCL_ERROR)
10105 return TCL_ERROR;
10106
10107 if (intern.idb_major_type != DB5_MAJORTYPE_BRLCAD ||
10108 intern.idb_minor_type != DB5_MINORTYPE_BRLCAD_ARB8) {
10109 Tcl_AppendResult(interp, "Object not an ARB", (char *)NULL);
10110 rt_db_free_internal(&intern, &rt_uniresource);
10111
10112 return TCL_ERROR;
10113 }
10114
10115 if (sscanf(argv[2], "%d", &edge) != 1) {
10116 struct bu_vls vls;
10117
10118 bu_vls_init(&vls);
10119 bu_vls_printf(&vls, "bad edge - %s", argv[2]);
10120 Tcl_AppendResult(interp, bu_vls_addr(&vls), (char *)NULL);
10121 bu_vls_free(&vls);
10122 rt_db_free_internal(&intern, &rt_uniresource);
10123
10124 return TCL_ERROR;
10125 }
10126 edge -= 1;
10127
10128 if (sscanf(argv[3], "%lf %lf %lf", &pt[X], &pt[Y], &pt[Z]) != 3) {
10129 struct bu_vls vls;
10130
10131 bu_vls_init(&vls);
10132 bu_vls_printf(&vls, "bad point - %s", argv[3]);
10133 Tcl_AppendResult(interp, bu_vls_addr(&vls), (char *)NULL);
10134 bu_vls_free(&vls);
10135 rt_db_free_internal(&intern, &rt_uniresource);
10136
10137 return TCL_ERROR;
10138 }
10139
10140 arb = (struct rt_arb_internal *)intern.idb_ptr;
10141 RT_ARB_CK_MAGIC(arb);
10142
10143 arb_type = rt_arb_std_type(&intern, &wdbp->wdb_tol);
10144
10145
10146 switch (arb_type) {
10147 case ARB4:
10148 if (edge < 0 || 4 < edge)
10149 bad_edge_id = 1;
10150 break;
10151 case ARB5:
10152 if (edge < 0 || 8 < edge)
10153 bad_edge_id = 1;
10154 break;
10155 case ARB6:
10156 if (edge < 0 || 9 < edge)
10157 bad_edge_id = 1;
10158 break;
10159 case ARB7:
10160 if (edge < 0 || 11 < edge)
10161 bad_edge_id = 1;
10162 break;
10163 case ARB8:
10164 if (edge < 0 || 11 < edge)
10165 bad_edge_id = 1;
10166 break;
10167 default:
10168 Tcl_AppendResult(interp, "unrecognized arb type", (char *)NULL);
10169 rt_db_free_internal(&intern, &rt_uniresource);
10170
10171 return TCL_ERROR;
10172 }
10173
10174
10175 if (bad_edge_id) {
10176 struct bu_vls vls;
10177
10178 bu_vls_init(&vls);
10179 bu_vls_printf(&vls, "bad edge - %s", argv[2]);
10180 Tcl_AppendResult(interp, bu_vls_addr(&vls), (char *)NULL);
10181 bu_vls_free(&vls);
10182 rt_db_free_internal(&intern, &rt_uniresource);
10183
10184 return TCL_ERROR;
10185 }
10186
10187 if (rt_arb_calc_planes(interp, arb, arb_type, planes, &wdbp->wdb_tol)) {
10188 rt_db_free_internal(&intern, &rt_uniresource);
10189
10190 return TCL_ERROR;
10191 }
10192
10193 if (rt_arb_edit(interp, arb, arb_type, edge, pt, planes, &wdbp->wdb_tol)) {
10194 rt_db_free_internal(&intern, &rt_uniresource);
10195
10196 return TCL_ERROR;
10197 }
10198
10199 {
10200 register int i;
10201 struct bu_vls vls;
10202
10203 bu_vls_init(&vls);
10204
10205 for (i = 0; i < 8; ++i) {
10206 bu_vls_printf(&vls, "V%d {%g %g %g} ",
10207 i + 1,
10208 arb->pt[i][X],
10209 arb->pt[i][Y],
10210 arb->pt[i][Z]);
10211 }
10212
10213 Tcl_AppendResult(interp, bu_vls_addr(&vls), (char *)NULL);
10214 bu_vls_free(&vls);
10215 }
10216
10217 rt_db_free_internal(&intern, &rt_uniresource);
10218 return TCL_OK;
10219 }
10220
10221
10222
10223
10224
10225
10226
10227
10228
10229 static int
10230 wdb_move_arb_edge_tcl(ClientData clientData,
10231 Tcl_Interp *interp,
10232 int argc,
10233 char **argv)
10234 {
10235 struct rt_wdb *wdbp = (struct rt_wdb *)clientData;
10236
10237 return wdb_move_arb_edge_cmd(wdbp, interp, argc-1, argv+1);
10238 }
10239
10240 int
10241 wdb_move_arb_face_cmd(struct rt_wdb *wdbp,
10242 Tcl_Interp *interp,
10243 int argc,
10244 char **argv)
10245 {
10246 struct rt_db_internal intern;
10247 struct rt_arb_internal *arb;
10248 fastf_t planes[7][4];
10249 int arb_type;
10250 int face;
10251 point_t pt;
10252
10253 if (argc != 4) {
10254 struct bu_vls vls;
10255
10256 bu_vls_init(&vls);
10257 bu_vls_printf(&vls, "helplib_alias wdb_move_arb_face %s", argv[0]);
10258 Tcl_Eval(interp, bu_vls_addr(&vls));
10259 bu_vls_free(&vls);
10260
10261 return TCL_ERROR;
10262 }
10263
10264 if (wdbp->dbip == 0) {
10265 Tcl_AppendResult(interp,
10266 "db does not support lookup operations",
10267 (char *)NULL);
10268 return TCL_ERROR;
10269 }
10270
10271 if (rt_tcl_import_from_path(interp, &intern, argv[1], wdbp) == TCL_ERROR)
10272 return TCL_ERROR;
10273
10274 if (intern.idb_major_type != DB5_MAJORTYPE_BRLCAD ||
10275 intern.idb_minor_type != DB5_MINORTYPE_BRLCAD_ARB8) {
10276 Tcl_AppendResult(interp, "Object not an ARB", (char *)NULL);
10277 rt_db_free_internal(&intern, &rt_uniresource);
10278
10279 return TCL_OK;
10280 }
10281
10282 if (sscanf(argv[2], "%d", &face) != 1) {
10283 struct bu_vls vls;
10284
10285 bu_vls_init(&vls);
10286 bu_vls_printf(&vls, "bad face - %s", argv[2]);
10287 Tcl_AppendResult(interp, bu_vls_addr(&vls), (char *)NULL);
10288 bu_vls_free(&vls);
10289 rt_db_free_internal(&intern, &rt_uniresource);
10290
10291 return TCL_ERROR;
10292 }
10293
10294
10295 face -= 1;
10296 if (face < 0 || 5 < face) {
10297 struct bu_vls vls;
10298
10299 bu_vls_init(&vls);
10300 bu_vls_printf(&vls, "bad face - %s", argv[2]);
10301 Tcl_AppendResult(interp, bu_vls_addr(&vls), (char *)NULL);
10302 bu_vls_free(&vls);
10303 rt_db_free_internal(&intern, &rt_uniresource);
10304
10305 return TCL_ERROR;
10306 }
10307
10308 if (sscanf(argv[3], "%lf %lf %lf", &pt[X], &pt[Y], &pt[Z]) != 3) {
10309 struct bu_vls vls;
10310
10311 bu_vls_init(&vls);
10312 bu_vls_printf(&vls, "bad point - %s", argv[3]);
10313 Tcl_AppendResult(interp, bu_vls_addr(&vls), (char *)NULL);
10314 bu_vls_free(&vls);
10315 rt_db_free_internal(&intern, &rt_uniresource);
10316
10317 return TCL_ERROR;
10318 }
10319
10320 arb = (struct rt_arb_internal *)intern.idb_ptr;
10321 RT_ARB_CK_MAGIC(arb);
10322
10323 arb_type = rt_arb_std_type(&intern, &wdbp->wdb_tol);
10324
10325 if (rt_arb_calc_planes(interp, arb, arb_type, planes, &wdbp->wdb_tol)) {
10326 rt_db_free_internal(&intern, &rt_uniresource);
10327
10328 return TCL_ERROR;
10329 }
10330
10331
10332 planes[face][3] = VDOT(&planes[face][0], pt);
10333
10334
10335 (void)rt_arb_calc_points(arb, arb_type, planes, &wdbp->wdb_tol);
10336
10337 {
10338 register int i;
10339 struct bu_vls vls;
10340
10341 bu_vls_init(&vls);
10342
10343 for (i = 0; i < 8; ++i) {
10344 bu_vls_printf(&vls, "V%d {%g %g %g} ",
10345 i + 1,
10346 arb->pt[i][X],
10347 arb->pt[i][Y],
10348 arb->pt[i][Z]);
10349 }
10350
10351 Tcl_AppendResult(interp, bu_vls_addr(&vls), (char *)NULL);
10352 bu_vls_free(&vls);
10353 }
10354
10355 rt_db_free_internal(&intern, &rt_uniresource);
10356 return TCL_OK;
10357 }
10358
10359
10360
10361
10362
10363
10364
10365
10366
10367 static int
10368 wdb_move_arb_face_tcl(ClientData clientData,
10369 Tcl_Interp *interp,
10370 int argc,
10371 char **argv)
10372 {
10373 struct rt_wdb *wdbp = (struct rt_wdb *)clientData;
10374
10375 return wdb_move_arb_face_cmd(wdbp, interp, argc-1, argv+1);
10376 }
10377
10378
10379 static short int rt_arb_vertices[5][24] = {
10380 { 1,2,3,0, 1,2,4,0, 2,3,4,0, 1,3,4,0, 0,0,0,0, 0,0,0,0 },
10381 { 1,2,3,4, 1,2,5,0, 2,3,5,0, 3,4,5,0, 1,4,5,0, 0,0,0,0 },
10382 { 1,2,3,4, 2,3,6,5, 1,5,6,4, 1,2,5,0, 3,4,6,0, 0,0,0,0 },
10383 { 1,2,3,4, 5,6,7,0, 1,4,5,0, 2,3,7,6, 1,2,6,5, 4,3,7,5 },
10384 { 1,2,3,4, 5,6,7,8, 1,5,8,4, 2,3,7,6, 1,2,6,5, 4,3,7,8 }
10385 };
10386
10387 int
10388 wdb_rotate_arb_face_cmd(struct rt_wdb *wdbp,
10389 Tcl_Interp *interp,
10390 int argc,
10391 char **argv)
10392 {
10393 struct rt_db_internal intern;
10394 struct rt_arb_internal *arb;
10395 fastf_t planes[7][4];
10396 int arb_type;
10397 int face;
10398 int vi;
10399 point_t pt;
10400 register int i;
10401 int pnt5;
10402
10403 if (argc != 5) {
10404 struct bu_vls vls;
10405
10406 bu_vls_init(&vls);
10407 bu_vls_printf(&vls, "helplib_alias wdb_move_arb_face %s", argv[0]);
10408 Tcl_Eval(interp, bu_vls_addr(&vls));
10409 bu_vls_free(&vls);
10410
10411 return TCL_ERROR;
10412 }
10413
10414 if (wdbp->dbip == 0) {
10415 Tcl_AppendResult(interp,
10416 "db does not support lookup operations",
10417 (char *)NULL);
10418 return TCL_ERROR;
10419 }
10420
10421 if (rt_tcl_import_from_path(interp, &intern, argv[1], wdbp) == TCL_ERROR)
10422 return TCL_ERROR;
10423
10424 if (intern.idb_major_type != DB5_MAJORTYPE_BRLCAD ||
10425 intern.idb_minor_type != DB5_MINORTYPE_BRLCAD_ARB8) {
10426 Tcl_AppendResult(interp, "Object not an ARB", (char *)NULL);
10427 rt_db_free_internal(&intern, &rt_uniresource);
10428
10429 return TCL_OK;
10430 }
10431
10432 if (sscanf(argv[2], "%d", &face) != 1) {
10433 struct bu_vls vls;
10434
10435 bu_vls_init(&vls);
10436 bu_vls_printf(&vls, "bad face - %s", argv[2]);
10437 Tcl_AppendResult(interp, bu_vls_addr(&vls), (char *)NULL);
10438 bu_vls_free(&vls);
10439 rt_db_free_internal(&intern, &rt_uniresource);
10440
10441 return TCL_ERROR;
10442 }
10443
10444
10445 face -= 1;
10446 if (face < 0 || 5 < face) {
10447 struct bu_vls vls;
10448
10449 bu_vls_init(&vls);
10450 bu_vls_printf(&vls, "bad face - %s", argv[2]);
10451 Tcl_AppendResult(interp, bu_vls_addr(&vls), (char *)NULL);
10452 bu_vls_free(&vls);
10453 rt_db_free_internal(&intern, &rt_uniresource);
10454
10455 return TCL_ERROR;
10456 }
10457
10458 if (sscanf(argv[3], "%d", &vi) != 1) {
10459 struct bu_vls vls;
10460
10461 bu_vls_init(&vls);
10462 bu_vls_printf(&vls, "bad vertex index - %s", argv[2]);
10463 Tcl_AppendResult(interp, bu_vls_addr(&vls), (char *)NULL);
10464 bu_vls_free(&vls);
10465 rt_db_free_internal(&intern, &rt_uniresource);
10466
10467 return TCL_ERROR;
10468 }
10469
10470
10471
10472 vi -= 1;
10473 if (vi < 0 || 7 < vi) {
10474 struct bu_vls vls;
10475
10476 bu_vls_init(&vls);
10477 bu_vls_printf(&vls, "bad vertex - %s", argv[2]);
10478 Tcl_AppendResult(interp, bu_vls_addr(&vls), (char *)NULL);
10479 bu_vls_free(&vls);
10480 rt_db_free_internal(&intern, &rt_uniresource);
10481
10482 return TCL_ERROR;
10483 }
10484
10485 if (sscanf(argv[4], "%lf %lf %lf", &pt[X], &pt[Y], &pt[Z]) != 3) {
10486 struct bu_vls vls;
10487
10488 bu_vls_init(&vls);
10489 bu_vls_printf(&vls, "bad point - %s", argv[3]);
10490 Tcl_AppendResult(interp, bu_vls_addr(&vls), (char *)NULL);
10491 bu_vls_free(&vls);
10492 rt_db_free_internal(&intern, &rt_uniresource);
10493
10494 return TCL_ERROR;
10495 }
10496
10497 arb = (struct rt_arb_internal *)intern.idb_ptr;
10498 RT_ARB_CK_MAGIC(arb);
10499
10500 arb_type = rt_arb_std_type(&intern, &wdbp->wdb_tol);
10501
10502 if (rt_arb_calc_planes(interp, arb, arb_type, planes, &wdbp->wdb_tol)) {
10503 rt_db_free_internal(&intern, &rt_uniresource);
10504
10505 return TCL_ERROR;
10506 }
10507
10508
10509 pnt5 = 0;
10510 for(i=0; i<4; i++) {
10511 if (rt_arb_vertices[arb_type-4][face*4+i]==5)
10512 pnt5=1;
10513 }
10514
10515
10516 if (arb_type == ARB7 && pnt5)
10517 vi = 4;
10518
10519 {
10520
10521 vect_t tempvec;
10522 vect_t work;
10523 fastf_t *plane;
10524 mat_t rmat;
10525
10526 bn_mat_angles(rmat, pt[X], pt[Y], pt[Z]);
10527
10528 plane = &planes[face][0];
10529 VMOVE(work, plane);
10530 MAT4X3VEC(plane, rmat, work);
10531
10532
10533 VMOVE(tempvec, arb->pt[vi]);
10534
10535
10536 planes[face][3]=VDOT(plane, tempvec);
10537 }
10538
10539
10540 (void)rt_arb_calc_points(arb, arb_type, planes, &wdbp->wdb_tol);
10541
10542 {
10543 register int i;
10544 struct bu_vls vls;
10545
10546 bu_vls_init(&vls);
10547
10548 for (i = 0; i < 8; ++i) {
10549 bu_vls_printf(&vls, "V%d {%g %g %g} ",
10550 i + 1,
10551 arb->pt[i][X],
10552 arb->pt[i][Y],
10553 arb->pt[i][Z]);
10554 }
10555
10556 Tcl_AppendResult(interp, bu_vls_addr(&vls), (char *)NULL);
10557 bu_vls_free(&vls);
10558 }
10559
10560 rt_db_free_internal(&intern, &rt_uniresource);
10561 return TCL_OK;
10562 }
10563
10564
10565
10566
10567
10568
10569
10570
10571 static int
10572 wdb_rotate_arb_face_tcl(ClientData clientData,
10573 Tcl_Interp *interp,
10574 int argc,
10575 char **argv)
10576 {
10577 struct rt_wdb *wdbp = (struct rt_wdb *)clientData;
10578
10579 return wdb_rotate_arb_face_cmd(wdbp, interp, argc-1, argv+1);
10580 }
10581
10582 int
10583 wdb_orotate_cmd(struct rt_wdb *wdbp,
10584 Tcl_Interp *interp,
10585 int argc,
10586 char **argv)
10587 {
10588 register struct directory *dp;
10589 struct wdb_trace_data wtd;
10590 struct rt_db_internal intern;
10591 fastf_t xrot, yrot, zrot;
10592 mat_t rmat;
10593 mat_t pmat;
10594 mat_t emat;
10595 mat_t tmpMat;
10596 mat_t invXform;
10597 point_t rpp_min;
10598 point_t rpp_max;
10599 point_t keypoint;
10600 Tcl_DString ds;
10601
10602 WDB_TCL_CHECK_READ_ONLY;
10603
10604 if (argc != 5 && argc != 8) {
10605 struct bu_vls vls;
10606
10607 bu_vls_init(&vls);
10608 bu_vls_printf(&vls, "helplib wdb_orotate");
10609 Tcl_Eval(interp, bu_vls_addr(&vls));
10610 bu_vls_free(&vls);
10611
10612 return TCL_ERROR;
10613 }
10614
10615 if (sscanf(argv[2], "%lf", &xrot) != 1) {
10616 Tcl_DStringInit(&ds);
10617 Tcl_DStringAppend(&ds, argv[0], -1);
10618 Tcl_DStringAppend(&ds, ": bad xrot value - ", -1);
10619 Tcl_DStringAppend(&ds, argv[2], -1);
10620 Tcl_DStringResult(interp, &ds);
10621
10622 return TCL_ERROR;
10623 }
10624
10625 if (sscanf(argv[3], "%lf", &yrot) != 1) {
10626 Tcl_DStringInit(&ds);
10627 Tcl_DStringAppend(&ds, argv[0], -1);
10628 Tcl_DStringAppend(&ds, ": bad yrot value - ", -1);
10629 Tcl_DStringAppend(&ds, argv[3], -1);
10630 Tcl_DStringResult(interp, &ds);
10631
10632 return TCL_ERROR;
10633 }
10634
10635 if (sscanf(argv[4], "%lf", &zrot) != 1) {
10636 Tcl_DStringInit(&ds);
10637 Tcl_DStringAppend(&ds, argv[0], -1);
10638 Tcl_DStringAppend(&ds, ": bad zrot value - ", -1);
10639 Tcl_DStringAppend(&ds, argv[4], -1);
10640 Tcl_DStringResult(interp, &ds);
10641
10642 return TCL_ERROR;
10643 }
10644
10645 if (argc == 5) {
10646
10647
10648 if (wdb_get_obj_bounds2(wdbp, interp, 1, argv+1, &wtd, rpp_min, rpp_max) == TCL_ERROR)
10649 return TCL_ERROR;
10650
10651 dp = wtd.wtd_obj[wtd.wtd_objpos-1];
10652 if (!(dp->d_flags & DIR_SOLID)) {
10653 if (wdb_get_obj_bounds(wdbp, interp, 1, argv+1, 1, rpp_min, rpp_max) == TCL_ERROR)
10654 return TCL_ERROR;
10655 }
10656
10657 VADD2(keypoint, rpp_min, rpp_max);
10658 VSCALE(keypoint, keypoint, 0.5);
10659 } else {
10660
10661 MAT_IDN(wtd.wtd_xform);
10662
10663 if (sscanf(argv[5], "%lf", &keypoint[X]) != 1) {
10664 Tcl_DStringInit(&ds);
10665 Tcl_DStringAppend(&ds, argv[0], -1);
10666 Tcl_DStringAppend(&ds, ": bad kx value - ", -1);
10667 Tcl_DStringAppend(&ds, argv[5], -1);
10668 Tcl_DStringResult(interp, &ds);
10669
10670 return TCL_ERROR;
10671 }
10672
10673 if (sscanf(argv[6], "%lf", &keypoint[Y]) != 1) {
10674 Tcl_DStringInit(&ds);
10675 Tcl_DStringAppend(&ds, argv[0], -1);
10676 Tcl_DStringAppend(&ds, ": bad ky value - ", -1);
10677 Tcl_DStringAppend(&ds, argv[6], -1);
10678 Tcl_DStringResult(interp, &ds);
10679
10680 return TCL_ERROR;
10681 }
10682
10683 if (sscanf(argv[7], "%lf", &keypoint[Z]) != 1) {
10684 Tcl_DStringInit(&ds);
10685 Tcl_DStringAppend(&ds, argv[0], -1);
10686 Tcl_DStringAppend(&ds, ": bad kz value - ", -1);
10687 Tcl_DStringAppend(&ds, argv[7], -1);
10688 Tcl_DStringResult(interp, &ds);
10689
10690 return TCL_ERROR;
10691 }
10692
10693 VSCALE(keypoint, keypoint, wdbp->dbip->dbi_local2base);
10694
10695 if ((dp = db_lookup(wdbp->dbip, argv[1], LOOKUP_QUIET)) == DIR_NULL) {
10696 Tcl_DStringInit(&ds);
10697 Tcl_DStringAppend(&ds, argv[0], -1);
10698 Tcl_DStringAppend(&ds, ": ", -1);
10699 Tcl_DStringAppend(&ds, argv[1], -1);
10700 Tcl_DStringAppend(&ds, " not found", -1);
10701 Tcl_DStringResult(interp, &ds);
10702
10703 return TCL_ERROR;
10704 }
10705 }
10706
10707 #if 0
10708 MAT_IDN(rmat);
10709 MAT_IDN(mat);
10710 #endif
10711 bn_mat_angles(rmat, xrot, yrot, zrot);
10712 bn_mat_xform_about_pt(pmat, rmat, keypoint);
10713
10714 bn_mat_inv(invXform, wtd.wtd_xform);
10715 bn_mat_mul(tmpMat, invXform, pmat);
10716 bn_mat_mul(emat, tmpMat, wtd.wtd_xform);
10717
10718 if (rt_db_get_internal(&intern, dp, wdbp->dbip, emat, &rt_uniresource) < 0) {
10719 Tcl_DStringInit(&ds);
10720 Tcl_DStringAppend(&ds, argv[0], -1);
10721 Tcl_DStringAppend(&ds, ": ", -1);
10722 Tcl_DStringAppend(&ds, " rt_db_get_internal(", -1);
10723 Tcl_DStringAppend(&ds, argv[1], -1);
10724 Tcl_DStringAppend(&ds, ") failure", -1);
10725 Tcl_DStringResult(interp, &ds);
10726
10727 return TCL_ERROR;
10728 }
10729 RT_CK_DB_INTERNAL(&intern);
10730
10731 if (rt_db_put_internal(dp,
10732 wdbp->dbip,
10733 &intern,
10734 &rt_uniresource) < 0) {
10735 rt_db_free_internal(&intern, &rt_uniresource);
10736
10737 Tcl_DStringInit(&ds);
10738 Tcl_DStringAppend(&ds, argv[0], -1);
10739 Tcl_DStringAppend(&ds, ": Database write error, aborting", -1);
10740 Tcl_DStringResult(interp, &ds);
10741
10742 return TCL_ERROR;
10743 }
10744 rt_db_free_internal(&intern, &rt_uniresource);
10745
10746
10747 bu_observer_notify(interp, &wdbp->wdb_observers, bu_vls_addr(&wdbp->wdb_name));
10748
10749 return TCL_OK;
10750 }
10751
10752
10753
10754
10755
10756
10757
10758 static int
10759 wdb_orotate_tcl(ClientData clientData,
10760 Tcl_Interp *interp,
10761 int argc,
10762 char **argv)
10763 {
10764 struct rt_wdb *wdbp = (struct rt_wdb *)clientData;
10765
10766 return wdb_orotate_cmd(wdbp, interp, argc-1, argv+1);
10767 }
10768
10769 int
10770 wdb_oscale_cmd(struct rt_wdb *wdbp,
10771 Tcl_Interp *interp,
10772 int argc,
10773 char **argv)
10774 {
10775 register struct directory *dp;
10776 struct wdb_trace_data wtd;
10777 struct rt_db_internal intern;
10778 mat_t smat;
10779 mat_t emat;
10780 mat_t tmpMat;
10781 mat_t invXform;
10782 point_t rpp_min;
10783 point_t rpp_max;
10784 fastf_t sf;
10785 point_t keypoint;
10786 Tcl_DString ds;
10787
10788 WDB_TCL_CHECK_READ_ONLY;
10789
10790 if (argc != 3 && argc != 6) {
10791 struct bu_vls vls;
10792
10793 bu_vls_init(&vls);
10794 bu_vls_printf(&vls, "helplib wdb_oscale");
10795 Tcl_Eval(interp, bu_vls_addr(&vls));
10796 bu_vls_free(&vls);
10797
10798 return TCL_ERROR;
10799 }
10800
10801 if (sscanf(argv[2], "%lf", &sf) != 1) {
10802 Tcl_DStringInit(&ds);
10803 Tcl_DStringAppend(&ds, argv[0], -1);
10804 Tcl_DStringAppend(&ds, ": bad sf value - ", -1);
10805 Tcl_DStringAppend(&ds, argv[2], -1);
10806 Tcl_DStringResult(interp, &ds);
10807
10808 return TCL_ERROR;
10809 }
10810
10811 if (argc == 3) {
10812 if (wdb_get_obj_bounds2(wdbp, interp, 1, argv+1, &wtd, rpp_min, rpp_max) == TCL_ERROR)
10813 return TCL_ERROR;
10814
10815 dp = wtd.wtd_obj[wtd.wtd_objpos-1];
10816 if (!(dp->d_flags & DIR_SOLID)) {
10817 if (wdb_get_obj_bounds(wdbp, interp, 1, argv+1, 1, rpp_min, rpp_max) == TCL_ERROR)
10818 return TCL_ERROR;
10819 }
10820
10821 VADD2(keypoint, rpp_min, rpp_max);
10822 VSCALE(keypoint, keypoint, 0.5);
10823 } else {
10824
10825 MAT_IDN(wtd.wtd_xform);
10826
10827 if (sscanf(argv[3], "%lf", &keypoint[X]) != 1) {
10828 Tcl_DStringInit(&ds);
10829 Tcl_DStringAppend(&ds, argv[0], -1);
10830 Tcl_DStringAppend(&ds, ": bad kx value - ", -1);
10831 Tcl_DStringAppend(&ds, argv[3], -1);
10832 Tcl_DStringResult(interp, &ds);
10833
10834 return TCL_ERROR;
10835 }
10836
10837 if (sscanf(argv[4], "%lf", &keypoint[Y]) != 1) {
10838 Tcl_DStringInit(&ds);
10839 Tcl_DStringAppend(&ds, argv[0], -1);
10840 Tcl_DStringAppend(&ds, ": bad ky value - ", -1);
10841 Tcl_DStringAppend(&ds, argv[4], -1);
10842 Tcl_DStringResult(interp, &ds);
10843
10844 return TCL_ERROR;
10845 }
10846
10847 if (sscanf(argv[5], "%lf", &keypoint[Z]) != 1) {
10848 Tcl_DStringInit(&ds);
10849 Tcl_DStringAppend(&ds, argv[0], -1);
10850 Tcl_DStringAppend(&ds, ": bad kz value - ", -1);
10851 Tcl_DStringAppend(&ds, argv[5], -1);
10852 Tcl_DStringResult(interp, &ds);
10853
10854 return TCL_ERROR;
10855 }
10856
10857 VSCALE(keypoint, keypoint, wdbp->dbip->dbi_local2base);
10858
10859 if ((dp = db_lookup(wdbp->dbip, argv[1], LOOKUP_QUIET)) == DIR_NULL) {
10860 Tcl_DStringInit(&ds);
10861 Tcl_DStringAppend(&ds, argv[0], -1);
10862 Tcl_DStringAppend(&ds, ": ", -1);
10863 Tcl_DStringAppend(&ds, argv[1], -1);
10864 Tcl_DStringAppend(&ds, " not found", -1);
10865 Tcl_DStringResult(interp, &ds);
10866
10867 return TCL_ERROR;
10868 }
10869 }
10870
10871 MAT_IDN(smat);
10872 bn_mat_scale_about_pt(smat, keypoint, sf);
10873
10874 bn_mat_inv(invXform, wtd.wtd_xform);
10875 bn_mat_mul(tmpMat, invXform, smat);
10876 bn_mat_mul(emat, tmpMat, wtd.wtd_xform);
10877
10878 if (rt_db_get_internal(&intern, dp, wdbp->dbip, emat, &rt_uniresource) < 0) {
10879 Tcl_DStringInit(&ds);
10880 Tcl_DStringAppend(&ds, argv[0], -1);
10881 Tcl_DStringAppend(&ds, ": ", -1);
10882 Tcl_DStringAppend(&ds, " rt_db_get_internal(", -1);
10883 Tcl_DStringAppend(&ds, argv[1], -1);
10884 Tcl_DStringAppend(&ds, ") failure", -1);
10885 Tcl_DStringResult(interp, &ds);
10886
10887 return TCL_ERROR;
10888 }
10889 RT_CK_DB_INTERNAL(&intern);
10890
10891 if (rt_db_put_internal(dp,
10892 wdbp->dbip,
10893 &intern,
10894 &rt_uniresource) < 0) {
10895 rt_db_free_internal(&intern, &rt_uniresource);
10896
10897 Tcl_DStringInit(&ds);
10898 Tcl_DStringAppend(&ds, argv[0], -1);
10899 Tcl_DStringAppend(&ds, ": Database write error, aborting", -1);
10900 Tcl_DStringResult(interp, &ds);
10901
10902 return TCL_ERROR;
10903 }
10904 rt_db_free_internal(&intern, &rt_uniresource);
10905
10906
10907 bu_observer_notify(interp, &wdbp->wdb_observers, bu_vls_addr(&wdbp->wdb_name));
10908
10909 return TCL_OK;
10910 }
10911
10912
10913
10914
10915
10916
10917
10918 static int
10919 wdb_oscale_tcl(ClientData clientData,
10920 Tcl_Interp *interp,
10921 int argc,
10922 char **argv)
10923 {
10924 struct rt_wdb *wdbp = (struct rt_wdb *)clientData;
10925
10926 return wdb_oscale_cmd(wdbp, interp, argc-1, argv+1);
10927 }
10928
10929 int
10930 wdb_otranslate_cmd(struct rt_wdb *wdbp,
10931 Tcl_Interp *interp,
10932 int argc,
10933 char **argv)
10934 {
10935 register struct directory *dp;
10936 struct wdb_trace_data wtd;
10937 struct rt_db_internal intern;
10938 vect_t delta;
10939 mat_t dmat;
10940 mat_t emat;
10941 mat_t tmpMat;
10942 mat_t invXform;
10943 point_t rpp_min;
10944 point_t rpp_max;
10945 Tcl_DString ds;
10946
10947 WDB_TCL_CHECK_READ_ONLY;
10948
10949 if (argc != 5) {
10950 struct bu_vls vls;
10951
10952 bu_vls_init(&vls);
10953 bu_vls_printf(&vls, "helplib wdb_otranslate");
10954 Tcl_Eval(interp, bu_vls_addr(&vls));
10955 bu_vls_free(&vls);
10956
10957 return TCL_ERROR;
10958 }
10959
10960 if (wdb_get_obj_bounds2(wdbp, interp, 1, argv+1, &wtd, rpp_min, rpp_max) == TCL_ERROR)
10961 return TCL_ERROR;
10962
10963 dp = wtd.wtd_obj[wtd.wtd_objpos-1];
10964 if (!(dp->d_flags & DIR_SOLID)) {
10965 if (wdb_get_obj_bounds(wdbp, interp, 1, argv+1, 1, rpp_min, rpp_max) == TCL_ERROR)
10966 return TCL_ERROR;
10967 }
10968
10969 if (sscanf(argv[2], "%lf", &delta[X]) != 1) {
10970 Tcl_DStringInit(&ds);
10971 Tcl_DStringAppend(&ds, argv[0], -1);
10972 Tcl_DStringAppend(&ds, ": bad x value - ", -1);
10973 Tcl_DStringAppend(&ds, argv[2], -1);
10974 Tcl_DStringResult(interp, &ds);
10975
10976 return TCL_ERROR;
10977 }
10978
10979 if (sscanf(argv[3], "%lf", &delta[Y]) != 1) {
10980 Tcl_DStringInit(&ds);
10981 Tcl_DStringAppend(&ds, argv[0], -1);
10982 Tcl_DStringAppend(&ds, ": bad y value - ", -1);
10983 Tcl_DStringAppend(&ds, argv[3], -1);
10984 Tcl_DStringResult(interp, &ds);
10985
10986 return TCL_ERROR;
10987 }
10988
10989 if (sscanf(argv[4], "%lf", &delta[Z]) != 1) {
10990 Tcl_DStringInit(&ds);
10991 Tcl_DStringAppend(&ds, argv[0], -1);
10992 Tcl_DStringAppend(&ds, ": bad z value - ", -1);
10993 Tcl_DStringAppend(&ds, argv[4], -1);
10994 Tcl_DStringResult(interp, &ds);
10995
10996 return TCL_ERROR;
10997 }
10998
10999 MAT_IDN(dmat);
11000 VSCALE(delta, delta, wdbp->dbip->dbi_local2base);
11001 MAT_DELTAS_VEC(dmat, delta);
11002
11003 bn_mat_inv(invXform, wtd.wtd_xform);
11004 bn_mat_mul(tmpMat, invXform, dmat);
11005 bn_mat_mul(emat, tmpMat, wtd.wtd_xform);
11006
11007 if (rt_db_get_internal(&intern, dp, wdbp->dbip, emat, &rt_uniresource) < 0) {
11008 Tcl_DStringInit(&ds);
11009 Tcl_DStringAppend(&ds, argv[0], -1);
11010 Tcl_DStringAppend(&ds, ": ", -1);
11011 Tcl_DStringAppend(&ds, " rt_db_get_internal(", -1);
11012 Tcl_DStringAppend(&ds, argv[1], -1);
11013 Tcl_DStringAppend(&ds, ") failure", -1);
11014 Tcl_DStringResult(interp, &ds);
11015
11016 return TCL_ERROR;
11017 }
11018 RT_CK_DB_INTERNAL(&intern);
11019
11020 if (rt_db_put_internal(dp,
11021 wdbp->dbip,
11022 &intern,
11023 &rt_uniresource) < 0) {
11024 rt_db_free_internal(&intern, &rt_uniresource);
11025
11026 Tcl_DStringInit(&ds);
11027 Tcl_DStringAppend(&ds, argv[0], -1);
11028 Tcl_DStringAppend(&ds, ": Database write error, aborting", -1);
11029 Tcl_DStringResult(interp, &ds);
11030
11031 return TCL_ERROR;
11032 }
11033 rt_db_free_internal(&intern, &rt_uniresource);
11034
11035
11036 bu_observer_notify(interp, &wdbp->wdb_observers, bu_vls_addr(&wdbp->wdb_name));
11037
11038 return TCL_OK;
11039 }
11040
11041
11042
11043
11044
11045
11046
11047 static int
11048 wdb_otranslate_tcl(ClientData clientData,
11049 Tcl_Interp *interp,
11050 int argc,
11051 char **argv)
11052 {
11053 struct rt_wdb *wdbp = (struct rt_wdb *)clientData;
11054
11055 return wdb_otranslate_cmd(wdbp, interp, argc-1, argv+1);
11056 }
11057
11058 int
11059 wdb_ocenter_cmd(struct rt_wdb *wdbp,
11060 Tcl_Interp *interp,
11061 int argc,
11062 char **argv)
11063 {
11064 register struct directory *dp;
11065 struct wdb_trace_data wtd;
11066 struct rt_db_internal intern;
11067 mat_t dmat;
11068 mat_t emat;
11069 mat_t tmpMat;
11070 mat_t invXform;
11071 point_t rpp_min;
11072 point_t rpp_max;
11073 point_t oldCenter;
11074 point_t center;
11075 point_t delta;
11076 struct bu_vls vls;
11077 Tcl_DString ds;
11078
11079 if (argc != 2 && argc !=5) {
11080 bu_vls_init(&vls);
11081 bu_vls_printf(&vls, "helplib wdb_ocenter");
11082 Tcl_Eval(interp, bu_vls_addr(&vls));
11083 bu_vls_free(&vls);
11084
11085 return TCL_ERROR;
11086 }
11087
11088
11089
11090
11091
11092 if (wdb_get_obj_bounds2(wdbp, interp, 1, argv+1, &wtd, rpp_min, rpp_max) == TCL_ERROR)
11093 return TCL_ERROR;
11094
11095 dp = wtd.wtd_obj[wtd.wtd_objpos-1];
11096 if (!(dp->d_flags & DIR_SOLID)) {
11097 if (wdb_get_obj_bounds(wdbp, interp, 1, argv+1, 1, rpp_min, rpp_max) == TCL_ERROR)
11098 return TCL_ERROR;
11099 }
11100
11101 VADD2(oldCenter, rpp_min, rpp_max);
11102 VSCALE(oldCenter, oldCenter, 0.5);
11103
11104 if (argc == 2) {
11105 VSCALE(center, oldCenter, wdbp->dbip->dbi_base2local);
11106
11107 bu_vls_init(&vls);
11108 bn_encode_vect(&vls, center);
11109 Tcl_AppendResult(interp, bu_vls_addr(&vls), (char *)0);
11110 bu_vls_free(&vls);
11111
11112 return TCL_OK;
11113 }
11114
11115 WDB_TCL_CHECK_READ_ONLY;
11116
11117
11118 if (sscanf(argv[2], "%lf", ¢er[X]) != 1) {
11119 Tcl_DStringInit(&ds);
11120 Tcl_DStringAppend(&ds, argv[0], -1);
11121 Tcl_DStringAppend(&ds, ": bad x value - ", -1);
11122 Tcl_DStringAppend(&ds, argv[2], -1);
11123 Tcl_DStringResult(interp, &ds);
11124
11125 return TCL_ERROR;
11126 }
11127
11128 if (sscanf(argv[3], "%lf", ¢er[Y]) != 1) {
11129 Tcl_DStringInit(&ds);
11130 Tcl_DStringAppend(&ds, argv[0], -1);
11131 Tcl_DStringAppend(&ds, ": bad y value - ", -1);
11132 Tcl_DStringAppend(&ds, argv[3], -1);
11133 Tcl_DStringResult(interp, &ds);
11134
11135 return TCL_ERROR;
11136 }
11137
11138 if (sscanf(argv[4], "%lf", ¢er[Z]) != 1) {
11139 Tcl_DStringInit(&ds);
11140 Tcl_DStringAppend(&ds, argv[0], -1);
11141 Tcl_DStringAppend(&ds, ": bad x value - ", -1);
11142 Tcl_DStringAppend(&ds, argv[4], -1);
11143 Tcl_DStringResult(interp, &ds);
11144
11145 return TCL_ERROR;
11146 }
11147
11148 VSCALE(center, center, wdbp->dbip->dbi_local2base);
11149 VSUB2(delta, center, oldCenter);
11150 MAT_IDN(dmat);
11151 MAT_DELTAS_VEC(dmat, delta);
11152
11153 bn_mat_inv(invXform, wtd.wtd_xform);
11154 bn_mat_mul(tmpMat, invXform, dmat);
11155 bn_mat_mul(emat, tmpMat, wtd.wtd_xform);
11156
11157 if (rt_db_get_internal(&intern, dp, wdbp->dbip, emat, &rt_uniresource) < 0) {
11158 Tcl_DStringInit(&ds);
11159 Tcl_DStringAppend(&ds, argv[0], -1);
11160 Tcl_DStringAppend(&ds, ": ", -1);
11161 Tcl_DStringAppend(&ds, " rt_db_get_internal(", -1);
11162 Tcl_DStringAppend(&ds, argv[1], -1);
11163 Tcl_DStringAppend(&ds, ") failure", -1);
11164 Tcl_DStringResult(interp, &ds);
11165
11166 return TCL_ERROR;
11167 }
11168 RT_CK_DB_INTERNAL(&intern);
11169
11170 if (rt_db_put_internal(dp,
11171 wdbp->dbip,
11172 &intern,
11173 &rt_uniresource) < 0) {
11174 rt_db_free_internal(&intern, &rt_uniresource);
11175
11176 Tcl_DStringInit(&ds);
11177 Tcl_DStringAppend(&ds, argv[0], -1);
11178 Tcl_DStringAppend(&ds, ": Database write error, aborting", -1);
11179 Tcl_DStringResult(interp, &ds);
11180
11181 return TCL_ERROR;
11182 }
11183 rt_db_free_internal(&intern, &rt_uniresource);
11184
11185
11186 bu_observer_notify(interp, &wdbp->wdb_observers, bu_vls_addr(&wdbp->wdb_name));
11187
11188 return TCL_OK;
11189 }
11190
11191
11192
11193
11194
11195
11196
11197 static int
11198 wdb_ocenter_tcl(ClientData clientData,
11199 Tcl_Interp *interp,
11200 int argc,
11201 char **argv)
11202 {
11203 struct rt_wdb *wdbp = (struct rt_wdb *)clientData;
11204
11205 return wdb_ocenter_cmd(wdbp, interp, argc-1, argv+1);
11206 }
11207
11208
11209
11210
11211
11212
11213
11214
11215
11216