Exemplo n.º 1
0
//----------------------------------------------------------------------------
bool MTMesh::Remove (int label0, int label1, int label2)
{
	TIter iter = mTMap.find(MTITriangle(label0, label1, label2));
	if (iter == mTMap.end())
	{
		// The triangle does not exist.
		return false;
	}
	int t = iter->second;

	MTTriangle& triangle = mTriangles[t];

	// Detach triangle from edges.
	int e0 = triangle.Edge(0);
	int e1 = triangle.Edge(1);
	int e2 = triangle.Edge(2);
	MTEdge& edge0 = mEdges[e0];
	MTEdge& edge1 = mEdges[e1];
	MTEdge& edge2 = mEdges[e2];
	DetachTriangleFromEdge(t, triangle, 0, e0, edge0);
	DetachTriangleFromEdge(t, triangle, 1, e1, edge1);
	DetachTriangleFromEdge(t, triangle, 2, e2, edge2);

	// Detach triangle from vertices.
	int v0 = triangle.Vertex(0);
	MTVertex& vertex0 = mVertices[v0];
	vertex0.RemoveTriangle(t);

	int v1 = triangle.Vertex(1);
	MTVertex& vertex1 = mVertices[v1];
	vertex1.RemoveTriangle(t);

	int v2 = triangle.Vertex(2);
	MTVertex& vertex2 = mVertices[v2];
	vertex2.RemoveTriangle(t);

	// Detach edges from vertices (only if last edge to reference vertex).
	bool e0Destroy = (edge0.Triangle(0) == -1);
	if (e0Destroy)
	{
		vertex0.RemoveEdge(e0);
		vertex1.RemoveEdge(e0);
	}

	bool e1Destroy = (edge1.Triangle(0) == -1);
	if (e1Destroy)
	{
		vertex1.RemoveEdge(e1);
		vertex2.RemoveEdge(e1);
	}

	bool e2Destroy = (edge2.Triangle(0) == -1);
	if (e2Destroy)
	{
		vertex0.RemoveEdge(e2);
		vertex2.RemoveEdge(e2);
	}

	// Removal of components from the sets and maps starts here.  Be careful
	// using set indices, component references, and map iterators since
	// deletion has side effects.  Deletion of a component might cause another
	// component to be moved within the corresponding set or map.
	bool v0Destroy = (vertex0.GetNumEdges() == 0);
	bool v1Destroy = (vertex1.GetNumEdges() == 0);
	bool v2Destroy = (vertex2.GetNumEdges() == 0);

	// Remove edges if no longer used.
	if (e0Destroy)
	{
		RemoveEdge(label0, label1);
	}

	if (e1Destroy)
	{
		RemoveEdge(label1, label2);
	}

	if (e2Destroy)
	{
		RemoveEdge(label2, label0);
	}

	// Remove vertices if no longer used.
	if (v0Destroy)
	{
		RemoveVertex(label0);
	}

	if (v1Destroy)
	{
		RemoveVertex(label1);
	}

	if (v2Destroy)
	{
		RemoveVertex(label2);
	}

	// Remove triangle (definitely no longer used).
	RemoveTriangle(label0, label1, label2);
	return true;
}
Exemplo n.º 2
0
void CMesh::CollapseEdge(TEdge *pEdge, bool bRemoveSecond)
{
  TVertex *p2Remain, *p2Remove;
  CArray<TVertex *> arrInvalVerts;
  TEdgeHash hashEvaluatedEdges;
  int i, iTri;
  ASSERT(pEdge);
  p2Remain = pEdge->m_pVertices[!bRemoveSecond];
  p2Remove = pEdge->m_pVertices[bRemoveSecond];

  for (i = 0; i < p2Remove->m_pTriangles->m_iCount; i++) {
    TVertex *pOther0, *pOther1;
    p2Remove->m_pTriangles->At(i)->GetOtherVertices(p2Remove, pOther0, pOther1);
    arrInvalVerts.Append(pOther0);
    arrInvalVerts.Append(pOther1);
  }

  ASSERT(pEdge->m_pTriangles[0]);
  // Order of removal is important, if we remove the first one first and it's the only one left, 
  // the edge will get deleted and the attempt to remove the other one will crash
  RemoveTriangle(pEdge->m_pTriangles[1]); 
  RemoveTriangle(pEdge->m_pTriangles[0]);
  ASSERT(!GetEdge(p2Remain, p2Remove));

/*
#ifdef _DEBUG
  {
    for (int i = 0; i < p2Remove->m_pTriangles->m_iCount; i++) {
      TVertex *pVert0, *pVert1;
      TTriangle *pTri = p2Remove->m_pTriangles->At(i);
      pTri->GetOtherVertices(p2Remove, pVert0, pVert1);
      TTriangle kTestTri(p2Remain, pVert0, pVert1);
      TTriangleHash::TIter it = m_hashTriangles.Find(&kTestTri);
      ASSERT(!it);
      if (it)
        TEdge *pE = GetEdge(pVert0, pVert1);
    }
  }
#endif
*/

  while (p2Remove->m_pTriangles->m_iCount > 0) {
    TVertex *pVert0, *pVert1;
    TTriangle *pTri = p2Remove->m_pTriangles->At(p2Remove->m_pTriangles->m_iCount - 1);
    pTri->GetOtherVertices(p2Remove, pVert0, pVert1);
    int iTriIndex = pTri->m_iIndex;
    RemoveTriangle(pTri);
    AddTriangle(p2Remain, pVert0, pVert1, iTriIndex);
  }
  m_hashVertices.RemoveValue(p2Remove);
  delete p2Remove;

  for (i = 0; i < arrInvalVerts.m_iCount; i++) {
    for (iTri = 0; iTri < arrInvalVerts[i]->m_pTriangles->m_iCount; iTri++) {
      TVertex *pOther[2];
      TEdge *pEdge;
      int iVert;
      arrInvalVerts[i]->m_pTriangles->At(iTri)->GetOtherVertices(arrInvalVerts[i], pOther[0], pOther[1]);
      for (iVert = 0; iVert < 2; iVert++) {
        pEdge = GetEdge(arrInvalVerts[i], pOther[iVert]);
        if (hashEvaluatedEdges.Find(pEdge))
          continue;
        EvaluateEdge(pEdge, false);
        EvaluateEdge(pEdge, true);
        hashEvaluatedEdges.Add(pEdge);
      }
    }
  }
}