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