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
00095 assert(checkIntSize());
00096
00097
00098 bool freeze = parseCommandLine(argc,argv,message);
00099
00100
00101 Log & log(Log::instance());
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112 Container::instance();
00113 log.recordTime("scanning file:");
00114
00115
00116
00117
00118
00119 if(freeze==true){ Container::instance().readFrozen(FROZEN_VERTICES_FILE.c_str()); }
00120
00121
00122 Space::instance();
00123 log.recordTime("Initialize space data structure:");
00124
00125
00126 Container::instance().assignFacesToBoxes();
00127 log.recordTime("Assign faces to boxes:");
00128 log.setPartitioningBoxStats();
00129 log.printPartitioningStats(cout);
00130
00131
00132 log.writeObjectData();
00133 log.recordTime("Writing data to log files:");
00134
00135
00136 Nice::instance().findNonniceVertices();
00137 log.recordTime("Find nice vertices:");
00138 log.printNumNonnice(cout);
00139
00140
00141 Intersecting_Faces::instance().findAllFaceIntersections();
00142 log.recordTime("Find all face intersections:");
00143 log.printNumInt(cout);
00144
00145
00146 Container::instance().findClosestFaceToEachVertex();
00147 log.recordTime("Get separation distances:");
00148 log.printClosestPtStats(cout);
00149
00150
00151
00152
00153
00154
00155 Container::instance().computeGlobalEnergy();
00156
00157
00158 log.updateFile(0,false,0);
00159 log.recordTime("Update log files:");
00160
00161
00162 log.writeSepDistances(0);
00163
00164
00165 log.writeIntersected(0);
00166
00167
00168
00169
00170
00171 cout << "\n ****** Begin main loop ******\n\n";
00172 log.recordTime("Begin main loop:");
00173
00174 for (int group=1;group<(NUM_GROUPS+1);group++)
00175 {
00176 Vertex_Schedule & vs(Vertex_Schedule::instance());
00177
00178
00179
00180 vs.setNumMovedVertsGroup(1);
00181
00182 Virtual_Disp::instance().groupInit();
00183 Refractory::instance().groupInit();
00184 log.groupInit();
00185 Gain_Schedule::instance().initAvg();
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197 while (vs.getNumMovedVertsGroup()<GROUP_SIZE)
00198 {
00199
00200
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
00208 vp_cit v=vs.beginVset();
00209 while(v!=vs.endVset())
00210 {
00211 if(Refractory::instance().vertexIsMoveCandidate(*v))
00212 {
00213
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
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
00227 v++;
00228 if(v==vs.endVset()){break;}
00229
00230
00231
00232
00233
00234 if (!(vs.getNumMovedVertsGroup()%100000))
00235 {
00236 Container::instance().checkClosestFace(group,"SUCCESSFUL");
00237 }
00238
00239 }
00240 else
00241 {
00242
00243
00244 vp_cit q = Refractory::instance().detectPunishableVertex(v,int_flag,angle_flag);
00245 v=q;
00246 if(v==vs.endVset()){break;}
00247
00248
00249
00250
00251
00252 if (!(vs.getNumMovedVertsGroup()%100000))
00253 {
00254 Container::instance().checkClosestFace(group,"UNSUCCESSFUL");
00255 }
00256
00257 }
00258
00259
00260
00261 }
00262 else
00263 {
00264
00265
00266 v++;
00267 if(v==vs.endVset()){break;}
00268 }
00269 }
00270 if(vs.noSetVerticesMoved())
00271 {
00272
00273
00274
00275 Virtual_Disp::instance().incrementIterator();
00276 }
00277 else
00278 {
00279
00280 Virtual_Disp::instance().resetIterator();
00281 }
00282 }
00283
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
00291 log.writeFiles(group);
00292 Gain_Schedule::instance().updateMaxGain();
00293
00294
00295 Container::instance().checkClosestFace(group,"AFTER");
00296
00297 Container::instance().checkFacesInBoxes(group,"AFTER");
00298
00299 }
00300
00301
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
00320 Gain_Schedule::instance().freeAvg();
00321
00323 log.fileOutit();
00324 cout << "meshmorph complete\n\n";
00325 }