~ubuntu-branches/ubuntu/gutsy/blender/gutsy-security

« back to all changes in this revision

Viewing changes to release/scripts/object_drop.py

  • Committer: Bazaar Package Importer
  • Author(s): Florian Ernst
  • Date: 2007-05-17 11:47:59 UTC
  • mfrom: (1.2.6 upstream)
  • Revision ID: james.westby@ubuntu.com-20070517114759-yp4ybrnhp2u7pk66
Tags: 2.44-1
* New upstream release.
* Drop debian/patches/01_64bits_stupidity, not needed anymore: as of this
  version blender is 64 bits safe again. Adjust README.Debian accordingly.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#!BPY
 
2
"""
 
3
Name: 'Drop Onto Ground'
 
4
Blender: 243
 
5
Group: 'Object'
 
6
Tooltip: 'Drop the selected objects onto "ground" objects'
 
7
"""
 
8
__author__= "Campbell Barton"
 
9
__url__= ["blender.org", "blenderartists.org"]
 
10
__version__= "1.0"
 
11
 
 
12
__bpydoc__= """
 
13
"""
 
14
 
 
15
# --------------------------------------------------------------------------
 
16
# Drop Objects v1.0 by Campbell Barton (AKA Ideasman42)
 
17
# --------------------------------------------------------------------------
 
18
# ***** BEGIN GPL LICENSE BLOCK *****
 
19
#
 
20
# This program is free software; you can redistribute it and/or
 
21
# modify it under the terms of the GNU General Public License
 
22
# as published by the Free Software Foundation; either version 2
 
23
# of the License, or (at your option) any later version.
 
24
#
 
25
# This program is distributed in the hope that it will be useful,
 
26
# but WITHOUT ANY WARRANTY; without even the implied warranty of
 
27
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
28
# GNU General Public License for more details.
 
29
#
 
30
# You should have received a copy of the GNU General Public License
 
31
# along with this program; if not, write to the Free Software Foundation,
 
32
# Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 
33
#
 
34
# ***** END GPL LICENCE BLOCK *****
 
35
# --------------------------------------------------------------------------
 
36
 
 
37
 
 
38
from Blender import Draw, Geometry, Mathutils, Window
 
39
import bpy
 
40
 
 
41
 
 
42
GLOBALS = {}
 
43
GLOBALS['GROUND_SOURCE'] = [Draw.Create(1), Draw.Create(0)]
 
44
GLOBALS['GROUND_GROUP_NAME'] = Draw.Create('terrain')
 
45
GLOBALS['DROP_AXIS'] = [Draw.Create(1), Draw.Create(0)]                                         # on what axis will we drop?
 
46
GLOBALS['DROP_OVERLAP_CHECK'] = Draw.Create(1)                          # is the terrain a single skin?
 
47
GLOBALS['EVENT'] = 2
 
48
GLOBALS['MOUSE'] = None
 
49
 
 
50
def collect_terrain_triangles(obs_terrain):
 
51
        terrain_tris = []
 
52
        me = bpy.data.meshes.new()
 
53
        
 
54
        for ob in obs_terrain:
 
55
                # this matrix takes the object and drop matrix into account
 
56
                ob_mat = ob.matrixWorld # * drop_matrix
 
57
                
 
58
                def blend_face_to_terrain_tris(f):
 
59
                        cos = [v.co*ob_mat for v in f]
 
60
                        if len(cos) == 4:       return [(cos[0], cos[1], cos[2]), (cos[0], cos[2], cos[3])]
 
61
                        else:                           return [(cos[0], cos[1], cos[2]), ]
 
62
                
 
63
                # Clear
 
64
                me.verts = None
 
65
                try:    me.getFromObject(ob)
 
66
                except: pass
 
67
                
 
68
                for f in me.faces: # may be [], thats ok
 
69
                        terrain_tris.extend( blend_face_to_terrain_tris(f) )
 
70
        
 
71
        me.verts = None # clear to save ram
 
