apps/ccam/vrml303.c

Go to the documentation of this file.
00001 /*
00002  * vrml303.c
00003  *
00004  */
00005 #include <fcntl.h>  /*open*/
00006 #include <unistd.h> /* close */
00007 
00008 #include <stdio.h>
00009 #include <stdlib.h>
00010 #include <sys/mman.h>           /* mmap */
00011 #include <string.h>
00012 
00013 #include <math.h>
00014 
00015 #include "vrml303.h"
00016 #include "zlib/zlib.h"
00017 #include "gzio_compress.h"
00018 
00019 #define D(x)
00020 
00021 //#define DEBUG_CONT 1
00022 
00023 
00024 
00025 #ifdef DEBUG_CONT
00026  #define DEBUG_TOP
00027  #define MD1(x) fprintf(stderr,"%s:%d:",__FILE__,__LINE__);x
00028 #else
00029  #define MD1(x)
00030 #endif
00031 
00032 //#define MD2(x) fprintf(stderr,"%s:%d:",__FILE__,__LINE__);x
00033 #define MD2(x)
00034 
00035 
00036 //#define DEBUG_TOP
00037 #ifdef DEBUG_TOP
00038  #define MD(x) fprintf(stderr,"%s:%d:",__FILE__,__LINE__);x
00039 #else
00040  #define MD(x)
00041 #endif
00042 
00043 
00044 // should be less than SQRT(MYMAXINT/2)
00045 #define MYMAXINT 0x7fffffff
00046 #define EDGEFRACTMAX 16384
00047 #define LINEWIDTH2BREAK 80
00048 //returns pointer to a string of spaces n?(n+inc):0 character long (or shorter)
00049 char * indentString(int n, int inc);
00050 #define MAXCOLORS 32
00051 // options - string of up to MAXCOLORS characters (and 0)
00052 // 0,k,K - black
00053 // 1,r,R - red
00054 // 2,g,G - green
00055 // 3,y,Y - yellow
00056 // 4,b,B - blue
00057 // 5,m,M - magengta
00058 // 6,c,C - cyan
00059 // 7,w,W - white
00060 void initPseudoColor(const char * options); // will prepare arrays for up to MAXCOLORS colors.
00061 // will produce color as "0.123 0.456 0.789" using (i.e "BR" ) color options string and value 0..MYMAXINT
00062 char * pseudoColorStr(char * cs, int value);
00063 //   MD(fprintf(stderr,"width- %d, height %d, quality - %d, contrast - %d, color - %d, orient - %d, depth - %d\r\n", ImageWidth,ImageHeight, Quality, Contrast, Color, bayerOrient, Depth));
00064 //edArr[y][x][0] - horizontal edge (x,y) to (x+1,y)
00065 //edArr[y][x][1] - vertical edge (x,y) to (x,y+1)
00066 // value - "-1" - no intersections with current isoline, 0..EDGEFRACTMAX where does it intersect
00067 // if one end equals level and the other is equal or less - no intersection
00068 // vert[y][x] (and level) should be normalized to 0..MYMAXINT
00069 // returns number of marked edges
00070 int fillEdgesArray (int level,
00071                                         int x0, int y0, int x1, int y1, // window of interest 
00072                                         int vert[MAX_VERTEX_Y][MAX_VERTEX_X],
00073                                         short edArr[MAX_VERTEX_Y+1][MAX_VERTEX_X+1][2]);
00074 // edgeNum[0] - y,
00075 // edgeNum[1] - x,
00076 // edgeNum[2] - start edge orient (o - hor, 1 - vert),
00077 // edgeNum[3] - dir (0 - up or right, 1 - down or left)
00078 // returns 0 - did not found, 1 - found (result in edgeNum) on the boarder, 2 - found inside (result in edgeNum)
00079 // edgeNum should be initialized by (x0,y0,0,ANY) before the first call
00080 int findStartEdge  (int * edgeNum,      // 4-element integer array - y,x,orient(0,1),dir(0,1)
00081                                         int x0, int y0, int x1, int y1, // window of interest 
00082                                         short edArr[MAX_VERTEX_Y+1][MAX_VERTEX_X+1][2]);
00083 //returns 0 - did not found, 1 - found. Will modify *edgeNum elements
00084 // modify to orient i.e. right hand is always higher?
00085 int findNextEdge   (int * edgeNum,      // 4-element integer array - y,x,orient(0,1),dir(0,1)
00086                                         int x0, int y0, int x1, int y1, // window of interest 
00087                                         short edArr[MAX_VERTEX_Y+1][MAX_VERTEX_X+1][2]);
00088 
00089 // returns number of coordinates exported (closed lines should start and end with index 0)
00090 int exportIsolineCoord (int closed,     // 1 - closed line, 0 -opened
00091                                           int scaleX,   // multiply x by scaleX to get pixels
00092                                           int scaleY,   // multiply y by scaleY to get pixels
00093                                           int dcm,              // 1/10(should match format)
00094                                           int indent,   // indentation
00095                                           const char * frmt, // output format as "     %d.%01d 123.4 -%d.%01d"
00096                                           int * edgeNumS,       // 4-element integer array - will not be modified!
00097                                           int x0, int y0, int x1, int y1, // window of interest 
00098                                           short edArr[MAX_VERTEX_Y+1][MAX_VERTEX_X+1][2]);
00099 
00100 int exportIsolineNode  (int level,
00101                                           int scaleX,   // multiply x by scaleX to get pixels
00102                                           int scaleY,   // multiply y by scaleY to get pixels
00103                                           int dcm,              // 1/10(should match format)
00104                                           int indent, //if 0 - all will be 0, else - 1 per level
00105                                           const char * charZ,   // string representation of z (VRML-y) of the isoline (0 or level)
00106                                           const char * Appearance,      // name of appearance to use (should be defined earlier)
00107                                           int x0, int y0, int x1, int y1, // window of interest
00108                                           int vert[MAX_VERTEX_Y][MAX_VERTEX_X],
00109                                           short edArr[MAX_VERTEX_Y+1][MAX_VERTEX_X+1][2]);
00110 void exportVRMLStart(int level);
00111 void exportVRMLViewpoints(int width, int height, int elev);
00112 
00113 //returns <0 - errror, (vertNum_x & 0xfff)+((vertNum_y & 0xfff) << 12) if OK
00114 int initVertexArray ( const char * dmaFileName,
00115                                           int   width,
00116                                           int height,
00117                                           int maxpixel, // maximal pixel (full scale -= 1024, 0 - auto normalize)
00118                                           int decimate_x,       // rectangle width to be combined in one vertex
00119                                           int decimate_y,       // rectangle height to be combined in one vertex
00120                                           int vert[MAX_VERTEX_Y][MAX_VERTEX_X] // vertex array
00121                                           );
00122 
00123 void exportFacesAppearance(const char * aname, const char * mname, double transparency);
00124 void exportIsolinesAppearance(const char * prefix, int numLev);
00125 void exportCoordinateSet(const char * name,
00126                                                  int width, int height, // number of vertexes is (width+1)*(height+1) !!
00127                                                  int elev,
00128                                                  int scale_X, int scale_Y,
00129                                                  int dcp,       // 0 or 1 only
00130                                                  int indent,
00131                                                  int vert[MAX_VERTEX_Y][MAX_VERTEX_X]);
00132 void exportColorSet(const char * name,
00133                                         int width, int height,
00134                                         int indent,
00135                                         int vert[MAX_VERTEX_Y][MAX_VERTEX_X]);
00136 void exportSwitchStart(const char * name, const char * suffics, int * ind);
00137 void exportSwitchEnd(int * ind);
00138 void exportTransformStart(const char * name, const char * suffics, int * ind);
00139 void exportTransformEnd(int * ind);
00140 
00141 void exportIFSStart       (const char * app,                       // name of Appearance to use
00142                        const char * coord,                         // name of Coordinate to use
00143                                            const char * color,                     // name of Color to use
00144                                            int * ind) ;                                    // address of indent value
00145 
00146 void exportILSStart (const char * app,     // name of Appearance to use (may be NULL)
00147                      const char * coord,   // name of Coordinate to use (may NOT be NULL)
00148                      const char * color,   // name of Color to use      (may be NULL)
00149                      int * ind) ;          // address of indent value
00150 
00151 void exportIFLSEnd        (int * ind) ;                                    // address of indent value
00152 
00153 void exportTopFaces   (int x0, int y0, int x1,int y1,  // window parameters
00154                        int rowLen,                                         // number of vertexes in a row
00155                        const char * app,                           // name of Appearance to use
00156                        const char * coord,                         // name of Coordinate to use
00157                                            const char * color,                     // name of Color to use
00158                                            int * ind) ;                                    // address of indent value   
00159 
00160 void exportBottomFaces(int x0, int y0, int x1,int y1,  // window parameters
00161                        int rowLen,                                         // number of vertexes in a row
00162                        const char * app,                           // name of Appearance to use
00163                        const char * coord,                         // name of Coordinate to use
00164                                            const char * color,                     // name of Color to use
00165                                            int * ind) ;                                    // address of indent value   
00166 
00167 void exportSideFaces  (int x0, int y0, int x1,int y1,  // window parameters
00168                        int rowLen,                                         // number of vertexes in a row
00169                        const char * app,                           // name of Appearance to use
00170                        const char * coord,                         // name of Coordinate to use
00171                                            const char * color,                     // name of Color to use
00172                        int wallNum,                                        // wall number (0..3)
00173                                            int * ind) ;                                    // address of indent value   
00174 
00175 void exportTopEdges   (int x0, int y0, int x1,int y1,  // window parameters
00176                        int rowLen,                                         // number of vertexes in a row
00177                        const char * coord,                         // name of Coordinate to use
00178                                            const char * color,                     // name of Color to use
00179                                            int * ind) ;                                    // address of indent value   
00180 
00181 void exportBottomEdges(int x0, int y0, int x1,int y1,  // window parameters
00182                        int rowLen,                                         // number of vertexes in a row
00183                        const char * coord,                         // name of Coordinate to use
00184                                            const char * color,                     // name of Color to use
00185                                            int * ind) ;                                    // address of indent value   
00186 
00187 
00188 void exportSideEdges   (int x0, int y0, int x1,int y1,  // window parameters
00189                        int rowLen,                                         // number of vertexes in a row
00190                        const char * coord,                         // name of Coordinate to use
00191                                            const char * color,                     // name of Color to use
00192                        int wallNum,                                        // wall number (0..3)        
00193                                            int * ind) ;                                    // address of indent value   
00194 
00195 
00196  
00197 //table for nextEdge calculation
00198 int nextEdgeTable[][2][3][4]= //[orient][dir][choice(0..2)](dy,dx,new_orient,new_dir)
00199                 {
00200                  {                                       // orient==0
00201                   {                              // dir==0
00202                    { 0, 1, 1, 0},        // choice==0
00203                    { 1, 0, 0, 0},        // choice==1
00204                    { 0, 0, 1, 1}},       // choice==2
00205                   {                              // dir==1
00206                    {-1, 0, 1, 1},        // choice==0
00207                    {-1, 0, 0, 1},        // choice==1
00208                    {-1, 1, 1, 0}}},      // choice==2
00209                  {                                       // orient==1
00210                   {                              // dir==0
00211                    { 0, 0, 0, 1},        // choice==0
00212                    { 0, 1, 1, 0},        // choice==1
00213                    { 1, 0, 0, 0}},       // choice==2
00214                   {                              // dir==1
00215                    { 1,-1, 0, 0},        // choice==0
00216                    { 0,-1, 1, 1},        // choice==1
00217                    { 0,-1, 0, 1}}}}; // choice==2
00218 char indentS[]="                                                                                     ";
00219 struct  {
00220   int numcolors;
00221   int coeff;
00222   int red[MAXCOLORS];
00223   int green[MAXCOLORS];
00224   int blue[MAXCOLORS];
00225 } colorTab;
00226 //******************************************************************
00227 // compressed file
00228     gzFile gzfile;
00229 
00230 
00231 
00232 //******************************************************************
00233 
00234 #ifdef DEBUG_CONT
00235 void printEdgesArray (int nx, int ny, short edArr[MAX_VERTEX_Y+1][MAX_VERTEX_X+1][2]) {
00236   int x,y;
00237   MD1(fprintf(stderr,"printEdgesArray(%d, %d, edArr)\r\n",nx,ny));
00238   for (y=0;y<ny;y++) {
00239     fprintf(stderr,"y= %02d ",y);
00240     for (x=0;x<nx;x++) {
00241       fprintf(stderr,"[%5d %5d] ",(int) edArr[y][x][0],(int) edArr[y][x][1]);
00242     }
00243     fprintf(stderr,"\r\n");
00244   }
00245 }
00246 #endif
00247 
00248 // options - string of up to MAXCOLORS characters (and 0)
00249 // 0,k,K - black
00250 // 1,r,R - red
00251 // 2,g,G - green
00252 // 3,y,Y - yellow
00253 // 4,b,B - blue
00254 // 5,m,M - magengta
00255 // 6,c,C - cyan
00256 // 7,w,W - white
00257 void initPseudoColor(const char * options){ // will prepare arrays for up to MAXCOLORS colors.
00258  int i;
00259  char s1[]="WW";
00260  const char * cp=options;
00261 // char tmp[20];
00262 // int tmpv; 
00263  if ((!options) || (strlen(options)==0)) cp=(const char *) s1;
00264  else if (strlen(options)==1) {
00265    s1[0]='0';
00266    s1[1]=options[0];
00267    cp=(const char *) s1;
00268  }
00269  colorTab.numcolors=strlen(cp);
00270  if (colorTab.numcolors>MAXCOLORS) colorTab.numcolors=MAXCOLORS;
00271  colorTab.coeff=((1000*(colorTab.numcolors-1))<<16)/(MYMAXINT>>16);
00272 
00273  for (i=0;i<colorTab.numcolors;i++) switch (cp[i] ) {
00274   case '0':
00275   case 'k':
00276   case 'K':
00277           {colorTab.red[i]=0;colorTab.green[i]=0;colorTab.blue[i]=0;break;}
00278   case '1':
00279   case 'r':
00280   case 'R':
00281           {colorTab.red[i]=1;colorTab.green[i]=0;colorTab.blue[i]=0;break;}
00282   case '2':
00283   case 'g':
00284   case 'G':
00285           {colorTab.red[i]=0;colorTab.green[i]=1;colorTab.blue[i]=0;break;}
00286   case '3':
00287   case 'y':
00288   case 'Y':
00289           {colorTab.red[i]=1;colorTab.green[i]=1;colorTab.blue[i]=0;break;}
00290   case '4':
00291   case 'b':
00292   case 'B':
00293           {colorTab.red[i]=0;colorTab.green[i]=0;colorTab.blue[i]=1;break;}
00294   case '5':
00295   case 'm':
00296   case 'M':
00297           {colorTab.red[i]=1;colorTab.green[i]=0;colorTab.blue[i]=1;break;}
00298   case '6':
00299   case 'c':
00300   case 'C':
00301           {colorTab.red[i]=0;colorTab.green[i]=1;colorTab.blue[i]=1;break;}
00302   case '7':
00303   case 'w':
00304   case 'W':
00305           {colorTab.red[i]=1;colorTab.green[i]=1;colorTab.blue[i]=1;break;}
00306   default:
00307           {colorTab.red[i]=1;colorTab.green[i]=1;colorTab.blue[i]=1;break;}
00308  }
00309 #if 0
00310  fprintf(stderr,"initPseudoColor (%s), colorTab.numcolors=%d, coeff=%d\n",cp,colorTab.numcolors,colorTab.coeff);
00311  fprintf(stderr,"colorTab.red= %d %d %d %d\n",colorTab.red[0],colorTab.red[1],colorTab.red[2],colorTab.red[3]);
00312  fprintf(stderr,"colorTab.green= %d %d %d %d\n",colorTab.green[0],colorTab.green[1],colorTab.green[2],colorTab.green[3]);
00313  fprintf(stderr,"colorTab.blue= %d %d %d %d\n",colorTab.blue[0],colorTab.blue[1],colorTab.red[2],colorTab.blue[3]);
00314  tmpv=0;fprintf(stderr,"pseudoColorStr(%x)= %s\n",tmpv,pseudoColorStr(tmp,tmpv));
00315    tmpv=((tmpv>>16)*colorTab.coeff)>>16;  fprintf(stderr,"value= %x\n",tmpv);
00316  tmpv=0x10000000;fprintf(stderr,"pseudoColorStr(%x)= %s\n",tmpv,pseudoColorStr(tmp,tmpv));
00317    tmpv=((tmpv>>16)*colorTab.coeff)>>16;  fprintf(stderr,"value= %x\n",tmpv);
00318  tmpv=0x20000000;fprintf(stderr,"pseudoColorStr(%x)= %s\n",tmpv,pseudoColorStr(tmp,tmpv));
00319    tmpv=((tmpv>>16)*colorTab.coeff)>>16;  fprintf(stderr,"value= %x\n",tmpv);
00320  tmpv=0x40000000;fprintf(stderr,"pseudoColorStr(%x)= %s\n",tmpv,pseudoColorStr(tmp,tmpv));
00321    tmpv=((tmpv>>16)*colorTab.coeff)>>16;  fprintf(stderr,"value= %x\n",tmpv);
00322  tmpv=0x7fffffff;fprintf(stderr,"pseudoColorStr(%x)= %s\n",tmpv,pseudoColorStr(tmp,tmpv));
00323    tmpv=((tmpv>>16)*colorTab.coeff)>>16;  fprintf(stderr,"value= %x\n",tmpv);
00324 #endif
00325 
00326 }
00327 
00328 // will produce color as "0.123 0.456 0.789" value 0..MYMAXINT
00329 // 
00330 char * pseudoColorStr(char * cs, int value) {
00331   int ci,cf;
00332   int r,g,b;
00333   value=((value>>16)*colorTab.coeff)>>16; //value is expected to be in the range 0..MYMAXINT (0x7ffffff)
00334   ci=value/1000;
00335   if (ci>=colorTab.numcolors) ci=colorTab.numcolors;
00336   cf=value-1000*ci;
00337   if (cf>999) cf=999;
00338   if (colorTab.red[ci]==colorTab.red[ci+1]) r=colorTab.red[ci]?1000:0;
00339   else if (colorTab.red[ci]) r=1000-cf;
00340   else r=cf;
00341   if (colorTab.green[ci]==colorTab.green[ci+1]) g=colorTab.green[ci]?1000:0;
00342   else if (colorTab.green[ci]) g=1000-cf;
00343   else g=cf;
00344   if (colorTab.blue[ci]==colorTab.blue[ci+1]) b=colorTab.blue[ci]?1000:0;
00345   else if (colorTab.blue[ci]) b=1000-cf;
00346   else b=cf;
00347   sprintf(cs,"%d.%03d %d.%03d %d.%03d",(r==1000),(r==1000)?0:r,
00348                                                                            (g==1000),(g==1000)?0:g,
00349                                                                            (b==1000),(b==1000)?0:b);
00350   return cs;
00351 }
00352 
00353 
00354 //returns pointer to a string of spaces n?(n+inc):0 character long (or shorter)
00355 char * indentString(int n, int inc) {
00356   n= (n>=0)?(n+inc):0;
00357   if (n>=sizeof(indentS)) n=sizeof(indentS)-1;
00358   if (n<0) n=0;
00359   return &indentS[(sizeof(indentS)-1)-n];
00360 }
00361 
00362 
00363 
00364 int fillEdgesArray (int level,
00365                                         int x0, int y0, int x1, int y1, // window of interest 
00366                                         int vert[MAX_VERTEX_Y][MAX_VERTEX_X],
00367                                         short edArr[MAX_VERTEX_Y+1][MAX_VERTEX_X+1][2]) {
00368   int numis=0;
00369   int x,y,d;
00370 
00371   MD1(fprintf(stderr,"fillEdgesArray: level=%d, x0=%d, y0=%d, x1=%d, y1=%d\r\n", level, x0, y0, x1, y1));
00372   MD1(fprintf(stderr,"sizeof(edArr)=%d\r\n", sizeof(edArr)));
00373 //  memset (edArr, -1,(MAX_VERTEX_Y+1)*(MAX_VERTEX_X+1)*sizeof(edArr)); // all "1"-s - is -1
00374   memset (edArr, -1,(MAX_VERTEX_Y+1)*(MAX_VERTEX_X+1)*2*2); // all "1"-s - is -1
00375 #ifdef DEBUG_CONT
00376   printEdgesArray (x1+1,y1+1, edArr);
00377 #endif
00378 
00379 // check x0,x1,y0,y1?
00380   for (y=y0;y<=y1;y++)
00381    for (x=x0; x<x1; x++)
00382     if (((vert[y][x] >level) || (vert[y][x+1]> level)) &&
00383             ((vert[y][x]<=level) || (vert[y][x+1]<=level))) {
00384                 if              (vert[y][x]   == level) edArr[y][x][0]=0;
00385                 else if (vert[y][x+1] == level) edArr[y][x][0]=EDGEFRACTMAX;
00386                 else {
00387                   d=(vert[y][x+1]-vert[y][x])/EDGEFRACTMAX;
00388                   if (d==0) d=(vert[y][x+1]>vert[y][x])?1:-1; 
00389                   edArr[y][x][0]= (level-vert[y][x])/d;
00390                   if (edArr[y][x][0]<1) edArr[y][x][0]=1;
00391                   else if (edArr[y][x][0]>(EDGEFRACTMAX-1))     edArr[y][x][0]=EDGEFRACTMAX-1;
00392                 }
00393                 numis++;
00394   }
00395 
00396   for (x=x0;x<=x1;x++)
00397    for (y=y0; y<y1; y++)
00398     if (((vert[y][x] >level) || (vert[y+1][x]> level)) &&
00399             ((vert[y][x]<=level) || (vert[y+1][x]<=level))) {
00400                 if              (vert[y][x]   == level) edArr[y][x][1]=0;
00401                 else if (vert[y+1][x] == level) edArr[y][x][1]=EDGEFRACTMAX;
00402                 else {
00403                   d=(vert[y+1][x]-vert[y][x])/EDGEFRACTMAX;
00404                   if (d==0) d=(vert[y+1][x]>vert[y][x])?1:-1; 
00405                   edArr[y][x][1]= (level-vert[y][x])/d;
00406                   if (edArr[y][x][1]<1) edArr[y][x][1]=1;
00407                   else if (edArr[y][x][1]>(EDGEFRACTMAX-1))     edArr[y][x][1]=EDGEFRACTMAX-1;
00408                 }
00409                 numis++;
00410   }
00411   if (numis==0) return 0; // no intersections at all
00412 // filter out all single-point lines
00413 // internal
00414   for (y=y0+1;y<y1;y++)
00415    for (x=x0;x<x1;x++)
00416     if ((edArr[y][x][0]==    EDGEFRACTMAX) &&
00417             (edArr[y-1][x+1][1]==EDGEFRACTMAX) &&
00418                 (edArr[y][x+1][0]==  0) &&
00419                 (edArr[y][x+1][1]==  0)) {
00420           edArr[y][x][0]=-1;
00421           edArr[y-1][x+1][1]=-1;
00422           edArr[y][x+1][0]=-1;
00423           edArr[y][x+1][1]=-1;
00424           numis-=4;
00425         }
00426  // x=x0;
00427   for (y=y0+1;y<y1;y++)
00428     if ((edArr[y][x0][0]==  0) &&
00429                 (edArr[y][x0][1]==  0) &&
00430             (edArr[y-1][x0][1]==EDGEFRACTMAX)) {
00431           edArr[y][x0][0]=-1;
00432           edArr[y][x0][1]=-1;
00433           edArr[y-1][x0][1]=-1;
00434           numis-=3;
00435         }
00436  // x=x1;
00437   for (y=y0+1;y<y1;y++)
00438     if ((edArr[y][x1-1][0]==EDGEFRACTMAX) &&
00439                 (edArr[y][x1][1]==  0) &&
00440             (edArr[y-1][x1][1]==EDGEFRACTMAX)) {
00441           edArr[y][x1-1][0]=-1;
00442           edArr[y][x1][1]=-1;
00443           edArr[y-1][x1][1]=-1;
00444           numis-=3;
00445         }
00446  // y=y0;
00447   for (x=x0+1;x<x1;x++)
00448     if ((edArr[y0][x][1]==  0) &&
00449                 (edArr[y0][x-1][0]==EDGEFRACTMAX) &&
00450             (edArr[y0][x][0]==  0)) {
00451           edArr[y0][x][1]=-1;
00452           edArr[y0][x-1][0]=-1;
00453           edArr[y0][x][0]=-1;
00454           numis-=3;
00455         }
00456  // y=y1;
00457   for (x=x0+1;x<x1;x++)
00458     if ((edArr[y1-1][x][1]==EDGEFRACTMAX) &&
00459                 (edArr[y1][x-1][0]==EDGEFRACTMAX) &&
00460             (edArr[y1][x][0]==  0)) {
00461           edArr[y1-1][x][1]=-1;
00462           edArr[y1][x-1][0]=-1;
00463           edArr[y1][x][0]=-1;
00464           numis-=3;
00465         }
00466  // corners
00467   if ((edArr[y0][x0][0]==  0) &&
00468           (edArr[y0][x0][1]==  0)) {
00469         edArr[y0][x0][0]=-1;
00470         edArr[y0][x0][1]=-1;
00471         numis-=2;
00472   }
00473   if ((edArr[y0][x1-1][0]==EDGEFRACTMAX) &&
00474           (edArr[y0][x1][1]==  0)) {
00475         edArr[y0][x1-1][0]=-1;
00476         edArr[y0][x1][1]=-1;
00477         numis-=2;
00478   }
00479   if ((edArr[y1-1][x1][1]==EDGEFRACTMAX) &&
00480           (edArr[y1][x1-1][0]==EDGEFRACTMAX)) {
00481         edArr[y1-1][x1][1]=-1;
00482         edArr[y1][x1-1][0]=-1;
00483         numis-=2;
00484   }
00485   if ((edArr[y1-1][x0][1]==EDGEFRACTMAX) &&
00486           (edArr[y1][x0][0]==0)) {
00487         edArr[y1-1][x0][1]=-1;
00488         edArr[y1][x0][0]=-1;
00489         numis-=2;
00490   }
00491 
00492   return numis;
00493 }
00494 
00495 // edgeNum[0] - y,
00496 // edgeNum[1] - x,
00497 // edgeNum[2] - start edge orient (o - hor, 1 - vert),
00498 // edgeNum[3] - dir (+1 - up or right, -1 - down or left)
00499 // returns 0 - did not found, 1 - found (result in edgeNum) on the boarder, 2 - found inside (result in edgeNum)
00500 // edgeNum should be initialized by (x0,y0,0,ANY) before the first call
00501 int findStartEdge  (int * edgeNum,      // 4-element integer array - y,x,orient(0,1),dir(+1,-1)
00502                                         int x0, int y0, int x1, int y1, // window of interest 
00503                                         short edArr[MAX_VERTEX_Y+1][MAX_VERTEX_X+1][2]) {
00504   int x,y;
00505 // try on y=y0 (last_x+1-->x1)
00506   if ((edgeNum[0]==y0) && (edgeNum[2]==0)) {
00507    for (x=edgeNum[1]+(edgeNum[1]>x0);x<x1;x++)
00508     if (edArr[y0][x][0]>=0) {
00509           edgeNum[0]=y0;
00510           edgeNum[1]=x;
00511           edgeNum[2]=0;
00512           edgeNum[3]=0;
00513           return 1;
00514    }
00515    edgeNum[0]=y0-1;
00516    edgeNum[1]=x1;
00517    edgeNum[2]=1;
00518   }
00519 // try on x=x1 (last_y+1-->y1)
00520   if ((edgeNum[1]==x1) && (edgeNum[2]==1)) {
00521    for (y=edgeNum[0]+1;y<y1;y++)
00522     if (edArr[y][x1][1]>=0) {
00523           edgeNum[0]=y;
00524           edgeNum[1]=x1;
00525           edgeNum[2]=1;
00526           edgeNum[3]=1;
00527           return 1;
00528    }
00529    edgeNum[0]=y1;
00530    edgeNum[1]=x1;
00531    edgeNum[2]=0;
00532   }
00533 // try on y=y1 (last_x-1-->x0)
00534   if ((edgeNum[0]==y1) && (edgeNum[2]==0)) {
00535    for (x=edgeNum[1]-1;x>=x0;x--)
00536     if (edArr[y1][x][0]>=0) {
00537           edgeNum[0]=y1;
00538           edgeNum[1]=x;
00539           edgeNum[2]=0;
00540           edgeNum[3]=1;
00541           return 1;
00542    }
00543    edgeNum[0]=y1;
00544    edgeNum[1]=x0;
00545    edgeNum[2]=1;
00546   }
00547 // try on x=x0 (last_y1-->y0)
00548   if ((edgeNum[1]==x0) && (edgeNum[2]==1)) {
00549    for (y=edgeNum[0]-1;y>=y0;y--)
00550     if (edArr[y][x0][1]>=0) {
00551           edgeNum[0]=y;
00552           edgeNum[1]=x0;
00553           edgeNum[2]=1;
00554           edgeNum[3]=0;
00555           return 1;
00556    }
00557    edgeNum[0]=y0;
00558    edgeNum[1]=x0;
00559    edgeNum[2]=1;
00560   }
00561 
00562 // look inside - only vertical edges OK
00563   edgeNum[2]=1;
00564   edgeNum[3]=0;
00565   y=edgeNum[0];
00566   x=edgeNum[1]+1;
00567   if (x>=x1) {
00568     y++;
00569         x=x0+1;
00570   } 
00571   while (y<y1) {
00572     if (edArr[y][x][1]>=0) {
00573       edgeNum[0]=y;
00574       edgeNum[1]=x;
00575           return 2;
00576         }
00577     if ((++x)>=x1) {
00578       y++;
00579           x=x0+1;
00580     } 
00581   }
00582   return 0;     // nothing found
00583 }
00584 // can see 0,1 or 3 intersections. If 3 - will look for a nearest one (rare case)
00585 //int nextEdgeTable[][2][3][4]= //[orient][dir][choice(0..2)](dy,dx,new_orient,new_dir)
00586 int findNextEdge  (int * edgeNum,       // 4-element integer array - y,x,orient(0,1),dir(+1,-1)
00587                                         int x0, int y0, int x1, int y1, // window of interest 
00588                                         short edArr[MAX_VERTEX_Y+1][MAX_VERTEX_X+1][2]) {
00589   int i;
00590   int choice=-1;
00591   int n=0;
00592   int neib[4];
00593   MD1(fprintf(stderr,"findNextEdge: edgeNum=[%d %d %d %d], x0=%d, y0=%d, x1=%d, y1=%d\r\n", edgeNum[0], edgeNum[1], edgeNum[2], edgeNum[3], x0, y0, x1, y1));
00594 
00595 // supposed we are not on the boarder looking outwards - will check later
00596 // supposed initial edge is in range 0..EDGEFRACTMAX
00597   for (i=0;i<3;i++){ 
00598     neib[i]=edArr[edgeNum[0]+nextEdgeTable[edgeNum[2]][edgeNum[3]][i][0]] //y
00599                  [edgeNum[1]+nextEdgeTable[edgeNum[2]][edgeNum[3]][i][1]] //x
00600                  [           nextEdgeTable[edgeNum[2]][edgeNum[3]][i][2]];//orient
00601         if (neib[i]>=0) {
00602           n++; //
00603           choice=i;
00604         }
00605   }
00606   MD1(fprintf(stderr,"findNextEdge: n=%d, choice=%d\r\n", n, choice));
00607 
00608   if (n==0) return 0;
00609   if (n==3) { // resolve "saddle" -- find nearest
00610     neib[3]=edArr[edgeNum[0]][edgeNum[1]][edgeNum[2]];
00611 // orient all neib elements to point counterclockwise
00612     if (edgeNum[2]==0) {
00613       if (edgeNum[3]==0) {
00614             neib[1]= EDGEFRACTMAX-neib[1];
00615             neib[2]= EDGEFRACTMAX-neib[2];
00616           } else { // if (edgeNum[3]==0)
00617             neib[0]= EDGEFRACTMAX-neib[0];
00618             neib[3]= EDGEFRACTMAX-neib[3];
00619           } // if (edgeNum[3]==0)
00620     } else { // if (edgeNum[2]==0)
00621       if (edgeNum[3]==0) {
00622             neib[2]= EDGEFRACTMAX-neib[2];
00623             neib[3]= EDGEFRACTMAX-neib[3];
00624           } else { // if (edgeNum[3]==0)
00625             neib[0]= EDGEFRACTMAX-neib[0];
00626             neib[1]= EDGEFRACTMAX-neib[1];
00627           } // if (edgeNum[3]==0)
00628     } // if (edgeNum[2]==0)
00629 //replace neib[0..2] with lengths^2;
00630     neib[0]= (EDGEFRACTMAX-neib[3])*(EDGEFRACTMAX-neib[3]) + neib[0]*neib[0];
00631     neib[1]= (neib[3]+neib[1]-EDGEFRACTMAX)*(neib[3]+neib[1]-EDGEFRACTMAX) + EDGEFRACTMAX*EDGEFRACTMAX;
00632     neib[2]= neib[3]*neib[3] + (EDGEFRACTMAX-neib[2])*(EDGEFRACTMAX-neib[2]);
00633 // now find the shortest one (chose right-hand if equal)
00634     choice=(neib[0]>neib[2])?((neib[1]>neib[2])? 2 : 1 ):((neib[0]>neib[1])? 1 : 0);
00635   }//if (n==3)
00636   edgeNum[0]+=nextEdgeTable[edgeNum[2]][edgeNum[3]][choice][0]; //y
00637   edgeNum[1]+=nextEdgeTable[edgeNum[2]][edgeNum[3]][choice][1]; //x
00638   i          =nextEdgeTable[edgeNum[2]][edgeNum[3]][choice][2]; //orient
00639   edgeNum[3] =nextEdgeTable[edgeNum[2]][edgeNum[3]][choice][3]; //direction
00640   edgeNum[2] =i;
00641   return 1;
00642 }
00643 
00644 // returns number of coordinates exported (closed lines should start and end with index 0)
00645 // supports integer (dcm==1,frmt has 2 fields) and fractional output (dcm=10, frmt has 4 fields)
00646 // will export just data, no "[" or "]"
00647 // edgeNum is supposed to point to starting edge/direction (after findStartEdge)
00648 // relies on "closed" - all open lines should be processed first.
00649 int exportIsolineCoord (int closed,     // 1 - closed line, 0 -opened
00650                                           int scaleX,   // multiply x by scaleX to get pixels
00651                                           int scaleY,   // multiply y by scaleY to get pixels
00652                                           int dcm,              // 1/10/100/1000 (should match format)
00653                                           int indent,   // indentation
00654                                           const char * frmt, // output format as "%d.%01d 123.4 -%d.%01d"
00655                                           int * edgeNumS,       // 4-element integer array - y,x,orient(0,1),dir(0,1)
00656                                           int x0, int y0, int x1, int y1, // window of interest 
00657                                           short edArr[MAX_VERTEX_Y+1][MAX_VERTEX_X+1][2]) {
00658   int yp=     -1;
00659   int xp=     -1;
00660   int x,y;
00661   int nOutPoints=0;
00662   int nPoints=0;
00663   int edgeNum[4];
00664   int edgeNumP[4];
00665   int found;
00666   MD1(fprintf(stderr,"exportIsolineCoord:lclosed= %x scaleX=%d, scaleY=%d, dcm=%d, indent=%d, frmt=%s, edgeNumS=[%d %d %d %d], x0=%d, y0=%d, x1=%d, y1=%d\r\n",closed, scaleX, scaleY, dcm, indent, frmt, edgeNumS[0], edgeNumS[1], edgeNumS[2], edgeNumS[3], x0, y0, x1, y1));
00667 
00668 
00669   memcpy( edgeNum, edgeNumS, sizeof(edgeNum)); // copy start edge
00670   MD1(fprintf(stderr," -- exportIsolineCoord: edgeNum=[%d %d %d %d]\r\n", edgeNum[0], edgeNum[1], edgeNum[2], edgeNum[3]));
00671 
00672   while(1) {
00673 //    calculate coordinates to output
00674     x=edgeNum[1]*scaleX*dcm + ((edgeNum[2]==0)?((edArr[edgeNum[0]][edgeNum[1]][0]*scaleX*dcm)/EDGEFRACTMAX):0);
00675     y=edgeNum[0]*scaleY*dcm + ((edgeNum[2]==1)?((edArr[edgeNum[0]][edgeNum[1]][1]*scaleY*dcm)/EDGEFRACTMAX):0);
00676   MD1(fprintf(stderr,"edgeNum=[%d %d %d %d], scaleX=%d, scaleY=%d, dcm=%d\r\n", edgeNum[0], edgeNum[1], edgeNum[2], edgeNum[3], scaleX, scaleY, dcm));
00677   MD1(fprintf(stderr,"x=%d, y=%d, xp=%d, yp=%d, nPoints=%d\r\n", x, y, xp, yp, nPoints));
00678 
00679         if ((x!=xp) || (y!=yp) || (nPoints==0)) {
00680       if (nOutPoints) gzprintf(gzfile,",\n");
00681           gzprintf(gzfile,indentString(indent,0));
00682           if (dcm==1) gzprintf(gzfile,frmt,x,y);
00683           else gzprintf(gzfile,frmt,x/dcm,x%dcm,y/dcm,y%dcm);
00684           xp=x;
00685           yp=y;
00686           nOutPoints++;
00687         } // if ((x!=xp) || (y!=yp) || (npoints==0))
00688 // break here if nowhere to go in "open" mode
00689     if (!closed) {
00690           if (edgeNum[2]) {
00691             if (edgeNum[3]) {
00692                    if (edgeNum[1]== x0) break;
00693                 } else { // if (edgeNum[3])
00694                    if (edgeNum[1]== x1) break;
00695                 } // if (edgeNum[3])
00696           } else { // if (edgeNum[2])
00697             if (edgeNum[3]) {
00698                    if (edgeNum[0]== y0) break;
00699                 } else { // if (edgeNum[3])
00700                    if (edgeNum[0]== y1) break;
00701                 } // if (edgeNum[3])
00702           } // if (edgeNum[2])
00703         }
00704     
00705 //      find next point
00706         memcpy( edgeNumP, edgeNum, sizeof(edgeNumP)); // save previous edge
00707   MD1(fprintf(stderr," --- exportIsolineCoord: edgeNum=[%d %d %d %d]\r\n", edgeNum[0], edgeNum[1], edgeNum[2], edgeNum[3]));
00708 
00709         found= findNextEdge  (edgeNum, x0, y0, x1, y1, edArr);
00710   MD1(fprintf(stderr,"findNextEdge () returned %d, edgeNum=[%d %d %d %d]\r\n",found, edgeNum[0], edgeNum[1], edgeNum[2], edgeNum[3]));
00711 
00712 // erase previous edge (if not first in closed mode)
00713     if ((nPoints) || !closed) edArr[edgeNumP[0]][edgeNumP[1]][edgeNumP[2]]=-1;
00714 // break here in "closed" mode if new edge is the same as the starting one
00715     if (closed && (edgeNum[0]==edgeNumS[0]) && (edgeNum[1]==edgeNumS[1]) && (edgeNum[2]==edgeNumS[2]))  break;
00716         nPoints++;
00717   }// while (1)
00718   MD1(fprintf(stderr," ---- exportIsolineCoord: edgeNum=[%d %d %d %d]\r\n", edgeNum[0], edgeNum[1], edgeNum[2], edgeNum[3]));
00719 
00720   edArr[edgeNum[0]][edgeNum[1]][edgeNum[2]]=-1; // erase start point in closed mode, last - in open
00721   return nOutPoints;
00722 }
00723 
00724 // will rely on DEF of Appearance
00725 int exportIsolineNode  (int level,
00726                                           int scaleX,   // multiply x by scaleX to get pixels
00727                                           int scaleY,   // multiply y by scaleY to get pixels
00728                                           int dcm,              // 1/10
00729                                           int indent, //if 0 - all will be 0, else - 1 per level
00730                                           const char * charZ,   // string representation of z (VRML-y) of the countour (0 or level)
00731                                           const char * Appearance,      // name of appearance to use (should be defined earlier)
00732                                           int x0, int y0, int x1, int y1, // window of interest
00733                                           int vert[MAX_VERTEX_Y][MAX_VERTEX_X],
00734                                           short edArr[MAX_VERTEX_Y+1][MAX_VERTEX_X+1][2]) {
00735   int edgeNum[]={0,0,0,0};
00736   int nIsolines=0;
00737   int found;
00738   int nl,i;
00739   char frmt[40];
00740   char ddi[]="%d";
00741   char ddf[]= "%d.%0";
00742   int printPos,printPosInc;
00743   edgeNum[0]=y0;
00744   edgeNum[1]=x0;
00745   MD1(fprintf(stderr,"exportIsolineNode:level= %x scaleX=%d, scaleY=%d, dcm=%d, indent=%d, charZ=%s, Appearance=%s, x0=%d, y0=%d, x1=%d, y1=%d\r\n",level, scaleX, scaleY, dcm, indent, charZ, Appearance, x0, y0, x1, y1));
00746 
00747 // prepare edges array, see if there is any Isoline
00748   i=fillEdgesArray (level, x0,  y0, x1,  y1, vert, edArr);
00749   MD1(fprintf(stderr,"fillEdgesArray returned %d\r\n",i));
00750 #ifdef DEBUG_CONT
00751   printEdgesArray (x1+1,y1+1, edArr);
00752 #endif
00753   if   (i==0) return 0;
00754   gzprintf(gzfile,"%sGroup {\n"
00755             "%schildren [\n",indentString(indent,0),indentString(indent,1));
00756   while ((found= findStartEdge  (edgeNum, x0, y0, x1, y1, edArr))) { // found=1 -"open", 2 - "closed"
00757     MD1(fprintf(stderr,"findStartEdge ([%d %d %d %d],...) returned %d\r\n",edgeNum[0],edgeNum[1],edgeNum[2],edgeNum[3],found));
00758 
00759     nIsolines++;
00760     gzprintf(gzfile,"%sShape {\n"
00761              "%sappearance USE %s\n"
00762              "%sgeometry IndexedLineSet {\n"
00763               "%scoord Coordinate { point [\n",
00764                 indentString(indent,2),
00765                 indentString(indent,3),Appearance,
00766                 indentString(indent,3),
00767                 indentString(indent,4));
00768 // prepare frmt;
00769     switch (dcm) {
00770       case 10:   {i=1;break;}
00771       case 100:  {i=2;break;} // not supported
00772       case 1000: {i=3;break;} // not supported
00773           default: {
00774             i=0;
00775             dcm=1;
00776           }
00777     }
00778     if (dcm==1) sprintf(frmt,"%s %s -%s", ddi, charZ, ddi);
00779     else                sprintf(frmt,"%s%dd %s -%s%dd", ddf, i, charZ, ddf, i);
00780     nl=exportIsolineCoord ((found==2), scaleX, scaleY,
00781                                   dcm,          // 1/10/100/1000 (should match format)
00782                                           (indent>=0)?(indent+5):-1,    // indentation
00783                                           frmt, // output format as "%d.%01d 123.4 -%d.%01d"
00784                                           edgeNum,      // will not be modified
00785                                           x0, y0, x1, y1, edArr);
00786     MD1(fprintf(stderr,"exportIsolineCoord (...) returned %d\r\n",nl));
00787         gzprintf(gzfile,"]\n%s}\n",indentString(indent,4));
00788     if (nl) { // export coordindex
00789       gzprintf(gzfile,"%scoordIndex [%n", indentString(indent,4),&printPos);
00790           for (i=0;i<nl;i++) {
00791         if (printPos>LINEWIDTH2BREAK) gzprintf(gzfile,"\n%s%n", indentString(indent,5),&printPos); // limit long lines
00792         gzprintf(gzfile,"%d,%n",i,&printPosInc);
00793         printPos+=printPosInc;
00794           }
00795           if (found==2) gzprintf(gzfile,"0,");
00796           gzprintf(gzfile,"-1]\n");
00797         }
00798         gzprintf(gzfile,"%s}\n%s}\n", indentString(indent,3), indentString(indent,2)); // close IndexedLineSet, Shape
00799 
00800   } // while ((found= findStartEdge  (edgeNumS, x0, y0, x1, y1, edArr)))
00801   gzprintf(gzfile,"%s]}\n",indentString(indent,0));  // close children, Group
00802   return nIsolines;
00803 }
00804 void exportVRMLStart(int level) { // compression level - 0..9 (o - plain text)
00805 // Start VRML file, output constant portions
00806   char mode[3];
00807   if (level<0) level=0;
00808   if (level>9) level=9;
00809   sprintf(mode,"w%d",level);
00810   MD2(fprintf(stderr,"exportVRMLStart level= %d mode=%s\r\n",level, mode));
00811 
00812   printf("Content-Type: x-world/x-vrml\n\n"); // 2 new lines!
00813 // now start the compressor
00814     gzfile = gz_useFile (stdout, mode); // modified to shortcut gzprintf to printf if "w0"
00815     if (gzfile == NULL) {
00816         fprintf(stderr, "gzdopen error\n");
00817         exit(1);
00818     }
00819     gzprintf(gzfile,"#VRML V2.0 utf8\n" \
00820                  "# generated by Elphel Model 303 camera, http://www.elphel.com\n" \
00821                  "\n" \
00822                  "NavigationInfo {\n" \
00823                  "      type       [\"EXAMINE\", \"ANY\"]" \
00824                  "      avatarSize [2.5, 16, 7.5]\n" \
00825                  "      speed      100.0\n" \
00826                  "      headlight  TRUE\n" \
00827                  "}\n" );
00828 
00829 }
00830 void exportVRMLViewpoints(int width, int height, int elev) {
00831 
00832 // output 4 corner viewpoints and two top ones
00833   int camheight=elev>>1;
00834   gzprintf(gzfile,"DEF VP00 Viewpoint {\n" \
00835                  "  fieldOfView 0.75\n"\
00836                  "  orientation 0 1 0 -0.785398\n" \
00837                  "  position %d %d %d\n" \
00838                  "  description \"View from x- y-\"\n" \
00839                  "}\n",-width,camheight,height);
00840   gzprintf(gzfile,"DEF VP10 Viewpoint {\n" \
00841                  "  fieldOfView 0.75\n"\
00842                  "  orientation 0 1 0 0.785398\n" \
00843                  "  position %d %d %d\n" \
00844                  "  description \"View from x+ y-\"\n" \
00845                  "}\n",width+width,camheight,height);
00846   gzprintf(gzfile,"DEF VP11 Viewpoint {\n" \
00847                  "  fieldOfView 0.75\n"\
00848                  "  orientation 0 1 0 2.356194\n" \
00849                  "  position %d %d %d\n" \
00850                  "  description \"View from x+ y+\"\n" \
00851                  "}\n",width+width,camheight,-height-height);
00852   gzprintf(gzfile,"DEF VP01 Viewpoint {\n" \
00853                  "  fieldOfView 0.75\n"\
00854                  "  orientation 0 1 0 -2.356194\n" \
00855                  "  position %d %d %d\n" \
00856                  "  description \"View from x- y+\"\n" \
00857                  "}\n",-width,camheight,-height-height);
00858   gzprintf(gzfile,"DEF VPTOP Viewpoint {\n" \
00859                  "  fieldOfView 0.75\n"\
00860                  "  orientation 1 0 0 -1.570796\n" \
00861                  "  position %d %d %d\n" \
00862                  "  description \"Top view\"\n" \
00863                  "}\n",width>>1,elev*2,-(height>>1));
00864   gzprintf(gzfile,"DEF VPTOPFAR Viewpoint {\n" \
00865                  "  fieldOfView 0.025\n"\
00866                  "  orientation 1 0 0 -1.570796\n" \
00867                  "  position %d %d %d\n" \
00868                  "  description \"Far top view\"\n" \
00869                  "}\n",width>>1,elev*60,-(height>>1));
00870 }
00871 
00872 
00873 
00874 // ****************************************************
00875 //returns <0 - errror, (vertNum_x & 0xfff) | ((vertNum_y & 0xfff) << 12) if OK
00876 int initVertexArray (const char * dmaFileName,
00877                                         int     width,
00878                                         int height,
00879                                         int maxpixel,   // maximal pixel (full scale -= 1024, 0 - auto normalize)
00880                                         int decimate_x, // rectangle width to be combined in one vertex
00881                                         int decimate_y, // rectangle height to be combined in one vertex
00882                                         int vert[MAX_VERTEX_Y][MAX_VERTEX_X] // vertex array
00883                                         ) {
00884 //#define MAX_VERTEX_X 161
00885 //#define MAX_VERTEX_Y 129
00886    int   vertNum_x;
00887    int   vertNum_y;
00888    int i,DMALongsPerRow,data_fd;
00889    unsigned long        * DMAData;  // opened through mmap
00890    int y,iy,x,ix,l,d,k;
00891 
00892 
00893    if ( (width>MAX_IMAGE_WIDTH) ||
00894         (width<=0) ||
00895             (height>MAX_IMAGE_HEIGHT) ||
00896         (height<=0) ) return -1;
00897    vertNum_x=   width/decimate_x;
00898    if (vertNum_x > MAX_VERTEX_X) {
00899      decimate_x=  width/MAX_VERTEX_X;
00900          if (decimate_x==0) decimate_x=1;
00901          if ((width/decimate_x) > MAX_VERTEX_X) decimate_x++;
00902          vertNum_x=     width/decimate_x;
00903    }
00904 
00905    vertNum_y=   height/decimate_y;
00906    if (vertNum_y > MAX_VERTEX_Y) {
00907      decimate_y=  height/MAX_VERTEX_Y;
00908          if (decimate_y==0) decimate_y=1;
00909          if ((height/decimate_y) > MAX_VERTEX_Y) decimate_y++;
00910          vertNum_y=     height/decimate_y;
00911    }
00912 
00913    i=width/3;
00914    DMALongsPerRow = (3*i == width)? i: i+1;
00915 //try open dmaFileName
00916    if ((data_fd = open(dmaFileName, O_RDONLY))==-1) return -2; // file open error
00917  MD(fprintf(stderr,"\r\n"));
00918         DMAData = (unsigned long *) mmap(0, (DMALongsPerRow*height)<<2, PROT_READ, MAP_OPTIONS, data_fd, 0);
00919    MD(fprintf(stderr,"vertNum_x - %d, vertNum_y -  %d, decimate_x - %d, decimate_y - %d\n",\
00920         vertNum_x, vertNum_y, decimate_x, decimate_y));
00921 
00922         if((int)(DMAData) == -1) { // Error in mmap
00923                 close(data_fd);
00924                 return -3;
00925         }
00926    MD(fprintf(stderr,"sizeof(vert) = %x\n",sizeof(vert)));
00927 // now prepare the integer vertex array
00928     memset (vert, 0,MAX_VERTEX_Y*MAX_VERTEX_X*4);
00929 
00930         for (y=0;y<vertNum_y;y++) {
00931           for (iy=0;iy<decimate_y;iy++){
00932 
00933             l=DMALongsPerRow*((vertNum_y-y-1)*decimate_y+iy);
00934             d=DMAData[l++];
00935             k=0;
00936             for (x=0;x<vertNum_x;x++) {
00937 //    if ((iy==0) &&(vert[y][x])) {
00938 //   MD(fprintf(stderr,"vert[%d][%d]= %d\n",y, x, vert[y][x]));
00939 //    }
00940               for (ix=0;ix<decimate_x;ix++){
00941                 vert[y][x]+=(d>>k)&0x3ff;
00942                 if ((k+=10)>20) {
00943                      k=0;
00944                      d=DMAData[l++];
00945                     }
00946                   }
00947 
00948             }
00949           }
00950         }
00951 // adjust maxpixel
00952   if (maxpixel >0) {
00953     if (maxpixel > 1024) maxpixel=1024;
00954         maxpixel=maxpixel*decimate_x*decimate_y;
00955   } else {
00956 // find maximum
00957         maxpixel=decimate_x*decimate_y;//to protect from 0-s
00958         for (y=0;y<vertNum_y;y++)
00959           for (x=0;x<vertNum_x;x++)
00960             if (vert[y][x] > maxpixel) maxpixel= vert[y][x];
00961   }
00962 //  normalize vert[y][x] to MYMAXINT
00963   i=0;
00964   while (maxpixel>0xffff) {
00965     maxpixel >>=1;
00966     i++;
00967   }
00968   k= MYMAXINT/maxpixel;
00969         for (y=0;y<vertNum_y;y++)
00970           for (x=0;x<vertNum_x;x++)
00971             vert[y][x]= k*(vert[y][x]>>i);
00972 
00973 // maximum height will be equal to maximum of 2 dimensions - change here if needed
00974    MD(fprintf(stderr,"vertNum_x - %d, vertNum_y -  %d, decimate_x - %d, decimate_y - %d\n",\
00975         vertNum_x, vertNum_y, decimate_x, decimate_y));
00976 
00977   return (vertNum_x & 0xfff) | ((vertNum_y & 0xfff) << 12);
00978 
00979 }
00980 
00981 
00982 void exportFacesAppearance(const char * aname, const char * mname, double transparency) {
00983   gzprintf(gzfile,"DEF %s Appearance {\n" \
00984                  " material DEF %s Material     {\n" \
00985                  "  transparency %f\n" \
00986                  " }\n" \
00987                  "}\n", aname, mname, transparency);
00988 }
00989 
00990 void exportIsolinesAppearance(const char * prefix, int numLev) {
00991  int i,l;
00992  char cs[20];
00993  gzprintf(gzfile,"DEF %s Group  {children [\n",prefix); 
00994  for (i=0;i<numLev;i++) {
00995    l=(2*i+1)*(MYMAXINT/(numLev<<1));
00996    gzprintf(gzfile," DEF %s_%d Appearance { material Material { emissiveColor %s }}\n",prefix,i,pseudoColorStr(cs,l));
00997  }
00998  gzprintf(gzfile,"]}\n"); 
00999 }
01000 void exportCoordinateSet(const char * name,
01001                                                  int width, int height, // number of vertexes is (width+1)*(height+1) !!
01002                                                  int elev,
01003                                                  int scale_X, int scale_Y,
01004                                                  int dcp,       // 0 or 1 only
01005                                                  int indent,
01006                                                  int vert[MAX_VERTEX_Y][MAX_VERTEX_X]) {
01007  int x,y,sx,sy,k;
01008  int zi,zf;
01009 
01010  if (dcp) {
01011     dcp=1;
01012         elev=10*elev;
01013  }
01014  k=(elev<<16)/(MYMAXINT>>16);
01015  gzprintf(gzfile,"DEF %s        Coordinate { point [\n",name);
01016  for (y=0;y<=height;y++) {
01017    sy=y*scale_Y;
01018    for (x=0;x<=width;x++) {
01019      sx=x*scale_X;
01020          zf=((vert[y][x]>>16)*k)>>16;
01021          if (dcp) {
01022            zi=zf/10;zf-=10*zi;
01023            gzprintf(gzfile,"%s%d 0 %d, %d %d.%01d %d",indentString(indent,1),sx,-sy,sx,zi,zf,-sy);
01024          } else { // if (dcp)
01025            gzprintf(gzfile,"%s%d 0 %d, %d %d %d",indentString(indent,1),sx,-sy,sx,zf,-sy);
01026          }  // if (dcp)
01027          if (x<width) gzprintf(gzfile,",\n");
01028    }
01029    if (y<height) gzprintf(gzfile,",\n");
01030  }
01031  gzprintf(gzfile,"]}\n");
01032 }
01033 void exportColorSet(const char * name,
01034                                         int width, int height,
01035                                         int indent,
01036                                         int vert[MAX_VERTEX_Y][MAX_VERTEX_X]) {
01037  int x,y;
01038  char bottomColor[20];
01039  char topColor[20];
01040  pseudoColorStr(bottomColor,0);
01041         
01042  gzprintf(gzfile,"DEF %s        Color {color[\n",name);
01043  for (y=0;y<=height;y++) {
01044    for (x=0;x<=width;x++) {
01045          gzprintf(gzfile,"%s%s, %s",indentString(indent,1), bottomColor, pseudoColorStr(topColor,vert[y][x]));
01046          if (x<width) gzprintf(gzfile,",\n");
01047    }
01048    if (y<height) gzprintf(gzfile,",\n");
01049  }
01050  gzprintf(gzfile,"]}\n");
01051 }
01052 
01053 void exportSwitchStart(const char * name, const char * suffics, int * ind) {
01054    gzprintf(gzfile,"%sDEF %s%s Switch {\n"
01055           "%swhichChoice 0\n"
01056           "%schoice [ Group {  children [\n",indentString(*ind,0),name, suffics,
01057                                                                                  indentString(*ind,1),
01058                                                                                  indentString(*ind,1));
01059   if (*ind>=0) *ind+=2;
01060 }
01061 
01062 void exportSwitchEnd(int * ind) {
01063   if (*ind>=0) *ind-=2;
01064    gzprintf(gzfile,"%s]}]\n"
01065           "%s}\n",indentString(*ind,1),
01066                                  indentString(*ind,0));
01067 }
01068 
01069 void exportTransformStart(const char * name, const char * suffics, int * ind) {
01070    if ((name) && (strlen(name)>0)) {
01071      gzprintf(gzfile,"%sDEF %s",indentString(*ind,0),name);
01072      if ((suffics) && (strlen(suffics)>0))      gzprintf(gzfile,"%s", suffics);
01073      gzprintf(gzfile," ");
01074    } else  gzprintf(gzfile,"%s",indentString(*ind,0));
01075    gzprintf(gzfile,"Transform {\n"
01076           "%sscale      1 1 1\n"
01077           "%schildren [\n", indentString(*ind,1),
01078                             indentString(*ind,1));
01079   if (*ind>=0) *ind+=2;
01080 }
01081 void exportTransformEnd(int * ind) {
01082   if (*ind>=0) *ind-=2;
01083    gzprintf(gzfile,"%s]\n"
01084           "%s}\n",indentString(*ind,1),
01085                   indentString(*ind,0));
01086 }
01087 
01088 
01089 void exportIFSStart       (const char * app,                       // name of Appearance to use (may be NULL)
01090                        const char * coord,                         // name of Coordinate to use (may NOT be NULL)
01091                                            const char * color,                     // name of Color to use              (may be NULL)
01092                                            int * ind) {                                    // address of indent value
01093    gzprintf(gzfile,"%sShape {\n",indentString(*ind,0));
01094    if (app) gzprintf(gzfile,"%sappearance USE %s\n",indentString(*ind,1),app);
01095    gzprintf(gzfile,"%sgeometry IndexedFaceSet {\n"
01096           "%sccw TRUE\n"
01097           "%ssolid TRUE\n"
01098           "%sconvex FALSE\n"
01099           "%scoord USE %s\n",indentString(*ind,1),
01100                                                  indentString(*ind,2),
01101                                                  indentString(*ind,2),
01102                                                  indentString(*ind,2),
01103                                                  indentString(*ind,2),coord);
01104    if (color) gzprintf(gzfile,"%scolor USE %s\n",indentString(*ind,2),color);
01105    gzprintf(gzfile,"%scoordIndex [\n",indentString(*ind,2));
01106 
01107   if (*ind>=0) *ind+=3;
01108 }
01109 
01110 void exportILSStart (const char * app,     // name of Appearance to use (may be NULL)
01111                      const char * coord,   // name of Coordinate to use (may NOT be NULL)
01112                      const char * color,   // name of Color to use      (may be NULL)
01113                      int * ind) {                                          // address of indent value
01114    gzprintf(gzfile,"%sShape {\n",indentString(*ind,0));
01115    if (app) gzprintf(gzfile,"%sappearance USE %s\n",indentString(*ind,1),app);
01116    gzprintf(gzfile,"%sgeometry IndexedLineSet {\n"
01117           "%scoord USE %s\n",indentString(*ind,1),
01118                                                  indentString(*ind,2),coord);
01119    if (color) gzprintf(gzfile,"%scolor USE %s\n",indentString(*ind,2),color);
01120    gzprintf(gzfile,"%scoordIndex [\n",indentString(*ind,2));
01121 
01122   if (*ind>=0) *ind+=3;
01123 }
01124 
01125 void exportIFLSEnd        (int * ind) {                                    // address of indent value
01126   if (*ind>=0) *ind-=3;
01127    gzprintf(gzfile,"]\n"
01128           "%s}\n"
01129           "%s}\n",indentString(*ind,1),
01130                    indentString(*ind,0));
01131 }
01132 
01133 
01134 void exportTopFaces   (int x0, int y0, int x1,int y1,  // window parameters
01135                        int rowLen,                                         // number of vertexes in a row
01136                        const char * app,                           // name of Appearance to use
01137                        const char * coord,                         // name of Coordinate to use
01138                                            const char * color,                     // name of Color to use
01139                                            int * ind) {                                    // address of indent value
01140   int x,y,i,j,d;
01141   exportIFSStart (app, coord, color,ind);
01142   d=rowLen<<1;
01143   for (y=y0;y<y1;y++) {
01144     i=((rowLen*y)<<1)+1;
01145     for (x=x0;x<x1;x++) {
01146 #if 0
01147 // "square" faces
01148       gzprintf(gzfile,"%s%d,%d,%d,%d,%d,-1",
01149                                    indentString(*ind,0),
01150                                    (j=(i+(x<<1))),
01151                                    j+2,
01152                                    j+2+d,
01153                                    j+d,
01154                                    j);
01155 #else
01156 // triangular faces
01157       gzprintf(gzfile,"%s%d,%d,%d,%d,-1,%d,%d,%d,%d,-1",
01158                                    indentString(*ind,0),
01159                                    (j=(i+(x<<1))),
01160                                    j+2,
01161                                    j+2+d,
01162                                    j,
01163                                    j,
01164                                    j+2+d,
01165                                    j+d,
01166                                    j);
01167 #endif
01168 
01169           if (x<(x1-1)) gzprintf(gzfile,",\n");
01170     } // for (x=x0;x<x1;x++)
01171         if (y<(y1-1)) gzprintf(gzfile,",\n");
01172   } // for (y=y0;y<y1;y++)
01173   exportIFLSEnd  (ind);
01174 }
01175 
01176 void exportBottomFaces(int x0, int y0, int x1,int y1,  // window parameters
01177                        int rowLen,                                         // number of vertexes in a row
01178                        const char * app,                           // name of Appearance to use
01179                        const char * coord,                         // name of Coordinate to use
01180                                            const char * color,                     // name of Color to use
01181                                            int * ind) {                                    // address of indent value
01182   exportIFSStart (app, coord, color,ind);
01183   gzprintf(gzfile,"%s%d,%d,%d,%d,%d,-1",
01184                               indentString(*ind,0),
01185                               (rowLen*y0+x0)<<1,
01186                               (rowLen*y1+x0)<<1,
01187                               (rowLen*y1+x1)<<1,
01188                               (rowLen*y0+x1)<<1,
01189                               (rowLen*y0+x0)<<1);
01190   exportIFLSEnd  (ind);
01191 }
01192 
01193 void exportSideFaces  (int x0, int y0, int x1,int y1,  // window parameters
01194                        int rowLen,                                         // number of vertexes in a row
01195                        const char * app,                           // name of Appearance to use
01196                        const char * coord,                         // name of Coordinate to use
01197                                            const char * color,                     // name of Color to use
01198                        int wallNum,                                        // wall number (0..3)
01199                                            int * ind) {                                    // address of indent value
01200   int i0,i1,di,n,j,i;
01201   int printPos,printPosInc;
01202   exportIFSStart (app, coord, color,ind);
01203   if ((wallNum>=0)  && (wallNum <=3)) {
01204     switch (wallNum) {
01205       case 0: {
01206             i0=(rowLen*y0+x0)<<1;
01207             i1=(rowLen*y0+x1)<<1;
01208             di=-2;
01209             n=x1-x0;
01210             break;}
01211       case 1: {
01212             i0=(rowLen*y0+x1)<<1;
01213             i1=(rowLen*y1+x1)<<1;
01214             di=-((rowLen)<<1);
01215             n=y1-y0;
01216             break;}
01217       case 2: {
01218             i0=(rowLen*y1+x1)<<1;
01219             i1=(rowLen*y1+x0)<<1;
01220             di=2;
01221             n=x1-x0;
01222             break;}
01223 //     case 3: {
01224       default: {
01225             i0=(rowLen*y1+x0)<<1;
01226             i1=(rowLen*y0+x0)<<1;
01227             di=(rowLen)<<1;
01228             n=y1-y0;
01229             break;}
01230     }
01231 //    gzprintf(gzfile,"%s%d,%d", indentString(*ind,0), i0,i1);
01232     gzprintf(gzfile,"%s%d,%d,%n", indentString(*ind,0), i0,i1,&printPos);
01233     i=i1+1;
01234     for (j=0; j<=n; j++) {
01235 //      if (!(j&0x3f)) gzprintf(gzfile,"\n%s", indentString(*ind,1)); // limit long lines
01236         if (printPos>LINEWIDTH2BREAK) gzprintf(gzfile,"\n%s%n", indentString(*ind,1),&printPos); // limit long lines
01237 //      gzprintf(gzfile,"%d,",i+=di);
01238 //      gzprintf(gzfile,"%d,",i); i+=di;
01239       gzprintf(gzfile,"%d,%n",i,&printPosInc);
01240       printPos+=printPosInc;
01241       i+=di;
01242     }
01243     gzprintf(gzfile,"%d,-1", i0);
01244   } // if ((wallNum>=0)  && (wallNum <=3))
01245   exportIFLSEnd  (ind);
01246 }
01247 
01248 void exportTopEdges   (int x0, int y0, int x1,int y1,  // window parameters
01249                        int rowLen,                                         // number of vertexes in a row
01250                        const char * coord,                         // name of Coordinate to use
01251                                            const char * color,                     // name of Color to use
01252                                            int * ind) {                                    // address of indent value
01253   int x,y,i,j,di;
01254   int printPos,printPosInc;
01255 
01256   exportILSStart   (NULL, coord, color,ind);
01257   for (y=y0;y<=y1;y++) {
01258     i=((rowLen*y+x0)<<1)+1;
01259     gzprintf(gzfile,"\n%s%n", indentString(*ind,0), &printPos);
01260     for (j=1;j<=(x1-x0+1);j++) {
01261       if (printPos>LINEWIDTH2BREAK) gzprintf(gzfile,"\n%s%n", indentString(*ind,1),&printPos); // limit long lines
01262       gzprintf(gzfile,"%d,%n",i,&printPosInc);
01263       printPos+=printPosInc;
01264       i+=2;
01265         }
01266         gzprintf(gzfile,"-1");
01267   }
01268 
01269   di=rowLen<<1;
01270   for (x=x0;x<=x1;x++) {
01271     i=((rowLen*y0+x)<<1)+1;
01272     gzprintf(gzfile,"\n%s%n", indentString(*ind,0), &printPos);
01273     for (j=1;j<=(y1-y0+1);j++) {
01274       if (printPos>LINEWIDTH2BREAK) gzprintf(gzfile,"\n%s%n", indentString(*ind,1),&printPos); // limit long lines
01275       gzprintf(gzfile,"%d,%n",i,&printPosInc);
01276       printPos+=printPosInc;
01277       i+=di;
01278         }
01279         gzprintf(gzfile,"-1");
01280   }
01281   exportIFLSEnd  (ind);
01282 }
01283 void exportBottomEdges(int x0, int y0, int x1,int y1,  // window parameters
01284                        int rowLen,                                         // number of vertexes in a row
01285                        const char * coord,                         // name of Coordinate to use
01286                                            const char * color,                     // name of Color to use
01287                                            int * ind) {                                    // address of indent value
01288   exportILSStart (NULL, coord, color,ind);
01289   gzprintf(gzfile,"%s%d,%d,%d,%d,%d,-1",
01290                                    indentString(*ind,0),
01291                                                            (rowLen*y0+x0)<<1,
01292                                                            (rowLen*y1+x0)<<1,
01293                                                            (rowLen*y1+x1)<<1,
01294                                                            (rowLen*y0+x1)<<1,
01295                                                            (rowLen*y0+x0)<<1);
01296   exportIFLSEnd  (ind);
01297 }
01298 
01299 void exportSideEdges   (int x0, int y0, int x1,int y1,  // window parameters
01300                        int rowLen,                                         // number of vertexes in a row
01301                        const char * coord,                         // name of Coordinate to use
01302                                            const char * color,                     // name of Color to use
01303                        int wallNum,                                        // wall number (0..3)        
01304                                            int * ind) {                                    // address of indent value   
01305   int i,di,n,j;                                         
01306   exportILSStart (NULL, coord, color,ind);
01307 
01308   if ((wallNum>=0)  && (wallNum <=3)) {
01309     switch (wallNum) {
01310       case 0: {
01311             i=(rowLen*y0+x0)<<1;
01312             di=2;
01313             n=x1-x0;
01314             break;}
01315       case 1: {
01316             i=(rowLen*y0+x1)<<1;
01317             di=((rowLen)<<1);
01318             n=y1-y0;
01319             break;}
01320       case 2: {
01321             i=(rowLen*y1+x1)<<1;
01322             di=-2;
01323             n=x1-x0;
01324             break;}
01325 //      case 3: {
01326       default: {
01327             i=(rowLen*y1+x0)<<1;
01328             di=-((rowLen)<<1);
01329             n=y1-y0;
01330             break;}
01331     }
01332     for (j=0; j<n; j++) {
01333       gzprintf(gzfile,"%s%d,%d,-1,\n", indentString(*ind,0), i, (i+=di)+1);
01334         }
01335     gzprintf(gzfile,  "%s%d,%d,-1", indentString(*ind,0), i, i+1);
01336   } // if ((wallNum>=0)  && (wallNum <=3))
01337   exportIFLSEnd  (ind);
01338 }
01339 
01340 
01341 //**********************************************
01342 int export_vrml (const char * dmaFileName,
01343                  int width,
01344                  int height,
01345                  int maxpixel,       // maximal pixel (full scale -= 1024, 0 - auto normalize)
01346                  int decimate_x,     // rectangle width to be combined in one vertex
01347                  int decimate_y,     // rectangle height to be combined in one vertex
01348                  int blocks_x,       // number of separate blocks in x direction
01349                  int blocks_y,       // number of separate blocks in y direction
01350                  int indent,         // VRML text indentation (0/1)
01351                  int dcp,            // number of coordinate digits after "." - 0,1,2,3
01352                  int nIsolines,      // number of isolines to build
01353                  int genFlatIso,     // 0/1, generate flat isolines with Z=0
01354                  int genElevIso,     // 0/1, generate elevated isolines with Z matching intensity
01355                  const char * colors, // string of pseudocolors, i.e "BR" or "mbcgyr" or "546231" 
01356                  int compressionLevel // gzip compression level for VRML file (0 - plain text out)
01357                  ) {
01358    
01359 //#define MAX_VERTEX_X 161
01360 //#define MAX_VERTEX_Y 129
01361    int   vert[MAX_VERTEX_Y][MAX_VERTEX_X];
01362    short edArr[MAX_VERTEX_Y+1][MAX_VERTEX_X+1][2];
01363 
01364    char s[256];
01365    char s1[256];
01366    int   elev,i,j,l,level;
01367 
01368    int   vertNum_x;
01369    int   vertNum_y;
01370    int   x0,x1,y0,y1,zf,zi;
01371 
01372    MD(fprintf(stderr,"&vert[0][0] = %x, &edArr[0][0][0] = %x\r\n", (int) &vert[0][0], (int) &edArr[0][0][0]));
01373 
01374 
01375 // change indent 0(no) ->-1, >0(yes)->0
01376    indent=indent?0:-1;
01377 // set nIsolines=0 if none are selected
01378    if (!genFlatIso && !genElevIso) nIsolines=0;
01379    if (nIsolines==0) {genFlatIso=0; genElevIso=0;}
01380    MD(fprintf(stderr,"dmaFileName- %s, width - %d, height -  %d, decimate_x - %d, decimate_y - %d, blocks_x - %d, blocks_y - %d\r\n",\
01381                                         dmaFileName,width,height,decimate_x, decimate_y, blocks_x, blocks_y));
01382 // fix decimation/number of blocks
01383    if (decimate_x <1) decimate_x=1;
01384    if (decimate_y <1) decimate_y=1;
01385    if (blocks_x    <1) blocks_x=   1;
01386    if (blocks_y    <1) blocks_y=   1;
01387 // build vertex array normalized to MYMAXINT, return if error
01388 //returns <0 - errror, (vertNum_x & 0xfff) | ((vertNum_y & 0xfff) << 12) if OK
01389    if ((i= initVertexArray (dmaFileName,        width, height, maxpixel, decimate_x,  decimate_y, vert))<0) return i;
01390    vertNum_x= i & 0xfff;
01391    vertNum_y= (i>>12) & 0xfff;
01392 
01393 // adjust height and width to get rid of partial rectangles (after DMALongsPerRow calculation)
01394    width= (vertNum_x-1)*decimate_x;
01395    height=(vertNum_y-1)*decimate_y;
01396 
01397 // maximum height will be equal to maximum of 2 dimensions - change here if needed
01398    elev=(height>width)?height:width;
01399    MD(fprintf(stderr,"vertNum_x - %d, vertNum_y -  %d, decimate_x - %d, decimate_y - %d\n",\
01400         vertNum_x, vertNum_y, decimate_x, decimate_y));
01401 // init pseudo color structure
01402   initPseudoColor(colors);
01403 // Start VRML file, output constant part
01404   exportVRMLStart(compressionLevel); // gzip compression level for VRML file (0 - plain text out)
01405 // output WorldInfo
01406  gzprintf(gzfile,"DEF WORLDINFO WorldInfo {\n" \
01407         " title  \"Elphel Model 303 3D visualization\"\n" \
01408                 " info [\n" \
01409                 "  \"width=     %4d\", # number of image pixels used (x direction)\n" \
01410                 "  \"height=    %4d\", # number of image pixels used (y direction)\n" \
01411                 "  \"maxpixel=  %4d\", # maximal pixel (full scale -= 1024, 0 - auto normalize)\n" \
01412                 "  \"decimate_x=%4d\", # rectangle width to be combined in one vertex\n" \
01413                 "  \"decimate_y=%4d\", # rectangle height to be combined in one vertex\n" \
01414                 "  \"blocks_x=  %4d\", # number of separate blocks in x direction\n" \
01415                 "  \"blocks_y=  %4d\", # number of separate blocks in y direction\n" \
01416                 "  \"indent=    %4d\", # VRML text indentation (0/1)\n" \
01417                 "  \"dcp=       %4d\", # number of coordinate digits after \".\" - 0,1(,2,3)\n" \
01418                 "  \"nIsolines= %4d\", # number of isolines to build\n" \
01419                 "  \"genFlatIso=%4d\", # generate flat isolines with Z=0\n" \
01420                 "  \"genElevIso=%4d\", # generate elevated isolines lines with Z matching intensity\n" \
01421                 "  \"colors=    %s\", # string of pseudocolors, i.e \"BR\" or \"mbcgyr\" or \"546231\"\n" \
01422                 "  \"vertNum_x= %4d\", # model grid X size\n" \
01423                 "  \"vertNum_y= %4d\"  # model grid Y size\n" \
01424                 " ]\n}\n",
01425                   width,
01426                   height,
01427                   maxpixel,
01428                   decimate_x,
01429                   decimate_y,
01430                   blocks_x,
01431                   blocks_y,
01432                   indent,
01433                   dcp,
01434                   nIsolines,
01435                   genFlatIso,
01436                   genElevIso,
01437                   colors,
01438                   vertNum_x,
01439                   vertNum_y
01440                 );
01441 
01442 
01443 // output viewpoints
01444   exportVRMLViewpoints(width, height, elev);
01445   exportFacesAppearance("APP_FACES","MAT_FACES",0.2);
01446   if (nIsolines>0) exportIsolinesAppearance("APP_ISO", nIsolines);
01447   exportCoordinateSet("COORD_SET", vertNum_x-1, vertNum_y-1, elev, decimate_x, decimate_y, dcp, indent, vert);
01448   exportColorSet     ("COLOR_SET", vertNum_x-1, vertNum_y-1, indent, vert);
01449 // enclose all geometry in "Transform" node to allow scaling everything
01450   exportTransformStart("ALL_GEOMETRY","", &indent);
01451 // start switch that will allow to turn off all but isolines geometry
01452   exportSwitchStart("BLOCKS","", &indent);
01453 // now iterate through all blocks
01454   for (i=0;i<blocks_y;i++) for (j=0;j<blocks_x;j++){
01455 // overlapping corners of the blocks
01456     y0=(i*    (vertNum_y-1))/blocks_y;
01457         y1=((i+1)*(vertNum_y-1))/blocks_y;
01458     x0=(j*    (vertNum_x-1))/blocks_x;
01459         x1=((j+1)*(vertNum_x-1))/blocks_x;
01460         sprintf(s,"BLOCK_%d_%d",i,j);
01461     exportSwitchStart(s, "",&indent); // "BLOCK_yy_xx"
01462 // export top geometry
01463       exportSwitchStart(s, "_TOP",&indent); // "BLOCK_yy_xx_TOP"
01464            exportTopFaces(x0,y0,x1,y1,vertNum_x,"APP_FACES","COORD_SET","COLOR_SET",&indent);
01465            exportTopEdges(x0,y0,x1,y1,vertNum_x,"COORD_SET","COLOR_SET",&indent);
01466       exportSwitchEnd( &indent); // "BLOCK_yy_xx_TOP"
01467 // export bottom geometry
01468       exportSwitchStart(s, "_BOTTOM",&indent); // "BLOCK_yy_xx_BOTTOM"
01469            exportBottomFaces(x0,y0,x1,y1,vertNum_x,"APP_FACES","COORD_SET","COLOR_SET",&indent);
01470            exportBottomEdges(x0,y0,x1,y1,vertNum_x,"COORD_SET","COLOR_SET",&indent);
01471       exportSwitchEnd( &indent); // "BLOCK_yy_xx_BOTTOM"
01472 // export side walls
01473       exportSwitchStart(s, "_Y0",&indent); // "BLOCK_yy_xx_Y0"
01474            exportSideFaces(x0,y0,x1,y1,vertNum_x,"APP_FACES","COORD_SET","COLOR_SET",0,&indent);
01475            exportSideEdges(x0,y0,x1,y1,vertNum_x,"COORD_SET","COLOR_SET",0,&indent);
01476       exportSwitchEnd( &indent); // "BLOCK_yy_xx_Y0"
01477 
01478       exportSwitchStart(s, "_X1",&indent); // "BLOCK_yy_xx_X1"
01479            exportSideFaces(x0,y0,x1,y1,vertNum_x,"APP_FACES","COORD_SET","COLOR_SET",1,&indent);
01480            exportSideEdges(x0,y0,x1,y1,vertNum_x,"COORD_SET","COLOR_SET",1,&indent);
01481       exportSwitchEnd( &indent); // "BLOCK_yy_xx_X1"
01482 
01483       exportSwitchStart(s, "_Y1",&indent); // "BLOCK_yy_xx_Y1"
01484            exportSideFaces(x0,y0,x1,y1,vertNum_x,"APP_FACES","COORD_SET","COLOR_SET",2,&indent);
01485            exportSideEdges(x0,y0,x1,y1,vertNum_x,"COORD_SET","COLOR_SET",2,&indent);
01486       exportSwitchEnd( &indent); // "BLOCK_yy_xx_Y1"
01487 
01488       exportSwitchStart(s, "_X0",&indent); // "BLOCK_yy_xx_X0"
01489            exportSideFaces(x0,y0,x1,y1,vertNum_x,"APP_FACES","COORD_SET","COLOR_SET",3,&indent);
01490            exportSideEdges(x0,y0,x1,y1,vertNum_x,"COORD_SET","COLOR_SET",3,&indent);
01491       exportSwitchEnd( &indent); // "BLOCK_yy_xx_X0"
01492     exportSwitchEnd( &indent); // "BLOCK_yy_xx"
01493   } // for (i=0;i<blocks_y;i++) for (j=0;j<blocks_x;j++)
01494   exportSwitchEnd( &indent); // "BLOCKS"
01495 
01496 /*
01497  int genFlatIso, // 0/1, generate flat isolines with Z=0
01498  int genElevIso, // 0/1, generate elevated isolines with Z matching intensity
01499 
01500 */
01501   if (genFlatIso) {
01502     MD(fprintf(stderr,"export_vrml: flat isolines\r\n"));
01503     exportSwitchStart("ISO_FLAT", "",&indent); // "ISO_FLAT"
01504     for (i=0;i<blocks_y;i++) for (j=0;j<blocks_x;j++){
01505 // overlapping corners of the blocks
01506       y0=(i*    (vertNum_y-1))/blocks_y;
01507           y1=((i+1)*(vertNum_y-1))/blocks_y;
01508       x0=(j*    (vertNum_x-1))/blocks_x;
01509           x1=((j+1)*(vertNum_x-1))/blocks_x;
01510           sprintf(s,"ISO_FLAT_%d_%d",i,j);
01511       exportSwitchStart(s, "",&indent); // "ISO_FLAT_yy_xx"
01512           for (l=0;l<nIsolines;l++) {
01513         level=(2*l+1)*(MYMAXINT/(nIsolines<<1));
01514                 sprintf(s,"APP_ISO_%d",l);
01515         exportIsolineNode  (level,
01516                                                   decimate_x, decimate_y,
01517                                               dcp?10:0,                                 // 1/10
01518                                               indent,                                   // if -1 - all will be 0, else - 1 per level
01519                                               "0",                                              // string representation of z (VRML-y) of the countour (0 or level)
01520                                               s,                                                // name of appearance to use (should be defined earlier)
01521                                               x0, y0, x1, y1,                   // window of interest
01522                                               vert,                                             // array of vertex Z values
01523                                               edArr);
01524           }
01525       exportSwitchEnd( &indent); // "ISO_FLAT_yy_xx"
01526     } // for (i=0;i<blocks_y;i++) for (j=0;j<blocks_x;j++)
01527     exportSwitchEnd( &indent); // "ISO_FLAT"
01528   } // if (genFlatIso)
01529   if (genElevIso) {
01530     MD(fprintf(stderr,"export_vrml: elevated isolines\r\n"));
01531     exportSwitchStart("ISO_ELEV", "",&indent); // "ISO_ELEV"
01532     for (i=0;i<blocks_y;i++) for (j=0;j<blocks_x;j++){
01533 // overlapping corners of the blocks
01534       y0=(i*    (vertNum_y-1))/blocks_y;
01535           y1=((i+1)*(vertNum_y-1))/blocks_y;
01536       x0=(j*    (vertNum_x-1))/blocks_x;
01537           x1=((j+1)*(vertNum_x-1))/blocks_x;
01538           sprintf(s,"ISO_ELEV_%d_%d",i,j);
01539       exportSwitchStart(s, "",&indent); // "ISO_ELEV_yy_xx"
01540           for (l=0;l<nIsolines;l++) {
01541         level=(2*l+1)*(MYMAXINT/(nIsolines<<1));
01542                 sprintf(s,"APP_ISO_%d",l);
01543                 if (dcp) {
01544                   zf=((level>>16)*(((elev*10)<<16)/(MYMAXINT>>16)))>>16;
01545               zi=zf/10;
01546               zf-=10*zi;
01547                   sprintf(s1,"%d.%01d",zi,zf); 
01548                 } else { // if (dcp)
01549                   zf=((level>>16)*(( elev    <<16)/(MYMAXINT>>16)))>>16;
01550                   sprintf(s1,"%d",zf); 
01551                 } // if (dcp)
01552         exportIsolineNode  (level,
01553                                                   decimate_x, decimate_y,
01554                                               dcp?10:0,                                 // 1/10
01555                                               indent,                                   // if -1 - all will be 0, else - 1 per level
01556                                               s1,                                               // string representation of z (VRML-y) of the countour (0 or level)
01557                                               s,                                                // name of appearance to use (should be defined earlier)
01558                                               x0, y0, x1, y1,                   // window of interest
01559                                               vert,                                             // array of vertex Z values
01560                                               edArr);
01561           }
01562       exportSwitchEnd( &indent); // "ISO_ELEV_yy_xx"
01563     } // for (i=0;i<blocks_y;i++) for (j=0;j<blocks_x;j++)
01564 
01565     exportSwitchEnd( &indent); // "ISO_ELEV"
01566   } // if (genElevIso)
01567   exportTransformEnd( &indent); // "ALL_GEOMETRY"
01568   gzclose(gzfile);
01569 
01570   return 0; // all OK
01571 }
01572 

Generated on Thu Aug 7 16:18:59 2008 for elphel by  doxygen 1.5.1