Changeset 3871


Ignore:
Timestamp:
Aug 18, 2013 3:50:12 PM (11 years ago)
Author:
ldelgass
Message:

Add code based on nanovis to convert nanowire DX data to VTK unstructured grid
with wedge cells. Currently uses voronoi tool to do the 2D Delaunay
triangulation.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/gui/src/RpDxToVtk.c

    r3869 r3871  
    1212 * ======================================================================
    1313 */
     14#include <stdio.h>
    1415#include <string.h>
    1516#include <stdlib.h>
     17#include <sys/types.h>
     18#include <unistd.h>
    1619#include <ctype.h>
    1720#include <math.h>
     
    1922#include <float.h>
    2023#include "tcl.h"
     24
     25#define DO_WEDGES
    2126
    2227static INLINE char *
     
    235240    }
    236241    for (i = 0; i < nXYPoints; i++) {
    237         double x, y, z;
     242        double x, y;
    238243        char *nextPtr;
    239244
     
    257262        }
    258263        p = nextPtr;
    259         z = strtod(p, &nextPtr);
     264        /* z is unused */
     265        strtod(p, &nextPtr);
    260266        if (nextPtr == p) {
    261267            Tcl_AppendResult(interp, "bad value found in reading points",
     
    271277    *stringPtr = (char *)p;
    272278    return TCL_OK;
     279}
     280
     281static void
     282Normalize(double v[3])
     283{
     284    double len = sqrt(v[0]*v[0] + v[1]*v[1] + v[2]*v[2]);
     285    v[0] /= len;
     286    v[1] /= len;
     287    v[2] /= len;
     288}
     289
     290static double
     291Dot(double v1[3], double v2[3])
     292{
     293    return (v1[0]*v2[0] + v1[1]*v2[1] + v1[2]*v2[2]);
     294}
     295
     296static void
     297Cross(double v1[3], double v2[3], double vout[3])
     298{
     299    vout[0] = v1[1]*v2[2] - v1[2]*v2[1];
     300    vout[1] = v1[2]*v2[0] - v1[0]*v2[2];
     301    vout[2] = v1[0]*v2[1] - v1[1]*v2[0];
    273302}
    274303
     
    292321{
    293322    double *points;
    294     Tcl_Obj *objPtr, *pointsObjPtr, *fieldObjPtr;
     323    Tcl_Obj *objPtr, *pointsObjPtr, *fieldObjPtr, *cellsObjPtr;
    295324    char *p, *pend;
    296325    char *string;
     
    300329    double origin[3];
    301330    int count[3];
    302     int length, nAxes, nPoints, nXYPoints;
     331    int length, nAxes, nPoints, nXYPoints, nCells;
    303332    char *name;
    304333    int isUniform;
     
    308337    name = "component";
    309338    points = NULL;
    310     nAxes = nPoints = nXYPoints = 0;
     339    nAxes = nPoints = nXYPoints = nCells = 0;
    311340    dx = dy = dz = 0.0; /* Suppress compiler warning. */
    312341    origin[0] = origin[1] = origin[2] = 0.0; /* May not have an origin line. */
     
    329358    }
    330359    pointsObjPtr = Tcl_NewStringObj("", -1);
     360    cellsObjPtr = Tcl_NewStringObj("", -1);
    331361    fieldObjPtr = Tcl_NewStringObj("", -1);
    332362    for (p = string, pend = p + length; p < pend; /*empty*/) {
     
    539569            }
    540570        }
    541         free(points);
    542571
    543572        objPtr = Tcl_NewStringObj("# vtk DataFile Version 2.0\n", -1);
     
    548577        Tcl_AppendToObj(objPtr, mesg, -1);
    549578        Tcl_AppendObjToObj(objPtr, pointsObjPtr);
     579#ifdef DO_WEDGES
     580        {
     581            double xmin, xmax, ymin, ymax;
     582            xmin = xmax = points[0];
     583            ymin = ymax = points[1];
     584            for (i = 1; i < nXYPoints; i++) {
     585                double x, y;
     586                x = points[i*2];
     587                y = points[i*2+1];
     588                if (x < xmin) xmin = x;
     589                if (x > xmax) xmax = x;
     590                if (y < ymin) ymin = y;
     591                if (y > ymax) ymax = y;
     592            }
     593
     594            char fpts[128];
     595            sprintf(fpts, "/tmp/tmppts%d", getpid());
     596            char fcells[128];
     597            sprintf(fcells, "/tmp/tmpcells%d", getpid());
     598
     599            FILE *ftmp = fopen(fpts, "w");
     600            // save corners of bounding box first, to work around meshing
     601            // problems in voronoi utility
     602            int numBoundaryPoints = 4;
     603
     604            // Bump out the bounds by an epsilon to avoid problem when
     605            // corner points are already nodes
     606            double XEPS = (xmax - xmin) / 10.0f;
     607            double YEPS = (ymax - ymin) / 10.0f;
     608
     609            fprintf(ftmp, "%g %g\n", xmin - XEPS, ymin - YEPS);
     610            fprintf(ftmp, "%g %g\n", xmax + XEPS, ymin - YEPS);
     611            fprintf(ftmp, "%g %g\n", xmax + XEPS, ymax + YEPS);
     612            fprintf(ftmp, "%g %g\n", xmin - XEPS, ymax + YEPS);
     613
     614            for (i = 0; i < nXYPoints; i++) {
     615                fprintf(ftmp, "%g %g\n", points[i*2], points[i*2+1]);
     616            }
     617            fclose(ftmp);
     618#ifdef notdef
     619            double normal[3];
     620            normal[0] = normal[1] = 0.0;
     621            if (dx >= 0) {
     622                normal[2] = 1.0;
     623            } else {
     624                normal[2] = -1.0;
     625            }
     626#endif
     627            char cmdstr[512];
     628            sprintf(cmdstr, "voronoi -t < %s > %s", fpts, fcells);
     629            if (system(cmdstr) == 0) {
     630                int c0, c1, c2;
     631                ftmp = fopen(fcells, "r");
     632                while (!feof(ftmp)) {
     633                    if (fscanf(ftmp, "%d %d %d", &c0, &c1, &c2) == 3) {
     634                        c0 -= numBoundaryPoints;
     635                        c1 -= numBoundaryPoints;
     636                        c2 -= numBoundaryPoints;
     637                        // skip boundary points we added
     638                        if (c0 >= 0 && c1 >= 0 && c2 >= 0) {
     639#ifdef notdef
     640                            /* Winding of base triangle should point to
     641                               outside of cell using right hand rule */
     642                            double v1[3], v2[3], c[3];
     643                            v1[0] = points[c1*2] - points[c0*2];
     644                            v1[1] = points[c1*2+1] - points[c0*2+1];
     645                            v1[2] = 0;
     646                            v2[0] = points[c2*2] - points[c0*2];
     647                            v2[1] = points[c2*2+1] - points[c0*2+1];
     648                            v2[2] = 0;
     649                            Cross(v1, v2, c);
     650                            if (Dot(normal, c) > 0) {
     651                                int tmp = c0;
     652                                c0 = c2;
     653                                c2 = tmp;
     654                            }
     655#endif
     656                            for (iz = 0; iz < count[2] - 1; iz++) {
     657                                int base = nXYPoints * iz;
     658                                int top = base + nXYPoints;
     659                                nCells++;
     660                                sprintf(mesg, "%d %d %d %d %d %d %d\n", 6,
     661                                        base + c0, base + c1, base + c2,
     662                                        top + c0, top + c1, top + c2);
     663                                Tcl_AppendToObj(cellsObjPtr, mesg, -1);
     664                            }
     665                        }
     666                    } else {
     667                        break;
     668                    }
     669                }
     670                fclose(ftmp);
     671             } else {
     672                fprintf(stderr, "voronoi mesher failed");
     673            }
     674            unlink(fpts);
     675            unlink(fcells);
     676        }
     677        free(points);
     678        sprintf(mesg, "CELLS %d %d\n", nCells, 7*nCells);
     679        Tcl_AppendToObj(objPtr, mesg, -1);
     680        Tcl_AppendObjToObj(objPtr, cellsObjPtr);
     681        sprintf(mesg, "CELL_TYPES %d\n", nCells);
     682        Tcl_AppendToObj(objPtr, mesg, -1);
     683        sprintf(mesg, "%d\n", 13);
     684        for (i = 0; i < nCells; i++) {
     685            Tcl_AppendToObj(objPtr, mesg, -1);
     686        }
     687#endif
    550688        sprintf(mesg, "POINT_DATA %d\n", nPoints);
    551689        Tcl_AppendToObj(objPtr, mesg, -1);
     
    558696
    559697    Tcl_DecrRefCount(pointsObjPtr);
     698    Tcl_DecrRefCount(cellsObjPtr);
    560699    Tcl_DecrRefCount(fieldObjPtr);
    561700    Tcl_SetObjResult(interp, objPtr);
Note: See TracChangeset for help on using the changeset viewer.