Exemple #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;
}
Exemple #2
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;
}
Exemple #3
0
void
pop_gop(int gop, char *parent1_id, char *parent2_id, char *child1_id, char *child2_id, struct db_i *dbi_p, struct db_i *dbi_c, struct resource *resp)
{
    struct rt_db_internal in1, in2;
    struct rt_comb_internal *parent1;
    struct rt_comb_internal *parent2;
    struct directory *dp;
    union tree *cpoint, **cross_parent;
    struct node *add;
    int i = 0;
    struct node *chosen_node;
    int rand_node;

    RT_CHECK_DBI( dbi_p );
    RT_CHECK_DBI( dbi_c );
    RT_CK_RESOURCE( resp );


    crossover_point = (union tree *)NULL;
    crossover_parent = (union tree **)NULL;
    node = (struct node*)NULL;

    if ( !rt_db_lookup_internal(dbi_p, parent1_id, &dp, &in1, LOOKUP_NOISY, &rt_uniresource))
	bu_exit(EXIT_FAILURE, "Failed to read parent1");
    shape_number =num_nodes= 0;
    parent1 = (struct rt_comb_internal *)in1.idb_ptr;
    mutate = 0;
    switch (gop) {
	case REPRODUCE:
	    pop_functree(dbi_p, dbi_c, parent1->tree, resp, child1_id);
	    break;
	case CROSSOVER:

	    crossover = 1;
	    /*load other parent */
	    if ( !rt_db_lookup_internal(dbi_p, parent2_id, &dp, &in2, LOOKUP_NOISY, resp))
		bu_exit(EXIT_FAILURE, "Failed to read parent2");
	    parent2 = (struct rt_comb_internal *)in2.idb_ptr;

	    BU_ALLOC(node, struct node);
	    BU_LIST_INIT(&node->l);
	    chosen_node = NULL;

	    do{
		num_nodes = 0;
		crossover_parent = &parent1->tree;
		crossover_node = (int)(pop_rand() * db_count_tree_nodes(parent1->tree, 0));
		node_idx = 0;
		pop_functree(dbi_p, dbi_c, parent1->tree, resp, NULL);
		cross_parent = crossover_parent;
		cpoint = crossover_point;


		crossover_op = crossover_point->tr_op;
#define MASK (OP_UNION | OP_XOR | OP_SUBTRACT|OP_INTERSECT)
		if (crossover_op & MASK)crossover_op = MASK;
		crossover_node = db_count_tree_nodes(crossover_point, 0);
		if (pop_find_nodes(parent2->tree) == crossover_node) {
		    BU_ALLOC(add, struct node);
		    add->s_parent = &parent2->tree;
		    add->s_child = parent2->tree;
		    BU_LIST_INSERT(&node->l, &add->l);
		    ++num_nodes;
		}
		if (num_nodes > 0) {
		    rand_node = (int)(pop_rand() * num_nodes);
		    for (add=BU_LIST_FIRST(node, &node->l);BU_LIST_NOT_HEAD(add, &node->l) && chosen_node == NULL; add=BU_LIST_PNEXT(node, add)) {
			if (i++ == rand_node) {
			    chosen_node = add;
			    /* break cleanly...? */
			}
		    }
		}
	    }while(chosen_node == NULL);


	    /* cross trees */
	    *cross_parent = chosen_node->s_child;
	    *chosen_node->s_parent =cpoint;

	    while (BU_LIST_WHILE(add, node, &node->l)) {
		BU_LIST_DEQUEUE(&add->l);
		bu_free(add, "node");
	    }
	    bu_free(node, "node");


	    crossover = 0;

	    /*duplicate shapes held in trees*/
	    pop_functree(dbi_p, dbi_c, parent1->tree, resp, child1_id);
	    shape_number = 0;
	    pop_functree(dbi_p, dbi_c, parent2->tree, resp, child2_id);


	    if ((dp = db_diradd(dbi_c, child2_id, -1, 0, dp->d_flags, (genptr_t)&dp->d_minor_type)) == RT_DIR_NULL)
		bu_exit(EXIT_FAILURE, "Failed to add new individual to child database");
	    if (rt_db_put_internal(dp, dbi_c, &in2, resp) < 0)
		bu_exit(EXIT_FAILURE, "Database write failure");
	    rt_db_free_internal(&in2);

	    break;
	case MUTATE:
	    crossover_parent = &parent1->tree;
	    crossover_node = (int)(pop_rand() * db_count_tree_nodes(parent1->tree, 0));
	    node_idx = 0;
	    mutate = 1;
	    pop_functree(dbi_p, dbi_c, parent1->tree, resp, child1_id);
	    mutate = 0;
	    break;
	    /*
	    //random node to mutate
	    n = (int)(pop_rand() * db_count_tree_nodes(parent1->tree, 0));
	    s_parent = &parent1->tree;
	    s_node = n;
	    node = 0;
	    //find node
	    pop_functree(dbi_p, dbi_c, parent1->tree, resp, NULL);
	    */


	default:
	    bu_exit(EXIT_FAILURE, "illegal genetic operator\nfailed to execute genetic op");
    }


    if ((dp=db_diradd(dbi_c, child1_id, -1, 0, dp->d_flags, (genptr_t)&dp->d_minor_type)) == RT_DIR_NULL) {
	bu_exit(EXIT_FAILURE, "Failed to add new individual to child database");
    }
    if (rt_db_put_internal(dp, dbi_c,  &in1, resp) < 0)
      bu_exit(EXIT_FAILURE, "Database write failure");
    rt_db_free_internal(&in1);
}