GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: src/limn/shapes.c Lines: 0 219 0.0 %
Date: 2017-05-26 Branches: 0 77 0.0 %

Line Branch Exec Source
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) 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
25
#include "limn.h"
26
27
int
28
limnObjectCubeAdd(limnObject *obj, unsigned int lookIdx) {
29
  unsigned int vII[4], vII0, partIdx;
30
31
  partIdx = limnObjectPartAdd(obj);
32
  /* HEY: we have to set this first so that
33
     obj->setVertexRGBAFromLook can do the right thing */
34
  obj->part[partIdx]->lookIdx = lookIdx;
35
  /*
36
                                     7     6
37
38
                  z               4     5
39
                  |    y
40
                  |   /              3     2
41
                  |  /
42
                  | /             0     1
43
                    ------ x
44
  */
45
  vII0 = limnObjectVertexAdd(obj, partIdx, -1, -1, -1);
46
  limnObjectVertexAdd(obj, partIdx, 1, -1, -1);
47
  limnObjectVertexAdd(obj, partIdx, 1,  1, -1);
48
  limnObjectVertexAdd(obj, partIdx, -1,  1, -1);
49
  limnObjectVertexAdd(obj, partIdx, -1, -1,  1);
50
  limnObjectVertexAdd(obj, partIdx, 1, -1,  1);
51
  limnObjectVertexAdd(obj, partIdx, 1,  1,  1);
52
  limnObjectVertexAdd(obj, partIdx, -1,  1,  1);
53
  ELL_4V_SET(vII, vII0+3, vII0+2, vII0+1, vII0+0);
54
  limnObjectFaceAdd(obj, partIdx, lookIdx, 4, vII);
55
  ELL_4V_SET(vII, vII0+1, vII0+5, vII0+4, vII0+0);
56
  limnObjectFaceAdd(obj, partIdx, lookIdx, 4, vII);
57
  ELL_4V_SET(vII, vII0+2, vII0+6, vII0+5, vII0+1);
58
  limnObjectFaceAdd(obj, partIdx, lookIdx, 4, vII);
59
  ELL_4V_SET(vII, vII0+3, vII0+7, vII0+6, vII0+2);
60
  limnObjectFaceAdd(obj, partIdx, lookIdx, 4, vII);
61
  ELL_4V_SET(vII, vII0+0, vII0+4, vII0+7, vII0+3);
62
  limnObjectFaceAdd(obj, partIdx, lookIdx, 4, vII);
63
  ELL_4V_SET(vII, vII0+5, vII0+6, vII0+7, vII0+4);
64
  limnObjectFaceAdd(obj, partIdx, lookIdx, 4, vII);
65
66
  return partIdx;
67
}
68
69
int
70
limnObjectSquareAdd(limnObject *obj, unsigned int lookIdx) {
71
  unsigned int vII0, vII[4], partIdx;
72
73
  partIdx = limnObjectPartAdd(obj);
74
  /* HEY: we have to set this first so that
75
     obj->setVertexRGBAFromLook can do the right thing */
76
  obj->part[partIdx]->lookIdx = lookIdx;
77
  vII0 = limnObjectVertexAdd(obj, partIdx, 0, 0, 0);
78
  limnObjectVertexAdd(obj, partIdx, 1, 0, 0);
79
  limnObjectVertexAdd(obj, partIdx, 1, 1, 0);
80
  limnObjectVertexAdd(obj, partIdx, 0, 1, 0);
81
  ELL_4V_SET(vII, vII0+0, vII0+1, vII0+2, vII0+3);
82
  limnObjectFaceAdd(obj, partIdx, lookIdx, 4, vII);
83
  return partIdx;
84
}
85
86
/*
87
******** limnObjectCylinderAdd
88
**
89
** adds a cylinder that fills up the bi-unit cube [-1,1]^3,
90
** with axis "axis" (0:X, 1:Y, 2:Z), with discretization "res"
91
*/
92
int
93
limnObjectCylinderAdd(limnObject *obj, unsigned int lookIdx,
94
                      unsigned int axis, unsigned int res) {
95
  unsigned int partIdx, ii, jj, tmp, vII0=0, *vII;
96
  double theta;
97
98
  partIdx = limnObjectPartAdd(obj);
99
  /* HEY: we have to set this first so that
100
     obj->setVertexRGBAFromLook can do the right thing */
101
  obj->part[partIdx]->lookIdx = lookIdx;
102
  vII = (unsigned int *)calloc(res, sizeof(unsigned int));
103
104
  for (ii=0; ii<=res-1; ii++) {
105
    theta = AIR_AFFINE(0, ii, res, 0, 2*AIR_PI);
106
    switch(axis) {
107
    case 0:
108
      tmp = limnObjectVertexAdd(obj, partIdx,
109
                                1,
110
                                AIR_CAST(float, -sin(theta)),
111
                                AIR_CAST(float, cos(theta)));
112
      limnObjectVertexAdd(obj, partIdx,
113
                          -1,
114
                          AIR_CAST(float, -sin(theta)),
115
                          AIR_CAST(float, cos(theta)));
116
      break;
117
    case 1:
118
      tmp = limnObjectVertexAdd(obj, partIdx,
119
                                AIR_CAST(float, sin(theta)),
120
                                1,
121
                                AIR_CAST(float, cos(theta)));
122
      limnObjectVertexAdd(obj, partIdx,
123
                          AIR_CAST(float, sin(theta)),
124
                          -1,
125
                          AIR_CAST(float, cos(theta)));
126
      break;
127
    case 2: default:
128
      tmp = limnObjectVertexAdd(obj, partIdx,
129
                                AIR_CAST(float, cos(theta)),
130
                                AIR_CAST(float, sin(theta)),
131
                                1);
132
      limnObjectVertexAdd(obj, partIdx,
133
                          AIR_CAST(float, cos(theta)),
134
                          AIR_CAST(float, sin(theta)),
135
                          -1);
136
      break;
137
    }
138
    if (!ii) {
139
      vII0 = tmp;
140
    }
141
  }
142
  /* add all side faces */
143
  for (ii=0; ii<=res-1; ii++) {
144
    jj = (ii+1) % res;
145
    ELL_4V_SET(vII, vII0 + 2*ii, vII0 + 2*ii + 1,
146
               vII0 + 2*jj + 1, vII0 + 2*jj);
147
    limnObjectFaceAdd(obj, partIdx, lookIdx, 4, vII);
148
  }
149
  /* add top */
150
  for (ii=0; ii<=res-1; ii++) {
151
    vII[ii] = vII0 + 2*ii;
152
  }
153
  limnObjectFaceAdd(obj, partIdx, lookIdx, res, vII);
154
  /* add bottom */
155
  for (ii=0; ii<=res-1; ii++) {
156
    vII[ii] = vII0 + 2*(res-1-ii) + 1;
157
  }
158
  limnObjectFaceAdd(obj, partIdx, lookIdx, res, vII);
159
160
  free(vII);
161
  return partIdx;
162
}
163
164
int
165
limnObjectConeAdd(limnObject *obj, unsigned int lookIdx,
166
                  unsigned int axis, unsigned int res) {
167
  double th;
168
  unsigned int partIdx, tmp, vII0=0, ii, jj, *vII;
169
170
  vII = (unsigned int *)calloc(res, sizeof(unsigned int));
171
172
  partIdx = limnObjectPartAdd(obj);
173
  /* HEY: we have to set this first so that
174
     obj->setVertexRGBAFromLook can do the right thing */
175
  obj->part[partIdx]->lookIdx = lookIdx;
176
  for (ii=0; ii<=res-1; ii++) {
177
    th = AIR_AFFINE(0, ii, res, 0, 2*AIR_PI);
178
    switch(axis) {
179
    case 0:
180
      tmp = limnObjectVertexAdd(obj, partIdx,
181
                                0,
182
                                AIR_CAST(float, -sin(th)),
183
                                AIR_CAST(float, cos(th)));
184
      break;
185
    case 1:
186
      tmp = limnObjectVertexAdd(obj, partIdx,
187
                                AIR_CAST(float, sin(th)),
188
                                0,
189
                                AIR_CAST(float, cos(th)));
190
      break;
191
    case 2: default:
192
      tmp = limnObjectVertexAdd(obj, partIdx,
193
                                AIR_CAST(float, cos(th)),
194
                                AIR_CAST(float, sin(th)),
195
                                0);
196
      break;
197
    }
198
    if (!ii) {
199
      vII0 = tmp;
200
    }
201
  }
202
  switch(axis) {
203
  case 0:
204
    limnObjectVertexAdd(obj, partIdx, 1, 0, 0);
205
    break;
206
  case 1:
207
    limnObjectVertexAdd(obj, partIdx, 0, 1, 0);
208
    break;
209
  case 2: default:
210
    limnObjectVertexAdd(obj, partIdx, 0, 0, 1);
211
    break;
212
  }
213
  for (ii=0; ii<=res-1; ii++) {
214
    jj = (ii+1) % res;
215
    ELL_3V_SET(vII, vII0+ii, vII0+jj, vII0+res);
216
    limnObjectFaceAdd(obj, partIdx, lookIdx, 3, vII);
217
  }
218
  for (ii=0; ii<=res-1; ii++) {
219
    vII[ii] = vII0+res-1-ii;
220
  }
221
  limnObjectFaceAdd(obj, partIdx, lookIdx, res, vII);
222
223
  free(vII);
224
  return partIdx;
225
}
226
227
int
228
limnObjectPolarSphereAdd(limnObject *obj, unsigned int lookIdx,
229
                         unsigned int axis, unsigned int thetaRes,
230
                         unsigned int phiRes) {
231
  unsigned int partIdx, vII0, nti, ti, pi, vII[4], pl;
232
  double t, p;
233
234
  thetaRes = AIR_MAX(thetaRes, 3);
235
  phiRes = AIR_MAX(phiRes, 2);
236
237
  partIdx = limnObjectPartAdd(obj);
238
  /* HEY: we have to set this first so that
239
     obj->setVertexRGBAFromLook can do the right thing */
240
  obj->part[partIdx]->lookIdx = lookIdx;
241
  switch(axis) {
242
  case 0:
243
    vII0 = limnObjectVertexAdd(obj, partIdx, 1, 0, 0);
244
    break;
245
  case 1:
246
    vII0 = limnObjectVertexAdd(obj, partIdx, 0, 1, 0);
247
    break;
248
  case 2: default:
249
    vII0 = limnObjectVertexAdd(obj, partIdx, 0, 0, 1);
250
    break;
251
  }
252
  for (pi=1; pi<=phiRes-1; pi++) {
253
    p = AIR_AFFINE(0, pi, phiRes, 0, AIR_PI);
254
    for (ti=0; ti<=thetaRes-1; ti++) {
255
      t = AIR_AFFINE(0, ti, thetaRes, 0, 2*AIR_PI);
256
      switch(axis) {
257
      case 0:
258
        limnObjectVertexAdd(obj, partIdx,
259
                            AIR_CAST(float, cos(p)),
260
                            AIR_CAST(float, -sin(t)*sin(p)),
261
                            AIR_CAST(float, cos(t)*sin(p)));
262
        break;
263
      case 1:
264
        limnObjectVertexAdd(obj, partIdx,
265
                            AIR_CAST(float, sin(t)*sin(p)),
266
                            AIR_CAST(float, cos(p)),
267
                            AIR_CAST(float, cos(t)*sin(p)));
268
        break;
269
      case 2: default:
270
        limnObjectVertexAdd(obj, partIdx,
271
                            AIR_CAST(float, cos(t)*sin(p)),
272
                            AIR_CAST(float, sin(t)*sin(p)),
273
                            AIR_CAST(float, cos(p)));
274
        break;
275
      }
276
    }
277
  }
278
  switch(axis) {
279
  case 0:
280
    pl = limnObjectVertexAdd(obj, partIdx, -1, 0, 0);
281
    break;
282
  case 1:
283
    pl = limnObjectVertexAdd(obj, partIdx, 0, -1, 0);
284
    break;
285
  case 2: default:
286
    pl = limnObjectVertexAdd(obj, partIdx, 0, 0, -1);
287
    break;
288
  }
289
  for (ti=1; ti<=thetaRes; ti++) {
290
    nti = ti < thetaRes ? ti+1 : 1;
291
    ELL_3V_SET(vII, vII0+ti, vII0+nti, vII0+0);
292
    limnObjectFaceAdd(obj, partIdx, lookIdx, 3, vII);
293
  }
294
  for (pi=0; pi<=phiRes-3; pi++) {
295
    for (ti=1; ti<=thetaRes; ti++) {
296
      nti = ti < thetaRes ? ti+1 : 1;
297
      ELL_4V_SET(vII, vII0+pi*thetaRes + ti, vII0+(pi+1)*thetaRes + ti,
298
                 vII0+(pi+1)*thetaRes + nti, vII0+pi*thetaRes + nti);
299
      limnObjectFaceAdd(obj, partIdx, lookIdx, 4, vII);
300
    }
301
  }
302
  for (ti=1; ti<=thetaRes; ti++) {
303
    nti = ti < thetaRes ? ti+1 : 1;
304
    ELL_3V_SET(vII, vII0+pi*thetaRes + ti, pl, vII0+pi*thetaRes + nti);
305
    limnObjectFaceAdd(obj, partIdx, lookIdx, 3, vII);
306
  }
307
308
  return partIdx;
309
}
310
311
int
312
limnObjectPolarSuperquadFancyAdd(limnObject *obj,
313
                                 unsigned int lookIdx, unsigned int axis,
314
                                 float A, float B, float C, float R,
315
                                 unsigned int thetaRes, unsigned int phiRes) {
316
  unsigned int partIdx, vII0, nti, ti, pi, vII[4], pl;
317
  double x, y, z, t, p;
318
319
  AIR_UNUSED(R);
320
  thetaRes = AIR_MAX(thetaRes, 3);
321
  phiRes = AIR_MAX(phiRes, 2);
322
323
  partIdx = limnObjectPartAdd(obj);
324
  /* HEY: we have to set this first so that
325
     obj->setVertexRGBAFromLook can do the right thing */
326
  obj->part[partIdx]->lookIdx = lookIdx;
327
  switch(axis) {
328
  case 0:
329
    vII0 = limnObjectVertexAdd(obj, partIdx, 1, 0, 0);
330
    break;
331
  case 1:
332
    vII0 = limnObjectVertexAdd(obj, partIdx, 0, 1, 0);
333
    break;
334
  case 2: default:
335
    vII0 = limnObjectVertexAdd(obj, partIdx, 0, 0, 1);
336
    break;
337
  }
338
  for (pi=1; pi<=phiRes-1; pi++) {
339
    p = AIR_AFFINE(0, pi, phiRes, 0, AIR_PI);
340
    for (ti=0; ti<=thetaRes-1; ti++) {
341
      t = AIR_AFFINE(0, ti, thetaRes, 0, 2*AIR_PI);
342
      switch(axis) {
343
      case 0:
344
        x = airSgnPow(cos(p),B);
345
        y = -airSgnPow(sin(t),A) * airSgnPow(sin(p),B);
346
        z = airSgnPow(cos(t),A) * airSgnPow(sin(p),B);
347
        if (C != B) {
348
          /* modify profile along y axis to create beta=C */
349
          double yp, ymax;
350
          yp = airSgnPow(sin(acos(airSgnPow(x, 1/C))), C);
351
          ymax = airSgnPow(sin(p), B);
352
          if (ymax) {
353
            y *= yp/ymax;
354
          }
355
        }
356
        break;
357
      case 1:
358
        x = airSgnPow(sin(t),A) * airSgnPow(sin(p),B);
359
        y = airSgnPow(cos(p),B);
360
        z = airSgnPow(cos(t),A) * airSgnPow(sin(p),B);
361
        break;
362
      case 2: default:
363
        x = airSgnPow(cos(t),A) * airSgnPow(sin(p),B);
364
        y = airSgnPow(sin(t),A) * airSgnPow(sin(p),B);
365
        z = airSgnPow(cos(p),B);
366
        if (C != B) {
367
          /* modify profile along y axis to create beta=C */
368
          double yp, ymax;
369
          yp = airSgnPow(sin(acos(airSgnPow(z, 1/C))), C);
370
          ymax = airSgnPow(sin(p), B);
371
          if (ymax) {
372
            y *= yp/ymax;
373
          }
374
        }
375
        break;
376
      }
377
      limnObjectVertexAdd(obj, partIdx,
378
                          AIR_CAST(float, x),
379
                          AIR_CAST(float, y),
380
                          AIR_CAST(float, z));
381
    }
382
  }
383
  switch(axis) {
384
  case 0:
385
    pl = limnObjectVertexAdd(obj, partIdx, -1, 0, 0);
386
    break;
387
  case 1:
388
    pl = limnObjectVertexAdd(obj, partIdx, 0, -1, 0);
389
    break;
390
  case 2: default:
391
    pl = limnObjectVertexAdd(obj, partIdx, 0, 0, -1);
392
    break;
393
  }
394
  for (ti=1; ti<=thetaRes; ti++) {
395
    nti = ti < thetaRes ? ti+1 : 1;
396
    ELL_3V_SET(vII, vII0+ti, vII0+nti, vII0+0);
397
    limnObjectFaceAdd(obj, partIdx, lookIdx, 3, vII);
398
  }
399
  for (pi=0; pi<=phiRes-3; pi++) {
400
    for (ti=1; ti<=thetaRes; ti++) {
401
      nti = ti < thetaRes ? ti+1 : 1;
402
      ELL_4V_SET(vII, vII0+pi*thetaRes + ti, vII0+(pi+1)*thetaRes + ti,
403
                 vII0+(pi+1)*thetaRes + nti, vII0+pi*thetaRes + nti);
404
      limnObjectFaceAdd(obj, partIdx, lookIdx, 4, vII);
405
    }
406
  }
407
  for (ti=1; ti<=thetaRes; ti++) {
408
    nti = ti < thetaRes ? ti+1 : 1;
409
    ELL_3V_SET(vII, vII0+pi*thetaRes + ti, pl, vII0+pi*thetaRes + nti);
410
    limnObjectFaceAdd(obj, partIdx, lookIdx, 3, vII);
411
  }
412
413
  return partIdx;
414
}
415
416
int
417
limnObjectPolarSuperquadAdd(limnObject *obj,
418
                            unsigned int lookIdx, unsigned int axis,
419
                            float A, float B,
420
                            unsigned int thetaRes, unsigned int phiRes) {
421
422
  return limnObjectPolarSuperquadFancyAdd(obj, lookIdx, axis,
423
                                          A, B, B, 0,
424
                                          thetaRes, phiRes);
425
}