13 import maya.api.OpenMaya 
as om
 
   14 import maya.api.OpenMayaRender 
as omr
 
   24     The presence of this function tells Maya that the plugin produces, and 
   25     expects to be passed, objects created using the Maya Python API 2.0. 
   34 def smoothstep(t, a, b):
 
   40     return t*t*(3.0 - 2.0*t)
 
   42 def linearstep(t, a, b):
 
   47     return (t - a)/(b - a)
 
   52 class brickTextureNode(om.MPxNode):
 
   54     id = om.MTypeId( 0x8100d )
 
   68         return brickTextureNode()
 
   72         nAttr = om.MFnNumericAttribute()
 
   76         brickTextureNode.aColor1 = nAttr.createColor(
"brickColor", 
"bc")
 
   81         nAttr.default = (.75, .3, .1)           
 
   83         brickTextureNode.aColor2 = nAttr.createColor(
"jointColor", 
"jc")
 
   88         nAttr.default = (.75, .75, .75)         
 
   90         brickTextureNode.aBlurFactor = nAttr.create( 
"blurFactor", 
"bf", om.MFnNumericData.kFloat)
 
   98         child1 = nAttr.create( 
"uCoord", 
"u", om.MFnNumericData.kFloat) 
   99         child2 = nAttr.create( "vCoord", 
"v", om.MFnNumericData.kFloat)
 
  100         brickTextureNode.aUVCoord = nAttr.create( 
"uvCoord", 
"uv", child1, child2)
 
  102         nAttr.storable = 
True 
  103         nAttr.readable = 
True 
  104         nAttr.writable = 
True 
  107         child1 = nAttr.create( 
"uvFilterSizeX", 
"fsx", om.MFnNumericData.kFloat)
 
  108         child2 = nAttr.create( 
"uvFilterSizeY", 
"fsy", om.MFnNumericData.kFloat)
 
  109         brickTextureNode.aFilterSize = nAttr.create(
"uvFilterSize", 
"fs", child1, child2)
 
  111         nAttr.storable = 
True 
  112         nAttr.readable = 
True 
  113         nAttr.writable = 
True 
  117         brickTextureNode.aOutColor = nAttr.createColor(
"outColor", 
"oc")
 
  118         nAttr.keyable = 
False 
  119         nAttr.storable = 
False 
  120         nAttr.readable = 
True 
  121         nAttr.writable = 
False 
  124         om.MPxNode.addAttribute(brickTextureNode.aColor1)
 
  125         om.MPxNode.addAttribute(brickTextureNode.aColor2)
 
  126         om.MPxNode.addAttribute(brickTextureNode.aBlurFactor)
 
  127         om.MPxNode.addAttribute(brickTextureNode.aFilterSize)
 
  128         om.MPxNode.addAttribute(brickTextureNode.aUVCoord)
 
  130         om.MPxNode.addAttribute(brickTextureNode.aOutColor)
 
  133         om.MPxNode.attributeAffects(brickTextureNode.aColor1,       brickTextureNode.aOutColor)
 
  134         om.MPxNode.attributeAffects(brickTextureNode.aColor2,       brickTextureNode.aOutColor)
 
  135         om.MPxNode.attributeAffects(brickTextureNode.aBlurFactor,   brickTextureNode.aOutColor)
 
  136         om.MPxNode.attributeAffects(brickTextureNode.aFilterSize,   brickTextureNode.aOutColor)
 
  137         om.MPxNode.attributeAffects(brickTextureNode.aUVCoord,      brickTextureNode.aOutColor)
 
  140         om.MPxNode.__init__(self)
 
  151     def compute(self, plug, block):
 
  153         if (plug != brickTextureNode.aOutColor) 
