1 # SPDX-FileCopyrightText: 2012 Blender Foundation
3 # SPDX-License-Identifier: GPL-2.0-or-later
5 def points_as_bmesh_cells(
14 from mathutils
import Vector
18 points_sorted_current
= [p
for p
in points
]
22 if points_scale
is not None:
23 points_scale
= tuple(points_scale
)
24 if points_scale
== (1.0, 1.0, 1.0):
27 # there are many ways we could get planes - convex hull for eg
28 # but it ends up fastest if we just use bounding box
30 xa
= [v
[0] for v
in verts
]
31 ya
= [v
[1] for v
in verts
]
32 za
= [v
[2] for v
in verts
]
34 xmin
, xmax
= min(xa
) - margin_bounds
, max(xa
) + margin_bounds
35 ymin
, ymax
= min(ya
) - margin_bounds
, max(ya
) + margin_bounds
36 zmin
, zmax
= min(za
) - margin_bounds
, max(za
) + margin_bounds
38 Vector((+1.0, 0.0, 0.0, -xmax
)),
39 Vector((-1.0, 0.0, 0.0, +xmin
)),
40 Vector((0.0, +1.0, 0.0, -ymax
)),
41 Vector((0.0, -1.0, 0.0, +ymin
)),
42 Vector((0.0, 0.0, +1.0, -zmax
)),
43 Vector((0.0, 0.0, -1.0, +zmin
)),
46 for i
, point_cell_current
in enumerate(points
):
47 planes
= [None] * len(convexPlanes
)
48 for j
in range(len(convexPlanes
)):
49 planes
[j
] = convexPlanes
[j
].copy()
50 planes
[j
][3] += planes
[j
].xyz
.dot(point_cell_current
)
51 distance_max
= 10000000000.0 # a big value!
53 points_sorted_current
.sort(key
=lambda p
: (p
- point_cell_current
).length_squared
)
55 for j
in range(1, len(points
)):
56 normal
= points_sorted_current
[j
] - point_cell_current
57 nlength
= normal
.length
59 if points_scale
is not None:
60 normal_alt
= normal
.copy()
61 normal_alt
.x
*= points_scale
[0]
62 normal_alt
.y
*= points_scale
[1]
63 normal_alt
.z
*= points_scale
[2]
65 # rotate plane to new distance
66 # should always be positive!! - but abs incase
67 scalar
= normal_alt
.normalized().dot(normal
.normalized())
68 # assert(scalar >= 0.0)
72 if nlength
> distance_max
:
75 plane
= normal
.normalized()
77 plane
[3] = (-nlength
/ 2.0) + margin_cell
80 vertices
[:], plane_indices
[:] = mathutils
.geometry
.points_in_planes(planes
)
81 if len(vertices
) == 0:
84 if len(plane_indices
) != len(planes
):
85 planes
[:] = [planes
[k
] for k
in plane_indices
]
87 # for comparisons use length_squared and delay
88 # converting to a real length until the end.
89 distance_max
= 10000000000.0 # a big value!
91 distance
= v
.length_squared
92 if distance_max
< distance
:
93 distance_max
= distance
94 distance_max
= sqrt(distance_max
) # make real length
97 if len(vertices
) == 0:
100 cells
.append((point_cell_current
, vertices
[:]))