Skip to content

Commit

Permalink
Added experimental SVG import
Browse files Browse the repository at this point in the history
  • Loading branch information
kintel committed Jul 19, 2016
1 parent fdd4209 commit bd20fe6
Show file tree
Hide file tree
Showing 38 changed files with 2,329 additions and 6 deletions.
10 changes: 10 additions & 0 deletions Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,16 @@
<key>CFBundleTypeRole</key>
<string>Viewer</string>
</dict>
<dict>
<key>CFBundleTypeExtensions</key>
<array>
<string>svg</string>
</array>
<key>CFBundleTypeName</key>
<string>SVG file</string>
<key>CFBundleTypeRole</key>
<string>Viewer</string>
</dict>
</array>
<key>NSAppleScriptEnabled</key>
<true/>
Expand Down
1 change: 1 addition & 0 deletions common.pri
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ include(eigen.pri)
include(boost.pri)
include(glib-2.0.pri)
include(gettext.pri)
include(libxml2.pri)
include(sparkle.pri)
include(harfbuzz.pri)
include(freetype.pri)
Expand Down
35 changes: 35 additions & 0 deletions libxml2.pri
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# Detect libxml2, then use this priority list to determine
# which library to use:
#
# Priority
# 1. LIBXML2_INCLUDEPATH / LIBXML2_LIBPATH (qmake parameter, not checked it given on commandline)
# 2. OPENSCAD_LIBRARIES (environment variable)
# 3. system's standard include paths from pkg-config

libxml2 {
# read environment variables
OPENSCAD_LIBRARIES_DIR = $$(OPENSCAD_LIBRARIES)
LIBXML2_DIR = $$(LIBXML2DIR)

!isEmpty(OPENSCAD_LIBRARIES_DIR) {
isEmpty(LIBXML2_INCLUDEPATH) {
LIBXML2_INCLUDEPATH = $$OPENSCAD_LIBRARIES_DIR/include/libxml2
LIBXML2_LIBPATH = $$OPENSCAD_LIBRARIES_DIR/lib
}
}

isEmpty(LIBXML2_INCLUDEPATH) {
LIBXML2_CFLAGS = $$system("pkg-config --cflags libxml-2.0")
} else {
LIBXML2_CFLAGS = -I$$LIBXML2_INCLUDEPATH
}

isEmpty(LIBXML2_LIBPATH) {
LIBXML2_LIBS = $$system("pkg-config --libs libxml-2.0")
} else {
LIBXML2_LIBS = -L$$LIBXML2_LIBPATH -lxml2
}

QMAKE_CXXFLAGS += $$LIBXML2_CFLAGS
LIBS += $$LIBXML2_LIBS
}
19 changes: 18 additions & 1 deletion openscad.pro
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,7 @@ CONFIG += harfbuzz
CONFIG += freetype
CONFIG += fontconfig
CONFIG += gettext
CONFIG += libxml2

