Here are attached three tests I used for the pull routine all checking for
combinations, and leaves whether matrices are properly pulled, but however
i've been tweaking the pull_leaf() and pull_comb() codes here to see where
the nan come from.

Cheers!
Nyah
/**
 * pull_leaf_test(): This routine successfully pulls a primtive and returns the 4x4 matrix tranformation representing the primitive. 
 *                   and sets the other parts to identity.
 */ 

#include "common.h"
#include "raytrace.h"
#include "bn.h"
#include "vmath.h"


/* routine counts the number of leaves encountered.
 */
void 
incr_leaf(struct db_i *dbip, struct directory *dp, genptr_t data)
{
    int *counter = (int*)data;
    (*counter)++;
    return;
}

/* counts the number of combinations encountered. */
void
incr_comb(struct db_i *dbip, struct directory *dp, genptr_t data)
{
    int *counter = (int *)data;
    (*counter)++;
    return;
}


/* routine takes the maximum and minimum points from the AABB and determines the translation matrix
 * which moves the centrepoint to the origin and moves the primitive by the its inverse
 * before pulling the translation.
 */
void
translate(matp_t matrix, mat_t tm, point_t min, point_t max)
{
    vect_t c_pt; /* centre point */
    mat_t t_mat; /* temp matrix */
    vect_t t_vec; /* translation vector */
    
    /* computes the centrepoint from both minimum and maximum point
     * following this algorithm: cen[i] = bbx_min[i] + bbx_max[i]) / 2.0
     */
    VADD2(c_pt, max, min);
    VSCALE(c_pt, c_pt, 1/2);
    
    /* translates the centrepoint to the origin. and computes the inverse of this transformation which will be applied to the primitive */
    VREVERSE(t_vec, c_pt);
    MAT_DELTAS_VEC(t_mat, t_vec);
    MAT_DELTAS_VEC(matrix, t_vec);/* pulls translation component of primitive */
    
    /* copies transformation matrix whose inverse restores primitive and bbox */
    MAT_COPY(tm, t_mat);
    
    return;
}


/**
 * P U L L _ L E A F
 *
 * @brief
 * This routine takes the internal database representation of a leaf node or
 * primitive object and builds  a matrix transformation, closest to this node's,
 * sets these values to default and returns matrix.
 * Fixme: This routine only pulls translations up. So additional support for rotations/scale
 *        would be needed for further purposes.
 */
static void
pull_leaf(struct db_i *dbip, struct directory *dp, genptr_t mp)
{
    struct rt_db_internal intern;
    struct bn_tol tol;
    struct resource *resp;
    point_t min;             /* mininum point of bbox */
    point_t max;             /* maximum point of bbox */
    matp_t mat = (matp_t)mp; /* current transformation matrix */
    mat_t matrix, invXform;
    int ret;
    
    BN_TOL_INIT(&tol); /* initializes the tolerance */
    resp = &rt_uniresource;
    rt_init_resource( &rt_uniresource, 0, NULL );

    if (mat == NULL) {
	mat = (matp_t)bu_malloc(sizeof(mat_t), "cur_mat");
        MAT_IDN(mat);
    }

    if (!(dp->d_flags & RT_DIR_SOLID))
        return;
    if (rt_db_get_internal(&intern, dp, dbip, mat, &rt_uniresource) < 0) {
        bu_vls_printf(mp, "Database read error, aborting\n");
        return;
    }
    
    MAT_IDN(mat);
    MAT_IDN(matrix);
    
    /* this computes the AABB bounding box of the leaf object
     * using the bbox call back routine in its rt_functab table.
     * it then passes the minimum and maximum point to translate()
     * which then extracts the translation.
     */
    (intern.idb_meth)->ft_bbox(&intern, &min, &max, &tol);
    
    /* pulls primitive translation matrix copying inverse transformation to restore primitive and bbox */
    translate(mat,matrix, min, max);
    bn_mat_inverse(invXform, matrix);/* computes the inverse of transformation matrix. */
    
    
    ret = (intern.idb_meth)->ft_xform(&intern, invXform, &intern, 0, dbip, resp);/* restores the primitive */

    /* prints current matrix representing current primitive. */
    bn_mat_print("Matrix", mat); 
    
    /**
     * Check primitive after pull to see if everything is fine or primitive was properly pulled.
     */
     mat_t new_mat;
     (intern.idb_meth)->ft_bbox(&intern, &min, &max, &tol);
     translate(new_mat, mat, min, max);
     
     bu_log("\nMatrix Transformation of primitive after pull. ");
     bn_mat_print("Matrix after pull", new_mat);     
    
    return;
}



