Skip to main content

Tekla Structures

tip

This guide provides the basic information about the Tekla integration.

If this is your first time setting up an integration, we recommend to follow one of the Intermediate tutorials.

System requirements:

  • 💻 Windows PC
  • 🐍 Python =< 3.11+ (pyTekla requirement)
  • PyTekla (Tekla Open API wrapper)
  • Tekla Structures (with an active model on the worker)

Additional information

Below you can find some useful information for this integration.

Download and install pyTekla

PyTekla is a Python wrapper that provides a thin wrapper around the Tekla Open API. The Tekla Open API is an API that provides a range of tools and functions that allow developers to automate processes, integrate with other software (VIKTOR in this case) and customise the behaviour of Tekla Structures software. You can follow the instructions to installing PyTekla here.

Setup environment

Before you can start building your VIKTOR - Tekla apps, you will need to complete some steps for the setup.

Step 1: Start a VIKTOR app

You will need to create, install and start an empty app. If you would like a quick reminder on how to do this, you can follow the steps here. For your VIKTOR app, you will not need to add any extra packages to your requirements.txt as they will be installed on the worker. Furthermore you can copy app.py below to get started with the VIKTOR - Tekla integration. In this example, the app.py dumps the parameters into a .json file that the worker will be able to use for run_tekla.py.


import json
from pathlib import Path

from viktor import ViktorController, File
from viktor.external.generic import GenericAnalysis
from viktor.parametrization import ViktorParametrization, NumberField, LineBreak, Text, AutocompleteField
from viktor.views import IFCResult, IFCView



class Parametrization(ViktorParametrization):
#Add your parameters here
pass


class Controller(ViktorController):
label = 'Tekla Integration Example'
parametrization = Parametrization

#Add your functions here

@IFCView("IFC Viewer", duration_guess=5)
def show_ifc(self, params, entity_id, **kwargs):
# Create empty file to dump the params json in
file = File()
params['export_ifc'] = True
with file.open() as f:
json.dump(params, f)

# Run the python script and obtain the output files
generic_analysis = GenericAnalysis(files=[('input.json', file)],
executable_key="run_tekla",
output_filenames=["output.ifc"])
generic_analysis.execute(timeout=60)

return_ifc = generic_analysis.get_output_file("output.ifc", as_file=True)

return IFCResult(return_ifc)

Step 2: Configure a generic worker

VIKTOR does not provide a dedicated worker for Tekla Structures. You can download the generic worker here.

You can follow the steps to configuring the generic worker as described in the docs. You will first need to make a folder for the worker to use as a working directory (in this example we named it viktor-tekla) to connect the worker to in the configuration. You can use the following configuration as a template, make sure to add the arguments that you will use as your inputs for Tekla:

config.yaml

executables:
tekla:
path: 'C:\Users\your-name\AppData\Local\Programs\Python\Python310\python.exe'
arguments:
- 'C:\Users\your-name\viktor-tekla\run_tekla.py'
-
workingDirectoryPath: 'C:\Users\your-name\viktor-tekla'
maxParallelProcesses: 1 #must be one, please do not change

Now that you have the worker configured and a working directory, you can create a run_tekla.py file which will contain all the instructions for the automation. Alternatively, you could also send this file to the worker but then you must add it to the config.yaml arguments. Do not run/test the worker yet, we first have to configure PyTekla.

Step 3: Configure PyTekla

Open a python environment on the machine that hosts the worker, make sure this is the Python version that you have configured in your worker.

run the following commands:

import pytekla
pytekla.config.set_tekla_path("C:/Program Files/Tekla Structures/2023.0/bin")

Make sure that the Tekla path is set to the bin folder of your Tekla Structures.

You may now run the VIKTOR worker as administrator, and connect it to your workspace.

Step 4: Start using Tekla in a VIKTOR app

There are two options to using Tekla in VIKTOR. One way is to use the PyTekla Wrapper to perform all the operations on the Tekla model. The other option is to use Tekla through Grasshopper.

Method 1: use PyTekla

You can use PyTekla's wrpapper to open, save and close models Tekla models. You can copy the boiler plate code into your run_tekla.py file to get started. Then you can add your own code to start developing with pyTekla. This boiler plate allows you to edit an active model in Tekla. Note that this boiler plate is for opening and closing models you will require some extra code.

