use f.area where possible over python function and use len(mface) over len(mface.v)
[blender.git] / release / scripts / envelope_symmetry.py
1 #!BPY
2
3 """
4 Name: 'Envelope Symmetry'
5 Blender: 234
6 Group: 'Animation'
7 Tooltip: 'Make envelope symetrical'
8 """
9
10 __author__ = "Jonas Petersen"
11 __url__ = ("blender", "elysiun", "Script's homepage, http://www.mindfloaters.de/blender/", "thread at blender.org, http://www.blender.org/modules.php?op=modload&name=phpBB2&file=viewtopic&t=4858 ")
12 __version__ = "0.9 2004-11-10"
13 __doc__ = """\
14 This script creates perfectly symmetrical envelope sets.  It is part of the
15 envelop assignment tools.
16
17 "Envelopes" are Mesh objects with names following this naming convention:
18
19 <bone name>:<float value>
20
21 Please check the script's homepage and the thread at blender.org (last link button above) for more info.
22
23 For this version users need to edit the script code to change default options.
24 """
25
26 # --------------------------------------------------------------------------
27 # "Envelope Symmetry" by Jonas Petersen
28 # Version 0.9 - 10th November 2004 - first public release
29 # --------------------------------------------------------------------------
30 #
31 # A script for creating perfectly symmetrical envelope sets. It is
32 # part of the envelope assignment tool.
33 #
34 # It is available in Object Mode via the menu item:
35 #
36 #   Object -> Scripts -> Envelope Symmetry
37 #
38 # With default settings it will:
39 #
40 # - Look for bones
41 #
42 # Find the latest version at: http://www.mindfloaters.de/blender/
43 #
44 # --------------------------------------------------------------------------
45 # $Id$
46 # --------------------------------------------------------------------------
47 # ***** BEGIN GPL LICENSE BLOCK *****
48 #
49 # Copyright (C) 2004: Jonas Petersen, jonas at mindfloaters dot de
50 #
51 # This program is free software; you can redistribute it and/or
52 # modify it under the terms of the GNU General Public License
53 # as published by the Free Software Foundation; either version 2
54 # of the License, or (at your option) any later version.
55 #
56 # This program is distributed in the hope that it will be useful,
57 # but WITHOUT ANY WARRANTY; without even the implied warranty of
58 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
59 # GNU General Public License for more details.
60 #
61 # You should have received a copy of the GNU General Public License
62 # along with this program; if not, write to the Free Software Foundation,
63 # Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
64 #
65 # ***** END GPL LICENCE BLOCK *****
66
67 # --------------------------------------------------------------------------
68 # CONFIGURATION
69 # --------------------------------------------------------------------------
70
71 # Note: Theses values will later be editable via a gui interface
72 # within Blender.
73
74 # The suffix for the reference and opposite envelope.
75 # The configuration of of the opposite envelope will be overwritten by
76 # the configuration of the reference envelope (shape, position, bone, weight).
77 # The default is REF_SUFFIX = '.L' and OPP_SUFFIX = '.R'.
78 REF_SUFFIX = '.R'
79 OPP_SUFFIX = '.L'
80
81 # MIRROR_AXIS defines the axis in which bones are mirrored/aligned.
82 # Values:
83 #   0 for X (default)
84 #   1 for Y
85 #   2 for Z
86 MIRROR_AXIS = 0
87
88 # SEPARATOR is the character used to delimit the bone name and the weight
89 # in the envelope name.
90 SEPARATOR = ":"
91
92 # --------------------------------------------------------------------------
93 # END OF CONFIGURATION
94 # --------------------------------------------------------------------------
95
96 import Blender, math, sys
97 from Blender import Mathutils
98 from BPyNMesh import *
99
100 def flipFace(v):
101         if len(v) == 3: v[0], v[1], v[2] = v[2], v[1], v[0]
102         elif len(v) == 4: v[0], v[1], v[2], v[3] = v[3], v[2], v[1], v[0]
103
104 # return object with given object name (with variable parts) and mesh name
105 def getObjectByName(obj_name, mesh_name):
106         objs = Blender.Object.Get()
107         for obj in objs:
108                 if obj.getType() == "Mesh":
109 #                       if obj.getName()[0:len(obj_name)] == obj_name and obj.getData().name == mesh_name:
110                         # use only mesh_name so bone name and weight (in the envelope name)
111                         # can be changed by the user and mirrored by the script.
112                         if obj.getData().name == mesh_name:
113                                 return obj
114         return False
115
116 SUFFIX_LEN = len(REF_SUFFIX);
117
118 Blender.Window.EditMode(0)
119
120 count = 0
121 objs = Blender.Object.Get()
122 for obj in objs:
123         if obj.getType() != 'Mesh':
124                 continue
125
126         count += 1
127         name = obj.getName()
128         pos = name.find(SEPARATOR)
129         if (pos > -1):
130                 ApplySizeAndRotation(obj)
131
132                 base_name = name[0:pos-SUFFIX_LEN]
133                 suffix = name[pos-SUFFIX_LEN:pos]
134                 weight = name[pos:len(name)] # the SEPARATOR following a float value
135
136                 if suffix == REF_SUFFIX:
137                         mesh = obj.getData()
138                         mirror_name = base_name +  OPP_SUFFIX + weight
139                         mirror_mesh_name = mesh.name + ".mirror"
140
141                         mirror_obj = getObjectByName(base_name + OPP_SUFFIX, mirror_mesh_name)
142
143                         if mirror_obj:
144
145                                 # update vertices
146
147                                 mirror_mesh = mirror_obj.getData()
148                                 for i in range(len(mesh.verts)):
149                                         org = mesh.verts[i]
150                                         mir = mirror_mesh.verts[i]
151                                         mir.co[0], mir.co[1], mir.co[2] = org.co[0], org.co[1], org.co[2]
152                                         mir.co[MIRROR_AXIS] *= -1
153
154                                 mirror_mesh.update()
155                         else:
156
157                                 # create mirror object
158
159                                 mirror_mesh = Blender.NMesh.GetRaw(obj.getData().name)
160                                 for face in mirror_mesh.faces:
161                                         flipFace(face.v)
162                                 for vert in mirror_mesh.verts:
163                                         vert.co[MIRROR_AXIS] *= -1
164
165                                 mirror_obj = Blender.NMesh.PutRaw(mirror_mesh, mirror_mesh_name)
166
167                         # update name, drawType and location
168                         
169                         mirror_obj.setName(mirror_name)
170                         mirror_obj.drawType = obj.drawType
171
172                         loc = [obj.LocX, obj.LocY, obj.LocZ]
173                         loc[MIRROR_AXIS] *= -1
174                         mirror_obj.setLocation(loc)
175
176 Blender.Window.EditMode(0)