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 ointersect_pointion) 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 # ----------------------------------------------------------
23 # Modified by: Alan Odom (Clockmender) & Rune Morling (ermo)
24 # ----------------------------------------------------------
27 from mathutils
import Vector
28 from mathutils
.geometry
import intersect_line_line
, intersect_point_line
29 from .pdt_functions
import debug
32 def point_on_edge(point
, edge
):
33 """Find Point on Edge.
37 edge: tuple containing 2 vectors.
40 True if point happens to lie on the edge, False otherwise.
43 intersect_point
, _percent
= intersect_point_line(point
, *edge
)
44 on_line
= (intersect_point
- point
).length
< 1.0e-5
45 return on_line
and (0.0 <= _percent
<= 1.0)
48 def line_from_edge_intersect(edge1
, edge2
):
49 """Get New Line from Intersections.
52 Prepares input for sending to intersect_line_line
55 edge1, edge2: tuples containing 2 vectors.
58 Output of intersect_line_line.
61 [intersect_point1
, intersect_point2
], [intersect_point3
, intersect_point4
] = edge1
, edge2
62 return intersect_line_line(
63 intersect_point1
, intersect_point2
, intersect_point3
, intersect_point4
67 def get_intersection(edge1
, edge2
):
68 """Get Intersections of 2 Edges.
71 edge1, edge2: tuples containing 2 vectors.
74 The point halfway on line. See intersect_line_line.
77 line
= line_from_edge_intersect(edge1
, edge2
)
79 return (line
[0] + line
[1]) / 2
83 def test_coplanar(edge1
, edge2
):
84 """Test 2 Edges are Co-planar.
87 The line that describes the shortest line between the two edges would be short if the
88 lines intersect mathematically. If this line is longer than 1.0e-5 then they are either
92 edge1, edge2: tuples containing 2 vectors.
95 True if edge1 and edge2 or coplanar, False otherwise.
98 line
= line_from_edge_intersect(edge1
, edge2
)
100 return (line
[0] - line
[1]).length
< 1.0e-5
104 def closest_idx(intersect_point
, edge
):
105 """Get Closest Vertex to input point.
108 If both points in edge are equally far from intersect_point, then v1 is returned.
111 intersect_point: vector
115 Index of vertex closest to intersect_point.
118 if isinstance(edge
, bmesh
.types
.BMEdge
):
119 edge_verts
= edge
.verts
120 vector_a
= edge_verts
[0].co
121 vector_b
= edge_verts
[1].co
122 distance_test
= (vector_a
- intersect_point
).length
<= (vector_b
- intersect_point
).length
123 return edge_verts
[0].index
if distance_test
else edge_verts
[1].index
125 debug(f
"Received {edge}, check expected input in docstring ")
129 def closest_vector(intersect_point
, edge
):
130 """Return Closest Vector to input Point.
133 If both points in e are equally far from intersect_point, then v1 is returned.
136 intersect_point: vector
137 edge: tuple containing 2 vectors
140 Vector closest to intersect_point.
143 if isinstance(edge
, tuple) and all([isinstance(co
, Vector
) for co
in edge
]):
144 vector_a
, vector_b
= edge
145 distance_test
= (vector_a
- intersect_point
).length
<= (vector_b
- intersect_point
).length
146 return vector_a
if distance_test
else vector_b
148 debug(f
"Received {edge}, check expected input in docstring ")
152 def coords_tuple_from_edge_idx(bm
, idx
):
153 """Return Tuple from Vertices.
157 idx: Index of chosen Edge
160 Tuple from Edge Vertices.
163 return tuple(v
.co
for v
in bm
.edges
[idx
].verts
)
166 def vectors_from_indices(bm
, raw_vert_indices
):
167 """Return List of vectors from input Vertex Indices.
171 raw_vert_indices: List of Chosen Vertex Indices
174 List of Vertex coordinates.
177 return [bm
.verts
[i
].co
for i
in raw_vert_indices
]
180 def vertex_indices_from_edges_tuple(bm
, edge_tuple
):
181 """Return List of vertices.
184 bm: Active object's Bmesh
185 edge_tuple: contains 2 edge indices.
188 The vertex indices of edge_tuple as an Integer list.
191 def find_verts(ind_v
, ind_w
):
192 return bm
.edges
[edge_tuple
[ind_v
]].verts
[ind_w
].index
194 return [find_verts(i
>> 1, i
% 2) for i
in range(4)]
197 def get_vert_indices_from_bmedges(edges
):
198 """Return List of Edges for evaluation.
201 edges: a list of 2 bm edges
204 The vertex indices of edge_tuple as a flat list.
211 temp_edges
.append(v
.index
)
215 def num_edges_point_lies_on(intersect_point
, edges
):
216 """Returns the number of edges that a point lies on.
219 intersection_point: Vector describing 3D coordinates of intersection point
220 edges: List of Bmesh edges
223 Number of Intersecting Edges (Integer).
226 res
= [point_on_edge(intersect_point
, edge
) for edge
in [edges
[:2], edges
[2:]]]
227 return len([i
for i
in res
if i
])
230 def find_intersecting_edges(bm
, intersect_point
, idx1
, idx2
):
231 """Find Intercecting Edges.
234 intersect_point: Vector describing 3D coordinates of intersection point
235 idx1, idx2: edge indices
238 The list of edge indices where intersect_point is on those edges.
241 if not intersect_point
:
244 edges
= [coords_tuple_from_edge_idx(bm
, idx
) for idx
in idxs
]
245 return [idx
for edge
, idx
in zip(edges
, idxs
) if point_on_edge(intersect_point
, edge
)]
248 def vert_idxs_from_edge_idx(bm
, idx
):
249 """Find Vertex Indices form Edge Indices.
256 Vertex Indices of Edge.
260 return edge
.verts
[0].index
, edge
.verts
[1].index