Parametric Engine Guide

Overview

OpenBrIM is a cloud-based parametric bridge information modeling platform with an extensible ecosystem where bridge components and concepts are defined in a parametric way and assembled like LEGO pieces to represent bridge projects (3D views, finite element analysis models, CAD drawings, design documents, reports, and more).

This guide explains the core parametric engine for AI agents who will create XML-based components and models using this system.

Core Concepts

1. Objects (Obj)

Objects are the fundamental building blocks in the system. Every component, structure, or entity is represented as an object.

Key characteristics:

  • Every object has a unique ID (GUID)

  • Every object has a Name (N attribute)

  • Every object has a Type (T attribute) that defines its class or base object

  • Objects can contain parameters and child objects

  • Objects form a hierarchical tree structure through parent-child relationships

  • Objects can inherit from other objects by using that object's name as their Type

1.1 Library Objects

Library objects are reusable template objects that other objects can inherit from. They follow a specific pattern:

Library Object Structure:

Key Attributes:

  • N: The library object name (used by other objects to inherit from this)

  • T="Project": Marks this as a library/template object

  • Tags: Classification tags for organizing and filtering library objects

    • @secondlayer: Visibility layer in UI

    • usastandard, steelIGirder, release: Descriptive tags

  • ObjLabel: Human-readable display name

  • Category: Organizational category (uses : for subcategories)

Using Library Objects (Inheritance):

Other objects reference library objects by setting their T attribute to the library object's N value:

How Inheritance Works:

  1. The child object (T="OBP_GirderStressSummaryTable") inherits all parameters and structure from the library object

  2. Child objects can override inherited parameter values

  3. Child objects can add new parameters not in the library object

  4. Changes to the library object automatically affect all instances (unless overridden)

Common Library Object Categories:

  • Code Check Objects: Design code compliance checks

  • Report Objects: Report templates and layouts

  • Component Objects: Reusable structural components (beams, columns, connections)

  • Material Objects: Material property definitions

  • Section Objects: Cross-section definitions

Example: Creating a Custom Library Object

1.2 Export Objects

Export objects are containers within library objects that expose computed parameters and generated child objects to instances. Parameters placed inside <O T="Export"> containers become accessible to other objects.

Purpose:

  • Export computed/calculated parameters from library objects to instances

  • Make generated child objects (geometry, components, etc.) accessible

  • Share internal calculations with other objects in the project

  • Parameters with Role="Input" are automatically exported - no need to add them to Export objects

Important Dependency Rule: If an exported parameter depends on other parameters, those dependencies must also be exported OR have Role="Input". Parameters without a role (private by default) cannot be accessed by exported parameters.

Export Object Structure:

Complete Example:

How Export Works:

  1. Input Parameters (Role="Input"):

    • Automatically exported to instances

    • Users can modify these values

    • No need to include in Export objects

    • Can be referenced by parameters inside Export objects

  2. Export Container (<O T="Export">):

    • Parameters inside are accessible to other objects

    • Computed from Input parameters or other exported params

    • Read-only in instances (calculated from library)

    • Child objects (geometry, etc.) inside are also exported

  3. Private Parameters (no role):

    • NOT accessible to Export parameters

    • Cannot be used as dependencies for exported calculations

    • For internal use only within the same scope

Using Exported Values:

When you create an instance of a library object, exported parameters become accessible:

Best Practices:

  1. Ensure Proper Dependencies:

    • Exported parameters can ONLY depend on: Role="Input" params OR other exported params

    • If you need intermediate calculations, put them inside the Export object

  2. Don't Export Inputs:

    • Input parameters are already exported automatically

    • Only use Export objects for computed/calculated results

  3. Name Export Objects for Override:

    • Give Export objects a name (e.g., <O N="Results" T="Export">) when you want child objects to override them

    • Named Export groups can be overridden using Override="1" in extended objects:

  4. ⚠️ CRITICAL: Never Add Guard Directly to T="Export" Objects:

    Problem: When Guard is added directly to T="Export" objects in library objects, the Guard appears on the library object instance in the source code, which can cause the entire object to not execute.

    Solution: Add Guard to a nested Group within the Export object:

    Rule: Always wrap guarded parameters in a nested T="Group" within the Export object.

For more details: See AI-Export.md


1.3 DesignRun Objects

DesignRun objects are bridge objects that override parameters of a target library object specified by LibObjTypeName. They work similarly to Extends + Override="1", but with a critical restriction: only parameters that exist within the LibObjTypeName object can be overridden (scoped override, not hierarchical).

Purpose:

  • Override parameters of a specific library object (scoped to that object only)

  • Act as a bridge between user-defined parameters and library object parameters

  • Execute design calculations with custom parameter values

Key Parameters:

  • LibObjTypeName (CRITICAL): Specifies which library object's parameters to override

  • LibObjVersion: Version number of the target library object

Key Restrictions:

  1. Parameters only - Cannot override child objects (cannot use Override="1" on objects)

  2. Must pre-exist - Can only override parameters that already exist within LibObjTypeName scope

  3. Scoped to LibObjTypeName - Overrides parameters within that library object and its extended objects

  4. Includes extended objects - If LibObjTypeName has child objects using Extends, their parameters can also be overridden

Common Practice:

  • Typically override Role="Input" parameters - These are data inputs from users

  • Rarely override calculated parameters - If logic needs changing, modify the base library object instead

  • Rationale: DesignRun is for data override, not logic override

DesignRun Object Structure:

How DesignRun Works:

  1. DesignRun specifies target library object via LibObjTypeName

  2. Parameters in DesignRun override corresponding parameters within that library object's scope

  3. Extended objects included - Parameters from objects extended within LibObjTypeName can also be overridden

  4. If the same parameter name appears multiple times in the library scope, all instances are overridden

  5. Library object uses the overridden parameter values in its calculations

  6. Only parameters that exist in LibObjTypeName scope can be overridden (no new parameters)

CRITICAL: Bidirectional Parameter Synchronization

DesignRun overrides are scoped to the LibObjTypeName object only (unlike Extends + Override="1" which is hierarchical). This means parameter names must match between the library object and DesignRun. When you rename a parameter:

Direction 1: Library → DesignRun If you rename a parameter in the library object that is overridden by DesignRun:

  1. Find all DesignRun objects with LibObjTypeName pointing to that library

  2. Update the parameter name in those DesignRun objects

Direction 2: DesignRun → Library If you rename a parameter in DesignRun that overrides a library parameter:

  1. Check the library object specified in LibObjTypeName

  2. Update the parameter name in that library object

  3. Update all internal references to that parameter in the library

Example 1: Scoped Override (Only LibObjTypeName)

Example 2: Overriding Extended Object Parameters

Example 3: Renaming Parameters

Step-by-Step: Renaming Parameters

When you need to rename a parameter that's involved in DesignRun override:

Starting from Library Object:

  1. Identify the library object (e.g., OBPBase_MyCodeCheck)

  2. Change the parameter name in the library object (e.g., oldNamenewName)

  3. Update all internal references to that parameter within the library

  4. Search for all DesignRun objects with LibObjTypeName = "OBPBase_MyCodeCheck"

  5. Update parameter names in those DesignRun objects to match the new name

