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:
authorJoerg Mueller <nexyon@gmail.com>2011-07-22 01:11:58 +0400
committerJoerg Mueller <nexyon@gmail.com>2011-07-22 01:11:58 +0400
commit4532bd731d5edbe348d4df810856f6bdfdea705c (patch)
tree778fdcd594b5f384eacf5cd82f50afc10bbed513 /release/scripts/modules
parentcf34f7509f4ea8c3f0c92045933f089c72de5313 (diff)
parentbbfe3c9c49523d3987a3144da119d8f6afd09cf9 (diff)
Merge with trunk up to r38584.
Diffstat (limited to 'release/scripts/modules')
-rw-r--r--release/scripts/modules/addon_utils.py12
-rw-r--r--release/scripts/modules/bpy/path.py13
-rw-r--r--release/scripts/modules/bpy/utils.py9
-rw-r--r--release/scripts/modules/bpy_extras/image_utils.py6
-rw-r--r--release/scripts/modules/bpy_extras/io_utils.py41
-rw-r--r--release/scripts/modules/bpy_extras/mesh_utils.py73
6 files changed, 145 insertions, 9 deletions
diff --git a/release/scripts/modules/addon_utils.py b/release/scripts/modules/addon_utils.py
index 07f1dc618dc..cf74282d064 100644
--- a/release/scripts/modules/addon_utils.py
+++ b/release/scripts/modules/addon_utils.py
@@ -31,6 +31,8 @@ __all__ = (
import bpy as _bpy
+error_duplicates = False
+
def paths():
# RELEASE SCRIPTS: official scripts distributed in Blender releases
paths = _bpy.utils.script_paths("addons")
@@ -47,8 +49,11 @@ def paths():
def modules(module_cache):
+ global error_duplicates
import os
+ error_duplicates = False
+
path_list = paths()
# fake module importing
@@ -117,7 +122,12 @@ def modules(module_cache):
modules_stale -= {mod_name}
mod = module_cache.get(mod_name)
if mod:
- if mod.__time__ != os.path.getmtime(mod_path):
+ if mod.__file__ != mod_path:
+ print("multiple addons with the same name:\n %r\n %r" %
+ (mod.__file__, mod_path))
+ error_duplicates = True
+
+ elif mod.__time__ != os.path.getmtime(mod_path):
print("reloading addon:", mod_name, mod.__time__, os.path.getmtime(mod_path), mod_path)
del module_cache[mod_name]
mod = None
diff --git a/release/scripts/modules/bpy/path.py b/release/scripts/modules/bpy/path.py
index 5e95428f641..f6254efac2e 100644
--- a/release/scripts/modules/bpy/path.py
+++ b/release/scripts/modules/bpy/path.py
@@ -35,7 +35,7 @@ def abspath(path, start=None):
:type start: string
"""
if path.startswith("//"):
- return _os.path.join(_os.path.dirname(_bpy.data.filepath if start is None else start), path[2:])
+ return _os.path.join(_os.path.dirname(_bpy.data.filepath) if start is None else start, path[2:])
return path
@@ -117,7 +117,7 @@ def display_name_from_filepath(name):
"""
Returns the path stripped of directort and extension, ensured to be utf8 compatible.
"""
- return _os.path.splitext(_os.path.basename(name))[0].encode("utf8", "replace").decode("utf8")
+ return _os.path.splitext(basename(name))[0].encode("utf8", "replace").decode("utf8")
def resolve_ncase(path):
@@ -231,3 +231,12 @@ def module_names(path, recursive=False):
modules.append(("%s.%s" % (filename, mod_name), mod_path))
return modules
+
+
+def basename(path):
+ """
+ Equivalent to os.path.basename, but skips a "//" suffix.
+
+ Use for Windows compatibility.
+ """
+ return _os.path.basename(path[2:] if path.startswith("//") else path)
diff --git a/release/scripts/modules/bpy/utils.py b/release/scripts/modules/bpy/utils.py
index 7c0d3d24cba..57d3e6dd703 100644
--- a/release/scripts/modules/bpy/utils.py
+++ b/release/scripts/modules/bpy/utils.py
@@ -298,11 +298,18 @@ _presets = _os.path.join(_scripts[0], "presets") # FIXME - multiple paths
def preset_paths(subdir):
"""
Returns a list of paths for a specific preset.
+
+ :arg subdir: preset subdirectory (must not be an absolute path).
+ :type subdir: string
+ :return: script paths.
+ :rtype: list
"""
dirs = []
for path in script_paths("presets", all=True):
directory = _os.path.join(path, subdir)
- if _os.path.isdir(directory):
+ if not directory.startswith(path):
+ raise Exception("invalid subdir given %r" % subdir)
+ elif _os.path.isdir(directory):
dirs.append(directory)
return dirs
diff --git a/release/scripts/modules/bpy_extras/image_utils.py b/release/scripts/modules/bpy_extras/image_utils.py
index f91535a0ad4..e56c1c651c4 100644
--- a/release/scripts/modules/bpy_extras/image_utils.py
+++ b/release/scripts/modules/bpy_extras/image_utils.py
@@ -86,7 +86,9 @@ def load_image(imagepath,
variants = [imagepath]
if dirname:
- variants += [os.path.join(dirname, imagepath), os.path.join(dirname, os.path.basename(imagepath))]
+ variants += [os.path.join(dirname, imagepath),
+ os.path.join(dirname, bpy.path.basename(imagepath)),
+ ]
for filepath_test in variants:
if ncase_cmp:
@@ -99,7 +101,7 @@ def load_image(imagepath,
return _image_load(nfilepath)
if place_holder:
- image = bpy.data.images.new(os.path.basename(imagepath), 128, 128)
+ image = bpy.data.images.new(bpy.path.basename(imagepath), 128, 128)
# allow the path to be resolved later
image.filepath = imagepath
return image
diff --git a/release/scripts/modules/bpy_extras/io_utils.py b/release/scripts/modules/bpy_extras/io_utils.py
index cfa2233f7b6..9545e20b025 100644
--- a/release/scripts/modules/bpy_extras/io_utils.py
+++ b/release/scripts/modules/bpy_extras/io_utils.py
@@ -22,6 +22,7 @@ __all__ = (
"ExportHelper",
"ImportHelper",
"axis_conversion",
+ "axis_conversion_ensure",
"create_derived_objects",
"free_derived_objects",
"unpack_list",
@@ -154,12 +155,50 @@ def axis_conversion(from_forward='Y', from_up='Z', to_forward='Y', to_up='Z'):
if from_forward == to_forward and from_up == to_up:
return Matrix().to_3x3()
+ if from_forward[-1] == from_up[-1] or to_forward[-1] == to_up[-1]:
+ raise Exception("invalid axis arguments passed, "
+ "can't use up/forward on the same axis.")
+
value = reduce(int.__or__, (_axis_convert_num[a] << (i * 3) for i, a in enumerate((from_forward, from_up, to_forward, to_up))))
for i, axis_lut in enumerate(_axis_convert_lut):
if value in axis_lut:
return Matrix(_axis_convert_matrix[i])
- assert("internal error")
+ assert(0)
+
+
+def axis_conversion_ensure(operator, forward_attr, up_attr):
+ """
+ Function to ensure an operator has valid axis conversion settings, intended
+ to be used from :class:`Operator.check`.
+
+ :arg operator: the operator to access axis attributes from.
+ :type operator: :class:`Operator`
+ :arg forward_attr:
+ :type forward_attr: string
+ :arg up_attr: the directory the *filepath* will be referenced from (normally the export path).
+ :type up_attr: string
+ :return: True if the value was modified.
+ :rtype: boolean
+ """
+ def validate(axis_forward, axis_up):
+ if axis_forward[-1] == axis_up[-1]:
+ axis_up = axis_up[0:-1] + 'XYZ'[('XYZ'.index(axis_up[-1]) + 1) % 3]
+
+ return axis_forward, axis_up
+
+ change = False
+
+ axis = getattr(operator, forward_attr), getattr(operator, up_attr)
+ axis_new = validate(*axis)
+
+ if axis != axis_new:
+ setattr(operator, forward_attr, axis_new[0])
+ setattr(operator, up_attr, axis_new[1])
+
+ return True
+ else:
+ return False
# return a tuple (free, object list), free is True if memory should be freed later with free_derived_objects()
diff --git a/release/scripts/modules/bpy_extras/mesh_utils.py b/release/scripts/modules/bpy_extras/mesh_utils.py
index 34925ccb5e9..c42d3d0236a 100644
--- a/release/scripts/modules/bpy_extras/mesh_utils.py
+++ b/release/scripts/modules/bpy_extras/mesh_utils.py
@@ -16,7 +16,7 @@
#
# ##### END GPL LICENSE BLOCK #####
-# <pep8 compliant>
+# <pep8-80 compliant>
__all__ = (
"mesh_linked_faces",
@@ -25,6 +25,7 @@ __all__ = (
"edge_loops_from_faces",
"edge_loops_from_edges",
"ngon_tesselate",
+ "face_random_points",
)
@@ -67,7 +68,8 @@ def mesh_linked_faces(mesh):
if mapped_index != nxt_mapped_index:
ok = True
- # Assign mapping to this group so they all map to this group
+ # Assign mapping to this group so they
+ # all map to this group
for grp_f in face_groups[nxt_mapped_index]:
face_mapping[grp_f.index] = mapped_index
@@ -433,3 +435,70 @@ def ngon_tesselate(from_data, indices, fix_loops=True):
fill[i] = tuple([ii for ii in reversed(fi)])
return fill
+
+
+def face_random_points(num_points, faces):
+ """
+ Generates a list of random points over mesh faces.
+
+ :arg num_points: the number of random points to generate on each face.
+ :type int:
+ :arg faces: list of the faces to generate points on.
+ :type faces: :class:`MeshFaces`, sequence
+ :return: list of random points over all faces.
+ :rtype: list
+ """
+
+ from random import random
+ from mathutils.geometry import area_tri
+
+ # Split all quads into 2 tris, tris remain unchanged
+ tri_faces = []
+ for f in faces:
+ tris = []
+ verts = f.id_data.vertices
+ fv = f.vertices[:]
+ tris.append((verts[fv[0]].co,
+ verts[fv[1]].co,
+ verts[fv[2]].co,
+ ))
+ if len(fv) == 4:
+ tris.append((verts[fv[0]].co,
+ verts[fv[3]].co,
+ verts[fv[2]].co,
+ ))
+ tri_faces.append(tris)
+
+ # For each face, generate the required number of random points
+ sampled_points = [None] * (num_points * len(faces))
+ for i, tf in enumerate(tri_faces):
+ for k in range(num_points):
+ # If this is a quad, we need to weight its 2 tris by their area
+ if len(tf) != 1:
+ area1 = area_tri(*tf[0])
+ area2 = area_tri(*tf[1])
+ area_tot = area1 + area2
+
+ area1 = area1 / area_tot
+ area2 = area2 / area_tot
+
+ vecs = tf[0 if (random() < area1) else 1]
+ else:
+ vecs = tf[0]
+
+ u1 = random()
+ u2 = random()
+ u_tot = u1 + u2
+
+ if u_tot > 1:
+ u1 = 1.0 - u1
+ u2 = 1.0 - u2
+
+ side1 = vecs[1] - vecs[0]
+ side2 = vecs[2] - vecs[0]
+
+ p = vecs[0] + u1 * side1 + u2 * side2
+
+ sampled_points[num_points * i + k] = p
+
+ return sampled_points