Esempio n. 1
0
// static
void VStream::copyMemory(Vu8* toBuffer, const Vu8* fromBuffer, Vs64 numBytesToCopy) {
    /*
    The purpose of this function is simply to allow the full 64-bit length
    while remaining compatible with platforms where memcpy() only
    supports a 32-bit length. It's not just a matter of type conversion,
    because if the requested length actually exceeds size_t, then
    we must copy in a loop. (Very unlikely to actually occur in real-world
    scenarios, but we may as well do it correctly.)
    We do make one assumption: that size_t is at least 31 bits, that is
    that it can hold a number up to at least V_MAX_S32.
    If Vs64 and size_t are identical, or we're copying less than 2GB of data,
    then memcpy is fine!
    */

    if (! VStream::needSizeConversion(numBytesToCopy)) {
        // Entire copy can occur in a single call to memcpy.
        ::memcpy(toBuffer, fromBuffer, static_cast<size_t>(numBytesToCopy));
    } else {
        // Need to call memcpy multiple times because numBytesToCopy is too big.
        Vs64    numBytesRemaining = numBytesToCopy;
        size_t  copyChunkSize;
        Vu8*    toPtr = toBuffer;
        const Vu8* fromPtr = fromBuffer;

        do {
            copyChunkSize = static_cast<size_t>(V_MIN(V_MAX_S32, numBytesRemaining));

            ::memcpy(toPtr, fromPtr, copyChunkSize);

            numBytesRemaining -= copyChunkSize;
            fromPtr += copyChunkSize;
            toPtr += copyChunkSize;

        } while (numBytesRemaining > 0);
    }
}
Esempio n. 2
0
int
read_IR(FILE *fp)
{
    int fy;
    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.			*/
	    V_MIN(ir_min, min);
	    V_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;
	    int i;
	    int lgtindex;
	    RGBpixel *pixel;
	    for (i = 0; i < ir_aperture; i++) {
		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);
	}
    }
}
Esempio n. 3
0
/* Calculate bounding box of an object */
int
fig_calc_bbox(vhash *object)
{
    int i, num, xmin, xmax, ymin, ymax, x, y, justify, count = 0;
    int type, bxmin, bxmax, bymin, bymax, width, height;
    vlist *objects, *xp, *yp;
    vhash *obj, *figure;
    float fontsize;
    viter iter;
    char *text;

    type = vh_iget(object, "TYPE");

    switch (type) {

    case FIG_ROOT:
    case FIG_COMPOUND:
        if ((objects = vh_pget(object, "OBJECTS")) == NULL)
            return 0;

        v_iterate(objects, iter) {
            obj = vl_iter_pval(iter);
            if (!fig_calc_bbox(obj))
                continue;

            xmin = vh_iget(obj, "XMIN");
            xmax = vh_iget(obj, "XMAX");
            ymin = vh_iget(obj, "YMIN");
            ymax = vh_iget(obj, "YMAX");

            if (count++ == 0) {
                bxmin = xmin;
                bxmax = xmax;
                bymin = ymin;
                bymax = ymax;
            } else {
                bxmin = V_MIN(xmin, bxmin);
                bxmax = V_MAX(xmax, bxmax);
                bymin = V_MIN(ymin, bymin);
                bymax = V_MAX(ymax, bymax);
            }
        }

        break;

    case FIG_TEXT:
        x = vh_iget(object, "X");
        y = vh_iget(object, "Y");

        figure = fig_get_figure(object);
        fontsize = fig_get_fval(object, "FONTSIZE");

        text = fig_get_sval(object, "TEXT");
        width = fig_get_width(figure, fontsize) * strlen(text);
        height = fig_get_height(figure, fontsize);
        justify = fig_get_ival(object, "JUSTIFY");

        vh_fstore(object, "WIDTH", width);
        vh_fstore(object, "HEIGHT", height);

        switch (justify) {
        case FIG_JUSTIFY_LEFT:
            bxmin = x;
            bxmax = x + width;
            break;
        case FIG_JUSTIFY_CENTRE:
            bxmin = x - width / 2;
            bxmax = x + width / 2;
            break;
        case FIG_JUSTIFY_RIGHT:
            bxmin = x - width;
            bxmax = x;
            break;
        }

        bymin = y - height;
        bymax = y;
        break;

    default:
        if ((xp = vh_pget(object, "XP")) == NULL)
            return 0;

        if ((yp = vh_pget(object, "YP")) == NULL)
            return 0;

        num = vl_length(xp);
        for (i = 0; i < num; i++) {
            x = vl_iget(xp, i);
            y = vl_iget(yp, i);

            if (count++ == 0) {
                bxmin = bxmax = x;
                bymin = bymax = y;
            } else {
                bxmin = V_MIN(x, bxmin);
                bxmax = V_MAX(x, bxmax);
                bymin = V_MIN(y, bymin);
                bymax = V_MAX(y, bymax);
            }
        }

        break;
    }
int
Getcurve(int curve, struct ptlist **curv_pts)
{
    int type;
    int npts = 0;
    int i, j;
    double pi;
    struct ptlist *ptr, *prev;

    pi = atan2(0.0, -1.0);

    (*curv_pts) = NULL;
    prev = NULL;

    switch (dir[curve]->type) {
	case 110: {
	    /* line */
	    point_t pt1;

	    Readrec(dir[curve]->param);
	    Readint(&type, "");
	    if (type != dir[curve]->type) {
		bu_log("Error in Getcurve, looking for curve type %d, found %d\n" ,
		       dir[curve]->type, type);
		npts = 0;
		break;
	    }

	    BU_ALLOC((*curv_pts), struct ptlist);
	    ptr = (*curv_pts);

	    /* Read first point */
	    for (i = 0; i < 3; i++)
		Readcnv(&pt1[i], "");
	    MAT4X3PNT(ptr->pt, *dir[curve]->rot, pt1);

	    ptr->prev = NULL;
	    prev = ptr;

	    BU_ALLOC(ptr->next, struct ptlist);
	    ptr = ptr->next;

	    /* Read second point */
	    for (i = 0; i < 3; i++)
		Readcnv(&pt1[i], "");
	    MAT4X3PNT(ptr->pt, *dir[curve]->rot, pt1);
	    ptr->next = NULL;
	    ptr->prev = prev;

	    npts = 2;
	    break;
	}
	case 100: {
	    /* circular arc */
	    point_t center, start, stop, tmp;
	    fastf_t common_z, ang1, ang2, delta;
	    double cosdel, sindel, rx, ry;

	    delta = (2.0*pi)/ARCSEGS;

	    Readrec(dir[curve]->param);
	    Readint(&type, "");
	    if (type != dir[curve]->type) {
		bu_log("Error in Getcurve, looking for curve type %d, found %d\n" ,
		       dir[curve]->type, type);
		npts = 0;
		break;
	    }

	    /* Read common Z coordinate */
	    Readcnv(&common_z, "");

	    /* Read center point */
	    Readcnv(&center[X], "");
	    Readcnv(&center[Y], "");
	    center[Z] = common_z;

	    /* Read start point */
	    Readcnv(&start[X], "");
	    Readcnv(&start[Y], "");
	    start[Z] = common_z;

	    /* Read stop point */
	    Readcnv(&stop[X], "");
	    Readcnv(&stop[Y], "");
	    stop[Z] = common_z;

	    ang1 = atan2(start[Y] - center[Y], start[X] - center[X]);
	    ang2 = atan2(stop[Y] - center[Y], stop[X] - center[X]);
	    while (ang2 <= ang1)
		ang2 += (2.0*pi);

	    npts = (ang2 - ang1)/delta;
	    npts++;
	    V_MAX(npts, 3);

	    delta = (ang2 - ang1)/(npts-1);
	    cosdel = cos(delta);
	    sindel = sin(delta);

	    /* Calculate points on curve */
	    BU_ALLOC((*curv_pts), struct ptlist);
	    ptr = (*curv_pts);
	    prev = NULL;

	    MAT4X3PNT(ptr->pt, *dir[curve]->rot, start);

	    ptr->prev = prev;
	    prev = ptr;

	    BU_ALLOC(ptr->next, struct ptlist);
	    ptr = ptr->next;
	    ptr->prev = prev;

	    VMOVE(tmp, start);
	    for (i = 1; i < npts; i++) {
		rx = tmp[X] - center[X];
		ry = tmp[Y] - center[Y];
		tmp[X] = center[X] + rx*cosdel - ry*sindel;
		tmp[Y] = center[Y] + rx*sindel + ry*cosdel;
		MAT4X3PNT(ptr->pt, *dir[curve]->rot, tmp);
		prev = ptr;

		BU_ALLOC(ptr->next, struct ptlist);
		ptr = ptr->next;
		ptr->prev = prev;
	    }
	    ptr = prev;
	    bu_free((char *)ptr->next, "Getcurve: ptr->next");
	    ptr->next = NULL;
	    break;
	}
	case 106: {
	    /* copius data */
	    int interpflag;	/* interpretation flag
				   1 => x, y pairs (common z-coord)
				   2 => x, y, z coords
				   3 => x, y, z coords and i, j, k vectors */
	    int ntuples;	/* number of points */
	    fastf_t common_z;	/* common z-coordinate */
	    point_t pt1;		/* temporary storage for incoming point */

	    Readrec(dir[curve]->param);
	    Readint(&type, "");
	    if (type != dir[curve]->type) {
		bu_log("Error in Getcurve, looking for curve type %d, found %d\n" ,
		       dir[curve]->type, type);
		npts = 0;
		break;
	    }

	    Readint(&interpflag, "");
	    Readint(&ntuples, "");

	    switch (dir[curve]->form) {
		case 1:
		case 11:
		case 40:
		case 63: {
		    /* data are coordinate pairs with common z */
		    if (interpflag != 1) {
			bu_log("Error in Getcurve for copius data entity D%07d, IP=%d, should be 1\n",
			       dir[curve]->direct, interpflag);
			npts = 0;
			break;
		    }
		    Readcnv(&common_z, "");

		    BU_ALLOC((*curv_pts), struct ptlist);
		    ptr = (*curv_pts);
		    ptr->prev = NULL;

		    for (i = 0; i < ntuples; i++) {
			Readcnv(&pt1[X], "");
			Readcnv(&pt1[Y], "");
			pt1[Z] = common_z;
			MAT4X3PNT(ptr->pt, *dir[curve]->rot, pt1);
			prev = ptr;

			BU_ALLOC(ptr->next, struct ptlist);
			ptr = ptr->next;
			ptr->prev = prev;
			ptr->next = NULL;
		    }
		    ptr = ptr->prev;
		    bu_free((char *)ptr->next, "Getcurve: ptr->next");
		    ptr->next = NULL;
		    npts = ntuples;
		    break;
		}
		case 2:
		case 12: {
		    /* data are coordinate triples */
		    if (interpflag != 2) {
			bu_log("Error in Getcurve for copius data entity D%07d, IP=%d, should be 2\n",
			       dir[curve]->direct, interpflag);
			npts = 0;
			break;
		    }
		    BU_ALLOC((*curv_pts), struct ptlist);
		    ptr = (*curv_pts);
		    ptr->prev = NULL;

		    for (i = 0; i < ntuples; i++) {
			Readcnv(&pt1[X], "");
			Readcnv(&pt1[Y], "");
			Readcnv(&pt1[Z], "");
			MAT4X3PNT(ptr->pt, *dir[curve]->rot, pt1);
			prev = ptr;

			BU_ALLOC(ptr->next, struct ptlist);
			ptr = ptr->next;
			ptr->prev = prev;
		    }
		    ptr = ptr->prev;
		    bu_free((char *)ptr->next, "Getcurve: ptr->next");
		    ptr->next = NULL;
		    npts = ntuples;
		    break;
		}
		default: {
		    bu_log("Error in Getcurve for copius data entity D%07d, form %d is not a legal choice\n",
			   dir[curve]->direct, dir[curve]->form);
		    npts = 0;
		    break;
		}
	    }
	    break;
	}
	case 112: {
	    /* parametric spline */
	    struct spline *splroot;
	    struct segment *seg, *seg1;
	    vect_t tmp;
	    double a;

	    Readrec(dir[curve]->param);
	    Readint(&type, "");
	    if (type != dir[curve]->type) {
		bu_log("Error in Getcurve, looking for curve type %d, found %d\n" ,
		       dir[curve]->type, type);
		npts = 0;
		break;
	    }
	    Readint(&i, "");	/* Skip over type */
	    Readint(&i, "");	/* Skip over continuity */

	    BU_ALLOC(splroot, struct spline);
	    splroot->start = NULL;

	    Readint(&splroot->ndim, ""); /* 2->planar, 3->3d */
	    Readint(&splroot->nsegs, ""); /* Number of segments */
	    Readdbl(&a, "");	/* first breakpoint */

	    /* start a linked list of segments */
	    seg = splroot->start;
	    for (i = 0; i < splroot->nsegs; i++) {
		if (seg == NULL) {
		    BU_ALLOC(seg, struct segment);
		    splroot->start = seg;
		} else {
		    BU_ALLOC(seg->next, struct segment);
		    seg = seg->next;
		}
		seg->segno = i+1;
		seg->next = NULL;
		seg->tmin = a; /* set minimum T for this segment */
		Readflt(&seg->tmax, ""); /* get maximum T for segment */
		a = seg->tmax;
	    }

	    /* read coefficients for polynomials */
	    seg = splroot->start;
	    for (i = 0; i < splroot->nsegs; i++) {
		for (j = 0; j < 4; j++)
		    Readflt(&seg->cx[j], ""); /* x coeff's */
		for (j = 0; j < 4; j++)
		    Readflt(&seg->cy[j], ""); /* y coeff's */
		for (j = 0; j < 4; j++)
		    Readflt(&seg->cz[j], ""); /* z coeff's */
		seg = seg->next;
	    }

	    /* Calculate points */

	    BU_ALLOC((*curv_pts), struct ptlist);
	    ptr = (*curv_pts);
	    prev = NULL;
	    ptr->prev = NULL;

	    npts = 0;
	    seg = splroot->start;
	    while (seg != NULL) {
		/* plot 9 points per segment (This should
		   be replaced by some logic) */
		for (i = 0; i < 9; i++) {
		    a = (fastf_t)i/(8.0)*(seg->tmax-seg->tmin);
		    tmp[0] = splinef(seg->cx, a);
		    tmp[1] = splinef(seg->cy, a);
		    if (splroot->ndim == 3)
			tmp[2] = splinef(seg->cz, a);
		    else
			tmp[2] = seg->cz[0];
		    MAT4X3PNT(ptr->pt, *dir[curve]->rot, tmp);
		    for (j = 0; j < 3; j++)
			ptr->pt[j] *= conv_factor;
		    npts++;
		    prev = ptr;

		    BU_ALLOC(ptr->next, struct ptlist);
		    ptr = ptr->next;
		    ptr->prev = prev;
		}
		seg = seg->next;
	    }
	    ptr = ptr->prev;
	    bu_free((char *)ptr->next, "Getcurve: ptr->next");
	    ptr->next = NULL;

	    /* free the used memory */
	    seg = splroot->start;
	    while (seg != NULL) {
		seg1 = seg;
		seg = seg->next;
		bu_free((char *)seg1, "Getcurve: seg1");
	    }
	    bu_free((char *)splroot, "Getcurve: splroot");
	    splroot = NULL;

	    break;
	}
	case 104: {
	    /* conic arc */
	    double A, B, C, D, E, F, a, b, c, del, I, theta, dpi, t1, t2, xc, yc;
	    point_t v1, v2, tmp;
	    mat_t rot1;
	    int num_points;

	    Readrec(dir[curve]->param);
	    Readint(&type, "");
	    if (type != dir[curve]->type) {
		bu_log("Error in Getcurve, looking for curve type %d, found %d\n" ,
		       dir[curve]->type, type);
		npts = 0;
		break;
	    }

	    /* read coefficients */
	    Readdbl(&A, "");
	    Readdbl(&B, "");
	    Readdbl(&C, "");
	    Readdbl(&D, "");
	    Readdbl(&E, "");
	    Readdbl(&F, "");

	    /* read common z-coordinate */
	    Readflt(&v1[2], "");
	    v2[2] = v1[2];

	    /* read start point */
	    Readflt(&v1[0], "");
	    Readflt(&v1[1], "");

	    /* read terminate point */
	    Readflt(&v2[0], "");
	    Readflt(&v2[1], "");

	    type = 0;
	    if (dir[curve]->form == 1) {
		/* Ellipse */
		if (fabs(E) < SMALL)
		    E = 0.0;
		if (fabs(B) < SMALL)
		    B = 0.0;
		if (fabs(D) < SMALL)
		    D = 0.0;

		if (ZERO(B) && ZERO(D) && ZERO(E))
		    type = 1;
		else
		    bu_log("Entity #%d is an incorrectly formatted ellipse\n", curve);
	    }

	    /* make coeff of X**2 equal to 1.0 */
	    a = A*C - B*B/4.0;
	    if (fabs(a) < 1.0  && fabs(a) > TOL) {
		a = fabs(A);
		if (fabs(B) < a && !ZERO(B))
		    a = fabs(B);
		V_MIN(a, fabs(C));

		A = A/a;
		B = B/a;
		C = C/a;
		D = D/a;
		E = E/a;
		F = F/a;
		a = A*C - B*B/4.0;
	    }

	    if (!type) {
		/* check for type of conic */
		del = A*(C*F-E*E/4.0)-0.5*B*(B*F/2.0-D*E/4.0)+0.5*D*(B*E/4.0-C*D/2.0);
		I = A+C;
		if (ZERO(del)) {
		    /* not a conic */
		    bu_log("Entity #%d, claims to be conic arc, but isn't\n", curve);
		    break;
		} else if (a > 0.0 && del*I < 0.0)
		    type = 1; /* ellipse */
		else if (a < 0.0)
		    type = 2; /* hyperbola */
		else if (ZERO(a))
		    type = 3; /* parabola */
		else {
		    /* imaginary ellipse */
		    bu_log("Entity #%d is an imaginary ellipse!!\n", curve);
		    break;
		}
	    }

	    switch (type) {

		double p, r1;

		case 3:	/* parabola */

			/* make A+C == 1.0 */
		    if (!EQUAL(A+C, 1.0)) {
			b = A+C;
			A = A/b;
			B = B/b;
			C = C/b;
			D = D/b;
			E = E/b;
			F = F/b;
		    }

		    /* theta is the angle that the parabola axis is rotated
		       about the origin from the x-axis */
		    theta = 0.5*atan2(B, C-A);

		    /* p is the distance from vertex to directrix */
		    p = (-E*sin(theta) - D*cos(theta))/4.0;
		    if (fabs(p) < TOL) {
			bu_log("Cannot plot entity %d, p=%g\n", curve, p);
			break;
		    }

		    /* calculate vertex (xc, yc). This is based on the
		       parametric representation:
		       x = xc + a*t*t*cos(theta) - t*sin(theta)
		       y = yc + a*t*t*sin(theta) + t*cos(theta)
		       and the fact that v1 and v2 are on the curve
		    */
		    a = 1.0/(4.0*p);
		    b = ((v1[0]-v2[0])*cos(theta) + (v1[1]-v2[1])*sin(theta))/a;
		    c = ((v1[1]-v2[1])*cos(theta) - (v1[0]-v2[0])*sin(theta));
		    if (fabs(c) < TOL*TOL) {
			bu_log("Cannot plot entity %d\n", curve);
			break;
		    }
		    b = b/c;
		    t1 = (b + c)/2.0; /* value of 't' at v1 */
		    t2 = (b - c)/2.0; /* value of 't' at v2 */
		    xc = v1[0] - a*t1*t1*cos(theta) + t1*sin(theta);
		    yc = v1[1] - a*t1*t1*sin(theta) - t1*cos(theta);

		    /* Calculate points */

		    BU_ALLOC((*curv_pts), struct ptlist);
		    ptr = (*curv_pts);
		    ptr->prev = NULL;
		    prev = NULL;

		    npts = 0;
		    num_points = ARCSEGS+1;
		    dpi = (t2-t1)/(double)num_points; /* parameter increment */

		    /* start point */
		    VSET(tmp, xc, yc, v1[2]);
		    MAT4X3PNT(ptr->pt, *dir[curve]->rot, tmp);
		    VSCALE(ptr->pt, ptr->pt, conv_factor);
		    npts++;
		    prev = ptr;

		    BU_ALLOC(ptr->next, struct ptlist);
		    ptr = ptr->next;
		    ptr->prev = prev;

		    /* middle points */
		    b = cos(theta);
		    c = sin(theta);
		    for (i = 1; i < num_points-1; i++) {
			r1 = t1 + dpi*i;
			tmp[0] = xc + a*r1*r1*b - r1*c;
			tmp[1] = yc + a*r1*r1*c + r1*b;
			MAT4X3PNT(ptr->pt, *dir[curve]->rot, tmp);
			VSCALE(ptr->pt, ptr->pt, conv_factor);
			npts++;
			prev = ptr;

			BU_ALLOC(ptr->next, struct ptlist);
			ptr = ptr->next;
			ptr->prev = prev;
		    }

		    /* plot terminate point */
		    tmp[0] = v2[0];
		    tmp[1] = v2[1];
		    MAT4X3PNT(ptr->pt, *dir[curve]->rot, tmp);
		    for (j = 0; j < 3; j++)
			ptr->pt[j] *= conv_factor;
		    npts++;
		    ptr->next = NULL;
		    break;

		case 1:	/* ellipse */
		case 2: {
		    /* hyperbola */
		    double A1, C1, F1, alpha, beta;
		    mat_t rot2;
		    point_t v3;

		    /* calculate center of ellipse or hyperbola */
		    xc = (B*E/4.0 - D*C/2.0)/a;
		    yc = (B*D/4.0 - A*E/2.0)/a;

		    /* theta is angle that the curve axis is rotated about
		       the origin from the x-axis */
		    if (!ZERO(B))
			theta = 0.5*atan2(B, A-C);
		    else
			theta = 0.0;

		    /* calculate coeff's for same curve, but with
		       vertex at origin and theta = 0.0 */
		    A1 = A + 0.5*B*tan(theta);
		    C1 = C - 0.5*B*tan(theta);
		    F1 = F - A*xc*xc - B*xc*yc - C*yc*yc;


		    if (type == 2 && F1/A1 > 0.0)
			theta += pi/2.0;

		    /* set-up matrix to translate and rotate
		       the start and terminate points to match
		       the simpler curve (A1, C1, and F1 coeff's)	*/

		    for (i = 0; i < 16; i++)
			rot1[i] = idn[i];
		    MAT_DELTAS(rot1, -xc, -yc, 0.0);
		    MAT4X3PNT(tmp, rot1, v1);
		    VMOVE(v1, tmp);
		    MAT4X3PNT(tmp, rot1, v2);
		    VMOVE(v2, tmp);
		    MAT_DELTAS(rot1, 0.0, 0.0, 0.0);
		    rot1[0] = cos(theta);
		    rot1[1] = sin(theta);
		    rot1[4] = (-rot1[1]);
		    rot1[5] = rot1[0];
		    MAT4X3PNT(tmp, rot1, v1);
		    VMOVE(v1, tmp);
		    MAT4X3PNT(tmp, rot1, v2);
		    VMOVE(v2, tmp);
		    MAT_DELTAS(rot1, 0.0, 0.0, 0.0);

		    /* calculate:
		       alpha = start angle
		       beta = terminate angle
		    */
		    beta = 0.0;
		    if (EQUAL(v2[0], v1[0]) && EQUAL(v2[1], v1[1])) {
			/* full circle */
			alpha = 0.0;
			beta = 2.0*pi;
		    }
		    a = sqrt(fabs(F1/A1)); /* semi-axis length */
		    b = sqrt(fabs(F1/C1)); /* semi-axis length */

		    if (type == 1) {
			/* ellipse */
			alpha = atan2(a*v1[1], b*v1[0]);
			if (ZERO(beta)) {
			    beta = atan2(a*v2[1], b*v2[0]);
			    beta = beta - alpha;
			}
		    } else {
			/* hyperbola */
			alpha = myarcsinh(v1[1]/b);
			beta = myarcsinh(v2[1]/b);
			if (fabs(a*cosh(beta) - v2[0]) > 0.01)
			    a = (-a);
			beta = beta - alpha;
		    }
		    num_points = ARCSEGS;

		    /* set-up matrix to translate and rotate
		       the simpler curve back to the original
		       position */

		    MAT_DELTAS(rot1, xc, yc, 0.0);
		    rot1[1] = (-rot1[1]);
		    rot1[4] = (-rot1[4]);
#if defined(USE_BN_MULT_)
		    /* o <= a X b */
		    bn_mat_mul(rot2, *(dir[curve]->rot), rot1);
#else
		    /* a X b => o */
		    Matmult(*(dir[curve]->rot), rot1, rot2);
#endif

		    /* calculate start point */
		    BU_ALLOC((*curv_pts), struct ptlist);
		    ptr = (*curv_pts);
		    prev = NULL;
		    ptr->prev = NULL;

		    npts = 0;
		    VSCALE(v3, v1, conv_factor);
		    MAT4X3PNT(ptr->pt, rot2, v3);
		    npts++;
		    prev = ptr;

		    BU_ALLOC(ptr->next, struct ptlist);
		    ptr = ptr->next;
		    ptr->prev = prev;

		    /* middle points */
		    for (i = 1; i < num_points; i++) {
			point_t tmp2 = {0.0, 0.0, 0.0};

			theta = alpha + (double)i/(double)num_points*beta;
			if (type == 2) {
			    tmp2[0] = a*cosh(theta);
			    tmp2[1] = b*sinh(theta);
			} else {
			    tmp2[0] = a*cos(theta);
			    tmp2[1] = b*sin(theta);
			}
			VSCALE(tmp2, tmp2, conv_factor);
			MAT4X3PNT(ptr->pt, rot2, tmp2);
			npts++;
			prev = ptr;

			BU_ALLOC(ptr->next, struct ptlist);
			ptr = ptr->next;
			ptr->prev = prev;
		    }

		    /* terminate point */
		    VSCALE(v2, v2, conv_factor);
		    MAT4X3PNT(ptr->pt, rot2, v2);
		    npts++;
		    ptr->next = NULL;
		    break;
		}
	    }
	    break;
	}
	case 102:	/* composite curve */ {

	    int ncurves, *curvptr;
	    struct ptlist *tmp_ptr;

	    Readrec(dir[curve]->param);
	    Readint(&type, "");
	    if (type != dir[curve]->type) {
		bu_log("Error in Getcurve, looking for curve type %d, found %d\n" ,
		       dir[curve]->type, type);
		npts = 0;
		break;
	    }

	    Readint(&ncurves, "");
	    curvptr = (int *)bu_calloc(ncurves, sizeof(int), "Getcurve: curvptr");
	    for (i = 0; i < ncurves; i++) {
		Readint(&curvptr[i], "");
		curvptr[i] = (curvptr[i]-1)/2;
	    }

	    npts = 0;
	    (*curv_pts) = NULL;
	    for (i = 0; i < ncurves; i++) {
		npts += Getcurve(curvptr[i], &tmp_ptr);
		if ((*curv_pts) == NULL)
		    (*curv_pts) = tmp_ptr;
		else {
		    ptr = (*curv_pts);
		    while (ptr->next != NULL)
			ptr = ptr->next;
		    ptr->next = tmp_ptr;
		    ptr->next->prev = ptr;
		    if (NEAR_EQUAL(ptr->pt[X], tmp_ptr->pt[X], TOL) &&
			NEAR_EQUAL(ptr->pt[Y], tmp_ptr->pt[Y], TOL) &&
			NEAR_EQUAL(ptr->pt[Z], tmp_ptr->pt[Z], TOL)) {
			ptr->next = ptr->next->next;
			if (ptr->next != NULL)
			    ptr->next->prev = ptr;
			bu_free((char *)tmp_ptr, "Getcurve: tmp_ptr");
			npts--;
		    }
		}
	    }
	    break;
	}
	case 126: {
	    /* rational B-spline */
	    int k, m, n, a, prop1, prop2, prop3, prop4;
	    fastf_t *t;	/* knot values */
	    fastf_t *w;	/* weights */
	    point_t *cntrl_pts;	/* control points */
	    fastf_t v0, v1;	/* starting and stopping parameter values */
	    fastf_t v;	/* current parameter value */
	    fastf_t delv;	/* parameter increment */

	    Readrec(dir[curve]->param);
	    Readint(&type, "");
	    if (type != dir[curve]->type) {
		bu_log("Error in Getcurve, looking for curve type %d, found %d\n" ,
		       dir[curve]->type, type);
		npts = 0;
		break;
	    }

	    Readint(&k, "");
	    Readint(&m, "");
	    Readint(&prop1, "");
	    Readint(&prop2, "");
	    Readint(&prop3, "");
	    Readint(&prop4, "");

	    n = k - m + 1;
	    a = n + 2 * m;

	    t = (fastf_t *)bu_calloc(a+1, sizeof(fastf_t), "Getcurve: spline t");
	    for (i = 0; i < a+1; i++)
		Readflt(&t[i], "");
	    Knot(a+1, t);

	    w = (fastf_t *)bu_calloc(k+1, sizeof(fastf_t), "Getcurve: spline w");
	    for (i = 0; i < k+1; i++)
		Readflt(&w[i], "");

	    cntrl_pts = (point_t *)bu_calloc(k+1, sizeof(point_t), "Getcurve: spline cntrl_pts");
	    for (i = 0; i < k+1; i++) {
		fastf_t tmp;

		for (j = 0; j < 3; j++) {
		    Readcnv(&tmp, "");
		    cntrl_pts[i][j] = tmp;
		}
	    }

	    Readflt(&v0, "");
	    Readflt(&v1, "");

	    delv = (v1 - v0)/((fastf_t)(3*k));

	    /* Calculate points */

	    BU_ALLOC((*curv_pts), struct ptlist);
	    ptr = (*curv_pts);
	    ptr->prev = NULL;
	    prev = NULL;

	    npts = 0;
	    v = v0;
	    while (v < v1) {
		point_t tmp;

		B_spline(v, k, m+1, cntrl_pts, w, tmp);
		MAT4X3PNT(ptr->pt, *dir[curve]->rot, tmp);
		npts++;
		prev = ptr;

		BU_ALLOC(ptr->next, struct ptlist);
		ptr = ptr->next;
		ptr->prev = prev;

		v += delv;
	    }
	    VMOVE(ptr->pt, cntrl_pts[k]);
	    npts++;
	    ptr->next = NULL;

	    /* Free memory */
	    Freeknots();
	    bu_free((char *)cntrl_pts, "Getcurve: spline cntrl_pts");
	    bu_free((char *)w, "Getcurve: spline w");
	    bu_free((char *)t, "Getcurve: spline t");

	    break;
	}
    }
    return npts;
}
int
main (int argc, char **argv)
{
    /* Variables used for XWindow.  */
    Display *my_display;		/* Display unit.  */
    Window root_id;		/* Root window.  */
    Window my_window;		/* First window opened.  */
    Window wind_pic;		/* Window with picture.  */
    Window wind_exit;		/* Exit window.  */
    Window wind_scale;		/* Color scale window.  */
    GC my_gc;			/* Gc for my_window.  */
    XSizeHints window_hints;	/* Hints for 1st window.  */
    XEvent event_received;	/* Events.  */
    long input_event_mask;	/* Input event mask that are to
				 * be responded to.  */
    unsigned long black;		/* Black pixel value.  */
    unsigned long white;		/* White pixel value.  */
    int screen=0;		/* Used for getting colors.  */
    XColor colval[MAXCOL];	/* Color values.  */
    XRectangle rect[MAXARR];	/* Array for drawing rectangles.  */
    char **a=(char **)NULL;	/* Place holder for XSetStandard Properties.  */
    const char winttl[] = "SEE";	/* Window title.  */
    const char quit[] = "QUIT";		/* Exit label.  */
    Font font;			/* Structure for setting font.  */

    /* Other variables.  */
    FILE *fpr;			/* Used to read a file.  */
    FILE *fpw;			/* Used to write a file.  */
    char file[MAXFIL];		/* File to be read.  */
    char line[151];		/* Used to read one line of a file.  */
    size_t main_w, main_h;	/* Width & height of main window.  */
    size_t wide, high;	/* Width and height of picture window.  */
    double pixval[MAXPIX][MAXPIX];/* Pixel value (width, height).  */
    double min=0.0, max=0.0;	/* Minimum & maximum pixel values.  */
    int i, j, k, m;			/* Loop counters.  */
    double r;			/* Temporary variable.  */
    double dcol;			/* Color step.  */
    double pixbin[MAXCOL + 1];	/* Pixel bins.  */
    double dpix;			/* Delta between pixel bins.  */
    int color[MAXPIX][MAXPIX];	/* Indicates color.  */
    int icol;			/* Indicates color shading.  */
    double check;		/* Used for finding colors.  */
    char string[11];		/* Used to write a label.  */
    int flag=0;			/* Color flag.  */
    int lstarr;			/* Last color array.  */
    int flag_pix;		/* 0=>no pix file written, 1=>pix file written.  */
    char file_pix[MAXFIL];	/* Pix file name.  */
    unsigned char c;		/* Used to write pix file.  */
    int ret;
    int ch;

    struct colstr *array = NULL;	/* Array for color information.  */

    bu_opterr = 0;
    while ((ch = bu_getopt(argc, argv, "h?")) != -1)
    {	if (bu_optopt == '?') ch = 'h';
	switch (ch) {
	    case 'h':
		fprintf(stderr,"ir-X is interactive; sample session in 'man' page\n");
		bu_exit(1,NULL);
	    default:
		break;
	}
    }

    fprintf(stderr,"   Program continues running:\n");

    array = (struct colstr *)bu_calloc(MAXCOL + EXTRA, sizeof(struct colstr), "allocate colstr array");

    /* Get file name to be read.  */
    printf("Enter name of file to be read (%d char max).\n\t", MAXFIL);
    (void)fflush(stdout);
    ret = scanf("%25s", file);
    if (ret == 0)
	perror("scanf");

    /* Find what color shading to use.  */
    printf("Indicate type of color shading to use.\n");
    printf("\t0 - gray\n");
    printf("\t1 - red\n");
    printf("\t2 - black-blue-cyan-green-yellow-white\n");
    printf("\t3 - black-blue-magenta-red-yellow-white\n");
    (void)fflush(stdout);
    ret = scanf("%d", &icol);
    if (ret == 0)
	perror("scanf");
    if ((icol != 1) && (icol != 2) && (icol != 3)) icol = 0;

    /* Determine if a pix file is to be written.  */
    flag_pix = 0;
    printf("Do you wish to create a pix file (0-no, 1-yes)?\n\t");
    (void)fflush(stdout);
    ret = scanf("%d", &flag_pix);
    if (ret == 0)
	perror("scanf");
    if (flag_pix != 1)
	 flag_pix = 0;
    else {
	printf("Enter name of the pix file to be created ");
	printf("(%d char max).\n\t", MAXFIL);
	(void)fflush(stdout);
	ret = scanf("%25s", file_pix);
	if (ret == 0)
	    perror("scanf");
    }

    printf("Zeroing color info array ");
    (void)fflush(stdout);

    /* Zero color info array.  */
    for (i=0; i<(MAXCOL + EXTRA); i++) {
	array[i].cnt = 0;
	array[i].more = 0;
    }
    lstarr = MAXCOL;

    printf("- finished zeroing\n");
    (void)fflush(stdout);

    printf("Setting up color scale ");
    (void)fflush(stdout);

    /* Set up color scale.  */
    dcol = (65535.0 + 1.0) / MAXCOL;
    if (icol == 0) {
	/* Shades of gray.  */
	printf("-shades of gray ");
	(void)fflush(stdout);
	for (i=0; i<MAXCOL; i++) {
	    colval[i].red = (unsigned short)((double)i * dcol);
	    colval[i].green = (unsigned short)((double)i * dcol);
	    colval[i].blue = (unsigned short)((double)i * dcol);
	}
    }

    else if (icol == 1) {
	/* Shades of red.  */
	printf("- shades of red ");
	(void)fflush(stdout);
	for (i=0; i<MAXCOL; i++) {
	    colval[i].red = (unsigned short)((double)i * dcol);
	    colval[i].green = (unsigned short)0;
	    colval[i].blue = (unsigned short)0;
	}
    }

    else if (icol == 2) {
	/* Black-blue-cyan-green-yellow-white.  */
	printf("- black-blue-cyan-green-yellow-white ");
	(void)fflush(stdout);
	if (MAXCOL > 1280.0) {
	    printf("Maximum number of colors, %d, is ", MAXCOL);
	    printf("greater than 1280.\n");
	    printf("This may create problems.\n");
	}
	/* Color step.  */
	dcol = 1280. / MAXCOL;
	i = 0;
	/* Colors (0, 0, 0) to (0, 0, 255).  */
	check = 0.0;
	while ((check <= 255.0) && (i < MAXCOL)) {
	    colval[i].red = (unsigned short)0;
	    colval[i].green = (unsigned short)0;
	    colval[i].blue = (unsigned short)(check * 256.0);
	    check += dcol;
	    i++;
	}
	/* Colors (0, 0, 255) to (0, 255, 255).  */
	check = 0.0;
	while ((check <= 255.0) && (i < MAXCOL)) {
	    colval[i].red = (unsigned short)0;
	    colval[i].green = (unsigned short)(check * 256.0);
	    colval[i].blue = (unsigned short)(255 * 256);
	    check += dcol;
	    i++;
	}
	/* Colors (0, 255, 255) to (0, 255, 0).  */
	check = 255.0;
	while ((check >= 0.0) && (i < MAXCOL)) {
	    colval[i].red = (unsigned short)0;
	    colval[i].green = (unsigned short)(255 * 256);
	    colval[i].blue = (unsigned short)(check * 256.0);
	    check -= dcol;
	    i++;
	}
	/* Colors (0, 255, 0) to (255, 255, 0).  */
	check = 0.0;
	while ((check <= 255.0) && (i < MAXCOL)) {
	    colval[i].red = (unsigned short)(check * 256.0);
	    colval[i].green = (unsigned short)(255 * 256);
	    colval[i].blue = (unsigned short)0;
	    check += dcol;
	    i++;
	}
	/* Colors (255, 255, 0) to (255, 255, 255).  */
	check = 0.0;
	while ((check <= 255.0) && (i < MAXCOL)) {
	    colval[i].red = (unsigned short)(255 * 256);
	    colval[i].green = (unsigned short)(255 * 256);
	    colval[i].blue = (unsigned short)(check * 256.0);
	    check += dcol;
	    i++;
	}
    }

    else if (icol == 3) {
	/* Black-blue-magenta-red-yellow-white.  */
	printf("- black-blue-magenta-red-yellow-white ");
	(void)fflush(stdout);
	if (MAXCOL > 1280.0) {
	    printf("Maximum number of colors, %d, is ", MAXCOL);
	    printf("greater than 1280.\n");
	    printf("This may create problems.\n");
	}
	/* Color step.  */
	dcol = 1280. / MAXCOL;
	i = 0;
	/* Colors (0, 0, 0) to (0, 0, 255).  */
	check = 0.0;
	while ((check <= 255.0) && (i < MAXCOL)) {
	    colval[i].red = (unsigned short)0;
	    colval[i].green = (unsigned short)0;
	    colval[i].blue = (unsigned short)(check * 256.0);
	    check += dcol;
	    i++;
	}
	/* Colors (0, 0, 255) to (255, 0, 255).  */
	check = 0.0;
	while ((check <= 255.0) && (i < MAXCOL)) {
	    colval[i].red = (unsigned short)(check * 256.0);
	    colval[i].green = (unsigned short)0;
	    colval[i].blue = (unsigned short)(255 * 256);
	    check += dcol;
	    i++;
	}
	/* Colors (255, 0, 255) to (255, 0, 0).  */
	check = 255.0;
	while ((check >= 0.0) && (i < MAXCOL)) {
	    colval[i].red = (unsigned short)(255 * 256);
	    colval[i].green = (unsigned short)0;
	    colval[i].blue = (unsigned short)(check * 256.0);
	    check -= dcol;
	    i++;
	}
	/* Colors (255, 0, 0) to (255, 255, 0).  */
	check = 0.0;
	while ((check <= 255.0) && (i < MAXCOL)) {
	    colval[i].red = (unsigned short)(255 * 256);
	    colval[i].green = (unsigned short)(check * 256.0);
	    colval[i].blue = (unsigned short)0;
	    check += dcol;
	    i++;
	}
	/* Colors (255, 255, 0) to (255, 255, 255).  */
	check = 0.0;
	while ((check <= 255.0) && (i < MAXCOL)) {
	    colval[i].red = (unsigned short)(255 * 256);
	    colval[i].green = (unsigned short)(255 * 256);
	    colval[i].blue = (unsigned short)(check * 256.0);
	    check += dcol;
	    i++;
	}
    }

    printf("- finished.\n");
    (void)fflush(stdout);

    printf("Reading file ");
    (void)fflush(stdout);

    /* Open file for reading.  */
    fpr = fopen(file, "rb");

    /* Check for non-existent file.  */
    while (fpr == NULL) {
	printf("\nThis file does not exist, please try again.\n");
	(void)fflush(stdout);
	ret = scanf("%25s", file);
	if (ret == 0) {
	    bu_exit(EXIT_FAILURE, "ir-X - scanf failure - no file to work with!!\n");
	}
	fpr = fopen(file, "rb");
    }

    /* Read width and height of window.  */
    (void)bu_fgets(line, 150, fpr);
    {
	unsigned long w, h;
	sscanf(line, "%lu %lu", &w, &h);
	wide = w;
	high = h;
    }

    /* Check that width and height are not too big.  */
    if (wide > (size_t)MAXPIX) {
	printf("The width of the window, %lu, is greater\n", (unsigned long)wide);
	printf("than the maximum for width, %lu.  Press\n", (unsigned long)MAXPIX);
	printf("delete to end program.\n");
	(void)fflush(stdout);
    }
    if (high > MAXPIX) {
	printf("The height of the window, %lu, is greater\n", (unsigned long)wide);
	printf("than the maximum for height, %lu.  Press\n", (unsigned long)MAXPIX);
	printf("delete to end program.\n");
	(void)fflush(stdout);
    }

    /* Read pixel values.  */
    for (i=0; i<(int)high; i++) {
	for (j=0; j<(int)wide; j++) {
	    (void)bu_fgets(line, 150, fpr);
	    sscanf(line, "%lf", &pixval[j][i]);
	}
    }

    /* Close file.  */
    (void)fclose(fpr);

    printf("- file read.\n");
    (void)fflush(stdout);

    /* Print out width and height of window.  */
    printf("Width:  %lu\n", (unsigned long)wide);
    printf("Height:  %lu\n", (unsigned long)high);
    (void)fflush(stdout);

    printf("Finding min & max.\n");
    (void)fflush(stdout);

    /* Find minimum and maximum of pixel values.  */
    for (i=0; (size_t)i<high; i++) {
	for (j=0; (size_t)j<wide; j++) {
	    if ((j==0) && (i==0)) {
		min = pixval[j][i];
		max = pixval[j][i];
	    }
	    V_MIN(min, pixval[j][i]);
	    V_MAX(max, pixval[j][i]);
	}
    }

    /* Write minimum and maximum pixel values.  */
    printf("Minimum:  %f\n", min);
    printf("Maximum:  %f\n", max);
    (void)fflush(stdout);

    printf("Finding pixel bins ");
    (void)fflush(stdout);

    /* Find pixel bins.  */
    dpix = (max - min) / MAXCOL;
    pixbin[0] = min;
    for (i=1; i<MAXCOL; i++) {
	pixbin[i] = pixbin[i-1] + dpix;
    }
    pixbin[MAXCOL] = max;

    /* Find the color for each pixel.  */
    for (i=0; (size_t)i<high; i++) {
	for (j=0; (size_t)j<wide; j++) {
	    /* Determine the color associated with pixval[j][i].  */
	    m = 0;
	    k = 0;
	    color[j][i] = 0;
	    while ((m == 0) && (k < MAXCOL)) {
		if ((pixval[j][i] > pixbin[k]) &&
		    (pixval[j][i] <= pixbin[k + 1]))
		{
		    color[j][i] = k;
		    m = 1;
		}
		k++;
	    }
	}
    }

    printf("- found pixel bins.\n");
    (void)fflush(stdout);

    printf("Putting color info in arrays ");
    (void)fflush(stdout);

    /* Put color info in arrays.  */
    for (i=0; (size_t)i<high; i++) {
	for (j=0; (size_t)j<wide; j++) {
	    if (array[color[j][i]].cnt < MAXARR) {
		array[color[j][i]].x1[array[color[j][i]].cnt] = j;
		array[color[j][i]].y1[array[color[j][i]].cnt] = i;
		array[color[j][i]].cnt++;
	    } else {
		if (array[color[j][i]].more == 0) {
		    if (lstarr < (MAXCOL + EXTRA)) {
			array[color[j][i]].more = lstarr;
			k = lstarr;
			lstarr++;
			array[k].x1[array[k].cnt] = j;
			array[k].y1[array[k].cnt] = i;
			array[k].cnt++;
		    } else {
			flag = 1;
		    }
		} else {
		    k = array[color[j][i]].more;
		    if (array[k].cnt < MAXARR) {
			array[k].x1[array[k].cnt] = j;
			array[k].y1[array[k].cnt] = i;
			array[k].cnt++;
		    } else {
			flag = 1;
		    }
		}
	    }
	}
    }

    printf("- color info in arrays.\n");
    (void)fflush(stdout);

    if (flag != 0) {
	printf("There too many pixels of one color.  Note that\n");
	printf("this means there is something wrong with the\n");
	printf("picture!\n");
	(void)fflush(stdout);
    }

    /* Set up window to be the size that was read.  */
    /* Open display.  */
    my_display = XOpenDisplay(NULL);

    /* Get id of parent (root is parent).  */
    root_id = DefaultRootWindow(my_display);

    /* Find value for black & white.  */
    black = BlackPixel(my_display, DefaultScreen(my_display));
    white = WhitePixel(my_display, DefaultScreen(my_display));

    /* Create a window & find its id.  */
    main_w = wide + (unsigned int)150;
    main_h = high + (unsigned int)150;
    my_window = XCreateSimpleWindow(my_display, root_id, 0, 0,
				    main_w, main_h, 50, white, black);

    /* Set appropriate fields in window hits structure.  */
    /* This is only done for the first window created.  */
    window_hints.width = (int)main_w;
    window_hints.height = (int)main_h;
    window_hints.flags = PSize;

    /* Inform window manager of hints.  */
    /* Set XSetStandarProperties instead of XSetNormalHints.  */
    XSetStandardProperties(my_display, my_window, winttl, winttl, None, a, 0,
			   &window_hints);

    /* Create picture window & find its id.  */
    wind_pic = XCreateSimpleWindow(my_display, my_window, 20, 20, wide, high,
				   5, white, black);

    /* Create exit window & find its id.  */
    wind_exit = XCreateSimpleWindow(my_display, my_window, (wide + 30),
				    (high + 65), 80, 30, 5, white, black);

    /* Create color scale window & find its id.  */
    wind_scale = XCreateSimpleWindow(my_display, my_window, 10, (high + 50),
				     (2 * MAXCOL), 60, 5, white, black);

    /* Select input event masks that are to be responded to (exposure).  */
    input_event_mask = ExposureMask | ButtonPressMask;

    /* Notify server about input event masks.  */
    XSelectInput(my_display, my_window, ExposureMask);
    XSelectInput(my_display, wind_pic, ExposureMask);
    XSelectInput(my_display, wind_exit, input_event_mask);
    XSelectInput(my_display, wind_scale, input_event_mask);

    /* Map window to display so that it will show up.  */
    XMapWindow(my_display, my_window);

    /* Map picture window, exit window, & color scale window to display */
    /* so that they will show up.  */
    XMapWindow(my_display, wind_pic);
    XMapWindow(my_display, wind_exit);
    XMapWindow(my_display, wind_scale);

    /* Create graphics context (gc) for my window.  */
    my_gc = XCreateGC(my_display, my_window, None, NULL);

    /* Create a loop so that events will occur.  */
    for (;;) {
	XNextEvent(my_display, &event_received);
	switch (event_received.type) {
	    /* Do the following when an expose occurs.  */
	    case Expose:		/* Code for expose event.  */
		/* Draw the picture if the picture window is exposed.  */
		if (event_received.xexpose.window == wind_pic) {
		    /* START # 1 */
		    /* Send groups of color to screen.  */
		    for (k=0; k<MAXCOL; k++) {
			if (array[k].cnt > 0) {
			    for (i=0; i<array[k].cnt; i++) {
				rect[i].x = array[k].x1[i];
				rect[i].y = array[k].y1[i];
				rect[i].width = 1;
				rect[i].height = 1;
			    }
			    m = array[k].cnt;
			    XAllocColor(my_display, DefaultColormap(my_display, screen),
					&colval[k]);
			    XSetForeground(my_display, my_gc, colval[k].pixel);
			    XFillRectangles(my_display, wind_pic, my_gc, rect, m);

			    /* Send extra array if there is a lot of that color.  */
			    if (array[k].more > 0) {
				j = array[k].more;
				for (i=0; i<array[j].cnt; i++) {
				    rect[i].x = array[j].x1[i];
				    rect[i].y = array[j].y1[i];
				    rect[i].width = 1;
				    rect[i].height = 1;
				}
				m = array[j].cnt;
				XAllocColor(my_display, DefaultColormap(my_display,
									screen), &colval[k]);
				XSetForeground(my_display, my_gc, colval[k].pixel);
				XFillRectangles(my_display, wind_pic, my_gc, rect, m);
			    }
			}
		    }
		}						/* END # 1 */

		/* If exit window is exposed write label.  */
		else if (event_received.xexpose.window == wind_exit) {
		    /* START # 2 */
		    XSetForeground(my_display, my_gc, white);
		    font = XLoadFont(my_display, "8x13bold");
		    XSetFont(my_display, my_gc, font);
		    XDrawString(my_display, wind_exit, my_gc, 25, 20, quit,
				strlen(quit));
		}						/* END # 2 */

		/* If color scale window is exposed put up color scale.  */
		else if (event_received.xexpose.window == wind_scale) {
		    for (i=0; i<MAXCOL; i++) {
			XAllocColor(my_display, DefaultColormap(my_display,
								screen), &colval[i]);
			XSetForeground(my_display, my_gc, colval[i].pixel);
			XFillRectangle(my_display, wind_scale, my_gc,
				       (i * 2), 0, 2, 30);
		    }
		    /* Write label.  */
		    XSetForeground(my_display, my_gc, white);
		    font = XLoadFont(my_display, "8x13bold");
		    XSetFont(my_display, my_gc, font);
		    (void)sprintf(string, "%.0f", min);
		    XDrawString(my_display, wind_scale, my_gc,
				2, 45, string, strlen(string));
		    r = min + (max - min) / 4.0;
		    (void)sprintf(string, "%.0f", r);
		    XDrawString(my_display, wind_scale, my_gc,
				(MAXCOL * 2 / 4 - 8), 45, string, strlen(string));
		    r = min + (max - min) / 2.0;
		    (void)sprintf(string, "%.0f", r);
		    XDrawString(my_display, wind_scale, my_gc,
				(MAXCOL * 2 / 2 - 8), 45, string, strlen(string));
		    r = min + (max - min) * 3. / 4.0;
		    (void)sprintf(string, "%.0f", r);
		    XDrawString(my_display, wind_scale, my_gc,
				(MAXCOL * 2 * 3 / 4 - 8), 45, string, strlen(string));
		    (void)sprintf(string, "%.0f", max);
		    XDrawString(my_display, wind_scale, my_gc,
				(MAXCOL * 2 - 16), 45, string, strlen(string));
		}
		break;

		/* Do the following if a mouse press occurs.  */
	    case ButtonPress:
		if (event_received.xbutton.window == wind_exit) {
		    XCloseDisplay(my_display);

		    /* Create pix file if necessary.  */
		    if (flag_pix == 1) {
			/* START # 1.  */
			/* Open pix file to be written to.  */
			fpw = fopen(file_pix, "wb");

			/* Write colors to file.  */
			for (i=high; i>0; i--) {
			    /* START # 2.  */
			    for (j=0; (size_t)j<wide; j++) {
				/* START # 3.  */
				c = (unsigned char)((int)(colval[color[j][i-1]].red
							  / 256));
				putc(c, fpw);
				c = (unsigned char)((int)
						    (colval[color[j][i-1]].green / 256));
				putc(c, fpw);
				c = (unsigned char)((int)(colval[color[j][i-1]].blue
							  / 256));
				putc(c, fpw);
			    }				/* END # 3.  */
			}					/* END # 2.  */

			/* Close file.  */
			(void)fclose(fpw);

			printf("Pix file, %s, has been written.\n", file_pix);
			(void)fflush(stdout);
		    }					/* END # 1.  */

		    bu_free(array, "free colstr array");
		    return 0;
		}
		break;
	}
    }

    bu_free(array, "free colstr array");
    return 0;
}
Esempio n. 6
0
/**
 * R T _ M E T A B A L L _ T E S S
 *
 * Tessellate a metaball.
 */
int
rt_metaball_tess(struct nmgregion **r, struct model *m, struct rt_db_internal *ip, const struct rt_tess_tol *ttol, const struct bn_tol *tol)
{
    struct rt_metaball_internal *mb;
    fastf_t mtol, radius;
    point_t center, min, max;
    fastf_t i, j, k, finalstep = +INFINITY;
    struct bu_vls times = BU_VLS_INIT_ZERO;
    struct wdb_metaballpt *mbpt;
    struct shell *s;
    int numtri = 0;

    if (r == NULL || m == NULL)
	return -1;
    *r = NULL;

    NMG_CK_MODEL(m);

    RT_CK_DB_INTERNAL(ip);
    mb = (struct rt_metaball_internal *)ip->idb_ptr;
    RT_METABALL_CK_MAGIC(mb);

    rt_prep_timer();

    /* since this geometry isn't necessarily prepped, we have to figure out the
     * finalstep and bounding box manually. */
    for (BU_LIST_FOR(mbpt, wdb_metaballpt, &mb->metaball_ctrl_head))
	V_MIN(finalstep, mbpt->fldstr);
    finalstep /= (fastf_t)1e5;

    radius = rt_metaball_get_bounding_sphere(&center, mb->threshold, mb);
    if(radius < 0) {	/* no control points */
	bu_log("Attempting to tesselate metaball with no control points");
	return -1;
    }
    rt_metaball_bbox(ip, &min, &max, tol);

    /* TODO: get better sampling tolerance, unless this is "good enough" */
    mtol = ttol->abs;
    V_MAX(mtol, ttol->rel * radius * 10);
    V_MAX(mtol, tol->dist);

    *r = nmg_mrsv(m);	/* new empty nmg */
    s = BU_LIST_FIRST(shell, &(*r)->s_hd);

    /* the incredibly naïve approach. Time could be cut in half by simply
     * caching 4 point values, more by actually marching or doing active
     * refinement. This is the simplest pattern for now.
     */
    for (i = min[X]; i < max[X]; i += mtol)
	for (j = min[Y]; j < max[Y]; j += mtol)
	    for (k = min[Z]; k < max[Z]; k += mtol) {
		point_t p[8];
		int pv = 0;

		/* generate the vertex values */
#define MEH(c,di,dj,dk) VSET(p[c], i+di, j+dj, k+dk); pv |= rt_metaball_point_inside((const point_t *)&p[c], mb) << c;
		MEH(0, 0, 0, mtol);
		MEH(1, mtol, 0, mtol);
		MEH(2, mtol, 0, 0);
		MEH(3, 0, 0, 0);
		MEH(4, 0, mtol, mtol);
		MEH(5, mtol, mtol, mtol);
		MEH(6, mtol, mtol, 0);
		MEH(7, 0, mtol, 0);
#undef MEH

		if ( pv != 0 && pv != 255 ) {	/* entire cube is either inside or outside */
		    point_t edges[12];
		    int rval;

		    /* compute the edge values (if needed) */
#define MEH(a,b,c) if(!(pv&(1<<b)&&pv&(1<<c))) { \
    rt_metaball_find_intersection(edges+a, mb, (const point_t *)(p+b), (const point_t *)(p+c), mtol, finalstep); \
}

		    /* magic numbers! an edge, then the two attached vertices.
		     * For edge/vertex mapping, refer to the awesome ascii art
		     * at the beginning of this file. */
		    MEH(0 ,0,1);
		    MEH(1 ,1,2);
		    MEH(2 ,2,3);
		    MEH(3 ,0,3);
		    MEH(4 ,4,5);
		    MEH(5 ,5,6);
		    MEH(6 ,6,7);
		    MEH(7 ,4,7);
		    MEH(8 ,0,4);
		    MEH(9 ,1,5);
		    MEH(10,2,6);
		    MEH(11,3,7);
#undef MEH

		    rval = nmg_mc_realize_cube(s, pv, (point_t *)edges, tol);
		    numtri += rval;
		    if(rval < 0) {
			bu_log("Error attempting to realize a cube O.o\n");
			return rval;
		    }
		}
	    }

    nmg_mark_edges_real(&s->l.magic);
    nmg_region_a(*r, tol);

    nmg_model_fuse(m, tol);

    rt_get_timer(&times, NULL);
    bu_log("metaball tesselate (%d triangles): %s\n", numtri, bu_vls_addr(&times));

    return 0;
}
Esempio n. 7
0
int
read_Trie(FILE *fp)
{
    static char	name_buf[MAX_TRIE_LEVEL+1];
    Trie	*triep;
    F_Hdr_Ptlist	hdr_ptlist;
    int		min, max;
    /* Read temperature range information.				*/
    if (	fread( (char *) &min, (int) sizeof(int), 1, fp ) != 1
		||	fread( (char *) &max, (int) sizeof(int), 1, fp ) != 1
	)
    {
	bu_log( "Could not read min/max info.\n" );
	rewind( fp );
    }
    else
    {
	bu_log( "IR data base 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.			*/
	    V_MIN( ir_min, min );
	    V_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;
    }
    while ( bu_fgets( name_buf, MAX_TRIE_LEVEL, fp ) != NULL )
    {
	name_buf[strlen(name_buf)-1] = '\0'; /* Clobber new-line.*/
	triep = add_Trie( name_buf, &reg_triep );
	if ( fread( (char *) &hdr_ptlist, (int) sizeof(F_Hdr_Ptlist), 1, fp )
	     != 1
	    )
	{
	    bu_log( "\"%s\"(%d) Read failed!\n", __FILE__, __LINE__ );
	    return	0;
	}
	for (; hdr_ptlist.f_length > 0; hdr_ptlist.f_length-- )
	{
	    fastf_t		point[3];
	    float		c_point[3];
	    Octree		*octreep;
	    if ( fread( (char *) c_point, (int) sizeof(c_point), 1, fp ) != 1 )
	    {
		bu_log(	"\"%s\"(%d) Read failed.\n",
			__FILE__, __LINE__ );
		return	0;
	    }
	    VMOVE( point, c_point );
	    if ( (octreep = add_Region_Octree(	&ir_octree,
						point,
						triep,
						hdr_ptlist.f_temp,
						0
		      )
		     ) != OCTREE_NULL
		)
		append_Octp( triep, octreep );
	}
    }
    return	1;
}
Esempio n. 8
0
// static
Vs64 VStream::streamCopy(VStream& fromStream, VStream& toStream, Vs64 numBytesToCopy, Vs64 tempBufferSize) {
    Vs64 numBytesCopied = 0;

    /*
    First we figure out which (if either) of the streams can give us a buffer
    pointer. Either or both of these may be NULL.
    */
    Vu8* fromBuffer = fromStream._getReadIOPtr();
    Vu8* toBuffer = toStream._getWriteIOPtr();

    /*
    If the source stream gave us a buffer to read from, we have to ask it
    how much data it really has, so we know how much we're really going to be
    copying.
    */
    if (fromBuffer != NULL) {
        numBytesToCopy = fromStream._prepareToRead(numBytesToCopy);
    }

    /*
    If the target stream gave us a buffer to write to, we have to ask it
    again after first giving it a chance to expand the buffer to fit the
    requested copy size.
    */
    if (toBuffer != NULL) {
        toStream._prepareToWrite(numBytesToCopy);
        toBuffer = toStream._getWriteIOPtr();
    }

    /*
    Now we can proceed with the copy. The matrix of possibities is the
    two possible sources (buffer or stream) and the two possible targets
    (buffer or stream). We handle each case optimally.
    */
    if ((fromBuffer == NULL) && (toBuffer != NULL)) {
        // stream-to-buffer copy
        numBytesCopied = fromStream.read(toBuffer, numBytesToCopy);
        toStream._finishWrite(numBytesCopied);
    } else if ((fromBuffer != NULL) && (toBuffer == NULL)) {
        // buffer-to-stream copy
        numBytesCopied = toStream.write(fromBuffer, numBytesToCopy);
        fromStream._finishRead(numBytesCopied);
    } else if ((fromBuffer != NULL) && (toBuffer != NULL)) {
        // buffer-to-buffer copy
        VStream::copyMemory(toBuffer, fromBuffer, numBytesToCopy);
        numBytesCopied = numBytesToCopy;

        fromStream._finishRead(numBytesCopied);
        toStream._finishWrite(numBytesCopied);
    } else {
        /*
        Worst case scenario: direct copy between streams without their own
        buffers, so we have to create a buffer to do the transfer.
        */

        Vu8* tempBuffer;
        Vs64 numBytesRemaining;
        Vs64 numTempBytesToCopy;
        Vs64 numTempBytesRead;
        Vs64 numTempBytesWritten;

        numBytesRemaining = numBytesToCopy;
        tempBufferSize = V_MIN(numBytesToCopy, tempBufferSize);

        tempBuffer = VStream::newNewBuffer(tempBufferSize);

        while (numBytesRemaining > 0) {
            numTempBytesToCopy = V_MIN(numBytesRemaining, tempBufferSize);

            numTempBytesRead = fromStream.read(tempBuffer, numTempBytesToCopy);

            // If we detect EOF, we're done.
            if (numTempBytesRead == 0) {
                break;
            }

            numTempBytesWritten = toStream.write(tempBuffer, numTempBytesRead);

            numBytesRemaining -= numTempBytesWritten;
            numBytesCopied += numTempBytesWritten;

            // If we couldn't write any bytes, we have a problem and should stop here.
            if (numTempBytesWritten == 0) {
                break;
            }
        }

        delete [] tempBuffer;
    }

    return numBytesCopied;
}
bool
BSplineCurveWithKnots::Load(STEPWrapper *sw, SDAI_Application_instance *sse)
{
    step = sw;
    id = sse->STEPfile_id;

    // load base class attributes
    if (!BSplineCurve::Load(step, sse)) {
	std::cout << CLASSNAME << ":Error loading base class ::BSplineCurve." << std::endl;
	goto step_error;
    }

    // need to do this for local attributes to makes sure we have
    // the actual entity and not a complex/supertype parent
    sse = step->getEntity(sse, ENTITYNAME);

    if (knot_multiplicities.empty()) {
	STEPattribute *attr = step->getAttribute(sse, "knot_multiplicities");

	if (attr) {
	    STEPaggregate *sa = (STEPaggregate *)(attr->ptr.a);
	    if (!sa) goto step_error;
	    IntNode *in = (IntNode *)sa->GetHead();
	    if (!in) goto step_error;

	    while (in != NULL) {
		knot_multiplicities.push_back(in->value);
		in = (IntNode *)in->NextNode();
	    }
	} else {
	    std::cout << CLASSNAME << ": Error loading BSplineCurveWithKnots(knot_multiplicities)." << std::endl;
	    goto step_error;
	}
    }

    if (knots.empty()) {
	STEPattribute *attr = step->getAttribute(sse, "knots");
	if (attr) {
	    STEPaggregate *sa = (STEPaggregate *)(attr->ptr.a);
	    if (!sa) goto step_error;
	    RealNode *rn = (RealNode *)sa->GetHead();
	    if (!rn) goto step_error;

	    while (rn != NULL) {
		knots.push_back(rn->value);
		rn = (RealNode *)rn->NextNode();
	    }
	} else {
	    std::cout << CLASSNAME << ": Error loading BSplineCurveWithKnots(knots)." << std::endl;
	    goto step_error;
	}
    }

    knot_spec = (Knot_type)step->getEnumAttribute(sse, "knot_spec");
    V_MIN(knot_spec, Knot_type_unset);

    sw->entity_status[id] = STEP_LOADED;
    return true;
step_error:
    sw->entity_status[id] = STEP_LOAD_ERROR;
    return false;
}
Esempio n. 10
0
static void
make_bot_object(const char *name,
		struct rt_wdb *wdbp)
{
    int i;
    int max_pt=0, min_pt=999999;
    int num_vertices;
    struct bu_bitv *bv=NULL;
    int bot_mode;
    int count;
    struct rt_bot_internal bot_ip;

    bot_ip.magic = RT_BOT_INTERNAL_MAGIC;
    for (i = 0; i < face_count; i++) {
	V_MIN(min_pt, faces[i*3]);
	V_MAX(max_pt, faces[i*3]);
	V_MIN(min_pt, faces[i*3+1]);
	V_MAX(max_pt, faces[i*3+1]);
	V_MIN(min_pt, faces[i*3+2]);
	V_MAX(max_pt, faces[i*3+2]);
    }

    num_vertices = max_pt - min_pt + 1;
    bot_ip.num_vertices = num_vertices;
    bot_ip.vertices = (fastf_t *)bu_calloc(num_vertices*3, sizeof(fastf_t), "BOT vertices");
    for (i = 0; i < num_vertices; i++)
	VMOVE(&bot_ip.vertices[i*3], grid_pts[min_pt+i]);

    for (i = 0; i < face_count * 3; i++)
	faces[i] -= min_pt;
    bot_ip.num_faces = face_count;
    bot_ip.faces = bu_calloc(face_count*3, sizeof(int), "BOT faces");
    for (i = 0; i < face_count*3; i++)
	bot_ip.faces[i] = faces[i];

    bot_ip.face_mode = (struct bu_bitv *)NULL;
    bot_ip.thickness = (fastf_t *)NULL;
    if (mode == PLATE_MODE) {
	bot_mode = RT_BOT_PLATE;
	bv = bu_bitv_new(face_count);
	for (i = 0; i < face_count; i++) {
	    if (facemode[i] == POS_FRONT)
		BU_BITSET(bv, i);
	}
	bot_ip.face_mode = bv;
	bot_ip.thickness = (fastf_t *)bu_calloc(face_count, sizeof(fastf_t), "BOT thickness");
	for (i = 0; i < face_count; i++)
	    bot_ip.thickness[i] = thickness[i];
    } else
	bot_mode = RT_BOT_SOLID;

    bot_ip.mode = bot_mode;
    bot_ip.orientation = RT_BOT_UNORIENTED;
    bot_ip.bot_flags = 0;

    count = rt_bot_vertex_fuse(&bot_ip, &wdbp->wdb_tol);
    count = rt_bot_face_fuse(&bot_ip);
    if (count)
	bu_log("WARNING: %d duplicate faces eliminated from group %d component %d\n", count, group_id, comp_id);

    rt_mk_bot(wdbp, name, bot_mode, RT_BOT_UNORIENTED, 0,
	      bot_ip.num_vertices, bot_ip.num_faces, bot_ip.vertices,
	      bot_ip.faces, bot_ip.thickness, bot_ip.face_mode);

    if (mode == PLATE_MODE) {
	bu_free((char *)bot_ip.thickness, "BOT thickness");
	bu_free((char *)bot_ip.face_mode, "BOT face_mode");
    }
    bu_free((char *)bot_ip.vertices, "BOT vertices");
    bu_free((char *)bot_ip.faces, "BOT faces");
}
bool
BBNode::isTrimmed(const ON_2dPoint &uv, BRNode **closest, double &closesttrim, double within_distance_tol) const
{
    BRNode *br;
    std::list<BRNode *> trims;

    closesttrim = -1.0;
    if (m_checkTrim) {
	getTrimsAbove(uv, trims);

	if (trims.empty()) {
	    return true;
	} else { /* find closest BB */
	    std::list<BRNode *>::iterator i;
	    BRNode *vclosest = NULL;
	    BRNode *uclosest = NULL;
	    fastf_t currHeight = (fastf_t)0.0;
	    bool currTrimStatus = false;
	    bool verticalTrim = false;
	    bool underTrim = false;
	    double vdist = 0.0;
	    double udist = 0.0;

	    for (i = trims.begin(); i != trims.end(); i++) {
		br = dynamic_cast<BRNode *>(*i);

		/* skip if trim below */
		if (br->m_node.m_max[1] + within_distance_tol < uv[Y]) {
		    continue;
		}

		if (br->m_Vertical) {
		    if ((br->m_v[0] <= uv[Y]) && (br->m_v[1] >= uv[Y])) {
			double dist = fabs(uv[X] - br->m_v[0]);
			if (!verticalTrim) { /* haven't seen vertical trim yet */
			    verticalTrim = true;
			    vdist = dist;
			    vclosest = br;
			} else {
			    if (dist < vdist) {
				vdist = dist;
				vclosest = br;
			    }
			}

		    }
		    continue;
		}
		double v;
		bool trimstatus = br->isTrimmed(uv, v);
		if (v >= 0.0) {
		    if (closest && *closest == NULL) {
			currHeight = v;
			currTrimStatus = trimstatus;
			if (closest) {
			    *closest = br;
			}
		    } else if (v < currHeight) {
			currHeight = v;
			currTrimStatus = trimstatus;
			if (closest) {
			    *closest = br;
			}
		    }
		} else {
		    double dist = fabs(v);
		    if (!underTrim) {
			underTrim = true;
			udist = dist;
			uclosest = br;
		    } else {
			V_MIN(udist, dist);
			uclosest = br;
		    }
		}
	    }
	    if (closest && *closest == NULL) {
		if (verticalTrim) {
		    closesttrim = vdist;
		    if (closest) {
			*closest = vclosest;
		    }
		}
		if ((underTrim) && (!verticalTrim || (udist < closesttrim))) {
		    closesttrim = udist;
		    if (closest) {
			*closest = uclosest;
		    }
		}
		return true;
	    } else {
		closesttrim = currHeight;
		if ((verticalTrim) && (vdist < closesttrim)) {
		    closesttrim = vdist;
		    if (closest) {
			*closest = vclosest;
		    }
		}
		if ((underTrim) && (udist < closesttrim)) {
		    closesttrim = udist;
		    if (closest) {
			*closest = uclosest;
		    }
		}
		return currTrimStatus;
	    }
	}
    } else {
	if (m_trimmed) {
	    return true;
	} else {
	    return false;
	}
    }
}