# Component Instances

## Overview

This guide covers how to **create and use library component instances** in ParamML - a fundamental feature for building reusable, parametric components.

**What you'll learn:**

* What object instances are
* How to create instances
* What gets copied to instances
* Basic usage patterns
* Simple nested instances

**For advanced topics** (Export dependencies, complex nesting, debugging): → See `AI-Export.md`

***

## What are Object Instances?

An **object instance** is created when you use a Library Component as a building block in your own component.

**Think of it like:**

* **Component Definition** = Blueprint/Template (e.g., "Cube")
* **Instance** = Using that blueprint (e.g., "MyCube")

### Analogy

```
Component Definition (Cube)
    ↓ (instantiate)
Instance (MyCube, YourCube, AnotherCube...)
```

Like a cookie cutter (component) making multiple cookies (instances).

***

## Creating an Instance

### Basic Syntax

To create an instance, use the component name as the `T` (Type) attribute:

```xml
<O N="InstanceName" T="ComponentName">
    <!-- Set input parameters -->
</O>
```

### Simple Example

### Simple Example

**Component definition:**

```xml
<O N="Rectangle" T="Project">
    <P N="width" V="100" Role="Input" />
    <P N="height" V="50" Role="Input" />
    
    <O T="Export">
        <P N="area" V="width * height" />
        <P N="perimeter" V="2 * (width + height)" />
    </O>
</O>
```

**Creating instances:**

```xml
<!-- Instance 1 -->
<O N="SmallRect" T="Rectangle">
    <!-- Inputs set by user -->
    <P N="width" V="50" />
    <P N="height" V="25" />
    
    <!-- Exported parameters copied automatically -->
    <P N="area" V="width * height" />
    <P N="perimeter" V="2 * (width + height)" />
</O>

<!-- Instance 2 -->
<O N="LargeRect" T="Rectangle">
    <!-- Inputs set by user -->
    <P N="width" V="200" />
    <P N="height" V="100" />
    
    <!-- Exported parameters copied automatically -->
    <P N="area" V="width * height" />
    <P N="perimeter" V="2 * (width + height)" />
</O>
```

**Using instances:**

```xml
<P N="small_area" V="SmallRect.area" />        <!-- = 50 * 25 = 1250 -->
<P N="large_area" V="LargeRect.area" />        <!-- = 200 * 100 = 20000 -->
<P N="total_area" V="small_area + large_area" /> <!-- = 21250 -->
```

***

## What Gets Copied to an Instance

When you create an instance, **only specific content appears**:

### ✅ What Gets Copied

1. **Input parameters** (`Role="Input"`)
2. **Everything inside `<O T="Export">`**

### ❌ What Does NOT Get Copied

* Parameters without `Role="Input"` that are outside Export
* Objects outside Export
* Geometry (Volume, Surface, Point objects)
* Internal calculations outside Export

### Example: What Appears

**Component definition:**

```xml
<O N="Beam" T="Project">
    <!-- ✅ Copied: Input parameters -->
    <P N="length" V="1000" Role="Input" />
    <P N="load" V="50" Role="Input" />
    
    <!-- ❌ NOT copied: Internal parameter -->
    <P N="load_factor" V="1.5" />
    
    <!-- ✅ Copied: Export content -->
    <O T="Export">
        <P N="moment" V="load * length * length / 8" />
        <P N="shear" V="load * length / 2" />
    </O>
    
    <!-- ❌ NOT copied: Geometry -->
    <O N="BeamGeo" T="Volume">
        <!-- ... -->
    </O>
</O>
```

**Instance:**

```xml
<O N="MyBeam" T="Beam">
    <!-- ✅ Inputs appear -->
    <P N="length" V="1000" />
    <P N="load" V="50" />
    
    <!-- ✅ Exports appear -->
    <P N="moment" V="load * length * length / 8" />
    <P N="shear" V="load * length / 2" />
    
    <!-- ❌ load_factor does NOT appear -->
    <!-- ❌ BeamGeo does NOT appear -->
</O>
```

**What you can access:**

```xml
<P N="m" V="MyBeam.moment" />           <!-- ✅ Works -->
<P N="s" V="MyBeam.shear" />            <!-- ✅ Works -->
<P N="f" V="MyBeam.load_factor" />      <!-- ❌ Not accessible -->
<P N="g" V="MyBeam.BeamGeo" />          <!-- ❌ Not accessible -->
```

***

## The Export Object

The `<O T="Export">` object controls **what is accessible** when someone creates an instance of your component.

### Why Export Exists

Export creates a **clean interface** - only exposing what users need, hiding implementation details.

**Without Export:**

* ❌ Everything would be accessible
* ❌ Implementation details exposed
* ❌ Hard to refactor without breaking code
* ❌ Messy, confusing interface

**With Export:**

* ✅ Clean, simple interface
* ✅ Hide complexity
* ✅ Can change internals without breaking users
* ✅ Clear what's intended for external use

### Basic Export Example

