BRL-CAD
copymat.c
Go to the documentation of this file.
1 /* C O P Y M A T . 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/copymat.c
21  *
22  * The copymat command.
23  *
24  */
25 
26 #include "common.h"
27 
28 #include <stdlib.h>
29 #include <ctype.h>
30 #include <string.h>
31 
32 #include "./ged_private.h"
33 
34 
35 int
36 ged_copymat(struct ged *gedp, int argc, const char *argv[])
37 {
38  char *child = NULL;
39  char *parent = NULL;
40  struct bu_vls pvls = BU_VLS_INIT_ZERO;
41  int i;
42  int sep;
43  int status;
44  struct db_tree_state ts;
45  struct directory *dp;
46  struct rt_comb_internal *comb;
47  struct rt_db_internal intern;
48  struct animate anp;
49  union tree *tp;
50  static const char *usage = "a/b c/d";
51 
54  GED_CHECK_ARGC_GT_0(gedp, argc, GED_ERROR);
55 
56  /* initialize result */
57  bu_vls_trunc(gedp->ged_result_str, 0);
58 
59  /* must be wanting help */
60  if (argc == 1) {
61  bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage);
62  return GED_HELP;
63  }
64 
65  if (argc != 3) {
66  bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage);
67  return GED_ERROR;
68  }
69 
70  /*
71  * Ensure that each argument contains exactly one slash
72  */
73  for (i = 1; i <= 2; ++i) {
74  if (((child = strchr(argv[i], '/')) == NULL)
75  || (strchr(++child, '/') != NULL))
76  {
77  bu_vls_printf(gedp->ged_result_str, "%s: bad arc: '%s'\n", argv[0], argv[i]);
78  return GED_ERROR;
79  }
80  }
81 
82  memset(&anp, 0, sizeof(struct animate));
83  anp.magic = ANIMATE_MAGIC;
84 
85  ts = gedp->ged_wdbp->wdb_initial_tree_state; /* struct copy */
86  ts.ts_dbip = gedp->ged_wdbp->dbip;
87  ts.ts_resp = &rt_uniresource;
88  MAT_IDN(ts.ts_mat);
90  if (child == NULL
91  || db_follow_path_for_state(&ts, &(anp.an_path), argv[1], LOOKUP_NOISY) < 0)
92  {
93  bu_vls_printf(gedp->ged_result_str, "%s: cannot follow path for arc: '%s'\n", argv[0], argv[1]);
94  return GED_ERROR;
95  }
96 
97  bu_vls_strcat(&pvls, argv[2]);
98  parent = bu_vls_addr(&pvls);
99  sep = strchr(parent, '/') - parent;
100  bu_vls_trunc(&pvls, sep);
101  switch (rt_db_lookup_internal(gedp->ged_wdbp->dbip, parent, &dp, &intern, LOOKUP_NOISY, &rt_uniresource)) {
102  case ID_COMBINATION:
103  if (dp->d_flags & RT_DIR_COMB)
104  break;
105  else {
107  "%s: Non-combination directory <%p> '%s' for combination rt_db_internal <%p>\nThis should not happen\n",
108  argv[0], (void *)dp, dp->d_namep, (void *)&intern);
109  }
110  /* Fall through this case */
111  default:
112  bu_vls_printf(gedp->ged_result_str, "%s: Object '%s' is not a combination\n", argv[0], parent);
113  /* Fall through this case */
114  case ID_NULL:
115  bu_vls_free(&pvls);
116  return GED_ERROR;
117  }
118  comb = (struct rt_comb_internal *) intern.idb_ptr;
119  RT_CK_COMB(comb);
120 
121  tp = db_find_named_leaf(comb->tree, child);
122  if (tp == TREE_NULL) {
123  bu_vls_printf(gedp->ged_result_str, "%s: unable to find instance of '%s' in combination '%s'\n",
124  argv[0], child, dp->d_namep);
125  status = GED_ERROR;
126  goto wrapup;
127  }
128 
129  /*
130  * Finally, copy the matrix
131  */
132  if (!bn_mat_is_identity(ts.ts_mat)) {
133  if (tp->tr_l.tl_mat == NULL)
134  tp->tr_l.tl_mat = bn_mat_dup(ts.ts_mat);
135  else
136  MAT_COPY(tp->tr_l.tl_mat, ts.ts_mat);
137  } else if (tp->tr_l.tl_mat != NULL) {
138  bu_free((void *) tp->tr_l.tl_mat, "tl_mat");
139  tp->tr_l.tl_mat = (matp_t) 0;
140  }
141 
142  if (rt_db_put_internal(dp, gedp->ged_wdbp->dbip, &intern, &rt_uniresource) < 0) {
143  bu_vls_printf(gedp->ged_result_str, "%s: Database write error, aborting\n", argv[0]);
144  status = GED_ERROR;
145  goto wrapup;
146  }
147 
148  status = GED_OK;
149 
150 wrapup:
151 
152  bu_vls_free(&pvls);
153  if (status == GED_ERROR)
154  rt_db_free_internal(&intern);
155  return status;
156 }
157 
158 
159 /*
160  * Local Variables:
161  * tab-width: 8
162  * mode: C
163  * indent-tabs-mode: t
164  * c-file-style: "stroustrup"
165  * End:
166  * ex: shiftwidth=4 tabstop=8
167  */
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
int bn_mat_is_identity(const mat_t m)
Definition: mat.c:980
int rt_db_put_internal(struct directory *dp, struct db_i *dbip, struct rt_db_internal *ip, struct resource *resp)
Definition: dir.c:136
union tree * db_find_named_leaf(union tree *tp, const char *cp)
Definition: db_tree.c:393
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
#define RT_CK_COMB(_p)
Definition: raytrace.h:955
#define ID_NULL
Unused.
Definition: raytrace.h:458
struct rt_wdb * ged_wdbp
Definition: ged.h:340
Header file for the BRL-CAD common definitions.
#define ID_COMBINATION
Combination Record.
Definition: raytrace.h:499
void db_full_path_init(struct db_full_path *pathp)
Definition: db_fullpath.c:40
#define GED_ERROR
Definition: ged.h:61
char * strchr(const char *sp, int c)
void bu_vls_free(struct bu_vls *vp)
Definition: vls.c:248
void * memset(void *s, int c, size_t n)
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
#define ANIMATE_MAGIC
Definition: magic.h:196
struct db_i * ts_dbip
Definition: raytrace.h:1040
#define TREE_NULL
Definition: raytrace.h:1181
mat_t ts_mat
transform matrix
Definition: raytrace.h:1050
matp_t tl_mat
xform matp, NULL ==> identity
Definition: raytrace.h:1173
matp_t bn_mat_dup(const mat_t in)
Definition: mat.c:1046
char * bu_vls_addr(const struct bu_vls *vp)
Definition: vls.c:111
struct bu_vls * ged_result_str
Definition: ged.h:357
struct resource * ts_resp
Per-CPU data.
Definition: raytrace.h:1074
uint32_t magic
magic number
Definition: raytrace.h:1337
int rt_db_lookup_internal(struct db_i *dbip, const char *obj_name, struct directory **dpp, struct rt_db_internal *ip, int noisy, struct resource *resp)
Definition: dir.c:240
int ged_copymat(struct ged *gedp, int argc, const char *argv[])
Definition: copymat.c:36
struct db_full_path an_path
(sub)-path pattern
Definition: raytrace.h:1339
struct tree::tree_db_leaf tr_l
void * idb_ptr
Definition: raytrace.h:195
#define RT_DIR_COMB
combination
Definition: raytrace.h:884
struct db_tree_state wdb_initial_tree_state
Definition: raytrace.h:1267
union tree * tree
Leading to tree_db_leaf leaves.
Definition: raytrace.h:938
void bu_vls_printf(struct bu_vls *vls, const char *fmt,...) _BU_ATTR_PRINTF23
Definition: vls.c:694
#define LOOKUP_NOISY
Definition: raytrace.h:892
#define GED_HELP
Definition: ged.h:62
void bu_free(void *ptr, const char *str)
Definition: malloc.c:328
#define BU_VLS_INIT_ZERO
Definition: vls.h:84
#define GED_CHECK_READ_ONLY(_gedp, _flags)
Definition: ged.h:181
int d_flags
flags
Definition: raytrace.h:869
Definition: vls.h:56
int db_follow_path_for_state(struct db_tree_state *tsp, struct db_full_path *pathp, const char *orig_str, int noisy)
Definition: db_tree.c:839
void rt_db_free_internal(struct rt_db_internal *ip)
Definition: dir.c:216