Velocity Envelope and Points

Thiago_Sase wrote on 8/17/2024, 3:23 PM

@jetdv Sir, please, if possible, how can I add 4 points to this velocity envelope. If I select a Video event, then I need the velocity envelope to be created and automatically adds 4 points in the middle of the event, I mean, any selected event with any duration. How can I do that?

 

using System;
using ScriptPortal.Vegas;
using System.Windows.Forms;

namespace AddVelocityEnvelope
{
    public class Class1
    {
        public Vegas myVegas;

        public void Main(Vegas vegas)
        {
            myVegas = vegas;

            foreach (Track myTrack in myVegas.Project.Tracks)
            {
                if (myTrack.IsVideo())
                {
                    foreach (TrackEvent evnt in myTrack.Events)
                    {
                        if (evnt.Selected)
                        {
                            VideoEvent vevnt = (VideoEvent)evnt;
                            Envelope vEnv = GetOrCreateVelocityEnvelope(vevnt);

                            if (vEnv != null)
                            {
                                
                                AddEnvelopePoint(vEnv, evnt.Start, 1.0); 

                            }
                        }
                    }
                }
            }
        }

        private Envelope GetOrCreateVelocityEnvelope(VideoEvent vevnt)
        {
            foreach (Envelope env in vevnt.Envelopes)
            {
                if (env.Type == EnvelopeType.Velocity)
                {
                    return env;
                }
            }

            Envelope newEnv = new Envelope(EnvelopeType.Velocity);
            vevnt.Envelopes.Add(newEnv);
            return newEnv;
        }

        private void AddEnvelopePoint(Envelope MyEnv, Timecode PointLoc, double PointSpeed)
        {
            try
            {
                EnvelopePoint newPoint = new EnvelopePoint(PointLoc, PointSpeed);
                MyEnv.Points.Add(newPoint);
            }
            catch (Exception ex)
            {
                MessageBox.Show("Failed to add envelope point: " + ex.Message);
            }
        }
    }

    public class EntryPoint
    {
        public void FromVegas(Vegas vegas)
        {
            Class1 script = new Class1();
            script.Main(vegas);
        }
    }
}

 

Comments

jetdv wrote on 8/17/2024, 4:58 PM

@Thiago_Sase Exactly "where" in the event do you want these points added? You said "middle" of the event but they can't all four be exactly in the center.

Basically, get your event length. Then figure out, based on that length, where you want them located.

  1. Get the length
  2. divide that length by 2 to get the exact center
  3. Place an envelope point at the center - "big distance" (or, perhaps, "0" for the beginning of the event)
  4. place an envelope point at center - "little distance" (or start + "distance" if a set amount from the beginning)
  5. place an envelope point at center + "little distance" (or length - "distance" if a set amount from the end)
  6. place an envelope point at center + "big distance" (or, perhaps, "length" for the end of the event)

You now have four points added a set distance from the center of the event.

Thiago_Sase wrote on 8/17/2024, 5:09 PM

@jetdv Let's say that the "rule" of the script is if the event = > than 4 seconds then the 4 points will be added if not, a message will be displayed "The Event has to be bigger than 4 seconds".

Thiago_Sase wrote on 8/17/2024, 7:14 PM

@jetdv After many tries, I got this;
 

using System;
using System.Collections.Generic;
using System.IO;
using System.Windows.Forms;
using ScriptPortal.Vegas;

namespace Test_Script
{
    public class Class1
    {
        public Vegas myVegas;
        public void Main(Vegas vegas)
        {
            myVegas = vegas;

            
            foreach (Track track in myVegas.Project.Tracks)
            {
                foreach (TrackEvent trackEvent in track.Events)
                {
                    VideoEvent videoEvent = trackEvent as VideoEvent;
                    if (trackEvent.Selected && videoEvent != null)
                    {
                        MessageBox.Show("Event Length: " + videoEvent.Length.ToString());

                        Envelope VelEnv = new Envelope(EnvelopeType.Velocity);
                        videoEvent.Envelopes.Add(VelEnv);

                        AddVelocityPointRelativeToEvent(VelEnv, videoEvent, 10, 1);  // 10 frames from event start
                        AddVelocityPointRelativeToEvent(VelEnv, videoEvent, 20, 1); // 20 frames from event start
                        AddVelocityPointRelativeToEvent(VelEnv, videoEvent, 30, 1); // 30 frames from event start
                        AddVelocityPointRelativeToEvent(VelEnv, videoEvent, 40, 1); // 40 frames from event start
                    }
                }
            }
        }

