From 20be3da09a186272aa36719c3bcd8fa324fecd86 Mon Sep 17 00:00:00 2001 From: luboslenco Date: Thu, 22 Aug 2019 17:17:35 +0200 Subject: [PATCH] Import stl --- Sources/arm/Context.hx | 2 +- Sources/arm/format/StlParser.hx | 65 +++++++++++++++++++++++++++++++++ Sources/arm/io/ImportStl.hx | 21 +++++++++++ Sources/arm/io/Importer.hx | 1 + Sources/arm/ui/UITrait.hx | 2 +- Sources/arm/util/Path.hx | 1 + 6 files changed, 90 insertions(+), 2 deletions(-) create mode 100644 Sources/arm/format/StlParser.hx create mode 100644 Sources/arm/io/ImportStl.hx diff --git a/Sources/arm/Context.hx b/Sources/arm/Context.hx index 43f90dd2..6cbf1b3c 100644 --- a/Sources/arm/Context.hx +++ b/Sources/arm/Context.hx @@ -168,7 +168,7 @@ class Context { public static function importMesh() { UIFiles.show = true; UIFiles.isSave = false; - UIFiles.filters = "obj,fbx,blend,arm"; + UIFiles.filters = "obj,fbx,stl,blend,arm"; UIFiles.filesDone = function(path:String) { Importer.importFile(path); } diff --git a/Sources/arm/format/StlParser.hx b/Sources/arm/format/StlParser.hx new file mode 100644 index 00000000..bdcf5620 --- /dev/null +++ b/Sources/arm/format/StlParser.hx @@ -0,0 +1,65 @@ +package arm.format; + +class StlParser { + + public var posa:kha.arrays.Int16Array = null; + public var nora:kha.arrays.Int16Array = null; + public var texa:kha.arrays.Int16Array = null; + public var inda:kha.arrays.Uint32Array = null; + + public var scalePos = 1.0; + public var scaleTex = 1.0; + public var name = ""; + public var hasNext = false; + public var pos = 0; + + public function new(blob:kha.Blob) { + var bytes = blob.bytes; + var input = new haxe.io.BytesInput(bytes); + var header = input.read(80); + if (header.getString(0, 5) == "solid") { + return; // ascii not supported + } + var faces = input.readInt32(); + var posTemp = new kha.arrays.Float32Array(faces * 9); + var norTemp = new kha.arrays.Float32Array(faces * 3); + for (i in 0...faces) { + var i3 = i * 3; + norTemp[i3 ] = input.readFloat(); + norTemp[i3 + 1] = input.readFloat(); + norTemp[i3 + 2] = input.readFloat(); + var i9 = i * 9; + posTemp[i9 ] = input.readFloat(); + posTemp[i9 + 1] = input.readFloat(); + posTemp[i9 + 2] = input.readFloat(); + posTemp[i9 + 3] = input.readFloat(); + posTemp[i9 + 4] = input.readFloat(); + posTemp[i9 + 5] = input.readFloat(); + posTemp[i9 + 6] = input.readFloat(); + posTemp[i9 + 7] = input.readFloat(); + posTemp[i9 + 8] = input.readFloat(); + input.readInt16(); // attribute + } + + scalePos = 0.0; + for (i in 0...posTemp.length) { + var f = Math.abs(posTemp[i]); + if (scalePos < f) scalePos = f; + } + var inv = 32767 * (1 / scalePos); + + var verts = Std.int(posTemp.length / 3); + posa = new kha.arrays.Int16Array(verts * 4); + nora = new kha.arrays.Int16Array(verts * 2); + inda = new kha.arrays.Uint32Array(verts); + for (i in 0...verts) { + posa[i * 4 ] = Std.int( posTemp[i * 3 ] * inv); + posa[i * 4 + 1] = Std.int(-posTemp[i * 3 + 2] * inv); + posa[i * 4 + 2] = Std.int( posTemp[i * 3 + 1] * inv); + nora[i * 2 ] = Std.int( norTemp[i ] * 32767); + nora[i * 2 + 1] = Std.int(-norTemp[i + 2] * 32767); + posa[i * 4 + 3] = Std.int( norTemp[i + 1] * 32767); + inda[i] = i; + } + } +} diff --git a/Sources/arm/io/ImportStl.hx b/Sources/arm/io/ImportStl.hx new file mode 100644 index 00000000..f6b392c8 --- /dev/null +++ b/Sources/arm/io/ImportStl.hx @@ -0,0 +1,21 @@ +package arm.io; + +import kha.Blob; +import iron.data.Data; +import arm.format.StlParser; +import arm.ui.UITrait; +using StringTools; + +class ImportStl { + + public static function run(path:String) { + Data.getBlob(path, function(b:Blob) { + var obj = new StlParser(b); + var p = path.replace("\\", "/"); + var index = p.lastIndexOf("/"); + obj.name = p.substring(index >= 0 ? index + 1 : 0, p.length - 4); + Importer.makeMesh(obj, path); + Data.deleteBlob(path); + }); + } +} diff --git a/Sources/arm/io/Importer.hx b/Sources/arm/io/Importer.hx index eec5389a..a2b8a58b 100644 --- a/Sources/arm/io/Importer.hx +++ b/Sources/arm/io/Importer.hx @@ -70,6 +70,7 @@ class Importer { var p = path.toLowerCase(); if (p.endsWith(".obj")) ImportObj.run(path); else if (p.endsWith(".fbx")) ImportFbx.run(path); + else if (p.endsWith(".stl")) ImportStl.run(path); else if (p.endsWith(".blend")) ImportBlend.run(path); if (Context.mergedObject != null) { diff --git a/Sources/arm/ui/UITrait.hx b/Sources/arm/ui/UITrait.hx index e82e6338..9c815e60 100644 --- a/Sources/arm/ui/UITrait.hx +++ b/Sources/arm/ui/UITrait.hx @@ -442,7 +442,7 @@ class UITrait { else if (Operator.shortcut(Config.keymap.import_assets)) { UIFiles.show = true; UIFiles.isSave = false; - UIFiles.filters = "jpg,png,tga,bmp,psd,gif,hdr,obj,fbx,blend,arm"; + UIFiles.filters = "jpg,png,tga,bmp,psd,gif,hdr,obj,fbx,stl,blend,arm"; UIFiles.filesDone = function(path:String) { Importer.importFile(path); } diff --git a/Sources/arm/util/Path.hx b/Sources/arm/util/Path.hx index 8b2e84f7..706f5789 100644 --- a/Sources/arm/util/Path.hx +++ b/Sources/arm/util/Path.hx @@ -33,6 +33,7 @@ class Path { var p = path.toLowerCase(); return p.endsWith(".obj") || p.endsWith(".fbx") || + p.endsWith(".stl") || p.endsWith(".blend"); }