From efb1f3466aae2a05119c60b870947b71ccc9ff1d Mon Sep 17 00:00:00 2001 From: Neltulz Date: Tue, 14 Jan 2020 16:43:41 -0600 Subject: [PATCH] v1.0.6 - Compact Panel, Bug Fixes - New Compact Popup & Pie Panel - Ability to add edges with flow to multiple selected objects - Bug Fix: Unable to perform edge flow if there was no active object when objects were selected --- README_Neltulz_Edge_Curve_Plus.html | 25 ++-- __init__.py | 46 ++++--- addon_preferences.py | 90 +++++++++++--- keymaps.py | 4 +- main_ot.py | 179 +++++++++++++++++++++------- misc_layout.py | 145 ++++++++++++++++++---- misc_ot.py | 50 ++++---- panels.py | 77 +++++------- properties.py | 39 ++---- 9 files changed, 450 insertions(+), 205 deletions(-) diff --git a/README_Neltulz_Edge_Curve_Plus.html b/README_Neltulz_Edge_Curve_Plus.html index 9f31b4a..999f6d8 100644 --- a/README_Neltulz_Edge_Curve_Plus.html +++ b/README_Neltulz_Edge_Curve_Plus.html @@ -4,17 +4,17 @@ - Neltulz - Edge Curve Plus - ReadMe + Neltulz - Edge Curve - ReadMe - + - + @@ -79,7 +79,7 @@

- Neltulz - Edge Curve Plus
Version: 1.0.5
Last Update: 12/23/2019
+ Neltulz - Edge Curve
Version: 1.0.6
Last Update: 01/14/2020

@@ -180,7 +180,7 @@

Key Features

Dependencies

-

Neltulz - Edge Curve Plus requires the EdgeFlow addon for blender to be installed prior to using. +

Neltulz - Edge Curve requires the EdgeFlow addon for blender to be installed prior to using. Download the latest version here: EdgeFlow Addon for Blender

@@ -197,7 +197,7 @@

Github

