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

git.blender.org/blender-addons.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'object_fracture_cell/process/cell_calc.py')
-rw-r--r--object_fracture_cell/process/cell_calc.py149
1 files changed, 149 insertions, 0 deletions
diff --git a/object_fracture_cell/process/cell_calc.py b/object_fracture_cell/process/cell_calc.py
new file mode 100644
index 00000000..272ebff1
--- /dev/null
+++ b/object_fracture_cell/process/cell_calc.py
@@ -0,0 +1,149 @@
+# ##### BEGIN GPL LICENSE BLOCK #####
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+#
+# ##### END GPL LICENSE BLOCK #####
+
+# <pep8 compliant>
+
+# Script copyright (C) Blender Foundation 2012
+
+
+def points_to_verts(original_xyz_minmax,
+ points,
+ points_scale=None,
+ margin_bounds=0.05,
+ margin_cell=0.0):
+
+ from math import sqrt
+ import mathutils
+ from mathutils import Vector
+
+ cells = []
+ 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:
+ xmin, xmax = original_xyz_minmax["x"]
+ ymin, ymax = original_xyz_minmax["y"]
+ zmin, zmax = original_xyz_minmax["z"]
+
+ xmin -= margin_bounds
+ xmax += margin_bounds
+ ymin -= margin_bounds
+ ymax += margin_bounds
+ zmin -= margin_bounds
+ zmax += margin_bounds
+
+ # (x,y,z,scaler) for plane. xyz is normaliized direction. scaler is scale for plane.
+ # Plane will be made at the perpendicular direction of the normal vector.
+ 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)),
+ ]
+
+ if len(points) > 1:
+ points_dist_sorted = [(Vector(p[0]), p[1]) for p in points]
+
+ for i, point_current in enumerate(points):
+ planes = [None] * len(convexPlanes)
+ for j in range(len(convexPlanes)):
+ planes[j] = convexPlanes[j].copy()
+ # e.g. Dot product point's (xyz) with convex's (+1.0,0.0,0.0) detects x value of the point.
+ # e.g. Then, x scaler += point's x value.
+ planes[j][3] += planes[j].xyz.dot(point_current[0])
+
+ distance_max = 10000000000.0 # a big value!
+
+ points_dist_sorted_current = points_dist_sorted.copy()
+ # Closer points to the current point are earlier order. Of course, current point is the first.
+ points_dist_sorted_current.sort(key=lambda p: (p[0] - point_current[0]).length_squared)
+
+ # The point itself is removed.
+ points_dist_sorted_current.pop(0)
+
+ # Compare the current point with other points.
+ for j in range(len(points_dist_sorted_current)):
+
+ point_target = points_dist_sorted_current[j]
+ normal = 0
+ normal = point_target[0] - point_current[0]
+ nlength = normal.length # is sqrt(X^2+y^2+z^2).
+
+ 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
+ # Scale rate (normal_alt/normal). If these are the same, dot product is 1.
+ scalar = normal_alt.normalized().dot(normal.normalized())
+ # assert(scalar >= 0.0)
+ nlength *= scalar
+ normal = normal_alt
+
+ if nlength > distance_max:
+ break
+
+ # 4D vector, the same form as convexPlanes. (x,y,z,scaler).
+ plane = normal.normalized()
+ plane.resize_4d()
+ plane[3] = (-nlength / 2.0) + margin_cell
+ planes.append(plane)
+
+ # Make vertex points of cell, by crossing point of planes.
+ 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 ここでルートでマックスを下げているのか?でも下で2倍にしているが。
+ distance_max *= 2.0
+
+ if len(vertices) == 0:
+ continue
+
+ cells.append((point_current[0], vertices[:]))
+ del vertices[:]
+
+ else:
+ vertices[:], plane_indices[:] = mathutils.geometry.points_in_planes(convexPlanes)
+ #convex_center = Vector(((xmin-xmax)/2, (ymin-ymax)/2, (zmin-zmax)/2))
+ convex_center = Vector((0,0,0))
+ cells.append((convex_center, vertices[:]))
+
+ return cells \ No newline at end of file