Newer
Older
# ##### 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 ointersect_pointion) 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>
#
# ----------------------------------------------------------
# Author: Zeffii
# Modified by: Alan Odom (Clockmender) & Rune Morling (ermo)
# ----------------------------------------------------------
#
import bmesh
from mathutils import Vector
from mathutils.geometry import intersect_line_line, intersect_point_line
from .pdt_functions import debug
def point_on_edge(point, edge):
"""Find Point on Edge.
Args:
edge: tuple containing 2 vectors.
Returns:
True if point happens to lie on the edge, False otherwise.
intersect_point, _percent = intersect_point_line(point, *edge)
on_line = (intersect_point - point).length < 1.0e-5
return on_line and (0.0 <= _percent <= 1.0)
def line_from_edge_intersect(edge1, edge2):
"""Get New Line from Intersections.
Note:
Prepares input for sending to intersect_line_line
Args:
edge1, edge2: tuples containing 2 vectors.
Returns:
Output of intersect_line_line.
"""
[intersect_point1, intersect_point2], [intersect_point3, intersect_point4] = edge1, edge2
return intersect_line_line(
intersect_point1, intersect_point2, intersect_point3, intersect_point4
)
def get_intersection(edge1, edge2):
"""Get Intersections of 2 Edges.
Args:
edge1, edge2: tuples containing 2 vectors.
Returns:
The point halfway on line. See intersect_line_line.
"""
line = line_from_edge_intersect(edge1, edge2)
if line:
return (line[0] + line[1]) / 2
def test_coplanar(edge1, edge2):
"""Test 2 Edges are Co-planar.
Note:
The line that describes the shortest line between the two edges would be short if the
lines intersect mathematically. If this line is longer than 1.0e-5 then they are either
coplanar or parallel
Args:
edge1, edge2: tuples containing 2 vectors.
Returns:
True if edge1 and edge2 or coplanar, False otherwise.
"""
line = line_from_edge_intersect(edge1, edge2)
if line:
return (line[0] - line[1]).length < 1.0e-5
def closest_idx(intersect_point, edge):
"""Get Closest Vertex to input point.
Note:
If both points in edge are equally far from intersect_point, then v1 is returned.
intersect_point: vector
edge: bmesh edge
Index of vertex closest to intersect_point.
if isinstance(edge, bmesh.types.BMEdge):
edge_verts = edge.verts
vector_a = edge_verts[0].co
vector_b = edge_verts[1].co
distance_test = (vector_a - intersect_point).length <= (vector_b - intersect_point).length
return edge_verts[0].index if distance_test else edge_verts[1].index
debug(f"Received {edge}, check expected input in docstring ")
return None
def closest_vector(intersect_point, edge):
"""Return Closest Vector to input Point.
Note:
If both points in e are equally far from intersect_point, then v1 is returned.
intersect_point: vector
edge: tuple containing 2 vectors
Vector closest to intersect_point.
if isinstance(edge, tuple) and all([isinstance(co, Vector) for co in edge]):
vector_a, vector_b = edge
distance_test = (vector_a - intersect_point).length <= (vector_b - intersect_point).length
return vector_a if distance_test else vector_b
debug(f"Received {edge}, check expected input in docstring ")
return None
def coords_tuple_from_edge_idx(bm, idx):
"""Return Tuple from Vertices.
Args:
bm: Object Bmesh
idx: Index of chosen Edge
Returns:
Tuple from Edge Vertices.
"""
return tuple(v.co for v in bm.edges[idx].verts)
def vectors_from_indices(bm, raw_vert_indices):
"""Return List of vectors from input Vertex Indices.
Args:
bm: Object Bmesh
raw_vert_indices: List of Chosen Vertex Indices
Returns:
List of Vertex coordinates.
"""
return [bm.verts[i].co for i in raw_vert_indices]
def vertex_indices_from_edges_tuple(bm, edge_tuple):
"""Return List of vertices.
Args:
edge_tuple: contains 2 edge indices.
Returns:
The vertex indices of edge_tuple as an Integer list.
return bm.edges[edge_tuple[ind_v]].verts[ind_w].index
return [find_verts(i >> 1, i % 2) for i in range(4)]
def get_vert_indices_from_bmedges(edges):
"""Return List of Edges for evaluation.
Args:
Returns:
The vertex indices of edge_tuple as a flat list.
"""
temp_edges = []
debug(edges)
for e in edges:
for v in e.verts:
temp_edges.append(v.index)
return temp_edges
def num_edges_point_lies_on(intersect_point, edges):
"""Returns the number of edges that a point lies on.
Args:
intersection_point: Vector describing 3D coordinates of intersection point
edges: List of Bmesh edges
Returns:
Number of Intersecting Edges (Integer).
"""
res = [point_on_edge(intersect_point, edge) for edge in [edges[:2], edges[2:]]]
return len([i for i in res if i])
def find_intersecting_edges(bm, intersect_point, idx1, idx2):
"""Find Intercecting Edges.
Args:
intersect_point: Vector describing 3D coordinates of intersection point
The list of edge indices where intersect_point is on those edges.
return []
idxs = [idx1, idx2]
edges = [coords_tuple_from_edge_idx(bm, idx) for idx in idxs]
return [idx for edge, idx in zip(edges, idxs) if point_on_edge(intersect_point, edge)]
def vert_idxs_from_edge_idx(bm, idx):
"""Find Vertex Indices form Edge Indices.
Args:
bm: Object's Bmesh
idx: Selection Index
Returns:
Vertex Indices of Edge.
"""
edge = bm.edges[idx]
return edge.verts[0].index, edge.verts[1].index