/** * 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 */ }
HIDDEN int add_operator(struct ged *gedp, struct bu_list *hp, char ch, short int *last_tok) { char illegal[2]; BU_CK_LIST_HEAD(hp); switch (ch) { case 'u': append_union(hp); *last_tok = TOK_UNION; break; case '+': append_inter(hp); *last_tok = TOK_INTER; break; case '-': append_subtr(hp); *last_tok = TOK_SUBTR; break; default: illegal[0] = ch; illegal[1] = '\0'; bu_vls_printf(gedp->ged_result_str, "Illegal operator: %s, aborting\n", illegal); free_tokens(hp); return GED_ERROR; } return GED_OK; }
int rt_superell_plot(struct bu_list *vhead, struct rt_db_internal *ip, const struct rt_tess_tol *UNUSED(ttol), const struct bn_tol *UNUSED(tol), const struct rt_view_info *UNUSED(info)) { int i; struct rt_superell_internal *eip; fastf_t top[16*3]; fastf_t middle[16*3]; fastf_t bottom[16*3]; BU_CK_LIST_HEAD(vhead); RT_CK_DB_INTERNAL(ip); eip = (struct rt_superell_internal *)ip->idb_ptr; RT_SUPERELL_CK_MAGIC(eip); rt_superell_16pts(top, eip->v, eip->a, eip->b); rt_superell_16pts(bottom, eip->v, eip->b, eip->c); rt_superell_16pts(middle, eip->v, eip->a, eip->c); RT_ADD_VLIST(vhead, &top[15*ELEMENTS_PER_VECT], BN_VLIST_LINE_MOVE); for (i=0; i<16; i++) { RT_ADD_VLIST(vhead, &top[i*ELEMENTS_PER_VECT], BN_VLIST_LINE_DRAW); } RT_ADD_VLIST(vhead, &bottom[15*ELEMENTS_PER_VECT], BN_VLIST_LINE_MOVE); for (i=0; i<16; i++) { RT_ADD_VLIST(vhead, &bottom[i*ELEMENTS_PER_VECT], BN_VLIST_LINE_DRAW); } RT_ADD_VLIST(vhead, &middle[15*ELEMENTS_PER_VECT], BN_VLIST_LINE_MOVE); for (i=0; i<16; i++) { RT_ADD_VLIST(vhead, &middle[i*ELEMENTS_PER_VECT], BN_VLIST_LINE_DRAW); } return 0; }
int rt_obj_plot(struct bu_list *vhead, struct rt_db_internal *ip, const struct rt_tess_tol *ttol, const struct bn_tol *tol) { int id; const struct rt_functab *ft; if (!vhead || !ip) return -1; BU_CK_LIST_HEAD(vhead); RT_CK_DB_INTERNAL(ip); if (ttol) RT_CK_TESS_TOL(ttol); if (tol) BN_CK_TOL(tol); id = ip->idb_minor_type; if (id < 0) return -2; ft = &rt_functab[id]; if (!ft) return -3; if (!ft->ft_plot) return -4; return ft->ft_plot(vhead, ip, ttol, tol, NULL); }
HIDDEN int wdb_add_operator(Tcl_Interp *interp, struct bu_list *hp, char ch, short int *last_tok) { char illegal[2]; BU_CK_LIST_HEAD(hp); switch (ch) { case 'u': wdb_append_union(hp); *last_tok = WDB_TOK_UNION; break; case '+': wdb_append_inter(hp); *last_tok = WDB_TOK_INTER; break; case '-': wdb_append_subtr(hp); *last_tok = WDB_TOK_SUBTR; break; default: illegal[0] = ch; illegal[1] = '\0'; Tcl_AppendResult(interp, "Illegal operator: ", illegal, ", aborting\n", (char *)NULL); wdb_free_tokens(hp); return TCL_ERROR; } return TCL_OK; }
/** * R T _ P G _ P L O T */ int rt_pg_plot(struct bu_list *vhead, struct rt_db_internal *ip, const struct rt_tess_tol *UNUSED(ttol), const struct bn_tol *UNUSED(tol), const struct rt_view_info *UNUSED(info)) { 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; pp = &pgp->poly[p]; RT_ADD_VLIST(vhead, &pp->verts[3*(pp->npts-1)], BN_VLIST_LINE_MOVE); for (i=0; i < pp->npts; i++) { RT_ADD_VLIST(vhead, &pp->verts[3*i], BN_VLIST_LINE_DRAW); } } return 0; /* OK */ }
HIDDEN int wdb_add_operand(Tcl_Interp *interp, struct bu_list *hp, char *name) { char *ptr_lparen; char *ptr_rparen; int name_len; union tree *node; struct tokens *tok; BU_CK_LIST_HEAD(hp); ptr_lparen = strchr(name, '('); ptr_rparen = strchr(name, ')'); RT_GET_TREE( node, &rt_uniresource ); node->magic = RT_TREE_MAGIC; node->tr_op = OP_DB_LEAF; node->tr_l.tl_mat = (matp_t)NULL; if (ptr_lparen || ptr_rparen) { int tmp1, tmp2; if (ptr_rparen) tmp1 = ptr_rparen - name; else tmp1 = (-1); if (ptr_lparen) tmp2 = ptr_lparen - name; else tmp2 = (-1); if (tmp2 == (-1) && tmp1 > 0) name_len = tmp1; else if (tmp1 == (-1) && tmp2 > 0) name_len = tmp2; else if (tmp1 > 0 && tmp2 > 0) { if (tmp1 < tmp2) name_len = tmp1; else name_len = tmp2; } else { Tcl_AppendResult(interp, "Cannot determine length of operand name: ", name, ", aborting\n", (char *)NULL); return (0); } } else name_len = strlen( name ); node->tr_l.tl_name = (char *)bu_malloc(name_len+1, "node name"); bu_strlcpy(node->tr_l.tl_name, name, name_len+1); tok = (struct tokens *)bu_malloc(sizeof(struct tokens), "tok"); tok->type = WDB_TOK_TREE; tok->tp = node; BU_LIST_INSERT(hp, &tok->l); return (name_len); }
HIDDEN int add_operand(struct ged *gedp, struct bu_list *hp, char *name) { char *ptr_lparen; char *ptr_rparen; int name_len; union tree *node; struct tokens *tok; BU_CK_LIST_HEAD(hp); ptr_lparen = strchr(name, '('); ptr_rparen = strchr(name, ')'); RT_GET_TREE(node, &rt_uniresource); node->tr_op = OP_DB_LEAF; node->tr_l.tl_mat = (matp_t)NULL; if (ptr_lparen || ptr_rparen) { int tmp1, tmp2; if (ptr_rparen) tmp1 = ptr_rparen - name; else tmp1 = (-1); if (ptr_lparen) tmp2 = ptr_lparen - name; else tmp2 = (-1); if (tmp2 == (-1) && tmp1 > 0) name_len = tmp1; else if (tmp1 == (-1) && tmp2 > 0) name_len = tmp2; else if (tmp1 > 0 && tmp2 > 0) { if (tmp1 < tmp2) name_len = tmp1; else name_len = tmp2; } else { bu_vls_printf(gedp->ged_result_str, "Cannot determine length of operand name: %s, aborting\n", name); return 0; } } else name_len = (int)strlen(name); node->tr_l.tl_name = (char *)bu_malloc(name_len+1, "node name"); bu_strlcpy(node->tr_l.tl_name, name, name_len+1); BU_ALLOC(tok, struct tokens); tok->type = TOK_TREE; tok->tp = node; BU_LIST_INSERT(hp, &tok->l); return name_len; }
void show_sites (struct bu_list *sl) { struct site *sp; BU_CK_LIST_HEAD(sl); for (BU_LIST_FOR(sp, site, sl)) { bu_log("I got a site (%g, %g, %g)\n", sp->s_x, sp->s_y, sp->s_z); } }
int rt_xxx_plot(struct bu_list *vhead, struct rt_db_internal *ip, const struct rt_tess_tol *UNUSED(ttol), const struct bn_tol *UNUSED(tol), const struct rt_view_info *UNUSED(info)) { struct rt_xxx_internal *xxx_ip; BU_CK_LIST_HEAD(vhead); RT_CK_DB_INTERNAL(ip); xxx_ip = (struct rt_xxx_internal *)ip->idb_ptr; RT_XXX_CK_MAGIC(xxx_ip); return -1; }
HIDDEN void wdb_append_inter(struct bu_list *hp) { struct tokens *tok; BU_CK_LIST_HEAD(hp); tok = (struct tokens *)bu_malloc(sizeof(struct tokens), "tok"); tok->type = WDB_TOK_INTER; tok->tp = (union tree *)NULL; BU_LIST_INSERT( hp, &tok->l ); }
HIDDEN void append_union(struct bu_list *hp) { struct tokens *tok; BU_CK_LIST_HEAD(hp); BU_ALLOC(tok, struct tokens); tok->type = TOK_UNION; tok->tp = (union tree *)NULL; BU_LIST_INSERT(hp, &tok->l); }
HIDDEN void wdb_append_inter(struct bu_list *hp) { struct tokens *tok; BU_CK_LIST_HEAD(hp); BU_ALLOC(tok, struct tokens); tok->type = WDB_TOK_INTER; tok->tp = (union tree *)NULL; BU_LIST_INSERT(hp, &tok->l); }
void enqueue_site (struct bu_list *sl, fastf_t x, fastf_t y, fastf_t z) { struct site *sp; BU_CK_LIST_HEAD(sl); sp = (struct site *) bu_malloc(sizeof(struct site), "site structure"); sp -> s_magic = SITE_MAGIC; sp -> s_x = x; sp -> s_y = y; sp -> s_z = z; BU_LIST_INSERT(sl, &(sp -> l)); }
void enqueue_site (struct bu_list *sl, fastf_t x, fastf_t y, fastf_t z) { struct site *sp; BU_CK_LIST_HEAD(sl); BU_ALLOC(sp, struct site); sp->s_magic = SITE_MAGIC; sp->s_x = x; sp->s_y = y; sp->s_z = z; BU_LIST_INSERT(sl, &(sp->l)); }
HIDDEN void wdb_free_tokens(struct bu_list *hp) { struct tokens *tok; BU_CK_LIST_HEAD(hp); while (BU_LIST_WHILE(tok, tokens, hp)) { BU_LIST_DEQUEUE(&tok->l); if (tok->type == WDB_TOK_TREE) { db_free_tree(tok->tp, &rt_uniresource); } } }
/** * text is for the title line */ static void show_scripts(struct bu_list *sl, char *text) { int i; struct script_rec *srp; BU_CK_LIST_HEAD(sl); i = 0; bu_log("- - - - - - - The command-line scripts - - - - - - -\n%s\n", text); for (BU_LIST_FOR(srp, script_rec, sl)) { BU_CKMAG(srp, SCRIPT_REC_MAGIC, "script record"); bu_log("%d. script %s '%s'\n", ++i, (srp->sr_type == READING_STRING) ? "string" : (srp->sr_type == READING_FILE) ? "file" : "???", bu_vls_addr(&(srp->sr_script))); } bu_log("- - - - - - - - - - - - - - - - - - - - - - - - - -\n"); }
/** * string is a literal or a file name */ static void enqueue_script(struct bu_list *qp, int type, char *string) { struct script_rec *srp; FILE *cfPtr; struct bu_vls str = BU_VLS_INIT_ZERO; BU_CK_LIST_HEAD(qp); BU_ALLOC(srp, struct script_rec); srp->sr_magic = SCRIPT_REC_MAGIC; srp->sr_type = type; bu_vls_init(&(srp->sr_script)); /*Check if supplied file name is local or in brlcad's nirt data dir*/ if (type == READING_FILE) { bu_vls_trunc(&str, 0); bu_vls_printf(&str, "%s", string); cfPtr = fopen(bu_vls_addr(&str), "rb"); if (cfPtr == NULL) { bu_vls_trunc(&str, 0); bu_vls_printf(&str, "%s/%s.nrt", bu_brlcad_data("nirt", 0), string); cfPtr = fopen(bu_vls_addr(&str), "rb"); if (cfPtr != NULL) { fclose(cfPtr); } else { bu_vls_trunc(&str, 0); bu_vls_printf(&str, "%s", string); } } else { fclose(cfPtr); } bu_vls_printf(&(srp->sr_script), "%s", bu_vls_addr(&str)); } else { bu_vls_strcat(&(srp->sr_script), string); } BU_LIST_INSERT(qp, &(srp->l)); bu_vls_free(&str); }
int rt_metaball_plot(struct bu_list *vhead, struct rt_db_internal *ip, const struct rt_tess_tol *UNUSED(ttol), const struct bn_tol *UNUSED(tol), const struct rt_view_info *UNUSED(info)) { struct rt_metaball_internal *mb; struct wdb_metaballpt *mbpt; point_t bsc; fastf_t rad; BU_CK_LIST_HEAD(vhead); RT_CK_DB_INTERNAL(ip); mb = (struct rt_metaball_internal *)ip->idb_ptr; RT_METABALL_CK_MAGIC(mb); rad = rt_metaball_get_bounding_sphere(&bsc, mb->threshold, mb); /* cope with the case where 0 points are defined. */ if (rad<0) return 0; #if PLOT_THE_BIG_BOUNDING_SPHERE rt_metaball_plot_sph(vhead, &bsc, rad); #endif for (BU_LIST_FOR(mbpt, wdb_metaballpt, &mb->metaball_ctrl_head)) rt_metaball_plot_sph(vhead, &mbpt->coord, mbpt->fldstr / mb->threshold); return 0; }
void rt_metaball_plot_sph(struct bu_list *vhead, point_t *center, fastf_t radius) { fastf_t top[16*3], middle[16*3], bottom[16*3]; point_t a, b, c; int i; BU_CK_LIST_HEAD(vhead); VSET(a, radius, 0, 0); VSET(b, 0, radius, 0); VSET(c, 0, 0, radius); rt_ell_16pts(top, *center, a, b); rt_ell_16pts(bottom, *center, b, c); rt_ell_16pts(middle, *center, a, c); RT_ADD_VLIST(vhead, &top[15*ELEMENTS_PER_VECT], BN_VLIST_LINE_MOVE); for (i = 0; i < 16; i++) RT_ADD_VLIST(vhead, &top[i*ELEMENTS_PER_VECT], BN_VLIST_LINE_DRAW); RT_ADD_VLIST(vhead, &bottom[15*ELEMENTS_PER_VECT], BN_VLIST_LINE_MOVE); for (i = 0; i < 16; i++) RT_ADD_VLIST(vhead, &bottom[i*ELEMENTS_PER_VECT], BN_VLIST_LINE_DRAW); RT_ADD_VLIST(vhead, &middle[15*ELEMENTS_PER_VECT], BN_VLIST_LINE_MOVE); for (i = 0; i < 16; i++) RT_ADD_VLIST(vhead, &middle[i*ELEMENTS_PER_VECT], BN_VLIST_LINE_DRAW); }
/********************************************************** * Code for identifying semi-flat patches in bots * and creating wireframe edges **********************************************************/ extern "C" int rt_bot_adaptive_plot(struct rt_db_internal *ip, const struct rt_view_info *info) { struct rt_bot_internal *bot; RT_CK_DB_INTERNAL(ip); BU_CK_LIST_HEAD(info->vhead); bot = (struct rt_bot_internal *)ip->idb_ptr; RT_BOT_CK_MAGIC(bot); vect_t gvects[6]; VSET(gvects[0], -1,0,0); VSET(gvects[1], 0,-1,0); VSET(gvects[2], 0,0,-1); VSET(gvects[3], 1,0,0); VSET(gvects[4], 0,1,0); VSET(gvects[5], 0,0,1); if (bot->num_vertices <= 0 || !bot->vertices || bot->num_faces <= 0 || !bot->faces) return 0; /* Declare key containers */ double *face_normals= (double *)bu_calloc(bot->num_faces * 3, sizeof(double), "normals"); /* Stash all the initial categorization test results - can be re-used later */ // unsigned int *categorization_results = (unsigned int *)bu_calloc(sizeof(unsigned int) * bot->num_faces * 6, "categorization results"); /* Initial group assignments */ unsigned int *groups = (unsigned int *)bu_calloc(bot->num_faces, sizeof(unsigned int), "groups"); /* Initially, patch breakdown is made in a faces -> patch_id map */ unsigned int *patches= (unsigned int *)bu_calloc(bot->num_faces, sizeof(unsigned int), "patch_id_numbers"); /* Don't know yet how big these needs to be */ unsigned int *vert_to_face = NULL; /* Sanity check vertex indices in face definitions */ for (unsigned int i = 0; i < bot->num_faces; ++i) { if ((unsigned int)bot->faces[i*3+0] > (unsigned int)(bot->num_vertices)) return 0; if ((unsigned int)bot->faces[i*3+1] > (unsigned int)(bot->num_vertices)) return 0; if ((unsigned int)bot->faces[i*3+2] > (unsigned int)(bot->num_vertices)) return 0; } /* Pre-compute face normals once */ for (unsigned int i = 0; i < bot->num_faces; i++) { vect_t a, b, norm_dir; VSUB2(a, &bot->vertices[bot->faces[i*3+1]*3], &bot->vertices[bot->faces[i*3]*3]); VSUB2(b, &bot->vertices[bot->faces[i*3+2]*3], &bot->vertices[bot->faces[i*3]*3]); VCROSS(norm_dir, a, b); VUNITIZE(norm_dir); face_normals[i*3]=norm_dir[0]; face_normals[i*3+1]=norm_dir[1]; face_normals[i*3+2]=norm_dir[2]; } /* Calculate categorization results and assign groups */ for (unsigned int i = 0; i < bot->num_faces; i++) { int result_max = 0; double result = 0.0; double vdot = 0.0; vect_t norm_dir; VSET(norm_dir, face_normals[i*3], face_normals[i*3+1], face_normals[i*3+2]); for (unsigned int j=0; j < 6; j++) { vdot = VDOT(gvects[j],norm_dir); //categorization_results[i*j] = vdot; if (vdot > result) { result_max = j; result = vdot; } } groups[i] = result_max; } bu_free(face_normals, "face_normals"); /* Determine the maximum number of faces associated with any one vertex */ unsigned int *vert_face_cnt = (unsigned int *)bu_calloc(bot->num_vertices, sizeof(unsigned int), "vert face cnt"); for (unsigned int i = 0; i < bot->num_faces; i++) { vert_face_cnt[bot->faces[i*3+0]]++; vert_face_cnt[bot->faces[i*3+1]]++; vert_face_cnt[bot->faces[i*3+2]]++; } unsigned int max_face_cnt = 0; for (unsigned int i = 0; i < bot->num_vertices; i++) { if (vert_face_cnt[i] > max_face_cnt) max_face_cnt = vert_face_cnt[i]; } /* Now, allocate a 2D array that can hold the full vert->face map * and populate it */ vert_to_face = (unsigned int *)bu_calloc(bot->num_vertices * max_face_cnt, sizeof(unsigned int), "map"); unsigned int *vert_sizes = (unsigned int *)bu_calloc(bot->num_vertices, sizeof(unsigned int), "map"); for (unsigned int i = 0; i < bot->num_faces; i++) { for (unsigned int j = 0; j < 3; j++) { unsigned int vert = bot->faces[i*3+j]; unsigned int k = vert_sizes[vert]; /* rows are vertex indexes, columns hold the faces */ /* Need to increment face index by one so we can reference * the first face and still use the true/false test that 0 allows */ vert_to_face[max_face_cnt * vert + k] = i + 1; vert_sizes[vert]++; //bu_log("vert_to_face(%d,%d)[%d] = %d\n", vert, k, max_face_cnt * vert + k, i + 1); } } /* Order the groups by number of bots */ /* Note - needed only when group boarders are not enforced in patch building */ // unsigned int group_cnt[6] = {0}; unsigned int ordered_groups[6] = {0,1,2,3,4,5}; /* for (unsigned int i = 0; i < bot->num_faces; i++) { group_cnt[groups[i]]++; } for (unsigned int i = 0; i < 6; i++) { unsigned int more = 0; for (unsigned int j = 0; j < 6; j++) { if (group_cnt[j] > group_cnt[i]) more++; } ordered_groups[more] = i; } */ // All faces must belong to some patch - continue until all faces are processed unsigned int patch_cnt = 0; for (unsigned int i = 0; i < 6; i++) { int unused = 0; while (unused != -1) { unsigned int face_stp = 0; // Start a new patch unused = -1; patch_cnt++; // Find remaining face in group while (unused == -1 && face_stp < bot->num_faces) { if (ordered_groups[i] == groups[face_stp] && !patches[face_stp]) { unused = face_stp; } face_stp++; } if (unused != -1) { std::queue<unsigned int> face_queue; face_queue.push(unused); patches[unused] = patch_cnt; while (!face_queue.empty()) { unsigned int face_num = face_queue.front(); face_queue.pop(); for (unsigned int k = 0; k < 3; k++) { unsigned int vert_id = bot->faces[face_num*3+k]; for (unsigned int l = 0; l < vert_face_cnt[vert_id]; l++) { unsigned int new_face = vert_to_face[max_face_cnt * vert_id + l] - 1; if (groups[new_face] == ordered_groups[i] && !patches[new_face]) { face_queue.push(new_face); patches[new_face] = patch_cnt; } } } } } } } bu_free(groups, "groups"); bu_free(vert_to_face, "vert_to_face"); unsigned int *patch_vert_cnt = vert_sizes; memset(patch_vert_cnt, 0, bot->num_vertices * sizeof(unsigned int)); unsigned int *vert_edge_status = (unsigned int *)bu_calloc(bot->num_vertices, sizeof(unsigned int), "vert status"); for (unsigned int i = 0; i < patch_cnt; i++) { memset(patch_vert_cnt, 0, bot->num_vertices * sizeof(unsigned int)); for (unsigned int j = 0; j < bot->num_faces; j++) { if (patches[j] == i+1) { patch_vert_cnt[bot->faces[j*3+0]]++; patch_vert_cnt[bot->faces[j*3+1]]++; patch_vert_cnt[bot->faces[j*3+2]]++; } } for (unsigned int j = 0; j < bot->num_vertices; j++) { if (patch_vert_cnt[j] && patch_vert_cnt[j] != vert_face_cnt[j]) { vert_edge_status[j]++; } } } bu_free(patches, "patches"); bu_free(patch_vert_cnt, "patch_vert_cnt"); bu_free(vert_face_cnt, "vert_face_cnt"); for (unsigned int j = 0; j < bot->num_faces; j++) { if (vert_edge_status[bot->faces[j*3+0]] && vert_edge_status[bot->faces[j*3+1]]) { RT_ADD_VLIST(info->vhead, &(bot->vertices[bot->faces[j*3+0]*3]), BN_VLIST_LINE_MOVE); RT_ADD_VLIST(info->vhead, &(bot->vertices[bot->faces[j*3+1]*3]), BN_VLIST_LINE_DRAW); } if (vert_edge_status[bot->faces[j*3+1]] && vert_edge_status[bot->faces[j*3+2]]) { RT_ADD_VLIST(info->vhead, &(bot->vertices[bot->faces[j*3+1]*3]), BN_VLIST_LINE_MOVE); RT_ADD_VLIST(info->vhead, &(bot->vertices[bot->faces[j*3+2]*3]), BN_VLIST_LINE_DRAW); } if (vert_edge_status[bot->faces[j*3+2]] && vert_edge_status[bot->faces[j*3+0]]) { RT_ADD_VLIST(info->vhead, &(bot->vertices[bot->faces[j*3+2]*3]), BN_VLIST_LINE_MOVE); RT_ADD_VLIST(info->vhead, &(bot->vertices[bot->faces[j*3+0]*3]), BN_VLIST_LINE_DRAW); } } bu_free(vert_edge_status, "vert status"); return 0; }
int rt_revolve_plot(struct bu_list *vhead, struct rt_db_internal *ip, const struct rt_tess_tol *ttol, const struct bn_tol *UNUSED(tol), const struct rt_view_info *UNUSED(info)) { struct rt_revolve_internal *rip; size_t nvert, narc, nadd, nseg, i, j, k; point2d_t *verts; struct rt_curve *crv; vect_t ell[16], cir[16], ucir[16], height, xdir, ydir, ux, uy, uz, rEnd, xEnd, yEnd; fastf_t cos22_5 = 0.9238795325112867385; fastf_t cos67_5 = 0.3826834323650898373; int *endcount = NULL; point_t add, add2, add3; BU_CK_LIST_HEAD(vhead); RT_CK_DB_INTERNAL(ip); rip = (struct rt_revolve_internal *)ip->idb_ptr; RT_REVOLVE_CK_MAGIC(rip); nvert = rip->skt->vert_count; verts = rip->skt->verts; crv = &rip->skt->curve; if (rip->ang < M_2PI) { narc = ceil(rip->ang * 8 * M_1_PI); } else { narc = 16; } VSCALE(xEnd, rip->r, cos(rip->ang)); VCROSS(rEnd, rip->axis3d, rip->r); /* using rEnd for temp storage */ VSCALE(yEnd, rEnd, sin(rip->ang)); VADD2(rEnd, xEnd, yEnd); VMOVE(uz, rip->axis3d); VMOVE(ux, rip->r); VCROSS(uy, uz, ux); VUNITIZE(ux); VUNITIZE(uy); VUNITIZE(uz); /* setup unit circle to be scaled */ VMOVE(ucir[ 0], ux); VREVERSE(ucir[ 8], ucir[0]); VSCALE(xdir, ux, cos22_5); VSCALE(ydir, uy, cos67_5); VADD2(ucir[ 1], xdir, ydir); VREVERSE(ucir[ 9], ucir[1]); VREVERSE(xdir, xdir); VADD2(ucir[ 7], xdir, ydir); VREVERSE(ucir[15], ucir[7]); VSCALE(xdir, ux, M_SQRT1_2); VSCALE(ydir, uy, M_SQRT1_2); VADD2(ucir[ 2], xdir, ydir); VREVERSE(ucir[10], ucir[2]); VREVERSE(xdir, xdir); VADD2(ucir[ 6], xdir, ydir); VREVERSE(ucir[14], ucir[6]); VSCALE(xdir, ux, cos67_5); VSCALE(ydir, uy, cos22_5); VADD2(ucir[ 3], xdir, ydir); VREVERSE(ucir[11], ucir[3]); VREVERSE(xdir, xdir); VADD2(ucir[ 5], xdir, ydir); VREVERSE(ucir[13], ucir[5]); VMOVE(ucir[ 4], uy); VREVERSE(ucir[12], ucir[4]); /* find open endpoints, and determine which points are used */ if (nvert) endcount = (int *)bu_calloc(nvert, sizeof(int), "endcount"); nseg = rip->skt->curve.count; for (i=0; i<nseg; i++) { uint32_t *lng; struct line_seg *lsg; struct carc_seg *csg; struct nurb_seg *nsg; struct bezier_seg *bsg; lng = (uint32_t *)rip->skt->curve.segment[i]; switch (*lng) { case CURVE_LSEG_MAGIC: lsg = (struct line_seg *)lng; endcount[lsg->start]++; endcount[lsg->end]++; break; case CURVE_CARC_MAGIC: csg = (struct carc_seg *)lng; if (csg->radius <= 0.0) break; endcount[csg->start]++; endcount[csg->end]++; break; case CURVE_BEZIER_MAGIC: bsg = (struct bezier_seg *)lng; endcount[bsg->ctl_points[0]]++; endcount[bsg->ctl_points[bsg->degree]]++; break; case CURVE_NURB_MAGIC: nsg = (struct nurb_seg *)lng; endcount[nsg->ctl_points[0]]++; endcount[nsg->ctl_points[nsg->c_size-1]]++; break; default: bu_log("rt_revolve_prep: ERROR: unrecognized segment type!\n"); break; } } /* draw circles */ for (i=0; i<nvert; i++) { if (endcount[i] == 0) continue; VSCALE(height, uz, verts[i][Y]); for (j=0; j<narc; j++) { VSCALE(cir[j], ucir[j], verts[i][X]); VADD3(ell[j], rip->v3d, cir[j], height); } RT_ADD_VLIST(vhead, ell[0], BN_VLIST_LINE_MOVE); for (j=1; j<narc; j++) { RT_ADD_VLIST(vhead, ell[j], BN_VLIST_LINE_DRAW); } if (narc < 16) { VSCALE(cir[narc], rEnd, verts[i][X]); VADD3(ell[narc], rip->v3d, cir[narc], height); RT_ADD_VLIST(vhead, ell[narc], BN_VLIST_LINE_DRAW); } else { RT_ADD_VLIST(vhead, ell[0], BN_VLIST_LINE_DRAW); } } /* convert endcounts to store which endpoints are odd */ for (i=0, j=0; i<rip->skt->vert_count; i++) { if (endcount[i] % 2 != 0) { /* add 'i' to list, insertion sort by vert[i][Y] */ for (k=j; k>0; k--) { if ((ZERO(verts[i][Y] - verts[endcount[k-1]][Y]) && verts[i][X] > verts[endcount[k-1]][X]) || (!ZERO(verts[i][Y] - verts[endcount[k-1]][Y]) && verts[i][Y] < verts[endcount[k-1]][Y])) { endcount[k] = endcount[k-1]; } else { break; } } endcount[k] = i; j++; } } nadd = j; while (j < rip->skt->vert_count) { endcount[j++] = -1; } /* draw sketch outlines */ for (i=0; i<narc; i++) { curve_to_vlist(vhead, ttol, rip->v3d, ucir[i], uz, rip->skt, crv); for (j=0; j<nadd; j++) { if (j+1 < nadd && ZERO(verts[endcount[j]][Y] - verts[endcount[j+1]][Y])) { VJOIN1(add, rip->v3d, verts[endcount[j]][Y], rip->axis3d); VJOIN1(add2, add, verts[endcount[j]][X], ucir[i]); VJOIN1(add3, add, verts[endcount[j+1]][X], ucir[i]); RT_ADD_VLIST(vhead, add2, BN_VLIST_LINE_MOVE); RT_ADD_VLIST(vhead, add3, BN_VLIST_LINE_DRAW); j++; } else { VJOIN1(add, rip->v3d, verts[endcount[j]][Y], rip->axis3d); VJOIN1(add2, add, verts[endcount[j]][X], ucir[i]); RT_ADD_VLIST(vhead, add, BN_VLIST_LINE_MOVE); RT_ADD_VLIST(vhead, add2, BN_VLIST_LINE_DRAW); } } } if (narc < 16) { curve_to_vlist(vhead, ttol, rip->v3d, rEnd, uz, rip->skt, crv); for (j=0; j<nadd; j++) { if (j+1 < nadd && ZERO(verts[endcount[j]][Y] - verts[endcount[j+1]][Y])) { VJOIN1(add, rip->v3d, verts[endcount[j]][Y], rip->axis3d); VJOIN1(add2, add, verts[endcount[j]][X], rEnd); VJOIN1(add3, add, verts[endcount[j+1]][X], rEnd); RT_ADD_VLIST(vhead, add2, BN_VLIST_LINE_MOVE); RT_ADD_VLIST(vhead, add3, BN_VLIST_LINE_DRAW); j++; } else { VJOIN1(add, rip->v3d, verts[endcount[j]][Y], rip->axis3d); VJOIN1(add2, add, verts[endcount[j]][X], rEnd); RT_ADD_VLIST(vhead, add, BN_VLIST_LINE_MOVE); RT_ADD_VLIST(vhead, add2, BN_VLIST_LINE_DRAW); } } for (j=0; j<nadd; j+=2) { if (!ZERO(verts[endcount[j]][Y] - verts[endcount[j+1]][Y])) { VJOIN1(add, rip->v3d, verts[endcount[j]][Y], rip->axis3d); VJOIN1(add2, rip->v3d, verts[endcount[j+1]][Y], rip->axis3d); RT_ADD_VLIST(vhead, add, BN_VLIST_LINE_MOVE); RT_ADD_VLIST(vhead, add2, BN_VLIST_LINE_DRAW); } } } if (nvert) bu_free(endcount, "endcount"); return 0; }
/** * Brute force through all possible plane intersections. * Generate all edge lines, then intersect the line with all * the other faces to find the vertices on that line. * If the geometry is correct, there will be no more than two. * While not the fastest strategy, this will produce an accurate * plot without requiring extra bookkeeping. * Note that the vectors will be drawn in no special order. */ int rt_arbn_plot(struct bu_list *vhead, struct rt_db_internal *ip, const struct rt_tess_tol *UNUSED(ttol), const struct bn_tol *tol, const struct rt_view_info *UNUSED(info)) { struct rt_arbn_internal *aip; size_t i; size_t j; size_t k; BU_CK_LIST_HEAD(vhead); RT_CK_DB_INTERNAL(ip); aip = (struct rt_arbn_internal *)ip->idb_ptr; RT_ARBN_CK_MAGIC(aip); for (i = 0; i < aip->neqn - 1; i++) { for (j = i + 1; j < aip->neqn; j++) { double dot; int point_count; /* # points on this line */ point_t a, b; /* start and end points */ vect_t dist; VSETALL(a, 0); VSETALL(b, 0); /* If normals are parallel, no intersection */ dot = VDOT(aip->eqn[i], aip->eqn[j]); if (BN_VECT_ARE_PARALLEL(dot, tol)) continue; /* Have an edge line, isect with all other planes */ point_count = 0; for (k = 0; k < aip->neqn; k++) { size_t m; point_t pt; size_t next_k; next_k = 0; if (k == i || k == j) continue; if (bn_mkpoint_3planes(pt, aip->eqn[i], aip->eqn[j], aip->eqn[k]) < 0) continue; /* See if point is outside arb */ for (m = 0; m < aip->neqn; m++) { if (i == m || j == m || k == m) continue; if (VDOT(pt, aip->eqn[m])-aip->eqn[m][3] > tol->dist) { next_k = 1; break; } } if (next_k != 0) continue; if (point_count <= 0) { RT_ADD_VLIST(vhead, pt, BN_VLIST_LINE_MOVE); VMOVE(a, pt); } else if (point_count == 1) { VSUB2(dist, pt, a); if (MAGSQ(dist) < tol->dist_sq) continue; RT_ADD_VLIST(vhead, pt, BN_VLIST_LINE_DRAW); VMOVE(b, pt); } else { VSUB2(dist, pt, a); if (MAGSQ(dist) < tol->dist_sq) continue; VSUB2(dist, pt, b); if (MAGSQ(dist) < tol->dist_sq) continue; bu_log("rt_arbn_plot() error, point_count=%d (>2) on edge %zu/%zu, non-convex\n", point_count+1, i, j); VPRINT(" a", a); VPRINT(" b", b); VPRINT("pt", pt); RT_ADD_VLIST(vhead, pt, BN_VLIST_LINE_DRAW); /* draw it */ } point_count++; } /* Point counts of 1 are (generally) not harmful, * occurring on pyramid peaks and the like. */ } } return 0; }
int rt_hyp_plot(struct bu_list *vhead, struct rt_db_internal *incoming, const struct rt_tess_tol *UNUSED(ttol), const struct bn_tol *UNUSED(tol), const struct rt_view_info *UNUSED(info)) { int i, j; /* loop indices */ struct rt_hyp_internal *hyp_in; struct hyp_specific *hyp; vect_t majorAxis[8], /* vector offsets along major axis */ minorAxis[8], /* vector offsets along minor axis */ heightAxis[7], /* vector offsets for layers */ Bunit; /* unit vector along semi-minor axis */ vect_t ell[16]; /* stores 16 points to draw ellipses */ vect_t ribs[16][7]; /* assume 7 layers for now */ fastf_t scale; /* used to calculate semi-major/minor axes for top/bottom */ fastf_t cos22_5 = 0.9238795325112867385; fastf_t cos67_5 = 0.3826834323650898373; BU_CK_LIST_HEAD(vhead); RT_CK_DB_INTERNAL(incoming); hyp_in = (struct rt_hyp_internal *)incoming->idb_ptr; RT_HYP_CK_MAGIC(hyp_in); hyp = hyp_internal_to_specific(hyp_in); VCROSS(Bunit, hyp->hyp_H, hyp->hyp_Au); VUNITIZE(Bunit); VMOVE(heightAxis[0], hyp->hyp_H); VSCALE(heightAxis[1], heightAxis[0], 0.5); VSCALE(heightAxis[2], heightAxis[0], 0.25); VSETALL(heightAxis[3], 0); VREVERSE(heightAxis[4], heightAxis[2]); VREVERSE(heightAxis[5], heightAxis[1]); VREVERSE(heightAxis[6], heightAxis[0]); for (i = 0; i < 7; i++) { /* determine Z height depending on i */ scale = sqrt(MAGSQ(heightAxis[i])*(hyp->hyp_c * hyp->hyp_c)/(hyp->hyp_r1 * hyp->hyp_r1) + 1); /* calculate vectors for offset */ VSCALE(majorAxis[0], hyp->hyp_Au, hyp->hyp_r1 * scale); VSCALE(majorAxis[1], majorAxis[0], cos22_5); VSCALE(majorAxis[2], majorAxis[0], M_SQRT1_2); VSCALE(majorAxis[3], majorAxis[0], cos67_5); VREVERSE(majorAxis[4], majorAxis[3]); VREVERSE(majorAxis[5], majorAxis[2]); VREVERSE(majorAxis[6], majorAxis[1]); VREVERSE(majorAxis[7], majorAxis[0]); VSCALE(minorAxis[0], Bunit, hyp->hyp_r2 * scale); VSCALE(minorAxis[1], minorAxis[0], cos22_5); VSCALE(minorAxis[2], minorAxis[0], M_SQRT1_2); VSCALE(minorAxis[3], minorAxis[0], cos67_5); VREVERSE(minorAxis[4], minorAxis[3]); VREVERSE(minorAxis[5], minorAxis[2]); VREVERSE(minorAxis[6], minorAxis[1]); VREVERSE(minorAxis[7], minorAxis[0]); /* calculate ellipse */ VADD3(ell[ 0], hyp->hyp_V, heightAxis[i], majorAxis[0]); VADD4(ell[ 1], hyp->hyp_V, heightAxis[i], majorAxis[1], minorAxis[3]); VADD4(ell[ 2], hyp->hyp_V, heightAxis[i], majorAxis[2], minorAxis[2]); VADD4(ell[ 3], hyp->hyp_V, heightAxis[i], majorAxis[3], minorAxis[1]); VADD3(ell[ 4], hyp->hyp_V, heightAxis[i], minorAxis[0]); VADD4(ell[ 5], hyp->hyp_V, heightAxis[i], majorAxis[4], minorAxis[1]); VADD4(ell[ 6], hyp->hyp_V, heightAxis[i], majorAxis[5], minorAxis[2]); VADD4(ell[ 7], hyp->hyp_V, heightAxis[i], majorAxis[6], minorAxis[3]); VADD3(ell[ 8], hyp->hyp_V, heightAxis[i], majorAxis[7]); VADD4(ell[ 9], hyp->hyp_V, heightAxis[i], majorAxis[6], minorAxis[4]); VADD4(ell[10], hyp->hyp_V, heightAxis[i], majorAxis[5], minorAxis[5]); VADD4(ell[11], hyp->hyp_V, heightAxis[i], majorAxis[4], minorAxis[6]); VADD3(ell[12], hyp->hyp_V, heightAxis[i], minorAxis[7]); VADD4(ell[13], hyp->hyp_V, heightAxis[i], majorAxis[3], minorAxis[6]); VADD4(ell[14], hyp->hyp_V, heightAxis[i], majorAxis[2], minorAxis[5]); VADD4(ell[15], hyp->hyp_V, heightAxis[i], majorAxis[1], minorAxis[4]); /* draw ellipse */ RT_ADD_VLIST(vhead, ell[15], BN_VLIST_LINE_MOVE); for (j = 0; j < 16; j++) { RT_ADD_VLIST(vhead, ell[j], BN_VLIST_LINE_DRAW); } /* add ellipse's points to ribs */ for (j = 0; j < 16; j++) { VMOVE(ribs[j][i], ell[j]); } } /* draw ribs */ for (i = 0; i < 16; i++) { RT_ADD_VLIST(vhead, ribs[i][0], BN_VLIST_LINE_MOVE); for (j = 1; j < 7; j++) { RT_ADD_VLIST(vhead, ribs[i][j], BN_VLIST_LINE_DRAW); } } BU_PUT(hyp, struct hyp_specific); return 0; }
/** * Make a list of all edgeuses which are at the same distance as the * first element on the list. Toss out opposing pairs of edgeuses of the * same edge. * */ HIDDEN void make_near_list(struct edge_info *edge_list, struct bu_list *near1, const struct bn_tol *tol) { struct edge_info *ei; struct edge_info *ei_p; struct edge_info *tmp; fastf_t dist; BU_CK_LIST_HEAD(&edge_list->l); BU_CK_LIST_HEAD(near1); /* toss opposing pairs of uses of the same edge from the list */ ei = BU_LIST_FIRST(edge_info, &edge_list->l); while (BU_LIST_NOT_HEAD(&ei->l, &edge_list->l)) { NMG_CK_EI(ei); ei_p = BU_LIST_FIRST(edge_info, &edge_list->l); while (BU_LIST_NOT_HEAD(&ei_p->l, &edge_list->l)) { NMG_CK_EI(ei_p); NMG_CK_VED(ei_p->ved_p); /* if we've found an opposing use of the same * edge toss the pair of them */ if (ei_p->ved_p->magic_p == ei->ved_p->magic_p && ei_p->eu_p->eumate_p->vu_p->v_p == ei->eu_p->vu_p->v_p && ei_p->eu_p->vu_p->v_p == ei->eu_p->eumate_p->vu_p->v_p) { if (UNLIKELY(RTG.NMG_debug & DEBUG_PT_FU)) { bu_log("tossing edgeuse pair:\n"); bu_log("(%g %g %g) -> (%g %g %g)\n", V3ARGS(ei->eu_p->vu_p->v_p->vg_p->coord), V3ARGS(ei->eu_p->eumate_p->vu_p->v_p->vg_p->coord)); bu_log("(%g %g %g) -> (%g %g %g)\n", V3ARGS(ei_p->eu_p->vu_p->v_p->vg_p->coord), V3ARGS(ei_p->eu_p->eumate_p->vu_p->v_p->vg_p->coord)); } tmp = ei_p; ei_p = BU_LIST_PLAST(edge_info, &ei_p->l); BU_LIST_DEQUEUE(&tmp->l); bu_free((char *)tmp, "edge info struct"); tmp = ei; ei = BU_LIST_PLAST(edge_info, &ei->l); BU_LIST_DEQUEUE(&tmp->l); bu_free((char *)tmp, "edge info struct"); break; } ei_p = BU_LIST_PNEXT(edge_info, &ei_p->l); } ei = BU_LIST_PNEXT(edge_info, &ei->l); } if (BU_LIST_IS_EMPTY(&edge_list->l)) return; ei = BU_LIST_FIRST(edge_info, &edge_list->l); NMG_CK_EI(ei); NMG_CK_VED(ei->ved_p); dist = ei->ved_p->dist; /* create "near" list with all ei's at this dist */ for (BU_LIST_FOR(ei, edge_info, &edge_list->l)) { NMG_CK_EI(ei); NMG_CK_VED(ei->ved_p); if (NEAR_EQUAL(ei->ved_p->dist, dist, tol->dist_sq)) { ei_p = BU_LIST_PLAST(edge_info, &ei->l); BU_LIST_DEQUEUE(&ei->l); BU_LIST_APPEND(near1, &ei->l); ei = ei_p; } } if (UNLIKELY(RTG.NMG_debug & DEBUG_PT_FU)) { bu_log("dist %g near list\n", dist); for (BU_LIST_FOR(ei, edge_info, near1)) { bu_log("\t(%g %g %g) -> (%g %g %g)\n", V3ARGS(ei->eu_p->vu_p->v_p->vg_p->coord), V3ARGS(ei->eu_p->eumate_p->vu_p->v_p->vg_p->coord)); bu_log("\tdist:%g class:%s status:%d\n\t\tv1(%g %g %g) v2(%g %g %g)\n", ei->ved_p->dist, nmg_class_name(ei->nmg_class), ei->ved_p->status, V3ARGS(ei->ved_p->v1->vg_p->coord), V3ARGS(ei->ved_p->v2->vg_p->coord)); bu_log("\tei->ved_p->magic_p=%p, ei->eu_p->vu_p=%p, ei->eu_p->eumate_p->vu_p=%p\n", (void *)ei->ved_p->magic_p, (void *)ei->eu_p->vu_p, (void *)ei->eu_p->eumate_p->vu_p); } }
/* * This is called (from viewshade() in shade.c) once for each hit point * to be shaded. The purpose here is to fill in values in the shadework * structure. */ int gauss_render(struct application *ap, const struct partition *pp, struct shadework *swp, void *dp) /* defined in material.h */ /* ptr to the shader-specific struct */ { register struct gauss_specific *gauss_sp = (struct gauss_specific *)dp; struct seg *seg_p; struct reg_db_internals *dbint_p; double optical_density = 0.0; /* check the validity of the arguments we got */ RT_AP_CHECK(ap); RT_CHECK_PT(pp); CK_gauss_SP(gauss_sp); if (rdebug&RDEBUG_SHADE) { bu_struct_print("gauss_render Parameters:", gauss_print_tab, (char *)gauss_sp); bu_log("r_pt(%g %g %g) r_dir(%g %g %g)\n", V3ARGS(ap->a_ray.r_pt), V3ARGS(ap->a_ray.r_dir)); } BU_CK_LIST_HEAD(&swp->sw_segs->l); BU_CK_LIST_HEAD(&gauss_sp->dbil); /* look at each segment that participated in the ray partition(s) */ for (BU_LIST_FOR(seg_p, seg, &swp->sw_segs->l)) { if (rdebug&RDEBUG_SHADE) { bu_log("seg %g -> %g\n", seg_p->seg_in.hit_dist, seg_p->seg_out.hit_dist); } RT_CK_SEG(seg_p); RT_CK_SOLTAB(seg_p->seg_stp); /* check to see if the seg/solid is in this partition */ if (bu_ptbl_locate(&pp->pt_seglist, (long *)seg_p) != -1) { /* XXX You might use a bu_ptbl list of the solid pointers... */ /* check to see if the solid is from this region */ for (BU_LIST_FOR(dbint_p, reg_db_internals, &gauss_sp->dbil)) { CK_DBINT(dbint_p); if (dbint_p->st_p == seg_p->seg_stp) { /* The solid from the region is * the solid from the segment * from the partition */ optical_density += eval_seg(ap, dbint_p, seg_p); break; } } } else { if (rdebug&RDEBUG_SHADE) bu_log("gauss_render() bittest failed\n"); } }