MCPcopy Create free account
hub / github.com/ICE27182/Python-3D-renderer / load_obj

Method load_obj

v1.0/renderer.py:22–126  ·  view source on GitHub ↗

Load mesh(es) from a given obj file

(filename, meshes, directory=".")

Source from the content-addressed store, hash-verified

20
21
22 def load_obj(filename, meshes, directory=".") -> dict:
23 """Load mesh(es) from a given obj file"""
24 def check_name_collision(name:str) -> str:
25 if name in meshes:
26 num = 2
27 while f"{name}_{num}" in meshes:
28 num += 1
29 print(f"There's a name collison with the mesh \"{name}\" in the file {filename}." +
30 f"So its name has been changed from \"{name}\" to \"{name}_{num}\"")
31 return f"{name}_{num}"
32 else:
33 return name
34 def relative_v_calculation(v):
35 return (v[0] - mesh.center[0], v[1] - mesh.center[1], v[2] - mesh.center[2])
36 outputs = {}
37 with open(f"{directory}\\{filename}", "r") as obj:
38 obj:str = obj.read()
39
40 if obj[0] == "#":
41 meshes_num = obj.count("\no ")
42 if meshes_num == 0:
43 meshes_num = 1
44 # Its name won't be defined later by o line, which doesn't exist. So are these max values
45 name = filename[:-4]
46 name = check_name_collision(name)
47 outputs[name] = Mesh(name)
48 v_max, vn_max, vt_max = 0, 0, 0,
49 elif obj[:2] == "v ":
50 meshes_num = 1
51 # Its name won't be defined later by o line, which doesn't exist. So are these max values
52 name = filename[:-4]
53 name = check_name_collision(name)
54 outputs[name] = Mesh(name)
55 v_max, vn_max, vt_max = 0, 0, 0,
56 elif obj[:2] == "o ":
57 # In case the mesh's name ends with "o ", not using obj.count("o ")
58 meshes_num = obj.count("\no ") + 1
59 else:
60 raise Exception("Idk what's in the file. So, check it.")
61
62 print(f"{meshes_num} {'meshes have' if meshes_num > 1 else 'mesh has'} been found in {filename}.")
63
64 obj = obj.split("\n")
65 v, vn, vt, = 0, 0, 0,
66
67 for line in obj:
68 if line == "" or line[0] in ("#", "\n", " "):
69 continue
70 elif line[0] == "f":
71 # f 1 2 3 or f 1//1 2//1 3//1 or f 1/2/1 2/3/1 3/2/1
72 line = line[2:].split()
73 if "//" in line[0]:
74 line = [[int(line[index].split("//")[0]) for index in range(len(line))], [], int(line[0].split("//")[-1])]
75 for index in range(len(line[0])):
76 line[0][index] -= (v_max + 1)
77 line[-1] -= (vn_max + 1)
78 outputs[name].f.append(line)
79 # 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

Callers

nothing calls this directly

Calls 2

MeshClass · 0.70
get_normalMethod · 0.45

Tested by

no test coverage detected