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
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)Alex
If you take this any further, I'm sure there are a few people who'd be interested in this!
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)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()# ***** 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)