/* * R T _ M E T A B A L L _ S H O T */ int rt_metaball_shot(struct soltab *stp, register struct xray *rp, struct application *ap, struct seg *seghead) { struct rt_metaball_internal *mb = (struct rt_metaball_internal *)stp->st_specific; struct seg *segp = NULL; int retval = 0; fastf_t step, distleft; point_t p, inc; const point_t *cp = (const point_t *)&p; /* switching behavior to retain old code for performance and correctness * comparisons. */ #define SHOOTALGO 3 #if SHOOTALGO == 2 int fhin = 1; #endif step = mb->initstep; distleft = (rp->r_max-rp->r_min) + step * 3.0; VMOVE(p, rp->r_pt); VSCALE(inc, rp->r_dir, step); /* assume it's normalized and we want to creep at step */ /* walk back out of the solid */ while(rt_metaball_point_value(cp, mb) >= mb->threshold) { #if SHOOTALGO == 2 fhin = -1; #endif distleft += step; VSUB2(p, p, inc); } #if SHOOTALGO == 2 /* we hit, but not as fine-grained as we want. So back up one step, * cut the step size in half and start over... */ { int mb_stat = 0, segsleft = abs(ap->a_onehit); point_t delta; #define STEPBACK { distleft += step; VSUB2(p, p, inc); step *= .5; VSCALE(inc, inc, .5); } #define STEPIN(x) { \ --segsleft; \ ++retval; \ VSUB2(delta, p, rp->r_pt); \ segp->seg_##x.hit_dist = fhin * MAGNITUDE(delta); \ segp->seg_##x.hit_surfno = 0; } while (mb_stat == 0 && distleft >= -0) { int in; distleft -= step; VADD2(p, p, inc); in = rt_metaball_point_value(cp, mb) > mb->threshold; if (mb_stat == 1) if ( !in ) if (step<=mb->finalstep) { STEPIN(out) step = mb->initstep; mb_stat = 0; if (ap->a_onehit != 0 || segsleft <= 0) return retval; } else STEPBACK else if ( in ) if (step<=mb->finalstep) { RT_GET_SEG(segp, ap->a_resource); segp->seg_stp = stp; STEPIN(in) fhin = 1; BU_LIST_INSERT(&(seghead->l), &(segp->l)); /* reset the ray-walk stuff */ mb_stat = 1; VADD2(p, p, inc); /* set p to a point inside */ step = mb->initstep; } else STEPBACK } } #undef STEPBACK #undef STEPIN #elif SHOOTALGO == 3 { int mb_stat = 0, segsleft = abs(ap->a_onehit); point_t lastpoint; while (distleft >= 0.0 || mb_stat == 1) { /* advance to the next point */ distleft -= step; VMOVE(lastpoint, p); VADD2(p, p, inc); if (mb_stat == 1) { if (rt_metaball_point_value(cp, mb) < mb->threshold) { point_t intersect, delta; const point_t *pA = (const point_t *)&lastpoint; const point_t *pB = (const point_t *)&p; rt_metaball_find_intersection(&intersect, mb, pA, pB, step, mb->finalstep); VMOVE(segp->seg_out.hit_point, intersect); --segsleft; ++retval; VSUB2(delta, intersect, rp->r_pt); segp->seg_out.hit_dist = MAGNITUDE(delta); segp->seg_out.hit_surfno = 0; mb_stat = 0; if (ap->a_onehit != 0 && segsleft <= 0) return retval; } } else { if (rt_metaball_point_value(cp, mb) > mb->threshold) { point_t intersect, delta; const point_t *pA = (const point_t *)&lastpoint; const point_t *pB = (const point_t *)&p; rt_metaball_find_intersection(&intersect, mb, pA, pB, step, mb->finalstep); RT_GET_SEG(segp, ap->a_resource); segp->seg_stp = stp; --segsleft; ++retval; VMOVE(segp->seg_in.hit_point, intersect); VSUB2(delta, intersect, rp->r_pt); segp->seg_in.hit_dist = MAGNITUDE(delta); segp->seg_in.hit_surfno = 0; BU_LIST_INSERT(&(seghead->l), &(segp->l)); mb_stat = 1; step = mb->initstep; } } } } #else # error "pick a valid algo." #endif return retval; }
extern "C" void rt_eto_brep(ON_Brep **b, const struct rt_db_internal *ip, const struct bn_tol *) { struct rt_eto_internal *eip; RT_CK_DB_INTERNAL(ip); eip = (struct rt_eto_internal *)ip->idb_ptr; RT_ETO_CK_MAGIC(eip); point_t p_origin; vect_t v1, v1a, x_dir, y_dir; ON_3dPoint plane_origin; ON_3dVector plane_x_dir, plane_y_dir; double ell_axis_len_1, ell_axis_len_2; // First, find a plane in 3 space with x and y axes // along an axis of the ellipse to be rotated, and its // coordinate origin at the center of the ellipse. // // To identify a point on the eto suitable for use (there // are of course infinitely many such points described by // a circle at radius eto_r from the eto vertex) obtain // a vector at a right angle to the eto normal, unitize it // and scale it. VCROSS(v1, eip->eto_C, eip->eto_N); if (NEAR_ZERO(MAGNITUDE(v1), VUNITIZE_TOL)) { vect_t dir_vect; VSET(dir_vect, 0, 1, 0); VCROSS(v1, dir_vect, eip->eto_N); if (NEAR_ZERO(MAGNITUDE(v1), VUNITIZE_TOL)) { VSET(dir_vect, 1, 0, 0); VCROSS(v1, dir_vect, eip->eto_N); } } point_t temp; VMOVE(temp, v1); VCROSS(v1a, v1, eip->eto_N); VSET(v1, -v1a[0], -v1a[1], -v1a[2]); VUNITIZE( v1 ); VSCALE(v1, v1, eip->eto_r); VADD2(v1, v1, eip->eto_V); VMOVE(x_dir, eip->eto_C); VCROSS(y_dir, x_dir, temp); VSET(p_origin, v1[0], v1[1], v1[2]); plane_origin = ON_3dPoint(p_origin); plane_x_dir = ON_3dVector(x_dir); plane_y_dir = ON_3dVector(y_dir); const ON_Plane ell_plane(plane_origin, plane_x_dir, plane_y_dir); // Once the plane has been created, create the ellipse // within the plane. ell_axis_len_1 = MAGNITUDE(eip->eto_C); ell_axis_len_2 = eip->eto_rd; ON_Ellipse ellipse(ell_plane, ell_axis_len_1, ell_axis_len_2); // Generate an ON_Curve from the ellipse and revolve it // around eto_N ON_NurbsCurve ellcurve; ellipse.GetNurbForm(ellcurve); point_t eto_endvertex; VADD2(eto_endvertex, eip->eto_V, eip->eto_N); ON_3dPoint eto_vertex_pt = ON_3dPoint(eip->eto_V); ON_3dPoint eto_endvertex_pt = ON_3dPoint(eto_endvertex); ON_Line revaxis = ON_Line(eto_vertex_pt, eto_endvertex_pt); ON_RevSurface* eto_surf = ON_RevSurface::New(); eto_surf->m_curve = &ellcurve; eto_surf->m_axis = revaxis; /* Create brep with one face*/ ON_BrepFace *newface = (*b)->NewFace(*eto_surf); (*b)->FlipFace(*newface); // (*b)->Standardize(); // (*b)->Compact(); }
/* * This routine is called (at prep time) * once for each region which uses this shader. * Any shader-specific initialization should be done here. * * Returns: * 1 success * 0 success, but delete region * -1 failure */ HIDDEN int bbd_setup(struct region *rp, struct bu_vls *matparm, void **dpp, const struct mfuncs *mfp, struct rt_i *rtip) { register struct bbd_specific *bbd_sp; struct rt_db_internal intern; struct rt_tgc_internal *tgc; int s; mat_t mat; struct bbd_img *bi; double angle; vect_t vtmp; int img_num; vect_t vv; /* check the arguments */ RT_CHECK_RTI(rtip); BU_CK_VLS(matparm); RT_CK_REGION(rp); if (rdebug&RDEBUG_SHADE) bu_log("bbd_setup(%s)\n", rp->reg_name); RT_CK_TREE(rp->reg_treetop); if (rp->reg_treetop->tr_a.tu_op != OP_SOLID) { bu_log("--- Warning: Region %s shader %s", rp->reg_name, mfp->mf_name); bu_bomb("Shader should be used on region of single (rec/rcc) primitive\n"); } RT_CK_SOLTAB(rp->reg_treetop->tr_a.tu_stp); if (rp->reg_treetop->tr_a.tu_stp->st_id != ID_REC) { bu_log("--- Warning: Region %s shader %s", rp->reg_name, mfp->mf_name); bu_log("Shader should be used on region of single REC/RCC primitive %d\n", rp->reg_treetop->tr_a.tu_stp->st_id); bu_bomb("oops\n"); } /* Get memory for the shader parameters and shader-specific data */ BU_GET(bbd_sp, struct bbd_specific); *dpp = bbd_sp; /* initialize the default values for the shader */ memcpy(bbd_sp, &bbd_defaults, sizeof(struct bbd_specific)); bu_vls_init(&bbd_sp->img_filename); BU_LIST_INIT(&bbd_sp->imgs); bbd_sp->rtip = rtip; /* because new_image() needs this */ bbd_sp->img_count = 0; /* parse the user's arguments for this use of the shader. */ if (bu_struct_parse(matparm, bbd_parse_tab, (char *)bbd_sp, NULL) < 0) return -1; if (bbd_sp->img_count > MAX_IMAGES) { bu_log("too many images (%zu) in shader for %s sb < %d\n", bbd_sp->img_count, rp->reg_name, MAX_IMAGES); bu_bomb("excessive image count\n"); } MAT_IDN(mat); RT_DB_INTERNAL_INIT(&intern); s = rt_db_get_internal(&intern, rp->reg_treetop->tr_a.tu_stp->st_dp, rtip->rti_dbip, mat, &rt_uniresource); if (intern.idb_minor_type != ID_TGC && intern.idb_minor_type != ID_REC) { bu_log("What did I get? %d\n", intern.idb_minor_type); } if (s < 0) { bu_log("%s:%d didn't get internal", __FILE__, __LINE__); bu_bomb(""); } tgc = (struct rt_tgc_internal *)intern.idb_ptr; RT_TGC_CK_MAGIC(tgc); angle = M_PI / (double)bbd_sp->img_count; img_num = 0; VMOVE(vv, tgc->h); VUNITIZE(vv); for (BU_LIST_FOR(bi, bbd_img, &bbd_sp->imgs)) { static const point_t o = VINIT_ZERO; bn_mat_arb_rot(mat, o, vv, angle*img_num); /* compute plane equation */ MAT4X3VEC(bi->img_plane, mat, tgc->a); VUNITIZE(bi->img_plane); bi->img_plane[H] = VDOT(tgc->v, bi->img_plane); MAT4X3VEC(vtmp, mat, tgc->b); VADD2(bi->img_origin, tgc->v, vtmp); /* image origin in 3d space */ /* calculate image u vector */ VREVERSE(bi->img_x, vtmp); VUNITIZE(bi->img_x); bi->img_xlen = MAGNITUDE(vtmp) * 2; /* calculate image v vector */ VMOVE(bi->img_y, tgc->h); VUNITIZE(bi->img_y); bi->img_ylen = MAGNITUDE(tgc->h); if (rdebug&RDEBUG_SHADE) { HPRINT("\nimg_plane", bi->img_plane); VPRINT("vtmp", vtmp); VPRINT("img_origin", bi->img_origin); bu_log("img_xlen:%g ", bi->img_xlen); VPRINT("img_x", bi->img_x); bu_log("img_ylen:%g ", bi->img_ylen); VPRINT("img_y", bi->img_y); } img_num++; } rt_db_free_internal(&intern); if (rdebug&RDEBUG_SHADE) { bu_struct_print(" Parameters:", bbd_print_tab, (char *)bbd_sp); } return 1; }
struct faceuse * Make_planar_face(struct shell *s, int entityno, int face_orient) { int sol_num; /* IGES solid type number */ int no_of_edges; /* edge count for this loop */ int no_of_param_curves; int vert_count = 0; /* Actual number of vertices used to make face */ struct iges_edge_use *edge_list; /* list of edgeuses from iges loop entity */ struct faceuse *fu = NULL; /* NMG face use */ struct loopuse *lu; /* NMG loop use */ struct vertex ***verts; /* list of vertices */ struct iges_vertex_list *v_list; int done; int i, j, k; /* Acquiring Data */ if (dir[entityno]->param <= pstart) { bu_log("Illegal parameter pointer for entity D%07d (%s)\n" , dir[entityno]->direct, dir[entityno]->name); return 0; } Readrec(dir[entityno]->param); Readint(&sol_num, ""); if (sol_num != 508) { bu_exit(1, "ERROR: Entity #%d is not a loop (it's a %s)\n", entityno, iges_type(sol_num)); } Readint(&no_of_edges, ""); edge_list = (struct iges_edge_use *)bu_calloc(no_of_edges, sizeof(struct iges_edge_use) , "Make_face (edge_list)"); for (i = 0; i < no_of_edges; i++) { Readint(&edge_list[i].edge_is_vertex, ""); Readint(&edge_list[i].edge_de, ""); Readint(&edge_list[i].index, ""); Readint(&edge_list[i].orient, ""); if (!face_orient) { /* need opposite orientation of edge */ if (edge_list[i].orient) edge_list[i].orient = 0; else edge_list[i].orient = 1; } edge_list[i].root = (struct iges_param_curve *)NULL; Readint(&no_of_param_curves, ""); for (j = 0; j < no_of_param_curves; j++) { struct iges_param_curve *new_crv; struct iges_param_curve *crv; Readint(&k, ""); /* ignore iso-parametric flag */ BU_ALLOC(new_crv, struct iges_param_curve); if (edge_list[i].root == (struct iges_param_curve *)NULL) edge_list[i].root = new_crv; else { crv = edge_list[i].root; while (crv->next != (struct iges_param_curve *)NULL) crv = crv->next; crv->next = new_crv; } Readint(&new_crv->curve_de, ""); new_crv->next = (struct iges_param_curve *)NULL; } } verts = (struct vertex ***)bu_calloc(no_of_edges, sizeof(struct vertex **) , "Make_face: vertex_list **"); for (i = 0; i < no_of_edges; i++) { if (face_orient) verts[i] = Get_vertex(&edge_list[i]); else verts[no_of_edges-1-i] = Get_vertex(&edge_list[i]); } /* eliminate zero length edges */ vert_count = no_of_edges; done = 0; while (!done) { done = 1; for (i = 0; i < vert_count; i++) { k = i + 1; if (k == vert_count) k = 0; if (verts[i] == verts[k]) { bu_log("Ignoring zero length edge\n"); done = 0; vert_count--; for (j = i; j < vert_count; j++) verts[j] = verts[j+1]; } } } if (vert_count) { plane_t pl; /* Plane equation for face */ fastf_t area; /* area of loop */ fastf_t dist; vect_t min2max; point_t outside_pt; fu = nmg_cmface(s, verts, vert_count); /* associate geometry */ v_list = vertex_root; while (v_list != NULL) { for (i = 0; i < v_list->no_of_verts; i++) { if (v_list->i_verts[i].v != NULL && v_list->i_verts[i].v->vg_p == NULL) { NMG_CK_VERTEX(v_list->i_verts[i].v); nmg_vertex_gv(v_list->i_verts[i].v , v_list->i_verts[i].pt); } } v_list = v_list->next; } lu = BU_LIST_FIRST(loopuse, &fu->lu_hd); NMG_CK_LOOPUSE(lu); area = nmg_loop_plane_area(lu, pl); if (area < 0.0) { bu_log("Could not calculate area for face (entityno = %d)\n", entityno); nmg_pr_fu_briefly(fu, ""); nmg_kfu(fu); fu = (struct faceuse *)NULL; goto err; } nmg_face_g(fu, pl); nmg_face_bb(fu->f_p, &tol); /* find a point that is surely outside the loop */ VSUB2(min2max, fu->f_p->max_pt, fu->f_p->min_pt); VADD2(outside_pt, fu->f_p->max_pt, min2max); /* move it to the plane of the face */ dist = DIST_PT_PLANE(outside_pt, pl); VJOIN1(outside_pt, outside_pt, -dist, pl); if (nmg_class_pt_lu_except(outside_pt, lu, (struct edge *)NULL, &tol) != NMG_CLASS_AoutB) { nmg_reverse_face(fu); if (fu->orientation != OT_SAME) { fu = fu->fumate_p; if (fu->orientation != OT_SAME) bu_exit(1, "ERROR: no OT_SAME use for a face!\n"); } } } else bu_log("No edges left!\n"); err: bu_free((char *)edge_list, "Make_face (edge_list)"); bu_free((char *)verts, "Make_face (vertexlist)"); return fu; }
void nmg_2_vrml(FILE *fp, const struct db_full_path *pathp, struct model *m, struct mater_info *mater) { struct nmgregion *reg; struct bu_ptbl verts; struct vrml_mat mat; struct bu_vls vls = BU_VLS_INIT_ZERO; char *tok; int i; int first=1; int is_light=0; float r, g, b; point_t ave_pt; char *full_path; /*There may be a better way to capture the region_id, than getting the rt_comb_internal structure, * (and may be a better way to capture the rt_comb_internal struct), but for now I just copied the * method used in select_lights/select_non_lights above, could have used a global variable but I noticed * none other were used, so I didn't want to be the first */ struct directory *dp; struct rt_db_internal intern; struct rt_comb_internal *comb; int id; NMG_CK_MODEL( m ); BARRIER_CHECK; full_path = db_path_to_string( pathp ); /* replace all occurrences of '.' with '_' */ char_replace(full_path, '.', '_'); RT_CK_FULL_PATH( pathp ); dp = DB_FULL_PATH_CUR_DIR( pathp ); if ( !(dp->d_flags & RT_DIR_COMB) ) return; id = rt_db_get_internal( &intern, dp, dbip, (matp_t)NULL, &rt_uniresource ); if ( id < 0 ) { bu_log( "Cannot internal form of %s\n", dp->d_namep ); return; } if ( id != ID_COMBINATION ) { bu_log( "Directory/database mismatch!\n\t is '%s' a combination or not?\n", dp->d_namep ); return; } comb = (struct rt_comb_internal *)intern.idb_ptr; RT_CK_COMB( comb ); if ( mater->ma_color_valid ) { r = mater->ma_color[0]; g = mater->ma_color[1]; b = mater->ma_color[2]; } else { r = g = b = 0.5; } if ( mater->ma_shader ) { tok = strtok( mater->ma_shader, tok_sep ); bu_strlcpy( mat.shader, tok, TXT_NAME_SIZE ); } else mat.shader[0] = '\0'; mat.shininess = -1; mat.transparency = -1.0; mat.lt_fraction = -1.0; VSETALL( mat.lt_dir, 0.0 ); mat.lt_angle = -1.0; mat.tx_file[0] = '\0'; mat.tx_w = -1; mat.tx_n = -1; bu_vls_strcpy( &vls, &mater->ma_shader[strlen(mat.shader)] ); (void)bu_struct_parse( &vls, vrml_mat_parse, (char *)&mat ); if ( bu_strncmp( "light", mat.shader, 5 ) == 0 ) { /* this is a light source */ is_light = 1; } else { fprintf( fp, "\t<Shape DEF=\"%s\">\n", full_path); fprintf( fp, "\t\t<Appearance>\n"); if ( bu_strncmp( "plastic", mat.shader, 7 ) == 0 ) { if ( mat.shininess < 0 ) mat.shininess = 10; if ( mat.transparency < 0.0 ) mat.transparency = 0.0; fprintf( fp, "\t\t\t<Material diffuseColor=\"%g %g %g\" shininess=\"%g\" transparency=\"%g\" specularColor=\"%g %g %g\"/>\n", r, g, b, 1.0-exp(-(double)mat.shininess/20.0), mat.transparency, 1.0, 1.0, 1.0); } else if ( bu_strncmp( "glass", mat.shader, 5 ) == 0 ) { if ( mat.shininess < 0 ) mat.shininess = 4; if ( mat.transparency < 0.0 ) mat.transparency = 0.8; fprintf( fp, "\t\t\t<Material diffuseColor=\"%g %g %g\" shininess=\"%g\" transparency=\"%g\" specularColor=\"%g %g %g\"/>\n", r, g, b, 1.0-exp(-(double)mat.shininess/20.0), mat.transparency, 1.0, 1.0, 1.0); } else if ( mater->ma_color_valid ) { fprintf( fp, "\t\t\t<Material diffuseColor=\"%g %g %g\"/>\n", r, g, b); } else { /* If no color was defined set the colors according to the thousands groups */ int thou = comb->region_id/1000; thou == 0 ? fprintf( fp, "\t\t\t<Material USE=\"Material_999\"/>\n") : thou == 1 ? fprintf( fp, "\t\t\t<Material USE=\"Material_1999\"/>\n") : thou == 2 ? fprintf( fp, "\t\t\t<Material USE=\"Material_2999\"/>\n") : thou == 3 ? fprintf( fp, "\t\t\t<Material USE=\"Material_3999\"/>\n") : thou == 4 ? fprintf( fp, "\t\t\t<Material USE=\"Material_4999\"/>\n") : thou == 5 ? fprintf( fp, "\t\t\t<Material USE=\"Material_5999\"/>\n") : thou == 6 ? fprintf( fp, "\t\t\t<Material USE=\"Material_6999\"/>\n") : thou == 7 ? fprintf( fp, "\t\t\t<Material USE=\"Material_7999\"/>\n") : thou == 8 ? fprintf( fp, "\t\t\t<Material USE=\"Material_8999\"/>\n") : fprintf( fp, "\t\t\t<Material USE=\"Material_9999\"/>\n"); } } if ( !is_light ) { process_non_light(m); fprintf( fp, "\t\t</Appearance>\n"); } /* FIXME: need code to handle light */ /* get list of vertices */ nmg_vertex_tabulate( &verts, &m->magic ); fprintf( fp, "\t\t<IndexedFaceSet coordIndex=\"\n"); first = 1; if ( !is_light ) { for ( BU_LIST_FOR( reg, nmgregion, &m->r_hd ) ) { struct shell *s; NMG_CK_REGION( reg ); for ( BU_LIST_FOR( s, shell, ®->s_hd ) ) { struct faceuse *fu; NMG_CK_SHELL( s ); for ( BU_LIST_FOR( fu, faceuse, &s->fu_hd ) ) { struct loopuse *lu; NMG_CK_FACEUSE( fu ); if ( fu->orientation != OT_SAME ) continue; for ( BU_LIST_FOR( lu, loopuse, &fu->lu_hd ) ) { struct edgeuse *eu; NMG_CK_LOOPUSE( lu ); if ( BU_LIST_FIRST_MAGIC( &lu->down_hd ) != NMG_EDGEUSE_MAGIC ) continue; if ( !first ) fprintf( fp, ",\n" ); else first = 0; fprintf( fp, "\t\t\t\t" ); for ( BU_LIST_FOR( eu, edgeuse, &lu->down_hd ) ) { struct vertex *v; NMG_CK_EDGEUSE( eu ); v = eu->vu_p->v_p; NMG_CK_VERTEX( v ); fprintf( fp, " %d,", bu_ptbl_locate( &verts, (long *)v ) ); } fprintf( fp, "-1" ); } } } } /* close coordIndex */ fprintf( fp, "\" "); fprintf( fp, "normalPerVertex=\"false\" "); fprintf( fp, "convex=\"false\" "); fprintf( fp, "creaseAngle=\"0.5\" "); /* close IndexedFaceSet open tag */ fprintf( fp, ">\n"); } fprintf( fp, "\t\t\t<Coordinate point=\""); for ( i=0; i<BU_PTBL_END( &verts ); i++ ) { struct vertex *v; struct vertex_g *vg; point_t pt_meters; v = (struct vertex *)BU_PTBL_GET( &verts, i ); NMG_CK_VERTEX( v ); vg = v->vg_p; NMG_CK_VERTEX_G( vg ); /* convert to desired units */ VSCALE( pt_meters, vg->coord, scale_factor ); if ( is_light ) VADD2( ave_pt, ave_pt, pt_meters ); if ( first ) { if ( !is_light ) fprintf( fp, " %10.10e %10.10e %10.10e, ", V3ARGS(pt_meters)); first = 0; } else if ( !is_light ) fprintf( fp, "%10.10e %10.10e %10.10e, ", V3ARGS( pt_meters )); } /* close point */ fprintf(fp, "\""); /* close Coordinate */ fprintf(fp, "/>\n"); /* IndexedFaceSet end tag */ fprintf( fp, "\t\t</IndexedFaceSet>\n"); /* Shape end tag */ fprintf( fp, "\t</Shape>\n"); BARRIER_CHECK; }
void render_cut_work(render_t *render, struct tie_s *tiep, struct tie_ray_s *ray, vect_t *pixel) { render_cut_t *rd; render_cut_hit_t hit; vect_t color; struct tie_id_s id; tfloat t, dot; rd = (render_cut_t *)render->data; /* Draw Arrow - Blue */ if (tie_work(&rd->tie, ray, &id, render_arrow_hit, NULL)) { VSET(*pixel, 0.0, 0.0, 1.0); return; } /* * I don't think this needs to be done for every pixel? * Flip plane normal to face us. */ t = ray->pos[0]*rd->plane[0] + ray->pos[1]*rd->plane[1] + ray->pos[2]*rd->plane[2] + rd->plane[3]; hit.mod = t < 0 ? 1 : -1; /* * Optimization: * First intersect this ray with the plane and fire the ray from there * Plane: Ax + By + Cz + D = 0 * Ray = O + td * t = -(Pn · R0 + D) / (Pn · Rd) */ t = (rd->plane[0]*ray->pos[0] + rd->plane[1]*ray->pos[1] + rd->plane[2]*ray->pos[2] + rd->plane[3]) / (rd->plane[0]*ray->dir[0] + rd->plane[1]*ray->dir[1] + rd->plane[2]*ray->dir[2]); /* Ray never intersects plane */ if (t > 0) return; ray->pos[0] += -t * ray->dir[0]; ray->pos[1] += -t * ray->dir[1]; ray->pos[2] += -t * ray->dir[2]; HMOVE(hit.plane, rd->plane); /* Render Geometry */ if (!tie_work(tiep, ray, &id, render_cut_hit, &hit)) return; /* * If the point after the splitting plane is an outhit, fill it in as if it were solid. * If the point after the splitting plane is an inhit, then just shade as usual. */ /* flipped normal */ dot = fabs(VDOT( ray->dir, hit.id.norm)); if (hit.mesh->flags & (ADRT_MESH_SELECT|ADRT_MESH_HIT)) { VSET(color, hit.mesh->flags & ADRT_MESH_HIT ? (tfloat)0.9 : (tfloat)0.2, (tfloat)0.2, hit.mesh->flags & ADRT_MESH_SELECT ? (tfloat)0.9 : (tfloat)0.2); } else { /* Mix actual color with white 4:1, shade 50% darker */ #if 0 VSET(color, 1.0, 1.0, 1.0); VSCALE(color, color, 3.0); VADD2(color, color, hit.mesh->attributes->color); VSCALE(color, color, 0.125); #else VSET(color, (tfloat)0.8, (tfloat)0.8, (tfloat)0.7); #endif } #if 0 if (dot < 0) { #endif /* Shade using inhit */ VSCALE((*pixel), color, (dot*0.90)); #if 0 } else { TIE_3 vec; fastf_t angle; /* shade solid */ VSUB2(vec, ray->pos, hit.id.pos); VUNITIZE(vec); angle = vec[0]*hit.mod*-hit.plane[0] + vec[1]*-hit.mod*hit.plane[1] + vec[2]*-hit.mod*hit.plane[2]; VSCALE((*pixel), color, (angle*0.90)); } #endif *pixel[0] += (tfloat)0.1; *pixel[1] += (tfloat)0.1; *pixel[2] += (tfloat)0.1; }
int _ged_translate_tgc(struct ged *gedp, struct rt_tgc_internal *tgc, const char *attribute, vect_t tvec, int rflag) { fastf_t la, lb, lc, ld; vect_t hvec; RT_TGC_CK_MAGIC(tgc); VSCALE(tvec, tvec, gedp->ged_wdbp->dbip->dbi_local2base); switch (attribute[0]) { case 'h': case 'H': switch (attribute[1]) { case '\0': if (rflag) { VADD2(hvec, tgc->h, tvec); } else { VSUB2(hvec, tvec, tgc->v); } /* check for zero H vector */ if (MAGNITUDE(hvec) <= SQRT_SMALL_FASTF) { bu_vls_printf(gedp->ged_result_str, "Zero H vector not allowed."); return GED_ERROR; } VMOVE(tgc->h, hvec); break; case 'r': case 'R': if (attribute[2] != '\0') { bu_vls_printf(gedp->ged_result_str, "bad tgc attribute - %s", attribute); return GED_ERROR; } if (rflag) { VADD2(hvec, tgc->h, tvec); } else { VSUB2(hvec, tvec, tgc->v); } /* check for zero H vector */ if (MAGNITUDE(hvec) <= SQRT_SMALL_FASTF) { bu_vls_printf(gedp->ged_result_str, "Zero H vector not allowed."); return GED_ERROR; } VMOVE(tgc->h, hvec); /* have new height vector -- redefine rest of tgc */ la = MAGNITUDE(tgc->a); lb = MAGNITUDE(tgc->b); lc = MAGNITUDE(tgc->c); ld = MAGNITUDE(tgc->d); /* find 2 perpendicular vectors normal to H for new A, B */ VCROSS(tgc->b, tgc->h, tgc->a); VCROSS(tgc->a, tgc->b, tgc->h); VUNITIZE(tgc->a); VUNITIZE(tgc->b); /* Create new C, D from unit length A, B, with previous len */ VSCALE(tgc->c, tgc->a, lc); VSCALE(tgc->d, tgc->b, ld); /* Restore original vector lengths to A, B */ VSCALE(tgc->a, tgc->a, la); VSCALE(tgc->b, tgc->b, lb); break; default: bu_vls_printf(gedp->ged_result_str, "bad tgc attribute - %s", attribute); return GED_ERROR; } break; default: bu_vls_printf(gedp->ged_result_str, "bad tgc attribute - %s", attribute); return GED_ERROR; } return GED_OK; }
extern "C" void rt_revolve_brep(ON_Brep **b, const struct rt_db_internal *ip, const struct bn_tol *tol) { struct rt_db_internal *tmp_internal; struct rt_revolve_internal *rip; struct rt_sketch_internal *eip; BU_ALLOC(tmp_internal, struct rt_db_internal); RT_DB_INTERNAL_INIT(tmp_internal); rip = (struct rt_revolve_internal *)ip->idb_ptr; RT_REVOLVE_CK_MAGIC(rip); eip = rip->skt; RT_SKETCH_CK_MAGIC(eip); ON_3dPoint plane_origin; ON_3dVector plane_x_dir, plane_y_dir; bool full_revolve = true; if (rip->ang < 2*ON_PI && rip->ang > 0) full_revolve = false; // Find plane in 3 space corresponding to the sketch. vect_t startpoint; VADD2(startpoint, rip->v3d, rip->r); plane_origin = ON_3dPoint(startpoint); plane_x_dir = ON_3dVector(eip->u_vec); plane_y_dir = ON_3dVector(eip->v_vec); const ON_Plane sketch_plane = ON_Plane(plane_origin, plane_x_dir, plane_y_dir); // For the brep, need the list of 3D vertex points. In sketch, they // are stored as 2D coordinates, so use the sketch_plane to define 3 space // points for the vertices. for (size_t i = 0; i < eip->vert_count; i++) { (*b)->NewVertex(sketch_plane.PointAt(eip->verts[i][0], eip->verts[i][1]), 0.0); } // Create the brep elements corresponding to the sketch lines, curves // and bezier segments. Create 2d, 3d and BrepEdge elements for each segment. // Will need to use the bboxes of each element to // build the overall bounding box for the face. Use bGrowBox to expand // a single box. struct line_seg *lsg; struct carc_seg *csg; struct bezier_seg *bsg; uint32_t *lng; for (size_t i = 0; i < (&eip->curve)->count; i++) { lng = (uint32_t *)(&eip->curve)->segment[i]; switch (*lng) { case CURVE_LSEG_MAGIC: { lsg = (struct line_seg *)lng; ON_Curve* lsg3d = new ON_LineCurve((*b)->m_V[lsg->start].Point(), (*b)->m_V[lsg->end].Point()); lsg3d->SetDomain(0.0, 1.0); (*b)->m_C3.Append(lsg3d); } break; case CURVE_CARC_MAGIC: csg = (struct carc_seg *)lng; if (csg->radius < 0) { { ON_3dPoint cntrpt = (*b)->m_V[csg->end].Point(); ON_3dPoint edgept = (*b)->m_V[csg->start].Point(); ON_Plane cplane = ON_Plane(cntrpt, plane_x_dir, plane_y_dir); ON_Circle c3dcirc = ON_Circle(cplane, cntrpt.DistanceTo(edgept)); ON_Curve* c3d = new ON_ArcCurve((const ON_Circle)c3dcirc); c3d->SetDomain(0.0, 1.0); (*b)->m_C3.Append(c3d); } } else { // need to calculated 3rd point on arc - look to sketch.c around line 581 for // logic } break; case CURVE_BEZIER_MAGIC: bsg = (struct bezier_seg *)lng; { ON_3dPointArray bezpoints = ON_3dPointArray(bsg->degree + 1); for (int j = 0; j < bsg->degree + 1; j++) { bezpoints.Append((*b)->m_V[bsg->ctl_points[j]].Point()); } ON_BezierCurve bez3d = ON_BezierCurve((const ON_3dPointArray)bezpoints); ON_NurbsCurve* beznurb3d = ON_NurbsCurve::New(); bez3d.GetNurbForm(*beznurb3d); beznurb3d->SetDomain(0.0, 1.0); (*b)->m_C3.Append(beznurb3d); } break; default: bu_log("Unhandled sketch object\n"); break; } } vect_t endpoint; VADD2(endpoint, rip->v3d, rip->axis3d); const ON_Line& revaxis = ON_Line(ON_3dPoint(rip->v3d), ON_3dPoint(endpoint)); FindLoops(b, &revaxis, rip->ang); // Create the two boundary surfaces, if it's not a full revolution if (!full_revolve) { // First, deduce the transformation matrices to calculate the position of the end surface // The transformation matrices are to rotate an arbitrary point around an arbitrary axis // Let the point A = (x, y, z), the rotation axis is p1p2 = (x2,y2,z2)-(x1,y1,z1) = (a,b,c) // Then T1 is to translate p1 to the origin // Rx is to rotate p1p2 around the X axis to the plane XOZ // Ry is to rotate p1p2 around the Y axis to be coincident to Z axis // Rz is to rotate A with the angle around Z axis (the new p1p2) // RxInv, RyInv, T1Inv are the inverse transformation of Rx, Ry, T1, respectively. // The whole transformation is A' = A*T1*Rx*Ry*Rz*Ry*Inv*Rx*Inv = A*R vect_t end_plane_origin, end_plane_x_dir, end_plane_y_dir; mat_t R; MAT_IDN(R); mat_t T1, Rx, Ry, Rz, RxInv, RyInv, T1Inv; MAT_IDN(T1); VSET(&T1[12], -rip->v3d[0], -rip->v3d[1], -rip->v3d[2]); MAT_IDN(Rx); fastf_t v = sqrt(rip->axis3d[1]*rip->axis3d[1]+rip->axis3d[2]*rip->axis3d[2]); VSET(&Rx[4], 0, rip->axis3d[2]/v, rip->axis3d[1]/v); VSET(&Rx[8], 0, -rip->axis3d[1]/v, rip->axis3d[2]/v); MAT_IDN(Ry); fastf_t u = MAGNITUDE(rip->axis3d); VSET(&Ry[0], v/u, 0, -rip->axis3d[0]/u); VSET(&Ry[8], rip->axis3d[0]/u, 0, v/u); MAT_IDN(Rz); fastf_t C, S; C = cos(rip->ang); S = sin(rip->ang); VSET(&Rz[0], C, S, 0); VSET(&Rz[4], -S, C, 0); bn_mat_inv(RxInv, Rx); bn_mat_inv(RyInv, Ry); bn_mat_inv(T1Inv, T1); mat_t temp; bn_mat_mul4(temp, T1, Rx, Ry, Rz); bn_mat_mul4(R, temp, RyInv, RxInv, T1Inv); VEC3X3MAT(end_plane_origin, plane_origin, R); VADD2(end_plane_origin, end_plane_origin, &R[12]); VEC3X3MAT(end_plane_x_dir, plane_x_dir, R); VEC3X3MAT(end_plane_y_dir, plane_y_dir, R); // Create the start and end surface with rt_sketch_brep() struct rt_sketch_internal sketch; sketch = *(rip->skt); ON_Brep *b1 = ON_Brep::New(); VMOVE(sketch.V, plane_origin); VMOVE(sketch.u_vec, plane_x_dir); VMOVE(sketch.v_vec, plane_y_dir); tmp_internal->idb_ptr = (void *)(&sketch); rt_sketch_brep(&b1, tmp_internal, tol); (*b)->Append(*b1->Duplicate()); ON_Brep *b2 = ON_Brep::New(); VMOVE(sketch.V, end_plane_origin); VMOVE(sketch.u_vec, end_plane_x_dir); VMOVE(sketch.v_vec, end_plane_y_dir); tmp_internal->idb_ptr = (void *)(&sketch); rt_sketch_brep(&b2, tmp_internal, tol); (*b)->Append(*b2->Duplicate()); (*b)->FlipFace((*b)->m_F[(*b)->m_F.Count()-1]); } bu_free(tmp_internal, "free temporary rt_db_internal"); }
int main (int argc, char *argv[]) { int val; /* intentionally double for scan */ double elapsed, yaw1, pitch1, roll1, yaw2, pitch2, roll2; double cen1[3], cen2[3]; vect_t rad_ang_ans, cen_ans, ang_ans, rotated = VINIT_ZERO; mat_t m_rot1, m_rot2, m_ans; int one_time, read_cen1, read_cen2, read_rot1, read_rot2; if (argc == 1 && isatty(fileno(stdin)) && isatty(fileno(stdout))) { usage(); return 0; } if (!get_args(argc, argv)) { usage(); return 0; } read_cen1 = read_cen2 = read_rot1 = read_rot2 = 1; switch (output_mode) { case CASCADE_A: if (cmd_fcen) { VMOVE(cen1, fcenter); read_cen1 = 0; } if (cmd_rcen) { VMOVE(cen2, rcenter); read_cen2 = 0; } if (cmd_fypr) { anim_dy_p_r2mat(m_rot1, fypr[0], fypr[1], fypr[2]); read_rot1 = 0; } if (cmd_rypr) { anim_dy_p_r2mat(m_rot2, rypr[0], rypr[1], rypr[2]); read_rot2 = 0; } break; case CASCADE_R: if (cmd_fcen) { VMOVE(cen1, fcenter); read_cen1 = 0; } if (cmd_acen) { VMOVE(cen2, acenter); read_cen2 = 0; } if (cmd_fypr) { anim_dy_p_r2mat(m_rot1, fypr[0], fypr[1], fypr[2]); read_rot1 = 0; } if (cmd_aypr) { anim_dy_p_r2mat(m_rot2, aypr[0], aypr[1], aypr[2]); read_rot2 = 0; } break; case CASCADE_F: if (cmd_acen) { VMOVE(cen1, acenter); read_cen1 = 0; } if (cmd_rcen) { VMOVE(cen2, rcenter); read_cen2 = 0; } if (cmd_aypr) { anim_dy_p_r2mat(m_rot1, aypr[0], aypr[1], aypr[2]); read_rot1 = 0; } if (cmd_rypr) { anim_dy_p_r2mat(m_rot2, rypr[0], rypr[1], rypr[2]); read_rot2 = 0; } break; default: break; } one_time = (!(read_cen1||read_cen2||read_rot1||read_rot2)); read_time = one_time ? 0 : print_time; elapsed = 0.0; val = 3; while (1) { if (read_time) { val=scanf("%lf", &elapsed); if (val < 1) break; } if (read_cen1) val =scanf("%lf %lf %lf", cen1, cen1+1, cen1+2); if (read_rot1) { val=scanf("%lf %lf %lf", &yaw1, &pitch1, &roll1); anim_dy_p_r2mat(m_rot1, yaw1, pitch1, roll1); } if (read_cen2) { val=scanf("%lf %lf %lf", cen2, cen2+1, cen2+2); } if (read_rot2) { val=scanf("%lf %lf %lf", &yaw2, &pitch2, &roll2); anim_dy_p_r2mat(m_rot2, yaw2, pitch2, roll2); } if (val<3) break; if (output_mode==CASCADE_R) { anim_tran(m_rot1); VSUB2(rotated, cen2, cen1); MAT4X3PNT(cen_ans, m_rot1, rotated); bn_mat_mul(m_ans, m_rot1, m_rot2); } else if (output_mode==CASCADE_F) { anim_tran(m_rot2); bn_mat_mul(m_ans, m_rot1, m_rot2); MAT4X3PNT(rotated, m_ans, cen2); VSUB2(cen_ans, cen1, rotated); } else { MAT4X3PNT(rotated, m_rot1, cen2); VADD2(cen_ans, rotated, cen1); bn_mat_mul(m_ans, m_rot1, m_rot2); } anim_mat2ypr(m_ans, rad_ang_ans); VSCALE(ang_ans, rad_ang_ans, RAD2DEG); if (print_time) { printf("%g", elapsed); } printf("\t%.12g\t%.12g\t%.12g", cen_ans[0], cen_ans[1], cen_ans[2]); printf("\t%.12g\t%.12g\t%.12g", ang_ans[0], ang_ans[1], ang_ans[2]); printf("\n"); if (one_time) break; } return 0; }
HIDDEN int nmg_brep_face(ON_Brep **b, const struct faceuse *fu, const struct bn_tol *tol, long *brepi) { const struct face_g_plane *fg = fu->f_p->g.plane_p; struct bu_ptbl vert_table; struct vertex **pt; int ret = 0; int pnt_cnt = 0; int pnt_index = 0; vect_t u_axis, v_axis; point_t obr_center; point_t *points_3d = NULL; point_t *points_obr = NULL; struct loopuse *lu; struct edgeuse *eu; /* Find out how many points we have, set up any uninitialized ON_Brep vertex * structures, and prepare a map of NMG index values to the point array indices */ nmg_tabulate_face_g_verts(&vert_table, fg); for (BU_PTBL_FOR(pt, (struct vertex **), &vert_table)) { if (brepi[(*pt)->vg_p->index] == -INT_MAX) { ON_BrepVertex& vert = (*b)->NewVertex((*pt)->vg_p->coord, SMALL_FASTF); brepi[(*pt)->vg_p->index] = vert.m_vertex_index; } pnt_cnt++; } /* Prepare the 3D obr input array */ points_3d = (point_t *)bu_calloc(pnt_cnt + 1, sizeof(point_t), "nmg points"); for (BU_PTBL_FOR(pt, (struct vertex **), &vert_table)) { VSET(points_3d[pnt_index], (*pt)->vg_p->coord[0],(*pt)->vg_p->coord[1],(*pt)->vg_p->coord[2]); pnt_index++; } bu_ptbl_free(&vert_table); /* Calculate the 3D coplanar oriented bounding rectangle (obr) */ ret += bg_3d_coplanar_obr(&obr_center, &u_axis, &v_axis, (const point_t *)points_3d, pnt_cnt); if (ret) { bu_log("Failed to get oriented bounding rectangle for NMG faceuse #%lu\n", fu->index); return -1; } bu_free(points_3d, "done with obr 3d point inputs"); /* Use the obr to define the 3D corner points of the NURBS surface */ points_obr = (point_t *)bu_calloc(3 + 1, sizeof(point_t), "points_3d"); VADD3(points_obr[2], obr_center, u_axis, v_axis); VSCALE(u_axis, u_axis, -1); VADD3(points_obr[3], obr_center, u_axis, v_axis); VSCALE(v_axis, v_axis, -1); VADD3(points_obr[0], obr_center, u_axis, v_axis); VSCALE(u_axis, u_axis, -1); VADD3(points_obr[1], obr_center, u_axis, v_axis); /* We need to orient our surface correctly according to the NMG - using * the openNURBS FlipFace function later does not seem to work very * well. If an outer loop is found in the NMG with a cw orientation, * factor that in in addition to the fu->f_p->flip flag. */ int ccw = 0; vect_t vtmp, uv1, uv2, vnormal; point_t center; VADD2(center, points_obr[0], points_obr[1]); VADD2(center, center, points_obr[2]); VADD2(center, center, points_obr[3]); VSCALE(center, center, 0.25); for (BU_LIST_FOR(lu, loopuse, &fu->lu_hd)) { if (lu->orientation == OT_SAME && nmg_loop_is_ccw(lu, fg->N, tol) == -1) ccw = -1; } if (ccw != -1) { VSET(vnormal, fg->N[0], fg->N[1], fg->N[2]); } else { VSET(vnormal, -fg->N[0], -fg->N[1], -fg->N[2]); } if (fu->f_p->flip) VSET(vnormal, -vnormal[0], -vnormal[1], -vnormal[2]); VSUB2(uv1, points_obr[0], center); VSUB2(uv2, points_obr[1], center); VCROSS(vtmp, uv1, uv2); if (VDOT(vtmp, vnormal) < 0) { VMOVE(vtmp, points_obr[0]); VMOVE(points_obr[0], points_obr[1]); VMOVE(points_obr[1], vtmp); VMOVE(vtmp, points_obr[3]); VMOVE(points_obr[3], points_obr[2]); VMOVE(points_obr[2], vtmp); } /* Now that we've got our points correctly oriented for * the NURBS surface, proceed to create it. */ ON_3dPoint p1 = ON_3dPoint(points_obr[0]); ON_3dPoint p2 = ON_3dPoint(points_obr[1]); ON_3dPoint p3 = ON_3dPoint(points_obr[2]); ON_3dPoint p4 = ON_3dPoint(points_obr[3]); (*b)->m_S.Append(sideSurface(p1, p2, p3, p4)); ON_Surface *surf = (*(*b)->m_S.Last()); int surfindex = (*b)->m_S.Count(); ON_BrepFace& face = (*b)->NewFace(surfindex - 1); // With the surface and the face defined, make // trimming loops and create faces. To generate UV // coordinates for each from and to for the // edgecurves, the UV origin is defined to be v1, // v1->v2 is defined as the U domain, and v1->v4 is // defined as the V domain. VSUB2(u_axis, points_obr[2], points_obr[1]); VSUB2(v_axis, points_obr[0], points_obr[1]); fastf_t u_axis_dist = MAGNITUDE(u_axis); fastf_t v_axis_dist = MAGNITUDE(v_axis); /* Now that we have the surface and the face, add the loops */ for (BU_LIST_FOR(lu, loopuse, &fu->lu_hd)) { if (BU_LIST_FIRST_MAGIC(&lu->down_hd) != NMG_EDGEUSE_MAGIC) continue; // loop is a single vertex // Check if this is an inner or outer loop ON_BrepLoop::TYPE looptype = (lu->orientation == OT_SAME) ? ON_BrepLoop::outer : ON_BrepLoop::inner; ON_BrepLoop& loop = (*b)->NewLoop(looptype, face); for (BU_LIST_FOR(eu, edgeuse, &lu->down_hd)) { vect_t ev1, ev2; struct vertex_g *vg1 = eu->vu_p->v_p->vg_p; struct vertex_g *vg2 = eu->eumate_p->vu_p->v_p->vg_p; NMG_CK_VERTEX_G(vg1); NMG_CK_VERTEX_G(vg2); VMOVE(ev1, vg1->coord); VMOVE(ev2, vg2->coord); // Add edge if not already added if (brepi[eu->e_p->index] == -INT_MAX) { /* always add edges with the small vertex index as from */ int vert1 = (vg1->index <= vg2->index) ? brepi[vg1->index] : brepi[vg2->index]; int vert2 = (vg1->index > vg2->index) ? brepi[vg1->index] : brepi[vg2->index]; // Create and add 3D curve ON_Curve* c3d = new ON_LineCurve((*b)->m_V[vert1].Point(), (*b)->m_V[vert2].Point()); c3d->SetDomain(0.0, 1.0); (*b)->m_C3.Append(c3d); // Create and add 3D edge ON_BrepEdge& e = (*b)->NewEdge((*b)->m_V[vert1], (*b)->m_V[vert2] , (*b)->m_C3.Count() - 1); e.m_tolerance = 0.0; brepi[eu->e_p->index] = e.m_edge_index; } // Regardless of whether the edge existed as an object, it needs to be added to the trimming loop ON_3dPoint vg1pt(vg1->coord); int orientation = ((vg1pt != (*b)->m_V[(*b)->m_E[(int)brepi[eu->e_p->index]].m_vi[0]].Point())) ? 1 : 0; // Make a 2d trimming curve, create a trim, and add the trim to the loop vect_t vect1, vect2, u_component, v_component; double u0, u1, v0, v1; ON_2dPoint from_uv, to_uv; VSUB2(vect1, ev1, points_obr[0]); VSUB2(vect2, ev2, points_obr[0]); surf->GetDomain(0, &u0, &u1); surf->GetDomain(1, &v0, &v1); VPROJECT(vect1, u_axis, u_component, v_component); from_uv.y = u0 + MAGNITUDE(u_component)/u_axis_dist*(u1-u0); from_uv.x = v0 + MAGNITUDE(v_component)/v_axis_dist*(v1-v0); VPROJECT(vect2, u_axis, u_component, v_component); to_uv.y = u0 + MAGNITUDE(u_component)/u_axis_dist*(u1-u0); to_uv.x = v0 + MAGNITUDE(v_component)/v_axis_dist*(v1-v0); ON_Curve* c2d = new ON_LineCurve(from_uv, to_uv); c2d->SetDomain(0.0, 1.0); int c2i = (*b)->m_C2.Count(); (*b)->m_C2.Append(c2d); ON_BrepTrim& trim = (*b)->NewTrim((*b)->m_E[(int)brepi[eu->e_p->index]], orientation, loop, c2i); trim.m_type = ON_BrepTrim::mated; trim.m_tolerance[0] = 0.0; trim.m_tolerance[1] = 0.0; } } bu_free(points_obr, "Done with obr"); return 0; }
int block(int entityno) { fastf_t xscale = 0.0; fastf_t yscale = 0.0; fastf_t zscale = 0.0; fastf_t x_1, y_1, z_1; /* First vertex components */ fastf_t x_2, y_2, z_2; /* xdir vector components */ fastf_t x_3, y_3, z_3; /* zdir vector components */ point_t v; /* the first vertex */ vect_t xdir; /* a unit vector */ vect_t xvec; /* vector along x-axis */ vect_t ydir; /* a unit vector */ vect_t yvec; /* vector along y-axis */ vect_t zdir; /* a unit vector */ vect_t zvec; /* vector along z-axis */ point_t pts[9]; /* array of points */ int sol_num; /* IGES solid type number */ /* Default values */ x_1 = 0.0; y_1 = 0.0; z_1 = 0.0; x_2 = 1.0; y_2 = 0.0; z_2 = 0.0; x_3 = 0.0; y_3 = 0.0; z_3 = 1.0; /* Acquiring Data */ if (dir[entityno]->param <= pstart) { bu_log("Illegal parameter pointer for entity D%07d (%s)\n" , dir[entityno]->direct, dir[entityno]->name); return 0; } Readrec(dir[entityno]->param); Readint(&sol_num, ""); Readcnv(&xscale, ""); Readcnv(&yscale, ""); Readcnv(&zscale, ""); Readcnv(&x_1, ""); Readcnv(&y_1, ""); Readcnv(&z_1, ""); Readflt(&x_2, ""); Readflt(&y_2, ""); Readflt(&z_2, ""); Readflt(&x_3, ""); Readflt(&y_3, ""); Readflt(&z_3, ""); if (xscale <= 0.0 || yscale <= 0.0 || zscale <= 0.0) { bu_log("Illegal parameters for entity D%07d (%s)\n" , dir[entityno]->direct, dir[entityno]->name); return 0; } /* * Making the necessaries. First an id is made for the new entity. * Then the vertices for the bottom and top faces are found. Point * is located in the lower left corner of the solid, and the vertices are * counted in the counter-clockwise direction, around the bottom face. * Next these vertices are extruded to form the top face. The points * thus made are loaded into an array of points and handed off to mk_arb8(). * Make and unitize necessary vectors. */ VSET(xdir, x_2, y_2, z_2); /* Makes x-dir vector */ VUNITIZE(xdir); VSET(zdir, x_3, y_3, z_3); /* Make z-dir vector */ VUNITIZE(zdir); VCROSS(ydir, zdir, xdir); /* Make y-dir vector */ /* Scale all vectors */ VSCALE(xvec, xdir, xscale); VSCALE(zvec, zdir, zscale); VSCALE(yvec, ydir, yscale); /* Make the bottom face. */ VSET(v, x_1, y_1, z_1); /* Yields first vertex */ VMOVE(pts[0], v); /* put first vertex into array */ VADD2(pts[1], v, xvec); /* Finds second vertex */ VADD3(pts[2], v, xvec, yvec); /* Finds third vertex */ VADD2(pts[3], v, yvec); /* Finds fourth vertex */ /* Now extrude the bottom face to make the top. */ VADD2(pts[4], v, zvec); /* Finds fifth vertex */ VADD2(pts[5], pts[1], zvec); /* Finds sixth vertex */ VADD2(pts[6], pts[2], zvec); /* Finds seventh vertex */ VADD2(pts[7], pts[3], zvec); /* Find eighth vertex */ /* Now the information is handed off to mk_arb8(). */ mk_arb8(fdout, dir[entityno]->name, &pts[0][X]); return 1; }
/* T R E E T H E R M _ S E T U P * * This routine is called (at prep time) * once for each region which uses this shader. * Any shader-specific initialization should be done here. */ HIDDEN int tthrm_setup(register struct region *rp, struct bu_vls *matparm, genptr_t *dpp, const struct mfuncs *UNUSED(mfp), struct rt_i *rtip) /* pointer to reg_udata in *rp */ /* New since 4.4 release */ { register struct tthrm_specific *tthrm_sp; struct bu_mapped_file *tt_file; char *tt_data; long cyl_tot = 0; long tseg; float *fp; float fv[4]; double min_temp; double max_temp; point_t center; point_t pt; vect_t dir; static const double inv_nodes = 1.0/8.0; int node; int i; int long_size = 0; size_t file_size_long; size_t file_size_int; /* check the arguments */ RT_CHECK_RTI(rtip); BU_CK_VLS(matparm); RT_CK_REGION(rp); if (rdebug&RDEBUG_SHADE) bu_log("tthrm_setup(Region:\"%s\", tthrm(%s))\n", rp->reg_name, bu_vls_addr(matparm)); /* Get memory for the shader parameters and shader-specific data */ BU_GET(tthrm_sp, struct tthrm_specific); *dpp = tthrm_sp; tthrm_sp->magic = tthrm_MAGIC; tthrm_sp->tt_name[0] = '\0'; tthrm_sp->tt_min_temp = tthrm_sp->tt_max_temp = 0.0; if (rdebug&RDEBUG_SHADE) bu_log("Parsing: (%s)\n", bu_vls_addr(matparm)); if (bu_struct_parse(matparm, tthrm_parse, (char *)tthrm_sp) < 0) { bu_bomb(__FILE__); } if (tthrm_sp->tt_name[0] == '\0') { bu_log("Must specify file for tthrm shader on %s (got \"%s\"\n", rp->reg_name, bu_vls_addr(matparm)); bu_bomb(__FILE__); } tt_file = bu_open_mapped_file(tthrm_sp->tt_name, (char *)NULL); if (!tt_file) { bu_log("Error mapping \"%s\"\n", tthrm_sp->tt_name); bu_bomb("shader tthrm: can't get thermal data"); } tt_data = tt_file->buf; if (rdebug&RDEBUG_SHADE) bu_log("tthrm_setup() data: %p total\n", (void *)tt_data); /* Compute how big the file should be, so that we can guess * at the size of the integer at the front of the file */ file_size_int = sizeof(int) + *((int *)tt_data) * (sizeof(short) + sizeof(float) * 4 * NUM_NODES); file_size_long = sizeof(long) + *((long *)tt_data) * (sizeof(short) + sizeof(float) * 4 * NUM_NODES); switch (sizeof(long)) { case 8: if (tt_file->buflen == file_size_long) { /* 64bit data on 64bit host */ long_size = sizeof(long); tthrm_sp->tt_max_seg = cyl_tot = *((long *)tt_data); } else if (tt_file->buflen == file_size_int) { /* 32bit data on 32bit host */ long_size = sizeof(int); tthrm_sp->tt_max_seg = cyl_tot = *((int *)tt_data); } break; case 4: if (tt_file->buflen == file_size_long) { /* 32bit data on 32bit host */ long_size = sizeof(long); tthrm_sp->tt_max_seg = cyl_tot = *((long *)tt_data); } else if (tt_file->buflen == (file_size_long+4)) { /* 64bit data on 32bit host */ cyl_tot = *((int *)tt_data); if (cyl_tot != 0) { bu_log("%s:%d thermal data written on 64bit machine with more that 2^32 segs\n", __FILE__, __LINE__); bu_bomb(""); } long_size = sizeof(long) + 4; tthrm_sp->tt_max_seg = cyl_tot = ((int *)tt_data)[1]; } break; default: bu_log("a long int is %d bytes on this machine\n", sizeof(long)); bu_bomb("I can only handle 4 or 8 byte longs\n"); break; } if (rdebug&RDEBUG_SHADE) bu_log("cyl_tot = %ld\n", cyl_tot); tthrm_sp->tt_segs = (struct thrm_seg *) bu_calloc(cyl_tot, sizeof(struct thrm_seg), "thermal segs"); min_temp = MAX_FASTF; max_temp = -MAX_FASTF; #define CYL_DATA(_n) ((float *) (&tt_data[ \ long_size + \ (_n) * (sizeof(short) + sizeof(float) * 4 * NUM_NODES) + \ sizeof(short) \ ])) for (tseg = 0; tseg < cyl_tot; tseg++) { /* compute centerpoint, min/max temperature values */ fp = CYL_DATA(tseg); VSETALL(center, 0.0); for (node=0; node < NUM_NODES; node++, fp+=4) { /* this is necessary to assure that all float * values are aligned on 4-byte boundaries */ memcpy(fv, fp, sizeof(float)*4); if (rdebug&RDEBUG_SHADE) bu_log("tthrm_setup() node %d (%g %g %g) %g\n", node, fv[0], fv[1], fv[2], fv[3]); /* make sure we don't have any "infinity" values */ for (i=0; i < 4; i++) { if (fv[i] > MAX_FASTF || fv[i] < -MAX_FASTF) { bu_log("%s:%d seg %ld node %d coord %d out of bounds: %g\n", __FILE__, __LINE__, tseg, node, i, fv[i]); bu_bomb("choke, gasp, *croak*\n"); } } /* copy the values to the segment list, converting * from Meters to Millimeters in the process */ VSCALE(tthrm_sp->tt_segs[tseg].node[node], fv, 1000.0); tthrm_sp->tt_segs[tseg].temperature[node] = fv[3]; VADD2(center, center, fv); if (fv[3] > max_temp) max_temp = fv[3]; if (fv[3] < min_temp) min_temp = fv[3]; } VSCALE(center, center, 1000.0); VSCALE(tthrm_sp->tt_segs[tseg].pt, center, inv_nodes); if (rdebug&RDEBUG_SHADE) { bu_log("Center: (%g %g %g) (now in mm, not m)\n", V3ARGS(tthrm_sp->tt_segs[tseg].pt)); } /* compute vectors from center pt for each node */ fp = CYL_DATA(tseg); for (node=0; node < NUM_NODES; node++, fp+=4) { /* this is necessary to assure that all float * values are aligned on 4-byte boundaries */ memcpy(fv, fp, sizeof(float)*4); VSCALE(pt, fv, 1000.0); VSUB2(tthrm_sp->tt_segs[tseg].vect[node], pt, tthrm_sp->tt_segs[tseg].pt ); } /* compute a direction vector for the thermal segment */ VCROSS(dir, tthrm_sp->tt_segs[tseg].vect[0], tthrm_sp->tt_segs[tseg].vect[2]); VUNITIZE(dir); VMOVE(tthrm_sp->tt_segs[tseg].dir, dir); tthrm_sp->tt_segs[tseg].magic = THRM_SEG_MAGIC; } bu_close_mapped_file(tt_file); if (ZERO(tthrm_sp->tt_min_temp) && EQUAL(tthrm_sp->tt_max_temp, SMALL_FASTF)) { tthrm_sp->tt_min_temp = min_temp; tthrm_sp->tt_max_temp = max_temp; bu_log("computed temp min/max on %s: %g/%g\n", rp->reg_name, min_temp, max_temp); } else { min_temp =tthrm_sp->tt_min_temp; max_temp = tthrm_sp->tt_max_temp; bu_log("taking user specified on %s: min/max %g/%g\n", rp->reg_name, min_temp, max_temp); } if (!EQUAL(max_temp, min_temp)) { tthrm_sp->tt_temp_scale = 1.0 / (max_temp - min_temp); } else { /* min and max are equal, maybe zero */ if (ZERO(max_temp)) tthrm_sp->tt_temp_scale = 0.0; else tthrm_sp->tt_temp_scale = 255.0/max_temp; } /* The shader needs to operate in a coordinate system which stays * fixed on the region when the region is moved (as in animation) * we need to get a matrix to perform the appropriate transform(s). * * Shading is done in "region coordinates": */ db_region_mat(tthrm_sp->tthrm_m_to_sh, rtip->rti_dbip, rp->reg_name, &rt_uniresource); if (rdebug&RDEBUG_SHADE) { bu_log("min_temp: %17.14e max_temp %17.14e temp_scale: %17.14e\n", tthrm_sp->tt_min_temp, tthrm_sp->tt_max_temp, tthrm_sp->tt_temp_scale); bu_log("tthrm_setup(%s, %s)done\n", rp->reg_name, bu_vls_addr(matparm)); tthrm_print(rp, *dpp); } return 1; }
void do_pixel(int cpu, int pat_num, int pixelnum) { int i; struct application a; struct pixel_ext pe; vect_t stereo_point; /* Ref point on eye or view plane */ vect_t point; /* Ref point on eye or view plane */ vect_t colorsum = {(fastf_t)0.0, (fastf_t)0.0, (fastf_t)0.0}; int samplenum = 0; static const double one_over_255 = 1.0 / 255.0; register RGBpixel pixel = {0, 0, 0}; const int pindex = (pixelnum * sizeof(RGBpixel)); /* Obtain fresh copy of global application struct */ a = ap; /* struct copy */ a.a_resource = &resource[cpu]; if ( incr_mode ) { register int i = 1<<incr_level; a.a_y = pixelnum/i; a.a_x = pixelnum - (a.a_y * i); /* a.a_x = pixelnum%i; */ if ( incr_level != 0 ) { /* See if already done last pass */ if ( ((a.a_x & 1) == 0 ) && ((a.a_y & 1) == 0 ) ) return; } a.a_x <<= (incr_nlevel-incr_level); a.a_y <<= (incr_nlevel-incr_level); } else { a.a_y = pixelnum/width; a.a_x = pixelnum - (a.a_y * width); /* a.a_x = pixelnum%width; */ } if (Query_one_pixel) { if (a.a_x == query_x && a.a_y == query_y) { rdebug = query_rdebug; rt_g.debug = query_debug; } else { rt_g.debug = rdebug = 0; } } if ( sub_grid_mode ) { if ( a.a_x < sub_xmin || a.a_x > sub_xmax ) return; if ( a.a_y < sub_ymin || a.a_y > sub_ymax ) return; } if ( fullfloat_mode ) { register struct floatpixel *fp; fp = &curr_float_frame[a.a_y*width + a.a_x]; if ( fp->ff_frame >= 0 ) { return; /* pixel was reprojected */ } } /* Check the pixel map to determine if this image should be rendered or not */ if (pixmap) { a.a_user= 1; /* Force Shot Hit */ if (pixmap[pindex + RED] + pixmap[pindex + GRN] + pixmap[pindex + BLU]) { /* non-black pixmap pixel */ a.a_color[RED]= (double)(pixmap[pindex + RED]) * one_over_255; a.a_color[GRN]= (double)(pixmap[pindex + GRN]) * one_over_255; a.a_color[BLU]= (double)(pixmap[pindex + BLU]) * one_over_255; /* we're done */ view_pixel( &a ); if ( a.a_x == width-1 ) { view_eol( &a ); /* End of scan line */ } return; } } /* our starting point, used for non-jitter */ VJOIN2 (point, viewbase_model, a.a_x, dx_model, a.a_y, dy_model); /* not tracing the corners of a prism by default */ a.a_pixelext=(struct pixel_ext *)NULL; /* black or no pixmap, so compute the pixel(s) */ /* LOOP BELOW IS UNROLLED ONE SAMPLE SINCE THAT'S THE COMMON CASE. * * XXX - If you edit the unrolled or non-unrolled section, be sure * to edit the other section. */ if (hypersample == 0) { /* not hypersampling, so just do it */ /****************/ /* BEGIN UNROLL */ /****************/ if (jitter & JITTER_CELL ) { jitter_start_pt(point, &a, samplenum, pat_num); } if (a.a_rt_i->rti_prismtrace) { /* compute the four corners */ pe.magic = PIXEL_EXT_MAGIC; VJOIN2(pe.corner[0].r_pt, viewbase_model, a.a_x, dx_model, a.a_y, dy_model ); VJOIN2(pe.corner[1].r_pt, viewbase_model, (a.a_x+1), dx_model, a.a_y, dy_model ); VJOIN2(pe.corner[2].r_pt, viewbase_model, (a.a_x+1), dx_model, (a.a_y+1), dy_model ); VJOIN2(pe.corner[3].r_pt, viewbase_model, a.a_x, dx_model, (a.a_y+1), dy_model ); a.a_pixelext = &pe; } if ( rt_perspective > 0.0 ) { VSUB2( a.a_ray.r_dir, point, eye_model ); VUNITIZE( a.a_ray.r_dir ); VMOVE( a.a_ray.r_pt, eye_model ); if (a.a_rt_i->rti_prismtrace) { VSUB2(pe.corner[0].r_dir, pe.corner[0].r_pt, eye_model); VSUB2(pe.corner[1].r_dir, pe.corner[1].r_pt, eye_model); VSUB2(pe.corner[2].r_dir, pe.corner[2].r_pt, eye_model); VSUB2(pe.corner[3].r_dir, pe.corner[3].r_pt, eye_model); } } else { VMOVE( a.a_ray.r_pt, point ); VMOVE( a.a_ray.r_dir, ap.a_ray.r_dir ); if (a.a_rt_i->rti_prismtrace) { VMOVE(pe.corner[0].r_dir, a.a_ray.r_dir); VMOVE(pe.corner[1].r_dir, a.a_ray.r_dir); VMOVE(pe.corner[2].r_dir, a.a_ray.r_dir); VMOVE(pe.corner[3].r_dir, a.a_ray.r_dir); } } if ( report_progress ) { report_progress = 0; bu_log("\tframe %d, xy=%d,%d on cpu %d, samp=%d\n", curframe, a.a_x, a.a_y, cpu, samplenum ); } a.a_level = 0; /* recursion level */ a.a_purpose = "main ray"; (void)rt_shootray( &a ); if ( stereo ) { fastf_t right, left; right = CRT_BLEND(a.a_color); VSUB2( stereo_point, point, left_eye_delta ); if ( rt_perspective > 0.0 ) { VSUB2( a.a_ray.r_dir, stereo_point, eye_model ); VUNITIZE( a.a_ray.r_dir ); VADD2( a.a_ray.r_pt, eye_model, left_eye_delta ); } else { VMOVE( a.a_ray.r_pt, stereo_point ); } a.a_level = 0; /* recursion level */ a.a_purpose = "left eye ray"; (void)rt_shootray( &a ); left = CRT_BLEND(a.a_color); VSET( a.a_color, left, 0, right ); } VADD2( colorsum, colorsum, a.a_color ); /**************/ /* END UNROLL */ /**************/ } else { /* hypersampling, so iterate */ for ( samplenum=0; samplenum<=hypersample; samplenum++ ) { /* shoot at a point based on the jitter pattern number */ /**********************/ /* BEGIN NON-UNROLLED */ /**********************/ if (jitter & JITTER_CELL ) { jitter_start_pt(point, &a, samplenum, pat_num); } if (a.a_rt_i->rti_prismtrace) { /* compute the four corners */ pe.magic = PIXEL_EXT_MAGIC; VJOIN2(pe.corner[0].r_pt, viewbase_model, a.a_x, dx_model, a.a_y, dy_model ); VJOIN2(pe.corner[1].r_pt, viewbase_model, (a.a_x+1), dx_model, a.a_y, dy_model ); VJOIN2(pe.corner[2].r_pt, viewbase_model, (a.a_x+1), dx_model, (a.a_y+1), dy_model ); VJOIN2(pe.corner[3].r_pt, viewbase_model, a.a_x, dx_model, (a.a_y+1), dy_model ); a.a_pixelext = &pe; } if ( rt_perspective > 0.0 ) { VSUB2( a.a_ray.r_dir, point, eye_model ); VUNITIZE( a.a_ray.r_dir ); VMOVE( a.a_ray.r_pt, eye_model ); if (a.a_rt_i->rti_prismtrace) { VSUB2(pe.corner[0].r_dir, pe.corner[0].r_pt, eye_model); VSUB2(pe.corner[1].r_dir, pe.corner[1].r_pt, eye_model); VSUB2(pe.corner[2].r_dir, pe.corner[2].r_pt, eye_model); VSUB2(pe.corner[3].r_dir, pe.corner[3].r_pt, eye_model); } } else { VMOVE( a.a_ray.r_pt, point ); VMOVE( a.a_ray.r_dir, ap.a_ray.r_dir ); if (a.a_rt_i->rti_prismtrace) { VMOVE(pe.corner[0].r_dir, a.a_ray.r_dir); VMOVE(pe.corner[1].r_dir, a.a_ray.r_dir); VMOVE(pe.corner[2].r_dir, a.a_ray.r_dir); VMOVE(pe.corner[3].r_dir, a.a_ray.r_dir); } } if ( report_progress ) { report_progress = 0; bu_log("\tframe %d, xy=%d,%d on cpu %d, samp=%d\n", curframe, a.a_x, a.a_y, cpu, samplenum ); } a.a_level = 0; /* recursion level */ a.a_purpose = "main ray"; (void)rt_shootray( &a ); if ( stereo ) { fastf_t right, left; right = CRT_BLEND(a.a_color); VSUB2( stereo_point, point, left_eye_delta ); if ( rt_perspective > 0.0 ) { VSUB2( a.a_ray.r_dir, stereo_point, eye_model ); VUNITIZE( a.a_ray.r_dir ); VADD2( a.a_ray.r_pt, eye_model, left_eye_delta ); } else { VMOVE( a.a_ray.r_pt, stereo_point ); } a.a_level = 0; /* recursion level */ a.a_purpose = "left eye ray"; (void)rt_shootray( &a ); left = CRT_BLEND(a.a_color); VSET( a.a_color, left, 0, right ); } VADD2( colorsum, colorsum, a.a_color ); /********************/ /* END NON-UNROLLED */ /********************/ } /* for samplenum <= hypersample */ { /* scale the hypersampled results */ fastf_t f; f = 1.0 / (hypersample+1); VSCALE( a.a_color, colorsum, f ); } } /* end unrolling else case */ /* bu_log("2: [%d,%d] : [%.2f,%.2f,%.2f]\n", pixelnum%width, pixelnum/width, a.a_color[0], a.a_color[1], a.a_color[2]); */ /* we're done */ view_pixel( &a ); if ( a.a_x == width-1 ) { view_eol( &a ); /* End of scan line */ } return; }
int ged_move_botpts(struct ged *gedp, int argc, const char *argv[]) { static const char *usage = "bot vec vertex_1 [vertex_2 ... vertex_n]"; struct directory *dp; struct rt_db_internal intern; struct rt_bot_internal *botip; mat_t mat; register int i; size_t vertex_i; char *last; /* must be double for scanf */ double vec[ELEMENTS_PER_VECT]; GED_CHECK_DATABASE_OPEN(gedp, GED_ERROR); GED_CHECK_ARGC_GT_0(gedp, argc, GED_ERROR); /* initialize result */ bu_vls_trunc(gedp->ged_result_str, 0); /* must be wanting help */ if (argc == 1) { bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); return GED_HELP; } if (argc < 4) { bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); return GED_ERROR; } if ((last = strrchr(argv[1], '/')) == NULL) last = (char *)argv[1]; else ++last; if (last[0] == '\0') { bu_vls_printf(gedp->ged_result_str, "%s: illegal input - %s", argv[0], argv[1]); return GED_ERROR; } dp = db_lookup(gedp->ged_wdbp->dbip, last, LOOKUP_QUIET); if (dp == RT_DIR_NULL) { bu_vls_printf(gedp->ged_result_str, "%s: failed to find %s", argv[0], argv[1]); return GED_ERROR; } if (bu_sscanf(argv[2], "%lf %lf %lf", &vec[X], &vec[Y], &vec[Z]) != 3) { bu_vls_printf(gedp->ged_result_str, "%s: bad vector - %s", argv[0], argv[2]); return GED_ERROR; } VSCALE(vec, vec, gedp->ged_wdbp->dbip->dbi_local2base); if (wdb_import_from_path2(gedp->ged_result_str, &intern, argv[1], gedp->ged_wdbp, mat) == GED_ERROR) { bu_vls_printf(gedp->ged_result_str, "%s: failed to find %s", argv[0], argv[1]); return GED_ERROR; } if (intern.idb_major_type != DB5_MAJORTYPE_BRLCAD || intern.idb_minor_type != DB5_MINORTYPE_BRLCAD_BOT) { bu_vls_printf(gedp->ged_result_str, "Object is not a BOT"); rt_db_free_internal(&intern); return GED_ERROR; } botip = (struct rt_bot_internal *)intern.idb_ptr; for (i = 3; i < argc; ++i) { if (bu_sscanf(argv[i], "%zu", &vertex_i) != 1) { bu_vls_printf(gedp->ged_result_str, "%s: bad bot vertex index - %s\n", argv[0], argv[i]); continue; } if (vertex_i >= botip->num_vertices) { bu_vls_printf(gedp->ged_result_str, "%s: bad bot vertex index - %s\n", argv[0], argv[i]); continue; } VADD2(&botip->vertices[vertex_i*3], vec, &botip->vertices[vertex_i*3]); } { mat_t invmat; point_t curr_pt; size_t idx; bn_mat_inv(invmat, mat); for (idx = 0; idx < botip->num_vertices; idx++) { MAT4X3PNT(curr_pt, invmat, &botip->vertices[idx*3]); VMOVE(&botip->vertices[idx*3], curr_pt); } } GED_DB_PUT_INTERNAL(gedp, dp, &intern, &rt_uniresource, GED_ERROR); rt_db_free_internal(&intern); return GED_OK; }
int ged_bot_edge_split(struct ged *gedp, int argc, const char *argv[]) { static const char *usage = "bot edge"; struct directory *dp; struct rt_db_internal intern; struct rt_bot_internal *botip; mat_t mat; char *last; size_t v1_i; size_t v2_i; size_t last_fi; size_t last_vi; size_t save_vi; size_t i; point_t new_pt; GED_CHECK_DATABASE_OPEN(gedp, GED_ERROR); GED_CHECK_ARGC_GT_0(gedp, argc, GED_ERROR); /* initialize result */ bu_vls_trunc(gedp->ged_result_str, 0); /* must be wanting help */ if (argc == 1) { bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); return GED_HELP; } if (argc != 3) { bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); return GED_ERROR; } if ((last = strrchr(argv[1], '/')) == NULL) last = (char *)argv[1]; else ++last; if (last[0] == '\0') { bu_vls_printf(gedp->ged_result_str, "%s: illegal input - %s", argv[0], argv[1]); return GED_ERROR; } dp = db_lookup(gedp->ged_wdbp->dbip, last, LOOKUP_QUIET); if (dp == RT_DIR_NULL) { bu_vls_printf(gedp->ged_result_str, "%s: failed to find %s", argv[0], argv[1]); return GED_ERROR; } if (bu_sscanf(argv[2], "%zu %zu", &v1_i, &v2_i) != 2) { bu_vls_printf(gedp->ged_result_str, "%s: bad bot edge - %s", argv[0], argv[2]); return GED_ERROR; } if (wdb_import_from_path2(gedp->ged_result_str, &intern, last, gedp->ged_wdbp, mat) == GED_ERROR) { bu_vls_printf(gedp->ged_result_str, "%s: failed to find %s", argv[0], argv[1]); return GED_ERROR; } if (intern.idb_major_type != DB5_MAJORTYPE_BRLCAD || intern.idb_minor_type != DB5_MINORTYPE_BRLCAD_BOT) { bu_vls_printf(gedp->ged_result_str, "Object is not a BOT"); rt_db_free_internal(&intern); return GED_ERROR; } botip = (struct rt_bot_internal *)intern.idb_ptr; last_fi = botip->num_faces; last_vi = botip->num_vertices; if (v1_i >= botip->num_vertices || v2_i >= botip->num_vertices) { bu_vls_printf(gedp->ged_result_str, "%s: bad bot edge - %s", argv[0], argv[2]); rt_db_free_internal(&intern); return GED_ERROR; } /* * Create the new point, modify all faces (should only be two) * that share the specified edge and hook in the two extra faces. */ /* First, create some space */ botip->num_vertices++; botip->num_faces += 2; botip->vertices = (fastf_t *)bu_realloc((void *)botip->vertices, botip->num_vertices*3*sizeof(fastf_t), "realloc bot vertices"); botip->faces = (int *)bu_realloc((void *)botip->faces, botip->num_faces*3*sizeof(int), "realloc bot faces"); /* Create the new point. We're using the average of the edge's points */ VADD2(new_pt, &botip->vertices[v1_i*3], &botip->vertices[v2_i*3]); VSCALE(new_pt, new_pt, 0.5); /* Add the new point to the last position in the list of vertices. */ VMOVE(&botip->vertices[last_vi*3], new_pt); /* Update faces associated with the specified edge */ for (i = 0; i < last_fi; ++i) { if (((size_t)botip->faces[i*3] == v1_i && (size_t)botip->faces[i*3+1] == v2_i) || ((size_t)botip->faces[i*3] == v2_i && (size_t)botip->faces[i*3+1] == v1_i)) { save_vi = botip->faces[i*3+1]; botip->faces[i*3+1] = last_vi; /* Initialize a new face */ botip->faces[last_fi*3] = last_vi; botip->faces[last_fi*3+1] = save_vi; botip->faces[last_fi*3+2] = botip->faces[i*3+2]; ++last_fi; } else if (((size_t)botip->faces[i*3] == v1_i && (size_t)botip->faces[i*3+2] == v2_i) || ((size_t)botip->faces[i*3] == v2_i && (size_t)botip->faces[i*3+2] == v1_i)) { save_vi = botip->faces[i*3]; botip->faces[i*3] = last_vi; /* Initialize a new face */ botip->faces[last_fi*3] = last_vi; botip->faces[last_fi*3+1] = save_vi; botip->faces[last_fi*3+2] = botip->faces[i*3+1]; ++last_fi; } else if (((size_t)botip->faces[i*3+1] == v1_i && (size_t)botip->faces[i*3+2] == v2_i) || ((size_t)botip->faces[i*3+1] == v2_i && (size_t)botip->faces[i*3+2] == v1_i)) { save_vi = botip->faces[i*3+2]; botip->faces[i*3+2] = last_vi; /* Initialize a new face */ botip->faces[last_fi*3] = botip->faces[i*3]; botip->faces[last_fi*3+1] = last_vi; botip->faces[last_fi*3+2] = save_vi; ++last_fi; } if (last_fi >= botip->num_faces) break; } GED_DB_PUT_INTERNAL(gedp, dp, &intern, &rt_uniresource, GED_ERROR); rt_db_free_internal(&intern); return GED_OK; }
/* * Given an XYZ hit point, compute the concentric ring structure. We do * this by computing the dot-product of the hit point vs. the ring vertex, * which is then used to compute the distance from the ring center. This * distance is then multiplied by a velocity coefficient that is signed. */ HIDDEN int wood_render(struct application *UNUSED(ap), const struct partition *UNUSED(partp), struct shadework *swp, void *dp) { register struct wood_specific *wd = (struct wood_specific *)dp; vect_t g, h; point_t dprod, lprod; double c, A, B, C; double x, y, z, xd, yd, zd; double mixture, pp, pq, wt; /* * Compute the normalized hit point */ xd = wd->b_max[0] - wd->b_min[0] + 1.0; yd = wd->b_max[1] - wd->b_min[1] + 1.0; zd = wd->b_max[2] - wd->b_min[2] + 1.0; x = wd->dither[X] + ((swp->sw_hit.hit_point[0] - wd->b_min[0]) / xd); y = wd->dither[Y] + ((swp->sw_hit.hit_point[1] - wd->b_min[1]) / yd); z = wd->dither[Z] + ((swp->sw_hit.hit_point[2] - wd->b_min[2]) / zd); /* * Compute the distance from the ring center to the hit * point by formulating a triangle between the hit point, * the ring vertex, and ring's local X-axis. */ VSUB2(h, swp->sw_hit.hit_point, wd->vertex); VMOVE(g, h); VUNITIZE(g); /* xlate to ray */ wt = wood_turb(x, y, z, wd) * wd->depth; /* used in two places */ c = fabs(VDOT(g, wd->dir)); A = MAGNITUDE(h) + wt; B = c * A; /* abscissa */ C = sqrt(pow(A, 2.0) - pow(B, 2.0)); /* ordinate */ /* * Divide the ordinate by the spacing coefficient, and * compute the sine from that product. */ c = fabs(sin((C / wd->spacing) * M_PI)); /* * Dither the "q" control */ pq = cos(((wd->qd * wt) + wd->qp + wd->phase) * DEG2RAD); pp = cos(wd->phase * DEG2RAD); /* * Color the hit point based on the phase of the ring */ if (c < pq) { VMOVE(swp->sw_color, wd->lt_rgb); } else if (c >= pp) { VMOVE(swp->sw_color, wd->dk_rgb); } else { mixture = (c - pq) / (pp - pq); VSCALE(lprod, wd->lt_rgb, (1.0 - mixture)); VSCALE(dprod, wd->dk_rgb, mixture); VADD2(swp->sw_color, lprod, dprod); } /* * All done. Return to the caller */ return 1; }