Introduction

We are going to need smart engineering solutions to solve our planet’s problems (and soon in other celestial bodies in our solar system) in a smart and scalable manner. Parametric programming is a fantastic approach to optimize efficient engineering methods and achieve those goals.

We recently came across a very interesting platform named VIKTOR which introduces smart app development for engineering with our favorite programming language: Python. The Python-based software is applicable to so many disciplines in the engineering and applied science fields. From material science to organic chemistry, civil engineering to mechanical engineering, Viktor offers an impressive toolbox and takes care of tedious processes such as app hosting, app deployment, intellectual property management and server administration.

In this mini-tutorial we will demonstrate how to create parametric design elements using VIKTOR and Python. VIKTRO also helps package, save, deploy and distribute your engineering app with your colleagues or clients and it can be useful for both engineers and engineering-related business teams as well.

Tutorial: Creating Web Apps with VIKTOR (powered by Python)

Creating a web app is an awesome way to let people interact with your Python code because people everywhere in the world can access it; even the ones without any Python skills can use a graphical interface. It brings a whole another level of visualization and interactivity to your engineering project. First, we will ask VIKTOR to create a folder with an empty app containing all files you need, and then install it. 

Some years ago, you would be right, but nowadays, the low-code app development platform VIKTOR makes it so easy that virtually anyone with Python knowledge can do it.

In this tutorial, we will guide you to build your very first app with VIKTOR. We will start with a blank app and create an interactive 3D model of a radio tower step by step. So, let’s get started!

Note: In case you need it, we included a complete web app code at the end of this tutorial.

Open Viktor.AI in Terminal
Full app showing parametric design of a radio tower with spherical, conical and cylindrical elements created by Python & VIKTOR.

Contents:

  1. Creating and starting an empty app
  2. Creating a 3D model
  3. Adding input fields
  4. Connecting the input fields to the 3D model
  5. Adding a Sphere
  6. Adding the mast
  7. Adding Materials
  8. What is next?
  9. All code together

Prerequisites

  • A free VIKTOR account
  • Installing the free VIKTOR library based on the instructions you receive by mail after making an account
  • Some Python programming experience
  • Ability to write and use functions
    (You are always welcome to refer to our Python User Functions Exercises and the relevant lesson here as well as any other Python lessons, tutorials and exercises we have to reinforce your programming proficiency.)

Installing VIKTOR

Before we get started, we need to download and install VIKTOR. VIKTOR is the platform that will help us create and host the web app using nothing but Python.

Here, you can create your VIKTOR account for free. Just follow the installation instructions which are pretty straightforward. This will take approximately 10 mins.

Creating, installing and starting an empty app

First, we will first ask VIKTOR to create a folder with an empty app containing all files
you need, and then install it. We will use this app as a basis to make your app. So, let’s get started!

  1. In the file explorer, go to the location where you like to store this and other future apps. Let’s assume the folder is called ‘viktor-apps’.
  2. Right-click in this folder and click on ‘Open in Terminal’ (or similar, e.g. ‘Open PowerShell window here’) to open the command-line shell, as in the image below. Note that in older versions of Windows, you may need to Shift + Right-click on the folder.

 

Open Viktor.AI in Terminal

 

  1. On the command line, write the following command:
viktor-cli create-app tower-app

This command creates an app with the name ‘tower-app’. After executing the command, you will find a folder called ‘tower-app’ inside the ‘viktor-apps’ folder.

1. In the PowerShell navigate to the ‘tower-app’ folder:

  cd tower-app

2. Before installing a new app, you need to clear the database by running the following command:

viktor-cli clear

3. Now you can install your app using the command below. Installation can take up to 3 minutes, so just have a little patience and read the information below.

viktor-cli install

The command tells VIKTOR to install the app stored inside the folder where you run the command. That is why we ask you to navigate to the app folder first.

4. Start the app with:

viktor-cli start

Congratulations, your app is up and running! However, do not close your command-line shell; otherwise, your app will stop.

5. Open your app in your browser by visiting VIKTOR cloud as explained in the command-line shell

6. After logging in, open the “Development” card. Great, your app is up and running. Now let’s go to the fun part: start building the 3D model!

Creating a 3D model

