NonmanifoldLevel::NonmanifoldLevel(subdivision::Mesh& subdivision) { VertexPositionMapType averagedCenters; VertexPositionMapType averagedMidpoints; VertexEdgeCountMapType valencies; VertexAdjacencyMapType cornerAdjacentMaps; VertexAdjacencyMapType midpointAdjacentMaps; VertexVectorType corners; VertexVertexMapType vertexMap; for (int i = 0; i < subdivision.getNumberVertices(); i++) { subdivision::Vertex& vertex = subdivision.getVertex(i); subdivision::Vertex& created = createVertex(vertex); corners.push_back(&created); vertexMap[&vertex] = &created; valencies[&created] = 0; float* averagedCenter = new float[3]; averagedCenters[&created] = averagedCenter; averagedCenter[0] = 0; averagedCenter[1] = 0; averagedCenter[2] = 0; float* averagedEnd = new float[3]; averagedMidpoints[&created] = averagedEnd; averagedEnd[0] = 0; averagedEnd[1] = 0; averagedEnd[2] = 0; } VertexVectorType midpoints; for (int i = 0; i < subdivision.getNumberEdges(); i++) { subdivision::Edge& edge = subdivision.getEdge(i); subdivision::HalfEdge& firstHalfEdge = edge.getFirstHalf(); subdivision::HalfEdge& secondHalfEdge = edge.getSecondHalf(); subdivision::Vertex& fromVertex = firstHalfEdge.getFromVertex(); subdivision::Vertex& toVertex = firstHalfEdge.getToVertex(); subdivision::Vertex* midpoint = new subdivision::Vertex(); midpoints.push_back(midpoint); _subdivision.add(*midpoint); float* averagedCenter = new float[3]; averagedCenters[midpoint] = averagedCenter; averagedCenter[0] = 0; averagedCenter[1] = 0; averagedCenter[2] = 0; _midpointMappings[&firstHalfEdge] = midpoint; _midpointMappings[&secondHalfEdge] = midpoint; subdivision::Vertex* mappedFromVertex = vertexMap[&fromVertex]; subdivision::Vertex* mappedToVertex = vertexMap[&toVertex]; valencies[mappedFromVertex]++; valencies[mappedToVertex]++; _subdivision.createEdge(*mappedFromVertex, *midpoint); _subdivision.createEdge(*midpoint, *mappedToVertex); midpoint->_coordinates[0] = fromVertex._coordinates[0] + toVertex._coordinates[0]; midpoint->_coordinates[1] = fromVertex._coordinates[1] + toVertex._coordinates[1]; midpoint->_coordinates[2] = fromVertex._coordinates[2] + toVertex._coordinates[2]; midpoint->_coordinates[3] = 1; averagedMidpoints[mappedFromVertex][0] += midpoint->_coordinates[0]; averagedMidpoints[mappedFromVertex][1] += midpoint->_coordinates[1]; averagedMidpoints[mappedFromVertex][2] += midpoint->_coordinates[2]; averagedMidpoints[mappedToVertex][0] += midpoint->_coordinates[0]; averagedMidpoints[mappedToVertex][1] += midpoint->_coordinates[1]; averagedMidpoints[mappedToVertex][2] += midpoint->_coordinates[2]; } VertexVectorType centers; for (int i = 0; i < subdivision.getNumberFaces(); i++) { subdivision::Face& face = subdivision.getFace(i); subdivision::Vertex* center = new subdivision::Vertex(); centers.push_back(center); _centerMappings[&face] = center; _subdivision.add(*center); for (int j = 0; j < face.getNumberHalfEdges(); j++) { subdivision::HalfEdge& halfEdge = face.getHalfEdge(j); subdivision::Vertex* midpoint = _midpointMappings[&halfEdge]; subdivision::Edge* edge = _subdivision.createEdge(*midpoint, *center); } center->_coordinates[0] = 0; center->_coordinates[1] = 0; center->_coordinates[2] = 0; center->_coordinates[3] = 1; for (int j = 0; j < face.getNumberVertices(); j++) { subdivision::Vertex& vertex = face.getVertex(j); center->_coordinates[0] += vertex._coordinates[0]; center->_coordinates[1] += vertex._coordinates[1]; center->_coordinates[2] += vertex._coordinates[2]; } center->_coordinates[0] /= face.getNumberVertices(); center->_coordinates[1] /= face.getNumberVertices(); center->_coordinates[2] /= face.getNumberVertices(); } for (int i = 0; i < subdivision.getNumberFaces(); i++) { subdivision::Face& face = subdivision.getFace(i); subdivision::Vertex* center = _centerMappings[&face]; int numberEdges = face.getNumberHalfEdges(); subdivision::HalfEdge& lastHalfEdge = face.getHalfEdge(numberEdges - 1); subdivision::Vertex* last = _midpointMappings[&lastHalfEdge]; for (int j = 0; j < face.getNumberHalfEdges(); j++) { subdivision::HalfEdge& halfEdge = face.getHalfEdge(j); subdivision::Vertex& oldCorner = halfEdge.getFromVertex(); subdivision::Vertex* corner = vertexMap[&oldCorner]; subdivision::Vertex* next = _midpointMappings[&halfEdge]; _subdivision.createFace(*corner, *next, *center, *last); averagedCenters[next][0] += center->_coordinates[0]; averagedCenters[next][1] += center->_coordinates[1]; averagedCenters[next][2] += center->_coordinates[2]; averagedCenters[corner][0] += center->_coordinates[0]; averagedCenters[corner][1] += center->_coordinates[1]; averagedCenters[corner][2] += center->_coordinates[2]; last = next; } } for (int i = 0; i < corners.size(); i++) { subdivision::Vertex* corner = corners[i]; int valence = valencies[corner]; corner->_coordinates[0] *= (valence - 3) / 3; corner->_coordinates[1] *= (valence - 3) / 3; corner->_coordinates[2] *= (valence - 3) / 3; corner->_coordinates[0] += averagedMidpoints[corner][0] / (valence * 3); corner->_coordinates[1] += averagedMidpoints[corner][1] / (valence * 3); corner->_coordinates[2] += averagedMidpoints[corner][2] / (valence * 3); corner->_coordinates[0] += averagedCenters[corner][0] / (valence * 3); corner->_coordinates[1] += averagedCenters[corner][1] / (valence * 3); corner->_coordinates[2] += averagedCenters[corner][2] / (valence * 3); } for (int i = 0; i < midpoints.size(); i++) { subdivision::Vertex* midpoint = midpoints[i]; midpoint->_coordinates[0] += averagedCenters[midpoint][0]; midpoint->_coordinates[1] += averagedCenters[midpoint][1]; midpoint->_coordinates[2] += averagedCenters[midpoint][2]; midpoint->_coordinates[0] /= 4; midpoint->_coordinates[1] /= 4; midpoint->_coordinates[2] /= 4; } }