remove api field, was never used
[blender-addons-contrib.git] / object_drop_to_ground.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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
16 #
17 # ##### END GPL LICENSE BLOCK #####
18 bl_info = {
19     "name": "Drop to ground",
20     "author": "Unnikrishnan(kodemax), Florian Meyer(testscreenings)",
21     "version": (1, 1),
22     "blender": (2, 5, 9),
23     "location": "Tool shelf",
24     "description": "Drops the selected objects to the active object",
25     "warning": "Before using it do :- ctrl+a -> apply rotation on the object to be dropped",
26     "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.5/Py/Scripts/Object/Drop_to_ground",
27     "tracker_url": "http://projects.blender.org/tracker/?func=detail&atid=467&aid=25349",
28     "category": "Object"}
29  
30 import bpy , random
31 from bpy.props import *
32 import mathutils
33 import math
34  
35 def get_align_matrix(location, normal):
36     up = mathutils.Vector((0,0,1))                      
37     angle = normal.angle(up)
38     axis = up.cross(normal)                            
39     mat_rot = mathutils.Matrix.Rotation(angle, 4, axis) 
40     mat_loc = mathutils.Matrix.Translation(location)
41     mat_align = mat_rot * mat_loc                      
42     return mat_align
43
44
45 def get_lowest_Coord1(ob):
46     matrix = ob.matrix_world.copy()
47     verts = ob.data.vertices
48     lowest = mathutils.Vector((0,0,10000))
49     for vert in verts:
50         if (matrix * vert.co).z < lowest.z:
51             lowest = matrix * vert.co
52     return lowest
53
54
55 def do_drop(context,tmpObj, ob):
56     print('\n', ob.name)
57     align_object = context.scene.align_object
58     use_center = context.scene.use_center
59     lowest = get_lowest_Coord1(ob)
60     location, normal, index = tmpObj.ray_cast(lowest, lowest + mathutils.Vector((0,0,-10000)))
61         
62     if not index == -1:
63         if not use_center:
64             temp = (bpy.context.scene.cursor_location).copy()
65             bpy.context.scene.cursor_location = lowest
66             bpy.ops.object.origin_set(type = 'ORIGIN_CURSOR')
67             
68         if align_object:
69             sca = ob.scale.copy()
70             mat_align = get_align_matrix(location, normal)
71             ob.matrix_world = mat_align
72             ob.scale = sca 
73             
74         else:
75             ob.location = location
76          
77         
78         if not use_center:
79             bpy.context.scene.cursor_location = temp
80             bpy.ops.object.origin_set(type = 'ORIGIN_GEOMETRY')
81    
82     else:
83         print('\nno hit')
84         return    
85
86 # compute randomisation based on the general or specific percentage chosen
87 # if the specific percentage is zero then the general percentage is used
88 def compute_percentage(min,max,value,percentage):
89     range = max-min
90     general_percentage = 100
91     
92     if percentage == 0:
93         percentage_random = ( value -((range*(general_percentage/100))/2) )+ (range * (general_percentage / 100) * random.random())
94     else:
95         percentage_random = ( value - ((range*(percentage/100))/2)) + (range * (percentage / 100) * random.random())
96          
97     if percentage_random > max:
98         percentage_random = max
99     if percentage_random < min:
100         percentage_random = min
101     
102     return percentage_random 
103
104 def main(self, context):
105
106     print('\n_______START__________')
107     obs = bpy.context.selected_objects
108     ground = bpy.context.active_object
109     obs.remove(ground)
110     context = bpy.context
111     sc = context.scene
112
113
114     tmpMesh = ground.to_mesh(sc, True, 'PREVIEW')
115     tmpMesh.transform(ground.matrix_world)
116     tmpObj = bpy.data.objects.new('tmpGround', tmpMesh)
117     """tmpObj.update(sc, 1, 1, 1)"""
118     sc.objects.link(tmpObj)
119     sc.update()
120
121     for ob in obs:
122         bpy.ops.object.select_all(action='DESELECT')
123         ob.select = True
124         
125         #randomise location it its enabled
126         if sc.random_loc :
127             print("randomising the location of object : ", ob.name)
128             print("current location :" + str(ob.location))
129             bpy.ops.transform.translate(value=(compute_percentage(sc.rl_min_x,sc.rl_max_x,0,100),
130                            compute_percentage(sc.rl_min_y,sc.rl_max_y,0,100),
131                            compute_percentage(sc.rl_min_z,sc.rl_max_z,0,100)))
132             print("randomised location : ", str(ob.location))
133         do_drop(context, tmpObj, ob)
134
135     bpy.ops.object.select_all(action='DESELECT')
136     tmpObj.select = True
137     bpy.ops.object.delete('EXEC_DEFAULT')
138
139     for ob in obs:
140         ob.select = True
141     ground.select = True
142
143  
144 class VIEW3D_PT_tools_drop_to_ground(bpy.types.Panel):
145     bl_space_type = 'VIEW_3D'
146     bl_region_type = 'TOOLS'
147     bl_label = "Drop to ground"
148     bl_context = "objectmode"
149
150     def draw(self, context):
151         active_obj = context.active_object
152         layout = self.layout
153         col = layout.column(align=True)
154         col.operator("object.drop_to_ground", text="Drop")
155         col.prop(context.scene, "align_object")
156         col.prop(context.scene, "use_center")
157         box= layout.box()
158         box.prop(context.scene, "random_loc")
159         
160         # random location gui appears only if its enabled
161         if bpy.context.scene.random_loc:
162             
163             row = box.row()
164             row.label(text="(X,Y,Z) [min/max]")
165             row = box.row()
166             a = row.split(percentage = 0.5, align = True)
167             a.prop(context.scene, "rl_min_x")
168             a.prop(context.scene, "rl_max_x")
169             row = box.row()
170             b = row.split(percentage = 0.5, align = True)
171             b.prop(context.scene, "rl_min_y")
172             b.prop(context.scene, "rl_max_y")
173             row = box.row()
174             b = row.split(percentage = 0.5, align = True)
175             b.prop(context.scene, "rl_min_z")
176             b.prop(context.scene, "rl_max_z")
177         
178 class OBJECT_OT_drop_to_ground(bpy.types.Operator):
179     """Drop to ground"""
180     bl_idname = "object.drop_to_ground"
181     bl_label = "Drop to ground"
182     bl_description = "Drops selected objects onto the active object"
183     bl_options = {'REGISTER', 'UNDO'}
184  
185     def execute(self, context):
186         main(self, context)
187         return {'FINISHED'}
188
189  
190  
191 #### REGISTER ####
192
193 def register():
194     bpy.utils.register_module(__name__)
195     bpy.types.Scene.align_object = BoolProperty(
196         name="Align object to ground",
197         description="Aligns the object to the ground",
198         default=True)
199     bpy.types.Scene.use_center = BoolProperty(
200         name="Use the center to drop",
201         description="When dropping the object will be relocated on the basis of its senter",
202         default=False)
203     
204     #random location props
205     bpy.types.Scene.random_loc = BoolProperty(
206         name="Random Location",
207         description="When dropping the object will be relocated randomly ",
208         default=False)
209     bpy.types.Scene.rl_min_x =  IntProperty(name="min", description = " Minimum of location randomisation while droped to the ground for the x axis", default = 0)
210     bpy.types.Scene.rl_max_x =  IntProperty(name="max", description = " Maximum of location randomisation while droped to the ground for the x axis", default = 0)
211     bpy.types.Scene.rl_min_y =  IntProperty(name="min", description = " Minimum of location randomisation while droped to the ground for the y axis", default = 0)
212     bpy.types.Scene.rl_max_y =  IntProperty(name="max", description = " Maximum of location randomisation while droped to the ground for the y axis", default = 0)
213     bpy.types.Scene.rl_min_z =  IntProperty(name="min", description = " Minimum of location randomisation while droped to the ground for the z axis", default = 0)
214     bpy.types.Scene.rl_max_z =  IntProperty(name="max", description = " Maximum of location randomisation while droped to the ground for the z axis", default = 0)
215      
216 def unregister():
217     bpy.utils.unregister_module(__name__)
218     del bpy.types.Scene.align_object
219     del bpy.types.Scene.use_center
220     del bpy.types.Scene.random_loc
221     del bpy.types.Scene.rl_min_x
222     del bpy.types.Scene.rl_max_x
223     del bpy.types.Scene.rl_min_y
224     del bpy.types.Scene.rl_max_y
225     del bpy.types.Scene.rl_min_z
226     del bpy.types.Scene.rl_max_z
227     
228 if __name__ == '__main__':
229     register()