Work on mesh decimation.

This commit is contained in:
David Williams 2007-09-18 15:41:59 +00:00
parent 377b7a5cdd
commit 336eba9680
6 changed files with 82 additions and 23 deletions

View File

@ -46,7 +46,7 @@ namespace Ogre
SurfaceEdgeIterator otherHalfEdge; SurfaceEdgeIterator otherHalfEdge;
//FIXME - could use boost::optional for this? //FIXME - could use boost::optional for this?
bool hasOtherHalfEdge; bool hasTriangle;
SurfaceEdge(); SurfaceEdge();

View File

@ -40,8 +40,8 @@ namespace Ogre
UIntVector3 position; UIntVector3 position;
Vector3 normal; Vector3 normal;
float alpha; float alpha;
uchar flags; //uchar flags;
uchar noOfUses; //uchar noOfUses;
bool fixed; bool fixed;

View File

@ -1010,7 +1010,7 @@ namespace Ogre
iterPatch->second.computeNormalsFromVolume(volIter); iterPatch->second.computeNormalsFromVolume(volIter);
iterPatch->second.endDefinition(); iterPatch->second.endDefinition();
bool removedVertex = false; bool removedVertex = false;
for(uint ct = 0; ct < 2; ct++) for(uint ct = 0; ct < 10; ct++)
//do //do
{ {
removedVertex = iterPatch->second.decimate3(); removedVertex = iterPatch->second.decimate3();

View File

@ -5,14 +5,14 @@
namespace Ogre namespace Ogre
{ {
SurfaceEdge::SurfaceEdge() SurfaceEdge::SurfaceEdge()
:hasOtherHalfEdge(false) :hasTriangle(false)
{ {
} }
std::string SurfaceEdge::toString(void) std::string SurfaceEdge::toString(void)
{ {
std::stringstream ss; std::stringstream ss;
ss << "SurfaceEdge: Target Vertex = " << target->toString(); ss << "SurfaceEdge: Target Vertex = " << target->toString() << "Source Vertex = " << otherHalfEdge->target->toString();
return ss.str(); return ss.str();
} }
@ -21,7 +21,8 @@ namespace Ogre
return return
( (
(lhs.target == rhs.target) && (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.target == rhs.target)
{ {
if(lhs.triangle == rhs.triangle) if(lhs.otherHalfEdge->target == rhs.otherHalfEdge->target)
{ {
return false; return false;
} }
return (*(lhs.triangle) < *(rhs.triangle)); return (*(lhs.otherHalfEdge->target) < *(rhs.otherHalfEdge->target));
} }
return (*(lhs.target) < *(rhs.target)); return (*(lhs.target) < *(rhs.target));
} }

View File

@ -97,14 +97,38 @@ namespace Ogre
v2Iter = m_listVertices.end(); v2Iter = m_listVertices.end();
v2Iter--; v2Iter--;
} }
v0Iter->noOfUses++;
v1Iter->noOfUses++;
v2Iter->noOfUses++;
//else //else
//LogManager::getSingleton().logMessage("Already Exists " + StringConverter::toString(v2.position.x) + "," + StringConverter::toString(v2.position.y) + "," + StringConverter::toString(v2.position.z)); //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"); //LogManager::getSingleton().logMessage("Creating Edges");
SurfaceEdge v0v1; SurfaceEdge v0v1;
v0v1.target = v1Iter; v0v1.target = v1Iter;
@ -146,6 +170,10 @@ namespace Ogre
v0v1Iter->triangle = iterTriangle; v0v1Iter->triangle = iterTriangle;
v1v2Iter->triangle = iterTriangle; v1v2Iter->triangle = iterTriangle;
v2v0Iter->triangle = iterTriangle; v2v0Iter->triangle = iterTriangle;
v0v1Iter->hasTriangle = true;
v1v2Iter->hasTriangle = true;
v2v0Iter->hasTriangle = true;
} }
void SurfacePatch::computeNormalsFromVolume(VolumeIterator volIter) void SurfacePatch::computeNormalsFromVolume(VolumeIterator volIter)
@ -279,18 +307,21 @@ namespace Ogre
void SurfacePatch::computeOtherHalfEdges(void) void SurfacePatch::computeOtherHalfEdges(void)
{ {
LogManager::getSingleton().logMessage("Computing other half edges");
//Clear all other edges //Clear all other edges
for(SurfaceEdgeIterator edgeIter = m_listEdges.begin(); edgeIter != m_listEdges.end(); ++edgeIter) for(SurfaceEdgeIterator edgeIter = m_listEdges.begin(); edgeIter != m_listEdges.end(); ++edgeIter)
{ {
edgeIter->otherHalfEdge = m_listEdges.end(); edgeIter->otherHalfEdge = m_listEdges.end();
edgeIter->hasOtherHalfEdge = false;
} }
//FIXME - speed this up by storing edges in a container which sorts by edge 'target'. //FIXME - speed this up by storing edges in a container which sorts by edge 'target'.
std::list<SurfaceEdge> listAddedEdges;
//Assign all other edges //Assign all other edges
for(SurfaceEdgeIterator outerEdgeIter = m_listEdges.begin(); outerEdgeIter != m_listEdges.end(); ++outerEdgeIter) 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) for(SurfaceEdgeIterator innerEdgeIter = m_listEdges.begin(); innerEdgeIter != m_listEdges.end(); ++innerEdgeIter)
{ {
if((innerEdgeIter->target == outerEdgeIter->previousHalfEdge->target) && (outerEdgeIter->target == innerEdgeIter->previousHalfEdge->target)) if((innerEdgeIter->target == outerEdgeIter->previousHalfEdge->target) && (outerEdgeIter->target == innerEdgeIter->previousHalfEdge->target))
@ -298,11 +329,34 @@ namespace Ogre
innerEdgeIter->otherHalfEdge = outerEdgeIter; innerEdgeIter->otherHalfEdge = outerEdgeIter;
outerEdgeIter->otherHalfEdge = innerEdgeIter; outerEdgeIter->otherHalfEdge = innerEdgeIter;
innerEdgeIter->hasOtherHalfEdge = true; foundOtherHalf = true;
outerEdgeIter->hasOtherHalfEdge = 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) bool SurfacePatch::decimate3(void)
@ -325,11 +379,15 @@ namespace Ogre
SurfaceEdgeIterator nextEdge = firstEdge; SurfaceEdgeIterator nextEdge = firstEdge;
do do
{ {
if(nextEdge->hasTriangle == false)
{
break;
}
listConnectedVertices.push_back(nextEdge->target); listConnectedVertices.push_back(nextEdge->target);
nextEdge = nextEdge->nextHalfEdge->nextHalfEdge->otherHalfEdge; nextEdge = nextEdge->nextHalfEdge->nextHalfEdge->otherHalfEdge;
}while((nextEdge != firstEdge) && (nextEdge != m_listEdges.end())); }while((nextEdge != firstEdge) && (nextEdge != m_listEdges.end()));
if(nextEdge == m_listEdges.end()) if(nextEdge->hasTriangle == false)
{ {
continue; continue;
} }

View File

@ -14,7 +14,7 @@ namespace Ogre
SurfaceVertex::SurfaceVertex(UIntVector3 positionToSet) SurfaceVertex::SurfaceVertex(UIntVector3 positionToSet)
:position(positionToSet) :position(positionToSet)
{ {
noOfUses = 0; /*noOfUses = 0;
flags = 0; flags = 0;
if(position.x == 0) if(position.x == 0)
flags |= 1; flags |= 1;
@ -27,14 +27,14 @@ namespace Ogre
if(position.z == 0) if(position.z == 0)
flags |= 16; flags |= 16;
if(position.z == 8) if(position.z == 8)
flags |= 32; flags |= 32;*/
} }
SurfaceVertex::SurfaceVertex(UIntVector3 positionToSet, Vector3 normalToSet) SurfaceVertex::SurfaceVertex(UIntVector3 positionToSet, Vector3 normalToSet)
:position(positionToSet) :position(positionToSet)
,normal(normalToSet) ,normal(normalToSet)
{ {
noOfUses = 0; /*noOfUses = 0;
flags = 0; flags = 0;
if(position.x == 0) if(position.x == 0)
flags |= 1; flags |= 1;
@ -47,13 +47,13 @@ namespace Ogre
if(position.z == 0) if(position.z == 0)
flags |= 16; flags |= 16;
if(position.z == 8) if(position.z == 8)
flags |= 32; flags |= 32;*/
} }
std::string SurfaceVertex::toString(void) std::string SurfaceVertex::toString(void)
{ {
std::stringstream ss; 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(); return ss.str();
} }