In this part of the tutorial, we will create a 3D model of the radio tower using the geometry module. Before we start building the 3D model, let’s check out what the current application looks like.

In your browser,

  1. Click on “Create”.
  2. Fill in a name in the pop-up
  3. Click “Create and open”

You should now see an empty page. So let’s start creating our 3D model.

Add a 3D model to your app

First, we will visualize the base of the radio tower. The base will just be a cylinder, which will have a height and a diameter. The first part is a bit slow, but I promise that we will draw the rest of the tower at lighting speed.

  1. Go to the folder tower-app and open app.py in your favourite code editors.
  2. Check app.py so that it looks like this:
from viktor.core import ViktorController
from viktor.parametrization import ViktorParametrization

class Parametrization(ViktorParametrization):
     pass

class Controller(ViktorController):
    label = 'VIKTOR Tutorial'
    parametrization = Parametrization

3. On the top, import some additional functions we will need to create the app:

from viktor.geometry import Point,Line,CircularExtrusion,Material,Color
from viktor.views import GeometryView,GeometryResult

4. First we will create a geometry view to show your 3D model and define a function to draw everything. We do this inside your controller like this.

...
class Controller(ViktorController):
  label = 'VIKTOR Tutorial'
  parametrization = Parametrization

  @GeometryView("3D", duration_guess=1)
  def visualize_tower(self, params, **kwargs):
    """Creates the 3D view and visualizes the Radio Tower"""

    return GeometryResult()
  • Now we will start drawing. First, let’s define 2 reference points we need for our design:
...
  @GeometryView("3D", duration_guess=1)
  def visualize_tower(self, params, **kwargs):
    """Creates the 3D view and visualizes the Radio Tower"""

    # Reference points

    base_start = Point(0, 0, 0)         #<--- Add this lines
    base_end = Point(0, 0, 50)          #<--- Add this lines

    return GeometryResult()
  • To create your base of the tower, we will use CirculerExtrusion, which draws a cylinder following a line between the points base_start and base_end. Under the two point we just created add:
    # Create tower base

    line = Line(base_start, base_end)
    base = CircularExtrusion(diameter=5, line=line)

    return GeometryResult(base)     # <--- don't forget to change this line
  • If everything went right, you should be able to see the cylinder in your app. Save the app.py file, go to your app and refresh the page.

Python code up to cylinder creation

In case something went wrong, here you can see the complete code so far. Just copy/paste it in app.py and everything should work.

from viktor.core import ViktorController
from viktor.parametrization import ViktorParametrization
from viktor.geometry import Point, Line, CircularExtrusion, Cone, Sphere, Material, Color
from viktor.views import GeometryResult, GeometryView


class Parametrization(ViktorParametrization):
    pass


class Controller(ViktorController):
    label = 'VIKTOR Tutorial'
    parametrization = Parametrization

    @GeometryView("3D", duration_guess=1)
    def visualize_tower(self, params, **kwargs):
        """Creates the 3D view and visualizes the Radio Tower"""

        # Reference points

        base_start = Point(0, 0, 0)
        base_end = Point(0, 0, 50)

        # Create tower base

        line = Line(base_start, base_end)
        base = CircularExtrusion(diameter=5, line=line)

        return GeometryResult(base)

Adding input fields

We created a 3D model in the last section, but what if you want a user to change the geometry dynamically? Using VIKTOR’s input fields you can. Let’s add a few input fields to change the length, width and height of your cylinder.

  • Let’s import the NumberField we need. At the top of you code add:
from viktor.parametrization import NumberField
  • Under class Parametrization(ViktorParametrization): we will add 2 fields to change the dimensions of the cylinder, and don’t forget to eliminate pass. You code should look like this:
...
class Parametrization(ViktorParametrization):
    """Parametrization of the Radio Tower"""

    # Base of the tower
    base_height = NumberField("Height base", default=50, min=1)
    base_diameter = NumberField("Diameter base", default=3, min=1)

    #pass  <---- DELETE THIS LINE
    ...
  • Again, save the app.py file. Go to your app, refresh the page and see the NumberFields appear in your app.

Did you notice that changing the values does not modify the 3D model? This is because we have not connected the NumberFields to your 3D model yet. We’ll do this next.

