Merging r51923 through r52851 from trunk into soc-2011-tomato
This commit is contained in:
108
doc/python_api/examples/bmesh.ops.1.py
Normal file
108
doc/python_api/examples/bmesh.ops.1.py
Normal file
@@ -0,0 +1,108 @@
|
||||
# This script uses bmesh operators to make 2 links of a chain.
|
||||
|
||||
import bpy
|
||||
import bmesh
|
||||
import math
|
||||
import mathutils
|
||||
|
||||
# Make a new BMesh
|
||||
bm = bmesh.new()
|
||||
|
||||
# Add a circle XXX, should return all geometry created, not just verts.
|
||||
bmesh.ops.create_circle(
|
||||
bm,
|
||||
cap_ends=False,
|
||||
diameter=0.2,
|
||||
segments=8)
|
||||
|
||||
|
||||
# Spin and deal with geometry on side 'a'
|
||||
edges_start_a = bm.edges[:]
|
||||
geom_start_a = bm.verts[:] + edges_start_a
|
||||
ret = bmesh.ops.spin(
|
||||
bm,
|
||||
geom=geom_start_a,
|
||||
angle=math.radians(180.0),
|
||||
steps=8,
|
||||
axis=(1.0, 0.0, 0.0),
|
||||
cent=(0.0, 1.0, 0.0))
|
||||
edges_end_a = [ele for ele in ret["geom_last"]
|
||||
if isinstance(ele, bmesh.types.BMEdge)]
|
||||
del ret
|
||||
|
||||
|
||||
# Extrude and create geometry on side 'b'
|
||||
ret = bmesh.ops.extrude_edge_only(
|
||||
bm,
|
||||
edges=edges_start_a)
|
||||
geom_extrude_mid = ret["geom"]
|
||||
del ret
|
||||
|
||||
|
||||
# Collect the edges to spin XXX, 'extrude_edge_only' could return this.
|
||||
verts_extrude_b = [ele for ele in geom_extrude_mid
|
||||
if isinstance(ele, bmesh.types.BMVert)]
|
||||
edges_extrude_b = [ele for ele in geom_extrude_mid
|
||||
if isinstance(ele, bmesh.types.BMEdge) and ele.is_boundary]
|
||||
bmesh.ops.translate(
|
||||
bm,
|
||||
verts=verts_extrude_b,
|
||||
vec=(0.0, 0.0, 1.0))
|
||||
|
||||
|
||||
# Create the circle on side 'b'
|
||||
ret = bmesh.ops.spin(
|
||||
bm,
|
||||
geom=verts_extrude_b + edges_extrude_b,
|
||||
angle=-math.radians(180.0),
|
||||
steps=8,
|
||||
axis=(1.0, 0.0, 0.0),
|
||||
cent=(0.0, 1.0, 1.0))
|
||||
edges_end_b = [ele for ele in ret["geom_last"]
|
||||
if isinstance(ele, bmesh.types.BMEdge)]
|
||||
del ret
|
||||
|
||||
|
||||
# Bridge the resulting edge loops of both spins 'a & b'
|
||||
bmesh.ops.bridge_loops(
|
||||
bm,
|
||||
edges=edges_end_a + edges_end_b)
|
||||
|
||||
|
||||
# Now we have made a links of the chain, make a copy and rotate it
|
||||
# (so this looks something like a chain)
|
||||
|
||||
ret = bmesh.ops.duplicate(
|
||||
bm,
|
||||
geom=bm.verts[:] + bm.edges[:] + bm.faces[:])
|
||||
geom_dupe = ret["geom"]
|
||||
verts_dupe = [ele for ele in geom_dupe if isinstance(ele, bmesh.types.BMVert)]
|
||||
del ret
|
||||
|
||||
# position the new link
|
||||
bmesh.ops.translate(
|
||||
bm,
|
||||
verts=verts_dupe,
|
||||
vec=(0.0, 0.0, 2.0))
|
||||
bmesh.ops.rotate(
|
||||
bm,
|
||||
verts=verts_dupe,
|
||||
cent=(0.0, 1.0, 0.0),
|
||||
matrix=mathutils.Matrix.Rotation(math.radians(90.0), 3, 'Z'))
|
||||
|
||||
# Done with creating the mesh, simply link it into the scene so we can see it
|
||||
|
||||
# Finish up, write the bmesh into a new mesh
|
||||
me = bpy.data.meshes.new("Mesh")
|
||||
bm.to_mesh(me)
|
||||
bm.free()
|
||||
|
||||
|
||||
# Add the mesh to the scene
|
||||
scene = bpy.context.scene
|
||||
obj = bpy.data.objects.new("Object", me)
|
||||
scene.objects.link(obj)
|
||||
|
||||
# Select and make active
|
||||
scene.objects.active = obj
|
||||
obj.select = True
|
||||
@@ -254,13 +254,6 @@ General functions
|
||||
|
||||
:rtype: list [float], len(getSpectrum()) == 512
|
||||
|
||||
.. function:: stopDSP()
|
||||
|
||||
Stops the sound driver using DSP effects.
|
||||
|
||||
Only the fmod sound driver supports this.
|
||||
DSP can be computationally expensive.
|
||||
|
||||
.. function:: getMaxLogicFrame()
|
||||
|
||||
Gets the maximum number of logic frames per render frame.
|
||||
@@ -331,6 +324,24 @@ General functions
|
||||
|
||||
.. warning: Not implimented yet
|
||||
|
||||
.. function:: getExitKey()
|
||||
|
||||
Gets the key used to exit the game engine
|
||||
|
||||
:return: The key (defaults to :mod:`bge.events.ESCKEY`)
|
||||
:rtype: int
|
||||
|
||||
.. function:: setExitKey(key)
|
||||
|
||||
Sets the key used to exit the game engine
|
||||
|
||||
:arg key: A key constant from :mod:`bge.events`
|
||||
:type key: int
|
||||
|
||||
.. function:: NextFrame()
|
||||
|
||||
Render next frame (if Python has control)
|
||||
|
||||
*****************
|
||||
Utility functions
|
||||
*****************
|
||||
@@ -373,6 +384,10 @@ Utility functions
|
||||
.. function:: PrintGLInfo()
|
||||
|
||||
Prints GL Extension Info into the console
|
||||
|
||||
.. function:: PrintMemInfo()
|
||||
|
||||
Prints engine statistics into the console
|
||||
|
||||
*********
|
||||
Constants
|
||||
@@ -401,6 +416,45 @@ Sensor Status
|
||||
.. data:: KX_SENSOR_ACTIVE
|
||||
.. data:: KX_SENSOR_JUST_DEACTIVATED
|
||||
|
||||
---------------
|
||||
Armature Sensor
|
||||
---------------
|
||||
|
||||
.. _armaturesensor-type:
|
||||
|
||||
See :class:`bge.types.KX_ArmatureSensor.type`
|
||||
|
||||
.. data:: KX_ARMSENSOR_STATE_CHANGED
|
||||
|
||||
Detect that the constraint is changing state (active/inactive)
|
||||
|
||||
:value: 0
|
||||
|
||||
.. data:: KX_ARMSENSOR_LIN_ERROR_BELOW
|
||||
|
||||
Detect that the constraint linear error is above a threshold
|
||||
|
||||
:value: 1
|
||||
|
||||
.. data:: KX_ARMSENSOR_LIN_ERROR_ABOVE
|
||||
|
||||
Detect that the constraint linear error is below a threshold
|
||||
|
||||
:value: 2
|
||||
|
||||
.. data:: KX_ARMSENSOR_ROT_ERROR_BELOW
|
||||
|
||||
Detect that the constraint rotation error is above a threshold
|
||||
|
||||
:value: 3
|
||||
|
||||
.. data:: KX_ARMSENSOR_ROT_ERROR_ABOVE
|
||||
|
||||
Detect that the constraint rotation error is below a threshold
|
||||
|
||||
:value: 4
|
||||
|
||||
|
||||
.. _logic-property-sensor:
|
||||
|
||||
---------------
|
||||
@@ -483,6 +537,52 @@ See :class:`bge.types.BL_ActionActuator`
|
||||
.. data:: KX_ACTIONACT_LOOPEND
|
||||
.. data:: KX_ACTIONACT_PROPERTY
|
||||
|
||||
-----------------
|
||||
Armature Actuator
|
||||
-----------------
|
||||
|
||||
.. _armatureactuator-constants-type:
|
||||
|
||||
See :class:`bge.types.BL_ArmatureActuator.type`
|
||||
|
||||
.. data:: KX_ACT_ARMATURE_RUN
|
||||
|
||||
Just make sure the armature will be updated on the next graphic frame.
|
||||
This is the only persistent mode of the actuator:
|
||||
it executes automatically once per frame until stopped by a controller
|
||||
|
||||
:value: 0
|
||||
|
||||
.. data:: KX_ACT_ARMATURE_ENABLE
|
||||
|
||||
Enable the constraint.
|
||||
|
||||
:value: 1
|
||||
|
||||
.. data:: KX_ACT_ARMATURE_DISABLE
|
||||
|
||||
Disable the constraint (runtime constraint values are not updated).
|
||||
|
||||
:value: 2
|
||||
|
||||
.. data:: KX_ACT_ARMATURE_SETTARGET
|
||||
|
||||
Change target and subtarget of constraint.
|
||||
|
||||
:value: 3
|
||||
|
||||
.. data:: KX_ACT_ARMATURE_SETWEIGHT
|
||||
|
||||
Change weight of constraint (IK only).
|
||||
|
||||
:value: 4
|
||||
|
||||
.. data:: KX_ACT_ARMATURE_SETINFLUENCE
|
||||
|
||||
Change influence of constraint.
|
||||
|
||||
:value: 5
|
||||
|
||||
-------------------
|
||||
Constraint Actuator
|
||||
-------------------
|
||||
@@ -493,31 +593,31 @@ See :class:`bge.types.KX_ConstraintActuator.option`
|
||||
|
||||
* Applicable to Distance constraint:
|
||||
|
||||
.. data:: KX_ACT_CONSTRAINT_NORMAL
|
||||
.. data:: KX_CONSTRAINTACT_NORMAL
|
||||
|
||||
Activate alignment to surface
|
||||
|
||||
.. data:: KX_ACT_CONSTRAINT_DISTANCE
|
||||
.. data:: KX_CONSTRAINTACT_DISTANCE
|
||||
|
||||
Activate distance control
|
||||
|
||||
.. data:: KX_ACT_CONSTRAINT_LOCAL
|
||||
.. data:: KX_CONSTRAINTACT_LOCAL
|
||||
|
||||
Direction of the ray is along the local axis
|
||||
|
||||
* Applicable to Force field constraint:
|
||||
|
||||
.. data:: KX_ACT_CONSTRAINT_DOROTFH
|
||||
.. data:: KX_CONSTRAINTACT_DOROTFH
|
||||
|
||||
Force field act on rotation as well
|
||||
|
||||
* Applicable to both:
|
||||
|
||||
.. data:: KX_ACT_CONSTRAINT_MATERIAL
|
||||
.. data:: KX_CONSTRAINTACT_MATERIAL
|
||||
|
||||
Detect material rather than property
|
||||
|
||||
.. data:: KX_ACT_CONSTRAINT_PERMANENT
|
||||
.. data:: KX_CONSTRAINTACT_PERMANENT
|
||||
|
||||
No deactivation if ray does not hit target
|
||||
|
||||
@@ -585,27 +685,27 @@ See :class:`bge.types.KX_ConstraintActuator.limit`
|
||||
|
||||
Set orientation of Z axis
|
||||
|
||||
.. data:: KX_ACT_CONSTRAINT_FHNX
|
||||
.. data:: KX_CONSTRAINTACT_FHNX
|
||||
|
||||
Set force field along negative X axis
|
||||
|
||||
.. data:: KX_ACT_CONSTRAINT_FHNY
|
||||
.. data:: KX_CONSTRAINTACT_FHNY
|
||||
|
||||
Set force field along negative Y axis
|
||||
|
||||
.. data:: KX_ACT_CONSTRAINT_FHNZ
|
||||
.. data:: KX_CONSTRAINTACT_FHNZ
|
||||
|
||||
Set force field along negative Z axis
|
||||
|
||||
.. data:: KX_ACT_CONSTRAINT_FHPX
|
||||
.. data:: KX_CONSTRAINTACT_FHPX
|
||||
|
||||
Set force field along positive X axis
|
||||
|
||||
.. data:: KX_ACT_CONSTRAINT_FHPY
|
||||
.. data:: KX_CONSTRAINTACT_FHPY
|
||||
|
||||
Set force field along positive Y axis
|
||||
|
||||
.. data:: KX_ACT_CONSTRAINT_FHPZ
|
||||
.. data:: KX_CONSTRAINTACT_FHPZ
|
||||
|
||||
Set force field along positive Z axis
|
||||
|
||||
@@ -708,102 +808,32 @@ See :class:`bge.types.KX_SoundActuator`
|
||||
.. data:: KX_SOUNDACT_LOOPBIDIRECTIONAL_STOP
|
||||
|
||||
:value: 6
|
||||
|
||||
|
||||
-----------------
|
||||
Steering Actuator
|
||||
-----------------
|
||||
|
||||
.. _logic-steering-actuator:
|
||||
|
||||
See :class:`bge.types.KX_SteeringActuator.behavior`
|
||||
|
||||
.. data:: KX_STEERING_SEEK
|
||||
|
||||
:value: 1
|
||||
|
||||
.. data:: KX_STEERING_FLEE
|
||||
|
||||
:value: 2
|
||||
|
||||
.. data:: KX_STEERING_PATHFOLLOWING
|
||||
|
||||
:value: 3
|
||||
|
||||
|
||||
=======
|
||||
Various
|
||||
=======
|
||||
|
||||
.. _input-status:
|
||||
|
||||
------------
|
||||
Input Status
|
||||
------------
|
||||
|
||||
See :class:`bge.types.SCA_PythonKeyboard`, :class:`bge.types.SCA_PythonMouse`, :class:`bge.types.SCA_MouseSensor`, :class:`bge.types.SCA_KeyboardSensor`
|
||||
|
||||
.. data:: KX_INPUT_NONE
|
||||
.. data:: KX_INPUT_JUST_ACTIVATED
|
||||
.. data:: KX_INPUT_ACTIVE
|
||||
.. data:: KX_INPUT_JUST_RELEASED
|
||||
|
||||
-------------
|
||||
Mouse Buttons
|
||||
-------------
|
||||
|
||||
See :class:`bge.types.SCA_MouseSensor`
|
||||
|
||||
.. data:: KX_MOUSE_BUT_LEFT
|
||||
.. data:: KX_MOUSE_BUT_MIDDLE
|
||||
.. data:: KX_MOUSE_BUT_RIGHT
|
||||
|
||||
------
|
||||
States
|
||||
------
|
||||
|
||||
See :class:`bge.types.KX_StateActuator`
|
||||
|
||||
.. data:: KX_STATE1
|
||||
.. data:: KX_STATE2
|
||||
.. data:: KX_STATE3
|
||||
.. data:: KX_STATE4
|
||||
.. data:: KX_STATE5
|
||||
.. data:: KX_STATE6
|
||||
.. data:: KX_STATE7
|
||||
.. data:: KX_STATE8
|
||||
.. data:: KX_STATE9
|
||||
.. data:: KX_STATE10
|
||||
.. data:: KX_STATE11
|
||||
.. data:: KX_STATE12
|
||||
.. data:: KX_STATE13
|
||||
.. data:: KX_STATE14
|
||||
.. data:: KX_STATE15
|
||||
.. data:: KX_STATE16
|
||||
.. data:: KX_STATE17
|
||||
.. data:: KX_STATE18
|
||||
.. data:: KX_STATE19
|
||||
.. data:: KX_STATE20
|
||||
.. data:: KX_STATE21
|
||||
.. data:: KX_STATE22
|
||||
.. data:: KX_STATE23
|
||||
.. data:: KX_STATE24
|
||||
.. data:: KX_STATE25
|
||||
.. data:: KX_STATE26
|
||||
.. data:: KX_STATE27
|
||||
.. data:: KX_STATE28
|
||||
.. data:: KX_STATE29
|
||||
.. data:: KX_STATE30
|
||||
|
||||
.. _state-actuator-operation:
|
||||
|
||||
See :class:`bge.types.KX_StateActuator.operation`
|
||||
|
||||
.. data:: KX_STATE_OP_CLR
|
||||
|
||||
Substract bits to state mask
|
||||
|
||||
:value: 0
|
||||
|
||||
.. data:: KX_STATE_OP_CPY
|
||||
|
||||
Copy state mask
|
||||
|
||||
:value: 1
|
||||
|
||||
.. data:: KX_STATE_OP_NEG
|
||||
|
||||
Invert bits to state mask
|
||||
|
||||
:value: 2
|
||||
|
||||
.. data:: KX_STATE_OP_SET
|
||||
|
||||
Add bits to state mask
|
||||
|
||||
:value: 3
|
||||
|
||||
.. _Two-D-FilterActuator-mode:
|
||||
|
||||
---------
|
||||
2D Filter
|
||||
---------
|
||||
@@ -877,6 +907,227 @@ See :class:`bge.types.KX_StateActuator.operation`
|
||||
.. data:: RAS_2DFILTER_SOBEL
|
||||
|
||||
:value: 7
|
||||
|
||||
----------------
|
||||
Armature Channel
|
||||
----------------
|
||||
.. _armaturechannel-constants-rotation-mode:
|
||||
|
||||
See :class:`bge.types.BL_ArmatureChannel.rotation_mode`
|
||||
|
||||
.. note:
|
||||
euler mode are named as in Blender UI but the actual axis order is reversed
|
||||
|
||||
.. data:: ROT_MODE_QUAT
|
||||
|
||||
Use quaternion in rotation attribute to update bone rotation.
|
||||
|
||||
:value: 0
|
||||
|
||||
.. data:: ROT_MODE_XYZ
|
||||
|
||||
Use euler_rotation and apply angles on bone's Z, Y, X axis successively.
|
||||
|
||||
:value: 1
|
||||
|
||||
.. data:: ROT_MODE_XZY
|
||||
|
||||
Use euler_rotation and apply angles on bone's Y, Z, X axis successively.
|
||||
|
||||
:value: 2
|
||||
|
||||
.. data:: ROT_MODE_YXZ
|
||||
|
||||
Use euler_rotation and apply angles on bone's Z, X, Y axis successively.
|
||||
|
||||
:value: 3
|
||||
|
||||
.. data:: ROT_MODE_YZX
|
||||
|
||||
Use euler_rotation and apply angles on bone's X, Z, Y axis successively.
|
||||
|
||||
:value: 4
|
||||
|
||||
.. data:: ROT_MODE_ZXY
|
||||
|
||||
Use euler_rotation and apply angles on bone's Y, X, Z axis successively.
|
||||
|
||||
:value: 5
|
||||
|
||||
.. data:: ROT_MODE_ZYX
|
||||
|
||||
Use euler_rotation and apply angles on bone's X, Y, Z axis successively.
|
||||
|
||||
:value: 6
|
||||
|
||||
|
||||
-------------------
|
||||
Armature Constraint
|
||||
-------------------
|
||||
.. _armatureconstraint-constants-type:
|
||||
|
||||
See :class:`bge.types.BL_ArmatureConstraint.type`
|
||||
|
||||
.. data:: CONSTRAINT_TYPE_TRACKTO
|
||||
.. data:: CONSTRAINT_TYPE_KINEMATIC
|
||||
.. data:: CONSTRAINT_TYPE_ROTLIKE
|
||||
.. data:: CONSTRAINT_TYPE_LOCLIKE
|
||||
.. data:: CONSTRAINT_TYPE_MINMAX
|
||||
.. data:: CONSTRAINT_TYPE_SIZELIKE
|
||||
.. data:: CONSTRAINT_TYPE_LOCKTRACK
|
||||
.. data:: CONSTRAINT_TYPE_STRETCHTO
|
||||
.. data:: CONSTRAINT_TYPE_CLAMPTO
|
||||
.. data:: CONSTRAINT_TYPE_TRANSFORM
|
||||
.. data:: CONSTRAINT_TYPE_DISTLIMIT
|
||||
|
||||
.. _armatureconstraint-constants-ik-type:
|
||||
|
||||
See :class:`bge.types.BL_ArmatureConstraint.ik_type`
|
||||
|
||||
.. data:: CONSTRAINT_IK_COPYPOSE
|
||||
|
||||
constraint is trying to match the position and eventually the rotation of the target.
|
||||
|
||||
:value: 0
|
||||
|
||||
.. data:: CONSTRAINT_IK_DISTANCE
|
||||
|
||||
Constraint is maintaining a certain distance to target subject to ik_mode
|
||||
|
||||
:value: 1
|
||||
|
||||
.. _armatureconstraint-constants-ik-flag:
|
||||
|
||||
See :class:`bge.types.BL_ArmatureConstraint.ik_flag`
|
||||
|
||||
.. data:: CONSTRAINT_IK_FLAG_TIP
|
||||
|
||||
Set when the constraint operates on the head of the bone and not the tail
|
||||
|
||||
:value: 1
|
||||
|
||||
.. data:: CONSTRAINT_IK_FLAG_ROT
|
||||
|
||||
Set when the constraint tries to match the orientation of the target
|
||||
|
||||
:value: 2
|
||||
|
||||
.. data:: CONSTRAINT_IK_FLAG_STRETCH
|
||||
|
||||
Set when the armature is allowed to stretch (only the bones with stretch factor > 0.0)
|
||||
|
||||
:value: 16
|
||||
|
||||
.. data:: CONSTRAINT_IK_FLAG_POS
|
||||
|
||||
Set when the constraint tries to match the position of the target.
|
||||
|
||||
:value: 32
|
||||
|
||||
.. _armatureconstraint-constants-ik-mode:
|
||||
|
||||
See :class:`bge.types.BL_ArmatureConstraint.ik_mode`
|
||||
|
||||
.. data:: CONSTRAINT_IK_MODE_INSIDE
|
||||
|
||||
The constraint tries to keep the bone within ik_dist of target
|
||||
|
||||
:value: 0
|
||||
|
||||
.. data:: CONSTRAINT_IK_MODE_OUTSIDE
|
||||
|
||||
The constraint tries to keep the bone outside ik_dist of the target
|
||||
|
||||
:value: 1
|
||||
|
||||
.. data:: CONSTRAINT_IK_MODE_ONSURFACE
|
||||
|
||||
The constraint tries to keep the bone exactly at ik_dist of the target.
|
||||
|
||||
:value: 2
|
||||
|
||||
.. _input-status:
|
||||
|
||||
----------------
|
||||
Blender Material
|
||||
----------------
|
||||
|
||||
.. data:: BL_DST_ALPHA
|
||||
.. data:: BL_DST_COLOR
|
||||
.. data:: BL_ONE
|
||||
.. data:: BL_ONE_MINUS_DST_ALPHA
|
||||
.. data:: BL_ONE_MINUS_DST_COLOR
|
||||
.. data:: BL_ONE_MINUS_SRC_ALPHA
|
||||
.. data:: BL_ONE_MINUS_SRC_COLOR
|
||||
.. data:: BL_SRC_ALPHA
|
||||
.. data:: BL_SRC_ALPHA_SATURATE
|
||||
.. data:: BL_SRC_COLOR
|
||||
.. data:: BL_ZERO
|
||||
|
||||
------------
|
||||
Input Status
|
||||
------------
|
||||
|
||||
See :class:`bge.types.SCA_PythonKeyboard`, :class:`bge.types.SCA_PythonMouse`, :class:`bge.types.SCA_MouseSensor`, :class:`bge.types.SCA_KeyboardSensor`
|
||||
|
||||
.. data:: KX_INPUT_NONE
|
||||
.. data:: KX_INPUT_JUST_ACTIVATED
|
||||
.. data:: KX_INPUT_ACTIVE
|
||||
.. data:: KX_INPUT_JUST_RELEASED
|
||||
|
||||
-------------
|
||||
KX_GameObject
|
||||
-------------
|
||||
.. _gameobject-playaction-mode:
|
||||
|
||||
See :class:`bge.types.KX_GameObject.playAction`
|
||||
|
||||
.. data:: KX_ACTION_MODE_PLAY
|
||||
|
||||
Play the action once.
|
||||
|
||||
:value: 0
|
||||
|
||||
.. data:: KX_ACTION_MODE_LOOP
|
||||
|
||||
Loop the action (repeat it).
|
||||
|
||||
:value: 1
|
||||
|
||||
.. data:: KX_ACTION_MODE_PING_PONG
|
||||
|
||||
Play the action one direct then back the other way when it has completed.
|
||||
|
||||
:value: 2
|
||||
|
||||
|
||||
-------------
|
||||
Mouse Buttons
|
||||
-------------
|
||||
|
||||
See :class:`bge.types.SCA_MouseSensor`
|
||||
|
||||
.. data:: KX_MOUSE_BUT_LEFT
|
||||
.. data:: KX_MOUSE_BUT_MIDDLE
|
||||
.. data:: KX_MOUSE_BUT_RIGHT
|
||||
|
||||
--------------------------
|
||||
Navigation Mesh Draw Modes
|
||||
--------------------------
|
||||
|
||||
.. _navmesh-draw-mode:
|
||||
|
||||
.. data:: RM_WALLS
|
||||
|
||||
Draw only the walls.
|
||||
|
||||
.. data:: RM_POLYS
|
||||
|
||||
Draw only polygons.
|
||||
|
||||
.. data:: RM_TRIS
|
||||
|
||||
Draw triangle mesh.
|
||||
|
||||
------
|
||||
Shader
|
||||
@@ -904,18 +1155,69 @@ Shader
|
||||
|
||||
.. data:: SHD_TANGENT
|
||||
|
||||
----------------
|
||||
Blender Material
|
||||
----------------
|
||||
------
|
||||
States
|
||||
------
|
||||
|
||||
.. data:: BL_DST_ALPHA
|
||||
.. data:: BL_DST_COLOR
|
||||
.. data:: BL_ONE
|
||||
.. data:: BL_ONE_MINUS_DST_ALPHA
|
||||
.. data:: BL_ONE_MINUS_DST_COLOR
|
||||
.. data:: BL_ONE_MINUS_SRC_ALPHA
|
||||
.. data:: BL_ONE_MINUS_SRC_COLOR
|
||||
.. data:: BL_SRC_ALPHA
|
||||
.. data:: BL_SRC_ALPHA_SATURATE
|
||||
.. data:: BL_SRC_COLOR
|
||||
.. data:: BL_ZERO
|
||||
See :class:`bge.types.KX_StateActuator`
|
||||
|
||||
.. data:: KX_STATE1
|
||||
.. data:: KX_STATE2
|
||||
.. data:: KX_STATE3
|
||||
.. data:: KX_STATE4
|
||||
.. data:: KX_STATE5
|
||||
.. data:: KX_STATE6
|
||||
.. data:: KX_STATE7
|
||||
.. data:: KX_STATE8
|
||||
.. data:: KX_STATE9
|
||||
.. data:: KX_STATE10
|
||||
.. data:: KX_STATE11
|
||||
.. data:: KX_STATE12
|
||||
.. data:: KX_STATE13
|
||||
.. data:: KX_STATE14
|
||||
.. data:: KX_STATE15
|
||||
.. data:: KX_STATE16
|
||||
.. data:: KX_STATE17
|
||||
.. data:: KX_STATE18
|
||||
.. data:: KX_STATE19
|
||||
.. data:: KX_STATE20
|
||||
.. data:: KX_STATE21
|
||||
.. data:: KX_STATE22
|
||||
.. data:: KX_STATE23
|
||||
.. data:: KX_STATE24
|
||||
.. data:: KX_STATE25
|
||||
.. data:: KX_STATE26
|
||||
.. data:: KX_STATE27
|
||||
.. data:: KX_STATE28
|
||||
.. data:: KX_STATE29
|
||||
.. data:: KX_STATE30
|
||||
|
||||
.. _state-actuator-operation:
|
||||
|
||||
See :class:`bge.types.KX_StateActuator.operation`
|
||||
|
||||
.. data:: KX_STATE_OP_CLR
|
||||
|
||||
Substract bits to state mask
|
||||
|
||||
:value: 0
|
||||
|
||||
.. data:: KX_STATE_OP_CPY
|
||||
|
||||
Copy state mask
|
||||
|
||||
:value: 1
|
||||
|
||||
.. data:: KX_STATE_OP_NEG
|
||||
|
||||
Invert bits to state mask
|
||||
|
||||
:value: 2
|
||||
|
||||
.. data:: KX_STATE_OP_SET
|
||||
|
||||
Add bits to state mask
|
||||
|
||||
:value: 3
|
||||
|
||||
.. _Two-D-FilterActuator-mode:
|
||||
|
||||
@@ -205,6 +205,18 @@ Types
|
||||
|
||||
:type: boolean
|
||||
|
||||
.. attribute:: pos_ticks
|
||||
|
||||
The number of ticks since the last positive pulse (read-only).
|
||||
|
||||
:type: int
|
||||
|
||||
.. attribute:: neg_ticks
|
||||
|
||||
The number of ticks since the last negative pulse (read-only).
|
||||
|
||||
:type: int
|
||||
|
||||
.. attribute:: status
|
||||
|
||||
The status of the sensor (read-only): can be one of :ref:`these constants<sensor-status>`.
|
||||
@@ -621,6 +633,71 @@ Types
|
||||
|
||||
:type: string
|
||||
|
||||
|
||||
.. class:: KX_SteeringActuator(SCA_IActuator)
|
||||
|
||||
Steering Actuator for navigation.
|
||||
|
||||
.. attribute:: behavior
|
||||
|
||||
The steering behavior to use.
|
||||
|
||||
:type: one of :ref:`these constants <logic-steering-actuator>`
|
||||
|
||||
.. attribute:: velocity
|
||||
|
||||
Velocity magnitude
|
||||
|
||||
:type: float
|
||||
|
||||
.. attribute:: acceleration
|
||||
|
||||
Max acceleration
|
||||
|
||||
:type: float
|
||||
|
||||
.. attribute:: turnspeed
|
||||
|
||||
Max turn speed
|
||||
|
||||
:type: float
|
||||
|
||||
.. attribute:: distance
|
||||
|
||||
Relax distance
|
||||
|
||||
:type: float
|
||||
|
||||
.. attribute:: target
|
||||
|
||||
Target object
|
||||
|
||||
:type: :class:`KX_GameObject`
|
||||
|
||||
.. attribute:: navmesh
|
||||
|
||||
Navigation mesh
|
||||
|
||||
:type: :class:`KX_GameObject`
|
||||
|
||||
.. attribute:: selfterminated
|
||||
|
||||
Terminate when target is reached
|
||||
|
||||
:type: boolean
|
||||
|
||||
.. attribute:: enableVisualization
|
||||
|
||||
Enable debug visualization
|
||||
|
||||
:type: boolean
|
||||
|
||||
.. attribute:: pathUpdatePeriod
|
||||
|
||||
Path update period
|
||||
|
||||
:type: int
|
||||
|
||||
.. class:: CListValue(CPropValue)
|
||||
|
||||
This is a list like object used in the game engine internally that behaves similar to a python list in most ways.
|
||||
@@ -682,10 +759,32 @@ Types
|
||||
|
||||
The id is derived from a memory location and will be different each time the game engine starts.
|
||||
|
||||
.. warning::
|
||||
|
||||
The id can't be stored as an integer in game object properties, as those only have a limited range that the id may not be contained in. Instead an id can be stored as a string game property and converted back to an integer for use in from_id lookups.
|
||||
|
||||
.. class:: KX_BlenderMaterial(PyObjectPlus)
|
||||
|
||||
KX_BlenderMaterial
|
||||
|
||||
.. attribute:: shader
|
||||
|
||||
The materials shader.
|
||||
|
||||
:type: :class:`BL_Shader`
|
||||
|
||||
.. attribute:: blending
|
||||
|
||||
Ints used for pixel blending, (src, dst), matching the setBlending method.
|
||||
|
||||
:type: (integer, integer)
|
||||
|
||||
.. attribute:: material_index
|
||||
|
||||
The material's index.
|
||||
|
||||
:type: integer
|
||||
|
||||
.. method:: getShader()
|
||||
|
||||
Returns the material's shader.
|
||||
@@ -743,7 +842,13 @@ Types
|
||||
strength of of the camera following movement.
|
||||
|
||||
:type: float
|
||||
|
||||
|
||||
.. attribute:: axis
|
||||
|
||||
The camera axis (0, 1, 2) for positive ``XYZ``, (3, 4, 5) for negative ``XYZ``.
|
||||
|
||||
:type: int
|
||||
|
||||
.. attribute:: min
|
||||
|
||||
minimum distance to the target object maintained by the actuator.
|
||||
@@ -762,12 +867,6 @@ Types
|
||||
|
||||
:type: float
|
||||
|
||||
.. attribute:: useXY
|
||||
|
||||
axis this actuator is tracking, True=X, False=Y.
|
||||
|
||||
:type: boolean
|
||||
|
||||
.. attribute:: object
|
||||
|
||||
the object this actuator tracks.
|
||||
@@ -988,14 +1087,14 @@ Types
|
||||
The object's parent object. (read-only).
|
||||
|
||||
:type: :class:`KX_GameObject` or None
|
||||
|
||||
.. attribute:: group_children
|
||||
|
||||
.. attribute:: groupMembers
|
||||
|
||||
Returns the list of group members if the object is a group object, otherwise None is returned.
|
||||
|
||||
:type: :class:`CListValue` of :class:`KX_GameObject` or None
|
||||
|
||||
.. attribute:: group_parent
|
||||
.. attribute:: groupObject
|
||||
|
||||
Returns the group object that the object belongs to or None if the object is not part of a group.
|
||||
|
||||
@@ -1100,30 +1199,30 @@ Types
|
||||
The object's world space transform matrix. 4x4 Matrix.
|
||||
|
||||
:type: :class:`mathutils.Matrix`
|
||||
|
||||
|
||||
.. attribute:: localLinearVelocity
|
||||
|
||||
The object's local linear velocity. [x, y, z]
|
||||
|
||||
:type: :class:`mathutils.Vector`
|
||||
|
||||
The object's local linear velocity. [x, y, z]
|
||||
|
||||
:type: :class:`mathutils.Vector`
|
||||
|
||||
.. attribute:: worldLinearVelocity
|
||||
|
||||
The object's world linear velocity. [x, y, z]
|
||||
|
||||
:type: :class:`mathutils.Vector`
|
||||
|
||||
|
||||
:type: :class:`mathutils.Vector`
|
||||
|
||||
.. attribute:: localAngularVelocity
|
||||
|
||||
The object's local angular velocity. [x, y, z]
|
||||
|
||||
:type: :class:`mathutils.Vector`
|
||||
|
||||
|
||||
:type: :class:`mathutils.Vector`
|
||||
|
||||
.. attribute:: worldAngularVelocity
|
||||
|
||||
The object's world angular velocity. [x, y, z]
|
||||
|
||||
:type: :class:`mathutils.Vector`
|
||||
|
||||
:type: :class:`mathutils.Vector`
|
||||
|
||||
.. attribute:: timeOffset
|
||||
|
||||
@@ -1211,6 +1310,13 @@ Types
|
||||
|
||||
:type: :class:`CListValue` of :class:`KX_GameObject`'s
|
||||
|
||||
.. attribute:: life
|
||||
|
||||
The number of seconds until the object ends, assumes 50fps.
|
||||
(when added with an add object actuator), (read-only).
|
||||
|
||||
:type: float
|
||||
|
||||
.. method:: endObject()
|
||||
|
||||
Delete this object, can be used in place of the EndObject Actuator.
|
||||
@@ -1653,7 +1759,7 @@ Types
|
||||
:arg blendin: the amount of blending between this animation and the previous one on this layer
|
||||
:type blendin: float
|
||||
:arg play_mode: the play mode
|
||||
:type play_mode: KX_ACTION_MODE_PLAY, KX_ACTION_MODE_LOOP, or KX_ACTION_MODE_PING_PONG
|
||||
:type play_mode: one of :ref:`these constants <gameobject-playaction-mode>`
|
||||
:arg layer_weight: how much of the previous layer to use for blending (0 = add)
|
||||
:type layer_weight: float
|
||||
:arg ipo_flags: flags for the old IPO behaviors (force, etc)
|
||||
@@ -1810,10 +1916,6 @@ Types
|
||||
|
||||
:type: list [r, g, b]
|
||||
|
||||
.. attribute:: colour
|
||||
|
||||
Synonym for color.
|
||||
|
||||
.. attribute:: lin_attenuation
|
||||
|
||||
The linear component of this light's attenuation. (SPOT and NORMAL lights only).
|
||||
@@ -1898,11 +2000,6 @@ Types
|
||||
|
||||
:type: integer
|
||||
|
||||
.. method:: getNumMaterials()
|
||||
|
||||
:return: number of materials associated with this object
|
||||
:rtype: integer
|
||||
|
||||
.. method:: getMaterialName(matid)
|
||||
|
||||
Gets the name of the specified material.
|
||||
@@ -1943,11 +2040,6 @@ Types
|
||||
:return: a vertex object.
|
||||
:rtype: :class:`KX_VertexProxy`
|
||||
|
||||
.. method:: getNumPolygons()
|
||||
|
||||
:return: The number of polygon in the mesh.
|
||||
:rtype: integer
|
||||
|
||||
.. method:: getPolygon(index)
|
||||
|
||||
Gets the specified polygon from the mesh.
|
||||
@@ -1957,6 +2049,28 @@ Types
|
||||
:return: a polygon object.
|
||||
:rtype: :class:`PolyProxy`
|
||||
|
||||
.. method:: transform(matid, matrix)
|
||||
|
||||
Transforms the vertices of a mesh.
|
||||
|
||||
:arg matid: material index, -1 transforms all.
|
||||
:type matid: integer
|
||||
:arg matrix: transformation matrix.
|
||||
:type matrix: 4x4 matrix [[float]]
|
||||
|
||||
.. method:: transformUV(matid, matrix, uv_index=-1, uv_index_from=-1)
|
||||
|
||||
Transforms the vertices UV's of a mesh.
|
||||
|
||||
:arg matid: material index, -1 transforms all.
|
||||
:type matid: integer
|
||||
:arg matrix: transformation matrix.
|
||||
:type matrix: 4x4 matrix [[float]]
|
||||
:arg uv_index: optional uv index, -1 for all, otherwise 0 or 1.
|
||||
:type uv_index: integer
|
||||
:arg uv_index_from: optional uv index to copy from, -1 to transform the current uv.
|
||||
:type uv_index_from: integer
|
||||
|
||||
.. class:: SCA_MouseSensor(SCA_ISensor)
|
||||
|
||||
Mouse Sensor logic brick.
|
||||
@@ -2156,6 +2270,52 @@ Types
|
||||
|
||||
:type: list of strings
|
||||
|
||||
|
||||
.. class:: KX_FontObject(KX_GameObject)
|
||||
|
||||
TODO.
|
||||
|
||||
|
||||
.. class:: KX_NavMeshObject(KX_GameObject)
|
||||
|
||||
Python interface for using and controlling navigation meshes.
|
||||
|
||||
.. method:: findPath(start, goal)
|
||||
|
||||
Finds the path from start to goal points.
|
||||
|
||||
:arg start: the start point
|
||||
:arg start: 3D Vector
|
||||
:arg goal: the goal point
|
||||
:arg start: 3D Vector
|
||||
:return: a path as a list of points
|
||||
:rtype: list of points
|
||||
|
||||
.. method:: raycast(start, goal)
|
||||
|
||||
Raycast from start to goal points.
|
||||
|
||||
:arg start: the start point
|
||||
:arg start: 3D Vector
|
||||
:arg goal: the goal point
|
||||
:arg start: 3D Vector
|
||||
:return: the hit factor
|
||||
:rtype: float
|
||||
|
||||
.. method:: draw(mode)
|
||||
|
||||
Draws a debug mesh for the navigation mesh.
|
||||
|
||||
:arg mode: the drawing mode (one of :ref:`these constants <navmesh-draw-mode>`)
|
||||
:arg mode: integer
|
||||
:return: None
|
||||
|
||||
.. method:: rebuild()
|
||||
|
||||
Rebuild the navigation mesh.
|
||||
|
||||
:return: None
|
||||
|
||||
.. class:: KX_ObjectActuator(SCA_IActuator)
|
||||
|
||||
The object actuator ("Motion Actuator") applies force, torque, displacement, angular displacement,
|
||||
@@ -2309,49 +2469,6 @@ Types
|
||||
|
||||
:type: boolean
|
||||
|
||||
.. class:: KX_PhysicsObjectWrapper(PyObjectPlus)
|
||||
|
||||
KX_PhysicsObjectWrapper
|
||||
|
||||
.. method:: setActive(active)
|
||||
|
||||
Set the object to be active.
|
||||
|
||||
:arg active: set to True to be active
|
||||
:type active: boolean
|
||||
|
||||
.. method:: setAngularVelocity(x, y, z, local)
|
||||
|
||||
Set the angular velocity of the object.
|
||||
|
||||
:arg x: angular velocity for the x-axis
|
||||
:type x: float
|
||||
|
||||
:arg y: angular velocity for the y-axis
|
||||
:type y: float
|
||||
|
||||
:arg z: angular velocity for the z-axis
|
||||
:type z: float
|
||||
|
||||
:arg local: set to True for local axis
|
||||
:type local: boolean
|
||||
|
||||
.. method:: setLinearVelocity(x, y, z, local)
|
||||
|
||||
Set the linear velocity of the object.
|
||||
|
||||
:arg x: linear velocity for the x-axis
|
||||
:type x: float
|
||||
|
||||
:arg y: linear velocity for the y-axis
|
||||
:type y: float
|
||||
|
||||
:arg z: linear velocity for the z-axis
|
||||
:type z: float
|
||||
|
||||
:arg local: set to True for local axis
|
||||
:type local: boolean
|
||||
|
||||
.. class:: KX_PolyProxy(SCA_IObject)
|
||||
|
||||
A polygon holds the index of the vertex forming the poylgon.
|
||||
@@ -2360,7 +2477,7 @@ Types
|
||||
The polygon attributes are read-only, you need to retrieve the vertex proxy if you want
|
||||
to change the vertex settings.
|
||||
|
||||
.. attribute:: matname
|
||||
.. attribute:: material_name
|
||||
|
||||
The name of polygon material, empty if no material.
|
||||
|
||||
@@ -2372,13 +2489,13 @@ Types
|
||||
|
||||
:type: :class:`KX_PolygonMaterial` or :class:`KX_BlenderMaterial`
|
||||
|
||||
.. attribute:: texture
|
||||
.. attribute:: texture_name
|
||||
|
||||
The texture name of the polygon.
|
||||
|
||||
:type: string
|
||||
|
||||
.. attribute:: matid
|
||||
.. attribute:: material_id
|
||||
|
||||
The material index of the polygon, use this to retrieve vertex proxy from mesh proxy.
|
||||
|
||||
@@ -2609,18 +2726,6 @@ Types
|
||||
|
||||
:type: boolean
|
||||
|
||||
.. attribute:: lightlayer
|
||||
|
||||
Light layers this material affects.
|
||||
|
||||
:type: bitfield.
|
||||
|
||||
.. attribute:: triangle
|
||||
|
||||
Mesh data with this material is triangles. It's probably not safe to change this.
|
||||
|
||||
:type: boolean
|
||||
|
||||
.. attribute:: diffuse
|
||||
|
||||
The diffuse color of the material. black = [0.0, 0.0, 0.0] white = [1.0, 1.0, 1.0].
|
||||
@@ -2886,8 +2991,8 @@ Types
|
||||
.. method:: instantAddObject()
|
||||
|
||||
adds the object without needing to calling SCA_PythonController.activate()
|
||||
|
||||
.. note:: Use objectLastCreated to get the newly created object.
|
||||
|
||||
.. note:: Use objectLastCreated to get the newly created object.
|
||||
|
||||
.. class:: KX_SCA_DynamicActuator(SCA_IActuator)
|
||||
|
||||
@@ -3113,6 +3218,12 @@ Types
|
||||
|
||||
:type: list
|
||||
|
||||
.. attribute:: gravity
|
||||
|
||||
The scene gravity using the world x, y and z axis.
|
||||
|
||||
:type: list [fx, fy, fz]
|
||||
|
||||
.. method:: addObject(object, other, time=0)
|
||||
|
||||
Adds an object to the scene like the Add Object Actuator would.
|
||||
@@ -3154,6 +3265,10 @@ Types
|
||||
Return the value matching key, or the default value if its not found.
|
||||
:return: The key value or a default.
|
||||
|
||||
.. method:: drawObstacleSimulation()
|
||||
|
||||
Draw debug visualization of obstacle simulation.
|
||||
|
||||
.. class:: KX_SceneActuator(SCA_IActuator)
|
||||
|
||||
Scene Actuator logic brick.
|
||||
@@ -3200,13 +3315,7 @@ Types
|
||||
|
||||
Sound Actuator.
|
||||
|
||||
The :data:`startSound`, :data:`pauseSound` and :data:`stopSound` do not requirethe actuator to be activated - they act instantly provided that the actuator has been activated once at least.
|
||||
|
||||
.. attribute:: fileName
|
||||
|
||||
The filename of the sound this actuator plays.
|
||||
|
||||
:type: string
|
||||
The :data:`startSound`, :data:`pauseSound` and :data:`stopSound` do not require the actuator to be activated - they act instantly provided that the actuator has been activated once at least.
|
||||
|
||||
.. attribute:: volume
|
||||
|
||||
@@ -3214,48 +3323,102 @@ Types
|
||||
|
||||
:type: float
|
||||
|
||||
.. attribute:: time
|
||||
|
||||
The current position in the audio stream (in seconds).
|
||||
|
||||
:type: float
|
||||
|
||||
.. attribute:: pitch
|
||||
|
||||
The pitch of the sound.
|
||||
|
||||
:type: float
|
||||
|
||||
.. attribute:: rollOffFactor
|
||||
|
||||
The roll off factor. Rolloff defines the rate of attenuation as the sound gets further away.
|
||||
|
||||
:type: float
|
||||
|
||||
.. attribute:: looping
|
||||
|
||||
The loop mode of the actuator.
|
||||
|
||||
:type: integer
|
||||
|
||||
.. attribute:: position
|
||||
|
||||
The position of the sound as a list: [x, y, z].
|
||||
|
||||
:type: float array
|
||||
|
||||
.. attribute:: velocity
|
||||
|
||||
The velocity of the emitter as a list: [x, y, z]. The relative velocity to the observer determines the pitch. List of 3 floats: [x, y, z].
|
||||
|
||||
:type: float array
|
||||
|
||||
.. attribute:: orientation
|
||||
|
||||
The orientation of the sound. When setting the orientation you can also use quaternion [float, float, float, float] or euler angles [float, float, float].
|
||||
|
||||
:type: 3x3 matrix [[float]]
|
||||
|
||||
.. attribute:: mode
|
||||
|
||||
The operation mode of the actuator. Can be one of :ref:`these constants<logic-sound-actuator>`
|
||||
|
||||
:type: integer
|
||||
|
||||
.. attribute:: sound
|
||||
|
||||
The sound the actuator should play.
|
||||
|
||||
:type: Audaspace factory
|
||||
|
||||
.. attribute:: is3D
|
||||
|
||||
Whether or not the actuator should be using 3D sound. (read-only)
|
||||
|
||||
:type: boolean
|
||||
|
||||
.. attribute:: volume_maximum
|
||||
|
||||
The maximum gain of the sound, no matter how near it is.
|
||||
|
||||
:type: float
|
||||
|
||||
.. attribute:: volume_minimum
|
||||
|
||||
The minimum gain of the sound, no matter how far it is away.
|
||||
|
||||
:type: float
|
||||
|
||||
.. attribute:: distance_reference
|
||||
|
||||
The distance where the sound has a gain of 1.0.
|
||||
|
||||
:type: float
|
||||
|
||||
.. attribute:: distance_maximum
|
||||
|
||||
The maximum distance at which you can hear the sound.
|
||||
|
||||
:type: float
|
||||
|
||||
.. attribute:: attenuation
|
||||
|
||||
The influence factor on volume depending on distance.
|
||||
|
||||
:type: float
|
||||
|
||||
.. attribute:: cone_angle_inner
|
||||
|
||||
The angle of the inner cone.
|
||||
|
||||
:type: float
|
||||
|
||||
.. attribute:: cone_angle_outer
|
||||
|
||||
The angle of the outer cone.
|
||||
|
||||
:type: float
|
||||
|
||||
.. attribute:: cone_volume_outer
|
||||
|
||||
The gain outside the outer cone (the gain in the outer cone will be interpolated between this value and the normal gain in the inner cone).
|
||||
|
||||
:type: float
|
||||
|
||||
.. method:: startSound()
|
||||
|
||||
Starts the sound.
|
||||
|
||||
:return: None
|
||||
|
||||
.. method:: pauseSound()
|
||||
|
||||
Pauses the sound.
|
||||
|
||||
:return: None
|
||||
|
||||
.. method:: stopSound()
|
||||
|
||||
Stops the sound.
|
||||
|
||||
:return: None
|
||||
|
||||
.. class:: KX_StateActuator(SCA_IActuator)
|
||||
|
||||
State actuator changes the state mask of parent object.
|
||||
@@ -3472,7 +3635,7 @@ Types
|
||||
|
||||
Whether or not the character is on the ground. (read-only)
|
||||
|
||||
:type: boolean
|
||||
:type: boolean
|
||||
|
||||
.. attribute:: gravity
|
||||
|
||||
@@ -3518,10 +3681,6 @@ Types
|
||||
|
||||
Black = [0.0, 0.0, 0.0, 1.0], White = [1.0, 1.0, 1.0, 1.0]
|
||||
|
||||
.. attribute:: colour
|
||||
|
||||
Synonym for color.
|
||||
|
||||
.. attribute:: x
|
||||
|
||||
The x coordinate of the vertex.
|
||||
@@ -4242,24 +4401,6 @@ Types
|
||||
|
||||
:type: integer
|
||||
|
||||
.. method:: setSeed(seed)
|
||||
|
||||
Sets the seed of the random number generator.
|
||||
|
||||
If the seed is 0, the generator will produce the same value on every call.
|
||||
|
||||
:type seed: integer
|
||||
|
||||
.. method:: getSeed()
|
||||
|
||||
:return: The initial seed of the generator. Equal seeds produce equal random series.
|
||||
:rtype: integer
|
||||
|
||||
.. method:: getLastDraw()
|
||||
|
||||
:return: The last random number generated.
|
||||
:rtype: integer
|
||||
|
||||
.. class:: SCA_XNORController(SCA_IController)
|
||||
|
||||
An XNOR controller activates when all linked sensors are the same (activated or inative).
|
||||
@@ -4327,7 +4468,7 @@ Types
|
||||
.. attribute:: projection_matrix
|
||||
|
||||
This camera's 4x4 projection matrix.
|
||||
|
||||
|
||||
.. note::
|
||||
|
||||
This is the identity matrix prior to rendering the first frame (any Python done on frame 1).
|
||||
@@ -4580,48 +4721,6 @@ Types
|
||||
|
||||
Armature Actuators change constraint condition on armatures.
|
||||
|
||||
.. _armatureactuator-constants-type:
|
||||
|
||||
Constants related to :data:`~bge.types.BL_ArmatureActuator.type`
|
||||
|
||||
.. data:: KX_ACT_ARMATURE_RUN
|
||||
|
||||
Just make sure the armature will be updated on the next graphic frame.
|
||||
This is the only persistent mode of the actuator:
|
||||
it executes automatically once per frame until stopped by a controller
|
||||
|
||||
:value: 0
|
||||
|
||||
.. data:: KX_ACT_ARMATURE_ENABLE
|
||||
|
||||
Enable the constraint.
|
||||
|
||||
:value: 1
|
||||
|
||||
.. data:: KX_ACT_ARMATURE_DISABLE
|
||||
|
||||
Disable the constraint (runtime constraint values are not updated).
|
||||
|
||||
:value: 2
|
||||
|
||||
.. data:: KX_ACT_ARMATURE_SETTARGET
|
||||
|
||||
Change target and subtarget of constraint.
|
||||
|
||||
:value: 3
|
||||
|
||||
.. data:: KX_ACT_ARMATURE_SETWEIGHT
|
||||
|
||||
Change weight of constraint (IK only).
|
||||
|
||||
:value: 4
|
||||
|
||||
.. data:: KX_ACT_ARMATURE_SETINFLUENCE
|
||||
|
||||
Change influence of constraint.
|
||||
|
||||
:value: 5
|
||||
|
||||
.. attribute:: type
|
||||
|
||||
The type of action that the actuator executes when it is active.
|
||||
@@ -4676,40 +4775,6 @@ Types
|
||||
|
||||
Armature sensor detect conditions on armatures.
|
||||
|
||||
.. _armaturesensor-type:
|
||||
|
||||
Constants related to :data:`type`
|
||||
|
||||
.. data:: KX_ARMSENSOR_STATE_CHANGED
|
||||
|
||||
Detect that the constraint is changing state (active/inactive)
|
||||
|
||||
:value: 0
|
||||
|
||||
.. data:: KX_ARMSENSOR_LIN_ERROR_BELOW
|
||||
|
||||
Detect that the constraint linear error is above a threshold
|
||||
|
||||
:value: 1
|
||||
|
||||
.. data:: KX_ARMSENSOR_LIN_ERROR_ABOVE
|
||||
|
||||
Detect that the constraint linear error is below a threshold
|
||||
|
||||
:value: 2
|
||||
|
||||
.. data:: KX_ARMSENSOR_ROT_ERROR_BELOW
|
||||
|
||||
Detect that the constraint rotation error is above a threshold
|
||||
|
||||
:value: 3
|
||||
|
||||
.. data:: KX_ARMSENSOR_ROT_ERROR_ABOVE
|
||||
|
||||
Detect that the constraint rotation error is below a threshold
|
||||
|
||||
:value: 4
|
||||
|
||||
.. attribute:: type
|
||||
|
||||
The type of measurement that the sensor make when it is active.
|
||||
@@ -4744,87 +4809,6 @@ Types
|
||||
|
||||
Not all armature constraints are supported in the GE.
|
||||
|
||||
.. _armatureconstraint-constants-type:
|
||||
|
||||
Constants related to :data:`type`
|
||||
|
||||
.. data:: CONSTRAINT_TYPE_TRACKTO
|
||||
.. data:: CONSTRAINT_TYPE_KINEMATIC
|
||||
.. data:: CONSTRAINT_TYPE_ROTLIKE
|
||||
.. data:: CONSTRAINT_TYPE_LOCLIKE
|
||||
.. data:: CONSTRAINT_TYPE_MINMAX
|
||||
.. data:: CONSTRAINT_TYPE_SIZELIKE
|
||||
.. data:: CONSTRAINT_TYPE_LOCKTRACK
|
||||
.. data:: CONSTRAINT_TYPE_STRETCHTO
|
||||
.. data:: CONSTRAINT_TYPE_CLAMPTO
|
||||
.. data:: CONSTRAINT_TYPE_TRANSFORM
|
||||
.. data:: CONSTRAINT_TYPE_DISTLIMIT
|
||||
|
||||
.. _armatureconstraint-constants-ik-type:
|
||||
|
||||
Constants related to :data:`ik_type`
|
||||
|
||||
.. data:: CONSTRAINT_IK_COPYPOSE
|
||||
|
||||
constraint is trying to match the position and eventually the rotation of the target.
|
||||
|
||||
:value: 0
|
||||
|
||||
.. data:: CONSTRAINT_IK_DISTANCE
|
||||
|
||||
Constraint is maintaining a certain distance to target subject to ik_mode
|
||||
|
||||
:value: 1
|
||||
|
||||
.. _armatureconstraint-constants-ik-flag:
|
||||
|
||||
Constants related to :data:`ik_flag`
|
||||
|
||||
.. data:: CONSTRAINT_IK_FLAG_TIP
|
||||
|
||||
Set when the constraint operates on the head of the bone and not the tail
|
||||
|
||||
:value: 1
|
||||
|
||||
.. data:: CONSTRAINT_IK_FLAG_ROT
|
||||
|
||||
Set when the constraint tries to match the orientation of the target
|
||||
|
||||
:value: 2
|
||||
|
||||
.. data:: CONSTRAINT_IK_FLAG_STRETCH
|
||||
|
||||
Set when the armature is allowed to stretch (only the bones with stretch factor > 0.0)
|
||||
|
||||
:value: 16
|
||||
|
||||
.. data:: CONSTRAINT_IK_FLAG_POS
|
||||
|
||||
Set when the constraint tries to match the position of the target.
|
||||
|
||||
:value: 32
|
||||
|
||||
.. _armatureconstraint-constants-ik-mode:
|
||||
|
||||
Constants related to :data:`ik_mode`
|
||||
|
||||
.. data:: CONSTRAINT_IK_MODE_INSIDE
|
||||
|
||||
The constraint tries to keep the bone within ik_dist of target
|
||||
|
||||
:value: 0
|
||||
|
||||
.. data:: CONSTRAINT_IK_MODE_OUTSIDE
|
||||
|
||||
The constraint tries to keep the bone outside ik_dist of the target
|
||||
|
||||
:value: 1
|
||||
|
||||
.. data:: CONSTRAINT_IK_MODE_ONSURFACE
|
||||
|
||||
The constraint tries to keep the bone exactly at ik_dist of the target.
|
||||
|
||||
:value: 2
|
||||
|
||||
.. attribute:: type
|
||||
|
||||
@@ -4943,16 +4927,6 @@ Types
|
||||
Proxy to armature pose channel. Allows to read and set armature pose.
|
||||
The attributes are identical to RNA attributes, but mostly in read-only mode.
|
||||
|
||||
See :data:`rotation_mode`
|
||||
|
||||
.. data:: PCHAN_ROT_QUAT
|
||||
.. data:: PCHAN_ROT_XYZ
|
||||
.. data:: PCHAN_ROT_XZY
|
||||
.. data:: PCHAN_ROT_YXZ
|
||||
.. data:: PCHAN_ROT_YZX
|
||||
.. data:: PCHAN_ROT_ZXY
|
||||
.. data:: PCHAN_ROT_ZYX
|
||||
|
||||
.. attribute:: name
|
||||
|
||||
channel name (=bone name), read-only.
|
||||
@@ -5086,17 +5060,7 @@ Types
|
||||
|
||||
Method of updating the bone rotation, read-write.
|
||||
|
||||
:type: integer
|
||||
|
||||
Use the following constants (euler mode are named as in Blender UI but the actual axis order is reversed).
|
||||
|
||||
* PCHAN_ROT_QUAT(0) : use quaternioin in rotation attribute to update bone rotation
|
||||
* PCHAN_ROT_XYZ(1) : use euler_rotation and apply angles on bone's Z, Y, X axis successively
|
||||
* PCHAN_ROT_XZY(2) : use euler_rotation and apply angles on bone's Y, Z, X axis successively
|
||||
* PCHAN_ROT_YXZ(3) : use euler_rotation and apply angles on bone's Z, X, Y axis successively
|
||||
* PCHAN_ROT_YZX(4) : use euler_rotation and apply angles on bone's X, Z, Y axis successively
|
||||
* PCHAN_ROT_ZXY(5) : use euler_rotation and apply angles on bone's Y, X, Z axis successively
|
||||
* PCHAN_ROT_ZYX(6) : use euler_rotation and apply angles on bone's X, Y, Z axis successively
|
||||
:type: integer (one of :ref:`these constants <armaturechannel-constants-rotation-mode>`)
|
||||
|
||||
.. attribute:: channel_matrix
|
||||
|
||||
|
||||
@@ -689,7 +689,7 @@ OpenGL}" and the online NeHe tutorials are two of the best resources.
|
||||
|
||||
Return the specified pixel map
|
||||
|
||||
.. seealso:: `OpenGL Docs <http://www.opengl.org/sdk/docs/man/xhtml/glGetPixelMap.xml>`_
|
||||
.. seealso:: `OpenGL Docs <http://www.opengl.org/sdk/docs/man2/xhtml/glGetPixelMap.xml>`_
|
||||
|
||||
:type map: Enumerated constant
|
||||
:arg map: Specifies the name of the pixel map to return.
|
||||
@@ -701,7 +701,7 @@ OpenGL}" and the online NeHe tutorials are two of the best resources.
|
||||
|
||||
Return the polygon stipple pattern
|
||||
|
||||
.. seealso:: `OpenGL Docs <http://www.opengl.org/sdk/docs/man/xhtml/glGetPolygonStipple.xml>`_
|
||||
.. seealso:: `OpenGL Docs <http://www.opengl.org/sdk/docs/man2/xhtml/glGetPolygonStipple.xml>`_
|
||||
|
||||
:type mask: :class:`bgl.Buffer` object I{type GL_BYTE}
|
||||
:arg mask: Returns the stipple pattern. The initial value is all 1's.
|
||||
@@ -824,13 +824,25 @@ OpenGL}" and the online NeHe tutorials are two of the best resources.
|
||||
|
||||
Set the current color index
|
||||
|
||||
.. seealso:: `OpenGL Docs <http://www.opengl.org/sdk/docs/man/xhtml/glIndex.xml>`_
|
||||
.. seealso:: `OpenGL Docs <http://www.opengl.org/sdk/docs/man2/xhtml/glIndex.xml>`_
|
||||
|
||||
:type c: :class:`bgl.Buffer` object. Depends on function prototype.
|
||||
:arg c: Specifies a pointer to a one element array that contains the new value for
|
||||
the current color index.
|
||||
|
||||
|
||||
.. function:: glIndexMask(mask):
|
||||
|
||||
Control the writing of individual bits in the color index buffers
|
||||
|
||||
.. seealso:: `OpenGL Docs <http://www.opengl.org/sdk/docs/man2/xhtml/glIndexMask.xml>`_
|
||||
|
||||
:type mask: int
|
||||
:arg mask: Specifies a bit mask to enable and disable the writing of individual bits
|
||||
in the color index buffers.
|
||||
Initially, the mask is all 1's.
|
||||
|
||||
|
||||
.. function:: glInitNames():
|
||||
|
||||
Initialize the name stack
|
||||
@@ -1510,7 +1522,7 @@ OpenGL}" and the online NeHe tutorials are two of the best resources.
|
||||
:arg mode: Specifies a symbolic value representing a shading technique.
|
||||
|
||||
|
||||
.. function:: glStencilFuc(func, ref, mask):
|
||||
.. function:: glStencilFunc(func, ref, mask):
|
||||
|
||||
Set function and reference value for stencil testing
|
||||
|
||||
@@ -1835,7 +1847,238 @@ OpenGL}" and the online NeHe tutorials are two of the best resources.
|
||||
:arg objx, objy, objz: Return the computed object coordinates.
|
||||
|
||||
|
||||
class Buffer:
|
||||
.. function:: glUseProgram(program):
|
||||
|
||||
Installs a program object as part of current rendering state
|
||||
|
||||
.. seealso:: `OpenGL Docs <http://www.opengl.org/sdk/docs/man/xhtml/glUseProgram.xml>`_
|
||||
|
||||
:type program: int
|
||||
:arg program: Specifies the handle of the program object whose executables are to be used as part of current rendering state.
|
||||
|
||||
|
||||
.. function:: glValidateProgram(program):
|
||||
|
||||
Validates a program object
|
||||
|
||||
.. seealso:: `OpenGL Docs <http://www.opengl.org/sdk/docs/man/xhtml/glValidateProgram.xml>`_
|
||||
|
||||
:type program: int
|
||||
:arg program: Specifies the handle of the program object to be validated.
|
||||
|
||||
|
||||
.. function:: glLinkProgram(program):
|
||||
|
||||
Links a program object.
|
||||
|
||||
.. seealso:: `OpenGL Docs <http://www.opengl.org/sdk/docs/man/xhtml/glLinkProgram.xml>`_
|
||||
|
||||
:type program: int
|
||||
:arg program: Specifies the handle of the program object to be linked.
|
||||
|
||||
|
||||
.. function:: glActiveTexture(texture):
|
||||
|
||||
Select active texture unit.
|
||||
|
||||
.. seealso:: `OpenGL Docs <http://www.opengl.org/sdk/docs/man/xhtml/glActiveTexture.xml>`_
|
||||
|
||||
:type texture: int
|
||||
:arg texture: Constant in ``GL_TEXTURE0`` 0 - 8
|
||||
|
||||
|
||||
.. function:: glAttachShader(program, shader):
|
||||
|
||||
Attaches a shader object to a program object.
|
||||
|
||||
.. seealso:: `OpenGL Docs <http://www.opengl.org/sdk/docs/man/xhtml/glAttachShader.xml>`_
|
||||
|
||||
:type program: int
|
||||
:arg program: Specifies the program object to which a shader object will be attached.
|
||||
:type shader: int
|
||||
:arg shader: Specifies the shader object that is to be attached.
|
||||
|
||||
|
||||
.. function:: glCompileShader(shader):
|
||||
|
||||
Compiles a shader object.
|
||||
|
||||
.. seealso:: `OpenGL Docs <http://www.opengl.org/sdk/docs/man/xhtml/glCompileShader.xml>`_
|
||||
|
||||
:type shader: int
|
||||
:arg shader: Specifies the shader object to be compiled.
|
||||
|
||||
|
||||
.. function:: glCreateProgram():
|
||||
|
||||
Creates a program object
|
||||
|
||||
.. seealso:: `OpenGL Docs <http://www.opengl.org/sdk/docs/man/xhtml/glCreateProgram.xml>`_
|
||||
|
||||
:rtype: int
|
||||
:return: The new program or zero if an error occurs.
|
||||
|
||||
|
||||
.. function:: glCreateShader(shaderType):
|
||||
|
||||
Creates a shader object.
|
||||
|
||||
.. seealso:: `OpenGL Docs <http://www.opengl.org/sdk/docs/man/xhtml/glCreateShader.xml>`_
|
||||
|
||||
:type shaderType: Specifies the type of shader to be created.
|
||||
Must be one of ``GL_VERTEX_SHADER``,
|
||||
``GL_TESS_CONTROL_SHADER``,
|
||||
``GL_TESS_EVALUATION_SHADER``,
|
||||
``GL_GEOMETRY_SHADER``,
|
||||
or ``GL_FRAGMENT_SHADER``.
|
||||
:arg shaderType:
|
||||
:rtype: int
|
||||
:return: 0 if an error occurs.
|
||||
|
||||
|
||||
.. function:: glDeleteProgram(program):
|
||||
|
||||
Deletes a program object.
|
||||
|
||||
.. seealso:: `OpenGL Docs <http://www.opengl.org/sdk/docs/man/xhtml/glDeleteProgram.xml>`_
|
||||
|
||||
:type program: int
|
||||
:arg program: Specifies the program object to be deleted.
|
||||
|
||||
|
||||
.. function:: glDeleteShader(shader):
|
||||
|
||||
Deletes a shader object.
|
||||
|
||||
.. seealso:: `OpenGL Docs <http://www.opengl.org/sdk/docs/man/xhtml/glDeleteShader.xml>`_
|
||||
|
||||
:type shader: int
|
||||
:arg shader: Specifies the shader object to be deleted.
|
||||
|
||||
|
||||
.. function:: glDetachShader(program, shader):
|
||||
|
||||
Detaches a shader object from a program object to which it is attached.
|
||||
|
||||
.. seealso:: `OpenGL Docs <http://www.opengl.org/sdk/docs/man/xhtml/glDetachShader.xml>`_
|
||||
|
||||
:type program: int
|
||||
:arg program: Specifies the program object from which to detach the shader object.
|
||||
:type shader: int
|
||||
:arg shader: pecifies the program object from which to detach the shader object.
|
||||
|
||||
|
||||
.. function:: glGetAttachedShaders(program, maxCount, count, shaders):
|
||||
|
||||
Returns the handles of the shader objects attached to a program object.
|
||||
|
||||
.. seealso:: `OpenGL Docs <http://www.opengl.org/sdk/docs/man/xhtml/glGetAttachedShaders.xml>`_
|
||||
|
||||
:type program: int
|
||||
:arg program: Specifies the program object to be queried.
|
||||
:type maxCount: int
|
||||
:arg maxCount: Specifies the size of the array for storing the returned object names.
|
||||
:type count: :class:`bgl.Buffer` int buffer.
|
||||
:arg count: Returns the number of names actually returned in objects.
|
||||
:type shaders: :class:`bgl.Buffer` int buffer.
|
||||
:arg shaders: Specifies an array that is used to return the names of attached shader objects.
|
||||
|
||||
|
||||
.. function:: glGetProgramInfoLog(program, maxLength, length, infoLog):
|
||||
|
||||
Returns the information log for a program object.
|
||||
|
||||
.. seealso:: `OpenGL Docs <http://www.opengl.org/sdk/docs/man/xhtml/glGetProgramInfoLog.xml>`_
|
||||
|
||||
:type program: int
|
||||
:arg program: Specifies the program object whose information log is to be queried.
|
||||
:type maxLength: int
|
||||
:arg maxLength: Specifies the size of the character buffer for storing the returned information log.
|
||||
:type length: :class:`bgl.Buffer` int buffer.
|
||||
:arg length: Returns the length of the string returned in **infoLog** (excluding the null terminator).
|
||||
:type infoLog: :class:`bgl.Buffer` char buffer.
|
||||
:arg infoLog: Specifies an array of characters that is used to return the information log.
|
||||
|
||||
|
||||
.. function:: glGetShaderInfoLog(program, maxLength, length, infoLog):
|
||||
|
||||
Returns the information log for a shader object.
|
||||
|
||||
.. seealso:: `OpenGL Docs <http://www.opengl.org/sdk/docs/man/xhtml/glGetShaderInfoLog.xml>`_
|
||||
|
||||
:type shader: int
|
||||
:arg shader: Specifies the shader object whose information log is to be queried.
|
||||
:type maxLength: int
|
||||
:arg maxLength: Specifies the size of the character buffer for storing the returned information log.
|
||||
:type length: :class:`bgl.Buffer` int buffer.
|
||||
:arg length: Returns the length of the string returned in **infoLog** (excluding the null terminator).
|
||||
:type infoLog: :class:`bgl.Buffer` char buffer.
|
||||
:arg infoLog: Specifies an array of characters that is used to return the information log.
|
||||
|
||||
|
||||
.. function:: glGetProgramiv(program, pname, params):
|
||||
|
||||
Returns a parameter from a program object.
|
||||
|
||||
.. seealso:: `OpenGL Docs <http://www.opengl.org/sdk/docs/man/xhtml/glGetProgram.xml>`_
|
||||
|
||||
:type program: int
|
||||
:arg program: Specifies the program object to be queried.
|
||||
:type pname: int
|
||||
:arg pname: Specifies the object parameter.
|
||||
:type params: :class:`bgl.Buffer` int buffer.
|
||||
:arg params: Returns the requested object parameter.
|
||||
|
||||
|
||||
.. function:: glIsShader(shader):
|
||||
|
||||
Determines if a name corresponds to a shader object.
|
||||
|
||||
.. seealso:: `OpenGL Docs <http://www.opengl.org/sdk/docs/man/xhtml/glIsShader.xml>`_
|
||||
|
||||
:type shader: int
|
||||
:arg shader: Specifies a potential shader object.
|
||||
|
||||
|
||||
.. function:: glIsProgram(program):
|
||||
|
||||
Determines if a name corresponds to a program object
|
||||
|
||||
.. seealso:: `OpenGL Docs <http://www.opengl.org/sdk/docs/man/xhtml/glIsProgram.xml>`_
|
||||
|
||||
:type program: int
|
||||
:arg program: Specifies a potential program object.
|
||||
|
||||
|
||||
.. function:: glGetShaderSource(shader, bufSize, length, source):
|
||||
|
||||
Returns the source code string from a shader object
|
||||
|
||||
.. seealso:: `OpenGL Docs <http://www.opengl.org/sdk/docs/man/xhtml/glGetShaderSource.xml>`_
|
||||
|
||||
:type shader: int
|
||||
:arg shader: Specifies the shader object to be queried.
|
||||
:type bufSize: int
|
||||
:arg bufSize: Specifies the size of the character buffer for storing the returned source code string.
|
||||
:type length: :class:`bgl.Buffer` int buffer.
|
||||
:arg length: Returns the length of the string returned in source (excluding the null terminator).
|
||||
:type source: :class:`bgl.Buffer` char.
|
||||
:arg source: Specifies an array of characters that is used to return the source code string.
|
||||
|
||||
|
||||
.. function:: glShaderSource(shader, shader_string):
|
||||
|
||||
Replaces the source code in a shader object.
|
||||
|
||||
.. seealso:: `OpenGL Docs <http://www.opengl.org/sdk/docs/man/xhtml/glShaderSource.xml>`_
|
||||
|
||||
:type shader: int
|
||||
:arg shader: Specifies the handle of the shader object whose source code is to be replaced.
|
||||
:type shader_string: string
|
||||
:arg shader_string: The shader string.
|
||||
|
||||
|
||||
.. class:: Buffer
|
||||
|
||||
The Buffer object is simply a block of memory that is delineated and initialized by the
|
||||
user. Many OpenGL functions return data to a C-style pointer, however, because this
|
||||
|
||||
@@ -262,10 +262,16 @@ The calculation of some of the uniforms is based on matrices available in the sc
|
||||
|
||||
.. data:: GPU_DYNAMIC_SAMPLER_2DSHADOW
|
||||
|
||||
The uniform is an float representing the bumpmap scaling.
|
||||
|
||||
:value: 14
|
||||
|
||||
.. data:: GPU_DYNAMIC_OBJECT_AUTOBUMPSCALE
|
||||
|
||||
The uniform is an integer representing a shadow buffer corresponding to a lamp
|
||||
casting shadow.
|
||||
|
||||
:value: 14
|
||||
:value: 15
|
||||
|
||||
|
||||
GLSL attribute type
|
||||
|
||||
@@ -4,6 +4,13 @@
|
||||
./blender.bin -b -noaudio -P doc/python_api/sphinx_doc_gen.py -- --partial bmesh* ; cd doc/python_api ; sphinx-build sphinx-in sphinx-out ; cd ../../
|
||||
|
||||
|
||||
Submodules:
|
||||
|
||||
* :mod:`bmesh.ops`
|
||||
* :mod:`bmesh.types`
|
||||
* :mod:`bmesh.utils`
|
||||
|
||||
|
||||
Intro
|
||||
-----
|
||||
|
||||
@@ -35,7 +42,6 @@ For an overview of BMesh data types and how they reference each other see:
|
||||
TODO items are...
|
||||
|
||||
* add access to BMesh **walkers**
|
||||
* add api for calling BMesh operators (unrelated to bpy.ops)
|
||||
* add custom-data manipulation functions add/remove/rename.
|
||||
|
||||
Example Script
|
||||
|
||||
305
doc/python_api/rst/info_api_reference.rst
Normal file
305
doc/python_api/rst/info_api_reference.rst
Normal file
@@ -0,0 +1,305 @@
|
||||
|
||||
*******************
|
||||
Reference API Usage
|
||||
*******************
|
||||
|
||||
Blender has many interlinking data types which have an auto-generated reference api which often has the information
|
||||
you need to write a script, but can be difficult to use.
|
||||
|
||||
This document is designed to help you understand how to use the reference api.
|
||||
|
||||
|
||||
Reference API Scope
|
||||
===================
|
||||
|
||||
The reference API covers :mod:`bpy.types`, which stores types accessed via :mod:`bpy.context` - *The user context*
|
||||
or :mod:`bpy.data` - *Blend file data*.
|
||||
|
||||
Other modules such as :mod:`bge`, :mod:`bmesh` and :mod:`aud` are not using Blenders data API
|
||||
so this document doesn't apply to those modules.
|
||||
|
||||
|
||||
Data Access
|
||||
===========
|
||||
|
||||
The most common case for using the reference API is to find out how to access data in the blend file.
|
||||
|
||||
Before going any further its best to be aware of ID Data-Blocks in Blender since you will often find properties
|
||||
relative to them.
|
||||
|
||||
|
||||
ID Data
|
||||
-------
|
||||
|
||||
ID Data-Blocks are used in Blender as top-level data containers.
|
||||
|
||||
From the user interface this isn't so obvious, but when developing you need to know about ID Data-Blocks.
|
||||
|
||||
ID data types include Scene, Group, Object, Mesh, Screen, World, Armature, Image and Texture.
|
||||
for a full list see the sub-classes of :class:`bpy.types.ID`
|
||||
|
||||
Here are some characteristics ID Data-Blocks share.
|
||||
|
||||
- ID's are blend file data, so loading a new blend file reloads an entire new set of Data-Blocks.
|
||||
- ID's can be accessed in Python from ``bpy.data.*``
|
||||
- Each data-block has a unique ``.name`` attribute, displayed in the interface.
|
||||
- Animation data is stored in ID's ``.animation_data``.
|
||||
- ID's are the only data types that can be linked between blend files.
|
||||
- ID's can be added/copied and removed via Python.
|
||||
- ID's have their own garbage-collection system which frees unused ID's when saving.
|
||||
- When a data-block has a reference to some external data, this is typically an ID Data-Block.
|
||||
|
||||
|
||||
Simple Data Access
|
||||
------------------
|
||||
|
||||
Lets start with a simple case, say you wan't a python script to adjust the objects location.
|
||||
|
||||
Start by finding this setting in the interface ``Properties Window -> Object -> Transform -> Location``
|
||||
|
||||
From the button you can right click and select **Online Python Reference**, this will link you to:
|
||||
:class:`bpy.types.Object.location`
|
||||
|
||||
Being an API reference, this link often gives little more information then the tool-tip, though some of the pages
|
||||
include examples (normally at the top of the page).
|
||||
|
||||
At this point you may say *Now what?* - you know that you have to use ``.location`` and that its an array of 3 floats
|
||||
but you're still left wondering how to access this in a script.
|
||||
|
||||
So the next step is to find out where to access objects, go down to the bottom of the page to the **References**
|
||||
section, for objects there are many references, but one of the most common places to access objects is via the context.
|
||||
|
||||
It's easy to be overwhelmed at this point since there ``Object`` get referenced in so many places - modifiers,
|
||||
functions, textures and constraints.
|
||||
|
||||
But if you want to access any data the user has selected
|
||||
you typically only need to check the :mod:`bpy.context` references.
|
||||
|
||||
Even then, in this case there are quite a few though if you read over these - most are mode specific.
|
||||
If you happen to be writing a tool that only runs in weight paint mode, then using ``weight_paint_object``
|
||||
would be appropriate.
|
||||
However to access an item the user last selected, look for the ``active`` members,
|
||||
Having access to a single active member the user selects is a convention in Blender: eg. ``active_bone``,
|
||||
``active_pose_bone``, ``active_node`` ... and in this case we can use - ``active_object``.
|
||||
|
||||
|
||||
So now we have enough information to find the location of the active object.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
bpy.context.active_object.location
|
||||
|
||||
You can type this into the python console to see the result.
|
||||
|
||||
The other common place to access objects in the reference is :class:`bpy.types.BlendData.objects`.
|
||||
|
||||
.. note::
|
||||
|
||||
This is **not** listed as :mod:`bpy.data.objects`,
|
||||
this is because :mod:`bpy.data` is an instance of the :class:`bpy.types.BlendData` class,
|
||||
so the documentation points there.
|
||||
|
||||
|
||||
With :mod:`bpy.data.objects`, this is a collection of objects so you need to access one of its members.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
bpy.data.objects["Cube"].location
|
||||
|
||||
|
||||
Nested Properties
|
||||
-----------------
|
||||
|
||||
The previous example is quite straightforward because ``location`` is a property of ``Object`` which can be accessed
|
||||
from the context directly.
|
||||
|
||||
Here are some more complex examples:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
# access a render layers samples
|
||||
bpy.context.scene.render.layers["RenderLayer"].samples
|
||||
|
||||
# access to the current weight paint brush size
|
||||
bpy.context.tool_settings.weight_paint.brush.size
|
||||
|
||||
# check if the window is fullscreen
|
||||
bpy.context.window.screen.show_fullscreen
|
||||
|
||||
|
||||
As you can see there are times when you want to access data which is nested
|
||||
in a way that causes you to go through a few indirections.
|
||||
|
||||
The properties are arranged to match how data is stored internally (in blenders C code) which is often logical but
|
||||
not always quite what you would expect from using Blender.
|
||||
|
||||
So this takes some time to learn, it helps you understand how data fits together in Blender which is important
|
||||
to know when writing scripts.
|
||||
|
||||
|
||||
When starting out scripting you will often run into the problem where you're not sure how to access the data you want.
|
||||
|
||||
There are a few ways to do this.
|
||||
|
||||
- Use the Python console's auto-complete to inspect properties. *This can be hit-and-miss but has the advantage
|
||||
that you can easily see the values of properties and assign them to interactively see the results.*
|
||||
|
||||
- Copy the Data-Path from the user interface. *Explained further in :ref:`Copy Data Path <info_data_path_copy>`*
|
||||
|
||||
- Using the documentation to follow references. *Explained further in :ref:`Indirect Data Access <info_data_path_indirect>`*
|
||||
|
||||
|
||||
.. _info_data_path_copy
|
||||
|
||||
Copy Data Path
|
||||
--------------
|
||||
|
||||
Blender can compute the Python string to a property which is shown in the tool-tip, on the line below ``Python: ...``,
|
||||
This saves having to use the API reference to click back up the references to find where data is accessed from.
|
||||
|
||||
There is a user-interface feature to copy the data-path which gives the path from an :class:`bpy.types.ID` data-block,
|
||||
to its property.
|
||||
|
||||
To see how this works we'll get the path to the Subdivision-Surface modifiers subdivision setting.
|
||||
|
||||
Start with the default scene and select the **Modifiers** tab, then add a **Subdivision-Surface** modifier to the cube.
|
||||
|
||||
Now hover your mouse over the button labeled **View**, The tool-tip includes :class:`bpy.types.SubsurfModifier.levels`
|
||||
but we want the path from the object to this property.
|
||||
|
||||
Note that the text copied won't include the ``bpy.data.collection["name"].`` component since its assumed that
|
||||
you won't be doing collection look-ups on every access and typically you'll want to use the context rather
|
||||
then access each :class:`bpy.types.ID` instance by name.
|
||||
|
||||
|
||||
Type in the ID path into a Python console :mod:`bpy.context.active_object`. Include the trailing dot and don't hit "enter", yet.
|
||||
|
||||
Now right-click on the button and select **Copy Data Path**, then paste the result into the console.
|
||||
|
||||
So now you should have the answer:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
bpy.context.active_object.modifiers["Subsurf"].levels
|
||||
|
||||
Hit "enter" and you'll get the current value of 1. Now try changing the value to 2:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
bpy.context.active_object.modifiers["Subsurf"].levels = 2
|
||||
|
||||
You can see the value update in the Subdivision-Surface modifier's UI as well as the cube.
|
||||
|
||||
|
||||
.. _info_data_path_indirect
|
||||
|
||||
Indirect Data Access
|
||||
--------------------
|
||||
|
||||
For this example we'll go over something more involved, showing the steps to access the active sculpt brushes texture.
|
||||
|
||||
Lets say we want to access the texture of a brush via Python, to adjust its ``contrast`` for example.
|
||||
|
||||
- Start in the default scene and enable 'Sculpt' mode from the 3D-View header.
|
||||
|
||||
- From the toolbar expand the **Texture** panel and add a new texture.
|
||||
|
||||
*Notice the texture button its self doesn't have very useful links (you can check the tool-tips).*
|
||||
|
||||
- The contrast setting isn't exposed in the sculpt toolbar, so view the texture in the properties panel...
|
||||
|
||||
- In the properties button select the Texture context.
|
||||
|
||||
- Select the Brush icon to show the brush texture.
|
||||
|
||||
- Expand the **Colors** panel to locate the **Contrast** button.
|
||||
|
||||
- Right click on the contrast button and select **Online Python Reference** This takes you to ``bpy.types.Texture.contrast``
|
||||
|
||||
- Now we can see that ``contrast`` is a property of texture, so next we'll check on how to access the texture from the brush.
|
||||
|
||||
- Check on the **References** at the bottom of the page, sometimes there are many references, and it may take
|
||||
some guess work to find the right one, but in this case its obviously ``Brush.texture``.
|
||||
|
||||
*Now we know that the texture can be accessed from* ``bpy.data.brushes["BrushName"].texture``
|
||||
*but normally you won't want to access the brush by name, so we'll see now to access the active brush instead.*
|
||||
|
||||
- So the next step is to check on where brushes are accessed from via the **References**.
|
||||
In this case there is simply ``bpy.context.brush`` which is all we need.
|
||||
|
||||
|
||||
Now you can use the Python console to form the nested properties needed to access brush textures contrast,
|
||||
logically we now know.
|
||||
|
||||
*Context -> Brush -> Texture -> Contrast*
|
||||
|
||||
Since the attribute for each is given along the way we can compose the data path in the python console:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
bpy.context.brush.texture.contrast
|
||||
|
||||
|
||||
There can be multiple ways to access the same data, which you choose often depends on the task.
|
||||
|
||||
An alternate path to access the same setting is...
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
bpy.context.sculpt.brush.texture.contrast
|
||||
|
||||
Or access the brush directly...
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
bpy.data.brushes["BrushName"].texture.contrast
|
||||
|
||||
|
||||
If you are writing a user tool normally you want to use the :mod:`bpy.context` since the user normally expects
|
||||
the tool to operate on what they have selected.
|
||||
|
||||
For automation you are more likely to use :mod:`bpy.data` since you want to be able to access specific data and manipulate
|
||||
it, no matter what the user currently has the view set at.
|
||||
|
||||
|
||||
Operators
|
||||
=========
|
||||
|
||||
Most key-strokes and buttons in Blender call an operator which is also exposed to python via :mod:`bpy.ops`,
|
||||
|
||||
To see the Python equivalent hover your mouse over the button and see the tool-tip,
|
||||
eg ``Python: bpy.ops.render.render()``,
|
||||
If there is no tool-tip or the ``Python:`` line is missing then this button is not using an operator and
|
||||
can't be accessed from Python.
|
||||
|
||||
|
||||
If you want to use this in a script you can press :kbd:`Control-C` while your mouse is over the button to copy it to the
|
||||
clipboard.
|
||||
|
||||
You can also right click on the button and view the **Online Python Reference**, this mainly shows arguments and
|
||||
their defaults however operators written in Python show their file and line number which may be useful if you
|
||||
are interested to check on the source code.
|
||||
|
||||
.. note::
|
||||
|
||||
Not all operators can be called usefully from Python, for more on this see :ref:`using operators <using_operators>`.
|
||||
|
||||
|
||||
Info View
|
||||
---------
|
||||
|
||||
Blender records operators you run and displays them in the **Info** space.
|
||||
This is located above the file-menu which can be dragged down to display its contents.
|
||||
|
||||
Select the **Script** screen that comes default with Blender to see its output.
|
||||
You can perform some actions and see them show up - delete a vertex for example.
|
||||
|
||||
Each entry can be selected (Right-Mouse-Button), then copied :kbd:`Control-C`, usually to paste in the text editor or python console.
|
||||
|
||||
.. note::
|
||||
|
||||
Not all operators get registered for display,
|
||||
zooming the view for example isn't so useful to repeat so its excluded from the output.
|
||||
|
||||
To display *every* operator that runs see :ref:`Show All Operators <info_show_all_operators>`
|
||||
|
||||
@@ -5,6 +5,8 @@ Gotchas
|
||||
This document attempts to help you work with the Blender API in areas that can be troublesome and avoid practices that are known to give instability.
|
||||
|
||||
|
||||
.. _using_operators:
|
||||
|
||||
Using Operators
|
||||
===============
|
||||
|
||||
@@ -118,18 +120,19 @@ If you insist - yes its possible, but scripts that use this hack wont be conside
|
||||
bpy.ops.wm.redraw_timer(type='DRAW_WIN_SWAP', iterations=1)
|
||||
|
||||
|
||||
I can't edit the mesh in edit-mode!
|
||||
===================================
|
||||
Modes and Mesh Access
|
||||
=====================
|
||||
|
||||
Blender's EditMesh is an internal data structure (not saved and not exposed to python), this gives the main annoyance that you need to exit edit-mode to edit the mesh from python.
|
||||
When working with mesh data you may run into the problem where a script fails to run as expected in edit-mode. This is caused by edit-mode having its own data which is only written back to the mesh when exiting edit-mode.
|
||||
|
||||
The reason we have not made much attempt to fix this yet is because we
|
||||
will likely move to BMesh mesh API eventually, so any work on the API now will be wasted effort.
|
||||
A common example is that exporters may access a mesh through ``obj.data`` (a :class:`bpy.types.Mesh`) but the user is in edit-mode, where the mesh data is available but out of sync with the edit mesh.
|
||||
|
||||
With the BMesh API we may expose mesh data to python so we can
|
||||
write useful tools in python which are also fast to execute while in edit-mode.
|
||||
In this situation you can...
|
||||
|
||||
For the time being this limitation just has to be worked around but we're aware its frustrating needs to be addressed.
|
||||
* Exit edit-mode before running the tool.
|
||||
* Explicitly update the mesh by calling :class:`bmesh.types.BMesh.to_mesh`.
|
||||
* Modify the script to support working on the edit-mode data directly, see: :mod:`bmesh.from_edit_mesh`.
|
||||
* Report the context as incorrect and only allow the script to run outside edit-mode.
|
||||
|
||||
|
||||
.. _info_gotcha_mesh_faces:
|
||||
@@ -311,7 +314,7 @@ Naming Limitations
|
||||
|
||||
A common mistake is to assume newly created data is given the requested name.
|
||||
|
||||
This can cause bugs when you add some data (normally imported) and then reference it later by name.
|
||||
This can cause bugs when you add some data (normally imported) then reference it later by name.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
@@ -493,7 +496,7 @@ Heres an example of threading supported by Blender:
|
||||
t.join()
|
||||
|
||||
|
||||
This an example of a timer which runs many times a second and moves the default cube continuously while Blender runs (Unsupported).
|
||||
This an example of a timer which runs many times a second and moves the default cube continuously while Blender runs **(Unsupported)**.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
@@ -516,7 +519,7 @@ So far, no work has gone into making Blender's python integration thread safe, s
|
||||
|
||||
.. note::
|
||||
|
||||
Pythons threads only allow co-currency and won't speed up your scripts on multi-processor systems, the ``subprocess`` and ``multiprocess`` modules can be used with blender and make use of multiple CPU's too.
|
||||
Pythons threads only allow co-currency and won't speed up your scripts on multi-processor systems, the ``subprocess`` and ``multiprocess`` modules can be used with Blender and make use of multiple CPU's too.
|
||||
|
||||
|
||||
Help! My script crashes Blender
|
||||
@@ -536,11 +539,18 @@ Here are some general hints to avoid running into these problems.
|
||||
|
||||
* Crashes may not happen every time, they may happen more on some configurations/operating-systems.
|
||||
|
||||
.. note::
|
||||
|
||||
To find the line of your script that crashes you can use the ``faulthandler`` module.
|
||||
See `faulthandler docs <http://docs.python.org/dev/library/faulthandler.html>`_.
|
||||
|
||||
While the crash may be in Blenders C/C++ code, this can help a lot to track down the area of the script that causes the crash.
|
||||
|
||||
|
||||
Undo/Redo
|
||||
---------
|
||||
|
||||
Undo invalidates all :class:`bpy.types.ID` instances (Object, Scene, Mesh etc).
|
||||
Undo invalidates all :class:`bpy.types.ID` instances (Object, Scene, Mesh, Lamp... etc).
|
||||
|
||||
This example shows how you can tell undo changes the memory locations.
|
||||
|
||||
@@ -557,6 +567,21 @@ This example shows how you can tell undo changes the memory locations.
|
||||
As suggested above, simply not holding references to data when Blender is used interactively by the user is the only way to ensure the script doesn't become unstable.
|
||||
|
||||
|
||||
Undo & Library Data
|
||||
^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
One of the advantages with Blenders library linking system that undo can skip checking changes in library data since it is assumed to be static.
|
||||
|
||||
Tools in Blender are not allowed to modify library data.
|
||||
|
||||
Python however does not enforce this restriction.
|
||||
|
||||
This can be useful in some cases, using a script to adjust material values for example.
|
||||
But its also possible to use a script to make library data point to newly created local data, which is not supported since a call to undo will remove the local data but leave the library referencing it and likely crash.
|
||||
|
||||
So it's best to consider modifying library data an advanced usage of the API and only to use it when you know what you're doing.
|
||||
|
||||
|
||||
Edit Mode / Memory Access
|
||||
-------------------------
|
||||
|
||||
@@ -616,15 +641,36 @@ Removing Data
|
||||
|
||||
**Any** data that you remove shouldn't be modified or accessed afterwards, this includes f-curves, drivers, render layers, timeline markers, modifiers, constraints along with objects, scenes, groups, bones.. etc.
|
||||
|
||||
This is a problem in the API at the moment that we should eventually solve.
|
||||
The ``remove()`` api calls will invalidate the data they free to prevent common mistakes.
|
||||
|
||||
The following example shows how this precortion works.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
mesh = bpy.data.meshes.new(name="MyMesh")
|
||||
# normally the script would use the mesh here...
|
||||
bpy.data.meshes.remove(mesh)
|
||||
print(mesh.name) # <- give an exception rather then crashing:
|
||||
|
||||
# ReferenceError: StructRNA of type Mesh has been removed
|
||||
|
||||
|
||||
But take care because this is limited to scripts accessing the variable which is removed, the next example will still crash.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
mesh = bpy.data.meshes.new(name="MyMesh")
|
||||
vertices = mesh.vertices
|
||||
bpy.data.meshes.remove(mesh)
|
||||
print(vertices) # <- this may crash
|
||||
|
||||
|
||||
sys.exit
|
||||
========
|
||||
|
||||
Some python modules will call sys.exit() themselves when an error occurs, while not common behavior this is something to watch out for because it may seem as if blender is crashing since sys.exit() will quit blender immediately.
|
||||
Some python modules will call ``sys.exit()`` themselves when an error occurs, while not common behavior this is something to watch out for because it may seem as if blender is crashing since ``sys.exit()`` will quit blender immediately.
|
||||
|
||||
For example, the ``optparse`` module will print an error and exit if the arguments are invalid.
|
||||
|
||||
An ugly way of troubleshooting this is to set ``sys.exit = None`` and see what line of python code is quitting, you could of course replace ``sys.exit``/ with your own function but manipulating python in this way is bad practice.
|
||||
An ugly way of troubleshooting this is to set ``sys.exit = None`` and see what line of python code is quitting, you could of course replace ``sys.exit`` with your own function but manipulating python in this way is bad practice.
|
||||
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
.. _info_overview:
|
||||
|
||||
*******************
|
||||
Python API Overview
|
||||
*******************
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
.. _info_quickstart:
|
||||
|
||||
***********************
|
||||
Quickstart Introduction
|
||||
***********************
|
||||
|
||||
@@ -44,15 +44,17 @@ if this can't be generated, only the property name is copied.
|
||||
|
||||
.. note::
|
||||
|
||||
This uses the same method for creating the animation path used by :class:`FCurve.data_path` and :class:`DriverTarget.data_path` drivers.
|
||||
This uses the same method for creating the animation path used by :class:`bpy.types.FCurve.data_path` and :class:`bpy.types.DriverTarget.data_path` drivers.
|
||||
|
||||
|
||||
.. _info_show_all_operators
|
||||
|
||||
Show All Operators
|
||||
==================
|
||||
|
||||
While blender logs operators in the Info space, this only reports operators with the ``REGISTER`` option enabeld so as not to flood the Info view with calls to ``bpy.ops.view3d.smoothview`` and ``bpy.ops.view3d.zoom``.
|
||||
|
||||
However, for testing it can be useful to see **every** operator called in a terminal, do this by enabling the debug option either by passing the ``--debug`` argument when starting blender or by setting :mod:`bpy.app.debug` to True while blender is running.
|
||||
However, for testing it can be useful to see **every** operator called in a terminal, do this by enabling the debug option either by passing the ``--debug-wm`` argument when starting blender or by setting :mod:`bpy.app.debug_wm` to True while blender is running.
|
||||
|
||||
|
||||
Use an External Editor
|
||||
@@ -218,6 +220,14 @@ The next example is an equivalent single line version of the script above which
|
||||
``code.interact`` can be added at any line in the script and will pause the script an launch an interactive interpreter in the terminal, when you're done you can quit the interpreter and the script will continue execution.
|
||||
|
||||
|
||||
If you have **IPython** installed you can use their ``embed()`` function which will implicitly use the current namespace, this has autocomplete and some useful features that the standard python eval-loop doesn't have.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
import IPython
|
||||
IPython.embed()
|
||||
|
||||
|
||||
Admittedly this highlights the lack of any python debugging support built into blender, but its still handy to know.
|
||||
|
||||
.. note::
|
||||
|
||||
645
doc/python_api/rst/info_tutorial_addon.rst
Normal file
645
doc/python_api/rst/info_tutorial_addon.rst
Normal file
@@ -0,0 +1,645 @@
|
||||
|
||||
Addon Tutorial
|
||||
##############
|
||||
|
||||
************
|
||||
Introduction
|
||||
************
|
||||
|
||||
|
||||
Intended Audience
|
||||
=================
|
||||
|
||||
This tutorial is designed to help technical artists or developers learn to extend Blender.
|
||||
An understanding of the basics of Python is expected for those working through this tutorial.
|
||||
|
||||
|
||||
Prerequisites
|
||||
-------------
|
||||
|
||||
Before going through the tutorial you should...
|
||||
|
||||
* Familiarity with the basics of working in Blender.
|
||||
|
||||
* Know how to run a script in Blender's text editor (as documented in the quick-start)
|
||||
|
||||
* Have an understanding of Python primitive types (int, boolean, string, list, tuple, dictionary, and set).
|
||||
|
||||
* Be familiar with the concept of Python modules.
|
||||
|
||||
* Basic understanding of classes (object orientation) in Python.
|
||||
|
||||
|
||||
Suggested reading before starting this tutorial.
|
||||
|
||||
* `Dive Into Python <http://getpython3.com/diveintopython3/index.html>`_ sections (1, 2, 3, 4, and 7).
|
||||
* :ref:`Blender API Quickstart <info_quickstart>`
|
||||
to help become familiar with Blender/Python basics.
|
||||
|
||||
|
||||
To best troubleshoot any error message Python prints while writing scripts you run blender with from a terminal,
|
||||
see :ref:`Use The Terminal <use_the_terminal>`.
|
||||
|
||||
Documentation Links
|
||||
===================
|
||||
|
||||
While going through the tutorial you may want to look into our reference documentation.
|
||||
|
||||
* :ref:`Blender API Overview <info_overview>`. -
|
||||
*This document is rather detailed but helpful if you want to know more on a topic.*
|
||||
|
||||
* :mod:`bpy.context` api reference. -
|
||||
*Handy to have a list of available items your script may operate on.*
|
||||
|
||||
* :class:`bpy.types.Operator`. -
|
||||
*The following addons define operators, these docs give details and more examples of operators.*
|
||||
|
||||
|
||||
******
|
||||
Addons
|
||||
******
|
||||
|
||||
|
||||
What is an Addon?
|
||||
=================
|
||||
|
||||
An addon is simply a Python module with some additional requirements so Blender can display it in a list with useful
|
||||
information.
|
||||
|
||||
To give an example, here is the simplest possible addon.
|
||||
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
bl_info = {"name": "My Test Addon", "category": "Object"}
|
||||
def register():
|
||||
print("Hello World")
|
||||
def unregister():
|
||||
print("Goodbye World")
|
||||
|
||||
|
||||
* ``bl_info`` is a dictionary containing addon meta-data such as the title, version and author to be displayed in the
|
||||
user preferences addon list.
|
||||
* ``register`` is a function which only runs when enabling the addon, this means the module can be loaded without
|
||||
activating the addon.
|
||||
* ``unregister`` is a function to unload anything setup by ``register``, this is called when the addon is disabled.
|
||||
|
||||
|
||||
|
||||
Notice this addon does not do anything related to Blender, (the :mod:`bpy` module is not imported for example).
|
||||
|
||||
This is a contrived example of an addon that serves to illustrate the point
|
||||
that the base requirements of an addon are simple.
|
||||
|
||||
An addon will typically register operators, panels, menu items etc, but its worth noting that _any_ script can do this,
|
||||
when executed from the text editor or even the interactive console - there is nothing inherently different about an
|
||||
addon that allows it to integrate with Blender, such functionality is just provided by the :mod:`bpy` module for any
|
||||
script to access.
|
||||
|
||||
So an addon is just a way to encapsulate a Python module in a way a user can easily utilize.
|
||||
|
||||
.. note::
|
||||
|
||||
Running this script within the text editor won't print anything,
|
||||
to see the output it must be installed through the user preferences.
|
||||
Messages will be printed when enabling and disabling.
|
||||
|
||||
|
||||
Your First Addon
|
||||
================
|
||||
|
||||
The simplest possible addon above was useful as an example but not much else.
|
||||
This next addon is simple but shows how to integrate a script into Blender using an ``Operator``
|
||||
which is the typical way to define a tool accessed from menus, buttons and keyboard shortcuts.
|
||||
|
||||
For the first example we'll make a script that simply moves all objects in a scene.
|
||||
|
||||
|
||||
Write The Script
|
||||
----------------
|
||||
|
||||
Add the following script to the text editor in Blender.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
import bpy
|
||||
|
||||
scene = bpy.context.scene
|
||||
for obj in scene.objects:
|
||||
obj.location.x += 1.0
|
||||
|
||||
|
||||
.. image:: run_script.png
|
||||
:width: 924px
|
||||
:align: center
|
||||
:height: 574px
|
||||
:alt: Run Script button
|
||||
|
||||
Click the Run Script button, all objects in the active scene are moved by 1.0 Blender unit.
|
||||
Next we'll make this script into an addon.
|
||||
|
||||
|
||||
Write the Addon (Simple)
|
||||
------------------------
|
||||
|
||||
This addon takes the body of the script above, and adds them to an operator's ``execute()`` function.
|
||||
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
bl_info = {
|
||||
"name": "Move X Axis",
|
||||
"category": "Object",
|
||||
}
|
||||
|
||||
import bpy
|
||||
|
||||
|
||||
class ObjectMoveX(bpy.types.Operator):
|
||||
"""My Object Moving Script""" # blender will use this as a tooltip for menu items and buttons.
|
||||
bl_idname = "object.move_x" # unique identifier for buttons and menu items to reference.
|
||||
bl_label = "Move X by One" # display name in the interface.
|
||||
bl_options = {'REGISTER', 'UNDO'} # enable undo for the operator.
|
||||
|
||||
def execute(self, context): # execute() is called by blender when running the operator.
|
||||
|
||||
# The original script
|
||||
scene = context.scene
|
||||
for obj in scene.objects:
|
||||
obj.location.x += 1.0
|
||||
|
||||
return {'FINISHED'} # this lets blender know the operator finished successfully.
|
||||
|
||||
def register():
|
||||
bpy.utils.register_class(ObjectMoveX)
|
||||
|
||||
|
||||
def unregister():
|
||||
bpy.utils.unregister_class(ObjectMoveX)
|
||||
|
||||
|
||||
# This allows you to run the script directly from blenders text editor
|
||||
# to test the addon without having to install it.
|
||||
if __name__ == "__main__":
|
||||
register()
|
||||
|
||||
|
||||
.. note:: ``bl_info`` is split across multiple lines, this is just a style convention used to more easily add items.
|
||||
|
||||
.. note:: Rather than using ``bpy.context.scene``, we use the ``context.scene`` argument passed to ``execute()``.
|
||||
In most cases these will be the same however in some cases operators will be passed a custom context
|
||||
so script authors should prefer the ``context`` argument passed to operators.
|
||||
|
||||
|
||||
To test the script you can copy and paste this into Blender text editor and run it, this will execute the script
|
||||
directly and call register immediately.
|
||||
|
||||
However running the script wont move any objects, for this you need to execute the newly registered operator.
|
||||
|
||||
.. image:: spacebar.png
|
||||
:width: 924px
|
||||
:align: center
|
||||
:height: 574px
|
||||
:alt: Spacebar
|
||||
|
||||
Do this by pressing ``SpaceBar`` to bring up the operator search dialog and type in "Move X by One" (the ``bl_label``),
|
||||
then press ``Enter``.
|
||||
|
||||
|
||||
|
||||
The objects should move as before.
|
||||
|
||||
*Keep this addon open in Blender for the next step - Installing.*
|
||||
|
||||
Install The Addon
|
||||
-----------------
|
||||
|
||||
Once you have your addon within in Blender's text editor, you will want to be able to install it so it can be enabled in
|
||||
the user preferences to load on startup.
|
||||
|
||||
Even though the addon above is a test, lets go through the steps anyway so you know how to do it for later.
|
||||
|
||||
To install the Blender text as an addon you will first have to save it to disk, take care to obey the naming
|
||||
restrictions that apply to Python modules and end with a ``.py`` extension.
|
||||
|
||||
Once the file is on disk, you can install it as you would for an addon downloaded online.
|
||||
|
||||
Open the user **File -> User Preferences**, Select the **Addon** section, press **Install Addon...** and select the file.
|
||||
|
||||
Now the addon will be listed and you can enable it by pressing the check-box, if you want it to be enabled on restart,
|
||||
press **Save as Default**.
|
||||
|
||||
.. note::
|
||||
|
||||
The destination of the addon depends on your Blender configuration.
|
||||
When installing an addon the source and destination path are printed in the console.
|
||||
You can also find addon path locations by running this in the Python console.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
import addon_utils
|
||||
print(addon_utils.paths())
|
||||
|
||||
More is written on this topic here:
|
||||
`Directory Layout <http://wiki.blender.org/index.php/Doc:2.6/Manual/Introduction/Installing_Blender/DirectoryLayout>`_
|
||||
|
||||
|
||||
Your Second Addon
|
||||
=================
|
||||
|
||||
For our second addon, we will focus on object instancing - this is - to make linked copies of an object in a
|
||||
similar way to what you may have seen with the array modifier.
|
||||
|
||||
|
||||
Write The Script
|
||||
----------------
|
||||
|
||||
As before, first we will start with a script, develop it, then convert into an addon.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
import bpy
|
||||
from bpy import context
|
||||
|
||||
# Get the current scene
|
||||
scene = context.scene
|
||||
|
||||
# Get the 3D cursor
|
||||
cursor = scene.cursor_location
|
||||
|
||||
# Get the active object (assume we have one)
|
||||
obj = scene.objects.active
|
||||
|
||||
# Now make a copy of the object
|
||||
obj_new = obj.copy()
|
||||
|
||||
# The object won't automatically get into a new scene
|
||||
scene.objects.link(obj_new)
|
||||
|
||||
# Now we can place the object
|
||||
obj_new.location = cursor
|
||||
|
||||
|
||||
Now try copy this script into Blender and run it on the default cube.
|
||||
Make sure you click to move the 3D cursor before running as the duplicate will appear at the cursor's location.
|
||||
|
||||
|
||||
... go off and test ...
|
||||
|
||||
|
||||
After running, notice that when you go into edit-mode to change the cube - all of the copies change,
|
||||
in Blender this is known as *Linked-Duplicates*.
|
||||
|
||||
|
||||
Next, we're going to do this in a loop, to make an array of objects between the active object and the cursor.
|
||||
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
import bpy
|
||||
from bpy import context
|
||||
|
||||
scene = context.scene
|
||||
cursor = scene.cursor_location
|
||||
obj = scene.objects.active
|
||||
|
||||
# Use a fixed value for now, eventually make this user adjustable
|
||||
total = 10
|
||||
|
||||
# Add 'total' objects into the scene
|
||||
for i in range(total):
|
||||
obj_new = obj.copy()
|
||||
scene.objects.link(obj_new)
|
||||
|
||||
# Now place the object in between the cursor
|
||||
# and the active object based on 'i'
|
||||
factor = i / total
|
||||
obj_new.location = (obj.location * factor) + (cursor * (1.0 - factor))
|
||||
|
||||
|
||||
Try run this script with with the active object and the cursor spaced apart to see the result.
|
||||
|
||||
With this script you'll notice we're doing some math with the object location and cursor, this works because both are
|
||||
3D :class:`mathutils.Vector` instances, a convenient class provided by the :mod:`mathutils` module and
|
||||
allows vectors to be multiplied by numbers and matrices.
|
||||
|
||||
If you are interested in this area, read into :class:`mathutils.Vector` - there are many handy utility functions
|
||||
such as getting the angle between vectors, cross product, dot products
|
||||
as well as more advanced functions in :mod:`mathutils.geometry` such as bezier spline interpolation and
|
||||
ray-triangle intersection.
|
||||
|
||||
For now we'll focus on making this script an addon, but its good to know that this 3D math module is available and
|
||||
can help you with more advanced functionality later on.
|
||||
|
||||
|
||||
Write the Addon
|
||||
---------------
|
||||
|
||||
The first step is to convert the script as-is into an addon.
|
||||
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
bl_info = {
|
||||
"name": "Cursor Array",
|
||||
"category": "Object",
|
||||
}
|
||||
|
||||
import bpy
|
||||
|
||||
|
||||
class ObjectCursorArray(bpy.types.Operator):
|
||||
"""Object Cursor Array"""
|
||||
bl_idname = "object.cursor_array"
|
||||
bl_label = "Cursor Array"
|
||||
bl_options = {'REGISTER', 'UNDO'}
|
||||
|
||||
def execute(self, context):
|
||||
scene = context.scene
|
||||
cursor = scene.cursor_location
|
||||
obj = scene.objects.active
|
||||
|
||||
total = 10
|
||||
|
||||
for i in range(total):
|
||||
obj_new = obj.copy()
|
||||
scene.objects.link(obj_new)
|
||||
|
||||
factor = i / total
|
||||
obj_new.location = (obj.location * factor) + (cursor * (1.0 - factor))
|
||||
|
||||
return {'FINISHED'}
|
||||
|
||||
def register():
|
||||
bpy.utils.register_class(ObjectCursorArray)
|
||||
|
||||
|
||||
def unregister():
|
||||
bpy.utils.unregister_class(ObjectCursorArray)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
register()
|
||||
|
||||
|
||||
Everything here has been covered in the previous steps, you may want to try run the addon still
|
||||
and consider what could be done to make it more useful.
|
||||
|
||||
|
||||
... go off and test ...
|
||||
|
||||
|
||||
The two of the most obvious missing things are - having the total fixed at 10, and having to access the operator from
|
||||
space-bar is not very convenient.
|
||||
|
||||
Both these additions are explained next, with the final script afterwards.
|
||||
|
||||
|
||||
Operator Property
|
||||
^^^^^^^^^^^^^^^^^
|
||||
|
||||
There are a variety of property types that are used for tool settings, common property types include:
|
||||
int, float, vector, color, boolean and string.
|
||||
|
||||
These properties are handled differently to typical Python class attributes
|
||||
because Blender needs to be display them in the interface,
|
||||
store their settings in key-maps and keep settings for re-use.
|
||||
|
||||
While this is handled in a fairly Pythonic way, be mindful that you are in fact defining tool settings that
|
||||
are loaded into Blender and accessed by other parts of Blender, outside of Python.
|
||||
|
||||
|
||||
To get rid of the literal 10 for `total`, we'll us an operator property.
|
||||
Operator properties are defined via bpy.props module, this is added to the class body.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
# moved assignment from execute() to the body of the class...
|
||||
total = bpy.props.IntProperty(name="Steps", default=2, min=1, max=100)
|
||||
|
||||
# and this is accessed on the class
|
||||
# instance within the execute() function as...
|
||||
self.total
|
||||
|
||||
|
||||
These properties from :mod:`bpy.props` are handled specially by Blender when the class is registered
|
||||
so they display as buttons in the user interface.
|
||||
There are many arguments you can pass to properties to set limits, change the default and display a tooltip.
|
||||
|
||||
.. seealso:: :mod:`bpy.props.IntProperty`
|
||||
|
||||
This document doesn't go into details about using other property types,
|
||||
however the link above includes examples of more advanced property usage.
|
||||
|
||||
|
||||
Menu Item
|
||||
^^^^^^^^^
|
||||
|
||||
Addons can add to the user interface of existing panels, headers and menus defined in Python.
|
||||
|
||||
For this example we'll add to an existing menu.
|
||||
|
||||
.. image:: menu_id.png
|
||||
:width: 334px
|
||||
:align: center
|
||||
:height: 128px
|
||||
:alt: Menu Identifier
|
||||
|
||||
To find the identifier of a menu you can hover your mouse over the menu item and the identifier is displayed.
|
||||
|
||||
The method used for adding a menu item is to append a draw function into an existing class.
|
||||
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
def menu_func(self, context):
|
||||
self.layout.operator(ObjectCursorArray.bl_idname)
|
||||
|
||||
def register():
|
||||
bpy.types.VIEW3D_MT_object.append(menu_func)
|
||||
|
||||
|
||||
For docs on extending menus see: :doc:`bpy.types.Menu`.
|
||||
|
||||
|
||||
Keymap
|
||||
^^^^^^
|
||||
|
||||
In Blender addons have their own key-maps so as not to interfere with Blenders built in key-maps.
|
||||
|
||||
In the example below, a new object-mode :class:`bpy.types.KeyMap` is added,
|
||||
then a :class:`bpy.types.KeyMapItem` is added to the key-map which references our newly added operator,
|
||||
using :kbd:`Ctrl-Shift-Space` as the key shortcut to activate it.
|
||||
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
# store keymaps here to access after registration
|
||||
addon_keymaps = []
|
||||
|
||||
def register():
|
||||
|
||||
# handle the keymap
|
||||
wm = bpy.context.window_manager
|
||||
km = wm.keyconfigs.addon.keymaps.new(name='Object Mode', space_type='EMPTY')
|
||||
|
||||
kmi = km.keymap_items.new(ObjectCursorArray.bl_idname, 'SPACE', 'PRESS', ctrl=True, shift=True)
|
||||
kmi.properties.total = 4
|
||||
|
||||
addon_keymaps.append(km)
|
||||
|
||||
|
||||
def unregister():
|
||||
|
||||
# handle the keymap
|
||||
wm = bpy.context.window_manager
|
||||
for km in addon_keymaps:
|
||||
wm.keyconfigs.addon.keymaps.remove(km)
|
||||
# clear the list
|
||||
addon_keymaps.clear()
|
||||
|
||||
|
||||
Notice how the key-map item can have a different ``total`` setting then the default set by the operator,
|
||||
this allows you to have multiple keys accessing the same operator with different settings.
|
||||
|
||||
|
||||
.. note::
|
||||
|
||||
While :kbd:`Ctrl-Shift-Space` isn't a default Blender key shortcut, its hard to make sure addons won't
|
||||
overwrite each others keymaps, At least take care when assigning keys that they don't
|
||||
conflict with important functionality within Blender.
|
||||
|
||||
For API documentation on the functions listed above, see:
|
||||
:class:`bpy.types.KeyMaps.new`,
|
||||
:class:`bpy.types.KeyMap`,
|
||||
:class:`bpy.types.KeyMapItems.new`,
|
||||
:class:`bpy.types.KeyMapItem`.
|
||||
|
||||
|
||||
Bringing it all together
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
bl_info = {
|
||||
"name": "Cursor Array",
|
||||
"category": "Object",
|
||||
}
|
||||
|
||||
import bpy
|
||||
|
||||
|
||||
class ObjectCursorArray(bpy.types.Operator):
|
||||
"""Object Cursor Array"""
|
||||
bl_idname = "object.cursor_array"
|
||||
bl_label = "Cursor Array"
|
||||
bl_options = {'REGISTER', 'UNDO'}
|
||||
|
||||
total = bpy.props.IntProperty(name="Steps", default=2, min=1, max=100)
|
||||
|
||||
def execute(self, context):
|
||||
scene = context.scene
|
||||
cursor = scene.cursor_location
|
||||
obj = scene.objects.active
|
||||
|
||||
for i in range(self.total):
|
||||
obj_new = obj.copy()
|
||||
scene.objects.link(obj_new)
|
||||
|
||||
factor = i / self.total
|
||||
obj_new.location = (obj.location * factor) + (cursor * (1.0 - factor))
|
||||
|
||||
return {'FINISHED'}
|
||||
|
||||
|
||||
def menu_func(self, context):
|
||||
self.layout.operator(ObjectCursorArray.bl_idname)
|
||||
|
||||
# store keymaps here to access after registration
|
||||
addon_keymaps = []
|
||||
|
||||
|
||||
def register():
|
||||
bpy.utils.register_class(ObjectCursorArray)
|
||||
bpy.types.VIEW3D_MT_object.append(menu_func)
|
||||
|
||||
# handle the keymap
|
||||
wm = bpy.context.window_manager
|
||||
km = wm.keyconfigs.addon.keymaps.new(name='Object Mode', space_type='EMPTY')
|
||||
kmi = km.keymap_items.new(ObjectCursorArray.bl_idname, 'SPACE', 'PRESS', ctrl=True, shift=True)
|
||||
kmi.properties.total = 4
|
||||
addon_keymaps.append(km)
|
||||
|
||||
def unregister():
|
||||
bpy.utils.unregister_class(ObjectCursorArray)
|
||||
bpy.types.VIEW3D_MT_object.remove(menu_func)
|
||||
|
||||
# handle the keymap
|
||||
wm = bpy.context.window_manager
|
||||
for km in addon_keymaps:
|
||||
wm.keyconfigs.addon.keymaps.remove(km)
|
||||
# clear the list
|
||||
del addon_keymaps[:]
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
register()
|
||||
|
||||
.. image:: in_menu.png
|
||||
:width: 591px
|
||||
:align: center
|
||||
:height: 649px
|
||||
:alt: In the menu
|
||||
|
||||
Run the script (or save it and add it through the Preferences like before) and it will appear in the menu.
|
||||
|
||||
.. image:: op_prop.png
|
||||
:width: 669px
|
||||
:align: center
|
||||
:height: 644px
|
||||
:alt: Operator Property
|
||||
|
||||
After selecting it from the menu, you can choose how many instance of the cube you want created.
|
||||
|
||||
|
||||
.. note::
|
||||
|
||||
Directly executing the script multiple times will add the menu each time too.
|
||||
While not useful behavior, theres nothing to worry about since addons won't register them selves multiple
|
||||
times when enabled through the user preferences.
|
||||
|
||||
|
||||
Conclusions
|
||||
===========
|
||||
|
||||
Addons can encapsulate certain functionality neatly for writing tools to improve your work-flow or for writing utilities
|
||||
for others to use.
|
||||
|
||||
While there are limits to what Python can do within Blender, there is certainly a lot that can be achieved without
|
||||
having to dive into Blender's C/C++ code.
|
||||
|
||||
The example given in the tutorial is limited, but shows the Blender API used for common tasks that you can expand on
|
||||
to write your own tools.
|
||||
|
||||
|
||||
Further Reading
|
||||
---------------
|
||||
|
||||
Blender comes commented templates which are accessible from the text editor header, if you have specific areas
|
||||
you want to see example code for, this is a good place to start.
|
||||
|
||||
|
||||
Here are some sites you might like to check on after completing this tutorial.
|
||||
|
||||
* :ref:`Blender/Python API Overview <info_overview>` -
|
||||
*For more background details on Blender/Python integration.*
|
||||
|
||||
* `How to Think Like a Computer Scientist <http://interactivepython.org/courselib/static/thinkcspy/index.html>`_ -
|
||||
*Great info for those who are still learning Python.*
|
||||
|
||||
* `Blender Development (Wiki) <http://wiki.blender.org/index.php/Dev:Contents>`_ -
|
||||
*Blender Development, general information and helpful links.*
|
||||
|
||||
* `Blender Artists (Coding Section) <http://blenderartists.org/forum/forumdisplay.php?47-Coding>`_ -
|
||||
*forum where people ask Python development questions*
|
||||
|
||||
380
doc/python_api/rst_from_bmesh_opdefines.py
Normal file
380
doc/python_api/rst_from_bmesh_opdefines.py
Normal file
@@ -0,0 +1,380 @@
|
||||
# ##### 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 LICENSE BLOCK #####
|
||||
|
||||
# <pep8 compliant>
|
||||
|
||||
# This is a quite stupid script which extracts bmesh api docs from
|
||||
# 'bmesh_opdefines.c' in order to avoid having to add a lot of introspection
|
||||
# data access into the api.
|
||||
#
|
||||
# The script is stupid becase it makes assumptions about formatting...
|
||||
# that each arg has its own line, that comments above or directly after will be __doc__ etc...
|
||||
#
|
||||
# We may want to replace this script with something else one day but for now its good enough.
|
||||
# if it needs large updates it may be better to rewrite using a real parser or
|
||||
# add introspection into bmesh.ops.
|
||||
# - campbell
|
||||
|
||||
import os
|
||||
|
||||
CURRENT_DIR = os.path.abspath(os.path.dirname(__file__))
|
||||
SOURCE_DIR = os.path.normpath(os.path.abspath(os.path.normpath(os.path.join(CURRENT_DIR, "..", ".."))))
|
||||
FILE_OP_DEFINES_C = os.path.join(SOURCE_DIR, "source", "blender", "bmesh", "intern", "bmesh_opdefines.c")
|
||||
OUT_RST = os.path.join(CURRENT_DIR, "rst", "bmesh.ops.rst")
|
||||
|
||||
HEADER = r"""
|
||||
BMesh Operators (bmesh.ops)
|
||||
===========================
|
||||
|
||||
.. module:: bmesh.ops
|
||||
|
||||
This module gives access to low level bmesh operations.
|
||||
|
||||
Most operators take input and return output, they can be chained together
|
||||
to perform useful operations.
|
||||
|
||||
.. note::
|
||||
|
||||
This API us new in 2.65 and not yet well tested.
|
||||
|
||||
|
||||
Operator Example
|
||||
++++++++++++++++
|
||||
This script shows how operators can be used to model a link of a chain.
|
||||
|
||||
.. literalinclude:: ../examples/bmesh.ops.1.py
|
||||
"""
|
||||
|
||||
|
||||
def main():
|
||||
fsrc = open(FILE_OP_DEFINES_C, 'r', encoding="utf-8")
|
||||
|
||||
blocks = []
|
||||
|
||||
is_block = False
|
||||
is_comment = False # /* global comments only */
|
||||
|
||||
comment_ctx = None
|
||||
block_ctx = None
|
||||
|
||||
for l in fsrc:
|
||||
l = l[:-1]
|
||||
# weak but ok
|
||||
if ("BMOpDefine" in l and l.split()[1] == "BMOpDefine") and not "bmo_opdefines[]" in l:
|
||||
is_block = True
|
||||
block_ctx = []
|
||||
blocks.append((comment_ctx, block_ctx))
|
||||
elif l.strip().startswith("/*"):
|
||||
is_comment = True
|
||||
comment_ctx = []
|
||||
|
||||
if is_block:
|
||||
if l.strip().startswith("//"):
|
||||
pass
|
||||
else:
|
||||
# remove c++ comment if we have one
|
||||
cpp_comment = l.find("//")
|
||||
if cpp_comment != -1:
|
||||
l = l[:cpp_comment]
|
||||
|
||||
block_ctx.append(l)
|
||||
|
||||
if l.strip() == "};":
|
||||
is_block = False
|
||||
comment_ctx = None
|
||||
|
||||
if is_comment:
|
||||
c_comment_start = l.find("/*")
|
||||
if c_comment_start != -1:
|
||||
l = l[c_comment_start + 2:]
|
||||
|
||||
c_comment_end = l.find("*/")
|
||||
if c_comment_end != -1:
|
||||
l = l[:c_comment_end]
|
||||
|
||||
is_comment = False
|
||||
comment_ctx.append(l)
|
||||
|
||||
fsrc.close()
|
||||
del fsrc
|
||||
|
||||
|
||||
# namespace hack
|
||||
vars = (
|
||||
"BMO_OP_SLOT_ELEMENT_BUF",
|
||||
"BMO_OP_SLOT_BOOL",
|
||||
"BMO_OP_SLOT_FLT",
|
||||
"BMO_OP_SLOT_INT",
|
||||
"BMO_OP_SLOT_MAT",
|
||||
"BMO_OP_SLOT_VEC",
|
||||
"BMO_OP_SLOT_PTR",
|
||||
"BMO_OP_SLOT_MAPPING",
|
||||
|
||||
"BMO_OP_SLOT_SUBTYPE_MAP_ELEM",
|
||||
"BMO_OP_SLOT_SUBTYPE_MAP_BOOL",
|
||||
"BMO_OP_SLOT_SUBTYPE_MAP_INT",
|
||||
"BMO_OP_SLOT_SUBTYPE_MAP_FLT",
|
||||
"BMO_OP_SLOT_SUBTYPE_MAP_EMPTY",
|
||||
"BMO_OP_SLOT_SUBTYPE_MAP_INTERNAL",
|
||||
|
||||
"BMO_OP_SLOT_SUBTYPE_PTR_SCENE",
|
||||
"BMO_OP_SLOT_SUBTYPE_PTR_OBJECT",
|
||||
"BMO_OP_SLOT_SUBTYPE_PTR_MESH",
|
||||
"BMO_OP_SLOT_SUBTYPE_PTR_BMESH",
|
||||
|
||||
"BMO_OP_SLOT_SUBTYPE_ELEM_IS_SINGLE",
|
||||
|
||||
"BM_VERT",
|
||||
"BM_EDGE",
|
||||
"BM_FACE",
|
||||
|
||||
"BMO_OP_FLAG_UNTAN_MULTIRES",
|
||||
)
|
||||
vars_dict = {}
|
||||
for i, v in enumerate(vars):
|
||||
vars_dict[v] = (1 << i)
|
||||
globals().update(vars_dict)
|
||||
# reverse lookup
|
||||
vars_dict_reverse = {v: k for k, v in vars_dict.items()}
|
||||
# end namespace hack
|
||||
|
||||
blocks_py = []
|
||||
for comment, b in blocks:
|
||||
# magic, translate into python
|
||||
b[0] = b[0].replace("static BMOpDefine ", "")
|
||||
|
||||
for i, l in enumerate(b):
|
||||
l = l.strip()
|
||||
l = l.replace("{", "(")
|
||||
l = l.replace("}", ")")
|
||||
|
||||
if l.startswith("/*"):
|
||||
l = l.replace("/*", "'''own <")
|
||||
else:
|
||||
l = l.replace("/*", "'''inline <")
|
||||
l = l.replace("*/", ">''',")
|
||||
|
||||
# exec func. eg: bmo_rotate_edges_exec,
|
||||
if l.startswith("bmo_") and l.endswith("_exec,"):
|
||||
l = "None,"
|
||||
b[i] = l
|
||||
|
||||
#for l in b:
|
||||
# print(l)
|
||||
|
||||
text = "\n".join(b)
|
||||
global_namespace = {
|
||||
"__file__": "generated",
|
||||
"__name__": "__main__",
|
||||
}
|
||||
|
||||
global_namespace.update(vars_dict)
|
||||
|
||||
text_a, text_b = text.split("=", 1)
|
||||
text = "result = " + text_b
|
||||
exec(compile(text, "generated", 'exec'), global_namespace)
|
||||
# print(global_namespace["result"])
|
||||
blocks_py.append((comment, global_namespace["result"]))
|
||||
|
||||
|
||||
# ---------------------
|
||||
# Now convert into rst.
|
||||
fout = open(OUT_RST, 'w', encoding="utf-8")
|
||||
fw = fout.write
|
||||
fw(HEADER)
|
||||
for comment, b in blocks_py:
|
||||
args_in = None
|
||||
args_out = None
|
||||
for member in b[1:]:
|
||||
if type(member) == tuple:
|
||||
if args_in is None:
|
||||
args_in = member
|
||||
elif args_out is None:
|
||||
args_out = member
|
||||
break
|
||||
|
||||
args_in_index = []
|
||||
args_out_index = []
|
||||
|
||||
if args_in is not None:
|
||||
args_in_index[:] = [i for (i, a) in enumerate(args_in) if type(a) == tuple]
|
||||
if args_out is not None:
|
||||
args_out_index[:] = [i for (i, a) in enumerate(args_out) if type(a) == tuple]
|
||||
|
||||
fw(".. function:: %s(bm, %s)\n\n" % (b[0], ", ".join([args_in[i][0] for i in args_in_index])))
|
||||
|
||||
# -- wash the comment
|
||||
comment_washed = []
|
||||
for i, l in enumerate(comment):
|
||||
assert((l.strip() == "") or
|
||||
(l in {"/*", " *"}) or
|
||||
(l.startswith(("/* ", " * "))))
|
||||
|
||||
l = l[3:]
|
||||
if i == 0 and not l.strip():
|
||||
continue
|
||||
if l.strip():
|
||||
l = " " + l
|
||||
comment_washed.append(l)
|
||||
|
||||
fw("\n".join(comment_washed))
|
||||
fw("\n")
|
||||
# -- done
|
||||
|
||||
|
||||
# get the args
|
||||
def get_args_wash(args, args_index, is_ret):
|
||||
args_wash = []
|
||||
for i in args_index:
|
||||
arg = args[i]
|
||||
if len(arg) == 3:
|
||||
name, tp, tp_sub = arg
|
||||
elif len(arg) == 2:
|
||||
name, tp = arg
|
||||
tp_sub = None
|
||||
else:
|
||||
print(arg)
|
||||
assert(0)
|
||||
|
||||
tp_str = ""
|
||||
|
||||
comment_prev = ""
|
||||
comment_next = ""
|
||||
if i != 0:
|
||||
comment_prev = args[i + 1]
|
||||
if type(comment_prev) == str and comment_prev.startswith("our <"):
|
||||
comment_prev = comment_next[5:-1] # strip inline <...>
|
||||
else:
|
||||
comment_prev = ""
|
||||
|
||||
if i + 1 < len(args):
|
||||
comment_next = args[i + 1]
|
||||
if type(comment_next) == str and comment_next.startswith("inline <"):
|
||||
comment_next = comment_next[8:-1] # strip inline <...>
|
||||
else:
|
||||
comment_next = ""
|
||||
|
||||
comment = ""
|
||||
if comment_prev:
|
||||
comment += comment_prev.strip()
|
||||
if comment_next:
|
||||
comment += ("\n" if comment_prev else "") + comment_next.strip()
|
||||
|
||||
if tp == BMO_OP_SLOT_FLT:
|
||||
tp_str = "float"
|
||||
elif tp == BMO_OP_SLOT_INT:
|
||||
tp_str = "int"
|
||||
elif tp == BMO_OP_SLOT_BOOL:
|
||||
tp_str = "bool"
|
||||
elif tp == BMO_OP_SLOT_MAT:
|
||||
tp_str = ":class:`mathutils.Matrix`"
|
||||
elif tp == BMO_OP_SLOT_VEC:
|
||||
tp_str = ":class:`mathutils.Vector`"
|
||||
if not is_ret:
|
||||
tp_str += " or any sequence of 3 floats"
|
||||
elif tp == BMO_OP_SLOT_PTR:
|
||||
tp_str = "dict"
|
||||
assert(tp_sub is not None)
|
||||
if tp_sub == BMO_OP_SLOT_SUBTYPE_PTR_BMESH:
|
||||
tp_str = ":class:`bmesh.types.BMesh`"
|
||||
elif tp_sub == BMO_OP_SLOT_SUBTYPE_PTR_SCENE:
|
||||
tp_str = ":class:`bpy.types.Scene`"
|
||||
elif tp_sub == BMO_OP_SLOT_SUBTYPE_PTR_OBJECT:
|
||||
tp_str = ":class:`bpy.types.Object`"
|
||||
elif tp_sub == BMO_OP_SLOT_SUBTYPE_PTR_MESH:
|
||||
tp_str = ":class:`bpy.types.Mesh`"
|
||||
else:
|
||||
print("Cant find", vars_dict_reverse[tp_sub])
|
||||
assert(0)
|
||||
|
||||
elif tp == BMO_OP_SLOT_ELEMENT_BUF:
|
||||
assert(tp_sub is not None)
|
||||
|
||||
ls = []
|
||||
if tp_sub & BM_VERT: ls.append(":class:`bmesh.types.BMVert`")
|
||||
if tp_sub & BM_EDGE: ls.append(":class:`bmesh.types.BMEdge`")
|
||||
if tp_sub & BM_FACE: ls.append(":class:`bmesh.types.BMFace`")
|
||||
assert(ls) # must be at least one
|
||||
|
||||
if tp_sub & BMO_OP_SLOT_SUBTYPE_ELEM_IS_SINGLE:
|
||||
tp_str = "/".join(ls)
|
||||
else:
|
||||
tp_str = ("list of (%s)" % ", ".join(ls))
|
||||
|
||||
del ls
|
||||
elif tp == BMO_OP_SLOT_MAPPING:
|
||||
if tp_sub & BMO_OP_SLOT_SUBTYPE_MAP_EMPTY:
|
||||
tp_str = "set of vert/edge/face type"
|
||||
else:
|
||||
tp_str = "dict mapping vert/edge/face types to "
|
||||
if tp_sub == BMO_OP_SLOT_SUBTYPE_MAP_BOOL:
|
||||
tp_str += "bool"
|
||||
elif tp_sub == BMO_OP_SLOT_SUBTYPE_MAP_INT:
|
||||
tp_str += "int"
|
||||
elif tp_sub == BMO_OP_SLOT_SUBTYPE_MAP_FLT:
|
||||
tp_str += "float"
|
||||
elif tp_sub == BMO_OP_SLOT_SUBTYPE_MAP_ELEM:
|
||||
tp_str += ":class:`bmesh.types.BMVert`/:class:`bmesh.types.BMEdge`/:class:`bmesh.types.BMFace`"
|
||||
elif tp_sub == BMO_OP_SLOT_SUBTYPE_MAP_INTERNAL:
|
||||
tp_str += "unknown internal data, not compatible with python"
|
||||
else:
|
||||
print("Cant find", vars_dict_reverse[tp_sub])
|
||||
assert(0)
|
||||
else:
|
||||
print("Cant find", vars_dict_reverse[tp])
|
||||
assert(0)
|
||||
|
||||
args_wash.append((name, tp_str, comment))
|
||||
return args_wash
|
||||
# end get_args_wash
|
||||
|
||||
# all ops get this arg
|
||||
fw(" :arg bm: The bmesh to operate on.\n")
|
||||
fw(" :type bm: :class:`bmesh.types.BMesh`\n")
|
||||
|
||||
args_in_wash = get_args_wash(args_in, args_in_index, False)
|
||||
args_out_wash = get_args_wash(args_out, args_out_index, True)
|
||||
|
||||
for (name, tp, comment) in args_in_wash:
|
||||
if comment == "":
|
||||
comment = "Undocumented."
|
||||
|
||||
fw(" :arg %s: %s\n" % (name, comment))
|
||||
fw(" :type %s: %s\n" % (name, tp))
|
||||
|
||||
if args_out_wash:
|
||||
fw(" :return:\n\n")
|
||||
|
||||
for (name, tp, comment) in args_out_wash:
|
||||
assert(name.endswith(".out"))
|
||||
name = name[:-4]
|
||||
fw(" - ``%s``: %s\n\n" % (name, comment))
|
||||
fw(" **type** %s\n" % tp)
|
||||
|
||||
fw("\n")
|
||||
fw(" :rtype: dict with string keys\n")
|
||||
|
||||
fw("\n\n")
|
||||
|
||||
fout.close()
|
||||
del fout
|
||||
print(OUT_RST)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -35,7 +35,7 @@ API dump in RST files
|
||||
./blender.bin --background --python doc/python_api/sphinx_doc_gen.py -- --output ../python_api
|
||||
|
||||
For quick builds:
|
||||
./blender.bin --background --python doc/python_api/sphinx_doc_gen.py -- --partial
|
||||
./blender.bin --background --python doc/python_api/sphinx_doc_gen.py -- --partial bmesh.*
|
||||
|
||||
|
||||
Sphinx: HTML generation
|
||||
@@ -245,6 +245,7 @@ else:
|
||||
"bgl",
|
||||
"blf",
|
||||
"bmesh",
|
||||
"bmesh.ops",
|
||||
"bmesh.types",
|
||||
"bmesh.utils",
|
||||
"bpy.app",
|
||||
@@ -297,7 +298,7 @@ try:
|
||||
__import__("aud")
|
||||
except ImportError:
|
||||
BPY_LOGGER.debug("Warning: Built without 'aud' module, docs incomplete...")
|
||||
EXCLUDE_MODULES = EXCLUDE_MODULES + ("aud", )
|
||||
EXCLUDE_MODULES = list(EXCLUDE_MODULES) + ["aud"]
|
||||
|
||||
# examples
|
||||
EXAMPLES_DIR = os.path.abspath(os.path.join(SCRIPT_DIR, "examples"))
|
||||
@@ -315,6 +316,8 @@ RST_DIR = os.path.abspath(os.path.join(SCRIPT_DIR, "rst"))
|
||||
INFO_DOCS = (
|
||||
("info_quickstart.rst", "Blender/Python Quickstart: new to blender/scripting and want to get your feet wet?"),
|
||||
("info_overview.rst", "Blender/Python API Overview: a more complete explanation of python integration"),
|
||||
("info_tutorial_addon.rst", "Blender/Python Addon Tutorial: a step by step guide on how to write an addon from scratch"),
|
||||
("info_api_reference.rst", "Blender/Python API Reference Usage: examples of how to use the API reference docs"),
|
||||
("info_best_practice.rst", "Best Practice: Conventions to follow for writing good scripts"),
|
||||
("info_tips_and_tricks.rst", "Tips and Tricks: Hints to help you while writing scripts for blender"),
|
||||
("info_gotcha.rst", "Gotcha's: some of the problems you may come up against when writing scripts"),
|
||||
@@ -1251,7 +1254,7 @@ def pyrna2sphinx(basepath):
|
||||
bases = list(reversed(struct.get_bases()))
|
||||
|
||||
# props
|
||||
lines[:] = []
|
||||
del lines[:]
|
||||
|
||||
if _BPY_STRUCT_FAKE:
|
||||
descr_items = [(key, descr) for key, descr in sorted(bpy.types.Struct.__bases__[0].__dict__.items()) if not key.startswith("__")]
|
||||
@@ -1282,7 +1285,7 @@ def pyrna2sphinx(basepath):
|
||||
fw("\n")
|
||||
|
||||
# funcs
|
||||
lines[:] = []
|
||||
del lines[:]
|
||||
|
||||
if _BPY_STRUCT_FAKE:
|
||||
for key, descr in descr_items:
|
||||
@@ -1305,7 +1308,7 @@ def pyrna2sphinx(basepath):
|
||||
fw(line)
|
||||
fw("\n")
|
||||
|
||||
lines[:] = []
|
||||
del lines[:]
|
||||
|
||||
if struct.references:
|
||||
# use this otherwise it gets in the index for a normal heading.
|
||||
@@ -1472,6 +1475,11 @@ def write_sphinx_conf_py(basepath):
|
||||
file.close()
|
||||
|
||||
|
||||
def execfile(filepath):
|
||||
global_namespace = {"__file__": filepath, "__name__": "__main__"}
|
||||
exec(compile(open(filepath).read(), filepath, 'exec'), global_namespace)
|
||||
|
||||
|
||||
def write_rst_contents(basepath):
|
||||
'''
|
||||
Write the rst file of the main page, needed for sphinx (index.html)
|
||||
@@ -1532,14 +1540,18 @@ def write_rst_contents(basepath):
|
||||
"mathutils", "mathutils.geometry", "mathutils.noise",
|
||||
# misc
|
||||
"bgl", "blf", "gpu", "aud", "bpy_extras",
|
||||
# bmesh
|
||||
"bmesh", "bmesh.types", "bmesh.utils",
|
||||
# bmesh, submodules are in own page
|
||||
"bmesh",
|
||||
)
|
||||
|
||||
for mod in standalone_modules:
|
||||
if mod not in EXCLUDE_MODULES:
|
||||
fw(" %s\n\n" % mod)
|
||||
|
||||
# special case, this 'bmesh.ops.rst' is extracted from C source
|
||||
if "bmesh.ops" not in EXCLUDE_MODULES:
|
||||
execfile(os.path.join(SCRIPT_DIR, "rst_from_bmesh_opdefines.py"))
|
||||
|
||||
# game engine
|
||||
if "bge" not in EXCLUDE_MODULES:
|
||||
fw(title_string("Game Engine Modules", "=", double=True))
|
||||
@@ -1701,6 +1713,8 @@ def copy_handwritten_rsts(basepath):
|
||||
"bgl", # "Blender OpenGl wrapper"
|
||||
"gpu", # "GPU Shader Module"
|
||||
|
||||
"bmesh.ops", # generated by rst_from_bmesh_opdefines.py
|
||||
|
||||
# includes...
|
||||
"include__bmesh",
|
||||
]
|
||||
@@ -1712,6 +1726,11 @@ def copy_handwritten_rsts(basepath):
|
||||
# changelog
|
||||
shutil.copy2(os.path.join(RST_DIR, "change_log.rst"), basepath)
|
||||
|
||||
# copy images, could be smarter but just glob for now.
|
||||
for f in os.listdir(RST_DIR):
|
||||
if f.endswith(".png"):
|
||||
shutil.copy2(os.path.join(RST_DIR, f), basepath)
|
||||
|
||||
|
||||
def rna2sphinx(basepath):
|
||||
|
||||
|
||||
Reference in New Issue
Block a user