#Uncomment the following line to enable the QScintilla editor
!nogui {
Expand Down Expand Up @@ -351,7 +352,22 @@ HEADERS += src/version_check.h \
src/legacyeditor.h \
src/LibraryInfoDialog.h

SOURCES += src/version_check.cc \
SOURCES += \
src/libsvg/libsvg.cc \
src/libsvg/circle.cc \
src/libsvg/ellipse.cc \
src/libsvg/line.cc \
src/libsvg/polygon.cc \
src/libsvg/polyline.cc \
src/libsvg/rect.cc \
src/libsvg/group.cc \
src/libsvg/svgpage.cc \
src/libsvg/path.cc \
src/libsvg/shape.cc \
src/libsvg/transformation.cc \
src/libsvg/util.cc \
\
src/version_check.cc \
src/ProgressWidget.cc \
src/linalg.cc \
src/Camera.cc \
Expand Down Expand Up @@ -436,6 +452,7 @@ SOURCES += src/version_check.cc \
src/import.cc \
src/import_stl.cc \
src/import_off.cc \
src/import_svg.cc \
src/renderer.cc \
src/colormap.cc \
src/ThrownTogetherRenderer.cc \
Expand Down
1 change: 1 addition & 0 deletions src/feature.cc
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ Feature::list_t Feature::feature_list;
const Feature Feature::ExperimentalEachExpression("lc-each", "Enable <code>each</code> expression in list comprehensions.");
const Feature Feature::ExperimentalElseExpression("lc-else", "Enable <code>else</code> expression in list comprehensions.");
const Feature Feature::ExperimentalForCExpression("lc-for-c", "Enable C-style <code>for</code> expression in list comprehensions.");
const Feature Feature::ExperimentalSvgImport("svg-import", "Enable SVG import.");

Feature::Feature(const std::string &name, const std::string &description)
: enabled(false), name(name), description(description)
Expand Down
1 change: 1 addition & 0 deletions src/feature.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ class Feature
static const Feature ExperimentalEachExpression;
static const Feature ExperimentalElseExpression;
static const Feature ExperimentalForCExpression;
static const Feature ExperimentalSvgImport;

const std::string& get_name() const;
const std::string& get_description() const;
Expand Down
13 changes: 12 additions & 1 deletion src/import.cc
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@
*
*/

#include "importnode.h"
#include "import.h"
#include "importnode.h"

#include "module.h"
#include "ModuleInstantiation.h"
Expand All @@ -36,6 +36,7 @@
#include "dxfdata.h"
#include "printutils.h"
#include "fileutils.h"
#include "feature.h"

#include <sys/types.h>
#include <sstream>
Expand Down Expand Up @@ -98,6 +99,7 @@ AbstractNode *ImportModule::instantiate(const Context *ctx, const ModuleInstanti
if (ext == ".stl") actualtype = TYPE_STL;
else if (ext == ".off") actualtype = TYPE_OFF;
else if (ext == ".dxf") actualtype = TYPE_DXF;
else if (Feature::ExperimentalSvgImport.is_enabled() && ext == ".svg") actualtype = TYPE_SVG;
}

ImportNode *node = new ImportNode(inst, actualtype);
Expand Down Expand Up @@ -127,6 +129,11 @@ AbstractNode *ImportModule::instantiate(const Context *ctx, const ModuleInstanti

if (node->scale <= 0) node->scale = 1;

ValuePtr width = c.lookup_variable("width", true);
ValuePtr height = c.lookup_variable("height", true);
node->width = (width->type() == Value::NUMBER) ? width->toDouble() : -1;
node->height = (height->type() == Value::NUMBER) ? height->toDouble() : -1;

return node;
}

Expand All @@ -148,6 +155,10 @@ const Geometry *ImportNode::createGeometry() const
g = p;
break;
}
case TYPE_SVG: {
g = import_svg(this->filename);
break;
}
case TYPE_DXF: {
DxfData dd(this->fn, this->fs, this->fa, this->filename, this->layername, this->origin_x, this->origin_y, this->scale);
g = dd.toPolygon2d();
Expand Down
2 changes: 1 addition & 1 deletion src/import.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,4 @@

class PolySet *import_stl(const std::string &filename);
PolySet *import_off(const std::string &filename);
const class Polygon2d &import_dxf(const std::string &filename);
class Polygon2d *import_svg(const std::string &filename);
62 changes: 62 additions & 0 deletions src/import_svg.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
#include "import.h"
#include "Polygon2d.h"
#include "printutils.h"
#include "libsvg/libsvg.h"
#include "clipper-utils.h"

Polygon2d *import_svg(const std::string &filename)
{
libsvg::shapes_list_t *shapes = libsvg::libsvg_read_file(filename.c_str());
double x_min = 1.0/0.0;
double x_max = -1.0/0.0;
double y_min = 1.0/0.0;
double y_max = -1.0/0.0;
for (libsvg::shapes_list_t::iterator it = shapes->begin();it != shapes->end();it++) {
PRINTD("SVG shape");
libsvg::shape *s = (*it);
for (libsvg::path_list_t::iterator it = s->get_path_list().begin();it != s->get_path_list().end();it++) {
PRINTD("SVG path");
libsvg::path_t& p = *it;
for (libsvg::path_t::iterator it2 = p.begin();it2 != p.end();it2++) {
Eigen::Vector3d& v = *it2;
if (v.x() < x_min) {
x_min = v.x();
}
if (v.x() > x_max) {
x_max = v.x();
}
if (v.y() < y_min) {
y_min = v.y();
}
if (v.y() > y_max) {
y_max = v.y();
}
}
}
}

double cx = (x_min + x_max) / 2;
double cy = (y_min + y_max) / 2;

std::vector<const Polygon2d*> polygons;
for (libsvg::shapes_list_t::iterator it = shapes->begin();it != shapes->end();it++) {
Polygon2d *poly = new Polygon2d();
libsvg::shape *s = (*it);
for (libsvg::path_list_t::iterator it = s->get_path_list().begin();it != s->get_path_list().end();it++) {
libsvg::path_t& p = *it;

Outline2d outline;
for (libsvg::path_t::iterator it2 = p.begin();it2 != p.end();it2++) {
Eigen::Vector3d& v = *it2;
double x = v.x() - cx;
double y = -v.y() + cy;
outline.vertices.push_back(Vector2d(x, y));
outline.positive=true;
}
poly->addOutline(outline);
}
polygons.push_back(poly);
}
return ClipperUtils::apply(polygons, ClipperLib::ctUnion);
}

2 changes: 2 additions & 0 deletions src/importnode.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ enum import_type_e {
TYPE_UNKNOWN,
TYPE_STL,
TYPE_OFF,
TYPE_SVG,
TYPE_DXF
};

Expand All @@ -24,5 +25,6 @@ class ImportNode : public LeafNode
int convexity;
double fn, fs, fa;
double origin_x, origin_y, scale;
double width, height;
virtual const class Geometry *createGeometry() const;
};
43 changes: 43 additions & 0 deletions src/libsvg/circle.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
#include "circle.h"

