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 "hoover.h"
25 
26 hooverContext *
hooverContextNew()27 hooverContextNew() {
28   hooverContext *ctx;
29 
30   ctx = (hooverContext *)calloc(1, sizeof(hooverContext));
31   if (ctx) {
32     ctx->cam = limnCameraNew();
33     ELL_3V_SET(ctx->volSize, 0, 0, 0);
34     ELL_3V_SET(ctx->volSpacing, AIR_NAN, AIR_NAN, AIR_NAN);
35     ctx->volCentering = hooverDefVolCentering;
36     ctx->shape = NULL;
37     ctx->imgSize[0] = ctx->imgSize[1] = 0;
38     ctx->imgCentering = hooverDefImgCentering;
39     ctx->user = NULL;
40     ctx->numThreads = 1;
41     ctx->workIdx = 0;
42     ctx->workMutex = NULL;
43     ctx->renderBegin = hooverStubRenderBegin;
44     ctx->threadBegin = hooverStubThreadBegin;
45     ctx->rayBegin = hooverStubRayBegin;
46     ctx->sample = hooverStubSample;
47     ctx->rayEnd = hooverStubRayEnd;
48     ctx->threadEnd = hooverStubThreadEnd;
49     ctx->renderEnd = hooverStubRenderEnd;
50   }
51   return(ctx);
52 }
53 
54 int
hooverContextCheck(hooverContext * ctx)55 hooverContextCheck(hooverContext *ctx) {
56   static const char me[]="hooverContextCheck";
57   int sxe, sye, sze, minSize, centr;
58 
59   if (!ctx) {
60     biffAddf(HOOVER, "%s: got NULL pointer", me);
61     return 1;
62   }
63   if (airEnumValCheck(nrrdCenter, ctx->imgCentering)) {
64     biffAddf(HOOVER, "%s: pixel centering (%d) invalid",
65              me, ctx->imgCentering);
66     return 1;
67   }
68   centr = (ctx->shape ? ctx->shape->center : ctx->volCentering);
69   if (airEnumValCheck(nrrdCenter, centr)) {
70     biffAddf(HOOVER, "%s: voxel centering (%d) invalid", me, centr);
71     return 1;
72   }
73   if (limnCameraAspectSet(ctx->cam,
74                           ctx->imgSize[0], ctx->imgSize[1], ctx->imgCentering)
75       || limnCameraUpdate(ctx->cam)) {
76     biffMovef(HOOVER, LIMN, "%s: trouble setting up camera", me);
77     return 1;
78   }
79   if (ctx->shape) {
80     if (!ELL_4M_EXISTS(ctx->shape->ItoW)) {
81       biffAddf(HOOVER, "%s: given shape doesn't seem to be set", me);
82       return 1;
83     }
84   } else {
85     minSize = (nrrdCenterCell == centr ? 1 : 2);
86     if (!(ctx->volSize[0] >= minSize
87           && ctx->volSize[1] >= minSize
88           && ctx->volSize[2] >= minSize)) {
89       biffAddf(HOOVER, "%s: volume dimensions (%dx%dx%d) too small", me,
90                ctx->volSize[0], ctx->volSize[1], ctx->volSize[2]);
91       return 1;
92     }
93     sxe = AIR_EXISTS(ctx->volSpacing[0]);
94     sye = AIR_EXISTS(ctx->volSpacing[1]);
95     sze = AIR_EXISTS(ctx->volSpacing[2]);
96     if (!sxe && !sye && !sze) {
97       /* none of the incoming spacings existed, we'll go out on a limb
98          and assume unit spacing */
99       ctx->volSpacing[0] = nrrdDefaultSpacing;
100       ctx->volSpacing[1] = ctx->volSpacing[2] = ctx->volSpacing[0];
101       fprintf(stderr, "%s: WARNING: assuming spacing %g for all axes\n",
102               me, ctx->volSpacing[0]);
103       /* HEY : nrrdDefaultSpacing need not be the same as gageParm's
104          defaultSpacing, but we don't know anything about gage here,
105          so what else can we do? */
106     } else if (sxe && sye && sze) {
107       /* all existed */
108       if (!(ctx->volSpacing[0] > 0.0
109             && ctx->volSpacing[1] > 0.0
110             && ctx->volSpacing[2] > 0.0)) {
111         biffAddf(HOOVER, "%s: volume spacing (%gx%gx%g) invalid", me,
112                  ctx->volSpacing[0], ctx->volSpacing[1], ctx->volSpacing[2]);
113         return 1;
114       }
115     } else {
116       /* some existed, some didn't */
117       biffAddf(HOOVER, "%s: spacings %g, %g, %g don't all exist or not", me,
118                ctx->volSpacing[0], ctx->volSpacing[1], ctx->volSpacing[2]);
119       return 1;
120     }
121   }
122   if (!(ctx->imgSize[0] > 0 && ctx->imgSize[1] > 0)) {
123     biffAddf(HOOVER, "%s: image dimensions (%dx%d) invalid", me,
124              ctx->imgSize[0], ctx->imgSize[1]);
125     return 1;
126   }
127   if (!(ctx->numThreads >= 1)) {
128     biffAddf(HOOVER, "%s: number threads (%d) invalid", me, ctx->numThreads);
129     return 1;
130   }
131   if (!(ctx->numThreads <= HOOVER_THREAD_MAX)) {
132     biffAddf(HOOVER, "%s: sorry, number threads (%d) > max (%d)", me,
133              ctx->numThreads, HOOVER_THREAD_MAX);
134     return 1;
135   }
136   if (!ctx->renderBegin) {
137     biffAddf(HOOVER, "%s: need a non-NULL begin rendering callback", me);
138     return 1;
139   }
140   if (!ctx->rayBegin) {
141     biffAddf(HOOVER, "%s: need a non-NULL begin ray callback", me);
142     return 1;
143   }
144   if (!ctx->threadBegin) {
145     biffAddf(HOOVER, "%s: need a non-NULL begin thread callback", me);
146     return 1;
147   }
148   if (!ctx->sample) {
149     biffAddf(HOOVER, "%s: need a non-NULL sampler callback function", me);
150     return 1;
151   }
152   if (!ctx->rayEnd) {
153     biffAddf(HOOVER, "%s: need a non-NULL end ray callback", me);
154     return 1;
155   }
156   if (!ctx->threadEnd) {
157     biffAddf(HOOVER, "%s: need a non-NULL end thread callback", me);
158     return 1;
159   }
160   if (!ctx->renderEnd) {
161     biffAddf(HOOVER, "%s: need a non-NULL end render callback", me);
162     return 1;
163   }
164 
165   return 0;
166 }
167 
168 void
hooverContextNix(hooverContext * ctx)169 hooverContextNix(hooverContext *ctx) {
170 
171   if (ctx) {
172     limnCameraNix(ctx->cam);
173     /* workMutex is cleaned up at end of render */
174     free(ctx);
175   }
176 }
177 
178