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

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCampbell Barton <ideasman42@gmail.com>2009-06-12 08:16:12 +0400
committerCampbell Barton <ideasman42@gmail.com>2009-06-12 08:16:12 +0400
commit96c5f36eff4ee85aad90c507070447a6ad5bdda9 (patch)
treec3b6550785d3e5e2895b6f99b9a33ea21d46e8fd /release
parent642fea299b7ce108783d1075c6c1a3d94eab3f7d (diff)
OBJ import support for nurbs curves
Imports nurbs with orderU and endpointU (inferred from weights). No support for vert-weights, surfaces, 2D curves or non-bspline's yet. fix for exporting closed nurbs, was overlapping too much of the curve.
Diffstat (limited to 'release')
-rw-r--r--release/scripts/export_obj.py5
-rw-r--r--release/scripts/import_obj.py275
2 files changed, 230 insertions, 50 deletions
diff --git a/release/scripts/export_obj.py b/release/scripts/export_obj.py
index 5a6d80f45f3..a57788abf3f 100644
--- a/release/scripts/export_obj.py
+++ b/release/scripts/export_obj.py
@@ -236,9 +236,8 @@ def write_nurb(file, ob, ob_mat):
pt_num += 1
curve_ls.append(-1)
else:
- val = DEG_ORDER_U - 1
- pt_num += val*2
- curve_ls = curve_ls[-val:] + curve_ls + curve_ls[0:val] # Blenders OrderU of 3 -> val==1, 4 -> 2 etc
+ pt_num += DEG_ORDER_U-1
+ curve_ls = curve_ls + curve_ls[0:DEG_ORDER_U]
file.write('curv 0.0 1.0 %s\n' % (' '.join( [str(i) for i in curve_ls] ))) # Blender has no U and V values for the curve
diff --git a/release/scripts/import_obj.py b/release/scripts/import_obj.py
index 31501173fda..5234fe80a91 100644
--- a/release/scripts/import_obj.py
+++ b/release/scripts/import_obj.py
@@ -536,6 +536,96 @@ def create_mesh(scn, new_objects, has_ngons, CREATE_FGONS, CREATE_EDGES, verts_l
me.addVertGroup(group_name)
me.assignVertsToGroup(group_name, group_indicies,1.00, Mesh.AssignModes.REPLACE)
+
+def create_nurbs(scn, context_nurbs, vert_loc, new_objects):
+ '''
+ Add nurbs object to blender, only support one type at the moment
+ '''
+ deg = context_nurbs.get('deg', (3,))
+ curv_range = context_nurbs.get('curv_range', None)
+ curv_idx = context_nurbs.get('curv_idx', [])
+ parm_u = context_nurbs.get('parm_u', [])
+ parm_v = context_nurbs.get('parm_v', [])
+ name = context_nurbs.get('name', 'ObjNurb')
+ cstype = context_nurbs.get('cstype', None)
+
+ if cstype == None:
+ print '\tWarning, cstype not found'
+ return
+ if cstype != 'bspline':
+ print '\tWarning, cstype is not supported (only bspline)'
+ return
+ if not curv_idx:
+ print '\tWarning, curv argument empty or not set'
+ return
+ if len(deg) > 1 or parm_v:
+ print '\tWarning, surfaces not supported'
+ return
+
+ cu = bpy.data.curves.new(name, 'Curve')
+ nu = None
+ for pt in curv_idx:
+
+ pt = vert_loc[pt]
+ pt = (pt[0], pt[1], pt[2], 1.0)
+
+ if nu == None:
+ nu = cu.appendNurb(pt)
+ else:
+ nu.append(pt)
+
+ nu.orderU = deg[0]+1
+
+ # get for endpoint flag from the weighting
+ if curv_range and len(parm_u) > deg[0]+1:
+ do_endpoints = True
+ for i in xrange(deg[0]+1):
+
+ if abs(parm_u[i]-curv_range[0]) > 0.0001:
+ do_endpoints = False
+ break
+
+ if abs(parm_u[-(i+1)]-curv_range[1]) > 0.0001:
+ do_endpoints = False
+ break
+
+ else:
+ do_endpoints = False
+
+ if do_endpoints:
+ nu.flagU |= 2
+
+
+ # close
+ '''
+ do_closed = False
+ if len(parm_u) > deg[0]+1:
+ for i in xrange(deg[0]+1):
+ #print curv_idx[i], curv_idx[-(i+1)]
+
+ if curv_idx[i]==curv_idx[-(i+1)]:
+ do_closed = True
+ break
+
+ if do_closed:
+ nu.flagU |= 1
+ '''
+
+ ob = scn.objects.new(cu)
+ new_objects.append(ob)
+
+
+def strip_slash(line_split):
+ if line_split[-1][-1]== '\\':
+ if len(line_split[-1])==1:
+ line_split.pop() # remove the \ item
+ else:
+ line_split[-1]= line_split[-1][:-1] # remove the \ from the end last number
+ return True
+ return False
+
+
+
def get_float_func(filepath):
'''
find the float function for this obj file
@@ -590,6 +680,11 @@ def load_obj(filepath,
context_smooth_group= None
context_object= None
context_vgroup = None
+
+ # Nurbs
+ context_nurbs = {}
+ nurbs = []
+ context_parm = '' # used by nurbs too but could be used elsewhere
has_ngons= False
# has_smoothgroups= False - is explicit with len(unique_smooth_groups) being > 0
@@ -604,7 +699,7 @@ def load_obj(filepath,
# it means they are multiline-
# since we use xreadline we cant skip to the next line
# so we need to know weather
- multi_line_face= False
+ context_multi_line= ''
print '\tparsing obj file "%s"...' % filepath,
time_sub= sys.time()
@@ -627,12 +722,11 @@ def load_obj(filepath,
# Handel faces lines (as faces) and the second+ lines of fa multiline face here
# use 'f' not 'f ' because some objs (very rare have 'fo ' for faces)
- elif line.startswith('f') or (line.startswith('l ') and CREATE_EDGES) or multi_line_face:
+ elif line.startswith('f') or context_multi_line == 'f':
- if multi_line_face:
+ if context_multi_line:
# use face_vert_loc_indicies and face_vert_tex_indicies previously defined and used the obj_face
line_split= line.split()
- multi_line_face= False
else:
line_split= line[2:].split()
@@ -648,14 +742,10 @@ def load_obj(filepath,
context_object\
))
- if line_split[-1][-1]== '\\':
- multi_line_face= True
- if len(line_split[-1])==1:
- line_split.pop() # remove the \ item
- else:
- line_split[-1]= line_split[-1][:-1] # remove the \ from the end last number
-
- isline= line.startswith('l')
+ if strip_slash(line_split):
+ context_multi_line = 'f'
+ else:
+ context_multi_line = ''
for v in line_split:
obj_vert= v.split('/')
@@ -672,24 +762,60 @@ def load_obj(filepath,
face_vert_loc_indicies.append(vert_loc_index)
- if not isline:
- 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 indicies absolute
- if vert_tex_index < 0:
- vert_tex_index= len(verts_tex) + vert_tex_index + 1
-
- face_vert_tex_indicies.append(vert_tex_index)
- else:
- # dummy
- face_vert_tex_indicies.append(0)
+ 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 indicies absolute
+ if vert_tex_index < 0:
+ vert_tex_index= len(verts_tex) + vert_tex_index + 1
+
+ face_vert_tex_indicies.append(vert_tex_index)
+ else:
+ # dummy
+ face_vert_tex_indicies.append(0)
if len(face_vert_loc_indicies) > 4:
has_ngons= True
+
+ elif CREATE_EDGES and (line.startswith('l ') or context_multi_line == 'l'):
+ # very similar to the face load function above with some parts removed
+ if context_multi_line:
+ # use face_vert_loc_indicies and face_vert_tex_indicies previously defined and used the obj_face
+ line_split= line.split()
+
+ else:
+ line_split= line[2:].split()
+ face_vert_loc_indicies= []
+ face_vert_tex_indicies= []
+
+ # Instance a face
+ faces.append((\
+ face_vert_loc_indicies,\
+ face_vert_tex_indicies,\
+ context_material,\
+ context_smooth_group,\
+ context_object\
+ ))
+
+ if strip_slash(line_split):
+ context_multi_line = 'l'
+ else:
+ context_multi_line = ''
+
+ isline= line.startswith('l')
+
+ for v in line_split:
+ vert_loc_index= int(v)-1
+
+ # Make relative negative vert indicies absolute
+ if vert_loc_index < 0:
+ vert_loc_index= len(verts_loc) + vert_loc_index + 1
+
+ face_vert_loc_indicies.append(vert_loc_index)
+
elif line.startswith('s'):
if CREATE_SMOOTH_GROUPS:
context_smooth_group= line_value(line.split())
@@ -720,6 +846,62 @@ def load_obj(filepath,
unique_materials[context_material]= None
elif line.startswith('mtllib'): # usemap or usemat
material_libs.extend( line.split()[1:] ) # can have multiple mtllib filenames per line
+
+
+ # Nurbs support
+ elif line.startswith('cstype '):
+ context_nurbs['cstype']= line_value(line.split()) # 'rat bspline' / 'bspline'
+ elif line.startswith('curv ') or context_multi_line == 'curv':
+ line_split= line.split()
+
+ curv_idx = context_nurbs['curv_idx'] = context_nurbs.get('curv_idx', []) # incase were multiline
+
+ if not context_multi_line:
+ context_nurbs['curv_range'] = float_func(line_split[1]), float_func(line_split[2])
+ line_split[0:3] = [] # remove first 3 items
+
+ if strip_slash(line_split):
+ context_multi_line = 'curv'
+ else:
+ context_multi_line = ''
+
+
+ for i in line_split:
+ vert_loc_index = int(i)-1
+
+ if vert_loc_index < 0:
+ vert_loc_index= len(verts_loc) + vert_loc_index + 1
+
+ curv_idx.append(vert_loc_index)
+
+ elif line.startswith('parm') or context_multi_line == 'parm':
+ line_split= line.split()
+
+ if context_multi_line:
+ context_multi_line = ''
+ else:
+ context_parm = line_split[1]
+ line_split[0:2] = [] # remove first 2
+
+ if strip_slash(line_split):
+ context_multi_line = 'parm'
+ else:
+ context_multi_line = ''
+
+ if context_parm.lower() == 'u':
+ context_nurbs.setdefault('parm_u', []).extend( [float_func(f) for f in line_split] )
+ elif context_parm.lower() == 'v': # surfaces not suported yet
+ context_nurbs.setdefault('parm_v', []).extend( [float_func(f) for f in line_split] )
+ # else: # may want to support other parm's ?
+
+ elif line.startswith('deg '):
+ context_nurbs['deg']= [int(i) for i in line.split()[1:]]
+ elif line.startswith('end'):
+ # Add the nurbs curve
+ context_nurbs['name'] = context_object
+ nurbs.append(context_nurbs)
+ context_nurbs = {}
+ context_parm = ''
''' # How to use usemap? depricated?
elif line.startswith('usema'): # usemap or usemat
@@ -754,6 +936,11 @@ def load_obj(filepath,
# Create meshes from the data, warning 'vertex_groups' wont support splitting
create_mesh(scn, new_objects, has_ngons, CREATE_FGONS, CREATE_EDGES, verts_loc_split, verts_tex, faces_split, unique_materials_split, unique_material_images, unique_smooth_groups, vertex_groups, dataname)
+ # nurbs support
+ for context_nurbs in nurbs:
+ create_nurbs(scn, context_nurbs, verts_loc, new_objects)
+
+
axis_min= [ 1000000000]*3
axis_max= [-1000000000]*3
@@ -989,34 +1176,28 @@ if __name__=='__main__' and not DEBUG:
else:
Window.FileSelector(load_obj_ui, 'Import a Wavefront OBJ', '*.obj')
-
-'''
# For testing compatibility
+'''
else:
# DEBUG ONLY
TIME= sys.time()
+ DIR = '/fe/obj'
import os
print 'Searching for files'
- os.system('find /fe/obj -iname "*.obj" > /tmp/temp3ds_list')
-
- print '...Done'
- file= open('/tmp/temp3ds_list', 'rU')
- lines= file.readlines()
- file.close()
-
- def between(v,a,b):
- if v <= max(a,b) and v >= min(a,b):
- return True
- return False
-
- for i, _obj in enumerate(lines):
- if between(i, 0,20):
- _obj= _obj[:-1]
- print 'Importing', _obj, '\nNUMBER', i, 'of', len(lines)
- _obj_file= _obj.split('/')[-1].split('\\')[-1]
- newScn= bpy.data.scenes.new(_obj_file)
+ def fileList(path):
+ for dirpath, dirnames, filenames in os.walk(path):
+ for filename in filenames:
+ yield os.path.join(dirpath, filename)
+
+ files = [f for f in fileList(DIR) if f.lower().endswith('.obj')]
+ files.sort()
+
+ for i, obj_file in enumerate(files):
+ if 0 < i < 20:
+ print 'Importing', obj_file, '\nNUMBER', i, 'of', len(files)
+ newScn= bpy.data.scenes.new(os.path.basename(obj_file))
newScn.makeCurrent()
- load_obj(_obj, False)
+ load_obj(obj_file, False)
print 'TOTAL TIME: %.6f' % (sys.time() - TIME)
'''