/** Initialise the list of faces for the mesh * * \param nverts - number of vertices per face * \param verts - concatenated array of vertex indices into the primvar arrays. * \param faces - newly initialised faces go here. */ void EmitterMesh::createFaceList(const Ri::IntArray& nverts, const Ri::IntArray& verts, FaceVec& faces) const { // Create face list int faceStart = 0; float totWeight = 0; int sizeNVerts = nverts.size(); int totVerts = 0; faces.reserve(sizeNVerts); for(int i = 0; i < sizeNVerts; ++i) { if(nverts[i] != 3 && nverts[i] != 4) { assert(0 && "emitter mesh can only deal with 3 and 4-sided faces"); continue; } faces.push_back(MeshFace(&verts[0]+faceStart, totVerts, nverts[i])); faceStart += nverts[i]; // Get weight for face float w = faceArea(faces.back()); faces.back().weight = w; totWeight += w; totVerts += nverts[i]; } // normalized areas so that total area = 1. float scale = 1/totWeight; for(int i = 0; i < sizeNVerts; ++i) faces[i].weight *= scale; }
//giving a point, find out which cell contains this point //since the number of cells is not large, we search by loop over all cells vector<int> Grid::findNeighborsByCells(const VecD3& point) { vector<int> neighborList; const int nCells = _cells.getCount(); const CRConnectivity& cellNodes = *_cellNodes; const Array<VecD3>& nodeCoords = *_coordinates; for ( int c=0; c<nCells; c++){ const int nsize = cellNodes.getCount(c); int node[nsize]; for(int n=0; n<nsize; n++){ node[n] = cellNodes(c,n); } Array<VecD3> faceArea(nsize); Array<VecD3> faceCentroid(nsize); for(int n=0; n<nsize-1; n++){ faceArea[n]=nodeCoords[node[n+1]]-nodeCoords[node[n]]; faceCentroid[n]=(nodeCoords[node[n+1]]+nodeCoords[node[n]])/2.; } faceArea[nsize-1]=nodeCoords[node[0]]-nodeCoords[node[nsize-1]]; faceCentroid[nsize-1]=(nodeCoords[node[0]]+nodeCoords[node[nsize-1]])/2.; int find = 1; for(int n=0; n<nsize; n++){ VecD3 faceNorm; faceNorm[0]=faceArea[n][1]; faceNorm[1]=-faceArea[n][0]; faceNorm[2]=faceArea[n][2]; VecD3 dr = point - faceCentroid[n]; dr[2] = 0.0; //difference in z direction is neglected. just check x-y plane if (dot(faceNorm,dr) > 0.0) { find = 0; break; } } //point falls into a cell if (find){ for(int n=0; n<nsize; n++){ node[n]=cellNodes(c,n); neighborList.push_back(node[n]); } return(neighborList); } } //point falls outside of grid boundary //find the cloest cell to this point //use that cell to interpolate double distMin = 1.0e10; int closestCell = 0; for ( int c=0; c<nCells; c++){ const int nsize = cellNodes.getCount(c); VecD3 cellCentroid; cellCentroid[0]=0.0; cellCentroid[1]=0.0; cellCentroid[2]=0.0; for(int n=0; n<nsize; n++){ cellCentroid += nodeCoords[cellNodes(c,n)]; } cellCentroid /= 3.; VecD3 dr = point - cellCentroid; double distance = mag(dr); if(distance < distMin){ distMin = distance; closestCell = c; } } const int nsize = cellNodes.getCount(closestCell); for(int n=0; n<nsize; n++){ neighborList.push_back(cellNodes(closestCell,n)); } return(neighborList); }