void DenseBipartiteGraph::switch_4_cycle(int u1, int v1, int u2, int v2) {

	if (u1 > v1) {
		// rotate
		uint tmp = u1;
		u1 = v1;
		v1 = u2;
		u2 = v2;
		v2 = tmp;
	}

	// translate node labels
	v1 -= nrows;
	v2 -= nrows;

#ifdef DEBUG
	std::cout << "switch cycle [ " << u1 << " " << v1 << " " << u2 << " " << v2
	<< " ]" << std::endl;
#endif

	flip_edge(u1, v1);
	flip_edge(u1, v2);
	flip_edge(u2, v1);
	flip_edge(u2, v2);
}
Esempio n. 2
0
CubitStatus CubitFacetData::flip_edge( CubitFacetEdge *edge )
{
  int i;
  for(i=0; i<3; i++)
  {
    if (edgeArray[i] == edge)
      return flip_edge(i);
  }
  return CUBIT_FAILURE;
}
IGL_INLINE void igl::delaunay_triangulation(
    const Eigen::PlainObjectBase<DerivedV>& V,
    Orient2D orient2D,
    InCircle incircle,
    Eigen::PlainObjectBase<DerivedF>& F)
{
  assert(V.cols() == 2);
  typedef typename DerivedF::Scalar Index;
  typedef typename DerivedV::Scalar Scalar;
  igl::lexicographic_triangulation(V, orient2D, F);
  const size_t num_faces = F.rows();
  if (num_faces == 0) {
    // Input points are degenerate.  No faces will be generated.
    return;
  }
  assert(F.cols() == 3);

  Eigen::MatrixXi E;
  Eigen::MatrixXi uE;
  Eigen::VectorXi EMAP;
  std::vector<std::vector<Index> > uE2E;
  igl::unique_edge_map(F, E, uE, EMAP, uE2E);

  auto is_delaunay = [&V,&F,&uE2E,num_faces,&incircle](size_t uei) {
    auto& half_edges = uE2E[uei];
    if (half_edges.size() != 2) {
      throw "Cannot flip non-manifold or boundary edge";
    }

    const size_t f1 = half_edges[0] % num_faces;
    const size_t f2 = half_edges[1] % num_faces;
    const size_t c1 = half_edges[0] / num_faces;
    const size_t c2 = half_edges[1] / num_faces;
    assert(c1 < 3);
    assert(c2 < 3);
    assert(f1 != f2);
    const size_t v1 = F(f1, (c1+1)%3);
    const size_t v2 = F(f1, (c1+2)%3);
    const size_t v4 = F(f1, c1);
    const size_t v3 = F(f2, c2);
    const Scalar p1[] = {V(v1, 0), V(v1, 1)};
    const Scalar p2[] = {V(v2, 0), V(v2, 1)};
    const Scalar p3[] = {V(v3, 0), V(v3, 1)};
    const Scalar p4[] = {V(v4, 0), V(v4, 1)};
    auto orientation = incircle(p1, p2, p4, p3);
    return orientation <= 0;
  };

  bool all_delaunay = false;
  while(!all_delaunay) {
    all_delaunay = true;
    for (size_t i=0; i<uE2E.size(); i++) {
      if (uE2E[i].size() == 2) {
        if (!is_delaunay(i)) {
          all_delaunay = false;
          flip_edge(F, E, uE, EMAP, uE2E, i);
        }
      }
    }
  }
}
Esempio n. 4
0
void EdgeFlipper::process_mesh( )
{
    
    if ( m_surf.m_verbose )
    {
        std::cout << "---------------------- EdgeFlipper: flipping ----------------------" << std::endl;
    }
	    
    m_surf.m_dirty_triangles.clear();
    
    bool flip_occurred_ever = false;          // A flip occurred in this function call
    bool flip_occurred = true;                // A flip occurred in the current loop iteration
    
    static unsigned int MAX_NUM_FLIP_PASSES = 5;
    unsigned int num_flip_passes = 0;
    
    NonDestructiveTriMesh& m_mesh = m_surf.m_mesh;
    const std::vector<Vec3d>& xs = m_surf.get_positions();
    
    //
    // Each "pass" is once over the entire set of edges (ignoring edges created during the current pass)
    //
    
    while ( flip_occurred && num_flip_passes++ < MAX_NUM_FLIP_PASSES )
    {
        if ( m_surf.m_verbose )
        {
            std::cout << "---------------------- El Topo: flipping ";
            std::cout << "pass " << num_flip_passes << "/" << MAX_NUM_FLIP_PASSES;
            std::cout << "----------------------" << std::endl;
        }
        
        flip_occurred = false;
        
        size_t number_of_edges = m_mesh.m_edges.size();      // don't work on newly created edges
        
        for( size_t i = 0; i < number_of_edges; i++ )
        {
            if ( m_mesh.m_edges[i][0] == m_mesh.m_edges[i][1] )   { continue; }
            if ( m_mesh.m_edge_to_triangle_map[i].size() > 4 || m_mesh.m_edge_to_triangle_map[i].size() < 2 )   { continue; }
            if ( m_mesh.m_is_boundary_vertex[ m_mesh.m_edges[i][0] ] || m_mesh.m_is_boundary_vertex[ m_mesh.m_edges[i][1] ] )  { continue; }  // skip boundary vertices
            
            size_t triangle_a = (size_t)~0, triangle_b =(size_t)~0;
            
            if ( m_mesh.m_edge_to_triangle_map[i].size() == 2 )
            {    
                triangle_a = m_mesh.m_edge_to_triangle_map[i][0];
                triangle_b = m_mesh.m_edge_to_triangle_map[i][1];         
                assert (    m_mesh.oriented( m_mesh.m_edges[i][0], m_mesh.m_edges[i][1], m_mesh.get_triangle(triangle_a) ) 
                        != m_mesh.oriented( m_mesh.m_edges[i][0], m_mesh.m_edges[i][1], m_mesh.get_triangle(triangle_b) ) );
            }
            else if ( m_mesh.m_edge_to_triangle_map[i].size() == 4 )
            {           
                triangle_a = m_mesh.m_edge_to_triangle_map[i][0];
                
                // Find first triangle with orientation opposite triangle_a's orientation
                unsigned int j = 1;
                for ( ; j < 4; ++j )
                {
                    triangle_b = m_mesh.m_edge_to_triangle_map[i][j];
                    if (    m_mesh.oriented( m_mesh.m_edges[i][0], m_mesh.m_edges[i][1], m_mesh.get_triangle(triangle_a) ) 
                        != m_mesh.oriented( m_mesh.m_edges[i][0], m_mesh.m_edges[i][1], m_mesh.get_triangle(triangle_b) ) )
                    {
                        break;
                    }
                }
                assert ( j < 4 );
            }
            else
            {
                std::cout << m_mesh.m_edge_to_triangle_map[i].size() << " triangles incident to an edge" << std::endl;
                assert(0);
            }
            
            // Don't flip edge on a degenerate triangle
            const Vec3st& tri_a = m_mesh.get_triangle( triangle_a );
            const Vec3st& tri_b = m_mesh.get_triangle( triangle_b );
            
            if (   tri_a[0] == tri_a[1] 
                || tri_a[1] == tri_a[2] 
                || tri_a[2] == tri_a[0] 
                || tri_b[0] == tri_b[1] 
                || tri_b[1] == tri_b[2] 
                || tri_b[2] == tri_b[0] )
            {
                continue;
            }
            
            size_t third_vertex_0 = m_mesh.get_third_vertex( m_mesh.m_edges[i][0], m_mesh.m_edges[i][1], tri_a );
            size_t third_vertex_1 = m_mesh.get_third_vertex( m_mesh.m_edges[i][0], m_mesh.m_edges[i][1], tri_b );
            
            if ( third_vertex_0 == third_vertex_1 )
            {
                continue;
            }
            
            bool flipped = false;
            
            double current_length = mag( xs[m_mesh.m_edges[i][1]] - xs[m_mesh.m_edges[i][0]] );        
            double potential_length = mag( xs[third_vertex_1] - xs[third_vertex_0] );     
            if ( potential_length < current_length - m_edge_flip_min_length_change )
            {
                flipped = flip_edge( i, triangle_a, triangle_b, third_vertex_0, third_vertex_1 );            
            }
            
            //         else if ( regularity_improves( i, triangle_a, triangle_b, third_vertex_0, third_vertex_1 ) )
            //         {
            //            
            //            size_t r_before = total_mesh_regularity();
            //            
            //            flipped = flip_edge( i, triangle_a, triangle_b, third_vertex_0, third_vertex_1 );
            //            
            //            size_t r_after = total_mesh_regularity();
            //
            //            assert( !flipped || r_after < r_before );
            //            
            //         }
            
            
            flip_occurred |= flipped;
        }
        
        flip_occurred_ever |= flip_occurred;
    }
    
    
    if ( flip_occurred_ever )
    {
        m_surf.trim_non_manifold( m_surf.m_dirty_triangles );
    }
    
}
// Subdivide each facet of the lcc by using sqrt(3)-subdivision.
void
subdivide_lcc_3 (LCC & m)
{
  if (m.number_of_darts () == 0)
    return;

  LCC::size_type mark = m.get_new_mark ();
  LCC::size_type treated = m.get_new_mark ();
  m.negate_mark (mark);  // All the old darts are marked in O(1).

  // 1) We smoth the old vertices.
  std::vector <std::pair<Point_3, Dart_handle> > vertices;  // smooth the old vertices
  vertices.reserve (m.number_of_attributes<0> ());  // get intermediate space
  std::transform (m.vertex_attributes().begin (), 
		  m.vertex_attributes().end (),
		  std::back_inserter (vertices), 
		  Smooth_old_vertex (m, mark));

  // 2) We subdivide each facet.
  m.negate_mark (treated);  // All the darts are marked in O(1).
  unsigned int nb = 0;
  for (LCC::Dart_range::iterator it (m.darts().begin ());
       m.number_of_marked_darts (treated) > 0; ++it)
  {
    ++nb;
    if (m.is_marked (it, treated))
    {
      // We unmark the darts of the facet to process only once dart/facet.
      CGAL::unmark_cell < LCC, 2 > (m, it, treated);
      // We triangulate the facet.
      m.insert_barycenter_in_cell<2>(it);
    }
  }

  CGAL_assertion (m.is_whole_map_unmarked (treated));
  CGAL_assertion (m.is_valid ());
  m.free_mark (treated);

  // 3) We update the coordinates of old vertices.
  for (std::vector<std::pair<Point_3, Dart_handle> >::iterator
         vit=vertices.begin(); vit!=vertices.end(); ++vit)
  {
    m.point(vit->second)=vit->first;
  }

  // 4) We flip all the old edges.
  m.negate_mark (mark);  // Now only new darts are marked.
  Dart_handle d2 =LCC::null_handle;
  for (LCC::Dart_range::iterator it (m.darts().begin ());
       it != m.darts().end ();)
  {
    d2 = it++;
    if (!m.is_marked (d2, mark))  // This is an old dart.
    {
      // We process only the last dart of a same edge.
      if (!m.is_free(d2,2) && (m.beta(d2,2,3)==m.beta(d2,3,2)))
      {
        if (m.is_marked(m.beta(d2,2), mark) &&
            (m.is_free(d2,3) ||
             (m.is_marked(m.beta(d2,3), mark) &&
              m.is_marked(m.beta(d2,2,3), mark))))
        {
          flip_edge (m, d2);
          m.mark(d2, mark);
        }
        else
          m.mark (d2, mark);
      }
      else
        m.mark (d2, mark);
    }
  }

  CGAL_assertion (m.is_whole_map_marked (mark));
  m.free_mark (mark);
  
  CGAL_postcondition ( m.is_valid ());
}