extern "C" void rt_ehy_brep(ON_Brep **b, const struct rt_db_internal *ip, const struct bn_tol *) { struct rt_ehy_internal *eip; RT_CK_DB_INTERNAL(ip); eip = (struct rt_ehy_internal *)ip->idb_ptr; RT_EHY_CK_MAGIC(eip); // Check the parameters if (!NEAR_ZERO(VDOT(eip->ehy_Au, eip->ehy_H), RT_DOT_TOL)) { bu_log("rt_ehy_brep: Au and H are not perpendicular!\n"); return; } if (!NEAR_EQUAL(MAGNITUDE(eip->ehy_Au), 1.0, RT_LEN_TOL)) { bu_log("rt_ehy_brep: Au not a unit vector!\n"); return; } if (MAGNITUDE(eip->ehy_H) < RT_LEN_TOL || eip->ehy_c < RT_LEN_TOL || eip->ehy_r1 < RT_LEN_TOL || eip->ehy_r2 < RT_LEN_TOL) { bu_log("rt_ehy_brep: not all dimensions positive!\n"); return; } if (eip->ehy_r2 > eip->ehy_r1) { bu_log("rt_ehy_brep: semi-minor axis cannot be longer than semi-major axis!\n"); return; } point_t p1_origin; ON_3dPoint plane1_origin, plane2_origin; ON_3dVector plane_x_dir, plane_y_dir; // First, find plane in 3 space corresponding to the bottom face of the EPA. vect_t x_dir, y_dir; VMOVE(x_dir, eip->ehy_Au); VCROSS(y_dir, eip->ehy_Au, eip->ehy_H); VUNITIZE(y_dir); VMOVE(p1_origin, eip->ehy_V); plane1_origin = ON_3dPoint(p1_origin); plane_x_dir = ON_3dVector(x_dir); plane_y_dir = ON_3dVector(y_dir); const ON_Plane ehy_bottom_plane(plane1_origin, plane_x_dir, plane_y_dir); // Next, create an ellipse in the plane corresponding to the edge of the ehy. ON_Ellipse ellipse1(ehy_bottom_plane, eip->ehy_r1, eip->ehy_r2); ON_NurbsCurve* ellcurve1 = ON_NurbsCurve::New(); ellipse1.GetNurbForm((*ellcurve1)); ellcurve1->SetDomain(0.0, 1.0); // Generate the bottom cap ON_SimpleArray<ON_Curve*> boundary; boundary.Append(ON_Curve::Cast(ellcurve1)); ON_PlaneSurface* bp = new ON_PlaneSurface(); bp->m_plane = ehy_bottom_plane; bp->SetDomain(0, -100.0, 100.0); bp->SetDomain(1, -100.0, 100.0); bp->SetExtents(0, bp->Domain(0)); bp->SetExtents(1, bp->Domain(1)); (*b)->m_S.Append(bp); const int bsi = (*b)->m_S.Count() - 1; ON_BrepFace& bface = (*b)->NewFace(bsi); (*b)->NewPlanarFaceLoop(bface.m_face_index, ON_BrepLoop::outer, boundary, true); const ON_BrepLoop* bloop = (*b)->m_L.Last(); bp->SetDomain(0, bloop->m_pbox.m_min.x, bloop->m_pbox.m_max.x); bp->SetDomain(1, bloop->m_pbox.m_min.y, bloop->m_pbox.m_max.y); bp->SetExtents(0, bp->Domain(0)); bp->SetExtents(1, bp->Domain(1)); (*b)->SetTrimIsoFlags(bface); delete ellcurve1; // Now, the hard part. Need an elliptical hyperbolic NURBS surface // First step is to create a nurbs curve. double intercept_calc = (eip->ehy_c)*(eip->ehy_c)/(MAGNITUDE(eip->ehy_H) + eip->ehy_c); double intercept_dist = MAGNITUDE(eip->ehy_H) + eip->ehy_c - intercept_calc; double intercept_length = intercept_dist - MAGNITUDE(eip->ehy_H); double MX = MAGNITUDE(eip->ehy_H); double MP = MX + intercept_length; double w = (MX/MP)/(1-MX/MP); point_t ep1, ep2, ep3; VSET(ep1, -eip->ehy_r1, 0, 0); VSET(ep2, 0, 0, w*intercept_dist); VSET(ep3, eip->ehy_r1, 0, 0); ON_3dPoint onp1 = ON_3dPoint(ep1); ON_3dPoint onp2 = ON_3dPoint(ep2); ON_3dPoint onp3 = ON_3dPoint(ep3); ON_3dPointArray cpts(3); cpts.Append(onp1); cpts.Append(onp2); cpts.Append(onp3); ON_BezierCurve *bcurve = new ON_BezierCurve(cpts); bcurve->MakeRational(); bcurve->SetWeight(1, w); ON_NurbsCurve* tnurbscurve = ON_NurbsCurve::New(); bcurve->GetNurbForm(*tnurbscurve); ON_NurbsCurve* hypbnurbscurve = ON_NurbsCurve::New(); const ON_Interval subinterval = ON_Interval(0, 0.5); tnurbscurve->GetNurbForm(*hypbnurbscurve, 0.0, &subinterval); // Next, rotate that curve around the height vector. point_t revpoint1, revpoint2; VSET(revpoint1, 0, 0, 0); VSET(revpoint2, 0, 0, MX); ON_3dPoint rpnt1 = ON_3dPoint(revpoint1); ON_3dPoint rpnt2 = ON_3dPoint(revpoint2); ON_Line revaxis = ON_Line(rpnt1, rpnt2); ON_RevSurface* hyp_surf = ON_RevSurface::New(); hyp_surf->m_curve = hypbnurbscurve; hyp_surf->m_axis = revaxis; hyp_surf->m_angle = ON_Interval(0, 2*ON_PI); // Get the NURBS form of the surface ON_NurbsSurface *ehycurvedsurf = ON_NurbsSurface::New(); hyp_surf->GetNurbForm(*ehycurvedsurf, 0.0); delete hyp_surf; delete tnurbscurve; delete bcurve; // Transformations for (int i = 0; i < ehycurvedsurf->CVCount(0); i++) { for (int j = 0; j < ehycurvedsurf->CVCount(1); j++) { point_t cvpt; ON_4dPoint ctrlpt; ehycurvedsurf->GetCV(i, j, ctrlpt); // Scale the control points of the // resulting surface to map to the shorter axis. VSET(cvpt, ctrlpt.x, ctrlpt.y * eip->ehy_r2/eip->ehy_r1, ctrlpt.z); // Rotate according to the directions of Au and H vect_t Hu; mat_t R; point_t new_cvpt; VSCALE(Hu, eip->ehy_H, 1/MAGNITUDE(eip->ehy_H)); MAT_IDN(R); VMOVE(&R[0], eip->ehy_Au); VMOVE(&R[4], y_dir); VMOVE(&R[8], Hu); VEC3X3MAT(new_cvpt, cvpt, R); VMOVE(cvpt, new_cvpt); // Translate according to V vect_t scale_v; VSCALE(scale_v, eip->ehy_V, ctrlpt.w); VADD2(cvpt, cvpt, scale_v); ON_4dPoint newpt = ON_4dPoint(cvpt[0], cvpt[1], cvpt[2], ctrlpt.w); ehycurvedsurf->SetCV(i, j, newpt); } } (*b)->m_S.Append(ehycurvedsurf); int surfindex = (*b)->m_S.Count(); ON_BrepFace& face = (*b)->NewFace(surfindex - 1); (*b)->FlipFace(face); int faceindex = (*b)->m_F.Count(); (*b)->NewOuterLoop(faceindex-1); }
/** * callback when a HELO message packet is received. * * We should not encounter this packet specifically since we listened * for it before beginning processing of packets as part of a simple * handshake setup. */ void server_helo(struct pkg_conn *UNUSED(connection), char *buf) { bu_log("Unexpected HELO encountered\n"); free(buf); }
/** * callback when a CIAO message packet is received */ void server_ciao(struct pkg_conn *UNUSED(connection), char *buf) { bu_log("CIAO encountered\n"); free(buf); }
/** * Make all the edgeuses around eu2's edge to refer to eu1's edge, * taking care to organize them into the proper angular orientation, * so that the attached faces are correctly arranged radially * around the edge. * * This depends on both edges being part of face loops, * with vertex and face geometry already associated. * * The two edgeuses being joined might well be from separate shells, * so the issue of preserving (simple) faceuse orientation parity * (SAME, OPPOSITE, OPPOSITE, SAME, ...) * can't be used here -- that only applies to faceuses from the same shell. * * Some of the edgeuses around both edges may be wires. * * Call to nmg_check_radial at end has been deleted. * Note that after two radial EU's have been joined * a third cannot be joined to them without creating * unclosed space that nmg_check_radial will find. */ void nmg_radial_join_eu(struct edgeuse *eu1, struct edgeuse *eu2, const struct bn_tol *tol) { NMG_CK_EDGEUSE(eu1); NMG_CK_EDGEUSE(eu1->radial_p); NMG_CK_EDGEUSE(eu1->eumate_p); NMG_CK_EDGEUSE(eu2); NMG_CK_EDGEUSE(eu2->radial_p); NMG_CK_EDGEUSE(eu2->eumate_p); BN_CK_TOL(tol); if (eu1->e_p == eu2->e_p) return; if (!NMG_ARE_EUS_ADJACENT(eu1, eu2)) bu_bomb("nmg_radial_join_eu() edgeuses don't share vertices.\n"); if (eu1->vu_p->v_p == eu1->eumate_p->vu_p->v_p) bu_bomb("nmg_radial_join_eu(): 0 length edge (topology)\n"); if (bn_pt3_pt3_equal(eu1->vu_p->v_p->vg_p->coord, eu1->eumate_p->vu_p->v_p->vg_p->coord, tol)) { bu_log("vertices should have been fused:\n"); bu_log("\tvertex %p (%.12f %.12f %.12f)\n", (void *)eu1->vu_p->v_p, V3ARGS(eu1->vu_p->v_p->vg_p->coord)); bu_log("\tvertex %p (%.12f %.12f %.12f)\n", (void *)eu1->eumate_p->vu_p->v_p, V3ARGS(eu1->eumate_p->vu_p->v_p->vg_p->coord)); bu_bomb("nmg_radial_join_eu(): 0 length edge (geometry)\n"); } #if 1 nmg_radial_join_eu_NEW(eu1, eu2, tol); return; #else /* Ensure faces are of same orientation, if both eu's have faces */ fu1 = nmg_find_fu_of_eu(eu1); fu2 = nmg_find_fu_of_eu(eu2); if (fu1 && fu2) { if (fu1->orientation != fu2->orientation) { eu2 = eu2->eumate_p; fu2 = nmg_find_fu_of_eu(eu2); if (fu1->orientation != fu2->orientation) bu_bomb("nmg_radial_join_eu(): Cannot find matching orientations for faceuses\n"); } } /* XXX This angle-based algorithm can't handle snurb faces! */ if (fu1 && fu1->f_p->g.magic_p && *fu1->f_p->g.magic_p == NMG_FACE_G_SNURB_MAGIC) return; if (fu2 && fu2->f_p->g.magic_p && *fu2->f_p->g.magic_p == NMG_FACE_G_SNURB_MAGIC) return; /* Construct local coordinate system for this edge, * so all angles can be measured relative to a common reference. */ nmg_eu_2vecs_perp(xvec, yvec, zvec, original_eu1, tol); if (RTG.NMG_debug & DEBUG_MESH_EU) { bu_log("nmg_radial_join_eu(eu1=%p, eu2=%p) e1=%p, e2=%p\n", (void *)eu1, (void *)eu2, (void *)eu1->e_p, (void *)eu2->e_p); nmg_euprint("\tJoining", eu1); nmg_euprint("\t to", eu2); bu_log("Faces around eu1:\n"); nmg_pr_fu_around_eu_vecs(eu1, xvec, yvec, zvec, tol); bu_log("Faces around eu2:\n"); nmg_pr_fu_around_eu_vecs(eu2, xvec, yvec, zvec, tol); } best_eg = nmg_pick_best_edge_g(eu1, eu2, tol); for (iteration1=0; eu2 && iteration1 < 10000; iteration1++) { int code = 0; struct edgeuse *first_eu1 = eu1; int wire_skip = 0; /* Resume where we left off from last eu2 insertion */ /* find a place to insert eu2 around eu1's edge */ for (iteration2=0; iteration2 < 10000; iteration2++) { struct faceuse *fur; abs1 = abs2 = absr = -M_2PI; eur = eu1->radial_p; NMG_CK_EDGEUSE(eur); fu2 = nmg_find_fu_of_eu(eu2); if (fu2 == (struct faceuse *)NULL) { /* eu2 is a wire, it can go anywhere */ bu_log("eu2=%p is a wire, insert after eu1=%p\n", (void *)eu2, (void *)eu1); goto insert; } fu1 = nmg_find_fu_of_eu(eu1); if (fu1 == (struct faceuse *)NULL) { /* eu1 is a wire, skip on to real face eu */ bu_log("eu1=%p is a wire, skipping on\n", (void *)eu1); wire_skip++; goto cont; } fur = nmg_find_fu_of_eu(eur); while (fur == (struct faceuse *)NULL) { /* eur is wire, advance eur */ bu_log("eur=%p is a wire, advancing to non-wire eur\n", (void *)eur); eur = eur->eumate_p->radial_p; wire_skip++; if (eur == eu1->eumate_p) { bu_log("went all the way around\n"); /* Went all the way around */ goto insert; } fur = nmg_find_fu_of_eu(eur); } NMG_CK_FACEUSE(fu1); NMG_CK_FACEUSE(fu2); NMG_CK_FACEUSE(fur); /* * Can't just check for shared fg here, * the angle changes by +/- 180 degrees, * depending on which side of the eu the loop is on * along this edge. */ abs1 = nmg_measure_fu_angle(eu1, xvec, yvec, zvec); abs2 = nmg_measure_fu_angle(eu2, xvec, yvec, zvec); absr = nmg_measure_fu_angle(eur, xvec, yvec, zvec); if (RTG.NMG_debug & DEBUG_MESH_EU) { bu_log(" abs1=%g, abs2=%g, absr=%g\n", abs1*RAD2DEG, abs2*RAD2DEG, absr*RAD2DEG); } /* If abs1 == absr, warn about unfused faces, and skip. */ if (NEAR_EQUAL(abs1, absr, 1.0e-8)) { if (fu1->f_p->g.plane_p == fur->f_p->g.plane_p) { /* abs1 == absr, faces are fused, don't insert here. */ if (RTG.NMG_debug & DEBUG_MESH_EU) { bu_log("fu1 and fur share face geometry %p (flip1=%d, flip2=%d), skip\n", (void *)fu1->f_p->g.plane_p, fu1->f_p->flip, fur->f_p->flip); } goto cont; } bu_log("nmg_radial_join_eu: WARNING 2 faces should have been fused, may be ambiguous.\n abs1=%e, absr=%e, asb2=%e\n", abs1*RAD2DEG, absr*RAD2DEG, abs2*RAD2DEG); bu_log(" fu1=%p, f1=%p, f1->flip=%d, fg1=%p\n", (void *)fu1, (void *)fu1->f_p, fu1->f_p->flip, (void *)fu1->f_p->g.plane_p); bu_log(" fu2=%p, f2=%p, f2->flip=%d, fg2=%p\n", (void *)fu2, (void *)fu2->f_p, fu2->f_p->flip, (void *)fu2->f_p->g.plane_p); bu_log(" fur=%p, fr=%p, fr->flip=%d, fgr=%p\n", (void *)fur, (void *)fur->f_p, fur->f_p->flip, (void *)fur->f_p->g.plane_p); PLPRINT(" fu1", fu1->f_p->g.plane_p->N); PLPRINT(" fu2", fu2->f_p->g.plane_p->N); PLPRINT(" fur", fur->f_p->g.plane_p->N); { int debug = RTG.NMG_debug; if (nmg_two_face_fuse(fu1->f_p, fur->f_p, tol) == 0) bu_bomb("faces didn't fuse?\n"); RTG.NMG_debug = debug; } bu_log(" nmg_radial_join_eu() skipping this eu\n"); goto cont; } /* * If abs1 < abs2 < absr * (taking into account 360 wrap), * then insert face here. * Special handling if abs1==abs2 or abs2==absr. */ code = nmg_is_angle_in_wedge(abs1, absr, abs2); if (RTG.NMG_debug & DEBUG_MESH_EU) bu_log(" code=%d %s\n", code, (code!=0)?"INSERT_HERE":"skip"); if (code > 0) break; if (code == -1) { /* absr == abs2 */ break; } if (code <= -2) { /* abs1 == abs2 */ break; } cont: /* If eu1 is only one pair of edgeuses, done */ if (eu1 == eur->eumate_p) break; eu1 = eur->eumate_p; if (eu1 == first_eu1) { /* If all eu's were wires, here is fine */ if (wire_skip >= iteration2) break; /* Nope, something bad happened */ bu_bomb("nmg_radial_join_eu(): went full circle, no face insertion point.\n"); break; } } if (iteration2 >= 10000) { bu_bomb("nmg_radial_join_eu: infinite loop (2)\n"); } /* find the next use of the edge eu2 is on. If eu2 and its * mate are the last uses of the edge, there will be no next * edgeuse to move. (Loop termination condition). */ insert: nexteu = eu2->radial_p; if (nexteu == eu2->eumate_p) nexteu = (struct edgeuse *)NULL; /* because faces are always created with counter-clockwise * exterior loops and clockwise interior loops, * radial edgeuses IN THE SAME SHELL will never point in * the same direction or share the same vertex. We thus make * sure that eu2 is an edgeuse which might be radial to eu1 * XXX Need to look back for last eu IN THE SHELL OF eu2. * XXX Even this isn't good enough, as we may be inserting * XXX something new _after_ that last starting point. */ eus = eu1; while (nmg_find_s_of_eu(eus) != nmg_find_s_of_eu(eu2)) { eus = eus->eumate_p->radial_p; if (eus == eu1) break; /* full circle */ } if (eu2->vu_p->v_p == eus->vu_p->v_p) eu2 = eu2->eumate_p; if (RTG.NMG_debug & DEBUG_MESH_EU) { bu_log(" Inserting. code=%d\n", code); bu_log("joining eu1=%p eu2=%p with abs1=%g, absr=%g\n", (void *)eu1, (void *)eu2, abs1*RAD2DEG, absr*RAD2DEG); } /* * Make eu2 radial to eu1. * This should insert eu2 between eu1 and eu1->radial_p * (which may be less far around than eur, but that's OK). * This does NOT change the edge geometry pointer. */ nmg_je(eu1, eu2); if (RTG.NMG_debug & DEBUG_MESH_EU) { bu_log("After nmg_je(), faces around original_eu1 are:\n"); nmg_pr_fu_around_eu_vecs(original_eu1, xvec, yvec, zvec, tol); } /* Proceed to the next source edgeuse */ eu2 = nexteu; } if (iteration1 >= 10000) bu_bomb("nmg_radial_join_eu: infinite loop (1)\n"); NMG_CK_EDGEUSE(original_eu1); /* * Make another pass, ensuring that all edgeuses are using the * "best_eg" line. */ eu1 = original_eu1; for (;;) { if (eu1->g.lseg_p != best_eg) { nmg_use_edge_g(eu1, &best_eg->l.magic); } eu1 = eu1->eumate_p->radial_p; if (eu1 == original_eu1) break; } if (RTG.NMG_debug & DEBUG_MESH_EU) bu_log("nmg_radial_join_eu: END\n"); #endif }
int main(int argc, char *argv[]) { int verbose = 0; int ncpu = 1; /* Number of processors */ char *output_file = NULL; /* output filename */ struct db_i *dbip; struct model *the_model; struct rt_tess_tol ttol; /* tessellation tolerance in mm */ struct db_tree_state tree_state; /* includes tol & model */ int i, use_mc = 0, use_bottess = 0; struct egg_conv_data conv_data; struct gcv_region_end_data gcvwriter = {nmg_to_egg, NULL}; gcvwriter.client_data = (void *)&conv_data; bu_setprogname(argv[0]); bu_setlinebuf(stderr); tree_state = rt_initial_tree_state; /* struct copy */ tree_state.ts_tol = &conv_data.tol; tree_state.ts_ttol = &ttol; tree_state.ts_m = &the_model; /* Set up tessellation tolerance defaults */ ttol.magic = RT_TESS_TOL_MAGIC; /* Defaults, updated by command line options. */ ttol.abs = 0.0; ttol.rel = 0.01; ttol.norm = 0.0; /* Set up calculation tolerance defaults */ /* FIXME: These need to be improved */ conv_data.tol.magic = BN_TOL_MAGIC; conv_data.tol.dist = BN_TOL_DIST; conv_data.tol.dist_sq = conv_data.tol.dist * conv_data.tol.dist; conv_data.tol.perp = 1e-6; conv_data.tol.para = 1 - conv_data.tol.perp; conv_data.tot_polygons = 0; /* make empty NMG model */ the_model = nmg_mm(); BU_LIST_INIT(&RTG.rtg_vlfree); /* for vlist macros */ /* Get command line arguments. */ while ((i = bu_getopt(argc, argv, "a:89n:o:r:vx:D:P:X:h?")) != -1) { switch (i) { case 'a': /* Absolute tolerance. */ ttol.abs = atof(bu_optarg); ttol.rel = 0.0; break; case 'n': /* Surface normal tolerance. */ ttol.norm = atof(bu_optarg); ttol.rel = 0.0; break; case 'o': /* Output file name. */ output_file = bu_optarg; break; case 'r': /* Relative tolerance. */ ttol.rel = atof(bu_optarg); break; case 'v': verbose++; break; case 'P': ncpu = atoi(bu_optarg); break; case 'x': sscanf(bu_optarg, "%x", (unsigned int *)&RTG.debug); break; case 'D': conv_data.tol.dist = atof(bu_optarg); conv_data.tol.dist_sq = conv_data.tol.dist * conv_data.tol.dist; rt_pr_tol(&conv_data.tol); break; case 'X': sscanf(bu_optarg, "%x", (unsigned int *)&RTG.NMG_debug); break; case '8': use_mc = 1; break; case '9': use_bottess = 1; break; default: usage(argv[0]); } } if (bu_optind+1 >= argc) usage(argv[0]); conv_data.fp = stdout; if (output_file) { if ((conv_data.fp=fopen(output_file, "wb+")) == NULL) { perror(argv[0]); bu_exit(1, "Cannot open ASCII output file (%s) for writing\n", output_file); } } /* Open brl-cad database */ argc -= bu_optind; argv += bu_optind; if (argc < 2 || argv[0] == NULL || argv[1] == NULL) usage(argv[0]); gcvwriter.write_region = nmg_to_egg; if ((dbip = db_open(argv[0], DB_OPEN_READONLY)) == DBI_NULL) { perror(argv[0]); bu_exit(1, "Unable to open geometry database file (%s)\n", argv[0]); } if (db_dirbuild(dbip)) { bu_exit(1, "ERROR: db_dirbuild failed\n"); } BN_CK_TOL(tree_state.ts_tol); RT_CK_TESS_TOL(tree_state.ts_ttol); if (verbose) { bu_log("Model: %s\n", argv[0]); bu_log("Objects:"); for (i=1; i<argc; i++) bu_log(" %s", argv[i]); bu_log("\nTessellation tolerances:\n\tabs = %g mm\n\trel = %g\n\tnorm = %g\n", tree_state.ts_ttol->abs, tree_state.ts_ttol->rel, tree_state.ts_ttol->norm); bu_log("Calculational tolerances:\n\tdist = %g mm perp = %g\n", tree_state.ts_tol->dist, tree_state.ts_tol->perp); } /* print the egg header stuff, including the command line to execute it */ fprintf(conv_data.fp, "<CoordinateSystem> { Z-Up }\n\n"); fprintf(conv_data.fp, "<Comment> {\n \"%s", *argv); for (i=1; i<argc; i++) fprintf(conv_data.fp, " %s", argv[i]); fprintf(conv_data.fp, "\"\n}\n"); /* Walk indicated tree(s). Each region will be output separately */ while (--argc) { fprintf(conv_data.fp, "<Group> %s {\n", *(argv+1)); (void) db_walk_tree(dbip, /* db_i */ 1, /* argc */ (const char **)(++argv), /* argv */ ncpu, /* ncpu */ &tree_state, /* state */ NULL, /* start func */ use_mc?gcv_region_end_mc:use_bottess?gcv_bottess_region_end:gcv_region_end, /* end func */ use_mc?NULL:nmg_booltree_leaf_tess, /* leaf func */ (void *)&gcvwriter); /* client_data */ fprintf(conv_data.fp, "}\n"); } bu_log("%ld triangles written\n", conv_data.tot_polygons); if (output_file) fclose(conv_data.fp); /* Release dynamic storage */ nmg_km(the_model); rt_vlist_cleanup(); db_close(dbip); return 0; }
int main(int argc, char *argv[]) { size_t i; int ret; int c; double percent; char copy_buffer[CP_BUF_SIZE] = {0}; struct directory *dp; bu_setprogname(argv[0]); bu_setlinebuf(stderr); bu_log("%s", brlcad_ident("BRL-CAD to IGES Translator")); bu_log("Please direct bug reports to <*****@*****.**>\n\n"); tree_state = rt_initial_tree_state; /* struct copy */ tree_state.ts_tol = &tol; tree_state.ts_ttol = &ttol; tree_state.ts_m = &the_model; ttol.magic = RT_TESS_TOL_MAGIC; /* Defaults, updated by command line options. */ ttol.abs = 0.0; ttol.rel = 0.01; ttol.norm = 0.0; /* 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; the_model = nmg_mm(); BU_LIST_INIT(&RTG.rtg_vlfree); /* for vlist macros */ rt_init_resource(&rt_uniresource, 0, NULL); prog_name = argv[0]; /* Get command line arguments. */ while ((c = bu_getopt(argc, argv, "ftsmd:a:n:o:p:r:vx:P:X:")) != -1) { switch (c) { case 'f': /* Select facetized output */ mode = FACET_MODE; multi_file = 0; break; case 't': mode = TRIMMED_SURF_MODE; multi_file = 0; break; case 'm': /* multi-file mode */ multi_file = 1; mode = TRIMMED_SURF_MODE; break; case 's': /* Select NURB output */ do_nurbs = 1; break; case 'v': verbose++; break; case 'a': /* Absolute tolerance. */ ttol.abs = atof(bu_optarg); break; case 'r': /* Relative tolerance. */ ttol.rel = atof(bu_optarg); break; case 'n': /* Surface normal tolerance. */ ttol.norm = atof(bu_optarg); break; case 'd': /* distance tolerance */ tol.dist = atof(bu_optarg); tol.dist_sq = tol.dist * tol.dist; break; case 'x': sscanf(bu_optarg, "%x", (unsigned int *)&RTG.debug); break; case 'X': sscanf(bu_optarg, "%x", (unsigned int *)&RTG.NMG_debug); NMG_debug = RTG.NMG_debug; break; case 'o': /* Output file name. */ output_file = bu_optarg; break; case 'P': ncpu = atoi(bu_optarg); break; default: usage(argv[0]); break; } } if (bu_optind+1 >= argc) { usage(argv[0]); } /* Open BRL-CAD database */ argc -= bu_optind; argv += bu_optind; db_name = argv[0]; if ((DBIP = db_open(db_name, DB_OPEN_READONLY)) == DBI_NULL) { perror("g-iges"); bu_exit(1, "ERROR: unable to open geometry database file (%s)\n", db_name); } /* Scan the database */ if (db_dirbuild(DBIP)) { bu_exit(1, "db_dirbuild failed\n"); } if (!multi_file) { /* let the IGES routines know the selected tolerances and the database pointer */ iges_init(&tol, &ttol, verbose, DBIP); /* Open the output file */ if (output_file == NULL) fp_dir = stdout; else { if ((fp_dir = fopen(output_file, "wb")) == NULL) { perror(output_file); bu_exit(1, "Cannot open output file: %s\n", output_file); } } /* Open the temporary file for the parameter section */ if ((fp_param = bu_temp_file(NULL, 0)) == NULL) { perror("g-iges"); bu_exit(1, "Cannot open temporary file\n"); } /* Write start and global sections of the IGES file */ w_start_global(fp_dir, fp_param, argv[0], prog_name, output_file, __DATE__, brlcad_version()); } else { if (!bu_file_directory(output_file)) { bu_exit(1, "-o option must provide a directory, %s is not a directory\n", output_file); } } /* Count object references */ /* for (i = 1; i < argc; i++) { dp = db_lookup(DBIP, argv[i], 1); db_functree(DBIP, dp, count_refs, 0, NULL); } */ /* tree tops must have independent status, so we need to remember them */ independent = (argv+1); no_of_indeps = (size_t)argc-1; if (mode == FACET_MODE) { /* Walk indicated tree(s). Each region will be output * as a single manifold solid BREP object */ ret = db_walk_tree(DBIP, argc-1, (const char **)(argv+1), ncpu, &tree_state, 0, /* take all regions */ do_nmg_region_end, nmg_booltree_leaf_tess, (void *)NULL); /* in librt/nmg_bool.c */ if (ret) bu_exit(1, "g-iges: Could not facetize anything!"); if (!multi_file) { /* Now walk the same trees again, but only output groups */ for (i = 1; i < (size_t)argc; i++) { char *ptr; ptr = strrchr(argv[i], '/'); if (ptr != NULL) { ptr++; } else { ptr = argv[i]; } dp = db_lookup(DBIP, ptr, 1); if (!dp) { bu_log("WARNING: Unable to locate %s in %s\n, skipping\n", ptr, db_name); continue; } db_functree(DBIP, dp, csg_comb_func, 0, &rt_uniresource, NULL); } } } else if (mode == CSG_MODE) { /* Walk indicated tree(s). Each combination and solid will be output * as a CSG object, unless there is no IGES equivalent (then the * solid will be tessellated and output as a BREP object) */ for (i = 1; i < (size_t)argc; i++) { dp = db_lookup(DBIP, argv[i], 1); if (!dp) { bu_log("WARNING: Unable to locate %s in %s\n, skipping\n", argv[i], db_name); continue; } db_functree(DBIP, dp, csg_comb_func, csg_leaf_func, &rt_uniresource, NULL); } } else if (mode == TRIMMED_SURF_MODE) { /* Walk the indicated tree(s). Each region is output as a collection * of trimmed NURBS */ ret = db_walk_tree(DBIP, argc-1, (const char **)(argv+1), ncpu, &tree_state, 0, /* take all regions */ do_nmg_region_end, nmg_booltree_leaf_tess, (void *)NULL); /* in librt/nmg_bool.c */ if (ret) bu_exit(1, "g-iges: Could not facetize anything!"); } if (!multi_file) { /* Copy the parameter section from the temporary file to the output file */ if ((bu_fseek(fp_param, 0, 0))) { perror("g-iges"); bu_exit(1, "Cannot seek to start of temporary file\n"); } while ((i = fread(copy_buffer, 1, CP_BUF_SIZE, fp_param))) if (fwrite(copy_buffer, 1, i, fp_dir) != i) { perror("g-iges"); bu_exit(1, "Error in copying parameter data to %s\n", output_file); } /* Write the terminate section */ w_terminate(fp_dir); } /* Print some statistics */ Print_stats(stdout); /* report on the success rate for facetizing regions */ if (mode == FACET_MODE || mode == TRIMMED_SURF_MODE) { percent = 0; if (regions_tried>0) percent = ((double)regions_done * 100) / regions_tried; bu_log("Tried %d regions, %d converted to nmg's successfully. %g%%\n", regions_tried, regions_done, percent); } /* re-iterate warnings */ if (scale_error || solid_error || comb_error) bu_log("WARNING: the IGES file produced has errors:\n"); if (scale_error) bu_log("\t%d scaled objects found, written to IGES file without being scaled\n", scale_error); if (solid_error) bu_log("\t%d solids were not converted to IGES format\n", solid_error); if (comb_error) bu_log("\t%d combinations were not converted to IGES format\n", comb_error); return 0; }
void csg_comb_func(struct db_i *dbip, struct directory *dp, void *UNUSED(ptr)) { struct rt_db_internal intern; struct rt_comb_internal *comb; struct iges_properties props; int comb_len; size_t i; int dependent = 1; int *de_pointers; int id; /* when this is called in facet mode, we only want groups */ if (mode == FACET_MODE && (dp->d_flags & RT_DIR_REGION)) return; /* check if already written */ if (dp->d_uses < 0) return; for (i = 0; i < no_of_indeps; i++) { if (!bu_strncmp(dp->d_namep, independent[i], NAMESIZE+1)) { dependent = 0; break; } } id = rt_db_get_internal(&intern, dp, dbip, (matp_t)NULL, &rt_uniresource); if (id < 0) return; if (id != ID_COMBINATION) { bu_log("Directory/Database mismatch! is %s a combination or not?\n", dp->d_namep); return; } comb = (struct rt_comb_internal *)intern.idb_ptr; RT_CK_COMB(comb); if (verbose) bu_log("Combination - %s\n", dp->d_namep); if (!comb->tree) { bu_log("Warning: empty combination (%s)\n", dp->d_namep); dp->d_uses = 0; return; } comb_len = db_tree_nleaves(comb->tree); de_pointers = (int *)bu_calloc(comb_len, sizeof(int), "csg_comb_func"); comb_form = 0; de_pointer_number = 0; if (get_de_pointers(comb->tree, dp, comb_len, de_pointers)) { bu_log("Error in combination %s\n", dp->d_namep); bu_free((char *)de_pointers, "csg_comb_func de_pointers"); rt_db_free_internal(&intern); return; } bu_strlcpy(props.name, dp->d_namep, NAMESIZE+1); props.material_name[0] = '\0'; props.material_params[0] = '\0'; props.region_flag = ' '; props.ident = 0; props.air_code = 0; props.material_code = 0; props.los_density = 0; props.color[0] = 0; props.color[1] = 0; props.color[2] = 0; get_props(&props, comb); dp->d_uses = (-comb_to_iges(comb, comb_len, dependent, &props, de_pointers, fp_dir, fp_param)); if (!dp->d_uses) { comb_error++; bu_log("g-iges: combination (%s) not written to iges file\n", dp->d_namep); } rt_db_free_internal(&intern); bu_free((char *)de_pointers, "csg_comb_func de_pointers"); }
int main (int argc, char *argv[]) { unsigned char *inbuf; /* Buffer */ unsigned char *cbuf; /* " */ unsigned char *dbuf; /* " */ unsigned char *inbp; /* Buffer pointer */ unsigned char *cbp; /* " " */ unsigned char *dbp; /* " " */ char *inf_name; /* File name */ char *cf_name; /* " " */ char *df_name; /* " " */ int p_per_b; /* pixels/buffer */ int inb_size; /* Buffer Size (in bytes) */ int cb_size; /* " " " " */ int db_size; /* " " " " */ int ch; int i; int c_per_p; /* chars/pixel */ int cwidth; /* chars/pixel (in bytes) */ int d_per_p; /* doubles/pixel (in doubles) */ int dwidth; /* doubles/pixel (in bytes) */ int pwidth; /* bytes/pixel, total */ int num; int infd; /* File descriptor */ int cfd = -1; /* " " */ int dfd = -1; /* " " */ extern int bu_optind; /* index from bu_getopt(3C) */ extern char *bu_optarg; /* argument from bu_getopt(3C) */ c_per_p = 3; cf_name = "-"; d_per_p = 1; df_name = ""; while ((ch = bu_getopt(argc, argv, OPT_STRING)) != EOF) switch (ch) { case 'd': df_name = (char *) bu_malloc(strlen(bu_optarg)+1, "df_name"); bu_strlcpy(df_name, bu_optarg, strlen(bu_optarg)+1); break; case 'c': cf_name = (char *) bu_malloc(strlen(bu_optarg)+1, "cf_name"); bu_strlcpy(cf_name, bu_optarg, strlen(bu_optarg)+1); break; case '#': if ((sscanf(bu_optarg, "%d.%d", &c_per_p, &d_per_p) != 2) && (sscanf(bu_optarg, ".%d", &d_per_p) != 1) && (sscanf(bu_optarg, "%d", &c_per_p) != 1)) { bu_log("Invalid pixel-size specification: '%s'\n", bu_optarg); print_usage(); } break; case '?': default: print_usage(); } if (c_per_p <= 0) { bu_log("Illegal number of color bytes per pixel: %d\n", c_per_p); return 1; } if (d_per_p <= 0) { bu_log("Illegal number of doubles per pixel: %d\n", d_per_p); return 1; } /* * Establish the input stream */ switch (argc - bu_optind) { case 0: inf_name = "stdin"; infd = 0; break; case 1: inf_name = argv[bu_optind++]; if ((infd = open(inf_name, O_RDONLY)) == -1) { bu_log("Cannot open file '%s'\n", inf_name); return 1; } break; default: print_usage(); } /* * Establish the output stream for chars */ if (*cf_name == '\0') { cf_name = 0; } else if ((*cf_name == '-') && (*(cf_name + 1) == '\0')) { cf_name = "stdout"; cfd = 1; } else if ((cfd = open(cf_name, O_WRONLY | O_CREAT | O_TRUNC, 0644)) == -1) { bu_log("Cannot open file '%s'\n", cf_name); return 1; } /* * Establish the output stream for doubles */ if (*df_name == '\0') { df_name = 0; } else if ((*df_name == '-') && (*(df_name + 1) == '\0')) { df_name = "stdout"; dfd = 1; } else if ((dfd = open(df_name, O_WRONLY | O_CREAT | O_TRUNC, 0644)) == -1) { bu_log("Cannot open file '%s'\n", df_name); return 1; } cwidth = c_per_p * 1; dwidth = d_per_p * 8; pwidth = cwidth + dwidth; p_per_b = ((1 << 16) / pwidth); /* A nearly 64-kbyte buffer */ inb_size = p_per_b * pwidth; cb_size = p_per_b * cwidth; db_size = p_per_b * dwidth; inbuf = (unsigned char *) bu_malloc(inb_size, "char buffer"); cbuf = (unsigned char *) bu_malloc(cb_size, "char buffer"); dbuf = (unsigned char *) bu_malloc(db_size, "double buffer"); while ((num = read(infd, inbuf, inb_size)) > 0) { inbp = inbuf; cbp = cbuf; dbp = dbuf; for (i = 0; i < num / pwidth; ++i) { memcpy(cbp, inbp, cwidth); memcpy(dbp, inbp + cwidth, cwidth); inbp += pwidth; cbp += cwidth; dbp += dwidth; } if (cf_name) write(cfd, cbuf, i * cwidth); if (df_name) write(dfd, dbuf, i * dwidth); if (num % pwidth != 0) bu_log("pixdsplit: WARNING: incomplete final pixel ignored\n"); } if (num < 0) { perror("pixdsplit"); return 1; } return 0; }
int spline(int entityno, struct face_g_snurb **b_patch) { int k1; /* upper index of first sum */ int k2; /* upper index of second sum */ int m1; /* degree of 1st set of basis functions */ int m2; /* degree of 2nd set of basis functions */ int prop1; /* !0 if closed in first direction */ int prop2; /* !0 if closed in second direction */ int prop3; /* !0 if polynomial (else rational) */ int prop4; /* !0 if periodic in first direction */ int prop5; /* !0 if periodic in second direction */ int sol_num; /* IGES solid type number */ int n1, n2; int i, j, k; int count = 0; int point_size; fastf_t min_knot; double max_wt; double scan; /* Acquiring Data */ if (dir[entityno]->param <= pstart) { bu_log("Illegal parameter pointer for entity D%07d (%s)\n" , dir[entityno]->direct, dir[entityno]->name); return 0; } Readrec(dir[entityno]->param); Readint(&sol_num, ""); Readint(&k1, ""); Readint(&k2, ""); Readint(&m1, ""); Readint(&m2, ""); Readint(&prop1, ""); Readint(&prop2, ""); Readint(&prop3, ""); Readint(&prop4, ""); Readint(&prop5, ""); n1 = k1 - m1 + 1; n2 = k2 - m2 + 1; /* spl_new: Creates a spline surface data structure * u_order (e.g. cubic = order 4) * v_order * num_u (e.g. num control points + order) * num_v * num_rows num control points in V direction * num_cols num control points in U direction * point_size number of values in a point (e.g. 3 or 4) */ if (prop3 == 0) { point_size = 4; } else { point_size = 3; } (*b_patch) = rt_nurb_new_snurb( m1+1, m2+1, n1+2*m1+1, n2+2*m2+1, k2+1, k1+1, RT_NURB_MAKE_PT_TYPE(point_size, 2, (prop3 == 0 ? RT_NURB_PT_RATIONAL : RT_NURB_PT_NONRAT)), (struct resource *)NULL); /* U knot vector */ min_knot = 0.0; for (i = 0; i <= n1+2*m1; i++) { Readdbl(&scan, ""); (*b_patch)->u.knots[i] = scan; /* double to fastf_t */ if ((*b_patch)->u.knots[i] < min_knot) min_knot = (*b_patch)->u.knots[i]; } if (min_knot < 0.0) { for (i = 0; i <= n1+2*m1; i++) { (*b_patch)->u.knots[i] -= min_knot; } } min_knot = 0.0; /* V knot vector */ for (i = 0; i <= n2+2*m2; i++) { Readdbl(&scan, ""); (*b_patch)->v.knots[i] = scan; /* double to fastf_t */ if ((*b_patch)->v.knots[i] < min_knot) min_knot = (*b_patch)->v.knots[i]; } if (min_knot < 0.0) { for (i = 0; i <= n2+2*m2; i++) { (*b_patch)->v.knots[i] -= min_knot; } } /* weights */ max_wt = 0.0; count = 0; for (i = 0; i <= k2; i++) { for (j = 0; j <= k1; j++) { if (point_size == 4) { Readdbl(&scan, ""); (*b_patch)->ctl_points[count*4 + 3] = scan; /* double to fastf_t */ if ((*b_patch)->ctl_points[count*4 + 3] > max_wt) max_wt = (*b_patch)->ctl_points[count*4 + 3]; } else { Readdbl(&max_wt, ""); } count++; } } /* control points */ count = 0; for (i = 0; i <= k2; i++) { for (j = 0; j <= k1; j++) { Readcnv(&(*b_patch)->ctl_points[count*point_size], ""); Readcnv(&(*b_patch)->ctl_points[count*point_size + 1], ""); Readcnv(&(*b_patch)->ctl_points[count*point_size + 2], ""); count++; } } if (point_size == 4) { /* apply weights */ count = 0; for (i = 0; i <= k2; i++) { for (j = 0; j <= k1; j++) { for (k = 0; k < 3; k++) (*b_patch)->ctl_points[count*4 + k] *= (*b_patch)->ctl_points[count*4 + 3]; count++; } } } return 1; }
void db_close(register struct db_i *dbip) { register int i; register struct directory *dp, *nextdp; if (!dbip) return; RT_CK_DBI(dbip); if (RT_G_DEBUG&DEBUG_DB) bu_log("db_close(%s) %p uses=%d\n", dbip->dbi_filename, (void *)dbip, dbip->dbi_uses); bu_semaphore_acquire(BU_SEM_LISTS); if ((--dbip->dbi_uses) > 0) { bu_semaphore_release(BU_SEM_LISTS); /* others are still using this database */ return; } bu_semaphore_release(BU_SEM_LISTS); /* ready to free the database -- use count is now zero */ /* free up any mapped files */ if (dbip->dbi_mf) { /* * We're using an instance of a memory mapped file. * We have two choices: * Either dissociate from the memory mapped file * by clearing dbi_mf->apbuf, or * keeping our already-scanned dbip ready for * further use, with our dbi_uses counter at 0. * For speed of re-open, at the price of some address space, * the second choice is taken. */ bu_close_mapped_file(dbip->dbi_mf); bu_free_mapped_files(0); dbip->dbi_mf = (struct bu_mapped_file *)NULL; } /* try to ensure/encourage that the file is written out */ db_sync(dbip); if (dbip->dbi_fp) { fclose(dbip->dbi_fp); } if (dbip->dbi_title) bu_free(dbip->dbi_title, "dbi_title"); if (dbip->dbi_filename) bu_free(dbip->dbi_filename, "dbi_filename"); db_free_anim(dbip); rt_color_free(); /* Free MaterHead list */ /* Release map of database holes */ rt_mempurge(&(dbip->dbi_freep)); rt_memclose(); dbip->dbi_inmem = NULL; /* sanity */ bu_ptbl_free(&dbip->dbi_clients); /* Free all directory entries */ for (i = 0; i < RT_DBNHASH; i++) { for (dp = dbip->dbi_Head[i]; dp != RT_DIR_NULL;) { RT_CK_DIR(dp); nextdp = dp->d_forw; RT_DIR_FREE_NAMEP(dp); /* frees d_namep */ if ((dp->d_flags & RT_DIR_INMEM) && (dp->d_un.ptr != NULL)) { bu_free(dp->d_un.ptr, "db_close d_un.ptr"); dp->d_un.ptr = NULL; dp->d_len = 0; } /* Put 'dp' back on the freelist */ dp->d_forw = rt_uniresource.re_directory_hd; rt_uniresource.re_directory_hd = dp; /* null'ing the forward pointer here is a huge * memory leak as it causes the loss of all * nodes on the freelist except the first. * (so don't do it) */ dp = nextdp; } dbip->dbi_Head[i] = RT_DIR_NULL; /* sanity*/ } if (dbip->dbi_filepath != NULL) { bu_free_argv(2, dbip->dbi_filepath); dbip->dbi_filepath = NULL; /* sanity */ } bu_free((char *)dbip, "struct db_i"); }
struct db_i * db_open(const char *name, const char *mode) { register struct db_i *dbip = DBI_NULL; register int i; char **argv; if (name == NULL) return DBI_NULL; if (RT_G_DEBUG & DEBUG_DB) { bu_log("db_open(%s, %s)\n", name, mode); } if (mode && mode[0] == 'r' && mode[1] == '\0') { /* Read-only mode */ struct bu_mapped_file *mfp; mfp = bu_open_mapped_file(name, "db_i"); if (mfp == NULL) { if (RT_G_DEBUG & DEBUG_DB) { bu_log("db_open(%s) FAILED, unable to open as a mapped file\n", name); } return DBI_NULL; } /* Is this a re-use of a previously mapped file? */ if (mfp->apbuf) { dbip = (struct db_i *)mfp->apbuf; RT_CK_DBI(dbip); dbip->dbi_uses++; /* * decrement the mapped file reference counter by 1, * references are already counted in dbip->dbi_uses */ bu_close_mapped_file(mfp); if (RT_G_DEBUG & DEBUG_DB) { bu_log("db_open(%s) dbip=%p: reused previously mapped file\n", name, (void *)dbip); } return dbip; } BU_ALLOC(dbip, struct db_i); dbip->dbi_mf = mfp; dbip->dbi_eof = (off_t)mfp->buflen; dbip->dbi_inmem = mfp->buf; dbip->dbi_mf->apbuf = (void *)dbip; /* Do this too, so we can seek around on the file */ if ((dbip->dbi_fp = fopen(name, "rb")) == NULL) { if (RT_G_DEBUG & DEBUG_DB) { bu_log("db_open(%s) FAILED, unable to open file for reading\n", name); } bu_free((char *)dbip, "struct db_i"); return DBI_NULL; } dbip->dbi_read_only = 1; } else { /* Read-write mode */ BU_ALLOC(dbip, struct db_i); dbip->dbi_eof = (off_t)-1L; if ((dbip->dbi_fp = fopen(name, "r+b")) == NULL) { if (RT_G_DEBUG & DEBUG_DB) { bu_log("db_open(%s) FAILED, unable to open file for reading/writing\n", name); } bu_free((char *)dbip, "struct db_i"); return DBI_NULL; } dbip->dbi_read_only = 0; } /* Initialize fields */ for (i = 0; i < RT_DBNHASH; i++) dbip->dbi_Head[i] = RT_DIR_NULL; dbip->dbi_local2base = 1.0; /* mm */ dbip->dbi_base2local = 1.0; dbip->dbi_title = (char *)0; dbip->dbi_uses = 1; /* FIXME: At some point, expand argv search paths with * getenv("BRLCAD_FILE_PATH") paths */ /* intentionally acquiring dynamic memory here since we set * dbip->dbi_filepath to argv. arg values and array memory are * released during db_close. */ argv = (char **)bu_malloc(3 * sizeof(char *), "dbi_filepath[3]"); argv[0] = bu_strdup("."); argv[1] = bu_dirname(name); argv[2] = NULL; dbip->dbi_filepath = argv; #if !defined(_WIN32) || defined(__CYGWIN__) /* If not a full path */ if (argv[1][0] != '/') { struct bu_vls fullpath = BU_VLS_INIT_ZERO; bu_free((void *)argv[1], "db_open: argv[1]"); argv[1] = getcwd((char *)NULL, (size_t)MAXPATHLEN); /* Something went wrong and we didn't get the CWD. So, * free up any memory allocated here and return DBI_NULL */ if (argv[1] == NULL) { if (dbip->dbi_mf) { bu_close_mapped_file(dbip->dbi_mf); bu_free_mapped_files(0); dbip->dbi_mf = (struct bu_mapped_file *)NULL; } if (dbip->dbi_fp) { fclose(dbip->dbi_fp); } bu_free((void *)argv[0], "db_open: argv[0]"); bu_free((void *)argv, "db_open: argv"); bu_free((char *)dbip, "struct db_i"); return DBI_NULL; } bu_vls_printf(&fullpath, "%s/%s", argv[1], name); dbip->dbi_filename = bu_strdup(bu_vls_addr(&fullpath)); bu_vls_free(&fullpath); } else { /* Record the filename and file path */ dbip->dbi_filename = bu_strdup(name); } #else /* Record the filename and file path */ dbip->dbi_filename = bu_strdup(name); #endif bu_ptbl_init(&dbip->dbi_clients, 128, "dbi_clients[]"); dbip->dbi_magic = DBI_MAGIC; /* Now it's valid */ /* determine version */ dbip->dbi_version = 0; /* make db_version() calculate */ dbip->dbi_version = db_version(dbip); if (dbip->dbi_version < 5) { if (rt_db_flip_endian(dbip)) { if (dbip->dbi_version > 0) dbip->dbi_version *= -1; dbip->dbi_read_only = 1; bu_log("WARNING: Binary-incompatible v4 geometry database detected.\n"); bu_log(" Endianness flipped. Converting to READ ONLY.\n"); } } if (RT_G_DEBUG & DEBUG_DB) { bu_log("db_open(%s) dbip=%p version=%d\n", dbip->dbi_filename, (void *)dbip, dbip->dbi_version); } return dbip; }
/** * This function parses the input shaders * Example: * shadername=color#Cin#point#0.0#0.0#1.0 * shadername=glass * shadername=checker#K#float#4.0 * join=color#Cout#shader#Cin1 * join=glass#Cout#shader#Cin1 **/ int osl_parse(const struct bu_vls *in_vls, ShaderGroupInfo &group_info) { struct bu_vls vls = BU_VLS_INIT_ZERO; register char *cp; char *name; char *value; int retval; BU_CK_VLS(in_vls); /* Duplicate the input string. This algorithm is destructive. */ bu_vls_vlscat(&vls, in_vls); cp = bu_vls_addr(&vls); while (*cp) { /* NAME = VALUE white-space-separator */ /* skip any leading whitespace */ while (*cp != '\0' && isspace(*cp)) cp++; /* Find equal sign */ name = cp; while (*cp != '\0' && *cp != '=') cp++; if (*cp == '\0') { if (name == cp) break; /* end of string in middle of arg */ bu_log("bu_structparse: input keyword '%s' is not followed by '=' in '%s'\nInput must be in keyword=value format.\n", name, bu_vls_addr(in_vls)); bu_vls_free(&vls); return -2; } *cp++ = '\0'; /* Find end of value. */ if (*cp == '"') { /* strings are double-quote (") delimited skip leading " & * find terminating " while skipping escaped quotes (\") */ for (value = ++cp; *cp != '\0'; ++cp) if (*cp == '"' && (cp == value || *(cp-1) != '\\')) break; if (*cp != '"') { bu_log("bu_structparse: keyword '%s'=\" without closing \"\n", name); bu_vls_free(&vls); return -3; } } else { /* non-strings are white-space delimited */ value = cp; while (*cp != '\0' && !isspace(*cp)) cp++; } if (*cp != '\0') *cp++ = '\0'; if (BU_STR_EQUAL(name, "shadername")) { ShaderInfo sh_info; osl_parse_shader(value, sh_info); group_info.shader_layers.push_back(sh_info); } else if (BU_STR_EQUAL(name, "join")) { ShaderEdge sh_edge; osl_parse_edge(value, sh_edge); group_info.shader_edges.push_back(sh_edge); } } bu_vls_free(&vls); return 0; }
static int make_shape(struct rt_wdb *fd, int verbose, int debug, size_t idx, size_t num, point2d_t *v) { size_t i; point_t V = VINIT_ZERO; vect_t h = VINIT_ZERO; struct bu_vls str_sketch = BU_VLS_INIT_ZERO; struct bu_vls str_extrude = BU_VLS_INIT_ZERO; struct rt_sketch_internal skt; struct line_seg *lsg = NULL; /* nothing to do? */ if (num == 0 || !v) return 0; if (!fd) { if (debug) bu_log("ERROR: unable to write out shape\n"); return 1; } if (verbose || debug) bu_log("%zu vertices\n", num); skt.magic = RT_SKETCH_INTERNAL_MAGIC; VMOVE(skt.V, V); VSET(skt.u_vec, 1.0, 0.0, 0.0); VSET(skt.v_vec, 0.0, 1.0, 0.0); skt.vert_count = num; skt.verts = v; /* Specify number of segments */ skt.curve.count = num; /* FIXME: investigate allocation */ skt.curve.reverse = (int *)bu_calloc(skt.curve.count, sizeof(int), "sketch: reverse"); skt.curve.segment = (void **)bu_calloc(skt.curve.count, sizeof(void *), "segs"); /* Insert all line segments except the last one */ for (i = 0; i < num-1; i++) { BU_ALLOC(lsg, struct line_seg); lsg->magic = CURVE_LSEG_MAGIC; lsg->start = i; lsg->end = i + 1; skt.curve.segment[i] = (void *)lsg; } /* Connect the last connected vertex to the first vertex */ BU_ALLOC(lsg, struct line_seg); lsg->magic = CURVE_LSEG_MAGIC; lsg->start = num - 1; lsg->end = 0; skt.curve.segment[num - 1] = (void *)lsg; /* write out sketch shape */ bu_vls_sprintf(&str_sketch, "shape-%zu.sketch", idx); mk_sketch(fd, bu_vls_addr(&str_sketch), &skt); /* extrude the shape */ bu_vls_sprintf(&str_extrude, "shape-%zu.extrude", idx); VSET(h, 0.0, 0.0, 10.0); /* FIXME: arbitrary height */ mk_extrusion(fd, bu_vls_addr(&str_extrude), bu_vls_addr(&str_sketch), skt.V, h, skt.u_vec, skt.v_vec, 0); /* clean up */ bu_vls_free(&str_sketch); bu_vls_free(&str_extrude); rt_curve_free(&skt.curve); return 0; }
int main(int argc, char *argv[]) { int opt; size_t i; const char *argv0 = argv[0]; struct rt_wdb *fd_out; struct bu_vls vls_in = BU_VLS_INIT_ZERO; struct bu_vls vls_out = BU_VLS_INIT_ZERO; int opt_debug = 0; int opt_verbose = 0; /* shapelib vars */ SHPHandle shapefile; size_t shp_num_invalid = 0; int shp_num_entities = 0; int shp_type = 0; /* intentionally double for scan */ double shp_min[4] = HINIT_ZERO; double shp_max[4] = HINIT_ZERO; /* geometry */ point2d_t *verts = NULL; size_t num_verts = 0; if (argc < 2) { usage(argv0); bu_exit(1, NULL); } while ((opt = bu_getopt(argc, argv, "dxv")) != -1) { switch (opt) { case 'd': opt_debug = 1; break; 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 'v': opt_verbose++; break; default: usage(argv0); bu_exit(1, NULL); break; } } argv += bu_optind; argc -= bu_optind; if (opt_verbose) bu_log("Verbose output enabled.\n"); if (opt_debug) bu_log("Debugging output enabled.\n"); /* validate input/output file specifiers */ if (argc < 1) { usage(argv0); bu_exit(1, "ERROR: Missing input and output file names\n"); } bu_vls_strcat(&vls_in, argv[0]); if (argc < 2) { bu_vls_printf(&vls_out, "%s.g", argv[0]); } else { bu_vls_strcat(&vls_out, argv[1]); } if (opt_verbose) { bu_log("Reading from [%s]\n", bu_vls_addr(&vls_in)); bu_log("Writing to [%s]\n\n", bu_vls_addr(&vls_out)); } /* initialize single threaded resource */ rt_init_resource(&rt_uniresource, 0, NULL); /* open the input */ shapefile = SHPOpen(bu_vls_addr(&vls_in), "rb"); if (!shapefile) { bu_log("ERROR: Unable to open shapefile [%s]\n", bu_vls_addr(&vls_in)); bu_vls_free(&vls_in); bu_vls_free(&vls_out); bu_exit(4, NULL); } /* print shapefile details */ if (opt_verbose) { SHPGetInfo(shapefile, &shp_num_entities, &shp_type, shp_min, shp_max); bu_log("Shapefile Type: %s\n", SHPTypeName(shp_type)); bu_log("# of Shapes: %d\n\n", shp_num_entities); bu_log("File Bounds: (%12.3f,%12.3f, %.3g, %.3g)\n" " to (%12.3f,%12.3f, %.3g, %.3g)\n", shp_min[0], shp_min[1], shp_min[2], shp_min[3], shp_max[0], shp_max[1], shp_max[2], shp_max[3]); } /* open the .g for writing */ if ((fd_out = wdb_fopen(bu_vls_addr(&vls_out))) == NULL) { bu_log("ERROR: Unable to open shapefile [%s]\n", bu_vls_addr(&vls_out)); bu_vls_free(&vls_in); bu_vls_free(&vls_out); perror(argv0); bu_exit(5, NULL); } /* iterate over all entities */ for (i=0; i < (size_t)shp_num_entities; i++) { SHPObject *object; int shp_part; size_t j; object = SHPReadObject(shapefile, i); if (!object) { if (opt_debug) bu_log("Shape %zu of %zu is missing, skipping.\n", i+1, (size_t)shp_num_entities); continue; } /* validate the object */ if (opt_debug) { int shp_altered = SHPRewindObject(shapefile, object); if (shp_altered > 0) { bu_log("WARNING: Shape %zu of %zu has [%d] bad loop orientations.\n", i+1, (size_t)shp_num_entities, shp_altered); shp_num_invalid++; } } /* print detail header */ if (opt_verbose) { if (object->bMeasureIsUsed) { bu_log("\nShape:%zu (%s) nVertices=%d, nParts=%d\n" " Bounds:(%12.3f,%12.3f, %g, %g)\n" " to (%12.3f,%12.3f, %g, %g)\n", i+1, SHPTypeName(object->nSHPType), object->nVertices, object->nParts, object->dfXMin, object->dfYMin, object->dfZMin, object->dfMMin, object->dfXMax, object->dfYMax, object->dfZMax, object->dfMMax); } else { bu_log("\nShape:%zu (%s) nVertices=%d, nParts=%d\n" " Bounds:(%12.3f,%12.3f, %g)\n" " to (%12.3f,%12.3f, %g)\n", i+1, SHPTypeName(object->nSHPType), object->nVertices, object->nParts, object->dfXMin, object->dfYMin, object->dfZMin, object->dfXMax, object->dfYMax, object->dfZMax); } if (object->nParts > 0 && object->panPartStart[0] != 0) { if (opt_debug) bu_log("Shape %zu of %zu: panPartStart[0] = %d, not zero as expected.\n", i+1, (size_t)shp_num_entities, object->panPartStart[0]); continue; } } num_verts = 0; verts = (point2d_t *)bu_calloc((size_t)object->nVertices, sizeof(point2d_t), "alloc point array"); for (j = 0, shp_part = 1; j < (size_t)object->nVertices; j++) { if (shp_part < object->nParts && j == (size_t)object->panPartStart[shp_part]) { shp_part++; bu_log("Shape %zu of %zu: End of Loop\n", i+1, (size_t)shp_num_entities); make_shape(fd_out, opt_verbose, opt_debug, i, num_verts, verts); /* reset for next loop */ memset(verts, 0, sizeof(point2d_t) * object->nVertices); num_verts = 0; } bu_log("%zu/%zu:%zu/%zu\t\t", i+1, (size_t)shp_num_entities, j+1, (size_t)object->nVertices); bu_log("(%12.4f, %12.4f, %12.4f, %g)\n", object->padfX[j], object->padfY[j], object->padfZ[j], object->padfM[j]); V2SET(verts[num_verts], object->padfX[j], object->padfY[j]); num_verts++; } bu_log("Shape %zu of %zu: End of Loop\n", i+1, (size_t)shp_num_entities); make_shape(fd_out, opt_verbose, opt_debug, i, num_verts, verts); bu_free(verts, "free point array"); verts = NULL; num_verts = 0; SHPDestroyObject(object); object = NULL; } if (opt_verbose) { if (shp_num_invalid > 0) { bu_log("WARNING: %zu of %zu shape(s) had bad loop orientations.\n", shp_num_invalid, (size_t)shp_num_entities); } bu_log("\nDone.\n"); } /* close up our files */ SHPClose(shapefile); wdb_close(fd_out); /* free up allocated resources */ bu_vls_free(&vls_in); bu_vls_free(&vls_out); return 0; }
int make_hole(struct rt_wdb *wdbp, /* database to be modified */ point_t hole_start, /* center of start of hole */ vect_t hole_depth, /* depth and direction of hole */ fastf_t hole_radius, /* radius of hole */ int num_objs, /* number of objects that this hole affects */ struct directory **dp) /* array of directory pointers * [num_objs] of objects to * get this hole applied */ { struct bu_vls tmp_name = BU_VLS_INIT_ZERO; int i, base_len, count=0; RT_CHECK_WDB(wdbp); /* make sure we are only making holes in combinations, they do not * have to be regions */ for (i=0; i<num_objs; i++) { RT_CK_DIR(dp[i]); if (!(dp[i]->d_flags & RT_DIR_COMB)) { bu_log("make_hole(): can only make holes in combinations\n"); bu_log("\t%s is not a combination\n", dp[i]->d_namep); return 4; } } /* make a unique name for the RCC we will use (of the form * "make_hole_%d") */ bu_vls_strcat(&tmp_name, "make_hole_"); base_len = bu_vls_strlen(&tmp_name); bu_vls_strcat(&tmp_name, "0"); while ((db_lookup(wdbp->dbip, bu_vls_addr(&tmp_name), LOOKUP_QUIET)) != RT_DIR_NULL) { count++; bu_vls_trunc(&tmp_name, base_len); bu_vls_printf(&tmp_name, "%d", count); } /* build the RCC based on parameters passed in */ if (mk_rcc(wdbp, bu_vls_addr(&tmp_name), hole_start, hole_depth, hole_radius)) { bu_log("Failed to create hole cylinder!!!\n"); bu_vls_free(&tmp_name); return 2; } /* subtract this RCC from each combination in the list passed in */ for (i=0; i<num_objs; i++) { struct rt_db_internal intern; struct rt_comb_internal *comb; union tree *tree; /* get the internal form of the combination */ if (rt_db_get_internal(&intern, dp[i], wdbp->dbip, NULL, wdbp->wdb_resp) < 0) { bu_log("Failed to get %s\n", dp[i]->d_namep); bu_vls_free(&tmp_name); return 3; } comb = (struct rt_comb_internal *)intern.idb_ptr; /* Build a new "subtract" node (will be the root of the new tree) */ BU_ALLOC(tree, union tree); RT_TREE_INIT(tree); tree->tr_b.tb_op = OP_SUBTRACT; tree->tr_b.tb_left = comb->tree; /* subtract from the original tree */ comb->tree = tree; /* Build a node for the RCC to be subtracted */ BU_ALLOC(tree, union tree); RT_TREE_INIT(tree); tree->tr_l.tl_op = OP_DB_LEAF; tree->tr_l.tl_mat = NULL; tree->tr_l.tl_name = bu_strdup(bu_vls_addr(&tmp_name)); /* copy name of RCC */ /* Put the RCC node to the right of the root */ comb->tree->tr_b.tb_right = tree; /* Save the modified combination. This will overwrite the * original combination if wdbp was opened with the * RT_WDB_TYPE_DB_DISK flag. If wdbp was opened with the * RT_WDB_TYPE_DB_INMEM flag, then the combination will be * temporarily over-written in memory only and the disk file * will not be modified. */ wdb_put_internal(wdbp, dp[i]->d_namep, &intern, 1.0); } return 0; }
/* * * Usage: * procname cell xmin ymin width height color */ HIDDEN int fbo_cell_tcl(void *clientData, int argc, const char **argv) { struct fb_obj *fbop = (struct fb_obj *)clientData; int xmin, ymin; long width; long height; size_t i; RGBpixel pixel; unsigned char *pp; if (argc != 7) { bu_log("ERROR: expecting seven arguments\n"); return BRLCAD_ERROR; } if (sscanf(argv[2], "%d", &xmin) != 1) { bu_log("fb_cell: bad xmin value - %s", argv[2]); return BRLCAD_ERROR; } if (sscanf(argv[3], "%d", &ymin) != 1) { bu_log("fb_cell: bad ymin value - %s", argv[3]); return BRLCAD_ERROR; } /* check coordinates */ if (!fbo_coords_ok(fbop->fbo_fbs.fbs_fbp, xmin, ymin)) { bu_log("fb_cell: coordinates (%s, %s) are invalid.", argv[2], argv[3]); return BRLCAD_ERROR; } if (sscanf(argv[4], "%ld", &width) != 1) { bu_log("fb_cell: bad width - %s", argv[4]); return BRLCAD_ERROR; } if (sscanf(argv[5], "%ld", &height) != 1) { bu_log("fb_cell: bad height - %s", argv[5]); return BRLCAD_ERROR; } /* check width and height */ if (width <=0 || height <=0) { bu_log("fb_cell: width and height must be > 0"); return BRLCAD_ERROR; } /* * Decompose the color list into its constituents. * For now must be in the form of rrr ggg bbb. */ if (fbo_tcllist2color(argv[6], pixel) == BRLCAD_ERROR) { bu_log("fb_cell: invalid color spec: %s", argv[6]); return BRLCAD_ERROR; } pp = (unsigned char *)bu_calloc(width*height, sizeof(RGBpixel), "allocate pixel array"); for (i = 0; i < width*height*sizeof(RGBpixel); i+=sizeof(RGBpixel)) { pp[i] = pixel[0]; pp[i+1] = pixel[1]; pp[i+2] = pixel[2]; } fb_writerect(fbop->fbo_fbs.fbs_fbp, xmin, ymin, width, height, pp); bu_free((void *)pp, "free pixel array"); return BRLCAD_OK; }
/** * Handle user interaction. Interact() prompts on stdin for a key * word, looks the key word up in the command table and, if it finds * the key word, the command is executed. */ void interact(int input_source, void *sPtr, struct rt_i *rtip) { int Ch; /* individual characters of the input line */ int Prev_ch=0; /* previous character */ char line_buffer[256]; /* line of text the user types */ int i; /* position on the line_buffer[] */ com_table *ctp; /* command table pointer */ int key_len; /* the length of the key word */ int in_cmt; /* are we now within a comment? */ int more_on_line = 0; /* are we withing a multi-command line? */ #define next_char(s) (input_source == READING_FILE) ? \ fgetc((FILE *) s) : \ (input_source == READING_STRING) ? \ sgetc((char *) s) : \ (bu_log("next_char(%d) error. Shouldn't happen\n", \ input_source), EOF) if (nirt_debug & DEBUG_INTERACT) { bu_log("interact(%s, %p)...\n", (input_source == READING_FILE) ? "READING_FILE" : (input_source == READING_STRING) ? "READING_STRING" : "???", sPtr); } /* Prime the pump when reading from a string */ if (input_source == READING_STRING) sgetc((char *)0); for (;;) { in_cmt = 0; key_len = 0; if ((input_source == READING_FILE) && (sPtr == stdin) && (silent_flag != SILENT_YES) && (! more_on_line)) (void) fputs(NIRT_PROMPT, stdout); more_on_line = 0; while (((Ch = next_char(sPtr)) == ' ') || (Ch == '\t')) { if (nirt_debug & DEBUG_INTERACT) bu_log("Skipping '%c'\n", Ch); } if (Ch == '\n' || Ch == '\r') continue; for (i = 0; (Ch != '\n') && (Ch != '\r') && (i < 255); ++i) { if (Ch == CMT_CHAR) { if ( Prev_ch == '\\' ) { i--; } else { in_cmt = 1; while (((Ch = next_char(sPtr)) != EOF) && (Ch != '\n') && (Ch != '\r')) ; } } if (Ch == SEP_CHAR) { more_on_line = 1; break; } else if ((Ch == '\n') || (Ch == '\r')) { break; } if ((input_source == READING_STRING) && (Ch == '\0')) break; if (Ch == EOF) { if ((input_source == READING_FILE) && (sPtr == stdin)) bu_exit(1, "Unexpected EOF in input!!\n"); else return; } if (key_len == 0 && (Ch == ' ' || Ch == '\t')) key_len = i; /* length of key word */ line_buffer[i] = Ch; Prev_ch = Ch; if (nirt_debug & DEBUG_INTERACT) bu_log("line_buffer[%d] = '%c' (o%o)\n", i, Ch, Ch); Ch = next_char(sPtr); } if (key_len == 0) { /* length of key word */ if (in_cmt) continue; key_len = i; } line_buffer[i] = '\0'; if (nirt_debug & DEBUG_INTERACT) bu_log("Line buffer contains '%s'\n", line_buffer); ctp = get_comtab_ent(line_buffer, key_len); if (ctp == CT_NULL) { line_buffer[key_len] = '\0'; fprintf(stderr, "Invalid command name '%s'. Enter '?' for help\n", line_buffer); } else { /* call the callback */ (*(ctp->com_func)) (&line_buffer[key_len], ctp, rtip); } } }
/* * * Usage: * procname cell xmin ymin width height color */ HIDDEN int fbo_rect_tcl(void *clientData, int argc, const char **argv) { struct fb_obj *fbop = (struct fb_obj *)clientData; int xmin, ymin; int xmax, ymax; int width; int height; int i; RGBpixel pixel; if (argc != 7) { bu_log("ERROR: expecting seven arguments\n"); return BRLCAD_ERROR; } if (sscanf(argv[2], "%d", &xmin) != 1) { bu_log("fb_rect: bad xmin value - %s", argv[2]); return BRLCAD_ERROR; } if (sscanf(argv[3], "%d", &ymin) != 1) { bu_log("fb_rect: bad ymin value - %s", argv[3]); return BRLCAD_ERROR; } /* check coordinates */ if (!fbo_coords_ok(fbop->fbo_fbs.fbs_fbp, xmin, ymin)) { bu_log("fb_rect: coordinates (%s, %s) are invalid.", argv[2], argv[3]); return BRLCAD_ERROR; } if (sscanf(argv[4], "%d", &width) != 1) { bu_log("fb_rect: bad width - %s", argv[4]); return BRLCAD_ERROR; } if (sscanf(argv[5], "%d", &height) != 1) { bu_log("fb_rect: bad height - %s", argv[5]); return BRLCAD_ERROR; } /* check width and height */ if (width <=0 || height <=0) { bu_log("fb_rect: width and height must be > 0"); return BRLCAD_ERROR; } /* * Decompose the color list into its constituents. * For now must be in the form of rrr ggg bbb. */ if (fbo_tcllist2color(argv[6], pixel) == BRLCAD_ERROR) { bu_log("fb_rect: invalid color spec: %s", argv[6]); return BRLCAD_ERROR; } xmax = xmin + width; ymax = ymin + height; /* draw horizontal lines */ for (i = xmin; i <= xmax; ++i) { /* working on bottom line */ fb_write(fbop->fbo_fbs.fbs_fbp, i, ymin, pixel, 1); /* working on top line */ fb_write(fbop->fbo_fbs.fbs_fbp, i, ymax, pixel, 1); } /* draw vertical lines */ for (i = ymin; i <= ymax; ++i) { /* working on left line */ fb_write(fbop->fbo_fbs.fbs_fbp, xmin, i, pixel, 1); /* working on right line */ fb_write(fbop->fbo_fbs.fbs_fbp, xmax, i, pixel, 1); } return BRLCAD_OK; }
/* * Called from db_walk_tree(). * * This routine must be prepared to run in parallel. */ union tree * do_nmg_region_end(struct db_tree_state *tsp, const struct db_full_path *pathp, union tree *curtree, void *UNUSED(client_data)) { union tree *result; struct nmgregion *r; struct bu_list vhead; struct directory *dp; int dependent; size_t i; RT_CK_TESS_TOL(tsp->ts_ttol); BN_CK_TOL(tsp->ts_tol); NMG_CK_MODEL(*tsp->ts_m); BU_LIST_INIT(&vhead); if (RT_G_DEBUG&DEBUG_TREEWALK || verbose) { char *sofar = db_path_to_string(pathp); bu_log("\ndo_nmg_region_end(%d %d%%) %s\n", regions_tried, regions_tried>0 ? (regions_done * 100) / regions_tried : 0, sofar); bu_free(sofar, "path string"); } if (curtree->tr_op == OP_NOP) return curtree; regions_tried++; if (verbose) bu_log("\ndoing boolean tree evaluate...\n"); /* evaluate the boolean */ result = process_boolean(tsp, curtree, pathp); if (result) r = result->tr_d.td_r; else r = (struct nmgregion *)NULL; if (verbose) bu_log("\nfinished boolean tree evaluate...\n"); regions_done++; if (r != NULL) { dp = DB_FULL_PATH_CUR_DIR(pathp); if (multi_file) { /* Open the output file */ if (output_file == NULL) fp_dir = stdout; else { char *multi_name; size_t len; int unique = 0; char suffix[SUFFIX_LEN+1]; /* construct a unique file name */ len = strlen(output_file) + strlen(dp->d_namep) + 6 + SUFFIX_LEN; multi_name = (char *)bu_malloc(sizeof(char)*len, "multi_name"); snprintf(multi_name, len, "%s/%s.igs", output_file, dp->d_namep); bu_strlcpy(suffix, "a", sizeof(suffix)); suffix[0]--; while (!unique) { if (bu_file_readable(multi_name)) { unique = 1; break; } /* not unique, try adding a suffix */ len = strlen(suffix); i = len - 1; suffix[i]++; while (suffix[i] > 'z' && i > 0) { suffix[i] = 'a'; i--; suffix[i]++; } if (suffix[0] > 'z' && len < SUFFIX_LEN) { for (i = 0; i <= len; i++) suffix[i] = 'a'; } else if (suffix[0] > 'z' && len >= SUFFIX_LEN) { bu_log("too many files with the same name (%s)\n", dp->d_namep); bu_exit(1, "Cannot create a unique filename, \n"); } snprintf(multi_name, len, "%s/%s%s.igs", output_file, dp->d_namep, suffix); } if ((fp_dir = fopen(multi_name, "wb")) == NULL) { perror("g-iges"); bu_exit(1, "Cannot open output file: %s\n", multi_name); } } /* Open the temporary file for the parameter section */ if ((fp_param = bu_temp_file(NULL, 0)) == NULL) { perror("g-iges"); bu_exit(1, "Cannot open temporary file\n"); } /* let the IGES routines know the selected tolerances and the database pointer */ iges_init(&tol, &ttol, verbose, DBIP); /* Write start and global sections of the IGES file */ w_start_global(fp_dir, fp_param, db_name, prog_name, output_file, __DATE__, brlcad_version()); } if (mode == FACET_MODE) { dependent = 1; for (i = 0; i < no_of_indeps; i++) { if (!bu_strncmp(dp->d_namep, independent[i], NAMESIZE+1)) { dependent = 0; break; } } dp->d_uses = (-nmgregion_to_iges(dp->d_namep, r, dependent, fp_dir, fp_param)); } else if (mode == TRIMMED_SURF_MODE) dp->d_uses = (-nmgregion_to_tsurf(dp->d_namep, r, fp_dir, fp_param)); /* NMG region is no longer necessary */ nmg_kr(r); if (multi_file) { char copy_buffer[CP_BUF_SIZE] = {0}; /* Copy the parameter section from the temporary file to the output file */ if ((bu_fseek(fp_param, 0, 0))) { perror("g-iges"); bu_exit(1, "Cannot seek to start of temporary file\n"); } while ((i = fread(copy_buffer, 1, CP_BUF_SIZE, fp_param))) if (fwrite(copy_buffer, 1, i, fp_dir) != i) { perror("g-iges"); bu_exit(1, "Error in copying parameter data to %s\n", output_file); } /* Write the terminate section */ w_terminate(fp_dir); fclose(fp_dir); fclose(fp_param); } } /* * Dispose of original tree, so that all associated dynamic * memory is released now, not at the end of all regions. * A return of TREE_NULL from this routine signals an error, * so we need to cons up an OP_NOP node to return. */ db_free_tree(curtree, &rt_uniresource); /* Does an nmg_kr() */ BU_ALLOC(curtree, union tree); RT_TREE_INIT(curtree); curtree->tr_op = OP_NOP; return curtree; }
/* * Open/create a framebuffer object. * * Usage: * fb_open [name device [args]] */ HIDDEN int fbo_open_tcl(void *UNUSED(clientData), Tcl_Interp *interp, int argc, const char **argv) { struct fb_obj *fbop; FBIO *ifp; int width = 512; int height = 512; register int c; struct bu_vls vls = BU_VLS_INIT_ZERO; if (argc == 1) { /* get list of framebuffer objects */ for (BU_LIST_FOR(fbop, fb_obj, &HeadFBObj.l)) Tcl_AppendResult(interp, bu_vls_addr(&fbop->fbo_name), " ", (char *)NULL); return BRLCAD_OK; } if (argc < 3) { bu_vls_printf(&vls, "helplib fb_open"); Tcl_Eval(interp, bu_vls_addr(&vls)); bu_vls_free(&vls); return BRLCAD_ERROR; } /* process args */ bu_optind = 3; bu_opterr = 0; while ((c = bu_getopt(argc, (char * const *)argv, "w:W:s:S:n:N:")) != -1) { switch (c) { case 'W': case 'w': width = atoi(bu_optarg); break; case 'N': case 'n': height = atoi(bu_optarg); break; case 'S': case 's': width = atoi(bu_optarg); height = width; break; case '?': default: bu_log("fb_open: bad option - %s", bu_optarg); return BRLCAD_ERROR; } } if ((ifp = fb_open(argv[2], width, height)) == FBIO_NULL) { bu_log("fb_open: bad device - %s", argv[2]); return BRLCAD_ERROR; } if (fb_ioinit(ifp) != 0) { bu_log("fb_open: fb_ioinit() failed."); return BRLCAD_ERROR; } BU_ALLOC(fbop, struct fb_obj); bu_vls_init(&fbop->fbo_name); bu_vls_strcpy(&fbop->fbo_name, argv[1]); fbop->fbo_fbs.fbs_fbp = ifp; fbop->fbo_fbs.fbs_listener.fbsl_fbsp = &fbop->fbo_fbs; fbop->fbo_fbs.fbs_listener.fbsl_fd = -1; fbop->fbo_fbs.fbs_listener.fbsl_port = -1; fbop->fbo_interp = interp; /* append to list of fb_obj's */ BU_LIST_APPEND(&HeadFBObj.l, &fbop->l); (void)Tcl_CreateCommand(interp, bu_vls_addr(&fbop->fbo_name), (Tcl_CmdProc *)fbo_cmd, (ClientData)fbop, fbo_deleteProc); /* Return new function name as result */ Tcl_ResetResult(interp); Tcl_AppendResult(interp, bu_vls_addr(&fbop->fbo_name), (char *)NULL); return BRLCAD_OK; }
static void usage(const char *argv0) { bu_log("Usage: %s [-f|t|m] [-v] [-s] [-xX lvl] [-a abs_tol] [-r rel_tol] [-n norm_tol] [-d dist_tol] [-P num_cpus] [-o output_file] brlcad_db.g object(s)\n", argv0); bu_log(" options:\n"); bu_log(" f - convert each region to faceted BREP before output\n"); bu_log(" t - produce a file of trimmed surfaces (experimental)\n"); bu_log(" m - produces a separate IGES file for each region, \n"); bu_log(" implies -t, -o gives directory for output IGES file\n"); bu_log(" s - produce NURBS for faces of any BREP objects\n"); bu_log(" v - verbose\n"); bu_log(" a - absolute tolerance for tessellation (mm)\n"); bu_log(" r - relative tolerance for tessellation\n"); bu_log(" n - normal tolerance for tessellation\n"); bu_log(" d - distance tolerance (mm) (minimum distance between distinct points)\n"); bu_log(" x - librt debug flag\n"); bu_log(" X - nmg debug flag\n"); bu_log(" o - file to receive IGES output (or directory when '-m' option is used)\n"); bu_log(" P - number of processors to use\n"); bu_log(" The f and t options are mutually exclusive. If neither is specified, \n"); bu_log(" the default output is a CSG file to the maximum extent possible\n"); bu_exit(1, NULL); }
int read_IR(FILE *fp) { register int fy; register int rx, ry; int min, max; if ( fread( (char *) &min, (int) sizeof(int), 1, fp ) != 1 || fread( (char *) &max, (int) sizeof(int), 1, fp ) != 1 ) { bu_log( "Can't read minimum and maximum temperatures.\n" ); return 0; } else { bu_log( "IR data temperature range is %d to %d\n", min, max ); if ( ir_min == ABSOLUTE_ZERO ) { /* Temperature range not set. */ ir_min = min; ir_max = max; } else { /* Merge with existing range. */ ir_min = Min( ir_min, min ); ir_max = Max( ir_max, max ); bu_log( "Global temperature range is %d to %d\n", ir_min, ir_max ); } (void) fflush( stdout ); } if ( ! init_Temp_To_RGB() ) { return 0; } for ( ry = 0, fy = grid_sz-1; ; ry += ir_aperture, fy-- ) { if ( fb_seek( fbiop, 0, fy ) == -1 ) { bu_log( "\"%s\"(%d) fb_seek to pixel <%d,%d> failed.\n", __FILE__, __LINE__, 0, fy ); return 0; } for ( rx = 0; rx < IR_DATA_WID; rx += ir_aperture ) { int fah; int sum = 0; register int i; register int lgtindex; RGBpixel *pixel; for ( i = 0; i < ir_aperture; i++ ) { register int j; for ( j = 0; j < ir_aperture; j++ ) { if ( get_IR( rx+j, ry+i, &fah, fp ) ) sum += fah < ir_min ? ir_min : fah; else /* EOF */ { if ( ir_octree.o_temp == ABSOLUTE_ZERO ) ir_octree.o_temp = AMBIENT - 1; display_Temps( grid_sz/8, 0 ); return 1; } } } fah = Avg_Fah( sum ); if ( (lgtindex = fah-ir_min) > ir_max_index || lgtindex < 0 ) { bu_log( "temperature out of range (%d)\n", fah ); return 0; } pixel = (RGBpixel *) ir_table[lgtindex]; (void) fb_wpixel( fbiop, (unsigned char *)pixel ); } } }
/** * Actually do the work of meshing two faces. * The two fu arguments may be the same, which causes the face to be * meshed against itself. * * The return is the number of edges meshed. */ int nmg_mesh_two_faces(register struct faceuse *fu1, register struct faceuse *fu2, const struct bn_tol *tol) { struct loopuse *lu1; struct loopuse *lu2; struct edgeuse *eu1; struct edgeuse *eu2; struct vertex *v1a, *v1b; struct edge *e1; pointp_t pt1, pt2; int count = 0; /* Visit all the loopuses in faceuse 1 */ for (BU_LIST_FOR(lu1, loopuse, &fu1->lu_hd)) { /* Ignore self-loops */ if (BU_LIST_FIRST_MAGIC(&lu1->down_hd) != NMG_EDGEUSE_MAGIC) continue; /* Visit all the edgeuses in loopuse1 */ for (BU_LIST_FOR(eu1, edgeuse, &lu1->down_hd)) { v1a = eu1->vu_p->v_p; v1b = eu1->eumate_p->vu_p->v_p; e1 = eu1->e_p; if (RTG.NMG_debug & DEBUG_MESH) { pt1 = v1a->vg_p->coord; pt2 = v1b->vg_p->coord; bu_log("ref_e=%8p v:%8p--%8p (%g, %g, %g)->(%g, %g, %g)\n", (void *)e1, (void *)v1a, (void *)v1b, V3ARGS(pt1), V3ARGS(pt2)); } /* Visit all the loopuses in faceuse2 */ for (BU_LIST_FOR(lu2, loopuse, &fu2->lu_hd)) { /* Ignore self-loops */ if (BU_LIST_FIRST_MAGIC(&lu2->down_hd) != NMG_EDGEUSE_MAGIC) continue; /* Visit all the edgeuses in loopuse2 */ for (BU_LIST_FOR(eu2, edgeuse, &lu2->down_hd)) { if (RTG.NMG_debug & DEBUG_MESH) { pt1 = eu2->vu_p->v_p->vg_p->coord; pt2 = eu2->eumate_p->vu_p->v_p->vg_p->coord; bu_log("\te:%8p v:%8p--%8p (%g, %g, %g)->(%g, %g, %g)\n", (void *)eu2->e_p, (void *)eu2->vu_p->v_p, (void *)eu2->eumate_p->vu_p->v_p, V3ARGS(pt1), V3ARGS(pt2)); } /* See if already shared */ if (eu2->e_p == e1) continue; if ((eu2->vu_p->v_p == v1a && eu2->eumate_p->vu_p->v_p == v1b) || (eu2->eumate_p->vu_p->v_p == v1a && eu2->vu_p->v_p == v1b)) { nmg_radial_join_eu(eu1, eu2, tol); count++; } } } } } return count; }
int f_IR_Model(register struct application *ap, Octree *op) { fastf_t octnt_min[3], octnt_max[3]; fastf_t delta = modl_radius / pow_Of_2( ap->a_level ); fastf_t point[3]; /* Intersection point. */ fastf_t norml[3]; /* Unit normal at point. */ /* Push ray origin along ray direction to intersection point. */ VJOIN1( point, ap->a_ray.r_pt, ap->a_uvec[0], ap->a_ray.r_dir ); /* Compute octant RPP. */ octnt_min[X] = op->o_points->c_point[X] - delta; octnt_min[Y] = op->o_points->c_point[Y] - delta; octnt_min[Z] = op->o_points->c_point[Z] - delta; octnt_max[X] = op->o_points->c_point[X] + delta; octnt_max[Y] = op->o_points->c_point[Y] + delta; octnt_max[Z] = op->o_points->c_point[Z] + delta; if ( AproxEq( point[X], octnt_min[X], EPSILON ) ) /* Intersection point lies on plane whose normal is the negative X-axis. */ { norml[X] = -1.0; norml[Y] = 0.0; norml[Z] = 0.0; } else if ( AproxEq( point[X], octnt_max[X], EPSILON ) ) /* Intersection point lies on plane whose normal is the positive X-axis. */ { norml[X] = 1.0; norml[Y] = 0.0; norml[Z] = 0.0; } else if ( AproxEq( point[Y], octnt_min[Y], EPSILON ) ) /* Intersection point lies on plane whose normal is the negative Y-axis. */ { norml[X] = 0.0; norml[Y] = -1.0; norml[Z] = 0.0; } else if ( AproxEq( point[Y], octnt_max[Y], EPSILON ) ) /* Intersection point lies on plane whose normal is the positive Y-axis. */ { norml[X] = 0.0; norml[Y] = 1.0; norml[Z] = 0.0; } else if ( AproxEq( point[Z], octnt_min[Z], EPSILON ) ) /* Intersection point lies on plane whose normal is the negative Z-axis. */ { norml[X] = 0.0; norml[Y] = 0.0; norml[Z] = -1.0; } else if ( AproxEq( point[Z], octnt_max[Z], EPSILON ) ) /* Intersection point lies on plane whose normal is the positive Z-axis. */ { norml[X] = 0.0; norml[Y] = 0.0; norml[Z] = 1.0; } { /* Factor in reflectance from "ambient" light source. */ fastf_t intensity = Dot( norml, lgts[0].dir ); /* Calculate index into false-color table. */ register int lgtindex = op->o_temp - ir_min; if ( lgtindex > ir_max_index ) { bu_log( "Temperature (%d) above range of data.\n", op->o_temp ); return -1; } if ( lgtindex < 0 ) /* Un-assigned octants get colored grey. */ ap->a_color[0] = ap->a_color[1] = ap->a_color[2] = intensity; else /* Lookup false-coloring for octant's temperature. */ { intensity *= RGB_INVERSE; ap->a_color[0] = (fastf_t) (ir_table[lgtindex][RED]) * intensity; ap->a_color[1] = (fastf_t) (ir_table[lgtindex][GRN]) * intensity; ap->a_color[2] = (fastf_t) (ir_table[lgtindex][BLU]) * intensity; } } return 1; }
/** * start up a server that listens for a single client. */ void run_server(int port) { struct pkg_conn *client; int netfd; char portname[MAX_DIGITS + 1] = {0}; /* int pkg_result = 0; */ char *buffer, *msgbuffer; long bytes = 0; FILE *fp; /** our server callbacks for each message type */ struct pkg_switch callbacks[] = { {MSG_HELO, server_helo, "HELO", NULL}, {MSG_DATA, server_data, "DATA", NULL}, {MSG_CIAO, server_ciao, "CIAO", NULL}, {0, 0, (char *)0, (void*)0} }; validate_port(port); /* start up the server on the given port */ snprintf(portname, MAX_DIGITS, "%d", port); netfd = pkg_permserver(portname, "tcp", 0, 0); if (netfd < 0) { bu_bomb("Unable to start the server"); } /* listen for a good client indefinitely. this is a simple * handshake that waits for a HELO message from the client. if it * doesn't get one, the server continues to wait. */ do { client = pkg_getclient(netfd, callbacks, NULL, 0); if (client == PKC_NULL) { bu_log("Connection seems to be busy, waiting...\n"); sleep(10); continue; } else if (client == PKC_ERROR) { bu_log("Fatal error accepting client connection.\n"); pkg_close(client); client = PKC_NULL; continue; } /* got a connection, process it */ msgbuffer = pkg_bwaitfor (MSG_HELO, client); if (msgbuffer == NULL) { bu_log("Failed to process the client connection, still waiting\n"); pkg_close(client); client = PKC_NULL; } else { bu_log("msgbuffer: %s\n", msgbuffer); /* validate magic header that client should have sent */ if (!BU_STR_EQUAL(msgbuffer, MAGIC_ID)) { bu_log("Bizarre corruption, received a HELO without at matching MAGIC ID!\n"); pkg_close(client); client = PKC_NULL; } } } while (client == PKC_NULL); /* have client, will send file */ fp = fopen("lempar.c", "rb"); buffer = (char *)bu_calloc(2048, 1, "buffer allocation"); if (fp == NULL) { bu_log("Unable to open lempar.c\n"); bu_bomb("Unable to read file\n"); } /* send the file data to the server */ while (!feof(fp) && !ferror(fp)) { bytes = fread(buffer, 1, 2048, fp); bu_log("Read %ld bytes from lempar.c\n", bytes); if (bytes > 0) { bytes = pkg_send(MSG_DATA, buffer, (size_t)bytes, client); if (bytes < 0) { pkg_close(client); bu_log("Unable to successfully send data"); bu_free(buffer, "buffer release"); return; } } } /* Tell the client we're done */ bytes = pkg_send(MSG_CIAO, "DONE", 5, client); if (bytes < 0) { bu_log("Connection to client seems faulty.\n"); } /* Confirm the client is done */ buffer = pkg_bwaitfor (MSG_CIAO , client); bu_log("buffer: %s\n", buffer); /* shut down the server, one-time use */ pkg_close(client); }
void display_Temps(int xmin, int ymin) { register int x, y; register int interval = ((grid_sz*3+2)/4)/(S_BINS+2); register int xmax = xmin+(interval*S_BINS); register int ymax; fastf_t xrange = xmax - xmin; /* Avoid page thrashing of frame buffer. */ ymin = adjust_Page( ymin ); ymax = ymin + interval; /* Initialize ir_table if necessary. */ if ( ! ir_Chk_Table() ) return; for ( y = ymin; y <= ymax; y++ ) { x = xmin; if ( fb_seek( fbiop, x, y ) == -1 ) { bu_log( "\"%s\"(%d) fb_seek to pixel <%d,%d> failed.\n", __FILE__, __LINE__, x, y ); return; } for (; x <= xmax + interval; x++ ) { fastf_t percent; static RGBpixel *pixel; percent = D_XPOS / xrange; if ( D_XPOS % interval == 0 ) { int temp = AMBIENT+percent*RANGE; register int lgtindex = temp - ir_min; pixel = (RGBpixel *) ir_table[Min(lgtindex, ir_max_index)]; /* this should be an &ir_table..., allowed by ANSI C, but not K&R compilers. */ (void) fb_wpixel( fbiop, (unsigned char *) black ); } else { (void) fb_wpixel( fbiop, (unsigned char *) pixel ); } } } font = get_font( (char *) NULL, bu_log ); if ( font.ffdes == NULL ) { bu_log( "Could not load font.\n" ); fb_flush( fbiop ); return; } y = ymin; for ( x = xmin; x <= xmax; x += interval ) { char tempstr[4]; fastf_t percent = D_XPOS / xrange; int temp = AMBIENT+percent*RANGE; int shrinkfactor = fb_getwidth( fbiop )/grid_sz; (void) sprintf( tempstr, "%3d", temp ); do_line( x+2, y+(interval-(12/shrinkfactor))/2, tempstr /*, shrinkfactor*/ ); } fb_flush( fbiop ); return; }
/** * callback when a DATA message packet is received */ void server_data(struct pkg_conn *UNUSED(connection), char *buf) { bu_log("Received file data\n"); free(buf); }
int make_hole_in_prepped_regions(struct rt_wdb *wdbp, /* database to be modified */ struct rt_i *rtip, /* rt_i pointer for the same database */ point_t hole_start, /* center of start of hole */ vect_t hole_depth, /* depth and direction of hole */ fastf_t radius, /* radius of hole */ struct bu_ptbl *regions) /* list of region structures to which this hole * is to be applied */ { struct bu_vls tmp_name = BU_VLS_INIT_ZERO; size_t i, base_len, count=0; struct directory *dp; struct rt_db_internal intern; struct soltab *stp; RT_CHECK_WDB(wdbp); /* make a unique name for the RCC we will use (of the form "make_hole_%d") */ bu_vls_strcat(&tmp_name, "make_hole_"); base_len = bu_vls_strlen(&tmp_name); bu_vls_strcat(&tmp_name, "0"); while ((db_lookup(wdbp->dbip, bu_vls_addr(&tmp_name), LOOKUP_QUIET)) != RT_DIR_NULL) { count++; bu_vls_trunc(&tmp_name, base_len); bu_vls_printf(&tmp_name, "%zu", count); } /* build the RCC based on parameters passed in */ if (mk_rcc(wdbp, bu_vls_addr(&tmp_name), hole_start, hole_depth, radius)) { bu_log("Failed to create hole cylinder!!!\n"); bu_vls_free(&tmp_name); return 2; } /* lookup the newly created RCC */ dp=db_lookup(wdbp->dbip, bu_vls_addr(&tmp_name), LOOKUP_QUIET); if (dp == RT_DIR_NULL) { bu_log("Failed to lookup RCC (%s) just made by make_hole_in_prepped_regions()!!!\n", bu_vls_addr(&tmp_name)); bu_bomb("Failed to lookup RCC just made by make_hole_in_prepped_regions()!!!\n"); } /* get the internal form of the new RCC */ if (rt_db_get_internal(&intern, dp, wdbp->dbip, NULL, wdbp->wdb_resp) < 0) { bu_log("Failed to get internal form of RCC (%s) just made by make_hole_in_prepped_regions()!!!\n", bu_vls_addr(&tmp_name)); bu_bomb("Failed to get internal form of RCC just made by make_hole_in_prepped_regions()!!!\n"); } /* Build a soltab structure for the new RCC */ BU_ALLOC(stp, struct soltab); stp->l.magic = RT_SOLTAB_MAGIC; stp->l2.magic = RT_SOLTAB2_MAGIC; stp->st_uses = 1; stp->st_dp = dp; stp->st_bit = rtip->nsolids++; /* Add the new soltab structure to the rt_i structure */ rtip->rti_Solids = (struct soltab **)bu_realloc(rtip->rti_Solids, rtip->nsolids * sizeof(struct soltab *), "new rti_Solids"); rtip->rti_Solids[stp->st_bit] = stp; /* actually prep the new RCC */ if (intern.idb_meth->ft_prep(stp, &intern, rtip)) { bu_log("Failed to prep RCC (%s) just made by make_hole_in_prepped_regions()!!!\n", bu_vls_addr(&tmp_name)); bu_bomb("Failed to prep RCC just made by make_hole_in_prepped_regions()!!!\n"); } /* initialize the soltabs list of containing regions */ bu_ptbl_init(&stp->st_regions, BU_PTBL_LEN(regions), "stp->st_regions"); /* Subtract the new RCC from each region structure in the list provided */ for (i=0; i<BU_PTBL_LEN(regions); i++) { struct region *rp; union tree *treep; /* get the next region structure */ rp = (struct region *)BU_PTBL_GET(regions, i); RT_CK_REGION(rp); /* create a tree node for the subtraction operation, this will be the new tree root */ BU_ALLOC(treep, union tree); RT_TREE_INIT(treep); treep->tr_b.tb_op = OP_SUBTRACT; treep->tr_b.tb_left = rp->reg_treetop; /* subtract from the old treetop */ treep->tr_b.tb_regionp = rp; /* make the new node the new treetop */ rp->reg_treetop = treep; /* create a tree node for the new RCC */ BU_ALLOC(treep, union tree); RT_TREE_INIT(treep); treep->tr_a.tu_op = OP_SOLID; treep->tr_a.tu_stp = stp; treep->tr_a.tu_regionp = rp; /* the new RCC gets hung on the right of the subtract node */ rp->reg_treetop->tr_b.tb_right = treep; /* make sure the "all unions" flag is not set on this region */ rp->reg_all_unions = 0; /* Add this region to the list of containing regions for the new RCC */ bu_ptbl_ins(&stp->st_regions, (long *)rp); } /* insert the new RCC soltab structure into the already existing space partitioning tree */ insert_in_bsp(stp, &rtip->rti_CutHead); return 0; }
int main(int argc, char **argv) { struct directory *dp; if (argc != 3 && argc != 4) { bu_exit(1, "Usage:\n\t%s [-v] input.g output.g\n", argv[0]); } if (argc == 4) { if (BU_STR_EQUAL(argv[1], "-v")) verbose = 1; else { bu_log("Illegal option: %s\n", argv[1]); bu_exit(1, "Usage:\n\t%s [-v] input.g output.g\n", argv[0]); } } rt_init_resource(&rt_uniresource, 0, NULL); dbip = db_open(argv[argc-2], DB_OPEN_READONLY); if (dbip == DBI_NULL) { perror(argv[0]); bu_exit(1, "Cannot open geometry database file (%s)\n", argv[argc-2]); } if ((fdout=wdb_fopen(argv[argc-1])) == NULL) { perror(argv[0]); bu_exit(1, "Cannot open file (%s)\n", argv[argc-1]); } if (db_dirbuild(dbip)) { bu_exit(1, "db_dirbuild failed\n"); } /* Visit all records in input database, and spew them out, * modifying NMG objects into BoTs. */ FOR_ALL_DIRECTORY_START(dp, dbip) { struct rt_db_internal intern; int id; int ret; id = rt_db_get_internal(&intern, dp, dbip, NULL, &rt_uniresource); if (id < 0) { fprintf(stderr, "%s: rt_db_get_internal(%s) failure, skipping\n", argv[0], dp->d_namep); continue; } if (id == ID_NMG) { nmg_conv(&intern, dp->d_namep); } else { ret = wdb_put_internal(fdout, dp->d_namep, &intern, 1.0); if (ret < 0) { fprintf(stderr, "%s: wdb_put_internal(%s) failure, skipping\n", argv[0], dp->d_namep); rt_db_free_internal(&intern); continue; } } rt_db_free_internal(&intern); } FOR_ALL_DIRECTORY_END wdb_close(fdout); return 0; }
int main (int argc, char **argv) { char *inf_name; int ch; int i; int nm_sites; int normalize = 0; /* Make all weights sum to one? */ fastf_t *coeff; FILE *infp = NULL; struct bu_list site_list; struct bu_vls *tail_buf = 0; struct site *sp; /* intentionally double for scan */ double x, y, z; BU_LIST_INIT(&site_list); while ((ch = bu_getopt(argc, argv, OPT_STRING)) != -1) switch (ch) { case 'n': normalize = 1; break; case 's': if (sscanf(bu_optarg, "%lf %lf %lf", &x, &y, &z) != 3) { bu_log("Illegal site: '%s'\n", bu_optarg); print_usage(); } enqueue_site(&site_list, x, y, z); break; case 't': if (tail_buf == 0) /* Only initialize it once */ tail_buf = bu_vls_vlsinit(); break; case '?': default: print_usage(); } switch (argc - bu_optind) { case 0: infp = stdin; break; case 1: inf_name = argv[bu_optind++]; if ((infp = fopen(inf_name, "r")) == NULL) bu_exit (1, "Cannot open file '%s'\n", inf_name); break; default: print_usage(); } if (BU_LIST_IS_EMPTY(&site_list)) { enqueue_site(&site_list, (fastf_t) 1.0, (fastf_t) 0.0, (fastf_t) 0.0); enqueue_site(&site_list, (fastf_t) 0.0, (fastf_t) 1.0, (fastf_t) 0.0); enqueue_site(&site_list, (fastf_t) 0.0, (fastf_t) 0.0, (fastf_t) 1.0); } nm_sites = 0; for (BU_LIST_FOR(sp, site, &site_list)) ++nm_sites; coeff = (fastf_t *) bu_malloc(nm_sites * sizeof(fastf_t), "coefficient array"); while (read_point(infp, coeff, nm_sites, normalize, tail_buf) != EOF) { x = y = z = 0.0; i = 0; for (BU_LIST_FOR(sp, site, &site_list)) { x += sp->s_x * coeff[i]; y += sp->s_y * coeff[i]; z += sp->s_z * coeff[i]; ++i; } bu_flog(stdout, "%g %g %g", x, y, z); if (tail_buf) bu_flog(stdout, "%s", bu_vls_addr(tail_buf)); bu_flog(stdout, "\n"); } return 0; }