bool FixedFunctionOp::isInverse(ConstOpRcPtr & op) const
{
    ConstFixedFunctionOpRcPtr typedRcPtr = DynamicPtrCast<const FixedFunctionOp>(op);
    if(!typedRcPtr) return false;

    ConstFixedFunctionOpDataRcPtr fnOpData = typedRcPtr->fnData();
    return fnData()->isInverse(fnOpData);
}
void FixedFunctionOp::finalize()
{
    // In this initial implementation, only 32f processing is natively supported.
    fnData()->setInputBitDepth(BIT_DEPTH_F32);
    fnData()->setOutputBitDepth(BIT_DEPTH_F32);

    fnData()->validate();
    fnData()->finalize();

    const FixedFunctionOp & constThis = *this;
    ConstFixedFunctionOpDataRcPtr fnOpData = constThis.fnData();
    m_cpuOp = GetFixedFunctionCPURenderer(fnOpData);

    // Create the cacheID
    std::ostringstream cacheIDStream;
    cacheIDStream << "<FixedFunctionOp ";
    cacheIDStream << fnData()->getCacheID() << " ";
    cacheIDStream << ">";
    
    m_cacheID = cacheIDStream.str();
}
void FixedFunctionOp::extractGpuShaderInfo(GpuShaderDescRcPtr & shaderDesc) const
{
    if(getInputBitDepth()!=BIT_DEPTH_F32 || getOutputBitDepth()!=BIT_DEPTH_F32)
    {
        throw Exception("Only 32F bit depth is supported for the GPU shader");
    }

    GpuShaderText ss(shaderDesc->getLanguage());
    ss.indent();

    ConstFixedFunctionOpDataRcPtr fnOpData = fnData();
    GetFixedFunctionGPUShaderProgram(ss, fnOpData);

    ss.dedent();

    shaderDesc->addToFunctionShaderCode(ss.string().c_str());
}
MMatrix sphericalBlendShapeVisualizerDrawOverride::getSpaceMatrix(const MDagPath& objPath) const
{
	MStatus status;

	MObject locatorNode = objPath.node(&status);
	if (!status)
	{
		return MMatrix();
	}

	MPlug spaceMatrixPlug(locatorNode, sphericalBlendShapeVisualizer::aSpaceMatrix);
	MObject spaceMatrixObject;
	status = spaceMatrixPlug.getValue(spaceMatrixObject);
	MFnMatrixData fnData(spaceMatrixObject);
	MMatrix matrix = fnData.matrix();

	return matrix;
}