Small fix for undefined variable in vertex loop if the list is empty.
[blender-addons-contrib.git] / object_physics_meadow / duplimesh.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
19 # <pep8 compliant>
20
21 import bpy, sys
22 from math import *
23 from mathutils import *
24
25 def project_on_ground(groundob, co):
26     groundmat4 = groundob.matrix_world
27     inv_groundmat4 = groundmat4.inverted()
28     groundmat3 = groundmat4.to_3x3()
29     
30     zmin = min(p[2] for p in groundob.bound_box) - 1.0
31     zmax = max(p[2] for p in groundob.bound_box) + 1.0
32     
33     obco = inv_groundmat4 * Vector(co[0:3] + (1.0,)) # co expected to be in world space
34     ray_start = (obco[0], obco[1], zmax)
35     ray_end = (obco[0], obco[1], zmin)
36     
37     hit, nor, index = groundob.ray_cast(ray_start, ray_end)
38     if index >= 0:
39         return True, groundmat4 * hit, groundmat3 * nor, index
40     else:
41         return False, co, (0.0, 0.0, 1.0), -1
42
43
44 def make_dupli_mesh(name, obmat, samples, scale):
45     scalemat = Matrix()
46     scalemat[0][0] = scalemat[1][1] = scalemat[2][2] = scale
47     scalemat[3][3] = 1.0
48     
49     invobmat = obmat.inverted()
50     
51     def make_verts():
52         verts = []
53         i = 0
54         for i, (loc, rot) in enumerate(samples):
55             mat = Matrix.Translation(loc) * invobmat * rot * scalemat
56             verts.append(mat * Vector((-0.86603, -0.5, 0.0)))
57             verts.append(mat * Vector(( 0.86603, -0.5, 0.0)))
58             verts.append(mat * Vector(( 0.0,      1.0, 0.0)))
59         return i, verts
60     
61     def edges(tot):
62         for i in range(tot):
63             yield (i*3 + 0, i*3 + 1)
64             yield (i*3 + 1, i*3 + 2)
65             yield (i*3 + 2, i*3 + 0)
66     
67     def faces(tot):
68         for i in range(tot):
69             yield (i*3 + 0, i*3 + 1, i*3 + 2)
70     
71     tot, verts = make_verts()
72     mesh = bpy.data.meshes.new(name)
73     # XXX edges somehow are broken, but can be calculated automatically
74     #mesh.from_pydata(verts, [e for e in edges(tot)], [f for f in faces(tot)])
75     mesh.from_pydata(verts, [], [f for f in faces(tot)])
76     mesh.update()
77     return mesh