Axiom.Core.ProgressiveMesh.Collapse C# (CSharp) Method

Collapse() public method

Internal method, collapses vertex onto it's saved collapse target.
This updates the working triangle list to drop a triangle and recalculates the edge collapse costs around the collapse target. This also updates all the working vertex lists for the relevant buffer.
public Collapse ( PMVertex src ) : void
src PMVertex
return void
		void Collapse( PMVertex src )
		{
			PMVertex dest = src.collapseTo;
			List<PMVertex> recomputeSet = new List<PMVertex>();

			// Abort if we're never supposed to collapse
			if ( src.collapseCost == float.MaxValue )
				return;

			// Remove this vertex from the running for the next check
			src.collapseTo = null;
			src.collapseCost = float.MaxValue;
			worstCosts[ (int)src.index ] = float.MaxValue;

			// Collapse the edge uv by moving vertex u onto v
			// Actually remove tris on uv, then update tris that
			// have u to have v, and then remove u.
			if ( dest == null )
			{
				// src is a vertex all by itself 
				return;
			}

			// Add dest and all the neighbours of source and dest to recompute list
			recomputeSet.Add( dest );

			foreach ( PMVertex neighbor in src.neighbors )
			{
				if ( !recomputeSet.Contains( neighbor ) )
					recomputeSet.Add( neighbor );
			}
			foreach ( PMVertex neighbor in dest.neighbors )
			{
				if ( !recomputeSet.Contains( neighbor ) )
					recomputeSet.Add( neighbor );
			}

			// delete triangles on edge src-dest
			// Notify others to replace src with dest
			// Queue of faces for removal / replacement
			// prevents us screwing up the iterators while we parse
			List<PMTriangle> faceRemovalList = new List<PMTriangle>();
			List<PMTriangle> faceReplacementList = new List<PMTriangle>();

			foreach ( PMTriangle face in src.faces )
			{
				if ( face.HasCommonVertex( dest ) )
				{
					// Tri is on src-dest therefore is gone
					faceRemovalList.Add( face );
					// Reduce index count by 3 (useful for quick allocation later)
					currNumIndexes -= 3;
				}
				else
				{
					// Only src involved, replace with dest
					faceReplacementList.Add( face );
				}
			}

			src.toBeRemoved = true;
			// Replace all the faces queued for replacement
			foreach ( PMTriangle face in faceReplacementList )
			{
				/* Locate the face vertex which corresponds with the common 'dest' vertex
				   To to this, find a removed face which has the FACE vertex corresponding with
				   src, and use it's FACE vertex version of dest.
				*/
				PMFaceVertex srcFaceVert = face.GetFaceVertexFromCommon( src );
				PMFaceVertex destFaceVert = null;
				foreach ( PMTriangle removed in faceRemovalList )
				{
					//if (removed.HasFaceVertex(srcFaceVert))
					//{
					destFaceVert = removed.GetFaceVertexFromCommon( dest );
					//}
				}

				Debug.Assert( destFaceVert != null );

				face.ReplaceVertex( srcFaceVert, destFaceVert );
			}
			// Remove all the faces queued for removal
			foreach ( PMTriangle face in faceRemovalList )
			{
				face.NotifyRemoved();
			}

			// Notify the vertex that it is gone
			src.NotifyRemoved();

			// recompute costs
			foreach ( PMVertex recomp in recomputeSet )
			{
				ComputeEdgeCostAtVertex( recomp.index );
			}
		}
		#endregion