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()
 
  194     def postConstructor(self):
 
  200 class brickTextureNodeOverride(omr.MPxShadingNodeOverride):
 
  203         return brickTextureNodeOverride(obj)
 
  205     def __init__(self, obj):
 
  206         omr.MPxShadingNodeOverride.__init__(self, obj)
 
  209         fragmentMgr = omr.MRenderer.getFragmentManager()
 
  210         if fragmentMgr != 
None:
 
  211             if not fragmentMgr.hasFragment(
"brickTextureNodePluginFragment"):
 
  212                 fragmentBody = 
"<fragment uiName=\"brickTextureNodePluginFragment\" name=\"brickTextureNodePluginFragment\" type=\"plumbing\" class=\"ShadeFragment\" version=\"1.0\">" 
  213                 fragmentBody += 
"   <description><![CDATA[Brick procedural texture fragment]]></description>" 
  214                 fragmentBody += 
"   <properties>" 
  215                 fragmentBody += 
"       <float3 name=\"brickColor\" />" 
  216                 fragmentBody += 
"       <float3 name=\"jointColor\" />" 
  217                 fragmentBody += 
"       <float name=\"blurFactor\" />" 
  218                 fragmentBody += 
"       <float2 name=\"uvCoord\" semantic=\"mayaUvCoordSemantic\" flags=\"varyingInputParam\" />" 
  219                 fragmentBody += 
"       <float2 name=\"uvFilterSize\" />" 
  220                 fragmentBody += 
"   </properties>" 
  221                 fragmentBody += 
"   <values>" 
  222                 fragmentBody += 
"       <float3 name=\"brickColor\" value=\"0.75,0.3,0.1\" />" 
  223                 fragmentBody += 
"       <float3 name=\"jointColor\" value=\"0.75,0.75,0.75\" />" 
  224                 fragmentBody += 
"   </values>" 
  225                 fragmentBody += 
"   <outputs>" 
  226                 fragmentBody += 
"       <float3 name=\"outColor\" />" 
  227                 fragmentBody += 
"   </outputs>" 
  228                 fragmentBody += 
"   <implementation>" 
  229                 fragmentBody += 
"   <implementation render=\"OGSRenderer\" language=\"Cg\" lang_version=\"2.1\">" 
  230                 fragmentBody += 
"       <function_name val=\"brickTextureNodePluginFragment\" />" 
  231                 fragmentBody += 
"       <source><![CDATA[" 
  232                 fragmentBody += 
"float btnplinearstep(float t, float a, float b) \n" 
  233                 fragmentBody += 
"{ \n" 
  234                 fragmentBody += 
"   if (t < a) return 0.0f; \n" 
  235                 fragmentBody += 
"   if (t > b) return 1.0f; \n" 
  236                 fragmentBody += 
"   return (t - a)/(b - a); \n" 
  237                 fragmentBody += 
"} \n" 
  238                 fragmentBody += 
"float3 brickTextureNodePluginFragment(float3 color1, float3 color2, float blur, float2 uv, float2 fs) \n" 
  239                 fragmentBody += 
"{ \n" 
  240                 fragmentBody += 
"   uv -= floor(uv); \n" 
  241                 fragmentBody += 
"   float v1 = 0.05f; float v2 = 0.45f; float v3 = 0.55f; float v4 = 0.95f; \n" 
  242                 fragmentBody += 
"   float u1 = 0.05f; float u2 = 0.45f; float u3 = 0.55f; float u4 = 0.95f; \n" 
  243                 fragmentBody += 
"   float du = blur*fs.x/2.0f; \n" 
  244                 fragmentBody += 
"   float dv = blur*fs.y/2.0f; \n" 
  245                 fragmentBody += 
"   float t = max( \n" 
  246                 fragmentBody += 
"       min(btnplinearstep(uv.y, v1 - dv, v1 + dv) - btnplinearstep(uv.y, v2 - dv, v2 + dv), \n" 
  247                 fragmentBody += 
