66 lines
2.4 KiB
Python
66 lines
2.4 KiB
Python
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)
|