bool Graph::EdgeCollapse(long v1, long v2) { long edgeToDelete = GetEdgeID(v1, v2); if (edgeToDelete >= 0) { // delete the edge (v1, v2) DeleteEdge(edgeToDelete); // add v2 to v1 ancestors m_vertices[v1].m_ancestors.push_back(v2); // add v2's ancestors to v1's ancestors m_vertices[v1].m_ancestors.insert(m_vertices[v1].m_ancestors.begin(), m_vertices[v2].m_ancestors.begin(), m_vertices[v2].m_ancestors.end()); // update adjacency information SArray<long, SARRAY_DEFAULT_MIN_SIZE> & v1Edges = m_vertices[v1].m_edges; long b = -1; long idEdge; for(size_t ed = 0; ed < m_vertices[v2].m_edges.Size(); ++ed) { idEdge = m_vertices[v2].m_edges[ed]; if (m_edges[idEdge].m_v1 == v2) { b = m_edges[idEdge].m_v2; } else { b = m_edges[idEdge].m_v1; } if (GetEdgeID(v1, b) >= 0) { m_edges[idEdge].m_deleted = true; m_vertices[b].DeleteEdge(idEdge); m_nE--; } else { m_edges[idEdge].m_v1 = v1; m_edges[idEdge].m_v2 = b; v1Edges.Insert(idEdge); } } // delete the vertex v2 DeleteVertex(v2); return true; } return false; }
bool Graph::EdgeCollapse(long v1, long v2) { long edgeToDelete = GetEdgeID(v1, v2); if (edgeToDelete >= 0) { // delete the edge (v1, v2) DeleteEdge(edgeToDelete); // add v2 to v1 ancestors m_vertices[v1].m_ancestors.push_back(v2); // add v2's ancestors to v1's ancestors m_vertices[v1].m_ancestors.insert(m_vertices[v1].m_ancestors.begin(), m_vertices[v2].m_ancestors.begin(), m_vertices[v2].m_ancestors.end()); // update adjacency information std::set<long> & v1Edges = m_vertices[v1].m_edges; std::set<long>::const_iterator ed(m_vertices[v2].m_edges.begin()); std::set<long>::const_iterator itEnd(m_vertices[v2].m_edges.end()); long b = -1; for(; ed != itEnd; ++ed) { if (m_edges[*ed].m_v1 == v2) { b = m_edges[*ed].m_v2; } else { b = m_edges[*ed].m_v1; } if (GetEdgeID(v1, b) >= 0) { m_edges[*ed].m_deleted = true; m_vertices[b].DeleteEdge(*ed); m_nE--; } else { m_edges[*ed].m_v1 = v1; m_edges[*ed].m_v2 = b; v1Edges.insert(*ed); } } // delete the vertex v2 DeleteVertex(v2); return true; } return false; }
template <class T> void CIsoSurface<T>::GenerateSurface(const T* ptScalarField, T tIsoLevel, unsigned int nCellsX, unsigned int nCellsY, unsigned int nCellsZ, float fCellLengthX, float fCellLengthY, float fCellLengthZ) { if (m_bValidSurface) DeleteSurface(); m_tIsoLevel = tIsoLevel; m_nCellsX = nCellsX; m_nCellsY = nCellsY; m_nCellsZ = nCellsZ; m_fCellLengthX = fCellLengthX; m_fCellLengthY = fCellLengthY; m_fCellLengthZ = fCellLengthZ; m_ptScalarField = ptScalarField; unsigned int nPointsInXDirection = (m_nCellsX + 1); unsigned int nPointsInSlice = nPointsInXDirection*(m_nCellsY + 1); // Generate isosurface. for (unsigned int z = 0; z < m_nCellsZ; z++) for (unsigned int y = 0; y < m_nCellsY; y++) for (unsigned int x = 0; x < m_nCellsX; x++) { // Calculate table lookup index from those // vertices which are below the isolevel.% unsigned int tableIndex = 0; if (m_ptScalarField[z*nPointsInSlice + y*nPointsInXDirection + x] < m_tIsoLevel) tableIndex |= 1; if (m_ptScalarField[z*nPointsInSlice + (y+1)*nPointsInXDirection + x] < m_tIsoLevel) tableIndex |= 2; if (m_ptScalarField[z*nPointsInSlice + (y+1)*nPointsInXDirection + (x+1)] < m_tIsoLevel) tableIndex |= 4; if (m_ptScalarField[z*nPointsInSlice + y*nPointsInXDirection + (x+1)] < m_tIsoLevel) tableIndex |= 8; if (m_ptScalarField[(z+1)*nPointsInSlice + y*nPointsInXDirection + x] < m_tIsoLevel) tableIndex |= 16; if (m_ptScalarField[(z+1)*nPointsInSlice + (y+1)*nPointsInXDirection + x] < m_tIsoLevel) tableIndex |= 32; if (m_ptScalarField[(z+1)*nPointsInSlice + (y+1)*nPointsInXDirection + (x+1)] < m_tIsoLevel) tableIndex |= 64; if (m_ptScalarField[(z+1)*nPointsInSlice + y*nPointsInXDirection + (x+1)] < m_tIsoLevel) tableIndex |= 128; // Now create a triangulation of the isosurface in this // cell. if (m_edgeTable[tableIndex] != 0) { if (m_edgeTable[tableIndex] & 8) { POINT3DID pt = CalculateIntersection(x, y, z, 3); unsigned int id = GetEdgeID(x, y, z, 3); m_i2pt3idVertices.insert(ID2POINT3DID::value_type(id, pt)); } if (m_edgeTable[tableIndex] & 1) { POINT3DID pt = CalculateIntersection(x, y, z, 0); unsigned int id = GetEdgeID(x, y, z, 0); m_i2pt3idVertices.insert(ID2POINT3DID::value_type(id, pt)); } if (m_edgeTable[tableIndex] & 256) { POINT3DID pt = CalculateIntersection(x, y, z, 8); unsigned int id = GetEdgeID(x, y, z, 8); m_i2pt3idVertices.insert(ID2POINT3DID::value_type(id, pt)); } if (x == m_nCellsX - 1) { if (m_edgeTable[tableIndex] & 4) { POINT3DID pt = CalculateIntersection(x, y, z, 2); unsigned int id = GetEdgeID(x, y, z, 2); m_i2pt3idVertices.insert(ID2POINT3DID::value_type(id, pt)); } if (m_edgeTable[tableIndex] & 2048) { POINT3DID pt = CalculateIntersection(x, y, z, 11); unsigned int id = GetEdgeID(x, y, z, 11); m_i2pt3idVertices.insert(ID2POINT3DID::value_type(id, pt)); } } if (y == m_nCellsY - 1) { if (m_edgeTable[tableIndex] & 2) { POINT3DID pt = CalculateIntersection(x, y, z, 1); unsigned int id = GetEdgeID(x, y, z, 1); m_i2pt3idVertices.insert(ID2POINT3DID::value_type(id, pt)); } if (m_edgeTable[tableIndex] & 512) { POINT3DID pt = CalculateIntersection(x, y, z, 9); unsigned int id = GetEdgeID(x, y, z, 9); m_i2pt3idVertices.insert(ID2POINT3DID::value_type(id, pt)); } } if (z == m_nCellsZ - 1) { if (m_edgeTable[tableIndex] & 16) { POINT3DID pt = CalculateIntersection(x, y, z, 4); unsigned int id = GetEdgeID(x, y, z, 4); m_i2pt3idVertices.insert(ID2POINT3DID::value_type(id, pt)); } if (m_edgeTable[tableIndex] & 128) { POINT3DID pt = CalculateIntersection(x, y, z, 7); unsigned int id = GetEdgeID(x, y, z, 7); m_i2pt3idVertices.insert(ID2POINT3DID::value_type(id, pt)); } } if ((x==m_nCellsX - 1) && (y==m_nCellsY - 1)) if (m_edgeTable[tableIndex] & 1024) { POINT3DID pt = CalculateIntersection(x, y, z, 10); unsigned int id = GetEdgeID(x, y, z, 10); m_i2pt3idVertices.insert(ID2POINT3DID::value_type(id, pt)); } if ((x==m_nCellsX - 1) && (z==m_nCellsZ - 1)) if (m_edgeTable[tableIndex] & 64) { POINT3DID pt = CalculateIntersection(x, y, z, 6); unsigned int id = GetEdgeID(x, y, z, 6); m_i2pt3idVertices.insert(ID2POINT3DID::value_type(id, pt)); } if ((y==m_nCellsY - 1) && (z==m_nCellsZ - 1)) if (m_edgeTable[tableIndex] & 32) { POINT3DID pt = CalculateIntersection(x, y, z, 5); unsigned int id = GetEdgeID(x, y, z, 5); m_i2pt3idVertices.insert(ID2POINT3DID::value_type(id, pt)); } for (unsigned int i = 0; m_triTable[tableIndex][i] != -1; i += 3) { TRIANGLE triangle; unsigned int pointID0, pointID1, pointID2; pointID0 = GetEdgeID(x, y, z, m_triTable[tableIndex][i]); pointID1 = GetEdgeID(x, y, z, m_triTable[tableIndex][i+1]); pointID2 = GetEdgeID(x, y, z, m_triTable[tableIndex][i+2]); triangle.pointID[0] = pointID0; triangle.pointID[1] = pointID1; triangle.pointID[2] = pointID2; m_trivecTriangles.push_back(triangle); } } } RenameVerticesAndTriangles(); CalculateNormals(); m_bValidSurface = true; }