Example #1
0
void CMesh::Simplify(int iVertices2Remain, float fMaxError, bool bConsiderMaterials)
{
  TEdge *pEdge;
  bool bRemoveSecond;

  m_bConsiderMaterials = bConsiderMaterials;
  if (!m_arrCollapses.m_iCount) {
    InitOutputs();
    InitBorders();
  }
  InitEdgeEvaluation();
  while (m_hashVertices.m_iCount > iVertices2Remain) {
    if (!SelectEdge(pEdge, bRemoveSecond, fMaxError))
      break;
    RecordCollapse(pEdge, bRemoveSecond);
    CollapseEdge(pEdge, bRemoveSecond);
//    CheckEdges();
  }
}
Example #2
0
////////////////////////////////////////////////////////////////////////
//	MergeVertices
///	merges two vertices and restructures the adjacent elements.
void MergeVertices(Grid& grid, Vertex* v1, Vertex* v2)
{
//	make sure that GRIDOPT_VERTEXCENTRIC_INTERCONNECTION is enabled
    if(grid.num_edges() && (!grid.option_is_enabled(VRTOPT_STORE_ASSOCIATED_EDGES))) {
        LOG("  WARNING in MergeVertices: autoenabling VRTOPT_STORE_ASSOCIATED_EDGES\n");
        grid.enable_options(VRTOPT_STORE_ASSOCIATED_EDGES);
    }
    if(grid.num_faces() && (!grid.option_is_enabled(VRTOPT_STORE_ASSOCIATED_FACES))) {
        LOG("  WARNING in MergeVertices: autoenabling VRTOPT_STORE_ASSOCIATED_FACES\n");
        grid.enable_options(VRTOPT_STORE_ASSOCIATED_FACES);
    }
    if(grid.num_volumes() && (!grid.option_is_enabled(VRTOPT_STORE_ASSOCIATED_VOLUMES))) {
        LOG("  WARNING in MergeVertices: autoenabling VRTOPT_STORE_ASSOCIATED_VOLUMES\n");
        grid.enable_options(VRTOPT_STORE_ASSOCIATED_VOLUMES);
    }


    Edge* conEdge = grid.get_edge(v1, v2);
    if(conEdge) {
        //	perform an edge-collapse on conEdge
        CollapseEdge(grid, conEdge, v1);
    }
    else {
        //	notify the grid, that the two vertices will be merged
        grid.objects_will_be_merged(v1, v1, v2);

        //	we have to check if there are elements that connect the vertices.
        //	We have to delete those.
        EraseConnectingElements(grid, v1, v2);

        //	create new edges for each edge that is connected with v2.
        //	avoid double edges
        if(grid.num_edges() > 0)
        {
            EdgeDescriptor ed;
            Grid::AssociatedEdgeIterator iterEnd = grid.associated_edges_end(v2);
            for(Grid::AssociatedEdgeIterator iter = grid.associated_edges_begin(v2); iter != iterEnd; ++iter)
            {
                Edge* e = *iter;
                if(e->vertex(0) == v2)
                    ed.set_vertices(v1, e->vertex(1));
                else
                    ed.set_vertices(e->vertex(0), v1);

                Edge* existingEdge = grid.get_edge(ed);
                if(!existingEdge)
                    grid.create_by_cloning(e, ed, e);
                else
                    grid.objects_will_be_merged(existingEdge, existingEdge, e);
            }
        }

        //	create new faces for each face that is connected to v2
        //	avoid double faces.
        if(grid.num_faces() > 0)
        {
            FaceDescriptor fd;
            Grid::AssociatedFaceIterator iterEnd = grid.associated_faces_end(v2);
            for(Grid::AssociatedFaceIterator iter = grid.associated_faces_begin(v2); iter != iterEnd; ++iter)
            {
                Face* f = *iter;
                uint numVrts = f->num_vertices();
                fd.set_num_vertices(numVrts);
                for(uint i = 0; i < numVrts; ++i)
                {
                    if(f->vertex(i) == v2)
                        fd.set_vertex(i, v1);
                    else
                        fd.set_vertex(i, f->vertex(i));
                }

                Face* existingFace = grid.get_face(fd);
                if(!existingFace)
                    grid.create_by_cloning(f, fd, f);
                else
                    grid.objects_will_be_merged(existingFace, existingFace, f);
            }
        }

        //	create new volumes for each volume that is connected to v2
        if(grid.num_volumes() > 0)
        {
            VolumeDescriptor vd;
            Grid::AssociatedVolumeIterator iterEnd = grid.associated_volumes_end(v2);
            for(Grid::AssociatedVolumeIterator iter = grid.associated_volumes_begin(v2); iter != iterEnd; ++iter)
            {
                Volume* v = *iter;
                uint numVrts = v->num_vertices();
                vd.set_num_vertices(numVrts);
                for(uint i = 0; i < numVrts; ++i)
                {
                    if(v->vertex(i) == v2)
                        vd.set_vertex(i, v1);
                    else
                        vd.set_vertex(i, v->vertex(i));
                }

                //assert(!"avoid double volumes! implement FindVolume and use it here.");
                grid.create_by_cloning(v, vd, v);
            }
        }

        //	new elements have been created. remove the old ones.
        //	it is sufficient to simply erase v2.
        grid.erase(v2);
    }
}