Learn how to customize the VRED Core with typical use cases.
Video Captions: Hello and welcome to this tutorial for VRED Core. I'm your host Christopher and today I will continue the tutorial on use cases and automating tasks with VRED Core that we started in the last video. I will show you how you can build pipelines that render scenes, convert files to another file format, and optimize your Scenegraph using simple automation scripts that process multiple files all at once.
There are many different ways to write automated scripts for VRED Core, and it also depends on your operating system, your use case, and many other factors. That's why there’s no correct way to write scripts, but there are good and not-so-good ways.
In this tutorial, I will use Python scripts to automate VRED Core pipelines, but you could achieve the same result with batch script on Windows or shared scripts on Linux, or a whole different approach. This is just to give you an idea about what you can do.
I'm using the Visual Studio Code environment which is free to use with Python runtime installed on my system. With the press of a button, I can run my scripts and immediately see the results in the terminal.
Let's start with first example. I want to convert all files in a directory to another file format. In the last tutorial, we learned about the -pre and -post command line options, which help us execute code when we start VRED from the command line. With this parameter, we can tell VRED to load a file and simply save it as another file format, by changing the file extension.
In this example, I want to go a step further. I want to automatically convert all files in a directory to another file format. We start with a new Python file and define variables that configure our script. We define the path to the VRED Core executable and we define the file extension of our source file, as well as the directory where to find them. We also define the file extension of our target files, and the directory where they should be saved.
Notice how I use Window start paths here and use the r keyword to tell Python that the strings should be read exactly like it is defined here. Otherwise, we would have to escape the backslashes. I also have to create the target directory, if it doesn't exist already.
After this, we can start iterating over all the files in the source directory. We only want to process files with the correct extension, and I extract the file name without the extension to build a file path to save the converted file. Then, I build the file path for the source file and the target file. This has to be done because the variable file name only contains the file name, not the whole path.
We have to be careful with file paths here because VRED only uses Linux-style file paths internally. The Python function join, however, will return a Windows-style file path. This is why we have to replace all backslashes with the forwardslashes before we can use the file paths.
Last, but not least, we start VRED Core with the sub-process function call, and add the -pre Python parameters to convert our files. When we run the script, all files from the Source directory will be loaded in VRED and saved as another file format into target directory.
You already might suspect that this is not the most efficient way to automate a task with VRED Core. This is because for every file, our script will start VRED, which takes some time, processes the files, and closes VRED again.
This is fine for a handful of files, but if you want to process many files in a short time, this script has too much overhead. But don't worry, we will fix this in our next example.
Let's have a look at batch rendering, or to be more precise, how we can customize automated rendering in VRED Pro. You are often faced with a problem that you have to render a lot of frames with different combinations of viewpoints and variants. This is quite easy in VRED Pro, because you can use the render settings to tell VRED to render every combination of variant sets and viewpoints in your sequence.
But of course, we want you to achieve the same result in VRED Core with a Python script. Again, we start with a new Python file, while we add our code that will render all of our combinations of viewpoints and variant sets. At first, we define a few variables that tell the script where the VRED file is located, which variants we want to use, and which viewpoints we want to render. We also define a path template that’ll be used to generate a new file name where we can sort a rendered image.
Next, we load the VRED file with the load function and start iterating over all the viewpoints and variants sets. And this will, one after the other, select this particular state in the scene, and then render the image with createSnapshot.
Here, we follow our path template we defined earlier with the name of the viewpoint and the variant and we also set our rendering resolution. This Python script will render all our images for us, but we somehow have to import the script into VRED.
In the previous example, we used the -pre Python parameter and the whole script is loaded just like regular Python file. There are online services where you can encode a text or a file as base64 and you could take the result as a parameter for VRED.
This string of letters and numbers is the same code just encoded, so that VRED can understand and read it as a real Python code. We could just copy and paste the base64 string of the -pre Python parameter and the whole script is loaded just like regular Python file. There are online services where you can encode a text or a file as base64 and you can take the result as a parameter for VRED.
This string letters and numbers is the same code just encoded, so that VRED can understand and read it as a real Python code. We can just copy and paste the base64 string of the -pre Python parameter, but in this example, we want to show you how you can encode the VRED script directly in our Python script.
To do this, we have to surround the Python code block with triple quotes, and store the text in the variable. The triple quotes ensure that the code block is interpreted exactly as it is written here, line by line. The script has to be a valid Python script, so white space and everything has to be correct, otherwise, it will throw an error when VRED tries to run it.
Now, we can use the variable to encode its content to base64 with this line of code. The last line, will start VRED Core with the parameter -pre Python and the encoded Python script as an input. We only have to add some missing imports to the top and are ready to go.Running the script will take a while, but in the end, we should have rendered nine different images of our scene.
Okay, so we can import a whole Python script into VRED Core with base64 encoding, which is great, but the way we did it, in this example, still has some downsides. The main down is that the VRED Python script is in the same file as the automation Python script.
And, as you can see, our IE doesn't show the normal Python syntax highlighting when we put the VRED script in quotes. The script is just hard to read and maintain this way, therefore, we will optimize it further in the next example where we will show you how you can automate optimizations in scene geometry.
This time, we will need two Python files, one containing the VRED Python scripts and the other one is to start VRED Core with this script as the input. In our VRED script, we start like in the data conversion example, and define variables for a directory that contains the unoptimized files and one for the optimized files.
Of course, we also have to create the directory if it does not exist yet. We iterate over the unoptimized files, create a source and a target file path, load the unoptimized file, and apply our optimizations. These optimizations are defined in the vrOptimize module in the Python API 1 of VRED. You can find the documentation online.
There are lots of optimizations you can apply, and depending on your geometry and your use case, these optimizations will, of course, vary. These two options I chose, are just an example here. At the end, we only have to save our file to the target file path. When all files have been processed, we can terminate VRED. So this script will be directly imported into VRED using the same base64 encoding method like in the previous example. But this time, we start VRED from another Python script to keep them separate.
Now a second Python file, we define a path to VRED Core and we also define a path to the directory where the two files are stored. This can be done with the file attribute of this Python script that contains the whole path to exactly this script when it is executed. Then we open a VRED script file that we just created and that is located in the same directory and read its content. And then we can encode the file content as base64 and start VRED like in the previous example.
Separating the VRED script and the automation script has the advantage that you can reuse in the VRED script in other pipelines, and you have the full advantage if developing in an IDE, like in Visual Studio, like syntax highlighting.
In this example, you can also see that we start VRED only once, and then process all files inside the running VRED instance, which is much more efficient than starting VRED for every file we want to optimize.
So, you see, there's a multitude of ways to automate in script rendering or data preparation pipelines in VRED. And this can be done with Python, but also with other scripting languages like batch, shell, or whatever you like. This totally depends on the task, the use cases, and the development environment you use. But the underlying principles are always similar. You use the -pre and -post Python command line parameters to inject a Python script into VRED, which does the processing for you. And these Python scripts can use a whole range of functions defined in VRED's Python API.
I hope I could give you some starting points how to script your first automated VRED pipeline. That's it for today. I hope you enjoyed the scripting tutorial and I'll see you next time.
Here are the accompanying example Python scripts for the Tutorial 4: How to Customize VRED Core with Typical Use Cases video.
To download these files zipped, click here.
import base64
import subprocess
import os
print("=[VRED Core Tutorial] Batch Data Conversion")
vredCorePath = r'D:\Programme\Autodesk\VREDCore-13.3\bin\WIN64\VREDCore.exe'
sourceExtension = 'vpb'
sourceDirectory = r'C:\VRED_Examples\vpb'
targetExtension = 'fbx'
targetDirectory = r'C:\VRED_Examples\fbx'
# Create target directory if it does not exist
if not os.path.exists(targetDirectory):
os.makedirs(targetDirectory)
# Iterate over files in source directory and process each filename
for filename in os.listdir(sourceDirectory):
# ... but only if the file extension matches
if filename.endswith(sourceExtension):
# Extract the file name without the extension
namePart = filename.split('.')[0]
print("=[VRED Core Tutorial] Data Conversion: {} from {} to {}".format(namePart, sourceExtension, targetExtension))
# Create paths for the source and the target file
# Replace windows backslashes with linux style forward slashes
sourcePath = os.path.join(sourceDirectory, filename).replace('\\','/')
targetPath = os.path.join(targetDirectory, '{}.{}'.format(namePart, targetExtension)).replace('\\','/')
# Start vred and process files
subprocess.call([vredCorePath, '-prepython=load("{}"); save("{}"); terminateVred()'.format(sourcePath, targetPath)])
print("=[VRED Core Tutorial] Finished Batch Data Conversion...")
import os
import base64
import subprocess
vredCorePath = r'D:\Programme\Autodesk\VREDCore-13.3\bin\WIN64\VREDCore.exe'
directory = os.path.dirname(__file__)
with open(os.path.join(directory, 'batch-data-optimization.py'), 'r') as file:
# Read file content
scriptContent = file.read()
# Convert python script to base64, in order to import it into VRED
base64EncodedScript = base64.b64encode(scriptContent.encode('UTF-8')).decode('UTF-8')
# Start VRED with prepython and the base64 encoded script as input
subprocess.call([vredCorePath, '-prepython={}'.format(base64EncodedScript)])
import os
print("=[VRED Core Tutorial] Batch Data Optimization")
sourceDirectory = 'C:/VRED_Examples/unoptimized'
targetDirectory = 'C:/VRED_Examples/optimzied'
# Create target directory if it does not exist
if not os.path.exists(targetDirectory):
os.makedirs(targetDirectory)
# Iterate over files in source directory and process each filename
for filename in os.listdir(sourceDirectory):
print("=[VRED Core Tutorial] Optimize file: {}".format(filename))
# Create paths for the source and the target file
# Replace windows backslashes with linux style forward slashes
sourcePath = os.path.join(sourceDirectory, filename).replace('\\\\','/')
targetPath = os.path.join(targetDirectory, filename).replace('\\\\','/')
# Load file in VRED
load(sourcePath)
# Optimize Geometry
removeTransformNodesWithNoChildren(findNode("Root"))
optimizeIndices(findNode("Root"))
# Save optimized file
save(targetPath)
# Close VRED instance
terminateVred()
import sys
import base64
import subprocess
vredCorePath = r'D:\Programme\Autodesk\VREDCore-17.2\bin\WIN64\VREDCore.exe'
batchRenderingScript = '''
vredSceneFile = r"C:/ProgramData/Autodesk/VREDPro-<internalVersion>/examples/Automotive_Genesis.vpb"
variants = ("Black Metallic", "Blue Fire Metallic", "Silver Dark Metallic")
viewpoints = ("Home", "Left-Back", "Viewpoint")
pathTemplate = r"C:/VRED_Examples/batch_rendering/variant_{viewpoint}_{variant}.png"
print("=[VRED Core Tutorial] Load Source file...")
load(vredSceneFile)
print("=[VRED Core Tutorial] Iterate viewpoints and variants...")
for viewpointName in viewpoints:
vp = vrCameraService.getViewpoint(viewpointName)
if not vp.isNull():
vp.activate()
for variantName in variants:
print("=[VRED Core Tutorial] Rendering {}, {}".format(viewpointName, variantName))
vrVariants.selectVariantSet(variantName)
createSnapshot(pathTemplate.format(viewpoint=viewpointName, variant=variantName), 1920, 1080)
print("End")
'''
# Convert python script to base64, in order to import it into VRED
base64EncodedScript = base64.b64encode(batchRenderingScript.encode('UTF-8')).decode('UTF-8')
# Start VRED with prepython and the base64 encoded script as input
subprocess.call([vredCorePath, '-prepython={}'.format(base64EncodedScript)])