Merge branch 'blender-v4.0-release'
[blender-addons.git] / precision_drawing_tools / pdt_bix.py
blobdeef4fd4a047ee2fb7748c4eb37b4ceab86312d3
1 # SPDX-FileCopyrightText: 2016-2022 Blender Foundation
3 # SPDX-License-Identifier: GPL-2.0-or-later
6 # ----------------------------------------------------------
7 # Author: Zeffii
8 # Modified by: Alan Odom (Clockmender) & Rune Morling (ermo)
9 # ----------------------------------------------------------
12 import bpy
13 import bmesh
14 from . import pdt_cad_module as cm
15 from .pdt_msg_strings import (
16 PDT_ERR_2CPNPE,
17 PDT_ERR_NCEDGES,
18 PDT_ERR_EDOB_MODE,
20 from .pdt_functions import debug, oops
23 def add_line_to_bisection(context):
24 """Computes Bisector of 2 Co-Planar Edges.
26 Args:
27 context: Blender bpy.context instance
29 Returns:
30 Nothing.
31 """
33 obj = context.object
34 if all([bool(obj), obj.type == "MESH", obj.mode == "EDIT"]):
35 pg = context.scene.pdt_pg
36 obj_data = obj.data
37 bm = bmesh.from_edit_mesh(obj_data)
39 bm.verts.ensure_lookup_table()
40 bm.edges.ensure_lookup_table()
42 edges = [e for e in bm.edges if e.select and not e.hide]
44 if not len(edges) == 2:
45 pg.error = f"{PDT_ERR_2CPNPE}"
46 context.window_manager.popup_menu(oops, title="Error", icon="ERROR")
47 return
49 [[vector_a, vector_b], [vector_c, vector_d]] = [[v.co for v in e.verts] for e in edges]
50 debug(f"vectors found:\n {vector_a}\n {vector_b}\n {vector_c}\n {vector_d}")
52 dist1 = (vector_a - vector_b).length
53 dist2 = (vector_c - vector_d).length
54 bdist = min([dist1, dist2])
55 edge1 = (vector_a, vector_b)
56 edge2 = (vector_c, vector_d)
58 if not cm.test_coplanar(edge1, edge2):
59 pg.error = PDT_ERR_NCEDGES
60 context.window_manager.popup_menu(oops, title="Error", icon="ERROR")
61 return
63 # get intersect_point and pick farthest vertex from (projected) intersections
64 intersect_point = cm.get_intersection(edge1, edge2)
65 far1 = (
66 vector_b
67 if (vector_a - intersect_point).length < (vector_b - intersect_point).length
68 else vector_a
70 far2 = (
71 vector_d
72 if (vector_c - intersect_point).length < (vector_d - intersect_point).length
73 else vector_c
76 dex1 = far1 - intersect_point
77 dex2 = far2 - intersect_point
78 dex1 = dex1 * (bdist / dex1.length)
79 dex2 = dex2 * (bdist / dex2.length)
80 intersect_point2 = intersect_point + (dex1).lerp(dex2, 0.5)
81 intersect_point3 = intersect_point2.lerp(intersect_point, 2.0)
83 vec1 = bm.verts.new(intersect_point2)
84 vec2 = bm.verts.new(intersect_point)
85 vec3 = bm.verts.new(intersect_point3)
86 bm.edges.new((vec1, vec2))
87 bm.edges.new((vec2, vec3))
88 bmesh.ops.remove_doubles(bm, verts=bm.verts, dist=0.0001)
89 bmesh.update_edit_mesh(obj_data)
90 else:
91 pg.error = f"{PDT_ERR_EDOB_MODE},{obj.mode})"
92 context.window_manager.popup_menu(oops, title="Error", icon="ERROR")
93 return
96 class PDT_OT_LineOnBisection(bpy.types.Operator):
97 """Create Bisector between 2 Selected Edges"""
99 bl_idname = "pdt.linetobisect"
100 bl_label = "Add Edges Bisector"
101 bl_options = {"REGISTER", "UNDO"}
103 @classmethod
104 def poll(cls, context):
105 """Only allow operation on a mesh object in EDIT mode.
107 Args:
108 context: Blender bpy.context instance.
110 Returns:
111 Boolean.
114 obj = context.active_object
115 if obj is None:
116 return False
117 return all([obj is not None, obj.type == "MESH", obj.mode == "EDIT"])
119 def execute(self, context):
120 """Computes Bisector of 2 Co-Planar Edges.
122 Note:
123 Requires an Active Object
124 Active Object must be Mesh type
125 Active Object must be in Edit Mode.
127 Args:
128 context: Blender bpy.context instance.
130 Returns:
131 Status Set.
134 pg = context.scene.pdt_pg
135 pg.command = f"bis"
136 return {"FINISHED"}