diff options
-rw-r--r-- | precision_drawing_tools/__init__.py | 6 | ||||
-rw-r--r-- | precision_drawing_tools/pdt_command.py | 36 | ||||
-rw-r--r-- | precision_drawing_tools/pdt_design.py | 76 | ||||
-rw-r--r-- | precision_drawing_tools/pdt_functions.py | 2 | ||||
-rw-r--r-- | precision_drawing_tools/pdt_menus.py | 1 | ||||
-rw-r--r-- | precision_drawing_tools/pdt_msg_strings.py | 4 |
6 files changed, 100 insertions, 25 deletions
diff --git a/precision_drawing_tools/__init__.py b/precision_drawing_tools/__init__.py index e99e7735..926dcc30 100644 --- a/precision_drawing_tools/__init__.py +++ b/precision_drawing_tools/__init__.py @@ -83,6 +83,7 @@ from .pdt_msg_strings import ( PDT_DES_FILLETRAD, PDT_DES_FILLETSEG, PDT_DES_FILLETVERTS, + PDT_DES_FILLINT, PDT_DES_FLIPANG, PDT_DES_FLIPPER, PDT_DES_LIBCOLS, @@ -419,6 +420,11 @@ class PDTSceneProperties(PropertyGroup): default=True, description=PDT_DES_FILLETVERTS, ) + fillet_int : BoolProperty( + name="Intersect", + default=False, + description=PDT_DES_FILLINT, + ) class PDTPreferences(AddonPreferences): diff --git a/precision_drawing_tools/pdt_command.py b/precision_drawing_tools/pdt_command.py index b293dc0d..4206b199 100644 --- a/precision_drawing_tools/pdt_command.py +++ b/precision_drawing_tools/pdt_command.py @@ -30,6 +30,7 @@ from .pdt_functions import ( debug, disAng, getPercent, + intersection, objCheck, oops, updateSel, @@ -86,6 +87,7 @@ def pdt_help(self, context): label(text="- Fillet Options:") label(text="v: Fillet Vertices") label(text="e: Fillet Edges") + label(text="i: Fillet & Intersect 2 Disconnected Edges") label(text="- Math Options:") label(text="x, y, z: Send result to X, Y and Z input fields in PDT Design") label(text="d, a, p: Send result to Distance, Angle or Percent input field in PDT Design") @@ -226,9 +228,9 @@ def command_run(self, context): elif mode == "o": pg.mathsout = num return - # "x"/"y"/"z" modes are only legal for Math Operation + # "o"/"x"/"y"/"z" modes are only legal for Math Operation else: - if mode in {"x", "y", "z"}: + if mode in {"o", "x", "y", "z"}: pg.error = PDT_ERR_BADCOORDL context.window_manager.popup_menu(oops, title="Error", icon="ERROR") return @@ -855,7 +857,7 @@ def command_run(self, context): # --------------- # Fillet Geometry elif oper == "F": - if mode not in {"v", "e"}: + if mode not in {"v", "e", "i"}: pg.error = f"'{mode}' {PDT_ERR_NON_VALID} '{oper}'" context.window_manager.popup_menu(oops, title="Error", icon="ERROR") return @@ -871,7 +873,7 @@ def command_run(self, context): pg.error = PDT_ERR_BAD3VALS context.window_manager.popup_menu(oops, title="Error", icon="ERROR") return - if mode == "v": + if mode in {"i", "v"}: vert_bool = True elif mode == "e": vert_bool = False @@ -889,6 +891,32 @@ def command_run(self, context): _profile = float(vals[2]) if _profile < 0.0 or _profile > 1.0: _profile = 0.5 # This is a circular profile + if mode == "i": + # Fillet & Intersect Two Edges + edges = [e for e in bm.edges if e.select] + if len(edges) == 2 and len(verts) == 4: + va = edges[0].verts[0] + vo = edges[0].verts[1] + vl = edges[1].verts[0] + vf = edges[1].verts[1] + vector_delta, done = intersection(va.co, vo.co, vl.co, vf.co, plane) + if not done: + errmsg = f"{PDT_ERR_INT_LINES} {plane} {PDT_LAB_PLANE}" + self.report({"ERROR"}, errmsg) + return {"FINISHED"} + if (va.co - vector_delta).length < (vo.co - vector_delta).length: + va.co = vector_delta + vo.select_set(False) + else: + vo.co = vector_delta + va.select_set(False) + if (vl.co - vector_delta).length < (vf.co - vector_delta).length: + vl.co = vector_delta + vf.select_set(False) + else: + vf.co = vector_delta + vl.select_set(False) + bmesh.ops.remove_doubles(bm, verts=bm.verts, dist=0.0001) bpy.ops.mesh.bevel( offset_type="OFFSET", offset=_offset, diff --git a/precision_drawing_tools/pdt_design.py b/precision_drawing_tools/pdt_design.py index a20ebdd4..2d69877b 100644 --- a/precision_drawing_tools/pdt_design.py +++ b/precision_drawing_tools/pdt_design.py @@ -56,6 +56,7 @@ from .pdt_msg_strings import ( PDT_ERR_SEL_2_OBJS, PDT_ERR_SEL_2_VERTIO, PDT_ERR_SEL_2_VERTS, + PDT_ERR_SEL_2_EDGES, PDT_ERR_SEL_3_OBJS, PDT_ERR_SEL_3_VERTIO, PDT_ERR_SEL_3_VERTS, @@ -837,13 +838,9 @@ class PDT_OT_PlacementInt(Operator): elif len(edges) == 2: ext_a = pg.extend va = edges[0].verts[0] - actV = va.co vo = edges[0].verts[1] - othV = vo.co vl = edges[1].verts[0] - lstV = vl.co vf = edges[1].verts[1] - fstV = vf.co else: errmsg = ( PDT_ERR_SEL_4_VERTS @@ -854,7 +851,7 @@ class PDT_OT_PlacementInt(Operator): ) self.report({"ERROR"}, errmsg) return {"FINISHED"} - vector_delta, done = intersection(actV, othV, lstV, fstV, plane) + vector_delta, done = intersection(va.co, vo.co, vl.co, vf.co, plane) if not done: errmsg = f"{PDT_ERR_INT_LINES} {plane} {PDT_LAB_PLANE}" self.report({"ERROR"}, errmsg) @@ -880,7 +877,7 @@ class PDT_OT_PlacementInt(Operator): nVert = None proc = False - if (actV - vector_delta).length < (othV - vector_delta).length: + if (va.co - vector_delta).length < (vo.co - vector_delta).length: if oper == "MV": va.co = vector_delta proc = True @@ -895,7 +892,7 @@ class PDT_OT_PlacementInt(Operator): nVert = bm.verts.new(vector_delta) bm.edges.new([vo, nVert]) - if (lstV - vector_delta).length < (fstV - vector_delta).length: + if (vl.co - vector_delta).length < (vf.co - vector_delta).length: if oper == "MV" and ext_a: vl.co = vector_delta elif oper == "EV" and ext_a: @@ -1186,22 +1183,63 @@ class PDT_OT_Fillet(Operator): scene = context.scene pg = scene.pdt_pg + plane = pg.plane obj = context.view_layer.objects.active bm = bmesh.from_edit_mesh(obj.data) verts = [v for v in bm.verts if v.select] - if len(verts) == 0: - errmsg = PDT_ERR_SEL_1_VERT - self.report({"ERROR"}, errmsg) - return {"FINISHED"} + if pg.fillet_int: + # Fillet & Intersect Two Edges + edges = [e for e in bm.edges if e.select] + if len(edges) == 2 and len(verts) == 4: + va = edges[0].verts[0] + vo = edges[0].verts[1] + vl = edges[1].verts[0] + vf = edges[1].verts[1] + vector_delta, done = intersection(va.co, vo.co, vl.co, vf.co, plane) + if not done: + errmsg = f"{PDT_ERR_INT_LINES} {plane} {PDT_LAB_PLANE}" + self.report({"ERROR"}, errmsg) + return {"FINISHED"} + if (va.co - vector_delta).length < (vo.co - vector_delta).length: + va.co = vector_delta + vo.select_set(False) + else: + vo.co = vector_delta + va.select_set(False) + if (vl.co - vector_delta).length < (vf.co - vector_delta).length: + vl.co = vector_delta + vf.select_set(False) + else: + vf.co = vector_delta + vl.select_set(False) + bmesh.ops.remove_doubles(bm, verts=bm.verts, dist=0.0001) + bpy.ops.mesh.bevel( + offset_type="OFFSET", + offset=pg.fillet_radius, + segments=pg.fillet_segments, + profile=pg.fillet_profile, + vertex_only=True, + ) + return {"FINISHED"} + else: + errmsg = f"{PDT_ERR_SEL_2_EDGES} {len(edges)})" + self.report({"ERROR"}, errmsg) + return {"FINISHED"} else: - bpy.ops.mesh.bevel( - offset_type="OFFSET", - offset=pg.fillet_radius, - segments=pg.fillet_segments, - profile=pg.fillet_profile, - vertex_only=pg.fillet_vertices_only, - ) - return {"FINISHED"} + if len(verts) == 0: + errmsg = PDT_ERR_SEL_1_VERT + self.report({"ERROR"}, errmsg) + return {"FINISHED"} + else: + # Intersct Edges + bpy.ops.mesh.bevel( + offset_type="OFFSET", + offset=pg.fillet_radius, + segments=pg.fillet_segments, + profile=pg.fillet_profile, + vertex_only=pg.fillet_vertices_only, + ) + return {"FINISHED"} class PDT_OT_Angle2(Operator): diff --git a/precision_drawing_tools/pdt_functions.py b/precision_drawing_tools/pdt_functions.py index f766cf31..01e595ff 100644 --- a/precision_drawing_tools/pdt_functions.py +++ b/precision_drawing_tools/pdt_functions.py @@ -500,7 +500,7 @@ def objCheck(obj, scene, oper): else: return bm, True if len(bm.select_history) >= 1: - if _oper not in {"D", "E", "G", "N", "S"}: + if _oper not in {"D", "E", "F", "G", "N", "S"}: actV = checkSelection(1, bm, obj) else: verts = [v for v in bm.verts if v.select] diff --git a/precision_drawing_tools/pdt_menus.py b/precision_drawing_tools/pdt_menus.py index a3b03a40..139fb3a4 100644 --- a/precision_drawing_tools/pdt_menus.py +++ b/precision_drawing_tools/pdt_menus.py @@ -188,6 +188,7 @@ class PDT_PT_PanelDesign(Panel): row.prop(pdt_pg, "fillet_vertices_only", text=PDT_LAB_USEVERTS) row = box.row() row.operator("pdt.fillet", text=f"{PDT_LAB_FILLET}") + row.prop(pdt_pg, "fillet_int", text="Int/Fillet") class PDT_PT_PanelPivotPoint(Panel): diff --git a/precision_drawing_tools/pdt_msg_strings.py b/precision_drawing_tools/pdt_msg_strings.py index 72f55924..703a0b7b 100644 --- a/precision_drawing_tools/pdt_msg_strings.py +++ b/precision_drawing_tools/pdt_msg_strings.py @@ -84,6 +84,7 @@ PDT_ERR_SEL_1_VERT = "Select at least 1 Vertex (Currently selected:" PDT_ERR_SEL_2_VERTI = "Select at least 2 Vertices Individually (Currently selected:" PDT_ERR_SEL_2_VERTIO = "Select Exactly 2 Vertices Individually (Currently selected:" PDT_ERR_SEL_2_VERTS = "Select Exactly 2 Vertices (Currently selected:" +PDT_ERR_SEL_2_EDGES = "Select Only 2 Non-Intersecting Edges (Currently selected:" PDT_ERR_SEL_3_VERTS = "Select Exactly 3 Vertices (Currently selected:" PDT_ERR_SEL_3_VERTIO = "Select Exactly 3 Vertices Individually (Currently selected:" PDT_ERR_SEL_2_V_1_E = "Select 2 Vertices Individually, or 1 Edge (Currently selected:" @@ -113,7 +114,7 @@ PDT_ERR_SCALEZERO = "Scale Distance is 0" PDT_ERR_CHARS_NUM = "Bad Command Format, not enough Characters" PDT_ERR_BADFLETTER = "Bad Operator (1st Letter); C D E F G N M P S V or ? only" -PDT_ERR_BADSLETTER = "Bad Mode (2nd Letter); A D I or P only (+ X Y & Z for Maths) (+ V & G for Fillet)" +PDT_ERR_BADSLETTER = "Bad Mode (2nd Letter); A D I or P only (+ X Y & Z for Maths) (+ I V & G for Fillet)" PDT_ERR_BADMATHS = "Not a Valid Mathematical Expression!" PDT_ERR_BADCOORDL = "X Y & Z Not permitted in anything other than Maths Operations" PDT_ERR_BAD1VALS = "Bad Command - 1 Value needed" @@ -170,3 +171,4 @@ PDT_DES_FILLETRAD = "Fillet Radius" PDT_DES_FILLETSEG = "Number of Fillet Segments" PDT_DES_FILLETPROF = "Fillet Profile" PDT_DES_FILLETVERTS = "Use Vertices, or Edges, Set to False for Extruded Geometry" +PDT_DES_FILLINT = "Intersect & Fillet Two Selected Edges" |