source: trunk/gui/src/RpConvertDxToVtk.c @ 3177

Last change on this file since 3177 was 3177, checked in by mmc, 12 years ago

Updated all of the copyright notices to reference the transfer to
the new HUBzero Foundation, LLC.

File size: 7.9 KB
Line 
1
2/*
3 * ----------------------------------------------------------------------
4 *  RpConvertDxToVtk -
5 *
6 * ======================================================================
7 *  AUTHOR:  Michael McLennan, Purdue University
8 *  Copyright (c) 2004-2012  HUBzero Foundation, LLC
9 *
10 *  See the file "license.terms" for information on usage and
11 *  redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES.
12 * ======================================================================
13 */
14#include <string.h>
15#include <stdlib.h>
16#include <ctype.h>
17#include <math.h>
18#include <limits.h>
19#include <float.h>
20#include "tcl.h"
21
22static INLINE char *
23SkipSpaces(char *string)
24{
25    while (isspace(*string)) {
26        string++;
27    }
28    return string;
29}
30
31static INLINE char *
32GetLine(char **stringPtr, const char *endPtr)
33{
34    char *line, *p;
35
36    line = SkipSpaces(*stringPtr);
37    for (p = line; p < endPtr; p++) {
38        if (*p == '\n') {
39            *stringPtr = p + 1;
40            return line;
41        }
42    }
43    *stringPtr = p;
44    return line;
45}
46
47static int
48GetPoints(Tcl_Interp *interp, int nPoints, int *counts, char **stringPtr,
49          const char *endPtr, Tcl_Obj *objPtr)
50{
51    int nValues;
52    int i;
53    const char *p;
54    char mesg[2000];
55    float *array, scale, vmin, vmax;
56    int iX, iY, iZ;
57
58    nValues = 0;
59    p = *stringPtr;
60    array = malloc(sizeof(float) * nPoints);
61    if (array == NULL) {
62        return TCL_ERROR;
63    }
64    vmin = FLT_MAX, vmax = -FLT_MAX;
65    iX = iY = iZ = 0;
66    for (i = 0; i < nPoints; i++) {
67        double value;
68        char *nextPtr;
69        int loc;
70
71        if (p >= endPtr) {
72            Tcl_AppendResult(interp, "unexpected EOF in reading points",
73                             (char *)NULL);
74            return TCL_ERROR;
75        }
76        value = strtod(p, &nextPtr);
77        if (nextPtr == p) {
78            Tcl_AppendResult(interp, "bad value found in reading points",
79                             (char *)NULL);
80            return TCL_ERROR;
81        }
82        p = nextPtr;
83        loc = iZ*counts[0]*counts[1] + iY*counts[0] + iX;
84        if (++iZ >= counts[2]) {
85            iZ = 0;
86            if (++iY >= counts[1]) {
87                iY = 0;
88                ++iX;
89            }
90        }
91        array[loc] = value;
92        if (value < vmin) {
93            vmin = value;
94        }
95        if (value > vmax) {
96            vmax = value;
97        }
98    }
99    scale = 1.0 / (vmax - vmin);
100    for (i = 0; i < nPoints; i++) {
101#ifdef notdef
102        sprintf(mesg, "%g\n", (array[i] - vmin) * scale);
103#endif
104        sprintf(mesg, "%g\n", array[i]);
105        Tcl_AppendToObj(objPtr, mesg, -1);
106    }
107    free(array);
108    *stringPtr = p;
109    return TCL_OK;
110}
111
112/*
113 *  ConvertDxToVtk string
114 */
115
116static int
117ConvertDxToVtkCmd(ClientData clientData, Tcl_Interp *interp, int objc,
118                  Tcl_Obj *const *objv)
119{
120    Tcl_Obj *objPtr, *pointsObjPtr;
121    char *p, *pend;
122    char *string;
123    char mesg[2000];
124    double delta[3];
125    double origin[3];
126    int count[3];
127    int length, nComponents, nValues, nPoints;
128    char *name;
129
130    name = "myScalars";
131    nComponents = nPoints = 0;
132    delta[0] = delta[1] = delta[2] = 0.0; /* Suppress compiler warning. */
133    origin[0] = origin[1] = origin[2] = 0.0; /* May not have an origin line. */
134    count[0] = count[1] = count[2] = 0; /* Suppress compiler warning. */
135
136    if (objc != 2) {
137        Tcl_AppendResult(interp, "wrong # arguments: should be \"",
138                         Tcl_GetString(objv[0]), " string\"", (char *)NULL);
139        return TCL_ERROR;
140    }
141    string = Tcl_GetStringFromObj(objv[1], &length);
142    if (strncmp("<ODX>", string, 5) == 0) {
143        string += 5;
144        length -= 5;
145    }
146    pointsObjPtr = Tcl_NewStringObj("", -1);
147    for (p = string, pend = p + length; p < pend; /*empty*/) {
148        char *line;
149        double ddx, ddy, ddz;
150
151        line = GetLine(&p, pend);
152        if (line >= pend) {
153            break;                      /* EOF */
154        }
155        if ((line[0] == '#') || (line[0] == '\n')) {
156            continue;                   /* Skip blank or comment lines. */
157        }
158        if (sscanf(line, "object %*d class gridpositions counts %d %d %d",
159                   count, count + 1, count + 2) == 3) {
160            if ((count[0] < 0) || (count[1] < 0) || (count[2] < 0)) {
161                sprintf(mesg, "invalid grid size: x=%d, y=%d, z=%d",
162                        count[0], count[1], count[2]);
163                Tcl_AppendResult(interp, mesg, (char *)NULL);
164                return TCL_ERROR;
165            }
166#ifdef notdef
167            fprintf(stderr, "found gridpositions counts %d %d %d\n",
168                    count[0], count[1], count[2]);
169#endif
170        } else if (sscanf(line, "origin %lg %lg %lg", origin, origin + 1,
171                origin + 2) == 3) {
172            /* Found origin. */
173#ifdef notdef
174            fprintf(stderr, "found origin %g %g %g\n",
175                    origin[0], origin[1], origin[2]);
176#endif
177        } else if (sscanf(line, "delta %lg %lg %lg", &ddx, &ddy, &ddz) == 3) {
178            if (nComponents == 3) {
179                Tcl_AppendResult(interp, "too many delta statements",
180                        (char *)NULL);
181                return TCL_ERROR;
182            }
183            delta[nComponents] = sqrt((ddx * ddx) + (ddy * ddy) + (ddz * ddz));
184            nComponents++;
185#ifdef notdef
186            fprintf(stderr, "found delta %g %g %g\n", ddx, ddy, ddx);
187#endif
188        } else if (sscanf(line, "object %*d class regulararray count %d",
189                          count[2]) == 1) {
190           
191        } else if (sscanf(line, "object %*d class array type %*s shape 3"
192                " rank 1 items %d data follows", &nPoints) == 1) {
193            fprintf(stderr, "found class array type shape 3 nPoints=%d\n",
194                    nPoints);
195            if (nPoints < 0) {
196                sprintf(mesg, "bad # points %d", nPoints);
197                Tcl_AppendResult(interp, mesg, (char *)NULL);
198                return TCL_ERROR;
199            }   
200            if (nPoints != count[0]*count[1]*count[2]) {
201                sprintf(mesg, "inconsistent data: expected %d points"
202                        " but found %d points", count[0]*count[1]*count[2],
203                        nPoints);
204                Tcl_AppendResult(interp, mesg, (char *)NULL);
205                return TCL_ERROR;
206            }
207            if (GetPoints(interp, nPoints, count, &p, pend, pointsObjPtr)
208                != TCL_OK) {
209                return TCL_ERROR;
210            }
211        } else if (sscanf(line, "object %*d class array type %*s rank 0"
212                " %*s %d data follows", &nPoints) == 1) {
213#ifdef notdef
214            fprintf(stderr, "found class array type rank 0 nPoints=%d\n",
215                nPoints);
216#endif
217            if (nPoints != count[0]*count[1]*count[2]) {
218                sprintf(mesg, "inconsistent data: expected %d points"
219                        " but found %d points", count[0]*count[1]*count[2],
220                        nPoints);
221                Tcl_AppendResult(interp, mesg, (char *)NULL);
222                return TCL_ERROR;
223            }
224            if (GetPoints(interp, nPoints, count, &p, pend, pointsObjPtr)
225                != TCL_OK) {
226                return TCL_ERROR;
227            }
228#ifdef notdef
229        } else {
230            fprintf(stderr, "unknown line (%.80s)\n", line);
231#endif
232        }
233    }
234    if (nPoints != count[0]*count[1]*count[2]) {
235        sprintf(mesg, "inconsistent data: expected %d points"
236                        " but found %d points", count[0]*count[1]*count[2],
237                        nPoints);
238        Tcl_AppendResult(interp, mesg, (char *)NULL);
239        return TCL_ERROR;
240    }
241
242    objPtr = Tcl_NewStringObj("# vtk DataFile Version 2.0\n", -1);
243    Tcl_AppendToObj(objPtr, "Converted from DX file\n", -1);
244    Tcl_AppendToObj(objPtr, "ASCII\n", -1);
245    Tcl_AppendToObj(objPtr, "DATASET STRUCTURED_POINTS\n", -1);
246    sprintf(mesg, "DIMENSIONS %d %d %d\n", count[0], count[1], count[2]);
247    Tcl_AppendToObj(objPtr, mesg, -1);
248    sprintf(mesg, "ORIGIN %g %g %g\n", origin[0], origin[1], origin[2]);
249    Tcl_AppendToObj(objPtr, mesg, -1);
250    sprintf(mesg, "SPACING %g %g %g\n", delta[0], delta[1], delta[2]);
251    Tcl_AppendToObj(objPtr, mesg, -1);
252    sprintf(mesg, "POINT_DATA %d\n", nPoints);
253    Tcl_AppendToObj(objPtr, mesg, -1);
254    sprintf(mesg, "SCALARS %s float 1\n", name);
255    Tcl_AppendToObj(objPtr, mesg, -1);
256    sprintf(mesg, "LOOKUP_TABLE default\n");
257    Tcl_AppendToObj(objPtr, mesg, -1);
258    Tcl_AppendObjToObj(objPtr, pointsObjPtr);
259    Tcl_DecrRefCount(pointsObjPtr);
260    Tcl_SetObjResult(interp, objPtr);
261    return TCL_OK;
262}
263
264/*
265 * ------------------------------------------------------------------------
266 *  RpConvertDxToVtk_Init --
267 *
268 *  Invoked when the Rappture GUI library is being initialized
269 *  to install the "ConvertDxToVtk" command into the interpreter.
270 *
271 *  Returns TCL_OK if successful, or TCL_ERROR (along with an error
272 *  message in the interp) if anything goes wrong.
273 * ------------------------------------------------------------------------
274 */
275int
276RpConvertDxToVtk_Init(Tcl_Interp *interp)
277{
278    /* install the widget command */
279    Tcl_CreateObjCommand(interp, "Rappture::ConvertDxToVtk", ConvertDxToVtkCmd,
280        NULL, NULL);
281    return TCL_OK;
282}
Note: See TracBrowser for help on using the repository browser.