Skip to content

Commit

Permalink
Merge pull request #15 from pinkfish/pinkfish-patch-1
Browse files Browse the repository at this point in the history
Update colorscad.sh to allow path to openscad program
  • Loading branch information
jschobben authored Jan 20, 2025
2 parents 82605aa + 290d0c7 commit dd0bfe0
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 25 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@ Both colorscad and 3mfmerge changes are included here. Unless explicitly mention

## [Unreleased]

### Added

- Support using OpenSCAD binaries which are not called `openscad`, via env var `OPENSCAD_CMD` (thanks: pinkfish)

## [0.5.2] - 2024-09-15

### Added
Expand Down
12 changes: 9 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,19 @@ AMF export should work with OpenSCAD version 2015.03, but was mostly tested on 2
Platform-wise, it should run anywhere Bash runs (that includes i.e. cygwin).
No assumptions are made about OS-specific directories, such as /tmp/ and the like.

The platform-native OpenSCAD binary does need to be reachable via the PATH,
which means on Windows Cygwin users may need to first run something like:<br>
The platform-native OpenSCAD binary needs to be available for this script to work.
If it is called `openscad` and available on the PATH, then it should work out-of-the-box.

In case the binary has a strange name, then set environment variable `OPENSCAD_CMD` to its name.
This may be a full path, or just the name.

Unless `OPENSCAD_CMD` is set to a full path, the binary needs to be reachable via the PATH.
On Windows Cygwin users may need to first run something like:<br>
```export PATH=/cygdrive/c/Program\ Files/OpenSCAD:$PATH```<br>
Similarly, Mac users can try:<br>
```export PATH=/Applications/OpenSCAD.app/Contents/MacOS:$PATH```

