示例#1
0
        def GetMaterialTabPolicy(self):
            editorNode = self.getReferencedNode('node_material')
            if not editorNode: return

            scriptItem = self.getScriptItem()

            rootPolicy = QT4FormWidgets.PythonGroupPolicy('material')

            rootPolicy.getWidgetHints()['open'] = True
            lookFileEnablePolicy = QT4FormWidgets.ValuePolicyProxy(
                FormMaster.CreateParameterPolicy(
                    rootPolicy,
                    SA.GetLookFileMaterialEnabledParameter(scriptItem)))
            lookFileEnablePolicy.setWidgetHints({'widget': 'checkBox'})

            rootPolicy.addChildPolicy(lookFileEnablePolicy)

            refPolicy = QT4FormWidgets.PythonGroupPolicy(
                'reference', rootPolicy)
            refPolicy.getWidgetHints().update({
                'open':
                True,
                'conditionalVisOp':
                'notEqualTo',
                'conditionalVisPath':
                '../%s' % lookFileEnablePolicy.getName(),
                'conditionalVisValue':
                '0',
            })

            rootPolicy.addChildPolicy(refPolicy)

            refParam = SA.GetLookFileMaterialReferenceParameter(scriptItem)

            remap = {
                'asset': 'lookfile',
            }
            for param in refParam.getChildren():
                policy = QT4FormWidgets.ValuePolicyProxy(
                    FormMaster.CreateParameterPolicy(refPolicy, param))
                hints = {}
                editorNode.addParameterHints(
                    'Material.lookfile.' +
                    remap.get(policy.getName(), policy.getName()), hints)
                if policy.getName() == 'materialPath':
                    hints = dict(hints)
                    hints['assetPolicy'] = '../asset'

                policy.setWidgetHints(hints)
                refPolicy.addChildPolicy(policy)

            rootPolicy.addChildPolicy(
                FormMaster.CreateParameterPolicy(
                    rootPolicy, editorNode.getParameter('addShaderType')))

            rootPolicy.addChildPolicy(
                FormMaster.CreateParameterPolicy(
                    rootPolicy, editorNode.getParameter('shaders')))

            return rootPolicy
示例#2
0
    def __getObjectTabPolicy(self):
        """
        Returns the widget that should be displayed under the 'Object' tab.
        """
        # Get the create node in the package, which contains the transform
        # parameter.
        packageNode = self.getPackageNode()
        createNode = NU.GetRefNode(packageNode, "create")
        if createNode is None:
            return None

        # Create a root group policy and add some hints on it
        rootPolicy = QT4FormWidgets.PythonGroupPolicy('object')
        rootPolicy.getWidgetHints()['open'] = True
        rootPolicy.getWidgetHints()['hideTitle'] = True

        transformPolicy = QT4FormWidgets.PythonGroupPolicy('transform')
        transformPolicy.getWidgetHints()['open'] = True

        translatePolicy = FormMaster.CreateParameterPolicy(
            None, createNode.getParameter("transform.translate"))
        rotatePolicy = FormMaster.CreateParameterPolicy(
            None, createNode.getParameter("transform.rotate"))
        scalePolicy = FormMaster.CreateParameterPolicy(
            None, createNode.getParameter("transform.scale"))

        transformPolicy.addChildPolicy(translatePolicy)
        transformPolicy.addChildPolicy(rotatePolicy)
        transformPolicy.addChildPolicy(scalePolicy)

        rootPolicy.addChildPolicy(transformPolicy)

        return rootPolicy
    def getMaterialTabPolicy(self):
        # Create a new material policy that just has the prmanLightParams for
        # each light type
        packageNode = self.getPackageNode()
        materialNode = NU.GetRefNode(packageNode, "material_edit")
        if materialNode is not None:
            materialPolicy = QT4FormWidgets.PythonGroupPolicy('material')
            materialPolicy.getWidgetHints()['hideTitle'] = True

            lightShaderPolicy = FormMaster.CreateParameterPolicy(materialPolicy,
                materialNode.getParameter('shaders.arnoldLightShader'))
            lightShaderPolicy = QT4FormWidgets.ValuePolicyProxy(lightShaderPolicy)
            lightShaderPolicy.setWidgetHints(lightShaderPolicy.getWidgetHints())
            lightShaderPolicy.getWidgetHints()['readOnly'] = True
            materialPolicy.addChildPolicy(lightShaderPolicy)

            imageShaderPolicy = FormMaster.CreateParameterPolicy(materialPolicy,
                materialNode.getParameter('shaders.arnoldSurfaceShader'))
            imageShaderPolicy = QT4FormWidgets.ValuePolicyProxy(imageShaderPolicy)
            imageShaderPolicy.setWidgetHints(imageShaderPolicy.getWidgetHints())
            imageShaderPolicy.getWidgetHints()['readOnly'] = True
            materialPolicy.addChildPolicy(imageShaderPolicy)

            params1Policy = FormMaster.CreateParameterPolicy(materialPolicy,
                materialNode.getParameter('shaders.arnoldLightParams'))
            params1Policy.getWidgetHints()['open'] = True
            params2Policy = FormMaster.CreateParameterPolicy(materialPolicy,
                materialNode.getParameter('shaders.arnoldSurfaceParams'))
            params2Policy.getWidgetHints()['open'] = True
            materialPolicy.addChildPolicy(params1Policy)
            materialPolicy.addChildPolicy(params2Policy)
            return materialPolicy
        return None
