Exemplo n.º 1
0
void create_circle( std::vector<Vec3d>& verts, 
                   std::vector<Vec3st>& tris, 
                   std::vector<double>& masses,
                   const Vec3d& centre,
                   double radius,
                   size_t nx )
{
    Vec3d low = centre - Vec3d( radius, 0.0, radius );
    
    double dx = 2.0 * radius / (double)nx;
    
    Array2<Vec3d> grid_points;
    grid_points.resize(nx, nx);
    for ( size_t i = 0; i < nx; ++i )
    {
        for ( size_t j = 0; j < nx; ++j )
        {
            grid_points(i,j) = low + dx * Vec3d( i, 0, j );
            verts.push_back( low + dx * Vec3d( i, 0, j ) );
        }
    }
    
    // cells
    for ( size_t i = 0; i < nx-1; ++i )
    {
        for ( size_t j = 0; j < nx-1; ++j )
        {
            size_t a = i   + nx*j;
            size_t b = i+1 + nx*j;
            size_t c = i+1 + nx*(j+1);
            size_t d = i   + nx*(j+1);
            
            
            if ( ( dist( verts[a], centre ) < radius ) &&
                ( dist( verts[b], centre ) < radius ) &&
                ( dist( verts[d], centre ) < radius ) )
            {
                tris.push_back( Vec3st( a, b, d ) );
            }
            
            if ( ( dist( verts[b], centre ) < radius ) &&
                ( dist( verts[c], centre ) < radius ) &&
                ( dist( verts[d], centre ) < radius ) )            
            {
                tris.push_back( Vec3st( b, c, d ) );
            }
        }
    }
    
    masses.clear();
    masses.resize( verts.size(), 1.0 );
    
    NonDestructiveTriMesh temp_tri_mesh;
    temp_tri_mesh.set_num_vertices( verts.size() );
    for ( size_t i = 0; i < tris.size(); ++i )
    {
        temp_tri_mesh.add_triangle( tris[i] );
    }
    
}
Exemplo n.º 2
0
void create_sheet( std::vector<Vec3d>& verts, 
                  std::vector<Vec3st>& tris, 
                  const Vec3d& low_corner, 
                  double dx, 
                  size_t nx, 
                  size_t ny )
{
    
    for(size_t i = 0; i < ny; i++)
    {
        for(size_t j = 0; j < nx; j++)
        {
            
            // plane normal is pointing in +y direction
            Vec3d offset;
            offset[0] = dx*j;  //width*((double)j/nx); 
            offset[1] = 0.0;
            offset[2] = dx*i;  //width*((double)i/ny);              
            
            verts.push_back( low_corner + offset );
            
            rest_vertices.push_back( Vec2d(offset[0], offset[2]) );         
        }
    }
    
    for(size_t i = 0; i < ny-1; i++)
    {
        for(size_t j = 0; j < nx-1; j++)
        {
            size_t idx = i*(nx)+j;
            tris.push_back(Vec3st(idx, idx+(nx), idx+1));
            tris.push_back(Vec3st(idx+1, idx+(nx), idx+(nx)+1));
        }
    }
}
void AccelerationGrid::add_element(size_t idx, const Vec3d& xmin, const Vec3d& xmax)
{
    if(m_elementidxs.size() <= idx)
    {
        m_elementidxs.resize(idx+1);
        m_elementxmins.resize(idx+1);
        m_elementxmaxs.resize(idx+1);
        m_elementquery.resize(idx+1);
    }
    
    m_elementxmins[idx] = xmin;
    m_elementxmaxs[idx] = xmax;
    m_elementquery[idx] = 0;
    
    Vec3i xmini, xmaxi;
    boundstoindices(xmin, xmax, xmini, xmaxi);
    
    for(int i = xmini[0]; i <= xmaxi[0]; i++)
    {
        for(int j = xmini[1]; j <= xmaxi[1]; j++)
        {
            for(int k = xmini[2]; k <= xmaxi[2]; k++)
            {
                std::vector<size_t>*& cell = m_cells(i, j, k);
                if(!cell)
                    cell = new std::vector<size_t>();
                
                cell->push_back(idx);
                m_elementidxs[idx].push_back(Vec3st(i, j, k));
            }
        }
    }
}
Exemplo n.º 4
0
void append_mesh( std::vector<Vec3st>& tris, 
                 std::vector<Vec3d>& verts,
                 std::vector<double>& masses,
                 const std::vector<Vec3st>& new_tris, 
                 const std::vector<Vec3d>& new_verts,
                 const std::vector<double>& new_masses )
{
    size_t old_num_verts = verts.size();
    
    for ( size_t i = 0; i < new_verts.size(); ++i )
    {
        verts.push_back( new_verts[i] );
    }
    
    for ( size_t i = 0; i < new_tris.size(); ++i )
    {
        tris.push_back( new_tris[i] + Vec3st(old_num_verts) );
    }
    
    for ( size_t i = 0; i < new_masses.size(); ++i )
    {
        masses.push_back( new_masses[i] );
    }
    
}
Exemplo n.º 5
0
void create_curved_sheet( std::vector<Vec3d>& verts, 
                         std::vector<Vec3st>& tris, 
                         const Vec3d& low_corner, 
                         double dx, 
                         size_t nx, 
                         size_t ny )
{
    std::cout << "sheet: " << low_corner << ", " << dx << std::endl;
    std::cout << "resolution: " << nx << "x" << ny << std::endl;
    std::cout << "dimensions: " << dx*nx << "x" << dx*ny << std::endl;
    
    unsigned int num_curves = 4;
    double amplitude = dx*nx / 20.0;
    
    for(size_t i = 0; i < ny; i++)
    {
        for(size_t j = 0; j < nx; j++)
        {
            
            double theta = 2.0 * M_PI * (double)j / (double)nx * (double)num_curves;
            
            // plane normal is pointing in +y direction
            double x = dx*j;  //width*((double)j/nx); 
            double z = dx*i;  //width*((double)i/ny);              
            double y = 1e-3*z + amplitude * sin( theta );  
            verts.push_back(Vec3d(x,y,z) + low_corner);
            
        }
    }
    
    for(size_t i = 0; i < ny-1; i++)
    {
        for(size_t j = 0; j < nx-1; j++)
        {
            size_t idx = i*(nx)+j;
            tris.push_back(Vec3st(idx, idx+(nx), idx+1));
            tris.push_back(Vec3st(idx+1, idx+(nx), idx+(nx)+1));
        }
    }
}
Exemplo n.º 6
0
bool read_objfile(NonDestructiveTriMesh &mesh, std::vector<Vec3d> &x, const char *filename_format, ...)
{

#ifdef _MSC_VER
    va_list ap;
    va_start(ap, filename_format);
    int len=_vscprintf(filename_format, ap) // _vscprintf doesn't count
        +1; // terminating '\0'
    char *filename=new char[len];
    vsprintf(filename, filename_format, ap);
    std::ifstream input(filename, std::ifstream::binary);
    delete[] filename;
    va_end(ap);
#else
    va_list ap;
    va_start(ap, filename_format);
    char *filename;
    vasprintf(&filename, filename_format, ap);
    std::ifstream input(filename, std::ifstream::binary);
    std::free(filename);
    va_end(ap);
#endif

    if(!input.good()) return false;
    
    x.clear();
    mesh.clear();
    
    char line[LINESIZE];
    std::vector<int> vertex_list;
    while(input.good()){
        input.getline(line, LINESIZE);
        switch(line[0]){
            case 'v': // vertex data
                if(line[1]==' '){
                    Vec3d new_vertex;
                    std::sscanf(line+2, "%lf %lf %lf", &new_vertex[0], &new_vertex[1], &new_vertex[2]);
                    x.push_back(new_vertex);
                }
                break;
            case 'f': // face data
                if(line[1]==' '){
                    read_face_list(line+2, vertex_list);
                    for(int j=0; j<(int)vertex_list.size()-2; ++j)
                        mesh.add_triangle( Vec3st(vertex_list[0], vertex_list[j+1], vertex_list[j+2]) );
                }
                break;
        }
    }
    return true;
}
Exemplo n.º 7
0
bool read_binary_file( NonDestructiveTriMesh &mesh, 
                      std::vector<Vec3d> &x, 
                      std::vector<double> &masses, 
                      double& curr_t, 
                      const char *filename_format, ...)
{
    va_list ap;
    va_start(ap, filename_format);   
    bifstream infile( filename_format, ap );
    va_end(ap);
    
    assert( infile.good() );
    
    infile.read_endianity();
    
    infile >> curr_t;
    
    unsigned int nverts;
    infile >> nverts;
    x.resize( nverts );
    for ( unsigned int i = 0; i < nverts; ++i )
    {
        infile >> x[i][0];
        infile >> x[i][1];
        infile >> x[i][2];  
        mesh.add_vertex();
    }
    
    masses.resize( nverts );
    for ( unsigned int i = 0; i < nverts; ++i )
    {
        infile >> masses[i];
    }
    
    unsigned int ntris;
    infile >> ntris;
    
    for ( unsigned int t = 0; t < ntris; ++t )
    {
        Vec3ui tri;
        infile >> tri[0];
        infile >> tri[1];
        infile >> tri[2];
        
        mesh.add_triangle( Vec3st(tri) );
    }
    
    infile.close();
    
    return infile.good();
}
Exemplo n.º 8
0
void Driver::SurfAppendMesh(SurfTrack* g_surf,ObjModel& obj)
{
  int oldVNum=g_surf->get_num_vertices();

  for (int i = 0; i < obj.vertexNum; i++)
  {
    Vector3d& p=obj.vertex[i];
    g_surf->add_vertex(Vec3d(p(0),p(1),p(2)),1.0f);
  }

  for (int i = 0; i < obj.faceNum; i++)
  {
    Face& f=obj.face[i];
    int first=oldVNum+f.first-1;
    int second=oldVNum+f.second-1;
    int third=oldVNum+f.third-1;
    g_surf->add_triangle(Vec3st(first,second,third));
  }
}
Exemplo n.º 9
0
void create_sphere( const Vec3d& sphere_centre,
                   double sphere_radius,
                   double dx,
                   std::vector<Vec3d>& verts, 
                   std::vector<Vec3st>& tris )
{
    
    const Vec3d domain_low = sphere_centre - Vec3d(sphere_radius + 3*dx);
    const Vec3d domain_high = sphere_centre + Vec3d(sphere_radius + 3*dx);
    Array3d phi;
    create_sphere_signed_distance( sphere_centre, sphere_radius, dx, domain_low, domain_high, phi );  
    
    MarchingTilesHiRes marching_tiles( domain_low, dx, phi );
    marching_tiles.contour();
    marching_tiles.improve_mesh();
    
    std::vector<Vec3d> new_verts( marching_tiles.x.size() );
    for ( size_t i = 0; i < new_verts.size(); ++i )
    {
        new_verts[i] = marching_tiles.x[i];
    }
    
    std::vector<Vec3st> new_tris( marching_tiles.tri.size() );
    for ( size_t i = 0; i < new_tris.size(); ++i )
    {
        new_tris[i] = Vec3st( marching_tiles.tri[i] );
    }
    
    project_to_exact_sphere( new_verts, sphere_centre, sphere_radius );
    
    Vec3st offset( verts.size() );
    for ( size_t i = 0; i < new_verts.size(); ++i )
    {
        verts.push_back( new_verts[i] );
    }
    
    for ( size_t i = 0; i < new_tris.size(); ++i )
    {
        tris.push_back( new_tris[i] + offset );
    }
    
}
Exemplo n.º 10
0
void contour_phi( const Vec3d& domain_low, double domain_dx, Array3d& phi, std::vector<Vec3st>& tris, std::vector<Vec3d>& verts )
{
    MarchingTilesHiRes tiles( domain_low, domain_dx, phi );
    
    std::cout << "Contouring..." << std::endl;
    tiles.contour();
    
    std::cout << "Improving..." << std::endl;
    tiles.improve_mesh();
    
    std::cout << "Copying..." << std::endl;
    for ( size_t i = 0; i < tiles.tri.size(); ++i )
    {
        tris.push_back( Vec3st( tiles.tri[i] ) );
    }
    
    for ( size_t i = 0; i < tiles.x.size(); ++i )
    {
        verts.push_back( tiles.x[i] );
    }   
    
    std::cout << "done" << std::endl;   
}
Exemplo n.º 11
0
void SurfTrack::remove_triangle(size_t t)
{
    m_mesh.nondestructive_remove_triangle( t );
    if ( m_collision_safety )
    {
        m_broad_phase->remove_triangle( t );
    }
    
    m_triangle_change_history.push_back( TriangleUpdateEvent( TriangleUpdateEvent::TRIANGLE_REMOVE, t, Vec3st(0) ) );
    
}
Exemplo n.º 12
0
//void improvemesh(SurfaceMesh msh,ElTopoParameters elparameters,SurfaceMesh * outmsh)
extern "C" void improvemesh
(
 double * inmsh_verticies,
 int inmsh_Nverticies,
 int * inmsh_triangles,
 int inmsh_Ntriangles,
 double * outmsh_verticies,
 int * outmsh_Nverticies,
 int * outmsh_triangles,
 int * outmsh_Ntriangles,
 double m_proximity_epsilon,
 double m_friction_coefficient,
 double m_min_triangle_area,
 double m_improve_collision_epsilon,
 bool m_use_fraction,
 double m_min_edge_length,
 double m_max_edge_length, 
 double m_max_volume_change,
 double m_min_triangle_angle,
 double m_max_triangle_angle,   
 bool m_use_curvature_when_splitting,
 bool m_use_curvature_when_collapsing,
 double m_min_curvature_multiplier,
 double m_max_curvature_multiplier,
 bool m_allow_vertex_movement,
 double m_edge_flip_min_length_change,
 double m_merge_proximity_epsilon,
 bool m_collision_safety,
 bool m_allow_topology_changes,
 bool m_allow_non_manifold,
 bool m_perform_improvement,
 bool m_verbose
 )
{
  std::vector<Vec3d> vs;
  std::vector<double> masses;

  for ( int i = 0; i < inmsh_Nverticies; ++i )
    {
      vs.push_back( Vec3d( inmsh_verticies[3*i], inmsh_verticies[3*i + 1], inmsh_verticies[3*i + 2] ) );
      masses.push_back( 0.5 );      
    }
    
  std::vector<Vec3st> ts;
  for ( int i = 0; i < inmsh_Ntriangles; ++i )
    {
      ts.push_back( Vec3st( inmsh_triangles[3*i], inmsh_triangles[3*i + 1], inmsh_triangles[3*i + 2] ) );
      printf("%d %d %d\n", inmsh_triangles[3*i], inmsh_triangles[3*i + 1], inmsh_triangles[3*i + 2] );
    }

  
  
  SurfTrackInitializationParameters parameters;

  parameters.m_proximity_epsilon = m_proximity_epsilon;
  parameters.m_friction_coefficient = m_friction_coefficient;
  parameters.m_min_triangle_area = m_min_triangle_area;
  parameters.m_improve_collision_epsilon = m_improve_collision_epsilon;
  parameters.m_use_fraction = m_use_fraction;
  parameters.m_min_edge_length = m_min_edge_length;
  parameters.m_max_edge_length = m_max_edge_length;
  parameters.m_max_volume_change = m_max_volume_change;
  parameters.m_min_triangle_angle = m_min_triangle_angle;
  parameters.m_max_triangle_angle = m_max_triangle_angle;
  parameters.m_use_curvature_when_splitting = m_use_curvature_when_splitting;
  parameters.m_use_curvature_when_collapsing = m_use_curvature_when_collapsing;
  parameters.m_min_curvature_multiplier = m_min_curvature_multiplier;
  parameters.m_max_curvature_multiplier = m_max_curvature_multiplier;
  parameters.m_allow_vertex_movement = m_allow_vertex_movement;
  parameters.m_edge_flip_min_length_change = m_edge_flip_min_length_change;
  parameters.m_merge_proximity_epsilon = m_merge_proximity_epsilon;
  parameters.m_collision_safety = m_collision_safety;
  parameters.m_allow_topology_changes = m_allow_topology_changes;
  parameters.m_allow_non_manifold = m_allow_non_manifold;
  parameters.m_perform_improvement = m_perform_improvement;
  parameters.m_subdivision_scheme = new ButterflyScheme();
  
  SurfTrack surface_tracker( vs, ts, masses, parameters );
  surface_tracker.m_verbose = m_verbose;

  printf("Hello again \n");

  
  surface_tracker.improve_mesh();
  surface_tracker.topology_changes();
  surface_tracker.defrag_mesh();

  // Creating usual array objects
  
  *outmsh_Nverticies = surface_tracker.get_num_vertices();
  //double verticies_out[Nverticies_out*3];
  
  for ( int i = 0; i < *outmsh_Nverticies; ++i )
    {
      outmsh_verticies[3*i+0] = surface_tracker.get_position(i)[0];
      outmsh_verticies[3*i+1] = surface_tracker.get_position(i)[1];
      outmsh_verticies[3*i+2] = surface_tracker.get_position(i)[2];
    }

  *outmsh_Ntriangles = surface_tracker.m_mesh.num_triangles();
//  int triangles_out[Ntriangles_out*3];
  for ( int i = 0; i < *outmsh_Ntriangles; ++i )
    {
      const Vec3st& curr_tri = surface_tracker.m_mesh.get_triangle(i); 
      outmsh_triangles[3*i + 0] = curr_tri[0];
      outmsh_triangles[3*i + 1] = curr_tri[1];
      outmsh_triangles[3*i + 2] = curr_tri[2];
    }

  printf("Nverticies=%d  Ntriangles=%d   volume=%f \n",*outmsh_Nverticies,*outmsh_Ntriangles,surface_tracker.get_volume());
  
//  printmesh(102,Nverticies_out,Ntriangles_out,verticies_out,triangles_out);
//  outmsh->verticies = verticies_out;
  //outmsh->Nverticies = Nverticies_out;
//  outmsh->triangles = triangles_out;
//  outmsh->Ntriangles = Ntriangles_out;

}
Exemplo n.º 13
0
void el_topo_static_operations( const ElTopoMesh* inputs,
                               const struct ElTopoGeneralOptions* general_options,
                               const struct ElTopoStaticOperationsOptions* options, 
                               struct ElTopoDefragInformation* defrag_info,  
                               struct ElTopoMesh* outputs )
{
    //
    // data wrangling
    //
    
