Пример #1
0
void
crregion(char *region, char *op, int *members, int number, char *solidname, int maxlen)
{
    int i;
    struct bu_list head;

    if (dbip == DBI_NULL)
	return;

    BU_LIST_INIT(&head);

    for (i=0; i<number; i++) {
	solidname[8] = '\0';
	crname(solidname, members[i], maxlen);
	if ( db_lookup( dbip, solidname, LOOKUP_QUIET) == DIR_NULL ) {
	    Tcl_AppendResult(interp, "region: ", region, " will skip member: ",
			     solidname, "\n", (char *)NULL);
	    continue;
	}
	mk_addmember( solidname, &head, NULL, op[i] );
    }
    (void)mk_comb( wdbp, region, &head,
		   1, NULL, NULL, NULL,
		   500+Trackpos+i, 0, mat_default, los_default,
		   0, 1, 1 );
}
Пример #2
0
bool
BRLCADWrapper::WriteCombs()
{
    MAP_OF_BU_LIST_HEADS::iterator i = heads.begin();
    while (i != heads.end()) {
	std::string combname = (*i).first;
	struct bu_list *head = (*i++).second;
	unsigned char rgb[] = {200, 180, 180};

	(void)mk_comb(outfp, combname.c_str(), head, 0, "plastic", "", rgb, 0, 0, 0, 0, 0, 0, 0);

	mk_freemembers(head);

	BU_FREE(head, struct bu_list);

    }
    heads.clear();
    return true;
}
Пример #3
0
bool
BRLCADWrapper::WriteBrep(std::string name, ON_Brep *brep, mat_t &mat)
{
    std::ostringstream str;
    std::string strcnt;
    std::string sol = name + ".s";
    std::string reg = name;

    mk_brep(outfp, sol.c_str(), brep);
    unsigned char rgb[] = {200, 180, 180};

    BRLCADWrapper::getRandomColor(rgb);

    struct bu_list head;
    BU_LIST_INIT(&head);
    if (mk_addmember(sol.c_str(), &head, mat, WMOP_UNION) == WMEMBER_NULL)
	return false;

    if (mk_comb(outfp, reg.c_str(), &head, 1, "plastic", "", rgb, 0, 0, 0, 0, 0, 0, 0) > 0)
	return true;

    return false;
}
Пример #4
0
struct obj_info *
Assembly_import( int id_start )
{
    char line[MAX_LINE_SIZE];
    struct obj_info *this_assem, *member;
    struct wmember assem_head;
    int id_end, member_id;
    size_t i;

    BU_ALLOC(this_assem, struct obj_info);

    this_assem->obj_type = ASSEMBLY_TYPE;
    this_assem->obj_id = id_start;
    this_assem->part_count = 0;
    this_assem->members = NULL;
    while ( bu_fgets( line, MAX_LINE_SIZE, fd_in ) ) {
	if ( !bu_strncmp( line, "AssemblyName", 12 ) ) {
	    line[strlen( line ) - 1] = '\0';
	    this_assem->obj_name = bu_strdup( &line[13] );
	    lower_case( this_assem->obj_name );
	    DO_INDENT;
	    bu_log( "Start of assembly %s (id = %d)\n", this_assem->obj_name, id_start );
	    indent_level += indent_delta;
	} else if ( !bu_strncmp( line, "PartId", 6 ) ) {
	    /* found a member part */
	    member_id = atoi( &line[7] );
	    member = Part_import( member_id );
	    if ( !member )
		continue;
	    this_assem->part_count++;
	    this_assem->members = (struct obj_info **)bu_realloc(
		this_assem->members,
		this_assem->part_count * sizeof( struct obj_info *),
		"this_assem->members" );
	    this_assem->members[this_assem->part_count-1] = member;
	} else if ( !bu_strncmp( line, "AssemblyId", 10 ) ) {
	    /* found a member assembly */
	    member_id = atoi( &line[11] );
	    member = Assembly_import( member_id );
	    this_assem->part_count++;
	    this_assem->members = (struct obj_info **)bu_realloc(
		this_assem->members,
		this_assem->part_count * sizeof( struct obj_info *),
		"this_assem->members" );
	    this_assem->members[this_assem->part_count-1] = member;
	} else if ( !bu_strncmp( line, "EndAssemblyId", 13 ) ) {
	    /* found end of assembly, make sure it is this one */
	    id_end = atoi( &line[14] );
	    if ( id_end != id_start )
		bu_exit( 1, "%s: ERROR: found end of assembly id %d while processing id %d\n", progname,id_end, id_start );
	    indent_level -= indent_delta;
	    DO_INDENT;
	    bu_log( "Found end of assembly %s (id = %d)\n",  this_assem->obj_name, id_start );
	    break;
	} else {
	    bu_log( "%s: Unrecognized line encountered while processing assembly id %d:\n", progname,id_start );
	    bu_exit( 1, "%s\n", line );
	}
    }

    Make_brlcad_names( this_assem );

    /* write this assembly to the database */
    BU_LIST_INIT( &assem_head.l );

    for ( i=0; i<this_assem->part_count; i++ )
	if ( mk_addmember( this_assem->members[i]->brlcad_comb,
			   &assem_head.l, NULL, WMOP_UNION ) == WMEMBER_NULL )
	    bu_exit( 1, "%s: ERROR: Failed to add region %s to assembly %s\n",
			progname,this_assem->members[i]->brlcad_comb, this_assem->brlcad_comb );

    if ( mk_comb( fd_out, this_assem->brlcad_comb, &assem_head.l, 0, NULL, NULL, NULL,
		  0, 0, 0, 0, 0, 0, 0 ) )
	bu_exit( 1, "%s: ERROR: Failed to write combination (%s) to database\n", progname,this_assem->brlcad_comb );
    if ( use_part_name_hash ) {
	if ( db5_update_attribute( this_assem->brlcad_comb, "Part_No",
				   this_assem->obj_name, fd_out->dbip ) ) {
	    bu_log( "Failed to assign Part_no attribute to %s\n",
		    this_assem->brlcad_comb );
	}
    }

    return this_assem;
}
Пример #5
0
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( &reg_head.l );
	if ( mk_addmember( part->brlcad_solid, &reg_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, &reg_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;
}
Пример #6
0
int
ged_voxelize(struct ged *gedp, int argc, const char *argv[])
{
    struct rt_i *rtip;
    static const char *usage = "[-s \"dx dy dz\"] [-d n] [-t f] new_obj old_obj [old_obj2 old_obj3 ...]";
    fastf_t sizeVoxel[3];
    int levelOfDetail;
    genptr_t callBackData;
    struct voxelizeData voxDat;
    int c;

    /* intentionally double for scan */
    double threshold;

    GED_CHECK_DATABASE_OPEN(gedp, GED_ERROR);
    GED_CHECK_ARGC_GT_0(gedp, argc, GED_ERROR);

    /* initialization */
    bu_vls_trunc(gedp->ged_result_str, 0);

    /* incorrect arguments */
    if (argc < 3) {
	bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage);
	return GED_HELP;
    }

    sizeVoxel[0]  = 1.0;
    sizeVoxel[1]  = 1.0;
    sizeVoxel[2]  = 1.0;
    levelOfDetail = 1;
    threshold = 0.5;

    bu_optind = 1;
    while ((c = bu_getopt(argc, (char * const *)argv, (const char *)"s:d:t:")) != -1) {
	double scan[3];

	switch (c) {
	    case 's':
		if (sscanf(bu_optarg, "%lf %lf %lf",
			   &scan[0],
			   &scan[1],
			   &scan[2]) != 3) {
		    bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage);
		    return GED_ERROR;
		} else {
		    /* convert from double to fastf_t */
		    VMOVE(sizeVoxel, scan);

		    sizeVoxel[0] = sizeVoxel[0] * gedp->ged_wdbp->dbip->dbi_local2base;
		    sizeVoxel[1] = sizeVoxel[1] * gedp->ged_wdbp->dbip->dbi_local2base;
		    sizeVoxel[2] = sizeVoxel[2] * gedp->ged_wdbp->dbip->dbi_local2base;
		}
		break;

	    case 'd':
		if (sscanf(bu_optarg, "%d", &levelOfDetail) != 1) {
		    bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage);
		    return GED_ERROR;
		}
		break;

	    case 't':
		if(sscanf(bu_optarg, "%lf", &threshold) != 1) {
		    bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage);
		    return GED_ERROR;
		}
		break;

	    default:
		bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage);
		return GED_ERROR;
	}
    }

    argc -= bu_optind;
    argv += bu_optind;

    if (argc < 2) {
	bu_vls_printf(gedp->ged_result_str, "error: missing argument(s)\n");
	return GED_ERROR;
    }

    voxDat.newname = (char *)argv[0];
    argc--;
    argv++;

    if (db_lookup(gedp->ged_wdbp->dbip, voxDat.newname, LOOKUP_QUIET) != RT_DIR_NULL) {
	bu_vls_printf(gedp->ged_result_str, "error: solid '%s' already exists, aborting\n", voxDat.newname);
	return GED_ERROR;
    }

    rtip = rt_new_rti(gedp->ged_wdbp->dbip);
    rtip->useair = 1;

    /* Walk trees.  Here we identify any object trees in the database
     * that the user wants included in the ray trace.
     */
    while(argc > 0) {
	if(rt_gettree(rtip,argv[0]) < 0) {
	    bu_vls_printf(gedp->ged_result_str, "error: object '%s' does not exists, aborting\n", argv[1]);
	    return GED_ERROR;
	}

	argc--;
	argv++;
    }


    voxDat.sizeVoxel[0] = sizeVoxel[0];
    voxDat.sizeVoxel[1] = sizeVoxel[1];
    voxDat.sizeVoxel[2] = sizeVoxel[2];
    voxDat.threshold = threshold;
    voxDat.wdbp = gedp->ged_wdbp;
    voxDat.bbMin = rtip->mdl_min;
    BU_LIST_INIT(&voxDat.content.l);

    callBackData = (void*)(&voxDat);

   /* voxelize function is called here with rtip(ray trace instance), userParameter and create_boxes function */
    voxelize(rtip, sizeVoxel, levelOfDetail, create_boxes, callBackData);

    mk_comb(gedp->ged_wdbp, voxDat.newname, &voxDat.content.l, 1, "plastic", "sh=4 sp=0.5 di=0.5 re=0.1", 0, 1000, 0, 0, 100, 0, 0, 0);

    mk_freemembers(&voxDat.content.l);
    rt_free_rti(rtip);

    return GED_OK;
}
Пример #7
0
/*
 *
 *	F _ A M T R A C K ( ) :	adds track given "wheel" info
 *
 */
