1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122
|
# -*- coding: utf-8 -*-
# Copyright (c) Vispy Development Team. All Rights Reserved.
# Distributed under the (new) BSD License. See LICENSE.txt for more info.
"""Reading and writing of data like images and meshes."""
import os
from os import path as op
from .wavefront import WavefrontReader, WavefrontWriter
from .stl import load_stl
def read_mesh(fname):
"""Read mesh data from file.
Parameters
----------
fname : str
File name to read. Format will be inferred from the filename.
Currently only '.obj' and '.obj.gz' are supported.
Returns
-------
vertices : array
Vertices.
faces : array | None
Triangle face definitions.
normals : array
Normals for the mesh.
texcoords : array | None
Texture coordinates.
"""
# Check format
fmt = op.splitext(fname)[1].lower()
if fmt == '.gz':
fmt = op.splitext(op.splitext(fname)[0])[1].lower()
if fmt in ('.obj'):
return WavefrontReader.read(fname)
elif fmt in ('.stl'):
file_obj = open(fname, mode='rb')
mesh = load_stl(file_obj)
vertices = mesh['vertices']
faces = mesh['faces']
normals = mesh['face_normals']
texcoords = None
return vertices, faces, normals, texcoords
else:
try:
import meshio
except ImportError:
raise ValueError('read_mesh does not understand format %s.' % fmt)
try:
mesh = meshio.read(fname)
except meshio.ReadError:
raise ValueError('read_mesh does not understand format %s.' % fmt)
triangles = mesh.get_cells_type("triangle")
if len(triangles) == 0:
raise ValueError('mesh file does not contain triangles.')
return mesh.points, triangles, None, None
def write_mesh(fname, vertices, faces, normals, texcoords, name='',
format=None, overwrite=False, reshape_faces=True):
"""Write mesh data to file.
Parameters
----------
fname : str
Filename to write. Must end with ".obj" or ".gz".
vertices : array
Vertices.
faces : array | None
Triangle face definitions.
normals : array
Normals for the mesh.
texcoords : array | None
Texture coordinates.
name : str
Name of the object.
format : str
Currently only "obj" is supported.
overwrite : bool
If the file exists, overwrite it.
reshape_faces : bool
Reshape the `faces` array to (Nf, 3). Set to `False`
if you need to write a mesh with non triangular faces.
"""
# Check file
if op.isfile(fname) and not overwrite:
raise IOError('file "%s" exists, use overwrite=True' % fname)
if format is None:
format = os.path.splitext(fname)[1][1:]
# Check format
if format == 'obj':
WavefrontWriter.write(fname, vertices, faces,
normals, texcoords, name, reshape_faces)
return
try:
import meshio
except ImportError:
raise ValueError('write_mesh does not understand format %s.' % format)
cell_data = {}
if normals is not None:
cell_data["normals"] = [normals]
if texcoords is not None:
cell_data["texcoords"] = [texcoords]
mesh = meshio.Mesh(vertices, [("triangle", faces)], cell_data=cell_data)
try:
mesh.write(fname, file_format=format)
except meshio.WriteError:
raise ValueError('write_mesh does not understand format %s.' % format)
|