Exemplo n.º 1
0
      // 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 ()));
        }
      }
Exemplo n.º 2
0
      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));
      }