BRL-CAD
voxelize.c
Go to the documentation of this file.
1 /* V O X E L I Z E . 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/voxelize.c
21  *
22  * The voxelize 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 #include "raytrace.h"
34 
35 #include "./ged_private.h"
36 #include "analyze.h"
37 #include "wdb.h"
38 
39 
41 {
45  struct rt_wdb *wdbp;
46  char *newname;
47  struct wmember content;
48 };
49 
50 HIDDEN void
51 create_boxes(void *callBackData, int x, int y, int z, const char *a, fastf_t fill)
52 {
53  if (a != NULL) {
54  fastf_t min[3], max[3];
55 
56  struct bu_vls *vp;
57  char bufx[50], bufy[50], bufz[50];
58  char *nameDestination;
59 
60  struct voxelizeData *dataValues = (struct voxelizeData *)callBackData;
61 
62  sprintf(bufx, "%d", x);
63  sprintf(bufy, "%d", y);
64  sprintf(bufz, "%d", z);
65 
66  if (dataValues->threshold <= fill) {
67  vp = bu_vls_vlsinit();
68  bu_vls_strcat(vp, dataValues->newname);
69  bu_vls_strcat(vp, ".x");
70  bu_vls_strcat(vp, bufx);
71  bu_vls_strcat(vp, "y");
72  bu_vls_strcat(vp, bufy);
73  bu_vls_strcat(vp, "z");
74  bu_vls_strcat(vp, bufz);
75  bu_vls_strcat(vp, ".s");
76 
77  min[0] = (dataValues->bbMin)[0] + (x * (dataValues->sizeVoxel)[0]);
78  min[1] = (dataValues->bbMin)[1] + (y * (dataValues->sizeVoxel)[1]);
79  min[2] = (dataValues->bbMin)[2] + (z * (dataValues->sizeVoxel)[2]);
80  max[0] = (dataValues->bbMin)[0] + ( (x + 1.0) * (dataValues->sizeVoxel)[0]);
81  max[1] = (dataValues->bbMin)[1] + ( (y + 1.0) * (dataValues->sizeVoxel)[1]);
82  max[2] = (dataValues->bbMin)[2] + ( (z + 1.0) * (dataValues->sizeVoxel)[2]);
83 
84  nameDestination = bu_vls_strgrab(vp);
85  mk_rpp(dataValues->wdbp,nameDestination, min, max);
86  mk_addmember(nameDestination, &dataValues->content.l, 0, WMOP_UNION);
87  }
88  }
89  /* else this voxel is air */
90 }
91 
92 int
93 ged_voxelize(struct ged *gedp, int argc, const char *argv[])
94 {
95  struct rt_i *rtip;
96  static const char *usage = "[-s \"dx dy dz\"] [-d n] [-t f] new_obj old_obj [old_obj2 old_obj3 ...]";
97  fastf_t sizeVoxel[3];
98  int levelOfDetail;
99  void *callBackData;
100  struct voxelizeData voxDat;
101  int c;
102 
103  /* intentionally double for scan */
104  double threshold;
105 
107  GED_CHECK_ARGC_GT_0(gedp, argc, GED_ERROR);
108 
109  /* initialization */
110  bu_vls_trunc(gedp->ged_result_str, 0);
111 
112  /* incorrect arguments */
113  if (argc < 3) {
114  bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage);
115  return GED_HELP;
116  }
117 
118  sizeVoxel[0] = 1.0;
119  sizeVoxel[1] = 1.0;
120  sizeVoxel[2] = 1.0;
121  levelOfDetail = 1;
122  threshold = 0.5;
123 
124  bu_optind = 1;
125  while ((c = bu_getopt(argc, (char * const *)argv, (const char *)"s:d:t:")) != -1) {
126  double scan[3];
127 
128  switch (c) {
129  case 's':
130  if (sscanf(bu_optarg, "%lf %lf %lf",
131  &scan[0],
132  &scan[1],
133  &scan[2]) != 3) {
134  bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage);
135  return GED_ERROR;
136  } else {
137  /* convert from double to fastf_t */
138  VMOVE(sizeVoxel, scan);
139 
140  sizeVoxel[0] = sizeVoxel[0] * gedp->ged_wdbp->dbip->dbi_local2base;
141  sizeVoxel[1] = sizeVoxel[1] * gedp->ged_wdbp->dbip->dbi_local2base;
142  sizeVoxel[2] = sizeVoxel[2] * gedp->ged_wdbp->dbip->dbi_local2base;
143  }
144  break;
145 
146  case 'd':
147  if (sscanf(bu_optarg, "%d", &levelOfDetail) != 1) {
148  bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage);
149  return GED_ERROR;
150  }
151  break;
152 
153  case 't':
154  if (sscanf(bu_optarg, "%lf", &threshold) != 1) {
155  bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage);
156  return GED_ERROR;
157  }
158  break;
159 
160  default:
161  bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage);
162  return GED_ERROR;
163  }
164  }
165 
166  argc -= bu_optind;
167  argv += bu_optind;
168 
169  if (argc < 2) {
170  bu_vls_printf(gedp->ged_result_str, "error: missing argument(s)\n");
171  return GED_ERROR;
172  }
173 
174  voxDat.newname = (char *)argv[0];
175  argc--;
176  argv++;
177 
178  if (db_lookup(gedp->ged_wdbp->dbip, voxDat.newname, LOOKUP_QUIET) != RT_DIR_NULL) {
179  bu_vls_printf(gedp->ged_result_str, "error: solid '%s' already exists, aborting\n", voxDat.newname);
180  return GED_ERROR;
181  }
182 
183  rtip = rt_new_rti(gedp->ged_wdbp->dbip);
184  rtip->useair = 1;
185 
186  /* Walk trees. Here we identify any object trees in the database
187  * that the user wants included in the ray trace.
188  */
189  while (argc > 0) {
190  if (rt_gettree(rtip,argv[0]) < 0) {
191  bu_vls_printf(gedp->ged_result_str, "error: object '%s' does not exists, aborting\n", argv[1]);
192  return GED_ERROR;
193  }
194 
195  argc--;
196  argv++;
197  }
198 
199 
200  voxDat.sizeVoxel[0] = sizeVoxel[0];
201  voxDat.sizeVoxel[1] = sizeVoxel[1];
202  voxDat.sizeVoxel[2] = sizeVoxel[2];
203  voxDat.threshold = threshold;
204  voxDat.wdbp = gedp->ged_wdbp;
205  voxDat.bbMin = rtip->mdl_min;
206  BU_LIST_INIT(&voxDat.content.l);
207 
208  callBackData = (void*)(&voxDat);
209 
210  /* voxelize function is called here with rtip(ray trace instance), userParameter and create_boxes function */
211  voxelize(rtip, sizeVoxel, levelOfDetail, create_boxes, callBackData);
212 
213  mk_comb(gedp->ged_wdbp, voxDat.newname, &voxDat.content.l, 1, "plastic", "sh=4 sp=0.5 di=0.5 re=0.1", 0, 1000, 0, 0, 100, 0, 0, 0);
214 
215  mk_freemembers(&voxDat.content.l);
216  rt_free_rti(rtip);
217 
218  return GED_OK;
219 }
220 
221 
222 /*
223  * Local Variables:
224  * tab-width: 8
225  * mode: C
226  * indent-tabs-mode: t
227  * c-file-style: "stroustrup"
228  * End:
229  * ex: shiftwidth=4 tabstop=8
230  */
void usage(struct ged *gedp)
Definition: coil.c:315
#define GED_OK
Definition: ged.h:55
point_t mdl_min
min corner of model bounding RPP
Definition: raytrace.h:1769
char * newname
Definition: voxelize.c:46
void voxelize(struct rt_i *rtip, fastf_t voxelSize[3], int levelOfDetail, void(*create_boxes)(void *callBackData, int x, int y, int z, const char *regionName, fastf_t percentageFill), void *callBackData)
Definition: voxels.c:147
Definition: ged.h:338
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
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
struct rt_wdb * ged_wdbp
Definition: ged.h:340
Definition: wdb.h:64
char * bu_optarg
Definition: globals.c:91
Header file for the BRL-CAD common definitions.
int bu_optind
Definition: globals.c:89
#define WMOP_UNION
Definition: wdb.h:887
int bu_getopt(int nargc, char *const nargv[], const char *ostr)
Definition: getopt.c:43
struct bu_list l
Definition: wdb.h:65
#define GED_ERROR
Definition: ged.h:61
#define HIDDEN
Definition: common.h:86
struct wmember content
Definition: voxelize.c:47
#define GED_CHECK_DATABASE_OPEN(_gedp, _flags)
Definition: ged.h:114
int mk_rpp(struct rt_wdb *fp, const char *name, const point_t min, const point_t max)
char * bu_vls_strgrab(struct bu_vls *vp)
Definition: vls.c:290
#define LOOKUP_QUIET
Definition: raytrace.h:893
struct wmember * mk_addmember(const char *name, struct bu_list *headp, mat_t mat, int op)
Definition: reg.c:181
struct bu_vls * bu_vls_vlsinit(void)
Definition: vls.c:91
struct bu_vls * ged_result_str
Definition: ged.h:357
int mk_comb(struct rt_wdb *wdbp, const char *combname, struct bu_list *headp, int region_kind, const char *shadername, const char *shaderargs, const unsigned char *rgb, int id, int air, int material, int los, int inherit, int append_ok, int gift_semantics)
Definition: reg.c:230
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
struct rt_wdb * wdbp
Definition: voxelize.c:45
#define BU_LIST_INIT(_hp)
Definition: list.h:148
fastf_t * bbMin
Definition: voxelize.c:43
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 GED_HELP
Definition: ged.h:62
int ged_voxelize(struct ged *gedp, int argc, const char *argv[])
Definition: voxelize.c:93
fastf_t threshold
Definition: voxelize.c:42
double dbi_local2base
local2mm
Definition: raytrace.h:807
void mk_freemembers(struct bu_list *headp)
Definition: reg.c:216
ustring fill
HIDDEN void create_boxes(void *callBackData, int x, int y, int z, const char *a, fastf_t fill)
Definition: voxelize.c:51
Definition: vls.h:56
double fastf_t
Definition: defines.h:300
fastf_t sizeVoxel[3]
Definition: voxelize.c:44