示例#4
0
    def _AddLightLinkingInitialStatePolicy(cls, uiDelegate, rootPolicy):
        """
        Overridden class method of LightUIDelegate that adds a parameter to
        manage the light linking initialState.

        We need this because we inherit from LightUIDelegate, but unlike light
        creation nodes, whose Linking>light linking>initialState value comes
        from the LightCreate node, ours comes from LightListEdit.

        @type uiDelegate: C{SkyDomeUIDelegate}
        @type rootPolicy: C{QT4FormWidgets.PythonGroupPolicy}
        @param uiDelegate: the instance of UIDelegate on which we are
            performing the operation.
        @param rootPolicy: The policy to which we append the initialState
            parameter.
        """
        lightListEditNode = uiDelegate.getReferencedNode('node_lightListEdit')
        if not lightListEditNode:
            return

        initialStateParam = lightListEditNode.getParameter('initialState')
        if not initialStateParam:
            return

        initialStatePolicy = FormMaster.CreateParameterPolicy(
            rootPolicy, initialStateParam)
        rootPolicy.addChildPolicy(initialStatePolicy)
    def __getObjectTabPolicy(self):
        """
        Returns the widget that should be displayed under the 'Object' tab.
        """
        # Works similarly to SkyDomeUIDelegate.__getObjectTabPolicy, but uses
        # the TransformEdit to modify the transform.
        packageNode = self.getPackageNode()
        transfromEditNode = NU.GetRefNode(packageNode, "transform_edit")

        if transfromEditNode is None:
            return None

        rootPolicy = QT4FormWidgets.PythonGroupPolicy('object')
        rootPolicy.getWidgetHints()['open'] = True
        rootPolicy.getWidgetHints()['hideTitle'] = True

        # Add these three top-level parameters in TransformEdit to the root
        # policy.
        for paramName in ('action', 'rotationOrder', 'args'):
            parameter = transfromEditNode.getParameter(paramName)
            policy = FormMaster.CreateParameterPolicy(rootPolicy,
                                                      parameter)
            rootPolicy.addChildPolicy(policy)

        return rootPolicy