int
main(void)
{
  struct db_i *dbip;
  struct directory *dp;
  struct resource *resp;
  int counter = 0;
  mat_t cur_mat; /* holds the current tranformation matrix */
  MAT_IDN(cur_mat);
  
  bu_log("\n***************************************************************************************************"
         "\n****  This program tests the pull_leaf routine whether it successfully pulls a matrix transf ******"
         "\n**** from a primitive node printing the matrices extracted and also counting the total number******"
         "\n****                       leaves traversed.                                                 ******"
         "\n****                 Author: Nyah Check, Developer @ BRL-CAD (c) 2013                        ******\n\n");

  /* if (argc < 2) {
    bu_exit(0, "need more, db.g obj\n");
  }*/
  
  dbip = db_open("/home/Ch3ck/Desktop/comb_test.g", "rw");
  if (dbip == NULL) {
    bu_exit(1, "Unable to open %s\n", "/home/Ch3ck/Desktop/comb_test.g");
  }
  
  if (db_dirbuild(dbip) < 0) {
    db_close(dbip);
    bu_exit(1, "Unable to load %s\n", "/home/Ch3ck/Desktop/comb_test.g");
  }
  
  bu_log("Database title is:\n%s\n", dbip->dbi_title);
  bu_log("Units: %s\n", bu_units_string(dbip->dbi_local2base));

  if ((dp = db_lookup(dbip, "goblet1.c", 1)) == NULL) {
    db_close(dbip);
    bu_exit(1, "Unable to find %s\n", "goblet1.c");
  }

  resp = &rt_uniresource;
  rt_init_resource( &rt_uniresource, 0, NULL );
  
  
  /* recursively walks up a tree extracting and printing the matrix tranformations in leaves or primitive nodes. */
  db_functree(dbip, dp, incr_comb,
              pull_leaf,
              resp, &cur_mat);
              
  bu_log("Number of combinations and leaves encountered %d\n", counter);

  return 0;
}
/**
 * pull_comb_test(): this file tests the pull combination routine whether it successfully pulls a combination moving the 
 *                  matrix transformation higher up a tree setting the current combination matrix to identity.
 */ 

#include "common.h"
#include "raytrace.h"
#include "bn.h"


struct db_tree_state state;

void 
incr_region(struct db_i *dbip, struct directory *dp, genptr_t data)
{
  int *counter = (int*)data;
  (*counter)++;
  return;
}

/* Null routine that skips leaves. */
void leaf_skip(struct db_i *dbip, struct directory *dp, genptr_t UNUSED)
{
	return;
}


/* declarates the pull_comb() routine. */
void pull_comb(struct db_i *, struct directory *, genptr_t);

/**
 * This restores the matrix transformation at a combination by taking leaf matrix tranformations, inverting
 * and storing the changes at the combinations.
 */
static void
pull_comb_mat(struct db_i *dbip, struct rt_comb_internal *comb, union tree *comb_leaf, matp_t mp, genptr_t UNUSED, genptr_t UNUSED1, genptr_t UNUSED2)
{
    struct directory *dp;
    struct bu_vls *msg = (struct bu_vls *)UNUSED;
    mat_t inv_mat;
    matp_t mat = mp;

    RT_CK_DBI(dbip);
    RT_CK_TREE(comb_leaf);

    if ((dp = db_lookup(dbip, comb_leaf->tr_l.tl_name, LOOKUP_NOISY)) == RT_DIR_NULL)
	return;

    if (!comb_leaf->tr_l.tl_mat) {
         comb_leaf->tr_l.tl_mat = (matp_t)bu_malloc(sizeof(mat_t), "tl_mat");
         MAT_COPY(comb_leaf->tr_l.tl_mat, mp);
       
         return;
    } else {
  	 /* make sure the matrices are not repeating..... write a directive to check this.  */
   	 /* invert the matrix transformation of the leaf and store new matrix  at comb */
 	bn_mat_inverse(inv_mat, comb_leaf->tr_l.tl_mat );
        
   	 /* multiply inverse and store at combination */
   	 bn_mat_mul2(inv_mat,mp);
   	 MAT_COPY(comb_leaf->tr_l.tl_mat, mp);
   	 pull_comb(dbip, dp, mat);
    }
}


/**
 *@brief
 *pull_comb(): This routine enters a comb restoring the matrix transformation at the combination
 *                calls and calls pull_comb_mat() which updates current matrix transformation and moves up tree.
 *Note:           the generic pointer points to a matrix if successful or a string if unsuccessful.
 */
