PDT: Refactor per Pylint suggestions + readability
- Remove unused imports - Add comments where appropriate - Improve readability of variable names - Re-implement a couple of functions using dictionaries instead of if-statements - Results of Pylint & Black operations, plus some fixes to code.
This commit is contained in:
parent
7805692b57
commit
877308f917
|
@ -21,11 +21,9 @@
|
|||
# Author: Alan Odom (Clockmender), Rune Morling (ermo) Copyright (c) 2019
|
||||
# -----------------------------------------------------------------------
|
||||
#
|
||||
import bpy
|
||||
import bmesh
|
||||
import math
|
||||
from math import sqrt, tan, pi
|
||||
import numpy as np
|
||||
from math import sqrt, tan, pi
|
||||
from mathutils import Vector
|
||||
from mathutils.geometry import intersect_point_line
|
||||
from .pdt_functions import (
|
||||
|
@ -45,7 +43,7 @@ from .pdt_functions import (
|
|||
from . import pdt_exception
|
||||
PDT_SelectionError = pdt_exception.SelectionError
|
||||
PDT_InvalidVector = pdt_exception.InvalidVector
|
||||
PDT_ObjectMode = pdt_exception.ObjectMode
|
||||
PDT_ObjectModeError = pdt_exception.ObjectModeError
|
||||
PDT_InfRadius = pdt_exception.InfRadius
|
||||
PDT_NoObjectError = pdt_exception.NoObjectError
|
||||
PDT_IntersectionError = pdt_exception.IntersectionError
|
||||
|
@ -101,10 +99,13 @@ def vector_build(context, pg, obj, operation, values, num_values):
|
|||
flip_a = pg.flip_angle
|
||||
flip_p = pg.flip_percent
|
||||
|
||||
# Cartesian 3D coordinates
|
||||
if num_values == 3 and len(values) == 3:
|
||||
output_vector = Vector((float(values[0]), float(values[1]), float(values[2])))
|
||||
# Polar 2D coordinates
|
||||
elif num_values == 2 and len(values) == 2:
|
||||
output_vector = dis_ang(values, flip_a, plane, scene)
|
||||
# Percentage of imaginary line between two 3D coordinates
|
||||
elif num_values == 1 and len(values) == 1:
|
||||
output_vector = get_percent(obj, flip_p, float(values[0]), operation, scene)
|
||||
else:
|
||||
|
@ -115,7 +116,7 @@ def vector_build(context, pg, obj, operation, values, num_values):
|
|||
else:
|
||||
pg.error = PDT_ERR_BAD1VALS
|
||||
context.window_manager.popup_menu(oops, title="Error", icon="ERROR")
|
||||
raise pdt_InvalidVector
|
||||
raise PDT_InvalidVector
|
||||
return output_vector
|
||||
|
||||
|
||||
|
@ -149,7 +150,7 @@ def placement_normal(context, operation):
|
|||
if obj is None:
|
||||
pg.error = PDT_ERR_NO_ACT_OBJ
|
||||
context.window_manager.popup_menu(oops, title="Error", icon="ERROR")
|
||||
raise PDT_ObjectMode
|
||||
raise PDT_ObjectModeError
|
||||
obj_loc = obj.matrix_world.decompose()[0]
|
||||
bm = bmesh.from_edit_mesh(obj.data)
|
||||
if len(bm.select_history) == 3:
|
||||
|
@ -224,10 +225,9 @@ def placement_normal(context, operation):
|
|||
else:
|
||||
pg.error = f"{operation} {PDT_ERR_NON_VALID} {PDT_LAB_NOR}"
|
||||
context.window_manager.popup_menu(oops, title="Error", icon="ERROR")
|
||||
return
|
||||
|
||||
|
||||
def placement_centre(context, operation):
|
||||
def placement_arc_centre(context, operation):
|
||||
"""Manipulates Geometry, or Objects to an Arc Centre defined by 3 points on an Imaginary Arc.
|
||||
|
||||
-- set position of CUrsor (CU)
|
||||
|
@ -256,7 +256,7 @@ def placement_centre(context, operation):
|
|||
if obj is None:
|
||||
pg.error = PDT_ERR_NO_ACT_OBJ
|
||||
context.window_manager.popup_menu(oops, title="Error", icon="ERROR")
|
||||
raise PDT_ObjectMode
|
||||
raise PDT_ObjectModeError
|
||||
obj = context.view_layer.objects.active
|
||||
obj_loc = obj.matrix_world.decompose()[0]
|
||||
bm = bmesh.from_edit_mesh(obj.data)
|
||||
|
@ -333,7 +333,6 @@ def placement_centre(context, operation):
|
|||
else:
|
||||
pg.error = f"{operation} {PDT_ERR_NON_VALID} {PDT_LAB_ARCCENTRE}"
|
||||
context.window_manager.popup_menu(oops, title="Error", icon="ERROR")
|
||||
return
|
||||
|
||||
|
||||
def placement_intersect(context, operation):
|
||||
|
@ -556,7 +555,7 @@ def join_two_vertices(context):
|
|||
else:
|
||||
pg.error = f"{PDT_ERR_EDOB_MODE},{obj.mode})"
|
||||
context.window_manager.popup_menu(oops, title="Error", icon="ERROR")
|
||||
raise PDT_ObjectMode
|
||||
raise PDT_ObjectModeError
|
||||
|
||||
|
||||
def set_angle_distance_two(context):
|
||||
|
@ -631,15 +630,12 @@ def set_angle_distance_two(context):
|
|||
if plane == "LO":
|
||||
pg.distance = round(sqrt(
|
||||
(vector_a.x - vector_b.x) ** 2 +
|
||||
(vector_a.y - vector_b.y) ** 2), val_round
|
||||
)
|
||||
(vector_a.y - vector_b.y) ** 2), val_round)
|
||||
else:
|
||||
pg.distance = round(sqrt(
|
||||
(vector_a[a1] - vector_b[a1]) ** 2 +
|
||||
(vector_a[a2] - vector_b[a2]) ** 2), val_round
|
||||
)
|
||||
pg.cartesian_coords = Vector(([round(i, val_round) for i in (vector_b - vector_a)]))
|
||||
return
|
||||
(vector_a[a2] - vector_b[a2]) ** 2), val_round)
|
||||
pg.cartesian_coords = Vector(([round(i, val_round) for i in vector_b - vector_a]))
|
||||
|
||||
|
||||
def set_angle_distance_three(context):
|
||||
|
@ -672,7 +668,7 @@ def set_angle_distance_three(context):
|
|||
if vector_a is None:
|
||||
pg.error = PDT_ERR_VERT_MODE
|
||||
context.window_manager.popup_menu(oops, title="Error", icon="ERROR")
|
||||
raise pdt_InvalidVector
|
||||
raise PDT_InvalidVector
|
||||
else:
|
||||
pg.error = f"{PDT_ERR_SEL_3_VERTIO} {len(bm.select_history)})"
|
||||
context.window_manager.popup_menu(oops, title="Error", icon="ERROR")
|
||||
|
@ -708,8 +704,7 @@ def set_angle_distance_three(context):
|
|||
else:
|
||||
pg.angle = round(ang, val_round)
|
||||
pg.distance = round((vector_a - vector_b).length, val_round)
|
||||
pg.cartesian_coords = Vector(([round(i, val_round) for i in (vector_b - vector_a)]))
|
||||
return
|
||||
pg.cartesian_coords = Vector(([round(i, val_round) for i in vector_b - vector_a]))
|
||||
|
||||
|
||||
def origin_to_cursor(context):
|
||||
|
@ -750,8 +745,7 @@ def origin_to_cursor(context):
|
|||
else:
|
||||
pg.error = f"{PDT_ERR_EDOB_MODE} {obj.mode})"
|
||||
context.window_manager.popup_menu(oops, title="Error", icon="ERROR")
|
||||
raise PDT_ObjectMode
|
||||
return
|
||||
raise PDT_ObjectModeError
|
||||
|
||||
|
||||
def taper(context):
|
||||
|
@ -809,7 +803,7 @@ def taper(context):
|
|||
v.co[a2] = v.co[a2] - (dis_v * tan(ang_v * pi / 180))
|
||||
bmesh.update_edit_mesh(obj.data)
|
||||
bm.select_history.clear()
|
||||
return
|
||||
pg.error = f"{PDT_ERR_EDOB_MODE},{obj.mode})"
|
||||
context.window_manager.popup_menu(oops, title="Error", icon="ERROR")
|
||||
raise PDT_ObjectMode
|
||||
else:
|
||||
pg.error = f"{PDT_ERR_EDOB_MODE},{obj.mode})"
|
||||
context.window_manager.popup_menu(oops, title="Error", icon="ERROR")
|
||||
raise PDT_ObjectModeError
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
# Author: Alan Odom (Clockmender), Rune Morling (ermo) Copyright (c) 2019
|
||||
# -----------------------------------------------------------------------
|
||||
#
|
||||
# Exception Routines
|
||||
# Exceptions are used in the absence of nullable types in python
|
||||
|
||||
|
||||
class SelectionError(Exception):
|
||||
|
@ -36,7 +36,7 @@ class CommandFailure(Exception):
|
|||
pass
|
||||
|
||||
|
||||
class ObjectMode(Exception):
|
||||
class ObjectModeError(Exception):
|
||||
pass
|
||||
|
||||
|
||||
|
@ -66,3 +66,6 @@ class VerticesConnected(Exception):
|
|||
|
||||
class InvalidAngle(Exception):
|
||||
pass
|
||||
|
||||
class ShaderError(Exception):
|
||||
pass
|
||||
|
|
|
@ -107,7 +107,7 @@ from .pdt_msg_strings import (
|
|||
PDT_DES_ROTMOVAX,
|
||||
PDT_DES_TRIM,
|
||||
PDT_DES_VALIDLET,
|
||||
PDT_DES_WORPLANE
|
||||
PDT_DES_WORPLANE,
|
||||
)
|
||||
from .pdt_command import command_run
|
||||
from .pdt_functions import scale_set
|
||||
|
@ -176,7 +176,9 @@ def enumlist_collections(self, context):
|
|||
if len(pg.collection_search_string) == 0:
|
||||
object_names = [ob for ob in data_from.collections]
|
||||
else:
|
||||
object_names = [ob for ob in data_from.collections if pg.collection_search_string in ob]
|
||||
object_names = [
|
||||
ob for ob in data_from.collections if pg.collection_search_string in ob
|
||||
]
|
||||
for object_name in object_names:
|
||||
_pdt_col_items.append((object_name, object_name, ""))
|
||||
else:
|
||||
|
@ -219,32 +221,21 @@ def enumlist_materials(self, context):
|
|||
class PDTSceneProperties(PropertyGroup):
|
||||
"""Contains all PDT related properties."""
|
||||
|
||||
object_search_string : StringProperty(
|
||||
name="Search", default="", description=PDT_DES_LIBSER
|
||||
)
|
||||
collection_search_string : StringProperty(
|
||||
name="Search", default="", description=PDT_DES_LIBSER
|
||||
)
|
||||
material_search_string : StringProperty(
|
||||
name="Search", default="", description=PDT_DES_LIBSER
|
||||
)
|
||||
object_search_string: StringProperty(name="Search", default="", description=PDT_DES_LIBSER)
|
||||
collection_search_string: StringProperty(name="Search", default="", description=PDT_DES_LIBSER)
|
||||
material_search_string: StringProperty(name="Search", default="", description=PDT_DES_LIBSER)
|
||||
|
||||
cartesian_coords : FloatVectorProperty(
|
||||
name="Coords",
|
||||
default=(0.0, 0.0, 0.0),
|
||||
subtype="XYZ",
|
||||
description=PDT_DES_COORDS
|
||||
cartesian_coords: FloatVectorProperty(
|
||||
name="Coords", default=(0.0, 0.0, 0.0), subtype="XYZ", description=PDT_DES_COORDS
|
||||
)
|
||||
distance : FloatProperty(
|
||||
distance: FloatProperty(
|
||||
name="Distance", default=0.0, precision=5, description=PDT_DES_OFFDIS, unit="LENGTH"
|
||||
)
|
||||
angle : FloatProperty(
|
||||
angle: FloatProperty(
|
||||
name="Angle", min=-180, max=180, default=0.0, precision=5, description=PDT_DES_OFFANG
|
||||
)
|
||||
percent : FloatProperty(
|
||||
name="Percent", default=0.0, precision=5, description=PDT_DES_OFFPER
|
||||
)
|
||||
plane : EnumProperty(
|
||||
percent: FloatProperty(name="Percent", default=0.0, precision=5, description=PDT_DES_OFFPER)
|
||||
plane: EnumProperty(
|
||||
items=(
|
||||
("XZ", "Front(X-Z)", "Use X-Z Plane"),
|
||||
("XY", "Top(X-Y)", "Use X-Y Plane"),
|
||||
|
@ -255,7 +246,7 @@ class PDTSceneProperties(PropertyGroup):
|
|||
default="XZ",
|
||||
description=PDT_DES_WORPLANE,
|
||||
)
|
||||
select : EnumProperty(
|
||||
select: EnumProperty(
|
||||
items=(
|
||||
("REL", "Current Pos.", "Move Relative to Current Position"),
|
||||
(
|
||||
|
@ -268,13 +259,17 @@ class PDTSceneProperties(PropertyGroup):
|
|||
default="SEL",
|
||||
description=PDT_DES_MOVESEL,
|
||||
)
|
||||
operation : EnumProperty(
|
||||
operation: EnumProperty(
|
||||
items=(
|
||||
("CU", "Move Cursor", "This function will Move the Cursor"),
|
||||
("PP", "Move Pivot Point", "This function will Move the Pivot Point"),
|
||||
("MV", "Move Entities", "This function will Move selected Vertices or Objects"),
|
||||
("NV", "Add New Vertex", "This function will Add a New Vertex"),
|
||||
("EV", "Extrude Vertex/Vertices", "This function will Extrude Vertex/Vertices Only in EDIT Mode"),
|
||||
(
|
||||
"EV",
|
||||
"Extrude Vertex/Vertices",
|
||||
"This function will Extrude Vertex/Vertices Only in EDIT Mode",
|
||||
),
|
||||
("SE", "Split Edges", "This function will Split Edges Only in EDIT Mode"),
|
||||
(
|
||||
"DG",
|
||||
|
@ -291,7 +286,7 @@ class PDTSceneProperties(PropertyGroup):
|
|||
default="CU",
|
||||
description=PDT_DES_OPMODE,
|
||||
)
|
||||
taper : EnumProperty(
|
||||
taper: EnumProperty(
|
||||
items=(
|
||||
("RX-MY", "RotX-MovY", "Rotate X - Move Y"),
|
||||
("RX-MZ", "RotX-MovZ", "Rotate X - Move Z"),
|
||||
|
@ -305,27 +300,19 @@ class PDTSceneProperties(PropertyGroup):
|
|||
description=PDT_DES_ROTMOVAX,
|
||||
)
|
||||
|
||||
flip_angle : BoolProperty(
|
||||
name="Flip Angle", default=False, description=PDT_DES_FLIPANG
|
||||
)
|
||||
flip_percent : BoolProperty(
|
||||
name="Flip %", default=False, description=PDT_DES_FLIPPER
|
||||
)
|
||||
flip_angle: BoolProperty(name="Flip Angle", default=False, description=PDT_DES_FLIPANG)
|
||||
flip_percent: BoolProperty(name="Flip %", default=False, description=PDT_DES_FLIPPER)
|
||||
|
||||
extend : BoolProperty(
|
||||
name="Trim/Extend All", default=False, description=PDT_DES_TRIM
|
||||
)
|
||||
extend: BoolProperty(name="Trim/Extend All", default=False, description=PDT_DES_TRIM)
|
||||
|
||||
lib_objects : EnumProperty(
|
||||
items=enumlist_objects, name="Objects", description=PDT_DES_LIBOBS
|
||||
)
|
||||
lib_collections : EnumProperty(
|
||||
lib_objects: EnumProperty(items=enumlist_objects, name="Objects", description=PDT_DES_LIBOBS)
|
||||
lib_collections: EnumProperty(
|
||||
items=enumlist_collections, name="Collections", description=PDT_DES_LIBCOLS
|
||||
)
|
||||
lib_materials : EnumProperty(
|
||||
lib_materials: EnumProperty(
|
||||
items=enumlist_materials, name="Materials", description=PDT_DES_LIBMATS
|
||||
)
|
||||
lib_mode : EnumProperty(
|
||||
lib_mode: EnumProperty(
|
||||
items=(
|
||||
("OBJECTS", "Objects", "Use Objects"),
|
||||
("COLLECTIONS", "Collections", "Use Collections"),
|
||||
|
@ -336,14 +323,11 @@ class PDTSceneProperties(PropertyGroup):
|
|||
description=PDT_DES_LIBMODE,
|
||||
)
|
||||
|
||||
rotation_coords : FloatVectorProperty(
|
||||
name="Rotation",
|
||||
default=(0.0, 0.0, 0.0),
|
||||
subtype="XYZ",
|
||||
description="Rotation Coordinates"
|
||||
rotation_coords: FloatVectorProperty(
|
||||
name="Rotation", default=(0.0, 0.0, 0.0), subtype="XYZ", description="Rotation Coordinates"
|
||||
)
|
||||
|
||||
object_order : EnumProperty(
|
||||
object_order: EnumProperty(
|
||||
items=(
|
||||
("1,2,3,4", "1,2,3,4", "Objects 1 & 2 are First Line"),
|
||||
("1,3,2,4", "1,3,2,4", "Objects 1 & 3 are First Line"),
|
||||
|
@ -353,105 +337,86 @@ class PDTSceneProperties(PropertyGroup):
|
|||
default="1,2,3,4",
|
||||
description=PDT_DES_OBORDER,
|
||||
)
|
||||
vrotangle : FloatProperty(name="View Rotate Angle", default=10, max=180, min=-180)
|
||||
command : StringProperty(
|
||||
name="Command",
|
||||
default="CA0,0,0",
|
||||
update=command_run,
|
||||
description=PDT_DES_VALIDLET,
|
||||
vrotangle: FloatProperty(name="View Rotate Angle", default=10, max=180, min=-180)
|
||||
command: StringProperty(
|
||||
name="Command", default="CA0,0,0", update=command_run, description=PDT_DES_VALIDLET,
|
||||
)
|
||||
maths_output : FloatProperty(
|
||||
name="Maths output",
|
||||
default=0,
|
||||
description=PDT_DES_OUTPUT,
|
||||
maths_output: FloatProperty(
|
||||
name="Maths output", default=0, description=PDT_DES_OUTPUT,
|
||||
)
|
||||
error : StringProperty(name="Error", default="")
|
||||
error: StringProperty(name="Error", default="")
|
||||
|
||||
# Was pivot* -- is now pivot_*
|
||||
pivot_loc : FloatVectorProperty(
|
||||
name="Pivot Location",
|
||||
default=(0.0, 0.0, 0.0),
|
||||
subtype="XYZ",
|
||||
description=PDT_DES_PPLOC,
|
||||
pivot_loc: FloatVectorProperty(
|
||||
name="Pivot Location", default=(0.0, 0.0, 0.0), subtype="XYZ", description=PDT_DES_PPLOC,
|
||||
)
|
||||
pivot_scale : FloatVectorProperty(
|
||||
pivot_scale: FloatVectorProperty(
|
||||
name="Pivot Scale", default=(1.0, 1.0, 1.0), subtype="XYZ", description=PDT_DES_PPSCALEFAC
|
||||
)
|
||||
pivot_size : FloatProperty(
|
||||
pivot_size: FloatProperty(
|
||||
name="Pivot Factor", min=0.4, max=10, default=2, precision=1, description=PDT_DES_PPSIZE
|
||||
)
|
||||
pivot_width : IntProperty(
|
||||
name="Width", min=1, max=5, default=2, description=PDT_DES_PPWIDTH
|
||||
)
|
||||
pivot_width: IntProperty(name="Width", min=1, max=5, default=2, description=PDT_DES_PPWIDTH)
|
||||
# FIXME: might as well become pivot_angle
|
||||
pivot_ang : FloatProperty(name="Pivot Angle", min=-180, max=180, default=0.0)
|
||||
pivot_ang: FloatProperty(name="Pivot Angle", min=-180, max=180, default=0.0)
|
||||
# FIXME: pivot_dist for consistency?
|
||||
pivot_dis : FloatProperty(name="Pivot Dist",
|
||||
default=0.0,
|
||||
min = 0,
|
||||
update=scale_set,
|
||||
description=PDT_DES_PIVOTDIS,
|
||||
pivot_dis: FloatProperty(
|
||||
name="Pivot Dist", default=0.0, min=0, update=scale_set, description=PDT_DES_PIVOTDIS,
|
||||
)
|
||||
pivot_alpha : FloatProperty(
|
||||
name="Alpha",
|
||||
min=0.2,
|
||||
max=1,
|
||||
default=0.6,
|
||||
precision=1,
|
||||
description=PDT_DES_PPTRANS,
|
||||
pivot_alpha: FloatProperty(
|
||||
name="Alpha", min=0.2, max=1, default=0.6, precision=1, description=PDT_DES_PPTRANS,
|
||||
)
|
||||
pivot_show : BoolProperty()
|
||||
pivot_show: BoolProperty()
|
||||
|
||||
# Was filletrad
|
||||
fillet_radius : FloatProperty(
|
||||
fillet_radius: FloatProperty(
|
||||
name="Fillet Radius", min=0.0, default=1.0, description=PDT_DES_FILLETRAD
|
||||
)
|
||||
# Was filletnum
|
||||
fillet_segments : IntProperty(
|
||||
fillet_segments: IntProperty(
|
||||
name="Fillet Segments", min=1, default=4, description=PDT_DES_FILLETSEG
|
||||
)
|
||||
# Was filletpro
|
||||
fillet_profile : FloatProperty(
|
||||
fillet_profile: FloatProperty(
|
||||
name="Fillet Profile", min=0.0, max=1.0, default=0.5, description=PDT_DES_FILLETPROF
|
||||
)
|
||||
# Was filletbool
|
||||
fillet_vertices_only : BoolProperty(
|
||||
name="Fillet Vertices Only",
|
||||
default=True,
|
||||
description=PDT_DES_FILLETVERTS,
|
||||
fillet_vertices_only: BoolProperty(
|
||||
name="Fillet Vertices Only", default=True, description=PDT_DES_FILLETVERTS,
|
||||
)
|
||||
fillet_intersect : BoolProperty(
|
||||
name="Intersect",
|
||||
default=False,
|
||||
description=PDT_DES_FILLINT,
|
||||
fillet_intersect: BoolProperty(
|
||||
name="Intersect", default=False, description=PDT_DES_FILLINT,
|
||||
)
|
||||
|
||||
|
||||
class PDTPreferences(AddonPreferences):
|
||||
# This must match the addon name, use '__package__' when defining this in a submodule of a python package.
|
||||
# This must match the addon name, use '__package__'
|
||||
# when defining this in a submodule of a python package.
|
||||
|
||||
bl_idname = __name__
|
||||
|
||||
pdt_library_path : StringProperty(
|
||||
name="Parts Library", default="", description="Parts Library File",
|
||||
maxlen=1024, subtype='FILE_PATH'
|
||||
pdt_library_path: StringProperty(
|
||||
name="Parts Library",
|
||||
default="",
|
||||
description="Parts Library File",
|
||||
maxlen=1024,
|
||||
subtype="FILE_PATH",
|
||||
)
|
||||
|
||||
debug : BoolProperty(
|
||||
name="Enable console debug output from PDT scripts", default=False,
|
||||
description="NOTE: Does not enable debugging globally in Blender (only in PDT scripts)"
|
||||
debug: BoolProperty(
|
||||
name="Enable console debug output from PDT scripts",
|
||||
default=False,
|
||||
description="NOTE: Does not enable debugging globally in Blender (only in PDT scripts)",
|
||||
)
|
||||
|
||||
pdt_ui_width : IntProperty(
|
||||
name='UI Width Cut-off',
|
||||
pdt_ui_width: IntProperty(
|
||||
name="UI Width Cut-off",
|
||||
default=350,
|
||||
description="Cutoff width for shrinking items per line in menus"
|
||||
description="Cutoff width for shrinking items per line in menus",
|
||||
)
|
||||
|
||||
pdt_input_round : IntProperty(
|
||||
name='Input Rounding',
|
||||
default=5,
|
||||
description='Rounding Factor for Inputs'
|
||||
pdt_input_round: IntProperty(
|
||||
name="Input Rounding", default=5, description="Rounding Factor for Inputs"
|
||||
)
|
||||
|
||||
def draw(self, context):
|
||||
|
@ -510,12 +475,12 @@ classes = (
|
|||
pdt_pivot_point.PDT_OT_PivotWrite,
|
||||
pdt_pivot_point.PDT_OT_PivotRead,
|
||||
pdt_view.PDT_OT_ViewRot,
|
||||
pdt_view.PDT_OT_vRotL,
|
||||
pdt_view.PDT_OT_vRotR,
|
||||
pdt_view.PDT_OT_vRotU,
|
||||
pdt_view.PDT_OT_vRotD,
|
||||
pdt_view.PDT_OT_vRoll,
|
||||
pdt_view.PDT_OT_viso,
|
||||
pdt_view.PDT_OT_ViewRotL,
|
||||
pdt_view.PDT_OT_ViewRotR,
|
||||
pdt_view.PDT_OT_ViewRotU,
|
||||
pdt_view.PDT_OT_ViewRotD,
|
||||
pdt_view.PDT_OT_ViewRoll,
|
||||
pdt_view.PDT_OT_ViewIso,
|
||||
pdt_view.PDT_OT_Reset3DView,
|
||||
pdt_xall.PDT_OT_IntersectAllEdges,
|
||||
)
|
||||
|
@ -534,10 +499,10 @@ def register():
|
|||
|
||||
# OpenGL flag
|
||||
#
|
||||
wm = WindowManager
|
||||
window_manager = WindowManager
|
||||
# Register Internal OpenGL Property
|
||||
#
|
||||
wm.pdt_run_opengl = BoolProperty(default=False)
|
||||
window_manager.pdt_run_opengl = BoolProperty(default=False)
|
||||
|
||||
Scene.pdt_pg = PointerProperty(type=PDTSceneProperties)
|
||||
|
||||
|
@ -554,10 +519,10 @@ def unregister():
|
|||
pdt_pivot_point.PDT_OT_ModalDrawOperator.handle_remove(
|
||||
pdt_pivot_point.PDT_OT_ModalDrawOperator, bpy.context
|
||||
)
|
||||
wm = bpy.context.window_manager
|
||||
p = "pdt_run_opengl"
|
||||
if p in wm:
|
||||
del wm[p]
|
||||
window_manager = bpy.context.window_manager
|
||||
pdt_wm = "pdt_run_opengl"
|
||||
if pdt_wm in window_manager:
|
||||
del window_manager[pdt_wm]
|
||||
|
||||
for cls in reversed(classes):
|
||||
unregister_class(cls)
|
||||
|
|
|
@ -34,6 +34,7 @@ from .pdt_msg_strings import (
|
|||
)
|
||||
from .pdt_functions import debug, oops
|
||||
|
||||
|
||||
def add_line_to_bisection(context):
|
||||
"""Computes Bisector of 2 Co-Planar Edges.
|
||||
|
||||
|
@ -47,8 +48,8 @@ def add_line_to_bisection(context):
|
|||
obj = context.object
|
||||
if all([bool(obj), obj.type == "MESH", obj.mode == "EDIT"]):
|
||||
pg = context.scene.pdt_pg
|
||||
me = obj.data
|
||||
bm = bmesh.from_edit_mesh(me)
|
||||
obj_data = obj.data
|
||||
bm = bmesh.from_edit_mesh(obj_data)
|
||||
|
||||
bm.verts.ensure_lookup_table()
|
||||
bm.edges.ensure_lookup_table()
|
||||
|
@ -60,39 +61,47 @@ def add_line_to_bisection(context):
|
|||
context.window_manager.popup_menu(oops, title="Error", icon="ERROR")
|
||||
return
|
||||
|
||||
[[v1, v2], [v3, v4]] = [[v.co for v in e.verts] for e in edges]
|
||||
debug(f"vectors found:\n {v1}\n {v2}\n {v3}\n {v4}")
|
||||
[[vector_a, vector_b], [vector_c, vector_d]] = [[v.co for v in e.verts] for e in edges]
|
||||
debug(f"vectors found:\n {vector_a}\n {vector_b}\n {vector_c}\n {vector_d}")
|
||||
|
||||
dist1 = (v1 - v2).length
|
||||
dist2 = (v3 - v4).length
|
||||
dist1 = (vector_a - vector_b).length
|
||||
dist2 = (vector_c - vector_d).length
|
||||
bdist = min([dist1, dist2])
|
||||
edge1 = (v1, v2)
|
||||
edge2 = (v3, v4)
|
||||
edge1 = (vector_a, vector_b)
|
||||
edge2 = (vector_c, vector_d)
|
||||
|
||||
if not cm.test_coplanar(edge1, edge2):
|
||||
pg.error = PDT_ERR_NCEDGES
|
||||
context.window_manager.popup_menu(oops, title="Error", icon="ERROR")
|
||||
return
|
||||
|
||||
# get pt and pick farthest vertex from (projected) intersections
|
||||
pt = cm.get_intersection(edge1, edge2)
|
||||
far1 = v2 if (v1 - pt).length < (v2 - pt).length else v1
|
||||
far2 = v4 if (v3 - pt).length < (v4 - pt).length else v3
|
||||
# get intersect_point and pick farthest vertex from (projected) intersections
|
||||
intersect_point = cm.get_intersection(edge1, edge2)
|
||||
far1 = (
|
||||
vector_b
|
||||
if (vector_a - intersect_point).length < (vector_b - intersect_point).length
|
||||
else vector_a
|
||||
)
|
||||
far2 = (
|
||||
vector_d
|
||||
if (vector_c - intersect_point).length < (vector_d - intersect_point).length
|
||||
else vector_c
|
||||
)
|
||||
|
||||
dex1 = far1 - pt
|
||||
dex2 = far2 - pt
|
||||
dex1 = far1 - intersect_point
|
||||
dex2 = far2 - intersect_point
|
||||
dex1 = dex1 * (bdist / dex1.length)
|
||||
dex2 = dex2 * (bdist / dex2.length)
|
||||
pt2 = pt + (dex1).lerp(dex2, 0.5)
|
||||
pt3 = pt2.lerp(pt, 2.0)
|
||||
intersect_point2 = intersect_point + (dex1).lerp(dex2, 0.5)
|
||||
intersect_point3 = intersect_point2.lerp(intersect_point, 2.0)
|
||||
|
||||
vec1 = bm.verts.new(pt2)
|
||||
vec2 = bm.verts.new(pt)
|
||||
vec3 = bm.verts.new(pt3)
|
||||
vec1 = bm.verts.new(intersect_point2)
|
||||
vec2 = bm.verts.new(intersect_point)
|
||||
vec3 = bm.verts.new(intersect_point3)
|
||||
bm.edges.new((vec1, vec2))
|
||||
bm.edges.new((vec2, vec3))
|
||||
bmesh.ops.remove_doubles(bm, verts=bm.verts, dist=0.0001)
|
||||
bmesh.update_edit_mesh(me)
|
||||
bmesh.update_edit_mesh(obj_data)
|
||||
else:
|
||||
pg.error = f"{PDT_ERR_EDOB_MODE},{obj.mode})"
|
||||
context.window_manager.popup_menu(oops, title="Error", icon="ERROR")
|
||||
|
@ -109,10 +118,10 @@ class PDT_OT_LineOnBisection(bpy.types.Operator):
|
|||
@classmethod
|
||||
def poll(cls, context):
|
||||
"""Only allow operation on a mesh object in EDIT mode."""
|
||||
ob = context.active_object
|
||||
if ob is None:
|
||||
obj = context.active_object
|
||||
if obj is None:
|
||||
return False
|
||||
return all([ob is not None, ob.type == "MESH", ob.mode == "EDIT"])
|
||||
return all([obj is not None, obj.type == "MESH", obj.mode == "EDIT"])
|
||||
|
||||
def execute(self, context):
|
||||
"""Computes Bisector of 2 Co-Planar Edges.
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
# of the License, or (at your ointersect_pointion) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
|
@ -28,19 +28,20 @@ from mathutils import Vector
|
|||
from mathutils.geometry import intersect_line_line, intersect_point_line
|
||||
from .pdt_functions import debug
|
||||
|
||||
def point_on_edge(p, edge):
|
||||
|
||||
def point_on_edge(point, edge):
|
||||
"""Find Point on Edge.
|
||||
|
||||
Args:
|
||||
p: vector
|
||||
point: vector
|
||||
edge: tuple containing 2 vectors.
|
||||
|
||||
Returns:
|
||||
True if point p happens to lie on the edge, False otherwise.
|
||||
"""
|
||||
|
||||
pt, _percent = intersect_point_line(p, *edge)
|
||||
on_line = (pt - p).length < 1.0e-5
|
||||
intersect_point, _percent = intersect_point_line(point, *edge)
|
||||
on_line = (intersect_point - point).length < 1.0e-5
|
||||
return on_line and (0.0 <= _percent <= 1.0)
|
||||
|
||||
|
||||
|
@ -56,8 +57,10 @@ def line_from_edge_intersect(edge1, edge2):
|
|||
Output of intersect_line_line.
|
||||
"""
|
||||
|
||||
[p1, p2], [p3, p4] = edge1, edge2
|
||||
return intersect_line_line(p1, p2, p3, p4)
|
||||
[intersect_point1, intersect_point2], [intersect_point3, intersect_point4] = edge1, edge2
|
||||
return intersect_line_line(
|
||||
intersect_point1, intersect_point2, intersect_point3, intersect_point4
|
||||
)
|
||||
|
||||
|
||||
def get_intersection(edge1, edge2):
|
||||
|
@ -73,6 +76,7 @@ def get_intersection(edge1, edge2):
|
|||
line = line_from_edge_intersect(edge1, edge2)
|
||||
if line:
|
||||
return (line[0] + line[1]) / 2
|
||||
return None
|
||||
|
||||
|
||||
def test_coplanar(edge1, edge2):
|
||||
|
@ -92,50 +96,53 @@ def test_coplanar(edge1, edge2):
|
|||
line = line_from_edge_intersect(edge1, edge2)
|
||||
if line:
|
||||
return (line[0] - line[1]).length < 1.0e-5
|
||||
return None
|
||||
|
||||
|
||||
def closest_idx(pt, e):
|
||||
def closest_idx(intersect_point, edge):
|
||||
"""Get Closest Vertex to input point.
|
||||
|
||||
If both points in e are equally far from pt, then v1 is returned.
|
||||
If both points in e are equally far from intersect_point, then v1 is returned.
|
||||
|
||||
Args:
|
||||
pt: vector
|
||||
e: bmesh edge
|
||||
intersect_point: vector
|
||||
edge: bmesh edge
|
||||
|
||||
Returns:
|
||||
Index of vertex closest to pt.
|
||||
Index of vertex closest to intersect_point.
|
||||
"""
|
||||
|
||||
if isinstance(e, bmesh.types.BMEdge):
|
||||
ev = e.verts
|
||||
v1 = ev[0].co
|
||||
v2 = ev[1].co
|
||||
distance_test = (v1 - pt).length <= (v2 - pt).length
|
||||
return ev[0].index if distance_test else ev[1].index
|
||||
if isinstance(edge, bmesh.types.BMEdge):
|
||||
edge_verts = edge.verts
|
||||
vector_a = edge_verts[0].co
|
||||
vector_b = edge_verts[1].co
|
||||
distance_test = (vector_a - intersect_point).length <= (vector_b - intersect_point).length
|
||||
return edge_verts[0].index if distance_test else edge_verts[1].index
|
||||
|
||||
debug(f"Received {e}, check expected input in docstring ")
|
||||
debug(f"Received {edge}, check expected input in docstring ")
|
||||
return None
|
||||
|
||||
|
||||
def closest_vector(pt, e):
|
||||
def closest_vector(intersect_point, edge):
|
||||
"""Return Closest Vector to input Point.
|
||||
|
||||
If both points in e are equally far from pt, then v1 is returned.
|
||||
If both points in e are equally far from intersect_point, then v1 is returned.
|
||||
|
||||
Args:
|
||||
pt: vector
|
||||
e: tuple containing 2 vectors
|
||||
intersect_point: vector
|
||||
edge: tuple containing 2 vectors
|
||||
|
||||
Returns:
|
||||
Vector closest to pt.
|
||||
Vector closest to intersect_point.
|
||||
"""
|
||||
|
||||
if isinstance(e, tuple) and all([isinstance(co, Vector) for co in e]):
|
||||
v1, v2 = e
|
||||
distance_test = (v1 - pt).length <= (v2 - pt).length
|
||||
return v1 if distance_test else v2
|
||||
if isinstance(edge, tuple) and all([isinstance(co, Vector) for co in edge]):
|
||||
vector_a, vector_b = edge
|
||||
distance_test = (vector_a - intersect_point).length <= (vector_b - intersect_point).length
|
||||
return vector_a if distance_test else vector_b
|
||||
|
||||
debug(f"Received {e}, check expected input in docstring ")
|
||||
debug(f"Received {edge}, check expected input in docstring ")
|
||||
return None
|
||||
|
||||
|
||||
def coords_tuple_from_edge_idx(bm, idx):
|
||||
|
@ -159,8 +166,8 @@ def vertex_indices_from_edges_tuple(bm, edge_tuple):
|
|||
The vertex indices of edge_tuple.
|
||||
"""
|
||||
|
||||
def k(v, w):
|
||||
return bm.edges[edge_tuple[v]].verts[w].index
|
||||
def k(ind_v, ind_w):
|
||||
return bm.edges[edge_tuple[ind_v]].verts[ind_w].index
|
||||
|
||||
return [k(i >> 1, i % 2) for i in range(4)]
|
||||
|
||||
|
@ -182,29 +189,38 @@ def get_vert_indices_from_bmedges(edges):
|
|||
return temp_edges
|
||||
|
||||
|
||||
def num_edges_point_lies_on(pt, edges):
|
||||
def num_edges_point_lies_on(intersect_point, edges):
|
||||
"""Returns the number of edges that a point lies on."""
|
||||
res = [point_on_edge(pt, edge) for edge in [edges[:2], edges[2:]]]
|
||||
res = [point_on_edge(intersect_point, edge) for edge in [edges[:2], edges[2:]]]
|
||||
return len([i for i in res if i])
|
||||
|
||||
|
||||
def find_intersecting_edges(bm, pt, idx1, idx2):
|
||||
def find_intersecting_edges(bm, intersect_point, idx1, idx2):
|
||||
"""Find Intercecting Edges.
|
||||
|
||||
Args:
|
||||
pt: Vector
|
||||
intersect_point: Vector
|
||||
idx1, ix2: edge indices
|
||||
|
||||
Returns:
|
||||
The list of edge indices where pt is on those edges.
|
||||
The list of edge indices where intersect_point is on those edges.
|
||||
"""
|
||||
if not pt:
|
||||
if not intersect_point:
|
||||
return []
|
||||
idxs = [idx1, idx2]
|
||||
edges = [coords_tuple_from_edge_idx(bm, idx) for idx in idxs]
|
||||
return [idx for edge, idx in zip(edges, idxs) if point_on_edge(pt, edge)]
|
||||
return [idx for edge, idx in zip(edges, idxs) if point_on_edge(intersect_point, edge)]
|
||||
|
||||
|
||||
def vert_idxs_from_edge_idx(bm, idx):
|
||||
"""Find Vertex Indices form Edge Indices.
|
||||
|
||||
Args:
|
||||
Object Bmesh as bm
|
||||
Selection Index as idx
|
||||
|
||||
Returns:
|
||||
Vertex Indices of Edge.
|
||||
"""
|
||||
edge = bm.edges[idx]
|
||||
return edge.verts[0].index, edge.verts[1].index
|
||||
|
|
|
@ -40,7 +40,7 @@ from .pdt_command_functions import (
|
|||
origin_to_cursor,
|
||||
taper,
|
||||
placement_normal,
|
||||
placement_centre,
|
||||
placement_arc_centre,
|
||||
placement_intersect,
|
||||
)
|
||||
from .pdt_msg_strings import (
|
||||
|
@ -59,6 +59,8 @@ from .pdt_msg_strings import (
|
|||
PDT_ERR_BADMATHS,
|
||||
PDT_OBJ_MODE_ERROR,
|
||||
PDT_ERR_SEL_4_VERTS,
|
||||
PDT_ERR_INT_LINES,
|
||||
PDT_LAB_PLANE,
|
||||
)
|
||||
from .pdt_bix import add_line_to_bisection
|
||||
from .pdt_etof import extend_vertex
|
||||
|
@ -68,8 +70,9 @@ 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
|
||||
PDT_ObjectModeError = pdt_exception.ObjectModeError
|
||||
PDT_MathsError = pdt_exception.MathsError
|
||||
PDT_IntersectionError = pdt_exception.IntersectionError
|
||||
|
||||
|
||||
class PDT_OT_CommandReRun(Operator):
|
||||
|
@ -149,7 +152,7 @@ def command_run(self, context):
|
|||
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
|
||||
raise PDT_ObjectModeError
|
||||
|
||||
# Special Cases of Command.
|
||||
if command == "?" or command.lower() == "help":
|
||||
|
@ -157,52 +160,47 @@ def command_run(self, context):
|
|||
context.window_manager.popup_menu(pdt_help, title="PDT Command Line Help", icon="INFO")
|
||||
# fmt: on
|
||||
return
|
||||
elif command == "":
|
||||
if command == "":
|
||||
return
|
||||
elif command.upper() == "J2V":
|
||||
if command.upper() == "J2V":
|
||||
join_two_vertices(context)
|
||||
return
|
||||
elif command.upper() == "AD2":
|
||||
if command.upper() == "AD2":
|
||||
set_angle_distance_two(context)
|
||||
return
|
||||
elif command.upper() == "AD3":
|
||||
if command.upper() == "AD3":
|
||||
set_angle_distance_three(context)
|
||||
return
|
||||
elif command.upper() == "OTC":
|
||||
if command.upper() == "OTC":
|
||||
origin_to_cursor(context)
|
||||
return
|
||||
elif command.upper() == "TAP":
|
||||
if command.upper() == "TAP":
|
||||
taper(context)
|
||||
return
|
||||
elif command.upper() == "BIS":
|
||||
if command.upper() == "BIS":
|
||||
add_line_to_bisection(context)
|
||||
return
|
||||
elif command.upper() == "ETF":
|
||||
if command.upper() == "ETF":
|
||||
extend_vertex(context)
|
||||
return
|
||||
elif command.upper() == "INTALL":
|
||||
if command.upper() == "INTALL":
|
||||
intersect_all(context)
|
||||
return
|
||||
elif command.upper()[1:] == "NML":
|
||||
if command.upper()[1:] == "NML":
|
||||
placement_normal(context, command.upper()[0])
|
||||
return
|
||||
elif command.upper()[1:] == "CEN":
|
||||
placement_centre(context, command.upper()[0])
|
||||
if command.upper()[1:] == "CEN":
|
||||
placement_arc_centre(context, command.upper()[0])
|
||||
return
|
||||
elif command.upper()[1:] == "INT":
|
||||
if command.upper()[1:] == "INT":
|
||||
placement_intersect(context, command.upper()[0])
|
||||
return
|
||||
|
||||
# Check First Letter
|
||||
# Check Command Length
|
||||
if len(command) < 3:
|
||||
pg.error = PDT_ERR_CHARS_NUM
|
||||
context.window_manager.popup_menu(oops, title="Error", icon="ERROR")
|
||||
return
|
||||
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 First Letter
|
||||
operation = command[0].upper()
|
||||
|
@ -214,11 +212,11 @@ def command_run(self, context):
|
|||
# Check Second Letter.
|
||||
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"})
|
||||
):
|
||||
(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
|
||||
|
@ -249,7 +247,7 @@ def command_run(self, context):
|
|||
|
||||
# ------------------------
|
||||
# Move Vertices or Objects
|
||||
elif operation == "G":
|
||||
if operation == "G":
|
||||
try:
|
||||
move_entities(context, pg, operation, mode, obj, bm, verts, values)
|
||||
except PDT_CommandFailure:
|
||||
|
@ -257,7 +255,7 @@ def command_run(self, context):
|
|||
|
||||
# --------------
|
||||
# Add New Vertex
|
||||
elif operation == "N":
|
||||
if operation == "N":
|
||||
try:
|
||||
add_new_vertex(context, pg, operation, mode, obj, bm, verts, values)
|
||||
except PDT_CommandFailure:
|
||||
|
@ -265,7 +263,7 @@ def command_run(self, context):
|
|||
|
||||
# -----------
|
||||
# Split Edges
|
||||
elif operation == "S":
|
||||
if operation == "S":
|
||||
try:
|
||||
split_edges(context, pg, operation, mode, obj, obj_loc, bm, values)
|
||||
except PDT_CommandFailure:
|
||||
|
@ -274,7 +272,7 @@ def command_run(self, context):
|
|||
|
||||
# ----------------
|
||||
# Extrude Vertices
|
||||
elif operation == "V":
|
||||
if operation == "V":
|
||||
try:
|
||||
extrude_vertices(context, pg, operation, mode, obj, obj_loc, bm, verts, values)
|
||||
except PDT_CommandFailure:
|
||||
|
@ -282,7 +280,7 @@ def command_run(self, context):
|
|||
|
||||
# ----------------
|
||||
# Extrude Geometry
|
||||
elif operation == "E":
|
||||
if operation == "E":
|
||||
try:
|
||||
extrude_geometry(context, pg, operation, mode, obj, bm, values)
|
||||
except PDT_CommandFailure:
|
||||
|
@ -290,7 +288,7 @@ def command_run(self, context):
|
|||
|
||||
# ------------------
|
||||
# Duplicate Geometry
|
||||
elif operation == "D":
|
||||
if operation == "D":
|
||||
try:
|
||||
duplicate_geometry(context, pg, operation, mode, obj, bm, values)
|
||||
except PDT_CommandFailure:
|
||||
|
@ -298,18 +296,12 @@ def command_run(self, context):
|
|||
|
||||
# ---------------
|
||||
# Fillet Geometry
|
||||
elif operation == "F":
|
||||
if 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."""
|
||||
|
@ -392,12 +384,19 @@ def command_maths(context, mode, pg, expression, output_target):
|
|||
elif output_target == "p":
|
||||
pg.percent = round(maths_result, val_round)
|
||||
else:
|
||||
# Mst be "o"
|
||||
# Must be "o"
|
||||
pg.maths_output = round(maths_result, val_round)
|
||||
return
|
||||
|
||||
|
||||
def command_parse(context):
|
||||
"""Parse Command Input.
|
||||
|
||||
Args:
|
||||
context: Blender bpy.context instance.
|
||||
|
||||
Returns:
|
||||
pg, values_out, obj, obj_loc, bm, verts.
|
||||
"""
|
||||
scene = context.scene
|
||||
pg = scene.pdt_pg
|
||||
command = pg.command.strip()
|
||||
|
@ -418,7 +417,7 @@ def command_parse(context):
|
|||
val_round = context.preferences.addons[__package__].preferences.pdt_input_round
|
||||
values_out = [str(round(float(v), val_round)) for v in values]
|
||||
|
||||
bm, good = obj_check(context, obj, scene, operation)
|
||||
bm, good = obj_check(obj, scene, operation)
|
||||
if good:
|
||||
obj_loc = obj.matrix_world.decompose()[0]
|
||||
else:
|
||||
|
@ -426,12 +425,11 @@ def command_parse(context):
|
|||
|
||||
if mode_s == 'SEL' and bm is not None and mode not in {"a"}:
|
||||
if len(bm.select_history) == 0:
|
||||
if len([v for v in bm.verts if v.select]) == 0:
|
||||
verts = [v for v in bm.verts if v.select]
|
||||
if len(verts) == 0:
|
||||
pg.error = PDT_ERR_NO_SEL_GEOM
|
||||
context.window_manager.popup_menu(oops, title="Error", icon="ERROR")
|
||||
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":
|
||||
|
@ -446,6 +444,16 @@ def command_parse(context):
|
|||
|
||||
|
||||
def move_cursor_pivot(context, pg, operation, mode, obj, verts, values):
|
||||
"""Moves Cursor & Pivot Point.
|
||||
|
||||
Args:
|
||||
context: Blender bpy.context instance.
|
||||
pg, operation, mode, obj, verts, values
|
||||
|
||||
Returns:
|
||||
Nothing.
|
||||
"""
|
||||
|
||||
# Absolute/Global Coordinates, or Delta/Relative Coordinates
|
||||
if mode in {"a", "d"}:
|
||||
try:
|
||||
|
@ -466,7 +474,7 @@ def move_cursor_pivot(context, pg, operation, mode, obj, verts, values):
|
|||
except:
|
||||
raise PDT_InvalidVector
|
||||
|
||||
if vector_delta == None:
|
||||
if vector_delta is None:
|
||||
raise PDT_InvalidVector
|
||||
|
||||
scene = context.scene
|
||||
|
@ -507,10 +515,19 @@ def move_cursor_pivot(context, pg, operation, mode, obj, verts, values):
|
|||
scene.cursor.location = vector_delta
|
||||
else:
|
||||
pg.pivot_loc = vector_delta
|
||||
return
|
||||
|
||||
|
||||
def move_entities(context, pg, operation, mode, obj, bm, verts, values):
|
||||
"""Moves Entities.
|
||||
|
||||
Args:
|
||||
context: Blender bpy.context instance.
|
||||
pg, operation, mode, obj, bm, verts, values
|
||||
|
||||
Returns:
|
||||
Nothing.
|
||||
"""
|
||||
|
||||
obj_loc = obj.matrix_world.decompose()[0]
|
||||
|
||||
# Absolute/Global Coordinates
|
||||
|
@ -562,10 +579,19 @@ def move_entities(context, pg, operation, mode, obj, bm, verts, values):
|
|||
if obj.mode == 'EDIT':
|
||||
bmesh.update_edit_mesh(obj.data)
|
||||
bm.select_history.clear()
|
||||
return
|
||||
|
||||
|
||||
def add_new_vertex(context, pg, operation, mode, obj, bm, verts, values):
|
||||
"""Add New Vertex.
|
||||
|
||||
Args:
|
||||
context: Blender bpy.context instance.
|
||||
pg, operation, mode, obj, bm, verts, values
|
||||
|
||||
Returns:
|
||||
Nothing.
|
||||
"""
|
||||
|
||||
obj_loc = obj.matrix_world.decompose()[0]
|
||||
|
||||
if not obj.mode == "EDIT":
|
||||
|
@ -606,10 +632,19 @@ def add_new_vertex(context, pg, operation, mode, obj, bm, verts, values):
|
|||
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):
|
||||
"""Split Edges.
|
||||
|
||||
Args:
|
||||
context: Blender bpy.context instance.
|
||||
pg, operation, mode, obj, obj_loc, bm, verts, values
|
||||
|
||||
Returns:
|
||||
Nothing.
|
||||
"""
|
||||
|
||||
if not obj.mode == "EDIT":
|
||||
pg.error = PDT_ERR_SPLITEDIT
|
||||
context.window_manager.popup_menu(oops, title="Error", icon="ERROR")
|
||||
|
@ -694,10 +729,19 @@ def split_edges(context, pg, operation, mode, obj, obj_loc, bm, values):
|
|||
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):
|
||||
"""Extrude Vertices.
|
||||
|
||||
Args:
|
||||
context: Blender bpy.context instance.
|
||||
pg, operation, mode, obj, onj_loc, bm, verts, values
|
||||
|
||||
Returns:
|
||||
Nothing.
|
||||
"""
|
||||
|
||||
if not obj.mode == "EDIT":
|
||||
pg.error = PDT_ERR_EXTEDIT
|
||||
context.window_manager.popup_menu(oops, title="Error", icon="ERROR")
|
||||
|
@ -760,10 +804,19 @@ def extrude_vertices(context, pg, operation, mode, obj, obj_loc, bm, verts, valu
|
|||
|
||||
bmesh.update_edit_mesh(obj.data)
|
||||
bm.select_history.clear()
|
||||
return
|
||||
|
||||
|
||||
def extrude_geometry(context, pg, operation, mode, obj, bm, values):
|
||||
"""Extrude Geometry.
|
||||
|
||||
Args:
|
||||
context: Blender bpy.context instance.
|
||||
pg, operation, mode, obj, bm, verts, values
|
||||
|
||||
Returns:
|
||||
Nothing.
|
||||
"""
|
||||
|
||||
if not obj.mode == "EDIT":
|
||||
pg.error = PDT_ERR_EXTEDIT
|
||||
context.window_manager.popup_menu(oops, title="Error", icon="ERROR")
|
||||
|
@ -799,9 +852,19 @@ def extrude_geometry(context, pg, operation, mode, obj, bm, values):
|
|||
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):
|
||||
"""Duplicate Geometry.
|
||||
|
||||
Args:
|
||||
context: Blender bpy.context instance.
|
||||
pg, operation, mode, obj, bm, verts, values
|
||||
|
||||
Returns:
|
||||
Nothing.
|
||||
"""
|
||||
|
||||
if not obj.mode == "EDIT":
|
||||
pg.error = PDT_ERR_DUPEDIT
|
||||
context.window_manager.popup_menu(oops, title="Error", icon="ERROR")
|
||||
|
@ -837,10 +900,19 @@ def duplicate_geometry(context, pg, operation, mode, obj, bm, values):
|
|||
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):
|
||||
"""Fillet Geometry.
|
||||
|
||||
Args:
|
||||
context: Blender bpy.context instance.
|
||||
pg, operation, mode, obj, bm, verts, values
|
||||
|
||||
Returns:
|
||||
Nothing.
|
||||
"""
|
||||
|
||||
if not obj.mode == "EDIT":
|
||||
pg.error = PDT_ERR_FILEDIT
|
||||
context.window_manager.popup_menu(oops, title="Error", icon="ERROR")
|
||||
|
@ -870,14 +942,14 @@ def fillet_geometry(context, pg, mode, obj, bm, verts, values):
|
|||
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
|
||||
)
|
||||
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)
|
||||
pg.error = f"{PDT_ERR_INT_LINES} {plane} {PDT_LAB_PLANE}"
|
||||
context.window_manager.popup_menu(oops, title="Error", icon="ERROR")
|
||||
raise PDT_IntersectionError
|
||||
if (v_active.co - vector_delta).length < (v_other.co - vector_delta).length:
|
||||
v_active.co = vector_delta
|
||||
|
@ -904,4 +976,3 @@ def fillet_geometry(context, pg, mode, obj, bm, verts, values):
|
|||
profile=_profile,
|
||||
vertex_only=vert_bool
|
||||
)
|
||||
return
|
||||
|
|
|
@ -21,42 +21,14 @@
|
|||
# Author: Alan Odom (Clockmender), Rune Morling (ermo) Copyright (c) 2019
|
||||
# -----------------------------------------------------------------------
|
||||
#
|
||||
import bmesh
|
||||
import bpy
|
||||
import numpy as np
|
||||
from bpy.types import Operator
|
||||
from mathutils import Vector
|
||||
from mathutils.geometry import intersect_point_line
|
||||
from math import sin, cos, tan, pi, sqrt
|
||||
from .pdt_functions import (
|
||||
check_selection,
|
||||
set_axis,
|
||||
view_coords,
|
||||
view_coords_i,
|
||||
intersection,
|
||||
)
|
||||
from .pdt_msg_strings import (
|
||||
PDT_ERR_EDOB_MODE,
|
||||
PDT_ERR_INT_LINES,
|
||||
PDT_ERR_INT_NO_ALL,
|
||||
PDT_ERR_NON_VALID,
|
||||
PDT_ERR_NO_ACT_OBJ,
|
||||
PDT_ERR_SEL_2_OBJS,
|
||||
PDT_ERR_SEL_2_VERTIO,
|
||||
PDT_ERR_SEL_3_OBJS,
|
||||
PDT_ERR_SEL_3_VERTIO,
|
||||
PDT_ERR_SEL_4_OBJS,
|
||||
PDT_ERR_SEL_4_VERTS,
|
||||
PDT_ERR_TAPER_ANG,
|
||||
PDT_ERR_TAPER_SEL,
|
||||
PDT_ERR_VERT_MODE,
|
||||
PDT_INF_OBJ_MOVED,
|
||||
PDT_LAB_ABS,
|
||||
PDT_LAB_DEL,
|
||||
PDT_LAB_DIR,
|
||||
PDT_LAB_INTERSECT,
|
||||
PDT_LAB_PERCENT,
|
||||
PDT_LAB_PLANE,
|
||||
)
|
||||
|
||||
|
||||
|
@ -587,21 +559,21 @@ class PDT_OT_Fillet(Operator):
|
|||
val_round = context.preferences.addons[__package__].preferences.pdt_input_round
|
||||
if pg.fillet_intersect:
|
||||
pg.command = (
|
||||
f"fi{str(round(pg.fillet_radius, val_round))}"
|
||||
f",{str(round(pg.fillet_segments, val_round))}"
|
||||
f",{str(round(pg.fillet_profile, val_round))}"
|
||||
f"fi{str(round(pg.fillet_radius, val_round))}"
|
||||
f",{str(round(pg.fillet_segments, val_round))}"
|
||||
f",{str(round(pg.fillet_profile, val_round))}"
|
||||
)
|
||||
elif pg.fillet_vertices_only:
|
||||
pg.command = (
|
||||
f"fv{str(round(pg.fillet_radius, val_round))}"
|
||||
f",{str(round(pg.fillet_segments, val_round))}"
|
||||
f",{str(round(pg.fillet_profile, val_round))}"
|
||||
f"fv{str(round(pg.fillet_radius, val_round))}"
|
||||
f",{str(round(pg.fillet_segments, val_round))}"
|
||||
f",{str(round(pg.fillet_profile, val_round))}"
|
||||
)
|
||||
else:
|
||||
pg.command = (
|
||||
f"fe{str(round(pg.fillet_radius, val_round))}"
|
||||
f",{str(round(pg.fillet_segments, val_round))}"
|
||||
f",{str(round(pg.fillet_profile, val_round))}"
|
||||
f"fe{str(round(pg.fillet_radius, val_round))}"
|
||||
f",{str(round(pg.fillet_segments, val_round))}"
|
||||
f",{str(round(pg.fillet_profile, val_round))}"
|
||||
)
|
||||
return {"FINISHED"}
|
||||
|
||||
|
|
|
@ -29,25 +29,23 @@ import bmesh
|
|||
from mathutils.geometry import intersect_line_plane
|
||||
from .pdt_msg_strings import (
|
||||
PDT_ERR_NOINT,
|
||||
PDT_ERR_SEL_1_E_1_F
|
||||
PDT_ERR_EDOB_MODE,
|
||||
)
|
||||
from .pdt_functions import oops
|
||||
|
||||
|
||||
def failure_message(self, context):
|
||||
def failure_message(context):
|
||||
"""Warn to the user to select 1 edge and 1 face."""
|
||||
pg = context.scene.pdt_pg
|
||||
pg.error = f"Select One Face and One Edge"
|
||||
context.window_manager.popup_menu(oops, title="Error", icon="ERROR")
|
||||
return
|
||||
|
||||
|
||||
def failure_message_on_plane(self, context):
|
||||
def failure_message_on_plane(context):
|
||||
"""Report an informative error message in a popup."""
|
||||
pg = context.scene.pdt_pg
|
||||
pg.error = f"{PDT_ERR_NOINT}"
|
||||
context.window_manager.popup_menu(oops, title="Error", icon="ERROR")
|
||||
return
|
||||
|
||||
def extend_vertex(context):
|
||||
"""Computes Edge Extension to Face.
|
||||
|
@ -59,31 +57,33 @@ def extend_vertex(context):
|
|||
Nothing."""
|
||||
|
||||
obj = bpy.context.edit_object
|
||||
pg = context.scene.pdt_pg
|
||||
|
||||
if all([bool(obj), obj.type == "MESH", obj.mode == "EDIT"]):
|
||||
me = obj.data
|
||||
bm = bmesh.from_edit_mesh(me)
|
||||
object_data = obj.data
|
||||
bm = bmesh.from_edit_mesh(object_data)
|
||||
verts = bm.verts
|
||||
faces = bm.faces
|
||||
|
||||
planes = [f for f in faces if f.select]
|
||||
if not len(planes) == 1:
|
||||
failure_message(self, context)
|
||||
failure_message(context)
|
||||
return
|
||||
|
||||
plane = planes[0]
|
||||
plane_vert_indices = plane.verts[:]
|
||||
all_selected_vert_indices = [v for v in verts if v.select]
|
||||
|
||||
M = set(plane_vert_indices)
|
||||
N = set(all_selected_vert_indices)
|
||||
O = N.difference(M)
|
||||
O = list(O)
|
||||
plane_verts = set(plane_vert_indices)
|
||||
all_verts = set(all_selected_vert_indices)
|
||||
diff_verts = all_verts.difference(plane_verts)
|
||||
diff_verts = list(diff_verts)
|
||||
|
||||
if not len(O) == 2:
|
||||
failure_message(self, context)
|
||||
if not len(diff_verts) == 2:
|
||||
failure_message(context)
|
||||
return
|
||||
|
||||
(v1_ref, v1), (v2_ref, v2) = [(i, i.co) for i in O]
|
||||
(v1_ref, v1), (v2_ref, v2) = [(i, i.co) for i in diff_verts]
|
||||
|
||||
plane_co = plane.calc_center_median()
|
||||
plane_no = plane.normal
|
||||
|
@ -92,15 +92,15 @@ def extend_vertex(context):
|
|||
|
||||
if new_co:
|
||||
new_vertex = verts.new(new_co)
|
||||
A_len = (v1 - new_co).length
|
||||
B_len = (v2 - new_co).length
|
||||
a_len = (v1 - new_co).length
|
||||
b_len = (v2 - new_co).length
|
||||
|
||||
vertex_reference = v1_ref if (A_len < B_len) else v2_ref
|
||||
vertex_reference = v1_ref if (a_len < b_len) else v2_ref
|
||||
bm.edges.new([vertex_reference, new_vertex])
|
||||
bmesh.update_edit_mesh(me, True)
|
||||
bmesh.update_edit_mesh(object_data, True)
|
||||
|
||||
else:
|
||||
failure_message_on_plane(self, context)
|
||||
failure_message_on_plane(context)
|
||||
else:
|
||||
pg.error = f"{PDT_ERR_EDOB_MODE},{obj.mode})"
|
||||
context.window_manager.popup_menu(oops, title="Error", icon="ERROR")
|
||||
|
@ -117,10 +117,10 @@ class PDT_OT_EdgeToFace(bpy.types.Operator):
|
|||
@classmethod
|
||||
def poll(cls, context):
|
||||
"""Only allow this to work if a mesh is selected in EDIT mode."""
|
||||
ob = context.object
|
||||
if ob is None:
|
||||
obj = context.object
|
||||
if obj is None:
|
||||
return False
|
||||
return all([bool(ob), ob.type == "MESH", ob.mode == "EDIT"])
|
||||
return all([bool(obj), obj.type == "MESH", obj.mode == "EDIT"])
|
||||
|
||||
def execute(self, context):
|
||||
"""Extends Disconnected Edge to Intersect with Face.
|
||||
|
|
|
@ -37,12 +37,9 @@ from .pdt_msg_strings import (
|
|||
PDT_ERR_SEL_2_OBJS,
|
||||
PDT_ERR_NO_ACT_OBJ,
|
||||
PDT_ERR_SEL_1_EDGEM,
|
||||
PDT_ERR_BAD1VALS,
|
||||
PDT_ERR_BAD2VALS,
|
||||
PDT_ERR_BAD3VALS,
|
||||
PDT_ERR_SEL_2_VERTS,
|
||||
PDT_ERR_CONNECTED,
|
||||
)
|
||||
from . import pdt_exception
|
||||
PDT_ShaderError = pdt_exception.ShaderError
|
||||
|
||||
|
||||
def debug(msg, prefix=""):
|
||||
|
@ -96,7 +93,10 @@ def oops(self, context):
|
|||
def set_mode(mode_pl):
|
||||
"""Sets Active Axes for View Orientation.
|
||||
|
||||
Sets indices of axes for locational vectors
|
||||
Sets indices of axes for locational vectors:
|
||||
"XY": a1 = x, a2 = y, a3 = z
|
||||
"XZ": a1 = x, a2 = z, a3 = y
|
||||
"YZ": a1 = y, a2 = z, a3 = x
|
||||
|
||||
Args:
|
||||
mode_pl: Plane Selector variable as input
|
||||
|
@ -105,16 +105,12 @@ def set_mode(mode_pl):
|
|||
3 Integer indices.
|
||||
"""
|
||||
|
||||
if mode_pl == "XY":
|
||||
# a1 = x a2 = y a3 = z
|
||||
return 0, 1, 2
|
||||
if mode_pl == "XZ":
|
||||
# a1 = x a2 = z a3 = y
|
||||
return 0, 2, 1
|
||||
if mode_pl == "YZ":
|
||||
# a1 = y a2 = z a3 = x
|
||||
return 1, 2, 0
|
||||
#FIXME: This needs a proper specification and a default
|
||||
order = {
|
||||
"XY": (0, 1, 2),
|
||||
"XZ": (0, 2, 1),
|
||||
"YZ": (1, 2, 0),
|
||||
}
|
||||
return order[mode_pl]
|
||||
|
||||
|
||||
def set_axis(mode_pl):
|
||||
|
@ -132,19 +128,15 @@ def set_axis(mode_pl):
|
|||
3 Integer Indicies.
|
||||
"""
|
||||
|
||||
if mode_pl == "RX-MY":
|
||||
return 0, 1, 2
|
||||
if mode_pl == "RX-MZ":
|
||||
return 0, 2, 1
|
||||
if mode_pl == "RY-MX":
|
||||
return 1, 0, 2
|
||||
if mode_pl == "RY-MZ":
|
||||
return 1, 2, 0
|
||||
if mode_pl == "RZ-MX":
|
||||
return 2, 0, 1
|
||||
if mode_pl == "RZ-MY":
|
||||
return 2, 1, 0
|
||||
#FIXME: This needs a proper specification and a default
|
||||
order = {
|
||||
"RX-MY": (0, 1, 2),
|
||||
"RX-MZ": (0, 2, 1),
|
||||
"RY-MX": (1, 0, 2),
|
||||
"RY-MZ": (1, 2, 0),
|
||||
"RZ-MX": (2, 0, 1),
|
||||
"RZ-MY": (2, 1, 0),
|
||||
}
|
||||
return order[mode_pl]
|
||||
|
||||
|
||||
def check_selection(num, bm, obj):
|
||||
|
@ -163,20 +155,19 @@ def check_selection(num, bm, obj):
|
|||
|
||||
if len(bm.select_history) < num:
|
||||
return None
|
||||
else:
|
||||
actE = bm.select_history[-1]
|
||||
if isinstance(actE, bmesh.types.BMVert):
|
||||
vector_a = actE.co
|
||||
active_vertex = bm.select_history[-1]
|
||||
if isinstance(active_vertex, bmesh.types.BMVert):
|
||||
vector_a = active_vertex.co
|
||||
if num == 1:
|
||||
return vector_a
|
||||
elif num == 2:
|
||||
if num == 2:
|
||||
vector_b = bm.select_history[-2].co
|
||||
return vector_a, vector_b
|
||||
elif num == 3:
|
||||
if num == 3:
|
||||
vector_b = bm.select_history[-2].co
|
||||
vector_c = bm.select_history[-3].co
|
||||
return vector_a, vector_b, vector_c
|
||||
elif num == 4:
|
||||
if num == 4:
|
||||
vector_b = bm.select_history[-2].co
|
||||
vector_c = bm.select_history[-3].co
|
||||
vector_d = bm.select_history[-4].co
|
||||
|
@ -233,13 +224,13 @@ def view_coords(x_loc, y_loc, z_loc):
|
|||
|
||||
areas = [a for a in bpy.context.screen.areas if a.type == "VIEW_3D"]
|
||||
if len(areas) > 0:
|
||||
vm = areas[0].spaces.active.region_3d.view_matrix
|
||||
vm = vm.to_3x3().normalized().inverted()
|
||||
vl = Vector((x_loc, y_loc, z_loc))
|
||||
vw = vm @ vl
|
||||
return vw
|
||||
else:
|
||||
return Vector((0, 0, 0))
|
||||
view_matrix = areas[0].spaces.active.region_3d.view_matrix
|
||||
view_matrix = view_matrix.to_3x3().normalized().inverted()
|
||||
view_location = Vector((x_loc, y_loc, z_loc))
|
||||
new_view_location = view_matrix @ view_location
|
||||
return new_view_location
|
||||
|
||||
return Vector((0, 0, 0))
|
||||
|
||||
|
||||
def view_coords_i(x_loc, y_loc, z_loc):
|
||||
|
@ -258,13 +249,13 @@ def view_coords_i(x_loc, y_loc, z_loc):
|
|||
|
||||
areas = [a for a in bpy.context.screen.areas if a.type == "VIEW_3D"]
|
||||
if len(areas) > 0:
|
||||
vm = areas[0].spaces.active.region_3d.view_matrix
|
||||
vm = vm.to_3x3().normalized()
|
||||
vl = Vector((x_loc, y_loc, z_loc))
|
||||
vw = vm @ vl
|
||||
return vw
|
||||
else:
|
||||
return Vector((0, 0, 0))
|
||||
view_matrix = areas[0].spaces.active.region_3d.view_matrix
|
||||
view_matrix = view_matrix.to_3x3().normalized()
|
||||
view_location = Vector((x_loc, y_loc, z_loc))
|
||||
new_view_location = view_matrix @ view_location
|
||||
return new_view_location
|
||||
|
||||
return Vector((0, 0, 0))
|
||||
|
||||
|
||||
def view_dir(dis_v, ang_v):
|
||||
|
@ -283,15 +274,15 @@ def view_dir(dis_v, ang_v):
|
|||
|
||||
areas = [a for a in bpy.context.screen.areas if a.type == "VIEW_3D"]
|
||||
if len(areas) > 0:
|
||||
vm = areas[0].spaces.active.region_3d.view_matrix
|
||||
vm = vm.to_3x3().normalized().inverted()
|
||||
vl = Vector((0, 0, 0))
|
||||
vl.x = dis_v * cos(ang_v * pi / 180)
|
||||
vl.y = dis_v * sin(ang_v * pi / 180)
|
||||
vw = vm @ vl
|
||||
return vw
|
||||
else:
|
||||
return Vector((0, 0, 0))
|
||||
view_matrix = areas[0].spaces.active.region_3d.view_matrix
|
||||
view_matrix = view_matrix.to_3x3().normalized().inverted()
|
||||
view_location = Vector((0, 0, 0))
|
||||
view_location.x = dis_v * cos(ang_v * pi / 180)
|
||||
view_location.y = dis_v * sin(ang_v * pi / 180)
|
||||
new_view_location = view_matrix @ view_location
|
||||
return new_view_location
|
||||
|
||||
return Vector((0, 0, 0))
|
||||
|
||||
|
||||
def euler_to_quaternion(roll, pitch, yaw):
|
||||
|
@ -307,16 +298,16 @@ def euler_to_quaternion(roll, pitch, yaw):
|
|||
"""
|
||||
|
||||
# fmt: off
|
||||
qx = (np.sin(roll/2) * np.cos(pitch/2) * np.cos(yaw/2)
|
||||
- np.cos(roll/2) * np.sin(pitch/2) * np.sin(yaw/2))
|
||||
qy = (np.cos(roll/2) * np.sin(pitch/2) * np.cos(yaw/2)
|
||||
+ np.sin(roll/2) * np.cos(pitch/2) * np.sin(yaw/2))
|
||||
qz = (np.cos(roll/2) * np.cos(pitch/2) * np.sin(yaw/2)
|
||||
- np.sin(roll/2) * np.sin(pitch/2) * np.cos(yaw/2))
|
||||
qw = (np.cos(roll/2) * np.cos(pitch/2) * np.cos(yaw/2)
|
||||
+ np.sin(roll/2) * np.sin(pitch/2) * np.sin(yaw/2))
|
||||
quat_x = (np.sin(roll/2) * np.cos(pitch/2) * np.cos(yaw/2)
|
||||
- np.cos(roll/2) * np.sin(pitch/2) * np.sin(yaw/2))
|
||||
quat_y = (np.cos(roll/2) * np.sin(pitch/2) * np.cos(yaw/2)
|
||||
+ np.sin(roll/2) * np.cos(pitch/2) * np.sin(yaw/2))
|
||||
quat_z = (np.cos(roll/2) * np.cos(pitch/2) * np.sin(yaw/2)
|
||||
- np.sin(roll/2) * np.sin(pitch/2) * np.cos(yaw/2))
|
||||
quat_w = (np.cos(roll/2) * np.cos(pitch/2) * np.cos(yaw/2)
|
||||
+ np.sin(roll/2) * np.sin(pitch/2) * np.sin(yaw/2))
|
||||
# fmt: on
|
||||
return Quaternion((qw, qx, qy, qz))
|
||||
return Quaternion((quat_w, quat_x, quat_y, quat_z))
|
||||
|
||||
|
||||
def arc_centre(vector_a, vector_b, vector_c):
|
||||
|
@ -331,22 +322,29 @@ def arc_centre(vector_a, vector_b, vector_c):
|
|||
Vector representing Arc Centre and Float representing Arc Radius.
|
||||
"""
|
||||
|
||||
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_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)
|
||||
coord_a = np.array([vector_a.x, vector_a.y, vector_a.z])
|
||||
coord_b = np.array([vector_b.x, vector_b.y, vector_b.z])
|
||||
coord_c = np.array([vector_c.x, vector_c.y, vector_c.z])
|
||||
line_a = np.linalg.norm(coord_c - coord_b)
|
||||
line_b = np.linalg.norm(coord_c - coord_a)
|
||||
line_c = np.linalg.norm(coord_b - coord_a)
|
||||
# fmt: off
|
||||
s = (a+b+c) / 2
|
||||
R = a*b*c/4 / np.sqrt(s * (s-a) * (s-b) * (s-c))
|
||||
b1 = a*a * (b*b + c*c - a*a)
|
||||
b2 = b*b * (a*a + c*c - b*b)
|
||||
b3 = c*c * (a*a + b*b - c*c)
|
||||
line_s = (line_a+line_b+line_c) / 2
|
||||
radius = (
|
||||
line_a*line_b*line_c/4
|
||||
/ np.sqrt(line_s
|
||||
* (line_s-line_a)
|
||||
* (line_s-line_b)
|
||||
* (line_s-line_c))
|
||||
)
|
||||
base_1 = line_a*line_a * (line_b*line_b + line_c*line_c - line_a*line_a)
|
||||
base_2 = line_b*line_b * (line_a*line_a + line_c*line_c - line_b*line_b)
|
||||
base_3 = line_c*line_c * (line_a*line_a + line_b*line_b - line_c*line_c)
|
||||
# fmt: on
|
||||
P = np.column_stack((A, B, C)).dot(np.hstack((b1, b2, b3)))
|
||||
P /= b1 + b2 + b3
|
||||
return Vector((P[0], P[1], P[2])), R
|
||||
intersect_coord = np.column_stack((coord_a, coord_b, coord_c))
|
||||
intersect_coord = intersect_coord.dot(np.hstack((base_1, base_2, base_3)))
|
||||
intersect_coord /= base_1 + base_2 + base_3
|
||||
return Vector((intersect_coord[0], intersect_coord[1], intersect_coord[2])), radius
|
||||
|
||||
|
||||
def intersection(vertex_a, vertex_b, vertex_c, vertex_d, plane):
|
||||
|
@ -371,38 +369,39 @@ def intersection(vertex_a, vertex_b, vertex_c, vertex_d, plane):
|
|||
vertex_offset = vertex_c - vertex_a
|
||||
vertex_c = view_coords_i(vertex_offset.x, vertex_offset.y, vertex_offset.z)
|
||||
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 = (vector_ref.x, vector_ref.y)
|
||||
coord_a = (vertex_c.x, vertex_c.y)
|
||||
coord_b = (vertex_d.x, vertex_d.y)
|
||||
coord_c = (vertex_b.x, vertex_b.y)
|
||||
coord_d = (vector_ref.x, vector_ref.y)
|
||||
else:
|
||||
a1, a2, a3 = set_mode(plane)
|
||||
ap1 = (vertex_c[a1], vertex_c[a2])
|
||||
ap2 = (vertex_d[a1], vertex_d[a2])
|
||||
bp1 = (vertex_a[a1], vertex_a[a2])
|
||||
bp2 = (vertex_b[a1], vertex_b[a2])
|
||||
s = np.vstack([ap1, ap2, bp1, bp2])
|
||||
h = np.hstack((s, np.ones((4, 1))))
|
||||
l1 = np.cross(h[0], h[1])
|
||||
l2 = np.cross(h[2], h[3])
|
||||
x, y, z = np.cross(l1, l2)
|
||||
if z == 0:
|
||||
coord_a = (vertex_c[a1], vertex_c[a2])
|
||||
coord_b = (vertex_d[a1], vertex_d[a2])
|
||||
coord_c = (vertex_a[a1], vertex_a[a2])
|
||||
coord_d = (vertex_b[a1], vertex_b[a2])
|
||||
v_stack = np.vstack([coord_a, coord_b, coord_c, coord_d])
|
||||
h_stack = np.hstack((v_stack, np.ones((4, 1))))
|
||||
line_a = np.cross(h_stack[0], h_stack[1])
|
||||
line_b = np.cross(h_stack[2], h_stack[3])
|
||||
x_loc, y_loc, z_loc = np.cross(line_a, line_b)
|
||||
if z_loc == 0:
|
||||
return Vector((0, 0, 0)), False
|
||||
nx = x / z
|
||||
nz = y / z
|
||||
new_x_loc = x_loc / z_loc
|
||||
new_z_loc = y_loc / z_loc
|
||||
if plane == "LO":
|
||||
ly = 0
|
||||
new_y_loc = 0
|
||||
else:
|
||||
ly = vertex_a[a3]
|
||||
new_y_loc = vertex_a[a3]
|
||||
# Order Vector Delta
|
||||
if plane == "XZ":
|
||||
vector_delta = Vector((nx, ly, nz))
|
||||
vector_delta = Vector((new_x_loc, new_y_loc, new_z_loc))
|
||||
elif plane == "XY":
|
||||
vector_delta = Vector((nx, nz, ly))
|
||||
vector_delta = Vector((new_x_loc, new_z_loc, new_y_loc))
|
||||
elif plane == "YZ":
|
||||
vector_delta = Vector((ly, nx, nz))
|
||||
elif plane == "LO":
|
||||
vector_delta = view_coords(nx, nz, ly) + vertex_a
|
||||
vector_delta = Vector((new_y_loc, new_x_loc, new_z_loc))
|
||||
else:
|
||||
# Must be Local View Plane
|
||||
vector_delta = view_coords(new_x_loc, new_z_loc, new_y_loc) + vertex_a
|
||||
return vector_delta, True
|
||||
|
||||
|
||||
|
@ -442,38 +441,38 @@ def get_percent(obj, flip_p, per_v, data, scene):
|
|||
pg.error = PDT_ERR_SEL_2_V_1_E + str(len(verts)) + " Vertices"
|
||||
bpy.context.window_manager.popup_menu(oops, title="Error", icon="ERROR")
|
||||
return None
|
||||
p1 = np.array([vector_a.x, vector_a.y, vector_a.z])
|
||||
p2 = np.array([vector_b.x, vector_b.y, vector_b.z])
|
||||
coord_a = np.array([vector_a.x, vector_a.y, vector_a.z])
|
||||
coord_b = np.array([vector_b.x, vector_b.y, vector_b.z])
|
||||
if obj.mode == "OBJECT":
|
||||
objs = bpy.context.view_layer.objects.selected
|
||||
if len(objs) != 2:
|
||||
pg.error = PDT_ERR_SEL_2_OBJS + str(len(objs)) + ")"
|
||||
bpy.context.window_manager.popup_menu(oops, title="Error", icon="ERROR")
|
||||
return None
|
||||
p1 = np.array(
|
||||
coord_a = np.array(
|
||||
[
|
||||
objs[-1].matrix_world.decompose()[0].x,
|
||||
objs[-1].matrix_world.decompose()[0].y,
|
||||
objs[-1].matrix_world.decompose()[0].z,
|
||||
]
|
||||
)
|
||||
p2 = np.array(
|
||||
coord_b = np.array(
|
||||
[
|
||||
objs[-2].matrix_world.decompose()[0].x,
|
||||
objs[-2].matrix_world.decompose()[0].y,
|
||||
objs[-2].matrix_world.decompose()[0].z,
|
||||
]
|
||||
)
|
||||
p4 = np.array([0, 0, 0])
|
||||
p3 = p2 - p1
|
||||
coord_c = coord_b - coord_a
|
||||
coord_d = np.array([0, 0, 0])
|
||||
_per_v = per_v
|
||||
if (flip_p and data != "MV") or data == "MV":
|
||||
_per_v = 100 - per_v
|
||||
V = (p4+p3) * (_per_v / 100) + p1
|
||||
return Vector((V[0], V[1], V[2]))
|
||||
coord_out = (coord_d+coord_c) * (_per_v / 100) + coord_a
|
||||
return Vector((coord_out[0], coord_out[1], coord_out[2]))
|
||||
|
||||
|
||||
def obj_check(context, obj, scene, operator):
|
||||
def obj_check(obj, scene, operator):
|
||||
"""Check Object & Selection Validity.
|
||||
|
||||
Args:
|
||||
|
@ -499,32 +498,29 @@ def obj_check(context, obj, scene, operator):
|
|||
pg.error = f"{PDT_ERR_SEL_1_EDGEM} {len(bm.edges)})"
|
||||
bpy.context.window_manager.popup_menu(oops, title="Error", icon="ERROR")
|
||||
return None, False
|
||||
else:
|
||||
return bm, True
|
||||
return bm, True
|
||||
if len(bm.select_history) >= 1:
|
||||
vector_a = None
|
||||
if _operator not in {"D", "E", "F", "G", "N", "S"}:
|
||||
vector_a = check_selection(1, bm, obj)
|
||||
else:
|
||||
verts = [v for v in bm.verts if v.select]
|
||||
if len(verts) > 0:
|
||||
vector_a = verts[0]
|
||||
else:
|
||||
vector_a = None
|
||||
if vector_a is None:
|
||||
pg.error = PDT_ERR_VERT_MODE
|
||||
bpy.context.window_manager.popup_menu(oops, title="Error", icon="ERROR")
|
||||
return None, False
|
||||
return bm, True
|
||||
else:
|
||||
return None, True
|
||||
return None, True
|
||||
|
||||
|
||||
def dis_ang(vals, flip_a, plane, scene):
|
||||
def dis_ang(values, flip_angle, plane, scene):
|
||||
"""Set Working Axes when using Direction command.
|
||||
|
||||
Args:
|
||||
vals: Input Arguments (Values)
|
||||
flip_a: Whether to flip the angle
|
||||
values: Input Arguments
|
||||
flip_angle: Whether to flip the angle
|
||||
plane: Working Plane
|
||||
scene: Current Scene
|
||||
|
||||
|
@ -533,9 +529,9 @@ def dis_ang(vals, flip_a, plane, scene):
|
|||
"""
|
||||
|
||||
pg = scene.pdt_pg
|
||||
dis_v = float(vals[0])
|
||||
ang_v = float(vals[1])
|
||||
if flip_a:
|
||||
dis_v = float(values[0])
|
||||
ang_v = float(values[1])
|
||||
if flip_angle:
|
||||
if ang_v > 0:
|
||||
ang_v = ang_v - 180
|
||||
else:
|
||||
|
@ -555,10 +551,10 @@ def dis_ang(vals, flip_a, plane, scene):
|
|||
|
||||
# Shader for displaying the Pivot Point as Graphics.
|
||||
#
|
||||
shader = gpu.shader.from_builtin("3D_UNIFORM_COLOR") if not bpy.app.background else None
|
||||
SHADER = gpu.shader.from_builtin("3D_UNIFORM_COLOR") if not bpy.app.background else None
|
||||
|
||||
|
||||
def draw3D(coords, gtype, rgba, context):
|
||||
def draw_3d(coords, gtype, rgba, context):
|
||||
"""Draw Pivot Point Graphics.
|
||||
|
||||
Draws either Lines Points, or Tris using defined shader
|
||||
|
@ -573,19 +569,19 @@ def draw3D(coords, gtype, rgba, context):
|
|||
Nothing.
|
||||
"""
|
||||
|
||||
batch = batch_for_shader(shader, gtype, {"pos": coords})
|
||||
batch = batch_for_shader(SHADER, gtype, {"pos": coords})
|
||||
|
||||
try:
|
||||
if coords is not None:
|
||||
bgl.glEnable(bgl.GL_BLEND)
|
||||
shader.bind()
|
||||
shader.uniform_float("color", rgba)
|
||||
batch.draw(shader)
|
||||
SHADER.bind()
|
||||
SHADER.uniform_float("color", rgba)
|
||||
batch.draw(SHADER)
|
||||
except:
|
||||
pass
|
||||
raise PDT_ShaderError
|
||||
|
||||
|
||||
def drawCallback3D(self, context):
|
||||
def draw_callback_3d(self, context):
|
||||
"""Create Coordinate List for Pivot Point Graphic.
|
||||
|
||||
Creates coordinates for Pivot Point Graphic consisting of 6 Tris
|
||||
|
@ -601,73 +597,73 @@ def drawCallback3D(self, context):
|
|||
|
||||
scene = context.scene
|
||||
pg = scene.pdt_pg
|
||||
w = context.region.width
|
||||
x = pg.pivot_loc.x
|
||||
y = pg.pivot_loc.y
|
||||
z = pg.pivot_loc.z
|
||||
region_width = context.region.width
|
||||
x_loc = pg.pivot_loc.x
|
||||
y_loc = pg.pivot_loc.y
|
||||
z_loc = pg.pivot_loc.z
|
||||
# Scale it from view
|
||||
areas = [a for a in context.screen.areas if a.type == "VIEW_3D"]
|
||||
if len(areas) > 0:
|
||||
sf = abs(areas[0].spaces.active.region_3d.window_matrix.decompose()[2][1])
|
||||
scale_factor = abs(areas[0].spaces.active.region_3d.window_matrix.decompose()[2][1])
|
||||
# Check for orhtographic view and resize
|
||||
#if areas[0].spaces.active.region_3d.is_orthographic_side_view:
|
||||
# a = w / sf / 60000 * pg.pivot_size
|
||||
# dim_a = region_width / sf / 60000 * pg.pivot_size
|
||||
#else:
|
||||
# a = w / sf / 5000 * pg.pivot_size
|
||||
a = w / sf / 50000 * pg.pivot_size
|
||||
b = a * 0.65
|
||||
c = a * 0.05 + (pg.pivot_width * a * 0.02)
|
||||
o = c / 3
|
||||
# dim_a = region_width / sf / 5000 * pg.pivot_size
|
||||
dim_a = region_width / scale_factor / 50000 * pg.pivot_size
|
||||
dim_b = dim_a * 0.65
|
||||
dim_c = dim_a * 0.05 + (pg.pivot_width * dim_a * 0.02)
|
||||
dim_o = dim_c / 3
|
||||
|
||||
# fmt: off
|
||||
# X Axis
|
||||
coords = [
|
||||
(x, y, z),
|
||||
(x+b, y-o, z),
|
||||
(x+b, y+o, z),
|
||||
(x+a, y, z),
|
||||
(x+b, y+c, z),
|
||||
(x+b, y-c, z),
|
||||
(x_loc, y_loc, z_loc),
|
||||
(x_loc+dim_b, y_loc-dim_o, z_loc),
|
||||
(x_loc+dim_b, y_loc+dim_o, z_loc),
|
||||
(x_loc+dim_a, y_loc, z_loc),
|
||||
(x_loc+dim_b, y_loc+dim_c, z_loc),
|
||||
(x_loc+dim_b, y_loc-dim_c, z_loc),
|
||||
]
|
||||
# fmt: on
|
||||
colour = (1.0, 0.0, 0.0, pg.pivot_alpha)
|
||||
draw3D(coords, "TRIS", colour, context)
|
||||
coords = [(x, y, z), (x+a, y, z)]
|
||||
draw3D(coords, "LINES", colour, context)
|
||||
draw_3d(coords, "TRIS", colour, context)
|
||||
coords = [(x_loc, y_loc, z_loc), (x_loc+dim_a, y_loc, z_loc)]
|
||||
draw_3d(coords, "LINES", colour, context)
|
||||
# fmt: off
|
||||
# Y Axis
|
||||
coords = [
|
||||
(x, y, z),
|
||||
(x-o, y+b, z),
|
||||
(x+o, y+b, z),
|
||||
(x, y+a, z),
|
||||
(x+c, y+b, z),
|
||||
(x-c, y+b, z),
|
||||
(x_loc, y_loc, z_loc),
|
||||
(x_loc-dim_o, y_loc+dim_b, z_loc),
|
||||
(x_loc+dim_o, y_loc+dim_b, z_loc),
|
||||
(x_loc, y_loc+dim_a, z_loc),
|
||||
(x_loc+dim_c, y_loc+dim_b, z_loc),
|
||||
(x_loc-dim_c, y_loc+dim_b, z_loc),
|
||||
]
|
||||
# fmt: on
|
||||
colour = (0.0, 1.0, 0.0, pg.pivot_alpha)
|
||||
draw3D(coords, "TRIS", colour, context)
|
||||
coords = [(x, y, z), (x, y + a, z)]
|
||||
draw3D(coords, "LINES", colour, context)
|
||||
draw_3d(coords, "TRIS", colour, context)
|
||||
coords = [(x_loc, y_loc, z_loc), (x_loc, y_loc + dim_a, z_loc)]
|
||||
draw_3d(coords, "LINES", colour, context)
|
||||
# fmt: off
|
||||
# Z Axis
|
||||
coords = [
|
||||
(x, y, z),
|
||||
(x-o, y, z+b),
|
||||
(x+o, y, z+b),
|
||||
(x, y, z+a),
|
||||
(x+c, y, z+b),
|
||||
(x-c, y, z+b),
|
||||
(x_loc, y_loc, z_loc),
|
||||
(x_loc-dim_o, y_loc, z_loc+dim_b),
|
||||
(x_loc+dim_o, y_loc, z_loc+dim_b),
|
||||
(x_loc, y_loc, z_loc+dim_a),
|
||||
(x_loc+dim_c, y_loc, z_loc+dim_b),
|
||||
(x_loc-dim_c, y_loc, z_loc+dim_b),
|
||||
]
|
||||
# fmt: on
|
||||
colour = (0.2, 0.5, 1.0, pg.pivot_alpha)
|
||||
draw3D(coords, "TRIS", colour, context)
|
||||
coords = [(x, y, z), (x, y, z + a)]
|
||||
draw3D(coords, "LINES", colour, context)
|
||||
draw_3d(coords, "TRIS", colour, context)
|
||||
coords = [(x_loc, y_loc, z_loc), (x_loc, y_loc, z_loc + dim_a)]
|
||||
draw_3d(coords, "LINES", colour, context)
|
||||
# Centre
|
||||
coords = [(x, y, z)]
|
||||
coords = [(x_loc, y_loc, z_loc)]
|
||||
colour = (1.0, 1.0, 0.0, pg.pivot_alpha)
|
||||
draw3D(coords, "POINTS", colour, context)
|
||||
draw_3d(coords, "POINTS", colour, context)
|
||||
|
||||
|
||||
def scale_set(self, context):
|
||||
|
|
|
@ -31,6 +31,7 @@ from .pdt_msg_strings import PDT_ERR_NO_LIBRARY
|
|||
|
||||
class PDT_OT_LibShow(Operator):
|
||||
"""Show Library File Details."""
|
||||
|
||||
bl_idname = "pdt.lib_show"
|
||||
bl_label = "Show Library Details"
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
|
@ -51,7 +52,9 @@ class PDT_OT_LibShow(Operator):
|
|||
pg.error = str(Path(file_path))
|
||||
debug("PDT Parts Library:")
|
||||
debug(f"{pg.error}")
|
||||
bpy.context.window_manager.popup_menu(oops, title="Information - Parts Library File", icon="INFO")
|
||||
bpy.context.window_manager.popup_menu(
|
||||
oops, title="Information - Parts Library File", icon="INFO"
|
||||
)
|
||||
return {"FINISHED"}
|
||||
|
||||
|
||||
|
@ -86,37 +89,51 @@ class PDT_OT_Append(Operator):
|
|||
if path.is_file() and ".blend" in str(path):
|
||||
if pg.lib_mode == "OBJECTS":
|
||||
# Force object Mode
|
||||
bpy.ops.object.mode_set(mode='OBJECT')
|
||||
bpy.ops.object.mode_set(mode="OBJECT")
|
||||
bpy.ops.wm.append(
|
||||
filepath=str(path), directory=str(path) + "/Object", filename=pg.lib_objects
|
||||
filepath=str(path),
|
||||
directory=str(path) + "/Object",
|
||||
filename=pg.lib_objects,
|
||||
)
|
||||
for obj in context.view_layer.objects:
|
||||
if obj.name not in obj_names:
|
||||
obj.select_set(False)
|
||||
obj.location = Vector(
|
||||
(scene.cursor.location.x, scene.cursor.location.y, scene.cursor.location.z)
|
||||
(
|
||||
scene.cursor.location.x,
|
||||
scene.cursor.location.y,
|
||||
scene.cursor.location.z,
|
||||
)
|
||||
)
|
||||
return {"FINISHED"}
|
||||
elif pg.lib_mode == "COLLECTIONS":
|
||||
if pg.lib_mode == "COLLECTIONS":
|
||||
bpy.ops.wm.append(
|
||||
filepath=str(path), directory=str(path) + "/Collection", filename=pg.lib_collections
|
||||
filepath=str(path),
|
||||
directory=str(path) + "/Collection",
|
||||
filename=pg.lib_collections,
|
||||
)
|
||||
for obj in context.view_layer.objects:
|
||||
if obj.name not in obj_names:
|
||||
obj.select_set(False)
|
||||
obj.location = Vector(
|
||||
(scene.cursor.location.x, scene.cursor.location.y, scene.cursor.location.z)
|
||||
(
|
||||
scene.cursor.location.x,
|
||||
scene.cursor.location.y,
|
||||
scene.cursor.location.z,
|
||||
)
|
||||
)
|
||||
return {"FINISHED"}
|
||||
elif pg.lib_mode == "MATERIALS":
|
||||
if pg.lib_mode == "MATERIALS":
|
||||
bpy.ops.wm.append(
|
||||
filepath=str(path), directory=str(path) + "/Material", filename=pg.lib_materials
|
||||
filepath=str(path),
|
||||
directory=str(path) + "/Material",
|
||||
filename=pg.lib_materials,
|
||||
)
|
||||
return {"FINISHED"}
|
||||
else:
|
||||
errmsg = PDT_ERR_NO_LIBRARY
|
||||
self.report({"ERROR"}, errmsg)
|
||||
return {"FINISHED"}
|
||||
|
||||
errmsg = PDT_ERR_NO_LIBRARY
|
||||
self.report({"ERROR"}, errmsg)
|
||||
return {"FINISHED"}
|
||||
|
||||
|
||||
class PDT_OT_Link(Operator):
|
||||
|
@ -148,26 +165,32 @@ class PDT_OT_Link(Operator):
|
|||
if path.is_file() and ".blend" in str(path):
|
||||
if pg.lib_mode == "OBJECTS":
|
||||
# Force object Mode
|
||||
bpy.ops.object.mode_set(mode='OBJECT')
|
||||
bpy.ops.object.mode_set(mode="OBJECT")
|
||||
bpy.ops.wm.link(
|
||||
filepath=str(path), directory=str(path) + "/Object", filename=pg.lib_objects
|
||||
filepath=str(path),
|
||||
directory=str(path) + "/Object",
|
||||
filename=pg.lib_objects,
|
||||
)
|
||||
for obj in context.view_layer.objects:
|
||||
obj.select_set(False)
|
||||
return {"FINISHED"}
|
||||
elif pg.lib_mode == "COLLECTIONS":
|
||||
if pg.lib_mode == "COLLECTIONS":
|
||||
bpy.ops.wm.link(
|
||||
filepath=str(path), directory=str(path) + "/Collection", filename=pg.lib_collections
|
||||
filepath=str(path),
|
||||
directory=str(path) + "/Collection",
|
||||
filename=pg.lib_collections,
|
||||
)
|
||||
for obj in context.view_layer.objects:
|
||||
obj.select_set(False)
|
||||
return {"FINISHED"}
|
||||
elif pg.lib_mode == "MATERIALS":
|
||||
if pg.lib_mode == "MATERIALS":
|
||||
bpy.ops.wm.link(
|
||||
filepath=str(path), directory=str(path) + "/Material", filename=pg.lib_materials
|
||||
filepath=str(path),
|
||||
directory=str(path) + "/Material",
|
||||
filename=pg.lib_materials,
|
||||
)
|
||||
return {"FINISHED"}
|
||||
else:
|
||||
errmsg = PDT_ERR_NO_LIBRARY
|
||||
self.report({"ERROR"}, errmsg)
|
||||
return {"FINISHED"}
|
||||
|
||||
errmsg = PDT_ERR_NO_LIBRARY
|
||||
self.report({"ERROR"}, errmsg)
|
||||
return {"FINISHED"}
|
||||
|
|
|
@ -28,147 +28,153 @@
|
|||
#
|
||||
# Menu Labels
|
||||
#
|
||||
PDT_LAB_ABS = "Absolute" # "Global"
|
||||
PDT_LAB_DEL = "Delta" # "Relative"
|
||||
PDT_LAB_DIR = "Direction" # "Polar"
|
||||
PDT_LAB_NOR = "Normal" # "Perpendicular"
|
||||
PDT_LAB_ARCCENTRE = "Arc Centre"
|
||||
PDT_LAB_PLANE = "Plane"
|
||||
PDT_LAB_MODE = "Mode"
|
||||
PDT_LAB_OPERATION = "Operation"
|
||||
PDT_LAB_PERCENT = "Percent"
|
||||
PDT_LAB_INTERSECT = "Intersect" # "Convergance"
|
||||
PDT_LAB_ORDER = "Order"
|
||||
PDT_LAB_FLIPANGLE = "Flip Angle"
|
||||
PDT_LAB_FLIPPERCENT = "Flip %"
|
||||
PDT_LAB_ALLACTIVE = "All/Active"
|
||||
PDT_LAB_VARIABLES = "Coordinates/Delta Offsets & Other Variables"
|
||||
PDT_LAB_CVALUE = "Coordinates"
|
||||
PDT_LAB_DISVALUE = "Distance"
|
||||
PDT_LAB_ANGLEVALUE = "Angle"
|
||||
PDT_LAB_PERCENTS = "%"
|
||||
PDT_LAB_TOOLS = "Tools"
|
||||
PDT_LAB_JOIN2VERTS = "Join 2 Verts"
|
||||
PDT_LAB_ORIGINCURSOR = "Origin To Cursor"
|
||||
PDT_LAB_AD2D = "Set A/D 2D"
|
||||
PDT_LAB_AD3D = "Set A/D 3D"
|
||||
PDT_LAB_TAPERAXES = "" # Intentionally left blank
|
||||
PDT_LAB_TAPER = "Taper"
|
||||
PDT_LAB_INTERSETALL = "Intersect All"
|
||||
PDT_LAB_BISECT = "Bisect"
|
||||
PDT_LAB_EDGETOEFACE = "Edge-To-Face"
|
||||
PDT_LAB_FILLET = "Fillet"
|
||||
PDT_LAB_SEGMENTS = "Segments"
|
||||
PDT_LAB_USEVERTS = "Use Vertices"
|
||||
PDT_LAB_RADIUS = "Radius"
|
||||
PDT_LAB_PROFILE = "Profile"
|
||||
PDT_LAB_PIVOTSIZE = "" # Intentionally left blank
|
||||
PDT_LAB_PIVOTWIDTH = "" # Intentionally left blank
|
||||
PDT_LAB_PIVOTALPHA = "" # Intentionally left blank
|
||||
PDT_LAB_PIVOTLOC = "" # Intentionally left blank
|
||||
PDT_LAB_PIVOTLOCH = "Location"
|
||||
PDT_LAB_ABS = "Absolute" # "Global"
|
||||
PDT_LAB_DEL = "Delta" # "Relative"
|
||||
PDT_LAB_DIR = "Direction" # "Polar"
|
||||
PDT_LAB_NOR = "Normal" # "Perpendicular"
|
||||
PDT_LAB_ARCCENTRE = "Arc Centre"
|
||||
PDT_LAB_PLANE = "Plane"
|
||||
PDT_LAB_MODE = "Mode"
|
||||
PDT_LAB_OPERATION = "Operation"
|
||||
PDT_LAB_PERCENT = "Percent"
|
||||
PDT_LAB_INTERSECT = "Intersect" # "Convergance"
|
||||
PDT_LAB_ORDER = "Order"
|
||||
PDT_LAB_FLIPANGLE = "Flip Angle"
|
||||
PDT_LAB_FLIPPERCENT = "Flip %"
|
||||
PDT_LAB_ALLACTIVE = "All/Active"
|
||||
PDT_LAB_VARIABLES = "Coordinates/Delta Offsets & Other Variables"
|
||||
PDT_LAB_CVALUE = "Coordinates"
|
||||
PDT_LAB_DISVALUE = "Distance"
|
||||
PDT_LAB_ANGLEVALUE = "Angle"
|
||||
PDT_LAB_PERCENTS = "%"
|
||||
PDT_LAB_TOOLS = "Tools"
|
||||
PDT_LAB_JOIN2VERTS = "Join 2 Verts"
|
||||
PDT_LAB_ORIGINCURSOR = "Origin To Cursor"
|
||||
PDT_LAB_AD2D = "Set A/D 2D"
|
||||
PDT_LAB_AD3D = "Set A/D 3D"
|
||||
PDT_LAB_TAPERAXES = "" # Intentionally left blank
|
||||
PDT_LAB_TAPER = "Taper"
|
||||
PDT_LAB_INTERSETALL = "Intersect All"
|
||||
PDT_LAB_BISECT = "Bisect"
|
||||
PDT_LAB_EDGETOEFACE = "Edge-To-Face"
|
||||
PDT_LAB_FILLET = "Fillet"
|
||||
PDT_LAB_SEGMENTS = "Segments"
|
||||
PDT_LAB_USEVERTS = "Use Vertices"
|
||||
PDT_LAB_RADIUS = "Radius"
|
||||
PDT_LAB_PROFILE = "Profile"
|
||||
PDT_LAB_PIVOTSIZE = "" # Intentionally left blank
|
||||
PDT_LAB_PIVOTWIDTH = "" # Intentionally left blank
|
||||
PDT_LAB_PIVOTALPHA = "" # Intentionally left blank
|
||||
PDT_LAB_PIVOTLOC = "" # Intentionally left blank
|
||||
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"
|
||||
PDT_ERR_NON_VALID = "is Not a Valid Option in Selected Object's Mode for Command:"
|
||||
PDT_ERR_VERT_MODE = "Work in Vertex Mode for this Function"
|
||||
PDT_ERR_NOPPLOC = "Custom Property PDT_PP_LOC for this object not found, have you Written it yet?"
|
||||
PDT_ERR_NO_LIBRARY = "PDT Library Blend File (parts_library.blend) is Missing from Addons/clockworxpdt Folder"
|
||||
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"
|
||||
PDT_ERR_NON_VALID = "is Not a Valid Option in Selected Object's Mode for Command:"
|
||||
PDT_ERR_VERT_MODE = "Work in Vertex Mode for this Function"
|
||||
PDT_ERR_NOPPLOC = (
|
||||
"Custom Property PDT_PP_LOC for this object not found, have you Written it yet?"
|
||||
)
|
||||
PDT_ERR_NO_LIBRARY = ("PDT Library Blend File (parts_library.blend) is Missing "
|
||||
+ "from Addons/clockworxpdt Folder")
|
||||
|
||||
PDT_ERR_SEL_1_VERTI = "Select at least 1 Vertex Individually (Currently selected:"
|
||||
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:"
|
||||
PDT_ERR_SEL_4_VERTS = "Select 4 Vertices Individually, or 2 Edges (Currently selected:"
|
||||
PDT_ERR_SEL_1_E_1_F = "Select 1 Face and 1 Detached Edge"
|
||||
PDT_ERR_SEL_1_VERTI = "Select at least 1 Vertex Individually (Currently selected:"
|
||||
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:"
|
||||
PDT_ERR_SEL_4_VERTS = "Select 4 Vertices Individually, or 2 Edges (Currently selected:"
|
||||
PDT_ERR_SEL_1_E_1_F = "Select 1 Face and 1 Detached Edge"
|
||||
|
||||
PDT_ERR_SEL_1_EDGE = "Select Exactly 1 Edge (Currently selected:"
|
||||
PDT_ERR_SEL_1_EDGEM = "Select at least 1 Edge (Currently selected:"
|
||||
PDT_ERR_SEL_1_EDGE = "Select Exactly 1 Edge (Currently selected:"
|
||||
PDT_ERR_SEL_1_EDGEM = "Select at least 1 Edge (Currently selected:"
|
||||
|
||||
PDT_ERR_SEL_1_OBJ = "Select Exactly 1 Object (Currently selected:"
|
||||
PDT_ERR_SEL_2_OBJS = "Select Exactly 2 Objects (Currently selected:"
|
||||
PDT_ERR_SEL_3_OBJS = "Select Exactly 3 Objects (Currently selected:"
|
||||
PDT_ERR_SEL_4_OBJS = "Select Exactly 4 Objects (Currently selected:"
|
||||
PDT_ERR_SEL_1_OBJ = "Select Exactly 1 Object (Currently selected:"
|
||||
PDT_ERR_SEL_2_OBJS = "Select Exactly 2 Objects (Currently selected:"
|
||||
PDT_ERR_SEL_3_OBJS = "Select Exactly 3 Objects (Currently selected:"
|
||||
PDT_ERR_SEL_4_OBJS = "Select Exactly 4 Objects (Currently selected:"
|
||||
|
||||
PDT_ERR_FACE_SEL = "You have a Face Selected, this would have ruined the Topology"
|
||||
PDT_ERR_FACE_SEL = "You have a Face Selected, this would have ruined the Topology"
|
||||
|
||||
PDT_ERR_INT_LINES = "Implied Lines Do Not Intersect in"
|
||||
PDT_ERR_INT_NO_ALL = "Active Vertex was not Closest to Intersection and All/Act was not Selected"
|
||||
PDT_ERR_STRIGHT_LINE = "Selected Points all lie in a Straight Line"
|
||||
PDT_ERR_CONNECTED = "Vertices are already Connected"
|
||||
PDT_ERR_EDIT_MODE = "Only Works in EDIT Mode (Current mode:"
|
||||
PDT_ERR_EDOB_MODE = "Only Works in EDIT, or OBJECT Modes (Current mode:"
|
||||
PDT_ERR_TAPER_ANG = "Angle must be in Range -80 to +80 (Currently set to:"
|
||||
PDT_ERR_TAPER_SEL = "Select at Least 2 Vertices Individually - Active is Rotation Point (Currently selected:"
|
||||
PDT_ERR_NO3DVIEW = "View3D not found, cannot run operator"
|
||||
PDT_ERR_SCALEZERO = "Scale Distance is 0"
|
||||
PDT_ERR_INT_LINES = "Implied Lines Do Not Intersect in"
|
||||
PDT_ERR_INT_NO_ALL = (
|
||||
"Active Vertex was not Closest to Intersection and All/Act was not Selected"
|
||||
)
|
||||
PDT_ERR_STRIGHT_LINE = "Selected Points all lie in a Straight Line"
|
||||
PDT_ERR_CONNECTED = "Vertices are already Connected"
|
||||
PDT_ERR_EDIT_MODE = "Only Works in EDIT Mode (Current mode:"
|
||||
PDT_ERR_EDOB_MODE = "Only Works in EDIT, or OBJECT Modes (Current mode:"
|
||||
PDT_ERR_TAPER_ANG = "Angle must be in Range -80 to +80 (Currently set to:"
|
||||
PDT_ERR_TAPER_SEL = ("Select at Least 2 Vertices Individually - Active is Rotation Point "
|
||||
+ "(Currently selected:")
|
||||
PDT_ERR_NO3DVIEW = "View3D not found, cannot run operator"
|
||||
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_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"
|
||||
PDT_ERR_BAD2VALS = "Bad Command - 2 Values needed"
|
||||
PDT_ERR_BAD3VALS = "Bad Command - 3 Coords needed"
|
||||
PDT_ERR_ADDVEDIT = "Only Add New Vertices in Edit Mode"
|
||||
PDT_ERR_SPLITEDIT = "Only Split Edges in Edit Mode"
|
||||
PDT_ERR_EXTEDIT = "Only Extrude Vertices in Edit Mode"
|
||||
PDT_ERR_DUPEDIT = "Only Duplicate Geometry in Edit Mode"
|
||||
PDT_ERR_FILEDIT = "Only Fillet Geometry in Edit Mode"
|
||||
PDT_ERR_NOCOMMAS = "No commas allowed in Maths Command"
|
||||
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_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"
|
||||
PDT_ERR_BAD2VALS = "Bad Command - 2 Values needed"
|
||||
PDT_ERR_BAD3VALS = "Bad Command - 3 Coords needed"
|
||||
PDT_ERR_ADDVEDIT = "Only Add New Vertices in Edit Mode"
|
||||
PDT_ERR_SPLITEDIT = "Only Split Edges in Edit Mode"
|
||||
PDT_ERR_EXTEDIT = "Only Extrude Vertices in Edit Mode"
|
||||
PDT_ERR_DUPEDIT = "Only Duplicate Geometry in Edit Mode"
|
||||
PDT_ERR_FILEDIT = "Only Fillet Geometry in Edit Mode"
|
||||
PDT_ERR_NOCOMMAS = "No commas allowed in Maths Command"
|
||||
|
||||
PDT_ERR_2CPNPE = "Select 2 Co-Planar Non-Parallel Edges"
|
||||
PDT_ERR_NCEDGES = "Edges must be Co-Planar Non-Parallel Edges, Selected Edges aren't"
|
||||
PDT_ERR_1EDGE1FACE = "Select 1 face and 1 Detached Edge"
|
||||
PDT_ERR_NOINT = "No Intersection Found"
|
||||
PDT_ERR_2CPNPE = "Select 2 Co-Planar Non-Parallel Edges"
|
||||
PDT_ERR_NCEDGES = "Edges must be Co-Planar Non-Parallel Edges, Selected Edges aren't"
|
||||
PDT_ERR_1EDGE1FACE = "Select 1 face and 1 Detached Edge"
|
||||
PDT_ERR_NOINT = "No Intersection Found"
|
||||
|
||||
# Info messages
|
||||
#
|
||||
PDT_INF_OBJ_MOVED = "Active Object Moved to Intersection, "
|
||||
PDT_INF_OBJ_MOVED = "Active Object Moved to Intersection, "
|
||||
|
||||
# Confirm Messages
|
||||
#
|
||||
PDT_CON_AREYOURSURE = "Are You Sure About This?"
|
||||
PDT_CON_AREYOURSURE = "Are You Sure About This?"
|
||||
|
||||
# Descriptions
|
||||
#
|
||||
PDT_DES_COORDS = "Cartesian Inputs"
|
||||
PDT_DES_OFFDIS = "Offset Distance"
|
||||
PDT_DES_OFFANG = "Offset Angle"
|
||||
PDT_DES_OFFPER = "Offset Percentage"
|
||||
PDT_DES_WORPLANE = "Choose Working Plane"
|
||||
PDT_DES_MOVESEL = "Select Move Mode"
|
||||
PDT_DES_OPMODE = "Select Operation Mode"
|
||||
PDT_DES_ROTMOVAX = "Rotational Axis - Movement Axis"
|
||||
PDT_DES_FLIPANG = "Flip Angle 180 degrees"
|
||||
PDT_DES_FLIPPER = "Flip Percent to 100 - %"
|
||||
PDT_DES_TRIM = "Trim/Extend only Active Vertex, or All"
|
||||
PDT_DES_LIBOBS = "Objects in Library"
|
||||
PDT_DES_LIBCOLS = "Collections in Library"
|
||||
PDT_DES_LIBMATS = "Materials in Library"
|
||||
PDT_DES_LIBMODE = "Library Mode"
|
||||
PDT_DES_LIBSER = "Enter A Search String (Contained)"
|
||||
PDT_DES_OBORDER = "Object Order to Lines"
|
||||
PDT_DES_VALIDLET = "Valid 1st letters; C D E G N P S V, Valid 2nd letters: A D I O P"
|
||||
PDT_DES_OUTPUT = "Output for Maths Operations"
|
||||
PDT_DES_PPLOC = "Location of PivotPoint"
|
||||
PDT_DES_PPSCALEFAC = "Scale Factors"
|
||||
PDT_DES_PPSIZE = "Pivot Size Factor"
|
||||
PDT_DES_PPWIDTH = "Pivot Line Width in Pixels"
|
||||
PDT_DES_PPTRANS = "Pivot Point Transparency"
|
||||
PDT_DES_PIVOTDIS = "Input Distance to Compare with Sytem Distance to set Scales"
|
||||
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"
|
||||
PDT_DES_COORDS = "Cartesian Inputs"
|
||||
PDT_DES_OFFDIS = "Offset Distance"
|
||||
PDT_DES_OFFANG = "Offset Angle"
|
||||
PDT_DES_OFFPER = "Offset Percentage"
|
||||
PDT_DES_WORPLANE = "Choose Working Plane"
|
||||
PDT_DES_MOVESEL = "Select Move Mode"
|
||||
PDT_DES_OPMODE = "Select Operation Mode"
|
||||
PDT_DES_ROTMOVAX = "Rotational Axis - Movement Axis"
|
||||
PDT_DES_FLIPANG = "Flip Angle 180 degrees"
|
||||
PDT_DES_FLIPPER = "Flip Percent to 100 - %"
|
||||
PDT_DES_TRIM = "Trim/Extend only Active Vertex, or All"
|
||||
PDT_DES_LIBOBS = "Objects in Library"
|
||||
PDT_DES_LIBCOLS = "Collections in Library"
|
||||
PDT_DES_LIBMATS = "Materials in Library"
|
||||
PDT_DES_LIBMODE = "Library Mode"
|
||||
PDT_DES_LIBSER = "Enter A Search String (Contained)"
|
||||
PDT_DES_OBORDER = "Object Order to Lines"
|
||||
PDT_DES_VALIDLET = "Valid 1st letters; C D E G N P S V, Valid 2nd letters: A D I O P"
|
||||
PDT_DES_OUTPUT = "Output for Maths Operations"
|
||||
PDT_DES_PPLOC = "Location of PivotPoint"
|
||||
PDT_DES_PPSCALEFAC = "Scale Factors"
|
||||
PDT_DES_PPSIZE = "Pivot Size Factor"
|
||||
PDT_DES_PPWIDTH = "Pivot Line Width in Pixels"
|
||||
PDT_DES_PPTRANS = "Pivot Point Transparency"
|
||||
PDT_DES_PIVOTDIS = "Input Distance to Compare with Sytem Distance to set Scales"
|
||||
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"
|
||||
|
|
|
@ -26,7 +26,7 @@ import bmesh
|
|||
from bpy.types import Operator, SpaceView3D
|
||||
from mathutils import Vector, Matrix
|
||||
from math import pi
|
||||
from .pdt_functions import view_coords, drawCallback3D
|
||||
from .pdt_functions import view_coords, draw_callback_3d
|
||||
from .pdt_msg_strings import (
|
||||
PDT_CON_AREYOURSURE,
|
||||
PDT_ERR_EDIT_MODE,
|
||||
|
@ -60,7 +60,7 @@ class PDT_OT_ModalDrawOperator(bpy.types.Operator):
|
|||
|
||||
if PDT_OT_ModalDrawOperator._handle is None:
|
||||
PDT_OT_ModalDrawOperator._handle = SpaceView3D.draw_handler_add(
|
||||
drawCallback3D, (self, context), "WINDOW", "POST_VIEW"
|
||||
draw_callback_3d, (self, context), "WINDOW", "POST_VIEW"
|
||||
)
|
||||
context.window_manager.pdt_run_opengl = True
|
||||
|
||||
|
@ -103,9 +103,8 @@ class PDT_OT_ModalDrawOperator(bpy.types.Operator):
|
|||
context.area.tag_redraw()
|
||||
|
||||
return {"FINISHED"}
|
||||
else:
|
||||
self.report({"ERROR"}, PDT_ERR_NO3DVIEW)
|
||||
|
||||
self.report({"ERROR"}, PDT_ERR_NO3DVIEW)
|
||||
return {"CANCELLED"}
|
||||
|
||||
|
||||
|
@ -117,10 +116,11 @@ class PDT_OT_ViewPlaneRotate(Operator):
|
|||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
ob = context.object
|
||||
if ob is None:
|
||||
"""Check Onject Status."""
|
||||
obj = context.object
|
||||
if obj is None:
|
||||
return False
|
||||
return all([bool(ob), ob.type == "MESH", ob.mode == "EDIT"])
|
||||
return all([bool(obj), obj.type == "MESH", obj.mode == "EDIT"])
|
||||
|
||||
|
||||
def execute(self, context):
|
||||
|
@ -170,10 +170,11 @@ class PDT_OT_ViewPlaneScale(Operator):
|
|||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
ob = context.object
|
||||
if ob is None:
|
||||
"""Check Onject Status."""
|
||||
obj = context.object
|
||||
if obj is None:
|
||||
return False
|
||||
return all([bool(ob), ob.type == "MESH", ob.mode == "EDIT"])
|
||||
return all([bool(obj), obj.type == "MESH", obj.mode == "EDIT"])
|
||||
|
||||
|
||||
def execute(self, context):
|
||||
|
@ -205,17 +206,17 @@ class PDT_OT_ViewPlaneScale(Operator):
|
|||
bm = bmesh.from_edit_mesh(obj.data)
|
||||
verts = verts = [v for v in bm.verts if v.select]
|
||||
for v in verts:
|
||||
dx = (pg.pivot_loc.x - obj.matrix_world.decompose()[0].x - v.co.x) * (
|
||||
delta_x = (pg.pivot_loc.x - obj.matrix_world.decompose()[0].x - v.co.x) * (
|
||||
1 - pg.pivot_scale.x
|
||||
)
|
||||
dy = (pg.pivot_loc.y - obj.matrix_world.decompose()[0].y - v.co.y) * (
|
||||
delta_y = (pg.pivot_loc.y - obj.matrix_world.decompose()[0].y - v.co.y) * (
|
||||
1 - pg.pivot_scale.y
|
||||
)
|
||||
dz = (pg.pivot_loc.z - obj.matrix_world.decompose()[0].z - v.co.z) * (
|
||||
delta_z = (pg.pivot_loc.z - obj.matrix_world.decompose()[0].z - v.co.z) * (
|
||||
1 - pg.pivot_scale.z
|
||||
)
|
||||
dv = Vector((dx, dy, dz))
|
||||
v.co = v.co + dv
|
||||
delta_v = Vector((delta_x, delta_y, delta_z))
|
||||
v.co = v.co + delta_v
|
||||
bmesh.update_edit_mesh(obj.data)
|
||||
return {"FINISHED"}
|
||||
|
||||
|
@ -276,10 +277,11 @@ class PDT_OT_PivotSelected(Operator):
|
|||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
ob = context.object
|
||||
if ob is None:
|
||||
"""Check Onject Status."""
|
||||
obj = context.object
|
||||
if obj is None:
|
||||
return False
|
||||
return all([bool(ob), ob.type == "MESH", ob.mode == "EDIT"])
|
||||
return all([bool(obj), obj.type == "MESH", obj.mode == "EDIT"])
|
||||
|
||||
|
||||
def execute(self, context):
|
||||
|
@ -313,9 +315,9 @@ class PDT_OT_PivotSelected(Operator):
|
|||
pg.pivot_loc = scene.cursor.location
|
||||
scene.cursor.location = old_cursor_loc
|
||||
return {"FINISHED"}
|
||||
else:
|
||||
self.report({"ERROR"}, PDT_ERR_NO_SEL_GEOM)
|
||||
return {"FINISHED"}
|
||||
|
||||
self.report({"ERROR"}, PDT_ERR_NO_SEL_GEOM)
|
||||
return {"FINISHED"}
|
||||
|
||||
|
||||
class PDT_OT_PivotOrigin(Operator):
|
||||
|
@ -326,10 +328,11 @@ class PDT_OT_PivotOrigin(Operator):
|
|||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
ob = context.object
|
||||
if ob is None:
|
||||
"""Check Onject Status."""
|
||||
obj = context.object
|
||||
if obj is None:
|
||||
return False
|
||||
return all([bool(ob), ob.type == "MESH"])
|
||||
return all([bool(obj), obj.type == "MESH"])
|
||||
|
||||
def execute(self, context):
|
||||
"""Moves Pivot Point to Object Origin.
|
||||
|
@ -362,10 +365,11 @@ class PDT_OT_PivotWrite(Operator):
|
|||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
ob = context.object
|
||||
if ob is None:
|
||||
"""Check Onject Status."""
|
||||
obj = context.object
|
||||
if obj is None:
|
||||
return False
|
||||
return all([bool(ob), ob.type == "MESH"])
|
||||
return all([bool(obj), obj.type == "MESH"])
|
||||
|
||||
def execute(self, context):
|
||||
"""Writes Pivot Point Location to Object's Custom Properties.
|
||||
|
@ -408,10 +412,11 @@ class PDT_OT_PivotRead(Operator):
|
|||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
ob = context.object
|
||||
if ob is None:
|
||||
"""Check Onject Status."""
|
||||
obj = context.object
|
||||
if obj is None:
|
||||
return False
|
||||
return all([bool(ob), ob.type == "MESH"])
|
||||
return all([bool(obj), obj.type == "MESH"])
|
||||
|
||||
def execute(self, context):
|
||||
"""Reads Pivot Point Location from Object's Custom Properties.
|
||||
|
@ -438,6 +443,6 @@ class PDT_OT_PivotRead(Operator):
|
|||
if "PDT_PP_LOC" in obj:
|
||||
pg.pivot_loc = obj["PDT_PP_LOC"]
|
||||
return {"FINISHED"}
|
||||
else:
|
||||
self.report({"ERROR"}, PDT_ERR_NOPPLOC)
|
||||
return {"FINISHED"}
|
||||
|
||||
self.report({"ERROR"}, PDT_ERR_NOPPLOC)
|
||||
return {"FINISHED"}
|
||||
|
|
|
@ -32,6 +32,8 @@ from .pdt_functions import debug, euler_to_quaternion
|
|||
|
||||
|
||||
class PDT_OT_ViewRot(Operator):
|
||||
"""Rotate View by Absolute Coordinates."""
|
||||
|
||||
bl_idname = "pdt.viewrot"
|
||||
bl_label = "Rotate View"
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
|
@ -58,13 +60,15 @@ class PDT_OT_ViewRot(Operator):
|
|||
roll_value = euler_to_quaternion(
|
||||
pg.rotation_coords.x * pi / 180,
|
||||
pg.rotation_coords.y * pi / 180,
|
||||
pg.rotation_coords.z * pi / 180
|
||||
pg.rotation_coords.z * pi / 180,
|
||||
)
|
||||
context.region_data.view_rotation = roll_value
|
||||
return {"FINISHED"}
|
||||
|
||||
|
||||
class PDT_OT_vRotL(Operator):
|
||||
class PDT_OT_ViewRotL(Operator):
|
||||
"""Rotate View Left."""
|
||||
|
||||
bl_idname = "pdt.viewleft"
|
||||
bl_label = "Rotate Left"
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
|
@ -90,7 +94,9 @@ class PDT_OT_vRotL(Operator):
|
|||
return {"FINISHED"}
|
||||
|
||||
|
||||
class PDT_OT_vRotR(Operator):
|
||||
class PDT_OT_ViewRotR(Operator):
|
||||
"""Rotate View Right."""
|
||||
|
||||
bl_idname = "pdt.viewright"
|
||||
bl_label = "Rotate Right"
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
|
@ -117,7 +123,9 @@ class PDT_OT_vRotR(Operator):
|
|||
return {"FINISHED"}
|
||||
|
||||
|
||||
class PDT_OT_vRotU(Operator):
|
||||
class PDT_OT_ViewRotU(Operator):
|
||||
"""Rotate View Up."""
|
||||
|
||||
bl_idname = "pdt.viewup"
|
||||
bl_label = "Rotate Up"
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
|
@ -144,7 +152,9 @@ class PDT_OT_vRotU(Operator):
|
|||
return {"FINISHED"}
|
||||
|
||||
|
||||
class PDT_OT_vRotD(Operator):
|
||||
class PDT_OT_ViewRotD(Operator):
|
||||
"""Rotate View Down."""
|
||||
|
||||
bl_idname = "pdt.viewdown"
|
||||
bl_label = "Rotate Down"
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
|
@ -171,7 +181,9 @@ class PDT_OT_vRotD(Operator):
|
|||
return {"FINISHED"}
|
||||
|
||||
|
||||
class PDT_OT_vRoll(Operator):
|
||||
class PDT_OT_ViewRoll(Operator):
|
||||
"""Roll View."""
|
||||
|
||||
bl_idname = "pdt.viewroll"
|
||||
bl_label = "Roll View"
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
|
@ -198,7 +210,9 @@ class PDT_OT_vRoll(Operator):
|
|||
return {"FINISHED"}
|
||||
|
||||
|
||||
class PDT_OT_viso(Operator):
|
||||
class PDT_OT_ViewIso(Operator):
|
||||
"""Set View Isometric."""
|
||||
|
||||
bl_idname = "pdt.viewiso"
|
||||
bl_label = "Isometric View"
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
|
@ -216,17 +230,17 @@ class PDT_OT_viso(Operator):
|
|||
Status Set.
|
||||
"""
|
||||
# Try working this out in your head!
|
||||
context.region_data.view_rotation = Quaternion(
|
||||
(0.8205, 0.4247, -0.1759, -0.3399)
|
||||
)
|
||||
context.region_data.view_perspective = 'ORTHO'
|
||||
context.region_data.view_rotation = Quaternion((0.8205, 0.4247, -0.1759, -0.3399))
|
||||
context.region_data.view_perspective = "ORTHO"
|
||||
return {"FINISHED"}
|
||||
|
||||
|
||||
class PDT_OT_Reset3DView(Operator):
|
||||
"""Reset Views to Factory Default."""
|
||||
|
||||
bl_idname = "pdt.reset_3d_view"
|
||||
bl_label = "Reset 3D View"
|
||||
bl_options = {'REGISTER', 'UNDO'}
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
bl_description = "Reset 3D View to Blender Defaults."
|
||||
|
||||
def execute(self, context):
|
||||
|
@ -241,13 +255,15 @@ class PDT_OT_Reset3DView(Operator):
|
|||
|
||||
# The default view_distance to the origin when starting up Blender
|
||||
default_view_distance = 17.986562728881836
|
||||
default_view_distance = bpy.data.screens['Layout'].areas[-1].spaces[0].region_3d.view_distance
|
||||
default_view_distance = (
|
||||
bpy.data.screens["Layout"].areas[-1].spaces[0].region_3d.view_distance
|
||||
)
|
||||
# The default view_matrix when starting up Blender
|
||||
default_view_matrix = (
|
||||
(0.41, -0.4017, 0.8188, 0.0),
|
||||
(0.912, 0.1936, -0.3617, 0.0),
|
||||
(-0.0133, 0.8950, 0.4458, 0.0),
|
||||
(0.0, 0.0, -17.9866, 1.0)
|
||||
(0.0, 0.0, -17.9866, 1.0),
|
||||
)
|
||||
|
||||
view = context.region_data
|
||||
|
@ -270,4 +286,4 @@ class PDT_OT_Reset3DView(Operator):
|
|||
view.update()
|
||||
debug(f"view_matrix AFTER reset:\n{view.view_matrix}")
|
||||
|
||||
return {'FINISHED'}
|
||||
return {"FINISHED"}
|
||||
|
|
|
@ -29,14 +29,18 @@ from mathutils.geometry import intersect_line_line as LineIntersect
|
|||
import itertools
|
||||
from collections import defaultdict
|
||||
from . import pdt_cad_module as cm
|
||||
from .pdt_functions import oops
|
||||
from .pdt_msg_strings import (
|
||||
PDT_ERR_EDOB_MODE
|
||||
)
|
||||
|
||||
|
||||
def order_points(edge, point_list):
|
||||
"""Order these edges from distance to v1, then sandwich the sorted list with v1, v2."""
|
||||
v1, v2 = edge
|
||||
|
||||
def dist(co):
|
||||
return (v1 - co).length
|
||||
def dist(coord):
|
||||
return (v1 - coord).length
|
||||
|
||||
point_list = sorted(point_list, key=dist)
|
||||
return [v1] + point_list + [v2]
|
||||
|
@ -89,8 +93,8 @@ def get_intersection_dictionary(bm, edge_indices):
|
|||
|
||||
permutations = get_valid_permutations(bm, edge_indices)
|
||||
|
||||
k = defaultdict(list)
|
||||
d = defaultdict(list)
|
||||
list_k = defaultdict(list)
|
||||
list_d = defaultdict(list)
|
||||
|
||||
for edges in permutations:
|
||||
raw_vert_indices = cm.vertex_indices_from_edges_tuple(bm, edges)
|
||||
|
@ -103,35 +107,35 @@ def get_intersection_dictionary(bm, edge_indices):
|
|||
continue
|
||||
|
||||
# reaches this point only when an intersection happens on both edges.
|
||||
[k[edge].append(points[0]) for edge in edges]
|
||||
[list_k[edge].append(points[0]) for edge in edges]
|
||||
|
||||
# k will contain a dict of edge indices and points found on those edges.
|
||||
for edge_idx, unordered_points in k.items():
|
||||
for edge_idx, unordered_points in list_k.items():
|
||||
tv1, tv2 = bm.edges[edge_idx].verts
|
||||
v1 = bm.verts[tv1.index].co
|
||||
v2 = bm.verts[tv2.index].co
|
||||
ordered_points = order_points((v1, v2), unordered_points)
|
||||
d[edge_idx].extend(ordered_points)
|
||||
list_d[edge_idx].extend(ordered_points)
|
||||
|
||||
return d
|
||||
return list_d
|
||||
|
||||
|
||||
def update_mesh(bm, int_dict):
|
||||
"""Make new geometry (delete old first)."""
|
||||
|
||||
oe = bm.edges
|
||||
ov = bm.verts
|
||||
orig_e = bm.edges
|
||||
orig_v = bm.verts
|
||||
|
||||
new_verts = []
|
||||
collect = new_verts.extend
|
||||
for _, point_list in int_dict.items():
|
||||
num_edges_to_add = len(point_list) - 1
|
||||
for i in range(num_edges_to_add):
|
||||
a = ov.new(point_list[i])
|
||||
b = ov.new(point_list[i + 1])
|
||||
oe.new((a, b))
|
||||
coord_a = orig_v.new(point_list[i])
|
||||
coord_b = orig_v.new(point_list[i + 1])
|
||||
orig_e.new((coord_a, coord_b))
|
||||
bm.normal_update()
|
||||
collect([a, b])
|
||||
collect([coord_a, coord_b])
|
||||
|
||||
bmesh.ops.delete(bm, geom=[edge for edge in bm.edges if edge.select], context="EDGES")
|
||||
bmesh.ops.remove_doubles(bm, verts=bm.verts, dist=0.0001)
|
||||
|
@ -178,6 +182,7 @@ def intersect_all(context):
|
|||
|
||||
bmesh.update_edit_mesh(obj.data)
|
||||
else:
|
||||
pg.error = f"{PDT_ERR_EDOB_MODE},{obj.mode})"
|
||||
context.window_manager.popup_menu(oops, title="Error", icon="ERROR")
|
||||
return
|
||||
|
||||
|
@ -196,10 +201,19 @@ class PDT_OT_IntersectAllEdges(bpy.types.Operator):
|
|||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
ob = context.active_object
|
||||
if ob is None:
|
||||
"""Check to see object is in correct condidtion.
|
||||
|
||||
Args:
|
||||
Class,
|
||||
context: Blender bpy.context instance.
|
||||
|
||||
Returns:
|
||||
Boolean
|
||||
"""
|
||||
obj = context.active_object
|
||||
if obj is None:
|
||||
return False
|
||||
return ob is not None and ob.type == "MESH" and ob.mode == "EDIT"
|
||||
return obj is not None and obj.type == "MESH" and obj.mode == "EDIT"
|
||||
|
||||
def execute(self, context):
|
||||
"""Computes All intersections with Crossing Geometry.
|
||||
|
|
Loading…
Reference in New Issue