Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender-addons.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBastien Montagne <montagne29@wanadoo.fr>2015-02-18 18:51:45 +0300
committerBastien Montagne <montagne29@wanadoo.fr>2015-02-18 18:51:45 +0300
commitcfdf95dc8a0eae6cb18efc4a105b53755a0f0365 (patch)
tree1c21fabe782e959f8ca69386be1790384dc38944 /io_scene_obj
parent4b1ccc3a7bb7fe22668d136e2e5b429ff9086500 (diff)
OBJ importer: add support for (custom) normals.
Not much to say, pretty similar to how FBX custom normals import works...
Diffstat (limited to 'io_scene_obj')
-rw-r--r--io_scene_obj/import_obj.py66
1 files changed, 49 insertions, 17 deletions
diff --git a/io_scene_obj/import_obj.py b/io_scene_obj/import_obj.py
index cba060c8..18f196e4 100644
--- a/io_scene_obj/import_obj.py
+++ b/io_scene_obj/import_obj.py
@@ -31,6 +31,7 @@ Note, This loads mesh objects and materials only, nurbs and curves are not suppo
http://wiki.blender.org/index.php/Scripts/Manual/Import/wavefront_obj
"""
+import array
import os
import time
import bpy
@@ -379,7 +380,7 @@ def split_mesh(verts_loc, faces, unique_materials, filepath, SPLIT_OB_OR_GROUP):
oldkey = -1 # initialize to a value that will never match the key
for face in faces:
- key = face[4]
+ key = face[5]
if oldkey != key:
# Check the key has changed.
@@ -407,7 +408,7 @@ def split_mesh(verts_loc, faces, unique_materials, filepath, SPLIT_OB_OR_GROUP):
face_vert_loc_indices[enum] = map_index # remap to the local index
- matname = face[2]
+ matname = face[3]
if matname and matname not in unique_materials_split:
unique_materials_split[matname] = unique_materials[matname]
@@ -420,6 +421,7 @@ def split_mesh(verts_loc, faces, unique_materials, filepath, SPLIT_OB_OR_GROUP):
def create_mesh(new_objects,
use_edges,
verts_loc,
+ verts_nor,
verts_tex,
faces,
unique_materials,
@@ -446,6 +448,7 @@ def create_mesh(new_objects,
# reverse loop through face indices
for f_idx in range(len(faces) - 1, -1, -1):
(face_vert_loc_indices,
+ face_vert_nor_indices,
face_vert_tex_indices,
context_material,
context_smooth_group,
@@ -522,6 +525,11 @@ def create_mesh(new_objects,
me.polygons.foreach_set("loop_start", faces_loop_start)
me.polygons.foreach_set("loop_total", faces_loop_total)
+ if verts_nor:
+ # Note: we store 'temp' normals in loops, since validate() may alter final mesh,
+ # we can only set custom lnors *after* calling it.
+ me.create_normals_split()
+
if verts_tex and me.polygons:
me.uv_textures.new()
@@ -533,6 +541,7 @@ def create_mesh(new_objects,
raise Exception("bad face") # Shall not happen, we got rid of those earlier!
(face_vert_loc_indices,
+ face_vert_nor_indices,
face_vert_tex_indices,
context_material,
context_smooth_group,
@@ -548,6 +557,10 @@ def create_mesh(new_objects,
context_material_old = context_material
blen_poly.material_index = mat
+ if verts_nor:
+ 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 context_material:
image = unique_material_images[context_material]
@@ -555,8 +568,8 @@ def create_mesh(new_objects,
me.uv_textures[0].data[i].image = image
blen_uvs = me.uv_layers[0]
- for j, lidx in enumerate(blen_poly.loop_indices):
- blen_uvs.data[lidx].uv = verts_tex[face_vert_tex_indices[j]]
+ for face_uvidx, lidx in zip(face_vert_tex_indices, blen_poly.loop_indices):
+ blen_uvs.data[lidx].uv = verts_tex[face_uvidx]
use_edges = use_edges and bool(edges)
if use_edges:
@@ -564,13 +577,26 @@ def create_mesh(new_objects,
# edges should be a list of (a, b) tuples
me.edges.foreach_set("vertices", unpack_list(edges))
- me.validate()
+ me.validate(cleanup_cddata=False) # *Very* important to not remove lnors here!
me.update(calc_edges=use_edges)
+ # XXX If validate changes the geometry, this is likely to be broken...
if unique_smooth_groups and sharp_edges:
for e in me.edges:
if e.key in sharp_edges:
e.use_edge_sharp = True
+ me.show_edge_sharp = True
+
+ if verts_nor:
+ clnors = array.array('f', [0.0] * (len(me.loops) * 3))
+ me.loops.foreach_get("normal", clnors)
+
+ if not unique_smooth_groups:
+ me.polygons.foreach_set("use_smooth", [True] * len(me.polygons))
+
+ me.normals_split_custom_set(tuple(zip(*(iter(clnors),) * 3)))
+ me.use_auto_smooth = True
+ me.show_edge_sharp = True
ob = bpy.data.objects.new(me.name, me)
new_objects.append(ob)
@@ -717,6 +743,7 @@ def load(operator, context, filepath,
time_main = time.time()
verts_loc = []
+ verts_nor = []
verts_tex = []
faces = [] # tuples of the faces
material_libs = [] # filanems to material libs this uses
@@ -736,9 +763,6 @@ def load(operator, context, filepath,
nurbs = []
context_parm = b'' # used by nurbs too but could be used elsewhere
- has_ngons = False
- # has_smoothgroups= False - is explicit with len(unique_smooth_groups) being > 0
-
# Until we can use sets
unique_materials = {}
unique_material_images = {}
@@ -768,7 +792,7 @@ def load(operator, context, filepath,
verts_loc.append((float_func(line_split[1]), float_func(line_split[2]), float_func(line_split[3])))
elif line_start == b'vn':
- pass
+ verts_nor.append((float_func(line_split[1]), float_func(line_split[2]), float_func(line_split[3])))
elif line_start == b'vt':
verts_tex.append((float_func(line_split[1]), float_func(line_split[2])))
@@ -784,10 +808,12 @@ def load(operator, context, filepath,
else:
line_split = line_split[1:]
face_vert_loc_indices = []
+ face_vert_nor_indices = []
face_vert_tex_indices = []
# Instance a face
faces.append((face_vert_loc_indices,
+ face_vert_nor_indices,
face_vert_tex_indices,
context_material,
context_smooth_group,
@@ -813,22 +839,27 @@ def load(operator, context, filepath,
face_vert_loc_indices.append(vert_loc_index)
+ # formatting for faces with normals and textures is
+ # loc_index/tex_index/nor_index
if len(obj_vert) > 1 and obj_vert[1]:
- # formatting for faces with normals and textures us
- # loc_index/tex_index/nor_index
-
vert_tex_index = int(obj_vert[1]) - 1
# Make relative negative vert indices absolute
if vert_tex_index < 0:
vert_tex_index = len(verts_tex) + vert_tex_index + 1
-
face_vert_tex_indices.append(vert_tex_index)
else:
# dummy
face_vert_tex_indices.append(0)
- if len(face_vert_loc_indices) > 4:
- has_ngons = True
+ if len(obj_vert) > 2 and obj_vert[2]:
+ vert_nor_index = int(obj_vert[2]) - 1
+ # Make relative negative vert indices absolute
+ if vert_nor_index < 0:
+ vert_nor_index = len(verts_nor) + vert_nor_index + 1
+ face_vert_nor_indices.append(vert_nor_index)
+ else:
+ # dummy
+ face_vert_nor_indices.append(0)
elif use_edges and (line_start == b'l' or context_multi_line == b'l'):
# very similar to the face load function above with some parts removed
@@ -840,10 +871,12 @@ def load(operator, context, filepath,
else:
line_split = line_split[1:]
face_vert_loc_indices = []
+ face_vert_nor_indices = []
face_vert_tex_indices = []
# Instance a face
faces.append((face_vert_loc_indices,
+ face_vert_nor_indices,
face_vert_tex_indices,
context_material,
context_smooth_group,
@@ -855,8 +888,6 @@ def load(operator, context, filepath,
else:
context_multi_line = b''
- # isline = line_start == b'l' # UNUSED
-
for v in line_split:
obj_vert = v.split(b'/')
vert_loc_index = int(obj_vert[0]) - 1
@@ -986,6 +1017,7 @@ def load(operator, context, filepath,
create_mesh(new_objects,
use_edges,
verts_loc_split,
+ verts_nor,
verts_tex,
faces_split,
unique_materials_split,