00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037 #ifndef lint
00038 static const char RCSid[] = "@(#)$Header: /cvsroot/brlcad/brlcad/src/librt/wdb.c,v 14.13 2006/09/16 02:04:26 lbutler Exp $ (ARL)";
00039 #endif
00040
00041 #include "common.h"
00042
00043 #include <stdio.h>
00044 #include <math.h>
00045
00046 #include "machine.h"
00047 #include "bu.h"
00048 #include "vmath.h"
00049 #include "bn.h"
00050 #include "rtgeom.h"
00051 #include "raytrace.h"
00052 #include "wdb.h"
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065 struct rt_wdb *
00066 wdb_fopen_v( const char *filename, int version )
00067 {
00068 struct db_i *dbip;
00069
00070 if( rt_uniresource.re_magic != RESOURCE_MAGIC )
00071 rt_init_resource( &rt_uniresource, 0, NULL );
00072
00073 if( (dbip = db_create( filename, version )) == DBI_NULL )
00074 return RT_WDB_NULL;
00075
00076 return wdb_dbopen( dbip, RT_WDB_TYPE_DB_DISK );
00077 }
00078
00079 struct rt_wdb *
00080 wdb_fopen( const char *filename)
00081 {
00082 return wdb_fopen_v(filename, 5);
00083 }
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096 struct rt_wdb *
00097 wdb_dbopen( struct db_i *dbip, int mode )
00098 {
00099 struct rt_wdb *wdbp;
00100
00101 RT_CK_DBI(dbip);
00102
00103 if (mode != RT_WDB_TYPE_DB_DISK && mode != RT_WDB_TYPE_DB_DISK_APPEND_ONLY &&
00104 mode != RT_WDB_TYPE_DB_INMEM && mode != RT_WDB_TYPE_DB_INMEM_APPEND_ONLY) {
00105 bu_log("wdb_dbopen(%s) mode %d unknown\n",
00106 dbip->dbi_filename, mode );
00107 return RT_WDB_NULL;
00108 }
00109
00110 #if 0
00111 if( (mode == RT_WDB_TYPE_DB_DISK || mode == RT_WDB_TYPE_DB_DISK_APPEND_ONLY ) &&
00112 dbip->dbi_read_only ) {
00113
00114 bu_log("wdb_dbopen(%s): read-only\n",
00115 dbip->dbi_filename );
00116 }
00117 #endif
00118
00119 if( rt_uniresource.re_magic != RESOURCE_MAGIC )
00120 rt_init_resource( &rt_uniresource, 0, NULL );
00121
00122 BU_GETSTRUCT(wdbp, rt_wdb);
00123 wdbp->l.magic = RT_WDB_MAGIC;
00124 wdbp->type = mode;
00125 wdbp->dbip = dbip;
00126 wdbp->dbip->dbi_wdbp = wdbp;
00127
00128
00129 wdbp->wdb_tol.magic = BN_TOL_MAGIC;
00130 wdbp->wdb_tol.dist = 0.005;
00131 wdbp->wdb_tol.dist_sq = wdbp->wdb_tol.dist * wdbp->wdb_tol.dist;
00132 wdbp->wdb_tol.perp = 1e-6;
00133 wdbp->wdb_tol.para = 1 - wdbp->wdb_tol.perp;
00134
00135 wdbp->wdb_ttol.magic = RT_TESS_TOL_MAGIC;
00136 wdbp->wdb_ttol.abs = 0.0;
00137 wdbp->wdb_ttol.rel = 0.01;
00138 wdbp->wdb_ttol.norm = 0;
00139 bu_vls_init( &wdbp->wdb_prestr );
00140
00141 return wdbp;
00142
00143 }
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157 int
00158 wdb_import(struct rt_wdb *wdbp, struct rt_db_internal *internp, const char *name, const mat_t mat )
00159 {
00160 struct directory *dp;
00161
00162 if( (dp = db_lookup( wdbp->dbip, name, LOOKUP_QUIET )) == DIR_NULL )
00163 return -4;
00164
00165 return rt_db_get_internal( internp, dp, wdbp->dbip, mat, &rt_uniresource );
00166 }
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177 int
00178 wdb_export_external(
00179 struct rt_wdb *wdbp,
00180 struct bu_external *ep,
00181 const char *name,
00182 int flags,
00183 unsigned char type)
00184 {
00185 struct directory *dp;
00186
00187 RT_CK_WDB(wdbp);
00188 BU_CK_EXTERNAL(ep);
00189
00190
00191 if( wdbp->dbip->dbi_version <= 4 ) {
00192 db_wrap_v4_external( ep, name );
00193 } else if( wdbp->dbip->dbi_version == 5 ) {
00194 if( db_wrap_v5_external( ep, name ) < 0 ) {
00195 bu_log("wdb_export_external(%s): db_wrap_v5_external error\n",
00196 name );
00197 return -4;
00198 }
00199 } else {
00200 bu_log("wdb_export_external(%s): version %d unsupported\n",
00201 name, wdbp->dbip->dbi_version );
00202 return -4;
00203 }
00204
00205 switch( wdbp->type ) {
00206
00207 case RT_WDB_TYPE_DB_DISK:
00208 if( wdbp->dbip->dbi_read_only ) {
00209 bu_log("wdb_export_external(%s): read-only database, write aborted\n");
00210 return -5;
00211 }
00212
00213 dp = db_lookup( wdbp->dbip, name, LOOKUP_QUIET );
00214 if( dp == DIR_NULL ) {
00215 if( (dp = db_diradd( wdbp->dbip, name, -1L, 0, flags,
00216 (genptr_t)&type )) == DIR_NULL ) {
00217 bu_log("wdb_export_external(%s): db_diradd error\n",
00218 name );
00219 return -3;
00220 }
00221 }
00222 dp->d_flags = (dp->d_flags & ~7) | flags;
00223 if( db_put_external( ep, dp, wdbp->dbip ) < 0 ) {
00224 bu_log("wdb_export_external(%s): db_put_external error\n",
00225 name );
00226 return -3;
00227 }
00228 break;
00229
00230 case RT_WDB_TYPE_DB_DISK_APPEND_ONLY:
00231 if( wdbp->dbip->dbi_read_only ) {
00232 bu_log("wdb_export_external(%s): read-only database, write aborted\n");
00233 return -5;
00234 }
00235
00236 if( (dp = db_diradd( wdbp->dbip, name, -1L, 0, flags,
00237 (genptr_t)&type )) == DIR_NULL ) {
00238 bu_log("wdb_export_external(%s): db_diradd error\n",
00239 name );
00240 return -3;
00241 }
00242 if( db_put_external( ep, dp, wdbp->dbip ) < 0 ) {
00243 bu_log("wdb_export_external(%s): db_put_external error\n",
00244 name );
00245 return -3;
00246 }
00247 break;
00248
00249 case RT_WDB_TYPE_DB_INMEM_APPEND_ONLY:
00250 if( (dp = db_lookup( wdbp->dbip, name, 0 )) != DIR_NULL ) {
00251 bu_log("wdb_export_external(%s): ERROR, that name is already in use, and APPEND_ONLY mode has been specified.\n",
00252 name );
00253 return -3;
00254 }
00255 if( (dp = db_diradd( wdbp->dbip, name, -1L, 0, flags,
00256 (genptr_t)&type )) == DIR_NULL ) {
00257 bu_log("wdb_export_external(%s): db_diradd error\n",
00258 name );
00259 return -3;
00260 }
00261
00262 db_inmem( dp, ep, flags, wdbp->dbip );
00263
00264 break;
00265
00266 case RT_WDB_TYPE_DB_INMEM:
00267 if( (dp = db_lookup( wdbp->dbip, name, 0 )) == DIR_NULL ) {
00268 if( (dp = db_diradd( wdbp->dbip, name, -1L, 0, flags,
00269 (genptr_t)&type )) == DIR_NULL ) {
00270 bu_log("wdb_export_external(%s): db_diradd error\n",
00271 name );
00272 bu_free_external( ep );
00273 return -3;
00274 }
00275 } else {
00276 dp->d_flags = (dp->d_flags & ~7) | flags;
00277 }
00278
00279 db_inmem( dp, ep, flags, wdbp->dbip );
00280
00281 break;
00282 }
00283
00284 return 0;
00285 }
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304 int
00305 wdb_put_internal(
00306 struct rt_wdb *wdbp,
00307 const char *name,
00308 struct rt_db_internal *ip,
00309 double local2mm )
00310 {
00311 struct bu_external ext;
00312 int ret;
00313 int flags;
00314
00315 RT_CK_WDB(wdbp);
00316 RT_CK_DB_INTERNAL(ip);
00317
00318 if( wdbp->dbip->dbi_version <= 4 ) {
00319 BU_INIT_EXTERNAL( &ext );
00320 ret = ip->idb_meth->ft_export( &ext, ip, local2mm, wdbp->dbip, &rt_uniresource );
00321 if( ret < 0 ) {
00322 bu_log("rt_db_put_internal(%s): solid export failure\n",
00323 name);
00324 ret = -1;
00325 goto out;
00326 }
00327 db_wrap_v4_external( &ext, name );
00328 } else {
00329 if( rt_db_cvt_to_external5( &ext, name, ip, local2mm, wdbp->dbip, &rt_uniresource, ip->idb_major_type ) < 0 ) {
00330 bu_log("wdb_export(%s): solid export failure\n",
00331 name );
00332 ret = -2;
00333 goto out;
00334 }
00335 }
00336 BU_CK_EXTERNAL( &ext );
00337
00338 flags = db_flags_internal( ip );
00339 ret = wdb_export_external( wdbp, &ext, name, flags, ip->idb_type );
00340 out:
00341 bu_free_external( &ext );
00342 rt_db_free_internal( ip, &rt_uniresource );
00343 return ret;
00344 }
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366 int
00367 wdb_export(
00368 struct rt_wdb *wdbp,
00369 const char *name,
00370 genptr_t gp,
00371 int id,
00372 double local2mm )
00373 {
00374 struct rt_db_internal intern;
00375
00376 RT_CK_WDB(wdbp);
00377
00378 if( (id <= 0 || id > ID_MAX_SOLID) && id != ID_COMBINATION ) {
00379 bu_log("wdb_export(%s): id=%d bad\n",
00380 name, id );
00381 return(-1);
00382 }
00383
00384 RT_INIT_DB_INTERNAL( &intern );
00385 intern.idb_major_type = DB5_MAJORTYPE_BRLCAD;
00386 intern.idb_type = id;
00387 intern.idb_ptr = gp;
00388 intern.idb_meth = &rt_functab[id];
00389
00390 return wdb_put_internal( wdbp, name, &intern, local2mm );
00391 }
00392
00393
00394
00395
00396
00397
00398 void
00399 wdb_close( struct rt_wdb *wdbp )
00400 {
00401
00402 RT_CK_WDB(wdbp);
00403
00404
00405
00406 db_close( wdbp->dbip );
00407
00408 bu_vls_free( &wdbp->wdb_prestr );
00409 bu_free( (genptr_t)wdbp, "struct rt_wdb");
00410 }
00411
00412
00413
00414
00415
00416
00417
00418
00419
00420