Created
April 13, 2021 19:06
-
-
Save EleotleCram/a8be83aca555fd92e906a797ee8ff40f to your computer and use it in GitHub Desktop.
Automation utility for conversion of CAD input files (.step, etc.) to .obj files using CAD Assistant, xdotool and xprop.
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
#! /bin/bash | |
# Auto CAD Assistant - Automation utility for conversion of CAD input files (.step, etc.) to .obj | |
# files using CAD Assistant, xdotool and xprop. Just give it a bunch of input CAD files and behold | |
# the robot as it automatically navigates and operates CAD Assistant. | |
# MIT License | |
# | |
# Copyright (c) 2021 Marcel Toele | |
# | |
# Permission is hereby granted, free of charge, to any person obtaining a copy | |
# of this software and associated documentation files (the "Software"), to deal | |
# in the Software without restriction, including without limitation the rights | |
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | |
# copies of the Software, and to permit persons to whom the Software is | |
# furnished to do so, subject to the following conditions: | |
# | |
# The above copyright notice and this permission notice shall be included in all | |
# copies or substantial portions of the Software. | |
# | |
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | |
# SOFTWARE. | |
DEBUG=false | |
PROGNAME="$(basename "$0")" | |
# Path to CAD Assistant binary (or, in this case, an alias): | |
CADASS=cadass | |
usage() { | |
echo -e "Usage:\n\n\t${PROGNAME} FILE [FILE ...]\n" 1>&2 | |
} | |
die() { | |
echo -e "${PROGNAME}: $1" 1>&2 | |
exit 1 | |
} | |
try_for_x_sec() { | |
x=$1 | |
t0=$(date +%s) | |
tEnd=$( expr $t0 + $x ) | |
shift | |
while [ $(date +%s) -lt $tEnd ] ; do | |
$DEBUG && echo ">>> $@ <<<" 1>&2 | |
stdout=$("$@") | |
if [ $? -eq 0 ] ; then | |
$DEBUG && echo "Success" 1>&2 | |
echo "${stdout}" | |
return 0 | |
else | |
$DEBUG && echo "No success yet..." 1>&2 | |
fi | |
sleep 1 | |
done | |
die "try_for_x_sec: Error: The following commands never succeeded (exiting before bad things happen...):\n\n\t\t$*\n" | |
} | |
click_at() { | |
x=$1 | |
y=$2 | |
xdotool mousemove $x $y | |
xdotool click 1 | |
} | |
as_keys() { | |
echo "${1}" | sed ' | |
s/ / ~/g; | |
s/\([^ ]\)/ \1/g; | |
s/~/space/g; | |
s/[.]/period/g; | |
s/[,]/comma/g; | |
s/[+]/plus/g; | |
s/[-]/minus/g; | |
s/[_]/underscore/g; | |
s/[:]/colon/g; | |
s/[;]/semicolon/g; | |
s/[(]/parenleft/g; | |
s/[)]/parenright/g; | |
s/[{}]/braceleft/g; | |
s/[}]/braceright/g; | |
s/\[/bracketleft/g; | |
s/\]/bracketright/g; | |
s/[<]/less/g; | |
s/[=]/equal/g; | |
s/[>]/greater/g; | |
s/[?]/question/g; | |
s/\^/asciicirum/g; | |
s/[#]/numbersign/g; | |
s/[$]/dollar/g; | |
s/[%]/percent/g; | |
s/[&]/ampersand/g; | |
' | |
} | |
convert_file() { | |
file="$1" | |
outfile="${file%.*}.obj" | |
if [ -e "${outfile}" ] ; then | |
echo "\"${outfile}\" already exists, skipping..." | |
return 0 | |
fi | |
if xdotool search --onlyvisible --name "CAD Assistant" > /dev/null ; then | |
die "Existing CAD Assistent detected, please close this one first." | |
fi | |
outfile_basename="$(basename "${outfile}")" | |
outfile_basename_keys="$(as_keys "${outfile_basename}")" | |
$DEBUG && echo -e "${file}\n\t-> ${outfile}\n\t-> ${outfile_basename}\n\t-> ${outfile_basename_keys}\n" | |
# Open CAD Assistant and load model: | |
$CADASS "${file}" &> /dev/null & | |
cadass_pid=$! | |
# Find CAD Assistant window id: | |
cadass_win_id=$(try_for_x_sec 10 xdotool search --onlyvisible --name "^Import.*CAD Assistant") | |
$DEBUG && echo "cadass_win_id: ${cadass_win_id} $(xdotool getwindowname ${cadass_win_id})" | |
# Wait until CAD Assistant is done importing the model: | |
# (This '[^Ii]...*' approach is not ideal, but it'll have to do) | |
try_for_x_sec 10 xdotool search --onlyvisible --name "^[^Ii][^Mm][^Pp][^Oo][^Rr][^Tt].*CAD Assistant" > /dev/null | |
# Turn off window decorations and give the window well-defined and known geometry, | |
# so that click offsets become deterministic: | |
try_for_x_sec 2 xprop -id ${cadass_win_id} -format _MOTIF_WM_HINTS 32i -set _MOTIF_WM_HINTS 2 | |
try_for_x_sec 2 xdotool windowmove ${cadass_win_id} 0 0 | |
try_for_x_sec 2 xdotool windowsize ${cadass_win_id} 1000 600 | |
# Click save icon in menu: | |
click_at 25 150 | |
# Click file type: | |
click_at 768 600 | |
# Select OBJ: | |
click_at 763 210 | |
# click file name field: | |
click_at 458 600 | |
# Select all text: | |
xdotool key --window ${cadass_win_id} control+a | |
sleep 0.1 | |
# Type destination filename (without extension): | |
xdotool key --window ${cadass_win_id} ${outfile_basename_keys} | |
# Click on save icon in file dialog: | |
click_at 936 600 | |
# Wait until destination file exists on disk: | |
try_for_x_sec 10 ls -lah "${outfile}" | |
# Close CAD Assistant: | |
xdotool windowkill ${cadass_win_id} | |
} | |
$DEBUG && set -x | |
if [ "$#" -eq 0 ]; then | |
usage | |
die "Missing required argument" | |
fi | |
if [ "$1" = "-h" ] || [ "$1" = "--help" ]; then | |
usage | |
exit 0 | |
fi | |
for FILE in "$@"; do | |
convert_file "${FILE}" | |
done |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment