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

git.blender.org/blender-addons.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRune Morling <ermo.blender.org@spammesenseless.net>2020-01-15 00:35:18 +0300
committerRune Morling <ermo.blender.org@spammesenseless.net>2020-01-15 00:35:18 +0300
commitff72807a80529f94e434b06f14b8c0a2f185c6f3 (patch)
treef711e38c437854eeebcc3b2095b012ce699435e6
parent4e13b241c85652ea2309d76f717f975e37e7c091 (diff)
parent7ae27d2b019c1320bdda28c319036236a15520b5 (diff)
PDT: Merge branch 'blender-v2.82-release' fixes
-rw-r--r--blenderkit/__init__.py28
-rw-r--r--blenderkit/bg_blender.py2
-rw-r--r--blenderkit/bkit_oauth.py4
-rw-r--r--blenderkit/categories.py33
-rw-r--r--blenderkit/download.py2
-rw-r--r--blenderkit/search.py34
-rw-r--r--blenderkit/ui.py19
-rw-r--r--blenderkit/ui_panels.py43
-rw-r--r--precision_drawing_tools/__init__.py22
-rw-r--r--precision_drawing_tools/pdt_command.py122
-rw-r--r--precision_drawing_tools/pdt_design.py110
-rw-r--r--precision_drawing_tools/pdt_functions.py2
-rw-r--r--precision_drawing_tools/pdt_library.py2
-rw-r--r--precision_drawing_tools/pdt_menus.py75
-rw-r--r--precision_drawing_tools/pdt_msg_strings.py11
-rw-r--r--precision_drawing_tools/pdt_view.py26
-rw-r--r--rigify/rig_ui_template.py2
17 files changed, 379 insertions, 158 deletions
diff --git a/blenderkit/__init__.py b/blenderkit/__init__.py
index 5409a441..5cecc7b9 100644
--- a/blenderkit/__init__.py
+++ b/blenderkit/__init__.py
@@ -19,8 +19,8 @@
bl_info = {
"name": "BlenderKit Asset Library",
"author": "Vilem Duha, Petr Dlouhy",
- "version": (1, 0, 28),
- "blender": (2, 80, 0),
+ "version": (1, 0, 29),
+ "blender": (2, 82, 0),
"location": "View3D > Properties > BlenderKit",
"description": "Online BlenderKit library (materials, models, brushes and more)",
"warning": "",
@@ -257,11 +257,11 @@ def asset_type_callback(self, context):
)
else:
items = (
- ('MODEL', 'Upload Model', 'Browse models', 'OBJECT_DATAMODE', 0),
+ ('MODEL', 'Upload Model', 'Upload a model to BlenderKit', 'OBJECT_DATAMODE', 0),
# ('SCENE', 'SCENE', 'Browse scenes', 'SCENE_DATA', 1),
- ('MATERIAL', 'Uplaod Material', 'Browse materials', 'MATERIAL', 2),
+ ('MATERIAL', 'Uplaod Material', 'Upload a material to BlenderKit', 'MATERIAL', 2),
# ('TEXTURE', 'Texture', 'Browse textures', 'TEXTURE', 3),
- ('BRUSH', 'Upload Brush', 'Browse brushes', 'BRUSH_DATA', 3)
+ ('BRUSH', 'Upload Brush', 'Upload a brush to BlenderKit', 'BRUSH_DATA', 3)
)
return items
@@ -269,9 +269,9 @@ class BlenderKitUIProps(PropertyGroup):
down_up: EnumProperty(
name="Download vs Upload",
items=(
- ('SEARCH', 'Search', 'Searching is active', 'VIEWZOOM', 0),
- ('UPLOAD', 'Upload', 'Uploads are active', 'COPYDOWN', 1),
- # ('RATING', 'Rating', 'Rating is active', 'SOLO_ON', 2)
+ ('SEARCH', 'Search', 'Sctivate searching', 'VIEWZOOM', 0),
+ ('UPLOAD', 'Upload', 'Activate uploading', 'COPYDOWN', 1),
+ # ('RATING', 'Rating', 'Activate rating', 'SOLO_ON', 2)
),
description="BLenderKit",
default="SEARCH",
@@ -813,19 +813,19 @@ class BlenderKitModelUploadProps(PropertyGroup, BlenderKitCommonUploadProps):
manufacturer: StringProperty(
name="Manufacturer",
- description="Manufacturer, company making a design peace or product",
+ description="Manufacturer, company making a design peace or product. Not you",
default="",
)
designer: StringProperty(
name="Designer",
- description="Author of the original design piece depicted",
+ description="Author of the original design piece depicted. Usually not you",
default="",
)
design_collection: StringProperty(
name="Design Collection",
- description="Fill if this piece is part of a design collection",
+ description="Fill if this piece is part of a real world design collection",
default="",
)
@@ -1217,8 +1217,8 @@ class BlenderKitModelSearchProps(PropertyGroup, BlenderKitCommonSearchProps):
append_method: EnumProperty(
name="Import Method",
items=(
- ('LINK_COLLECTION', 'Link Collection', ''),
- ('APPEND_OBJECTS', 'Append Objects', ''),
+ ('LINK_COLLECTION', 'Link', 'Link Collection'),
+ ('APPEND_OBJECTS', 'Append', 'Append as Objects'),
),
description="choose if the assets will be linked or appended",
default="LINK_COLLECTION"
@@ -1343,7 +1343,7 @@ class BlenderKitAddonPreferences(AddonPreferences):
login_attempt: BoolProperty(
name="Login/Signup attempt",
- description="When this is on, BlenderKit is trying to connect and login.",
+ description="When this is on, BlenderKit is trying to connect and login",
default=False
)
diff --git a/blenderkit/bg_blender.py b/blenderkit/bg_blender.py
index 9d3521e4..e8ccb04d 100644
--- a/blenderkit/bg_blender.py
+++ b/blenderkit/bg_blender.py
@@ -155,7 +155,7 @@ process_sources = (
class KillBgProcess(bpy.types.Operator):
- '''Remove processes in background.'''
+ '''Remove processes in background'''
bl_idname = "object.kill_bg_process"
bl_label = "Kill Background Process"
bl_options = {'REGISTER'}
diff --git a/blenderkit/bkit_oauth.py b/blenderkit/bkit_oauth.py
index 259fedf5..dc272104 100644
--- a/blenderkit/bkit_oauth.py
+++ b/blenderkit/bkit_oauth.py
@@ -99,7 +99,7 @@ def write_tokens(auth_token, refresh_token, oauth_response):
class RegisterLoginOnline(bpy.types.Operator):
- """Bring linked object hierarchy to scene and make it editable."""
+ """Login online on BlenderKit webpage"""
bl_idname = "wm.blenderkit_login"
bl_label = "BlenderKit login or signup"
@@ -124,7 +124,7 @@ class RegisterLoginOnline(bpy.types.Operator):
class Logout(bpy.types.Operator):
- """Bring linked object hierarchy to scene and make it editable."""
+ """Logout from BlenderKit immediately"""
bl_idname = "wm.blenderkit_logout"
bl_label = "BlenderKit logout"
diff --git a/blenderkit/categories.py b/blenderkit/categories.py
index 1d411499..8983e3ad 100644
--- a/blenderkit/categories.py
+++ b/blenderkit/categories.py
@@ -30,6 +30,7 @@ import requests
import json
import os
import bpy
+import time
import shutil
import threading
@@ -106,22 +107,34 @@ def load_categories():
except:
print('categories failed to read')
-def fetch_categories(API_key):
+#
+catfetch_counter = 0
+
+
+def fetch_categories(API_key, force = False):
url = paths.get_api_url() + 'categories/'
headers = utils.get_headers(API_key)
tempdir = paths.get_temp_dir()
categories_filepath = os.path.join(tempdir, 'categories.json')
+ catfile_age = time.time() - os.path.getmtime(categories_filepath)
+ # global catfetch_counter
+ # catfetch_counter += 1
+ # utils.p('fetching categories: ', catfetch_counter)
+ # utils.p('age of cat file', catfile_age)
try:
- r = rerequests.get(url, headers=headers)
- rdata = r.json()
- categories = rdata['results']
- fix_category_counts(categories)
- # filter_categories(categories) #TODO this should filter categories for search, but not for upload. by now off.
- with open(categories_filepath, 'w') as s:
- json.dump(categories, s, indent=4)
+ # read categories only once per day maximum, or when forced to do so.
+ if catfile_age > 86400 or force:
+ utils.p('requesting categories')
+ r = rerequests.get(url, headers=headers)
+ rdata = r.json()
+ categories = rdata['results']
+ fix_category_counts(categories)
+ # filter_categories(categories) #TODO this should filter categories for search, but not for upload. by now off.
+ with open(categories_filepath, 'w') as s:
+ json.dump(categories, s, indent=4)
tasks_queue.add_task((load_categories, ()))
except Exception as e:
utils.p('category fetching failed')
@@ -131,6 +144,6 @@ def fetch_categories(API_key):
shutil.copy(source_path, categories_filepath)
-def fetch_categories_thread(API_key):
- cat_thread = threading.Thread(target=fetch_categories, args=([API_key]), daemon=True)
+def fetch_categories_thread(API_key, force = False):
+ cat_thread = threading.Thread(target=fetch_categories, args=([API_key, force]), daemon=True)
cat_thread.start()
diff --git a/blenderkit/download.py b/blenderkit/download.py
index d652807e..c4a14ecd 100644
--- a/blenderkit/download.py
+++ b/blenderkit/download.py
@@ -823,7 +823,7 @@ asset_types = (
class BlenderkitKillDownloadOperator(bpy.types.Operator):
- """Kill a download."""
+ """Kill a download"""
bl_idname = "scene.blenderkit_download_kill"
bl_label = "BlenderKit Kill Asset Download"
bl_options = {'REGISTER', 'INTERNAL'}
diff --git a/blenderkit/search.py b/blenderkit/search.py
index 9923610f..87bf45da 100644
--- a/blenderkit/search.py
+++ b/blenderkit/search.py
@@ -110,9 +110,10 @@ def fetch_server_data():
len(user_preferences.api_key) < 38 and \
user_preferences.api_key_timeout < time.time() + 3600:
bkit_oauth.refresh_token_thread()
- if api_key != '':
+ if api_key != '' and bpy.context.window_manager.get('bkit profile') == None:
get_profile()
- categories.fetch_categories_thread(api_key)
+ if bpy.context.window_manager.get('bkit_categories') is None:
+ categories.fetch_categories_thread(api_key)
first_time = True
@@ -327,15 +328,23 @@ def split_subs(text, threshold=40):
# temporarily disable this, to be able to do this in drawing code
text = text.rstrip()
+ text = text.replace('\r\n', '\n')
+
lines = []
while len(text) > threshold:
- i = text.rfind(' ', 0, threshold)
- i1 = text.rfind(',', 0, threshold)
- i2 = text.rfind('.', 0, threshold)
- i = max(i, i1, i2)
- if i <= 0:
- i = threshold
+ #first handle if there's an \n line ending
+ i_rn = text.find('\n')
+ if 1 < i_rn < threshold:
+ i = i_rn
+ text = text.replace('\n','',1)
+ else:
+ i = text.rfind(' ', 0, threshold)
+ i1 = text.rfind(',', 0, threshold)
+ i2 = text.rfind('.', 0, threshold)
+ i = max(i, i1, i2)
+ if i <= 0:
+ i = threshold
lines.append(text[:i])
text = text[i:]
lines.append(text)
@@ -614,6 +623,7 @@ def fetch_author(a_id, api_key):
utils.p(e)
utils.p('finish fetch')
+# profile_counter =0
def get_author(r):
a_id = str(r['author']['id'])
@@ -622,11 +632,13 @@ def get_author(r):
if authors == {}:
bpy.context.window_manager['bkit authors'] = authors
a = authors.get(a_id)
- if a is None or a is '' or \
- (a.get('gravatarHash') is not None and a.get('gravatarImg') is None):
- authors[a_id] = None
+ if a is None:# or a is '' or (a.get('gravatarHash') is not None and a.get('gravatarImg') is None):
+ authors[a_id] = ''
thread = threading.Thread(target=fetch_author, args=(a_id, preferences.api_key), daemon=True)
thread.start()
+ # global profile_counter
+ # profile_counter+=1
+ # print(profile_counter,'author:', a_id)
return a
diff --git a/blenderkit/ui.py b/blenderkit/ui.py
index f8d48b2d..fc9563a9 100644
--- a/blenderkit/ui.py
+++ b/blenderkit/ui.py
@@ -762,7 +762,7 @@ def draw_callback_2d_search(self, context):
ui_props.thumb_size,
img,
1)
- if search_results_orig['count'] - ui_props.scrolloffset > (ui_props.wcount * ui_props.hcount):
+ if search_results_orig['count'] - ui_props.scrolloffset > (ui_props.wcount * ui_props.hcount) + 1:
if ui_props.active_index == -1:
ui_bgl.draw_rect(ui_props.bar_x + ui_props.bar_width - 25,
ui_props.bar_y - ui_props.bar_height, 25,
@@ -841,7 +841,7 @@ def draw_callback_2d_search(self, context):
directory = paths.get_temp_dir('%s_search' % mappingdict[props.asset_type])
sr = s.get('search results')
- if sr != None and ui_props.active_index != -3:
+ if sr != None and -1 < ui_props.active_index < len(sr):
r = sr[ui_props.active_index]
tpath = os.path.join(directory, r['thumbnail'])
@@ -1154,6 +1154,7 @@ def update_ui_size(area, region):
ui.rating_x = ui.bar_x
ui.rating_y = ui.bar_y - ui.bar_height
+
def get_largest_3dview():
maxsurf = 0
maxa = None
@@ -1174,6 +1175,7 @@ def get_largest_3dview():
region = r
return maxw, maxa, region
+
class AssetBarOperator(bpy.types.Operator):
'''runs search and displays the asset bar at the same time'''
bl_idname = "view3d.blenderkit_asset_bar"
@@ -1189,6 +1191,12 @@ class AssetBarOperator(bpy.types.Operator):
description="search only subtree of this category",
default="", options={'SKIP_SAVE'})
+ tooltip: bpy.props.StringProperty(default='runs search and displays the asset bar at the same time')
+
+ @classmethod
+ def description(cls, context, properties):
+ return properties.tooltip
+
def search_more(self):
sro = bpy.context.scene.get('search results orig')
if sro is not None and sro.get('next') is not None:
@@ -1306,7 +1314,7 @@ class AssetBarOperator(bpy.types.Operator):
r = self.region
s = bpy.context.scene
sr = s.get('search results')
-
+ search_results_orig = s.get('search results orig')
# If there aren't any results, we need no interaction(yet)
if sr is None:
return {'PASS_THROUGH'}
@@ -1412,8 +1420,9 @@ class AssetBarOperator(bpy.types.Operator):
else:
ui_props.draw_tooltip = False
- if mx > ui_props.bar_x + ui_props.bar_width - 50 and len(sr) - ui_props.scrolloffset > (
- ui_props.wcount * ui_props.hcount):
+ if mx > ui_props.bar_x + ui_props.bar_width - 50 and search_results_orig[
+ 'count'] - ui_props.scrolloffset > (
+ ui_props.wcount * ui_props.hcount) + 1:
ui_props.active_index = -1
return {'RUNNING_MODAL'}
if mx < ui_props.bar_x + 50 and ui_props.scrolloffset > 0:
diff --git a/blenderkit/ui_panels.py b/blenderkit/ui_panels.py
index 44bd4d2e..b981fbcc 100644
--- a/blenderkit/ui_panels.py
+++ b/blenderkit/ui_panels.py
@@ -270,12 +270,16 @@ def draw_assetbar_show_hide(layout, props):
if ui_props.assetbar_on:
icon = 'HIDE_OFF'
+ ttip = 'Click to Hide Asset Bar'
else:
icon = 'HIDE_ON'
+ ttip = 'Click to Show Asset Bar'
op = layout.operator('view3d.blenderkit_asset_bar', text='', icon=icon)
op.keep_running = False
op.do_search = False
+ op.tooltip = ttip
+
def draw_panel_model_search(self, context):
s = context.scene
@@ -347,8 +351,8 @@ def draw_panel_model_search(self, context):
layout.separator()
layout.label(text='Import method:')
- col = layout.column()
- col.prop(props, 'append_method', expand=True, icon_only=False)
+ row = layout.row()
+ row.prop(props, 'append_method', expand=True, icon_only=False)
layout.prop(props, 'randomize_rotation')
if props.randomize_rotation:
layout.prop(props, 'randomize_rotation_amount')
@@ -681,6 +685,8 @@ class VIEW3D_PT_blenderkit_unified(Panel):
op = layout.operator('view3d.blenderkit_asset_bar', text=text, icon='EXPORT')
op.keep_running = False
op.do_search = False
+ op.tooltip = 'Show/Hide asset preview'
+
e = s.render.engine
if e not in ('CYCLES', 'BLENDER_EEVEE'):
rtext = 'Only Cycles and EEVEE render engines are currently supported. ' \
@@ -767,17 +773,17 @@ class OBJECT_MT_blenderkit_asset_menu(bpy.types.Menu):
op = layout.operator('view3d.blenderkit_search', text='Search Similar')
op.keywords = asset_data['name'] + ' ' + asset_data['description'] + ' ' + ' '.join(asset_data['tags'])
-
- if bpy.context.view_layer.objects.active is not None and ui_props.asset_type == 'MODEL':
- aob = bpy.context.active_object
- op = layout.operator('scene.blenderkit_download', text='Replace Active Models')
- op.asset_type = ui_props.asset_type
- op.asset_index = ui_props.active_index
- op.model_location = aob.location
- op.model_rotation = aob.rotation_euler
- op.target_object = aob.name
- op.material_target_slot = aob.active_material_index
- op.replace = True
+ if asset_data.get('canDownload') != 0:
+ if bpy.context.view_layer.objects.active is not None and ui_props.asset_type == 'MODEL':
+ aob = bpy.context.active_object
+ op = layout.operator('scene.blenderkit_download', text='Replace Active Models')
+ op.asset_type = ui_props.asset_type
+ op.asset_index = ui_props.active_index
+ op.model_location = aob.location
+ op.model_rotation = aob.rotation_euler
+ op.target_object = aob.name
+ op.material_target_slot = aob.active_material_index
+ op.replace = True
wm = bpy.context.window_manager
profile = wm.get('bkit profile')
@@ -870,6 +876,7 @@ class UrlPopupDialog(bpy.types.Operator):
layout = self.layout
label_multiline(layout, text=self.message)
+ layout.active_default = True
op = layout.operator("wm.url_open", text=self.link_text, icon='QUESTION')
op.url = self.url
@@ -968,7 +975,7 @@ class VIEW3D_PT_blenderkit_downloads(Panel):
def header_search_draw(self, context):
- '''Top bar menu in 3d view.'''
+ '''Top bar menu in 3d view'''
layout = self.layout
s = bpy.context.scene
ui_props = s.blenderkitUI
@@ -982,13 +989,7 @@ def header_search_draw(self, context):
layout.separator_spacer()
layout.prop(ui_props, "asset_type", text='', icon='URL')
layout.prop(props, "search_keywords", text="", icon='VIEWZOOM')
- if ui_props.assetbar_on:
- icon = 'HIDE_OFF'
- else:
- icon = 'HIDE_ON'
- op = layout.operator('view3d.blenderkit_asset_bar', text='', icon=icon)
- op.keep_running = False
- op.do_search = False
+ draw_assetbar_show_hide(layout, props)
# We can store multiple preview collections here,
diff --git a/precision_drawing_tools/__init__.py b/precision_drawing_tools/__init__.py
index 1f1d4454..35e55158 100644
--- a/precision_drawing_tools/__init__.py
+++ b/precision_drawing_tools/__init__.py
@@ -29,7 +29,7 @@
bl_info = {
"name": "Precision Drawing Tools (PDT)",
"author": "Alan Odom (Clockmender), Rune Morling (ermo)",
- "version": (1, 1, 6),
+ "version": (1, 1, 8),
"blender": (2, 80, 0),
"location": "View3D > UI > PDT",
"description": "Precision Drawing Tools for Acccurate Modelling",
@@ -83,6 +83,7 @@ from .pdt_msg_strings import (
PDT_DES_FILLETRAD,
PDT_DES_FILLETSEG,
PDT_DES_FILLETVERTS,
+ PDT_DES_FILLINT,
PDT_DES_FLIPANG,
PDT_DES_FLIPPER,
PDT_DES_LIBCOLS,
@@ -96,6 +97,7 @@ from .pdt_msg_strings import (
PDT_DES_OFFDIS,
PDT_DES_OFFPER,
PDT_DES_OPMODE,
+ PDT_DES_OUTPUT,
PDT_DES_PIVOTDIS,
PDT_DES_PPLOC,
PDT_DES_PPSCALEFAC,
@@ -358,6 +360,11 @@ class PDTSceneProperties(PropertyGroup):
update=command_run,
description=PDT_DES_VALIDLET,
)
+ maths_output : FloatProperty(
+ name="Maths output",
+ default=0,
+ description=PDT_DES_OUTPUT,
+ )
error : StringProperty(name="Error", default="")
# Was pivot* -- is now pivot_*
@@ -413,6 +420,11 @@ class PDTSceneProperties(PropertyGroup):
default=True,
description=PDT_DES_FILLETVERTS,
)
+ fillet_int : BoolProperty(
+ name="Intersect",
+ default=False,
+ description=PDT_DES_FILLINT,
+ )
class PDTPreferences(AddonPreferences):
@@ -430,6 +442,12 @@ class PDTPreferences(AddonPreferences):
description="NOTE: Does not enable debugging globally in Blender (only in PDT scripts)"
)
+ pdt_ui_width : IntProperty(
+ name='UI Width Cut-off',
+ default=350,
+ description="Cutoff width for shrinking items per line in menus"
+ )
+
def draw(self, context):
layout = self.layout
@@ -437,6 +455,7 @@ class PDTPreferences(AddonPreferences):
row1 = box.row()
row2 = box.row()
row1.prop(self, "debug")
+ row1.prop(self, "pdt_ui_width")
row2.prop(self, "pdt_library_path")
@@ -449,6 +468,7 @@ classes = (
PDTSceneProperties,
PDTPreferences,
pdt_bix.PDT_OT_LineOnBisection,
+ pdt_command.PDT_OT_CommandReRun,
pdt_design.PDT_OT_PlacementAbs,
pdt_design.PDT_OT_PlacementDelta,
pdt_design.PDT_OT_PlacementDis,
diff --git a/precision_drawing_tools/pdt_command.py b/precision_drawing_tools/pdt_command.py
index 423bc83c..6b433fcc 100644
--- a/precision_drawing_tools/pdt_command.py
+++ b/precision_drawing_tools/pdt_command.py
@@ -23,12 +23,14 @@
#
import bpy
import bmesh
+from bpy.types import Operator
from mathutils import Vector
import math
from .pdt_functions import (
debug,
disAng,
getPercent,
+ intersection,
objCheck,
oops,
updateSel,
@@ -85,9 +87,11 @@ def pdt_help(self, context):
label(text="- Fillet Options:")
label(text="v: Fillet Vertices")
label(text="e: Fillet Edges")
+ label(text="i: Fillet & Intersect 2 Disconnected Edges")
label(text="- Math Options:")
label(text="x, y, z: Send result to X, Y and Z input fields in PDT Design")
label(text="d, a, p: Send result to Distance, Angle or Percent input field in PDT Design")
+ label(text="o: Send Maths Calculation to Output")
label(text="")
label(text="Note that commands are case-insensitive: ED = Ed = eD = ed")
label(text="")
@@ -102,6 +106,26 @@ def pdt_help(self, context):
label(text="'- Segments: 4 (int) -- choosing an even amount of segments gives better geometry")
label(text="'- Profile: 0.5 (float[0.0;1.0]) -- 0.5 (default) yields a circular, convex shape")
+class PDT_OT_CommandReRun(Operator):
+ """Repeat Current Displayed Command."""
+
+ bl_idname = "pdt.command_rerun"
+ bl_label = "Re-run Current Command"
+ bl_options = {"REGISTER", "UNDO"}
+
+ def execute(self, context):
+ """Repeat Current Command Line Input.
+
+ Args:
+ context: Blender bpy.context instance.
+
+ Returns:
+ Nothing.
+ """
+ command_run(self, context)
+ return {"FINISHED"}
+
+
def command_run(self, context):
"""Run Command String as input into Command Line.
@@ -129,7 +153,7 @@ def command_run(self, context):
Valid Second Letters (as 'mode' - pg.command[1])
A = Absolute XYZ, D = Delta XYZ, I = Distance at Angle, P = Percent
- X = X Delta, Y = Y, Delta Z, = Z Delta (Maths Operation only)
+ X = X Delta, Y = Y, Delta Z, = Z Delta, O = Output (Maths Operation only)
V = Vertex Bevel, E = Edge Bevel
Capitals and lower case letters are both allowed
@@ -145,22 +169,22 @@ def command_run(self, context):
Example; madegrees(atan(3/4)) - sets PDT Angle to smallest angle of 3,4,5 Triangle;
(36.8699 degrees)
- This is why all Math functions are imported
-
Returns:
Nothing.
"""
scene = context.scene
pg = scene.pdt_pg
- cmd = pg.command
+ cmd = pg.command.strip()
- if cmd.strip() == "?" or cmd.lower().strip() == "help":
+ if cmd == "?" or cmd.lower() == "help":
# fmt: off
context.window_manager.popup_menu(pdt_help, title="PDT Command Line Help", icon="INFO")
# fmt: on
return
- if len(cmd) < 3:
+ elif cmd == "":
+ return
+ elif len(cmd) < 3:
pg.error = PDT_ERR_CHARS_NUM
context.window_manager.popup_menu(oops, title="Error", icon="ERROR")
return
@@ -170,7 +194,7 @@ def command_run(self, context):
context.window_manager.popup_menu(oops, title="Error", icon="ERROR")
return
mode = cmd[1].lower()
- if mode not in {"a", "d", "e", "g", "i", "p", "v", "x", "y", "z"}:
+ if mode not in {"a", "d", "e", "g", "i", "o", "p", "v", "x", "y", "z"}:
pg.error = PDT_ERR_BADSLETTER
context.window_manager.popup_menu(oops, title="Error", icon="ERROR")
return
@@ -178,16 +202,13 @@ def command_run(self, context):
# --------------
# Math Operation
if oper == "M":
- if mode not in {"x", "y", "z", "d", "a", "p"}:
+ if mode not in {"x", "y", "z", "d", "a", "p", "o"}:
pg.error = f"{mode} {PDT_ERR_NON_VALID} Maths)"
context.window_manager.popup_menu(oops, title="Error", icon="ERROR")
return
exp = cmd[2:]
namespace = {}
namespace.update(vars(math))
- if "," in exp:
- pg.error = PDT_ERR_NOCOMMAS
- context.window_manager.popup_menu(oops, title="Error", icon="ERROR")
try:
num = eval(exp, namespace, namespace)
except ValueError:
@@ -206,10 +227,12 @@ def command_run(self, context):
pg.angle = num
elif mode == "p":
pg.percent = num
+ elif mode == "o":
+ pg.maths_output = num
return
- # "x"/"y"/"z" modes are only legal for Math Operation
+ # "o"/"x"/"y"/"z" modes are only legal for Math Operation
else:
- if mode in {"x", "y", "z"}:
+ if mode in {"o", "x", "y", "z"}:
pg.error = PDT_ERR_BADCOORDL
context.window_manager.popup_menu(oops, title="Error", icon="ERROR")
return
@@ -250,6 +273,16 @@ def command_run(self, context):
pg.error = f"'{mode}' {PDT_ERR_NON_VALID} '{oper}'"
context.window_manager.popup_menu(oops, title="Error", icon="ERROR")
return
+ if mode in {"d","i"}:
+ if len(bm.select_history) == 0:
+ if len(bm.verts) == 0:
+ pg.error = PDT_ERR_NO_SEL_GEOM
+ context.window_manager.popup_menu(oops, title="Error", icon="ERROR")
+ return
+ else:
+ verts = bm.verts
+ else:
+ verts = bm.select_history
# Absolute/Global Coordinates
if mode == "a":
if len(vals) != 3:
@@ -277,10 +310,10 @@ def command_run(self, context):
if obj.mode == "EDIT":
if oper == "C":
scene.cursor.location = (
- bm.select_history[-1].co + obj_loc + vector_delta
+ verts[-1].co + obj_loc + vector_delta
)
else:
- pg.pivot_loc = bm.select_history[-1].co + obj_loc + vector_delta
+ pg.pivot_loc = verts[-1].co + obj_loc + vector_delta
elif obj.mode == "OBJECT":
if oper == "C":
scene.cursor.location = obj_loc + vector_delta
@@ -302,10 +335,10 @@ def command_run(self, context):
if obj.mode == "EDIT":
if oper == "C":
scene.cursor.location = (
- bm.select_history[-1].co + obj_loc + vector_delta
+ verts[-1].co + obj_loc + vector_delta
)
else:
- pg.pivot_loc = bm.select_history[-1].co + obj_loc + vector_delta
+ pg.pivot_loc = verts[-1].co + obj_loc + vector_delta
elif obj.mode == "OBJECT":
if oper == "C":
scene.cursor.location = obj_loc + vector_delta
@@ -422,6 +455,16 @@ def command_run(self, context):
pg.error = PDT_ERR_ADDVEDIT
context.window_manager.popup_menu(oops, title="Error", icon="ERROR")
return
+ if mode in {"d","i"}:
+ if len(bm.select_history) == 0:
+ if len(bm.verts) == 0:
+ pg.error = PDT_ERR_NO_SEL_GEOM
+ context.window_manager.popup_menu(oops, title="Error", icon="ERROR")
+ return
+ else:
+ verts = bm.verts
+ else:
+ verts = bm.select_history
# Absolute/Global Coordinates
if mode == "a":
if len(vals) != 3:
@@ -443,7 +486,7 @@ def command_run(self, context):
context.window_manager.popup_menu(oops, title="Error", icon="ERROR")
return
vector_delta = Vector((float(vals[0]), float(vals[1]), float(vals[2])))
- vNew = bm.select_history[-1].co + vector_delta
+ vNew = verts[-1].co + vector_delta
nVert = bm.verts.new(vNew)
for v in [v for v in bm.verts if v.select]:
v.select_set(False)
@@ -451,13 +494,13 @@ def command_run(self, context):
bmesh.update_edit_mesh(obj.data)
bm.select_history.clear()
# Direction/Polar Coordinates
- elif mode == "d":
+ elif mode == "i":
if len(vals) != 2:
pg.error = PDT_ERR_BAD2VALS
context.window_manager.popup_menu(oops, title="Error", icon="ERROR")
return
vector_delta = disAng(vals, flip_a, plane, scene)
- vNew = bm.select_history[-1].co + vector_delta
+ vNew = verts[-1].co + vector_delta
nVert = bm.verts.new(vNew)
for v in [v for v in bm.verts if v.select]:
v.select_set(False)
@@ -670,7 +713,7 @@ def command_run(self, context):
# Percent Options
elif mode == "p":
vector_delta = getPercent(obj, flip_p, float(vals[0]), oper, scene)
- verts = [v for v in bm.verts if v.select]
+ verts = [v for v in bm.verts if v.select].copy()
if len(verts) == 0:
pg.error = PDT_ERR_NO_SEL_GEOM
context.window_manager.popup_menu(oops, title="Error", icon="ERROR")
@@ -681,7 +724,7 @@ def command_run(self, context):
bm.edges.new([v, nVert])
v.select_set(False)
else:
- bm.edges.new([bm.select_history[-1], nVert])
+ bm.edges.new([verts[-1], nVert])
nVert.select_set(True)
bmesh.update_edit_mesh(obj.data)
bm.select_history.clear()
@@ -836,7 +879,7 @@ def command_run(self, context):
# ---------------
# Fillet Geometry
elif oper == "F":
- if mode not in {"v", "e"}:
+ if mode not in {"v", "e", "i"}:
pg.error = f"'{mode}' {PDT_ERR_NON_VALID} '{oper}'"
context.window_manager.popup_menu(oops, title="Error", icon="ERROR")
return
@@ -852,7 +895,7 @@ def command_run(self, context):
pg.error = PDT_ERR_BAD3VALS
context.window_manager.popup_menu(oops, title="Error", icon="ERROR")
return
- if mode == "v":
+ if mode in {"i", "v"}:
vert_bool = True
elif mode == "e":
vert_bool = False
@@ -870,6 +913,37 @@ def command_run(self, context):
_profile = float(vals[2])
if _profile < 0.0 or _profile > 1.0:
_profile = 0.5 # This is a circular profile
+ if mode == "i":
+ # Fillet & Intersect Two Edges
+ edges = [e for e in bm.edges if e.select]
+ if len(edges) == 2 and len(verts) == 4:
+ v_active = edges[0].verts[0]
+ v_other = edges[0].verts[1]
+ v_last = edges[1].verts[0]
+ v_first = edges[1].verts[1]
+ vector_delta, done = intersection(v_active.co,
+ v_other.co,
+ v_last.co,
+ v_first.co,
+ plane
+ )
+ if not done:
+ errmsg = f"{PDT_ERR_INT_LINES} {plane} {PDT_LAB_PLANE}"
+ self.report({"ERROR"}, errmsg)
+ return {"FINISHED"}
+ if (v_active.co - vector_delta).length < (v_other.co - vector_delta).length:
+ v_active.co = vector_delta
+ v_other.select_set(False)
+ else:
+ v_other.co = vector_delta
+ v_active.select_set(False)
+ if (v_last.co - vector_delta).length < (v_first.co - vector_delta).length:
+ v_last.co = vector_delta
+ v_first.select_set(False)
+ else:
+ v_first.co = vector_delta
+ v_last.select_set(False)
+ bmesh.ops.remove_doubles(bm, verts=bm.verts, dist=0.0001)
bpy.ops.mesh.bevel(
offset_type="OFFSET",
offset=_offset,
diff --git a/precision_drawing_tools/pdt_design.py b/precision_drawing_tools/pdt_design.py
index a20ebdd4..f0943ce6 100644
--- a/precision_drawing_tools/pdt_design.py
+++ b/precision_drawing_tools/pdt_design.py
@@ -56,6 +56,7 @@ from .pdt_msg_strings import (
PDT_ERR_SEL_2_OBJS,
PDT_ERR_SEL_2_VERTIO,
PDT_ERR_SEL_2_VERTS,
+ PDT_ERR_SEL_2_EDGES,
PDT_ERR_SEL_3_OBJS,
PDT_ERR_SEL_3_VERTIO,
PDT_ERR_SEL_3_VERTS,
@@ -825,10 +826,10 @@ class PDT_OT_PlacementInt(Operator):
edges = [e for e in bm.edges if e.select]
if len(bm.select_history) == 4:
ext_a = pg.extend
- va = bm.select_history[-1]
- vo = bm.select_history[-2]
- vl = bm.select_history[-3]
- vf = bm.select_history[-4]
+ v_active = bm.select_history[-1]
+ v_other = bm.select_history[-2]
+ v_last = bm.select_history[-3]
+ v_first = bm.select_history[-4]
actV, othV, lstV, fstV = checkSelection(4, bm, obj)
if actV is None:
errmsg = PDT_ERR_VERT_MODE
@@ -836,14 +837,10 @@ class PDT_OT_PlacementInt(Operator):
return {"FINISHED"}
elif len(edges) == 2:
ext_a = pg.extend
- va = edges[0].verts[0]
- actV = va.co
- vo = edges[0].verts[1]
- othV = vo.co
- vl = edges[1].verts[0]
- lstV = vl.co
- vf = edges[1].verts[1]
- fstV = vf.co
+ v_active = edges[0].verts[0]
+ v_other = edges[0].verts[1]
+ v_last = edges[1].verts[0]
+ v_first = edges[1].verts[1]
else:
errmsg = (
PDT_ERR_SEL_4_VERTS
@@ -854,7 +851,12 @@ class PDT_OT_PlacementInt(Operator):
)
self.report({"ERROR"}, errmsg)
return {"FINISHED"}
- vector_delta, done = intersection(actV, othV, lstV, fstV, plane)
+ vector_delta, done = intersection(v_active.co,
+ v_other.co,
+ v_last.co,
+ v_first.co,
+ plane
+ )
if not done:
errmsg = f"{PDT_ERR_INT_LINES} {plane} {PDT_LAB_PLANE}"
self.report({"ERROR"}, errmsg)
@@ -880,9 +882,9 @@ class PDT_OT_PlacementInt(Operator):
nVert = None
proc = False
- if (actV - vector_delta).length < (othV - vector_delta).length:
+ if (v_active.co - vector_delta).length < (v_other.co - vector_delta).length:
if oper == "MV":
- va.co = vector_delta
+ v_active.co = vector_delta
proc = True
elif oper == "EV":
nVert = bm.verts.new(vector_delta)
@@ -890,19 +892,19 @@ class PDT_OT_PlacementInt(Operator):
proc = True
else:
if oper == "MV" and ext_a:
- vo.co = vector_delta
+ v_other.co = vector_delta
elif oper == "EV" and ext_a:
nVert = bm.verts.new(vector_delta)
bm.edges.new([vo, nVert])
- if (lstV - vector_delta).length < (fstV - vector_delta).length:
+ if (v_last.co - vector_delta).length < (v_first.co - vector_delta).length:
if oper == "MV" and ext_a:
- vl.co = vector_delta
+ v_last.co = vector_delta
elif oper == "EV" and ext_a:
bm.edges.new([vl, nVert])
else:
if oper == "MV" and ext_a:
- vf.co = vector_delta
+ v_first.co = vector_delta
elif oper == "EV" and ext_a:
bm.edges.new([vf, nVert])
bm.select_history.clear()
@@ -1186,22 +1188,68 @@ class PDT_OT_Fillet(Operator):
scene = context.scene
pg = scene.pdt_pg
+ plane = pg.plane
obj = context.view_layer.objects.active
bm = bmesh.from_edit_mesh(obj.data)
verts = [v for v in bm.verts if v.select]
- if len(verts) == 0:
- errmsg = PDT_ERR_SEL_1_VERT
- self.report({"ERROR"}, errmsg)
- return {"FINISHED"}
+ if pg.fillet_int:
+ # Fillet & Intersect Two Edges
+ edges = [e for e in bm.edges if e.select]
+ if len(edges) == 2 and len(verts) == 4:
+ v_active = edges[0].verts[0]
+ v_other = edges[0].verts[1]
+ v_last = edges[1].verts[0]
+ v_first = edges[1].verts[1]
+ vector_delta, done = intersection(v_active.co,
+ v_other.co,
+ v_last.co,
+ v_first.co,
+ plane
+ )
+ if not done:
+ errmsg = f"{PDT_ERR_INT_LINES} {plane} {PDT_LAB_PLANE}"
+ self.report({"ERROR"}, errmsg)
+ return {"FINISHED"}
+ if (v_active.co - vector_delta).length < (v_other.co - vector_delta).length:
+ v_active.co = vector_delta
+ vo.select_set(False)
+ else:
+ v_other.co = vector_delta
+ v_active.select_set(False)
+ if (v_last.co - vector_delta).length < (v_first.co - vector_delta).length:
+ v_last.co = vector_delta
+ v_first.select_set(False)
+ else:
+ v_first.co = vector_delta
+ v_last.select_set(False)
+ bmesh.ops.remove_doubles(bm, verts=bm.verts, dist=0.0001)
+ bpy.ops.mesh.bevel(
+ offset_type="OFFSET",
+ offset=pg.fillet_radius,
+ segments=pg.fillet_segments,
+ profile=pg.fillet_profile,
+ vertex_only=True,
+ )
+ return {"FINISHED"}
+ else:
+ errmsg = f"{PDT_ERR_SEL_2_EDGES} {len(edges)})"
+ self.report({"ERROR"}, errmsg)
+ return {"FINISHED"}
else:
- bpy.ops.mesh.bevel(
- offset_type="OFFSET",
- offset=pg.fillet_radius,
- segments=pg.fillet_segments,
- profile=pg.fillet_profile,
- vertex_only=pg.fillet_vertices_only,
- )
- return {"FINISHED"}
+ if len(verts) == 0:
+ errmsg = PDT_ERR_SEL_1_VERT
+ self.report({"ERROR"}, errmsg)
+ return {"FINISHED"}
+ else:
+ # Intersct Edges
+ bpy.ops.mesh.bevel(
+ offset_type="OFFSET",
+ offset=pg.fillet_radius,
+ segments=pg.fillet_segments,
+ profile=pg.fillet_profile,
+ vertex_only=pg.fillet_vertices_only,
+ )
+ return {"FINISHED"}
class PDT_OT_Angle2(Operator):
diff --git a/precision_drawing_tools/pdt_functions.py b/precision_drawing_tools/pdt_functions.py
index f766cf31..01e595ff 100644
--- a/precision_drawing_tools/pdt_functions.py
+++ b/precision_drawing_tools/pdt_functions.py
@@ -500,7 +500,7 @@ def objCheck(obj, scene, oper):
else:
return bm, True
if len(bm.select_history) >= 1:
- if _oper not in {"D", "E", "G", "N", "S"}:
+ if _oper not in {"D", "E", "F", "G", "N", "S"}:
actV = checkSelection(1, bm, obj)
else:
verts = [v for v in bm.verts if v.select]
diff --git a/precision_drawing_tools/pdt_library.py b/precision_drawing_tools/pdt_library.py
index 30f26408..096cdcf3 100644
--- a/precision_drawing_tools/pdt_library.py
+++ b/precision_drawing_tools/pdt_library.py
@@ -79,7 +79,7 @@ class PDT_OT_Append(Operator):
scene = context.scene
pg = scene.pdt_pg
- obj_names = [o.name for o in context.view_layer.objects]
+ obj_names = [o.name for o in context.view_layer.objects].copy()
file_path = context.preferences.addons[__package__].preferences.pdt_library_path
path = Path(file_path)
diff --git a/precision_drawing_tools/pdt_menus.py b/precision_drawing_tools/pdt_menus.py
index 3095f775..01cd5d09 100644
--- a/precision_drawing_tools/pdt_menus.py
+++ b/precision_drawing_tools/pdt_menus.py
@@ -21,6 +21,7 @@
# Author: Alan Odom (Clockmender), Rune Morling (ermo) Copyright (c) 2019
# -----------------------------------------------------------------------
#
+import bpy
from bpy.types import Panel
from .pdt_msg_strings import (
PDT_LAB_ABS,
@@ -64,6 +65,23 @@ from .pdt_msg_strings import (
PDT_LAB_VARIABLES
)
+def ui_width():
+ """Return the Width of the UI Panel.
+
+ Args:
+ None.
+
+ Returns:
+ UI Width.
+ """
+
+ area = bpy.context.area
+ resolution = bpy.context.preferences.system.ui_scale
+
+ for reg in area.regions:
+ if reg.type == "UI":
+ region_width = reg.width
+ return region_width
# PDT Panel menus
#
@@ -76,6 +94,7 @@ class PDT_PT_PanelDesign(Panel):
bl_options = {'DEFAULT_CLOSED'}
def draw(self, context):
+ ui_cutoff = bpy.context.preferences.addons[__package__].preferences.pdt_ui_width
layout = self.layout
pdt_pg = context.scene.pdt_pg
#
@@ -112,9 +131,10 @@ class PDT_PT_PanelDesign(Panel):
# cartesian input coordinates in a box
row = box_1a.row()
box = row.box()
- #box.label(text="Cartesian Coordinates:")
row = box.row()
- row.prop(pdt_pg, "cartesian_coords", text=PDT_LAB_CVALUE)
+ split = row.split(factor=0.35, align=True)
+ split.label(text=PDT_LAB_CVALUE)
+ split.prop(pdt_pg, "cartesian_coords", text="")
row = box.row()
row.operator("pdt.absolute", icon="EMPTY_AXIS", text=f"{PDT_LAB_ABS} »")
row.operator("pdt.delta", icon="EMPTY_AXIS", text=f"{PDT_LAB_DEL} »")
@@ -145,6 +165,8 @@ class PDT_PT_PanelDesign(Panel):
box = box_1b.box()
row = box.row()
row.operator("pdt.intersect", text=f"|4| {PDT_LAB_INTERSECT} »")
+ if ui_width() < ui_cutoff:
+ row = box.row()
row.prop(pdt_pg, "object_order", text=PDT_LAB_ORDER)
#
# percentage row
@@ -154,6 +176,8 @@ class PDT_PT_PanelDesign(Panel):
row = box.row()
row.operator("pdt.percent", text=f"|2| % »")
row.prop(pdt_pg, "percent", text=PDT_LAB_PERCENTS)
+ if ui_width() < ui_cutoff:
+ row = box.row()
row.prop(pdt_pg, "flip_percent", text=PDT_LAB_FLIPPERCENT)
# -----
@@ -188,6 +212,7 @@ class PDT_PT_PanelDesign(Panel):
row.prop(pdt_pg, "fillet_vertices_only", text=PDT_LAB_USEVERTS)
row = box.row()
row.operator("pdt.fillet", text=f"{PDT_LAB_FILLET}")
+ row.prop(pdt_pg, "fillet_int", text="Intersect")
class PDT_PT_PanelPivotPoint(Panel):
@@ -199,24 +224,30 @@ class PDT_PT_PanelPivotPoint(Panel):
bl_options = {'DEFAULT_CLOSED'}
def draw(self, context):
+ ui_cutoff = bpy.context.preferences.addons[__package__].preferences.pdt_ui_width
pdt_pg = context.scene.pdt_pg
layout = self.layout
row = layout.row()
- split = row.split(factor=0.4, align=True)
+ col = row.column()
if context.window_manager.pdt_run_opengl is False:
icon = "PLAY"
txt = "Show"
else:
icon = "PAUSE"
txt = "Hide"
- split.operator("pdt.modaldraw", icon=icon, text=txt)
- split.prop(pdt_pg, "pivot_size", text=PDT_LAB_PIVOTSIZE)
- split.prop(pdt_pg, "pivot_width", text=PDT_LAB_PIVOTWIDTH)
- split.prop(pdt_pg, "pivot_alpha", text=PDT_LAB_PIVOTALPHA)
- row = layout.row()
- row.label(text=PDT_LAB_PIVOTLOCH)
+ col.operator("pdt.modaldraw", icon=icon, text=txt)
+ col = row.column()
+ col.prop(pdt_pg, "pivot_size", text=PDT_LAB_PIVOTSIZE)
+ if ui_width() < ui_cutoff:
+ row = layout.row()
+ col = row.column()
+ col.prop(pdt_pg, "pivot_width", text=PDT_LAB_PIVOTWIDTH)
+ col = row.column()
+ col.prop(pdt_pg, "pivot_alpha", text=PDT_LAB_PIVOTALPHA)
row = layout.row()
- row.prop(pdt_pg, "pivot_loc", text=PDT_LAB_PIVOTLOC)
+ split = row.split(factor=0.35, align=True)
+ split.label(text=PDT_LAB_PIVOTLOCH)
+ split.prop(pdt_pg, "pivot_loc", text=PDT_LAB_PIVOTLOC)
row = layout.row()
col = row.column()
col.operator("pdt.pivotselected", icon="EMPTY_AXIS", text="Selection")
@@ -240,9 +271,9 @@ class PDT_PT_PanelPivotPoint(Panel):
col = row.column()
col.prop(pdt_pg, "distance", text="System Distance")
row = layout.row()
- row.label(text="Pivot Point Scale Factors")
- row = layout.row()
- row.prop(pdt_pg, "pivot_scale", text="")
+ split = row.split(factor=0.35, align=True)
+ split.label(text="Scale")
+ split.prop(pdt_pg, "pivot_scale", text="")
row = layout.row()
col = row.column()
col.operator("pdt.pivotwrite", icon="FILE_TICK", text="PP Write")
@@ -259,6 +290,7 @@ class PDT_PT_PanelPartsLibrary(Panel):
bl_options = {'DEFAULT_CLOSED'}
def draw(self, context):
+ ui_cutoff = context.preferences.addons[__package__].preferences.pdt_ui_width
layout = self.layout
pdt_pg = context.scene.pdt_pg
row = layout.row()
@@ -266,6 +298,8 @@ class PDT_PT_PanelPartsLibrary(Panel):
col.operator("pdt.append", text="Append")
col = row.column()
col.operator("pdt.link", text="Link")
+ if ui_width() < ui_cutoff:
+ row = layout.row()
col = row.column()
col.prop(pdt_pg, "lib_mode", text="")
box = layout.box()
@@ -304,8 +338,13 @@ class PDT_PT_PanelViewControl(Panel):
bl_category = "PDT"
bl_options = {'DEFAULT_CLOSED'}
+ # Sub-layout highlight states
+ _ui_groups = [False, False]
+
def draw(self, context):
+ ui_cutoff = context.preferences.addons[__package__].preferences.pdt_ui_width
layout = self.layout
+ ui_groups = self._ui_groups
pdt_pg = context.scene.pdt_pg
box = layout.box()
row = box.row()
@@ -314,10 +353,14 @@ class PDT_PT_PanelViewControl(Panel):
col = row.column()
col.operator("pdt.viewrot", text="Rotate Abs")
row = box.row()
- row.prop(pdt_pg, "rotation_coords", text="Rotation")
+ split = row.split(factor=0.35, align=True)
+ split.label(text="Rotation")
+ split.prop(pdt_pg, "rotation_coords", text="")
row = box.row()
col = row.column()
col.prop(pdt_pg, "vrotangle", text="Angle")
+ if ui_width() < ui_cutoff:
+ row = box.row()
col = row.column()
col.operator("pdt.viewleft", text="", icon="TRIA_LEFT")
col = row.column()
@@ -355,3 +398,7 @@ class PDT_PT_PanelCommandLine(Panel):
row.label(text="Comand Line, uses Plane & Mode Options")
row = layout.row()
row.prop(pdt_pg, "command", text="")
+ # Try Re-run
+ row.operator("pdt.command_rerun", text="", icon="LOOP_BACK")
+ row = layout.row()
+ row.prop(pdt_pg, "maths_output", text="Maths Output")
diff --git a/precision_drawing_tools/pdt_msg_strings.py b/precision_drawing_tools/pdt_msg_strings.py
index 2c6cab25..46d8d635 100644
--- a/precision_drawing_tools/pdt_msg_strings.py
+++ b/precision_drawing_tools/pdt_msg_strings.py
@@ -43,7 +43,7 @@ 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 = "" # Intentionally left blank
+PDT_LAB_CVALUE = "Coordinates"
PDT_LAB_DISVALUE = "Distance"
PDT_LAB_ANGLEVALUE = "Angle"
PDT_LAB_PERCENTS = "%"
@@ -66,7 +66,7 @@ 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 = "Pivot Point Location"
+PDT_LAB_PIVOTLOCH = "Location"
#
# Error Message
#
@@ -84,6 +84,7 @@ PDT_ERR_SEL_1_VERT = "Select at least 1 Vertex (Currently selected:"
PDT_ERR_SEL_2_VERTI = "Select at least 2 Vertices Individually (Currently selected:"
PDT_ERR_SEL_2_VERTIO = "Select Exactly 2 Vertices Individually (Currently selected:"
PDT_ERR_SEL_2_VERTS = "Select Exactly 2 Vertices (Currently selected:"
+PDT_ERR_SEL_2_EDGES = "Select Only 2 Non-Intersecting Edges (Currently selected:"
PDT_ERR_SEL_3_VERTS = "Select Exactly 3 Vertices (Currently selected:"
PDT_ERR_SEL_3_VERTIO = "Select Exactly 3 Vertices Individually (Currently selected:"
PDT_ERR_SEL_2_V_1_E = "Select 2 Vertices Individually, or 1 Edge (Currently selected:"
@@ -113,7 +114,7 @@ PDT_ERR_SCALEZERO = "Scale Distance is 0"
PDT_ERR_CHARS_NUM = "Bad Command Format, not enough Characters"
PDT_ERR_BADFLETTER = "Bad Operator (1st Letter); C D E F G N M P S V or ? only"
-PDT_ERR_BADSLETTER = "Bad Mode (2nd Letter); A D I or P only (+ X Y & Z for Maths) (+ V & G for Fillet)"
+PDT_ERR_BADSLETTER = "Bad Mode (2nd Letter); A D I or P only (+ X Y & Z for Maths) (+ I V & G for Fillet)"
PDT_ERR_BADMATHS = "Not a Valid Mathematical Expression!"
PDT_ERR_BADCOORDL = "X Y & Z Not permitted in anything other than Maths Operations"
PDT_ERR_BAD1VALS = "Bad Command - 1 Value needed"
@@ -158,7 +159,8 @@ 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 P"
+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"
@@ -169,3 +171,4 @@ PDT_DES_FILLETRAD = "Fillet Radius"
PDT_DES_FILLETSEG = "Number of Fillet Segments"
PDT_DES_FILLETPROF = "Fillet Profile"
PDT_DES_FILLETVERTS = "Use Vertices, or Edges, Set to False for Extruded Geometry"
+PDT_DES_FILLINT = "Intersect & Fillet Two Selected Edges"
diff --git a/precision_drawing_tools/pdt_view.py b/precision_drawing_tools/pdt_view.py
index 5257515f..9160aded 100644
--- a/precision_drawing_tools/pdt_view.py
+++ b/precision_drawing_tools/pdt_view.py
@@ -32,11 +32,10 @@ from .pdt_functions import debug, euler_to_quaternion
class PDT_OT_ViewRot(Operator):
- """Rotate View using X Y Z Absolute Rotations."""
-
bl_idname = "pdt.viewrot"
bl_label = "Rotate View"
bl_options = {"REGISTER", "UNDO"}
+ bl_description = "View Rotation by Absolute Values"
def execute(self, context):
"""View Rotation by Absolute Values.
@@ -68,11 +67,10 @@ class PDT_OT_ViewRot(Operator):
class PDT_OT_vRotL(Operator):
- """Orbit View to Left by Angle."""
-
bl_idname = "pdt.viewleft"
bl_label = "Rotate Left"
bl_options = {"REGISTER", "UNDO"}
+ bl_description = "View Orbit Left by Delta Value"
def execute(self, context):
"""View Orbit Left by Delta Value.
@@ -97,11 +95,10 @@ class PDT_OT_vRotL(Operator):
class PDT_OT_vRotR(Operator):
- """Orbit View to Right by Angle."""
-
bl_idname = "pdt.viewright"
bl_label = "Rotate Right"
bl_options = {"REGISTER", "UNDO"}
+ bl_description = "View Orbit Right by Delta Value"
def execute(self, context):
"""View Orbit Right by Delta Value.
@@ -127,11 +124,10 @@ class PDT_OT_vRotR(Operator):
class PDT_OT_vRotU(Operator):
- """Orbit View to Up by Angle."""
-
bl_idname = "pdt.viewup"
bl_label = "Rotate Up"
bl_options = {"REGISTER", "UNDO"}
+ bl_description = "View Orbit Up by Delta Value"
def execute(self, context):
"""View Orbit Up by Delta Value.
@@ -157,11 +153,10 @@ class PDT_OT_vRotU(Operator):
class PDT_OT_vRotD(Operator):
- """Orbit View to Down by Angle."""
-
bl_idname = "pdt.viewdown"
bl_label = "Rotate Down"
bl_options = {"REGISTER", "UNDO"}
+ bl_description = "View Orbit Down by Delta Value"
def execute(self, context):
"""View Orbit Down by Delta Value.
@@ -187,11 +182,10 @@ class PDT_OT_vRotD(Operator):
class PDT_OT_vRoll(Operator):
- """Roll View by Angle."""
-
bl_idname = "pdt.viewroll"
bl_label = "Roll View"
bl_options = {"REGISTER", "UNDO"}
+ bl_description = "View Roll by Delta Value"
def execute(self, context):
"""View Roll by Delta Value.
@@ -217,11 +211,10 @@ class PDT_OT_vRoll(Operator):
class PDT_OT_viso(Operator):
- """Isometric View."""
-
bl_idname = "pdt.viewiso"
bl_label = "Isometric View"
bl_options = {"REGISTER", "UNDO"}
+ bl_description = "Isometric View."
def execute(self, context):
"""Set Isometric View.
@@ -241,15 +234,15 @@ class PDT_OT_viso(Operator):
areas[0].spaces.active.region_3d.view_rotation = Quaternion(
(0.8205, 0.4247, -0.1759, -0.3399)
)
+ areas[0].spaces.active.region_3d.view_perspective = 'ORTHO'
return {"FINISHED"}
class PDT_OT_Reset3DView(Operator):
- """Reset 3D View to Blender Defaults."""
-
bl_idname = "pdt.reset_3d_view"
bl_label = "Reset 3D View"
bl_options = {'REGISTER', 'UNDO'}
+ bl_description = "Reset 3D View to Blender Defaults."
def execute(self, context):
"""Reset 3D View to Blender Defaults.
@@ -289,6 +282,7 @@ class PDT_OT_Reset3DView(Operator):
# Otherwise, the view matrix needs to be reset (includes distance).
debug(f"view_matrix before reset:\n{view.view_matrix}")
view.view_matrix = default_view_matrix
+ view.view_distance = default_view_distance
view.update()
debug(f"view_matrix AFTER reset:\n{view.view_matrix}")
diff --git a/rigify/rig_ui_template.py b/rigify/rig_ui_template.py
index bb5a9cbd..411c9417 100644
--- a/rigify/rig_ui_template.py
+++ b/rigify/rig_ui_template.py
@@ -1163,7 +1163,7 @@ class ScriptGenerator(base_generate.GeneratorPlugin):
# Generate the UI script
if metarig.data.rigify_rig_basename:
- rig_ui_name = metarig.data.rigify_rig_basename + '_rig_ui.py'
+ rig_ui_name = metarig.data.rigify_rig_basename + '_ui.py'
else:
rig_ui_name = 'rig_ui.py'