Fix T45184: OBJ importer would add UV or clnor layers to all objects in split-import case.

In case some parts have UVs and others not, when doing split import we have to
avoid creating empty dummy UV layers for meshes that have no 'tex' data in .obj.
Same goes for clnors.
This commit is contained in:
Bastien Montagne 2015-06-25 14:56:53 +02:00
parent 107df683a0
commit 4c1e066129
Notes: blender-bot 2023-02-14 19:55:23 +01:00
Referenced by issue #45184, export_obj issue when exporting .blend or unsaved project
2 changed files with 38 additions and 15 deletions

View File

@ -21,7 +21,7 @@
bl_info = {
"name": "Wavefront OBJ format",
"author": "Campbell Barton, Bastien Montagne",
"version": (2, 1, 1),
"version": (2, 1, 2),
"blender": (2, 74, 0),
"location": "File > Import-Export",
"description": "Import-Export OBJ, Import OBJ mesh, UV's, "

View File

@ -369,7 +369,7 @@ def split_mesh(verts_loc, faces, unique_materials, filepath, SPLIT_OB_OR_GROUP):
if not SPLIT_OB_OR_GROUP or not faces:
# use the filename for the object name since we aren't chopping up the mesh.
return [(verts_loc, faces, unique_materials, filename)]
return [(verts_loc, faces, unique_materials, filename, bool(verts_nor), bool(verts_tex))]
def key_to_name(key):
# if the key is a tuple, join it to make a string
@ -388,12 +388,19 @@ def split_mesh(verts_loc, faces, unique_materials, filepath, SPLIT_OB_OR_GROUP):
if oldkey != key:
# Check the key has changed.
(verts_split, faces_split,
unique_materials_split, vert_remap) = face_split_dict.setdefault(key, ([], [], {}, {}))
(verts_split, faces_split, unique_materials_split, vert_remap,
use_verts_nor, use_verts_tex) = face_split_dict.setdefault(key, ([], [], {}, {}, [], []))
oldkey = key
face_vert_loc_indices = face[0]
# In case a face only uses zero indices for vnors/vtex (aka UV), we assume it actually does not use those...
if not use_verts_nor and face[1]:
use_verts_nor.append(True)
if not use_verts_tex and face[2]:
use_verts_tex.append(True)
# Remap verts to new vert list and add where needed
for enum, i in enumerate(face_vert_loc_indices):
map_index = vert_remap.get(i)
@ -411,8 +418,9 @@ def split_mesh(verts_loc, faces, unique_materials, filepath, SPLIT_OB_OR_GROUP):
faces_split.append(face)
# remove one of the items and reorder
return [(verts_split, faces_split, unique_materials_split, key_to_name(key))
for key, (verts_split, faces_split, unique_materials_split, _) in face_split_dict.items()]
return [(verts_split, faces_split, unique_materials_split, key_to_name(key), bool(use_vnor), bool(use_vtex))
for key, (verts_split, faces_split, unique_materials_split, _, use_vnor, use_vtex)
in face_split_dict.items()]
def create_mesh(new_objects,
@ -459,7 +467,8 @@ def create_mesh(new_objects,
if len_face_vert_loc_indices == 1:
faces.pop(f_idx) # cant add single vert faces
elif not face_vert_tex_indices or len_face_vert_loc_indices == 2: # faces that have no texture coords are lines
# Face with a single item in face_vert_nor_indices is actually a polyline!
elif len(face_vert_nor_indices) == 1 or len_face_vert_loc_indices == 2:
if use_edges:
edges.extend((face_vert_loc_indices[i], face_vert_loc_indices[i + 1])
for i in range(len_face_vert_loc_indices - 1))
@ -490,11 +499,11 @@ def create_mesh(new_objects,
[face_vert_nor_indices[ngon[0]],
face_vert_nor_indices[ngon[1]],
face_vert_nor_indices[ngon[2]],
],
] if face_vert_nor_indices else [],
[face_vert_tex_indices[ngon[0]],
face_vert_tex_indices[ngon[1]],
face_vert_tex_indices[ngon[2]],
],
] if face_vert_tex_indices else [],
context_material,
context_smooth_group,
context_object,
@ -600,11 +609,11 @@ def create_mesh(new_objects,
context_material_old = context_material
blen_poly.material_index = mat
if verts_nor:
if verts_nor and face_vert_nor_indices:
for face_noidx, lidx in zip(face_vert_nor_indices, blen_poly.loop_indices):
me.loops[lidx].normal[:] = verts_nor[face_noidx]
if verts_tex:
if verts_tex and face_vert_tex_indices:
if context_material:
image = unique_material_images[context_material]
if image: # Can be none if the material dosnt have an image.
@ -865,6 +874,7 @@ def load(operator, context, filepath,
face_vert_loc_indices = None
face_vert_nor_indices = None
face_vert_tex_indices = None
face_vert_nor_valid = face_vert_tex_valid = False
face_items_usage = set()
face_invalid_blenpoly = None
prev_vidx = None
@ -930,6 +940,7 @@ def load(operator, context, filepath,
if len(obj_vert) > 1 and obj_vert[1]:
idx = int(obj_vert[1]) - 1
face_vert_tex_indices.append((idx + len(verts_tex) + 1) if (idx < 0) else idx)
face_vert_tex_valid = True
else:
# dummy
face_vert_tex_indices.append(0)
@ -937,11 +948,19 @@ def load(operator, context, filepath,
if len(obj_vert) > 2 and obj_vert[2]:
idx = int(obj_vert[2]) - 1
face_vert_nor_indices.append((idx + len(verts_nor) + 1) if (idx < 0) else idx)
face_vert_nor_valid = True
else:
# dummy
face_vert_nor_indices.append(0)
if not context_multi_line:
# Clear nor/tex indices in case we had none defined for this face.
if not face_vert_nor_valid:
face_vert_nor_indices.clear()
if not face_vert_tex_valid:
face_vert_tex_indices.clear()
face_vert_nor_valid = face_vert_tex_valid = False
# Means we have finished a face, we have to do final check if ngon is suspected to be blender-invalid...
if face_invalid_blenpoly:
face_invalid_blenpoly.clear()
@ -962,8 +981,11 @@ def load(operator, context, filepath,
# Instantiate a face
face = create_face(context_material, context_smooth_group, context_object)
face_vert_loc_indices = face[0]
# XXX A bit hackish, we use special 'value' of face_vert_nor_indices (a single True item) to tag this
# as a polyline, and not a regular face...
face[1][:] = [True]
faces.append(face)
# Else, use face_vert_loc_indices and face_vert_tex_indices previously defined and used the obj_face
# Else, use face_vert_loc_indices previously defined and used the obj_face
context_multi_line = b'l' if strip_slash(line_split) else b''
@ -1087,13 +1109,14 @@ def load(operator, context, filepath,
SPLIT_OB_OR_GROUP = bool(use_split_objects or use_split_groups)
for data in split_mesh(verts_loc, faces, unique_materials, filepath, SPLIT_OB_OR_GROUP):
verts_loc_split, faces_split, unique_materials_split, dataname = data
verts_loc_split, faces_split, unique_materials_split, dataname, use_vnor, use_vtex = data
# Create meshes from the data, warning 'vertex_groups' wont support splitting
#~ print(dataname, use_vnor, use_vtex)
create_mesh(new_objects,
use_edges,
verts_loc_split,
verts_nor,
verts_tex,
verts_nor if use_vnor else [],
verts_tex if use_vtex else [],
faces_split,
unique_materials_split,
unique_material_images,