diff --git a/source/blender/compositor/nodes/COM_KeyingNode.cpp b/source/blender/compositor/nodes/COM_KeyingNode.cpp index d81092f21d7..be5fd773b60 100644 --- a/source/blender/compositor/nodes/COM_KeyingNode.cpp +++ b/source/blender/compositor/nodes/COM_KeyingNode.cpp @@ -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)); diff --git a/source/blender/compositor/nodes/COM_KeyingNode.h b/source/blender/compositor/nodes/COM_KeyingNode.h index 17436a32353..fefcfa46d49 100644 --- a/source/blender/compositor/nodes/COM_KeyingNode.h +++ b/source/blender/compositor/nodes/COM_KeyingNode.h @@ -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); diff --git a/source/blender/compositor/operations/COM_KeyingScreenOperation.cpp b/source/blender/compositor/operations/COM_KeyingScreenOperation.cpp index 20b293bef34..6fd20b477e7 100644 --- a/source/blender/compositor/operations/COM_KeyingScreenOperation.cpp +++ b/source/blender/compositor/operations/COM_KeyingScreenOperation.cpp @@ -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); diff --git a/source/blender/editors/space_node/drawnode.c b/source/blender/editors/space_node/drawnode.c index c5f237a0420..69f2867535a 100644 --- a/source/blender/editors/space_node/drawnode.c +++ b/source/blender/editors/space_node/drawnode.c @@ -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); } diff --git a/source/blender/makesdna/DNA_node_types.h b/source/blender/makesdna/DNA_node_types.h index bd9b0a4585e..15641d97709 100644 --- a/source/blender/makesdna/DNA_node_types.h +++ b/source/blender/makesdna/DNA_node_types.h @@ -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; diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c index 6d2d3895b1a..33eb755a96d 100644 --- a/source/blender/makesrna/intern/rna_nodetree.c +++ b/source/blender/makesrna/intern/rna_nodetree.c @@ -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 --------------------------------------------------------- */