Last active
April 9, 2026 17:13
-
-
Save evenprimes/f5b3cb9bbef3d5c8c03cc7a74c62b730 to your computer and use it in GitHub Desktop.
OpenSCAD rendering script
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <# | |
| .SYNOPSIS | |
| Export STLs and PNGs of OpenSCAD scripts to the desktop. | |
| .DESCRIPTION | |
| Exports all defined parts from an OpenSCAD script. | |
| Assumptions: | |
| - The OpenSCAD script defines a RENDER_PART variable. | |
| - When RENDER_PART = 0, it echo()s a list of parts with a number and name. | |
| The name will be used as the STL and PNG filename. | |
| RENDER_PART = 1; | |
| if (RENDER_PART == 0) | |
| { | |
| echo("render 1 cube"); | |
| echo("render 2 cylinder"); | |
| } | |
| if (RENDER_PART == 1) { cube(10); } | |
| if (RENDER_PART == 2) { cylinder(d=10,l=10); } | |
| When rendering all objects, only objects with a number < 1000 will be rendered. | |
| Objects with an ID > 1000 are considered test objects. They can be rendered, but only manually. | |
| .PARAMETER SCADScript | |
| Path of the OpenSCAD script. | |
| .PARAMETER PartNumber (Optional) | |
| Part number to export, if only 1 part is desired. | |
| #> | |
| [CmdletBinding()] | |
| param ( | |
| [Parameter(Position = 0, mandatory = $true)] | |
| [ValidateScript({ Test-Path $_ -PathType Leaf })] | |
| [System.IO.FileInfo] | |
| $SCADScript, | |
| # list of parts to print | |
| [Parameter(Position = 1, mandatory = $false, ValueFromRemainingArguments = $true)] | |
| [ValidateRange("Positive")] | |
| [int[]] | |
| $PartNumbers = -1, | |
| # Just list the available parts? | |
| [Parameter()] | |
| [switch] | |
| $List = $false, | |
| # Include PNG outputs? | |
| [Parameter()] | |
| [switch] | |
| $IncludePNG = $false | |
| ) | |
| write-debug "Type of SCADScript: $($SCADScript.GetType())" | |
| function Export-SinglePart { | |
| [CmdletBinding()] | |
| param ( | |
| [Parameter(Position = 0, mandatory = $true)] | |
| [string] | |
| $SCADScript, | |
| # Which part to export | |
| [Parameter(Position = 1, mandatory = $true)] | |
| [ValidateRange("Positive")] | |
| [int] | |
| $PartNumber, | |
| # Part Name | |
| [Parameter(Position = 2, mandatory = $true)] | |
| [string] | |
| $PartName, | |
| # Parameter help description | |
| [Parameter(Position = 3, Mandatory = $true)] | |
| [bool] | |
| $IncludePNG | |
| ) | |
| $dval = "RENDER_PART=$PartNumber" | |
| if (Test-Path -Path $home\Desktop) { | |
| $stl_dest = "$home\Desktop\$($PartName).stl" | |
| } | |
| else { | |
| if (Test-Path -Path $env:OneDrive) { | |
| $stl_dest = "$env:OneDrive\Desktop\$($PartName).stl" | |
| } | |
| else { | |
| $stl_dest = "$($PartName).stl" | |
| } | |
| } | |
| # $stl_dest = "$home\Desktop\$($PartName).stl" | |
| Write-Host -ForegroundColor Cyan "`nRendering $PartName..." | |
| if ($IncludePNG) { | |
| $png_dest = "$home\Desktop\$($PartName).png" | |
| & openscad -D $dval -o $stl_dest -o $png_dest $SCADScript | |
| } | |
| else { | |
| & openscad -D $dval -o $stl_dest $SCADScript | |
| } | |
| } | |
| function Get-PartList { | |
| param ( | |
| # Path of the SCAD script we are interrogating | |
| [Parameter()] | |
| [string] | |
| $SCADScript | |
| ) | |
| $dval = "RENDER_PART=0" | |
| $PartList = @{} | |
| & openscad -D $dval -o "$temp\scriptlist.stl" $SCADScript | | |
| ForEach-Object { | |
| if ($_ -match '(\d+) (.*)\"') { | |
| $PartList[[int]$Matches.1] = $Matches.2 | |
| } | |
| } | |
| return $PartList | |
| } | |
| $PartList = Get-PartList($SCADScript) | |
| if ($List) { | |
| $PartList.Keys | Sort-Object | ForEach-Object { | |
| Write-Host $_, $PartList[$_] | |
| } | |
| Exit | |
| } | |
| if ($PartNumber -eq -1) { | |
| foreach ($Key in $PartList.Keys) { | |
| if ($Key -lt 1000) { | |
| Export-SinglePart -SCADScript $SCADScript -PartNumber $Key -PartName $PartList[$Key] -IncludePNG $IncludePNG | |
| } | |
| } | |
| } | |
| else { | |
| foreach ($PartNumber in $PartNumbers) { | |
| Write-Debug "Working on part number $PartNumber" | |
| if ($PartList.ContainsKey($PartNumber)) { | |
| Export-SinglePart -SCADScript $SCADScript -PartNumber $PartNumber -PartName $PartList[$PartNumber] -IncludePNG $IncludePNG | |
| } | |
| else { | |
| Write-Host "$SCADScript doesn't have part number '$PartNumber', will output based on part number" -ForegroundColor DarkCyan | |
| $ofile = "$(Split-Path -Path $SCADScript -LeafBase)_part-$PartNumber" | |
| Export-SinglePart -SCADScript $SCADScript -PartNumber $PartNumber -PartName $ofile -IncludePNG $IncludePNG | |
| } | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // MARK: Render Control | |
| RENDER_PART = 2; | |
| if (RENDER_PART == 0) | |
| { | |
| echo("render 1 first part"); | |
| echo("render 2 second part"); | |
| } | |
| if (RENDER_PART == 1) | |
| { | |
| // Render an actual part. | |
| cube([ 10, 10, 10 ]); | |
| } | |
| if (RENDER_PART == 2) | |
| { | |
| // Render another part. | |
| complex_part(); | |
| } | |
| if (RENDER_PART == -1) | |
| { | |
| // Render a test part, but only during development. | |
| // -1 isn't in the list of renderable parts for the script. | |
| subpart1(); | |
| } | |
| // Start designs in modules here. | |
| module complex_part() | |
| { | |
| union() | |
| { | |
| subpart1(); | |
| subpart2(); | |
| } | |
| } | |
| module subpart1() { cube([ 50, 50, 50 ], center = true); } | |
| module subpart2() { translate([ 0, 0, 25 ]) cylinder(h = 50, r = 25); } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment