1 # SPDX-FileCopyrightText: 2016-2022 Blender Foundation
3 # SPDX-License-Identifier: GPL-2.0-or-later
6 # ----------------------------------------------------------
8 # Modified by: Alan Odom (Clockmender) & Rune Morling (ermo)
9 # ----------------------------------------------------------
14 from mathutils
.geometry
import intersect_line_plane
15 from .pdt_msg_strings
import (
20 from .pdt_functions
import oops
23 def failure_message(context
):
24 """Warn to the user to select 1 edge and 1 face.
27 context: Blender bpy.context instance.
33 pg
= context
.scene
.pdt_pg
34 pg
.error
= f
"{PDT_ERR_SEL_1_E_1_F}"
35 context
.window_manager
.popup_menu(oops
, title
="Error", icon
="ERROR")
38 def failure_message_on_plane(context
):
39 """Report an informative error message in a popup.
42 context: Blender bpy.context instance.
48 pg
= context
.scene
.pdt_pg
49 pg
.error
= f
"{PDT_ERR_NOINT}"
50 context
.window_manager
.popup_menu(oops
, title
="Error", icon
="ERROR")
52 def extend_vertex(context
):
53 """Computes Edge Extension to Face.
56 context: Blender bpy.context instance.
62 obj
= bpy
.context
.edit_object
63 pg
= context
.scene
.pdt_pg
65 if all([bool(obj
), obj
.type == "MESH", obj
.mode
== "EDIT"]):
66 object_data
= obj
.data
67 bm
= bmesh
.from_edit_mesh(object_data
)
71 planes
= [f
for f
in faces
if f
.select
]
72 if not len(planes
) == 1:
73 failure_message(context
)
77 plane_vert_indices
= plane
.verts
[:]
78 all_selected_vert_indices
= [v
for v
in verts
if v
.select
]
80 plane_verts
= set(plane_vert_indices
)
81 all_verts
= set(all_selected_vert_indices
)
82 diff_verts
= all_verts
.difference(plane_verts
)
83 diff_verts
= list(diff_verts
)
85 if not len(diff_verts
) == 2:
86 failure_message(context
)
89 (v1_ref
, v1
), (v2_ref
, v2
) = [(i
, i
.co
) for i
in diff_verts
]
91 plane_co
= plane
.calc_center_median()
92 plane_no
= plane
.normal
94 new_co
= intersect_line_plane(v1
, v2
, plane_co
, plane_no
, False)
97 new_vertex
= verts
.new(new_co
)
98 a_len
= (v1
- new_co
).length
99 b_len
= (v2
- new_co
).length
101 vertex_reference
= v1_ref
if (a_len
< b_len
) else v2_ref
102 bm
.edges
.new([vertex_reference
, new_vertex
])
103 bmesh
.update_edit_mesh(object_data
, loop_triangles
=True)
106 failure_message_on_plane(context
)
108 pg
.error
= f
"{PDT_ERR_EDOB_MODE},{obj.mode})"
109 context
.window_manager
.popup_menu(oops
, title
="Error", icon
="ERROR")
113 class PDT_OT_EdgeToFace(bpy
.types
.Operator
):
114 """Extend Selected Edge to Projected Intersection with Selected Face"""
116 bl_idname
= "pdt.edge_to_face"
117 bl_label
= "Extend Edge to Face"
118 bl_options
= {"REGISTER", "UNDO"}
121 def poll(cls
, context
):
122 """Only allow this to work if a mesh is selected in EDIT mode.
125 context: Blender bpy.context instance.
134 return all([bool(obj
), obj
.type == "MESH", obj
.mode
== "EDIT"])
136 def execute(self
, context
):
137 """Extends Disconnected Edge to Intersect with Face.
140 context: Blender bpy.context instance.
146 pg
= context
.scene
.pdt_pg