Python API 2.0 Reference
python/api1/py1CustomImagePlane.py
1 from __future__ import division
2 #-
3 # ==========================================================================
4 # Copyright (C) 1995 - 2006 Autodesk, Inc. and/or its licensors. All
5 # rights reserved.
6 #
7 # The coded instructions, statements, computer programs, and/or related
8 # material (collectively the "Data") in these files contain unpublished
9 # information proprietary to Autodesk, Inc. ("Autodesk") and/or its
10 # licensors, which is protected by U.S. and Canadian federal copyright
11 # law and by international treaties.
12 #
13 # The Data is provided for use exclusively by You. You have the right
14 # to use, modify, and incorporate this Data into other products for
15 # purposes authorized by the Autodesk software license agreement,
16 # without fee.
17 #
18 # The copyright notices in the Software and this entire statement,
19 # including the above license grant, this restriction and the
20 # following disclaimer, must be included in all copies of the
21 # Software, in whole or in part, and all derivative works of
22 # the Software, unless such copies or derivative works are solely
23 # in the form of machine-executable object code generated by a
24 # source language processor.
25 #
26 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND.
27 # AUTODESK DOES NOT MAKE AND HEREBY DISCLAIMS ANY EXPRESS OR IMPLIED
28 # WARRANTIES INCLUDING, BUT NOT LIMITED TO, THE WARRANTIES OF
29 # NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR
30 # PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE, OR
31 # TRADE PRACTICE. IN NO EVENT WILL AUTODESK AND/OR ITS LICENSORS
32 # BE LIABLE FOR ANY LOST REVENUES, DATA, OR PROFITS, OR SPECIAL,
33 # DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES, EVEN IF AUTODESK
34 # AND/OR ITS LICENSORS HAS BEEN ADVISED OF THE POSSIBILITY
35 # OR PROBABILITY OF SUCH DAMAGES.
36 #
37 # ==========================================================================
38 #+
39 
40 ########################################################################
41 # DESCRIPTION:
42 #
43 # Produces the dependency graph node "spCustomImagePlane".
44 #
45 # Demonstrates how to create your own custom image plane based on
46 # Maya's internal image plane classes. This allows API users to
47 # override the default Maya image plane behavior. This class works
48 # like typical API nodes in that it can have a compute method and
49 # can contain static attributes added by the API user. This
50 # example class overrides the default image plane behavior and
51 # allows users to add transparency to an image plane using the
52 # transparency attribute on the node. Note that this code also
53 # illustrates how to use MImage to control the floating point
54 # depth buffer. When useDepthMap is set to true, depth is added
55 # to the image such that half of the image is at the near
56 # clip plane and the remaining half is at the far clip plane.
57 #
58 # Once the image plane node has been created, you must
59 # attach it to the camera shape that is displaying the node.
60 # Image planes are attached to cameras using the imagePlane message
61 # attribute on the camera shape. To attach this example image
62 # plane, you must connect the image plane's message attribute to
63 # the cameraShapes imagePlane attribute. Note that the imagePlane
64 # attribute is a multi attribute and can hold references to
65 # multiple image planes.
66 #
67 # This example works only with renderers that use node evaluation
68 # as a part of the rendering process like Maya. It does
69 # not work with renderers that rely on a scene translation mechanism like
70 # mental ray.
71 #
72 # To use, run the following:
73 #
74 # import maya
75 # maya.cmds.loadPlugin("customImagePlane.py")
76 # imageP = maya.cmds.createNode("spCustomImagePlane")
77 # maya.cmds.connectAttr( imageP + ".message", "perspShape.imagePlane[0]", force = True )
78 #
79 # Then, assign an image to the customImagePlane node.
80 #
81 ########################################################################
82 
83 from builtins import range
84 import maya.OpenMaya as OpenMaya
85 import maya.OpenMayaMPx as OpenMayaMPx
86 import sys
87 
88 kPluginNodeTypeName = "spCustomImagePlane"
89 kPluginNodeId = OpenMaya.MTypeId(0x0008005c)
90 
91 # Node definition
92 class customImagePlane(OpenMayaMPx.MPxImagePlane):
93  # class variables
94  aTransparency = OpenMaya.MObject()
95 
96  # internal variables
97  fTransparency = 0.0
98 
99  def __init__(self):
100  OpenMayaMPx.MPxImagePlane.__init__(self)
101 
102  def getInternalValue(self, plug, handle ):
103  if plug == self.aTransparency:
104  handle.setDouble( self.fTransparency )
105  return True
106 
107  return OpenMayaMPx.MPxImagePlane.getInternalValue(self, plug, handle )
108 
109  def setInternalValue(self, plug, handle ):
110  if plug == self.aTransparency:
111  self.fTransparency = handle.asDouble()
112  self.setImageDirty()
113  return True
114 
115  return OpenMayaMPx.MPxImagePlane.setInternalValue(self, plug, handle )
116 
117  def loadImageMap(self, fileName, frame, image):
118  try:
119  image.readFromFile(fileName)
120 
121  # get the width and height of the image an MScriptUtil is needed
122  # to pass in a pointer to the MImage::getSize() method
123  widthUtil = OpenMaya.MScriptUtil(0)
124  widthPtr = widthUtil.asUintPtr()
125  heightUtil = OpenMaya.MScriptUtil(0)
126  heightPtr = heightUtil.asUintPtr()
127  image.getSize( widthPtr, heightPtr )
128 
129  width = widthUtil.getUint(widthPtr)
130  height = heightUtil.getUint(heightPtr)
131  size = width * height
132 
133  # Implement transparency
134  charPixelPtr = image.pixels()
135  for i in range( 0, size, 4 ):
136  alphaIndex = (i*4)+3
137  alpha = OpenMayaScript.getCharArrayItem(charPixelPtr,alphaIndex)
138  OpenMayaScript.setCharArray( alpha * (1.0 - self.fTransparency), alphaIndex )
139 
140  # Implement use depth map
141  thisNode = self.thisMObject()
142  fnThisNode = OpenMaya.MFnDependencyNode(thisNode)
143  useDepthMap = fnThisNode.attribute("useDepthMap")
144  depthMap = OpenMaya.MPlug( thisNode, useDepthMap )
145  value = depthMap.asBool()
146 
147  if value:
148  buffer = []
149  c = 0
150  for i in range( 0, height ):
151  for j in range( 0, width ):
152  if i > height/2.0:
153  buffer.insert(c, -1.0)
154  else:
155  buffer.insert(c, 0.0)
156  c+=1
157 
158  depthMapArray = OpenMaya.MScriptUtil()
159  depthMapArray.createFromList( buffer )
160  depthMapArrayFloatPtr = depthMapArray.asFloatPtr()
161  image.setDepthMap( depthMapArrayFloatPtr, width, height )
162 
163  except:
164  pass
165 
166 # creator
167 def nodeCreator():
168  return OpenMayaMPx.asMPxPtr( customImagePlane() )
169 
170 # initializer
171 def nodeInitializer():
173 
174  # Setup the input attributes
175  customImagePlane.aTransparency = nAttr.create("transparency", "tp", OpenMaya.MFnNumericData.kDouble, 0.0)
176  nAttr.setStorable(True)
177  nAttr.setInternal(True)
178  nAttr.setMin(0.0)
179  nAttr.setMax(1.0)
180  nAttr.setKeyable(True)
181 
182  customImagePlane.addAttribute(customImagePlane.aTransparency)
183 
184 # initialize the script plug-in
185 def initializePlugin(mobject):
186  mplugin = OpenMayaMPx.MFnPlugin(mobject, "Autodesk", "1.0", "Any")
187  try:
188  mplugin.registerNode( kPluginNodeTypeName, kPluginNodeId, nodeCreator, nodeInitializer, OpenMayaMPx.MPxNode.kImagePlaneNode )
189  except:
190  sys.stderr.write( "Failed to register node: %s" % kPluginNodeTypeName )
191  raise
192 
193 
194 # uninitialize the script plug-in
195 def uninitializePlugin(mobject):
196  mplugin = OpenMayaMPx.MFnPlugin(mobject)
197  try:
198  mplugin.deregisterNode( kPluginNodeId )
199  except:
200  sys.stderr.write( "Failed to register node: %s" % kPluginNodeTypeName )
201  raise