2
$\begingroup$

I have the folowing code:

import bpy

class modal_pressure_simulate(bpy.types.Operator):

    bl_description = "simulate pressure"
    bl_idname = "wm.pressure_simulate"
    bl_label = "pressure"

    def modal (self, context, event):
        context.scene.tool_settings.unified_paint_settings.size = event.mouse_x / 156

        return {"PASS_THROUGH"}

    def execute(self, context):
        wm = context.window_manager
        self._timer = wm.event_timer_add(0.001,None)
        wm.modal_handler_add(self)
        return {"RUNNING_MODAL"}

    def invoke(self,context,event):
        wm = context.window_manager
        self._timer = wm.event_timer_add(0.01,None)
        wm.modal_handler_add(self)
        return {"RUNNING_MODAL"}

    def cancel (self, context):
        pass

if __name__ == "__main__":

    bpy.utils.register_class(modal_pressure_simulate)

    #bpy.ops.wm.pressure_simulate()

When in sculpt mode and operator is called the brush size will be changed based on mouse_x position but when click to sculpt the operator pauses.

How I can keep it running even if another operator is called?

$\endgroup$
2
$\begingroup$

Not sure what your issue was, so I added some edits to turn operator on / off using a window manager boolproperty update. Will also turn off if object is not in 'SCULPT' mode.

Moved the sculpt brush resize into the timer loop.

Unless you are going to set some operator properties in invoke there is no need for invoke and execute both adding handlers / timers.

enter image description here

import bpy
from bpy.props import BoolProperty, IntProperty

class ModalPressureSimulate(bpy.types.Operator):

    bl_description = "simulate pressure"
    bl_idname = "wm.pressure_simulate"
    bl_label = "pressure"
    numerator = IntProperty(default=156)
    def modal (self, context, event):

        scene = context.scene
        obj = context.object
        wm = context.window_manager

        if not wm.modal_pressure or obj.mode != 'SCULPT':
            return self.cancel(context)

        if event.type == 'TIMER':
            ps = scene.tool_settings.unified_paint_settings
            ps.size = event.mouse_x / self.numerator
            #print(event.mouse_x / 156)

        return {"PASS_THROUGH"}


    def execute(self, context):
        wm = context.window_manager
        self._timer = wm.event_timer_add(0.01, context.window)
        wm.modal_handler_add(self)
        return {"RUNNING_MODAL"}

    def cancel (self, context):
        wm = context.window_manager
        wm.event_timer_remove(self._timer)
        wm.modal_pressure = False
        return {'CANCELLED'}

def toggle_pressure(self, context):
    print("Pressure Sim Mode ", self.modal_pressure)
    if self.modal_pressure:
        bpy.ops.wm.pressure_simulate()
        #bpy.ops.wm.pressure_simulate(numerator=20)

def add_button(self, context):
    layout = self.layout
    wm = context.window_manager
    if context.object.mode == 'SCULPT':
        layout.prop(wm, "modal_pressure", toggle=True)

def register():
    bpy.utils.register_class(ModalPressureSimulate)

    bpy.types.WindowManager.modal_pressure = BoolProperty(
                                        name="Pressure",
                                        description="Toggle Pressure",
                                        default=False,
                                        update=toggle_pressure)

    bpy.types.VIEW3D_HT_header.prepend(add_button)

if __name__ == "__main__":
    register()
$\endgroup$
  • $\begingroup$ thanks, I found the problem in my code, it needs 'if event.type == 'TIMER': 'to work. $\endgroup$ – Jeacom Feb 6 '17 at 15:48

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.