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 <string.h>
15 #include <dx/dx.h>
16 #include "linesRR1DClass.h"
17
18 static void _dxfCleanup(LinesRR1DInterpolator);
19 static Error _dxfInitializeTask(Pointer);
20 static Error _dxfInitialize(LinesRR1DInterpolator);
21
22 #define DIAGNOSTIC(str) \
23 DXMessage("regular lines interpolator failure: %s", (str))
24
25 int
_dxfRecognizeLinesRR1D(Field field)26 _dxfRecognizeLinesRR1D(Field field)
27 {
28 Array array;
29 int nDim;
30 int status;
31
32 CHECK(field, CLASS_FIELD);
33
34 ELT_TYPECHECK(field, "lines");
35
36 status = OK;
37
38 array = (Array)DXGetComponentValue(field, "positions");
39 if (!array)
40 return ERROR;
41 else
42 {
43 if (!DXQueryGridPositions(array, &nDim, NULL, NULL, NULL))
44 return ERROR;
45
46 if (nDim != 1)
47 return ERROR;
48 }
49
50 array = (Array)DXGetComponentValue(field, "connections");
51 if (!array)
52 return ERROR;
53 else
54 {
55 if (!DXQueryGridConnections(array, &nDim, NULL))
56 return ERROR;
57
58 if (nDim != 1)
59 return ERROR;
60 }
61
62 return status;
63 }
64
65 LinesRR1DInterpolator
_dxfNewLinesRR1DInterpolator(Field field,enum interp_init initType,double fuzz,Matrix * m)66 _dxfNewLinesRR1DInterpolator(Field field,
67 enum interp_init initType, double fuzz, Matrix *m)
68 {
69 return (LinesRR1DInterpolator)_dxf_NewLinesRR1DInterpolator(field,
70 initType, fuzz, m, &_dxdlinesrr1dinterpolator_class);
71 }
72
73 LinesRR1DInterpolator
_dxf_NewLinesRR1DInterpolator(Field field,enum interp_init initType,float fuzz,Matrix * m,struct linesrr1dinterpolator_class * class)74 _dxf_NewLinesRR1DInterpolator(Field field,
75 enum interp_init initType, float fuzz, Matrix *m,
76 struct linesrr1dinterpolator_class *class)
77 {
78 LinesRR1DInterpolator li;
79 float *mm, *MM;
80
81 li = (LinesRR1DInterpolator)_dxf_NewFieldInterpolator(field, fuzz, m,
82 (struct fieldinterpolator_class *)class);
83 if (! li)
84 return NULL;
85
86 mm = ((Interpolator)li)->min;
87 MM = ((Interpolator)li)->max;
88
89 if ((MM[0] - mm[0]) == 0.0)
90 {
91 DXDelete((Object)li);
92 return NULL;
93 }
94
95 li->dataArray = NULL;
96 li->pointsArray = NULL;
97 li->data = NULL;
98
99 if (initType == INTERP_INIT_PARALLEL)
100 {
101 if (! DXAddTask(_dxfInitializeTask, (Pointer)&li, sizeof(li), 1.0))
102 {
103 DXDelete((Object)li);
104 return NULL;
105 }
106 }
107 else if (initType == INTERP_INIT_IMMEDIATE)
108 {
109 if (! _dxfInitialize(li))
110 {
111 DXDelete((Object)li);
112 return NULL;
113 }
114 }
115
116 return li;
117 }
118
119 static Error
_dxfInitialize(LinesRR1DInterpolator li)120 _dxfInitialize(LinesRR1DInterpolator li)
121 {
122 Field field;
123 int nDim;
124 float origin;
125 float delta;
126 Type dataType;
127 Category dataCategory;
128
129 field = (Field)((Interpolator)li)->dataObject;
130
131 /*
132 * De-reference data
133 */
134 li->dataArray = (Array)DXGetComponentValue(field, "data");
135 if (!li->dataArray)
136 {
137 DXSetError(ERROR_MISSING_DATA, "#10240", "data");
138 return ERROR;
139 }
140 DXReference((Object)li->dataArray);
141
142 DXGetArrayInfo(li->dataArray, NULL, &((Interpolator)li)->type,
143 &((Interpolator)li)->category, &((Interpolator)li)->rank,
144 ((Interpolator)li)->shape);
145
146 li->data = DXCreateArrayHandle(li->dataArray);
147 if (! li->data)
148 return ERROR;
149
150 /*
151 * Get the grid.
152 */
153 li->pointsArray = (Array)DXGetComponentValue(field, "positions");
154 if (!li->pointsArray)
155 {
156 DXSetError(ERROR_MISSING_DATA, "#10240", "positions");
157 return ERROR;
158 }
159 DXReference((Object)li->pointsArray);
160
161 /*
162 * get info about data values
163 */
164 DXGetArrayInfo(li->dataArray, NULL, &dataType, &dataCategory, NULL, NULL);
165
166 /*
167 * Don't worry about maintaining shape of input; just determine how
168 * many values to interpolate.
169 */
170 li->nElements = DXGetItemSize(li->dataArray) /
171 DXTypeSize(((Interpolator)li)->type);
172
173 /*
174 * The grid should be regular
175 */
176 DXQueryGridPositions(li->pointsArray, &nDim, &li->count, &origin, &delta);
177
178 li->invDelta = 1.0 / delta;
179 li->origin = origin;
180
181 /*
182 * Figure fuzz as a proportion of primitive lenth
183 */
184 li->fieldInterpolator.fuzz *= delta;
185
186 li->fieldInterpolator.initialized = 1;
187
188 return OK;
189 }
190
191 Error
_dxfLinesRR1DInterpolator_Delete(LinesRR1DInterpolator li)192 _dxfLinesRR1DInterpolator_Delete(LinesRR1DInterpolator li)
193 {
194 _dxfCleanup(li);
195 return _dxfFieldInterpolator_Delete((FieldInterpolator) li);
196 }
197
198 int
_dxfLinesRR1DInterpolator_PrimitiveInterpolate(LinesRR1DInterpolator li,int * n,float ** points,Pointer * values,int fuzzFlag)199 _dxfLinesRR1DInterpolator_PrimitiveInterpolate(LinesRR1DInterpolator li, int *n,
200 float **points, Pointer *values, int fuzzFlag)
201 {
202 float x;
203 int ix;
204 float dx;
205 float xMax, xMin;
206 int ixMax;
207 float org;
208 float iD;
209 float w0, w1;
210 int i;
211 float *p;
212 Pointer v;
213 float fuzz;
214 int dep;
215 int itemSize, typeSize;
216 InvalidComponentHandle icH = ((FieldInterpolator)li)->invCon;
217 ubyte *dbuf;
218 Matrix *xform;
219
220 if (! li->fieldInterpolator.initialized)
221 {
222 if (! _dxfInitialize(li))
223 {
224 _dxfCleanup(li);
225 return 0;
226 }
227
228 li->fieldInterpolator.initialized = 1;
229 }
230
231 dep = li->fieldInterpolator.data_dependency;
232 typeSize = DXTypeSize(((Interpolator)li)->type);
233 itemSize = li->nElements * typeSize;
234
235 /*
236 * De-reference indexing info from interpolator
237 */
238 org = li->origin;
239 iD = li->invDelta;
240
241 /*
242 * De-reference bounding box
243 */
244 xMax = ((Interpolator)li)->max[0];
245 xMin = ((Interpolator)li)->min[0];
246
247 ixMax = li->count - 1;
248
249 fuzz = li->fuzz;
250
251 if (((FieldInterpolator)li)->xflag)
252 xform = &(((FieldInterpolator)li)->xform);
253 else
254 xform = NULL;
255
256 p = *points;
257 v = *values;
258
259 dbuf = (ubyte *)DXAllocate(2*itemSize);
260 if (! dbuf)
261 return 0;
262
263 while (*n > 0)
264 {
265 float xpt;
266
267 if (xform)
268 xpt = (*p)*xform->A[0][0] + xform->b[0];
269 else
270 xpt = *p;
271
272 if (fuzzFlag == FUZZ_ON)
273 {
274 if (xpt < xMin-fuzz || xpt > xMax+fuzz) break;
275 }
276 else
277 {
278 if (xpt < xMin || xpt > xMax) break;
279 }
280
281 x = (xpt - org) * iD;
282
283 #define INTERPOLATE(type, round) \
284 { \
285 type *v0, *v1, *r; \
286 \
287 r = (type *)v; \
288 \
289 v0 = (type *)DXGetArrayEntry(li->data, ix, (Pointer)dbuf); \
290 v1 = (type *)DXGetArrayEntry(li->data, \
291 ix+1, (Pointer)(dbuf+itemSize)); \
292 \
293 for (i = 0; i < li->nElements; i++) \
294 *r++ = w1*(*v1++) + w0*(*v0++) + round; \
295 \
296 v = (Pointer)r; \
297 }
298
299 if (((FieldInterpolator)li)->cstData)
300 {
301 memcpy(v, ((FieldInterpolator)li)->cstData, itemSize);
302 v = (Pointer)(((char *)v) + itemSize);
303 }
304 else if (dep == DATA_POSITIONS_DEPENDENT)
305 {
306 Type dataType;
307
308 ix = x;
309 dx = x - ix;
310 if (ix >= ixMax)
311 {
312 ix = ixMax - 1;
313 dx = 1.0;
314 }
315 else if (ix < 0 || dx < 0.0)
316 {
317 ix = 0;
318 dx = 0.0;
319 }
320
321 w0 = 1.0 - dx;
322 w1 = dx;
323
324 if (icH && DXIsElementInvalid(icH, ix))
325 break;
326
327 if ((dataType = ((Interpolator)li)->type) == TYPE_FLOAT)
328 {
329 INTERPOLATE(float, 0.0);
330 }
331 else if (dataType == TYPE_DOUBLE)
332 {
333 INTERPOLATE(double, 0.0);
334 }
335 else if (dataType == TYPE_INT)
336 {
337 INTERPOLATE(int, 0.5);
338 }
339 else if (dataType == TYPE_SHORT)
340 {
341 INTERPOLATE(short, 0.5);
342 }
343 else if (dataType == TYPE_USHORT)
344 {
345 INTERPOLATE(ushort, 0.5);
346 }
347 else if (dataType == TYPE_UINT)
348 {
349 INTERPOLATE(uint, 0.5);
350 }
351 else if (dataType == TYPE_BYTE)
352 {
353 INTERPOLATE(byte, 0.5);
354 }
355 else if (dataType == TYPE_UBYTE)
356 {
357 INTERPOLATE(ubyte, 0.5);
358 }
359 else
360 {
361 INTERPOLATE(unsigned char, 0.5);
362 }
363 }
364 else
365 {
366 ix = x;
367 if (ix >= ixMax)
368 ix = ixMax - 1;
369 else if (ix < 0)
370 ix = 0;
371
372 if (icH && DXIsElementInvalid(icH, ix))
373 break;
374
375 memcpy(v,
376 DXGetArrayEntry(li->data, ix, (Pointer)dbuf), itemSize);
377 v = ((char *)v) + itemSize;
378 }
379
380 /*
381 * only use fuzz on first point
382 */
383 fuzzFlag = FUZZ_OFF;
384
385 p += 1;
386 (*n)--;
387 }
388
389 DXFree((Pointer)dbuf);
390
391 *points = (float *)p;
392 *values = v;
393
394 return OK;
395 }
396
397 static void
_dxfCleanup(LinesRR1DInterpolator li)398 _dxfCleanup(LinesRR1DInterpolator li)
399 {
400 if (li->data)
401 {
402 DXFreeArrayHandle(li->data);
403 li->data = NULL;
404 }
405
406 if (li->pointsArray)
407 {
408 DXDelete((Object)li->pointsArray);
409 li->pointsArray = NULL;
410 }
411
412 if (li->dataArray)
413 {
414 DXDelete((Object)li->dataArray);
415 li->dataArray = NULL;
416 }
417 }
418
419 Object
_dxfLinesRR1DInterpolator_Copy(LinesRR1DInterpolator old,enum _dxd_copy copy)420 _dxfLinesRR1DInterpolator_Copy(LinesRR1DInterpolator old, enum _dxd_copy copy)
421 {
422 LinesRR1DInterpolator new;
423
424 new = (LinesRR1DInterpolator)
425 _dxf_NewObject((struct object_class *)&_dxdlinesrr1dinterpolator_class);
426
427 if (!(_dxf_CopyLinesRR1DInterpolator(new, old, copy)))
428 {
429 DXDelete((Object)new);
430 return NULL;
431 }
432 else
433 return (Object)new;
434 }
435
436 LinesRR1DInterpolator
_dxf_CopyLinesRR1DInterpolator(LinesRR1DInterpolator new,LinesRR1DInterpolator old,enum _dxd_copy copy)437 _dxf_CopyLinesRR1DInterpolator(LinesRR1DInterpolator new,
438 LinesRR1DInterpolator old, enum _dxd_copy copy)
439 {
440 if (! _dxf_CopyFieldInterpolator((FieldInterpolator)new,
441 (FieldInterpolator)old, copy))
442 return NULL;
443
444 new->origin = old->origin;
445 new->invDelta = old->invDelta;
446 new->nElements = old->nElements;
447 new->count = old->count;
448 new->fuzz = old->fuzz;
449
450 if (old->fieldInterpolator.initialized)
451 {
452 new->pointsArray = (Array)DXReference((Object)old->pointsArray);
453 new->dataArray = (Array)DXReference((Object)old->dataArray);
454 new->data = DXCreateArrayHandle(new->dataArray);
455 }
456
457 if (DXGetError())
458 return NULL;
459 else
460 return new;
461 }
462
463 static Error
_dxfInitializeTask(Pointer p)464 _dxfInitializeTask(Pointer p)
465 {
466 return _dxfInitialize(*(LinesRR1DInterpolator *)p);
467 }
468
469 Interpolator
_dxfLinesRR1DInterpolator_LocalizeInterpolator(LinesRR1DInterpolator li)470 _dxfLinesRR1DInterpolator_LocalizeInterpolator(LinesRR1DInterpolator li)
471 {
472 if (li->fieldInterpolator.localized)
473 return (Interpolator)li;
474
475 li->fieldInterpolator.localized = 1;
476
477 return (Interpolator)li;
478 }
479