1 |
|
|
/* |
2 |
|
|
Teem: Tools to process and visualize scientific data and images . |
3 |
|
|
Copyright (C) 2013, 2012, 2011, 2010, 2009 University of Chicago |
4 |
|
|
Copyright (C) 2010, 2009, 2008 Thomas Schultz |
5 |
|
|
Copyright (C) 2008, 2007, 2006, 2005 Gordon Kindlmann |
6 |
|
|
Copyright (C) 2004, 2003, 2002, 2001, 2000, 1999, 1998 University of Utah |
7 |
|
|
|
8 |
|
|
This library is free software; you can redistribute it and/or |
9 |
|
|
modify it under the terms of the GNU Lesser General Public License |
10 |
|
|
(LGPL) as published by the Free Software Foundation; either |
11 |
|
|
version 2.1 of the License, or (at your option) any later version. |
12 |
|
|
The terms of redistributing and/or modifying this software also |
13 |
|
|
include exceptions to the LGPL that facilitate static linking. |
14 |
|
|
|
15 |
|
|
This library is distributed in the hope that it will be useful, |
16 |
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of |
17 |
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
18 |
|
|
Lesser General Public License for more details. |
19 |
|
|
|
20 |
|
|
You should have received a copy of the GNU Lesser General Public License |
21 |
|
|
along with this library; if not, write to Free Software Foundation, Inc., |
22 |
|
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
23 |
|
|
*/ |
24 |
|
|
|
25 |
|
|
|
26 |
|
|
#include "limn.h" |
27 |
|
|
|
28 |
|
|
int |
29 |
|
|
limnPolyDataCube(limnPolyData *pld, |
30 |
|
|
unsigned int infoBitFlag, |
31 |
|
|
int sharpEdge) { |
32 |
|
|
static const char me[]="limnPolyDataCube"; |
33 |
|
|
unsigned int vertNum, vertIdx, primNum, indxNum, cnum, ci; |
34 |
|
|
|
35 |
|
|
vertNum = sharpEdge ? 6*4 : 8; |
36 |
|
|
primNum = 1; |
37 |
|
|
indxNum = 6*4; |
38 |
|
|
if (limnPolyDataAlloc(pld, infoBitFlag, vertNum, indxNum, primNum)) { |
39 |
|
|
biffAddf(LIMN, "%s: couldn't allocate output", me); |
40 |
|
|
return 1; |
41 |
|
|
} |
42 |
|
|
pld->type[0] = limnPrimitiveQuads; |
43 |
|
|
pld->icnt[0] = indxNum; |
44 |
|
|
|
45 |
|
|
vertIdx = 0; |
46 |
|
|
cnum = sharpEdge ? 3 : 1; |
47 |
|
|
for (ci=0; ci<cnum; ci++) { |
48 |
|
|
ELL_4V_SET(pld->xyzw + 4*vertIdx, -1, -1, -1, 1); vertIdx++; |
49 |
|
|
} |
50 |
|
|
for (ci=0; ci<cnum; ci++) { |
51 |
|
|
ELL_4V_SET(pld->xyzw + 4*vertIdx, -1, 1, -1, 1); vertIdx++; |
52 |
|
|
} |
53 |
|
|
for (ci=0; ci<cnum; ci++) { |
54 |
|
|
ELL_4V_SET(pld->xyzw + 4*vertIdx, 1, 1, -1, 1); vertIdx++; |
55 |
|
|
} |
56 |
|
|
for (ci=0; ci<cnum; ci++) { |
57 |
|
|
ELL_4V_SET(pld->xyzw + 4*vertIdx, 1, -1, -1, 1); vertIdx++; |
58 |
|
|
} |
59 |
|
|
for (ci=0; ci<cnum; ci++) { |
60 |
|
|
ELL_4V_SET(pld->xyzw + 4*vertIdx, -1, -1, 1, 1); vertIdx++; |
61 |
|
|
} |
62 |
|
|
for (ci=0; ci<cnum; ci++) { |
63 |
|
|
ELL_4V_SET(pld->xyzw + 4*vertIdx, -1, 1, 1, 1); vertIdx++; |
64 |
|
|
} |
65 |
|
|
for (ci=0; ci<cnum; ci++) { |
66 |
|
|
ELL_4V_SET(pld->xyzw + 4*vertIdx, 1, 1, 1, 1); vertIdx++; |
67 |
|
|
} |
68 |
|
|
for (ci=0; ci<cnum; ci++) { |
69 |
|
|
ELL_4V_SET(pld->xyzw + 4*vertIdx, 1, -1, 1, 1); vertIdx++; |
70 |
|
|
} |
71 |
|
|
|
72 |
|
|
vertIdx = 0; |
73 |
|
|
if (sharpEdge) { |
74 |
|
|
ELL_4V_SET(pld->indx + vertIdx, 0, 3, 6, 9); vertIdx += 4; |
75 |
|
|
ELL_4V_SET(pld->indx + vertIdx, 2, 14, 16, 5); vertIdx += 4; |
76 |
|
|
ELL_4V_SET(pld->indx + vertIdx, 4, 17, 18, 8); vertIdx += 4; |
77 |
|
|
ELL_4V_SET(pld->indx + vertIdx, 7, 19, 21, 10); vertIdx += 4; |
78 |
|
|
ELL_4V_SET(pld->indx + vertIdx, 1, 11, 23, 13); vertIdx += 4; |
79 |
|
|
ELL_4V_SET(pld->indx + vertIdx, 12, 22, 20, 15); vertIdx += 4; |
80 |
|
|
} else { |
81 |
|
|
ELL_4V_SET(pld->indx + vertIdx, 0, 1, 2, 3); vertIdx += 4; |
82 |
|
|
ELL_4V_SET(pld->indx + vertIdx, 0, 4, 5, 1); vertIdx += 4; |
83 |
|
|
ELL_4V_SET(pld->indx + vertIdx, 1, 5, 6, 2); vertIdx += 4; |
84 |
|
|
ELL_4V_SET(pld->indx + vertIdx, 2, 6, 7, 3); vertIdx += 4; |
85 |
|
|
ELL_4V_SET(pld->indx + vertIdx, 0, 3, 7, 4); vertIdx += 4; |
86 |
|
|
ELL_4V_SET(pld->indx + vertIdx, 4, 7, 6, 5); vertIdx += 4; |
87 |
|
|
} |
88 |
|
|
|
89 |
|
|
if ((1 << limnPolyDataInfoNorm) & infoBitFlag) { |
90 |
|
|
if (sharpEdge) { |
91 |
|
|
ELL_3V_SET(pld->norm + 3*0, 0, 0, -1); |
92 |
|
|
ELL_3V_SET(pld->norm + 3*3, 0, 0, -1); |
93 |
|
|
ELL_3V_SET(pld->norm + 3*6, 0, 0, -1); |
94 |
|
|
ELL_3V_SET(pld->norm + 3*9, 0, 0, -1); |
95 |
|
|
ELL_3V_SET(pld->norm + 3*2, -1, 0, 0); |
96 |
|
|
ELL_3V_SET(pld->norm + 3*5, -1, 0, 0); |
97 |
|
|
ELL_3V_SET(pld->norm + 3*14, -1, 0, 0); |
98 |
|
|
ELL_3V_SET(pld->norm + 3*16, -1, 0, 0); |
99 |
|
|
ELL_3V_SET(pld->norm + 3*4, 0, 1, 0); |
100 |
|
|
ELL_3V_SET(pld->norm + 3*8, 0, 1, 0); |
101 |
|
|
ELL_3V_SET(pld->norm + 3*17, 0, 1, 0); |
102 |
|
|
ELL_3V_SET(pld->norm + 3*18, 0, 1, 0); |
103 |
|
|
ELL_3V_SET(pld->norm + 3*7, 1, 0, 0); |
104 |
|
|
ELL_3V_SET(pld->norm + 3*10, 1, 0, 0); |
105 |
|
|
ELL_3V_SET(pld->norm + 3*19, 1, 0, 0); |
106 |
|
|
ELL_3V_SET(pld->norm + 3*21, 1, 0, 0); |
107 |
|
|
ELL_3V_SET(pld->norm + 3*1, 0, -1, 0); |
108 |
|
|
ELL_3V_SET(pld->norm + 3*11, 0, -1, 0); |
109 |
|
|
ELL_3V_SET(pld->norm + 3*13, 0, -1, 0); |
110 |
|
|
ELL_3V_SET(pld->norm + 3*23, 0, -1, 0); |
111 |
|
|
ELL_3V_SET(pld->norm + 3*12, 0, 0, 1); |
112 |
|
|
ELL_3V_SET(pld->norm + 3*15, 0, 0, 1); |
113 |
|
|
ELL_3V_SET(pld->norm + 3*20, 0, 0, 1); |
114 |
|
|
ELL_3V_SET(pld->norm + 3*22, 0, 0, 1); |
115 |
|
|
} else { |
116 |
|
|
float cn; |
117 |
|
|
cn = AIR_CAST(float, sqrt(3.0)); |
118 |
|
|
ELL_3V_SET(pld->norm + 3*0, -cn, -cn, -cn); |
119 |
|
|
ELL_3V_SET(pld->norm + 3*1, -cn, cn, -cn); |
120 |
|
|
ELL_3V_SET(pld->norm + 3*2, cn, cn, -cn); |
121 |
|
|
ELL_3V_SET(pld->norm + 3*3, cn, -cn, -cn); |
122 |
|
|
ELL_3V_SET(pld->norm + 3*4, -cn, -cn, cn); |
123 |
|
|
ELL_3V_SET(pld->norm + 3*5, -cn, cn, cn); |
124 |
|
|
ELL_3V_SET(pld->norm + 3*6, cn, cn, cn); |
125 |
|
|
ELL_3V_SET(pld->norm + 3*7, cn, -cn, cn); |
126 |
|
|
} |
127 |
|
|
} |
128 |
|
|
|
129 |
|
|
if ((1 << limnPolyDataInfoRGBA) & infoBitFlag) { |
130 |
|
|
for (vertIdx=0; vertIdx<pld->rgbaNum; vertIdx++) { |
131 |
|
|
ELL_4V_SET(pld->rgba + 4*vertIdx, 255, 255, 255, 255); |
132 |
|
|
} |
133 |
|
|
} |
134 |
|
|
|
135 |
|
|
return 0; |
136 |
|
|
} |
137 |
|
|
|
138 |
|
|
int |
139 |
|
|
limnPolyDataCubeTriangles(limnPolyData *pld, |
140 |
|
|
unsigned int infoBitFlag, |
141 |
|
|
int sharpEdge) { |
142 |
|
|
static const char me[]="limnPolyDataCubeTriangles"; |
143 |
|
|
unsigned int vertNum, vertIdx, primNum, indxNum, cnum, ci; |
144 |
|
|
|
145 |
|
|
vertNum = sharpEdge ? 6*4 : 8; |
146 |
|
|
primNum = 1; |
147 |
|
|
indxNum = 6*6; |
148 |
|
|
if (limnPolyDataAlloc(pld, infoBitFlag, vertNum, indxNum, primNum)) { |
149 |
|
|
biffAddf(LIMN, "%s: couldn't allocate output", me); |
150 |
|
|
return 1; |
151 |
|
|
} |
152 |
|
|
pld->type[0] = limnPrimitiveTriangles; |
153 |
|
|
pld->icnt[0] = indxNum; |
154 |
|
|
|
155 |
|
|
vertIdx = 0; |
156 |
|
|
cnum = sharpEdge ? 3 : 1; |
157 |
|
|
for (ci=0; ci<cnum; ci++) { |
158 |
|
|
ELL_4V_SET(pld->xyzw + 4*vertIdx, 1, -1, 1, 1); vertIdx++; |
159 |
|
|
} |
160 |
|
|
for (ci=0; ci<cnum; ci++) { |
161 |
|
|
ELL_4V_SET(pld->xyzw + 4*vertIdx, -1, -1, 1, 1); vertIdx++; |
162 |
|
|
} |
163 |
|
|
for (ci=0; ci<cnum; ci++) { |
164 |
|
|
ELL_4V_SET(pld->xyzw + 4*vertIdx, 1, 1, 1, 1); vertIdx++; |
165 |
|
|
} |
166 |
|
|
for (ci=0; ci<cnum; ci++) { |
167 |
|
|
ELL_4V_SET(pld->xyzw + 4*vertIdx, -1, 1, 1, 1); vertIdx++; |
168 |
|
|
} |
169 |
|
|
for (ci=0; ci<cnum; ci++) { |
170 |
|
|
ELL_4V_SET(pld->xyzw + 4*vertIdx, 1, 1, -1, 1); vertIdx++; |
171 |
|
|
} |
172 |
|
|
for (ci=0; ci<cnum; ci++) { |
173 |
|
|
ELL_4V_SET(pld->xyzw + 4*vertIdx, -1, 1, -1, 1); vertIdx++; |
174 |
|
|
} |
175 |
|
|
for (ci=0; ci<cnum; ci++) { |
176 |
|
|
ELL_4V_SET(pld->xyzw + 4*vertIdx, 1, -1, -1, 1); vertIdx++; |
177 |
|
|
} |
178 |
|
|
for (ci=0; ci<cnum; ci++) { |
179 |
|
|
ELL_4V_SET(pld->xyzw + 4*vertIdx, -1, -1, -1, 1); vertIdx++; |
180 |
|
|
} |
181 |
|
|
|
182 |
|
|
vertIdx = 0; |
183 |
|
|
if (sharpEdge) { |
184 |
|
|
ELL_3V_SET(pld->indx + vertIdx, 0, 6, 3); vertIdx += 3; |
185 |
|
|
ELL_3V_SET(pld->indx + vertIdx, 3, 6, 9); vertIdx += 3; |
186 |
|
|
|
187 |
|
|
ELL_3V_SET(pld->indx + vertIdx, 7, 12, 10); vertIdx += 3; |
188 |
|
|
ELL_3V_SET(pld->indx + vertIdx, 10, 12, 16); vertIdx += 3; |
189 |
|
|
|
190 |
|
|
ELL_3V_SET(pld->indx + vertIdx, 11, 15, 4); vertIdx += 3; |
191 |
|
|
ELL_3V_SET(pld->indx + vertIdx, 4, 15, 21); vertIdx += 3; |
192 |
|
|
|
193 |
|
|
ELL_3V_SET(pld->indx + vertIdx, 17, 14, 22); vertIdx += 3; |
194 |
|
|
ELL_3V_SET(pld->indx + vertIdx, 22, 14, 20); vertIdx += 3; |
195 |
|
|
|
196 |
|
|
ELL_3V_SET(pld->indx + vertIdx, 2, 5, 19); vertIdx += 3; |
197 |
|
|
ELL_3V_SET(pld->indx + vertIdx, 19, 5, 23); vertIdx += 3; |
198 |
|
|
|
199 |
|
|
ELL_3V_SET(pld->indx + vertIdx, 13, 8, 18); vertIdx += 3; |
200 |
|
|
ELL_3V_SET(pld->indx + vertIdx, 18, 8, 1); vertIdx += 3; |
201 |
|
|
} else { |
202 |
|
|
ELL_3V_SET(pld->indx + vertIdx, 0, 2, 1); vertIdx += 3; |
203 |
|
|
ELL_3V_SET(pld->indx + vertIdx, 1, 2, 3); vertIdx += 3; |
204 |
|
|
|
205 |
|
|
ELL_3V_SET(pld->indx + vertIdx, 2, 4, 3); vertIdx += 3; |
206 |
|
|
ELL_3V_SET(pld->indx + vertIdx, 3, 4, 5); vertIdx += 3; |
207 |
|
|
|
208 |
|
|
ELL_3V_SET(pld->indx + vertIdx, 3, 5, 1); vertIdx += 3; |
209 |
|
|
ELL_3V_SET(pld->indx + vertIdx, 1, 5, 7); vertIdx += 3; |
210 |
|
|
|
211 |
|
|
ELL_3V_SET(pld->indx + vertIdx, 5, 4, 7); vertIdx += 3; |
212 |
|
|
ELL_3V_SET(pld->indx + vertIdx, 7, 4, 6); vertIdx += 3; |
213 |
|
|
|
214 |
|
|
ELL_3V_SET(pld->indx + vertIdx, 7, 6, 1); vertIdx += 3; |
215 |
|
|
ELL_3V_SET(pld->indx + vertIdx, 1, 6, 0); vertIdx += 3; |
216 |
|
|
|
217 |
|
|
ELL_3V_SET(pld->indx + vertIdx, 4, 2, 6); vertIdx += 3; |
218 |
|
|
ELL_3V_SET(pld->indx + vertIdx, 2, 6, 0); vertIdx += 3; |
219 |
|
|
} |
220 |
|
|
|
221 |
|
|
if ((1 << limnPolyDataInfoNorm) & infoBitFlag) { |
222 |
|
|
if (sharpEdge) { |
223 |
|
|
ELL_3V_SET(pld->norm + 3*14, 0, 0, -1); |
224 |
|
|
ELL_3V_SET(pld->norm + 3*17, 0, 0, -1); |
225 |
|
|
ELL_3V_SET(pld->norm + 3*20, 0, 0, -1); |
226 |
|
|
ELL_3V_SET(pld->norm + 3*22, 0, 0, -1); |
227 |
|
|
ELL_3V_SET(pld->norm + 3* 4, -1, 0, 0); |
228 |
|
|
ELL_3V_SET(pld->norm + 3*11, -1, 0, 0); |
229 |
|
|
ELL_3V_SET(pld->norm + 3*15, -1, 0, 0); |
230 |
|
|
ELL_3V_SET(pld->norm + 3*21, -1, 0, 0); |
231 |
|
|
ELL_3V_SET(pld->norm + 3* 7, 0, 1, 0); |
232 |
|
|
ELL_3V_SET(pld->norm + 3*10, 0, 1, 0); |
233 |
|
|
ELL_3V_SET(pld->norm + 3*12, 0, 1, 0); |
234 |
|
|
ELL_3V_SET(pld->norm + 3*16, 0, 1, 0); |
235 |
|
|
ELL_3V_SET(pld->norm + 3* 1, 1, 0, 0); |
236 |
|
|
ELL_3V_SET(pld->norm + 3* 8, 1, 0, 0); |
237 |
|
|
ELL_3V_SET(pld->norm + 3*13, 1, 0, 0); |
238 |
|
|
ELL_3V_SET(pld->norm + 3*18, 1, 0, 0); |
239 |
|
|
ELL_3V_SET(pld->norm + 3* 2, 0, -1, 0); |
240 |
|
|
ELL_3V_SET(pld->norm + 3* 5, 0, -1, 0); |
241 |
|
|
ELL_3V_SET(pld->norm + 3*19, 0, -1, 0); |
242 |
|
|
ELL_3V_SET(pld->norm + 3*23, 0, -1, 0); |
243 |
|
|
ELL_3V_SET(pld->norm + 3* 0, 0, 0, 1); |
244 |
|
|
ELL_3V_SET(pld->norm + 3* 3, 0, 0, 1); |
245 |
|
|
ELL_3V_SET(pld->norm + 3* 6, 0, 0, 1); |
246 |
|
|
ELL_3V_SET(pld->norm + 3* 9, 0, 0, 1); |
247 |
|
|
} else { |
248 |
|
|
float cn; |
249 |
|
|
cn = AIR_CAST(float, 1.0/sqrt(3.0)); |
250 |
|
|
ELL_3V_SET(pld->norm + 3*0, cn, -cn, cn); |
251 |
|
|
ELL_3V_SET(pld->norm + 3*1, -cn, -cn, cn); |
252 |
|
|
ELL_3V_SET(pld->norm + 3*2, cn, cn, cn); |
253 |
|
|
ELL_3V_SET(pld->norm + 3*3, -cn, cn, cn); |
254 |
|
|
ELL_3V_SET(pld->norm + 3*4, cn, cn, -cn); |
255 |
|
|
ELL_3V_SET(pld->norm + 3*5, -cn, cn, -cn); |
256 |
|
|
ELL_3V_SET(pld->norm + 3*6, cn, -cn, -cn); |
257 |
|
|
ELL_3V_SET(pld->norm + 3*7, -cn, -cn, -cn); |
258 |
|
|
} |
259 |
|
|
} |
260 |
|
|
|
261 |
|
|
if ((1 << limnPolyDataInfoTex2) & infoBitFlag) { |
262 |
|
|
if (sharpEdge) { |
263 |
|
|
ELL_2V_SET(pld->tex2 + 2*14, 1, 1); |
264 |
|
|
ELL_2V_SET(pld->tex2 + 2*17, 0, 1); |
265 |
|
|
ELL_2V_SET(pld->tex2 + 2*20, 1, 0); |
266 |
|
|
ELL_2V_SET(pld->tex2 + 2*22, 0, 0); |
267 |
|
|
ELL_2V_SET(pld->tex2 + 2* 4, 1, 0); |
268 |
|
|
ELL_2V_SET(pld->tex2 + 2*11, 0, 0); |
269 |
|
|
ELL_2V_SET(pld->tex2 + 2*15, 0, 1); |
270 |
|
|
ELL_2V_SET(pld->tex2 + 2*21, 1, 1); |
271 |
|
|
ELL_2V_SET(pld->tex2 + 2* 7, 0, 0); |
272 |
|
|
ELL_2V_SET(pld->tex2 + 2*10, 1, 0); |
273 |
|
|
ELL_2V_SET(pld->tex2 + 2*12, 0, 1); |
274 |
|
|
ELL_2V_SET(pld->tex2 + 2*16, 1, 1); |
275 |
|
|
ELL_2V_SET(pld->tex2 + 2* 1, 0, 0); |
276 |
|
|
ELL_2V_SET(pld->tex2 + 2* 8, 1, 0); |
277 |
|
|
ELL_2V_SET(pld->tex2 + 2*13, 1, 1); |
278 |
|
|
ELL_2V_SET(pld->tex2 + 2*18, 0, 1); |
279 |
|
|
ELL_2V_SET(pld->tex2 + 2* 2, 1, 0); |
280 |
|
|
ELL_2V_SET(pld->tex2 + 2* 5, 0, 0); |
281 |
|
|
ELL_2V_SET(pld->tex2 + 2*19, 1, 1); |
282 |
|
|
ELL_2V_SET(pld->tex2 + 2*23, 0, 1); |
283 |
|
|
ELL_2V_SET(pld->tex2 + 2* 0, 1, 1); |
284 |
|
|
ELL_2V_SET(pld->tex2 + 2* 3, 0, 1); |
285 |
|
|
ELL_2V_SET(pld->tex2 + 2* 6, 1, 0); |
286 |
|
|
ELL_2V_SET(pld->tex2 + 2* 9, 0, 0); |
287 |
|
|
} else { |
288 |
|
|
ELL_2V_SET(pld->tex2 + 2*0, 1, 1); |
289 |
|
|
ELL_2V_SET(pld->tex2 + 2*1, 0, 1); |
290 |
|
|
ELL_2V_SET(pld->tex2 + 2*2, 1, 0); |
291 |
|
|
ELL_2V_SET(pld->tex2 + 2*3, 0, 0); |
292 |
|
|
ELL_2V_SET(pld->tex2 + 2*4, 1, 0); |
293 |
|
|
ELL_2V_SET(pld->tex2 + 2*5, 0, 0); |
294 |
|
|
ELL_2V_SET(pld->tex2 + 2*6, 1, 1); |
295 |
|
|
ELL_2V_SET(pld->tex2 + 2*7, 0, 1); |
296 |
|
|
} |
297 |
|
|
} |
298 |
|
|
|
299 |
|
|
if ((1 << limnPolyDataInfoTang) & infoBitFlag) { |
300 |
|
|
if (sharpEdge) { |
301 |
|
|
ELL_3V_SET(pld->tang + 3*14, 1, 0, 0); |
302 |
|
|
ELL_3V_SET(pld->tang + 3*17, 1, 0, 0); |
303 |
|
|
ELL_3V_SET(pld->tang + 3*20, 1, 0, 0); |
304 |
|
|
ELL_3V_SET(pld->tang + 3*22, 1, 0, 0); |
305 |
|
|
ELL_3V_SET(pld->tang + 3* 4, 0, -1, 0); |
306 |
|
|
ELL_3V_SET(pld->tang + 3*11, 0, -1, 0); |
307 |
|
|
ELL_3V_SET(pld->tang + 3*15, 0, -1, 0); |
308 |
|
|
ELL_3V_SET(pld->tang + 3*21, 0, -1, 0); |
309 |
|
|
ELL_3V_SET(pld->tang + 3* 7, -1, 0, 0); |
310 |
|
|
ELL_3V_SET(pld->tang + 3*10, -1, 0, 0); |
311 |
|
|
ELL_3V_SET(pld->tang + 3*12, -1, 0, 0); |
312 |
|
|
ELL_3V_SET(pld->tang + 3*16, -1, 0, 0); |
313 |
|
|
ELL_3V_SET(pld->tang + 3* 1, 0, 1, 0); |
314 |
|
|
ELL_3V_SET(pld->tang + 3* 8, 0, 1, 0); |
315 |
|
|
ELL_3V_SET(pld->tang + 3*13, 0, 1, 0); |
316 |
|
|
ELL_3V_SET(pld->tang + 3*18, 0, 1, 0); |
317 |
|
|
ELL_3V_SET(pld->tang + 3* 2, 1, 0, 0); |
318 |
|
|
ELL_3V_SET(pld->tang + 3* 5, 1, 0, 0); |
319 |
|
|
ELL_3V_SET(pld->tang + 3*19, 1, 0, 0); |
320 |
|
|
ELL_3V_SET(pld->tang + 3*23, 1, 0, 0); |
321 |
|
|
ELL_3V_SET(pld->tang + 3* 0, 1, 0, 0); |
322 |
|
|
ELL_3V_SET(pld->tang + 3* 3, 1, 0, 0); |
323 |
|
|
ELL_3V_SET(pld->tang + 3* 6, 1, 0, 0); |
324 |
|
|
ELL_3V_SET(pld->tang + 3* 9, 1, 0, 0); |
325 |
|
|
} else { |
326 |
|
|
float sn; |
327 |
|
|
sn = AIR_CAST(float, 1.0/sqrt(2.0)); |
328 |
|
|
ELL_3V_SET(pld->tang + 3*0, -sn, sn, 0); |
329 |
|
|
ELL_3V_SET(pld->tang + 3*1, sn, sn, 0); |
330 |
|
|
ELL_3V_SET(pld->tang + 3*2, -sn, -sn, 0); |
331 |
|
|
ELL_3V_SET(pld->tang + 3*3, sn, -sn, 0); |
332 |
|
|
ELL_3V_SET(pld->tang + 3*4, -sn, -sn, 0); |
333 |
|
|
ELL_3V_SET(pld->tang + 3*5, sn, -sn, 0); |
334 |
|
|
ELL_3V_SET(pld->tang + 3*6, -sn, sn, 0); |
335 |
|
|
ELL_3V_SET(pld->tang + 3*7, sn, sn, 0); |
336 |
|
|
} |
337 |
|
|
} |
338 |
|
|
|
339 |
|
|
if ((1 << limnPolyDataInfoRGBA) & infoBitFlag) { |
340 |
|
|
for (vertIdx=0; vertIdx<pld->rgbaNum; vertIdx++) { |
341 |
|
|
ELL_4V_SET(pld->rgba + 4*vertIdx, 255, 255, 255, 255); |
342 |
|
|
} |
343 |
|
|
} |
344 |
|
|
|
345 |
|
|
return 0; |
346 |
|
|
} |
347 |
|
|
|
348 |
|
|
int |
349 |
|
|
limnPolyDataOctahedron(limnPolyData *pld, |
350 |
|
|
unsigned int infoBitFlag, |
351 |
|
|
int sharpEdge) { |
352 |
|
|
static const char me[]="limnPolyDataOctahedron"; |
353 |
|
|
unsigned int vertNum, vertIdx, primNum, indxNum, cnum, ci; |
354 |
|
|
|
355 |
|
|
vertNum = sharpEdge ? 4*6 : 6; |
356 |
|
|
primNum = 1; |
357 |
|
|
indxNum = 8*3; |
358 |
|
|
if (limnPolyDataAlloc(pld, infoBitFlag, vertNum, indxNum, primNum)) { |
359 |
|
|
biffAddf(LIMN, "%s: couldn't allocate output", me); |
360 |
|
|
return 1; |
361 |
|
|
} |
362 |
|
|
pld->type[0] = limnPrimitiveTriangles; |
363 |
|
|
pld->icnt[0] = indxNum; |
364 |
|
|
|
365 |
|
|
vertIdx = 0; |
366 |
|
|
cnum = sharpEdge ? 4 : 1; |
367 |
|
|
for (ci=0; ci<cnum; ci++) { |
368 |
|
|
ELL_4V_SET(pld->xyzw + 4*vertIdx, 0, 0, 1, 1); vertIdx++; /* 0 */ |
369 |
|
|
} |
370 |
|
|
for (ci=0; ci<cnum; ci++) { |
371 |
|
|
ELL_4V_SET(pld->xyzw + 4*vertIdx, 0, 1, 0, 1); vertIdx++; /* 1 */ |
372 |
|
|
} |
373 |
|
|
for (ci=0; ci<cnum; ci++) { |
374 |
|
|
ELL_4V_SET(pld->xyzw + 4*vertIdx, 1, 0, 0, 1); vertIdx++; /* 2 */ |
375 |
|
|
} |
376 |
|
|
for (ci=0; ci<cnum; ci++) { |
377 |
|
|
ELL_4V_SET(pld->xyzw + 4*vertIdx, 0, -1, 0, 1); vertIdx++; /* 3 */ |
378 |
|
|
} |
379 |
|
|
for (ci=0; ci<cnum; ci++) { |
380 |
|
|
ELL_4V_SET(pld->xyzw + 4*vertIdx, -1, 0, 0, 1); vertIdx++; /* 4 */ |
381 |
|
|
} |
382 |
|
|
for (ci=0; ci<cnum; ci++) { |
383 |
|
|
ELL_4V_SET(pld->xyzw + 4*vertIdx, 0, 0, -1, 1); vertIdx++; /* 5 */ |
384 |
|
|
} |
385 |
|
|
|
386 |
|
|
vertIdx = 0; |
387 |
|
|
if (sharpEdge) { |
388 |
|
|
ELL_3V_SET(pld->indx + vertIdx, 0, 8, 4); vertIdx += 3; /* 0 */ |
389 |
|
|
ELL_3V_SET(pld->indx + vertIdx, 1, 15, 9); vertIdx += 3; /* 1 */ |
390 |
|
|
ELL_3V_SET(pld->indx + vertIdx, 2, 16, 12); vertIdx += 3; /* 2 */ |
391 |
|
|
ELL_3V_SET(pld->indx + vertIdx, 3, 6, 19); vertIdx += 3; /* 3 */ |
392 |
|
|
ELL_3V_SET(pld->indx + vertIdx, 5, 11, 23); vertIdx += 3; /* 4 */ |
393 |
|
|
ELL_3V_SET(pld->indx + vertIdx, 10, 14, 20); vertIdx += 3; /* 5 */ |
394 |
|
|
ELL_3V_SET(pld->indx + vertIdx, 17, 21, 13); vertIdx += 3; /* 6 */ |
395 |
|
|
ELL_3V_SET(pld->indx + vertIdx, 7, 22, 18); vertIdx += 3; /* 7 */ |
396 |
|
|
} else { |
397 |
|
|
ELL_3V_SET(pld->indx + vertIdx, 0, 2, 1); vertIdx += 3; /* 0 */ |
398 |
|
|
ELL_3V_SET(pld->indx + vertIdx, 0, 3, 2); vertIdx += 3; /* 1 */ |
399 |
|
|
ELL_3V_SET(pld->indx + vertIdx, 0, 4, 3); vertIdx += 3; /* 2 */ |
400 |
|
|
ELL_3V_SET(pld->indx + vertIdx, 0, 1, 4); vertIdx += 3; /* 3 */ |
401 |
|
|
ELL_3V_SET(pld->indx + vertIdx, 1, 2, 5); vertIdx += 3; /* 4 */ |
402 |
|
|
ELL_3V_SET(pld->indx + vertIdx, 2, 3, 5); vertIdx += 3; /* 5 */ |
403 |
|
|
ELL_3V_SET(pld->indx + vertIdx, 4, 5, 3); vertIdx += 3; /* 6 */ |
404 |
|
|
ELL_3V_SET(pld->indx + vertIdx, 1, 5, 4); vertIdx += 3; /* 7 */ |
405 |
|
|
} |
406 |
|
|
|
407 |
|
|
if ((1 << limnPolyDataInfoNorm) & infoBitFlag) { |
408 |
|
|
if (sharpEdge) { |
409 |
|
|
float cn; |
410 |
|
|
cn = AIR_CAST(float, 1.0/sqrt(3)); |
411 |
|
|
/* 0 */ |
412 |
|
|
ELL_3V_SET(pld->norm + 3*0, cn, cn, cn); |
413 |
|
|
ELL_3V_SET(pld->norm + 3*8, cn, cn, cn); |
414 |
|
|
ELL_3V_SET(pld->norm + 3*4, cn, cn, cn); |
415 |
|
|
/* 1 */ |
416 |
|
|
ELL_3V_SET(pld->norm + 3*1, cn, -cn, cn); |
417 |
|
|
ELL_3V_SET(pld->norm + 3*15, cn, -cn, cn); |
418 |
|
|
ELL_3V_SET(pld->norm + 3*9, cn, -cn, cn); |
419 |
|
|
/* 2 */ |
420 |
|
|
ELL_3V_SET(pld->norm + 3*2, -cn, -cn, cn); |
421 |
|
|
ELL_3V_SET(pld->norm + 3*16, -cn, -cn, cn); |
422 |
|
|
ELL_3V_SET(pld->norm + 3*12, -cn, -cn, cn); |
423 |
|
|
/* 3 */ |
424 |
|
|
ELL_3V_SET(pld->norm + 3*3, -cn, cn, cn); |
425 |
|
|
ELL_3V_SET(pld->norm + 3*6, -cn, cn, cn); |
426 |
|
|
ELL_3V_SET(pld->norm + 3*19, -cn, cn, cn); |
427 |
|
|
/* 4 */ |
428 |
|
|
ELL_3V_SET(pld->norm + 3*5, cn, cn, -cn); |
429 |
|
|
ELL_3V_SET(pld->norm + 3*11, cn, cn, -cn); |
430 |
|
|
ELL_3V_SET(pld->norm + 3*23, cn, cn, -cn); |
431 |
|
|
/* 5 */ |
432 |
|
|
ELL_3V_SET(pld->norm + 3*10, cn, -cn, -cn); |
433 |
|
|
ELL_3V_SET(pld->norm + 3*14, cn, -cn, -cn); |
434 |
|
|
ELL_3V_SET(pld->norm + 3*20, cn, -cn, -cn); |
435 |
|
|
/* 6 */ |
436 |
|
|
ELL_3V_SET(pld->norm + 3*17, -cn, -cn, -cn); |
437 |
|
|
ELL_3V_SET(pld->norm + 3*21, -cn, -cn, -cn); |
438 |
|
|
ELL_3V_SET(pld->norm + 3*13, -cn, -cn, -cn); |
439 |
|
|
/* 7 */ |
440 |
|
|
ELL_3V_SET(pld->norm + 3*7, -cn, cn, -cn); |
441 |
|
|
ELL_3V_SET(pld->norm + 3*22, -cn, cn, -cn); |
442 |
|
|
ELL_3V_SET(pld->norm + 3*18, -cn, cn, -cn); |
443 |
|
|
} else { |
444 |
|
|
ELL_3V_SET(pld->norm + 3*0, 0, 0, 1); /* 0 */ |
445 |
|
|
ELL_3V_SET(pld->norm + 3*1, 0, 1, 0); /* 1 */ |
446 |
|
|
ELL_3V_SET(pld->norm + 3*2, 1, 0, 0); /* 2 */ |
447 |
|
|
ELL_3V_SET(pld->norm + 3*3, 0, -1, 0); /* 3 */ |
448 |
|
|
ELL_3V_SET(pld->norm + 3*4, -1, 0, 0); /* 4 */ |
449 |
|
|
ELL_3V_SET(pld->norm + 3*5, 0, 0, -1); /* 5 */ |
450 |
|
|
} |
451 |
|
|
} |
452 |
|
|
|
453 |
|
|
if ((1 << limnPolyDataInfoRGBA) & infoBitFlag) { |
454 |
|
|
for (vertIdx=0; vertIdx<pld->rgbaNum; vertIdx++) { |
455 |
|
|
ELL_4V_SET(pld->rgba + 4*vertIdx, 255, 255, 255, 255); |
456 |
|
|
} |
457 |
|
|
} |
458 |
|
|
return 0; |
459 |
|
|
} |
460 |
|
|
|
461 |
|
|
int |
462 |
|
|
limnPolyDataCylinder(limnPolyData *pld, |
463 |
|
|
unsigned int infoBitFlag, |
464 |
|
|
unsigned int thetaRes, int sharpEdge) { |
465 |
|
|
static const char me[]="limnPolyDataCylinder"; |
466 |
|
|
unsigned int vertNum, primNum, primIdx, indxNum, thetaIdx, vertIdx, blah; |
467 |
|
|
double theta, cth, sth, sq2; |
468 |
|
|
|
469 |
|
|
/* sanity bounds */ |
470 |
|
|
thetaRes = AIR_MAX(3, thetaRes); |
471 |
|
|
|
472 |
|
|
vertNum = sharpEdge ? 4*thetaRes : 2*thetaRes; |
473 |
|
|
primNum = 3; |
474 |
|
|
indxNum = 2*thetaRes + 2*(thetaRes+1); /* 2 fans + 1 strip */ |
475 |
|
|
if (limnPolyDataAlloc(pld, infoBitFlag, vertNum, indxNum, primNum)) { |
476 |
|
|
biffAddf(LIMN, "%s: couldn't allocate output", me); |
477 |
|
|
return 1; |
478 |
|
|
} |
479 |
|
|
|
480 |
|
|
vertIdx = 0; |
481 |
|
|
for (blah=0; blah < (sharpEdge ? 2u : 1u); blah++) { |
482 |
|
|
for (thetaIdx=0; thetaIdx<thetaRes; thetaIdx++) { |
483 |
|
|
theta = AIR_AFFINE(0, thetaIdx, thetaRes, 0, 2*AIR_PI); |
484 |
|
|
ELL_4V_SET_TT(pld->xyzw + 4*vertIdx, float, |
485 |
|
|
cos(theta), sin(theta), 1, 1); |
486 |
|
|
/* |
487 |
|
|
fprintf(stderr, "!%s: vert[%u] = %g %g %g\n", me, vertIdx, |
488 |
|
|
(pld->xyzw + 4*vertIdx)[0], |
489 |
|
|
(pld->xyzw + 4*vertIdx)[1], |
490 |
|
|
(pld->xyzw + 4*vertIdx)[2]); |
491 |
|
|
*/ |
492 |
|
|
++vertIdx; |
493 |
|
|
} |
494 |
|
|
} |
495 |
|
|
for (blah=0; blah < (sharpEdge ? 2u : 1u); blah++) { |
496 |
|
|
for (thetaIdx=0; thetaIdx<thetaRes; thetaIdx++) { |
497 |
|
|
theta = AIR_AFFINE(0, thetaIdx, thetaRes, 0, 2*AIR_PI); |
498 |
|
|
ELL_4V_SET_TT(pld->xyzw + 4*vertIdx, float, |
499 |
|
|
cos(theta), sin(theta), -1, 1); |
500 |
|
|
/* |
501 |
|
|
fprintf(stderr, "!%s: vert[%u] = %g %g %g\n", me, vertIdx, |
502 |
|
|
(pld->xyzw + 4*vertIdx)[0], |
503 |
|
|
(pld->xyzw + 4*vertIdx)[1], |
504 |
|
|
(pld->xyzw + 4*vertIdx)[2]); |
505 |
|
|
*/ |
506 |
|
|
++vertIdx; |
507 |
|
|
} |
508 |
|
|
} |
509 |
|
|
|
510 |
|
|
primIdx = 0; |
511 |
|
|
vertIdx = 0; |
512 |
|
|
/* fan on top */ |
513 |
|
|
/* fprintf(stderr, "!%s: fan on top:\n", me); */ |
514 |
|
|
for (thetaIdx=0; thetaIdx<thetaRes; thetaIdx++) { |
515 |
|
|
/* fprintf(stderr, "!%s: indx[%u] = %u\n", me, vertIdx, thetaIdx); */ |
516 |
|
|
pld->indx[vertIdx++] = thetaIdx; |
517 |
|
|
} |
518 |
|
|
pld->type[primIdx] = limnPrimitiveTriangleFan; |
519 |
|
|
pld->icnt[primIdx] = thetaRes; |
520 |
|
|
primIdx++; |
521 |
|
|
|
522 |
|
|
/* single strip around */ |
523 |
|
|
/* fprintf(stderr, "!%s: strip around:\n", me); */ |
524 |
|
|
for (thetaIdx=0; thetaIdx<thetaRes; thetaIdx++) { |
525 |
|
|
/* |
526 |
|
|
fprintf(stderr, "!%s: indx[%u] = %u\n", me, vertIdx, |
527 |
|
|
(sharpEdge ? 1 : 0)*thetaRes + thetaIdx); |
528 |
|
|
*/ |
529 |
|
|
pld->indx[vertIdx++] = (sharpEdge ? 1 : 0)*thetaRes + thetaIdx; |
530 |
|
|
/* |
531 |
|
|
fprintf(stderr, "!%s: indx[%u] = %u\n", me, vertIdx, |
532 |
|
|
(sharpEdge ? 2 : 1)*thetaRes + thetaIdx); |
533 |
|
|
*/ |
534 |
|
|
pld->indx[vertIdx++] = (sharpEdge ? 2 : 1)*thetaRes + thetaIdx; |
535 |
|
|
} |
536 |
|
|
/* |
537 |
|
|
fprintf(stderr, "!%s: indx[%u] = %u\n", me, vertIdx, |
538 |
|
|
(sharpEdge ? 1 : 0)*thetaRes); |
539 |
|
|
*/ |
540 |
|
|
pld->indx[vertIdx++] = (sharpEdge ? 1 : 0)*thetaRes; |
541 |
|
|
/* |
542 |
|
|
fprintf(stderr, "!%s: indx[%u] = %u\n", me, vertIdx, |
543 |
|
|
(sharpEdge ? 2 : 1)*thetaRes); |
544 |
|
|
*/ |
545 |
|
|
pld->indx[vertIdx++] = (sharpEdge ? 2 : 1)*thetaRes; |
546 |
|
|
pld->type[primIdx] = limnPrimitiveTriangleStrip; |
547 |
|
|
pld->icnt[primIdx] = 2*(thetaRes+1); |
548 |
|
|
primIdx++; |
549 |
|
|
|
550 |
|
|
/* fan on bottom */ |
551 |
|
|
/* fprintf(stderr, "!%s: fan on bottom:\n", me); */ |
552 |
|
|
for (thetaIdx=0; thetaIdx<thetaRes; thetaIdx++) { |
553 |
|
|
/* |
554 |
|
|
fprintf(stderr, "!%s: indx[%u] = %u\n", me, vertIdx, |
555 |
|
|
(sharpEdge ? 3 : 1)*thetaRes + thetaIdx); |
556 |
|
|
*/ |
557 |
|
|
pld->indx[vertIdx++] = (sharpEdge ? 3 : 1)*thetaRes + thetaIdx; |
558 |
|
|
} |
559 |
|
|
pld->type[primIdx] = limnPrimitiveTriangleFan; |
560 |
|
|
pld->icnt[primIdx] = thetaRes; |
561 |
|
|
primIdx++; |
562 |
|
|
|
563 |
|
|
if ((1 << limnPolyDataInfoNorm) & infoBitFlag) { |
564 |
|
|
sq2 = sqrt(2.0); |
565 |
|
|
if (sharpEdge) { |
566 |
|
|
for (thetaIdx=0; thetaIdx<thetaRes; thetaIdx++) { |
567 |
|
|
theta = AIR_AFFINE(0, thetaIdx, thetaRes, 0, 2*AIR_PI); |
568 |
|
|
cth = cos(theta); |
569 |
|
|
sth = sin(theta); |
570 |
|
|
ELL_3V_SET_TT(pld->norm + 3*(thetaIdx + 0*thetaRes), |
571 |
|
|
float, 0, 0, 1); |
572 |
|
|
ELL_3V_SET_TT(pld->norm + 3*(thetaIdx + 1*thetaRes), |
573 |
|
|
float, cth, sth, 0); |
574 |
|
|
ELL_3V_SET_TT(pld->norm + 3*(thetaIdx + 2*thetaRes), |
575 |
|
|
float, cth, sth, 0); |
576 |
|
|
ELL_3V_SET_TT(pld->norm + 3*(thetaIdx + 3*thetaRes), |
577 |
|
|
float, 0, 0, -1); |
578 |
|
|
} |
579 |
|
|
} else { |
580 |
|
|
for (thetaIdx=0; thetaIdx<thetaRes; thetaIdx++) { |
581 |
|
|
theta = AIR_AFFINE(0, thetaIdx, thetaRes, 0, 2*AIR_PI); |
582 |
|
|
cth = sq2*cos(theta); |
583 |
|
|
sth = sq2*sin(theta); |
584 |
|
|
ELL_3V_SET_TT(pld->norm + 3*(thetaIdx + 0*thetaRes), float, |
585 |
|
|
cth, sth, sq2); |
586 |
|
|
ELL_3V_SET_TT(pld->norm + 3*(thetaIdx + 1*thetaRes), float, |
587 |
|
|
cth, sth, -sq2); |
588 |
|
|
} |
589 |
|
|
} |
590 |
|
|
} |
591 |
|
|
|
592 |
|
|
if ((1 << limnPolyDataInfoTex2) & infoBitFlag) { |
593 |
|
|
if (sharpEdge) { |
594 |
|
|
for (thetaIdx=0; thetaIdx<thetaRes; thetaIdx++) { |
595 |
|
|
theta = AIR_AFFINE(0, thetaIdx, thetaRes, 0, 1); |
596 |
|
|
ELL_2V_SET_TT(pld->tex2 + 2*(thetaIdx + 0*thetaRes), float, theta, 0); |
597 |
|
|
ELL_2V_SET_TT(pld->tex2 + 2*(thetaIdx + 1*thetaRes), float, theta, 0); |
598 |
|
|
ELL_2V_SET_TT(pld->tex2 + 2*(thetaIdx + 2*thetaRes), float, theta, 1); |
599 |
|
|
ELL_2V_SET_TT(pld->tex2 + 2*(thetaIdx + 3*thetaRes), float, theta, 1); |
600 |
|
|
} |
601 |
|
|
} else { |
602 |
|
|
for (thetaIdx=0; thetaIdx<thetaRes; thetaIdx++) { |
603 |
|
|
theta = AIR_AFFINE(0, thetaIdx, thetaRes, 0, 1); |
604 |
|
|
ELL_2V_SET_TT(pld->tex2 + 2*(thetaIdx + 0*thetaRes), float, theta, 0); |
605 |
|
|
ELL_2V_SET_TT(pld->tex2 + 2*(thetaIdx + 1*thetaRes), float, theta, 1); |
606 |
|
|
} |
607 |
|
|
} |
608 |
|
|
} |
609 |
|
|
|
610 |
|
|
if ((1 << limnPolyDataInfoTang) & infoBitFlag) { |
611 |
|
|
float xx, yy, tang[3], tlen; |
612 |
|
|
if (sharpEdge) { |
613 |
|
|
for (thetaIdx=0; thetaIdx<thetaRes; thetaIdx++) { |
614 |
|
|
xx = (pld->xyzw + 4*(thetaIdx + 0*thetaRes))[0]; |
615 |
|
|
yy = (pld->xyzw + 4*(thetaIdx + 0*thetaRes))[1]; |
616 |
|
|
ELL_3V_SET(tang, -yy, xx, 0.0); |
617 |
|
|
ELL_3V_NORM_TT(tang, float, tang, tlen); |
618 |
|
|
ELL_3V_COPY(pld->tang + 3*(thetaIdx + 0*thetaRes), tang); |
619 |
|
|
ELL_3V_COPY(pld->tang + 3*(thetaIdx + 1*thetaRes), tang); |
620 |
|
|
ELL_3V_COPY(pld->tang + 3*(thetaIdx + 2*thetaRes), tang); |
621 |
|
|
ELL_3V_COPY(pld->tang + 3*(thetaIdx + 3*thetaRes), tang); |
622 |
|
|
} |
623 |
|
|
} else { |
624 |
|
|
for (thetaIdx=0; thetaIdx<thetaRes; thetaIdx++) { |
625 |
|
|
xx = (pld->xyzw + 4*(thetaIdx + 0*thetaRes))[0]; |
626 |
|
|
yy = (pld->xyzw + 4*(thetaIdx + 0*thetaRes))[1]; |
627 |
|
|
ELL_3V_SET(tang, -yy, xx, 0.0); |
628 |
|
|
ELL_3V_NORM_TT(tang, float, tang, tlen); |
629 |
|
|
ELL_3V_COPY(pld->tang + 3*(thetaIdx + 0*thetaRes), tang); |
630 |
|
|
ELL_3V_COPY(pld->tang + 3*(thetaIdx + 1*thetaRes), tang); |
631 |
|
|
} |
632 |
|
|
} |
633 |
|
|
} |
634 |
|
|
|
635 |
|
|
if ((1 << limnPolyDataInfoRGBA) & infoBitFlag) { |
636 |
|
|
for (vertIdx=0; vertIdx<pld->rgbaNum; vertIdx++) { |
637 |
|
|
ELL_4V_SET(pld->rgba + 4*vertIdx, 255, 255, 255, 255); |
638 |
|
|
} |
639 |
|
|
} |
640 |
|
|
|
641 |
|
|
return 0; |
642 |
|
|
} |
643 |
|
|
|
644 |
|
|
int |
645 |
|
|
limnPolyDataCone(limnPolyData *pld, |
646 |
|
|
unsigned int infoBitFlag, |
647 |
|
|
unsigned int thetaRes, int sharpEdge) { |
648 |
|
|
static const char me[]="limnPolyDataCone"; |
649 |
|
|
unsigned int vertNum, primNum, primIdx, indxNum, thetaIdx, vertIdx, blah; |
650 |
|
|
double theta, cth, sth; |
651 |
|
|
|
652 |
|
|
/* sanity bounds */ |
653 |
|
|
thetaRes = AIR_MAX(3, thetaRes); |
654 |
|
|
|
655 |
|
|
vertNum = sharpEdge ? 3*thetaRes : 1 + thetaRes; |
656 |
|
|
primNum = 2; |
657 |
|
|
indxNum = thetaRes + 2*(thetaRes+1); /* 1 fans + 1 strip */ |
658 |
|
|
if (limnPolyDataAlloc(pld, infoBitFlag, vertNum, indxNum, primNum)) { |
659 |
|
|
biffAddf(LIMN, "%s: couldn't allocate output", me); |
660 |
|
|
return 1; |
661 |
|
|
} |
662 |
|
|
|
663 |
|
|
/* top point(s) */ |
664 |
|
|
vertIdx = 0; |
665 |
|
|
if (sharpEdge) { |
666 |
|
|
for (thetaIdx=0; thetaIdx<thetaRes; thetaIdx++) { |
667 |
|
|
ELL_4V_SET_TT(pld->xyzw + 4*vertIdx, float, |
668 |
|
|
0, 0, 1, 1); |
669 |
|
|
++vertIdx; |
670 |
|
|
} |
671 |
|
|
} else { |
672 |
|
|
ELL_4V_SET_TT(pld->xyzw + 4*vertIdx, float, |
673 |
|
|
0, 0, 1, 1); |
674 |
|
|
++vertIdx; |
675 |
|
|
} |
676 |
|
|
/* bottom edge */ |
677 |
|
|
for (blah=0; blah < (sharpEdge ? 2u : 1u); blah++) { |
678 |
|
|
for (thetaIdx=0; thetaIdx<thetaRes; thetaIdx++) { |
679 |
|
|
theta = AIR_AFFINE(0, thetaIdx, thetaRes, 0, 2*AIR_PI); |
680 |
|
|
ELL_4V_SET_TT(pld->xyzw + 4*vertIdx, float, |
681 |
|
|
cos(theta), sin(theta), -1, 1); |
682 |
|
|
++vertIdx; |
683 |
|
|
} |
684 |
|
|
} |
685 |
|
|
|
686 |
|
|
primIdx = 0; |
687 |
|
|
vertIdx = 0; |
688 |
|
|
/* single strip around */ |
689 |
|
|
for (thetaIdx=0; thetaIdx<thetaRes; thetaIdx++) { |
690 |
|
|
pld->indx[vertIdx++] = sharpEdge ? thetaIdx : 0; |
691 |
|
|
pld->indx[vertIdx++] = (sharpEdge ? thetaRes : 1) + thetaIdx; |
692 |
|
|
} |
693 |
|
|
pld->indx[vertIdx++] = 0; |
694 |
|
|
pld->indx[vertIdx++] = sharpEdge ? thetaRes : 1; |
695 |
|
|
pld->type[primIdx] = limnPrimitiveTriangleStrip; |
696 |
|
|
pld->icnt[primIdx] = 2*(thetaRes+1); |
697 |
|
|
primIdx++; |
698 |
|
|
|
699 |
|
|
/* fan on bottom */ |
700 |
|
|
for (thetaIdx=0; thetaIdx<thetaRes; thetaIdx++) { |
701 |
|
|
pld->indx[vertIdx++] = (sharpEdge ? 2*thetaRes : 1) + thetaIdx; |
702 |
|
|
} |
703 |
|
|
pld->type[primIdx] = limnPrimitiveTriangleFan; |
704 |
|
|
pld->icnt[primIdx] = thetaRes; |
705 |
|
|
primIdx++; |
706 |
|
|
|
707 |
|
|
if ((1 << limnPolyDataInfoNorm) & infoBitFlag) { |
708 |
|
|
double isq3; |
709 |
|
|
isq3 = 1/sqrt(3.0); |
710 |
|
|
if (sharpEdge) { |
711 |
|
|
for (thetaIdx=0; thetaIdx<thetaRes; thetaIdx++) { |
712 |
|
|
theta = AIR_AFFINE(0, thetaIdx, thetaRes, 0, 2*AIR_PI); |
713 |
|
|
cth = cos(theta); |
714 |
|
|
sth = sin(theta); |
715 |
|
|
ELL_3V_SET_TT(pld->norm + 3*(thetaIdx + 0*thetaRes), |
716 |
|
|
float, cth*isq3, sth*isq3, isq3); |
717 |
|
|
ELL_3V_SET_TT(pld->norm + 3*(thetaIdx + 1*thetaRes), |
718 |
|
|
float, cth*isq3, sth*isq3, isq3); |
719 |
|
|
ELL_3V_SET_TT(pld->norm + 3*(thetaIdx + 2*thetaRes), |
720 |
|
|
float, 0, 0, -1); |
721 |
|
|
} |
722 |
|
|
} else { |
723 |
|
|
ELL_3V_SET_TT(pld->norm + 3*(0), float, |
724 |
|
|
0, 0, 1); |
725 |
|
|
for (thetaIdx=0; thetaIdx<thetaRes; thetaIdx++) { |
726 |
|
|
theta = AIR_AFFINE(0, thetaIdx, thetaRes, 0, 2*AIR_PI); |
727 |
|
|
cth = cos(theta); |
728 |
|
|
sth = sin(theta); |
729 |
|
|
ELL_3V_SET_TT(pld->norm + 3*(thetaIdx + 1), |
730 |
|
|
float, cth*isq3, sth*isq3, -isq3); /* close enough */ |
731 |
|
|
} |
732 |
|
|
} |
733 |
|
|
} |
734 |
|
|
|
735 |
|
|
if ((1 << limnPolyDataInfoRGBA) & infoBitFlag) { |
736 |
|
|
for (vertIdx=0; vertIdx<pld->rgbaNum; vertIdx++) { |
737 |
|
|
ELL_4V_SET(pld->rgba + 4*vertIdx, 255, 255, 255, 255); |
738 |
|
|
} |
739 |
|
|
} |
740 |
|
|
|
741 |
|
|
return 0; |
742 |
|
|
} |
743 |
|
|
|
744 |
|
|
/* |
745 |
|
|
******** limnPolyDataSuperquadric |
746 |
|
|
** |
747 |
|
|
** makes a superquadric parameterized around the Z axis |
748 |
|
|
*/ |
749 |
|
|
int |
750 |
|
|
limnPolyDataSuperquadric(limnPolyData *pld, |
751 |
|
|
unsigned int infoBitFlag, |
752 |
|
|
float alpha, float beta, |
753 |
|
|
unsigned int thetaRes, unsigned int phiRes) { |
754 |
|
|
static const char me[]="limnPolyDataSuperquadric"; |
755 |
|
|
unsigned int vertIdx, vertNum, fanNum, stripNum, primNum, indxNum, |
756 |
|
|
thetaIdx, phiIdx, primIdx; |
757 |
|
|
double theta, phi; |
758 |
|
|
|
759 |
|
|
/* sanity bounds */ |
760 |
|
|
thetaRes = AIR_MAX(3u, thetaRes); |
761 |
|
|
phiRes = AIR_MAX(2u, phiRes); |
762 |
|
|
alpha = AIR_MAX(0.00001f, alpha); |
763 |
|
|
beta = AIR_MAX(0.00001f, beta); |
764 |
|
|
|
765 |
|
|
vertNum = 2 + thetaRes*(phiRes-1); |
766 |
|
|
fanNum = 2; |
767 |
|
|
stripNum = phiRes-2; |
768 |
|
|
primNum = fanNum + stripNum; |
769 |
|
|
indxNum = (thetaRes+2)*fanNum + 2*(thetaRes+1)*stripNum; |
770 |
|
|
if (limnPolyDataAlloc(pld, infoBitFlag, vertNum, indxNum, primNum)) { |
771 |
|
|
biffAddf(LIMN, "%s: couldn't allocate output", me); |
772 |
|
|
return 1; |
773 |
|
|
} |
774 |
|
|
|
775 |
|
|
vertIdx = 0; |
776 |
|
|
ELL_4V_SET(pld->xyzw + 4*vertIdx, 0, 0, 1, 1); |
777 |
|
|
if ((1 << limnPolyDataInfoNorm) & infoBitFlag) { |
778 |
|
|
ELL_3V_SET(pld->norm + 3*vertIdx, 0, 0, 1); |
779 |
|
|
} |
780 |
|
|
++vertIdx; |
781 |
|
|
for (phiIdx=1; phiIdx<phiRes; phiIdx++) { |
782 |
|
|
double cost, sint, cosp, sinp; |
783 |
|
|
phi = AIR_AFFINE(0, phiIdx, phiRes, 0, AIR_PI); |
784 |
|
|
cosp = cos(phi); |
785 |
|
|
sinp = sin(phi); |
786 |
|
|
for (thetaIdx=0; thetaIdx<thetaRes; thetaIdx++) { |
787 |
|
|
theta = AIR_AFFINE(0, thetaIdx, thetaRes, 0, 2*AIR_PI); |
788 |
|
|
cost = cos(theta); |
789 |
|
|
sint = sin(theta); |
790 |
|
|
ELL_4V_SET_TT(pld->xyzw + 4*vertIdx, float, |
791 |
|
|
airSgnPow(cost,alpha) * airSgnPow(sinp,beta), |
792 |
|
|
airSgnPow(sint,alpha) * airSgnPow(sinp,beta), |
793 |
|
|
airSgnPow(cosp,beta), |
794 |
|
|
1.0); |
795 |
|
|
if ((1 << limnPolyDataInfoNorm) & infoBitFlag) { |
796 |
|
|
if (1 == alpha && 1 == beta) { |
797 |
|
|
ELL_3V_COPY(pld->norm + 3*vertIdx, pld->xyzw + 4*vertIdx); |
798 |
|
|
} else { |
799 |
|
|
ELL_3V_SET_TT(pld->norm + 3*vertIdx, float, |
800 |
|
|
2*airSgnPow(cost,2-alpha)*airSgnPow(sinp,2-beta)/beta, |
801 |
|
|
2*airSgnPow(sint,2-alpha)*airSgnPow(sinp,2-beta)/beta, |
802 |
|
|
2*airSgnPow(cosp,2-beta)/beta); |
803 |
|
|
} |
804 |
|
|
} |
805 |
|
|
++vertIdx; |
806 |
|
|
} |
807 |
|
|
} |
808 |
|
|
ELL_4V_SET(pld->xyzw + 4*vertIdx, 0, 0, -1, 1); |
809 |
|
|
if ((1 << limnPolyDataInfoNorm) & infoBitFlag) { |
810 |
|
|
ELL_3V_SET(pld->norm + 3*vertIdx, 0, 0, -1); |
811 |
|
|
} |
812 |
|
|
++vertIdx; |
813 |
|
|
|
814 |
|
|
/* triangle fan at top */ |
815 |
|
|
vertIdx = 0; |
816 |
|
|
primIdx = 0; |
817 |
|
|
pld->indx[vertIdx++] = 0; |
818 |
|
|
for (thetaIdx=0; thetaIdx<thetaRes; thetaIdx++) { |
819 |
|
|
pld->indx[vertIdx++] = thetaIdx + 1; |
820 |
|
|
} |
821 |
|
|
pld->indx[vertIdx++] = 1; |
822 |
|
|
pld->type[primIdx] = limnPrimitiveTriangleFan; |
823 |
|
|
pld->icnt[primIdx++] = thetaRes + 2; |
824 |
|
|
|
825 |
|
|
/* tristrips around */ |
826 |
|
|
for (phiIdx=1; phiIdx<phiRes-1; phiIdx++) { |
827 |
|
|
/* |
828 |
|
|
fprintf(stderr, "!%s: prim[%u] = vert[%u] =", me, primIdx, vertIdx); |
829 |
|
|
*/ |
830 |
|
|
for (thetaIdx=0; thetaIdx<thetaRes; thetaIdx++) { |
831 |
|
|
/* |
832 |
|
|
fprintf(stderr, " [%u %u] %u %u", |
833 |
|
|
vertIdx, vertIdx + 1, |
834 |
|
|
(phiIdx-1)*thetaRes + thetaIdx + 1, |
835 |
|
|
phiIdx*thetaRes + thetaIdx + 1); |
836 |
|
|
*/ |
837 |
|
|
pld->indx[vertIdx++] = (phiIdx-1)*thetaRes + thetaIdx + 1; |
838 |
|
|
pld->indx[vertIdx++] = phiIdx*thetaRes + thetaIdx + 1; |
839 |
|
|
} |
840 |
|
|
/* |
841 |
|
|
fprintf(stderr, " [%u %u] %u %u (%u verts)\n", |
842 |
|
|
vertIdx, vertIdx + 1, |
843 |
|
|
(phiIdx-1)*thetaRes + 1, |
844 |
|
|
phiIdx*thetaRes + 1, 2*(thetaRes+1)); |
845 |
|
|
*/ |
846 |
|
|
pld->indx[vertIdx++] = (phiIdx-1)*thetaRes + 1; |
847 |
|
|
pld->indx[vertIdx++] = phiIdx*thetaRes + 1; |
848 |
|
|
pld->type[primIdx] = limnPrimitiveTriangleStrip; |
849 |
|
|
pld->icnt[primIdx++] = 2*(thetaRes+1); |
850 |
|
|
} |
851 |
|
|
|
852 |
|
|
/* triangle fan at bottom */ |
853 |
|
|
pld->indx[vertIdx++] = vertNum-1; |
854 |
|
|
for (thetaIdx=0; thetaIdx<thetaRes; thetaIdx++) { |
855 |
|
|
pld->indx[vertIdx++] = thetaRes*(phiRes-2) + thetaRes - thetaIdx; |
856 |
|
|
} |
857 |
|
|
pld->indx[vertIdx++] = thetaRes*(phiRes-2) + thetaRes; |
858 |
|
|
pld->type[primIdx] = limnPrimitiveTriangleFan; |
859 |
|
|
pld->icnt[primIdx++] = thetaRes + 2; |
860 |
|
|
|
861 |
|
|
if ((1 << limnPolyDataInfoRGBA) & infoBitFlag) { |
862 |
|
|
for (vertIdx=0; vertIdx<pld->rgbaNum; vertIdx++) { |
863 |
|
|
ELL_4V_SET(pld->rgba + 4*vertIdx, 255, 255, 255, 255); |
864 |
|
|
} |
865 |
|
|
} |
866 |
|
|
|
867 |
|
|
return 0; |
868 |
|
|
} |
869 |
|
|
|
870 |
|
|
/* |
871 |
|
|
******** limnPolyDataSpiralBetterquadric |
872 |
|
|
** |
873 |
|
|
** puts a "betterquadric" into a single spiral triangle strip |
874 |
|
|
*/ |
875 |
|
|
int |
876 |
|
|
limnPolyDataSpiralBetterquadric(limnPolyData *pld, |
877 |
|
|
unsigned int infoBitFlag, |
878 |
|
|
float alpha, float beta, float cee, |
879 |
|
|
float minRad, |
880 |
|
|
unsigned int thetaRes, unsigned int phiRes) { |
881 |
|
|
static const char me[]="limnPolyDataSpiralBetterquadric"; |
882 |
|
|
unsigned int vertIdx, vertNum, indxNum, thetaIdx, phiIdx; |
883 |
|
|
|
884 |
|
|
/* sanity bounds */ |
885 |
|
|
thetaRes = AIR_MAX(3u, thetaRes); |
886 |
|
|
phiRes = AIR_MAX(2u, phiRes); |
887 |
|
|
alpha = AIR_MAX(0.00001f, alpha); |
888 |
|
|
beta = AIR_MAX(0.00001f, beta); |
889 |
|
|
|
890 |
|
|
vertNum = thetaRes*phiRes + 1; |
891 |
|
|
indxNum = 2*thetaRes*(phiRes+1) - 2; |
892 |
|
|
if (limnPolyDataAlloc(pld, infoBitFlag, vertNum, indxNum, 1)) { |
893 |
|
|
biffAddf(LIMN, "%s: couldn't allocate output", me); |
894 |
|
|
return 1; |
895 |
|
|
} |
896 |
|
|
|
897 |
|
|
vertIdx = 0; |
898 |
|
|
for (phiIdx=0; phiIdx<phiRes; phiIdx++) { |
899 |
|
|
for (thetaIdx=0; thetaIdx<thetaRes; thetaIdx++) { |
900 |
|
|
double cost, sint, cosp, sinp, xx, yy, zz; |
901 |
|
|
double phi = (AIR_AFFINE(0, phiIdx, phiRes, 0, AIR_PI) |
902 |
|
|
+ AIR_AFFINE(0, thetaIdx, thetaRes, 0, AIR_PI)/phiRes); |
903 |
|
|
double theta = AIR_AFFINE(0, thetaIdx, thetaRes, 0.0, 2*AIR_PI); |
904 |
|
|
cosp = cos(phi); |
905 |
|
|
sinp = sin(phi); |
906 |
|
|
cost = cos(theta); |
907 |
|
|
sint = sin(theta); |
908 |
|
|
xx = airSgnPow(cost,alpha) * airSgnPow(sinp,beta); |
909 |
|
|
yy = airSgnPow(sint,alpha) * airSgnPow(sinp,beta); |
910 |
|
|
zz = airSgnPow(cosp,beta); |
911 |
|
|
if (cee != beta) { |
912 |
|
|
/* expand profile along y axis to match having beta=cee */ |
913 |
|
|
double yp, ymax; |
914 |
|
|
yp = airSgnPow(sin(acos(airSgnPow(zz, 1/cee))), cee); |
915 |
|
|
ymax = airSgnPow(sinp, beta); |
916 |
|
|
if (ymax) { |
917 |
|
|
yy *= yp/ymax; |
918 |
|
|
} |
919 |
|
|
} |
920 |
|
|
ELL_4V_SET_TT(pld->xyzw + 4*vertIdx, float, xx, yy, zz, 1.0); |
921 |
|
|
if (minRad > 0.0) { |
922 |
|
|
/* add thickness to small radius */ |
923 |
|
|
double rr; |
924 |
|
|
xx = (pld->xyzw + 4*vertIdx)[0]; |
925 |
|
|
yy = (pld->xyzw + 4*vertIdx)[1]; |
926 |
|
|
rr = sqrt(xx*xx + yy*yy); |
927 |
|
|
if (rr) { |
928 |
|
|
(pld->xyzw + 4*vertIdx)[0] *= AIR_CAST(float, AIR_AFFINE(0, rr, 1, minRad/rr, 1/rr)); |
929 |
|
|
(pld->xyzw + 4*vertIdx)[1] *= AIR_CAST(float, AIR_AFFINE(0, rr, 1, minRad/rr, 1/rr)); |
930 |
|
|
} |
931 |
|
|
} |
932 |
|
|
if (((1 << limnPolyDataInfoNorm) & infoBitFlag) |
933 |
|
|
|| ((1 << limnPolyDataInfoTang) & infoBitFlag)) { |
934 |
|
|
double norm[3], nlen; |
935 |
|
|
if (1 == alpha && 1 == beta) { |
936 |
|
|
ELL_3V_COPY(norm, pld->xyzw + 4*vertIdx); |
937 |
|
|
} else { |
938 |
|
|
if (!vertIdx) { |
939 |
|
|
ELL_3V_SET(norm, 0.0, 0.0, 1.0); |
940 |
|
|
} else { |
941 |
|
|
ELL_3V_SET(norm, |
942 |
|
|
(2*airSgnPow(cost,2-alpha)*airSgnPow(sinp,2-beta)/beta), |
943 |
|
|
(2*airSgnPow(sint,2-alpha)*airSgnPow(sinp,2-beta)/beta), |
944 |
|
|
2*airSgnPow(cosp,2-beta)/beta); |
945 |
|
|
} |
946 |
|
|
} |
947 |
|
|
if ((nlen = ELL_3V_LEN(norm))) { |
948 |
|
|
ELL_3V_SCALE(norm, 1.0/nlen, norm); |
949 |
|
|
} else { |
950 |
|
|
ELL_3V_SET(norm, 0.0, 0.0, 1.0); |
951 |
|
|
} |
952 |
|
|
if ((1 << limnPolyDataInfoNorm) & infoBitFlag) { |
953 |
|
|
ELL_3V_COPY_TT(pld->norm + 3*vertIdx, float, norm); |
954 |
|
|
} |
955 |
|
|
if ((1 << limnPolyDataInfoTang) & infoBitFlag) { |
956 |
|
|
double tang[3], tlen; |
957 |
|
|
ELL_3V_SET(tang, -norm[1], norm[0], 0.0); |
958 |
|
|
if ((tlen = ELL_3V_LEN(tang))) { |
959 |
|
|
ELL_3V_SCALE(tang, 1.0/tlen, tang); |
960 |
|
|
} else { |
961 |
|
|
ELL_3V_SET(tang, 1.0, 0.0, 0.0); |
962 |
|
|
} |
963 |
|
|
ELL_3V_COPY_TT(pld->tang + 3*vertIdx, float, tang); |
964 |
|
|
} |
965 |
|
|
} |
966 |
|
|
if ((1 << limnPolyDataInfoTex2) & infoBitFlag) { |
967 |
|
|
ELL_2V_SET_TT(pld->tex2 + 2*vertIdx, float, |
968 |
|
|
AIR_AFFINE(0.0, theta, 2*AIR_PI, 0.0, 1.0), |
969 |
|
|
AIR_AFFINE(0.0, phi, AIR_PI, 0.0, 1.0)); |
970 |
|
|
} |
971 |
|
|
++vertIdx; |
972 |
|
|
} |
973 |
|
|
} |
974 |
|
|
ELL_4V_SET(pld->xyzw + 4*vertIdx, 0, 0, -1, 1); |
975 |
|
|
if ((1 << limnPolyDataInfoNorm) & infoBitFlag) { |
976 |
|
|
ELL_3V_SET(pld->norm + 3*vertIdx, 0.0, 0.0, -1.0); |
977 |
|
|
} |
978 |
|
|
if ((1 << limnPolyDataInfoTex2) & infoBitFlag) { |
979 |
|
|
ELL_2V_SET(pld->tex2 + 2*vertIdx, 0.5, 1.0); |
980 |
|
|
} |
981 |
|
|
if ((1 << limnPolyDataInfoTang) & infoBitFlag) { |
982 |
|
|
ELL_3V_SET(pld->tang + 3*vertIdx, 1.0, 0.0, 0.0); |
983 |
|
|
} |
984 |
|
|
++vertIdx; |
985 |
|
|
|
986 |
|
|
/* single triangle strip */ |
987 |
|
|
pld->type[0] = limnPrimitiveTriangleStrip; |
988 |
|
|
pld->icnt[0] = indxNum; |
989 |
|
|
vertIdx = 0; |
990 |
|
|
for (thetaIdx=1; thetaIdx<thetaRes; thetaIdx++) { |
991 |
|
|
pld->indx[vertIdx++] = 0; |
992 |
|
|
pld->indx[vertIdx++] = thetaIdx; |
993 |
|
|
} |
994 |
|
|
for (phiIdx=0; phiIdx<phiRes-1; phiIdx++) { |
995 |
|
|
for (thetaIdx=0; thetaIdx<thetaRes; thetaIdx++) { |
996 |
|
|
pld->indx[vertIdx++] = ((phiIdx + 0) * thetaRes) + thetaIdx; |
997 |
|
|
pld->indx[vertIdx++] = ((phiIdx + 1) * thetaRes) + thetaIdx; |
998 |
|
|
} |
999 |
|
|
} |
1000 |
|
|
for (thetaIdx=0; thetaIdx<thetaRes; thetaIdx++) { |
1001 |
|
|
pld->indx[vertIdx++] = (phiRes - 1)*thetaRes + thetaIdx; |
1002 |
|
|
pld->indx[vertIdx++] = (phiRes - 0)*thetaRes; |
1003 |
|
|
} |
1004 |
|
|
#if 0 |
1005 |
|
|
if ( (cee != beta || minRad > 0.0) |
1006 |
|
|
&& ((1 << limnPolyDataInfoNorm) & infoBitFlag) ) { |
1007 |
|
|
/* have deformed object in some way that confounds analytic normals */ |
1008 |
|
|
if (limnPolyDataVertexNormals(pld)) { |
1009 |
|
|
biffAddf(LIMN, "%s: trouble getting normals", me); return 1; |
1010 |
|
|
} |
1011 |
|
|
} |
1012 |
|
|
#endif |
1013 |
|
|
if ((1 << limnPolyDataInfoRGBA) & infoBitFlag) { |
1014 |
|
|
for (vertIdx=0; vertIdx<pld->rgbaNum; vertIdx++) { |
1015 |
|
|
ELL_4V_SET(pld->rgba + 4*vertIdx, 255, 255, 255, 255); |
1016 |
|
|
} |
1017 |
|
|
} |
1018 |
|
|
|
1019 |
|
|
return 0; |
1020 |
|
|
} |
1021 |
|
|
|
1022 |
|
|
/* |
1023 |
|
|
******** limnPolyDataSpiralSuperquadric |
1024 |
|
|
** |
1025 |
|
|
** puts a superquadric into a single spiral triangle strip |
1026 |
|
|
*/ |
1027 |
|
|
int |
1028 |
|
|
limnPolyDataSpiralSuperquadric(limnPolyData *pld, |
1029 |
|
|
unsigned int infoBitFlag, |
1030 |
|
|
float alpha, float beta, |
1031 |
|
|
unsigned int thetaRes, unsigned int phiRes) { |
1032 |
|
|
static const char me[]="limnPolyDataSpiralSuperquadric"; |
1033 |
|
|
|
1034 |
|
|
if (limnPolyDataSpiralBetterquadric(pld, infoBitFlag, |
1035 |
|
|
alpha, beta, beta, 0.0, |
1036 |
|
|
thetaRes, phiRes)) { |
1037 |
|
|
biffAddf(LIMN, "%s: trouble", me); return 1; |
1038 |
|
|
} |
1039 |
|
|
return 0; |
1040 |
|
|
} |
1041 |
|
|
|
1042 |
|
|
/* |
1043 |
|
|
******** limnPolyDataPolarSphere |
1044 |
|
|
** |
1045 |
|
|
** makes a unit sphere, centered at the origin, parameterized around Z axis |
1046 |
|
|
*/ |
1047 |
|
|
int |
1048 |
|
|
limnPolyDataPolarSphere(limnPolyData *pld, |
1049 |
|
|
unsigned int infoBitFlag, |
1050 |
|
|
unsigned int thetaRes, unsigned int phiRes) { |
1051 |
|
|
static const char me[]="limnPolyDataPolarSphere"; |
1052 |
|
|
|
1053 |
|
|
if (limnPolyDataSuperquadric(pld, infoBitFlag, |
1054 |
|
|
1.0, 1.0, thetaRes, phiRes)) { |
1055 |
|
|
biffAddf(LIMN, "%s: trouble", me); |
1056 |
|
|
return 1; |
1057 |
|
|
} |
1058 |
|
|
return 0; |
1059 |
|
|
} |
1060 |
|
|
|
1061 |
|
|
int |
1062 |
|
|
limnPolyDataSpiralSphere(limnPolyData *pld, |
1063 |
|
|
unsigned int infoBitFlag, |
1064 |
|
|
unsigned int thetaRes, |
1065 |
|
|
unsigned int phiRes) { |
1066 |
|
|
static const char me[]="limnPolyDataSpiralSphere"; |
1067 |
|
|
|
1068 |
|
|
if (limnPolyDataSpiralSuperquadric(pld, infoBitFlag, |
1069 |
|
|
1.0, 1.0, thetaRes, phiRes)) { |
1070 |
|
|
biffAddf(LIMN, "%s: trouble", me); |
1071 |
|
|
return 1; |
1072 |
|
|
} |
1073 |
|
|
return 0; |
1074 |
|
|
} |
1075 |
|
|
|
1076 |
|
|
/* Geometry for an icosahedron */ |
1077 |
|
|
#define ICO_ONE 0.5257311121f |
1078 |
|
|
#define ICO_TAU 0.8506508084f |
1079 |
|
|
static float icovertices[36] = { |
1080 |
|
|
0.0f, ICO_ONE, ICO_TAU, 0.0f, -ICO_ONE, -ICO_TAU, |
1081 |
|
|
0.0f, -ICO_ONE, ICO_TAU, 0.0f, ICO_ONE, -ICO_TAU, |
1082 |
|
|
ICO_ONE, ICO_TAU, 0.0f, -ICO_ONE, -ICO_TAU, 0.0f, |
1083 |
|
|
ICO_ONE, -ICO_TAU, 0.0f, -ICO_ONE, ICO_TAU, 0.0f, |
1084 |
|
|
ICO_TAU, 0.0f, ICO_ONE, -ICO_TAU, 0.0f, -ICO_ONE, |
1085 |
|
|
-ICO_TAU, 0.0f, ICO_ONE, ICO_TAU, 0.0f, -ICO_ONE |
1086 |
|
|
}; |
1087 |
|
|
#undef ICO_ONE |
1088 |
|
|
#undef ICO_TAU |
1089 |
|
|
|
1090 |
|
|
static unsigned int icoedges[60] = { |
1091 |
|
|
0, 2, 1, 3, 0, 4, 1, 5, 0, 8, 1, 9, 0, 10, 1, 11, /* 0-7 */ |
1092 |
|
|
0, 7, 1, 6, 2, 6, 3, 7, 2, 8, 3, 9, 2, 10, 3, 11, /* 8-15 */ |
1093 |
|
|
2, 5, 3, 4, 4, 8, 5, 9, 4, 7, 5, 6, 4, 11, 5, 10, /* 16-23*/ |
1094 |
|
|
6, 8, 7, 9, 6, 11, 7, 10, 8, 11, 9, 10 /* 24-29 */ |
1095 |
|
|
}; |
1096 |
|
|
|
1097 |
|
|
static unsigned int icofaces[60] = { |
1098 |
|
|
0, 4, 12, 1, 5, 13, 0, 6, 14, 1, 7, 15, |
1099 |
|
|
6, 8, 27, 7, 9, 26, 2, 4, 18, 3, 5, 19, |
1100 |
|
|
10, 12, 24, 11, 13, 25, 14, 16, 23, 15, 17, 22, |
1101 |
|
|
2, 8, 20, 3, 9, 21, 10, 16, 21, 11, 17, 20, |
1102 |
|
|
24, 26, 28, 25, 27, 29, 18, 22, 28, 19, 23, 29 |
1103 |
|
|
}; |
1104 |
|
|
|
1105 |
|
|
/* |
1106 |
|
|
******** limnPolyDataIcoSphere |
1107 |
|
|
** |
1108 |
|
|
** Makes a unit sphere, centered at the origin, by refining an icosahedron |
1109 |
|
|
** level times. Each refinement step subdivides each edge at its center, |
1110 |
|
|
** turning each triangle into four smaller ones. |
1111 |
|
|
** |
1112 |
|
|
** In the output, vertex 2*i and 2*i+1 are antipodal points, which allows for |
1113 |
|
|
** a more efficient implementation of operations that produce the same or |
1114 |
|
|
** a mirrored result for antipodal points (e.g., tensor glyphs). |
1115 |
|
|
*/ |
1116 |
|
|
|
1117 |
|
|
int |
1118 |
|
|
limnPolyDataIcoSphere(limnPolyData *pld, |
1119 |
|
|
unsigned int infoBitFlag, |
1120 |
|
|
unsigned int level) { |
1121 |
|
|
static const char me[]="limnPolyDataIcoSphere"; |
1122 |
|
|
unsigned int vertNum=12, edgeNum=30, faceNum=20, center; |
1123 |
|
|
float *verts, *xyzwp, *vertp; |
1124 |
|
|
unsigned char *rgbap; |
1125 |
|
|
unsigned int *edges, *faces; |
1126 |
|
|
unsigned int i,e,f; /* loop counters */ |
1127 |
|
|
airArray *mop; /* free memory in case of allocation error */ |
1128 |
|
|
|
1129 |
|
|
/* sanity checks */ |
1130 |
|
|
if (!pld) { |
1131 |
|
|
biffAddf(LIMN, "%s: got NULL pointer", me); |
1132 |
|
|
return 1; |
1133 |
|
|
} |
1134 |
|
|
mop = airMopNew(); |
1135 |
|
|
|
1136 |
|
|
/* x/y/z positions */ |
1137 |
|
|
verts = (float *) malloc (sizeof(float)*12*3); |
1138 |
|
|
if (verts==NULL) goto error_and_exit; |
1139 |
|
|
airMopAdd(mop, verts, airFree, airMopAlways); |
1140 |
|
|
memcpy(verts,icovertices,sizeof(float)*12*3); |
1141 |
|
|
/* endpoints for each edge */ |
1142 |
|
|
edges = (unsigned int *) malloc (sizeof(unsigned int)*30*2); |
1143 |
|
|
if (edges==NULL) goto error_and_exit; |
1144 |
|
|
airMopAdd(mop, edges, airFree, airMopAlways); |
1145 |
|
|
memcpy(edges,icoedges,sizeof(unsigned int)*60); |
1146 |
|
|
/* vertices of each face */ |
1147 |
|
|
faces = (unsigned int *) malloc (sizeof(unsigned int)*20*3); |
1148 |
|
|
if (faces==NULL) goto error_and_exit; |
1149 |
|
|
airMopAdd(mop, faces, airFree, airMopAlways); |
1150 |
|
|
memcpy(faces,icofaces,sizeof(unsigned int)*60); |
1151 |
|
|
|
1152 |
|
|
for (i=0; i<level; ++i) { |
1153 |
|
|
/* subdivision step */ |
1154 |
|
|
unsigned int nvertNum=vertNum+edgeNum; |
1155 |
|
|
unsigned int nedgeNum=2*edgeNum+3*faceNum; |
1156 |
|
|
unsigned int nfaceNum=4*faceNum; |
1157 |
|
|
float *newverts; |
1158 |
|
|
unsigned int *newedges, *newfaces; |
1159 |
|
|
newverts = (float *) malloc(sizeof(float)*3*nvertNum); |
1160 |
|
|
if (newverts==NULL) goto error_and_exit; |
1161 |
|
|
airMopAdd(mop, newverts, airFree, airMopAlways); |
1162 |
|
|
newedges = (unsigned int *) malloc(sizeof(unsigned int)*2*nedgeNum); |
1163 |
|
|
if (newedges==NULL) goto error_and_exit; |
1164 |
|
|
airMopAdd(mop, newedges, airFree, airMopAlways); |
1165 |
|
|
newfaces = (unsigned int *) malloc(sizeof(unsigned int)*3*nfaceNum); |
1166 |
|
|
if (newfaces==NULL) goto error_and_exit; |
1167 |
|
|
airMopAdd(mop, newfaces, airFree, airMopAlways); |
1168 |
|
|
memcpy(newverts, verts, sizeof(float)*3*vertNum); |
1169 |
|
|
for (e=0; e<edgeNum; e+=2) { /* split both edge and anti-edge */ |
1170 |
|
|
float norm; |
1171 |
|
|
ELL_3V_ADD2(newverts+3*(vertNum+e), verts+3*(edges[2*e]), |
1172 |
|
|
verts+3*(edges[2*e+1])); |
1173 |
|
|
/* project new vertex to unit sphere */ |
1174 |
|
|
ELL_3V_NORM_TT(newverts+3*(vertNum+e),float,newverts+3*(vertNum+e),norm); |
1175 |
|
|
ELL_3V_SCALE_TT(newverts+3*(vertNum+e+1),float,-1.0,newverts+3*(vertNum+e)); |
1176 |
|
|
/* split the edges such that anti-edge follows edge */ |
1177 |
|
|
newedges[4*e]=edges[2*e]; |
1178 |
|
|
newedges[4*e+1]=vertNum+e; |
1179 |
|
|
newedges[4*e+2]=edges[2*e+2]; |
1180 |
|
|
newedges[4*e+3]=vertNum+e+1; |
1181 |
|
|
|
1182 |
|
|
newedges[4*e+4]=vertNum+e; |
1183 |
|
|
newedges[4*e+5]=edges[2*e+1]; |
1184 |
|
|
newedges[4*e+6]=vertNum+e+1; |
1185 |
|
|
newedges[4*e+7]=edges[2*e+3]; |
1186 |
|
|
} |
1187 |
|
|
for (f=0; f<faceNum; f+=2) { /* split both face and anti-face */ |
1188 |
|
|
unsigned int oldedge11=faces[3*f], oldedge12=faces[3*f+1], |
1189 |
|
|
oldedge13=faces[3*f+2], oldedge21=faces[3*f+3], |
1190 |
|
|
oldedge22=faces[3*f+4], oldedge23=faces[3*f+5]; |
1191 |
|
|
unsigned int eidx=2*edgeNum+3*f; /* index of the first edge to add */ |
1192 |
|
|
char pol11=0, pol12=0, pol13=0, pol21=0, pol22=0, pol23=0; /* polarity */ |
1193 |
|
|
/* add three edges per face - anti-edge has to follow edge! */ |
1194 |
|
|
newedges[2*eidx]=newedges[2*eidx+9]=vertNum+oldedge11; |
1195 |
|
|
newedges[2*eidx+1]=newedges[2*eidx+4]=vertNum+oldedge12; |
1196 |
|
|
newedges[2*eidx+5]=newedges[2*eidx+8]=vertNum+oldedge13; |
1197 |
|
|
newedges[2*eidx+2]=newedges[2*eidx+11]=vertNum+oldedge21; |
1198 |
|
|
newedges[2*eidx+3]=newedges[2*eidx+6]=vertNum+oldedge22; |
1199 |
|
|
newedges[2*eidx+7]=newedges[2*eidx+10]=vertNum+oldedge23; |
1200 |
|
|
/* split the faces - we do not have directed half-edges! |
1201 |
|
|
* determine the "polarity" of the edges (0 forward / 2 backward) */ |
1202 |
|
|
if (edges[2*oldedge11+1]==edges[2*oldedge13+1] || |
1203 |
|
|
edges[2*oldedge11+1]==edges[2*oldedge13]) |
1204 |
|
|
pol11=2; |
1205 |
|
|
if (edges[2*oldedge12+1]==edges[2*oldedge11+1] || |
1206 |
|
|
edges[2*oldedge12+1]==edges[2*oldedge11]) |
1207 |
|
|
pol12=2; |
1208 |
|
|
if (edges[2*oldedge13+1]==edges[2*oldedge12+1] || |
1209 |
|
|
edges[2*oldedge13+1]==edges[2*oldedge12]) |
1210 |
|
|
pol13=2; |
1211 |
|
|
if (edges[2*oldedge21+1]==edges[2*oldedge23+1] || |
1212 |
|
|
edges[2*oldedge21+1]==edges[2*oldedge23]) |
1213 |
|
|
pol21=2; |
1214 |
|
|
if (edges[2*oldedge22+1]==edges[2*oldedge21+1] || |
1215 |
|
|
edges[2*oldedge22+1]==edges[2*oldedge21]) |
1216 |
|
|
pol22=2; |
1217 |
|
|
if (edges[2*oldedge23+1]==edges[2*oldedge22+1] || |
1218 |
|
|
edges[2*oldedge23+1]==edges[2*oldedge22]) |
1219 |
|
|
pol23=2; |
1220 |
|
|
|
1221 |
|
|
newfaces[12*f] = 2*oldedge11-(oldedge11%2)+pol11; /* bottom/left */ |
1222 |
|
|
newfaces[12*f+1] = eidx+4; |
1223 |
|
|
newfaces[12*f+2] = 2*oldedge13-(oldedge13%2)+2-pol13; |
1224 |
|
|
newfaces[12*f+3] = 2*oldedge21-(oldedge21%2)+pol21; /* anti */ |
1225 |
|
|
newfaces[12*f+4] = eidx+5; |
1226 |
|
|
newfaces[12*f+5] = 2*oldedge23-(oldedge23%2)+2-pol23; |
1227 |
|
|
|
1228 |
|
|
newfaces[12*f+6] = 2*oldedge11-(oldedge11%2)+2-pol11; /* bottom/right */ |
1229 |
|
|
newfaces[12*f+7] = 2*oldedge12-(oldedge12%2)+pol12; |
1230 |
|
|
newfaces[12*f+8] = eidx; |
1231 |
|
|
newfaces[12*f+9] = 2*oldedge21-(oldedge21%2)+2-pol21; /* anti */ |
1232 |
|
|
newfaces[12*f+10]= 2*oldedge22-(oldedge22%2)+pol22; |
1233 |
|
|
newfaces[12*f+11]= eidx+1; |
1234 |
|
|
|
1235 |
|
|
newfaces[12*f+12]= 2*oldedge12-(oldedge12%2)+2-pol12; /* top */ |
1236 |
|
|
newfaces[12*f+13]= 2*oldedge13-(oldedge13%2)+pol13; |
1237 |
|
|
newfaces[12*f+14]= eidx+2; |
1238 |
|
|
newfaces[12*f+15]= 2*oldedge22-(oldedge22%2)+2-pol22; /* anti */ |
1239 |
|
|
newfaces[12*f+16]= 2*oldedge23-(oldedge23%2)+pol23; |
1240 |
|
|
newfaces[12*f+17]= eidx+3; |
1241 |
|
|
|
1242 |
|
|
newfaces[12*f+18]= eidx; /* center */ |
1243 |
|
|
newfaces[12*f+19]= eidx+2; |
1244 |
|
|
newfaces[12*f+20]= eidx+4; |
1245 |
|
|
newfaces[12*f+21]= eidx+1; /* anti */ |
1246 |
|
|
newfaces[12*f+22]= eidx+3; |
1247 |
|
|
newfaces[12*f+23]= eidx+5; |
1248 |
|
|
} |
1249 |
|
|
/* make subdivided mesh the current one */ |
1250 |
|
|
airMopSub(mop, verts, airFree); |
1251 |
|
|
airMopSub(mop, edges, airFree); |
1252 |
|
|
airMopSub(mop, faces, airFree); |
1253 |
|
|
free(verts); free(edges); free(faces); |
1254 |
|
|
verts=newverts; edges=newedges; faces=newfaces; |
1255 |
|
|
vertNum=nvertNum; edgeNum=nedgeNum; faceNum=nfaceNum; |
1256 |
|
|
} |
1257 |
|
|
/* done; now copy to a limnPolyData struct */ |
1258 |
|
|
if (limnPolyDataAlloc(pld, infoBitFlag, vertNum, 3*faceNum, 1)) { |
1259 |
|
|
biffAddf(LIMN, "%s: couldn't allocate output", me); |
1260 |
|
|
return 1; |
1261 |
|
|
} |
1262 |
|
|
xyzwp=pld->xyzw; vertp=verts; |
1263 |
|
|
for (i=0; i<vertNum; i++) { |
1264 |
|
|
ELL_4V_SET(xyzwp, vertp[0], vertp[1], vertp[2], 1.0); |
1265 |
|
|
xyzwp+=4; vertp+=3; |
1266 |
|
|
} |
1267 |
|
|
if ((1 << limnPolyDataInfoNorm) & infoBitFlag) { |
1268 |
|
|
/* normals equal the vertex coordinates */ |
1269 |
|
|
memcpy(pld->norm, verts, sizeof(float)*3*vertNum); |
1270 |
|
|
} |
1271 |
|
|
if ((1 << limnPolyDataInfoRGBA) & infoBitFlag) { |
1272 |
|
|
rgbap=pld->rgba; vertp=verts; |
1273 |
|
|
for (i=0; i<vertNum; i++) { |
1274 |
|
|
ELL_4V_SET_TT(rgbap, unsigned char, 255, 255, 255, 255); |
1275 |
|
|
rgbap+=4; vertp+=3; |
1276 |
|
|
} |
1277 |
|
|
} |
1278 |
|
|
if ((1 << limnPolyDataInfoTex2) & infoBitFlag) { |
1279 |
|
|
for (i=0; i<vertNum; i++) { |
1280 |
|
|
double rr, xyz[3], phi, theta; |
1281 |
|
|
ELL_3V_COPY(xyz, pld->xyzw + 4*i); |
1282 |
|
|
rr = sqrt(xyz[0]*xyz[0] + xyz[1]*xyz[1]); |
1283 |
|
|
phi = atan2(rr, xyz[2]); |
1284 |
|
|
theta = atan2(xyz[1], xyz[0]); |
1285 |
|
|
ELL_2V_SET_TT(pld->tex2 + 2*i, float, |
1286 |
|
|
AIR_AFFINE(-AIR_PI, theta, AIR_PI, 0.0, 1.0), |
1287 |
|
|
AIR_AFFINE(0.0, phi, AIR_PI, 0.0, 1.0)); |
1288 |
|
|
} |
1289 |
|
|
} |
1290 |
|
|
if ((1 << limnPolyDataInfoTang) & infoBitFlag) { |
1291 |
|
|
for (i=0; i<vertNum; i++) { |
1292 |
|
|
double rr, xyz[3], tang[3], len; |
1293 |
|
|
ELL_3V_COPY(xyz, pld->xyzw + 4*i); |
1294 |
|
|
rr = sqrt(xyz[0]*xyz[0] + xyz[1]*xyz[1]); |
1295 |
|
|
if (rr) { |
1296 |
|
|
ELL_3V_SET(tang, -xyz[1], xyz[0], 0.0); |
1297 |
|
|
ELL_3V_NORM_TT(pld->tang + 3*i, float, tang, len); |
1298 |
|
|
} else { |
1299 |
|
|
ELL_3V_SET(pld->tang + 3*i, 1.0f, 0.0f, 0.0f); |
1300 |
|
|
} |
1301 |
|
|
} |
1302 |
|
|
} |
1303 |
|
|
|
1304 |
|
|
/* We need to replace reference to edges in faces with references to |
1305 |
|
|
* vertices. Make sure that they are ordered CCW */ |
1306 |
|
|
pld->type[0] = limnPrimitiveTriangles; |
1307 |
|
|
pld->icnt[0] = faceNum*3; |
1308 |
|
|
for (f=0; f<faceNum; ++f) { |
1309 |
|
|
unsigned int vertices[3]; /* find the right vertices */ |
1310 |
|
|
float diff1[3],diff2[3],cross[3]; |
1311 |
|
|
vertices[0]=edges[2*faces[3*f]]; |
1312 |
|
|
vertices[1]=edges[2*faces[3*f]+1]; |
1313 |
|
|
if (edges[2*faces[3*f+1]]==vertices[0] || |
1314 |
|
|
edges[2*faces[3*f+1]]==vertices[1]) |
1315 |
|
|
vertices[2]=edges[2*faces[3*f+1]+1]; |
1316 |
|
|
else |
1317 |
|
|
vertices[2]=edges[2*faces[3*f+1]]; |
1318 |
|
|
/* put them into correct order */ |
1319 |
|
|
ELL_3V_SUB(diff1,verts+3*vertices[1],verts+3*vertices[0]); |
1320 |
|
|
ELL_3V_SUB(diff2,verts+3*vertices[2],verts+3*vertices[0]); |
1321 |
|
|
ELL_3V_CROSS(cross,diff1,diff2); |
1322 |
|
|
pld->indx[3*f]=vertices[0]; |
1323 |
|
|
if (ELL_3V_DOT(cross,verts+3*vertices[0])<0) { |
1324 |
|
|
pld->indx[3*f+1]=vertices[2]; |
1325 |
|
|
pld->indx[3*f+2]=vertices[1]; |
1326 |
|
|
} else { |
1327 |
|
|
pld->indx[3*f+1]=vertices[1]; |
1328 |
|
|
pld->indx[3*f+2]=vertices[2]; |
1329 |
|
|
} |
1330 |
|
|
} |
1331 |
|
|
/* re-order the triangles */ |
1332 |
|
|
center=3*(faceNum/2); |
1333 |
|
|
for (i=0; i<faceNum/2; i++) { |
1334 |
|
|
ELL_3V_COPY(faces+3*i,pld->indx+6*i); |
1335 |
|
|
ELL_3V_COPY(faces+center+3*i,pld->indx+6*i+3); |
1336 |
|
|
} |
1337 |
|
|
airMopAdd(mop, pld->indx, airFree, airMopAlways); |
1338 |
|
|
airMopSub(mop, faces, airFree); |
1339 |
|
|
pld->indx=faces; |
1340 |
|
|
/* done */ |
1341 |
|
|
airMopOkay(mop); |
1342 |
|
|
return 0; |
1343 |
|
|
error_and_exit: |
1344 |
|
|
biffAddf(LIMN, "%s: memory allocation failed", me); |
1345 |
|
|
airMopError(mop); |
1346 |
|
|
return 1; |
1347 |
|
|
} |
1348 |
|
|
|
1349 |
|
|
int |
1350 |
|
|
limnPolyDataPlane(limnPolyData *pld, |
1351 |
|
|
unsigned int infoBitFlag, |
1352 |
|
|
unsigned int uRes, unsigned int vRes) { |
1353 |
|
|
static const char me[]="limnPolyDataPlane"; |
1354 |
|
|
unsigned int vertNum, indxNum, primNum, uIdx, vIdx, vertIdx, primIdx; |
1355 |
|
|
float uu, vv; |
1356 |
|
|
|
1357 |
|
|
/* sanity */ |
1358 |
|
|
uRes = AIR_MAX(2, uRes); |
1359 |
|
|
vRes = AIR_MAX(2, vRes); |
1360 |
|
|
|
1361 |
|
|
vertNum = uRes*vRes; |
1362 |
|
|
primNum = vRes-1; |
1363 |
|
|
indxNum = primNum*2*uRes; |
1364 |
|
|
if (limnPolyDataAlloc(pld, infoBitFlag, vertNum, indxNum, primNum)) { |
1365 |
|
|
biffAddf(LIMN, "%s: couldn't allocate output", me); |
1366 |
|
|
return 1; |
1367 |
|
|
} |
1368 |
|
|
|
1369 |
|
|
vertIdx = 0; |
1370 |
|
|
for (vIdx=0; vIdx<vRes; vIdx++) { |
1371 |
|
|
vv = AIR_CAST(float, AIR_AFFINE(0, vIdx, vRes-1, -1.0, 1.0)); |
1372 |
|
|
for (uIdx=0; uIdx<uRes; uIdx++) { |
1373 |
|
|
uu = AIR_CAST(float, AIR_AFFINE(0, uIdx, uRes-1, -1.0, 1.0)); |
1374 |
|
|
ELL_4V_SET(pld->xyzw + 4*vertIdx, uu, vv, 0.0, 1.0); |
1375 |
|
|
if ((1 << limnPolyDataInfoNorm) & infoBitFlag) { |
1376 |
|
|
ELL_3V_SET_TT(pld->norm + 3*vertIdx, float, 0.0, 0.0, 1.0); |
1377 |
|
|
} |
1378 |
|
|
if ((1 << limnPolyDataInfoRGBA) & infoBitFlag) { |
1379 |
|
|
ELL_4V_SET(pld->rgba + 4*vertIdx, 255, 255, 255, 255); |
1380 |
|
|
} |
1381 |
|
|
if ((1 << limnPolyDataInfoTex2) & infoBitFlag) { |
1382 |
|
|
ELL_2V_SET_TT(pld->tex2 + 2*vertIdx, float, (uu+1.0)/2.0, (vv+1.0)/2.0); |
1383 |
|
|
} |
1384 |
|
|
if ((1 << limnPolyDataInfoTang) & infoBitFlag) { |
1385 |
|
|
ELL_3V_SET_TT(pld->tang + 3*vertIdx, float, 1.0, 0.0, 0.0); |
1386 |
|
|
} |
1387 |
|
|
++vertIdx; |
1388 |
|
|
} |
1389 |
|
|
} |
1390 |
|
|
|
1391 |
|
|
vertIdx = 0; |
1392 |
|
|
for (primIdx=0; primIdx<primNum; primIdx++) { |
1393 |
|
|
for (uIdx=0; uIdx<uRes; uIdx++) { |
1394 |
|
|
pld->indx[vertIdx++] = uIdx + uRes*(primIdx+1); |
1395 |
|
|
pld->indx[vertIdx++] = uIdx + uRes*(primIdx); |
1396 |
|
|
} |
1397 |
|
|
pld->type[primIdx] = limnPrimitiveTriangleStrip; |
1398 |
|
|
pld->icnt[primIdx] = 2*uRes; |
1399 |
|
|
} |
1400 |
|
|
|
1401 |
|
|
return 0; |
1402 |
|
|
} |
1403 |
|
|
|
1404 |
|
|
int |
1405 |
|
|
limnPolyDataSquare(limnPolyData *pld, unsigned int infoBitFlag) { |
1406 |
|
|
static const char me[]="limnPolyDataSquare"; |
1407 |
|
|
|
1408 |
|
|
if (limnPolyDataAlloc(pld, infoBitFlag, 4, 4, 1)) { |
1409 |
|
|
biffAddf(LIMN, "%s: couldn't allocate output", me); |
1410 |
|
|
return 1; |
1411 |
|
|
} |
1412 |
|
|
ELL_4V_SET(pld->xyzw + 4*0, -1.0, -1.0, 0.0, 1.0); |
1413 |
|
|
ELL_4V_SET(pld->xyzw + 4*1, 1.0, -1.0, 0.0, 1.0); |
1414 |
|
|
ELL_4V_SET(pld->xyzw + 4*2, -1.0, 1.0, 0.0, 1.0); |
1415 |
|
|
ELL_4V_SET(pld->xyzw + 4*3, 1.0, 1.0, 0.0, 1.0); |
1416 |
|
|
if ((1 << limnPolyDataInfoNorm) & infoBitFlag) { |
1417 |
|
|
ELL_3V_SET(pld->norm + 3*0, 0.0, 0.0, 1.0); |
1418 |
|
|
ELL_3V_SET(pld->norm + 3*1, 0.0, 0.0, 1.0); |
1419 |
|
|
ELL_3V_SET(pld->norm + 3*2, 0.0, 0.0, 1.0); |
1420 |
|
|
ELL_3V_SET(pld->norm + 3*3, 0.0, 0.0, 1.0); |
1421 |
|
|
} |
1422 |
|
|
if ((1 << limnPolyDataInfoRGBA) & infoBitFlag) { |
1423 |
|
|
ELL_4V_SET(pld->rgba + 4*0, 255, 255, 255, 255); |
1424 |
|
|
ELL_4V_SET(pld->rgba + 4*1, 255, 255, 255, 255); |
1425 |
|
|
ELL_4V_SET(pld->rgba + 4*2, 255, 255, 255, 255); |
1426 |
|
|
ELL_4V_SET(pld->rgba + 4*3, 255, 255, 255, 255); |
1427 |
|
|
} |
1428 |
|
|
if ((1 << limnPolyDataInfoTex2) & infoBitFlag) { |
1429 |
|
|
ELL_2V_SET(pld->tex2 + 2*0, 0.0, 1.0); |
1430 |
|
|
ELL_2V_SET(pld->tex2 + 2*1, 1.0, 1.0); |
1431 |
|
|
ELL_2V_SET(pld->tex2 + 2*2, 0.0, 0.0); |
1432 |
|
|
ELL_2V_SET(pld->tex2 + 2*3, 1.0, 0.0); |
1433 |
|
|
} |
1434 |
|
|
if ((1 << limnPolyDataInfoTang) & infoBitFlag) { |
1435 |
|
|
ELL_3V_SET(pld->tang + 3*0, 1.0, 0.0, 0.0); |
1436 |
|
|
ELL_3V_SET(pld->tang + 3*1, 1.0, 0.0, 0.0); |
1437 |
|
|
ELL_3V_SET(pld->tang + 3*2, 1.0, 0.0, 0.0); |
1438 |
|
|
ELL_3V_SET(pld->tang + 3*3, 1.0, 0.0, 0.0); |
1439 |
|
|
} |
1440 |
|
|
pld->type[0] = limnPrimitiveTriangleStrip; |
1441 |
|
|
ELL_4V_SET(pld->indx, 0, 1, 2, 3); |
1442 |
|
|
pld->icnt[0] = 4; |
1443 |
|
|
|
1444 |
|
|
return 0; |
1445 |
|
|
} |
1446 |
|
|
|
1447 |
|
|
int |
1448 |
|
|
limnPolyDataSuperquadric2D(limnPolyData *pld, |
1449 |
|
|
unsigned int infoBitFlag, |
1450 |
|
|
float alpha, unsigned int res) { |
1451 |
|
|
static const char me[]="limnPolyDataSuperquadric2D"; |
1452 |
|
|
unsigned int i, vertNum; |
1453 |
|
|
float phi; |
1454 |
|
|
|
1455 |
|
|
vertNum = res+1; /* initial vertex at origin */ |
1456 |
|
|
if (limnPolyDataAlloc(pld, infoBitFlag, vertNum, |
1457 |
|
|
vertNum+1, /* last index wraps around */ |
1458 |
|
|
1)) { |
1459 |
|
|
biffAddf(LIMN, "%s: couldn't allocate output", me); |
1460 |
|
|
return 1; |
1461 |
|
|
} |
1462 |
|
|
/* initial vertex at origin */ |
1463 |
|
|
ELL_4V_SET(pld->xyzw + 4*0, 0.0, 0.0, 0.0, 1.0); |
1464 |
|
|
/* printf("!%s: xyzw[0] = %g %g %g %g\n", me, (pld->xyzw + 4*0)[0], (pld->xyzw + 4*0)[1], (pld->xyzw + 4*0)[2], (pld->xyzw + 4*0)[3]); */ |
1465 |
|
|
for (i=1; i<vertNum; i++) { |
1466 |
|
|
phi = AIR_AFFINE(1, i, vertNum, 0, 2*AIR_PI); |
1467 |
|
|
ELL_4V_SET(pld->xyzw + 4*i, |
1468 |
|
|
airSgnPow(cos(phi),alpha), |
1469 |
|
|
airSgnPow(sin(phi),alpha), |
1470 |
|
|
0.0, 1.0); |
1471 |
|
|
/* printf("!%s: xyzw[%u] = %g %g %g %g\n", me, i ,(pld->xyzw + 4*i)[0], (pld->xyzw + 4*i)[1], (pld->xyzw + 4*i)[2], (pld->xyzw + 4*i)[3]); */ |
1472 |
|
|
} |
1473 |
|
|
if ((1 << limnPolyDataInfoNorm) & infoBitFlag) { |
1474 |
|
|
for (i=0; i<vertNum; i++) { |
1475 |
|
|
ELL_3V_SET(pld->norm + 3*i, 0.0, 0.0, 1.0); |
1476 |
|
|
} |
1477 |
|
|
} |
1478 |
|
|
if ((1 << limnPolyDataInfoRGBA) & infoBitFlag) { |
1479 |
|
|
for (i=0; i<vertNum; i++) { |
1480 |
|
|
ELL_4V_SET(pld->rgba + 4*i, 255, 255, 255, 255); |
1481 |
|
|
} |
1482 |
|
|
} |
1483 |
|
|
if ((1 << limnPolyDataInfoTex2) & infoBitFlag) { |
1484 |
|
|
/* punting */ |
1485 |
|
|
ELL_2V_COPY(pld->tex2 + 2*i, pld->xyzw + 4*i); |
1486 |
|
|
} |
1487 |
|
|
if ((1 << limnPolyDataInfoTang) & infoBitFlag) { |
1488 |
|
|
/* punting */ |
1489 |
|
|
ELL_3V_SET(pld->tang + 3*i, 0.0, 0.0, 0.0); |
1490 |
|
|
} |
1491 |
|
|
pld->type[0] = limnPrimitiveTriangleFan; |
1492 |
|
|
for (i=0; i<vertNum; i++) { |
1493 |
|
|
pld->indx[i] = i; |
1494 |
|
|
/* printf("!%s: idx[%u] = %u\n", me, i, pld->indx[i]); */ |
1495 |
|
|
} |
1496 |
|
|
/* very last index loops around to first non-origin point */ |
1497 |
|
|
pld->indx[i] = 1; |
1498 |
|
|
/* printf("!%s: idx[%u] = %u\n", me, i, pld->indx[i]); */ |
1499 |
|
|
pld->icnt[0] = vertNum+1; |
1500 |
|
|
|
1501 |
|
|
return 0; |
1502 |
|
|
} |
1503 |
|
|
|