move load_image into image_utils and add some docstrings to bpy_extras module.
This commit is contained in:
@@ -65,8 +65,9 @@ else:
|
|||||||
"bpy.props",
|
"bpy.props",
|
||||||
"bpy.utils",
|
"bpy.utils",
|
||||||
"bpy.context",
|
"bpy.context",
|
||||||
# "bpy.types", # supports filtering
|
"bpy.types", # supports filtering
|
||||||
"bpy.ops", # supports filtering
|
"bpy.ops", # supports filtering
|
||||||
|
#"bpy_extras",
|
||||||
"bge",
|
"bge",
|
||||||
"aud",
|
"aud",
|
||||||
"bgl",
|
"bgl",
|
||||||
@@ -363,10 +364,8 @@ def pymodule2sphinx(BASEPATH, module_name, module, title):
|
|||||||
for submod_name in module_all:
|
for submod_name in module_all:
|
||||||
ns = {}
|
ns = {}
|
||||||
exec_str = "from %s import %s as submod" % (module.__name__, submod_name)
|
exec_str = "from %s import %s as submod" % (module.__name__, submod_name)
|
||||||
print(exec_str)
|
|
||||||
exec(exec_str, ns, ns)
|
exec(exec_str, ns, ns)
|
||||||
submod = ns["submod"]
|
submod = ns["submod"]
|
||||||
print(submod)
|
|
||||||
if type(submod) == types.ModuleType:
|
if type(submod) == types.ModuleType:
|
||||||
submod_ls.append((submod_name, submod))
|
submod_ls.append((submod_name, submod))
|
||||||
|
|
||||||
|
@@ -19,19 +19,88 @@
|
|||||||
# <pep8 compliant>
|
# <pep8 compliant>
|
||||||
|
|
||||||
__all__ = (
|
__all__ = (
|
||||||
"image_load",
|
"load_image",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# limited replacement for BPyImage.comprehensiveImageLoad
|
||||||
|
def load_image(imagepath,
|
||||||
|
dirname="",
|
||||||
|
place_holder=False,
|
||||||
|
recursive=False,
|
||||||
|
ncase_cmp=True,
|
||||||
|
convert_callback=None,
|
||||||
|
verbose=False,
|
||||||
|
):
|
||||||
|
"""
|
||||||
|
Return an image from the file path with options to search multiple paths and
|
||||||
|
return a placeholder if its not found.
|
||||||
|
|
||||||
def image_load(filepath, dirpath, place_holder=False, recursive=False, convert_callback=None):
|
:arg filepath: The image filename
|
||||||
import bpy
|
If a path precedes it, this will be searched as well.
|
||||||
|
:type filepath: string
|
||||||
|
:arg dirname: is the directory where the image may be located - any file at
|
||||||
|
the end will be ignored.
|
||||||
|
:type dirname: string
|
||||||
|
:arg place_holder: if True a new place holder image will be created.
|
||||||
|
this is usefull so later you can relink the image to its original data.
|
||||||
|
:type place_holder: bool
|
||||||
|
:arg recursive: If True, directories will be recursivly searched.
|
||||||
|
Be carefull with this if you have files in your root directory because
|
||||||
|
it may take a long time.
|
||||||
|
:type recursive: bool
|
||||||
|
:arg ncase_cmp: on non windows systems, find the correct case for the file.
|
||||||
|
:type ncase_cmp: bool
|
||||||
|
:arg convert_callback: a function that takes an existing path and returns a new one.
|
||||||
|
Use this when loading image formats blender may not support, the CONVERT_CALLBACK
|
||||||
|
can take the path for a GIF (for example), convert it to a PNG and return the PNG's path.
|
||||||
|
For formats blender can read, simply return the path that is given.
|
||||||
|
:type convert_callback: function
|
||||||
|
:return: an image or None
|
||||||
|
:rtype: :class:`Image`
|
||||||
|
"""
|
||||||
import os
|
import os
|
||||||
|
|
||||||
try:
|
# TODO: recursive
|
||||||
return bpy.data.images.load(filepath)
|
|
||||||
except RuntimeError:
|
def _image_load(path):
|
||||||
if place_holder:
|
import bpy
|
||||||
image = bpy.data.images.new(os.path.basename(filepath), 128, 128)
|
|
||||||
# allow the path to be resolved later
|
if convert_callback:
|
||||||
image.filepath = filepath
|
path = convert_callback(path)
|
||||||
return image
|
|
||||||
|
image = bpy.data.images.load(path)
|
||||||
|
|
||||||
|
if verbose:
|
||||||
|
print(" image loaded '%s'" % path)
|
||||||
|
|
||||||
|
return image
|
||||||
|
|
||||||
|
if verbose:
|
||||||
|
print("load_image('%s', '%s', ...)" % (imagepath, dirname))
|
||||||
|
|
||||||
|
if os.path.exists(imagepath):
|
||||||
|
return _image_load(imagepath)
|
||||||
|
|
||||||
|
variants = [imagepath]
|
||||||
|
|
||||||
|
if dirname:
|
||||||
|
variants += [os.path.join(dirname, imagepath), os.path.join(dirname, os.path.basename(imagepath))]
|
||||||
|
|
||||||
|
for filepath_test in variants:
|
||||||
|
if ncase_cmp:
|
||||||
|
ncase_variants = filepath_test, bpy.path.resolve_ncase(filepath)
|
||||||
|
else:
|
||||||
|
ncase_variants = (filepath_test, )
|
||||||
|
|
||||||
|
for nfilepath in ncase_variants:
|
||||||
|
if os.path.exists(nfilepath):
|
||||||
|
return _image_load(nfilepath)
|
||||||
|
|
||||||
|
if place_holder:
|
||||||
|
image = bpy.data.images.new(os.path.basename(filepath), 128, 128)
|
||||||
|
# allow the path to be resolved later
|
||||||
|
image.filepath = imagepath
|
||||||
|
return image
|
||||||
|
|
||||||
|
# TODO comprehensiveImageLoad also searched in bpy.config.textureDir
|
||||||
|
return None
|
||||||
|
@@ -22,7 +22,6 @@ __all__ = (
|
|||||||
"ExportHelper",
|
"ExportHelper",
|
||||||
"ImportHelper",
|
"ImportHelper",
|
||||||
"axis_conversion",
|
"axis_conversion",
|
||||||
"load_image",
|
|
||||||
"create_derived_objects",
|
"create_derived_objects",
|
||||||
"free_derived_objects",
|
"free_derived_objects",
|
||||||
"unpack_list",
|
"unpack_list",
|
||||||
@@ -162,24 +161,6 @@ def axis_conversion(from_forward='Y', from_up='Z', to_forward='Y', to_up='Z'):
|
|||||||
assert("internal error")
|
assert("internal error")
|
||||||
|
|
||||||
|
|
||||||
# limited replacement for BPyImage.comprehensiveImageLoad
|
|
||||||
def load_image(imagepath, dirname):
|
|
||||||
import os
|
|
||||||
|
|
||||||
if os.path.exists(imagepath):
|
|
||||||
return bpy.data.images.load(imagepath)
|
|
||||||
|
|
||||||
variants = [imagepath, os.path.join(dirname, imagepath), os.path.join(dirname, os.path.basename(imagepath))]
|
|
||||||
|
|
||||||
for filepath in variants:
|
|
||||||
for nfilepath in (filepath, bpy.path.resolve_ncase(filepath)):
|
|
||||||
if os.path.exists(nfilepath):
|
|
||||||
return bpy.data.images.load(nfilepath)
|
|
||||||
|
|
||||||
# TODO comprehensiveImageLoad also searched in bpy.config.textureDir
|
|
||||||
return None
|
|
||||||
|
|
||||||
|
|
||||||
# return a tuple (free, object list), free is True if memory should be freed later with free_derived_objects()
|
# return a tuple (free, object list), free is True if memory should be freed later with free_derived_objects()
|
||||||
def create_derived_objects(scene, ob):
|
def create_derived_objects(scene, ob):
|
||||||
if ob.parent and ob.parent.dupli_type != 'NONE':
|
if ob.parent and ob.parent.dupli_type != 'NONE':
|
||||||
|
@@ -28,11 +28,15 @@ __all__ = (
|
|||||||
)
|
)
|
||||||
|
|
||||||
def mesh_linked_faces(mesh):
|
def mesh_linked_faces(mesh):
|
||||||
'''
|
"""
|
||||||
Splits the mesh into connected parts,
|
Splits the mesh into connected faces, use this for seperating cubes from
|
||||||
these parts are returned as lists of faces.
|
other mesh elements within 1 mesh datablock.
|
||||||
used for seperating cubes from other mesh elements in the 1 mesh
|
|
||||||
'''
|
:arg mesh: the mesh used to group with.
|
||||||
|
:type mesh: :class:`Mesh`
|
||||||
|
:return: lists of lists containing faces.
|
||||||
|
:rtype: list
|
||||||
|
"""
|
||||||
|
|
||||||
# Build vert face connectivity
|
# Build vert face connectivity
|
||||||
vert_faces = [[] for i in range(len(mesh.vertices))]
|
vert_faces = [[] for i in range(len(mesh.vertices))]
|
||||||
@@ -78,6 +82,11 @@ def mesh_linked_faces(mesh):
|
|||||||
|
|
||||||
|
|
||||||
def edge_face_count_dict(mesh):
|
def edge_face_count_dict(mesh):
|
||||||
|
"""
|
||||||
|
:return: dict of edge keys with their value set to the number of
|
||||||
|
faces using each edge.
|
||||||
|
:rtype: dict
|
||||||
|
"""
|
||||||
face_edge_keys = [face.edge_keys for face in mesh.faces]
|
face_edge_keys = [face.edge_keys for face in mesh.faces]
|
||||||
face_edge_count = {}
|
face_edge_count = {}
|
||||||
for face_keys in face_edge_keys:
|
for face_keys in face_edge_keys:
|
||||||
@@ -91,8 +100,13 @@ def edge_face_count_dict(mesh):
|
|||||||
|
|
||||||
|
|
||||||
def edge_face_count(mesh):
|
def edge_face_count(mesh):
|
||||||
|
"""
|
||||||
|
:return: list face users for each item in mesh.edges.
|
||||||
|
:rtype: list
|
||||||
|
"""
|
||||||
edge_face_count_dict = edge_face_count_dict(mesh)
|
edge_face_count_dict = edge_face_count_dict(mesh)
|
||||||
return [edge_face_count_dict.get(ed.key, 0) for ed in mesh.edges]
|
get = dict.get
|
||||||
|
return [get(edge_face_count_dict, ed.key, 0) for ed in mesh.edges]
|
||||||
|
|
||||||
|
|
||||||
def edge_loops_from_faces(mesh, faces=None, seams=()):
|
def edge_loops_from_faces(mesh, faces=None, seams=()):
|
||||||
@@ -101,12 +115,18 @@ def edge_loops_from_faces(mesh, faces=None, seams=()):
|
|||||||
|
|
||||||
Takes me.faces or a list of faces and returns the edge loops
|
Takes me.faces or a list of faces and returns the edge loops
|
||||||
These edge loops are the edges that sit between quads, so they dont touch
|
These edge loops are the edges that sit between quads, so they dont touch
|
||||||
1 quad, note: not connected will make 2 edge loops, both only containing 2 edges.
|
1 quad, note: not connected will make 2 edge loops,
|
||||||
|
both only containing 2 edges.
|
||||||
|
|
||||||
return a list of edge key lists
|
return a list of edge key lists
|
||||||
[ [(0,1), (4, 8), (3,8)], ...]
|
[[(0, 1), (4, 8), (3, 8)], ...]
|
||||||
|
|
||||||
return a list of edge vertex index lists
|
:arg mesh: the mesh used to get edge loops from.
|
||||||
|
:type mesh: :class:`Mesh`
|
||||||
|
:arg faces: optional face list to only use some of the meshes faces.
|
||||||
|
:type faces: :class:`MeshFaces`, sequence or or NoneType
|
||||||
|
:return: return a list of edge vertex index lists.
|
||||||
|
:rtype: list
|
||||||
"""
|
"""
|
||||||
|
|
||||||
OTHER_INDEX = 2, 3, 0, 1 # opposite face index
|
OTHER_INDEX = 2, 3, 0, 1 # opposite face index
|
||||||
@@ -117,7 +137,7 @@ def edge_loops_from_faces(mesh, faces=None, seams=()):
|
|||||||
edges = {}
|
edges = {}
|
||||||
|
|
||||||
for f in faces:
|
for f in faces:
|
||||||
# if len(f) == 4:
|
# if len(f) == 4:
|
||||||
if f.vertices_raw[3] != 0:
|
if f.vertices_raw[3] != 0:
|
||||||
edge_keys = f.edge_keys
|
edge_keys = f.edge_keys
|
||||||
for i, edkey in enumerate(f.edge_keys):
|
for i, edkey in enumerate(f.edge_keys):
|
||||||
|
@@ -29,6 +29,16 @@ import mathutils
|
|||||||
|
|
||||||
|
|
||||||
def add_object_align_init(context, operator):
|
def add_object_align_init(context, operator):
|
||||||
|
"""
|
||||||
|
Return a matrix using the operator settings and view context.
|
||||||
|
|
||||||
|
:arg context: The context to use.
|
||||||
|
:type context: :class:`Context`
|
||||||
|
:arg operator: The operator, checked for location and rotation properties.
|
||||||
|
:type operator: :class:`Operator`
|
||||||
|
:return: the matrix from the context and settings.
|
||||||
|
:rtype: :class:`Matrix`
|
||||||
|
"""
|
||||||
space_data = context.space_data
|
space_data = context.space_data
|
||||||
if space_data.type != 'VIEW_3D':
|
if space_data.type != 'VIEW_3D':
|
||||||
space_data = None
|
space_data = None
|
||||||
@@ -70,7 +80,19 @@ def add_object_align_init(context, operator):
|
|||||||
|
|
||||||
|
|
||||||
def object_data_add(context, obdata, operator=None):
|
def object_data_add(context, obdata, operator=None):
|
||||||
|
"""
|
||||||
|
Add an object using the view context and preference to to initialize the
|
||||||
|
location, rotation and layer.
|
||||||
|
|
||||||
|
:arg context: The context to use.
|
||||||
|
:type context: :class:`Context`
|
||||||
|
:arg obdata: the data used for the new object.
|
||||||
|
:type obdata: valid object data type or None.
|
||||||
|
:arg operator: The operator, checked for location and rotation properties.
|
||||||
|
:type operator: :class:`Operator`
|
||||||
|
:return: the newly created object in the scene.
|
||||||
|
:rtype: :class:`ObjectBase`
|
||||||
|
"""
|
||||||
scene = context.scene
|
scene = context.scene
|
||||||
|
|
||||||
# ugh, could be made nicer
|
# ugh, could be made nicer
|
||||||
|
Reference in New Issue
Block a user