Example #1
0
/* A "wrapping" combination is a combination that contains a single object
 * and does not apply a matrix to it */
int
Comb_Is_Wrapper(struct directory *dp, struct rt_wdb *wdbp)
{
    struct rt_db_internal comb_intern;
    struct rt_db_internal comb_child_intern;
    struct rt_comb_internal *comb;
    union tree *child;
    struct directory *child_dp;
    int node_count = 0;

    rt_db_get_internal(&comb_intern, dp, wdbp->dbip, bn_mat_identity, &rt_uniresource);
    RT_CK_DB_INTERNAL(&comb_intern);
    if (comb_intern.idb_minor_type != DB5_MINORTYPE_BRLCAD_COMBINATION) {
	rt_db_free_internal(&comb_intern);
	return -1;
    }

    /* If this comb has more than one child, it isn't a wrapper */
    comb = (struct rt_comb_internal *)comb_intern.idb_ptr;
    if (comb->tree) {
	node_count = db_count_tree_nodes(comb->tree, 0);
	if (node_count > 1) {
	    rt_db_free_internal(&comb_intern);
	    return 1;
	}
    } else {
	/* Empty comb */
	return -2;
    }

    /* If the child doesn't exist, this isn't a wrapper */
    child = _db_tree_get_child(comb->tree);
    child_dp = db_lookup(wdbp->dbip, child->tr_l.tl_name, LOOKUP_QUIET);
    if (child_dp == RT_DIR_NULL) {
	rt_db_free_internal(&comb_intern);
	return 1;
    }

    /* If the child is a comb, this isn't a wrapper */
    rt_db_get_internal(&comb_child_intern, child_dp, wdbp->dbip, bn_mat_identity, &rt_uniresource);
    RT_CK_DB_INTERNAL(&comb_child_intern);
    if (comb_child_intern.idb_minor_type == DB5_MINORTYPE_BRLCAD_COMBINATION) {
	rt_db_free_internal(&comb_intern);
	rt_db_free_internal(&comb_child_intern);
	return 1;
    }

    /* If the child has a matrix over it, this isn't a wrapper */
    if (child->tr_l.tl_mat) {
	rt_db_free_internal(&comb_intern);
	rt_db_free_internal(&comb_child_intern);
	return 1;
    }

    /* If we made it here, we have a wrapper */
    rt_db_free_internal(&comb_intern);
    rt_db_free_internal(&comb_child_intern);
    return 0;
}
Example #2
0
void BRLFile::CsgLeaf(struct db_i *dbip, struct directory *dp, genptr_t ptr)
{
    BRLFile *that=(BRLFile*)ptr;

    if(that->verbose&BRL)
        std::cout << "Leaf " << dp->d_namep << '\n';

    struct rt_db_internal       ip;
    switch(rt_db_get_internal(&ip, dp, dbip, (fastf_t *)NULL, &rt_uniresource)){
    case ID_ARB8: {
        struct rt_arb_internal *arb=(struct rt_arb_internal *)ip.idb_ptr;
        if(that->verbose&BRL) {
            std::cout << "    ARB8\n";
            for(int i=0;i<8;i++) {
                std::cout << "    pt[" << i << "]=" << arb->pt[i] << '\n';
            } 
        }
        that->construction.push_front(BRLTopo(arb));
        } break;
    case ID_TGC: {
        struct rt_tgc_internal *tgc=(struct rt_tgc_internal *)ip.idb_ptr;
        if(that->verbose&BRL) {
            std::cout 
                << "    TGC\n"
                << "    v=" << tgc->v << '\n'
                << "    h=" << tgc->h << '\n'
                << "    a=" << tgc->a << '\n'
                << "    b=" << tgc->b << '\n'
                << "    c=" << tgc->c << '\n'
                << "    d=" << tgc->d << '\n';
        }
        that->construction.push_front(BRLTopo(tgc));
        } break;
    case ID_ELL: {
        struct rt_ell_internal *ell=(struct rt_ell_internal *)ip.idb_ptr;
        if(that->verbose&BRL) {
            std::cout << "    v=" << ell->v << '\n';
            std::cout << "    a=" << ell->a << '\n';
            std::cout << "    b=" << ell->b << '\n';
            std::cout << "    c=" << ell->c << '\n';
        }
        that->construction.push_front(BRLTopo(ell));
        } break;
    default:
        std::cout << "    Unhandled type " << 
            rt_db_get_internal(&ip, dp, dbip, (fastf_t *)NULL, &rt_uniresource) 
            << '\n';
    }
}
int
rt_db_lookup_internal (
    struct db_i *dbip,
    const char *obj_name,
    struct directory **dpp,
    struct rt_db_internal *ip,
    int noisy,
    struct resource *resp)
{
    struct directory *dp;

    if (obj_name == (char *) 0) {
	if (noisy == LOOKUP_NOISY)
	    bu_log("rt_db_lookup_internal() No object specified\n");
	return ID_NULL;
    }
    if ((dp = db_lookup(dbip, obj_name, noisy)) == RT_DIR_NULL)
	return ID_NULL;
    if (rt_db_get_internal(ip, dp, dbip, (matp_t) NULL, resp) < 0) {
	if (noisy == LOOKUP_NOISY)
	    bu_log("rt_db_lookup_internal() Failed to get internal form of object '%s'\n",
		   dp->d_namep);
	return ID_NULL;
    }

    *dpp = dp;
    return ip->idb_type;
}
Example #4
0
void
count_refs(struct db_i *dbip, struct directory *dp, void *UNUSED(ptr))
{
    struct rt_db_internal intern;
    struct rt_comb_internal *comb;
    int id;

    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 get internal form of %s\n", dp->d_namep);
	return;
    }

    comb = (struct rt_comb_internal *)intern.idb_ptr;
    RT_CK_COMB(comb);

    if (!comb->tree) {
	bu_log("Warning: empty combination (%s)\n", dp->d_namep);
	dp->d_uses = 0;
	return;
    }

    comb_form = 0;

    db_tree_funcleaf(dbip, comb, comb->tree, incr_refs,
		     (void *)NULL, (void *)NULL, (void *)NULL, (void *)NULL);

}
Example #5
0
void
csg_leaf_func(struct db_i *dbip, struct directory *dp, void *UNUSED(ptr))
{
    struct rt_db_internal ip;

    /* if this solid has already been output, don't do it again */
    if (dp->d_uses < 0)
	return;

    if (verbose)
	bu_log("solid - %s\n", dp->d_namep);

    if (rt_db_get_internal(&ip, dp, dbip, (fastf_t *)NULL, &rt_uniresource) < 0)
	bu_log("Error in import");

    solid_is_brep = 0;
    dp->d_uses = (-iges_write[ip.idb_type].do_iges_write(&ip, dp->d_namep, fp_dir, fp_param));

    if (!dp->d_uses) {
	bu_log("g-iges: failed to translate %s to IGES format\n", dp->d_namep);
	solid_error++;
    }

    if (solid_is_brep)
	dp->d_nref = 1;
    else
	dp->d_nref = 0;

    rt_db_free_internal(&ip);
}
/* return 0 when IS a light or an error occurred. regions are skipped
 * when this function returns 0.
 */
static int
select_non_lights(struct db_tree_state *UNUSED(tsp), const struct db_full_path *pathp, const struct rt_comb_internal *UNUSED(combp), void *UNUSED(client_data))
{
    struct directory *dp;
    struct rt_db_internal intern;
    struct rt_comb_internal *comb;
    int id;

    RT_CK_FULL_PATH(pathp);
    dp = DB_FULL_PATH_CUR_DIR(pathp);

    id = rt_db_get_internal(&intern, dp, dbip, (matp_t)NULL, &rt_uniresource);
    if (id < 0) {
	/* error occurred retrieving object */
	bu_log("Warning: Can not load internal form of %s\n", dp->d_namep);
	return 0;
    }

    if ((dp->d_flags & RT_DIR_COMB) && (id == ID_COMBINATION)) {
	comb = (struct rt_comb_internal *)intern.idb_ptr;
	RT_CK_COMB(comb);
	if (BU_STR_EQUAL(bu_vls_addr(&comb->shader), "light")) {
	    rt_db_free_internal(&intern);
	    return 0;
	}
    }

    return 1;
}
Example #7
0
static const char *
save_comb(struct ged *gedp, struct directory *dpold)
{
    /* Save a combination under a temporary name */

    struct directory *dp;
    struct rt_db_internal intern;

    /* Make a new name */
    const char *name = mktemp_comb(gedp, tmpcomb);

    if (rt_db_get_internal(&intern, dpold, gedp->ged_wdbp->dbip, (fastf_t *)NULL, &rt_uniresource) < 0) {
	bu_vls_printf(gedp->ged_result_str, "save_comb: Database read error, aborting\n");
	return NULL;
    }

    if ((dp = db_diradd(gedp->ged_wdbp->dbip, name, RT_DIR_PHONY_ADDR, 0, dpold->d_flags, (genptr_t)&intern.idb_type)) == RT_DIR_NULL) {
	bu_vls_printf(gedp->ged_result_str, "save_comb: Cannot save copy of %s, no changed made\n", dpold->d_namep);
	return NULL;
    }

    if (rt_db_put_internal(dp, gedp->ged_wdbp->dbip, &intern, &rt_uniresource) < 0) {
	bu_vls_printf(gedp->ged_result_str, "save_comb: Cannot save copy of %s, no changed made\n", dpold->d_namep);
	return NULL;
    }

    return name;
}
void mesh_tracker(struct db_i *dbip, struct directory *dp, void *UNUSED(ptr))
{
    struct rt_db_internal internal;

    /* leaf node must be a solid */
    if (!(dp->d_flags & RT_DIR_SOLID)) {
	fprintf(stderr, "warning: '%s' is not a solid! (not processed)\n", dp->d_namep);
	return;
    }

    /* solid must be a bot */
    if (rt_db_get_internal(&internal, dp, dbip, NULL, &rt_uniresource) != ID_BOT) {
	fprintf(stderr, "warning: '%s' is not a bot! (not processed)\n", dp->d_namep);
	return;
    }
    /* track bot */
    if (NULL == curr) {
	BU_ALLOC(head, struct mesh);
	head->name = dp->d_namep;
	head->bot = (struct rt_bot_internal *)internal.idb_ptr;
	head->next = NULL;
	curr = head;
    } else {
	BU_ALLOC(curr->next, struct mesh);
	curr = curr->next;
	curr->name = dp->d_namep;
	curr->bot = (struct rt_bot_internal *)internal.idb_ptr;
	curr->next = NULL;
    }
    /* accumulate counts */
    total_vertex_count += (uint32_t)curr->bot->num_vertices;
    total_face_count += (uint32_t)curr->bot->num_faces;
    mesh_count++;
}
Example #9
0
/*
 * Supports for the 'keep' method.
 * Write each node encountered exactly once.
 */
