import os import platform from .generic import MeshScript from ..constants import log from distutils.spawn import find_executable # start the search with the user's PATH _search_path = os.environ['PATH'] # add additional search locations on windows if platform.system() == 'Windows': # split existing path by delimiter _search_path = [i for i in _search_path.split(';') if len(i) > 0] _search_path.append(os.path.normpath(r'C:\Program Files\OpenSCAD')) _search_path.append(os.path.normpath(r'C:\Program Files (x86)\OpenSCAD')) _search_path = ';'.join(_search_path) log.debug('searching for scad in: %s', _search_path) # add mac-specific search locations if platform.system() == 'Darwin': _search_path = [i for i in _search_path.split(':') if len(i) > 0] _search_path.append('/Applications/OpenSCAD.app/Contents/MacOS') _search_path = ':'.join(_search_path) log.debug('searching for scad in: %s', _search_path) # try to find the SCAD executable by name _scad_executable = find_executable('openscad', path=_search_path) if _scad_executable is None: _scad_executable = find_executable('OpenSCAD', path=_search_path) exists = _scad_executable is not None def interface_scad(meshes, script, debug=False, **kwargs): """ A way to interface with openSCAD which is itself an interface to the CGAL CSG bindings. CGAL is very stable if difficult to install/use, so this function provides a tempfile- happy solution for getting the basic CGAL CSG functionality. Parameters --------- meshes: list of Trimesh objects script: string of the script to send to scad. Trimesh objects can be referenced in the script as $mesh_0, $mesh_1, etc. """ if not exists: raise ValueError('No SCAD available!') # OFF is a simple text format that references vertices by-index # making it slightly preferable to STL for this kind of exchange duty with MeshScript(meshes=meshes, script=script, debug=debug, exchange='off') as scad: result = scad.run(_scad_executable + ' $SCRIPT -o $MESH_POST') return result def boolean(meshes, operation='difference', debug=False, **kwargs): """ Run an operation on a set of meshes """ script = operation + '(){' for i in range(len(meshes)): script += 'import(\"$MESH_' + str(i) + '\");' script += '}' return interface_scad(meshes, script, debug=debug, **kwargs)