BRL-CAD
bot_merge.c
Go to the documentation of this file.
1 /* B O T _ M E R G 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/bot_merge.c
21  *
22  * The bot_merge command.
23  *
24  */
25 
26 #include "common.h"
27 
28 #include <stdlib.h>
29 #include <ctype.h>
30 #include <string.h>
31 
32 #include "rtgeom.h"
33 
34 #include "./ged_private.h"
35 
36 
37 int
38 ged_bot_merge(struct ged *gedp, int argc, const char *argv[])
39 {
40  struct directory *dp, *new_dp;
41  struct rt_db_internal intern;
42  struct rt_bot_internal **bots;
43  int i, idx;
44  int avail_vert, avail_face;
45  size_t face;
46  static const char *usage = "bot_dest bot1_src [botn_src]";
47 
50  GED_CHECK_ARGC_GT_0(gedp, argc, GED_ERROR);
51 
52  /* initialize result */
53  bu_vls_trunc(gedp->ged_result_str, 0);
54 
55  /* must be wanting help */
56  if (argc == 1) {
57  bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage);
58  return GED_HELP;
59  }
60 
61  bots = (struct rt_bot_internal **)bu_calloc(argc, sizeof(struct rt_bot_internal *), "bot internal");
62 
63  /* create a new bot */
64  BU_ALLOC(bots[0], struct rt_bot_internal);
65  bots[0]->mode = 0;
66  bots[0]->orientation = RT_BOT_UNORIENTED;
67  bots[0]->bot_flags = 0;
68  bots[0]->num_vertices = 0;
69  bots[0]->num_faces = 0;
70  bots[0]->faces = (int *)0;
71  bots[0]->vertices = (fastf_t *)0;
72  bots[0]->thickness = (fastf_t *)0;
73  bots[0]->face_mode = (struct bu_bitv*)0;
74  bots[0]->num_normals = 0;
75  bots[0]->normals = (fastf_t *)0;
76  bots[0]->num_face_normals = 0;
77  bots[0]->face_normals = 0;
78  bots[0]->magic = RT_BOT_INTERNAL_MAGIC;
79 
80 
81  /* read in all the bots */
82  for (idx = 1, i = 2; i < argc; i++) {
83  if ((dp = db_lookup(gedp->ged_wdbp->dbip, argv[i], LOOKUP_NOISY)) == RT_DIR_NULL) {
84  continue;
85  }
86 
88 
89  if (intern.idb_major_type != DB5_MAJORTYPE_BRLCAD || intern.idb_minor_type != DB5_MINORTYPE_BRLCAD_BOT) {
90  bu_vls_printf(gedp->ged_result_str, "%s: %s is not a BOT solid! Skipping.\n", argv[0], argv[i]);
91  continue;
92  }
93 
94  bots[idx] = (struct rt_bot_internal *)intern.idb_ptr;
95 
96  intern.idb_ptr = (void *)0;
97 
98  RT_BOT_CK_MAGIC(bots[idx]);
99 
100  bots[0]->num_vertices += bots[idx]->num_vertices;
101  bots[0]->num_faces += bots[idx]->num_faces;
102 
103  idx++;
104  }
105 
106  if (idx == 1) return GED_ERROR;
107 
108 
109  for (i = 1; i < idx; i++) {
110  /* check for surface normals */
111  if (bots[0]->mode) {
112  if (bots[0]->mode != bots[i]->mode) {
113  bu_vls_printf(gedp->ged_result_str, "%s: Warning: not all bots share same mode\n", argv[0]);
114  }
115  } else {
116  bots[0]->mode = bots[i]->mode;
117  }
118 
119  if (bots[i]->bot_flags & RT_BOT_HAS_SURFACE_NORMALS) bots[0]->bot_flags |= RT_BOT_HAS_SURFACE_NORMALS;
120  if (bots[i]->bot_flags & RT_BOT_USE_NORMALS) bots[0]->bot_flags |= RT_BOT_USE_NORMALS;
121 
122  if (bots[0]->orientation) {
123  if (bots[i]->orientation == RT_BOT_UNORIENTED) {
124  bots[0]->orientation = RT_BOT_UNORIENTED;
125  } else {
126  bots[i]->magic = 1; /* set flag to reverse order of faces */
127  }
128  } else {
129  bots[0]->orientation = bots[i]->orientation;
130  }
131  }
132 
133 
134  bots[0]->vertices = (fastf_t *)bu_calloc(bots[0]->num_vertices*3, sizeof(fastf_t), "verts");
135  bots[0]->faces = (int *)bu_calloc(bots[0]->num_faces*3, sizeof(int), "verts");
136 
137  if (bots[0]->mode == RT_BOT_PLATE || bots[0]->mode == RT_BOT_PLATE_NOCOS) {
138  bots[0]->thickness = (fastf_t *)bu_calloc(bots[0]->num_faces, sizeof(fastf_t), "thickness");
139  bots[0]->face_mode = (struct bu_bitv *)bu_calloc(bots[0]->num_faces, sizeof(struct bu_bitv), "face_mode");
140  }
141 
142  avail_vert = 0;
143  avail_face = 0;
144 
145 
146  for (i = 1; i < idx; i++) {
147  /* copy the vertices */
148  memcpy(&bots[0]->vertices[3*avail_vert], bots[i]->vertices, bots[i]->num_vertices*3*sizeof(fastf_t));
149 
150  /* copy/convert the faces, potentially maintaining a common orientation */
151  if (bots[0]->orientation != RT_BOT_UNORIENTED && bots[i]->magic != RT_BOT_INTERNAL_MAGIC) {
152  /* copy and reverse */
153  for (face=0; face < bots[i]->num_faces; face++) {
154  /* copy the 3 verts of this face and convert to new index */
155  bots[0]->faces[avail_face*3+face*3+2] = bots[i]->faces[face*3 ] + avail_vert;
156  bots[0]->faces[avail_face*3+face*3+1] = bots[i]->faces[face*3+1] + avail_vert;
157  bots[0]->faces[avail_face*3+face*3 ] = bots[i]->faces[face*3+2] + avail_vert;
158 
159  if (bots[0]->mode == RT_BOT_PLATE || bots[0]->mode == RT_BOT_PLATE_NOCOS) {
160  bots[0]->thickness[avail_face+face] = bots[i]->thickness[face];
161  bots[0]->face_mode[avail_face+face] = bots[i]->face_mode[face];
162  }
163  }
164  } else {
165  /* just copy */
166  for (face=0; face < bots[i]->num_faces; face++) {
167  /* copy the 3 verts of this face and convert to new index */
168  bots[0]->faces[avail_face*3+face*3 ] = bots[i]->faces[face*3 ] + avail_vert;
169  bots[0]->faces[avail_face*3+face*3+1] = bots[i]->faces[face*3+1] + avail_vert;
170  bots[0]->faces[avail_face*3+face*3+2] = bots[i]->faces[face*3+2] + avail_vert;
171 
172  if (bots[0]->mode == RT_BOT_PLATE || bots[0]->mode == RT_BOT_PLATE_NOCOS) {
173  bots[0]->thickness[avail_face+face] = bots[i]->thickness[face];
174  bots[0]->face_mode[avail_face+face] = bots[i]->face_mode[face];
175  }
176  }
177  }
178 
179  /* copy surface normals */
180  if (bots[0]->bot_flags == RT_BOT_HAS_SURFACE_NORMALS) {
181  bu_log("not yet copying surface normals\n");
182  if (bots[i]->bot_flags == RT_BOT_HAS_SURFACE_NORMALS) {
183  } else {
184  }
185  }
186 
187  avail_vert += bots[i]->num_vertices;
188  avail_face += bots[i]->num_faces;
189  }
190 
191  RT_DB_INTERNAL_INIT(&intern);
192  intern.idb_type = ID_BOT;
193  intern.idb_major_type = DB5_MAJORTYPE_BRLCAD;
194  intern.idb_minor_type = DB5_MINORTYPE_BRLCAD_BOT;
195  intern.idb_meth = &OBJ[ID_BOT];
196  intern.idb_ptr = (void *)bots[0];
197 
198  GED_DB_DIRADD(gedp, new_dp, argv[1], RT_DIR_PHONY_ADDR, 0, RT_DIR_SOLID, (void *)&intern.idb_type, GED_ERROR);
199  GED_DB_PUT_INTERNAL(gedp, new_dp, &intern, &rt_uniresource, GED_ERROR);
200 
201  bu_free(bots, "bots");
202 
203  return GED_OK;
204 }
205 
206 
207 /*
208  * Local Variables:
209  * tab-width: 8
210  * mode: C
211  * indent-tabs-mode: t
212  * c-file-style: "stroustrup"
213  * End:
214  * ex: shiftwidth=4 tabstop=8
215  */
void usage(struct ged *gedp)
Definition: coil.c:315
#define GED_DB_DIRADD(_gedp, _dp, _name, _laddr, _len, _dirflags, _ptr, _flags)
Definition: ged.h:213
#define GED_OK
Definition: ged.h:55
void bu_log(const char *,...) _BU_ATTR_PRINTF12
Definition: log.c:176
#define RT_BOT_INTERNAL_MAGIC
Definition: magic.h:85
Definition: ged.h:338
const mat_t bn_mat_identity
Matrix and vector functionality.
Definition: mat.c:46
struct db_i * dbip
Definition: raytrace.h:1266
void bu_vls_trunc(struct bu_vls *vp, int len)
Definition: vls.c:198
#define ID_BOT
Bag o' triangles.
Definition: raytrace.h:488
#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
Header file for the BRL-CAD common definitions.
#define GED_ERROR
Definition: ged.h:61
#define GED_DB_PUT_INTERNAL(_gedp, _dp, _intern, _resource, _flags)
Definition: ged.h:243
int idb_major_type
Definition: raytrace.h:192
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 BU_ALLOC(_ptr, _type)
Definition: malloc.h:223
void * bu_calloc(size_t nelem, size_t elsize, const char *str)
Definition: malloc.c:321
#define RT_DIR_SOLID
this name is a solid
Definition: raytrace.h:883
#define RT_DB_INTERNAL_INIT(_p)
Definition: raytrace.h:199
const struct rt_functab * idb_meth
for ft_ifree(), etc.
Definition: raytrace.h:194
#define RT_DIR_PHONY_ADDR
Special marker for d_addr field.
Definition: raytrace.h:879
oldeumate l2 magic
Definition: nmg_mod.c:3843
struct bu_vls * ged_result_str
Definition: ged.h:357
void * idb_ptr
Definition: raytrace.h:195
int ged_bot_merge(struct ged *gedp, int argc, const char *argv[])
Definition: bot_merge.c:38
const struct rt_functab OBJ[]
Definition: table.c:159
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 GED_HELP
Definition: ged.h:62
int idb_minor_type
ID_xxx.
Definition: raytrace.h:193
#define GED_DB_GET_INTERNAL(_gedp, _intern, _dp, _mat, _resource, _flags)
Definition: ged.h:233
void bu_free(void *ptr, const char *str)
Definition: malloc.c:328
Definition: bitv.h:105
#define GED_CHECK_READ_ONLY(_gedp, _flags)
Definition: ged.h:181
double fastf_t
Definition: defines.h:300
eu1 orientation
Definition: nmg_mod.c:3916