示例#6
0
    def getObjectTabPolicy(self):
        """
        Returns the widget that should be displayed under the 'Object' tab.
        """
        # Get the create node in the package, which contains the transform
        # parameter.
        # return self._LightUIDelegate__getObjectTabPolicy()
        packageNode = self.getPackageNode()
        createNode = NU.GetRefNode(packageNode, "create")
        if createNode is None:
            return None

        # Create a root group policy and add some hints on it
        rootPolicy = QT4FormWidgets.PythonGroupPolicy('object')
        rootPolicy.getWidgetHints()['open'] = True
        rootPolicy.getWidgetHints()['hideTitle'] = True

        transformPolicy = QT4FormWidgets.PythonGroupPolicy('transform')
        transformPolicy.getWidgetHints()['open'] = True

        translatePolicy = FormMaster.CreateParameterPolicy(
            None, createNode.getParameter("transform.translate"))
        rotatePolicy = FormMaster.CreateParameterPolicy(
            None, createNode.getParameter("transform.rotate"))
        scalePolicy = FormMaster.CreateParameterPolicy(
            None, createNode.getParameter("transform.scale"))

        transformPolicy.addChildPolicy(translatePolicy)
        transformPolicy.addChildPolicy(rotatePolicy)
        transformPolicy.addChildPolicy(scalePolicy)
        rootPolicy.addChildPolicy(transformPolicy)

        viewerObjectSettingsNode = NU.GetRefNode(packageNode,
                                                 "viewerObjectSettings")
        annotationPolicy = QT4FormWidgets.PythonGroupPolicy('annotation')
        annotationPolicy.getWidgetHints()['open'] = False

        textPolicy = FormMaster.CreateParameterPolicy(
            None,
            viewerObjectSettingsNode.getParameter(
                'args.viewer.default.annotation.text'))
        colorPolicy = FormMaster.CreateParameterPolicy(
            None,
            viewerObjectSettingsNode.getParameter(
                'args.viewer.default.annotation.color'))
        previewColor = FormMaster.CreateParameterPolicy(
            None, createNode.getParameter('previewColor'))
        pickablePolicy = FormMaster.CreateParameterPolicy(
            None,
            viewerObjectSettingsNode.getParameter(
                'args.viewer.default.pickable'))

        annotationPolicy.addChildPolicy(textPolicy)
        annotationPolicy.addChildPolicy(colorPolicy)
        annotationPolicy.addChildPolicy(previewColor)
        annotationPolicy.addChildPolicy(pickablePolicy)

        rootPolicy.addChildPolicy(annotationPolicy)

        return rootPolicy
        def getObjectTabPolicy(self):
            editorNode = self.getReferencedNode('node_primCreate')
            if not editorNode: return

            rootPolicy = QT4FormWidgets.PythonGroupPolicy('object')
            rootPolicy.getWidgetHints()['hideTitle'] = True

            scriptItem = self.getScriptItem()

            attrsParam = SA.GetAttributesParameterForPath(
                scriptItem.getGafferPro(),
                scriptItem.getMaterialPath(),
                create=False)
            if attrsParam:
                for name in ('resolution', ):

                    param = attrsParam.getChild("geometry." + name)
                    if not param:
                        continue

                    policy = QT4FormWidgets.ValuePolicyProxy(
                        FormMaster.CreateParameterPolicy(rootPolicy, param))
                    policy.getWidgetHints()['int'] = True
                    rootPolicy.addChildPolicy(policy)

            for name in (
                    'previewAlpha',
                    'transform',
                    'viewerPickable',
            ):
                rootPolicy.addChildPolicy(
                    FormMaster.CreateParameterPolicy(
                        rootPolicy, editorNode.getParameter(name)))

            ll = scriptItem.getNode().getParameter('latlongOrientation')
            if ll:
                llp = FormMaster.CreateParameterPolicy(rootPolicy, ll)
                llp.getWidgetHints()['widget'] = 'popup'
                llp.getWidgetHints()['options'] = 'Interior|Exterior'
                llp.getWidgetHints(
                )['help'] = Resources.HELP_LATLONGORIENTATION
                rootPolicy.addChildPolicy(llp)

            return rootPolicy
示例#8
0
            def addLinkingPolicy(defaultPolicy, exceptionsPolicy, name):
                if not defaultPolicy: return

                group = QT4FormWidgets.PythonGroupPolicy(name, rootPolicy)
                group.getWidgetHints()['open'] = True
                rootPolicy.addChildPolicy(group)

                policy = QT4FormWidgets.ValuePolicyProxy(
                    FormMaster.CreateParameterPolicy(group, defaultPolicy))
                policy.setWidgetHints({
                    'widget': 'mapper',
                    'options': 'on:1|off:0'
                })
                group.addChildPolicy(policy)

                policy = FormMaster.NodeBypassPolicy(
                    group, exceptionsPolicy.getNode())
                hints = policy.getWidgetHints()
                hints['label'] = 'enable exceptions'
                hints['widget'] = 'checkBox'
                hints['headerChild'] = 'objects'
                group.addChildPolicy(policy)

                cel = QT4FormWidgets.ValuePolicyProxy(
                    FormMaster.CreateParameterPolicy(group, exceptionsPolicy))
                hints = {}
                hints['widget'] = 'cel'
                hints['conditionalVisOps'] = {
                    'conditionalVisOp': 'notEqualTo',
                    'conditionalVisPath': '../' + policy.getName(),
                    'conditionalVisValue': '0',
                }
                hints['widget'] = 'cel'
                hints['help'] = \
                        'Exceptions will not work unless scene' \
                        ' is connected into Gaffer'
                hints['helpAlert'] = 'warning'

                hints['open'] = True
                cel.setWidgetHints(hints)

                group.addChildPolicy(cel)
        def getLinkingTabPolicy(self):
            editorNode = self.getReferencedNode('node_aimConstraint')
            if not editorNode: return

            scriptItem = self.getScriptItem()

            rootPolicy = QT4FormWidgets.PythonGroupPolicy('object')
            rootPolicy.getWidgetHints()['hideTitle'] = True

            nodePolicy = FormMaster.CreateParameterPolicy(
                None, editorNode.getParameter("basePath"))
            rootPolicy.addChildPolicy(nodePolicy)

            return rootPolicy
    def getMaterialTabPolicy(self):
        # Create a new material policy that just has the prmanLightParams for
        # each light type

        packageNode = self.getPackageNode()
        materialNode = NU.GetRefNode(packageNode, "material")
        if materialNode:
            materialNode.checkDynamicParameters()
            materialPolicy = QT4FormWidgets.PythonGroupPolicy('material')
            materialPolicy.getWidgetHints()['hideTitle'] = True

            shaderPolicy = FormMaster.CreateParameterPolicy(materialPolicy,
                materialNode.getParameter('shaders.arnoldLightShader'))
            shaderPolicy = QT4FormWidgets.ValuePolicyProxy(shaderPolicy)
            shaderPolicy.setWidgetHints(shaderPolicy.getWidgetHints())
            shaderPolicy.getWidgetHints()['readOnly'] = False
            materialPolicy.addChildPolicy(shaderPolicy)

            paramsPolicy = FormMaster.CreateParameterPolicy(materialPolicy,
                materialNode.getParameter('shaders.arnoldLightParams'))
            paramsPolicy.getWidgetHints()['open'] = True
            materialPolicy.addChildPolicy(paramsPolicy)
            return materialPolicy
        return None
