more ui api changes.
[blender.git] / release / scripts / modules / bpy_types.py
1 # ##### BEGIN GPL LICENSE BLOCK #####
2 #
3 #  This program is free software; you can redistribute it and/or
4 #  modify it under the terms of the GNU General Public License
5 #  as published by the Free Software Foundation; either version 2
6 #  of the License, or (at your option) any later version.
7 #
8 #  This program is distributed in the hope that it will be useful,
9 #  but WITHOUT ANY WARRANTY; without even the implied warranty of
10 #  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11 #  GNU General Public License for more details.
12 #
13 #  You should have received a copy of the GNU General Public License
14 #  along with this program; if not, write to the Free Software Foundation,
15 #  Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
16 #
17 # ##### END GPL LICENSE BLOCK #####
18 from _bpy import types as bpy_types
19
20 StructRNA = bpy_types.Struct.__bases__[0]
21 # StructRNA = bpy_types.Struct
22
23
24 class Context(StructRNA):
25
26     def copy(self):
27         new_context = {}
28         generic_keys = StructRNA.__dict__.keys()
29         for item in dir(self):
30             if item not in generic_keys:
31                 new_context[item] = getattr(self, item)
32
33         return new_context
34
35
36 class Object(bpy_types.ID):
37
38     def _get_children(self):
39         import bpy
40         return [child for child in bpy.data.objects if child.parent == self]
41
42     children = property(_get_children)
43
44
45 def ord_ind(i1,i2):
46     if i1<i2: return i1,i2
47     return i2,i1
48
49 class Mesh(bpy_types.ID):
50
51     def _get_edge_keys(self):
52         return [edge_key for face in self.faces for edge_key in face.edge_keys]
53
54     edge_keys = property(_get_edge_keys)
55
56     def _get_edge_face_count_dict(self):
57         face_edge_keys = [face.edge_keys for face in self.faces]
58         face_edge_count = {}
59         for face_keys in face_edge_keys:
60             for key in face_keys:
61                 try:
62                     face_edge_count[key] += 1
63                 except:
64                     face_edge_count[key] = 1
65
66         return face_edge_count
67
68     edge_face_count_dict = property(_get_edge_face_count_dict)
69
70     def _get_edge_face_count(self):
71         edge_face_count_dict = self.edge_face_count_dict
72         return [edge_face_count_dict.get(ed.key, 0) for ed in mesh.edges]
73
74     edge_face_count = property(_get_edge_face_count)
75
76
77 class MeshEdge(StructRNA):
78
79     def _get_key(self):
80         return ord_ind(*tuple(self.verts))
81
82     key = property(_get_key)
83
84
85 class MeshFace(StructRNA):
86
87     def _get_edge_keys(self):
88         verts = tuple(self.verts)
89         if len(verts)==3:
90             return ord_ind(verts[0], verts[1]),  ord_ind(verts[1], verts[2]),  ord_ind(verts[2], verts[0])
91
92         return ord_ind(verts[0], verts[1]),  ord_ind(verts[1], verts[2]),  ord_ind(verts[2], verts[3]),  ord_ind(verts[3], verts[0])
93
94     edge_keys = property(_get_edge_keys)
95
96
97 import collections
98 class OrderedMeta(type):
99     def __init__(cls, name, bases, attributes):
100         super(OrderedMeta, cls).__init__(name, bases, attributes)
101         cls.order = list(attributes.keys())
102     def __prepare__(name, bases, **kwargs):
103         return collections.OrderedDict()
104
105
106 # Only defined so operators members can be used by accessing self.order
107 class Operator(StructRNA, metaclass=OrderedMeta):
108     pass
109
110
111 class Menu(StructRNA):
112     
113     def path_menu(self, searchpaths, operator):
114         layout = self.layout
115         # hard coded to set the operators 'path' to the filename.
116         
117         import os
118
119         def path_to_name(f):
120             ''' Only capitalize all lowercase names, mixed case use them as is.
121             '''
122             f_base = os.path.splitext(f)[0]
123             
124             # string replacements
125             f_base = f_base.replace("_colon_", ":")
126             
127             f_base = f_base.replace("_", " ")
128             
129             if f_base.lower() == f_base:
130                 return ' '.join([w[0].upper() + w[1:] for w in f_base.split()])
131             else:
132                 return f_base
133
134         layout = self.layout
135
136         # collect paths
137         files = []
138         for path in searchpaths:
139             files.extend([(f, os.path.join(path, f)) for f in os.listdir(path)])
140
141         files.sort()
142
143         for f, path in files:
144
145             if f.startswith("."):
146                 continue
147
148             layout.operator(operator, text=path_to_name(f)).path = path
149     
150     def draw_preset(self, context):
151         '''Define these on the subclass
152          - preset_operator
153          - preset_subdir
154         '''
155         import bpy
156         self.path_menu(bpy.utils.preset_paths(self.preset_subdir), self.preset_operator)