Tomato: added option to clamp result of Mix RGB and Color Math nodes
authorSergey Sharybin <sergey.vfx@gmail.com>
Tue, 10 Jul 2012 09:12:33 +0000 (09:12 +0000)
committerSergey Sharybin <sergey.vfx@gmail.com>
Tue, 10 Jul 2012 09:12:33 +0000 (09:12 +0000)
27 files changed:
source/blender/compositor/nodes/COM_MathNode.cpp
source/blender/compositor/nodes/COM_MixNode.cpp
source/blender/compositor/operations/COM_MathBaseOperation.cpp
source/blender/compositor/operations/COM_MathBaseOperation.h
source/blender/compositor/operations/COM_MixAddOperation.cpp
source/blender/compositor/operations/COM_MixBaseOperation.cpp
source/blender/compositor/operations/COM_MixBaseOperation.h
source/blender/compositor/operations/COM_MixBlendOperation.cpp
source/blender/compositor/operations/COM_MixBurnOperation.cpp
source/blender/compositor/operations/COM_MixColorOperation.cpp
source/blender/compositor/operations/COM_MixDarkenOperation.cpp
source/blender/compositor/operations/COM_MixDifferenceOperation.cpp
source/blender/compositor/operations/COM_MixDivideOperation.cpp
source/blender/compositor/operations/COM_MixDodgeOperation.cpp
source/blender/compositor/operations/COM_MixGlareOperation.cpp
source/blender/compositor/operations/COM_MixHueOperation.cpp
source/blender/compositor/operations/COM_MixLightenOperation.cpp
source/blender/compositor/operations/COM_MixLinearLightOperation.cpp
source/blender/compositor/operations/COM_MixMultiplyOperation.cpp
source/blender/compositor/operations/COM_MixOverlayOperation.cpp
source/blender/compositor/operations/COM_MixSaturationOperation.cpp
source/blender/compositor/operations/COM_MixScreenOperation.cpp
source/blender/compositor/operations/COM_MixSoftLightOperation.cpp
source/blender/compositor/operations/COM_MixSubtractOperation.cpp
source/blender/compositor/operations/COM_MixValueOperation.cpp
source/blender/editors/space_node/drawnode.c
source/blender/makesrna/intern/rna_nodetree.c

index 300c9967cc4166dce5ba033deb214d3e55b16c14..307590b977b4b33e53f7295b48cf966b957ba28f 100644 (file)
@@ -83,10 +83,14 @@ void MathNode::convertToOperations(ExecutionSystem *graph, CompositorContext *co
        }
        
        if (operation != NULL) {
+               bool useClamp = this->getbNode()->custom2;
+
                this->getInputSocket(0)->relinkConnections(operation->getInputSocket(0), 0, graph);
                this->getInputSocket(1)->relinkConnections(operation->getInputSocket(1), 1, graph);
                this->getOutputSocket(0)->relinkConnections(operation->getOutputSocket());
-       
+
+               operation->setUseClamp(useClamp);
+
                graph->addOperation(operation);
        }
 }
