| 1 | |
| 2 | |
| 3 | class Mesh: |
| 4 | def __init__(self, name, v=None, vn=None, vt=None, f=None,) -> None: |
| 5 | import math |
| 6 | self.sqrt = math.sqrt |
| 7 | self.sin = lambda x: math.sin(x * math.pi / 180) |
| 8 | self.cos = lambda x: math.cos(x * math.pi / 180) |
| 9 | self.name = name |
| 10 | self.v = [] if v == None else v |
| 11 | self.vn = [] if vn == None else vn |
| 12 | self.vt = [] if vt == None else vt |
| 13 | self.f = [] if f == None else f |
| 14 | if self.v != []: |
| 15 | def relative_v_calculation(v): |
| 16 | return (v[0] - self.center[0], v[1] - self.center[1], v[2] - self.center[2]) |
| 17 | self.center = list(map(sum, (zip(*self.v)))) |
| 18 | self.center = [self.center[i] / len(self.v) for i in range(3)] |
| 19 | self.relative_v = map(relative_v_calculation, self.v) |
| 20 | |
| 21 | |
| 22 | |
| 23 | def load_obj(filename, meshes, directory=".") -> dict: |
| 24 | """Load mesh(es) from a given obj file""" |
| 25 | def check_name_collision(name:str) -> str: |
| 26 | if name in meshes: |
| 27 | num = 2 |
| 28 | while f"{name}_{num}" in meshes: |
| 29 | num += 1 |
| 30 | print(f"There's a name collison with the mesh \"{name}\" in the file {filename}." + |
| 31 | f"So its name has been changed from \"{name}\" to \"{name}_{num}\"") |
| 32 | return f"{name}_{num}" |
| 33 | else: |
| 34 | return name |
| 35 | def relative_v_calculation(v): |
| 36 | return (v[0] - mesh.center[0], v[1] - mesh.center[1], v[2] - mesh.center[2]) |
| 37 | outputs = {} |
| 38 | with open(f"{directory}\\{filename}", "r") as obj: |
| 39 | obj:str = obj.read() |
| 40 | |
| 41 | if obj[0] == "#": |
| 42 | meshes_num = obj.count("\no ") |
| 43 | if meshes_num == 0: |
| 44 | meshes_num = 1 |
| 45 | # Its name won't be defined later by o line, which doesn't exist. So are these max values |
| 46 | name = filename[:-4] |
| 47 | name = check_name_collision(name) |
| 48 | outputs[name] = Mesh(name) |
| 49 | v_max, vn_max, vt_max = 0, 0, 0, |
| 50 | elif obj[:2] == "v ": |
| 51 | meshes_num = 1 |
| 52 | # Its name won't be defined later by o line, which doesn't exist. So are these max values |
| 53 | name = filename[:-4] |
| 54 | name = check_name_collision(name) |
| 55 | outputs[name] = Mesh(name) |
| 56 | v_max, vn_max, vt_max = 0, 0, 0, |
| 57 | elif obj[:2] == "o ": |
| 58 | # In case the mesh's name ends with "o ", not using obj.count("o ") |
| 59 | meshes_num = obj.count("\no ") + 1 |
| 60 | else: |