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_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_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_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_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_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_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_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_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; }