void
pull_comb(struct db_i *dbip,
             struct directory *dp,  
             genptr_t mp)
{
    struct rt_db_internal intern;
    struct rt_comb_internal *comb;
    matp_t mat = (matp_t)mp;
    mat_t m;
    mat_t invMat;
    
    if (dp->d_flags & RT_DIR_SOLID)
        return;
    if (rt_db_get_internal(&intern, dp, dbip, m, &rt_uniresource) < 0) {
	bu_log("Database read error, aborting\n");
	return;
    }
    
    comb = (struct rt_comb_internal *)intern.idb_ptr;
   
    /* checks if matrix pointer is valid */
    if ( mat == NULL) {
        mat = (matp_t)bu_malloc(sizeof(mat_t), "cur_mat");
        MAT_IDN(mat);
    }
    
    /**
     * This multiplies the inverse of the previous matrix with the current matrix updates pointer and moves up the tree
     * expressed as follows, Prev_mat = Inverse(PrevMatrix) * cur_matrix;
     * 
     */
    bn_mat_print("Cur_mat", m);
    bn_mat_print("Source Transformation", mat);
    bn_mat_inverse(invMat, mat);
    bn_mat_print("\nInv Source Transformation", invMat);
    bn_mat_mul2(invMat,m);			 
    MAT_COPY(mat, m);/* updates current matrix pointer */
    bn_mat_print("Pull mat", m);
    
    if (comb->tree) {
	db_tree_funcleaf(dbip, comb, comb->tree, pull_comb_mat,
			 &m, (genptr_t)NULL, (genptr_t)NULL, (genptr_t)NULL);
	
	if (rt_db_put_internal(dp, dbip, &intern, &rt_uniresource) < 0) {
	    bu_log("Cannot write modified combination (%s) to database\n", dp->d_namep);
	    return;
	}
    }
}


int
main(void)
{
  struct db_i *dbip;
  struct directory *dp;
  struct resource *resp;
  int counter = 0;
  mat_t cur_mat; /* holds the current tranformation matrix */
  MAT_IDN(cur_mat);
  
  bu_log("\nThis program tests the pull_comb routine whether it successfully pulls a matrix transformation up a combination tree\n");
  bu_log("\nSkipping leaves, printing the matrix transformation at each combination before and after the pull\n\n");

  /* if (argc < 2) {
    bu_exit(0, "need more, db.g obj\n");
  }*/
  
  dbip = db_open("/home/Ch3ck/Desktop/comb_test.g", "rw");
  if (dbip == NULL) {
    bu_exit(1, "Unable to open %s\n", "/home/Ch3ck/Desktop/comb_test.g");
  }
  
  if (db_dirbuild(dbip) < 0) {
    db_close(dbip);
    bu_exit(1, "Unable to load %s\n", "/home/Ch3ck/Desktop/comb_test.g");
  }
  
  bu_log("Database title is:\n%s\n", dbip->dbi_title);
  bu_log("Units: %s\n", bu_units_string(dbip->dbi_local2base));

  if ((dp = db_lookup(dbip, "goblet1.c", 1)) == NULL) {
    db_close(dbip);
    bu_exit(1, "Unable to find %s\n", "goblet1.c");
  }

  resp = &rt_uniresource;
  rt_init_resource( &rt_uniresource, 0, NULL );
  
  /* recursively walks up a tree restoring matrix combinations at combination regions printing changes. */
  db_functree(dbip, dp, pull_comb,
              leaf_skip,/*skip all leaves */
              resp, &cur_mat);
              
  bu_log("Number of combinations encountered %d\n", counter);

  return 0;
}
/**
 * pull_leaf_test(): This routine successfully pulls a primtive and returns the 4x4 matrix tranformation representing the primitive. 
 *                   and sets the other parts to identity.
 */ 

#include "common.h"
#include "raytrace.h"
#include "bn.h"
#include "vmath.h"


/* routine counts the number of leaves encountered.
 */
void 
incr_leaf(struct db_i *dbip, struct directory *dp, genptr_t data)
{
    int *counter = (int*)data;
    (*counter)++;
    return;
}

/* counts the number of combinations encountered. */
void
incr_comb(struct db_i *dbip, struct directory *dp, genptr_t data)
{
    int *counter = (int *)data;
    (*counter)++;
    return;
}


void
pull_comb(struct db_i *dbip,
	  struct directory *dp,
	  genptr_t mp);


