コード例 #1
0
ファイル: triangle_mesh.hpp プロジェクト: kalectro/pcl_groovy
      // 3 - 2      3 - 2
      // | / |  or  | \ |
      // 0 - 1      0 - 1
      FaceIndexPair
      addFace (const VertexIndex&  idx_v_0,
               const VertexIndex&  idx_v_1,
               const VertexIndex&  idx_v_2,
               const VertexIndex&  idx_v_3,
               const FaceData&     face_data = FaceData ())
      {
        // Try to add two faces
        // 3 - 2
        // | / |
        // 0 - 1
        FaceIndex idx_face_0 = this->addFace (idx_v_0, idx_v_1, idx_v_2, face_data);
        FaceIndex idx_face_1 = this->addFace (idx_v_0, idx_v_2, idx_v_3, face_data);

        if (idx_face_0.isValid ())
        {
          return (std::make_pair (idx_face_0, idx_face_1));
        }
        else if (idx_face_1.isValid ())
        {
          idx_face_0 = this->addFace (idx_v_0, idx_v_1, idx_v_2, face_data); // might be possible to add now
          return (std::make_pair (idx_face_1, idx_face_0));
        }

        // Try to add two faces
        // 3 - 2
        // | \ |
        // 0 - 1
        idx_face_0 = this->addFace (idx_v_1, idx_v_2, idx_v_3, face_data);
        idx_face_1 = this->addFace (idx_v_0, idx_v_1, idx_v_3, face_data);

        if (idx_face_0.isValid ())
        {
          return (std::make_pair (idx_face_0, idx_face_1));
        }
        else if (idx_face_1.isValid ())
        {
          idx_face_0 = this->addFace (idx_v_1, idx_v_2, idx_v_3, face_data); // might be possible to add now
          return (std::make_pair (idx_face_1, idx_face_0));
        }

        // Connect the triangle pair if possible
        if (!idx_v_0.isValid () || !idx_v_1.isValid () || !idx_v_2.isValid () || !idx_v_3.isValid ())
        {
          return (std::make_pair (FaceIndex (), FaceIndex ()));
        }
        VertexIndexes vi; vi.reserve (4);
        vi.push_back (idx_v_0);
        vi.push_back (idx_v_1);
        vi.push_back (idx_v_2);
        vi.push_back (idx_v_3);
        if (!this->uniqueCheck (vi))
        {
          return (std::make_pair (FaceIndex (), FaceIndex ()));
        }

        HalfEdgeIndex idx_he_01, idx_he_12, idx_he_23, idx_he_30;

        // Check manifoldness
        bool is_new_01 = true;
        bool is_new_12 = true;
        bool is_new_23 = true;
        bool is_new_30 = true;

        if (!Base::checkTopology1 (idx_v_0,idx_v_1, idx_he_01, is_new_01) ||
            !Base::checkTopology1 (idx_v_1,idx_v_2, idx_he_12, is_new_12) ||
            !Base::checkTopology1 (idx_v_2,idx_v_3, idx_he_23, is_new_23) ||
            !Base::checkTopology1 (idx_v_3,idx_v_0, idx_he_30, is_new_30))
        {
          return (std::make_pair (FaceIndex (), FaceIndex ()));
        }

        // Connect the triangle pair
        if (!is_new_01 && is_new_12 && !is_new_23 && is_new_30)
        {
          return (this->connectTrianglePair (idx_he_01, idx_he_23, idx_v_0, idx_v_1, idx_v_2, idx_v_3, face_data));
        }
        else if (is_new_01 && !is_new_12 && is_new_23 && !is_new_30)
        {
          return (this->connectTrianglePair (idx_he_12, idx_he_30, idx_v_1, idx_v_2, idx_v_3, idx_v_0, face_data));
        }
        else
        {
          assert (true); // This should not happen!
          return (std::make_pair (FaceIndex (), FaceIndex ()));
        }
      }