int
f_amtrack(ClientData clientData, Tcl_Interp *interp, int argc, char **argv)
{

    fastf_t fw[3], lw[3], iw[3], dw[3], tr[3];
    char solname[12], regname[12], grpname[9], oper[3];
    int i, j, memb[4];
    char temp[4];
    vect_t	temp1, temp2;
    int item, mat, los;
    int arg;
    int edit_result;
    struct bu_list head;

    CHECK_DBI_NULL;
    CHECK_READ_ONLY;

    BU_LIST_INIT(&head);

    if (argc < 1 || 27 < argc) {
	struct bu_vls vls;

	bu_vls_init(&vls);
	bu_vls_printf(&vls, "help track");
	Tcl_Eval(interp, bu_vls_addr(&vls));
	bu_vls_free(&vls);
	return TCL_ERROR;
    }

    /* interupts */
    if ( setjmp( jmp_env ) == 0 )
	(void)signal( SIGINT, sig3);  /* allow interupts */
    else
	return TCL_OK;

    oper[0] = oper[2] = WMOP_INTERSECT;
    oper[1] = WMOP_SUBTRACT;

    arg = 1;

    /* get the roadwheel info */
    if ( argc < arg+1 ) {
	Tcl_AppendResult(interp, MORE_ARGS_STR, "Enter X of the FIRST roadwheel: ",
			 (char *)NULL);
	edit_result = TCL_ERROR;
	goto end;
    }
    fw[0] = atof( argv[arg] ) * local2base;
    ++arg;

    if ( argc < arg+1 ) {
	Tcl_AppendResult(interp, MORE_ARGS_STR, "Enter X of the LAST roadwheel: ",
			 (char *)NULL);
	edit_result = TCL_ERROR;
	goto end;
    }
    lw[0] = atof( argv[arg] ) * local2base;
    ++arg;

    if ( fw[0] <= lw[0] ) {
	Tcl_AppendResult(interp, "First wheel after last wheel - STOP\n", (char *)NULL);
	edit_result = TCL_ERROR;
	goto end;
    }

    if ( argc < arg+1 ) {
	Tcl_AppendResult(interp, MORE_ARGS_STR, "Enter Z of the roadwheels: ",
			 (char *)NULL);
	edit_result = TCL_ERROR;
	goto end;
    }
    fw[1] = lw[1] = atof( argv[arg] ) * local2base;
    ++arg;

    if ( argc < arg+1 ) {
	Tcl_AppendResult(interp, MORE_ARGS_STR, "Enter radius of the roadwheels: ",
			 (char *)NULL);
	edit_result = TCL_ERROR;
	goto end;
    }
    fw[2] = lw[2] = atof( argv[arg] ) * local2base;
    ++arg;
    if ( fw[2] <= 0 ) {
	Tcl_AppendResult(interp, "Radius <= 0 - STOP\n", (char *)NULL);
	edit_result = TCL_ERROR;
	goto end;
    }

    if ( argc < arg+1 ) {
	/* get the drive wheel info */
	Tcl_AppendResult(interp, MORE_ARGS_STR, "Enter X of the drive (REAR) wheel: ",
			 (char *)NULL);
	edit_result = TCL_ERROR;
	goto end;
    }
    dw[0] = atof( argv[arg] ) * local2base;
    ++arg;
    if ( dw[0] >= lw[0] ) {
	Tcl_AppendResult(interp, "DRIVE wheel not in the rear - STOP \n", (char *)NULL);
	edit_result = TCL_ERROR;
	goto end;
    }

    if ( argc < arg+1 ) {
	Tcl_AppendResult(interp, MORE_ARGS_STR, "Enter Z of the drive (REAR) wheel: ",
			 (char *)NULL);
	edit_result = TCL_ERROR;
	goto end;
    }
    dw[1] = atof( argv[arg] ) * local2base;
    ++arg;

    if ( argc < arg+1 ) {
	Tcl_AppendResult(interp, MORE_ARGS_STR, "Enter radius of the drive (REAR) wheel: ",
			 (char *)NULL);
	edit_result = TCL_ERROR;
	goto end;
    }
    dw[2] = atof( argv[arg] ) * local2base;
    ++arg;
    if ( dw[2] <= 0 ) {
	Tcl_AppendResult(interp, "Radius <= 0 - STOP\n", (char *)NULL);
	edit_result = TCL_ERROR;
	goto end;
    }

    /* get the idler wheel info */
    if ( argc < arg+1 ) {
	Tcl_AppendResult(interp, MORE_ARGS_STR, "Enter X of the idler (FRONT) wheel: ",
			 (char *)NULL);
	edit_result = TCL_ERROR;
	goto end;
    }
    iw[0] = atof( argv[arg] ) * local2base;
    ++arg;
    if ( iw[0] <= fw[0] ) {
	Tcl_AppendResult(interp, "IDLER wheel not in the front - STOP \n", (char *)NULL);
	edit_result = TCL_ERROR;
	goto end;
    }

    if ( argc < arg+1 ) {
	Tcl_AppendResult(interp, MORE_ARGS_STR, "Enter Z of the idler (FRONT) wheel: ",
			 (char *)NULL);
	edit_result = TCL_ERROR;
	goto end;
    }
    iw[1] = atof( argv[arg] ) * local2base;
    ++arg;

    if ( argc < arg+1 ) {
	Tcl_AppendResult(interp, MORE_ARGS_STR, "Enter radius of the idler (FRONT) wheel: ",
			 (char *)NULL);
	edit_result = TCL_ERROR;
	goto end;
    }
    iw[2] = atof( argv[arg] ) * local2base;
    ++arg;
    if ( iw[2] <= 0 ) {
	Tcl_AppendResult(interp, "Radius <= 0 - STOP\n", (char *)NULL);
	edit_result = TCL_ERROR;
	goto end;
    }

    /* get track info */
    if ( argc < arg+1 ) {
	Tcl_AppendResult(interp, MORE_ARGS_STR, "Enter Y-MIN of the track: ",
			 (char *)NULL);
	edit_result = TCL_ERROR;
	goto end;
    }
    tr[2] = tr[0] = atof( argv[arg] ) * local2base;
    ++arg;

    if ( argc < arg+1 ) {
	Tcl_AppendResult(interp, MORE_ARGS_STR, "Enter Y-MAX of the track: ",
			 (char *)NULL);
	edit_result = TCL_ERROR;
	goto end;
    }
    tr[1] = atof( argv[arg] ) * local2base;
    ++arg;
    if ( tr[0] == tr[1] ) {
	Tcl_AppendResult(interp, "MIN == MAX ... STOP\n", (char *)NULL);
	edit_result = TCL_ERROR;
	goto end;
    }
    if ( tr[0] > tr[1] ) {
	Tcl_AppendResult(interp, "MIN > MAX .... will switch\n", (char *)NULL);
	tr[1] = tr[0];
	tr[0] = tr[2];
    }

    if ( argc < arg+1 ) {
	Tcl_AppendResult(interp, MORE_ARGS_STR, "Enter track thickness: ",
			 (char *)NULL);
	edit_result = TCL_ERROR;
	goto end;
    }
    tr[2] = atof( argv[arg] ) * local2base;
    ++arg;
    if ( tr[2] <= 0 ) {
	Tcl_AppendResult(interp, "Track thickness <= 0 - STOP\n", (char *)NULL);
	edit_result = TCL_ERROR;
	goto end;
    }

    solname[0] = regname[0] = grpname[0] = 't';
    solname[1] = regname[1] = grpname[1] = 'r';
    solname[2] = regname[2] = grpname[2] = 'a';
    solname[3] = regname[3] = grpname[3] = 'c';
    solname[4] = regname[4] = grpname[4] = 'k';
    solname[5] = regname[5] = '.';
    solname[6] = 's';
    regname[6] = 'r';
    solname[7] = regname[7] = '.';
    grpname[5] = solname[8] = regname[8] = '\0';
    grpname[8] = solname[11] = regname[11] = '\0';
/*
  bu_log("\nX of first road wheel  %10.4f\n", fw[0]);
  bu_log("X of last road wheel   %10.4f\n", lw[0]);
  bu_log("Z of road wheels       %10.4f\n", fw[1]);
  bu_log("radius of road wheels  %10.4f\n", fw[2]);
  bu_log("\nX of drive wheel       %10.4f\n", dw[0]);
  bu_log("Z of drive wheel       %10.4f\n", dw[1]);
  bu_log("radius of drive wheel  %10.4f\n", dw[2]);
  bu_log("\nX of idler wheel       %10.4f\n", iw[0]);
  bu_log("Z of idler wheel       %10.4f\n", iw[1]);
  bu_log("radius of idler wheel  %10.4f\n", iw[2]);
  bu_log("\nY MIN of track         %10.4f\n", tr[0]);
  bu_log("Y MAX of track         %10.4f\n", tr[1]);
  bu_log("thickness of track     %10.4f\n", tr[2]);
*/

/* Check for names to use:
 *	1.  start with track.s.1->10 and track.r.1->10
 *	2.  if bad, increment count by 10 and try again
 */

 tryagain:	/* sent here to try next set of names */

    for (i=0; i<11; i++) {
	crname(solname, i, sizeof(solname));
	crname(regname, i, sizeof(regname));
	if (	(db_lookup( dbip, solname, LOOKUP_QUIET) != DIR_NULL)	||
		(db_lookup( dbip, regname, LOOKUP_QUIET) != DIR_NULL)	) {
	    /* name already exists */
	    solname[8] = regname[8] = '\0';
	    if ( (Trackpos += 10) > 500 ) {
		Tcl_AppendResult(interp, "Track: naming error -- STOP\n",
				 (char *)NULL);
		edit_result = TCL_ERROR;
		goto end;
	    }
	    goto tryagain;
	}
	solname[8] = regname[8] = '\0';
    }

    /* no interupts */
    (void)signal( SIGINT, SIG_IGN );

    /* find the front track slope to the idler */
    for (i=0; i<24; i++)
	sol.s_values[i] = 0.0;

    slope(fw, iw, tr);
    VMOVE(temp2, &sol.s_values[0]);
    crname(solname, 1, sizeof(solname));
    bu_strlcpy(sol.s_name, solname, NAMESIZE+1);
    sol.s_type = ID_ARB8;
    if ( wrobj(solname, DIR_SOLID) )
	return TCL_ERROR;

    solname[8] = '\0';

    /* find track around idler */
    for (i=0; i<24; i++)
	sol.s_values[i] = 0.0;
    sol.s_type = ID_TGC;
    trcurve(iw, tr);
    crname(solname, 2, sizeof(solname));
    bu_strlcpy(sol.s_name, solname, NAMESIZE+1);
    if ( wrobj( solname, DIR_SOLID ) )
	return TCL_ERROR;
    solname[8] = '\0';
    /* idler dummy rcc */
    sol.s_values[6] = iw[2];
    sol.s_values[11] = iw[2];
    VMOVE(&sol.s_values[12], &sol.s_values[6]);
    VMOVE(&sol.s_values[15], &sol.s_values[9]);
    crname(solname, 3, sizeof(solname));
    bu_strlcpy(sol.s_name, solname, NAMESIZE+1);
    if ( wrobj( solname, DIR_SOLID ) )
	return TCL_ERROR;
    solname[8] = '\0';

    /* find idler track dummy arb8 */
    for (i=0; i<24; i++)
	sol.s_values[i] = 0.0;
    crname(solname, 4, sizeof(solname));
    bu_strlcpy(sol.s_name, solname, NAMESIZE+1);
    sol.s_type = ID_ARB8;
    crdummy(iw, tr, 1);
    if ( wrobj(solname, DIR_SOLID) )
	return TCL_ERROR;
    solname[8] = '\0';

    /* track slope to drive */
    for (i=0; i<24; i++)
	sol.s_values[i] = 0.0;
    slope(lw, dw, tr);
    VMOVE(temp1, &sol.s_values[0]);
    crname(solname, 5, sizeof(solname));
    bu_strlcpy(sol.s_name, solname, NAMESIZE+1);
    if (wrobj(solname, DIR_SOLID))
	return TCL_ERROR;
    solname[8] = '\0';

    /* track around drive */
    for (i=0; i<24; i++)
	sol.s_values[i] = 0.0;
    sol.s_type = ID_TGC;
    trcurve(dw, tr);
    crname(solname, 6, sizeof(solname));
    bu_strlcpy(sol.s_name, solname, NAMESIZE+1);
    if ( wrobj(solname, DIR_SOLID) )
	return TCL_ERROR;
    solname[8] = '\0';

    /* drive dummy rcc */
    sol.s_values[6] = dw[2];
    sol.s_values[11] = dw[2];
    VMOVE(&sol.s_values[12], &sol.s_values[6]);
    VMOVE(&sol.s_values[15], &sol.s_values[9]);
    crname(solname, 7, sizeof(solname));
    bu_strlcpy(sol.s_name, solname, NAMESIZE+1);
    if ( wrobj(solname, DIR_SOLID) )
	return TCL_ERROR;
    solname[8] = '\0';

    /* drive dummy arb8 */
    for (i=0; i<24; i++)
	sol.s_name[i] = 0.0;
    crname(solname, 8, sizeof(solname));
    bu_strlcpy(sol.s_name, solname, NAMESIZE+1);
    sol.s_type = ID_ARB8;
    crdummy(dw, tr, 2);
    if ( wrobj(solname, DIR_SOLID) )
	return TCL_ERROR;
    solname[8] = '\0';

    /* track bottom */
    temp1[1] = temp2[1] = tr[0];
    bottom(temp1, temp2, tr);
    crname(solname, 9, sizeof(solname));
    bu_strlcpy(sol.s_name, solname, NAMESIZE+1);
    if ( wrobj(solname, DIR_SOLID) )
	return TCL_ERROR;
    solname[8] = '\0';

    /* track top */
    temp1[0] = dw[0];
    temp1[1] = temp2[1] = tr[0];
    temp1[2] = dw[1] + dw[2];
    temp2[0] = iw[0];
    temp2[2] = iw[1] + iw[2];
    top(temp1, temp2, tr);
    crname(solname, 10, sizeof(solname));
    bu_strlcpy(sol.s_name, solname, NAMESIZE+1);
    if ( wrobj(solname, DIR_SOLID) )
	return TCL_ERROR;
    solname[8] = '\0';

    /* add the regions */
    item = item_default;
    mat = mat_default;
    los = los_default;
    item_default = 500;
    mat_default = 1;
    los_default = 50;
    /* region 1 */
    memb[0] = 1;
    memb[1] = 4;
    crname(regname, 1, sizeof(regname));
    crregion(regname, oper, memb, 2, solname, sizeof(regname));
    solname[8] = regname[8] = '\0';

    /* region 2 */
    crname(regname, 2, sizeof(regname));
    memb[0] = 2;
    memb[1] = 3;
    memb[2] = 4;
    crregion(regname, oper, memb, 3, solname, sizeof(regname));
    solname[8] = regname[8] = '\0';

    /* region 5 */
    crname(regname, 5, sizeof(regname));
    memb[0] = 5;
    memb[1] = 8;
    crregion(regname, oper, memb, 2, solname, sizeof(regname));
    solname[8] = regname[8] = '\0';

    /* region 6 */
    crname(regname, 6, sizeof(regname));
    memb[0] = 6;
    memb[1] = 7;
    memb[2] = 8;
    crregion(regname, oper, memb, 3, solname, sizeof(regname));
    solname[8] = regname[8] = '\0';

    /* region 9 */
    crname(regname, 9, sizeof(regname));
    memb[0] = 9;
    memb[1] = 1;
    memb[2] = 5;
    oper[2] = WMOP_SUBTRACT;
    crregion(regname, oper, memb, 3, solname, sizeof(regname));
    solname[8] = regname[8] = '\0';

    /* region 10 */
    crname(regname, 10, sizeof(regname));
    memb[0] = 10;
    memb[1] = 4;
    memb[2] = 8;
    crregion(regname, oper, memb, 3, solname, sizeof(regname));
    solname[8] = regname[8] = '\0';

    /* group all the track regions */
    j = 1;
    if ( (i = Trackpos / 10 + 1) > 9 )
	j = 2;
    itoa(i, temp, j);
    bu_strlcat(grpname, temp, sizeof(grpname));
    for (i=1; i<11; i++) {
	if ( i == 3 || i ==4 || i == 7 || i == 8 )
	    continue;
	regname[8] = '\0';
	crname(regname, i, sizeof(regname));
	if ( db_lookup( dbip, regname, LOOKUP_QUIET) == DIR_NULL ) {
	    Tcl_AppendResult(interp, "group: ", grpname, " will skip member: ",
			     regname, "\n", (char *)NULL);
	    continue;
	}
	mk_addmember( regname, &head, NULL, WMOP_UNION );
    }

    /* Add them all at once */
    if ( mk_comb( wdbp, grpname, &head,
		  0, NULL, NULL, NULL,
		  0, 0, 0, 0,
		  0, 1, 1 ) < 0 )
    {
	Tcl_AppendResult(interp,
			 "An error has occured while adding '",
			 grpname, "' to the database.\n", (char *)NULL);
    }

    /* draw this track */
    Tcl_AppendResult(interp, "The track regions are in group ", grpname,
		     "\n", (char *)NULL);
    {
	const char *arglist[3];
	arglist[0] = "e";
	arglist[1] = grpname;
	arglist[2] = NULL;
	edit_result = cmd_draw( clientData, interp, 2, arglist );
    }

    Trackpos += 10;
    item_default = item;
    mat_default = mat;
    los_default = los;
    grpname[5] = solname[8] = regname[8] = '\0';

    return edit_result;
 end:
    (void)signal( SIGINT, SIG_IGN );
    return edit_result;
}