All code toghter so far

from viktor.core import ViktorController
from viktor.parametrization import ViktorParametrization, NumberField
from viktor.geometry import Point, Line, CircularExtrusion, Cone, Sphere, Material, Color
from viktor.views import GeometryResult, GeometryView


class Parametrization(ViktorParametrization):
    """Parametrization of the Radio Tower"""

    # Base of the tower
    base_height = NumberField("Height base", default=50, min=1)
    base_diameter = NumberField("Diameter base", default=3, min=1)


class Controller(ViktorController):
    label = 'VIKTOR Tutorial'
    parametrization = Parametrization

    @GeometryView("3D", duration_guess=1)
    def visualize_tower(self, params, **kwargs):
        """Creates the 3D view and visualizes the Radio Tower"""

        # Reference points

        base_start = Point(0, 0, 0)
        base_end = Point(0, 0, 50)

        # Create tower base

        line = Line(base_start, base_end)
        base = CircularExtrusion(diameter=5, line=line)

        return GeometryResult(base)

Connecting the input fields to the 3D model

We’ll connect the input fields to the 3D model to make it dynamic:

  • Change the 3rd value of base_end from a static 50 to params.base_height and the value of diameter to params.base_diameter as shown below:
...

     @GeometryView("3D",duration_guess=1)
        def visualize_tower(self, params, **kwargs):
        """Creates the 3D view and visualizes the Radio Tower"""

        # Reference points
        base_start = Point(0, 0, 0)
        base_end = Point(0, 0, params.base_height)      # <--- add params.base_height here

        # Create tower base
        line = Line(base_start, base_end)
        base = CircularExtrusion(diameter=params.base_diameter, line=line)      # <--- params.base_diameter here

        return GeometryResult(base)
  • Again, save the app.py file. This time, instead of refreshing your app, just change some input values. Did you see that? VIKTOR updated the app, and your 3D model is now dynamic!

Awesome, we already created a fully functioning parametrized model of a beam including a 3D visualisation! If you were
wondering whether this is a good time: Yes, this is a perfect moment to pat yourself on the back!

How does this work?

So what happens in the background? Each time you change an input parameter, VIKTOR reruns the corresponding code and shows the results in the view. In technical words, your code is stateless.

  • All the input parameters are stored in the variable params. That is why it is important to pass it to def visualize_tower(self, params, **kwargs).
  • params is a Munch, which is like a Python dictionary. You can access the data inside params using dot-style notation. So, for example, to access height inside params, you write params.height.

Adding a sphere

At the top of the tower we add a Sphere.

1. Let’s import Sphere

from viktor.geometry import Sphere

2. We will add and input field to determine the Sphere’s radius:

...
class Parametrization(ViktorParametrization):

 base_height = NumberField("Height base", default=50, min=1)
 base_diameter = NumberField("Diameter base", default=3, min=1)
 sphere_radius = NumberField("Radius sphere", default=4, min=1)      # <-- Add this line

3. Go to our @GeometryView and add a Sphere under the lines that define the base. Sphere needs a point and a diameter. Don’t forget to return the Sphere at the end, so it is visualized. Your code should look like this:

@GeometryView("3D", duration_guess=1)
def visualize_tower(self, params, **kwargs):
  """Creates the 3D view and visualizes the Radio Tower"""

  # Reference points

  base_start = Point(0, 0, 0)
  base_end = Point(0, 0, params.base_height)

  # Create tower base

  line = Line(base_start, base_end)
  base = CircularExtrusion(diameter=params.base_diameter, line=line)

  # Create tower cabin

  cabin = Sphere(base_end, params.sphere_radius)  # <-- Add this line

  return GeometryResult([base, cabin]) # <--- put base and cabin in a list, so they are shown.

4. Again. Save the file and refresh the app.

Adding the mast

Now that you are used to VIKTOR, we ramp up the speed and quickly add the mast on top of our tower in the exact same way we have done before.

1. Import the code:

from viktor.geometry import Cone

2. Add the NumberField for the mast height:

mast_height = NumberField("Height mast", default=30, min=1)

3. Draw a cone and don’t forget to return it so it is visualized:

# Tower top