Starting from DesignRun Object:

  1. Find LibObjTypeName value to identify the target library object

  2. Change the parameter name in DesignRun (e.g., oldNamenewName)

  3. Open the library object specified in LibObjTypeName

  4. Update the parameter name in the library object

  5. Update all internal references to that parameter within the library

⚠️ WARNING: Non-Input Parameter Override Behavior

DesignRun has a dangerous capability that must be carefully controlled:

The Problem: DesignRun can override ANY parameter in the LibObjTypeName scope, not just Role="Input" parameters. When you override a non-Input parameter:

  • ALL occurrences of that parameter name in the library object scope are overridden

  • This includes uses in calculations, expressions, and child objects

  • The override affects the entire LibObjTypeName object and its extended objects

Example - Unintended Override:

Result:

  • width_input = 15 (from UserWidth) ✅ Expected

  • safety_factor = 2.0 (from UserSafetyFactor) ⚠️ Overridden everywhere

  • capacity = (15 * 20) * 2.0 = 600 (uses overridden safety_factor)

  • check1 = 600 * 2.0 = 1200 (uses overridden safety_factor)

  • check2 = 15 * 2.0 = 30 (uses overridden safety_factor)

When This Happens:

  • Breaks library object's internal logic - calculated parameters no longer use intended values

  • Creates maintenance nightmare - changes to library don't behave as expected

  • Violates separation of concerns - DR should only provide input data, not override calculations

  • Hard to debug - override affects multiple locations silently

  • Unexpected behavior - other developers don't expect internal parameters to be overridden

What To Do Instead:

If user needs to control a parameter that's not Role="Input":

  1. Add Role="Input" to that parameter in the library object (RECOMMENDED)

    • Makes it officially part of the library object's API

    • Clear to all developers that this parameter is meant to be configurable

    • Proper design pattern - data inputs belong in Role="Input"

  2. If parameter should remain internal:

    • Do NOT override it from DesignRun

    • Modify library object logic if behavior needs to change

    • Keep data override (DR) separate from logic (library)

Comparison:

Aspect

Role="Input" Parameter

Non-Input Parameter

Purpose

User-configurable data input

Internal constant/calculation

Recommended for DR?

YES - primary use case

NO - problematic

Override behavior

Standard, expected

Overrides ALL occurrences

Best practice

Always map these in DR

NEVER override from DR

User expectation

Should be controllable

Should be internal/fixed

When found in DR

Normal, correct usage

Flag as error in code review

Best Practices:

  1. Parameters only, not objects - DesignRun can only override parameters, not child objects

  2. Must pre-exist in library scope - Cannot add new parameters; can only override existing ones (including extended objects)

  3. Scoped to LibObjTypeName - Overrides parameters within library object and its extended objects

  4. Extended objects included - Parameters from Extends objects within library can be overridden

  5. ONLY override Role="Input" parameters - These are data inputs designed to be overridden

  6. NEVER override non-Input parameters - This breaks library logic and creates bugs

    • ⚠️ If you find a non-Input override in DR: Add Role="Input" to library or remove from DR

  7. Multiple same-name parameters - If the library has the same parameter name multiple times, all are overridden

  8. Data override, not logic override - Use DesignRun for data inputs, use library edits for logic changes

  9. Bidirectional sync is critical - Changes in either location require updates in the other

  10. Always check LibObjTypeName to find which library object is being overridden

  11. Check extended objects too - If library uses Extends, those parameters can also be overridden

  12. Search across multiple files - DesignRun objects may be in different files than the library

  13. Test after renaming to ensure overrides still work correctly

  14. Code review must flag non-Input overrides - These are bugs that need fixing

2. Parameters (Param)

Parameters store data and expressions within objects. They are the "DNA" of parametric behavior.

Parameter Types:

  • Number (ParamType.Number): Numeric values or mathematical expressions

  • Text (ParamType.Text): String values or object references

Value Types:

  • Expression (ValueType.Expression): Contains formulas that are evaluated (e.g., "L/2 + 10")

  • Value (ValueType.Value): Contains literal values (e.g., 100)

Parameter Properties:

  • Name (N): Parameter identifier

  • Value (V): The expression or value

  • Type (T): Expr, Num, Text, or ObjectType (for references)

  • Description (D): Human-readable description

  • UnitType (UT): Length, Force, Stress, etc.

  • UnitCategory (UC): Default, Metric, Imperial, etc.

  • Role: None, Input, Private, Export, Import

  • Category: For grouping parameters in UI

  • DisplayWidth: UI display width

  • Attr: If "1", parameter is serialized as XML attribute (for brevity)

  • Optional: If "1", parameter is optional

3. Expression Evaluation (Eval)

The evaluation engine computes parameter values by:

  1. Parsing expressions using JavaScript-compatible syntax

  2. Resolving identifiers to their values from the parametric model

  3. Executing mathematical operations and functions

  4. Caching results for performance

Supported Operations:

  • Arithmetic: +, -, *, /, %, ^

  • Comparison: <, >, <=, >=, ==, !=

  • Logical: &&, ||, !

  • Ternary: condition ? value1 : value2

  • Mathematical functions: sqrt, abs, sin, cos, tan, asin, acos, atan, atan2, min, max, pow, exp, log, floor, ceil, round, etc.

Identifier Resolution:

  • Parameters are referenced by name (e.g., Length, Width)

  • The system uses a distance-based algorithm to resolve identifiers (detailed below)

  • Objects are referenced by name and accessed with dot notation (e.g., Girder1.Length)

  • Use brackets for indexed access (e.g., Girders[0].Width)

3.1 Lazy Evaluation

The parametric engine uses lazy evaluation, meaning expressions are not computed when they are defined—they are evaluated only when their values are actually needed.

How It Works:

  1. Definition Time: Expressions are stored as text strings and compiled into an Abstract Syntax Tree (AST)

  2. Evaluation Time: When a parameter value is requested (e.g., for display, geometry generation, or use in another expression), the GetValue() method is called

  3. Backward Evaluation: The engine works backward through dependencies—if ParamA needs ParamB, it evaluates ParamB first, which might need ParamC, and so on

  4. Caching: Computed values are cached to avoid redundant calculations. The cache is invalidated when dependencies change

  5. Circular Dependency Detection: The execution stack tracks the evaluation chain to detect and prevent circular dependencies

Benefits:

  • Performance: Only computes what's actually needed

  • Flexibility: Parameters can reference objects/parameters that are defined later in the XML

  • Dynamic Updates: When an input parameter changes, only affected downstream parameters are re-evaluated on next access

Example:

Evaluation Chain Example:

3.2 Distance-Based Parameter Resolution

When multiple parameters or objects have the same name, the engine uses a distance-based algorithm to determine which one to use. This allows parameters to be overridden at different levels of the hierarchy.

Resolution Algorithm:

