Python API 2.0 Reference
python/api2/py2VertexBufferMutator.py
1 # Copyright 2015 Autodesk, Inc. All rights reserved.
2 #
3 # Use of this software is subject to the terms of the Autodesk
4 # license agreement provided at the time of installation or download,
5 # or which otherwise accompanies this software in either electronic
6 # or hard copy form.
7 
8 from builtins import range
9 from ctypes import *
10 import maya.api.OpenMayaRender as omr
11 import maya.api.OpenMaya as om
12 
13 # Example plugin: vertexBufferMutator.cpp
14 #
15 # This plug-in is an example of a custom MPxVertexBufferMutator.
16 # It provides custom vertex streams based on shader requirements coming from
17 # an MPxShaderOverride. The semanticName() in the MVertexBufferDescriptor is used
18 # to signify a unique identifier for a custom stream.
19 
20 # This plugin is meant to be used in conjunction with the hwPhongShader
21 # where the position geometry is defined with the semantic "swizzlePosition"
22 
23 def maya_useNewAPI():
24  """
25  The presence of this function tells Maya that the plugin produces, and
26  expects to be passed, objects created using the Maya Python API 2.0.
27  """
28  pass
29 
30 class MyCustomBufferMutator(omr.MPxVertexBufferMutator):
31  def __init__(self):
32  omr.MPxVertexBufferMutator.__init__(self)
33 
34  def modifyVertexStream(self, object, vertexBuffer, targetIndexing):
35  # get the descriptor from the vertex buffer.
36  # It describes the format and layout of the stream.
37  descriptor = vertexBuffer.descriptor()
38 
39  # we are expecting a float stream.
40  if descriptor.dataType != omr.MGeometry.kFloat:
41  return
42 
43  # we are expecting a float3
44  if descriptor.dimension != 3:
45  return
46 
47  # we are expecting a position channel
48  if descriptor.semantic != omr.MGeometry.kPosition:
49  return
50 
51  # get the mesh from the current path
52  # if it is not a mesh we do nothing.
53  mesh = om.MFnMesh(object)
54 
55  vertexCount = vertexBuffer.vertexCount()
56  if vertexCount <= 0:
57  return
58 
59  # acquire the buffer to fill with data.
60  buffer = vertexBuffer.acquire(vertexCount, False) # writeOnly = False : we want the current buffer values
61 
62  inc = sizeof(c_float)
63  address = buffer
64 
65  for i in range(0, vertexCount):
66  # Here we swap the x, y and z values
67  xaddr = address
68  yaddr = address+inc
69  zaddr = address+2*inc
70  address += 3*inc
71 
72  x = c_float.from_address(xaddr).value
73  c_float.from_address(xaddr).value = c_float.from_address(yaddr).value # y --> x
74  c_float.from_address(yaddr).value = c_float.from_address(zaddr).value # z --> y
75  c_float.from_address(zaddr).value = x # x --> z
76 
77  # commit the buffer to signal completion.
78  vertexBuffer.commit(buffer)
79 
80 # This is the buffer generator creation function registered with the DrawRegistry.
81 # Used to initialize the generator.
82 def createMyCustomBufferMutator():
83  return MyCustomBufferMutator()
84 
85 # The following routines are used to register/unregister
86 # the vertex mutators with Maya
87 def initializePlugin(obj):
88 
89  omr.MDrawRegistry.registerVertexBufferMutator("swizzlePosition_py", createMyCustomBufferMutator)
90 
91 def uninitializePlugin(obj):
92 
93  omr.MDrawRegistry.deregisterVertexBufferMutator("swizzlePosition_py")
94