Note
Go to the end to download the full example code.
Interpolating Between Geometries#
This example demonstrates how to interpolate between two geometries in latent space.
Latent space interpolation allows you to:
Create smooth transitions between existing designs.
Explore the design space systematically.
Generate variations that blend features from multiple geometries.
Before you begin#
Complete “Building a Generative Design Model” to train a Generative design model.
Ensure that the model training has been completed successfully. To do so, verify if a new workspace was created for the trained model.
Import necessary libraries#
Configure your settings#
Update these variables with your specific settings:
ORGANIZATION = "my_organization" # Replace with your organization name
PROJECT_NAME = "new-bracket-project" # Replace with your project name
WORKSPACE_NAME = "new-bracket-project #1" # Typically "{PROJECT_NAME} #{number}"
OUTPUT_DIR = "interpolations" # Directory to save interpolated geometries
NUM_STEPS = 10 # Number of interpolation steps
RESOLUTION = (100, 100, 100) # Output resolution (x, y, z)
# Choose geometries to interpolate between (by name)
GEOM_A_NAME = "geometry_name_a" # Replace with actual geometry name
GEOM_B_NAME = "geometry_name_b" # Replace with actual geometry name
Define functions for interpolation#
Before interpolating between two geometries, we need two key functions:
A function to efficiently extract the latent parameters from the training data.
A function to interpolate between two latent vectors.
def get_latent_parameters(workspace) -> Dict[str, List[float]]:
"""Download and load latent parameters for all geometries in the workspace.
Parameters
----------
workspace : Workspace
The workspace containing the trained model.
Returns
-------
Dict[str, List[float]]
Dictionary mapping geometry names to their latent parameter vectors.
"""
os.makedirs("latent-parameters", exist_ok=True)
path = os.path.join("latent-parameters", f"{workspace.name}.json")
workspace.download_latent_parameters_json(path)
with open(path, "r") as f:
latent_dict = json.load(f)
print(f"Loaded {len(latent_dict)} geometries' latent parameters.")
return latent_dict
def interpolate_latents(vec1: List[float], vec2: List[float], alpha: float) -> List[float]:
"""Perform linear interpolation between two latent vectors.
Parameters
----------
vec1 : List[float]
First latent parameter vector.
vec2 : List[float]
Second latent parameter vector.
alpha : float
Interpolation factor (0.0 = vec1, 1.0 = vec2).
Returns
-------
List[float]
Interpolated latent parameter vector.
"""
return [(1 - alpha) * x + alpha * y for x, y in zip(vec1, vec2)]
Initialize the client and get the workspace#
Connect to GeomAI and retrieve your trained workspace:
simai_client = asc.SimAIClient(organization=ORGANIZATION)
geomai_client = simai_client.geomai
workspace = geomai_client.workspaces.get(name=WORKSPACE_NAME)
print(f"Using workspace: {workspace.name}")
Get latent parameters for all geometries#
Download the latent parameters of all training geometries in the workspace:
latent_dict = get_latent_parameters(workspace)
Display available geometries#
List all geometries available for interpolation:
print("\nAvailable geometries:")
for i, name in enumerate(latent_dict.keys()):
print(f" [{i}] {name}")
Validate selected geometries#
Check if the selected geometries exist:
if GEOM_A_NAME not in latent_dict:
print(f"Error: Geometry '{GEOM_A_NAME}' not found in workspace.")
print("Please update GEOM_A_NAME with a valid geometry name from the list above.")
raise ValueError(f"Geometry '{GEOM_A_NAME}' not found")
if GEOM_B_NAME not in latent_dict:
print(f"Error: Geometry '{GEOM_B_NAME}' not found in workspace.")
print("Please update GEOM_B_NAME with a valid geometry name from the list above.")
raise ValueError(f"Geometry '{GEOM_B_NAME}' not found")
print(f"\nInterpolating from '{GEOM_A_NAME}' to '{GEOM_B_NAME}' in {NUM_STEPS} steps.")
Interpolate in latent space and generate geometries#
Generate intermediate geometries by linearly interpolating in latent space:
vec_a = latent_dict[GEOM_A_NAME]
vec_b = latent_dict[GEOM_B_NAME]
predictions: list[Prediction] = []
for i in range(NUM_STEPS + 1):
alpha = i / NUM_STEPS
latent_params = interpolate_latents(vec_a, vec_b, alpha)
print(f"\nGenerating geometry {i}/{NUM_STEPS} (alpha={alpha:.2f})...")
config = GeomAIPredictionConfiguration(
latent_params=latent_params,
resolution=RESOLUTION,
)
prediction = geomai_client.predictions.run(config, workspace)
print(f"Prediction {i}: {prediction.id} started...")
predictions.append(prediction)
Download generated geometries#
for i, prediction in enumerate(predictions):
if prediction.wait(timeout=600): # Wait up to 10 minutes
if prediction.has_failed:
print(f"✗ Prediction {i} failed: {prediction.failure_reason}")
continue
# Save result
out_dir = os.path.join(OUTPUT_DIR, workspace.name)
os.makedirs(out_dir, exist_ok=True)
out_path = os.path.join(out_dir, f"prediction_{i:02d}_{prediction.id}.vtp")
geomai_client.predictions.download(prediction.id, out_path)
print(f"✓ Saved prediction to {out_path}")
else:
print(f"✗ Prediction {i} timed out.")
The downloaded VTP files can be used for:
Visualization in your usual solver.
SimAI training data or predictions.
Further analysis and post-processing.
Next steps#
To go further, you can:
Interpolate between more than two geometries.
Combine interpolation with optimization for specific design goals.