DGN Core Converter#

The DGN core converter is a Kit extension that converts Bentley MicroStation DGN v8 files to USD. It is the GUI-less backend for omni.kit.converter.dgn.


Quick Start#

Use this recipe when running inside Kit with omni.kit.converter.dgn_core enabled.

import omni.converter.dgn
from omni.kit.converter.dgn_core import OdaDgnOptions, get_instance

converter = get_instance()
if converter is None:
    raise RuntimeError("omni.kit.converter.dgn_core is not loaded")

options = OdaDgnOptions()
options.levelFilterStyle = omni.converter.dgn.FilterStyle.eOmit
options.levelIncludes = ["Default", "3D*"]
options.meshConversionStyle = omni.converter.dgn.ConversionStyle.eRenderable
options.curveConversionStyle = omni.converter.dgn.ConversionStyle.eNone
options.importAttributesByList = True

output_url, status = await converter.create_converter_task(
    "C:/data/site.DGN",
    "C:/data/site.usd",
    options.toArgs(),
)

if status.error_code != 0 or not output_url:
    raise RuntimeError(status.error_msg)

Success means status.error_code == 0 and output_url is non-empty.


Prerequisites#

  • Run inside a Kit Python environment where omni.kit.converter.dgn_core and its native ODA converter library are loaded.

  • The input .DGN file must exist locally or be resolvable through supported Omniverse/Nucleus URL handling.

  • The output folder must be writable locally or resolvable through supported Omniverse/Nucleus URL handling.

  • create_converter_task(...) is async; call it from an async context.


What This Converter Does#

Reads .DGN files through the Open Design Alliance Kernel and Drawings SDKs and writes USD output. It converts DGN containers to UsdGeomXform, mesh-like elements to UsdGeomMesh, supported curves and 3D text to UsdGeomBasisCurves when enabled, and DGN properties to USD attributes when configured.

DGN level names are prepended to converted prim names so users can quickly find geometry from a source level.


Input and Output Formats#

Format

Notes

.DGN

Bentley MicroStation DGN v8 input. Filter regex currently matches uppercase .DGN.

Output

Notes

.usd, .usda, .usdc

USD output path supplied by the caller.


Conversion APIs#

Use these APIs to perform conversions, in this order of preference:

API

When to use

get_instance().create_converter_task(input_path, output_path, options.toArgs())

Preferred core extension API when calling the loaded extension from Python. Returns (output_url, ConverterStatus) and handles local and Nucleus paths.

DgnConverterCoreHelper._create_import_task(input_path, output_path, file_format_args)

Lower-level helper used by the extension implementation. Treat as internal despite being the helper conversion method.

omni.converter.dgn.Converter(options).convert(...)

Backend SDK wrapper for local conversion paths. Use only when you do not need the core extension’s Nucleus handling, output copying, logging, and Scene Optimizer post-processing.

Minimal direct API call:

import omni.converter.dgn
from omni.kit.converter.dgn_core import OdaDgnOptions, get_instance

converter = get_instance()
options = OdaDgnOptions()
options.levelFilterStyle = omni.converter.dgn.FilterStyle.eOmit
options.levelIncludes = ["Default", "3D*"]
options.meshConversionStyle = omni.converter.dgn.ConversionStyle.eRenderable
options.curveConversionStyle = omni.converter.dgn.ConversionStyle.eNone
options.importAttributesByList = True

output_url, status = await converter.create_converter_task(
    "C:/data/site.DGN",
    "C:/data/site.usd",
    options.toArgs(),
)

For direct backend conversion with local paths only, pass the options object itself:

import omni.converter.dgn
from omni.kit.converter.dgn_core import OdaDgnOptions

options = OdaDgnOptions()
options.levelFilterStyle = omni.converter.dgn.FilterStyle.eOmit
options.levelIncludes = ["Default", "3D*"]
options.meshConversionStyle = omni.converter.dgn.ConversionStyle.eRenderable
options.curveConversionStyle = omni.converter.dgn.ConversionStyle.eNone
options.importAttributesByList = True

converter = omni.converter.dgn.Converter(options)
error_code, error_msg = converter.convert("C:/data/site.DGN", "C:/data/site.usd", {})

Supported DGN Element Types#

DGN element category

USD output

Cell Header, Shared Cell Reference, Shared Cell Definition

UsdGeomXform

Complex Shape, Shape 3D, Solid, Surface, Mesh, Cone, BSpline Surface

UsdGeomMesh

Line, Line String, Ellipse, Arc, BSpline Curve

UsdGeomBasisCurves when curve conversion is renderable


Converter Options#

Configure these as properties on OdaDgnOptions. Pass options.toArgs() to create_converter_task(...); pass options directly only when calling omni.converter.dgn.Converter(options).