"           max(btnplinearstep(uv.x, u3 - du, u3 + du), 1.0f - btnplinearstep(uv.x, u2 - du, u2 + du))), \n" 
  248                 fragmentBody += 
"       min(btnplinearstep(uv.y, v3 - dv, v3 + dv) - btnplinearstep(uv.y, v4 - dv, v4 + dv), \n" 
  249                 fragmentBody += 
"           btnplinearstep(uv.x, u1 - du, u1 + du) - btnplinearstep(uv.x, u4 - du, u4 + du))); \n" 
  250                 fragmentBody += 
"   return t*color1 + (1.0f - t)*color2; \n" 
  251                 fragmentBody += 
"} \n]]>" 
  252                 fragmentBody += 
"       </source>" 
  253                 fragmentBody += 
"   </implementation>" 
  254                 fragmentBody += 
"   <implementation render=\"OGSRenderer\" language=\"HLSL\" lang_version=\"11.0\">" 
  255                 fragmentBody += 
"       <function_name val=\"brickTextureNodePluginFragment\" />" 
  256                 fragmentBody += 
"       <source><![CDATA[" 
  257                 fragmentBody += 
"float btnplinearstep(float t, float a, float b) \n" 
  258                 fragmentBody += 
"{ \n" 
  259                 fragmentBody += 
"   if (t < a) return 0.0f; \n" 
  260                 fragmentBody += 
"   if (t > b) return 1.0f; \n" 
  261                 fragmentBody += 
"   return (t - a)/(b - a); \n" 
  262                 fragmentBody += 
"} \n" 
  263                 fragmentBody += 
"float3 brickTextureNodePluginFragment(float3 color1, float3 color2, float blur, float2 uv, float2 fs) \n" 
  264                 fragmentBody += 
"{ \n" 
  265                 fragmentBody += 
"   uv -= floor(uv); \n" 
  266                 fragmentBody += 
"   float v1 = 0.05f; float v2 = 0.45f; float v3 = 0.55f; float v4 = 0.95f; \n" 
  267                 fragmentBody += 
"   float u1 = 0.05f; float u2 = 0.45f; float u3 = 0.55f; float u4 = 0.95f; \n" 
  268                 fragmentBody += 
"   float du = blur*fs.x/2.0f; \n" 
  269                 fragmentBody += 
"   float dv = blur*fs.y/2.0f; \n" 
  270                 fragmentBody += 
"   float t = max( \n" 
  271                 fragmentBody += 
"       min(btnplinearstep(uv.y, v1 - dv, v1 + dv) - btnplinearstep(uv.y, v2 - dv, v2 + dv), \n" 
  272                 fragmentBody += 
"           max(btnplinearstep(uv.x, u3 - du, u3 + du), 1.0f - btnplinearstep(uv.x, u2 - du, u2 + du))), \n" 
  273                 fragmentBody += 
"       min(btnplinearstep(uv.y, v3 - dv, v3 + dv) - btnplinearstep(uv.y, v4 - dv, v4 + dv), \n" 
  274                 fragmentBody += 
"           btnplinearstep(uv.x, u1 - du, u1 + du) - btnplinearstep(uv.x, u4 - du, u4 + du))); \n" 
  275                 fragmentBody += 
"   return t*color1 + (1.0f - t)*color2; \n" 
  276                 fragmentBody += 
"} \n]]>" 
  277                 fragmentBody += 
"       </source>" 
  278                 fragmentBody += 
"   </implementation>" 
  279                 fragmentBody += 
"   <implementation render=\"OGSRenderer\" language=\"GLSL\" lang_version=\"3.0\">" 
  280                 fragmentBody += 
"       <function_name val=\"brickTextureNodePluginFragment\" />" 
  281                 fragmentBody += 
"       <source><![CDATA[" 
  282                 fragmentBody += 
"float btnplinearstep(float t, float a, float b) \n" 
  283                 fragmentBody += 
"{ \n" 
  284                 fragmentBody += 
