summaryrefslogtreecommitdiff
path: root/src/import.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/import.cc')
-rw-r--r--src/import.cc223
1 files changed, 223 insertions, 0 deletions
diff --git a/src/import.cc b/src/import.cc
new file mode 100644
index 0000000..c9b1a66
--- /dev/null
+++ b/src/import.cc
@@ -0,0 +1,223 @@
+/*
+ * OpenSCAD (www.openscad.at)
+ * Copyright (C) 2009 Clifford Wolf <clifford@clifford.at>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#define INCLUDE_ABSTRACT_NODE_DETAILS
+
+#include "openscad.h"
+#include "printutils.h"
+
+#include <QFile>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+enum import_type_e {
+ TYPE_STL,
+ TYPE_OFF,
+ TYPE_DXF
+};
+
+class ImportModule : public AbstractModule
+{
+public:
+ import_type_e type;
+ ImportModule(import_type_e type) : type(type) { }
+ virtual AbstractNode *evaluate(const Context *ctx, const ModuleInstantiation *inst) const;
+};
+
+class ImportNode : public AbstractPolyNode
+{
+public:
+ import_type_e type;
+ QString filename;
+ QString layername;
+ int convexity;
+ double fn, fs, fa;
+ double origin_x, origin_y, scale;
+ ImportNode(const ModuleInstantiation *mi, import_type_e type) : AbstractPolyNode(mi), type(type) { }
+ virtual PolySet *render_polyset(render_mode_e mode) const;
+ virtual QString dump(QString indent) const;
+};
+
+AbstractNode *ImportModule::evaluate(const Context *ctx, const ModuleInstantiation *inst) const
+{
+ ImportNode *node = new ImportNode(inst, type);
+
+ QVector<QString> argnames;
+ if (type == TYPE_DXF) {
+ argnames = QVector<QString>() << "file" << "layer" << "convexity" << "origin" << "scale";
+ } else {
+ argnames = QVector<QString>() << "file" << "convexity";
+ }
+ QVector<Expression*> argexpr;
+
+ // Map old argnames to new argnames for compatibility
+ QVector<QString> inst_argnames = inst->argnames;
+ for (int i=0; i<inst_argnames.size(); i++) {
+ if (inst_argnames[i] == "filename")
+ inst_argnames[i] = "file";
+ if (inst_argnames[i] == "layername")
+ inst_argnames[i] = "layer";
+ }
+
+ Context c(ctx);
+ c.args(argnames, argexpr, inst_argnames, inst->argvalues);
+
+ node->fn = c.lookup_variable("$fn").num;
+ node->fs = c.lookup_variable("$fs").num;
+ node->fa = c.lookup_variable("$fa").num;
+
+ node->filename = c.lookup_variable("file").text;
+ node->layername = c.lookup_variable("layer", true).text;
+ node->convexity = c.lookup_variable("convexity", true).num;
+
+ if (node->convexity <= 0)
+ node->convexity = 1;
+
+ Value origin = c.lookup_variable("origin", true);
+ node->origin_x = node->origin_y = 0;
+ origin.getv2(node->origin_x, node->origin_y);
+
+ node->scale = c.lookup_variable("scale", true).num;
+
+ if (node->scale <= 0)
+ node->scale = 1;
+
+ return node;
+}
+
+void register_builtin_import()
+{
+ builtin_modules["import_stl"] = new ImportModule(TYPE_STL);
+ builtin_modules["import_off"] = new ImportModule(TYPE_OFF);
+ builtin_modules["import_dxf"] = new ImportModule(TYPE_DXF);
+}
+
+PolySet *ImportNode::render_polyset(render_mode_e) const
+{
+ PolySet *p = new PolySet();
+ p->convexity = convexity;
+
+ if (type == TYPE_STL)
+ {
+ handle_dep(filename);
+ QFile f(filename);
+ if (!f.open(QIODevice::ReadOnly)) {
+ PRINTF("WARNING: Can't open import file `%s'.", filename.toAscii().data());
+ return p;
+ }
+
+ QByteArray data = f.read(5);
+ if (data.size() == 5 && QString(data) == QString("solid"))
+ {
+ int i = 0;
+ double vdata[3][3];
+ QRegExp splitre = QRegExp("\\s*(vertex)?\\s+");
+ f.readLine();
+ while (!f.atEnd())
+ {
+ QString line = QString(f.readLine()).remove("\n").remove("\r");
+ if (line.contains("solid") || line.contains("facet") || line.contains("endloop"))
+ continue;
+ if (line.contains("outer loop")) {
+ i = 0;
+ continue;
+ }
+ if (line.contains("vertex")) {
+ QStringList tokens = line.split(splitre);
+ bool ok[3] = { false, false, false };
+ if (tokens.size() == 4) {
+ vdata[i][0] = tokens[1].toDouble(&ok[0]);
+ vdata[i][1] = tokens[2].toDouble(&ok[1]);
+ vdata[i][2] = tokens[3].toDouble(&ok[2]);
+ }
+ if (!ok[0] || !ok[1] || !ok[2]) {
+ PRINTF("WARNING: Can't parse vertex line `%s'.", line.toAscii().data());
+ i = 10;
+ } else if (++i == 3) {
+ p->append_poly();
+ p->append_vertex(vdata[0][0], vdata[0][1], vdata[0][2]);
+ p->append_vertex(vdata[1][0], vdata[1][1], vdata[1][2]);
+ p->append_vertex(vdata[2][0], vdata[2][1], vdata[2][2]);
+ }
+ }
+ }
+ }
+ else
+ {
+ f.read(80-5+4);
+ while (1) {
+ struct {
+ float i, j, k;
+ float x1, y1, z1;
+ float x2, y2, z2;
+ float x3, y3, z3;
+ unsigned short acount;
+ } __attribute__ ((packed)) data;
+ if (f.read((char*)&data, sizeof(data)) != sizeof(data))
+ break;
+ p->append_poly();
+ p->append_vertex(data.x1, data.y1, data.z1);
+ p->append_vertex(data.x2, data.y2, data.z2);
+ p->append_vertex(data.x3, data.y3, data.z3);
+ }
+ }
+ }
+
+ if (type == TYPE_OFF)
+ {
+ PRINTF("WARNING: OFF import is not implemented yet.");
+ }
+
+ if (type == TYPE_DXF)
+ {
+ DxfData dd(fn, fs, fa, filename, layername, origin_x, origin_y, scale);
+ p->is2d = true;
+ dxf_tesselate(p, &dd, 0, true, false, 0);
+ dxf_border_to_ps(p, &dd);
+ }
+
+ return p;
+}
+
+QString ImportNode::dump(QString indent) const
+{
+ if (dump_cache.isEmpty()) {
+ QString text;
+ struct stat st;
+ memset(&st, 0, sizeof(struct stat));
+ stat(filename.toAscii().data(), &st);
+ if (type == TYPE_STL)
+ text.sprintf("import_stl(file = \"%s\", cache = \"%x.%x\", convexity = %d);\n",
+ filename.toAscii().data(), (int)st.st_mtime, (int)st.st_size, convexity);
+ if (type == TYPE_OFF)
+ text.sprintf("import_off(file = \"%s\", cache = \"%x.%x\", convexity = %d);\n",
+ filename.toAscii().data(), (int)st.st_mtime, (int)st.st_size, convexity);
+ if (type == TYPE_DXF)
+ text.sprintf("import_dxf(file = \"%s\", cache = \"%x.%x\", layer = \"%s\", "
+ "origin = [ %g %g ], scale = %g, convexity = %d, "
+ "$fn = %g, $fa = %g, $fs = %g);\n",
+ filename.toAscii().data(), (int)st.st_mtime, (int)st.st_size,
+ layername.toAscii().data(), origin_x, origin_y, scale, convexity,
+ fn, fs, fa);
+ ((AbstractNode*)this)->dump_cache = indent + QString("n%1: ").arg(idx) + text;
+ }
+ return dump_cache;
+}
+
contact: Jan Huwald // Impressum