Welcome to mirror list, hosted at ThFree Co, Russian Federation.

fracture_cell_calc.py « object_fracture_cell - git.blender.org/blender-addons.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: c609f2995f4feee2bb6eadaf1fde2e039cf564be (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
# SPDX-License-Identifier: GPL-2.0-or-later

# <pep8 compliant>

# Script copyright (C) Blender Foundation 2012


def points_as_bmesh_cells(
        verts,
        points,
        points_scale=None,
        margin_bounds=0.05,
        margin_cell=0.0,
):
    from math import sqrt
    import mathutils
    from mathutils import Vector

    cells = []

    points_sorted_current = [p for p in points]
    plane_indices = []
    vertices = []

    if points_scale is not None:
        points_scale = tuple(points_scale)
    if points_scale == (1.0, 1.0, 1.0):
        points_scale = None

    # there are many ways we could get planes - convex hull for eg
    # but it ends up fastest if we just use bounding box
    if 1:
        xa = [v[0] for v in verts]
        ya = [v[1] for v in verts]
        za = [v[2] for v in verts]

        xmin, xmax = min(xa) - margin_bounds, max(xa) + margin_bounds
        ymin, ymax = min(ya) - margin_bounds, max(ya) + margin_bounds
        zmin, zmax = min(za) - margin_bounds, max(za) + margin_bounds
        convexPlanes = [
            Vector((+1.0, 0.0, 0.0, -xmax)),
            Vector((-1.0, 0.0, 0.0, +xmin)),
            Vector((0.0, +1.0, 0.0, -ymax)),
            Vector((0.0, -1.0, 0.0, +ymin)),
            Vector((0.0, 0.0, +1.0, -zmax)),
            Vector((0.0, 0.0, -1.0, +zmin)),
        ]

    for i, point_cell_current in enumerate(points):
        planes = [None] * len(convexPlanes)
        for j in range(len(convexPlanes)):
            planes[j] = convexPlanes[j].copy()
            planes[j][3] += planes[j].xyz.dot(point_cell_current)
        distance_max = 10000000000.0  # a big value!

        points_sorted_current.sort(key=lambda p: (p - point_cell_current).length_squared)

        for j in range(1, len(points)):
            normal = points_sorted_current[j] - point_cell_current
            nlength = normal.length

            if points_scale is not None:
                normal_alt = normal.copy()
                normal_alt.x *= points_scale[0]
                normal_alt.y *= points_scale[1]
                normal_alt.z *= points_scale[2]

                # rotate plane to new distance
                # should always be positive!! - but abs incase
                scalar = normal_alt.normalized().dot(normal.normalized())
                # assert(scalar >= 0.0)
                nlength *= scalar
                normal = normal_alt

            if nlength > distance_max:
                break

            plane = normal.normalized()
            plane.resize_4d()
            plane[3] = (-nlength / 2.0) + margin_cell
            planes.append(plane)

            vertices[:], plane_indices[:] = mathutils.geometry.points_in_planes(planes)
            if len(vertices) == 0:
                break

            if len(plane_indices) != len(planes):
                planes[:] = [planes[k] for k in plane_indices]

            # for comparisons use length_squared and delay
            # converting to a real length until the end.
            distance_max = 10000000000.0  # a big value!
            for v in vertices:
                distance = v.length_squared
                if distance_max < distance:
                    distance_max = distance
            distance_max = sqrt(distance_max)  # make real length
            distance_max *= 2.0

        if len(vertices) == 0:
            continue

        cells.append((point_cell_current, vertices[:]))
        del vertices[:]

    return cells