hub/venv/lib/python3.7/site-packages/trimesh/exchange/off.py

101 lines
2.8 KiB
Python

import re
import numpy as np
from .. import util
def load_off(file_obj, **kwargs):
"""
Load an OFF file into the kwargs for a Trimesh constructor
Parameters
----------
file_obj : file object
Contains an OFF file
Returns
----------
loaded : dict
kwargs for Trimesh constructor
"""
text = file_obj.read()
# will magically survive weird encoding sometimes
# comment strip will handle all cases of commenting
text = util.comment_strip(
util.decode_text(text)).strip()
# split the first key
_, header, raw = re.split('(COFF|OFF)', text, 1)
if header.upper() not in ['OFF', 'COFF']:
raise NameError(
'Not an OFF file! Header was: `{}`'.format(header))
# split into lines and remove whitespace
splits = [i.strip() for i in str.splitlines(str(raw))]
# remove empty lines
splits = [i for i in splits if len(i) > 0]
# the first non-comment line should be the counts
header = np.array(splits[0].split(), dtype=np.int64)
vertex_count, face_count = header[:2]
vertices = np.array([
i.split()[:3] for i in
splits[1: vertex_count + 1]],
dtype=np.float64)
# will fail if incorrect number of vertices loaded
vertices = vertices.reshape((vertex_count, 3))
# get lines with face data
faces = [i.split() for i in
splits[vertex_count + 1:vertex_count + face_count + 1]]
# the first value is count
faces = [line[1:int(line[0]) + 1] for line in faces]
# convert faces to numpy array
# will fail on mixed garbage as FSM intended -_-
faces = np.array(faces, dtype=np.int64)
# save data as kwargs for a trimesh.Trimesh
kwargs = {'vertices': vertices,
'faces': faces}
return kwargs
def export_off(mesh, digits=10):
"""
Export a mesh as an OFF file, a simple text format
Parameters
-----------
mesh : trimesh.Trimesh
Geometry to export
digits : int
Number of digits to include on floats
Returns
-----------
export : str
OFF format output
"""
# make sure specified digits is an int
digits = int(digits)
# prepend a 3 (face count) to each face
faces_stacked = np.column_stack((np.ones(len(mesh.faces)) * 3,
mesh.faces)).astype(np.int64)
export = 'OFF\n'
# the header is vertex count, face count, another number
export += str(len(mesh.vertices)) + ' ' + str(len(mesh.faces)) + ' 0\n'
export += util.array_to_string(
mesh.vertices, col_delim=' ', row_delim='\n', digits=digits) + '\n'
export += util.array_to_string(
faces_stacked, col_delim=' ', row_delim='\n')
return export
_off_loaders = {'off': load_off}
_off_exporters = {'off': export_off}