nodes: revert to single output
This commit is contained in:
@@ -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 {
|
||||
|
||||
@@ -39,7 +39,6 @@ struct XMLNodeData {
|
||||
struct SerializedConnection {
|
||||
NodeInput input;
|
||||
quintptr output_node;
|
||||
QString output;
|
||||
};
|
||||
|
||||
struct BlockLink {
|
||||
|
||||
+1
-1
@@ -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),
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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_;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
@@ -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);
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -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]);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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_;
|
||||
|
||||
@@ -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())) {
|
||||
|
||||
@@ -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
@@ -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
@@ -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) {
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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
@@ -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
@@ -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()
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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 ¶ms)
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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
@@ -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()) {
|
||||
|
||||
@@ -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 ¶ms, const TimeRange &time);
|
||||
static NodeGlobals GenerateGlobals(const VideoParams ¶ms, 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_;
|
||||
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -102,7 +102,7 @@ void RenderManager::ClearOldDecoders()
|
||||
}
|
||||
}
|
||||
|
||||
QByteArray RenderManager::Hash(const Node *n, const QString& output, const VideoParams ¶ms, const rational &time)
|
||||
QByteArray RenderManager::Hash(const Node *n, const Node::ValueHint &output, const VideoParams ¶ms, const rational &time)
|
||||
{
|
||||
QCryptographicHash hasher(QCryptographicHash::Sha1);
|
||||
|
||||
|
||||
@@ -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 ¶ms, const rational &time);
|
||||
static QByteArray Hash(const NodeOutput &output, const VideoParams ¶ms, const rational &time)
|
||||
{
|
||||
return Hash(output.node(), output.output(), params, time);
|
||||
}
|
||||
static QByteArray Hash(const Node *n, const Node::ValueHint &output, const VideoParams ¶ms, const rational &time);
|
||||
|
||||
/**
|
||||
* @brief Asynchronously generate a frame at a given time
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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)));
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)");
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
|
||||
@@ -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_;
|
||||
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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) :
|
||||
|
||||
@@ -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_;
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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());
|
||||
|
||||
Reference in New Issue
Block a user