Example #1
0
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);
}
Example #2
0
/**
 * 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);
}
Example #3
0
/**
 * 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);
}
Example #4
0
/**
 * 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;
}
Example #6
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;
}
Example #7
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");

}
Example #8
0
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;
}
Example #9
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;
}
Example #10
0
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");
}
Example #11
0
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;
}
Example #13
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;
}
Example #14
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;
}
Example #15
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;
}
Example #16
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;
}
Example #17
0
/**
 * 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);
	}
    }
}
Example #18
0
/*
 *
 * 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;
}
Example #19
0
/*
 * 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;
}
Example #20
0
/*
 * 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;
}
Example #21
0
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);
}
Example #22
0
File: ir.c Project: cciechad/brlcad
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 );
	}
    }
}
Example #23
0
/**
 * 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;
}
Example #24
0
File: ir.c Project: cciechad/brlcad
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;
}
Example #25
0
/**
 * 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);
}
Example #26
0
File: ir.c Project: cciechad/brlcad
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;
}
Example #27
0
/**
 * 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);
}
Example #28
0
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;
}
Example #29
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;
}
Example #30
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;
}