diff options
author | Rune Morling <ermo.blender.org@spammesenseless.net> | 2020-01-15 00:35:18 +0300 |
---|---|---|
committer | Rune Morling <ermo.blender.org@spammesenseless.net> | 2020-01-15 00:35:18 +0300 |
commit | ff72807a80529f94e434b06f14b8c0a2f185c6f3 (patch) | |
tree | f711e38c437854eeebcc3b2095b012ce699435e6 | |
parent | 4e13b241c85652ea2309d76f717f975e37e7c091 (diff) | |
parent | 7ae27d2b019c1320bdda28c319036236a15520b5 (diff) |
PDT: Merge branch 'blender-v2.82-release' fixes
-rw-r--r-- | blenderkit/__init__.py | 28 | ||||
-rw-r--r-- | blenderkit/bg_blender.py | 2 | ||||
-rw-r--r-- | blenderkit/bkit_oauth.py | 4 | ||||
-rw-r--r-- | blenderkit/categories.py | 33 | ||||
-rw-r--r-- | blenderkit/download.py | 2 | ||||
-rw-r--r-- | blenderkit/search.py | 34 | ||||
-rw-r--r-- | blenderkit/ui.py | 19 | ||||
-rw-r--r-- | blenderkit/ui_panels.py | 43 | ||||
-rw-r--r-- | precision_drawing_tools/__init__.py | 22 | ||||
-rw-r--r-- | precision_drawing_tools/pdt_command.py | 122 | ||||
-rw-r--r-- | precision_drawing_tools/pdt_design.py | 110 | ||||
-rw-r--r-- | precision_drawing_tools/pdt_functions.py | 2 | ||||
-rw-r--r-- | precision_drawing_tools/pdt_library.py | 2 | ||||
-rw-r--r-- | precision_drawing_tools/pdt_menus.py | 75 | ||||
-rw-r--r-- | precision_drawing_tools/pdt_msg_strings.py | 11 | ||||
-rw-r--r-- | precision_drawing_tools/pdt_view.py | 26 | ||||
-rw-r--r-- | rigify/rig_ui_template.py | 2 |
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' |