        public void AddVelocityPointRelativeToEvent(Envelope VelEnv, VideoEvent videoEvent, int frames, double PointSpeed)
        {
            Timecode pointLocation = videoEvent.Start + FramesToTimecode(frames);

            if (pointLocation <= videoEvent.End)
            {
                EnvelopePoint a = VelEnv.Points.GetPointAtX(pointLocation);
                if (a == null)
                {
                    a = new EnvelopePoint(pointLocation, PointSpeed);
                    VelEnv.Points.Add(a);
                }
                else
                {
                    a.Y = PointSpeed;
                }
            }
            else
            {
                MessageBox.Show("Point location exceeds the event's duration.");
            }
        }

        public Timecode FramesToTimecode(int frames)
        {
            double frameRate = myVegas.Project.Video.FrameRate;
            return new Timecode(frames / frameRate);
        }
    }

    public class EntryPoint
    {
        public void FromVegas(Vegas vegas)
        {
            Test_Script.Class1 test = new Test_Script.Class1();
            test.Main(vegas);
        }
    }
}

The 4 Points were added, it worked with a selected event, but they are overlapping each other. And the position of the points are not following this logic here;
 

AddVelocityPointRelativeToEvent(VelEnv, videoEvent, 10, 1);  // 10 frames from event start
 AddVelocityPointRelativeToEvent(VelEnv, videoEvent, 20, 1); // 20 frames from event start
 AddVelocityPointRelativeToEvent(VelEnv, videoEvent, 30, 1); // 30 frames from event start
 AddVelocityPointRelativeToEvent(VelEnv, videoEvent, 40, 1); // 40 frames from event start 

On that logic, the event has to be its length = > than 40 frames and the 4 points have to be distributed among those 40 frames. But is not working as expected.

I tested with events of 1 second, 10 seconds, 30 seconds, 1 minute, 2 minutes, 10 minutes, the behavior of the location of the points are the same.

What am I doing wrong, Sir? Please, If you could help me find a solution.

Last changed by Thiago_Sase on 8/17/2024, 7:31 PM, changed a total of 4 times.

OS: Windows 10 22H2
CPU: Intel Core I7 12700
MEMORY: 32GB DDR4 3200MHz
GHAPHIC CARD: RTX 3060 8GB
HARD DRIVES: SSD for System and M.2 for Media Files

jetdv wrote on 8/17/2024, 7:35 PM

Go back to this:

        private void AddEnvelopePoint(Envelope MyEnv, Timecode PointLoc, double PointSpeed)
        {
            try
            {
                EnvelopePoint newPoint = new EnvelopePoint(PointLoc, PointSpeed);
                MyEnv.Points.Add(newPoint);
            }
            catch (Exception ex)
            {
                MessageBox.Show("Failed to add envelope point: " + ex.Message);
            }
        }

Put all of the logic in the main routine. And do you really want it 10, 20, 30 and 40 frames from the start? Or more "relative" to the length of the event?

This will give you four points surrounding the "center" of the event:

            foreach (Track track in myVegas.Project.Tracks)
            {
                foreach (TrackEvent trackEvent in track.Events)
                {
                    VideoEvent videoEvent = trackEvent as VideoEvent;
                    if (trackEvent.Selected && videoEvent != null)
                    {
                        MessageBox.Show("Event Length: " + videoEvent.Length.ToString());

                        Envelope VelEnv = new Envelope(EnvelopeType.Velocity);
                        videoEvent.Envelopes.Add(VelEnv);

                        Timecode BigOffset = new Timecode("00:00:00:20");
                        Timecode LittleOffset = new Timecode("00:00:00:10");
                        Timecode Center = videoEvent.Length;

                        AddEnvelopePoint(VelEnv, Center - BigOffset, 1);
                        AddEnvelopePoint(VelEnv, Center - LittleOffset, 1);
                        AddEnvelopePoint(VelEnv, Center + LittleOffset, 1);
                        AddEnvelopePoint(VelEnv, Center + BigOffset, 1);
                    }
                }
            }

If you really want 10, 20, 30 , 40 frames, just use:
 

            foreach (Track track in myVegas.Project.Tracks)
            {
                foreach (TrackEvent trackEvent in track.Events)
                {
                    VideoEvent videoEvent = trackEvent as VideoEvent;
                    if (trackEvent.Selected && videoEvent != null)
                    {
                        MessageBox.Show("Event Length: " + videoEvent.Length.ToString());

                        Envelope VelEnv = new Envelope(EnvelopeType.Velocity);
                        videoEvent.Envelopes.Add(VelEnv);

                        AddEnvelopePoint(VelEnv, Timecode.FromFrames(10), 1);
                        AddEnvelopePoint(VelEnv, Timecode.FromFrames(20), 1);
                        AddEnvelopePoint(VelEnv, Timecode.FromFrames(30), 1);
                        AddEnvelopePoint(VelEnv, Timecode.FromFrames(40), 1);
                    }
                }
            }