and (plug.parent() != brickTextureNode.aOutColor):
 
  156         uv = block.inputValue( brickTextureNode.aUVCoord ).asFloat2()
 
  157         surfaceColor1 = block.inputValue( brickTextureNode.aColor1 ).asFloatVector()
 
  158         surfaceColor2 = block.inputValue( brickTextureNode.aColor2 ).asFloatVector()
 
  161         uv[0] -= math.floor(uv[0])
 
  162         uv[1] -= math.floor(uv[1])
 
  167         blur = block.inputValue( brickTextureNode.aBlurFactor ).asFloat()
 
  170         v2 = v1 + brickHeight
 
  171         v3 = v2 + borderWidth
 
  172         v4 = v3 + brickHeight
 
  175         u3 = u2 + borderWidth
 
  178         fs = block.inputValue( brickTextureNode.aFilterSize ).asFloat2()
 
  182         t = max(min(linearstep(uv[1], v1 - dv, v1 + dv) - linearstep(uv[1], v2 - dv, v2 + dv), max(linearstep(uv[0], u3 - du, u3 + du), 1 - linearstep(uv[0], u2 - du, u2 + du))), min(linearstep(uv[1], v3 - dv, v3 + dv) - linearstep(uv[1], v4 - dv, v4 + dv), linearstep(uv[0], u1 - du, u1 + du) - linearstep(uv[0], u4 - du, u4 + du)))
 
  184         resultColor = t*surfaceColor1 + (1.0 - t)*surfaceColor2
 
  187         outColorHandle = block.outputValue( brickTextureNode.aOutColor )
 
  188         outColorHandle.setMFloatVector( resultColor )
 
  189         outColorHandle.setClean()
 
  191     def postConstructor(self):
 
  197 class brickTextureNodeOverride(omr.MPxShadingNodeOverride):
 
  200         return brickTextureNodeOverride(obj)
 
  202     def __init__(self, obj):
 
  203         omr.MPxShadingNodeOverride.__init__(self, obj)
 
  206         fragmentMgr = omr.MRenderer.getFragmentManager()
 
  207         if fragmentMgr != 
None:
 
  208             if not fragmentMgr.hasFragment(
"brickTextureNodePluginFragment"):
 
  209                 fragmentBody = 
"<fragment uiName=\"brickTextureNodePluginFragment\" name=\"brickTextureNodePluginFragment\" type=\"plumbing\" class=\"ShadeFragment\" version=\"1.0\">" 
  210                 fragmentBody += 
"   <description><![CDATA[Brick procedural texture fragment]]></description>" 
  211                 fragmentBody += 
"   <properties>" 
  212                 fragmentBody += 
"       <float3 name=\"brickColor\" />" 
  213                 fragmentBody += 
"       <float3 name=\"jointColor\" />" 
  214                 fragmentBody += 
"       <float name=\"blurFactor\" />" 
  215                 fragmentBody += 
"       <float2 name=\"uvCoord\" semantic=\"mayaUvCoordSemantic\" flags=\"varyingInputParam\" />" 
  216                 fragmentBody += 
"       <float2 name=\"uvFilterSize\" />" 
  217                 fragmentBody += 
"   </properties>" 
  218                 fragmentBody += 
"   <values>" 
  219                 fragmentBody += 
"       <float3 name=\"brickColor\" value=\"0.75,0.3,0.1\" />" 
  220                 fragmentBody += 
"       <float3 name=\"jointColor\" value=\"0.75,0.75,0.75\" />" 
  221                 fragmentBody += 
"   </values>" 
  222                 fragmentBody += 
"   <outputs>" 
  223                 fragmentBody += 
"       <float3 name=\"outColor\" />" 
  224                 fragmentBody += 
"   </outputs>" 
  225                 fragmentBody += 
"   <implementation>" 
  226                 fragmentBody += 
"   <implementation render=\"OGSRenderer\" language=\"Cg\" lang_version=\"2.1\">" 
  227                 fragmentBody += 
"       <function_name val=\"brickTextureNodePluginFragment\" />" 
  228                 fragmentBody += 
"       <source><![CDATA[" 
  229                 fragmentBody += 
"float btnplinearstep(float t, float a, float b) \n" 
  230                 fragmentBody += 
"{ \n" 
  231                 fragmentBody += 
"   if (t < a) return 0.0f; \n" 
  232                 fragmentBody += 
"   if (t > b) return 1.0f; \n" 
  233                 fragmentBody += 
"   return (t - a)/(b - a); \n" 
  234                 fragmentBody += 
"} \n" 
  235                 fragmentBody += 
"float3 brickTextureNodePluginFragment(float3 color1, float3 color2, float blur, float2 uv, float2 fs) \n" 
  236                 fragmentBody += 
"{ \n" 
  237                 fragmentBody += 
"   uv -= floor(uv); \n" 
  238                 fragmentBody += 
