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  */
10 
11 #include <dxconfig.h>
12 
13 
14 /* issues: partitioned grids for base, handling 2D and 3D */
15 /* should do not only data but all components dep positions */
16 /* what about data dep connections? need to do a set type after */
17 /* the work is done */
18 
19 #include <stdio.h>
20 #include <math.h>
21 #if defined(HAVE_STRING_H)
22 #include <string.h>
23 #endif
24 
25 #include <dx/dx.h>
26 #include "_glyph.h"
27 #include "_connectgrids.h"
28 
29 
30 Error
m_Regrid(Object * in,Object * out)31 m_Regrid(Object *in, Object *out)
32 {
33   char *string;
34   Class class;
35   Category category;
36   Object ino=NULL, base=NULL;
37   Array missing=NULL;
38   float radius,  *radius_ptr, exponent;
39   Type type;
40   int numitems, rank, shape[30], numnearest;
41 
42   radius_ptr = &radius;
43 
44   if (!in[0]) {
45     DXSetError(ERROR_BAD_PARAMETER, "#10000","input");
46     return ERROR;
47   }
48 
49   class = DXGetObjectClass(in[0]);
50   if ((class != CLASS_ARRAY)&&
51       (class != CLASS_FIELD)&&
52       (class != CLASS_GROUP)&&
53       (class != CLASS_XFORM)) {
54     DXSetError(ERROR_BAD_PARAMETER, "#10630", "input");
55     return ERROR;
56   }
57 
58 
59   if (!in[1]) {
60      DXSetError(ERROR_BAD_PARAMETER,"#10000", "grid");
61      goto error;
62   }
63 
64   /* now get numnearest, radius, missing, exponent */
65 
66   /* numnearest */
67   if (!in[2]) {
68      numnearest = 1;
69   }
70   else {
71      if (!DXExtractInteger(in[2], &numnearest)) {
72         if (!DXExtractString(in[2], &string)) {
73            DXSetError(ERROR_BAD_PARAMETER, "#10370",
74                       "nearest", "an integer or the string `infinity`");
75            goto error;
76         }
77         /* XXX lower case */
78         if (strcmp(string,"infinity")) {
79            DXSetError(ERROR_BAD_PARAMETER, "#10370",
80                       "nearest", "an integer or the string `infinity`");
81            goto error;
82         }
83         numnearest = -1;
84      }
85      else {
86         if (numnearest <= 0) {
87            DXSetError(ERROR_BAD_PARAMETER,"#10020","nearest");
88            goto error;
89         }
90      }
91   }
92 
93 
94   /* radius */
95   if (!in[3]) {
96      *radius_ptr = -1;
97   }
98   else {
99      if (!DXExtractFloat(in[3], radius_ptr)) {
100         if (!DXExtractString(in[3], &string)) {
101            DXSetError(ERROR_BAD_PARAMETER, "#10370",
102                 "radius", "a positive scalar value or the string `infinity`");
103            goto error;
104         }
105         /* XXX lower case */
106         if (strcmp(string,"infinity")) {
107            DXSetError(ERROR_BAD_PARAMETER, "#10370",
108                 "radius", "a positive scalar value or the string `infinity`");
109            goto error;
110         }
111         *radius_ptr = -1;
112      }
113      else {
114         if (*radius_ptr < 0) {
115            DXSetError(ERROR_BAD_PARAMETER, "#10370",
116                 "radius", "a positive scalar value or the string `infinity`");
117            goto error;
118         }
119         else if (*radius_ptr == 0){
120            DXWarning("Regrid radius set to 0, data values assigned to nearest grid point");
121            numnearest=0;
122         }
123      }
124   }
125 
126 
127 
128   /* now get exponent */
129   if (!in[4]) {
130      exponent = 1;
131   }
132   else {
133      if (!DXExtractFloat(in[4], &exponent)) {
134         DXSetError(ERROR_BAD_PARAMETER,"#10080",
135                    "exponent");
136         goto error;
137      }
138   }
139 
140   /* get missing */
141   if (in[5]) {
142       if (!(DXGetObjectClass(in[5])==CLASS_ARRAY)) {
143 	DXSetError(ERROR_BAD_PARAMETER, "#10261",
144 		   "missing");
145 	goto error;
146       }
147       missing = (Array)in[5];
148   }
149 
150 /*Moved common data prep steps outside of if/else statement --JAB*/
151     class = DXGetObjectClass(in[0]);
152     if (class == CLASS_ARRAY) {
153       if (!DXGetArrayInfo((Array)in[0], &numitems, &type, &category,
154 			  &rank, shape))
155         goto error;
156       if ((type != TYPE_FLOAT)||(rank != 1)) {
157         /* should also handle scalar I guess XXX */
158         DXSetError(ERROR_BAD_PARAMETER,"#10630","input");
159         goto error;
160       }
161       if (shape[0]<1 || shape[0]> 3) {
162         DXSetError(ERROR_BAD_PARAMETER,"#10370",
163                    "input","1-, 2-, or 3-dimensional");
164         goto error;
165       }
166       /* just a list of positions; let's make it a field with positions*/
167       ino = (Object)DXNewField();
168       if (!ino)
169         goto error;
170       if (!DXSetComponentValue((Field)ino,"positions",in[0]))
171         goto error;
172     }
173     else {
174       /* so I can safely delete it at the bottom, as well as modify it */
175       ino = DXCopy(in[0], COPY_STRUCTURE);
176     }
177 
178     /* remove connections */
179     if (DXExists(ino, "connections"))
180      DXRemove(ino,"connections");
181 
182     /* cull */
183     ino = DXCull(ino);
184 
185 
186     /* copy the field with positions and connections; we'll add
187      * data using the given input 0 */
188     base = DXApplyTransform(in[1],NULL);
189 
190     /* copy the attributes of the input scattered points to the output grid*/
191     if (!DXCopyAttributes(base, ino))
192       goto error;
193 
194     if (!DXCreateTaskGroup())
195       goto error;
196 
197     /*Issue warning when base grid with invalid positions is used*/
198     if (DXExists(base, "invalid positions") && missing)
199       DXWarning("Regrid base grid contains invalid positions which are not removed when missing is set");
200 
201 /* if nearest is infinity, we use the "radius" method.
202    if radius is 0, we assign data value to nearest grid point,
203    In all other cases we use the "nearest" method" */
204 
205   if (numnearest == -1) {
206     /* use the "radius" method */
207 
208     if (!_dxfConnectRadiusObject((Object)ino, (Object)base,
209 				 radius, exponent, missing))
210       goto error;
211   }
212   else if (numnearest == 0) {
213     /*assign value to nearest grid point - JAB*/
214 
215     /* remove invalid postions if missing does not exist*/
216     if (DXExists(base, "invalid positions") && !missing)
217      DXRemove(base,"invalid positions");
218 
219     if (!_dxfConnectScatterObject((Object)ino, (Object)base, missing))
220       goto error;
221   }
222   else {
223     /* use the "nearest" method */
224     /* if radius was infinity... */
225     if (*radius_ptr==-1)
226        radius_ptr = NULL;
227     if (!_dxfConnectNearestObject(ino, base, numnearest, radius_ptr,
228 			          exponent, missing))
229       goto error;
230 
231   }
232 
233   if (!DXExecuteTaskGroup())
234     goto error;
235 
236   DXDelete((Object)ino);
237   out[0] = base;
238 
239   return OK;
240 
241  error:
242   DXDelete((Object)ino);
243   DXDelete((Object)base);
244   return ERROR;
245 
246 }
247