# THIS FILE HAS TO BE ON THE VIKTOR WORKER DIRECTORY FOR THIS EXAMPLE

# Pip install required packages [on worker]
import os
import json
import math

import ctypes # An included library with Python install.

from pytekla import wrap
from Tekla.Structures.Model import Model
from Tekla.Structures.Model.Operations import Operation
from System import String


def save_model_as_ifc(path: str) -> bool:
"""This is a function to save the active Tekla model as IFC"""
model = wrap("Model.Model")
myie = List[String]()
myie.Add("..//default//General//Shared//IFC//AdditionalPSets//CIP Construction data.xml")
flags = Operation.IFCExportFlags()
flags.IsLocationFromOrganizer = True
flags.IsPoursEnabled = True

success = Operation.CreateIFC4ExportFromAll(
path,
Operation.IFCExportViewTypeEnum.REFERENCE_VIEW,
myie,
Operation.ExportBasePoint.GLOBAL,
"__Name__",
"ByObjectClass",
flags,
"")
return success


# Define path to local working directory
workdir = os.getcwd() + '\\'

# Read input parameters from JSON file
with open(workdir + 'input.json') as f:
params = json.load(f)

# Clear the model to prevent overwriting
model = wrap('Model.Model')
for tekla_obj in model.get_objects_with_types(["Beam"]):
if tekla_obj:
tekla_obj.Delete()


# Add your code here


model.commit_changes("Viktor changes") # Delete this line if you dont want Tekla visualization

# Save ifc
path = workdir + 'output.ifc'
success = save_model_as_ifc(path)

Method 2: use Grasshopper

A powerful connection can also be made with the Grasshopper-Tekla link. Tekla structures are easily created with Grasshopper and the GH-components available. When creating a VIKTOR - Tekla app, Grasshopper can also be used. The main issue is that we want a .ifc from the Tekla model; and Grasshopper nodes don't allow for saving / export Tekla files. This can be solved like this:

  • Follow this guide to set up your VIKTOR app that communicates with GH.
  • Have your worker look for an output.ifc in your worker-directory
  • Use these Grasshopper nodes to create a Tekla model
  • Add the following C# component to your Grasshopper file (feel free to replace some defaults, documentation here):
if (run){
Model model = new Model();
success = Operation.CreateIFC4ExportFromAll(
ifc_path,
Operation.IFCExportViewTypeEnum.REFERENCE_VIEW,
new List<string> { @"..\\default\\General\\Shared\\IFC\\AdditionalPSets\\CIP Construction data.xml" },
Operation.ExportBasePoint.GLOBAL,
"__Name__",
"ByObjectClass",
new Operation.IFCExportFlags { IsLocationFromOrganizer = true, IsPoursEnabled = true},
string.Empty);
}
success = true;
  • you can then add the success output to a context print (this way the worker will know the script is finished).

Below you can find an example of how this may look:

Would you like to see an example?

VIKTOR offers a wide variety of sample repositories on GitHub, one of which is the PyTekla integration app.

Testing

New in v13.5.0

mock_GenericAnalysis decorator for easier testing of GenericAnalysis

GenericAnalysis.execute needs to be mocked within the context of (automated) testing.

The viktor.testing module provides the mock_GenericAnalysis decorator that facilitate mocking of workers:

import unittest

from viktor import File
from viktor.testing import mock_GenericAnalysis

from app.my_entity_type.controller import MyEntityTypeController

class TestMyEntityTypeController(unittest.TestCase):

@mock_GenericAnalysis(get_output_file={
'result.xml': File.from_path('test_file.xml'), # <name>: <File>
'result.json': File.from_path('test_file.json'),
...
})
def test_generic_analysis(self):
MyEntityTypeController().generic_analysis()

For the decorator's input parameters the following holds:

  • If a Sequence type is provided, the next entry is returned for each corresponding method call. When a call is performed on a depleted iterable, an Exception is raised.
  • If a single object is provided, the object is returned each time the corresponding method is called (endlessly).
  • If None is provided (default), a default File/BytesIO object (with empty content) is returned each time the corresponding method is called (endlessly).