```xml
<O N="Column" T="Project">
    <P N="width" V="400" Role="Input" />
    <P N="height" V="3000" Role="Input" />
    
    <!-- Internal - hidden -->
    <P N="density" V="2400" />
    <P N="unit_weight" V="density * 9.81 / 1000000" />
    
    <!-- Public interface - accessible -->
    <O T="Export">
        <P N="area" V="width * width" />
        <P N="volume" V="area * height" />
        <P N="weight" V="volume * unit_weight" />  <!-- ⚠️ Problem - see AI-Export.md -->
    </O>
    
    <!-- Geometry - hidden -->
    <O N="ColumnGeo" T="Volume">
        <!-- ... -->
    </O>
</O>
```

**Instance sees only:**

```xml
<O N="MyColumn" T="Column">
    <P N="width" V="400" />
    <P N="height" V="3000" />
    <P N="area" V="..." />
    <P N="volume" V="..." />
    <P N="weight" V="..." />
</O>
```

**⚠️ Note:** The `weight` calculation has a dependency issue. See `AI-Export.md` for details on the **Dependency Rule**.

***

## Setting Instance Parameters

### Set Input Values

```xml
<O N="Beam" T="Project">
    <P N="length" V="1000" Role="Input" />  <!-- Default value -->
    <P N="width" V="200" Role="Input" />
    
    <O T="Export">
        <P N="area" V="length * width" />
    </O>
</O>

<!-- Use defaults -->
<O N="Beam1" T="Beam" />
<!-- Beam1: length=1000, width=200, area=200000 -->

<!-- Set all -->
<O N="Beam3" T="Beam">
    <P N="length" V="2000" />
    <P N="width" V="300" />
</O>
<!-- Beam3: length=2000, width=300, area=600000 -->
```

### Use Expressions

Instance parameters can be expressions:

```xml
<P N="column_spacing" V="500" />

<O N="Beam1" T="Beam">
    <P N="length" V="column_spacing * 4" />  <!-- 2000 -->
    <P N="width" V="length / 10" />          <!-- 200 -->
</O>
```

### Reference Other Instances

```xml
<O N="Column1" T="Column">
    <P N="height" V="3000" />
</O>

<O N="Beam1" T="Beam">
    <!-- Use Column1's exported value -->
    <P N="length" V="Column1.height / 3" />  <!-- 1000 -->
</O>
```

***

## Nested Instances (Simple)

Instances can contain other instances.

### Simple Nesting

**Building block:**

```xml
<O N="Bolt" T="Project">
    <P N="diameter" V="20" Role="Input" />
    
    <O T="Export">
        <P N="area" V="PI * (diameter/2)^2" />
        <P N="capacity" V="area * 400" />
    </O>
</O>
```

**Component using Bolt:**

```xml
<O N="Connection" T="Project">
    <P N="num_bolts" V="4" Role="Input" />
    <P N="bolt_diameter" V="20" Role="Input" />
    
    <O T="Export">
        <!-- Create Bolt instance inside Export -->
        <O N="Bolt" T="Bolt">
            <P N="diameter" V="bolt_diameter" />
            <P N="area" V="PI * (diameter/2)^2" />
            <P N="capacity" V="area * 400" />
        </O>
        
        <P N="total_capacity" V="num_bolts * Bolt.capacity" />
    </O>
</O>
```

**Using Connection:**

```xml
<O N="MyConnection" T="Connection">
    <P N="num_bolts" V="6" />
    <P N="bolt_diameter" V="24" />
    
    <!-- Nested instance appears -->
    <O N="Bolt" T="Bolt" Exported="1">
        <P N="diameter" V="bolt_diameter" />
        <P N="area" V="PI * (diameter/2)^2" />
        <P N="capacity" V="area * 400" />
    </O>
    
    <P N="total_capacity" V="num_bolts * Bolt.capacity" />
</O>

<!-- Can access nested values -->
<P N="bolt_cap" V="MyConnection.Bolt.capacity" />        <!-- ✅ Works -->
<P N="total_cap" V="MyConnection.total_capacity" />      <!-- ✅ Works -->
```

**Key point:** The nested `Bolt` instance must be **inside Export** for external access.

***

## The `Exported="1"` Attribute

You'll see `Exported="1"` on nested instances.

### How It Works

**In component definition (what you write):**

```xml
<O T="Export">
    <O N="Bolt" T="Bolt">
        <!-- No Exported="1" here -->
    </O>
</O>
```

**In instance (system generates):**

```xml
<O N="MyConnection" T="Connection">
    <O N="Bolt" T="Bolt" Exported="1">
        <!-- System adds Exported="1" automatically -->
    </O>
</O>
```

**What it means:** Marks the object as an exported instance, allowing nested access.

**Rule:** Never write `Exported="1"` - the system adds it automatically.

***

## Common Patterns

### Pattern 1: Multiple Instances of Same Component