namespace libsvg {

const std::string circle::name("circle");

circle::circle()
{
}

circle::circle(const circle& orig) : shape(orig)
{
r = orig.r;
}

circle::~circle()
{
}

void
circle::set_attrs(attr_map_t& attrs)
{
shape::set_attrs(attrs);
this->x = parse_double(attrs["cx"]);
this->y = parse_double(attrs["cy"]);
this->r = parse_double(attrs["r"]);

path_t path;
draw_ellipse(path, get_x(), get_y(), get_radius(), get_radius());
path_list.push_back(path);
}

void
circle::dump()
{
std::cout << get_name()
<< ": x = " << this->x
<< ": y = " << this->y
<< ": r = " << this->r
<< std::endl;
}

}
29 changes: 29 additions & 0 deletions src/libsvg/circle.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
#ifndef LIBSVG_CIRCLE_H
#define LIBSVG_CIRCLE_H

#include "shape.h"

namespace libsvg {

class circle : public shape {
protected:
double r;

public:
circle();
circle(const circle& orig);
virtual ~circle();

virtual double get_radius() { return r; }

virtual void set_attrs(attr_map_t& attrs);
virtual void dump();
const std::string& get_name() const { return circle::name; };

static const std::string name;
};

}

#endif /* LIBSVG_CIRCLE_H */

49 changes: 49 additions & 0 deletions src/libsvg/ellipse.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
#include <stdlib.h>
#include <iostream>

#include "ellipse.h"

namespace libsvg {

const std::string ellipse::name("ellipse");

ellipse::ellipse()
{
}

ellipse::ellipse(const ellipse& orig) : shape(orig)
{
rx = orig.rx;
ry = orig.ry;
}

ellipse::~ellipse()
{
}

void
ellipse::set_attrs(attr_map_t& attrs)
{
shape::set_attrs(attrs);
this->x = parse_double(attrs["cx"]);
this->y = parse_double(attrs["cy"]);
this->rx = parse_double(attrs["rx"]);
this->ry = parse_double(attrs["ry"]);

path_t path;
draw_ellipse(path, get_x(), get_y(), get_radius_x(), get_radius_y());
path_list.push_back(path);
}

void
ellipse::dump()
{
std::cout << get_name()
<< ": x = " << this->x
<< ": y = " << this->y
<< ": rx = " << this->rx
<< ": ry = " << this->ry
<< std::endl;
}

}
Loading

0 comments on commit bd20fe6

Please sign in to comment.