"   float v1 = 0.05f; float v2 = 0.45f; float v3 = 0.55f; float v4 = 0.95f; \n" 
  239                 fragmentBody += 
"   float u1 = 0.05f; float u2 = 0.45f; float u3 = 0.55f; float u4 = 0.95f; \n" 
  240                 fragmentBody += 
"   float du = blur*fs.x/2.0f; \n" 
  241                 fragmentBody += 
"   float dv = blur*fs.y/2.0f; \n" 
  242                 fragmentBody += 
"   float t = max( \n" 
  243                 fragmentBody += 
"       min(btnplinearstep(uv.y, v1 - dv, v1 + dv) - btnplinearstep(uv.y, v2 - dv, v2 + dv), \n" 
  244                 fragmentBody += 
"           max(btnplinearstep(uv.x, u3 - du, u3 + du), 1.0f - btnplinearstep(uv.x, u2 - du, u2 + du))), \n" 
  245                 fragmentBody += 
"       min(btnplinearstep(uv.y, v3 - dv, v3 + dv) - btnplinearstep(uv.y, v4 - dv, v4 + dv), \n" 
  246                 fragmentBody += 
"           btnplinearstep(uv.x, u1 - du, u1 + du) - btnplinearstep(uv.x, u4 - du, u4 + du))); \n" 
  247                 fragmentBody += 
"   return t*color1 + (1.0f - t)*color2; \n" 
  248                 fragmentBody += 
"} \n]]>" 
  249                 fragmentBody += 
"       </source>" 
  250                 fragmentBody += 
"   </implementation>" 
  251                 fragmentBody += 
"   <implementation render=\"OGSRenderer\" language=\"HLSL\" lang_version=\"11.0\">" 
  252                 fragmentBody += 
"       <function_name val=\"brickTextureNodePluginFragment\" />" 
  253                 fragmentBody += 
"       <source><![CDATA[" 
  254                 fragmentBody += 
"float btnplinearstep(float t, float a, float b) \n" 
  255                 fragmentBody += 
"{ \n" 
  256                 fragmentBody += 
"   if (t < a) return 0.0f; \n" 
  257                 fragmentBody += 
"   if (t > b) return 1.0f; \n" 
  258                 fragmentBody += 
"   return (t - a)/(b - a); \n" 
  259                 fragmentBody += 
"} \n" 
  260                 fragmentBody += 
"float3 brickTextureNodePluginFragment(float3 color1, float3 color2, float blur, float2 uv, float2 fs) \n" 
  261                 fragmentBody += 
"{ \n" 
  262                 fragmentBody += 
"   uv -= floor(uv); \n" 
  263                 fragmentBody += 
"   float v1 = 0.05f; float v2 = 0.45f; float v3 = 0.55f; float v4 = 0.95f; \n" 
  264                 fragmentBody += 
"   float u1 = 0.05f; float u2 = 0.45f; float u3 = 0.55f; float u4 = 0.95f; \n" 
  265                 fragmentBody += 
"   float du = blur*fs.x/2.0f; \n" 
  266                 fragmentBody += 
"   float dv = blur*fs.y/2.0f; \n" 
  267                 fragmentBody += 
"   float t = max( \n" 
  268                 fragmentBody += 
"       min(btnplinearstep(uv.y, v1 - dv, v1 + dv) - btnplinearstep(uv.y, v2 - dv, v2 + dv), \n" 
  269                 fragmentBody += 
"           max(btnplinearstep(uv.x, u3 - du, u3 + du), 1.0f - btnplinearstep(uv.x, u2 - du, u2 + du))), \n" 
  270                 fragmentBody += 
"       min(btnplinearstep(uv.y, v3 - dv, v3 + dv) - btnplinearstep(uv.y, v4 - dv, v4 + dv), \n" 
  271                 fragmentBody += 
"           btnplinearstep(uv.x, u1 - du, u1 + du) - btnplinearstep(uv.x, u4 - du, u4 + du))); \n" 
  272                 fragmentBody += 
"   return t*color1 + (1.0f - t)*color2; \n" 
  273                 fragmentBody += 
"} \n]]>" 
  274                 fragmentBody += 
"       </source>" 
  275                 fragmentBody += 
"   </implementation>" 
  276                 fragmentBody += 
"   <implementation render=\"OGSRenderer\" language=\"GLSL\" lang_version=\"3.0\">" 
  277                 fragmentBody += 