    std::vector<Vec3d> vs;
    std::vector<double> masses;
    
    for ( int i = 0; i < inputs->num_vertices; ++i )
    {
        vs.push_back( Vec3d( inputs->vertex_locations[3*i], inputs->vertex_locations[3*i + 1], inputs->vertex_locations[3*i + 2] ) );
        masses.push_back( inputs->vertex_masses[i] );      
    }
    
    std::vector<Vec3st> ts;
    for ( int i = 0; i < inputs->num_triangles; ++i )
    {
        ts.push_back( Vec3st( inputs->triangles[3*i], inputs->triangles[3*i + 1], inputs->triangles[3*i + 2] ) );
    }
    
    
    // =================================================================================
    
    //
    // do the actual operations
    //
    
    // build a SurfTrack
    SurfTrackInitializationParameters construction_parameters;
    
    construction_parameters.m_proximity_epsilon = general_options->m_proximity_epsilon;
    
    construction_parameters.m_use_fraction = false;
    construction_parameters.m_min_edge_length = options->m_min_edge_length;
    construction_parameters.m_max_edge_length = options->m_max_edge_length;
    construction_parameters.m_max_volume_change = options->m_max_volume_change;   
    construction_parameters.m_min_triangle_angle = options->m_min_triangle_angle;
    construction_parameters.m_max_triangle_angle = options->m_max_triangle_angle;
    construction_parameters.m_use_curvature_when_splitting = options->m_use_curvature_when_splitting;
    construction_parameters.m_use_curvature_when_collapsing = options->m_use_curvature_when_collapsing;
    construction_parameters.m_min_curvature_multiplier = options->m_min_curvature_multiplier;
    construction_parameters.m_max_curvature_multiplier = options->m_max_curvature_multiplier;
    construction_parameters.m_allow_vertex_movement = options->m_allow_vertex_movement;
    construction_parameters.m_edge_flip_min_length_change = options->m_edge_flip_min_length_change;   
    construction_parameters.m_merge_proximity_epsilon = options->m_merge_proximity_epsilon;
    construction_parameters.m_collision_safety = general_options->m_collision_safety;
    construction_parameters.m_allow_topology_changes = options->m_allow_topology_changes;
    construction_parameters.m_perform_improvement = options->m_perform_improvement;
    construction_parameters.m_subdivision_scheme = (SubdivisionScheme*) options->m_subdivision_scheme;
    
    
    SurfTrack surface_tracker( vs, ts, masses, construction_parameters ); 
    
