scripted/customImagePlane.py

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