Exemplo n.º 1
0
void ColorBalanceNode::convertToOperations(ExecutionSystem *graph, CompositorContext *context)
{
	InputSocket *inputSocket = this->getInputSocket(0);
	InputSocket *inputImageSocket = this->getInputSocket(1);
	OutputSocket *outputSocket = this->getOutputSocket(0);
	
	bNode *node = this->getbNode();
	NodeColorBalance *n = (NodeColorBalance *)node->storage;
	NodeOperation *operation;
	if (node->custom1 == 0) {
		ColorBalanceLGGOperation *operationLGG = new ColorBalanceLGGOperation();
		{
			int c;
	
			for (c = 0; c < 3; c++) {
				n->lift_lgg[c] = 2.0f - n->lift[c];
				n->gamma_inv[c] = (n->gamma[c] != 0.0f) ? 1.0f / n->gamma[c] : 1000000.0f;
			}
		}
	
		operationLGG->setGain(n->gain);
		operationLGG->setLift(n->lift_lgg);
		operationLGG->setGammaInv(n->gamma_inv);
		operation = operationLGG;
	}
	else {
		ColorBalanceASCCDLOperation *operationCDL = new ColorBalanceASCCDLOperation();
		operationCDL->setGain(n->gain);
		operationCDL->setLift(n->lift);
		operationCDL->setGamma(n->gamma);
		operation = operationCDL;
	}
	
	inputSocket->relinkConnections(operation->getInputSocket(0), 0, graph);
	inputImageSocket->relinkConnections(operation->getInputSocket(1), 1, graph);
	outputSocket->relinkConnections(operation->getOutputSocket(0));
	graph->addOperation(operation);
}
Exemplo n.º 2
0
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);
				}
			}
		}
	}
}
Exemplo n.º 3
0
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);
	}
}
Exemplo n.º 4
0
void MixNode::convertToOperations(ExecutionSystem *graph, CompositorContext *context)
{
	InputSocket *valueSocket = this->getInputSocket(0);
	InputSocket *color1Socket = this->getInputSocket(1);
	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;
	
	switch (editorNode->custom1) {
		case MA_RAMP_ADD:
			convertProg = new MixAddOperation();
			break;
		case MA_RAMP_MULT:
			convertProg = new MixMultiplyOperation();
			break;
		case MA_RAMP_LIGHT:
			convertProg = new MixLightenOperation();
			break;
		case MA_RAMP_BURN:
			convertProg = new MixBurnOperation();
			break;
		case MA_RAMP_HUE:
			convertProg = new MixHueOperation();
			break;
		case MA_RAMP_COLOR:
			convertProg = new MixColorOperation();
			break;
		case MA_RAMP_SOFT:
			convertProg = new MixSoftLightOperation();
			break;
		case MA_RAMP_SCREEN:
			convertProg = new MixScreenOperation();
			break;
		case MA_RAMP_LINEAR:
			convertProg = new MixLinearLightOperation();
			break;
		case MA_RAMP_DIFF:
			convertProg = new MixDifferenceOperation();
			break;
		case MA_RAMP_SAT:
			convertProg = new MixSaturationOperation();
			break;
		case MA_RAMP_DIV:
			convertProg = new MixDivideOperation();
			break;
		case MA_RAMP_SUB:
			convertProg = new MixSubtractOperation();
			break;
		case MA_RAMP_DARK:
			convertProg = new MixDarkenOperation();
			break;
		case MA_RAMP_OVERLAY:
			convertProg = new MixOverlayOperation();
			break;
		case MA_RAMP_VAL:
			convertProg = new MixValueOperation();
			break;
		case MA_RAMP_DODGE:
			convertProg = new MixDodgeOperation();
			break;

		case MA_RAMP_BLEND:
		default:
			convertProg = new MixBlendOperation();
			break;
	}
	convertProg->setUseValueAlphaMultiply(useAlphaPremultiply);
	convertProg->setUseClamp(useClamp);

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

	valueSocket->relinkConnections(convertProg->getInputSocket(0), 0, graph);
	color1Socket->relinkConnections(convertProg->getInputSocket(1), 1, graph);
	color2Socket->relinkConnections(convertProg->getInputSocket(2), 2, graph);
	outputSocket->relinkConnections(convertProg->getOutputSocket(0));
	addPreviewOperation(graph, context, convertProg->getOutputSocket(0));
	
	convertProg->getInputSocket(2)->setResizeMode(color2Socket->getResizeMode());
	
	graph->addOperation(convertProg);
}
Exemplo n.º 5
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);
}