BRL-CAD
wdb.c
Go to the documentation of this file.
1 /* W D B . C
2  * BRL-CAD
3  *
4  * Copyright (c) 2000-2014 United States Government as represented by
5  * the U.S. Army Research Laboratory.
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public License
9  * version 2.1 as published by the Free Software Foundation.
10  *
11  * This library is distributed in the hope that it will be useful, but
12  * WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this file; see the file named COPYING for more
18  * information.
19  */
20 
21 
22 #include "common.h"
23 
24 #include <stdlib.h>
25 #include <string.h>
26 #include <math.h>
27 #include "bio.h"
28 
29 
30 #include "vmath.h"
31 #include "bn.h"
32 #include "rtgeom.h"
33 #include "raytrace.h"
34 #include "wdb.h"
35 
36 
37 struct rt_wdb *
38 wdb_fopen_v(const char *filename, int version)
39 {
40  struct db_i *dbip;
41 
42  if ( filename == NULL ) return RT_WDB_NULL;
43 
46  }
47 
48  if ((dbip = db_create(filename, version)) == DBI_NULL)
49  return RT_WDB_NULL;
50 
51  return wdb_dbopen(dbip, RT_WDB_TYPE_DB_DISK);
52 }
53 
54 
55 struct rt_wdb *
56 wdb_fopen(const char *filename)
57 {
58  if ( filename == NULL ) return RT_WDB_NULL;
59  return wdb_fopen_v(filename, 5);
60 }
61 
62 
63 struct rt_wdb *
64 wdb_dbopen(struct db_i *dbip, int mode)
65 {
66  struct rt_wdb *wdbp;
67 
68  RT_CK_DBI(dbip);
69 
70  if ((mode != RT_WDB_TYPE_DB_DISK) &&
72  (mode != RT_WDB_TYPE_DB_INMEM) &&
74  {
75  bu_log("wdb_dbopen(%s) mode %d unknown\n",
76  dbip->dbi_filename, mode);
77  return RT_WDB_NULL;
78  }
79 
82 
83  BU_ALLOC(wdbp, struct rt_wdb);
84  wdb_init(wdbp, dbip, mode);
85 
86  return wdbp;
87 
88 }
89 
90 
91 int
92 wdb_import(struct rt_wdb *wdbp, struct rt_db_internal *internp, const char *name, const mat_t mat)
93 {
94  struct directory *dp;
95 
96  dp = db_lookup(wdbp->dbip, name, LOOKUP_QUIET);
97  if (dp == RT_DIR_NULL)
98  return -4;
99 
100  return rt_db_get_internal(internp, dp, wdbp->dbip, mat, &rt_uniresource);
101 }
102 
103 
104 int
106  struct rt_wdb *wdbp,
107  struct bu_external *ep,
108  const char *name,
109  int flags,
110  unsigned char type)
111 {
112  struct directory *dp;
113  int version;
114 
115  RT_CK_WDB(wdbp);
116  BU_CK_EXTERNAL(ep);
117 
118  /* Stash name into external representation */
119  version = db_version(wdbp->dbip);
120  if (version < 5) {
121  db_wrap_v4_external(ep, name);
122  } else if (version == 5) {
123  if (db_wrap_v5_external(ep, name) < 0) {
124  bu_log("wdb_export_external(%s): db_wrap_v5_external error\n",
125  name);
126  return -4;
127  }
128  } else {
129  bu_log("wdb_export_external(%s): version %d unsupported\n",
130  name, version);
131  return -4;
132  }
133 
134  switch (wdbp->type) {
135 
136  case RT_WDB_TYPE_DB_DISK:
137  if (wdbp->dbip->dbi_read_only) {
138  bu_log("wdb_export_external(%s): read-only database, write aborted\n", name);
139  return -5;
140  }
141  /* If name already exists, that object will be updated. */
142  dp = db_lookup(wdbp->dbip, name, LOOKUP_QUIET);
143  if (dp == RT_DIR_NULL) {
144  if ((dp = db_diradd(wdbp->dbip, name, RT_DIR_PHONY_ADDR, 0, flags, (void *)&type)) == RT_DIR_NULL) {
145  bu_log("wdb_export_external(%s): db_diradd error\n", name);
146  return -3;
147  }
148  }
149  /* keep the caller's flags, except we don't want to
150  * pretend a disk dp is an inmem dp. the data is
151  * read/written differently for both.
152  */
153  dp->d_flags = (dp->d_flags & ~7) | (flags & ~(RT_DIR_INMEM));
154  if (db_put_external(ep, dp, wdbp->dbip) < 0) {
155  bu_log("wdb_export_external(%s): db_put_external error\n",
156  name);
157  return -3;
158  }
159  break;
160 
162  if (wdbp->dbip->dbi_read_only) {
163  bu_log("wdb_export_external(%s): read-only database, write aborted\n", name);
164  return -5;
165  }
166  /* If name already exists, new non-conflicting name will be generated */
167  if ((dp = db_diradd(wdbp->dbip, name, RT_DIR_PHONY_ADDR, 0, flags, (void *)&type)) == RT_DIR_NULL) {
168  bu_log("wdb_export_external(%s): db_diradd error\n", name);
169  return -3;
170  }
171  if (db_put_external(ep, dp, wdbp->dbip) < 0) {
172  bu_log("wdb_export_external(%s): db_put_external error\n",
173  name);
174  return -3;
175  }
176  break;
177 
179  dp = db_lookup(wdbp->dbip, name, 0);
180  if (dp != RT_DIR_NULL) {
181  bu_log("wdb_export_external(%s): ERROR, that name is already in use, and APPEND_ONLY mode has been specified.\n", name);
182  return -3;
183  }
184  dp = db_diradd(wdbp->dbip, name, RT_DIR_PHONY_ADDR, 0, flags, (void *)&type);
185  if (dp == RT_DIR_NULL) {
186  bu_log("wdb_export_external(%s): db_diradd error\n",
187  name);
188  return -3;
189  }
190 
191  db_inmem(dp, ep, flags, wdbp->dbip);
192  /* ep->buf has been stolen, replaced with null. */
193  break;
194 
196  dp = db_lookup(wdbp->dbip, name, 0);
197  if (dp == RT_DIR_NULL) {
198  dp = db_diradd(wdbp->dbip, name, RT_DIR_PHONY_ADDR, 0, flags, (void *)&type);
199  if (dp == RT_DIR_NULL) {
200  bu_log("wdb_export_external(%s): db_diradd error\n", name);
201  bu_free_external(ep);
202  return -3;
203  }
204  } else {
205  dp->d_flags = (dp->d_flags & ~7) | flags;
206  }
207 
208  db_inmem(dp, ep, flags, wdbp->dbip);
209  /* ep->buf has been stolen, replaced with null. */
210  break;
211  }
212 
213  return 0;
214 }
215 
216 
217 int
219  struct rt_wdb *wdbp,
220  const char *name,
221  struct rt_db_internal *ip,
222  double local2mm)
223 {
224  struct bu_external ext;
225  int ret;
226  int flags;
227 
228  RT_CK_WDB(wdbp);
229  RT_CK_DB_INTERNAL(ip);
230 
231  if (db_version(wdbp->dbip) < 5) {
232  BU_EXTERNAL_INIT(&ext);
233 
234  ret = -1;
235  if (ip->idb_meth && ip->idb_meth->ft_export4) {
236  ret = ip->idb_meth->ft_export4(&ext, ip, local2mm, wdbp->dbip, &rt_uniresource);
237  }
238  if (ret < 0) {
239  bu_log("rt_db_put_internal(%s): solid export failure\n",
240  name);
241  ret = -1;
242  goto out;
243  }
244  db_wrap_v4_external(&ext, name);
245  } else {
246  if (rt_db_cvt_to_external5(&ext, name, ip, local2mm, wdbp->dbip, &rt_uniresource, ip->idb_major_type) < 0) {
247  bu_log("wdb_export(%s): solid export failure\n",
248  name);
249  ret = -2;
250  goto out;
251  }
252  }
253  BU_CK_EXTERNAL(&ext);
254 
255  flags = db_flags_internal(ip);
256  ret = wdb_export_external(wdbp, &ext, name, flags, ip->idb_type);
257 out:
258  bu_free_external(&ext);
260  return ret;
261 }
262 
263 
264 int
266  struct rt_wdb *wdbp,
267  const char *name,
268  void *gp,
269  int id,
270  double local2mm)
271 {
272  struct rt_db_internal intern;
273 
274  RT_CK_WDB(wdbp);
275 
276  if ((id <= 0 || id > ID_MAX_SOLID) && id != ID_COMBINATION) {
277  bu_log("wdb_export(%s): id=%d bad\n",
278  name, id);
279  return -1;
280  }
281 
282  RT_DB_INTERNAL_INIT(&intern);
283  intern.idb_major_type = DB5_MAJORTYPE_BRLCAD;
284  intern.idb_type = id;
285  intern.idb_ptr = gp;
286  intern.idb_meth = &OBJ[id];
287 
288  return wdb_put_internal(wdbp, name, &intern, local2mm);
289 }
290 
291 
292 void
293 wdb_init(struct rt_wdb *wdbp, struct db_i *dbip, int mode)
294 {
296 
297  wdbp->type = mode;
298  wdbp->dbip = dbip;
299  wdbp->dbip->dbi_wdbp = wdbp;
300 
301  /* Provide the same default tolerance that librt/prep.c does */
302  wdbp->wdb_tol.magic = BN_TOL_MAGIC;
303  wdbp->wdb_tol.dist = 0.0005;
304  wdbp->wdb_tol.dist_sq = wdbp->wdb_tol.dist * wdbp->wdb_tol.dist;
305  wdbp->wdb_tol.perp = 1e-6;
306  wdbp->wdb_tol.para = 1 - wdbp->wdb_tol.perp;
307 
309  wdbp->wdb_ttol.abs = 0.0;
310  wdbp->wdb_ttol.rel = 0.01;
311  wdbp->wdb_ttol.norm = 0;
312 
313  bu_vls_init(&wdbp->wdb_name);
314  bu_vls_init(&wdbp->wdb_prestr);
315 
316  /* initialize tree state */
317  wdbp->wdb_initial_tree_state = rt_initial_tree_state; /* struct copy */
318  wdbp->wdb_initial_tree_state.ts_ttol = &wdbp->wdb_ttol;
319  wdbp->wdb_initial_tree_state.ts_tol = &wdbp->wdb_tol;
320 
321  /* default region ident codes */
322  wdbp->wdb_item_default = 1000;
323  wdbp->wdb_air_default = 0;
324  wdbp->wdb_mat_default = 1;
325  wdbp->wdb_los_default = 100;
326 
327  /* resource structure */
328  wdbp->wdb_resp = &rt_uniresource;
329 }
330 
331 
332 void
333 wdb_close(struct rt_wdb *wdbp)
334 {
335 
336  RT_CK_WDB(wdbp);
337 
338  BU_LIST_DEQUEUE(&wdbp->l);
339  BU_LIST_MAGIC_SET(&wdbp->l, 0); /* sanity */
340 
341  /* XXX Flush any unwritten "struct matter" records here */
342 
343  if (wdbp->dbip) {
344  db_close(wdbp->dbip);
345  wdbp->dbip = NULL;
346  }
347 
348  /* release allocated member memory */
349  bu_vls_free(&wdbp->wdb_name);
350  bu_vls_free(&wdbp->wdb_prestr);
351 
352  /* sanity */
353  wdbp->type = 0;
354  wdbp->wdb_resp = NULL;
355  wdbp->wdb_interp = NULL;
356 
357  /* release memory */
358  bu_free((void *)wdbp, "struct rt_wdb");
359  wdbp = NULL;
360 }
361 
362 
363 int
364 wdb_import_from_path2(struct bu_vls *logstr, struct rt_db_internal *ip, const char *path, struct rt_wdb *wdb, matp_t matp)
365 {
366  struct db_i *dbip;
367  int status;
368 
369  /* Can't run RT_CK_DB_INTERNAL(ip), it hasn't been filled in yet */
370  RT_CK_WDB(wdb);
371  dbip = wdb->dbip;
372  RT_CK_DBI(dbip);
373 
374  if (strchr(path, '/')) {
375  /* This is a path */
376  struct db_tree_state ts;
377  struct db_full_path old_path;
378  struct db_full_path new_path;
379  struct directory *dp_curr;
380  int ret;
381 
383  db_full_path_init(&old_path);
384  db_full_path_init(&new_path);
385 
386  if (db_string_to_path(&new_path, dbip, path) < 0) {
387  bu_vls_printf(logstr, "wdb_import_from_path: '%s' contains unknown object names\n", path);
388  return BRLCAD_ERROR;
389  }
390 
391  dp_curr = DB_FULL_PATH_CUR_DIR(&new_path);
392  ret = db_follow_path(&ts, &old_path, &new_path, LOOKUP_NOISY, 0);
393  db_free_full_path(&old_path);
394  db_free_full_path(&new_path);
395 
396  MAT_COPY(matp, ts.ts_mat);
397 
398  if (!dp_curr || ret < 0) {
399  bu_vls_printf(logstr, "wdb_import_from_path: '%s' is a bad path\n", path);
400  return BRLCAD_ERROR;
401  }
402 
403  status = wdb_import(wdb, ip, dp_curr->d_namep, ts.ts_mat);
404  if (status == -4) {
405  bu_vls_printf(logstr, "%s not found in path %s\n", dp_curr->d_namep, path);
406  return BRLCAD_ERROR;
407  }
408  if (status < 0) {
409  bu_vls_printf(logstr, "wdb_import failure: %s", dp_curr->d_namep);
410  return BRLCAD_ERROR;
411  }
412  } else {
413  MAT_IDN(matp);
414 
415  status = wdb_import(wdb, ip, path, (matp_t)NULL);
416  if (status == -4) {
417  bu_vls_printf(logstr, "%s: not found\n", path);
418  return BRLCAD_ERROR;
419  }
420  if (status < 0) {
421  bu_vls_printf(logstr, "wdb_import failure: %s", path);
422  return BRLCAD_ERROR;
423  }
424  }
425 
426  return BRLCAD_OK;
427 }
428 
429 
430 int
431 wdb_import_from_path(struct bu_vls *logstr, struct rt_db_internal *ip, const char *path, struct rt_wdb *wdb)
432 {
433  mat_t mat;
434 
435  return wdb_import_from_path2(logstr, ip, path, wdb, mat);
436 }
437 
438 
439 /*
440  * Local Variables:
441  * mode: C
442  * tab-width: 8
443  * indent-tabs-mode: t
444  * c-file-style: "stroustrup"
445  * End:
446  * ex: shiftwidth=4 tabstop=8
447  */
int type
Definition: raytrace.h:1265
int wdb_item_default
GIFT region ID.
Definition: raytrace.h:1278
int db_follow_path(struct db_tree_state *tsp, struct db_full_path *total_path, const struct db_full_path *new_path, int noisy, long pdepth)
Definition: db_tree.c:682
void bu_vls_init(struct bu_vls *vp)
Definition: vls.c:56
char * d_namep
pointer to name string
Definition: raytrace.h:859
char filename[MAXLENGTH]
Definition: human.c:105
Definition: raytrace.h:800
void bu_log(const char *,...) _BU_ATTR_PRINTF12
Definition: log.c:176
int rt_db_get_internal(struct rt_db_internal *ip, const struct directory *dp, const struct db_i *dbip, const mat_t mat, struct resource *resp)
Definition: dir.c:76
const struct db_tree_state rt_initial_tree_state
Definition: globals.c:90
int wdb_mat_default
GIFT material code.
Definition: raytrace.h:1280
struct bu_vls wdb_name
database object name
Definition: raytrace.h:1284
#define RT_DIR_INMEM
object is in memory (only)
Definition: raytrace.h:889
double dist
>= 0
Definition: tol.h:73
struct db_i * dbip
Definition: raytrace.h:1266
Definition: clone.c:90
int wdb_import_from_path(struct bu_vls *logstr, struct rt_db_internal *ip, const char *path, struct rt_wdb *wdb)
Definition: wdb.c:431
struct rt_wdb * dbi_wdbp
PRIVATE: ptr back to containing rt_wdb.
Definition: raytrace.h:825
double dist_sq
dist * dist
Definition: tol.h:74
struct directory * db_lookup(const struct db_i *, const char *name, int noisy)
Definition: db_lookup.c:153
#define BU_LIST_MAGIC_SET(_l, _magic)
Definition: list.h:129
int db_version(struct db_i *dbip)
Definition: db5_scan.c:414
#define BN_TOL_MAGIC
Definition: magic.h:74
void bu_free_external(struct bu_external *ep)
Header file for the BRL-CAD common definitions.
#define DB_FULL_PATH_CUR_DIR(_pp)
Definition: db_fullpath.h:51
#define ID_COMBINATION
Combination Record.
Definition: raytrace.h:499
void db_full_path_init(struct db_full_path *pathp)
Definition: db_fullpath.c:40
struct rt_tess_tol wdb_ttol
Definition: raytrace.h:1268
int wdb_put_internal(struct rt_wdb *wdbp, const char *name, struct rt_db_internal *ip, double local2mm)
Definition: wdb.c:218
#define RT_CK_WDB(_p)
Definition: raytrace.h:1292
double rel
rel dist tol
Definition: raytrace.h:181
void rt_init_resource(struct resource *resp, int cpu_num, struct rt_i *rtip)
Definition: prep.c:585
char * strchr(const char *sp, int c)
void db_inmem(struct directory *dp, struct bu_external *ext, int flags, struct db_i *dbip)
Definition: db_inmem.c:130
int idb_major_type
Definition: raytrace.h:192
void bu_vls_free(struct bu_vls *vp)
Definition: vls.c:248
int(* ft_export4)(struct bu_external *, const struct rt_db_internal *, double, const struct db_i *, struct resource *)
Definition: raytrace.h:2152
uint32_t re_magic
Magic number.
Definition: raytrace.h:1441
int wdb_export(struct rt_wdb *wdbp, const char *name, void *gp, int id, double local2mm)
Definition: wdb.c:265
struct resource rt_uniresource
default. Defined in librt/globals.c
Definition: globals.c:41
#define RESOURCE_MAGIC
Definition: magic.h:210
#define RT_CK_DB_INTERNAL(_p)
Definition: raytrace.h:207
void db_init_db_tree_state(struct db_tree_state *tsp, struct db_i *dbip, struct resource *resp)
Definition: db_tree.c:93
#define BU_ALLOC(_ptr, _type)
Definition: malloc.h:223
int db_string_to_path(struct db_full_path *pp, const struct db_i *dbip, const char *str)
Definition: db_fullpath.c:361
int wdb_export_external(struct rt_wdb *wdbp, struct bu_external *ep, const char *name, int flags, unsigned char type)
Definition: wdb.c:105
#define RT_DB_INTERNAL_INIT(_p)
Definition: raytrace.h:199
#define LOOKUP_QUIET
Definition: raytrace.h:893
const struct rt_functab * idb_meth
for ft_ifree(), etc.
Definition: raytrace.h:194
void db_free_full_path(struct db_full_path *pp)
Definition: db_fullpath.c:473
#define RT_WDB_TYPE_DB_DISK
Definition: raytrace.h:1295
#define BRLCAD_OK
Definition: defines.h:71
mat_t ts_mat
transform matrix
Definition: raytrace.h:1050
#define BU_LIST_INIT_MAGIC(_hp, _magic)
Definition: list.h:156
#define RT_DIR_PHONY_ADDR
Special marker for d_addr field.
Definition: raytrace.h:879
void db_wrap_v4_external(struct bu_external *op, const char *name)
Definition: db_comb.c:885
int wdb_los_default
Line-of-sight estimate.
Definition: raytrace.h:1281
int db_wrap_v5_external(struct bu_external *ep, const char *name)
Definition: db5_io.c:702
void db_close(struct db_i *dbip)
goto out
Definition: nmg_mod.c:3846
Tcl_Interp * wdb_interp
Definition: raytrace.h:1286
#define RT_WDB_MAGIC
Definition: magic.h:172
struct bu_vls wdb_prestr
Definition: raytrace.h:1273
#define RT_CK_DBI(_p)
Definition: raytrace.h:829
int dbi_read_only
!0 => read only file
Definition: raytrace.h:806
struct db_i * db_create(const char *name, int version)
Definition: db_open.c:225
void wdb_close(struct rt_wdb *wdbp)
Definition: wdb.c:333
double perp
nearly 0
Definition: tol.h:75
uint32_t magic
Definition: raytrace.h:179
struct directory * db_diradd(struct db_i *, const char *name, off_t laddr, size_t len, int flags, void *ptr)
Definition: db_lookup.c:190
void wdb_init(struct rt_wdb *wdbp, struct db_i *dbip, int mode)
Definition: wdb.c:293
int rt_db_cvt_to_external5(struct bu_external *ext, const char *name, const struct rt_db_internal *ip, double conv2mm, struct db_i *dbip, struct resource *resp, const int major)
Definition: db5_io.c:632
void * idb_ptr
Definition: raytrace.h:195
struct rt_wdb * wdb_fopen_v(const char *filename, int version)
Definition: wdb.c:38
struct bn_tol wdb_tol
Definition: raytrace.h:1269
uint32_t magic
Definition: tol.h:72
#define RT_WDB_TYPE_DB_INMEM_APPEND_ONLY
Definition: raytrace.h:1298
const struct rt_functab OBJ[]
Definition: table.c:159
const struct rt_tess_tol * ts_ttol
Tessellation tolerance.
Definition: raytrace.h:1070
#define DBI_NULL
Definition: raytrace.h:827
struct db_tree_state wdb_initial_tree_state
Definition: raytrace.h:1267
double abs
absolute dist tol
Definition: raytrace.h:180
void bu_vls_printf(struct bu_vls *vls, const char *fmt,...) _BU_ATTR_PRINTF23
Definition: vls.c:694
#define RT_DIR_NULL
Definition: raytrace.h:875
#define LOOKUP_NOISY
Definition: raytrace.h:892
#define BU_EXTERNAL_INIT(_p)
Definition: parse.h:229
int wdb_import(struct rt_wdb *wdbp, struct rt_db_internal *internp, const char *name, const mat_t mat)
Definition: wdb.c:92
int db_flags_internal(const struct rt_db_internal *intern)
Definition: db_flags.c:43
double norm
normal tol
Definition: raytrace.h:182
#define RT_WDB_TYPE_DB_INMEM
Definition: raytrace.h:1297
int wdb_import_from_path2(struct bu_vls *logstr, struct rt_db_internal *ip, const char *path, struct rt_wdb *wdb, matp_t matp)
Definition: wdb.c:364
int db_put_external(struct bu_external *ep, struct directory *dp, struct db_i *dbip)
Definition: db_io.c:281
struct resource * wdb_resp
Definition: raytrace.h:1270
void bu_free(void *ptr, const char *str)
Definition: malloc.c:328
#define RT_TESS_TOL_MAGIC
Definition: magic.h:170
#define BU_CK_EXTERNAL(_p)
Definition: parse.h:224
int wdb_air_default
Definition: raytrace.h:1279
#define RT_WDB_TYPE_DB_DISK_APPEND_ONLY
Definition: raytrace.h:1296
#define BU_LIST_DEQUEUE(cur)
Definition: list.h:209
#define ID_MAX_SOLID
Maximum defined ID_xxx for solids.
Definition: raytrace.h:494
int d_flags
flags
Definition: raytrace.h:869
Definition: vls.h:56
#define BRLCAD_ERROR
Definition: defines.h:72
const struct bn_tol * ts_tol
Math tolerance.
Definition: raytrace.h:1071
char * dbi_filename
file name
Definition: raytrace.h:805
struct rt_wdb * wdb_fopen(const char *filename)
Definition: wdb.c:56
struct rt_wdb * wdb_dbopen(struct db_i *dbip, int mode)
Definition: wdb.c:64
double para
nearly 1
Definition: tol.h:76
struct bu_list l
Definition: raytrace.h:1264
void rt_db_free_internal(struct rt_db_internal *ip)
Definition: dir.c:216
#define RT_WDB_NULL
Definition: raytrace.h:1294