nodes: revert to single output

This commit is contained in:
itsmattkc
2021-09-07 22:01:36 -07:00
parent 9843fd47f0
commit b07bccb7dc
89 changed files with 511 additions and 616 deletions
+2 -2
View File
@@ -29,9 +29,9 @@ namespace olive {
void XMLConnectNodes(const XMLNodeData &xml_node_data, MultiUndoCommand *command)
{
foreach (const XMLNodeData::SerializedConnection& con, xml_node_data.desired_connections) {
NodeOutput out(xml_node_data.node_ptrs.value(con.output_node), con.output);
Node *out = xml_node_data.node_ptrs.value(con.output_node);
if (out.IsValid()) {
if (out) {
if (command) {
command->add_child(new NodeEdgeAddCommand(out, con.input));
} else {
-1
View File
@@ -39,7 +39,6 @@ struct XMLNodeData {
struct SerializedConnection {
NodeInput input;
quintptr output_node;
QString output;
};
struct BlockLink {
+1 -1
View File
@@ -75,7 +75,7 @@
namespace olive {
Core* Core::instance_ = nullptr;
const uint Core::kProjectVersion = 210528;
const uint Core::kProjectVersion = 210907;
Core::Core(const CoreParams& params) :
main_window_(nullptr),
+1 -2
View File
@@ -62,9 +62,8 @@ QString PanNode::Description() const
return tr("Adjust the stereo panning of an audio source.");
}
void PanNode::Value(const QString &output, const NodeValueRow &value, const NodeGlobals &globals, NodeValueTable *table) const
void PanNode::Value(const NodeValueRow &value, const NodeGlobals &globals, NodeValueTable *table) const
{
Q_UNUSED(output)
Q_UNUSED(globals)
// Create a sample job
+1 -1
View File
@@ -40,7 +40,7 @@ public:
virtual QVector<CategoryID> Category() const override;
virtual QString Description() const override;
virtual void Value(const QString& output, const NodeValueRow& value, const NodeGlobals &globals, NodeValueTable *table) const override;
virtual void Value(const NodeValueRow& value, const NodeGlobals &globals, NodeValueTable *table) const override;
virtual void ProcessSamples(const NodeValueRow &values, const SampleBufferPtr input, SampleBufferPtr output, int index) const override;
+1 -3
View File
@@ -61,10 +61,8 @@ QString VolumeNode::Description() const
return tr("Adjusts the volume of an audio source.");
}
void VolumeNode::Value(const QString &output, const NodeValueRow &value, const NodeGlobals &globals, NodeValueTable *table) const
void VolumeNode::Value(const NodeValueRow &value, const NodeGlobals &globals, NodeValueTable *table) const
{
Q_UNUSED(output)
return ValueInternal(kOpMultiply,
kPairSampleNumber,
kSamplesInput,
+1 -1
View File
@@ -40,7 +40,7 @@ public:
virtual QVector<CategoryID> Category() const override;
virtual QString Description() const override;
virtual void Value(const QString& output, const NodeValueRow& value, const NodeGlobals &globals, NodeValueTable *table) const override;
virtual void Value(const NodeValueRow& value, const NodeGlobals &globals, NodeValueTable *table) const override;
virtual void ProcessSamples(const NodeValueRow &values, const SampleBufferPtr input, SampleBufferPtr output, int index) const override;
+4 -4
View File
@@ -100,7 +100,7 @@ void Block::InputValueChangedEvent(const QString &input, int element)
}
}
bool Block::HashPassthrough(const QString &input, const QString &output, QCryptographicHash &hash, const NodeGlobals &globals, const VideoParams &video_params) const
bool Block::HashPassthrough(const QString &input, const Node::ValueHint &output, QCryptographicHash &hash, const NodeGlobals &globals, const VideoParams &video_params) const
{
if (IsInputConnected(input)) {
TimeRange t = InputTimeAdjustment(input, -1, globals.time());
@@ -108,8 +108,8 @@ bool Block::HashPassthrough(const QString &input, const QString &output, QCrypto
NodeGlobals new_globals = globals;
new_globals.set_time(t);
NodeOutput out = GetConnectedOutput(input);
out.node()->Hash(out.output(), hash, new_globals, video_params);
Node *out = GetConnectedOutput(input);
out->Hash(GetValueHintForInput(input, -1), hash, new_globals, video_params);
return true;
}
@@ -130,7 +130,7 @@ void Block::Retranslate()
SetInputName(kEnabledInput, tr("Enabled"));
}
void Block::Hash(const QString &, QCryptographicHash &, const NodeGlobals &, const VideoParams &) const
void Block::Hash(const ValueHint &hint, QCryptographicHash &, const NodeGlobals &, const VideoParams &) const
{
// A block does nothing by default, so we hash nothing
}
+2 -2
View File
@@ -115,7 +115,7 @@ public:
index_ = i;
}
virtual void Hash(const QString& output, QCryptographicHash &hash, const NodeGlobals &globals, const VideoParams& video_params) const override;
virtual void Hash(const Node::ValueHint &hint, QCryptographicHash &hash, const NodeGlobals &globals, const VideoParams& video_params) const override;
virtual void InvalidateCache(const TimeRange& range, const QString& from, int element = -1, InvalidateCacheOptions options = InvalidateCacheOptions()) override;
@@ -134,7 +134,7 @@ signals:
protected:
virtual void InputValueChangedEvent(const QString& input, int element) override;
bool HashPassthrough(const QString &input, const QString& output, QCryptographicHash &hash, const NodeGlobals &globals, const VideoParams& video_params) const;
bool HashPassthrough(const QString &input, const ValueHint &output, QCryptographicHash &hash, const NodeGlobals &globals, const VideoParams& video_params) const;
Block* previous_;
Block* next_;
+13 -5
View File
@@ -20,6 +20,7 @@
#include "clip.h"
#include "node/output/track/track.h"
#include "widget/slider/floatslider.h"
#include "widget/slider/rationalslider.h"
@@ -50,7 +51,7 @@ ClipBlock::ClipBlock() :
IgnoreHashingFrom(kReverseInput);
PrependInput(kBufferIn, NodeValue::kNone, InputFlags(kInputFlagNotKeyframable));
SetValueHintForInput(kBufferIn, {NodeValue::kBuffer, -1, QString()});
SetValueHintForInput(kBufferIn, -1, {NodeValue::kBuffer, -1, QString()});
}
Node *ClipBlock::copy() const
@@ -60,6 +61,14 @@ Node *ClipBlock::copy() const
QString ClipBlock::Name() const
{
if (track()) {
if (track()->type() == Track::kVideo) {
return tr("Video Clip");
} else if (track()->type() == Track::kAudio) {
return tr("Audio Clip");
}
}
return tr("Clip");
}
@@ -232,9 +241,8 @@ TimeRange ClipBlock::OutputTimeAdjustment(const QString& input, int element, con
return super::OutputTimeAdjustment(input, element, input_time);
}
void ClipBlock::Value(const QString &output, const NodeValueRow &value, const NodeGlobals &globals, NodeValueTable *table) const
void ClipBlock::Value(const NodeValueRow &value, const NodeGlobals &globals, NodeValueTable *table) const
{
Q_UNUSED(output)
Q_UNUSED(globals)
// We discard most values here except for the buffer we received
@@ -256,9 +264,9 @@ void ClipBlock::Retranslate()
SetInputName(kReverseInput, tr("Reverse"));
}
void ClipBlock::Hash(const QString &out, QCryptographicHash &hash, const NodeGlobals &globals, const VideoParams &video_params) const
void ClipBlock::Hash(const ValueHint &out, QCryptographicHash &hash, const NodeGlobals &globals, const VideoParams &video_params) const
{
HashPassthrough(kBufferIn, out, hash, globals, video_params);
HashPassthrough(kBufferIn, GetValueHintForInput(kBufferIn, -1), hash, globals, video_params);
}
}
+2 -2
View File
@@ -55,11 +55,11 @@ public:
virtual TimeRange OutputTimeAdjustment(const QString& input, int element, const TimeRange& input_time) const override;
virtual void Value(const QString& output, const NodeValueRow& value, const NodeGlobals &globals, NodeValueTable *table) const override;
virtual void Value(const NodeValueRow& value, const NodeGlobals &globals, NodeValueTable *table) const override;
virtual void Retranslate() override;
virtual void Hash(const QString& output, QCryptographicHash &hash, const NodeGlobals &globals, const VideoParams& video_params) const override;
virtual void Hash(const Node::ValueHint& output, QCryptographicHash &hash, const NodeGlobals &globals, const VideoParams& video_params) const override;
double speed() const
{
+10 -12
View File
@@ -137,10 +137,10 @@ double TransitionBlock::GetInProgress(const double &time) const
return clamp((GetInternalTransitionTime(time) - out_offset().toDouble()) / in_offset().toDouble(), 0.0, 1.0);
}
void TransitionBlock::Hash(const QString &output, QCryptographicHash &hash, const NodeGlobals &globals, const VideoParams &video_params) const
void TransitionBlock::Hash(const ValueHint &output, QCryptographicHash &hash, const NodeGlobals &globals, const VideoParams &video_params) const
{
if (HashPassthrough(kInBlockInput, output, hash, globals, video_params) || HashPassthrough(kOutBlockInput, output, hash, globals, video_params)) {
HashAddNodeSignature(hash, output);
HashAddNodeSignature(hash);
double time_dbl = globals.time().in().toDouble();
double all_prog = GetTotalProgress(time_dbl);
@@ -173,10 +173,8 @@ void TransitionBlock::InsertTransitionTimes(AcceleratedJob *job, const double &t
NodeValue(NodeValue::kFloat, GetInProgress(time), this));
}
void TransitionBlock::Value(const QString &output, const NodeValueRow &value, const NodeGlobals &globals, NodeValueTable *table) const
void TransitionBlock::Value(const NodeValueRow &value, const NodeGlobals &globals, NodeValueTable *table) const
{
Q_UNUSED(output)
NodeValue out_buffer = value[kOutBlockInput];
NodeValue in_buffer = value[kInBlockInput];
NodeValue::Type data_type = (out_buffer.type() != NodeValue::kNone) ? out_buffer.type() : in_buffer.type();
@@ -236,7 +234,7 @@ void TransitionBlock::InvalidateCache(const TimeRange &range, const QString &fro
TimeRange r = range;
if (from == kOutBlockInput || from == kInBlockInput) {
Block *n = dynamic_cast<Block*>(GetConnectedNode(from));
Block *n = dynamic_cast<Block*>(GetConnectedOutput(from));
if (n) {
r = Track::TransformRangeFromBlock(n, r);
}
@@ -275,24 +273,24 @@ double TransitionBlock::TransformCurve(double linear) const
return linear;
}
void TransitionBlock::InputConnectedEvent(const QString &input, int element, const NodeOutput &output)
void TransitionBlock::InputConnectedEvent(const QString &input, int element, Node *output)
{
Q_UNUSED(element)
if (input == kOutBlockInput) {
// If node is not a block, this will just be null
if ((connected_out_block_ = dynamic_cast<ClipBlock*>(output.node()))) {
if ((connected_out_block_ = dynamic_cast<ClipBlock*>(output))) {
connected_out_block_->set_out_transition(this);
}
} else if (input == kInBlockInput) {
// If node is not a block, this will just be null
if ((connected_in_block_ = dynamic_cast<ClipBlock*>(output.node()))) {
if ((connected_in_block_ = dynamic_cast<ClipBlock*>(output))) {
connected_in_block_->set_in_transition(this);
}
}
}
void TransitionBlock::InputDisconnectedEvent(const QString &input, int element, const NodeOutput &output)
void TransitionBlock::InputDisconnectedEvent(const QString &input, int element, Node *output)
{
Q_UNUSED(element)
Q_UNUSED(output)
@@ -313,7 +311,7 @@ void TransitionBlock::InputDisconnectedEvent(const QString &input, int element,
TimeRange TransitionBlock::InputTimeAdjustment(const QString &input, int element, const TimeRange &input_time) const
{
if (input == kInBlockInput || input == kOutBlockInput) {
Block* block = dynamic_cast<Block*>(GetConnectedNode(input));
Block* block = dynamic_cast<Block*>(GetConnectedOutput(input));
if (block) {
return input_time + in() - block->in();
}
@@ -325,7 +323,7 @@ TimeRange TransitionBlock::InputTimeAdjustment(const QString &input, int element
TimeRange TransitionBlock::OutputTimeAdjustment(const QString &input, int element, const TimeRange &input_time) const
{
if (input == kInBlockInput || input == kOutBlockInput) {
Block* block = dynamic_cast<Block*>(GetConnectedNode(input));
Block* block = dynamic_cast<Block*>(GetConnectedOutput(input));
if (block) {
return input_time + block->in() - in();
}
+4 -4
View File
@@ -65,9 +65,9 @@ public:
double GetOutProgress(const double &time) const;
double GetInProgress(const double &time) const;
virtual void Hash(const QString& output, QCryptographicHash& hash, const NodeGlobals &globals, const VideoParams& video_params) const override;
virtual void Hash(const ValueHint& output, QCryptographicHash& hash, const NodeGlobals &globals, const VideoParams& video_params) const override;
virtual void Value(const QString& output, const NodeValueRow& value, const NodeGlobals &globals, NodeValueTable *table) const override;
virtual void Value(const NodeValueRow& value, const NodeGlobals &globals, NodeValueTable *table) const override;
virtual void InvalidateCache(const TimeRange& range, const QString& from, int element = -1, InvalidateCacheOptions options = InvalidateCacheOptions()) override;
@@ -83,9 +83,9 @@ protected:
double TransformCurve(double linear) const;
virtual void InputConnectedEvent(const QString& input, int element, const NodeOutput& output) override;
virtual void InputConnectedEvent(const QString& input, int element, Node *output) override;
virtual void InputDisconnectedEvent(const QString& input, int element, const NodeOutput& output) override;
virtual void InputDisconnectedEvent(const QString& input, int element, Node *output) override;
virtual TimeRange InputTimeAdjustment(const QString& input, int element, const TimeRange& input_time) const override;
+1 -3
View File
@@ -55,10 +55,8 @@ void CropDistortNode::Retranslate()
SetInputName(kFeatherInput, tr("Feather"));
}
void CropDistortNode::Value(const QString &output, const NodeValueRow &value, const NodeGlobals &globals, NodeValueTable *table) const
void CropDistortNode::Value(const NodeValueRow &value, const NodeGlobals &globals, NodeValueTable *table) const
{
Q_UNUSED(output)
ShaderJob job;
job.InsertValue(value);
job.InsertValue(QStringLiteral("resolution_in"), NodeValue(NodeValue::kVec2, globals.resolution(), this));
+1 -1
View File
@@ -63,7 +63,7 @@ public:
virtual void Retranslate() override;
virtual void Value(const QString& output, const NodeValueRow& value, const NodeGlobals &globals, NodeValueTable *table) const override;
virtual void Value(const NodeValueRow& value, const NodeGlobals &globals, NodeValueTable *table) const override;
virtual ShaderCode GetShaderCode(const QString &shader_id) const override;
@@ -39,7 +39,7 @@ TransformDistortNode::TransformDistortNode()
AddInput(kInterpolationInput, NodeValue::kCombo, 2);
AddInput(kTextureInput, NodeValue::kTexture, InputFlags(kInputFlagNotKeyframable));
PrependInput(kTextureInput, NodeValue::kTexture, InputFlags(kInputFlagNotKeyframable));
}
void TransformDistortNode::Retranslate()
@@ -54,10 +54,8 @@ void TransformDistortNode::Retranslate()
SetComboBoxStrings(kInterpolationInput, {tr("Nearest Neighbor"), tr("Bilinear"), tr("Mipmapped Bilinear")});
}
void TransformDistortNode::Value(const QString &output, const NodeValueRow &value, const NodeGlobals &globals, NodeValueTable *table) const
void TransformDistortNode::Value(const NodeValueRow &value, const NodeGlobals &globals, NodeValueTable *table) const
{
Q_UNUSED(output)
// Generate matrix
QMatrix4x4 generated_matrix = GenerateMatrix(value, true, false, false, false);
@@ -309,11 +307,11 @@ void TransformDistortNode::GizmoRelease()
gizmo_drag_ = nullptr;
}
void TransformDistortNode::Hash(const QString &output, QCryptographicHash &hash, const NodeGlobals &globals, const VideoParams &video_params) const
void TransformDistortNode::Hash(const ValueHint &output, QCryptographicHash &hash, const NodeGlobals &globals, const VideoParams &video_params) const
{
// If not connected to output, this will produce nothing
NodeOutput out = GetConnectedOutput(kTextureInput);
if (!out.IsValid()) {
Node *out = GetConnectedOutput(kTextureInput);
if (!out) {
return;
}
@@ -321,7 +319,7 @@ void TransformDistortNode::Hash(const QString &output, QCryptographicHash &hash,
NodeTraverser traverser;
traverser.SetCacheVideoParams(video_params);
NodeValueRow db = traverser.GenerateRow(this, output, globals.time());
NodeValueRow db = traverser.GenerateRow(this, globals.time());
TexturePtr tex = db[kTextureInput].data().value<TexturePtr>();
if (tex) {
VideoParams tex_params = tex->params();
@@ -330,12 +328,12 @@ void TransformDistortNode::Hash(const QString &output, QCryptographicHash &hash,
if (!matrix.isIdentity()) {
// Add fingerprint
HashAddNodeSignature(hash, output);
HashAddNodeSignature(hash);
hash.addData(reinterpret_cast<const char*>(&matrix), sizeof(matrix));
}
}
out.node()->Hash(out.output(), hash, globals, video_params);
out->Hash(GetValueHintForInput(kTextureInput, -1), hash, globals, video_params);
}
QMatrix4x4 TransformDistortNode::AdjustMatrixByResolutions(const QMatrix4x4 &mat, const QVector2D &sequence_res, const QVector2D &texture_res, AutoScaleType autoscale_type)
@@ -65,7 +65,7 @@ public:
virtual void Retranslate() override;
virtual void Value(const QString& output, const NodeValueRow& value, const NodeGlobals &globals, NodeValueTable *table) const override;
virtual void Value(const NodeValueRow& value, const NodeGlobals &globals, NodeValueTable *table) const override;
virtual ShaderCode GetShaderCode(const QString& shader_id) const override;
@@ -80,7 +80,7 @@ public:
virtual void GizmoMove(const QPointF &p, const rational &time) override;
virtual void GizmoRelease() override;
virtual void Hash(const QString& output, QCryptographicHash& hash, const NodeGlobals &globals, const VideoParams& video_params) const override;
virtual void Hash(const ValueHint& output, QCryptographicHash& hash, const NodeGlobals &globals, const VideoParams& video_params) const override;
enum AutoScaleType {
kAutoScaleNone,
-4
View File
@@ -63,10 +63,6 @@ void NodeFactory::Initialize()
Node* created_node = CreateFromFactoryIndex(static_cast<InternalID>(i));
library_.append(created_node);
if (created_node->outputs().isEmpty()) {
qWarning() << "Node" << created_node->id() << "has no outputs";
}
}
}
+1 -3
View File
@@ -87,10 +87,8 @@ ShaderCode BlurFilterNode::GetShaderCode(const QString &shader_id) const
return ShaderCode(FileFunctions::ReadFileAsString(":/shaders/blur.frag"));
}
void BlurFilterNode::Value(const QString &output, const NodeValueRow &value, const NodeGlobals &globals, NodeValueTable *table) const
void BlurFilterNode::Value(const NodeValueRow &value, const NodeGlobals &globals, NodeValueTable *table) const
{
Q_UNUSED(output)
ShaderJob job;
job.InsertValue(value);
+1 -1
View File
@@ -43,7 +43,7 @@ public:
virtual void Retranslate() override;
virtual ShaderCode GetShaderCode(const QString &shader_id) const override;
virtual void Value(const QString& output, const NodeValueRow& value, const NodeGlobals &globals, NodeValueTable *table) const override;
virtual void Value(const NodeValueRow& value, const NodeGlobals &globals, NodeValueTable *table) const override;
static const QString kTextureInput;
static const QString kMethodInput;
+1 -3
View File
@@ -44,10 +44,8 @@ void MosaicFilterNode::Retranslate()
SetInputName(kVertInput, tr("Vertical"));
}
void MosaicFilterNode::Value(const QString &output, const NodeValueRow &value, const NodeGlobals &globals, NodeValueTable *table) const
void MosaicFilterNode::Value(const NodeValueRow &value, const NodeGlobals &globals, NodeValueTable *table) const
{
Q_UNUSED(output)
ShaderJob job;
job.InsertValue(value);
+1 -1
View File
@@ -60,7 +60,7 @@ public:
virtual void Retranslate() override;
virtual void Value(const QString& output, const NodeValueRow& value, const NodeGlobals &globals, NodeValueTable *table) const override;
virtual void Value(const NodeValueRow& value, const NodeGlobals &globals, NodeValueTable *table) const override;
virtual ShaderCode GetShaderCode(const QString &shader_id) const override;
static const QString kTextureInput;
+1 -3
View File
@@ -82,10 +82,8 @@ void StrokeFilterNode::Retranslate()
SetInputName(kInnerInput, tr("Inner"));
}
void StrokeFilterNode::Value(const QString &output, const NodeValueRow &value, const NodeGlobals &globals, NodeValueTable *table) const
void StrokeFilterNode::Value(const NodeValueRow &value, const NodeGlobals &globals, NodeValueTable *table) const
{
Q_UNUSED(output)
ShaderJob job;
job.InsertValue(value);
+1 -1
View File
@@ -42,7 +42,7 @@ public:
virtual void Retranslate() override;
virtual void Value(const QString& output, const NodeValueRow& value, const NodeGlobals &globals, NodeValueTable *table) const override;
virtual void Value(const NodeValueRow& value, const NodeGlobals &globals, NodeValueTable *table) const override;
virtual ShaderCode GetShaderCode(const QString &shader_id) const override;
static const QString kTextureInput;
+1 -3
View File
@@ -88,10 +88,8 @@ void MatrixGenerator::Retranslate()
SetInputName(kAnchorInput, tr("Anchor Point"));
}
void MatrixGenerator::Value(const QString &output, const NodeValueRow &value, const NodeGlobals &globals, NodeValueTable *table) const
void MatrixGenerator::Value(const NodeValueRow &value, const NodeGlobals &globals, NodeValueTable *table) const
{
Q_UNUSED(output)
// Push matrix output
QMatrix4x4 mat = GenerateMatrix(value, true, false, false, false);
table->Push(NodeValue::kMatrix, mat, this);
+1 -1
View File
@@ -46,7 +46,7 @@ public:
virtual void Retranslate() override;
virtual void Value(const QString& output, const NodeValueRow& value, const NodeGlobals &globals, NodeValueTable *table) const override;
virtual void Value(const NodeValueRow& value, const NodeGlobals &globals, NodeValueTable *table) const override;
static const QString kPositionInput;
static const QString kRotationInput;
+1 -3
View File
@@ -86,10 +86,8 @@ ShaderCode PolygonGenerator::GetShaderCode(const QString &shader_id) const
return ShaderCode(FileFunctions::ReadFileAsString(QStringLiteral(":/shaders/polygon.frag")));
}
void PolygonGenerator::Value(const QString &output, const NodeValueRow &value, const NodeGlobals &globals, NodeValueTable *table) const
void PolygonGenerator::Value(const NodeValueRow &value, const NodeGlobals &globals, NodeValueTable *table) const
{
Q_UNUSED(output)
ShaderJob job;
job.InsertValue(value);
+1 -1
View File
@@ -44,7 +44,7 @@ public:
virtual void Retranslate() override;
virtual ShaderCode GetShaderCode(const QString& shader_id) const override;
virtual void Value(const QString& output, const NodeValueRow& value, const NodeGlobals &globals, NodeValueTable *table) const override;
virtual void Value(const NodeValueRow& value, const NodeGlobals &globals, NodeValueTable *table) const override;
virtual bool HasGizmos() const override;
//virtual void DrawGizmos(NodeValueDatabase& db, QPainter *p) const override;
+1 -3
View File
@@ -68,10 +68,8 @@ ShaderCode ShapeNode::GetShaderCode(const QString &shader_id) const
return ShaderCode(FileFunctions::ReadFileAsString(QStringLiteral(":/shaders/shape.frag")));
}
void ShapeNode::Value(const QString &output, const NodeValueRow &value, const NodeGlobals &globals, NodeValueTable *table) const
void ShapeNode::Value(const NodeValueRow &value, const NodeGlobals &globals, NodeValueTable *table) const
{
Q_UNUSED(output)
ShaderJob job;
job.InsertValue(value);
+1 -1
View File
@@ -47,7 +47,7 @@ public:
virtual void Retranslate() override;
virtual ShaderCode GetShaderCode(const QString& shader_id) const override;
virtual void Value(const QString& output, const NodeValueRow& value, const NodeGlobals &globals, NodeValueTable *table) const override;
virtual void Value(const NodeValueRow& value, const NodeGlobals &globals, NodeValueTable *table) const override;
static QString kTypeInput;
+1 -3
View File
@@ -62,10 +62,8 @@ void SolidGenerator::Retranslate()
SetInputName(kColorInput, tr("Color"));
}
void SolidGenerator::Value(const QString &output, const NodeValueRow &value, const NodeGlobals &globals, NodeValueTable *table) const
void SolidGenerator::Value(const NodeValueRow &value, const NodeGlobals &globals, NodeValueTable *table) const
{
Q_UNUSED(output)
ShaderJob job;
job.InsertValue(value);
table->Push(NodeValue::kShaderJob, QVariant::fromValue(job), this);
+1 -1
View File
@@ -42,7 +42,7 @@ public:
virtual void Retranslate() override;
virtual void Value(const QString& output, const NodeValueRow& value, const NodeGlobals &globals, NodeValueTable *table) const override;
virtual void Value(const NodeValueRow& value, const NodeGlobals &globals, NodeValueTable *table) const override;
virtual ShaderCode GetShaderCode(const QString &shader_id) const override;
static const QString kColorInput;
+1 -3
View File
@@ -89,10 +89,8 @@ void TextGenerator::Retranslate()
SetComboBoxStrings(kVAlignInput, {tr("Top"), tr("Center"), tr("Bottom")});
}
void TextGenerator::Value(const QString &output, const NodeValueRow &value, const NodeGlobals &globals, NodeValueTable *table) const
void TextGenerator::Value(const NodeValueRow &value, const NodeGlobals &globals, NodeValueTable *table) const
{
Q_UNUSED(output)
GenerateJob job;
job.InsertValue(value);
job.SetAlphaChannelRequired(GenerateJob::kAlphaForceOn);
+1 -1
View File
@@ -42,7 +42,7 @@ public:
virtual void Retranslate() override;
virtual void Value(const QString& output, const NodeValueRow& value, const NodeGlobals &globals, NodeValueTable *table) const override;
virtual void Value(const NodeValueRow& value, const NodeGlobals &globals, NodeValueTable *table) const override;
virtual void GenerateFrame(FramePtr frame, const GenerateJob &job) const override;
+2 -2
View File
@@ -123,9 +123,9 @@ signals:
*/
void NodeRemoved(Node* node);
void InputConnected(const NodeOutput& output, const NodeInput& input);
void InputConnected(Node *output, const NodeInput& input);
void InputDisconnected(const NodeOutput& output, const NodeInput& input);
void InputDisconnected(Node *output, const NodeInput& input);
void ValueChanged(const NodeInput& input);
+2 -4
View File
@@ -51,10 +51,8 @@ QString TimeInput::Description() const
return tr("Generates the time (in seconds) at this frame.");
}
void TimeInput::Value(const QString &output, const NodeValueRow &value, const NodeGlobals &globals, NodeValueTable *table) const
void TimeInput::Value(const NodeValueRow &value, const NodeGlobals &globals, NodeValueTable *table) const
{
Q_UNUSED(output)
table->Push(NodeValue::kFloat,
globals.time().in().toDouble(),
this,
@@ -62,7 +60,7 @@ void TimeInput::Value(const QString &output, const NodeValueRow &value, const No
QStringLiteral("time"));
}
void TimeInput::Hash(const QString &output, QCryptographicHash &hash, const NodeGlobals &globals, const VideoParams &video_params) const
void TimeInput::Hash(const ValueHint &output, QCryptographicHash &hash, const NodeGlobals &globals, const VideoParams &video_params) const
{
Node::Hash(output, hash, globals, video_params);
+2 -2
View File
@@ -40,9 +40,9 @@ public:
virtual QVector<CategoryID> Category() const override;
virtual QString Description() const override;
virtual void Value(const QString& output, const NodeValueRow& value, const NodeGlobals &globals, NodeValueTable *table) const override;
virtual void Value(const NodeValueRow& value, const NodeGlobals &globals, NodeValueTable *table) const override;
virtual void Hash(const QString& output, QCryptographicHash& hash, const NodeGlobals &globals, const VideoParams& video_params) const override;
virtual void Hash(const ValueHint& output, QCryptographicHash& hash, const NodeGlobals &globals, const VideoParams& video_params) const override;
};
+1 -2
View File
@@ -59,10 +59,9 @@ void ValueNode::Retranslate()
SetComboBoxStrings(kTypeInput, type_names);
}
void ValueNode::Value(const QString &output, const NodeValueRow &value, const NodeGlobals &globals, NodeValueTable *table) const
void ValueNode::Value(const NodeValueRow &value, const NodeGlobals &globals, NodeValueTable *table) const
{
Q_UNUSED(globals)
Q_UNUSED(output)
// Ensure value is pushed onto the table
table->Push(value[kValueInput]);
+1 -1
View File
@@ -63,7 +63,7 @@ public:
virtual void Retranslate() override;
virtual void Value(const QString &output, const NodeValueRow& value, const NodeGlobals &globals, NodeValueTable *table) const override;
virtual void Value(const NodeValueRow& value, const NodeGlobals &globals, NodeValueTable *table) const override;
protected:
virtual void InputValueChangedEvent(const QString &input, int element) override;
+1 -3
View File
@@ -88,10 +88,8 @@ ShaderCode MathNode::GetShaderCode(const QString &shader_id) const
return GetShaderCodeInternal(shader_id, kParamAIn, kParamBIn);
}
void MathNode::Value(const QString &output, const NodeValueRow &value, const NodeGlobals &globals, NodeValueTable *table) const
void MathNode::Value(const NodeValueRow &value, const NodeGlobals &globals, NodeValueTable *table) const
{
Q_UNUSED(output)
// Auto-detect what values to operate with
// FIXME: Very inefficient
NodeValueTable at, bt;
+1 -1
View File
@@ -54,7 +54,7 @@ public:
SetStandardValue(kMethodIn, o);
}
virtual void Value(const QString& output, const NodeValueRow& value, const NodeGlobals &globals, NodeValueTable *table) const override;
virtual void Value(const NodeValueRow& value, const NodeGlobals &globals, NodeValueTable *table) const override;
virtual void ProcessSamples(const NodeValueRow &values, const SampleBufferPtr input, SampleBufferPtr output, int index) const override;
+8 -10
View File
@@ -73,10 +73,8 @@ ShaderCode MergeNode::GetShaderCode(const QString &shader_id) const
return ShaderCode(FileFunctions::ReadFileAsString(":/shaders/alphaover.frag"));
}
void MergeNode::Value(const QString &output, const NodeValueRow &value, const NodeGlobals &globals, NodeValueTable *table) const
void MergeNode::Value(const NodeValueRow &value, const NodeGlobals &globals, NodeValueTable *table) const
{
Q_UNUSED(output)
ShaderJob job;
job.InsertValue(value);
@@ -102,12 +100,12 @@ void MergeNode::Value(const QString &output, const NodeValueRow &value, const No
}
}
void MergeNode::Hash(const QString &output, QCryptographicHash &hash, const NodeGlobals &globals, const VideoParams &video_params) const
void MergeNode::Hash(const ValueHint &output, QCryptographicHash &hash, const NodeGlobals &globals, const VideoParams &video_params) const
{
NodeTraverser traverser;
traverser.SetCacheVideoParams(video_params);
NodeValueDatabase db = traverser.GenerateDatabase(this, output, globals.time());
NodeValueDatabase db = traverser.GenerateDatabase(this, globals.time());
TexturePtr base_tex = db[kBaseIn].Get(NodeValue::kTexture).value<TexturePtr>();
TexturePtr blend_tex = db[kBlendIn].Get(NodeValue::kTexture).value<TexturePtr>();
@@ -118,17 +116,17 @@ void MergeNode::Hash(const QString &output, QCryptographicHash &hash, const Node
if (!passthrough_base && !passthrough_blend) {
// This merge will actually do something so we add a fingerprint
HashAddNodeSignature(hash, output);
HashAddNodeSignature(hash);
}
if (!passthrough_base) {
NodeOutput blend_output = GetConnectedOutput(kBlendIn);
blend_output.node()->Hash(blend_output.output(), hash, globals, video_params);
Node *blend_output = GetConnectedOutput(kBlendIn);
blend_output->Hash(GetValueHintForInput(kBlendIn, -1), hash, globals, video_params);
}
if (!passthrough_blend) {
NodeOutput base_output = GetConnectedOutput(kBaseIn);
base_output.node()->Hash(base_output.output(), hash, globals, video_params);
Node *base_output = GetConnectedOutput(kBaseIn);
base_output->Hash(GetValueHintForInput(kBaseIn, -1), hash, globals, video_params);
}
Q_ASSERT(!passthrough_base || !passthrough_blend);
+2 -2
View File
@@ -43,12 +43,12 @@ public:
virtual void Retranslate() override;
virtual ShaderCode GetShaderCode(const QString &shader_id) const override;
virtual void Value(const QString& output, const NodeValueRow& value, const NodeGlobals &globals, NodeValueTable *table) const override;
virtual void Value(const NodeValueRow& value, const NodeGlobals &globals, NodeValueTable *table) const override;
static const QString kBaseIn;
static const QString kBlendIn;
virtual void Hash(const QString& output, QCryptographicHash &hash, const NodeGlobals &globals, const VideoParams& video_params) const override;
virtual void Hash(const ValueHint& output, QCryptographicHash &hash, const NodeGlobals &globals, const VideoParams& video_params) const override;
private:
NodeInput* base_in_;
+1 -3
View File
@@ -76,10 +76,8 @@ void TrigonometryNode::Retranslate()
SetInputName(kMethodIn, tr("Method"));
}
void TrigonometryNode::Value(const QString &output, const NodeValueRow &value, const NodeGlobals &globals, NodeValueTable *table) const
void TrigonometryNode::Value(const NodeValueRow &value, const NodeGlobals &globals, NodeValueTable *table) const
{
Q_UNUSED(output)
double x = value[kXIn].data().toFloat();
switch (static_cast<Operation>(GetStandardValue(kMethodIn).toInt())) {
+1 -1
View File
@@ -42,7 +42,7 @@ public:
virtual void Retranslate() override;
virtual void Value(const QString& output, const NodeValueRow& value, const NodeGlobals &globals, NodeValueTable *table) const override;
virtual void Value(const NodeValueRow& value, const NodeGlobals &globals, NodeValueTable *table) const override;
static const QString kMethodIn;
static const QString kXIn;
+66 -83
View File
@@ -35,6 +35,7 @@
#include "project/project.h"
#include "ui/colorcoding.h"
#include "ui/icons/icons.h"
#include "widget/nodeparamview/nodeparamviewundo.h"
#include "widget/nodeview/nodeviewundo.h"
namespace olive {
@@ -50,7 +51,6 @@ Node::Node() :
operation_stack_(0),
cache_result_(false)
{
AddOutput();
}
Node::~Node()
@@ -122,19 +122,18 @@ void Node::Load(QXmlStreamReader *reader, XMLNodeData& xml_node_data, uint versi
}
QString output_node_id;
QString output_param_id;
while (XMLReadNextStartElement(reader)) {
if (reader->name() == QStringLiteral("node")) {
if ((version >= 210907 && reader->name() == QStringLiteral("output")) || reader->name() == QStringLiteral("node")) {
output_node_id = reader->readElementText();
} else if (reader->name() == QStringLiteral("output")) {
output_param_id = reader->readElementText();
} else if (version < 210907 && reader->name() == QStringLiteral("output")) {
qDebug() << "FIXME: Convert output string to ValueHint";
} else {
reader->skipCurrentElement();
}
}
xml_node_data.desired_connections.append({NodeInput(this, param_id, ele), output_node_id.toULongLong(), output_param_id});
xml_node_data.desired_connections.append({NodeInput(this, param_id, ele), output_node_id.toULongLong()});
} else {
reader->skipCurrentElement();
}
@@ -173,8 +172,7 @@ void Node::Save(QXmlStreamWriter *writer) const
writer->writeAttribute(QStringLiteral("input"), it->first.input());
writer->writeAttribute(QStringLiteral("element"), QString::number(it->first.element()));
writer->writeTextElement(QStringLiteral("node"), QString::number(reinterpret_cast<quintptr>(it->second.node())));
writer->writeTextElement(QStringLiteral("output"), it->second.output());
writer->writeTextElement(QStringLiteral("output"), QString::number(reinterpret_cast<quintptr>(it->second)));
writer->writeEndElement(); // connection
}
@@ -248,25 +246,25 @@ QBrush Node::brush(qreal top, qreal bottom) const
}
}
void Node::ConnectEdge(const NodeOutput &output, const NodeInput &input)
void Node::ConnectEdge(Node *output, const NodeInput &input)
{
// Ensure graph is the same
Q_ASSERT(input.node()->parent() == output.node()->parent());
Q_ASSERT(input.node()->parent() == output->parent());
// Ensure a connection isn't getting overwritten
Q_ASSERT(input.node()->input_connections().find(input) == input.node()->input_connections().end());
// Insert connection on both sides
input.node()->input_connections_[input] = output;
output.node()->output_connections_.push_back(std::pair<NodeOutput, NodeInput>({output, input}));
output->output_connections_.push_back(std::pair<Node*, NodeInput>({output, input}));
// Call internal events
input.node()->InputConnectedEvent(input.input(), input.element(), output);
output.node()->OutputConnectedEvent(output.output(), input);
output->OutputConnectedEvent(input);
// Emit signals
emit input.node()->InputConnected(output, input);
emit output.node()->OutputConnected(output, input);
emit output->OutputConnected(output, input);
// Invalidate all if this node isn't ignoring this input
if (!input.node()->ignore_connections_.contains(input.input())) {
@@ -274,10 +272,10 @@ void Node::ConnectEdge(const NodeOutput &output, const NodeInput &input)
}
}
void Node::DisconnectEdge(const NodeOutput &output, const NodeInput &input)
void Node::DisconnectEdge(Node *output, const NodeInput &input)
{
// Ensure graph is the same
Q_ASSERT(input.node()->parent() == output.node()->parent());
Q_ASSERT(input.node()->parent() == output->parent());
// Ensure connection exists
Q_ASSERT(input.node()->input_connections().at(input) == output);
@@ -286,15 +284,15 @@ void Node::DisconnectEdge(const NodeOutput &output, const NodeInput &input)
InputConnections& inputs = input.node()->input_connections_;
inputs.erase(inputs.find(input));
OutputConnections& outputs = output.node()->output_connections_;
outputs.erase(std::find(outputs.begin(), outputs.end(), std::pair<NodeOutput, NodeInput>({output, input})));
OutputConnections& outputs = output->output_connections_;
outputs.erase(std::find(outputs.begin(), outputs.end(), std::pair<Node*, NodeInput>({output, input})));
// Call internal events
input.node()->InputDisconnectedEvent(input.input(), input.element(), output);
output.node()->OutputDisconnectedEvent(output.output(), input);
output->OutputDisconnectedEvent(input);
emit input.node()->InputDisconnected(output, input);
emit output.node()->OutputDisconnected(output, input);
emit output->OutputDisconnected(output, input);
if (!input.node()->ignore_connections_.contains(input.input())) {
input.node()->InvalidateAll(input.input(), input.element());
@@ -437,10 +435,10 @@ void Node::SetInputIsKeyframing(const QString &input, bool e, int element)
bool Node::IsInputConnected(const QString &input, int element) const
{
return GetConnectedOutput(input, element).IsValid();
return GetConnectedOutput(input, element);
}
NodeOutput Node::GetConnectedOutput(const QString &input, int element) const
Node *Node::GetConnectedOutput(const QString &input, int element) const
{
for (auto it=input_connections_.cbegin(); it!=input_connections_.cend(); it++) {
if (it->first.input() == input && it->first.element() == element) {
@@ -448,7 +446,7 @@ NodeOutput Node::GetConnectedOutput(const QString &input, int element) const
}
}
return NodeOutput();
return nullptr;
}
bool Node::IsUsingStandardValue(const QString &input, int track, int element) const
@@ -1013,10 +1011,9 @@ Node::InputFlags Node::GetInputFlags(const QString &input) const
}
}
void Node::Value(const QString& output, const NodeValueRow& value, const NodeGlobals &globals, NodeValueTable *table) const
void Node::Value(const NodeValueRow& value, const NodeGlobals &globals, NodeValueTable *table) const
{
// Do nothing
Q_UNUSED(output)
Q_UNUSED(value)
Q_UNUSED(globals)
Q_UNUSED(table)
@@ -1092,19 +1089,19 @@ void Node::CopyDependencyGraph(const QVector<Node *> &src, const QVector<Node *>
for (auto it=src_node->input_connections_.cbegin(); it!=src_node->input_connections_.cend(); it++) {
// Determine if the connected node is in our src list
int connection_index = src.indexOf(it->second.node());
int connection_index = src.indexOf(it->second);
if (connection_index > -1) {
// Find the equivalent node in the dst list
Node* dst_connection = dst.at(connection_index);
NodeOutput copied_output = NodeOutput(dst_connection, it->second.output());
Node *copied_output = dst.at(connection_index);
NodeInput copied_input = NodeInput(dst_node, it->first.input(), it->first.element());
if (command) {
command->add_child(new NodeEdgeAddCommand(copied_output, copied_input));
command->add_child(new NodeSetValueHintCommand(copied_input, src_node->GetValueHintForInput(copied_input.input(), copied_input.element())));
} else {
ConnectEdge(copied_output, copied_input);
copied_input.node()->SetValueHintForInput(copied_input.input(), copied_input.element(), src_node->GetValueHintForInput(copied_input.input(), copied_input.element()));
}
}
}
@@ -1128,8 +1125,7 @@ Node *Node::CopyNodeAndDependencyGraphMinusItemsInternal(QMap<Node*, Node*>& cre
// Go through input connections and copy if non-item and connect if item
for (auto it=node->input_connections_.cbegin(); it!=node->input_connections_.cend(); it++) {
NodeInput input = it->first;
NodeOutput output = it->second;
Node* connected = output.node();
Node* connected = it->second;
Node* connected_copy;
if (connected->IsItem()) {
@@ -1144,8 +1140,9 @@ Node *Node::CopyNodeAndDependencyGraphMinusItemsInternal(QMap<Node*, Node*>& cre
}
}
command->add_child(new NodeEdgeAddCommand(NodeOutput(connected_copy, output.output()),
NodeInput(copy, input.input(), input.element())));
NodeInput copied_input(copy, input.input(), input.element());
command->add_child(new NodeEdgeAddCommand(connected_copy, copied_input));
command->add_child(new NodeSetValueHintCommand(copied_input, node->GetValueHintForInput(input.input(), input.element())));
}
if (node->parent()->GetPositionMap().contains(node)) {
@@ -1256,10 +1253,9 @@ bool Node::AreLinked(Node *a, Node *b)
return a->links_.contains(b);
}
void Node::HashAddNodeSignature(QCryptographicHash &hash, const QString &output) const
void Node::HashAddNodeSignature(QCryptographicHash &hash) const
{
hash.addData(id().toUtf8());
hash.addData(output.toUtf8());
}
void Node::InsertInput(const QString &id, NodeValue::Type type, const QVariant &default_value, Node::InputFlags flags, int index)
@@ -1306,32 +1302,6 @@ void Node::RemoveInput(const QString &id)
emit InputRemoved(id);
}
void Node::AddOutput(const QString &id)
{
if (id.isEmpty()) {
qWarning() << "Rejected adding output with an empty ID on node" << this->id();
return;
}
if (HasParamWithID(id)) {
qWarning() << "Failed to add output to node" << this->id() << "- param with ID" << id << "already exists";
return;
}
outputs_.append(id);
emit OutputAdded(id);
}
void Node::RemoveOutput(const QString &id)
{
if (outputs_.removeOne(id)) {
emit OutputRemoved(id);
} else {
ReportInvalidInput("remove", id);
}
}
void Node::ReportInvalidInput(const char *attempted_action, const QString& id) const
{
qWarning() << "Failed to" << attempted_action << "parameter" << id
@@ -1453,13 +1423,29 @@ void Node::SetLabel(const QString &s)
}
}
void Node::Hash(const QString &output, QCryptographicHash &hash, const NodeGlobals &globals, const VideoParams &video_params) const
QString Node::GetLabelAndName() const
{
if (GetLabel().isEmpty()) {
return Name();
} else {
return tr("%1 (%2)").arg(GetLabel(), Name());
}
}
QString Node::GetLabelOrName() const
{
if (GetLabel().isEmpty()) {
return Name();
}
return GetLabel();
}
void Node::Hash(const ValueHint &output, QCryptographicHash &hash, const NodeGlobals &globals, const VideoParams &video_params) const
{
// Add this Node's ID and output being used
HashAddNodeSignature(hash, output);
HashAddNodeSignature(hash);
auto inputs = inputs_for_output(output);
foreach (const QString& input, inputs) {
foreach (const QString& input, inputs()) {
// For each input, try to hash its value
if (ignore_when_hashing_.contains(input)) {
continue;
@@ -1557,10 +1543,9 @@ void Node::SetCanBeDeleted(bool s)
void GetDependenciesRecursively(QVector<Node*>& list, const Node* node, bool traverse, bool exclusive_only)
{
for (auto it=node->input_connections().cbegin(); it!=node->input_connections().cend(); it++) {
Node* connected_node = it->second.node();
Node* connected_node = it->second;
if (!exclusive_only
|| (connected_node->outputs().size() == 1 && !connected_node->IsItem())) {
if (!exclusive_only || !connected_node->IsItem()) {
if (!list.contains(connected_node)) {
list.append(connected_node);
@@ -1597,11 +1582,11 @@ void Node::HashInputElement(QCryptographicHash &hash, const QString& input, int
if (IsInputConnected(input, element)) {
// Traverse down this edge
NodeOutput output = GetConnectedOutput(input, element);
Node *output = GetConnectedOutput(input, element);
NodeGlobals new_globals = globals;
new_globals.set_time(input_time);
output.node()->Hash(output.output(), hash, new_globals, video_params);
output->Hash(GetValueHintForInput(input, element), hash, new_globals, video_params);
} else {
// Grab the value at this time
QVariant value = GetValueAtTime(input, input_time.in(), element);
@@ -1655,7 +1640,7 @@ bool Node::OutputsTo(Node *n, bool recursively, const OutputConnections &ignore_
return true;
} else if (recursively && connected->OutputsTo(n, recursively, ignore_edges, added_edge)) {
return true;
} else if (added_edge.first.node() == this) {
} else if (added_edge.first == this) {
Node *proposed_connected = added_edge.second.node();
if (proposed_connected == n) {
@@ -1702,11 +1687,11 @@ bool Node::OutputsTo(const NodeInput &input, bool recursively) const
bool Node::InputsFrom(Node *n, bool recursively) const
{
for (auto it=input_connections_.cbegin(); it!=input_connections_.cend(); it++) {
const NodeOutput& connected = it->second;
Node *connected = it->second;
if (connected.node() == n) {
if (connected == n) {
return true;
} else if (recursively && connected.node()->InputsFrom(n, recursively)) {
} else if (recursively && connected->InputsFrom(n, recursively)) {
return true;
}
}
@@ -1717,11 +1702,11 @@ bool Node::InputsFrom(Node *n, bool recursively) const
bool Node::InputsFrom(const QString &id, bool recursively) const
{
for (auto it=input_connections_.cbegin(); it!=input_connections_.cend(); it++) {
const NodeOutput& connected = it->second;
Node *connected = it->second;
if (connected.node()->id() == id) {
if (connected->id() == id) {
return true;
} else if (recursively && connected.node()->InputsFrom(id, recursively)) {
} else if (recursively && connected->InputsFrom(id, recursively)) {
return true;
}
}
@@ -1808,7 +1793,7 @@ QVector<TimeRange> Node::TransformTimeTo(const TimeRange &time, Node *target, bo
// If this input is connected, traverse it to see if we stumble across the specified `node`
for (auto it=input_connections_.cbegin(); it!=input_connections_.cend(); it++) {
TimeRange input_adjustment = InputTimeAdjustment(it->first.input(), it->first.element(), time);
Node* connected = it->second.node();
Node* connected = it->second;
if (connected == target) {
// We found the target, no need to keep traversing
@@ -2121,29 +2106,27 @@ void Node::InputValueChangedEvent(const QString &input, int element)
Q_UNUSED(element)
}
void Node::InputConnectedEvent(const QString &input, int element, const NodeOutput &output)
void Node::InputConnectedEvent(const QString &input, int element, Node *output)
{
Q_UNUSED(input)
Q_UNUSED(element)
Q_UNUSED(output)
}
void Node::InputDisconnectedEvent(const QString &input, int element, const NodeOutput &output)
void Node::InputDisconnectedEvent(const QString &input, int element, Node *output)
{
Q_UNUSED(input)
Q_UNUSED(element)
Q_UNUSED(output)
}
void Node::OutputConnectedEvent(const QString &output, const NodeInput &input)
void Node::OutputConnectedEvent(const NodeInput &input)
{
Q_UNUSED(output)
Q_UNUSED(input)
}
void Node::OutputDisconnectedEvent(const QString &output, const NodeInput &input)
void Node::OutputDisconnectedEvent(const NodeInput &input)
{
Q_UNUSED(output)
Q_UNUSED(input)
}
+28 -61
View File
@@ -198,30 +198,14 @@ public:
return input_ids_;
}
virtual QVector<QString> inputs_for_output(const QString& output) const
{
Q_UNUSED(output)
return inputs();
}
const QVector<QString>& outputs() const
{
return outputs_;
}
bool HasInputWithID(const QString& id) const
{
return input_ids_.contains(id);
}
bool HasOutputWithID(const QString& id) const
{
return outputs_.contains(id);
}
bool HasParamWithID(const QString& id) const
{
return HasInputWithID(id) || HasOutputWithID(id);
return HasInputWithID(id);
}
/**
@@ -255,9 +239,9 @@ public:
}
}
static void ConnectEdge(const NodeOutput& output, const NodeInput& input);
static void ConnectEdge(Node *output, const NodeInput& input);
static void DisconnectEdge(const NodeOutput& output, const NodeInput& input);
static void DisconnectEdge(Node *output, const NodeInput& input);
QString GetInputName(const QString& id) const;
@@ -295,23 +279,13 @@ public:
return IsInputStatic(input.input(), input.element());
}
NodeOutput GetConnectedOutput(const QString& input, int element = -1) const;
Node *GetConnectedOutput(const QString& input, int element = -1) const;
NodeOutput GetConnectedOutput(const NodeInput& input) const
Node *GetConnectedOutput(const NodeInput& input) const
{
return GetConnectedOutput(input.input(), input.element());
}
Node* GetConnectedNode(const QString& input, int element = -1) const
{
return GetConnectedOutput(input, element).node();
}
Node* GetConnectedNode(const NodeInput& input) const
{
return GetConnectedNode(input.input(), input.element());
}
bool IsUsingStandardValue(const QString& input, int track, int element = -1) const;
NodeValue::Type GetInputDataType(const QString& id) const;
@@ -494,19 +468,19 @@ public:
QString tag;
};
ValueHint GetValueHintForInput(const QString &input) const
ValueHint GetValueHintForInput(const QString &input, int element) const
{
return value_hints_.value(input);
return value_hints_.value({input, element});
}
void SetValueHintForInput(const QString &input, const ValueHint &hint)
void SetValueHintForInput(const QString &input, int element, const ValueHint &hint)
{
value_hints_.insert(input, hint);
value_hints_.insert({input, element}, hint);
}
const NodeKeyframeTrack& GetTrackFromKeyframe(NodeKeyframe* key) const;
using InputConnections = std::map<NodeInput, NodeOutput>;
using InputConnections = std::map<NodeInput, Node*>;
/**
* @brief Return map of input connections
@@ -519,7 +493,7 @@ public:
return input_connections_;
}
using OutputConnection = std::pair<NodeOutput, NodeInput>;
using OutputConnection = std::pair<Node*, NodeInput>;
using OutputConnections = std::vector<OutputConnection>;
/**
@@ -739,7 +713,7 @@ public:
* corresponding output if it's connected to one. If your node doesn't directly deal with time, the default behavior
* of the NodeParam objects will handle everything related to it automatically.
*/
virtual void Value(const QString &output, const NodeValueRow& value, const NodeGlobals &globals, NodeValueTable *table) const;
virtual void Value(const NodeValueRow& value, const NodeGlobals &globals, NodeValueTable *table) const;
virtual bool HasGizmos() const;
@@ -752,7 +726,10 @@ public:
const QString& GetLabel() const;
void SetLabel(const QString& s);
virtual void Hash(const QString& output, QCryptographicHash& hash, const NodeGlobals &globals, const VideoParams& video_params) const;
QString GetLabelAndName() const;
QString GetLabelOrName() const;
virtual void Hash(const ValueHint &output, QCryptographicHash& hash, const NodeGlobals &globals, const VideoParams& video_params) const;
void InvalidateAll(const QString& input, int element = -1);
@@ -873,7 +850,7 @@ protected:
};
void HashAddNodeSignature(QCryptographicHash &hash, const QString &output) const;
void HashAddNodeSignature(QCryptographicHash &hash) const;
void InsertInput(const QString& id, NodeValue::Type type, const QVariant& default_value, InputFlags flags, int index);
@@ -899,10 +876,6 @@ protected:
void RemoveInput(const QString& id);
void AddOutput(const QString& id = kDefaultOutput);
void RemoveOutput(const QString& id);
void SetInputName(const QString& id, const QString& name);
void SetComboBoxStrings(const QString& id, const QStringList& strings)
@@ -954,13 +927,13 @@ protected:
virtual void InputValueChangedEvent(const QString& input, int element);
virtual void InputConnectedEvent(const QString& input, int element, const NodeOutput& output);
virtual void InputConnectedEvent(const QString& input, int element, Node *output);
virtual void InputDisconnectedEvent(const QString& input, int element, const NodeOutput& output);
virtual void InputDisconnectedEvent(const QString& input, int element, Node *output);
virtual void OutputConnectedEvent(const QString& output, const NodeInput& input);
virtual void OutputConnectedEvent(const NodeInput& input);
virtual void OutputDisconnectedEvent(const QString& output, const NodeInput& input);
virtual void OutputDisconnectedEvent(const NodeInput& input);
virtual void childEvent(QChildEvent *event) override;
@@ -984,13 +957,13 @@ signals:
void ValueChanged(const NodeInput& input, const TimeRange& range);
void InputConnected(const NodeOutput& output, const NodeInput& input);
void InputConnected(Node *output, const NodeInput& input);
void InputDisconnected(const NodeOutput& output, const NodeInput& input);
void InputDisconnected(Node *output, const NodeInput& input);
void OutputConnected(const NodeOutput& output, const NodeInput& input);
void OutputConnected(Node *output, const NodeInput& input);
void OutputDisconnected(const NodeOutput& output, const NodeInput& input);
void OutputDisconnected(Node *output, const NodeInput& input);
void InputPropertyChanged(const QString& input, const QString& key, const QVariant& value);
@@ -1010,10 +983,6 @@ signals:
void InputRemoved(const QString& id);
void OutputAdded(const QString& id);
void OutputRemoved(const QString& id);
void InputNameChanged(const QString& id, const QString& name);
void InputDataTypeChanged(const QString& id, NodeValue::Type type);
@@ -1075,7 +1044,7 @@ private:
try {
NodeInput input(node_, input_, i);
NodeOutput output = node_->input_connections().at(input);
Node *output = node_->input_connections().at(input);
removed_connections_[input] = output;
@@ -1219,8 +1188,6 @@ private:
QVector<QString> input_ids_;
QVector<Input> input_data_;
QVector<QString> outputs_;
QMap<QString, NodeInputImmediate*> standard_immediates_;
QMap<QString, QVector<NodeInputImmediate*> > array_immediates_;
@@ -1237,7 +1204,7 @@ private:
bool cache_result_;
QMap<QString, ValueHint> value_hints_;
QMap<InputElementPair, ValueHint> value_hints_;
private slots:
/**
@@ -1271,7 +1238,7 @@ template<class T>
void Node::FindInputNodeInternal(const Node* n, QVector<T *> &list)
{
for (auto it=n->input_connections_.cbegin(); it!=n->input_connections_.cend(); it++) {
Node* edge = it->second.node();
Node* edge = it->second;
T* cast_test = dynamic_cast<T*>(edge);
if (cast_test) {
+15 -24
View File
@@ -72,6 +72,14 @@ Node *Track::copy() const
QString Track::Name() const
{
if (track_type_ == Track::kVideo) {
return tr("Video Track %1").arg(index_);
} else if (track_type_ == Track::kAudio) {
return tr("Audio Track %1").arg(index_);
} else if (track_type_ == Track::kSubtitle) {
return tr("Subtitle Track %1").arg(index_);
}
return tr("Track");
}
@@ -145,7 +153,7 @@ void Track::SaveCustom(QXmlStreamWriter *writer) const
writer->writeTextElement(QStringLiteral("height"), QString::number(GetTrackHeight()));
}
void Track::InputConnectedEvent(const QString &input, int element, const NodeOutput &output)
void Track::InputConnectedEvent(const QString &input, int element, Node *output)
{
if (input == kBlockInput) {
if (element == -1) {
@@ -155,7 +163,7 @@ void Track::InputConnectedEvent(const QString &input, int element, const NodeOut
}
// Check if a block was connected, if not, ignore
Block* block = dynamic_cast<Block*>(output.node());
Block* block = dynamic_cast<Block*>(output);
if (!block) {
return;
@@ -220,7 +228,7 @@ void Track::InputConnectedEvent(const QString &input, int element, const NodeOut
}
}
void Track::InputDisconnectedEvent(const QString &input, int element, const NodeOutput &output)
void Track::InputDisconnectedEvent(const QString &input, int element, Node *output)
{
if (input == kBlockInput) {
if (element == -1) {
@@ -229,7 +237,7 @@ void Track::InputDisconnectedEvent(const QString &input, int element, const Node
return;
}
Block* b = dynamic_cast<Block*>(output.node());
Block* b = dynamic_cast<Block*>(output);
if (!b) {
return;
@@ -425,7 +433,7 @@ void Track::InvalidateCache(const TimeRange& range, const QString& from, int ele
if (from == kBlockInput
&& element >= 0
&& (b = dynamic_cast<const Block*>(GetConnectedOutput(from, element).node()))
&& (b = dynamic_cast<const Block*>(GetConnectedOutput(from, element)))
&& !options.value(QStringLiteral("lengthevent")).toBool()) {
// Limit the range signal to the corresponding block
TimeRange transformed = TransformRangeFromBlock(b, range);
@@ -553,23 +561,6 @@ rational Track::track_length() const
}
}
QString Track::GetDefaultTrackName(Track::Type type, int index)
{
// Starts tracks at 1 rather than 0
int user_friendly_index = index+1;
switch (type) {
case Track::kVideo: return tr("Video %1").arg(user_friendly_index);
case Track::kAudio: return tr("Audio %1").arg(user_friendly_index);
case Track::kSubtitle: return tr("Subtitle %1").arg(user_friendly_index);
case Track::kNone:
case Track::kCount:
break;
}
return tr("Track %1").arg(user_friendly_index);
}
bool Track::IsMuted() const
{
return GetStandardValue(kMutedInput).toBool();
@@ -580,7 +571,7 @@ bool Track::IsLocked() const
return locked_;
}
void Track::Hash(const QString &output, QCryptographicHash &hash, const NodeGlobals &globals, const VideoParams &video_params) const
void Track::Hash(const Node::ValueHint &output, QCryptographicHash &hash, const NodeGlobals &globals, const VideoParams &video_params) const
{
Q_UNUSED(output)
@@ -590,7 +581,7 @@ void Track::Hash(const QString &output, QCryptographicHash &hash, const NodeGlob
if (b) {
NodeGlobals new_globals = globals;
new_globals.set_time(TransformRangeForBlock(b, globals.time()));
b->Hash(kDefaultOutput, hash, new_globals, video_params);
b->Hash(GetValueHintForInput(kBlockInput, GetArrayIndexFromBlock(b)), hash, new_globals, video_params);
}
}
+5 -7
View File
@@ -355,13 +355,13 @@ public:
rational track_length() const;
static QString GetDefaultTrackName(Track::Type type, int index);
bool IsMuted() const;
bool IsLocked() const;
virtual void Hash(const QString& output, QCryptographicHash& hash, const NodeGlobals &globals, const VideoParams& video_params) const override;
virtual void Hash(const Node::ValueHint& output, QCryptographicHash& hash, const NodeGlobals &globals, const VideoParams& video_params) const override;
int GetArrayIndexFromBlock(Block* block) const;
static const double kTrackHeightDefault;
static const double kTrackHeightMinimum;
@@ -416,17 +416,15 @@ protected:
virtual void SaveCustom(QXmlStreamWriter* writer) const override;
virtual void InputConnectedEvent(const QString& input, int element, const NodeOutput& output) override;
virtual void InputConnectedEvent(const QString& input, int element, Node *output) override;
virtual void InputDisconnectedEvent(const QString& input, int element, const NodeOutput& output) override;
virtual void InputDisconnectedEvent(const QString& input, int element, Node *output) override;
virtual void InputValueChangedEvent(const QString& input, int element) override;
private:
void UpdateInOutFrom(int index);
int GetArrayIndexFromBlock(Block* block) const;
int GetArrayIndexFromCacheIndex(int index) const;
int GetCacheIndexFromArrayIndex(int index) const;
+6 -20
View File
@@ -252,20 +252,6 @@ void ViewerOutput::InvalidateCache(const TimeRange& range, const QString& from,
super::InvalidateCache(range, from, element, options);
}
QVector<QString> ViewerOutput::inputs_for_output(const QString &output) const
{
QVector<QString> inputs;
Track::Type type = Track::Reference::TypeFromString(output);
if (type == Track::kVideo) {
inputs.append(kTextureInput);
} else if (type == Track::kAudio) {
inputs.append(kSamplesInput);
}
return inputs;
}
QVector<Track::Reference> ViewerOutput::GetEnabledStreamsAsReferences() const
{
QVector<Track::Reference> refs;
@@ -329,7 +315,7 @@ void ViewerOutput::VerifyLength()
}
}
void ViewerOutput::InputConnectedEvent(const QString &input, int element, const NodeOutput &output)
void ViewerOutput::InputConnectedEvent(const QString &input, int element, Node *output)
{
if (input == kTextureInput) {
emit TextureInputChanged();
@@ -338,7 +324,7 @@ void ViewerOutput::InputConnectedEvent(const QString &input, int element, const
super::InputConnectedEvent(input, element, output);
}
void ViewerOutput::InputDisconnectedEvent(const QString &input, int element, const NodeOutput &output)
void ViewerOutput::InputDisconnectedEvent(const QString &input, int element, Node *output)
{
if (input == kTextureInput) {
emit TextureInputChanged();
@@ -354,7 +340,7 @@ rational ViewerOutput::VerifyLengthInternal(Track::Type type) const
switch (type) {
case Track::kVideo:
if (IsInputConnected(kTextureInput)) {
NodeValueTable t = traverser.GenerateTable(GetConnectedOutput(kTextureInput), TimeRange(0, 0));
NodeValueTable t = traverser.GenerateTable(GetConnectedOutput(kTextureInput), GetValueHintForInput(kTextureInput, -1), TimeRange(0, 0));
rational r = t.Get(NodeValue::kRational, QStringLiteral("length")).value<rational>();
if (!r.isNaN()) {
return r;
@@ -363,7 +349,7 @@ rational ViewerOutput::VerifyLengthInternal(Track::Type type) const
break;
case Track::kAudio:
if (IsInputConnected(kSamplesInput)) {
NodeValueTable t = traverser.GenerateTable(GetConnectedOutput(kSamplesInput), TimeRange(0, 0));
NodeValueTable t = traverser.GenerateTable(GetConnectedOutput(kSamplesInput), GetValueHintForInput(kSamplesInput, -1), TimeRange(0, 0));
rational r = t.Get(NodeValue::kRational, QStringLiteral("length")).value<rational>();;
if (!r.isNaN()) {
return r;
@@ -379,12 +365,12 @@ rational ViewerOutput::VerifyLengthInternal(Track::Type type) const
return 0;
}
NodeOutput ViewerOutput::GetConnectedTextureOutput()
Node *ViewerOutput::GetConnectedTextureOutput()
{
return GetConnectedOutput(kTextureInput);
}
NodeOutput ViewerOutput::GetConnectedSampleOutput()
Node *ViewerOutput::GetConnectedSampleOutput()
{
return GetConnectedOutput(kSamplesInput);
}
+4 -6
View File
@@ -68,8 +68,6 @@ public:
virtual void InvalidateCache(const TimeRange& range, const QString& from, int element, InvalidateCacheOptions options) override;
virtual QVector<QString> inputs_for_output(const QString& output) const override;
VideoParams GetVideoParams(int index = 0) const
{
// This check isn't strictly necessary (GetStandardValue will return a null VideoParams anyway),
@@ -150,9 +148,9 @@ public:
virtual void Retranslate() override;
virtual NodeOutput GetConnectedTextureOutput();
virtual Node *GetConnectedTextureOutput();
virtual NodeOutput GetConnectedSampleOutput();
virtual Node *GetConnectedSampleOutput();
void SetViewerVideoCacheEnabled(bool e) { video_cache_enabled_ = e; }
void SetViewerAudioCacheEnabled(bool e) { audio_cache_enabled_ = e; }
@@ -207,9 +205,9 @@ public slots:
void VerifyLength();
protected:
virtual void InputConnectedEvent(const QString &input, int element, const NodeOutput &output) override;
virtual void InputConnectedEvent(const QString &input, int element, Node *output) override;
virtual void InputDisconnectedEvent(const QString &input, int element, const NodeOutput &output) override;
virtual void InputDisconnectedEvent(const QString &input, int element, Node *output) override;
virtual rational VerifyLengthInternal(Track::Type type) const;
+2 -8
View File
@@ -60,12 +60,12 @@ bool NodeInput::IsArray() const
}
}
NodeOutput NodeInput::GetConnectedOutput() const
Node *NodeInput::GetConnectedOutput() const
{
if (IsValid()) {
return node_->GetConnectedOutput(*this);
} else {
return NodeOutput();
return nullptr;
}
}
@@ -128,12 +128,6 @@ uint qHash(const NodeInput &i)
return qHash(i.node()) ^ qHash(i.input()) ^ qHash(i.element());
}
NodeOutput::NodeOutput(Node *n)
{
node_ = n;
output_ = Node::kDefaultOutput;
}
uint qHash(const NodeKeyframeTrackReference &i)
{
return qHash(i.input()) & qHash(i.track());
+25 -46
View File
@@ -41,51 +41,6 @@ struct NodeInputPair {
QString input;
};
/**
* @brief Defines a node output
*/
class NodeOutput
{
public:
NodeOutput(Node* n, const QString& o)
{
node_ = n;
output_ = o;
}
NodeOutput(Node* n);
NodeOutput()
{
node_ = nullptr;
}
bool operator==(const NodeOutput& rhs) const
{
return node_ == rhs.node_ && output_ == rhs.output_;
}
Node* node() const
{
return node_;
}
const QString& output() const
{
return output_;
}
bool IsValid() const
{
return node_;
}
private:
Node* node_;
QString output_;
};
/**
* @brief Defines a Node input
*/
@@ -166,7 +121,7 @@ public:
bool IsArray() const;
NodeOutput GetConnectedOutput() const;
Node *GetConnectedOutput() const;
NodeValue::Type GetDataType() const;
@@ -192,6 +147,30 @@ private:
};
struct InputElementPair {
QString input;
int element;
bool operator<(const InputElementPair &rhs) const
{
if (input != rhs.input) {
return input < rhs.input;
}
return element < rhs.element;
}
bool operator==(const InputElementPair &rhs) const
{
return input == rhs.input && element == rhs.element;
}
bool operator!=(const InputElementPair &rhs) const
{
return !(*this == rhs);
}
};
class NodeKeyframeTrackReference {
public:
NodeKeyframeTrackReference()
+4 -4
View File
@@ -84,10 +84,10 @@ int Folder::index_of_child_in_array(Node *item) const
return item_element_index_.at(index_of_item);
}
void Folder::InputConnectedEvent(const QString &input, int element, const NodeOutput &output)
void Folder::InputConnectedEvent(const QString &input, int element, Node *output)
{
if (input == kChildInput && element != -1) {
Node* item = output.node();
Node* item = output;
// The insert index is always our "count" because we only support appending in our internal
// model. For sorting/organizing, a QSortFilterProxyModel is used instead.
@@ -99,10 +99,10 @@ void Folder::InputConnectedEvent(const QString &input, int element, const NodeOu
}
}
void Folder::InputDisconnectedEvent(const QString &input, int element, const NodeOutput &output)
void Folder::InputDisconnectedEvent(const QString &input, int element, Node *output)
{
if (input == kChildInput && element != -1) {
Node* item = output.node();
Node* item = output;
int child_index = item_children_.indexOf(item);
emit BeginRemoveItem(item, child_index);
+2 -2
View File
@@ -170,9 +170,9 @@ signals:
void EndRemoveItem();
protected:
virtual void InputConnectedEvent(const QString& input, int element, const NodeOutput& output) override;
virtual void InputConnectedEvent(const QString& input, int element, Node *output) override;
virtual void InputDisconnectedEvent(const QString& input, int element, const NodeOutput& output) override;
virtual void InputDisconnectedEvent(const QString& input, int element, Node *output) override;
private:
template<typename T>
+38 -37
View File
@@ -73,12 +73,6 @@ void Footage::Retranslate()
SetComboBoxStrings(kLoopModeInput, {tr("None"), tr("Loop"), tr("Clamp")});
}
QVector<QString> Footage::inputs_for_output(const QString &output) const
{
Q_UNUSED(output)
return {kFilenameInput, kLoopModeInput};
}
bool Footage::LoadCustom(QXmlStreamReader *reader, XMLNodeData &xml_node_data, uint version, const QAtomicInt* cancelled)
{
if (reader->name() == QStringLiteral("timestamp")) {
@@ -280,6 +274,24 @@ int Footage::GetStreamIndex(Track::Type type, int index) const
}
}
Track::Reference Footage::GetReferenceFromRealIndex(int real_index) const
{
// Check video streams
for (int i=0; i<GetVideoStreamCount(); i++) {
if (GetVideoParams(i).stream_index() == real_index) {
return Track::Reference(Track::kVideo, i);
}
}
for (int i=0; i<GetAudioStreamCount(); i++) {
if (GetAudioParams(i).stream_index() == real_index) {
return Track::Reference(Track::kAudio, i);
}
}
return Track::Reference();
}
const QString &Footage::decoder() const
{
return decoder_;
@@ -323,27 +335,16 @@ QString Footage::DescribeAudioStream(const AudioParams &params)
QString::number(params.sample_rate()));
}
void Footage::Hash(const QString& output, QCryptographicHash &hash, const NodeGlobals &globals, const VideoParams &video_params) const
void Footage::Hash(const Node::ValueHint& output, QCryptographicHash &hash, const NodeGlobals &globals, const VideoParams &video_params) const
{
super::Hash(output, hash, globals, video_params);
// Footage last modified date
hash.addData(QString::number(timestamp()).toUtf8());
// Translate output ID to stream
Track::Reference ref = Track::Reference::FromString(output);
for (int i=0; i<GetVideoStreamCount(); i++) {
VideoParams params = GetVideoParams(i);
if (ref.type() == Track::kVideo) {
VideoParams params = GetVideoParams(ref.index());
if (params.is_valid()) {
// Add footage details to hash
QString fn = filename();
// Footage stream
hash.addData(QString::number(ref.index()).toUtf8());
if (!fn.isEmpty()) {
// Current color config and space
hash.addData(project()->color_manager()->GetConfigFilename().toUtf8());
hash.addData(GetColorspaceToUse(params).toUtf8());
@@ -370,16 +371,12 @@ void Footage::Hash(const QString& output, QCryptographicHash &hash, const NodeGl
hash.addData(reinterpret_cast<const char*>(&start_time), sizeof(start_time));
}
}
}
}
}
void Footage::Value(const QString &output, const NodeValueRow &value, const NodeGlobals &globals, NodeValueTable *table) const
void Footage::Value(const NodeValueRow &value, const NodeGlobals &globals, NodeValueTable *table) const
{
Q_UNUSED(globals)
Track::Reference ref = Track::Reference::FromString(output);
// Pop filename from table
QString file = value[kFilenameInput].data().toString();
@@ -387,6 +384,12 @@ void Footage::Value(const QString &output, const NodeValueRow &value, const Node
// If the file exists and the reference is valid, push a footage job to the renderer
if (QFileInfo(file).exists()) {
// Push length
table->Push(NodeValue::kRational, QVariant::fromValue(GetLength()), this, false, QStringLiteral("length"));
// Push each stream as a footage job
for (int i=0; i<GetTotalStreamCount(); i++) {
Track::Reference ref = GetReferenceFromRealIndex(i);
FootageJob job(decoder_, filename(), ref.type(), GetLength(), loop_mode);
if (ref.type() == Track::kVideo) {
@@ -402,8 +405,8 @@ void Footage::Value(const QString &output, const NodeValueRow &value, const Node
job.set_cache_path(project()->cache_path());
}
table->Push(NodeValue::kRational, QVariant::fromValue(GetLength()), this, false, QStringLiteral("length"));
table->Push(NodeValue::kFootageJob, QVariant::fromValue(job), this);
table->Push(NodeValue::kFootageJob, QVariant::fromValue(job), this, false, ref.ToString());
}
}
}
@@ -424,23 +427,21 @@ QString Footage::GetStreamTypeName(Track::Type type)
return tr("Unknown");
}
NodeOutput Footage::GetConnectedTextureOutput()
Node *Footage::GetConnectedTextureOutput()
{
QString output = Track::Reference(Track::kVideo, 0).ToString();
if (HasOutputWithID(output)) {
return NodeOutput(this, output);
if (GetVideoStreamCount() > 0) {
return this;
} else {
return NodeOutput();
return nullptr;
}
}
NodeOutput Footage::GetConnectedSampleOutput()
Node *Footage::GetConnectedSampleOutput()
{
QString output = Track::Reference(Track::kAudio, 0).ToString();
if (HasOutputWithID(output)) {
return NodeOutput(this, output);
if (GetAudioStreamCount() > 0) {
return this;
} else {
return NodeOutput();
return nullptr;
}
}
+4 -6
View File
@@ -84,8 +84,6 @@ public:
virtual void Retranslate() override;
virtual QVector<QString> inputs_for_output(const QString &output) const override;
/**
* @brief Reset Footage state ready for running through Probe() again
*
@@ -181,15 +179,15 @@ public:
static QString DescribeVideoStream(const VideoParams& params);
static QString DescribeAudioStream(const AudioParams& params);
virtual void Hash(const QString& output, QCryptographicHash &hash, const NodeGlobals &globals, const VideoParams& video_params) const override;
virtual void Hash(const ValueHint &output, QCryptographicHash &hash, const NodeGlobals &globals, const VideoParams& video_params) const override;
virtual void Value(const QString &output, const NodeValueRow& value, const NodeGlobals &globals, NodeValueTable *table) const override;
virtual void Value(const NodeValueRow& value, const NodeGlobals &globals, NodeValueTable *table) const override;
static QString GetStreamTypeName(Track::Type type);
virtual NodeOutput GetConnectedTextureOutput() override;
virtual Node *GetConnectedTextureOutput() override;
virtual NodeOutput GetConnectedSampleOutput() override;
virtual Node *GetConnectedSampleOutput() override;
static rational AdjustTimeByLoopMode(rational time, LoopMode loop_mode, const rational& length, VideoParams::Type type, const rational &timebase);
+4 -4
View File
@@ -137,12 +137,12 @@ rational Sequence::VerifyLengthInternal(Track::Type type) const
return 0;
}
void Sequence::InputConnectedEvent(const QString &input, int element, const NodeOutput &output)
void Sequence::InputConnectedEvent(const QString &input, int element, Node *output)
{
foreach (TrackList* list, track_lists_) {
if (list->track_input() == input) {
// Return because we found our input
list->TrackConnected(output.node(), element);
list->TrackConnected(output, element);
return;
}
}
@@ -150,12 +150,12 @@ void Sequence::InputConnectedEvent(const QString &input, int element, const Node
super::InputConnectedEvent(input, element, output);
}
void Sequence::InputDisconnectedEvent(const QString &input, int element, const NodeOutput &output)
void Sequence::InputDisconnectedEvent(const QString &input, int element, Node *output)
{
foreach (TrackList* list, track_lists_) {
if (list->track_input() == input) {
// Return because we found our input
list->TrackDisconnected(output.node(), element);
list->TrackDisconnected(output, element);
return;
}
}
+2 -2
View File
@@ -97,9 +97,9 @@ public:
}
protected:
virtual void InputConnectedEvent(const QString &input, int element, const NodeOutput &output) override;
virtual void InputConnectedEvent(const QString &input, int element, Node *output) override;
virtual void InputDisconnectedEvent(const QString &input, int element, const NodeOutput &output) override;
virtual void InputDisconnectedEvent(const QString &input, int element, Node *output) override;
virtual rational VerifyLengthInternal(Track::Type type) const override;
+4 -9
View File
@@ -34,6 +34,7 @@ TimeRemapNode::TimeRemapNode()
AddInput(kTimeInput, NodeValue::kRational, QVariant::fromValue(rational(0)), InputFlags(kInputFlagNotConnectable));
SetInputProperty(kTimeInput, QStringLiteral("view"), RationalSlider::kTime);
SetInputProperty(kTimeInput, QStringLiteral("viewlock"), true);
IgnoreHashingFrom(kTimeInput);
AddInput(kInputInput, NodeValue::kNone, InputFlags(kInputFlagNotKeyframable));
}
@@ -92,22 +93,16 @@ void TimeRemapNode::Retranslate()
SetInputName(kInputInput, QStringLiteral("Input"));
}
QVector<QString> TimeRemapNode::inputs_for_output(const QString &output) const
{
Q_UNUSED(output)
return {kInputInput};
}
void TimeRemapNode::Hash(const QString &output, QCryptographicHash &hash, const NodeGlobals &globals, const VideoParams &video_params) const
void TimeRemapNode::Hash(const ValueHint &output, QCryptographicHash &hash, const NodeGlobals &globals, const VideoParams &video_params) const
{
// Don't hash anything of our own, just pass-through to the connected node at the remapped tmie
Q_UNUSED(output)
if (IsInputConnected(kInputInput)) {
NodeOutput out = GetConnectedOutput(kInputInput);
Node *out = GetConnectedOutput(kInputInput);
NodeGlobals new_globals = globals;
new_globals.set_time(TimeRange(GetRemappedTime(globals.time().in()), GetRemappedTime(globals.time().out())));
out.node()->Hash(out.output(), hash, new_globals, video_params);
out->Hash(GetValueHintForInput(kInputInput, -1), hash, new_globals, video_params);
}
}
+1 -3
View File
@@ -45,9 +45,7 @@ public:
virtual void Retranslate() override;
virtual QVector<QString> inputs_for_output(const QString &output) const override;
virtual void Hash(const QString &output, QCryptographicHash &hash, const NodeGlobals &globals, const VideoParams& video_params) const override;
virtual void Hash(const ValueHint &output, QCryptographicHash &hash, const NodeGlobals &globals, const VideoParams& video_params) const override;
static const QString kTimeInput;
static const QString kInputInput;
+37 -19
View File
@@ -26,13 +26,12 @@
namespace olive {
NodeValueDatabase NodeTraverser::GenerateDatabase(const Node* node, const QString& output, const TimeRange &range)
NodeValueDatabase NodeTraverser::GenerateDatabase(const Node* node, const TimeRange &range)
{
NodeValueDatabase database;
// We need to insert tables into the database for each input
auto inputs = node->inputs_for_output(output);
foreach (const QString& input, inputs) {
foreach (const QString& input, node->inputs()) {
if (IsCancelled()) {
return NodeValueDatabase();
}
@@ -43,7 +42,7 @@ NodeValueDatabase NodeTraverser::GenerateDatabase(const Node* node, const QStrin
return database;
}
NodeValueRow NodeTraverser::GenerateRow(NodeValueDatabase *database, const Node *node, const QString &output, const TimeRange &range)
NodeValueRow NodeTraverser::GenerateRow(NodeValueDatabase *database, const Node *node, const TimeRange &range)
{
// Generate row
NodeValueRow row;
@@ -55,17 +54,36 @@ NodeValueRow NodeTraverser::GenerateRow(NodeValueDatabase *database, const Node
return row;
}
NodeValueRow NodeTraverser::GenerateRow(const Node *node, const QString &output, const TimeRange &range)
NodeValueRow NodeTraverser::GenerateRow(const Node *node, const TimeRange &range)
{
// Generate database of input values of node
NodeValueDatabase database = GenerateDatabase(node, output, range);
NodeValueDatabase database = GenerateDatabase(node, range);
return GenerateRow(&database, node, output, range);
return GenerateRow(&database, node, range);
}
NodeValue NodeTraverser::GenerateRowValue(const Node *node, const QString &input, NodeValueTable *table)
{
Node::ValueHint hint = node->GetValueHintForInput(input);
NodeValue value = GenerateRowValueElement(node, input, -1, table);
if (value.array()) {
// Resolve each element of array
QVector<NodeValueTable> tables = value.data().value<QVector<NodeValueTable> >();
QVector<NodeValue> output(tables.size());
for (int i=0; i<tables.size(); i++) {
output[i] = GenerateRowValueElement(node, input, i, &tables[i]);
}
value = NodeValue(value.type(), QVariant::fromValue(output), value.source(), value.array(), value.tag());
}
return value;
}
NodeValue NodeTraverser::GenerateRowValueElement(const Node *node, const QString &input, int element, NodeValueTable *table)
{
Node::ValueHint hint = node->GetValueHintForInput(input, element);
QVector<NodeValue::Type> types = hint.type;
if (types.isEmpty()) {
@@ -133,7 +151,7 @@ NodeValueTable NodeTraverser::ProcessInput(const Node* node, const QString& inpu
TimeRange adjusted_range = node->InputTimeAdjustment(input, -1, range);
// Value will equal something from the connected node, follow it
return GenerateTable(node->GetConnectedOutput(input), adjusted_range);
return GenerateTable(node->GetConnectedOutput(input), node->GetValueHintForInput(input, -1), adjusted_range);
} else {
@@ -151,7 +169,7 @@ NodeValueTable NodeTraverser::ProcessInput(const Node* node, const QString& inpu
TimeRange adjusted_range = node->InputTimeAdjustment(input, i, range);
if (node->IsInputConnected(input, i)) {
sub_tbl = GenerateTable(node->GetConnectedOutput(input, i), adjusted_range);
sub_tbl = GenerateTable(node->GetConnectedOutput(input, i), node->GetValueHintForInput(input, i), adjusted_range);
} else {
QVariant input_value = node->GetValueAtTime(input, adjusted_range.in(), i);
sub_tbl.Push(node->GetInputDataType(input), input_value, node);
@@ -176,7 +194,7 @@ NodeValueTable NodeTraverser::ProcessInput(const Node* node, const QString& inpu
}
}
NodeValueTable NodeTraverser::GenerateTable(const Node *n, const QString& output, const TimeRange& range)
NodeValueTable NodeTraverser::GenerateTable(const Node *n, const Node::ValueHint &hint, const TimeRange& range)
{
const Track* track = dynamic_cast<const Track*>(n);
if (track) {
@@ -187,8 +205,8 @@ NodeValueTable NodeTraverser::GenerateTable(const Node *n, const QString& output
// FIXME: Cache certain values here if we've already processed them before
// Generate row for node
NodeValueDatabase database = GenerateDatabase(n, output, range);
NodeValueRow row = GenerateRow(&database, n, output, range);
NodeValueDatabase database = GenerateDatabase(n, range);
NodeValueRow row = GenerateRow(&database, n, range);
//qDebug() << "FIXME: Implement pre-process of row";
@@ -196,10 +214,10 @@ NodeValueTable NodeTraverser::GenerateTable(const Node *n, const QString& output
NodeValueTable table = database.Merge();
// By this point, the node should have all the inputs it needs to render correctly
n->Value(output, row, GenerateGlobals(video_params_, range), &table);
n->Value(row, GenerateGlobals(video_params_, range), &table);
// Post-process table
PostProcessTable(n, output, range, table);
PostProcessTable(n, hint, range, table);
return table;
}
@@ -212,7 +230,7 @@ NodeValueTable NodeTraverser::GenerateBlockTable(const Track *track, const TimeR
NodeValueTable table;
if (active_block) {
table = GenerateTable(active_block, Track::TransformRangeForBlock(active_block, range));
table = GenerateTable(active_block, track->GetValueHintForInput(Track::kBlockInput, track->GetArrayIndexFromBlock(active_block)), Track::TransformRangeForBlock(active_block, range));
}
return table;
@@ -231,7 +249,7 @@ QVariant NodeTraverser::ProcessAudioFootage(const FootageJob& stream, const Time
Q_UNUSED(stream)
Q_UNUSED(input_time)
return QVariant();
return QVariant::fromValue(SampleBuffer::Create());
}
QVariant NodeTraverser::ProcessShader(const Node *node, const TimeRange &range, const ShaderJob &job)
@@ -284,7 +302,7 @@ QVector2D NodeTraverser::GenerateResolution() const
return QVector2D(video_params_.square_pixel_width(), video_params_.height());
}
void NodeTraverser::PostProcessTable(const Node *node, const QString& output, const TimeRange &range, NodeValueTable &output_params)
void NodeTraverser::PostProcessTable(const Node *node, const Node::ValueHint &hint, const TimeRange &range, NodeValueTable &output_params)
{
bool got_cached_frame = false;
QByteArray cached_node_hash;
@@ -292,7 +310,7 @@ void NodeTraverser::PostProcessTable(const Node *node, const QString& output, co
// Convert footage to image/sample buffers
if (CanCacheFrames() && node->GetCacheTextures()) {
// This node is set to cache the result, see if we can retrieved a previously cached version
cached_node_hash = RenderManager::Hash(node, output, GetCacheVideoParams(), range.in());
cached_node_hash = RenderManager::Hash(node, hint, GetCacheVideoParams(), range.in());
QVariant cached_frame = GetCachedTexture(cached_node_hash);
if (!cached_frame.isNull()) {
+6 -9
View File
@@ -36,18 +36,15 @@ class NodeTraverser : public CancelableObject
public:
NodeTraverser() = default;
NodeValueTable GenerateTable(const Node *n, const QString &output, const TimeRange &range);
NodeValueTable GenerateTable(const NodeOutput& output, const TimeRange &range)
{
return GenerateTable(output.node(), output.output(), range);
}
NodeValueTable GenerateTable(const Node *n, const Node::ValueHint &hint, const TimeRange &range);
NodeValueDatabase GenerateDatabase(const Node *node, const QString &output, const TimeRange &range);
NodeValueDatabase GenerateDatabase(const Node *node, const TimeRange &range);
NodeValueRow GenerateRow(NodeValueDatabase *database, const Node *node, const QString &output, const TimeRange &range);
NodeValueRow GenerateRow(const Node *node, const QString &output, const TimeRange &range);
NodeValueRow GenerateRow(NodeValueDatabase *database, const Node *node, const TimeRange &range);
NodeValueRow GenerateRow(const Node *node, const TimeRange &range);
NodeValue GenerateRowValue(const Node *node, const QString &input, NodeValueTable *table);
NodeValue GenerateRowValueElement(const Node *node, const QString &input, int element, NodeValueTable *table);
static NodeGlobals GenerateGlobals(const VideoParams &params, const TimeRange &time);
static NodeGlobals GenerateGlobals(const VideoParams &params, const rational &time)
@@ -94,7 +91,7 @@ protected:
QVector2D GenerateResolution() const;
private:
void PostProcessTable(const Node *node, const QString &output, const TimeRange &range, NodeValueTable &output_params);
void PostProcessTable(const Node *node, const Node::ValueHint &hint, const TimeRange &range, NodeValueTable &output_params);
VideoParams video_params_;
+12 -12
View File
@@ -70,7 +70,7 @@ QVector<PreviewAutoCacher::HashData> PreviewAutoCacher::GenerateHashes(ViewerOut
const rational &time = times.at(i);
// See if hash already exists in disk cache
QByteArray hash = RenderManager::Hash(viewer->GetConnectedTextureOutput(), viewer->GetVideoParams(), time);
QByteArray hash = RenderManager::Hash(viewer->GetConnectedTextureOutput(), viewer->GetValueHintForInput(ViewerOutput::kTextureInput, -1), viewer->GetVideoParams(), time);
// Check memory list since disk checking is slow
bool hash_exists = existing_hashes.contains(hash);
@@ -357,20 +357,20 @@ void PreviewAutoCacher::RemoveNode(Node *node)
delete copy;
}
void PreviewAutoCacher::AddEdge(const NodeOutput &output, const NodeInput &input)
void PreviewAutoCacher::AddEdge(Node *output, const NodeInput &input)
{
Node* our_output = copy_map_.value(output.node());
Node* our_output = copy_map_.value(output);
Node* our_input = copy_map_.value(input.node());
Node::ConnectEdge(NodeOutput(our_output, output.output()), NodeInput(our_input, input.input(), input.element()));
Node::ConnectEdge(our_output, NodeInput(our_input, input.input(), input.element()));
}
void PreviewAutoCacher::RemoveEdge(const NodeOutput &output, const NodeInput &input)
void PreviewAutoCacher::RemoveEdge(Node *output, const NodeInput &input)
{
Node* our_output = copy_map_.value(output.node());
Node* our_output = copy_map_.value(output);
Node* our_input = copy_map_.value(input.node());
Node::DisconnectEdge(NodeOutput(our_output, output.output()), NodeInput(our_input, input.input(), input.element()));
Node::DisconnectEdge(our_output, NodeInput(our_input, input.input(), input.element()));
}
void PreviewAutoCacher::CopyValue(const NodeInput &input)
@@ -458,23 +458,23 @@ void PreviewAutoCacher::ClearVideoDownloadQueue(bool hard)
void PreviewAutoCacher::NodeAdded(Node *node)
{
graph_update_queue_.append({QueuedJob::kNodeAdded, node, NodeInput(), NodeOutput()});
graph_update_queue_.append({QueuedJob::kNodeAdded, node, NodeInput(), nullptr});
UpdateGraphChangeValue();
}
void PreviewAutoCacher::NodeRemoved(Node *node)
{
graph_update_queue_.append({QueuedJob::kNodeRemoved, node, NodeInput(), NodeOutput()});
graph_update_queue_.append({QueuedJob::kNodeRemoved, node, NodeInput(), nullptr});
UpdateGraphChangeValue();
}
void PreviewAutoCacher::EdgeAdded(const NodeOutput &output, const NodeInput &input)
void PreviewAutoCacher::EdgeAdded(Node *output, const NodeInput &input)
{
graph_update_queue_.append({QueuedJob::kEdgeAdded, nullptr, input, output});
UpdateGraphChangeValue();
}
void PreviewAutoCacher::EdgeRemoved(const NodeOutput &output, const NodeInput &input)
void PreviewAutoCacher::EdgeRemoved(Node *output, const NodeInput &input)
{
graph_update_queue_.append({QueuedJob::kEdgeRemoved, nullptr, input, output});
UpdateGraphChangeValue();
@@ -482,7 +482,7 @@ void PreviewAutoCacher::EdgeRemoved(const NodeOutput &output, const NodeInput &i
void PreviewAutoCacher::ValueChanged(const NodeInput &input)
{
graph_update_queue_.append({QueuedJob::kValueChanged, nullptr, input, NodeOutput()});
graph_update_queue_.append({QueuedJob::kValueChanged, nullptr, input, nullptr});
UpdateGraphChangeValue();
}
+5 -5
View File
@@ -87,8 +87,8 @@ private:
void AddNode(Node* node);
void RemoveNode(Node* node);
void AddEdge(const NodeOutput& output, const NodeInput& input);
void RemoveEdge(const NodeOutput& output, const NodeInput& input);
void AddEdge(Node *output, const NodeInput& input);
void RemoveEdge(Node *output, const NodeInput& input);
void CopyValue(const NodeInput& input);
void InsertIntoCopyMap(Node* node, Node* copy);
@@ -130,7 +130,7 @@ private:
Type type;
Node* node;
NodeInput input;
NodeOutput output;
Node *output;
};
ViewerOutput* viewer_node_;
@@ -214,9 +214,9 @@ private slots:
void NodeRemoved(Node* node);
void EdgeAdded(const NodeOutput& output, const NodeInput& input);
void EdgeAdded(Node *output, const NodeInput& input);
void EdgeRemoved(const NodeOutput& output, const NodeInput& input);
void EdgeRemoved(Node *output, const NodeInput& input);
void ValueChanged(const NodeInput& input);
+1 -1
View File
@@ -102,7 +102,7 @@ void RenderManager::ClearOldDecoders()
}
}
QByteArray RenderManager::Hash(const Node *n, const QString& output, const VideoParams &params, const rational &time)
QByteArray RenderManager::Hash(const Node *n, const Node::ValueHint &output, const VideoParams &params, const rational &time)
{
QCryptographicHash hasher(QCryptographicHash::Sha1);
+1 -5
View File
@@ -67,11 +67,7 @@ public:
/**
* @brief Generate a unique identifier for a certain node at a certain time
*/
static QByteArray Hash(const Node *n, const QString &output, const VideoParams &params, const rational &time);
static QByteArray Hash(const NodeOutput &output, const VideoParams &params, const rational &time)
{
return Hash(output.node(), output.output(), params, time);
}
static QByteArray Hash(const Node *n, const Node::ValueHint &output, const VideoParams &params, const rational &time);
/**
* @brief Asynchronously generate a frame at a given time
+7 -8
View File
@@ -47,10 +47,9 @@ TexturePtr RenderProcessor::GenerateTexture(const rational &time, const rational
ViewerOutput* viewer = Node::ValueToPtr<ViewerOutput>(ticket_->property("viewer"));
NodeValueTable table;
NodeOutput texture_output = viewer->GetConnectedTextureOutput();
if (texture_output.IsValid()) {
table = GenerateTable(texture_output.node(), texture_output.output(),
TimeRange(time, time + frame_length));
Node *texture_output = viewer->GetConnectedTextureOutput();
if (texture_output) {
table = GenerateTable(texture_output, viewer->GetValueHintForInput(ViewerOutput::kTextureInput, -1), TimeRange(time, time + frame_length));
}
return table.Get(NodeValue::kTexture).value<TexturePtr>();
@@ -170,9 +169,9 @@ void RenderProcessor::Run()
TimeRange time = ticket_->property("time").value<TimeRange>();
NodeValueTable table;
NodeOutput texture_output = viewer->GetConnectedSampleOutput();
if (texture_output.IsValid()) {
table = GenerateTable(texture_output.node(), texture_output.output(), time);
Node *texture_output = viewer->GetConnectedSampleOutput();
if (texture_output) {
table = GenerateTable(texture_output, viewer->GetValueHintForInput(ViewerOutput::kSamplesInput, -1),time);
}
QVariant sample_variant = table.Get(NodeValue::kSamples);
@@ -263,7 +262,7 @@ NodeValueTable RenderProcessor::GenerateBlockTable(const Track *track, const Tim
int max_dest_sz = audio_params.time_to_samples(range_for_block.length());
// Destination buffer
NodeValueTable table = GenerateTable(b, Track::TransformRangeForBlock(b, range_for_block));
NodeValueTable table = GenerateTable(b, track->GetValueHintForInput(Track::kBlockInput, track->GetArrayIndexFromBlock(b)),Track::TransformRangeForBlock(b, range_for_block));
SampleBufferPtr samples_from_this_block = table.Take(NodeValue::kSamples).value<SampleBufferPtr>();
if (!samples_from_this_block) {
+3 -1
View File
@@ -47,7 +47,9 @@ PreCacheTask::PreCacheTask(Footage *footage, int index, Sequence* sequence)
footage_ = static_cast<Footage*>(footage->copy());
footage_->setParent(project_);
Node::CopyInputs(footage, footage_, false);
Node::ConnectEdge(NodeOutput(footage_, Track::Reference(Track::kVideo, index).ToString()), NodeInput(viewer(), ViewerOutput::kTextureInput));
Node::ConnectEdge(footage_, NodeInput(viewer(), ViewerOutput::kTextureInput));
viewer()->SetValueHintForInput(ViewerOutput::kTextureInput, -1, {{NodeValue::kTexture}, -1, Track::Reference(Track::kVideo, index).ToString()});
SetTitle(tr("Pre-caching %1:%2").arg(footage_->filename(), QString::number(index)));
}
+1 -1
View File
@@ -91,7 +91,7 @@ bool RenderTask::Render(ColorManager* manager,
}
times[i] = r;
hashes[i] = RenderManager::instance()->Hash(viewer()->GetConnectedTextureOutput(), video_params_, r);
hashes[i] = RenderManager::instance()->Hash(viewer()->GetConnectedTextureOutput(), viewer()->GetValueHintForInput(ViewerOutput::kTextureInput, -1), video_params_, r);
}
// Filter out duplicates
@@ -422,7 +422,7 @@ int NodeParamViewItemBody::GetElementY(NodeInput c) const
return lbl_center.y();
}
void NodeParamViewItemBody::EdgeChanged(const NodeOutput& output, const NodeInput& input)
void NodeParamViewItemBody::EdgeChanged(Node *output, const NodeInput& input)
{
Q_UNUSED(output)
+1 -1
View File
@@ -148,7 +148,7 @@ private:
static const int kWidgetStartColumn;
private slots:
void EdgeChanged(const NodeOutput &output, const NodeInput &input);
void EdgeChanged(Node *output, const NodeInput &input);
void ArrayCollapseBtnPressed(bool checked);
@@ -201,4 +201,15 @@ void NodeParamArrayAppendCommand::undo()
node_->InputArrayRemoveLast(input_, false);
}
void NodeSetValueHintCommand::redo()
{
old_hint_ = input_.node()->GetValueHintForInput(input_.input(), input_.element());
input_.node()->SetValueHintForInput(input_.input(), input_.element(), new_hint_);
}
void NodeSetValueHintCommand::undo()
{
input_.node()->SetValueHintForInput(input_.input(), input_.element(), old_hint_);
}
}
@@ -164,6 +164,38 @@ private:
};
class NodeSetValueHintCommand : public UndoCommand
{
public:
NodeSetValueHintCommand(const NodeInput &input, const Node::ValueHint &hint) :
input_(input),
new_hint_(hint)
{
}
NodeSetValueHintCommand(Node *node, const QString &input, int element, const Node::ValueHint &hint) :
NodeSetValueHintCommand(NodeInput(node, input, element), hint)
{
}
virtual Project* GetRelevantProject() const override
{
return input_.node()->project();
}
protected:
virtual void redo() override;
virtual void undo() override;
private:
NodeInput input_;
Node::ValueHint new_hint_;
Node::ValueHint old_hint_;
};
}
#endif // NODEPARAMVIEWUNDO_H
+4 -6
View File
@@ -43,7 +43,7 @@ void NodeTableView::SelectNodes(const QVector<Node *> &nodes)
{
foreach (Node* n, nodes) {
QTreeWidgetItem* top_item = new QTreeWidgetItem();
top_item->setText(0, n->Name());
top_item->setText(0, n->GetLabelAndName());
top_item->setFirstColumnSpanned(true);
this->addTopLevelItem(top_item);
top_level_item_map_.insert(n, top_item);
@@ -70,7 +70,7 @@ void NodeTableView::SetTime(const rational &time)
QTreeWidgetItem* item = i.value();
// Generate a value database for this node at this time
NodeValueDatabase db = traverser.GenerateDatabase(node, QString(), TimeRange(time, time));
NodeValueDatabase db = traverser.GenerateDatabase(node, TimeRange(time, time));
// Delete any children of this item that aren't in this database
for (int j=0; j<item->childCount(); j++) {
@@ -81,9 +81,7 @@ void NodeTableView::SetTime(const rational &time)
}
// Update all inputs
NodeValueDatabase::const_iterator l;
for (l=db.begin(); l!=db.end(); l++) {
for (auto l=db.begin(); l!=db.end(); l++) {
const NodeValueTable& table = l.value();
if (!node->HasInputWithID(l.key())) {
@@ -132,7 +130,7 @@ void NodeTableView::SetTime(const rational &time)
// Determine source
QString source_name;
if (value.source()) {
source_name = value.source()->Name();
source_name = value.source()->GetLabelAndName();
} else {
source_name = tr("(unknown)");
}
+17 -22
View File
@@ -20,7 +20,6 @@
#include "nodeview.h"
#include <cfloat>
#include <QInputDialog>
#include <QMouseEvent>
#include <QScrollBar>
@@ -460,8 +459,7 @@ void NodeView::mousePressEvent(QMouseEvent *event)
for (NodeViewEdge *edge_item : scene_.edges()) {
if (edge_item->arrow_bounding_rect().contains(scene_pt)) {
create_edge_src_ = scene_.NodeToUIObject(edge_item->output().node());
create_edge_src_output_ = edge_item->output().output();
create_edge_src_ = scene_.NodeToUIObject(edge_item->output());
create_edge_ = edge_item;
create_edge_already_exists_ = true;
return;
@@ -542,12 +540,10 @@ void NodeView::mouseMoveEvent(QMouseEvent *event)
NodeValue::Type drop_edge_data_type = NodeValue::kNone;
// Run the Node and guess what type it's actually returning
// Run the Node and determine what type is being used
NodeTraverser traverser;
NodeValueTable table = traverser.GenerateTable(new_drop_edge->output(), TimeRange(0, 0));
if (table.Count() > 0) {
drop_edge_data_type = table.at(table.Count() - 1).type();
}
NodeValue drop_edge_value = traverser.GenerateRow(new_drop_edge->output(), TimeRange(0, 0))[new_drop_edge->input().input()];
drop_edge_data_type = drop_edge_value.type();
// Iterate through the inputs of our dragging node and see if our node has any acceptable
// inputs to connect to for this type
@@ -633,7 +629,7 @@ void NodeView::mouseReleaseEvent(QMouseEvent *event)
if (creating_input.IsValid()) {
// Make connection
if (!reconnected_to_itself) {
NodeOutput creating_output(create_edge_src_->GetNode(), create_edge_src_output_);
Node *creating_output = create_edge_src_->GetNode();
if (creating_input.IsConnected()) {
Node::OutputConnection existing_edge_to_remove = {creating_input.GetConnectedOutput(), creating_input};
@@ -656,7 +652,7 @@ void NodeView::mouseReleaseEvent(QMouseEvent *event)
UpdateContextsFromEdgeRemove(command, removed_edges);
}
if (added_edge.first.IsValid()) {
if (added_edge.first) {
UpdateContextsFromEdgeAdd(command, added_edge, removed_edges);
}
@@ -994,9 +990,9 @@ void NodeView::RemoveNode(Node *node)
scene_.RemoveNode(node);
}
void NodeView::AddEdge(const NodeOutput &output, const NodeInput &input)
void NodeView::AddEdge(Node *output, const NodeInput &input)
{
Node *output_node = output.node();
Node *output_node = output;
Node *input_node = input.node();
if (scene_.item_map().contains(output_node) && scene_.item_map().contains(input_node)) {
@@ -1004,7 +1000,7 @@ void NodeView::AddEdge(const NodeOutput &output, const NodeInput &input)
}
}
void NodeView::RemoveEdge(const NodeOutput &output, const NodeInput &input)
void NodeView::RemoveEdge(Node *output, const NodeInput &input)
{
scene_.RemoveEdge(output, input);
}
@@ -1306,7 +1302,7 @@ void NodeView::UpdateContextsFromEdgeRemove(MultiUndoCommand *command, const Nod
{
// For each edge we remove, determine if we should remove the node from a context as well
for (const Node::OutputConnection &edge : remove_edges) {
Node *output_node = edge.first.node();
Node *output_node = edge.first;
QVector<Node *> contexts_to_remove_from;
int contexts_containing = 0;
@@ -1357,7 +1353,7 @@ void NodeView::RecursivelyRemoveFloatingNodeFromContext(MultiUndoCommand *comman
// Remove any dependency from the context that's also floating
for (auto it=node->input_connections().cbegin(); it!=node->input_connections().cend(); it++) {
Node *dependency = it->second.node();
Node *dependency = it->second;
// Determine if this node happens to output to anything else in the context (which may be
// another floating node that won't be removed by this operation)
@@ -1376,7 +1372,7 @@ void NodeView::RecursivelyAddNodeToContext(MultiUndoCommand *command, Node *node
// Add dependency
for (auto it=node->input_connections().cbegin(); it!=node->input_connections().cend(); it++) {
Node *dependency = it->second.node();
Node *dependency = it->second;
RecursivelyAddNodeToContext(command, dependency, context);
}
}
@@ -1386,7 +1382,7 @@ void NodeView::UpdateContextsFromEdgeAdd(MultiUndoCommand *command, const Node::
{
// Determine if node currently does NOT output to a context that it WILL after this operation
QVector<Node*> contexts_to_add_to;
Node *connecting_node = added_edge.first.node();
Node *connecting_node = added_edge.first;
Node *input_node = added_edge.second.node();
for (auto it=graph_->GetPositionMap().cbegin(); it!=graph_->GetPositionMap().cend(); it++) {
if (it.value().contains(input_node)) {
@@ -1441,7 +1437,6 @@ void NodeView::CreateNewEdge(NodeViewItem *output_item, const QPoint &mouse_pos)
{
create_edge_ = new NodeViewEdge();
create_edge_src_ = output_item;
create_edge_src_output_ = Node::kDefaultOutput;
create_edge_already_exists_ = false;
create_edge_->SetCurved(scene_.GetEdgesAreCurved());
@@ -1504,12 +1499,12 @@ void NodeView::PositionNewEdge(const QPoint &pos)
if (highlight_index >= 0) {
create_edge_dst_input_ = create_edge_dst_->GetInputAtIndex(highlight_index);
create_edge_->SetPoints(create_edge_src_->GetOutputPoint(Node::kDefaultOutput),
create_edge_->SetPoints(create_edge_src_->GetOutputPoint(),
create_edge_dst_->GetInputPoint(create_edge_dst_input_.input(), create_edge_dst_input_.element(), create_edge_src_->pos()),
true);
} else {
create_edge_dst_input_.Reset();
create_edge_->SetPoints(create_edge_src_->GetOutputPoint(Node::kDefaultOutput),
create_edge_->SetPoints(create_edge_src_->GetOutputPoint(),
scene_pt,
false);
}
@@ -1606,7 +1601,7 @@ NodeViewItem *NodeView::UpdateNodeItem(Node *node, bool ignore_own_context)
item = scene_.AddNode(node);
for (auto it=node->input_connections().cbegin(); it!=node->input_connections().cend(); it++) {
if (scene_.item_map().contains(it->second.node())) {
if (scene_.item_map().contains(it->second)) {
scene_.AddEdge(it->second, it->first);
}
}
@@ -1619,7 +1614,7 @@ NodeViewItem *NodeView::UpdateNodeItem(Node *node, bool ignore_own_context)
}
// Determine "view" position by averaging the Y value and "min"ing the X value of all contexts
QPointF item_pos(DBL_MAX, 0.0);
QPointF item_pos(std::numeric_limits<qreal>::max(), 0.0);
int average_count = 0;
for (Node *context : qAsConst(filter_nodes_)) {
if (context == node && ignore_own_context) {
+2 -3
View File
@@ -211,7 +211,6 @@ private:
NodeViewEdge* create_edge_;
NodeViewItem* create_edge_src_;
QString create_edge_src_output_;
NodeViewItem* create_edge_dst_;
NodeInput create_edge_dst_input_;
bool create_edge_dst_temp_expanded_;
@@ -281,8 +280,8 @@ private slots:
//void AddNode(Node *node);
void RemoveNode(Node *node);
void AddEdge(const NodeOutput& output, const NodeInput& input);
void RemoveEdge(const NodeOutput& output, const NodeInput& input);
void AddEdge(Node *output, const NodeInput& input);
void RemoveEdge(Node *output, const NodeInput& input);
void AddNodePosition(Node *node, Node *relative);
void RemoveNodePosition(Node *node, Node *relative);
+2 -2
View File
@@ -35,7 +35,7 @@ namespace olive {
#define super QGraphicsPathItem
NodeViewEdge::NodeViewEdge(const NodeOutput &output, const NodeInput &input,
NodeViewEdge::NodeViewEdge(Node *output, const NodeInput &input,
NodeViewItem* from_item, NodeViewItem* to_item,
QGraphicsItem* parent) :
super(parent),
@@ -59,7 +59,7 @@ NodeViewEdge::NodeViewEdge(QGraphicsItem *parent) :
void NodeViewEdge::Adjust()
{
// Draw a line between the two
SetPoints(from_item()->GetOutputPoint(output_.output()),
SetPoints(from_item()->GetOutputPoint(),
to_item()->GetInputPoint(input_.input(), input_.element(), from_item()->pos()),
to_item()->IsExpanded());
}
+3 -3
View File
@@ -39,13 +39,13 @@ class NodeViewItem;
class NodeViewEdge : public QGraphicsPathItem
{
public:
NodeViewEdge(const NodeOutput& output, const NodeInput& input,
NodeViewEdge(Node *output, const NodeInput& input,
NodeViewItem* from_item, NodeViewItem* to_item,
QGraphicsItem* parent = nullptr);
NodeViewEdge(QGraphicsItem* parent = nullptr);
const NodeOutput& output() const
Node *output() const
{
return output_;
}
@@ -124,7 +124,7 @@ private:
void UpdateCurve();
NodeOutput output_;
Node *output_;
NodeInput input_;
+1 -9
View File
@@ -301,14 +301,6 @@ void NodeViewItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *opti
QString node_label = node_->GetLabel();
QString node_shortname = node_->ShortName();
if (node_label.isEmpty()) {
// If this is a track and has no user-supplied label, generate an automatic one
Track* track_cast_test = dynamic_cast<Track*>(node_);
if (track_cast_test) {
node_label = Track::GetDefaultTrackName(track_cast_test->type(), track_cast_test->Index());
}
}
int icon_size = painter->fontMetrics().height()/2;
if (node_label.isEmpty()) {
@@ -511,7 +503,7 @@ QPointF NodeViewItem::GetInputPoint(const QString &input, int element, const QPo
return pos() + GetInputPointInternal(node_inputs_.indexOf(input), source_pos);
}
QPointF NodeViewItem::GetOutputPoint(const QString& output) const
QPointF NodeViewItem::GetOutputPoint() const
{
switch (flow_dir_) {
case NodeViewCommon::kLeftToRight:
+1 -1
View File
@@ -80,7 +80,7 @@ public:
*/
QPointF GetInputPoint(const QString& input, int element, const QPointF &source_pos) const;
QPointF GetOutputPoint(const QString &output) const;
QPointF GetOutputPoint() const;
/**
* @brief Sets the direction nodes are flowing
+5 -5
View File
@@ -98,7 +98,7 @@ NodeViewItem *NodeViewScene::NodeToUIObject(Node *n)
return item_map_.value(n);
}
NodeViewEdge *NodeViewScene::EdgeToUIObject(const NodeOutput& output, const NodeInput& input)
NodeViewEdge *NodeViewScene::EdgeToUIObject(Node *output, const NodeInput& input)
{
foreach (NodeViewEdge* edge, edges_) {
if (edge->output() == output && edge->input() == input) {
@@ -172,18 +172,18 @@ void NodeViewScene::RemoveNode(Node *node)
delete item_map_.take(node);
}
NodeViewEdge* NodeViewScene::AddEdge(const NodeOutput &output, const NodeInput &input)
NodeViewEdge* NodeViewScene::AddEdge(Node *output, const NodeInput &input)
{
NodeViewEdge *edge = EdgeToUIObject(output, input);
if (!edge) {
edge = AddEdgeInternal(output, input, NodeToUIObject(output.node()), NodeToUIObject(input.node()));
edge = AddEdgeInternal(output, input, NodeToUIObject(output), NodeToUIObject(input.node()));
}
return edge;
}
void NodeViewScene::RemoveEdge(const NodeOutput &output, const NodeInput &input)
void NodeViewScene::RemoveEdge(Node *output, const NodeInput &input)
{
NodeViewEdge* edge = EdgeToUIObject(output, input);
if (edge) {
@@ -209,7 +209,7 @@ int NodeViewScene::DetermineWeight(Node *n)
return qMax(1, weight);
}
NodeViewEdge* NodeViewScene::AddEdgeInternal(const NodeOutput& output, const NodeInput& input, NodeViewItem *from, NodeViewItem *to)
NodeViewEdge* NodeViewScene::AddEdgeInternal(Node *output, const NodeInput& input, NodeViewItem *from, NodeViewItem *to)
{
NodeViewEdge* edge_ui = new NodeViewEdge(output, input, from, to);
+4 -4
View File
@@ -53,7 +53,7 @@ public:
* in this view/scene), this function returns nullptr.
*/
NodeViewItem* NodeToUIObject(Node* n);
NodeViewEdge *EdgeToUIObject(const NodeOutput &output, const NodeInput &input);
NodeViewEdge *EdgeToUIObject(Node *output, const NodeInput &input);
QVector<Node *> GetSelectedNodes() const;
QVector<NodeViewItem*> GetSelectedItems() const;
@@ -96,8 +96,8 @@ public slots:
*/
void RemoveNode(Node* node);
NodeViewEdge *AddEdge(const NodeOutput& output, const NodeInput& input);
void RemoveEdge(const NodeOutput& output, const NodeInput& input);
NodeViewEdge *AddEdge(Node *output, const NodeInput& input);
void RemoveEdge(Node *output, const NodeInput& input);
/**
* @brief Set whether edges in this scene should be curved or not
@@ -107,7 +107,7 @@ public slots:
private:
static int DetermineWeight(Node* n);
NodeViewEdge* AddEdgeInternal(const NodeOutput &output, const NodeInput &input, NodeViewItem* from, NodeViewItem* to);
NodeViewEdge* AddEdgeInternal(Node *output, const NodeInput &input, NodeViewItem* from, NodeViewItem* to);
void ConnectNode(Node *n);
+4 -4
View File
@@ -24,7 +24,7 @@
namespace olive {
NodeEdgeAddCommand::NodeEdgeAddCommand(const NodeOutput &output, const NodeInput &input) :
NodeEdgeAddCommand::NodeEdgeAddCommand(Node *output, const NodeInput &input) :
output_(output),
input_(input),
remove_command_(nullptr)
@@ -60,10 +60,10 @@ void NodeEdgeAddCommand::undo()
Project *NodeEdgeAddCommand::GetRelevantProject() const
{
return output_.node()->project();
return output_->project();
}
NodeEdgeRemoveCommand::NodeEdgeRemoveCommand(const NodeOutput &output, const NodeInput &input) :
NodeEdgeRemoveCommand::NodeEdgeRemoveCommand(Node *output, const NodeInput &input) :
output_(output),
input_(input)
{
@@ -81,7 +81,7 @@ void NodeEdgeRemoveCommand::undo()
Project *NodeEdgeRemoveCommand::GetRelevantProject() const
{
return output_.node()->project();
return output_->project();
}
NodeAddCommand::NodeAddCommand(NodeGraph *graph, Node *node) :
+4 -4
View File
@@ -35,7 +35,7 @@ namespace olive {
*/
class NodeEdgeRemoveCommand : public UndoCommand {
public:
NodeEdgeRemoveCommand(const NodeOutput& output, const NodeInput& input);
NodeEdgeRemoveCommand(Node *output, const NodeInput& input);
virtual Project* GetRelevantProject() const override;
@@ -44,7 +44,7 @@ protected:
virtual void undo() override;
private:
NodeOutput output_;
Node *output_;
NodeInput input_;
};
@@ -56,7 +56,7 @@ private:
*/
class NodeEdgeAddCommand : public UndoCommand {
public:
NodeEdgeAddCommand(const NodeOutput& output, const NodeInput& input);
NodeEdgeAddCommand(Node *output, const NodeInput& input);
virtual ~NodeEdgeAddCommand() override;
@@ -67,7 +67,7 @@ protected:
virtual void undo() override;
private:
NodeOutput output_;
Node *output_;
NodeInput input_;
NodeEdgeRemoveCommand* remove_command_;
+7 -4
View File
@@ -34,6 +34,7 @@
#include "node/generator/matrix/matrix.h"
#include "node/math/math/math.h"
#include "node/project/sequence/sequence.h"
#include "widget/nodeparamview/nodeparamviewundo.h"
#include "widget/nodeview/nodeviewundo.h"
#include "widget/timelinewidget/undo/timelineundopointer.h"
#include "window/mainwindow/mainwindow.h"
@@ -385,8 +386,6 @@ void ImportTool::DropGhosts(bool insert)
TimelineViewGhostItem::AttachedFootage footage_stream = ghost->GetData(TimelineViewGhostItem::kAttachedFootage).value<TimelineViewGhostItem::AttachedFootage>();
NodeOutput corresponding_output(footage_stream.footage, footage_stream.output);
ClipBlock* clip = new ClipBlock();
clip->set_media_in(ghost->GetMediaIn());
clip->set_length_and_media_out(ghost->GetLength());
@@ -405,7 +404,9 @@ void ImportTool::DropGhosts(bool insert)
TransformDistortNode* transform = new TransformDistortNode();
command->add_child(new NodeAddCommand(dst_graph, transform));
command->add_child(new NodeEdgeAddCommand(corresponding_output, NodeInput(transform, TransformDistortNode::kTextureInput)));
command->add_child(new NodeSetValueHintCommand(transform, TransformDistortNode::kTextureInput, -1, {{NodeValue::kTexture}, -1, footage_stream.output}));
command->add_child(new NodeEdgeAddCommand(footage_stream.footage, NodeInput(transform, TransformDistortNode::kTextureInput)));
command->add_child(new NodeEdgeAddCommand(transform, NodeInput(clip, ClipBlock::kBufferIn)));
command->add_child(new NodeSetPositionCommand(transform, clip, QPointF(-1, 0), false));
break;
@@ -415,7 +416,9 @@ void ImportTool::DropGhosts(bool insert)
VolumeNode* volume_node = new VolumeNode();
command->add_child(new NodeAddCommand(dst_graph, volume_node));
command->add_child(new NodeEdgeAddCommand(corresponding_output, NodeInput(volume_node, VolumeNode::kSamplesInput)));
command->add_child(new NodeSetValueHintCommand(volume_node, VolumeNode::kSamplesInput, -1, {{NodeValue::kSamples}, -1, footage_stream.output}));
command->add_child(new NodeEdgeAddCommand(footage_stream.footage, NodeInput(volume_node, VolumeNode::kSamplesInput)));
command->add_child(new NodeEdgeAddCommand(volume_node, NodeInput(clip, ClipBlock::kBufferIn)));
command->add_child(new NodeSetPositionCommand(volume_node, clip, QPointF(-1, 0), false));
break;
@@ -111,11 +111,7 @@ void TrackViewItem::LineEditCancelled()
void TrackViewItem::UpdateLabel()
{
if (track_->GetLabel().isEmpty()) {
label_->setText(track_->GetDefaultTrackName(track_->type(), track_->Index()));
} else {
label_->setText(track_->GetLabel());
}
label_->setText(track_->GetLabelOrName());
}
}
+3 -3
View File
@@ -402,8 +402,8 @@ void ViewerWidget::DecodeCachedImage(RenderTicketPtr ticket, const QString &cach
bool ViewerWidget::ShouldForceWaveform() const
{
return GetConnectedNode()
&& !GetConnectedNode()->GetConnectedTextureOutput().IsValid()
&& GetConnectedNode()->GetConnectedSampleOutput().IsValid();
&& !GetConnectedNode()->GetConnectedTextureOutput()
&& GetConnectedNode()->GetConnectedSampleOutput();
}
void ViewerWidget::SetEmptyImage()
@@ -686,7 +686,7 @@ bool ViewerWidget::FrameExistsAtTime(const rational &time)
bool ViewerWidget::ViewerMightBeAStill()
{
return GetConnectedNode() && GetConnectedNode()->GetConnectedTextureOutput().IsValid() && GetConnectedNode()->GetVideoLength().isNull();
return GetConnectedNode() && GetConnectedNode()->GetConnectedTextureOutput() && GetConnectedNode()->GetVideoLength().isNull();
}
void ViewerWidget::SetDisplayImage(QVariant frame, bool main_only)
+1 -1
View File
@@ -401,7 +401,7 @@ void ViewerDisplayWidget::OnPaint()
gt.SetCacheVideoParams(gizmo_params_);
TimeRange range = GenerateGizmoTime();
gizmo_db_ = gt.GenerateRow(gizmos_, Node::kDefaultOutput, range);
gizmo_db_ = gt.GenerateRow(gizmos_, range);
QPainter p(inner_widget());
p.setWorldTransform(GenerateGizmoTransform());