Shinya Kitaoka 810553
#pragma once
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifndef TCG_MESH_HPP
Toshihiro Shimizu 890ddd
#define TCG_MESH_HPP
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// tcg includes
Toshihiro Shimizu 890ddd
#include "../mesh.h"
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
namespace tcg {
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//************************************************************************
Toshihiro Shimizu 890ddd
//    Polygon Mesh methods
Toshihiro Shimizu 890ddd
//************************************************************************
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <typename e,="" f="" typename="" v,=""></typename>
Shinya Kitaoka 120a6e
int Mesh<v, e,="" f="">::edgeInciding(int vIdx1, int vIdx2, int n) const {</v,>
Shinya Kitaoka 120a6e
  const V &v1 = vertex(vIdx1);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  const tcg::list<int> &incidingV1 = v1.edges();</int>
Shinya Kitaoka 120a6e
  tcg::list<int>::const_iterator it;</int>
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  for (it = incidingV1.begin(); it != incidingV1.end(); ++it) {
Shinya Kitaoka 120a6e
    const E &e = edge(*it);
Shinya Kitaoka 120a6e
    if (e.otherVertex(vIdx1) == vIdx2 && n-- == 0) break;
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  return (it == incidingV1.end()) ? -1 : (*it);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <typename e,="" f="" typename="" v,=""></typename>
Shinya Kitaoka 120a6e
int Mesh<v, e,="" f="">::addEdge(const E &ed) {</v,>
Shinya Kitaoka 120a6e
  int e = int(m_edges.push_back(ed));
Shinya Kitaoka 120a6e
  m_edges[e].setIndex(e);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  // Add the edge index to the edge's vertices
Shinya Kitaoka 120a6e
  typename edge_traits<e>::vertices_const_iterator it, end(ed.verticesEnd());</e>
Shinya Kitaoka 120a6e
  for (it = ed.verticesBegin(); it != end; ++it) m_vertices[*it].addEdge(e);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  return e;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <typename e,="" f="" typename="" v,=""></typename>
Shinya Kitaoka 120a6e
int Mesh<v, e,="" f="">::addFace(const F &fc) {</v,>
Shinya Kitaoka 120a6e
  int f = int(m_faces.push_back(fc));
Shinya Kitaoka 120a6e
  m_faces[f].setIndex(f);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  // Add the face index to the face's edges
Shinya Kitaoka 120a6e
  typename face_traits<f>::edges_const_iterator it, end = fc.edgesEnd();</f>
Shinya Kitaoka 120a6e
  for (it = fc.edgesBegin(); it != end; ++it) m_edges[*it].addFace(f);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  return f;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <typename e,="" f="" typename="" v,=""></typename>
Shinya Kitaoka 120a6e
void Mesh<v, e,="" f="">::removeVertex(int v) {</v,>
Shinya Kitaoka 120a6e
  V &vx = vertex(v);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  // As long as there are incident edges, remove them
Shinya Kitaoka 120a6e
  while (vx.edgesCount() > 0) removeEdge(vx.edges().front());
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  m_vertices.erase(v);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <typename e,="" f="" typename="" v,=""></typename>
Shinya Kitaoka 120a6e
void Mesh<v, e,="" f="">::removeEdge(int e) {</v,>
Shinya Kitaoka 120a6e
  E &ed = edge(e);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // Remove all the associated faces
Shinya Kitaoka 120a6e
  typename edge_traits<e>::faces_iterator ft;</e>
Shinya Kitaoka 120a6e
  while ((ft = ed.facesBegin()) !=
Shinya Kitaoka 120a6e
         ed.facesEnd())  // current iterator could be erased here!
Shinya Kitaoka 120a6e
    removeFace(*ft);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // Remove the edge from the associated vertices
Shinya Kitaoka 120a6e
  typename edge_traits<e>::vertices_iterator vt, vEnd = ed.verticesEnd();</e>
Shinya Kitaoka 120a6e
  for (vt = ed.verticesBegin(); vt != vEnd; ++vt) {
Shinya Kitaoka 120a6e
    V &vx = vertex(*vt);
Shinya Kitaoka 120a6e
    typename vertex_traits<v>::edges_iterator et =</v>
Shinya Kitaoka 120a6e
        std::find(vx.edgesBegin(), vx.edgesEnd(), e);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    assert(et != vx.edgesEnd());
Shinya Kitaoka 120a6e
    vx.eraseEdge(et);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  m_edges.erase(e);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <typename e,="" f="" typename="" v,=""></typename>
Shinya Kitaoka 120a6e
void Mesh<v, e,="" f="">::removeFace(int f) {</v,>
Shinya Kitaoka 120a6e
  F &fc = face(f);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  // Remove the face from all adjacent edges
Shinya Kitaoka 120a6e
  typename face_traits<f>::edges_iterator et, eEnd = fc.edgesEnd();</f>
Shinya Kitaoka 120a6e
  for (et = fc.edgesBegin(); et != eEnd; ++et) {
Shinya Kitaoka 120a6e
    E &ed = edge(*et);
Shinya Kitaoka 120a6e
    typename edge_traits<e>::faces_iterator ft =</e>
Shinya Kitaoka 120a6e
        std::find(ed.facesBegin(), ed.facesEnd(), f);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    assert(ft != ed.facesEnd());
Shinya Kitaoka 120a6e
    ed.eraseFace(ft);
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  m_faces.erase(f);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*!
Shinya Kitaoka 120a6e
  \brief    Remaps the mesh indices in a natural order, removing unused cells in
Shinya Kitaoka 120a6e
  the internal
Toshihiro Shimizu 890ddd
            container model, for minimum memory consumption.
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  \warning  This is a slow operation, compared to all the others in the Mesh
Shinya Kitaoka 120a6e
  class.
Toshihiro Shimizu 890ddd
*/
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <typename e,="" f="" typename="" v,=""></typename>
Shinya Kitaoka 120a6e
void Mesh<v, e,="" f="">::squeeze() {</v,>
Shinya Kitaoka 120a6e
  // Build new indices for remapping.
Shinya Kitaoka 120a6e
  typename tcg::list<f>::iterator it, endI(m_faces.end());</f>
Shinya Kitaoka 120a6e
  int i;
Shinya Kitaoka 120a6e
  for (i = 0, it = m_faces.begin(); it != endI; ++i, ++it) it->setIndex(i);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  typename tcg::list<e>::iterator jt, endJ(m_edges.end());</e>
Shinya Kitaoka 120a6e
  for (i = 0, jt = m_edges.begin(); jt != endJ; ++i, ++jt) jt->setIndex(i);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  typename tcg::list<v>::iterator kt, endK(m_vertices.end());</v>
Shinya Kitaoka 120a6e
  for (i = 0, kt = m_vertices.begin(); kt != endK; ++i, ++kt) kt->setIndex(i);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // Update stored indices
Shinya Kitaoka 120a6e
  for (it = m_faces.begin(); it != endI; ++it) {
Shinya Kitaoka 120a6e
    F &face = *it;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    typename face_traits<f>::edges_iterator et, eEnd = face.edgesEnd();</f>
Shinya Kitaoka 120a6e
    for (et = face.edgesBegin(); et != eEnd; ++et) *et = edge(*et).getIndex();
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  for (jt = m_edges.begin(); jt != endJ; ++jt) {
Shinya Kitaoka 120a6e
    E &edge = *jt;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    typename edge_traits<e>::vertices_iterator vt, vEnd = edge.verticesEnd();</e>
Shinya Kitaoka 120a6e
    for (vt = edge.verticesBegin(); vt != vEnd; ++vt)
Shinya Kitaoka 120a6e
      *vt = vertex(*vt).getIndex();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    typename edge_traits<e>::faces_iterator ft, fEnd = edge.facesEnd();</e>
Shinya Kitaoka 120a6e
    for (ft = edge.facesBegin(); ft != fEnd; ++ft) *ft = face(*ft).getIndex();
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  tcg::list<int>::iterator lt;</int>
Shinya Kitaoka 120a6e
  for (kt = m_vertices.begin(); kt != endK; ++kt) {
Shinya Kitaoka 120a6e
    V &vertex = *kt;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    typename vertex_traits<v>::edges_iterator et, eEnd = vertex.edgesEnd();</v>
Shinya Kitaoka 120a6e
    for (et = vertex.edgesBegin(); et != eEnd; ++et) *et = edge(*et).getIndex();
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // Finally, rebuild the actual containers
Shinya Kitaoka 120a6e
  if (!m_faces.empty()) {
Shinya Kitaoka 120a6e
    tcg::list<f> temp(m_faces.begin(), m_faces.end());</f>
Shinya Kitaoka 120a6e
    std::swap(m_faces, temp);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (!m_edges.empty()) {
Shinya Kitaoka 120a6e
    tcg::list<e> temp(m_edges.begin(), m_edges.end());</e>
Shinya Kitaoka 120a6e
    std::swap(m_edges, temp);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (!m_vertices.empty()) {
Shinya Kitaoka 120a6e
    tcg::list<v> temp(m_vertices.begin(), m_vertices.end());</v>
Shinya Kitaoka 120a6e
    std::swap(m_vertices, temp);
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//************************************************************************
Toshihiro Shimizu 890ddd
//    Triangular Mesh methods
Toshihiro Shimizu 890ddd
//************************************************************************
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <typename e,="" f="" typename="" v,=""></typename>
Shinya Kitaoka 120a6e
TriMesh<v, e,="" f="">::TriMesh(int verticesHint) {</v,>
Shinya Kitaoka 120a6e
  int edgesHint = (3 * verticesHint) / 2;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  m_vertices.reserve(verticesHint);
Shinya Kitaoka 120a6e
  m_edges.reserve(edgesHint);
Shinya Kitaoka 120a6e
  m_faces.reserve(edgesHint + 1);  // Since V - E + F = 1 for planar graphs (no
Shinya Kitaoka 120a6e
                                   // outer face), and vMin == 0
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <typename e,="" f="" typename="" v,=""></typename>
Shinya Kitaoka 120a6e
int TriMesh<v, e,="" f="">::addFace(V &vx1, V &vx2, V &vx3) {</v,>
Shinya Kitaoka 120a6e
  int v1 = vx1.getIndex(), v2 = vx2.getIndex(), v3 = vx3.getIndex();
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  // Retrieve the edges having v1, v2, v3 in common
Shinya Kitaoka 120a6e
  int e1, e2, e3;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  e1 = this->edgeInciding(v1, v2);
Shinya Kitaoka 120a6e
  e2 = this->edgeInciding(v2, v3);
Shinya Kitaoka 120a6e
  e3 = this->edgeInciding(v3, v1);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (e1 < 0) e1 = this->addEdge(E(v1, v2));
Shinya Kitaoka 120a6e
  if (e2 < 0) e2 = this->addEdge(E(v2, v3));
Shinya Kitaoka 120a6e
  if (e3 < 0) e3 = this->addEdge(E(v3, v1));
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  F fc;
Shinya Kitaoka 120a6e
  fc.addEdge(e1), fc.addEdge(e2), fc.addEdge(e3);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  int f = int(m_faces.push_back(fc));
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  m_faces[f].setIndex(f);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  E &E1 = this->edge(e1);
Shinya Kitaoka 120a6e
  E1.addFace(f);
Shinya Kitaoka 120a6e
  E &E2 = this->edge(e2);
Shinya Kitaoka 120a6e
  E2.addFace(f);
Shinya Kitaoka 120a6e
  E &E3 = this->edge(e3);
Shinya Kitaoka 120a6e
  E3.addFace(f);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  return f;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <typename e,="" f="" typename="" v,=""></typename>
Shinya Kitaoka 120a6e
int TriMesh<v, e,="" f="">::otherFaceVertex(int f, int e) const {</v,>
Shinya Kitaoka 120a6e
  const F &face = Mesh<v, e,="" f="">::face(f);</v,>
Shinya Kitaoka 120a6e
  const E &otherEdge =
Shinya Kitaoka 120a6e
      face.edge(0) == e ? this->edge(face.edge(1)) : this->edge(face.edge(0));
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  int v1 = this->edge(e).vertex(0), v2 = this->edge(e).vertex(1),
Shinya Kitaoka 120a6e
      v3 = otherEdge.otherVertex(v1);
Shinya Kitaoka 120a6e
  return (v3 == v2) ? otherEdge.otherVertex(v2) : v3;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <typename e,="" f="" typename="" v,=""></typename>
Shinya Kitaoka 120a6e
int TriMesh<v, e,="" f="">::otherFaceEdge(int f, int v) const {</v,>
Shinya Kitaoka 120a6e
  const F &face = Mesh<v, e,="" f="">::face(f);</v,>
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  {
Shinya Kitaoka 120a6e
    const E &ed = this->edge(face.edge(0));
Shinya Kitaoka 120a6e
    if (ed.vertex(0) != v && ed.vertex(1) != v) return face.edge(0);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  {
Shinya Kitaoka 120a6e
    const E &ed = this->edge(face.edge(1));
Shinya Kitaoka 120a6e
    if (ed.vertex(0) != v && ed.vertex(1) != v) return face.edge(1);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  return face.edge(2);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <typename e,="" f="" typename="" v,=""></typename>
Shinya Kitaoka 120a6e
int TriMesh<v, e,="" f="">::swapEdge(int e) {</v,>
Shinya Kitaoka 120a6e
  E &ed = this->edge(e);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (ed.facesCount() < 2) return -1;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  int f1 = ed.face(0), f2 = ed.face(1);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  // Retrieve the 2 vertices not belonging to e in the adjacent faces
Shinya Kitaoka 120a6e
  int v1 = ed.vertex(0), v2 = ed.vertex(1);
Shinya Kitaoka 120a6e
  int v3 = otherFaceVertex(f1, e), v4 = otherFaceVertex(f2, e);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  assert(this->edgeInciding(v3, v4) < 0);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  // Remove e
Shinya Kitaoka 120a6e
  this->removeEdge(e);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  // Insert the new faces
Shinya Kitaoka 120a6e
  addFace(v1, v3, v4);  // Inserts edge E(v3, v4)
Shinya Kitaoka 120a6e
  addFace(v2, v4, v3);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  return this->edgeInciding(v3, v4);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
    *---*---*     Common case          *          FORBIDDEN case:
Toshihiro Shimizu 890ddd
   / \ / x / \                        /|\           note that the collapsed edge
Shinya Kitaoka 120a6e
  *---*-x-X---*                      /_*_\          have 3 (possibly more) other
Shinya Kitaoka 120a6e
  vertices
Shinya Kitaoka 120a6e
   \ / \ x \ /                      *--X--*         with edges inciding both the
Shinya Kitaoka 120a6e
  collapsed
Toshihiro Shimizu 890ddd
    *---*---*                        \   /          edge's extremes.
Toshihiro Shimizu 890ddd
                                      \ /
Shinya Kitaoka 120a6e
                                       *            This cannot be processed,
Shinya Kitaoka 120a6e
  since the
Shinya Kitaoka 120a6e
                                                    unexpected merged edge would
Shinya Kitaoka 120a6e
  either have
Shinya Kitaoka 120a6e
                                                    more than 2 adjacent faces,
Shinya Kitaoka 120a6e
  or a hole.
Toshihiro Shimizu 890ddd
*/
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <typename e,="" f="" typename="" v,=""></typename>
Shinya Kitaoka 120a6e
int TriMesh<v, e,="" f="">::collapseEdge(int e) {</v,>
Shinya Kitaoka 120a6e
  E &ed = this->edge(e);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  // First, retrieve ed's adjacent vertices
Shinya Kitaoka 120a6e
  int vKeep = ed.vertex(0), vDelete = ed.vertex(1);
Shinya Kitaoka 120a6e
  V &vxKeep = this->vertex(vKeep), &vxDelete = this->vertex(vDelete);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  // Then, retrieve the 2 vertices not belonging to e in the adjacent faces
Shinya Kitaoka 120a6e
  int f, fCount = ed.facesCount();
Shinya Kitaoka 120a6e
  int otherV[2];
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  for (f = 0; f != fCount; ++f) otherV[f] = otherFaceVertex(ed.face(f), e);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  // Remove e
Shinya Kitaoka 120a6e
  this->removeEdge(e);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  // Merge edges inciding vDelete and otherV with the corresponding inciding
Shinya Kitaoka 120a6e
  // vKeep and otherV
Shinya Kitaoka 120a6e
  for (f = 0; f != fCount; ++f) {
Shinya Kitaoka 120a6e
    int srcE = this->edgeInciding(vDelete, otherV[f]),
Shinya Kitaoka 120a6e
        dstE = this->edgeInciding(vKeep, otherV[f]);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    E &srcEd = this->edge(srcE), &dstEd = this->edge(dstE);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    typename edge_traits<e>::faces_iterator ft = srcEd.facesBegin();</e>
Shinya Kitaoka 120a6e
    while (ft != srcEd.facesEnd())  // current iterator will be erased
Shinya Kitaoka 120a6e
    {
Shinya Kitaoka 120a6e
      F &fc = this->face(*ft);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
      (fc.edge(0) == srcE)
Shinya Kitaoka 120a6e
          ? fc.setEdge(0, dstE)
Shinya Kitaoka 120a6e
          : (fc.edge(1) == srcE) ? fc.setEdge(1, dstE) : fc.setEdge(2, dstE);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
      dstEd.addFace(*ft);
Shinya Kitaoka 120a6e
      ft = srcEd.eraseFace(ft);  // here
Shinya Kitaoka 120a6e
    }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    this->removeEdge(srcE);
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  // Move further edges adjacent to vDelete to vKeep
Shinya Kitaoka 120a6e
  typename vertex_traits<v>::edges_iterator et = vxDelete.edgesBegin();</v>
Shinya Kitaoka 120a6e
  while (et != vxDelete.edgesEnd())  // current iterator will be erased
Shinya Kitaoka 120a6e
  {
Shinya Kitaoka 120a6e
    E &ed = this->edge(*et);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// Ensure that there is no remaining edge which would be duplicated
Toshihiro Shimizu 890ddd
// after vDelete and vKeep merge
Toshihiro Shimizu 890ddd
/* FIXME: edgeInciding がないと言われるのでとりあえず省略 */
Toshihiro Shimizu 890ddd
#if 0
Toshihiro Shimizu 890ddd
    assert("Detected vertex adjacent to collapsed edge's endpoints, but not to its faces." &&
Toshihiro Shimizu 890ddd
           edgeInciding(ed.otherVertex(vDelete), vKeep) < 0);
Toshihiro Shimizu 890ddd
#endif
Shinya Kitaoka 120a6e
    (ed.vertex(0) == vDelete) ? ed.setVertex(0, vKeep) : ed.setVertex(1, vKeep);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    vxKeep.addEdge(*et);
Shinya Kitaoka 120a6e
    et = vxDelete.eraseEdge(et);  // here
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  // Finally, update vKeep's position and remove vDelete
Shinya Kitaoka 120a6e
  vxKeep.P() = 0.5 * (vxKeep.P() + vxDelete.P());
Shinya Kitaoka 120a6e
  m_vertices.erase(vDelete);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  return vKeep;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <typename e,="" f="" typename="" v,=""></typename>
Shinya Kitaoka 120a6e
int TriMesh<v, e,="" f="">::splitEdge(int e) {</v,>
Shinya Kitaoka 120a6e
  E &ed = this->edge(e);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  // Build a new vertex on the middle of e
Shinya Kitaoka 120a6e
  int v1 = ed.vertex(0), v2 = ed.vertex(1);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  V &vx1 = this->vertex(v1), &vx2 = this->vertex(v2);
Shinya Kitaoka 120a6e
  V v(0.5 * (vx1.P() + vx2.P()));
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  int vIdx = this->addVertex(v);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  // Retrieve opposite vertices
Shinya Kitaoka 120a6e
  int otherV[2];  // NOTE: If ever extended to support edges with
Shinya Kitaoka 120a6e
  int f,
Shinya Kitaoka 120a6e
      fCount =
Shinya Kitaoka 120a6e
          ed.facesCount();  //       MORE than 2 adjacent faces, the new faces
Shinya Kitaoka 120a6e
  //       should be inserted BEFORE removing the split
Shinya Kitaoka 120a6e
  for (f      = 0; f != fCount; ++f)  //       edge.
Shinya Kitaoka 120a6e
    otherV[f] = otherFaceVertex(ed.face(f), e);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  // Remove e
Shinya Kitaoka 120a6e
  this->removeEdge(e);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  // Add the new edges
Shinya Kitaoka 120a6e
  this->addEdge(E(v1, vIdx));
Shinya Kitaoka 120a6e
  this->addEdge(E(vIdx, v2));
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  // Add the new faces
Shinya Kitaoka 120a6e
  for (f = 0; f != fCount; ++f)
Shinya Kitaoka 120a6e
    addFace(v1, vIdx, otherV[f]), addFace(vIdx, v2, otherV[f]);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  return vIdx;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
}  // namespace tcg
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
#endif  // TCG_MESH_HPP