Home› Technical Talk

Need help with blender script...

Sage
polycounter lvl 19
Offline / Send Message
Sage polycounter lvl 19
I was pretty happy when I got the object to move from one side to another. The purpose is to create an action that mimics the offset filter in Photoshop to help in the creation of seamless textures with 3d objects. I'm trying to automate some things I do manually. Anyways when I try to add the code to a menu it doesn't like my function. In the python console if I were to type my function name, the code works so I'm not sure what to do. Any help would be great. I'm probably using the wrong syntax. The menu works. If I execute it the menu appears with the cube. When I add my function to the menu I get an error. Any help would be great. I posted this already in the blender forums, but not sure if I'll get a response. If anyone here can help that be great. Thanks.

Alex

here is the code:

import bpy
import mathutils
import bpy.utils

#functions moves and object from it's current position to the opposite side...
def offsetPosX():
bpy.context.object.location[0] = bpy.context.object.location[0]*-1

def offsetPosZ():
bpy.context.object.location[1] = bpy.context.object.location[1]*-1

def offsetPosY():
bpy.context.object.location[2] = bpy.context.object.location[2]*-1

ob_offX = offsetPosX()

class customMenu(bpy.types.Menu):
bl_label = "My Game Tools"
bl_idname = "view3D.custom_menu"

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

layout.operator("mesh.primitive_cube_add")
layout.operator(ob_offX, text = "offsetx")

def register():
bpy.utils.register_class(customMenu)
bpy.ops.wm.call_menu(name=customMenu.bl_idname)

def unregister():
bpy.utils.unregister_class(customMenu)

if __name__ == "__main__":
register()

