1 /*
2   Teem: Tools to process and visualize scientific data and images             .
3   Copyright (C) 2012, 2011, 2010, 2009  University of Chicago
4   Copyright (C) 2008, 2007, 2006, 2005  Gordon Kindlmann
5   Copyright (C) 2004, 2003, 2002, 2001, 2000, 1999, 1998  University of Utah
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   (LGPL) as published by the Free Software Foundation; either
10   version 2.1 of the License, or (at your option) any later version.
11   The terms of redistributing and/or modifying this software also
12   include exceptions to the LGPL that facilitate static linking.
13 
14   This library is distributed in the hope that it will be useful,
15   but WITHOUT ANY WARRANTY; without even the implied warranty of
16   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17   Lesser General Public License for more details.
18 
19   You should have received a copy of the GNU Lesser General Public License
20   along with this library; if not, write to Free Software Foundation, Inc.,
21   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
22 */
23 
24 #include "echo.h"
25 #include "privateEcho.h"
26 
27 typedef void (*_echoBoundsGet_t)(echoPos_t lo[3], echoPos_t hi[3],
28                                  echoObject *obj);
29 
30 extern _echoBoundsGet_t _echoBoundsGet[ECHO_TYPE_NUM];
31 
32 #define BNDS_TMPL(TYPE, BODY)                                             \
33 void                                                                      \
34 _echo##TYPE##_bounds(echoPos_t lo[3], echoPos_t hi[3], echo##TYPE *obj) { \
35   int dummy=0;                                                            \
36                                                                           \
37   do { BODY dummy=dummy;} while (0);                                      \
38   lo[0] -= ECHO_EPSILON;                                                  \
39   lo[1] -= ECHO_EPSILON;                                                  \
40   lo[2] -= ECHO_EPSILON;                                                  \
41   hi[0] += ECHO_EPSILON;                                                  \
42   hi[1] += ECHO_EPSILON;                                                  \
43   hi[2] += ECHO_EPSILON;                                                  \
44   return;                                                                 \
45 }
46 
47 BNDS_TMPL(Sphere,
48           lo[0] = obj->pos[0] - obj->rad;
49           lo[1] = obj->pos[1] - obj->rad;
50           lo[2] = obj->pos[2] - obj->rad;
51           hi[0] = obj->pos[0] + obj->rad;
52           hi[1] = obj->pos[1] + obj->rad;
53           hi[2] = obj->pos[2] + obj->rad;
54           )
55 
56 BNDS_TMPL(Cylinder,
57           AIR_UNUSED(obj);
58           ELL_3V_SET(lo, -1, -1, -1);
59           ELL_3V_SET(hi,  1,  1,  1);
60           )
61 
62 BNDS_TMPL(Superquad,
63           AIR_UNUSED(obj);
64           ELL_3V_SET(lo, -1, -1, -1);
65           ELL_3V_SET(hi,  1,  1,  1);
66           )
67 
68 BNDS_TMPL(Cube,
69           AIR_UNUSED(obj);
70           ELL_3V_SET(lo, -1, -1, -1);
71           ELL_3V_SET(hi,  1,  1,  1);
72           )
73 
74 BNDS_TMPL(Triangle,
75           ELL_3V_COPY(lo, obj->vert[0]);
76           ELL_3V_MIN(lo, lo, obj->vert[1]);
77           ELL_3V_MIN(lo, lo, obj->vert[2]);
78           ELL_3V_COPY(hi, obj->vert[0]);
79           ELL_3V_MAX(hi, hi, obj->vert[1]);
80           ELL_3V_MAX(hi, hi, obj->vert[2]);
81           )
82 
83 BNDS_TMPL(Rectangle,
84           echoPos_t v[3][3];
85 
86           ELL_3V_COPY(lo, obj->origin);
87           ELL_3V_ADD2(v[0], lo, obj->edge0);
88           ELL_3V_ADD2(v[1], lo, obj->edge1);
89           ELL_3V_ADD2(v[2], v[0], obj->edge1);
90           ELL_3V_MIN(lo, lo, v[0]);
91           ELL_3V_MIN(lo, lo, v[1]);
92           ELL_3V_MIN(lo, lo, v[2]);
93           ELL_3V_COPY(hi, obj->origin);
94           ELL_3V_MAX(hi, hi, v[0]);
95           ELL_3V_MAX(hi, hi, v[1]);
96           ELL_3V_MAX(hi, hi, v[2]);
97           )
98 
99 BNDS_TMPL(TriMesh,
100           ELL_3V_COPY(lo, obj->min);
101           ELL_3V_COPY(hi, obj->max);
102           )
103 
104 BNDS_TMPL(Isosurface,
105           AIR_UNUSED(obj);
106           fprintf(stderr, "_echoIsosurface_bounds: unimplemented!\n");
107           )
108 
109 BNDS_TMPL(AABBox,
110           ELL_3V_COPY(lo, obj->min);
111           ELL_3V_COPY(hi, obj->max);
112           )
113 
114 BNDS_TMPL(List,
115           unsigned int i;
116           echoPos_t l[3];
117           echoPos_t h[3];
118           echoObject *o;
119 
120           ELL_3V_SET(lo, ECHO_POS_MAX, ECHO_POS_MAX, ECHO_POS_MAX);
121           ELL_3V_SET(hi, ECHO_POS_MIN, ECHO_POS_MIN, ECHO_POS_MIN);
122           for (i=0; i<obj->objArr->len; i++) {
123             o = obj->obj[i];
124             _echoBoundsGet[o->type](l, h, o);
125             ELL_3V_MIN(lo, lo, l);
126             ELL_3V_MAX(hi, hi, h);
127           }
128           )
129 
130 BNDS_TMPL(Split,
131           AIR_UNUSED(obj);
132           fprintf(stderr, "_echoSplit_bounds: unimplemented!\n");
133           )
134 
135 BNDS_TMPL(Instance,
136           echoPos_t a[8][4];
137           echoPos_t b[8][4];
138           echoPos_t l[3];
139           echoPos_t h[3];
140 
141           _echoBoundsGet[obj->obj->type](l, h, obj->obj);
142           ELL_4V_SET(a[0], l[0], l[1], l[2], 1);
143           ELL_4V_SET(a[1], h[0], l[1], l[2], 1);
144           ELL_4V_SET(a[2], l[0], h[1], l[2], 1);
145           ELL_4V_SET(a[3], h[0], h[1], l[2], 1);
146           ELL_4V_SET(a[4], l[0], l[1], h[2], 1);
147           ELL_4V_SET(a[5], h[0], l[1], h[2], 1);
148           ELL_4V_SET(a[6], l[0], h[1], h[2], 1);
149           ELL_4V_SET(a[7], h[0], h[1], h[2], 1);
150           ELL_4MV_MUL(b[0], obj->M, a[0]); ELL_4V_HOMOG(b[0], b[0]);
151           ELL_4MV_MUL(b[1], obj->M, a[1]); ELL_4V_HOMOG(b[1], b[1]);
152           ELL_4MV_MUL(b[2], obj->M, a[2]); ELL_4V_HOMOG(b[2], b[2]);
153           ELL_4MV_MUL(b[3], obj->M, a[3]); ELL_4V_HOMOG(b[3], b[3]);
154           ELL_4MV_MUL(b[4], obj->M, a[4]); ELL_4V_HOMOG(b[4], b[4]);
155           ELL_4MV_MUL(b[5], obj->M, a[5]); ELL_4V_HOMOG(b[5], b[5]);
156           ELL_4MV_MUL(b[6], obj->M, a[6]); ELL_4V_HOMOG(b[6], b[6]);
157           ELL_4MV_MUL(b[7], obj->M, a[7]); ELL_4V_HOMOG(b[7], b[7]);
158           ELL_3V_MIN(lo, b[0], b[1]);
159           ELL_3V_MIN(lo, lo, b[2]);
160           ELL_3V_MIN(lo, lo, b[3]);
161           ELL_3V_MIN(lo, lo, b[4]);
162           ELL_3V_MIN(lo, lo, b[5]);
163           ELL_3V_MIN(lo, lo, b[6]);
164           ELL_3V_MIN(lo, lo, b[7]);
165           ELL_3V_MAX(hi, b[0], b[1]);
166           ELL_3V_MAX(hi, hi, b[2]);
167           ELL_3V_MAX(hi, hi, b[3]);
168           ELL_3V_MAX(hi, hi, b[4]);
169           ELL_3V_MAX(hi, hi, b[5]);
170           ELL_3V_MAX(hi, hi, b[6]);
171           ELL_3V_MAX(hi, hi, b[7]);
172           )
173 
174 _echoBoundsGet_t
175 _echoBoundsGet[ECHO_TYPE_NUM] = {
176   (_echoBoundsGet_t)_echoSphere_bounds,
177   (_echoBoundsGet_t)_echoCylinder_bounds,
178   (_echoBoundsGet_t)_echoSuperquad_bounds,
179   (_echoBoundsGet_t)_echoCube_bounds,
180   (_echoBoundsGet_t)_echoTriangle_bounds,
181   (_echoBoundsGet_t)_echoRectangle_bounds,
182   (_echoBoundsGet_t)_echoTriMesh_bounds,
183   (_echoBoundsGet_t)_echoIsosurface_bounds,
184   (_echoBoundsGet_t)_echoAABBox_bounds,
185   (_echoBoundsGet_t)_echoSplit_bounds,
186   (_echoBoundsGet_t)_echoList_bounds,
187   (_echoBoundsGet_t)_echoInstance_bounds,
188 };
189 
190 void
echoBoundsGet(echoPos_t * lo,echoPos_t * hi,echoObject * obj)191 echoBoundsGet(echoPos_t *lo, echoPos_t *hi, echoObject *obj) {
192   _echoBoundsGet[obj->type](lo, hi, obj);
193 }
194