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

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