ann2fig.cpp

Go to the documentation of this file.
00001 //----------------------------------------------------------------------
00002 // File:                        ann2fig.cpp
00003 // Programmer:          David Mount
00004 // Last modified:       05/03/05
00005 // Description:         convert ann dump file to fig file
00006 //----------------------------------------------------------------------
00007 // Copyright (c) 1997-2005 University of Maryland and Sunil Arya and
00008 // David Mount.  All Rights Reserved.
00009 // 
00010 // This software and related documentation is part of the Approximate
00011 // Nearest Neighbor Library (ANN).  This software is provided under
00012 // the provisions of the Lesser GNU Public License (LGPL).  See the
00013 // file ../ReadMe.txt for further information.
00014 // 
00015 // The University of Maryland (U.M.) and the authors make no
00016 // representations about the suitability or fitness of this software for
00017 // any purpose.  It is provided "as is" without express or implied
00018 // warranty.
00019 //----------------------------------------------------------------------
00020 // History:
00021 //      Revision 0.1  03/04/98
00022 //              Initial release
00023 //      Revision 1.0  04/01/05
00024 //              Changed dump file suffix from .ann to .dmp.
00025 //      Revision 1.1  05/03/05
00026 //              Fixed usage output string.
00027 //----------------------------------------------------------------------
00028 //      This program inputs an ann dump file of a search structure
00029 //      perhaps along with point coordinates, and outputs a fig (Ver 3.1)
00030 //      file (see fig2dev (1)) displaying the tree.  The fig file may
00031 //      then be displayed using xfig, or converted to any of a number of
00032 //      other formats using fig2dev.
00033 //
00034 //      If the dimension is 2 then the entire tree is display.  If the
00035 //      dimension is larger than 2 then the user has the option of
00036 //      selecting which two dimensions will be displayed, and the slice
00037 //      value for each of the remaining dimensions.  All leaf cells
00038 //      intersecting the slice are shown along with the points in these
00039 //      cells. See the procedure getArgs() below for the command-line
00040 //      arguments.
00041 //----------------------------------------------------------------------
00042 
00043 #include <cstdio>                                               // C standard I/O
00044 #include <fstream>                                              // file I/O
00045 #include <string>                                               // string manipulation
00046 #include <ANN/ANNx.h>                                   // all ANN includes
00047 
00048 using namespace std;                                    // make std:: accessible
00049 
00050 //----------------------------------------------------------------------
00051 // Globals and their defaults
00052 //----------------------------------------------------------------------
00053 
00054 const int               STRING_LEN              = 500;  // string lengths
00055 const int               MAX_DIM                 = 1000; // maximum dimension
00056 const double    DEF_SLICE_VAL   = 0;    // default slice value
00057 const char              FIG_HEAD[]              = {"#FIG 3.1"}; // fig file header
00058 const char              DUMP_SUFFIX[]   = {".dmp"};     // suffix for dump file
00059 const char              FIG_SUFFIX[]    = {".fig"};     // suffix for fig file
00060 
00061 char                    file_name[STRING_LEN];  // (root) file name (say xxx)
00062 char                    infile_name[STRING_LEN];// input file name (xxx.dmp)
00063 char                    outfile_name[STRING_LEN];// output file name (xxx.fig)
00064 char                    caption[STRING_LEN];    // caption line (= command line)
00065 ofstream                ofile;                                  // output file stream
00066 ifstream                ifile;                                  // input file stream
00067 int                             dim_x = 0;                              // horizontal dimension
00068 int                             dim_y = 1;                              // vertical dimension
00069 double                  slice_val[MAX_DIM];             // array of slice values
00070 double                  u_per_in = 1200;                // fig units per inch (version 3.1)
00071 double                  in_size = 5;                    // size of figure (in inches)
00072 double                  in_low_x = 1;                   // fig upper left corner (in inches)
00073 double                  in_low_y = 1;                   // fig upper left corner (in inches)
00074 double                  u_size = 6000;                  // size of figure (in units)
00075 double                  u_low_x = 1200;                 // fig upper left corner (in units)
00076 double                  u_low_y = 1200;                 // fig upper left corner (in units)
00077 int                             pt_size = 10;                   // point size (in fig units)
00078 
00079 int                             dim;                                    // dimension
00080 int                             n_pts;                                  // number of points
00081 ANNpointArray   pts = NULL;                             // point array
00082 
00083 double                  scale;                                  // scale factor for transformation
00084 double                  offset_x;                               // offsets for transformation
00085 double                  offset_y;
00086 
00087                                                                                 // transformations
00088 #define TRANS_X(p)              (offset_x + scale*(p[dim_x]))
00089 #define TRANS_Y(p)              (offset_y - scale*(p[dim_y]))
00090 
00091 //----------------------------------------------------------------------
00092 //      Error handler
00093 //----------------------------------------------------------------------
00094 
00095 void Error(char *msg, ANNerr level)
00096 {
00097         if (level == ANNabort) {
00098                 cerr << "ann2fig: ERROR------->" << msg << "<-------------ERROR\n";
00099                 exit(1);
00100         }
00101         else {
00102                 cerr << "ann2fig: WARNING----->" << msg << "<-------------WARNING\n";
00103         }
00104 }
00105 
00106 //----------------------------------------------------------------------
00107 // set_slice_val - set all slice values to given value
00108 //----------------------------------------------------------------------
00109 
00110 void set_slice_val(double val)
00111 {
00112         for (int i = 0; i < MAX_DIM; i++) {
00113                 slice_val[i] = val;
00114         }
00115 }
00116 
00117 //----------------------------------------------------------------------
00118 // getArgs - get input arguments
00119 //
00120 //              Syntax:
00121 //              ann2fig [-upi scale] [-x low_x] [-y low_y] 
00122 //                              [-sz size] [-dx dim_x] [-dy dim_y] [-sl dim value]*
00123 //                              [-ps pointsize]
00124 //                              file
00125 //              
00126 //              where:
00127 //                      -upi scale                      fig units per inch (default = 1200)
00128 //                      -x low_x                        x and y offset of upper left corner (inches)
00129 //                      -y low_y                        ...(default = 1)
00130 //                      -sz size                        maximum side length of figure (in inches)
00131 //                                                              ...(default = 5)
00132 //                      -dx dim_x                       horizontal dimension (default = 0)
00133 //                      -dy dim_y                       vertical dimension (default = 1)
00134 //                      -sv value                       default slice value (default = 0)
00135 //                      -sl dim value           each such pair defines the value along the
00136 //                                                              ...given dimension at which to slice.  This
00137 //                                                              ...may be supplied for all dimensions except
00138 //                                                              ...dim_x and dim_y.
00139 //                      -ps pointsize           size of points in fig units (def = 10)
00140 //                      file                            file (input=file.dmp, output=file.fig)
00141 //
00142 //----------------------------------------------------------------------
00143 
00144 void getArgs(int argc, char **argv)
00145 {
00146         int i;
00147         int sl_dim;                                                                     // temp slice dimension
00148         double sl_val;                                                          // temp slice value
00149 
00150         set_slice_val(DEF_SLICE_VAL);                           // set initial slice-values
00151 
00152         if (argc <= 1) {
00153                 cerr << "Syntax:\n\
00154         ann2fig [-upi scale] [-x low_x] [-y low_y]\n\
00155                 [-sz size] [-dx dim_x] [-dy dim_y] [-sl dim value]*\n\
00156                 file\n\
00157         \n\
00158         where:\n\
00159             -upi scale          fig units per inch (default = 1200)\n\
00160             -x low_x            x and y offset of upper left corner (inches)\n\
00161             -y low_y            ...(default = 1)\n\
00162             -sz size            maximum side length of figure (in inches)\n\
00163                                 ...(default = 5)\n\
00164             -dx dim_x           horizontal dimension (default = 0)\n\
00165             -dy dim_y           vertical dimension (default = 1)\n\
00166             -sv value           default slice value (default = 0)\n\
00167             -sl dim value       each such pair defines the value along the\n\
00168                                 ...given dimension at which to slice.  This\n\
00169                                 ...may be supplied for each dimension except\n\
00170                                 ...dim_x and dim_y.\n\
00171             -ps pointsize       size of points in fig units (def = 10)\n\
00172             file                file (input=file.dmp, output=file.fig)\n";
00173                 exit(0);
00174         }
00175 
00176         ANNbool fileSeen = ANNfalse;                            // file argument seen?
00177 
00178         for (i = 1; i < argc; i++) {
00179                 if (!strcmp(argv[i], "-upi")) {                 // process -upi option
00180                         sscanf(argv[++i], "%lf", &u_per_in);
00181                 }
00182                 else if (!strcmp(argv[i], "-x")) {              // process -x option
00183                         sscanf(argv[++i], "%lf", &in_low_x);
00184                 }
00185                 else if (!strcmp(argv[i], "-y")) {              // process -y option
00186                         sscanf(argv[++i], "%lf", &in_low_y);
00187                 }
00188                 else if (!strcmp(argv[i], "-sz")) {             // process -sz option
00189                         sscanf(argv[++i], "%lf", &in_size);
00190                 }
00191                 else if (!strcmp(argv[i], "-dx")) {             // process -dx option
00192                         sscanf(argv[++i], "%d", &dim_x);
00193                 }
00194                 else if (!strcmp(argv[i], "-dy")) {             // process -dy option
00195                         sscanf(argv[++i], "%d", &dim_y);
00196                 }
00197                 else if (!strcmp(argv[i], "-sv")) {             // process -sv option
00198                         sscanf(argv[++i], "%lf", &sl_val);
00199                         set_slice_val(sl_val);                          // set slice values
00200                 }
00201                 else if (!strcmp(argv[i], "-sl")) {             // process -sl option
00202                         sscanf(argv[++i], "%d", &sl_dim);
00203                         if (sl_dim < 0 || sl_dim >= MAX_DIM) {
00204                                 Error("Slice dimension out of bounds", ANNabort);
00205                         }
00206                         sscanf(argv[++i], "%lf", &slice_val[sl_dim]);
00207                 }
00208                 if (!strcmp(argv[i], "-ps")) {                  // process -ps option
00209                         sscanf(argv[++i], "%i", &pt_size);
00210                 }
00211                 else {                                                                  // must be file name
00212                         fileSeen = ANNtrue;
00213                         sscanf(argv[i], "%s", file_name);
00214                         strcpy(infile_name, file_name);         // copy to input file name
00215                 strcat(infile_name, DUMP_SUFFIX);
00216                 strcpy(outfile_name, file_name);        // copy to output file name
00217                 strcat(outfile_name, FIG_SUFFIX);
00218                 }
00219         }
00220 
00221         if (!fileSeen) {                                                        // no file seen
00222                 Error("File argument is required", ANNabort);
00223         }
00224 
00225         ifile.open(infile_name, ios::in);                       // open for reading
00226         if (!ifile) {
00227                 Error("Cannot open input file", ANNabort);
00228         }
00229         ofile.open(outfile_name, ios::out);                     // open for writing
00230         if (!ofile) {
00231                 Error("Cannot open output file", ANNabort);
00232         }
00233 
00234         u_low_x = u_per_in * in_low_x;                          // convert inches to fig units
00235         u_low_y = u_per_in * in_low_y;
00236         u_size  = u_per_in * in_size;
00237 
00238         strcpy(caption, argv[0]);                                       // copy command line to caption
00239         for (i = 1; i < argc; i++) {
00240                 strcat(caption, " ");
00241                 strcat(caption, argv[i]);
00242         }
00243 }
00244 
00245 //----------------------------------------------------------------------
00246 // Graphics utilities for fig output
00247 //
00248 //              writeHeader                             write header for fig file
00249 //              writePoint                              write a point
00250 //              writeBox                                write a box
00251 //              writeLine                               write a line
00252 //----------------------------------------------------------------------
00253 
00254 void writeHeader()
00255 {
00256         ofile << FIG_HEAD << "\n"                                       // fig file header
00257                  << "Portrait\n"
00258                  << "Center\n"
00259                  << "Inches\n"
00260                  << (int) u_per_in << " 2\n";
00261 }
00262 
00263 void writePoint(ANNpoint p)                                             // write a single point
00264 {
00265                                                                                                 // filled black point object
00266         ofile << "1 3 0 1 -1 7 0 0 0 0.000 1 0.0000 ";
00267         int cent_x = (int) TRANS_X(p);                          // transform center coords
00268         int cent_y = (int) TRANS_Y(p);
00269         ofile << cent_x << " " << cent_y << " "         // write center, radius, bounds
00270                  << pt_size << " " << pt_size << " "
00271                  << cent_x << " " << cent_y << " "
00272                  << cent_x + pt_size << " " << cent_y + pt_size << "\n";
00273 }
00274 
00275 void writeBox(const ANNorthRect &r)                             // write box
00276 {
00277                                                                                                 // unfilled box object
00278         ofile << "2 2 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 5\n";
00279 
00280         int p0_x = (int) TRANS_X(r.lo);                         // transform endpoints
00281         int p0_y = (int) TRANS_Y(r.lo);
00282         int p1_x = (int) TRANS_X(r.hi);
00283         int p1_y = (int) TRANS_Y(r.hi);
00284         ofile << "\t"
00285                  << p0_x << " " << p0_y << " "                  // write vertices
00286                  << p1_x << " " << p0_y << " "
00287                  << p1_x << " " << p1_y << " "
00288                  << p0_x << " " << p1_y << " "
00289                  << p0_x << " " << p0_y << "\n";
00290 }
00291 
00292 void writeLine(ANNpoint p0, ANNpoint p1)                // write line
00293 {
00294                                                                                                 // unfilled line object
00295         ofile << "2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 2\n";
00296 
00297         int p0_x = (int) TRANS_X(p0);                           // transform endpoints
00298         int p0_y = (int) TRANS_Y(p0);
00299         int p1_x = (int) TRANS_X(p1);
00300         int p1_y = (int) TRANS_Y(p1);
00301         ofile << "\t"
00302                  << p0_x << " " << p0_y << " "                  // write vertices
00303                  << p1_x << " " << p1_y << "\n";
00304 }
00305 
00306 void writeCaption(                                                              // write caption text
00307         const ANNorthRect       &bnd_box,                               // bounding box
00308         char                            *caption)                               // caption
00309 {
00310         if (!strcmp(caption, "\0")) return;                     // null string?
00311         int px = (int) TRANS_X(bnd_box.lo);                     // put .5 in. lower left
00312         int py = (int) (TRANS_Y(bnd_box.lo) + 0.50 * u_per_in); 
00313         ofile << "4 0 -1 0 0 0 20 0.0000 4 255 2000 ";
00314         ofile << px << " " << py << " " << caption << "\\001\n";
00315 }
00316 
00317 //----------------------------------------------------------------------
00318 // overlap - test whether a box overlap slicing region
00319 //
00320 //              The slicing region is a 2-dimensional plane in space
00321 //              which contains points (x1, x2, ..., xn) satisfying the
00322 //              n-2 linear equalities:
00323 //
00324 //                                              xi == slice_val[i]              for i != dim_x, dim_y
00325 //
00326 //              This procedure returns true of the box defined by
00327 //              corner points box.lo and box.hi overlap this plane.
00328 //----------------------------------------------------------------------
00329 
00330 ANNbool overlap(const ANNorthRect &box)
00331 {
00332         for (int i = 0; i < dim; i++) {
00333                 if (i != dim_x && i != dim_y &&
00334                    (box.lo[i] > slice_val[i] || box.hi[i] < slice_val[i]))
00335                         return ANNfalse;
00336         }
00337         return ANNtrue;
00338 }
00339 
00340 //----------------------------------------------------------------------
00341 // readTree, recReadTree - inputs tree and outputs figure
00342 //
00343 //              readTree procedure initializes things and then calls recReadTree
00344 //              which does all the work.
00345 //
00346 //              recReadTree reads in a node of the tree, makes any recursive
00347 //              calls as needed to input the children of this node (if internal)
00348 //              and maintains the bounding box.  Note that the bounding box
00349 //              is modified within this procedure, but it is the responsibility
00350 //              of the procedure that it be restored to its original value
00351 //              on return.
00352 //
00353 //              Recall that these are the formats.  The tree is given in
00354 //              preorder.
00355 //
00356 //              Leaf node:
00357 //                              leaf <n_pts> <bkt[0]> <bkt[1]> ... <bkt[n-1]>
00358 //              Splitting nodes:
00359 //                              split <cut_dim> <cut_val> <lo_bound> <hi_bound>
00360 //              Shrinking nodes:
00361 //                              shrink <n_bnds>
00362 //                                              <cut_dim> <cut_val> <side>
00363 //                                              <cut_dim> <cut_val> <side>
00364 //                                              ... (repeated n_bnds times)
00365 //
00366 //              On reading a leaf we determine whether we should output the
00367 //              cell's points (if dimension = 2 or this cell overlaps the
00368 //              slicing region).  For splitting nodes we check whether the
00369 //              current cell overlaps the slicing plane and whether the
00370 //              cutting dimension coincides with either the x or y drawing
00371 //              dimensions.  If so, we output the corresponding splitting
00372 //              segment.
00373 //----------------------------------------------------------------------
00374 
00375 void recReadTree(ANNorthRect &box)
00376 {
00377         char tag[STRING_LEN];                                           // tag (leaf, split, shrink)
00378         int n_pts;                                                                      // number of points in leaf
00379         int idx;                                                                        // point index
00380         int cd;                                                                         // cut dimension
00381         ANNcoord cv;                                                            // cut value
00382         ANNcoord lb;                                                            // low bound
00383         ANNcoord hb;                                                            // high bound
00384         int n_bnds;                                                                     // number of bounding sides
00385         int sd;                                                                         // which side
00386 
00387         ifile >> tag;                                                           // input node tag
00388         if (strcmp(tag, "leaf") == 0) {                         // leaf node
00389 
00390                 ifile >> n_pts;                                                 // input number of points
00391                                                                                                 // check for overlap
00392                 if (dim == 2 || overlap(box)) { 
00393                         for (int i = 0; i < n_pts; i++) {       // yes, write the points
00394                                 ifile >> idx;
00395                                 writePoint(pts[idx]);
00396                         }
00397                 }
00398                 else {                                                                  // input but ignore points
00399                         for (int i = 0; i < n_pts; i++) {
00400                                 ifile >> idx;
00401                         }
00402                 }
00403         }
00404         else if (strcmp(tag, "split") == 0) {           // splitting node
00405 
00406                 ifile >> cd >> cv >> lb >> hb;
00407                 if (lb != box.lo[cd] || hb != box.hi[cd]) {
00408                         Error("Bounding box coordinates are fishy", ANNwarn);
00409                 }
00410 
00411                 ANNcoord lv = box.lo[cd];                               // save bounds for cutting dim
00412                 ANNcoord hv = box.hi[cd];
00413 
00414                 //--------------------------------------------------------------
00415                 //      The following code is rather fragile so modify at your
00416                 //      own risk.  We first decrease the high-end of the bounding
00417                 //      box down to the cutting plane and then read the left subtree.
00418                 //      Then we increase the low-end of the bounding box up to the
00419                 //      cutting plane (thus collapsing the bounding box to a d-1
00420                 //      dimensional hyperrectangle).  Then we draw the projection of
00421                 //      its diagonal if it crosses the slicing plane.  This will have
00422                 //      the effect of drawing its intersection on the slicing plane.
00423                 //      Then we restore the high-end of the bounding box and read
00424                 //      the right subtree.  Finally we restore the low-end of the
00425                 //      bounding box, before returning.
00426                 //--------------------------------------------------------------
00427                 box.hi[cd] = cv;                                                // decrease high bounds
00428                 recReadTree(box);                                               // read left subtree
00429                                                                                                 // check for overlap
00430                 box.lo[cd] = cv;                                                // increase low bounds
00431                 if (dim == 2 || overlap(box)) {                 // check for overlap
00432                         if (cd == dim_x || cd == dim_y) {       // cut through slice plane
00433                                 writeLine(box.lo, box.hi);              // draw cutting line
00434                         }
00435                 }
00436                 box.hi[cd] = hv;                                                // restore high bounds
00437 
00438                 recReadTree(box);                                               // read right subtree
00439                 box.lo[cd] = lv;                                                // restore low bounds
00440         }
00441         else if (strcmp(tag, "shrink") == 0) {          // splitting node
00442 
00443                 ANNorthRect inner(dim, box);                    // copy bounding box
00444                 ifile >> n_bnds;                                                // number of bounding sides
00445                 for (int i = 0; i < n_bnds; i++) {
00446                         ifile >> cd >> cv >> sd;                        // input bounding halfspace
00447                         ANNorthHalfSpace hs(cd, cv, sd);        // create orthogonal halfspace
00448                         hs.project(inner.lo);                           // intersect by projecting
00449                         hs.project(inner.hi);
00450                 }
00451                 if (dim == 2 || overlap(inner)) {
00452                         writeBox(inner);                                        // draw inner rectangle
00453                 }
00454                 recReadTree(inner);                                             // read inner subtree
00455                 recReadTree(box);                                               // read outer subtree
00456         }
00457         else {
00458                 Error("Illegal node type in dump file", ANNabort);
00459         }
00460 }
00461 
00462 void readTree(ANNorthRect &bnd_box)
00463 {
00464         writeHeader();                                                          // output header
00465         writeBox(bnd_box);                                                      // draw bounding box
00466         writeCaption(bnd_box, caption);                         // write caption
00467         recReadTree(bnd_box);                                           // do it
00468 }
00469 
00470 //----------------------------------------------------------------------
00471 // readANN - read the ANN dump file
00472 //
00473 //              This procedure reads in the dump file.  See the format below.
00474 //              It first reads the header line with version number.  If the
00475 //              points section is present it reads them (otherwise just leaves
00476 //              points = NULL), and then it reads the tree section.  It inputs
00477 //              the bounding box and determines the parameters for transforming
00478 //              the image to figure units.  It then invokes the procedure
00479 //              readTree to do all the real work.
00480 //
00481 //              Dump File Format: <xxx> = coordinate value (ANNcoord)
00482 //
00483 //              #ANN <version number> <comments> [END_OF_LINE]
00484 //              points <dim> <n_pts>                    (point coordinates: this is optional)
00485 //              0 <xxx> <xxx> ... <xxx>                 (point indices and coordinates)
00486 //              1 <xxx> <xxx> ... <xxx>
00487 //                ...
00488 //              tree <dim> <n_pts> <bkt_size>
00489 //              <xxx> <xxx> ... <xxx>                   (lower end of bounding box)
00490 //              <xxx> <xxx> ... <xxx>                   (upper end of bounding box)
00491 //                              If the tree is null, then a single line "null" is
00492 //                              output.  Otherwise the nodes of the tree are printed
00493 //                              one per line in preorder.  Leaves and splitting nodes 
00494 //                              have the following formats:
00495 //              Leaf node:
00496 //                              leaf <n_pts> <bkt[0]> <bkt[1]> ... <bkt[n-1]>
00497 //              Splitting nodes:
00498 //                              split <cut_dim> <cut_val> <lo_bound> <hi_bound>
00499 //              Shrinking nodes:
00500 //                              shrink <n_bnds>
00501 //                                              <cut_dim> <cut_val> <side>
00502 //                                              <cut_dim> <cut_val> <side>
00503 //                                              ... (repeated n_bnds times)
00504 //
00505 //              Note: Infinite lo_ and hi_bounds are printed as the special
00506 //                              values "-INF" and "+INF", respectively.  We do not
00507 //                              check for this, because the current version of ANN
00508 //                              starts with a finite bounding box if the tree is
00509 //                              nonempty.
00510 //----------------------------------------------------------------------
00511 
00512 void readANN()
00513 {
00514         int j;
00515         char str[STRING_LEN];                                           // storage for string
00516     char version[STRING_LEN];                                   // storage for version
00517         int  bkt_size;                                                          // bucket size
00518 
00519         ifile >> str;                                                           // input header
00520         if (strcmp(str, "#ANN") != 0) {                         // incorrect header
00521                 Error("Incorrect header for dump file", ANNabort);
00522         }
00523     ifile.getline(version, STRING_LEN);                 // get version (ignore)
00524         ifile >> str;                                                           // get major heading
00525         if (strcmp(str, "points") == 0) {                       // points section
00526                 ifile >> dim;                                                   // read dimension
00527                 ifile >> n_pts;                                                 // number of points
00528                 pts = annAllocPts(n_pts, dim);                  // allocate points
00529                 for (int i = 0; i < n_pts; i++) {               // input point coordinates
00530                         int idx;                                                        // point index
00531                         ifile >> idx;                                           // input point index
00532                         if (idx < 0 || idx >= n_pts) {
00533                                 Error("Point index is out of range", ANNabort);
00534                         }
00535                         for (j = 0; j < dim; j++) {
00536                                 ifile >> pts[idx][j];                   // read point coordinates
00537                         }
00538                 }
00539                 ifile >> str;                                                   // get next major heading
00540         }
00541         if (strcmp(str, "tree") == 0) {                         // tree section
00542                 ifile >> dim;                                                   // read dimension
00543                 if (dim_x > dim || dim_y > dim) {
00544                         Error("Dimensions out of bounds", ANNabort);
00545                 }
00546                 ifile >> n_pts;                                                 // number of points
00547                 ifile >> bkt_size;                                              // bucket size (ignored)
00548                                                                                                 // read bounding box
00549                 ANNorthRect bnd_box(dim);                               // create bounding box
00550                 for (j = 0; j < dim; j++) {
00551                         ifile >> bnd_box.lo[j];                         // read box low coordinates
00552                 }
00553                 for (j = 0; j < dim; j++) {
00554                         ifile >> bnd_box.hi[j];                         // read box high coordinates
00555                 }
00556                                                                                                 // compute scaling factors
00557                 double box_len_x = bnd_box.hi[dim_x] - bnd_box.lo[dim_x];
00558                 double box_len_y = bnd_box.hi[dim_y] - bnd_box.lo[dim_y];
00559                                                                                                 // longer side determines scale
00560                 if (box_len_x > box_len_y) scale = u_size/box_len_x;
00561                 else                                       scale = u_size/box_len_y;
00562                                                                                                 // compute offsets
00563                 offset_x = u_low_x - scale*bnd_box.lo[dim_x];
00564                 offset_y = u_low_y + scale*bnd_box.hi[dim_y];
00565                 readTree(bnd_box);                                              // read the tree and process
00566         }
00567         else if (strcmp(str, "null") == 0) return;      // empty tree
00568         else {
00569                 cerr << "Input string: " << str << "\n";
00570                 Error("Illegal ann format.  Expecting section heading", ANNabort);
00571         }
00572 }
00573 
00574 //----------------------------------------------------------------------
00575 // Main program
00576 //
00577 // Gets the command-line arguments and invokes the main scanning
00578 // procedure.
00579 //----------------------------------------------------------------------
00580 
00581 int main(int argc, char **argv)
00582 {
00583         getArgs(argc, argv);                                            // get input arguments
00584         readANN();                                                                      // read the dump file
00585         return 0;
00586 }

Generated on Wed Nov 23 18:59:54 2011 for FreeCAD by  doxygen 1.6.1