Installation

    -
  1. Download the Neltulz - Edge Curve Plus zip file anywhere on your +
  2. Download the Neltulz - Edge Curve zip file anywhere on your computer.
  3. Run Blender.
  4. @@ -208,10 +208,10 @@

    Installation

  5. At the top right, click Install.
  6. -
  7. Browse for the Neltulz - Edge Curve Plus zip file and click Install Add-on +
  8. Browse for the Neltulz - Edge Curve zip file and click Install Add-on from File
    Alternatively, you may double click the zip file to install it.
  9. -
  10. Next to Neltulz - Edge Curve Plus, enable the checkbox.
  11. +
  12. Next to Neltulz - Edge Curve, enable the checkbox.
  13. (OPTIONAL) If you are manually saving preferences (instead of automatically), at the lower left of the preferences window, click Save Preferences and close the preferences window.
  14. @@ -249,7 +249,7 @@
    Hotkeys
    ALT+SHIFT+E Insert Edge Loop(s) with Flow - ntz_edg_curv.insertedges + ntzedgcrv.insertedges numSegments = 1
    useEdgeFlow = True
    tension = 180
    numIterations = 4
    minAngle = 0 @@ -352,6 +352,13 @@

    From the GNU GPL v3.0:

    Changelog

      +
    • 2020-01-14 +
        +
      • New Compact Popup & Pie Panel
      • +
      • Ability to add edges with flow to multiple selected objects
      • +
      • Bug Fix: Unable to perform edge flow if there was no active object when objects were selected
      • +
      +
    • 2019-12-23
      • Set default sidebar tab name to "Neltulz" so that all Neltulz related sidebars from various Neltulz add-ons will be organized here.
      • diff --git a/__init__.py b/__init__.py index 3629720..00f5534 100644 --- a/__init__.py +++ b/__init__.py @@ -1,9 +1,9 @@ bl_info = { - "name" : "Neltulz - Edge Curve Plus", + "name" : "Neltulz - Edge Curve", "author" : "Neil V. Moore", "description" : "Allows you to quickly insert edge loops with flow (Requires edge flow addon)", "blender" : (2, 80, 0), - "version" : (1, 0, 5), + "version" : (1, 0, 6), "location" : "View3D", "warning" : "", "category" : "3D View", @@ -17,27 +17,34 @@ import bpy -from . properties import NeltulzEdgeCurvePlus_IgnitProperties -from . main_ot import OBJECT_OT_NeltulzEdgeCurvePlus -from . misc_ot import OBJECT_OT_NeltulzEdgeCurvePlus_ResetAllSettings -from . addon_preferences import OBJECT_OT_NeltulzEdgeCurvePlus_Preferences -from . panels import OBJECT_PT_NeltulzEdgeCurvePlus +from . properties import NTZEDGCRV_ignitproperties +from . main_ot import NTZEDGCRV_OT_insertedges +from . misc_ot import NTZEDGCRV_OT_resetsettings +from . addon_preferences import NTZEDGCRV_OT_addonprefs +from . panels import NTZEDGCRV_PT_options +from . panels import NTZEDGCRV_PT_sidebarpanel from . import keymaps PendingDeprecationWarning +bDebugModeActive = False +if bDebugModeActive: + print("##################################################################################################################################################################") + print("REMINDER: DEBUG MODE ACTIVE") + print("##################################################################################################################################################################") # ----------------------------------------------------------------------------- # Store classes in List so that they can be easily registered/unregistered # ----------------------------------------------------------------------------- classes = ( - NeltulzEdgeCurvePlus_IgnitProperties, - OBJECT_OT_NeltulzEdgeCurvePlus, - OBJECT_OT_NeltulzEdgeCurvePlus_ResetAllSettings, - OBJECT_OT_NeltulzEdgeCurvePlus_Preferences, - OBJECT_PT_NeltulzEdgeCurvePlus, + NTZEDGCRV_ignitproperties, + NTZEDGCRV_OT_insertedges, + NTZEDGCRV_OT_resetsettings, + NTZEDGCRV_OT_addonprefs, + NTZEDGCRV_PT_options, + NTZEDGCRV_PT_sidebarpanel, ) # ----------------------------------------------------------------------------- @@ -46,19 +53,28 @@ addon_keymaps = [] +#vscode pme workaround from iceythe (part 2 of 2) +def _reg(): + pme = bpy.utils._preferences.addons['pie_menu_editor'].preferences + for pm in pme.pie_menus: + if pm.key != 'NONE': + pm.register_hotkey() +#END vscode pme workaround (part 2 of 2) + def register(): from bpy.utils import register_class for cls in classes: register_class(cls) # update panel name - addon_preferences.update_panel(None, bpy.context) + prefs = bpy.context.preferences.addons[__name__].preferences + addon_preferences.update_panel(prefs, bpy.context) #add keymaps from keymaps.py keymaps.neltulz_edge_curve_plus_register_keymaps(addon_keymaps) #add property group to the scene - bpy.types.Scene.neltulzEdgeCurvePlus = bpy.props.PointerProperty(type=NeltulzEdgeCurvePlus_IgnitProperties) + bpy.types.Scene.ntzedgcrv = bpy.props.PointerProperty(type=NTZEDGCRV_ignitproperties) @@ -77,4 +93,4 @@ def unregister(): register() # test call - bpy.ops.ntz_edg_curv.insertedges() \ No newline at end of file + bpy.ops.ntzedgcrv.insertedges() \ No newline at end of file diff --git a/addon_preferences.py b/addon_preferences.py index 0d54aaf..a33f921 100644 --- a/addon_preferences.py +++ b/addon_preferences.py @@ -2,20 +2,25 @@ # recommended by "cytoo" import bpy -from . panels import OBJECT_PT_NeltulzEdgeCurvePlus +from . panels import NTZEDGCRV_PT_sidebarpanel from bpy.props import (StringProperty, BoolProperty, IntProperty, FloatProperty, FloatVectorProperty, EnumProperty, PointerProperty) from bpy.types import (Panel, Operator, AddonPreferences, PropertyGroup) # Define Panel classes for updating panels = ( - OBJECT_PT_NeltulzEdgeCurvePlus, + NTZEDGCRV_PT_sidebarpanel, ) def update_panel(self, context): - message = "Neltulz - Edge Curve Plus: Updating Panel locations has failed" + + sidebarPanelSize_PropVal = context.preferences.addons[__package__].preferences.sidebarPanelSize + category_PropVal = context.preferences.addons[__package__].preferences.category + popupAndPiePanelSize_PropVal = context.preferences.addons[__package__].preferences.popupAndPiePanelSize + + message = "Neltulz - Edge Curve: Updating Panel locations has failed" try: for panel in panels: if "bl_rna" in panel.__dict__: @@ -23,7 +28,25 @@ def update_panel(self, context): #Whatever the user typed into the text box in the add-ons settings, set that as the addon's tab category name for panel in panels: - panel.bl_category = context.preferences.addons[__package__].preferences.category + + if sidebarPanelSize_PropVal == "HIDE": + panel.bl_category = "" + panel.bl_region_type = "WINDOW" + + else: + if self.sidebarPanelSize == "DEFAULT": + panel.bUseCompactSidebarPanel = False + else: + panel.bUseCompactSidebarPanel = True + + panel.bl_category = category_PropVal + panel.bl_region_type = "UI" + + if self.popupAndPiePanelSize == "DEFAULT": + panel.bUseCompactPopupAndPiePanel = False + else: + panel.bUseCompactPopupAndPiePanel = True + bpy.utils.register_class(panel) except Exception as e: @@ -31,22 +54,61 @@ def update_panel(self, context): pass -class OBJECT_OT_NeltulzEdgeCurvePlus_Preferences(AddonPreferences): +class NTZEDGCRV_OT_addonprefs(AddonPreferences): # this must match the addon name, use '__package__' # when defining this in a submodule of a python package. bl_idname = __package__ category: StringProperty( - name="Tab Category", - description="Choose a name for the category of the panel", - default="Neltulz", - update=update_panel - ) + name="Tab Category", + description="Choose a name for the category of the panel", + default="Neltulz", + update=update_panel, + ) + + sidebarpanelSize_List = [ + ("DEFAULT", "Default", "", "", 0), + ("COMPACT", "Compact", "", "", 1), + ("HIDE", "Hide", "", "", 2), + ] + + popupAndPiePanelSize_List = [ + ("DEFAULT", "Default", "", "", 0), + ("COMPACT", "Compact", "", "", 1), + ] + + sidebarPanelSize : EnumProperty ( + items = sidebarpanelSize_List, + name = "Sidebar Panel Size", + description = "Sidebar Panel Size", + default = "DEFAULT", + update=update_panel, + ) + + popupAndPiePanelSize : EnumProperty ( + items = popupAndPiePanelSize_List, + name = "Popup & Pie Panel Size", + description = "Popup & Pie Panel Size", + default = "COMPACT", + update=update_panel, + ) def draw(self, context): + + from . misc_layout import createProp layout = self.layout - row = layout.row() - col = row.column() - col.label(text="Tab Category:") - col.prop(self, "category", text="") \ No newline at end of file + labelWidth = 7 + labelJustify = "RIGHT" + propJustify = "LEFT" + propWidth = 15 + propHeight = 1.25 + + if self.sidebarPanelSize == "HIDE": + bTabCatEnabled = False + else: + bTabCatEnabled = True + + createProp(self, context, None, True, "Sidebar Panel", self, "sidebarPanelSize", propHeight, labelWidth, propWidth, labelJustify, propJustify, None, True, False, layout) + createProp(self, context, None, bTabCatEnabled, "Tab Category", self, "category", propHeight, labelWidth, propWidth, labelJustify, propJustify, "", True, False, layout) + createProp(self, context, None, True, "Popup & Pie Panel", self, "popupAndPiePanelSize", propHeight, labelWidth, propWidth, labelJustify, propJustify, None, True, False, layout) \ No newline at end of file diff --git a/keymaps.py b/keymaps.py index 64eda73..4f124c5 100644 --- a/keymaps.py +++ b/keymaps.py @@ -1,5 +1,5 @@ import bpy -from . properties import NeltulzEdgeCurvePlus_IgnitProperties +from . properties import NTZEDGCRV_ignitproperties # ----------------------------------------------------------------------------- # Keymaps (For Register) @@ -11,7 +11,7 @@ def neltulz_edge_curve_plus_register_keymaps(addon_keymaps): def createEdgeCurvePlusKeymap(): #create shortcuts for keymap - kmi = km.keymap_items.new("ntz_edg_curv.insertedges", type = "E", ctrl=False, shift=True, alt=True, value = "PRESS") + kmi = km.keymap_items.new("ntzedgcrv.insertedges", type = "E", ctrl=False, shift=True, alt=True, value = "PRESS") kmi.properties.numSegments = 1 kmi.properties.useEdgeFlow = True kmi.properties.tension = 180 diff --git a/main_ot.py b/main_ot.py index b67f8a8..2279b1d 100644 --- a/main_ot.py +++ b/main_ot.py @@ -1,6 +1,7 @@ import bpy -from . properties import NeltulzEdgeCurvePlus_IgnitProperties +from . properties import NTZEDGCRV_ignitproperties from . import misc_functions +from . import misc_layout from bpy.props import (StringProperty, BoolProperty, IntProperty, FloatProperty, FloatVectorProperty, EnumProperty, PointerProperty) from bpy.types import (Panel, Operator, AddonPreferences, PropertyGroup) @@ -9,13 +10,19 @@ # Main Addon Operator # ----------------------------------------------------------------------------- -class OBJECT_OT_NeltulzEdgeCurvePlus(bpy.types.Operator): +class NTZEDGCRV_OT_insertedges(bpy.types.Operator): """Tooltip""" - bl_idname = "ntz_edg_curv.insertedges" - bl_label = "Neltulz - Edge Curve Plus" + bl_idname = "ntzedgcrv.insertedges" + bl_label = "Neltulz - Edge Curve" bl_description = "Allows you to quick insert edges with flow" bl_options = {'REGISTER', 'UNDO', 'PRESET'} + bForcePanelOptions : BoolProperty( + name="Force Panel Options", + description='Gets all of the operator properties from the sidebar panel options. This will override any settings in the user customized keymap.', + default = False + ) + numSegments : IntProperty( name="Segment Number", description="Number of segments to add. (Default: 1)", @@ -30,6 +37,11 @@ class OBJECT_OT_NeltulzEdgeCurvePlus(bpy.types.Operator): default = True ) + showEdgeFlowOptions : BoolProperty( + name="Show Edge Flow Options", + default = True + ) + tension : IntProperty( name="Tension", description="Tension (Default: 180)", @@ -59,64 +71,151 @@ class OBJECT_OT_NeltulzEdgeCurvePlus(bpy.types.Operator): def poll(cls, context): return (context.object.type == 'MESH' and bpy.context.object.mode == "EDIT") + + def draw(self, context): + scn = context.scene + layout = self.layout.column(align=True) + + layout.separator() + + layout.prop(self, "numSegments", slider=True) + + layout.separator() + + edgeFlowOptionsEnabled = False #declare + if self.useEdgeFlow: + edgeFlowOptionsEnabled = True + + misc_layout.createShowHide(self, context, None, None, "showEdgeFlowOptions", "useEdgeFlow", "Use Edge Flow", layout) + + if self.showEdgeFlowOptions: + + edgeFlowSection = layout.column(align=True) + + edgeFlowSection.separator() + + edgeFlowOptionsCol = edgeFlowSection.column(align=True) + edgeFlowOptionsCol.enabled = edgeFlowOptionsEnabled + + edgeFlowOptionsCol.prop(self, "tension", slider=edgeFlowOptionsEnabled) + edgeFlowOptionsCol.prop(self, "numIterations", slider=edgeFlowOptionsEnabled) + edgeFlowOptionsCol.prop(self, "minAngle", slider=edgeFlowOptionsEnabled) + + #END draw() + def execute(self, context): + scn = context.scene + + selObjs = bpy.context.selected_objects + activeObjAtBegin = bpy.context.view_layer.objects.active + + try: + #try to determine objectMode + modeAtBegin = bpy.context.object.mode + except: + modeAtBegin = "OBJECT" - obj = context.object - scene = context.scene + if activeObjAtBegin is not None: + if not activeObjAtBegin in selObjs: + if modeAtBegin == "EDIT": + activeObjAtBegin.select_set(True) + selObjs.append(activeObjAtBegin) + - selectedVerts = misc_functions.getSelectedVerts(self, context, obj) - if len(selectedVerts) > 0: + for obj in selObjs: - selectedEdges = misc_functions.getSelectedEdges(self, context, obj) - selectedEdgeIndices = list() + #if more than 1 object is selected, then we need to iterate them one at a time. + if len(selObjs) > 1: + bpy.ops.object.mode_set(mode='OBJECT') #switch back to object mode + bpy.ops.object.select_all(action='DESELECT') #deselect all objects + + bpy.context.view_layer.objects.active = obj + obj.select_set(True) - for edge in selectedEdges: - selectedEdgeIndices.append(edge.index) + selectedVerts = misc_functions.getSelectedVerts(self, context, obj) + if len(selectedVerts) > 0: + + selectedEdges = misc_functions.getSelectedEdges(self, context, obj) + selectedEdgeIndices = list() + for edge in selectedEdges: + selectedEdgeIndices.append(edge.index) - - totalNewEdgeLoopIndices = list() + + totalNewEdgeLoopIndices = list() - for edgeIndex in set(selectedEdgeIndices): - bpy.ops.mesh.loopcut(number_cuts=self.numSegments, object_index=0, edge_index=edgeIndex, mesh_select_mode_init=(False, True, False)) + for edgeIndex in set(selectedEdgeIndices): - newEdges = misc_functions.getSelectedEdges(self, context, obj) - newEdgeIndices = list() - for edge in newEdges: - newEdgeIndices.append(edge.index) + bpy.ops.mesh.loopcut(number_cuts=self.numSegments, object_index=0, edge_index=edgeIndex, mesh_select_mode_init=(False, True, False)) - totalNewEdgeLoopIndices = list( set(totalNewEdgeLoopIndices).union(newEdgeIndices) ) + newEdges = misc_functions.getSelectedEdges(self, context, obj) + newEdgeIndices = list() + for edge in newEdges: + newEdgeIndices.append(edge.index) - bpy.ops.mesh.select_all(action='DESELECT') - - totalEdges = misc_functions.getAllEdges(self, context, obj) - - #switch to object mode - bpy.ops.object.mode_set(mode='OBJECT') + totalNewEdgeLoopIndices = list( set(totalNewEdgeLoopIndices).union(newEdgeIndices) ) + + bpy.ops.mesh.select_all(action='DESELECT') + + totalEdges = misc_functions.getAllEdges(self, context, obj) + + #switch to object mode + bpy.ops.object.mode_set(mode='OBJECT') + + for i in range( len(totalNewEdgeLoopIndices) ): + obj.data.edges[ totalNewEdgeLoopIndices[i] ].select = True + + #switch to edit mode + bpy.ops.object.mode_set(mode='EDIT') + + + #detect if EdgeFlow addon is installed and enabled + if self.useEdgeFlow: + try: + bpy.ops.mesh.set_edge_flow(tension=self.tension, iterations=self.numIterations, min_angle=self.minAngle) + except: + self.report({'ERROR'}, 'The "EdgeFlow" add-on could not be found. Please check to see if the Edge Flow addon is installed and enabled.' ) + + + #reselect all originally selected objects, and then set the active object as the original active object + if len(selObjs) > 1: + bpy.ops.object.mode_set(mode='OBJECT') #switch back to object mode + bpy.ops.object.select_all(action='DESELECT') #deselect all objects + + for obj in selObjs: + obj.select_set(True) - for i in range( len(totalNewEdgeLoopIndices) ): - obj.data.edges[ totalNewEdgeLoopIndices[i] ].select = True + bpy.context.view_layer.objects.active = activeObjAtBegin #switch to edit mode bpy.ops.object.mode_set(mode='EDIT') - - - #detect if EdgeFlow addon is installed and enabled - if self.useEdgeFlow: - try: - bpy.ops.mesh.set_edge_flow(tension=self.tension, iterations=self.numIterations, min_angle=self.minAngle) - except: - self.report({'ERROR'}, 'The "EdgeFlow" add-on could not be found. Please check to see if the Edge Flow addon is installed and enabled.' ) - - else: - self.report({'ERROR'}, 'Please select something before running the script.' ) + + #final step - Reset bForcePanelOptions so that it doesn't interfere when it is not explicitly set via keymap + self.bForcePanelOptions = False return {'FINISHED'} # END execute() + + def invoke(self, context, event): + scn = context.scene + + if self.bForcePanelOptions: + + if scn.ntzedgcrv.customEdgeCurveSettings == "USE": + + self.numSegments = scn.ntzedgcrv.numSegmentsSlider + self.useEdgeFlow = scn.ntzedgcrv.useEdgeFlowCheckbox + self.tension = scn.ntzedgcrv.tensionSlider + self.numIterations = scn.ntzedgcrv.numIterationsSlider + self.minAngle = scn.ntzedgcrv.minAngleSlider + + return self.execute(context) + #END invoke() + # END Operator() diff --git a/misc_layout.py b/misc_layout.py index 7a0769d..e627296 100644 --- a/misc_layout.py +++ b/misc_layout.py @@ -1,11 +1,12 @@ import bpy + #Show hide section with arrow, optional checkbox, and text -def createShowHide(self, context, scene, properties, showHideBool, optionalCheckboxBool, text, layout): +def createShowHide(self, context, scn, properties, showHideBool, optionalCheckboxBool, text, layout): - if scene is not None: - data = eval( f"scene.{properties}" ) - boolThing = eval( f"scene.{properties}.{showHideBool}" ) + if scn is not None: + data = eval( f"scn.{properties}" ) + boolThing = eval( f"scn.{properties}.{showHideBool}" ) else: data = self boolThing = eval( f"self.{showHideBool}") @@ -34,35 +35,127 @@ def createShowHide(self, context, scene, properties, showHideBool, optionalCheck emptySpace.alignment = "EXPAND" emptySpace.prop(data, showHideBool, text=" ", emboss=False) -def createPropWithHideButton(self, context, scene, properties, propName, propNameVisibilityBool, customPropText, layout): +def createProp(self, context, scn, bEnabled, labelText, data, propItem, scale_y, labelScale, propScale, labelAlign, propAlign, propText, bExpandProp, bUseSlider, layout): propRow = layout.row(align=True) - propVisible = eval(f"scene.{properties}.{propNameVisibilityBool}") - if propVisible: - propXButtonIcon = "X" - propEditButtonIcon = "BLANK1" - propEnabled = True + if not bEnabled: + propRow.enabled = False + + propRow.scale_y = scale_y + + propRowLabel = propRow.row(align=True) + propRowLabel.alignment="EXPAND" + propRowLabel.ui_units_x = labelScale + + propRowLabel1 = propRowLabel.row(align=True) + propRowLabel1.alignment=labelAlign + propRowLabel1.scale_x = 1 + + propRowLabel1.label(text=labelText) + + propRowItem = propRow.row(align=True) + propRowItem.alignment=propAlign + + propRowItem1 = propRowItem.row(align=True) + propRowItem1.alignment=propAlign + propRowItem1.ui_units_x = propScale + propRowItem1.scale_x = 100 + + propRowItem1.prop(data, propItem, text=propText, expand=bExpandProp, slider=bUseSlider) + + +def createPropWithHideButtonAlt(self, context, scn, properties, propName, customPropText, bUseSlider, embossResetBtn, layout): + + propRow = layout.row(align=True) + + data = eval( f"scn.{properties}" ) + + + propCol = propRow.column(align=True) + propCol.prop ( data, propName, text=customPropText, slider=bUseSlider) + + resetPropCol = propRow.column(align=True) + resetPropCol.active = embossResetBtn + resetPropOp = resetPropCol.operator("ntzedgcrv.resetsettings", text="", icon="LOOP_BACK", emboss=embossResetBtn) + resetPropOp.settingToReset = propName + + +def mainEdgCrvPanel(self, context, bUseCompactSidebarPanel, bUseCompactPopupAndPiePanel): + layout = self.layout + scn = context.scene + + #determine if panel is inside of a popop/pie menu + panelInsidePopupOrPie = context.region.type == 'WINDOW' + if panelInsidePopupOrPie: + + if bUseCompactPopupAndPiePanel: + layout.ui_units_x = 8 + layout.label(text="Edge Curve+") + + else: + layout.ui_units_x = 13 + layout.label(text="Neltulz - Edge Curve+") + + obj = context.object + + compactPanelConditions = (panelInsidePopupOrPie and bUseCompactPopupAndPiePanel) or (not panelInsidePopupOrPie and bUseCompactSidebarPanel) + + if compactPanelConditions: + insertBtnScaleY = 1 else: - propXButtonIcon = "BLANK1" - propEditButtonIcon = "GREASEPENCIL" - propEnabled = False + insertBtnScaleY = 1.5 + + insertEdgesRow = layout.row(align=True) + insertEdgesRow.scale_y = insertBtnScaleY + + op = insertEdgesRow.operator('ntzedgcrv.insertedges', text="Insert Edge(s)", icon="OUTLINER_OB_CURVE") + + if scn.ntzedgcrv.customEdgeCurveSettings == "USE": + + op.numSegments = scn.ntzedgcrv.numSegmentsSlider + op.useEdgeFlow = scn.ntzedgcrv.useEdgeFlowCheckbox + op.tension = scn.ntzedgcrv.tensionSlider + op.numIterations = scn.ntzedgcrv.numIterationsSlider + op.minAngle = scn.ntzedgcrv.minAngleSlider + + popover = insertEdgesRow.popover(text="", panel="NTZEDGCRV_PT_options", icon="DOWNARROW_HLT") + + optionsSectionWrapper = layout.column(align=True) + + +def options_inner(self, context, scn, bUseCompactSidebarPanel, bUseCompactPopupAndPiePanel, layout): + + layout.label(text="Edge Curve Settings:") + layout.prop(scn.ntzedgcrv, "customEdgeCurveSettings", text="") + + if scn.ntzedgcrv.customEdgeCurveSettings == "USE": + + edgeCurveSettings = layout.box().column(align=True) + + createPropWithHideButtonAlt(self, context, scn, "ntzedgcrv", "numSegmentsSlider", None, True, True, edgeCurveSettings) + edgeCurveSettings.separator() + + createPropWithHideButtonAlt(self, context, scn, "ntzedgcrv", "useEdgeFlowCheckbox", None, False, False, edgeCurveSettings) + edgeCurveSettings.separator() - data = eval( f"scene.{properties}" ) + bEdgeFlowPropertiesEnabled = False #declare + bUseSlider = False + if scn.ntzedgcrv.useEdgeFlowCheckbox: + bEdgeFlowPropertiesEnabled = True + bUseSlider = True - propEditButton = propRow.column(align=True) - propEditButton.prop ( data, propNameVisibilityBool, text="", icon=propEditButtonIcon, emboss=False ) - propEditButton.enabled = not(propEnabled) - propEditButton.active = False + if bEdgeFlowPropertiesEnabled: + edgeFlowProperties = edgeCurveSettings.column(align=True) - propRow.separator() + createPropWithHideButtonAlt(self, context, scn, "ntzedgcrv", "tensionSlider", None, True, True, edgeFlowProperties) + createPropWithHideButtonAlt(self, context, scn, "ntzedgcrv", "numIterationsSlider", None, True, True, edgeFlowProperties) + createPropWithHideButtonAlt(self, context, scn, "ntzedgcrv", "minAngleSlider", None, True, True, edgeFlowProperties) - propCol = propRow.column(align=True) - propCol.prop ( data, propName, text=customPropText) - propCol.enabled = propEnabled - propRow.separator() + edgeCurveSettings.separator() - propXButton = propRow.column(align=True) - propXButton.prop ( data, propNameVisibilityBool, text="", icon=propXButtonIcon, emboss=False ) - propXButton.enabled = propEnabled \ No newline at end of file + resetButton = edgeCurveSettings.row(align=True) + resetButton.alignment="RIGHT" + op = resetButton.operator('ntzedgcrv.resetsettings', text="Reset All Settings", icon="LOOP_BACK") + op.settingToReset = "ALL" \ No newline at end of file diff --git a/misc_ot.py b/misc_ot.py index f3ebc8b..ea17871 100644 --- a/misc_ot.py +++ b/misc_ot.py @@ -1,19 +1,25 @@ import bpy -from . properties import NeltulzEdgeCurvePlus_IgnitProperties +from . properties import NTZEDGCRV_ignitproperties from . import misc_functions from bpy.props import (StringProperty, BoolProperty, IntProperty, FloatProperty, FloatVectorProperty, EnumProperty, PointerProperty) from bpy.types import (Panel, Operator, AddonPreferences, PropertyGroup) # ----------------------------------------------------------------------------- -# Reset All Settings +# Reset Settings # ----------------------------------------------------------------------------- -class OBJECT_OT_NeltulzEdgeCurvePlus_ResetAllSettings(bpy.types.Operator): +class NTZEDGCRV_OT_resetsettings(bpy.types.Operator): """Tooltip""" - bl_idname = "ntz_edg_curv.resetallsettings" - bl_label = "Neltulz - Edge Curve Plus : Reset All Settings" - bl_description = "Resets all settings" + bl_idname = "ntzedgcrv.resetsettings" + bl_label = "Neltulz - Edge Curve : Reset Setting(s)" + bl_description = "Resets setting(s)" + + settingToReset : StringProperty( + name="Setting to Reset", + description='Name of the setting to be reset', + default = "NONE" + ) @classmethod def poll(cls, context): @@ -21,23 +27,25 @@ def poll(cls, context): def execute(self, context): - scene = context.scene + scn = context.scene + + defaultSettingsDict = { + "numSegmentsSlider" : 1, + "useEdgeFlowCheckbox" : True, + "tensionSlider" : 180, + "numIterationsSlider" : 4, + "minAngleSlider" : 0, + } + + if self.settingToReset == "ALL": - scene.neltulzEdgeCurvePlus.numSegmentsSlider_Enable = True - scene.neltulzEdgeCurvePlus.numSegmentsSlider = 1 + for key in defaultSettingsDict: + setattr(scn.ntzedgcrv, key, defaultSettingsDict[key]) - scene.neltulzEdgeCurvePlus.useEdgeFlowCheckbox_Enable = True - scene.neltulzEdgeCurvePlus.useEdgeFlowCheckbox = True - - scene.neltulzEdgeCurvePlus.tensionSlider_Enable = True - scene.neltulzEdgeCurvePlus.tensionSlider = 180 - - scene.neltulzEdgeCurvePlus.numIterationsSlider_Enable = True - scene.neltulzEdgeCurvePlus.numIterationsSlider = 4 - - scene.neltulzEdgeCurvePlus.minAngleSlider_Enable = True - scene.neltulzEdgeCurvePlus.minAngleSlider = 0 + elif self.settingToReset != "NONE": + key = self.settingToReset + setattr(scn.ntzedgcrv, key, defaultSettingsDict[key]) return {'FINISHED'} # END execute() -# END Operator() \ No newline at end of file +# END Operator() diff --git a/panels.py b/panels.py index b0f7f31..314e862 100644 --- a/panels.py +++ b/panels.py @@ -1,5 +1,5 @@ import bpy -from . properties import NeltulzEdgeCurvePlus_IgnitProperties +from . properties import NTZEDGCRV_ignitproperties from . import misc_functions from . import misc_layout @@ -10,62 +10,41 @@ # Panel # ----------------------------------------------------------------------------- -class OBJECT_PT_NeltulzEdgeCurvePlus(Panel): - - bl_idname = "ntz_edg_curv.panel" - bl_label = "Edge Curve Plus v1.0.5" - bl_category = "Neltulz" +class NTZEDGCRV_PT_options(Panel): + bl_label = "Neltulz - Edge Curve - Options" + bl_idname = "NTZEDGCRV_PT_options" + bl_category = "" bl_space_type = "VIEW_3D" - bl_region_type = "UI" + bl_region_type = "WINDOW" def draw(self, context): - + scn = context.scene layout = self.layout - scene = context.scene - obj = context.object - - insertEdgesRow = layout.row(align=True) - insertEdgesRow.scale_y = 1.5 - - op = insertEdgesRow.operator('ntz_edg_curv.insertedges', text="Insert Edge(s)", icon="OUTLINER_OB_CURVE") - - if scene.neltulzEdgeCurvePlus.numSegmentsSlider_Enable: op.numSegments = scene.neltulzEdgeCurvePlus.numSegmentsSlider - if scene.neltulzEdgeCurvePlus.useEdgeFlowCheckbox_Enable: op.useEdgeFlow = scene.neltulzEdgeCurvePlus.useEdgeFlowCheckbox - if scene.neltulzEdgeCurvePlus.tensionSlider_Enable: op.tension = scene.neltulzEdgeCurvePlus.tensionSlider - if scene.neltulzEdgeCurvePlus.numIterationsSlider_Enable: op.numIterations = scene.neltulzEdgeCurvePlus.numIterationsSlider - if scene.neltulzEdgeCurvePlus.minAngleSlider_Enable: op.minAngle = scene.neltulzEdgeCurvePlus.minAngleSlider - - optionsSectionWrapper = layout.column(align=True) - - #create show/hide toggle for options section - misc_layout.createShowHide(self, context, scene, "neltulzEdgeCurvePlus", "bShowOptions", None, "Options", optionsSectionWrapper) - - if scene.neltulzEdgeCurvePlus.bShowOptions: + layout.ui_units_x = 15 - optionsSectionRow = optionsSectionWrapper.row(align=True) + optionsSection = layout.column(align=True) - spacer = optionsSectionRow.column(align=True) - spacer.label(text="", icon="BLANK1") + misc_layout.options_inner(self, context, scn, True, True, optionsSection) - optionsSection = optionsSectionRow.column(align=True) + #END draw() - optionsSection.separator() - - misc_layout.createPropWithHideButton(self, context, scene, "neltulzEdgeCurvePlus", "numSegmentsSlider", "numSegmentsSlider_Enable", None, optionsSection) - optionsSection.separator() - - misc_layout.createPropWithHideButton(self, context, scene, "neltulzEdgeCurvePlus", "useEdgeFlowCheckbox", "useEdgeFlowCheckbox_Enable", None, optionsSection) - optionsSection.separator() - - if scene.neltulzEdgeCurvePlus.useEdgeFlowCheckbox: +class NTZEDGCRV_PT_sidebarpanel(Panel): + bl_label = "Edge Curve Plus v1.0.6" + bl_category = "Neltulz" + bl_space_type = "VIEW_3D" + bl_region_type = "UI" - edgeFlowProperties = optionsSection.column(align=True) + bUseCompactSidebarPanel = BoolProperty( + name="Use Compact Panel", + description="Use Compact Panel", + default = False + ) - misc_layout.createPropWithHideButton(self, context, scene, "neltulzEdgeCurvePlus", "tensionSlider", "tensionSlider_Enable", None, edgeFlowProperties) - misc_layout.createPropWithHideButton(self, context, scene, "neltulzEdgeCurvePlus", "numIterationsSlider", "numIterationsSlider_Enable", None, edgeFlowProperties) - misc_layout.createPropWithHideButton(self, context, scene, "neltulzEdgeCurvePlus", "minAngleSlider", "minAngleSlider_Enable", None, edgeFlowProperties) + bUseCompactPopupAndPiePanel = BoolProperty( + name="Use Compact Popup & Pie Panel", + description="Use Compact Popup & Pie Panel", + default = True + ) - optionsSection.separator() - - resetButton = optionsSection.column(align=True) - op = resetButton.operator('ntz_edg_curv.resetallsettings', text="Reset All Settings") + def draw(self, context): + misc_layout.mainEdgCrvPanel(self, context, self.bUseCompactSidebarPanel, self.bUseCompactPopupAndPiePanel) \ No newline at end of file diff --git a/properties.py b/properties.py index 5b41c8d..0e2fbc3 100644 --- a/properties.py +++ b/properties.py @@ -4,7 +4,7 @@ from bpy.props import (StringProperty, BoolProperty, IntProperty, FloatProperty, FloatVectorProperty, EnumProperty, PointerProperty) from bpy.types import (Panel, Operator, AddonPreferences, PropertyGroup) -class NeltulzEdgeCurvePlus_IgnitProperties(bpy.types.PropertyGroup): +class NTZEDGCRV_ignitproperties(bpy.types.PropertyGroup): bShowOptions : BoolProperty ( name="Show Options", @@ -12,10 +12,15 @@ class NeltulzEdgeCurvePlus_IgnitProperties(bpy.types.PropertyGroup): default = False, ) - useEdgeFlowCheckbox_Enable : BoolProperty( - name="Enable Use Edge Flow", - description='Enables the "Use Edge Flow Checkbox" (Default: True)', - default = True + customEdgeCurveSettings_List = [ + ("UNSET", "Unset (Use Last Known)", "", "", 0), + ("USE", "Custom", "", "", 1), + ] + + customEdgeCurveSettings : EnumProperty ( + items = customEdgeCurveSettings_List, + name = "Use Custom Edge Curve Settings", + default = "USE" ) useEdgeFlowCheckbox : BoolProperty( @@ -24,12 +29,6 @@ class NeltulzEdgeCurvePlus_IgnitProperties(bpy.types.PropertyGroup): default = True ) - numSegmentsSlider_Enable : BoolProperty ( - name="Enable Num Segments Slider", - description="Enables the Num Segments Slider (Default: True)", - default = True - ) - numSegmentsSlider : IntProperty( name="Segment Num", description="Number of segments to add. (Default: 1)", @@ -38,12 +37,6 @@ class NeltulzEdgeCurvePlus_IgnitProperties(bpy.types.PropertyGroup): soft_max = 16 ) - numIterationsSlider_Enable : BoolProperty ( - name="Enable numIterationsSlider", - description="Enables the numIterationsSlider (Default: True)", - default = True - ) - numIterationsSlider : IntProperty( name="Num Iterations", description="Number of iterations. (Default: 1)", @@ -52,12 +45,6 @@ class NeltulzEdgeCurvePlus_IgnitProperties(bpy.types.PropertyGroup): soft_max = 128 ) - tensionSlider_Enable : BoolProperty ( - name="Enable Tension", - description="Enables the Tension slider", - default = True - ) - tensionSlider : IntProperty( name="Tension", description="Tension (Default: 180)", @@ -66,12 +53,6 @@ class NeltulzEdgeCurvePlus_IgnitProperties(bpy.types.PropertyGroup): min = -500 ) - minAngleSlider_Enable : BoolProperty ( - name="Enable minAngleSlider", - description="Enables the minAngleSlider", - default = True - ) - minAngleSlider : IntProperty( name="Minimum Angle", description="Minimum Angle (Default: 0)",