    surface_tracker.improve_mesh();
    
    // do merging
    surface_tracker.topology_changes();
    
    surface_tracker.defrag_mesh();
    
    
    // =================================================================================
    
    defrag_info->num_vertex_changes = to_int(surface_tracker.m_vertex_change_history.size());
    defrag_info->vertex_is_remove = (int*) malloc( defrag_info->num_vertex_changes * sizeof(int) );
    defrag_info->vertex_index = (int*) malloc( defrag_info->num_vertex_changes * sizeof(int) );
    defrag_info->split_edge = (int*) malloc( 2 * defrag_info->num_vertex_changes * sizeof(int) );
    
    for ( int i = 0; i < defrag_info->num_vertex_changes; ++i )
    {
        defrag_info->vertex_is_remove[i] = surface_tracker.m_vertex_change_history[i].m_is_remove ? 1 : 0;
        defrag_info->vertex_index[i] = to_int(surface_tracker.m_vertex_change_history[i].m_vertex_index);
        defrag_info->split_edge[2*i+0] = to_int(surface_tracker.m_vertex_change_history[i].m_split_edge[0]);
        defrag_info->split_edge[2*i+1] = to_int(surface_tracker.m_vertex_change_history[i].m_split_edge[1]);
    }
    
    defrag_info->num_triangle_changes = to_int(surface_tracker.m_triangle_change_history.size());
    defrag_info->triangle_is_remove = (int*) malloc( defrag_info->num_triangle_changes * sizeof(int) );
    defrag_info->triangle_index = (int*) malloc( defrag_info->num_triangle_changes * sizeof(int) );
    defrag_info->new_tri = (int*) malloc( 3 * defrag_info->num_triangle_changes * sizeof(int) );
    