示例#11
0
    def __setParameterValue(self, constant, value, createKeyframe):
        from Katana import FormMaster
        names = self.getProfile().getConstant(constant)
        param = self.__searchShaderParameters(names, edit=True)
        if param:
            frame = NodegraphAPI.GetCurrentTime()
            valueParam = param.getChild('value')
            oldValue = valueParam.getValue(NodegraphAPI.GetCurrentTime())
            if valueParam.isExpression():
                # Cannot keyframe an expression
                raise ScriptItems.AnimatingExpressionException(oldValue)

            elif param.isAnimated() and not NodegraphAPI.GetAutoKeyAll():
                if not valueParam.hasKey(frame) and createKeyframe:
                    valueParam.setKey(frame)
                elif valueParam.hasKey(
                        frame) is False and param.getAutoKey() is False:
                    raise ScriptItems.AnimationKeyNotFoundException(oldValue)

            FormMaster.CreateParameterPolicy(None, param).setValue(value)
示例#12
0
    def getColorPolicy(self):
        from Katana import FormMaster, Utils
        names = self.getProfile().getConstant('SHADER_COLOR_PARAM_NAMES')
        param = self.__searchShaderParameters(names, edit=True)
        if param:
            policy = FormMaster.CreateParameterPolicy(None, param)

            #WORKAROUND ALERT!
            #
            # For a newly created material without its Material tab visible,
            # the policy we're about to create is frozen because it has
            # no callbacks (which would typically be added by thawing widgets)
            # But, the policies HAVE been created by the Material tab-- so the relevant
            # ScenegraphIncomingValueSource already exists but is in a frozen
            # state since none of those policies are thawed.
            #
            # That means that if we've changed the shader value since that
            # ScenegraphIncomingValueSource was created, it will have outdated results
            #
            # Policy creation doesn't care about that but as soon as something
            # using the policy queries the incoming attr value, it'll fail.
            #
            # By adding a dummy callback to our policy, we force it to thaw
            # temporarily. This indirectly wakes up ScenegraphIncomingValueSource
            # which will registered for ProducerObserver events. By processing
            # all events, we ensure that the ScenegraphIncomingValueSource has
            # accurate results when a recook is required. We can then remove
            # the callback as anything which cares about future changes to the
            # policy's incoming value will end up thawing it.
            def callback(event):
                pass

            policy.addCallback(callback)
            Utils.EventModule.ProcessAllEvents()
            policy.delCallback(callback)

            return policy
