Psd Layer Splitter Script

zzzzzz9125 wrote on 4/11/2024, 8:10 AM

I don't know if I'm reinventing the wheel, but I just wrote a simple script that can be used to split layers of a .psd file in Vegas with one-click.

Here's my code:

using System;
using System.Windows.Forms;

using ScriptPortal.Vegas;  // "ScriptPortal.Vegas" for Magix Vegas Pro 14 or above, "Sony.Vegas" for Sony Vegas Pro 13 or below

namespace Test_Script
{

    public class Class
    {
        public Vegas myVegas;
        public void Main(Vegas vegas)
        {
            myVegas = vegas;
            myVegas.ResumePlaybackOnScriptExit = true;
            Project project = myVegas.Project;
            Tracks myTracks = project.Tracks;
            bool ctrlMode = ((Control.ModifierKeys & Keys.Control) != 0) ? true : false;

            for (int jj = myTracks.Count - 1; jj >= 0; jj--)
            {
                if (myTracks[jj].IsVideo())
                {
                    foreach (VideoEvent vEvent in myTracks[jj].Events)
                    {
                        VideoTrack myTrack = (VideoTrack) myTracks[jj];
                        if (vEvent.Selected)
                        {
                            if (vEvent.ActiveTake == null || vEvent.ActiveTake.Media == null || vEvent.ActiveTake.MediaStream == null)
                            {
                                continue;
                            }

                            int vStreamCount = vEvent.ActiveTake.Media.StreamCount(MediaType.Video);
                            if (vStreamCount < 2)
                            {
                                continue;
                            }

                            // If you hold down Ctrl and click the script icon on the toolbar, the selected event will be converted to Stream 1 (in a programming sense, it's a video stream with Index 0).
                            if (ctrlMode)
                            {
                                Take newTake = Take.CreateInstance(project, vEvent.ActiveTake.Media.GetVideoStreamByIndex(0));
                                vEvent.Takes.Clear();
                                vEvent.Takes.Add(newTake);
                            }

                            int vStreamIndex = GetVideoStreamIndex(vEvent);
                            if (vStreamIndex == 0)
                            {
                                vEvent.Mute = true;
                            }

                            int vStreamCountAdd = Mod(vStreamIndex - 1, vStreamCount);

                            TrackEventGroup grp = vEvent.Group;
                            if (grp == null)
                            {
                                grp = new TrackEventGroup(project);
                                project.Groups.Add(grp);
                                grp.Add(vEvent);
                            }

                            for (int i = 0; i < vStreamCountAdd; i++)
                            {
                                int j = i + jj;
                                VideoTrack newTrack = null;
                                if (j < myTracks.Count - 1)
                                {
                                    Track trackBelow = myTracks[j + 1];
                                    if (trackBelow.IsVideo() && !((VideoTrack)trackBelow).IsCompositingParent && (vStreamIndex == 0 ? ((VideoTrack)trackBelow).CompositeNestingLevel == myTrack.CompositeNestingLevel + 1 : ((VideoTrack)trackBelow).CompositeNestingLevel == myTrack.CompositeNestingLevel))
                                    {
                                        newTrack = (VideoTrack)trackBelow;
                                    }
                                }

                                if (newTrack == null)
                                {
                                    newTrack = new VideoTrack(project, j + 1, null);
                                    myTracks.Add(newTrack);
                                    newTrack.CompositeNestingLevel = myTrack.CompositeNestingLevel;
                                    if (vStreamIndex == 0)
                                    {
                                        newTrack.CompositeNestingLevel += 1;
                                    }
                                }

                                foreach (VideoEvent evnt in newTrack.Events)
                                {
                                    if (evnt.Start == vEvent.Start)
                                    {
                                        if (evnt.ActiveTake == null || evnt.ActiveTake.Media == null || evnt.ActiveTake.MediaStream == null || evnt.ActiveTake.Media == vEvent.ActiveTake.Media)
                                        {
                                            newTrack.Events.Remove(evnt);
                                        }
                                    }
                                }

                                VideoEvent newEvent = (VideoEvent) vEvent.Copy(newTrack, vEvent.Start);
                                Take newTake = Take.CreateInstance(project, vEvent.ActiveTake.Media.GetVideoStreamByIndex(vStreamCountAdd - i));
                                newEvent.Takes.Clear();
                                newEvent.Takes.Add(newTake);
                                newEvent.Selected = false;
                                newEvent.Mute = false;
                                grp.Add(newEvent);
                            }
                        }
                    }
                }
            }
        }

        public static int Mod(double a, double b)
        {
            int c = (int)(a - Math.Floor(a / b) * b);
            return c;
        }

        public static int GetVideoStreamIndex(VideoEvent vEvent)
        {
            int i = -1;
            foreach (MediaStream ms in vEvent.ActiveTake.Media.Streams)
            {
                if (ms.MediaType == MediaType.Video)
                {
                    i++;
                    if (ms == vEvent.ActiveTake.MediaStream)
                    {
                        return i;
                    }
                }
            }
            return 0;
        }
    }
}


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

To distinguish it in toolbar, I also made an icon for the script:

If you have any suggestions, please feel free to give feedback.

Comments

editeiro wrote on 7/20/2024, 10:41 AM

Dude, you didn't reinvent the wheel, you invented the car here, congratulations and thank you for that!

I've been looking for a tool like this for years, I usually organize images, logos and texts in Photoshop, and the worst part is distributing the media event streams across the timeline, it's a lot of work.

I even studied scripting for Vegas Pro, but I couldn't generate anything that worked.

I tested it here and it worked really well.
Thank you!

Could I share this script for tutoriais on my YouTube Channel?

zzzzzz9125 wrote on 7/20/2024, 11:15 AM

Could I share this script for tutoriais on my YouTube Channel?

Of course. Enjoy it!👉

Using VEGAS Pro 22 build 194 & VEGAS Pro 21 build 208.

Information about my PC:
Brand Name: HP VICTUS Laptop
System: Windows 11.0 (64-bit) 10.00.22631
CPU: 12th Gen Intel(R) Core(TM) i7-12700H
GPU: NVIDIA GeForce RTX 3050 Laptop GPU
GPU Driver: NVIDIA Studio Driver 560.70

editeiro wrote on 7/20/2024, 11:17 AM

@zzzzzz9125 

I have a suggestion, you could make a version that distributes the streams through the same video track, with a question box that allows you to choose the length of the event streams.

To stay like this:

So we have a good tool for importing timelapses or animated sprites as an image sequence, only through .psd

jetdv wrote on 7/20/2024, 12:41 PM

Right-click-drag the PSD file from Windows Explorer, select "across tracks" and it creates a track for every layer.

@editeiro, I haven't tried it but try: right-click-drag the PSD file from Windows Explorer, select "across time" and it add each layer across time..

zzzzzz9125 wrote on 7/20/2024, 1:57 PM

Right-click-drag the PSD file from Windows Explorer, select "across tracks" and it creates a track for every layer.

@jetdv I didn't even know this feature was there, I thought it was only for multiple footages, but thanks for reminding me, this overlaps somewhat with what my script does!