But I would check to see if the velocity envelope exists before adding a new one...

And there's already a 4 points tutorial scheduled for September 2 based on the envelope series that started two weeks ago (part 3 coming out in a couple of days - 4 points is part 5.)

Thiago_Sase wrote on 8/17/2024, 8:39 PM

@jetdv Thank you very much.

This solution failed by adding 4 points, only adds 2 points by the end of the event.

foreach (Track track in myVegas.Project.Tracks)
            {
                foreach (TrackEvent trackEvent in track.Events)
                {
                    VideoEvent videoEvent = trackEvent as VideoEvent;
                    if (trackEvent.Selected && videoEvent != null)
                    {
                        MessageBox.Show("Event Length: " + videoEvent.Length.ToString());

                        Envelope VelEnv = new Envelope(EnvelopeType.Velocity);
                        videoEvent.Envelopes.Add(VelEnv);

                        Timecode BigOffset = new Timecode("00:00:00:20");
                        Timecode LittleOffset = new Timecode("00:00:00:10");
                        Timecode Center = videoEvent.Length;

                        AddEnvelopePoint(VelEnv, Center - BigOffset, 1);
                        AddEnvelopePoint(VelEnv, Center - LittleOffset, 1);
                        AddEnvelopePoint(VelEnv, Center + LittleOffset, 1);
                        AddEnvelopePoint(VelEnv, Center + BigOffset, 1);
                    }
                }
            }

On the other hand, this one worked perfect, it was like magic. Now I can set the duration of gaps between the points and move them with the help of envelope edit tool to any part of the event length that I need;

foreach (Track track in myVegas.Project.Tracks)
            {
                foreach (TrackEvent trackEvent in track.Events)
                {
                    VideoEvent videoEvent = trackEvent as VideoEvent;
                    if (trackEvent.Selected && videoEvent != null)
                    {
                        MessageBox.Show("Event Length: " + videoEvent.Length.ToString());

                        Envelope VelEnv = new Envelope(EnvelopeType.Velocity);
                        videoEvent.Envelopes.Add(VelEnv);

                        AddEnvelopePoint(VelEnv, Timecode.FromFrames(10), 1);
                        AddEnvelopePoint(VelEnv, Timecode.FromFrames(20), 1);
                        AddEnvelopePoint(VelEnv, Timecode.FromFrames(30), 1);
                        AddEnvelopePoint(VelEnv, Timecode.FromFrames(40), 1);
                    }
                }
            }

And there's already a 4 points tutorial scheduled for September 2 based on the envelope series that started two weeks ago (part 3 coming out in a couple of days - 4 points is part 5.)

I can't wait to watch them as soon as they are available. I'm sure it will be another great learning experience.

Thank you very much, Edward.

jetdv wrote on 8/17/2024, 8:42 PM

@Thiago_Sase Sorry, I forgot to divide by 2:

Timecode Center = videoEvent.Length / 2;

 

Thiago_Sase wrote on 8/17/2024, 8:50 PM

@jetdv That solution gives this error;

"C:\Program Files\VEGAS\VEGAS Pro 22.0\Script Menu\Add Envelope Velocity.cs(29) : Cannot apply the '/' operator to operands of type 'ScriptPortal.Vegas.Timecode' and 'int'"

But the second solution works perfect.

jetdv wrote on 8/17/2024, 8:53 PM

@Thiago_Sase, there's always ways around that...

Timecode Center = Timecode.FromMilliseconds(videoEvent.Length.ToMilliseconds() / 2.0);

 

Thiago_Sase wrote on 8/17/2024, 9:25 PM

@jetdv It worked perfectly. Both versions. Thank you.

Thiago_Sase wrote on 8/17/2024, 9:28 PM

Version 01 - It will add the Velocity Envelope and automatically adds 4 points around the center of the selected event.
 

using System;
using ScriptPortal.Vegas;
using System.Windows.Forms;

namespace AddVelocityEnvelope
{
    public class Class1
    {
        public Vegas myVegas;

