void TimeNode::convertToOperations(NodeConverter &converter, const CompositorContext &context) const
{
	SetValueOperation *operation = new SetValueOperation();
	bNode *node = this->getbNode();

	/* stack order output: fac */
	float fac = 0.0f;
	const int framenumber = context.getFramenumber();

	if (framenumber < node->custom1) {
		fac = 0.0f;
	}
	else if (framenumber > node->custom2) {
		fac = 1.0f;
	}
	else if (node->custom1 < node->custom2) {
		fac = (context.getFramenumber() - node->custom1) / (float)(node->custom2 - node->custom1);
	}

	curvemapping_initialize((CurveMapping *)node->storage);
	fac = curvemapping_evaluateF((CurveMapping *)node->storage, 0, fac);
	operation->setValue(clamp_f(fac, 0.0f, 1.0f));
	converter.addOperation(operation);

	converter.mapOutputSocket(getOutputSocket(0), operation->getOutputSocket());
}
Example #2
0
void TimeNode::convertToOperations(ExecutionSystem *graph, CompositorContext *context)
{
	SetValueOperation *operation = new SetValueOperation();
	this->getOutputSocket(0)->relinkConnections(operation->getOutputSocket());
	bNode *node = this->getbNode();

	/* stack order output: fac */
	float fac = 0.0f;
	const int framenumber = context->getFramenumber();

	if (framenumber < node->custom1) {
		fac = 0.0f;
	}
	else if (framenumber > node->custom2) {
		fac = 1.0f;
	}
	else if (node->custom1 < node->custom2) {
		fac = (context->getFramenumber() - node->custom1) / (float)(node->custom2 - node->custom1);
	}

	curvemapping_initialize((CurveMapping *)node->storage);
	fac = curvemapping_evaluateF((CurveMapping *)node->storage, 0, fac);
	operation->setValue(CLAMPIS(fac, 0.0f, 1.0f));
	graph->addOperation(operation);
}
void MuteNode::reconnect(ExecutionSystem *graph, OutputSocket *output)
{
	vector<InputSocket *> &inputsockets = this->getInputSockets();
	for (unsigned int index = 0; index < inputsockets.size(); index++) {
		InputSocket *input = inputsockets[index];
		if (input->getDataType() == output->getDataType()) {
			if (input->isConnected()) {
				output->relinkConnections(input->getConnection()->getFromSocket(), false);
				return;
			}
		}
	}
	
	NodeOperation *operation = NULL;
	switch (output->getDataType()) {
		case COM_DT_VALUE:
		{
			SetValueOperation *valueoperation = new SetValueOperation();
			valueoperation->setValue(0.0f);
			operation = valueoperation;
			break;
		}
		case COM_DT_VECTOR:
		{
			SetVectorOperation *vectoroperation = new SetVectorOperation();
			vectoroperation->setX(0.0f);
			vectoroperation->setY(0.0f);
			vectoroperation->setW(0.0f);
			operation = vectoroperation;
			break;
		}
		case COM_DT_COLOR:
		{
			SetColorOperation *coloroperation = new SetColorOperation();
			coloroperation->setChannel1(0.0f);
			coloroperation->setChannel2(0.0f);
			coloroperation->setChannel3(0.0f);
			coloroperation->setChannel4(0.0f);
			operation = coloroperation;
			break;
		}
	}

	if (operation) {
		output->relinkConnections(operation->getOutputSocket(), false);
		graph->addOperation(operation);
	}

	output->clearConnections();
}
Example #4
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());
}
Example #5
0
void EllipseMaskNode::convertToOperations(ExecutionSystem *graph, CompositorContext *context)
{
    EllipseMaskOperation *operation;

    operation = new EllipseMaskOperation();
    operation->setData((NodeEllipseMask *)this->getbNode()->storage);

    InputSocket *inputSocket = this->getInputSocket(0);
    OutputSocket *outputSocket = this->getOutputSocket(0);

    if (inputSocket->isConnected()) {
        inputSocket->relinkConnections(operation->getInputSocket(0), 0, graph);
        outputSocket->relinkConnections(operation->getOutputSocket());
    }
    else {
        /* Value operation to produce original transparent image */
        SetValueOperation *valueOperation = new SetValueOperation();
        valueOperation->setValue(0.0f);
        graph->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);

        addLink(graph, valueOperation->getOutputSocket(0), scaleOperation->getInputSocket(0));
        addLink(graph, scaleOperation->getOutputSocket(0), operation->getInputSocket(0));
        outputSocket->relinkConnections(operation->getOutputSocket(0));

        scaleOperation->getInputSocket(0)->getConnection()->setIgnoreResizeCheck(true);

        graph->addOperation(scaleOperation);
    }

    this->getInputSocket(1)->relinkConnections(operation->getInputSocket(1), 1, graph);
    operation->setMaskType(this->getbNode()->custom1);

    graph->addOperation(operation);
}
void SocketProxyNode::convertToOperations(ExecutionSystem *graph, CompositorContext *context)
{
	OutputSocket *outputsocket = this->getOutputSocket(0);
	InputSocket *inputsocket = this->getInputSocket(0);
	if (outputsocket->isConnected()) {
		if (inputsocket->isConnected()) {
			SocketProxyOperation *operation = new SocketProxyOperation(this->getOutputSocket()->getDataType());
			inputsocket->relinkConnections(operation->getInputSocket(0));
			outputsocket->relinkConnections(operation->getOutputSocket(0));
			graph->addOperation(operation);
		}
		else {
			/* If input is not connected, add a constant value operation instead */
			switch (outputsocket->getDataType()) {
				case COM_DT_VALUE:
				{
					SetValueOperation *operation = new SetValueOperation();
					bNodeSocketValueFloat *dval = (bNodeSocketValueFloat *)inputsocket->getbNodeSocket()->default_value;
					operation->setValue(dval->value);
					outputsocket->relinkConnections(operation->getOutputSocket(0));
					graph->addOperation(operation);
					break;
				}
				case COM_DT_COLOR:
				{
					SetColorOperation *operation = new SetColorOperation();
					bNodeSocketValueRGBA *dval = (bNodeSocketValueRGBA *)inputsocket->getbNodeSocket()->default_value;
					operation->setChannels(dval->value);
					outputsocket->relinkConnections(operation->getOutputSocket(0));
					graph->addOperation(operation);
					break;
				}
				case COM_DT_VECTOR:
				{
					SetVectorOperation *operation = new SetVectorOperation();
					bNodeSocketValueVector *dval = (bNodeSocketValueVector *)inputsocket->getbNodeSocket()->default_value;
					operation->setVector(dval->value);
					outputsocket->relinkConnections(operation->getOutputSocket(0));
					graph->addOperation(operation);
					break;
				}
			}
		}
	}
}
void NodeOperationBuilder::add_input_constant_value(NodeOperationInput *input, NodeInput *node_input)
{
	switch (input->getDataType()) {
		case COM_DT_VALUE: {
			float value;
			if (node_input && node_input->getbNodeSocket())
				value = node_input->getEditorValueFloat();
			else
				value = 0.0f;
			
			SetValueOperation *op = new SetValueOperation();
			op->setValue(value);
			addOperation(op);
			addLink(op->getOutputSocket(), input);
			break;
		}
		case COM_DT_COLOR: {
			float value[4];
			if (node_input && node_input->getbNodeSocket())
				node_input->getEditorValueColor(value);
			else
				zero_v4(value);
			
			SetColorOperation *op = new SetColorOperation();
			op->setChannels(value);
			addOperation(op);
			addLink(op->getOutputSocket(), input);
			break;
		}
		case COM_DT_VECTOR: {
			float value[3];
			if (node_input && node_input->getbNodeSocket())
				node_input->getEditorValueVector(value);
			else
				zero_v3(value);
			
			SetVectorOperation *op = new SetVectorOperation();
			op->setVector(value);
			addOperation(op);
			addLink(op->getOutputSocket(), input);
			break;
		}
	}
}
Example #8
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 ImageNode::convertToOperations(ExecutionSystem *graph, CompositorContext *context)
{
	/// Image output
	OutputSocket *outputImage = this->getOutputSocket(0);
	bNode *editorNode = this->getbNode();
	Image *image = (Image *)editorNode->id;
	ImageUser *imageuser = (ImageUser *)editorNode->storage;
	int framenumber = context->getFramenumber();
	int numberOfOutputs = this->getNumberOfOutputSockets();
	BKE_image_user_frame_calc(imageuser, context->getFramenumber(), 0);

	/* force a load, we assume iuser index will be set OK anyway */
	if (image && image->type == IMA_TYPE_MULTILAYER) {
		bool is_multilayer_ok = false;
		ImBuf *ibuf = BKE_image_acquire_ibuf(image, imageuser, NULL);
		if (image->rr) {
			RenderLayer *rl = (RenderLayer *)BLI_findlink(&image->rr->layers, imageuser->layer);
			if (rl) {
				OutputSocket *socket;
				int index;

				is_multilayer_ok = true;

				for (index = 0; index < numberOfOutputs; index++) {
					NodeOperation *operation = NULL;
					socket = this->getOutputSocket(index);
					if (socket->isConnected() || index == 0) {
						bNodeSocket *bnodeSocket = socket->getbNodeSocket();
						NodeImageLayer *storage = (NodeImageLayer *)bnodeSocket->storage;
						int passindex = storage->pass_index;
						
						RenderPass *rpass = (RenderPass *)BLI_findlink(&rl->passes, passindex);
						if (rpass) {
							imageuser->pass = passindex;
							switch (rpass->channels) {
								case 1:
									operation = doMultilayerCheck(graph, rl, image, imageuser, framenumber, index, passindex, COM_DT_VALUE);
									break;
								/* using image operations for both 3 and 4 channels (RGB and RGBA respectively) */
								/* XXX any way to detect actual vector images? */
								case 3:
									operation = doMultilayerCheck(graph, rl, image, imageuser, framenumber, index, passindex, COM_DT_VECTOR);
									break;
								case 4:
									operation = doMultilayerCheck(graph, rl, image, imageuser, framenumber, index, passindex, COM_DT_COLOR);
									break;
								default:
									/* dummy operation is added below */
									break;
							}

							if (index == 0 && operation) {
								addPreviewOperation(graph, context, operation->getOutputSocket());
							}
						}
					}

					/* incase we can't load the layer */
					if (operation == NULL) {
						convertToOperations_invalid_index(graph, index);
					}
				}
			}
		}
		BKE_image_release_ibuf(image, ibuf, NULL);

		/* without this, multilayer that fail to load will crash blender [#32490] */
		if (is_multilayer_ok == false) {
			convertToOperations_invalid(graph, context);
		}
	}
	else {
		if (numberOfOutputs >  0) {
			ImageOperation *operation = new ImageOperation();
			if (outputImage->isConnected()) {
				outputImage->relinkConnections(operation->getOutputSocket());
			}
			operation->setImage(image);
			operation->setImageUser(imageuser);
			operation->setFramenumber(framenumber);
			graph->addOperation(operation);
			addPreviewOperation(graph, context, operation->getOutputSocket());
		}
		
		if (numberOfOutputs > 1) {
			OutputSocket *alphaImage = this->getOutputSocket(1);
			if (alphaImage->isConnected()) {
				ImageAlphaOperation *alphaOperation = new ImageAlphaOperation();
				alphaOperation->setImage(image);
				alphaOperation->setImageUser(imageuser);
				alphaOperation->setFramenumber(framenumber);
				alphaImage->relinkConnections(alphaOperation->getOutputSocket());
				graph->addOperation(alphaOperation);
			}
		}
		if (numberOfOutputs > 2) {
			OutputSocket *depthImage = this->getOutputSocket(2);
			if (depthImage->isConnected()) {
				ImageDepthOperation *depthOperation = new ImageDepthOperation();
				depthOperation->setImage(image);
				depthOperation->setImageUser(imageuser);
				depthOperation->setFramenumber(framenumber);
				depthImage->relinkConnections(depthOperation->getOutputSocket());
				graph->addOperation(depthOperation);
			}
		}
		if (numberOfOutputs > 3) {
			/* happens when unlinking image datablock from multilayer node */
			for (int i = 3; i < numberOfOutputs; i++) {
				OutputSocket *output = this->getOutputSocket(i);
				NodeOperation *operation = NULL;
				switch (output->getDataType()) {
					case COM_DT_VALUE:
					{
						SetValueOperation *valueoperation = new SetValueOperation();
						valueoperation->setValue(0.0f);
						operation = valueoperation;
						break;
					}
					case COM_DT_VECTOR:
					{
						SetVectorOperation *vectoroperation = new SetVectorOperation();
						vectoroperation->setX(0.0f);
						vectoroperation->setY(0.0f);
						vectoroperation->setW(0.0f);
						operation = vectoroperation;
						break;
					}
					case COM_DT_COLOR:
					{
						SetColorOperation *coloroperation = new SetColorOperation();
						coloroperation->setChannel1(0.0f);
						coloroperation->setChannel2(0.0f);
						coloroperation->setChannel3(0.0f);
						coloroperation->setChannel4(0.0f);
						operation = coloroperation;
						break;
					}
				}

				if (operation) {
					output->relinkConnections(operation->getOutputSocket());
					graph->addOperation(operation);
				}
			}
		}
	}
}
Example #10
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());
	}
}
Example #11
0
void Converter::convertResolution(NodeOperationBuilder &builder, NodeOperationOutput *fromSocket, NodeOperationInput *toSocket)
{
	InputResizeMode mode = toSocket->getResizeMode();

	NodeOperation *toOperation = &toSocket->getOperation();
	const float toWidth = toOperation->getWidth();
	const float toHeight = toOperation->getHeight();
	NodeOperation *fromOperation = &fromSocket->getOperation();
	const float fromWidth = fromOperation->getWidth();
	const float fromHeight = fromOperation->getHeight();
	bool doCenter = false;
	bool doScale = false;
	float addX = (toWidth - fromWidth) / 2.0f;
	float addY = (toHeight - fromHeight) / 2.0f;
	float scaleX = 0;
	float scaleY = 0;

	switch (mode) {
		case COM_SC_NO_RESIZE:
			break;
		case COM_SC_CENTER:
			doCenter = true;
			break;
		case COM_SC_FIT_WIDTH:
			doCenter = true;
			doScale = true;
			scaleX = scaleY = toWidth / fromWidth;
			break;
		case COM_SC_FIT_HEIGHT:
			doCenter = true;
			doScale = true;
			scaleX = scaleY = toHeight / fromHeight;
			break;
		case COM_SC_FIT:
			doCenter = true;
			doScale = true;
			scaleX = toWidth / fromWidth;
			scaleY = toHeight / fromHeight;
			if (scaleX < scaleY) {
				scaleX = scaleY;
			}
			else {
				scaleY = scaleX;
			}
			break;
		case COM_SC_STRETCH:
			doCenter = true;
			doScale = true;
			scaleX = toWidth / fromWidth;
			scaleY = toHeight / fromHeight;
			break;

	}

	if (doCenter) {
		NodeOperation *first = NULL;
		ScaleOperation *scaleOperation = NULL;
		if (doScale) {
			scaleOperation = new ScaleOperation();
			scaleOperation->getInputSocket(1)->setResizeMode(COM_SC_NO_RESIZE);
			scaleOperation->getInputSocket(2)->setResizeMode(COM_SC_NO_RESIZE);
			first = scaleOperation;
			SetValueOperation *sxop = new SetValueOperation();
			sxop->setValue(scaleX);
			builder.addLink(sxop->getOutputSocket(), scaleOperation->getInputSocket(1));
			SetValueOperation *syop = new SetValueOperation();
			syop->setValue(scaleY);
			builder.addLink(syop->getOutputSocket(), scaleOperation->getInputSocket(2));
			builder.addOperation(sxop);
			builder.addOperation(syop);

			unsigned int resolution[2] = {fromOperation->getWidth(),
			                              fromOperation->getHeight()};
			scaleOperation->setResolution(resolution);
			sxop->setResolution(resolution);
			syop->setResolution(resolution);
			builder.addOperation(scaleOperation);
		}

		TranslateOperation *translateOperation = new TranslateOperation();
		translateOperation->getInputSocket(1)->setResizeMode(COM_SC_NO_RESIZE);
		translateOperation->getInputSocket(2)->setResizeMode(COM_SC_NO_RESIZE);
		if (!first) first = translateOperation;
		SetValueOperation *xop = new SetValueOperation();
		xop->setValue(addX);
		builder.addLink(xop->getOutputSocket(), translateOperation->getInputSocket(1));
		SetValueOperation *yop = new SetValueOperation();
		yop->setValue(addY);
		builder.addLink(yop->getOutputSocket(), translateOperation->getInputSocket(2));
		builder.addOperation(xop);
		builder.addOperation(yop);

		unsigned int resolution[2] = {toOperation->getWidth(),
		                              toOperation->getHeight()};
		translateOperation->setResolution(resolution);
		xop->setResolution(resolution);
		yop->setResolution(resolution);
		builder.addOperation(translateOperation);

		if (doScale) {
			translateOperation->getInputSocket(0)->setResizeMode(COM_SC_NO_RESIZE);
			builder.addLink(scaleOperation->getOutputSocket(), translateOperation->getInputSocket(0));
		}

		/* remove previous link and replace */
		builder.removeInputLink(toSocket);
		first->getInputSocket(0)->setResizeMode(COM_SC_NO_RESIZE);
		toSocket->setResizeMode(COM_SC_NO_RESIZE);
		builder.addLink(fromSocket, first->getInputSocket(0));
		builder.addLink(translateOperation->getOutputSocket(), toSocket);
	}
}
void MovieClipNode::convertToOperations(ExecutionSystem *graph, CompositorContext *context)
{
	OutputSocket *outputMovieClip = this->getOutputSocket(0);
	OutputSocket *alphaMovieClip = this->getOutputSocket(1);
	OutputSocket *offsetXMovieClip = this->getOutputSocket(2);
	OutputSocket *offsetYMovieClip = this->getOutputSocket(3);
	OutputSocket *scaleMovieClip = this->getOutputSocket(4);
	OutputSocket *angleMovieClip = this->getOutputSocket(5);
	
	bNode *editorNode = this->getbNode();
	MovieClip *movieClip = (MovieClip *)editorNode->id;
	MovieClipUser *movieClipUser = (MovieClipUser *)editorNode->storage;
	bool cacheFrame = !context->isRendering();

	ImBuf *ibuf = NULL;
	if (movieClip) {
		if (cacheFrame)
			ibuf = BKE_movieclip_get_ibuf(movieClip, movieClipUser);
		else
			ibuf = BKE_movieclip_get_ibuf_flag(movieClip, movieClipUser, movieClip->flag, MOVIECLIP_CACHE_SKIP);
	}
	
	// always connect the output image
	MovieClipOperation *operation = new MovieClipOperation();
	
	addPreviewOperation(graph, context, operation->getOutputSocket());
	if (outputMovieClip->isConnected()) {
		outputMovieClip->relinkConnections(operation->getOutputSocket());
	}

	operation->setMovieClip(movieClip);
	operation->setMovieClipUser(movieClipUser);
	operation->setFramenumber(context->getFramenumber());
	operation->setCacheFrame(cacheFrame);
	graph->addOperation(operation);

	if (alphaMovieClip->isConnected()) {
		MovieClipAlphaOperation *alphaOperation = new MovieClipAlphaOperation();
		alphaOperation->setMovieClip(movieClip);
		alphaOperation->setMovieClipUser(movieClipUser);
		alphaOperation->setFramenumber(context->getFramenumber());
		alphaOperation->setCacheFrame(cacheFrame);
		alphaMovieClip->relinkConnections(alphaOperation->getOutputSocket());
		graph->addOperation(alphaOperation);
	}

	MovieTrackingStabilization *stab = &movieClip->tracking.stabilization;
	float loc[2], scale, angle;
	loc[0] = 0.0f;
	loc[1] = 0.0f;
	scale = 1.0f;
	angle = 0.0f;

	if (ibuf) {
		if (stab->flag & TRACKING_2D_STABILIZATION) {
			int clip_framenr = BKE_movieclip_remap_scene_to_clip_frame(movieClip, context->getFramenumber());

			BKE_tracking_stabilization_data_get(&movieClip->tracking, clip_framenr, ibuf->x, ibuf->y, loc, &scale, &angle);
		}
	}

	if (offsetXMovieClip->isConnected()) {
		SetValueOperation *operationSetValue = new SetValueOperation();
		operationSetValue->setValue(loc[0]);
		offsetXMovieClip->relinkConnections(operationSetValue->getOutputSocket());
		graph->addOperation(operationSetValue);
	}
	if (offsetYMovieClip->isConnected()) {
		SetValueOperation *operationSetValue = new SetValueOperation();
		operationSetValue->setValue(loc[1]);
		offsetYMovieClip->relinkConnections(operationSetValue->getOutputSocket());
		graph->addOperation(operationSetValue);
	}
	if (scaleMovieClip->isConnected()) {
		SetValueOperation *operationSetValue = new SetValueOperation();
		operationSetValue->setValue(scale);
		scaleMovieClip->relinkConnections(operationSetValue->getOutputSocket());
		graph->addOperation(operationSetValue);
	}
	if (angleMovieClip->isConnected()) {
		SetValueOperation *operationSetValue = new SetValueOperation();
		operationSetValue->setValue(angle);
		angleMovieClip->relinkConnections(operationSetValue->getOutputSocket());
		graph->addOperation(operationSetValue);
	}

	if (ibuf) {
		IMB_freeImBuf(ibuf);
	}
}
Example #13
0
void KeyingNode::convertToOperations(ExecutionSystem *graph, CompositorContext *context)
{
	InputSocket *inputImage = this->getInputSocket(0);
	InputSocket *inputScreen = this->getInputSocket(1);
	InputSocket *inputGarbageMatte = this->getInputSocket(2);
	InputSocket *inputCoreMatte = this->getInputSocket(3);
	OutputSocket *outputImage = this->getOutputSocket(0);
	OutputSocket *outputMatte = this->getOutputSocket(1);
	OutputSocket *outputEdges = this->getOutputSocket(2);
	OutputSocket *postprocessedMatte = NULL, *postprocessedImage = NULL, *originalImage = NULL, *edgesMatte = NULL;

	bNode *editorNode = this->getbNode();
	NodeKeyingData *keying_data = (NodeKeyingData *) editorNode->storage;

	/* keying operation */
	KeyingOperation *keyingOperation = new KeyingOperation();

	keyingOperation->setScreenBalance(keying_data->screen_balance);

	inputScreen->relinkConnections(keyingOperation->getInputSocket(1), 1, graph);

	if (keying_data->blur_pre) {
		/* chroma preblur operation for input of keying operation  */
		OutputSocket *preBluredImage = setupPreBlur(graph, inputImage, keying_data->blur_pre, &originalImage);
		addLink(graph, preBluredImage, keyingOperation->getInputSocket(0));
	}
	else {
		inputImage->relinkConnections(keyingOperation->getInputSocket(0), 0, graph);
		originalImage = keyingOperation->getInputSocket(0)->getConnection()->getFromSocket();
	}

	graph->addOperation(keyingOperation);

	postprocessedMatte = keyingOperation->getOutputSocket();

	/* black / white clipping */
	if (keying_data->clip_black > 0.0f || keying_data->clip_white < 1.0f) {
		postprocessedMatte = setupClip(graph, postprocessedMatte,
		                               keying_data->edge_kernel_radius, keying_data->edge_kernel_tolerance,
		                               keying_data->clip_black, keying_data->clip_white, false);
	}

	/* output edge matte */
	if (outputEdges->isConnected()) {
		edgesMatte = setupClip(graph, postprocessedMatte,
		                       keying_data->edge_kernel_radius, keying_data->edge_kernel_tolerance,
		                       keying_data->clip_black, keying_data->clip_white, true);
	}

	/* apply garbage matte */
	if (inputGarbageMatte->isConnected()) {
		SetValueOperation *valueOperation = new SetValueOperation();
		MathSubtractOperation *subtractOperation = new MathSubtractOperation();
		MathMinimumOperation *minOperation = new MathMinimumOperation();

		valueOperation->setValue(1.0f);

		addLink(graph, valueOperation->getOutputSocket(), subtractOperation->getInputSocket(0));
		inputGarbageMatte->relinkConnections(subtractOperation->getInputSocket(1), 0, graph);

		addLink(graph, subtractOperation->getOutputSocket(), minOperation->getInputSocket(0));
		addLink(graph, postprocessedMatte, minOperation->getInputSocket(1));

		postprocessedMatte = minOperation->getOutputSocket();

		graph->addOperation(valueOperation);
		graph->addOperation(subtractOperation);
		graph->addOperation(minOperation);
	}

	/* apply core matte */
	if (inputCoreMatte->isConnected()) {
		MathMaximumOperation *maxOperation = new MathMaximumOperation();

		inputCoreMatte->relinkConnections(maxOperation->getInputSocket(0), 0, graph);

		addLink(graph, postprocessedMatte, maxOperation->getInputSocket(1));

		postprocessedMatte = maxOperation->getOutputSocket();

		graph->addOperation(maxOperation);
	}

	/* apply blur on matte if needed */
	if (keying_data->blur_post)
		postprocessedMatte = setupPostBlur(graph, postprocessedMatte, keying_data->blur_post);

	/* matte dilate/erode */
	if (keying_data->dilate_distance != 0) {
		postprocessedMatte = setupDilateErode(graph, postprocessedMatte, keying_data->dilate_distance);
	}

	/* matte feather */
	if (keying_data->feather_distance != 0) {
		postprocessedMatte = setupFeather(graph, context, postprocessedMatte, keying_data->feather_falloff,
		                                  keying_data->feather_distance);
	}

	/* set alpha channel to output image */
	SetAlphaOperation *alphaOperation = new SetAlphaOperation();
	addLink(graph, originalImage, alphaOperation->getInputSocket(0));
	addLink(graph, postprocessedMatte, alphaOperation->getInputSocket(1));

	postprocessedImage = alphaOperation->getOutputSocket();

	/* despill output image */
	if (keying_data->despill_factor > 0.0f) {
		postprocessedImage = setupDespill(graph, postprocessedImage,
		                                  keyingOperation->getInputSocket(1)->getConnection()->getFromSocket(),
		                                  keying_data->despill_factor,
		                                  keying_data->despill_balance);
	}

	/* connect result to output sockets */
	outputImage->relinkConnections(postprocessedImage);
	outputMatte->relinkConnections(postprocessedMatte);

	if (edgesMatte)
		outputEdges->relinkConnections(edgesMatte);

	graph->addOperation(alphaOperation);
}