Added feather control to keying node

Behaves in the same way as feather dilate/erode node, applies
after dilate/erode in node.

Also use distance dilate/erode instead of size.
This commit is contained in:
Sergey Sharybin 2012-06-25 10:50:24 +00:00
parent 3c8a4c458b
commit 1755a0ada6
6 changed files with 75 additions and 10 deletions

View File

@ -40,6 +40,9 @@
#include "COM_SetAlphaOperation.h"
#include "COM_GaussianAlphaXBlurOperation.h"
#include "COM_GaussianAlphaYBlurOperation.h"
KeyingNode::KeyingNode(bNode *editorNode) : Node(editorNode)
{
/* pass */
@ -116,15 +119,15 @@ OutputSocket *KeyingNode::setupPostBlur(ExecutionSystem *graph, OutputSocket *po
OutputSocket *KeyingNode::setupDilateErode(ExecutionSystem *graph, OutputSocket *dilateErodeInput, int distance)
{
DilateStepOperation *dilateErodeOperation;
DilateDistanceOperation *dilateErodeOperation;
if (distance > 0) {
dilateErodeOperation = new DilateStepOperation();
dilateErodeOperation->setIterations(distance);
dilateErodeOperation = new DilateDistanceOperation();
dilateErodeOperation->setDistance(distance);
}
else {
dilateErodeOperation = new ErodeStepOperation();
dilateErodeOperation->setIterations(-distance);
dilateErodeOperation = new ErodeDistanceOperation();
dilateErodeOperation->setDistance(-distance);
}
addLink(graph, dilateErodeInput, dilateErodeOperation->getInputSocket(0));
@ -134,6 +137,46 @@ OutputSocket *KeyingNode::setupDilateErode(ExecutionSystem *graph, OutputSocket
return dilateErodeOperation->getOutputSocket(0);
}
OutputSocket *KeyingNode::setupFeather(ExecutionSystem *graph, CompositorContext *context,
OutputSocket *featherInput, int falloff, int distance)
{
/* this uses a modified gaussian blur function otherwise its far too slow */
CompositorQuality quality = context->getQuality();
/* initialize node data */
NodeBlurData *data = (NodeBlurData *)&this->alpha_blur;
memset(data, 0, sizeof(*data));
data->filtertype = R_FILTER_GAUSS;
if (distance > 0) {
data->sizex = data->sizey = distance;
}
else {
data->sizex = data->sizey = -distance;
}
GaussianAlphaXBlurOperation *operationx = new GaussianAlphaXBlurOperation();
operationx->setData(data);
operationx->setQuality(quality);
operationx->setSize(1.0f);
operationx->setSubtract(distance < 0);
operationx->setFalloff(falloff);
graph->addOperation(operationx);
GaussianAlphaYBlurOperation *operationy = new GaussianAlphaYBlurOperation();
operationy->setData(data);
operationy->setQuality(quality);
operationy->setSize(1.0f);
operationy->setSubtract(distance < 0);
operationy->setFalloff(falloff);
graph->addOperation(operationy);
addLink(graph, featherInput, operationx->getInputSocket(0));
addLink(graph, operationx->getOutputSocket(), operationy->getInputSocket(0));
return operationy->getOutputSocket();
}
OutputSocket *KeyingNode::setupDespill(ExecutionSystem *graph, OutputSocket *despillInput, OutputSocket *inputScreen, float factor)
{
KeyingDespillOperation *despillOperation = new KeyingDespillOperation();
@ -225,6 +268,12 @@ void KeyingNode::convertToOperations(ExecutionSystem *graph, CompositorContext *
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));

View File

@ -29,9 +29,13 @@
*/
class KeyingNode : public Node {
protected:
NodeBlurData alpha_blur; /* only used for blurring alpha, since the dilate/erode node doesnt have this */
OutputSocket *setupPreBlur(ExecutionSystem *graph, InputSocket *inputImage, int size, OutputSocket **originalImage);
OutputSocket *setupPostBlur(ExecutionSystem *graph, OutputSocket *postBlurInput, int size);
OutputSocket *setupDilateErode(ExecutionSystem *graph, OutputSocket *dilateErodeInput, int distance);
OutputSocket *setupFeather(ExecutionSystem *graph, CompositorContext *context, OutputSocket *featherInput,
int falloff, int distance);
OutputSocket *setupDespill(ExecutionSystem *graph, OutputSocket *despillInput, OutputSocket *inputSrceen, float factor);
OutputSocket *setupClip(ExecutionSystem *graph, OutputSocket *clipInput, int kernelRadius, float kernelTolerance,
float clipBlack, float clipWhite, bool edgeMatte);

View File

@ -116,8 +116,7 @@ KeyingScreenOperation::TriangulationData *KeyingScreenOperation::buildVoronoiTri
sites = (VoronoiSite *) MEM_callocN(sizeof(VoronoiSite) * sites_total, "keyingscreen voronoi sites");
track = (MovieTrackingTrack *) tracksbase->first;
i = 0;
while (track) {
for (track = (MovieTrackingTrack *) tracksbase->first, i = 0; track; track = track->next, i++) {
VoronoiSite *site = &sites[i];
MovieTrackingMarker *marker = BKE_tracking_marker_get(track, clip_frame);
ImBuf *pattern_ibuf = BKE_tracking_get_pattern_imbuf(ibuf, track, marker, TRUE, FALSE);
@ -142,9 +141,6 @@ KeyingScreenOperation::TriangulationData *KeyingScreenOperation::buildVoronoiTri
site->co[0] = marker->pos[0] * width;
site->co[1] = marker->pos[1] * height;
track = track->next;
i++;
}
IMB_freeImBuf(ibuf);

View File

@ -2482,6 +2482,8 @@ static void node_composit_buts_keying(uiLayout *layout, bContext *UNUSED(C), Poi
uiItemR(layout, ptr, "clip_black", 0, NULL, ICON_NONE);
uiItemR(layout, ptr, "clip_white", 0, NULL, ICON_NONE);
uiItemR(layout, ptr, "dilate_distance", 0, NULL, ICON_NONE);
uiItemR(layout, ptr, "feather_falloff", 0, NULL, ICON_NONE);
uiItemR(layout, ptr, "feather_distance", 0, NULL, ICON_NONE);
uiItemR(layout, ptr, "blur_post", 0, NULL, ICON_NONE);
}

View File

@ -655,6 +655,8 @@ typedef struct NodeKeyingData {
float edge_kernel_tolerance;
float clip_black, clip_white;
int dilate_distance;
int feather_distance;
int feather_falloff;
int blur_pre, blur_post;
} NodeKeyingData;

View File

@ -3620,6 +3620,18 @@ static void def_cmp_keying(StructRNA *srna)
RNA_def_property_range(prop, 0.0f, 1.0f);
RNA_def_property_ui_text(prop, "Edge Kernel Tolerance", "Tolerance to pixels inside kernel which are treating as belonging to the same plane");
RNA_def_property_update(prop, NC_NODE|NA_EDITED, "rna_Node_update");
prop = RNA_def_property(srna, "feather_falloff", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "feather_falloff");
RNA_def_property_enum_items(prop, proportional_falloff_curve_only_items);
RNA_def_property_ui_text(prop, "Feather Falloff", "Falloff type the feather");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
prop = RNA_def_property(srna, "feather_distance", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "feather_distance");
RNA_def_property_range(prop, -100, 100);
RNA_def_property_ui_text(prop, "Feather Distance", "Distance to grow/shrink the feather");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
}
/* -- Texture Nodes --------------------------------------------------------- */