Load mesh(es) from a given obj file
(filename, meshes, directory=".")
| 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: |
| 61 | raise Exception("Idk what's in the file. So, check it.") |
| 62 | |
| 63 | print(f"{meshes_num} {'meshes have' if meshes_num > 1 else 'mesh has'} been found in {filename}.") |
| 64 | |
| 65 | obj = obj.split("\n") |
| 66 | v, vn, vt, = 0, 0, 0, |
| 67 | |
| 68 | for line in obj: |
| 69 | if line == "" or line[0] in ("#", "\n", " "): |
| 70 | continue |
| 71 | elif line[0] == "f": |
| 72 | # f 1 2 3 or f 1//1 2//1 3//1 or f 1/2/1 2/3/1 3/2/1 |
| 73 | line = line[2:].split() |
| 74 | if "//" in line[0]: |
| 75 | line = [[int(line[index].split("//")[0]) for index in range(len(line))], [], int(line[0].split("//")[-1])] |
| 76 | for index in range(len(line[0])): |
| 77 | line[0][index] -= (v_max + 1) |
| 78 | line[-1] -= (vn_max + 1) |
| 79 | outputs[name].f.append(line) |
| 80 | # It is supposed to be cases like "f 1/2/1 2/3/1 3/2/1", but I'm not sure if things like "f 1/2/ 2/3/ 3/2/" exist, which would be a problem |
no test coverage detected