Пример #1
0
void LC_MakerCamSVG::writePolyline(RS_Polyline* polyline) {

    RS_DEBUG->print("RS_MakerCamSVG::writePolyline: Writing polyline ...");

    std::string path = svgPathMoveTo(convertToSvg(polyline->getStartpoint()));

	for(auto entity: *polyline){

        if (!entity->isAtomic()) {
            continue;
        }

        if (entity->rtti() == RS2::EntityArc) {

            path += svgPathArc((RS_Arc*)entity);
        }
        else {

            path += svgPathLineTo(convertToSvg(entity->getEndpoint()));
        }
    }

    if (polyline->isClosed()) {

        path += svgPathClose();
    }

    xmlWriter->addElement("path", NAMESPACE_URI_SVG);

    xmlWriter->addAttribute("d", path);

    xmlWriter->closeElement();
}
Пример #2
0
void LC_MakerCamSVG::writeLine(RS_Line* line) {

    RS_DEBUG->print("RS_MakerCamSVG::writeLine: Writing line ...");

    RS_Vector startpoint = convertToSvg(line->getStartpoint());
    RS_Vector endpoint = convertToSvg(line->getEndpoint());

    xmlWriter->addElement("line", NAMESPACE_URI_SVG);

    xmlWriter->addAttribute("x1", numXml(startpoint.x));
    xmlWriter->addAttribute("y1", numXml(startpoint.y));
    xmlWriter->addAttribute("x2", numXml(endpoint.x));
    xmlWriter->addAttribute("y2", numXml(endpoint.y));

    xmlWriter->closeElement();
}
Пример #3
0
void LC_MakerCamSVG::writeInsert(RS_Insert* insert) {

    RS_Block* block = insert->getBlockForInsert();

    RS_Vector insertionpoint = convertToSvg(insert->getInsertionPoint());

    if (writeBlocksInline) {

        RS_DEBUG->print("RS_MakerCamSVG::writeInsert: Writing insert inline ...");

        offset.set(insertionpoint.x, insertionpoint.y - (max.y - min.y));

        xmlWriter->addElement("g", NAMESPACE_URI_SVG);

        xmlWriter->addAttribute("blockname", qPrintable(block->getName()), NAMESPACE_URI_LC);

        writeLayers(block);

        xmlWriter->closeElement();

        offset.set(0, 0);
    }
    else {

        RS_DEBUG->print("RS_MakerCamSVG::writeInsert: Writing insert as reference to block ...");

        xmlWriter->addElement("use", NAMESPACE_URI_SVG);

        xmlWriter->addAttribute("x", numXml(insertionpoint.x));
        xmlWriter->addAttribute("y", numXml(insertionpoint.y - (max.y - min.y)));
        xmlWriter->addAttribute("href", "#" + std::to_string(block->getId()), NAMESPACE_URI_XLINK);

        xmlWriter->closeElement();
    }
}
Пример #4
0
void LC_MakerCamSVG::writeQuadraticBeziers(const std::vector<RS_Vector> &control_points, bool is_closed) {

    std::vector<RS_Vector> bezier_points = calcQuadraticBezierPoints(control_points, is_closed);

    std::string path = svgPathMoveTo(convertToSvg(bezier_points[0]));

    int bezier_points_size = bezier_points.size();

    int bezier_count = ((bezier_points_size - 1) / 2);

    for (int i = 0; i < bezier_count; i++) {
        path += svgPathQuadraticCurveTo(convertToSvg(bezier_points[2 * (i + 1)]), convertToSvg(bezier_points[2 * (i + 1) - 1]));
    }

    xmlWriter->addElement("path", NAMESPACE_URI_SVG);

    xmlWriter->addAttribute("d", path);

    xmlWriter->closeElement();
}
Пример #5
0
void LC_MakerCamSVG::writeArc(RS_Arc* arc) {

    RS_DEBUG->print("RS_MakerCamSVG::writeArc: Writing arc ...");

    std::string path = svgPathMoveTo(convertToSvg(arc->getStartpoint())) +
                       svgPathArc(arc);

    xmlWriter->addElement("path", NAMESPACE_URI_SVG);

    xmlWriter->addAttribute("d", path);

    xmlWriter->closeElement();
}
Пример #6
0
void LC_MakerCamSVG::writeCircle(RS_Circle* circle) {

    RS_DEBUG->print("RS_MakerCamSVG::writeCircle: Writing circle ...");

    RS_Vector center = convertToSvg(circle->getCenter());

    xmlWriter->addElement("circle", NAMESPACE_URI_SVG);

    xmlWriter->addAttribute("cx", numXml(center.x));
    xmlWriter->addAttribute("cy", numXml(center.y));
    xmlWriter->addAttribute("r", numXml(circle->getRadius()));

    xmlWriter->closeElement();
}
Пример #7
0
void LC_MakerCamSVG::writePoint(RS_Point* point) {

    RS_DEBUG->print("RS_MakerCamSVG::writePoint: Writing point ...");

    // NOTE: There is no "point" element in SVG, therefore creating a circle
    //       with minimal radius.

    RS_Vector center = convertToSvg(point->getPos());

    xmlWriter->addElement("circle", NAMESPACE_URI_SVG);

    xmlWriter->addAttribute("cx", numXml(center.x));
    xmlWriter->addAttribute("cy", numXml(center.y));
    xmlWriter->addAttribute("r", numXml(0.1));

    xmlWriter->closeElement();
}
Пример #8
0
std::string LC_MakerCamSVG::svgPathArc(RS_Arc* arc) {

    RS_Vector endpoint = convertToSvg(arc->getEndpoint());
    double radius = arc->getRadius();

    double startangle = RS_Math::rad2deg(arc->getAngle1());
    double endangle = RS_Math::rad2deg(arc->getAngle2());


    if (endangle <= startangle) {
        endangle += 360;
    }

    bool large_arc_flag = ((endangle - startangle) > 180);
    bool sweep_flag = false;

    if (arc->isReversed())
    {
        large_arc_flag = !large_arc_flag;
        sweep_flag = !sweep_flag;
    }

    return svgPathArc(endpoint, radius, radius, 0.0, large_arc_flag, sweep_flag);
}
Пример #9
0
void LC_MakerCamSVG::writeEllipse(RS_Ellipse* ellipse) {

    RS_Vector center = convertToSvg(ellipse->getCenter());
	const RS_Vector centerTranslation=center - ellipse->getCenter();

    double majorradius = ellipse->getMajorRadius();
    double minorradius = ellipse->getMinorRadius();

    if (convertEllipsesToBeziers) {

        std::string path = "";

        if (ellipse->isArc()) {

            const int segments = 4;

            RS_DEBUG->print("RS_MakerCamSVG::writeEllipse: Writing ellipse arc approximated by 'path' with %d cubic bézier segments (as discussed in https://www.spaceroots.org/documents/ellipse/elliptical-arc.pdf) ...", segments);

            double x_axis_rotation = 2 * M_PI - ellipse->getAngle();

            double start_angle = 2 * M_PI - ellipse->getAngle2();
            double end_angle = 2 * M_PI - ellipse->getAngle1();

            if (ellipse->isReversed()) {
                double temp_angle = start_angle;
                start_angle = end_angle;
                end_angle = temp_angle;
            }

            if (end_angle <= start_angle) {
                end_angle += 2 * M_PI;
            }

            double total_angle = end_angle - start_angle;

            double alpha = calcAlpha(total_angle / segments);

			RS_Vector start_point = centerTranslation + ellipse->getEllipsePoint(start_angle);

            path = svgPathMoveTo(start_point);

            for (int i = 1; i <= segments; i++) {
                double segment_start_angle = start_angle + ((i - 1) / (double)segments) * total_angle;
                double segment_end_angle = start_angle + (i / (double)segments) * total_angle;

				RS_Vector segment_start_point = centerTranslation + ellipse->getEllipsePoint(segment_start_angle);
				RS_Vector segment_end_point = centerTranslation + ellipse->getEllipsePoint(segment_end_angle);

                RS_Vector segment_control_point_1 = segment_start_point + calcEllipsePointDerivative(majorradius, minorradius, x_axis_rotation, segment_start_angle) * alpha;
                RS_Vector segment_control_point_2 = segment_end_point - calcEllipsePointDerivative(majorradius, minorradius, x_axis_rotation, segment_end_angle) * alpha;

                path += svgPathCurveTo(segment_end_point, segment_control_point_1, segment_control_point_2);
            }
        }
        else {

            RS_DEBUG->print("RS_MakerCamSVG::writeEllipse: Writing ellipse approximated by 'path' with 4 cubic bézier segments (as discussed in http://www.tinaja.com/glib/ellipse4.pdf) ...");

            const double kappa = 0.551784;

            RS_Vector major {majorradius, 0.0};
            RS_Vector minor {0.0, minorradius};

            RS_Vector flip_y {1.0, -1.0};

            major.rotate(ellipse->getAngle());
            minor.rotate(ellipse->getAngle());

            major.scale(flip_y);
            minor.scale(flip_y);

            RS_Vector offsetmajor {major * kappa};
            RS_Vector offsetminor {minor * kappa};

            path = svgPathMoveTo(center - major) +
                   svgPathCurveTo((center - minor), (center - major - offsetminor), (center - minor - offsetmajor)) +
                   svgPathCurveTo((center + major), (center - minor + offsetmajor), (center + major - offsetminor)) +
                   svgPathCurveTo((center + minor), (center + major + offsetminor), (center + minor + offsetmajor)) +
                   svgPathCurveTo((center - major), (center + minor - offsetmajor), (center - major + offsetminor)) +
                   svgPathClose();
        }

        xmlWriter->addElement("path", NAMESPACE_URI_SVG);

        xmlWriter->addAttribute("d", path);

        xmlWriter->closeElement();
    }
    else {

        if (ellipse->isArc()) {

            RS_DEBUG->print("RS_MakerCamSVG::writeEllipse: Writing ellipse arc as 'path' with arc segments ...");

            double x_axis_rotation = 180 - (RS_Math::rad2deg(ellipse->getAngle()));

            double startangle = RS_Math::rad2deg(ellipse->getAngle1());
            double endangle = RS_Math::rad2deg(ellipse->getAngle2());

            if (endangle <= startangle) {
                endangle += 360;
            }

            bool large_arc_flag = ((endangle - startangle) > 180);
            bool sweep_flag = false;

            if (ellipse->isReversed()) {
                large_arc_flag = !large_arc_flag;
                sweep_flag = !sweep_flag;
            }

            std::string path = svgPathMoveTo(convertToSvg(ellipse->getStartpoint())) +
                               svgPathArc(convertToSvg(ellipse->getEndpoint()), majorradius, minorradius, x_axis_rotation, large_arc_flag, sweep_flag);

            xmlWriter->addElement("path", NAMESPACE_URI_SVG);

            xmlWriter->addAttribute("d", path);

            xmlWriter->closeElement();
        }
        else {

            RS_DEBUG->print("RS_MakerCamSVG::writeEllipse: Writing full ellipse as 'ellipse' ...");

            double angle = 180 - (RS_Math::rad2deg(ellipse->getAngle()) - 90);

            std::string transform = "translate(" + numXml(center.x) + ", " + numXml(center.y) + ") " +
                                    "rotate(" + numXml(angle) + ")";

            xmlWriter->addElement("ellipse", NAMESPACE_URI_SVG);

            xmlWriter->addAttribute("rx", numXml(minorradius));
            xmlWriter->addAttribute("ry", numXml(majorradius));
            xmlWriter->addAttribute("transform", transform);

            xmlWriter->closeElement();
        }
    }
}