        public void Main(Vegas vegas)
        {
            myVegas = vegas;

            foreach (Track track in myVegas.Project.Tracks)
            {
                foreach (TrackEvent trackEvent in track.Events)
                {
                    VideoEvent videoEvent = trackEvent as VideoEvent;
                    if (trackEvent.Selected && videoEvent != null)
                    {
                        MessageBox.Show("Event Length: " + videoEvent.Length.ToString());

                        Envelope VelEnv = new Envelope(EnvelopeType.Velocity);
                        videoEvent.Envelopes.Add(VelEnv);

                        Timecode BigOffset = new Timecode("00:00:00:20");
                        Timecode LittleOffset = new Timecode("00:00:00:10");
                        Timecode Center = Timecode.FromMilliseconds(videoEvent.Length.ToMilliseconds() / 2.0);

                        AddEnvelopePoint(VelEnv, Center - BigOffset, 1);
                        AddEnvelopePoint(VelEnv, Center - LittleOffset, 1);
                        AddEnvelopePoint(VelEnv, Center + LittleOffset, 1);
                        AddEnvelopePoint(VelEnv, Center + BigOffset, 1);
                    }
                }
            }
        }

        private Envelope GetOrCreateVelocityEnvelope(VideoEvent vevnt)
        {
            foreach (Envelope env in vevnt.Envelopes)
            {
                if (env.Type == EnvelopeType.Velocity)
                {
                    return env;
                }
            }

            Envelope newEnv = new Envelope(EnvelopeType.Velocity);
            vevnt.Envelopes.Add(newEnv);
            return newEnv;
        }

        private void AddEnvelopePoint(Envelope MyEnv, Timecode PointLoc, double PointSpeed)
        {
            try
            {
                EnvelopePoint newPoint = new EnvelopePoint(PointLoc, PointSpeed);
                MyEnv.Points.Add(newPoint);
            }
            catch (Exception ex)
            {
                MessageBox.Show("Failed to add envelope point: " + ex.Message);
            }
        }
    }

    public class EntryPoint
    {
        public void FromVegas(Vegas vegas)
        {
            Class1 script = new Class1();
            script.Main(vegas);
        }
    }
}

 

Thiago_Sase wrote on 8/17/2024, 9:33 PM

Version 02 - It will add the Velocity Envelope and automatically adds 4 points from 10 frames of the start of the selected event, and you can set the gaps between the points manually in the code.

 

using System;
using ScriptPortal.Vegas;
using System.Windows.Forms;

namespace AddVelocityEnvelope
{
    public class Class1
    {
        public Vegas myVegas;

        public void Main(Vegas vegas)
        {
            myVegas = vegas;

            foreach (Track track in myVegas.Project.Tracks)
            {
                foreach (TrackEvent trackEvent in track.Events)
                {
                    VideoEvent videoEvent = trackEvent as VideoEvent;
                    if (trackEvent.Selected && videoEvent != null)
                    {
                        MessageBox.Show("Event Length: " + videoEvent.Length.ToString());

                        Envelope VelEnv = new Envelope(EnvelopeType.Velocity);
                        videoEvent.Envelopes.Add(VelEnv);

                        AddEnvelopePoint(VelEnv, Timecode.FromFrames(10), 1);
                        AddEnvelopePoint(VelEnv, Timecode.FromFrames(20), 1);
                        AddEnvelopePoint(VelEnv, Timecode.FromFrames(30), 1);
                        AddEnvelopePoint(VelEnv, Timecode.FromFrames(40), 1);
                    }
                }
            }
        }

        private Envelope GetOrCreateVelocityEnvelope(VideoEvent vevnt)
        {
            foreach (Envelope env in vevnt.Envelopes)
            {
                if (env.Type == EnvelopeType.Velocity)
                {
                    return env;
                }
            }

            Envelope newEnv = new Envelope(EnvelopeType.Velocity);
            vevnt.Envelopes.Add(newEnv);
            return newEnv;
        }

        private void AddEnvelopePoint(Envelope MyEnv, Timecode PointLoc, double PointSpeed)
        {
            try
            {
                EnvelopePoint newPoint = new EnvelopePoint(PointLoc, PointSpeed);
                MyEnv.Points.Add(newPoint);
            }
            catch (Exception ex)
            {
                MessageBox.Show("Failed to add envelope point: " + ex.Message);
            }
        }
    }

    public class EntryPoint
    {
        public void FromVegas(Vegas vegas)
        {
            Class1 script = new Class1();
            script.Main(vegas);
        }
    }
}

 

Last changed by Thiago_Sase on 8/17/2024, 9:34 PM, changed a total of 2 times.

OS: Windows 10 22H2
CPU: Intel Core I7 12700
MEMORY: 32GB DDR4 3200MHz
GHAPHIC CARD: RTX 3060 8GB
HARD DRIVES: SSD for System and M.2 for Media Files