Importing CAD Files¶
cavsim3d supports importing existing CAD geometry from STEP and IGES files using the OCCImporter class.
This tutorial demonstrates how to import, visualise, and prepare CAD models for simulation.
Supported Formats¶
| Format | Extension | Notes |
|---|---|---|
| STEP | .step, .stp |
Preferred -- lossless B-Rep |
| IGES | .iges, .igs |
Legacy -- may lose some geometry detail |
1. Basic Import¶
The simplest way to import a STEP file is to create an OCCImporter instance.
The unit parameter tells the importer what units the CAD file uses -- internally,
cavsim3d works in metres.
from cavsim3d.geometry.importers import OCCImporter
# Import a pillbox cavity STEP file (dimensions in metres)
cavity = OCCImporter('../example_models/pillbox.step', unit='m')
# View the imported geometry
cavity.show('geometry')
WebGuiWidget(layout=Layout(height='500px', width='100%'), value={'ngsolve_version': 'Netgen x.x', 'mesh_dim': …
# Generate mesh and visualise
cavity.generate_mesh(maxh=0.02)
cavity.show('mesh')
WebGuiWidget(layout=Layout(height='500px', width='100%'), value={'gui_settings': {}, 'ngsolve_version': '6.2.2…
2. Import with Manual Control¶
For more control over the import process (e.g., when you want to inspect or split the geometry),
set auto_build=False.
# Import a rectangular waveguide with manual control
geom = OCCImporter('../example_models/rectangular_waveguide.step', unit='m', auto_build=False)
# Inspect the geometry before meshing
print(f"Bounding box: {geom.get_bounding_box()}")
print(f"Number of solids: {geom.n_solids}")
# Build the geometry (assigns ports, normals, etc.)
geom.build()
geom.generate_mesh(maxh=0.02)
geom.show('geometry')
Bounding box: ((-1.0000000000918485e-07, -1e-07, -1e-07), (0.10000010000000001, 0.05000010000000002, 0.20000010000000001)) Number of solids: 1
WebGuiWidget(layout=Layout(height='500px', width='100%'), value={'ngsolve_version': 'Netgen x.x', 'mesh_dim': …
3. Importing a Multi-Cell Cavity¶
Larger structures like a 9-cell TESLA cavity can be imported the same way.
# Import a 9-cell TESLA cavity
tesla = OCCImporter('../example_models/tesla9cell.step', unit='m')
tesla.show('geometry')
WebGuiWidget(layout=Layout(height='500px', width='100%'), value={'ngsolve_version': 'Netgen x.x', 'mesh_dim': …
# Mesh and visualise
tesla.generate_mesh(maxh=0.02)
tesla.show('mesh')
WebGuiWidget(layout=Layout(height='500px', width='100%'), value={'gui_settings': {}, 'ngsolve_version': '6.2.2…
4. Import and split it into domains¶
Geometries or assemblies could be imported and split into multiple domains using split planes.
geom = OCCImporter('../example_models/circular_waveguide.step', unit='m',
auto_build=False)
# Add splitting planes along the z-axis
geom.add_splitting_plane_at_z(0.05) # Split at z = 50 mm
geom.add_splitting_plane_at_z(0.10) # Split at z = 100 mm
# Execute the split and build
geom.split()
geom.finalize(maxh=0.04)
# Inspect the split geometry
geom.print_info()
geom.show('geometry')
Named 3 solids, 4 ports External: port1, port4 Internal: port2, port3 Named 3 solids, 4 ports External: port1, port4 Internal: port2, port3 ============================================================ STEP Geometry Information ============================================================ File: ../example_models/circular_waveguide.step Unit: m Number of solids: 3 Is split: True Number of splitting planes: 2 Plane positions (z): [0.05, 0.1] Bounding Box: Min: (-0.1500, -0.1500, -0.0000) Max: (0.1500, 0.1500, 0.3000) Size: (0.3000, 0.3000, 0.3000) NGSolve geometry built: True Mesh generated: True ============================================================
WebGuiWidget(layout=Layout(height='500px', width='100%'), value={'ngsolve_version': 'Netgen x.x', 'mesh_dim': …
from cavsim3d.core.em_project import EMProject
proj = EMProject(name='imported_assembly', base_dir='./simulations', new=True)
assembly = proj.create_assembly(main_axis='Z')
part = proj.create_importer('../example_models/rectangular_waveguide.step', unit='m')
assembly.add("rwg1", part)
assembly.add("rwg2", part, after="rwg1")
assembly.build()
assembly.print_port_info()
assembly.generate_mesh(maxh=0.02)
assembly.show('geometry')
Creating new project 'imported_assembly' at simulations\imported_assembly
Port naming complete:
Total ports: 3
External ports: 2
Interface ports: 1
======================================================================
ASSEMBLY PORT MAP
======================================================================
Main axis: Z
Total ports: 3
----------------------------------------------------------------------
port1 │ Z=+0.000000 │ EXTERNAL │ 1 face(s) ◀▶
│ Components: rwg1.port1
port2 │ Z=+0.200000 │ INTERFACE │ 2 face(s) ◀┃▶
│ Components: rwg1.port2, rwg2.port1
port3 │ Z=+0.400000 │ EXTERNAL │ 1 face(s) ◀▶
│ Components: rwg2.port2
======================================================================
Schematic (along Z):
Ports: ║port1║ ─── ┃port2┃ ─── ║port3║
Components: [rwg1] ─── [rwg2]
WebGuiWidget(layout=Layout(height='500px', width='100%'), value={'ngsolve_version': 'Netgen x.x', 'mesh_dim': …
Summary¶
In this tutorial we:
- Imported STEP files with automatic and manual control
- Visualised geometry and meshes for different structures
- Split imported geometry into multiple domains
- Used imported geometry in an assembly
Next: See Creating Geometry from Primitives to build models without CAD files.