void CriticalCurves::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget)
{
    // Paint the critical curves.
    for (Arrangement_2_iterator arrangement = this->critical_curves.begin(); arrangement != this->critical_curves.end(); ++arrangement)
    {
        for (Edge_iterator edge = arrangement->edges_begin(); edge != arrangement->edges_end(); ++edge)
        {
            // TODO: improve the number of points used for the approximation..
            int n = 25;
            /* Temporarily commented.
            double point_size = 0.4;
            */
            approximated_point_2* points = new approximated_point_2[n + 1];
            edge->curve().polyline_approximation(n, points);
            if (CGAL::COLLINEAR == edge->curve().orientation())
            {
                // Draw a segment.
                QPointF p1 = QPointF(points[0].first, points[0].second);
                QPointF p2 = QPointF(points[1].first, points[1].second);
                painter->drawLine(p1, p2);
                /* Temporarily commented.
                // Draw its endpoints.
                QPointF p3 = QPointF(points[0].first, points[0].second);
                QPointF p4 = QPointF(points[1].first, points[1].second);
                painter->setBrush(QBrush(Qt::black));
                painter->drawEllipse(p3, point_size, point_size);
                painter->drawEllipse(p4, point_size, point_size);
                painter->setBrush(QBrush(Qt::transparent));
                */
            }
            else
            {
                // Draw an approximation of the conic arc.
                QPainterPath path;
                path.moveTo(points[0].first, points[0].second);
                for (int i = 1; i < n + 1; ++i)
                {
                    path.lineTo(points[i].first, points[i].second);
                }
                painter->drawPath(path);
                /* Temporarily commented.
                // Draw its endpoints.
                QPointF p3 = QPointF(points[0].first, points[0].second);
                QPointF p4 = QPointF(points[n].first, points[n].second);
                painter->setBrush(QBrush(Qt::black));
                painter->drawEllipse(p3, point_size, point_size);
                painter->drawEllipse(p4, point_size, point_size);
                painter->setBrush(QBrush(Qt::transparent));
                */
            }
        }
    }

    return;
}
void Scene_polyhedron_transform_item::direct_draw_edges() const {
  typedef Kernel::Point_3		Point;
  typedef Polyhedron::Edge_const_iterator	Edge_iterator;

  ::glDisable(GL_LIGHTING);
  ::glBegin(GL_LINES);
  Edge_iterator he;
  for(he = poly->edges_begin();
      he != poly->edges_end();
      he++)
  {
    const Point& a = he->vertex()->point();
    const Point& b = he->opposite()->vertex()->point();
    ::glVertex3d(a.x()-center_.x,a.y()-center_.y,a.z()-center_.z);
    ::glVertex3d(b.x()-center_.x,b.y()-center_.y,b.z()-center_.z);
  }
  ::glEnd();
  ::glEnable(GL_LIGHTING);
}
void Scene_polyhedron_transform_item::compute_elements() const
{
     positions_lines.resize(0);
    typedef Kernel::Point_3		Point;
    typedef Polyhedron::Edge_const_iterator	Edge_iterator;

    Edge_iterator he;
    for(he = poly->edges_begin();
        he != poly->edges_end();
        he++)
    {
        const Point& a = he->vertex()->point();
        const Point& b = he->opposite()->vertex()->point();
        positions_lines.push_back(a.x()-center_.x);
        positions_lines.push_back(a.y()-center_.y);
        positions_lines.push_back(a.z()-center_.z);

        positions_lines.push_back(b.x()-center_.x);
        positions_lines.push_back(b.y()-center_.y);
        positions_lines.push_back(b.z()-center_.z);

    }
}
void CriticalCurves::setParameters(double radius_1, double radius_2, Arrangements_2 insets_1, Arrangements_2 insets_2)
{
    Arrangement_2_iterator inset_1 = insets_1.begin();
    Arrangement_2_iterator inset_2 = insets_2.begin();

    while (inset_1 != insets_1.end() && inset_2 != insets_2.end())
    {
        Arrangement_2 arrangement;

        // Add the curves of the inset.
        for (Edge_iterator edge = inset_1->edges_begin(); edge != inset_1->edges_end(); ++edge)
        {
            insert(arrangement, edge->curve());
        }

        // Add the critical curves of type I.
        for (Edge_iterator edge = inset_2->edges_begin(); edge != inset_2->edges_end(); ++edge)
        {
            if (CGAL::COLLINEAR == edge->curve().orientation())
            {
                // Displaced a segment.
                Nt_traits nt_traits;
                Algebraic_ft factor = nt_traits.convert(Rational(radius_1) + Rational(radius_2));
                Conic_point_2 source = edge->curve().source();
                Conic_point_2 target = edge->curve().target();
                Algebraic_ft delta_x = target.x() - source.x();
                Algebraic_ft delta_y = target.y() - source.y();
                Algebraic_ft length = nt_traits.sqrt(delta_x * delta_x + delta_y * delta_y);
                Algebraic_ft translation_x = factor * delta_y / length;
                Algebraic_ft translation_y = - factor * delta_x / length;
                Conic_point_2 point_1(source.x() + translation_x, source.y() + translation_y);
                Conic_point_2 point_2(target.x() + translation_x, target.y() + translation_y);
                Algebraic_ft a = - delta_y;
                Algebraic_ft b = delta_x;
                Algebraic_ft c = factor * length - (source.y() * target.x() - source.x() * target.y());
                X_monotone_curve_2 x_monotone_curve(a, b, c, point_1, point_2);
                insert(arrangement, x_monotone_curve);
            }
            else
            {
                // Displaces an arc.
                Rational two(2);
                Rational four(4);

                Rational r = edge->curve().r();
                Rational s = edge->curve().s();
                Rational t = edge->curve().t();
                Rational u = edge->curve().u();
                Rational v = edge->curve().v();
                Rational w = edge->curve().w();

                Nt_traits nt_traits;
                Rational x_center = - u / (two * r);
                Rational y_center = - v / (two * r);
                Rat_point_2 rat_center(x_center, y_center);
                Conic_point_2 center(nt_traits.convert(x_center), nt_traits.convert(y_center));

                Rational radius = Rational(radius_1) + two * Rational(radius_2);

                Algebraic_ft coefficient = nt_traits.convert(radius / Rational(radius_2));

                Conic_point_2 source_1 = edge->curve().source();
                Algebraic_ft x_source_2 = center.x() + coefficient * (source_1.x() - center.x());
                Algebraic_ft y_source_2 = center.y() + coefficient * (source_1.y() - center.y());
                Conic_point_2 source_2(x_source_2, y_source_2);

                Conic_point_2 target_1 = edge->curve().target();
                Algebraic_ft x_target_2 = center.x() + coefficient * (target_1.x() - center.x());
                Algebraic_ft y_target_2 = center.y() + coefficient * (target_1.y() - center.y());
                Conic_point_2 target_2(x_target_2, y_target_2);

                Rat_circle_2 circle(rat_center, radius * radius);

                Conic_arc_2 conic_arc(circle, CGAL::COUNTERCLOCKWISE, source_2, target_2);

                insert(arrangement, conic_arc);
            }
        }

        // Add the critical curves of type II.
        for (Edge_iterator edge = inset_2->edges_begin(); edge != inset_2->edges_end(); ++edge)
        {
            double x = CGAL::to_double(edge->curve().source().x());
            double y = CGAL::to_double(edge->curve().source().y());
            double radius = radius_1 + radius_2;
            Rat_point_2 center(x, y);
            Rat_circle_2 circle(center, radius * radius);
            Conic_arc_2 conic_arc(circle);
            insert(arrangement, conic_arc);
        }

        // Remove the curves which are not include in the inset.
        Objects objects;
        Face_handle face;
        for (Edge_iterator edge = arrangement.edges_begin(); edge != arrangement.edges_end(); ++edge)
        {
            CGAL::zone(*inset_1, edge->curve(), std::back_inserter(objects));
            for (Object_iterator object = objects.begin(); object != objects.end(); ++object)
            {
                if (assign(face, *object))
                {
                    if (face->is_unbounded())
                    {
                        remove_edge(arrangement, edge);
                        break;
                    }
                }
            }
            objects.clear();
        }

        // Print essential information on the standard input.
        std::cout << "Arrangement:" << std::endl;
        std::cout << "  Number of vertices: " << arrangement.number_of_vertices() << std::endl;
        std::cout << "  Number of edges   : " << arrangement.number_of_edges() << std::endl;
        std::cout << "  Number of face    : " << arrangement.number_of_faces() << std::endl;

        this->critical_curves.push_back(arrangement);

        ++inset_1;
        ++inset_2;
    }

    // Commit changes.
    emit(criticalCurvesChanged());
    return;
}
void
Scene_textured_polyhedron_item::compute_normals_and_vertices(void)
{
    positions_facets.resize(0);
    positions_lines.resize(0);
    textures_map_facets.resize(0);
    textures_map_lines.resize(0);
    normals.resize(0);

    typedef ::EPIC_kernel Kernel;
    typedef CGAL::Textured_items Items;
    typedef Kernel::Point_3 Point;
    typedef Kernel::Vector_3 Vector;
    typedef CGAL::Polyhedron_3<Kernel,Items> Base;

    typedef Base::Halfedge_around_facet_circulator Halfedge_around_facet_circulator;
    typedef Base::Edge_iterator Edge_iterator;
    typedef Base::Facet Facet;
    typedef Base::Facet_iterator Facet_iterator;

    //Facets
    Facet_iterator f = poly->facets_begin();

    for(f = poly->facets_begin();
        f != poly->facets_end();
        f++)
    {

        Halfedge_around_facet_circulator he = f->facet_begin();
        Halfedge_around_facet_circulator end = he;
        CGAL_For_all(he,end)
        {

            // If Flat shading:1 normal per polygon added once per vertex
            if (cur_shading == Flat || cur_shading == FlatPlusEdges)
            {

                Vector n = CGAL::Polygon_mesh_processing::
                  compute_face_normal(f, static_cast<Base&>(*poly));
                normals.push_back(n[0]);
                normals.push_back(n[1]);
                normals.push_back(n[2]);
            }

            // If Gouraud shading: 1 normal per vertex
            else if(cur_shading == Gouraud)
            {

                const Facet::Normal_3& n = he->vertex()->normal();
                normals.push_back(n[0]);
                normals.push_back(n[1]);
                normals.push_back(n[2]);
            }

            //position
            const Point& p = he->vertex()->point();
            positions_facets.push_back(p.x());
            positions_facets.push_back(p.y());
            positions_facets.push_back(p.z());
            positions_facets.push_back(1.0);

            const double u = he->vertex()->u();
            const double v = he->vertex()->v();
            textures_map_facets.push_back(u);
            textures_map_facets.push_back(v);
        }


    }
    //Lines
    typedef Kernel::Point_3		Point;
    typedef Base::Edge_iterator	Edge_iterator;

    Edge_iterator he;

    for(he = poly->edges_begin();
        he != poly->edges_end();
        he++)
    {

        const Point& a = he->vertex()->point();
        const Point& b = he->opposite()->vertex()->point();
        positions_lines.push_back(a.x());
        positions_lines.push_back(a.y());
        positions_lines.push_back(a.z());
        positions_lines.push_back(1.0);

        const double u = he->vertex()->u();
        const double v = he->vertex()->v();
        textures_map_lines.push_back(u);
        textures_map_lines.push_back(v);

        positions_lines.push_back(b.x());
        positions_lines.push_back(b.y());
        positions_lines.push_back(b.z());
        positions_lines.push_back(1.0);

        const double ou = he->opposite()->vertex()->u();
        const double ov = he->opposite()->vertex()->v();
        textures_map_lines.push_back(ou);
        textures_map_lines.push_back(ov);

    }

}
void subdiv_border( Polyhedron& P) {
    if ( P.size_of_facets() == 0)
        return;
    // We use that new halfedges are appended at the end.
    Edge_iterator last_e = P.edges_end();
    -- last_e;  // the last of the old edges
    Edge_iterator e = P.edges_begin(); // create trisected border edges
    do {
        if ( e->opposite()->is_border())
            trisect_border_halfedge( P, e->opposite());
        else if ( e->is_border())
            trisect_border_halfedge( P, e);
    } while ( e++ != last_e);
    e = P.edges_begin();               // smooth points on border edges
    std::vector<Point> pts;  // store new smoothed points temporarily
    do {
        if ( e->opposite()->is_border())
            smooth_border_vertices( e->opposite(), std::back_inserter(pts));
        else if ( e->is_border())
            smooth_border_vertices( e, std::back_inserter(pts));
    } while ( e++ != last_e);
    e = P.edges_begin(); // copy smoothed points back
    std::vector<Point>::iterator i = pts.begin();
    do {
        if ( e->opposite()->is_border()) {
            e->vertex()->point() = *i++;
            e->opposite()->vertex()->point() = *i++;
            e->opposite()->next()->vertex()->point() = *i++;
        } else if ( e->is_border()) {
            e->opposite()->vertex()->point() = *i++;
            e->vertex()->point() = *i++;
            e->next()->vertex()->point() = *i++;
        }
    } while ( e++ != last_e);
    CGAL_assertion( i == pts.end());
    CGAL_postcondition( P.is_valid());
}