BRL-CAD
keep.c
Go to the documentation of this file.
1 /* K E E P . C
2  * BRL-CAD
3  *
4  * Copyright (c) 2008-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 /** @file libged/keep.c
21  *
22  * The keep command.
23  *
24  */
25 
26 #include "common.h"
27 
28 #include <string.h>
29 
30 #include "bu/cmd.h"
31 #include "bu/getopt.h"
32 #include "rtgeom.h"
33 
34 #include "./ged_private.h"
35 
36 
38  struct rt_wdb *wdbp;
39  struct ged *gedp;
40 };
41 
42 
43 /*
44  * Supports for the 'keep' method.
45  * Write each node encountered exactly once.
46  */
47 HIDDEN void
48 node_write(struct db_i *dbip, struct directory *dp, void *ptr)
49 {
50  struct keep_node_data *kndp = (struct keep_node_data *)ptr;
51  struct rt_db_internal intern;
52 
53  RT_CK_WDB(kndp->wdbp);
54 
55  if (dp->d_nref++ > 0)
56  return; /* already written */
57 
58  if (rt_db_get_internal(&intern, dp, dbip, NULL, &rt_uniresource) < 0) {
59  bu_vls_printf(kndp->gedp->ged_result_str, "Database read error, aborting\n");
60  return;
61  }
62 
63  if (dp->d_major_type == DB5_MAJORTYPE_BRLCAD && dp->d_minor_type == DB5_MINORTYPE_BRLCAD_EXTRUDE) {
64  /* if this is an extrusion, keep the referenced sketch */
65  struct rt_extrude_internal *extr;
66  struct directory *dp2;
67 
68  extr = (struct rt_extrude_internal *)intern.idb_ptr;
69  RT_EXTRUDE_CK_MAGIC(extr);
70 
71  if ((dp2 = db_lookup(dbip, extr->sketch_name, LOOKUP_QUIET)) != RT_DIR_NULL) {
72  node_write(dbip, dp2, ptr);
73  }
74  } else if (dp->d_major_type == DB5_MAJORTYPE_BRLCAD && dp->d_minor_type == DB5_MINORTYPE_BRLCAD_REVOLVE) {
75  /* if this is a revolve, keep the referenced sketch */
76  struct rt_revolve_internal *rev;
77  struct directory *dp2;
78 
79  rev = (struct rt_revolve_internal *)intern.idb_ptr;
80  RT_REVOLVE_CK_MAGIC(rev);
81 
82  if ((dp2 = db_lookup(dbip, bu_vls_addr(&rev->sketch_name), LOOKUP_QUIET)) != RT_DIR_NULL) {
83  node_write(dbip, dp2, ptr);
84  }
85  } else if (dp->d_major_type == DB5_MAJORTYPE_BRLCAD && dp->d_minor_type == DB5_MINORTYPE_BRLCAD_DSP) {
86  /* if this is a DSP, keep the referenced binary object too */
87  struct rt_dsp_internal *dsp;
88  struct directory *dp2;
89 
90  dsp = (struct rt_dsp_internal *)intern.idb_ptr;
91  RT_DSP_CK_MAGIC(dsp);
92 
93  if (dsp->dsp_datasrc == RT_DSP_SRC_OBJ) {
94  /* need to keep this object */
95  if ((dp2 = db_lookup(dbip, bu_vls_addr(&dsp->dsp_name), LOOKUP_QUIET)) != RT_DIR_NULL) {
96  node_write(dbip, dp2, ptr);
97  }
98  }
99  }
100 
101  if (wdb_put_internal(kndp->wdbp, dp->d_namep, &intern, 1.0) < 0) {
102  bu_vls_printf(kndp->gedp->ged_result_str, "Database write error, aborting\n");
103  return;
104  }
105 }
106 
107 
108 int
109 ged_keep(struct ged *gedp, int argc, const char *argv[])
110 {
111  int i;
112  struct keep_node_data knd;
113  struct rt_wdb *keepfp;
114  struct directory *dp;
115  struct bu_vls title = BU_VLS_INIT_ZERO;
116  struct db_i *new_dbip;
117  const char *cmd = argv[0];
118  static const char *usage = "[-R] file object(s)";
119 
120  int c;
121  int flag_R = 0;
122 
124  GED_CHECK_ARGC_GT_0(gedp, argc, GED_ERROR);
125 
126  /* initialize result */
127  bu_vls_trunc(gedp->ged_result_str, 0);
128 
129  /* must be wanting help */
130  if (argc == 1) {
131  bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", cmd, usage);
132  return GED_HELP;
133  }
134 
135  /* check for options */
136  bu_optind = 1;
137  while ((c = bu_getopt(argc, (char * const *)argv, "R")) != -1) {
138  switch (c) {
139  case 'R':
140  /* not recursively */
141  flag_R = 1;
142  break;
143  default:
144  bu_vls_printf(gedp->ged_result_str, "Unrecognized option - %c", c);
145  return GED_ERROR;
146  }
147  }
148  /* skip options processed plus command name */
149  argc -= bu_optind;
150  argv += bu_optind;
151 
152  if (argc < 2) {
153  bu_vls_printf(gedp->ged_result_str, "ERROR: missing file or object names\n");
154  bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", cmd, usage);
155  return GED_ERROR;
156  }
157 
158  /* First, clear any existing counts */
159  for (i = 0; i < RT_DBNHASH; i++) {
160  for (dp = gedp->ged_wdbp->dbip->dbi_Head[i]; dp != RT_DIR_NULL; dp = dp->d_forw)
161  dp->d_nref = 0;
162  }
163 
164  /* Alert user if named file already exists */
165 
166  new_dbip = db_open(argv[0], DB_OPEN_READWRITE);
167 
168  if (new_dbip != DBI_NULL) {
169  if (db_version(new_dbip) != db_version(gedp->ged_wdbp->dbip)) {
170  bu_vls_printf(gedp->ged_result_str, "%s: File format mismatch between '%s' and '%s'\n",
171  cmd, argv[0], gedp->ged_wdbp->dbip->dbi_filename);
172  return GED_ERROR;
173  }
174 
175  if ((keepfp = wdb_dbopen(new_dbip, RT_WDB_TYPE_DB_DISK)) == NULL) {
176  bu_vls_printf(gedp->ged_result_str, "%s: Error opening '%s'\n", cmd, argv[0]);
177  return GED_ERROR;
178  } else {
179  bu_vls_printf(gedp->ged_result_str, "%s: Appending to '%s'\n", cmd, argv[0]);
180 
181  /* --- Scan geometry database and build in-memory directory --- */
182  db_dirbuild(new_dbip);
183  }
184  } else {
185  /* Create a new database */
186  keepfp = wdb_fopen_v(argv[0], db_version(gedp->ged_wdbp->dbip));
187 
188  if (keepfp == NULL) {
189  perror(argv[0]);
190  return GED_ERROR;
191  }
192  }
193 
194  knd.wdbp = keepfp;
195  knd.gedp = gedp;
196 
197  /* ident record */
198  if (bu_strncmp(gedp->ged_wdbp->dbip->dbi_title, "Parts of: ", 10) != 0) {
199  bu_vls_strcat(&title, "Parts of: ");
200  }
201  bu_vls_strcat(&title, gedp->ged_wdbp->dbip->dbi_title);
202 
203  if (db_update_ident(keepfp->dbip, bu_vls_addr(&title), gedp->ged_wdbp->dbip->dbi_local2base) < 0) {
204  perror("fwrite");
205  bu_vls_printf(gedp->ged_result_str, "db_update_ident() failed\n");
206  wdb_close(keepfp);
207  bu_vls_free(&title);
208  return GED_ERROR;
209  }
210  bu_vls_free(&title);
211 
212  for (i = 1; i < argc; i++) {
213  if ((dp = db_lookup(gedp->ged_wdbp->dbip, argv[i], LOOKUP_NOISY)) == RT_DIR_NULL)
214  continue;
215 
216  if (!flag_R) {
217  /* recursively keep objects */
218  db_functree(gedp->ged_wdbp->dbip, dp, node_write, node_write, &rt_uniresource, (void *)&knd);
219  } else {
220  /* keep just this object */
221  node_write(gedp->ged_wdbp->dbip, dp, (void *)&knd);
222  }
223  }
224 
225  wdb_close(keepfp);
226  return GED_OK;
227 }
228 
229 
230 /*
231  * Local Variables:
232  * tab-width: 8
233  * mode: C
234  * indent-tabs-mode: t
235  * c-file-style: "stroustrup"
236  * End:
237  * ex: shiftwidth=4 tabstop=8
238  */
void usage(struct ged *gedp)
Definition: coil.c:315
#define GED_OK
Definition: ged.h:55
char * d_namep
pointer to name string
Definition: raytrace.h:859
Definition: raytrace.h:800
unsigned char d_major_type
object major type
Definition: raytrace.h:870
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
#define RT_DBNHASH
hash table is an array of linked lists with this many array pointer elements (Memory use for 32-bit: ...
Definition: raytrace.h:755
long d_nref
times ref'ed by COMBs
Definition: raytrace.h:868
Definition: ged.h:338
struct db_i * dbip
Definition: raytrace.h:1266
void bu_vls_strcat(struct bu_vls *vp, const char *s)
Definition: vls.c:368
void bu_vls_trunc(struct bu_vls *vp, int len)
Definition: vls.c:198
#define GED_CHECK_ARGC_GT_0(_gedp, _argc, _flags)
Definition: ged.h:202
struct directory * db_lookup(const struct db_i *, const char *name, int noisy)
Definition: db_lookup.c:153
int db_version(struct db_i *dbip)
Definition: db5_scan.c:414
struct rt_wdb * ged_wdbp
Definition: ged.h:340
Header file for the BRL-CAD common definitions.
int bu_optind
Definition: globals.c:89
struct directory * d_forw
link to next dir entry
Definition: raytrace.h:864
int bu_getopt(int nargc, char *const nargv[], const char *ostr)
Definition: getopt.c:43
#define GED_ERROR
Definition: ged.h:61
#define HIDDEN
Definition: common.h:86
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
#define DB_OPEN_READWRITE
Definition: raytrace.h:3555
void bu_vls_free(struct bu_vls *vp)
Definition: vls.c:248
unsigned char d_minor_type
object minor type
Definition: raytrace.h:871
int bu_strncmp(const char *string1, const char *string2, size_t n)
Definition: str.c:191
int ged_keep(struct ged *gedp, int argc, const char *argv[])
Definition: keep.c:109
struct resource rt_uniresource
default. Defined in librt/globals.c
Definition: globals.c:41
#define GED_CHECK_DATABASE_OPEN(_gedp, _flags)
Definition: ged.h:114
char * dbi_title
title from IDENT rec
Definition: raytrace.h:809
#define LOOKUP_QUIET
Definition: raytrace.h:893
#define RT_WDB_TYPE_DB_DISK
Definition: raytrace.h:1295
struct rt_wdb * wdbp
Definition: keep.c:38
int db_update_ident(struct db_i *dbip, const char *title, double local2mm)
Definition: db_scan.c:367
char * bu_vls_addr(const struct bu_vls *vp)
Definition: vls.c:111
struct bu_vls * ged_result_str
Definition: ged.h:357
void wdb_close(struct rt_wdb *wdbp)
Definition: wdb.c:333
void * idb_ptr
Definition: raytrace.h:195
struct rt_wdb * wdb_fopen_v(const char *filename, int version)
Definition: wdb.c:38
struct directory * dbi_Head[RT_DBNHASH]
Definition: raytrace.h:814
#define DBI_NULL
Definition: raytrace.h:827
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
struct ged * gedp
Definition: keep.c:39
struct db_i * db_open(const char *name, const char *mode)
Definition: db_open.c:59
#define GED_HELP
Definition: ged.h:62
void db_functree(struct db_i *dbip, struct directory *dp, void(*comb_func)(struct db_i *, struct directory *, void *), void(*leaf_func)(struct db_i *, struct directory *, void *), struct resource *resp, void *client_data)
Definition: db_walk.c:199
double dbi_local2base
local2mm
Definition: raytrace.h:807
int db_dirbuild(struct db_i *dbip)
Definition: db5_scan.c:301
#define BU_VLS_INIT_ZERO
Definition: vls.h:84
Definition: vls.h:56
HIDDEN void node_write(struct db_i *dbip, struct directory *dp, void *ptr)
Definition: keep.c:48
char * dbi_filename
file name
Definition: raytrace.h:805
struct rt_wdb * wdb_dbopen(struct db_i *dbip, int mode)
Definition: wdb.c:64