示例#13
0
     def getObjectTabPolicy(self):
         editorNode = self.getReferencedNode('node_primCreate')
         if not editorNode: return
 
         scriptItem = self.getScriptItem()
         
         rootPolicy = QT4FormWidgets.PythonGroupPolicy('object')
         rootPolicy.getWidgetHints()['hideTitle'] = True
 
         nodePolicy = FormMaster.CreateParameterPolicy(None,
                 editorNode.getParameter("transform"))
         rootPolicy.addChildPolicy(nodePolicy)
 
         AddConstraintPolicy(scriptItem, rootPolicy,
                             scriptItem.getPointConstraintNode(), 'point',
                             ['targetPath.i0', 'allowMissingTargets',
                              'baseOrigin', 'targetOrigin'])
 
         AddConstraintPolicy(scriptItem, rootPolicy,
                             scriptItem.getOrientConstraintNode(), 'orient',
                             ['targetPath', 'targetOrientation', 'targetFaceIndex',
                              'allowMissingTargets', 'xAxis', 'yAxis', 'zAxis'])
 
         return rootPolicy
示例#14
0
        def getObjectTabPolicy(self):
            editorNode = self.getReferencedNode('node_lightCreate')
            if not editorNode: return

            scriptItem = self.getScriptItem()

            rootPolicy = QT4FormWidgets.PythonGroupPolicy('object')
            rootPolicy.getWidgetHints()['hideTitle'] = True

            geoPolicy = QT4FormWidgets.PythonGroupPolicy(
                'geometry', rootPolicy)
            geoPolicy.getWidgetHints()['open'] = True

            rootPolicy.addChildPolicy(geoPolicy)

            attrsParam = SA.GetAttributesParameterForPath(
                scriptItem.getGafferPro(),
                scriptItem.getFullName(),
                create=False)

            radiusParam = editorNode.getParameter('radius')

            if attrsParam and attrsParam.getChild('geometry'):
                geoParam = attrsParam.getChild('geometry')

                if not radiusParam:
                    radiusParam = geoParam.getChild('radius')

            if radiusParam:
                radiusPolicy = QT4FormWidgets.ValuePolicyProxy(
                    FormMaster.CreateParameterPolicy(geoPolicy, radiusParam))
                radiusPolicy.getWidgetHints()['min'] = '0'
                geoPolicy.addChildPolicy(radiusPolicy)

            for name in ('fov', 'centerOfInterest', 'near', 'far',
                         'screenWindow'):
                geoPolicy.addChildPolicy(
                    FormMaster.CreateParameterPolicy(
                        geoPolicy, editorNode.getParameter(name)))

            transformPolicy = FormMaster.CreateParameterPolicy(
                rootPolicy, editorNode.getParameter('transform'))

            rootPolicy.addChildPolicy(transformPolicy)

            constraintNode = self.getReferencedNode('node_aimConstraint')
            if not constraintNode: return rootPolicy

            AddConstraintPolicy(scriptItem, rootPolicy, constraintNode, 'aim',
                                [
                                    'targetPath.i0', 'targetOrigin',
                                    'baseAimAxis', 'baseUpAxis', 'targetUpAxis'
                                ])

            displayPolicy = QT4FormWidgets.PythonGroupPolicy(
                'display', rootPolicy)

            rootPolicy.addChildPolicy(displayPolicy)

            vosNode = self.getReferencedNode('node_viewerObjectSettings')
            if vosNode:
                #            textPolicy = FormMaster.NodeBypassPolicy(displayPolicy, vosNode)
                #            hints = textPolicy.getWidgetHints()
                #            hints['label'] = 'display annotation'
                #            hints['widget'] = 'checkBox'
                #            displayPolicy.addChildPolicy(textPolicy)
                displayPolicy.addChildPolicy(
                    FormMaster.CreateParameterPolicy(
                        displayPolicy,
                        vosNode.getParameter(
                            'args.viewer.default.annotation.text')))

            previewColorPolicy = QT4FormWidgets.ValuePolicyProxy(
                FormMaster.CreateParameterPolicy(
                    displayPolicy, editorNode.getParameter('previewColor')))
            displayPolicy.addChildPolicy(previewColorPolicy)

            return rootPolicy
