/* * Write the nmg to a BRL-CAD style data base. */ int create_brlcad_db(struct rt_wdb *fpout, struct model *m, char *reg_name, char *grp_name) { char *rname, *sname; int empty_model; struct shell *s; struct nmgregion *r; rname = (char *)bu_malloc(sizeof(reg_name) + 3, "rname"); /* Region name. */ sname = (char *)bu_malloc(sizeof(reg_name) + 3, "sname"); /* Solid name. */ snprintf(sname, sizeof(reg_name) + 2, "s.%s", reg_name); empty_model = nmg_kill_zero_length_edgeuses(m); if (empty_model) { bu_log("Warning: skipping empty model."); return 0; } nmg_rebound(m, &tol); r = BU_LIST_FIRST(nmgregion, &m->r_hd); s = BU_LIST_FIRST(shell, &r->s_hd); mk_bot_from_nmg(fpout, sname, s); /* Make BOT object. */ snprintf(rname, sizeof(reg_name) + 2, "r.%s", reg_name); mk_comb1(fpout, rname, sname, 1); /* Put object in a region. */ if (grp_name) { mk_comb1(fpout, grp_name, rname, 1); /* Region in group. */ } return 0; }
int main(int argc, char **argv) { int c; int i; struct pshell *psh; struct pbar *pbp; struct wmember head; struct wmember all_head; char *nastran_file = "Converted from NASTRAN file (stdin)"; bu_setprogname(argv[0]); fpin = stdin; units = INCHES; /* FIXME: These need to be improved */ tol.magic = BN_TOL_MAGIC; tol.dist = 0.0005; tol.dist_sq = tol.dist * tol.dist; tol.perp = 1e-6; tol.para = 1 - tol.perp; while ((c=bu_getopt(argc, argv, "x:X:t:ni:o:mh?")) != -1) { switch (c) { case 'x': sscanf(bu_optarg, "%x", (unsigned int *)&RTG.debug); bu_printb("librt RT_G_DEBUG", RT_G_DEBUG, DEBUG_FORMAT); bu_log("\n"); break; case 'X': sscanf(bu_optarg, "%x", (unsigned int *)&RTG.NMG_debug); bu_printb("librt RTG.NMG_debug", RTG.NMG_debug, NMG_DEBUG_FORMAT); bu_log("\n"); break; case 't': /* calculational tolerance */ tol.dist = atof(bu_optarg); tol.dist_sq = tol.dist * tol.dist; break; case 'n': polysolids = 0; break; case 'm': units = MM; break; case 'i': fpin = fopen(bu_optarg, "rb"); if (fpin == (FILE *)NULL) { bu_log("Cannot open NASTRAN file (%s) for reading!\n", bu_optarg); bu_exit(1, Usage, argv[0]); } nastran_file = bu_optarg; break; case 'o': output_file = bu_optarg; break; default: bu_exit(1, Usage, argv[0]); } } fpout = wdb_fopen(output_file); if (fpout == NULL) { bu_log("Cannot open BRL-CAD file (%s) for writing!\n", output_file); bu_exit(1, Usage, argv[0]); } if (!fpin || !fpout) { bu_exit(1, Usage, argv[0]); } line = (char *)bu_malloc(MAX_LINE_SIZE, "line"); next_line = (char *)bu_malloc(MAX_LINE_SIZE, "next_line"); prev_line = (char *)bu_malloc(MAX_LINE_SIZE, "prev_line"); curr_rec = (char **)bu_calloc(NO_OF_FIELDS, sizeof(char *), "curr_rec"); for (i=0; i<NO_OF_FIELDS; i++) curr_rec[i] = (char *)bu_malloc(sizeof(char)*FIELD_LENGTH, "curr_rec[i]"); prev_rec = (char **)bu_calloc(NO_OF_FIELDS, sizeof(char *), "prev_rec"); for (i=0; i<NO_OF_FIELDS; i++) prev_rec[i] = (char *)bu_malloc(sizeof(char)*FIELD_LENGTH, "prev_rec[i]"); /* first pass, find start of NASTRAN "bulk data" */ start_off = (-1); bulk_data_start_line = 0; while (bu_fgets(line, MAX_LINE_SIZE, fpin)) { bulk_data_start_line++; if (bu_strncmp(line, "BEGIN BULK", 10)) continue; start_off = bu_ftell(fpin); break; } if (start_off < 0) { bu_log("Cannot find start of bulk data in NASTRAN file!\n"); bu_exit(1, Usage, argv[0]); } /* convert BULK data deck into something reasonable */ fptmp = bu_temp_file(NULL, 0); if (fptmp == NULL) { perror(argv[0]); bu_exit(1, "Cannot open temporary file\n"); } convert_input(); /* initialize some lists */ BU_LIST_INIT(&coord_head.l); BU_LIST_INIT(&pbar_head.l); BU_LIST_INIT(&pshell_head.l); BU_LIST_INIT(&all_head.l); nmg_model = (struct model *)NULL; /* count grid points */ bu_fseek(fptmp, 0, SEEK_SET); while (bu_fgets(line, MAX_LINE_SIZE, fptmp)) { if (!bu_strncmp(line, "GRID", 4)) grid_count++; } if (!grid_count) { bu_exit(1, "No geometry in this NASTRAN file!\n"); } /* get default values and properties */ bu_fseek(fptmp, 0, SEEK_SET); while (get_next_record(fptmp, 1, 0)) { if (!bu_strncmp(curr_rec[0], "BAROR", 5)) { /* get BAR defaults */ bar_def_pid = atoi(curr_rec[2]); } else if (!bu_strncmp(curr_rec[0], "PBAR", 4)) { struct pbar *pb; BU_ALLOC(pb, struct pbar); pb->pid = atoi(curr_rec[1]); pb->mid = atoi(curr_rec[2]); pb->area = atof(curr_rec[3]); BU_LIST_INIT(&pb->head.l); BU_LIST_INSERT(&pbar_head.l, &pb->l); } else if (!bu_strncmp(curr_rec[0], "PSHELL", 6)) { BU_ALLOC(psh, struct pshell); psh->s = (struct shell *)NULL; psh->pid = atoi(curr_rec[1]); psh->mid = atoi(curr_rec[2]); psh->thick = atof(curr_rec[3]); BU_LIST_INSERT(&pshell_head.l, &psh->l); pshell_count++; } } /* allocate storage for grid points */ g_pts = (struct grid_point *)bu_calloc(grid_count, sizeof(struct grid_point), "grid points"); /* get all grid points */ bu_fseek(fptmp, 0, SEEK_SET); while (get_next_record(fptmp, 1, 0)) { int gid; int cid; double tmp[3]; if (bu_strncmp(curr_rec[0], "GRID", 4)) continue; gid = atoi(curr_rec[1]); cid = atoi(curr_rec[2]); for (i=0; i<3; i++) { tmp[i] = atof(curr_rec[i+3]); } g_pts[grid_used].gid = gid; g_pts[grid_used].cid = cid; g_pts[grid_used].v = (struct vertex **)bu_calloc(pshell_count + 1, sizeof(struct vertex *), "g_pts vertex array"); VMOVE(g_pts[grid_used].pt, tmp); grid_used++; } /* find coordinate systems */ bu_fseek(fptmp, 0, SEEK_SET); while (get_next_record(fptmp, 1, 0)) { if (bu_strncmp(curr_rec[0], "CORD", 4)) continue; get_coord_sys(); } /* convert everything to BRL-CAD coordinate system */ i = 0; while (convert_all_cs() || convert_all_pts()) { i++; if (i > 10) { bu_exit(1, "Cannot convert to default coordinate system, check for circular definition\n"); } } mk_id(fpout, nastran_file); /* get elements */ bu_fseek(fptmp, 0, SEEK_SET); while (get_next_record(fptmp, 1, 0)) { if (!bu_strncmp(curr_rec[0], "CBAR", 4)) get_cbar(); else if (!bu_strncmp(curr_rec[0], "CROD", 4)) get_cbar(); else if (!bu_strncmp(curr_rec[0], "CTRIA3", 6)) get_ctria3(); else if (!bu_strncmp(curr_rec[0], "CQUAD4", 6)) get_cquad4(); } if (nmg_model) { nmg_rebound(nmg_model, &tol); if (polysolids) mk_bot_from_nmg(fpout, "pshell.0", nmg_shell); else mk_nmg(fpout, "pshell.0", nmg_model); } BU_LIST_INIT(&head.l); for (BU_LIST_FOR(psh, pshell, &pshell_head.l)) { struct model *m; char name[NAMESIZE+1]; if (!psh->s) continue; m = nmg_find_model(&psh->s->l.magic); nmg_rebound(m, &tol); nmg_fix_normals(psh->s, &tol); if (psh->thick > tol.dist) { nmg_model_face_fuse(m, &tol); nmg_hollow_shell(psh->s, psh->thick*conv[units], 1, &tol); } sprintf(name, "pshell.%d", psh->pid); if (polysolids) mk_bot_from_nmg(fpout, name, psh->s); else mk_nmg(fpout, name, m); mk_addmember(name, &head.l, NULL, WMOP_UNION); } if (BU_LIST_NON_EMPTY(&head.l)) { mk_lfcomb(fpout, "shells", &head, 0); mk_addmember("shells", &all_head.l, NULL, WMOP_UNION); } BU_LIST_INIT(&head.l); for (BU_LIST_FOR(pbp, pbar, &pbar_head.l)) { char name[NAMESIZE+1]; if (BU_LIST_IS_EMPTY(&pbp->head.l)) continue; sprintf(name, "pbar_group.%d", pbp->pid); mk_lfcomb(fpout, name, &pbp->head, 0); mk_addmember(name, &head.l, NULL, WMOP_UNION); } if (BU_LIST_NON_EMPTY(&head.l)) { mk_lfcomb(fpout, "pbars", &head, 0); mk_addmember("pbars", &all_head.l, NULL, WMOP_UNION); } if (BU_LIST_NON_EMPTY(&all_head.l)) { mk_lfcomb(fpout, "all", &all_head, 0); } wdb_close(fpout); return 0; }
int ged_shells(struct ged *gedp, int argc, const char *argv[]) { struct directory *old_dp, *new_dp; struct rt_db_internal old_intern, new_intern; struct model *m_tmp, *m; struct nmgregion *r_tmp, *r; struct shell *s_tmp, *s; int shell_count=0; struct bu_vls shell_name = BU_VLS_INIT_ZERO; long **trans_tbl; static const char *usage = "nmg_model"; GED_CHECK_DATABASE_OPEN(gedp, GED_ERROR); GED_CHECK_READ_ONLY(gedp, GED_ERROR); GED_CHECK_ARGC_GT_0(gedp, argc, GED_ERROR); /* initialize result */ bu_vls_trunc(gedp->ged_result_str, 0); /* must be wanting help */ if (argc == 1) { bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); return GED_HELP; } if (argc != 2) { bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); return GED_ERROR; } if ((old_dp = db_lookup(gedp->ged_wdbp->dbip, argv[1], LOOKUP_NOISY)) == RT_DIR_NULL) return GED_ERROR; if (rt_db_get_internal(&old_intern, old_dp, gedp->ged_wdbp->dbip, bn_mat_identity, &rt_uniresource) < 0) { bu_vls_printf(gedp->ged_result_str, "rt_db_get_internal() error\n"); return GED_ERROR; } if (old_intern.idb_type != ID_NMG) { bu_vls_printf(gedp->ged_result_str, "Object is not an NMG!!!\n"); return GED_ERROR; } m = (struct model *)old_intern.idb_ptr; NMG_CK_MODEL(m); for (BU_LIST_FOR(r, nmgregion, &m->r_hd)) { for (BU_LIST_FOR(s, shell, &r->s_hd)) { s_tmp = nmg_dup_shell(s, &trans_tbl, &gedp->ged_wdbp->wdb_tol); bu_free((void *)trans_tbl, "trans_tbl"); m_tmp = nmg_mmr(); r_tmp = BU_LIST_FIRST(nmgregion, &m_tmp->r_hd); BU_LIST_DEQUEUE(&s_tmp->l); BU_LIST_APPEND(&r_tmp->s_hd, &s_tmp->l); s_tmp->r_p = r_tmp; nmg_m_reindex(m_tmp, 0); nmg_m_reindex(m, 0); bu_vls_printf(&shell_name, "shell.%d", shell_count); while (db_lookup(gedp->ged_wdbp->dbip, bu_vls_addr(&shell_name), 0) != RT_DIR_NULL) { bu_vls_trunc(&shell_name, 0); shell_count++; bu_vls_printf(&shell_name, "shell.%d", shell_count); } /* Export NMG as a new solid */ RT_DB_INTERNAL_INIT(&new_intern); new_intern.idb_major_type = DB5_MAJORTYPE_BRLCAD; new_intern.idb_type = ID_NMG; new_intern.idb_meth = &OBJ[ID_NMG]; new_intern.idb_ptr = (void *)m_tmp; new_dp=db_diradd(gedp->ged_wdbp->dbip, bu_vls_addr(&shell_name), RT_DIR_PHONY_ADDR, 0, RT_DIR_SOLID, (void *)&new_intern.idb_type); if (new_dp == RT_DIR_NULL) { bu_vls_printf(gedp->ged_result_str, "An error has occurred while adding a new object to the database.\n"); return GED_ERROR; } /* make sure the geometry/bounding boxes are up to date */ nmg_rebound(m_tmp, &gedp->ged_wdbp->wdb_tol); if (rt_db_put_internal(new_dp, gedp->ged_wdbp->dbip, &new_intern, &rt_uniresource) < 0) { /* Free memory */ nmg_km(m_tmp); bu_vls_printf(gedp->ged_result_str, "rt_db_put_internal() failure\n"); return GED_ERROR; } /* Internal representation has been freed by rt_db_put_internal */ new_intern.idb_ptr = (void *)NULL; } } bu_vls_free(&shell_name); return GED_OK; }