|
31 | 31 | # ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
32 | 32 | # POSSIBILITY OF SUCH DAMAGE. |
33 | 33 | # ---------------------------------------------------------------------------- |
34 | | -import os |
35 | | - |
36 | | -import pywavefront.material |
37 | | -import pywavefront.mesh |
38 | | -import pywavefront.parser |
39 | | - |
40 | | - |
41 | | -class PywavefrontException(Exception): |
42 | | - pass |
43 | | - |
44 | | - |
45 | | -class Wavefront(object): |
46 | | - """Import a wavefront .obj file.""" |
47 | | - def __init__(self, file_name): |
48 | | - self.file_name = file_name |
49 | | - |
50 | | - self.materials = {} |
51 | | - self.meshes = {} # Name mapping |
52 | | - self.mesh_list = [] # Also includes anonymous meshes |
53 | | - |
54 | | - ObjParser(self, self.file_name) |
55 | | - |
56 | | - def draw(self): |
57 | | - for this_mesh in self.mesh_list: |
58 | | - this_mesh.draw() |
59 | | - |
60 | | - def add_mesh(self, the_mesh): |
61 | | - self.mesh_list.append(the_mesh) |
62 | | - self.meshes[the_mesh.name] = the_mesh |
63 | | - |
64 | | - |
65 | | -class ObjParser(parser.Parser): |
66 | | - """This parser parses lines from .obj files.""" |
67 | | - |
68 | | - def __init__(self, wavefront, file_name): |
69 | | - super(ObjParser, self).__init__(file_name) |
70 | | - self.wavefront = wavefront |
71 | | - |
72 | | - self.mesh = None |
73 | | - self.material = None |
74 | | - self.vertices = [[0., 0., 0.]] |
75 | | - self.normals = [[0., 0., 0.]] |
76 | | - self.tex_coords = [[0., 0.]] |
77 | | - self.read_file() |
78 | | - |
79 | | - # methods for parsing types of wavefront lines |
80 | | - def parse_v(self, args): |
81 | | - self.vertices.append(list(map(float, args[0:3]))) |
82 | | - |
83 | | - def parse_vn(self, args): |
84 | | - self.normals.append(list(map(float, args[0:3]))) |
85 | | - |
86 | | - def parse_vt(self, args): |
87 | | - self.tex_coords.append(list(map(float, args[0:2]))) |
88 | | - |
89 | | - def parse_mtllib(self, args): |
90 | | - mtllib = os.path.join(self.dir, " ".join(args)) |
91 | | - materials = material.MaterialParser(mtllib).materials |
92 | | - for material_name, material_object in materials.items(): |
93 | | - self.wavefront.materials[material_name] = material_object |
94 | | - |
95 | | - def parse_usemtl(self, args): |
96 | | - [usemtl] = args |
97 | | - self.material = self.wavefront.materials.get(usemtl, None) |
98 | | - if self.material is None: |
99 | | - raise PywavefrontException('Unknown material: %s' % args[0]) |
100 | | - if self.mesh is not None: |
101 | | - self.mesh.add_material(self.material) |
102 | | - |
103 | | - def parse_usemat(self, args): |
104 | | - self.parse_usemtl(args) |
105 | | - |
106 | | - def parse_o(self, args): |
107 | | - [o] = args |
108 | | - self.mesh = mesh.Mesh(o) |
109 | | - self.wavefront.add_mesh(self.mesh) |
110 | | - |
111 | | - def parse_f(self, args): |
112 | | - if (len(self.tex_coords) > 1) and (len(self.normals) == 1): |
113 | | - # does the spec allow for texture coordinates without normals? |
114 | | - # if we allow this condition, the user will get a black screen |
115 | | - # which is really confusing |
116 | | - raise PywavefrontException('Found texture coordinates, but no normals') |
117 | | - |
118 | | - if self.mesh is None: |
119 | | - self.mesh = mesh.Mesh() |
120 | | - self.wavefront.add_mesh(self.mesh) |
121 | | - if self.material is None: |
122 | | - self.material = material.Material() |
123 | | - self.wavefront.materials[self.material.name] = self.material |
124 | | - self.mesh.add_material(self.material) |
125 | | - |
126 | | - # For fan triangulation, remember first and latest vertices |
127 | | - v1 = None |
128 | | - vlast = None |
129 | | - for i, v in enumerate(args[0:]): |
130 | | - if type(v) is bytes: |
131 | | - v = v.decode() |
132 | | - v_index, t_index, n_index = \ |
133 | | - (list(map(int, [j or 0 for j in v.split('/')])) + [0, 0])[:3] |
134 | | - if v_index < 0: |
135 | | - v_index += len(self.vertices) - 1 |
136 | | - if t_index < 0: |
137 | | - t_index += len(self.tex_coords) - 1 |
138 | | - if n_index < 0: |
139 | | - n_index += len(self.normals) - 1 |
140 | | - vertex = list(self.tex_coords[t_index]) + \ |
141 | | - list(self.normals[n_index]) + \ |
142 | | - list(self.vertices[v_index]) |
143 | | - |
144 | | - if i >= 3: |
145 | | - # Triangulate |
146 | | - self.material.vertices += v1 + vlast |
147 | | - self.material.vertices += vertex |
148 | | - |
149 | | - if i == 0: |
150 | | - v1 = vertex |
151 | | - vlast = vertex |
| 34 | +from pywavefront.exceptions import PywavefrontException |
| 35 | +from pywavefront.obj import ObjParser |
| 36 | +from pywavefront.wavefront import Wavefront |
0 commit comments