int ged_edmater(struct rt_wdb *wdbp, int argc, const char *argv[]) { FILE *fp; int i; int status; const char **av; static const char *usage = "comb(s)"; char tmpfil[MAXPATHLEN]; GED_CHECK_DATABASE_OPEN(wdbp, GED_ERROR); GED_CHECK_READ_ONLY(wdbp, GED_ERROR); /* must be wanting help */ if (argc == 1) { wdbp->wdb_result_flags |= GED_RESULT_FLAGS_HELP_BIT; bu_vls_printf(&wdbp->wdb_result_str, "Usage: %s %s", argv[0], usage); return GED_OK; } fp = bu_temp_file(tmpfil, MAXPATHLEN); if (!fp) return TCL_ERROR; av = (const char **)bu_malloc(sizeof(char *)*(argc + 2), "f_edmater: av"); av[0] = "wmater"; av[1] = tmpfil; for(i = 2; i < argc + 1; ++i) av[i] = argv[i-1]; av[i] = NULL; if (ged_wmater(wdbp, argc + 1, av) == TCL_ERROR) { (void)unlink(tmpfil); bu_free((genptr_t)av, "f_edmater: av"); return TCL_ERROR; } (void)fclose(fp); if (ged_editit(tmpfil)) { av[0] = "rmater"; av[2] = NULL; status = ged_rmater(wdbp, 2, av); } else { status = TCL_ERROR; } (void)unlink(tmpfil); bu_free((genptr_t)av, "ged_edmater: av"); return status; }
int ged_killall(struct ged *gedp, int argc, const char *argv[]) { int nflag; int ret; static const char *usage = "[-n] object(s)"; GED_CHECK_DATABASE_OPEN(gedp, GED_ERROR); GED_CHECK_DRAWABLE(gedp, GED_ERROR); GED_CHECK_READ_ONLY(gedp, GED_ERROR); GED_CHECK_ARGC_GT_0(gedp, argc, GED_ERROR); /* initialize result */ bu_vls_trunc(gedp->ged_result_str, 0); /* must be wanting help */ if (argc == 1) { bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); return GED_HELP; } /* Process the -n option */ if (argc > 1 && argv[1][0] == '-' && argv[1][1] == 'n' && argv[1][2] == '\0') { int i; nflag = 1; /* Objects that would be killed are in the first sublist */ bu_vls_printf(gedp->ged_result_str, "{"); for (i = 2; i < argc; i++) bu_vls_printf(gedp->ged_result_str, "%s ", argv[i]); bu_vls_printf(gedp->ged_result_str, "} {"); } else nflag = 0; gedp->ged_internal_call = 1; if ((ret = ged_killrefs(gedp, argc, argv)) != GED_OK) { gedp->ged_internal_call = 0; bu_vls_printf(gedp->ged_result_str, "KILL skipped because of earlier errors.\n"); return ret; } gedp->ged_internal_call = 0; if (nflag) { /* Close the sublist of objects that reference the would-be killed objects. */ bu_vls_printf(gedp->ged_result_str, "}"); return GED_OK; } /* ALL references removed...now KILL the object[s] */ /* reuse argv[] */ argv[0] = "kill"; return ged_kill(gedp, argc, argv); }
int ged_comb_color(struct rt_wdb *wdbp, int argc, const char *argv[]) { int i; int val; register struct directory *dp; struct rt_db_internal intern; struct rt_comb_internal *comb; static const char *usage = "comb_color combination R G B"; GED_CHECK_DATABASE_OPEN(wdbp, GED_ERROR); GED_CHECK_READ_ONLY(wdbp, GED_ERROR); /* initialize result */ bu_vls_trunc(&wdbp->wdb_result_str, 0); wdbp->wdb_result = GED_RESULT_NULL; wdbp->wdb_result_flags = 0; /* must be wanting help */ if (argc == 1) { wdbp->wdb_result_flags |= GED_RESULT_FLAGS_HELP_BIT; bu_vls_printf(&wdbp->wdb_result_str, "Usage: %s %s", argv[0], usage); return GED_OK; } if (argc != 5) { bu_vls_printf(&wdbp->wdb_result_str, "Usage: %s %s", argv[0], usage); return GED_ERROR; } GED_DB_LOOKUP(wdbp, dp, argv[1], LOOKUP_NOISY, GED_ERROR); GED_CHECK_COMB(wdbp, dp, GED_ERROR); GED_DB_GET_INTERNAL(wdbp, &intern, dp, (fastf_t *)NULL, &rt_uniresource, GED_ERROR); comb = (struct rt_comb_internal *)intern.idb_ptr; RT_CK_COMB(comb); for (i = 0; i < 3; ++i) { if (sscanf(argv[i+2], "%d", &val) != 1 || val < 0 || 255 < val) { bu_vls_printf(&wdbp->wdb_result_str,"RGB value out of range: %s", argv[i + 2]); rt_db_free_internal(&intern, &rt_uniresource); return GED_ERROR; } else comb->rgb[i] = val; } comb->rgb_valid = 1; GED_DB_PUT_INTERNAL(wdbp, dp, &intern, &rt_uniresource, GED_ERROR); return GED_OK; }
int ged_bot_flip(struct ged *gedp, int argc, const char *argv[]) { int i; struct directory *dp; struct rt_db_internal intern; struct rt_bot_internal *bot; static const char *usage = "bot [bot2 bot3 ...]"; GED_CHECK_DATABASE_OPEN(gedp, GED_ERROR); GED_CHECK_READ_ONLY(gedp, GED_ERROR); GED_CHECK_ARGC_GT_0(gedp, argc, GED_ERROR); /* initialize result */ bu_vls_trunc(gedp->ged_result_str, 0); /* must be wanting help */ if (argc == 1) { bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); return GED_HELP; } for (i = 1; i < argc; ++i) { /* Skip past any path elements */ char *obj = (char *)bu_calloc(strlen(argv[i]), sizeof(char), "ged_bot_flip obj"); bu_basename(obj, argv[i]); if (BU_STR_EQUAL(obj, ".")) { /* malformed path, lookup using exactly what was provided */ bu_free(obj, "free bu_basename"); obj = bu_strdup(argv[i]); } if ((dp = db_lookup(gedp->ged_wdbp->dbip, obj, LOOKUP_QUIET)) == RT_DIR_NULL) { bu_vls_printf(gedp->ged_result_str, "%s: db_lookup(%s) error\n", argv[0], obj); } else { GED_DB_GET_INTERNAL(gedp, &intern, dp, bn_mat_identity, &rt_uniresource, GED_ERROR); if (intern.idb_major_type != DB5_MAJORTYPE_BRLCAD || intern.idb_minor_type != DB5_MINORTYPE_BRLCAD_BOT) { bu_vls_printf(gedp->ged_result_str, "%s: %s is not a BOT solid!\n", argv[0], obj); } else { bot = (struct rt_bot_internal *)intern.idb_ptr; rt_bot_flip(bot); GED_DB_PUT_INTERNAL(gedp, dp, &intern, gedp->ged_wdbp->wdb_resp, GED_ERROR); } } bu_free(obj, "free obj"); } return GED_OK; }
int ged_adjust(struct ged *gedp, int argc, const char *argv[]) { int status; struct directory *dp; char *name; struct rt_db_internal intern; static const char *usage = "object attr value ?attr value?"; GED_CHECK_DATABASE_OPEN(gedp, GED_ERROR); GED_CHECK_READ_ONLY(gedp, GED_ERROR); GED_CHECK_ARGC_GT_0(gedp, argc, GED_ERROR); /* initialize result */ bu_vls_trunc(gedp->ged_result_str, 0); /* must be wanting help */ if (argc == 1) { bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); return GED_HELP; } if (argc < 4) { bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); return GED_ERROR; } name = (char *)argv[1]; GED_DB_LOOKUP(gedp, dp, name, LOOKUP_QUIET, GED_ERROR); GED_DB_GET_INTERNAL(gedp, &intern, dp, (matp_t)NULL, &rt_uniresource, GED_ERROR); RT_CK_DB_INTERNAL(&intern); /* Find out what type of object we are dealing with and tweak it. */ RT_CK_FUNCTAB(intern.idb_meth); if (!intern.idb_meth->ft_adjust) { bu_vls_printf(gedp->ged_result_str, "wdb_export(%s) adjust failure", name); return GED_ERROR; } status = intern.idb_meth->ft_adjust(gedp->ged_result_str, &intern, argc-2, argv+2); if (status == GED_OK && wdb_put_internal(gedp->ged_wdbp, name, &intern, 1.0) < 0) { bu_vls_printf(gedp->ged_result_str, "wdb_export(%s) failure", name); rt_db_free_internal(&intern); return GED_ERROR; } return GED_OK; }
int ged_bot_condense(struct ged *gedp, int argc, const char *argv[]) { struct directory *old_dp, *new_dp; struct rt_db_internal intern; struct rt_bot_internal *bot; int count2=0; static const char *usage = "new_bot old_bot"; GED_CHECK_DATABASE_OPEN(gedp, GED_ERROR); GED_CHECK_READ_ONLY(gedp, GED_ERROR); GED_CHECK_ARGC_GT_0(gedp, argc, GED_ERROR); /* initialize result */ bu_vls_trunc(gedp->ged_result_str, 0); /* must be wanting help */ if (argc == 1) { bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); return GED_HELP; } if (argc != 3) { bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); return GED_ERROR; } GED_DB_LOOKUP(gedp, old_dp, argv[2], LOOKUP_NOISY, GED_ERROR & GED_QUIET); GED_DB_GET_INTERNAL(gedp, &intern, old_dp, bn_mat_identity, &rt_uniresource, GED_ERROR); if (intern.idb_major_type != DB5_MAJORTYPE_BRLCAD || intern.idb_minor_type != DB5_MINORTYPE_BRLCAD_BOT) { bu_vls_printf(gedp->ged_result_str, "%s: %s is not a BOT solid!\n", argv[0], argv[2]); return GED_ERROR; } bot = (struct rt_bot_internal *)intern.idb_ptr; RT_BOT_CK_MAGIC(bot); count2 = rt_bot_condense(bot); bu_vls_printf(gedp->ged_result_str, "%s: %d dead vertices eliminated\n", argv[0], count2); GED_DB_DIRADD(gedp, new_dp, argv[1], RT_DIR_PHONY_ADDR, 0, RT_DIR_SOLID, (void *)&intern.idb_type, GED_ERROR); GED_DB_PUT_INTERNAL(gedp, new_dp, &intern, &rt_uniresource, GED_ERROR); return GED_OK; }
int ged_copy(struct ged *gedp, int argc, const char *argv[]) { struct directory *from_dp; struct bu_external external; static const char *usage = "from to"; GED_CHECK_DATABASE_OPEN(gedp, GED_ERROR); GED_CHECK_READ_ONLY(gedp, GED_ERROR); GED_CHECK_ARGC_GT_0(gedp, argc, GED_ERROR); /* initialize result */ bu_vls_trunc(gedp->ged_result_str, 0); /* must be wanting help */ if (argc == 1) { bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); return GED_HELP; } if (argc != 3) { bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); return GED_ERROR; } GED_DB_LOOKUP(gedp, from_dp, argv[1], LOOKUP_NOISY, GED_ERROR & GED_QUIET); GED_CHECK_EXISTS(gedp, argv[2], LOOKUP_QUIET, GED_ERROR); if (db_get_external(&external, from_dp, gedp->ged_wdbp->dbip)) { bu_vls_printf(gedp->ged_result_str, "Database read error, aborting\n"); return GED_ERROR; } if (wdb_export_external(gedp->ged_wdbp, &external, argv[2], from_dp->d_flags, from_dp->d_minor_type) < 0) { bu_free_external(&external); bu_vls_printf(gedp->ged_result_str, "Failed to write new object (%s) to database - aborting!!\n", argv[2]); return GED_ERROR; } bu_free_external(&external); return GED_OK; }
int ged_edcolor(struct ged *gedp, int argc, const char *argv[]) { GED_CHECK_DATABASE_OPEN(gedp, GED_ERROR); GED_CHECK_READ_ONLY(gedp, GED_ERROR); GED_CHECK_ARGC_GT_0(gedp, argc, GED_ERROR); /* initialize result */ bu_vls_trunc(gedp->ged_result_str, 0); if (argc != 3) { bu_vls_printf(gedp->ged_result_str, "Usage: %s", argv[0]); return GED_ERROR; } return edcolor(gedp, argc, argv); }
HIDDEN int constraint_eval(void *datap, int argc, const char *argv[]) { size_t i, obj; struct directory *dp; struct bu_attribute_value_set avs; struct bu_attribute_value_pair *avpp; int ret = BRLCAD_OK; struct ged *gedp = (struct ged *)datap; if (!gedp || argc < 1 || !argv) return BRLCAD_ERROR; GED_CHECK_READ_ONLY(gedp, GED_ERROR); /* multiple arguments assumed to be multiple objects */ for (obj = 0; 2+obj < (size_t)argc; obj++) { /* load the constraint object */ dp = db_lookup(gedp->ged_wdbp->dbip, argv[2+obj], LOOKUP_QUIET); if (dp == RT_DIR_NULL) { bu_vls_printf(gedp->ged_result_str, "Unable to find %s in the database.\n", argv[2+obj]); ret = BRLCAD_ERROR; continue; } bu_avs_init_empty(&avs); if (db5_get_attributes(gedp->ged_wdbp->dbip, &avs, dp)) { bu_vls_printf(gedp->ged_result_str, "Cannot get constraints from %s\n", dp->d_namep); ret = BRLCAD_ERROR; } for (i=0, avpp = avs.avp; i < avs.count; i++, avpp++) { bu_vls_printf(gedp->ged_result_str, "Evaluating %s constraint: %s %s\n", argv[2+obj], avpp->name, avpp->value); bu_vls_printf(gedp->ged_result_str, "<<constraint eval here>>\n"); } bu_avs_free(&avs); } return ret; }
int ged_log(struct ged *gedp, int argc, const char *argv[]) { static char *usage = "get|start|stop"; GED_CHECK_DATABASE_OPEN(gedp, GED_ERROR); GED_CHECK_READ_ONLY(gedp, GED_ERROR); GED_CHECK_ARGC_GT_0(gedp, argc, GED_ERROR); /* initialize result */ bu_vls_trunc(gedp->ged_result_str, 0); /* must be wanting help */ if (argc == 1) { bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); return GED_HELP; } if (argc != 2) { bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); return GED_ERROR; } if (argv[1][0] == 'g' && BU_STR_EQUAL(argv[1], "get")) { bu_vls_vlscatzap(gedp->ged_result_str, gedp->ged_log); return GED_OK; } if (argv[1][0] == 's' && BU_STR_EQUAL(argv[1], "start")) { bu_log_add_hook(log_hook, (void *)gedp->ged_log); return GED_OK; } if (argv[1][0] == 's' && BU_STR_EQUAL(argv[1], "stop")) { bu_log_delete_hook(log_hook, (void *)gedp->ged_log); return GED_OK; } bu_log("Usage: %s %s ", argv[0], usage); return GED_ERROR; }
HIDDEN int constraint_set(void *datap, int argc, const char *argv[]) { struct directory *dp; struct bu_attribute_value_set avs = BU_AVS_INIT_ZERO; struct bu_vls expression = BU_VLS_INIT_ZERO; struct ged *gedp = (struct ged *)datap; if (!gedp || argc < 3 || !argv) return BRLCAD_ERROR; GED_CHECK_READ_ONLY(gedp, GED_ERROR); dp = db_lookup(gedp->ged_wdbp->dbip, argv[2], LOOKUP_QUIET); if (!dp) { /* TODO: need to create the object here */ return BRLCAD_ERROR; } if (db5_get_attributes(gedp->ged_wdbp->dbip, &avs, dp)) { bu_vls_printf(gedp->ged_result_str, "Cannot get constraints for %s\n", dp->d_namep); bu_avs_free(&avs); return BRLCAD_ERROR; } bu_vls_from_argv(&expression, argc-4, &argv[4]); (void)bu_avs_add(&avs, argv[3], bu_vls_addr(&expression)); bu_vls_free(&expression); if (db5_update_attributes(dp, &avs, gedp->ged_wdbp->dbip)) { bu_vls_printf(gedp->ged_result_str, "Failed to set constraints on %s\n", dp->d_namep); bu_avs_free(&avs); return GED_ERROR; } bu_avs_free(&avs); return BRLCAD_OK; }
int ged_otranslate(struct ged *gedp, int argc, const char *argv[]) { struct directory *dp; struct _ged_trace_data gtd; struct rt_db_internal intern; vect_t delta; double scan[3]; mat_t dmat; mat_t emat; mat_t tmpMat; mat_t invXform; point_t rpp_min; point_t rpp_max; static const char *usage = "obj dx dy dz"; GED_CHECK_DATABASE_OPEN(gedp, GED_ERROR); GED_CHECK_READ_ONLY(gedp, GED_ERROR); GED_CHECK_ARGC_GT_0(gedp, argc, GED_ERROR); /* initialize result */ bu_vls_trunc(gedp->ged_result_str, 0); /* must be wanting help */ if (argc == 1) { bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); return GED_HELP; } if (argc != 5) { bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); return GED_ERROR; } if (_ged_get_obj_bounds2(gedp, 1, argv+1, >d, rpp_min, rpp_max) == GED_ERROR) return GED_ERROR; dp = gtd.gtd_obj[gtd.gtd_objpos-1]; if (!(dp->d_flags & RT_DIR_SOLID)) { if (_ged_get_obj_bounds(gedp, 1, argv+1, 1, rpp_min, rpp_max) == GED_ERROR) return GED_ERROR; } if (sscanf(argv[2], "%lf", &scan[X]) != 1) { bu_vls_printf(gedp->ged_result_str, "%s: bad x value - %s", argv[0], argv[2]); return GED_ERROR; } if (sscanf(argv[3], "%lf", &scan[Y]) != 1) { bu_vls_printf(gedp->ged_result_str, "%s: bad y value - %s", argv[0], argv[3]); return GED_ERROR; } if (sscanf(argv[4], "%lf", &scan[Z]) != 1) { bu_vls_printf(gedp->ged_result_str, "%s: bad z value - %s", argv[0], argv[4]); return GED_ERROR; } MAT_IDN(dmat); VSCALE(delta, scan, gedp->ged_wdbp->dbip->dbi_local2base); MAT_DELTAS_VEC(dmat, delta); bn_mat_inv(invXform, gtd.gtd_xform); bn_mat_mul(tmpMat, invXform, dmat); bn_mat_mul(emat, tmpMat, gtd.gtd_xform); GED_DB_GET_INTERNAL(gedp, &intern, dp, emat, &rt_uniresource, GED_ERROR); RT_CK_DB_INTERNAL(&intern); GED_DB_PUT_INTERNAL(gedp, dp, &intern, &rt_uniresource, GED_ERROR); return GED_OK; }
int ged_ptranslate(struct ged *gedp, int argc, const char *argv[]) { const char *cmd_name = argv[0]; int ret; int rflag; struct rt_db_internal intern; vect_t tvec; double scan[3]; char *last; struct directory *dp; static const char *usage = "[-r] obj attribute tvec"; GED_CHECK_DATABASE_OPEN(gedp, GED_ERROR); GED_CHECK_READ_ONLY(gedp, GED_ERROR); GED_CHECK_ARGC_GT_0(gedp, argc, GED_ERROR); /* initialize result */ bu_vls_trunc(gedp->ged_result_str, 0); /* must be wanting help */ if (argc == 1) { bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", cmd_name, usage); return GED_HELP; } if (argc < 4 || argc > 5) { bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", cmd_name, usage); return GED_ERROR; } if (argc == 5) { if (argv[1][0] == '-' && argv[1][1] == 'r' && argv[1][2] == '\0') { rflag = 1; --argc; ++argv; } else { bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", cmd_name, usage); return GED_ERROR; } } else rflag = 0; if (sscanf(argv[3], "%lf %lf %lf", &scan[0], &scan[1], &scan[2]) != 3) { bu_vls_printf(gedp->ged_result_str, "%s: bad translation vector - %s", cmd_name, argv[3]); return GED_ERROR; } /* convert from double to fastf_t */ VMOVE(tvec, scan); if ((last = strrchr(argv[1], '/')) == NULL) last = (char *)argv[1]; else ++last; if (last[0] == '\0') { bu_vls_printf(gedp->ged_result_str, "%s: illegal input - %s", cmd_name, argv[1]); return GED_ERROR; } if ((dp = db_lookup(gedp->ged_wdbp->dbip, last, LOOKUP_QUIET)) == RT_DIR_NULL) { bu_vls_printf(gedp->ged_result_str, "%s: %s not found", cmd_name, argv[1]); return GED_ERROR; } GED_DB_GET_INTERNAL(gedp, &intern, dp, (matp_t)NULL, &rt_uniresource, GED_ERROR); RT_CK_DB_INTERNAL(&intern); if (intern.idb_major_type != DB5_MAJORTYPE_BRLCAD) { bu_vls_printf(gedp->ged_result_str, "%s: Object not eligible for translating.", cmd_name); rt_db_free_internal(&intern); return GED_ERROR; } switch (intern.idb_minor_type) { case DB5_MINORTYPE_BRLCAD_TGC: ret = _ged_translate_tgc(gedp, (struct rt_tgc_internal *)intern.idb_ptr, argv[2], tvec, rflag); break; case DB5_MINORTYPE_BRLCAD_EXTRUDE: ret = _ged_translate_extrude(gedp, (struct rt_extrude_internal *)intern.idb_ptr, argv[2], tvec, rflag); break; default: bu_vls_printf(gedp->ged_result_str, "%s: Object not yet supported.", cmd_name); rt_db_free_internal(&intern); return GED_ERROR; } if (ret == GED_OK) { GED_DB_PUT_INTERNAL(gedp, dp, &intern, &rt_uniresource, GED_ERROR); } else if (ret == GED_ERROR) { rt_db_free_internal(&intern); } return ret; }
int ged_copyeval(struct ged *gedp, int argc, const char *argv[]) { static const char *usage = "path_to_old_prim new_prim"; struct _ged_trace_data gtd; struct directory *dp; struct rt_db_internal *ip; struct rt_db_internal internal, new_int; char *tok; int endpos = 0; int i; mat_t start_mat; GED_CHECK_DATABASE_OPEN(gedp, GED_ERROR); GED_CHECK_READ_ONLY(gedp, GED_ERROR); GED_CHECK_ARGC_GT_0(gedp, argc, GED_ERROR); /* initialize result */ bu_vls_trunc(gedp->ged_result_str, 0); /* must be wanting help */ if (argc == 1) { bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); return GED_HELP; } if (argc != 3) { bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); return GED_ERROR; } /* initialize gtd */ gtd.gtd_gedp = gedp; gtd.gtd_flag = _GED_CPEVAL; gtd.gtd_prflag = 0; /* check if new solid name already exists in description */ GED_CHECK_EXISTS(gedp, argv[2], LOOKUP_QUIET, GED_ERROR); MAT_IDN(start_mat); /* build directory pointer array for desired path */ if (strchr(argv[1], '/')) { tok = strtok((char *)argv[1], "/"); while (tok) { GED_DB_LOOKUP(gedp, gtd.gtd_obj[endpos], tok, LOOKUP_NOISY, GED_ERROR & GED_QUIET); endpos++; tok = strtok((char *)NULL, "/"); } } else { GED_DB_LOOKUP(gedp, gtd.gtd_obj[endpos], argv[1], LOOKUP_NOISY, GED_ERROR & GED_QUIET); endpos++; } if (endpos < 1) { bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); return GED_ERROR; } gtd.gtd_objpos = endpos - 1; GED_DB_GET_INTERNAL(gedp, &internal, gtd.gtd_obj[endpos - 1], bn_mat_identity, &rt_uniresource, GED_ERROR); if (endpos > 1) { /* Make sure that final component in path is a solid */ if (internal.idb_type == ID_COMBINATION) { rt_db_free_internal(&internal); bu_vls_printf(gedp->ged_result_str, "final component on path must be a primitive!\n"); return GED_ERROR; } /* Accumulate the matrices */ ged_trace(gtd.gtd_obj[0], 0, start_mat, >d, 1); if (gtd.gtd_prflag == 0) { bu_vls_printf(gedp->ged_result_str, "PATH: "); for (i = 0; i < gtd.gtd_objpos; i++) bu_vls_printf(gedp->ged_result_str, "/%s", gtd.gtd_obj[i]->d_namep); bu_vls_printf(gedp->ged_result_str, " NOT FOUND\n"); rt_db_free_internal(&internal); return GED_ERROR; } /* Have found the desired path - wdb_xform is the transformation matrix */ /* wdb_xform matrix calculated in wdb_trace() */ /* create the new solid */ RT_DB_INTERNAL_INIT(&new_int); if (rt_generic_xform(&new_int, gtd.gtd_xform, &internal, 0, gedp->ged_wdbp->dbip, &rt_uniresource)) { rt_db_free_internal(&internal); bu_vls_printf(gedp->ged_result_str, "ged_copyeval: rt_generic_xform failed\n"); return GED_ERROR; } ip = &new_int; } else ip = &internal; /* should call GED_DB_DIRADD() but need to deal with freeing the * internals on failure. */ dp=db_diradd(gedp->ged_wdbp->dbip, argv[2], RT_DIR_PHONY_ADDR, 0, gtd.gtd_obj[endpos-1]->d_flags, (void *)&ip->idb_type); if (dp == RT_DIR_NULL) { rt_db_free_internal(&internal); if (ip == &new_int) rt_db_free_internal(&new_int); bu_vls_printf(gedp->ged_result_str, "An error has occurred while adding a new object to the database."); return GED_ERROR; } /* should call GED_DB_DIRADD() but need to deal with freeing the * internals on failure. */ if (rt_db_put_internal(dp, gedp->ged_wdbp->dbip, ip, &rt_uniresource) < 0) { /* if (ip == &new_int) then new_int gets freed by the rt_db_put_internal above * regardless of whether it succeeds or not. At this point only internal needs * to be freed. On the other hand if (ip == &internal), the internal gets freed * freed by the rt_db_put_internal above. In this case memory for new_int has * not been allocated. */ if (ip == &new_int) rt_db_free_internal(&internal); bu_vls_printf(gedp->ged_result_str, "Database write error, aborting"); return GED_ERROR; } /* see previous comment */ if (ip == &new_int) rt_db_free_internal(&internal); return GED_OK; }
int ged_orotate(struct ged *gedp, int argc, const char *argv[]) { struct directory *dp; struct _ged_trace_data gtd; struct rt_db_internal intern; /* intentionally double for scan */ double xrot, yrot, zrot; mat_t rmat; mat_t pmat; mat_t emat; mat_t tmpMat; mat_t invXform; point_t rpp_min; point_t rpp_max; point_t keypoint; static const char *usage = "obj rX rY rZ [kX kY kZ]"; GED_CHECK_DATABASE_OPEN(gedp, GED_ERROR); GED_CHECK_READ_ONLY(gedp, GED_ERROR); GED_CHECK_ARGC_GT_0(gedp, argc, GED_ERROR); /* initialize result */ bu_vls_trunc(gedp->ged_result_str, 0); /* must be wanting help */ if (argc == 1) { bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); return GED_HELP; } if (argc != 5 && argc != 8) { bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); return GED_ERROR; } if (sscanf(argv[2], "%lf", &xrot) != 1) { bu_vls_printf(gedp->ged_result_str, "%s: bad rX value - %s", argv[0], argv[2]); return GED_ERROR; } if (sscanf(argv[3], "%lf", &yrot) != 1) { bu_vls_printf(gedp->ged_result_str, "%s: bad rY value - %s", argv[0], argv[3]); return GED_ERROR; } if (sscanf(argv[4], "%lf", &zrot) != 1) { bu_vls_printf(gedp->ged_result_str, "%s: bad rZ value - %s", argv[0], argv[4]); return GED_ERROR; } if (argc == 5) { /* Use the object's center as the keypoint. */ if (_ged_get_obj_bounds2(gedp, 1, argv+1, >d, rpp_min, rpp_max) == GED_ERROR) return GED_ERROR; dp = gtd.gtd_obj[gtd.gtd_objpos-1]; if (!(dp->d_flags & RT_DIR_SOLID)) { if (_ged_get_obj_bounds(gedp, 1, argv+1, 1, rpp_min, rpp_max) == GED_ERROR) return GED_ERROR; } VADD2(keypoint, rpp_min, rpp_max); VSCALE(keypoint, keypoint, 0.5); } else { double scan[3]; /* The user has provided the keypoint. */ MAT_IDN(gtd.gtd_xform); if (sscanf(argv[5], "%lf", &scan[X]) != 1) { bu_vls_printf(gedp->ged_result_str, "%s: bad kX value - %s", argv[0], argv[5]); return GED_ERROR; } if (sscanf(argv[6], "%lf", &scan[Y]) != 1) { bu_vls_printf(gedp->ged_result_str, "%s: bad kY value - %s", argv[0], argv[6]); return GED_ERROR; } if (sscanf(argv[7], "%lf", &scan[Z]) != 1) { bu_vls_printf(gedp->ged_result_str, "%s: bad kZ value - %s", argv[0], argv[7]); return GED_ERROR; } VSCALE(keypoint, scan, gedp->ged_wdbp->dbip->dbi_local2base); if ((dp = db_lookup(gedp->ged_wdbp->dbip, argv[1], LOOKUP_QUIET)) == RT_DIR_NULL) { bu_vls_printf(gedp->ged_result_str, "%s: %s not found", argv[0], argv[1]); return GED_ERROR; } } bn_mat_angles(rmat, xrot, yrot, zrot); bn_mat_xform_about_pt(pmat, rmat, keypoint); bn_mat_inv(invXform, gtd.gtd_xform); bn_mat_mul(tmpMat, invXform, pmat); bn_mat_mul(emat, tmpMat, gtd.gtd_xform); GED_DB_GET_INTERNAL(gedp, &intern, dp, emat, &rt_uniresource, GED_ERROR); RT_CK_DB_INTERNAL(&intern); GED_DB_PUT_INTERNAL(gedp, dp, &intern, &rt_uniresource, GED_ERROR); return GED_OK; }
int ged_bo(struct ged *gedp, int argc, const char *argv[]) { int c; unsigned int minor_type=0; char *obj_name; char *file_name; int input_mode=0; int output_mode=0; struct rt_binunif_internal *bip; struct rt_db_internal intern; struct directory *dp; const char *argv0; static const char *usage = "{-i major_type minor_type | -o} dest source"; GED_CHECK_DATABASE_OPEN(gedp, GED_ERROR); GED_CHECK_READ_ONLY(gedp, GED_ERROR); GED_CHECK_ARGC_GT_0(gedp, argc, GED_ERROR); /* initialize result */ bu_vls_trunc(gedp->ged_result_str, 0); argv0 = argv[0]; /* must be wanting help */ if (argc == 1) { bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv0, usage); return GED_HELP; } /* check that we are using a version 5 database */ if (db_version(gedp->ged_wdbp->dbip) < 5) { bu_vls_printf(gedp->ged_result_str, "This is an older database version.\nIt does not support binary objects.Use \"dbupgrade\" to upgrade this database to the current version.\n"); return GED_ERROR; } bu_optind = 1; /* re-init bu_getopt() */ bu_opterr = 0; /* suppress bu_getopt()'s error message */ while ((c=bu_getopt(argc, (char * const *)argv, "iou:")) != -1) { switch (c) { case 'i': input_mode = 1; break; case 'o': output_mode = 1; break; default: bu_vls_printf(gedp->ged_result_str, "Unrecognized option - %c", c); return GED_ERROR; } } if (input_mode + output_mode != 1) { bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv0, usage); return GED_ERROR; } argc -= bu_optind; argv += bu_optind; if ((input_mode && argc != 4) || (output_mode && argc != 2)) { bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv0, usage); return GED_ERROR; } if (input_mode) { if (argv[0][0] == 'u') { if (argv[1][1] != '\0') { bu_vls_printf(gedp->ged_result_str, "Unrecognized minor type: %s", argv[1]); return GED_ERROR; } switch ((int)argv[1][0]) { case 'f': minor_type = DB5_MINORTYPE_BINU_FLOAT; break; case 'd': minor_type = DB5_MINORTYPE_BINU_DOUBLE; break; case 'c': minor_type = DB5_MINORTYPE_BINU_8BITINT; break; case 's': minor_type = DB5_MINORTYPE_BINU_16BITINT; break; case 'i': minor_type = DB5_MINORTYPE_BINU_32BITINT; break; case 'l': minor_type = DB5_MINORTYPE_BINU_64BITINT; break; case 'C': minor_type = DB5_MINORTYPE_BINU_8BITINT_U; break; case 'S': minor_type = DB5_MINORTYPE_BINU_16BITINT_U; break; case 'I': minor_type = DB5_MINORTYPE_BINU_32BITINT_U; break; case 'L': minor_type = DB5_MINORTYPE_BINU_64BITINT_U; break; default: bu_vls_printf(gedp->ged_result_str, "Unrecognized minor type: %s", argv[1]); return GED_ERROR; } } else { bu_vls_printf(gedp->ged_result_str, "Unrecognized major type: %s", argv[0]); return GED_ERROR; } /* skip past major_type and minor_type */ argc -= 2; argv += 2; if (minor_type == 0) { bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv0, usage); return GED_ERROR; } obj_name = (char *)*argv; GED_CHECK_EXISTS(gedp, obj_name, LOOKUP_QUIET, GED_ERROR); argc--; argv++; file_name = (char *)*argv; /* make a binunif of the entire file */ if (rt_mk_binunif (gedp->ged_wdbp, obj_name, file_name, minor_type, 0)) { bu_vls_printf(gedp->ged_result_str, "Error creating %s", obj_name); return GED_ERROR; } } else if (output_mode) { FILE *fp; file_name = (char *)*argv; argc--; argv++; obj_name = (char *)*argv; if ((dp=db_lookup(gedp->ged_wdbp->dbip, obj_name, LOOKUP_NOISY)) == RT_DIR_NULL) { return GED_ERROR; } if (!(dp->d_major_type & DB5_MAJORTYPE_BINARY_MASK)) { bu_vls_printf(gedp->ged_result_str, "%s is not a binary object", obj_name); return GED_ERROR; } if (dp->d_major_type != DB5_MAJORTYPE_BINARY_UNIF) { bu_vls_printf(gedp->ged_result_str, "source must be a uniform binary object"); return GED_ERROR; } fp = fopen(file_name, "w+b"); if (fp == NULL) { bu_vls_printf(gedp->ged_result_str, "Error: cannot open file %s for writing", file_name); return GED_ERROR; } if (rt_db_get_internal(&intern, dp, gedp->ged_wdbp->dbip, NULL, &rt_uniresource) < 0) { bu_vls_printf(gedp->ged_result_str, "Error reading %s from database", dp->d_namep); fclose(fp); return GED_ERROR; } RT_CK_DB_INTERNAL(&intern); bip = (struct rt_binunif_internal *)intern.idb_ptr; if (bip->count < 1) { bu_vls_printf(gedp->ged_result_str, "%s has no contents", obj_name); fclose(fp); rt_db_free_internal(&intern); return GED_ERROR; } if (fwrite(bip->u.int8, bip->count * db5_type_sizeof_h_binu(bip->type), 1, fp) != 1) { bu_vls_printf(gedp->ged_result_str, "Error writing contents to file"); fclose(fp); rt_db_free_internal(&intern); return GED_ERROR; } fclose(fp); rt_db_free_internal(&intern); } else { bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv0, usage); return GED_ERROR; } return GED_OK; }
int ged_move_all(struct ged *gedp, int argc, const char *argv[]) { int c; int fflag = 0; int nflag = 0; static const char *usage = "[-n] {-f <mapping_file>|<from> <to>}"; GED_CHECK_DATABASE_OPEN(gedp, GED_ERROR); GED_CHECK_READ_ONLY(gedp, GED_ERROR); GED_CHECK_ARGC_GT_0(gedp, argc, GED_ERROR); /* initialize result */ bu_vls_trunc(gedp->ged_result_str, 0); /* must be wanting help */ if (argc == 1) { bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); return GED_HELP; } if (argc < 3 || 4 < argc) { bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); return GED_ERROR; } if (db_version(gedp->ged_wdbp->dbip) < 5 && (int)strlen(argv[2]) > NAMESIZE) { bu_vls_printf(gedp->ged_result_str, "ERROR: name length limited to %zu characters in v4 databases\n", strlen(argv[2])); return GED_ERROR; } bu_optind = 1; while ((c = bu_getopt(argc, (char * const *)argv, "fn")) != -1) { switch (c) { case 'f': fflag = 1; break; case 'n': nflag = 1; break; default: bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); return GED_ERROR; } } argc -= bu_optind; argv += bu_optind; if (fflag) { if (argc != 1) { bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); return GED_ERROR; } return move_all_file(gedp, nflag, argv[0]); } if (argc != 2) { bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); return GED_ERROR; } return move_all_func(gedp, nflag, argv[0], argv[1]); }
int ged_unhide(struct ged *gedp, int argc, const char *argv[]) { struct directory *dp; struct db_i *dbip; struct bu_external ext; struct bu_external tmp; struct db5_raw_internal raw; int i; static const char *usage = "object(s)"; GED_CHECK_DATABASE_OPEN(gedp, GED_ERROR); GED_CHECK_READ_ONLY(gedp, GED_ERROR); GED_CHECK_ARGC_GT_0(gedp, argc, GED_ERROR); /* initialize result */ bu_vls_trunc(gedp->ged_result_str, 0); /* must be wanting help */ if (argc == 1) { bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); return GED_HELP; } dbip = gedp->ged_wdbp->dbip; if (db_version(dbip) < 5) { bu_vls_printf(gedp->ged_result_str, "Database was created with a previous release of BRL-CAD.\nSelect \"Tools->Upgrade Database...\" to enable support for this feature."); return GED_ERROR; } for (i = 1; i < argc; i++) { if ((dp = db_lookup(dbip, argv[i], LOOKUP_NOISY)) == RT_DIR_NULL) { continue; } RT_CK_DIR(dp); BU_EXTERNAL_INIT(&ext); if (db_get_external(&ext, dp, dbip) < 0) { bu_vls_printf(gedp->ged_result_str, "db_get_external failed for %s\n", dp->d_namep); continue; } if (db5_get_raw_internal_ptr(&raw, ext.ext_buf) == NULL) { bu_vls_printf(gedp->ged_result_str, "db5_get_raw_internal_ptr() failed for %s\n", dp->d_namep); bu_free_external(&ext); continue; } raw.h_name_hidden = (unsigned char)(0x0); BU_EXTERNAL_INIT(&tmp); db5_export_object3(&tmp, DB5HDR_HFLAGS_DLI_APPLICATION_DATA_OBJECT, dp->d_namep, raw.h_name_hidden, &raw.attributes, &raw.body, raw.major_type, raw.minor_type, raw.a_zzz, raw.b_zzz); bu_free_external(&ext); if (db_put_external(&tmp, dp, dbip)) { bu_vls_printf(gedp->ged_result_str, "db_put_external() failed for %s\n", dp->d_namep); bu_free_external(&tmp); continue; } bu_free_external(&tmp); dp->d_flags &= (~RT_DIR_HIDDEN); } return GED_OK; }
int ged_protate(struct ged *gedp, int argc, const char *argv[]) { int ret; mat_t rmat; char *last; struct rt_db_internal intern; struct directory *dp; /* intentionally double for scan */ double rx, ry, rz; static const char *usage = "obj attribute rvec"; GED_CHECK_DATABASE_OPEN(gedp, GED_ERROR); GED_CHECK_READ_ONLY(gedp, GED_ERROR); GED_CHECK_ARGC_GT_0(gedp, argc, GED_ERROR); /* initialize result */ bu_vls_trunc(gedp->ged_result_str, 0); /* must be wanting help */ if (argc == 1) { bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); return GED_HELP; } if (argc != 4) { bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); return GED_ERROR; } if (sscanf(argv[3], "%lf %lf %lf", &rx, &ry, &rz) != 3) { bu_vls_printf(gedp->ged_result_str, "%s: bad rotation vector - %s", argv[0], argv[3]); return GED_ERROR; } if ((last = strrchr(argv[1], '/')) == NULL) last = (char *)argv[1]; else ++last; if (last[0] == '\0') { bu_vls_printf(gedp->ged_result_str, "%s: illegal input - %s", argv[0], argv[1]); return GED_ERROR; } if ((dp = db_lookup(gedp->ged_wdbp->dbip, last, LOOKUP_QUIET)) == RT_DIR_NULL) { bu_vls_printf(gedp->ged_result_str, "%s: %s not found", argv[0], argv[1]); return GED_ERROR; } GED_DB_GET_INTERNAL(gedp, &intern, dp, (matp_t)NULL, &rt_uniresource, GED_ERROR); RT_CK_DB_INTERNAL(&intern); if (intern.idb_major_type != DB5_MAJORTYPE_BRLCAD) { bu_vls_printf(gedp->ged_result_str, "%s: Object not eligible for rotating.", argv[0]); rt_db_free_internal(&intern); return GED_ERROR; } bn_mat_angles(rmat, rx, ry, rz); switch (intern.idb_minor_type) { case DB5_MINORTYPE_BRLCAD_ETO: ret = _ged_rotate_eto(gedp, (struct rt_eto_internal *)intern.idb_ptr, argv[2], rmat); break; case DB5_MINORTYPE_BRLCAD_EXTRUDE: ret = _ged_rotate_extrude(gedp, (struct rt_extrude_internal *)intern.idb_ptr, argv[2], rmat); break; case DB5_MINORTYPE_BRLCAD_HYP: ret = _ged_rotate_hyp(gedp, (struct rt_hyp_internal *)intern.idb_ptr, argv[2], rmat); break; case DB5_MINORTYPE_BRLCAD_TGC: ret = _ged_rotate_tgc(gedp, (struct rt_tgc_internal *)intern.idb_ptr, argv[2], rmat); break; default: bu_vls_printf(gedp->ged_result_str, "%s: Object not yet supported.", argv[0]); rt_db_free_internal(&intern); return GED_ERROR; } if (ret == GED_OK) { GED_DB_PUT_INTERNAL(gedp, dp, &intern, &rt_uniresource, GED_ERROR); } else if (ret == GED_ERROR) { rt_db_free_internal(&intern); } return ret; }
int ged_dbcopy(struct ged *from_gedp, struct ged *to_gedp, const char *from, const char *to, int fflag) { struct directory *from_dp; struct bu_external external; GED_CHECK_DATABASE_OPEN(from_gedp, GED_ERROR); GED_CHECK_DATABASE_OPEN(to_gedp, GED_ERROR); GED_CHECK_READ_ONLY(to_gedp, GED_ERROR); /* initialize result */ bu_vls_trunc(from_gedp->ged_result_str, 0); bu_vls_trunc(to_gedp->ged_result_str, 0); GED_DB_LOOKUP(from_gedp, from_dp, from, LOOKUP_NOISY, GED_ERROR & GED_QUIET); if (!fflag && db_lookup(to_gedp->ged_wdbp->dbip, to, LOOKUP_QUIET) != RT_DIR_NULL) { bu_vls_printf(from_gedp->ged_result_str, "%s already exists.", to); return GED_ERROR; } if (db_get_external(&external, from_dp, from_gedp->ged_wdbp->dbip)) { bu_vls_printf(from_gedp->ged_result_str, "Database read error, aborting\n"); return GED_ERROR; } if (wdb_export_external(to_gedp->ged_wdbp, &external, to, from_dp->d_flags, from_dp->d_minor_type) < 0) { bu_free_external(&external); bu_vls_printf(from_gedp->ged_result_str, "Failed to write new object (%s) to database - aborting!!\n", to); return GED_ERROR; } bu_free_external(&external); /* Need to do something extra for _GLOBAL */ if (db_version(to_gedp->ged_wdbp->dbip) > 4 && BU_STR_EQUAL(to, DB5_GLOBAL_OBJECT_NAME)) { struct directory *to_dp; struct bu_attribute_value_set avs; const char *val; GED_DB_LOOKUP(to_gedp, to_dp, to, LOOKUP_NOISY, GED_ERROR & GED_QUIET); bu_avs_init_empty(&avs); if (db5_get_attributes(to_gedp->ged_wdbp->dbip, &avs, to_dp)) { bu_vls_printf(from_gedp->ged_result_str, "Cannot get attributes for object %s\n", to_dp->d_namep); return GED_ERROR; } if ((val = bu_avs_get(&avs, "title")) != NULL) to_gedp->ged_wdbp->dbip->dbi_title = strdup(val); if ((val = bu_avs_get(&avs, "units")) != NULL) { double loc2mm; if ((loc2mm = bu_mm_value(val)) > 0) { to_gedp->ged_wdbp->dbip->dbi_local2base = loc2mm; to_gedp->ged_wdbp->dbip->dbi_base2local = 1.0 / loc2mm; } } if ((val = bu_avs_get(&avs, "regionid_colortable")) != NULL) { rt_color_free(); db5_import_color_table((char *)val); } bu_avs_free(&avs); } return GED_OK; }
int ged_color(struct ged *gedp, int argc, const char *argv[]) { struct mater *newp; struct mater *mp; struct mater *next_mater; static const char *usage = "[-e] [low high r g b]"; GED_CHECK_DATABASE_OPEN(gedp, GED_ERROR); GED_CHECK_READ_ONLY(gedp, GED_ERROR); GED_CHECK_ARGC_GT_0(gedp, argc, GED_ERROR); /* initialize result */ bu_vls_trunc(gedp->ged_result_str, 0); /* must be wanting help */ if (argc == 1) { bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); return GED_HELP; } if (argc != 6 && argc != 2) { bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); return GED_ERROR; } /* edcolor */ if (argc == 2) { if (argv[1][0] == '-' && argv[1][1] == 'e' && argv[1][2] == '\0') { return edcolor(gedp, argc, argv); } else { bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); return GED_ERROR; } } if (db_version(gedp->ged_wdbp->dbip) < 5) { /* Delete all color records from the database */ mp = rt_material_head(); while (mp != MATER_NULL) { next_mater = mp->mt_forw; color_zaprec(gedp, mp); mp = next_mater; } /* construct the new color record */ BU_ALLOC(newp, struct mater); newp->mt_low = atoi(argv[1]); newp->mt_high = atoi(argv[2]); newp->mt_r = atoi(argv[3]); newp->mt_g = atoi(argv[4]); newp->mt_b = atoi(argv[5]); newp->mt_daddr = MATER_NO_ADDR; /* not in database yet */ /* Insert new color record in the in-memory list */ rt_insert_color(newp); /* Write new color records for all colors in the list */ mp = rt_material_head(); while (mp != MATER_NULL) { next_mater = mp->mt_forw; color_putrec(gedp, mp); mp = next_mater; } } else { struct bu_vls colors = BU_VLS_INIT_ZERO; /* construct the new color record */ BU_ALLOC(newp, struct mater); newp->mt_low = atoi(argv[1]); newp->mt_high = atoi(argv[2]); newp->mt_r = atoi(argv[3]); newp->mt_g = atoi(argv[4]); newp->mt_b = atoi(argv[5]); newp->mt_daddr = MATER_NO_ADDR; /* not in database yet */ /* Insert new color record in the in-memory list */ rt_insert_color(newp); /* * Gather color records from the in-memory list to build * the _GLOBAL objects regionid_colortable attribute. */ rt_vls_color_map(&colors); db5_update_attribute("_GLOBAL", "regionid_colortable", bu_vls_addr(&colors), gedp->ged_wdbp->dbip); bu_vls_free(&colors); } return GED_OK; }
int ged_bot(struct ged *gedp, int argc, const char *argv[]) { struct directory *bot_dp; struct rt_db_internal intern; struct rt_bot_internal *bot; const char *cmd = argv[0]; const char *sub = NULL; const char *arg = NULL; const char *primitive = NULL; size_t len; fastf_t tmp; fastf_t propVal; static const char *usage = "get (faces|minEdge|maxEdge|orientation|type|vertices) bot\nchull bot_in bot_out\n"; GED_CHECK_DATABASE_OPEN(gedp, GED_ERROR); GED_CHECK_READ_ONLY(gedp, GED_ERROR); GED_CHECK_ARGC_GT_0(gedp, argc, GED_ERROR); /* initialize result */ bu_vls_trunc(gedp->ged_result_str, 0); /* must be wanting help */ if (argc < 3) { bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", cmd, usage); return GED_ERROR; } /* determine subcommand */ sub = argv[1]; len = strlen(sub); if (bu_strncmp(sub, "get", len) == 0) { primitive = argv[argc - 1]; } if (bu_strncmp(sub, "chull", len) == 0) { primitive = argv[2]; } if (primitive == NULL) { bu_vls_printf(gedp->ged_result_str, "%s: %s is not a known subcommand!", cmd, sub); return GED_ERROR; } /* get bot */ GED_DB_LOOKUP(gedp, bot_dp, primitive, LOOKUP_NOISY, GED_ERROR & GED_QUIET); GED_DB_GET_INTERNAL(gedp, &intern, bot_dp, bn_mat_identity, &rt_uniresource, GED_ERROR); if (intern.idb_major_type != DB5_MAJORTYPE_BRLCAD || intern.idb_minor_type != DB5_MINORTYPE_BRLCAD_BOT) { bu_vls_printf(gedp->ged_result_str, "%s: %s is not a BOT solid!", cmd, primitive); return GED_ERROR; } bot = (struct rt_bot_internal *)intern.idb_ptr; RT_BOT_CK_MAGIC(bot); if (bu_strncmp(sub, "get", len) == 0) { arg = argv[2]; propVal = rt_bot_propget(bot, arg); /* print result string */ if (!EQUAL(propVal, -1.0)) { tmp = (int) propVal; /* int result */ if (EQUAL(propVal, tmp)) { bu_vls_printf(gedp->ged_result_str, "%d", (int) propVal); } /* float result */ else { bu_vls_printf(gedp->ged_result_str, "%f", propVal); } } else { bu_vls_printf(gedp->ged_result_str, "%s: %s is not a valid argument!", sub, arg); return GED_ERROR; } } if (bu_strncmp(sub, "chull", len) == 0) { int retval = 0; int fc = 0; int vc = 0; point_t *vert_array; int *faces; unsigned char err = 0; /* must be wanting help */ if (argc < 4) { bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", cmd, usage); return GED_ERROR; } retval = bg_3d_chull(&faces, &fc, &vert_array, &vc, (const point_t *)bot->vertices, (int)bot->num_vertices); if (retval != 3) return GED_ERROR; retval = mk_bot(gedp->ged_wdbp, argv[3], RT_BOT_SOLID, RT_BOT_CCW, err, vc, fc, (fastf_t *)vert_array, faces, NULL, NULL); if (retval) return GED_ERROR; } return GED_OK; }
int ged_killtree(struct ged *gedp, int argc, const char *argv[]) { struct directory *dp; int i; int c; struct killtree_data gktd; static const char *usage = "[-a|-f|-n] object(s)"; GED_CHECK_DATABASE_OPEN(gedp, GED_ERROR); GED_CHECK_READ_ONLY(gedp, GED_ERROR); GED_CHECK_ARGC_GT_0(gedp, argc, GED_ERROR); /* initialize result */ bu_vls_trunc(gedp->ged_result_str, 0); /* must be wanting help */ if (argc == 1) { bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); return GED_HELP; } gktd.gedp = gedp; gktd.killrefs = 0; gktd.print = 0; gktd.force = 0; gktd.ac = 1; gktd.top = NULL; gktd.av = (char **)bu_calloc(1, sizeof(char *) * AV_STEP, "alloc av"); gktd.av_capacity = AV_STEP; BU_ASSERT(gktd.ac + argc + 2 < AV_STEP); /* potential -n opts */ gktd.av[0] = "killrefs"; gktd.av[1] = (char *)0; bu_optind = 1; while ((c = bu_getopt(argc, (char * const *)argv, "afn")) != -1) { switch (c) { case 'a': gktd.killrefs = 1; break; case 'n': gktd.print = 1; gktd.av[gktd.ac++] = bu_strdup("-n"); gktd.av[gktd.ac] = (char *)0; break; case 'f': gktd.force = 1; break; default: bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); bu_free(gktd.av, "free av (error)"); gktd.av = NULL; return GED_ERROR; } } argc -= (bu_optind - 1); argv += (bu_optind - 1); /* Objects that would be killed are in the first sublist */ if (gktd.print) bu_vls_printf(gedp->ged_result_str, "{"); for (i = 1; i < argc; i++) { if ((dp = db_lookup(gedp->ged_wdbp->dbip, argv[i], LOOKUP_NOISY)) == RT_DIR_NULL) continue; /* ignore phony objects */ if (dp->d_addr == RT_DIR_PHONY_ADDR) continue; /* stash the what's killed so we can find refs elsewhere */ gktd.top = argv[i]; db_functree(gedp->ged_wdbp->dbip, dp, killtree_callback, killtree_callback, gedp->ged_wdbp->wdb_resp, (void *)&gktd); } /* Close the sublist of would-be killed objects. Also open the * sublist of objects that reference the would-be killed objects. */ if (gktd.print) bu_vls_printf(gedp->ged_result_str, "} {"); if (gktd.killrefs && gktd.ac > 1) { gedp->ged_internal_call = 1; (void)ged_killrefs(gedp, gktd.ac, (const char **)gktd.av); gedp->ged_internal_call = 0; for (i = 1; i < gktd.ac; i++) { if (!gktd.print) bu_vls_printf(gedp->ged_result_str, "Freeing %s\n", gktd.av[i]); bu_free((void *)gktd.av[i], "killtree_data"); gktd.av[i] = NULL; } } if (gktd.print) bu_vls_printf(gedp->ged_result_str, "}"); bu_free(gktd.av, "free av"); gktd.av = NULL; return GED_OK; }
int ged_get_comb(struct ged *gedp, int argc, const char *argv[]) { struct directory *dp; struct rt_db_internal intern; struct rt_comb_internal *comb; struct rt_tree_array *rt_tree_array; size_t i; size_t node_count; size_t actual_count; static const char *usage = "comb"; GED_CHECK_DATABASE_OPEN(gedp, GED_ERROR); GED_CHECK_READ_ONLY(gedp, GED_ERROR); GED_CHECK_ARGC_GT_0(gedp, argc, GED_ERROR); /* initialize result */ bu_vls_trunc(gedp->ged_result_str, 0); /* must be wanting help */ if (argc == 1) { bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); return GED_HELP; } if (argc != 2) { bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); return GED_ERROR; } dp = db_lookup(gedp->ged_wdbp->dbip, argv[1], LOOKUP_QUIET); if (dp != RT_DIR_NULL) { if (!(dp->d_flags & RT_DIR_COMB)) { bu_vls_printf(gedp->ged_result_str, "%s is not a combination, so cannot be edited this way\n", argv[1]); return GED_ERROR; } if (rt_db_get_internal(&intern, dp, gedp->ged_wdbp->dbip, (fastf_t *)NULL, &rt_uniresource) < 0) { bu_vls_printf(gedp->ged_result_str, "Database read error, aborting\n"); return GED_ERROR; } comb = (struct rt_comb_internal *)intern.idb_ptr; if (comb->tree && db_ck_v4gift_tree(comb->tree) < 0) { db_non_union_push(comb->tree, &rt_uniresource); if (db_ck_v4gift_tree(comb->tree) < 0) { bu_vls_printf(gedp->ged_result_str, "Cannot flatten tree for editing\n"); return GED_ERROR; } } node_count = db_tree_nleaves(comb->tree); if (node_count > 0) { rt_tree_array = (struct rt_tree_array *)bu_calloc(node_count, sizeof(struct rt_tree_array), "tree list"); actual_count = (struct rt_tree_array *)db_flatten_tree(rt_tree_array, comb->tree, OP_UNION, 1, &rt_uniresource) - rt_tree_array; BU_ASSERT_SIZE_T(actual_count, ==, node_count); comb->tree = TREE_NULL; } else {
int ged_bev(struct ged *gedp, int argc, const char *argv[]) { static const char *usage = "[P|t] new_obj obj1 op obj2 op obj3 ..."; int i; int c; int ncpu; char *cmdname; char *newname; struct rt_db_internal intern; struct directory *dp; char op; int failed; /* static due to longjmp */ static int triangulate = 0; static union tree *tmp_tree = NULL; GED_CHECK_DATABASE_OPEN(gedp, GED_ERROR); GED_CHECK_READ_ONLY(gedp, GED_ERROR); GED_CHECK_ARGC_GT_0(gedp, argc, GED_ERROR); /* initialize result */ bu_vls_trunc(gedp->ged_result_str, 0); /* must be wanting help */ if (argc == 1) { bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); return GED_HELP; } if (argc < 3) { bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); return GED_ERROR; } cmdname = (char *)argv[0]; /* Establish tolerances */ gedp->ged_wdbp->wdb_initial_tree_state.ts_ttol = &gedp->ged_wdbp->wdb_ttol; gedp->ged_wdbp->wdb_initial_tree_state.ts_tol = &gedp->ged_wdbp->wdb_tol; gedp->ged_wdbp->wdb_ttol.magic = RT_TESS_TOL_MAGIC; /* Initial values for options, must be reset each time */ ncpu = 1; triangulate = 0; /* Parse options. */ bu_optind = 1; /* re-init bu_getopt() */ while ((c=bu_getopt(argc, (char * const *)argv, "tP:")) != -1) { switch (c) { case 'P': #if 0 /* not yet supported */ ncpu = atoi(bu_optarg); #endif break; case 't': triangulate = 1; break; default: { bu_vls_printf(gedp->ged_result_str, "%s: option '%c' unknown\n", cmdname, c); } break; } } argc -= bu_optind; argv += bu_optind; newname = (char *)argv[0]; argv++; argc--; if (argc < 1) { bu_vls_printf(gedp->ged_result_str, "%s: Nothing to evaluate!!!\n", cmdname); return GED_ERROR; } GED_CHECK_EXISTS(gedp, newname, LOOKUP_QUIET, GED_ERROR); bu_vls_printf(gedp->ged_result_str, "%s: tessellating primitives with tolerances a=%g, r=%g, n=%g\n", argv[0], gedp->ged_wdbp->wdb_ttol.abs, gedp->ged_wdbp->wdb_ttol.rel, gedp->ged_wdbp->wdb_ttol.norm); bev_facetize_tree = (union tree *)0; bev_nmg_model = nmg_mm(); gedp->ged_wdbp->wdb_initial_tree_state.ts_m = &bev_nmg_model; op = ' '; tmp_tree = (union tree *)NULL; while (argc) { i = db_walk_tree(gedp->ged_wdbp->dbip, 1, (const char **)argv, ncpu, &gedp->ged_wdbp->wdb_initial_tree_state, 0, /* take all regions */ bev_facetize_region_end, nmg_booltree_leaf_tess, (genptr_t)gedp); if (i < 0) { bu_vls_printf(gedp->ged_result_str, "%s: error in db_walk_tree()\n", cmdname); /* Destroy NMG */ nmg_km(bev_nmg_model); return GED_ERROR; } argc--; argv++; if (tmp_tree && op != ' ') { union tree *new_tree; BU_ALLOC(new_tree, union tree); RT_TREE_INIT(new_tree); new_tree->tr_b.tb_regionp = REGION_NULL; new_tree->tr_b.tb_left = tmp_tree; new_tree->tr_b.tb_right = bev_facetize_tree; switch (op) { case 'u': case 'U': new_tree->tr_op = OP_UNION; break; case '-': new_tree->tr_op = OP_SUBTRACT; break; case '+': new_tree->tr_op = OP_INTERSECT; break; default: { bu_vls_printf(gedp->ged_result_str, "%s: Unrecognized operator: (%c)\nAborting\n", argv[0], op); db_free_tree(bev_facetize_tree, &rt_uniresource); nmg_km(bev_nmg_model); return GED_ERROR; } } tmp_tree = new_tree; bev_facetize_tree = (union tree *)NULL; } else if (!tmp_tree && op == ' ') { /* just starting out */ tmp_tree = bev_facetize_tree; bev_facetize_tree = (union tree *)NULL; } if (argc) { op = *argv[0]; argc--; argv++; } else op = ' '; } if (tmp_tree) { /* Now, evaluate the boolean tree into ONE region */ bu_vls_printf(gedp->ged_result_str, "%s: evaluating boolean expressions\n", cmdname); if (BU_SETJUMP) { BU_UNSETJUMP; bu_vls_printf(gedp->ged_result_str, "%s: WARNING: Boolean evaluation failed!!!\n", cmdname); if (tmp_tree) db_free_tree(tmp_tree, &rt_uniresource); tmp_tree = (union tree *)NULL; nmg_km(bev_nmg_model); bev_nmg_model = (struct model *)NULL; return GED_ERROR; } failed = nmg_boolean(tmp_tree, bev_nmg_model, &gedp->ged_wdbp->wdb_tol, &rt_uniresource); BU_UNSETJUMP; } else failed = 1; if (failed) { bu_vls_printf(gedp->ged_result_str, "%s: no resulting region, aborting\n", cmdname); if (tmp_tree) db_free_tree(tmp_tree, &rt_uniresource); tmp_tree = (union tree *)NULL; nmg_km(bev_nmg_model); bev_nmg_model = (struct model *)NULL; return GED_ERROR; } /* New region remains part of this nmg "model" */ NMG_CK_REGION(tmp_tree->tr_d.td_r); bu_vls_printf(gedp->ged_result_str, "%s: facetize %s\n", cmdname, tmp_tree->tr_d.td_name); nmg_vmodel(bev_nmg_model); /* Triangulate model, if requested */ if (triangulate) { bu_vls_printf(gedp->ged_result_str, "%s: triangulating resulting object\n", cmdname); if (BU_SETJUMP) { BU_UNSETJUMP; bu_vls_printf(gedp->ged_result_str, "%s: WARNING: Triangulation failed!!!\n", cmdname); if (tmp_tree) db_free_tree(tmp_tree, &rt_uniresource); tmp_tree = (union tree *)NULL; nmg_km(bev_nmg_model); bev_nmg_model = (struct model *)NULL; return GED_ERROR; } nmg_triangulate_model(bev_nmg_model, &gedp->ged_wdbp->wdb_tol); BU_UNSETJUMP; } bu_vls_printf(gedp->ged_result_str, "%s: converting NMG to database format\n", cmdname); /* Export NMG as a new solid */ RT_DB_INTERNAL_INIT(&intern); intern.idb_major_type = DB5_MAJORTYPE_BRLCAD; intern.idb_type = ID_NMG; intern.idb_meth = &rt_functab[ID_NMG]; intern.idb_ptr = (genptr_t)bev_nmg_model; bev_nmg_model = (struct model *)NULL; GED_DB_DIRADD(gedp, dp, newname, RT_DIR_PHONY_ADDR, 0, RT_DIR_SOLID, (genptr_t)&intern.idb_type, GED_ERROR); GED_DB_PUT_INTERNAL(gedp, dp, &intern, &rt_uniresource, GED_ERROR); tmp_tree->tr_d.td_r = (struct nmgregion *)NULL; /* Free boolean tree, and the regions in it. */ db_free_tree(tmp_tree, &rt_uniresource); return GED_OK; }
/* * used by the 'color' command when provided the -e option */ static int edcolor(struct ged *gedp, int argc, const char *argv[]) { struct mater *mp; struct mater *zot; FILE *fp; int c; char line[128]; static char hdr[] = "LOW\tHIGH\tRed\tGreen\tBlue\n"; char tmpfil[MAXPATHLEN]; char *editstring = NULL; GED_CHECK_DATABASE_OPEN(gedp, GED_ERROR); GED_CHECK_READ_ONLY(gedp, GED_ERROR); GED_CHECK_ARGC_GT_0(gedp, argc, GED_ERROR); bu_optind = 1; /* First, grab the editstring off of the argv list */ while ((c = bu_getopt(argc, (char * const *)argv, "E:")) != -1) { switch (c) { case 'E' : editstring = bu_optarg; break; default : break; } } argc -= bu_optind - 1; argv += bu_optind - 1; /* initialize result */ bu_vls_trunc(gedp->ged_result_str, 0); fp = bu_temp_file(tmpfil, MAXPATHLEN); if (fp == NULL) { bu_vls_printf(gedp->ged_result_str, "%s: could not create tmp file", argv[0]); return GED_ERROR; } fprintf(fp, "%s", hdr); for (mp = rt_material_head(); mp != MATER_NULL; mp = mp->mt_forw) { fprintf(fp, "%d\t%d\t%3d\t%3d\t%3d", mp->mt_low, mp->mt_high, mp->mt_r, mp->mt_g, mp->mt_b); fprintf(fp, "\n"); } (void)fclose(fp); if (!_ged_editit(editstring, (const char *)tmpfil)) { bu_vls_printf(gedp->ged_result_str, "%s: editor returned bad status. Aborted\n", argv[0]); return GED_ERROR; } /* Read file and process it */ if ((fp = fopen(tmpfil, "r")) == NULL) { perror(tmpfil); return GED_ERROR; } if (bu_fgets(line, sizeof (line), fp) == NULL || line[0] != hdr[0]) { bu_vls_printf(gedp->ged_result_str, "%s: Header line damaged, aborting\n", argv[0]); (void)fclose(fp); return GED_ERROR; } if (db_version(gedp->ged_wdbp->dbip) < 5) { /* Zap all the current records, both in core and on disk */ while (rt_material_head() != MATER_NULL) { zot = rt_material_head(); rt_new_material_head(zot->mt_forw); color_zaprec(gedp, zot); bu_free((void *)zot, "mater rec"); } while (bu_fgets(line, sizeof (line), fp) != NULL) { int cnt; int low, hi, r, g, b; /* character-separated numbers (ideally a space) */ cnt = sscanf(line, "%d%*c%d%*c%d%*c%d%*c%d", &low, &hi, &r, &g, &b); if (cnt != 9) { bu_vls_printf(gedp->ged_result_str, "%s: Discarding %s\n", argv[0], line); continue; } BU_ALLOC(mp, struct mater); mp->mt_low = low; mp->mt_high = hi; mp->mt_r = r; mp->mt_g = g; mp->mt_b = b; mp->mt_daddr = MATER_NO_ADDR; rt_insert_color(mp); color_putrec(gedp, mp); } } else { struct bu_vls vls = BU_VLS_INIT_ZERO; /* free colors in rt_material_head */ rt_color_free(); while (bu_fgets(line, sizeof (line), fp) != NULL) { int cnt; int low, hi, r, g, b; /* character-separated numbers (ideally a space) */ cnt = sscanf(line, "%d%*c%d%*c%d%*c%d%*c%d", &low, &hi, &r, &g, &b); /* check to see if line is reasonable */ if (cnt != 5) { bu_vls_printf(gedp->ged_result_str, "%s: Discarding %s\n", argv[0], line); continue; } bu_vls_printf(&vls, "{%d %d %d %d %d} ", low, hi, r, g, b); } db5_update_attribute("_GLOBAL", "regionid_colortable", bu_vls_addr(&vls), gedp->ged_wdbp->dbip); db5_import_color_table(bu_vls_addr(&vls)); bu_vls_free(&vls); } (void)fclose(fp); bu_file_delete(tmpfil); /* if there are drawables, update their colors */ if (gedp->ged_gdp) ged_color_soltab(gedp->ged_gdp->gd_headDisplay); return GED_OK; }
int ged_move(struct ged *gedp, int argc, const char *argv[]) { struct ged_display_list *gdlp; struct directory *dp; struct rt_db_internal intern; static const char *usage = "from to"; GED_CHECK_DATABASE_OPEN(gedp, GED_ERROR); GED_CHECK_READ_ONLY(gedp, GED_ERROR); GED_CHECK_ARGC_GT_0(gedp, argc, GED_ERROR); /* initialize result */ bu_vls_trunc(gedp->ged_result_str, 0); /* must be wanting help */ if (argc == 1) { bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); return GED_HELP; } if (argc != 3) { bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); return GED_ERROR; } if ((dp = db_lookup(gedp->ged_wdbp->dbip, argv[1], LOOKUP_NOISY)) == RT_DIR_NULL) return GED_ERROR; if (db_lookup(gedp->ged_wdbp->dbip, argv[2], LOOKUP_QUIET) != RT_DIR_NULL) { bu_vls_printf(gedp->ged_result_str, "%s: already exists", argv[2]); return GED_ERROR; } if (rt_db_get_internal(&intern, dp, gedp->ged_wdbp->dbip, (fastf_t *)NULL, &rt_uniresource) < 0) { bu_vls_printf(gedp->ged_result_str, "Database read error, aborting"); return GED_ERROR; } /* Change object name in the in-memory directory. */ if (db_rename(gedp->ged_wdbp->dbip, dp, argv[2]) < 0) { rt_db_free_internal(&intern); bu_vls_printf(gedp->ged_result_str, "error in db_rename to %s, aborting", argv[2]); return GED_ERROR; } /* Re-write to the database. New name is applied on the way out. */ if (rt_db_put_internal(dp, gedp->ged_wdbp->dbip, &intern, &rt_uniresource) < 0) { bu_vls_printf(gedp->ged_result_str, "Database write error, aborting"); return GED_ERROR; } /* Change object name if it matches the first element in the display list path. */ for (BU_LIST_FOR(gdlp, ged_display_list, gedp->ged_gdp->gd_headDisplay)) { int first = 1; int found = 0; struct bu_vls new_path = BU_VLS_INIT_ZERO; char *dupstr = strdup(bu_vls_addr(&gdlp->gdl_path)); char *tok = strtok(dupstr, "/"); while (tok) { if (first) { first = 0; if (BU_STR_EQUAL(tok, argv[1])) { found = 1; bu_vls_printf(&new_path, "%s", argv[2]); } else break; /* no need to go further */ } else bu_vls_printf(&new_path, "/%s", tok); tok = strtok((char *)NULL, "/"); } if (found) { bu_vls_free(&gdlp->gdl_path); bu_vls_printf(&gdlp->gdl_path, "%s", bu_vls_addr(&new_path)); } free((void *)dupstr); bu_vls_free(&new_path); } return GED_OK; }
int ged_bot_face_sort(struct ged *gedp, int argc, const char *argv[]) { int i; int tris_per_piece=0; static const char *usage = "triangles_per_piece bot_solid1 [bot_solid2 bot_solid3 ...]"; GED_CHECK_DATABASE_OPEN(gedp, GED_ERROR); GED_CHECK_READ_ONLY(gedp, GED_ERROR); GED_CHECK_ARGC_GT_0(gedp, argc, GED_ERROR); /* initialize result */ bu_vls_trunc(gedp->ged_result_str, 0); /* must be wanting help */ if (argc == 1) { bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); return GED_HELP; } if (argc < 3) { bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); return GED_ERROR; } tris_per_piece = atoi(argv[1]); if (tris_per_piece < 1) { bu_vls_printf(gedp->ged_result_str, "Illegal value for triangle per piece (%s)\n", argv[1]); bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); return GED_ERROR; } for (i = 2; i < argc; i++) { struct directory *dp; struct rt_db_internal intern; struct rt_bot_internal *bot; if ((dp=db_lookup(gedp->ged_wdbp->dbip, argv[i], LOOKUP_NOISY)) == RT_DIR_NULL) { continue; } GED_DB_GET_INTERNAL(gedp, &intern, dp, bn_mat_identity, gedp->ged_wdbp->wdb_resp, GED_ERROR); if (intern.idb_major_type != DB5_MAJORTYPE_BRLCAD || intern.idb_minor_type != DB5_MINORTYPE_BRLCAD_BOT) { rt_db_free_internal(&intern); bu_vls_printf(gedp->ged_result_str, "%s is not a BOT primitive, skipped\n", dp->d_namep); continue; } bot = (struct rt_bot_internal *)intern.idb_ptr; RT_BOT_CK_MAGIC(bot); bu_log("processing %s (%zu triangles)\n", dp->d_namep, bot->num_faces); if (rt_bot_sort_faces(bot, tris_per_piece)) { rt_db_free_internal(&intern); bu_vls_printf(gedp->ged_result_str, "Face sort failed for %s, this BOT not sorted\n", dp->d_namep); continue; } GED_DB_PUT_INTERNAL(gedp, dp, &intern, gedp->ged_wdbp->wdb_resp, GED_ERROR); } return GED_OK; }
int ged_make_name(struct rt_wdb *wdbp, int argc, char *argv[]) { int status = GED_OK; struct bu_vls obj_name; char *cp, *tp; static int i = 0; int len; static const char *usage = "template | -s [num]"; GED_CHECK_DATABASE_OPEN(wdbp, GED_ERROR); GED_CHECK_READ_ONLY(wdbp, GED_ERROR); /* initialize result */ bu_vls_trunc(&wdbp->wdb_result_str, 0); wdbp->wdb_result = GED_RESULT_NULL; wdbp->wdb_result_flags = 0; /* must be wanting help */ if (argc == 1) { wdbp->wdb_result_flags |= GED_RESULT_FLAGS_HELP_BIT; bu_vls_printf(&wdbp->wdb_result_str, "Usage: %s %s", argv[0], usage); return GED_OK; } switch (argc) { case 2: if (strcmp(argv[1], "-s") != 0) break; else { i = 0; return GED_OK; } case 3: { int new_i; if ((strcmp(argv[1], "-s") == 0) && (sscanf(argv[2], "%d", &new_i) == 1)) { i = new_i; return GED_OK; } } default: bu_vls_printf(&wdbp->wdb_result_str, "Usage: %s %s", argv[0], usage); return GED_ERROR; } bu_vls_init(&obj_name); for (cp = argv[1], len = 0; *cp != '\0'; ++cp, ++len) { if (*cp == '@') { if (*(cp + 1) == '@') ++cp; else break; } bu_vls_putc(&obj_name, *cp); } bu_vls_putc(&obj_name, '\0'); tp = (*cp == '\0') ? "" : cp + 1; do { bu_vls_trunc(&obj_name, len); bu_vls_printf(&obj_name, "%d", i++); bu_vls_strcat(&obj_name, tp); } while (db_lookup(wdbp->dbip, bu_vls_addr(&obj_name), LOOKUP_QUIET) != DIR_NULL); bu_vls_printf(&wdbp->wdb_result_str, bu_vls_addr(&obj_name)); bu_vls_free(&obj_name); return GED_OK; }
int ged_nmg_collapse(struct ged *gedp, int argc, const char *argv[]) { char *new_name; struct model *m; struct rt_db_internal intern; struct directory *dp; struct bu_ptbl faces; struct face *fp; size_t count; fastf_t tol_coll; fastf_t min_angle; static const char *usage = "nmg_prim new_prim max_err_dist [min_angle]"; GED_CHECK_DATABASE_OPEN(gedp, GED_ERROR); GED_CHECK_READ_ONLY(gedp, GED_ERROR); GED_CHECK_ARGC_GT_0(gedp, argc, GED_ERROR); /* initialize result */ bu_vls_trunc(gedp->ged_result_str, 0); /* must be wanting help */ if (argc == 1) { bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); return GED_HELP; } if (argc < 4) { bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); return GED_ERROR; } if (strchr(argv[2], '/')) { bu_vls_printf(gedp->ged_result_str, "Do not use '/' in solid names: %s\n", argv[2]); return GED_ERROR; } new_name = (char *)argv[2]; if (db_lookup(gedp->ged_wdbp->dbip, new_name, LOOKUP_QUIET) != RT_DIR_NULL) { bu_vls_printf(gedp->ged_result_str, "%s already exists\n", new_name); return GED_ERROR; } if ((dp=db_lookup(gedp->ged_wdbp->dbip, argv[1], LOOKUP_NOISY)) == RT_DIR_NULL) return GED_ERROR; if (dp->d_flags & RT_DIR_COMB) { bu_vls_printf(gedp->ged_result_str, "%s is a combination, only NMG primitives are allowed here\n", argv[1]); return GED_ERROR; } if (rt_db_get_internal(&intern, dp, gedp->ged_wdbp->dbip, (matp_t)NULL, &rt_uniresource) < 0) { bu_vls_printf(gedp->ged_result_str, "Failed to get internal form of %s!!!!\n", argv[1]); return GED_ERROR; } if (intern.idb_type != ID_NMG) { bu_vls_printf(gedp->ged_result_str, "%s is not an NMG solid!!!!\n", argv[1]); rt_db_free_internal(&intern); return GED_ERROR; } tol_coll = atof(argv[3]) * gedp->ged_wdbp->dbip->dbi_local2base; if (tol_coll <= 0.0) { bu_vls_printf(gedp->ged_result_str, "tolerance distance too small\n"); return GED_ERROR; } if (argc == 5) { min_angle = atof(argv[4]); if (min_angle < 0.0) { bu_vls_printf(gedp->ged_result_str, "Minimum angle cannot be less than zero\n"); return GED_ERROR; } } else min_angle = 0.0; m = (struct model *)intern.idb_ptr; NMG_CK_MODEL(m); /* check that all faces are planar */ nmg_face_tabulate(&faces, &m->magic); for (BU_PTBL_FOR(fp, (struct face *), &faces)) { if (fp->g.magic_p != NULL && *(fp->g.magic_p) != NMG_FACE_G_PLANE_MAGIC) { bu_log("\tnot planar\n"); bu_ptbl_free(&faces); bu_vls_printf(gedp->ged_result_str, "nmg_collapse can only be applied to NMG primitives with planar faces\n"); return GED_ERROR; } } bu_ptbl_free(&faces); /* triangulate model */ nmg_triangulate_model(m, &gedp->ged_wdbp->wdb_tol); count = (size_t)nmg_edge_collapse(m, &gedp->ged_wdbp->wdb_tol, tol_coll, min_angle); dp=db_diradd(gedp->ged_wdbp->dbip, new_name, RT_DIR_PHONY_ADDR, 0, RT_DIR_SOLID, (void *)&intern.idb_type); if (dp == RT_DIR_NULL) { bu_vls_printf(gedp->ged_result_str, "Cannot add %s to directory\n", new_name); rt_db_free_internal(&intern); return GED_ERROR; } if (rt_db_put_internal(dp, gedp->ged_wdbp->dbip, &intern, &rt_uniresource) < 0) { rt_db_free_internal(&intern); bu_vls_printf(gedp->ged_result_str, "Database write error, aborting.\n"); return GED_ERROR; } rt_db_free_internal(&intern); bu_vls_printf(gedp->ged_result_str, "%zu edges collapsed\n", count); return GED_OK; }