diff --git a/__init__.py b/__init__.py index f63eba7..139269c 100644 --- a/__init__.py +++ b/__init__.py @@ -1,10 +1,12 @@ import bpy + +from . import zh_CN from .utils import reg bl_info = { "name": "Bbrush", "author": "AIGODLIKE Community:小萌新", - "version": (1, 2, 4), + "version": (1, 2, 5), "blender": (4, 0, 0), "location": "Entering the sculpt mode will be displayed in the top bar", "description": "", @@ -33,10 +35,6 @@ def unregister(self): bpy.app.translations.unregister(self.name) -# Set -############ -from . import zh_CN - Bbrush_zh_CN = TranslationHelper('Bbrush_zh_CN', zh_CN.data) Bbrush_zh_HANS = TranslationHelper('Bbrush_zh_HANS', zh_CN.data, lang='zh_HANS') diff --git a/ops/brush_mask.py b/ops/brush_mask.py index 5541ae7..f4df60b 100644 --- a/ops/brush_mask.py +++ b/ops/brush_mask.py @@ -3,13 +3,14 @@ import bpy import gpu import numpy as np +from bpy.app.translations import pgettext as _ from bpy.props import BoolProperty from gpu_extras.batch import batch_for_shader from mathutils import Vector +from .sculpt_operator import sculpt_invert_hide_face from ..utils.log import log from ..utils.public import PublicOperator, PublicDraw -from bpy.app.translations import pgettext as _ def get_circular(x, y, segments=64): @@ -141,14 +142,6 @@ def is_normal_invoke(self): class MaskClick(MaskProperty): - @staticmethod - def invert_sculpt_hide_face(): - is_3_6_up_version = bpy.app.version >= (3, 6, 0) - if is_3_6_up_version: - bpy.ops.sculpt.face_set_invert_visibility() - else: - bpy.ops.sculpt.face_set_change_visibility('EXEC_DEFAULT', True, mode='INVERT') - def mask_click(self): in_model = self.mouse_is_in_model_up ops = bpy.ops @@ -170,7 +163,7 @@ def mask_click(self): mode='TOGGLE') elif self.ctrl_shift: if in_model: - self.invert_sculpt_hide_face() + sculpt_invert_hide_face() else: paint.hide_show('EXEC_DEFAULT', True, @@ -404,7 +397,7 @@ def exit_exception(self): mode='VALUE', value=1) elif self.ctrl_shift_alt or self.ctrl_shift: - self.invert_sculpt_hide_face() + sculpt_invert_hide_face() def event_move_update(self): """ diff --git a/ops/brush_sculpt.py b/ops/brush_sculpt.py index 5f34ef5..d4a07ad 100644 --- a/ops/brush_sculpt.py +++ b/ops/brush_sculpt.py @@ -1,6 +1,7 @@ import bpy from mathutils import Vector +from .sculpt_operator import normal_brush_handle from ..utils.log import log from ..utils.public import PublicOperator, PublicDraw @@ -91,6 +92,10 @@ class BBrushSculpt(DepthUpdate): bl_description = 'Sculpting in the style of Zbrush' bl_options = {'REGISTER'} + def __init__(self): + self.in_modal = None + self.mouse_move_count = None + def invoke(self, context, event): log.debug(self.bl_idname) @@ -101,17 +106,18 @@ def invoke(self, context, event): self.start_mouse = self.mouse_co self.start_buffer_scale = self.pref.depth_scale + if self.is_3d_view: + self.in_modal = self.mouse_is_in_model_up context.window_manager.modal_handler_add(self) return {'RUNNING_MODAL'} else: self.report({'WARNING'}, "Active space must be a View3d") return {'CANCELLED'} - def modal(self, context, event): + def modal(self, context: bpy.types.Context, event: bpy.types.Event): self.init_modal(context, event) self.tag_redraw(context) - try: if self.is_exit: # 退出模态操作 context.area.header_text_set(None) @@ -123,29 +129,27 @@ def modal(self, context, event): self.depth_scale_update(context, event) return {'RUNNING_MODAL'} else: - return self.modal_handle() + return self.modal_handle(event) except Exception as e: log.error(e.args) return {'FINISHED'} - def modal_handle(self): - in_modal = self.mouse_is_in_model_up - if in_modal: + def modal_handle(self, event: bpy.types.Event): + if self.in_modal: if self.only_alt: self.smooth_brush_handle() else: - bpy.ops.sculpt.brush_stroke('INVOKE_DEFAULT', - True, - mode='NORMAL') + normal_brush_handle() else: if self.only_alt: bpy.ops.view3d.move('INVOKE_DEFAULT', True, ) else: - bpy.ops.view3d.rotate('INVOKE_DEFAULT', - True, - ) + if event.value_prev != "RELEASE": + bpy.ops.view3d.rotate('INVOKE_DEFAULT', + True, + ) return {'FINISHED'} def smooth_brush_handle(self): diff --git a/ops/brush_switch.py b/ops/brush_switch.py index 136ffa9..7044890 100644 --- a/ops/brush_switch.py +++ b/ops/brush_switch.py @@ -139,20 +139,21 @@ def modal(self, context, event): self.mask_mode() else: self.set_shortcut_keys('NORMAL') - self.tag_redraw(context) # 进行重绘,避免更改工具栏后内容还是旧的 + self.tag_redraw(context) return self.event_ops(event) def event_ops(self, event): press = self.event_is_press tmp = getattr(self, '_tmp_brush', False) - if self.only_shift and event.type in ('INBETWEEN_MOUSEMOVE', 'MOUSEMOVE', 'LEFTMOUSE'): + if self.only_shift and event.type == "LEFTMOUSE" and event.value == "PRESS": if self.active_tool_name != "builtin_brush.Smooth": setattr(self, '_tmp_brush', self.active_tool_name) bpy.ops.wm.tool_set_by_id(name="builtin_brush.Smooth") + self.tag_redraw(bpy.context) elif tmp: bpy.ops.wm.tool_set_by_id(name=self._tmp_brush) delattr(self, '_tmp_brush') - print(event, event.type != 'F', event.type, event.value) + self.tag_redraw(bpy.context) if press: if event.type == 'NUMPAD_PLUS': diff --git a/ops/sculpt_operator.py b/ops/sculpt_operator.py new file mode 100644 index 0000000..294b3d6 --- /dev/null +++ b/ops/sculpt_operator.py @@ -0,0 +1,23 @@ +"""放置雕刻操作符 +统一各版本操作符不同带来的bug +""" +import bpy + +is_3_6_up_version = bpy.app.version >= (3, 6, 0) +is_4_1_up_version = bpy.app.version >= (4, 1, 0) + + +# 反转可见面 +def sculpt_invert_hide_face(): + if is_4_1_up_version: + bpy.ops.paint.visibility_invert() + elif is_3_6_up_version: + bpy.ops.sculpt.face_set_invert_visibility() + else: + bpy.ops.sculpt.face_set_change_visibility('EXEC_DEFAULT', True, mode='INVERT') + + +def normal_brush_handle(): + bpy.ops.sculpt.brush_stroke('INVOKE_DEFAULT', + True, + mode='NORMAL') diff --git a/ui/draw_depth.py b/ui/draw_depth.py index 18b3f37..5b3b075 100644 --- a/ui/draw_depth.py +++ b/ui/draw_depth.py @@ -1,8 +1,8 @@ import bpy import gpu import numpy as np -from mathutils import Matrix from gpu_extras.batch import batch_for_shader +from mathutils import Matrix from ..utils.public import PublicClass @@ -172,39 +172,30 @@ def draw_gpu_buffer_new_buffer_funcs(cls, sam_width, sam_height, width, height, format='RGB16F', data=sam_all_depth_buffer) - mv = gpu.matrix.get_model_view_matrix() - p = gpu.matrix.get_projection_matrix() + with gpu.matrix.push_pop(): - gpu.matrix.reset() - gpu.matrix.translate((-1, 1, 0)) - gpu.matrix.translate(cls.depth_buffer['translate']) - - depth_scale = cls.pref_().depth_scale - gpu.matrix.scale((depth_scale, depth_scale)) - shader.uniform_sampler("image", depth_gpu_texture) - batch.draw(shader) + gpu.matrix.reset() + gpu.matrix.translate((-1, 1, 0)) + gpu.matrix.translate(cls.depth_buffer['translate']) - gpu.matrix.load_projection_matrix(p) - gpu.matrix.load_matrix(mv) + depth_scale = cls.pref_().depth_scale + gpu.matrix.scale((depth_scale, depth_scale)) + shader.uniform_sampler("image", depth_gpu_texture) + batch.draw(shader) @classmethod def draw_gpu_buffer(cls, context): gpu.state.depth_mask_set(False) - mv = gpu.matrix.get_model_view_matrix() - p = gpu.matrix.get_projection_matrix() depth_scale = cls.pref_().depth_scale - - gpu.matrix.reset() - gpu.matrix.translate((-1, 1, 0)) - gpu.matrix.translate(cls.depth_buffer['translate']) - gpu.matrix.scale((depth_scale, depth_scale)) - - draw_shader_old(context.region.width, - context.region.height) # 使用自定义着色器绘制,将会快很多 - - gpu.matrix.load_projection_matrix(p) - gpu.matrix.load_matrix(mv) + with gpu.matrix.push_pop(): + # gpu.matrix.reset() + gpu.matrix.translate([-1, 1, 0]) + gpu.matrix.translate(cls.depth_buffer['translate']) + gpu.matrix.scale([depth_scale, depth_scale]) + + draw_shader_old(context.region.width, + context.region.height) # 使用自定义着色器绘制,将会快很多 @classmethod def draw_depth(cls): diff --git a/ui/draw_shortcut_keys.py b/ui/draw_shortcut_keys.py index 8492a11..e7fb075 100644 --- a/ui/draw_shortcut_keys.py +++ b/ui/draw_shortcut_keys.py @@ -1,6 +1,7 @@ import blf import bpy +from .draw_depth import get_toolbar_width from ..utils.public import PublicClass @@ -23,7 +24,7 @@ def draw(self): blf.size(font_id, 18 * font_size) blf.color(font_id, 1, 1, 1, 1) - x = self.pref.shortcut_offset_x + x = self.pref.shortcut_offset_x + get_toolbar_width() y = self.pref.shortcut_offset_y for index, item in enumerate(reversed(self.draw_shortcut_keys)): y += 18 * font_size + column_space_size diff --git a/utils/key.py b/utils/key.py index ca477c2..0b07174 100644 --- a/utils/key.py +++ b/utils/key.py @@ -9,11 +9,11 @@ sculpt_modify_keymaps = { 'Sculpt': { ('wm.call_panel', (('name', 'VIEW3D_PT_sculpt_context_menu'),)): {'value': "RELEASE"}, - (brush_stroke, ()): {'active': False}, - (brush_stroke, (('mode', 0),)): {'active': False}, - (brush_stroke, (('mode', 1),)): {'active': False}, - (brush_stroke, (('mode', 2),)): {'active': False}, - (mask_lasso_gesture, ()): {'active': False}, + (brush_stroke, ()): f_active, + (brush_stroke, (('mode', 0),)): f_active, + (brush_stroke, (('mode', 1),)): f_active, + (brush_stroke, (('mode', 2),)): f_active, + (mask_lasso_gesture, ()): f_active, (mask_lasso_gesture, (('value', 1.0),)): {'ctrl': True}, (mask_lasso_gesture, (('value', 0.0),)): {'alt': True}, }, f'{view}: Sculpt, Box Mask': { @@ -26,24 +26,26 @@ ('paint.mask_line_gesture', (('value', 1.0),)): {'ctrl': True}, ('paint.mask_line_gesture', (('value', 0.0),)): {'alt': True}}, f'{view}: Sculpt, Box Hide': { - (hide_show, (('action', 1),)): {'active': False}, - (hide_show, (('action', 0),)): {'active': False}, - (hide_show, (('action', 1), ('area', 2))): {'active': False}}, + (hide_show, (('action', 1),)): f_active, + (hide_show, (('action', 0),)): f_active, + (hide_show, (('action', 1), ('area', 2))): f_active}, f'{view}: Sculpt, Lasso Trim': { ('sculpt.trim_lasso_gesture', ()): {'ctrl': True, 'shift': True}}, f'{view}: Sculpt, Box Trim': { ('sculpt.trim_box_gesture', ()): {'ctrl': True, 'shift': True}}, f'{view}: Sculpt, Line Project': { ('sculpt.project_line_gesture', ()): {'ctrl': True, 'shift': True}}, + 'Screen': { ('sculpt.project_line_gesture', ()): {'ctrl': True, 'shift': True}}, '3D View': { - (select_lasso, (('mode', 1),)): {'active': False}, - (select_lasso, (('mode', 2),)): {'active': False}, - (select_lasso, ()): {'active': False}, - ('view3d.cursor3d', ()): {'active': False}, - ('transform.translate', ()): {'active': False}, - ('emm.hdr_rotation', ()): {'active': False}, ('view3d.select', ()): {'active': False}} + (select_lasso, (('mode', 1),)): f_active, + (select_lasso, (('mode', 2),)): f_active, + (select_lasso, ()): f_active, + ('view3d.cursor3d', ()): f_active, + ('transform.translate', ()): f_active, + ('emm.hdr_rotation', ()): f_active, + ('view3d.select', ()): f_active} } empty_window = {'space_type': 'EMPTY', 'region_type': 'WINDOW'} @@ -98,10 +100,10 @@ ('SWITCH_TO_MOVE', {'type': 'LEFT_CTRL', 'value': 'PRESS'}, None), ('SWITCH_TO_MOVE', {'type': 'LEFT_ALT', 'value': 'ANY'}, None), ]}), ('Sculpt', empty_window, {'items': [ + *bbrush_key_items, (bbrush_switch, {'type': 'LEFT_CTRL', 'value': 'ANY'}, None), (bbrush_switch, {'type': 'LEFT_ALT', 'value': 'ANY'}, None), (bbrush_switch, {'type': 'LEFT_SHIFT', 'value': 'ANY'}, None), - *bbrush_key_items, ('object.transfer_mode', {'type': 'LEFTMOUSE', 'value': 'CLICK', 'alt': True}, None), ('view3d.rotate', @@ -259,10 +261,10 @@ def change_keymap(is_modify: bool): def register(): - keymap_register(sculpt_keys_items) change_keymap(True) + keymap_register(sculpt_keys_items) def unregister(): - keymap_unregister(sculpt_keys_items) change_keymap(False) + keymap_unregister(sculpt_keys_items) diff --git a/utils/log.py b/utils/log.py index bcbff98..8f9a8f8 100644 --- a/utils/log.py +++ b/utils/log.py @@ -2,6 +2,7 @@ import os from bpy.app.translations import pgettext as _ + def log_path(): folder = os.path.join(os.environ["TMP"], r"blender") if not os.path.isdir(folder): diff --git a/utils/preferences.py b/utils/preferences.py index 34cee5f..5f37dcc 100644 --- a/utils/preferences.py +++ b/utils/preferences.py @@ -75,7 +75,7 @@ def sculpt_update(self, context): ) shortcut_offset_x: IntProperty( name=_('Shortcut key offset X'), - default=150, max=114514, min=0) + default=20, max=114514, min=0) shortcut_offset_y: IntProperty( name=_('Shortcut key offset Y'), default=20, max=114514, min=0)