Пример #1
0
int main(int argc, char **argv)
{
   std::cout << "Starting\n";

   std::ifstream in (argc == 1 ? "data/moebius.cin" : argv[1]);
   std::istream_iterator<Gt::Point_2> start (in);
   std::istream_iterator<Gt::Point_2> stop;

   std::cout << "File opened\n";

   M dia;

   std::cout << "Created\n";

   int n = dia.init (start, stop);

   std::cout << "Initialized " << n << std::endl;

   Rt rt (dia.rt ());

   std::cout << "Copied\n";

   rt.is_valid ();

   std::cout << "Validated\n";

   dia.build ();

   std::cout << "Built\n";

   return 0;
}
Пример #2
0
int main()
{
  // generate points on a 3D grid
  std::vector<Weighted_point> P;

  int number_of_points = 0;

  for (int z=0 ; z<5 ; z++)
    for (int y=0 ; y<5 ; y++)
      for (int x=0 ; x<5 ; x++) {
	  Point p(x, y, z);
          Weight w = (x+y-z*y*x)*2.0; // let's say this is the weight.
	  P.push_back(Weighted_point(p, w));
          ++number_of_points;
      }

  Rt T;

  // insert all points in a row (this is faster than one insert() at a time).
  T.insert (P.begin(), P.end());

  assert( T.is_valid() );
  assert( T.dimension() == 3 );

  std::cout << "Number of vertices : " << T.number_of_vertices() << std::endl;

  // removal of all vertices
  int count = 0;
  while (T.number_of_vertices() > 0) {
      T.remove (T.finite_vertices_begin());
      ++count;
  }

  assert( count == number_of_points );

  return 0;
}
// Constructs regular triangulation of weighted points.
// Builds graph of cells with voids. Finds connected components of this graph (voids as clusters of cells).
// For each component calculates total void volume and area.
// Excludes roughs on the surface (components, connected to the infinite cell).
bool regular_triangulation_voids(const Wpi_container& points, Voids_result &res)
{
    typedef typename boost::adjacency_list<boost::vecS, boost::vecS, boost::undirectedS, Cell_handle> CellGraph;
    typedef typename boost::graph_traits<CellGraph>::vertex_descriptor GVertex;
    typedef typename boost::graph_traits<CellGraph>::vertex_iterator GVertex_iterator;

    Rt T;            // regular triangulation
    CellGraph G;     // Voronoi subgraph where cells_sqr_r > 0 and edges_sqr_r > 0 (cells and edges with voids)
    GVertex_iterator vi, vi_end;


    res.out_log << "Number of input points for RT : " <<  points.size() << std::endl;
    T.insert(points.begin(), points.end());    // insert all points in a row (this is faster than one insert() at a time).
    T.infinite_vertex()->info().atom_id = -1;  // set special atom_id for dummy infinite triangulation vertex

    assert(T.dimension() == 3);
    /*res.out_log << "Is valid : " << T.is_valid() << std::endl;*/
    res.out_log << "Number of vertices in RT : " << T.number_of_vertices() << std::endl;
    res.out_log << "Number of cells : " << T.number_of_cells() << std::endl;
    res.out_log << "Number of finite cells : " << T.number_of_finite_cells() << std::endl;
    /*res.out_log << "Inf. vert. atom id : " << T.infinite_vertex()->info().atom_id << std::endl;*/

    // Add finite cells having sqr_r > 0 as graph verticies
    Finite_cells_iterator cit, cit_end = T.finite_cells_end();
    for (cit = T.finite_cells_begin(); cit != cit_end; cit++) {
        if (cit->weighted_circumcenter().weight() > 0)       // cached weighted circumcenter computation
            cit->id() = add_vertex(Cell_handle(cit), G);     // store corresponding graph vertex descriptor in cell's id()
    }

    // store one of infinite cells in graph: it will represent all of them. It should be the last vertex in graph with maximal vertex_descriptor.
    const GVertex inf_graph_v = add_vertex(T.infinite_cell(), G);
    res.out_log << "inf_graph_v descriptor : " << inf_graph_v << std::endl;

    // Add graph edges connecting cells with void
    for (boost::tie(vi, vi_end) = vertices(G); vi != vi_end; ++vi) {
        const GVertex v1 = *vi;           // current graph vertex

        if (v1 != inf_graph_v) { // check edges only from finite cells
            const Cell_handle c1 = G[v1];    // current cell

            for (int i = 0; i < 4; i++) {       // for each of four neighbor cells
                const Cell_handle c2 = c1->neighbor(i);
                bool ends_in_void = false;   // do both corresponding Voronoi verticies lie in void space?
                bool on_same_side = false;   // do both ends lie on the same side of corresponding cell facet?
                const Weighted_point &p1 = c1->vertex((i+1)&3)->point();     // weighted points of common facet between c and c2 cells
                const Weighted_point &p2 = c1->vertex((i+2)&3)->point();
                const Weighted_point &p3 = c1->vertex((i+3)&3)->point();
                const Point &wcc = c1->weighted_circumcenter().point();
                GVertex v2;  // neighbor vertex in graph to construct edge to

                if (c2->id() != -1) {    // neighbor cell is finite and in graph: id()=vertex_descriptor
                    v2 = c2->id();
                    ends_in_void = true;
                    on_same_side = (orientation(p1.point(), p2.point(), p3.point(), wcc) ==
                                    orientation(p1.point(), p2.point(), p3.point(), c2->weighted_circumcenter().point()));
                } else if (T.is_infinite(c2))   {
                    v2 = inf_graph_v;    // use our infinite graph vertex as destination if neighbor cell is infinite
                    ends_in_void = true;
                    on_same_side = (orientation(p1.point(), p2.point(), p3.point(), wcc) !=
                                    orientation(p1.point(), p2.point(), p3.point(), c1->vertex(i)->point().point()));  // same side with infinite vertex = different sides with cell vertex
                }

                typename K::Compute_squared_radius_smallest_orthogonal_sphere_3 r_mouth;  // facet bottleneck squared radius (facet closed if < 0)
                if (ends_in_void && (v2 > v1) && (on_same_side || r_mouth(p1, p2, p3) > 0))
                    add_edge(v1, v2, G);  // use ordering v2>v1 to rule out most of the parallel edges: rely on v_inf>v1 for all finite vertices
            }
        }
    }

    res.out_log << "Number of vertices in G : " << num_vertices(G) << std::endl;
    res.out_log << "Number of edges in G : " << num_edges(G) << std::endl;

    // Find connected components on this Voronoi subnetwork
    std::vector<int> component(num_vertices(G));
    int num_components = boost::connected_components(G, &component[0]);
    const int inf_comp_id = component[inf_graph_v];  // component of infinite vertex
    res.out_log << "Number of connected components : " << num_components << std::endl;
    res.out_log << "Component id of infinite vertex : " << inf_comp_id << std::endl;

    // Reserve storage for results
    res.voids.resize(num_components);
    std::fill(res.atom_surf.begin(), res.atom_surf.end(), 0.0L);

    // Calculate total volume of each finite component
    for (boost::tie(vi, vi_end) = vertices(G); vi != vi_end; ++vi) {
        const int comp_id = component[*vi];
        if (comp_id != inf_comp_id) {   // skip infinite component
            Cell_handle cell = G[*vi];  // current cell
            double Vc, Sc;              // cell volume and surface
            Array_double_4 Sa;          // per atom surface in cell
            Vc = cell_void_volume(cell, Sc, Sa);     // void volume of cell and its surface area

            res.voids[comp_id].volume += Vc;  // add to volume of component
            res.voids[comp_id].surface += Sc;
            for (int k = 0; k < 4; k++) {  // process four cell atoms
                int atom_id = cell->vertex(k)->info().atom_id;
                res.atom_surf[atom_id] += Sa[k];     // atom exposed surface
                res.voids[comp_id].atoms.insert(atom_id);  // add to set of cavity atoms
            }
        }
    }

    // Remove skipped infinite component with zero values
    res.voids.erase(res.voids.begin() + inf_comp_id);

    // Sort cavities by volume
    std::sort(res.voids.begin(), res.voids.end(), void_greater);

    return true;
}