mask motion blur shutter option
authorCampbell Barton <ideasman42@gmail.com>
Fri, 27 Jul 2012 10:20:36 +0000 (10:20 +0000)
committerCampbell Barton <ideasman42@gmail.com>
Fri, 27 Jul 2012 10:20:36 +0000 (10:20 +0000)
source/blender/blenkernel/BKE_blender.h
source/blender/blenloader/intern/readfile.c
source/blender/compositor/nodes/COM_MaskNode.cpp
source/blender/compositor/operations/COM_MaskOperation.cpp
source/blender/compositor/operations/COM_MaskOperation.h
source/blender/editors/space_node/drawnode.c
source/blender/makesdna/DNA_node_types.h
source/blender/makesrna/intern/rna_nodetree.c
source/blender/nodes/composite/nodes/node_composite_mask.c

index c4f5100d649ea6908af8f37e5a2f434ba0cd04b0..0c09c24e70954fcc1147561805058afd404e2ee8 100644 (file)
@@ -42,7 +42,7 @@ extern "C" {
  * and keep comment above the defines.
  * Use STRINGIFY() rather than defining with quotes */
 #define BLENDER_VERSION         263
-#define BLENDER_SUBVERSION      16
+#define BLENDER_SUBVERSION      17
 
 #define BLENDER_MINVERSION      250
 #define BLENDER_MINSUBVERSION   0
index 68252fd7e25021f6c39d3d3b7e7c00098d7654f4..a0529271666591477e8ea7aaf6efee36f9bf2a13 100644 (file)
@@ -7027,6 +7027,24 @@ static void do_version_ntree_dilateerode_264(void *UNUSED(data), ID *UNUSED(id),
        }
 }
 
+static void do_version_ntree_mask_264(void *UNUSED(data), ID *UNUSED(id), bNodeTree *ntree)
+{
+       bNode *node;
+
+       for (node = ntree->nodes.first; node; node = node->next) {
+               if (node->type == CMP_NODE_MASK) {
+                       if (node->storage == NULL) {
+                               NodeMask *data = MEM_callocN(sizeof(NodeMask), __func__);
+                               /* move settings into own struct */
+                               data->size_x = node->custom3;
+                               data->size_y = node->custom4;
+                               node->custom3 = 0.5f; /* default shutter */
+                               node->storage = data;
+                       }
+               }
+       }
+}
+
 static void do_version_ntree_keying_despill_balance(void *UNUSED(data), ID *UNUSED(id), bNodeTree *ntree)
 {
        bNode *node;
@@ -7863,6 +7881,13 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
                        ntreetype->foreach_nodetree(main, NULL, do_version_ntree_keying_despill_balance);
        }
 
+       if (main->versionfile < 263 || (main->versionfile == 263 && main->subversionfile < 17)) {
+               bNodeTreeType *ntreetype = ntreeGetType(NTREE_COMPOSIT);
+
+               if (ntreetype && ntreetype->foreach_nodetree)
+                       ntreetype->foreach_nodetree(main, NULL, do_version_ntree_mask_264);
+       }
+
        /* WATCH IT!!!: pointers from libdata have not been converted yet here! */
        /* WATCH IT 2!: Userdef struct init has to be in editors/interface/resources.c! */
 