示例#15
0
class GafferLightScriptItem(ScriptItems.GafferScriptItem):
    @staticmethod
    def create(gnode, path):
        lightGroup = SA.BuildLocationPackageForPath(gnode, path)

        SA.AddNodeReferenceForPath(gnode, path, 'package', lightGroup)

        lightGroup.setName(os.path.basename(path) + '_package')
        lightGroup.setType(PackageName)

        nodes = []

        lightCreate = NodegraphAPI.CreateNode('LightCreate', lightGroup)
        lightCreate.addInputPort('in')

        lightCreate.getParameter('name').setExpression('getParent().pathName')

        nodes.append(lightCreate)

        material = NodegraphAPI.CreateNode('Material', lightGroup)
        material.getParameter('action').setValue('edit material', 0)
        material.getParameter('makeInteractive').setValue('Yes', 0)
        material.getParameter('edit.location').setExpression(
            'str(getParent().pathName)+"/master/material"')

        nodes.append(material)

        aimConstraint = NodegraphAPI.CreateNode('AimConstraint', lightGroup)
        aimConstraint.getParameter('basePath').setExpression(
            'getParent().pathName')
        p = aimConstraint.getParameter('addToConstraintList')
        if p: p.setValue(1, 0)
        aimConstraint.setBypassed(True)

        nodes.append(aimConstraint)

        viewerSettings = None
        try:
            # This node is optional - if we're in an older version
            # of Katana it doesn't matter if it's not created
            viewerSettings = NodegraphAPI.CreateNode('ViewerObjectSettings',
                                                     lightGroup)
            viewerSettings.getParameter('CEL').setExpression(
                'getParent().pathName')
            colorParam = viewerSettings.getParameter(
                'args.viewer.default.annotation.color.value')
            colorParam.getChild('i0').setExpression(
                'getParam("%s.previewColor.red")' % lightCreate.getName())
            colorParam.getChild('i1').setExpression(
                'getParam("%s.previewColor.green")' % lightCreate.getName())
            colorParam.getChild('i2').setExpression(
                'getParam("%s.previewColor.blue")' % lightCreate.getName())
            enableParam = viewerSettings.getParameter(
                'args.viewer.default.annotation.color.enable')
            enableParam.setExpression(
                '(getParamRelative(self, "../value.i0"), getParamRelative(self, "../value.i1"), getParamRelative(self, "../value.i2")) != (1.0, 1.0, 1.0)'
            )
            nodes.append(viewerSettings)

        except RuntimeError:
            pass

        SA.WireInlineNodes(lightGroup, nodes)

        SA.AddNodeReferenceParam(lightGroup, 'node_lightCreate', lightCreate)
        SA.AddNodeReferenceParam(lightGroup, 'node_material', material)
        SA.AddNodeReferenceParam(lightGroup, 'node_aimConstraint',
                                 aimConstraint)
        if viewerSettings:
            SA.AddNodeReferenceParam(lightGroup, 'node_viewerObjectSettings',
                                     viewerSettings)

        SA.BuildLookFileMaterialParametersForPath(gnode,
                                                  path + '/master/material')

        attrsParam = SA.GetAttributesParameterForPath(gnode, path, create=True)

        materialAssignParam = attrsParam.createChildString(
            'materialAssign', '')
        materialAssignParam.setExpression(
                '"/"+getParamRelative(self, "../../../master/material").'\
                'param.getFullName(False).replace(".", "/")')

        geoGroup = attrsParam.createChildGroup('geometry')

        if not lightCreate.getParameter('radius'):
            geoGroup.createChildNumber('radius', 1)

        postMerge = SA.GetPostMergeStack(gnode)

        postStack = postMerge.buildChildNode(
            adoptNode=NodegraphAPI.CreateNode('GroupStack', postMerge))

        postStack.setName(os.path.basename(path) + '_postPackage')

        defaultLink = lightCreate.getParameter('initialState')

        defaultShadowLink = lightCreate.getParameters().createChildGroup(
            'lightListDefaultsIfDisabled').createChildNumber(
                'geoShadowEnable', 1)

        pathExpr = 'getNode(%r).pathName' % lightGroup.getName()
        SA.BuildLightLinkNodes(lightGroup,
                               postStack,
                               defaultLink,
                               pathExpr,
                               nodeReferenceParameterName='node_enable',
                               lightLinkNodeName='Enable')
        SA.BuildLightLinkNodes(lightGroup, postStack, defaultShadowLink,
                               pathExpr).getParameter('effect').setValue(
                                   'shadow visibility', 0)

        SA.AddNodeReferenceForPath(gnode, path, 'postmerge', postStack)

    def getCreateNode(self):
        n = self.getNode()
        lc = SA.GetRefNode(n, 'lightCreate')
        return lc

    def getAbstractTransformNode(self):
        return self.getCreateNode()

    def getMaterialNode(self):
        n = self.getNode()
        m = SA.GetRefNode(n, 'material')
        return m

    def getAimConstraintNode(self):
        n = self.getNode()
        ac = SA.GetRefNode(n, 'aimConstraint')
        return ac

    def setAimTarget(self, path):
        ac = self.getAimConstraintNode()
        if not ac: return
        exp = SA.GetScenegraphPathExpression(self, path)
        if exp: ac.getParameter('targetPath.i0').setExpression(exp)
        else: ac.getParameter('targetPath.i0').setValue(path, 0.0)
        ac.setBypassed(False)

    def getMasterMaterial(self):
        n = self.getNode()
        mmOs = SA.GetRefNode(n, 'mmOs')

        if not mmOs:
            return

        if mmOs.isBypassed():
            return

        return mmOs.getParameter('user.mmOs').getValue(0)

    def setMasterMaterial(self, masterMaterialPath):
        self.setLookFileMaterialEnabled(False)
        n = self.getNode()
        mmOs = SA.GetRefNode(n, 'mmOs')

        if not mmOs:
            if not masterMaterialPath:
                return

            # TODO: switch this to OpScript and upgrade existing Gaffer nodes

            mmOs = NodegraphAPI.CreateNode('OpScript', n)
            mmOs.setName('mmos')
            SA.AddNodeReferenceParam(n, 'node_mmOs', mmOs)

            material = SA.GetRefNode(n, 'material')

            x, y = NodegraphAPI.GetNodePosition(material)
            NodegraphAPI.SetNodePosition(mmOs, (x - 100, y))

            mmOs.getInputPortByIndex(0).connect(
                material.getInputPortByIndex(0).getConnectedPort(0))
            material.getInputPortByIndex(0).connect(
                mmOs.getOutputPortByIndex(0))

            mmOs.getParameter('CEL').setExpression(
                """str(getParent().pathName) + '/master'""")
            mmOs.getParameter('script.lua').setValue(
                Resources.MASTERMATERIAL_OPSCRIPT, 0)

            NodegraphAPI.UserParameters.CreateString(mmOs, 'mmOs')

        if not masterMaterialPath:
            mmOs.setBypassed(True)
            return

        gp = self.getGafferPro()
        mmItem = gp.getScriptItemForPath(masterMaterialPath)

        mmScriptItemClass = ScriptItems.GetGafferScriptItemClass(
            'GafferProMasterMaterialPackage')
        if not isinstance(mmItem, mmScriptItemClass):
            raise TypeError("%r doesn't exist as master material" %
                            (masterMaterialPath))

        mmOs.getParameter('user.mmOs').setExpression(
            """getNode(%r).pathName""" % mmItem.getNode().getName())

        mmOs.setBypassed(False)

    def getMaterialPath(self):
        return self.getFullName() + '/master/material'

    def setShader(self, shaderName, asExpression=False):
        self.setMasterMaterial(None)
        self.setLookFileMaterialEnabled(False)
        n = self.getNode()
        m = SA.GetRefNode(n, 'material')
        profile = self.getProfile()
        shaderParam = profile.getMaterialParameterName()

        shadersParam = m.getParameter('shaders')
        if shadersParam.getChild(shaderParam) is None:
            m.addShaderType(shaderParam[:-6])

        if shaderName is None:
            m.getParameter('shaders.%s.enable' % shaderParam).setValue(0, 0)
        else:
            m.getParameter('shaders.%s.enable' % shaderParam).setValue(1, 0)
            if asExpression:
                m.getParameter('shaders.%s.value' %
                               shaderParam).setExpression(shaderName)
            else:
                m.getParameter('shaders.%s.value' % shaderParam).setValue(
                    shaderName, 0)

        profile.shaderSelected(self)

    @deprecated('setShader()', log)
    def setArnoldShader(self, shaderName):
        self.setShader(shaderName)

    def getLookFileMaterialEnabled(self):
        lookFileParam = SA.GetLookFileMaterialEnabledParameter(self)
        if lookFileParam:
            return bool(lookFileParam.getValue(0))

        return False

    def setLookFileMaterialEnabled(self, state):
        SA.GetLookFileMaterialEnabledParameter(self).setValue(bool(state), 0)

    def setLookFileMaterial(self, spref, path, asExpression=False):
        if hasattr(self, 'setMasterMaterial'):
            self.setMasterMaterial(None)
        self.setLookFileMaterialEnabled(True)
        refParam = SA.GetLookFileMaterialReferenceParameter(self)
        if asExpression:
            refParam.getChild('asset').setExpression(spref)
            refParam.getChild('materialPath').setExpression(path)
        else:
            refParam.getChild('asset').setValue(spref, 0)
            refParam.getChild('materialPath').setValue(path, 0)

    def getLookFileMaterial(self):
        refParam = SA.GetLookFileMaterialReferenceParameter(self)
        return tuple(x.getValue(0) for x in refParam.getChildren())

    def acceptsChild(self, childScriptItem):
        return type(childScriptItem).__name__ == 'GafferAimTargetScriptItem'

    def supportsMuting(self):
        return True

    def supportsLocking(self):
        return True

    def isLocked(self):
        node = self.getNodeReference('node_lightCreate')
        interactiveParam = node.getParameter('makeInteractive')
        if interactiveParam:
            return node.getParameter('makeInteractive').getValue(0.0) != 'Yes'

        return False

    def setLocked(self, lock):
        node = self.getNodeReference('node_lightCreate')
        node.getParameter('makeInteractive').setValue("No" if lock else "Yes",
                                                      0.0)

    def getLinkingExceptionsEnabled(self):
        return not self.getNodeReference('node_enable').isBypassed()

    def getShadowLinkingExceptionsEnabled(self):
        return not self.getNodeReference('node_geoShadowEnable').isBypassed()

    def setLinkingExceptionsEnabled(self, state):
        self.getNodeReference('node_enable').setBypassed(not state)

    def setShadowLinkingExceptionsEnabled(self, state):
        self.getNodeReference('node_geoShadowEnable').setBypassed(not state)

    def getColor(self, rootProducer=None):
        names = self.getProfile().getConstant('SHADER_COLOR_PARAM_NAMES')
        if names:
            attr = self.__findAttribute(names, rootProducer)
            if attr:
                return attr.getNearestSample(0.0)

    def getColorPolicy(self):
        from Katana import FormMaster, Utils
        names = self.getProfile().getConstant('SHADER_COLOR_PARAM_NAMES')
        param = self.__searchShaderParameters(names, edit=True)
        if param:
            policy = FormMaster.CreateParameterPolicy(None, param)

            #WORKAROUND ALERT!
            #
            # For a newly created material without its Material tab visible,
            # the policy we're about to create is frozen because it has
            # no callbacks (which would typically be added by thawing widgets)
            # But, the policies HAVE been created by the Material tab-- so the relevant
            # ScenegraphIncomingValueSource already exists but is in a frozen
            # state since none of those policies are thawed.
            #
            # That means that if we've changed the shader value since that
            # ScenegraphIncomingValueSource was created, it will have outdated results
            #
            # Policy creation doesn't care about that but as soon as something
            # using the policy queries the incoming attr value, it'll fail.
            #
            # By adding a dummy callback to our policy, we force it to thaw
            # temporarily. This indirectly wakes up ScenegraphIncomingValueSource
            # which will registered for ProducerObserver events. By processing
            # all events, we ensure that the ScenegraphIncomingValueSource has
            # accurate results when a recook is required. We can then remove
            # the callback as anything which cares about future changes to the
            # policy's incoming value will end up thawing it.
            def callback(event):
                pass

            policy.addCallback(callback)
            Utils.EventModule.ProcessAllEvents()
            policy.delCallback(callback)

            return policy

    def getIntensity(self, rootProducer=None):
        names = self.getProfile().getConstant('SHADER_INT_PARAM_NAMES')
        if names:
            attr = self.__findAttribute(names, rootProducer)
            if attr:
                return attr.getNearestSample(0.0)[0]

    def getExposure(self, rootProducer=None):
        names = self.getProfile().getConstant('SHADER_EXP_PARAM_NAMES')
        if names:
            attr = self.__findAttribute(names, rootProducer)
            if attr:
                return attr.getNearestSample(0.0)[0]

    def __findAttribute(self, names, rootProducer):
        if not rootProducer: return None
        producer = rootProducer.getProducerByPath(self.getFullName())
        if not producer: return None
        #material = producer.getGlobalAttribute('materialAssign')
        #if not material: return None
        #materialProducer = rootProducer.getProducerByPath(material.getNearestSample(0.0)[0])

        # GEOLIB3 We're resolving materials here, no need to walk to
        # the material location
        materialProducer = producer

        for name in names:
            attr = materialProducer.getGlobalAttribute('material.%s' % name)
            if attr: return attr

    def canEditColor(self):
        names = self.getProfile().getConstant('SHADER_COLOR_PARAM_NAMES')
        return bool(self.__searchShaderParameters(names, edit=True))

    def setColor(self, (r, g, b)):
        from Katana import FormMaster
        names = self.getProfile().getConstant('SHADER_COLOR_PARAM_NAMES')
        param = self.__searchShaderParameters(names, edit=True)
        if param:
            policy = FormMaster.CreateParameterPolicy(None, param)
            policy.getArrayChild(0).setValue(r)
            policy.getArrayChild(1).setValue(g)
            policy.getArrayChild(2).setValue(b)