void RemoveHangingVertices( std::vector< Vertex >& vertices , std::vector< std::vector< int > >& polygons ) { hash_map< int , int > vMap; std::vector< bool > vertexFlags( vertices.size() , false ); for( size_t i=0 ; i<polygons.size() ; i++ ) for( size_t j=0 ; j<polygons[i].size() ; j++ ) vertexFlags[ polygons[i][j] ] = true; int vCount = 0; for( int i=0 ; i<int(vertices.size()) ; i++ ) if( vertexFlags[i] ) vMap[i] = vCount++; for( size_t i=0 ; i<polygons.size() ; i++ ) for( size_t j=0 ; j<polygons[i].size() ; j++ ) polygons[i][j] = vMap[ polygons[i][j] ]; std::vector< Vertex > _vertices( vCount ); for( int i=0 ; i<int(vertices.size()) ; i++ ) if( vertexFlags[i] ) _vertices[ vMap[i] ] = vertices[i]; vertices = _vertices; }
double getClosestPointOLD(ClosestPointInfo *inf, const Point3D &pTest, const Surface &s, const SpacialHash &faceHash, float stopBelow){ // get from the hash - they are not in order and distances are squared SpacialHash::CellRec *recs; int numCells = faceHash.getCells(&recs, pTest); // flags for used triangles Array<bool> flags(s.triangles.getSize()); flags.clear(); // flags for whether point has been tested Array<bool> vertexFlags(s.vertices.getSize()); vertexFlags.clear(); // find closest bit of surface inf->num = 0; inf->triangle = 0; inf->type = DIST_TYPE_INVALID; double minD = REAL_MAX; double stopBelowSqr = -1; if (stopBelow > 0) stopBelowSqr = stopBelow*stopBelow; for (int i = 0; i < numCells; i++){ /*&& recs[i].d <= minD + EPSILON_LARGE*/ // -- for when the cells were sorted SpacialHash::CellRec rec = recs[i]; if (rec.d > minD) // -- unsorted cells continue; Array<int> *tris = faceHash.getCell(rec.i, rec.j, rec.k); int numTris = tris->getSize(); if (numTris > 0){ getClosestPointINTERNAL(inf, &minD, pTest, s, stopBelowSqr, tris, &flags, &vertexFlags); if (minD < stopBelowSqr){ // opt for dodec test delete recs; return sqrt(minD); } } } delete recs; return sqrt(minD); }
double getClosestPointOrdered(ClosestPointInfo *inf, const Point3D &pTest, const Surface &s, const SpacialHash &faceHash, float stopBelow){ // get the dimensions and size of the grid int nX = faceHash.getDimX(); int nY = faceHash.getDimY(); int nZ = faceHash.getDimZ(); float cellSize = faceHash.getSize(); // flags for used triangles Array<bool> flags(s.triangles.getSize()); flags.clear(); // flags for whether point has been tested Array<bool> vertexFlags(s.vertices.getSize()); vertexFlags.clear(); // get cells from the hash SpacialHash::CellRec *recs; int numCells = faceHash.getCells(&recs, pTest); // initialise the closest point algorithm inf->num = 0; inf->triangle = 0; inf->type = DIST_TYPE_INVALID; double minD = REAL_MAX; double stopBelowSqr = -1; if (stopBelow > 0) stopBelowSqr = stopBelow*stopBelow; for (int i = 0; i < numCells; i++){ SpacialHash::CellRec rec = recs[i]; if (rec.d <= minD){ Array<int> *cell = faceHash.getCell(rec.i, rec.j, rec.k); getClosestPointINTERNAL(inf, &minD, pTest, s, stopBelowSqr, cell, &flags, &vertexFlags); if (minD < stopBelowSqr){ delete recs; return sqrt(minD); } } } delete recs; return sqrt(minD); }
// NOT WORKING YET double getClosestPoint(ClosestPointInfo *inf, const Point3D &pTest, const Surface &s, const SpacialHash &faceHash, float stopBelow){ // get the dimensions and size of the grid int nX = faceHash.getDimX(); int nY = faceHash.getDimY(); int nZ = faceHash.getDimZ(); float cellSize = faceHash.getSize(); // work out the MAX ring number (doesn't really need to be small) int maxRing = nX; if (nY > maxRing) maxRing = nY; if (nZ > maxRing) maxRing = nZ; // get the cell int Cx, Cy, Cz; faceHash.getBoundedIndices(&Cx, &Cy, &Cz, pTest); // flags for used triangles Array<bool> flags(s.triangles.getSize()); flags.clear(); // flags for whether point has been tested Array<bool> vertexFlags(s.vertices.getSize()); vertexFlags.clear(); // initialise the closest point algorithm inf->num = 0; inf->triangle = 0; inf->type = DIST_TYPE_INVALID; double minD = REAL_MAX; double stopBelowSqr = -1; if (stopBelow > 0) stopBelowSqr = stopBelow*stopBelow; // process the first cell Array<int> *cell = faceHash.getCell(Cx, Cy, Cz); if (cell->getSize()) getClosestPointINTERNAL(inf, &minD, pTest, s, stopBelowSqr, cell, &flags, &vertexFlags); #define DOCELL() { \ Array<int> *cell = faceHash.getCell(x, y, z); \ if (cell->getSize() && faceHash.getDistanceSQR(x, y, z, pTest) < minD){ \ getClosestPointINTERNAL(inf, &minD, pTest, s, stopBelowSqr, cell, &flags, &vertexFlags); \ if (minD < stopBelowSqr) \ return sqrt(minD); \ } } \ // process rings int x, y, z; for (int ring = 1; ring <= maxRing; ring++){ // check for terminate of ring double d = (ring-1)*cellSize; if (d*d > minD) return sqrt(minD); // done // get clamped bounds for the ring int minX = Cx - ring; if (minX < 0) minX = 0; int minY = Cy - ring; if (minY < 0) minY = 0; int minZ = Cz - ring; if (minZ < 0) minZ = 0; int maxX = Cx + ring; if (maxX >= nX) maxX = nX-1; int maxY = Cy + ring; if (maxY >= nY) maxY = nY-1; int maxZ = Cz + ring; if (maxZ >= nZ) maxZ = nZ-1; // top y = Cy - ring; if (y >= 0){ for (x = minX; x <= maxX; x++) for (z = minZ; z <= maxZ; z++) DOCELL(); } // bottom y = Cy + ring; if (y < nY){ for (x = minX; x <= maxX; x++) for (z = minZ; z <= maxZ; z++) DOCELL(); } // work out the starting points int localMinY = Cy - ring + 1; // top and bottom already done if (localMinY < minY) localMinY = minY; int localMaxY = Cy + ring - 1; if (localMaxY > maxY) localMaxY = maxY; int localMinZ = Cz - ring; if (localMinZ < minZ) localMinZ = minZ; int localMaxZ = Cz + ring; if (localMaxZ > maxZ) localMaxZ = maxZ; // left x = Cx - ring; if (x >= 0){ for (y = localMinY; y <= localMaxY; y++) for (z = localMinZ; z <= localMaxZ; z++) DOCELL(); } // right x = Cx + ring; if (x < nX){ for (y = localMinY; y <= localMaxY; y++) for (z = localMinZ; z <= localMaxZ; z++) DOCELL(); } // work out the starting points int localMinX = Cx - ring + 1; // left and right already done if (localMinX < minX) localMinX = minX; int localMaxX = Cx + ring - 1; if (localMaxX > maxX) localMaxX = maxX; // front z = Cz - ring; if (z > 0){ for (x = localMinX; x <= localMaxX; x++) for (y = localMinY; y <= localMaxY; y++) DOCELL(); } // back z = Cz + ring; if (z < nZ){ for (x = localMinX; x <= localMaxX; x++) for (y = localMinY; y <= localMaxY; y++) DOCELL(); } } return sqrt(minD); }