db_walk.c

Go to the documentation of this file.
00001 /*                       D B _ W A L K . C
00002  * BRL-CAD
00003  *
00004  * Copyright (c) 1988-2006 United States Government as represented by
00005  * the U.S. Army Research Laboratory.
00006  *
00007  * This library is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU Lesser General Public License
00009  * as published by the Free Software Foundation; either version 2 of
00010  * the License, or (at your option) any later version.
00011  *
00012  * This library is distributed in the hope that it will be useful, but
00013  * WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015  * Library General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU Lesser General Public
00018  * License along with this file; see the file named COPYING for more
00019  * information.
00020  */
00021 
00022 /** @addtogroup dbio */
00023 
00024 /*@{*/
00025 /** @file db_walk.c
00026  *
00027  * Functions -
00028  *      db_functree     No-frills tree-walk
00029  *      comb_functree   No-frills combination-walk (deprecated)
00030  *
00031  *
00032  *  Authors -
00033  *      Michael John Muuss
00034  *      John R. Anderson
00035  *
00036  *  Source -
00037  *      SECAD/VLD Computing Consortium, Bldg 394
00038  *      The U. S. Army Ballistic Research Laboratory
00039  *      Aberdeen Proving Ground, Maryland  21005-5066
00040  *
00041  */
00042 
00043 #ifndef lint
00044 static const char RCSid[] = "@(#)$Header: /cvsroot/brlcad/brlcad/src/librt/db_walk.c,v 14.13 2006/09/16 02:04:24 lbutler Exp $ (BRL)";
00045 #endif
00046 
00047 #include "common.h"
00048 
00049 
00050 
00051 #include <stdio.h>
00052 #ifdef HAVE_STRING_H
00053 #include <string.h>
00054 #else
00055 #include <strings.h>
00056 #endif
00057 
00058 #include "machine.h"
00059 #include "vmath.h"
00060 #include "db.h"
00061 #include "raytrace.h"
00062 
00063 #include "./debug.h"
00064 
00065 /*
00066  *          D B _ T R A V E R S E _ S U B T R E E
00067  *
00068  *  A generic traversal function.
00069  *
00070  */
00071 void
00072 db_traverse_subtree(union tree *tp,
00073                     void (*traverse_func) ( struct directory *, struct db_traverse * ),
00074                     struct db_traverse *dtp)
00075 {
00076     struct directory *dp;
00077 
00078     if( !tp )
00079         return;
00080 
00081     RT_CK_DBTR( dtp );
00082     RT_CHECK_DBI( dtp->dbip );
00083     RT_CK_TREE( tp );
00084     RT_CK_RESOURCE( dtp->resp );
00085 
00086     switch( tp->tr_op )  {
00087 
00088         case OP_DB_LEAF:
00089             if( (dp=db_lookup( dtp->dbip, tp->tr_l.tl_name, LOOKUP_NOISY )) == DIR_NULL )
00090                 return;
00091             traverse_func( dp, dtp );
00092             break;
00093 
00094         case OP_UNION:
00095         case OP_INTERSECT:
00096         case OP_SUBTRACT:
00097         case OP_XOR:
00098             db_traverse_subtree( tp->tr_b.tb_left, traverse_func, dtp );
00099             db_traverse_subtree( tp->tr_b.tb_right, traverse_func, dtp );
00100             break;
00101         default:
00102             bu_log( "db_functree_subtree: unrecognized operator %d\n", tp->tr_op );
00103             bu_bomb( "db_functree_subtree: unrecognized operator\n" );
00104     }
00105 }
00106 
00107 /*
00108  *     D B _ P R E O R D E R _ T R A V E R S E
00109  *
00110  *  This subroutine is called for a no-frills tree-walk,
00111  *  with the provided subroutines being called when entering and 
00112  *  exiting combinations and at leaf (solid) nodes.
00113  *
00114  *  This routine is recursive, so no variables may be declared static.
00115  *
00116  */
00117 void
00118 db_preorder_traverse( struct directory *dp,
00119                       struct db_traverse *dtp )
00120 {
00121     register int i;
00122     RT_CK_DBTR(dtp);
00123     RT_CK_DBI(dtp->dbip);
00124 
00125     if (RT_G_DEBUG & DEBUG_DB)
00126         bu_log("db_preorder_traverse(%s) x%x, x%x, comb_enter=x%x, comb_exit=x%x, leaf=x%x, client_data=x%x\n",
00127                 dp->d_namep, dtp->dbip, dp, dtp->comb_enter_func, dtp->comb_exit_func, dtp->leaf_func, dtp->client_data );
00128 
00129     if ( dp->d_flags & DIR_COMB )  {
00130         /* entering region */
00131         if( dtp->comb_enter_func )
00132             dtp->comb_enter_func( dtp->dbip, dp, dtp->client_data );
00133         if ( dtp->dbip->dbi_version < 5 ) {
00134             register union record   *rp;
00135             register struct directory *mdp;
00136             /*
00137              * Load the combination into local record buffer
00138              * This is in external v4 format.
00139              */
00140             if( (rp = db_getmrec( dtp->dbip, dp )) == (union record *)0 )
00141                 return;
00142             /* recurse */
00143             for( i=1; i < dp->d_len; i++ )  {
00144                 if( (mdp = db_lookup( dtp->dbip, rp[i].M.m_instname,
00145                                 LOOKUP_NOISY )) == DIR_NULL )
00146                     continue;
00147                 db_preorder_traverse( mdp, dtp );
00148             }
00149             bu_free( (char *)rp, "db_preorder_traverse[]" );
00150         } else {
00151             struct rt_db_internal in;
00152             struct rt_comb_internal *comb;
00153             struct directory *ndp;
00154 
00155             if( rt_db_get_internal5( &in, dp, dtp->dbip, NULL, dtp->resp ) < 0 )
00156                 return;
00157 
00158             comb = (struct rt_comb_internal *)in.idb_ptr;
00159 
00160             db_traverse_subtree( comb->tree, db_preorder_traverse, dtp );
00161 
00162             rt_db_free_internal( &in, dtp->resp );
00163         }
00164         /* exiting region */
00165         if( dtp->comb_exit_func )
00166             dtp->comb_exit_func( dtp->dbip, dp, dtp->client_data );
00167     } else if( dp->d_flags & DIR_SOLID || dp->d_major_type & DB5_MAJORTYPE_BINARY_MASK )  {
00168         /* at leaf */
00169         if( dtp->leaf_func )
00170             dtp->leaf_func( dtp->dbip, dp, dtp->client_data );
00171     } else {
00172         bu_log("db_preorder_traverse:  %s is neither COMB nor SOLID?\n",
00173                 dp->d_namep );
00174     }
00175 }
00176 
00177  
00178 
00179 
00180 /*      D B _ F U N C T R E E _ S U B T R E E
00181  *
00182  *      The only reason for this to be broken out is that
00183  *      2 separate locations in db_functree() call it.
00184  */
00185 void
00186 db_functree_subtree(struct db_i *dbip,
00187                     union tree *tp,
00188                     void (*comb_func) (struct db_i *, struct directory *, genptr_t),
00189                     void (*leaf_func) (struct db_i *, struct directory *, genptr_t),
00190                     struct resource *resp,
00191                     genptr_t client_data)
00192 {
00193     struct directory *dp;
00194 
00195     if( !tp )
00196         return;
00197 
00198     RT_CHECK_DBI( dbip );
00199     RT_CK_TREE( tp );
00200     RT_CK_RESOURCE( resp );
00201 
00202     switch( tp->tr_op )  {
00203 
00204         case OP_DB_LEAF:
00205             if( (dp=db_lookup( dbip, tp->tr_l.tl_name, LOOKUP_NOISY )) == DIR_NULL )
00206                 return;
00207             db_functree( dbip, dp, comb_func, leaf_func, resp, client_data);
00208             break;
00209 
00210         case OP_UNION:
00211         case OP_INTERSECT:
00212         case OP_SUBTRACT:
00213         case OP_XOR:
00214             db_functree_subtree( dbip, tp->tr_b.tb_left, comb_func, leaf_func, resp, client_data );
00215             db_functree_subtree( dbip, tp->tr_b.tb_right, comb_func, leaf_func, resp, client_data );
00216             break;
00217         default:
00218             bu_log( "db_functree_subtree: unrecognized operator %d\n", tp->tr_op );
00219             bu_bomb( "db_functree_subtree: unrecognized operator\n" );
00220     }
00221 }
00222 
00223 /**
00224  *                      D B _ F U N C T R E E
00225  *
00226  *  This subroutine is called for a no-frills tree-walk,
00227  *  with the provided subroutines being called at every combination
00228  *  and leaf (solid) node, respectively.
00229  *
00230  *  This routine is recursive, so no variables may be declared static.
00231  *
00232  */
00233 void
00234 db_functree(struct db_i *dbip,
00235             struct directory *dp,
00236             void (*comb_func) (struct db_i *, struct directory *, genptr_t),
00237             void (*leaf_func) (struct db_i *, struct directory *, genptr_t),
00238             struct resource *resp,
00239             genptr_t client_data)
00240 {
00241     register int                i;
00242 
00243     RT_CK_DBI(dbip);
00244     if(RT_G_DEBUG&DEBUG_DB) bu_log("db_functree(%s) x%x, x%x, comb=x%x, leaf=x%x, client_data=x%x\n",
00245                                    dp->d_namep, dbip, dp, comb_func, leaf_func, client_data );
00246 
00247     if( dp->d_flags & DIR_COMB )  {
00248         if( dbip->dbi_version < 5 ) {
00249             register union record       *rp;
00250             register struct directory *mdp;
00251             /*
00252              * Load the combination into local record buffer
00253              * This is in external v4 format.
00254              */
00255             if( (rp = db_getmrec( dbip, dp )) == (union record *)0 )
00256                 return;
00257 
00258             /* recurse */
00259             for( i=1; i < dp->d_len; i++ )  {
00260                 if( (mdp = db_lookup( dbip, rp[i].M.m_instname, LOOKUP_NOISY )) == DIR_NULL )
00261                     continue;
00262                 db_functree( dbip, mdp, comb_func, leaf_func, resp, client_data );
00263             }
00264             bu_free( (char *)rp, "db_functree record[]" );
00265         } else {
00266             struct rt_db_internal in;
00267             struct rt_comb_internal *comb;
00268 
00269             if( rt_db_get_internal5( &in, dp, dbip, NULL, resp ) < 0 )
00270                 return;
00271 
00272             comb = (struct rt_comb_internal *)in.idb_ptr;
00273             db_functree_subtree( dbip, comb->tree, comb_func, leaf_func, resp, client_data );
00274             rt_db_free_internal( &in, resp );
00275         }
00276 
00277         /* Finally, the combination itself */
00278         if( comb_func )
00279             comb_func( dbip, dp, client_data );
00280 
00281     } else if( dp->d_flags & DIR_SOLID || dp->d_major_type & DB5_MAJORTYPE_BINARY_MASK )  {
00282         if( leaf_func )
00283             leaf_func( dbip, dp, client_data );
00284     } else {
00285         bu_log("db_functree:  %s is neither COMB nor SOLID?\n",
00286                dp->d_namep );
00287     }
00288 }
00289 
00290 /*@}*/
00291 /*
00292  * Local Variables:
00293  * mode: C
00294  * tab-width: 8
00295  * c-basic-offset: 4
00296  * indent-tabs-mode: t
00297  * End:
00298  * ex: shiftwidth=4 tabstop=8
00299  */

Generated on Mon Sep 18 01:24:49 2006 for BRL-CAD by  doxygen 1.4.6