static int move_walk(ClientData UNUSED(clientData), Tcl_Interp *interp, int UNUSED(objc), Tcl_Obj *const *objv) { struct isst_s *isst; Togl *togl; vect_t vec; int flag; if (Togl_GetToglFromObj(interp, objv[1], &togl) != TCL_OK) return TCL_ERROR; isst = (struct isst_s *) Togl_GetClientData(togl); if (Tcl_GetIntFromObj(interp, objv[2], &flag) != TCL_OK) return TCL_ERROR; if (flag >= 0) { VSUB2(vec, isst->camera.focus, isst->camera.pos); VSCALE(vec, vec, 0.1 * isst->tie->radius); VADD2(isst->camera.pos, isst->camera.pos, vec); VADD2(isst->camera.focus, isst->camera.focus, vec); } else { VSUB2(vec, isst->camera.pos, isst->camera.focus); VSCALE(vec, vec, 0.1 * isst->tie->radius); VADD2(isst->camera.pos, isst->camera.pos, vec); VADD2(isst->camera.focus, isst->camera.focus, vec); } isst->dirty = 1; return TCL_OK; }
void Normals(void) { struct points *ptr; if ( root == NULL ) return; ptr = root->next; if ( ptr == NULL ) return; VSUB2( root->nnext, ptr->p, root->p ); VUNITIZE( root->nnext ); while ( ptr->next != NULL ) { VREVERSE( ptr->nprev, ptr->prev->nnext ); VSUB2( ptr->nnext, ptr->next->p, ptr->p ); VUNITIZE( ptr->nnext ); VCROSS( ptr->norm, ptr->nprev, ptr->nnext ); VUNITIZE( ptr->norm ); VADD2( ptr->nmitre, ptr->nprev, ptr->nnext ); VUNITIZE( ptr->nmitre ); VCROSS( ptr->mnorm, ptr->norm, ptr->nmitre ); VUNITIZE( ptr->mnorm ); if ( VDOT( ptr->mnorm, ptr->nnext ) > 0.0 ) VREVERSE( ptr->mnorm, ptr->mnorm ); ptr->alpha = acos( VDOT( ptr->nnext, ptr->nprev ) ); ptr = ptr->next; } }
void render_flos_work(render_t *render, struct tie_s *tie, struct tie_ray_s *ray, vect_t *pixel) { struct tie_id_s id, tid; vect_t vec; fastf_t angle; struct render_flos_s *rd; rd = (struct render_flos_s *)render->data; if (tie_work(tie, ray, &id, render_hit, NULL) != NULL) { VSET(*pixel, 0.0, 0.5, 0.0); } else return; VSUB2(vec, ray->pos, id.pos); VUNITIZE(vec); angle = VDOT(vec, id.norm); /* Determine if direct line of sight to fragment */ VMOVE(ray->pos, rd->frag_pos); VSUB2(ray->dir, id.pos, rd->frag_pos); VUNITIZE(ray->dir); if (tie_work(tie, ray, &tid, render_hit, NULL)) { if (fabs (id.pos[0] - tid.pos[0]) < TIE_PREC && fabs (id.pos[1] - tid.pos[1]) < TIE_PREC && fabs (id.pos[2] - tid.pos[2]) < TIE_PREC) { VSET(*pixel, 1.0, 0.0, 0.0); } } VSCALE(*pixel, *pixel, (0.5+angle*0.5)); }
/** * R T _ P G _ P L O T _ P O L Y * * Convert to vlist, draw as polygons. */ int rt_pg_plot_poly(struct bu_list *vhead, struct rt_db_internal *ip, const struct rt_tess_tol *UNUSED(ttol), const struct bn_tol *UNUSED(tol)) { size_t i; size_t p; /* current polygon number */ struct rt_pg_internal *pgp; BU_CK_LIST_HEAD(vhead); RT_CK_DB_INTERNAL(ip); pgp = (struct rt_pg_internal *)ip->idb_ptr; RT_PG_CK_MAGIC(pgp); for (p = 0; p < pgp->npoly; p++) { struct rt_pg_face_internal *pp; vect_t aa, bb, norm; pp = &pgp->poly[p]; if (pp->npts < 3) continue; VSUB2(aa, &pp->verts[3*(0)], &pp->verts[3*(1)]); VSUB2(bb, &pp->verts[3*(0)], &pp->verts[3*(2)]); VCROSS(norm, aa, bb); VUNITIZE(norm); RT_ADD_VLIST(vhead, norm, BN_VLIST_POLY_START); RT_ADD_VLIST(vhead, &pp->verts[3*(pp->npts-1)], BN_VLIST_POLY_MOVE); for (i=0; i < pp->npts-1; i++) { RT_ADD_VLIST(vhead, &pp->verts[3*i], BN_VLIST_POLY_DRAW); } RT_ADD_VLIST(vhead, &pp->verts[3*(pp->npts-1)], BN_VLIST_POLY_END); } return 0; /* OK */ }
int _ged_do_tra(struct ged *gedp, char coord, vect_t tvec, int (*func)()) { point_t delta; point_t work; point_t vc, nvc; if (func != (int (*)())0) return (*func)(gedp, coord, tvec); switch (coord) { case 'm': VSCALE(delta, tvec, -gedp->ged_wdbp->dbip->dbi_base2local); MAT_DELTAS_GET_NEG(vc, gedp->ged_gvp->gv_center); break; case 'v': default: VSCALE(tvec, tvec, -2.0*gedp->ged_wdbp->dbip->dbi_base2local*gedp->ged_gvp->gv_isize); MAT4X3PNT(work, gedp->ged_gvp->gv_view2model, tvec); MAT_DELTAS_GET_NEG(vc, gedp->ged_gvp->gv_center); VSUB2(delta, work, vc); break; } VSUB2(nvc, vc, delta); MAT_DELTAS_VEC_NEG(gedp->ged_gvp->gv_center, nvc); ged_view_update(gedp->ged_gvp); return GED_OK; }
inline void rt_metaball_norm_internal(vect_t *n, point_t *p, struct rt_metaball_internal *mb) { struct wdb_metaballpt *mbpt; vect_t v; fastf_t a; VSETALL(*n, 0.0); switch (mb->method) { case METABALL_METABALL: bu_log("Sorry, strict metaballs are not yet implemented\n"); break; case METABALL_ISOPOTENTIAL: for (BU_LIST_FOR(mbpt, wdb_metaballpt, &mb->metaball_ctrl_head)) { VSUB2(v, *p, mbpt->coord); a = MAGSQ(v); VJOIN1(*n, *n, fabs(mbpt->fldstr)*mbpt->fldstr / (SQ(a)), v); /* f/r^4 */ } break; case METABALL_BLOB: for (BU_LIST_FOR(mbpt, wdb_metaballpt, &mb->metaball_ctrl_head)) { VSUB2(v, *p, mbpt->coord); a = MAGSQ(v); VJOIN1(*n, *n, 2.0*mbpt->sweat/SQ(mbpt->fldstr)*exp(mbpt->sweat*(1-(a/SQ(mbpt->fldstr)))) , v); } break; default: bu_log("unknown metaball method\n"); break; } VUNITIZE(*n); }
static void render_camera_prep_ortho(render_camera_t *camera) { vect_t look, up, side, temp; tfloat angle, s, c; /* Generate standard up vector */ up[0] = 0; up[1] = 0; up[2] = 1; /* Generate unitized lookector */ VSUB2(look, camera->focus, camera->pos); VUNITIZE(look); /* Make unitized up vector perpendicular to lookector */ VMOVE(temp, look); angle = VDOT(up, temp); VSCALE(temp, temp, angle); VSUB2(up, up, temp); VUNITIZE(up); /* Generate a temporary side vector */ VCROSS(side, up, look); /* Apply tilt to up vector - negate angle to make positive angles clockwise */ s = sin(-camera->tilt * DEG2RAD); c = cos(-camera->tilt * DEG2RAD); VSCALE(up, up, c); VSCALE(side, side, s); VADD2(up, up, side); /* Create final side vector */ VCROSS(side, up, look); /* look direction */ VMOVE(camera->view_list[0].top_l, look); /* gridsize is millimeters along the horizontal axis to display */ /* left (side) */ VSCALE(temp, side, (camera->aspect * camera->gridsize * 0.5)); VADD2(camera->view_list[0].pos, camera->pos, temp); /* and (up) */ VSCALE(temp, up, (camera->gridsize * 0.5)); VADD2(camera->view_list[0].pos, camera->view_list[0].pos, temp); /* compute step vectors for camera position */ /* X */ VSCALE(camera->view_list[0].step_x, side, (-camera->gridsize * camera->aspect / (tfloat)camera->w)); /* Y */ VSCALE(camera->view_list[0].step_y, up, (-camera->gridsize / (tfloat)camera->h)); }
void top(fastf_t *vec1, fastf_t *vec2, fastf_t *t) { fastf_t tooch, mag; vect_t del, tvec; int i, j; tooch = t[2] * .25; del[0] = vec2[0] - vec1[0]; del[1] = 0.0; del[2] = vec2[2] - vec1[2]; mag = MAGNITUDE( del ); VSCALE(tvec, del, tooch/mag); VSUB2(&sol.s_values[0], vec1, tvec); VADD2(del, del, tvec); VADD2(&sol.s_values[3], del, tvec); tvec[0] = tvec[2] = 0.0; tvec[1] = t[1] - t[0]; VCROSS(del, tvec, &sol.s_values[3]); mag = MAGNITUDE( del ); if (del[2] < 0) mag *= -1.0; VSCALE(&sol.s_values[9], del, t[2]/mag); VADD2(&sol.s_values[6], &sol.s_values[3], &sol.s_values[9]); VMOVE(&sol.s_values[12], tvec); for (i=3; i<=9; i+=3) { j = i + 12; VADD2(&sol.s_values[j], &sol.s_values[i], tvec); } }
void make_room(char *rname, fastf_t *imin, fastf_t *imax, fastf_t *thickness, struct wmember *headp) /* Interior RPP min point */ { struct wmember head; char name[32]; vect_t omin; vect_t omax; BU_LIST_INIT( &head.l ); VSUB2( omin, imin, thickness ); VADD2( omax, imax, thickness ); snprintf( name, 32, "o%s", rname ); mk_rpp( outfp, name, omin, omax ); (void)mk_addmember( name, &head.l, NULL, WMOP_UNION ); snprintf( name, 32, "i%s", rname ); mk_rpp( outfp, name, imin, imax ); mk_addmember( name, &head.l, NULL, WMOP_SUBTRACT ); mk_lfcomb( outfp, rname, &head, 1 ); (void)mk_addmember( rname, &(headp->l), NULL, WMOP_UNION ); }
/** * For a hit on the surface of an METABALL, return the (u, v) * coordinates of the hit point, 0 <= u, v <= 1. * * u = azimuth * v = elevation */ void rt_metaball_uv(struct application *ap, struct soltab *stp, struct hit *hitp, struct uvcoord *uvp) { struct rt_metaball_internal *metaball = (struct rt_metaball_internal *)stp->st_specific; vect_t work, pprime; fastf_t r; if (ap) RT_CK_APPLICATION(ap); if (stp) RT_CK_SOLTAB(stp); if (hitp) RT_CK_HIT(hitp); if (!uvp) return; if (!metaball) return; /* stuff stolen from sph */ VSUB2(work, hitp->hit_point, stp->st_center); VSCALE(pprime, work, 1.0/MAGNITUDE(work)); /* Assert that pprime has unit length */ /* U is azimuth, atan() range: -pi to +pi */ uvp->uv_u = bn_atan2(pprime[Y], pprime[X]) * M_1_2PI; if (uvp->uv_u < 0) uvp->uv_u += 1.0; /* * V is elevation, atan() range: -pi/2 to +pi/2, because sqrt() * ensures that X parameter is always >0 */ uvp->uv_v = bn_atan2(pprime[Z], sqrt(pprime[X] * pprime[X] + pprime[Y] * pprime[Y])) * M_1_2PI; /* approximation: r / (circumference, 2 * pi * aradius) */ r = ap->a_rbeam + ap->a_diverge * hitp->hit_dist; uvp->uv_du = uvp->uv_dv = M_1_2PI * r / stp->st_aradius; return; }
void writeCylinder ( rt_wdb* wdbp, Form& form, bool translate ) { char name[NAMELEN + 1]; vect_t base, height; if (translate) { VADD2(base, form.data.pt[0], form.tr_vec); } else { VMOVE(base, form.data.pt[0]); } VSUB2(height, form.data.pt[1], form.data.pt[0]); VSCALE(base, base, IntavalUnitInMm); VSCALE(height, height, IntavalUnitInMm); fastf_t radius = form.radius1 * IntavalUnitInMm; sprintf(name, "s%lu.rcc", (long unsigned)++rcc_counter); mk_rcc(wdbp, name, base, height, radius); addToRegion(form.compnr, name); if (form.s_compnr >= 1000) excludeFromRegion(form.s_compnr, name); }
/** * Clip a ray against a rectangular parallelepiped (RPP) that has faces * parallel to the coordinate planes (a clipping RPP). The RPP is * defined by a minimum point and a maximum point. * * Returns - * 0 if ray does not hit RPP, * !0 if ray hits RPP. * * Implicit Return - * if !0 was returned, "a" and "b" have been clipped to the RPP. */ int vclip(vect_t a, vect_t b, fastf_t *min, fastf_t *max) { static vect_t diff; static double sv; static double st; static double mindist, maxdist; fastf_t *pt = &a[0]; fastf_t *dir = &diff[0]; int i; mindist = -CLIP_DISTANCE; maxdist = CLIP_DISTANCE; VSUB2(diff, b, a); for (i=0; i < 3; i++, pt++, dir++, max++, min++) { if (*dir < -EPSILON) { if ((sv = (*min - *pt) / *dir) < 0.0) return 0; /* MISS */ if (maxdist > sv) maxdist = sv; if (mindist < (st = (*max - *pt) / *dir)) mindist = st; } else if (*dir > EPSILON) { if ((st = (*max - *pt) / *dir) < 0.0) return 0; /* MISS */ if (maxdist > st) maxdist = st; if (mindist < ((sv = (*min - *pt) / *dir))) mindist = sv; } else { /* * If direction component along this axis is NEAR 0, * (i.e., this ray is aligned with this axis), merely * check against the boundaries. */ if ((*min > *pt) || (*max < *pt)) return 0; /* MISS */; } } if (mindist >= maxdist) return 0; /* MISS */ if (mindist > 1 || maxdist < 0) return 0; /* MISS */ if (mindist <= 0 && maxdist >= 1) return 1; /* HIT, no clipping needed */ /* Don't grow one end of a contained segment */ if (mindist < 0) mindist = 0; if (maxdist > 1) maxdist = 1; /* Compute actual intercept points */ VJOIN1(b, a, maxdist, diff); /* b must go first */ VJOIN1(a, a, mindist, diff); return 1; /* HIT */ }
/* * Determine whether the current hitpoint along a series of * reflections is visible from the origin of the ray. * (which is the location of our "point" eye for now) * * Strategy: we shoot back toward the origin of the ray * If we don't hit anything (i.e. miss) we made it. * If we hit something we made it if that distance is greater * than the distance back to the eye. */ static int isvisible( struct application *ap, struct hit *hitp, const vect_t norm ) { int cpu_num; struct application sub_ap; vect_t rdir; if ( ap->a_resource == RESOURCE_NULL) cpu_num = 0; else cpu_num = ap->a_resource->re_cpu; /* compute the ray direction */ VSUB2( rdir, firstray[cpu_num].r_pt, hitp->hit_point ); VUNITIZE( rdir ); if ( VDOT(rdir, norm) < 0 ) return 0; /* backfacing */ sub_ap = *ap; /* struct copy */ sub_ap.a_level = ap->a_level+1; sub_ap.a_onehit = 1; sub_ap.a_purpose = "sight"; sub_ap.a_hit = hiteye; sub_ap.a_miss = hittrue; /* * New origin is one unit in the ray direction in * order to get away from the surface we intersected. */ VADD2( sub_ap.a_ray.r_pt, hitp->hit_point, rdir ); VMOVE( sub_ap.a_ray.r_dir, rdir ); return rt_shootray( &sub_ap ); }
/* * W R A Y */ void wray(struct partition *pp, struct application *ap, FILE *fp, const vect_t inormal) { struct vldray vldray; register struct hit *hitp= pp->pt_inhit; VMOVE(&(vldray.ox), hitp->hit_point); VSUB2(&(vldray.rx), pp->pt_outhit->hit_point, hitp->hit_point); WRAY_NORMAL(vldray, inormal); vldray.pa = vldray.pe = vldray.pc = vldray.sc = 0; /* no curv */ /* Air is marked by zero or negative region ID codes. * When air is encountered, the air code is taken from reg_aircode. * The negative of the air code is used for the "ob" field, to * distinguish air from other regions. */ if ((vldray.ob = pp->pt_regionp->reg_regionid) <= 0) vldray.ob = -(pp->pt_regionp->reg_aircode); WRAY_TAG(vldray, ap); if (fwrite(&vldray, sizeof(struct vldray), 1, fp) != 1) bu_bomb("rway: write error"); }
/** * R E C _ C U R V E * * Return the "curvature" of the cylinder. If an endplate, * pick a principle direction orthogonal to the normal, and * indicate no curvature. Otherwise, compute curvature. * Normal must have been computed before calling this routine. */ void rt_rec_curve(struct curvature *cvp, struct hit *hitp, struct soltab *stp) { struct rec_specific *rec = (struct rec_specific *)stp->st_specific; vect_t uu; fastf_t ax, bx, q; switch (hitp->hit_surfno) { case REC_NORM_BODY: /* This could almost certainly be simpler if we used * inverse A rather than inverse A squared, right Ed? */ VMOVE(cvp->crv_pdir, rec->rec_Hunit); VSUB2(uu, hitp->hit_point, rec->rec_V); cvp->crv_c1 = 0; ax = VDOT(uu, rec->rec_A) * rec->rec_iAsq; bx = VDOT(uu, rec->rec_B) * rec->rec_iBsq; q = sqrt(ax * ax * rec->rec_iAsq + bx * bx * rec->rec_iBsq); cvp->crv_c2 = - rec->rec_iAsq * rec->rec_iBsq / (q*q*q); break; case REC_NORM_TOP: case REC_NORM_BOT: bn_vec_ortho(cvp->crv_pdir, hitp->hit_normal); cvp->crv_c1 = cvp->crv_c2 = 0; break; default: bu_log("rt_rec_curve: bad surfno %d\n", hitp->hit_surfno); break; } }
/* * Map "display plate coordinates" (which can just be the screen viewing cube), * into [-1, +1] coordinates, with perspective. * Per "High Resolution Virtual Reality" by Michael Deering, * Computer Graphics 26, 2, July 1992, pp 195-201. * * L is lower left corner of screen, H is upper right corner. * L[Z] is the front (near) clipping plane location. * H[Z] is the back (far) clipping plane location. * * This corresponds to the SGI "window()" routine, but taking into account * skew due to the eyepoint being offset parallel to the image plane. * * The gist of the algorithm is to translate the display plate to the * view center, shear the eye point to (0, 0, 1), translate back, * then apply an off-axis perspective projection. * * Another (partial) reference is "A comparison of stereoscopic cursors * for the interactive manipulation of B-splines" by Barham & McAllister, * SPIE Vol 1457 Stereoscopic Display & Applications, 1991, pg 19. */ void ged_deering_persp_mat(fastf_t *m, const fastf_t *l, const fastf_t *h, const fastf_t *eye) /* lower left corner of screen */ /* upper right (high) corner of screen */ /* eye location. Traditionally at (0, 0, 1) */ { vect_t diff; /* H - L */ vect_t sum; /* H + L */ VSUB2(diff, h, l); VADD2(sum, h, l); m[0] = 2 * eye[Z] / diff[X]; m[1] = 0; m[2] = (sum[X] - 2 * eye[X]) / diff[X]; m[3] = -eye[Z] * sum[X] / diff[X]; m[4] = 0; m[5] = 2 * eye[Z] / diff[Y]; m[6] = (sum[Y] - 2 * eye[Y]) / diff[Y]; m[7] = -eye[Z] * sum[Y] / diff[Y]; /* Multiplied by -1, to do right-handed Z coords */ m[8] = 0; m[9] = 0; m[10] = -(sum[Z] - 2 * eye[Z]) / diff[Z]; m[11] = -(-eye[Z] + 2 * h[Z] * eye[Z]) / diff[Z]; m[12] = 0; m[13] = 0; m[14] = -1; m[15] = eye[Z]; /* XXX May need to flip Z ? (lefthand to righthand?) */ }
static int find_closest_color(float color[3]) { int icolor[3]; int i; int dist_sq; int color_num; VSCALE(icolor, color, 255); color_num = 0; dist_sq = MAGSQ(icolor); for (i = 1; i < 256; i++) { int tmp_dist; int diff[3]; VSUB2(diff, icolor, &rgb[i*3]); tmp_dist = MAGSQ(diff); if (tmp_dist < dist_sq) { dist_sq = tmp_dist; color_num = i; } } return color_num; }
static int hit_headon(struct application *ap, struct partition *PartHeadp) { register char diff_solid; vect_t diff; register fastf_t len; if (PartHeadp->pt_forw->pt_forw != PartHeadp) Tcl_AppendResult(interp, "hit_headon: multiple partitions\n", (char *)NULL); VJOIN1(PartHeadp->pt_forw->pt_inhit->hit_point, ap->a_ray.r_pt, PartHeadp->pt_forw->pt_inhit->hit_dist, ap->a_ray.r_dir); VSUB2(diff, PartHeadp->pt_forw->pt_inhit->hit_point, aim_point); diff_solid = (FIRST_SOLID(sp) != PartHeadp->pt_forw->pt_inseg->seg_stp->st_dp); len = MAGNITUDE(diff); if ( NEAR_ZERO(len, epsilon) || ( diff_solid && VDOT(diff, ap->a_ray.r_dir) > 0 ) ) return(1); else return(0); }
/* * Determine whether the current hitpoint along a series of * reflections is visible from the origin of the ray. * (which is the location of our "point" eye for now) * * Strategy: we shoot back toward the origin of the ray * If we don't hit anything (i.e. miss) we made it. * If we hit something we made it if that distance is greater * than the distance back to the eye. */ static int isvisible(struct application *ap, struct hit *hitp, const fastf_t *norm) { struct application sub_ap; vect_t rdir; /* compute the ray direction */ VSUB2( rdir, firstray.r_pt, hitp->hit_point ); VUNITIZE( rdir ); if ( VDOT(rdir, norm) < 0 ) return( 0 ); /* backfacing */ sub_ap = *ap; /* struct copy */ sub_ap.a_level = ap->a_level+1; sub_ap.a_onehit = 1; sub_ap.a_hit = hiteye; sub_ap.a_miss = hittrue; /* * New origin is one unit in the ray direction in * order to get away from the surface we intersected. */ VADD2( sub_ap.a_ray.r_pt, hitp->hit_point, rdir ); VMOVE( sub_ap.a_ray.r_dir, rdir ); return( rt_shootray( &sub_ap ) ); }
void calc_isect2(point_t VTX0, point_t VTX1, point_t VTX2, fastf_t VV0, fastf_t VV1, fastf_t VV2, fastf_t D0, fastf_t D1, fastf_t D2, fastf_t *isect0, fastf_t *isect1, point_t isectpoint0, point_t isectpoint1) { fastf_t tmp=D0/(D0-D1); point_t diff; *isect0=VV0+(VV1-VV0)*tmp; VSUB2(diff, VTX1, VTX0); VSCALE(diff, diff, tmp); VADD2(isectpoint0, diff, VTX0); tmp=D0/(D0-D2); *isect1=VV0+(VV2-VV0)*tmp; VSUB2(diff, VTX2, VTX0); VSCALE(diff, diff, tmp); VADD2(isectpoint1, VTX0, diff); }
static int isst_load_g(ClientData UNUSED(clientData), Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { struct isst_s *isst; char **argv; int argc; double az, el; struct bu_vls tclstr = BU_VLS_INIT_ZERO; vect_t vec; Togl *togl; if (objc < 4) { Tcl_WrongNumArgs(interp, 1, objv, "load_g pathname object"); return TCL_ERROR; } if (Togl_GetToglFromObj(interp, objv[1], &togl) != TCL_OK) { return TCL_ERROR; } isst = (struct isst_s *) Togl_GetClientData(togl); argv = (char **)malloc(sizeof(char *) * (strlen(Tcl_GetString(objv[3])) + 1)); /* allocate way too much. */ argc = bu_argv_from_string(argv, strlen(Tcl_GetString(objv[3])), Tcl_GetString(objv[3])); load_g(isst->tie, Tcl_GetString(objv[2]), argc, (const char **)argv, &(isst->meshes)); free(argv); VSETALL(isst->camera.pos, isst->tie->radius); VMOVE(isst->camera.focus, isst->tie->mid); VMOVE(isst->camera_pos_init, isst->camera.pos); VMOVE(isst->camera_focus_init, isst->camera.focus); /* Set the initial az and el values in Tcl/Tk */ VSUB2(vec, isst->camera.pos, isst->camera.focus); VUNITIZE(vec); AZEL_FROM_V3DIR(az, el, vec); az = az * -DEG2RAD; el = el * -DEG2RAD; bu_vls_sprintf(&tclstr, "%f", az); Tcl_SetVar(interp, "az", bu_vls_addr(&tclstr), 0); bu_vls_sprintf(&tclstr, "%f", el); Tcl_SetVar(interp, "el", bu_vls_addr(&tclstr), 0); bu_vls_free(&tclstr); render_phong_init(&isst->camera.render, NULL); isst->ogl = 1; isst->w = Togl_Width(togl); isst->h = Togl_Height(togl); resize_isst(isst); isst->t1 = bu_gettime(); isst->t2 = bu_gettime(); return TCL_OK; }
HIDDEN void get_cbar(void) { int eid, pid; int g1, g2; point_t pt1, pt2; fastf_t radius; vect_t height; struct pbar *pb; char cbar_name[NAMESIZE+1]; eid = atoi( curr_rec[1] ); pid = atoi( curr_rec[2] ); if ( !pid ) { if ( bar_def_pid ) pid = bar_def_pid; else pid = eid; } g1 = atoi( curr_rec[3] ); g2 = atoi( curr_rec[4] ); get_grid( g1, pt1 ); get_grid( g2, pt2 ); for ( BU_LIST_FOR( pb, pbar, &pbar_head.l ) ) { if ( pb->pid == pid ) break; } if ( BU_LIST_IS_HEAD( &pb->l, &pbar_head.l ) ) { log_line( "Non-existent PID referenced in CBAR" ); return; } VSCALE( pt1, pt1, conv[units] ); VSCALE( pt2, pt2, conv[units] ); radius = sqrt( pb->area/bn_pi ); radius = radius * conv[units]; VSUB2( height, pt2, pt1 ); sprintf( cbar_name, "cbar.%d", eid ); mk_rcc( fpout, cbar_name, pt1, height, radius ); mk_addmember( cbar_name, &pb->head.l, NULL, WMOP_UNION ); }
void rt_arbn_centroid(point_t *cent, const struct rt_db_internal *ip) { struct poly_face *faces; struct rt_arbn_internal *aip = (struct rt_arbn_internal *)ip->idb_ptr; size_t i; point_t arbit_point = VINIT_ZERO; fastf_t volume = 0.0; *cent[0] = 0.0; *cent[1] = 0.0; *cent[2] = 0.0; if (cent == NULL) return; /* allocate array of face structs */ faces = (struct poly_face *)bu_calloc(aip->neqn, sizeof(struct poly_face), "rt_arbn_centroid: faces"); for (i = 0; i < aip->neqn; i++) { /* allocate array of pt structs, max number of verts per faces = (# of faces) - 1 */ faces[i].pts = (point_t *)bu_calloc(aip->neqn - 1, sizeof(point_t), "rt_arbn_centroid: pts"); } rt_arbn_faces_area(faces, aip); for (i = 0; i < aip->neqn; i++) { bn_polygon_centroid(&faces[i].cent, faces[i].npts, (const point_t *) faces[i].pts); VADD2(arbit_point, arbit_point, faces[i].cent); } VSCALE(arbit_point, arbit_point, (1/aip->neqn)); for (i = 0; i < aip->neqn; i++) { vect_t tmp = VINIT_ZERO; /* calculate volume */ VSCALE(tmp, faces[i].plane_eqn, faces[i].area); faces[i].vol_pyramid = (VDOT(faces[i].pts[0], tmp)/3); volume += faces[i].vol_pyramid; /*Vector from arbit_point to centroid of face, results in h of pyramid */ VSUB2(faces[i].cent_pyramid, faces[i].cent, arbit_point); /*centroid of pyramid is 1/4 up from the bottom */ VSCALE(faces[i].cent_pyramid, faces[i].cent_pyramid, 0.75f); /* now cent_pyramid is back in the polyhedron */ VADD2(faces[i].cent_pyramid, faces[i].cent_pyramid, arbit_point); /* weight centroid of pyramid by pyramid's volume */ VSCALE(faces[i].cent_pyramid, faces[i].cent_pyramid, faces[i].vol_pyramid); /* add cent_pyramid to the centroid of the polyhedron */ VADD2(*cent, *cent, faces[i].cent_pyramid); } /* reverse the weighting */ VSCALE(*cent, *cent, (1/volume)); for (i = 0; i < aip->neqn; i++) { bu_free((char *)faces[i].pts, "rt_arbn_centroid: pts"); } bu_free((char *)faces, "rt_arbn_centroid: faces"); }
HIDDEN int convert_cs(struct coord_sys *cs) { struct coord_sys *cs2; point_t tmp_orig, tmp_pt1, tmp_pt2; VSETALL(tmp_orig, 0.0); VSETALL(tmp_pt1, 0.0); VSETALL(tmp_pt2, 0.0); if (!cs->rid) return 0; for (BU_LIST_FOR(cs2, coord_sys, &coord_head.l)) { if (cs2->cid != cs->rid) continue; break; } if (BU_LIST_IS_HEAD(&cs2->l, &coord_head.l)) { bu_exit(1, "A coordinate system is defined in terms of a non-existent coordinate system!!!\n"); } if (convert_pt(cs->origin, cs2, tmp_orig)) return 1; if (convert_pt(cs->v1, cs2, tmp_pt1)) return 1; if (convert_pt(cs->v2, cs2, tmp_pt2)) return 1; VMOVE(cs->origin, tmp_orig); VSUB2(cs->v3, tmp_pt1, cs->origin); VUNITIZE(cs->v3); VSUB2(cs->v1, tmp_pt2, cs->origin); VCROSS(cs->v2, cs->v3, cs->v1); VUNITIZE(cs->v2); VCROSS(cs->v1, cs->v3, cs->v2); cs->rid = 0; return 0; }
void compute_normal(struct rt_bot_internal *bot, int p1, int p2, int p3, float *dest) { float v1[3]; float v2[3]; float v3[3]; float vec1[3]; float vec2[3]; float fnorm[3]; float temp[3]; float *np1, *np2, *np3; /* get face normal */ get_vertex(bot, p1, v1); if (flip_normals) { get_vertex(bot, p3, v2); get_vertex(bot, p2, v3); } else { get_vertex(bot, p2, v2); get_vertex(bot, p3, v3); } VSUB2(vec1, v1, v2); VSUB2(vec2, v1, v3); VCROSS(fnorm, vec1, vec2); VUNITIZE(fnorm); /* average existing normal with face normal per vertex */ np1 = dest + 3*p1; np2 = dest + 3*p2; np3 = dest + 3*p3; VADD2(temp, fnorm, np1); VUNITIZE(temp); VMOVE(np1, temp); VADD2(temp, fnorm, np2); VUNITIZE(temp); VMOVE(np2, temp); VADD2(temp, fnorm, np3); VUNITIZE(temp); VMOVE(np3, temp); }
/** * Classify a point vs a vertex (touching/missed) */ static int nmg_class_pt_vu(struct fpi *fpi, struct vertexuse *vu) { vect_t delta; struct ve_dist *ved; NMG_CK_VERTEXUSE(vu); /* see if we've classified this vertex WRT the point already */ for (BU_LIST_FOR(ved, ve_dist, &fpi->ve_dh)) { NMG_CK_VED(ved); if (ved->magic_p == &vu->v_p->magic) { goto found; } } /* if we get here, we didn't find the vertex in the list of * previously classified geometry. Create an entry in the * face's list of processed geometry. */ VSUB2(delta, vu->v_p->vg_p->coord, fpi->pt); BU_ALLOC(ved, struct ve_dist); ved->magic_p = &vu->v_p->magic; ved->dist = MAGNITUDE(delta); if (ved->dist < fpi->tol->dist_sq) { ved->status = NMG_FPI_TOUCHED; if (fpi->hits == NMG_FPI_PERGEOM) { /* need to cast vu_func pointer for actual use as a function */ void (*cfp)(struct vertexuse *, point_t, const char*); cfp = (void (*)(struct vertexuse *, point_t, const char *))fpi->vu_func; cfp(vu, fpi->pt, fpi->priv); } } else ved->status = NMG_FPI_MISSED; ved->v1 = ved->v2 = vu->v_p; BU_LIST_MAGIC_SET(&ved->l, NMG_VE_DIST_MAGIC); BU_LIST_APPEND(&fpi->ve_dh, &ved->l); found: if (fpi->vu_func && ved->status == NMG_FPI_TOUCHED && fpi->hits == NMG_FPI_PERUSE) { /* need to cast vu_func pointer for actual use as a function */ void (*cfp)(struct vertexuse *, point_t, const char*); cfp = (void (*)(struct vertexuse *, point_t, const char *))fpi->vu_func; cfp(vu, fpi->pt, fpi->priv); } return ved->status; }
/** * R T _ P G F A C E * * This function is called with pointers to 3 points, * and is used to prepare PG faces. * ap, bp, cp point to vect_t points. * * Return - * 0 if the 3 points didn't form a plane (e.g., colinear, etc.). * # pts (3) if a valid plane resulted. */ HIDDEN int rt_pgface(struct soltab *stp, fastf_t *ap, fastf_t *bp, fastf_t *cp, const struct bn_tol *tol) { struct tri_specific *trip; vect_t work; fastf_t m1, m2, m3, m4; BU_GET(trip, struct tri_specific); VMOVE(trip->tri_A, ap); VSUB2(trip->tri_BA, bp, ap); VSUB2(trip->tri_CA, cp, ap); VCROSS(trip->tri_wn, trip->tri_BA, trip->tri_CA); /* Check to see if this plane is a line or pnt */ m1 = MAGNITUDE(trip->tri_BA); m2 = MAGNITUDE(trip->tri_CA); VSUB2(work, bp, cp); m3 = MAGNITUDE(work); m4 = MAGNITUDE(trip->tri_wn); if (m1 < tol->dist || m2 < tol->dist || m3 < tol->dist || m4 < tol->dist) { BU_PUT(trip, struct tri_specific); if (RT_G_DEBUG & DEBUG_ARB8) bu_log("pg(%s): degenerate facet\n", stp->st_name); return 0; /* BAD */ } /* wn is a normal of not necessarily unit length. * N is an outward pointing unit normal. * We depend on the points being given in CCW order here. */ VMOVE(trip->tri_N, trip->tri_wn); VUNITIZE(trip->tri_N); /* Add this face onto the linked list for this solid */ trip->tri_forw = (struct tri_specific *)stp->st_specific; stp->st_specific = (genptr_t)trip; return 3; /* OK */ }
fastf_t rt_metaball_point_value_iso(const point_t *p, const struct bu_list *points) { struct wdb_metaballpt *mbpt; fastf_t ret = 0.0; point_t v; for (BU_LIST_FOR(mbpt, wdb_metaballpt, points)) { VSUB2(v, mbpt->coord, *p); ret += fabs(mbpt->fldstr) * mbpt->fldstr / MAGSQ(v); /* f/r^2 */ } return ret; }
int soup_add_face_precomputed(struct soup_s *s, point_t a, point_t b , point_t c, plane_t d, uint32_t foo) { struct face_s *f; vect_t e1, e2, x; VSUB2(e1, b, a); VSUB2(e2, c, a); VCROSS(x, e1, e2); /* grow face array if needed */ if (s->nfaces >= s->maxfaces) s->faces = (struct face_s *)bu_realloc(s->faces, (s->maxfaces += faces_per_page) * sizeof(struct face_s), "bot soup faces"); f = s->faces + s->nfaces; VMOVE(f->vert[0], a); if (VDOT(x, d) <= 0) { VMOVE(f->vert[1], b); VMOVE(f->vert[2], c); } else { VMOVE(f->vert[1], c); VMOVE(f->vert[2], b); } HMOVE(f->plane, d); /* solve the bounding box (should this be VMINMAX?) */ VMOVE(f->min, f->vert[0]); VMOVE(f->max, f->vert[0]); VMIN(f->min, f->vert[1]); VMAX(f->max, f->vert[1]); VMIN(f->min, f->vert[2]); VMAX(f->max, f->vert[2]); /* fluff the bounding box for fp fuzz */ f->min[X]-=.1; f->min[Y]-=.1; f->min[Z]-=.1; f->max[X]+=.1; f->max[Y]+=.1; f->max[Z]+=.1; f->foo = foo; s->nfaces++; return 0; }
/** *@brief * Draw a vector between points "from" and "to", with the option of * having an arrowhead on either or both ends. * * The fromheadfract and toheadfract values indicate the length of the * arrowheads relative to the length of the vector to-from. A typical * value is 0.1, making the head 10% of the size of the vector. The * sign of the "fract" values indicates the pointing direction. * Positive points towards the "to" point, negative points towards * "from". Upon return, the virtual pen is left at the "to" position. */ void tp_3vector(FILE *plotfp, fastf_t *from, fastf_t *to, double fromheadfract, double toheadfract) { register fastf_t len; register fastf_t hooklen; vect_t diff; vect_t c1, c2; vect_t h1, h2; vect_t backup; point_t tip; pdv_3line(plotfp, from, to); /* "pen" is left at "to" position */ VSUB2(diff, to, from); if ((len = MAGNITUDE(diff)) < SMALL) return; VSCALE(diff, diff, 1/len); bn_vec_ortho(c1, diff); VCROSS(c2, c1, diff); if (!ZERO(fromheadfract)) { hooklen = fromheadfract*len; VSCALE(backup, diff, -hooklen); VSCALE(h1, c1, hooklen); VADD3(tip, from, h1, backup); pdv_3move(plotfp, from); pdv_3cont(plotfp, tip); VSCALE(h2, c2, hooklen); VADD3(tip, from, h2, backup); pdv_3move(plotfp, tip); } if (!ZERO(toheadfract)) { hooklen = toheadfract*len; VSCALE(backup, diff, -hooklen); VSCALE(h1, c1, hooklen); VADD3(tip, to, h1, backup); pdv_3move(plotfp, to); pdv_3cont(plotfp, tip); VSCALE(h2, c2, hooklen); VADD3(tip, to, h2, backup); pdv_3move(plotfp, tip); } /* Be certain "pen" is left at "to" position */ if (!ZERO(fromheadfract) || !ZERO(toheadfract)) pdv_3cont(plotfp, to); }