I haven't tried it but try: right-click-drag the PSD file from Windows Explorer, select "across time" and it add each layer across time..

However, this doesn't seem to be working.

 

I have a suggestion, you could make a version that distributes the streams through the same video track, with a question box that allows you to choose the length of the event streams.

To stay like this:

So we have a good tool for importing timelapses or animated sprites as an image sequence, only through .psd

@editeiro I've changed the code to meet your need, and the code is as follows:

using System;
using System.Windows.Forms;
using System.Collections.Generic;

using ScriptPortal.Vegas;  // "ScriptPortal.Vegas" for Magix Vegas Pro 14 or above, "Sony.Vegas" for Sony Vegas Pro 13 or below

namespace Test_Script
{

    public class Class
    {
        public Vegas myVegas;
        
        public void Main(Vegas vegas)
        {
            myVegas = vegas;
            myVegas.ResumePlaybackOnScriptExit = true;
            Project project = myVegas.Project;
            Tracks myTracks = project.Tracks;
            bool ctrlMode = ((Control.ModifierKeys & Keys.Control) != 0) ? true : false;

            List<VideoEvent> vEvents = new List<VideoEvent>();
            foreach (Track myTrack in project.Tracks)
            {
                if (myTrack.IsVideo())
                {
                    foreach (TrackEvent evnt in myTrack.Events)
                    {
                        if (evnt.Selected)
                        {
                            if (evnt.ActiveTake == null || evnt.ActiveTake.Media == null || evnt.ActiveTake.MediaStream == null)
                            {
                                continue;
                            }

                            vEvents.Add((VideoEvent)evnt);
                        }
                    }
                }
            }

            foreach (VideoEvent vEvent in vEvents)
            {
                int vStreamCount = vEvent.ActiveTake.Media.StreamCount(MediaType.Video);
                if (vStreamCount < 2)
                {
                    continue;
                }

                // If you hold down Ctrl and click the script icon on the toolbar, the selected event will be converted to Stream 1 (in a programming sense, it's a video stream with Index 0).
                if (ctrlMode)
                {
                    Take newTake = Take.CreateInstance(project, vEvent.ActiveTake.Media.GetVideoStreamByIndex(0));
                    vEvent.Takes.Clear();
                    vEvent.Takes.Add(newTake);
                }

                int vStreamIndex = GetVideoStreamIndex(vEvent), vStreamCountAdd = Mod(vStreamIndex - 1, vStreamCount);

                if (vStreamCountAdd == 0)
                {
                    continue;
                }

                TrackEventGroup grp = vEvent.Group;
                if (grp == null)
                {
                    grp = new TrackEventGroup(project);
                    project.Groups.Add(grp);
                    grp.Add(vEvent);
                }

                Timecode length = Timecode.FromNanos((long)(vEvent.Length.Nanos / vStreamCountAdd)), start = vEvent.Start;
                if (vStreamIndex != 0)
                {
                    length = vEvent.Length;
                    start += length;
                }

                for (int i = 0; i < vStreamCountAdd; i++)
                {
                    foreach (VideoEvent evnt in vEvent.Track.Events)
                    {
                        if (evnt.Start == start && evnt.Length == length && evnt != vEvent)
                        {
                            if (evnt.ActiveTake == null || evnt.ActiveTake.Media == null || evnt.ActiveTake.MediaStream == null || evnt.ActiveTake.Media == vEvent.ActiveTake.Media)
                            {
                                vEvent.Track.Events.Remove(evnt);
                            }
                        }
                    }

                    VideoEvent newEvent = (VideoEvent) vEvent.Copy(vEvent.Track, start);
                    newEvent.Length = length;
                    Take newTake = Take.CreateInstance(project, vEvent.ActiveTake.Media.GetVideoStreamByIndex(vStreamCountAdd - i));
                    newEvent.Takes.Clear();
                    newEvent.Takes.Add(newTake);
                    grp.Add(newEvent);
                    start += length;
                }
            }
        }

        public static int Mod(double a, double b)
        {
            int c = (int)(a - Math.Floor(a / b) * b);
            return c;
        }

        public static int GetVideoStreamIndex(VideoEvent vEvent)
        {
            int i = -1;
            foreach (MediaStream ms in vEvent.ActiveTake.Media.Streams)
            {
                if (ms.MediaType == MediaType.Video)
                {
                    i++;
                    if (ms == vEvent.ActiveTake.MediaStream)
                    {
                        return i;
                    }
                }
            }
            return 0;
        }
    }
}

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

Compare how these two scripts work:

 

with a question box that allows you to choose the length of the event streams

For this requirement, since I prefer one-click operations, the event lengths in this script are based on the original event's length. If you want to stretch them simultaneously, for they are already grouped, you can just hold down Ctrl.

Last changed by zzzzzz9125 on 7/20/2024, 2:01 PM, changed a total of 2 times.

Using VEGAS Pro 22 build 194 & VEGAS Pro 21 build 208.

Information about my PC:
Brand Name: HP VICTUS Laptop
System: Windows 11.0 (64-bit) 10.00.22631
CPU: 12th Gen Intel(R) Core(TM) i7-12700H
GPU: NVIDIA GeForce RTX 3050 Laptop GPU
GPU Driver: NVIDIA Studio Driver 560.70

iEmby wrote on 7/20/2024, 1:58 PM

Right-click-drag the PSD file from Windows Explorer, select "across tracks" and it creates a track for every layer.

@editeiro, I haven't tried it but try: right-click-drag the PSD file from Windows Explorer, select "across time" and it add each layer across time..

Yes right... is your script doing something extra from this? like keep blending modes alive as in PSD, mute layers to mute, @zzzzzz9125

PROCESSOR
     

Operating System: Windows 11 Pro 64-bit (Always Updated)
System Manufacturer: ASUS
12th Gen Intel(R) Core(TM) i7-12700 (20 CPUs), ~2.1GHz - 4.90GHz
Memory: 32GB RAM
Page File: 11134MB used, 7934MB Available
DirectX Version: DirectX 12

-----------------------------------------------

MOTHERBOARD

 

ASUS PRIME H610-CS D4
Intel® H610 (LGA 1700)
Ready for 12th Gen Intel® Processors
Micro-ATX Motherboard with DDR4
Realtek 1 Gb Ethernet
PCH Heatsink
PCIe 4.0 | M.2 slot (32Gbps) 
HDMI® | D-Sub | USB 3.2 Gen 1 ports
SATA 6 Gbps | COM header
LPT header | TPM header
Luminous Anti-Moisture Coating
5X Protection III
(Multiple Hardware Safeguards
For all-round protection)

-----------------------------------------------
EXTERNAL GRAPHIC CARD

-----------------------------------------------

INTERNAL GRAPHIC CARD (iGPU)

------------------------------------------------

LED - MONITOR

Monitor Name: Generic PnP Monitor
Monitor Model: HP 22es
Monitor Id: HWP331B
Native Mode: 1920 x 1080(p) (60.000Hz)
Output Type: HDMI

-----------------------------------------------

STORAGE DRIVE

