dir.c

Go to the documentation of this file.
00001 /*                           D I R . C
00002  * BRL-CAD
00003  *
00004  * Copyright (c) 1985-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 /** @file dir.c
00025  * Ray Tracing program, GED database directory manager.
00026  *
00027  *  Functions -
00028  *      rt_dirbuild     Read GED database, build directory
00029  *
00030  *  Author -
00031  *      Michael John Muuss
00032  *
00033  *  Source -
00034  *      SECAD/VLD Computing Consortium, Bldg 394
00035  *      The U. S. Army Ballistic Research Laboratory
00036  *      Aberdeen Proving Ground, Maryland  21005
00037  *
00038  */
00039 
00040 #ifndef lint
00041 static const char RCSdir[] = "@(#)$Header: /cvsroot/brlcad/brlcad/src/librt/dir.c,v 14.14 2006/09/16 02:04:24 lbutler Exp $";
00042 #endif
00043 
00044 #include "common.h"
00045 
00046 
00047 
00048 #include <stdio.h>
00049 #ifdef HAVE_STRING_H
00050 #include <string.h>
00051 #else
00052 #include <strings.h>
00053 #endif
00054 #include "machine.h"
00055 #include "vmath.h"
00056 #include "raytrace.h"
00057 #include "./debug.h"
00058 
00059 /*
00060  *                      R T _ D I R B U I L D
00061  *
00062  *  Builds a directory of the object names.
00063  *
00064  *  Allocate and initialize information for this
00065  *  instance of an RT model database.
00066  *
00067  * Returns -
00068  *      (struct rt_i *) Success
00069  *      RTI_NULL        Fatal Error
00070  */
00071 struct rt_i *
00072 rt_dirbuild( const char *filename, char *buf, int len )
00073 {
00074         register struct rt_i    *rtip;
00075         register struct db_i    *dbip;          /* Database instance ptr */
00076 
00077         if( rt_uniresource.re_magic == 0 )
00078                 rt_init_resource( &rt_uniresource, 0, NULL );
00079 
00080         if( (dbip = db_open( filename, "r" )) == DBI_NULL )
00081                 return( RTI_NULL );             /* FAIL */
00082         RT_CK_DBI(dbip);
00083 
00084         if( db_dirbuild( dbip ) < 0 )  {
00085                 db_close( dbip );
00086                 return RTI_NULL;                /* FAIL */
00087         }
00088 
00089         rtip = rt_new_rti( dbip );              /* clones dbip */
00090         db_close(dbip);                         /* releases original dbip */
00091 
00092         if( buf != (char *)NULL )
00093                 strncpy( buf, dbip->dbi_title, len );
00094 
00095         return( rtip );                         /* OK */
00096 }
00097 
00098 /*
00099  *                      R T _ D B _ G E T _ I N T E R N A L
00100  *
00101  *  Get an object from the database, and convert it into it's internal
00102  *  representation.
00103  *
00104  *  Returns -
00105  *      <0      On error
00106  *      id      On success.
00107  */
00108 int
00109 rt_db_get_internal(
00110         struct rt_db_internal   *ip,
00111         const struct directory  *dp,
00112         const struct db_i       *dbip,
00113         const mat_t             mat,
00114         struct resource         *resp)
00115 {
00116         struct bu_external      ext;
00117         register int            id;
00118 
00119         BU_INIT_EXTERNAL(&ext);
00120         RT_INIT_DB_INTERNAL(ip);
00121 
00122         if( dbip->dbi_version > 4 )
00123                 return  rt_db_get_internal5( ip, dp, dbip, mat, resp );
00124 
00125         if( db_get_external( &ext, dp, dbip ) < 0 )
00126                 return -2;              /* FAIL */
00127 
00128         if( dp->d_flags & DIR_COMB )  {
00129                 id = ID_COMBINATION;
00130         } else {
00131                 /* As a convenience to older ft_import routines */
00132                 if( mat == NULL )  mat = bn_mat_identity;
00133                 id = rt_id_solid( &ext );
00134         }
00135 
00136         /* ip is already initialized and should not be re-initialized */
00137         if( rt_functab[id].ft_import( ip, &ext, mat, dbip, resp ) < 0 )  {
00138                 bu_log("rt_db_get_internal(%s):  import failure\n",
00139                         dp->d_namep );
00140                 rt_db_free_internal( ip, resp );
00141                 bu_free_external( &ext );
00142                 return -1;              /* FAIL */
00143         }
00144         bu_free_external( &ext );
00145         RT_CK_DB_INTERNAL( ip );
00146         ip->idb_meth = &rt_functab[id];
00147 
00148         /* prior to version 5, there are no attributes */
00149         bu_avs_init_empty( &ip->idb_avs );
00150 
00151         return id;                      /* OK */
00152 }
00153 
00154 /*
00155  *                      R T _ D B _ P U T _ I N T E R N A L
00156  *
00157  *  Convert the internal representation of a solid to the external one,
00158  *  and write it into the database.
00159  *  On success only, the internal representation is freed.
00160  *
00161  *  Returns -
00162  *      <0      error
00163  *       0      success
00164  */
00165 int
00166 rt_db_put_internal(
00167         struct directory        *dp,
00168         struct db_i             *dbip,
00169         struct rt_db_internal   *ip,
00170         struct resource         *resp)
00171 {
00172         struct bu_external      ext;
00173         int                     ret;
00174 
00175         BU_INIT_EXTERNAL(&ext);
00176         RT_CK_DB_INTERNAL( ip );
00177 
00178         if( dbip->dbi_version > 4 )
00179                 return  rt_db_put_internal5( dp, dbip, ip, resp,
00180                     DB5_MAJORTYPE_BRLCAD );
00181 
00182         /* Scale change on export is 1.0 -- no change */
00183         ret = ip->idb_meth->ft_export( &ext, ip, 1.0, dbip, resp );
00184         if( ret < 0 )  {
00185                 bu_log("rt_db_put_internal(%s):  solid export failure\n",
00186                         dp->d_namep);
00187                 rt_db_free_internal( ip, resp );
00188                 bu_free_external( &ext );
00189                 return -2;              /* FAIL */
00190         }
00191         rt_db_free_internal( ip, resp );
00192 
00193         if( db_put_external( &ext, dp, dbip ) < 0 )  {
00194                 bu_free_external( &ext );
00195                 return -1;              /* FAIL */
00196         }
00197 
00198         bu_free_external( &ext );
00199         return 0;                       /* OK */
00200 }
00201 
00202 /*
00203  *                      R T _ F W R I T E _ I N T E R N A L
00204  *
00205  *  Put an object in internal format out onto a file in external format.
00206  *  Used by LIBWDB.
00207  *
00208  *  Can't really require a dbip parameter, as many callers won't have one.
00209  *
00210  *  Returns -
00211  *      0       OK
00212  *      <0      error
00213  */
00214 int
00215 rt_fwrite_internal(
00216         FILE *fp,
00217         const char *name,
00218         const struct rt_db_internal *ip,
00219         double conv2mm )
00220 {
00221         struct bu_external      ext;
00222 
00223         RT_CK_DB_INTERNAL(ip);
00224         RT_CK_FUNCTAB( ip->idb_meth );
00225         BU_INIT_EXTERNAL( &ext );
00226 
00227         if( ip->idb_meth->ft_export( &ext, ip, conv2mm, NULL /*dbip*/, &rt_uniresource ) < 0 )  {
00228                 bu_log("rt_file_put_internal(%s): solid export failure\n",
00229                         name );
00230                 bu_free_external( &ext );
00231                 return(-2);                             /* FAIL */
00232         }
00233         BU_CK_EXTERNAL( &ext );
00234 
00235         if( db_fwrite_external( fp, name, &ext ) < 0 )  {
00236                 bu_log("rt_fwrite_internal(%s): db_fwrite_external() error\n",
00237                         name );
00238                 bu_free_external( &ext );
00239                 return(-3);
00240         }
00241         bu_free_external( &ext );
00242         return(0);
00243 
00244 }
00245 
00246 /*
00247  *                      R T _ D B _ F R E E _ I N T E R N A L
00248  */
00249 void
00250 rt_db_free_internal( struct rt_db_internal *ip, struct resource *resp )
00251 {
00252         RT_CK_DB_INTERNAL( ip );
00253 
00254         /* meth is not required since may be asked to free something
00255          * that was never set.
00256          */
00257         if (ip->idb_meth) {
00258             RT_CK_FUNCTAB(ip->idb_meth);
00259             if (ip->idb_ptr) {
00260                 ip->idb_meth->ft_ifree(ip, resp);
00261             }
00262         }
00263 
00264         /* resp is not checked, since most ifree's don't take/need it
00265          * (only combinations use it) -- leave it up to ft_ifree to check it
00266          */
00267         if( ip->idb_ptr )  {
00268             ip->idb_ptr = NULL;         /* sanity.  Should be handled by INIT, below */
00269         }
00270         if( ip->idb_avs.magic == BU_AVS_MAGIC ) {
00271             bu_avs_free(&ip->idb_avs);
00272         }
00273         RT_INIT_DB_INTERNAL(ip);
00274 }
00275 
00276 /*
00277  *              R T _ D B _ L O O K U P _ I N T E R N A L
00278  *
00279  *          Convert an object name to a rt_db_internal pointer
00280  *
00281  *      Looks up the named object in the directory of the specified model,
00282  *      obtaining a directory pointer.  Then gets that object from the
00283  *      database and constructs its internal representation.  Returns
00284  *      ID_NULL on error, otherwise returns the type of the object.
00285  */
00286 int
00287 rt_db_lookup_internal (
00288         struct db_i *dbip,
00289         const char *obj_name,
00290         struct directory **dpp,
00291         struct rt_db_internal *ip,
00292         int noisy,
00293         struct resource *resp)
00294 {
00295     struct directory            *dp;
00296 
00297     if (obj_name == (char *) 0)
00298     {
00299         if (noisy == LOOKUP_NOISY)
00300             bu_log("rt_db_lookup_internal() No object specified\n");
00301         return ID_NULL;
00302     }
00303     if ((dp = db_lookup(dbip, obj_name, noisy)) == DIR_NULL)
00304         return ID_NULL;
00305     if (rt_db_get_internal(ip, dp, dbip, (matp_t) NULL, resp ) < 0 )
00306     {
00307         if (noisy == LOOKUP_NOISY)
00308             bu_log("rt_db_lookup_internal() Failed to get internal form of object '%s'\n",
00309                 dp -> d_namep);
00310         return ID_NULL;
00311     }
00312 
00313     *dpp = dp;
00314     return (ip -> idb_type);
00315 }
00316 
00317 /*@}*/
00318 /*
00319  * Local Variables:
00320  * mode: C
00321  * tab-width: 8
00322  * c-basic-offset: 4
00323  * indent-tabs-mode: t
00324  * End:
00325  * ex: shiftwidth=4 tabstop=8
00326  */

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