Replies

  • ProperSquid
    Options
    Offline / Send Message
    ProperSquid polycounter lvl 12
    This should do the trick:
    from bpy import utils
    import bpy
    
    
    # Create the operator to do the offset.
    class OffsetOperator(bpy.types.Operator):
        bl_idname = "object.offset_operator"
        bl_label = "My Offset"
    
        def execute(self, context):
            loc_x = context.active_object.location.x
            context.active_object.location.x = loc_x * -1
            return {"FINISHED"}
    
    
    # Create the menu for the operator.
    class CustomMenu(bpy.types.Menu):
        bl_label = "My Game Tools"
        bl_idname = "view3D.custom_menu"
    
        def draw(self, context):
            self.layout.operator(OffsetOperator.bl_idname,
                                 text=OffsetOperator.bl_label)
    
    
    def register():
        utils.register_class(OffsetOperator)
        utils.register_class(CustomMenu)
    
    
    def unregister():
        utils.unregister_class(OffsetOperator)
        utils.unregister_class(CustomMenu)
    
    
    if __name__ == '__main__':
        register()
        bpy.ops.wm.call_menu(name=CustomMenu.bl_idname)
    
  • Sage
    Options
    Offline / Send Message
    Sage polycounter lvl 19
    What mystic voodoo is this. :O :O :O :O :O Thanks man. Works great!!!! I think I understand what you did.

    Alex
  • Michael Knubben
    Options
    Offline / Send Message
    hey, glad to see more people get into scripting Blender! Even the few scripts I use have really change the entire experience for me, and I'm always happy to see what people come up with.

    If you take this any further, I'm sure there are a few people who'd be interested in this!
  • Sage
    Options
    Offline / Send Message
    Sage polycounter lvl 19
    ProperSquid is a genius. He is helping me take it further. I'll post the proof of his genius... So the tool does the offset thing in xyz and rotate objects by 45 degress now... I love Blender, things are just a bit messy in a way, but it has gotten ten times better since I started using seriously nine months ago.

    things I want to add.

    xray mode with a slider that controls the opacity of the object. Basically have all the controls in one spot and a way to tint the color.

    set the grid to a specific size. I was going to hard code it to a power of 2. I did this in max and was rather easy. so the values would be 2, 4, 16, etc and then have a plus minus that multiplies or divides the value so it's a power of 2.

    have some modifiers there... that trivial to add though... Modifiers I use often are Solidify, subd, mirror...

    there is a B_max script for blender that adds a bunch of cool tools from 3ds max there...

    Good point, and lesson learned.

    new code:
    import math
    
    from bpy import utils
    from bpy.props import BoolProperty, EnumProperty
    import bpy
    
    ROT_LIST = [(str(math.radians(45.0)), "45", "Rotate 45 degrees."),
                (str(math.radians(0.0)), "0", "Rotate 0 degrees."),
                (str(math.radians(-45.0)), "-45", "Rotate -45 degrees.")]
    
    
    # Create the operator to do the offset.
    class Offset(bpy.types.Operator):
        bl_idname = "object.offset"
        bl_label = "Offset"
        bl_options = {'REGISTER', 'UNDO'}
    
        offset_x = BoolProperty(name="Offset X",
                                description="Offset the object on the X axis.",
                                default=True)
        offset_y = BoolProperty(name="Offset Y",
                                description="Offset the object on the Y axis.",
                                default=True)
        offset_z = BoolProperty(name="Offset Z",
                                description="Offset the object on the Z axis.",
                                default=False)
    
        def execute(self, context):
            loc_x = context.active_object.location.x
            loc_y = context.active_object.location.y
            loc_z = context.active_object.location.z
    
            context.active_object.location.x = loc_x * -1
    
            context.active_object.location.y = loc_y * -1
    
            context.active_object.location.z = loc_z * -1
    
            return {"FINISHED"}
    
    
    # Create the operator to do the rotate.
    class Rotate(bpy.types.Operator):
        bl_idname = "object.rotate"
        bl_label = "Rotate"
        bl_options = {'REGISTER', 'UNDO'}
    
        rotate_x = EnumProperty(items=ROT_LIST,
                                name="Rotate X",
                                description="Rotate the object on the X axis.",
                                default=str(math.radians(0.0)))
        rotate_y = EnumProperty(items=ROT_LIST,
                                name="Rotate Y",
                                description="Rotate the object on the Y axis.",
                                default=str(math.radians(0.0)))
        rotate_z = EnumProperty(items=ROT_LIST,
                                name="Rotate Z",
                                description="Rotate the object on the Z axis.",
                                default=str(math.radians(0.0)))
    
        def execute(self, context):
            rot_x = float(self.rotate_x)
            rot_y = float(self.rotate_y)
            rot_z = float(self.rotate_z)
    
            context.active_object.rotation_euler.x = rot_x
    
            context.active_object.rotation_euler.y = rot_y
    
            context.active_object.rotation_euler.z = rot_z
    
            return {"FINISHED"}
    
    
    # Create the menu for the operator.
    class GameToolsMenu(bpy.types.Menu):
        bl_label = "My Game Tools"
        bl_idname = "view3D.game_tools_menu"
    
        def draw(self, context):
            self.layout.operator(Offset.bl_idname,
                                 text=Offset.bl_label)
            self.layout.operator(Rotate.bl_idname,
                                 text=Rotate.bl_label)
    
    
    def register():
        utils.register_class(Offset)
        utils.register_class(Rotate)
        utils.register_class(GameToolsMenu)
    
    
    def unregister():
        utils.unregister_class(Offset)
        utils.unregister_class(Rotate)
        utils.unregister_class(GameToolsMenu)
    
    
    if __name__ == '__main__':
        register()
        bpy.ops.wm.call_menu(name=GameToolsMenu.bl_idname)
    
  • JedTheKrampus
    Options
    Offline / Send Message
    JedTheKrampus polycounter lvl 8
    You should really wrap your code with [code] tags so that we don't have to re-indent everything to try out your script.
  • Sage
    Options
    Offline / Send Message
    Sage polycounter lvl 19
    worked up this target weld script for blender... nothing fancy but it was hard for me to get it to work...
    import bpy
    
    
    
    class Target_Weld(bpy.types.Operator):
        """Tooltip"""
        bl_idname = "object.target_weld_toggle"
        bl_label = "Target Weld Toggle"
        
        if bpy.data.scenes['Scene'].tool_settings.use_mesh_automerge == False: # checks if target weld is off, then turns it on
            bpy.data.scenes['Scene'].tool_settings.use_mesh_automerge = True
            bpy.context.scene.tool_settings.snap_element = 'VERTEX' # sets snaps to vertex
    
            
        elif bpy.data.scenes['Scene'].tool_settings.use_mesh_automerge == True: # if target weld is on, it turns it off
            bpy.data.scenes['Scene'].tool_settings.use_mesh_automerge = False
            bpy.context.scene.tool_settings.snap_element = 'INCREMENT' # sets snaps setting back to grid
    
            
    def register():
        bpy.utils.register_class(Target_Weld)
    
    
    def unregister():
        bpy.utils.unregister_class(Target_Weld)
    
    
    if __name__ == "__main__":
        register()
    
    
    
    
  • Sage
    Options
    Offline / Send Message
    Sage polycounter lvl 19
    This is what I have so far for my add-on... It's far from perfect, but it sort of does what I want. The target weld toggle works provided it's not in an add on... It seems I have the wrong context, Any help would be great. Thanks. The code is also messy and the formatting is way off. Ideally for the rotate tools you launch the tool and you can select which axis it affects and you can rotate 45 or -45 degrees. I'm also having problems getting to certain functions. I can't set pivot_point. I haven't been able to figure it out. I read online a few ways to do it but I can't get it to work. I need it to make a collape multiple edges. Basically what I'm trying to do is scale with a value of 0, with pivot_point set to 'INDIVIDUAL_ORIGINS', transform_orientation set to 'LOCAL' and then run a remove doubles on the entire object to collapse the edges. Any help would be great. Thanks.


    # ***** BEGIN GPL LICENSE BLOCK *****
    #
    # This program is free software; you can redistribute it and/or
    # modify it under the terms of the GNU General Public License
    # as published by the Free Software Foundation; either version 2
    # of the License, or (at your option) any later version.
    #
    # This program is distributed in the hope that it will be useful,
    # but WITHOUT ANY WARRANTY; without even the implied warranty of
    # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    # GNU General Public License for more details.
    #
    # You should have received a copy of the GNU General Public License
    # along with this program; if not, write to the Free Software Foundation,
    # Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
    #
    # ***** END GPL LICENCE BLOCK *****
    
    bl_info = {
    	"name": "My Game Tools",
    	"author": "Sage2626",
    	"version": (0, 1, 0),
    	"blender": (2, 72, 0),
    	"location": "View3D > MyGameTools",
    	"description": "Tools for 3D Enviornment creation",
    	"warning": "",
    	"wiki_url": "",
    	"tracker_url": "",
    	"category": "3D View"}
    
    
    
    import bpy
    from bpy import utils
    
    # Offset tools defined
    # Create the operator to do the X offset.
    
    class OffsetX(bpy.types.Operator):
        bl_idname = "object.offset_x"
        bl_label = "My X Offset"
        bl_options = {'REGISTER', 'UNDO'}
    
        def execute(self, context):
            offset = context.active_object.location
            offset.x *= -1.0   #offset x location
            return {"FINISHED"}
    
    # Create the operator to do the Y offset.
    
    class OffsetY(bpy.types.Operator):
        bl_idname = "object.offset_y"
        bl_label = "My Y Offset"
        bl_options = {'REGISTER', 'UNDO'}
    
        def execute(self, context):
            offset = context.active_object.location
            offset.y *= -1.0   #offset y location
            return {"FINISHED"}
    
    # Create the operator to do the Z offset.
    
    class OffsetZ(bpy.types.Operator):
        bl_idname = "object.offset_z"
        bl_label = "My X Offset"
        bl_options = {'REGISTER', 'UNDO'}
    
        def execute(self, context):
            offset = context.active_object.location
            offset.z *= -1.0   #offset z location
            return {"FINISHED"}
    
    
    #### Rotate Tools################
    
    ################################# 45 Clockwise Rotation on X ################################
    
    
    class PosRotx(bpy.types.Operator):
        bl_idname = "object.pos_rot_x"
        bl_label = "Rotate +45"
        bl_options = {'REGISTER', 'UNDO'}
        
        def execute(self, context):
            cw_rot_x = bpy.context.active_object.rotation_euler[0]
            bpy.context.active_object.rotation_euler[0] = cw_rot_x + 0.785398
            return {"FINISHED"}
    
        
    ################################# 45 Counter Clockwise Rotation on X ################################
    
    
    class NegRotx(bpy.types.Operator):
        bl_idname = "object.neg_rot_x"
        bl_label = "Rotate -45"
        bl_options = {'REGISTER', 'UNDO'}
        
        def execute(self, context):
            ccw_rot_x = bpy.context.active_object.rotation_euler[0]
            bpy.context.active_object.rotation_euler[0] = ccw_rot_x - 0.785398
            return {"FINISHED"}
    
    
    
    ################################# 45 Clockwise Rotation on Y ################################
    
    
    class PosRoty(bpy.types.Operator):
        bl_idname = "object.pos_rot_y"
        bl_label = "Rotate +45"
        bl_options = {'REGISTER', 'UNDO'}
        
        def execute(self, context):
            cw_rot_y = bpy.context.active_object.rotation_euler[1]
            bpy.context.active_object.rotation_euler[1] = cw_rot_y + 0.785398
            return {"FINISHED"}
        
    ################################# 45 Counter Clockwise Rotation on Y ################################
    
    
    class NegRoty(bpy.types.Operator):
        bl_idname = "object.neg_rot_y"
        bl_label = "Rotate -45"
        bl_options = {'REGISTER', 'UNDO'}
        
        def execute(self, context):
            ccw_rot_y = bpy.context.active_object.rotation_euler[1]
            bpy.context.active_object.rotation_euler[1] = ccw_rot_y - 0.785398
            return {"FINISHED"}
        
    
    ################################# 45 Clockwise Rotation on Z ################################
    
    
    class PosRotz(bpy.types.Operator):
        bl_idname = "object.pos_rot_z"
        bl_label = "Rotate +45"
        bl_options = {'REGISTER', 'UNDO'}
        
        def execute(self, context):
            cw_rot_z = bpy.context.active_object.rotation_euler[2]
            bpy.context.active_object.rotation_euler[2] = cw_rot_z + 0.785398
            return {"FINISHED"}
        
    ################################# 45 Counter Clockwise Rotation on Z ################################
    
    class NegRotz(bpy.types.Operator):
        bl_idname = "object.neg_rot_z"
        bl_label = "Rotate -45"
        bl_options = {'REGISTER', 'UNDO'}
        
        def execute(self, context):
            ccw_rot_z = bpy.context.active_object.rotation_euler[2]
            bpy.context.active_object.rotation_euler[2] = ccw_rot_z - 0.785398
            return {"FINISHED"}
    
    
    ####################################### Target Weld  Toggle #####################################################
    
    
    class Target_Weld(bpy.types.Operator):
        """Target Weld tool"""
        bl_idname = "object.target_weld_toggle"
        bl_label = "Target Weld Toggle"
        
        if bpy.data.scenes['Scene'].tool_settings.use_mesh_automerge == False: # checks if target weld is off, then turns it on
            bpy.data.scenes['Scene'].tool_settings.use_mesh_automerge = True
            bpy.context.scene.tool_settings.snap_element = 'VERTEX' # sets snaps to vertex
    
            
        elif bpy.data.scenes['Scene'].tool_settings.use_mesh_automerge == True: # if target weld is on, it turns it off
            bpy.data.scenes['Scene'].tool_settings.use_mesh_automerge = False
            bpy.context.scene.tool_settings.snap_element = 'INCREMENT' # sets snaps setting back to grid
    
    
    
    
    ################################# Create the menu for the operator. ###############################################
    class GameTools(bpy.types.Menu):
        bl_label = "My Game Tools"
        bl_idname = "view3D.custom_menu"
    
        def draw(self, context):
            layout = self.layout
            col = layout.column(align=True)
            #split = layout.split()
                              
            col.label(text="Offset Tools:")
            #row = col.row(align=True)
                   
            col.operator(OffsetX.bl_idname, text='         X')
            col.operator(OffsetY.bl_idname, text='         Y')
            col.operator(OffsetZ.bl_idname, text='         Z')
            
            col.separator()
            
            col.label(text="Rotate Tools:")
            
            col.label(text="    Rotate X:")
            col.operator(PosRotx.bl_idname, text='     + 45')
            col.operator(NegRotx.bl_idname, text='     -   45')
            
            col.separator()
            col.label(text="    Rotate Y:")
            col.operator(PosRoty.bl_idname, text='     + 45')
            col.operator(NegRoty.bl_idname, text='     -   45')
            
            col.separator()
            col.label(text="    Rotate Z:")
            col.operator(PosRotz.bl_idname, text='     + 45')
            col.operator(NegRotz.bl_idname, text='     -   45')
            
            col.separator()
            
            col.label(text="   Mesh Tools:")
            
            col.operator(Target_Weld.bl_idname, text= "Target Weld Toggle")
    
    
    def register():
        utils.register_class(OffsetX)
        utils.register_class(OffsetY)
        utils.register_class(OffsetZ)
        utils.register_class(PosRotx)
        utils.register_class(NegRotx)
        utils.register_class(PosRoty)
        utils.register_class(NegRoty)
        utils.register_class(PosRotz)
        utils.register_class(NegRotz)
        utils.register_class(Target_Weld)
        utils.register_class(GameTools)
    
    
    def unregister():
        utils.unregister_class(OffsetX)
        utils.unregister_class(OffsetY)
        utils.unregister_class(OffsetZ)
        utils.uregister_class(PosRotx)
        utils.uregister_class(NegRotx)
        utils.uregister_class(PosRoty)
        utils.uregister_class(NegRoty)
        utils.uregister_class(PosRotz)
        utils.uregister_class(NegRotz)
        utils.uregister_class(Target_Weld)
        utils.unregister_class(GameTools)
    
    
    if __name__ == '__main__':
        register()
        bpy.ops.wm.call_menu(name=GameTools.bl_idname)
    
Sign In or Register to comment.