Drive: C:
Free Space: 182.3 GB
Total Space: 253.9 GB
File System: NTFS
Model: WD Blue SN570 1TB (NVMe)

---------------O----------------

My System Info (PDF File).

https://drive.google.com/open?id=1-eoLmuXzshTRH_8RunAYAuNocKpiLoiV&usp=drive_fs

 

Also Check

VEGAS Scripts Collection By Me

GitHub Profile

My YouTube Channel Dedicated to Only VEGAS Pro Tutorials

EDITROOM : My YouTube Channel (For VEGAS Tutorials)

zzzzzz9125 wrote on 7/20/2024, 2:08 PM

Yes right... is your script doing something extra from this? like keep blending modes alive as in PSD, mute layers to mute, @zzzzzz9125

@iEmby No, my script reads .psd the same way Vegas Pro reads .psd. I didn't do anything to parse it: that would have required a complex .dll, and I was just writing a simple script.

Last changed by zzzzzz9125 on 7/20/2024, 2:10 PM, changed a total of 3 times.

Using VEGAS Pro 22 build 194 & VEGAS Pro 21 build 208.

Information about my PC:
Brand Name: HP VICTUS Laptop
System: Windows 11.0 (64-bit) 10.00.22631
CPU: 12th Gen Intel(R) Core(TM) i7-12700H
GPU: NVIDIA GeForce RTX 3050 Laptop GPU
GPU Driver: NVIDIA Studio Driver 560.70

editeiro wrote on 7/20/2024, 3:01 PM

@jetdv I didn't know that the Across Tracks option worked with .psd, thanks for the guidance.

I still think that @zzzzzz9125 script is a good option as it makes it easier to distribute these streams across the timeline and saves time.

I can import several .psd files at once, choose where they will be and trim the length of each one and run the script on them all at once.

The Script creates an individual track for each stream respecting the length and group them as Composite Childs allowing me to move them all at once with Parent Motion.
like this example:

and @zzzzzz9125
Thank you for adjusting the script to place the streams in sequence across the track, it worked well here.

editeiro wrote on 7/20/2024, 3:59 PM

@zzzzzz9125 @jetdv

taking advantage of the topic about scripting for psd

I like to animate Game Stages and Fake3D Photos in Vegas, and I prepare all these layers in Photoshop
like this one:

@zzzzzz9125
Your script is very useful for separating layers in the timeline, 
but it is still necessary to work on distributing the streams in depth using the Compositing Mode "3D Source Alpha" and adjusting the Track Motion position parameters.

The more pixels I add to the z-position, the more I need to increase the width-height proportionally
This an example:

And to automate the process of distributing layers in 3D space, I wonder if it would be possible to automate the following steps using a script:

  1. Switch the Track to 3D Source Alpha
  2. Duplicate Track
  3. Run the code to Split the PSD in multiple streams
  4. Turn the Video Track of each Stream into 3D Compositing Mode
  5. Add values ​​to the z, width and height parameters of position in a proportional manner
    (to keep the layer within the preview area)
  6. Make aC ompositing Child of all these Tracks to the First Track and make a Composite Parent Motion to 3D Source Alpha.

This is just a script idea, I imagine that to work in all cases, the script will need a code that can understand:

  • - What is the correct proportion between z, width and height of Position.
  • - How to add these values ​​in descending order to each stream from the "farthest" to the "closest"
  • - How to increase these values ​​based on the number of .psd streams
    The greater the number of Layers, the more "depth" there should be in the composition.

Tell me if this is possible or if it's a lot of work,
because if it is possible, we can help the various editors and motion designers who are looking
for this effect here:

but to work in Vegas Pro.

Thank for the Attention!

zzzzzz9125 wrote on 7/20/2024, 8:26 PM

Your script is very useful for separating layers in the timeline, 
but it is still necessary to work on distributing the streams in depth using the Compositing Mode "3D Source Alpha" and adjusting the Track Motion position parameters.

The more pixels I add to the z-position, the more I need to increase the width-height proportionally
This an example:

And to automate the process of distributing layers in 3D space, I wonder if it would be possible to automate the following steps using a script:

  1. Switch the Track to 3D Source Alpha
  2. Duplicate Track
  3. Run the code to Split the PSD in multiple streams
  4. Turn the Video Track of each Stream into 3D Compositing Mode
  5. Add values ​​to the z, width and height parameters of position in a proportional manner
    (to keep the layer within the preview area)
  6. Make aC ompositing Child of all these Tracks to the First Track and make a Composite Parent Motion to 3D Source Alpha.

This is just a script idea, I imagine that to work in all cases, the script will need a code that can understand:

  • - What is the correct proportion between z, width and height of Position.
  • - How to add these values ​​in descending order to each stream from the "farthest" to the "closest"
  • - How to increase these values ​​based on the number of .psd streams
    The greater the number of Layers, the more "depth" there should be in the composition.

Tell me if this is possible or if it's a lot of work,
because if it is possible, we can help the various editors and motion designers who are looking
for this effect here:

but to work in Vegas Pro.

Thank for the Attention!

@editeiro Let's take a look at how many of these points can be achieved.

  1. Switch the Track to 3D Source Alpha
  2. Duplicate Track
  3. Run the code to Split the PSD in multiple streams
  4. Turn the Video Track of each Stream into 3D Compositing Mode
  5. Add values ​​to the z, width and height parameters of position in a proportional manner
    (to keep the layer within the preview area)
  6. Make aC ompositing Child of all these Tracks to the First Track and make a Composite Parent Motion to 3D Source Alpha.

It seems possible to do all of these things, except for 2, because Vegas Pro doesn't provide a method to copy tracks in the Script API. It's easier to just copy the track motion keyframes.

However, the following one is still worth discussing:

Add values ​​to the z, width and height parameters of position in a proportional manner

Setting z values is relatively simple. We can assume a list of decreasing values, such as {0, -100, -200, ...}, and add these values in turn. This can represent 3D layer relationships simply. (It seems impossible to measure the actual z values.) I watched your video, you seem to want to change width & height values as well, but I'm not sure how to calculate them with z values. Do you have any idea?

I'll try to implement these features over the next few days...

Last changed by zzzzzz9125 on 7/20/2024, 8:42 PM, changed a total of 5 times.

Using VEGAS Pro 22 build 194 & VEGAS Pro 21 build 208.

Information about my PC:
Brand Name: HP VICTUS Laptop
System: Windows 11.0 (64-bit) 10.00.22631
CPU: 12th Gen Intel(R) Core(TM) i7-12700H
GPU: NVIDIA GeForce RTX 3050 Laptop GPU
GPU Driver: NVIDIA Studio Driver 560.70

jetdv wrote on 7/20/2024, 9:49 PM

Well... #2 is possible depending on what all you want to duplicate and how much effort you want to put into it. You can certainly make a new track, set it also to 3D Source Alpha, copy any event from the first track to the second track, and then other things can be copied as well - depending on what you want copied. But, as was mentioned, there's no built-in "copy track" option.

All the rest could certainly be done, though.

editeiro wrote on 7/21/2024, 12:25 PM

