hub/venv/lib/python3.7/site-packages/trimesh/interfaces/generic.py

113 lines
3.7 KiB
Python
Raw Normal View History

import os
import logging
import platform
import subprocess
from string import Template
from tempfile import NamedTemporaryFile
from subprocess import check_call
from .. import exchange
# create a default logger
log = logging.getLogger('trimesh.interfaces')
class MeshScript:
def __init__(self,
meshes,
script,
exchange='stl',
debug=False,
**kwargs):
self.debug = debug
self.kwargs = kwargs
self.meshes = meshes
self.script = script
self.exchange = exchange
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='.{}'.format(
self.exchange),
mode='wb',
delete=False) for i in self.meshes]
self.mesh_post = NamedTemporaryFile(
suffix='.{}'.format(
self.exchange),
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_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)
if platform.system() == 'Windows':
script_text = script_text.replace('\\', '\\\\')
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
# avoid resourcewarnings with null
with open(os.devnull, 'w') as devnull:
startupinfo = None
if platform.system() == 'Windows':
startupinfo = subprocess.STARTUPINFO()
startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW
if self.debug:
# in debug mode print the output
stdout = None
else:
stdout = devnull
if self.debug:
log.info('executing: {}'.format(' '.join(command_run)))
check_call(command_run,
stdout=stdout,
stderr=subprocess.STDOUT,
startupinfo=startupinfo)
# bring the binaries result back as a set of Trimesh kwargs
mesh_results = exchange.load.load_mesh(self.mesh_post.name,
**self.kwargs)
return mesh_results
def __exit__(self, *args, **kwargs):
if self.debug:
log.info('MeshScript.debug: not deleting {}'.format(
self.script_out.name))
return
# delete all the temporary files by name
# they are closed but their names are still available
os.remove(self.script_out.name)
for file_obj in self.mesh_pre:
os.remove(file_obj.name)
os.remove(self.mesh_post.name)