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_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_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_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_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_brep(struct ged *gedp, int argc, const char *argv[]) { struct bn_vlblock*vbp; const char *solid_name; static const char *usage = "brep <obj> [command|brepname|suffix] "; struct directory *ndp; struct rt_db_internal intern; struct rt_brep_internal* bi; struct brep_specific* bs; struct soltab *stp; char commtag[64]; char namebuf[64]; int i, j, real_flag, valid_command, ret; const char *commands[] = {"info", "plot", "translate", "intersect", "csg", "u", "i", "-"}; int num_commands = (int)(sizeof(commands) / sizeof(const char *)); db_op_t op = DB_OP_NULL; GED_CHECK_DATABASE_OPEN(gedp, GED_ERROR); GED_CHECK_DRAWABLE(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 < 2) { bu_vls_printf(gedp->ged_result_str, "Usage: %s\n\t%s\n", argv[0], usage); bu_vls_printf(gedp->ged_result_str, "commands:\n"); bu_vls_printf(gedp->ged_result_str, "\tvalid - report on validity of specific BREP\n"); bu_vls_printf(gedp->ged_result_str, "\tinfo - return count information for specific BREP\n"); bu_vls_printf(gedp->ged_result_str, "\tinfo S [index] - return information for specific BREP 'surface'\n"); bu_vls_printf(gedp->ged_result_str, "\tinfo F [index] - return information for specific BREP 'face'\n"); bu_vls_printf(gedp->ged_result_str, "\tplot - plot entire BREP\n"); bu_vls_printf(gedp->ged_result_str, "\tplot S [index] - plot specific BREP 'surface'\n"); bu_vls_printf(gedp->ged_result_str, "\tplot F [index] - plot specific BREP 'face'\n"); bu_vls_printf(gedp->ged_result_str, "\tcsg - convert BREP to implicit primitive CSG tree\n"); bu_vls_printf(gedp->ged_result_str, "\ttranslate SCV index i j dx dy dz - translate a surface control vertex\n"); bu_vls_printf(gedp->ged_result_str, "\tintersect <obj2> <i> <j> [PP|PC|PS|CC|CS|SS] - BREP intersections\n"); bu_vls_printf(gedp->ged_result_str, "\tu|i|- <obj2> <output> - BREP boolean evaluations\n"); bu_vls_printf(gedp->ged_result_str, "\t[brepname] - convert the non-BREP object to BREP form\n"); bu_vls_printf(gedp->ged_result_str, "\t --no-evaluation [suffix] - convert non-BREP comb to unevaluated BREP form\n"); return GED_HELP; } if (argc < 2 || argc > 11) { bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); return GED_ERROR; } solid_name = argv[1]; if ((ndp = db_lookup(gedp->ged_wdbp->dbip, solid_name, LOOKUP_NOISY)) == RT_DIR_NULL) { bu_vls_printf(gedp->ged_result_str, "Error: %s is not a solid or does not exist in database", solid_name); return GED_ERROR; } else { real_flag = (ndp->d_addr == RT_DIR_PHONY_ADDR) ? 0 : 1; } if (!real_flag) { /* solid doesn't exist - don't kill */ bu_vls_printf(gedp->ged_result_str, "Error: %s is not a real solid", solid_name); return GED_OK; } GED_DB_GET_INTERNAL(gedp, &intern, ndp, bn_mat_identity, &rt_uniresource, GED_ERROR); RT_CK_DB_INTERNAL(&intern); bi = (struct rt_brep_internal*)intern.idb_ptr; if (BU_STR_EQUAL(argv[2], "valid")) { int valid = rt_brep_valid(&intern, gedp->ged_result_str); return (valid) ? GED_OK : GED_ERROR; } if (BU_STR_EQUAL(argv[2], "intersect")) { /* handle surface-surface intersection */ struct rt_db_internal intern2; /* we need exactly 6 or 7 arguments */ if (argc != 6 && argc != 7) { bu_vls_printf(gedp->ged_result_str, "There should be 6 or 7 arguments for intersection.\n"); bu_vls_printf(gedp->ged_result_str, "See the usage for help.\n"); return GED_ERROR; } /* get the other solid */ if ((ndp = db_lookup(gedp->ged_wdbp->dbip, argv[3], LOOKUP_NOISY)) == RT_DIR_NULL) { bu_vls_printf(gedp->ged_result_str, "Error: %s is not a solid or does not exist in database", argv[3]); return GED_ERROR; } else { real_flag = (ndp->d_addr == RT_DIR_PHONY_ADDR) ? 0 : 1; } if (!real_flag) { /* solid doesn't exist - don't kill */ bu_vls_printf(gedp->ged_result_str, "Error: %s is not a real solid", argv[3]); return GED_OK; } GED_DB_GET_INTERNAL(gedp, &intern2, ndp, bn_mat_identity, &rt_uniresource, GED_ERROR); i = atoi(argv[4]); j = atoi(argv[5]); vbp = rt_vlblock_init(); if (argc == 6 || BU_STR_EQUAL(argv[6], "SS")) { brep_intersect_surface_surface(&intern, &intern2, i, j, vbp); } else if (BU_STR_EQUAL(argv[6], "PP")) { brep_intersect_point_point(&intern, &intern2, i, j); } else if (BU_STR_EQUAL(argv[6], "PC")) { brep_intersect_point_curve(&intern, &intern2, i, j); } else if (BU_STR_EQUAL(argv[6], "PS")) { brep_intersect_point_surface(&intern, &intern2, i, j); } else if (BU_STR_EQUAL(argv[6], "CC")) { brep_intersect_curve_curve(&intern, &intern2, i, j); } else if (BU_STR_EQUAL(argv[6], "CS")) { brep_intersect_curve_surface(&intern, &intern2, i, j); } else { bu_vls_printf(gedp->ged_result_str, "Invalid intersection type %s.\n", argv[6]); } _ged_cvt_vlblock_to_solids(gedp, vbp, namebuf, 0); bn_vlblock_free(vbp); vbp = (struct bn_vlblock *)NULL; rt_db_free_internal(&intern); rt_db_free_internal(&intern2); return GED_OK; } if (BU_STR_EQUAL(argv[2], "csg")) { /* Call csg conversion routine */ struct bu_vls bname_csg; bu_vls_init(&bname_csg); bu_vls_sprintf(&bname_csg, "csg_%s", solid_name); if (db_lookup(gedp->ged_wdbp->dbip, bu_vls_addr(&bname_csg), LOOKUP_QUIET) != RT_DIR_NULL) { bu_vls_printf(gedp->ged_result_str, "%s already exists.", bu_vls_addr(&bname_csg)); bu_vls_free(&bname_csg); return GED_OK; } bu_vls_free(&bname_csg); return _ged_brep_to_csg(gedp, argv[1]); } /* make sure arg isn't --no-evaluate */ if (argc > 2 && argv[2][1] != '-') { op = db_str2op(argv[2]); } if (op != DB_OP_NULL) { /* test booleans on brep. * u: union, i: intersect, -: diff, x: xor */ struct rt_db_internal intern2, intern_res; struct rt_brep_internal *bip; if (argc != 5) { bu_vls_printf(gedp->ged_result_str, "Error: There should be exactly 5 params.\n"); return GED_ERROR; } /* get the other solid */ if ((ndp = db_lookup(gedp->ged_wdbp->dbip, argv[3], LOOKUP_NOISY)) == RT_DIR_NULL) { bu_vls_printf(gedp->ged_result_str, "Error: %s is not a solid or does not exist in database", argv[3]); return GED_ERROR; } else { real_flag = (ndp->d_addr == RT_DIR_PHONY_ADDR) ? 0 : 1; } if (!real_flag) { /* solid doesn't exist - don't kill */ bu_vls_printf(gedp->ged_result_str, "Error: %s is not a real solid", argv[3]); return GED_OK; } GED_DB_GET_INTERNAL(gedp, &intern2, ndp, bn_mat_identity, &rt_uniresource, GED_ERROR); rt_brep_boolean(&intern_res, &intern, &intern2, op); bip = (struct rt_brep_internal*)intern_res.idb_ptr; mk_brep(gedp->ged_wdbp, argv[4], bip->brep); rt_db_free_internal(&intern); rt_db_free_internal(&intern2); rt_db_free_internal(&intern_res); return GED_OK; } if (BU_STR_EQUAL(argv[2], "selection")) { ret = selection_command(gedp, &intern, argc, argv); if (BU_STR_EQUAL(argv[3], "translate") && ret == 0) { GED_DB_PUT_INTERNAL(gedp, ndp, &intern, &rt_uniresource, GED_ERROR); } rt_db_free_internal(&intern); return ret; } if (!RT_BREP_TEST_MAGIC(bi)) { /* The solid is not in brep form. Covert it to brep. */ struct bu_vls bname, suffix; int no_evaluation = 0; bu_vls_init(&bname); bu_vls_init(&suffix); if (argc == 2) { /* brep obj */ bu_vls_sprintf(&bname, "%s_brep", solid_name); bu_vls_sprintf(&suffix, "_brep"); } else if (BU_STR_EQUAL(argv[2], "--no-evaluation")) { no_evaluation = 1; if (argc == 3) { /* brep obj --no-evaluation */ bu_vls_sprintf(&bname, "%s_brep", solid_name); bu_vls_sprintf(&suffix, "_brep"); } else if (argc == 4) { /* brep obj --no-evaluation suffix */ bu_vls_sprintf(&bname, argv[3]); bu_vls_sprintf(&suffix, argv[3]); } } else { /* brep obj brepname/suffix */ bu_vls_sprintf(&bname, argv[2]); bu_vls_sprintf(&suffix, argv[2]); } if (no_evaluation && intern.idb_type == ID_COMBINATION) { struct bu_vls bname_suffix; bu_vls_init(&bname_suffix); bu_vls_sprintf(&bname_suffix, "%s%s", solid_name, bu_vls_addr(&suffix)); if (db_lookup(gedp->ged_wdbp->dbip, bu_vls_addr(&bname_suffix), LOOKUP_QUIET) != RT_DIR_NULL) { bu_vls_printf(gedp->ged_result_str, "%s already exists.", bu_vls_addr(&bname_suffix)); bu_vls_free(&bname); bu_vls_free(&suffix); bu_vls_free(&bname_suffix); return GED_OK; } brep_conversion_comb(&intern, bu_vls_addr(&bname_suffix), bu_vls_addr(&suffix), gedp->ged_wdbp, mk_conv2mm); bu_vls_free(&bname_suffix); } else { struct rt_db_internal brep_db_internal; ON_Brep* brep; if (db_lookup(gedp->ged_wdbp->dbip, bu_vls_addr(&bname), LOOKUP_QUIET) != RT_DIR_NULL) { bu_vls_printf(gedp->ged_result_str, "%s already exists.", bu_vls_addr(&bname)); bu_vls_free(&bname); bu_vls_free(&suffix); return GED_OK; } ret = brep_conversion(&intern, &brep_db_internal, gedp->ged_wdbp->dbip); if (ret == -1) { bu_vls_printf(gedp->ged_result_str, "%s doesn't have a " "brep-conversion function yet. Type: %s", solid_name, intern.idb_meth->ft_label); } else if (ret == -2) { bu_vls_printf(gedp->ged_result_str, "%s cannot be converted " "to brep correctly.", solid_name); } else { brep = ((struct rt_brep_internal *)brep_db_internal.idb_ptr)->brep; ret = mk_brep(gedp->ged_wdbp, bu_vls_addr(&bname), brep); if (ret == 0) { bu_vls_printf(gedp->ged_result_str, "%s is made.", bu_vls_addr(&bname)); } rt_db_free_internal(&brep_db_internal); } } bu_vls_free(&bname); bu_vls_free(&suffix); rt_db_free_internal(&intern); return GED_OK; } BU_ALLOC(stp, struct soltab); if (argc == 2) { bu_vls_printf(gedp->ged_result_str, "Usage: %s %s\n", argv[0], usage); bu_vls_printf(gedp->ged_result_str, "\t%s is in brep form, please input a command.", solid_name); return GED_HELP; } valid_command = 0; for (i = 0; i < num_commands; ++i) { if (BU_STR_EQUAL(argv[2], commands[i])) { valid_command = 1; break; } } if (!valid_command) { bu_vls_printf(gedp->ged_result_str, "Usage: %s %s\n", argv[0], usage); bu_vls_printf(gedp->ged_result_str, "\t%s is in brep form, please input a command.", solid_name); return GED_HELP; } if ((bs = (struct brep_specific*)stp->st_specific) == NULL) { BU_ALLOC(bs, struct brep_specific); bs->brep = bi->brep; bi->brep = NULL; stp->st_specific = (void *)bs; } vbp = rt_vlblock_init(); brep_command(gedp->ged_result_str, solid_name, (const struct rt_tess_tol *)&gedp->ged_wdbp->wdb_ttol, &gedp->ged_wdbp->wdb_tol, bs, bi, vbp, argc, argv, commtag); if (BU_STR_EQUAL(argv[2], "translate")) { bi->brep = bs->brep; GED_DB_PUT_INTERNAL(gedp, ndp, &intern, &rt_uniresource, GED_ERROR); } snprintf(namebuf, 64, "%s%s_", commtag, solid_name); _ged_cvt_vlblock_to_solids(gedp, vbp, namebuf, 0); bn_vlblock_free(vbp); vbp = (struct bn_vlblock *)NULL; rt_db_free_internal(&intern); 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_bot_face_split(struct ged *gedp, int argc, const char *argv[]) { static const char *usage = "bot face"; struct directory *dp; static fastf_t sf = 1.0 / 3.0; struct rt_db_internal intern; struct rt_bot_internal *botip; mat_t mat; char *last; size_t face_i; size_t last_vi; size_t save_vi; point_t new_pt; GED_CHECK_DATABASE_OPEN(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 ((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; } dp = db_lookup(gedp->ged_wdbp->dbip, last, LOOKUP_QUIET); if (dp == RT_DIR_NULL) { bu_vls_printf(gedp->ged_result_str, "%s: failed to find %s", argv[0], argv[1]); return GED_ERROR; } if (bu_sscanf(argv[2], "%zu", &face_i) != 1) { bu_vls_printf(gedp->ged_result_str, "%s: bad bot vertex index - %s", argv[0], argv[2]); return GED_ERROR; } if (wdb_import_from_path2(gedp->ged_result_str, &intern, last, gedp->ged_wdbp, mat) == GED_ERROR) { bu_vls_printf(gedp->ged_result_str, "%s: failed to find %s", argv[0], argv[1]); return 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, "Object is not a BOT"); rt_db_free_internal(&intern); return GED_ERROR; } botip = (struct rt_bot_internal *)intern.idb_ptr; last_vi = botip->num_vertices; if (face_i >= botip->num_faces) { bu_vls_printf(gedp->ged_result_str, "%s: bad bot face index - %s", argv[0], argv[2]); rt_db_free_internal(&intern); return GED_ERROR; } /* Create the new point, modify face_i and hook in the two extra faces */ /* First, create some space */ botip->num_vertices++; botip->num_faces += 2; botip->vertices = (fastf_t *)bu_realloc((void *)botip->vertices, botip->num_vertices*3*sizeof(fastf_t), "realloc bot vertices"); botip->faces = (int *)bu_realloc((void *)botip->faces, botip->num_faces*3*sizeof(int), "realloc bot faces"); /* Create the new point. For the moment, we're using the average of the face_i's points */ VADD3(new_pt, &botip->vertices[botip->faces[face_i*3]*3], &botip->vertices[botip->faces[face_i*3+1]*3], &botip->vertices[botip->faces[face_i*3+2]*3]); VSCALE(new_pt, new_pt, sf); /* Add the new point to the last position in the list of vertices. */ VMOVE(&botip->vertices[last_vi*3], new_pt); /* Update face_i */ save_vi = botip->faces[face_i*3+2]; botip->faces[face_i*3+2] = last_vi; /* Initialize the two new faces */ botip->faces[(botip->num_faces-2)*3] = botip->faces[face_i*3+1]; botip->faces[(botip->num_faces-2)*3+1] = save_vi; botip->faces[(botip->num_faces-2)*3+2] = last_vi; botip->faces[(botip->num_faces-1)*3] = save_vi; botip->faces[(botip->num_faces-1)*3+1] = botip->faces[face_i*3]; botip->faces[(botip->num_faces-1)*3+2] = last_vi; bu_vls_printf(gedp->ged_result_str, "%zu", last_vi); GED_DB_PUT_INTERNAL(gedp, dp, &intern, &rt_uniresource, GED_ERROR); rt_db_free_internal(&intern); return GED_OK; }
/* * 'make_pnts' command for importing point-cloud data into a 'pnts' * primitive. * * Input values: * argv[1] object name * argv[2] filename with path * argv[3] point data file format string * argv[4] point data file units string or conversion factor to millimeters * argv[5] default size of each point * */ int ged_make_pnts(struct ged *gedp, int argc, const char *argv[]) { struct directory *dp; struct rt_db_internal internal; rt_pnt_type type; double local2base; unsigned long numPoints = 0; struct rt_pnts_internal *pnts; double defaultSize = 0.0; void *headPoint = NULL; FILE *fp; int temp_string_index = 0; /* index into temp_string, set to first character in temp_string, i.e. the start */ unsigned long int num_doubles_read = 0; /* counters of double read from file */ int current_character_double = 0; /* flag indicating if current character read is part of a double or delimiter */ int previous_character_double = 0; /* flag indicating if previously read character was part of a double or delimiter */ unsigned long int num_characters_read_from_file = 0; /* counter of number of characters read from file */ unsigned long int start_offset_of_current_double = 0; /* character offset from start of file for current double */ int found_double = 0; /* flag indicating if double encountered in file and needs to be processed */ int found_eof = 0; /* flag indicating if end-of-file encountered when reading file */ int done_processing_format_string = 0; /* flag indicating if loop processing format string should be exited */ char *temp_char_ptr = (char *)NULL; int buf = 0; /* raw character read from file */ double temp_double = 0.0; char temp_string[1024]; int temp_string_size = 1024; /* number of characters that can be stored in temp_string including null terminator character */ /* it is expected that the character representation of a double will never exceed this size string */ char *endp = (char *)NULL; struct bu_vls format_string = BU_VLS_INIT_ZERO; size_t format_string_index = 0; unsigned int num_doubles_per_point = 0; void *point = NULL; char **prompt; static const char *usage = "point_cloud_name filename_with_path file_format file_data_units default_point_size"; prompt = &p_make_pnts[0]; 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 > 6) { bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); return GED_ERROR; } /* prompt for point-cloud name */ if (argc < 2) { bu_vls_printf(gedp->ged_result_str, "%s", prompt[0]); return GED_MORE; } GED_CHECK_EXISTS(gedp, argv[1], LOOKUP_QUIET, GED_ERROR); /* prompt for data file name with path */ if (argc < 3) { bu_vls_printf(gedp->ged_result_str, "%s", prompt[1]); return GED_MORE; } /* prompt for data file format */ if (argc < 4) { bu_vls_printf(gedp->ged_result_str, "%s", prompt[2]); return GED_MORE; } /* Validate 'point file data format string' and return point-cloud type. */ if (str2type(argv[3], &type, gedp->ged_result_str) == GED_ERROR) { return GED_ERROR; } /* prompt for data file units */ if (argc < 5) { bu_vls_printf(gedp->ged_result_str, "%s", prompt[3]); return GED_MORE; } /* Validate the unit string and return conversion factor to millimeters. */ if (str2mm(argv[4], &local2base, gedp->ged_result_str) == GED_ERROR) { return GED_ERROR; } /* prompt for default point size */ if (argc < 6) { bu_vls_printf(gedp->ged_result_str, "%s", prompt[4]); return GED_MORE; } defaultSize = strtod(argv[5], &endp); if ((endp != argv[5]) && (*endp == '\0')) { /* convert to double success */ if (defaultSize < 0.0) { bu_vls_printf(gedp->ged_result_str, "Default point size '%lf' must be non-negative.\n", defaultSize); return GED_ERROR; } } else { bu_vls_printf(gedp->ged_result_str, "Invalid default point size '%s'\n", argv[5]); return GED_ERROR; } bu_vls_strcat(&format_string, argv[3]); bu_vls_trimspace(&format_string); /* init database structure */ RT_DB_INTERNAL_INIT(&internal); internal.idb_major_type = DB5_MAJORTYPE_BRLCAD; internal.idb_type = ID_PNTS; internal.idb_meth = &OBJ[ID_PNTS]; BU_ALLOC(internal.idb_ptr, struct rt_pnts_internal); /* init internal structure */ pnts = (struct rt_pnts_internal *) internal.idb_ptr; pnts->magic = RT_PNTS_INTERNAL_MAGIC; pnts->scale = defaultSize; pnts->type = type; pnts->count = numPoints; /* set again later */ pnts->point = NULL; /* empty list head */ switch (type) { case RT_PNT_TYPE_PNT: BU_ALLOC(headPoint, struct pnt); BU_LIST_INIT(&(((struct pnt *)headPoint)->l)); num_doubles_per_point = 3; break; case RT_PNT_TYPE_COL: BU_ALLOC(headPoint, struct pnt_color); BU_LIST_INIT(&(((struct pnt_color *)headPoint)->l)); num_doubles_per_point = 6; break; case RT_PNT_TYPE_SCA: BU_ALLOC(headPoint, struct pnt_scale); BU_LIST_INIT(&(((struct pnt_scale *)headPoint)->l)); num_doubles_per_point = 4; break; case RT_PNT_TYPE_NRM: BU_ALLOC(headPoint, struct pnt_normal); BU_LIST_INIT(&(((struct pnt_normal *)headPoint)->l)); num_doubles_per_point = 6; break; case RT_PNT_TYPE_COL_SCA: BU_ALLOC(headPoint, struct pnt_color_scale); BU_LIST_INIT(&(((struct pnt_color_scale *)headPoint)->l)); num_doubles_per_point = 7; break; case RT_PNT_TYPE_COL_NRM: BU_ALLOC(headPoint, struct pnt_color_normal); BU_LIST_INIT(&(((struct pnt_color_normal *)headPoint)->l)); num_doubles_per_point = 9; break; case RT_PNT_TYPE_SCA_NRM: BU_ALLOC(headPoint, struct pnt_scale_normal); BU_LIST_INIT(&(((struct pnt_scale_normal *)headPoint)->l)); num_doubles_per_point = 7; break; case RT_PNT_TYPE_COL_SCA_NRM: BU_ALLOC(headPoint, struct pnt_color_scale_normal); BU_LIST_INIT(&(((struct pnt_color_scale_normal *)headPoint)->l)); num_doubles_per_point = 10; break; } BU_ASSERT_PTR(headPoint, !=, NULL); pnts->point = headPoint; if ((fp=fopen(argv[2], "rb")) == NULL) { bu_vls_printf(gedp->ged_result_str, "Make '%s' failed. ", argv[1]); bu_vls_printf(gedp->ged_result_str, "Could not open file '%s'.\n", argv[2]); bu_vls_free(&format_string); rt_db_free_internal(&internal); return GED_ERROR; } while (!found_eof) { /* points_loop */ /* allocate memory for single point structure for current point-cloud type */ switch (type) { case RT_PNT_TYPE_PNT: BU_ALLOC(point, struct pnt); break; case RT_PNT_TYPE_COL: BU_ALLOC(point, struct pnt_color); break; case RT_PNT_TYPE_SCA: BU_ALLOC(point, struct pnt_scale); break; case RT_PNT_TYPE_NRM: BU_ALLOC(point, struct pnt_normal); break; case RT_PNT_TYPE_COL_SCA: BU_ALLOC(point, struct pnt_color_scale); break; case RT_PNT_TYPE_COL_NRM: BU_ALLOC(point, struct pnt_color_normal); break; case RT_PNT_TYPE_SCA_NRM: BU_ALLOC(point, struct pnt_scale_normal); break; case RT_PNT_TYPE_COL_SCA_NRM: BU_ALLOC(point, struct pnt_color_scale_normal); break; } /* make sure we have something */ BU_ASSERT_PTR(point, !=, NULL); while (!found_eof && !done_processing_format_string) { /* format_string_loop */ char format = '\0'; while (!found_eof && !found_double) { /* find_doubles_loop */ format = bu_vls_addr(&format_string)[format_string_index]; buf = fgetc(fp); num_characters_read_from_file++; if (feof(fp)) { if (ferror(fp)) { perror("ERROR: Problem reading file, system error message"); fclose(fp); bu_vls_printf(gedp->ged_result_str, "Make '%s' failed. ", argv[1]); bu_vls_printf(gedp->ged_result_str, "Unable to read file at byte '%lu'.\n", num_characters_read_from_file); bu_vls_free(&format_string); rt_db_free_internal(&internal); return GED_ERROR; } else { found_eof = 1; } } if (found_eof) { fclose(fp); current_character_double = 0; if (num_doubles_read == 0) { bu_vls_printf(gedp->ged_result_str, "Make '%s' failed. ", argv[1]); bu_vls_printf(gedp->ged_result_str, "No data in file '%s'.\n", argv[2]); bu_vls_free(&format_string); rt_db_free_internal(&internal); return GED_ERROR; } } else { temp_char_ptr = strchr("0123456789.+-eE", buf); if (temp_char_ptr != NULL) { /* character read is part of a double */ current_character_double = 1; } else { current_character_double = 0; } } if (previous_character_double && current_character_double) { if (temp_string_index >= temp_string_size) { fclose(fp); bu_vls_printf(gedp->ged_result_str, "Make '%s' failed. ", argv[1]); bu_vls_printf(gedp->ged_result_str, "String representing double too large, exceeds '%d' character limit. ", temp_string_size - 1); report_import_error_location(num_doubles_read, num_doubles_per_point, start_offset_of_current_double, format, gedp->ged_result_str); bu_vls_free(&format_string); rt_db_free_internal(&internal); return GED_ERROR; } temp_string[temp_string_index] = (char)buf; temp_string_index++; } if (previous_character_double && !current_character_double) { if (temp_string_index >= temp_string_size) { fclose(fp); bu_vls_printf(gedp->ged_result_str, "Make '%s' failed. ", argv[1]); bu_vls_printf(gedp->ged_result_str, "String representing double too large, exceeds '%d' character limit. ", temp_string_size - 1); report_import_error_location(num_doubles_read, num_doubles_per_point, start_offset_of_current_double, format, gedp->ged_result_str); bu_vls_free(&format_string); rt_db_free_internal(&internal); return GED_ERROR; } temp_string[temp_string_index] = '\0'; /* do not convert string to double for format character '?' */ if (format != '?') { temp_double = strtod(temp_string, &endp); if (!((endp != temp_string) && (*endp == '\0'))) { fclose(fp); bu_vls_printf(gedp->ged_result_str, "Make '%s' failed. ", argv[1]); bu_vls_printf(gedp->ged_result_str, "Unable to convert string '%s' to double. ", temp_string); report_import_error_location(num_doubles_read, num_doubles_per_point, start_offset_of_current_double, format, gedp->ged_result_str); bu_vls_free(&format_string); rt_db_free_internal(&internal); return GED_ERROR; } num_doubles_read++; } else { temp_double = 0.0; } temp_string_index = 0; found_double = 1; previous_character_double = current_character_double; } if (!previous_character_double && current_character_double) { temp_string[temp_string_index] = (char)buf; temp_string_index++; start_offset_of_current_double = num_characters_read_from_file; previous_character_double = current_character_double; } } /* loop exits when eof encountered (and/or) double found */ if (found_double) { /* insert double into point structure for current point-cloud type */ /* do not attempt to insert double into point structure for format character '?' */ if (format != '?') { switch (type) { case RT_PNT_TYPE_PNT: INSERT_COORDINATE_INTO_STRUCTURE(pnt, format, (temp_double * local2base)); break; case RT_PNT_TYPE_COL: INSERT_COORDINATE_INTO_STRUCTURE(pnt_color, format, (temp_double * local2base)); INSERT_COLOR_INTO_STRUCTURE(pnt_color, format, temp_double); break; case RT_PNT_TYPE_SCA: INSERT_COORDINATE_INTO_STRUCTURE(pnt_scale, format, (temp_double * local2base)); INSERT_SCALE_INTO_STRUCTURE(pnt_scale, format, (temp_double * local2base)); break; case RT_PNT_TYPE_NRM: INSERT_COORDINATE_INTO_STRUCTURE(pnt_normal, format, (temp_double * local2base)); INSERT_NORMAL_INTO_STRUCTURE(pnt_normal, format, (temp_double * local2base)); break; case RT_PNT_TYPE_COL_SCA: INSERT_COORDINATE_INTO_STRUCTURE(pnt_color_scale, format, (temp_double * local2base)); INSERT_COLOR_INTO_STRUCTURE(pnt_color_scale, format, temp_double); INSERT_SCALE_INTO_STRUCTURE(pnt_color_scale, format, (temp_double * local2base)); break; case RT_PNT_TYPE_COL_NRM: INSERT_COORDINATE_INTO_STRUCTURE(pnt_color_normal, format, (temp_double * local2base)); INSERT_COLOR_INTO_STRUCTURE(pnt_color_normal, format, temp_double); INSERT_NORMAL_INTO_STRUCTURE(pnt_color_normal, format, (temp_double * local2base)); break; case RT_PNT_TYPE_SCA_NRM: INSERT_COORDINATE_INTO_STRUCTURE(pnt_scale_normal, format, (temp_double * local2base)); INSERT_SCALE_INTO_STRUCTURE(pnt_scale_normal, format, (temp_double * local2base)); INSERT_NORMAL_INTO_STRUCTURE(pnt_scale_normal, format, (temp_double * local2base)); break; case RT_PNT_TYPE_COL_SCA_NRM: INSERT_COORDINATE_INTO_STRUCTURE(pnt_color_scale_normal, format, (temp_double * local2base)); INSERT_COLOR_INTO_STRUCTURE(pnt_color_scale_normal, format, temp_double); INSERT_SCALE_INTO_STRUCTURE(pnt_color_scale_normal, format, (temp_double * local2base)); INSERT_NORMAL_INTO_STRUCTURE(pnt_color_scale_normal, format, (temp_double * local2base)); break; } } found_double = 0; /* allows loop to continue */ format_string_index++; if (format_string_index >= bu_vls_strlen(&format_string)) { done_processing_format_string = 1; } } } /* loop exits when eof encountered (and/or) all doubles for * a single point are stored in point structure */ if (done_processing_format_string) { /* push single point structure onto linked-list of points * which makeup the point-cloud. */ switch (type) { case RT_PNT_TYPE_PNT: BU_LIST_PUSH(&(((struct pnt *)headPoint)->l), &((struct pnt *)point)->l); break; case RT_PNT_TYPE_COL: BU_LIST_PUSH(&(((struct pnt_color *)headPoint)->l), &((struct pnt_color *)point)->l); break; case RT_PNT_TYPE_SCA: BU_LIST_PUSH(&(((struct pnt_scale *)headPoint)->l), &((struct pnt_scale *)point)->l); break; case RT_PNT_TYPE_NRM: BU_LIST_PUSH(&(((struct pnt_normal *)headPoint)->l), &((struct pnt_normal *)point)->l); break; case RT_PNT_TYPE_COL_SCA: BU_LIST_PUSH(&(((struct pnt_color_scale *)headPoint)->l), &((struct pnt_color_scale *)point)->l); break; case RT_PNT_TYPE_COL_NRM: BU_LIST_PUSH(&(((struct pnt_color_normal *)headPoint)->l), &((struct pnt_color_normal *)point)->l); break; case RT_PNT_TYPE_SCA_NRM: BU_LIST_PUSH(&(((struct pnt_scale_normal *)headPoint)->l), &((struct pnt_scale_normal *)point)->l); break; case RT_PNT_TYPE_COL_SCA_NRM: BU_LIST_PUSH(&(((struct pnt_color_scale_normal *)headPoint)->l), &((struct pnt_color_scale_normal *)point)->l); break; } numPoints++; format_string_index = 0; done_processing_format_string = 0; } } /* loop exits when eof encountered */ if (num_doubles_read < num_doubles_per_point) { bu_vls_printf(gedp->ged_result_str, "Make '%s' failed. Number of values read inconsistent with point-cloud type ", argv[1]); bu_vls_printf(gedp->ged_result_str, "defined by format string '%V'. The number of values read must be an even ", format_string); bu_vls_printf(gedp->ged_result_str, "multiple of %d but read %lu values.\n", num_doubles_per_point, num_doubles_read); bu_vls_free(&format_string); rt_db_free_internal(&internal); return GED_ERROR; } if (num_doubles_read % num_doubles_per_point) { bu_vls_printf(gedp->ged_result_str, "Make '%s' failed. Number of values read inconsistent with point-cloud type ", argv[1]); bu_vls_printf(gedp->ged_result_str, "defined by format string '%V'. The number of values read must be an even ", format_string); bu_vls_printf(gedp->ged_result_str, "multiple of %d but read %lu values.\n", num_doubles_per_point, num_doubles_read); bu_vls_free(&format_string); rt_db_free_internal(&internal); return GED_ERROR; } pnts->count = numPoints; GED_DB_DIRADD(gedp, dp, argv[1], RT_DIR_PHONY_ADDR, 0, RT_DIR_SOLID, (void *)&internal.idb_type, GED_ERROR); GED_DB_PUT_INTERNAL(gedp, dp, &internal, &rt_uniresource, GED_ERROR); bu_vls_free(&format_string); bu_vls_printf(gedp->ged_result_str, "Make '%s' success, %lu values read, %lu points imported.\n", argv[1], num_doubles_read, numPoints); return GED_OK; }
int ged_bot_fuse(struct ged *gedp, int argc, const char **argv) { struct directory *old_dp, *new_dp; struct rt_db_internal intern, intern2; struct rt_bot_internal *bot; int count=0; static const char *usage = "new_bot old_bot"; struct model *m; struct nmgregion *r; int ret, c, i; struct bn_tol *tol = &gedp->ged_wdbp->wdb_tol; int total = 0; volatile int out_type = 0; /* open edge output type: 0 = none, 1 = show, 2 = plot */ size_t open_cnt; struct bu_vls name_prefix = BU_VLS_INIT_ZERO; /* bu_getopt() options */ static const char *bot_fuse_options = "sp"; static const char *bot_fuse_options_str = "[-s|-p]"; 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 && argc != 4) { bu_vls_printf(gedp->ged_result_str, "Usage: %s %s %s", argv[0], bot_fuse_options_str, usage); return GED_HELP; } /* Turn off getopt's error messages */ bu_opterr = 0; bu_optind = 1; /* get all the option flags from the command line */ while ((c=bu_getopt(argc, (char **)argv, bot_fuse_options)) != -1) { switch (c) { case 's': { out_type = 1; /* show open edges */ break; } case 'p': { out_type = 2; /* plot open edges */ break; } default : { bu_vls_printf(gedp->ged_result_str, "Unknown option: '%c'", c); return GED_HELP; } } } i = argc - 2; bu_log("%s: start\n", argv[0]); GED_DB_LOOKUP(gedp, old_dp, argv[i+1], 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[i+1]); return GED_ERROR; } /* create nmg model structure */ m = nmg_mm(); /* place bot in nmg structure */ bu_log("%s: running rt_bot_tess\n", argv[0]); ret = rt_bot_tess(&r, m, &intern, &gedp->ged_wdbp->wdb_ttol, tol); /* free internal representation of original bot */ rt_db_free_internal(&intern); if (ret != 0) { bu_vls_printf(gedp->ged_result_str, "%s: %s fuse failed (1).\n", argv[0], argv[i+1]); nmg_km(m); return GED_ERROR; } total = 0; /* Step 1 -- the vertices. */ bu_log("%s: running nmg_vertex_fuse\n", argv[0]); count = nmg_vertex_fuse(&m->magic, tol); total += count; bu_log("%s: %s, %d vertex fused\n", argv[0], argv[i+1], count); /* Step 1.5 -- break edges on vertices, before fusing edges */ bu_log("%s: running nmg_break_e_on_v\n", argv[0]); count = nmg_break_e_on_v(&m->magic, tol); total += count; bu_log("%s: %s, %d broke 'e' on 'v'\n", argv[0], argv[i+1], count); if (total) { struct nmgregion *r2; struct shell *s; bu_log("%s: running nmg_make_faces_within_tol\n", argv[0]); /* vertices and/or edges have been moved, * may have created out-of-tolerance faces */ for (BU_LIST_FOR(r2, nmgregion, &m->r_hd)) { for (BU_LIST_FOR(s, shell, &r2->s_hd)) nmg_make_faces_within_tol(s, tol); } } /* Step 2 -- the face geometry */ bu_log("%s: running nmg_model_face_fuse\n", argv[0]); count = nmg_model_face_fuse(m, tol); total += count; bu_log("%s: %s, %d faces fused\n", argv[0], argv[i+1], count); /* Step 3 -- edges */ bu_log("%s: running nmg_edge_fuse\n", argv[0]); count = nmg_edge_fuse(&m->magic, tol); total += count; bu_log("%s: %s, %d edges fused\n", argv[0], argv[i+1], count); bu_log("%s: %s, %d total fused\n", argv[0], argv[i+1], total); if (!BU_SETJUMP) { /* try */ /* convert the nmg model back into a bot */ bot = nmg_bot(BU_LIST_FIRST(shell, &r->s_hd), tol); bu_vls_sprintf(&name_prefix, "open_edges.%s", argv[i]); bu_log("%s: running show_dangling_edges\n", argv[0]); open_cnt = show_dangling_edges(gedp, &m->magic, bu_vls_addr(&name_prefix), out_type); bu_log("%s: WARNING %ld open edges, new BOT may be invalid!!!\n", argv[0], open_cnt); bu_vls_free(&name_prefix); /* free the nmg model structure */ nmg_km(m); } else { /* catch */ BU_UNSETJUMP; bu_vls_printf(gedp->ged_result_str, "%s: %s fuse failed (2).\n", argv[0], argv[i+1]); return GED_ERROR; } BU_UNSETJUMP; RT_DB_INTERNAL_INIT(&intern2); intern2.idb_major_type = DB5_MAJORTYPE_BRLCAD; intern2.idb_type = ID_BOT; intern2.idb_meth = &OBJ[ID_BOT]; intern2.idb_ptr = (void *)bot; GED_DB_DIRADD(gedp, new_dp, argv[i], RT_DIR_PHONY_ADDR, 0, RT_DIR_SOLID, (void *)&intern2.idb_type, GED_ERROR); GED_DB_PUT_INTERNAL(gedp, new_dp, &intern2, &rt_uniresource, GED_ERROR); bu_log("%s: Created new BOT (%s)\n", argv[0], argv[i]); bu_log("%s: Done.\n", argv[0]); return GED_OK; }
int ged_bot_smooth(struct ged *gedp, int argc, const char *argv[]) { char *new_bot_name, *old_bot_name; struct directory *dp_old, *dp_new; struct rt_bot_internal *old_bot; struct rt_db_internal intern; fastf_t tolerance_angle=180.0; int arg_index=1; static const char *usage = "[-t ntol] 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); dp_old = dp_new = RT_DIR_NULL; /* 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; } /* 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 BOT surface normals.\nUse \"dbupgrade\" to upgrade this database to the current version.\n"); return GED_ERROR; } if (argc < 3) { bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); return GED_ERROR; } while (*argv[arg_index] == '-') { /* this is an option */ if (BU_STR_EQUAL(argv[arg_index], "-t")) { arg_index++; tolerance_angle = atof(argv[arg_index]); } else { bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); return GED_ERROR; } arg_index++; } if (arg_index >= argc) { bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); return GED_ERROR; } new_bot_name = (char *)argv[arg_index++]; old_bot_name = (char *)argv[arg_index]; GED_DB_LOOKUP(gedp, dp_old, old_bot_name, LOOKUP_QUIET, GED_ERROR); if (!BU_STR_EQUAL(old_bot_name, new_bot_name)) { GED_CHECK_EXISTS(gedp, new_bot_name, LOOKUP_QUIET, GED_ERROR); } else { dp_new = dp_old; } GED_DB_GET_INTERNAL(gedp, &intern, dp_old, NULL, gedp->ged_wdbp->wdb_resp, 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 is not a BOT primitive\n", old_bot_name); rt_db_free_internal(&intern); return GED_ERROR; } old_bot = (struct rt_bot_internal *)intern.idb_ptr; RT_BOT_CK_MAGIC(old_bot); if (rt_bot_smooth(old_bot, old_bot_name, gedp->ged_wdbp->dbip, tolerance_angle*DEG2RAD)) { bu_vls_printf(gedp->ged_result_str, "Failed to smooth %s\n", old_bot_name); rt_db_free_internal(&intern); return GED_ERROR; } if (dp_new == RT_DIR_NULL) { GED_DB_DIRADD(gedp, dp_new, new_bot_name, RT_DIR_PHONY_ADDR, 0, RT_DIR_SOLID, (void *)&intern.idb_type, GED_ERROR); } GED_DB_PUT_INTERNAL(gedp, dp_new, &intern, gedp->ged_wdbp->wdb_resp, GED_ERROR); rt_db_free_internal(&intern); return GED_OK; }
int ged_pset(struct ged *gedp, int argc, const char *argv[]) { int ret; struct rt_db_internal intern; /* intentionally double for scan */ double val; char *last; struct directory *dp; static const char *usage = "obj attribute val"; 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", &val) != 1) { bu_vls_printf(gedp->ged_result_str, "%s: bad value - %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 scaling.", argv[0]); rt_db_free_internal(&intern); return GED_ERROR; } switch (intern.idb_minor_type) { case DB5_MINORTYPE_BRLCAD_METABALL: ret = _ged_set_metaball(gedp, (struct rt_metaball_internal *)intern.idb_ptr, argv[2], val); 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_move_botpts(struct ged *gedp, int argc, const char *argv[]) { static const char *usage = "bot vec vertex_1 [vertex_2 ... vertex_n]"; struct directory *dp; struct rt_db_internal intern; struct rt_bot_internal *botip; mat_t mat; register int i; size_t vertex_i; char *last; /* must be double for scanf */ double vec[ELEMENTS_PER_VECT]; GED_CHECK_DATABASE_OPEN(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 ((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; } dp = db_lookup(gedp->ged_wdbp->dbip, last, LOOKUP_QUIET); if (dp == RT_DIR_NULL) { bu_vls_printf(gedp->ged_result_str, "%s: failed to find %s", argv[0], argv[1]); return GED_ERROR; } if (bu_sscanf(argv[2], "%lf %lf %lf", &vec[X], &vec[Y], &vec[Z]) != 3) { bu_vls_printf(gedp->ged_result_str, "%s: bad vector - %s", argv[0], argv[2]); return GED_ERROR; } VSCALE(vec, vec, gedp->ged_wdbp->dbip->dbi_local2base); if (wdb_import_from_path2(gedp->ged_result_str, &intern, argv[1], gedp->ged_wdbp, mat) == GED_ERROR) { bu_vls_printf(gedp->ged_result_str, "%s: failed to find %s", argv[0], argv[1]); return 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, "Object is not a BOT"); rt_db_free_internal(&intern); return GED_ERROR; } botip = (struct rt_bot_internal *)intern.idb_ptr; for (i = 3; i < argc; ++i) { if (bu_sscanf(argv[i], "%zu", &vertex_i) != 1) { bu_vls_printf(gedp->ged_result_str, "%s: bad bot vertex index - %s\n", argv[0], argv[i]); continue; } if (vertex_i >= botip->num_vertices) { bu_vls_printf(gedp->ged_result_str, "%s: bad bot vertex index - %s\n", argv[0], argv[i]); continue; } VADD2(&botip->vertices[vertex_i*3], vec, &botip->vertices[vertex_i*3]); } { mat_t invmat; point_t curr_pt; size_t idx; bn_mat_inv(invmat, mat); for (idx = 0; idx < botip->num_vertices; idx++) { MAT4X3PNT(curr_pt, invmat, &botip->vertices[idx*3]); VMOVE(&botip->vertices[idx*3], curr_pt); } } GED_DB_PUT_INTERNAL(gedp, dp, &intern, &rt_uniresource, GED_ERROR); rt_db_free_internal(&intern); return GED_OK; }
int ged_bot_edge_split(struct ged *gedp, int argc, const char *argv[]) { static const char *usage = "bot edge"; struct directory *dp; struct rt_db_internal intern; struct rt_bot_internal *botip; mat_t mat; char *last; size_t v1_i; size_t v2_i; size_t last_fi; size_t last_vi; size_t save_vi; size_t i; point_t new_pt; GED_CHECK_DATABASE_OPEN(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 ((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; } dp = db_lookup(gedp->ged_wdbp->dbip, last, LOOKUP_QUIET); if (dp == RT_DIR_NULL) { bu_vls_printf(gedp->ged_result_str, "%s: failed to find %s", argv[0], argv[1]); return GED_ERROR; } if (bu_sscanf(argv[2], "%zu %zu", &v1_i, &v2_i) != 2) { bu_vls_printf(gedp->ged_result_str, "%s: bad bot edge - %s", argv[0], argv[2]); return GED_ERROR; } if (wdb_import_from_path2(gedp->ged_result_str, &intern, last, gedp->ged_wdbp, mat) == GED_ERROR) { bu_vls_printf(gedp->ged_result_str, "%s: failed to find %s", argv[0], argv[1]); return 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, "Object is not a BOT"); rt_db_free_internal(&intern); return GED_ERROR; } botip = (struct rt_bot_internal *)intern.idb_ptr; last_fi = botip->num_faces; last_vi = botip->num_vertices; if (v1_i >= botip->num_vertices || v2_i >= botip->num_vertices) { bu_vls_printf(gedp->ged_result_str, "%s: bad bot edge - %s", argv[0], argv[2]); rt_db_free_internal(&intern); return GED_ERROR; } /* * Create the new point, modify all faces (should only be two) * that share the specified edge and hook in the two extra faces. */ /* First, create some space */ botip->num_vertices++; botip->num_faces += 2; botip->vertices = (fastf_t *)bu_realloc((void *)botip->vertices, botip->num_vertices*3*sizeof(fastf_t), "realloc bot vertices"); botip->faces = (int *)bu_realloc((void *)botip->faces, botip->num_faces*3*sizeof(int), "realloc bot faces"); /* Create the new point. We're using the average of the edge's points */ VADD2(new_pt, &botip->vertices[v1_i*3], &botip->vertices[v2_i*3]); VSCALE(new_pt, new_pt, 0.5); /* Add the new point to the last position in the list of vertices. */ VMOVE(&botip->vertices[last_vi*3], new_pt); /* Update faces associated with the specified edge */ for (i = 0; i < last_fi; ++i) { if (((size_t)botip->faces[i*3] == v1_i && (size_t)botip->faces[i*3+1] == v2_i) || ((size_t)botip->faces[i*3] == v2_i && (size_t)botip->faces[i*3+1] == v1_i)) { save_vi = botip->faces[i*3+1]; botip->faces[i*3+1] = last_vi; /* Initialize a new face */ botip->faces[last_fi*3] = last_vi; botip->faces[last_fi*3+1] = save_vi; botip->faces[last_fi*3+2] = botip->faces[i*3+2]; ++last_fi; } else if (((size_t)botip->faces[i*3] == v1_i && (size_t)botip->faces[i*3+2] == v2_i) || ((size_t)botip->faces[i*3] == v2_i && (size_t)botip->faces[i*3+2] == v1_i)) { save_vi = botip->faces[i*3]; botip->faces[i*3] = last_vi; /* Initialize a new face */ botip->faces[last_fi*3] = last_vi; botip->faces[last_fi*3+1] = save_vi; botip->faces[last_fi*3+2] = botip->faces[i*3+1]; ++last_fi; } else if (((size_t)botip->faces[i*3+1] == v1_i && (size_t)botip->faces[i*3+2] == v2_i) || ((size_t)botip->faces[i*3+1] == v2_i && (size_t)botip->faces[i*3+2] == v1_i)) { save_vi = botip->faces[i*3+2]; botip->faces[i*3+2] = last_vi; /* Initialize a new face */ botip->faces[last_fi*3] = botip->faces[i*3]; botip->faces[last_fi*3+1] = last_vi; botip->faces[last_fi*3+2] = save_vi; ++last_fi; } if (last_fi >= botip->num_faces) break; } GED_DB_PUT_INTERNAL(gedp, dp, &intern, &rt_uniresource, GED_ERROR); rt_db_free_internal(&intern); return GED_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_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; }
int ged_comb_std(struct ged *gedp, int argc, const char *argv[]) { char *comb_name; int ch; int region_flag = -1; struct directory *dp = RT_DIR_NULL; struct rt_db_internal intern; struct rt_comb_internal *comb = NULL; struct tokens tok_hd; short last_tok; int i; union tree *final_tree; static const char *usage = "[-cr] comb_name <boolean_expr>"; 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; } /* Parse options */ bu_optind = 1; /* re-init bu_getopt() */ while ((ch = bu_getopt(argc, (char * const *)argv, "cgr?")) != -1) { switch (ch) { case 'c': case 'g': region_flag = 0; break; case 'r': region_flag = 1; break; /* XXX How about -p and -v for FASTGEN? */ case '?': default: bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); return GED_OK; } } argc -= (bu_optind + 1); argv += bu_optind; comb_name = (char *)*argv++; if (argc == -1) { bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); return GED_OK; } if ((region_flag != -1) && (argc == 0)) { /* * Set/Reset the REGION flag of an existing combination */ GED_DB_LOOKUP(gedp, dp, comb_name, LOOKUP_NOISY, GED_ERROR & GED_QUIET); if (!(dp->d_flags & RT_DIR_COMB)) { bu_vls_printf(gedp->ged_result_str, "%s is not a combination\n", comb_name); return GED_ERROR; } GED_DB_GET_INTERNAL(gedp, &intern, dp, (fastf_t *)NULL, &rt_uniresource, GED_ERROR); comb = (struct rt_comb_internal *)intern.idb_ptr; RT_CK_COMB(comb); if (region_flag) { if (!comb->region_flag) { /* assign values from the defaults */ comb->region_id = gedp->ged_wdbp->wdb_item_default++; comb->aircode = gedp->ged_wdbp->wdb_air_default; comb->GIFTmater = gedp->ged_wdbp->wdb_mat_default; comb->los = gedp->ged_wdbp->wdb_los_default; } comb->region_flag = 1; } else comb->region_flag = 0; GED_DB_PUT_INTERNAL(gedp, dp, &intern, &rt_uniresource, GED_ERROR); return GED_OK; } /* * At this point, we know we have a Boolean expression. * If the combination already existed and region_flag is -1, * then leave its region_flag alone. * If the combination didn't exist yet, * then pretend region_flag was 0. * Otherwise, make sure to set its c_flags according to region_flag. */ GED_CHECK_EXISTS(gedp, comb_name, LOOKUP_QUIET, GED_ERROR); dp = RT_DIR_NULL; /* parse Boolean expression */ BU_LIST_INIT(&tok_hd.l); tok_hd.type = TOK_NULL; last_tok = TOK_LPAREN; for (i = 0; i < argc; i++) { char *ptr; ptr = (char *)argv[i]; while (*ptr) { while (*ptr == '(' || *ptr == ')') { switch (*ptr) { case '(': append_lparen(&tok_hd.l); last_tok = TOK_LPAREN; break; case ')': append_rparen(&tok_hd.l); last_tok = TOK_RPAREN; break; } ptr++; } if (*ptr == '\0') continue; if (last_tok == TOK_RPAREN) { /* next token MUST be an operator */ if (add_operator(gedp, &tok_hd.l, *ptr, &last_tok) == GED_ERROR) { free_tokens(&tok_hd.l); return GED_ERROR; } ptr++; } else if (last_tok == TOK_LPAREN) { /* next token MUST be an operand */ int name_len; name_len = add_operand(gedp, &tok_hd.l, ptr); if (name_len < 1) { free_tokens(&tok_hd.l); return GED_ERROR; } last_tok = TOK_TREE; ptr += name_len; } else if (last_tok == TOK_TREE) { /* must be an operator */ if (add_operator(gedp, &tok_hd.l, *ptr, &last_tok) == GED_ERROR) { free_tokens(&tok_hd.l); return GED_ERROR; } ptr++; } else if (last_tok == TOK_UNION || last_tok == TOK_INTER || last_tok == TOK_SUBTR) { /* must be an operand */ int name_len; name_len = add_operand(gedp, &tok_hd.l, ptr); if (name_len < 1) { free_tokens(&tok_hd.l); return GED_ERROR; } last_tok = TOK_TREE; ptr += name_len; } } } if (check_syntax(gedp, &tok_hd.l, comb_name, dp)) { free_tokens(&tok_hd.l); return GED_ERROR; } final_tree = eval_bool(&tok_hd.l); { int flags; flags = RT_DIR_COMB; BU_ALLOC(comb, struct rt_comb_internal); RT_COMB_INTERNAL_INIT(comb); comb->tree = final_tree; comb->region_id = -1; if (region_flag == (-1)) comb->region_flag = 0; else comb->region_flag = region_flag; if (comb->region_flag) { comb->region_flag = 1; comb->region_id = gedp->ged_wdbp->wdb_item_default++; comb->aircode = gedp->ged_wdbp->wdb_air_default; comb->los = gedp->ged_wdbp->wdb_los_default; comb->GIFTmater = gedp->ged_wdbp->wdb_mat_default; bu_vls_printf(gedp->ged_result_str, "Creating region with attrs: region_id=%d, ", comb->region_id); if (comb->aircode) bu_vls_printf(gedp->ged_result_str, "air=%d, ", comb->aircode); bu_vls_printf(gedp->ged_result_str, "los=%d, material_id=%d\n", comb->los, comb->GIFTmater); flags |= RT_DIR_REGION; } RT_DB_INTERNAL_INIT(&intern); intern.idb_major_type = DB5_MAJORTYPE_BRLCAD; intern.idb_type = ID_COMBINATION; intern.idb_meth = &OBJ[ID_COMBINATION]; intern.idb_ptr = (void *)comb; GED_DB_DIRADD(gedp, dp, comb_name, RT_DIR_PHONY_ADDR, 0, flags, (void *)&intern.idb_type, GED_ERROR); GED_DB_PUT_INTERNAL(gedp, dp, &intern, &rt_uniresource, GED_ERROR); } return GED_OK; }