How to draw in 3D view ?


Thx so much zeffii you are the best. I will try to figure out how it works.

Hi
Can someone tell my why ’ Hello World ’ does not disappear when i click on ’ on / off ’ button?




# ------ bl_info ------
bl_info = {
    'name': 'draw_test',
    'author': '',
    'version': (0, 0, 0),
    'blender': (2, 5, 7),
    'api': 36812,
    'location': '',
    'description': '',
    'warning': '',
    'wiki_url': '',
    'tracker_url': '',
    'category': 'Mesh' }

# ------ ------
import bpy
from bpy.props import *

import bgl
import blf

# ------ ------
def draw_callback_px(self, context):

    font_id = 0

    blf.position(font_id, 15, 30, 0)
    blf.size(font_id, 20, 72)
    blf.draw(font_id, 'Hello World')

# ------ panel 0 ------
class p_0_(bpy.types.Panel):

    bl_space_type = 'VIEW_3D'
    bl_region_type = 'TOOLS'

    bl_idname = 'p_0_id'
    bl_label = 'panel 0'
    bl_context = 'mesh_edit'
        
    def draw(self, context):
        layout = self.layout
                
        layout.label(text = 'Test :')
        layout.operator('f_0.op_0_id', text = 'Test')

# ------ operator 0 ------
class op_0_(bpy.types.Operator):

    bl_idname = 'f_0.op_0_id'
    bl_label = 'op 0'
    bl_options = {'REGISTER', 'UNDO'}
        
    bool_ = BoolProperty( name = 'on / off',
                          description = '',
                          default = False )

    def draw(self, context):
        layout = self.layout
        
        layout.prop(self, 'bool_')

    #def modal(self, context, event):
        #context.area.tag_redraw()

    '''
    def invoke(self, context, event):
        if context.area.type == 'VIEW_3D':

            context.window_manager.modal_handler_add(self)

            self._handle = context.region.callback_add(draw_callback_px, (self, context), 'POST_PIXEL')
            return {'RUNNING_MODAL'}
        else:
            self.report({'WARNING'}, "View3D not found, cannot run operator")
            return {'CANCELLED'}
        '''

    def execute(self, context):
                
        self._handle = context.region.callback_add(draw_callback_px, (self, context), 'POST_PIXEL')
                
        if context.area.type == 'VIEW_3D':
            if self.bool_ == True:
                #context.window_manager.modal_handler_add(self._handle)
                                
                context.region.callback_add(draw_callback_px, (self, context), 'POST_PIXEL')
                        
            else:
                context.region.callback_remove(self._handle)
                context.area.tag_redraw()

        return {'FINISHED'}


# ------ classes to register ------
class_list = [ p_0_,
               op_0_ ]



# ------ register ------
def register():
    for c in class_list:
        bpy.utils.register_class(c)

# ------ unregister ------
def unregister():
    for c in class_list:
        bpy.utils.unregister_class(c)

# ------ ------
if __name__ == "__main__":
    register()



i’d like to help but first ditch all the gratuitous white space and indent with 4 spaces instead of 8.

OK done. I do it this way because its easier for me to see parts of the code.
Thx for helping me.

that’s better now give the operator and panel class more meaningful names.

maybe a good resource for you: http://wiki.blender.org/index.php/Dev:2.5/Py/API/Intro and http://www.blender.org/documentation/blender_python_api_2_57_release/
i’d recommend following conventions while you seek help. Compare the structure of the classes and how they are named with some of the scripts available on the foundation’s servers : http://wiki.blender.org/index.php/Extensions:2.5/Py/Scripts

Thank you for your reply. The code that i posted is just to solve the problem. It does not need meaningful names.
Those links that you posted i have seen them and looked through them a lot of times.
I just thought that it would be easier for someone who has already done the same thing to point out why it does not work.

Thx zeffii i will check those out.




# ------ bl_info ------
bl_info = {
    'name': 'draw_test',
    'author': '',
    'version': (0, 0, 0),
    'blender': (2, 5, 7),
    'api': 36812,
    'location': '',
    'description': '',
    'warning': '',
    'wiki_url': '',
    'tracker_url': '',
    'category': 'Mesh' }



# ------ ------
import bpy
from bpy.props import *

import bgl
import blf



class test():

    display = 0
    list_0 = []



def list_clear_(l):
        l[:] = []
        return l



# ------ ------
def draw_callback_px(self, context):

    font_id = 0

    blf.position(font_id, 15, 30, 0)
    blf.size(font_id, 20, 72)
    blf.draw(font_id, 'Hello World')




# ------ panel 0 ------
class p_0_(bpy.types.Panel):

    bl_space_type = 'VIEW_3D'
    bl_region_type = 'TOOLS'

    bl_idname = 'p_0_id'
    bl_label = 'panel 0'
    bl_context = 'mesh_edit'

    def draw(self, context):
        layout = self.layout

        layout.label(text = 'Test :')
        layout.operator('f_0.op_0_id', text = 'Test')



# ------ operator 0 ------
class op_0_(bpy.types.Operator):

    bl_idname = 'f_0.op_0_id'
    bl_label = 'op 0'
    bl_options = {'REGISTER', 'UNDO'}
        
    bool_ = BoolProperty( name = 'on / off',
                          description = '',
                          default = False )

    
    # ------ draw ------
    def draw(self, context):
        layout = self.layout

        layout.prop(self, 'bool_')



    # ------ execute ------
    def execute(self, context):

        if context.area.type == 'VIEW_3D':
            if self.bool_ == True :
                handle_0 = context.region.callback_add(draw_callback_px, (self, context), 'POST_PIXEL')
                
                list_clear_(test.list_0)
                test.list_0.append(handle_0)

            else:
                if len(test.list_0) == 0:
                    pass
                else:
                    context.region.callback_remove(test.list_0[0])

        context.area.tag_redraw()
        return {'FINISHED'}



# ------ classes to register ------
class_list = [ p_0_,
               op_0_ ]



# ------ register ------
def register():
    for c in class_list:
        bpy.utils.register_class(c)

# ------ unregister ------
def unregister():
    for c in class_list:
        bpy.utils.unregister_class(c)

# ------ ------
if __name__ == "__main__":
    register()


How can i stop displaying text that is being drawn in 3d view if i do not disable it with toggle button.
For example when i use operator that displays text in 3d view and i switch to different operator for example scale object. I would like it to disappear automatically when operator changes.