コード例 #2
0
int main ()
{
  Mesh          mesh;
  VertexIndexes vi;

  // Create a closed circle around vertex 0 //
  //   1 - 6                                //
  //  / \ / \                               //
  // 2 - 0 - 5                              //
  //  \ / \ /                               //
  //   3 - 4                                //
  vi.push_back (mesh.addVertex (MyVertexData (0)));
  vi.push_back (mesh.addVertex (MyVertexData (1)));
  vi.push_back (mesh.addVertex (MyVertexData (2)));
  vi.push_back (mesh.addVertex (MyVertexData (3)));
  vi.push_back (mesh.addVertex (MyVertexData (4)));
  vi.push_back (mesh.addVertex (MyVertexData (5)));
  vi.push_back (mesh.addVertex (6)); // Converted to MyVertexData
  vi.push_back (mesh.addVertex (7)); // Will not be connected -> isolated vertex

  mesh.addFace (vi[0], vi[1], vi[2]);
  mesh.addFace (vi[0], vi[2], vi[3]);
  mesh.addFace (vi[0], vi[3], vi[4]);
  mesh.addFace (vi[0], vi[4], vi[5]);
  mesh.addFace (vi[0], vi[5], vi[6]);
  mesh.addFace (0, 6, 1); // Converted to VertexIndex

  printVertexes (mesh);
  printFaces (mesh);

  //////////////////////////////////////////////////////////////////////////////

  std::cout << "Outgoing half-edges of vertex 0:" << std::endl;
  OHEAVCC       circ_oheav     = mesh.getOutgoingHalfEdgeAroundVertexConstCirculator (vi[0]);
  const OHEAVCC circ_oheav_end = circ_oheav;
  do
  {
    std::cout << "  "
              << circ_oheav->getOriginatingVertex (mesh) << " "
              << circ_oheav->getTerminatingVertex (mesh)
              << std::endl;
    ++circ_oheav;
  } while (circ_oheav!=circ_oheav_end);

  //////////////////////////////////////////////////////////////////////////////

  std::cout << "Circulate around the boundary half-edges:" << std::endl;
  const HalfEdgeIndex& idx_he_boundary = mesh.getElement (vi[0]).
                                         getOutgoingHalfEdge (mesh).
                                         getTerminatingVertex (mesh).
                                         getOutgoingHalfEdgeIndex ();
  HEABCC       circ_heab     = mesh.getHalfEdgeAroundBoundaryConstCirculator (idx_he_boundary);
  const HEABCC circ_heab_end = circ_heab;
  do
  {
    std::cout << "  "
              << circ_heab->getOriginatingVertex (mesh) << " "
              << circ_heab->getTerminatingVertex (mesh)
              << std::endl;
    ++circ_heab;
  } while (circ_heab!=circ_heab_end);

  //////////////////////////////////////////////////////////////////////////////

  std::cout << std::endl << "Deleting face 1 and 4 ...\n";
  std::cout << "(If the mesh is set to manifold further faces are removed automatically)\n\n";
  mesh.deleteFace (FaceIndex (1));
  mesh.deleteFace (4); // Converted to FaceIndex

  mesh.cleanUp (false); // Delete (true) or don't delete (false) isolated vertexes
  vi.clear (); // The vertex indexes are no longer synchronized with the mesh!

  printVertexes (mesh);
  printFaces (mesh);

  //////////////////////////////////////////////////////////////////////////

  std::cout << "Circulate around all faces of vertex 0:\n";

  FAVCC       circ_fav     = mesh.getFaceAroundVertexConstCirculator (mesh.frontVertexes ());
  const FAVCC circ_fav_end = circ_fav;
  do
  {
    // Very important: Some half_edges are on the boundary
    //  -> have an invalid face index
    if (circ_fav.isValid ())
    {
      printFace (mesh, *circ_fav);
    }
    else
    {
      std::cout << "  invalid face -> boundary half-edge\n";
    }
    ++circ_fav;
  } while (circ_fav!=circ_fav_end);

  return (0);
}
コード例 #3
0
ファイル: triangle_mesh.hpp プロジェクト: kalectro/pcl_groovy
      FaceIndex
      addFace (const VertexIndex&  idx_v_0,
               const VertexIndex&  idx_v_1,
               const VertexIndex&  idx_v_2,
               const FaceData&     face_data = FaceData ())
      {
        if (!idx_v_0.isValid () || !idx_v_1.isValid () || !idx_v_2.isValid ())
        {
          return (FaceIndex ());
        }

        VertexIndexes vi; vi.reserve (3);
        vi.push_back (idx_v_0);
        vi.push_back (idx_v_1);
        vi.push_back (idx_v_2);
        if (!this->uniqueCheck (vi))
        {
          return (FaceIndex ());
        }

        HalfEdgeIndex idx_he_01, idx_he_12, idx_he_20;
        HalfEdgeIndex idx_he_10, idx_he_21, idx_he_02;

        if (Base::getElement (idx_v_0).isIsolated () && Base::getElement (idx_v_1).isIsolated () && Base::getElement (idx_v_2).isIsolated ())
        {
          Base::addHalfEdgePair (idx_v_0,idx_v_1, HalfEdgeData (),HalfEdgeData (), idx_he_01,idx_he_10);
          Base::addHalfEdgePair (idx_v_1,idx_v_2, HalfEdgeData (),HalfEdgeData (), idx_he_12,idx_he_21);
          Base::addHalfEdgePair (idx_v_2,idx_v_0, HalfEdgeData (),HalfEdgeData (), idx_he_20,idx_he_02);

          Base::connectHalfEdges (true,true, idx_he_01,idx_he_10, idx_he_12,idx_he_21, idx_v_1);
          Base::connectHalfEdges (true,true, idx_he_12,idx_he_21, idx_he_20,idx_he_02, idx_v_2);
          Base::connectHalfEdges (true,true, idx_he_20,idx_he_02, idx_he_01,idx_he_10, idx_v_0);

          return (this->connectFace (face_data, idx_he_01,idx_he_12,idx_he_20));
        }

        // Check for topological errors
        bool is_new_01 = true;
        bool is_new_12 = true;
        bool is_new_20 = true;

        if (!Base::checkTopology1 (idx_v_0,idx_v_1, idx_he_01, is_new_01) ||
            !Base::checkTopology1 (idx_v_1,idx_v_2, idx_he_12, is_new_12) ||
            !Base::checkTopology1 (idx_v_2,idx_v_0, idx_he_20, is_new_20))
        {
          return (FaceIndex ());
        }

        if (!Base::checkTopology2 (is_new_01,is_new_12, Base::getElement (idx_v_1).isIsolated ()) ||
            !Base::checkTopology2 (is_new_12,is_new_20, Base::getElement (idx_v_2).isIsolated ()) ||
            !Base::checkTopology2 (is_new_20,is_new_01, Base::getElement (idx_v_0).isIsolated ()))
        {
          return (FaceIndex ());
        }

        // Reconnect the existing half-edges if needed
        bool make_adjacent_01_12 = false;
        bool make_adjacent_12_20 = false;
        bool make_adjacent_20_01 = false;
        HalfEdgeIndex idx_he_boundary_01_12;
        HalfEdgeIndex idx_he_boundary_12_20;
        HalfEdgeIndex idx_he_boundary_20_01;

        if (!Base::checkAdjacency (idx_he_01,idx_he_12, is_new_01,is_new_12, make_adjacent_01_12, idx_he_boundary_01_12) ||
            !Base::checkAdjacency (idx_he_12,idx_he_20, is_new_12,is_new_20, make_adjacent_12_20, idx_he_boundary_12_20) ||
            !Base::checkAdjacency (idx_he_20,idx_he_01, is_new_20,is_new_01, make_adjacent_20_01, idx_he_boundary_20_01))
        {
          return (FaceIndex ());
        }

        Base::makeAdjacent (idx_he_01,idx_he_12, make_adjacent_01_12, idx_he_boundary_01_12);
        Base::makeAdjacent (idx_he_12,idx_he_20, make_adjacent_12_20, idx_he_boundary_12_20);
        Base::makeAdjacent (idx_he_20,idx_he_01, make_adjacent_20_01, idx_he_boundary_20_01);

        // Add the new half-edges if needed
        if (is_new_01) Base::addHalfEdgePair (idx_v_0,idx_v_1, HalfEdgeData (),HalfEdgeData (), idx_he_01,idx_he_10);
        else           idx_he_10 = Base::getElement (idx_he_01).getOppositeHalfEdgeIndex ();

        if (is_new_12) Base::addHalfEdgePair (idx_v_1,idx_v_2, HalfEdgeData (),HalfEdgeData (), idx_he_12,idx_he_21);
        else           idx_he_21 = Base::getElement (idx_he_12).getOppositeHalfEdgeIndex ();

        if (is_new_20) Base::addHalfEdgePair (idx_v_2,idx_v_0, HalfEdgeData (),HalfEdgeData (), idx_he_20,idx_he_02);
        else           idx_he_02 = Base::getElement (idx_he_20).getOppositeHalfEdgeIndex ();

        // Connect the half-edges and vertexes
        Base::connectHalfEdges (is_new_01,is_new_12, idx_he_01,idx_he_10, idx_he_12,idx_he_21, idx_v_1);
        Base::connectHalfEdges (is_new_12,is_new_20, idx_he_12,idx_he_21, idx_he_20,idx_he_02, idx_v_2);
        Base::connectHalfEdges (is_new_20,is_new_01, idx_he_20,idx_he_02, idx_he_01,idx_he_10, idx_v_0);

        // Connect the face
        return (this->connectFace (face_data, idx_he_01,idx_he_12,idx_he_20));
      }