"       <function_name val=\"brickTextureNodePluginFragment\" />" 
  278                 fragmentBody += 
"       <source><![CDATA[" 
  279                 fragmentBody += 
"float btnplinearstep(float t, float a, float b) \n" 
  280                 fragmentBody += 
"{ \n" 
  281                 fragmentBody += 
"   if (t < a) return 0.0f; \n" 
  282                 fragmentBody += 
"   if (t > b) return 1.0f; \n" 
  283                 fragmentBody += 
"   return (t - a)/(b - a); \n" 
  284                 fragmentBody += 
"} \n" 
  285                 fragmentBody += 
"vec3 brickTextureNodePluginFragment(vec3 color1, vec3 color2, float blur, vec2 uv, vec2 fs) \n" 
  286                 fragmentBody += 
"{ \n" 
  287                 fragmentBody += 
"   uv -= floor(uv); \n" 
  288                 fragmentBody += 
"   float v1 = 0.05f; float v2 = 0.45f; float v3 = 0.55f; float v4 = 0.95f; \n" 
  289                 fragmentBody += 
"   float u1 = 0.05f; float u2 = 0.45f; float u3 = 0.55f; float u4 = 0.95f; \n" 
  290                 fragmentBody += 
"   float du = blur*fs.x/2.0f; \n" 
  291                 fragmentBody += 
"   float dv = blur*fs.y/2.0f; \n" 
  292                 fragmentBody += 
"   float t = max( \n" 
  293                 fragmentBody += 
"       min(btnplinearstep(uv.y, v1 - dv, v1 + dv) - btnplinearstep(uv.y, v2 - dv, v2 + dv), \n" 
  294                 fragmentBody += 
"           max(btnplinearstep(uv.x, u3 - du, u3 + du), 1.0f - btnplinearstep(uv.x, u2 - du, u2 + du))), \n" 
  295                 fragmentBody += 
"       min(btnplinearstep(uv.y, v3 - dv, v3 + dv) - btnplinearstep(uv.y, v4 - dv, v4 + dv), \n" 
  296                 fragmentBody += 
"           btnplinearstep(uv.x, u1 - du, u1 + du) - btnplinearstep(uv.x, u4 - du, u4 + du))); \n" 
  297                 fragmentBody += 
"   return t*color1 + (1.0f - t)*color2; \n" 
  298                 fragmentBody += 
"} \n]]>" 
  299                 fragmentBody += 
"       </source>" 
  300                 fragmentBody += 
"   </implementation>" 
  301                 fragmentBody += 
"   </implementation>" 
  302                 fragmentBody += 
"</fragment>" 
  304                 fragmentMgr.addShadeFragmentFromBuffer(fragmentBody, 
False)
 
  306     def supportedDrawAPIs(self):
 
  307         return omr.MRenderer.kOpenGL | omr.MRenderer.kOpenGLCoreProfile | omr.MRenderer.kDirectX11
 
  309     def fragmentName(self):
 
  310         return "brickTextureNodePluginFragment" 
  316 sRegistrantId = 
"brickTexturePlugin" 
  318 def initializePlugin(obj):
 
  319     plugin = om.MFnPlugin(obj, 
"Autodesk", 
"4.5", 
"Any")
 
  321         userClassify = 
"texture/2d:drawdb/shader/texture/2d/brickTexture" 
  322         plugin.registerNode(
"brickTexture", brickTextureNode.id, brickTextureNode.creator, brickTextureNode.initialize, om.MPxNode.kDependNode, userClassify)
 
  324         sys.stderr.write(
"Failed to register node\n")
 
  329         omr.MDrawRegistry.registerShadingNodeOverrideCreator(
"drawdb/shader/texture/2d/brickTexture", sRegistrantId, brickTextureNodeOverride.creator)
 
  331         sys.stderr.write(
"Failed to register override\n")
 
  334 def uninitializePlugin(obj):
 
  335     plugin = om.MFnPlugin(obj)
 
  337         plugin.deregisterNode(brickTextureNode.id)
 
  339         sys.stderr.write(
"Failed to deregister node\n")
 
  344         omr.MDrawRegistry.deregisterShadingNodeOverrideCreator(
"drawdb/shader/texture/2d/brickTexture", sRegistrantId)
 
  346         sys.stderr.write(
"Failed to deregister override\n")