    for ( int i = 0; i < defrag_info->num_triangle_changes; ++i )
    {
        defrag_info->triangle_is_remove[i] = surface_tracker.m_triangle_change_history[i].m_is_remove ? 1 : 0;
        defrag_info->triangle_index[i] = to_int(surface_tracker.m_triangle_change_history[i].m_triangle_index);
        defrag_info->new_tri[3*i+0] = to_int(surface_tracker.m_triangle_change_history[i].m_tri[0]);
        defrag_info->new_tri[3*i+1] = to_int(surface_tracker.m_triangle_change_history[i].m_tri[1]);
        defrag_info->new_tri[3*i+2] = to_int(surface_tracker.m_triangle_change_history[i].m_tri[2]);
    }
    
    
    defrag_info->defragged_triangle_map_size = to_int(surface_tracker.m_defragged_triangle_map.size());
    defrag_info->defragged_triangle_map = (int*) malloc( 2 * defrag_info->defragged_triangle_map_size * sizeof(int)  );
    
    for ( int i = 0; i < defrag_info->defragged_triangle_map_size; ++i )
    {
        defrag_info->defragged_triangle_map[2*i+0] = to_int(surface_tracker.m_defragged_triangle_map[i][0]);
        defrag_info->defragged_triangle_map[2*i+1] = to_int(surface_tracker.m_defragged_triangle_map[i][1]);
    }
    
