From 747c24d75ff2093ca6e28bcbe3f03a91e1a11a40 Mon Sep 17 00:00:00 2001 From: luboslenco Date: Fri, 13 Mar 2020 23:27:00 +0100 Subject: [PATCH] Brush import export --- Sources/arm/Context.hx | 7 +++++- Sources/arm/Project.hx | 7 ++++++ Sources/arm/io/ExportArm.hx | 32 +++++++++++++++++++++++++ Sources/arm/io/ImportArm.hx | 46 ++++++++++++++++++++++++++++++++++++ Sources/arm/ui/TabBrushes.hx | 35 ++++++++++++++++++++++++--- 5 files changed, 123 insertions(+), 4 deletions(-) diff --git a/Sources/arm/Context.hx b/Sources/arm/Context.hx index dc3f1c12..718c99a9 100644 --- a/Sources/arm/Context.hx +++ b/Sources/arm/Context.hx @@ -70,7 +70,12 @@ class Context { public static function selectBrush(i: Int) { if (Project.brushes.length <= i) return; - brush = Project.brushes[i]; + setBrush(Project.brushes[i]); + } + + public static function setBrush(b: BrushSlot) { + if (Project.brushes.indexOf(b) == -1) return; + brush = b; MaterialParser.parseBrush(); UITrait.inst.parseBrushInputs(); UITrait.inst.hwnd1.redraws = 2; diff --git a/Sources/arm/Project.hx b/Sources/arm/Project.hx index 21152db5..374255e2 100644 --- a/Sources/arm/Project.hx +++ b/Sources/arm/Project.hx @@ -235,6 +235,12 @@ class Project { }); } + public static function importBrush() { + UIFiles.show("arm", false, function(path: String) { + ImportArm.runBrush(path); + }); + } + public static function importMesh() { UIFiles.show(Path.meshFormats.join(","), false, function(path: String) { importMeshBox(path); @@ -293,6 +299,7 @@ class Project { typedef TProjectFormat = { public var version: String; @:optional public var brush_nodes: Array; + @:optional public var brush_icons: Array; @:optional public var material_nodes: Array; @:optional public var material_icons: Array; @:optional public var assets: Array; // texture_assets diff --git a/Sources/arm/io/ExportArm.hx b/Sources/arm/io/ExportArm.hx index da4f19f8..b0119ced 100644 --- a/Sources/arm/io/ExportArm.hx +++ b/Sources/arm/io/ExportArm.hx @@ -112,6 +112,38 @@ class ExportArm { Krom.fileSaveBytes(path, bytes.getData()); } + public static function runBrush(path: String) { + var bnodes: Array = []; + var b = Context.brush; + var c: TNodeCanvas = Json.parse(Json.stringify(b.canvas)); + var assets: Array = []; + for (n in c.nodes) { + if (n.type == "TEX_IMAGE") { + var index = n.buttons[0].default_value; + n.buttons[0].data = App.enumTexts(n.type)[index]; + + var asset = Project.assets[index]; + if (assets.indexOf(asset) == -1) { + assets.push(asset); + } + } + } + bnodes.push(c); + + var texture_files = assetsToFiles(assets); + + var raw = { + version: App.version, + brush_nodes: bnodes, + brush_icons: [Lz4.encode(b.image.getPixels())], + assets: texture_files + }; + + var bytes = ArmPack.encode(raw); + if (!path.endsWith(".arm")) path += ".arm"; + Krom.fileSaveBytes(path, bytes.getData()); + } + static function assetsToFiles(assets: Array): Array { var texture_files: Array = []; for (a in assets) { diff --git a/Sources/arm/io/ImportArm.hx b/Sources/arm/io/ImportArm.hx index 5f6a66b9..a9e2db7a 100644 --- a/Sources/arm/io/ImportArm.hx +++ b/Sources/arm/io/ImportArm.hx @@ -316,6 +316,52 @@ class ImportArm { Data.deleteBlob(path); } + public static function runBrush(path: String) { + Data.getBlob(path, function(b: Blob) { + var project: TProjectFormat = ArmPack.decode(b.toBytes()); + if (project.version == null) { Data.deleteBlob(path); return; } + runBrushFromProject(project, path); + }); + } + + public static function runBrushFromProject(project: TProjectFormat, path: String) { + var base = Path.baseDir(path); + for (file in project.assets) { + #if krom_windows + file = file.replace("/", "\\"); + #else + file = file.replace("\\", "/"); + #end + // Convert image path from relative to absolute + var abs = Data.isAbsolute(file) ? file : base + file; + if (!File.exists(abs)) { + makePink(abs); + } + arm.io.ImportTexture.run(abs); + } + + var imported: Array = []; + + for (n in project.brush_nodes) { + initNodes(n.nodes); + Context.brush = new BrushSlot(n); + Project.brushes.push(Context.brush); + imported.push(Context.brush); + } + + function makeBrushPreview(_) { + for (b in imported) { + Context.setBrush(b); + RenderUtil.makeBrushPreview(); + } + iron.App.removeRender(makeBrushPreview); + } + iron.App.notifyOnRender(makeBrushPreview); + + UITrait.inst.hwnd1.redraws = 2; + Data.deleteBlob(path); + } + static function makePink(abs: String) { Log.error(Strings.error2 + abs); var b = Bytes.alloc(4); diff --git a/Sources/arm/ui/TabBrushes.hx b/Sources/arm/ui/TabBrushes.hx index 59a78413..4808e824 100644 --- a/Sources/arm/ui/TabBrushes.hx +++ b/Sources/arm/ui/TabBrushes.hx @@ -1,9 +1,13 @@ package arm.ui; +import haxe.Json; import iron.system.Time; import zui.Zui; import arm.data.BrushSlot; import arm.node.MaterialParser; +import arm.util.RenderUtil; +import arm.io.ExportArm; +import arm.sys.Path; class TabBrushes { @@ -19,7 +23,9 @@ class TabBrushes { UITrait.inst.parseBrushInputs(); UINodes.inst.hwnd.redraws = 2; } - if (ui.button("Import")) {} + if (ui.button("Import")) { + Project.importBrush(); + } if (ui.button("Nodes")) UITrait.inst.showBrushNodes(); var slotw = Std.int(51 * ui.SCALE()); @@ -66,16 +72,39 @@ class TabBrushes { // App.dragBrush = Context.brush; } if (ui.isHovered && ui.inputReleasedR) { + var add = Project.brushes.length > 1 ? 1 : 0; UIMenu.draw(function(ui: Zui) { //var b = Project.brushes[i]; ui.text(Project.brushes[i].canvas.name, Right, ui.t.HIGHLIGHT_COL); - if (ui.button("Delete", Left) && Project.brushes.length > 1) { + if (ui.button("Export", Left)) { + Context.selectBrush(i); + UIFiles.show("arm", true, function(path: String) { + var f = UIFiles.filename; + if (f == "") f = "untitled"; + ExportArm.runBrush(path + Path.sep + f); + }); + } + + if (ui.button("Duplicate", Left)) { + function dupliBrush(_) { + iron.App.removeRender(dupliBrush); + Context.brush = new BrushSlot(); + Project.brushes.push(Context.brush); + var cloned = Json.parse(Json.stringify(Project.brushes[i].canvas)); + Context.brush.canvas = cloned; + Context.setBrush(Context.brush); + RenderUtil.makeBrushPreview(); + } + iron.App.notifyOnRender(dupliBrush); + } + + if (Project.brushes.length > 1 && ui.button("Delete", Left)) { Context.selectBrush(i == 0 ? 1 : 0); Project.brushes.splice(i, 1); UITrait.inst.hwnd1.redraws = 2; } - }, 2); + }, 3 + add); } if (ui.isHovered && imgFull != null) ui.tooltipImage(imgFull); }