It should mostly work on Bash 3 (i.e. Mac's non-Homebrew default), although for best results Bash 4 is recommended.
This script should mostly work on Bash 3 (i.e. Mac's non-Homebrew default), although for best results Bash 4 is recommended.

Usage
-----
Expand Down
22 changes: 16 additions & 6 deletions colorscad.sh
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ DIR_SCRIPT="$(
pwd
)"


function usage {
cat <<EOF
Usage: $0 -i <input scad file> -o <output file> [OTHER OPTIONS...] [-- OPENSCAD OPTIONS...]
Expand All @@ -20,11 +21,15 @@ Options
and must have as extension either '.amf' or '.3mf'
-v Verbose logging: mostly, this enables the OpenSCAD rendering stats output (default disabled)
Environment variables
OPENSCAD_CMD The name of the openscad binary to use, may include full path (default: 'openscad')
Example which also includes some openscad options at the end:
$0 -i input.scad -o output.3mf -f -j 4 -- -D 'var="some value"' --hardwarnings
EOF
}


FORCE=0
INPUT=
OUTPUT=
Expand Down Expand Up @@ -69,6 +74,11 @@ done
shift "$((OPTIND-1))"
OPENSCAD_EXTRA=("$@")

if [ -n "$OPENSCAD_CMD" ]; then
echo "OpenSCAD binary in use: $(command -v "$OPENSCAD_CMD")"
fi
: "${OPENSCAD_CMD=openscad}"

if [ "$(uname)" = Darwin ]; then
# BSD sed, as used on macOS, uses a different parameter than GNU sed to enable line-buffered mode
function sed_u {
Expand Down Expand Up @@ -120,14 +130,14 @@ if [ "$FORMAT" != amf ] && [ "$FORMAT" != 3mf ]; then
exit 1
fi

if ! command -v openscad &> /dev/null; then
echo "Error: openscad command not found! Make sure it's in your PATH."
if ! command -v "$OPENSCAD_CMD" &> /dev/null; then
echo "Error: ${OPENSCAD_CMD} command not found! Make sure it's in your PATH."
exit 1
fi

if [ "$FORMAT" = 3mf ]; then
# Check if openscad was built with 3mf support
if ! openscad --info 2>&1 | grep '^lib3mf version: ' | grep -qv 'not enabled'; then
if ! "$OPENSCAD_CMD" --info 2>&1 | grep '^lib3mf version: ' | grep -qv 'not enabled'; then
echo "Warning: your openscad version does not seem to have 3MF support, see 'openscad --info'."
echo "Either update it, or use AMF output."
echo
Expand Down Expand Up @@ -169,7 +179,7 @@ TEMPDIR=$(mktemp -d ./tmp.XXXXXX)
trap "rm -Rf '$(pwd)/${INPUT_CSG}' '$(pwd)/${TEMPDIR}'" EXIT

# Convert input to a .csg file, mainly to resolve named colors. Also to evaluate functions etc. only once.
openscad "$INPUT" -o "$INPUT_CSG" "${OPENSCAD_EXTRA[@]}"
"$OPENSCAD_CMD" "$INPUT" -o "$INPUT_CSG" "${OPENSCAD_EXTRA[@]}"

if ! [ -s "$INPUT_CSG" ]; then
echo "Error: the produced file '$INPUT_CSG' is empty. Looks like something went wrong..."
Expand All @@ -184,7 +194,7 @@ echo "Get list of used colors"
# means more geometry; we want to start the biggest jobs first to improve parallelism.
COLOR_ID_TAG="colorid_$$_${RANDOM}"
COLORS=$(
openscad "$INPUT_CSG" -o "${TEMPDIR}/no_color.stl" -D "module color(c) {echo(${COLOR_ID_TAG}=str(c));}" 2>&1 |
"$OPENSCAD_CMD" "$INPUT_CSG" -o "${TEMPDIR}/no_color.stl" -D "module color(c) {echo(${COLOR_ID_TAG}=str(c));}" 2>&1 |
tr -d '\r"' |
sed -n "s/^ECHO: ${COLOR_ID_TAG} = // p" |
sort |
Expand Down Expand Up @@ -241,7 +251,7 @@ function render_color {
if [ $VERBOSE -ne 1 ]; then
EXTRA_ARGS=--quiet
fi
openscad "$INPUT_CSG" -o "$OUT_FILE" $EXTRA_ARGS -D "\$colored = false; module color(c) {if (\$colored) {children();} else {\$colored = true; if (str(c) == \"${COLOR}\") children();}}"
"$OPENSCAD_CMD" "$INPUT_CSG" -o "$OUT_FILE" $EXTRA_ARGS -D "\$colored = false; module color(c) {if (\$colored) {children();} else {\$colored = true; if (str(c) == \"${COLOR}\") children();}}"
if [ -s "$OUT_FILE" ]; then
echo "Finished at ${OUT_FILE}"
else
Expand Down
40 changes: 24 additions & 16 deletions test/run.sh
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,14 @@ set -o errexit -o errtrace -o nounset
X=$(command -v "$0")
cd "${X%${X##*/}}."

: "${OPENSCAD_CMD=openscad}"
COLORSCAD=$(pwd)/../colorscad.sh

# Use a temp dir relative to this script's dir, because openscad might not have access to the default
# temp dir; on i.e. Ubuntu, openscad can be a snap package which doesn't have access to /tmp/
TEMPDIR_REL=$(mktemp -d ./tmp.XXXXXX)
TEMPDIR="$(pwd)/${TEMPDIR_REL}"
trap "openscad --info 2>&1 | grep '^OpenSCAD Version: '; rm -Rf '$TEMPDIR'" EXIT
trap "'${OPENSCAD_CMD}' --info 2>&1 | grep '^OpenSCAD Version: '; rm -Rf '$TEMPDIR'" EXIT

SKIP_3MF=0
OLD_BOOLEAN=0
Expand All @@ -31,11 +32,12 @@ function grep_q {
grep "$@" > /dev/null
}


# If a test fails, check if it's due to the used openscad version; if so, suggest workarounds.
function fail_tips {
trap - ERR # Prevent recursion
if [ $SKIP_3MF -eq 0 ]; then
if ! openscad --info 2>&1 | grep '^lib3mf version: ' | grep_q -v 'not enabled'; then
if ! "$OPENSCAD_CMD" --info 2>&1 | grep '^lib3mf version: ' | grep_q -v 'not enabled'; then
echo "Warning: all the 3MF tests will fail if your openscad version does not have 3mf support."
echo "To skip those tests, use: $0 skip3mf"
echo
Expand All @@ -46,7 +48,7 @@ function fail_tips {
cd "$TEMPDIR"
echo 'module empty(){}; intersection() {empty(); cube();}' > intersect.scad
# <=2019.05 ignores the "empty" module, producing output; newer versions treat it as an empty volume.
openscad --quiet intersect.scad -o intersect.stl || true
"$OPENSCAD_CMD" --quiet intersect.scad -o intersect.stl || true
if [ -s intersect.stl ]; then
echo "Warning: your openscad version uses 'old' boolean semantics."
echo "To properly test on this version, use: $0 old_boolean"
Expand All @@ -55,7 +57,7 @@ function fail_tips {
rm intersect.*
)
fi
if ! openscad --help 2>&1 | grep -q -- '--input'; then
if ! "$OPENSCAD_CMD" --help 2>&1 | grep -q -- '--input'; then
# On newer builds, 'predictible-output' must be enabled to get the same behavior as older ones
echo "For OpenSCAD >= 2024.01.26, only a build with experimental features enabled will work."
fi
Expand Down Expand Up @@ -133,11 +135,15 @@ function test_render {
local OUTPUT="${TEMPDIR}/output.${FORMAT}"
rm -f "$OUTPUT"
# OpenSCAD >= 2024.01.26 with lib3mf v2 requires enabling "predictible-output" to get the same behavior as older versions
if openscad --help 2>&1 | grep -q predictible-output; then
function openscad { command openscad --enable=predictible-output "$@"; }; export -f openscad
fi
${COLORSCAD} -i "$INPUT" -o "$OUTPUT" -j 4 > >(sed 's/^/ /') 2>&1
unset openscad
(
if "$OPENSCAD_CMD" --help 2>&1 | grep -q predictible-output; then
export OPENSCAD_CMD_ORG=${OPENSCAD_CMD}
function openscad_test_override { "$OPENSCAD_CMD_ORG" --enable=predictible-output "$@"; }
export -f openscad_test_override
export OPENSCAD_CMD=openscad_test_override
fi
${COLORSCAD} -i "$INPUT" -o "$OUTPUT" -j 4 > >(sed 's/^/ /') 2>&1
)

# Canonicalize the expectation and output, so they can be compared
rm -Rf "${TEMPDIR}/exp" "${TEMPDIR}/out"
Expand All @@ -160,8 +166,8 @@ function test_render {


# Make sure there's something to test
if ! command -v openscad &> /dev/null; then
echo "Error: openscad command not found! Make sure it's in your PATH."
if ! command -v "$OPENSCAD_CMD" &> /dev/null; then
echo "Error: ${OPENSCAD_CMD} command not found! Make sure it's in your PATH."
exit 1
fi

Expand Down Expand Up @@ -189,19 +195,21 @@ echo "Testing bad weather:"
${COLORSCAD} -i color.scad -o wrong.ext | grep_q "the output file's extension must be one of 'amf' or '3mf'"
(
function command {
if [ "$1" = -v ] && [ "$2" = openscad ]; then return 1; fi
if [ "$1" = -v ] && [ "$2" = "$OPENSCAD_CMD" ]; then return 1; fi
builtin command "$@"
}
export -f command
${COLORSCAD} -i color.scad -o output.amf | grep_q 'openscad command not found'
${COLORSCAD} -i color.scad -o output.amf | grep_q "${OPENSCAD_CMD} command not found"
)
OPENSCAD_CMD=i_am_not_here ${COLORSCAD} -i color.scad -o output.amf | grep_q 'i_am_not_here command not found'
(
trap 'echo "Failure on line $LINENO"; exit 1' ERR
# If 'openscad --info' does not list 3mf support, it's a warning (followed by an abort due to this mock not producing output)
function openscad { :; }
export -f openscad
function openscad_test_override { :; }
export -f openscad_test_override
export OPENSCAD_CMD=openscad_test_override
${COLORSCAD} -i color.scad -o output.3mf | grep_q 'Warning: your openscad version does not seem to have 3MF support'
function openscad { echo "lib3mf version: (not enabled)"; }
function openscad_test_override { echo "lib3mf version: (not enabled)"; }
${COLORSCAD} -i color.scad -o output.3mf | grep_q 'Warning: your openscad version does not seem to have 3MF support'
)
echo 'cheese' > syntax_error.scad
Expand Down

0 comments on commit dd0bfe0

Please sign in to comment.