72
        return terrain_tris
 
73
 
 
74
def calc_drop_loc(ob, terrain_tris, axis):
 
75
        pt = Mathutils.Vector(ob.loc)
 
76
        
 
77
        isect = None
 
78
        isect_best = None
 
79
        isect_best_len = 0.0
 
80
        
 
81
        for t1,t2,t3 in terrain_tris:
 
82
                #if Geometry.PointInTriangle2D(pt, t1,t2,t3):
 
83
                isect = Mathutils.Intersect(t1, t2, t3, axis, pt, 1) # 1==clip
 
84
                if isect:
 
85
                        if not GLOBALS['DROP_OVERLAP_CHECK'].val:
 
86
                                # Find the first location
 
87
                                return isect
 
88
                        else:
 
89
                                if isect_best:
 
90
                                        isect_len = (pt-isect).length
 
91
                                        if isect_len < isect_best_len:
 
92
                                                isect_best_len = isect_len
 
93
                                                isect_best = isect
 
94
                                        
 
95
                                else:
 
96
                                        isect_best_len = (pt-isect).length
 
97
                                        isect_best = isect;
 
98
        return isect_best
 
99
 
 
100
 
 
101
def error_nogroup():
 
102
        Draw.PupMenu('The Group name does not exist')
 
103
def error_noact():
 
104
        Draw.PupMenu('There is no active object')
 
105
def error_noground():
 
106
        Draw.PupMenu('No triangles could be found to drop the objects onto')
 
107
def error_no_obs():
 
108
        Draw.PupMenu('No objects selected to drop')
 
109
 
 
110
# event and value arnt used
 
111
def terrain_clamp(event, value):
 
112
        
 
113
        sce = bpy.data.scenes.active
 
114
        if GLOBALS['GROUND_SOURCE'][0].val:
 
115
                obs_terrain = [sce.objects.active]
 
116
                if not obs_terrain[0]:
 
117
                        error_noact()
 
118
                        return
 
119
        else:
 
120
                try:    obs_terrain = bpy.data.groups[ GLOBALS['GROUND_GROUP_NAME'].val ].objects
 
121
                except:
 
122
                        error_nogroup()
 
123
                        return
 
124
        
 
125
        obs_clamp = [ob for ob in sce.objects.context if ob not in obs_terrain and not ob.lib]
 
126
        if not obs_clamp:
 
127
                error_no_obs()
 
128
                return
 
129
        
 
130
        terrain_tris = collect_terrain_triangles(obs_terrain)
 
131
        if not terrain_tris:
 
132
                error_noground()
 
133
                return
 
134
        
 
135
        
 
136
        
 
137
        if GLOBALS['DROP_AXIS'][0].val:
 
138
                axis = Mathutils.Vector(0,0,-1)
 
139
        else:
 
140
                axis = Mathutils.Vector(Window.GetViewVector())
 
141
        
 
142
        for ob in obs_clamp:
 
143
                loc = calc_drop_loc(ob, terrain_tris, axis)
 
144
                if loc:
 
145
                        ob.loc = loc
 
146
        
 
147
        # to make the while loop exist
 
148
        GLOBALS['EVENT'] = EVENT_EXIT
 
149
 
 
150
 
 
151
# UI STUFF ------------------------
 
152
def do_axis_z(e,v):     
 
153
        GLOBALS['DROP_AXIS'][0].val = 1
 
154
        GLOBALS['DROP_AXIS'][1].val = 0
 
155
        GLOBALS['EVENT'] = e
 
156
 
 
157
def do_axis_view(e,v):
 
158
        GLOBALS['DROP_AXIS'][0].val = 0
 
159
        GLOBALS['DROP_AXIS'][1].val = 1
 
160
        GLOBALS['EVENT'] = e
 
161
 
 
162
def do_ground_source_act(e,v):
 
163
        GLOBALS['GROUND_SOURCE'][0].val = 1
 
164
        GLOBALS['GROUND_SOURCE'][1].val = 0
 
