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