index 71a7191a35eeca15046f6f0727cc7a3fbd911dfa..8d549d0936228766e8ba66594e4cd22d10e86965 100644 (file)
@@ -36,11 +36,12 @@ MaskNode::MaskNode(bNode *editorNode) : Node(editorNode)
 
 void MaskNode::convertToOperations(ExecutionSystem *graph, CompositorContext *context)
 {
-       const RenderData *data = context->getRenderData();
+       const RenderData *rd = context->getRenderData();
 
        OutputSocket *outputMask = this->getOutputSocket(0);
 
        bNode *editorNode = this->getbNode();
+       NodeMask *data = (NodeMask *)editorNode->storage;
        Mask *mask = (Mask *)editorNode->id;
 
        // always connect the output image
@@ -48,16 +49,16 @@ void MaskNode::convertToOperations(ExecutionSystem *graph, CompositorContext *co
        operation->setbNode(editorNode);
 
        if (editorNode->custom1 & CMP_NODEFLAG_MASK_FIXED) {
-               operation->setMaskWidth(editorNode->custom3);
-               operation->setMaskHeight(editorNode->custom4);
+               operation->setMaskWidth(data->size_x);
+               operation->setMaskHeight(data->size_y);
        }
        else if (editorNode->custom1 & CMP_NODEFLAG_MASK_FIXED_SCENE) {
-               operation->setMaskWidth(editorNode->custom3 * (data->size / 100.0f));
-               operation->setMaskHeight(editorNode->custom4 * (data->size / 100.0f));
+               operation->setMaskWidth(data->size_x * (rd->size / 100.0f));
+               operation->setMaskHeight(data->size_y * (rd->size / 100.0f));
        }
        else {
-               operation->setMaskWidth(data->xsch * data->size / 100.0f);
-               operation->setMaskHeight(data->ysch * data->size / 100.0f);
+               operation->setMaskWidth(rd->xsch * rd->size / 100.0f);
+               operation->setMaskHeight(rd->ysch * rd->size / 100.0f);
        }
 
        if (outputMask->isConnected()) {
@@ -69,8 +70,12 @@ void MaskNode::convertToOperations(ExecutionSystem *graph, CompositorContext *co
        operation->setSmooth((bool)(editorNode->custom1 & CMP_NODEFLAG_MASK_AA) != 0);
        operation->setFeather((bool)(editorNode->custom1 & CMP_NODEFLAG_MASK_NO_FEATHER) == 0);
 
-       if (editorNode->custom1 & CMP_NODEFLAG_MASK_MOTION_BLUR) {
+       if ((editorNode->custom1 & CMP_NODEFLAG_MASK_MOTION_BLUR) &&
+           (editorNode->custom2 > 1) &&
+           (editorNode->custom3 > FLT_EPSILON))
+       {
                operation->setMotionBlurSamples(editorNode->custom2);
+               operation->setMotionBlurShutter(editorNode->custom3);
        }
 
        graph->addOperation(operation);
index a4e548d47ac2d5f7c6af53e4acc6ec51b84614b1..a3326de0a3088f5296175963d67586b82214954a 100644 (file)
@@ -139,7 +139,8 @@ MaskOperation::MaskOperation() : NodeOperation()
        this->m_maskHeight = 0;
        this->m_maskWidthInv = 0.0f;
        this->m_maskHeightInv = 0.0f;
-       this->m_framenumber = 0;
+       this->m_frame_shutter = 0.0f;
+       this->m_frame_number = 0;
        this->m_rasterMaskHandleTot = 1;
        memset(this->m_rasterMaskHandles, 0, sizeof(this->m_rasterMaskHandles));
 }
@@ -156,9 +157,8 @@ void MaskOperation::initExecution()
                }
                else {
                        /* make a throw away copy of the mask */
-                       const float frame_range = 1.0f; /* should be 1 max, could be configurable */
-                       const float frame = (float)this->m_framenumber - frame_range;
-                       const float frame_step = (frame_range * 2.0f) / this->m_rasterMaskHandleTot;
+                       const float frame = (float)this->m_frame_number - this->m_frame_shutter;
+                       const float frame_step = (this->m_frame_shutter * 2.0f) / this->m_rasterMaskHandleTot;
                        float frame_iter = frame;
 
                        Mask *mask_temp;
@@ -174,7 +174,7 @@ void MaskOperation::initExecution()
                                     masklay;
                                     masklay = (MaskLayer *)masklay->next)
                                {
-                                       masklay_shape = BKE_mask_layer_shape_varify_frame(masklay, this->m_framenumber);
+                                       masklay_shape = BKE_mask_layer_shape_varify_frame(masklay, this->m_frame_number);
                                        BKE_mask_layer_shape_from_mask(masklay, masklay_shape);
                                }
                        }
index a8c23b3bca164282f8634b889ace04dcbfb881cf..77d8e1148c2db759117fb4d899b3425427545baf 100644 (file)
@@ -54,7 +54,9 @@ protected:
        float m_maskWidthInv;  /* 1 / m_maskWidth  */
        float m_maskHeightInv; /* 1 / m_maskHeight */
 
-       int m_framenumber;
+       float m_frame_shutter;
+       int   m_frame_number;
+
        bool m_do_smooth;
        bool m_do_feather;
 
@@ -91,10 +93,12 @@ public:
                this->m_maskHeight = height;
                this->m_maskHeightInv = 1.0f / (float)height;
        }
-       void setFramenumber(int framenumber) { this->m_framenumber = framenumber; }
+       void setFramenumber(int frame_number) { this->m_frame_number = frame_number; }
        void setSmooth(bool smooth) { this->m_do_smooth = smooth; }
        void setFeather(bool feather) { this->m_do_feather = feather; }
+
        void setMotionBlurSamples(int samples) { this->m_rasterMaskHandleTot = max(1, samples); }
+       void setMotionBlurShutter(float shutter) { this->m_frame_shutter = shutter; }
 
 #ifdef USE_RASKTER
        void *initializeTileData(rcti *rect);
index b7a51adc5435785552113c0ac325f988cdfcb82c..b3ae8d3e939cbc76bf402af2faa2cc7526fbc2b4 100644 (file)
@@ -2506,6 +2506,7 @@ static void node_composit_buts_mask(uiLayout *layout, bContext *C, PointerRNA *p
        uiItemR(layout, ptr, "use_motion_blur", 0, NULL, ICON_NONE);
        if (node->custom1 & CMP_NODEFLAG_MASK_MOTION_BLUR) {
                uiItemR(layout, ptr, "motion_blur_samples", 0, NULL, ICON_NONE);
+               uiItemR(layout, ptr, "motion_blur_shutter", 0, NULL, ICON_NONE);
        }
 }
 
index 8d36b428aca7afa519e827de5555fb1a91fa24b8..5b8445465a2b7d2a2e4a413cab5118e79b4e538f 100644 (file)
@@ -589,6 +589,10 @@ typedef struct NodeDilateErode {
        char pad[7];
 } NodeDilateErode;
 
+typedef struct NodeMask {
+       int size_x, size_y;
+} NodeMask;
+
 typedef struct NodeTexBase {
        TexMapping tex_mapping;
        ColorMapping color_mapping;
index da30b109efd3174708f160fa75b239541865dbe7..4f259e80f25d6aa95990d444a78b84a80369ff9e 100644 (file)
@@ -3195,20 +3195,28 @@ static void def_cmp_mask(StructRNA *srna)
        RNA_def_property_ui_text(prop, "Samples", "Number of motion blur samples");
        RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
 
+       prop = RNA_def_property(srna, "motion_blur_shutter", PROP_FLOAT, PROP_NONE);
+       RNA_def_property_float_sdna(prop, NULL, "custom3");
+       RNA_def_property_range(prop, 0.0, 1.0f);
+       RNA_def_property_ui_text(prop, "Shutter", "Exposure for motion blur as a factor of FPS");
+       RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
+
+
        prop = RNA_def_property(srna, "size_source", PROP_ENUM, PROP_NONE);
        RNA_def_property_enum_bitflag_sdna(prop, NULL, "custom1");
        RNA_def_property_enum_items(prop, aspect_type_items);
        RNA_def_property_ui_text(prop, "Size Source", "Where to get the mask size from for aspect/size information");
        RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
 
+
+       RNA_def_struct_sdna_from(srna, "NodeMask", "storage");
+
        prop = RNA_def_property(srna, "size_x", PROP_INT, PROP_NONE);
-       RNA_def_property_int_funcs(prop, "rna_Node_custom3_get_as_int", "rna_Node_custom3_set_as_int", NULL);
        RNA_def_property_range(prop, 1.0f, 10000.0f);
        RNA_def_property_ui_text(prop, "X", "");
        RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
 
        prop = RNA_def_property(srna, "size_y", PROP_INT, PROP_NONE);
-       RNA_def_property_int_funcs(prop, "rna_Node_custom4_get_as_int", "rna_Node_custom4_set_as_int", NULL);
        RNA_def_property_range(prop, 1.0f, 10000.0f);
        RNA_def_property_ui_text(prop, "Y", "");
        RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
index 3cd3a732829b2eed5a64f85ec0ac4c21b9610f20..5df8bdc0a85955cef85d66c736f8f2fdbd51a337 100644 (file)
@@ -82,6 +82,16 @@ static void exec(void *data, bNode *node, bNodeStack **UNUSED(in), bNodeStack **
        }
 }
 
+static void node_composit_init_mask(bNodeTree *UNUSED(ntree), bNode* node, bNodeTemplate *UNUSED(ntemp))
+{
+       NodeMask *data = MEM_callocN(sizeof(NodeMask), STRINGIFY(NodeMask));
+       data->size_x = data->size_y = 256;
+       node->storage = data;
+
+       node->custom2 = 16;    /* samples */
+       node->custom3 = 0.5f;  /* shutter */
+}
+
 void register_node_type_cmp_mask(bNodeTreeType *ttype)
 {
        static bNodeType ntype;
@@ -89,7 +99,10 @@ void register_node_type_cmp_mask(bNodeTreeType *ttype)
        node_type_base(ttype, &ntype, CMP_NODE_MASK, "Mask", NODE_CLASS_INPUT, NODE_OPTIONS);
        node_type_socket_templates(&ntype, NULL, cmp_node_mask_out);
        node_type_size(&ntype, 140, 100, 320);
+       node_type_init(&ntype, node_composit_init_mask);
        node_type_exec(&ntype, exec);
 
+       node_type_storage(&ntype, "NodeMask", node_free_standard_storage, node_copy_standard_storage);
+
        nodeRegisterType(ttype, &ntype);
 }