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
00040
00041
00042
00043 #include "common.h"
00044
00045 #include <stdlib.h>
00046 #include <stdio.h>
00047 #ifdef HAVE_STRING_H
00048 # include <string.h>
00049 #else
00050 # include <strings.h>
00051 #endif
00052 #include <fcntl.h>
00053 #include <math.h>
00054 #include <signal.h>
00055 #ifdef HAVE_SYS_TYPES_H
00056 # include <sys/types.h>
00057 #endif
00058 #ifdef HAVE_SYS_WAIT_H
00059 # include <sys/wait.h>
00060 #endif
00061 #ifdef HAVE_UNISTD_H
00062 # include <unistd.h>
00063 #endif
00064
00065 #include "machine.h"
00066 #include "tcl.h"
00067 #include "cmd.h"
00068 #include "vmath.h"
00069 #include "bn.h"
00070 #include "mater.h"
00071 #include "raytrace.h"
00072 #include "rtgeom.h"
00073 #include "solid.h"
00074 #include "plot3.h"
00075
00076
00077 struct dg_client_data {
00078 struct dg_obj *dgop;
00079 Tcl_Interp *interp;
00080 int wireframe_color_override;
00081 int wireframe_color[3];
00082 int draw_nmg_only;
00083 int nmg_triangulate;
00084 int draw_wireframes;
00085 int draw_normals;
00086 int draw_solid_lines_only;
00087 int draw_no_surfaces;
00088 int shade_per_vertex_normals;
00089 int draw_edge_uses;
00090 int fastpath_count;
00091 int do_not_draw_nmg_solids_during_debugging;
00092 struct bn_vlblock *draw_edge_uses_vbp;
00093 int shaded_mode_override;
00094 fastf_t transparency;
00095 int dmode;
00096 };
00097
00098 struct dg_rt_client_data {
00099 struct run_rt *rrtp;
00100 struct dg_obj *dgop;
00101 Tcl_Interp *interp;
00102 };
00103
00104 #define DGO_WIREFRAME 0
00105 #define DGO_SHADED_MODE_BOTS 1
00106 #define DGO_SHADED_MODE_ALL 2
00107 #define DGO_BOOL_EVAL 3
00108 static union tree *
00109 dgo_bot_check_region_end(register struct db_tree_state *tsp,
00110 struct db_full_path *pathp,
00111 union tree *curtree,
00112 genptr_t client_data);
00113 static union tree *
00114 dgo_bot_check_leaf(struct db_tree_state *tsp,
00115 struct db_full_path *pathp,
00116 struct rt_db_internal *ip,
00117 genptr_t client_data);
00118
00119 int dgo_shaded_mode_cmd();
00120 static int dgo_how_tcl();
00121 static int dgo_set_outputHandler_tcl();
00122 static int dgo_set_uplotOutputMode_tcl();
00123 static int dgo_set_transparency_tcl();
00124 static int dgo_shaded_mode_tcl();
00125
00126 #include "./debug.h"
00127
00128 #define DGO_CHECK_WDBP_NULL(_dgop,_interp) \
00129 if (_dgop->dgo_wdbp == RT_WDB_NULL) \
00130 { \
00131 Tcl_AppendResult(_interp, "Not associated with a database!\n", (char *)NULL); \
00132 return TCL_ERROR; \
00133 }
00134
00135
00136
00137
00138
00139
00140 extern struct mater *rt_material_head;
00141
00142
00143 extern struct bu_cmdtab vdraw_cmds[];
00144
00145
00146 extern int dgo_qray_cmd(struct dg_obj *dgop, Tcl_Interp *interp, int argc, char **argv);
00147 extern void dgo_init_qray(struct dg_obj *dgop);
00148 extern void dgo_free_qray(struct dg_obj *dgop);
00149
00150 int dgo_cmd(ClientData clientData, Tcl_Interp *interp, int argc, char **argv);
00151
00152 static int dgo_open_tcl(ClientData clientData, Tcl_Interp *interp, int argc, char **argv);
00153 static int dgo_headSolid_tcl(ClientData clientData, Tcl_Interp *interp, int argc, char **argv);
00154 static int dgo_illum_tcl(ClientData clientData, Tcl_Interp *interp, int argc, char **argv);
00155 static int dgo_label_tcl(ClientData clientData, Tcl_Interp *interp, int argc, char **argv);
00156 static int dgo_draw_tcl(ClientData clientData, Tcl_Interp *interp, int argc, char **argv);
00157 static int dgo_ev_tcl(ClientData clientData, Tcl_Interp *interp, int argc, char **argv);
00158 static int dgo_erase_tcl(ClientData clientData, Tcl_Interp *interp, int argc, char **argv);
00159 static int dgo_erase_all_tcl(ClientData clientData, Tcl_Interp *interp, int argc, char **argv);
00160 static int dgo_who_tcl(ClientData clientData, Tcl_Interp *interp, int argc, char **argv);
00161 static int dgo_rt_tcl(ClientData clientData, Tcl_Interp *interp, int argc, char **argv);
00162 static int dgo_rtabort_tcl(ClientData clientData, Tcl_Interp *interp, int argc, char **argv);
00163 static int dgo_vdraw_tcl(ClientData clientData, Tcl_Interp *interp, int argc, char **argv);
00164 static int dgo_overlay_tcl(ClientData clientData, Tcl_Interp *interp, int argc, char **argv);
00165 static int dgo_get_autoview_tcl(ClientData clientData, Tcl_Interp *interp, int argc, char **argv);
00166 static int dgo_get_eyemodel_tcl(ClientData clientData, Tcl_Interp *interp, int argc, char **argv);
00167 static int dgo_zap_tcl(ClientData clientData, Tcl_Interp *interp, int argc, char **argv);
00168 static int dgo_blast_tcl(ClientData clientData, Tcl_Interp *interp, int argc, char **argv);
00169 static int dgo_assoc_tcl(ClientData clientData, Tcl_Interp *interp, int argc, char **argv);
00170 static int dgo_rtcheck_tcl(ClientData clientData, Tcl_Interp *interp, int argc, char **argv);
00171 static int dgo_observer_tcl(ClientData clientData, Tcl_Interp *interp, int argc, char **argv);
00172 static int dgo_report_tcl(ClientData clientData, Tcl_Interp *interp, int argc, char **argv);
00173 extern int dgo_E_tcl(ClientData clientData, Tcl_Interp *interp, int argc, char **argv);
00174 static int dgo_autoview_tcl(ClientData clientData, Tcl_Interp *interp, int argc, char **argv);
00175 static int dgo_qray_tcl(ClientData clientData, Tcl_Interp *interp, int argc, char **argv);
00176 static int dgo_nirt_tcl(ClientData clientData, Tcl_Interp *interp, int argc, char **argv);
00177 static int dgo_vnirt_tcl(ClientData clientData, Tcl_Interp *interp, int argc, char **argv);
00178
00179 static union tree *dgo_wireframe_region_end(register struct db_tree_state *tsp, struct db_full_path *pathp, union tree *curtree, genptr_t client_data);
00180 static union tree *dgo_wireframe_leaf(struct db_tree_state *tsp, struct db_full_path *pathp, struct rt_db_internal *ip, genptr_t client_data);
00181 static int dgo_drawtrees(struct dg_obj *dgop, Tcl_Interp *interp, int argc, char **argv, int kind, struct dg_client_data *_dgcdp);
00182 int dgo_invent_solid(struct dg_obj *dgop, Tcl_Interp *interp, char *name, struct bu_list *vhead, long int rgb, int copy, fastf_t transparency, int dmode);
00183 static void dgo_bound_solid(Tcl_Interp *interp, register struct solid *sp);
00184 void dgo_drawH_part2(int dashflag, struct bu_list *vhead, struct db_full_path *pathp, struct db_tree_state *tsp, struct solid *existing_sp, struct dg_client_data *dgcdp);
00185 void dgo_eraseobjpath(struct dg_obj *dgop, Tcl_Interp *interp, int argc, char **argv, int noisy, int all);
00186 static void dgo_eraseobjall(struct dg_obj *dgop, Tcl_Interp *interp, register struct directory **dpp);
00187 static void dgo_eraseobj(struct dg_obj *dgop, Tcl_Interp *interp, register struct directory **dpp);
00188 void dgo_color_soltab(struct solid *hsp);
00189 static int dgo_run_rt(struct dg_obj *dgop, struct view_obj *vop);
00190 static void dgo_rt_write(struct dg_obj *dgop, struct view_obj *vop, FILE *fp, fastf_t *eye_model);
00191 static void dgo_rt_set_eye_model(struct dg_obj *dgop, struct view_obj *vop, fastf_t *eye_model);
00192 void dgo_cvt_vlblock_to_solids(struct dg_obj *dgop, Tcl_Interp *interp, struct bn_vlblock *vbp, char *name, int copy);
00193 int dgo_build_tops(Tcl_Interp *interp, struct solid *hsp, char **start, register char **end);
00194 void dgo_pr_wait_status(Tcl_Interp *interp, int status);
00195
00196 static void dgo_print_schain(struct dg_obj *dgop, Tcl_Interp *interp, int lvl);
00197 static void dgo_print_schain_vlcmds(struct dg_obj *dgop, Tcl_Interp *interp);
00198
00199 struct dg_obj HeadDGObj;
00200 static struct solid FreeSolid;
00201
00202
00203 static struct bu_cmdtab dgo_cmds[] = {
00204 {"assoc", dgo_assoc_tcl},
00205 {"autoview", dgo_autoview_tcl},
00206 {"blast", dgo_blast_tcl},
00207 {"clear", dgo_zap_tcl},
00208 #if 0
00209 {"close", dgo_close_tcl},
00210 #endif
00211 {"draw", dgo_draw_tcl},
00212 {"E", dgo_E_tcl},
00213 {"erase", dgo_erase_tcl},
00214 {"erase_all", dgo_erase_all_tcl},
00215 {"ev", dgo_ev_tcl},
00216 {"get_autoview", dgo_get_autoview_tcl},
00217 {"get_eyemodel", dgo_get_eyemodel_tcl},
00218 {"headSolid", dgo_headSolid_tcl},
00219 {"how", dgo_how_tcl},
00220 {"illum", dgo_illum_tcl},
00221 {"label", dgo_label_tcl},
00222 {"nirt", dgo_nirt_tcl},
00223 {"observer", dgo_observer_tcl},
00224 {"overlay", dgo_overlay_tcl},
00225 {"qray", dgo_qray_tcl},
00226 {"report", dgo_report_tcl},
00227 {"rt", dgo_rt_tcl},
00228 {"rtabort", dgo_rtabort_tcl},
00229 {"rtcheck", dgo_rtcheck_tcl},
00230 {"rtedge", dgo_rt_tcl},
00231 {"set_outputHandler", dgo_set_outputHandler_tcl},
00232 {"set_uplotOutputMode", dgo_set_uplotOutputMode_tcl},
00233 {"set_transparency", dgo_set_transparency_tcl},
00234 {"shaded_mode", dgo_shaded_mode_tcl},
00235 #if 0
00236 {"tol", dgo_tol_tcl},
00237 #endif
00238 {"vdraw", dgo_vdraw_tcl},
00239 {"vnirt", dgo_vnirt_tcl},
00240 {"who", dgo_who_tcl},
00241 {"zap", dgo_zap_tcl},
00242 {(char *)0, (int (*)())0}
00243 };
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254 int
00255 dgo_cmd(ClientData clientData, Tcl_Interp *interp, int argc, char **argv)
00256 {
00257 return bu_cmd(clientData, interp, argc, argv, dgo_cmds, 1);
00258 }
00259
00260 int
00261 Dgo_Init(Tcl_Interp *interp)
00262 {
00263 BU_LIST_INIT(&HeadDGObj.l);
00264 BU_LIST_INIT(&FreeSolid.l);
00265
00266 (void)Tcl_CreateCommand(interp, "dg_open", (Tcl_CmdProc *)dgo_open_tcl, (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL);
00267
00268 return TCL_OK;
00269 }
00270
00271
00272
00273
00274 void
00275 dgo_deleteProc(ClientData clientData)
00276 {
00277 struct dg_obj *dgop = (struct dg_obj *)clientData;
00278
00279
00280 bu_observer_free(&dgop->dgo_observers);
00281
00282
00283
00284
00285
00286
00287
00288
00289 bu_vls_free(&dgop->dgo_name);
00290 dgo_free_qray(dgop);
00291
00292 BU_LIST_DEQUEUE(&dgop->l);
00293 bu_free((genptr_t)dgop, "dgo_deleteProc: dgop");
00294 }
00295
00296 #if 0
00297
00298
00299
00300
00301
00302
00303 static int
00304 dgo_close_tcl(clientData, interp, argc, argv)
00305 ClientData clientData;
00306 Tcl_Interp *interp;
00307 int argc;
00308 char **argv;
00309 {
00310 struct bu_vls vls;
00311 struct dg_obj *dgop = (struct dg_obj *)clientData;
00312
00313 if (argc != 2) {
00314 bu_vls_init(&vls);
00315 bu_vls_printf(&vls, "helplib dgo_close");
00316 Tcl_Eval(interp, bu_vls_addr(&vls));
00317 bu_vls_free(&vls);
00318 return TCL_ERROR;
00319 }
00320
00321
00322 Tcl_DeleteCommand(interp, bu_vls_addr(&dgop->dgo_name));
00323
00324 return TCL_OK;
00325 }
00326 #endif
00327
00328
00329
00330
00331 struct dg_obj *
00332 dgo_open_cmd(char *oname,
00333 struct rt_wdb *wdbp)
00334 {
00335 struct dg_obj *dgop;
00336
00337 BU_GETSTRUCT(dgop,dg_obj);
00338
00339
00340 bu_vls_init(&dgop->dgo_name);
00341 bu_vls_strcpy(&dgop->dgo_name, oname);
00342 dgop->dgo_wdbp = wdbp;
00343 BU_LIST_INIT(&dgop->dgo_headSolid);
00344 BU_LIST_INIT(&dgop->dgo_headVDraw);
00345 BU_LIST_INIT(&dgop->dgo_observers.l);
00346 BU_LIST_INIT(&dgop->dgo_headRunRt.l);
00347 dgop->dgo_freeSolids = &FreeSolid;
00348 dgop->dgo_uplotOutputMode = PL_OUTPUT_MODE_BINARY;
00349
00350 dgo_init_qray(dgop);
00351
00352
00353 BU_LIST_APPEND(&HeadDGObj.l,&dgop->l);
00354
00355 return dgop;
00356 }
00357
00358
00359
00360
00361
00362
00363
00364
00365 static int
00366 dgo_open_tcl(ClientData clientData,
00367 Tcl_Interp *interp,
00368 int argc,
00369 char **argv)
00370 {
00371 struct dg_obj *dgop;
00372 struct rt_wdb *wdbp;
00373 struct bu_vls vls;
00374
00375 if (argc == 1) {
00376
00377 for (BU_LIST_FOR(dgop, dg_obj, &HeadDGObj.l))
00378 Tcl_AppendResult(interp, bu_vls_addr(&dgop->dgo_name), " ", (char *)NULL);
00379
00380 return TCL_OK;
00381 }
00382
00383 if (argc != 3) {
00384 bu_vls_init(&vls);
00385 bu_vls_printf(&vls, "helplib dgo_open");
00386 Tcl_Eval(interp, bu_vls_addr(&vls));
00387 bu_vls_free(&vls);
00388 return TCL_ERROR;
00389 }
00390
00391
00392 for (BU_LIST_FOR(wdbp, rt_wdb, &rt_g.rtg_headwdb.l)) {
00393 if (strcmp(bu_vls_addr(&wdbp->wdb_name), argv[2]) == 0)
00394 break;
00395 }
00396
00397 if (BU_LIST_IS_HEAD(wdbp, &rt_g.rtg_headwdb.l))
00398 wdbp = RT_WDB_NULL;
00399
00400
00401 (void)Tcl_DeleteCommand(interp, argv[1]);
00402
00403 dgop = dgo_open_cmd(argv[1], wdbp);
00404 (void)Tcl_CreateCommand(interp,
00405 bu_vls_addr(&dgop->dgo_name),
00406 (Tcl_CmdProc *)dgo_cmd,
00407 (ClientData)dgop,
00408 dgo_deleteProc);
00409
00410
00411 Tcl_ResetResult(interp);
00412 Tcl_AppendResult(interp, bu_vls_addr(&dgop->dgo_name), (char *)NULL);
00413
00414 return TCL_OK;
00415 }
00416
00417
00418
00419 #if 0
00420
00421 int
00422 dgo__cmd(struct dg_obj *dgop,
00423 Tcl_Interp *interp,
00424 int argc,
00425 char **argv)
00426 {
00427 }
00428
00429
00430
00431
00432
00433 static int
00434 dgo__tcl(ClientData clientData,
00435 Tcl_Interp *interp,
00436 int argc,
00437 char **argv)
00438 {
00439 struct dg_obj *dgop = (struct dg_obj *)clientData;
00440
00441 return dgo__cmd(dgop, interp, argc-1, argv+1);
00442 }
00443 #endif
00444
00445
00446
00447
00448
00449
00450
00451
00452 static int
00453 dgo_headSolid_tcl(ClientData clientData,
00454 Tcl_Interp *interp,
00455 int argc,
00456 char **argv)
00457 {
00458 struct dg_obj *dgop = (struct dg_obj *)clientData;
00459 struct bu_vls vls;
00460
00461 bu_vls_init(&vls);
00462
00463 if (argc != 2) {
00464 bu_vls_printf(&vls, "helplib_alias dgo_headSolid %s", argv[0]);
00465 Tcl_Eval(interp, bu_vls_addr(&vls));
00466 bu_vls_free(&vls);
00467 return TCL_ERROR;
00468 }
00469
00470 bu_vls_printf(&vls, "%lu", (unsigned long)&dgop->dgo_headSolid);
00471 Tcl_AppendResult(interp, bu_vls_addr(&vls), (char *)NULL);
00472 bu_vls_free(&vls);
00473 return TCL_OK;
00474 }
00475
00476 int
00477 dgo_illum_cmd(struct dg_obj *dgop,
00478 Tcl_Interp *interp,
00479 int argc,
00480 char **argv)
00481 {
00482 register struct solid *sp;
00483 struct bu_vls vls;
00484 int found = 0;
00485 int illum = 1;
00486
00487 if (argc == 3) {
00488 if (argv[1][0] == '-' && argv[1][1] == 'n')
00489 illum = 0;
00490 else
00491 goto bad;
00492
00493 --argc;
00494 ++argv;
00495 }
00496
00497 if (argc != 2)
00498 goto bad;
00499
00500 FOR_ALL_SOLIDS(sp, &dgop->dgo_headSolid) {
00501 register int i;
00502
00503 for (i = 0; i < sp->s_fullpath.fp_len; ++i) {
00504 if (*argv[1] == *DB_FULL_PATH_GET(&sp->s_fullpath,i)->d_namep &&
00505 strcmp(argv[1], DB_FULL_PATH_GET(&sp->s_fullpath,i)->d_namep) == 0) {
00506 found = 1;
00507 if (illum)
00508 sp->s_iflag = UP;
00509 else
00510 sp->s_iflag = DOWN;
00511 }
00512 }
00513 }
00514
00515 if (!found) {
00516 bu_vls_init(&vls);
00517 bu_vls_printf(&vls, "illum: %s not found", argv[1]);
00518 Tcl_AppendResult(interp, bu_vls_addr(&vls), (char *)NULL);
00519 bu_vls_free(&vls);
00520 return TCL_ERROR;
00521 }
00522
00523 return TCL_OK;
00524
00525 bad:
00526 bu_vls_init(&vls);
00527 bu_vls_printf(&vls, "helplib_alias dgo_illum %s", argv[0]);
00528 Tcl_Eval(interp, bu_vls_addr(&vls));
00529 bu_vls_free(&vls);
00530 return TCL_ERROR;
00531 }
00532
00533
00534
00535
00536
00537
00538
00539
00540 static int
00541 dgo_illum_tcl(ClientData clientData,
00542 Tcl_Interp *interp,
00543 int argc,
00544 char **argv)
00545 {
00546 struct dg_obj *dgop = (struct dg_obj *)clientData;
00547 int ret;
00548
00549 DGO_CHECK_WDBP_NULL(dgop,interp);
00550
00551 if ((ret = dgo_illum_cmd(dgop, interp, argc-1, argv+1)) == TCL_OK)
00552 dgo_notify(dgop, interp);
00553
00554 return ret;
00555 }
00556
00557 int
00558 dgo_label_cmd(struct dg_obj *dgop,
00559 Tcl_Interp *interp,
00560 int argc,
00561 char **argv)
00562 {
00563
00564
00565 return TCL_OK;
00566 }
00567
00568
00569
00570
00571
00572
00573
00574
00575 static int
00576 dgo_label_tcl(ClientData clientData, Tcl_Interp *interp, int argc, char **argv)
00577 {
00578 struct dg_obj *dgop = (struct dg_obj *)clientData;
00579
00580 DGO_CHECK_WDBP_NULL(dgop,interp);
00581
00582 return dgo_label_cmd(dgop, interp, argc-1, argv+1);
00583 }
00584
00585 int
00586 dgo_draw_cmd(struct dg_obj *dgop,
00587 Tcl_Interp *interp,
00588 int argc,
00589 char **argv,
00590 int kind)
00591 {
00592 if (argc < 2) {
00593 struct bu_vls vls;
00594
00595 bu_vls_init(&vls);
00596
00597 switch (kind) {
00598 default:
00599 case 1:
00600 bu_vls_printf(&vls, "helplib_alias dgo_draw %s", argv[0]);
00601 break;
00602 case 2:
00603 bu_vls_printf(&vls, "helplib_alias dgo_E %s", argv[0]);
00604 break;
00605 case 3:
00606 bu_vls_printf(&vls, "helplib_alias dgo_ev %s", argv[0]);
00607 break;
00608 }
00609
00610 Tcl_Eval(interp, bu_vls_addr(&vls));
00611 bu_vls_free(&vls);
00612
00613 return TCL_ERROR;
00614 }
00615
00616
00617 --argc;
00618 ++argv;
00619
00620
00621
00622
00623 dgo_eraseobjpath(dgop, interp, argc, argv, LOOKUP_QUIET, 0);
00624
00625 dgo_drawtrees(dgop, interp, argc, argv, kind, (struct dg_client_data *)0);
00626
00627 dgo_color_soltab((struct solid *)&dgop->dgo_headSolid);
00628
00629 return TCL_OK;
00630 }
00631
00632
00633
00634
00635
00636
00637
00638
00639 static int
00640 dgo_draw_tcl(ClientData clientData, Tcl_Interp *interp, int argc, char **argv)
00641 {
00642 struct dg_obj *dgop = (struct dg_obj *)clientData;
00643 int ret;
00644
00645 DGO_CHECK_WDBP_NULL(dgop,interp);
00646
00647 if ((ret = dgo_draw_cmd(dgop, interp, argc-1, argv+1, 1)) == TCL_OK)
00648 dgo_notify(dgop, interp);
00649
00650 return ret;
00651 }
00652
00653
00654
00655
00656
00657
00658
00659
00660 static int
00661 dgo_ev_tcl(ClientData clientData,
00662 Tcl_Interp *interp,
00663 int argc,
00664 char **argv)
00665 {
00666 struct dg_obj *dgop = (struct dg_obj *)clientData;
00667 int ret;
00668
00669 DGO_CHECK_WDBP_NULL(dgop,interp);
00670
00671 if ((ret = dgo_draw_cmd(dgop, interp, argc-1, argv+1, 3)) == TCL_OK)
00672 dgo_notify(dgop, interp);
00673
00674 return ret;
00675 }
00676
00677 int
00678 dgo_erase_cmd(struct dg_obj *dgop,
00679 Tcl_Interp *interp,
00680 int argc,
00681 char **argv)
00682 {
00683
00684 if (argc < 2) {
00685 struct bu_vls vls;
00686
00687 bu_vls_init(&vls);
00688 bu_vls_printf(&vls, "helplib_alias dgo_erase %s", argv[0]);
00689 Tcl_Eval(interp, bu_vls_addr(&vls));
00690 bu_vls_free(&vls);
00691 return TCL_ERROR;
00692 }
00693
00694 dgo_eraseobjpath(dgop, interp, argc-1, argv+1, LOOKUP_NOISY, 0);
00695
00696 return TCL_OK;
00697 }
00698
00699
00700
00701
00702
00703
00704
00705
00706 static int
00707 dgo_erase_tcl(ClientData clientData, Tcl_Interp *interp, int argc, char **argv)
00708 {
00709 struct dg_obj *dgop = (struct dg_obj *)clientData;
00710 int ret;
00711
00712 DGO_CHECK_WDBP_NULL(dgop,interp);
00713
00714 if ((ret = dgo_erase_cmd(dgop, interp, argc-1, argv+1)) == TCL_OK)
00715 dgo_notify(dgop, interp);
00716
00717 return ret;
00718 }
00719
00720 int
00721 dgo_erase_all_cmd(struct dg_obj *dgop,
00722 Tcl_Interp *interp,
00723 int argc,
00724 char **argv)
00725 {
00726 if (argc < 2) {
00727 struct bu_vls vls;
00728
00729 bu_vls_init(&vls);
00730 bu_vls_printf(&vls, "helplib_alias dgo_erase_all %s", argv[0]);
00731 Tcl_Eval(interp, bu_vls_addr(&vls));
00732 bu_vls_free(&vls);
00733 return TCL_ERROR;
00734 }
00735
00736 dgo_eraseobjpath(dgop, interp, argc-1, argv+1, LOOKUP_NOISY, 1);
00737
00738 return TCL_OK;
00739 }
00740
00741
00742
00743
00744
00745 static int
00746 dgo_erase_all_tcl(ClientData clientData, Tcl_Interp *interp, int argc, char **argv)
00747 {
00748 struct dg_obj *dgop = (struct dg_obj *)clientData;
00749 int ret;
00750
00751 DGO_CHECK_WDBP_NULL(dgop,interp);
00752
00753 if ((ret = dgo_erase_all_cmd(dgop, interp, argc-1, argv+1)) == TCL_OK)
00754 dgo_notify(dgop, interp);
00755
00756 return ret;
00757 }
00758
00759 struct directory **
00760 dgo_build_dpp(struct dg_obj *dgop,
00761 Tcl_Interp *interp,
00762 char *path) {
00763 register struct directory *dp;
00764 struct directory **dpp;
00765 int i;
00766 char *begin;
00767 char *end;
00768 char *newstr;
00769 char *list;
00770 int ac;
00771 const char **av;
00772 const char **av_orig = NULL;
00773 struct bu_vls vls;
00774
00775 bu_vls_init(&vls);
00776
00777
00778
00779
00780
00781 newstr = strdup(path);
00782 begin = newstr;
00783 while ((end = strchr(begin, '/')) != NULL) {
00784 *end = '\0';
00785 bu_vls_printf(&vls, "%s ", begin);
00786 begin = end + 1;
00787 }
00788 bu_vls_printf(&vls, "%s ", begin);
00789 free((void *)newstr);
00790
00791 list = bu_vls_addr(&vls);
00792
00793 if (Tcl_SplitList((Tcl_Interp *)interp, list, &ac, &av_orig) != TCL_OK) {
00794 Tcl_AppendResult(interp, "-1", (char *)NULL);
00795 bu_vls_free(&vls);
00796 return (struct directory **)NULL;
00797 }
00798
00799
00800 av = av_orig;
00801 if (*av[0] == '\0') {
00802 --ac;
00803 ++av;
00804 }
00805
00806
00807 if (*av[ac-1] == '\0')
00808 --ac;
00809
00810
00811
00812
00813
00814 dpp = bu_calloc(ac+1, sizeof(struct directory *), "dgo_build_dpp: directory pointers");
00815 for (i = 0; i < ac; ++i) {
00816 if ((dp = db_lookup(dgop->dgo_wdbp->dbip, av[i], 0)) != DIR_NULL)
00817 dpp[i] = dp;
00818 else {
00819
00820 Tcl_AppendResult(interp, "-1", (char *)NULL);
00821
00822 bu_free((genptr_t)dpp, "dgo_build_dpp: directory pointers");
00823 Tcl_Free((char *)av_orig);
00824 bu_vls_free(&vls);
00825 return (struct directory **)NULL;
00826 }
00827 }
00828
00829 dpp[i] = DIR_NULL;
00830
00831 Tcl_Free((char *)av_orig);
00832 bu_vls_free(&vls);
00833 return dpp;
00834 }
00835
00836 int
00837 dgo_how_cmd(struct dg_obj *dgop,
00838 Tcl_Interp *interp,
00839 int argc,
00840 char **argv)
00841 {
00842 register struct solid *sp;
00843 struct bu_vls vls;
00844 int i;
00845 struct directory **dpp;
00846 register struct directory **tmp_dpp;
00847 int both = 0;
00848
00849 bu_vls_init(&vls);
00850
00851 if (argc < 2 || 3 < argc) {
00852 bu_vls_printf(&vls, "helplib_alias dgo_how %s", argv[0]);
00853 Tcl_Eval(interp, bu_vls_addr(&vls));
00854 bu_vls_free(&vls);
00855 return TCL_ERROR;
00856 }
00857
00858 if (argc == 3 &&
00859 argv[1][0] == '-' &&
00860 argv[1][1] == 'b') {
00861 both = 1;
00862
00863 if ((dpp = dgo_build_dpp(dgop, interp, argv[2])) == NULL)
00864 goto good;
00865 } else {
00866 if ((dpp = dgo_build_dpp(dgop, interp, argv[1])) == NULL)
00867 goto good;
00868 }
00869
00870 FOR_ALL_SOLIDS(sp, &dgop->dgo_headSolid) {
00871 for (i = 0, tmp_dpp = dpp;
00872 i < sp->s_fullpath.fp_len && *tmp_dpp != DIR_NULL;
00873 ++i, ++tmp_dpp) {
00874 if (sp->s_fullpath.fp_names[i] != *tmp_dpp)
00875 break;
00876 }
00877
00878 if (*tmp_dpp != DIR_NULL)
00879 continue;
00880
00881
00882 if (both)
00883 bu_vls_printf(&vls, "%d %g", sp->s_dmode, sp->s_transparency);
00884 else
00885 bu_vls_printf(&vls, "%d", sp->s_dmode);
00886
00887 Tcl_AppendResult(interp, bu_vls_addr(&vls), (char *)NULL);
00888 goto good;
00889 }
00890
00891
00892 Tcl_AppendResult(interp, "-1", (char *)NULL);
00893
00894 good:
00895 if (dpp != (struct directory **)NULL)
00896 bu_free((genptr_t)dpp, "dgo_how_cmd: directory pointers");
00897 bu_vls_free(&vls);
00898
00899 return TCL_OK;
00900 }
00901
00902
00903
00904
00905
00906
00907
00908 static int
00909 dgo_how_tcl(clientData, interp, argc, argv)
00910 ClientData clientData;
00911 Tcl_Interp *interp;
00912 int argc;
00913 char **argv;
00914 {
00915 struct dg_obj *dgop = (struct dg_obj *)clientData;
00916
00917 DGO_CHECK_WDBP_NULL(dgop,interp);
00918 return dgo_how_cmd(dgop, interp, argc-1, argv+1);
00919 }
00920
00921 int
00922 dgo_who_cmd(struct dg_obj *dgop,
00923 Tcl_Interp *interp,
00924 int argc,
00925 char **argv)
00926 {
00927 register struct solid *sp;
00928 int skip_real, skip_phony;
00929
00930 if (argc < 1 || 2 < argc) {
00931 struct bu_vls vls;
00932
00933 bu_vls_init(&vls);
00934 bu_vls_printf(&vls, "helplib_alias dgo_who %s", argv[0]);
00935 Tcl_Eval(interp, bu_vls_addr(&vls));
00936 bu_vls_free(&vls);
00937 return TCL_ERROR;
00938 }
00939
00940 skip_real = 0;
00941 skip_phony = 1;
00942 if (argc == 2) {
00943 switch (argv[1][0]) {
00944 case 'b':
00945 skip_real = 0;
00946 skip_phony = 0;
00947 break;
00948 case 'p':
00949 skip_real = 1;
00950 skip_phony = 0;
00951 break;
00952 case 'r':
00953 skip_real = 0;
00954 skip_phony = 1;
00955 break;
00956 default:
00957 Tcl_AppendResult(interp, "dgo_who: argument not understood\n", (char *)NULL);
00958 return TCL_ERROR;
00959 }
00960 }
00961
00962
00963
00964
00965
00966 FOR_ALL_SOLIDS(sp, &dgop->dgo_headSolid)
00967 sp->s_flag = DOWN;
00968 FOR_ALL_SOLIDS(sp, &dgop->dgo_headSolid) {
00969 register struct solid *forw;
00970
00971 if (sp->s_flag == UP)
00972 continue;
00973 if (FIRST_SOLID(sp)->d_addr == RT_DIR_PHONY_ADDR) {
00974 if (skip_phony) continue;
00975 } else {
00976 if (skip_real) continue;
00977 }
00978 Tcl_AppendResult(interp, FIRST_SOLID(sp)->d_namep, " ", (char *)NULL);
00979 sp->s_flag = UP;
00980 FOR_REST_OF_SOLIDS(forw, sp, &dgop->dgo_headSolid){
00981 if (FIRST_SOLID(forw) == FIRST_SOLID(sp))
00982 forw->s_flag = UP;
00983 }
00984 }
00985 FOR_ALL_SOLIDS(sp, &dgop->dgo_headSolid)
00986 sp->s_flag = DOWN;
00987
00988 return TCL_OK;
00989 }
00990
00991
00992
00993
00994
00995
00996
00997 static int
00998 dgo_who_tcl(ClientData clientData, Tcl_Interp *interp, int argc, char **argv)
00999 {
01000 struct dg_obj *dgop = (struct dg_obj *)clientData;
01001
01002 DGO_CHECK_WDBP_NULL(dgop,interp);
01003 return dgo_who_cmd(dgop, interp, argc-1, argv+1);
01004 }
01005
01006 static void
01007 dgo_overlay(struct dg_obj *dgop, Tcl_Interp *interp, FILE *fp, char *name, double char_size)
01008 {
01009 int ret;
01010 struct rt_vlblock *vbp;
01011
01012 vbp = rt_vlblock_init();
01013 ret = rt_uplot_to_vlist(vbp, fp, char_size, dgop->dgo_uplotOutputMode);
01014 fclose(fp);
01015
01016 if (ret < 0) {
01017 rt_vlblock_free(vbp);
01018 return;
01019 }
01020
01021 dgo_cvt_vlblock_to_solids(dgop, interp, vbp, name, 0);
01022 rt_vlblock_free(vbp);
01023 }
01024
01025 int
01026 dgo_overlay_cmd(struct dg_obj *dgop,
01027 Tcl_Interp *interp,
01028 int argc,
01029 char **argv)
01030 {
01031 FILE *fp;
01032 double char_size;
01033 char *name;
01034
01035 if (argc < 3 || 4 < argc) {
01036 struct bu_vls vls;
01037
01038 bu_vls_init(&vls);
01039 bu_vls_printf(&vls, "helplib_alias dgo_overlay %s", argv[0]);
01040 Tcl_Eval(interp, bu_vls_addr(&vls));
01041 bu_vls_free(&vls);
01042
01043 return TCL_ERROR;
01044 }
01045
01046 if (sscanf(argv[2], "%lf", &char_size) != 1) {
01047 Tcl_AppendResult(interp, "dgo_overlay: bad character size - ",
01048 argv[2], "\n", (char *)NULL);
01049 return TCL_ERROR;
01050 }
01051
01052 if (argc == 3)
01053 name = "_PLOT_OVERLAY_";
01054 else
01055 name = argv[3];
01056
01057 #if defined(_WIN32) && !defined(__CYGWIN__)
01058 # define PL_MODE "rb"
01059 #else
01060 # define PL_MODE "r"
01061 #endif
01062 if ((fp = fopen(argv[1], PL_MODE)) == NULL) {
01063 Tcl_AppendResult(interp, "dgo_overlay: failed to open file - ",
01064 argv[1], "\n", (char *)NULL);
01065
01066 return TCL_ERROR;
01067 }
01068
01069 dgo_overlay(dgop, interp, fp, name, char_size);
01070 return TCL_OK;
01071 }
01072
01073
01074
01075
01076
01077 static int
01078 dgo_overlay_tcl(ClientData clientData, Tcl_Interp *interp, int argc, char **argv)
01079 {
01080 struct dg_obj *dgop = (struct dg_obj *)clientData;
01081 int ret;
01082
01083 DGO_CHECK_WDBP_NULL(dgop,interp);
01084
01085 if ((ret = dgo_overlay_cmd(dgop, interp, argc-1, argv+1)) == TCL_OK)
01086 dgo_notify(dgop, interp);
01087
01088 return ret;
01089 }
01090
01091 void
01092 dgo_autoview(struct dg_obj *dgop,
01093 struct view_obj *vop,
01094 Tcl_Interp *interp)
01095 {
01096 register struct solid *sp;
01097 vect_t min, max;
01098 vect_t minus, plus;
01099 vect_t center;
01100 vect_t radial;
01101
01102 VSETALL(min, INFINITY);
01103 VSETALL(max, -INFINITY);
01104
01105 FOR_ALL_SOLIDS(sp, &dgop->dgo_headSolid) {
01106 minus[X] = sp->s_center[X] - sp->s_size;
01107 minus[Y] = sp->s_center[Y] - sp->s_size;
01108 minus[Z] = sp->s_center[Z] - sp->s_size;
01109 VMIN(min, minus);
01110 plus[X] = sp->s_center[X] + sp->s_size;
01111 plus[Y] = sp->s_center[Y] + sp->s_size;
01112 plus[Z] = sp->s_center[Z] + sp->s_size;
01113 VMAX(max, plus);
01114 }
01115
01116 if (BU_LIST_IS_EMPTY(&dgop->dgo_headSolid)) {
01117
01118 VSETALL(center, 0.0);
01119 VSETALL(radial, 1000.0);
01120 } else {
01121 VADD2SCALE(center, max, min, 0.5);
01122 VSUB2(radial, max, center);
01123 }
01124
01125 if (VNEAR_ZERO(radial , SQRT_SMALL_FASTF))
01126 VSETALL(radial , 1.0);
01127
01128 MAT_IDN(vop->vo_center);
01129 MAT_DELTAS(vop->vo_center, -center[X], -center[Y], -center[Z]);
01130 vop->vo_scale = radial[X];
01131 V_MAX(vop->vo_scale, radial[Y]);
01132 V_MAX(vop->vo_scale, radial[Z]);
01133
01134 vop->vo_size = 2.0 * vop->vo_scale;
01135 vop->vo_invSize = 1.0 / vop->vo_size;
01136 vo_update(vop, interp, 1);
01137 }
01138
01139 int
01140 dgo_autoview_cmd(struct dg_obj *dgop,
01141 struct view_obj *vop,
01142 Tcl_Interp *interp,
01143 int argc,
01144 char **argv)
01145 {
01146 if (argc != 2) {
01147 struct bu_vls vls;
01148
01149 bu_vls_init(&vls);
01150 bu_vls_printf(&vls, "helplib_alias dgo_autoview %s", argv[0]);
01151 Tcl_Eval(interp, bu_vls_addr(&vls));
01152 bu_vls_free(&vls);
01153 return TCL_ERROR;
01154 }
01155
01156 DGO_CHECK_WDBP_NULL(dgop,interp);
01157 dgo_autoview(dgop, vop, interp);
01158
01159 return TCL_OK;
01160 }
01161
01162
01163
01164
01165
01166 static int
01167 dgo_autoview_tcl(ClientData clientData,
01168 Tcl_Interp *interp,
01169 int argc,
01170 char **argv)
01171 {
01172 struct dg_obj *dgop = (struct dg_obj *)clientData;
01173 struct view_obj *vop;
01174
01175 if (argc != 3) {
01176 struct bu_vls vls;
01177
01178 bu_vls_init(&vls);
01179 bu_vls_printf(&vls, "helplib_alias dgo_autoview %s", argv[0]);
01180 Tcl_Eval(interp, bu_vls_addr(&vls));
01181 bu_vls_free(&vls);
01182 return TCL_ERROR;
01183 }
01184
01185 #if 0
01186 DGO_CHECK_WDBP_NULL(dgop,interp);
01187 #endif
01188
01189
01190 for (BU_LIST_FOR(vop, view_obj, &HeadViewObj.l)) {
01191 if (strcmp(bu_vls_addr(&vop->vo_name), argv[2]) == 0)
01192 break;
01193 }
01194
01195 if (BU_LIST_IS_HEAD(vop, &HeadViewObj.l)) {
01196 Tcl_AppendResult(interp, "dgo_autoview: bad view object - ", argv[2],
01197 "\n", (char *)NULL);
01198 return TCL_ERROR;
01199 }
01200
01201 return dgo_autoview_cmd(dgop, vop, interp, argc-1, argv+1);
01202 }
01203
01204 int
01205 dgo_get_autoview_cmd(struct dg_obj *dgop,
01206 Tcl_Interp *interp,
01207 int argc,
01208 char **argv)
01209 {
01210 struct bu_vls vls;
01211 register struct solid *sp;
01212 vect_t min, max;
01213 vect_t minus, plus;
01214 vect_t center;
01215 vect_t radial;
01216 int pflag = 0;
01217 register int c;
01218
01219 if (argc < 1 || 2 < argc) {
01220 struct bu_vls vls;
01221
01222 bu_vls_init(&vls);
01223 bu_vls_printf(&vls, "helplib_alias dgo_get_autoview %s", argv[0]);
01224 Tcl_Eval(interp, bu_vls_addr(&vls));
01225 bu_vls_free(&vls);
01226 return TCL_ERROR;
01227 }
01228
01229
01230 bu_optind = 1;
01231 while ((c = bu_getopt(argc, argv, "p")) != EOF) {
01232 switch (c) {
01233 case 'p':
01234 pflag = 1;
01235 break;
01236 default: {
01237 struct bu_vls vls;
01238
01239 bu_vls_init(&vls);
01240 bu_vls_printf(&vls, "helplib_alias dgo_get_autoview %s", argv[0]);
01241 Tcl_Eval(interp, bu_vls_addr(&vls));
01242 bu_vls_free(&vls);
01243 return TCL_ERROR;
01244 }
01245 }
01246 }
01247 argc -= bu_optind;
01248 argv += bu_optind;
01249
01250 DGO_CHECK_WDBP_NULL(dgop,interp);
01251
01252 VSETALL(min, INFINITY);
01253 VSETALL(max, -INFINITY);
01254
01255 FOR_ALL_SOLIDS(sp, &dgop->dgo_headSolid) {
01256
01257 if (!pflag &&
01258 sp->s_fullpath.fp_names != (struct directory **)0 &&
01259 sp->s_fullpath.fp_names[0] != (struct directory *)0 &&
01260 sp->s_fullpath.fp_names[0]->d_addr == RT_DIR_PHONY_ADDR)
01261 continue;
01262
01263 minus[X] = sp->s_center[X] - sp->s_size;
01264 minus[Y] = sp->s_center[Y] - sp->s_size;
01265 minus[Z] = sp->s_center[Z] - sp->s_size;
01266 VMIN(min, minus);
01267 plus[X] = sp->s_center[X] + sp->s_size;
01268 plus[Y] = sp->s_center[Y] + sp->s_size;
01269 plus[Z] = sp->s_center[Z] + sp->s_size;
01270 VMAX(max, plus);
01271 }
01272
01273 if (BU_LIST_IS_EMPTY(&dgop->dgo_headSolid)) {
01274
01275 VSETALL(center, 0.0);
01276 VSETALL(radial, 1000.0);
01277 } else {
01278 VADD2SCALE(center, max, min, 0.5);
01279 VSUB2(radial, max, center);
01280 }
01281
01282 if (VNEAR_ZERO(radial , SQRT_SMALL_FASTF))
01283 VSETALL(radial , 1.0);
01284
01285 VSCALE(center, center, dgop->dgo_wdbp->dbip->dbi_base2local);
01286 radial[X] *= dgop->dgo_wdbp->dbip->dbi_base2local;
01287
01288 bu_vls_init(&vls);
01289 bu_vls_printf(&vls, "center {%g %g %g} size %g", V3ARGS(center), radial[X] * 2.0);
01290 Tcl_AppendResult(interp, bu_vls_addr(&vls), (char *)NULL);
01291 bu_vls_free(&vls);
01292
01293 return TCL_OK;
01294 }
01295
01296
01297
01298
01299
01300 static int
01301 dgo_get_autoview_tcl(ClientData clientData,
01302 Tcl_Interp *interp,
01303 int argc,
01304 char **argv)
01305 {
01306 struct dg_obj *dgop = (struct dg_obj *)clientData;
01307
01308 return dgo_get_autoview_cmd(dgop, interp, argc-1, argv+1);
01309 }
01310
01311
01312
01313
01314 int
01315 dgo_get_eyemodel_cmd(struct dg_obj *dgop,
01316 Tcl_Interp *interp,
01317 int argc,
01318 char **argv)
01319 {
01320 struct bu_vls vls;
01321 struct view_obj * vop;
01322 quat_t quat;
01323 vect_t eye_model;
01324
01325 if (argc != 2) {
01326 struct bu_vls vls;
01327
01328 bu_vls_init(&vls);
01329 bu_vls_printf(&vls, "helplib_alias dgo_get_eyemodel %s", argv[0]);
01330 Tcl_Eval(interp, bu_vls_addr(&vls));
01331 bu_vls_free(&vls);
01332 return TCL_ERROR;
01333 }
01334
01335
01336
01337
01338 for (BU_LIST_FOR(vop, view_obj, &HeadViewObj.l)) {
01339 if (strcmp(bu_vls_addr(&vop->vo_name), argv[1]) == 0)
01340 break;
01341 }
01342
01343 if (BU_LIST_IS_HEAD(vop, &HeadViewObj.l)) {
01344 Tcl_AppendResult(interp,
01345 "dgo_get_eyemodel: bad view object - ",
01346 argv[2],
01347 "\n", (char *)NULL);
01348 return TCL_ERROR;
01349 }
01350
01351 dgo_rt_set_eye_model(dgop, vop, eye_model);
01352
01353 bu_vls_init(&vls);
01354
01355 quat_mat2quat(quat, vop->vo_rotation );
01356
01357 bu_vls_printf(&vls, "viewsize %.15e;\n", vop->vo_size);
01358 bu_vls_printf(&vls, "orientation %.15e %.15e %.15e %.15e;\n",
01359 V4ARGS(quat));
01360 bu_vls_printf(&vls, "eye_pt %.15e %.15e %.15e;\n",
01361 eye_model[X], eye_model[Y], eye_model[Z] );
01362 Tcl_AppendResult(interp, bu_vls_addr(&vls), NULL);
01363 bu_vls_free(&vls);
01364 return TCL_OK;
01365 }
01366
01367
01368
01369
01370
01371 static int
01372 dgo_get_eyemodel_tcl(ClientData clientData,
01373 Tcl_Interp *interp,
01374 int argc,
01375 char **argv)
01376 {
01377 struct dg_obj *dgop = (struct dg_obj *)clientData;
01378 return dgo_get_eyemodel_cmd(dgop, interp, argc-1, argv+1);
01379 }
01380
01381 int
01382 dgo_rt_cmd(struct dg_obj *dgop,
01383 struct view_obj *vop,
01384 Tcl_Interp *interp,
01385 int argc,
01386 char **argv)
01387 {
01388 register char **vp;
01389 register int i;
01390 char pstring[32];
01391
01392 if (argc < 1 || MAXARGS < argc) {
01393 struct bu_vls vls;
01394
01395 bu_vls_init(&vls);
01396 bu_vls_printf(&vls, "helplib_alias dgo_%s %s", argv[0], argv[0]);
01397 Tcl_Eval(interp, bu_vls_addr(&vls));
01398 bu_vls_free(&vls);
01399 return TCL_ERROR;
01400 }
01401
01402 vp = &dgop->dgo_rt_cmd[0];
01403 *vp++ = argv[0];
01404 *vp++ = "-M";
01405
01406 if (vop->vo_perspective > 0) {
01407 (void)sprintf(pstring, "-p%g", vop->vo_perspective);
01408 *vp++ = pstring;
01409 }
01410
01411 for (i=1; i < argc; i++) {
01412 if (argv[i][0] == '-' && argv[i][1] == '-' &&
01413 argv[i][2] == '\0') {
01414 ++i;
01415 break;
01416 }
01417 *vp++ = argv[i];
01418 }
01419
01420 #ifdef _WIN32
01421 {
01422 char buf[512];
01423
01424 sprintf(buf, "\"%s\"", dgop->dgo_wdbp->dbip->dbi_filename);
01425 *vp++ = buf;
01426 }
01427 #else
01428 *vp++ = dgop->dgo_wdbp->dbip->dbi_filename;
01429 #endif
01430
01431
01432
01433
01434
01435
01436 if (i == argc) {
01437 dgop->dgo_rt_cmd_len = vp - dgop->dgo_rt_cmd;
01438 dgop->dgo_rt_cmd_len += dgo_build_tops(interp,
01439 (struct solid *)&dgop->dgo_headSolid,
01440 vp,
01441 &dgop->dgo_rt_cmd[MAXARGS]);
01442 } else {
01443 while (i < argc)
01444 *vp++ = argv[i++];
01445 *vp = 0;
01446 vp = &dgop->dgo_rt_cmd[0];
01447 while (*vp)
01448 Tcl_AppendResult(interp, *vp++, " ", (char *)NULL);
01449
01450 Tcl_AppendResult(interp, "\n", (char *)NULL);
01451 }
01452 (void)dgo_run_rt(dgop, vop);
01453
01454 return TCL_OK;
01455 }
01456
01457
01458
01459
01460
01461 static int
01462 dgo_rt_tcl(ClientData clientData, Tcl_Interp *interp, int argc, char **argv)
01463 {
01464 struct dg_obj *dgop = (struct dg_obj *)clientData;
01465 struct view_obj *vop;
01466
01467 if (argc < 3 || MAXARGS < argc) {
01468 struct bu_vls vls;
01469
01470 bu_vls_init(&vls);
01471 bu_vls_printf(&vls, "helplib_alias dgo_%s %s", argv[0], argv[0]);
01472 Tcl_Eval(interp, bu_vls_addr(&vls));
01473 bu_vls_free(&vls);
01474 return TCL_ERROR;
01475 }
01476
01477 DGO_CHECK_WDBP_NULL(dgop,interp);
01478
01479
01480 for (BU_LIST_FOR(vop, view_obj, &HeadViewObj.l)) {
01481 if (strcmp(bu_vls_addr(&vop->vo_name), argv[2]) == 0)
01482 break;
01483 }
01484
01485 if (BU_LIST_IS_HEAD(vop, &HeadViewObj.l)) {
01486 Tcl_AppendResult(interp, "dgo_rt: bad view object - ", argv[2],
01487 "\n", (char *)NULL);
01488 return TCL_ERROR;
01489 }
01490
01491
01492 argv[2] = argv[1];
01493 return dgo_rt_cmd(dgop, vop, interp, argc-2, argv+2);
01494 }
01495
01496 int
01497 dgo_vdraw_cmd(struct dg_obj *dgop,
01498 Tcl_Interp *interp,
01499 int argc,
01500 char **argv)
01501 {
01502 return bu_cmd((ClientData)dgop, interp, argc-1, argv+1, vdraw_cmds, 0);
01503 }
01504
01505
01506
01507
01508
01509 static int
01510 dgo_vdraw_tcl(ClientData clientData,
01511 Tcl_Interp *interp,
01512 int argc,
01513 char **argv)
01514 {
01515 struct dg_obj *dgop = (struct dg_obj *)clientData;
01516
01517 DGO_CHECK_WDBP_NULL(dgop,interp);
01518
01519 return dgo_vdraw_cmd(dgop, interp, argc-1, argv+1);
01520 }
01521
01522 void
01523 dgo_zap_cmd(struct dg_obj *dgop,
01524 Tcl_Interp *interp)
01525 {
01526 register struct solid *sp;
01527 register struct solid *nsp;
01528 struct directory *dp;
01529
01530 sp = BU_LIST_NEXT(solid, &dgop->dgo_headSolid);
01531 while (BU_LIST_NOT_HEAD(sp, &dgop->dgo_headSolid)) {
01532 dp = FIRST_SOLID(sp);
01533 RT_CK_DIR(dp);
01534 if (dp->d_addr == RT_DIR_PHONY_ADDR) {
01535 if (db_dirdelete(dgop->dgo_wdbp->dbip, dp) < 0) {
01536 Tcl_AppendResult(interp, "dgo_zap: db_dirdelete failed\n", (char *)NULL);
01537 }
01538 }
01539
01540 nsp = BU_LIST_PNEXT(solid, sp);
01541 BU_LIST_DEQUEUE(&sp->l);
01542 FREE_SOLID(sp,&FreeSolid.l);
01543 sp = nsp;
01544 }
01545 }
01546
01547
01548
01549
01550
01551 static int
01552 dgo_zap_tcl(ClientData clientData,
01553 Tcl_Interp *interp,
01554 int argc,
01555 char **argv)
01556 {
01557 struct dg_obj *dgop = (struct dg_obj *)clientData;
01558
01559 DGO_CHECK_WDBP_NULL(dgop,interp);
01560
01561 if (argc != 2) {
01562 struct bu_vls vls;
01563
01564 bu_vls_init(&vls);
01565 bu_vls_printf(&vls, "helplib_alias dgo_%s %s", argv[1], argv[1]);
01566 Tcl_Eval(interp, bu_vls_addr(&vls));
01567 bu_vls_free(&vls);
01568 return TCL_ERROR;
01569 }
01570
01571 dgo_zap_cmd(dgop, interp);
01572 dgo_notify(dgop, interp);
01573
01574 return TCL_OK;
01575 }
01576
01577 int
01578 dgo_blast_cmd(struct dg_obj *dgop,
01579 Tcl_Interp *interp,
01580 int argc,
01581 char **argv)
01582 {
01583
01584 dgo_zap_cmd(dgop, interp);
01585
01586
01587 return dgo_draw_cmd(dgop, interp, argc, argv, 1);
01588 }
01589
01590
01591
01592
01593
01594 static int
01595 dgo_blast_tcl(ClientData clientData, Tcl_Interp *interp, int argc, char **argv)
01596 {
01597 struct dg_obj *dgop = (struct dg_obj *)clientData;
01598 int ret;
01599
01600 DGO_CHECK_WDBP_NULL(dgop,interp);
01601
01602 if (argc < 3) {
01603 struct bu_vls vls;
01604
01605 bu_vls_init(&vls);
01606 bu_vls_printf(&vls, "helplib_alias dgo_blast %s", argv[0]);
01607 Tcl_Eval(interp, bu_vls_addr(&vls));
01608 bu_vls_free(&vls);
01609
01610 return TCL_ERROR;
01611 }
01612
01613 if ((ret = dgo_blast_cmd(dgop, interp, argc-1, argv+1)) == TCL_OK)
01614 dgo_notify(dgop, interp);
01615
01616 return ret;
01617 }
01618
01619 #if 0
01620
01621
01622
01623
01624
01625
01626
01627
01628
01629
01630
01631 static int
01632 dgo_tol_tcl(clientData, interp, argc, argv)
01633 ClientData clientData;
01634 Tcl_Interp *interp;
01635 int argc;
01636 char **argv;
01637 {
01638 struct dg_obj *dgop = (struct dg_obj *)clientData;
01639 struct bu_vls vls;
01640 double f;
01641
01642 DGO_CHECK_WDBP_NULL(dgop,interp);
01643
01644 if (argc < 2 || 4 < argc){
01645 bu_vls_init(&vls);
01646 bu_vls_printf(&vls, "helplib_alias dgo_tol %s", argv[0]);
01647 Tcl_Eval(interp, bu_vls_addr(&vls));
01648 bu_vls_free(&vls);
01649 return TCL_ERROR;
01650 }
01651
01652
01653 if (argc == 2) {
01654 Tcl_AppendResult(interp, "Current tolerance settings are:\n", (char *)NULL);
01655 Tcl_AppendResult(interp, "Tesselation tolerances:\n", (char *)NULL );
01656
01657 if (dgop->dgo_ttol.abs > 0.0) {
01658 bu_vls_init(&vls);
01659 bu_vls_printf(&vls, "\tabs %g mm\n", dgop->dgo_ttol.abs);
01660 Tcl_AppendResult(interp, bu_vls_addr(&vls), (char *)NULL);
01661 bu_vls_free(&vls);
01662 } else {
01663 Tcl_AppendResult(interp, "\tabs None\n", (char *)NULL);
01664 }
01665
01666 if (dgop->dgo_ttol.rel > 0.0) {
01667 bu_vls_init(&vls);
01668 bu_vls_printf(&vls, "\trel %g (%g%%)\n",
01669 dgop->dgo_ttol.rel, dgop->dgo_ttol.rel * 100.0 );
01670 Tcl_AppendResult(interp, bu_vls_addr(&vls), (char *)NULL);
01671 bu_vls_free(&vls);
01672 } else {
01673 Tcl_AppendResult(interp, "\trel None\n", (char *)NULL);
01674 }
01675
01676 if (dgop->dgo_ttol.norm > 0.0) {
01677 int deg, min;
01678 double sec;
01679
01680 bu_vls_init(&vls);
01681 sec = dgop->dgo_ttol.norm * bn_radtodeg;
01682 deg = (int)(sec);
01683 sec = (sec - (double)deg) * 60;
01684 min = (int)(sec);
01685 sec = (sec - (double)min) * 60;
01686
01687 bu_vls_printf(&vls, "\tnorm %g degrees (%d deg %d min %g sec)\n",
01688 dgop->dgo_ttol.norm * bn_radtodeg, deg, min, sec);
01689 Tcl_AppendResult(interp, bu_vls_addr(&vls), (char *)NULL);
01690 bu_vls_free(&vls);
01691 } else {
01692 Tcl_AppendResult(interp, "\tnorm None\n", (char *)NULL);
01693 }
01694
01695 bu_vls_init(&vls);
01696 bu_vls_printf(&vls,"Calculational tolerances:\n");
01697 bu_vls_printf(&vls,
01698 "\tdistance = %g mm\n\tperpendicularity = %g (cosine of %g degrees)\n",
01699 dgop->dgo_tol.dist, dgop->dgo_tol.perp,
01700 acos(dgop->dgo_tol.perp)*bn_radtodeg);
01701 Tcl_AppendResult(interp, bu_vls_addr(&vls), (char *)NULL);
01702 bu_vls_free(&vls);
01703
01704 return TCL_OK;
01705 }
01706
01707
01708 if (argc == 3) {
01709 int status = TCL_OK;
01710
01711 bu_vls_init(&vls);
01712
01713 switch (argv[2][0]) {
01714 case 'a':
01715 if (dgop->dgo_ttol.abs > 0.0)
01716 bu_vls_printf(&vls, "%g", dgop->dgo_ttol.abs);
01717 else
01718 bu_vls_printf(&vls, "None");
01719 break;
01720 case 'r':
01721 if (dgop->dgo_ttol.rel > 0.0)
01722 bu_vls_printf(&vls, "%g", dgop->dgo_ttol.rel);
01723 else
01724 bu_vls_printf(&vls, "None");
01725 break;
01726 case 'n':
01727 if (dgop->dgo_ttol.norm > 0.0)
01728 bu_vls_printf(&vls, "%g", dgop->dgo_ttol.norm);
01729 else
01730 bu_vls_printf(&vls, "None");
01731 break;
01732 case 'd':
01733 bu_vls_printf(&vls, "%g", dgop->dgo_tol.dist);
01734 break;
01735 case 'p':
01736 bu_vls_printf(&vls, "%g", dgop->dgo_tol.perp);
01737 break;
01738 default:
01739 bu_vls_printf(&vls, "unrecognized tolerance type - %s\n", argv[2]);
01740 status = TCL_ERROR;
01741 break;
01742 }
01743
01744 Tcl_AppendResult(interp, bu_vls_addr(&vls), (char *)NULL);
01745 bu_vls_free(&vls);
01746 return status;
01747 }
01748
01749
01750 if (sscanf(argv[3], "%lf", &f) != 1) {
01751 bu_vls_init(&vls);
01752 bu_vls_printf(&vls, "bad tolerance - %s\n", argv[3]);
01753 Tcl_AppendResult(interp, bu_vls_addr(&vls), (char *)NULL);
01754 bu_vls_free(&vls);
01755
01756 return TCL_ERROR;
01757 }
01758
01759 switch (argv[2][0]) {
01760 case 'a':
01761
01762 if (f <= 0.0)
01763 dgop->dgo_ttol.abs = 0.0;
01764 else
01765 dgop->dgo_ttol.abs = f;
01766 break;
01767 case 'r':
01768 if (f < 0.0 || f >= 1.0) {
01769 Tcl_AppendResult(interp,
01770 "relative tolerance must be between 0 and 1, not changed\n",
01771 (char *)NULL);
01772 return TCL_ERROR;
01773 }
01774
01775 dgop->dgo_ttol.rel = f;
01776 break;
01777 case 'n':
01778
01779 if (f < 0.0 || f > 90.0) {
01780 Tcl_AppendResult(interp,
01781 "Normal tolerance must be in positive degrees, < 90.0\n",
01782 (char *)NULL);
01783 return TCL_ERROR;
01784 }
01785
01786 dgop->dgo_ttol.norm = f * bn_degtorad;
01787 break;
01788 case 'd':
01789
01790 if (f < 0.0) {
01791 Tcl_AppendResult(interp,
01792 "Calculational distance tolerance must be positive\n",
01793 (char *)NULL);
01794 return TCL_ERROR;
01795 }
01796 dgop->dgo_tol.dist = f;
01797 dgop->dgo_tol.dist_sq = dgop->dgo_tol.dist * dgop->dgo_tol.dist;
01798 break;
01799 case 'p':
01800
01801 if (f < 0.0 || f > 1.0) {
01802 Tcl_AppendResult(interp,
01803 "Calculational perpendicular tolerance must be from 0 to 1\n",
01804 (char *)NULL);
01805 return TCL_ERROR;
01806 }
01807 dgop->dgo_tol.perp = f;
01808 dgop->dgo_tol.para = 1.0 - f;
01809 break;
01810 default:
01811 bu_vls_init(&vls);
01812 bu_vls_printf(&vls, "unrecognized tolerance type - %s\n", argv[2]);
01813 Tcl_AppendResult(interp, bu_vls_addr(&vls), (char *)NULL);
01814 bu_vls_free(&vls);
01815
01816 return TCL_ERROR;
01817 }
01818
01819 return TCL_OK;
01820 }
01821 #endif
01822
01823 struct rtcheck {
01824 #ifdef _WIN32
01825 HANDLE fd;
01826 HANDLE hProcess;
01827 DWORD pid;
01828 #ifdef TCL_OK
01829 Tcl_Channel chan;
01830 #else
01831 genptr_t chan;
01832 #endif
01833 #else
01834 int fd;
01835 int pid;
01836 #endif
01837 FILE *fp;
01838 struct bn_vlblock *vbp;
01839 struct bu_list *vhead;
01840 double csize;
01841 struct dg_obj *dgop;
01842 Tcl_Interp *interp;
01843 };
01844
01845 struct rtcheck_output {
01846 #ifdef _WIN32
01847 HANDLE fd;
01848 Tcl_Channel chan;
01849 #else
01850 int fd;
01851 #endif
01852 struct dg_obj *dgop;
01853 Tcl_Interp *interp;
01854 };
01855
01856
01857
01858
01859
01860
01861
01862
01863
01864
01865 static void
01866 dgo_wait_status(Tcl_Interp *interp, int status)
01867 {
01868 int sig = status & 0x7f;
01869 int core = status & 0x80;
01870 int ret = status >> 8;
01871 struct bu_vls tmp_vls;
01872
01873 if (status == 0) {
01874 Tcl_AppendResult(interp, "Normal exit\n", (char *)NULL);
01875 return;
01876 }
01877
01878 bu_vls_init(&tmp_vls);
01879 bu_vls_printf(&tmp_vls, "Abnormal exit x%x", status);
01880
01881 if (core)
01882 bu_vls_printf(&tmp_vls, ", core dumped");
01883
01884 if (sig)
01885 bu_vls_printf(&tmp_vls, ", terminating signal = %d", sig);
01886 else
01887 bu_vls_printf(&tmp_vls, ", return (exit) code = %d", ret);
01888
01889 Tcl_AppendResult(interp, bu_vls_addr(&tmp_vls), "\n", (char *)NULL);
01890 bu_vls_free(&tmp_vls);
01891 }
01892
01893 #ifndef _WIN32
01894 static void
01895 dgo_rtcheck_vector_handler(ClientData clientData, int mask)
01896 {
01897 int value;
01898 struct solid *sp;
01899 struct rtcheck *rtcp = (struct rtcheck *)clientData;
01900
01901
01902 if ((value = getc(rtcp->fp)) == EOF) {
01903 int retcode;
01904 int rpid;
01905
01906 Tcl_DeleteFileHandler(rtcp->fd);
01907 fclose(rtcp->fp);
01908
01909 FOR_ALL_SOLIDS(sp, &rtcp->dgop->dgo_headSolid)
01910 sp->s_flag = DOWN;
01911
01912
01913 dgo_cvt_vlblock_to_solids(rtcp->dgop, rtcp->interp, rtcp->vbp, "OVERLAPS", 0);
01914 rt_vlblock_free(rtcp->vbp);
01915
01916
01917 while ((rpid = wait(&retcode)) != rtcp->pid && rpid != -1)
01918 dgo_wait_status(rtcp->interp, retcode);
01919
01920 dgo_notify(rtcp->dgop, rtcp->interp);
01921
01922
01923 bu_free((genptr_t)rtcp, "dgo_rtcheck_vector_handler: rtcp");
01924
01925 return;
01926 }
01927
01928 (void)rt_process_uplot_value(&rtcp->vhead,
01929 rtcp->vbp,
01930 rtcp->fp,
01931 value,
01932 rtcp->csize,
01933 rtcp->dgop->dgo_uplotOutputMode);
01934 }
01935
01936 static void
01937 dgo_rtcheck_output_handler(ClientData clientData, int mask)
01938 {
01939 int count;
01940 char line[RT_MAXLINE] = {0};
01941 struct rtcheck_output *rtcop = (struct rtcheck_output *)clientData;
01942
01943
01944 count = read((int)rtcop->fd, line, RT_MAXLINE);
01945 if (count <= 0) {
01946 if (count < 0) {
01947 perror("READ ERROR");
01948 }
01949 Tcl_DeleteFileHandler(rtcop->fd);
01950 close(rtcop->fd);
01951
01952 bu_free((genptr_t)rtcop, "dgo_rtcheck_output_handler: rtcop");
01953 return;
01954 }
01955
01956 line[count] = '\0';
01957 if (rtcop->dgop->dgo_outputHandler != NULL) {
01958 struct bu_vls vls;
01959
01960 bu_vls_init(&vls);
01961 bu_vls_printf(&vls, "%s \"%s\"", rtcop->dgop->dgo_outputHandler, line);
01962 Tcl_Eval(rtcop->interp, bu_vls_addr(&vls));
01963 bu_vls_free(&vls);
01964 } else
01965 bu_log("%s", line);
01966 }
01967
01968 #else
01969
01970 void
01971 dgo_rtcheck_vector_handler(ClientData clientData, int mask)
01972 {
01973 int value;
01974 struct solid *sp;
01975 struct rtcheck *rtcp = (struct rtcheck *)clientData;
01976
01977
01978 if (feof(rtcp->fp)) {
01979 Tcl_DeleteChannelHandler(rtcp->chan,
01980 dgo_rtcheck_vector_handler,
01981 (ClientData)rtcp);
01982 Tcl_Close(rtcp->interp, rtcp->chan);
01983 fclose(rtcp->fp);
01984 CloseHandle(rtcp->fd);
01985
01986 FOR_ALL_SOLIDS(sp, &rtcp->dgop->dgo_headSolid)
01987 sp->s_flag = DOWN;
01988
01989
01990 dgo_cvt_vlblock_to_solids(rtcp->dgop, rtcp->interp, rtcp->vbp, "OVERLAPS", 0);
01991 rt_vlblock_free(rtcp->vbp);
01992
01993
01994 WaitForSingleObject( rtcp->hProcess, INFINITE );
01995
01996
01997
01998
01999 dgo_notify(rtcp->dgop, rtcp->interp);
02000
02001
02002 bu_free((genptr_t)rtcp, "dgo_rtcheck_vector_handler: rtcp");
02003
02004 return;
02005 }
02006
02007 value = getc(rtcp->fp);
02008 (void)rt_process_uplot_value(&rtcp->vhead,
02009 rtcp->vbp,
02010 rtcp->fp,
02011 value,
02012 rtcp->csize,
02013 rtcp->dgop->dgo_uplotOutputMode);
02014 }
02015
02016 void
02017 dgo_rtcheck_output_handler(ClientData clientData, int mask)
02018 {
02019 int count;
02020 char line[RT_MAXLINE];
02021 struct rtcheck_output *rtcop = (struct rtcheck_output *)clientData;
02022
02023
02024 if (Tcl_Eof(rtcop->chan) ||
02025 (!ReadFile(rtcop->fd, line, RT_MAXLINE,&count,0))) {
02026
02027 Tcl_DeleteChannelHandler(rtcop->chan,
02028 dgo_rtcheck_output_handler,
02029 (ClientData)rtcop);
02030 #if 1
02031 Tcl_Close(rtcop->interp, rtcop->chan);
02032 #endif
02033 CloseHandle(rtcop->fd);
02034
02035 bu_free((genptr_t)rtcop, "dgo_rtcheck_output_handler: rtcop");
02036 return;
02037 }
02038
02039 line[count] = '\0';
02040 if (rtcop->dgop->dgo_outputHandler != NULL) {
02041 struct bu_vls vls;
02042
02043 bu_vls_init(&vls);
02044 bu_vls_printf(&vls, "%s \"%s\"", rtcop->dgop->dgo_outputHandler, line);
02045 Tcl_Eval(rtcop->interp, bu_vls_addr(&vls));
02046 bu_vls_free(&vls);
02047 } else
02048 bu_log("%s", line);
02049 }
02050
02051 #endif
02052
02053 int
02054 dgo_rtcheck_cmd(struct dg_obj *dgop,
02055 struct view_obj *vop,
02056 Tcl_Interp *interp,
02057 int argc,
02058 char **argv)
02059 {
02060 register char **vp;
02061 register int i;
02062 #ifndef _WIN32
02063 int pid;
02064 int i_pipe[2];
02065 int o_pipe[2];
02066 int e_pipe[2];
02067 #else
02068 HANDLE i_pipe[2],pipe_iDup;
02069 HANDLE o_pipe[2],pipe_oDup;
02070 HANDLE e_pipe[2],pipe_eDup;
02071 STARTUPINFO si;
02072 PROCESS_INFORMATION pi;
02073 SECURITY_ATTRIBUTES sa;
02074 char line[2048];
02075 char name[256];
02076 #endif
02077 FILE *fp;
02078 struct rtcheck *rtcp;
02079 struct rtcheck_output *rtcop;
02080 vect_t temp;
02081 vect_t eye_model;
02082
02083 #ifndef _WIN32
02084 vp = &dgop->dgo_rt_cmd[0];
02085 *vp++ = argv[0];
02086 *vp++ = "-M";
02087 for (i=1; i < argc; i++)
02088 *vp++ = argv[i];
02089 *vp++ = dgop->dgo_wdbp->dbip->dbi_filename;
02090
02091
02092
02093
02094
02095
02096 if (i == argc) {
02097 dgop->dgo_rt_cmd_len = vp - dgop->dgo_rt_cmd;
02098 dgop->dgo_rt_cmd_len += dgo_build_tops(interp,
02099 (struct solid *)&dgop->dgo_headSolid,
02100 vp,
02101 &dgop->dgo_rt_cmd[MAXARGS]);
02102 } else {
02103 while (i < argc)
02104 *vp++ = argv[i++];
02105 *vp = 0;
02106 vp = &dgop->dgo_rt_cmd[0];
02107 while (*vp)
02108 Tcl_AppendResult(interp, *vp++, " ", (char *)NULL);
02109
02110 Tcl_AppendResult(interp, "\n", (char *)NULL);
02111 }
02112
02113 (void)pipe(i_pipe);
02114 (void)pipe(o_pipe);
02115 (void)pipe(e_pipe);
02116
02117 if ((pid = fork()) == 0) {
02118
02119 (void)close(0);
02120 (void)dup(o_pipe[0]);
02121 (void)close(1);
02122 (void)dup(i_pipe[1]);
02123 (void)close(2);
02124 (void)dup(e_pipe[1]);
02125
02126
02127 (void)close(i_pipe[0]);
02128 (void)close(i_pipe[1]);
02129 (void)close(o_pipe[0]);
02130 (void)close(o_pipe[1]);
02131 (void)close(e_pipe[0]);
02132 (void)close(e_pipe[1]);
02133
02134 for (i=3; i < 20; i++)
02135 (void)close(i);
02136
02137 (void)execvp(dgop->dgo_rt_cmd[0], dgop->dgo_rt_cmd);
02138 perror(dgop->dgo_rt_cmd[0]);
02139 exit(16);
02140 }
02141
02142
02143 (void)close(o_pipe[0]);
02144 fp = fdopen(o_pipe[1], "w");
02145 #if 1
02146 VSET(temp, 0.0, 0.0, 1.0);
02147 MAT4X3PNT(eye_model, vop->vo_view2model, temp);
02148 #else
02149 dgo_rt_set_eye_model(dgop, vop, eye_model);
02150 #endif
02151 dgo_rt_write(dgop, vop, fp, eye_model);
02152
02153 (void)fclose(fp);
02154
02155
02156 (void)close(i_pipe[1]);
02157 (void)close(e_pipe[1]);
02158
02159 BU_GETSTRUCT(rtcp, rtcheck);
02160
02161
02162 rtcp->fd = i_pipe[0];
02163 rtcp->fp = fdopen(i_pipe[0], "r");
02164 rtcp->pid = pid;
02165 rtcp->vbp = rt_vlblock_init();
02166 rtcp->vhead = rt_vlblock_find(rtcp->vbp, 0xFF, 0xFF, 0x00);
02167 rtcp->csize = vop->vo_scale * 0.01;
02168 rtcp->dgop = dgop;
02169 rtcp->interp = interp;
02170
02171
02172 Tcl_CreateFileHandler(i_pipe[0], TCL_READABLE,
02173 dgo_rtcheck_vector_handler, (ClientData)rtcp);
02174
02175 BU_GETSTRUCT(rtcop, rtcheck_output);
02176 rtcop->fd = e_pipe[0];
02177 rtcop->dgop = dgop;
02178 rtcop->interp = interp;
02179 Tcl_CreateFileHandler(rtcop->fd,
02180 TCL_READABLE,
02181 dgo_rtcheck_output_handler,
02182 (ClientData)rtcop);
02183
02184 return TCL_OK;
02185 #else
02186
02187 vp = &dgop->dgo_rt_cmd[0];
02188 *vp++ = "rtcheck";
02189 *vp++ = "-M";
02190 for (i=1; i < argc; i++)
02191 *vp++ = argv[i];
02192
02193 {
02194 char buf[512];
02195
02196 sprintf(buf, "\"%s\"", dgop->dgo_wdbp->dbip->dbi_filename);
02197 *vp++ = buf;
02198 }
02199
02200
02201
02202
02203
02204
02205 if (i == argc) {
02206 dgop->dgo_rt_cmd_len = vp - dgop->dgo_rt_cmd;
02207 dgop->dgo_rt_cmd_len += dgo_build_tops(interp,
02208 (struct solid *)&dgop->dgo_headSolid,
02209 vp,
02210 &dgop->dgo_rt_cmd[MAXARGS]);
02211 } else {
02212 while (i < argc)
02213 *vp++ = argv[i++];
02214 *vp = 0;
02215 vp = &dgop->dgo_rt_cmd[0];
02216 while (*vp)
02217 Tcl_AppendResult(interp, *vp++, " ", (char *)NULL);
02218
02219 Tcl_AppendResult(interp, "\n", (char *)NULL);
02220 }
02221
02222
02223 memset((void *)&si, 0, sizeof(STARTUPINFO));
02224 memset((void *)&pi, 0, sizeof(PROCESS_INFORMATION));
02225 memset((void *)&sa, 0, sizeof(SECURITY_ATTRIBUTES));
02226
02227 sa.nLength = sizeof(SECURITY_ATTRIBUTES);
02228 sa.bInheritHandle = TRUE;
02229 sa.lpSecurityDescriptor = NULL;
02230
02231
02232 CreatePipe( &e_pipe[0], &e_pipe[1], &sa, 0);
02233
02234
02235 DuplicateHandle( GetCurrentProcess(), e_pipe[0],
02236 GetCurrentProcess(), &pipe_eDup,
02237 0, FALSE,
02238 DUPLICATE_SAME_ACCESS );
02239 CloseHandle( e_pipe[0]);
02240
02241
02242 CreatePipe( &o_pipe[0], &o_pipe[1], &sa, 0);
02243
02244
02245 DuplicateHandle( GetCurrentProcess(), o_pipe[1],
02246 GetCurrentProcess(), &pipe_oDup ,
02247 0, FALSE,
02248 DUPLICATE_SAME_ACCESS );
02249 CloseHandle( o_pipe[1]);
02250
02251
02252 CreatePipe(&i_pipe[0], &i_pipe[1], &sa, 0);
02253
02254
02255 DuplicateHandle(GetCurrentProcess(), i_pipe[0],
02256 GetCurrentProcess(), &pipe_iDup,
02257 0, FALSE,
02258 DUPLICATE_SAME_ACCESS );
02259 CloseHandle(i_pipe[0]);
02260
02261
02262 si.cb = sizeof(STARTUPINFO);
02263 si.lpReserved = NULL;
02264 si.lpReserved2 = NULL;
02265 si.cbReserved2 = 0;
02266 si.lpDesktop = NULL;
02267 si.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
02268 si.hStdInput = o_pipe[0];
02269 si.hStdOutput = i_pipe[1];
02270 si.hStdError = e_pipe[1];
02271 si.wShowWindow = SW_HIDE;
02272
02273 sprintf(line,"%s ",dgop->dgo_rt_cmd[0]);
02274 for (i=1; i < dgop->dgo_rt_cmd_len; i++) {
02275 sprintf(name,"%s ",dgop->dgo_rt_cmd[i]);
02276 strcat(line,name);
02277 }
02278
02279 CreateProcess(NULL, line, NULL, NULL, TRUE,
02280 DETACHED_PROCESS, NULL, NULL,
02281 &si, &pi);
02282
02283
02284 CloseHandle(o_pipe[0]);
02285
02286
02287 (void)CloseHandle(i_pipe[1]);
02288 (void)CloseHandle(e_pipe[1]);
02289
02290
02291 fp = _fdopen(_open_osfhandle((HFILE)pipe_oDup,_O_TEXT), "wb");
02292 _setmode(_fileno(fp), _O_BINARY);
02293
02294 #if 1
02295 VSET(temp, 0.0, 0.0, 1.0);
02296 MAT4X3PNT(eye_model, vop->vo_view2model, temp);
02297 #else
02298 dgo_rt_set_eye_model(dgop, vop, eye_model);
02299 #endif
02300 dgo_rt_write(dgop, vop, fp, eye_model);
02301 (void)fclose(fp);
02302
02303 BU_GETSTRUCT(rtcp, rtcheck);
02304
02305
02306 rtcp->fd = pipe_iDup;
02307 rtcp->fp = _fdopen( _open_osfhandle((HFILE)pipe_iDup,_O_TEXT), "rb" );
02308 _setmode(_fileno(rtcp->fp), _O_BINARY);
02309 rtcp->hProcess = pi.hProcess;
02310 rtcp->pid = pi.dwProcessId;
02311 rtcp->vbp = rt_vlblock_init();
02312 rtcp->vhead = rt_vlblock_find(rtcp->vbp, 0xFF, 0xFF, 0x00);
02313 rtcp->csize = vop->vo_scale * 0.01;
02314 rtcp->dgop = dgop;
02315 rtcp->interp = interp;
02316
02317 rtcp->chan = Tcl_MakeFileChannel(pipe_iDup,TCL_READABLE);
02318 Tcl_CreateChannelHandler(rtcp->chan,TCL_READABLE,
02319 dgo_rtcheck_vector_handler,
02320 (ClientData)rtcp);
02321
02322 BU_GETSTRUCT(rtcop, rtcheck_output);
02323 rtcop->fd = pipe_eDup;
02324 rtcop->chan = Tcl_MakeFileChannel(pipe_eDup,TCL_READABLE);
02325 rtcop->dgop = dgop;
02326 rtcop->interp = interp;
02327 Tcl_CreateChannelHandler(rtcop->chan,
02328 TCL_READABLE,
02329 dgo_rtcheck_output_handler,
02330 (ClientData)rtcop);
02331 return TCL_OK;
02332
02333
02334 #endif
02335 }
02336
02337
02338
02339
02340
02341 static int
02342 dgo_rtcheck_tcl(ClientData clientData, Tcl_Interp *interp, int argc, char **argv)
02343 {
02344 struct dg_obj *dgop = (struct dg_obj *)clientData;
02345 struct view_obj *vop;
02346
02347 DGO_CHECK_WDBP_NULL(dgop,interp);
02348
02349 if (argc < 3 || MAXARGS < argc) {
02350 struct bu_vls vls;
02351
02352 bu_vls_init(&vls);
02353 bu_vls_printf(&vls, "helplib_alias dgo_rtcheck %s", argv[0]);
02354 Tcl_Eval(interp, bu_vls_addr(&vls));
02355 bu_vls_free(&vls);
02356
02357 return TCL_ERROR;
02358 }
02359
02360
02361 for (BU_LIST_FOR(vop, view_obj, &HeadViewObj.l)) {
02362 if (strcmp(bu_vls_addr(&vop->vo_name), argv[2]) == 0)
02363 break;
02364 }
02365
02366 if (BU_LIST_IS_HEAD(vop, &HeadViewObj.l)) {
02367 Tcl_AppendResult(interp, "dgo_rtcheck: bad view object - ", argv[2],
02368 "\n", (char *)NULL);
02369 return TCL_ERROR;
02370 }
02371
02372 return dgo_rtcheck_cmd(dgop, vop, interp, argc-2, argv+2);
02373 }
02374
02375
02376
02377
02378
02379
02380
02381 static int
02382 dgo_assoc_tcl(ClientData clientData, Tcl_Interp *interp, int argc, char **argv)
02383 {
02384 struct dg_obj *dgop = (struct dg_obj *)clientData;
02385 struct rt_wdb *wdbp;
02386 struct bu_vls vls;
02387
02388
02389 if (argc == 2) {
02390 if (dgop->dgo_wdbp == RT_WDB_NULL)
02391 Tcl_AppendResult(interp, (char *)NULL);
02392 else
02393 Tcl_AppendResult(interp, bu_vls_addr(&dgop->dgo_wdbp->wdb_name), (char *)NULL);
02394 return TCL_OK;
02395 }
02396
02397
02398 if (argc == 3) {
02399
02400 for (BU_LIST_FOR(wdbp, rt_wdb, &rt_g.rtg_headwdb.l)) {
02401 if (strcmp(bu_vls_addr(&wdbp->wdb_name), argv[2]) == 0)
02402 break;
02403 }
02404
02405 if (BU_LIST_IS_HEAD(wdbp, &rt_g.rtg_headwdb.l))
02406 wdbp = RT_WDB_NULL;
02407
02408 if (dgop->dgo_wdbp != RT_WDB_NULL)
02409 dgo_zap_cmd(dgop, interp);
02410
02411 dgop->dgo_wdbp = wdbp;
02412 dgo_notify(dgop, interp);
02413
02414 return TCL_OK;
02415 }
02416
02417
02418 bu_vls_init(&vls);
02419 bu_vls_printf(&vls, "helplib_alias dgo_assoc %s", argv[0]);
02420 Tcl_Eval(interp, bu_vls_addr(&vls));
02421 bu_vls_free(&vls);
02422
02423 return TCL_ERROR;
02424 }
02425
02426 int
02427 dgo_observer_cmd(struct dg_obj *dgop,
02428 Tcl_Interp *interp,
02429 int argc,
02430 char **argv) {
02431 if (argc < 2) {
02432 struct bu_vls vls;
02433
02434
02435 bu_vls_init(&vls);
02436 bu_vls_printf(&vls, "helplib_alias dgo_observer %s", argv[0]);
02437 Tcl_Eval(interp, bu_vls_addr(&vls));
02438 bu_vls_free(&vls);
02439 return TCL_ERROR;
02440 }
02441
02442 return bu_cmd((ClientData)&dgop->dgo_observers,
02443 interp, argc-1, argv+1, bu_observer_cmds, 0);
02444 }
02445
02446
02447
02448
02449
02450
02451
02452
02453 static int
02454 dgo_observer_tcl(ClientData clientData,
02455 Tcl_Interp *interp,
02456 int argc,
02457 char **argv) {
02458 struct dg_obj *dgop = (struct dg_obj *)clientData;
02459
02460 return dgo_observer_cmd(dgop, interp, argc-1, argv+1);
02461 }
02462
02463 int
02464 dgo_report_cmd(struct dg_obj *dgop,
02465 Tcl_Interp *interp,
02466 int argc,
02467 char **argv)
02468 {
02469 int lvl = 0;
02470
02471 if (argc < 1 || 2 < argc) {
02472 struct bu_vls vls;
02473
02474 bu_vls_init(&vls);
02475 bu_vls_printf(&vls, "helplib_alias dgo_report %s", argv[0]);
02476 Tcl_Eval(interp, bu_vls_addr(&vls));
02477 bu_vls_free(&vls);
02478 return TCL_ERROR;
02479 }
02480
02481 if (argc == 2)
02482 lvl = atoi(argv[1]);
02483
02484 if (lvl <= 3)
02485 dgo_print_schain(dgop, interp, lvl);
02486 else
02487 dgo_print_schain_vlcmds(dgop, interp);
02488
02489 return TCL_OK;
02490 }
02491
02492
02493
02494
02495 static int
02496 dgo_report_tcl(ClientData clientData, Tcl_Interp *interp, int argc, char **argv)
02497 {
02498 struct dg_obj *dgop = (struct dg_obj *)clientData;
02499
02500 DGO_CHECK_WDBP_NULL(dgop,interp);
02501
02502 return dgo_report_cmd(dgop, interp, argc-1, argv+1);
02503 }
02504
02505
02506 #ifndef _WIN32
02507 int
02508 dgo_rtabort_cmd(struct dg_obj *dgop,
02509 Tcl_Interp *interp,
02510 int argc,
02511 char **argv)
02512 {
02513 struct run_rt *rrp;
02514
02515 for (BU_LIST_FOR(rrp, run_rt, &dgop->dgo_headRunRt.l)) {
02516 kill(rrp->pid, SIGKILL);
02517 rrp->aborted = 1;
02518 }
02519
02520 return TCL_OK;
02521 }
02522 #else
02523 int
02524 dgo_rtabort_cmd(struct dg_obj *dgop,
02525 Tcl_Interp *interp,
02526 int argc,
02527 char **argv)
02528 {
02529 struct run_rt *rrp;
02530 HANDLE hProcess;
02531
02532 for (BU_LIST_FOR(rrp, run_rt, &dgop->dgo_headRunRt.l)) {
02533 hProcess= OpenProcess(PROCESS_ALL_ACCESS, TRUE,rrp->pid);
02534 if(hProcess != NULL)
02535 TerminateProcess(hProcess, 0);
02536 rrp->aborted = 1;
02537 }
02538
02539 return TCL_OK;
02540 }
02541 #endif
02542
02543 static int
02544 dgo_rtabort_tcl(ClientData clientData,
02545 Tcl_Interp *interp,
02546 int argc,
02547 char **argv)
02548 {
02549 struct dg_obj *dgop = (struct dg_obj *)clientData;
02550
02551 return dgo_rtabort_cmd(dgop, interp, argc-1, argv+1);
02552 }
02553
02554 static int
02555 dgo_qray_tcl(ClientData clientData,
02556 Tcl_Interp *interp,
02557 int argc,
02558 char **argv)
02559 {
02560 struct dg_obj *dgop = (struct dg_obj *)clientData;
02561
02562 DGO_CHECK_WDBP_NULL(dgop,interp);
02563 return dgo_qray_cmd(dgop, interp, argc-1, argv+1);
02564 }
02565
02566 static int
02567 dgo_nirt_tcl(ClientData clientData,
02568 Tcl_Interp *interp,
02569 int argc,
02570 char **argv)
02571 {
02572 struct dg_obj *dgop = (struct dg_obj *)clientData;
02573 struct view_obj *vop;
02574
02575 if (argc < 3 || MAXARGS < argc) {
02576 struct bu_vls vls;
02577
02578 bu_vls_init(&vls);
02579 bu_vls_printf(&vls, "helplib_alias dgo_nirt %s", argv[0]);
02580 Tcl_Eval(interp, bu_vls_addr(&vls));
02581 bu_vls_free(&vls);
02582 return TCL_ERROR;
02583 }
02584
02585 DGO_CHECK_WDBP_NULL(dgop,interp);
02586
02587
02588 for (BU_LIST_FOR(vop, view_obj, &HeadViewObj.l)) {
02589 if (strcmp(bu_vls_addr(&vop->vo_name), argv[2]) == 0)
02590 break;
02591 }
02592
02593 if (BU_LIST_IS_HEAD(vop, &HeadViewObj.l)) {
02594 Tcl_AppendResult(interp, "dgo_nirt: bad view object - ", argv[2],
02595 "\n", (char *)NULL);
02596 return TCL_ERROR;
02597 }
02598
02599 return dgo_nirt_cmd(dgop, vop, interp, argc-2, argv+2);
02600 }
02601
02602 static int
02603 dgo_vnirt_tcl(ClientData clientData,
02604 Tcl_Interp *interp,
02605 int argc,
02606 char **argv)
02607 {
02608 struct dg_obj *dgop = (struct dg_obj *)clientData;
02609 struct view_obj *vop;
02610
02611 if (argc < 5 || MAXARGS < argc) {
02612 struct bu_vls vls;
02613
02614 bu_vls_init(&vls);
02615 bu_vls_printf(&vls, "helplib_alias dgo_vnirt %s", argv[0]);
02616 Tcl_Eval(interp, bu_vls_addr(&vls));
02617 bu_vls_free(&vls);
02618 return TCL_ERROR;
02619 }
02620
02621 DGO_CHECK_WDBP_NULL(dgop,interp);
02622
02623
02624 for (BU_LIST_FOR(vop, view_obj, &HeadViewObj.l)) {
02625 if (strcmp(bu_vls_addr(&vop->vo_name), argv[2]) == 0)
02626 break;
02627 }
02628
02629 if (BU_LIST_IS_HEAD(vop, &HeadViewObj.l)) {
02630 Tcl_AppendResult(interp, "dgo_vnirt: bad view object - ", argv[2],
02631 "\n", (char *)NULL);
02632 return TCL_ERROR;
02633 }
02634
02635 return dgo_vnirt_cmd(dgop, vop, interp, argc-2, argv+2);
02636 }
02637
02638 int
02639 dgo_set_outputHandler_cmd(struct dg_obj *dgop,
02640 Tcl_Interp *interp,
02641 int argc,
02642 char **argv)
02643 {
02644 if (argc < 1 || 2 < argc) {
02645 struct bu_vls vls;
02646
02647 bu_vls_init(&vls);
02648 bu_vls_printf(&vls, "helplib_alias dgo_set_outputHandler %s", argv[0]);
02649 Tcl_Eval(interp, bu_vls_addr(&vls));
02650 bu_vls_free(&vls);
02651
02652 return TCL_ERROR;
02653 }
02654
02655
02656 if (argc == 1) {
02657 Tcl_DString ds;
02658
02659 Tcl_DStringInit(&ds);
02660 if (dgop->dgo_outputHandler != NULL)
02661 Tcl_DStringAppend(&ds, dgop->dgo_outputHandler, -1);
02662 Tcl_DStringResult(interp, &ds);
02663
02664 return TCL_OK;
02665 }
02666
02667
02668
02669 if (dgop->dgo_outputHandler != NULL) {
02670 bu_free((genptr_t)dgop->dgo_outputHandler, "dgo_set_outputHandler: zap");
02671 dgop->dgo_outputHandler = NULL;
02672 }
02673
02674 if (argv[1] != NULL && argv[1][0] != '\0')
02675 dgop->dgo_outputHandler = bu_strdup(argv[1]);
02676
02677 return TCL_OK;
02678 }
02679
02680
02681
02682
02683
02684
02685
02686 static int
02687 dgo_set_outputHandler_tcl(ClientData clientData,
02688 Tcl_Interp *interp,
02689 int argc,
02690 char **argv)
02691 {
02692 struct dg_obj *dgop = (struct dg_obj *)clientData;
02693
02694 return dgo_set_outputHandler_cmd(dgop, interp, argc-1, argv+1);
02695 }
02696
02697 int
02698 dgo_set_uplotOutputMode_cmd(struct dg_obj *dgop,
02699 Tcl_Interp *interp,
02700 int argc,
02701 char **argv)
02702 {
02703 if (argc < 1 || 2 < argc) {
02704 struct bu_vls vls;
02705
02706 bu_vls_init(&vls);
02707 bu_vls_printf(&vls, "helplib_alias dgo_set_plOutputMode %s", argv[0]);
02708 Tcl_Eval(interp, bu_vls_addr(&vls));
02709 bu_vls_free(&vls);
02710
02711 return TCL_ERROR;
02712 }
02713
02714
02715 if (argc == 1) {
02716 Tcl_DString ds;
02717
02718 Tcl_DStringInit(&ds);
02719 if (dgop->dgo_uplotOutputMode == PL_OUTPUT_MODE_BINARY)
02720 Tcl_DStringAppend(&ds, "binary", -1);
02721 else
02722 Tcl_DStringAppend(&ds, "text", -1);
02723 Tcl_DStringResult(interp, &ds);
02724
02725 return TCL_OK;
02726 }
02727
02728 if (argv[1][0] == 'b' &&
02729 !strcmp("binary", argv[1]))
02730 dgop->dgo_uplotOutputMode = PL_OUTPUT_MODE_BINARY;
02731 else if (argv[1][0] == 't' &&
02732 !strcmp("text", argv[1]))
02733 dgop->dgo_uplotOutputMode = PL_OUTPUT_MODE_TEXT;
02734 else {
02735 struct bu_vls vls;
02736
02737 bu_vls_init(&vls);
02738 bu_vls_printf(&vls, "helplib_alias dgo_set_plOutputMode %s", argv[0]);
02739 Tcl_Eval(interp, bu_vls_addr(&vls));
02740 bu_vls_free(&vls);
02741
02742 return TCL_ERROR;
02743 }
02744
02745 return TCL_OK;
02746 }
02747
02748
02749
02750
02751
02752
02753
02754 static int
02755 dgo_set_uplotOutputMode_tcl(ClientData clientData,
02756 Tcl_Interp *interp,
02757 int argc,
02758 char **argv)
02759 {
02760 struct dg_obj *dgop = (struct dg_obj *)clientData;
02761
02762 return dgo_set_uplotOutputMode_cmd(dgop, interp, argc-1, argv+1);
02763 }
02764
02765 int
02766 dgo_set_transparency_cmd(struct dg_obj *dgop,
02767 Tcl_Interp *interp,
02768 int argc,
02769 char **argv)
02770 {
02771 register struct solid *sp;
02772 int i;
02773 struct directory **dpp;
02774 register struct directory **tmp_dpp;
02775 fastf_t transparency;
02776
02777
02778 if (argc != 3) {
02779 struct bu_vls vls;
02780
02781 bu_vls_init(&vls);
02782 bu_vls_printf(&vls, "helplib_alias dgo_set_transparency %s", argv[0]);
02783 Tcl_Eval(interp, bu_vls_addr(&vls));
02784 bu_vls_free(&vls);
02785
02786 return TCL_ERROR;
02787 }
02788
02789 if (sscanf(argv[2], "%lf", &transparency) != 1) {
02790 Tcl_AppendResult(interp, "dgo_set_transparency: bad transparency - ",
02791 argv[2], "\n", (char *)NULL);
02792 return TCL_ERROR;
02793 }
02794
02795 if ((dpp = dgo_build_dpp(dgop, interp, argv[1])) == NULL) {
02796 return TCL_OK;
02797 }
02798
02799 FOR_ALL_SOLIDS(sp, &dgop->dgo_headSolid) {
02800 for (i = 0, tmp_dpp = dpp;
02801 i < sp->s_fullpath.fp_len && *tmp_dpp != DIR_NULL;
02802 ++i, ++tmp_dpp) {
02803 if (sp->s_fullpath.fp_names[i] != *tmp_dpp)
02804 break;
02805 }
02806
02807 if (*tmp_dpp != DIR_NULL)
02808 continue;
02809
02810
02811 sp->s_transparency = transparency;
02812 }
02813
02814 if (dpp != (struct directory **)NULL)
02815 bu_free((genptr_t)dpp, "dgo_set_transparency_cmd: directory pointers");
02816
02817 return TCL_OK;
02818 }
02819
02820
02821
02822
02823
02824
02825
02826 static int
02827 dgo_set_transparency_tcl(ClientData clientData,
02828 Tcl_Interp *interp,
02829 int argc,
02830 char **argv)
02831 {
02832 struct dg_obj *dgop = (struct dg_obj *)clientData;
02833 int ret;
02834
02835 if ((ret = dgo_set_transparency_cmd(dgop, interp, argc-1, argv+1)) == TCL_OK)
02836 dgo_notify(dgop, interp);
02837
02838 return ret;
02839 }
02840
02841 int
02842 dgo_shaded_mode_cmd(struct dg_obj *dgop,
02843 Tcl_Interp *interp,
02844 int argc,
02845 char **argv)
02846 {
02847 struct bu_vls vls;
02848
02849
02850 if (argc == 1) {
02851 bu_vls_init(&vls);
02852 bu_vls_printf(&vls, "%d", dgop->dgo_shaded_mode);
02853 Tcl_AppendResult(interp, bu_vls_addr(&vls), (char *)0);
02854 bu_vls_free(&vls);
02855 return TCL_OK;
02856 }
02857
02858
02859 if (argc == 2) {
02860 int shaded_mode;
02861
02862 if (sscanf(argv[1], "%d", &shaded_mode) != 1)
02863 goto bad;
02864
02865 if (shaded_mode < 0 || 2 < shaded_mode)
02866 goto bad;
02867
02868 dgop->dgo_shaded_mode = shaded_mode;
02869 return TCL_OK;
02870 }
02871
02872 bad:
02873 bu_vls_init(&vls);
02874 bu_vls_printf(&vls, "helplib_alias dgo_shaded_mode %s", argv[0]);
02875 Tcl_Eval(interp, bu_vls_addr(&vls));
02876 bu_vls_free(&vls);
02877 return TCL_ERROR;
02878 }
02879
02880
02881
02882
02883
02884 static int
02885 dgo_shaded_mode_tcl(ClientData clientData,
02886 Tcl_Interp *interp,
02887 int argc,
02888 char **argv)
02889 {
02890 struct dg_obj *dgop = (struct dg_obj *)clientData;
02891
02892 return dgo_shaded_mode_cmd(dgop, interp, argc-1, argv+1);
02893 }
02894
02895 #if 0
02896
02897 int
02898 dgo__cmd(struct dg_obj *dgop,
02899 Tcl_Interp *interp,
02900 int argc,
02901 char **argv)
02902 {
02903 }
02904
02905
02906
02907
02908
02909 static int
02910 dgo__tcl(ClientData clientData,
02911 Tcl_Interp *interp,
02912 int argc,
02913 char **argv)
02914 {
02915 struct dg_obj *dgop = (struct dg_obj *)clientData;
02916
02917 return dgo__cmd(dgop, interp, argc-1, argv+1);
02918 }
02919 #endif
02920
02921
02922
02923 static union tree *
02924 dgo_wireframe_region_end(register struct db_tree_state *tsp, struct db_full_path *pathp, union tree *curtree, genptr_t client_data)
02925 {
02926 return (curtree);
02927 }
02928
02929
02930
02931
02932
02933
02934 static union tree *
02935 dgo_wireframe_leaf(struct db_tree_state *tsp, struct db_full_path *pathp, struct rt_db_internal *ip, genptr_t client_data)
02936 {
02937 union tree *curtree;
02938 int dashflag;
02939 struct bu_list vhead;
02940 struct dg_client_data *dgcdp = (struct dg_client_data *)client_data;
02941
02942 RT_CK_TESS_TOL(tsp->ts_ttol);
02943 BN_CK_TOL(tsp->ts_tol);
02944 RT_CK_RESOURCE(tsp->ts_resp);
02945
02946 BU_LIST_INIT(&vhead);
02947
02948 if (RT_G_DEBUG&DEBUG_TREEWALK) {
02949 char *sofar = db_path_to_string(pathp);
02950
02951 Tcl_AppendResult(dgcdp->interp, "dgo_wireframe_leaf(",
02952 ip->idb_meth->ft_name,
02953 ") path='", sofar, "'\n", (char *)NULL);
02954 bu_free((genptr_t)sofar, "path string");
02955 }
02956
02957 if (dgcdp->draw_solid_lines_only)
02958 dashflag = 0;
02959 else
02960 dashflag = (tsp->ts_sofar & (TS_SOFAR_MINUS|TS_SOFAR_INTER));
02961
02962 RT_CK_DB_INTERNAL(ip);
02963
02964 if (ip->idb_meth->ft_plot(&vhead, ip,
02965 tsp->ts_ttol,
02966 tsp->ts_tol) < 0) {
02967 Tcl_AppendResult(dgcdp->interp, DB_FULL_PATH_CUR_DIR(pathp)->d_namep,
02968 ": plot failure\n", (char *)NULL);
02969 return (TREE_NULL);
02970 }
02971
02972
02973
02974
02975
02976
02977
02978 if (ip->idb_type == ID_GRIP) {
02979 int r,g,b;
02980 r= tsp->ts_mater.ma_color[0];
02981 g= tsp->ts_mater.ma_color[1];
02982 b= tsp->ts_mater.ma_color[2];
02983 tsp->ts_mater.ma_color[0] = 0;
02984 tsp->ts_mater.ma_color[1] = 128;
02985 tsp->ts_mater.ma_color[2] = 128;
02986 dgo_drawH_part2(dashflag, &vhead, pathp, tsp, SOLID_NULL, dgcdp);
02987 tsp->ts_mater.ma_color[0] = r;
02988 tsp->ts_mater.ma_color[1] = g;
02989 tsp->ts_mater.ma_color[2] = b;
02990 } else {
02991 dgo_drawH_part2(dashflag, &vhead, pathp, tsp, SOLID_NULL, dgcdp);
02992 }
02993
02994
02995 RT_GET_TREE(curtree, tsp->ts_resp);
02996 curtree->magic = RT_TREE_MAGIC;
02997 curtree->tr_op = OP_NOP;
02998
02999 return (curtree);
03000 }
03001
03002
03003
03004
03005
03006
03007
03008
03009
03010
03011
03012
03013
03014
03015 static int
03016 dgo_nmg_region_start(struct db_tree_state *tsp, struct db_full_path *pathp, const struct rt_comb_internal *combp, genptr_t client_data)
03017 {
03018 union tree *tp;
03019 struct directory *dp;
03020 struct rt_db_internal intern;
03021 mat_t xform;
03022 matp_t matp;
03023 struct bu_list vhead;
03024 struct dg_client_data *dgcdp = (struct dg_client_data *)client_data;
03025
03026 if (RT_G_DEBUG&DEBUG_TREEWALK) {
03027 char *sofar = db_path_to_string(pathp);
03028 bu_log("dgo_nmg_region_start(%s)\n", sofar);
03029 bu_free((genptr_t)sofar, "path string");
03030 rt_pr_tree( combp->tree, 1 );
03031 db_pr_tree_state(tsp);
03032 }
03033
03034 RT_CK_DBI(tsp->ts_dbip);
03035 RT_CK_RESOURCE(tsp->ts_resp);
03036
03037 BU_LIST_INIT(&vhead);
03038
03039 RT_CK_COMB(combp);
03040 tp = combp->tree;
03041 if (!tp)
03042 return( -1 );
03043 RT_CK_TREE(tp);
03044 if (tp->tr_l.tl_op != OP_DB_LEAF)
03045 return 0;
03046
03047
03048
03049
03050 dp = db_lookup( tsp->ts_dbip, tp->tr_l.tl_name, LOOKUP_NOISY );
03051 if (!dp)
03052 return 0;
03053 if (tsp->ts_mat) {
03054 if (tp->tr_l.tl_mat) {
03055 matp = xform;
03056 bn_mat_mul(xform, tsp->ts_mat, tp->tr_l.tl_mat);
03057 } else {
03058 matp = tsp->ts_mat;
03059 }
03060 } else {
03061 if (tp->tr_l.tl_mat) {
03062 matp = tp->tr_l.tl_mat;
03063 } else {
03064 matp = (matp_t)NULL;
03065 }
03066 }
03067 if (rt_db_get_internal(&intern, dp, tsp->ts_dbip, matp, &rt_uniresource) < 0)
03068 return 0;
03069
03070 switch (intern.idb_type) {
03071 case ID_POLY:
03072 {
03073 if (RT_G_DEBUG&DEBUG_TREEWALK) {
03074 bu_log("fastpath draw ID_POLY %s\n", dp->d_namep);
03075 }
03076 if (dgcdp->draw_wireframes) {
03077 (void)rt_pg_plot( &vhead, &intern, tsp->ts_ttol, tsp->ts_tol );
03078 } else {
03079 (void)rt_pg_plot_poly( &vhead, &intern, tsp->ts_ttol, tsp->ts_tol );
03080 }
03081 }
03082 goto out;
03083 case ID_BOT:
03084 {
03085 if (RT_G_DEBUG&DEBUG_TREEWALK) {
03086 bu_log("fastpath draw ID_BOT %s\n", dp->d_namep);
03087 }
03088 if (dgcdp->draw_wireframes) {
03089 (void)rt_bot_plot( &vhead, &intern, tsp->ts_ttol, tsp->ts_tol );
03090 } else {
03091 (void)rt_bot_plot_poly( &vhead, &intern, tsp->ts_ttol, tsp->ts_tol );
03092 }
03093 }
03094 goto out;
03095 case ID_COMBINATION:
03096 default:
03097 break;
03098 }
03099 rt_db_free_internal(&intern, tsp->ts_resp);
03100 return 0;
03101
03102 out:
03103
03104 db_add_node_to_full_path(pathp, dp);
03105 dgo_drawH_part2(0, &vhead, pathp, tsp, SOLID_NULL, dgcdp);
03106 DB_FULL_PATH_POP(pathp);
03107 rt_db_free_internal(&intern, tsp->ts_resp);
03108 dgcdp->fastpath_count++;
03109 return -1;
03110 }
03111
03112
03113
03114
03115
03116
03117 static union tree *
03118 dgo_nmg_region_end(register struct db_tree_state *tsp, struct db_full_path *pathp, union tree *curtree, genptr_t client_data)
03119 {
03120 struct nmgregion *r;
03121 struct bu_list vhead;
03122 int failed;
03123 struct dg_client_data *dgcdp = (struct dg_client_data *)client_data;
03124
03125 RT_CK_TESS_TOL(tsp->ts_ttol);
03126 BN_CK_TOL(tsp->ts_tol);
03127 NMG_CK_MODEL(*tsp->ts_m);
03128 RT_CK_RESOURCE(tsp->ts_resp);
03129
03130 BU_LIST_INIT( &vhead );
03131
03132 if(RT_G_DEBUG&DEBUG_TREEWALK) {
03133 char *sofar = db_path_to_string(pathp);
03134
03135 Tcl_AppendResult(dgcdp->interp, "dgo_nmg_region_end() path='", sofar,
03136 "'\n", (char *)NULL);
03137 bu_free((genptr_t)sofar, "path string");
03138 } else {
03139 char *sofar = db_path_to_string(pathp);
03140
03141 bu_log( "%s:\n", sofar );
03142 bu_free((genptr_t)sofar, "path string");
03143 }
03144
03145 if( curtree->tr_op == OP_NOP ) return curtree;
03146
03147 if ( !dgcdp->draw_nmg_only ) {
03148 if( BU_SETJUMP )
03149 {
03150 char *sofar = db_path_to_string(pathp);
03151
03152 BU_UNSETJUMP;
03153
03154 Tcl_AppendResult(dgcdp->interp, "WARNING: Boolean evaluation of ", sofar,
03155 " failed!!!\n", (char *)NULL );
03156 bu_free((genptr_t)sofar, "path string");
03157 if( curtree )
03158 db_free_tree( curtree, tsp->ts_resp );
03159 return (union tree *)NULL;
03160 }
03161 failed = nmg_boolean( curtree, *tsp->ts_m, tsp->ts_tol, tsp->ts_resp );
03162 BU_UNSETJUMP;
03163 if( failed ) {
03164 db_free_tree( curtree, tsp->ts_resp );
03165 return (union tree *)NULL;
03166 }
03167 }
03168 else if( curtree->tr_op != OP_NMG_TESS )
03169 {
03170 Tcl_AppendResult(dgcdp->interp, "Cannot use '-d' option when Boolean evaluation is required\n", (char *)NULL);
03171 db_free_tree( curtree, tsp->ts_resp );
03172 return (union tree *)NULL;
03173 }
03174 r = curtree->tr_d.td_r;
03175 NMG_CK_REGION(r);
03176
03177 if( dgcdp->do_not_draw_nmg_solids_during_debugging && r ) {
03178 db_free_tree( curtree, tsp->ts_resp );
03179 return (union tree *)NULL;
03180 }
03181
03182 if (dgcdp->nmg_triangulate) {
03183 if (BU_SETJUMP) {
03184 char *sofar = db_path_to_string(pathp);
03185
03186 BU_UNSETJUMP;
03187
03188 Tcl_AppendResult(dgcdp->interp, "WARNING: Triangulation of ", sofar,
03189 " failed!!!\n", (char *)NULL );
03190 bu_free((genptr_t)sofar, "path string");
03191 if( curtree )
03192 db_free_tree( curtree, tsp->ts_resp );
03193 return (union tree *)NULL;
03194 }
03195 nmg_triangulate_model(*tsp->ts_m, tsp->ts_tol);
03196 BU_UNSETJUMP;
03197 }
03198
03199 if( r != 0 ) {
03200 int style;
03201
03202 NMG_CK_REGION(r);
03203
03204 if (dgcdp->draw_wireframes) {
03205
03206 style = NMG_VLIST_STYLE_VECTOR;
03207 } else {
03208
03209 style = NMG_VLIST_STYLE_POLYGON;
03210 }
03211 if (dgcdp->draw_normals) {
03212 style |= NMG_VLIST_STYLE_VISUALIZE_NORMALS;
03213 }
03214 if (dgcdp->shade_per_vertex_normals) {
03215 style |= NMG_VLIST_STYLE_USE_VU_NORMALS;
03216 }
03217 if (dgcdp->draw_no_surfaces) {
03218 style |= NMG_VLIST_STYLE_NO_SURFACES;
03219 }
03220 nmg_r_to_vlist(&vhead, r, style);
03221
03222 dgo_drawH_part2(0, &vhead, pathp, tsp, SOLID_NULL, dgcdp);
03223
03224 if (dgcdp->draw_edge_uses) {
03225 nmg_vlblock_r(dgcdp->draw_edge_uses_vbp, r, 1);
03226 }
03227
03228 db_free_tree( curtree, tsp->ts_resp );
03229 return (union tree *)NULL;
03230 }
03231
03232
03233 return curtree;
03234 }
03235
03236
03237
03238
03239
03240
03241
03242
03243
03244
03245
03246
03247
03248
03249
03250
03251
03252 static int
03253 dgo_drawtrees(struct dg_obj *dgop, Tcl_Interp *interp, int argc, char **argv, int kind, struct dg_client_data *_dgcdp)
03254 {
03255 int ret = 0;
03256 register int c;
03257 int ncpu = 1;
03258 int dgo_nmg_use_tnurbs = 0;
03259 int dgo_enable_fastpath = 0;
03260 struct model *dgo_nmg_model;
03261 struct dg_client_data *dgcdp;
03262 RT_CHECK_DBI(dgop->dgo_wdbp->dbip);
03263
03264 if (argc <= 0)
03265 return(-1);
03266
03267
03268 if (_dgcdp != (struct dg_client_data *)0) {
03269 BU_GETSTRUCT(dgcdp, dg_client_data);
03270 *dgcdp = *_dgcdp;
03271 } else {
03272
03273 BU_GETSTRUCT(dgcdp, dg_client_data);
03274 dgcdp->dgop = dgop;
03275 dgcdp->interp = interp;
03276
03277
03278 dgcdp->draw_nmg_only = 0;
03279 dgcdp->nmg_triangulate = 1;
03280 dgcdp->draw_wireframes = 0;
03281 dgcdp->draw_normals = 0;
03282 dgcdp->draw_solid_lines_only = 0;
03283 dgcdp->draw_no_surfaces = 0;
03284 dgcdp->shade_per_vertex_normals = 0;
03285 dgcdp->draw_edge_uses = 0;
03286 dgcdp->wireframe_color_override = 0;
03287 dgcdp->fastpath_count = 0;
03288
03289
03290 dgcdp->wireframe_color[0] = 255;
03291 dgcdp->wireframe_color[1] = 0;
03292 dgcdp->wireframe_color[2] = 0;
03293
03294
03295 dgcdp->transparency = 1.0;
03296
03297
03298 dgcdp->shaded_mode_override = -1;
03299
03300 dgo_enable_fastpath = 0;
03301
03302
03303 bu_optind = 0;
03304 while ((c = bu_getopt(argc,argv,"dfm:nqstuvwx:C:STP:")) != EOF) {
03305 switch (c) {
03306 case 'u':
03307 dgcdp->draw_edge_uses = 1;
03308 break;
03309 case 's':
03310 dgcdp->draw_solid_lines_only = 1;
03311 break;
03312 case 't':
03313 dgo_nmg_use_tnurbs = 1;
03314 break;
03315 case 'v':
03316 dgcdp->shade_per_vertex_normals = 1;
03317 break;
03318 case 'w':
03319 dgcdp->draw_wireframes = 1;
03320 break;
03321 case 'S':
03322 dgcdp->draw_no_surfaces = 1;
03323 break;
03324 case 'T':
03325 dgcdp->nmg_triangulate = 0;
03326 break;
03327 case 'n':
03328 dgcdp->draw_normals = 1;
03329 break;
03330 case 'P':
03331 ncpu = atoi(bu_optarg);
03332 break;
03333 case 'q':
03334 dgcdp->do_not_draw_nmg_solids_during_debugging = 1;
03335 break;
03336 case 'd':
03337 dgcdp->draw_nmg_only = 1;
03338 break;
03339 case 'f':
03340 dgo_enable_fastpath = 1;
03341 break;
03342 case 'C':
03343 {
03344 int r,g,b;
03345 register char *cp = bu_optarg;
03346
03347 r = atoi(cp);
03348 while( (*cp >= '0' && *cp <= '9') ) cp++;
03349 while( *cp && (*cp < '0' || *cp > '9') ) cp++;
03350 g = atoi(cp);
03351 while( (*cp >= '0' && *cp <= '9') ) cp++;
03352 while( *cp && (*cp < '0' || *cp > '9') ) cp++;
03353 b = atoi(cp);
03354
03355 if( r < 0 || r > 255 ) r = 255;
03356 if( g < 0 || g > 255 ) g = 255;
03357 if( b < 0 || b > 255 ) b = 255;
03358
03359 dgcdp->wireframe_color_override = 1;
03360 dgcdp->wireframe_color[0] = r;
03361 dgcdp->wireframe_color[1] = g;
03362 dgcdp->wireframe_color[2] = b;
03363 }
03364 break;
03365 case 'm':
03366
03367 dgcdp->shaded_mode_override = atoi(bu_optarg);
03368 if (2 < dgcdp->shaded_mode_override)
03369 dgcdp->shaded_mode_override = 2;
03370
03371 break;
03372 case 'x':
03373 dgcdp->transparency = atof(bu_optarg);
03374
03375
03376 if (dgcdp->transparency < 0.0)
03377 dgcdp->transparency = 0.0;
03378
03379 if (1.0 < dgcdp->transparency)
03380 dgcdp->transparency = 1.0;
03381
03382 break;
03383 default:
03384 {
03385 struct bu_vls vls;
03386
03387 bu_vls_init(&vls);
03388 bu_vls_printf(&vls, "helplib %s", argv[0]);
03389 Tcl_Eval(interp, bu_vls_addr(&vls));
03390 bu_vls_free(&vls);
03391 bu_free((genptr_t)dgcdp, "dgo_drawtrees: dgcdp");
03392
03393 return TCL_ERROR;
03394 }
03395 }
03396 }
03397 argc -= bu_optind;
03398 argv += bu_optind;
03399
03400 switch (kind) {
03401 case 1:
03402 if (dgop->dgo_shaded_mode && dgcdp->shaded_mode_override < 0) {
03403 dgcdp->dmode = dgop->dgo_shaded_mode;
03404 } else if (0 <= dgcdp->shaded_mode_override)
03405 dgcdp->dmode = dgcdp->shaded_mode_override;
03406 else
03407 dgcdp->dmode = DGO_WIREFRAME;
03408
03409 break;
03410 case 2:
03411 case 3:
03412 dgcdp->dmode = DGO_BOOL_EVAL;
03413 break;
03414 }
03415
03416 }
03417
03418 switch (kind) {
03419 default:
03420 Tcl_AppendResult(interp, "ERROR, bad kind\n", (char *)NULL);
03421 bu_free((genptr_t)dgcdp, "dgo_drawtrees: dgcdp");
03422 return(-1);
03423 case 1:
03424
03425
03426
03427
03428
03429
03430
03431
03432
03433
03434
03435 if (DGO_SHADED_MODE_BOTS <= dgcdp->dmode && dgcdp->dmode <= DGO_SHADED_MODE_ALL) {
03436 int i;
03437 int ac = 1;
03438 char *av[2];
03439 #if 0
03440 struct directory *dp;
03441 #endif
03442
03443 av[1] = (char *)0;
03444
03445 for (i = 0; i < argc; ++i) {
03446 #if 0
03447 if ((dp = db_lookup(dgop->dgo_wdbp->dbip, argv[i], LOOKUP_NOISY)) == DIR_NULL)
03448 continue;
03449 #endif
03450
03451 av[0] = argv[i];
03452
03453 ret = db_walk_tree(dgop->dgo_wdbp->dbip,
03454 ac,
03455 (const char **)av,
03456 ncpu,
03457 &dgop->dgo_wdbp->wdb_initial_tree_state,
03458 0,
03459 dgo_bot_check_region_end,
03460 dgo_bot_check_leaf,
03461 (genptr_t)dgcdp);
03462 }
03463 } else
03464 ret = db_walk_tree(dgop->dgo_wdbp->dbip,
03465 argc,
03466 (const char **)argv,
03467 ncpu,
03468 &dgop->dgo_wdbp->wdb_initial_tree_state,
03469 0,
03470 dgo_wireframe_region_end,
03471 dgo_wireframe_leaf,
03472 (genptr_t)dgcdp);
03473 break;
03474 case 2:
03475 Tcl_AppendResult(interp, "drawtrees: can't do big-E here\n", (char *)NULL);
03476 bu_free((genptr_t)dgcdp, "dgo_drawtrees: dgcdp");
03477 return (-1);
03478 case 3:
03479 {
03480
03481 dgo_nmg_model = nmg_mm();
03482 dgop->dgo_wdbp->wdb_initial_tree_state.ts_m = &dgo_nmg_model;
03483 if (dgcdp->draw_edge_uses) {
03484 Tcl_AppendResult(interp, "Doing the edgeuse thang (-u)\n", (char *)NULL);
03485 dgcdp->draw_edge_uses_vbp = rt_vlblock_init();
03486 }
03487
03488 ret = db_walk_tree(dgop->dgo_wdbp->dbip, argc, (const char **)argv,
03489 ncpu,
03490 &dgop->dgo_wdbp->wdb_initial_tree_state,
03491 dgo_enable_fastpath ? dgo_nmg_region_start : 0,
03492 dgo_nmg_region_end,
03493 dgo_nmg_use_tnurbs ? nmg_booltree_leaf_tnurb : nmg_booltree_leaf_tess,
03494 (genptr_t)dgcdp);
03495
03496 if (dgcdp->draw_edge_uses) {
03497 dgo_cvt_vlblock_to_solids(dgop, interp, dgcdp->draw_edge_uses_vbp, "_EDGEUSES_", 0);
03498 rt_vlblock_free(dgcdp->draw_edge_uses_vbp);
03499 dgcdp->draw_edge_uses_vbp = (struct bn_vlblock *)NULL;
03500 }
03501
03502
03503 nmg_km(dgo_nmg_model);
03504 break;
03505 }
03506 }
03507 if (dgcdp->fastpath_count) {
03508 bu_log("%d region%s rendered through polygon fastpath\n",
03509 dgcdp->fastpath_count, dgcdp->fastpath_count==1?"":"s");
03510 }
03511
03512 bu_free((genptr_t)dgcdp, "dgo_drawtrees: dgcdp");
03513
03514 if (ret < 0)
03515 return (-1);
03516
03517 return (0);
03518 }
03519
03520
03521
03522
03523
03524 void
03525 dgo_cvt_vlblock_to_solids(struct dg_obj *dgop, Tcl_Interp *interp, struct bn_vlblock *vbp, char *name, int copy)
03526 {
03527 int i;
03528 char shortname[32];
03529 char namebuf[64];
03530
03531 strncpy(shortname, name, 16-6);
03532 shortname[16-6] = '\0';
03533
03534 for( i=0; i < vbp->nused; i++ ) {
03535 if (BU_LIST_IS_EMPTY(&(vbp->head[i])))
03536 continue;
03537
03538 sprintf(namebuf, "%s%lx",
03539 shortname, vbp->rgb[i]);
03540 dgo_invent_solid(dgop, interp, namebuf, &vbp->head[i], vbp->rgb[i], copy, 0.0, 0);
03541 }
03542 }
03543
03544
03545
03546
03547
03548
03549
03550
03551
03552
03553 int
03554 dgo_invent_solid(struct dg_obj *dgop,
03555 Tcl_Interp *interp,
03556 char *name,
03557 struct bu_list *vhead,
03558 long int rgb,
03559 int copy,
03560 fastf_t transparency,
03561 int dmode)
03562 {
03563 register struct directory *dp;
03564 struct directory *dpp[2] = {DIR_NULL, DIR_NULL};
03565 register struct solid *sp;
03566 unsigned char type='0';
03567
03568 if (dgop->dgo_wdbp->dbip == DBI_NULL)
03569 return 0;
03570
03571 if ((dp = db_lookup(dgop->dgo_wdbp->dbip, name, LOOKUP_QUIET)) != DIR_NULL) {
03572 if (dp->d_addr != RT_DIR_PHONY_ADDR) {
03573 Tcl_AppendResult(interp, "dgo_invent_solid(", name,
03574 ") would clobber existing database entry, ignored\n", (char *)NULL);
03575 return (-1);
03576 }
03577
03578
03579
03580
03581
03582 dpp[0] = dp;
03583 dgo_eraseobjall(dgop, interp, dpp);
03584 }
03585
03586 dp = db_diradd(dgop->dgo_wdbp->dbip, name, RT_DIR_PHONY_ADDR, 0, DIR_SOLID, (genptr_t)&type);
03587
03588
03589 GET_SOLID(sp,&FreeSolid.l);
03590
03591 if (copy) {
03592 BU_LIST_INIT( &(sp->s_vlist) );
03593 rt_vlist_copy( &(sp->s_vlist), vhead );
03594 } else {
03595
03596 BU_LIST_APPEND_LIST( &(sp->s_vlist), vhead );
03597 BU_LIST_INIT(vhead);
03598 }
03599 dgo_bound_solid(interp, sp);
03600
03601
03602 db_add_node_to_full_path( &sp->s_fullpath, dp );
03603
03604 sp->s_iflag = DOWN;
03605 sp->s_soldash = 0;
03606 sp->s_Eflag = 1;
03607 sp->s_color[0] = sp->s_basecolor[0] = (rgb>>16) & 0xFF;
03608 sp->s_color[1] = sp->s_basecolor[1] = (rgb>> 8) & 0xFF;
03609 sp->s_color[2] = sp->s_basecolor[2] = (rgb ) & 0xFF;
03610 sp->s_regionid = 0;
03611 sp->s_dlist = BU_LIST_LAST(solid, &dgop->dgo_headSolid)->s_dlist + 1;
03612
03613 sp->s_uflag = 0;
03614 sp->s_dflag = 0;
03615 sp->s_cflag = 0;
03616 sp->s_wflag = 0;
03617
03618 sp->s_transparency = transparency;
03619 sp->s_dmode = dmode;
03620
03621
03622 BU_LIST_APPEND(dgop->dgo_headSolid.back, &sp->l);
03623
03624 return (0);
03625 }
03626
03627
03628
03629
03630
03631
03632 static void
03633 dgo_bound_solid(Tcl_Interp *interp, register struct solid *sp)
03634 {
03635 register struct bn_vlist *vp;
03636 register double xmax, ymax, zmax;
03637 register double xmin, ymin, zmin;
03638
03639 xmax = ymax = zmax = -INFINITY;
03640 xmin = ymin = zmin = INFINITY;
03641 sp->s_vlen = 0;
03642 for (BU_LIST_FOR(vp, bn_vlist, &(sp->s_vlist))) {
03643 register int j;
03644 register int nused = vp->nused;
03645 register int *cmd = vp->cmd;
03646 register point_t *pt = vp->pt;
03647 for (j = 0; j < nused; j++,cmd++,pt++) {
03648 switch (*cmd) {
03649 case BN_VLIST_POLY_START:
03650 case BN_VLIST_POLY_VERTNORM:
03651
03652 break;
03653 case BN_VLIST_LINE_MOVE:
03654 case BN_VLIST_LINE_DRAW:
03655 case BN_VLIST_POLY_MOVE:
03656 case BN_VLIST_POLY_DRAW:
03657 case BN_VLIST_POLY_END:
03658 V_MIN(xmin, (*pt)[X]);
03659 V_MAX(xmax, (*pt)[X]);
03660 V_MIN(ymin, (*pt)[Y]);
03661 V_MAX(ymax, (*pt)[Y]);
03662 V_MIN(zmin, (*pt)[Z]);
03663 V_MAX(zmax, (*pt)[Z]);
03664 break;
03665 default:
03666 {
03667 struct bu_vls tmp_vls;
03668
03669 bu_vls_init(&tmp_vls);
03670 bu_vls_printf(&tmp_vls, "unknown vlist op %d\n", *cmd);
03671 Tcl_AppendResult(interp, bu_vls_addr(&tmp_vls), (char *)NULL);
03672 bu_vls_free(&tmp_vls);
03673 }
03674 }
03675 }
03676 sp->s_vlen += nused;
03677 }
03678
03679 sp->s_center[X] = (xmin + xmax) * 0.5;
03680 sp->s_center[Y] = (ymin + ymax) * 0.5;
03681 sp->s_center[Z] = (zmin + zmax) * 0.5;
03682
03683 sp->s_size = xmax - xmin;
03684 V_MAX( sp->s_size, ymax - ymin );
03685 V_MAX( sp->s_size, zmax - zmin );
03686 }
03687
03688
03689
03690
03691
03692
03693
03694
03695
03696 void
03697 dgo_drawH_part2(int dashflag, struct bu_list *vhead, struct db_full_path *pathp, struct db_tree_state *tsp, struct solid *existing_sp, struct dg_client_data *dgcdp)
03698 {
03699 register struct solid *sp;
03700
03701 if (!existing_sp) {
03702
03703 GET_SOLID(sp, &FreeSolid.l);
03704
03705
03706 sp->s_dlist = BU_LIST_LAST(solid, &dgcdp->dgop->dgo_headSolid)->s_dlist + 1;
03707 } else {
03708
03709
03710
03711 sp = existing_sp;
03712 }
03713
03714
03715
03716
03717
03718 BU_LIST_APPEND_LIST(&(sp->s_vlist), vhead);
03719 dgo_bound_solid(dgcdp->interp, sp);
03720
03721
03722
03723
03724
03725 if (!existing_sp) {
03726
03727 if (dgcdp->wireframe_color_override) {
03728
03729 sp->s_uflag = 1;
03730 sp->s_dflag = 0;
03731 sp->s_basecolor[0] = dgcdp->wireframe_color[0];
03732 sp->s_basecolor[1] = dgcdp->wireframe_color[1];
03733 sp->s_basecolor[2] = dgcdp->wireframe_color[2];
03734 } else {
03735 sp->s_uflag = 0;
03736 if (tsp) {
03737 if (tsp->ts_mater.ma_color_valid) {
03738 sp->s_dflag = 0;
03739 sp->s_basecolor[0] = tsp->ts_mater.ma_color[0] * 255.;
03740 sp->s_basecolor[1] = tsp->ts_mater.ma_color[1] * 255.;
03741 sp->s_basecolor[2] = tsp->ts_mater.ma_color[2] * 255.;
03742 } else {
03743 sp->s_dflag = 1;
03744 sp->s_basecolor[0] = 255;
03745 sp->s_basecolor[1] = 0;
03746 sp->s_basecolor[2] = 0;
03747 }
03748 }
03749 }
03750 sp->s_cflag = 0;
03751 sp->s_flag = DOWN;
03752 sp->s_iflag = DOWN;
03753 sp->s_soldash = dashflag;
03754 sp->s_Eflag = 0;
03755 db_dup_full_path( &sp->s_fullpath, pathp );
03756 sp->s_regionid = tsp->ts_regionid;
03757 sp->s_transparency = dgcdp->transparency;
03758 sp->s_dmode = dgcdp->dmode;
03759
03760
03761 bu_semaphore_acquire(RT_SEM_MODEL);
03762 BU_LIST_APPEND(dgcdp->dgop->dgo_headSolid.back, &sp->l);
03763 bu_semaphore_release(RT_SEM_MODEL);
03764 }
03765
03766 #if 0
03767
03768 if (!existing_sp) {
03769
03770 bu_semaphore_acquire(RT_SEM_MODEL);
03771 BU_LIST_APPEND(dgcdp->dgop->dgo_headSolid.back, &sp->l);
03772 bu_semaphore_release(RT_SEM_MODEL);
03773 } else {
03774
03775 sp->s_flag = UP;
03776 }
03777 #endif
03778 }
03779
03780
03781
03782
03783
03784
03785
03786 void
03787 dgo_eraseobjall_callback(struct db_i *dbip,
03788 Tcl_Interp *interp,
03789 struct directory *dp,
03790 int notify)
03791 {
03792 struct dg_obj *dgop;
03793 struct directory *dpp[2] = {DIR_NULL, DIR_NULL};
03794
03795 dpp[0] = dp;
03796 for (BU_LIST_FOR(dgop, dg_obj, &HeadDGObj.l))
03797
03798 if (dgop->dgo_wdbp->dbip == dbip) {
03799 dgo_eraseobjall(dgop, interp, dpp);
03800
03801 if (notify)
03802 dgo_notify(dgop, interp);
03803 }
03804 }
03805
03806
03807
03808
03809
03810 void
03811 dgo_eraseobjpath(struct dg_obj *dgop,
03812 Tcl_Interp *interp,
03813 int argc,
03814 char **argv,
03815 int noisy,
03816 int all)
03817 {
03818 register struct directory *dp;
03819 register int i;
03820 struct bu_vls vls;
03821 #if 0
03822 Tcl_Obj *save_result;
03823
03824 save_result = Tcl_GetObjResult(interp);
03825 Tcl_IncrRefCount(save_result);
03826 #endif
03827
03828 bu_vls_init(&vls);
03829 for (i = 0; i < argc; i++) {
03830 int j;
03831 char *list;
03832 int ac;
03833 char **av, **av_orig;
03834 struct directory **dpp = (struct directory **)0;
03835
03836 #if 0
03837 bu_vls_trunc(&vls, 0);
03838 bu_vls_printf(&vls, "split %s /", argv[i]);
03839 if (Tcl_Eval(interp, bu_vls_addr(&vls)) != TCL_OK) {
03840 continue;
03841 }
03842 list = Tcl_GetStringResult(interp);
03843 #else
03844 {
03845 char *begin;
03846 char *end;
03847 char *newstr = strdup(argv[i]);
03848
03849 begin = newstr;
03850 bu_vls_trunc(&vls, 0);
03851
03852 while ((end = strchr(begin, '/')) != NULL) {
03853 *end = '\0';
03854 bu_vls_printf(&vls, "%s ", begin);
03855 begin = end + 1;
03856 }
03857 bu_vls_printf(&vls, "%s ", begin);
03858 free((void *)newstr);
03859 }
03860 list = bu_vls_addr(&vls);
03861 #endif
03862 if (Tcl_SplitList(interp, list, &ac, (const char ***)&av_orig) != TCL_OK)
03863 continue;
03864
03865
03866 if ( ( ac == 0 ) || (av_orig == 0) || ( *av_orig == 0 ) ) {
03867 bu_log("WARNING: Asked to look up a null-named database object\n");
03868 goto end;
03869 }
03870
03871
03872 av = av_orig;
03873
03874 if (*av[0] == '\0') {
03875 --ac;
03876 ++av;
03877 }
03878
03879
03880 if (*av[ac-1] == '\0')
03881 --ac;
03882
03883 dpp = bu_calloc(ac+1, sizeof(struct directory *), "eraseobjpath: directory pointers");
03884 for (j = 0; j < ac; ++j)
03885 if ((dp = db_lookup(dgop->dgo_wdbp->dbip, av[j], noisy)) != DIR_NULL)
03886 dpp[j] = dp;
03887 else
03888 goto end;
03889
03890 dpp[j] = DIR_NULL;
03891
03892 if (all)
03893 dgo_eraseobjall(dgop, interp, dpp);
03894 else
03895 dgo_eraseobj(dgop, interp, dpp);
03896
03897 end:
03898 bu_free((genptr_t)dpp, "eraseobjpath: directory pointers");
03899 Tcl_Free((char *)av_orig);
03900 }
03901 bu_vls_free(&vls);
03902
03903 #if 0
03904 Tcl_SetObjResult(interp, save_result);
03905 Tcl_DecrRefCount(save_result);
03906 #endif
03907 }
03908
03909
03910
03911
03912
03913
03914
03915 static void
03916 dgo_eraseobjall(struct dg_obj *dgop,
03917 Tcl_Interp *interp,
03918 register struct directory **dpp)
03919 {
03920 register struct directory **tmp_dpp;
03921 register struct solid *sp;
03922 register struct solid *nsp;
03923 struct db_full_path subpath;
03924
03925 if(dgop->dgo_wdbp->dbip == DBI_NULL)
03926 return;
03927
03928 if (*dpp == DIR_NULL)
03929 return;
03930
03931 db_full_path_init(&subpath);
03932 for (tmp_dpp = dpp; *tmp_dpp != DIR_NULL; ++tmp_dpp) {
03933 RT_CK_DIR(*tmp_dpp);
03934 db_add_node_to_full_path(&subpath, *tmp_dpp);
03935 }
03936
03937 sp = BU_LIST_NEXT(solid, &dgop->dgo_headSolid);
03938 while (BU_LIST_NOT_HEAD(sp, &dgop->dgo_headSolid)) {
03939 nsp = BU_LIST_PNEXT(solid, sp);
03940 if( db_full_path_subset( &sp->s_fullpath, &subpath ) ) {
03941 BU_LIST_DEQUEUE(&sp->l);
03942 FREE_SOLID(sp, &FreeSolid.l);
03943 }
03944 sp = nsp;
03945 }
03946
03947 if ((*dpp)->d_addr == RT_DIR_PHONY_ADDR) {
03948 if (db_dirdelete(dgop->dgo_wdbp->dbip, *dpp) < 0) {
03949 Tcl_AppendResult(interp, "dgo_eraseobjall: db_dirdelete failed\n", (char *)NULL);
03950 }
03951 }
03952 db_free_full_path(&subpath);
03953 }
03954
03955
03956
03957
03958
03959
03960
03961
03962 static void
03963 dgo_eraseobj(struct dg_obj *dgop,
03964 Tcl_Interp *interp,
03965 register struct directory **dpp)
03966 {
03967 #if 1
03968
03969
03970
03971
03972 register struct directory **tmp_dpp;
03973 register struct solid *sp;
03974 register struct solid *nsp;
03975 register int i;
03976
03977 if(dgop->dgo_wdbp->dbip == DBI_NULL)
03978 return;
03979
03980 if (*dpp == DIR_NULL)
03981 return;
03982
03983 for (tmp_dpp = dpp; *tmp_dpp != DIR_NULL; ++tmp_dpp)
03984 RT_CK_DIR(*tmp_dpp);
03985
03986 sp = BU_LIST_FIRST(solid, &dgop->dgo_headSolid);
03987 while (BU_LIST_NOT_HEAD(sp, &dgop->dgo_headSolid)) {
03988 nsp = BU_LIST_PNEXT(solid, sp);
03989 for (i = 0, tmp_dpp = dpp;
03990 i < sp->s_fullpath.fp_len && *tmp_dpp != DIR_NULL;
03991 ++i, ++tmp_dpp)
03992 if (sp->s_fullpath.fp_names[i] != *tmp_dpp)
03993 goto end;
03994
03995 if (*tmp_dpp != DIR_NULL)
03996 goto end;
03997
03998 BU_LIST_DEQUEUE(&sp->l);
03999 FREE_SOLID(sp, &FreeSolid.l);
04000 end:
04001 sp = nsp;
04002 }
04003
04004 if ((*dpp)->d_addr == RT_DIR_PHONY_ADDR ) {
04005 if (db_dirdelete(dgop->dgo_wdbp->dbip, *dpp) < 0) {
04006 Tcl_AppendResult(interp, "dgo_eraseobj: db_dirdelete failed\n", (char *)NULL);
04007 }
04008 }
04009 #else
04010 register struct directory **tmp_dpp;
04011 register struct solid *sp;
04012 register struct solid *nsp;
04013 struct db_full_path subpath;
04014
04015 if(dgop->dgo_wdbp->dbip == DBI_NULL)
04016 return;
04017
04018 if (*dpp == DIR_NULL)
04019 return;
04020
04021 db_full_path_init(&subpath);
04022 for (tmp_dpp = dpp; *tmp_dpp != DIR_NULL; ++tmp_dpp) {
04023 RT_CK_DIR(*tmp_dpp);
04024 db_add_node_to_full_path(&subpath, *tmp_dpp);
04025 }
04026
04027 sp = BU_LIST_FIRST(solid, &dgop->dgo_headSolid);
04028 while (BU_LIST_NOT_HEAD(sp, &dgop->dgo_headSolid)) {
04029 nsp = BU_LIST_PNEXT(solid, sp);
04030 if( db_full_path_subset( &sp->s_fullpath, &subpath ) ) {
04031 BU_LIST_DEQUEUE(&sp->l);
04032 FREE_SOLID(sp, &FreeSolid.l);
04033 }
04034 sp = nsp;
04035 }
04036
04037 if ((*dpp)->d_addr == RT_DIR_PHONY_ADDR ) {
04038 if (db_dirdelete(dgop->dgo_wdbp->dbip, *dpp) < 0) {
04039 Tcl_AppendResult(interp, "dgo_eraseobj: db_dirdelete failed\n", (char *)NULL);
04040 }
04041 }
04042 db_free_full_path(&subpath);
04043 #endif
04044 }
04045
04046
04047
04048
04049
04050
04051
04052 void
04053 dgo_color_soltab(struct solid *hsp)
04054 {
04055 register struct solid *sp;
04056 register struct mater *mp;
04057
04058 FOR_ALL_SOLIDS(sp, &hsp->l) {
04059 sp->s_cflag = 0;
04060
04061
04062 if (sp->s_uflag) {
04063 sp->s_color[0] = sp->s_basecolor[0];
04064 sp->s_color[1] = sp->s_basecolor[1];
04065 sp->s_color[2] = sp->s_basecolor[2];
04066 continue;
04067 }
04068
04069 for (mp = rt_material_head; mp != MATER_NULL; mp = mp->mt_forw) {
04070 if (sp->s_regionid <= mp->mt_high &&
04071 sp->s_regionid >= mp->mt_low) {
04072 sp->s_color[0] = mp->mt_r;
04073 sp->s_color[1] = mp->mt_g;
04074 sp->s_color[2] = mp->mt_b;
04075 goto done;
04076 }
04077 }
04078
04079
04080
04081
04082
04083
04084
04085
04086
04087
04088 if (sp->s_dflag)
04089 sp->s_cflag = 1;
04090
04091 sp->s_color[0] = sp->s_basecolor[0];
04092 sp->s_color[1] = sp->s_basecolor[1];
04093 sp->s_color[2] = sp->s_basecolor[2];
04094 done: ;
04095 }
04096 }
04097
04098
04099
04100
04101
04102
04103 int
04104 dgo_build_tops(Tcl_Interp *interp,
04105 struct solid *hsp,
04106 char **start,
04107 register char **end)
04108 {
04109 register char **vp = start;
04110 register struct solid *sp;
04111
04112
04113
04114
04115
04116 FOR_ALL_SOLIDS(sp, &hsp->l)
04117 sp->s_flag = DOWN;
04118 FOR_ALL_SOLIDS(sp, &hsp->l) {
04119 register struct solid *forw;
04120 struct directory *dp = FIRST_SOLID(sp);
04121
04122 if (sp->s_flag == UP)
04123 continue;
04124 if (dp->d_addr == RT_DIR_PHONY_ADDR)
04125 continue;
04126 if (vp < end)
04127 *vp++ = dp->d_namep;
04128 else {
04129 Tcl_AppendResult(interp, "mged: ran out of comand vector space at ",
04130 dp->d_namep, "\n", (char *)NULL);
04131 break;
04132 }
04133 sp->s_flag = UP;
04134 for (BU_LIST_PFOR(forw, sp, solid, &hsp->l)) {
04135 if (FIRST_SOLID(forw) == dp)
04136 forw->s_flag = UP;
04137 }
04138 }
04139 *vp = (char *) 0;
04140 return vp-start;
04141 }
04142
04143
04144
04145
04146
04147
04148
04149
04150
04151 static void
04152 dgo_rt_write(struct dg_obj *dgop,
04153 struct view_obj *vop,
04154 FILE *fp,
04155 vect_t eye_model)
04156 {
04157 register int i;
04158 quat_t quat;
04159 register struct solid *sp;
04160
04161 (void)fprintf(fp, "viewsize %.15e;\n", vop->vo_size);
04162 quat_mat2quat(quat, vop->vo_rotation );
04163 (void)fprintf(fp, "orientation %.15e %.15e %.15e %.15e;\n", V4ARGS(quat));
04164 (void)fprintf(fp, "eye_pt %.15e %.15e %.15e;\n",
04165 eye_model[X], eye_model[Y], eye_model[Z] );
04166
04167 (void)fprintf(fp, "start 0; clean;\n");
04168 FOR_ALL_SOLIDS (sp, &dgop->dgo_headSolid) {
04169 for (i=0;i<sp->s_fullpath.fp_len;i++) {
04170 DB_FULL_PATH_GET(&sp->s_fullpath,i)->d_flags &= ~DIR_USED;
04171 }
04172 }
04173 FOR_ALL_SOLIDS(sp, &dgop->dgo_headSolid) {
04174 for (i=0; i<sp->s_fullpath.fp_len; i++ ) {
04175 if (!(DB_FULL_PATH_GET(&sp->s_fullpath,i)->d_flags & DIR_USED)) {
04176 register struct animate *anp;
04177 for (anp = DB_FULL_PATH_GET(&sp->s_fullpath,i)->d_animate; anp;
04178 anp=anp->an_forw) {
04179 db_write_anim(fp, anp);
04180 }
04181 DB_FULL_PATH_GET(&sp->s_fullpath,i)->d_flags |= DIR_USED;
04182 }
04183 }
04184 }
04185
04186 FOR_ALL_SOLIDS(sp, &dgop->dgo_headSolid) {
04187 for (i=0;i< sp->s_fullpath.fp_len;i++) {
04188 DB_FULL_PATH_GET(&sp->s_fullpath,i)->d_flags &= ~DIR_USED;
04189 }
04190 }
04191 (void)fprintf(fp, "end;\n");
04192 }
04193
04194 #ifndef _WIN32
04195 static void
04196 dgo_rt_output_handler(ClientData clientData,
04197 int mask)
04198 {
04199 struct dg_rt_client_data *drcdp = (struct dg_rt_client_data *)clientData;
04200 struct run_rt *run_rtp;
04201 int count;
04202 char line[RT_MAXLINE+1];
04203
04204 if (drcdp == (struct dg_rt_client_data *)NULL ||
04205 drcdp->dgop == (struct dg_obj *)NULL ||
04206 drcdp->rrtp == (struct run_rt *)NULL ||
04207 drcdp->interp == (Tcl_Interp *)NULL)
04208 return;
04209
04210 run_rtp = drcdp->rrtp;
04211
04212
04213 count = read((int)run_rtp->fd, line, RT_MAXLINE);
04214 if (count <= 0) {
04215 int retcode;
04216 int rpid;
04217 int aborted;
04218
04219 if (count < 0) {
04220 perror("READ ERROR");
04221 }
04222
04223 Tcl_DeleteFileHandler(run_rtp->fd);
04224 close(run_rtp->fd);
04225
04226
04227 while ((rpid = wait(&retcode)) != run_rtp->pid && rpid != -1);
04228
04229 aborted = run_rtp->aborted;
04230
04231 if (drcdp->dgop->dgo_outputHandler != NULL) {
04232 struct bu_vls vls;
04233
04234 bu_vls_init(&vls);
04235
04236 if (aborted)
04237 bu_vls_printf(&vls, "%s \"Raytrace aborted.\n\"",
04238 drcdp->dgop->dgo_outputHandler);
04239 else
04240 bu_vls_printf(&vls, "%s \"Raytrace complete.\n\"",
04241 drcdp->dgop->dgo_outputHandler);
04242
04243 Tcl_Eval(drcdp->interp, bu_vls_addr(&vls));
04244 bu_vls_free(&vls);
04245 } else {
04246 if (aborted)
04247 bu_log("Raytrace aborted.\n");
04248 else
04249 bu_log("Raytrace complete.\n");
04250 }
04251
04252
04253 BU_LIST_DEQUEUE(&run_rtp->l);
04254 bu_free((genptr_t)run_rtp, "dgo_rt_output_handler: run_rtp");
04255
04256 bu_free((genptr_t)drcdp, "dgo_rt_output_handler: drcdp");
04257
04258 return;
04259 }
04260
04261 line[count] = '\0';
04262
04263
04264 if (drcdp->dgop->dgo_outputHandler != NULL) {
04265 struct bu_vls vls;
04266
04267 bu_vls_init(&vls);
04268 bu_vls_printf(&vls, "%s \"%s\"", drcdp->dgop->dgo_outputHandler, line);
04269 Tcl_Eval(drcdp->interp, bu_vls_addr(&vls));
04270 bu_vls_free(&vls);
04271 } else
04272 bu_log("%s", line);
04273 }
04274
04275 #else
04276 static void
04277 dgo_rt_output_handler(ClientData clientData,
04278 int mask)
04279 {
04280 struct dg_rt_client_data *drcdp = (struct dg_rt_client_data *)clientData;
04281 struct run_rt *run_rtp;
04282 int count;
04283 char line[10240+1] = {0};
04284
04285 if (drcdp == (struct dg_rt_client_data *)NULL ||
04286 drcdp->dgop == (struct dg_obj *)NULL ||
04287 drcdp->rrtp == (struct run_rt *)NULL ||
04288 drcdp->interp == (Tcl_Interp *)NULL)
04289 return;
04290
04291 run_rtp = drcdp->rrtp;
04292
04293
04294 if (Tcl_Eof(run_rtp->chan) ||
04295 (!ReadFile(run_rtp->fd, line, 10240,&count,0))) {
04296 int aborted;
04297
04298 Tcl_DeleteChannelHandler(run_rtp->chan,
04299 dgo_rt_output_handler,
04300 (ClientData)drcdp);
04301 Tcl_Close(drcdp->interp, run_rtp->chan);
04302 CloseHandle(run_rtp->fd);
04303
04304
04305
04306
04307
04308 WaitForSingleObject( run_rtp->hProcess, 120 );
04309
04310
04311
04312
04313 if(GetLastError() == ERROR_PROCESS_ABORTED) {
04314 run_rtp->aborted = 1;
04315 }
04316
04317 aborted = run_rtp->aborted;
04318
04319 if (drcdp->dgop->dgo_outputHandler != NULL) {
04320 struct bu_vls vls;
04321
04322 bu_vls_init(&vls);
04323
04324 if (aborted)
04325 bu_vls_printf(&vls, "%s \"Raytrace aborted.\n\"",
04326 drcdp->dgop->dgo_outputHandler);
04327 else
04328 bu_vls_printf(&vls, "%s \"Raytrace complete.\n\"",
04329 drcdp->dgop->dgo_outputHandler);
04330
04331 Tcl_Eval(drcdp->interp, bu_vls_addr(&vls));
04332 bu_vls_free(&vls);
04333 } else {
04334 if (aborted)
04335 bu_log("Raytrace aborted.\n");
04336 else
04337 bu_log("Raytrace complete.\n");
04338 }
04339
04340
04341 BU_LIST_DEQUEUE(&run_rtp->l);
04342 bu_free((genptr_t)run_rtp, "dgo_rt_output_handler: run_rtp");
04343
04344 bu_free((genptr_t)drcdp, "dgo_rt_output_handler: drcdp");
04345
04346 return;
04347 }
04348
04349 line[count] = '\0';
04350
04351
04352 if (drcdp->dgop->dgo_outputHandler != NULL) {
04353 struct bu_vls vls;
04354
04355 bu_vls_init(&vls);
04356 bu_vls_printf(&vls, "%s \"%s\"", drcdp->dgop->dgo_outputHandler, line);
04357 Tcl_Eval(drcdp->interp, bu_vls_addr(&vls));
04358 bu_vls_free(&vls);
04359 } else
04360 bu_log("%s", line);
04361 }
04362
04363 #endif
04364
04365 static void
04366 dgo_rt_set_eye_model(struct dg_obj *dgop,
04367 struct view_obj *vop,
04368 vect_t eye_model)
04369 {
04370 if (vop->vo_zclip || vop->vo_perspective > 0) {
04371 vect_t temp;
04372
04373 VSET(temp, 0.0, 0.0, 1.0);
04374 MAT4X3PNT(eye_model, vop->vo_view2model, temp);
04375 } else {
04376
04377 register struct solid *sp;
04378 register int i;
04379 double t;
04380 double t_in;
04381 vect_t direction;
04382 vect_t extremum[2];
04383 vect_t minus, plus;
04384
04385 VSET(eye_model, -vop->vo_center[MDX],
04386 -vop->vo_center[MDY], -vop->vo_center[MDZ]);
04387
04388 for (i = 0; i < 3; ++i) {
04389 extremum[0][i] = INFINITY;
04390 extremum[1][i] = -INFINITY;
04391 }
04392
04393 FOR_ALL_SOLIDS (sp, &dgop->dgo_headSolid) {
04394 minus[X] = sp->s_center[X] - sp->s_size;
04395 minus[Y] = sp->s_center[Y] - sp->s_size;
04396 minus[Z] = sp->s_center[Z] - sp->s_size;
04397 VMIN( extremum[0], minus );
04398 plus[X] = sp->s_center[X] + sp->s_size;
04399 plus[Y] = sp->s_center[Y] + sp->s_size;
04400 plus[Z] = sp->s_center[Z] + sp->s_size;
04401 VMAX( extremum[1], plus );
04402 }
04403 VMOVEN(direction, vop->vo_rotation + 8, 3);
04404 VSCALE(direction, direction, -1.0);
04405 for (i = 0; i < 3; ++i)
04406 if (NEAR_ZERO(direction[i], 1e-10))
04407 direction[i] = 0.0;
04408 if ((eye_model[X] >= extremum[0][X]) &&
04409 (eye_model[X] <= extremum[1][X]) &&
04410 (eye_model[Y] >= extremum[0][Y]) &&
04411 (eye_model[Y] <= extremum[1][Y]) &&
04412 (eye_model[Z] >= extremum[0][Z]) &&
04413 (eye_model[Z] <= extremum[1][Z])) {
04414 t_in = -INFINITY;
04415 for (i = 0; i < 6; ++i) {
04416 if (direction[i%3] == 0)
04417 continue;
04418 t = (extremum[i/3][i%3] - eye_model[i%3]) /
04419 direction[i%3];
04420 if ((t < 0) && (t > t_in))
04421 t_in = t;
04422 }
04423 VJOIN1(eye_model, eye_model, t_in, direction);
04424 }
04425 }
04426 }
04427
04428
04429
04430
04431 static int
04432 dgo_run_rt(struct dg_obj *dgop,
04433 struct view_obj *vop)
04434 {
04435 register int i;
04436 FILE *fp_in;
04437 #ifndef _WIN32
04438 int pipe_in[2];
04439 int pipe_err[2];
04440 #else
04441 HANDLE pipe_in[2],pipe_inDup;
04442 HANDLE pipe_err[2],pipe_errDup;
04443 STARTUPINFO si = {0};
04444 PROCESS_INFORMATION pi = {0};
04445 SECURITY_ATTRIBUTES sa = {0};
04446 char line[2048];
04447 char name[256];
04448 #endif
04449 vect_t eye_model;
04450 struct run_rt *run_rtp;
04451 struct dg_rt_client_data *drcdp;
04452 #ifndef _WIN32
04453 int pid;
04454
04455 (void)pipe(pipe_in);
04456 (void)pipe(pipe_err);
04457
04458 if ((pid = fork()) == 0) {
04459
04460 setpgid(0, 0);
04461
04462
04463 (void)close(0);
04464 (void)dup(pipe_in[0]);
04465 (void)close(2);
04466 (void)dup(pipe_err[1]);
04467
04468
04469 (void)close(pipe_in[0]);
04470 (void)close(pipe_in[1]);
04471 (void)close(pipe_err[0]);
04472 (void)close(pipe_err[1]);
04473
04474 for (i=3; i < 20; i++)
04475 (void)close(i);
04476
04477 (void)execvp(dgop->dgo_rt_cmd[0], dgop->dgo_rt_cmd);
04478 perror(dgop->dgo_rt_cmd[0]);
04479 exit(16);
04480 }
04481
04482
04483 (void)close(pipe_in[0]);
04484 fp_in = fdopen(pipe_in[1], "w");
04485
04486 (void)close(pipe_err[1]);
04487
04488 dgo_rt_set_eye_model(dgop, vop, eye_model);
04489 dgo_rt_write(dgop, vop, fp_in, eye_model);
04490 (void)fclose(fp_in);
04491
04492 BU_GETSTRUCT(run_rtp, run_rt);
04493 BU_LIST_INIT(&run_rtp->l);
04494 BU_LIST_APPEND(&dgop->dgo_headRunRt.l, &run_rtp->l);
04495
04496 run_rtp->fd = pipe_err[0];
04497 run_rtp->pid = pid;
04498
04499 BU_GETSTRUCT(drcdp, dg_rt_client_data);
04500 drcdp->dgop = dgop;
04501 drcdp->rrtp = run_rtp;
04502 drcdp->interp = dgop->dgo_wdbp->wdb_interp;
04503
04504 Tcl_CreateFileHandler(run_rtp->fd,
04505 TCL_READABLE,
04506 dgo_rt_output_handler,
04507 (ClientData)drcdp);
04508
04509 return 0;
04510
04511 #else
04512 sa.nLength = sizeof(sa);
04513 sa.bInheritHandle = TRUE;
04514 sa.lpSecurityDescriptor = NULL;
04515
04516
04517 CreatePipe( &pipe_err[0], &pipe_err[1], &sa, 0);
04518
04519
04520 DuplicateHandle( GetCurrentProcess(), pipe_err[0],
04521 GetCurrentProcess(), &pipe_errDup ,
04522 0, FALSE,
04523 DUPLICATE_SAME_ACCESS );
04524 CloseHandle( pipe_err[0] );
04525
04526
04527 CreatePipe(&pipe_in[0], &pipe_in[1], &sa, 0);
04528
04529
04530 DuplicateHandle(GetCurrentProcess(), pipe_in[1],
04531 GetCurrentProcess(), &pipe_inDup,
04532 0, FALSE,
04533 DUPLICATE_SAME_ACCESS );
04534 CloseHandle(pipe_in[1]);
04535
04536
04537 si.cb = sizeof(STARTUPINFO);
04538 si.lpReserved = NULL;
04539 si.lpReserved2 = NULL;
04540 si.cbReserved2 = 0;
04541 si.lpDesktop = NULL;
04542 si.dwFlags = STARTF_USESTDHANDLES;
04543 si.hStdInput = pipe_in[0];
04544 si.hStdOutput = pipe_err[1];
04545 si.hStdError = pipe_err[1];
04546
04547 sprintf(line,"%s ",dgop->dgo_rt_cmd[0]);
04548 for(i=1;i<dgop->dgo_rt_cmd_len;i++) {
04549 sprintf(name,"%s ",dgop->dgo_rt_cmd[i]);
04550 strcat(line,name); }
04551
04552
04553 CreateProcess(NULL, line, NULL, NULL, TRUE,
04554 DETACHED_PROCESS, NULL, NULL,
04555 &si, &pi);
04556
04557 CloseHandle(pipe_in[0]);
04558 CloseHandle(pipe_err[1]);
04559
04560
04561 fp_in = _fdopen( _open_osfhandle((HFILE)pipe_inDup,_O_TEXT), "wb" );
04562 _setmode(_fileno(fp_in), _O_BINARY);
04563
04564 dgo_rt_set_eye_model(dgop, vop, eye_model);
04565 dgo_rt_write(dgop, vop, fp_in, eye_model);
04566 (void)fclose(fp_in);
04567
04568 BU_GETSTRUCT(run_rtp, run_rt);
04569 BU_LIST_INIT(&run_rtp->l);
04570 BU_LIST_APPEND(&dgop->dgo_headRunRt.l, &run_rtp->l);
04571
04572 run_rtp->fd = pipe_errDup;
04573 run_rtp->hProcess = pi.hProcess;
04574 run_rtp->pid = pi.dwProcessId;
04575 run_rtp->aborted=0;
04576 run_rtp->chan = Tcl_MakeFileChannel(run_rtp->fd, TCL_READABLE);
04577
04578 BU_GETSTRUCT(drcdp, dg_rt_client_data);
04579 drcdp->dgop = dgop;
04580 drcdp->rrtp = run_rtp;
04581 drcdp->interp = dgop->dgo_wdbp->wdb_interp;
04582
04583 Tcl_CreateChannelHandler(run_rtp->chan,
04584 TCL_READABLE,
04585 dgo_rt_output_handler,
04586 (ClientData)drcdp);
04587
04588 return 0;
04589
04590 #endif
04591
04592 }
04593
04594 void
04595 dgo_notify(struct dg_obj *dgop,
04596 Tcl_Interp *interp)
04597 {
04598 bu_observer_notify(interp, &dgop->dgo_observers, bu_vls_addr(&dgop->dgo_name));
04599 }
04600
04601 void
04602 dgo_notifyWdb(struct rt_wdb *wdbp,
04603 Tcl_Interp *interp)
04604 {
04605 struct dg_obj *dgop;
04606
04607 for (BU_LIST_FOR(dgop, dg_obj, &HeadDGObj.l))
04608 if (dgop->dgo_wdbp == wdbp)
04609 dgo_notify(dgop, interp);
04610 }
04611
04612 void
04613 dgo_impending_wdb_close(struct rt_wdb *wdbp,
04614 Tcl_Interp *interp)
04615 {
04616 struct dg_obj *dgop;
04617
04618 for (BU_LIST_FOR(dgop, dg_obj, &HeadDGObj.l))
04619 if (dgop->dgo_wdbp == wdbp) {
04620 dgo_zap_cmd(dgop, interp);
04621 dgop->dgo_wdbp = RT_WDB_NULL;
04622 dgo_notify(dgop, interp);
04623 }
04624 }
04625
04626 void
04627 dgo_zapall(struct rt_wdb *wdbp, Tcl_Interp *interp)
04628 {
04629 struct dg_obj *dgop;
04630
04631 for (BU_LIST_FOR(dgop, dg_obj, &HeadDGObj.l))
04632 if (dgop->dgo_wdbp == wdbp) {
04633 dgo_zap_cmd(dgop, interp);
04634 dgo_notify(dgop, interp);
04635 }
04636 }
04637
04638
04639
04640
04641
04642
04643
04644
04645 static void
04646 dgo_print_schain(struct dg_obj *dgop, Tcl_Interp *interp, int lvl)
04647
04648
04649
04650 {
04651 register struct solid *sp;
04652 register struct bn_vlist *vp;
04653 int nvlist;
04654 int npts;
04655 struct bu_vls vls;
04656
04657 if (dgop->dgo_wdbp->dbip == DBI_NULL)
04658 return;
04659
04660 bu_vls_init(&vls);
04661
04662 FOR_ALL_SOLIDS(sp, &dgop->dgo_headSolid) {
04663 if (lvl <= -2) {
04664
04665 bu_vls_printf(&vls, "%s ", LAST_SOLID(sp)->d_namep);
04666 continue;
04667 }
04668
04669 db_path_to_vls(&vls, &sp->s_fullpath);
04670
04671 if ((lvl != -1) && (sp->s_iflag == UP))
04672 bu_vls_printf(&vls, " ILLUM");
04673
04674 bu_vls_printf(&vls, "\n");
04675
04676 if (lvl <= 0)
04677 continue;
04678
04679
04680 bu_vls_printf(&vls, " cent=(%.3f,%.3f,%.3f) sz=%g ",
04681 sp->s_center[X]*dgop->dgo_wdbp->dbip->dbi_base2local,
04682 sp->s_center[Y]*dgop->dgo_wdbp->dbip->dbi_base2local,
04683 sp->s_center[Z]*dgop->dgo_wdbp->dbip->dbi_base2local,
04684 sp->s_size*dgop->dgo_wdbp->dbip->dbi_base2local);
04685 bu_vls_printf(&vls, "reg=%d\n",sp->s_regionid);
04686 bu_vls_printf(&vls, " basecolor=(%d,%d,%d) color=(%d,%d,%d)%s%s%s\n",
04687 sp->s_basecolor[0],
04688 sp->s_basecolor[1],
04689 sp->s_basecolor[2],
04690 sp->s_color[0],
04691 sp->s_color[1],
04692 sp->s_color[2],
04693 sp->s_uflag?" U":"",
04694 sp->s_dflag?" D":"",
04695 sp->s_cflag?" C":"");
04696
04697 if (lvl <= 1)
04698 continue;
04699
04700
04701 nvlist = 0;
04702 npts = 0;
04703 for (BU_LIST_FOR(vp, bn_vlist, &(sp->s_vlist))) {
04704 register int i;
04705 register int nused = vp->nused;
04706 register int *cmd = vp->cmd;
04707 register point_t *pt = vp->pt;
04708
04709 BN_CK_VLIST(vp);
04710 nvlist++;
04711 npts += nused;
04712
04713 if (lvl <= 2)
04714 continue;
04715
04716 for (i = 0; i < nused; i++,cmd++,pt++) {
04717 bu_vls_printf(&vls, " %s (%g, %g, %g)\n",
04718 rt_vlist_cmd_descriptions[*cmd],
04719 V3ARGS(*pt));
04720 }
04721 }
04722
04723 bu_vls_printf(&vls, " %d vlist structures, %d pts\n", nvlist, npts);
04724 bu_vls_printf(&vls, " %d pts (via rt_ck_vlist)\n", rt_ck_vlist(&(sp->s_vlist)));
04725 }
04726
04727 Tcl_AppendResult(interp, bu_vls_addr(&vls), (char *)NULL);
04728 bu_vls_free(&vls);
04729 }
04730
04731
04732
04733
04734
04735
04736
04737
04738 static void
04739 dgo_print_schain_vlcmds(struct dg_obj *dgop, Tcl_Interp *interp)
04740 {
04741 register struct solid *sp;
04742 register struct bn_vlist *vp;
04743 struct bu_vls vls;
04744
04745 if (dgop->dgo_wdbp->dbip == DBI_NULL)
04746 return;
04747
04748 bu_vls_init(&vls);
04749
04750 FOR_ALL_SOLIDS(sp, &dgop->dgo_headSolid) {
04751 bu_vls_printf(&vls, "-1 %d %d %d\n",
04752 sp->s_color[0],
04753 sp->s_color[1],
04754 sp->s_color[2]);
04755
04756
04757 for (BU_LIST_FOR(vp, bn_vlist, &(sp->s_vlist))) {
04758 register int i;
04759 register int nused = vp->nused;
04760 register int *cmd = vp->cmd;
04761 register point_t *pt = vp->pt;
04762
04763 BN_CK_VLIST(vp);
04764
04765 for (i = 0; i < nused; i++, cmd++, pt++)
04766 bu_vls_printf(&vls, "%d %g %g %g\n", *cmd, V3ARGS(*pt));
04767 }
04768 }
04769
04770 Tcl_AppendResult(interp, bu_vls_addr(&vls), (char *)NULL);
04771 bu_vls_free(&vls);
04772 }
04773
04774
04775
04776
04777
04778
04779
04780
04781
04782 void
04783 dgo_pr_wait_status(Tcl_Interp *interp,
04784 int status)
04785 {
04786 int sig = status & 0x7f;
04787 int core = status & 0x80;
04788 int ret = status >> 8;
04789 struct bu_vls tmp_vls;
04790
04791 if (status == 0) {
04792 Tcl_AppendResult(interp, "Normal exit\n", (char *)NULL);
04793 return;
04794 }
04795
04796 bu_vls_init(&tmp_vls);
04797 bu_vls_printf(&tmp_vls, "Abnormal exit x%x", status);
04798
04799 if (core)
04800 bu_vls_printf(&tmp_vls, ", core dumped");
04801
04802 if (sig)
04803 bu_vls_printf(&tmp_vls, ", terminating signal = %d", sig);
04804 else
04805 bu_vls_printf(&tmp_vls, ", return (exit) code = %d", ret);
04806
04807 Tcl_AppendResult(interp, bu_vls_addr(&tmp_vls), "\n", (char *)NULL);
04808 bu_vls_free(&tmp_vls);
04809 }
04810
04811 static union tree *
04812 dgo_bot_check_region_end(register struct db_tree_state *tsp,
04813 struct db_full_path *pathp,
04814 union tree *curtree,
04815 genptr_t client_data)
04816 {
04817 return curtree;
04818 }
04819
04820 static union tree *
04821 dgo_bot_check_leaf(struct db_tree_state *tsp,
04822 struct db_full_path *pathp,
04823 struct rt_db_internal *ip,
04824 genptr_t client_data)
04825 {
04826 union tree *curtree;
04827 int ac = 1;
04828 char *av[2];
04829 struct dg_client_data *dgcdp = (struct dg_client_data *)client_data;
04830
04831 av[0] = db_path_to_string(pathp);
04832 av[1] = (char *)0;
04833
04834
04835 RT_GET_TREE(curtree, tsp->ts_resp);
04836 curtree->magic = RT_TREE_MAGIC;
04837 curtree->tr_op = OP_NOP;
04838
04839
04840
04841
04842
04843 switch (dgcdp->dmode) {
04844 case DGO_SHADED_MODE_BOTS:
04845 if (ip->idb_major_type == DB5_MAJORTYPE_BRLCAD &&
04846 ip->idb_minor_type == DB5_MINORTYPE_BRLCAD_BOT) {
04847 struct bu_list vhead;
04848
04849 BU_LIST_INIT(&vhead);
04850
04851 (void)rt_bot_plot_poly(&vhead, ip, tsp->ts_ttol, tsp->ts_tol);
04852 dgo_drawH_part2(0, &vhead, pathp, tsp, SOLID_NULL, dgcdp);
04853 } else if (ip->idb_major_type == DB5_MAJORTYPE_BRLCAD &&
04854 ip->idb_minor_type == DB5_MINORTYPE_BRLCAD_POLY) {
04855 struct bu_list vhead;
04856
04857 BU_LIST_INIT(&vhead);
04858
04859 (void)rt_pg_plot_poly(&vhead, ip, tsp->ts_ttol, tsp->ts_tol);
04860 dgo_drawH_part2(0, &vhead, pathp, tsp, SOLID_NULL, dgcdp);
04861 } else {
04862
04863 int save_dgo_shaded_mode = dgcdp->dgop->dgo_shaded_mode;
04864 int save_shaded_mode_override = dgcdp->shaded_mode_override;
04865 int save_dmode = dgcdp->dmode;
04866
04867
04868 dgcdp->dgop->dgo_shaded_mode = 0;
04869 dgcdp->shaded_mode_override = -1;
04870 dgcdp->dmode = DGO_WIREFRAME;
04871
04872 dgo_drawtrees(dgcdp->dgop, dgcdp->interp, ac, av, 1, client_data);
04873
04874
04875 dgcdp->dgop->dgo_shaded_mode = save_dgo_shaded_mode;
04876 dgcdp->shaded_mode_override = save_shaded_mode_override;
04877 dgcdp->dmode = save_dmode;
04878 }
04879
04880 break;
04881 case DGO_SHADED_MODE_ALL:
04882 if (ip->idb_major_type == DB5_MAJORTYPE_BRLCAD &&
04883 ip->idb_minor_type != DB5_MINORTYPE_BRLCAD_PIPE) {
04884 if (ip->idb_minor_type == DB5_MINORTYPE_BRLCAD_BOT) {
04885 struct bu_list vhead;
04886
04887 BU_LIST_INIT(&vhead);
04888
04889 (void)rt_bot_plot_poly(&vhead, ip, tsp->ts_ttol, tsp->ts_tol);
04890 dgo_drawH_part2(0, &vhead, pathp, tsp, SOLID_NULL, dgcdp);
04891 } else if (ip->idb_minor_type == DB5_MINORTYPE_BRLCAD_POLY) {
04892 struct bu_list vhead;
04893
04894 BU_LIST_INIT(&vhead);
04895
04896 (void)rt_pg_plot_poly(&vhead, ip, tsp->ts_ttol, tsp->ts_tol);
04897 dgo_drawH_part2(0, &vhead, pathp, tsp, SOLID_NULL, dgcdp);
04898 } else
04899 dgo_drawtrees(dgcdp->dgop, dgcdp->interp, ac, av, 3, client_data);
04900 } else {
04901
04902 int save_dgo_shaded_mode = dgcdp->dgop->dgo_shaded_mode;
04903 int save_shaded_mode_override = dgcdp->shaded_mode_override;
04904 int save_dmode = dgcdp->dmode;
04905
04906
04907 dgcdp->dgop->dgo_shaded_mode = 0;
04908 dgcdp->shaded_mode_override = -1;
04909 dgcdp->dmode = DGO_WIREFRAME;
04910
04911 dgo_drawtrees(dgcdp->dgop, dgcdp->interp, ac, av, 1, client_data);
04912
04913
04914 dgcdp->dgop->dgo_shaded_mode = save_dgo_shaded_mode;
04915 dgcdp->shaded_mode_override = save_shaded_mode_override;
04916 dgcdp->dmode = save_dmode;
04917 }
04918
04919 break;
04920 }
04921
04922 bu_free((genptr_t)av[0], "dgo_bot_check_leaf: av[0]");
04923
04924 return curtree;
04925 }
04926
04927
04928
04929
04930
04931
04932
04933
04934
04935
04936