    defrag_info->defragged_vertex_map_size = to_int(surface_tracker.m_defragged_vertex_map.size());
    defrag_info->defragged_vertex_map = (int*) malloc( 2 * defrag_info->defragged_vertex_map_size * sizeof(int) );
    
    for ( int i = 0; i < defrag_info->defragged_vertex_map_size; ++i )
    {
        defrag_info->defragged_vertex_map[2*i+0] = to_int(surface_tracker.m_defragged_vertex_map[i][0]);
        defrag_info->defragged_vertex_map[2*i+1] = to_int(surface_tracker.m_defragged_vertex_map[i][1]);
    }
    
    // =================================================================================
    
    //
    // data wrangling
    //
    
    outputs->num_vertices = to_int(surface_tracker.get_num_vertices());
    outputs->vertex_locations = (double*) malloc( 3 * (outputs->num_vertices) * sizeof(double) );
    outputs->vertex_masses = (double*) malloc( (outputs->num_vertices) * sizeof(double) );
    
    for ( int i = 0; i < outputs->num_vertices; ++i )
    {
        const Vec3d& pos = surface_tracker.get_position(i);
        outputs->vertex_locations[3*i + 0] = pos[0];
        outputs->vertex_locations[3*i + 1] = pos[1];  
        outputs->vertex_locations[3*i + 2] = pos[2];
        outputs->vertex_masses[i] = surface_tracker.m_masses[i];
    }
    
