BRL-CAD
get_obj_bounds.c
Go to the documentation of this file.
1 /* G E T _ O B J _ B O U N D S . 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/get_obj_bounds.c
21  *
22  * The orot command.
23  *
24  */
25 
26 #include "common.h"
27 
28 #include <stdlib.h>
29 #include <string.h>
30 
31 #include "ged.h"
32 
33 #include "./ged_private.h"
34 
35 
36 int
37 ged_get_obj_bounds(struct ged *gedp,
38  int argc,
39  const char *argv[],
40  int use_air,
41  point_t rpp_min,
42  point_t rpp_max)
43 {
44  int i;
45  struct rt_i *rtip;
46  struct db_full_path path;
47  struct region *regp;
48 
49  /* Make a new rt_i instance from the existing db_i structure */
50  if ((rtip=rt_new_rti(gedp->ged_wdbp->dbip)) == RTI_NULL) {
51  bu_vls_printf(gedp->ged_result_str, "rt_new_rti failure for %s\n", gedp->ged_wdbp->dbip->dbi_filename);
52  return GED_ERROR;
53  }
54 
55  rtip->useair = use_air;
56 
57  /* Get trees for list of objects/paths */
58  for (i = 0; i < argc; i++) {
59  int gottree;
60 
61  /* Get full_path structure for argument */
62  db_full_path_init(&path);
63  if (db_string_to_path(&path, rtip->rti_dbip, argv[i])) {
64  bu_vls_printf(gedp->ged_result_str, "db_string_to_path failed for %s\n", argv[i]);
65  rt_free_rti(rtip);
66  return GED_ERROR;
67  }
68 
69  /* check if we already got this tree */
70  gottree = 0;
71  for (BU_LIST_FOR(regp, region, &(rtip->HeadRegion))) {
72  struct db_full_path tmp_path;
73 
74  db_full_path_init(&tmp_path);
75  if (db_string_to_path(&tmp_path, rtip->rti_dbip, regp->reg_name)) {
76  bu_vls_printf(gedp->ged_result_str, "db_string_to_path failed for %s\n", regp->reg_name);
77  rt_free_rti(rtip);
78  db_free_full_path(&path);
79  return GED_ERROR;
80  }
81  if (path.fp_names[0] == tmp_path.fp_names[0])
82  gottree = 1;
83  db_free_full_path(&tmp_path);
84  if (gottree)
85  break;
86  }
87 
88  /* if we don't already have it, get it */
89  if (!gottree && rt_gettree(rtip, argv[i])) {
90  bu_vls_printf(gedp->ged_result_str, "rt_gettree failed for %s\n", argv[i]);
91  rt_free_rti(rtip);
92  db_free_full_path(&path);
93  return GED_ERROR;
94  }
95  db_free_full_path(&path);
96  }
97 
98  /* prep calculates bounding boxes of solids */
99  rt_prep(rtip);
100 
101  /* initialize RPP bounds */
102  VSETALL(rpp_min, INFINITY);
103  VSETALL(rpp_max, -INFINITY);
104  for (i = 0; i < argc; i++) {
105  vect_t reg_min, reg_max;
106  const char *reg_name;
107  size_t name_len;
108 
109  /* check if input name is a region */
110  for (BU_LIST_FOR(regp, region, &(rtip->HeadRegion))) {
111  reg_name = regp->reg_name;
112  if (*argv[i] != '/' && *reg_name == '/')
113  reg_name++;
114 
115  if (BU_STR_EQUAL(reg_name, argv[i])) {
116  /* input name was a region */
117  if (rt_bound_tree(regp->reg_treetop, reg_min, reg_max)) {
118  bu_vls_printf(gedp->ged_result_str, "rt_bound_tree failed for %s\n", regp->reg_name);
119  rt_free_rti(rtip);
120  return TCL_ERROR;
121  }
122  VMINMAX(rpp_min, rpp_max, reg_min);
123  VMINMAX(rpp_min, rpp_max, reg_max);
124 
125  goto found;
126  }
127  }
128 
129  /* input name may be a group, need to check all regions under
130  * that group
131  */
132  name_len = strlen(argv[i]);
133  for (BU_LIST_FOR(regp, region, &(rtip->HeadRegion))) {
134  reg_name = regp->reg_name;
135  if (*argv[i] != '/' && *reg_name == '/')
136  reg_name++;
137 
138  if (bu_strncmp(argv[i], reg_name, name_len))
139  continue;
140 
141  /* This is part of the group */
142  if (rt_bound_tree(regp->reg_treetop, reg_min, reg_max)) {
143  bu_vls_printf(gedp->ged_result_str, "rt_bound_tree failed for %s\n", regp->reg_name);
144  rt_free_rti(rtip);
145  return TCL_ERROR;
146  }
147  VMINMAX(rpp_min, rpp_max, reg_min);
148  VMINMAX(rpp_min, rpp_max, reg_max);
149  }
150 
151  found:;
152  }
153 
154  rt_free_rti(rtip);
155 
156  return TCL_OK;
157 }
158 
159 
160 static int
161 get_objpath_mat(struct ged *gedp,
162  int argc,
163  const char *argv[],
164  struct _ged_trace_data *gtdp)
165 {
166  int i, pos_in;
167 
168  /*
169  * paths are matched up to last input member
170  * ANY path the same up to this point is considered as matching
171  */
172 
173  /* initialize gtd */
174  gtdp->gtd_gedp = gedp;
175  gtdp->gtd_flag = _GED_EVAL_ONLY;
176  gtdp->gtd_prflag = 0;
177 
178  pos_in = 0;
179 
180  if (argc == 1 && strchr(argv[0], '/')) {
181  char *tok;
182  char *av0;
183  gtdp->gtd_objpos = 0;
184 
185  av0 = strdup(argv[0]);
186  tok = strtok(av0, "/");
187  while (tok) {
188  if ((gtdp->gtd_obj[gtdp->gtd_objpos++] =
189  db_lookup(gedp->ged_wdbp->dbip, tok, LOOKUP_NOISY)) == RT_DIR_NULL) {
190  bu_vls_printf(gedp->ged_result_str, "get_objpath_mat: Failed to find %s", tok);
191  free(av0);
192  return GED_ERROR;
193  }
194 
195  tok = strtok((char *)0, "/");
196  }
197 
198  free(av0);
199  } else {
200  gtdp->gtd_objpos = argc;
201 
202  /* build directory pointer array for desired path */
203  for (i = 0; i < gtdp->gtd_objpos; i++) {
204  if ((gtdp->gtd_obj[i] =
205  db_lookup(gedp->ged_wdbp->dbip, argv[pos_in+i], LOOKUP_NOISY)) == RT_DIR_NULL) {
206  bu_vls_printf(gedp->ged_result_str, "get_objpath_mat: Failed to find %s", argv[pos_in+i]);
207  return GED_ERROR;
208  }
209  }
210  }
211 
212  MAT_IDN(gtdp->gtd_xform);
213  ged_trace(gtdp->gtd_obj[0], 0, bn_mat_identity, gtdp, 1);
214 
215  return GED_OK;
216 }
217 
218 
219 /**
220  * @brief
221  * This version works if the last member of the path is a primitive.
222  */
223 int
225  int argc,
226  const char *argv[],
227  struct _ged_trace_data *gtdp,
228  point_t rpp_min,
229  point_t rpp_max)
230 {
231  struct directory *dp;
232  struct rt_db_internal intern;
233  struct rt_i *rtip;
234  struct soltab st;
235  mat_t imat;
236 
237  /* initialize RPP bounds */
238  VSETALL(rpp_min, MAX_FASTF);
239  VREVERSE(rpp_max, rpp_min);
240 
241  if (get_objpath_mat(gedp, argc, argv, gtdp) == TCL_ERROR)
242  return GED_ERROR;
243 
244  dp = gtdp->gtd_obj[gtdp->gtd_objpos-1];
245  GED_DB_GET_INTERNAL(gedp, &intern, dp, gtdp->gtd_xform, &rt_uniresource, GED_ERROR);
246 
247  /* Make a new rt_i instance from the existing db_i structure */
248  if ((rtip=rt_new_rti(gedp->ged_wdbp->dbip)) == RTI_NULL) {
249  bu_vls_printf(gedp->ged_result_str, "rt_new_rti failure for %s", gedp->ged_wdbp->dbip->dbi_filename);
250  return GED_ERROR;
251  }
252 
253  memset(&st, 0, sizeof(struct soltab));
254 
255  st.l.magic = RT_SOLTAB_MAGIC;
257  st.st_dp = dp;
258  MAT_IDN(imat);
259  st.st_matp = imat;
260  st.st_meth = intern.idb_meth;
261 
262  /* Get bounds from internal object */
263  VMOVE(st.st_min, rpp_min);
264  VMOVE(st.st_max, rpp_max);
265  if (intern.idb_meth->ft_prep)
266  intern.idb_meth->ft_prep(&st, &intern, rtip);
267  VMOVE(rpp_min, st.st_min);
268  VMOVE(rpp_max, st.st_max);
269 
270  rt_free_rti(rtip);
271  rt_db_free_internal(&intern);
272 
273  return GED_OK;
274 }
275 
276 
277 /*
278  * Local Variables:
279  * tab-width: 8
280  * mode: C
281  * indent-tabs-mode: t
282  * c-file-style: "stroustrup"
283  * End:
284  * ex: shiftwidth=4 tabstop=8
285  */
#define GED_OK
Definition: ged.h:55
#define BU_LIST_FOR(p, structure, hp)
Definition: list.h:365
const struct directory * st_dp
Directory entry of solid.
Definition: raytrace.h:436
Definition: ged.h:338
const mat_t bn_mat_identity
Matrix and vector functionality.
Definition: mat.c:46
void rt_free_rti(struct rt_i *rtip)
Definition: prep.c:156
struct db_i * dbip
Definition: raytrace.h:1266
int useair
1="air" regions are retained while prepping
Definition: raytrace.h:1756
int rt_bound_tree(const union tree *tp, vect_t tree_min, vect_t tree_max)
#define RT_SOLTAB2_MAGIC
Definition: magic.h:168
#define VSETALL(a, s)
Definition: color.c:54
struct bu_list HeadRegion
ptr of list of regions in model
Definition: raytrace.h:1778
struct directory * db_lookup(const struct db_i *, const char *name, int noisy)
Definition: db_lookup.c:153
int ged_get_obj_bounds(struct ged *gedp, int argc, const char *argv[], int use_air, point_t rpp_min, point_t rpp_max)
struct rt_wdb * ged_wdbp
Definition: ged.h:340
int _ged_get_obj_bounds2(struct ged *gedp, int argc, const char *argv[], struct _ged_trace_data *gtdp, point_t rpp_min, point_t rpp_max)
This version works if the last member of the path is a primitive.
Header file for the BRL-CAD common definitions.
matp_t st_matp
solid coords to model space, NULL=identity
Definition: raytrace.h:441
const char * reg_name
Identifying string.
Definition: raytrace.h:539
void db_full_path_init(struct db_full_path *pathp)
Definition: db_fullpath.c:40
#define MAX_FASTF
Definition: defines.h:340
struct bu_list l
links, headed by rti_headsolid
Definition: raytrace.h:426
#define GED_ERROR
Definition: ged.h:61
#define RTI_NULL
Definition: raytrace.h:1830
char * strchr(const char *sp, int c)
int bu_strncmp(const char *string1, const char *string2, size_t n)
Definition: str.c:191
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_EVAL_ONLY
Definition: ged_private.h:55
int db_string_to_path(struct db_full_path *pp, const struct db_i *dbip, const char *str)
Definition: db_fullpath.c:361
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
char * strtok(char *s, const char *delim)
point_t st_max
max X, Y, Z of bounding RPP
Definition: raytrace.h:438
int(* ft_prep)(struct soltab *stp, struct rt_db_internal *ip, struct rt_i *rtip)
Definition: raytrace.h:2047
void ged_trace(struct directory *dp, int pathpos, const mat_t old_xlate, struct _ged_trace_data *gtdp, int verbose)
Definition: trace.c:82
#define RT_SOLTAB_MAGIC
Definition: magic.h:169
struct directory ** fp_names
array of dir pointers
Definition: db_fullpath.h:46
struct ged * gtd_gedp
Definition: ged.h:1914
struct bu_vls * ged_result_str
Definition: ged.h:357
uint32_t magic
Magic # for mem id/check.
Definition: list.h:119
struct rt_i * rt_new_rti(struct db_i *dbip)
Definition: prep.c:58
int rt_gettree(struct rt_i *rtip, const char *node)
Definition: tree.c:869
point_t st_min
min X, Y, Z of bounding RPP
Definition: raytrace.h:437
mat_t gtd_xform
Definition: ged.h:1917
struct db_i * rti_dbip
prt to Database instance struct
Definition: raytrace.h:1774
struct bu_list l2
links, headed by st_dp->d_use_hd
Definition: raytrace.h:427
void rt_prep(struct rt_i *rtip)
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
union tree * reg_treetop
Pointer to boolean tree.
Definition: raytrace.h:540
#define GED_DB_GET_INTERNAL(_gedp, _intern, _dp, _mat, _resource, _flags)
Definition: ged.h:233
char * strdup(const char *cp)
const struct rt_functab * st_meth
pointer to per-solid methods
Definition: raytrace.h:428
int gtd_flag
Definition: ged.h:1920
int gtd_prflag
Definition: ged.h:1919
char * dbi_filename
file name
Definition: raytrace.h:805
struct directory * gtd_obj[_GED_MAX_LEVELS]
Definition: ged.h:1916
void rt_db_free_internal(struct rt_db_internal *ip)
Definition: dir.c:216
int gtd_objpos
Definition: ged.h:1918
#define BU_STR_EQUAL(s1, s2)
Definition: str.h:126