When an expression references an identifier (e.g., Width or Beam1):

  1. Search Parent Chain First: Walk up from current object to root, looking for the parameter

    • Current object's parameters

    • Parent's parameters

    • Grandparent's parameters, etc.

    • Stop if found or root is reached

  2. Search Entire Project (if not found in parent chain): Get ALL parameters/objects with that name from the entire project

  3. Calculate Distance for each candidate:

  4. Pick Closest: Select the parameter/object with the minimum distance

Example: Basic Distance Resolution

Example: Parameter Shadowing (Override Pattern)

Example: Scope Penalty (+100 Distance)

Distance Calculation Reference:

Scenario
Steps
Penalties
Total Distance
Notes

Same object

0

0

0

Always wins

Parent object

1

0

1

Grandparent

2

0

2

Sibling (same parent)

2

0

2

Up 1, down 1

Through scoped parent

1

+100

101

Scope creates strong boundary

Sibling in scoped object

2

+100

102

Cross 2 scope boundaries

varies

+200

high

Rarely wins

Uncle (parent's sibling)

3

0

3

Up 2, down 1

Example: Nested Scopes

4. Repeat/Iteration (Repeat)

The Repeat object enables parametric arrays and iterations.

Key Parameters:

  • CTRL: Name of the control parameter (loop variable)

    • ⚠️ WARNING: Do NOT use reserved keywords as CTRL names (e.g., pi, e, sin, cos, etc.)

    • pi is reserved for π (3.14159...) and cannot be used as a loop variable

    • Use descriptive names like i, j, k, idx, pileIndex, etc.

  • S: Start value

  • E: End value

  • I: Increment (default: 1)

During compilation, the Repeat generates copies of its child content for each iteration.

Example: Create 5 points along a line

For details See AI-Core-Objects.md

Guards - Conditional Object Activation

Guard is a special parameter that activates or deactivates objects based on conditions.

Purpose

Guards allow conditional geometry, calculations, or object creation based on user selections or parameter values.

Syntax

The Guard parameter must evaluate to a boolean (true/false):

  • True → Object is active and evaluated

  • False → Object is deactivated (skipped)

Common Guard Operators

  • .EQ. - Equal to

  • .NE. - Not equal to

  • .GT. - Greater than

  • .LT. - Less than

  • .GE. - Greater than or equal

  • .LE. - Less than or equal

  • .AND. - Logical AND

  • .OR. - Logical OR

Example: Conditional Column Geometry

How it works:

  1. User selects ColumnType (Rectangular or Circular)

  2. Each geometry object has a Guard checking the selection

  3. Only the matching object is activated and creates geometry

  4. The other object is skipped

Multiple Conditions

Guards can use complex conditions:

Common Patterns

Option Selection:

Threshold-Based:

Multiple Criteria:


XML Format

Basic Structure

Concise vs. Verbose Format

Concise (Preferred): When possible, define parameters as attributes on the object node:

Verbose: When you need to specify parameter metadata (units, description, role, etc.):

Common Patterns

1. Simple Numeric Parameter

2. Expression Parameter

3. Parameter with Units

4. Text Parameter

5. Object Reference

6. Object Reference (Attribute Style)

When defining as an attribute, prefix with @ and optionally specify type with |:

7. User Input Parameter

8. List/Array Parameter

9. Referencing Objects Pattern (Bidirectional References)

This pattern establishes automatic two-way references between parent and child objects. When a child object references a parent, it automatically appears in the parent's "Referencing Objects" list. This is essential for navigating object relationships in complex models.

Use Cases:

  • Girder → Cross Frames (bracings)

  • Pier Column → Foundation

  • Deck → Barrier

Parent Object (Girder):

Child Object (CrossFrame):

Key Components:

Component
Location
Purpose

bracings parameter

Parent's "Referencing Objects" group

Stores list of child objects

ReadOnly="1"

Parent's ParamInfo

Prevents manual editing, system-managed

RefParam="@bracings"

Child's ParamInfo

Tells system to add this object to parent's bracings list

How It Works:

  1. User creates child object (CrossFrame) and selects parent (Girder)

  2. System automatically adds CrossFrame to Girder's bracings list via RefParam

  3. Parent's "Referencing Objects" tab shows all children

  4. When child is deleted, it's automatically removed from parent's list

Navigation Through References:

Other objects can navigate through referencing objects to access nested data. For example, a Deck object takes a girder list as input, then can access each girder's cross frames via girder.bracings:

9. Referencing Objects Pattern (Bidirectional References)

This pattern establishes automatic two-way references between parent and child objects. When a child object references a parent, it automatically appears in the parent's "Referencing Objects" list. This is essential for navigating object relationships in complex models.

Use Cases:

  • Girder → Cross Frames (bracings)

  • Pier Column → Foundation

  • Deck → Barrier

Parent Object (Girder):

Child Object (CrossFrame):

Key Components:

Component
Location
Purpose

bracings parameter

Parent's "Referencing Objects" group

Stores list of child objects

ReadOnly="1"

Parent's ParamInfo

Prevents manual editing, system-managed

RefParam="@bracings"

Child's ParamInfo

Tells system to add this object to parent's bracings list

How It Works:

  1. User creates child object (CrossFrame) and selects parent (Girder)

  2. System automatically adds CrossFrame to Girder's bracings list via RefParam

  3. Parent's "Referencing Objects" tab shows all children

  4. When child is deleted, it's automatically removed from parent's list

Navigation Through References:

Other objects can navigate through referencing objects to access nested data. For example, a Deck object takes a girder list as input, then can access each girder's cross frames via girder.bracings:

Practical Examples

Example 1: Simple Rectangle

Example 2: Parametric Rectangle

Example 3: Array of Points Using Repeat

Example 4: Girder with Cross-Section

Example 5: Multi-Girder Bridge

Example 6: Conditional Objects (Guards)

Example 7: Object Inheritance (Creating Variations)

Advanced Features

Object Inheritance

Objects can inherit from other objects in the project by using the base object's name as their Type. When you do this, the new object inherits all parameters and child objects from the base object, and you can override specific parameters as needed.

Pattern:

  1. Define a base object with parameters

  2. Create derived objects using the base object's name as the T attribute

  3. Override parameters by specifying them as attributes or child parameters

Example:

In the above example, SkinnyCol and WideCol inherit all the parameters, child objects, and behavior from Col, but override the dimensional parameters. This is particularly useful for creating variations of standard components.

Extends - Importing Library Objects

Overview

The Extends attribute copies all parameters and child objects from one or more library objects into your current object. This is the primary mechanism for:

  • Importing AASHTO chapter implementations

  • Reusing calculation modules

  • Building complex objects from simpler components

  • Creating object namespaces

Key Concept: Think of Extends as copying the entire object tree from the library object(s) into your object.


Extends creates a new instance (copy) of the library object. Think of the library as a class/template, and each Extends creates a new object instance from that template.

Key Concept: Each time you use Extends, you create a separate instance with its own copy of the library's code.

Example - Creating Multiple Instances:

What Happens:

  1. Extends creates a new instance: Extends="AASHTO_Section3_4::v3" makes a complete copy of the library's structure into the new object

  2. Each Extends = Separate Instance: Instance1 and Instance2 are independent copies with their own parameter values

  3. Override="1" enables parameter replacement: Allows you to define parameters that replace same-named parameters in this instance's copy

  4. Original library unchanged: The AASHTO_Section3_4 library itself remains unchanged

  5. Independent calculations: Instance1 calculates with ADTTSL=5000, Instance2 with ADTTSL=8000

Object-Oriented Programming Analogy:

Without Override (Reading Default Values):

With Override (Setting Instance Parameters):

Key Takeaways:

  • Extends = Create new instance (copy) from library template

  • Override="1" = Enable replacing parameters and objects in this instance

  • Each Extends creates a separate, independent instance

  • Parameters/objects you define replace same-named parameters/objects in that instance only

  • Original library remains unchanged

For more detailed explanation: See AI-Extends.md

Overriding Objects (Not Just Parameters)

With Override="1", you can override child objects by defining objects with the same name, not just parameters.

Example - Overriding Child Objects:

How Override Works:

  1. The engine copies the library into the instance

  2. For each parameter/object you define in the instance

  3. It searches for a matching name in the copied library

  4. If found, it replaces that parameter/object entirely

  5. This works for both parameters (<P>) and objects (<O>)

Use Cases:

  • Override specific calculation modules while keeping the rest of the library

  • Replace default implementations with custom logic

  • Inject test values for specific sub-objects


Multiple Extends

You can extend from multiple objects by using array syntax:

Key Points:

  • Use array syntax: Extends="[Obj1, Obj2, Obj3]"

  • All listed objects are copied into your object

  • If objects have parameters with the same name, the last one in the list wins

  • Transitive: If you extend A, and A extends B, you also get B's content


Override Attribute - Setting Library Inputs

Library objects often define input parameters (with Role="Input"). The Override="1" attribute allows you to provide values for these inputs when extending the library.

Think of it Like a Function Call:

Conceptual Equivalent in Programming:


Scoped Attribute with Extends

The Scoped="1" attribute is commonly used with library imports to prevent parameter name conflicts.

Without Scoped:

With Scoped:

Best Practice: Always use Scoped="1" when importing library objects to avoid unintended parameter shadowing.


Versioning with ::v3

Library objects often include version tags (e.g., ::v3) to support multiple versions of the same code.

Benefits:

  • Backward compatibility - old projects keep using ::v3

  • Gradual migration - test ::v4 in parallel

  • Clear dependency tracking


Complete Real-World Example


Key Takeaways

  1. Extends = Copy: Copies the entire object tree from library into your object

  2. Container Pattern: Create <O N="ChapterName" T="Group" Extends="Library::v3" Scoped="1"/> for namespacing

  3. Override="1": Allows setting input parameters of the extended library object

  4. Scoped="1": Isolates library internals from your project namespace

  5. Dot Notation: Access library content via ContainerName.InternalPath.Parameter

  6. Multiple Extends: Use array syntax Extends="[Obj1, Obj2, Obj3]"

  7. Versioning: Use ::v3 for version control


Common Patterns Summary

Pattern 1: Import Library as Namespace

Pattern 2: Import Library with Input Override

Pattern 3: Extend Multiple Libraries

Pattern 4: Transitive Access


Station-Dependent Parameters

Some parameters can vary along a station (alignment coordinate):

Format: [[station_start, station_end], value, ...]

Built-in Functions

Common parametric functions available in expressions:

  • Geometric: online(p1, p2, t), intersect(line1, line2), point(obj, station)

  • Array: sum(array), min(...), max(...), length(array), first(array), last(array)

  • Units: convert(value, fromUnit, toUnit), withunits(value, unitType, unitCat)

  • Object queries: refs(objType), objs(objType), value(objName, paramName)

  • Geometry: surfarea(surface), volume(solid), perimeter(boundary)

Special Identifiers

  • self: Reference to current object

  • myself: Reference to current parameter's parent object

  • pi: π constant

  • NULL: Null object reference

Best Practices

1. Use Descriptive Names

2. Provide Default Values for Inputs

3. Use Appropriate Unit Types

4. Prefer Concise Format When Possible

6. Use Guards for Conditional Content

Choose the appropriate guard type for your use case:

  • Guard: For typical optional components (most common)

  • GuardX: For library development when you need to preserve the guard condition

  • DesignGuard: For design checks that may not apply in all cases

7. Use map() for Parameter Loops, Repeat Only for Objects

CRITICAL PERFORMANCE RULE: Never use Repeat for calculating parameter values—always use functional programming instead.

When to use each:

  • Use Repeat: Creating actual objects (Points, Lines, Volumes, Girders, etc.)

  • Use map(): Transforming data, extracting properties, calculating values

  • Use filter(): Selecting subset of data based on conditions

  • Use reduce(): Aggregating data to single value

See section 4.1 for detailed explanation and performance impact.

8. Document Complex Expressions

8. Use Scoped Objects Deliberately

Use Scoped="1" to create isolated parameter namespaces and prevent accidental parameter resolution from outside:

9. Avoid Unintentional Parameter Shadowing

Be deliberate when using the same parameter name at multiple hierarchy levels. If shadowing is unintentional, use unique names:

10. Understand Distance-Based Resolution

When multiple parameters share the same name, document the expected resolution in comments:

11. Optimize for Lazy Evaluation

Structure your model to take advantage of lazy evaluation:

12. Consider Hierarchy Performance

Avoid excessively deep hierarchies for frequently-accessed parameters:

Common Pitfalls to Avoid

  1. Using Repeat for Parameter Loops (CRITICAL PERFORMANCE ISSUE): This is the #1 performance mistake in ParamML models.

    ❌ WRONG:

    Problem: Creates 100 objects in project tree, slow compilation, high memory usage

    ✅ CORRECT:

    Why: Single parameter, instant evaluation, minimal memory

    Rule: Use Repeat ONLY to create objects that must exist in the 3D model, FEA mesh, or project tree. For all data transformations, use map(), filter(), or reduce().

    See section 4.1 for detailed explanation.

  2. Circular Dependencies: Ensure Parameter A doesn't depend on Parameter B if B depends on A. The lazy evaluation system will detect this and throw an error.

  3. Undefined References: Always ensure referenced objects/parameters exist in the hierarchy or project.

  4. Type Mismatches: Don't use numeric expressions for Text parameters.

  5. Missing Units: Specify unit types for physical quantities (Length, Force, Stress, etc.).

  6. Invalid Guards: Guard expressions must evaluate to 0 (false) or 1 (true).

  7. Repeat Issues: Ensure S, E, and I parameters create finite iterations.

  8. Unintended Parameter Shadowing: When multiple parameters have the same name at different hierarchy levels, the closest one (by distance) is used. This can cause unexpected behavior if you're not aware of which parameter is being resolved.

  9. Scope Boundary Surprises: Objects with Scoped="1" add +100 to distance calculations, creating strong isolation boundaries. Parameters inside scoped objects are "far away" from outside objects.

  10. Distance vs. XML Order Confusion: Parameter resolution is based on hierarchy distance, not the order parameters appear in XML. The engine always picks the closest parameter by distance, even if another parameter with the same name was defined first.

  11. Lazy Evaluation Timing: Remember that expressions are NOT evaluated when defined. They're evaluated on-demand. Changing an input parameter doesn't automatically update dependent parameters until they're accessed.

  12. Guard Expression Restrictions: Guard/GuardX expressions cannot reference parameters inside the object they guard (this would create a circular dependency during compilation). Always reference external parameters for guard conditions.

    Additionally, remember that Guard and GuardX are compile-time (object removed if false), while DesignGuard is runtime (object marked "not applicable" in reports).

  13. Deep Hierarchy Performance: Extremely deep hierarchies (10+ levels) can slow down parameter resolution. Consider flattening the structure or using scoped objects strategically to limit search scope.

Debugging Tips

  1. Check Parameter Names: Names are case-sensitive.

  2. Verify Object Types: Ensure T attribute matches actual class names.

  3. Test Expressions: Start with simple literals before adding complexity.

  4. Use Descriptive Names: Makes debugging much easier and reduces shadowing issues.

  5. Check Parent-Child Structure: Ensure objects are properly nested.

  6. Validate XML: Ensure proper closing tags and attribute quoting.

  7. Trace Parameter Resolution: When a parameter has an unexpected value, manually calculate the distance from the evaluation point to all candidates with that name. The one with minimum distance wins.

  8. Check Scope Boundaries: Look for Scoped="1" attributes in parent objects. They create isolation that may prevent expected parameter resolution.

  9. Verify Lazy Evaluation: If a parameter doesn't seem updated after changing an input, check if anything has actually requested its value. Try explicitly accessing it to trigger re-evaluation.

  10. Use Unique Names Strategically: If shadowing is causing confusion, use unique parameter names across the hierarchy, or use very deliberate shadowing for override patterns.

  11. Debug with Comments: Add XML comments showing expected distance calculations to document your resolution assumptions:

Advanced Library Development Features

The following features are essential for creating reusable library components with rich UI integration and metadata.

1. ParamInfo Object

ParamInfo is a special object type that provides metadata and configuration for parameters, controlling their UI behavior, validation, and visibility.

Common ParamInfo Attributes:

  • Param: Name of the parameter being configured (use @ prefix for object references)

  • Required: If "1", parameter must be provided (UI enforces)

  • Pick: If "1", enables object picker UI for selection

  • List: If "1", parameter is a list/array

  • Min: Minimum number of list items

  • Max: Maximum number of list items

  • ListColumnHeaders: Array of column header names for list UI

  • ListColumnTypes: Array of types for each column

  • ParamGuard: Conditional visibility expression (see ParamGuard section below)

  • ParamInterface: Custom parameter input interface (see ParamInterface section below)

⚠️ CRITICAL: Min and Max for List Parameters

When using Pick="1" with list parameters, BOTH Min and Max must be specified if you want to allow multiple selections. If only Min is provided without Max, the system defaults Max to 1, allowing only a single selection even if Min > 1.

Rule: For list inputs with unknown maximum count, always specify a reasonable Max value (e.g., Max="100").

Example: Required Object with Picker

This makes the Girder parameter required and adds a UI picker button for selecting girder objects.

Example: List Parameter with UI Configuration

This configures NonCompCase as a list with 1-50 items and uses a custom interface for input.

Example: List with Column Headers

This creates a list parameter with a single column labeled "Additional Stations".

Complete Example:

2. Object Metadata Attributes

Library objects can include metadata attributes that control organization, categorization, and UI display.

Metadata Attributes:

  • Tags: Comma-separated tags for filtering and categorization (prefix with @ for tag names)

  • ObjLabel: User-friendly display name for the object

  • Category: Hierarchical category path (use : separator for subcategories)

Example:

Tag Usage:

  • @secondlayer: Indicates this is a secondary-level component

  • @usastandard: US design standards

  • @steelIGirder: Applies to steel I-girder bridges

  • @release: Ready for production release

Category Hierarchy: The category path creates a tree structure in the UI:

Best Practices:

  • Use descriptive ObjLabel values that users will recognize

  • Create consistent tag vocabularies across your library

  • Organize categories hierarchically from general to specific

  • Use tags for filtering (e.g., bridge type, code standard, region)

3. Extends Attribute

The Extends attribute provides a different inheritance mechanism than the T (Type) attribute. While T specifies the object's class or base type, Extends allows you to inherit parameters and structure from another object while maintaining a different base type.

Syntax:

Key Differences:

  • Type (T): Defines the object's fundamental class (e.g., Project, Group, Volume)

  • Extends: Imports parameters and child objects from another object without changing the base type

Example:

Versioning Pattern: Use ::vN suffix for versioned objects to maintain backward compatibility:

When to Use Extends vs Type:

  • Use Type (T): To define what kind of object it is (Volume, Group, Project, etc.)

  • Use Extends: To import a set of default parameters and structure from a template

4. ParamGuard

ParamGuard is different from Guard - while Guard removes entire objects, ParamGuard controls parameter visibility in the UI based on conditions.

Key Differences:

Feature
Guard
ParamGuard

Applied To

Objects

Parameters (via ParamInfo)

Effect

Removes object if false

Hides parameter UI if false

Evaluation

Compile-time

Runtime (UI update)

Use Case

Conditional components

Conditional parameter visibility

Syntax:

Example: Conditional Parameter Visibility

In this example:

  • When ReinfDataPref == 0: Only LumpedTopReinfArea is visible in UI

  • When ReinfDataPref == 1: DetailedBarSize and DetailedBarSpacing are visible

Complex Conditions:

Best Practices:

  • Use ParamGuard to simplify UI by hiding irrelevant parameters

  • Guard expressions should reference other parameters in the same object or parent objects

  • Combine with Required flag: Required="1" only enforces when ParamGuard is true

  • Keep guard expressions simple and fast (evaluated on every UI update)

5. ParamInterface

ParamInterface specifies a custom UI component for parameter input, enabling specialized editing experiences beyond standard text/number inputs.

Syntax:

Common Custom Interfaces:

  • @OBPParamInterfaceCombinationAndFactors: Load combination editor

  • @OBPParamInterfaceStationPicker: Station selection with alignment visualization

  • @OBPParamInterfaceColorPicker: Color selection UI

  • @OBPParamInterfaceMaterialPicker: Material database browser

Example: Load Combination Interface

Example: Custom Table Interface

Creating Custom Interfaces: Custom interfaces are defined as objects with specific UI behavior:

6. List Parameters with UI Configuration

List (array) parameters can be configured with rich UI metadata using ParamInfo.

List Configuration Attributes:

  • List="1": Declares parameter as a list

  • Min: Minimum number of items (enforced by UI)

  • Max: Maximum number of items

  • ListColumnHeaders: Array of column names (as JSON array string)

  • ListColumnTypes: Array of types for each column ('Number', 'Text', 'Object', etc.)

Example: Simple List

Example: Multi-Column List

Example: List of Object References

Accessing List Items in Expressions:

Best Practices:

  • Always set reasonable Min and Max limits

  • Provide descriptive column headers

  • Match ListColumnTypes to actual data types for proper validation

  • Use Pick="1" for lists of object references to enable picker UI

7. NAME_ALIAS and EXPR_ALIAS

These special documentation markers in parameter descriptions provide human-readable aliases for parameters and expressions, improving code readability and auto-generated documentation.

Syntax in Description Field:

NAME_ALIAS - Readable Parameter Names:

When referenced in reports or UI:

  • Shows "My_Total" instead of "My_Pos_MaxF_Total"

  • Shows "Mx_DL" instead of "Mx_Neg_DL_Max"

EXPR_ALIAS - Readable Expressions:

In documentation and error messages:

  • Shows "σ/σ_allowable" instead of the internal expression

  • Shows "KL/r" instead of "EffectiveLength / RadiusOfGyration"

Complete Example:

Benefits:

  • Auto-generated reports show clean, professional notation

  • Error messages reference familiar names

  • Code remains self-documenting

  • Maintains backward compatibility (internal names unchanged)

Best Practices:

  • Use NAME_ALIAS for commonly referenced parameters

  • Use EXPR_ALIAS for mathematical expressions with standard notation (Greek letters, engineering symbols)

  • Place aliases at the beginning of the description

  • Keep aliases concise and meaningful

8. StaticParams on Repeat

StaticParams is a performance optimization attribute for Repeat objects that identifies parameters whose values don't change across iterations.

Problem: In a Repeat object, child objects are instantiated for each iteration. Normally, all parameters are re-evaluated for every iteration, even if they reference values that are constant across all iterations.

Solution: StaticParams tells the engine which parameters can be evaluated once and reused across all iterations.

Syntax:

IMPORTANT: The StaticParams value MUST be enclosed in square brackets []. Without brackets, it will not work correctly.

Example Without StaticParams (Inefficient):

Example With StaticParams (Optimized):

Real-World Example:

Performance Impact:

  • Without StaticParams: If repeating 100 times with 10 static parameters = 1,000 evaluations

  • With StaticParams: 10 evaluations (static) + 100 evaluations (dynamic) = 110 evaluations

  • ~90% reduction in redundant calculations

Best Practices:

  • Include all parameters that reference parent objects or global constants

  • Include material properties, design codes, and analysis settings

  • Exclude parameters that use the iteration variable (i, CTRL)

  • Exclude parameters that reference the current iteration's data

  • Test with and without to verify performance improvement (significant for large repeats)

9. Section Geometry Objects

Section objects define cross-sectional geometry for structural elements. These are used for visualization, analysis, and design calculations.

Core Section Objects:

  • Section: Container for cross-section definition

  • Shape: Defines a 2D closed polygon within a section

  • Circle: Defines a circular shape within a section

  • Point: Vertices of shapes (2D local coordinates)

Section Object Structure:

Example: I-Girder Section

Example: Rectangular Section with Circular Void

Circle Object Attributes:

  • CX: X-coordinate of center

  • CY: Y-coordinate of center

  • R: Radius

  • IsVoid: If "1", circle is subtracted from section (void/opening)

ComputeProp Attribute:

  • ComputeProp="0": Section properties are NOT automatically computed (you provide them manually)

  • ComputeProp="1": Section properties (area, inertia, etc.) are automatically computed from geometry

Section with Properties:

Using Sections in Structural Elements:

Station-Dependent Sections:

10. Custom Object Types

Custom object types enable type-safe parameter references and ensure parameters reference objects of the correct type.

Standard Type Attribute:

Custom Object Type:

Type Hierarchy Example:

Common Custom Types in OpenBrIM:

  • OBPBase_GirderAnalysisResultsRef: Reference to girder analysis results

  • OBPInsertionPoint: Reference to an insertion point object

  • OBPSection: Reference to a section definition

  • OBPLoadCase: Reference to a load case

  • OBPCombination: Reference to a load combination

  • MaterialSteel: Reference to a steel material object

  • MaterialConcrete: Reference to a concrete material object

Benefits of Custom Types:

  • Type Safety: Prevents assigning wrong object types to parameters

  • UI Integration: Picker dialogs filter to show only compatible objects

  • Auto-completion: IDEs and editors can suggest valid objects

  • Documentation: Makes code intent clear (what kind of object is expected)

  • Validation: Runtime checks ensure correct object types

Example: Type-Safe Design Check

Creating Custom Types:

11. Required and Pick Flags

The Required and Pick flags on ParamInfo objects control parameter validation and UI behavior.

Required Flag:

  • Required="1": Parameter MUST have a valid value before object can be used

  • UI prevents saving/executing until required parameters are filled

  • Combines with ParamGuard: only required when guard condition is true

Example:

Pick Flag:

  • Pick="1": Adds a picker button in the UI next to the parameter

  • Clicking picker opens object selection dialog

  • Dialog is filtered by parameter's Type (if custom type specified)

Example:

Combined Usage:

Conditional Required:

List with Required:

Best Practices:

  • Always use Required="1" for critical parameters (girders, load cases, materials)

  • Combine Required="1" with Pick="1" for object references to guide users

  • Use Required with Min on lists to enforce minimum item count

  • Combine with ParamGuard to make parameters conditionally required

  • Provide sensible default values when possible (reduces required fields)

Example: Complete Parameter Configuration

12. Advanced ParamInfo Attributes

Beyond the basic ParamInfo features, OpenBrIM provides advanced attributes for UI optimization, custom interactions, and reference management.

12.1 ExpensiveComputation

Marks parameters as computationally expensive to enable UI performance optimizations.

Purpose: When set, the spreadsheet view caches computed values to avoid repeated evaluation of expensive expressions during rendering.

Syntax:

Example:

When to use:

  • FEA result extractions (force(), stress(), disp())

  • Geometric calculations (volume(), surfarea(), volumesurfareas())

  • Nested map() operations over large datasets

  • Complex iterative algorithms

  • Any parameter that takes >100ms to compute

Best Practices:

  • Combine with ReadOnly="1" for computed results

  • Use for parameters accessed frequently in UI but rarely changed

  • Don't overuse—only for genuinely expensive computations

12.2 CustomCellActions

Provides custom context menu actions for spreadsheet cells, enabling specialized editing interfaces.

Purpose: Adds custom actions to the right-click context menu in the spreadsheet view for interactive parameter editing.

Syntax:

Available Actions:

Stiffness/Matrix Editing:

  • "6x6Stiffness" - Edit 6x6 stiffness matrix (for nodes with StiffnessMatrix parameter)

  • "EditStiffness" - Edit spring stiffness values

  • "EditStiffnessTx", "EditStiffnessTy", "EditStiffnessTz" - Directional translational stiffness

  • "EditStiffnessRx", "EditStiffnessRy", "EditStiffnessRz" - Directional rotational stiffness

Analysis Curves:

  • "EditMomentCurvature" - Edit moment-curvature relationship

  • "ResponseSpectrumCurve" - Edit response spectrum curves

  • "PrestressingDetails" - Display tendon prestressing details

CADD Drawing:

  • "CADPolyDraw" - Draw polygon in CADD view

  • "CADPolyLineDraw" - Draw polyline in CADD view

  • "CADRectDraw" - Draw rectangle in CADD view

  • "CADPointDraw" - Draw point in CADD view

  • "CADCircleDraw" - Draw circle in CADD view

  • "CADLineDraw" - Draw line in CADD view

Other:

  • "DuplicateSection" - Duplicate section from ExtObj

  • "EditPath" - Edit path points interactively

  • "EditSpanLoc" - Edit span locations

  • "CentFactor", "WheelFactor", "ImpactFactor" - Edit load factors

Example:

Best Practices:

  • Only add actions relevant to the parameter's purpose

  • Combine with ParamGuard to show actions contextually

  • Use CADD actions for geometric input parameters

  • Use stiffness actions for FEA boundary condition parameters

12.3 RefParam

Establishes bidirectional references between objects for automatic dependency tracking.

Purpose: When an object is added/removed, automatically updates reference lists in related objects.

Syntax:

How it works:

  • When object is created, its name is added to the target list

  • When object is deleted, its name is removed from the target list

  • Maintains synchronized references across the project

Example:

Use Cases:

  • Maintaining lists of available load cases

  • Tracking which supports reference a pier

  • Maintaining object inventories

  • Automatic dropdown population

Note: RefParam creates two-way dependencies. Use carefully in modular library objects.

12.4 ReadOnly (Enhanced)

Makes parameters read-only in the UI while allowing programmatic updates.

Purpose: Prevents manual editing of computed values while displaying them to users.

Syntax:

Visual Effect:

  • Text color: Gray (#626262)

  • Cell editing: Disabled

  • Custom actions: Hidden

Example:

Common Pattern - Readonly Computed Quantities:

Best Practices:

  • Always use for derived/computed values

  • Combine with ExpensiveComputation for performance

  • Use for displaying object properties (e.g., Material.N, Section.Depth)

  • Don't use for input parameters

13. Coordinate Systems (CoorSys)

User-defined coordinate systems for local transformations and FEA boundary conditions.

Purpose: Define custom local coordinate systems using origin point and rotation (quaternion or Euler angles).

Type: CoorSys

Key Parameters:

  • X, Y, Z: Origin coordinates

  • Qx, Qy, Qz, Qw: Quaternion rotation components

  • Alpha, Beta, Gamma: Alternative Euler angles (ZYX order)

Quaternion Representation:

  • Qx, Qy, Qz: Vector part

  • Qw: Scalar part

  • Identity (no rotation): [0, 0, 0, 1]

Syntax:

Example - Using Quaternions:

Example - Using with Objects:

Quaternion Conversion Formulas:

Use Cases:

  • Skewed bridge piers

  • Rotated foundations

  • Local coordinate systems for boundary conditions

  • Transformed geometry placement

  • Consistent node positioning

Best Practices:

  • Use quaternions for single-axis rotations (more intuitive)

  • Quaternions avoid gimbal lock issues

  • Set origin at logical reference point

  • Document rotation axis and angle in description

  • Verify coordinate system orientation in 3D view

16. Object Attributes for Library Development

16.1 Override Attribute

Marks a group as overrideable by derived objects.

Purpose: Allows child objects to override entire groups of parameters when inheriting.

Syntax:

Example:

Use Cases:

  • IFC export configurations

  • Material overrides

  • Display settings

  • Analysis options

16.2 Opacity Attribute

Controls 3D object transparency.

Purpose: Sets opacity for visualization (0.0 = transparent, 1.0 = opaque).

Syntax:

Range: 0.0 to 1.0

Example:

Opacity Inheritance:

  • Child objects inherit parent opacity unless explicitly set

  • SpecifiedOpacity and opacity overrides can modify behavior

  • Final opacity = min(own opacity, parent opacity, overrides)

Use Cases:

  • Highlighting active elements

  • Showing/hiding secondary geometry

  • Construction sequence visualization

  • Context geometry display

Best Practices:

  • Use 1.0 for primary structural elements

  • Use 0.3-0.7 for reference geometry

  • Use 0.0 to hide (better than Guard for temporary hiding)

  • Consider performance impact of many transparent objects

13. Library Organization and Template System

OpenBrIM provides a comprehensive system for organizing library objects, workflows, and templates using metadata attributes. These attributes control how objects appear in the library tree view, template screens, and project workflows.

13.1 Core Organization Attributes

Metadata Attributes:

  • Tags: Comma-separated tags for filtering and categorization

  • ObjLabel: User-friendly display name (appears in UI)

  • Category: Hierarchical organization path (use : separator)

  • Role: Object role ("WorkFlow", "Template", "Input", etc.)

  • DocumentURL: Link to online documentation

  • ObjectVersion: Version number for tracking updates

  • Deprecated: If "1", marks object as deprecated

13.2 Tags Attribute

Tags enable filtering, categorization, and special behaviors for library objects.

Syntax:

Common Tag Categories:

Geographic/Standard Tags:

  • @usastandard: US design standards (AASHTO, ACI, AISC)

  • @eustandard: European standards (Eurocode)

  • @aashto, @aci, @aisc: Specific code standards

Bridge Type Tags:

  • @steelIGirder: Steel I-girder bridges

  • @precastIGirder: Precast concrete I-girders

  • @splicedIGirder: Spliced girder systems

  • @concreteBox: Concrete box girders

Functional Tags:

  • @workflow: Workflow definition object

  • @workflowtemplate: Template with workflow structure

  • @release: Ready for production use

  • @secondlayer: Secondary-level component

Special Tags:

  • @doc:URL: Embeds documentation link

  • @img:ImageName: Specifies template image

Example:

13.3 Role Attribute

The Role attribute defines how OpenBrIM treats and displays the object.

Role Values:

Role
Purpose
Behavior

WorkFlow

Workflow definition

Appears in workflow tree with hierarchical structure

Template

Project template

Appears on "Open Project" screen with thumbnail

Input

User input parameter

Highlighted in parameter list, shows in input forms

Export

Output/result parameter

Shown in results, available for export

Private

Internal parameter

Hidden from standard UI views

Import

Imported/referenced data

Marks data from external sources

Example: Workflow Object

Example: Template Object

13.4 Category Attribute

The Category attribute controls how objects and parameters are organized in the UI. Important: The behavior differs significantly between object-level and parameter-level usage.

13.4.1 Object-Level Categories (T="Project" Objects)

Objects with T="Project" support hierarchical categories using the :: separator:

Syntax:

Example:

This creates a tree structure in the library browser:

Multiple Levels:

Common Category Hierarchies:

Project Templates:

Generative:

Databases:

Use Cases:

  • Library organization

  • Template categorization

  • Code check object grouping

  • Project structure hierarchy


13.4.2 Parameter-Level Categories (P Elements)

Parameters support single-level categories only - the :: syntax is NOT supported.

Syntax:

✅ CORRECT Examples:

❌ INCORRECT - Will Not Work:

How It Appears in UI: Parameters are grouped by their Category value in the parameter panel:

Use Cases:

  • Grouping input parameters in UI

  • Organizing display settings

  • Categorizing geometry parameters

  • Database field organization


13.4.3 Key Differences

Feature
Object Category
Parameter Category

Syntax

Category="Parent::Child"

Category="SingleLevel"

Hierarchy

✅ Multi-level supported

❌ Single level only

:: Separator

✅ Supported

Not supported

UI Location

Library browser tree

Parameter panel groups

Applies To

<O T="Project"> objects

<P> parameters

Example

"Bridge Workflow::CADD"

"Detailing"


13.4.4 Common Mistakes

Mistake #1: Using :: in Parameter Categories

Why: OpenBrIM/ParamML does not parse :: in parameter Category attributes. The entire string is treated as a single category name.

Mistake #2: Confusing Nested Groups with Category Hierarchy

Nested groups (<O T="Group">) provide organizational structure in XML but do NOT create category hierarchy for parameters:

Parameters inherit nothing from parent group names - they must specify their own Category.


13.4.5 Best Practices

For Objects:

  • Use descriptive hierarchies: "Domain::Subdomain::Type"

  • Keep depth reasonable (2-4 levels maximum)

  • Match existing library structure conventions

  • Use :: (double colon) as the separator

For Parameters:

  • Use concise, clear category names

  • Group related parameters together

  • Common categories: "General", "Geometry", "Properties", "Display", "Advanced", "Detailing"

  • Coordinate with existing parameter categories in your library

  • Do NOT use :: separator

Mixed Usage Example:


13.4.6 Why the Difference?

Technical Reason:

  • Object categories organize the library structure (file/folder metaphor)

  • Parameter categories organize UI panels (flat grouping)

  • Different UI contexts require different organizational models

Design Reason:

  • Parameter panels work best with flat, scannable groups

  • Deep hierarchies in parameter panels would be cumbersome

  • Library browsers benefit from tree navigation


13.5 WorkFlow and WorkFlowItem Objects

Workflows provide structured, step-by-step guidance for bridge modeling.

WorkFlow Structure:

WorkFlowItem Attributes:

  • ObjectType: Reference to the library object type (use @ prefix)

  • Label: Display name in workflow tree

  • ObjectVersion: Minimum required version

  • DocumentURL: Link to documentation

  • IconStageCons: If "1", shows construction stage icon

Complete Workflow Example:

13.6 Template Objects

Templates appear on the "Open Project" screen and provide pre-configured starting points.

Template Structure:

Special Tags for Templates:

  • doc:URL: Documentation link (e.g., doc:https://docs.openbrim.com/...)

  • img:ImageName: Image identifier for thumbnail (e.g., img:AllInOneBridgeImg)

Example: All-in-One Template

13.7 Version Management

Track object versions for compatibility and updates.

ObjectVersion Attribute:

Versioned Object References:

Deprecation:

13.8 Documentation Integration

Link objects to external documentation for user guidance.

DocumentURL Attribute:

Documentation in Tags:

13.9 Organization Best Practices

1. Use Consistent Naming:

2. Hierarchical Categories:

3. Appropriate Tags:

4. Documentation Links:

5. Version Tracking:

6. Template Organization:

13.10 Complete Organization Example

13.11 Template Display System

Templates with Role="Template" appear on the "Open Project" screen.

Display Elements:

  • Thumbnail: Specified by img:ImageName tag

  • Title: From ObjLabel attribute

  • Description: Generated from category and tags

  • Documentation: From doc:URL tag

Example Template Card Display:

Key Features:

  • Searchable by tags and labels

  • Filterable by category

  • Clickable documentation links

  • Visual preview via thumbnail

13.12 Database Objects

Database objects are special library containers that organize collections of reusable components like sections, materials, or reinforcement patterns. They appear in the library tree under the "Databases" category and provide pre-configured objects that users can select and use in their projects.

Database Object Characteristics:

  • Category="Databases:...": Places object in Databases category

  • Tags includes @database: Marks as database object

  • Contains grouped collections of related objects

  • Each item has Role="Input" parameters for configuration

Database Structure:

Common Database Categories:

Category
Purpose
Typical Contents

Databases:Section Database

Cross-section shapes

Girders, barriers, columns, piles

Databases:Material Database

Material properties

Concrete grades, steel types

Databases:Rebar Database

Reinforcement patterns

Bar sizes, spacing patterns

Databases:Vehicle Database

Load vehicles

AASHTO trucks, railroad loads

Databases:Load Database

Load definitions

Wind, seismic, temperature

Example: Barrier Section Database

Database Organization Patterns:

1. By Agency/Standard:

2. By Type/Category:

3. By Size Range:

Parametric Database Objects:

Database objects can be parametric, allowing users to configure dimensions:

Fixed Database Objects:

For standard, non-parametric objects (like agency-specific standards):

Database Object Usage:

Users access database objects in two ways:

1. Direct Reference:

2. Object Picker UI:

Best Practices for Database Objects:

1. Organization:

2. Naming Conventions:

3. Documentation:

4. Units:

5. Tags:

Database Object Categories:

Section Databases:

Material Databases:

Reinforcement Databases:

Load Databases:

Example: Material Database

Database Integration with Projects:

Projects reference database objects for consistent, standardized components:

Summary:

Database objects provide:

  • Centralized libraries of standard components

  • Reusable templates for common elements

  • Agency standards compliance

  • Parametric flexibility for customization

  • Consistent organization across projects

  • Easy selection via UI pickers

Key attributes:

  • Category="Databases:Type"

  • Tags includes @database

  • Organized in hierarchical groups

  • Parameters marked with Role="Input" for user configuration

  • Complete units and metadata definitions

Summary

The OpenBrIM parametric engine provides a powerful XML-based system for creating reusable, parametric bridge components. Key principles:

  • Objects form hierarchical structures with names and types

  • Parameters store values and expressions that define object behavior

  • Expressions create parametric relationships between objects and parameters

  • Repeat objects enable arrays and iterations for creating multiple instances (use ONLY for objects, NOT for parameter loops)

  • map(), filter(), reduce() for all parameter transformations (10-100x faster than Repeat)

  • ParamInfo provides rich metadata for parameter UI, validation, and behavior

    • Advanced features: ExpensiveComputation, CustomCellActions, RefParam, ReadOnly

  • Guards control conditional object inclusion (Guard) and parameter visibility (ParamGuard)

  • Metadata attributes (Tags, ObjLabel, Category) organize library components

  • Extends enables template-based inheritance with versioning

  • Custom types provide type-safe object references

  • Section objects define cross-sectional geometry for structural analysis

  • FEA nodes support MergeNearest, MergeSameLoc, StiffnessMatrix for advanced mesh control

  • FEA elements support IsRigid, BetaAngle, CastingDay, and node releases for connection modeling

  • CoorSys defines user coordinate systems with quaternions for local transformations

  • Override and Opacity attributes for library flexibility and visualization

  • Performance features like StaticParams and ExpensiveComputation optimize large-scale parametric models

  • Concise XML should be preferred when metadata isn't required

  • Inheritance is achieved by using an object's name as the Type of a new object, allowing you to create variations by overriding specific parameters

By following this guide, AI agents can create sophisticated parametric bridge models that are flexible, reusable, and maintainable.

Last updated