Black-box optimization of geometry and functionality by integrating Optuna and 3D CAD

Published in
16 min readSep 20



This article introduces Tunny, Optuna’s 3D CAD wrapper. We will start with an introduction of Rhinoceros, a 3D CAD software on which Tunny runs.
Then, I will provide a brief overview of how I implemented Tunny. Finally, I will walk you through some design examples using Tunny, including crash safety design of a car front bumper in connection with CAE, and Human-in-the-loop optimization of vase shapes and architectural column placement.


Hi to all Optuna users!
I’m Hiroaki Natsume, an engineer at NatureArchitects Inc.

In early 2022, I was in an internal Bayesian optimization workshop. Since our company designs products in a way that functions naturally emerge from the shapes. 3D CAD and CAE are closely linked and used in design, with optimization being often performed when exploring shapes. During the workshop, our company’s president said to me, “Wouldn’t it be interesting if we could do Bayesian optimization of shapes with 3D CAD?

I was looking for a library that could do Bayesian optimization flexibly and found Optuna. This is how I began developing an Optuna wrapper for Grasshopper called “Tunny”. As I delved deeper into the development of the wrapper, I realized the need for more functionality, leading me to contribute to both Optuna and Optuna Dashboard. Later on, the developer of Optuna proposed that I write a blog about Optuna and Tunny.

The Japanese version is available on our company’s blog, and we hope you will take a look at it as well.

This article is intended for those who have experience in using or are interested in Optuna. Since the users of the Optuna are often familiar with machine learning and its related fields, but not with design, I will introduce Tunny in the following way.

  1. About Tunny and 3D CAD Rhinoceros
  2. About CAE and Optimization
  3. Human-in-the-loop and CAD integration

Although Optuna’s primary use case is tuning machine learning hyperparameters, the technique used is “black-box optimization”. Therefore, it is not a technology that targets only machine learning hyperparameters.

I would like to introduce “Tunny,” a tool for optimizing the parameters of the black-box “functionality” generated from “geometry”.

About Tunny

Tunny is a wrapper for Optuna, which runs on Grasshopper, the node editor plugin for 3D CAD’s Rhinoceros.

It is an OSS plugin released under MIT license in the following GitHub repository.

You might be wondering about the connection between CAD and optimization, so I hope you will first take a look at a simple operating situation.

Here, for a given surface, the following two problems are solved when it is composed of a grid of beam members.

  1. Uniformity of member lengths (minimization of standard deviation of member lengths)
  2. Minimize the difference in shape from a specific surface (TargetSurface)

The white rectangle moving in the red frame near the center is the variable, and each number represents a shape parameter.

The following is a plot of Optuna’s `visualization.plot_pareto_front` resulting from the further optimization in the video above, where Diff is the difference in geometry from the TargetSurface and SD_Length is the standard deviation of the member length. Diff is the Euclidean distance of the shape parameter.

This example may be easier to understand if you imagine a curved building roof. Using varying member lengths increases processing time and leads to higher costs, whereas uniform member lengths reduce manufacturing costs but may result in a roof shape different from the architect’s ideal design (TargetSurface). Such a relationship can be calculated and visualized by using Tunny. The result can be viewed as a black-box optimization solution of two objective functions: “construction cost” (a function of ease of construction) and “design” (shape).

Such optimization can be done without going to the trouble of using CAD, but only with Python, for example, if you are familiar with coding. However, one should go to specialists for the best results. If you are good at CAD, you can optimize more efficiently by using CAD, and Tunny is not intended for programmers but for ordinary designers who use CAD. Tunny’s great advantage is that it can perform shape optimization using Optuna, which has been developed with the latest algorithms in recent years, simply by setting up the GUI without writing any programs.

In the following sections, I hope to introduce the elements that make up Tunny in more detail.

This example is slightly modified from AMDlab’s example below, which you may also find interesting. (This page is in Japanese only.)

About Rhinoceros

Tunny runs on Grasshopper, a plug-in for Rhinoceros (“Rhino” hereafter).

Rhino is a 3D CAD software developed by Robert McNeel & Associates. It is characterized by its strength in NURBS modeling.

NURBS stands for Non-Uniform Rational B-Spline and is one of the spline curves used to express shapes through mathematical formulas. It is therefore often used in fields requiring smooth curved surfaces, such as car bodies, ships, and architectural exteriors.

