# Path: trimesh/interfaces/generic.py
# class MeshScript:
# 
#     def __init__(self,
#                  meshes,
#                  script):
#         self.meshes = meshes
#         self.script = script
# 
#     def __enter__(self):
#         # windows has problems with multiple programs using open files so we close
#         # them at the end of the enter call, and delete them ourselves at the
#         # exit
#         self.mesh_pre = [NamedTemporaryFile(suffix='.STL',
#                                             mode='wb',
#                                             delete=False) for i in self.meshes]
#         self.mesh_post = NamedTemporaryFile(suffix='.STL',
#                                             mode='rb',
#                                             delete=False)
#         self.script_out = NamedTemporaryFile(mode='wb',
#                                              delete=False)
# 
#         # export the meshes to a temporary STL container
#         for mesh, file_obj in zip(self.meshes, self.mesh_pre):
#             mesh.export(file_type='stl', file_obj=file_obj.name)
# 
#         self.replacement = {
#             'mesh_' + str(i): m.name for i, m in enumerate(self.mesh_pre)}
#         self.replacement['mesh_pre'] = str([i.name for i in self.mesh_pre])
#         self.replacement['mesh_post'] = self.mesh_post.name
#         self.replacement['script'] = self.script_out.name
# 
#         script_text = Template(self.script).substitute(self.replacement)
#         self.script_out.write(script_text.encode('utf-8'))
# 
#         # close all temporary files
#         self.script_out.close()
#         self.mesh_post.close()
#         for file_obj in self.mesh_pre:
#             file_obj.close()
#         return self
# 
#     def run(self, command):
#         command_run = Template(command).substitute(self.replacement).split()
#         # run the binary
#         check_call(command_run)
# 
#         # bring the binaries result back as a Trimesh object
#         with open(self.mesh_post.name, mode='rb') as file_obj:
#             mesh_result = load_stl(file_obj)
#         return mesh_result
# 
#     def __exit__(self, *args, **kwargs):
#         # delete all the temporary files by name
#         # they are closed but their names are still available
#         remove(self.script_out.name)
#         for file_obj in self.mesh_pre:
#             remove(file_obj.name)
#         remove(self.mesh_post.name)


from .generic import MeshScript
from distutils.spawn import find_executable

_scad_executable = find_executable('openscad')
exists = _scad_executable is not None


def interface_scad(meshes, script):
    '''
    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.

    Arguments
    ---------
    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!')

# Path: trimesh/interfaces/generic.py
# class MeshScript:
# 
#     def __init__(self,
#                  meshes,
#                  script):
#         self.meshes = meshes
#         self.script = script
# 
#     def __enter__(self):
#         # windows has problems with multiple programs using open files so we close
#         # them at the end of the enter call, and delete them ourselves at the
#         # exit
#         self.mesh_pre = [NamedTemporaryFile(suffix='.STL',
#                                             mode='wb',
#                                             delete=False) for i in self.meshes]
#         self.mesh_post = NamedTemporaryFile(suffix='.STL',
#                                             mode='rb',
#                                             delete=False)
#         self.script_out = NamedTemporaryFile(mode='wb',
#                                              delete=False)
# 
#         # export the meshes to a temporary STL container
#         for mesh, file_obj in zip(self.meshes, self.mesh_pre):
#             mesh.export(file_type='stl', file_obj=file_obj.name)
# 
#         self.replacement = {
#             'mesh_' + str(i): m.name for i, m in enumerate(self.mesh_pre)}
#         self.replacement['mesh_pre'] = str([i.name for i in self.mesh_pre])
#         self.replacement['mesh_post'] = self.mesh_post.name
#         self.replacement['script'] = self.script_out.name
# 
#         script_text = Template(self.script).substitute(self.replacement)
#         self.script_out.write(script_text.encode('utf-8'))
# 
#         # close all temporary files
#         self.script_out.close()
#         self.mesh_post.close()
#         for file_obj in self.mesh_pre:
#             file_obj.close()
#         return self
# 
#     def run(self, command):
#         command_run = Template(command).substitute(self.replacement).split()
#         # run the binary
#         check_call(command_run)
# 
#         # bring the binaries result back as a Trimesh object
#         with open(self.mesh_post.name, mode='rb') as file_obj:
#             mesh_result = load_stl(file_obj)
#         return mesh_result
# 
#     def __exit__(self, *args, **kwargs):
#         # delete all the temporary files by name
#         # they are closed but their names are still available
#         remove(self.script_out.name)
#         for file_obj in self.mesh_pre:
#             remove(file_obj.name)
#         remove(self.mesh_post.name)


# Path: trimesh/interfaces/scad.py
from .generic import MeshScript
from distutils.spawn import find_executable


_scad_executable = find_executable('openscad')
exists = _scad_executable is not None


def interface_scad(meshes, script):
    '''
    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.

    Arguments
    ---------
    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!')

    with MeshScript(meshes=meshes, script=script) as scad: