标签:des style blog color io os ar 使用 for
独学而无友,则孤陋而寡闻。深知独学的无奈,深知无友的感慨,所以个人将学习研究过程当中遇到的、学习到的东西分享出来,只为有志同道合的朋友互相交流,共同进步。 有一QQ群:285214996,希望汇聚所有这个领域的朋友,我们一起分享学习的快乐。
泊松表面重建中会PoissonRecon.cpp文件,下面是我个人在研究过程当中的分析过程,定有不当之处,还请指出。
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <math.h> 4 #include <float.h> 5 #ifdef _WIN32 6 #include <Windows.h> 7 #include <Psapi.h> 8 #endif // _WIN32 9 #include "Time.h" 10 #include "MarchingCubes.h" 11 #include "Octree.h" 12 #include "SparseMatrix.h" 13 #include "CmdLineParser.h" 14 #include "PPolynomial.h" 15 #include "Ply.h" 16 #include "MemoryUsage.h" 17 #include "omp.h" 18 #include <stdarg.h> 19 20 char* outputFile=NULL;//将注释写入的文件路径 21 int echoStdout=0;//控制是否在控制台显示,1显示,0不显示 22 23 /* 24 将注释按照format的格式输出到文件中,并且根据echoStdout的值来选择是否将值输出到控制台 25 */ 26 void DumpOutput( const char* format , ... ) 27 { 28 if( outputFile ) 29 { 30 FILE* fp = fopen( outputFile , "a" ); 31 va_list args; 32 va_start( args , format ); 33 vfprintf( fp , format , args ); 34 fclose( fp ); 35 va_end( args ); 36 } 37 if( echoStdout ) 38 { 39 va_list args; 40 va_start( args , format ); 41 vprintf( format , args ); 42 va_end( args ); 43 } 44 } 45 46 /* 47 将注释按照format的格式输出到文件中,且将注释写入到str中,并且根据echoStdout的值来选择是否将值输出到控制台 48 */ 49 void DumpOutput2( char* str , const char* format , ... ) 50 { 51 if( outputFile ) 52 { 53 FILE* fp = fopen( outputFile , "a" ); 54 va_list args; 55 va_start( args , format ); 56 vfprintf( fp , format , args ); 57 fclose( fp ); 58 va_end( args ); 59 } 60 if( echoStdout )//输出到STDOUT(标准输出) 61 { 62 va_list args; 63 va_start( args , format ); 64 vprintf( format , args ); 65 va_end( args ); 66 } 67 va_list args; 68 va_start( args , format ); 69 vsprintf( str , format , args ); 70 va_end( args ); 71 if( str[strlen(str)-1]==‘\n‘ ) str[strlen(str)-1] = 0; 72 } 73 74 #include "MultiGridOctreeData.h" 75 #ifdef MAX_MEMORY_GB 76 #undef MAX_MEMORY_GB 77 #endif // MAX_MEMORY_GB 78 //#define MAX_MEMORY_GB 8 79 80 /* 81 后面必须跟字符串,比如 --in bunny.points.ply 82 */ 83 cmdLineString 84 In( "in" ) , 85 Out( "out" ) , 86 VoxelGrid( "voxel" ) ,/*体素网格*/ 87 XForm( "xForm" ); 88 89 /* 90 直接使用,比如:--performance 91 */ 92 cmdLineReadable 93 #ifdef _WIN32 94 Performance( "performance" ) ,//性能 95 #endif // _WIN32 96 ShowResidual( "showResidual" ) ,//显示剩余误差 97 NoComments( "noComments" ) ,//无注释 98 PolygonMesh( "polygonMesh" ) ,//多边形 99 Confidence( "confidence" ) ,//置信度 100 NormalWeights( "normalWeight" ) ,//法向权重 101 NonManifold( "nonManifold" ) ,//非流形? 102 ASCII( "ascii" ) , 103 Density( "density" ) ,//密度 104 Verbose( "verbose" );//冗余信息显示 105 106 /* 107 后面必须跟整型数字,比如:--depth 8 108 */ 109 cmdLineInt 110 Depth( "depth" , 8 ) ,//深度 111 SolverDivide( "solverDivide" , 8 ) ,//解算深度 112 IsoDivide( "isoDivide" , 8 ) ,//等值面提取 113 KernelDepth( "kernelDepth" ) ,//核心深度 114 AdaptiveExponent( "adaptiveExp" , 1 ) ,//适应指数 115 MinIters( "minIters" , 24 ) ,//最小迭代 116 FixedIters( "iters" , -1 ) ,//修改的迭代? 117 VoxelDepth( "voxelDepth" , -1 ) ,//体素深度 118 #if 1 119 #ifdef _WIN32 120 #pragma message( "[WARNING] Setting default min-depth to 5" ) 121 #endif // _WIN32 122 MinDepth( "minDepth" , 5 ) ,//最小深度 123 #else 124 MinDepth( "minDepth" , 0 ) , 125 #endif 126 MaxSolveDepth( "maxSolveDepth" ) ,//最大解算深度 127 BoundaryType( "boundary" , 1 ) ,//边界 128 Threads( "threads" , omp_get_num_procs() );//线程数 129 /* 130 后面必须跟浮点型数字,比如:--samplesPerNode 1.f 131 */ 132 cmdLineFloat 133 SamplesPerNode( "samplesPerNode" , 1.f ) ,//每个节点中的样本点个数 134 Scale( "scale" , 1.1f ) ,//尺度|规模 135 SolverAccuracy( "accuracy" , float(1e-3) ) ,//解算精度 136 PointWeight( "pointWeight" , 4.f );//点的权重 137 138 //预设参考命令 139 cmdLineReadable* params[] = 140 { 141 &In , &Depth , &Out , &XForm , 142 &SolverDivide , &IsoDivide , &Scale , &Verbose , &SolverAccuracy , &NoComments , 143 &KernelDepth , &SamplesPerNode , &Confidence , &NormalWeights , &NonManifold , &PolygonMesh , &ASCII , &ShowResidual , &MinIters , &FixedIters , &VoxelDepth , 144 &PointWeight , &VoxelGrid , &Threads , &MinDepth , &MaxSolveDepth , 145 &AdaptiveExponent , &BoundaryType , 146 &Density , 147 #ifdef _WIN32//windows特有的 148 &Performance , 149 #endif // _WIN32 150 }; 151 152 153 void ShowUsage(char* ex) 154 { 155 //printf( "Usage: %s\n" , ex ); 156 printf( "用法: %s\n" , ex );//ex是可执行文件的绝对路径 157 158 //printf( "\t --%s <input points>\n" , In.name ); 159 printf( "\t --%s <输入点集>\n" , In.name ); 160 161 //printf( "\t[--%s <ouput triangle mesh>]\n" , Out.name ); 162 printf( "\t[--%s <输出的三角形网格>]\n" , Out.name ); 163 164 //printf( "\t[--%s <ouput voxel grid>]\n" , VoxelGrid.name ); 165 printf( "\t[--%s <输出立体像素网格>]\n" , VoxelGrid.name ); 166 167 //printf( "\t[--%s <maximum reconstruction depth>=%d]\n" , Depth.name , Depth.value ); 168 printf( "\t[--%s <最大重建深度>=%d]\n" , Depth.name , Depth.value ); 169 170 //printf( "\t\t Running at depth d corresponds to solving on a 2^d x 2^d x 2^d\n" ); 171 //printf( "\t\t voxel grid.\n" ); 172 printf( "\t\t 在深度d运行对应的解为2^d x 2^d x 2^d个体素网格\n" ); 173 174 //printf( "\t[--%s <depth at which to extract the voxel grid>=<%s>]\n" , VoxelDepth.name , Depth.name ); 175 printf( "\t[--%s <提取体素网格的深度>=<%s>]\n" , VoxelDepth.name , Depth.name ); 176 177 //printf( "\t[--%s <scale factor>=%f]\n" , Scale.name , Scale.value ); 178 printf( "\t[--%s <比例因子>=%f]\n" , Scale.name , Scale.value ); 179 180 //printf( "\t\t Specifies the factor of the bounding cube that the input\n" ); 181 //printf( "\t\t samples should fit into.\n" ); 182 printf( "\t\t 指定应该拟合的输入样本点的边界立方体的系数\n" ); 183 184 //printf( "\t[--%s <subdivision depth>=%d]\n" , SolverDivide.name , SolverDivide.value ); 185 printf( "\t[--%s <解算器细分深度>=%d]\n" , SolverDivide.name , SolverDivide.value ); 186 187 //printf( "\t\t The depth at which a block Gauss-Seidel solver is used\n"); 188 //printf( "\t\t to solve the Laplacian.\n"); 189 printf( "\t\t 用于求解拉普拉斯的阻塞高斯-塞德尔求解器深度\n"); 190 191 //printf( "\t[--%s <minimum number of samples per node>=%f]\n" , SamplesPerNode.name, SamplesPerNode.value ); 192 //printf( "\t\t This parameter specifies the minimum number of points that\n" ); 193 //printf( "\t\t should fall within an octree node.\n" ); 194 printf( "\t[--%s <每个节点样本点的最小数目>=%f]\n" , SamplesPerNode.name, SamplesPerNode.value ); 195 printf( "\t\t 此参数指定了应该落在一个八叉树节点内点的最小数目\n" ); 196 197 //printf( "\t[--%s <num threads>=%d]\n" , Threads.name , Threads.value ); 198 //printf( "\t\t This parameter specifies the number of threads across which\n" ); 199 //printf( "\t\t the solver should be parallelized.\n" ); 200 printf( "\t[--%s <线程数>=%d]\n" , Threads.name , Threads.value ); 201 printf( "\t\t 此参数指定横过其求解器应并行的线程数\n" ); 202 203 //printf( "\t[--%s]\n" , Confidence.name ); 204 //printf( "\t\t If this flag is enabled, the size of a sample‘s normals is\n" ); 205 //printf( "\t\t used as a confidence value, affecting the sample‘s\n" ); 206 //printf( "\t\t constribution to the reconstruction process.\n" ); 207 printf( "\t[--%s]\n" , Confidence.name ); 208 printf( "\t\t 如果这个标志被启用,样品法线的大小用作一个置信度值,影响到重建\n" ); 209 printf( "\t\t 过程中样品的贡献\n" ); 210 211 //printf( "\t[--%s]\n" , NormalWeights.name ); 212 //printf( "\t\t If this flag is enabled, the size of a sample‘s normals is\n" ); 213 //printf( "\t\t used as to modulate the interpolation weight.\n" ); 214 printf( "\t[--%s]\n" , NormalWeights.name ); 215 printf( "\t\t 如果这个标志被启用,样品的法线的大小用来调节内插权重\n" ); 216 217 //printf( "\t[--%s]\n" , NonManifold.name ); 218 //printf( "\t\t If this flag is enabled, the isosurface extraction does not add\n" ); 219 //printf( "\t\t a planar polygon‘s barycenter in order to ensure that the output\n" ); 220 //printf( "\t\t mesh is manifold.\n" ); 221 printf( "\t[--%s]\n" , NonManifold.name ); 222 printf( "\t\t 如果这个标志被启用,提取等值面不会添加一个平面多边形的重心,以\n" ); 223 printf( "\t\t 确保输出网格是多方面的\n" ); 224 225 //printf( "\t[--%s]\n" , PolygonMesh.name); 226 //printf( "\t\t If this flag is enabled, the isosurface extraction returns polygons\n" ); 227 //printf( "\t\t rather than triangles.\n" ); 228 printf( "\t[--%s]\n" , PolygonMesh.name); 229 printf( "\t\t 等值面提取返回的是多边形,而不是三角形\n" ); 230 231 //printf( "\t[--%s <interpolation weight>=%f]\n" , PointWeight.name , PointWeight.value ); 232 //printf( "\t\t This value specifies the weight that point interpolation constraints are\n" ); 233 //printf( "\t\t given when defining the (screened) Poisson system.\n" ); 234 printf( "\t[--%s <插值权重>=%f]\n" , PointWeight.name , PointWeight.value ); 235 printf( "\t\t 此值指定当定义(屏蔽)泊松系统时,给定点插值约束的权重\n" ); 236 237 //printf( "\t[--%s <minimum depth>=%d]\n" , MinDepth.name , MinDepth.value ); 238 //printf( "\t\t This flag specifies the minimum depth at which the octree is to be adaptive.\n" ); 239 printf( "\t[--%s <最小深度>=%d]\n" , MinDepth.name , MinDepth.value ); 240 printf( "\t\t 此标志指定的是八叉树要适应的最小深度\n" ); 241 242 //printf( "\t[--%s <solver accuracy>=%g]\n" , SolverAccuracy.name , SolverAccuracy.value ); 243 //printf( "\t[--%s <minimum number of solver iterations>=%d]\n" , MinIters.name , MinIters.value ); 244 printf( "\t[--%s <解算精度>=%g]\n" , SolverAccuracy.name , SolverAccuracy.value ); 245 printf( "\t[--%s <迭代求解器的最小数目>=%d]\n" , MinIters.name , MinIters.value ); 246 247 //printf( "\t[--%s <adaptive weighting exponent>=%d]\n", AdaptiveExponent.name , AdaptiveExponent.value ); 248 //printf( "\t\t This flag specifies the exponent scale for the adaptive weighting.\n" ); 249 printf( "\t[--%s <自适应加权指数>=%d]\n", AdaptiveExponent.name , AdaptiveExponent.value ); 250 printf( "\t\t 此标志指定自适应加权的指数规模\n" ); 251 252 #ifdef _WIN32 253 //printf( "\t[--%s]\n" , Performance.name ); 254 //printf( "\t\t If this flag is enabled, the running time and peak memory usage\n" ); 255 //printf( "\t\t is output after the reconstruction.\n" ); 256 printf( "\t[--%s]\n" , Performance.name ); 257 printf( "\t\t 如果这个标志启用后,运行时间和峰值内存使用量在重建后输出\n" ); 258 #endif // _WIN32 259 printf( "\t[--%s]\n" , Density.name ); 260 printf( "\t[--%s]\n" , ASCII.name ); 261 //printf( "\t\t If this flag is enabled, the output file is written out in ASCII format.\n" ); 262 printf( "\t\t 如果这个标志启用,输出文件会以ASCII的格式写入\n" ); 263 264 printf( "\t[--%s]\n" , NoComments.name ); 265 //printf( "\t\t If this flag is enabled, the output file will not include comments.\n" ); 266 printf( "\t\t 如果这个标志启用,输出文件将不包括注释\n" ); 267 268 printf( "\t[--%s]\n" , Verbose.name ); 269 //printf( "\t\t If this flag is enabled, the progress of the reconstructor will be output to STDOUT.\n" ); 270 printf( "\t\t 如果这个标志启用,重构的进度将被输出到STDOUT\n" ); 271 } 272 273 /* 274 Degree:维度 275 Vertex:顶点 276 OutputDensity:输出密度 277 */ 278 template< int Degree , class Vertex , bool OutputDensity > 279 int Execute( int argc , char* argv[] ) 280 { 281 int i; 282 int paramNum = sizeof(params)/sizeof(cmdLineReadable*);//预设命令数组params中命令参数的个数 283 int commentNum=0;//注释个数 284 char **comments;//“注释”变量,comments是一个指针1,指针指向了指针2,指针2指向了char,指针类型是4个字节 285 286 //“注释”初始化,有参数可以控制是否输出注释 287 comments = new char*[paramNum+7];//为什么加7?_201405042113 288 for( i=0 ; i<paramNum+7 ; i++ ) comments[i] = new char[1024]; 289 290 if( Verbose.set ) echoStdout=1;//判断是否输出到控制台,Verbose.set为TRUE时输出到控制台 291 292 /** 293 *读取定义的XForm4x4矩阵,如果读取失败直接定义4x4单位矩阵否则直接读取定义的值,如果没有设置直接定义4x4单位矩阵,最后求逆矩阵 294 */ 295 XForm4x4< Real > xForm , iXForm; 296 if( XForm.set ) 297 { 298 FILE* fp = fopen( XForm.value , "r" );//只读 299 if( !fp ) 300 { 301 fprintf( stderr , "[WARNING] Could not read x-form from: %s\n" , XForm.value ); 302 xForm = XForm4x4< Real >::Identity();//4x4单位矩阵 303 } 304 else 305 { 306 for( int i=0 ; i<4 ; i++ ) for( int j=0 ; j<4 ; j++ ) fscanf( fp , " %f " , &xForm( i , j ) ); 307 fclose( fp ); 308 } 309 } 310 else xForm = XForm4x4< Real >::Identity();//4x4单位矩阵 311 iXForm = xForm.inverse();//4x4单位矩阵的逆矩阵 312 313 /* 314 写入文件是肯定的,是否输出到控制台根据echoStdout是否为1判断,同时写入到comments[commentNum++]中 315 */ 316 DumpOutput2( comments[commentNum++] , "屏蔽泊松表面重建(版本 5.71)\n" ); 317 char str[1024]; 318 /* 319 将成功设定过的命令输出到控制台,如果有参数同时输出 320 */ 321 for( int i=0 ; i<paramNum ; i++ ) 322 if( params[i]->set )//如果参数被设定过则执行这一步 323 { 324 params[i]->writeValue( str );//将值写入到str中 325 if( strlen( str ) ) DumpOutput2( comments[commentNum++] , "\t--%s %s\n" , params[i]->name , str );//判断str中值得长度,如果有值即strlen(str)!=0则将参数名称连同值一起输出 326 else DumpOutput2( comments[commentNum++] , "\t--%s\n" , params[i]->name );//否则只输出参数名称 327 } 328 329 double t; 330 double tt=Time(); 331 Real isoValue = 0; 332 333 /* 334 八叉树结构Octree 335 此处是为了获取可用线程数 336 */ 337 Octree< Degree , OutputDensity > tree; 338 tree.threads = Threads.value;//使用OpenMP来获取线程数 339 //判断in是否设定过,没有设定过则输出可执行文件的绝对路径及文件名.扩展名 340 if( !In.set ) 341 { 342 ShowUsage(argv[0]); 343 return 0; 344 } 345 /* 346 最大解算深度MaxSolveDepth初始化时没有设置,如果在输入的命令行参数中也没有指定则将Depth.value的默认值8赋给MaxSolveDepth.value 347 */ 348 if( !MaxSolveDepth.set ) MaxSolveDepth.value = Depth.value; 349 /* 350 解算深度SolverDivide.value默认8 351 最小深度MinDepth.value默认5 352 如果解算深度小于最小深度则给出提示,将最小深度的值赋给解算深度 353 */ 354 if( SolverDivide.value<MinDepth.value )//解算器的深度应>=最小深度 355 { 356 fprintf( stderr , "[WARNING] %s must be at least as large as %s: %d>=%d\n" , SolverDivide.name , MinDepth.name , SolverDivide.value , MinDepth.value ); 357 SolverDivide.value = MinDepth.value; 358 } 359 /* 360 等值面提取深度默认为8 361 等值面提取深度应大于等于最小深度 362 如果小于最小深度则将最小深度的值赋给等值面提取深度 363 */ 364 if( IsoDivide.value<MinDepth.value )//等值提取的深度应>=最小深度 365 { 366 fprintf( stderr , "[WARNING] %s must be at least as large as %s: %d>=%d\n" , IsoDivide.name , MinDepth.name , IsoDivide.value , IsoDivide.value ); 367 IsoDivide.value = MinDepth.value; 368 } 369 370 /**201406231802 371 *八叉树节点OctNode 372 *给八叉树节点分配空间大小为MEMORY_ALLOCATOR_BLOCK_SIZE 373 *此处只是告知大小,但是没有具体分配空间,只是一个参数的设定而已,没有具体什么动作或操作 374 */ 375 OctNode< TreeNodeData< OutputDensity > , Real >::SetAllocator( MEMORY_ALLOCATOR_BLOCK_SIZE ); 376 377 t=Time(); 378 /**201406252155 379 *设定kernerDepth,如果设定过,就取设定的值,否则取Depth.value得默认值然后减去2 380 */ 381 int kernelDepth = KernelDepth.set ? KernelDepth.value : Depth.value-2;//为什么是减去2?201405042147 382 383 /*201406252156 384 设置B样条数据 385 输入: 386 Depth.value:最大深度 387 BoundaryType.value:边界类型 388 理解不透彻 389 */ 390 tree.setBSplineData( Depth.value , BoundaryType.value );//201405052103 391 /**201406252157 392 *检测刚才设定的kernelDepth是否合理,理论上应该小于Depth.value默认值8 393 *否则报错 394 */ 395 if( kernelDepth>Depth.value ) 396 { 397 fprintf( stderr,"[ERROR] %s can‘t be greater than %s: %d <= %d\n" , KernelDepth.name , Depth.name , KernelDepth.value , Depth.value ); 398 return EXIT_FAILURE; 399 } 400 401 double maxMemoryUsage; 402 t=Time() , tree.maxMemoryUsage=0; 403 /**201406261717 404 *输入 405 *输出 406 */ 407 int pointCount = tree.setTree( In.value , Depth.value , MinDepth.value , kernelDepth , Real(SamplesPerNode.value) , Scale.value , Confidence.set , NormalWeights.set , PointWeight.value , AdaptiveExponent.value , xForm ); 408 tree.ClipTree();//201405042200 409 tree.finalize( IsoDivide.value ); 410 411 DumpOutput2( comments[commentNum++] , "# Tree set in: %9.1f (s), %9.1f (MB)\n" , Time()-t , tree.maxMemoryUsage ); 412 DumpOutput( "Input Points: %d\n" , pointCount ); 413 DumpOutput( "Leaves/Nodes: %lld/%lld\n" , tree.tree.leaves() , tree.tree.nodes() ); 414 DumpOutput( "Memory Usage: %.3f MB\n" , float( MemoryInfo::Usage() )/(1<<20) ); 415 416 maxMemoryUsage = tree.maxMemoryUsage; 417 t=Time() , tree.maxMemoryUsage=0; 418 /* 419 201406281151 420 设置拉普拉斯约束 421 这里有OpenMP的并行 422 */ 423 tree.SetLaplacianConstraints();//201406071814 424 DumpOutput2( comments[commentNum++] , "# Constraints set in: %9.1f (s), %9.1f (MB)\n" , Time()-t , tree.maxMemoryUsage ); 425 DumpOutput( "Memory Usage: %.3f MB\n" , float( MemoryInfo::Usage())/(1<<20) ); 426 maxMemoryUsage = std::max< double >( maxMemoryUsage , tree.maxMemoryUsage ); 427 428 t=Time() , tree.maxMemoryUsage=0; 429 /* 430 201406281154 431 设置拉普拉斯矩阵迭代 432 输入: 433 SolverDivide:解算深度 434 ShowResidual:显示剩余误差 435 MinTters:最小迭代 436 SolverAccuracy:解算精度 437 MaxSolveDepth:最大解算深度 438 FixedIters:修改的迭代,此处值为-1 439 */ 440 tree.LaplacianMatrixIteration( SolverDivide.value, ShowResidual.set , MinIters.value , SolverAccuracy.value , MaxSolveDepth.value , FixedIters.value ); 441 DumpOutput2( comments[commentNum++] , "# Linear system solved in: %9.1f (s), %9.1f (MB)\n" , Time()-t , tree.maxMemoryUsage ); 442 DumpOutput( "Memory Usage: %.3f MB\n" , float( MemoryInfo::Usage() )/(1<<20) );//单位为MB,2的10次方是1k,2的20次方是1M 443 maxMemoryUsage = std::max< double >( maxMemoryUsage , tree.maxMemoryUsage ); 444 445 CoredFileMeshData< Vertex > mesh; 446 447 if( Verbose.set ) tree.maxMemoryUsage=0; 448 t=Time(); 449 /* 450 201406281158 451 这里有OpenMP并行 452 */ 453 isoValue = tree.GetIsoValue(); 454 DumpOutput( "Got average in: %f\n" , Time()-t ); 455 DumpOutput( "Iso-Value: %e\n" , isoValue ); 456 457 if( VoxelGrid.set ) 458 { 459 double t = Time(); 460 FILE* fp = fopen( VoxelGrid.value , "wb" ); 461 if( !fp ) fprintf( stderr , "Failed to open voxel file for writing: %s\n" , VoxelGrid.value ); 462 else 463 { 464 int res; 465 /* 466 201406281201 467 GetSolutionGrid获取网格 468 */ 469 Pointer( Real ) values = tree.GetSolutionGrid( res , isoValue , VoxelDepth.value ); 470 fwrite( &res , sizeof(int) , 1 , fp ); 471 if( sizeof(Real)==sizeof(float) ) fwrite( values , sizeof(float) , res*res*res , fp ); 472 else 473 { 474 float *fValues = new float[res*res*res]; 475 for( int i=0 ; i<res*res*res ; i++ ) fValues[i] = float( values[i] ); 476 fwrite( fValues , sizeof(float) , res*res*res , fp ); 477 delete[] fValues; 478 } 479 fclose( fp ); 480 DeletePointer( values ); 481 } 482 DumpOutput( "Got voxel grid in: %f\n" , Time()-t ); 483 } 484 485 if( Out.set ) 486 { 487 t = Time() , tree.maxMemoryUsage = 0; 488 /* 489 201406281203 490 GetMCIsoTriangles此处有OpenMP并行 491 */ 492 tree.GetMCIsoTriangles( isoValue , IsoDivide.value , &mesh , 0 , 1 , !NonManifold.set , PolygonMesh.set ); 493 if( PolygonMesh.set ) DumpOutput2( comments[commentNum++] , "# Got polygons in: %9.1f (s), %9.1f (MB)\n" , Time()-t , tree.maxMemoryUsage ); 494 else DumpOutput2( comments[commentNum++] , "# Got triangles in: %9.1f (s), %9.1f (MB)\n" , Time()-t , tree.maxMemoryUsage ); 495 maxMemoryUsage = std::max< double >( maxMemoryUsage , tree.maxMemoryUsage ); 496 DumpOutput2( comments[commentNum++],"# Total Solve: %9.1f (s), %9.1f (MB)\n" , Time()-tt , maxMemoryUsage ); 497 498 if( NoComments.set ) 499 { 500 if( ASCII.set ) PlyWritePolygons( Out.value , &mesh , PLY_ASCII , NULL , 0 , iXForm ); 501 else PlyWritePolygons( Out.value , &mesh , PLY_BINARY_NATIVE , NULL , 0 , iXForm ); 502 } 503 else 504 { 505 if( ASCII.set ) PlyWritePolygons( Out.value , &mesh , PLY_ASCII , comments , commentNum , iXForm ); 506 else PlyWritePolygons( Out.value , &mesh , PLY_BINARY_NATIVE , comments , commentNum , iXForm ); 507 } 508 } 509 510 return 1; 511 } 512 513 #ifdef _WIN32 514 inline double to_seconds( const FILETIME& ft ) 515 { 516 const double low_to_sec=100e-9; // 100 nanoseconds 517 const double high_to_sec=low_to_sec*4294967296.0;// 2^32 = 4294967296 518 return ft.dwLowDateTime*low_to_sec+ft.dwHighDateTime*high_to_sec; 519 } 520 #endif // _WIN32 521 522 /* 523 201406231200 524 *搞清楚每个函数的输入输出都是什么,还有完成了什么功能 525 *执行思路: 526 *获取命令行参数=cmdLineParse 527 *根据设置的参数执行=Execute 528 **/ 529 int main( int argc , char* argv[] ) 530 { 531 #if defined(WIN32) && defined(MAX_MEMORY_GB) 532 if( MAX_MEMORY_GB>0 ) 533 { 534 SIZE_T peakMemory = 1; 535 peakMemory <<= 30; 536 peakMemory *= MAX_MEMORY_GB; 537 printf( "Limiting memory usage to %.2f GB\n" , float( peakMemory>>30 ) ); 538 HANDLE h = CreateJobObject( NULL , NULL ); 539 AssignProcessToJobObject( h , GetCurrentProcess() ); 540 541 JOBOBJECT_EXTENDED_LIMIT_INFORMATION jeli = { 0 }; 542 jeli.BasicLimitInformation.LimitFlags = JOB_OBJECT_LIMIT_JOB_MEMORY; 543 jeli.JobMemoryLimit = peakMemory; 544 if( !SetInformationJobObject( h , JobObjectExtendedLimitInformation , &jeli , sizeof( jeli ) ) ) 545 fprintf( stderr , "Failed to set memory limit\n" ); 546 } 547 #endif // defined(WIN32) && defined(MAX_MEMORY_GB) 548 double t = Time(); 549 550 /* 551 201406231200 552 argc-1是除掉函数自身的名\***\***\bmcj.exe之外的参数总个数,位置从其后开始, 553 params中的内容为预定义的可选参数,1是指定是否在有错的情况下输出错误提示,有1时输出 554 输出:无输出 555 如果参数后面有值则设置set为TRUE并将值存放在对应的value中,这个是由重写的cmdLineReadable::read函数完成的 556 */ 557 cmdLineParse( argc-1 , &argv[1] , sizeof(params)/sizeof(cmdLineReadable*) , params , 1 );//命令后面的值都存放在value中 558 /* 559 201406231200 560 函数Execute的输入和输出都是什么 561 */ 562 if( Density.set ) Execute< 2 , PlyValueVertex< Real > , true >( argc , argv );//启用Density.set以告诉重构器输出等值面的顶点的深度估计信息 563 else Execute< 2 , PlyVertex< Real > , false >( argc , argv ); 564 #ifdef _WIN32 565 if( Performance.set ) 566 { 567 HANDLE cur_thread=GetCurrentThread();//获取当前线程的一个伪句柄 568 FILETIME tcreat, texit, tkernel, tuser; 569 if( GetThreadTimes( cur_thread , &tcreat , &texit , &tkernel , &tuser ) )//获取与一个线程的经过时间有关的信息,返回值非零表示成功 570 printf( "Time (墙钟时间(Wall)/用户模式消耗总时间(User)/内核模式消耗的总时间(Kernel)): %.2f / %.2f / %.2f\n" , Time()-t , to_seconds( tuser ) , to_seconds( tkernel ) ); 571 else printf( "Time: %.2f\n" , Time()-t ); 572 HANDLE h = GetCurrentProcess();//获取当前进程的一个伪句柄 573 PROCESS_MEMORY_COUNTERS pmc; 574 if( GetProcessMemoryInfo( h , &pmc , sizeof(pmc) ) ) printf( "内存峰值-Peak Memory (MB): %d\n" , pmc.PeakWorkingSetSize>>20 ); 575 } 576 #endif // _WIN32 577 return EXIT_SUCCESS; 578 }
也可通过下方的邮件联系我,相互交流。
标签:des style blog color io os ar 使用 for
原文地址:http://www.cnblogs.com/liangliangdetianxia/p/4030544.html