/* This restores the matrix transformation at a combination by taking leaf matrix tranformations, inverting
 * and storing the changes at the combinations.
 */
static void
pull_comb_mat(struct db_i *dbip, struct rt_comb_internal *UNUSED(comb), union tree *comb_leaf, matp_t mp, genptr_t UNUSED(usr_ptr2),
	      genptr_t UNUSED(usr_ptr3), genptr_t UNUSED(usr_ptr4))
{
    struct directory *dp;
    mat_t inv_mat;
    matp_t mat = mp;

    RT_CK_DBI(dbip);
    RT_CK_TREE(comb_leaf);

    if ((dp = db_lookup(dbip, comb_leaf->tr_l.tl_name, LOOKUP_NOISY)) == RT_DIR_NULL)
	return;

    if (!comb_leaf->tr_l.tl_mat) {
	comb_leaf->tr_l.tl_mat = (matp_t)bu_malloc(sizeof(mat_t), "tl_mat");
	MAT_COPY(comb_leaf->tr_l.tl_mat, mat);

	return;
    }

    /* invert the matrix transformation of the leaf and store new matrix  at comb */
    bn_mat_inverse(inv_mat, comb_leaf->tr_l.tl_mat );

    /* multiply inverse by current matrix and store at combination's leaf matrix node */
    bn_mat_mul2(inv_mat,mat);
    MAT_COPY(comb_leaf->tr_l.tl_mat, mat);
    bn_mat_print("Comb Matrix", mat);
    pull_comb(dbip, dp, mp);
}


/* pull_comb(): This routine enters a comb restoring the matrix transformation at the combination
 *              calls and calls pull_comb_mat() which updates current matrix transformation and moves up tree.
 * Note:        the generic pointer points to a matrix if successful or a string if unsuccessful.
 */
void
pull_comb(struct db_i *dbip,
	  struct directory *dp,
	  genptr_t mp)
{
    struct rt_db_internal intern;
    struct rt_comb_internal *comb;
    matp_t mat = (matp_t)mp;
    mat_t m;
    mat_t invMat;

    if (dp->d_flags & RT_DIR_SOLID)
	return;
    if (rt_db_get_internal(&intern, dp, dbip, m, &rt_uniresource) < 0) {
	bu_log("Database read error, aborting\n");
	return;
    }

    comb = (struct rt_comb_internal *)intern.idb_ptr;

    /* checks if matrix pointer is valid */
    if (mat == NULL) {
	mat = (matp_t)bu_malloc(sizeof(mat_t), "cur_mat");
	MAT_IDN(mat);
    }

    bn_mat_inverse(invMat, mat);
    bn_mat_mul2(mat,m);
    MAT_COPY(mat, m);/* updates current matrix pointer */

    if (comb->tree) {
	db_tree_funcleaf(dbip, comb, comb->tree, pull_comb_mat,
			 &m, (genptr_t)NULL, (genptr_t)NULL, (genptr_t)NULL);

	if (rt_db_put_internal(dp, dbip, &intern, &rt_uniresource) < 0) {
	    bu_log("Cannot write modified combination (%s) to database\n", dp->d_namep);
	    return;
	}
    }
}


/* routine takes the maximum and minimum points from the AABB and determines the translation matrix
 * which moves the centrepoint to the origin and moves the primitive by the its inverse
 * before pulling the translation.
 */
void
translate(matp_t matrix, mat_t tm, point_t min, point_t max)
{
    vect_t c_pt;  /* centre point */
    mat_t t_mat;  /* temp matrix */
    vect_t t_vec; /* translation vector */
    
    /* computes the centrepoint from both minimum and maximum point
     * following this algorithm: cen[i] = bbx_min[i] + bbx_max[i]) / 2.0
     */
    VADD2(c_pt, max, min);
    VSCALE(c_pt, c_pt, 1/2);
    
    /* translates the centrepoint to the origin. and computes the inverse of this transformation which will be applied to the primitive */
    VREVERSE(t_vec, c_pt);
    MAT_DELTAS_VEC(t_mat, t_vec);
    MAT_DELTAS_VEC(matrix, t_vec);/* pulls translation component of primitive */
    
    /* copies transformation matrix whose inverse restores primitive and bbox */
    MAT_COPY(tm, t_mat);
    
    return;
}


/**
 * P U L L _ L E A F
 *
 * @brief
 * This routine takes the internal database representation of a leaf node or
 * primitive object and builds  a matrix transformation, closest to this node's,
 * sets these values to default and returns matrix.
 * Fixme: This routine only pulls translations up. So additional support for rotations/scale
 *        would be needed for further purposes.
 */
