static void rasterizeAABBs( const std::vector<AABB>& aabbs, const Array2s& min_coord, const scalar& h, const Array2u& dimensions, std::map<unsigned,std::vector<unsigned>>& voxels ) { // For each bounding box for( std::vector<AABB>::size_type aabb_idx = 0; aabb_idx < aabbs.size(); ++aabb_idx ) { // Compute the cells the AABB overlaps with. Slightly enlarge the boxes to account for FPA errors. Array2u index_lower; computeCellIndex( aabbs[aabb_idx].min() - 1.0e-6, min_coord, h, index_lower ); Array2u index_upper; computeCellIndex( aabbs[aabb_idx].max() + 1.0e-6, min_coord, h, index_upper ); assert( ( index_lower <= index_upper ).all() ); for( unsigned x_idx = index_lower.x(); x_idx <= index_upper.x(); ++x_idx ) { for( unsigned y_idx = index_lower.y(); y_idx <= index_upper.y(); ++y_idx ) { // Compute the hash key for the given indexed voxel const unsigned key = keyForIndex( Array2u( x_idx, y_idx ), dimensions ); auto voxel_iterator = voxels.find( key ); // Create a new voxel, if needed if( voxel_iterator == voxels.end() ) { const auto insertion_result = voxels.insert( std::make_pair( key, std::vector<unsigned>{} ) ); assert( insertion_result.second ); voxel_iterator = insertion_result.first; } // Add the index of the AABB to the voxel voxel_iterator->second.emplace_back( aabb_idx ); } } } }
void Resizer::computeVertexInCell() { int vertexN = polyMesh->getVertexN(); vertexInCell = new int *[vertexN]; for(int i=0;i<vertexN;i++) vertexInCell[i] = new int[2]; //得到每个顶点的3维坐标 float (*vertex)[3] = polyMesh->vertex; for(int i=0;i<vertexN;i++) { //X方向的下标 int xx = computeIndex(edgeLength[0],vertex[i][0],minBoundingBox[0]); int yy = computeIndex(edgeLength[1],vertex[i][1],minBoundingBox[1]); int zz = computeIndex(edgeLength[2],vertex[i][2],minBoundingBox[2]); vertexInCell[i][0] = computeCellIndex(xx,yy,zz); //CELLNUM vertexInCell[i][1] = computeCellIndex1(xx,yy,zz); //CELLNUM+1 if(xx < 0 || yy < 0 || zz < 0) { printf("Something is error!\n"); return; } } }
//计算每个cell的phi值,即计算数组phi中每个元素的值(cellPhi[Z][Y][X]) //在原来grid的外面的右边、上边、前边各加一层(方便计算) void Resizer::computeCellPhi() { //为变量cellPhi[][][]申请空间 cellPhi = new double **[(CELLNUM+1)]; for(int i=0;i<(CELLNUM+1);i++) cellPhi[i] = new double *[(CELLNUM+1)]; for(int i=0;i<(CELLNUM+1);i++) for(int j=0;j<(CELLNUM+1);j++) cellPhi[i][j] = new double[(CELLNUM+1)]; //如果该cell与模型中的face相交,则cellPhi[i]值为1; //如果该cell与模型中的face不相交,则cellPhi[i]值为0.1 for(int k=0;k<CELLNUM+1;k++) //高Z { for(int j=0;j<CELLNUM+1;j++) //列Y { for(int i=0;i<CELLNUM+1;i++) //行X { if(i==CELLNUM||j==CELLNUM||k==CELLNUM) //此时为右边、上边、前边的一层 { cellPhi[k][j][i] = 0.0; } else { int cellIndex = computeCellIndex(i,j,k); //得出i,j,k对应的cell的下标 if(cellIncludingFaceNum[cellIndex] == 0) //不相交 { cellPhi[k][j][i] = 0.1; } else //相交 { cellPhi[k][j][i] = 1.0; } } } } } }
//计算每个cell的缩放的大小(主要是计算cellScale[][]的值) void Resizer::computeCellScale(float _S[3]) { //计算每个cell的Phi值 computeCellPhi(); //计算每个cell的W[][3]和scaleEstimation[][3]值 computeCellW(); computeCellScaleEstimation(_S); //先定义临时变量存放每个cell的9个变量 double **temp = new double *[(CELLNUM+1)*(CELLNUM+1)*(CELLNUM+1)]; for(int i=0;i<(CELLNUM+1)*(CELLNUM+1)*(CELLNUM+1);i++) temp[i] = new double[9]; //对temp[][]赋初值为0.0 for(int i=0;i<(CELLNUM+1)*(CELLNUM+1)*(CELLNUM+1);i++) for(int j=0;j<9;j++) temp[i][j] = 0.0; //对temp[][]重新计算 for(int k=0;k<CELLNUM;k++) { for(int j=0;j<CELLNUM;j++) { for(int i=0;i<CELLNUM;i++) { int cellIndex = computeCellIndex1(i,j,k); temp[cellIndex][0] += cellPhi[k][j][i]*cellPhi[k][j+1][i]+cellPhi[k][j][i]*cellPhi[k+1][j][i]; //ScX的平方 temp[cellIndex][1] += cellPhi[k][j][i]*cellPhi[k][j][i+1]+cellPhi[k][j][i]*cellPhi[k+1][j][i]; //ScY的平方 temp[cellIndex][2] += cellPhi[k][j][i]*cellPhi[k][j][i+1]+cellPhi[k][j][i]*cellPhi[k][j+1][i]; //ScZ的平方 temp[cellIndex][3] += -cellPhi[k][j][i]*cellPhi[k][j+1][i]; //ScX*Sd2X temp[cellIndex][4] += -cellPhi[k][j][i]*cellPhi[k+1][j][i]; //ScX*Sd3X temp[cellIndex][5] += -cellPhi[k][j][i]*cellPhi[k][j][i+1]; //ScY*Sd1Y temp[cellIndex][6] += -cellPhi[k][j][i]*cellPhi[k+1][j][i]; //ScY*Sd3Y temp[cellIndex][7] += -cellPhi[k][j][i]*cellPhi[k][j][i+1]; //ScZ*Sd1Z temp[cellIndex][8] += -cellPhi[k][j][i]*cellPhi[k][j+1][i]; //ScZ*Sd2Z //对Sd1所在的位置加上两项 cellIndex = computeCellIndex1(i+1,j,k); temp[cellIndex][1] += cellPhi[k][j][i]*cellPhi[k][j][i+1]; temp[cellIndex][2] += cellPhi[k][j][i]*cellPhi[k][j][i+1]; //对Sd2所在的位置加上两项 cellIndex = computeCellIndex1(i,j+1,k); temp[cellIndex][0] += cellPhi[k][j][i]*cellPhi[k][j+1][i]; temp[cellIndex][2] += cellPhi[k][j][i]*cellPhi[k][j+1][i]; //对Sd3所在的位置加上两项 cellIndex = computeCellIndex1(i,j,k+1); temp[cellIndex][0] += cellPhi[k][j][i]*cellPhi[k+1][j][i]; temp[cellIndex][1] += cellPhi[k][j][i]*cellPhi[k+1][j][i]; } } } //首先定义整个矩阵(注意在grid的右侧、上侧、前侧各加了一层,主要是为了方便计算) int m = 3*(CELLNUM+1)*(CELLNUM+1)*(CELLNUM+1)+3*CELLLAYER; //矩阵的行数 int n = 3*(CELLNUM+1)*(CELLNUM+1)*(CELLNUM+1)+3*CELLLAYER; //矩阵的列数 //矩阵中非0元的个数(注意计算过程:整个矩阵的0---3*ALLCELLNUM-1行,每行有最多8个非0元素;3*ALLCELLNUM---ALLCELLNUM+CELLLAYER*3-1行,每行有CELLNUM个非0元素) //注意要考虑对角线的元素 int nnz = 6*ALLCELLNUM+5*ALLCELLNUM+4*ALLCELLNUM; //稀疏矩阵中非0元素的个数 //存放整个矩阵的变量 taucs_ccs_matrix *pMatrix; //为pMatrix申请空间 pMatrix = taucs_ccs_create(m,n,nnz,TAUCS_DOUBLE); //设置pMatrix的一些属性(对称和下三角) pMatrix->flags += TAUCS_SYMMETRIC; pMatrix->flags += TAUCS_LOWER; int num1=0; //计数器,主要是为记录colptr[]位置下标 int num2=0; //计数器,主要是为记录rowind[]和values.d[]位置下标 int count=0; //主要是为记录colptr[]存放的值 //下面开始存放矩阵(注意:调用taucs库稀疏矩阵必须按列进行存储) //首先考虑X方向 for(int k=0;k<CELLNUM+1;k++) //高 { for(int j=0;j<CELLNUM+1;j++) //列 { for(int i=0;i<CELLNUM+1;i++) //行 { if(i==CELLNUM||j==CELLNUM||k==CELLNUM) //壳上的点 { //此时该行的元素都为0 pMatrix->colptr[num1] = count; num1++; } else //不是壳上的点 { //colptr[]存储每一列开始元素对应的下标 //rowind[]存储每个元素在相应的列中的下标 //value.d[]存储每个元素的元素值,注意要与rowind[]相对应 pMatrix->colptr[num1] = count; num1++; int cellIndex1 = computeCellIndex(i,j,k); //此下标用于取W和scaleEstimation的值 int cellIndex2 = computeCellIndex1(i,j,k); //此下标用于取temp的值 pMatrix->rowind[num2] = computeCellIndex1(i,j,k); pMatrix->values.d[num2] = 2.0*(W[cellIndex1][0]+W[cellIndex1][2])/(scaleEstimation[cellIndex1][0]*scaleEstimation[cellIndex1][0])+(4.0/3.0)*2.0*temp[cellIndex2][0]; num2++; pMatrix->rowind[num2] = computeCellIndex1(i,j+1,k); pMatrix->values.d[num2] = (4.0/3.0)*2.0*temp[cellIndex2][3]; num2++; pMatrix->rowind[num2] = computeCellIndex1(i,j,k+1); pMatrix->values.d[num2] = (4.0/3.0)*2.0*temp[cellIndex2][4]; num2++; pMatrix->rowind[num2] = (CELLNUM+1)*(CELLNUM+1)*(CELLNUM+1)+computeCellIndex1(i,j,k); pMatrix->values.d[num2] = -2.0*W[cellIndex1][0]/(scaleEstimation[cellIndex1][0]*scaleEstimation[cellIndex1][1]); num2++; pMatrix->rowind[num2] = 2*(CELLNUM+1)*(CELLNUM+1)*(CELLNUM+1)+computeCellIndex1(i,j,k); pMatrix->values.d[num2] = -2.0*W[cellIndex1][2]/(scaleEstimation[cellIndex1][0]*scaleEstimation[cellIndex1][2]); num2++; pMatrix->rowind[num2] = 3*(CELLNUM+1)*(CELLNUM+1)*(CELLNUM+1)+k*CELLNUM+j; pMatrix->values.d[num2] = 1.0; num2++; count = count+6; } } } } //处理Y方向(num1,num2和count应该接上面的值) for(int k=0;k<CELLNUM+1;k++) //高 { for(int j=0;j<CELLNUM+1;j++) //列 { for(int i=0;i<CELLNUM+1;i++) //行 { if(i==CELLNUM||j==CELLNUM||k==CELLNUM) //壳上的点 { //此时该行的元素都为0 pMatrix->colptr[num1] = count; num1++; } else //不是壳上的点 { //colptr[]存储每一列开始元素对应的下标 //rowind[]存储每个元素在相应的列中的下标 //value.d[]存储每个元素的元素值,注意要与rowind[]相对应 pMatrix->colptr[num1] = count; num1++; int cellIndex1 = computeCellIndex(i,j,k); //i,j,k对应的不带壳的grid中cell的下标 int cellIndex2 = computeCellIndex1(i,j,k); pMatrix->rowind[num2] = (CELLNUM+1)*(CELLNUM+1)*(CELLNUM+1)+computeCellIndex1(i,j,k); pMatrix->values.d[num2] = 2.0*(W[cellIndex1][0]+W[cellIndex1][1])/(scaleEstimation[cellIndex1][1]*scaleEstimation[cellIndex1][1])+(4.0/3.0)*2.0*temp[cellIndex2][1]; num2++; pMatrix->rowind[num2] = (CELLNUM+1)*(CELLNUM+1)*(CELLNUM+1)+computeCellIndex1(i+1,j,k); pMatrix->values.d[num2] = (4.0/3.0)*2.0*temp[cellIndex2][5]; num2++; pMatrix->rowind[num2] = (CELLNUM+1)*(CELLNUM+1)*(CELLNUM+1)+computeCellIndex1(i,j,k+1); pMatrix->values.d[num2] = (4.0/3.0)*2.0*temp[cellIndex2][6]; num2++; pMatrix->rowind[num2] = 2*(CELLNUM+1)*(CELLNUM+1)*(CELLNUM+1)+computeCellIndex1(i,j,k); pMatrix->values.d[num2] = -2.0*W[cellIndex1][1]/(scaleEstimation[cellIndex1][1]*scaleEstimation[cellIndex1][2]); num2++; pMatrix->rowind[num2] = 3*(CELLNUM+1)*(CELLNUM+1)*(CELLNUM+1)+CELLLAYER+k*CELLNUM+i; pMatrix->values.d[num2] = 1.0; num2++; count = count+5; } } } } //处理Z方向(num1,num2和count应该接上面的值) for(int k=0;k<CELLNUM+1;k++) //高 { for(int j=0;j<CELLNUM+1;j++) //列 { for(int i=0;i<CELLNUM+1;i++) //行 { if(i==CELLNUM||j==CELLNUM||k==CELLNUM) //壳上的点 { //此时该行的元素都为0 pMatrix->colptr[num1] = count; num1++; } else //不是壳上的点 { //colptr[]存储每一列开始元素对应的下标 //rowind[]存储每个元素在相应的列中的下标 //value.d[]存储每个元素的元素值,注意要与rowind[]相对应 pMatrix->colptr[num1] = count; num1++; int cellIndex1 = computeCellIndex(i,j,k); //i,j,k对应的不带壳的grid中cell的下标 int cellIndex2 = computeCellIndex1(i,j,k); pMatrix->rowind[num2] = 2*(CELLNUM+1)*(CELLNUM+1)*(CELLNUM+1)+computeCellIndex1(i,j,k); pMatrix->values.d[num2] = 2.0*(W[cellIndex1][1]+W[cellIndex1][2])/(scaleEstimation[cellIndex1][2]*scaleEstimation[cellIndex1][2])+(4.0/3.0)*2.0*temp[cellIndex2][2]; num2++; pMatrix->rowind[num2] = 2*(CELLNUM+1)*(CELLNUM+1)*(CELLNUM+1)+computeCellIndex1(i+1,j,k); pMatrix->values.d[num2] = (4.0/3.0)*2.0*temp[cellIndex2][7]; num2++; pMatrix->rowind[num2] = 2*(CELLNUM+1)*(CELLNUM+1)*(CELLNUM+1)+computeCellIndex1(i,j+1,k); pMatrix->values.d[num2] = (4.0/3.0)*2.0*temp[cellIndex2][8]; num2++; pMatrix->rowind[num2] = 3*(CELLNUM+1)*(CELLNUM+1)*(CELLNUM+1)+2*CELLLAYER+j*CELLNUM+i; pMatrix->values.d[num2] = 1.0; num2++; count = count+4; } } } } //注意:pMatrix->colptr[]共有n+1个元素,即使为0,也应存储 for(int i=num1;i<=n;i++) //此处n应能取到 pMatrix->colptr[i] = count; taucs_double *x = new taucs_double[3*(CELLNUM+1)*(CELLNUM+1)*(CELLNUM+1)+3*CELLLAYER]; //存放运算得到的未知数结果 //对矩阵x赋初值(加快收敛速度) for(int k=0;k<CELLNUM+1;k++) //高 { for(int j=0;j<CELLNUM+1;j++) //列 { for(int i=0;i<CELLNUM+1;i++) //行 { if(i==CELLNUM||j==CELLNUM||k==CELLNUM) //壳上的点,其对应的x[i]值赋值为0 { int index = computeCellIndex1(i,j,k); x[index] = 0.0; } else //不是壳上的点 { int index = computeCellIndex1(i,j,k); x[index] = _S[0]; x[(CELLNUM+1)*(CELLNUM+1)*(CELLNUM+1)+index] = _S[1]; x[2*(CELLNUM+1)*(CELLNUM+1)*(CELLNUM+1)+index] = _S[2]; } } } } //其余x[]值赋值为0 for(int i=3*(CELLNUM+1)*(CELLNUM+1)*(CELLNUM+1);i<3*(CELLNUM+1)*(CELLNUM+1)*(CELLNUM+1)+3*CELLLAYER;i++) x[i] = 0.0; taucs_double *b = new taucs_double[3*(CELLNUM+1)*(CELLNUM+1)*(CELLNUM+1)+3*CELLLAYER]; //存放右边的列矩阵 //对矩阵b赋值 for(int i=0;i<3*(CELLNUM+1)*(CELLNUM+1)*(CELLNUM+1);i++) b[i] = 0.0; for(int i=3*(CELLNUM+1)*(CELLNUM+1)*(CELLNUM+1);i<3*(CELLNUM+1)*(CELLNUM+1)*(CELLNUM+1)+CELLLAYER;i++) b[i] = CELLNUM*_S[0]; for(int i=3*(CELLNUM+1)*(CELLNUM+1)*(CELLNUM+1)+CELLLAYER;i<3*(CELLNUM+1)*(CELLNUM+1)*(CELLNUM+1)+2*CELLLAYER;i++) b[i] = CELLNUM*_S[1]; for(int i=3*(CELLNUM+1)*(CELLNUM+1)*(CELLNUM+1)+2*CELLLAYER;i<3*(CELLNUM+1)*(CELLNUM+1)*(CELLNUM+1)+3*CELLLAYER;i++) b[i] = CELLNUM*_S[2]; //调用函数解决问题 //注意:原论文其实是要计算预处理矩阵,主要是为了早点收敛 //我没有计算基于两点:1)时间紧迫,计算预处理矩阵又得花不少时间 2)直接计算收敛速度也很快的 int result = taucs_minres(pMatrix,NULL,NULL,x,b,1000,1e-4); //判断结果 if (result != TAUCS_SUCCESS) { printf ("Solution error.\n"); if (result==TAUCS_ERROR) printf ("Generic error."); if (result==TAUCS_ERROR_NOMEM) printf ("NOMEM error."); if (result==TAUCS_ERROR_BADARGS) printf ("BADARGS error."); if (result==TAUCS_ERROR_MAXDEPTH) printf ("MAXDEPTH error."); if (result==TAUCS_ERROR_INDEFINITE) printf ("NOT POSITIVE DEFINITE error."); } else { printf ("Solution success.\n"); //为cellScale[][3]申请空间 cellScale = new double *[ALLCELLNUM]; for(int i=0;i<ALLCELLNUM;i++) cellScale[i] = new double[3]; //正确求得解,将其赋值给cellScale[][3] for(int k=0;k<CELLNUM+1;k++) //高 { for(int j=0;j<CELLNUM+1;j++) //列 { for(int i=0;i<CELLNUM+1;i++) //行 { if(i==CELLNUM||j==CELLNUM||k==CELLNUM) //壳上的点,其对应的x[i]值是不需要的 { } else //不是壳上的点 { int cellIndex1 = computeCellIndex(i,j,k); //i,j,k对应的不带壳的grid中cell的下标 int cellIndex2 = computeCellIndex1(i,j,k); //i,j,k对应的带壳的grid中cell的下标 cellScale[cellIndex1][0] = x[cellIndex2]; cellScale[cellIndex1][1] = x[(CELLNUM+1)*(CELLNUM+1)*(CELLNUM+1)+cellIndex2]; cellScale[cellIndex1][2] = x[2*(CELLNUM+1)*(CELLNUM+1)*(CELLNUM+1)+cellIndex2]; } } } } } taucs_ccs_free(pMatrix); //此处可以释放W[][]和scaleEstimation[][]的资源了 for(int i=0;i<ALLCELLNUM;i++) { delete[] W[i]; } delete[] W; for(int i=0;i<ALLCELLNUM;i++) { delete[] scaleEstimation[i]; } delete[] scaleEstimation; printf("W和scaleEstimation释放资源没问题.\n"); //释放x[]和b[]的资源 delete[] x; delete[] b; printf("x和b释放资源没问题.\n"); }
void Resizer::computeFacePassthroughingCell(int _faceIndex,float _tempVertex[3][3],int _indexMin[3],int _indexMax[3],float _cellHalfLength[3]) { int num = 0; //记录该face穿过的cell的个数 float cellCenter[3]; //记录当前cell的中心点 //仔细考虑八种情况 if(_indexMax[0] == _indexMin[0]) { if(_indexMax[1] == _indexMin[1]) { if(_indexMax[2] == _indexMin[2]) //如果X,Y,Z方向都相同(肯定是相交的) { facePassthroughCell[_faceIndex][num] = computeCellIndex(_indexMin[0],_indexMin[1],_indexMin[2]); // printf("X,Y,Z方向都相同:%d--%d\n",num,computeCellIndex(_indexMin[0],_indexMin[1],_indexMin[2])); num++; facePassthroughCellNum[_faceIndex] = num; // Sleep(500); } else //如果X,Y方向相同,Z方向不同(需要判断是否相交) { cellCenter[0] = minBoundingBox[0]+_indexMin[0]*edgeLength[0]+_cellHalfLength[0]; cellCenter[1] = minBoundingBox[1]+_indexMin[1]*edgeLength[1]+_cellHalfLength[1]; for(int j=_indexMin[2];j<=_indexMax[2];j++) //Z轴 { cellCenter[2] = minBoundingBox[2]+j*edgeLength[2]+_cellHalfLength[2]; if(triBoxOverlap(cellCenter,_cellHalfLength,_tempVertex) == 1) //如果face和cell相交 { facePassthroughCell[_faceIndex][num] = computeCellIndex(_indexMin[0],_indexMin[1],j); // printf("X,Y方向相同,Z方向不同:%d--%d\n",num,computeCellIndex(_indexMin[0],_indexMin[1],j)); num++; // Sleep(500); } /*else { printf("X,Y方向相同,Z方向不同:face和cell不相交.\n"); Sleep(500); }*/ } facePassthroughCellNum[_faceIndex] = num; } } else //Y方向不相同 { if(_indexMin[2] == _indexMax[2]) //X,Z方向相同,Y方向不同 { cellCenter[0] = minBoundingBox[0]+_indexMin[0]*edgeLength[0]+_cellHalfLength[0]; cellCenter[2] = minBoundingBox[2]+_indexMin[2]*edgeLength[2]+_cellHalfLength[2]; for(int j=_indexMin[1];j<=_indexMax[1];j++) //Y轴 { cellCenter[1] = minBoundingBox[1]+j*edgeLength[1]+_cellHalfLength[1]; if(triBoxOverlap(cellCenter,_cellHalfLength,_tempVertex) == 1) //如果face和cell相交 { facePassthroughCell[_faceIndex][num] = computeCellIndex(_indexMin[0],j,_indexMin[2]); // printf("X,Z方向相同,Y方向不同:%d--%d\n",num,computeCellIndex(_indexMin[0],j,_indexMin[2])); num++; // Sleep(500); } /*else { printf("X,Z方向相同,Y方向不同:face和cell不相交.\n"); Sleep(500); }*/ facePassthroughCellNum[_faceIndex] = num; } } else //X方向相同,Y,Z方向不同 { cellCenter[0] = minBoundingBox[0]+_indexMin[0]*edgeLength[0]+_cellHalfLength[0]; for(int j=_indexMin[1];j<=_indexMax[1];j++) //Y方向 { for(int k=_indexMin[2];k<=_indexMax[2];k++) //Z方向 { cellCenter[1] = minBoundingBox[1]+j*edgeLength[1]+_cellHalfLength[1]; cellCenter[2] = minBoundingBox[2]+k*edgeLength[2]+_cellHalfLength[2]; if(triBoxOverlap(cellCenter,_cellHalfLength,_tempVertex) == 1) //如果face和cell相交 { facePassthroughCell[_faceIndex][num] = computeCellIndex(_indexMin[0],j,k); // printf("X方向相同,Y,Z方向不同:%d--%d\n",num,computeCellIndex(_indexMin[0],j,k)); num++; // Sleep(500); } /*else { printf("X方向相同,Y,Z方向不同:face和cell不相交.\n"); Sleep(500); }*/ facePassthroughCellNum[_faceIndex] = num; } } } } } else //X方向不同 { if(_indexMin[1] == _indexMax[1]) //Y方向相同 { if(_indexMin[2] == _indexMax[2]) //Y,Z方向相同,X方向不同 { cellCenter[1] = minBoundingBox[1]+_indexMin[1]*edgeLength[1]+_cellHalfLength[1]; cellCenter[2] = minBoundingBox[2]+_indexMin[2]*edgeLength[2]+_cellHalfLength[2]; for(int j=_indexMin[0];j<=_indexMax[0];j++) //X方向 { cellCenter[0] = minBoundingBox[0]+j*edgeLength[0]+_cellHalfLength[0]; if(triBoxOverlap(cellCenter,_cellHalfLength,_tempVertex) == 1) //如果face和cell相交 { facePassthroughCell[_faceIndex][num] = computeCellIndex(j,_indexMin[1],_indexMin[2]); // printf("Y,Z方向相同,X方向不同:%d--%d\n",num,computeCellIndex(j,_indexMin[1],_indexMin[2])); num++; // Sleep(500); } /*else { printf("Y,Z方向相同,X方向不同:face和cell不相交.\n"); Sleep(500); }*/ } facePassthroughCellNum[_faceIndex] = num; } else //Y方向相同,X,Z方向不同 { cellCenter[1] = minBoundingBox[1]+_indexMin[1]*edgeLength[1]+_cellHalfLength[1]; for(int j=_indexMin[0];j<=_indexMax[0];j++) //X方向 { for(int k=_indexMin[2];k<=_indexMax[2];k++) //Z方向 { cellCenter[0] = minBoundingBox[0]+j*edgeLength[0]+_cellHalfLength[0]; cellCenter[2] = minBoundingBox[2]+k*edgeLength[2]+_cellHalfLength[2]; if(triBoxOverlap(cellCenter,_cellHalfLength,_tempVertex) == 1) //如果face和cell相交 { facePassthroughCell[_faceIndex][num] = computeCellIndex(j,_indexMin[1],k); // printf("Y方向相同,X,Z方向不同:%d--%d\n",num,computeCellIndex(j,_indexMin[1],k)); num++; // Sleep(500); } /*else { printf("Y方向相同,X,Z方向不同:face和cell不相交.\n"); Sleep(500); }*/ facePassthroughCellNum[_faceIndex] = num; } } } } else //Y方向不同 { if(_indexMin[2] == _indexMax[2]) //Z方向相同,X,Y方向不同 { cellCenter[2] = minBoundingBox[2]+_indexMin[2]*edgeLength[2]+_cellHalfLength[2]; for(int j=_indexMin[0];j<=_indexMax[0];j++) //X方向 { for(int k=_indexMin[1];k<=_indexMax[1];k++) //Y方向 { cellCenter[0] = minBoundingBox[0]+j*edgeLength[0]+_cellHalfLength[0]; cellCenter[1] = minBoundingBox[1]+k*edgeLength[1]+_cellHalfLength[1]; if(triBoxOverlap(cellCenter,_cellHalfLength,_tempVertex) == 1) //如果face和cell相交 { facePassthroughCell[_faceIndex][num] = computeCellIndex(j,k,_indexMin[2]); // printf("Z方向相同,X,Y方向不同:%d--%d\n",num,computeCellIndex(j,k,_indexMin[2])); num++; // Sleep(500); } /*else { printf("Z方向相同,X,Y方向不同:face和cell不相交.\n"); Sleep(500); }*/ facePassthroughCellNum[_faceIndex] = num; } } } else //X,Y,Z方向都不同 { for(int j=_indexMin[0];j<=_indexMax[0];j++) //X轴 { for(int k=_indexMin[1];k<=_indexMax[1];k++) //Y轴 { for(int p=_indexMin[2];p<=_indexMax[2];p++) //Z轴 { cellCenter[0] = minBoundingBox[0]+j*edgeLength[0]+_cellHalfLength[0]; cellCenter[1] = minBoundingBox[1]+k*edgeLength[1]+_cellHalfLength[1]; cellCenter[2] = minBoundingBox[2]+p*edgeLength[2]+_cellHalfLength[2]; if(triBoxOverlap(cellCenter,_cellHalfLength,_tempVertex) == 1) //如果face和cell相交 { facePassthroughCell[_faceIndex][num] = computeCellIndex(j,k,p); /* printf("X,Y,Z方向不同:%d--%d\n",num,computeCellIndex(j,k,p)); printf("(%f,%f,%f),(%f,%f,%f),(%f,%f,%f)\n",_tempVertex[0][0],_tempVertex[0][1],_tempVertex[0][2], _tempVertex[1][0],_tempVertex[1][1],_tempVertex[1][2], _tempVertex[2][0],_tempVertex[2][1],_tempVertex[2][2]);*/ num++; // Sleep(1500); } /*else { printf("X,Y,Z方向不同:face和cell不相交.\n"); printf("(%f,%f,%f),(%f,%f,%f),(%f,%f,%f)\n",_tempVertex[0][0],_tempVertex[0][1],_tempVertex[0][2], _tempVertex[1][0],_tempVertex[1][1],_tempVertex[1][2], _tempVertex[2][0],_tempVertex[2][1],_tempVertex[2][2]); Sleep(1500); }*/ facePassthroughCellNum[_faceIndex] = num; } } } } } } }
//这个函数功能比较难 void Resizer::computeNewCellVertex() { double ***temp1 = new double **[3]; for(int i=0;i<3;i++) temp1[i] = new double *[(CELLNUM+2)*(CELLNUM+2)*(CELLNUM+2)]; for(int i=0;i<3;i++) for(int j=0;j<(CELLNUM+2)*(CELLNUM+2)*(CELLNUM+2);j++) temp1[i][j] = new double[4]; double **temp2 = new double *[3]; for(int i=0;i<3;i++) temp2[i] = new double[(CELLNUM+2)*(CELLNUM+2)*(CELLNUM+2)]; //为变量newCellVertex[][]申请空间 newCellVertex = new double *[(CELLNUM+1)*(CELLNUM+1)*(CELLNUM+1)]; for(int i=0;i<(CELLNUM+1)*(CELLNUM+1)*(CELLNUM+1);i++) newCellVertex[i] = new double[3]; //初始化所有元素为0 for(int i=0;i<3;i++) { for(int j=0;j<(CELLNUM+2)*(CELLNUM+2)*(CELLNUM+2);j++) { temp2[i][j] = 0.0; for(int k=0;k<4;k++) temp1[i][j][k] = 0.0; } } //对每个cell进行遍历,每次考虑8个顶点 for(int p=0;p<3;p++) { for(int k=0;k<CELLNUM;k++) //高 { for(int j=0;j<CELLNUM;j++) //列 { for(int i=0;i<CELLNUM;i++) //行 { int cellIndex = computeCellIndex(i,j,k); //(CELLNUM) //当前cell沿X方向的脆弱性 double tempVulnerability = cellVulnerability[cellIndex][p]; //当前cell的的Phi值 double tempPhi = cellPhi[k][j][i]; //当前cell的X方向的缩放大小 double tempScale = cellScale[cellIndex][p]; //当前cell的X方向缩放后的棱长 double t = tempScale*edgeLength[p]; //对于每个cell进行处理 //对第0个顶点 cellIndex = computeCellIndex2(i,j,k); temp1[p][cellIndex][0] += 2.0*tempPhi+tempVulnerability; temp1[p][cellIndex][1] += -tempVulnerability; temp1[p][cellIndex][2] += -tempPhi; temp1[p][cellIndex][3] += -tempPhi; temp2[p][cellIndex] += -2.0*tempVulnerability*t; //对第1个顶点 cellIndex = computeCellIndex2(i+1,j,k); temp1[p][cellIndex][0] += 2.0*tempPhi+tempVulnerability; temp1[p][cellIndex][2] += -tempPhi; temp1[p][cellIndex][3] += -tempPhi; temp2[p][cellIndex] += 2.0*tempVulnerability*t; //对第2个顶点 cellIndex = computeCellIndex2(i,j+1,k); temp1[p][cellIndex][0] += 2.0*tempPhi+tempVulnerability; temp1[p][cellIndex][1] += -tempVulnerability; temp1[p][cellIndex][3] += -tempPhi; temp2[p][cellIndex] += -2.0*tempVulnerability*t; //对第3个顶点 cellIndex = computeCellIndex2(i+1,j+1,k); temp1[p][cellIndex][0] += 2.0*tempPhi+tempVulnerability; temp1[p][cellIndex][3] += -tempPhi; temp2[p][cellIndex] += 2.0*tempVulnerability*t; //对第4个顶点 cellIndex = computeCellIndex2(i,j,k+1); temp1[p][cellIndex][0] += 2.0*tempPhi+tempVulnerability; temp1[p][cellIndex][1] += -tempVulnerability; temp1[p][cellIndex][2] += -tempPhi; temp2[p][cellIndex] += -2.0*tempVulnerability*t; //对第5个顶点 cellIndex = computeCellIndex2(i+1,j,k+1); temp1[p][cellIndex][0] += 2.0*tempPhi+tempVulnerability; temp1[p][cellIndex][2] += -tempPhi; temp2[p][cellIndex] += 2.0*tempVulnerability*t; //对第6个顶点 cellIndex = computeCellIndex2(i,j+1,k+1); temp1[p][cellIndex][0] += 2.0*tempPhi+tempVulnerability; temp1[p][cellIndex][1] += -tempVulnerability; temp2[p][cellIndex] += -2.0*tempVulnerability*t; //对第7个顶点 cellIndex = computeCellIndex2(i+1,j+1,k+1); temp1[p][cellIndex][0] += 2.0*tempPhi+tempVulnerability; temp2[p][cellIndex] += 2.0*tempVulnerability*t; } } } } //首先定义整个稀疏对称矩阵 int m = (CELLNUM+2)*(CELLNUM+2)*(CELLNUM+2); //矩阵的行数 int n = (CELLNUM+2)*(CELLNUM+2)*(CELLNUM+2); //矩阵的列数 //稀疏矩阵中所有的非0元素的总个数 int nnz = 4*(CELLNUM+1)*(CELLNUM+1)*(CELLNUM+1); //存放整个矩阵的变量 taucs_ccs_matrix *pMatrix[3]; //为pMatrix[]申请空间 for(int i=0;i<3;i++) pMatrix[i] = taucs_ccs_create(m,n,nnz,TAUCS_DOUBLE); //设置pMatrix的一些属性(对称和下三角) for(int i=0;i<3;i++) { pMatrix[i]->flags += TAUCS_SYMMETRIC; pMatrix[i]->flags += TAUCS_LOWER; } //X,Y,Z方向综合考虑 for(int p=0;p<3;p++) { int num=0; //计数器,主要是为记录rowind[]和values.d[]位置下标 int count=0; //主要是为记录colptr[]存放的值 for(int k=0;k<(CELLNUM+2);k++) //高 { for(int j=0;j<(CELLNUM+2);j++) //列 { for(int i=0;i<(CELLNUM+2);i++) //行 { if(i==CELLNUM+1||j==CELLNUM+1||k==CELLNUM+1) { int cellIndex = computeCellIndex2(i,j,k); pMatrix[p]->colptr[cellIndex] = count; } else { int cellIndex = computeCellIndex2(i,j,k); pMatrix[p]->colptr[cellIndex] = count; pMatrix[p]->rowind[num] = cellIndex; pMatrix[p]->values.d[num] = 2.0*temp1[p][cellIndex][0]; num++; pMatrix[p]->rowind[num] = computeCellIndex2(i+1,j,k); pMatrix[p]->values.d[num] = 2.0*temp1[p][cellIndex][1]; num++; pMatrix[p]->rowind[num] = computeCellIndex2(i,j+1,k); pMatrix[p]->values.d[num] = 2.0*temp1[p][cellIndex][2]; num++; pMatrix[p]->rowind[num] = computeCellIndex2(i,j,k+1); pMatrix[p]->values.d[num] = 2.0*temp1[p][cellIndex][3]; num++; count = count+4; } } } } pMatrix[p]->colptr[(CELLNUM+2)*(CELLNUM+2)*(CELLNUM+2)] = count; } taucs_double **x = new taucs_double *[3]; //存放运算得到的未知数结果 for(int i=0;i<3;i++) x[i] = new taucs_double[(CELLNUM+2)*(CELLNUM+2)*(CELLNUM+2)]; //对矩阵x[]进行赋值(以便快速收敛) for(int p=0;p<3;p++) { for(int k=0;k<(CELLNUM+2);k++) //高 { for(int j=0;j<(CELLNUM+2);j++) //列 { for(int i=0;i<(CELLNUM+2);i++) //行 { if(i>CELLNUM||j>CELLNUM||k>CELLNUM) { int cellIndex = computeCellIndex2(i,j,k); x[p][cellIndex] = 0.0; } else { if(p==0) { int cellIndex = computeCellIndex2(i,j,k); x[p][cellIndex] = oldCellVertex[computeCellIndex1(i,j,k)][p]; } else if(p==1) { int cellIndex = computeCellIndex2(j,i,k); //此处注意 x[p][cellIndex] = oldCellVertex[computeCellIndex1(i,j,k)][p]; } else //p==2 { int cellIndex = computeCellIndex2(k,i,j); //此处注意 x[p][cellIndex] = oldCellVertex[computeCellIndex1(i,j,k)][p]; } } } } } } taucs_double **b = new taucs_double *[3]; //存放右边的列矩阵 for(int i=0;i<3;i++) b[i] = new taucs_double[(CELLNUM+2)*(CELLNUM+2)*(CELLNUM+2)]; //对矩阵b[]进行赋值 for(int i=0;i<3;i++) { for(int j=0;j<(CELLNUM+2)*(CELLNUM+2)*(CELLNUM+2);j++) { b[i][j] = temp2[i][j]; } } //先对X方向调用函数解决问题 for(int p=0;p<3;p++) { int result = taucs_minres(pMatrix[p],NULL,NULL,x[p],b[p],1000,0.0001); //判断结果 if (result != TAUCS_SUCCESS) { printf ("Solution error.\n"); if (result==TAUCS_ERROR) printf ("Generic error."); if (result==TAUCS_ERROR_NOMEM) printf ("NOMEM error."); if (result==TAUCS_ERROR_BADARGS) printf ("BADARGS error."); if (result==TAUCS_ERROR_MAXDEPTH) printf ("MAXDEPTH error."); if (result==TAUCS_ERROR_INDEFINITE) printf ("NOT POSITIVE DEFINITE error."); } else { printf ("Solution success.\n"); //正确求得解,将其赋值给newCellVertex[][] for(int k=0;k<(CELLNUM+2);k++) //高 { for(int j=0;j<(CELLNUM+2);j++) //列 { for(int i=0;i<(CELLNUM+2);i++) //行 { if(i>CELLNUM||j>CELLNUM||k>CELLNUM) { //这不是我们要的 } else { if(p==0) { int cellIndex = computeCellIndex2(i,j,k); newCellVertex[computeCellIndex1(i,j,k)][p] = x[p][cellIndex]; } else if(p==1) { int cellIndex = computeCellIndex2(j,i,k); //此处注意 newCellVertex[computeCellIndex1(i,j,k)][p] = x[p][cellIndex]; } else //p==2 { int cellIndex = computeCellIndex2(k,i,j); //此处注意 newCellVertex[computeCellIndex1(i,j,k)][p] = x[p][cellIndex]; } } } } } } } for(int i=0;i<200;i++) { printf("(%f,%f,%f)<---->(%f,%f,%f)\n",oldCellVertex[i][0],oldCellVertex[i][1],oldCellVertex[i][2],newCellVertex[i][0],newCellVertex[i][1],newCellVertex[i][2]); } //释放资源 //释放temp1[][][] for(int i=0;i<3;i++) { for(int j=0;j<(CELLNUM+2)*(CELLNUM+2)*(CELLNUM+2);j++) { delete[] temp1[i][j]; } } for(int i=0;i<3;i++) { delete[] temp1[i]; } delete[] temp1; printf("temp1释放资源没问题.\n"); //释放temp2[][] for(int i=0;i<3;i++) { delete[] temp2[i]; } delete[] temp2; printf("temp2释放资源没问题.\n"); //释放x[][] for(int i=0;i<3;i++) { delete[] x[i]; } delete[] x; printf("x释放资源没问题.\n"); //释放b[][] for(int i=0;i<3;i++) { delete[] b[i]; } delete[] b; printf("b释放资源没问题.\n"); for(int i=0;i<3;i++) taucs_ccs_free(pMatrix[i]); printf("pMatrix释放资源没问题.\n"); }