From 336eba96807203441be5ad51d6e190fe7f33ec26 Mon Sep 17 00:00:00 2001 From: David Williams Date: Tue, 18 Sep 2007 15:41:59 +0000 Subject: [PATCH] Work on mesh decimation. --- include/SurfaceEdge.h | 2 +- include/SurfaceVertex.h | 4 +- source/PolyVoxSceneManager.cpp | 2 +- source/SurfaceEdge.cpp | 11 ++--- source/SurfacePatch.cpp | 76 ++++++++++++++++++++++++++++++---- source/SurfaceVertex.cpp | 10 ++--- 6 files changed, 82 insertions(+), 23 deletions(-) diff --git a/include/SurfaceEdge.h b/include/SurfaceEdge.h index e41de3ac..ad3c9338 100644 --- a/include/SurfaceEdge.h +++ b/include/SurfaceEdge.h @@ -46,7 +46,7 @@ namespace Ogre SurfaceEdgeIterator otherHalfEdge; //FIXME - could use boost::optional for this? - bool hasOtherHalfEdge; + bool hasTriangle; SurfaceEdge(); diff --git a/include/SurfaceVertex.h b/include/SurfaceVertex.h index 05fe5555..f7ceeb0d 100644 --- a/include/SurfaceVertex.h +++ b/include/SurfaceVertex.h @@ -40,8 +40,8 @@ namespace Ogre UIntVector3 position; Vector3 normal; float alpha; - uchar flags; - uchar noOfUses; + //uchar flags; + //uchar noOfUses; bool fixed; diff --git a/source/PolyVoxSceneManager.cpp b/source/PolyVoxSceneManager.cpp index a6f0a458..0dcbffad 100644 --- a/source/PolyVoxSceneManager.cpp +++ b/source/PolyVoxSceneManager.cpp @@ -1010,7 +1010,7 @@ namespace Ogre iterPatch->second.computeNormalsFromVolume(volIter); iterPatch->second.endDefinition(); bool removedVertex = false; - for(uint ct = 0; ct < 2; ct++) + for(uint ct = 0; ct < 10; ct++) //do { removedVertex = iterPatch->second.decimate3(); diff --git a/source/SurfaceEdge.cpp b/source/SurfaceEdge.cpp index 3b0054d7..c302e9ab 100644 --- a/source/SurfaceEdge.cpp +++ b/source/SurfaceEdge.cpp @@ -5,14 +5,14 @@ namespace Ogre { SurfaceEdge::SurfaceEdge() - :hasOtherHalfEdge(false) + :hasTriangle(false) { } std::string SurfaceEdge::toString(void) { std::stringstream ss; - ss << "SurfaceEdge: Target Vertex = " << target->toString(); + ss << "SurfaceEdge: Target Vertex = " << target->toString() << "Source Vertex = " << otherHalfEdge->target->toString(); return ss.str(); } @@ -21,7 +21,8 @@ namespace Ogre return ( (lhs.target == rhs.target) && - (lhs.triangle == rhs.triangle) + //(lhs.triangle == rhs.triangle) + (lhs.otherHalfEdge->target == rhs.otherHalfEdge->target) ); } @@ -29,11 +30,11 @@ namespace Ogre { if(lhs.target == rhs.target) { - if(lhs.triangle == rhs.triangle) + if(lhs.otherHalfEdge->target == rhs.otherHalfEdge->target) { return false; } - return (*(lhs.triangle) < *(rhs.triangle)); + return (*(lhs.otherHalfEdge->target) < *(rhs.otherHalfEdge->target)); } return (*(lhs.target) < *(rhs.target)); } diff --git a/source/SurfacePatch.cpp b/source/SurfacePatch.cpp index 3243fba1..a34b5ade 100644 --- a/source/SurfacePatch.cpp +++ b/source/SurfacePatch.cpp @@ -97,14 +97,38 @@ namespace Ogre v2Iter = m_listVertices.end(); v2Iter--; } - - v0Iter->noOfUses++; - v1Iter->noOfUses++; - v2Iter->noOfUses++; - //else //LogManager::getSingleton().logMessage("Already Exists " + StringConverter::toString(v2.position.x) + "," + StringConverter::toString(v2.position.y) + "," + StringConverter::toString(v2.position.z)); + /*SurfaceEdgeIterator v0v1Iter = m_listEdges.end(); + SurfaceEdgeIterator v1v2Iter = m_listEdges.end(); + SurfaceEdgeIterator v2v0Iter = m_listEdges.end(); + SurfaceEdgeIterator v1v0Iter = m_listEdges.end(); + SurfaceEdgeIterator v2v1Iter = m_listEdges.end(); + SurfaceEdgeIterator v0v2Iter = m_listEdges.end(); + for(SurfaceEdgeIterator edgeIter = m_listEdges.begin(); edgeIter != m_listEdges.end(); ++edgeIter) + { + if((edgeIter->otherHalfEdge->target == v0) && (edgeIter->target == v1)) + v0v1Iter = edgeIter; + if((edgeIter->otherHalfEdge->target == v1) && (edgeIter->target == v2)) + v1v2Iter = edgeIter; + if((edgeIter->otherHalfEdge->target == v2) && (edgeIter->target == v0)) + v2v0Iter = edgeIter; + if((edgeIter->otherHalfEdge->target == v1) && (edgeIter->target == v0)) + v1v0Iter = edgeIter; + if((edgeIter->otherHalfEdge->target == v2) && (edgeIter->target == v1)) + v2v1Iter = edgeIter; + if((edgeIter->otherHalfEdge->target == v0) && (edgeIter->target == v2)) + v0v2Iter = edgeIter; + } + + if(v0v1Iter == m_listEdges.end()) + { + SurfaceEdge v0v1; + m_listEdges.push_back(v0v1); + SurfaceEdgeIterator v0v1ToAdd; + }*/ + //LogManager::getSingleton().logMessage("Creating Edges"); SurfaceEdge v0v1; v0v1.target = v1Iter; @@ -146,6 +170,10 @@ namespace Ogre v0v1Iter->triangle = iterTriangle; v1v2Iter->triangle = iterTriangle; v2v0Iter->triangle = iterTriangle; + + v0v1Iter->hasTriangle = true; + v1v2Iter->hasTriangle = true; + v2v0Iter->hasTriangle = true; } void SurfacePatch::computeNormalsFromVolume(VolumeIterator volIter) @@ -279,18 +307,21 @@ namespace Ogre void SurfacePatch::computeOtherHalfEdges(void) { + LogManager::getSingleton().logMessage("Computing other half edges"); //Clear all other edges for(SurfaceEdgeIterator edgeIter = m_listEdges.begin(); edgeIter != m_listEdges.end(); ++edgeIter) { edgeIter->otherHalfEdge = m_listEdges.end(); - edgeIter->hasOtherHalfEdge = false; } //FIXME - speed this up by storing edges in a container which sorts by edge 'target'. + std::list listAddedEdges; + //Assign all other edges for(SurfaceEdgeIterator outerEdgeIter = m_listEdges.begin(); outerEdgeIter != m_listEdges.end(); ++outerEdgeIter) { + bool foundOtherHalf = false; for(SurfaceEdgeIterator innerEdgeIter = m_listEdges.begin(); innerEdgeIter != m_listEdges.end(); ++innerEdgeIter) { if((innerEdgeIter->target == outerEdgeIter->previousHalfEdge->target) && (outerEdgeIter->target == innerEdgeIter->previousHalfEdge->target)) @@ -298,11 +329,34 @@ namespace Ogre innerEdgeIter->otherHalfEdge = outerEdgeIter; outerEdgeIter->otherHalfEdge = innerEdgeIter; - innerEdgeIter->hasOtherHalfEdge = true; - outerEdgeIter->hasOtherHalfEdge = true; + foundOtherHalf = true; } } + if(!foundOtherHalf) + { + SurfaceEdge tempEdge; + + tempEdge.otherHalfEdge = outerEdgeIter; + tempEdge.target = outerEdgeIter->nextHalfEdge->nextHalfEdge->target; + + listAddedEdges.push_back(tempEdge); + } } + + LogManager::getSingleton().logMessage("No of added edges = " + StringConverter::toString(listAddedEdges.size())); + + for(SurfaceEdgeIterator addedEdgeIter = listAddedEdges.begin(); addedEdgeIter != listAddedEdges.end(); ++addedEdgeIter) + { + LogManager::getSingleton().logMessage("Adding new edge"); + m_listEdges.push_back(*addedEdgeIter); + SurfaceEdgeIterator justAddedIter = m_listEdges.end(); + --justAddedIter; + + justAddedIter->otherHalfEdge->otherHalfEdge = justAddedIter; + LogManager::getSingleton().logMessage("Done adding new edge"); + } + + LogManager::getSingleton().logMessage("Done computing other half edges"); } bool SurfacePatch::decimate3(void) @@ -325,11 +379,15 @@ namespace Ogre SurfaceEdgeIterator nextEdge = firstEdge; do { + if(nextEdge->hasTriangle == false) + { + break; + } listConnectedVertices.push_back(nextEdge->target); nextEdge = nextEdge->nextHalfEdge->nextHalfEdge->otherHalfEdge; }while((nextEdge != firstEdge) && (nextEdge != m_listEdges.end())); - if(nextEdge == m_listEdges.end()) + if(nextEdge->hasTriangle == false) { continue; } diff --git a/source/SurfaceVertex.cpp b/source/SurfaceVertex.cpp index 1ca5a3eb..fb5a7785 100644 --- a/source/SurfaceVertex.cpp +++ b/source/SurfaceVertex.cpp @@ -14,7 +14,7 @@ namespace Ogre SurfaceVertex::SurfaceVertex(UIntVector3 positionToSet) :position(positionToSet) { - noOfUses = 0; + /*noOfUses = 0; flags = 0; if(position.x == 0) flags |= 1; @@ -27,14 +27,14 @@ namespace Ogre if(position.z == 0) flags |= 16; if(position.z == 8) - flags |= 32; + flags |= 32;*/ } SurfaceVertex::SurfaceVertex(UIntVector3 positionToSet, Vector3 normalToSet) :position(positionToSet) ,normal(normalToSet) { - noOfUses = 0; + /*noOfUses = 0; flags = 0; if(position.x == 0) flags |= 1; @@ -47,13 +47,13 @@ namespace Ogre if(position.z == 0) flags |= 16; if(position.z == 8) - flags |= 32; + flags |= 32;*/ } std::string SurfaceVertex::toString(void) { std::stringstream ss; - ss << "SurfaceVertex: Position = (" << position.x << "," << position.y << "," << position.z << "), Normal = " << StringConverter::toString(normal) << ", Flags = " << uint(flags); + ss << "SurfaceVertex: Position = (" << position.x << "," << position.y << "," << position.z << "), Normal = " << StringConverter::toString(normal); return ss.str(); }