Example #1
0
void ComputeGaussCurvature(Polyhedron::Vertex_iterator v1)
{
  double theta(0.0);
  Point3d p1 = v1->point();
  Point3d p2,p3;
  Vector3d v12, v13;
  Polyhedron::Halfedge_around_vertex_circulator first, curr, next;
  first = curr = v1->vertex_begin();
  do
  {
    next = curr;
    next++;

    p2 = curr->opposite()->vertex()->point();
    p3 = next->opposite()->vertex()->point();

    v12 = p2-p1;
    v13 = p3-p1;

    theta += std::acos( dot(v12,v13) / (norm(v12)*norm(v13)) );
  }
  while(++curr!=first);

  v1->set_gauss_curvature(2.0*M_PI - theta);
}
Example #2
0
Polyhedron::Halfedge_iterator GetHalfedge(Polyhedron::Vertex_iterator a, Polyhedron::Vertex_iterator b)
{
  Polyhedron::Halfedge_around_vertex_circulator first, curr;
  first = curr = b->vertex_begin();
  do
  {
    if(a == curr->opposite()->vertex())
      return curr;
  }
  while(++curr!=first);

  throw std::runtime_error("[Polyhedron::GetHalfedge] Error, a is not connected to b.");
}
void Polyhedron_demo_jet_fitting_plugin::on_actionEstimateCurvature_triggered()
{
  // get active polyhedron
  const Scene_interface::Item_id index = scene->mainSelectionIndex();
  Scene_polyhedron_item* poly_item = 
    qobject_cast<Scene_polyhedron_item*>(scene->item(index));
  if(!poly_item)
    return;

  // wait cursor
  QApplication::setOverrideCursor(Qt::WaitCursor);

  Polyhedron* pMesh = poly_item->polyhedron();

  // types
  typedef CGAL::Monge_via_jet_fitting<Kernel> Fitting;
  typedef Fitting::Monge_form Monge_form;

  typedef Kernel::Point_3 Point;

  Scene_polylines_item* max_curv = new Scene_polylines_item;
  max_curv->setColor(Qt::red);
  max_curv->setName(tr("%1 (max curvatures)").arg(poly_item->name()));
  Scene_polylines_item* min_curv = new Scene_polylines_item;
  min_curv->setColor(Qt::green);
  min_curv->setName(tr("%1 (min curvatures)").arg(poly_item->name()));

  Polyhedron::Vertex_iterator v;
  for(v = pMesh->vertices_begin();
      v != pMesh->vertices_end();
      v++)
  {
    std::vector<Point> points;

    // pick central point
    const Point& central_point = v->point();
    points.push_back(central_point);

    // compute min edge len around central vertex
    // to scale the ribbons used to display the directions

    typedef Kernel::FT FT;

    FT min_edge_len = std::numeric_limits<FT>::infinity();
    Polyhedron::Halfedge_around_vertex_circulator he = v->vertex_begin();
    Polyhedron::Halfedge_around_vertex_circulator end = he;
    CGAL_For_all(he,end)
    {
      const Point& p = he->opposite()->vertex()->point();
      points.push_back(p);
      FT edge_len = std::sqrt(CGAL::squared_distance(central_point,p));
      min_edge_len = edge_len < min_edge_len ? edge_len : min_edge_len; // avoids #undef min
    }

    if(points.size() > 5)
    {
      // estimate curvature by fitting
      Fitting monge_fit;
      const int dim_monge = 2;
      const int dim_fitting = 2;
      Monge_form monge_form = monge_fit(points.begin(),points.end(),dim_fitting,dim_monge);

      // make monge form comply with vertex normal (to get correct
      // orientation)
      typedef Kernel::Vector_3 Vector;
      Vector n = CGAL::Polygon_mesh_processing::compute_vertex_normal(v, *pMesh);
      monge_form.comply_wrt_given_normal(n);

      Vector umin = min_edge_len * monge_form.minimal_principal_direction();
      Vector umax = min_edge_len * monge_form.maximal_principal_direction();

      Scene_polylines_item::Polyline max_segment(2), min_segment(2);

      const double du = 0.2;

      max_segment[0] = central_point + du * umax;
      max_segment[1] = central_point - du * umax;
      min_segment[0] = central_point + du * umin;
      min_segment[1] = central_point - du * umin;

      max_curv->polylines.push_back(max_segment);
      min_curv->polylines.push_back(min_segment);
    }
  }

  scene->addItem(max_curv);
  scene->addItem(min_curv);
  max_curv->changed();
  min_curv->changed();
  
  // default cursor
  QApplication::restoreOverrideCursor();
}