Results 1 to 8 of 8
  1. #1

    user input operator

    how do i get a user input like the rotate-operator. (3dview, select object, press 'r', type {x,y,z,1,2,3....,back_space})

    user_input.png



  2. #2
    So you want for example you press 'W' to be shown on the screen? If so, there is addon but not sure exactly where, search and you will find it in add-ons in User Preferences.



  3. #3
    do you know what the addon does? any hint?

    i could, of course catch every keystroke with a modal operator and
    Code:
    if event.type == 'w':
         foo()
    but then i need to catch back_space, arrow keys and so on. .....
    write it to
    Code:
    context.area.header_text_set(self.offset)
    i though, maybe there's a build-in?
    Last edited by ni-ko-o-kin; 11-Sep-12 at 16:33.



  4. #4
    Member
    Join Date
    Dec 2011
    Location
    Germany
    Posts
    3,306
    if i got you right, you wanna run a live operator like 'R' rotation. These live operators are written in C, and as far as i know, there is no way to call them from a python script.

    The only current way appears to be a custom modal operator, that captures user input. Which will be way slower than all C live operators.



  5. #5
    i started to do funny things like this:
    Code:
    import bpy
    from mathutils import Vector
    from bpy.props import StringProperty
    
    numbers = ('ZERO', 'ONE', 'TWO', 'THREE', 'FOUR', 'FIVE', 'SIX', 'SEVEN', 'EIGHT', 'NINE')
    num_numbers = ('NUMPAD_0', 'NUMPAD_1', 'NUMPAD_2', 'NUMPAD_3', 'NUMPAD_4', 'NUMPAD_5', 'NUMPAD_6', 'NUMPAD_7', 'NUMPAD_8', 'NUMPAD_9')
    
    class ViewOperator(bpy.types.Operator):
        """Translate the view using mouse events"""
        bl_idname = "view3d.modal_operator"
        bl_label = "Simple View Operator"
    
        offset = StringProperty(
                default="Rotation: |",
                name="Rotation:",
                )
    
        def modal(self, context, event):
    
            if event.type == 'MOUSEMOVE':
                context.area.header_text_set(self.offset)
    
            elif event.type == 'R' and event.value == 'RELEASE':
                bpy.ops.transform.rotate('INVOKE_DEFAULT', axis=(0,0,1))
    
            elif event.type in (numbers + num_numbers) and event.value == 'RELEASE':
                if event.type in numbers:
                    num_int = numbers.index(event.type)
                else:
                    num_int = num_numbers.index(event.type)
                    
                self.offset = self.offset[:-1] + str(num_int) + self.offset[-1:]
                context.area.header_text_set(self.offset)
                
            elif event.type == 'BACK_SPACE' and event.value == 'RELEASE':
                if len(self.offset) > 11:
                    self.offset = self.offset[:-2] + self.offset[-1:]
                context.area.header_text_set(self.offset)
                
            elif event.type == 'LEFTMOUSE':
                context.area.header_text_set()
                return {'FINISHED'}
    
            elif event.type in {'RIGHTMOUSE', 'ESC'}:
                context.area.header_text_set()
                return {'CANCELLED'}
    
            return {'RUNNING_MODAL'}
    
        def invoke(self, context, event):
    
            if context.space_data.type == 'VIEW_3D':
                context.window_manager.modal_handler_add(self)
                return {'RUNNING_MODAL'}
    
            else:
                self.report({'WARNING'}, "Active space must be a View3d")
                return {'CANCELLED'}
    
    
    def register():
        bpy.utils.register_class(ViewOperator)
    
    
    def unregister():
        bpy.utils.unregister_class(ViewOperator)
    
    
    if __name__ == "__main__":
        register()
    maybe someone can use the code...

    but then i solved it different. long story...



  6. #6
    Member
    Join Date
    Dec 2011
    Location
    Germany
    Posts
    3,306
    thanks, really useful!

    i took this a little further:

    Code:
    import bpy
    from mathutils import Vector
    from math import radians
    from bpy.props import StringProperty
    
    numbers = ('ZERO', 'ONE', 'TWO', 'THREE', 'FOUR', 'FIVE', 'SIX', 'SEVEN', 'EIGHT', 'NINE')
    num_numbers = ('NUMPAD_0', 'NUMPAD_1', 'NUMPAD_2', 'NUMPAD_3', 'NUMPAD_4', 'NUMPAD_5', 'NUMPAD_6', 'NUMPAD_7', 'NUMPAD_8', 'NUMPAD_9')
    
    class ViewOperator(bpy.types.Operator):
        """Translate the view using mouse events"""
        bl_idname = "view3d.modal_operator"
        bl_label = "Simple View Operator"
    
        offset = StringProperty(
                default="Rotation: |",
                name="Rotation:",
                )
    
        def modal(self, context, event):
            
            print(event.type, event.value)
    
            if event.type == 'MOUSEMOVE':
                context.area.header_text_set(self.offset)
    
            elif event.type == 'R' and event.value == 'RELEASE':
                bpy.ops.transform.rotate('INVOKE_DEFAULT', axis=(0,0,1))
    
            elif event.type in (numbers + num_numbers) and event.value == 'RELEASE':
                if event.type in numbers:
                    num_int = numbers.index(event.type)
                else:
                    num_int = num_numbers.index(event.type)
                    
                self.offset = self.offset[:-1] + str(num_int) + self.offset[-1:]
                context.area.header_text_set(self.offset)
                
            elif event.type == 'BACK_SPACE' and event.value == 'RELEASE':
                if len(self.offset) > 11:
                    self.offset = self.offset[:-2] + self.offset[-1:]
                context.area.header_text_set(self.offset)
                
            elif (event.type == 'LEFTMOUSE') or \
                 (event.type in ('RET', 'NUMPAD_ENTER') and event.value == 'PRESS'):
                    
                if len(self.offset) > 11:
                    value = float(self.offset[10:-1])
                    bpy.ops.transform.rotate(value=(radians(value),), axis=(0,0,1))
                    context.area.header_text_set()
                    return {'FINISHED'}
                else:
                    context.area.header_text_set()
                    return {'CANCELLED'}
        
            elif event.type in {'RIGHTMOUSE', 'ESC'}:
                context.area.header_text_set()
                return {'CANCELLED'}
    
    
            return {'RUNNING_MODAL'}
    
        def invoke(self, context, event):
    
            if context.space_data.type == 'VIEW_3D':
                context.window_manager.modal_handler_add(self)
                return {'RUNNING_MODAL'}
    
            else:
                self.report({'WARNING'}, "Active space must be a View3d")
                return {'CANCELLED'}
    
    
    def register():
        bpy.utils.register_class(ViewOperator)
    
    
    def unregister():
        bpy.utils.unregister_class(ViewOperator)
    
    
    if __name__ == "__main__":
        register()
    Also interesting is, that one can call a live operator from python, but i can't make this work properly like: call live operator, wait until it finished, then do custom code. The live operator seems to get called multiple times ('RUNNING_MODAL'), or the custom code won't execute ('CANCELLED').



  7. #7
    Member
    Join Date
    Dec 2011
    Location
    Germany
    Posts
    3,306
    oh, there is a way to get user input, but not with modal operator. Calling to live operator from a standard operator (non-modal) with INVOKE_DEFAULT and not passing the value argument does the trick.

    Code:
    bpy.ops.transform.rotate('INVOKE_DEFAULT', axis=(0,0,1))



  8. #8
    but then i solved it different.
    bpy.ops.transform.rotate('INVOKE_DEFAULT', axis=(0,0,1))
    that's what i did. first i thought i can only do an 'INVOKE_DEFAULT' OR value=.., angle=..., axis=...
    But then i tryed it with 'INVOKE_DEFAULT', axis=myaxis,... and it works!



Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •