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 "fieldinterpClass.h"
18 
19 typedef int          	  (*PFI)();
20 typedef FieldInterpolator (*PFFI)();
21 
22 int	_dxfRecognizeTetras(Field);
23 PFFI	_dxfNewTetrasInterpolator(Field, enum interp_init, double, Matrix *);
24 
25 int	_dxfRecognizeLinesII1D(Field);
26 PFFI	_dxfNewLinesII1DInterpolator(Field, enum interp_init, double, Matrix *);
27 
28 int	_dxfRecognizeLinesRR1D(Field);
29 PFFI	_dxfNewLinesRR1DInterpolator(Field, enum interp_init, double, Matrix *);
30 
31 int	_dxfRecognizeTrisRI2D(Field);
32 PFFI	_dxfNewTrisRI2DInterpolator(Field, enum interp_init, double, Matrix *);
33 
34 int	_dxfRecognizeQuadsRR2D(Field);
35 PFFI	_dxfNewQuadsRR2DInterpolator(Field, enum interp_init, double, Matrix *);
36 
37 int	_dxfRecognizeQuadsII2D(Field);
38 PFFI	_dxfNewQuadsII2DInterpolator(Field, enum interp_init, double, Matrix *);
39 
40 int	_dxfRecognizeCubesII(Field);
41 PFFI	_dxfNewCubesIIInterpolator(Field, enum interp_init, double, Matrix *);
42 
43 int     _dxfRecognizeLinesRI1D(Field);
44 PFFI    _dxfNewLinesRI1DInterpolator(Field, enum interp_init, double, Matrix *);
45 
46 int	_dxfRecognizeCubesRR(Field);
47 PFFI	_dxfNewCubesRRInterpolator(Field, enum interp_init, double, Matrix *);
48 
49 int	_dxfRecognizeFLE2D(Field);
50 PFFI	_dxfNewFle2DInterpolator(Field, enum interp_init, double, Matrix *);
51 
52 static struct subClass
53 {
54     PFI		recognizeMth;
55     PFFI	newMth;
56 } _dxdsubClasses[] =
57     {
58 	{ _dxfRecognizeTetras,    (PFFI)_dxfNewTetrasInterpolator    },
59 	{ _dxfRecognizeLinesRR1D, (PFFI)_dxfNewLinesRR1DInterpolator },
60 	{ _dxfRecognizeLinesRI1D, (PFFI)_dxfNewLinesRI1DInterpolator },
61 	{ _dxfRecognizeLinesII1D, (PFFI)_dxfNewLinesII1DInterpolator },
62 	{ _dxfRecognizeTrisRI2D,  (PFFI)_dxfNewTrisRI2DInterpolator  },
63 	{ _dxfRecognizeQuadsRR2D, (PFFI)_dxfNewQuadsRR2DInterpolator },
64 	{ _dxfRecognizeQuadsII2D, (PFFI)_dxfNewQuadsII2DInterpolator },
65 	{ _dxfRecognizeCubesRR,   (PFFI)_dxfNewCubesRRInterpolator   },
66 	{ _dxfRecognizeCubesII,   (PFFI)_dxfNewCubesIIInterpolator   },
67 	{ _dxfRecognizeFLE2D,     (PFFI)_dxfNewFle2DInterpolator     },
68 	{ NULL,		          NULL		   	             }
69     };
70 
71 FieldInterpolator
_dxfSelectFieldInterpolator(Field f,enum interp_init initType,float fuzz,Matrix * m)72 _dxfSelectFieldInterpolator(Field f,
73 		enum interp_init initType, float fuzz, Matrix *m)
74 {
75     FieldInterpolator	fi;
76     struct subClass 	*sub;
77 
78     /*
79      * If the field is empty of positions and/or connections,
80      * return an empty interpolator
81      */
82     if (DXEmptyField(f))
83         goto emptyInterpolator;
84 
85     for (sub = _dxdsubClasses; sub->recognizeMth != NULL; sub++)
86     {
87 	if (sub->recognizeMth(f))
88 	    break;
89 
90 	if (DXGetError() != ERROR_NONE)
91 	    break;
92     }
93 
94     if (!sub->recognizeMth || DXGetError() != ERROR_NONE)
95     {
96 	if (DXGetError() == ERROR_NONE)
97 	    DXSetError(ERROR_DATA_INVALID,  "#11850");
98 	return NULL;
99     }
100 
101     fi = (*(sub->newMth))(f, initType, (double)fuzz, m);
102     if (!fi)
103 	return NULL;
104 
105     return fi;
106 
107 emptyInterpolator:
108 
109     fi = _dxf_NewFieldInterpolator(f, fuzz, m, &_dxdfieldinterpolator_class);
110 
111     return fi;
112 }
113 
114 FieldInterpolator
_dxf_NewFieldInterpolator(Field f,float fuzz,Matrix * m,struct fieldinterpolator_class * class)115 _dxf_NewFieldInterpolator(Field f, float fuzz, Matrix *m,
116 			    struct fieldinterpolator_class *class)
117 {
118     FieldInterpolator fi;
119     Array	      boxArray, dArray;
120     float	      *boxPts, *boxPt;
121     int		      i, nDim, nItems;
122     Object	      attr;
123     char	      *str;
124 
125     fi = (FieldInterpolator)_dxf_NewInterpolator
126 		((struct interpolator_class *)class, (Object)f);
127 
128     if (! fi)
129 	return NULL;
130 
131     fi->initialized = 0;
132     fi->localized   = 0;
133     fi->fuzz 	    = fuzz;
134 
135     if (m)
136     {
137 	fi->xform = DXInvert(*m);
138 	fi->xflag = 1;
139     }
140     else
141 	fi->xflag = 0;
142 
143     for (i = 0; i < MAX_DIM; i++)
144     {
145 	fi->interpolator.min[i] =  DXD_MAX_FLOAT;
146 	fi->interpolator.max[i] = -DXD_MAX_FLOAT;
147     }
148 
149     if (DXBoundingBox((Object) f, NULL))
150     {
151 	boxArray = (Array)DXGetComponentValue(f, "box");
152 
153 	boxPts = (float *)DXGetArrayData(boxArray);
154 
155 	DXGetArrayInfo(boxArray, &nItems, NULL, NULL, NULL, &nDim);
156 
157 	fi->interpolator.nDim = nDim;
158 
159 	boxPt = boxPts;
160 	while (nItems-- > 0)
161 	{
162 	    for (i = 0; i < nDim; i++)
163 	    {
164 		if (*boxPt > fi->interpolator.max[i])
165 		    fi->interpolator.max[i] = *boxPt;
166 		if (*boxPt < fi->interpolator.min[i])
167 		    fi->interpolator.min[i] = *boxPt;
168 		boxPt ++;
169 	    }
170 
171 	}
172     }
173     else if (DXGetError() != ERROR_NONE)
174     {
175 	DXFree((Pointer)fi);
176 	return NULL;
177     }
178     else
179 	fi->interpolator.nDim = 0;
180 
181     if (NULL == (dArray = (Array)DXGetComponentValue(f, "data")))
182     {
183 	DXSetError(ERROR_MISSING_DATA, "#10250", "map", "data");
184 	return NULL;
185     }
186 
187     if (DXQueryConstantArray(dArray, NULL, NULL))
188 	fi->cstData = DXGetConstantArrayData(dArray);
189     else
190 	fi->cstData = NULL;
191 
192     /*
193      * Check dependency of connections array
194      */
195     if ((attr = DXGetComponentAttribute(f, "data", "dep")) == NULL)
196     {
197 	DXSetError(ERROR_MISSING_DATA, "#10241", "map");
198 	return NULL;
199     }
200 
201     if (DXGetObjectClass(attr) != CLASS_STRING)
202     {
203 	DXSetError(ERROR_MISSING_DATA, "#11080", "dependency attribute");
204 	return NULL;
205     }
206 
207     str = DXGetString((String)attr);
208 
209     if (! strcmp(str, "positions"))
210 	fi->data_dependency = DATA_POSITIONS_DEPENDENT;
211     else if (! strcmp(str, "connections"))
212 	fi->data_dependency = DATA_CONNECTIONS_DEPENDENT;
213     else if (! strcmp(str, "faces"))
214 	fi->data_dependency = DATA_FACES_DEPENDENT;
215     else
216     {
217 	DXSetError(ERROR_DATA_INVALID, "#10250", "data");
218 	DXFree((Pointer)fi);
219 	return NULL;
220     }
221 
222     if (! DXInvalidateConnections((Object)f))
223     {
224 	DXFree((Pointer)fi);
225 	return NULL;
226     }
227 
228     if (DXGetComponentValue(f, "connections"))
229     {
230 	fi->invCon = DXCreateInvalidComponentHandle((Object)f, NULL, "connections");
231 	if (! fi->invCon)
232 	{
233 	    DXFree((Pointer)fi);
234 	    return NULL;
235 	}
236 
237 	if (DXGetInvalidCount(fi->invCon) == 0)
238 	{
239 	    DXFreeInvalidComponentHandle(fi->invCon);
240 	    fi->invCon = NULL;
241 	}
242     }
243 
244     return fi;
245 }
246 
_dxfFieldInterpolator_Delete(FieldInterpolator fi)247 Error _dxfFieldInterpolator_Delete(FieldInterpolator fi)
248 {
249     if (fi->invCon)
250 	DXFreeInvalidComponentHandle(fi->invCon);
251     return _dxfInterpolator_Delete((Interpolator) fi);
252 }
253 
254 int
_dxfFieldInterpolator_Interpolate(FieldInterpolator fi,int * n,float ** points,Pointer * values,Interpolator * hint,int fuzzFlag)255 _dxfFieldInterpolator_Interpolate(FieldInterpolator fi, int *n,
256 	    float **points, Pointer *values, Interpolator *hint, int fuzzFlag)
257 {
258     int i, j;
259     int nStart;
260     float *p, xpoints[MAX_DIM];
261 
262     CHECK(fi, CLASS_INTERPOLATOR);
263 
264     if (hint)
265 	*hint = NULL;
266 
267     if (fi->xflag)
268     {
269 	p = xpoints;
270 	for (i = 0; i < fi->interpolator.nDim; i++)
271 	{
272 	    p[i] = fi->xform.b[i];
273 
274 	    for (j = 0; j < fi->interpolator.nDim; j++)
275 		p[i] += (*points)[j]*fi->xform.A[j][i];
276 	}
277     }
278     else
279 	p = *points;
280 
281     if (fuzzFlag == FUZZ_ON)
282 	for (i = 0; i < fi->interpolator.nDim; i++)
283 	{
284 	    if (fi->interpolator.min[i]-fi->fuzz > p[i]) return OK;
285 	    if (fi->interpolator.max[i]+fi->fuzz < p[i]) return OK;
286 	}
287     else
288 	for (i = 0; i < fi->interpolator.nDim; i++)
289 	{
290 	    if (fi->interpolator.min[i] > p[i]) return OK;
291 	    if (fi->interpolator.max[i] < p[i]) return OK;
292 	}
293 
294     /*
295      * Set hint ONLY if we interpolated some points
296      */
297 
298     nStart = *n;
299 
300     if (! _dxfPrimitiveInterpolate(fi, n, points, values, fuzzFlag))
301 	return ERROR;
302 
303     if (hint && nStart != *n)
304 	*hint = (Interpolator)fi;
305 
306     return OK;
307 }
308 
309 FieldInterpolator
_dxf_CopyFieldInterpolator(FieldInterpolator new,FieldInterpolator old,enum _dxd_copy copy)310 _dxf_CopyFieldInterpolator(FieldInterpolator new,
311 				FieldInterpolator old, enum _dxd_copy copy)
312 {
313     if (! _dxf_CopyInterpolator((Interpolator)new, (Interpolator)old))
314 	return NULL;
315 
316     new->localized          = old->localized;
317     new->initialized        = old->initialized;
318     new->fuzz 	            = old->fuzz;
319     new->data_dependency    = old->data_dependency;
320     new->cstData            = old->cstData;
321 
322     if (old->invCon)
323 	new->invCon = DXCreateInvalidComponentHandle
324 		((new->interpolator.dataObject), NULL, "connections");
325     else
326 	new->invCon = NULL;
327 
328     return new;
329 }
330 
331 
332