165
        GLOBALS['EVENT'] = e
 
166
 
 
167
def do_ground_source_group(e,v):
 
168
        GLOBALS['GROUND_SOURCE'][0].val = 0
 
169
        GLOBALS['GROUND_SOURCE'][1].val = 1
 
170
        GLOBALS['EVENT'] = e
 
171
 
 
172
def do_ground_group_name(e,v):
 
173
        try: g =        bpy.data.groups[v]
 
174
        except: g =     None
 
175
        if not g:       error_nogroup()
 
176
        GLOBALS['EVENT'] = e
 
177
        
 
178
 
 
179
 
 
180
EVENT_NONE = 0
 
181
EVENT_EXIT = 1
 
182
EVENT_REDRAW = 2
 
183
def terain_clamp_ui():
 
184
        
 
185
        # Only to center the UI
 
186
        x,y = GLOBALS['MOUSE']
 
187
        x-=40
 
188
        y-=60
 
189
        
 
190
        Draw.Label('Drop Axis', x-70,y+120, 60, 20)
 
191
        Draw.BeginAlign()
 
192
        GLOBALS['DROP_AXIS'][0] = Draw.Toggle('Z',              EVENT_REDRAW, x+20, y+120, 30, 20, GLOBALS['DROP_AXIS'][0].val, 'Drop down on the global Z axis', do_axis_z)
 
193
        GLOBALS['DROP_AXIS'][1] = Draw.Toggle('View Z', EVENT_REDRAW, x+50, y+120, 70, 20, GLOBALS['DROP_AXIS'][1].val, 'Drop allong the view vector', do_axis_view)
 
194
        Draw.EndAlign()
 
195
        
 
196
        # Source
 
197
        Draw.Label('Drop on to...', x-70,y+90, 120, 20)
 
198
        Draw.BeginAlign()
 
199
        GLOBALS['GROUND_SOURCE'][0] = Draw.Toggle('Active Object',      EVENT_REDRAW, x-70, y+70, 110, 20, GLOBALS['GROUND_SOURCE'][0].val, '', do_ground_source_act)
 
200
        GLOBALS['GROUND_SOURCE'][1] = Draw.Toggle('Group',                      EVENT_REDRAW, x+40, y+70, 80, 20, GLOBALS['GROUND_SOURCE'][1].val, '', do_ground_source_group)
 
201
        if GLOBALS['GROUND_SOURCE'][1].val:
 
202
                GLOBALS['GROUND_GROUP_NAME'] = Draw.String('GR:',       EVENT_REDRAW+1001, x-70, y+50, 190, 20, GLOBALS['GROUND_GROUP_NAME'].val, 21, '', do_ground_group_name)
 
203
        Draw.EndAlign()
 
204
        
 
205
        GLOBALS['DROP_OVERLAP_CHECK'] = Draw.Toggle('Overlapping Terrain', EVENT_NONE, x-70, y+20, 190, 20, GLOBALS['DROP_OVERLAP_CHECK'].val, "Check all terrain triangles and use the top most (slow)")
 
206
        
 
207
        Draw.PushButton('Drop Objects', EVENT_EXIT, x+20, y-10, 100, 20, 'Drop the selected objects', terrain_clamp)
 
208
        
 
209
        # So moving the mouse outside the popup exits the while loop
 
210
        GLOBALS['EVENT'] = EVENT_EXIT
 
211
 
 
212
def main():
 
213
        
 
214
        # This is to set the position if the popup
 
215
        GLOBALS['MOUSE'] = Window.GetMouseCoords()
 
216
        
 
217
        # hack so the toggle buttons redraw. this is not nice at all
 
218
        while GLOBALS['EVENT'] == EVENT_REDRAW:
 
219
                Draw.UIBlock(terain_clamp_ui)
 
220
        
 
221
if __name__ == '__main__':
 
222
        main()
 
223
 
 
224
GLOBALS.clear()
 
 
b'\\ No newline at end of file'