meshmorph.cc

Go to the documentation of this file.
00001 #include "meshmorph.h"
00002 
00003 #include <iostream>
00004 #include <cassert>
00005 
00006 #include "controls.h"
00007 #include "misc.h"
00008 #include "vertex.h"
00009 #include "face.h"
00010 #include "edge.h"
00011 #include "object.h"
00012 #include "nice.h"
00013 #include "intersecting_faces.h"
00014 #include "container.h"
00015 #include "state.h"
00016 #include "box.h"
00017 #include "space.h"
00018 #include "vertex_schedule.h"
00019 #include "virtual_disp.h"
00020 #include "refractory.h"
00021 #include "gain_schedule.h"
00022 #include "log.h"
00023 
00024 using std::cout;
00025 using std::endl;
00026 
00027 int main (int argc,char **argv)
00028 {
00029   str message = "\n";
00030   message=message+
00031         "NAME\n"+
00032         "       meshmorph - move meshes to control extracellular space\n"+
00033         "\nSYNOPSIS\n"+
00034         "       meshmorph [options]\n"+
00035         "\nDESCRIPTION\n"+
00036         "       Meshmorph moves vertices one at a time to relax\n"+
00037         "       a spring model of the cell membranes.\n"+
00038         "\nEXAMPLES\n"+
00039         "       meshmorph -i input -o output -t 20 -s 10 -a 80 -f frozen_vertices.dat\n"+
00040         "              Read meshes from directory 'input' and write new morphed\n"+
00041         "              meshes to directory 'output'. The target extracellular width\n"+
00042         "              is 20 data units and the relative weights for extracellular\n"+
00043         "              width and edge angle are 10 and 80, respectively, out of 100.\n"+
00044         "              The vertices as specified in the file 'frozen_vertices.dat'\n"+
00045         "              in the form 'object_name vertex_index' (one vertex per file)\n"+
00046         "              are not to be moved.\n"+
00047         "\nOPTIONS\n"+
00048         "       -i DIRECTORY\n"+
00049         "              Directory containing input meshes.\n"+
00050         "              Default is current directory.\n\n"+
00051         "       -o DIRECTORY\n"+
00052         "              Directory where output meshes will be written.\n"+
00053         "              Default is current directory.\n\n"+
00054         "       -t NUM\n"+
00055         "              Target extracellular width:\n"+
00056         "              The meshes will try to be morphed so as to have\n"+
00057         "              an extracellular width of size NUM.\n"+
00058         "              Units are same as meshes in input directory.\n"+
00059         "              Default is 20.\n\n"+
00060         "       -s NUM\n"+
00061         "              Separation weight:\n"+
00062         "              The force generated on each vertex by deviations\n"+
00063         "              in the measured extracellular width from the desired\n"+
00064         "              extracellular width will be scaled by NUM/100.\n"+
00065         "              Note that the separation weight and angle weight\n"+
00066         "              must sum to 90, since the edge stretch weight and\n"+
00067         "              face intersection weight sum to 10, and the sum of all\n"+
00068         "              must be 100.\n"+
00069         "              Default is 10.\n\n"+
00070         "       -a NUM\n"+
00071         "              Angle weight:\n"+
00072         "              The force generated on each vertex by deviations\n"+
00073         "              in the measured angle of nearby edges from 180 degrees\n"+
00074         "              will be scaled by NUM/100.\n"+
00075         "              Note that the separation weight and angle weight\n"+
00076         "              must sum to 90, since the edge stretch weight and\n"+
00077         "              face intersection weight sum to 10, and the sum of all\n"+
00078         "              must be 100.\n"+
00079         "              Default is 80.\n\n"+
00080         "       -f FILE\n"+
00081         "              Frozen vertices file:\n"+
00082         "              The vertices specified in FILE will not be moved and will\n"+
00083         "              retain their original position from the input meshes.\n"+
00084         "              The format of FILE must be 'object_name vertex_index'.\n"+
00085         "              For example, 'd000 134' indicates that vertex number 134\n"+
00086         "              in object d000 should be frozen.\n"+
00087         "              Default behavior in the case that '-f' option is not used\n"+
00088         "              is to not freeze any vertices.\n\n"+
00089         "       -h\n"+
00090         "              Print meshalyzer man page.\n"+
00091         "\nJustin Kinney                                2008/05/01\n";
00092 
00093 
00094   // check that assumption of 32 bit int is correct
00095   assert(checkIntSize());
00096 
00097   // parse command line
00098   bool freeze = parseCommandLine(argc,argv,message);
00099 
00100   // create Log class
00101   Log & log(Log::instance());
00102 
00103   // new NUM_GROUPS rule
00104   // input mesh set has already been sufficiently morphed
00105   // so 50 groups should be enough
00106   //NUM_GROUPS = 50 + static_cast<int>(fabs(TARGET_SEPARATION-20));
00107 
00108   //GROUP_SIZE = Container::instance().getVertexCount();
00109   //GROUP_SIZE = 10000;
00110 
00111   // create container, objects, vertices, faces, edges, and find adjacencies
00112   Container::instance();
00113   log.recordTime("scanning file:");
00114 
00115   // copy control.cc to OUTPUT_DATA_DIR
00116   //copyControlFile();
00117 
00118   // read frozen vertices
00119   if(freeze==true){ Container::instance().readFrozen(FROZEN_VERTICES_FILE.c_str()); }
00120 
00121   // initialize space data structure
00122   Space::instance();
00123   log.recordTime("Initialize space data structure:");
00124 
00125   // assign faces to boxes
00126   Container::instance().assignFacesToBoxes();
00127   log.recordTime("Assign faces to boxes:");
00128   log.setPartitioningBoxStats();
00129   log.printPartitioningStats(cout);
00130 
00131   // initialize and write data to log files
00132   log.writeObjectData();
00133   log.recordTime("Writing data to log files:");
00134 
00135   // identify vertices that lie inside of another object
00136   Nice::instance().findNonniceVertices();
00137   log.recordTime("Find nice vertices:");
00138   log.printNumNonnice(cout);
00139 
00140   // find all face intersections
00141   Intersecting_Faces::instance().findAllFaceIntersections();
00142   log.recordTime("Find all face intersections:");
00143   log.printNumInt(cout);
00144   
00145   // identify the closest point on a mesh to each vertex
00146   Container::instance().findClosestFaceToEachVertex();
00147   log.recordTime("Get separation distances:");
00148   log.printClosestPtStats(cout);
00149 
00150   // DEBUG
00151   //exit(0);
00152   // DEBUG
00153 
00154   // compute the cumulative potential energy of all springs in the model        
00155   Container::instance().computeGlobalEnergy();
00156 
00157   // update container class log file
00158   log.updateFile(0,false,0);
00159   log.recordTime("Update log files:");
00160 
00161   // save separation distances to file
00162   log.writeSepDistances(0);
00163 
00164   // write intersected faces to file
00165   log.writeIntersected(0);
00166 
00167   // create instance of moved-vertex tracking structure
00168   //VTrack pod;
00169 
00170   // main loop
00171   cout << "\n ****** Begin main loop ******\n\n";
00172   log.recordTime("Begin main loop:");
00173   // for each group of iterations
00174   for (int group=1;group<(NUM_GROUPS+1);group++)
00175   {
00176     Vertex_Schedule & vs(Vertex_Schedule::instance());
00177     // enforce maximum runtime policy
00178     //if( (time(NULL)-begintime) > MAX_RUNTIME){break;}
00179     // initialize count of vertices moved in group
00180     vs.setNumMovedVertsGroup(1);
00181     // initialize group variables
00182     Virtual_Disp::instance().groupInit();
00183     Refractory::instance().groupInit();
00184     log.groupInit();
00185     Gain_Schedule::instance().initAvg();
00186     // DEBUG
00187     //Virtual_Disp::instance().validateTopN2();
00188     //if(!(group%1000))
00189     //{
00190     //  // check closest face
00191     //  Container::instance().checkClosestFace(group,"BEFORE");
00192     //  Container::instance().writeTopNSepDis(group,"BEFORE");
00193     //  Container::instance().checkFacesInBoxes("BEFORE");
00194     //}
00195     // DEBUG
00196     // until GROUP_SIZE vertex moves have been made
00197     while (vs.getNumMovedVertsGroup()<GROUP_SIZE)
00198     {
00199       // enforce maximum runtime policy
00200       //if( (time(NULL)-begintime) > MAX_RUNTIME){break;}
00201       vs.identifyMeshRegionToUpdate();
00202       if(vs.noMoreVertices()==true)
00203       {
00204         cout << "\n\n main: Error. no acceptable set seeds were found.\n";
00205         exit(0);
00206       }
00207       // for each vertex in vector
00208       vp_cit v=vs.beginVset();
00209       while(v!=vs.endVset())
00210       {
00211         if(Refractory::instance().vertexIsMoveCandidate(*v))
00212         {
00213           // vertex is a move candidate
00214           vs.computeVertex(*v);
00215           if(ENABLE_VTRACK==true) log.premove(*v);
00216           bool int_flag = false,angle_flag=false;
00217           if(State::instance().assignNewVertexCoords(*v,vs.getVertexDestination(),int_flag,angle_flag))
00218           {
00219             // vertex was successfully moved
00220             vs.incrementNumMovedVertsGroup();
00221             Refractory::instance().updateStats();
00222             log.print(group);
00223             if(ENABLE_VTRACK==true) log.postmove(*v);
00224             log.updateStatsAndPrint();
00225             Gain_Schedule::instance().updateAvg(Container::instance().getEnergy(),vs.getNumMovedVertsGroup());
00226             // update iterator
00227             v++;
00228             if(v==vs.endVset()){break;}
00229             // DEBUG
00230             // check closest face
00231             //if (vs.getNumMovedVertsGroup()>200 &&
00232             //  !(vs.getNumMovedVertsGroup()%10))
00233             //if (vs.getNumMovedVertsGroup())
00234             if (!(vs.getNumMovedVertsGroup()%100000))
00235             {
00236               Container::instance().checkClosestFace(group,"SUCCESSFUL");
00237             }
00238             // DEBUG
00239           } 
00240           else
00241           {
00242             // vertex was NOT successfully moved
00243             //vp_it q = Vertex_Schedule::instance().detectPunishableVertex(v,int_flag,angle_flag,pod,c);
00244             vp_cit q = Refractory::instance().detectPunishableVertex(v,int_flag,angle_flag);
00245             v=q;
00246             if(v==vs.endVset()){break;}
00247             // DEBUG
00248             // check closest face
00249             //if (vs.getNumMovedVertsGroup()>200 &&
00250             //  !(vs.getNumMovedVertsGroup()%10))
00251             //if (vs.getNumMovedVertsGroup())
00252             if (!(vs.getNumMovedVertsGroup()%100000))
00253             {
00254               Container::instance().checkClosestFace(group,"UNSUCCESSFUL");
00255             }
00256             // DEBUG
00257           }
00258           // DEBUG
00259           //          Vertex_Schedule::instance().writeFile(c,group);
00260           // DEBUG
00261         }
00262         else
00263         {
00264           // vertex is NOT a move candidate
00265           // so move on to next vertex in set
00266           v++;
00267           if(v==vs.endVset()){break;}
00268         }
00269       } // end for each vertex in set
00270       if(vs.noSetVerticesMoved())
00271       {
00272         // NO vertices were moved from last set
00273         // build set from vertex with next largest virtual displacemnet
00274         // (assuming it passes test in identifyMeshRegionToUpdate())
00275         Virtual_Disp::instance().incrementIterator();
00276       }
00277       else
00278       {
00279         // vertices were moved from last set, so reset iterator
00280         Virtual_Disp::instance().resetIterator();
00281       }
00282     } //end while number of moved vertices less than GROUP_SIZE
00283     // update log file
00284     char chstr[128];
00285     sprintf(chstr,"%s%2d%s","Iteration ",group,": Update log files:");
00286     str phrase = chstr; 
00287     log.recordTime(phrase);
00288     log.printVertexSchedulingStats(cout);
00289 
00290     // write output files and update gain
00291     log.writeFiles(group);
00292     Gain_Schedule::instance().updateMaxGain();
00293     // DEBUG
00294     // check closest face
00295     Container::instance().checkClosestFace(group,"AFTER");
00296     //Container::instance().writeTopNSepDis(group,"AFTER");
00297     Container::instance().checkFacesInBoxes(group,"AFTER");
00298     // DEBUG
00299   }
00300 
00301   // write output files
00302   if(WRITE_MESH_EVERY_ITERATION==false)
00303   {
00304     cout << "Build Mesh final..................";
00305     cout.flush();
00306     Container::instance().writeMeshData(1);
00307     cout << "complete.\n";
00308     cout.flush();
00309   }
00310   if(WRITE_DISTANCES_EVERY_ITERATION==false)
00311   {
00312     cout << "Write closest point distances final..";
00313     cout.flush();
00314     log.writeSepDistances(1);
00315     cout << "complete.\n";
00316     cout.flush();
00317   }
00318 
00319   // free allocated memory
00320   Gain_Schedule::instance().freeAvg();
00321 
00323   log.fileOutit();
00324   cout << "meshmorph complete\n\n";
00325 }

Generated on Fri Jul 18 19:43:40 2008 for meshmorph by  doxygen 1.5.1