Added feather control to keying node
authorSergey Sharybin <sergey.vfx@gmail.com>
Mon, 25 Jun 2012 10:50:24 +0000 (10:50 +0000)
committerSergey Sharybin <sergey.vfx@gmail.com>
Mon, 25 Jun 2012 10:50:24 +0000 (10:50 +0000)
Behaves in the same way as feather dilate/erode node, applies
after dilate/erode in node.

Also use distance dilate/erode instead of size.

source/blender/compositor/nodes/COM_KeyingNode.cpp
source/blender/compositor/nodes/COM_KeyingNode.h
source/blender/compositor/operations/COM_KeyingScreenOperation.cpp
source/blender/editors/space_node/drawnode.c
source/blender/makesdna/DNA_node_types.h
source/blender/makesrna/intern/rna_nodetree.c

index d81092f21d7191eb0bf8ef9e3d418bd17ff26de3..be5fd773b608a1e92b97c31d1a74e45e38fc7f7b 100644 (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));
index 17436a32353a35a98d4897b748a12d3596f4fd6a..fefcfa46d49dc5bb5cf8dafb975d453b928ebf47 100644 (file)
   */
 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);
index 20b293bef34bc6a3dcdc27482f17a4c538082f44..6fd20b477e76f8323ead152ea4c71b52b873203c 100644 (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);
index c5f237a0420db1f483b743a314ee1ee59e4a52fc..69f2867535a5d8a6e44aec748d5b8d2433161f5e 100644 (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);
 }
 
index bd9b0a4585e96063ed1cf6d19dfb378b87a831b8..15641d9770996e0e9a04756257b7e685274f43b1 100644 (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;
 
index 6d2d3895b1a8e81a1041ad3dab5cb10bbab42459..33eb755a96d10a2419d06c1c5d6f42283d7f9c98 100644 (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 --------------------------------------------------------- */