top = Cone(diameter=params.base_diameter, height=params.mast_height, origin=base_end) # <-- Add this line

return GeometryResult([base,cabin,top]) # <-- Update this line

4. Save the file and refresh.

Adding materials

Great, we created the full 3D model of the tower, but it is looking a bit pale. Let’s add some color, we don’t want a plane crashing into it 😉

We will add color, by creating some Material and adding them to the 3D models.

1. Import Material and Color:

from viktor.geometry import Material, Color

2. Add materials as constants under the imports and before the Parametrization class:

...

WHITE = Material("White", color=Color.white())  # <-- Add these lines too
RED = Material("Red", color=Color.red())        # <-- Add these lines too

class Parametrization(ViktorParametrization): # <-- this line is just for your reference

...

3. Add the materials to the different geometries we created before, as shown here:

...

# Create tower base
line = Line(base_start, base_end)
base = CircularExtrusion(diameter=params.base_diameter, line=line, material=WHITE)

# Create tower cabin

cabin = Sphere(base_end, params.sphere_radius, material=WHITE)

# Tower top

top = Cone(diameter=params.base_diameter, height=params.mast_height, origin=base_end, material=RED)

4. Save, refresh, and you should have a colorful tower:

What is next?

If you managed to get this far, you have done a great job and successfully built your first Python app with VIKTOR! VIKTOR has a large collection of functions and visualizations that await exploring. Feel free to go and check out their docs and start making your own engineering apps powered by Python.

And if you need any help, want to request features or share your creations, you can head over to the Community Forum.

Final code for parametric Radio Tower design

Just in case, here you can find the complete code of the app:

from viktor.core import ViktorController
from viktor.parametrization import ViktorParametrization, NumberField
from viktor.geometry import Point, Line, CircularExtrusion, Cone, Sphere, Material, Color
from viktor.views import GeometryResult, GeometryView

WHITE = Material("White", color=Color.white())
RED = Material("Red", color=Color.red())


class Parametrization(ViktorParametrization):

  base_height = NumberField("Height base", default=50, min=1)
  base_diameter = NumberField("Diameter base", default=3, min=1)
  sphere_radius = NumberField("Radius sphere", default=4, min=1)
  mast_height = NumberField("Height mast", default=30, min=1)


class Controller(ViktorController):
  label = 'VIKTOR Tutorial'
  parametrization = Parametrization

  @GeometryView("3D", duration_guess=1)
  def visualize_tower(self, params, **kwargs):
    """Creates the 3D view and visualizes the Radio Tower"""

    print("Params:", params)

    # Reference points

    base_start = Point(0, 0, 0)
    base_end = Point(0, 0, params.base_height)

    # Create tower base

    line = Line(base_start, base_end)
    base = CircularExtrusion(diameter=params.base_diameter, line=line, material=WHITE)

    # Create tower cabin

    cabin = Sphere(base_end, params.sphere_radius, material=WHITE)

    # Tower top

    top = Cone(diameter=params.base_diameter, height=params.mast_height, origin=base_end, material=RED)

    return GeometryResult([base, cabin, top])

Now although this web application is pretty simple, it’s effective and useful. Furthermore, this implementation opens a whole new world of opportunities to design engineering apps using minimal Python code base with VIKTOR which can be applied to pretty much any concept under engineering and science subdomains.

VIKTOR takes care of the cybersecurity, hosting, server administration, management of intangible assets such as  intellectual property and low-level programming and the result is an intuitive app creation process which can hopefully yield fruitful  discussions and/or presentations in projects with parametric design elements.

We will be publishing a number of professional Python tutorials in near future to continue demonstrating Python’s potential in sophisticated use cases in the field and help you gain inspiration that can result in real world outcomes.

You can find the Python source code and information regarding dependencies of this app at our Github Repository: Python-3D-Tower-Web-App source code.

Guest Author
Anande is our guest author who is also a pioneer in parametric design and digital engineering topics. He is based in Netherlands and he has a background in Aerospace Engineering and Mechanical Engineering fields.

Anande takes "Automate the Boring Stuff" philosophy by heart and contributes to increase efficiency in engineering applications with smart Python-based parametric design solutions @VIKTOR.

Recommended Posts