Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender-addons.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlan Odom <clockmender@icloud.com>2020-01-26 13:52:00 +0300
committerRune Morling <ermo.blender.org@spammesenseless.net>2020-02-01 18:41:11 +0300
commit4d0298a3f9240cff351f7225819f55dbe29836a9 (patch)
tree1235ad364455bfc6809e55f93d4d916c3842b718 /precision_drawing_tools
parent0e62a382183b02799dda7e48d5a3f97dd2321be9 (diff)
PDT: Refactor - Stage 4
- Check Object Mode is either EDIT or OBJECT as appropriate. - Change If loop to check command values - error if D, E, For M commands. - Remove surplus command check in command_maths function. - Added import of exceptions file. - Check for Mesh Objects in Object or Edit Mode first and exit with error message if not. - Some minor changes for obscure failures in unusual circumstances. - Fixes and changes to code to correct minor errors and remove unnecessary checks. - Refactored Command File structure. - Add more checks to Fillet Operation to check selection and make sure current selected vertices/edges are always used. Previous version could use wrong selection if Bmesh SelectHistory was in place for Faces, or Edges.
Diffstat (limited to 'precision_drawing_tools')
-rw-r--r--precision_drawing_tools/pdt_command.py1132
-rw-r--r--precision_drawing_tools/pdt_functions.py17
-rw-r--r--precision_drawing_tools/pdt_msg_strings.py1
3 files changed, 666 insertions, 484 deletions
diff --git a/precision_drawing_tools/pdt_command.py b/precision_drawing_tools/pdt_command.py
index 5b6b1b51..ee1b3691 100644
--- a/precision_drawing_tools/pdt_command.py
+++ b/precision_drawing_tools/pdt_command.py
@@ -23,8 +23,8 @@
#
import bpy
import bmesh
+import math
from bpy.types import Operator
-from mathutils import Vector
from .pdt_functions import (
debug,
intersection,
@@ -33,9 +33,7 @@ from .pdt_functions import (
update_sel,
)
from .pdt_command_functions import (
- command_maths,
vector_build,
- move_cursor_pivot,
join_two_vertices,
set_angle_distance_two,
set_angle_distance_three,
@@ -47,7 +45,6 @@ from .pdt_command_functions import (
)
from .pdt_msg_strings import (
PDT_ERR_ADDVEDIT,
- PDT_ERR_BAD3VALS,
PDT_ERR_BADFLETTER,
PDT_ERR_CHARS_NUM,
PDT_ERR_DUPEDIT,
@@ -55,63 +52,24 @@ from .pdt_msg_strings import (
PDT_ERR_FACE_SEL,
PDT_ERR_FILEDIT,
PDT_ERR_NON_VALID,
- PDT_ERR_NO_ACT_OBJ,
PDT_ERR_NO_SEL_GEOM,
PDT_ERR_SEL_1_EDGE,
PDT_ERR_SEL_1_EDGEM,
- PDT_ERR_SEL_1_VERT,
- PDT_ERR_SPLITEDIT
+ PDT_ERR_SPLITEDIT,
+ PDT_ERR_BADMATHS,
+ PDT_OBJ_MODE_ERROR,
+ PDT_ERR_SEL_4_VERTS,
)
from .pdt_bix import add_line_to_bisection
from .pdt_etof import extend_vertex
from .pdt_xall import intersect_all
-
-def pdt_help(self, context):
- """Display PDT Command Line help in a pop-up."""
- label = self.layout.label
- label(text="Primary Letters (Available Secondary Letters):")
- label(text="")
- label(text="C: Cursor (a, d, i, p)")
- label(text="D: Duplicate Geometry (d, i)")
- label(text="E: Extrude Geometry (d, i)")
- label(text="F: Fillet (v, e)")
- label(text="G: Grab (Move) (a, d, i, p)")
- label(text="N: New Vertex (a, d, i, p)")
- label(text="M: Maths Functions (x, y, z, d, a, p)")
- label(text="P: Pivot Point (a, d, i, p)")
- label(text="V: Extrude Vertice Only (a, d, i, p)")
- label(text="S: Split Edges (a, d, i, p)")
- label(text="?: Quick Help")
- label(text="")
- label(text="Secondary Letters:")
- label(text="")
- label(text="- General Options:")
- label(text="a: Absolute (Global) Coordinates e.g. 1,3,2")
- label(text="d: Delta (Relative) Coordinates, e.g. 0.5,0,1.2")
- label(text="i: Directional (Polar) Coordinates e.g. 2.6,45")
- label(text="p: Percent e.g. 67.5")
- 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")
- label(text="o: Send Maths Calculation to Output")
- label(text="")
- label(text="Note that commands are case-insensitive: ED = Ed = eD = ed")
- label(text="")
- label(text="Examples:")
- label(text="")
- label(text="ed0.5,,0.6")
- label(text="'- Extrude Geometry Delta 0.5 in X, 0 in Y, 0.6 in Z")
- label(text="")
- label(text="fe0.1,4,0.5")
- label(text="'- Fillet Edges")
- label(text="'- Radius: 0.1 (float) -- the radius (or offset) of the bevel/fillet")
- label(text="'- Segments: 4 (int) -- choosing an even amount of segments gives better geometry")
- label(text="'- Profile: 0.5 (float[0.0;1.0]) -- 0.5 (default) yields a circular, convex shape")
+from . import pdt_exception
+PDT_SelectionError = pdt_exception.SelectionError
+PDT_InvalidVector = pdt_exception.InvalidVector
+PDT_CommandFailure = pdt_exception.CommandFailure
+PDT_ObjectMode = pdt_exception.ObjectMode
+PDT_MathError = pdt_exception.MathsError
class PDT_OT_CommandReRun(Operator):
@@ -185,7 +143,15 @@ def command_run(self, context):
pg = scene.pdt_pg
command = pg.command.strip()
- # Check First Letter.
+ # Check Object Type & Mode First
+ obj = context.view_layer.objects.active
+ if obj is not None:
+ if obj.mode not in {"OBJECT", "EDIT"} or obj.type != "MESH":
+ pg.error = PDT_OBJ_MODE_ERROR
+ context.window_manager.popup_menu(oops, title="Error", icon="ERROR")
+ raise PDT_ObjectMode
+
+ # Special Cases of Command.
if command == "?" or command.lower() == "help":
# fmt: off
context.window_manager.popup_menu(pdt_help, title="PDT Command Line Help", icon="INFO")
@@ -206,27 +172,29 @@ def command_run(self, context):
origin_to_cursor(context)
return
elif command.upper() == "TAP":
- taper(self, context)
+ taper(context)
return
elif command.upper() == "BIS":
add_line_to_bisection(context)
return
elif command.upper() == "ETF":
- extend_vertex(self, context)
+ extend_vertex(context)
return
elif command.upper() == "INTALL":
intersect_all(context)
return
- elif command.upper()[1:4] == "NML":
+ elif command.upper()[1:] == "NML":
placement_normal(context, command.upper()[0])
return
- elif command.upper()[1:4] == "CEN":
+ elif command.upper()[1:] == "CEN":
placement_centre(context, command.upper()[0])
return
- elif command.upper()[1:4] == "INT":
+ elif command.upper()[1:] == "INT":
placement_intersect(context, command.upper()[0])
return
- elif len(command) < 3:
+
+ # Check First Letter
+ if len(command) < 3:
pg.error = PDT_ERR_CHARS_NUM
context.window_manager.popup_menu(oops, title="Error", icon="ERROR")
return
@@ -235,39 +203,206 @@ def command_run(self, context):
pg.error = PDT_ERR_BADFLETTER
context.window_manager.popup_menu(oops, title="Error", icon="ERROR")
return
- mode = command[1].lower()
+
+ # Check First Letter
+ operation = command[0].upper()
+ if operation not in {"C", "D", "E", "F", "G", "N", "M", "P", "V", "S"}:
+ pg.error = PDT_ERR_BADFLETTER
+ context.window_manager.popup_menu(oops, title="Error", icon="ERROR")
+ return
# Check Second Letter.
- if operation == "F":
- if mode not in {"v", "e", "i"}:
- pg.error = f"'{mode}' {PDT_ERR_NON_VALID} '{operation}'"
- context.window_manager.popup_menu(oops, title="Error", icon="ERROR")
- return
- elif operation in {"D", "E"}:
- if mode not in {"d", "i"}:
- pg.error = f"'{mode}' {PDT_ERR_NON_VALID} '{operation}'"
- context.window_manager.popup_menu(oops, title="Error", icon="ERROR")
- return
- elif operation == "M":
- if mode not in {"a", "d", "i", "p", "o", "x", "y", "z"}:
- pg.error = f"'{mode}' {PDT_ERR_NON_VALID} '{operation}'"
- context.window_manager.popup_menu(oops, title="Error", icon="ERROR")
- return
- else:
- if mode not in {"a", "d", "i", "p"}:
- pg.error = f"'{mode}' {PDT_ERR_NON_VALID} '{operation}'"
- context.window_manager.popup_menu(oops, title="Error", icon="ERROR")
- return
+ mode = command[1].lower()
+ if (
+ (operation == "F" and mode not in {"v", "e", "i"})
+ or (operation in {"D", "E"} and mode not in {"d", "i"})
+ or (operation == "M" and mode not in {"a", "d", "i", "p", "o", "x", "y", "z"})
+ or (operation not in {"D", "E", "F", "M"} and mode not in {"a", "d", "i", "p"})
+ ):
+ pg.error = f"'{mode}' {PDT_ERR_NON_VALID} '{operation}'"
+ context.window_manager.popup_menu(oops, title="Error", icon="ERROR")
+ return
# --------------
# Maths Operation
if operation == "M":
- command_maths(context, mode, pg, command[2:], mode)
- return
+ try:
+ command_maths(context, mode, pg, command[2:], mode)
+ except PDT_MathsError:
+ return
# -----------------------------------------------------
# Not a Maths Operation, so let's parse the command line
+ try:
+ pg, values, obj, obj_loc, bm, verts = command_parse(context)
+ except PDT_SelectionError:
+ return
+
+ # ---------------------
+ # Cursor or Pivot Point
+ if operation in {"C", "P"}:
+ try:
+ move_cursor_pivot(context, pg, operation, mode, obj, verts, values)
+ except PDT_CommandFailure:
+ return
+
+ # ------------------------
+ # Move Vertices or Objects
+ elif operation == "G":
+ try:
+ move_entities(context, pg, operation, mode, obj, bm, verts, values)
+ except PDT_CommandFailure:
+ return
+
+ # --------------
+ # Add New Vertex
+ elif operation == "N":
+ try:
+ add_new_vertex(context, pg, operation, mode, obj, bm, verts, values)
+ except PDT_CommandFailure:
+ return
+
+ # -----------
+ # Split Edges
+ elif operation == "S":
+ try:
+ split_edges(context, pg, operation, mode, obj, obj_loc, bm, values)
+ except PDT_CommandFailure:
+ return
+
+
+ # ----------------
+ # Extrude Vertices
+ elif operation == "V":
+ try:
+ extrude_vertices(context, pg, operation, mode, obj, obj_loc, bm, verts, values)
+ except PDT_CommandFailure:
+ return
+
+ # ----------------
+ # Extrude Geometry
+ elif operation == "E":
+ try:
+ extrude_geometry(context, pg, operation, mode, obj, bm, values)
+ except PDT_CommandFailure:
+ return
+
+ # ------------------
+ # Duplicate Geometry
+ elif operation == "D":
+ try:
+ duplicate_geometry(context, pg, operation, mode, obj, bm, values)
+ except PDT_CommandFailure:
+ return
+
+ # ---------------
+ # Fillet Geometry
+ elif operation == "F":
+ try:
+ fillet_geometry(context, pg, mode, obj, bm, verts, values)
+ except PDT_CommandFailure:
+ return
+
+ # -------------
+ # Anything else
+ else:
+ # Trap all other value and allow for more options
+ return
+
+
+def pdt_help(self, context):
+ """Display PDT Command Line help in a pop-up."""
+ label = self.layout.label
+ label(text="Primary Letters (Available Secondary Letters):")
+ label(text="")
+ label(text="C: Cursor (a, d, i, p)")
+ label(text="D: Duplicate Geometry (d, i)")
+ label(text="E: Extrude Geometry (d, i)")
+ label(text="F: Fillet (v, e)")
+ label(text="G: Grab (Move) (a, d, i, p)")
+ label(text="N: New Vertex (a, d, i, p)")
+ label(text="M: Maths Functions (x, y, z, d, a, p)")
+ label(text="P: Pivot Point (a, d, i, p)")
+ label(text="V: Extrude Vertice Only (a, d, i, p)")
+ label(text="S: Split Edges (a, d, i, p)")
+ label(text="?: Quick Help")
+ label(text="")
+ label(text="Secondary Letters:")
+ label(text="")
+ label(text="- General Options:")
+ label(text="a: Absolute (Global) Coordinates e.g. 1,3,2")
+ label(text="d: Delta (Relative) Coordinates, e.g. 0.5,0,1.2")
+ label(text="i: Directional (Polar) Coordinates e.g. 2.6,45")
+ label(text="p: Percent e.g. 67.5")
+ 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")
+ label(text="o: Send Maths Calculation to Output")
+ label(text="")
+ label(text="Note that commands are case-insensitive: ED = Ed = eD = ed")
+ label(text="")
+ label(text="Examples:")
+ label(text="")
+ label(text="ed0.5,,0.6")
+ label(text="'- Extrude Geometry Delta 0.5 in X, 0 in Y, 0.6 in Z")
+ label(text="")
+ label(text="fe0.1,4,0.5")
+ label(text="'- Fillet Edges")
+ label(text="'- Radius: 0.1 (float) -- the radius (or offset) of the bevel/fillet")
+ label(text="'- Segments: 4 (int) -- choosing an even amount of segments gives better geometry")
+ label(text="'- Profile: 0.5 (float[0.0;1.0]) -- 0.5 (default) yields a circular, convex shape")
+
+
+def command_maths(context, mode, pg, expression, output_target):
+ """Evaluates Maths Input.
+
+ Args:
+ context: Blender bpy.context instance.
+ mode, pg, expression, output_target
+
+ Returns:
+ Nothing.
+ """
+
+ namespace = {}
+ namespace.update(vars(math))
+ try:
+ maths_result = eval(expression, namespace, namespace)
+ except:
+ pg.error = PDT_ERR_BADMATHS
+ context.window_manager.popup_menu(oops, title="Error", icon="ERROR")
+ raise PDT_MathsError
+ if output_target == "x":
+ pg.cartesian_coords.x = maths_result
+ elif output_target == "y":
+ pg.cartesian_coords.y = maths_result
+ elif output_target == "z":
+ pg.cartesian_coords.z = maths_result
+ elif output_target == "d":
+ pg.distance = maths_result
+ elif output_target == "a":
+ pg.angle = maths_result
+ elif output_target == "p":
+ pg.percent = maths_result
+ else:
+ # Mst be "o"
+ pg.maths_output = maths_result
+ return
+
+
+def command_parse(context):
+ scene = context.scene
+ pg = scene.pdt_pg
+ command = pg.command.strip()
+ operation = command[0].upper()
+ mode = command[1].lower()
values = command[2:].split(",")
+ mode_s = pg.select
+ obj = context.view_layer.objects.active
ind = 0
for r in values:
try:
@@ -276,13 +411,7 @@ def command_run(self, context):
except ValueError:
values[ind] = "0"
ind = ind + 1
- mode_s = pg.select
- flip_a = pg.flip_angle
- flip_p = pg.flip_percent
- ext_a = pg.extend
- plane = pg.plane
- obj = context.view_layer.objects.active
- bm, good = obj_check(obj, scene, operation)
+ bm, good = obj_check(context, obj, scene, operation)
if good:
obj_loc = obj.matrix_world.decompose()[0]
else:
@@ -293,426 +422,479 @@ def command_run(self, context):
if len([v for v in bm.verts if v.select]) == 0:
pg.error = PDT_ERR_NO_SEL_GEOM
context.window_manager.popup_menu(oops, title="Error", icon="ERROR")
- return
+ raise PDT_SelectionError
else:
verts = [v for v in bm.verts if v.select]
else:
verts = bm.select_history
+ elif operation == "G" and mode == "a":
+ verts = [v for v in bm.verts if v.select]
else:
verts = []
debug(f"command: {command}")
debug(f"obj: {obj}, bm: {bm}, obj_loc: {obj_loc}")
- # ---------------------
- # Cursor or Pivot Point
- if operation in {"C", "P"}:
- # Absolute/Global Coordinates, or Delta/Relative Coordinates
- if mode in {"a", "d"}:
- valid_result, vector_delta = vector_build(context, pg, obj, operation, values, 3)
- # Direction/Polar Coordinates
- elif mode == "i":
- valid_result, vector_delta = vector_build(context, pg, obj, operation, values, 2)
- # Percent Options
- elif mode == "p":
- valid_result, vector_delta = vector_build(context, pg, obj, operation, values, 1)
-
- if valid_result:
- move_cursor_pivot(context, pg, obj, verts, operation,
- mode, vector_delta)
- return
+ return pg, values, obj, obj_loc, bm, verts
- # ------------------------
- # Move Vertices or Objects
- elif operation == "G":
- if obj.mode == "EDIT":
- if len(verts) == 0:
- pg.error = PDT_ERR_NO_SEL_GEOM
- context.window_manager.popup_menu(oops, title="Error", icon="ERROR")
- return
- # Absolute/Global Coordinates
- if mode == "a":
- valid_result, vector_delta = vector_build(context, pg, obj, operation, values, 3)
- if not valid_result:
- return
+
+def move_cursor_pivot(context, pg, operation, mode, obj, verts, values):
+ # Absolute/Global Coordinates, or Delta/Relative Coordinates
+ if mode in {"a", "d"}:
+ try:
+ vector_delta = vector_build(context, pg, obj, operation, values, 3)
+ except:
+ raise PDT_InvalidVector
+ # Direction/Polar Coordinates
+ elif mode == "i":
+ try:
+ vector_delta = vector_build(context, pg, obj, operation, values, 2)
+ except:
+ raise PDT_InvalidVector
+ # Percent Options
+ else:
+ # Must be Percent
+ try:
+ vector_delta = vector_build(context, pg, obj, operation, values, 1)
+ except:
+ raise PDT_InvalidVector
+
+ if vector_delta == None:
+ raise PDT_InvalidVector
+
+ scene = context.scene
+ mode_sel = pg.select
+ obj_loc = obj.matrix_world.decompose()[0]
+
+ if mode == "a":
+ if operation == "C":
+ scene.cursor.location = vector_delta
+ elif operation == "P":
+ pg.pivot_loc = vector_delta
+ elif mode in {"d", "i"}:
+ if mode_sel == "REL":
+ if operation == "C":
+ scene.cursor.location = scene.cursor.location + vector_delta
+ else:
+ pg.pivot_loc = pg.pivot_loc + vector_delta
+ elif mode_sel == "SEL":
if obj.mode == "EDIT":
- for v in verts:
- v.co = vector_delta - obj_loc
- bmesh.ops.remove_doubles(
- bm, verts=[v for v in bm.verts if v.select], dist=0.0001
- )
- elif obj.mode == "OBJECT":
- for ob in context.view_layer.objects.selected:
- ob.location = vector_delta
-
- elif mode in {"d", "i"}:
- if mode == "d":
- # Delta/Relative Coordinates
- valid_result, vector_delta = vector_build(context, pg, obj, operation, values, 3)
- if not valid_result:
- return
+ if operation == "C":
+ scene.cursor.location = verts[-1].co + obj_loc + vector_delta
+ else:
+ pg.pivot_loc = verts[-1].co + obj_loc + vector_delta
+ if obj.mode == "OBJECT":
+ if operation == "C":
+ scene.cursor.location = obj_loc + vector_delta
+ else:
+ pg.pivot_loc = obj_loc + vector_delta
+ else:
+ # Must be Percent
+ if obj.mode == "EDIT":
+ if operation == "C":
+ scene.cursor.location = obj_loc + vector_delta
else:
- # Direction/Polar Coordinates
- valid_result, vector_delta = vector_build(context, pg, obj, operation, values, 2)
- if not valid_result:
- return
- if vector_delta is not None:
- if obj.mode == "EDIT":
- bmesh.ops.translate(
- bm, verts=[v for v in bm.verts if v.select], vec=vector_delta
- )
- elif obj.mode == "OBJECT":
- for ob in context.view_layer.objects.selected:
- ob.location = obj_loc + vector_delta
- # Percent Options
- elif mode == "p":
- valid_result, vector_delta = vector_build(context, pg, obj, operation, values, 1)
- if not valid_result:
- return
- if vector_delta is not None:
- if obj.mode == 'EDIT':
- verts[-1].co = vector_delta
- elif obj.mode == "OBJECT":
- obj.location = vector_delta
- if obj.mode == 'EDIT':
- bmesh.update_edit_mesh(obj.data)
- bm.select_history.clear()
- return
-
- # --------------
- # Add New Vertex
- elif operation == "N":
- if not obj.mode == "EDIT":
- pg.error = PDT_ERR_ADDVEDIT
- context.window_manager.popup_menu(oops, title="Error", icon="ERROR")
- return
- # Absolute/Global Coordinates
- if mode == "a":
- valid_result, vector_delta = vector_build(context, pg, obj, operation, values, 3)
- if not valid_result:
- return
- new_vertex = bm.verts.new(vector_delta - obj_loc)
- # Delta/Relative Coordinates
- elif mode == "d":
- valid_result, vector_delta = vector_build(context, pg, obj, operation, values, 3)
- if not valid_result:
- return
- new_vertex = bm.verts.new(verts[-1].co + vector_delta)
- # Direction/Polar Coordinates
- elif mode == "i":
- valid_result, vector_delta = vector_build(context, pg, obj, operation, values, 2)
- if not valid_result:
- return
- new_vertex = bm.verts.new(verts[-1].co + vector_delta)
- # Percent Options
- elif mode == "p":
- valid_result, vector_delta = vector_build(context, pg, obj, operation, values, 1)
- if not valid_result:
- return
- new_vertex = bm.verts.new(vector_delta)
-
- for v in [v for v in bm.verts if v.select]:
- v.select_set(False)
- new_vertex.select_set(True)
- bmesh.update_edit_mesh(obj.data)
- bm.select_history.clear()
- return
+ pg.pivot_loc = obj_loc + vector_delta
+ if obj.mode == "OBJECT":
+ if operation == "C":
+ scene.cursor.location = vector_delta
+ else:
+ pg.pivot_loc = vector_delta
+ return
- # -----------
- # Split Edges
- elif operation == "S":
- if not obj.mode == "EDIT":
- pg.error = PDT_ERR_SPLITEDIT
- context.window_manager.popup_menu(oops, title="Error", icon="ERROR")
- return
- # Absolute/Global Coordinates
- if mode == "a":
- valid_result, vector_delta = vector_build(context, pg, obj, operation, values, 3)
- if not valid_result:
- return
- edges = [e for e in bm.edges if e.select]
- if len(edges) != 1:
- pg.error = f"{PDT_ERR_SEL_1_EDGE} {len(edges)})"
- context.window_manager.popup_menu(oops, title="Error", icon="ERROR")
- return
- geom = bmesh.ops.subdivide_edges(bm, edges=edges, cuts=1)
- new_verts = [v for v in geom["geom_split"] if isinstance(v, bmesh.types.BMVert)]
- new_vertex = new_verts[0]
- new_vertex.co = vector_delta - obj_loc
- # Delta/Relative Coordinates
- elif mode == "d":
- valid_result, vector_delta = vector_build(context, pg, obj, operation, values, 3)
- if not valid_result:
- return
- edges = [e for e in bm.edges if e.select]
- faces = [f for f in bm.faces if f.select]
- if len(faces) != 0:
- pg.error = PDT_ERR_FACE_SEL
- context.window_manager.popup_menu(oops, title="Error", icon="ERROR")
- return
- if len(edges) < 1:
- pg.error = f"{PDT_ERR_SEL_1_EDGEM} {len(edges)})"
- context.window_manager.popup_menu(oops, title="Error", icon="ERROR")
- return
- geom = bmesh.ops.subdivide_edges(bm, edges=edges, cuts=1)
- new_verts = [v for v in geom["geom_split"] if isinstance(v, bmesh.types.BMVert)]
- bmesh.ops.translate(bm, verts=new_verts, vec=vector_delta)
- # Directional/Polar Coordinates
- elif mode == "i":
- valid_result, vector_delta = vector_build(context, pg, obj, operation, values, 2)
- if not valid_result:
- return
- edges = [e for e in bm.edges if e.select]
- faces = [f for f in bm.faces if f.select]
- if len(faces) != 0:
- pg.error = PDT_ERR_FACE_SEL
- context.window_manager.popup_menu(oops, title="Error", icon="ERROR")
- return
- if len(edges) < 1:
- pg.error = f"{PDT_ERR_SEL_1_EDGEM} {len(edges)})"
- context.window_manager.popup_menu(oops, title="Error", icon="ERROR")
- return
- geom = bmesh.ops.subdivide_edges(bm, edges=edges, cuts=1)
- new_verts = [v for v in geom["geom_split"] if isinstance(v, bmesh.types.BMVert)]
- bmesh.ops.translate(bm, verts=new_verts, vec=vector_delta)
- # Percent Options
- elif mode == "p":
- valid_result, vector_delta = vector_build(context, pg, obj, operation, values, 1)
- if not valid_result:
- return
- edges = [e for e in bm.edges if e.select]
- faces = [f for f in bm.faces if f.select]
- if len(faces) != 0:
- pg.error = PDT_ERR_FACE_SEL
- context.window_manager.popup_menu(oops, title="Error", icon="ERROR")
- return
- if len(edges) != 1:
- pg.error = f"{PDT_ERR_SEL_1_EDGEM} {len(edges)})"
- context.window_manager.popup_menu(oops, title="Error", icon="ERROR")
- return
- geom = bmesh.ops.subdivide_edges(bm, edges=edges, cuts=1)
- new_verts = [v for v in geom["geom_split"] if isinstance(v, bmesh.types.BMVert)]
- new_vertex = new_verts[0]
- new_vertex.co = vector_delta
- for v in [v for v in bm.verts if v.select]:
- v.select_set(False)
- for v in new_verts:
- v.select_set(False)
- bmesh.update_edit_mesh(obj.data)
- bm.select_history.clear()
- return
+def move_entities(context, pg, operation, mode, obj, bm, verts, values):
+ obj_loc = obj.matrix_world.decompose()[0]
- # ----------------
- # Extrude Vertices
- elif operation == "V":
- if not obj.mode == "EDIT":
- pg.error = PDT_ERR_EXTEDIT
- context.window_manager.popup_menu(oops, title="Error", icon="ERROR")
- return
- # Absolute/Global Coordinates
- if mode == "a":
- valid_result, vector_delta = vector_build(context, pg, obj, operation, values, 3)
- if not valid_result:
- return
- new_vertex = bm.verts.new(vector_delta - obj_loc)
+ # Absolute/Global Coordinates
+ if mode == "a":
+ try:
+ vector_delta = vector_build(context, pg, obj, operation, values, 3)
+ except:
+ raise PDT_InvalidVector
+ if obj.mode == "EDIT":
for v in verts:
- bm.edges.new([v, new_vertex])
- v.select_set(False)
- new_vertex.select_set(True)
+ v.co = vector_delta - obj_loc
bmesh.ops.remove_doubles(
bm, verts=[v for v in bm.verts if v.select], dist=0.0001
)
- # Delta/Relative Coordinates
- elif mode == "d":
- valid_result, vector_delta = vector_build(context, pg, obj, operation, values, 3)
- if not valid_result:
- return
- for v in verts:
- new_vertex = bm.verts.new(v.co)
- new_vertex.co = new_vertex.co + vector_delta
- bm.edges.new([v, new_vertex])
- v.select_set(False)
- new_vertex.select_set(True)
- # Direction/Polar Coordinates
- elif mode == "i":
- valid_result, vector_delta = vector_build(context, pg, obj, operation, values, 2)
- if not valid_result:
- return
- for v in verts:
- new_vertex = bm.verts.new(v.co)
- new_vertex.co = new_vertex.co + vector_delta
- bm.edges.new([v, new_vertex])
- v.select_set(False)
- new_vertex.select_set(True)
- # Percent Options
- elif mode == "p":
- valid_result, vector_delta = vector_build(context, pg, obj, operation, values, 1)
- if not valid_result:
- return
- verts = [v for v in bm.verts if v.select].copy()
- if len(verts) == 0:
- pg.error = PDT_ERR_NO_SEL_GEOM
- context.window_manager.popup_menu(oops, title="Error", icon="ERROR")
- return
- new_vertex = bm.verts.new(vector_delta)
- if ext_a:
- for v in [v for v in bm.verts if v.select]:
- bm.edges.new([v, new_vertex])
- v.select_set(False)
- else:
- bm.edges.new([verts[-1], new_vertex])
- new_vertex.select_set(True)
+ if obj.mode == "OBJECT":
+ for ob in context.view_layer.objects.selected:
+ ob.location = vector_delta
+ elif mode in {"d", "i"}:
+ if mode == "d":
+ # Delta/Relative Coordinates
+ try:
+ vector_delta = vector_build(context, pg, obj, operation, values, 3)
+ except:
+ raise PDT_InvalidVector
+ else:
+ # Direction/Polar Coordinates
+ try:
+ vector_delta = vector_build(context, pg, obj, operation, values, 2)
+ except:
+ raise PDT_InvalidVector
+ if obj.mode == "EDIT":
+ bmesh.ops.translate(
+ bm, verts=[v for v in bm.verts if v.select], vec=vector_delta
+ )
+ if obj.mode == "OBJECT":
+ for ob in context.view_layer.objects.selected:
+ ob.location = obj_loc + vector_delta
+ # Percent Options Only Other Choice
+ else:
+ try:
+ vector_delta = vector_build(context, pg, obj, operation, values, 1)
+ except:
+ raise PDT_InvalidVector
+ if obj.mode == 'EDIT':
+ verts[-1].co = vector_delta
+ if obj.mode == "OBJECT":
+ obj.location = vector_delta
+ if obj.mode == 'EDIT':
bmesh.update_edit_mesh(obj.data)
bm.select_history.clear()
- return
+ return
- # ----------------
- # Extrude Geometry
- elif operation == "E":
- if not obj.mode == "EDIT":
- pg.error = PDT_ERR_EXTEDIT
+
+def add_new_vertex(context, pg, operation, mode, obj, bm, verts, values):
+ obj_loc = obj.matrix_world.decompose()[0]
+
+ if not obj.mode == "EDIT":
+ pg.error = PDT_ERR_ADDVEDIT
+ context.window_manager.popup_menu(oops, title="Error", icon="ERROR")
+ raise PDT_SelectionError
+ # Absolute/Global Coordinates
+ if mode == "a":
+ try:
+ vector_delta = vector_build(context, pg, obj, operation, values, 3)
+ except:
+ raise PDT_InvalidVector
+ new_vertex = bm.verts.new(vector_delta - obj_loc)
+ # Delta/Relative Coordinates
+ elif mode == "d":
+ try:
+ vector_delta = vector_build(context, pg, obj, operation, values, 3)
+ except:
+ raise PDT_InvalidVector
+ new_vertex = bm.verts.new(verts[-1].co + vector_delta)
+ # Direction/Polar Coordinates
+ elif mode == "i":
+ try:
+ vector_delta = vector_build(context, pg, obj, operation, values, 2)
+ except:
+ raise PDT_InvalidVector
+ new_vertex = bm.verts.new(verts[-1].co + vector_delta)
+ # Percent Options Only Other Choice
+ else:
+ try:
+ vector_delta = vector_build(context, pg, obj, operation, values, 1)
+ except:
+ raise PDT_InvalidVector
+ new_vertex = bm.verts.new(vector_delta)
+
+ for v in [v for v in bm.verts if v.select]:
+ v.select_set(False)
+ new_vertex.select_set(True)
+ bmesh.update_edit_mesh(obj.data)
+ bm.select_history.clear()
+ return
+
+
+def split_edges(context, pg, operation, mode, obj, obj_loc, bm, values):
+ if not obj.mode == "EDIT":
+ pg.error = PDT_ERR_SPLITEDIT
+ context.window_manager.popup_menu(oops, title="Error", icon="ERROR")
+ return
+ # Absolute/Global Coordinates
+ if mode == "a":
+ try:
+ vector_delta = vector_build(context, pg, obj, operation, values, 3)
+ except:
+ raise PDT_InvalidVector
+ edges = [e for e in bm.edges if e.select]
+ if len(edges) != 1:
+ pg.error = f"{PDT_ERR_SEL_1_EDGE} {len(edges)})"
context.window_manager.popup_menu(oops, title="Error", icon="ERROR")
return
- # Delta/Relative Coordinates
- if mode == "d":
- valid_result, vector_delta = vector_build(context, pg, obj, operation, values, 3)
- if not valid_result:
- return
- # Direction/Polar Coordinates
- elif mode == "i":
- valid_result, vector_delta = vector_build(context, pg, obj, values, 2)
- if not valid_result:
- return
-
- ret = bmesh.ops.extrude_face_region(
- bm,
- geom=(
- [f for f in bm.faces if f.select]
- + [e for e in bm.edges if e.select]
- + [v for v in bm.verts if v.select]
- ),
- use_select_history=True,
- )
- geom_extr = ret["geom"]
- verts_extr = [v for v in geom_extr if isinstance(v, bmesh.types.BMVert)]
- edges_extr = [e for e in geom_extr if isinstance(e, bmesh.types.BMEdge)]
- faces_extr = [f for f in geom_extr if isinstance(f, bmesh.types.BMFace)]
- del ret
- bmesh.ops.translate(bm, verts=verts_extr, vec=vector_delta)
- update_sel(bm, verts_extr, edges_extr, faces_extr)
- bmesh.update_edit_mesh(obj.data)
- bm.select_history.clear()
- return
-
- # ------------------
- # Duplicate Geometry
- elif operation == "D":
- if not obj.mode == "EDIT":
- pg.error = PDT_ERR_DUPEDIT
+ geom = bmesh.ops.subdivide_edges(bm, edges=edges, cuts=1)
+ new_verts = [v for v in geom["geom_split"] if isinstance(v, bmesh.types.BMVert)]
+ new_vertex = new_verts[0]
+ new_vertex.co = vector_delta - obj_loc
+ # Delta/Relative Coordinates
+ elif mode == "d":
+ try:
+ vector_delta = vector_build(context, pg, obj, operation, values, 3)
+ except:
+ raise PDT_InvalidVector
+ edges = [e for e in bm.edges if e.select]
+ faces = [f for f in bm.faces if f.select]
+ if len(faces) != 0:
+ pg.error = PDT_ERR_FACE_SEL
context.window_manager.popup_menu(oops, title="Error", icon="ERROR")
return
- # Delta/Relative Coordinates
- if mode == "d":
- valid_result, vector_delta = vector_build(context, pg, obj, operation, values, 3)
- if not valid_result:
- return
- # Direction/Polar Coordinates
- elif mode == "i":
- valid_result, vector_delta = vector_build(context, pg, obj, operation, values, 2)
- if not valid_result:
- return
-
- ret = bmesh.ops.duplicate(
- bm,
- geom=(
- [f for f in bm.faces if f.select]
- + [e for e in bm.edges if e.select]
- + [v for v in bm.verts if v.select]
- ),
- use_select_history=True,
- )
- geom_dupe = ret["geom"]
- verts_dupe = [v for v in geom_dupe if isinstance(v, bmesh.types.BMVert)]
- edges_dupe = [e for e in geom_dupe if isinstance(e, bmesh.types.BMEdge)]
- faces_dupe = [f for f in geom_dupe if isinstance(f, bmesh.types.BMFace)]
- del ret
- bmesh.ops.translate(bm, verts=verts_dupe, vec=vector_delta)
- update_sel(bm, verts_dupe, edges_dupe, faces_dupe)
- bmesh.update_edit_mesh(obj.data)
- bm.select_history.clear()
- return
-
- # ---------------
- # Fillet Geometry
- elif operation == "F":
- if obj is None:
- pg.error = PDT_ERR_NO_ACT_OBJ
+ if len(edges) < 1:
+ pg.error = f"{PDT_ERR_SEL_1_EDGEM} {len(edges)})"
context.window_manager.popup_menu(oops, title="Error", icon="ERROR")
return
- if not obj.mode == "EDIT":
- pg.error = PDT_ERR_FILEDIT
+ geom = bmesh.ops.subdivide_edges(bm, edges=edges, cuts=1)
+ new_verts = [v for v in geom["geom_split"] if isinstance(v, bmesh.types.BMVert)]
+ bmesh.ops.translate(bm, verts=new_verts, vec=vector_delta)
+ # Directional/Polar Coordinates
+ elif mode == "i":
+ try:
+ vector_delta = vector_build(context, pg, obj, operation, values, 2)
+ except:
+ raise PDT_InvalidVector
+ edges = [e for e in bm.edges if e.select]
+ faces = [f for f in bm.faces if f.select]
+ if len(faces) != 0:
+ pg.error = PDT_ERR_FACE_SEL
context.window_manager.popup_menu(oops, title="Error", icon="ERROR")
return
- if len(values) != 3:
- pg.error = PDT_ERR_BAD3VALS
+ if len(edges) < 1:
+ pg.error = f"{PDT_ERR_SEL_1_EDGEM} {len(edges)})"
context.window_manager.popup_menu(oops, title="Error", icon="ERROR")
return
- if mode in {"i", "v"}:
- vert_bool = True
- elif mode == "e":
- vert_bool = False
- verts = [v for v in bm.verts if v.select]
- if len(verts) == 0:
- pg.error = PDT_ERR_SEL_1_VERT
+ geom = bmesh.ops.subdivide_edges(bm, edges=edges, cuts=1)
+ new_verts = [v for v in geom["geom_split"] if isinstance(v, bmesh.types.BMVert)]
+ bmesh.ops.translate(bm, verts=new_verts, vec=vector_delta)
+ # Percent Options
+ elif mode == "p":
+ try:
+ vector_delta = vector_build(context, pg, obj, operation, values, 1)
+ except:
+ raise PDT_InvalidVector
+ edges = [e for e in bm.edges if e.select]
+ faces = [f for f in bm.faces if f.select]
+ if len(faces) != 0:
+ pg.error = PDT_ERR_FACE_SEL
context.window_manager.popup_menu(oops, title="Error", icon="ERROR")
return
- # Note that passing an empty parameter results in that parameter being seen as "0"
- # _offset <= 0 is ignored since a bevel/fillet radius must be > 0 to make sense
- _offset = float(values[0])
- _segments = int(values[1])
- if _segments < 1:
- _segments = 1 # This is a single, flat segment (ignores profile)
- _profile = float(values[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:
- v_active = edges[0].verts[0]
- v_other = edges[0].verts[1]
- v_last = edges[1].verts[0]
- v_first = edges[1].verts[1]
- vector_delta, done = intersection(v_active.co,
- v_other.co,
- v_last.co,
- v_first.co,
- plane
- )
- if not done:
- errmsg = f"{PDT_ERR_INT_LINES} {plane} {PDT_LAB_PLANE}"
- self.report({"ERROR"}, errmsg)
- return {"FINISHED"}
- if (v_active.co - vector_delta).length < (v_other.co - vector_delta).length:
- v_active.co = vector_delta
- v_other.select_set(False)
- else:
- v_other.co = vector_delta
- v_active.select_set(False)
- if (v_last.co - vector_delta).length < (v_first.co - vector_delta).length:
- v_last.co = vector_delta
- v_first.select_set(False)
- else:
- v_first.co = vector_delta
- v_last.select_set(False)
- bmesh.ops.remove_doubles(bm, verts=bm.verts, dist=0.0001)
- bpy.ops.mesh.bevel(
- offset_type="OFFSET",
- offset=_offset,
- segments=_segments,
- profile=_profile,
- vertex_only=vert_bool
+ if len(edges) != 1:
+ pg.error = f"{PDT_ERR_SEL_1_EDGEM} {len(edges)})"
+ context.window_manager.popup_menu(oops, title="Error", icon="ERROR")
+ return
+ geom = bmesh.ops.subdivide_edges(bm, edges=edges, cuts=1)
+ new_verts = [v for v in geom["geom_split"] if isinstance(v, bmesh.types.BMVert)]
+ new_vertex = new_verts[0]
+ new_vertex.co = vector_delta
+
+ for v in [v for v in bm.verts if v.select]:
+ v.select_set(False)
+ for v in new_verts:
+ v.select_set(False)
+ bmesh.update_edit_mesh(obj.data)
+ bm.select_history.clear()
+ return
+
+
+def extrude_vertices(context, pg, operation, mode, obj, obj_loc, bm, verts, values):
+ if not obj.mode == "EDIT":
+ pg.error = PDT_ERR_EXTEDIT
+ context.window_manager.popup_menu(oops, title="Error", icon="ERROR")
+ return
+ # Absolute/Global Coordinates
+ if mode == "a":
+ try:
+ vector_delta = vector_build(context, pg, obj, operation, values, 3)
+ except:
+ raise PDT_InvalidVector
+ new_vertex = bm.verts.new(vector_delta - obj_loc)
+ verts = [v for v in bm.verts if v.select].copy()
+ for v in verts:
+ bm.edges.new([v, new_vertex])
+ v.select_set(False)
+ new_vertex.select_set(True)
+ bmesh.ops.remove_doubles(
+ bm, verts=[v for v in bm.verts if v.select], dist=0.0001
)
+ # Delta/Relative Coordinates
+ elif mode == "d":
+ try:
+ vector_delta = vector_build(context, pg, obj, operation, values, 3)
+ except:
+ raise PDT_InvalidVector
+ for v in verts:
+ new_vertex = bm.verts.new(v.co)
+ new_vertex.co = new_vertex.co + vector_delta
+ bm.edges.new([v, new_vertex])
+ v.select_set(False)
+ new_vertex.select_set(True)
+ # Direction/Polar Coordinates
+ elif mode == "i":
+ try:
+ vector_delta = vector_build(context, pg, obj, operation, values, 2)
+ except:
+ raise PDT_InvalidVector
+ for v in verts:
+ new_vertex = bm.verts.new(v.co)
+ new_vertex.co = new_vertex.co + vector_delta
+ bm.edges.new([v, new_vertex])
+ v.select_set(False)
+ new_vertex.select_set(True)
+ # Percent Options
+ elif mode == "p":
+ ext_a = pg.extend
+ try:
+ vector_delta = vector_build(context, pg, obj, operation, values, 1)
+ except:
+ raise PDT_InvalidVector
+ verts = [v for v in bm.verts if v.select].copy()
+ new_vertex = bm.verts.new(vector_delta)
+ if ext_a:
+ for v in [v for v in bm.verts if v.select]:
+ bm.edges.new([v, new_vertex])
+ v.select_set(False)
+ else:
+ bm.edges.new([verts[-1], new_vertex])
+ new_vertex.select_set(True)
+
+ bmesh.update_edit_mesh(obj.data)
+ bm.select_history.clear()
+ return
+
+
+def extrude_geometry(context, pg, operation, mode, obj, bm, values):
+ if not obj.mode == "EDIT":
+ pg.error = PDT_ERR_EXTEDIT
+ context.window_manager.popup_menu(oops, title="Error", icon="ERROR")
+ return
+ # Delta/Relative Coordinates
+ if mode == "d":
+ try:
+ vector_delta = vector_build(context, pg, obj, operation, values, 3)
+ except:
+ raise PDT_InvalidVector
+ # Direction/Polar Coordinates
+ elif mode == "i":
+ try:
+ vector_delta = vector_build(context, pg, obj, operation, values, 2)
+ except:
+ raise PDT_InvalidVector
+
+ ret = bmesh.ops.extrude_face_region(
+ bm,
+ geom=(
+ [f for f in bm.faces if f.select]
+ + [e for e in bm.edges if e.select]
+ + [v for v in bm.verts if v.select]
+ ),
+ use_select_history=True,
+ )
+ geom_extr = ret["geom"]
+ verts_extr = [v for v in geom_extr if isinstance(v, bmesh.types.BMVert)]
+ edges_extr = [e for e in geom_extr if isinstance(e, bmesh.types.BMEdge)]
+ faces_extr = [f for f in geom_extr if isinstance(f, bmesh.types.BMFace)]
+ del ret
+ bmesh.ops.translate(bm, verts=verts_extr, vec=vector_delta)
+ update_sel(bm, verts_extr, edges_extr, faces_extr)
+ bmesh.update_edit_mesh(obj.data)
+ bm.select_history.clear()
+ return
+
+def duplicate_geometry(context, pg, operation, mode, obj, bm, values):
+ if not obj.mode == "EDIT":
+ pg.error = PDT_ERR_DUPEDIT
+ context.window_manager.popup_menu(oops, title="Error", icon="ERROR")
return
+ # Delta/Relative Coordinates
+ if mode == "d":
+ try:
+ vector_delta = vector_build(context, pg, obj, operation, values, 3)
+ except:
+ raise PDT_InvalidVector
+ # Direction/Polar Coordinates
+ elif mode == "i":
+ try:
+ vector_delta = vector_build(context, pg, obj, operation, values, 2)
+ except:
+ raise PDT_InvalidVector
+
+ ret = bmesh.ops.duplicate(
+ bm,
+ geom=(
+ [f for f in bm.faces if f.select]
+ + [e for e in bm.edges if e.select]
+ + [v for v in bm.verts if v.select]
+ ),
+ use_select_history=True,
+ )
+ geom_dupe = ret["geom"]
+ verts_dupe = [v for v in geom_dupe if isinstance(v, bmesh.types.BMVert)]
+ edges_dupe = [e for e in geom_dupe if isinstance(e, bmesh.types.BMEdge)]
+ faces_dupe = [f for f in geom_dupe if isinstance(f, bmesh.types.BMFace)]
+ del ret
+ bmesh.ops.translate(bm, verts=verts_dupe, vec=vector_delta)
+ update_sel(bm, verts_dupe, edges_dupe, faces_dupe)
+ bmesh.update_edit_mesh(obj.data)
+ bm.select_history.clear()
+ return
+
+
+def fillet_geometry(context, pg, mode, obj, bm, verts, values):
+ if not obj.mode == "EDIT":
+ pg.error = PDT_ERR_FILEDIT
+ context.window_manager.popup_menu(oops, title="Error", icon="ERROR")
+ return
+ if mode in {"i", "v"}:
+ vert_bool = True
+ elif mode == "e":
+ vert_bool = False
+ # Note that passing an empty parameter results in that parameter being seen as "0"
+ # _offset <= 0 is ignored since a bevel/fillet radius must be > 0 to make sense
+ _offset = float(values[0])
+ _segments = int(values[1])
+ if _segments < 1:
+ _segments = 1 # This is a single, flat segment (ignores profile)
+ _profile = float(values[2])
+ if _profile < 0.0 or _profile > 1.0:
+ _profile = 0.5 # This is a circular profile
+ if mode == "i":
+ # Fillet & Intersect Two Edges
+ # Always use Current Selection
+ verts = [v for v in bm.verts if v.select]
+ edges = [e for e in bm.edges if e.select]
+ if len(edges) == 2 and len(verts) == 4:
+ plane = pg.plane
+ v_active = edges[0].verts[0]
+ v_other = edges[0].verts[1]
+ v_last = edges[1].verts[0]
+ v_first = edges[1].verts[1]
+ vector_delta, done = intersection(v_active.co,
+ v_other.co,
+ v_last.co,
+ v_first.co,
+ plane
+ )
+ if not done:
+ errmsg = f"{PDT_ERR_INT_LINES} {plane} {PDT_LAB_PLANE}"
+ self.report({"ERROR"}, errmsg)
+ raise PDT_IntersectionError
+ if (v_active.co - vector_delta).length < (v_other.co - vector_delta).length:
+ v_active.co = vector_delta
+ v_other.select_set(False)
+ else:
+ v_other.co = vector_delta
+ v_active.select_set(False)
+ if (v_last.co - vector_delta).length < (v_first.co - vector_delta).length:
+ v_last.co = vector_delta
+ v_first.select_set(False)
+ else:
+ v_first.co = vector_delta
+ v_last.select_set(False)
+ bmesh.ops.remove_doubles(bm, verts=bm.verts, dist=0.0001)
+ else:
+ pg.error = f"{PDT_ERR_SEL_4_VERTS} {len(verts)} Vert(s), {len(edges)} Edge(s))"
+ context.window_manager.popup_menu(oops, title="Error", icon="ERROR")
+ raise PDT_SelectionError
+
+ bpy.ops.mesh.bevel(
+ offset_type="OFFSET",
+ offset=_offset,
+ segments=_segments,
+ profile=_profile,
+ vertex_only=vert_bool
+ )
+ return
diff --git a/precision_drawing_tools/pdt_functions.py b/precision_drawing_tools/pdt_functions.py
index d6462852..65b4069a 100644
--- a/precision_drawing_tools/pdt_functions.py
+++ b/precision_drawing_tools/pdt_functions.py
@@ -175,12 +175,12 @@ def check_selection(num, bm, obj):
elif num == 3:
vector_b = bm.select_history[-2].co
vector_c = bm.select_history[-3].co
- return vector_a, vector_b, vector_d
+ return vector_a, vector_b, vector_c
elif num == 4:
vector_b = bm.select_history[-2].co
vector_c = bm.select_history[-3].co
vector_d = bm.select_history[-4].co
- return vector_a, vector_b, vector_d, vector_c
+ return vector_a, vector_b, vector_c, vector_d
else:
for f in bm.faces:
f.select_set(False)
@@ -319,7 +319,7 @@ def euler_to_quaternion(roll, pitch, yaw):
return Quaternion((qw, qx, qy, qz))
-def arc_centre(vector_a, vector_b, vector_d):
+def arc_centre(vector_a, vector_b, vector_c):
"""Calculates Centre of Arc from 3 Vector Locations using standard Numpy routine
Args:
@@ -333,7 +333,7 @@ def arc_centre(vector_a, vector_b, vector_d):
A = np.array([vector_a.x, vector_a.y, vector_a.z])
B = np.array([vector_b.x, vector_b.y, vector_b.z])
- C = np.array([vector_d.x, vector_d.y, vector_d.z])
+ C = np.array([vector_c.x, vector_c.y, vector_c.z])
a = np.linalg.norm(C - B)
b = np.linalg.norm(C - A)
c = np.linalg.norm(B - A)
@@ -370,11 +370,11 @@ def intersection(vertex_a, vertex_b, vertex_c, vertex_d, plane):
vertex_d = view_coords_i(vertex_offset.x, vertex_offset.y, vertex_offset.z)
vertex_offset = vertex_c - vertex_a
vertex_c = view_coords_i(vertex_offset.x, vertex_offset.y, vertex_offset.z)
- refV = Vector((0, 0, 0))
+ vector_ref = Vector((0, 0, 0))
ap1 = (vertex_c.x, vertex_c.y)
ap2 = (vertex_d.x, vertex_d.y)
bp1 = (vertex_b.x, vertex_b.y)
- bp2 = (refV.x, refV.y)
+ bp2 = (vector_ref.x, vector_ref.y)
else:
a1, a2, a3 = set_mode(plane)
ap1 = (vertex_c[a1], vertex_c[a2])
@@ -473,7 +473,7 @@ def get_percent(obj, flip_p, per_v, data, scene):
return Vector((V[0], V[1], V[2]))
-def obj_check(obj, scene, operator):
+def obj_check(context, obj, scene, operator):
"""Check Object & Selection Validity.
Args:
@@ -515,7 +515,7 @@ def obj_check(obj, scene, operator):
bpy.context.window_manager.popup_menu(oops, title="Error", icon="ERROR")
return None, False
return bm, True
- elif obj.mode == "OBJECT":
+ else:
return None, True
@@ -549,7 +549,6 @@ def dis_ang(vals, flip_a, plane, scene):
# fmt: off
vector_delta[a1] = vector_delta[a1] + (dis_v * cos(ang_v * pi/180))
vector_delta[a2] = vector_delta[a2] + (dis_v * sin(ang_v * pi/180))
- # FIXME: Is a3 just ignored?
# fmt: on
return vector_delta
diff --git a/precision_drawing_tools/pdt_msg_strings.py b/precision_drawing_tools/pdt_msg_strings.py
index 01895c4c..950e8661 100644
--- a/precision_drawing_tools/pdt_msg_strings.py
+++ b/precision_drawing_tools/pdt_msg_strings.py
@@ -71,6 +71,7 @@ PDT_LAB_PIVOTLOCH = "Location"
# Error Message
#
PDT_ERR_NO_ACT_OBJ = "No Active Object - Please Select an Object"
+PDT_OBJ_MODE_ERROR = "Only Mesh Object in Edit or Object Mode Supported"
PDT_ERR_NO_ACT_VERT = "No Active Vertex - Select One Vertex Individually"
PDT_ERR_NO_SEL_GEOM = "No Geometry/Objects Selected"
PDT_ERR_NO_ACT_VERTS = "No Selected Geometry - Please Select some Geometry"