    outputs->num_triangles = to_int(surface_tracker.m_mesh.num_triangles());
    outputs->triangles = (int*) malloc( 3 * (outputs->num_triangles) * sizeof(int) );
    
    for ( int i = 0; i < outputs->num_triangles; ++i )
    {
        const Vec3st& curr_tri = surface_tracker.m_mesh.get_triangle(i); 
        outputs->triangles[3*i + 0] = to_int(curr_tri[0]);
        outputs->triangles[3*i + 1] = to_int(curr_tri[1]);
        outputs->triangles[3*i + 2] = to_int(curr_tri[2]);
    }
    
}
Exemplo n.º 14
0
void el_topo_integrate( const ElTopoMesh* inputs,
                       const double* in_vertex_new_locations,
                       const struct ElTopoGeneralOptions* general_options,
                       const struct ElTopoIntegrationOptions* options,
                       double **out_vertex_locations,
                       double *out_dt )
{
    //
    // data wrangling
    //
    
    std::vector<Vec3d> vs;
    std::vector<double> masses;
    
    for ( int i = 0; i < inputs->num_vertices; ++i )
    {
        vs.push_back( Vec3d( inputs->vertex_locations[3*i], inputs->vertex_locations[3*i + 1], inputs->vertex_locations[3*i + 2] ) );
        masses.push_back( inputs->vertex_masses[i] );
    }
    
    std::vector<Vec3st> ts;
    for ( int i = 0; i < inputs->num_triangles; ++i )
    {
        ts.push_back( Vec3st( inputs->triangles[3*i], inputs->triangles[3*i + 1], inputs->triangles[3*i + 2] ) );
    }
    
    // =================================================================================
    
    //
    // do the integration
    //
    
    // build a DynamicSurface
	DynamicSurface dynamic_surface( vs, ts, masses, general_options->m_proximity_epsilon, options->m_friction_coefficient, general_options->m_collision_safety, general_options->m_verbose );
    
    dynamic_surface.set_all_newpositions( inputs->num_vertices, in_vertex_new_locations );
    
    // advance by dt
    double actual_dt;
    dynamic_surface.integrate( options->m_dt, actual_dt );
    
    // the dt used may be different than specified (if we cut the time step)
    *out_dt = actual_dt;
    
    
    // =================================================================================   
    
    //
    // data wrangling
    //
    
    *out_vertex_locations = (double*) malloc( 3 * inputs->num_vertices * sizeof(double) );
    for ( int i = 0; i < inputs->num_vertices; ++i )
    {
        const Vec3d& pos = dynamic_surface.get_position(i);
        (*out_vertex_locations)[3*i]     = pos[0];
        (*out_vertex_locations)[3*i + 1] = pos[1];
        (*out_vertex_locations)[3*i + 2] = pos[2];
    }
    
}
Exemplo n.º 15
0
void create_icosohedron( std::vector<Vec3d>& verts, 
                        std::vector<Vec3st>& tris )
{
    
    double t = 0.5 * ( 1. - sqrt(5.) );
    double c = 1. / sqrt( 1. - t*t );
    
    Vec3st offset( verts.size() );
    
    verts.push_back( c * Vec3d(  t,  1,  0 ) );
    verts.push_back( c * Vec3d( -t,  1,  0 ) );
    verts.push_back( c * Vec3d(  t, -1,  0 ) );
    verts.push_back( c * Vec3d( -t, -1,  0 ) );
    verts.push_back( c * Vec3d(  1,  0,  t ) );
    verts.push_back( c * Vec3d(  1,  0, -t ) );   
    verts.push_back( c * Vec3d( -1,  0,  t ) );
    verts.push_back( c * Vec3d( -1,  0, -t ) );
    verts.push_back( c * Vec3d(  0,  t,  1 ) );
    verts.push_back( c * Vec3d(  0, -t,  1 ) );
    verts.push_back( c * Vec3d(  0,  t, -1 ) );
    verts.push_back( c * Vec3d(  0, -t, -1 ) );
    
    tris.push_back( Vec3st(0,8,4) + offset );
    tris.push_back( Vec3st(0,5,10) + offset );
    tris.push_back( Vec3st(2,4,9) + offset );
    tris.push_back( Vec3st(2,11,5) + offset );
    tris.push_back( Vec3st(1,6,8) + offset );
    tris.push_back( Vec3st(1,10,7) + offset );
    tris.push_back( Vec3st(3,9,6) + offset );   
    tris.push_back( Vec3st(3,7,11) + offset );   
    tris.push_back( Vec3st(0,10,8) + offset );   
    tris.push_back( Vec3st(1,8,10) + offset );   
    tris.push_back( Vec3st(2,9,11) + offset );   
    tris.push_back( Vec3st(3,9,11) + offset );      
    tris.push_back( Vec3st(4,2,0) + offset );      
    tris.push_back( Vec3st(5,0,2) + offset );      
    tris.push_back( Vec3st(6,1,3) + offset );      
    tris.push_back( Vec3st(7,3,1) + offset );      
    tris.push_back( Vec3st(8,6,4) + offset );      
    tris.push_back( Vec3st(9,4,6) + offset );      
    tris.push_back( Vec3st(10,5,7) + offset );      
    tris.push_back( Vec3st(11,7,5) + offset );         
    
}
Exemplo n.º 16
0
bool MeshMerger::get_zipper_triangles( size_t edge_index_a, size_t edge_index_b, std::vector<Vec3st>& output_triangles )
{
    assert( output_triangles.size() == 8 );
    
    const Vec2st& edge_a = m_surf.m_mesh.m_edges[edge_index_a];
    const Vec2st& edge_b = m_surf.m_mesh.m_edges[edge_index_b];
    
    size_t zipper_vertices[8];
    
    zipper_vertices[0] = edge_a[0];
    zipper_vertices[2] = edge_a[1];
    zipper_vertices[4] = edge_b[0];
    zipper_vertices[6] = edge_b[1];
    
    const std::vector<size_t>& incident_triangles_a = m_surf.m_mesh.m_edge_to_triangle_map[edge_index_a];
    
    assert( incident_triangles_a.size() == 2 );       // should be checked before calling this function
    
    const Vec3st& inc_tri_a0 = m_surf.m_mesh.get_triangle( incident_triangles_a[0] );
    const Vec3st& inc_tri_a1 = m_surf.m_mesh.get_triangle( incident_triangles_a[1] );
    
    size_t third_vertices[2];
    third_vertices[0] = m_surf.m_mesh.get_third_vertex( zipper_vertices[0], zipper_vertices[2], inc_tri_a0 );
    third_vertices[1] = m_surf.m_mesh.get_third_vertex( zipper_vertices[0], zipper_vertices[2], inc_tri_a1 );
    
    if ( m_surf.m_mesh.oriented(zipper_vertices[0], zipper_vertices[2], inc_tri_a0 ) ) 
    {
        zipper_vertices[1] = third_vertices[0];
        zipper_vertices[3] = third_vertices[1];
    } 
    else if ( m_surf.m_mesh.oriented(zipper_vertices[0], zipper_vertices[2], inc_tri_a1) ) 
    {
        zipper_vertices[3] = third_vertices[0];
        zipper_vertices[1] = third_vertices[1];
    } 
    else 
    {
        // Should not happen
        std::cout << "Orientation check failed" << std::endl;
        assert( false );
    }
    
    const std::vector<size_t>& incident_triangles_b = m_surf.m_mesh.m_edge_to_triangle_map[edge_index_b];
    
    assert( incident_triangles_b.size() == 2 );       // should be checked before calling this function
    
    assert( edge_index_b < m_surf.m_mesh.m_edges.size() );
    
    const Vec2st& ce = m_surf.m_mesh.m_edges[edge_index_b];
    const std::vector<size_t>& et = m_surf.m_mesh.m_edge_to_triangle_map[edge_index_b];
    
    const Vec3st& inc_tri_b0 = m_surf.m_mesh.get_triangle( incident_triangles_b[0] );
    const Vec3st& inc_tri_b1 = m_surf.m_mesh.get_triangle( incident_triangles_b[1] );
    
    third_vertices[0] = m_surf.m_mesh.get_third_vertex( ce[0], ce[1], m_surf.m_mesh.get_triangle( et[0] ) );
    
    third_vertices[0] = m_surf.m_mesh.get_third_vertex( zipper_vertices[4], zipper_vertices[6], inc_tri_b0 );
    third_vertices[1] = m_surf.m_mesh.get_third_vertex( zipper_vertices[4], zipper_vertices[6], inc_tri_b1 );   
    
    if ( m_surf.m_mesh.oriented(zipper_vertices[4], zipper_vertices[6], inc_tri_b0) ) 
    {
        zipper_vertices[5] = third_vertices[0];
        zipper_vertices[7] = third_vertices[1];
    } 
    else if ( m_surf.m_mesh.oriented(zipper_vertices[4], zipper_vertices[6], inc_tri_b1) ) 
    {
        zipper_vertices[7] = third_vertices[0];
        zipper_vertices[5] = third_vertices[1];
    } 
    else 
    {
        // Should not happen
        std::cout << "Orientation check failed" << std::endl;
        assert( false );
    }
    
    // Check for degenerate case
    for ( unsigned int i = 0; i < 8; ++i) 
    {
        for ( unsigned int j = i+1; j < 8; ++j) 
        {
            
            if ( zipper_vertices[i] == zipper_vertices[j] )         // vertices not distinct
            {
                return false;
            }
            
            // Check if an edge already exists between two vertices in opposite edge neighbourhoods
            // (i.e. look for an edge which would be created by zippering)
            
            if ( (i < 4) && (j > 3) )
            {
                
                for ( size_t ii = 0; ii < m_surf.m_mesh.m_vertex_to_edge_map[ zipper_vertices[i] ].size(); ++ii )
                {
                    for ( size_t jj = 0; jj < m_surf.m_mesh.m_vertex_to_edge_map[ zipper_vertices[j] ].size(); ++jj )
                    {
                        if ( m_surf.m_mesh.m_vertex_to_edge_map[ zipper_vertices[i] ][ii] == m_surf.m_mesh.m_vertex_to_edge_map[ zipper_vertices[j] ][jj] )
                        {
                            return false;
                        }
                    }
                }
            }
            
        }
    }
    
    // Twist so that vertices 0 and 4 are the pair closest together
    twist_vertices( zipper_vertices );
    
    // now we can use a closed formula to construct zippering triangles
    
    output_triangles[0] = Vec3st( zipper_vertices[0], zipper_vertices[4], zipper_vertices[1] );  // a e b
    output_triangles[1] = Vec3st( zipper_vertices[1], zipper_vertices[4], zipper_vertices[7] );  // b e h
    output_triangles[2] = Vec3st( zipper_vertices[1], zipper_vertices[7], zipper_vertices[2] );  // b h c
    output_triangles[3] = Vec3st( zipper_vertices[2], zipper_vertices[7], zipper_vertices[6] );  // c h g
    output_triangles[4] = Vec3st( zipper_vertices[2], zipper_vertices[6], zipper_vertices[3] );  // c g d
    output_triangles[5] = Vec3st( zipper_vertices[3], zipper_vertices[6], zipper_vertices[5] );  // d g f
    output_triangles[6] = Vec3st( zipper_vertices[3], zipper_vertices[5], zipper_vertices[0] );  // d f a
    output_triangles[7] = Vec3st( zipper_vertices[0], zipper_vertices[5], zipper_vertices[4] );  // a f e
    
    return true;
}