From 6a12327e2a07440dc9f2204a37abdbc10d8a5236 Mon Sep 17 00:00:00 2001 From: clifford Date: Wed, 14 Oct 2009 12:34:50 +0000 Subject: [PATCH] Clifford Wolf: Added support for ASCII stl files git-svn-id: http://svn.clifford.at/openscad/trunk@102 b57f626f-c46c-0410-a088-ec61d464b74c --- import.cc | 139 +++++++++++++++++++++++++++++++++++++++++++++++++++ module.cc | 1 + openscad.h | 1 + openscad.pro | 2 +- 4 files changed, 142 insertions(+), 1 deletion(-) create mode 100644 import.cc diff --git a/import.cc b/import.cc new file mode 100644 index 00000000..c3af27e5 --- /dev/null +++ b/import.cc @@ -0,0 +1,139 @@ +/* + * OpenSCAD (www.openscad.at) + * Copyright (C) 2009 Clifford Wolf + * + * 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 + +enum import_type_e { + TYPE_STL, + TYPE_OFF +}; + +class ImportModule : public AbstractModule +{ +public: + import_type_e type; + ImportModule(import_type_e type) : type(type) { } + virtual AbstractNode *evaluate(const Context *ctx, const ModuleInstanciation *inst) const; +}; + +class ImportNode : public AbstractPolyNode +{ +public: + import_type_e type; + QString filename; + int convexity; + ImportNode(const ModuleInstanciation *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 ModuleInstanciation *inst) const +{ + ImportNode *node = new ImportNode(inst, type); + + QVector argnames = QVector() << "filename" << "convexity"; + QVector argexpr; + + Context c(ctx); + c.args(argnames, argexpr, inst->argnames, inst->argvalues); + + node->filename = c.lookup_variable("filename").text; + node->convexity = c.lookup_variable("convexity").num; + + return node; +} + +void register_builtin_import() +{ + builtin_modules["import_stl"] = new ImportModule(TYPE_STL); + builtin_modules["import_off"] = new ImportModule(TYPE_OFF); +} + +PolySet *ImportNode::render_polyset(render_mode_e) const +{ + PolySet *p = new PolySet(); + p->convexity = convexity; + + QFile f(filename); + if (!f.open(QIODevice::ReadOnly | QIODevice::Text)) { + PRINTF("WARNING: Can't open import file `%s'.", filename.toAscii().data()); + return p; + } + + if (type == TYPE_STL) + { + int i = 0; + double vdata[3][3]; + QRegExp splitre = QRegExp("\\s*(vertex)?\\s+"); + while (!f.atEnd()) + { + QString line = QString(f.readLine()).remove("\n"); + 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]); + } + } + } + } + + if (type == TYPE_OFF) + { + PRINTF("WARNING: OFF import is not implemented yet."); + } + + return p; +} + +QString ImportNode::dump(QString indent) const +{ + if (dump_cache.isEmpty()) { + QString text; + if (type == TYPE_STL) + text.sprintf("import_stl(filename = \"%s\");\n", filename.toAscii().data()); + if (type == TYPE_OFF) + text.sprintf("import_off(filename = \"%s\");\n", filename.toAscii().data()); + ((AbstractNode*)this)->dump_cache = indent + QString("n%1: ").arg(idx) + text; + } + return dump_cache; +} + diff --git a/module.cc b/module.cc index db7592c7..4e18c4a2 100644 --- a/module.cc +++ b/module.cc @@ -192,6 +192,7 @@ void initialize_builtin_modules() register_builtin_surface(); register_builtin_control(); register_builtin_render(); + register_builtin_import(); register_builtin_dxf_linear_extrude(); register_builtin_dxf_rotate_extrude(); } diff --git a/openscad.h b/openscad.h index 9539e044..0f565c92 100644 --- a/openscad.h +++ b/openscad.h @@ -386,6 +386,7 @@ extern void register_builtin_primitives(); extern void register_builtin_surface(); extern void register_builtin_control(); extern void register_builtin_render(); +extern void register_builtin_import(); extern void register_builtin_dxf_linear_extrude(); extern void register_builtin_dxf_rotate_extrude(); diff --git a/openscad.pro b/openscad.pro index 44e7a7ec..1b7377b6 100644 --- a/openscad.pro +++ b/openscad.pro @@ -16,7 +16,7 @@ SOURCES += openscad.cc mainwin.cc glview.cc SOURCES += value.cc expr.cc func.cc module.cc context.cc SOURCES += csgterm.cc polyset.cc csgops.cc transform.cc SOURCES += primitives.cc surface.cc control.cc render.cc -SOURCES += dxfdata.cc dxftess.cc dxfdim.cc +SOURCES += import.cc dxfdata.cc dxftess.cc dxfdim.cc SOURCES += dxflinextrude.cc dxfrotextrude.cc QMAKE_CXXFLAGS += -O0