index eb62ebd263590505b134f7b7e00711ca6259883d..7aeaaf56c9894a4c54720a320ae7d1ef8cf838f4 100644 (file)
@@ -58,6 +58,8 @@ void MixNode::convertToOperations(ExecutionSystem *graph, CompositorContext *con
        InputSocket *color2Socket = this->getInputSocket(2);
        OutputSocket *outputSocket = this->getOutputSocket(0);
        bNode *editorNode = this->getbNode();
+       bool useAlphaPremultiply = this->getbNode()->custom2 & 1;
+       bool useClamp = this->getbNode()->custom2 & 2;
        
        MixBaseOperation *convertProg;
        
@@ -119,7 +121,8 @@ void MixNode::convertToOperations(ExecutionSystem *graph, CompositorContext *con
                        convertProg = new MixBlendOperation();
                        break;
        }
-       convertProg->setUseValueAlphaMultiply(this->getbNode()->custom2);
+       convertProg->setUseValueAlphaMultiply(useAlphaPremultiply);
+       convertProg->setUseClamp(useClamp);
 
        valueSocket->relinkConnections(convertProg->getInputSocket(0), 0, graph);
        color1Socket->relinkConnections(convertProg->getInputSocket(1), 1, graph);
index 1bf89be57b5eb6a324f92a216a847ff0cf9e3fee..596895a963a6fb28dd988534ffc0bd1a9cc64aaf 100644 (file)
@@ -64,6 +64,13 @@ void MathBaseOperation::determineResolution(unsigned int resolution[], unsigned
        NodeOperation::determineResolution(resolution, preferredResolution);
 }
 
+void MathBaseOperation::clampIfNeeded(float *color)
+{
+       if (this->m_useClamp) {
+               CLAMP(color[0], 0.0f, 1.0f);
+       }
+}
+
 void MathAddOperation::executePixel(float *outputValue, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[])
 {
        float inputValue1[4];
@@ -73,6 +80,8 @@ void MathAddOperation::executePixel(float *outputValue, float x, float y, PixelS
        this->m_inputValue2Operation->read(&inputValue2[0], x, y, sampler, inputBuffers);
        
        outputValue[0] = inputValue1[0] + inputValue2[0];
+
+       clampIfNeeded(outputValue);
 }
 
 void MathSubtractOperation::executePixel(float *outputValue, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[])
@@ -84,6 +93,8 @@ void MathSubtractOperation::executePixel(float *outputValue, float x, float y, P
        this->m_inputValue2Operation->read(&inputValue2[0], x, y, sampler, inputBuffers);
        
        outputValue[0] = inputValue1[0] - inputValue2[0];
+
+       clampIfNeeded(outputValue);
 }
 
 void MathMultiplyOperation::executePixel(float *outputValue, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[])
@@ -95,6 +106,8 @@ void MathMultiplyOperation::executePixel(float *outputValue, float x, float y, P
        this->m_inputValue2Operation->read(&inputValue2[0], x, y, sampler, inputBuffers);
        
        outputValue[0] = inputValue1[0] * inputValue2[0];
+
+       clampIfNeeded(outputValue);
 }
 
 void MathDivideOperation::executePixel(float *outputValue, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[])
@@ -109,6 +122,8 @@ void MathDivideOperation::executePixel(float *outputValue, float x, float y, Pix
                outputValue[0] = 0.0;
        else
                outputValue[0] = inputValue1[0] / inputValue2[0];
+
+       clampIfNeeded(outputValue);
 }
 
 void MathSineOperation::executePixel(float *outputValue, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[])
@@ -120,6 +135,8 @@ void MathSineOperation::executePixel(float *outputValue, float x, float y, Pixel
        this->m_inputValue2Operation->read(&inputValue2[0], x, y, sampler, inputBuffers);
        
        outputValue[0] = sin(inputValue1[0]);
+
+       clampIfNeeded(outputValue);
 }
 
 void MathCosineOperation::executePixel(float *outputValue, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[])
@@ -131,6 +148,8 @@ void MathCosineOperation::executePixel(float *outputValue, float x, float y, Pix
        this->m_inputValue2Operation->read(&inputValue2[0], x, y, sampler, inputBuffers);
        
        outputValue[0] = cos(inputValue1[0]);
+
+       clampIfNeeded(outputValue);
 }
 
 void MathTangentOperation::executePixel(float *outputValue, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[])
@@ -142,6 +161,8 @@ void MathTangentOperation::executePixel(float *outputValue, float x, float y, Pi
        this->m_inputValue2Operation->read(&inputValue2[0], x, y, sampler, inputBuffers);
        
        outputValue[0] = tan(inputValue1[0]);
+
+       clampIfNeeded(outputValue);
 }
 
 void MathArcSineOperation::executePixel(float *outputValue, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[])
@@ -156,6 +177,8 @@ void MathArcSineOperation::executePixel(float *outputValue, float x, float y, Pi
                outputValue[0] = asin(inputValue1[0]);
        else
                outputValue[0] = 0.0;
+
+       clampIfNeeded(outputValue);
 }
 
 void MathArcCosineOperation::executePixel(float *outputValue, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[])
@@ -170,6 +193,8 @@ void MathArcCosineOperation::executePixel(float *outputValue, float x, float y,
                outputValue[0] = acos(inputValue1[0]);
        else
                outputValue[0] = 0.0;
+
+       clampIfNeeded(outputValue);
 }
 
 void MathArcTangentOperation::executePixel(float *outputValue, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[])
@@ -181,6 +206,8 @@ void MathArcTangentOperation::executePixel(float *outputValue, float x, float y,
        this->m_inputValue2Operation->read(&inputValue2[0], x, y, sampler, inputBuffers);
        
        outputValue[0] = atan(inputValue1[0]);
+
+       clampIfNeeded(outputValue);
 }
 
 void MathPowerOperation::executePixel(float *outputValue, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[])
@@ -204,6 +231,8 @@ void MathPowerOperation::executePixel(float *outputValue, float x, float y, Pixe
                        outputValue[0] = 0.0;
                }
        }
+
+       clampIfNeeded(outputValue);
 }
 
 void MathLogarithmOperation::executePixel(float *outputValue, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[])
