/** * Create a perspective matrix that transforms the +/1 viewing cube, * with the actual eye position (not at Z=+1) specified in viewing * coords, into a related space where the eye has been sheared onto * the Z axis and repositioned at Z=(0, 0, 1), with the same * perspective field of view as before. * * The Zbuffer clips off stuff with negative Z values. * * pmat = persp * xlate * shear */ void ged_mike_persp_mat(mat_t pmat, const point_t eye) { mat_t shear; mat_t persp; mat_t xlate; mat_t t1, t2; point_t sheared_eye; if (eye[Z] <= SMALL) { VPRINT("mike_persp_mat(): ERROR, z<0, eye", eye); return; } /* Shear "eye" to +Z axis */ MAT_IDN(shear); shear[2] = -eye[X]/eye[Z]; shear[6] = -eye[Y]/eye[Z]; MAT4X3VEC(sheared_eye, shear, eye); if (!NEAR_ZERO(sheared_eye[X], .01) || !NEAR_ZERO(sheared_eye[Y], .01)) { VPRINT("ERROR sheared_eye", sheared_eye); return; } /* Translate along +Z axis to put sheared_eye at (0, 0, 1). */ MAT_IDN(xlate); /* XXX should I use MAT_DELTAS_VEC_NEG()? X and Y should be 0 now */ MAT_DELTAS(xlate, 0, 0, 1-sheared_eye[Z]); /* Build perspective matrix inline, substituting fov=2*atan(1, Z) */ MAT_IDN(persp); /* From page 492 of Graphics Gems */ persp[0] = sheared_eye[Z]; /* scaling: fov aspect term */ persp[5] = sheared_eye[Z]; /* scaling: determines fov */ /* From page 158 of Rogers Mathematical Elements */ /* Z center of projection at Z=+1, r=-1/1 */ persp[14] = -1; bn_mat_mul(t1, xlate, shear); bn_mat_mul(t2, persp, t1); /* Now, move eye from Z=1 to Z=0, for clipping purposes */ MAT_DELTAS(xlate, 0, 0, -1); bn_mat_mul(pmat, xlate, t2); }
void do_tree(char *name, char *lname, int level) { int i; char nm[64]; char *leafp; int scale; struct wmember head; struct wmember *wp; BU_LIST_INIT(&head.l); if (level <= 1) leafp = lname; else leafp = nm; scale = 100; for (i=1; i<level; i++) scale *= 2; snprintf(nm, 64, "%sL", name); wp = mk_addmember(leafp, &head.l, NULL, WMOP_UNION); MAT_IDN(wp->wm_mat); snprintf(nm, 64, "%sR", name); wp = mk_addmember(leafp, &head.l, NULL, WMOP_UNION); MAT_DELTAS(wp->wm_mat, 1*scale, 0, 0); snprintf(nm, 64, "%sB", name); wp = mk_addmember(leafp, &head.l, NULL, WMOP_UNION); MAT_DELTAS(wp->wm_mat, 0.5*scale, sin60*scale, 0); snprintf(nm, 64, "%sT", name); wp = mk_addmember(leafp, &head.l, NULL, WMOP_UNION); MAT_DELTAS(wp->wm_mat, 0.5*scale, sin60/3*scale, sin60*scale); /* Set region flag on lowest level */ mk_lcomb(outfp, name, &head, level<=1, NULL, NULL, NULL, 0); /* Loop for children if level > 1 */ if (level <= 1) return; for (i=0; i<4; i++) { snprintf(nm, 64, "%s%c", name, "LRBTx"[i]); do_tree(nm, lname, level-1); } }
void make_pillar(char *prefix, int ix, int iy, fastf_t *center, fastf_t *lwh, struct wmember *headp) /* center of base */ { vect_t min, max; unsigned char rgb[4]; /* needs all 4 */ char pilname[32], rname[32], sname[32], oname[32]; int i; struct wmember head; struct wmember *wp; BU_LIST_INIT( &head.l ); snprintf( pilname, 32, "%s%d,%d", prefix, ix, iy ); snprintf( rname, 32, "%s.r", pilname ); snprintf( sname, 32, "%s.s", pilname ); snprintf( oname, 32, "Obj%d,%d", ix, iy ); VMOVE( min, center ); min[X] -= lwh[X]; min[Y] -= lwh[Y]; VADD2( max, center, lwh ); mk_rpp( outfp, sname, min, max ); /* Needs to be in a region, with color! */ get_rgb(rgb); i = PICK_MAT; mk_region1( outfp, rname, sname, mtab[i].mt_name, mtab[i].mt_param, rgb ); (void)mk_addmember( rname, &head.l, NULL, WMOP_UNION ); wp = mk_addmember( oname, &head.l, NULL, WMOP_UNION ); MAT_DELTAS( wp->wm_mat, center[X], center[Y], center[Z]+lwh[Z] ); mk_lfcomb( outfp, pilname, &head, 0 ); (void)mk_addmember( pilname, &(headp->l), NULL, WMOP_UNION ); }
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(¢er[X], ""); Readcnv(¢er[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; }
/* * Returns - * -2 unknown keyword * -1 error in processing keyword * 0 OK */ int multi_words( char *words[], int nwords ) { if ( strcmp( words[0], "rot" ) == 0 ) { mat_t mat; /* Expects rotations rx, ry, rz, in degrees */ if ( nwords < 4 ) return(-1); MAT_IDN( mat ); bn_mat_angles( mat, atof( words[1] ), atof( words[2] ), atof( words[3] ) ); out_mat( mat, stdout ); return(0); } if ( strcmp( words[0], "xlate" ) == 0 ) { mat_t mat; if ( nwords < 4 ) return(-1); /* Expects translations tx, ty, tz */ MAT_IDN( mat ); MAT_DELTAS( mat, atof( words[1] ), atof( words[2] ), atof( words[3] ) ); out_mat( mat, stdout ); return(0); } if ( strcmp( words[0], "rot_at" ) == 0 ) { mat_t mat; mat_t mat1; mat_t mat2; mat_t mat3; /* JG - Expects x, y, z, rx, ry, rz */ /* Translation back to the origin by (-x, -y, -z) */ /* is done first, then the rotation, and finally */ /* back into the original position by (+x, +y, +z). */ if ( nwords < 7 ) return(-1); MAT_IDN( mat1 ); MAT_IDN( mat2 ); MAT_IDN( mat3 ); MAT_DELTAS( mat1, -atof( words[1] ), -atof( words[2] ), -atof( words[3] ) ); bn_mat_angles( mat2, atof( words[4] ), atof( words[5] ), atof( words[6] ) ); MAT_DELTAS( mat3, atof( words[1] ), atof( words[2] ), atof( words[3] ) ); bn_mat_mul( mat, mat2, mat1 ); bn_mat_mul2( mat3, mat ); out_mat( mat, stdout ); return(0); } if ( strcmp( words[0], "orient" ) == 0 ) { register int i; mat_t mat; double args[8]; /* Expects tx, ty, tz, rx, ry, rz, [scale]. */ /* All rotation is done first, then translation */ /* Note: word[0] and args[0] are the keyword */ if ( nwords < 6+1 ) return(-1); for ( i=1; i<6+1; i++ ) args[i] = 0; args[7] = 1.0; /* optional arg, default to 1 */ for ( i=1; i<nwords; i++ ) args[i] = atof( words[i] ); MAT_IDN( mat ); bn_mat_angles( mat, args[4], args[5], args[6] ); MAT_DELTAS( mat, args[1], args[2], args[3] ); if ( NEAR_ZERO( args[7], VDIVIDE_TOL ) ) { /* Nearly zero, signal error */ fprintf(stderr, "Orient scale arg is near zero ('%s')\n", words[7] ); return(-1); } else { mat[15] = 1 / args[7]; } out_mat( mat, stdout ); return(0); } if ( strcmp( words[0], "ae" ) == 0 ) { mat_t mat; fastf_t az, el; if ( nwords < 3 ) return(-1); /* Expects azimuth, elev, optional twist */ az = atof(words[1]); el = atof(words[2]); #if 0 if ( nwords == 3 ) twist = 0.0; else twist = atof(words[3]); #endif MAT_IDN( mat ); /* XXX does not take twist, for now XXX */ bn_mat_ae( mat, az, el ); out_mat( mat, stdout ); return(0); } if ( strcmp( words[0], "arb_rot_pt" ) == 0 ) { mat_t mat; point_t pt1, pt2; vect_t dir; fastf_t ang; if ( nwords < 1+3+3+1 ) return(-1); /* Expects point1, point2, angle */ VSET( pt1, atof(words[1]), atof(words[2]), atof(words[3]) ); VSET( pt2, atof(words[4]), atof(words[5]), atof(words[6]) ); ang = atof(words[7]) * bn_degtorad; VSUB2( dir, pt2, pt2 ); VUNITIZE(dir); MAT_IDN( mat ); bn_mat_arb_rot( mat, pt1, dir, ang ); out_mat( mat, stdout ); return(0); } if ( strcmp( words[0], "arb_rot_dir" ) == 0 ) { mat_t mat; point_t pt1; vect_t dir; fastf_t ang; if ( nwords < 1+3+3+1 ) return(-1); /* Expects point1, dir, angle */ VSET( pt1, atof(words[1]), atof(words[2]), atof(words[3]) ); VSET( dir, atof(words[4]), atof(words[5]), atof(words[6]) ); ang = atof(words[7]) * bn_degtorad; VUNITIZE(dir); MAT_IDN( mat ); bn_mat_arb_rot( mat, pt1, dir, ang ); out_mat( mat, stdout ); return(0); } if ( strcmp( words[0], "quat" ) == 0 ) { mat_t mat; quat_t quat; /* Usage: quat x, y, z, w */ if ( nwords < 5 ) return -1; QSET( quat, atof(words[1]), atof(words[2]), atof(words[3]), atof(words[4]) ); quat_quat2mat( mat, quat ); out_mat( mat, stdout); return 0; } if ( strcmp( words[0], "fromto" ) == 0 ) { mat_t mat; point_t cur; point_t next; vect_t from; vect_t to; /* Usage: fromto +Z cur_xyz next_xyz */ if ( nwords < 8 ) return -1; if ( strcmp( words[1], "+X" ) == 0 ) { VSET( from, 1, 0, 0 ); } else if ( strcmp( words[1], "-X" ) == 0 ) { VSET( from, -1, 0, 0 ); } else if ( strcmp( words[1], "+Y" ) == 0 ) { VSET( from, 0, 1, 0 ); } else if ( strcmp( words[1], "-Y" ) == 0 ) { VSET( from, 0, -1, 0 ); } else if ( strcmp( words[1], "+Z" ) == 0 ) { VSET( from, 0, 0, 1 ); } else if ( strcmp( words[1], "-Z" ) == 0 ) { VSET( from, 0, 0, -1 ); } else { fprintf(stderr, "fromto '%s' is not +/-XYZ\n", words[1]); return -1; } VSET( cur, atof(words[2]), atof(words[3]), atof(words[4]) ); VSET( next, atof(words[5]), atof(words[6]), atof(words[7]) ); VSUB2( to, next, cur ); VUNITIZE(to); bn_mat_fromto( mat, from, to ); /* Check to see if it worked. */ { vect_t got; MAT4X3VEC( got, mat, from ); if ( VDOT( got, to ) < 0.9 ) { bu_log("\ntabsub ERROR: At t=%s, bn_mat_fromto failed!\n", chanwords[0] ); VPRINT("\tfrom", from); VPRINT("\tto", to); VPRINT("\tgot", got); } } out_mat( mat, stdout ); return 0; } return(-2); /* Unknown keyword */ }