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:
Diffstat (limited to 'release/scripts/modules/bpy_types.py')
-rw-r--r--release/scripts/modules/bpy_types.py207
1 files changed, 111 insertions, 96 deletions
diff --git a/release/scripts/modules/bpy_types.py b/release/scripts/modules/bpy_types.py
index 84d05a7a48d..f7429474b06 100644
--- a/release/scripts/modules/bpy_types.py
+++ b/release/scripts/modules/bpy_types.py
@@ -23,6 +23,7 @@ import _bpy
from mathutils import Vector
StructRNA = bpy_types.Struct.__bases__[0]
+StructMetaPropGroup = _bpy.StructMetaPropGroup
# StructRNA = bpy_types.Struct
@@ -141,19 +142,19 @@ class _GenericBone:
def x_axis(self):
""" Vector pointing down the x-axis of the bone.
"""
- return self.matrix.rotation_part() * Vector((1.0, 0.0, 0.0))
+ return Vector((1.0, 0.0, 0.0)) * self.matrix.to_3x3()
@property
def y_axis(self):
""" Vector pointing down the x-axis of the bone.
"""
- return self.matrix.rotation_part() * Vector((0.0, 1.0, 0.0))
+ return Vector((0.0, 1.0, 0.0)) * self.matrix.to_3x3()
@property
def z_axis(self):
""" Vector pointing down the x-axis of the bone.
"""
- return self.matrix.rotation_part() * Vector((0.0, 0.0, 1.0))
+ return Vector((0.0, 0.0, 1.0)) * self.matrix.to_3x3()
@property
def basename(self):
@@ -187,7 +188,7 @@ class _GenericBone:
@length.setter
def length(self, value):
- self.tail = self.head + ((self.tail - self.head).normalize() * value)
+ self.tail = self.head + ((self.tail - self.head).normalized() * value)
@property
def vector(self):
@@ -251,21 +252,21 @@ class _GenericBone:
bones = id_data.pose.bones
elif id_data_type == bpy_types.Armature:
bones = id_data.edit_bones
- if not bones: # not in editmode
+ if not bones: # not in editmode
bones = id_data.bones
return bones
-class PoseBone(StructRNA, _GenericBone):
+class PoseBone(StructRNA, _GenericBone, metaclass=StructMetaPropGroup):
__slots__ = ()
-class Bone(StructRNA, _GenericBone):
+class Bone(StructRNA, _GenericBone, metaclass=StructMetaPropGroup):
__slots__ = ()
-class EditBone(StructRNA, _GenericBone):
+class EditBone(StructRNA, _GenericBone, metaclass=StructMetaPropGroup):
__slots__ = ()
def align_orientation(self, other):
@@ -277,19 +278,29 @@ class EditBone(StructRNA, _GenericBone):
self.tail = self.head + vec
self.roll = other.roll
- def transform(self, matrix):
+ def transform(self, matrix, scale=True, roll=True):
"""
Transform the the bones head, tail, roll and envalope (when the matrix has a scale component).
- Expects a 4x4 or 3x3 matrix.
+
+ :arg matrix: 3x3 or 4x4 transformation matrix.
+ :type matrix: :class:`Matrix`
+ :arg scale: Scale the bone envalope by the matrix.
+ :type scale: bool
+ :arg roll: Correct the roll to point in the same relative direction to the head and tail.
+ :type roll: bool
"""
from mathutils import Vector
- z_vec = self.matrix.rotation_part() * Vector((0.0, 0.0, 1.0))
- self.tail = matrix * self.tail
- self.head = matrix * self.head
- scalar = matrix.median_scale
- self.head_radius *= scalar
- self.tail_radius *= scalar
- self.align_roll(matrix * z_vec)
+ z_vec = Vector((0.0, 0.0, 1.0)) * self.matrix.to_3x3()
+ self.tail = self.tail * matrix
+ self.head = self.head * matrix
+
+ if scale:
+ scalar = matrix.median_scale
+ self.head_radius *= scalar
+ self.tail_radius *= scalar
+
+ if roll:
+ self.align_roll(z_vec * matrix)
def ord_ind(i1, i2):
@@ -301,18 +312,25 @@ def ord_ind(i1, i2):
class Mesh(bpy_types.ID):
__slots__ = ()
- def from_pydata(self, verts, edges, faces):
+ def from_pydata(self, vertices, edges, faces):
"""
Make a mesh from a list of verts/edges/faces
Until we have a nicer way to make geometry, use this.
+
+ :arg vertices: float triplets each representing (X, Y, Z) eg: [(0.0, 1.0, 0.5), ...].
+ :type vertices: iterable object
+ :arg edges: int pairs, each pair contains two indices to the *vertices* argument. eg: [(1, 2), ...]
+ :type edges: iterable object
+ :arg faces: iterator of faces, each faces contains three or four indices to the *vertices* argument. eg: [(5, 6, 8, 9), (1, 2, 3), ...]
+ :type faces: iterable object
"""
- self.vertices.add(len(verts))
+ self.vertices.add(len(vertices))
self.edges.add(len(edges))
self.faces.add(len(faces))
- verts_flat = [f for v in verts for f in v]
- self.vertices.foreach_set("co", verts_flat)
- del verts_flat
+ vertices_flat = [f for v in vertices for f in v]
+ self.vertices.foreach_set("co", vertices_flat)
+ del vertices_flat
edges_flat = [i for e in edges for i in e]
self.edges.foreach_set("vertices", edges_flat)
@@ -325,7 +343,7 @@ class Mesh(bpy_types.ID):
else:
return f[0], f[1], f[2], 0
elif f[2] == 0 or f[3] == 0:
- return f[3], f[0], f[1], f[2]
+ return f[2], f[3], f[0], f[1]
return f
faces_flat = [v for f in faces for v in treat_face(f)]
@@ -368,7 +386,7 @@ class Mesh(bpy_types.ID):
return a list of edge vertex index lists
"""
- OTHER_INDEX = 2, 3, 0, 1 # opposite face index
+ OTHER_INDEX = 2, 3, 0, 1 # opposite face index
if faces is None:
faces = self.faces
@@ -389,7 +407,7 @@ class Mesh(bpy_types.ID):
edge_loops = []
for edkey, ed_adj in edges.items():
- if 0 < len(ed_adj) < 3: # 1 or 2
+ if 0 < len(ed_adj) < 3: # 1 or 2
# Seek the first edge
context_loop = [edkey, ed_adj[0]]
edge_loops.append(context_loop)
@@ -407,11 +425,11 @@ class Mesh(bpy_types.ID):
ed_adj = edges[context_loop[-1]]
if len(ed_adj) != 2:
- if other_dir and flipped == False: # the original edge had 2 other edges
- flipped = True # only flip the list once
+ if other_dir and flipped == False: # the original edge had 2 other edges
+ flipped = True # only flip the list once
context_loop.reverse()
ed_adj[:] = []
- context_loop.append(other_dir) # save 1 lookiup
+ context_loop.append(other_dir) # save 1 lookiup
ed_adj = edges[context_loop[-1]]
if len(ed_adj) != 2:
@@ -427,7 +445,6 @@ class Mesh(bpy_types.ID):
# Dont look at this again
ed_adj[:] = []
-
return edge_loops
def edge_loops_from_edges(self, edges=None):
@@ -543,83 +560,38 @@ class Text(bpy_types.ID):
import bpy
return tuple(obj for obj in bpy.data.objects if self in [cont.text for cont in obj.game.controllers if cont.type == 'PYTHON'])
-import collections
-
+# values are module: [(cls, path, line), ...]
TypeMap = {}
-# Properties (IDPropertyGroup) are different from types because they need to be registered
-# before adding sub properties to them, so they are registered on definition
-# and unregistered on unload
-PropertiesMap = {}
-
-# Using our own loading function we set this to false
-# so when running a script directly in the text editor
-# registers moduals instantly.
-_register_immediate = True
-
-def _unregister_module(module, free=True):
- for t in TypeMap.get(module, ()):
- try:
- bpy_types.unregister(t)
- except:
- import traceback
- print("bpy.utils._unregister_module(): Module '%s' failed to unregister class '%s.%s'" % (module, t.__module__, t.__name__))
- traceback.print_exc()
-
- if free == True and module in TypeMap:
- del TypeMap[module]
-
-
- for t in PropertiesMap.get(module, ()):
- try:
- bpy_types.unregister(t)
- except:
- import traceback
- print("bpy.utils._unload_module(): Module '%s' failed to unregister class '%s.%s'" % (module, t.__module__, t.__name__))
- traceback.print_exc()
-
- if free == True and module in PropertiesMap:
- del PropertiesMap[module]
-
-
-def _register_module(module):
- for t in TypeMap.get(module, ()):
- try:
- bpy_types.register(t)
- except:
- import traceback
- print("bpy.utils._register_module(): Module '%s' failed to register class '%s.%s'" % (module, t.__module__, t.__name__))
- traceback.print_exc()
class RNAMeta(type):
- @classmethod
- def _register_immediate(cls):
- return _register_immediate
-
def __new__(cls, name, bases, classdict, **args):
result = type.__new__(cls, name, bases, classdict)
if bases and bases[0] != StructRNA:
+ import traceback
+ import weakref
module = result.__module__
- ClassMap = TypeMap
-
- # Register right away if needed
- if cls._register_immediate():
- bpy_types.register(result)
- ClassMap = PropertiesMap
-
# first part of packages only
if "." in module:
module = module[:module.index(".")]
-
- ClassMap.setdefault(module, []).append(result)
+
+ sf = traceback.extract_stack(limit=2)[0]
+
+ TypeMap.setdefault(module, []).append((weakref.ref(result), sf[0], sf[1]))
return result
-class RNAMetaRegister(RNAMeta):
- @classmethod
- def _register_immediate(cls):
- return True
+ @property
+ def is_registered(cls):
+ return "bl_rna" in cls.__dict__
+
+import collections
+
+
+class RNAMetaPropGroup(RNAMeta, StructMetaPropGroup):
+ pass
+
class OrderedMeta(RNAMeta):
@@ -630,10 +602,39 @@ class OrderedMeta(RNAMeta):
def __prepare__(name, bases, **kwargs):
return collections.OrderedDict()
+
# Only defined so operators members can be used by accessing self.order
+# with doc generation 'self.properties.bl_rna.properties' can fail
class Operator(StructRNA, metaclass=OrderedMeta):
__slots__ = ()
+ def __getattribute__(self, attr):
+ properties = StructRNA.path_resolve(self, "properties")
+ bl_rna = getattr(properties, "bl_rna", None)
+ if bl_rna and attr in bl_rna.properties:
+ return getattr(properties, attr)
+ return super().__getattribute__(attr)
+
+ def __setattr__(self, attr, value):
+ properties = StructRNA.path_resolve(self, "properties")
+ bl_rna = getattr(properties, "bl_rna", None)
+ if bl_rna and attr in bl_rna.properties:
+ return setattr(properties, attr, value)
+ return super().__setattr__(attr, value)
+
+ def __delattr__(self, attr):
+ properties = StructRNA.path_resolve(self, "properties")
+ bl_rna = getattr(properties, "bl_rna", None)
+ if bl_rna and attr in bl_rna.properties:
+ return delattr(properties, attr)
+ return super().__delattr__(attr)
+
+ def as_keywords(self, ignore=()):
+ """ Return a copy of the properties as a dictionary.
+ """
+ ignore = ignore + ("rna_type",)
+ return {attr: getattr(self, attr) for attr in self.properties.rna_type.properties.keys() if attr not in ignore}
+
class Macro(StructRNA, metaclass=OrderedMeta):
# bpy_types is imported before ops is defined
@@ -644,13 +645,20 @@ class Macro(StructRNA, metaclass=OrderedMeta):
def define(self, opname):
from _bpy import ops
return ops.macro_define(self, opname)
-
-class IDPropertyGroup(StructRNA, metaclass=RNAMetaRegister):
+
+
+class PropertyGroup(StructRNA, metaclass=RNAMetaPropGroup):
__slots__ = ()
+
class RenderEngine(StructRNA, metaclass=RNAMeta):
__slots__ = ()
+
+class KeyingSetInfo(StructRNA, metaclass=RNAMeta):
+ __slots__ = ()
+
+
class _GenericUI:
__slots__ = ()
@@ -662,7 +670,12 @@ class _GenericUI:
def draw_ls(self, context):
for func in draw_ls._draw_funcs:
- func(self, context)
+ # so bad menu functions dont stop the entire menu from drawing.
+ try:
+ func(self, context)
+ except:
+ import traceback
+ traceback.print_exc()
draw_funcs = draw_ls._draw_funcs = [cls.draw]
cls.draw = draw_ls
@@ -671,7 +684,7 @@ class _GenericUI:
@classmethod
def append(cls, draw_func):
- """Prepend an draw function to this menu, takes the same arguments as the menus draw function."""
+ """Append a draw function to this menu, takes the same arguments as the menus draw function."""
draw_funcs = cls._dyn_ui_initialize()
draw_funcs.append(draw_func)
@@ -711,6 +724,9 @@ class Menu(StructRNA, _GenericUI, metaclass=RNAMeta):
layout = self.layout
+ if not searchpaths:
+ layout.label("* Missing Paths *")
+
# collect paths
files = []
for directory in searchpaths:
@@ -732,7 +748,6 @@ class Menu(StructRNA, _GenericUI, metaclass=RNAMeta):
props.filepath = filepath
if operator == "script.execute_preset":
props.menu_idname = self.bl_idname
- props.preset_name = preset_name
def draw_preset(self, context):
"""Define these on the subclass