"   if (t < a) return 0.0f; \n" 
  285                 fragmentBody += 
"   if (t > b) return 1.0f; \n" 
  286                 fragmentBody += 
"   return (t - a)/(b - a); \n" 
  287                 fragmentBody += 
"} \n" 
  288                 fragmentBody += 
"vec3 brickTextureNodePluginFragment(vec3 color1, vec3 color2, float blur, vec2 uv, vec2 fs) \n" 
  289                 fragmentBody += 
"{ \n" 
  290                 fragmentBody += 
"   uv -= floor(uv); \n" 
  291                 fragmentBody += 
"   float v1 = 0.05f; float v2 = 0.45f; float v3 = 0.55f; float v4 = 0.95f; \n" 
  292                 fragmentBody += 
"   float u1 = 0.05f; float u2 = 0.45f; float u3 = 0.55f; float u4 = 0.95f; \n" 
  293                 fragmentBody += 
"   float du = blur*fs.x/2.0f; \n" 
  294                 fragmentBody += 
"   float dv = blur*fs.y/2.0f; \n" 
  295                 fragmentBody += 
"   float t = max( \n" 
  296                 fragmentBody += 
"       min(btnplinearstep(uv.y, v1 - dv, v1 + dv) - btnplinearstep(uv.y, v2 - dv, v2 + dv), \n" 
  297                 fragmentBody += 
"           max(btnplinearstep(uv.x, u3 - du, u3 + du), 1.0f - btnplinearstep(uv.x, u2 - du, u2 + du))), \n" 
  298                 fragmentBody += 
"       min(btnplinearstep(uv.y, v3 - dv, v3 + dv) - btnplinearstep(uv.y, v4 - dv, v4 + dv), \n" 
  299                 fragmentBody += 
"           btnplinearstep(uv.x, u1 - du, u1 + du) - btnplinearstep(uv.x, u4 - du, u4 + du))); \n" 
  300                 fragmentBody += 
"   return t*color1 + (1.0f - t)*color2; \n" 
  301                 fragmentBody += 
"} \n]]>" 
  302                 fragmentBody += 
"       </source>" 
  303                 fragmentBody += 
"   </implementation>" 
  304                 fragmentBody += 
"   </implementation>" 
  305                 fragmentBody += 
"</fragment>" 
  307                 fragmentMgr.addShadeFragmentFromBuffer(fragmentBody, 
False)
 
  309     def supportedDrawAPIs(self):
 
  310         return omr.MRenderer.kOpenGL | omr.MRenderer.kOpenGLCoreProfile | omr.MRenderer.kDirectX11
 
  312     def fragmentName(self):
 
  313         return "brickTextureNodePluginFragment" 
  319 sRegistrantId = 
"brickTexturePlugin" 
  321 def initializePlugin(obj):
 
  322     plugin = om.MFnPlugin(obj, 
"Autodesk", 
"4.5", 
"Any")
 
  324         userClassify = 
"texture/2d:drawdb/shader/texture/2d/brickTexture" 
  325         plugin.registerNode(
"brickTexture", brickTextureNode.id, brickTextureNode.creator, brickTextureNode.initialize, om.MPxNode.kDependNode, userClassify)
 
  327         sys.stderr.write(
"Failed to register node\n")
 
  332         omr.MDrawRegistry.registerShadingNodeOverrideCreator(
"drawdb/shader/texture/2d/brickTexture", sRegistrantId, brickTextureNodeOverride.creator)
 
  334         sys.stderr.write(
"Failed to register override\n")
 
  337 def uninitializePlugin(obj):
 
  338     plugin = om.MFnPlugin(obj)
 
  340         plugin.deregisterNode(brickTextureNode.id)
 
  342         sys.stderr.write(
"Failed to deregister node\n")
 
  347         omr.MDrawRegistry.deregisterShadingNodeOverrideCreator(
"drawdb/shader/texture/2d/brickTexture", sRegistrantId)
 
  349         sys.stderr.write(
"Failed to deregister override\n")