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.utils",
 | 
			
		||||
        "bpy.context",
 | 
			
		||||
        # "bpy.types",  # supports filtering
 | 
			
		||||
        "bpy.types",  # supports filtering
 | 
			
		||||
        "bpy.ops",  # supports filtering
 | 
			
		||||
        #"bpy_extras",
 | 
			
		||||
        "bge",
 | 
			
		||||
        "aud",
 | 
			
		||||
        "bgl",
 | 
			
		||||
@@ -363,10 +364,8 @@ def pymodule2sphinx(BASEPATH, module_name, module, title):
 | 
			
		||||
        for submod_name in module_all:
 | 
			
		||||
            ns = {}
 | 
			
		||||
            exec_str = "from %s import %s as submod" % (module.__name__, submod_name)
 | 
			
		||||
            print(exec_str)
 | 
			
		||||
            exec(exec_str, ns, ns)
 | 
			
		||||
            submod = ns["submod"]
 | 
			
		||||
            print(submod)
 | 
			
		||||
            if type(submod) == types.ModuleType:
 | 
			
		||||
                submod_ls.append((submod_name, submod))
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -19,19 +19,88 @@
 | 
			
		||||
# <pep8 compliant>
 | 
			
		||||
 | 
			
		||||
__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):
 | 
			
		||||
    import bpy
 | 
			
		||||
    :arg filepath: The image filename
 | 
			
		||||
       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
 | 
			
		||||
 | 
			
		||||
    try:
 | 
			
		||||
        return bpy.data.images.load(filepath)
 | 
			
		||||
    except RuntimeError:
 | 
			
		||||
    # TODO: recursive
 | 
			
		||||
 | 
			
		||||
    def _image_load(path):
 | 
			
		||||
        import bpy
 | 
			
		||||
 | 
			
		||||
        if convert_callback:
 | 
			
		||||
            path = convert_callback(path)
 | 
			
		||||
 | 
			
		||||
        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 = filepath
 | 
			
		||||
        image.filepath = imagepath
 | 
			
		||||
        return image
 | 
			
		||||
 | 
			
		||||
    # TODO comprehensiveImageLoad also searched in bpy.config.textureDir
 | 
			
		||||
    return None
 | 
			
		||||
 
 | 
			
		||||
@@ -22,7 +22,6 @@ __all__ = (
 | 
			
		||||
    "ExportHelper",
 | 
			
		||||
    "ImportHelper",
 | 
			
		||||
    "axis_conversion",
 | 
			
		||||
    "load_image",
 | 
			
		||||
    "create_derived_objects",
 | 
			
		||||
    "free_derived_objects",
 | 
			
		||||
    "unpack_list",
 | 
			
		||||
@@ -162,24 +161,6 @@ def axis_conversion(from_forward='Y', from_up='Z', to_forward='Y', to_up='Z'):
 | 
			
		||||
    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()
 | 
			
		||||
def create_derived_objects(scene, ob):
 | 
			
		||||
    if ob.parent and ob.parent.dupli_type != 'NONE':
 | 
			
		||||
 
 | 
			
		||||
@@ -28,11 +28,15 @@ __all__ = (
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
def mesh_linked_faces(mesh):
 | 
			
		||||
    '''
 | 
			
		||||
    Splits the mesh into connected parts,
 | 
			
		||||
    these parts are returned as lists of faces.
 | 
			
		||||
    used for seperating cubes from other mesh elements in the 1 mesh
 | 
			
		||||
    '''
 | 
			
		||||
    """
 | 
			
		||||
    Splits the mesh into connected faces, use this for seperating cubes from
 | 
			
		||||
    other mesh elements within 1 mesh datablock.
 | 
			
		||||
 | 
			
		||||
    :arg mesh: the mesh used to group with.
 | 
			
		||||
    :type mesh: :class:`Mesh`
 | 
			
		||||
    :return: lists of lists containing faces.
 | 
			
		||||
    :rtype: list
 | 
			
		||||
    """
 | 
			
		||||
 | 
			
		||||
    # Build vert face connectivity
 | 
			
		||||
    vert_faces = [[] for i in range(len(mesh.vertices))]
 | 
			
		||||
@@ -78,6 +82,11 @@ def mesh_linked_faces(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_count = {}
 | 
			
		||||
    for face_keys in face_edge_keys:
 | 
			
		||||
@@ -91,8 +100,13 @@ def edge_face_count_dict(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)
 | 
			
		||||
    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=()):
 | 
			
		||||
@@ -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
 | 
			
		||||
    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
 | 
			
		||||
    [[(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
 | 
			
		||||
 
 | 
			
		||||
@@ -29,6 +29,16 @@ import mathutils
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
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
 | 
			
		||||
    if space_data.type != 'VIEW_3D':
 | 
			
		||||
        space_data = None
 | 
			
		||||
@@ -70,7 +80,19 @@ def add_object_align_init(context, operator):
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
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
 | 
			
		||||
 | 
			
		||||
    # ugh, could be made nicer
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user