Skip to content

Instantly share code, notes, and snippets.

@EleotleCram
Created April 13, 2021 19:06
Show Gist options
  • Save EleotleCram/a8be83aca555fd92e906a797ee8ff40f to your computer and use it in GitHub Desktop.
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.
#! /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