Compositor: Add Invert option to the movie clip stabilization node

This appears to be really common workflow when you stabilize shot to make compo
easier (roto, some effects and so) and then re-introduce the motion back.

Surely it's doable with some magic nodes and manual network for transforming
but such workflow is too common in VFX to resist adding one small option in
single node for this.
This commit is contained in:
Sergey Sharybin 2015-10-27 19:59:17 +05:00
parent b2f57190d9
commit ea67f55b87
6 changed files with 37 additions and 8 deletions

View File

@ -40,11 +40,13 @@ Stabilize2dNode::Stabilize2dNode(bNode *editorNode) : Node(editorNode)
void Stabilize2dNode::convertToOperations(NodeConverter &converter, const CompositorContext &context) const
{
bNode *editorNode = this->getbNode();
NodeInput *imageInput = this->getInputSocket(0);
MovieClip *clip = (MovieClip *)getbNode()->id;
MovieClip *clip = (MovieClip *)editorNode->id;
bool invert = (editorNode->custom2 & CMP_NODEFLAG_STABILIZE_INVERSE) != 0;
ScaleOperation *scaleOperation = new ScaleOperation();
scaleOperation->setSampler((PixelSampler)this->getbNode()->custom1);
scaleOperation->setSampler((PixelSampler)editorNode->custom1);
RotateOperation *rotateOperation = new RotateOperation();
rotateOperation->setDoDegree2RadConversion(false);
TranslateOperation *translateOperation = new TranslateOperation();
@ -53,24 +55,28 @@ void Stabilize2dNode::convertToOperations(NodeConverter &converter, const Compos
MovieClipAttributeOperation *xAttribute = new MovieClipAttributeOperation();
MovieClipAttributeOperation *yAttribute = new MovieClipAttributeOperation();
SetSamplerOperation *psoperation = new SetSamplerOperation();
psoperation->setSampler((PixelSampler)this->getbNode()->custom1);
psoperation->setSampler((PixelSampler)editorNode->custom1);
scaleAttribute->setAttribute(MCA_SCALE);
scaleAttribute->setFramenumber(context.getFramenumber());
scaleAttribute->setMovieClip(clip);
scaleAttribute->setInvert(invert);
angleAttribute->setAttribute(MCA_ANGLE);
angleAttribute->setFramenumber(context.getFramenumber());
angleAttribute->setMovieClip(clip);
angleAttribute->setInvert(invert);
xAttribute->setAttribute(MCA_X);
xAttribute->setFramenumber(context.getFramenumber());
xAttribute->setMovieClip(clip);
xAttribute->setInvert(invert);
yAttribute->setAttribute(MCA_Y);
yAttribute->setFramenumber(context.getFramenumber());
yAttribute->setMovieClip(clip);
yAttribute->setInvert(invert);
converter.addOperation(scaleAttribute);
converter.addOperation(angleAttribute);
converter.addOperation(xAttribute);

View File

@ -31,12 +31,14 @@ MovieClipAttributeOperation::MovieClipAttributeOperation() : NodeOperation()
this->m_valueSet = false;
this->m_framenumber = 0;
this->m_attribute = MCA_X;
this->m_invert = false;
}
void MovieClipAttributeOperation::executePixelSampled(float output[4],
float /*x*/, float /*y*/,
PixelSampler /*sampler*/)
{
/* TODO(sergey): This code isn't really thread-safe. */
if (!this->m_valueSet) {
float loc[2], scale, angle;
loc[0] = 0.0f;
@ -61,6 +63,14 @@ void MovieClipAttributeOperation::executePixelSampled(float output[4],
this->m_value = loc[1];
break;
}
if (this->m_invert) {
if (this->m_attribute != MCA_SCALE) {
this->m_value = -this->m_value;
}
else {
this->m_value = 1.0f / this->m_value;
}
}
this->m_valueSet = true;
}
output[0] = this->m_value;

View File

@ -41,6 +41,7 @@ private:
float m_value;
bool m_valueSet;
int m_framenumber;
bool m_invert;
MovieClipAttribute m_attribute;
public:
/**
@ -57,5 +58,6 @@ public:
void setMovieClip(MovieClip *clip) { this->m_clip = clip; }
void setFramenumber(int framenumber) { this->m_framenumber = framenumber; }
void setAttribute(MovieClipAttribute attribute) { this->m_attribute = attribute; }
void setInvert(bool invert) { this->m_invert = invert; }
};
#endif

View File

@ -2035,6 +2035,7 @@ static void node_composit_buts_stabilize2d(uiLayout *layout, bContext *C, Pointe
return;
uiItemR(layout, ptr, "filter_type", 0, "", ICON_NONE);
uiItemR(layout, ptr, "invert", 0, NULL, ICON_NONE);
}
static void node_composit_buts_translate(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)

View File

@ -1110,6 +1110,11 @@ enum {
CMP_NODEFLAG_PLANETRACKDEFORM_MOTION_BLUR = 1,
};
/* Stabilization node */
enum {
CMP_NODEFLAG_STABILIZE_INVERSE = 1,
};
#define CMP_NODE_PLANETRACKDEFORM_MBLUR_SAMPLES_MAX 64
/* Point Density shader node */

View File

@ -5826,6 +5826,11 @@ static void def_cmp_stabilize2d(StructRNA *srna)
RNA_def_property_enum_items(prop, node_sampler_type_items);
RNA_def_property_ui_text(prop, "Filter", "Method to use to filter stabilization");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
prop = RNA_def_property(srna, "invert", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "custom2", CMP_NODEFLAG_STABILIZE_INVERSE);
RNA_def_property_ui_text(prop, "Invert", "Invert stabilization to re-introduce motion to the frame");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
}
static void def_cmp_moviedistortion(StructRNA *srna)