diff --git a/.gitignore b/.gitignore
index 940794e..41a6308 100644
--- a/.gitignore
+++ b/.gitignore
@@ -3,6 +3,9 @@
##
## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
+# Project-specific files
+heightmap2stl-gui.zip
+
# User-specific files
*.suo
*.user
diff --git a/App.config b/App.config
new file mode 100644
index 0000000..d740e88
--- /dev/null
+++ b/App.config
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Main.Designer.cs b/Main.Designer.cs
new file mode 100644
index 0000000..d730fa5
--- /dev/null
+++ b/Main.Designer.cs
@@ -0,0 +1,227 @@
+namespace app
+{
+ partial class Main
+ {
+ ///
+ /// Required designer variable.
+ ///
+ private System.ComponentModel.IContainer components = null;
+
+ ///
+ /// Clean up any resources being used.
+ ///
+ /// true if managed resources should be disposed; otherwise, false.
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing && (components != null))
+ {
+ components.Dispose();
+ }
+ base.Dispose(disposing);
+ }
+
+ #region Windows Form Designer generated code
+
+ ///
+ /// Required method for Designer support - do not modify
+ /// the contents of this method with the code editor.
+ ///
+ private void InitializeComponent()
+ {
+ this.btnCreate = new System.Windows.Forms.Button();
+ this.txtFile = new System.Windows.Forms.TextBox();
+ this.label1 = new System.Windows.Forms.Label();
+ this.btnPick = new System.Windows.Forms.Button();
+ this.hostSoftwareSite = new System.Windows.Forms.LinkLabel();
+ this.txtLog = new System.Windows.Forms.TextBox();
+ this.numBaseHeight = new System.Windows.Forms.NumericUpDown();
+ this.numModelHeight = new System.Windows.Forms.NumericUpDown();
+ this.label2 = new System.Windows.Forms.Label();
+ this.label3 = new System.Windows.Forms.Label();
+ this.label4 = new System.Windows.Forms.Label();
+ this.btnCancel = new System.Windows.Forms.Button();
+ ((System.ComponentModel.ISupportInitialize)(this.numBaseHeight)).BeginInit();
+ ((System.ComponentModel.ISupportInitialize)(this.numModelHeight)).BeginInit();
+ this.SuspendLayout();
+ //
+ // btnCreate
+ //
+ this.btnCreate.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
+ this.btnCreate.Location = new System.Drawing.Point(325, 24);
+ this.btnCreate.Margin = new System.Windows.Forms.Padding(2);
+ this.btnCreate.Name = "btnCreate";
+ this.btnCreate.Size = new System.Drawing.Size(53, 22);
+ this.btnCreate.TabIndex = 3;
+ this.btnCreate.Text = "Create";
+ this.btnCreate.UseVisualStyleBackColor = true;
+ this.btnCreate.Click += new System.EventHandler(this.btnCreate_Click);
+ //
+ // txtFile
+ //
+ this.txtFile.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
+ | System.Windows.Forms.AnchorStyles.Right)));
+ this.txtFile.Location = new System.Drawing.Point(9, 25);
+ this.txtFile.Margin = new System.Windows.Forms.Padding(2);
+ this.txtFile.Name = "txtFile";
+ this.txtFile.ReadOnly = true;
+ this.txtFile.Size = new System.Drawing.Size(285, 20);
+ this.txtFile.TabIndex = 1;
+ //
+ // label1
+ //
+ this.label1.AutoSize = true;
+ this.label1.Location = new System.Drawing.Point(6, 10);
+ this.label1.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0);
+ this.label1.Name = "label1";
+ this.label1.Size = new System.Drawing.Size(95, 13);
+ this.label1.TabIndex = 0;
+ this.label1.Text = "Heightmap Source";
+ //
+ // btnPick
+ //
+ this.btnPick.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
+ this.btnPick.Location = new System.Drawing.Point(295, 24);
+ this.btnPick.Margin = new System.Windows.Forms.Padding(2);
+ this.btnPick.Name = "btnPick";
+ this.btnPick.Size = new System.Drawing.Size(26, 22);
+ this.btnPick.TabIndex = 2;
+ this.btnPick.Text = "...";
+ this.btnPick.UseVisualStyleBackColor = true;
+ this.btnPick.Click += new System.EventHandler(this.btnPick_Click);
+ //
+ // hostSoftwareSite
+ //
+ this.hostSoftwareSite.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
+ this.hostSoftwareSite.AutoSize = true;
+ this.hostSoftwareSite.Location = new System.Drawing.Point(6, 260);
+ this.hostSoftwareSite.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0);
+ this.hostSoftwareSite.Name = "hostSoftwareSite";
+ this.hostSoftwareSite.Size = new System.Drawing.Size(72, 13);
+ this.hostSoftwareSite.TabIndex = 11;
+ this.hostSoftwareSite.TabStop = true;
+ this.hostSoftwareSite.Tag = "https://sourceforge.net/projects/heightmap2stl/";
+ this.hostSoftwareSite.Text = "heightmap2stl";
+ this.hostSoftwareSite.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.hostSoftwareSite_LinkClicked);
+ //
+ // txtLog
+ //
+ this.txtLog.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
+ | System.Windows.Forms.AnchorStyles.Left)
+ | System.Windows.Forms.AnchorStyles.Right)));
+ this.txtLog.Location = new System.Drawing.Point(9, 95);
+ this.txtLog.Margin = new System.Windows.Forms.Padding(2);
+ this.txtLog.Multiline = true;
+ this.txtLog.Name = "txtLog";
+ this.txtLog.ReadOnly = true;
+ this.txtLog.ScrollBars = System.Windows.Forms.ScrollBars.Vertical;
+ this.txtLog.Size = new System.Drawing.Size(371, 157);
+ this.txtLog.TabIndex = 10;
+ //
+ // numBaseHeight
+ //
+ this.numBaseHeight.Location = new System.Drawing.Point(75, 49);
+ this.numBaseHeight.Margin = new System.Windows.Forms.Padding(2);
+ this.numBaseHeight.Name = "numBaseHeight";
+ this.numBaseHeight.Size = new System.Drawing.Size(45, 20);
+ this.numBaseHeight.TabIndex = 5;
+ //
+ // numModelHeight
+ //
+ this.numModelHeight.Location = new System.Drawing.Point(198, 49);
+ this.numModelHeight.Margin = new System.Windows.Forms.Padding(2);
+ this.numModelHeight.Name = "numModelHeight";
+ this.numModelHeight.Size = new System.Drawing.Size(45, 20);
+ this.numModelHeight.TabIndex = 7;
+ this.numModelHeight.Value = new decimal(new int[] {
+ 10,
+ 0,
+ 0,
+ 0});
+ //
+ // label2
+ //
+ this.label2.AutoSize = true;
+ this.label2.Location = new System.Drawing.Point(6, 51);
+ this.label2.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0);
+ this.label2.Name = "label2";
+ this.label2.Size = new System.Drawing.Size(65, 13);
+ this.label2.TabIndex = 4;
+ this.label2.Text = "Base Height";
+ //
+ // label3
+ //
+ this.label3.AutoSize = true;
+ this.label3.Location = new System.Drawing.Point(124, 51);
+ this.label3.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0);
+ this.label3.Name = "label3";
+ this.label3.Size = new System.Drawing.Size(70, 13);
+ this.label3.TabIndex = 6;
+ this.label3.Text = "Model Height";
+ //
+ // label4
+ //
+ this.label4.AutoSize = true;
+ this.label4.Location = new System.Drawing.Point(6, 80);
+ this.label4.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0);
+ this.label4.Name = "label4";
+ this.label4.Size = new System.Drawing.Size(81, 13);
+ this.label4.TabIndex = 9;
+ this.label4.Text = "Program Output";
+ //
+ // btnCancel
+ //
+ this.btnCancel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
+ this.btnCancel.Enabled = false;
+ this.btnCancel.Location = new System.Drawing.Point(327, 256);
+ this.btnCancel.Margin = new System.Windows.Forms.Padding(2);
+ this.btnCancel.Name = "btnCancel";
+ this.btnCancel.Size = new System.Drawing.Size(53, 20);
+ this.btnCancel.TabIndex = 8;
+ this.btnCancel.Text = "Cancel";
+ this.btnCancel.UseVisualStyleBackColor = true;
+ this.btnCancel.Click += new System.EventHandler(this.btnCancel_Click);
+ //
+ // Main
+ //
+ this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+ this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+ this.ClientSize = new System.Drawing.Size(384, 281);
+ this.Controls.Add(this.label4);
+ this.Controls.Add(this.label3);
+ this.Controls.Add(this.label2);
+ this.Controls.Add(this.numModelHeight);
+ this.Controls.Add(this.numBaseHeight);
+ this.Controls.Add(this.btnCancel);
+ this.Controls.Add(this.txtLog);
+ this.Controls.Add(this.hostSoftwareSite);
+ this.Controls.Add(this.btnPick);
+ this.Controls.Add(this.label1);
+ this.Controls.Add(this.txtFile);
+ this.Controls.Add(this.btnCreate);
+ this.Margin = new System.Windows.Forms.Padding(2);
+ this.Name = "Main";
+ this.Text = "heightmap2stl";
+ ((System.ComponentModel.ISupportInitialize)(this.numBaseHeight)).EndInit();
+ ((System.ComponentModel.ISupportInitialize)(this.numModelHeight)).EndInit();
+ this.ResumeLayout(false);
+ this.PerformLayout();
+
+ }
+
+ #endregion
+
+ private System.Windows.Forms.Button btnCreate;
+ private System.Windows.Forms.TextBox txtFile;
+ private System.Windows.Forms.Label label1;
+ private System.Windows.Forms.Button btnPick;
+ private System.Windows.Forms.LinkLabel hostSoftwareSite;
+ private System.Windows.Forms.TextBox txtLog;
+ private System.Windows.Forms.NumericUpDown numBaseHeight;
+ private System.Windows.Forms.NumericUpDown numModelHeight;
+ private System.Windows.Forms.Label label2;
+ private System.Windows.Forms.Label label3;
+ private System.Windows.Forms.Label label4;
+ private System.Windows.Forms.Button btnCancel;
+ }
+}
+
diff --git a/Main.cs b/Main.cs
new file mode 100644
index 0000000..72c51f8
--- /dev/null
+++ b/Main.cs
@@ -0,0 +1,198 @@
+using System;
+using System.ComponentModel;
+using System.Diagnostics;
+using System.IO;
+using System.Reflection;
+using System.Threading.Tasks;
+using System.Windows.Forms;
+
+[assembly: AssemblyTitle("heightmap2stl-gui")]
+[assembly: AssemblyProduct("heightmap2stl-gui")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
+
+namespace app
+{
+ static class Program
+ {
+ [STAThread]
+ static void Main()
+ {
+ Application.EnableVisualStyles();
+ Application.SetCompatibleTextRenderingDefault(false);
+ Application.Run(new Main());
+ }
+ }
+
+ public partial class Main : Form
+ {
+ private Process _p;
+
+ public Main()
+ {
+ InitializeComponent();
+ }
+
+ protected override void OnClosing(CancelEventArgs e)
+ {
+ base.OnClosing(e);
+ KillChildProcess();
+ }
+
+ private void btnCreate_Click(object sender, EventArgs e)
+ {
+ ClearLog();
+
+ if (FindJavaRuntime() == false)
+ {
+ AppendLog("JAVA cannot be found. Download/Install from https://java.com");
+ return;
+ }
+
+ if (string.IsNullOrEmpty(txtFile.Text))
+ {
+ AppendLog("Error: Heightmap Source is empty");
+ return;
+ }
+
+ var rawFileName = new FileInfo(txtFile.Text);
+ var stlFilePath = Path.GetFileNameWithoutExtension(rawFileName.FullName) + ".stl";
+ if (File.Exists(stlFilePath))
+ {
+ var overwrite = MessageBox.Show(this,
+ "Do you want to overwrite?" + Path.GetFileName(stlFilePath),
+ "File Exists",
+ MessageBoxButtons.YesNo, MessageBoxIcon.Warning);
+
+ if (overwrite == DialogResult.No)
+ {
+ AppendLog("Info: Operation Cancelled. Prevented overwriting existing STL file.");
+ return;
+ }
+ }
+
+ ExtractBinary();
+
+ btnCreate.Enabled = false;
+ btnCancel.Enabled = true;
+
+ Task.Factory.StartNew(RunExport).ContinueWith((ancestor, _) =>
+ {
+ btnCreate.Enabled = true;
+ btnCancel.Enabled = false;
+ },
+ null,
+ TaskScheduler.FromCurrentSynchronizationContext());
+ }
+
+ private void RunExport()
+ {
+ var rawFileName = new FileInfo(txtFile.Text);
+ _p = new Process();
+ _p.StartInfo.FileName = "java.exe";
+ _p.StartInfo.Arguments = string.Join(" ",
+ "-jar",
+ $"\"{AppTempPath()}\"",
+ $"\"{rawFileName.FullName}\"",
+ numModelHeight.Text,
+ numBaseHeight.Text
+ );
+ _p.StartInfo.CreateNoWindow = true;
+ _p.StartInfo.UseShellExecute = false;
+ _p.StartInfo.RedirectStandardOutput = true;
+ _p.StartInfo.RedirectStandardError = true;
+ _p.OutputDataReceived += OnDataReceived;
+ _p.ErrorDataReceived += OnDataReceived;
+ _p.Start();
+ _p.BeginOutputReadLine();
+ _p.BeginErrorReadLine();
+ _p.WaitForExit(360000);
+ _p.Close();
+ _p = null;
+ }
+
+ private void OnDataReceived(object sender, DataReceivedEventArgs args)
+ {
+ if (args.Data == null)
+ return;
+
+ AppendLog(args.Data);
+ }
+
+ private void AppendLog(string text)
+ {
+ if (txtLog.InvokeRequired)
+ txtLog.Invoke(new Action(AppendLog), text);
+ else
+ txtLog.AppendText(text + Environment.NewLine);
+ }
+
+ private void ClearLog()
+ {
+ if (txtLog.InvokeRequired)
+ txtLog.Invoke(new Action(ClearLog));
+ else
+ txtLog.Clear();
+ }
+
+ private bool FindJavaRuntime()
+ {
+ try
+ {
+ var psi = new ProcessStartInfo("java.exe", "-version");
+ psi.UseShellExecute = true;
+ var process = Process.Start(psi);
+ process?.WaitForExit(50000);
+ return process?.ExitCode == 0;
+ }
+ catch
+ {
+ // ignored
+ }
+ return false;
+ }
+
+ private void ExtractBinary()
+ {
+ string path = AppTempPath();
+ if (File.Exists(path)) return;
+ var asm = Assembly.GetEntryAssembly();
+ using (Stream app = asm.GetManifestResourceStream("app.heightmap2stl.jar"))
+ using (Stream writer = File.OpenWrite(path))
+ {
+ app?.CopyTo(writer);
+ }
+ }
+
+ private static string AppTempPath()
+ {
+ return Path.Combine(Environment.GetEnvironmentVariable("TEMP"), "heightmap2stl.jar");
+ }
+
+ private void hostSoftwareSite_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
+ {
+ Process.Start((string)e.Link.Tag);
+ }
+
+ private void btnPick_Click(object sender, EventArgs e)
+ {
+ using (FileDialog d = new OpenFileDialog())
+ {
+ if (DialogResult.OK != d.ShowDialog()) return;
+ txtFile.Text = d.FileName;
+ }
+ }
+
+ private void btnCancel_Click(object sender, EventArgs e)
+ {
+ KillChildProcess();
+ AppendLog(new string('-', 20));
+ AppendLog("Warning: User cancelled processing");
+ }
+
+ private void KillChildProcess()
+ {
+ _p?.Kill();
+ }
+ }
+}
diff --git a/README.md b/README.md
index f40371c..662ec4b 100644
--- a/README.md
+++ b/README.md
@@ -1,2 +1,2 @@
# heightmap2stl-gui
-a gui for heightmap2stl
+a gui for [heightmap2stl](https://sourceforge.net/projects/heightmap2stl/)
diff --git a/build.bat b/build.bat
new file mode 100644
index 0000000..4e6f018
--- /dev/null
+++ b/build.bat
@@ -0,0 +1,5 @@
+@echo off
+
+call msbuildpath.bat
+
+%MSBUILDDIR%msbuild.exe heightmap2stl-gui.csproj /p:Configuration=Release
\ No newline at end of file
diff --git a/heightmap2stl-gui.csproj b/heightmap2stl-gui.csproj
new file mode 100644
index 0000000..28da072
--- /dev/null
+++ b/heightmap2stl-gui.csproj
@@ -0,0 +1,71 @@
+
+
+
+
+ Debug
+ AnyCPU
+ {9CD32096-8889-4F20-9529-77750C6E97E5}
+ WinExe
+ Properties
+ app
+ heightmap2stl-gui
+ v4.5.2
+ 512
+ true
+
+
+ AnyCPU
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+
+
+ AnyCPU
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Main.cs
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/heightmap2stl.jar b/heightmap2stl.jar
new file mode 100644
index 0000000..ded106e
Binary files /dev/null and b/heightmap2stl.jar differ
diff --git a/heightmap2stl.sln b/heightmap2stl.sln
new file mode 100644
index 0000000..94f4377
--- /dev/null
+++ b/heightmap2stl.sln
@@ -0,0 +1,22 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 14
+VisualStudioVersion = 14.0.25420.1
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "heightmap2stl-gui", "heightmap2stl-gui.csproj", "{9CD32096-8889-4F20-9529-77750C6E97E5}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {9CD32096-8889-4F20-9529-77750C6E97E5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {9CD32096-8889-4F20-9529-77750C6E97E5}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {9CD32096-8889-4F20-9529-77750C6E97E5}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {9CD32096-8889-4F20-9529-77750C6E97E5}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/msbuildpath.bat b/msbuildpath.bat
new file mode 100644
index 0000000..dad8f37
--- /dev/null
+++ b/msbuildpath.bat
@@ -0,0 +1,24 @@
+@echo off
+
+reg.exe query "HKLM\SOFTWARE\Microsoft\MSBuild\ToolsVersions\4.0" /v MSBuildToolsPath > nul 2>&1
+if ERRORLEVEL 1 goto MissingMSBuildRegistry
+
+for /f "skip=2 tokens=2,*" %%A in ('reg.exe query "HKLM\SOFTWARE\Microsoft\MSBuild\ToolsVersions\4.0" /v MSBuildToolsPath') do SET MSBUILDDIR=%%B
+
+IF NOT EXIST %MSBUILDDIR%nul goto MissingMSBuildToolsPath
+IF NOT EXIST %MSBUILDDIR%msbuild.exe goto MissingMSBuildExe
+
+exit /b 0
+
+goto:eof
+::ERRORS
+::---------------------
+:MissingMSBuildRegistry
+echo Cannot obtain path to MSBuild tools from registry
+goto:eof
+:MissingMSBuildToolsPath
+echo The MSBuild tools path from the registry '%MSBUILDDIR%' does not exist
+goto:eof
+:MissingMSBuildExe
+echo The MSBuild executable could not be found at '%MSBUILDDIR%'
+goto:eof
diff --git a/pack.bat b/pack.bat
new file mode 100644
index 0000000..ba4a47f
--- /dev/null
+++ b/pack.bat
@@ -0,0 +1,3 @@
+@echo off
+if exist heightmap2stl-gui.zip del heightmap2stl-gui.zip
+powershell -NoProfile -ExecutionPolicy Bypass -Command "Compress-Archive -Path .\Bin\Release\heightmap2stl-gui.exe, .\Bin\Release\heightmap2stl-gui.exe.config -CompressionLevel Optimal -DestinationPath .\heightmap2stl-gui.zip"
\ No newline at end of file