source: trunk/packages/vizservers/nanovis/Unirect.cpp @ 1469

Last change on this file since 1469 was 1469, checked in by gah, 15 years ago

change unirect?d parsing for flows to not call Tcl command

File size: 22.0 KB
RevLine 
[1365]1
[1429]2#include <float.h>
[1365]3#include <tcl.h>
4#include <Unirect.h>
[1429]5#include "RpField1D.h"
6#include "RpFieldRect3D.h"
[1462]7#include "Trace.h"
[1365]8
9extern int GetFloatFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr,
10        float *valuePtr);
11extern int GetAxisFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr, int *indexPtr);
12
[1429]13static INLINE char *
14skipspaces(char *string)
15{
16    while (isspace(*string)) {
17        string++;
18    }
19    return string;
20}
21
22static INLINE char *
23getline(char **stringPtr, char *endPtr)
24{
25    char *line, *p;
26
27    line = skipspaces(*stringPtr);
28    for (p = line; p < endPtr; p++) {
29        if (*p == '\n') {
30            *p++ = '\0';
31            *stringPtr = p;
32            return line;
33        }
34    }
35    *stringPtr = p;
36    return line;
37}
38
[1469]39int
40Rappture::Unirect2d::ParseBuffer(Tcl_Interp *interp, Rappture::Buffer &buf)
41{
42    Tcl_Obj *objPtr;
43    objPtr = Tcl_NewStringObj(buf.bytes(), buf.size());
44    Tcl_Obj **objv;
45    int objc;
46    if (Tcl_ListObjGetElements(interp, objPtr, &objc, &objv) != TCL_OK) {
47        return NULL;
48    }
49    int result;
50    result = LoadData(interp, objc, objv);
51    Tcl_DecrRefCount(objPtr);
52    if ((result != TCL_OK) || (!isInitialized())) {
53        return TCL_ERROR;
54    }
55    return TCL_OK;
56}
57
58int
59Rappture::Unirect3d::ParseBuffer(Tcl_Interp *interp, Rappture::Buffer &buf)
60{
61    Tcl_Obj *objPtr;
62    objPtr = Tcl_NewStringObj(buf.bytes(), buf.size());
63    Tcl_Obj **objv;
64    int objc;
65    if (Tcl_ListObjGetElements(interp, objPtr, &objc, &objv) != TCL_OK) {
66        return NULL;
67    }
68    int result;
69    result = LoadData(interp, objc, objv);
70    Tcl_DecrRefCount(objPtr);
71    if ((result != TCL_OK) || (!isInitialized())) {
72        return TCL_ERROR;
73    }
74    return TCL_OK;
75}
76
[1365]77int
78Rappture::Unirect3d::LoadData(Tcl_Interp *interp, int objc,
79                              Tcl_Obj *const *objv)
80{
81    int num[3], nValues;
82    float min[3], max[3];
83    float *values;
84    const char *units[4], *order;
85
86
87    if ((objc & 0x01) == 0) {
88        Tcl_AppendResult(interp, Tcl_GetString(objv[0]), ": ",
[1462]89                "wrong # of arguments: should be key-value pairs",
[1365]90                (char *)NULL);
91        return TCL_ERROR;
92    }
93
94    /* Default order is  z, y, x. */
95    int axis1, axis2, axis3;
[1453]96    axis1 = 0;                  /* X-axis */
[1365]97    axis2 = 1;                  /* Y-axis */
[1453]98    axis3 = 2;                  /* Z-axis */
[1365]99
100    values = NULL;
101    num[0] = num[1] = num[2] = nValues = 0;
102    min[0] = min[1] = min[2] = max[0] = max[1] = max[2] = 0.0f;
103    order = units[0] = units[1] = units[2] = units[3] = NULL;
104
105    int i;
106    for (i = 1; i < objc; i += 2) {
107        const char *string;
108        char c;
109
110        string = Tcl_GetString(objv[i]);
111        c = string[0];
112        if ((c == 'x') && (strcmp(string, "xmin") == 0)) {
113            if (GetFloatFromObj(interp, objv[i+1], min+2) != TCL_OK) {
114                return TCL_ERROR;
115            }
116        } else if ((c == 'x') && (strcmp(string, "xmax") == 0)) {
117            if (GetFloatFromObj(interp, objv[i+1], max+2) != TCL_OK) {
118                return TCL_ERROR;
119            }
120        } else if ((c == 'x') && (strcmp(string, "xnum") == 0)) {
121            if (Tcl_GetIntFromObj(interp, objv[i+1], num+2) != TCL_OK) {
122                return TCL_ERROR;
123            }
124            if (num[2] <= 0) {
125                Tcl_AppendResult(interp, "bad xnum value: must be > 0",
126                     (char *)NULL);
127                return TCL_ERROR;
128            }
129        } else if ((c == 'x') && (strcmp(string, "xunits") == 0)) {
130            units[2] = Tcl_GetString(objv[i+1]);
131        } else if ((c == 'y') && (strcmp(string, "ymin") == 0)) {
132            if (GetFloatFromObj(interp, objv[i+1], min+1) != TCL_OK) {
133                return TCL_ERROR;
134            }
135        } else if ((c == 'y') && (strcmp(string, "ymax") == 0)) {
136            if (GetFloatFromObj(interp, objv[i+1], max+1) != TCL_OK) {
137                return TCL_ERROR;
138            }
139        } else if ((c == 'y') && (strcmp(string, "ynum") == 0)) {
140            if (Tcl_GetIntFromObj(interp, objv[i+1], num+1) != TCL_OK) {
141                return TCL_ERROR;
142            }
143            if (num[1] <= 0) {
144                Tcl_AppendResult(interp, "bad ynum value: must be > 0",
145                                 (char *)NULL);
146                return TCL_ERROR;
147            }
148        } else if ((c == 'y') && (strcmp(string, "yunits") == 0)) {
149            units[1] = Tcl_GetString(objv[i+1]);
150        } else if ((c == 'z') && (strcmp(string, "zmin") == 0)) {
151            if (GetFloatFromObj(interp, objv[i+1], min) != TCL_OK) {
152                return TCL_ERROR;
153            }
154        } else if ((c == 'z') && (strcmp(string, "zmax") == 0)) {
155            if (GetFloatFromObj(interp, objv[i+1], max) != TCL_OK) {
156                return TCL_ERROR;
157            }
158        } else if ((c == 'z') && (strcmp(string, "znum") == 0)) {
159            if (Tcl_GetIntFromObj(interp, objv[i+1], num) != TCL_OK) {
160                return TCL_ERROR;
161            }
162            if (num[0] <= 0) {
163                Tcl_AppendResult(interp, "bad znum value: must be > 0",
164                                 (char *)NULL);
165                return TCL_ERROR;
166            }
167        } else if ((c == 'z') && (strcmp(string, "zunits") == 0)) {
168            units[0] = Tcl_GetString(objv[i+1]);
169        } else if ((c == 'v') && (strcmp(string, "values") == 0)) {
170            Tcl_Obj **vobj;
171
172            if (Tcl_ListObjGetElements(interp, objv[i+1], &nValues, &vobj)
173                != TCL_OK) {
174                return TCL_ERROR;
175            }
176            values = new float[nValues];
177            int j;
178            for (j = 0; j < nValues; j++) {
179                if (GetFloatFromObj(interp, vobj[j], values + j)!=TCL_OK) {
180                    return TCL_ERROR;
181                }
182            }
183        } else if ((c == 'u') && (strcmp(string, "units") == 0)) {
[1429]184            _vUnits = strdup(Tcl_GetString(objv[i+1]));
[1447]185        } else if ((c == 'c') && (strcmp(string, "components") == 0)) {
186            int n;
187
188            if (Tcl_GetIntFromObj(interp, objv[i+1], &n) != TCL_OK) {
189                return TCL_ERROR;
190            }
191            if (n <= 0) {
192                Tcl_AppendResult(interp, "bad extents value: must be > 0",
193                                 (char *)NULL);
194                return TCL_ERROR;
195            }
196            _nComponents = n;
197        } else if ((c == 'a') && (strcmp(string, "axisorder") == 0)) {
[1365]198            Tcl_Obj **axes;
199            int n;
200
201            if (Tcl_ListObjGetElements(interp, objv[i+1], &n, &axes)
202                != TCL_OK) {
203                return TCL_ERROR;
204            }
205            if (n != 3) {
206                return TCL_ERROR;
207            }
208            if ((GetAxisFromObj(interp, axes[0], &axis1) != TCL_OK) ||
209                (GetAxisFromObj(interp, axes[1], &axis2) != TCL_OK) ||
210                (GetAxisFromObj(interp, axes[2], &axis3) != TCL_OK)) {
211                return TCL_ERROR;
212            }
213        } else {
214            Tcl_AppendResult(interp, "unknown key \"", string,
215                (char *)NULL);
216            return TCL_ERROR;
217        }
218    }
219    if (values == NULL) {
220        Tcl_AppendResult(interp, "missing \"values\" key", (char *)NULL);
221        return TCL_ERROR;
222    }
[1429]223    if ((size_t)nValues != (num[0] * num[1] * num[2] * _nComponents)) {
[1462]224        Trace("num[0]=%d num[1]=%d num[2]=%d ncomponents=%d nValues=%d\n",
225              num[0], num[1], num[2], _nComponents, nValues);
[1365]226        Tcl_AppendResult(interp,
[1462]227                "wrong # of values: must be xnum*ynum*znum*extents",
[1365]228                         (char *)NULL);
[1453]229       return TCL_ERROR;
[1365]230    }
231   
[1453]232#ifdef notdef
233    if ((axis1 != 0) || (axis2 != 1) || (axis3 != 2)) {
[1365]234        // Reorder the data into x, y, z where x varies fastest and so on.
235        int z;
236        float *data, *dp;
237
238        dp = data = new float[nValues];
239        for (z = 0; z < num[0]; z++) {
240            int y;
241
242            for (y = 0; y < num[1]; y++) {
243                int x;
244
245                for (x = 0; x < num[2]; x++) {
[1429]246                    int i;
[1365]247                   
248                    /* Compute the index from the data's described ordering. */
249                    i = ((z*num[axis2]*num[axis3]) + (y*num[axis3]) + x) * 3;
[1429]250                    for(size_t v = 0; v < _nComponents; v++) {
[1365]251                        dp[v] = values[i+v];
252                    }
[1429]253                    dp += _nComponents;
[1365]254                }
255            }
256        }
257        delete [] values;
258        values = data;
259    }
[1453]260#endif
[1429]261    _values = values;
262    _nValues = nValues;
[1365]263    if (units[3] != NULL) {
[1429]264        _vUnits = strdup(units[3]);
[1365]265    }
[1429]266    _xMin = min[axis3];
267    _xMax = max[axis3];
268    _xNum = num[axis3];
[1365]269    if (units[axis3] != NULL) {
[1429]270        _xUnits = strdup(units[axis3]);
[1365]271    }
[1429]272    _yMin = min[axis2];
273    _yMax = max[axis2];
274    _yNum = num[axis2];
[1365]275    if (units[axis2] != NULL) {
[1429]276        _yUnits = strdup(units[axis2]);
[1365]277    }
[1429]278    _zMin = min[axis1];
279    _zMax = max[axis1];
280    _zNum = num[axis1];
[1365]281    if (units[axis1] != NULL) {
[1429]282        _zUnits = strdup(units[axis1]);
[1365]283    }
[1429]284    _initialized = true;
[1458]285#ifdef notdef
[1453]286    {
287        FILE *f;
288        f = fopen("/tmp/unirect3d.txt", "w");
289        fprintf(f, "unirect3d xmin %g xmax %g xnum %d ", _xMin, _xMax, _xNum);
290        fprintf(f, "ymin %g ymax %g ynum %d ", _yMin, _yMax, _yNum);
291        fprintf(f, "zmin %g zmax %g znum %d ", _zMin, _zMax, _zNum);
292        fprintf(f, "components %d values {\n",  _nComponents);
293        for (size_t i = 0; i < _nValues; i+= 3) {
294            fprintf(f, "%g %g %g\n", _values[i], _values[i+1], _values[i+2]);
295        }
296        fprintf(f, "}\n");
297        fclose(f);
298    }
[1458]299#endif
[1365]300    return TCL_OK;
301}
302
303
304int
305Rappture::Unirect2d::LoadData(Tcl_Interp *interp, int objc,
306                              Tcl_Obj *const *objv)
307{
308
309    if ((objc & 0x01) == 0) {
310        Tcl_AppendResult(interp, Tcl_GetString(objv[0]), ": ",
311                "wrong number of arguments: should be key-value pairs",
312                (char *)NULL);
313        return TCL_ERROR;
314    }
315
316    int axis[2];
317    axis[0] = 1;                        /* X-axis */
318    axis[1] = 0;                        /* Y-axis */
319
[1429]320    _xNum = _yNum = _nValues = 0;
321    _xMin = _yMin = _xMax = _yMax = 0.0f;
322    if (_xUnits != NULL) {
323        free(_xUnits);
[1365]324    }
[1429]325    if (_yUnits != NULL) {
326        free(_yUnits);
[1365]327    }
[1429]328    if (_vUnits != NULL) {
329        free(_vUnits);
[1365]330    }
[1429]331    _xUnits = _yUnits = _vUnits = NULL;
332    if (_values != NULL) {
333        delete [] _values;
[1365]334    }
[1429]335    _values = NULL;
[1365]336
337    int i;
338    for (i = 1; i < objc; i += 2) {
339        const char *string;
340        char c;
341
342        string = Tcl_GetString(objv[i]);
343        c = string[0];
344        if ((c == 'x') && (strcmp(string, "xmin") == 0)) {
[1429]345            if (GetFloatFromObj(interp, objv[i+1], &_xMin) != TCL_OK) {
[1365]346                return TCL_ERROR;
347            }
348        } else if ((c == 'x') && (strcmp(string, "xmax") == 0)) {
[1429]349            if (GetFloatFromObj(interp, objv[i+1], &_xMax) != TCL_OK) {
[1365]350                return TCL_ERROR;
351            }
352        } else if ((c == 'x') && (strcmp(string, "xnum") == 0)) {
353            int n;
354            if (Tcl_GetIntFromObj(interp, objv[i+1], &n) != TCL_OK) {
355                return TCL_ERROR;
356            }
357            if (n <= 0) {
358                Tcl_AppendResult(interp, "bad xnum value: must be > 0",
359                     (char *)NULL);
360                return TCL_ERROR;
361            }
[1429]362            _xNum = n;
[1365]363        } else if ((c == 'x') && (strcmp(string, "xunits") == 0)) {
[1429]364            _xUnits = strdup(Tcl_GetString(objv[i+1]));
[1365]365        } else if ((c == 'y') && (strcmp(string, "ymin") == 0)) {
[1429]366            if (GetFloatFromObj(interp, objv[i+1], &_yMin) != TCL_OK) {
[1365]367                return TCL_ERROR;
368            }
369        } else if ((c == 'y') && (strcmp(string, "ymax") == 0)) {
[1429]370            if (GetFloatFromObj(interp, objv[i+1], &_yMax) != TCL_OK) {
[1365]371                return TCL_ERROR;
372            }
373        } else if ((c == 'y') && (strcmp(string, "ynum") == 0)) {
374            int n;
375            if (Tcl_GetIntFromObj(interp, objv[i+1], &n) != TCL_OK) {
376                return TCL_ERROR;
377            }
378            if (n <= 0) {
379                Tcl_AppendResult(interp, "bad ynum value: must be > 0",
380                                 (char *)NULL);
381                return TCL_ERROR;
382            }
[1429]383            _yNum = n;
[1365]384        } else if ((c == 'y') && (strcmp(string, "yunits") == 0)) {
[1429]385            _yUnits = strdup(Tcl_GetString(objv[i+1]));
[1365]386        } else if ((c == 'v') && (strcmp(string, "values") == 0)) {
387            Tcl_Obj **vobj;
388            int n;
389
390            if (Tcl_ListObjGetElements(interp, objv[i+1], &n, &vobj) != TCL_OK){
391                return TCL_ERROR;
392            }
393            if (n <= 0) {
394                Tcl_AppendResult(interp, "empty values list : must be > 0",
395                                 (char *)NULL);
396                return TCL_ERROR;
397            }
[1429]398            _nValues = n;
399            _values = new float[_nValues];
[1365]400            size_t j;
[1429]401            for (j = 0; j < _nValues; j++) {
402                if (GetFloatFromObj(interp, vobj[j], _values + j)!=TCL_OK) {
[1365]403                    return TCL_ERROR;
404                }
405            }
406        } else if ((c == 'u') && (strcmp(string, "units") == 0)) {
[1429]407            _vUnits = strdup(Tcl_GetString(objv[i+1]));
[1447]408        } else if ((c == 'c') && (strcmp(string, "components") == 0)) {
[1365]409            int n;
410
411            if (Tcl_GetIntFromObj(interp, objv[i+1], &n) != TCL_OK) {
412                return TCL_ERROR;
413            }
414            if (n <= 0) {
415                Tcl_AppendResult(interp, "bad extents value: must be > 0",
416                                 (char *)NULL);
417                return TCL_ERROR;
418            }
[1429]419            _nComponents = n;
[1365]420        } else if ((c == 'a') && (strcmp(string, "axisorder") == 0)) {
421            Tcl_Obj **order;
422            int n;
423
424            if (Tcl_ListObjGetElements(interp, objv[i+1], &n, &order)
425                != TCL_OK) {
426                return TCL_ERROR;
427            }
428            if (n != 2) {
429                Tcl_AppendResult(interp,
430                        "wrong # of axes defined for ordering the data",
431                        (char *)NULL);
432                return TCL_ERROR;
433            }
434            if ((GetAxisFromObj(interp, order[0], axis) != TCL_OK) ||
435                (GetAxisFromObj(interp, order[1], axis+1) != TCL_OK)) {
436                return TCL_ERROR;
437            }
438        } else {
439            Tcl_AppendResult(interp, "unknown key \"", string,
440                (char *)NULL);
441            return TCL_ERROR;
442        }
443    }
[1429]444    if (_values == NULL) {
[1365]445        Tcl_AppendResult(interp, "missing \"values\" key", (char *)NULL);
446        return TCL_ERROR;
447    }
[1429]448    if (_nValues != (_xNum * _yNum * _nComponents)) {
[1365]449        Tcl_AppendResult(interp,
[1447]450                "wrong number of values: must be xnum*ynum*components",
[1365]451                         (char *)NULL);
452        return TCL_ERROR;
453    }
454   
455#ifndef notdef
456    if ((axis[0] != 1) || (axis[1] != 0)) {
457        fprintf(stderr, "reordering data\n");
458        // Reorder the data into x, y where x varies fastest and so on.
459        size_t y;
460        float *data, *dp;
461
[1429]462        dp = data = new float[_nValues];
463        for (y = 0; y < _yNum; y++) {
[1365]464            size_t x;
465
[1429]466            for (x = 0; x < _xNum; x++) {
[1365]467                size_t i, v;
468                   
469                /* Compute the index from the data's described ordering. */
[1429]470                i = (y + (_yNum * x)) * _nComponents;
471                for(v = 0; v < _nComponents; v++) {
472                    dp[v] = _values[i+v];
[1365]473                }
[1429]474                dp += _nComponents;
[1365]475            }
476        }
[1429]477        delete [] _values;
478        _values = data;
[1365]479    }
480#endif
[1429]481    _initialized = true;
[1365]482    return TCL_OK;
483}
[1429]484
485
486bool
[1458]487Rappture::Unirect3d::ImportDx(Rappture::Outcome &result, size_t nComponents,
488                              size_t length, char *string)
[1429]489{
[1458]490    int nx, ny, nz, npts;
[1429]491    double x0, y0, z0, dx, dy, dz, ddx, ddy, ddz;
492    char *p, *endPtr;
493
494    dx = dy = dz = 0.0;         // Suppress compiler warning.
495    x0 = y0 = z0 = 0.0;         // May not have an origin line.
496    for (p = string, endPtr = p + length; p < endPtr; /*empty*/) {
497        char *line;
498
499        line = getline(&p, endPtr);
500        if (line == endPtr) {
501            break;
502        }
503        if ((line[0] == '#') || (line == '\0')) {
504            continue;           // Skip blank or comment lines.
505        }
506        if (sscanf(line, "object %*d class gridpositions counts %d %d %d",
507                   &nx, &ny, &nz) == 3) {
508            if ((nx < 0) || (ny < 0) || (nz < 0)) {
509                result.addError("invalid grid size: x=%d, y=%d, z=%d",
510                        nx, ny, nz);
511                return false;
512            }
513        } else if (sscanf(line, "origin %lg %lg %lg", &x0, &y0, &z0) == 3) {
514            // found origin
515        } else if (sscanf(line, "delta %lg %lg %lg", &ddx, &ddy, &ddz) == 3) {
516            // found one of the delta lines
517            if (ddx != 0.0) {
518                dx = ddx;
519            } else if (ddy != 0.0) {
520                dy = ddy;
521            } else if (ddz != 0.0) {
522                dz = ddz;
523            }
524        } else if (sscanf(line, "object %*d class array type %*s shape 3"
525                " rank 1 items %d data follows", &npts) == 1) {
[1458]526            if (npts < 0) {
527                result.addError("bad # points %d", npts);
528                return false;
529            }   
[1429]530            printf("#points=%d\n", npts);
531            if (npts != nx*ny*nz) {
532                result.addError("inconsistent data: expected %d points"
533                                " but found %d points", nx*ny*nz, npts);
534                return false;
535            }
536            break;
537        } else if (sscanf(line, "object %*d class array type %*s rank 0"
538                " times %d data follows", &npts) == 1) {
539            if (npts != nx*ny*nz) {
540                result.addError("inconsistent data: expected %d points"
541                                " but found %d points", nx*ny*nz, npts);
542                return false;
543            }
544            break;
545        }
546    }
547    if (npts != nx*ny*nz) {
548        result.addError("inconsistent data: expected %d points"
549                        " but found %d points", nx*ny*nz, npts);
550        return false;
551    }
552
553    _initialized = false;
554    _xValueMin = _yValueMin = _zValueMin = FLT_MAX;
555    _xValueMax = _yValueMax = _zValueMax = -FLT_MAX;
556    _xMin = x0, _yMin = y0, _zMin = z0;
557    _xNum = nx, _yNum = ny, _zNum = nz;
558    _xMax = _xMin + dx * _xNum;
559    _yMax = _yMin + dy * _yNum;
560    _zMax = _zMin + dz * _zNum;
[1434]561    _nComponents = nComponents;
562
[1429]563    if (_values != NULL) {
564        delete [] _values;
565    }
566    _values = new float[npts * _nComponents];
567    _nValues = 0;
568    for (size_t ix = 0; ix < _xNum; ix++) {
569        for (size_t iy = 0; iy < _yNum; iy++) {
570            for (size_t iz = 0; iz < _zNum; iz++) {
571                char *line;
572                if ((p == endPtr) || (_nValues > (size_t)npts)) {
573                    break;
574                }
575                line = getline(&p, endPtr);
576                if ((line[0] == '#') || (line[0] == '\0')) {
577                    continue;   // Skip blank or comment lines.
578                }
579                double vx, vy, vz;
580                if (sscanf(line, "%lg %lg %lg", &vx, &vy, &vz) == 3) {
581                    int nindex = (iz*nx*ny + iy*nx + ix) * 3;
582                    if (vx < _xValueMin) {
583                        _xValueMin = vx;
584                    } else if (vx > _xValueMax) {
585                        _xValueMax = vx;
586                    }
587                    if (vy < _yValueMin) {
588                        _yValueMin = vy;
589                    } else if (vy > _yValueMax) {
590                        _yValueMax = vy;
591                    }
592                    if (vz < _zValueMin) {
593                        _zValueMin = vz;
594                    } else if (vz > _zValueMax) {
595                        _zValueMax = vz;
596                    }
597                    _values[nindex] = vx;
598                    _values[nindex+1] = vy;
599                    _values[nindex+2] = vz;
600                    _nValues++;
601                }
602            }
603        }
604    }
605    // make sure that we read all of the expected points
[1458]606    if (_nValues != (size_t)npts) {
[1429]607        result.addError("inconsistent data: expected %d points"
608                        " but found %d points", npts, _nValues);
609        delete []  _values;
610        _values = NULL;
611        return false;
612    }
613    _nValues *= _nComponents;
614    _initialized = true;
[1453]615#ifdef notdef
616    {
617        FILE *f;
618        f = fopen("/tmp/dx.txt", "w");
619        fprintf(f, "unirect3d xmin %g xmax %g xnum %d ", _xMin, _xMax, _xNum);
620        fprintf(f, "ymin %g ymax %g ynum %d ", _yMin, _yMax, _yNum);
621        fprintf(f, "zmin %g zmax %g znum %d ", _zMin, _zMax, _zNum);
622        fprintf(f, "components %d values {\n",  _nComponents);
623        for (size_t i = 0; i < _nValues; i+= 3) {
624            fprintf(f, "%g %g %g\n", _values[i], _values[i+1], _values[i+2]);
625        }
626        fprintf(f, "}\n");
627        fclose(f);
[1452]628    }
[1453]629#endif
[1429]630    return true;
631}
632
633
634bool
[1458]635Rappture::Unirect3d::Resample(Rappture::Outcome &result, size_t nSamples)
[1429]636{
637    Rappture::Mesh1D xgrid(_xMin, _xMax, _xNum);
638    Rappture::Mesh1D ygrid(_yMin, _yMax, _yNum);
639    Rappture::Mesh1D zgrid(_zMin, _zMax, _zNum);
640    Rappture::FieldRect3D xfield(xgrid, ygrid, zgrid);
641    Rappture::FieldRect3D yfield(xgrid, ygrid, zgrid);
642    Rappture::FieldRect3D zfield(xgrid, ygrid, zgrid);
643
644    size_t i, j;
645    for (i = 0, j = 0; i < _nValues; i += _nComponents, j++) {
646        double vx, vy, vz;
647
648        vx = _values[i];
649        vy = _values[i+1];
650        vz = _values[i+2];
651       
652        xfield.define(j, vx);
653        yfield.define(j, vy);
654        zfield.define(j, vz);
655    }
656    // Figure out a good mesh spacing
657    double dx, dy, dz;
658    dx = xfield.rangeMax(Rappture::xaxis) - xfield.rangeMin(Rappture::xaxis);
659    dy = xfield.rangeMax(Rappture::yaxis) - xfield.rangeMin(Rappture::yaxis);
660    dz = xfield.rangeMax(Rappture::zaxis) - xfield.rangeMin(Rappture::zaxis);
661
662    double dmin;
663    dmin = pow((dx*dy*dz)/(nSamples*nSamples*nSamples), 0.333);
664   
665    printf("dx:%lf dy:%lf dz:%lf dmin:%lf\n", dx, dy, dz, dmin);
666
667    /* Recompute new number of points for each axis. */
668    _xNum = (size_t)ceil(dx/dmin);
669    _yNum = (size_t)ceil(dy/dmin);
670    _zNum = (size_t)ceil(dz/dmin);
671   
672#ifndef NV40
673    // must be an even power of 2 for older cards
674    _xNum = (int)pow(2.0, ceil(log10((double)_xNum)/log10(2.0)));
675    _yNum = (int)pow(2.0, ceil(log10((double)_yNum)/log10(2.0)));
676    _zNum = (int)pow(2.0, ceil(log10((double)_zNum)/log10(2.0)));
677#endif
678
679    size_t n = _nComponents * _xNum * _yNum * _zNum;
680    float *data = new float[n];
681    memset(data, 0, sizeof(float) * n);
682   
683    // Generate the uniformly sampled rectangle that we need for a volume
684    float *destPtr = data;
685    for (size_t i = 0; i < _zNum; i++) {
686        double z;
687
688        z = _zMin + (i * dmin);
689        for (size_t j = 0; j < _yNum; j++) {
690            double y;
691               
692            y = _yMin + (j * dmin);
693            for (size_t k = 0; k < _xNum; k++) {
694                double x;
695
696                x = _xMin + (k * dmin);
697                destPtr[0] = xfield.value(x, y, z);
698                destPtr[1] = yfield.value(x, y, z);
699                destPtr[2] = zfield.value(x, y, z);
700            }
701        }
702    }
703    delete [] _values;
704    _values = data;
705    _nValues = _xNum * _yNum * _zNum * _nComponents;
706    return true;
707}
708
[1434]709
710void
711Rappture::Unirect3d::GetVectorRange(void)
712{
713    assert(_nComponents == 3);
714    _magMax = -DBL_MAX, _magMin = DBL_MAX;
715    size_t i;
716    for (i = 0; i < _nValues; i += _nComponents) {
717        double vx, vy, vz, vm;
718
719        vx = _values[i];
720        vy = _values[i+1];
721        vz = _values[i+2];
722                   
723        vm = sqrt(vx*vx + vy*vy + vz*vz);
724        if (vm > _magMax) {
725            _magMax = vm;
726        }
727        if (vm < _magMin) {
728            _magMin = vm;
729        }
730    }
731}
[1447]732
733bool
734Rappture::Unirect3d::Convert(Rappture::Unirect2d *dataPtr)
735{
736    _initialized = false;
737
738    _xValueMin = dataPtr->xValueMin();
739    _yValueMin = dataPtr->yValueMin();
740    _zValueMin = 0.0;
741    _xMin = dataPtr->xMin();
742    _yMin = dataPtr->yMin();
743    _zMin = 0.0;
744    _xMax = dataPtr->xMax();
745    _yMax = dataPtr->yMax();
746    _zMax = 0.0;
747    _xNum = dataPtr->xNum();
748    _yNum = dataPtr->yNum();
749    _zNum = 1;
750    switch (dataPtr->nComponents()) {
751    case 1:
752    case 3:
753        if (_values != NULL) {
754            delete [] _values;
755        }
756        _values = new float[dataPtr->nValues()];
757        memcpy(_values, dataPtr->values(), dataPtr->nValues());
758        _nValues = dataPtr->nValues();
759        _nComponents = dataPtr->nComponents();
760        break;
761    case 2:
762        float *values;
763        _nValues = 3 * _xNum * _yNum * _zNum;
764        if (_values != NULL) {
765            delete [] _values;
766        }
767        _values = new float[_nValues];
768        if (_values == NULL) {
769            return false;
770        }
771        values = dataPtr->values();
772        size_t i, j;
773        for(j = i = 0; i < dataPtr->nValues(); i += 2, j+= 3) {
774            _values[j] = values[i];
775            _values[j+1] = values[i+1];
776            _values[j+2] = 0.0f;
777        }           
778        _nComponents = 3;
779        break;
780    }
781    return true;
782}
Note: See TracBrowser for help on using the repository browser.