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());
	}
}
示例#2
0
void ZCombineNode::convertToOperations(ExecutionSystem *system, CompositorContext *context)
{
	if ((context->getRenderData()->scemode & R_FULL_SAMPLE) || this->getbNode()->custom2) {
		if (this->getOutputSocket(0)->isConnected()) {
			ZCombineOperation *operation = NULL;
			if (this->getbNode()->custom1) {
				operation = new ZCombineAlphaOperation();
			}
			else {
				operation = new ZCombineOperation();
			}

			this->getInputSocket(0)->relinkConnections(operation->getInputSocket(0), 0, system);
			this->getInputSocket(1)->relinkConnections(operation->getInputSocket(1), 1, system);
			this->getInputSocket(2)->relinkConnections(operation->getInputSocket(2), 2, system);
			this->getInputSocket(3)->relinkConnections(operation->getInputSocket(3), 3, system);
			this->getOutputSocket(0)->relinkConnections(operation->getOutputSocket());
			system->addOperation(operation);
			if (this->getOutputSocket(1)->isConnected()) {
				MathMinimumOperation *zoperation = new MathMinimumOperation();
				addLink(system, operation->getInputSocket(1)->getConnection()->getFromSocket(), zoperation->getInputSocket(0));
				addLink(system, operation->getInputSocket(3)->getConnection()->getFromSocket(), zoperation->getInputSocket(1));
				this->getOutputSocket(1)->relinkConnections(zoperation->getOutputSocket());
				system->addOperation(zoperation);
			}
		}
		else {
			if (this->getOutputSocket(1)->isConnected()) {
				MathMinimumOperation *zoperation = new MathMinimumOperation();
				this->getInputSocket(1)->relinkConnections(zoperation->getInputSocket(0), 1, system);
				this->getInputSocket(3)->relinkConnections(zoperation->getInputSocket(1), 3, system);
				this->getOutputSocket(1)->relinkConnections(zoperation->getOutputSocket());
				system->addOperation(zoperation);
			}
		}
	}
	else {
		// 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();
			this->getInputSocket(1)->relinkConnections(maskoperation->getInputSocket(0), 3, system);
			this->getInputSocket(3)->relinkConnections(maskoperation->getInputSocket(1), 1, system);
		}
		else {
			maskoperation = new MathLessThanOperation();
			this->getInputSocket(1)->relinkConnections(maskoperation->getInputSocket(0), 1, system);
			this->getInputSocket(3)->relinkConnections(maskoperation->getInputSocket(1), 3, system);
		}

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

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

		system->addOperation(maskoperation);
		system->addOperation(antialiasoperation);
		system->addOperation(zcombineoperation);

		if (this->getOutputSocket(1)->isConnected()) {
			MathMinimumOperation *zoperation = new MathMinimumOperation();
			addLink(system, maskoperation->getInputSocket(0)->getConnection()->getFromSocket(), zoperation->getInputSocket(0));
			addLink(system, maskoperation->getInputSocket(1)->getConnection()->getFromSocket(), zoperation->getInputSocket(1));
			this->getOutputSocket(1)->relinkConnections(zoperation->getOutputSocket());
			system->addOperation(zoperation);
		}
	}
}
示例#3
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);
}