```xml
<O N="Column" T="Project">
    <P N="x" V="0" Role="Input" />
    <P N="y" V="0" Role="Input" />
    <P N="height" V="3000" Role="Input" />
    <O T="Export">
        <P N="top_z" V="height" />
        <P N="volume" V="400 * 400 * height" />
    </O>
</O>

<!-- Create grid of columns -->
<O N="Col_A1" T="Column">
    <P N="x" V="0" />
    <P N="y" V="0" />
    <P N="height" V="3000" />
    <!-- Exported parameters -->
    <P N="top_z" V="height" />
    <P N="volume" V="400 * 400 * height" />
</O>

<O N="Col_A2" T="Column">
    <P N="x" V="5000" />
    <P N="y" V="0" />
    <P N="height" V="3000" />
    <P N="top_z" V="height" />
    <P N="volume" V="400 * 400 * height" />
</O>

<O N="Col_B1" T="Column">
    <P N="x" V="0" />
    <P N="y" V="5000" />
    <P N="height" V="3000" />
    <P N="top_z" V="height" />
    <P N="volume" V="400 * 400 * height" />
</O>

<O N="Col_B2" T="Column">
    <P N="x" V="5000" />
    <P N="y" V="5000" />
    <P N="height" V="3000" />
    <P N="top_z" V="height" />
    <P N="volume" V="400 * 400 * height" />
</O>

<!-- Use exported values -->
<P N="total_volume" V="Col_A1.volume + Col_A2.volume + Col_B1.volume + Col_B2.volume" />
```

### Pattern 2: Instances with Different Parameters

```xml
<O N="Beam" T="Project">
    <P N="length" V="1000" Role="Input" />
    <P N="section" V="IPE200" T="Section" Role="Input" />

    <O T="Export">
        <P N="weight" V="length * section.weight_per_length" />
    </O>
</O>

<!-- Different sizes -->
<O N="MainBeam" T="Beam">
    <P N="length" V="8000" />
    <P N="section" V="IPE400" T="Section" />
    <!-- Exported parameters -->
    <P N="weight" V="length * section.weight_per_length" />
</O>

<O N="SecondaryBeam" T="Beam">
    <P N="length" V="4000" />
    <P N="section" V="IPE200" T="Section" />
    <P N="weight" V="length * section.weight_per_length" />
</O>

<!-- Use exported values -->
<P N="total_weight" V="MainBeam.weight + SecondaryBeam.weight * 4" />
```

### Pattern 3: Instance Coordinates from Another Instance

```xml
<O N="Foundation" T="Project">
    <P N="x" V="0" Role="Input" />
    <P N="y" V="0" Role="Input" />
    
    <O T="Export">
        <P N="top_elevation" V="100" />
    </O>
</O>

<O N="Column" T="Project">
    <P N="base_x" V="0" Role="Input" />
    <P N="base_y" V="0" Role="Input" />
    <P N="base_z" V="0" Role="Input" />
    <P N="height" V="3000" Role="Input" />

    <O T="Export">
        <P N="top_x" V="base_x" />
        <P N="top_y" V="base_y" />
        <P N="top_z" V="base_z + height" />
    </O>
</O>

<!-- Foundation instance -->
<O N="Found1" T="Foundation">
    <P N="x" V="0" />
    <P N="y" V="0" />
    
    <!-- Exported parameters -->
    <P N="top_elevation" V="100" />
</O>

<!-- Column starts at foundation top -->
<O N="Col1" T="Column">
    <P N="base_x" V="Found1.x" />
    <P N="base_y" V="Found1.y" />
    <P N="base_z" V="Found1.top_elevation" />
    <P N="height" V="3000" />
    
    <!-- Exported parameters -->
    <P N="top_x" V="base_x" />
    <P N="top_y" V="base_y" />
    <P N="top_z" V="base_z + height" />
</O>

<!-- Beam connects column tops -->
<O N="Beam1" T="Line">
    <O T="Point" X="Col1.top_x" Y="Col1.top_y" Z="Col1.top_z" />
    <O T="Point" X="Col2.top_x" Y="Col2.top_y" Z="Col2.top_z" />
</O>
```

## Quick Troubleshooting

### Problem: "Can't access parameter from instance"

**Check:**

1. Is the parameter inside `<O T="Export">`?
2. Does the parameter have `Role="Input"`?
3. If neither → it's not accessible from outside

**Solution:** Move parameter inside Export or add `Role="Input"`

### Problem: "Can't access nested object"

**Check:**

1. Is the nested object instance inside `<O T="Export">`?

**Solution:** Move the nested object instance inside Export

### Problem: "Calculation gives wrong value in instance"

**Likely cause:** Missing dependency (parameter referenced but not exported)

**Solution:** See `AI-Export.md` for the **Dependency Rule**

***

## Next Steps

**You now know:**

* ✅ How to create instances
* ✅ What gets copied to instances
* ✅ How to use instance values
* ✅ Simple nested instances

***

## Quick Reference

### Create Instance

```xml
<O N="InstanceName" T="ComponentName">
    <P N="input_param" V="value" />
</O>
```

### What Gets Copied

* ✅ `Role="Input"` parameters
* ✅ Everything inside `<O T="Export">`
* ❌ Everything else

### Access Instance Values

```xml
<P N="value" V="InstanceName.exported_param" />
<P N="nested" V="InstanceName.NestedObj.param" />
```

### Export for Accessibility

```xml
<O T="Export">
    <P N="accessible_param" V="..." />
    <O N="accessible_obj" T="SomeType" />
</O>
```
