Exemple #1
0
def _load(f, mesh=None):
    import numpy as np
    from lace.mesh import Mesh
    if not mesh:
        mesh = Mesh()
    faces = []
    facenormals = []
    verts = []

    head = f.readline().strip()
    if head.startswith("solid"):  # ascii STL format
        #name = head[6:]
        current_face = []
        for line in f:
            line = line.split()
            if line[0] == "endsolid":
                break
            elif line[0] == "facet":
                current_face = []
                if line[1] == "normal":
                    try:
                        facenormals.append([float(x) for x in line[2:]])
                    except:  # pylint: disable=bare-except
                        facenormals.append([np.nan, np.nan, np.nan])
                else:
                    facenormals.append([np.nan, np.nan, np.nan])
            elif line[0] == "endfacet":
                faces.append(current_face)
                current_face = []
            elif line[0:2] == ["outer", "loop"]:
                pass
            elif line[0] == "endloop":
                pass
            elif line[0] == "vertex":
                current_face.append(len(verts))
                try:
                    verts.append([float(x) for x in line[1:]])
                except:  # pylint: disable=bare-except
                    verts.append([np.nan, np.nan, np.nan])
            else:
                raise ValueError(
                    "Badly formatted STL file. I don't understand the line %s"
                    % line)
    else:
        raise Exception(
            "Looks like this is a binary STL file; you're going to have to implement that"
        )
        # format docs are here: http://en.wikipedia.org/wiki/STL_(file_format)

    mesh.v = np.array(verts, dtype=np.float64).copy()
    mesh.f = np.array(faces, dtype=np.uint32).copy()
    mesh.fn = np.array(facenormals, dtype=np.float64).copy()
    return mesh
Exemple #2
0
def _load(f, mesh=None):
    import numpy as np
    from lace.mesh import Mesh
    from lace.serialization.ply import plyutils
    res = plyutils.read(f.name)
    if not mesh:
        mesh = Mesh()
    mesh.v = np.array(res['pts'], dtype=np.float64).T.copy()
    mesh.f = np.array(res['tri'], dtype=np.uint32).T.copy()

    if not mesh.f.shape[0]:
        mesh.f = None

    if 'color' in res:
        mesh.vc = np.array(res['color']).T.copy() / 255
    if 'normals' in res:
        mesh.vn = np.array(res['normals']).T.copy()
    return mesh
Exemple #3
0
def _load(f, mesh=None):
    from lace.mesh import Mesh

    try:
        v, f, vn, vc = _parse_wrl(f)
    except Exception:
        import traceback
        tb = traceback.format_exc()
        raise ParseError("Unable to parse wrl file with exception : \n[\n%s]" %
                         tb)

    if not mesh:
        mesh = Mesh()
    if v.size != 0:
        mesh.v = v
    if f.size != 0:
        mesh.f = f
    if vn.size != 0:
        mesh.vn = vn
    if vc.size != 0:
        mesh.vc = vc
    return mesh
Exemple #4
0
    def downsampled_mesh(self, step):
        """Returns a downsampled copy of this mesh.

        Args:
            step: the step size for the sampling

        Returns:
            a new, downsampled Mesh object.

        Raises:
            ValueError if this Mesh has faces.
        """
        from lace.mesh import Mesh

        if self.f is not None:
            raise ValueError(
                'Function `downsampled_mesh` does not support faces.')

        low = Mesh()
        if self.v is not None:
            low.v = self.v[::step]
        if self.vc is not None:
            low.vc = self.vc[::step]
        return low
Exemple #5
0
 def test_predict_body_units_cm(self):
     mesh = Mesh()
     mesh.v = np.array([[150, 100, 50], [-150, 50, 150]])
     self.assertEqual(mesh.predict_body_units(), 'cm')
Exemple #6
0
 def test_predict_body_units_m(self):
     mesh = Mesh()
     mesh.v = np.array([[1.5, 1.0, 0.5], [-1.5, 0.5, 1.5]])
     self.assertEqual(mesh.predict_body_units(), 'm')
Exemple #7
0
 def test_v_converts_datatype(self):
     m = Mesh()
     m.v = np.array([[1, 1, 1]], dtype=np.uint32)
     self.assertEqual(m.v.dtype, np.float64)
Exemple #8
0
def _load(fd, mesh=None):
    from collections import OrderedDict
    from baiji import s3
    from lace.mesh import Mesh
    from lace.cache import sc
    import lace.serialization.obj.objutils as objutils  # pylint: disable=no-name-in-module

    v, vt, vn, vc, f, ft, fn, mtl_path, landm, segm = objutils.read(fd.name)
    if not mesh:
        mesh = Mesh()
    if v.size != 0:
        mesh.v = v
    if f.size != 0:
        mesh.f = f
    if vn.size != 0:
        mesh.vn = vn
    if vt.size != 0:
        mesh.vt = vt
    if vc.size != 0:
        mesh.vc = vc
    if fn.size != 0:
        mesh.fn = fn
    if ft.size != 0:
        mesh.ft = ft
    if segm:
        mesh.segm = OrderedDict([(k, v if isinstance(v, list) else v.tolist())
                                 for k, v in segm.items()])

    def path_relative_to_mesh(filename):
        # The OBJ file we're loading may have come from a local path, an s3 url,
        # or a file cached by sc. Since OBJ defines materials and texture files
        # with paths relative to the OBJ itself, we need to cope with the various
        # possibilities and if it's a cached file make sure that the material and
        # texture have been downloaded as well.
        #
        # If an absolute path is given and the file is missing, try looking in the same directory;
        # this lets you find the most common intention when an abs path is used.
        #
        # NB: We do not support loading material & texture info from objs read
        # from filelike objects without a location on the filesystem; what would
        # the relative file names mean in that case, anyway? (unless we're given
        # a valid absolute path, in which case go for it)
        import os
        import re

        # The second term here let's us detect windows absolute paths when we're running on posix
        if filename == os.path.abspath(filename) or re.match(
                r'^.\:(\\|/)', filename):
            if s3.exists(filename):
                return filename
            else:
                filename = s3.path.basename(filename)

        if hasattr(fd, 'remotename'):
            mesh_path = fd.remotename
        elif hasattr(fd, 'name'):
            mesh_path = fd.name
        else:
            return None

        path = s3.path.join(s3.path.dirname(mesh_path), filename)
        if sc.is_cachefile(mesh_path):
            try:
                return sc(path)
            except s3.KeyNotFound:
                return None
        return path

    mesh.materials_filepath = None
    if mtl_path:
        materials_filepath = path_relative_to_mesh(mtl_path.strip())
        if materials_filepath and s3.exists(materials_filepath):
            with s3.open(materials_filepath, 'r') as f:
                mesh.materials_file = f.readlines()
            mesh.materials_filepath = materials_filepath

    if hasattr(mesh, 'materials_file'):
        mesh.texture_filepaths = {
            line.split(None, 1)[0].strip():
            path_relative_to_mesh(line.split(None, 1)[1].strip())
            for line in mesh.materials_file if line.startswith('map_K')
        }
        if 'map_Ka' in mesh.texture_filepaths:
            mesh.texture_filepath = mesh.texture_filepaths['map_Ka']
        elif 'map_Kd' in mesh.texture_filepaths:
            mesh.texture_filepath = mesh.texture_filepaths['map_Kd']

    if landm:
        mesh.landm = landm
    return mesh