The following is a clear image of the shape representation where the gray curve below is a NURBS representation. The curve consists of multiple control points (red circles), each assigned a calculated weight to determine its impact on a resulting single line.

Specifically, the NURBS curve C(u) is shaped using a basis function N with weights w at k control points P as shown in the equation below.

The above is an equation for a curve, but it can represent a curved surface as well.

On the other hand, 3D modelers such as Blender uses a mesh to represent a shape. It is a set of surfaces consisting of three or four points, and is a different way of representing a shape.

Rhino can also handle meshes and Blender can handle NURBS. Basically, all 3D software nowadays can use either of them, and the difference is in which one is developed primarily.

About Grasshopper

Grasshopper (“GH” hereafter) is a node editor that runs on Rhino. Each process is a node (called “component” in GH), which can be combined to create a shape.

For a simple example, the following four arithmetic operations and curves can be created by specifying control points, which can be combined to create a variety of shapes.

You may have an impression that CAD is processed one by one in GUI using a mouse and commands. However, GH components are based on the SDK provided by Rhino, which enables the node-by-node processing of Rhino’s geometry. This is a major feature of GH.

Therefore, once a shape generation algorithm is created using a component, multiple shapes can be easily created using the same algorithm. It can also be used to study a complex shape while making minor modifications to it, or to create a shape based on rules like a mathematical equation. This approach to design is called computational design or algorithmic design.

In the example of roof shape optimization given at the beginning of this section, the positions of the NURBS control points representing the roof surface were parameters in GH, and the shape was controlled by manipulating these values.

Connection with Optuna

Now that I have introduced Rhino and GH, I will briefly introduce the specific implementation of working with Optuna.

Optuna has an ask-and-tell interface that allows for more flexible optimization settings, and Tunny is also implemented using the ask-and-tell interface. Please refer to the official Optuna documentation for more information on the ask-and-tell interface.

Rhino and GH are written and run in C#, and similarly Tunny is developed in C#. However, for the sake of clarity for Optuna users, I use Python-like pseudo code here. In fact, it uses Pythonnet, a library that enables running Python from C#. If you are interested, please check that out as well.

import optuna
study = optuna.create_study()

# Check for termination using values set in the GH UI
if CheckOptimizationComplete():

trial = study.ask()
variable = trail.suggest_float(....)

# Here the suggested values from optuna are reflected in GH
# and the results are retrieved
score = EvaluateGrasshopper(variable)
UpdateUI() # Update GH UI (e.g. progress bar)

study.tell(trial, score)

The ask-and-tell interface made development smoother than using other optimization libraries because of the flexibility to include processes such as the connection between C# and Python and UI updates that occur during a single trial.

In the above flow, the processing of the EvaluateGrasshopper method part is the GH operation. In the roof shape optimization mentioned at the beginning of this section, the following GH file is in operation.

For the blue Tunny component in the lower right corner, those connected by a blue line are recognized as variables in the optimization, and those connected by green lines as the return value of the objective function.

The following is an expanded version of just the connection between the variable and the return value of the objective function.

The following is the flow of the EvaluateGrasshopper method, which is processed in conjunction with the code and GH.

  1. When the EvaluateGrasshopper method is called in the code, GH’s Tunny component receives the value suggested by Optuna’s trial.suggest_float()
  2. The values are reflected in the component that summarizes the parameters connected by blue color (the component described as GenePool above).
  3. Once the proposed values are reflected on the GH, calculations are performed on the other components connected to the variable component, and the results are reflected in the components labeled SD_Length and Diff, which are connected to Objs in green.
  4. The SD_Length and Diff values passed to the Tunny component are passed to the code as the return value of the EvaluateGrasshopper method and reflected in the objective

In this way, Tunny uses GH processing as part of Optuna’s optimization process to achieve the connection between CAD and Optuna.

Example of a simple connection

The connection with the shape processing mentioned at the beginning of this article may be difficult to understand, so an example of optimization for a simple mathematical expression is given below.

First, let’s look at a case written in Python.

import optuna

def objective(trial):
x = trial.suggest_float("x", -15, 30, step=0.01)
y = trial.suggest_float("y", -15, 30, step=0.01)

c0 = (x - 5) ** 2 + y ** 2 - 25
c1 = -((x - 8) ** 2) - (y + 3) ** 2 + 7.7

trial.set_user_attr("constraint", (c0, c1))

