Exemple #1
0
int do_diag (cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
{
	unsigned int i;

	if (argc == 1 || strcmp (argv[1], "run") != 0) {
		/* List test info */
		if (argc == 1) {
			puts ("Available hardware tests:\n");
			post_info (NULL);
			puts ("Use 'diag [<test1> [<test2> ...]]'"
					" to get more info.\n");
			puts ("Use 'diag run [<test1> [<test2> ...]]'"
					" to run tests.\n");
		} else {
			for (i = 1; i < argc; i++) {
			    if (post_info (argv[i]) != 0)
				printf ("%s - no such test\n", argv[i]);
			}
		}
	} else {
		/* Run tests */
		if (argc == 2) {
			post_run (NULL, POST_RAM | POST_MANUAL);
		} else {
			for (i = 2; i < argc; i++) {
			    if (post_run (argv[i], POST_RAM | POST_MANUAL) != 0)
				printf ("%s - unable to execute the test\n",
					argv[i]);
			}
		}
	}

	return 0;
}
Exemple #2
0
bool EdgeFlipper::flip_edge( size_t edge, 
                            size_t tri0, 
                            size_t tri1, 
                            size_t third_vertex_0, 
                            size_t third_vertex_1 )
{     
    NonDestructiveTriMesh& m_mesh = m_surf.m_mesh;
    const std::vector<Vec3d>& xs = m_surf.get_positions();
    
    Vec2st& edge_vertices = m_mesh.m_edges[edge];
    
    // Find the vertices which will form the new edge
    Vec2st new_edge( third_vertex_0, third_vertex_1);
    
    // --------------
    
    // Control volume change
    double vol = fabs( signed_volume( xs[edge_vertices[0]], 
                                     xs[edge_vertices[1]], 
                                     xs[new_edge[0]], 
                                     xs[new_edge[1]] ) ); 
    
    if ( vol > m_surf.m_max_volume_change )
    {
        if ( m_surf.m_verbose ) { std::cout << "edge flip rejected: volume change = " << vol << std::endl; }
        return false;
    }
    
    // --------------
    
    // Prevent non-manifold surfaces if we're not allowing them
    if ( false == m_surf.m_allow_non_manifold )
    {
        for ( size_t i = 0; i < m_mesh.m_vertex_to_edge_map[ third_vertex_0 ].size(); ++i )
        {
            if ( ( m_mesh.m_edges[ m_mesh.m_vertex_to_edge_map[third_vertex_0][i] ][0] == third_vertex_1 ) ||
                ( m_mesh.m_edges[ m_mesh.m_vertex_to_edge_map[third_vertex_0][i] ][1] == third_vertex_1 ) )
            {
                // edge already exists
                if ( m_surf.m_verbose ) { std::cout << "edge flip rejected: edge exists" << std::endl;             }            
                return false;
            }
        }
    }
    
    // --------------
    
    // Don't flip edge on a degenerate tet
    if ( third_vertex_0 == third_vertex_1 )
    {
        if ( m_surf.m_verbose ) { std::cout << "edge flip rejected: degenerate tet" << std::endl; }
        return false;
    }
    
    // --------------
    
    // Create the new triangles
    // new edge winding order == winding order of old triangle0 == winding order of new triangle0
    
    size_t new_triangle_third_vertex_0, new_triangle_third_vertex_1;
    if ( m_mesh.oriented( m_mesh.m_edges[edge][0], m_mesh.m_edges[edge][1], m_mesh.get_triangle(tri0) ) ) 
    {
		assert( m_mesh.oriented( m_mesh.m_edges[edge][1], m_mesh.m_edges[edge][0], m_mesh.get_triangle(tri1) ) );
        new_triangle_third_vertex_0 = m_mesh.m_edges[edge][1];
        new_triangle_third_vertex_1 = m_mesh.m_edges[edge][0];
    }
    else
    {
		assert( m_mesh.oriented( m_mesh.m_edges[edge][0], m_mesh.m_edges[edge][1], m_mesh.get_triangle(tri1) ) );
		assert( m_mesh.oriented( m_mesh.m_edges[edge][1], m_mesh.m_edges[edge][0], m_mesh.get_triangle(tri0) ) );
        new_triangle_third_vertex_0 = m_mesh.m_edges[edge][0];
        new_triangle_third_vertex_1 = m_mesh.m_edges[edge][1];
    }
    
    Vec3st new_triangle0( new_edge[0], new_edge[1], new_triangle_third_vertex_0 );
    Vec3st new_triangle1( new_edge[1], new_edge[0], new_triangle_third_vertex_1 );
    
    if ( m_surf.m_verbose )
    {
        std::cout << "flip --- new triangle 0: " << new_triangle0 << std::endl;
        std::cout << "flip --- new triangle 1: " << new_triangle1 << std::endl;
    }
    
    // --------------
    
    // if both triangle normals agree before flipping, make sure they agree after flipping
    if ( dot( m_surf.get_triangle_normal(tri0), m_surf.get_triangle_normal(tri1) ) > 0.0 ) 
    {
        if ( dot( m_surf.get_triangle_normal(new_triangle0), m_surf.get_triangle_normal(new_triangle1) ) < 0.0 )
        {
            if ( m_surf.m_verbose ) { std::cout << "edge flip rejected: normal inversion" << std::endl; }
            return false;
        }
        
        if ( dot( m_surf.get_triangle_normal(new_triangle0), m_surf.get_triangle_normal(tri0) ) < 0.0 )
        {
            if ( m_surf.m_verbose ) { std::cout << "edge flip rejected: normal inversion" << std::endl; }
            return false;
        }
        
        if ( dot( m_surf.get_triangle_normal(new_triangle1), m_surf.get_triangle_normal(tri1) ) < 0.0 )
        {
            if ( m_surf.m_verbose ) { std::cout << "edge flip rejected: normal inversion" << std::endl; }
            return false;
        }
        
        if ( dot( m_surf.get_triangle_normal(new_triangle0), m_surf.get_triangle_normal(tri1) ) < 0.0 )
        {
            if ( m_surf.m_verbose ) { std::cout << "edge flip rejected: normal inversion" << std::endl; }
            return false;
        }
        
        if ( dot( m_surf.get_triangle_normal(new_triangle1), m_surf.get_triangle_normal(tri0) ) < 0.0 )
        {
            if ( m_surf.m_verbose ) { std::cout << "edge flip rejected: normal inversion" << std::endl; }
            return false;
        }
    }
    
    // --------------
    
    // Prevent intersection
    if ( m_surf.m_collision_safety && flip_introduces_collision( edge, new_edge, new_triangle0, new_triangle1 ) )
    {
        if ( m_surf.m_verbose ) { std::cout << "edge flip rejected: intersection" << std::endl; }
        return false;
    }
    
    // --------------
    
    // Prevent degenerate triangles
    if ( triangle_area( xs[new_triangle0[0]], xs[new_triangle0[1]], xs[new_triangle0[2]] ) < m_surf.m_min_triangle_area )
    {
        if ( m_surf.m_verbose ) { std::cout << "edge flip rejected: area too small" << std::endl;    }
        return false;
    }
    
    if ( triangle_area( xs[new_triangle1[0]], xs[new_triangle1[1]], xs[new_triangle1[2]] ) < m_surf.m_min_triangle_area )
    {
        if ( m_surf.m_verbose ) {std::cout << "edge flip rejected: area too small" << std::endl; }
        return false;
    }
    
    
    // --------------
    
    // Control change in area
    
    double old_area = m_surf.get_triangle_area( tri0 ) + m_surf.get_triangle_area( tri1 );
    double new_area = triangle_area( xs[new_triangle0[0]], xs[new_triangle0[1]], xs[new_triangle0[2]] ) 
    + triangle_area( xs[new_triangle1[0]], xs[new_triangle1[1]], xs[new_triangle1[2]] );
    
    if ( fabs( old_area - new_area ) > 0.1 * old_area )
    {
        if ( m_surf.m_verbose ) {std::cout << "edge flip rejected: area change too great" << std::endl; }
        return false;
    }
    
    // --------------
    
    // Don't flip unless both vertices are on a smooth patch
    if ( ( m_surf.classify_vertex( edge_vertices[0] ) > 1 ) || ( m_surf.classify_vertex( edge_vertices[1] ) > 1 ) )
    {
        if ( m_surf.m_verbose ) {std::cout << "edge flip rejected: vertices not on smooth patch" << std::endl;  }
        return false;
    }        
    
    
    // --------------
    
    // Don't introduce a large or small angle
    
    double min_angle = min_triangle_angle( xs[new_triangle0[0]], xs[new_triangle0[1]], xs[new_triangle0[2]] );
    min_angle = min( min_angle, min_triangle_angle( xs[new_triangle1[0]], xs[new_triangle1[1]], xs[new_triangle1[2]] ) );
    
    if ( rad2deg(min_angle) < m_surf.m_min_triangle_angle )
    {
        return false;
    }
    
    double max_angle = max_triangle_angle( xs[new_triangle0[0]], xs[new_triangle0[1]], xs[new_triangle0[2]] );
    max_angle = max( max_angle, max_triangle_angle( xs[new_triangle1[0]], xs[new_triangle1[1]], xs[new_triangle1[2]] ) );
    
    if ( rad2deg(max_angle) > m_surf.m_max_triangle_angle )
    {
        return false;
    }
    
    // --------------
    
    PreEdgeFlipInfo pre_info( edge, tri0, tri1 );

    for ( size_t i = 0; i < m_observers.size(); ++i )
    {
        if ( false == m_observers[i]->operationOK(m_surf, pre_info) )
        {
            return false;
        }
    }
    
    // --------------
    
    // Okay, now do the actual operation
       
    Vec3st old_tri0 = m_mesh.get_triangle(tri0);
    Vec3st old_tri1 = m_mesh.get_triangle(tri1);
    
    m_surf.remove_triangle( tri0 );
    m_surf.remove_triangle( tri1 );
    
    size_t new_triangle_index_0 = m_surf.add_triangle( new_triangle0 );
    size_t new_triangle_index_1 = m_surf.add_triangle( new_triangle1 );
        
    if ( m_surf.m_collision_safety )
    {
        if ( m_surf.m_collision_pipeline.check_triangle_vs_all_triangles_for_intersection( new_triangle_index_0 ) )
        {
            std::cout << "missed an intersection.  New triangles: " << new_triangle0 << ", " << new_triangle1 << std::endl;
            std::cout << "old triangles: " << old_tri0 << ", " << old_tri1 << std::endl;
            assert(0);
        }
        
        if ( m_surf.m_collision_pipeline.check_triangle_vs_all_triangles_for_intersection( new_triangle_index_1 ) )
        {
            std::cout << "missed an intersection.  New triangles: " << new_triangle0 << ", " << new_triangle1 << std::endl;
            std::cout << "old triangles: " << old_tri0 << ", " << old_tri1 << std::endl;      
            assert(0);
        }
    }
    
    m_surf.m_dirty_triangles.push_back( new_triangle_index_0 );
    m_surf.m_dirty_triangles.push_back( new_triangle_index_1 );   
    
    if ( m_surf.m_verbose ) { std::cout << "edge flip: ok" << std::endl; }
    
    PostEdgeFlipInfo post_info( pre_info, new_triangle_index_0, new_triangle_index_1 );
    
    for ( size_t i = 0; i < m_observers.size(); ++i )
    {
        m_observers[i]->operationOccurred(m_surf, post_info);
    }

    
    return true;
    
}