Skip to content

Commit 2b377b6

Browse files
committed
Building meshes with proper UVs is now solved! Having minimal vertices, is not.
1 parent bcca632 commit 2b377b6

2 files changed

Lines changed: 60 additions & 54 deletions

File tree

io_xplane2blender/importer/xplane_imp_cmd_builder.py

Lines changed: 59 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -238,58 +238,59 @@ class IntermediateDatablock:
238238
children: List["IntermediateDatablock"] = field(default_factory=list)
239239

240240
def build_mesh(self, vt_table: "VTTable") -> bpy.types.Mesh:
241+
"""
242+
Builds a mesh from the OBJ's VT Table, raises ValueError if
243+
an object with that mesh couldn't be built
244+
"""
241245
mesh_idxes = vt_table.idxes[self.start_idx : self.start_idx + self.count]
242-
idx_mapping: Dict[int, int] = {}
243-
vertices: List[VT] = []
244-
245-
for mesh_idx in mesh_idxes:
246-
if mesh_idx not in idx_mapping:
247-
idx_mapping[mesh_idx] = len(idx_mapping)
248-
vertices.append(vt_table.vertices[mesh_idx])
249246

250247
# Thanks senderle, https://stackoverflow.com/a/22045226
251248
def chunk(it, size):
252249
it = iter(it)
253250
return iter(lambda: tuple(itertools.islice(it, size)), ())
254251

255-
py_vertices = [(v.x, v.y, v.z) for v in vertices]
252+
py_vertices = [(v.x, v.y, v.z) for v in vt_table.vertices]
256253
py_faces: List[Tuple[int, int, int]] = [
257254
# We reverse the winding order to reverse the faces
258-
[idx_mapping[idx] for idx in face][::-1]
259-
for i, face in enumerate(chunk(mesh_idxes, 3))
255+
face[::-1]
256+
for face in chunk(mesh_idxes, 3)
260257
]
261258

262-
ob = test_creation_helpers.create_datablock_mesh(
263-
self.datablock_info,
264-
mesh_src=test_creation_helpers.From_PyData(
265-
py_vertices,
266-
[],
267-
py_faces,
268-
),
269-
)
270-
me = ob.data
271-
me.update(calc_edges=True)
272-
uv_layer = me.uv_layers[0] # .new()
273-
274-
i = 0
275-
if not me.validate(verbose=True):
276-
for face in py_faces:
277-
for idx in face:
278-
me.vertices[idx].normal = (
279-
vertices[idx].nx,
280-
vertices[idx].ny,
281-
vertices[idx].nz,
282-
)
283-
uv_layer.data[idx].uv = vertices[idx].s, vertices[idx].t
284-
if "body" in ob.name:
285-
# print(i, "uv", uv_layer.data[idx].uv)
286-
pass
287-
i += 1
288-
else:
289-
logger.error("Mesh was not valid, check console for more")
259+
normals = [(v.nx, v.ny, v.nz) for v in vt_table.vertices]
260+
uvs = [(v.s, v.t) for v in vt_table.vertices]
261+
262+
print(f"len(py_vertices)", len(py_vertices))
263+
print(f"len(py_faces)", len(py_faces))
264+
265+
me = bpy.data.meshes.new(self.name)
266+
me.from_pydata(py_vertices, [], py_faces)
267+
268+
if True or not me.validate(verbose=True):
269+
# Thanks Dave Prue and their "Import X-Plane Object" addon for the API example
270+
me.uv_layers.new()
271+
me.uv_layers[-1].data.foreach_set(
272+
"uv",
273+
[uv for pair in [uvs[l.vertex_index] for l in me.loops] for uv in pair],
274+
)
275+
276+
# Is this right?
277+
for i, vertex in enumerate(me.vertices):
278+
vertex.normal = normals[i]
290279

291-
test_creation_helpers.set_material(ob, "Material")
292-
return ob
280+
me.calc_normals()
281+
me.update(calc_edges=True)
282+
ob = test_creation_helpers.create_datablock_mesh(
283+
self.datablock_info,
284+
mesh_src=me,
285+
)
286+
test_creation_helpers.set_material(ob, "Material")
287+
288+
return ob
289+
else:
290+
logger.error(
291+
f"Mesh was not valid, object '{self.name}' not made, check console for more"
292+
)
293+
raise ValueError
293294

294295
@property
295296
def name(self) -> str:
@@ -898,9 +899,10 @@ def merge_show_hide_animations():
898899

899900
# end def optimize_empty_chain
900901
print(f"IN {intermediate_block.name}")
901-
out_block, blocks_rem_itr = optimize_empty_chain(
902-
intermediate_block, blocks_rem_itr
903-
)
902+
out_block = intermediate_block
903+
# out_block, blocks_rem_itr = optimize_empty_chain(
904+
# intermediate_block, blocks_rem_itr
905+
# )
904906

905907
print(
906908
f"OUT {out_block.name}, parent: {out_block.parent}, type: {out_block.datablock_type}"
@@ -1004,20 +1006,24 @@ def fill_in_eulers(
10041006
out_block.datablock_info
10051007
)
10061008
elif out_block.datablock_type == "MESH":
1007-
ob = out_block.build_mesh(self.vt_table)
1009+
try:
1010+
ob = out_block.build_mesh(self.vt_table)
1011+
except ValueError:
1012+
ob = None
10081013

1009-
ob.matrix_local = out_block.bake_matrix.copy()
1010-
bpy.context.view_layer.update()
1014+
if ob:
1015+
ob.matrix_local = out_block.bake_matrix.copy()
1016+
bpy.context.view_layer.update()
10111017

1012-
ob.rotation_mode = out_block.rotation_mode
1018+
ob.rotation_mode = out_block.rotation_mode
10131019

1014-
try:
1015-
out_block.transform_animation.apply_animation(ob)
1016-
except AttributeError: # No transform animation
1017-
pass
1020+
try:
1021+
out_block.transform_animation.apply_animation(ob)
1022+
except AttributeError: # No transform animation
1023+
pass
10181024

1019-
for animation in out_block.show_hide_animations:
1020-
animation.apply_animation(ob)
1025+
for animation in out_block.show_hide_animations:
1026+
animation.apply_animation(ob)
10211027

10221028
# end while for searching remaining blocks
10231029
# TODO: Unit test, and what about a bunch of animations that get optimized out with not TRIS blocks?

io_xplane2blender/importer/xplane_imp_parser.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ def import_obj(filepath: Union[pathlib.Path, str]) -> str:
113113
if skip:
114114
continue
115115

116-
# print(lineno, directive, components)
116+
# print(lineno, directive, components)
117117

118118
# TODO: Rewrite using giant switch-ish table and functions so it is more neat
119119
# Need scanf solution

0 commit comments

Comments
 (0)