HIDDEN void
node_write(struct db_i *dbip, struct directory *dp, void *ptr)
{
    struct keep_node_data *kndp = (struct keep_node_data *)ptr;
    struct rt_db_internal intern;

    RT_CK_WDB(kndp->wdbp);

    if (dp->d_nref++ > 0)
	return;		/* already written */

    if (rt_db_get_internal(&intern, dp, dbip, NULL, &rt_uniresource) < 0) {
	bu_vls_printf(kndp->gedp->ged_result_str, "Database read error, aborting\n");
	return;
    }

    if (dp->d_major_type == DB5_MAJORTYPE_BRLCAD && dp->d_minor_type == DB5_MINORTYPE_BRLCAD_EXTRUDE) {
	/* if this is an extrusion, keep the referenced sketch */
	struct rt_extrude_internal *extr;
	struct directory *dp2;

	extr = (struct rt_extrude_internal *)intern.idb_ptr;
	RT_EXTRUDE_CK_MAGIC(extr);

	if ((dp2 = db_lookup(dbip, extr->sketch_name, LOOKUP_QUIET)) != RT_DIR_NULL) {
	    node_write(dbip, dp2, ptr);
	}
    } else if (dp->d_major_type == DB5_MAJORTYPE_BRLCAD && dp->d_minor_type == DB5_MINORTYPE_BRLCAD_REVOLVE) {
	/* if this is a revolve, keep the referenced sketch */
	struct rt_revolve_internal *rev;
	struct directory *dp2;

	rev = (struct rt_revolve_internal *)intern.idb_ptr;
	RT_REVOLVE_CK_MAGIC(rev);

	if ((dp2 = db_lookup(dbip, bu_vls_addr(&rev->sketch_name), LOOKUP_QUIET)) != RT_DIR_NULL) {
	    node_write(dbip, dp2, ptr);
	}
    } else if (dp->d_major_type == DB5_MAJORTYPE_BRLCAD && dp->d_minor_type == DB5_MINORTYPE_BRLCAD_DSP) {
	/* if this is a DSP, keep the referenced binary object too */
	struct rt_dsp_internal *dsp;
	struct directory *dp2;

	dsp = (struct rt_dsp_internal *)intern.idb_ptr;
	RT_DSP_CK_MAGIC(dsp);

	if (dsp->dsp_datasrc == RT_DSP_SRC_OBJ) {
	    /* need to keep this object */
	    if ((dp2 = db_lookup(dbip, bu_vls_addr(&dsp->dsp_name),  LOOKUP_QUIET)) != RT_DIR_NULL) {
		node_write(dbip, dp2, ptr);
	    }
	}
    }

    if (wdb_put_internal(kndp->wdbp, dp->d_namep, &intern, 1.0) < 0) {
	bu_vls_printf(kndp->gedp->ged_result_str, "Database write error, aborting\n");
	return;
    }
}
Example #10
0
/**
 * Creates one metaball object that includes all points from an
 * existing list (in 'av') of named metaballs.  This routine creates
 * an rt_metaball_internal object directly via LIBRT given it requires
 * reading existing metaballs from the database.
 */
