Example #1
0
/*
 * Converts all segments in all paths to Geom::LineSegment or Geom::HLineSegment or
 * Geom::VLineSegment or Geom::CubicBezier.
 */
Geom::PathVector
pathv_to_linear_and_cubic_beziers( Geom::PathVector const &pathv )
{
    Geom::PathVector output;

    for (Geom::PathVector::const_iterator pit = pathv.begin(); pit != pathv.end(); ++pit) {
        output.push_back( Geom::Path() );
        output.back().start( pit->initialPoint() );
        output.back().close( pit->closed() );

        for (Geom::Path::const_iterator cit = pit->begin(); cit != pit->end_open(); ++cit) {
            if (is_straight_curve(*cit)) {
                Geom::LineSegment l(cit->initialPoint(), cit->finalPoint());
                output.back().append(l);
            } else {
                Geom::BezierCurve const *curve = dynamic_cast<Geom::BezierCurve const *>(&*cit);
                if (curve && curve->order() == 3) {
                    Geom::CubicBezier b((*curve)[0], (*curve)[1], (*curve)[2], (*curve)[3]);
                    output.back().append(b);
                } else {
                    // convert all other curve types to cubicbeziers
                    Geom::Path cubicbezier_path = Geom::cubicbezierpath_from_sbasis(cit->toSBasis(), 0.1);
                    output.back().append(cubicbezier_path);
                }
            }
        }
    }
    
    return output;
}
Example #2
0
static void
sp_path_convert_to_guides(SPItem *item)
{
    SPPath *path = SP_PATH(item);

    if (!path->_curve) {
        return;
    }

    std::list<std::pair<Geom::Point, Geom::Point> > pts;

    Geom::Affine const i2dt(path->i2dt_affine());

    Geom::PathVector const & pv = path->_curve->get_pathvector();
    for(Geom::PathVector::const_iterator pit = pv.begin(); pit != pv.end(); ++pit) {
        for(Geom::Path::const_iterator cit = pit->begin(); cit != pit->end_default(); ++cit) {
            // only add curves for straight line segments
            if( is_straight_curve(*cit) )
            {
                pts.push_back(std::make_pair(cit->initialPoint() * i2dt, cit->finalPoint() * i2dt));
            }
        }
    }

    sp_guide_pt_pairs_to_guides(item->document, pts);
}
Example #3
0
/*
 * sp_svg_write_polygon: Write points attribute for polygon tag.
 * pathv may only contain paths with only straight line segments
 * Return value: points attribute string.
 */
static gchar *sp_svg_write_polygon(Geom::PathVector const & pathv)
{
    Inkscape::SVGOStringStream os;

    for (Geom::PathVector::const_iterator pit = pathv.begin(); pit != pathv.end(); ++pit) {
        for (Geom::Path::const_iterator cit = pit->begin(); cit != pit->end_default(); ++cit) {
            if ( is_straight_curve(*cit) )
            {
                os << cit->finalPoint()[0] << "," << cit->finalPoint()[1] << " ";
            } else {
                g_error("sp_svg_write_polygon: polygon path contains non-straight line segments");
            }
        }
    }

    return g_strdup(os.str().c_str());
}
Example #4
0
/*
 * Converts all segments in all paths to Geom::LineSegment.  There is an intermediate
 * stage where some may be converted to beziers.  maxdisp is the maximum displacement from
 * the line segment to the bezier curve; ** maxdisp is not used at this moment **.
 *
 * This is NOT a terribly fast method, but it should give a solution close to the one with the
 * fewest points.
 */
Geom::PathVector
pathv_to_linear( Geom::PathVector const &pathv, double /*maxdisp*/)
{
    Geom::PathVector output;
    Geom::PathVector tmppath = pathv_to_linear_and_cubic_beziers(pathv);
    
    // Now all path segments are either already lines, or they are beziers.

    for (Geom::PathVector::const_iterator pit = tmppath.begin(); pit != tmppath.end(); ++pit) {
        output.push_back( Geom::Path() );
        output.back().start( pit->initialPoint() );
        output.back().close( pit->closed() );

        for (Geom::Path::const_iterator cit = pit->begin(); cit != pit->end_open(); ++cit) {
            if (is_straight_curve(*cit)) {
                Geom::LineSegment ls(cit->initialPoint(), cit->finalPoint());
                output.back().append(ls);
            } 
            else { /* all others must be Bezier curves */
                Geom::BezierCurve const *curve = dynamic_cast<Geom::BezierCurve const *>(&*cit);
                Geom::CubicBezier b((*curve)[0], (*curve)[1], (*curve)[2], (*curve)[3]);
                std::vector<Geom::Point> bzrpoints = b.points();
                Geom::Point A = bzrpoints[0];
                Geom::Point B = bzrpoints[1];
                Geom::Point C = bzrpoints[2];
                Geom::Point D = bzrpoints[3];
                std::vector<Geom::Point> pointlist;
                pointlist.push_back(A);
                recursive_bezier4(
                   A[X], A[Y], 
                   B[X], B[Y], 
                   C[X], C[Y], 
                   D[X], D[Y],
                   pointlist, 
                   0);
                pointlist.push_back(D);
                Geom::Point r1 = pointlist[0];
                for (unsigned int i=1; i<pointlist.size();i++){
                   Geom::Point prev_r1 = r1;
                   r1 = pointlist[i];
                   Geom::LineSegment ls(prev_r1, r1);
                   output.back().append(ls);
                }
                pointlist.clear();
           }
        }
    }
    
    return output;
}
static std::vector<Geom::Point> approxCurveWithPoints(SPCurve *curve)
{
    // The number of segments to use for not straight curves approximation
    const unsigned NUM_SEGS = 4;
    
    const Geom::PathVector& curve_pv = curve->get_pathvector();
   
    // The structure to hold the output
    std::vector<Geom::Point> poly_points;

    // Iterate over all curves, adding the endpoints for linear curves and
    // sampling the other curves
    double seg_size = 1.0 / NUM_SEGS;
    double at;
    at = 0;
    Geom::PathVector::const_iterator pit = curve_pv.begin();
    while (pit != curve_pv.end())
    {
        Geom::Path::const_iterator cit = pit->begin();
        while (cit != pit->end())
        {
            if (cit == pit->begin())
            {
                poly_points.push_back(cit->initialPoint());
            }

            if (dynamic_cast<Geom::CubicBezier const*>(&*cit))
            {
                at += seg_size;
                if (at <= 1.0 )
                    poly_points.push_back(cit->pointAt(at));
                else
                {
                    at = 0.0;
                    ++cit;
                }
            }
            else
            {
                poly_points.push_back(cit->finalPoint());
                ++cit;
            }
        }
        ++pit;
    }
    return poly_points;
}