BRL-CAD
nmg_mirror.c
Go to the documentation of this file.
1 /* N M G _ M I R R O R . C
2  * BRL-CAD
3  *
4  * Copyright (c) 2009-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 primitives/nmg/nmg_mirror.c
21  *
22  * mirror support
23  *
24  */
25 
26 #include "common.h"
27 
28 #include "raytrace.h"
29 #include "rtgeom.h"
30 
31 
32 /**
33  * Given a pointer to an internal GED database object, mirror the
34  * object's values about the given transformation matrix.
35  */
36 int
37 rt_nmg_mirror(struct rt_db_internal *ip, register const plane_t plane)
38 {
39  struct model *nmg;
40 
41  mat_t mirmat;
42  mat_t rmat;
43  mat_t temp;
44  vect_t nvec;
45  vect_t xvec;
46  vect_t mirror_dir;
47  point_t mirror_pt;
48  fastf_t ang;
49 
50  int i;
51  struct nmgregion *r;
52  struct shell *s;
53  struct bu_ptbl table;
54  struct vertex *v;
55 
56  static point_t origin = {0.0, 0.0, 0.0};
57 
58  static const struct bn_tol tol = {
59  BN_TOL_MAGIC, 0.0005, 0.0005*0.0005, 1e-6, 1-1e-6
60  };
61 
63 
64  nmg = (struct model *)ip->idb_ptr;
65  NMG_CK_MODEL(nmg);
66 
67  MAT_IDN(mirmat);
68 
69  VMOVE(mirror_dir, plane);
70  VSCALE(mirror_pt, plane, plane[W]);
71 
72  /* Build mirror transform matrix, for those who need it. */
73  /* First, perform a mirror down the X axis */
74  mirmat[0] = -1.0;
75 
76  /* Create the rotation matrix */
77  VSET(xvec, 1, 0, 0);
78  VCROSS(nvec, xvec, mirror_dir);
79  VUNITIZE(nvec);
80  ang = -acos(VDOT(xvec, mirror_dir));
81  bn_mat_arb_rot(rmat, origin, nvec, ang*2.0);
82 
83  /* Add the rotation to mirmat */
84  MAT_COPY(temp, mirmat);
85  bn_mat_mul(mirmat, temp, rmat);
86 
87  /* Add the translation to mirmat */
88  mirmat[3 + X*4] += mirror_pt[X] * mirror_dir[X];
89  mirmat[3 + Y*4] += mirror_pt[Y] * mirror_dir[Y];
90  mirmat[3 + Z*4] += mirror_pt[Z] * mirror_dir[Z];
91 
92  /* move every vertex */
93  nmg_vertex_tabulate(&table, &nmg->magic);
94  for (i=0; i<BU_PTBL_END(&table); i++) {
95  point_t pt;
96 
97  v = (struct vertex *)BU_PTBL_GET(&table, i);
98  NMG_CK_VERTEX(v);
99 
100  VMOVE(pt, v->vg_p->coord);
101  MAT4X3PNT(v->vg_p->coord, mirmat, pt);
102  }
103 
104  bu_ptbl_reset(&table);
105 
106  nmg_face_tabulate(&table, &nmg->magic);
107  for (i=0; i<BU_PTBL_END(&table); i++) {
108  struct face *f;
109 
110  f = (struct face *)BU_PTBL_GET(&table, i);
111  NMG_CK_FACE(f);
112 
113  if (!f->g.magic_p)
114  continue;
115 
116  if (*f->g.magic_p != NMG_FACE_G_PLANE_MAGIC) {
117  bu_log("Sorry, can only mirror NMG solids with planar faces\n");
118  bu_ptbl_free(&table);
119  return 1;
120  }
121  }
122 
123  for (BU_LIST_FOR (r, nmgregion, &nmg->r_hd)) {
124  for (BU_LIST_FOR (s, shell, &r->s_hd)) {
125  nmg_invert_shell(s);
126  }
127  }
128 
129 
130  for (i=0; i<BU_PTBL_END(&table); i++) {
131  struct face *f;
132  struct faceuse *fu;
133 
134  f = (struct face *)BU_PTBL_GET(&table, i);
135  NMG_CK_FACE(f);
136 
137  fu = f->fu_p;
138  if (fu->orientation != OT_SAME) {
139  fu = fu->fumate_p;
140  }
141  if (fu->orientation != OT_SAME) {
142  bu_log("ERROR: Unexpected NMG face orientation\n");
143  bu_ptbl_free(&table);
144  return 2;
145  }
146 
147  if (nmg_calc_face_g(fu)) {
148  bu_log("ERROR: Unable to calculate NMG faces for mirroring\n");
149  bu_ptbl_free(&table);
150  return 3;
151  }
152  }
153 
154  bu_ptbl_free(&table);
155 
156  /* FIXME: why do we need to rebound? should mirroring really
157  * require a tolerance??
158  */
159  nmg_rebound(nmg, &tol);
160 
161  return 0;
162 }
163 
164 
165 /*
166  * Local Variables:
167  * tab-width: 8
168  * mode: C
169  * indent-tabs-mode: t
170  * c-file-style: "stroustrup"
171  * End:
172  * ex: shiftwidth=4 tabstop=8
173  */
#define BU_LIST_FOR(p, structure, hp)
Definition: list.h:365
void bu_log(const char *,...) _BU_ATTR_PRINTF12
Definition: log.c:176
if lu s
Definition: nmg_mod.c:3860
#define VSET(a, b, c, d)
Definition: color.c:53
#define BN_TOL_MAGIC
Definition: magic.h:74
void nmg_rebound(struct model *m, const struct bn_tol *tol)
Definition: nmg_misc.c:2072
Header file for the BRL-CAD common definitions.
void bu_ptbl_reset(struct bu_ptbl *b)
Definition: ptbl.c:49
int nmg_calc_face_g(struct faceuse *fu)
Definition: nmg_misc.c:1786
void nmg_invert_shell(struct shell *s)
Definition: nmg_mod.c:890
Definition: ptbl.h:62
Definition: color.c:49
int rt_nmg_mirror(struct rt_db_internal *ip, register const plane_t plane)
Definition: nmg_mirror.c:37
#define RT_CK_DB_INTERNAL(_p)
Definition: raytrace.h:207
#define BU_PTBL_GET(ptbl, i)
Definition: ptbl.h:108
void bn_mat_mul(mat_t o, const mat_t a, const mat_t b)
Support for uniform tolerances.
Definition: tol.h:71
#define NMG_FACE_G_PLANE_MAGIC
Definition: magic.h:125
void bu_ptbl_free(struct bu_ptbl *b)
Definition: ptbl.c:226
void * idb_ptr
Definition: raytrace.h:195
#define BU_PTBL_END(ptbl)
Definition: ptbl.h:106
Definition: color.c:51
void nmg_face_tabulate(struct bu_ptbl *tab, const uint32_t *magic_p)
Definition: nmg_info.c:2247
double fastf_t
Definition: defines.h:300
void bn_mat_arb_rot(mat_t m, const point_t pt, const vect_t dir, const fastf_t ang)
Definition: mat.c:987
Definition: color.c:50
void nmg_vertex_tabulate(struct bu_ptbl *tab, const uint32_t *magic_p)
Definition: nmg_info.c:1985