@@ -218,6 +247,8 @@ void MathLogarithmOperation::executePixel(float *outputValue, float x, float y,
                outputValue[0] = log(inputValue1[0]) / log(inputValue2[0]);
        else
                outputValue[0] = 0.0;
+
+       clampIfNeeded(outputValue);
 }
 
 void MathMinimumOperation::executePixel(float *outputValue, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[])
@@ -229,6 +260,8 @@ void MathMinimumOperation::executePixel(float *outputValue, float x, float y, Pi
        this->m_inputValue2Operation->read(&inputValue2[0], x, y, sampler, inputBuffers);
        
        outputValue[0] = min(inputValue1[0], inputValue2[0]);
+
+       clampIfNeeded(outputValue);
 }
 
 void MathMaximumOperation::executePixel(float *outputValue, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[])
@@ -240,6 +273,8 @@ void MathMaximumOperation::executePixel(float *outputValue, float x, float y, Pi
        this->m_inputValue2Operation->read(&inputValue2[0], x, y, sampler, inputBuffers);
        
        outputValue[0] = max(inputValue1[0], inputValue2[0]);
+
+       clampIfNeeded(outputValue);
 }
 
 void MathRoundOperation::executePixel(float *outputValue, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[])
@@ -251,6 +286,8 @@ void MathRoundOperation::executePixel(float *outputValue, float x, float y, Pixe
        this->m_inputValue2Operation->read(&inputValue2[0], x, y, sampler, inputBuffers);
        
        outputValue[0] = round(inputValue1[0]);
+
+       clampIfNeeded(outputValue);
 }
 
 void MathLessThanOperation::executePixel(float *outputValue, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[])
@@ -262,6 +299,8 @@ void MathLessThanOperation::executePixel(float *outputValue, float x, float y, P
        this->m_inputValue2Operation->read(&inputValue2[0], x, y, sampler, inputBuffers);
        
        outputValue[0] = inputValue1[0] < inputValue2[0] ? 1.0f : 0.0f;
+
+       clampIfNeeded(outputValue);
 }
 
 void MathGreaterThanOperation::executePixel(float *outputValue, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[])
@@ -273,6 +312,8 @@ void MathGreaterThanOperation::executePixel(float *outputValue, float x, float y
        this->m_inputValue2Operation->read(&inputValue2[0], x, y, sampler, inputBuffers);
        
        outputValue[0] = inputValue1[0] > inputValue2[0] ? 1.0f : 0.0f;
+
+       clampIfNeeded(outputValue);
 }
 
 
index be06537cbf02ecfcc7dde3d6f3240951b9c1145f..e53176aea4989a826b3a4f6553d78d6f4ee58d71 100644 (file)
@@ -37,11 +37,15 @@ protected:
        SocketReader *m_inputValue1Operation;
        SocketReader *m_inputValue2Operation;
 
+       bool m_useClamp;
+
 protected:
        /**
         * Default constructor
         */
        MathBaseOperation();
+
+       void clampIfNeeded(float *color);
 public:
        /**
         * the inner loop of this program
@@ -62,6 +66,8 @@ public:
         * Determine resolution
         */
        void determineResolution(unsigned int resolution[], unsigned int preferredResolution[]);
+
+       void setUseClamp(bool value) { this->m_useClamp = value; }
 };
 
 class MathAddOperation : public MathBaseOperation {
index 7f7315fb3fff07c0c3eaac5ee83f83a4751e82d0..f8bd802928d1f88de8a10746e880825221c24bf9 100644 (file)
@@ -46,5 +46,7 @@ void MixAddOperation::executePixel(float *outputValue, float x, float y, PixelSa
        outputValue[1] = inputColor1[1] + value * inputColor2[1];
        outputValue[2] = inputColor1[2] + value * inputColor2[2];
        outputValue[3] = inputColor1[3];
+
+       clampIfNeeded(outputValue);
 }
 
index fbe92f54aa804c9d3243ba7b968bde7a817246d3..9e0ae0c6ee8a2089100c3cfd65f484627b824e1e 100644 (file)
@@ -94,3 +94,12 @@ void MixBaseOperation::determineResolution(unsigned int resolution[], unsigned i
        NodeOperation::determineResolution(resolution, preferredResolution);
 }
 
+void MixBaseOperation::clampIfNeeded(float *color)
+{
+       if (this->m_useClamp) {
+               CLAMP(color[0], 0.0f, 1.0f);
+               CLAMP(color[1], 0.0f, 1.0f);
+               CLAMP(color[2], 0.0f, 1.0f);
+               CLAMP(color[3], 0.0f, 1.0f);
+       }
+}
index 268d483224344e8d98aff4f21eb2a8fe78e80eb9..05301fd0378ee8bb8764c226a9c11999515220f6 100644 (file)
@@ -38,6 +38,9 @@ protected:
        SocketReader *m_inputColor1Operation;
        SocketReader *m_inputColor2Operation;
        bool m_valueAlphaMultiply;
+       bool m_useClamp;
+
+       void clampIfNeeded(float *color);
 public:
        /**
         * Default constructor
@@ -63,5 +66,6 @@ public:
        
        void setUseValueAlphaMultiply(const bool value) { this->m_valueAlphaMultiply = value; }
        bool useValueAlphaMultiply() { return this->m_valueAlphaMultiply; }
+       void setUseClamp(bool value) { this->m_useClamp = value; }
 };
 #endif
index 341aba0e7fcc4bd96e9790f27c0d114d1539f50a..0c6ede017975e7d415bc95c44cd920ebd8292af6 100644 (file)
@@ -47,4 +47,6 @@ void MixBlendOperation::executePixel(float *outputValue, float x, float y, Pixel
        outputValue[1] = valuem * (inputColor1[1]) + value * (inputColor2[1]);
        outputValue[2] = valuem * (inputColor1[2]) + value * (inputColor2[2]);
        outputValue[3] = inputColor1[3];
+
+       clampIfNeeded(outputValue);
 }
index 039915ab66a5d011d15573c90eba70adb4becfab..0d736583c58b3cebca6beb1d0c8ba8e9c82cb7be 100644 (file)
@@ -83,5 +83,7 @@ void MixBurnOperation::executePixel(float *outputValue, float x, float y, PixelS
        }
        
        outputValue[3] = inputColor1[3];
+
+       clampIfNeeded(outputValue);
 }
 
index cb5791c02bb8c11fddd661d7bf564961a6712f05..e7f7eb4d656d326d884a1e10b03008460f7d2830 100644 (file)
@@ -58,5 +58,7 @@ void MixColorOperation::executePixel(float *outputValue, float x, float y, Pixel
                outputValue[2] = valuem * (inputColor1[2]) + value * tmpb;
        }
        outputValue[3] = inputColor1[3];
+
+       clampIfNeeded(outputValue);
 }
 
index db243cf4a8775c983176b551109383d2f6c9901b..f229a89fdabfee805c6e1db43d52e5aa46355d8d 100644 (file)
@@ -53,5 +53,7 @@ void MixDarkenOperation::executePixel(float *outputValue, float x, float y, Pixe
        else outputValue[2] = inputColor1[2];
        
        outputValue[3] = inputColor1[3];
+
+       clampIfNeeded(outputValue);
 }
 
index 9fe1a3cb94b1812d25e40a50cecef8cc16012dcd..70d621822787c3ac3caf253333bce58ca1f6ee67 100644 (file)
@@ -46,5 +46,7 @@ void MixDifferenceOperation::executePixel(float *outputValue, float x, float y,
        outputValue[1] = valuem * inputColor1[1] + value *fabsf(inputColor1[1] - inputColor2[1]);
        outputValue[2] = valuem * inputColor1[2] + value *fabsf(inputColor1[2] - inputColor2[2]);
        outputValue[3] = inputColor1[3];
+
+       clampIfNeeded(outputValue);
 }
 
index 0e1bd408b8923a75c947800c510571d26f1c1aa8..7ca47c4f50790e5dd4b0d284594cafd13656b65c 100644 (file)
@@ -56,5 +56,7 @@ void MixDivideOperation::executePixel(float *outputValue, float x, float y, Pixe
                outputValue[2] = 0.0f;
        
        outputValue[3] = inputColor1[3];
+
+       clampIfNeeded(outputValue);
 }
 
index ea01806267be9103a716691abda9b57c8acf5cb9..b8ed3e252a9975ff99958ea7767f2e14f0b9b9d7 100644 (file)
@@ -88,5 +88,7 @@ void MixDodgeOperation::executePixel(float *outputValue, float x, float y, Pixel
                outputValue[2] = 0.0f;
        
        outputValue[3] = inputColor1[3];
+
+       clampIfNeeded(outputValue);
 }
 
index 7cd24b3bf061318539eed14af522d74c44835d59..f0729bec23dabb2e3a89e212a3cb30d4dc3c076d 100644 (file)
@@ -44,4 +44,6 @@ void MixGlareOperation::executePixel(float *outputValue, float x, float y, Pixel
        outputValue[1] = mf * ((inputColor1[1]) + value * (inputColor2[1] - inputColor1[1]));
        outputValue[2] = mf * ((inputColor1[2]) + value * (inputColor2[2] - inputColor1[2]));
        outputValue[3] = inputColor1[3];
+
+       clampIfNeeded(outputValue);
 }
index e7b444616f4653aaaf11b29ef3541009be074236..5528597ab178dca609470229bb4f052d3fb21592 100644 (file)
@@ -58,4 +58,6 @@ void MixHueOperation::executePixel(float *outputValue, float x, float y, PixelSa
                outputValue[2] = valuem * (inputColor1[2]) + value * tmpb;
        }
        outputValue[3] = inputColor1[3];
+
+       clampIfNeeded(outputValue);
 }
index 89166637f9f4f574c6927c545ee8eca71a94a5d9..d742bc27b001f4da2ab1a1b10dcb659c2fdacac6 100644 (file)
@@ -51,5 +51,7 @@ void MixLightenOperation::executePixel(float *outputValue, float x, float y, Pix
        if (tmp > inputColor1[2]) outputValue[2] = tmp;
        else outputValue[2] = inputColor1[2];
        outputValue[3] = inputColor1[3];
+
+       clampIfNeeded(outputValue);
 }
 
index 5406a3cbcc1c418e3a11d5ea85ea9d0367d87640..006faf3f18b0312b5889b28348440bae24701afc 100644 (file)
@@ -54,4 +54,6 @@ void MixLinearLightOperation::executePixel(float *outputValue, float x, float y,
                outputValue[2] = inputColor1[2] + value * (2.0f * (inputColor2[2]) - 1.0f);
        
        outputValue[3] = inputColor1[3];
+
+       clampIfNeeded(outputValue);
 }
index 978e96eb2f6c679cf0af7d2c318c33cc56574fe5..a480182a785bec89a2e8ee2fb1be0d0f8f961139 100644 (file)
@@ -46,5 +46,7 @@ void MixMultiplyOperation::executePixel(float *outputValue, float x, float y, Pi
        outputValue[1] = inputColor1[1] * (valuem + value * inputColor2[1]);
        outputValue[2] = inputColor1[2] * (valuem + value * inputColor2[2]);
        outputValue[3] = inputColor1[3];
+
+       clampIfNeeded(outputValue);
 }
 
index f4f96747acdc1982abaeb4031bdc76b55cbd9154..7c39f70faaa89a051fd8139974c9856785d12006 100644 (file)
@@ -62,5 +62,7 @@ void MixOverlayOperation::executePixel(float *outputValue, float x, float y, Pix
                outputValue[2] = 1.0f - (valuem + 2.0f * value * (1.0f - inputColor2[2])) * (1.0f - inputColor1[2]);
        }
        outputValue[3] = inputColor1[3];
+
+       clampIfNeeded(outputValue);
 }
 
index c9c6f691fdb07efff2f8a00b6c6705d6a6c36b24..1ae856d2ba0952c7f2144787dd02b08822ebb1e7 100644 (file)
@@ -54,4 +54,6 @@ void MixSaturationOperation::executePixel(float *outputValue, float x, float y,
                hsv_to_rgb(rH, (valuem * rS + value * colS), rV, &outputValue[0], &outputValue[1], &outputValue[2]);
        }
        outputValue[3] = inputColor1[3];
+
+       clampIfNeeded(outputValue);
 }
index 9bc9144f4ff94381693533772214c39aefea176a..c4ec210eb1cef0ebc6d8640c02f820197a214510 100644 (file)
@@ -47,5 +47,7 @@ void MixScreenOperation::executePixel(float *outputValue, float x, float y, Pixe
        outputValue[1] = 1.0f - (valuem + value * (1.0f - inputColor2[1])) * (1.0f - inputColor1[1]);
        outputValue[2] = 1.0f - (valuem + value * (1.0f - inputColor2[2])) * (1.0f - inputColor1[2]);
        outputValue[3] = inputColor1[3];
+
+       clampIfNeeded(outputValue);
 }
 
index 52c2e8829dc393b7cd63ade1c9a86b1777a91c51..9de56fde87dcbc32294d576e2a1a4c5bf422418d 100644 (file)
@@ -28,7 +28,7 @@ MixSoftLightOperation::MixSoftLightOperation() : MixBaseOperation()
 }
 
 void MixSoftLightOperation::executePixel(float *outputValue, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[]) \
-       {
+{
        float inputColor1[4];
        float inputColor2[4];
        float value;
@@ -52,5 +52,7 @@ void MixSoftLightOperation::executePixel(float *outputValue, float x, float y, P
        outputValue[1] = valuem * (inputColor1[1]) + value * (((1.0f - inputColor1[1]) * inputColor2[1] * (inputColor1[1])) + (inputColor1[1] * scg));
        outputValue[2] = valuem * (inputColor1[2]) + value * (((1.0f - inputColor1[2]) * inputColor2[2] * (inputColor1[2])) + (inputColor1[2] * scb));
        outputValue[3] = inputColor1[3];
-       }
+
+       clampIfNeeded(outputValue);
+}
 
index 60f54ab478de3b5b31017314c299e39303c1d456..4861346c9daf00eb58d3592c557d1a93f59b3ef0 100644 (file)
@@ -44,5 +44,7 @@ void MixSubtractOperation::executePixel(float *outputValue, float x, float y, Pi
        outputValue[1] = inputColor1[1] - value * (inputColor2[1]);
        outputValue[2] = inputColor1[2] - value * (inputColor2[2]);
        outputValue[3] = inputColor1[3];
+
+       clampIfNeeded(outputValue);
 }
 
index 2651b0d7dee3eb472dd50c7a294c45f22d2b73e5..511bbdf85f45283053a315fc8181cd8019905006 100644 (file)
@@ -52,4 +52,6 @@ void MixValueOperation::executePixel(float *outputValue, float x, float y, Pixel
        rgb_to_hsv(inputColor2[0], inputColor2[1], inputColor2[2], &colH, &colS, &colV);
        hsv_to_rgb(rH, rS, (valuem * rV + value * colV), &outputValue[0], &outputValue[1], &outputValue[2]);
        outputValue[3] = inputColor1[3];
+
+       clampIfNeeded(outputValue);
 }
index 625d2343dff49fd744c838b5200a734e8d8e0cdc..3193b8a079d2316c7193f150c43cd059532238a6 100644 (file)
@@ -300,14 +300,17 @@ static void node_buts_rgb(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr
 
 static void node_buts_mix_rgb(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
 {      
-       uiLayout *row;
+       uiLayout *row, *col;
 
        bNodeTree *ntree = (bNodeTree *)ptr->id.data;
 
-       row = uiLayoutRow(layout, TRUE);
+       col = uiLayoutColumn(layout, FALSE);
+       row = uiLayoutRow(col, TRUE);
        uiItemR(row, ptr, "blend_type", 0, "", ICON_NONE);
        if (ntree->type == NTREE_COMPOSIT)
                uiItemR(row, ptr, "use_alpha", 0, "", ICON_IMAGE_RGB_ALPHA);
+
+       uiItemR(col, ptr, "use_clamp", 0, NULL, ICON_NONE);
 }
 
 static void node_buts_time(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
@@ -449,6 +452,7 @@ static void node_buts_texture(uiLayout *layout, bContext *UNUSED(C), PointerRNA
 static void node_buts_math(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
 { 
        uiItemR(layout, ptr, "operation", 0, "", ICON_NONE);
+       uiItemR(layout, ptr, "use_clamp", 0, NULL, ICON_NONE);
 }
 
 static int node_resize_area_default(bNode *node, int x, int y)
index 3646e4d2a13d9438b6a9ca13d5226789dca9d23e..a72059063fd9e1455eb2154c664acf1aedecd8c4 100644 (file)
@@ -1191,6 +1191,11 @@ static void def_math(StructRNA *srna)
        RNA_def_property_enum_items(prop, node_math_items);
        RNA_def_property_ui_text(prop, "Operation", "");
        RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
+
+       prop = RNA_def_property(srna, "use_clamp", PROP_BOOLEAN, PROP_NONE);
+       RNA_def_property_boolean_sdna(prop, NULL, "custom2", 1);
+       RNA_def_property_ui_text(prop, "Clamp", "Clamp result of the node to 0..1 range");
+       RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
 }
 
 static void def_vector_math(StructRNA *srna)
@@ -1272,6 +1277,11 @@ static void def_mix_rgb(StructRNA *srna)
        RNA_def_property_boolean_sdna(prop, NULL, "custom2", 1);
        RNA_def_property_ui_text(prop, "Alpha", "Include alpha of second input in this operation");
        RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
+
+       prop = RNA_def_property(srna, "use_clamp", PROP_BOOLEAN, PROP_NONE);
+       RNA_def_property_boolean_sdna(prop, NULL, "custom2", 2);
+       RNA_def_property_ui_text(prop, "Clamp", "Clamp result of the node to 0..1 range");
+       RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
 }
 
 static void def_texture(StructRNA *srna)