I watched your video, you seem to want to change width & height values as well, but I'm not sure how to calculate them with z values. Do you have any idea?

Hi @zzzzzz9125
I don't understand scripting programming in Vegas Pro, I know some expressions in After Effects so I'll try to give an example here:

Thinking about porportions that work in a horizontal aspect (16:9, 4:3 or 1:1)

To progress in this parallax through the tracks, I do this:

With the tracks in 3D Source Alpha

  • I choose a value and add it to z-position and the same value I add to height-position

    I think for this to be progressive and proportional to the size of the project, we can do it like this:
  • Get the width value from the project properties
  • add 10% of the project-width value to the z-position and height-position of Track 2 (Last psd stream)
  • add 20% of the project-width to the z-position and height-position of Track 3
  • add 30%... 40%... 50%... and so on.
    *This progression has to be tested, perhaps {10, 15, 20...} or {8, 16, 32...} whichever works best in most cases

I think in percentage, because in larger compositions, in 4K for example, adding a fixed value will not have much effect on the Parallax depth

And if the parallax needs to be "deeper" you can change the depth-position of the Parent Motion
or multiply the project-width value by 1.5 or 2, directly in the code, to increase these distances and scales.

And , of Course, to Vertical vídeo, 9:16, we must invert the Width values ​​by the Height values
Both about Project Properties and Track Motion
What would generate, in the end, a script for horizontal comps and a script for vertical comps.

But I understand there is a problem here:

When I do this manually, the "Lock Aspect Ratio" button is activated so it increases the width-position in proportion to the value I add to the height-position

So I don't know if this can be considered in the code, or if we have to calculate it mathematically.

joelsonforte.br wrote on 7/21/2024, 6:18 PM

@zzzzzz9125

Is it possible to add an logic to the script so that, before creating video tracks, it checks whether or not there are already video tracks in the timeline? If there are video tracks, the created events will be added to these tracks and if they do not exist, the script will create the video tracks. This prevents creating too many trails unnecessarily.

In the moment, the script always creates new video tracks for the layers of the PSD file even if there are already video tracks created in the timeline. Suppose I add a PSD file to video track 1, and this PSD file has 9 layers. When executing this script, 9 video tracks will be created where the 9 layers will be located. If I place a new PSD file on track 1, also with 9 layers, when running the script again, 9 more video tracks will be created unnecessarily, as the events created could stay in the 9 video tracks that already exist. How can I resolve this? The ideal would be to take advantage of existing trails without the need to create new trails. New trails would only be created when they did not exist.

zzzzzz9125 wrote on 7/21/2024, 7:16 PM

Is it possible to add an logic to the script so that, before creating video tracks, it checks whether or not there are already video tracks in the timeline? If there are video tracks, the created events will be added to these tracks and if they do not exist, the script will create the video tracks. This prevents creating too many trails unnecessarily.

@joelsonforte.br May the script you are using be incomplete? It's not quite the same as the logic I wrote. It should set the lower tracks as child tracks of the current track and mute the events you selected.

In the video you provided, they were not set as child tracks, so due to the judgment logic of the script, it chose to create tracks.

Here's the code to determine if we need to create tracks:

VideoTrack newTrack = null;
if (j < myTracks.Count - 1)
{
    Track trackBelow = myTracks[j + 1];
    if (trackBelow.IsVideo() && !((VideoTrack)trackBelow).IsCompositingParent && (vStreamIndex == 0 ? ((VideoTrack)trackBelow).CompositeNestingLevel == myTrack.CompositeNestingLevel + 1 : ((VideoTrack)trackBelow).CompositeNestingLevel == myTrack.CompositeNestingLevel))
    {
        newTrack = (VideoTrack)trackBelow;
    }
}

if (newTrack == null)
{
    newTrack = new VideoTrack(project, j + 1, null);
    myTracks.Add(newTrack);
    newTrack.CompositeNestingLevel = myTrack.CompositeNestingLevel;
    if (vStreamIndex == 0)
    {
        newTrack.CompositeNestingLevel += 1;
    }
}

The screenshots below show my idea for writing this logic:

In particular, when the third one is at the next level:

For the script starts from the bottom to the top, when the third event has created the child tracks, the second one will also think that the track of the third one doesn't meet the conditions, so it decides to create another child tracks. I use this logic to avoid confusion in layers. Otherwise, it will mess up the case for this video below:

I didn't know that the Across Tracks option worked with .psd, thanks for the guidance.

I still think that @zzzzzz9125 script is a good option as it makes it easier to distribute these streams across the timeline and saves time.

I can import several .psd files at once, choose where they will be and trim the length of each one and run the script on them all at once.

The Script creates an individual track for each stream respecting the length and group them as Composite Childs allowing me to move them all at once with Parent Motion.
like this example:

 

@joelsonforte.br I don't know much about the other versions of Vegas Pro, if this is a version issue, please keep me posted.

Last changed by zzzzzz9125 on 7/21/2024, 7:23 PM, changed a total of 2 times.

Using VEGAS Pro 22 build 194 & VEGAS Pro 21 build 208.

Information about my PC:
Brand Name: HP VICTUS Laptop
System: Windows 11.0 (64-bit) 10.00.22631
CPU: 12th Gen Intel(R) Core(TM) i7-12700H
GPU: NVIDIA GeForce RTX 3050 Laptop GPU
GPU Driver: NVIDIA Studio Driver 560.70

joelsonforte.br wrote on 7/21/2024, 7:41 PM

@zzzzzz9125 Thanks for the logic, it worked perfectly.

Please can you make a small correction in the second script that adds the PSD layers Across Time. For some reason, the Stream 1 is overlapped by the events created. See the attached video. I need to fix it manually to make it correct.

zzzzzz9125 wrote on 7/21/2024, 7:56 PM

@zzzzzz9125 Thanks for the logic, it worked perfectly.

Please can you make a small correction in the second script that adds the PSD layers Across Time. For some reason, the Stream 1 is overlapped by the events created. See the attached video. I need to fix it manually to make it correct.

@joelsonforte.br @editeiro It's my problem. I forgot to delete the original events. The corrected script is as follows:

using System;
using System.Windows.Forms;
using System.Collections.Generic;

using ScriptPortal.Vegas;  // "ScriptPortal.Vegas" for Magix Vegas Pro 14 or above, "Sony.Vegas" for Sony Vegas Pro 13 or below

namespace Test_Script
{

    public class Class
    {
        public Vegas myVegas;
        
        public void Main(Vegas vegas)
        {
            myVegas = vegas;
            myVegas.ResumePlaybackOnScriptExit = true;
            Project project = myVegas.Project;
            Tracks myTracks = project.Tracks;
            bool ctrlMode = ((Control.ModifierKeys & Keys.Control) != 0) ? true : false;

            List<VideoEvent> vEvents = new List<VideoEvent>();
            foreach (Track myTrack in project.Tracks)
            {
                if (myTrack.IsVideo())
                {
                    foreach (TrackEvent evnt in myTrack.Events)
                    {
                        if (evnt.Selected)
                        {
                            if (evnt.ActiveTake == null || evnt.ActiveTake.Media == null || evnt.ActiveTake.MediaStream == null)
                            {
                                continue;
                            }

                            vEvents.Add((VideoEvent)evnt);
                        }
                    }
                }
            }

            foreach (VideoEvent vEvent in vEvents)
            {
                int vStreamCount = vEvent.ActiveTake.Media.StreamCount(MediaType.Video);
                if (vStreamCount < 2)
                {
                    continue;
                }

                // If you hold down Ctrl and click the script icon on the toolbar, the selected event will be converted to Stream 1 (in a programming sense, it's a video stream with Index 0).
                if (ctrlMode)
                {
                    Take newTake = Take.CreateInstance(project, vEvent.ActiveTake.Media.GetVideoStreamByIndex(0));
                    vEvent.Takes.Clear();
                    vEvent.Takes.Add(newTake);
                }

                int vStreamIndex = GetVideoStreamIndex(vEvent), vStreamCountAdd = Mod(vStreamIndex - 1, vStreamCount);

                if (vStreamCountAdd == 0)
                {
                    continue;
                }

                TrackEventGroup grp = vEvent.Group;
                if (grp == null)
                {
                    grp = new TrackEventGroup(project);
                    project.Groups.Add(grp);
                    grp.Add(vEvent);
                }

                Timecode length = Timecode.FromNanos((long)(vEvent.Length.Nanos / vStreamCountAdd)), start = vEvent.Start;
                if (vStreamIndex != 0)
                {
                    length = vEvent.Length;
                    start += length;
                }

                for (int i = 0; i < vStreamCountAdd; i++)
                {
                    foreach (VideoEvent evnt in vEvent.Track.Events)
                    {
                        if (evnt.Start == start && evnt.Length == length && evnt != vEvent)
                        {
                            if (evnt.ActiveTake == null || evnt.ActiveTake.Media == null || evnt.ActiveTake.MediaStream == null || evnt.ActiveTake.Media == vEvent.ActiveTake.Media)
                            {
                                vEvent.Track.Events.Remove(evnt);
                            }
                        }
                    }

                    VideoEvent newEvent = (VideoEvent) vEvent.Copy(vEvent.Track, start);
                    newEvent.Length = length;
                    Take newTake = Take.CreateInstance(project, vEvent.ActiveTake.Media.GetVideoStreamByIndex(vStreamCountAdd - i));
                    newEvent.Takes.Clear();
                    newEvent.Takes.Add(newTake);
                    grp.Add(newEvent);
                    start += length;
                }

                if (vStreamIndex == 0)
                {
                    vEvent.Track.Events.Remove(vEvent);
                }
            }
        }

        public static int Mod(double a, double b)
        {
            int c = (int)(a - Math.Floor(a / b) * b);
            return c;
        }

        public static int GetVideoStreamIndex(VideoEvent vEvent)
        {
            int i = -1;
            foreach (MediaStream ms in vEvent.ActiveTake.Media.Streams)
            {
                if (ms.MediaType == MediaType.Video)
                {
                    i++;
                    if (ms == vEvent.ActiveTake.MediaStream)
                    {
                        return i;
                    }
                }
            }
            return 0;
        }
    }
}

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

 

Last changed by zzzzzz9125 on 7/21/2024, 7:56 PM, changed a total of 1 times.

Using VEGAS Pro 22 build 194 & VEGAS Pro 21 build 208.

Information about my PC:
Brand Name: HP VICTUS Laptop
System: Windows 11.0 (64-bit) 10.00.22631
CPU: 12th Gen Intel(R) Core(TM) i7-12700H
GPU: NVIDIA GeForce RTX 3050 Laptop GPU
GPU Driver: NVIDIA Studio Driver 560.70

joelsonforte.br wrote on 7/21/2024, 8:03 PM

@zzzzzz9125

I think that Stream 1 has to be added to the code along with the other events created, as the Stream 1 corresponds to all layers of the PSD file.

zzzzzz9125 wrote on 7/21/2024, 8:25 PM

I think that Stream 1 has to be added to the code along with the other events created, as the Stream 1 corresponds to all layers of the PSD file.


@joelsonforte.br How about this? The script now leaves Stream 1 at the beginning.

using System;
using System.Windows.Forms;
using System.Collections.Generic;

using ScriptPortal.Vegas;  // "ScriptPortal.Vegas" for Magix Vegas Pro 14 or above, "Sony.Vegas" for Sony Vegas Pro 13 or below

namespace Test_Script
{

    public class Class
    {
        public Vegas myVegas;
        
        public void Main(Vegas vegas)
        {
            myVegas = vegas;
            myVegas.ResumePlaybackOnScriptExit = true;
            Project project = myVegas.Project;
            Tracks myTracks = project.Tracks;
            bool ctrlMode = ((Control.ModifierKeys & Keys.Control) != 0) ? true : false;

            List<VideoEvent> vEvents = new List<VideoEvent>();
            foreach (Track myTrack in project.Tracks)
            {
                if (myTrack.IsVideo())
                {
                    foreach (TrackEvent evnt in myTrack.Events)
                    {
                        if (evnt.Selected)
                        {
                            if (evnt.ActiveTake == null || evnt.ActiveTake.Media == null || evnt.ActiveTake.MediaStream == null)
                            {
                                continue;
                            }

                            vEvents.Add((VideoEvent)evnt);
                        }
                    }
                }
            }

            foreach (VideoEvent vEvent in vEvents)
            {
                int vStreamCount = vEvent.ActiveTake.Media.StreamCount(MediaType.Video);
                if (vStreamCount < 2)
                {
                    continue;
                }

                // If you hold down Ctrl and click the script icon on the toolbar, the selected event will be converted to Stream 1 (in a programming sense, it's a video stream with Index 0).
                if (ctrlMode)
                {
                    Take newTake = Take.CreateInstance(project, vEvent.ActiveTake.Media.GetVideoStreamByIndex(0));
                    vEvent.Takes.Clear();
                    vEvent.Takes.Add(newTake);
                }

                int vStreamIndex = GetVideoStreamIndex(vEvent), vStreamCountAdd = Mod(vStreamIndex - 1, vStreamCount);

                if (vStreamCountAdd == 0)
                {
                    continue;
                }

                TrackEventGroup grp = vEvent.Group;
                if (grp == null)
                {
                    grp = new TrackEventGroup(project);
                    project.Groups.Add(grp);
                    grp.Add(vEvent);
                }

                Timecode length = vStreamIndex == 0 ? Timecode.FromNanos((long)(vEvent.Length.Nanos / vStreamCount)) : vEvent.Length;
                vEvent.Length = length;
                Timecode start = vEvent.End;

                for (int i = 0; i < vStreamCountAdd; i++)
                {
                    foreach (VideoEvent evnt in vEvent.Track.Events)
                    {
                        if (evnt.Start == start && evnt.Length == length && evnt != vEvent)
                        {
                            if (evnt.ActiveTake == null || evnt.ActiveTake.Media == null || evnt.ActiveTake.MediaStream == null || evnt.ActiveTake.Media == vEvent.ActiveTake.Media)
                            {
                                vEvent.Track.Events.Remove(evnt);
                            }
                        }
                    }

                    VideoEvent newEvent = (VideoEvent) vEvent.Copy(vEvent.Track, start);
                    newEvent.Length = length;
                    Take newTake = Take.CreateInstance(project, vEvent.ActiveTake.Media.GetVideoStreamByIndex(vStreamCountAdd - i));
                    newEvent.Takes.Clear();
                    newEvent.Takes.Add(newTake);
                    grp.Add(newEvent);
                    start += length;
                }
            }
        }

        public static int Mod(double a, double b)
        {
            int c = (int)(a - Math.Floor(a / b) * b);
            return c;
        }

        public static int GetVideoStreamIndex(VideoEvent vEvent)
        {
            int i = -1;
            foreach (MediaStream ms in vEvent.ActiveTake.Media.Streams)
            {
                if (ms.MediaType == MediaType.Video)
                {
                    i++;
                    if (ms == vEvent.ActiveTake.MediaStream)
                    {
                        return i;
                    }
                }
            }
            return 0;
        }
    }
}

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

Last changed by zzzzzz9125 on 7/21/2024, 8:31 PM, changed a total of 3 times.

Using VEGAS Pro 22 build 194 & VEGAS Pro 21 build 208.

Information about my PC:
Brand Name: HP VICTUS Laptop
System: Windows 11.0 (64-bit) 10.00.22631
CPU: 12th Gen Intel(R) Core(TM) i7-12700H
GPU: NVIDIA GeForce RTX 3050 Laptop GPU
GPU Driver: NVIDIA Studio Driver 560.70

joelsonforte.br wrote on 7/21/2024, 8:35 PM

@zzzzzz9125 Perfect! That's exactly what I was talking about. Thanks!

I took advantage of your script and made a version that converts all layers of the PSD file into Takes. It's my way of saying thank you!

Here is a demonstration of how it works

using System;
using System.Windows.Forms;
using ScriptPortal.Vegas;  // "ScriptPortal.Vegas" for Magix Vegas Pro 14 or above, "Sony.Vegas" for Sony Vegas Pro 13 or below

namespace Test_Script
{
    public class Class
    {
        public Vegas myVegas;

        public void Main(Vegas vegas)
        {
            myVegas = vegas;
            myVegas.ResumePlaybackOnScriptExit = true;
            Project project = myVegas.Project;
            Tracks myTracks = project.Tracks;

            foreach (Track track in myTracks)
            {
                if (track.IsVideo())
                {
                    foreach (VideoEvent vEvent in track.Events)
                    {
                        if (vEvent.Selected)
                        {
                            Media media = vEvent.ActiveTake.Media;

                            if (media == null)
                            {
                                continue;
                            }

                            int layerCount = media.StreamCount(MediaType.Video);

                            if (layerCount <= 1)
                            {
                                continue;
                            }

                            // Clear existing takes and add the merged take first
                            vEvent.Takes.Clear();
                            Take mergedTake = Take.CreateInstance(project, media.GetVideoStreamByIndex(0));  // Assuming index 0 is the merged stream
                            vEvent.Takes.Add(mergedTake);

                            // Add takes for each layer
                            for (int i = 1; i < layerCount; i++)
                            {
                                MediaStream layerStream = media.GetVideoStreamByIndex(i);
                                Take newTake = Take.CreateInstance(project, layerStream);
                                vEvent.Takes.Add(newTake);
                            }

                            // Ensure the first take (merged) is active
                            vEvent.ActiveTake = vEvent.Takes[0];
                        }
                    }
                }
            }
        }
    }

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

 

zzzzzz9125 wrote on 7/21/2024, 9:14 PM

Perfect! That's exactly what I was talking about. Thanks!

I took advantage of your script and made a version that converts all layers of the PSD file into Takes. It's my way of saying thank you!

Here is a demonstration of how it works

@joelsonforte.br👍Cool icons, could you share them here? Perhaps I will incorporate all the .psd-related scripts into my Miscz Projects, and they will be organized into a systematic extension rather than individual scripts.

Last changed by zzzzzz9125 on 7/21/2024, 9:15 PM, changed a total of 1 times.

Using VEGAS Pro 22 build 194 & VEGAS Pro 21 build 208.

Information about my PC:
Brand Name: HP VICTUS Laptop
System: Windows 11.0 (64-bit) 10.00.22631
CPU: 12th Gen Intel(R) Core(TM) i7-12700H
GPU: NVIDIA GeForce RTX 3050 Laptop GPU
GPU Driver: NVIDIA Studio Driver 560.70

joelsonforte.br wrote on 7/21/2024, 9:29 PM

@zzzzzz9125 The files are at this link.
https://www.dropbox.com/scl/fi/t5zazz6ykl5404rrr9clp/Add-PSD-Layers.zip?rlkey=ytgtsoyxln1cena5a74jpbs2f&st=l2gohy92&dl=0

Let me know if any problems occur.

iEmby wrote on 7/21/2024, 10:36 PM

@joelsonforte.br sir,, is that script of AI Speech to Caption you have contains Punjabi Language

if yes can you share that ...??

PROCESSOR
     

Operating System: Windows 11 Pro 64-bit (Always Updated)
System Manufacturer: ASUS
12th Gen Intel(R) Core(TM) i7-12700 (20 CPUs), ~2.1GHz - 4.90GHz
Memory: 32GB RAM
Page File: 11134MB used, 7934MB Available
DirectX Version: DirectX 12

-----------------------------------------------

MOTHERBOARD

 

ASUS PRIME H610-CS D4
Intel® H610 (LGA 1700)
Ready for 12th Gen Intel® Processors
Micro-ATX Motherboard with DDR4
Realtek 1 Gb Ethernet
PCH Heatsink
PCIe 4.0 | M.2 slot (32Gbps) 
HDMI® | D-Sub | USB 3.2 Gen 1 ports
SATA 6 Gbps | COM header
LPT header | TPM header
Luminous Anti-Moisture Coating
5X Protection III
(Multiple Hardware Safeguards
For all-round protection)

-----------------------------------------------
EXTERNAL GRAPHIC CARD

-----------------------------------------------

INTERNAL GRAPHIC CARD (iGPU)

------------------------------------------------

LED - MONITOR

Monitor Name: Generic PnP Monitor
Monitor Model: HP 22es
Monitor Id: HWP331B
Native Mode: 1920 x 1080(p) (60.000Hz)
Output Type: HDMI

-----------------------------------------------

STORAGE DRIVE

Drive: C:
Free Space: 182.3 GB
Total Space: 253.9 GB
File System: NTFS
Model: WD Blue SN570 1TB (NVMe)

---------------O----------------

My System Info (PDF File).

https://drive.google.com/open?id=1-eoLmuXzshTRH_8RunAYAuNocKpiLoiV&usp=drive_fs

 

Also Check

VEGAS Scripts Collection By Me

GitHub Profile

My YouTube Channel Dedicated to Only VEGAS Pro Tutorials

EDITROOM : My YouTube Channel (For VEGAS Tutorials)

zzzzzz9125 wrote on 7/22/2024, 5:02 AM

@editeiro How about this one?

It pops up a window that lets you type in rate and offset. The script splits the .psd layers and does the 3D depth layout based on the rate and offset you enter.

The code is as follows:

using System;
using System.Drawing;
using System.Windows.Forms;
using System.Collections.Generic;

using ScriptPortal.Vegas;  // "ScriptPortal.Vegas" for Magix Vegas Pro 14 or above, "Sony.Vegas" for Sony Vegas Pro 13 or below

namespace Test_Script
{

    public class Class
    {
        public Vegas myVegas;
        public const CompositeMode COMPOSITEMODE = CompositeMode.SrcAlpha3D;
        public const double RATE3DDEFAULT = 10, OFFSET3DDEFAULT = 0;
        
        public void Main(Vegas vegas)
        {
            myVegas = vegas;
            myVegas.ResumePlaybackOnScriptExit = true;
            Project project = myVegas.Project;
            bool ctrlMode = ((Control.ModifierKeys & Keys.Control) != 0) ? true : false;

            double rate3D = RATE3DDEFAULT, offset3D = OFFSET3DDEFAULT;
            if (COMPOSITEMODE == CompositeMode.SrcAlpha3D)
            {
                DialogResult result = PopUpWindow(out rate3D, out offset3D);
                if (result != DialogResult.OK)
                {
                    return;
                }
            }

            foreach (VideoEvent vEvent in GetSelectedVideoEvents(project, true))
            {
                if (vEvent.ActiveTake == null || vEvent.ActiveTake.Media == null || vEvent.ActiveTake.MediaStream == null)
                {
                    continue;
                }

                int vStreamCount = vEvent.ActiveTake.Media.StreamCount(MediaType.Video);
                if (vStreamCount < 2)
                {
                    continue;
                }

                // If you hold down Ctrl and click the script icon on the toolbar, the selected event will be converted to Stream 1 (in a programming sense, it's a video stream with Index 0).
                if (ctrlMode)
                {
                    Take newTake = Take.CreateInstance(project, vEvent.ActiveTake.Media.GetVideoStreamByIndex(0));
                    vEvent.Takes.Clear();
                    vEvent.Takes.Add(newTake);
                }

                int vStreamIndex = GetVideoStreamIndex(vEvent);
                if (vStreamIndex == 0)
                {
                    vEvent.Mute = true;
                }

                int vStreamCountAdd = Mod(vStreamIndex - 1, vStreamCount);

                TrackEventGroup grp = vEvent.Group;
                if (grp == null)
                {
                    grp = new TrackEventGroup(project);
                    project.Groups.Add(grp);
                    grp.Add(vEvent);
                }

                VideoTrack myTrack = (VideoTrack)vEvent.Track;

                if (vStreamIndex == 0 && myTrack.Effects.Count > 0 && COMPOSITEMODE == CompositeMode.SrcAlpha3D)
                {
                    foreach (Effect ef in myTrack.Effects)
                    {
                        ef.ApplyAfterComposite = true;
                    }

                    myTrack = AddNewTrack(myVegas, myTrack, 0, true, trackCM: CompositeMode.SrcAlpha);
                    vEvent.Track = myTrack;
                }
                else
                {
                    myTrack.SetCompositeMode(COMPOSITEMODE, false);
                }

                for (int i = 0; i < vStreamCountAdd; i++)
                {
                    VideoTrack newTrack = AddNewTrack(myVegas, myTrack, i, vStreamIndex == 0, rate3D, offset3D);

                    foreach (VideoEvent evnt in newTrack.Events)
                    {
                        if (evnt.Start == vEvent.Start)
                        {
                            if (evnt.ActiveTake == null || evnt.ActiveTake.Media == null || evnt.ActiveTake.MediaStream == null || evnt.ActiveTake.Media == vEvent.ActiveTake.Media)
                            {
                                newTrack.Events.Remove(evnt);
                            }
                        }
                    }

                    VideoEvent newEvent = (VideoEvent) vEvent.Copy(newTrack, vEvent.Start);
                    Take newTake = Take.CreateInstance(project, vEvent.ActiveTake.Media.GetVideoStreamByIndex(vStreamCountAdd - i));
                    newEvent.Takes.Clear();
                    newEvent.Takes.Add(newTake);
                    newEvent.Selected = false;
                    newEvent.Mute = false;
                    grp.Add(newEvent);
                }
            }
        }

