Skip to content

lib

execute_sptree_command(zscript, communicator=None)

Execute Speedtree command.

Note that this will not wait around for the Speedtree command to run or for its completion. Nor will errors in the script be detected or raised.

Source code in client/ayon_speedtree/api/lib.py
29
30
31
32
33
34
35
36
37
38
39
def execute_sptree_command(zscript, communicator=None):
    """Execute Speedtree command.

    Note that this will *not* wait around for the Speedtree command to run or
    for its completion. Nor will errors in the script be detected or raised.

    """
    if not communicator:
        communicator = CommunicationWrapper.communicator
    print(f"Executing speedtree command: {zscript}")
    return communicator.execute_sptree_command(zscript)

export_model(current_file, fbx_filepath, xml_filepath)

Function to export model in fbx format along with the xml file.

Parameters:

Name Type Description Default
current_file str

current file

required
fbx_filepath str

fbx output filepath

required
xml_filepath str

xml output filepath

required
Source code in client/ayon_speedtree/api/lib.py
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
def export_model(current_file: str, fbx_filepath: str, xml_filepath: str):
    """Function to export model in fbx format along with the xml file.

    Args:
        current_file (str): current file
        fbx_filepath (str): fbx output filepath
        xml_filepath (str): xml output filepath
    """
    resource_path = os.path.dirname(os.path.dirname(os.environ["SPTREE_EXE"]))
    resource_path = os.path.normpath(resource_path)
    SpeedTree.StpSetExportResourcePath(resource_path)
    context = SpeedTree.StpContext()
    context.new()
    loaded, _ = context.loadSpeedTreeFile(current_file)
    if loaded:
        # Configure FBX export options
        export_options = SpeedTree.StpVfxExportOptions()
        export_options.initVfxExportOptions()

        # Set FBX-specific options
        export_options.fbxCacheCompatible = True
        export_options.fbxCacheFormat = (
            SpeedTree.StpFbxCacheFormat.STP_FBX_CACHE_FORMAT_MCX
        )
        export_options.fbxAxis = SpeedTree.StpFbxAxis.STP_FBX_AXIS_MAYA_Y_UP
        export_options.fbxBonesSmooth = True
        # Set other export options
        export_options.include3dGeometry = True
        export_options.includeBones = True
        export_options.animationWind = True
        export_options.animationFPS = 30
        export_options.textureSkipWriting = True
        fbx_success = context.exportForVfx(fbx_filepath, export_options)
        xml_success = context.exportForVfx(xml_filepath, export_options)
        # Cleanup
        if fbx_success and xml_success:
            log.debug("Successfully export tree model.")

    context.delete()

get_workdir()

Return the currently active work directory

Source code in client/ayon_speedtree/api/lib.py
24
25
26
def get_workdir() -> str:
    """Return the currently active work directory"""
    return os.environ["AYON_WORKDIR"]

load_spm_file(spm_file, communicator=None)

Load spm file for either loading existing file or refreshing purpose. There is no way in SpeedTree to increment and save for current workfile. Ayon needs to always save and re-load the spm file again for getting the latest version.

Source code in client/ayon_speedtree/api/lib.py
117
118
119
120
121
122
123
124
125
126
127
def load_spm_file(spm_file, communicator=None):
    """Load spm file for either loading existing file or refreshing purpose.
    There is no way in SpeedTree to increment and save for current workfile.
    Ayon needs to always save and re-load the spm file again for getting
    the latest version.
    """
    if not communicator:
        communicator = CommunicationWrapper.communicator
    print(f"Loading Spm file: {spm_file}")
    speedtree_executable = os.environ["SPTREE_EXE"]
    return communicator.replace_process([speedtree_executable, spm_file])

save_scene(window_title)

Hacky function to save file during context before passing it into the headless SDR to publish or increment and save file

Parameters:

Name Type Description Default
window_title str

Current Ayon tool windows.

required
Source code in client/ayon_speedtree/api/lib.py
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
@contextlib.contextmanager
def save_scene(window_title):
    """Hacky function to save file during context before passing
    it into the headless SDR to publish or increment and save file

    Args:
        window_title (str, optional): Current Ayon tool windows.

    """
    prev_hwnd = user32.FindWindowW(None, window_title)
    hwnd = user32.FindWindowW(None, "SpeedTree  Modeler 10.0.0 ")
    if hwnd:
        if user32.IsIconic(hwnd):
            user32.ShowWindow(hwnd, SW_RESTORE)
        user32.SetForegroundWindow(hwnd)
        _save_file_with_hotkey()
    try:
        yield
    finally:
        user32.ShowWindow(prev_hwnd, SW_RESTORE)