1 /***********************************************************************/
2 /* Open Visualization Data Explorer */
3 /* (C) Copyright IBM Corp. 1989,1999 */
4 /* ALL RIGHTS RESERVED */
5 /* This code licensed under the */
6 /* "IBM PUBLIC LICENSE - Open Visualization Data Explorer" */
7 /***********************************************************************/
8
9 #include <dxconfig.h>
10
11
12
13 #include <stdio.h>
14 #include <math.h>
15 #include <string.h>
16 #include <dx/dx.h>
17 #include "groupinterpClass.h"
18
19 GroupInterpolator
_dxfNewGroupInterpolator(Group g,enum interp_init initType,float fuzz,Matrix * m)20 _dxfNewGroupInterpolator(Group g,
21 enum interp_init initType, float fuzz, Matrix *m)
22 {
23 return _dxf_NewGroupInterpolator(g, initType, fuzz, m,
24 &_dxdgroupinterpolator_class);
25 }
26
27 GroupInterpolator
_dxf_NewGroupInterpolator(Group g,enum interp_init initType,float fuzz,Matrix * m,struct groupinterpolator_class * class)28 _dxf_NewGroupInterpolator(Group g,
29 enum interp_init initType, float fuzz, Matrix *m,
30 struct groupinterpolator_class *class)
31 {
32 GroupInterpolator gi;
33 int i, j;
34 Object child;
35 Interpolator *subPtr, sub, firstsub = NULL;
36 int isMultigrid;
37
38 CHECK(g, CLASS_GROUP);
39
40 gi=(GroupInterpolator)
41 _dxf_NewInterpolator((struct interpolator_class *)class, (Object)g);
42 if (!gi)
43 return NULL;
44
45 isMultigrid = DXGetGroupClass(g) == CLASS_MULTIGRID;
46
47 /*
48 * Create array of pointers to interpolators for each descendent
49 * of the current group. First, how many descendents?
50 */
51 for (i = 0; NULL != (child = DXGetEnumeratedMember(g, i, NULL)); i++);
52
53 gi->subInterp = (Interpolator *)DXAllocate(i*sizeof(Interpolator *));
54 if (!gi->subInterp)
55 {
56 DXFree((Pointer)gi);
57 return NULL;
58 }
59
60 /*
61 * Create interpolators for each. Collect a group bound box
62 * as we do so.
63 */
64 subPtr = gi->subInterp;
65 gi->nMembers = 0;
66 for (i = 0; NULL != (child = DXGetEnumeratedMember(g, i, NULL)); i++)
67 {
68 /*
69 * Ignore fields that have no elements
70 */
71 if (DXGetObjectClass(child) == CLASS_FIELD)
72 {
73 Array array;
74 int nElements;
75
76 if (DXEmptyField((Field)child))
77 continue;
78
79 array = (Array)DXGetComponentValue((Field)child, "connections");
80 if (! array)
81 continue;
82
83 DXGetArrayInfo(array, &nElements, NULL, NULL, NULL, NULL);
84 if (nElements == 0)
85 continue;
86 }
87
88 sub = (Interpolator)_dxfNewInterpolatorSwitch(child,
89 initType, fuzz, m);
90 if (! sub)
91 {
92 DXDelete((Object)gi);
93 return NULL;
94 }
95
96 *subPtr++ = sub;
97
98 DXReference((Object)sub);
99
100 gi->nMembers ++;
101
102 if (i == 0)
103 {
104 DXGetType(sub->dataObject, &gi->interpolator.type,
105 &gi->interpolator.category,
106 &gi->interpolator.rank,
107 gi->interpolator.shape);
108
109 gi->interpolator.nDim = sub->nDim;
110
111 memcpy((void *)(gi->interpolator.min), (void *)(sub->min),
112 gi->interpolator.nDim*sizeof(float));
113 memcpy((void *)(gi->interpolator.max), (void *)(sub->max),
114 gi->interpolator.nDim*sizeof(float));
115
116 firstsub = sub;
117 }
118 else
119 {
120 for (j = 0; j < gi->interpolator.nDim; j++)
121 {
122 if (sub->min[j] < gi->interpolator.min[j])
123 gi->interpolator.min[j] = sub->min[j];
124 if (sub->max[j] > gi->interpolator.max[j])
125 gi->interpolator.max[j] = sub->max[j];
126 }
127
128 if (! isMultigrid)
129 ((Interpolator)sub)->matrix = ((Interpolator)firstsub)->matrix;
130 }
131 }
132
133 /*
134 * Initially, no hint
135 */
136 gi->hint = NULL;
137
138 return gi;
139 }
140
141 Error
_dxfGroupInterpolator_Delete(GroupInterpolator gi)142 _dxfGroupInterpolator_Delete(GroupInterpolator gi)
143 {
144 int i;
145
146 /*
147 * DXFree interpolator pointed to by hint
148 */
149 if (gi->hint)
150 {
151 DXDelete((Object)gi->hint);
152 gi->hint = NULL;
153 }
154
155 /*
156 * DXFree descendent interpolators
157 */
158 if (gi->subInterp)
159 {
160 for (i = 0; i < gi->nMembers; i++)
161 if (gi->subInterp[i])
162 {
163 DXDelete((Object)gi->subInterp[i]);
164 gi->subInterp[i] = NULL;
165 }
166
167 DXFree((Pointer)gi->subInterp);
168 gi->subInterp = NULL;
169 }
170
171 _dxfInterpolator_Delete((Interpolator)gi);
172
173 return OK;
174 }
175
176 int
_dxfGroupInterpolator_Interpolate(GroupInterpolator gi,int * n,float ** points,Pointer * values,Interpolator * parentHint,int fuzzFlag)177 _dxfGroupInterpolator_Interpolate(GroupInterpolator gi, int *n,
178 float **points, Pointer *values, Interpolator *parentHint, int fuzzFlag)
179 {
180 Interpolator *sub, *subBase, myHint, newHint;
181 int i, nMem, nAtStart;
182
183 myHint = NULL;
184
185 nAtStart = *n;
186
187 /*
188 * Start with the child (possibly distant descendent)
189 * pointed to by the hint.
190 */
191 if (gi->hint)
192 if (! _dxfInterpolate(gi->hint, n, points, values, &myHint, fuzzFlag))
193 return 0;
194
195 /*
196 * Turn off fuzz as soon as a sample succeeds. All subsequent
197 * interpolation attempts will be done sans fuzz.
198 */
199 if (nAtStart > *n)
200 fuzzFlag = FUZZ_OFF;
201
202 /*
203 * As long as poits remain to be interpolated, call descendents
204 * to interpolate them. When a point is encountered that does
205 * not lie in any child field, quit.
206 */
207 nMem = gi->nMembers;
208 subBase = gi->subInterp;
209 while(*n != 0)
210 {
211 newHint = NULL;
212
213 sub = subBase;
214 for (i = 0; i < nMem; i++)
215 {
216 if ((*sub) != gi->hint)
217 if (! _dxfInterpolate((*sub), n, points, values, &newHint, fuzzFlag))
218 return 0;
219
220 /*
221 * Again, turn off fuzz as soon as a sample succeeds. All
222 * subsequent interpolation attempts will be done sans fuzz.
223 */
224 if (nAtStart > *n)
225 fuzzFlag = FUZZ_OFF;
226
227 if (newHint)
228 break;
229
230 sub++;
231 }
232
233 /*
234 * Keep going as long as we have more points to interpolate and
235 * we interpolated some last time through the children.
236 */
237 if (! newHint)
238 break;
239
240 myHint = newHint;
241 }
242
243 /*
244 * If we didn't interpolate any points and there was a hint,
245 * delete the old hint.
246 */
247 if (gi->hint != myHint)
248 {
249 if (gi->hint)
250 DXDelete((Object)(gi->hint));
251
252 if (myHint)
253 gi->hint = (Interpolator)DXReference((Object)(myHint));
254 else
255 gi->hint = NULL;
256 }
257
258 /*
259 * If the parent requested a hint, pass it up.
260 */
261 if (parentHint)
262 *parentHint = myHint;
263
264 return OK;
265 }
266
267 Object
_dxfGroupInterpolator_Copy(GroupInterpolator old,enum _dxd_copy copy)268 _dxfGroupInterpolator_Copy(GroupInterpolator old, enum _dxd_copy copy)
269 {
270 GroupInterpolator new;
271
272 new = (GroupInterpolator)
273 _dxf_NewObject((struct object_class *)&_dxdgroupinterpolator_class);
274
275 return (Object)_dxf_CopyGroupInterpolator(new, old, copy);
276 }
277
278 GroupInterpolator
_dxf_CopyGroupInterpolator(GroupInterpolator new,GroupInterpolator old,enum _dxd_copy copy)279 _dxf_CopyGroupInterpolator(GroupInterpolator new, GroupInterpolator old,
280 enum _dxd_copy copy)
281 {
282 Interpolator *ns, *os;
283 int i;
284
285 if (old == NULL)
286 return NULL;
287
288 if (! _dxf_CopyInterpolator((Interpolator)new, (Interpolator)old))
289 return NULL;
290
291 new->nMembers = old->nMembers;
292
293 new->subInterp = (Interpolator *)
294 DXAllocate(new->nMembers*sizeof(Interpolator));
295
296 if (! new->subInterp)
297 {
298 DXFree((Pointer)new);
299 return NULL;
300 }
301
302 ns = new->subInterp;
303 os = old->subInterp;
304 for (i = 0; i < new->nMembers; i++, os++, ns++)
305 {
306 if (NULL == (*ns = (Interpolator)DXCopy((Object)*os, copy)))
307 {
308 while(i-- > 0)
309 DXDelete((Object)*(--ns));
310 DXFree((Pointer)new->subInterp);
311 DXFree((Pointer)new);
312 return NULL;
313 }
314 DXReference((Object)*ns);
315 }
316
317 new->hint = NULL;
318
319 return new;
320 }
321
322 Interpolator
_dxfGroupInterpolator_LocalizeInterpolator(GroupInterpolator gi)323 _dxfGroupInterpolator_LocalizeInterpolator(GroupInterpolator gi)
324 {
325 int i;
326 Interpolator *childi;
327
328 childi = gi->subInterp;
329 for (i = 0; i < gi->nMembers; i++, childi++)
330 DXLocalizeInterpolator(*childi);
331
332 return (Interpolator)gi;
333 }
334