Profile

Welcome, guest!

Would you like to Login, or Register?

What are the benefits of registering?

Pastes: 22015

Quickie

If you tried registering a few days ago and didn't get the email activation reply, try now. Sorry!

Poll

Do you like Microsoft's Windows 7?

Yes
No
Undecided

Top Code
text5099
bash1552
cpp1382
php1097
c813
java705
html4strict514
python478
javascript380
csharp318
Top Members

Edit code: here. | Add this PasteBin to your website. | Report abuse.

Pasted as text by antonio on Monday, April 20th, 2009 6:31am

  1. #!BPY
  2.  
  3. """
  4. Name: 'Wavefront (.obj)...'
  5. Blender: 242
  6. Group: 'Import'
  7. Tooltip: 'Load a Wavefront OBJ File, Shift: batch import all dir.'
  8. """
  9.  
  10. __author__= "Campbell Barton", "Jiri Hnidek", "and then twak mucked it up"
  11. __url__= ["blender.org", "blenderartists.org"]
  12. __version__= "2.0 +0.1i"
  13.  
  14. __bpydoc__= """
  15. This script imports a Wavefront OBJ files to Blender.
  16.  
  17. Usage:
  18. Run this script from "File->Import" menu and then load the desired OBJ file.
  19. Note, This loads mesh objects and materials only, nurbs and curves are not supported.
  20. """
  21.  
  22. # ***** BEGIN GPL LICENSE BLOCK *****
  23. #
  24. # Script copyright (C) Campbell J Barton 2007
  25. #
  26. # This program is free software; you can redistribute it and/or
  27. # modify it under the terms of the GNU General Public License
  28. # as published by the Free Software Foundation; either version 2
  29. # of the License, or (at your option) any later version.
  30. #
  31. # This program is distributed in the hope that it will be useful,
  32. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  33. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  34. # GNU General Public License for more details.
  35. #
  36. # You should have received a copy of the GNU General Public License
  37. # along with this program; if not, write to the Free Software Foundation,
  38. # Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  39. #
  40. # ***** END GPL LICENCE BLOCK *****
  41. # --------------------------------------------------------------------------
  42.  
  43. from Blender import *
  44. import bpy
  45. import BPyMesh
  46. import BPyImage
  47. import BPyMessages
  48.  
  49. try:            import os
  50. except:         os= False
  51.  
  52.  
  53. # Generic path functions
  54. def stripFile(path):
  55.         '''Return directory, where the file is'''
  56.         lastSlash= max(path.rfind(''), path.rfind('/'))
  57.         if lastSlash != -1:
  58.                 path= path[:lastSlash]
  59.         return '%s%s' % (path, sys.sep)
  60.  
  61. def stripPath(path):
  62.         '''Strips the slashes from the back of a string'''
  63.         return path.split('/')[-1].split('')[-1]
  64.  
  65. def stripExt(name): # name is a string
  66.         '''Strips the prefix off the name before writing'''
  67.         index= name.rfind('.')
  68.         if index != -1:
  69.                 return name[ : index ]
  70.         else:
  71.                 return name
  72. # end path funcs
  73.  
  74.  
  75.  
  76. def line_value(line_split):
  77.         '''
  78.         Returns 1 string represneting the value for this line
  79.         None will be returned if theres only 1 word
  80.         '''
  81.         length= len(line_split)
  82.         if length == 1:
  83.                 return None
  84.        
  85.         elif length == 2:
  86.                 return line_split[1]
  87.        
  88.         elif length > 2:
  89.                 return ' '.join( line_split[1:] )
  90.  
  91. def obj_image_load(imagepath, DIR, IMAGE_SEARCH):
  92.         '''
  93.         Mainly uses comprehensiveImageLoad
  94.         but tries to replace '_' with ' ' for Max's exporter replaces spaces with underscores.
  95.         '''
  96.        
  97.         if '_' in imagepath:
  98.                 image= BPyImage.comprehensiveImageLoad(imagepath, DIR, PLACE_HOLDER= False, RECURSIVE= IMAGE_SEARCH)
  99.                 if image: return image
  100.                 # Did the exporter rename the image?
  101.                 image= BPyImage.comprehensiveImageLoad(imagepath.replace('_', ' '), DIR, PLACE_HOLDER= False, RECURSIVE= IMAGE_SEARCH)
  102.                 if image: return image
  103.        
  104.         # Return an image, placeholder if it dosnt exist
  105.         image= BPyImage.comprehensiveImageLoad(imagepath, DIR, PLACE_HOLDER= True, RECURSIVE= IMAGE_SEARCH)
  106.         return image
  107.        
  108.  
  109. def create_materials(filepath, material_libs, unique_materials, unique_material_images, IMAGE_SEARCH):
  110.         '''
  111.         Create all the used materials in this obj,
  112.         assign colors and images to the materials from all referenced material libs
  113.         '''
  114.         DIR= stripFile(filepath)
  115.        
  116.         #==================================================================================#
  117.         # This function sets textures defined in .mtl file                                 #
  118.         #==================================================================================#
  119.         def load_material_image(blender_material, context_material_name, imagepath, type):
  120.                
  121.                 texture= bpy.data.textures.new(type)
  122.                 texture.setType('Image')
  123.                
  124.                 # Absolute path - c:.. etc would work here
  125.                 image= obj_image_load(imagepath, DIR, IMAGE_SEARCH)
  126.                 has_data = image.has_data
  127.                 texture.image = image
  128.                
  129.                 # Adds textures for materials (rendering)
  130.                 if type == 'Kd':
  131.                         if has_data and image.depth == 32:
  132.                                 # Image has alpha
  133.                                 blender_material.setTexture(0, texture, Texture.TexCo.UV, Texture.MapTo.COL | Texture.MapTo.ALPHA)
  134.                                 texture.setImageFlags('MipMap', 'InterPol', 'UseAlpha')
  135.                                 blender_material.mode |= Material.Modes.ZTRANSP
  136.                                 blender_material.alpha = 0.0
  137.                         else:
  138.                                 blender_material.setTexture(0, texture, Texture.TexCo.UV, Texture.MapTo.COL)
  139.                                
  140.                         # adds textures to faces (Textured/Alt-Z mode)
  141.                         # Only apply the diffuse texture to the face if the image has not been set with the inline usemat func.
  142.                         unique_material_images[context_material_name]= image, has_data # set the texface image
  143.                
  144.                 elif type == 'Ka':
  145.                         blender_material.setTexture(1, texture, Texture.TexCo.UV, Texture.MapTo.CMIR) # TODO- Add AMB to BPY API
  146.                        
  147.                 elif type == 'Ks':
  148.                         blender_material.setTexture(2, texture, Texture.TexCo.UV, Texture.MapTo.SPEC)
  149.                
  150.                 elif type == 'Bump':
  151.                         blender_material.setTexture(3, texture, Texture.TexCo.UV, Texture.MapTo.NOR)           
  152.                 elif type == 'D':
  153.                         blender_material.setTexture(4, texture, Texture.TexCo.UV, Texture.MapTo.ALPHA)                         
  154.                         blender_material.mode |= Material.Modes.ZTRANSP
  155.                         blender_material.alpha = 0.0
  156.                         # Todo, unset deffuse material alpha if it has an alpha channel
  157.                        
  158.                 elif type == 'refl':
  159.                         blender_material.setTexture(5, texture, Texture.TexCo.UV, Texture.MapTo.REF)           
  160.        
  161.        
  162.         # Add an MTL with the same name as the obj if no MTLs are spesified.
  163.         temp_mtl= stripExt(stripPath(filepath))+ '.mtl'
  164.        
  165.         if sys.exists(DIR + temp_mtl) and temp_mtl not in material_libs:
  166.                         material_libs.append( temp_mtl )
  167.         del temp_mtl
  168.        
  169.         #Create new materials
  170.         for name in unique_materials.iterkeys():
  171.                 unique_materials[name]= bpy.data.materials.new(name)
  172.                
  173.                 unique_material_images[name]= None, False # assign None to all material images to start with, add to later.
  174.                
  175.         unique_materials[None]= None
  176.        
  177.         for libname in material_libs:
  178.                 mtlpath= DIR + libname
  179.                 if not sys.exists(mtlpath):
  180.                         #print '        Error Missing MTL: "%s"' % mtlpath
  181.                         pass
  182.                 else:
  183.                         #print '                loading mtl: "%s"' % mtlpath
  184.                         context_material= None
  185.                         mtl= open(mtlpath)
  186.                         for line in mtl.xreadlines():
  187.                                 if line.startswith('newmtl'):
  188.                                         context_material_name= line_value(line.split())
  189.                                         if unique_materials.has_key(context_material_name):
  190.                                                 context_material = unique_materials[ context_material_name ]
  191.                                         else:
  192.                                                 context_material = None
  193.                                
  194.                                 elif context_material:
  195.                                         # we need to make a material to assign properties to it.
  196.                                         line_split= line.split()
  197.                                         line_lower= line.lower()
  198.                                         if line_lower.startswith('ka'):
  199.                                                 context_material.setMirCol((float(line_split[1]), float(line_split[2]), float(line_split[3])))
  200.                                         elif line_lower.startswith('kd'):
  201.                                                 context_material.setRGBCol((float(line_split[1]), float(line_split[2]), float(line_split[3])))
  202.                                         elif line_lower.startswith('ks'):
  203.                                                 context_material.setSpecCol((float(line_split[1]), float(line_split[2]), float(line_split[3])))
  204.                                         elif line_lower.startswith('ns'):
  205.                                                 context_material.setHardness( int((float(line_split[1])*0.51)) )
  206.                                         elif line_lower.startswith('ni'): # Refraction index
  207.                                                 context_material.setIOR( max(1, min(float(line_split[1]), 3))) # Between 1 and 3
  208.                                         elif line_lower.startswith('d') or line_lower.startswith('tr'):
  209.                                                 context_material.setAlpha(float(line_split[1]))
  210.                                         elif line_lower.startswith('map_ka'):
  211.                                                 img_filepath= line_value(line.split())
  212.                                                 if img_filepath:
  213.                                                         load_material_image(context_material, context_material_name, img_filepath, 'Ka')
  214.                                         elif line_lower.startswith('map_ks'):
  215.                                                 img_filepath= line_value(line.split())
  216.                                                 if img_filepath:
  217.                                                         load_material_image(context_material, context_material_name, img_filepath, 'Ks')
  218.                                         elif line_lower.startswith('map_kd'):
  219.                                                 img_filepath= line_value(line.split())
  220.                                                 if img_filepath:
  221.                                                         load_material_image(context_material, context_material_name, img_filepath, 'Kd')
  222.                                         elif line_lower.startswith('map_bump'):
  223.                                                 img_filepath= line_value(line.split())
  224.                                                 if img_filepath:
  225.                                                         load_material_image(context_material, context_material_name, img_filepath, 'Bump')
  226.                                         elif line_lower.startswith('map_d') or line_lower.startswith('map_tr'): # Alpha map - Dissolve
  227.                                                 img_filepath= line_value(line.split())
  228.                                                 if img_filepath:
  229.                                                         load_material_image(context_material, context_material_name, img_filepath, 'D')
  230.                                        
  231.                                         elif line_lower.startswith('refl'): # Reflectionmap
  232.                                                 img_filepath= line_value(line.split())
  233.                                                 if img_filepath:
  234.                                                         load_material_image(context_material, context_material_name, img_filepath, 'refl')
  235.                         mtl.close()
  236.  
  237.  
  238.  
  239.        
  240. def split_mesh(verts_loc, faces, unique_materials, filepath, SPLIT_OB_OR_GROUP, SPLIT_MATERIALS):
  241.         '''
  242.         Takes vert_loc and faces, and seperates into multiple sets of
  243.         (verts_loc, faces, unique_materials, dataname)
  244.         This is done so objects do not overload the 16 material limit.
  245.         '''
  246.        
  247.         filename = stripExt(stripPath(filepath))
  248.        
  249.         if not SPLIT_OB_OR_GROUP and not SPLIT_MATERIALS:
  250.                 # use the filename for the object name since we arnt chopping up the mesh.
  251.                 return [(verts_loc, faces, unique_materials, filename)]
  252.        
  253.        
  254.         def key_to_name(key):
  255.                 # if the key is a tuple, join it to make a string
  256.                 if type(key) == tuple:
  257.                         return '%s_%s' % key
  258.                 elif not key:
  259.                         return filename # assume its a string. make sure this is true if the splitting code is changed
  260.                 else:
  261.                         return key
  262.        
  263.         # Return a key that makes the faces unique.
  264.         if SPLIT_OB_OR_GROUP and not SPLIT_MATERIALS:
  265.                 def face_key(face):
  266.                         return face[4] # object
  267.        
  268.         elif not SPLIT_OB_OR_GROUP and SPLIT_MATERIALS:
  269.                 def face_key(face):
  270.                         return face[2] # material
  271.        
  272.         else: # Both
  273.                 def face_key(face):
  274.                         return face[4], face[2] # object,material              
  275.        
  276.        
  277.         face_split_dict= {}
  278.        
  279.         oldkey= -1 # initialize to a value that will never match the key
  280.        
  281.         for face in faces:
  282.                
  283.                 key= face_key(face)
  284.                
  285.                 if oldkey != key:
  286.                         # Check the key has changed.
  287.                         try:
  288.                                 verts_split, faces_split, unique_materials_split, vert_remap= face_split_dict[key]
  289.                         except KeyError:
  290.                                 faces_split= []
  291.                                 verts_split= []
  292.                                 unique_materials_split= {}
  293.                                 vert_remap= [-1]*len(verts_loc)
  294.                                
  295.                                 face_split_dict[key]= (verts_split, faces_split, unique_materials_split, vert_remap)
  296.                        
  297.                         oldkey= key
  298.                        
  299.                 face_vert_loc_indicies= face[0]
  300.                
  301.                 # Remap verts to new vert list and add where needed
  302.                 for enum, i in enumerate(face_vert_loc_indicies):
  303.                         if vert_remap[i] == -1:
  304.                                 new_index= len(verts_split)
  305.                                 vert_remap[i]= new_index # set the new remapped index so we only add once and can reference next time.
  306.                                 face_vert_loc_indicies[enum] = new_index # remap to the local index
  307.                                 verts_split.append( verts_loc[i] ) # add the vert to the local verts
  308.                                
  309.                         else:
  310.                                 face_vert_loc_indicies[enum] = vert_remap[i] # remap to the local index
  311.                        
  312.                         matname= face[2]
  313.                         if matname and not unique_materials_split.has_key(matname):
  314.                                 unique_materials_split[matname] = unique_materials[matname]
  315.                
  316.                 faces_split.append(face)
  317.        
  318.        
  319.         # remove one of the itemas and reorder
  320.         return [(value[0], value[1], value[2], key_to_name(key)) for key, value in face_split_dict.iteritems()]
  321.  
  322.  
  323. def create_mesh(scn, new_objects, has_ngons, CREATE_FGONS, CREATE_EDGES, verts_loc, verts_tex, faces, unique_materials, unique_material_images, unique_smooth_groups, dataname):
  324.         '''
  325.         Takes all the data gathered and generates a mesh, adding the new object to new_objects
  326.         deals with fgons, sharp edges and assigning materials
  327.         '''
  328.         if not has_ngons:
  329.                 CREATE_FGONS= False
  330.        
  331.         if unique_smooth_groups:
  332.                 sharp_edges= {}
  333.                 smooth_group_users= dict([ (context_smooth_group, {}) for context_smooth_group in unique_smooth_groups.iterkeys() ])
  334.                 context_smooth_group_old= -1
  335.        
  336.         # Split fgons into tri's
  337.         fgon_edges= {} # Used for storing fgon keys
  338.         if CREATE_EDGES:
  339.                 edges= []
  340.        
  341.         context_object= None
  342.        
  343.         # reverse loop through face indicies
  344.         for f_idx in xrange(len(faces)-1, -1, -1):
  345.                
  346.                 face_vert_loc_indicies,
  347.                 face_vert_tex_indicies,
  348.                 context_material,
  349.                 context_smooth_group,
  350.                 context_object= faces[f_idx]
  351.                
  352.                 len_face_vert_loc_indicies = len(face_vert_loc_indicies)
  353.                
  354.                 if len_face_vert_loc_indicies==1:
  355.                         faces.pop(f_idx)# cant add single vert faces
  356.                
  357.                 elif not face_vert_tex_indicies or len_face_vert_loc_indicies == 2: # faces that have no texture coords are lines
  358.                         if CREATE_EDGES:
  359.                                 # generators are better in python 2.4+ but can't be used in 2.3
  360.                                 # edges.extend( (face_vert_loc_indicies[i], face_vert_loc_indicies[i+1]) for i in xrange(len_face_vert_loc_indicies-1) )
  361.                                 edges.extend( [(face_vert_loc_indicies[i], face_vert_loc_indicies[i+1]) for i in xrange(len_face_vert_loc_indicies-1)] )
  362.  
  363.                         faces.pop(f_idx)
  364.                 else:
  365.                        
  366.                         # Smooth Group
  367.                         if unique_smooth_groups and context_smooth_group:
  368.                                 # Is a part of of a smooth group and is a face
  369.                                 if context_smooth_group_old is not context_smooth_group:
  370.                                         edge_dict= smooth_group_users[context_smooth_group]
  371.                                         context_smooth_group_old= context_smooth_group
  372.                                
  373.                                 for i in xrange(len_face_vert_loc_indicies):
  374.                                         i1= face_vert_loc_indicies[i]
  375.                                         i2= face_vert_loc_indicies[i-1]
  376.                                         if i1>i2: i1,i2= i2,i1
  377.                                        
  378.                                         try:
  379.                                                 edge_dict[i1,i2]+= 1
  380.                                         except KeyError:
  381.                                                 edge_dict[i1,i2]=  1
  382.                        
  383.                         # FGons into triangles
  384.                         if has_ngons and len_face_vert_loc_indicies > 3:
  385.                                
  386.                                 ngon_face_indices= BPyMesh.ngon(verts_loc, face_vert_loc_indicies)
  387.                                 faces.extend(
  388.                                 [(
  389.                                 [face_vert_loc_indicies[ngon[0]], face_vert_loc_indicies[ngon[1]], face_vert_loc_indicies[ngon[2]] ],
  390.                                 [face_vert_tex_indicies[ngon[0]], face_vert_tex_indicies[ngon[1]], face_vert_tex_indicies[ngon[2]] ],
  391.                                 context_material,
  392.                                 context_smooth_group,
  393.                                 context_object)
  394.                                 for ngon in ngon_face_indices]
  395.                                 )
  396.                                
  397.                                 # edges to make fgons
  398.                                 if CREATE_FGONS:
  399.                                         edge_users= {}
  400.                                         for ngon in ngon_face_indices:
  401.  

Parent PasteBin: 5692
Your Name:
Code Language:
Security Image:
Text seen in Image: