Exemple #1
0
void LensDistortionNode::convertToOperations(ExecutionSystem *graph, CompositorContext *context)
{
    bNode *editorNode = this->getbNode();
    NodeLensDist *data = (NodeLensDist *)editorNode->storage;
    if (data->proj) {
        ProjectorLensDistortionOperation *operation = new ProjectorLensDistortionOperation();
        operation->setbNode(editorNode);
        this->getInputSocket(0)->relinkConnections(operation->getInputSocket(0), 0, graph);
        this->getInputSocket(2)->relinkConnections(operation->getInputSocket(1), 2, graph);
        this->getOutputSocket(0)->relinkConnections(operation->getOutputSocket(0));

        graph->addOperation(operation);

    }
    else {
        ScreenLensDistortionOperation *operation = new ScreenLensDistortionOperation();
        operation->setbNode(editorNode);
        operation->setFit(data->fit);
        operation->setJitter(data->jit);

        if (!getInputSocket(1)->isConnected())
            operation->setDistortion(getInputSocket(1)->getEditorValueFloat());
        if (!getInputSocket(2)->isConnected())
            operation->setDispersion(getInputSocket(2)->getEditorValueFloat());

        this->getInputSocket(0)->relinkConnections(operation->getInputSocket(0), 0, graph);
        this->getInputSocket(1)->relinkConnections(operation->getInputSocket(1), 1, graph);
        this->getInputSocket(2)->relinkConnections(operation->getInputSocket(2), 2, graph);

        this->getOutputSocket(0)->relinkConnections(operation->getOutputSocket(0));

        graph->addOperation(operation);
    }

}
void GammaNode::convertToOperations(NodeConverter &converter, const CompositorContext &context) const
{
	GammaOperation *operation = new GammaOperation();
	converter.addOperation(operation);
	
	converter.mapInputSocket(getInputSocket(0), operation->getInputSocket(0));
	converter.mapInputSocket(getInputSocket(1), operation->getInputSocket(1));
	converter.mapOutputSocket(getOutputSocket(0), operation->getOutputSocket(0));
}
void SwitchNode::convertToOperations(NodeConverter &converter, const CompositorContext &context) const
{
	bool condition = this->getbNode()->custom1;
	
	NodeOperationOutput *result;
	if (!condition)
		result = converter.addInputProxy(getInputSocket(0));
	else
		result = converter.addInputProxy(getInputSocket(1));
	
	converter.mapOutputSocket(getOutputSocket(0), result);
}
void BilateralBlurNode::convertToOperations(NodeConverter &converter,
                                            const CompositorContext &context) const
{
  NodeBilateralBlurData *data = (NodeBilateralBlurData *)this->getbNode()->storage;
  BilateralBlurOperation *operation = new BilateralBlurOperation();
  operation->setQuality(context.getQuality());
  operation->setData(data);

  converter.addOperation(operation);
  converter.mapInputSocket(getInputSocket(0), operation->getInputSocket(0));
  converter.mapInputSocket(getInputSocket(1), operation->getInputSocket(1));
  converter.mapOutputSocket(getOutputSocket(0), operation->getOutputSocket(0));
}
void SetAlphaNode::convertToOperations(NodeConverter &converter, const CompositorContext &/*context*/) const
{
	SetAlphaOperation *operation = new SetAlphaOperation();
	
	if (!this->getInputSocket(0)->isLinked() && this->getInputSocket(1)->isLinked()) {
		operation->setResolutionInputSocketIndex(1);
	}
	
	converter.addOperation(operation);
	
	converter.mapInputSocket(getInputSocket(0), operation->getInputSocket(0));
	converter.mapInputSocket(getInputSocket(1), operation->getInputSocket(1));
	converter.mapOutputSocket(getOutputSocket(0), operation->getOutputSocket());
}
Exemple #6
0
void GlareNode::convertToOperations(NodeConverter &converter,
                                    const CompositorContext & /*context*/) const
{
  bNode *node = this->getbNode();
  NodeGlare *glare = (NodeGlare *)node->storage;

  GlareBaseOperation *glareoperation = NULL;
  switch (glare->type) {
    default:
    case 3:
      glareoperation = new GlareGhostOperation();
      break;
    case 2:  // streaks
      glareoperation = new GlareStreaksOperation();
      break;
    case 1:  // fog glow
      glareoperation = new GlareFogGlowOperation();
      break;
    case 0:  // simple star
      glareoperation = new GlareSimpleStarOperation();
      break;
  }
  BLI_assert(glareoperation);
  glareoperation->setGlareSettings(glare);

  GlareThresholdOperation *thresholdOperation = new GlareThresholdOperation();
  thresholdOperation->setGlareSettings(glare);

  SetValueOperation *mixvalueoperation = new SetValueOperation();
  mixvalueoperation->setValue(0.5f + glare->mix * 0.5f);

  MixGlareOperation *mixoperation = new MixGlareOperation();
  mixoperation->setResolutionInputSocketIndex(1);
  mixoperation->getInputSocket(2)->setResizeMode(COM_SC_FIT);

  converter.addOperation(glareoperation);
  converter.addOperation(thresholdOperation);
  converter.addOperation(mixvalueoperation);
  converter.addOperation(mixoperation);

  converter.mapInputSocket(getInputSocket(0), thresholdOperation->getInputSocket(0));
  converter.addLink(thresholdOperation->getOutputSocket(), glareoperation->getInputSocket(0));

  converter.addLink(mixvalueoperation->getOutputSocket(), mixoperation->getInputSocket(0));
  converter.mapInputSocket(getInputSocket(0), mixoperation->getInputSocket(1));
  converter.addLink(glareoperation->getOutputSocket(), mixoperation->getInputSocket(2));
  converter.mapOutputSocket(getOutputSocket(), mixoperation->getOutputSocket());
}
void CornerPinNode::convertToOperations(NodeConverter &converter, const CompositorContext &context) const
{
	NodeInput *input_image = this->getInputSocket(0);
	/* note: socket order differs between UI node and operations:
	 * bNode uses intuitive order following top-down layout:
	 *   upper-left, upper-right, lower-left, lower-right
	 * Operations use same order as the tracking blenkernel functions expect:
	 *   lower-left, lower-right, upper-right, upper-left
	 */
	const int node_corner_index[4] = { 3, 4, 2, 1 };

	NodeOutput *output_warped_image = this->getOutputSocket(0);
	NodeOutput *output_plane = this->getOutputSocket(1);

	PlaneCornerPinWarpImageOperation *warp_image_operation = new PlaneCornerPinWarpImageOperation();
	converter.addOperation(warp_image_operation);
	PlaneCornerPinMaskOperation *plane_mask_operation = new PlaneCornerPinMaskOperation();
	converter.addOperation(plane_mask_operation);
	
	converter.mapInputSocket(input_image, warp_image_operation->getInputSocket(0));
	for (int i = 0; i < 4; ++i) {
		NodeInput *corner_input = getInputSocket(node_corner_index[i]);
		converter.mapInputSocket(corner_input, warp_image_operation->getInputSocket(i + 1));
		converter.mapInputSocket(corner_input, plane_mask_operation->getInputSocket(i));
	}
	converter.mapOutputSocket(output_warped_image, warp_image_operation->getOutputSocket());
	converter.mapOutputSocket(output_plane, plane_mask_operation->getOutputSocket());
}
NodeOperation *NodeOperation::getInputOperation(unsigned int inputSocketIndex)
{
	NodeOperationInput *input = getInputSocket(inputSocketIndex);
	if (input && input->isConnected())
		return &input->getLink()->getOperation();
	else
		return NULL;
}
void VectorCurveNode::convertToOperations(NodeConverter &converter, const CompositorContext &context) const
{
	VectorCurveOperation *operation = new VectorCurveOperation();
	operation->setCurveMapping((CurveMapping *)this->getbNode()->storage);
	converter.addOperation(operation);
	
	converter.mapInputSocket(getInputSocket(0), operation->getInputSocket(0));
	converter.mapOutputSocket(getOutputSocket(0), operation->getOutputSocket());
}
void TonemapNode::convertToOperations(NodeConverter &converter, const CompositorContext &/*context*/) const
{
	NodeTonemap *data = (NodeTonemap *)this->getbNode()->storage;

	TonemapOperation *operation = data->type == 1 ? new PhotoreceptorTonemapOperation() : new TonemapOperation();
	operation->setData(data);
	converter.addOperation(operation);

	converter.mapInputSocket(getInputSocket(0), operation->getInputSocket(0));
	converter.mapOutputSocket(getOutputSocket(0), operation->getOutputSocket(0));
}
void ColorCurveNode::convertToOperations(NodeConverter &converter, const CompositorContext &/*context*/) const
{
	if (this->getInputSocket(2)->isLinked() || this->getInputSocket(3)->isLinked()) {
		ColorCurveOperation *operation = new ColorCurveOperation();
		operation->setCurveMapping((CurveMapping *)this->getbNode()->storage);
		converter.addOperation(operation);

		converter.mapInputSocket(getInputSocket(0), operation->getInputSocket(0));
		converter.mapInputSocket(getInputSocket(1), operation->getInputSocket(1));
		converter.mapInputSocket(getInputSocket(2), operation->getInputSocket(2));
		converter.mapInputSocket(getInputSocket(3), operation->getInputSocket(3));

		converter.mapOutputSocket(getOutputSocket(0), operation->getOutputSocket());
	}
	else {
		ConstantLevelColorCurveOperation *operation = new ConstantLevelColorCurveOperation();
		float col[4];
		this->getInputSocket(2)->getEditorValueColor(col);
		operation->setBlackLevel(col);
		this->getInputSocket(3)->getEditorValueColor(col);
		operation->setWhiteLevel(col);
		operation->setCurveMapping((CurveMapping *)this->getbNode()->storage);
		converter.addOperation(operation);

		converter.mapInputSocket(getInputSocket(0), operation->getInputSocket(0));
		converter.mapInputSocket(getInputSocket(1), operation->getInputSocket(1));
		converter.mapOutputSocket(getOutputSocket(0), operation->getOutputSocket());
	}
}
void AlphaOverNode::convertToOperations(NodeConverter &converter, const CompositorContext &/*context*/) const
{
	NodeInput *color1Socket = this->getInputSocket(1);
	NodeInput *color2Socket = this->getInputSocket(2);
	bNode *editorNode = this->getbNode();

	MixBaseOperation *convertProg;
	NodeTwoFloats *ntf = (NodeTwoFloats *)editorNode->storage;
	if (ntf->x != 0.0f) {
		AlphaOverMixedOperation *mixOperation  = new AlphaOverMixedOperation();
		mixOperation->setX(ntf->x);
		convertProg = mixOperation;

	}
	else if (editorNode->custom1) {
		convertProg = new AlphaOverKeyOperation();
	}
	else {
		convertProg = new AlphaOverPremultiplyOperation();
	}

	convertProg->setUseValueAlphaMultiply(false);
	if (color1Socket->isLinked()) {
		convertProg->setResolutionInputSocketIndex(1);
	}
	else if (color2Socket->isLinked()) {
		convertProg->setResolutionInputSocketIndex(2);
	}
	else {
		convertProg->setResolutionInputSocketIndex(0);
	}

	converter.addOperation(convertProg);
	converter.mapInputSocket(getInputSocket(0), convertProg->getInputSocket(0));
	converter.mapInputSocket(getInputSocket(1), convertProg->getInputSocket(1));
	converter.mapInputSocket(getInputSocket(2), convertProg->getInputSocket(2));
	converter.mapOutputSocket(getOutputSocket(0), convertProg->getOutputSocket(0));
}
Exemple #13
0
void InpaintNode::convertToOperations(NodeConverter &converter,
                                      const CompositorContext & /*context*/) const
{

  bNode *editorNode = this->getbNode();

  /* if (editorNode->custom1 == CMP_NODE_INPAINT_SIMPLE) { */
  if (true) {
    InpaintSimpleOperation *operation = new InpaintSimpleOperation();
    operation->setIterations(editorNode->custom2);
    converter.addOperation(operation);

    converter.mapInputSocket(getInputSocket(0), operation->getInputSocket(0));
    converter.mapOutputSocket(getOutputSocket(0), operation->getOutputSocket(0));
  }
}
void ConvertAlphaNode::convertToOperations(NodeConverter &converter, const CompositorContext &context) const
{
	NodeOperation *operation = NULL;
	bNode *node = this->getbNode();

	/* value hardcoded in rna_nodetree.c */
	if (node->custom1 == 1) {
		operation = new ConvertPremulToStraightOperation();
	}
	else {
		operation = new ConvertStraightToPremulOperation();
	}
	
	converter.addOperation(operation);
	
	converter.mapInputSocket(getInputSocket(0), operation->getInputSocket(0));
	converter.mapOutputSocket(getOutputSocket(0), operation->getOutputSocket());
}
void BokehBlurNode::convertToOperations(NodeConverter &converter, const CompositorContext &context) const
{
	bNode *b_node = this->getbNode();

	NodeInput *inputSizeSocket = this->getInputSocket(2);

	bool connectedSizeSocket = inputSizeSocket->isLinked();
	const bool extend_bounds = (b_node->custom1 & CMP_NODEFLAG_BLUR_EXTEND_BOUNDS) != 0;

	if ((b_node->custom1 & CMP_NODEFLAG_BLUR_VARIABLE_SIZE) && connectedSizeSocket) {
		VariableSizeBokehBlurOperation *operation = new VariableSizeBokehBlurOperation();
		operation->setQuality(context.getQuality());
		operation->setThreshold(0.0f);
		operation->setMaxBlur(b_node->custom4);
		operation->setDoScaleSize(true);
		
		converter.addOperation(operation);
		converter.mapInputSocket(getInputSocket(0), operation->getInputSocket(0));
		converter.mapInputSocket(getInputSocket(1), operation->getInputSocket(1));
		converter.mapInputSocket(getInputSocket(2), operation->getInputSocket(2));
		converter.mapOutputSocket(getOutputSocket(0), operation->getOutputSocket());
	}
	else {
		BokehBlurOperation *operation = new BokehBlurOperation();
		operation->setQuality(context.getQuality());
		operation->setExtendBounds(extend_bounds);
		
		converter.addOperation(operation);
		converter.mapInputSocket(getInputSocket(0), operation->getInputSocket(0));
		converter.mapInputSocket(getInputSocket(1), operation->getInputSocket(1));

		// NOTE: on the bokeh blur operation the sockets are switched.
		// for this reason the next two lines are correct.
		// Fix for T43771
		converter.mapInputSocket(getInputSocket(2), operation->getInputSocket(3));
		converter.mapInputSocket(getInputSocket(3), operation->getInputSocket(2));

		converter.mapOutputSocket(getOutputSocket(0), operation->getOutputSocket());

		if (!connectedSizeSocket) {
			operation->setSize(this->getInputSocket(2)->getEditorValueFloat());
		}
	}
}
Exemple #16
0
void BoxMaskNode::convertToOperations(NodeConverter &converter,
                                      const CompositorContext &context) const
{
  NodeInput *inputSocket = this->getInputSocket(0);
  NodeOutput *outputSocket = this->getOutputSocket(0);

  BoxMaskOperation *operation;
  operation = new BoxMaskOperation();
  operation->setData((NodeBoxMask *)this->getbNode()->storage);
  operation->setMaskType(this->getbNode()->custom1);
  converter.addOperation(operation);

  if (inputSocket->isLinked()) {
    converter.mapInputSocket(inputSocket, operation->getInputSocket(0));
    converter.mapOutputSocket(outputSocket, operation->getOutputSocket());
  }
  else {
    /* Value operation to produce original transparent image */
    SetValueOperation *valueOperation = new SetValueOperation();
    valueOperation->setValue(0.0f);
    converter.addOperation(valueOperation);

    /* Scale that image up to render resolution */
    const RenderData *rd = context.getRenderData();
    ScaleFixedSizeOperation *scaleOperation = new ScaleFixedSizeOperation();

    scaleOperation->setIsAspect(false);
    scaleOperation->setIsCrop(false);
    scaleOperation->setOffset(0.0f, 0.0f);
    scaleOperation->setNewWidth(rd->xsch * rd->size / 100.0f);
    scaleOperation->setNewHeight(rd->ysch * rd->size / 100.0f);
    scaleOperation->getInputSocket(0)->setResizeMode(COM_SC_NO_RESIZE);
    converter.addOperation(scaleOperation);

    converter.addLink(valueOperation->getOutputSocket(0), scaleOperation->getInputSocket(0));
    converter.addLink(scaleOperation->getOutputSocket(0), operation->getInputSocket(0));
    converter.mapOutputSocket(outputSocket, operation->getOutputSocket(0));
  }

  converter.mapInputSocket(getInputSocket(1), operation->getInputSocket(1));
}
void CornerPinNode::convertToOperations(ExecutionSystem *graph, CompositorContext *context)
{
	InputSocket *input_image = this->getInputSocket(0);
	/* note: socket order differs between UI node and operations:
	 * bNode uses intuitive order following top-down layout:
	 *   upper-left, upper-right, lower-left, lower-right
	 * Operations use same order as the tracking blenkernel functions expect:
	 *   lower-left, lower-right, upper-right, upper-left
	 */
	const int node_corner_index[4] = { 3, 4, 2, 1 };

	OutputSocket *output_warped_image = this->getOutputSocket(0);
	OutputSocket *output_plane = this->getOutputSocket(1);

	PlaneCornerPinWarpImageOperation *warp_image_operation = new PlaneCornerPinWarpImageOperation();
	
	input_image->relinkConnections(warp_image_operation->getInputSocket(0), 0, graph);
	for (int i = 0; i < 4; ++i) {
		int node_index = node_corner_index[i];
		getInputSocket(node_index)->relinkConnections(warp_image_operation->getInputSocket(i + 1),
		                                              node_index, graph);
	}
	output_warped_image->relinkConnections(warp_image_operation->getOutputSocket());
	
	graph->addOperation(warp_image_operation);
	
	PlaneCornerPinMaskOperation *plane_mask_operation = new PlaneCornerPinMaskOperation();
	
	/* connect mask op inputs to the same sockets as the warp image op */
	for (int i = 0; i < 4; ++i)
		addLink(graph,
		        warp_image_operation->getInputSocket(i + 1)->getConnection()->getFromSocket(),
		        plane_mask_operation->getInputSocket(i));
	output_plane->relinkConnections(plane_mask_operation->getOutputSocket());
	
	graph->addOperation(plane_mask_operation);
}
void ZCombineNode::convertToOperations(NodeConverter &converter, const CompositorContext &context) const
{
	if ((context.getRenderData()->scemode & R_FULL_SAMPLE) || this->getbNode()->custom2) {
		ZCombineOperation *operation = NULL;
		if (this->getbNode()->custom1) {
			operation = new ZCombineAlphaOperation();
		}
		else {
			operation = new ZCombineOperation();
		}
		converter.addOperation(operation);
		
		converter.mapInputSocket(getInputSocket(0), operation->getInputSocket(0));
		converter.mapInputSocket(getInputSocket(1), operation->getInputSocket(1));
		converter.mapInputSocket(getInputSocket(2), operation->getInputSocket(2));
		converter.mapInputSocket(getInputSocket(3), operation->getInputSocket(3));
		converter.mapOutputSocket(getOutputSocket(0), operation->getOutputSocket());
		
		MathMinimumOperation *zoperation = new MathMinimumOperation();
		converter.addOperation(zoperation);
		
		converter.mapInputSocket(getInputSocket(1), zoperation->getInputSocket(0));
		converter.mapInputSocket(getInputSocket(3), zoperation->getInputSocket(1));
		converter.mapOutputSocket(getOutputSocket(1), zoperation->getOutputSocket());
	}
	else {
		/* XXX custom1 is "use_alpha", what on earth is this supposed to do here?!? */
		// not full anti alias, use masking for Z combine. be aware it uses anti aliasing.
		// step 1 create mask
		NodeOperation *maskoperation;
		if (this->getbNode()->custom1) {
			maskoperation = new MathGreaterThanOperation();
			converter.addOperation(maskoperation);
			
			converter.mapInputSocket(getInputSocket(1), maskoperation->getInputSocket(0));
			converter.mapInputSocket(getInputSocket(3), maskoperation->getInputSocket(1));
		}
		else {
			maskoperation = new MathLessThanOperation();
			converter.addOperation(maskoperation);
			
			converter.mapInputSocket(getInputSocket(1), maskoperation->getInputSocket(0));
			converter.mapInputSocket(getInputSocket(3), maskoperation->getInputSocket(1));
		}

		// step 2 anti alias mask bit of an expensive operation, but does the trick
		AntiAliasOperation *antialiasoperation = new AntiAliasOperation();
		converter.addOperation(antialiasoperation);
		
		converter.addLink(maskoperation->getOutputSocket(), antialiasoperation->getInputSocket(0));

		// use mask to blend between the input colors.
		ZCombineMaskOperation *zcombineoperation = this->getbNode()->custom1 ? new ZCombineMaskAlphaOperation() : new ZCombineMaskOperation();
		converter.addOperation(zcombineoperation);
		
		converter.addLink(antialiasoperation->getOutputSocket(), zcombineoperation->getInputSocket(0));
		converter.mapInputSocket(getInputSocket(0), zcombineoperation->getInputSocket(1));
		converter.mapInputSocket(getInputSocket(2), zcombineoperation->getInputSocket(2));
		converter.mapOutputSocket(getOutputSocket(0), zcombineoperation->getOutputSocket());

		MathMinimumOperation *zoperation = new MathMinimumOperation();
		converter.addOperation(zoperation);
		
		converter.mapInputSocket(getInputSocket(1), zoperation->getInputSocket(0));
		converter.mapInputSocket(getInputSocket(3), zoperation->getInputSocket(1));
		converter.mapOutputSocket(getOutputSocket(1), zoperation->getOutputSocket());
	}
}
void SocketProxyNode::convertToOperations(NodeConverter &converter, const CompositorContext &context) const
{
	NodeOperationOutput *proxy_output = converter.addInputProxy(getInputSocket(0), m_use_conversion);
	converter.mapOutputSocket(getOutputSocket(), proxy_output);
}
Exemple #20
0
void BlurNode::convertToOperations(NodeConverter &converter, const CompositorContext &context) const
{
	bNode *editorNode = this->getbNode();
	NodeBlurData *data = (NodeBlurData *)editorNode->storage;
	NodeInput *inputSizeSocket = this->getInputSocket(1);
	bool connectedSizeSocket = inputSizeSocket->isLinked();

	const float size = this->getInputSocket(1)->getEditorValueFloat();
	
	CompositorQuality quality = context.getQuality();
	NodeOperation *input_operation = NULL, *output_operation = NULL;

	if (data->filtertype == R_FILTER_FAST_GAUSS) {
		FastGaussianBlurOperation *operationfgb = new FastGaussianBlurOperation();
		operationfgb->setData(data);
		converter.addOperation(operationfgb);
		
		converter.mapInputSocket(getInputSocket(1), operationfgb->getInputSocket(1));
		
		input_operation = operationfgb;
		output_operation = operationfgb;
	}
	else if (editorNode->custom1 & CMP_NODEFLAG_BLUR_VARIABLE_SIZE) {
		MathAddOperation *clamp = new MathAddOperation();
		SetValueOperation *zero = new SetValueOperation();
		zero->setValue(0.0f);
		clamp->setUseClamp(true);
		
		converter.addOperation(clamp);
		converter.addOperation(zero);
		converter.mapInputSocket(getInputSocket(1), clamp->getInputSocket(0));
		converter.addLink(zero->getOutputSocket(), clamp->getInputSocket(1));
		
		GaussianAlphaXBlurOperation *operationx = new GaussianAlphaXBlurOperation();
		operationx->setData(data);
		operationx->setQuality(quality);
		operationx->setSize(1.0f);
		operationx->setFalloff(PROP_SMOOTH);
		operationx->setSubtract(false);
		
		converter.addOperation(operationx);
		converter.addLink(clamp->getOutputSocket(), operationx->getInputSocket(0));
		
		GaussianAlphaYBlurOperation *operationy = new GaussianAlphaYBlurOperation();
		operationy->setData(data);
		operationy->setQuality(quality);
		operationy->setSize(1.0f);
		operationy->setFalloff(PROP_SMOOTH);
		operationy->setSubtract(false);
		
		converter.addOperation(operationy);
		converter.addLink(operationx->getOutputSocket(), operationy->getInputSocket(0));
		
		GaussianBlurReferenceOperation *operation = new GaussianBlurReferenceOperation();
		operation->setData(data);
		operation->setQuality(quality);
		
		converter.addOperation(operation);
		converter.addLink(operationy->getOutputSocket(), operation->getInputSocket(1));
		
		output_operation = operation;
		input_operation = operation;
	}
	else if (!data->bokeh) {
		GaussianXBlurOperation *operationx = new GaussianXBlurOperation();
		operationx->setData(data);
		operationx->setQuality(quality);
		
		converter.addOperation(operationx);
		converter.mapInputSocket(getInputSocket(1), operationx->getInputSocket(1));
		
		GaussianYBlurOperation *operationy = new GaussianYBlurOperation();
		operationy->setData(data);
		operationy->setQuality(quality);

		converter.addOperation(operationy);
		converter.mapInputSocket(getInputSocket(1), operationy->getInputSocket(1));
		converter.addLink(operationx->getOutputSocket(), operationy->getInputSocket(0));

		if (!connectedSizeSocket) {
			operationx->setSize(size);
			operationy->setSize(size);
		}

		input_operation = operationx;
		output_operation = operationy;
	}
	else {
		GaussianBokehBlurOperation *operation = new GaussianBokehBlurOperation();
		operation->setData(data);
		operation->setQuality(quality);
		
		converter.addOperation(operation);
		converter.mapInputSocket(getInputSocket(1), operation->getInputSocket(1));

		if (!connectedSizeSocket) {
			operation->setSize(size);
		}

		input_operation = operation;
		output_operation = operation;
	}

	if (data->gamma) {
		GammaCorrectOperation *correct = new GammaCorrectOperation();
		GammaUncorrectOperation *inverse = new GammaUncorrectOperation();
		converter.addOperation(correct);
		converter.addOperation(inverse);
		
		converter.mapInputSocket(getInputSocket(0), correct->getInputSocket(0));
		converter.addLink(correct->getOutputSocket(), input_operation->getInputSocket(0));
		converter.addLink(output_operation->getOutputSocket(), inverse->getInputSocket(0));
		converter.mapOutputSocket(getOutputSocket(), inverse->getOutputSocket());
		
		converter.addPreview(inverse->getOutputSocket());
	}
	else {
		converter.mapInputSocket(getInputSocket(0), input_operation->getInputSocket(0));
		converter.mapOutputSocket(getOutputSocket(), output_operation->getOutputSocket());
		
		converter.addPreview(output_operation->getOutputSocket());
	}
}
void MathNode::convertToOperations(NodeConverter &converter, const CompositorContext &context) const
{
	MathBaseOperation *operation = NULL;
	
	switch (this->getbNode()->custom1) {
		case 0: /* Add */
			operation = new MathAddOperation();
			break;
		case 1: /* Subtract */
			operation = new MathSubtractOperation();
			break;
		case 2: /* Multiply */
			operation = new MathMultiplyOperation();
			break;
		case 3: /* Divide */
			operation = new MathDivideOperation();
			break;
		case 4: /* Sine */
			operation = new MathSineOperation();
			break;
		case 5: /* Cosine */
			operation = new MathCosineOperation();
			break;
		case 6: /* Tangent */
			operation = new MathTangentOperation();
			break;
		case 7: /* Arc-Sine */
			operation = new MathArcSineOperation();
			break;
		case 8: /* Arc-Cosine */
			operation = new MathArcCosineOperation();
			break;
		case 9: /* Arc-Tangent */
			operation = new MathArcTangentOperation();
			break;
		case 10: /* Power */
			operation = new MathPowerOperation();
			break;
		case 11: /* Logarithm */
			operation = new MathLogarithmOperation();
			break;
		case 12: /* Minimum */
			operation = new MathMinimumOperation();
			break;
		case 13: /* Maximum */
			operation = new MathMaximumOperation();
			break;
		case 14: /* Round */
			operation = new MathRoundOperation();
			break;
		case 15: /* Less Than */
			operation = new MathLessThanOperation();
			break;
		case 16: /* Greater Than */
			operation = new MathGreaterThanOperation();
			break;
		case 17: /* Modulo */
			operation = new MathModuloOperation();
			break;
		case 18: /* Absolute Value */
			operation = new MathAbsoluteOperation();
			break;
	}
	
	if (operation) {
		bool useClamp = getbNode()->custom2;
		operation->setUseClamp(useClamp);
		converter.addOperation(operation);
		
		converter.mapInputSocket(getInputSocket(0), operation->getInputSocket(0));
		converter.mapInputSocket(getInputSocket(1), operation->getInputSocket(1));
		converter.mapOutputSocket(getOutputSocket(0), operation->getOutputSocket());
	}
}
void DilateErodeNode::convertToOperations(NodeConverter &converter,
                                          const CompositorContext &context) const
{

  bNode *editorNode = this->getbNode();
  if (editorNode->custom1 == CMP_NODE_DILATEERODE_DISTANCE_THRESH) {
    DilateErodeThresholdOperation *operation = new DilateErodeThresholdOperation();
    operation->setDistance(editorNode->custom2);
    operation->setInset(editorNode->custom3);
    converter.addOperation(operation);

    converter.mapInputSocket(getInputSocket(0), operation->getInputSocket(0));

    if (editorNode->custom3 < 2.0f) {
      AntiAliasOperation *antiAlias = new AntiAliasOperation();
      converter.addOperation(antiAlias);

      converter.addLink(operation->getOutputSocket(), antiAlias->getInputSocket(0));
      converter.mapOutputSocket(getOutputSocket(0), antiAlias->getOutputSocket(0));
    }
    else {
      converter.mapOutputSocket(getOutputSocket(0), operation->getOutputSocket(0));
    }
  }
  else if (editorNode->custom1 == CMP_NODE_DILATEERODE_DISTANCE) {
    if (editorNode->custom2 > 0) {
      DilateDistanceOperation *operation = new DilateDistanceOperation();
      operation->setDistance(editorNode->custom2);
      converter.addOperation(operation);

      converter.mapInputSocket(getInputSocket(0), operation->getInputSocket(0));
      converter.mapOutputSocket(getOutputSocket(0), operation->getOutputSocket(0));
    }
    else {
      ErodeDistanceOperation *operation = new ErodeDistanceOperation();
      operation->setDistance(-editorNode->custom2);
      converter.addOperation(operation);

      converter.mapInputSocket(getInputSocket(0), operation->getInputSocket(0));
      converter.mapOutputSocket(getOutputSocket(0), operation->getOutputSocket(0));
    }
  }
  else if (editorNode->custom1 == CMP_NODE_DILATEERODE_DISTANCE_FEATHER) {
    /* this uses a modified gaussian blur function otherwise its far too slow */
    CompositorQuality quality = context.getQuality();

    GaussianAlphaXBlurOperation *operationx = new GaussianAlphaXBlurOperation();
    operationx->setData(&m_alpha_blur);
    operationx->setQuality(quality);
    operationx->setFalloff(PROP_SMOOTH);
    converter.addOperation(operationx);

    converter.mapInputSocket(getInputSocket(0), operationx->getInputSocket(0));
    // converter.mapInputSocket(getInputSocket(1), operationx->getInputSocket(1)); // no size input
    // yet

    GaussianAlphaYBlurOperation *operationy = new GaussianAlphaYBlurOperation();
    operationy->setData(&m_alpha_blur);
    operationy->setQuality(quality);
    operationy->setFalloff(PROP_SMOOTH);
    converter.addOperation(operationy);

    converter.addLink(operationx->getOutputSocket(), operationy->getInputSocket(0));
    // converter.mapInputSocket(getInputSocket(1), operationy->getInputSocket(1)); // no size input
    // yet
    converter.mapOutputSocket(getOutputSocket(0), operationy->getOutputSocket());

    converter.addPreview(operationy->getOutputSocket());

    /* TODO? */
    /* see gaussian blue node for original usage */
#if 0
    if (!connectedSizeSocket) {
      operationx->setSize(size);
      operationy->setSize(size);
    }
#else
    operationx->setSize(1.0f);
    operationy->setSize(1.0f);
#endif
    operationx->setSubtract(editorNode->custom2 < 0);
    operationy->setSubtract(editorNode->custom2 < 0);

    if (editorNode->storage) {
      NodeDilateErode *data_storage = (NodeDilateErode *)editorNode->storage;
      operationx->setFalloff(data_storage->falloff);
      operationy->setFalloff(data_storage->falloff);
    }
  }
  else {
    if (editorNode->custom2 > 0) {
      DilateStepOperation *operation = new DilateStepOperation();
      operation->setIterations(editorNode->custom2);
      converter.addOperation(operation);

      converter.mapInputSocket(getInputSocket(0), operation->getInputSocket(0));
      converter.mapOutputSocket(getOutputSocket(0), operation->getOutputSocket(0));
    }
    else {
      ErodeStepOperation *operation = new ErodeStepOperation();
      operation->setIterations(-editorNode->custom2);
      converter.addOperation(operation);

      converter.mapInputSocket(getInputSocket(0), operation->getInputSocket(0));
      converter.mapOutputSocket(getOutputSocket(0), operation->getOutputSocket(0));
    }
  }
}
void OutputFileNode::convertToOperations(NodeConverter &converter, const CompositorContext &context) const
{
	NodeImageMultiFile *storage = (NodeImageMultiFile *)this->getbNode()->storage;
	
	if (!context.isRendering()) {
		/* only output files when rendering a sequence -
		 * otherwise, it overwrites the output files just
		 * scrubbing through the timeline when the compositor updates.
		 */
		return;
	}
	
	if (storage->format.imtype == R_IMF_IMTYPE_MULTILAYER) {
		/* single output operation for the multilayer file */
		OutputOpenExrMultiLayerOperation *outputOperation = new OutputOpenExrMultiLayerOperation(
		        context.getRenderData(), context.getbNodeTree(), storage->base_path, storage->format.exr_codec);
		converter.addOperation(outputOperation);
		
		int num_inputs = getNumberOfInputSockets();
		bool previewAdded = false;
		for (int i = 0; i < num_inputs; ++i) {
			NodeInput *input = getInputSocket(i);
			NodeImageMultiFileSocket *sockdata = (NodeImageMultiFileSocket *)input->getbNodeSocket()->storage;
			
			/* note: layer becomes an empty placeholder if the input is not linked */
			outputOperation->add_layer(sockdata->layer, input->getDataType(), input->isLinked());
			
			converter.mapInputSocket(input, outputOperation->getInputSocket(i));
			
			if (!previewAdded) {
				converter.addNodeInputPreview(input);
				previewAdded = true;
			}
		}
	}
	else {  /* single layer format */
		int num_inputs = getNumberOfInputSockets();
		bool previewAdded = false;
		for (int i = 0; i < num_inputs; ++i) {
			NodeInput *input = getInputSocket(i);
			if (input->isLinked()) {
				NodeImageMultiFileSocket *sockdata = (NodeImageMultiFileSocket *)input->getbNodeSocket()->storage;
				ImageFormatData *format = (sockdata->use_node_format ? &storage->format : &sockdata->format);
				char path[FILE_MAX];
				
				/* combine file path for the input */
				BLI_join_dirfile(path, FILE_MAX, storage->base_path, sockdata->path);
				
				OutputSingleLayerOperation *outputOperation = new OutputSingleLayerOperation(
				        context.getRenderData(), context.getbNodeTree(), input->getDataType(), format, path,
				        context.getViewSettings(), context.getDisplaySettings());
				converter.addOperation(outputOperation);
				
				converter.mapInputSocket(input, outputOperation->getInputSocket(0));
				
				if (!previewAdded) {
					converter.addNodeInputPreview(input);
					previewAdded = true;
				}
			}
		}
	}
}