static void
pull_leaf(struct db_i *dbip, struct directory *dp, genptr_t mp)
{
    struct rt_db_internal intern;
    struct bn_tol tol;
    struct resource *resp;
    point_t min;             /* mininum point of bbox */
    point_t max;             /* maximum point of bbox */
    matp_t mat = (matp_t)mp; /* current transformation matrix */
    mat_t matrix, invXform;
    int ret;
    
    BN_TOL_INIT(&tol); /* initializes the tolerance */
    resp = &rt_uniresource;
    rt_init_resource( &rt_uniresource, 0, NULL );

    if (mat == NULL) {
	mat = (matp_t)bu_malloc(sizeof(mat_t), "cur_mat");
        MAT_IDN(mat);
    }

    if (!(dp->d_flags & RT_DIR_SOLID))
        return;
    if (rt_db_get_internal(&intern, dp, dbip, mat, &rt_uniresource) < 0) {
        bu_vls_printf(mp, "Database read error, aborting\n");
        return;
    }
    
    MAT_IDN(mat);
    MAT_IDN(matrix);
    
    /* this computes the AABB bounding box of the leaf object
     * using the bbox call back routine in its rt_functab table.
     * it then passes the minimum and maximum point to translate()
     * which then extracts the translation.
     */
    (intern.idb_meth)->ft_bbox(&intern, &min, &max, &tol);
    
    /* pulls primitive translation matrix copying inverse transformation to restore primitive and bbox */
    translate(mat,matrix, min, max);
    bn_mat_inverse(invXform, matrix);/* computes the inverse of transformation matrix. */
    
    ret = (intern.idb_meth)->ft_xform(&intern, invXform, &intern, 0, dbip, resp);/* restores the primitive */

    /* prints current matrix representing current primitive. */
    bn_mat_print("Leaf Matrix", mat); 
    
    return;
}



int
main(void)
{
  struct db_i *dbip;
  struct directory *dp;
  struct resource *resp;
  int l_ctr = 0, c_ctr = 0;
  mat_t cur_mat; /* holds the current tranformation matrix */
  MAT_IDN(cur_mat);
  
  bu_log("\n***************************************************************************************************"
         "\n****  This program tests the complete routine whether it successfully pulls a matrix transf  ******"
         "\n**** from a primitive node printing the matrices extracted and also counting the total number******"
         "\n****                       leaves traversed.                                                 ******"
         "\n****                 Author: Nyah Check, Developer @ BRL-CAD (c) 2013                        ******\n\n");
         
         
  
  dbip = db_open("/home/Ch3ck/Desktop/toy_truck.g", "rw");
  if (dbip == NULL) {
    bu_exit(1, "Unable to open %s\n", "/home/Ch3ck/Desktop/toy_truck.g");
  }
  
  if (db_dirbuild(dbip) < 0) {
    db_close(dbip);
    bu_exit(1, "Unable to load %s\n", "/home/Ch3ck/Desktop/toy_truck.g");
  }
  
  bu_log("Database title is:\n%s\n", dbip->dbi_title);
  bu_log("Units: %s\n", bu_units_string(dbip->dbi_local2base));

  if ((dp = db_lookup(dbip, "obj.c", 1)) == NULL) {
    db_close(dbip);
    bu_exit(1, "Unable to find %s\n", "obj.c");
  }

  resp = &rt_uniresource;
  rt_init_resource( &rt_uniresource, 0, NULL );
  
  /* walks up a db_tree counting the number of primitives encountered. */
  db_functree(dbip, dp,incr_comb,/* counts number of combinations. */
              incr_leaf, resp, &l_ctr); 
  
  /* recursively walks up a tree extracting and printing the matrix tranformations in leaves or primitive nodes. */
  db_functree(dbip, dp, pull_comb,
              pull_leaf,
              resp, &cur_mat);
              
  bu_log("Number of leaves encountered %d\n", l_ctr);

  return 0;
}
------------------------------------------------------------------------------
October Webinars: Code for Performance
Free Intel webinars can help you accelerate application performance.
Explore tips for MPI, OpenMP, advanced profiling, and more. Get the most from 
the latest Intel processors and coprocessors. See abstracts and register >
http://pubads.g.doubleclick.net/gampad/clk?id=60133471&iu=/4140/ostg.clktrk
_______________________________________________
BRL-CAD Developer mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/brlcad-devel

Reply via email to