add templates menu for OSL, use preprocessor directive color for decorators in python.
This commit is contained in:
92
release/scripts/templates_py/addon_add_object.py
Normal file
92
release/scripts/templates_py/addon_add_object.py
Normal file
@@ -0,0 +1,92 @@
|
||||
bl_info = {
|
||||
"name": "New Object",
|
||||
"author": "Your Name Here",
|
||||
"version": (1, 0),
|
||||
"blender": (2, 65, 0),
|
||||
"location": "View3D > Add > Mesh > New Object",
|
||||
"description": "Adds a new Mesh Object",
|
||||
"warning": "",
|
||||
"wiki_url": "",
|
||||
"tracker_url": "",
|
||||
"category": "Add Mesh"}
|
||||
|
||||
|
||||
import bpy
|
||||
from bpy.types import Operator
|
||||
from bpy.props import FloatVectorProperty
|
||||
from bpy_extras.object_utils import AddObjectHelper, object_data_add
|
||||
from mathutils import Vector
|
||||
|
||||
|
||||
def add_object(self, context):
|
||||
scale_x = self.scale.x
|
||||
scale_y = self.scale.y
|
||||
|
||||
verts = [Vector((-1 * scale_x, 1 * scale_y, 0)),
|
||||
Vector((1 * scale_x, 1 * scale_y, 0)),
|
||||
Vector((1 * scale_x, -1 * scale_y, 0)),
|
||||
Vector((-1 * scale_x, -1 * scale_y, 0)),
|
||||
]
|
||||
|
||||
edges = []
|
||||
faces = [[0, 1, 2, 3]]
|
||||
|
||||
mesh = bpy.data.meshes.new(name="New Object Mesh")
|
||||
mesh.from_pydata(verts, edges, faces)
|
||||
# useful for development when the mesh may be invalid.
|
||||
# mesh.validate(verbose=True)
|
||||
object_data_add(context, mesh, operator=self)
|
||||
|
||||
|
||||
class OBJECT_OT_add_object(Operator, AddObjectHelper):
|
||||
"""Create a new Mesh Object"""
|
||||
bl_idname = "mesh.add_object"
|
||||
bl_label = "Add Mesh Object"
|
||||
bl_options = {'REGISTER', 'UNDO'}
|
||||
|
||||
scale = FloatVectorProperty(
|
||||
name="scale",
|
||||
default=(1.0, 1.0, 1.0),
|
||||
subtype='TRANSLATION',
|
||||
description="scaling",
|
||||
)
|
||||
|
||||
def execute(self, context):
|
||||
|
||||
add_object(self, context)
|
||||
|
||||
return {'FINISHED'}
|
||||
|
||||
|
||||
# Registration
|
||||
|
||||
def add_object_button(self, context):
|
||||
self.layout.operator(
|
||||
OBJECT_OT_add_object.bl_idname,
|
||||
text="Add Object",
|
||||
icon='PLUGIN')
|
||||
|
||||
|
||||
# This allows you to right click on a button and link to the manual
|
||||
def add_object_manual_map():
|
||||
url_manual_prefix = "http://wiki.blender.org/index.php/Doc:2.6/Manual/"
|
||||
url_manual_mapping = (
|
||||
("bpy.ops.mesh.add_object", "Modeling/Objects"),
|
||||
)
|
||||
return url_manual_prefix, url_manual_mapping
|
||||
|
||||
|
||||
def register():
|
||||
bpy.utils.register_class(OBJECT_OT_add_object)
|
||||
bpy.utils.register_manual_map(add_object_manual_map)
|
||||
bpy.types.INFO_MT_mesh_add.append(add_object_button)
|
||||
|
||||
|
||||
def unregister():
|
||||
bpy.utils.unregister_class(OBJECT_OT_add_object)
|
||||
bpy.utils.unregister_manual_map(add_object_manual_map)
|
||||
bpy.types.INFO_MT_mesh_add.remove(add_object_button)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
register()
|
||||
122
release/scripts/templates_py/background_job.py
Normal file
122
release/scripts/templates_py/background_job.py
Normal file
@@ -0,0 +1,122 @@
|
||||
# This script is an example of how you can run blender from the command line
|
||||
# (in background mode with no interface) to automate tasks, in this example it
|
||||
# creates a text object, camera and light, then renders and/or saves it.
|
||||
# This example also shows how you can parse command line options to scripts.
|
||||
#
|
||||
# Example usage for this test.
|
||||
# blender --background --factory-startup --python $HOME/background_job.py -- \
|
||||
# --text="Hello World" \
|
||||
# --render="/tmp/hello" \
|
||||
# --save="/tmp/hello.blend"
|
||||
#
|
||||
# Notice:
|
||||
# '--factory-startup' is used to avoid the user default settings from
|
||||
# interfearing with automated scene generation.
|
||||
#
|
||||
# '--' causes blender to ignore all following arguments so python can use them.
|
||||
#
|
||||
# See blender --help for details.
|
||||
|
||||
import bpy
|
||||
|
||||
|
||||
def example_function(text, save_path, render_path):
|
||||
|
||||
scene = bpy.context.scene
|
||||
|
||||
# Clear existing objects.
|
||||
scene.camera = None
|
||||
for obj in scene.objects:
|
||||
scene.objects.unlink(obj)
|
||||
|
||||
txt_data = bpy.data.curves.new(name="MyText", type='FONT')
|
||||
|
||||
# Text Object
|
||||
txt_ob = bpy.data.objects.new(name="MyText", object_data=txt_data)
|
||||
scene.objects.link(txt_ob) # add the data to the scene as an object
|
||||
txt_data.body = text # the body text to the command line arg given
|
||||
txt_data.align = 'CENTER' # center text
|
||||
|
||||
# Camera
|
||||
cam_data = bpy.data.cameras.new("MyCam")
|
||||
cam_ob = bpy.data.objects.new(name="MyCam", object_data=cam_data)
|
||||
scene.objects.link(cam_ob) # instance the camera object in the scene
|
||||
scene.camera = cam_ob # set the active camera
|
||||
cam_ob.location = 0.0, 0.0, 10.0
|
||||
|
||||
# Lamp
|
||||
lamp_data = bpy.data.lamps.new("MyLamp", 'POINT')
|
||||
lamp_ob = bpy.data.objects.new(name="MyCam", object_data=lamp_data)
|
||||
scene.objects.link(lamp_ob)
|
||||
lamp_ob.location = 2.0, 2.0, 5.0
|
||||
|
||||
if save_path:
|
||||
try:
|
||||
f = open(save_path, 'w')
|
||||
f.close()
|
||||
ok = True
|
||||
except:
|
||||
print("Cannot save to path %r" % save_path)
|
||||
|
||||
import traceback
|
||||
traceback.print_exc()
|
||||
|
||||
if ok:
|
||||
bpy.ops.wm.save_as_mainfile(filepath=save_path)
|
||||
|
||||
if render_path:
|
||||
render = scene.render
|
||||
render.use_file_extension = True
|
||||
render.filepath = render_path
|
||||
bpy.ops.render.render(write_still=True)
|
||||
|
||||
|
||||
def main():
|
||||
import sys # to get command line args
|
||||
import argparse # to parse options for us and print a nice help message
|
||||
|
||||
# get the args passed to blender after "--", all of which are ignored by
|
||||
# blender so scripts may receive their own arguments
|
||||
argv = sys.argv
|
||||
|
||||
if "--" not in argv:
|
||||
argv = [] # as if no args are passed
|
||||
else:
|
||||
argv = argv[argv.index("--") + 1:] # get all args after "--"
|
||||
|
||||
# When --help or no args are given, print this help
|
||||
usage_text = \
|
||||
"Run blender in background mode with this script:"
|
||||
" blender --background --python " + __file__ + " -- [options]"
|
||||
|
||||
parser = argparse.ArgumentParser(description=usage_text)
|
||||
|
||||
# Example utility, add some text and renders or saves it (with options)
|
||||
# Possible types are: string, int, long, choice, float and complex.
|
||||
parser.add_argument("-t", "--text", dest="text", type=str, required=True,
|
||||
help="This text will be used to render an image")
|
||||
|
||||
parser.add_argument("-s", "--save", dest="save_path", metavar='FILE',
|
||||
help="Save the generated file to the specified path")
|
||||
parser.add_argument("-r", "--render", dest="render_path", metavar='FILE',
|
||||
help="Render an image to the specified path")
|
||||
|
||||
args = parser.parse_args(argv) # In this example we wont use the args
|
||||
|
||||
if not argv:
|
||||
parser.print_help()
|
||||
return
|
||||
|
||||
if not args.text:
|
||||
print("Error: --text=\"some string\" argument not given, aborting.")
|
||||
parser.print_help()
|
||||
return
|
||||
|
||||
# Run the example function
|
||||
example_function(args.text, args.save_path, args.render_path)
|
||||
|
||||
print("batch job finished, exiting")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
33
release/scripts/templates_py/batch_export.py
Normal file
33
release/scripts/templates_py/batch_export.py
Normal file
@@ -0,0 +1,33 @@
|
||||
# exports each selected object into its own file
|
||||
|
||||
import bpy
|
||||
import os
|
||||
|
||||
# export to blend file location
|
||||
basedir = os.path.dirname(bpy.data.filepath)
|
||||
|
||||
if not basedir:
|
||||
raise Exception("Blend file is not saved")
|
||||
|
||||
selection = bpy.context.selected_objects
|
||||
|
||||
bpy.ops.object.select_all(action='DESELECT')
|
||||
|
||||
for obj in selection:
|
||||
|
||||
obj.select = True
|
||||
|
||||
name = bpy.path.clean_name(obj.name)
|
||||
fn = os.path.join(basedir, name)
|
||||
|
||||
bpy.ops.export_scene.fbx(filepath=fn + ".fbx", use_selection=True)
|
||||
|
||||
## Can be used for multiple formats
|
||||
# bpy.ops.export_scene.x3d(filepath=fn + ".x3d", use_selection=True)
|
||||
|
||||
obj.select = False
|
||||
|
||||
print("written:", fn)
|
||||
|
||||
for obj in selection:
|
||||
obj.select = True
|
||||
22
release/scripts/templates_py/bmesh_simple.py
Normal file
22
release/scripts/templates_py/bmesh_simple.py
Normal file
@@ -0,0 +1,22 @@
|
||||
# This example assumes we have a mesh object selected
|
||||
|
||||
import bpy
|
||||
import bmesh
|
||||
|
||||
# Get the active mesh
|
||||
me = bpy.context.object.data
|
||||
|
||||
|
||||
# Get a BMesh representation
|
||||
bm = bmesh.new() # create an empty BMesh
|
||||
bm.from_mesh(me) # fill it in from a Mesh
|
||||
|
||||
|
||||
# Modify the BMesh, can do anything here...
|
||||
for v in bm.verts:
|
||||
v.co.x += 1.0
|
||||
|
||||
|
||||
# Finish up, write the bmesh back to the mesh
|
||||
bm.to_mesh(me)
|
||||
bm.free() # free and prevent further access
|
||||
23
release/scripts/templates_py/bmesh_simple_editmode.py
Normal file
23
release/scripts/templates_py/bmesh_simple_editmode.py
Normal file
@@ -0,0 +1,23 @@
|
||||
# This example assumes we have a mesh object in edit-mode
|
||||
|
||||
import bpy
|
||||
import bmesh
|
||||
|
||||
# Get the active mesh
|
||||
obj = bpy.context.edit_object
|
||||
me = obj.data
|
||||
|
||||
|
||||
# Get a BMesh representation
|
||||
bm = bmesh.from_edit_mesh(me)
|
||||
|
||||
bm.faces.active = None
|
||||
|
||||
# Modify the BMesh, can do anything here...
|
||||
for v in bm.verts:
|
||||
v.co.x += 1.0
|
||||
|
||||
|
||||
# Show the updates in the viewport
|
||||
# and recalculate n-gon tessellation.
|
||||
bmesh.update_edit_mesh(me, True)
|
||||
37
release/scripts/templates_py/builtin_keyingset.py
Normal file
37
release/scripts/templates_py/builtin_keyingset.py
Normal file
@@ -0,0 +1,37 @@
|
||||
import bpy
|
||||
|
||||
|
||||
class BUILTIN_KSI_hello(bpy.types.KeyingSetInfo):
|
||||
bl_label = "Hello World KeyingSet"
|
||||
|
||||
# poll - test for whether Keying Set can be used at all
|
||||
def poll(ksi, context):
|
||||
return context.active_object or context.selected_objects
|
||||
|
||||
# iterator - go over all relevant data, calling generate()
|
||||
def iterator(ksi, context, ks):
|
||||
for ob in context.selected_objects:
|
||||
ksi.generate(context, ks, ob)
|
||||
|
||||
# generator - populate Keying Set with property paths to use
|
||||
def generate(ksi, context, ks, data):
|
||||
id_block = data.id_data
|
||||
|
||||
ks.paths.add(id_block, "location")
|
||||
|
||||
for i in range(5):
|
||||
ks.paths.add(id_block, "layers", i, group_method='NAMED', group_name="5x Hello Layers")
|
||||
|
||||
ks.paths.add(id_block, "show_x_ray", group_method='NONE')
|
||||
|
||||
|
||||
def register():
|
||||
bpy.utils.register_class(BUILTIN_KSI_hello)
|
||||
|
||||
|
||||
def unregister():
|
||||
bpy.utils.unregister_class(BUILTIN_KSI_hello)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
register()
|
||||
35
release/scripts/templates_py/driver_functions.py
Normal file
35
release/scripts/templates_py/driver_functions.py
Normal file
@@ -0,0 +1,35 @@
|
||||
# This script defines functions to be used directly in drivers expressions to
|
||||
# extend the builtin set of python functions.
|
||||
#
|
||||
# This can be executed on manually or set to 'Register' to
|
||||
# initialize thefunctions on file load.
|
||||
|
||||
|
||||
# two sample functions
|
||||
def invert(f):
|
||||
""" Simple function call:
|
||||
|
||||
invert(val)
|
||||
"""
|
||||
return 1.0 - f
|
||||
|
||||
|
||||
uuid_store = {}
|
||||
|
||||
|
||||
def slow_value(value, fac, uuid):
|
||||
""" Delay the value by a factor, use a unique string to allow
|
||||
use in multiple drivers without conflict:
|
||||
|
||||
slow_value(val, 0.5, "my_value")
|
||||
"""
|
||||
value_prev = uuid_store.get(uuid, value)
|
||||
uuid_store[uuid] = value_new = (value_prev * fac) + (value * (1.0 - fac))
|
||||
return value_new
|
||||
|
||||
|
||||
import bpy
|
||||
|
||||
# Add variable defined in this script into the drivers namespace.
|
||||
bpy.app.driver_namespace["invert"] = invert
|
||||
bpy.app.driver_namespace["slow_value"] = slow_value
|
||||
73
release/scripts/templates_py/gamelogic.py
Normal file
73
release/scripts/templates_py/gamelogic.py
Normal file
@@ -0,0 +1,73 @@
|
||||
# This script must be assigned to a python controller
|
||||
# where it can access the object that owns it and the sensors/actuators that it connects to.
|
||||
|
||||
import bge
|
||||
|
||||
# support for Vector(), Matrix() types and advanced functions like Matrix.Scale(...) and Matrix.Rotation(...)
|
||||
# import mathutils
|
||||
|
||||
# for functions like getWindowWidth(), getWindowHeight()
|
||||
# import Rasterizer
|
||||
|
||||
|
||||
def main():
|
||||
cont = bge.logic.getCurrentController()
|
||||
|
||||
# The KX_GameObject that owns this controller.
|
||||
own = cont.owner
|
||||
|
||||
# for scripts that deal with spacial logic
|
||||
own_pos = own.worldPosition
|
||||
|
||||
# Some example functions, remove to write your own script.
|
||||
# check for a positive sensor, will run on any object without errors.
|
||||
print("Logic info for KX_GameObject", own.name)
|
||||
input = False
|
||||
|
||||
for sens in cont.sensors:
|
||||
# The sensor can be on another object, we may want to use it
|
||||
own_sens = sens.owner
|
||||
print(" sensor:", sens.name, end=" ")
|
||||
if sens.positive:
|
||||
print("(true)")
|
||||
input = True
|
||||
else:
|
||||
print("(false)")
|
||||
|
||||
for actu in cont.actuators:
|
||||
# The actuator can be on another object, we may want to use it
|
||||
own_actu = actu.owner
|
||||
print(" actuator:", actu.name)
|
||||
|
||||
# This runs the actuator or turns it off
|
||||
# note that actuators will continue to run unless explicitly turned off.
|
||||
if input:
|
||||
cont.activate(actu)
|
||||
else:
|
||||
cont.deactivate(actu)
|
||||
|
||||
# Its also good practice to get sensors and actuators by name
|
||||
# rather then index so any changes to their order wont break the script.
|
||||
|
||||
# sens_key = cont.sensors["key_sensor"]
|
||||
# actu_motion = cont.actuators["motion"]
|
||||
|
||||
# Loop through all other objects in the scene
|
||||
sce = bge.logic.getCurrentScene()
|
||||
print("Scene Objects:", sce.name)
|
||||
for ob in sce.objects:
|
||||
print(" ", ob.name, ob.worldPosition)
|
||||
|
||||
# Example where collision objects are checked for their properties
|
||||
# adding to our objects "life" property
|
||||
"""
|
||||
actu_collide = cont.sensors["collision_sens"]
|
||||
for ob in actu_collide.objectHitList:
|
||||
# Check to see the object has this property
|
||||
if "life" in ob:
|
||||
own["life"] += ob["life"]
|
||||
ob["life"] = 0
|
||||
print(own["life"])
|
||||
"""
|
||||
|
||||
main()
|
||||
27
release/scripts/templates_py/gamelogic_module.py
Normal file
27
release/scripts/templates_py/gamelogic_module.py
Normal file
@@ -0,0 +1,27 @@
|
||||
# This module can be accessed by a python controller with
|
||||
# its execution method set to 'Module'
|
||||
# * Set the module string to "gamelogic_module.main" (without quotes)
|
||||
# * When renaming the script it MUST have a .py extension
|
||||
# * External text modules are supported as long as they are at
|
||||
# the same location as the blendfile or one of its libraries.
|
||||
|
||||
import bge
|
||||
|
||||
# variables defined here will only be set once when the
|
||||
# module is first imported. Set object specific vars
|
||||
# inside the function if you intend to use the module
|
||||
# with multiple objects.
|
||||
|
||||
|
||||
def main(cont):
|
||||
own = cont.owner
|
||||
|
||||
sens = cont.sensors['mySensor']
|
||||
actu = cont.actuators['myActuator']
|
||||
|
||||
if sens.positive:
|
||||
cont.activate(actu)
|
||||
else:
|
||||
cont.deactivate(actu)
|
||||
|
||||
# dont call main(bge.logic.getCurrentController()), the py controller will
|
||||
17
release/scripts/templates_py/gamelogic_simple.py
Normal file
17
release/scripts/templates_py/gamelogic_simple.py
Normal file
@@ -0,0 +1,17 @@
|
||||
import bge
|
||||
|
||||
|
||||
def main():
|
||||
|
||||
cont = bge.logic.getCurrentController()
|
||||
own = cont.owner
|
||||
|
||||
sens = cont.sensors['mySensor']
|
||||
actu = cont.actuators['myActuator']
|
||||
|
||||
if sens.positive:
|
||||
cont.activate(actu)
|
||||
else:
|
||||
cont.deactivate(actu)
|
||||
|
||||
main()
|
||||
72
release/scripts/templates_py/operator_file_export.py
Normal file
72
release/scripts/templates_py/operator_file_export.py
Normal file
@@ -0,0 +1,72 @@
|
||||
import bpy
|
||||
|
||||
|
||||
def write_some_data(context, filepath, use_some_setting):
|
||||
print("running write_some_data...")
|
||||
f = open(filepath, 'w', encoding='utf-8')
|
||||
f.write("Hello World %s" % use_some_setting)
|
||||
f.close()
|
||||
|
||||
return {'FINISHED'}
|
||||
|
||||
|
||||
# ExportHelper is a helper class, defines filename and
|
||||
# invoke() function which calls the file selector.
|
||||
from bpy_extras.io_utils import ExportHelper
|
||||
from bpy.props import StringProperty, BoolProperty, EnumProperty
|
||||
from bpy.types import Operator
|
||||
|
||||
|
||||
class ExportSomeData(Operator, ExportHelper):
|
||||
"""This appears in the tooltip of the operator and in the generated docs"""
|
||||
bl_idname = "export_test.some_data" # important since its how bpy.ops.import_test.some_data is constructed
|
||||
bl_label = "Export Some Data"
|
||||
|
||||
# ExportHelper mixin class uses this
|
||||
filename_ext = ".txt"
|
||||
|
||||
filter_glob = StringProperty(
|
||||
default="*.txt",
|
||||
options={'HIDDEN'},
|
||||
)
|
||||
|
||||
# List of operator properties, the attributes will be assigned
|
||||
# to the class instance from the operator settings before calling.
|
||||
use_setting = BoolProperty(
|
||||
name="Example Boolean",
|
||||
description="Example Tooltip",
|
||||
default=True,
|
||||
)
|
||||
|
||||
type = EnumProperty(
|
||||
name="Example Enum",
|
||||
description="Choose between two items",
|
||||
items=(('OPT_A', "First Option", "Description one"),
|
||||
('OPT_B', "Second Option", "Description two")),
|
||||
default='OPT_A',
|
||||
)
|
||||
|
||||
def execute(self, context):
|
||||
return write_some_data(context, self.filepath, self.use_setting)
|
||||
|
||||
|
||||
# Only needed if you want to add into a dynamic menu
|
||||
def menu_func_export(self, context):
|
||||
self.layout.operator(ExportSomeData.bl_idname, text="Text Export Operator")
|
||||
|
||||
|
||||
def register():
|
||||
bpy.utils.register_class(ExportSomeData)
|
||||
bpy.types.INFO_MT_file_export.append(menu_func_export)
|
||||
|
||||
|
||||
def unregister():
|
||||
bpy.utils.unregister_class(ExportSomeData)
|
||||
bpy.types.INFO_MT_file_export.remove(menu_func_export)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
register()
|
||||
|
||||
# test call
|
||||
bpy.ops.export_test.some_data('INVOKE_DEFAULT')
|
||||
75
release/scripts/templates_py/operator_file_import.py
Normal file
75
release/scripts/templates_py/operator_file_import.py
Normal file
@@ -0,0 +1,75 @@
|
||||
import bpy
|
||||
|
||||
|
||||
def read_some_data(context, filepath, use_some_setting):
|
||||
print("running read_some_data...")
|
||||
f = open(filepath, 'r', encoding='utf-8')
|
||||
data = f.read()
|
||||
f.close()
|
||||
|
||||
# would normally load the data here
|
||||
print(data)
|
||||
|
||||
return {'FINISHED'}
|
||||
|
||||
|
||||
# ImportHelper is a helper class, defines filename and
|
||||
# invoke() function which calls the file selector.
|
||||
from bpy_extras.io_utils import ImportHelper
|
||||
from bpy.props import StringProperty, BoolProperty, EnumProperty
|
||||
from bpy.types import Operator
|
||||
|
||||
|
||||
class ImportSomeData(Operator, ImportHelper):
|
||||
"""This appears in the tooltip of the operator and in the generated docs"""
|
||||
bl_idname = "import_test.some_data" # important since its how bpy.ops.import_test.some_data is constructed
|
||||
bl_label = "Import Some Data"
|
||||
|
||||
# ImportHelper mixin class uses this
|
||||
filename_ext = ".txt"
|
||||
|
||||
filter_glob = StringProperty(
|
||||
default="*.txt",
|
||||
options={'HIDDEN'},
|
||||
)
|
||||
|
||||
# List of operator properties, the attributes will be assigned
|
||||
# to the class instance from the operator settings before calling.
|
||||
use_setting = BoolProperty(
|
||||
name="Example Boolean",
|
||||
description="Example Tooltip",
|
||||
default=True,
|
||||
)
|
||||
|
||||
type = EnumProperty(
|
||||
name="Example Enum",
|
||||
description="Choose between two items",
|
||||
items=(('OPT_A', "First Option", "Description one"),
|
||||
('OPT_B', "Second Option", "Description two")),
|
||||
default='OPT_A',
|
||||
)
|
||||
|
||||
def execute(self, context):
|
||||
return read_some_data(context, self.filepath, self.use_setting)
|
||||
|
||||
|
||||
# Only needed if you want to add into a dynamic menu
|
||||
def menu_func_import(self, context):
|
||||
self.layout.operator(ImportSomeData.bl_idname, text="Text Import Operator")
|
||||
|
||||
|
||||
def register():
|
||||
bpy.utils.register_class(ImportSomeData)
|
||||
bpy.types.INFO_MT_file_import.append(menu_func_import)
|
||||
|
||||
|
||||
def unregister():
|
||||
bpy.utils.unregister_class(ImportSomeData)
|
||||
bpy.types.INFO_MT_file_import.remove(menu_func_import)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
register()
|
||||
|
||||
# test call
|
||||
bpy.ops.import_test.some_data('INVOKE_DEFAULT')
|
||||
122
release/scripts/templates_py/operator_mesh_add.py
Normal file
122
release/scripts/templates_py/operator_mesh_add.py
Normal file
@@ -0,0 +1,122 @@
|
||||
import bpy
|
||||
import bmesh
|
||||
|
||||
|
||||
def add_box(width, height, depth):
|
||||
"""
|
||||
This function takes inputs and returns vertex and face arrays.
|
||||
no actual mesh data creation is done here.
|
||||
"""
|
||||
|
||||
verts = [(+1.0, +1.0, -1.0),
|
||||
(+1.0, -1.0, -1.0),
|
||||
(-1.0, -1.0, -1.0),
|
||||
(-1.0, +1.0, -1.0),
|
||||
(+1.0, +1.0, +1.0),
|
||||
(+1.0, -1.0, +1.0),
|
||||
(-1.0, -1.0, +1.0),
|
||||
(-1.0, +1.0, +1.0),
|
||||
]
|
||||
|
||||
faces = [(0, 1, 2, 3),
|
||||
(4, 7, 6, 5),
|
||||
(0, 4, 5, 1),
|
||||
(1, 5, 6, 2),
|
||||
(2, 6, 7, 3),
|
||||
(4, 0, 3, 7),
|
||||
]
|
||||
|
||||
# apply size
|
||||
for i, v in enumerate(verts):
|
||||
verts[i] = v[0] * width, v[1] * depth, v[2] * height
|
||||
|
||||
return verts, faces
|
||||
|
||||
|
||||
from bpy.props import FloatProperty, BoolProperty, FloatVectorProperty
|
||||
|
||||
|
||||
class AddBox(bpy.types.Operator):
|
||||
"""Add a simple box mesh"""
|
||||
bl_idname = "mesh.primitive_box_add"
|
||||
bl_label = "Add Box"
|
||||
bl_options = {'REGISTER', 'UNDO'}
|
||||
|
||||
width = FloatProperty(
|
||||
name="Width",
|
||||
description="Box Width",
|
||||
min=0.01, max=100.0,
|
||||
default=1.0,
|
||||
)
|
||||
height = FloatProperty(
|
||||
name="Height",
|
||||
description="Box Height",
|
||||
min=0.01, max=100.0,
|
||||
default=1.0,
|
||||
)
|
||||
depth = FloatProperty(
|
||||
name="Depth",
|
||||
description="Box Depth",
|
||||
min=0.01, max=100.0,
|
||||
default=1.0,
|
||||
)
|
||||
|
||||
# generic transform props
|
||||
view_align = BoolProperty(
|
||||
name="Align to View",
|
||||
default=False,
|
||||
)
|
||||
location = FloatVectorProperty(
|
||||
name="Location",
|
||||
subtype='TRANSLATION',
|
||||
)
|
||||
rotation = FloatVectorProperty(
|
||||
name="Rotation",
|
||||
subtype='EULER',
|
||||
)
|
||||
|
||||
def execute(self, context):
|
||||
|
||||
verts_loc, faces = add_box(self.width,
|
||||
self.height,
|
||||
self.depth,
|
||||
)
|
||||
|
||||
mesh = bpy.data.meshes.new("Box")
|
||||
|
||||
bm = bmesh.new()
|
||||
|
||||
for v_co in verts_loc:
|
||||
bm.verts.new(v_co)
|
||||
|
||||
for f_idx in faces:
|
||||
bm.faces.new([bm.verts[i] for i in f_idx])
|
||||
|
||||
bm.to_mesh(mesh)
|
||||
mesh.update()
|
||||
|
||||
# add the mesh as an object into the scene with this utility module
|
||||
from bpy_extras import object_utils
|
||||
object_utils.object_data_add(context, mesh, operator=self)
|
||||
|
||||
return {'FINISHED'}
|
||||
|
||||
|
||||
def menu_func(self, context):
|
||||
self.layout.operator(AddBox.bl_idname, icon='MESH_CUBE')
|
||||
|
||||
|
||||
def register():
|
||||
bpy.utils.register_class(AddBox)
|
||||
bpy.types.INFO_MT_mesh_add.append(menu_func)
|
||||
|
||||
|
||||
def unregister():
|
||||
bpy.utils.unregister_class(AddBox)
|
||||
bpy.types.INFO_MT_mesh_add.remove(menu_func)
|
||||
|
||||
if __name__ == "__main__":
|
||||
register()
|
||||
|
||||
# test call
|
||||
bpy.ops.mesh.primitive_box_add()
|
||||
51
release/scripts/templates_py/operator_modal.py
Normal file
51
release/scripts/templates_py/operator_modal.py
Normal file
@@ -0,0 +1,51 @@
|
||||
import bpy
|
||||
from bpy.props import IntProperty, FloatProperty
|
||||
|
||||
|
||||
class ModalOperator(bpy.types.Operator):
|
||||
"""Move an object with the mouse, example"""
|
||||
bl_idname = "object.modal_operator"
|
||||
bl_label = "Simple Modal Operator"
|
||||
|
||||
first_mouse_x = IntProperty()
|
||||
first_value = FloatProperty()
|
||||
|
||||
def modal(self, context, event):
|
||||
if event.type == 'MOUSEMOVE':
|
||||
delta = self.first_mouse_x - event.mouse_x
|
||||
context.object.location.x = self.first_value + delta * 0.01
|
||||
|
||||
elif event.type == 'LEFTMOUSE':
|
||||
return {'FINISHED'}
|
||||
|
||||
elif event.type in {'RIGHTMOUSE', 'ESC'}:
|
||||
context.object.location.x = self.first_value
|
||||
return {'CANCELLED'}
|
||||
|
||||
return {'RUNNING_MODAL'}
|
||||
|
||||
def invoke(self, context, event):
|
||||
if context.object:
|
||||
self.first_mouse_x = event.mouse_x
|
||||
self.first_value = context.object.location.x
|
||||
|
||||
context.window_manager.modal_handler_add(self)
|
||||
return {'RUNNING_MODAL'}
|
||||
else:
|
||||
self.report({'WARNING'}, "No active object, could not finish")
|
||||
return {'CANCELLED'}
|
||||
|
||||
|
||||
def register():
|
||||
bpy.utils.register_class(ModalOperator)
|
||||
|
||||
|
||||
def unregister():
|
||||
bpy.utils.unregister_class(ModalOperator)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
register()
|
||||
|
||||
# test call
|
||||
bpy.ops.object.modal_operator('INVOKE_DEFAULT')
|
||||
79
release/scripts/templates_py/operator_modal_draw.py
Normal file
79
release/scripts/templates_py/operator_modal_draw.py
Normal file
@@ -0,0 +1,79 @@
|
||||
import bpy
|
||||
import bgl
|
||||
import blf
|
||||
|
||||
|
||||
def draw_callback_px(self, context):
|
||||
print("mouse points", len(self.mouse_path))
|
||||
|
||||
font_id = 0 # XXX, need to find out how best to get this.
|
||||
|
||||
# draw some text
|
||||
blf.position(font_id, 15, 30, 0)
|
||||
blf.size(font_id, 20, 72)
|
||||
blf.draw(font_id, "Hello Word " + str(len(self.mouse_path)))
|
||||
|
||||
# 50% alpha, 2 pixel width line
|
||||
bgl.glEnable(bgl.GL_BLEND)
|
||||
bgl.glColor4f(0.0, 0.0, 0.0, 0.5)
|
||||
bgl.glLineWidth(2)
|
||||
|
||||
bgl.glBegin(bgl.GL_LINE_STRIP)
|
||||
for x, y in self.mouse_path:
|
||||
bgl.glVertex2i(x, y)
|
||||
|
||||
bgl.glEnd()
|
||||
|
||||
# restore opengl defaults
|
||||
bgl.glLineWidth(1)
|
||||
bgl.glDisable(bgl.GL_BLEND)
|
||||
bgl.glColor4f(0.0, 0.0, 0.0, 1.0)
|
||||
|
||||
|
||||
class ModalDrawOperator(bpy.types.Operator):
|
||||
"""Draw a line with the mouse"""
|
||||
bl_idname = "view3d.modal_operator"
|
||||
bl_label = "Simple Modal View3D Operator"
|
||||
|
||||
def modal(self, context, event):
|
||||
context.area.tag_redraw()
|
||||
|
||||
if event.type == 'MOUSEMOVE':
|
||||
self.mouse_path.append((event.mouse_region_x, event.mouse_region_y))
|
||||
|
||||
elif event.type == 'LEFTMOUSE':
|
||||
bpy.types.SpaceView3D.draw_handler_remove(self._handle, 'WINDOW')
|
||||
return {'FINISHED'}
|
||||
|
||||
elif event.type in {'RIGHTMOUSE', 'ESC'}:
|
||||
bpy.types.SpaceView3D.draw_handler_remove(self._handle, 'WINDOW')
|
||||
return {'CANCELLED'}
|
||||
|
||||
return {'RUNNING_MODAL'}
|
||||
|
||||
def invoke(self, context, event):
|
||||
if context.area.type == 'VIEW_3D':
|
||||
# the arguments we pass the the callback
|
||||
args = (self, context)
|
||||
# Add the region OpenGL drawing callback
|
||||
# draw in view space with 'POST_VIEW' and 'PRE_VIEW'
|
||||
self._handle = bpy.types.SpaceView3D.draw_handler_add(draw_callback_px, args, 'WINDOW', 'POST_PIXEL')
|
||||
|
||||
self.mouse_path = []
|
||||
|
||||
context.window_manager.modal_handler_add(self)
|
||||
return {'RUNNING_MODAL'}
|
||||
else:
|
||||
self.report({'WARNING'}, "View3D not found, cannot run operator")
|
||||
return {'CANCELLED'}
|
||||
|
||||
|
||||
def register():
|
||||
bpy.utils.register_class(ModalDrawOperator)
|
||||
|
||||
|
||||
def unregister():
|
||||
bpy.utils.unregister_class(ModalDrawOperator)
|
||||
|
||||
if __name__ == "__main__":
|
||||
register()
|
||||
45
release/scripts/templates_py/operator_modal_timer.py
Normal file
45
release/scripts/templates_py/operator_modal_timer.py
Normal file
@@ -0,0 +1,45 @@
|
||||
import bpy
|
||||
|
||||
|
||||
class ModalTimerOperator(bpy.types.Operator):
|
||||
"""Operator which runs its self from a timer"""
|
||||
bl_idname = "wm.modal_timer_operator"
|
||||
bl_label = "Modal Timer Operator"
|
||||
|
||||
_timer = None
|
||||
|
||||
def modal(self, context, event):
|
||||
if event.type == 'ESC':
|
||||
return self.cancel(context)
|
||||
|
||||
if event.type == 'TIMER':
|
||||
# change theme color, silly!
|
||||
color = context.user_preferences.themes[0].view_3d.space.back
|
||||
color.s = 1.0
|
||||
color.h += 0.01
|
||||
|
||||
return {'PASS_THROUGH'}
|
||||
|
||||
def execute(self, context):
|
||||
self._timer = context.window_manager.event_timer_add(0.1, context.window)
|
||||
context.window_manager.modal_handler_add(self)
|
||||
return {'RUNNING_MODAL'}
|
||||
|
||||
def cancel(self, context):
|
||||
context.window_manager.event_timer_remove(self._timer)
|
||||
return {'CANCELLED'}
|
||||
|
||||
|
||||
def register():
|
||||
bpy.utils.register_class(ModalTimerOperator)
|
||||
|
||||
|
||||
def unregister():
|
||||
bpy.utils.unregister_class(ModalTimerOperator)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
register()
|
||||
|
||||
# test call
|
||||
bpy.ops.wm.modal_timer_operator()
|
||||
70
release/scripts/templates_py/operator_modal_view3d.py
Normal file
70
release/scripts/templates_py/operator_modal_view3d.py
Normal file
@@ -0,0 +1,70 @@
|
||||
import bpy
|
||||
from mathutils import Vector
|
||||
from bpy.props import FloatVectorProperty
|
||||
|
||||
|
||||
class ViewOperator(bpy.types.Operator):
|
||||
"""Translate the view using mouse events"""
|
||||
bl_idname = "view3d.modal_operator"
|
||||
bl_label = "Simple View Operator"
|
||||
|
||||
offset = FloatVectorProperty(
|
||||
name="Offset",
|
||||
size=3,
|
||||
)
|
||||
|
||||
def execute(self, context):
|
||||
v3d = context.space_data
|
||||
rv3d = v3d.region_3d
|
||||
|
||||
rv3d.view_location = self._initial_location + Vector(self.offset)
|
||||
|
||||
def modal(self, context, event):
|
||||
v3d = context.space_data
|
||||
rv3d = v3d.region_3d
|
||||
|
||||
if event.type == 'MOUSEMOVE':
|
||||
self.offset = (self._initial_mouse - Vector((event.mouse_x, event.mouse_y, 0.0))) * 0.02
|
||||
self.execute(context)
|
||||
context.area.header_text_set("Offset %.4f %.4f %.4f" % tuple(self.offset))
|
||||
|
||||
elif event.type == 'LEFTMOUSE':
|
||||
context.area.header_text_set()
|
||||
return {'FINISHED'}
|
||||
|
||||
elif event.type in {'RIGHTMOUSE', 'ESC'}:
|
||||
rv3d.view_location = self._initial_location
|
||||
context.area.header_text_set()
|
||||
return {'CANCELLED'}
|
||||
|
||||
return {'RUNNING_MODAL'}
|
||||
|
||||
def invoke(self, context, event):
|
||||
|
||||
if context.space_data.type == 'VIEW_3D':
|
||||
v3d = context.space_data
|
||||
rv3d = v3d.region_3d
|
||||
|
||||
if rv3d.view_perspective == 'CAMERA':
|
||||
rv3d.view_perspective = 'PERSP'
|
||||
|
||||
self._initial_mouse = Vector((event.mouse_x, event.mouse_y, 0.0))
|
||||
self._initial_location = rv3d.view_location.copy()
|
||||
|
||||
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()
|
||||
110
release/scripts/templates_py/operator_modal_view3d_raycast.py
Normal file
110
release/scripts/templates_py/operator_modal_view3d_raycast.py
Normal file
@@ -0,0 +1,110 @@
|
||||
import bpy
|
||||
from mathutils import Vector
|
||||
from bpy_extras import view3d_utils
|
||||
|
||||
|
||||
def main(context, event, ray_max=10000.0):
|
||||
"""Run this function on left mouse, execute the ray cast"""
|
||||
# get the context arguments
|
||||
scene = context.scene
|
||||
region = context.region
|
||||
rv3d = context.region_data
|
||||
coord = event.mouse_region_x, event.mouse_region_y
|
||||
|
||||
# get the ray from the viewport and mouse
|
||||
view_vector = view3d_utils.region_2d_to_vector_3d(region, rv3d, coord)
|
||||
ray_origin = view3d_utils.region_2d_to_origin_3d(region, rv3d, coord)
|
||||
ray_target = ray_origin + (view_vector * ray_max)
|
||||
|
||||
|
||||
def visible_objects_and_duplis():
|
||||
"""Loop over (object, matrix) pairs (mesh only)"""
|
||||
|
||||
for obj in context.visible_objects:
|
||||
if obj.type == 'MESH':
|
||||
yield (obj, obj.matrix_world.copy())
|
||||
|
||||
if obj.dupli_type != 'NONE':
|
||||
obj.dupli_list_create(scene)
|
||||
for dob in obj.dupli_list:
|
||||
obj_dupli = dob.object
|
||||
if obj_dupli.type == 'MESH':
|
||||
yield (obj_dupli, dob.matrix.copy())
|
||||
|
||||
obj.dupli_list_clear()
|
||||
|
||||
def obj_ray_cast(obj, matrix):
|
||||
"""Wrapper for ray casting that moves the ray into object space"""
|
||||
|
||||
# get the ray relative to the object
|
||||
matrix_inv = matrix.inverted()
|
||||
ray_origin_obj = matrix_inv * ray_origin
|
||||
ray_target_obj = matrix_inv * ray_target
|
||||
|
||||
# cast the ray
|
||||
hit, normal, face_index = obj.ray_cast(ray_origin_obj, ray_target_obj)
|
||||
|
||||
if face_index != -1:
|
||||
return hit, normal, face_index
|
||||
else:
|
||||
return None, None, None
|
||||
|
||||
# cast rays and find the closest object
|
||||
best_length_squared = ray_max * ray_max
|
||||
best_obj = None
|
||||
|
||||
for obj, matrix in visible_objects_and_duplis():
|
||||
if obj.type == 'MESH':
|
||||
hit, normal, face_index = obj_ray_cast(obj, matrix)
|
||||
if hit is not None:
|
||||
hit_world = matrix * hit
|
||||
scene.cursor_location = hit_world
|
||||
length_squared = (hit_world - ray_origin).length_squared
|
||||
if length_squared < best_length_squared:
|
||||
best_length_squared = length_squared
|
||||
best_obj = obj
|
||||
|
||||
# now we have the object under the mouse cursor,
|
||||
# we could do lots of stuff but for the example just select.
|
||||
if best_obj is not None:
|
||||
best_obj.select = True
|
||||
context.scene.objects.active = best_obj
|
||||
|
||||
|
||||
class ViewOperatorRayCast(bpy.types.Operator):
|
||||
"""Modal object selection with a ray cast"""
|
||||
bl_idname = "view3d.modal_operator_raycast"
|
||||
bl_label = "RayCast View Operator"
|
||||
|
||||
def modal(self, context, event):
|
||||
if event.type in {'MIDDLEMOUSE', 'WHEELUPMOUSE', 'WHEELDOWNMOUSE'}:
|
||||
# allow navigation
|
||||
return {'PASS_THROUGH'}
|
||||
elif event.type == 'LEFTMOUSE':
|
||||
main(context, event)
|
||||
return {'RUNNING_MODAL'}
|
||||
elif event.type in {'RIGHTMOUSE', 'ESC'}:
|
||||
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(ViewOperatorRayCast)
|
||||
|
||||
|
||||
def unregister():
|
||||
bpy.utils.unregister_class(ViewOperatorRayCast)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
register()
|
||||
|
||||
59
release/scripts/templates_py/operator_node.py
Normal file
59
release/scripts/templates_py/operator_node.py
Normal file
@@ -0,0 +1,59 @@
|
||||
import bpy
|
||||
|
||||
|
||||
def main(context):
|
||||
space = context.space_data
|
||||
node_tree = space.node_tree
|
||||
node_active = context.active_node
|
||||
node_selected = context.selected_nodes
|
||||
|
||||
# now we have the context, perform a simple operation
|
||||
if node_active in node_selected:
|
||||
node_selected.remove(node_active)
|
||||
if len(node_selected) != 1:
|
||||
operator.report({'ERROR'}, "2 nodes must be selected")
|
||||
return
|
||||
|
||||
node_other, = node_selected
|
||||
|
||||
# now we have 2 nodes to operate on
|
||||
if not node_active.inputs:
|
||||
operator.report({'ERROR'}, "Active node has no inputs")
|
||||
return
|
||||
|
||||
if not node_other.outputs:
|
||||
operator.report({'ERROR'}, "Selected node has no outputs")
|
||||
return
|
||||
|
||||
socket_in = node_active.inputs[0]
|
||||
socket_out = node_other.outputs[0]
|
||||
|
||||
# add a link between the two nodes
|
||||
node_link = node_tree.links.new(socket_in, socket_out)
|
||||
|
||||
|
||||
class NodeOperator(bpy.types.Operator):
|
||||
"""Tooltip"""
|
||||
bl_idname = "node.simple_operator"
|
||||
bl_label = "Simple Node Operator"
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
space = context.space_data
|
||||
return space.type == 'NODE_EDITOR'
|
||||
|
||||
def execute(self, context):
|
||||
main(context)
|
||||
return {'FINISHED'}
|
||||
|
||||
|
||||
def register():
|
||||
bpy.utils.register_class(NodeOperator)
|
||||
|
||||
|
||||
def unregister():
|
||||
bpy.utils.unregister_class(NodeOperator)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
register()
|
||||
35
release/scripts/templates_py/operator_simple.py
Normal file
35
release/scripts/templates_py/operator_simple.py
Normal file
@@ -0,0 +1,35 @@
|
||||
import bpy
|
||||
|
||||
|
||||
def main(context):
|
||||
for ob in context.scene.objects:
|
||||
print(ob)
|
||||
|
||||
|
||||
class SimpleOperator(bpy.types.Operator):
|
||||
"""Tooltip"""
|
||||
bl_idname = "object.simple_operator"
|
||||
bl_label = "Simple Object Operator"
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
return context.active_object is not None
|
||||
|
||||
def execute(self, context):
|
||||
main(context)
|
||||
return {'FINISHED'}
|
||||
|
||||
|
||||
def register():
|
||||
bpy.utils.register_class(SimpleOperator)
|
||||
|
||||
|
||||
def unregister():
|
||||
bpy.utils.unregister_class(SimpleOperator)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
register()
|
||||
|
||||
# test call
|
||||
bpy.ops.object.simple_operator()
|
||||
56
release/scripts/templates_py/operator_uv.py
Normal file
56
release/scripts/templates_py/operator_uv.py
Normal file
@@ -0,0 +1,56 @@
|
||||
import bpy
|
||||
|
||||
|
||||
def main(context):
|
||||
obj = context.active_object
|
||||
mesh = obj.data
|
||||
|
||||
is_editmode = (obj.mode == 'EDIT')
|
||||
if is_editmode:
|
||||
bpy.ops.object.mode_set(mode='OBJECT', toggle=False)
|
||||
|
||||
if not mesh.uv_textures:
|
||||
uvtex = bpy.ops.mesh.uv_texture_add()
|
||||
else:
|
||||
uvtex = mesh.uv_textures.active
|
||||
|
||||
# adjust UVs
|
||||
for i, uv in enumerate(uvtex.data):
|
||||
uvs = uv.uv1, uv.uv2, uv.uv3, uv.uv4
|
||||
for j, v_idx in enumerate(mesh.faces[i].vertices):
|
||||
if uv.select_uv[j]:
|
||||
# apply the location of the vertex as a UV
|
||||
uvs[j][:] = mesh.vertices[v_idx].co.xy
|
||||
|
||||
if is_editmode:
|
||||
bpy.ops.object.mode_set(mode='EDIT', toggle=False)
|
||||
|
||||
|
||||
class UvOperator(bpy.types.Operator):
|
||||
"""UV Operator description"""
|
||||
bl_idname = "uv.simple_operator"
|
||||
bl_label = "Simple UV Operator"
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
obj = context.active_object
|
||||
return (obj and obj.type == 'MESH')
|
||||
|
||||
def execute(self, context):
|
||||
main(context)
|
||||
return {'FINISHED'}
|
||||
|
||||
|
||||
def register():
|
||||
bpy.utils.register_class(UvOperator)
|
||||
|
||||
|
||||
def unregister():
|
||||
bpy.utils.unregister_class(UvOperator)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
register()
|
||||
|
||||
# test call
|
||||
bpy.ops.uv.simple_operator()
|
||||
14
release/scripts/templates_py/script_stub.py
Normal file
14
release/scripts/templates_py/script_stub.py
Normal file
@@ -0,0 +1,14 @@
|
||||
# This stub runs a python script relative to the currently open
|
||||
# blend file, useful when editing scripts externally.
|
||||
|
||||
import bpy
|
||||
import os
|
||||
|
||||
# Use your own script name here:
|
||||
filename = "my_script.py"
|
||||
|
||||
filepath = os.path.join(os.path.dirname(bpy.data.filepath), filename)
|
||||
global_namespace = {"__file__": filepath, "__name__": "__main__"}
|
||||
file = open(filepath, 'rb')
|
||||
exec(compile(file.read(), filepath, 'exec'), global_namespace)
|
||||
file.close()
|
||||
49
release/scripts/templates_py/ui_menu.py
Normal file
49
release/scripts/templates_py/ui_menu.py
Normal file
@@ -0,0 +1,49 @@
|
||||
import bpy
|
||||
|
||||
|
||||
class CustomMenu(bpy.types.Menu):
|
||||
bl_label = "Custom Menu"
|
||||
bl_idname = "OBJECT_MT_custom_menu"
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
layout.operator("wm.open_mainfile")
|
||||
layout.operator("wm.save_as_mainfile").copy = True
|
||||
|
||||
layout.operator("object.shade_smooth")
|
||||
|
||||
layout.label(text="Hello world!", icon='WORLD_DATA')
|
||||
|
||||
# use an operator enum property to populate a sub-menu
|
||||
layout.operator_menu_enum("object.select_by_type",
|
||||
property="type",
|
||||
text="Select All by Type...",
|
||||
)
|
||||
|
||||
# call another menu
|
||||
layout.operator("wm.call_menu", text="Unwrap").name = "VIEW3D_MT_uv_map"
|
||||
|
||||
|
||||
def draw_item(self, context):
|
||||
layout = self.layout
|
||||
layout.menu(CustomMenu.bl_idname)
|
||||
|
||||
|
||||
def register():
|
||||
bpy.utils.register_class(CustomMenu)
|
||||
|
||||
# lets add ourselves to the main header
|
||||
bpy.types.INFO_HT_header.append(draw_item)
|
||||
|
||||
|
||||
def unregister():
|
||||
bpy.utils.unregister_class(CustomMenu)
|
||||
|
||||
bpy.types.INFO_HT_header.remove(draw_item)
|
||||
|
||||
if __name__ == "__main__":
|
||||
register()
|
||||
|
||||
# The menu can also be called from scripts
|
||||
bpy.ops.wm.call_menu(name=CustomMenu.bl_idname)
|
||||
26
release/scripts/templates_py/ui_menu_simple.py
Normal file
26
release/scripts/templates_py/ui_menu_simple.py
Normal file
@@ -0,0 +1,26 @@
|
||||
import bpy
|
||||
|
||||
|
||||
class SimpleCustomMenu(bpy.types.Menu):
|
||||
bl_label = "Simple Custom Menu"
|
||||
bl_idname = "OBJECT_MT_simple_custom_menu"
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
layout.operator("wm.open_mainfile")
|
||||
layout.operator("wm.save_as_mainfile")
|
||||
|
||||
|
||||
def register():
|
||||
bpy.utils.register_class(SimpleCustomMenu)
|
||||
|
||||
|
||||
def unregister():
|
||||
bpy.utils.unregister_class(SimpleCustomMenu)
|
||||
|
||||
if __name__ == "__main__":
|
||||
register()
|
||||
|
||||
# The menu can also be called from scripts
|
||||
bpy.ops.wm.call_menu(name=SimpleCustomMenu.bl_idname)
|
||||
73
release/scripts/templates_py/ui_panel.py
Normal file
73
release/scripts/templates_py/ui_panel.py
Normal file
@@ -0,0 +1,73 @@
|
||||
import bpy
|
||||
|
||||
|
||||
class LayoutDemoPanel(bpy.types.Panel):
|
||||
"""Creates a Panel in the scene context of the properties editor"""
|
||||
bl_label = "Layout Demo"
|
||||
bl_idname = "SCENE_PT_layout"
|
||||
bl_space_type = 'PROPERTIES'
|
||||
bl_region_type = 'WINDOW'
|
||||
bl_context = "scene"
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
scene = context.scene
|
||||
|
||||
# Create a simple row.
|
||||
layout.label(text=" Simple Row:")
|
||||
|
||||
row = layout.row()
|
||||
row.prop(scene, "frame_start")
|
||||
row.prop(scene, "frame_end")
|
||||
|
||||
# Create an row where the buttons are aligned to each other.
|
||||
layout.label(text=" Aligned Row:")
|
||||
|
||||
row = layout.row(align=True)
|
||||
row.prop(scene, "frame_start")
|
||||
row.prop(scene, "frame_end")
|
||||
|
||||
# Create two columns, by using a split layout.
|
||||
split = layout.split()
|
||||
|
||||
# First column
|
||||
col = split.column()
|
||||
col.label(text="Column One:")
|
||||
col.prop(scene, "frame_end")
|
||||
col.prop(scene, "frame_start")
|
||||
|
||||
# Second column, aligned
|
||||
col = split.column(align=True)
|
||||
col.label(text="Column Two:")
|
||||
col.prop(scene, "frame_start")
|
||||
col.prop(scene, "frame_end")
|
||||
|
||||
# Big render button
|
||||
layout.label(text="Big Button:")
|
||||
row = layout.row()
|
||||
row.scale_y = 3.0
|
||||
row.operator("render.render")
|
||||
|
||||
# Different sizes in a row
|
||||
layout.label(text="Different button sizes:")
|
||||
row = layout.row(align=True)
|
||||
row.operator("render.render")
|
||||
|
||||
sub = row.row()
|
||||
sub.scale_x = 2.0
|
||||
sub.operator("render.render")
|
||||
|
||||
row.operator("render.render")
|
||||
|
||||
|
||||
def register():
|
||||
bpy.utils.register_class(LayoutDemoPanel)
|
||||
|
||||
|
||||
def unregister():
|
||||
bpy.utils.unregister_class(LayoutDemoPanel)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
register()
|
||||
38
release/scripts/templates_py/ui_panel_simple.py
Normal file
38
release/scripts/templates_py/ui_panel_simple.py
Normal file
@@ -0,0 +1,38 @@
|
||||
import bpy
|
||||
|
||||
|
||||
class HelloWorldPanel(bpy.types.Panel):
|
||||
"""Creates a Panel in the Object properties window"""
|
||||
bl_label = "Hello World Panel"
|
||||
bl_idname = "OBJECT_PT_hello"
|
||||
bl_space_type = 'PROPERTIES'
|
||||
bl_region_type = 'WINDOW'
|
||||
bl_context = "object"
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
obj = context.object
|
||||
|
||||
row = layout.row()
|
||||
row.label(text="Hello world!", icon='WORLD_DATA')
|
||||
|
||||
row = layout.row()
|
||||
row.label(text="Active object is: " + obj.name)
|
||||
row = layout.row()
|
||||
row.prop(obj, "name")
|
||||
|
||||
row = layout.row()
|
||||
row.operator("mesh.primitive_cube_add")
|
||||
|
||||
|
||||
def register():
|
||||
bpy.utils.register_class(HelloWorldPanel)
|
||||
|
||||
|
||||
def unregister():
|
||||
bpy.utils.unregister_class(HelloWorldPanel)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
register()
|
||||
Reference in New Issue
Block a user