1 # ##### BEGIN GPL LICENSE BLOCK #####
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.
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.
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.
17 # ##### END GPL LICENSE BLOCK #####
21 # Script copyright (C) Blender Foundation 2012
24 def points_as_bmesh_cells(verts
,
31 from mathutils
import Vector
35 points_sorted_current
= [p
for p
in points
]
39 if points_scale
is not None:
40 points_scale
= tuple(points_scale
)
41 if points_scale
== (1.0, 1.0, 1.0):
44 # there are many ways we could get planes - convex hull for eg
45 # but it ends up fastest if we just use bounding box
47 xa
= [v
[0] for v
in verts
]
48 ya
= [v
[1] for v
in verts
]
49 za
= [v
[2] for v
in verts
]
51 xmin
, xmax
= min(xa
) - margin_bounds
, max(xa
) + margin_bounds
52 ymin
, ymax
= min(ya
) - margin_bounds
, max(ya
) + margin_bounds
53 zmin
, zmax
= min(za
) - margin_bounds
, max(za
) + margin_bounds
55 Vector((+1.0, 0.0, 0.0, -xmax
)),
56 Vector((-1.0, 0.0, 0.0, +xmin
)),
57 Vector((0.0, +1.0, 0.0, -ymax
)),
58 Vector((0.0, -1.0, 0.0, +ymin
)),
59 Vector((0.0, 0.0, +1.0, -zmax
)),
60 Vector((0.0, 0.0, -1.0, +zmin
)),
63 for i
, point_cell_current
in enumerate(points
):
64 planes
= [None] * len(convexPlanes
)
65 for j
in range(len(convexPlanes
)):
66 planes
[j
] = convexPlanes
[j
].copy()
67 planes
[j
][3] += planes
[j
].xyz
.dot(point_cell_current
)
68 distance_max
= 10000000000.0 # a big value!
70 points_sorted_current
.sort(key
=lambda p
: (p
- point_cell_current
).length_squared
)
72 for j
in range(1, len(points
)):
73 normal
= points_sorted_current
[j
] - point_cell_current
74 nlength
= normal
.length
76 if points_scale
is not None:
77 normal_alt
= normal
.copy()
78 normal_alt
.x
*= points_scale
[0]
79 normal_alt
.y
*= points_scale
[1]
80 normal_alt
.z
*= points_scale
[2]
82 # rotate plane to new distance
83 # should always be positive!! - but abs incase
84 scalar
= normal_alt
.normalized().dot(normal
.normalized())
85 # assert(scalar >= 0.0)
89 if nlength
> distance_max
:
92 plane
= normal
.normalized()
94 plane
[3] = (-nlength
/ 2.0) + margin_cell
97 vertices
[:], plane_indices
[:] = mathutils
.geometry
.points_in_planes(planes
)
98 if len(vertices
) == 0:
101 if len(plane_indices
) != len(planes
):
102 planes
[:] = [planes
[k
] for k
in plane_indices
]
104 # for comparisons use length_squared and delay
105 # converting to a real length until the end.
106 distance_max
= 10000000000.0 # a big value!
108 distance
= v
.length_squared
109 if distance_max
< distance
:
110 distance_max
= distance
111 distance_max
= sqrt(distance_max
) # make real length
114 if len(vertices
) == 0:
117 cells
.append((point_cell_current
, vertices
[:]))