static void
mix_balls(struct db_i *dbip, const char *name, int ac, const char *av[])
{
    int i;
    struct directory *dp;
    struct rt_metaball_internal *newmp;

    RT_CK_DBI(dbip);

    /* allocate a struct rt_metaball_internal object that we'll
     * manually fill in with points from the other metaballs being
     * joined together.
     */
    BU_ALLOC(newmp, struct rt_metaball_internal);
    newmp->magic = RT_METABALL_INTERNAL_MAGIC;
    newmp->threshold = 1.0;
    newmp->method = 1;
    BU_LIST_INIT(&newmp->metaball_ctrl_head);

    bu_log("Combining together the following metaballs:\n");

    for (i = 0; i < ac; i++) {
	struct rt_db_internal dir;
	struct rt_metaball_internal *mp;
	struct wdb_metaballpt *mpt;

	/* get a handle on the existing database object */
	bu_log("\t%s\n", av[i]);
	dp = db_lookup(dbip, av[i], 1);
	if (!dp) {
	    bu_log("Unable to find %s\n", av[i]);
	    continue;
	}

	/* load the existing database object */
	if (rt_db_get_internal(&dir, dp, dbip, NULL, &rt_uniresource) < 0) {
	    bu_log("Unable to load %s\n", av[i]);
	    continue;
	}

	/* access the metaball-specific internal structure */
	mp = (struct rt_metaball_internal *)dir.idb_ptr;
	RT_METABALL_CK_MAGIC(mp);

	/* iterate over each point in that database object and add it
	 * to our new metaball.
	 */
	for (BU_LIST_FOR(mpt, wdb_metaballpt, &mp->metaball_ctrl_head)) {
	    bu_log("Adding point (%lf %lf %lf)\n", V3ARGS(mpt->coord));
	    rt_metaball_add_point(newmp, (const point_t *)&mpt->coord, mpt->fldstr, mpt->sweat);
	}
    }

    bu_log("Joining balls together and creating [%s] object\n", name);

    /* write out new "mega metaball" out to disk */
    dbip->dbi_wdbp = wdb_dbopen(dbip, RT_WDB_TYPE_DB_DISK);
    wdb_export(dbip->dbi_wdbp, name, newmp, ID_METABALL, 1.0);
}
Example #11
0
HIDDEN int
printcodes(FILE *fp, struct directory *dp, int pathpos)
{
    int i;
    struct rt_db_internal intern;
    struct rt_comb_internal *comb;
    int id;

    CHECK_DBI_NULL;

    if (pathpos >= MAX_LEVELS) {
	regflag = ABORTED;
	return TCL_ERROR;
    }

    if (!(dp->d_flags & RT_DIR_COMB))
	return 0;

    if ((id=rt_db_get_internal(&intern, dp, dbip, (matp_t)NULL, &rt_uniresource)) < 0) {
	Tcl_AppendResult(INTERP, "printcodes: Cannot get records for ",
			 dp->d_namep, "\n", (char *)NULL);
	return TCL_ERROR;
    }

    if (id != ID_COMBINATION)
	return TCL_OK;

    comb = (struct rt_comb_internal *)intern.idb_ptr;
    RT_CK_COMB(comb);

    if (comb->region_flag) {
	fprintf(fp, "%-6ld %-3ld %-3ld %-4ld  ",
		comb->region_id,
		comb->aircode,
		comb->GIFTmater,
		comb->los);
	for (i=0; i < pathpos; i++)
	    fprintf(fp, "/%s", path[i]->d_namep);
	fprintf(fp, "/%s\n", dp->d_namep);
	intern.idb_meth->ft_ifree(&intern);
	return TCL_OK;
    }

    if (comb->tree) {
	path[pathpos] = dp;
	db_tree_funcleaf(dbip, comb, comb->tree, Do_printnode,
			 (void *)fp, (void *)&pathpos, (void *)NULL, (void *)NULL);
    }

    intern.idb_meth->ft_ifree(&intern);
    return TCL_OK;
}
HIDDEN int
wcodes_printcodes(struct ged *gedp, FILE *fp, struct directory *dp, size_t pathpos)
{
    size_t i;
    struct rt_db_internal intern;
    struct rt_comb_internal *comb;
    int id;

    if (!(dp->d_flags & RT_DIR_COMB))
	return GED_OK;

    if ((id=rt_db_get_internal(&intern, dp, gedp->ged_wdbp->dbip, (matp_t)NULL, &rt_uniresource)) < 0) {
	bu_vls_printf(gedp->ged_result_str, "Cannot get records for %s\n", dp->d_namep);
	return GED_ERROR;
    }

    if (id != ID_COMBINATION) {
	intern.idb_meth->ft_ifree(&intern);
	return GED_OK;
    }

    comb = (struct rt_comb_internal *)intern.idb_ptr;
    RT_CK_COMB(comb);

    if (comb->region_flag) {
	fprintf(fp, "%-6ld %-3ld %-3ld %-4ld  ",
		comb->region_id,
		comb->aircode,
		comb->GIFTmater,
		comb->los);
	for (i =0 ; i < pathpos; i++)
	    fprintf(fp, "/%s", path[i]->d_namep);
	fprintf(fp, "/%s\n", dp->d_namep);
	intern.idb_meth->ft_ifree(&intern);
	return GED_OK;
    }

    if (comb->tree) {
	if (pathpos >= path_capacity) {
	    path_capacity += PATH_STEP;
	    path = (struct directory **)bu_realloc(path, sizeof(struct directory *) * path_capacity, "realloc path bigger");
	}
	path[pathpos] = dp;
	db_tree_funcleaf(gedp->ged_wdbp->dbip, comb, comb->tree, wcodes_printnode,
			 (void *)fp, (void *)&pathpos, (void *)gedp, (void *)gedp);
    }

    intern.idb_meth->ft_ifree(&intern);
    return GED_OK;
}
Example #13
0
int
main(int argc, char** argv)
{
    struct rt_wdb* outfp;
    ON_Brep* brep;
    ON_TextLog error_log;
    const char* id_name = "B-Rep Example";
    const char* geom_name = "cube.s";

    ON::Begin();

    if (argc > 1) {
	printf("Writing a twisted cube b-rep...\n");
	outfp = wdb_fopen("brep_cube1.g");
	mk_id(outfp, id_name);
	brep = MakeTwistedCube(error_log);
	mk_brep(outfp, geom_name, brep);

	//mk_comb1(outfp, "cube.r", geom_name, 1);
	unsigned char rgb[] = {255,255,255};
	mk_region1(outfp, "cube.r", geom_name, "plastic", "", rgb);

	wdb_close(outfp);
	delete brep;
    }

    printf("Reading a twisted cube b-rep...\n");
    struct db_i* dbip = db_open("brep_cube1.g", "r");
    db_dirbuild(dbip);
    struct directory* dirp;
    if ((dirp = db_lookup(dbip, "cube.s", 0)) != DIR_NULL) {
	printf("\tfound cube.s\n");
	struct rt_db_internal ip;
	mat_t mat;
	MAT_IDN(mat);
	if (rt_db_get_internal(&ip, dirp, dbip, mat, &rt_uniresource) >= 0) {
	    printPoints((struct rt_brep_internal*)ip.idb_ptr);
	} else {
	    fprintf(stderr, "problem getting internal object rep\n");
	}
    }
    db_close(dbip);

    ON::End();

    return 0;
}
Example #14
0
int
ged_whatid(struct ged *gedp, int argc, const char *argv[])
{
    struct directory *dp;
    struct rt_db_internal intern;
    struct rt_comb_internal *comb;
    static const char *usage = "region";

    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 != 2) {
	bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage);
	return GED_ERROR;
    }


    if ((dp=db_lookup(gedp->ged_wdbp->dbip, argv[1], LOOKUP_NOISY)) == RT_DIR_NULL)
	return GED_ERROR;

    if (!(dp->d_flags & RT_DIR_REGION)) {
	bu_vls_printf(gedp->ged_result_str, "%s is not a region", argv[1]);
	return GED_ERROR;
    }

    if (rt_db_get_internal(&intern, dp, gedp->ged_wdbp->dbip, (fastf_t *)NULL, &rt_uniresource) < 0)
	return GED_ERROR;
    comb = (struct rt_comb_internal *)intern.idb_ptr;

    bu_vls_printf(gedp->ged_result_str, "%ld", comb->region_id);
    rt_db_free_internal(&intern);

    return GED_OK;
}
static int
select_lights(struct db_tree_state *UNUSED(tsp), const struct db_full_path *pathp, const struct rt_comb_internal *UNUSED(combp), void *UNUSED(client_data))
{
    struct directory *dp;
    struct rt_db_internal intern;
    struct rt_comb_internal *comb;
    int id;

    RT_CK_FULL_PATH( pathp );
    dp = DB_FULL_PATH_CUR_DIR( pathp );

    if ( !(dp->d_flags & RT_DIR_COMB) )
	return -1;

    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 -1;
    }

    if ( id != ID_COMBINATION )
    {
	bu_log( "Directory/database mismatch!\n\t is '%s' a combination or not?\n",
		dp->d_namep );
	return -1;
    }

    comb = (struct rt_comb_internal *)intern.idb_ptr;
    RT_CK_COMB( comb );

    if ( BU_STR_EQUAL( bu_vls_addr( &comb->shader ), "light" ) )
    {
	rt_db_free_internal(&intern);
	return 0;
    }
    else
    {
	rt_db_free_internal(&intern);
	return -1;
    }
}
HIDDEN int
edcodes_collect_regnames(struct ged *gedp, struct directory *dp, int pathpos)
{
    int id;
    int status = 0;
    struct rt_db_internal intern;
    struct rt_comb_internal *comb;

    if (!(dp->d_flags & RT_DIR_COMB))
	return EDCODES_OK;

    if ((id=rt_db_get_internal(&intern, dp, gedp->ged_wdbp->dbip,
			       (matp_t)NULL, &rt_uniresource)) < 0) {
	bu_vls_printf(gedp->ged_result_str,
		      "Cannot get records for %s\n", dp->d_namep);
	return EDCODES_NOTOK;
    }

    if (id != ID_COMBINATION) {
	intern.idb_meth->ft_ifree(&intern);
	return EDCODES_OK;
    }

    comb = (struct rt_comb_internal *)intern.idb_ptr;
    RT_CK_COMB(comb);

    if (comb->region_flag) {
	bu_vls_printf(gedp->ged_result_str, " %s", dp->d_namep);
	intern.idb_meth->ft_ifree(&intern);
	return EDCODES_OK;
    }

    if (comb->tree) {
	db_tree_funcleaf(gedp->ged_wdbp->dbip, comb, comb->tree, edcodes_traverse_node, (void *)&pathpos, (void *)gedp, (void *)&status, (void *)NULL);
    }

    intern.idb_meth->ft_ifree(&intern);

    if (status == EDCODES_HALT)
	return EDCODES_HALT;
    return EDCODES_OK;
}
Example #17
0
static int
list_children(struct ged *gedp, struct directory *dp)
{
    size_t i;
    struct rt_db_internal intern;
    struct rt_comb_internal *comb;

    if (!(dp->d_flags & RT_DIR_COMB))
	return GED_OK;

    if (rt_db_get_internal(&intern, dp, gedp->ged_wdbp->dbip, (fastf_t *)NULL, &rt_uniresource) < 0) {
	bu_vls_printf(gedp->ged_result_str, "Database read error, aborting");
	return GED_ERROR;
    }
    comb = (struct rt_comb_internal *)intern.idb_ptr;

    if (comb->tree) {
	struct bu_vls vls = BU_VLS_INIT_ZERO;
	size_t node_count;
	size_t actual_count;
	struct rt_tree_array *rt_tree_array;

	if (db_ck_v4gift_tree(comb->tree) < 0) {
	    db_non_union_push(comb->tree, &rt_uniresource);
	    if (db_ck_v4gift_tree(comb->tree) < 0) {
		bu_vls_printf(gedp->ged_result_str, "Cannot flatten tree for listing");
		return GED_ERROR;
	    }
	}
	node_count = db_tree_nleaves(comb->tree);
	if (node_count > 0) {
	    rt_tree_array = (struct rt_tree_array *)bu_calloc(node_count,
							      sizeof(struct rt_tree_array), "tree list");
	    actual_count = (struct rt_tree_array *)db_flatten_tree(
		rt_tree_array, comb->tree, OP_UNION,
		1, &rt_uniresource) - rt_tree_array;
	    BU_ASSERT_SIZE_T(actual_count, ==, node_count);
	    comb->tree = TREE_NULL;
	} else {
void smoothBot
(
    rt_wdb* wdbp,
    char*   name
) {
    directory* dp = db_lookup(wdbp->dbip, name, LOOKUP_QUIET);

    if (dp != RT_DIR_NULL) {
	rt_db_internal intern;

	if (rt_db_get_internal(&intern, dp, wdbp->dbip, 0, &rt_uniresource) == ID_BOT) {
	    rt_bot_internal* bot = static_cast<rt_bot_internal*>(intern.idb_ptr);

	    rt_bot_smooth(bot, name, wdbp->dbip, M_PI_4);

	    if (rt_db_put_internal(dp, wdbp->dbip, &intern, &rt_uniresource) < 0) {
		bu_bomb("Database write failure in smoothBot\n");
	    }
	}

	rt_db_free_internal(&intern);
    }
}
Example #19
0
/* Convenience function to get a comb child's directory pointer
 * when it the comb only has one child */
struct directory *
Comb_Get_Only_Child(struct directory *dp, struct rt_wdb *wdbp)
{
    struct rt_db_internal comb_intern;
    struct rt_comb_internal *comb;
    union tree *child;
    struct directory *child_dp;
    int node_count = 0;

    rt_db_get_internal(&comb_intern, dp, wdbp->dbip, bn_mat_identity, &rt_uniresource);
    RT_CK_DB_INTERNAL(&comb_intern);
    if (comb_intern.idb_minor_type != DB5_MINORTYPE_BRLCAD_COMBINATION) {
	rt_db_free_internal(&comb_intern);
	return RT_DIR_NULL;
    }

    /* If this comb has more than one child, there exists no "only" child */
    comb = (struct rt_comb_internal *)comb_intern.idb_ptr;
    if (comb->tree) {
	node_count = db_count_tree_nodes(comb->tree, 0);
	if (node_count > 1) {
	    rt_db_free_internal(&comb_intern);
	    return RT_DIR_NULL;
	}
    } else {
	/* Empty comb - there exists no "only" child */
	return RT_DIR_NULL;
    }

    /* If the child doesn't exist, there exists no "only" child, so at
     * this point whatever db_lookup returns is fine */
    child = _db_tree_get_child(comb->tree);
    child_dp = db_lookup(wdbp->dbip, child->tr_l.tl_name, LOOKUP_QUIET);
    rt_db_free_internal(&comb_intern);
    return child_dp;
}
Example #20
0
void BRLFile::CsgCombine(struct db_i *dbip, struct directory *dp, genptr_t ptr)
{
    BRLFile *that=(BRLFile*)ptr;

    struct rt_db_internal       ip;
    if(rt_db_get_internal(&ip, dp, dbip, NULL, &rt_uniresource)!=ID_COMBINATION
    ) {
        std::cerr << "Combination is not a combination in " 
            << __FUNCTION__ << '\n';
        exit(1);
    }

    struct rt_comb_internal *comb = (struct rt_comb_internal *)ip.idb_ptr;

    if(that->verbose&BRL) {
        std::cout << "Combine " << dp->d_namep << '\n';

        std::cout << *comb;
        std::cout << "    --------------------\n";
        std::cout << "    " << comb->tree << '\n';
    }

    that->construction.push_back(that->PerformBoolean(comb->tree));
}
int
ged_bo(struct ged *gedp, int argc, const char *argv[])
{
    int c;
    unsigned int minor_type=0;
    char *obj_name;
    char *file_name;
    int input_mode=0;
    int output_mode=0;
    struct rt_binunif_internal *bip;
    struct rt_db_internal intern;
    struct directory *dp;
    const char *argv0;
    static const char *usage = "{-i major_type minor_type | -o} dest source";

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

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

    argv0 = argv[0];

    /* must be wanting help */
    if (argc == 1) {
	bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv0, usage);
	return GED_HELP;
    }

    /* check that we are using a version 5 database */
    if (db_version(gedp->ged_wdbp->dbip) < 5) {
	bu_vls_printf(gedp->ged_result_str, "This is an older database version.\nIt does not support binary objects.Use \"dbupgrade\" to upgrade this database to the current version.\n");
	return GED_ERROR;
    }

    bu_optind = 1;		/* re-init bu_getopt() */
    bu_opterr = 0;          /* suppress bu_getopt()'s error message */
    while ((c=bu_getopt(argc, (char * const *)argv, "iou:")) != -1) {
	switch (c) {
	    case 'i':
		input_mode = 1;
		break;
	    case 'o':
		output_mode = 1;
		break;
	    default:
		bu_vls_printf(gedp->ged_result_str, "Unrecognized option - %c", c);
		return GED_ERROR;

	}
    }

    if (input_mode + output_mode != 1) {
	bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv0, usage);
	return GED_ERROR;
    }

    argc -= bu_optind;
    argv += bu_optind;

    if ((input_mode && argc != 4) || (output_mode && argc != 2)) {
	bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv0, usage);
	return GED_ERROR;
    }


    if (input_mode) {
	if (argv[0][0] == 'u') {

	    if (argv[1][1] != '\0') {
		bu_vls_printf(gedp->ged_result_str, "Unrecognized minor type: %s", argv[1]);
		return GED_ERROR;
	    }

	    switch ((int)argv[1][0]) {
		case 'f':
		    minor_type = DB5_MINORTYPE_BINU_FLOAT;
		    break;
		case 'd':
		    minor_type = DB5_MINORTYPE_BINU_DOUBLE;
		    break;
		case 'c':
		    minor_type = DB5_MINORTYPE_BINU_8BITINT;
		    break;
		case 's':
		    minor_type = DB5_MINORTYPE_BINU_16BITINT;
		    break;
		case 'i':
		    minor_type = DB5_MINORTYPE_BINU_32BITINT;
		    break;
		case 'l':
		    minor_type = DB5_MINORTYPE_BINU_64BITINT;
		    break;
		case 'C':
		    minor_type = DB5_MINORTYPE_BINU_8BITINT_U;
		    break;
		case 'S':
		    minor_type = DB5_MINORTYPE_BINU_16BITINT_U;
		    break;
		case 'I':
		    minor_type = DB5_MINORTYPE_BINU_32BITINT_U;
		    break;
		case 'L':
		    minor_type = DB5_MINORTYPE_BINU_64BITINT_U;
		    break;
		default:
		    bu_vls_printf(gedp->ged_result_str, "Unrecognized minor type: %s", argv[1]);
		    return GED_ERROR;
	    }
	} else {
	    bu_vls_printf(gedp->ged_result_str, "Unrecognized major type: %s", argv[0]);
	    return GED_ERROR;
	}

	/* skip past major_type and minor_type */
	argc -= 2;
	argv += 2;

	if (minor_type == 0) {
	    bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv0, usage);
	    return GED_ERROR;
	}

	obj_name = (char *)*argv;
	GED_CHECK_EXISTS(gedp, obj_name, LOOKUP_QUIET, GED_ERROR);

	argc--;
	argv++;

	file_name = (char *)*argv;

	/* make a binunif of the entire file */
	if (rt_mk_binunif (gedp->ged_wdbp, obj_name, file_name, minor_type, 0)) {
	    bu_vls_printf(gedp->ged_result_str, "Error creating %s", obj_name);
	    return GED_ERROR;
	}

    } else if (output_mode) {
	FILE *fp;

	file_name = (char *)*argv;

	argc--;
	argv++;

	obj_name = (char *)*argv;

	if ((dp=db_lookup(gedp->ged_wdbp->dbip, obj_name, LOOKUP_NOISY)) == RT_DIR_NULL) {
	    return GED_ERROR;
	}
	if (!(dp->d_major_type & DB5_MAJORTYPE_BINARY_MASK)) {
	    bu_vls_printf(gedp->ged_result_str, "%s is not a binary object", obj_name);
	    return GED_ERROR;
	}

	if (dp->d_major_type != DB5_MAJORTYPE_BINARY_UNIF) {
	    bu_vls_printf(gedp->ged_result_str, "source must be a uniform binary object");
	    return GED_ERROR;
	}

	fp = fopen(file_name, "w+b");
	if (fp == NULL) {
	    bu_vls_printf(gedp->ged_result_str, "Error: cannot open file %s for writing", file_name);
	    return GED_ERROR;
	}

	if (rt_db_get_internal(&intern, dp, gedp->ged_wdbp->dbip, NULL,
			       &rt_uniresource) < 0) {
	    bu_vls_printf(gedp->ged_result_str, "Error reading %s from database", dp->d_namep);
	    fclose(fp);
	    return GED_ERROR;
	}

	RT_CK_DB_INTERNAL(&intern);

	bip = (struct rt_binunif_internal *)intern.idb_ptr;
	if (bip->count < 1) {
	    bu_vls_printf(gedp->ged_result_str, "%s has no contents", obj_name);
	    fclose(fp);
	    rt_db_free_internal(&intern);
	    return GED_ERROR;
	}

	if (fwrite(bip->u.int8, bip->count * db5_type_sizeof_h_binu(bip->type),
		   1, fp) != 1) {
	    bu_vls_printf(gedp->ged_result_str, "Error writing contents to file");
	    fclose(fp);
	    rt_db_free_internal(&intern);
	    return GED_ERROR;
	}

	fclose(fp);
	rt_db_free_internal(&intern);

    } else {
	bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv0, usage);
	return GED_ERROR;
    }

    return GED_OK;
}
Example #22
0
void
verify_region_attrs(struct directory *dp, struct db_i *dbip, Tcl_Obj *obj)
{
    Tcl_Obj **objs;
    int len = 0;
    int i;
    struct rt_db_internal intern;
    struct rt_comb_internal *comb;

    if (rt_db_get_internal(&intern, dp, dbip, NULL, &rt_uniresource) < 0) {
	fprintf(stderr, "Cannot import %s\n", dp->d_namep);
	bu_exit(1, NULL);
    }

    comb = (struct rt_comb_internal *)intern.idb_ptr;
    RT_CHECK_COMB(comb);

    if (Tcl_ListObjGetElements(INTERP, obj, &len, &objs) != TCL_OK) {
	fprintf(stderr, "Cannot get length of attributes for %s\n", dp->d_namep);
	bu_exit(1, NULL);
    }

    for (i=1; i<len; i += 2) {
	char *key, *value;

	key = Tcl_GetStringFromObj(objs[i-1], NULL);
	value = Tcl_GetStringFromObj(objs[i], NULL);
	if (BU_STR_EQUAL(key, "region_id")) {
	    long id;

	    id = strtol(value, NULL, 0);
	    if (id != comb->region_id) {
		fprintf(stderr, "WARNING: %s in %s: \"region_id\" attribute says %ld, while region says %ld\n",
			dp->d_namep, dbip->dbi_filename, id, comb->region_id);
	    }
	} else if (BU_STR_EQUAL(key, "giftmater")) {
	    long GIFTmater;

	    GIFTmater = strtol(value, NULL, 0);
	    if (GIFTmater != comb->GIFTmater) {
		fprintf(stderr, "WARNING: %s in %s: \"giftmater\" attribute says %ld, while region says %ld\n",
			dp->d_namep, dbip->dbi_filename, GIFTmater, comb->GIFTmater);
	    }
	} else if (BU_STR_EQUAL(key, "los")) {
	    long los;

	    los = strtol(value, NULL, 0);
	    if (los != comb->los) {
		fprintf(stderr, "WARNING: %s in %s: \"los\" attribute says %ld, while region says %ld\n",
			dp->d_namep, dbip->dbi_filename, los, comb->los);
	    }
	} else if (BU_STR_EQUAL(key, "material")) {
	    if (!bu_strncmp(value, "gift", 4)) {
		long GIFTmater;

		GIFTmater = strtol(&value[4], NULL, 0);
		if (GIFTmater != comb->GIFTmater) {
		    fprintf(stderr, "WARNING: %s in %s: \"material\" attribute says %s, while region says %ld\n",
			    dp->d_namep, dbip->dbi_filename, value, comb->GIFTmater);
		}
	    }
	} else if (BU_STR_EQUAL(key, "aircode")) {
	    long aircode;

	    aircode = strtol(value, NULL, 0);
	    if (aircode != comb->aircode) {
		fprintf(stderr, "WARNING: %s in %s: \"aircode\" attribute says %ld, while region says %ld\n",
			dp->d_namep, dbip->dbi_filename, aircode, comb->aircode);
	    }
	}
    }
    rt_db_free_internal(&intern);
}
Example #23
0
void
db_update_nref( struct db_i *dbip, struct resource *resp )
{
    register int			i;
    register struct directory      *dp;
    struct rt_db_internal		intern;
    struct rt_comb_internal	       *comb;

    RT_CK_DBI( dbip );
    RT_CK_RESOURCE(resp);

    /* First, clear any existing counts */
    for ( i = 0; i < RT_DBNHASH; i++ )
	for ( dp = dbip->dbi_Head[i]; dp != DIR_NULL; dp = dp->d_forw )
	    dp->d_nref = 0;

    /* Examine all COMB nodes */
    for ( i = 0; i < RT_DBNHASH; i++ )  {
	for ( dp = dbip->dbi_Head[i]; dp != DIR_NULL; dp = dp->d_forw ) {

	    /* handle non-combination objects that reference other objects */
	    if ( dp->d_major_type == DB5_MAJORTYPE_BRLCAD ) {
		struct directory *dp2;

		if ( dp->d_minor_type == DB5_MINORTYPE_BRLCAD_EXTRUDE ) {
		    struct rt_extrude_internal *extr;

		    if ( rt_db_get_internal(&intern, dp, dbip, (fastf_t *)NULL, resp) < 0 )
			continue;
		    extr = (struct rt_extrude_internal *)intern.idb_ptr;
		    RT_EXTRUDE_CK_MAGIC( extr );
		    if ( extr->sketch_name ) {
			dp2 = db_lookup( dbip, extr->sketch_name, LOOKUP_QUIET );
			if ( dp2 != DIR_NULL ) {
			    dp2->d_nref++;
			}
		    }
		    rt_db_free_internal( &intern, resp );
		} else if ( dp->d_minor_type ==  DB5_MINORTYPE_BRLCAD_DSP ) {
		    struct rt_dsp_internal *dsp;

		    if ( rt_db_get_internal(&intern, dp, dbip, (fastf_t *)NULL, resp) < 0 )
			continue;
		    dsp = (struct rt_dsp_internal *)intern.idb_ptr;
		    RT_DSP_CK_MAGIC( dsp );
		    if ( dsp->dsp_datasrc == RT_DSP_SRC_OBJ && bu_vls_strlen( &dsp->dsp_name) > 0 ) {
			dp2 = db_lookup( dbip, bu_vls_addr( &dsp->dsp_name ), LOOKUP_QUIET );
			if ( dp2 != DIR_NULL ) {
			    dp2->d_nref++;
			}
		    }
		    rt_db_free_internal( &intern, resp );
		}
	    }
	    if ( !(dp->d_flags & DIR_COMB) )
		continue;
	    if ( rt_db_get_internal(&intern, dp, dbip, (fastf_t *)NULL, resp) < 0 )
		continue;
	    if ( intern.idb_type != ID_COMBINATION )  {
		bu_log("NOTICE: %s was marked a combination, but isn't one?  Clearing flag\n",
		       dp->d_namep);
		dp->d_flags &= ~DIR_COMB;
		rt_db_free_internal( &intern, resp );
		continue;
	    }
	    comb = (struct rt_comb_internal *)intern.idb_ptr;
	    db_tree_funcleaf( dbip, comb, comb->tree,
			      db_count_refs, (genptr_t)NULL,
			      (genptr_t)NULL, (genptr_t)NULL );
	    rt_db_free_internal( &intern, resp );
	}
    }
}
void
nmg_2_vrml(struct db_tree_state *tsp, const struct db_full_path *pathp, struct model *m)
{
    struct mater_info *mater = &tsp->ts_mater;
    const struct bn_tol *tol2 = tsp->ts_tol;
    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;
    point_t ave_pt = VINIT_ZERO;
    struct bu_vls shape_name = BU_VLS_INIT_ZERO;
    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;

    /* static due to libbu exception handling */
    static float r, g, b;

    NMG_CK_MODEL(m);

    full_path = db_path_to_string(pathp);

    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, NULL);

    if (bu_strncmp("light", mat.shader, 5) == 0) {
	/* this is a light source */
	is_light = 1;
    } else {
	path_2_vrml_id(&shape_name, full_path);
	fprintf(fp_out, "\t\tDEF %s Shape {\n", bu_vls_addr(&shape_name));

	fprintf(fp_out, "\t\t\t# Component_ID: %ld   %s\n", comb->region_id, full_path);
	fprintf(fp_out, "\t\t\tappearance Appearance {\n");

	if (bu_strncmp("plastic", mat.shader, 7) == 0) {
	    if (mat.shininess < 0) {
		mat.shininess = 10;
	    }
	    if (mat.transparency < SMALL_FASTF) {
		mat.transparency = 0.0;
	    }

	    fprintf(fp_out, "\t\t\t\tmaterial Material {\n");
	    fprintf(fp_out, "\t\t\t\t\tdiffuseColor %g %g %g \n", r, g, b);
	    fprintf(fp_out, "\t\t\t\t\tshininess %g\n", 1.0-exp(-(double)mat.shininess/20.0));
	    if (mat.transparency > SMALL_FASTF) {
		fprintf(fp_out, "\t\t\t\t\ttransparency %g\n", mat.transparency);
	    }
	    fprintf(fp_out, "\t\t\t\t\tspecularColor %g %g %g \n\t\t\t\t}\n", 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 < SMALL_FASTF) {
		mat.transparency = 0.8;
	    }

	    fprintf(fp_out, "\t\t\t\tmaterial Material {\n");
	    fprintf(fp_out, "\t\t\t\t\tdiffuseColor %g %g %g \n", r, g, b);
	    fprintf(fp_out, "\t\t\t\t\tshininess %g\n", 1.0-exp(-(double)mat.shininess/20.0));
	    if (mat.transparency > SMALL_FASTF) {
		fprintf(fp_out, "\t\t\t\t\ttransparency %g\n", mat.transparency);
	    }
	    fprintf(fp_out, "\t\t\t\t\tspecularColor %g %g %g \n\t\t\t\t}\n", 1.0, 1.0, 1.0);
	} else if (bu_strncmp("texture", mat.shader, 7) == 0) {
	    if (mat.tx_w < 0) {
		mat.tx_w = 512;
	    }
	    if (mat.tx_n < 0) {
		mat.tx_n = 512;
	    }
	    if (strlen(mat.tx_file)) {
		int tex_fd;
		unsigned char tex_buf[TXT_BUF_LEN * 3];

		if ((tex_fd = open(mat.tx_file, O_RDONLY | O_BINARY)) == (-1)) {
		    bu_log("Cannot open texture file (%s)\n", mat.tx_file);
		    perror("g-vrml: ");
		} else {
		    long tex_len;
		    long bytes_read = 0;
		    long bytes_to_go = 0;

		    /* Johns note - need to check (test) the texture stuff */
		    fprintf(fp_out, "\t\t\t\ttextureTransform TextureTransform {\n");
		    fprintf(fp_out, "\t\t\t\t\tscale 1.33333 1.33333\n\t\t\t\t}\n");
		    fprintf(fp_out, "\t\t\t\ttexture PixelTexture {\n");
		    fprintf(fp_out, "\t\t\t\t\trepeatS TRUE\n");
		    fprintf(fp_out, "\t\t\t\t\trepeatT TRUE\n");
		    fprintf(fp_out, "\t\t\t\t\timage %d %d %d\n", mat.tx_w, mat.tx_n, 3);
		    tex_len = mat.tx_w*mat.tx_n * 3;
		    while (bytes_read < tex_len) {
			int nbytes;
			long readval;

			bytes_to_go = tex_len - bytes_read;
			CLAMP(bytes_to_go, 0, TXT_BUF_LEN * 3);

			nbytes = 0;
			while (nbytes < bytes_to_go) {
			    readval = read(tex_fd, &tex_buf[nbytes], bytes_to_go-nbytes);
			    if (readval < 0) {
				perror("READ ERROR");
				break;
			    } else {
				nbytes += readval;
			    }
			}
			bytes_read += nbytes;
			for (i = 0; i < nbytes; i += 3) {
			    fprintf(fp_out, "\t\t\t0x%02x%02x%02x\n",
				    tex_buf[i], tex_buf[i+1], tex_buf[i+2]);
			}
		    }
		    fprintf(fp_out, "\t\t\t\t}\n");

		    close(tex_fd);
		}
	    }
	} else if (mater->ma_color_valid) {
	    /* no shader specified, but a color is assigned */
	    fprintf(fp_out, "\t\t\t\tmaterial Material {\n");
	    fprintf(fp_out, "\t\t\t\t\tdiffuseColor %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_out, "\t\t\tmaterial USE Material_999\n")
		: thou == 1 ? fprintf(fp_out, "\t\t\tmaterial USE Material_1999\n")
		: thou == 2 ? fprintf(fp_out, "\t\t\tmaterial USE Material_2999\n")
		: thou == 3 ? fprintf(fp_out, "\t\t\tmaterial USE Material_3999\n")
		: thou == 4 ? fprintf(fp_out, "\t\t\tmaterial USE Material_4999\n")
		: thou == 5 ? fprintf(fp_out, "\t\t\tmaterial USE Material_5999\n")
		: thou == 6 ? fprintf(fp_out, "\t\t\tmaterial USE Material_6999\n")
		: thou == 7 ? fprintf(fp_out, "\t\t\tmaterial USE Material_7999\n")
		: thou == 8 ? fprintf(fp_out, "\t\t\tmaterial USE Material_8999\n")
		: fprintf(fp_out, "\t\t\tmaterial USE Material_9999\n");
	}
    }

    if (!is_light) {
	nmg_triangulate_model(m, tol2);
	fprintf(fp_out, "\t\t\t}\n");
	fprintf(fp_out, "\t\t\tgeometry IndexedFaceSet {\n");
	fprintf(fp_out, "\t\t\t\tcoord Coordinate {\n");
    }

    /* get list of vertices */
    nmg_vertex_tabulate(&verts, &m->magic);
    if (!is_light) {
	fprintf(fp_out, "\t\t\t\t\tpoint [");
    } else {
	VSETALL(ave_pt, 0.0);
    }

    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_out, " %10.10e %10.10e %10.10e, # point %d\n", V3ARGS(pt_meters), i);
	    }
	    first = 0;
	} else if (!is_light) {
	    fprintf(fp_out, "\t\t\t\t\t%10.10e %10.10e %10.10e, # point %d\n", V3ARGS(pt_meters), i);
	}
    }

    if (!is_light) {
	fprintf(fp_out, "\t\t\t\t\t]\n\t\t\t\t}\n");
    } else {
	fastf_t one_over_count;
	one_over_count = 1.0/(fastf_t)BU_PTBL_END(&verts);
	VSCALE(ave_pt, ave_pt, one_over_count);
    }

    first = 1;
    if (!is_light) {
	fprintf(fp_out, "\t\t\t\tcoordIndex [\n");
	for (BU_LIST_FOR(reg, nmgregion, &m->r_hd)) {
	    struct shell *s;

	    NMG_CK_REGION(reg);
	    for (BU_LIST_FOR(s, shell, &reg->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_out, ",\n");
			} else {
			    first = 0;
			}

			fprintf(fp_out, "\t\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_out, " %d,", bu_ptbl_locate(&verts, (long *)v));
			}
			fprintf(fp_out, "-1");
		    }
		}
	    }
	}
	fprintf(fp_out, "\n\t\t\t\t]\n\t\t\t\tnormalPerVertex FALSE\n");
	fprintf(fp_out, "\t\t\t\tconvex FALSE\n");
	fprintf(fp_out, "\t\t\t\tcreaseAngle 0.5\n");
	fprintf(fp_out, "\t\t\t}\n\t\t}\n");
    } else {
Example #25
0
/*
 * This is a helper routine used in txt_setup() to load a texture either from
 * a file or from a db object.  The resources are released in txt_free()
 * (there is no specific unload_datasource function).
 */
HIDDEN int
txt_load_datasource(struct txt_specific *texture, struct db_i *dbInstance, const unsigned long int size)
{
    struct directory *dirEntry;

    RT_CK_DBI(dbInstance);

    if (texture == (struct txt_specific *)NULL) {
	bu_bomb("ERROR: txt_load_datasource() received NULL arg (struct txt_specific *)\n");
    }

    bu_log("Loading texture %s [%s]...", texture->tx_datasrc==TXT_SRC_AUTO?"from auto-determined datasource":texture->tx_datasrc==TXT_SRC_OBJECT?"from a database object":texture->tx_datasrc==TXT_SRC_FILE?"from a file":"from an unknown source (ERROR)", bu_vls_addr(&texture->tx_name));

    /* if the source is auto or object, we try to load the object */
    if ((texture->tx_datasrc==TXT_SRC_AUTO) || (texture->tx_datasrc==TXT_SRC_OBJECT)) {

	/* see if the object exists */
	if ((dirEntry=db_lookup(dbInstance, bu_vls_addr(&texture->tx_name), LOOKUP_QUIET)) == RT_DIR_NULL) {

	    /* unable to find the texture object */
	    if (texture->tx_datasrc!=TXT_SRC_AUTO) {
		return -1;
	    }
	} else {
	    struct rt_db_internal *dbip;

	    BU_ALLOC(dbip, struct rt_db_internal);

	    RT_DB_INTERNAL_INIT(dbip);
	    RT_CK_DB_INTERNAL(dbip);
	    RT_CK_DIR(dirEntry);

	    /* the object was in the directory, so go get it */
	    if (rt_db_get_internal(dbip, dirEntry, dbInstance, NULL, NULL) <= 0) {
		/* unable to load/create the texture database record object */
		return -1;
	    }

	    RT_CK_DB_INTERNAL(dbip);
	    RT_CK_BINUNIF(dbip->idb_ptr);

	    /* keep the binary object pointer */
	    texture->tx_binunifp=(struct rt_binunif_internal *)dbip->idb_ptr; /* make it so */

	    /* release the database instance pointer struct we created */
	    RT_DB_INTERNAL_INIT(dbip);
	    bu_free(dbip, "txt_load_datasource");

	    /* check size of object */
	    if (texture->tx_binunifp->count < size) {
		bu_log("\nWARNING: %s needs %d bytes, binary object only has %lu\n", bu_vls_addr(&texture->tx_name), size, texture->tx_binunifp->count);
	    } else if (texture->tx_binunifp->count > size) {
		bu_log("\nWARNING: Binary object is larger than specified texture size\n\tBinary Object: %zu pixels\n\tSpecified Texture Size: %zu pixels\n...continuing to load using image subsection...", texture->tx_binunifp->count);
	    }
	}
    }

    /* if we are auto and we couldn't find a database object match, or if source
     * is explicitly a file then we load the file.
     */
    if (((texture->tx_datasrc==TXT_SRC_AUTO) && (texture->tx_binunifp==NULL)) || (texture->tx_datasrc==TXT_SRC_FILE)) {

	texture->tx_mp = bu_open_mapped_file_with_path(dbInstance->dbi_filepath,	bu_vls_addr(&texture->tx_name), NULL);

	if (texture->tx_mp==NULL)
	    return -1;				/* FAIL */

	if (texture->tx_mp->buflen < size) {
	    bu_log("\nWARNING: %s needs %d bytes, file only has %lu\n", bu_vls_addr(&texture->tx_name), size, texture->tx_mp->buflen);
	} else if (texture->tx_mp->buflen > size) {
	    bu_log("\nWARNING: Texture file size is larger than specified texture size\n\tInput File: %zu pixels\n\tSpecified Texture Size: %lu pixels\n...continuing to load using image subsection...", texture->tx_mp->buflen, size);
	}

    }

    bu_log("done.\n");

    return 0;
}
Example #26
0
/**
 * Import an REVOLVE from the database format to the internal format.
 * Note that the data read will be in network order.  This means
 * Big-Endian integers and IEEE doubles for floating point.
 *
 * Apply modeling transformations as well.
 */
int
rt_revolve_import5(struct rt_db_internal *ip, const struct bu_external *ep, const mat_t mat, const struct db_i *dbip, struct resource *resp)
{
    struct rt_revolve_internal *rip;

    /* must be double for import and export */
    double vv[ELEMENTS_PER_VECT*3 + 1];

    char *sketch_name;
    unsigned char *ptr;
    struct directory *dp;
    struct rt_db_internal tmp_ip;

    if (dbip) RT_CK_DBI(dbip);

    RT_CK_DB_INTERNAL(ip);
    BU_CK_EXTERNAL(ep);

    /* set up the internal structure */
    ip->idb_major_type = DB5_MAJORTYPE_BRLCAD;
    ip->idb_type = ID_REVOLVE;
    ip->idb_meth = &OBJ[ID_REVOLVE];
    BU_ALLOC(ip->idb_ptr, struct rt_revolve_internal);

    rip = (struct rt_revolve_internal *)ip->idb_ptr;
    rip->magic = RT_REVOLVE_INTERNAL_MAGIC;

    /* Convert the data in ep->ext_buf into internal format.  Note the
     * conversion from network data (Big Endian ints, IEEE double
     * floating point) to host local data representations.
     */

    ptr = (unsigned char *)ep->ext_buf;
    sketch_name = (char *)ptr + (ELEMENTS_PER_VECT*3 + 1)*SIZEOF_NETWORK_DOUBLE;
    if (!dbip)
	rip->skt = (struct rt_sketch_internal *)NULL;
    else if ((dp=db_lookup(dbip, sketch_name, LOOKUP_NOISY)) == RT_DIR_NULL) {
	bu_log("ERROR: Cannot find sketch (%s) for extrusion\n",
	       sketch_name);
	rip->skt = (struct rt_sketch_internal *)NULL;
    } else {
	if (rt_db_get_internal(&tmp_ip, dp, dbip, bn_mat_identity, resp) != ID_SKETCH) {
	    bu_log("ERROR: Cannot import sketch (%s) for extrusion\n",
		   sketch_name);
	    bu_free(ip->idb_ptr, "extrusion");
	    return -1;
	} else
	    rip->skt = (struct rt_sketch_internal *)tmp_ip.idb_ptr;
    }

    bu_cv_ntohd((unsigned char *)&vv, (unsigned char *)ep->ext_buf, ELEMENTS_PER_VECT*3 + 1);

    /* Apply the modeling transformation */
    if (mat == NULL) mat = bn_mat_identity;
    MAT4X3PNT(rip->v3d, mat, &vv[0*3]);
    MAT4X3PNT(rip->axis3d, mat, &vv[1*3]);
    MAT4X3PNT(rip->r, mat, &vv[2*3]);
    rip->ang = vv[9];

    /* convert name of data location */
    bu_vls_init(&rip->sketch_name);
    bu_vls_strcpy(&rip->sketch_name, (char *)ep->ext_buf + (ELEMENTS_PER_VECT * 3 + 1) * SIZEOF_NETWORK_DOUBLE);

    return 0;			/* OK */
}
Example #27
0
int
ged_move(struct ged *gedp, int argc, const char *argv[])
{
    struct ged_display_list *gdlp;
    struct directory *dp;
    struct rt_db_internal intern;
    static const char *usage = "from to";

    GED_CHECK_DATABASE_OPEN(gedp, GED_ERROR);
    GED_CHECK_READ_ONLY(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 ((dp = db_lookup(gedp->ged_wdbp->dbip,  argv[1], LOOKUP_NOISY)) == RT_DIR_NULL)
	return GED_ERROR;

    if (db_lookup(gedp->ged_wdbp->dbip, argv[2], LOOKUP_QUIET) != RT_DIR_NULL) {
	bu_vls_printf(gedp->ged_result_str, "%s: already exists", argv[2]);
	return GED_ERROR;
    }

    if (rt_db_get_internal(&intern, dp, gedp->ged_wdbp->dbip, (fastf_t *)NULL, &rt_uniresource) < 0) {
	bu_vls_printf(gedp->ged_result_str, "Database read error, aborting");
	return GED_ERROR;
    }

    /* Change object name in the in-memory directory. */
    if (db_rename(gedp->ged_wdbp->dbip, dp, argv[2]) < 0) {
	rt_db_free_internal(&intern);
	bu_vls_printf(gedp->ged_result_str, "error in db_rename to %s, aborting", argv[2]);
	return GED_ERROR;
    }

    /* Re-write to the database.  New name is applied on the way out. */
    if (rt_db_put_internal(dp, gedp->ged_wdbp->dbip, &intern, &rt_uniresource) < 0) {
	bu_vls_printf(gedp->ged_result_str, "Database write error, aborting");
	return GED_ERROR;
    }

    /* Change object name if it matches the first element in the display list path. */
    for (BU_LIST_FOR(gdlp, ged_display_list, gedp->ged_gdp->gd_headDisplay)) {
	int first = 1;
	int found = 0;
	struct bu_vls new_path = BU_VLS_INIT_ZERO;
	char *dupstr = strdup(bu_vls_addr(&gdlp->gdl_path));
	char *tok = strtok(dupstr, "/");

	while (tok) {
	    if (first) {
		first = 0;

		if (BU_STR_EQUAL(tok, argv[1])) {
		    found = 1;
		    bu_vls_printf(&new_path, "%s", argv[2]);
		} else
		    break; /* no need to go further */
	    } else
		bu_vls_printf(&new_path, "/%s", tok);

	    tok = strtok((char *)NULL, "/");
	}

	if (found) {
	    bu_vls_free(&gdlp->gdl_path);
	    bu_vls_printf(&gdlp->gdl_path, "%s", bu_vls_addr(&new_path));
	}

	free((void *)dupstr);
	bu_vls_free(&new_path);
    }

    return GED_OK;
}
Example #28
0
int
main(int argc, char **argv)
{
    struct rt_wdb	*fp;
    struct db_i	*dbip;
    struct directory	*dp;
    long	errors = 0;
    struct bn_tol tol;
    char name[17];

    bu_setprogname(argv[0]);

    /* FIXME: These need to be improved */
    tol.magic = BN_TOL_MAGIC;
    tol.dist = 0.0005;
    tol.dist_sq = tol.dist * tol.dist;
    tol.perp = 1e-6;
    tol.para = 1 - tol.perp;

    bu_debug = BU_DEBUG_COREDUMP;

    rt_init_resource( &rt_uniresource, 0, NULL );

    if ( argc != 3 )  {
	fprintf(stderr, "Usage: %s v4.g v5.g\n", argv[0]);
	return 1;
    }

    if ( (dbip = db_open(argv[1], DB_OPEN_READONLY)) == DBI_NULL )  {
	perror( argv[1] );
	return 2;
    }

    if ( (fp = wdb_fopen( argv[2] )) == NULL )  {
	perror( argv[2] );
	return 3;
    }

    if ( db_version(dbip) != 4 ) {
	bu_log( "Input database must be a version 4 database!!!!\n" );
	return 4;
    }

    RT_CK_DBI(dbip);
    if ( db_dirbuild( dbip ) )
	bu_exit(1, "db_dirbuild failed\n" );

    db_update_ident( fp->dbip, dbip->dbi_title, dbip->dbi_local2base );

    /* Retrieve every item in the input database */
    FOR_ALL_DIRECTORY_START(dp, dbip)  {
	struct rt_db_internal	intern;
	int id;
	int ret;

	fprintf(stderr, "%.16s\n", dp->d_namep );

	id = rt_db_get_internal( &intern, dp, dbip, NULL, &rt_uniresource );
	if ( id < 0 )  {
	    fprintf(stderr,
		    "%s: rt_db_get_internal(%s) failure, skipping\n",
		    argv[0], dp->d_namep);
	    errors++;
	    continue;
	}
	if ( id == ID_COMBINATION ) {
	    struct rt_comb_internal *comb;
	    char *ptr;

	    comb = (struct rt_comb_internal *)intern.idb_ptr;
	    RT_CK_COMB( comb );

	    /* Convert "plastic" to "phong" in the shader string */
	    while ( (ptr=strstr( bu_vls_addr( &comb->shader), "plastic" )) != NULL ) {
		ptr[0] = 'p'; /* p */
		ptr[1] = 'h'; /* l */
		ptr[2] = 'o'; /* a */
		ptr[3] = 'n'; /* s */
		ptr[4] = 'g'; /* t */
		ptr[5] = ' '; /* i */
		ptr[6] = ' '; /* c */
	    }
	}
	if ( id == ID_HF ) {
	    if (rt_hf_to_dsp( &intern )) {
		fprintf(stderr,
			"%s: Conversion from HF to DSP failed for solid %s\n",
			argv[0], dp->d_namep );
		errors++;
		continue;
	    }
	}
	if ( id == ID_POLY)
	{
	    if ( rt_pg_to_bot( &intern, &tol, &rt_uniresource ) )
	    {
		fprintf( stderr, "%s: Conversion from polysolid to BOT failed for solid %s\n",
			 argv[0], dp->d_namep );
		errors++;
		continue;
	    }
	}

	/* to insure null termination */
	bu_strlcpy( name, dp->d_namep, sizeof(name) );
	ret = wdb_put_internal( fp, name, &intern, 1.0 );
	if ( ret < 0 )  {
	    fprintf(stderr,
		    "%s: wdb_put_internal(%s) failure, skipping\n",
		    argv[0], dp->d_namep);
	    rt_db_free_internal(&intern);
	    errors++;
	    continue;
	}
	rt_db_free_internal(&intern);
    } FOR_ALL_DIRECTORY_END

	  wdb_close( fp );
    db_close( dbip );

    fprintf(stderr, "%ld objects failed to convert\n", errors);
    return 0;
}
Example #29
0
HIDDEN int
move_all_func(struct ged *gedp, int nflag, const char *old_name, const char *new_name)
{
    int i;
    struct ged_display_list *gdlp;
    struct directory *dp;
    struct rt_db_internal intern;
    struct rt_comb_internal *comb;
    struct bu_ptbl stack;

    /* rename the record itself */
    if ((dp = db_lookup(gedp->ged_wdbp->dbip, old_name, LOOKUP_NOISY)) == RT_DIR_NULL)
	return GED_ERROR;

    if (db_lookup(gedp->ged_wdbp->dbip, new_name, LOOKUP_QUIET) != RT_DIR_NULL) {
	bu_vls_printf(gedp->ged_result_str, "%s: already exists", new_name);
	return GED_ERROR;
    }

    /* if this was a sketch, we need to look for all the extrude
     * objects that might use it.
     *
     * This has to be done here, before we rename the (possible) sketch object
     * because the extrude will do a rt_db_get on the sketch when we call
     * rt_db_get_internal on it.
     */
    if (dp->d_major_type == DB5_MAJORTYPE_BRLCAD && \
	dp->d_minor_type == DB5_MINORTYPE_BRLCAD_SKETCH) {

	struct directory *dirp;

	for (i = 0; i < RT_DBNHASH; i++) {
	    for (dirp = gedp->ged_wdbp->dbip->dbi_Head[i]; dirp != RT_DIR_NULL; dirp = dirp->d_forw) {

		if (dirp->d_major_type == DB5_MAJORTYPE_BRLCAD && \
		    dirp->d_minor_type == DB5_MINORTYPE_BRLCAD_EXTRUDE) {
		    struct rt_extrude_internal *extrude;

		    if (rt_db_get_internal(&intern, dirp, gedp->ged_wdbp->dbip, (fastf_t *)NULL, &rt_uniresource) < 0) {
			bu_log("Can't get extrude %s?\n", dirp->d_namep);
			continue;
		    }
		    extrude = (struct rt_extrude_internal *)intern.idb_ptr;
		    RT_EXTRUDE_CK_MAGIC(extrude);

		    if (BU_STR_EQUAL(extrude->sketch_name, old_name)) {
			if (nflag) {
			    bu_vls_printf(gedp->ged_result_str, "%s ", dirp->d_namep);
			    rt_db_free_internal(&intern);
			} else {
			    bu_free(extrude->sketch_name, "sketch name");
			    extrude->sketch_name = bu_strdup(new_name);

			    if (rt_db_put_internal(dirp, gedp->ged_wdbp->dbip, &intern, &rt_uniresource) < 0) {
				bu_log("oops\n");
			    }
			}
		    } else
			rt_db_free_internal(&intern);
		}
	    }
	}
    }

    if (!nflag) {
	/* Change object name in the directory. */
	if (db_rename(gedp->ged_wdbp->dbip, dp, new_name) < 0) {
	    bu_vls_printf(gedp->ged_result_str, "error in rename to %s, aborting", new_name);
	    return GED_ERROR;
	}

	/* Change name in the file */
	if (rt_db_get_internal(&intern, dp, gedp->ged_wdbp->dbip, (fastf_t *)NULL, &rt_uniresource) < 0) {
	    bu_vls_printf(gedp->ged_result_str, "Database read error, aborting");
	    return GED_ERROR;
	}

	if (rt_db_put_internal(dp, gedp->ged_wdbp->dbip, &intern, &rt_uniresource) < 0) {
	    bu_vls_printf(gedp->ged_result_str, "Database write error, aborting");
	    return GED_ERROR;
	}
    }

    bu_ptbl_init(&stack, 64, "combination stack for wdb_mvall_cmd");


    /* Examine all COMB nodes */
    for (i = 0; i < RT_DBNHASH; i++) {
	for (dp = gedp->ged_wdbp->dbip->dbi_Head[i]; dp != RT_DIR_NULL; dp = dp->d_forw) {
	    if (nflag) {
		union tree *comb_leaf;
		int done=0;

		if (!(dp->d_flags & RT_DIR_COMB)) continue;
		if (rt_db_get_internal(&intern, dp, gedp->ged_wdbp->dbip, (fastf_t *)NULL, &rt_uniresource) < 0) continue;
		comb = (struct rt_comb_internal *)intern.idb_ptr;
		bu_ptbl_reset(&stack);
		/* visit each leaf in the combination */
		comb_leaf = comb->tree;
		if (comb_leaf) {
		    while (!done) {
			while (comb_leaf->tr_op != OP_DB_LEAF) {
			    bu_ptbl_ins(&stack, (long *)comb_leaf);
			    comb_leaf = comb_leaf->tr_b.tb_left;
			}

			if (BU_STR_EQUAL(comb_leaf->tr_l.tl_name, old_name)) {
			    bu_vls_printf(gedp->ged_result_str, "%s ", dp->d_namep);
			}

			if (BU_PTBL_END(&stack) < 1) {
			    done = 1;
			    break;
			}
			comb_leaf = (union tree *)BU_PTBL_GET(&stack, BU_PTBL_END(&stack)-1);
			if (comb_leaf->tr_op != OP_DB_LEAF) {
			    bu_ptbl_rm(&stack, (long *)comb_leaf);
			    comb_leaf = comb_leaf->tr_b.tb_right;
			}
		    }
		}
		rt_db_free_internal(&intern);
	    } else {
		int comb_mvall_status = db_comb_mvall(dp, gedp->ged_wdbp->dbip, old_name, new_name, &stack);
		if (!comb_mvall_status) continue;
		if (comb_mvall_status == 2) {
		    bu_ptbl_free(&stack);
		    bu_vls_printf(gedp->ged_result_str, "Database write error, aborting");
		    return GED_ERROR;
		}
	    }
	}
    }

    bu_ptbl_free(&stack);

    if (!nflag) {
	/* Change object name anywhere in the display list path. */
	for (BU_LIST_FOR(gdlp, ged_display_list, gedp->ged_gdp->gd_headDisplay)) {
	    int first = 1;
	    int found = 0;
	    struct bu_vls new_path = BU_VLS_INIT_ZERO;
	    char *dupstr = strdup(bu_vls_addr(&gdlp->gdl_path));
	    char *tok = strtok(dupstr, "/");

	    while (tok) {
		if (BU_STR_EQUAL(tok, old_name)) {
		    found = 1;

		    if (first) {
			first = 0;
			bu_vls_printf(&new_path, "%s", new_name);
		    } else
			bu_vls_printf(&new_path, "/%s", new_name);
		} else {
		    if (first) {
			first = 0;
			bu_vls_printf(&new_path, "%s", tok);
		    } else
			bu_vls_printf(&new_path, "/%s", tok);
		}

		tok = strtok((char *)NULL, "/");
	    }

	    if (found) {
		bu_vls_free(&gdlp->gdl_path);
		bu_vls_printf(&gdlp->gdl_path, "%s", bu_vls_addr(&new_path));
	    }

	    free((void *)dupstr);
	    bu_vls_free(&new_path);
	}
    }

    return GED_OK;
}
Example #30
0
int
ged_nmg_collapse(struct ged *gedp, int argc, const char *argv[])
{
    char *new_name;
    struct model *m;
    struct rt_db_internal intern;
    struct directory *dp;
    struct bu_ptbl faces;
    struct face *fp;
    size_t count;
    fastf_t tol_coll;
    fastf_t min_angle;
    static const char *usage = "nmg_prim new_prim max_err_dist [min_angle]";

    GED_CHECK_DATABASE_OPEN(gedp, GED_ERROR);
    GED_CHECK_READ_ONLY(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 (strchr(argv[2], '/')) {
	bu_vls_printf(gedp->ged_result_str, "Do not use '/' in solid names: %s\n", argv[2]);
	return GED_ERROR;
    }

    new_name = (char *)argv[2];

    if (db_lookup(gedp->ged_wdbp->dbip, new_name, LOOKUP_QUIET) != RT_DIR_NULL) {
	bu_vls_printf(gedp->ged_result_str, "%s already exists\n", new_name);
	return GED_ERROR;
    }

    if ((dp=db_lookup(gedp->ged_wdbp->dbip, argv[1], LOOKUP_NOISY)) == RT_DIR_NULL)
	return GED_ERROR;

    if (dp->d_flags & RT_DIR_COMB) {
	bu_vls_printf(gedp->ged_result_str, "%s is a combination, only NMG primitives are allowed here\n", argv[1]);
	return GED_ERROR;
    }

    if (rt_db_get_internal(&intern, dp, gedp->ged_wdbp->dbip, (matp_t)NULL, &rt_uniresource) < 0) {
	bu_vls_printf(gedp->ged_result_str, "Failed to get internal form of %s!!!!\n", argv[1]);
	return GED_ERROR;
    }

    if (intern.idb_type != ID_NMG) {
	bu_vls_printf(gedp->ged_result_str, "%s is not an NMG solid!!!!\n", argv[1]);
	rt_db_free_internal(&intern);
	return GED_ERROR;
    }

    tol_coll = atof(argv[3]) * gedp->ged_wdbp->dbip->dbi_local2base;
    if (tol_coll <= 0.0) {
	bu_vls_printf(gedp->ged_result_str, "tolerance distance too small\n");
	return GED_ERROR;
    }

    if (argc == 5) {
	min_angle = atof(argv[4]);
	if (min_angle < 0.0) {
	    bu_vls_printf(gedp->ged_result_str, "Minimum angle cannot be less than zero\n");
	    return GED_ERROR;
	}
    } else
	min_angle = 0.0;

    m = (struct model *)intern.idb_ptr;
    NMG_CK_MODEL(m);

    /* check that all faces are planar */
    nmg_face_tabulate(&faces, &m->magic);
    for (BU_PTBL_FOR(fp, (struct face *), &faces)) {
	if (fp->g.magic_p != NULL && *(fp->g.magic_p) != NMG_FACE_G_PLANE_MAGIC) {
	    bu_log("\tnot planar\n");
	    bu_ptbl_free(&faces);
	    bu_vls_printf(gedp->ged_result_str,
			  "nmg_collapse can only be applied to NMG primitives with planar faces\n");
	    return GED_ERROR;
	}
    }
    bu_ptbl_free(&faces);

    /* triangulate model */
    nmg_triangulate_model(m, &gedp->ged_wdbp->wdb_tol);

    count = (size_t)nmg_edge_collapse(m, &gedp->ged_wdbp->wdb_tol, tol_coll, min_angle);

    dp=db_diradd(gedp->ged_wdbp->dbip, new_name, RT_DIR_PHONY_ADDR, 0, RT_DIR_SOLID, (void *)&intern.idb_type);
    if (dp == RT_DIR_NULL) {
	bu_vls_printf(gedp->ged_result_str, "Cannot add %s to directory\n", new_name);
	rt_db_free_internal(&intern);
	return GED_ERROR;
    }

    if (rt_db_put_internal(dp, gedp->ged_wdbp->dbip, &intern, &rt_uniresource) < 0) {
	rt_db_free_internal(&intern);
	bu_vls_printf(gedp->ged_result_str, "Database write error, aborting.\n");
	return GED_ERROR;
    }

    rt_db_free_internal(&intern);

    bu_vls_printf(gedp->ged_result_str, "%zu edges collapsed\n", count);

    return GED_OK;
}