Source code for pyunity.loader

"""
Utility functions related to loading
and saving PyUnity meshes and scenes.

This will be imported as ``pyunity.Loader``.

"""

from .vector3 import Vector3
from .meshes import Mesh
from .core import *
from .scenes import SceneManager
from . import Logger
import pickle
import os
# import random

[docs]def LoadObj(filename): """ Loads a .obj file to a PyUnity mesh. Parameters ---------- filename : str Name of file Returns ------- Mesh A mesh of the object file """ vertices = [] normals = [] faces = [] for line in open(filename, "r"): if line.startswith("#"): continue values = line.split() if not values: continue if values[0] == "v": v = Vector3(float(values[1]), float(values[3]), float(values[2])) vertices.append(v) elif values[0] == "f": face = [] for v in values[1:]: w = v.split("/") face.append(int(w[0]) - 1) face.reverse() faces.append(face) for face in faces: a = vertices[face[2]] - vertices[face[1]] b = vertices[face[0]] - vertices[face[1]] normal = a.cross(b).normalized() normals.append(normal) return Mesh(vertices, faces, normals)
[docs]def LoadMesh(filename): """ Loads a .mesh file generated by `SaveMesh`. It is optimized for faster loading. Parameters ---------- filename : str Name of file relative to the cwd Returns ------- Mesh Generated mesh """ with open(filename, "r") as f: lines = list(map(lambda x: x.rstrip(), f.readlines())) if "" in lines: lines.remove("") vertices = list(map(float, lines[0].split("/"))) vertices = [ Vector3(vertices[i], vertices[i + 1], vertices[i + 2]) for i in range(0, len(vertices), 3) ] faces = list(map(int, lines[1].split("/"))) faces = [ [faces[i], faces[i + 1], faces[i + 2]] for i in range(0, len(faces), 3) ] normals = [] for face in faces: a = vertices[face[2]] - vertices[face[1]] b = vertices[face[0]] - vertices[face[1]] normal = a.cross(b).normalized() normals.append(normal) return Mesh(vertices, faces, normals)
[docs]def SaveMesh(mesh, name, filePath=None): """ Saves a mesh to a .mesh file for faster loading. Parameters ---------- mesh : Mesh Mesh to save name : str Name of the mesh filePath : str, optional Pass in `__file__` to save in directory of script, otherwise pass in the path of where you want to save the file. For example, if you want to save in C:\Downloads, then give "C:\Downloads\mesh.mesh". If not specified, then the mesh is saved in the cwd. """ if filePath: directory = os.path.dirname(os.path.realpath(filePath)) else: directory = os.getcwd() with open(os.path.join(directory, name + ".mesh"), "w+") as f: i = 0 for vertex in mesh.verts: i += 1 f.write(str(vertex.x) + "/") f.write(str(vertex.y) + "/") f.write(str(vertex.z)) if i != len(mesh.verts): f.write("/") f.write("\n") i = 0 for triangle in mesh.triangles: i += 1 j = 0 for item in triangle: j += 1 f.write(str(item)) if i != len(mesh.triangles) or j != 3: f.write("/") f.write("\n")
# def randomHex(length): # """ # Returns a random hexadecimal string of length `length`. # Parameters # ---------- # length : int # Length of string # Returns # ------- # str # A random hexadecimal string # """ # return ("%0" + str(length) + "x") % random.randrange(16 ** length) # def AddHex(l, length): # x = randomHex(length) # while x in l: x = randomHex(length) # l.append(x) # return x
[docs]def SaveScene(scene, filePath=None): """ Save a scene to a file. Uses pickle. Parameters ---------- scene : Scene Scene to save filePath : str, optional Pass in `__file__` to save in directory of script, otherwise pass in a directory. If not specified, then the scene is saved in the cwd. """ # hexes = [] # with open(scene.name + ".scene", "w+") as f: # for gameObject in scene.gameObjects: # f.write("GameObject (" + gameObject.name + ") " + AddHex(hexes, 24) + ":\n") # for component in gameObject.components: # f.write(" Component " + type(component).__name__ + " " + AddHex(hexes, 24) + ":\n") if filePath: directory = os.path.dirname(os.path.realpath(filePath)) else: directory = os.getcwd() with open(os.path.join(directory, scene.name + ".scene"), "wb+") as f: pickle.dump(scene, f)
[docs]def LoadScene(sceneName, filePath=None): """ Load a scene from a file. Uses pickle. Parameters ---------- sceneName : str Name of the scene, without the .scene extension Returns ------- Scene Loaded scene Notes ----- If there already is a scene called `sceneName`, then no scene will be added. """ if sceneName in SceneManager.scenesByName: Logger.LogLine(Logger.WARNING, "Already has scene called", sceneName) return if filePath: directory = os.path.dirname(os.path.realpath(filePath)) else: directory = os.getcwd() with open(os.path.join(directory, sceneName + ".scene"), "rb") as f: scene = pickle.load(f) SceneManager.scenesByIndex.append(scene) SceneManager.scenesByName[sceneName] = scene return scene
class Primitives: __path = os.path.dirname(os.path.realpath(__file__)) cube = LoadMesh(os.path.join(__path, "primitives/cube.mesh")) quad = LoadMesh(os.path.join(__path, "primitives/quad.mesh")) double_quad = LoadMesh(os.path.join(__path, "primitives/double_quad.mesh")) sphere = LoadMesh(os.path.join(__path, "primitives/sphere.mesh")) capsule = LoadMesh(os.path.join(__path, "primitives/capsule.mesh")) cylinder = LoadMesh(os.path.join(__path, "primitives/cylinder.mesh"))