        static DialogResult PopUpWindow(out double rate, out double offset)
        {
            rate = RATE3DDEFAULT;
            offset  = OFFSET3DDEFAULT;
            Form form = new Form();
            form.SuspendLayout();
            form.ShowInTaskbar = false;
            form.AutoSize = true;
            form.BackColor = Color.FromArgb(45,45,45);
            form.ForeColor = Color.FromArgb(200,200,200);
            if (System.Diagnostics.FileVersionInfo.GetVersionInfo(Application.ExecutablePath).FileMajorPart < 15)
            {
                form.BackColor = Color.FromArgb(153,153,153);
                form.ForeColor = Color.FromArgb(0,0,0);
            }
            form.Font = new Font("Arial", 9);
            form.Text = "PSD 3D";
            form.FormBorderStyle = FormBorderStyle.FixedToolWindow;
            form.StartPosition = FormStartPosition.CenterScreen;
            form.AutoSizeMode = AutoSizeMode.GrowAndShrink;

            Panel p = new Panel();
            p.AutoSize = true;
            p.AutoSizeMode = AutoSizeMode.GrowAndShrink;
            form.Controls.Add(p);

            TableLayoutPanel l = new TableLayoutPanel();
            l.AutoSize = true;
            l.AutoSizeMode = AutoSizeMode.GrowAndShrink;
            l.GrowStyle = TableLayoutPanelGrowStyle.AddRows;
            l.ColumnCount = 2;
            l.ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, 70));
            l.ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, 70));
            p.Controls.Add(l);

            Label label = new Label();
            label.Margin = new Padding(6, 10, 6, 6);
            label.Text = "Rate";
            label.AutoSize = true;
            l.Controls.Add(label);

            TextBox rateBox = new TextBox();
            rateBox.AutoSize = true;
            rateBox.Margin = new Padding(6, 6, 6, 6);
            rateBox.Text = rate.ToString();
            l.Controls.Add(rateBox);

            label = new Label();
            label.Margin = new Padding(6, 10, 6, 6);
            label.Text = "Offset";
            label.AutoSize = true;
            l.Controls.Add(label);

            TextBox offsetBox = new TextBox();
            offsetBox.AutoSize = true;
            offsetBox.Margin = new Padding(6, 6, 6, 6);
            offsetBox.Text = offset.ToString();
            l.Controls.Add(offsetBox);

            FlowLayoutPanel panel = new FlowLayoutPanel();
            panel.FlowDirection = FlowDirection.RightToLeft;
            panel.AutoSize = true;
            panel.AutoSizeMode = AutoSizeMode.GrowAndShrink;
            panel.Anchor = AnchorStyles.None;
            l.Controls.Add(panel);
            l.SetColumnSpan(panel, 3);
            panel.Font = new Font("Arial", 8);

            Button ok = new Button();
            ok.Text = "OK";
            ok.DialogResult = DialogResult.OK;
            panel.Controls.Add(ok);
            form.AcceptButton = ok;

            form.ResumeLayout();

            DialogResult result = form.ShowDialog();
            double.TryParse(rateBox.Text, out rate);
            double.TryParse(offsetBox.Text, out offset);
            return result;
        }

        public static int Mod(double a, double b)
        {
            return (int)(a - Math.Floor(a / b) * b);
        }

        public static List<VideoEvent> GetSelectedVideoEvents(Project project, bool reverse = false)
        {
            List<VideoEvent> vEvents = new List<VideoEvent>();
            foreach (Track myTrack in project.Tracks)
            {
                if (myTrack.IsVideo())
                {
                    foreach (TrackEvent evnt in myTrack.Events)
                    {
                        if (evnt.Selected)
                        {
                            if (evnt.ActiveTake == null || evnt.ActiveTake.Media == null || evnt.ActiveTake.MediaStream == null)
                            {
                                continue;
                            }

                            vEvents.Add((VideoEvent)evnt);
                        }
                    }
                }
            }
            if (reverse)
            {
                vEvents.Reverse();
            }

            return vEvents;
        }

        public static int GetVideoStreamIndex(VideoEvent vEvent)
        {
            int i = -1;
            foreach (MediaStream ms in vEvent.ActiveTake.Media.Streams)
            {
                if (ms.MediaType == MediaType.Video)
                {
                    i++;
                    if (ms == vEvent.ActiveTake.MediaStream)
                    {
                        return i;
                    }
                }
            }
            return 0;
        }

        public static VideoTrack AddNewTrack(Vegas vegas, VideoTrack track, int i, bool isFirst, double rate = 0, double offset = 0, CompositeMode trackCM = COMPOSITEMODE)
        {
            VideoTrack newTrack = null;
            int j = i + track.Index;
            if (j < vegas.Project.Tracks.Count - 1)
            {
                Track trackBelow = vegas.Project.Tracks[j + 1];
                if (trackBelow.IsVideo())
                {
                    VideoTrack vt = (VideoTrack)trackBelow;
                    if (!vt.IsCompositingParent && vt.CompositeMode == track.CompositeMode && (isFirst ? vt.CompositeNestingLevel == track.CompositeNestingLevel + 1 : vt.CompositeNestingLevel == track.CompositeNestingLevel))
                    {
                        newTrack = (VideoTrack)trackBelow;
                    }
                }
            }

            if (newTrack == null)
            {
                newTrack = new VideoTrack(vegas.Project, j + 1, null);
                vegas.Project.Tracks.Add(newTrack);
                newTrack.CompositeNestingLevel = track.CompositeNestingLevel;
                if (isFirst)
                {
                    newTrack.CompositeNestingLevel += 1;
                }

                if (track.IsCompositingParent)
                {
                    track.SetParentCompositeMode(trackCM, false);
                }
                newTrack.SetCompositeMode(COMPOSITEMODE, false);

                newTrack.Name = track.Name;
                newTrack.Solo = track.Solo;
                newTrack.Mute = track.Mute;
            }

            if (COMPOSITEMODE == CompositeMode.SrcAlpha3D)
            {
                SetTrackMotion3D(vegas, newTrack, i, rate, offset);
            }

            return newTrack;
        }

        public static void SetTrackMotion3D(Vegas vegas, VideoTrack track, int i, double rate = 0, double offset = 0)
        {
            if (track.CompositeMode != CompositeMode.SrcAlpha3D)
            {
                return;
            }

            double unit = vegas.Project.Video.Height / 20, m = (i * rate - offset) / 100;

            foreach (TrackMotionKeyframe kf in track.TrackMotion.MotionKeyframes)
            {
                kf.Depth = unit * (1 + m);
                kf.Width = vegas.Project.Video.Width * (1 + m);
                kf.Height = vegas.Project.Video.Height * (1 + m);
                kf.PositionZ = unit * m * 193 / 9;
            }
        }
    }
}


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

 

In the end, I use a formula, which is obtained after my calculation, that is, if the size of the object in the screen is to remain unchanged while the width and height of the object completely change with the depth, the depth value and z value must meet the following formula:

z = (depth - projectHeight / 20) * 193 / 9

Feedback is welcome if you have any questions.

Last changed by zzzzzz9125 on 7/22/2024, 5:03 AM, changed a total of 1 times.

Using VEGAS Pro 22 build 194 & VEGAS Pro 21 build 208.

Information about my PC:
Brand Name: HP VICTUS Laptop
System: Windows 11.0 (64-bit) 10.00.22631
CPU: 12th Gen Intel(R) Core(TM) i7-12700H
GPU: NVIDIA GeForce RTX 3050 Laptop GPU
GPU Driver: NVIDIA Studio Driver 560.70

iEmby wrote on 7/22/2024, 3:44 PM

@joelsonforte.br @editeiro @zzzzzz9125 @jetdv

please share you finished OK scripts here

https://www.vegascreativesoftware.info/us/forum/vegas-pro-scripts-collections-share-your-script-here--145667/

so that user can find it easily.

Thankyou.

PROCESSOR
     

Operating System: Windows 11 Pro 64-bit (Always Updated)
System Manufacturer: ASUS
12th Gen Intel(R) Core(TM) i7-12700 (20 CPUs), ~2.1GHz - 4.90GHz
Memory: 32GB RAM
Page File: 11134MB used, 7934MB Available
DirectX Version: DirectX 12

-----------------------------------------------

MOTHERBOARD

 

ASUS PRIME H610-CS D4
Intel® H610 (LGA 1700)
Ready for 12th Gen Intel® Processors
Micro-ATX Motherboard with DDR4
Realtek 1 Gb Ethernet
PCH Heatsink
PCIe 4.0 | M.2 slot (32Gbps) 
HDMI® | D-Sub | USB 3.2 Gen 1 ports
SATA 6 Gbps | COM header
LPT header | TPM header
Luminous Anti-Moisture Coating
5X Protection III
(Multiple Hardware Safeguards
For all-round protection)

-----------------------------------------------
EXTERNAL GRAPHIC CARD

-----------------------------------------------

INTERNAL GRAPHIC CARD (iGPU)

------------------------------------------------

LED - MONITOR

Monitor Name: Generic PnP Monitor
Monitor Model: HP 22es
Monitor Id: HWP331B
Native Mode: 1920 x 1080(p) (60.000Hz)
Output Type: HDMI

-----------------------------------------------

STORAGE DRIVE

Drive: C:
Free Space: 182.3 GB
Total Space: 253.9 GB
File System: NTFS
Model: WD Blue SN570 1TB (NVMe)

---------------O----------------

My System Info (PDF File).

https://drive.google.com/open?id=1-eoLmuXzshTRH_8RunAYAuNocKpiLoiV&usp=drive_fs

 

Also Check

VEGAS Scripts Collection By Me

GitHub Profile

My YouTube Channel Dedicated to Only VEGAS Pro Tutorials

EDITROOM : My YouTube Channel (For VEGAS Tutorials)