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:
authorFlorian Meyer <florianfelix@web.de>2010-12-19 02:11:10 +0300
committerFlorian Meyer <florianfelix@web.de>2010-12-19 02:11:10 +0300
commite160a7268255d194fcb2d8099184f1a6efe5923f (patch)
treeed9b48005718ba44485e7e4f2b801660bcafc5b5
parent00924b79d57fe6c40714d6335a235287987514fb (diff)
basically completely recoded in order to use add_utils and io_utils. Also the rest of the thing is recoded. Since this was like my first script this new version is much more readable and easier to debug. As a bonus there is also a new option to align the planes in a row on import to justify a version bumb. I think i tested everything and it should be bug free. Hopefully :)
-rw-r--r--io_import_images_as_planes.py646
1 files changed, 234 insertions, 412 deletions
diff --git a/io_import_images_as_planes.py b/io_import_images_as_planes.py
index f5ad0793..257230e6 100644
--- a/io_import_images_as_planes.py
+++ b/io_import_images_as_planes.py
@@ -18,10 +18,10 @@
bl_addon_info = {
"name": "Import Images as Planes",
- "author": "Florian Meyer (testscreenings)",
- "version": (0,7),
- "blender": (2, 5, 3),
- "api": 31998,
+ "author": "Florian Meyer (tstscr)",
+ "version": (1,0),
+ "blender": (2, 5, 5),
+ "api": 33754,
"location": "File > Import > Images as Planes",
"description": "Imports images and creates planes with the appropriate aspect ratio. The images are mapped to the planes.",
"warning": "",
@@ -31,43 +31,12 @@ bl_addon_info = {
"func=detail&aid=21751&group_id=153&atid=469",
"category": "Import/Export"}
-"""
-This script imports images and creates Planes with them as textures.
-At the moment the naming for objects, materials, textures and meshes
-is derived from the imagename.
-
-One can either import a single image, or all images in one directory.
-When imporing a directory one can either check the checkbox or leave
-the filename empty.
-
-As a bonus one can choose to import images of only one type.
-Atm this is the list of possible extensions:
-extList =
- ('jpeg', 'jpg', 'png', 'tga', 'tiff', 'tif', 'exr',
- 'hdr', 'avi', 'mov', 'mp4', 'ogg', 'bmp', 'cin', 'dpx', 'psd')
-
-If someone knows a better way of telling if a file is an image which
-Blender can read, please tell so ;)
-
-when importing images that are allready referenced they are not
-reimported but the old ones reused as not to clutter the materials,
-textures and image lists.
-Instead the plane gets linked against an existing material.
-
-If one reimports images but chooses different material/texture mapping
-new materials are created.
-So one doesn't has to go through everything if one decides differently
-after importing 236 images.
-
-It also has an option to translate pixeldimensions into Blenderunits.
-"""
-
-import bpy
+import bpy, os, mathutils
from bpy.props import *
-from os import listdir
-from mathutils import Vector
-
+from add_utils import *
+from io_utils import ImportHelper, load_image
+## GLOBAL VARS ##
EXT_LIST = {
'jpeg': ['jpeg', 'jpg', 'jpe'],
'png': ['png'],
@@ -83,317 +52,195 @@ EXT_LIST = {
'cin': ['cin'],
'dpx': ['dpx'],
'psd': ['psd']}
+EXT_VALS = [val for val in EXT_LIST.values()]
+EXTENSIONS = []
+for i in EXT_VALS:
+ EXTENSIONS.extend(i)
+
+## FUNCTIONS ##
+def set_image_options(self, image):
+ image.use_premultiply = self.use_premultiply
+
+def create_image_textures(self, image):
+ #look for texture with importsettings
+ for texture in bpy.data.textures:
+ if texture.type == 'IMAGE'\
+ and texture.image\
+ and texture.image.filepath == image.filepath:
+ if self.use_transparency:
+ texture.use_alpha = True
+ else:
+ texture.use_alpha = False
+ return texture
+
+ #if no texture is found: create one
+ texture = bpy.data.textures.new(name=os.path.split(image.filepath)[1],
+ type='IMAGE')
+ texture.image = image
+ if self.use_transparency:
+ texture.use_alpha = True
+ else:
+ texture.use_alpha = False
+ return texture
-
-# Apply view rotation to objects if "Align To" for new objects
-# was set to "VIEW" in the User Preference.
-def apply_view_rotation(ob):
- context = bpy.context
- align = bpy.context.user_preferences.edit.object_align
-
- if (context.space_data.type == 'VIEW_3D'
- and align == 'VIEW'):
- view3d = context.space_data
- region = view3d.region_3d
- viewMatrix = region.view_matrix
- rot = viewMatrix.rotation_part()
- ob.rotation_euler = rot.invert().to_euler()
-
-
-# Create plane mesh
-def createPlaneMesh(dimension, img):
- # x is the x-aspectRatio.
+def create_material_for_texture(self, texture):
+ #look for material with the needed texture
+ for material in bpy.data.materials:
+ if material.texture_slots[0]\
+ and material.texture_slots[0].texture == texture:
+ if self.use_transparency:
+ material.alpha = 0
+ material.specular_alpha = 0
+ material.texture_slots[0].use_map_alpha = True
+ else:
+ material.alpha = 1
+ material.specular_alpha = 1
+ material.texture_slots[0].use_map_alpha = False
+ material.use_transparency = self.use_transparency
+ material.transparency_method = self.transparency_method
+ material.use_shadeless = self.use_shadeless
+ return material
+
+ # if no material found: create one
+ material = bpy.data.materials.new(name=os.path.split(texture.image.filepath)[1])
+ slot = material.texture_slots.add()
+ slot.texture = texture
+ slot.texture_coords = 'UV'
+ if self.use_transparency:
+ slot.use_map_alpha = True
+ material.alpha = 0
+ material.specular_alpha = 0
+ else:
+ material.alpha = 1
+ material.specular_alpha = 1
+ slot.use_map_alpha = False
+ material.use_transparency = self.use_transparency
+ material.transparency_method = self.transparency_method
+ material.use_shadeless = self.use_shadeless
+
+ return material
+
+def create_image_plane(self, context, material):
+ img = material.texture_slots[0].texture.image
x = img.size[0] / img.size[1]
y = 1
- if dimension[0]:
- x = (img.size[0] * (1.0 / dimension[1])) * 0.5
- y = (img.size[1] * (1.0 / dimension[1])) * 0.5
-
- verts = []
- faces = []
-
- v1 = (-x, -y, 0)
- v2 = (x, -y, 0)
- v3 = (x, y, 0)
- v4 = (-x, y, 0)
-
- verts.append(v1)
- verts.append(v2)
- verts.append(v3)
- verts.append(v4)
-
- faces.append([0, 1, 2, 3])
-
- return verts, faces
-
-
-# Create plane object
-def createPlaneObj(img, dimension):
- scene = bpy.context.scene
-
- verts, faces = createPlaneMesh(dimension, img)
-
- me = bpy.data.meshes.new(img.name)
- me.from_pydata(verts, [], faces)
- me.update()
-
- plane = bpy.data.objects.new(img.name, me)
+ if self.use_dimension:
+ x = (img.size[0] * (1.0 / self.factor)) * 0.5
+ y = (img.size[1] * (1.0 / self.factor)) * 0.5
+
+ verts = [(-x, -y, 0),
+ (x, -y, 0),
+ (x, y, 0),
+ (-x, y, 0)]
+ faces = [[0, 1, 2, 3]]
+
+ mesh_data = bpy.data.meshes.new(img.name)
+ mesh_data.from_pydata(verts, [], faces)
+ mesh_data.update()
+ add_object_data(context, mesh_data, operator=self)
+ plane = context.scene.objects.active
plane.data.uv_textures.new()
-
- scene.objects.link(plane)
- plane.location = scene.cursor_location
- apply_view_rotation(plane)
-
+ plane.data.materials.append(material)
+ plane.data.uv_textures[0].data[0].image = img
+ plane.data.uv_textures[0].data[0].use_image = True
+ plane.data.uv_textures[0].data[0].blend_type = 'ALPHA'
+ plane.data.uv_textures[0].data[0].use_twoside = True
return plane
-
-# Check if a file extension matches any
-# valid (i.e. recognized) image/movie format.
-def isImageFile(extension):
- for ext, ext_list in EXT_LIST.items():
- if extension in ext_list:
- return True
-
- return False
-
-
-# Get imagepaths from directory
-def getImageFilesInDirectory(directory, extension):
- import os
-
- # Get all files in the directory.
- allFiles = listdir(directory)
- allImages = []
-
- extensions = []
-
- # Import all images files?
- if extension == '*':
- all = True
-
- else:
- all = False
- # Get the possible extensions
- extensions = EXT_LIST[extension]
-
- # Put all image files in the list.
- for file in allFiles:
- # Get the file extension (includes the ".")
- e = os.path.splitext(file)[1]
-
- # Separate by "." and get the last list-entry.
- e = e.rpartition(".")[-1]
-
- # Convert to lower case
- e = e.lower()
-
- if (e in extensions
- or (all and isImageFile(e))):
- allImages.append(file)
-
- return allImages
-
-
-# Get image datablock from the (image's) filepath.
-def getImage(path):
- img = []
-
- # Check every Image if it is already there.
- for image in bpy.data.images:
- # If image with same path exists take that one.
- if image.filepath == path:
- img = image
-
- # Else create new Image and load from path.
- if not img:
- name = path.rpartition('\\')[2].rpartition('.')[0]
- img = bpy.data.images.new(name)
- img.source = 'FILE'
- img.filepath = path
-
- return img
-
-
-# Create/get Material
-def getMaterial(tex, mapping):
- mat = []
-
- # Check all existing materials.
- for material in bpy.data.materials:
- # If a material with name and mapping
- # texture with image exists, take that one...
- if (material.name == tex.image.name
- and tex.name in material.texture_slots
- and material.mapping == mapping):
- mat = material
-
- # ... otherwise create new one and apply mapping.
- if not mat:
- mat = bpy.data.materials.new(name=tex.name)
- mtex = mat.texture_slots.add()
- mtex.texture = tex
- mtex.texture_coords = 'UV'
- mtex.use_map_color_diffuse = True
-
- mat.mapping = mapping
- mat.name = tex.name
-
- return mat
-
-
-# Create/get Texture
-def getTexture(path, img):
- tex = []
-
- # Check all existing textures.
- for texture in bpy.data.textures:
- # If an (image)texture with image exists, take that one...
- if (texture.type == 'IMAGE'
- and texture.image
- and texture.image.filepath == path):
- tex = texture
-
- # ... otherwise create a new one and apply mapping.
- if not tex:
- name = path.rpartition('\\')[2].rpartition('.')[0]
- tex = bpy.data.textures.new(name=name, type='IMAGE')
- tex.image = img
-
- return tex
-
-
-# Custom material property - get
-def mapget(self):
- """Custom property of the images_as_planes addon."""
- mapping = []
- mapping.append(self.use_shadeless)
- mapping.append(self.use_transparency)
- mapping.append(self.alpha)
- mapping.append(self.specular_alpha)
- mapping.append(self.transparency_method)
-
- if (self.texture_slots[0]
- and self.texture_slots[0].texture.type == 'IMAGE'
- and self.texture_slots[0].texture.image):
- mapping.append(self.texture_slots[0].texture.image.use_premultiply)
-
- else:
- mapping.append("no image")
-
- return mapping
-
-
-# Custom material property - set
-def mapset(self, value):
- self.use_shadeless = value[0]
- self.use_transparency = value[1]
- self.alpha = float(value[2])
- self.specular_alpha = float(value[3])
- self.transparency_method = value[4]
-
- if (self.texture_slots[0]
- and self.texture_slots[0].texture.type == 'IMAGE'
- and self.texture_slots[0].texture.image):
- self.texture_slots[0].texture.image.use_premultiply = value[5]
- if self.use_transparency:
- self.texture_slots[0].use_map_alpha=True
-
-
-bpy.types.Material.mapping = property(mapget, mapset)
-
-
-def main(filePath, options, mapping, dimension):
+def generate_paths(self):
+ directory, file = os.path.split(self.filepath)
+
+ if file and not self.all_in_directory:
+ #test for extension
+ if not os.path.splitext(file)[1].lstrip('.').lower() in EXTENSIONS:
+ return [], directory
+
+ return [self.filepath], directory
+
+ if not file or self.all_in_directory:
+ imagepaths = []
+ files_in_directory = os.listdir(directory)
+ #clean files from nonimages
+ files_in_directory = [file for file in files_in_directory
+ if os.path.splitext(file)[1].lstrip('.').lower()
+ in EXTENSIONS]
+ #clean from unwanted extensions
+ if self.extension != '*':
+ files_in_directory = [file for file in files_in_directory
+ if os.path.splitext(file)[1].lstrip('.').lower()
+ in EXT_LIST[self.extension]]
+ #create paths
+ for file in files_in_directory:
+ imagepaths.append(os.path.join(directory, file))
+
+ #print(imagepaths)
+ return imagepaths, directory
+
+def align_planes(self, planes):
+ gap = self.align_offset
+ offset = 0
+ for i, plane in enumerate(planes):
+ offset += (plane.dimensions.x / 2) + gap
+ if i == 0: continue
+ move_local = mathutils.Vector((offset, 0, 0))
+ move_world = plane.location + move_local * plane.matrix_world.copy().invert()
+ plane.location += move_world
+ offset += (plane.dimensions.x / 2)
+
+##### MAIN #####
+def import_images(self, context):
+ import_list, directory = generate_paths(self)
images = []
- scene = bpy.context.scene
-
- # If "Create from Directory" (no filepath or checkbox) ####
- if options['dir'] or not filePath[1]:
- imageFiles = getImageFilesInDirectory(filePath[2], options['ext'])
-
- # Check if images are loaded and put them in the list.
- for imageFile in imageFiles:
- img = getImage(str(filePath[2]) + "\\" + str(imageFile))
- images.append(img)
-
- # Deselect all objects.
- bpy.ops.object.select_all(action='DESELECT')
-
- # Assign/get all things.
- for img in images:
- # Create/get Texture
- tex = getTexture(img.filepath, img)
-
- # Create/get Material
- mat = getMaterial(tex, mapping)
-
- # Create Plane
- plane = createPlaneObj(img, dimension)
-
- # Assign Material
- plane.data.materials.append(mat)
-
- # Put Image into UVTextureLayer
- plane.data.uv_textures[0].data[0].image = img
- plane.data.uv_textures[0].data[0].use_image = True
- plane.data.uv_textures[0].data[0].blend_type = 'ALPHA'
- plane.data.uv_textures[0].data[0].use_twoside = True
-
- plane.select = True
- scene.objects.active = plane
-
- # If "Create Single Plane" (filepath and is image)
- else:
- # Deselect all objects.
- bpy.ops.object.select_all(action='DESELECT')
-
- # Check if image is loaded.
- img = getImage(filePath[0])
-
- # Create/get Texture
- tex = getTexture(filePath[0], img)
-
- # Create/get Material
- mat = getMaterial(tex, mapping)
-
- # Create Plane
- plane = createPlaneObj(img, dimension)
-
- # Assign Material
- plane.data.materials.append(mat)
-
- # Put image into UVTextureLayer
- plane.data.uv_textures[0].data[0].image = img
- plane.data.uv_textures[0].data[0].use_image = True
- plane.data.uv_textures[0].data[0].blend_type = 'ALPHA'
- plane.data.uv_textures[0].data[0].use_twoside = True
-
+ textures = []
+ materials = []
+ planes = []
+
+ for path in import_list:
+ images.append(load_image(path, directory))
+
+ for image in images:
+ set_image_options(self, image)
+ textures.append(create_image_textures(self, image))
+
+ for texture in textures:
+ materials.append(create_material_for_texture(self, texture))
+
+ for material in materials:
+ plane = create_image_plane(self, context, material)
+ planes.append(plane)
+
+ context.scene.update()
+ if self.align:
+ align_planes(self, planes)
+
+ for plane in planes:
plane.select = True
- scene.objects.active = plane
-
+
+ self.report(type='INFO',
+ message='Added %i Image Plane(s)' %len(planes))
-# Operator
-class ImportImagesAsPlanes(bpy.types.Operator):
+##### OPERATOR #####
+class IMPORT_OT_image_to_plane(bpy.types.Operator, ImportHelper, AddObjectHelper):
''''''
- bl_idname = "import.images_as_planes"
+ bl_idname = "import.image_to_plane"
bl_label = "Import Images as Planes"
bl_description = "Create mesh plane(s) from image files" \
" with the appropiate aspect ratio."
bl_options = {'REGISTER', 'UNDO'}
- filepath = StringProperty(name="File Path",
- description="Filepath used for importing the file",
- maxlen=1024,
- default="")
- filename = StringProperty(name="File Name",
- description="Name of the file.")
- directory = StringProperty(name="Directory",
- description="Directory of the file.")
- fromDirectory = BoolProperty(name="All in directory",
- description="Import all image files (of the selected type)" \
- " in this directory.",
- default=False)
-
+ ## OPTIONS ##
+ all_in_directory = BoolProperty(name="All in directory",
+ description="Import all image files (of the selected type)" \
+ " in this directory.",
+ default=False)
+ align = BoolProperty(name='Align Planes',
+ description='Create Planes in a row',
+ default=True)
+ align_offset = FloatProperty(name='Offset',
+ description='Space between Planes',
+ min=0, soft_min=0,
+ default=0.1)
extEnum = [
('*', 'All image formats',
'Import all know image (or movie) formats.'),
@@ -413,112 +260,87 @@ class ImportImagesAsPlanes(bpy.types.Operator):
('dpx', 'DPX (.dpx)', 'DPX (Digital Picture Exchange)'),
('psd', 'PSD (.psd)', 'Photoshop Document')]
extension = EnumProperty(name="Extension",
- description="Only import files of this type.",
- items=extEnum)
+ description="Only import files of this type.",
+ items=extEnum)
+ use_dimension = BoolProperty(name="Use image dimensions",
+ description="Use the images pixels to derive the size of the plane.",
+ default=False)
+ factor = IntProperty(name="Pixels/BU",
+ description="Number of pixels per Blenderunit.",
+ min=1,
+ default=500)
+ ## MATERIAL OPTIONS ##
use_shadeless = BoolProperty(name="Shadeless",
- description="Set material to shadeless",
- default=False)
- transp = BoolProperty(name="Use alpha",
- description="Use alphachannel for transparency.",
- default=False)
- use_premultiply = BoolProperty(name="Premultiply",
- description="Premultiply image",
- default=False)
-
+ description="Set material to shadeless",
+ default=False)
+ use_transparency = BoolProperty(name="Use alpha",
+ description="Use alphachannel for transparency.",
+ default=False)
tEnum = [
- ('Z_TRANSPARENCY',
+ ('Z_TRANSPARENCY',
'Z Transparency',
'Use alpha buffer for transparent faces'),
- ('RAYTRACE',
+ ('RAYTRACE',
'Raytrace',
'Use raytracing for transparent refraction rendering.')]
- transp_method = EnumProperty(name="Transp. Method",
- description="Transparency Method",
- items=tEnum)
- useDim = BoolProperty(name="Use image dimensions",
- description="Use the images pixels to derive the size of the plane.",
- default=False)
- factor = IntProperty(name="Pixels/BU",
- description="Number of pixels per Blenderunit.",
- min=1,
- default=500)
+ transparency_method = EnumProperty(name="Transp. Method",
+ description="Transparency Method",
+ items=tEnum)
+ ## IMAGE OPTIONS ##
+ use_premultiply = BoolProperty(name="Premultiply",
+ description="Premultiply image",
+ default=False)
+
+ ## DRAW ##
def draw(self, context):
layout = self.layout
box = layout.box()
- box.label('Filter:', icon='FILTER')
- box.prop(self, 'fromDirectory')
+ box.label('Import Options:', icon='FILTER')
+ box.prop(self, 'all_in_directory')
box.prop(self, 'extension', icon='FILE_IMAGE')
+ box.prop(self, 'align')
+ box.prop(self, 'align_offset')
box = layout.box()
box.label('Material mappings:', icon='MATERIAL')
box.prop(self, 'use_shadeless')
- box.prop(self, 'transp')
+ box.prop(self, 'use_transparency')
box.prop(self, 'use_premultiply')
- box.prop(self, 'transp_method', expand=True)
+ box.prop(self, 'transparency_method', expand=True)
box = layout.box()
box.label('Plane dimensions:', icon='ARROW_LEFTRIGHT')
- box.prop(self, 'useDim')
+ box.prop(self, 'use_dimension')
box.prop(self, 'factor', expand=True)
- def execute(self, context):
- # File Path
- filepath = self.filepath
- filename = self.filename
- directory = self.directory
- filePath = (filepath, filename, directory)
-
- # General Options
- fromDirectory = self.fromDirectory
- extension = self.extension
- options = {'dir': fromDirectory, 'ext': extension}
-
- # Mapping
- alphavalue = 1
- transp = self.transp
- if transp:
- alphavalue = 0
-
- shadeless = self.use_shadeless
- transp_method = self.transp_method
- premultiply = self.use_premultiply
-
- mapping = ([shadeless,
- transp,
- alphavalue,
- alphavalue,
- transp_method,
- premultiply])
-
- # Use Pixelsdimensions
- useDim = self.useDim
- factor = self.factor
- dimension = (useDim, factor)
-
- # Call Main Function
- main(filePath, options, mapping, dimension)
+ ## EXECUTE ##
+ def execute(self, context):
+ #the add utils don't work in this case
+ #because many objects are added
+ #disable relevant things beforehand
+ editmode = context.user_preferences.edit.use_enter_edit_mode
+ context.user_preferences.edit.use_enter_edit_mode = False
+ if context.active_object\
+ and context.active_object.mode == 'EDIT':
+ bpy.ops.object.mode_set(mode='OBJECT')
+
+ import_images(self, context)
+
+ context.user_preferences.edit.use_enter_edit_mode = editmode
return {'FINISHED'}
- def invoke(self, context, event):
- wm = bpy.context.window_manager
- wm.fileselect_add(self)
- return {'RUNNING_MODAL'}
-# Registering / Unregister
-def menu_func(self, context):
- self.layout.operator(ImportImagesAsPlanes.bl_idname, text="Images as Planes", icon='PLUGIN')
+##### REGISTER #####
+def import_images_button(self, context):
+ self.layout.operator(IMPORT_OT_image_to_plane.bl_idname, text="Images as Planes", icon='PLUGIN')
def register():
- bpy.types.INFO_MT_file_import.append(menu_func)
-
-
+ bpy.types.INFO_MT_file_import.append(import_images_button)
def unregister():
- bpy.types.INFO_MT_file_import.remove(menu_func)
-
-
-if __name__ == "__main__":
+ bpy.types.INFO_MT_file_import.remove(import_images_button)
+if __name__ == '__main__':
register()