Enum-valued pybind property setters require enum objects, not raw integers. For example, set options.levelFilterStyle = omni.converter.dgn.FilterStyle.eOmit and options.meshConversionStyle = omni.converter.dgn.ConversionStyle.eRenderable. Numeric enum values are valid in JSON/dict config parsed by OdaDgnOptions.parse(...) and in the serialized dict returned by options.toArgs().

OdaDgnOptions Property

Default

Description

maxNumGridLines

10000

Maximum number of grid lines.

maxFacetEdgeLength

0.0

Maximum facet edge length.

normalTolerance

15.0

Circular surface tessellation tolerance in degrees.

gridAspectRatio

0.0

Grid aspect ratio.

betweenKnots

2

Additional points or isolines between knots for NURB data.

pointsPerEdge

0

Points per edge.

surfaceTolerance

0.02

Maximum distance between tessellated mesh and source surface.

useMaterials

true

Create USD materials; false writes colors as displayColor.

materialType

1

Material output: 0 none, 1 USD Preview Surface, 2 OmniPBR plus USD Preview Surface.

geometryAttributeStyle

1

Geometry attributes: 0 none, 1 custom attribute, 2 constant primvar.

instancing

true

Enable instancing through USD references. Prefer instancingStyle when selecting an instancing mode.

instancingStyle

1

Shared Cell Reference instancing: 0 none, 1 scenegraph instancing.

convertHidden

false

Export hidden DGN elements and set converted prim visibility to invisible.

meshConversionStyle

2

Mesh elements: 0 none, 1 attributes-only Xform, 2 renderable mesh.

curveConversionStyle

0

Non-text curves: 0 none, 1 attributes-only Xform, 2 renderable BasisCurves.

text3dConversionStyle

0

3D text: 0 none, 1 attributes only, 2 renderable BasisCurves in a separate layer.

text3dWidth

0.05

BasisCurves width for converted 3D text.

curveSamplePoints

8

Sample count for approximating curves and 3D text. Must be at least 2.

fallbackCurveWidth

-1.0

Width for curves with no source width. -1.0 uses source file default.

applyGlobalOrigin

false

Apply model global origin as transforms instead of storing it only as an attribute.

hideLevelsByList

true

Hide prims whose source level matches hiddenLevels.

hiddenLevels

[]

Case-sensitive wildcard level patterns to hide after conversion.

levelExcludeHidden

false

Exclude hidden levels from conversion.

levelFilterStyle

0

Level filter handling: 0 none, 1 omit, 2 deactivate, 3 hide.

levelIncludes

[]

Case-sensitive wildcard level patterns to include during filtering.

levelExcludes

[]

Case-sensitive wildcard level patterns to exclude during filtering.

mergeMeshes

true

Merge meshes that share level, color, and element type.

mergeCurves

true

Merge curves that share level, color, and element type.

triangulate

true

Triangulate polygons during conversion.

convertElementId

true

Convert DGN element IDs to USD attributes.

modelNamePatterns

[]

Case-sensitive wildcard model name patterns; empty means all models.

importAttributesByList

true

Convert selected DGN custom properties to USD attributes.

attributes

[]

JSON array of { "name", "converted_name", "prefix" } mappings for custom DGN properties.

mergedAttributeStyle

2 in docs, code selection initializes to 0

Handling for merged differing attributes: 0 discard, 1 face-varying primvar not implemented, 2 metadata subset prims.

progressLogging

true in code, docs list false

Report conversion progress.

verboseLogging

false

Emit detailed logs for debugging conversion issues.


Development Rules#

  • Keep OdaDgnOptions in python/impl/options.py as the single source for option parsing.

  • When adding or changing an option, update python/impl/options.py, docs/Overview.md, and tests together.

  • Preserve level/model filtering semantics: wildcard matching is case-sensitive; * means all; empty list behavior depends on the option.

  • Keep DGN level-name prim naming behavior aligned across implementation, tests, and docs.

  • Keep creator metadata behavior unless replacing it with equivalent extension/backend version metadata.


Verification#

Build and run the repo test suite from the repository root:

./repo.bat build -xrd
./repo.bat test

For focused changes, run the generated omni.kit.converter.dgn_core extension tests after building, or cover the affected tests under source/extensions/omni.kit.converter.dgn_core/python/tests.

The configured Python coverage threshold for this extension is 85%.


Codebase Map#

File

Role

python/impl/extension.py

DgnConverter, extension lifecycle, task creation.

python/impl/options.py

OdaDgnOptions, option defaults, parsing, aliases.

python/impl/filters.py

DGN file filter and supported format regex.

python/tests/

Conversion and memory leak tests.

docs/Overview.md

User-facing behavior, supported element types, and converter option documentation.

config/extension.toml

Package metadata, native converter library, tests, coverage settings.