Exemple #1
0
void ProgressiveMesh(std::vector<float3> &vert, std::vector<tridata> &tri,
                     std::vector<int> &map, std::vector<int> &permutation)
{
	AddVertex(vert);  // put input data into our data structures
	AddFaces(tri);
	ComputeAllEdgeCollapseCosts(); // cache all edge collapse costs
	permutation.resize(vertices.size());  // allocate space
	map.resize(vertices.size());          // allocate space
	// reduce the object down to nothing:
	while (vertices.size() > 0) {
		// get the next vertex to collapse
		Vertex *mn = MinimumCostEdge();
		// keep track of this vertex, i.e. the collapse ordering
		permutation[mn->id] = vertices.size() - 1;
		// keep track of vertex to which we collapse to
		map[vertices.size() - 1] = (mn->collapse) ? mn->collapse->id : -1;
		// Collapse this edge
		Collapse(mn,mn->collapse);
	}
	// reorder the map Array based on the collapse ordering
	for (unsigned int i = 0; i<map.size(); i++) {
		map[i] = (map[i]==-1)?0:permutation[map[i]];
	}
	// The caller of this function should reorder their vertices
	// according to the returned "permutation".
}
Exemple #2
0
void Chopper::chop( Array< Vector3 > & vert, Array< Triangle > &tri, 
							Array< int > &map, Array< int > &permutation )
{
	AddVertex(vert);  // put input data into our data structures
	AddFaces(tri);

	ComputeAllEdgeCollapseCosts(); // cache all edge collapse costs

	permutation.allocate(s_Vertices.size());  // allocate space
	map.allocate(s_Vertices.size());          // allocate space

	// reduce the object down to nothing:
	while(s_Vertices.size() > 0) 
	{
		// get the next vertex to collapse
		Vertex *mn = MinimumCostEdge();
		// keep track of this vertex, i.e. the collapse ordering
		permutation[mn->id]=s_Vertices.size()-1;
		// keep track of vertex to which we collapse to
		map[s_Vertices.size()-1] = (mn->collapse)?mn->collapse->id:-1;
		// Collapse this edge
		Collapse(mn,mn->collapse);
	}
	// reorder the map list based on the collapse ordering
	for(int i=0;i<map.size();i++) {
		map[i] = (map[i]==-1)?0:permutation[map[i]];
	}
	// The caller of this function should reorder their vertices
	// according to the returned "permutation".
}
Exemple #3
0
void Pair::Merge (Pair *pair)
{
    U32 SetCtx = 0;
    FacePtrSet *fset = pair->GetFaces();
    Face *pFace = (Face*)fset->Begin(SetCtx);
    while(pFace)
    {
        pFace->ReplacePair (pair, this);
        pFace = (Face*)fset->Next(SetCtx);
    }

    AddFaces (fset);
}
void IFXNeighborResController::IncreaseResolution()
{
  // Undo distal merges
  IFXDistalEdgeMerge* pMerge = m_distalMerges[m_resolution];
  while (pMerge)
  {
    ApplyEdgeMerge(pMerge);
    pMerge = pMerge->m_pNext;
  }

  ++m_resolution;
  for(I32 meshIndex = m_numMeshes - 1; meshIndex >= 0; meshIndex--)
  {
    U32* syncTable = m_pUpdatesGroup->GetSyncTable(meshIndex);
    U32 maxLocalRes = m_pUpdatesGroup->GetUpdates(meshIndex)->numResChanges;
    U32  localRes = m_pMeshStates[meshIndex].resolutionChangeIndex;

    if (localRes < maxLocalRes  &&  m_resolution > syncTable[localRes])
    {
      AddFaces(meshIndex);
    }
  }
}
void IFXNeighborResController::DetermineCollapsedEdges()
{
  IFXTRACE_GENERIC(L"IFX Neighbor res:\n");
  // Reduce the mesh resolution
  U32 resolution;
  for (resolution = m_pUpdatesGroup->GetMaxResolution() - 1; 
	   (I32)resolution >= 0; 
	   --resolution)
  {
    IFXTRACE_GENERIC(L"%d%c", resolution, (resolution % 10) ? ' ' : '\n' );

    // First pass:
    //   Determine which faces are deleted by this resolution change.
    //   Express as a range:
    //     m_pMeshStates[i].numFaces => deleted < m_pMeshStates[i].prevNumFaces
    //
    U32 i;
    for(i = 0; i < m_numMeshes; i++)
    {
      U32* syncTable = m_pUpdatesGroup->GetSyncTable(i);
      U32  localRes = m_pMeshStates[i].resolutionChangeIndex;

      if (localRes > 0  &&  resolution <= syncTable[localRes-1])
      {
        DecrementFaceCount(i);
      }
      else
      {
        // no faces deleted in this mesh; invalidate range
        m_pMeshStates[i].prevNumFaces = 0;
      }
    }

    // Analyze modified faces for merged edges
    for(i = 0; i < m_numMeshes; i++)
    {
      U32* syncTable = m_pUpdatesGroup->GetSyncTable(i);
      U32  localRes = m_pMeshStates[i].resolutionChangeIndex;

      if (localRes > 0  &&  resolution <= syncTable[localRes-1])
      {
        AnalyzeMergingEdges(i, resolution);
      }
    }

    // Mark duplicate faces and determine the collapse edges
    // by analyzing the unique faces.  Duplicate faces must be
    // marked in the reverse order that faces are removed.  Faces
    // are removed from highest face index to lowest, from mesh 0
    // to mesh n.  Thus duplicate faces are marked from lowest face
    // face index to highest, from mesh n to 0.
    for(I32 j = m_numMeshes - 1; j >= 0; j--)
    {
      U32* syncTable = m_pUpdatesGroup->GetSyncTable(j);
      U32  localRes = m_pMeshStates[j].resolutionChangeIndex;

      if (localRes > 0  &&  resolution <= syncTable[localRes-1])
      {
        MarkCollapseEdgesInMesh(j);
      }
    }

    // Remove deleted edges from edge map
    for(i = 0; i < m_numMeshes; i++)
    {
      U32* syncTable = m_pUpdatesGroup->GetSyncTable(i);
      U32  localRes = m_pMeshStates[i].resolutionChangeIndex;

      if (localRes > 0  &&  resolution <= syncTable[localRes-1])
      {
        UpdateEdgesInMap(i);
      }
    }

    // Third pass:
    //   Actually remove faces from connectivity
    for(i = 0; i < m_numMeshes; i++)
    {
      U32* syncTable = m_pUpdatesGroup->GetSyncTable(i);
      U32  localRes = m_pMeshStates[i].resolutionChangeIndex;

      if (localRes > 0  &&  resolution <= syncTable[localRes-1])
      {
        AltRemoveFaces(i);
      }
    }

    // Apply distal merges
    IFXDistalEdgeMerge* pMerge = m_distalMerges[resolution];
    while (pMerge)
    {
      ApplyEdgeMerge(pMerge);
      pMerge = pMerge->m_pNext;
    }


    m_pCLODManager->SetResolution(resolution);
  }

  // Restore the mesh resolution
  for (resolution = 1; resolution <= m_pUpdatesGroup->GetMaxResolution(); ++resolution)
  {
    // Undo distal merges
    IFXDistalEdgeMerge* pMerge = m_distalMerges[resolution-1];
    while (pMerge)
    {
      ApplyEdgeMerge(pMerge);
      pMerge = pMerge->m_pNext;
    }
    for(I32 i = m_numMeshes - 1; i >= 0; i--)
    {
      U32* syncTable = m_pUpdatesGroup->GetSyncTable(i);
      U32 maxLocalRes = m_pUpdatesGroup->GetUpdates(i)->numResChanges;
      U32 localRes = m_pMeshStates[i].resolutionChangeIndex;

      if (localRes < maxLocalRes  &&  resolution > syncTable[localRes])
      {
        AddFaces(i);
      }
    }
    m_pCLODManager->SetResolution(resolution);
  }
}