v0 = 4 * x ** 2 + 4 * y ** 2
v1 = (x - 5) ** 2 + (y - 5) ** 2

return v0, v1

def constraints(trial):
return trial.user_attrs["constraint"]

sampler = optuna.samplers.TPESampler(constraints_func=constraints)
study = optuna.create_study(
directions=["minimize", "minimize"]
study.optimize(objective, n_trials=32, timeout=600)

The following explains how the above code is expressed with Tunny.

The variables are projected to Optuna by connecting them to Vars (Variables), Objs (Objectives) and Attrs (Attributes). The number of optimization trials, timeout, study name, and sampler type can be selected from the UI on the right.

Press “RunOptimize” in the form on the right to perform optimization using Optuna.

After the optimization is performed, Optuna’s Storage (SQLite3 and JournalStorage are supported) can be used to read the results, and by specifying the visualization target, each function of Optuna’s visualization is called from Tunny to display the figure.

Optuna Dashboard is also supported, so you can also get real-time results when optimization is running in GH.

I used the term “CAD connection,” but as you can see from these examples, it might be easier to understand it as Optuna’s node-based UI.

CAE and Optimization

Now that Tunny’s components have been introduced, here are some more specific examples of how Tunny can be used.

Optuna users may first think of machine learning hyperparameter optimization when considering its applications, but here is an example of applying optimization to the design of a car component.

When designing a component, the safety of the component under load is examined through analysis. Computer Aided Engineering (CAE) is a design support tool that uses a computer to perform the analysis. More specifically, in the case of structural analysis, it refers to tools that employ methods such as FEM (Finite Element Method) for analysis.

However, in recent years, there has been a growing demand for more efficient design, more discovery of shapes that do not rely solely on know-how, and shorter lead times. Additionally, the demand for more promising geometries is increasing, with an expectation that they can be discovered through analysis before resorting to trial-and-error experiments.

Therefore, CAE, which allows geometry studies to be performed on a computer, is now being combined with optimization as a geometry search aid.

We are developing an environment in which the following sequence flows smoothly in GH: “analysis model shape generation” → “analysis execution” → “optimization” Tunny, created using Optuna, is used in the optimization part.

As an example of design using CAE, this section introduces our company’s design of a front bumper, an impact-absorbing member of the front of an automobile in the event of a collision.

Designing a front bumper

In this case, the component is a front bumper member of a car as shown below, and the design requirement is that this component must meet the following two safety criteria:

  1. Pedestrian leg protection in the event of a collision with a pedestrian (approx. 40 km/h)
  2. Protection of vehicles in the event of a low-speed collision between vehicles (about 10 km/h)

To evaluate safety, we conduct an analysis using (1) a cylinder to simulate a foot and (2) a fan-shaped member simulating the front part of a car, which is then subjected to a collision.

To make it easier to understand the targeted phenomenon, I provide below an example derived from the results of these analyses.

Pedestrian leg collision

Low-speed collision between cars

Pedestrian protection is easier to understand when considering the case of airbags, for example. In this case, it is necessary to minimize the impact of a collision with the softest possible objects. On the other hand, collisions between vehicles generate large amounts of energy, so the vehicle is expected to deform significantly upon impact with an extremely hard object, necessitating efficient energy absorption.

Thus, the design requirement is to satisfy two conflicting performance requirements for a single event, i.e., a collision. Moreover, since this is about safety performance, it is not simply a problem of maximizing safety, but also satisfying a minimum performance level. Therefore, we tackled the problem using multi-objective optimization with constraints.

Most existing bumper components are created by machining a block of foamed plastics like EPP, as shown on the left below. In order to reduce environmental impact and cost, Nature Architects designed a bumper that provides the same functionality as foamed plastics, but in a “shape” made of commodity plastic rather than a lump of material.

In its design, Tunny is used for shape exploration.

As for the shape to be optimized, an hourglass-shaped unit shape as shown below was found to be promising for this condition based on preliminary in-house studies. We assembled these components and applied them to the shape of a front bumper to evaluate its performance in a crash on a real scale.

Optimization is performed on an hourglass shape with the following four parameters, plus plate thickness and depth, for a total of six.

Next, let us discuss the sampler used for optimization. The analysis of automobile crashes is computationally expensive, and the substantial computation time required restricts the number of trials feasible in a short design period. Therefore, Bayesian optimization (TPE) was selected because it is easy to find the optimal solution with a small number of trials.

Optuna offers multiple samplers, so you can select the appropriate sampler for your problem.

Below, I present the results of the optimization run, featuring a few representative shapes.

In this design example, Tunny was used to perform multi-objective optimization to find a member geometry that satisfies the two safety performance requirements in the lower left-hand corner of the above figure.

Shape optimization using Tunny (Optuna) has confirmed the potential for cost reduction and environmentally friendly shape search.

Shape exploration in CAD using Human-in-the-loop

Optuna Dashboard now supports Human-in-the-loop optimization starting with v0.10. The Optuna Dashboard page shows a simple example of optimization using three rgb values as parameters to determine if the generated color is similar to the color of a sunset.

Quoted from Tutorial: Human-in-the-loop Optimization

Other uses were mentioned in previous meetups, including the optimization of input prompts to image generation AIs such as StableDiffusion.

This is where the CAD connection comes into play, and interesting things can be done. Tunny supports Human-in-the-loop with Optuna Dashboard, and two examples are presented below.

Optimization of vase shape

First, let’s consider a simple example: the Human-in-the-loop optimization of a vase shape.

Tunny allows you to save a model on Rhino and use it as an Artifact in Optuna by setting up Human-in-the-loop. The following example shows how to save the view of a model in Rhino as an image and evaluate it as an Artifact on the Optuna Dashboard using a slider.

The vase is created to connect four circles with a smooth surface, and optimization is performed for a total of six parameters: the radius of the four circles and the height of the two circles in the center.

Despite being a simple shape generation algorithm, it generates a wide variety of vase shapes, as shown in the video above. This may help you find your favorite vase shape with Human-in-the-loop.

The above optimization is based on an image obtained from a 3D model of a vase, but what is running behind the scenes is CAD. Therefore, outline and depth information can be easily computed as auxiliary information when converting the model to an image. By combining such information with technologies such as Control Net, the target shape can be directly manipulated, while the background can be created by image generation, etc. The combination of methods is expected to be effective.

For example, the shape parameters of a building could be determined by the designer in CAD, and the background could be created by image generation AI. This enables multiple building perspectives to be generated efficiently in the study phase, while the shape is directly generated using CAD.

CAE and Human-in-the-loop

In many manufacturing industries, there is a division of labor between designers and engineers who design structures, electrical systems, air conditioning, and other components.

More often than not, designers deal with personal sensibilities, while engineers deal with values derived from mathematical formulas and other theories. For this reason, most cases of optimization in design have so far focused on the latter.

Examples include maximizing the safety of members based on structural analysis and optimizing the energy efficiency of air conditioning through thermal analysis. In addition to these optimizations, Human-in-the-loop optimization may be used to optimize the entire design, including the designer’s sensibilities.

Below is an example of a building and column layout.

Structural analysis is performed under the constraint that no columns cover the rooms (boxes) to confirm building safety. The color contour of the building model shows the distribution of forces generated in the building during an earthquake. The redder the color, the greater the force generated.

In addition to this structural evaluation, there is a designer’s (and also client’s) preference as to where the columns should be in terms of building design.

Therefore, multi-objective optimization of “building model geometry” and “building safety during earthquakes (strain energy)” is performed to optimize the column placement in the objective function.

This example is for a building, but it is conceivable that this technology could be used for the exterior of a car as well. The shape of the exterior of a car is very important in its design. On the other hand, since wind resistance is generated when a car is running, a shape with too much resistance will result in lower fuel efficiency. Therefore, it may be possible to design the exterior of a car body more efficiently by multiobjective optimization of “designed shape” and “resistance during driving”.


This article may have been quite lengthy, so let’s bring it to a conclusion.Have I been able to successfully convey the possibilities and excitement of the connection between CAD and Optuna?

The last technology we covered, Human-in-the-loop, is very interesting but time-consuming to evaluate. If 100 trials are necessary for optimization, it would require a total of 50 minutes, assuming each human evaluation takes 30 seconds. This may pose a significant challenge for a person to take part in the optimization loop. However, methods for more efficient evaluation are being researched, and we look forward to future developments.

Tunny is developed as OSS. If you are interested, please feel free to contact me via Issue or Discussions on the GitHub repository.
Of course, contributions are also welcome.

Hopefully this article will be helpful to you as one way to use Optuna.

Thank you for taking the time to read the entire article to the end.



Writer for

Engineer at Nature Architects / hrntsm