struct obj_info * Part_import( int id_start ) { char line[MAX_LINE_SIZE]; struct obj_info *part; struct wmember reg_head; unsigned char rgb[3]; int surf_count=0; int id_end; int last_surf=0; int i; int tri[3]; int corner_index=-1; clean_vert_tree( tree_root ); VSETALL( rgb, 128 ); BU_ALLOC(part, struct obj_info); part->obj_type = PART_TYPE; part->obj_id = id_start; while ( bu_fgets( line, MAX_LINE_SIZE, fd_in ) ) { if ( !bu_strncmp( line, "PartName", 8 ) ) { line[strlen( line ) - 1] = '\0'; part->obj_name = bu_strdup( &line[9] ); lower_case( part->obj_name ); Make_brlcad_names( part ); } else if ( !bu_strncmp( line, "FaceCount", 9 ) ) { surf_count = atoi( &line[10] ); if ( surf_count == 0 ) { last_surf = 1; } } else if ( !bu_strncmp( line, "EndPartId", 9 ) ) { /* found end of part, check id */ id_end = atoi( &line[10] ); if ( id_end != id_start ) bu_exit( 1, "%s: ERROR: found end of part id %d while processing part %d\n", progname,id_end, id_start ); if ( last_surf ) { break; } } else if ( !bu_strncmp( line, "FaceRGB", 7 ) ) { /* get face color */ char *ptr; i = 8; ptr = strtok( &line[i], " \t" ); for ( i=0; i<3 && ptr; i++ ) { rgb[i] = atof( ptr ); ptr = strtok( (char *)NULL, " \t" ); } } else if ( !bu_strncmp( line, "Facet", 5 ) ) { /* read a triangle */ VSETALL( tri, -1 ); corner_index = -1; } else if ( !bu_strncmp( line, "Face", 4 ) ) { /* start of a surface */ int surf_no; surf_no = atoi( &line[5] ); if ( surf_no == surf_count ) { last_surf = 1; } } else if ( !bu_strncmp( line, "TriangleCount", 13 ) ) { /* get number of triangles for this surface */ } else if ( !bu_strncmp( line, "Vertices", 9 ) ) { /* get vertex list for this triangle */ } else if ( !bu_strncmp( line, "Vertex", 6 ) ) { /* get a vertex */ char *ptr = NULL; vect_t v = VINIT_ZERO; i = 7; while ( !isspace( (int)line[i] ) && line[i] != '\0' ) i++; ptr = strtok( &line[i], " \t" ); for ( i=0; i<3 && ptr; i++ ) { v[i] = atof( ptr ); ptr = strtok( (char *)NULL, " \t" ); } tri[++corner_index] = Add_vert( V3ARGS( v ), tree_root, local_tol_sq ); if ( corner_index == 2 ) { if ( !bad_triangle( tri, tree_root->the_array ) ) { add_triangle( tri ); } } } else if ( !bu_strncmp( line, "Normal", 6 ) ) { /* get a vertex normal */ } else if ( !bu_strncmp( line, "PointCount", 10 ) ) { /* get number of vertices for this surface */ } else bu_exit( 1, "%s: ERROR: unrecognized line encountered while processing part id %d:\n%s\n", progname,id_start, line ); } if ( curr_tri == 0 ) { /* no facets in this part, so ignore it */ bu_free( (char *)part, "part" ); part = (struct obj_info *)NULL; } else { /* write this part to database, first make a primitive solid */ if ( mk_bot( fd_out, part->brlcad_solid, RT_BOT_SOLID, RT_BOT_UNORIENTED, 0, tree_root->curr_vert, curr_tri, tree_root->the_array, part_tris, NULL, NULL ) ) bu_exit( 1, "%s: Failed to write primitive %s (%s) to database\n", progname,part->brlcad_solid, part->obj_name ); if ( verbose ) { DO_INDENT; bu_log( "Wrote BOT %s\n", part->brlcad_solid ); } /* then a region */ BU_LIST_INIT( ®_head.l ); if ( mk_addmember( part->brlcad_solid, ®_head.l, NULL, WMOP_UNION ) == WMEMBER_NULL ) bu_exit( 1, "%s: ERROR: Failed to add solid (%s), to region (%s)\n", progname,part->brlcad_solid, part->brlcad_comb ); if ( mk_comb( fd_out, part->brlcad_comb, ®_head.l, 1, NULL, NULL, rgb, ident++, 0, 1, 100, 0, 0, 0 ) ) bu_exit( 1, "%s: Failed to write region %s (%s) to database\n", progname,part->brlcad_comb, part->obj_name ); if ( verbose ) { DO_INDENT; bu_log( "Wrote region %s\n", part->brlcad_comb ); } if ( use_part_name_hash ) { if ( db5_update_attribute( part->brlcad_comb, "Part_No", part->obj_name, fd_out->dbip ) ) { bu_log( "Failed to assign Part_no attribute to %s\n", part->brlcad_comb ); } } } /* free some memory */ if ( part_tris ) { bu_free( (char *)part_tris, "part_tris" ); } max_tri = 0; curr_tri = 0; part_tris = NULL; return part; }
int main( int argc, char *argv[] ) { char inputString[512]; float inputX, inputY, inputZ; fastf_t *vertices; int *faces; fastf_t *thickness; FILE *inputFile; short int triangleAvailable; long int triangleCount; long int maxTriangleCapacity; long int j; char *outputObjectName; if (argc != 2) { usage(argv[0]); } outfp = wdb_fopen( "rawbot.g" ); if (outfp == NULL) { fprintf(stderr, "Unable to open the output file rawbot.g\n"); return 1; } /* units would be nice... */ mk_id( outfp, "RAW BOT" ); inputFile = fopen(argv[1], "r"); if (inputFile == NULL) { perror("unable to open file"); fprintf(stderr, "The input file [%s] was not readable\n", argv[1]); return 1; } vertices = bu_calloc(128 * 3, sizeof(fastf_t), "vertices"); maxTriangleCapacity = 128; triangleCount=0; triangleAvailable = 1; while ( triangleAvailable == 1 ) { /* read a set of input values -- input data should be a 3-tuple * of floating points. */ if (fscanf(inputFile, "%512s", inputString) != 1) { triangleAvailable = 0; continue; } inputX = atof(inputString); if (fscanf(inputFile, "%512s", inputString) != 1) { triangleAvailable = 0; continue; } inputY = atof(inputString); if (fscanf(inputFile, "%512s", inputString) != 1) { triangleAvailable = 0; continue; } inputZ = atof(inputString); if (triangleCount >= maxTriangleCapacity) { vertices = bu_realloc(vertices, ((maxTriangleCapacity + 128) * 3) * sizeof(fastf_t), "vertices"); maxTriangleCapacity += 128; } /* VSET( &vertices[triangleCount*3], inputX, inputY, inputZ ); */ vertices[(triangleCount*3)] = inputX; vertices[(triangleCount*3)+1] = inputY; vertices[(triangleCount*3)+2] = inputZ; /* printf("%f %f %f\n", vertices[(triangleCount*3)], vertices[(triangleCount*3)+1], vertices[(triangleCount*3)+2]); */ triangleCount++; } /* done with the input file */ fclose(inputFile); /* make sure we found some vertices */ if (triangleCount <= 0) { fprintf(stderr, "There were no triangles found in the input file\n"); bu_free(vertices, "vertices"); return 0; } else { printf("Found %ld triangles\n", triangleCount); } /* allocate memory for faces and thickness arrays */ /* XXX unfortunately we are limited to sizeof(int) since mk_bot takes * an int array */ faces = (int *)bu_calloc(triangleCount * 3, sizeof(int), "faces"); thickness = (fastf_t *)bu_calloc(triangleCount * 3, sizeof(int), "thickness"); for (j=0; j<triangleCount; j++) { faces[(j*3)] = (j*3); faces[(j*3)+1] = (j*3) + 1; faces[(j*3)+2] = (j*3) + 2; printf("%ld %ld %ld == (%f %f %f)\n", (j*3), (j*3)+1, (j*3)+2, vertices[(j*3)], vertices[(j*3)+1], vertices[(j*3)+2]); thickness[(j*3)] = thickness[(j*3)+1] = thickness[(j*3)+2] = 1.0; } /* for (j=0; j < triangleCount * 3; j++) { printf("%f\n", vertices[j]); } */ outputObjectName = (char *)bu_calloc(512, sizeof(char), "outputObjectName"); snprintf(outputObjectName, 512, "%s.surface.s", argv[1]); mk_bot( outfp, outputObjectName, RT_BOT_SURFACE, RT_BOT_UNORIENTED, 0, triangleCount*3, triangleCount, vertices, faces, (fastf_t *)NULL, (struct bu_bitv *)NULL ); snprintf(outputObjectName, 512, "%s.solid.s", argv[1]); mk_bot( outfp, outputObjectName, RT_BOT_SOLID, RT_BOT_UNORIENTED, 0, triangleCount*3, triangleCount, vertices, faces, (fastf_t *)NULL, (struct bu_bitv *)NULL ); /* snprintf(outputObjectName, 512, "%s.plate.s", argv[1]);*/ /* mk_bot( outfp, "bot_u_plate", RT_BOT_PLATE, RT_BOT_UNORIENTED, 0, triangleCount, triangleCount, vertices, faces, thickness, NULL ); */ bu_free(vertices, "vertices"); bu_free(faces, "faces"); bu_free(thickness, "thickness"); wdb_close(outfp); return 0; }
int main(int argc, char *argv[]) { struct db_i *dbip; struct directory *dp; struct rt_db_internal intern; struct rt_bot_internal *bot_ip = NULL; struct rt_wdb *wdbp; struct bu_vls name; struct bu_vls bname; struct Mesh_Info *prev_mesh = NULL; struct Mesh_Info *mesh = NULL; bu_vls_init(&name); if (argc != 3) { bu_exit(1, "Usage: %s file.g object", argv[0]); } dbip = db_open(argv[1], DB_OPEN_READWRITE); if (dbip == DBI_NULL) { bu_exit(1, "ERROR: Unable to read from geometry database file %s\n", argv[1]); } if (db_dirbuild(dbip) < 0) bu_exit(1, "ERROR: Unable to read from %s\n", argv[1]); dp = db_lookup(dbip, argv[2], LOOKUP_QUIET); if (dp == RT_DIR_NULL) { bu_exit(1, "ERROR: Unable to look up object %s\n", argv[2]); } RT_DB_INTERNAL_INIT(&intern) if (rt_db_get_internal(&intern, dp, dbip, NULL, &rt_uniresource) < 0) { bu_exit(1, "ERROR: Unable to get internal representation of %s\n", argv[2]); } if (intern.idb_minor_type != DB5_MINORTYPE_BRLCAD_BOT) { bu_exit(1, "ERROR: object %s does not appear to be of type BoT\n", argv[2]); } else { bot_ip = (struct rt_bot_internal *)intern.idb_ptr; } RT_BOT_CK_MAGIC(bot_ip); for (size_t i_cnt = 1; i_cnt < 3; i_cnt++) { mesh = iterate(bot_ip, prev_mesh); prev_mesh = mesh; // Plot results struct bu_vls fname; bu_vls_init(&fname); bu_vls_printf(&fname, "root3_%d.pl", i_cnt); FILE* plot_file = fopen(bu_vls_addr(&fname), "w"); std::map<size_t, std::vector<size_t> >::iterator f_it; std::vector<size_t>::iterator l_it; int r = int(256*drand48() + 1.0); int g = int(256*drand48() + 1.0); int b = int(256*drand48() + 1.0); for (f_it = mesh->face_pts.begin(); f_it != mesh->face_pts.end(); f_it++) { l_it = (*f_it).second.begin(); plot_face(&mesh->points_p0[(int)(*l_it)], &mesh->points_p0[(int)(*(l_it+1))], &mesh->points_p0[(int)(*(l_it+2))], r, g , b, plot_file); } fclose(plot_file); } // When constructing the final BoT, use the limit points for all // vertices ON_3dPointArray points_inf; for (size_t v = 0; v < (size_t)mesh->points_p0.Count(); v++) { points_inf.Append(*mesh->points_p0.At((int)v)); //point_inf(v, mesh, &points_inf); } // The subdivision process shrinks the bot relative to its original // vertex positions - to better approximate the original surface, // average the change in position of the original vertices to get a // scaling factor and apply it to all points in the final mesh. fastf_t scale = 0.0; for (size_t pcnt = 0; pcnt < bot_ip->num_vertices; pcnt++) { ON_3dVector v1(ON_3dPoint(&bot_ip->vertices[pcnt*3])); ON_3dVector v2(*points_inf.At((int)pcnt)); scale += 1 + (v1.Length() - v2.Length())/v1.Length(); } scale = scale / bot_ip->num_vertices; for (size_t pcnt = 0; pcnt < (size_t)points_inf.Count(); pcnt++) { ON_3dPoint p0(*points_inf.At((int)pcnt)); ON_3dPoint p1 = p0 * scale; *points_inf.At((int)pcnt) = p1; } wdbp = wdb_dbopen(dbip, RT_WDB_TYPE_DB_DISK); fastf_t *vertices = (fastf_t *)bu_malloc(sizeof(fastf_t) * points_inf.Count() * 3, "new verts"); int *faces = (int *)bu_malloc(sizeof(int) * mesh->face_pts.size() * 3, "new faces"); for (size_t v = 0; v < (size_t)points_inf.Count(); v++) { vertices[v*3] = points_inf[(int)v].x; vertices[v*3+1] = points_inf[(int)v].y; vertices[v*3+2] = points_inf[(int)v].z; } std::map<size_t, std::vector<size_t> >::iterator f_it; std::vector<size_t>::iterator l_it; for (f_it = mesh->face_pts.begin(); f_it != mesh->face_pts.end(); f_it++) { l_it = (*f_it).second.begin(); faces[(*f_it).first*3] = (*l_it); faces[(*f_it).first*3+1] = (*(l_it + 1)); faces[(*f_it).first*3+2] = (*(l_it + 2)); } bu_vls_init(&bname); bu_vls_sprintf(&bname, "%s_subd", argv[2]); mk_bot(wdbp, bu_vls_addr(&bname), RT_BOT_SOLID, RT_BOT_UNORIENTED, 0, points_inf.Count(), mesh->face_pts.size(), vertices, faces, (fastf_t *)NULL, (struct bu_bitv *)NULL); wdb_close(wdbp); bu_vls_free(&bname); bu_free(vertices, "free subdivision BoT vertices"); bu_free(faces, "free subdivision BoT faces"); return 0; }
void writeRingModeBox ( rt_wdb* wdbp, Form& form, bool translate ) { char name[NAMELEN + 1]; // get the transformed outer points vect_t outer[MAX_NPTS]; if (translate) { for (size_t i = 0; i < form.npts; ++i) VADD2(outer[i], form.data.pt[i], form.tr_vec); } else { for (size_t i = 0; i < form.npts; ++i) { VMOVE(outer[i], form.data.pt[i]); } } for (size_t i1 = 0; i1 < form.npts; ++i1) { VSCALE(outer[i1], outer[i1], IntavalUnitInMm); } // compute inner points vect_t inner[MAX_NPTS]; for (size_t i2 = 0; i2 < form.npts; ++i2) { vect_t a, b, c; VMOVE(a, outer[i2]); if (i2 == 0) { VMOVE(b, outer[i2 + 1]); VMOVE(c, outer[form.npts-1]); } else if (i2 == form.npts-1) { VMOVE(b, outer[0]); VMOVE(c, outer[i2 - 1]); } else { VMOVE(b, outer[i2 + 1]); VMOVE(c, outer[i2 - 1]); } vect_t b_v, c_v; VSUB2(b_v, b, a); VSUB2(c_v, c, a); vect_t n_v; VCROSS(n_v, b_v, c_v); // with on b_v vect_t width_b_v; VCROSS(width_b_v, b_v, n_v); if (VDOT(width_b_v, c_v) < 0) VREVERSE(width_b_v, width_b_v); VUNITIZE(width_b_v); VSCALE(width_b_v, width_b_v, form.width * IntavalUnitInMm); // with on c_v vect_t width_c_v; VCROSS(width_c_v, c_v, n_v); if (VDOT(width_c_v, b_v) < 0) VREVERSE(width_c_v, width_c_v); VUNITIZE(width_c_v); VSCALE(width_c_v, width_c_v, form.width * IntavalUnitInMm); // intersection VUNITIZE(b_v); VUNITIZE(c_v); vect_t cb_v; VSUB2(cb_v, b_v, c_v); fastf_t l_cb_v = MAGNITUDE(cb_v); if (!NEAR_ZERO(l_cb_v, VUNITIZE_TOL)) { vect_t width_cb_v; VSUB2(width_cb_v, width_b_v, width_c_v); vect_t s_b_v; VSCALE(s_b_v, b_v, MAGNITUDE(width_cb_v) / l_cb_v); vect_t res; VADD2(res, a, width_c_v); VADD2(res, res, s_b_v); VMOVE(inner[i2], res); } else { VMOVE(inner[i2], outer[i2]); } } // bot parameters // vertices size_t num_vertices = 0; size_t outer_i[MAX_NPTS]; size_t inner_i[MAX_NPTS]; fastf_t vertices[MAX_NPTS * 3]; for (size_t i3 = 0; i3 < form.npts; ++i3) { size_t i = 0; // outer // search for duplicate vertex for (; i < num_vertices; ++i) { if (NEAR_EQUAL(outer[i3][0], vertices[3 * i], VUNITIZE_TOL) && NEAR_EQUAL(outer[i3][1], vertices[3 * i + 1], VUNITIZE_TOL) && NEAR_EQUAL(outer[i3][2], vertices[3 * i + 2], VUNITIZE_TOL)) { outer_i[i3] = i; break; } } if (i == num_vertices) { // add a new vertex vertices[num_vertices * 3] = outer[i3][0]; vertices[num_vertices * 3 + 1] = outer[i3][1]; vertices[num_vertices * 3 + 2] = outer[i3][2]; outer_i[i3] = num_vertices; ++num_vertices; } // inner // search for duplicate vertex for (i = 0; i < num_vertices; ++i) { if (NEAR_EQUAL(inner[i3][0], vertices[3 * i], VUNITIZE_TOL) && NEAR_EQUAL(inner[i3][1], vertices[3 * i + 1], VUNITIZE_TOL) && NEAR_EQUAL(inner[i3][2], vertices[3 * i + 2], VUNITIZE_TOL)) { inner_i[i3] = i; break; } } if (i == num_vertices) { // add a new vertex vertices[num_vertices * 3] = inner[i3][0]; vertices[num_vertices * 3 + 1] = inner[i3][1]; vertices[num_vertices * 3 + 2] = inner[i3][2]; inner_i[i3] = num_vertices; ++num_vertices; } } // faces size_t num_faces = 0; int faces[MAX_TRIANGLES * 3]; for (size_t i4 = 0; i4 < form.npts; ++i4) { size_t nextIndex = (i4 + 1) % form.npts; addTriangle(faces, num_faces, outer_i[i4], outer_i[nextIndex], inner_i[i4]); addTriangle(faces, num_faces, inner_i[i4], outer_i[nextIndex], inner_i[nextIndex]); } fastf_t thickness[MAX_TRIANGLES]; for (size_t i5 = 0; i5 < num_faces; ++i5) thickness[i5] = form.thickness * IntavalUnitInMm; bu_bitv* faceMode = bu_bitv_new(num_faces); sprintf(name, "s%lu.pbot", (long unsigned)++bot_counter); mk_bot(wdbp, name, RT_BOT_PLATE, RT_BOT_UNORIENTED, 0, num_vertices, num_faces, vertices, faces, thickness, faceMode); addToRegion(form.compnr, name); if (form.s_compnr >= 1000) excludeFromRegion(form.s_compnr, name); bu_bitv_free(faceMode); }
int main(int argc, char **argv) { int faces[15]; fastf_t vertices[36]; fastf_t thickness[4]; struct rt_wdb *outfp = NULL; struct bu_bitv *face_mode = NULL; static const char *filename = "bot-test.g"; if (BU_STR_EQUAL(argv[1], "-h") || BU_STR_EQUAL(argv[1], "-?")) { printusage(); return 0; } if (argc == 1) { printusage(); fprintf(stderr," Program continues running (will create file bot-test.g because 'filename' was blank):\n"); } else if (argc > 1) filename = argv[1]; outfp = wdb_fopen(filename); mk_id(outfp, "BOT test"); VSET(vertices, 0.0, 0.0, 0.0); VSET(&vertices[3], 0.0, 100.0, 0.0); VSET(&vertices[6], 0.0, 100.0, 50.0); VSET(&vertices[9], 200.0, 0.0, 0.0); /* face #1 */ faces[0] = 0; faces[1] = 1; faces[2] = 2; /* face #2 */ faces[3] = 0; faces[4] = 2; faces[5] = 3; /* face #3 */ faces[6] = 0; faces[7] = 1; faces[8] = 3; /* face #4 */ faces[9] = 1; faces[10] = 2; faces[11] = 3; mk_bot(outfp, "bot_u_surf", RT_BOT_SURFACE, RT_BOT_UNORIENTED, 0, 4, 4, vertices, faces, (fastf_t *)NULL, (struct bu_bitv *)NULL); /* face #1 */ faces[0] = 0; faces[1] = 2; faces[2] = 1; /* face #2 */ faces[3] = 0; faces[4] = 3; faces[5] = 2; /* face #3 */ faces[6] = 0; faces[7] = 1; faces[8] = 3; /* face #4 */ faces[9] = 1; faces[10] = 2; faces[11] = 3; mk_bot(outfp, "bot_ccw_surf", RT_BOT_SURFACE, RT_BOT_CCW, 0, 4, 4, vertices, faces, (fastf_t *)NULL, (struct bu_bitv *)NULL); /* face #1 */ faces[0] = 1; faces[1] = 2; faces[2] = 0; /* face #2 */ faces[3] = 2; faces[4] = 3; faces[5] = 0; /* face #3 */ faces[6] = 3; faces[7] = 1; faces[8] = 0; /* face #4 */ faces[9] = 3; faces[10] = 2; faces[11] = 1; mk_bot(outfp, "bot_cw_surf", RT_BOT_SURFACE, RT_BOT_CW, 0, 4, 4, vertices, faces, (fastf_t *)NULL, (struct bu_bitv *)NULL); /* face #1 */ faces[0] = 0; faces[1] = 1; faces[2] = 2; /* face #2 */ faces[3] = 0; faces[4] = 2; faces[5] = 3; /* face #3 */ faces[6] = 0; faces[7] = 1; faces[8] = 3; /* face #4 */ faces[9] = 1; faces[10] = 2; faces[11] = 3; mk_bot(outfp, "bot_u_solid", RT_BOT_SOLID, RT_BOT_UNORIENTED, 0, 4, 4, vertices, faces, (fastf_t *)NULL, (struct bu_bitv *)NULL); /* face #1 */ faces[0] = 0; faces[1] = 2; faces[2] = 1; /* face #2 */ faces[3] = 0; faces[4] = 3; faces[5] = 2; /* face #3 */ faces[6] = 0; faces[7] = 1; faces[8] = 3; /* face #4 */ faces[9] = 1; faces[10] = 2; faces[11] = 3; mk_bot(outfp, "bot_ccw_solid", RT_BOT_SOLID, RT_BOT_CCW, 0, 4, 4, vertices, faces, (fastf_t *)NULL, (struct bu_bitv *)NULL); /* face #1 */ faces[0] = 1; faces[1] = 2; faces[2] = 0; /* face #2 */ faces[3] = 2; faces[4] = 3; faces[5] = 0; /* face #3 */ faces[6] = 3; faces[7] = 1; faces[8] = 0; /* face #4 */ faces[9] = 3; faces[10] = 2; faces[11] = 1; mk_bot(outfp, "bot_cw_solid", RT_BOT_SOLID, RT_BOT_CW, 0, 4, 4, vertices, faces, (fastf_t *)NULL, (struct bu_bitv *)NULL); face_mode = bu_bitv_new(4); BU_BITSET(face_mode, 1); thickness[0] = 2.1; thickness[1] = 2.2; thickness[2] = 2.3; thickness[3] = 2.4; /* face #1 */ faces[0] = 0; faces[1] = 1; faces[2] = 2; /* face #2 */ faces[3] = 0; faces[4] = 2; faces[5] = 3; /* face #3 */ faces[6] = 0; faces[7] = 1; faces[8] = 3; /* face #4 */ faces[9] = 1; faces[10] = 2; faces[11] = 3; mk_bot(outfp, "bot_u_plate", RT_BOT_PLATE, RT_BOT_UNORIENTED, 0, 4, 4, vertices, faces, thickness, face_mode); /* face #1 */ faces[0] = 0; faces[1] = 2; faces[2] = 1; /* face #2 */ faces[3] = 0; faces[4] = 3; faces[5] = 2; /* face #3 */ faces[6] = 0; faces[7] = 1; faces[8] = 3; /* face #4 */ faces[9] = 1; faces[10] = 2; faces[11] = 3; mk_bot(outfp, "bot_ccw_plate", RT_BOT_PLATE, RT_BOT_CCW, 0, 4, 4, vertices, faces, thickness, face_mode); /* face #1 */ faces[0] = 1; faces[1] = 2; faces[2] = 0; /* face #2 */ faces[3] = 2; faces[4] = 3; faces[5] = 0; /* face #3 */ faces[6] = 3; faces[7] = 1; faces[8] = 0; /* face #4 */ faces[9] = 3; faces[10] = 2; faces[11] = 1; mk_bot(outfp, "bot_cw_plate", RT_BOT_PLATE, RT_BOT_CW, 0, 4, 4, vertices, faces, thickness, face_mode); /* Make a bot with duplicate vertices to test the "fuse" and "condense" code */ VSET(vertices, 0.0, 0.0, 0.0); VSET(&vertices[3], 0.0, 100.0, 0.0); VSET(&vertices[6], 0.0, 100.0, 50.0); VMOVE(&vertices[9], &vertices[0]); VMOVE(&vertices[12], &vertices[6]); VSET(&vertices[15], 200.0, 0.0, 0.0); VMOVE(&vertices[18], &vertices[0]); VMOVE(&vertices[21], &vertices[3]); VMOVE(&vertices[24], &vertices[15]); VMOVE(&vertices[27], &vertices[3]); VMOVE(&vertices[30], &vertices[6]); VMOVE(&vertices[33], &vertices[15]); /* face #1 */ faces[0] = 0; faces[1] = 1; faces[2] = 2; /* face #2 */ faces[3] = 3; faces[4] = 4; faces[5] = 5; /* face #3 */ faces[6] = 6; faces[7] = 7; faces[8] = 8; /* face #4 */ faces[9] = 9; faces[10] = 10; faces[11] = 11; mk_bot(outfp, "bot_solid_dup_vs", RT_BOT_SOLID, RT_BOT_UNORIENTED, 0, 12, 4, vertices, faces, (fastf_t *)NULL, (struct bu_bitv *)NULL); faces[12] = 9; faces[13] = 10; faces[14] = 11; mk_bot(outfp, "bot_solid_dup_fs", RT_BOT_SOLID, RT_BOT_UNORIENTED, 0, 12, 5, vertices, faces, (fastf_t *)NULL, (struct bu_bitv *)NULL); bu_free((char *)face_mode, "bottest: face_mode"); wdb_close(outfp); return 0; }